From 41ad9c6a502484ae144889f0df1b4f762e5cf4b4 Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Fri, 16 Aug 2024 16:02:16 +0800 Subject: [PATCH 01/47] =?UTF-8?q?feat:=20=E5=88=9D=E6=AD=A5=E6=8A=BD?= =?UTF-8?q?=E7=A6=BB=E9=80=BB=E8=BE=91=E5=88=B0wormhole=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/functions/getTypescript.ts | 4 +- src/wormhole/createConfig.ts | 15 +++++++ src/wormhole/generate.ts | 34 ++++++++++++++++ src/wormhole/index.ts | 4 ++ src/wormhole/readConfig.ts | 20 ++++++++++ src/wormhole/type.ts | 15 +++++++ templates/alovaconfig.handlebars | 67 ++++++++++++++++++++++++++++++++ typings/index.d.ts | 16 +------- 8 files changed, 158 insertions(+), 17 deletions(-) create mode 100644 src/wormhole/createConfig.ts create mode 100644 src/wormhole/generate.ts create mode 100644 src/wormhole/index.ts create mode 100644 src/wormhole/readConfig.ts create mode 100644 src/wormhole/type.ts create mode 100644 templates/alovaconfig.handlebars diff --git a/src/functions/getTypescript.ts b/src/functions/getTypescript.ts index eaf08c3..81eac92 100644 --- a/src/functions/getTypescript.ts +++ b/src/functions/getTypescript.ts @@ -1,4 +1,3 @@ -import { log } from '@/components/message'; import { createRequire } from 'node:module'; import path from 'node:path'; import * as vscode from 'vscode'; @@ -14,7 +13,8 @@ export default () => { typescript = workspacedRequire('./node_modules/typescript'); delete workspacedRequire.cache[path.resolve(workspaceRootPath, './package.json')]; } catch (error: any) { - log(error.message); + // log(error.message); + console.log(error); } } return typescript; diff --git a/src/wormhole/createConfig.ts b/src/wormhole/createConfig.ts new file mode 100644 index 0000000..58ef02e --- /dev/null +++ b/src/wormhole/createConfig.ts @@ -0,0 +1,15 @@ +import getAlovaVersion, { AlovaVersion } from '@/functions/getAlovaVersion'; +import getAutoTemplateType from '@/functions/getAutoTemplateType'; +import { TemplateFile } from '@/modules/TemplateFile'; + +export const createConfig = async (projectPath: string) => { + const type = getAutoTemplateType(projectPath); + const alovaVersion: AlovaVersion = getAlovaVersion(projectPath); + const templateFile = new TemplateFile(type, alovaVersion); + return templateFile.outputFile({}, 'alova.config', projectPath, { + root: true, + ext: '.ts', + hasVersion: false + }); +}; +export default createConfig; diff --git a/src/wormhole/generate.ts b/src/wormhole/generate.ts new file mode 100644 index 0000000..5f018d9 --- /dev/null +++ b/src/wormhole/generate.ts @@ -0,0 +1,34 @@ +import message from '@/components/message'; +import generateApi from '@/functions/generateApi'; +import { Configuration } from '@/modules/Configuration'; +import { getFileNameByPath } from '@/utils'; + +export const generate = async (projectPath: string, config?: AlovaConfig) => { + if (!config) { + return; + } + const configuration = new Configuration(config, projectPath); + // 检查新配置 + configuration.checkConfig(); + const fileName = getFileNameByPath(configuration.workspaceRootDir); + const outputPathArr = configuration.getAllOutputPath(); + const templateTypeArr = configuration.getAllTemplateType(); + const openApiData = await configuration.getAllOpenApiData(); + const generatorConfigArr = configuration.config.generator; + const result = await Promise.all( + outputPathArr.map((outputPath, idx) => + // 生成api文件 + generateApi( + configuration.workspaceRootDir, + outputPath, + openApiData[idx], + generatorConfigArr[idx], + templateTypeArr[idx] ?? 'commonjs' + ) + ) + ); + if (result.some(item => !!item)) { + message.info(`[${fileName}]:Your API is updated`); + } +}; +export default generate; diff --git a/src/wormhole/index.ts b/src/wormhole/index.ts new file mode 100644 index 0000000..47b7fee --- /dev/null +++ b/src/wormhole/index.ts @@ -0,0 +1,4 @@ +export * from './createConfig'; +export * from './generate'; +export * from './readConfig'; +export * from './type'; diff --git a/src/wormhole/readConfig.ts b/src/wormhole/readConfig.ts new file mode 100644 index 0000000..aabf7fa --- /dev/null +++ b/src/wormhole/readConfig.ts @@ -0,0 +1,20 @@ +import { loadJs, loadTs } from '@/helper/lodaders'; +import { cosmiconfig } from 'cosmiconfig'; +import path from 'node:path'; + +const alovaExplorer = cosmiconfig('alova', { + cache: false, + loaders: { + '.js': loadJs, + '.cjs': loadJs, + '.mjs': loadJs, + '.ts': loadTs, + '.mts': loadTs, + '.cts': loadTs + } +}); +export const readConfig = async (projectPath: string) => { + const searchResult = await alovaExplorer.search(path.resolve(projectPath)); + return searchResult?.config as AlovaConfig | null; +}; +export default readConfig; diff --git a/src/wormhole/type.ts b/src/wormhole/type.ts new file mode 100644 index 0000000..b32aa0b --- /dev/null +++ b/src/wormhole/type.ts @@ -0,0 +1,15 @@ +export type Config = { + // api生成设置,为数组,每项代表一个自动生成的规则,包含生成的输入输出目录、规范文件地址等等 + // 目前只支持openapi规范,包括openapi的2.0和3.0格式,但目前只做3.0规范 + generator: GeneratorConfig[]; + + // 是否自动更新接口,默认开启,每5分钟检查一次,false时关闭 + autoUpdate: + | boolean + | { + // 编辑器开启时更新,默认false + launchEditor: boolean; + // 自动更新间隔,单位毫秒 + interval: number; + }; +}; diff --git a/templates/alovaconfig.handlebars b/templates/alovaconfig.handlebars new file mode 100644 index 0000000..7174a14 --- /dev/null +++ b/templates/alovaconfig.handlebars @@ -0,0 +1,67 @@ +import { Config } from '@alova/wormhole'; + +// For more config detailed visit: +// https://alova.js.org/tutorial/getting-started/extension-integration +export default { + generator: [ + { + /** + * file input. support: + * 1. openapi json file url + * 2. local file + */ + input: 'http://localhost:3000', + + /** + * input file platform. Currently only swagger is supported. + * When this parameter is specified, the input field only needs to specify the document address without specifying the openapi file + */ + platform: 'swagger', + + /** + * output path of interface file and type file. + * Multiple generators cannot have the same address, otherwise the generated code will overwrite each other. + */ + output: 'src/api', + + /** + * the mediaType of the generated response data. default is `application/json` + */ + // responseMediaType: 'application/json', + + /** + * the bodyMediaType of the generated request body data. default is `application/json` + */ + // bodyMediaType: 'application/json', + + /** + * the generated api version. options are `2` or `3`, default is `auto`. + */ + // version: 'auto', + + /** + * type of generated code. The options ​​are `auto/ts/typescript/module/commonjs`. + */ + // type: 'auto', + + /** + * exported global api name, you can access the generated api globally through this name, default is `Apis`. + * it is required when multiple generators are configured, and it cannot be repeated + */ + // global: 'Apis', + + /** + * filter or convert the generated api information, return an apiDescriptor, if this function is not specified, the apiDescripor object is not converted + */ + // handleApi: apiDescriptor => { + // return apiDescriptor; + // } + } + ], + + /** + * extension only + * whether to automatically update the interface, enabled by default, check every 5 minutes, closed when set to `false` + */ + // autoUpdate: true +}; \ No newline at end of file diff --git a/typings/index.d.ts b/typings/index.d.ts index de9bac2..2664067 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -54,21 +54,7 @@ declare type GeneratorConfig = { // 对类型生成也同样适用 handleApi(apiDescriptor: ApiDescriptor, log: (...args: any[]) => void): ApiDescriptor; }; -declare interface AlovaConfig { - // api生成设置,为数组,每项代表一个自动生成的规则,包含生成的输入输出目录、规范文件地址等等 - // 目前只支持openapi规范,包括openapi的2.0和3.0格式,但目前只做3.0规范 - generator: GeneratorConfig[]; - - // 是否自动更新接口,默认开启,每5分钟检查一次,false时关闭 - autoUpdate: - | boolean - | { - // 编辑器开启时更新,默认false - launchEditor: boolean; - // 自动更新间隔,单位毫秒 - interval: number; - }; -} +declare type AlovaConfig = import('@/wormhole').Config; declare interface Commonand { commandId: string; handler: (context: import('vscode').ExtensionContext) => (...args: U) => T | Promise; From c38773bee1c92b7df646a4c82c6cf81951e7847d Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Tue, 20 Aug 2024 11:19:22 +0800 Subject: [PATCH 02/47] =?UTF-8?q?refactor:=20wormhole=E5=88=9D=E6=AD=A5?= =?UTF-8?q?=E5=88=86=E7=A6=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/commands/generateApi.ts | 24 ++---------- src/commands/refresh.ts | 20 +--------- src/functions/generateApi.ts | 1 + src/functions/getAutoTemplateType.ts | 3 +- src/functions/getOpenApiData.ts | 1 + src/functions/openApi2Data.ts | 3 +- src/functions/readConfig.ts | 31 ++++----------- src/modules/Configuration.ts | 1 + src/modules/TemplateFile.ts | 1 + src/wormhole/generate.ts | 12 ++---- src/wormhole/readConfig.ts | 4 ++ src/wormhole/type.ts | 56 +++++++++++++++++++++++++++ typings/index.d.ts | 57 +--------------------------- 13 files changed, 86 insertions(+), 128 deletions(-) diff --git a/src/commands/generateApi.ts b/src/commands/generateApi.ts index eb375de..edd08a4 100644 --- a/src/commands/generateApi.ts +++ b/src/commands/generateApi.ts @@ -1,8 +1,8 @@ import message from '@/components/message'; -import generateApi from '@/functions/generateApi'; import readConfig from '@/functions/readConfig'; import { CONFIG_POOL } from '@/modules/Configuration'; import { getFileNameByPath } from '@/utils'; +import { generate } from '@/wormhole'; // 用于自动生成 export default { commandId: 'alova.generateApi', @@ -16,25 +16,9 @@ export default { continue; } configuration.shouldUpdate = false; - const fileName = getFileNameByPath(configuration.workspaceRootDir); - const outputPathArr = configuration.getAllOutputPath(); - const templateTypeArr = configuration.getAllTemplateType(); - const openApiData = await configuration.getAllOpenApiData(); - const generatorConfigArr = configuration.config.generator; - const result = await Promise.all( - outputPathArr.map((outputPath, idx) => - // 生成api文件 - generateApi( - configuration.workspaceRootDir, - outputPath, - openApiData[idx], - generatorConfigArr[idx], - templateTypeArr[idx] ?? 'commonjs' - ) - ) - ); - if (result.some(item => !!item)) { - message.info(`[${fileName}]:Your API is updated`); + const result = await generate(configuration.workspaceRootDir, configuration.config); + if (result?.some(item => !!item)) { + message.info(`[${getFileNameByPath(configuration.workspaceRootDir)}]:Your API is updated`); } } } diff --git a/src/commands/refresh.ts b/src/commands/refresh.ts index 2a7393a..1b2c62e 100644 --- a/src/commands/refresh.ts +++ b/src/commands/refresh.ts @@ -1,10 +1,10 @@ import Error from '@/components/error'; import message from '@/components/message'; import { loading, reset } from '@/components/statusBar'; -import generateApi from '@/functions/generateApi'; import readConfig from '@/functions/readConfig'; import { CONFIG_POOL } from '@/modules/Configuration'; import { getFileNameByPath } from '@/utils'; +import { generate } from '@/wormhole'; export default { commandId: 'alova.refresh', @@ -16,23 +16,7 @@ export default { // 生成api文件 for (const configuration of CONFIG_POOL) { - const outputPathArr = configuration.getAllOutputPath(); - const templateTypeArr = configuration.getAllTemplateType(); - const openApiData = await configuration.getAllOpenApiData(); - const generatorConfigArr = configuration.config.generator; - await Promise.all( - outputPathArr.map((outputPath, idx) => - // 生成api文件 - generateApi( - configuration.workspaceRootDir, - outputPath, - openApiData[idx], - generatorConfigArr[idx], - templateTypeArr[idx] ?? 'commonjs', - true - ) - ) - ); + await generate(configuration.workspaceRootDir, configuration.config, { force: true }); reset(); message.info(`[${getFileNameByPath(configuration.workspaceRootDir)}]:Your API is refresh`); } diff --git a/src/functions/generateApi.ts b/src/functions/generateApi.ts index 9c3d4e4..e248656 100644 --- a/src/functions/generateApi.ts +++ b/src/functions/generateApi.ts @@ -1,5 +1,6 @@ import openApi2Data from '@/functions/openApi2Data'; import { getAlovaJsonPath, TEMPLATE_DATA, TemplateFile, writeAlovaJson } from '@/modules/TemplateFile'; +import type { TemplateType } from '@/wormhole'; import { isEqual } from 'lodash'; import fs from 'node:fs'; import path from 'node:path'; diff --git a/src/functions/getAutoTemplateType.ts b/src/functions/getAutoTemplateType.ts index 18a63d1..77dc3c6 100644 --- a/src/functions/getAutoTemplateType.ts +++ b/src/functions/getAutoTemplateType.ts @@ -1,6 +1,7 @@ +import type { TemplateType } from '@/wormhole'; +import { createRequire } from 'node:module'; import path from 'node:path'; import { PackageJson } from 'type-fest'; -import { createRequire } from 'node:module'; export default (workspaceRootDir: string): TemplateType => { const workspacedRequire = createRequire(workspaceRootDir); diff --git a/src/functions/getOpenApiData.ts b/src/functions/getOpenApiData.ts index 1917d6d..aa16e44 100644 --- a/src/functions/getOpenApiData.ts +++ b/src/functions/getOpenApiData.ts @@ -1,5 +1,6 @@ import Error from '@/components/error'; import { fetchData } from '@/utils'; +import type { PlatformType } from '@/wormhole'; import importFresh from 'import-fresh'; import YAML from 'js-yaml'; import fs from 'node:fs'; diff --git a/src/functions/openApi2Data.ts b/src/functions/openApi2Data.ts index 8b838cc..6c1f6ef 100644 --- a/src/functions/openApi2Data.ts +++ b/src/functions/openApi2Data.ts @@ -4,6 +4,7 @@ import { convertToType, jsonSchema2TsStr } from '@/helper/schema2type'; import { getStandardOperationId, getStandardTags } from '@/helper/standard'; import { generateDefaultValues } from '@/helper/typeStr'; import { format, removeUndefined } from '@/utils'; +import type { ApiDescriptor } from '@/wormhole'; import { cloneDeep } from 'lodash'; import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'; import { AlovaVersion } from './getAlovaVersion'; @@ -273,7 +274,7 @@ export const transformPathObj = async ( apiDescriptor.parameters = []; const parametersArray = isReferenceObject(parameters) ? findBy$ref(parameters.$ref, openApi, true) - : (parameters ?? []); + : parameters ?? []; for (const parameter of parametersArray) { const parameterObject = removeAll$ref(parameter, openApi); apiDescriptor.parameters.push(parameterObject); diff --git a/src/functions/readConfig.ts b/src/functions/readConfig.ts index bd508a3..d552584 100644 --- a/src/functions/readConfig.ts +++ b/src/functions/readConfig.ts @@ -1,40 +1,28 @@ import Error from '@/components/error'; import message from '@/components/message'; -import { loadJs, loadTs } from '@/helper/lodaders'; import { CONFIG_POOL, Configuration } from '@/modules/Configuration'; import { getFileNameByPath } from '@/utils'; +import { readConfig as baseReadConfig } from '@/wormhole'; import chokidar, { FSWatcher } from 'chokidar'; -import { cosmiconfig } from 'cosmiconfig'; -import path from 'node:path'; import * as vscode from 'vscode'; const WATCH_CONFIG: Map = new Map(); const NO_CONFIG_WORKSPACE = new Set(); -const alovaExplorer = cosmiconfig('alova', { - cache: false, - loaders: { - '.js': loadJs, - '.cjs': loadJs, - '.mjs': loadJs, - '.ts': loadTs, - '.mts': loadTs, - '.cts': loadTs - } -}); + export function createWatcher(workspaceRootPath: string) { return chokidar .watch(`${workspaceRootPath}/*alova*`, { ignored: [/node_modules/] }) - .on('all', async (eventName, watchPath) => { + .on('all', async eventName => { if (!['add', 'change'].includes(eventName)) { return; } let configItem: Configuration | undefined; try { - const { config, filepath } = await readConfig(workspaceRootPath, false); + const { config } = await readConfig(workspaceRootPath, false); // 没有配置文件或者修改的不是当前的配置文件 - if (!config || filepath !== watchPath) { + if (!config) { return; } configItem = CONFIG_POOL.find(config => config.workspaceRootDir === workspaceRootPath); @@ -64,9 +52,9 @@ export async function readConfig(workspaceRootPath: string, isShowError = true, WATCH_CONFIG.set(workspaceRootPath, watch); } } - const searchResult = await alovaExplorer.search(path.resolve(workspaceRootPath)); + alovaConfig = await baseReadConfig(workspaceRootPath); try { - if (!searchResult || searchResult?.isEmpty) { + if (!alovaConfig) { const idx = CONFIG_POOL.findIndex(config => config.workspaceRootDir === workspaceRootPath); if (idx >= 0) { // 关闭自动更新 @@ -76,7 +64,6 @@ export async function readConfig(workspaceRootPath: string, isShowError = true, } if (NO_CONFIG_WORKSPACE.has(workspaceRootPath)) { return { - ...searchResult, config: alovaConfig }; } @@ -88,9 +75,6 @@ export async function readConfig(workspaceRootPath: string, isShowError = true, ); } } - // 读取文件内容 - alovaConfig = searchResult?.config; - alovaExplorer.clearCaches(); // 能读到配置文件,则移除没有配置文件的标记 if (NO_CONFIG_WORKSPACE.has(workspaceRootPath) && alovaConfig) { NO_CONFIG_WORKSPACE.delete(workspaceRootPath); @@ -99,7 +83,6 @@ export async function readConfig(workspaceRootPath: string, isShowError = true, message.error(error.message); } return { - ...searchResult, config: alovaConfig }; } diff --git a/src/modules/Configuration.ts b/src/modules/Configuration.ts index 9a98a65..29eb4ce 100644 --- a/src/modules/Configuration.ts +++ b/src/modules/Configuration.ts @@ -5,6 +5,7 @@ import getOpenApiData from '@/functions/getOpenApiData'; import { isValidJSIdentifier } from '@/helper/standard'; import { getAlovaJsonPath, readAlovaJson, TEMPLATE_DATA } from '@/modules/TemplateFile'; import { highPrecisionInterval, isEmpty } from '@/utils'; +import type { TemplateType } from '@/wormhole'; import path from 'node:path'; import * as vscode from 'vscode'; diff --git a/src/modules/TemplateFile.ts b/src/modules/TemplateFile.ts index e974d42..cd608fc 100644 --- a/src/modules/TemplateFile.ts +++ b/src/modules/TemplateFile.ts @@ -3,6 +3,7 @@ import { AlovaVersion } from '@/functions/getAlovaVersion'; import { TemplateData } from '@/functions/openApi2Data'; import { ALOVA_TEMP_PATH, TEMPLATE_PATH } from '@/globalConfig'; import { format, generateFile, readAndRenderTemplate } from '@/utils'; +import type { TemplateType } from '@/wormhole'; import { cloneDeep, merge } from 'lodash'; import fs from 'node:fs'; import path from 'node:path'; diff --git a/src/wormhole/generate.ts b/src/wormhole/generate.ts index 5f018d9..74b89e8 100644 --- a/src/wormhole/generate.ts +++ b/src/wormhole/generate.ts @@ -1,16 +1,13 @@ -import message from '@/components/message'; import generateApi from '@/functions/generateApi'; import { Configuration } from '@/modules/Configuration'; -import { getFileNameByPath } from '@/utils'; -export const generate = async (projectPath: string, config?: AlovaConfig) => { +export const generate = async (projectPath: string, config?: AlovaConfig, options = { force: false }) => { if (!config) { return; } const configuration = new Configuration(config, projectPath); // 检查新配置 configuration.checkConfig(); - const fileName = getFileNameByPath(configuration.workspaceRootDir); const outputPathArr = configuration.getAllOutputPath(); const templateTypeArr = configuration.getAllTemplateType(); const openApiData = await configuration.getAllOpenApiData(); @@ -23,12 +20,11 @@ export const generate = async (projectPath: string, config?: AlovaConfig) => { outputPath, openApiData[idx], generatorConfigArr[idx], - templateTypeArr[idx] ?? 'commonjs' + templateTypeArr[idx] ?? 'commonjs', + options.force ) ) ); - if (result.some(item => !!item)) { - message.info(`[${fileName}]:Your API is updated`); - } + return result; }; export default generate; diff --git a/src/wormhole/readConfig.ts b/src/wormhole/readConfig.ts index aabf7fa..39593f2 100644 --- a/src/wormhole/readConfig.ts +++ b/src/wormhole/readConfig.ts @@ -15,6 +15,10 @@ const alovaExplorer = cosmiconfig('alova', { }); export const readConfig = async (projectPath: string) => { const searchResult = await alovaExplorer.search(path.resolve(projectPath)); + alovaExplorer.clearCaches(); + if (searchResult?.isEmpty) { + return null; + } return searchResult?.config as AlovaConfig | null; }; export default readConfig; diff --git a/src/wormhole/type.ts b/src/wormhole/type.ts index b32aa0b..cd250ed 100644 --- a/src/wormhole/type.ts +++ b/src/wormhole/type.ts @@ -1,3 +1,59 @@ +// 查找对应的input属性值 +export type ConfigType = 'auto' | 'ts' | 'typescript' | 'module' | 'commonjs'; +// 模板类型 +export type TemplateType = 'typescript' | 'module' | 'commonjs'; +// 平台类型 +export type PlatformType = 'swagger' | 'knife4j' | 'yapi'; +export namespace OpenAPIV3_1 {} +export type SchemaObject = import('openapi-types').OpenAPIV3_1.SchemaObject; +export type Parameter = import('openapi-types').OpenAPIV3_1.ParameterObject; +export type OperationObject = import('openapi-types').OpenAPIV3_1.OperationObject; +export type ApiDescriptor = Omit & { + url: string; + method: string; + parameters?: Parameter[]; + requestBody?: SchemaObject; + responses?: SchemaObject; +}; +export type GeneratorConfig = { + // openapi的json文件url地址 + input: string; + // input: 'http://localhost:3000/openapi.json', + // input: 'openapi/api.json' // 以当前项目为相对目录的本地地址 + // input: 'http://192.168.5.123:8080' // 没有指向openapi文件时,必须配合platform参数使用 + + // 支持openapi的平台,目前先支持swagger、knife4j、yapi,默认为空 + // 当指定了此参数后,input字段只需要指定文档的地址而不需要指定到openapi文件,减小使用门槛 + // 不同平台,它的openapi文件地址不一样,根据平台标识去对应地址下读取文件即可。 + platform: PlatformType; + + // 接口文件和类型文件的输出路径,多个generator不能重复的地址,否则生成的代码会相互覆盖,无意义 + output: string; + + // (具体看下面)指定生成的响应数据的mediaType,指定后以此数据类型来生成200状态码的响应ts格式,默认application/json + responseMediaType: string; + + // (具体看下面)指定生成的请求体数据的mediaType,指定后以此数据类型来生成请求体的ts格式,默认application/json + bodyMediaType: string; + + // 生成代码的类型,可选值为auto/ts/typescript/module/commonjs,默认为auto,会通过一定规则判断当前项目的类型 + // ts/typescript:意思相同,表示生成ts类型文件 + // module:生成esModule规范文件 + // commonjs:表示生成commonjs规范文件 + type: ConfigType; + // 指定alova版本 + version: Number; + // 多项目使用global字段 + global?: string; + // 是否使用import来导入类型,默认false + // 开启此选项后,生成的apiDefinitions.ts文件将使用import语法来导入类型,而不是/// + useImportType: boolean; + // (具体看下面)过滤或转换生成的api接口函数,返回一个新的apiDescriptor来生成api调用函数 + // 未指定此函数时则不转换apiDescripor对象 + // apiDescriptor的格式与openapi文件的接口对象格式相同 + // 对类型生成也同样适用 + handleApi(apiDescriptor: ApiDescriptor, log: (...args: any[]) => void): ApiDescriptor; +}; export type Config = { // api生成设置,为数组,每项代表一个自动生成的规则,包含生成的输入输出目录、规范文件地址等等 // 目前只支持openapi规范,包括openapi的2.0和3.0格式,但目前只做3.0规范 diff --git a/typings/index.d.ts b/typings/index.d.ts index 2664067..e7395a9 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1,59 +1,4 @@ -// 查找对应的input属性值 -declare type ConfigType = 'auto' | 'ts' | 'typescript' | 'module' | 'commonjs'; -// 模板类型 -declare type TemplateType = 'typescript' | 'module' | 'commonjs'; -// 平台类型 -declare type PlatformType = 'swagger' | 'knife4j' | 'yapi'; -declare namespace OpenAPIV3_1 {} -declare type SchemaObject = import('openapi-types').OpenAPIV3_1.SchemaObject; -declare type Parameter = import('openapi-types').OpenAPIV3_1.ParameterObject; -declare type OperationObject = import('openapi-types').OpenAPIV3_1.OperationObject; -declare type ApiDescriptor = Omit & { - url: string; - method: string; - parameters?: Parameter[]; - requestBody?: SchemaObject; - responses?: SchemaObject; -}; -declare type GeneratorConfig = { - // openapi的json文件url地址 - input: string; - // input: 'http://localhost:3000/openapi.json', - // input: 'openapi/api.json' // 以当前项目为相对目录的本地地址 - // input: 'http://192.168.5.123:8080' // 没有指向openapi文件时,必须配合platform参数使用 - - // 支持openapi的平台,目前先支持swagger、knife4j、yapi,默认为空 - // 当指定了此参数后,input字段只需要指定文档的地址而不需要指定到openapi文件,减小使用门槛 - // 不同平台,它的openapi文件地址不一样,根据平台标识去对应地址下读取文件即可。 - platform: PlatformType; - - // 接口文件和类型文件的输出路径,多个generator不能重复的地址,否则生成的代码会相互覆盖,无意义 - output: string; - - // (具体看下面)指定生成的响应数据的mediaType,指定后以此数据类型来生成200状态码的响应ts格式,默认application/json - responseMediaType: string; - - // (具体看下面)指定生成的请求体数据的mediaType,指定后以此数据类型来生成请求体的ts格式,默认application/json - bodyMediaType: string; - - // 生成代码的类型,可选值为auto/ts/typescript/module/commonjs,默认为auto,会通过一定规则判断当前项目的类型 - // ts/typescript:意思相同,表示生成ts类型文件 - // module:生成esModule规范文件 - // commonjs:表示生成commonjs规范文件 - type: ConfigType; - // 指定alova版本 - version: Number; - // 多项目使用global字段 - global?: string; - // 是否使用import来导入类型,默认false - // 开启此选项后,生成的apiDefinitions.ts文件将使用import语法来导入类型,而不是/// - useImportType: boolean; - // (具体看下面)过滤或转换生成的api接口函数,返回一个新的apiDescriptor来生成api调用函数 - // 未指定此函数时则不转换apiDescripor对象 - // apiDescriptor的格式与openapi文件的接口对象格式相同 - // 对类型生成也同样适用 - handleApi(apiDescriptor: ApiDescriptor, log: (...args: any[]) => void): ApiDescriptor; -}; +declare type GeneratorConfig = import('@/wormhole').GeneratorConfig; declare type AlovaConfig = import('@/wormhole').Config; declare interface Commonand { commandId: string; From 2ed769d13039b8ee8796a3d2e44ba2811033c2b6 Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Fri, 23 Aug 2024 19:08:01 +0800 Subject: [PATCH 03/47] =?UTF-8?q?chore:=20=E6=9A=82=E6=97=B6=E4=BF=9D?= =?UTF-8?q?=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- alova-vscode-extension-0.0.3.zip | Bin 0 -> 775882 bytes .../[Content_Types].xml | 2 + .../extension.vsixmanifest | 47 +++++ .../extension/.eslintignore | 6 + .../extension/.prettierignore | 3 + .../extension/CHANGELOG.md | 9 + .../extension/LICENSE.txt | 21 +++ .../extension/README.md | 3 + .../extension/commitlint.config.cjs | 3 + .../extension/package.json | 128 ++++++++++++++ .../extension/resources/icon.png | Bin 0 -> 33114 bytes .../extension/resources/logo.ttf | Bin 0 -> 1456 bytes .../templates/apiDefinitions.handlebars | 7 + .../extension/templates/comment.handlebars | 19 ++ .../templates/commonjs/createApis.handlebars | 72 ++++++++ .../templates/commonjs/index.handlebars | 35 ++++ .../commonjs/v3-createApis.handlebars | 75 ++++++++ .../templates/commonjs/v3-index.handlebars | 35 ++++ .../extension/templates/globals.d.handlebars | 114 ++++++++++++ .../templates/module/createApis.handlebars | 67 ++++++++ .../templates/module/index.handlebars | 31 ++++ .../templates/module/v3-createApis.handlebars | 69 ++++++++ .../templates/module/v3-index.handlebars | 33 ++++ .../typescript/createApis.handlebars | 61 +++++++ .../templates/typescript/index.handlebars | 30 ++++ .../typescript/v3-createApis.handlebars | 61 +++++++ .../templates/typescript/v3-index.handlebars | 30 ++++ .../templates/v3-globals.d.handlebars | 146 ++++++++++++++++ src/extension.ts | 1 + src/functions/autocomplete.ts | 7 +- src/functions/getTypescript.ts | 2 +- src/functions/readConfig.ts | 3 +- src/globalConfig.ts | 7 +- src/utils/index.ts | 156 ----------------- src/utils/work.ts | 18 -- src/wormhole/config.ts | 16 ++ src/wormhole/createConfig.ts | 7 +- src/wormhole/functions/alovaJson.ts | 44 +++++ src/{ => wormhole}/functions/generateApi.ts | 24 +-- .../functions/getAlovaVersion.ts | 0 .../functions/getAutoTemplateType.ts | 0 .../functions/getFrameworkTag.ts | 2 +- .../functions/getOpenApiData.ts | 3 +- src/{ => wormhole}/functions/openApi2Data.ts | 18 +- src/wormhole/generate.ts | 9 +- src/{ => wormhole}/helper/lodaders.ts | 12 +- src/{ => wormhole}/helper/openapi.ts | 2 +- src/{ => wormhole}/helper/schema2type.ts | 6 +- src/{ => wormhole}/helper/standard.ts | 0 src/{ => wormhole}/helper/typeStr.ts | 2 +- src/wormhole/index.ts | 1 + src/{ => wormhole}/modules/Configuration.ts | 86 +++------- src/{ => wormhole}/modules/TemplateFile.ts | 80 +++------ src/wormhole/readConfig.ts | 5 +- src/wormhole/type.ts | 3 + src/wormhole/utils/index.ts | 162 ++++++++++++++++++ typings/index.d.ts | 2 - 57 files changed, 1436 insertions(+), 349 deletions(-) create mode 100644 alova-vscode-extension-0.0.3.zip create mode 100644 alova-vscode-extension-0.0.3/[Content_Types].xml create mode 100644 alova-vscode-extension-0.0.3/extension.vsixmanifest create mode 100644 alova-vscode-extension-0.0.3/extension/.eslintignore create mode 100644 alova-vscode-extension-0.0.3/extension/.prettierignore create mode 100644 alova-vscode-extension-0.0.3/extension/CHANGELOG.md create mode 100644 alova-vscode-extension-0.0.3/extension/LICENSE.txt create mode 100644 alova-vscode-extension-0.0.3/extension/README.md create mode 100644 alova-vscode-extension-0.0.3/extension/commitlint.config.cjs create mode 100644 alova-vscode-extension-0.0.3/extension/package.json create mode 100644 alova-vscode-extension-0.0.3/extension/resources/icon.png create mode 100644 alova-vscode-extension-0.0.3/extension/resources/logo.ttf create mode 100644 alova-vscode-extension-0.0.3/extension/templates/apiDefinitions.handlebars create mode 100644 alova-vscode-extension-0.0.3/extension/templates/comment.handlebars create mode 100644 alova-vscode-extension-0.0.3/extension/templates/commonjs/createApis.handlebars create mode 100644 alova-vscode-extension-0.0.3/extension/templates/commonjs/index.handlebars create mode 100644 alova-vscode-extension-0.0.3/extension/templates/commonjs/v3-createApis.handlebars create mode 100644 alova-vscode-extension-0.0.3/extension/templates/commonjs/v3-index.handlebars create mode 100644 alova-vscode-extension-0.0.3/extension/templates/globals.d.handlebars create mode 100644 alova-vscode-extension-0.0.3/extension/templates/module/createApis.handlebars create mode 100644 alova-vscode-extension-0.0.3/extension/templates/module/index.handlebars create mode 100644 alova-vscode-extension-0.0.3/extension/templates/module/v3-createApis.handlebars create mode 100644 alova-vscode-extension-0.0.3/extension/templates/module/v3-index.handlebars create mode 100644 alova-vscode-extension-0.0.3/extension/templates/typescript/createApis.handlebars create mode 100644 alova-vscode-extension-0.0.3/extension/templates/typescript/index.handlebars create mode 100644 alova-vscode-extension-0.0.3/extension/templates/typescript/v3-createApis.handlebars create mode 100644 alova-vscode-extension-0.0.3/extension/templates/typescript/v3-index.handlebars create mode 100644 alova-vscode-extension-0.0.3/extension/templates/v3-globals.d.handlebars delete mode 100644 src/utils/work.ts create mode 100644 src/wormhole/config.ts create mode 100644 src/wormhole/functions/alovaJson.ts rename src/{ => wormhole}/functions/generateApi.ts (74%) rename src/{ => wormhole}/functions/getAlovaVersion.ts (100%) rename src/{ => wormhole}/functions/getAutoTemplateType.ts (100%) rename src/{ => wormhole}/functions/getFrameworkTag.ts (92%) rename src/{ => wormhole}/functions/getOpenApiData.ts (97%) rename src/{ => wormhole}/functions/openApi2Data.ts (96%) rename src/{ => wormhole}/helper/lodaders.ts (91%) rename src/{ => wormhole}/helper/openapi.ts (99%) rename src/{ => wormhole}/helper/schema2type.ts (98%) rename src/{ => wormhole}/helper/standard.ts (100%) rename src/{ => wormhole}/helper/typeStr.ts (99%) rename src/{ => wormhole}/modules/Configuration.ts (56%) rename src/{ => wormhole}/modules/TemplateFile.ts (52%) create mode 100644 src/wormhole/utils/index.ts diff --git a/alova-vscode-extension-0.0.3.zip b/alova-vscode-extension-0.0.3.zip new file mode 100644 index 0000000000000000000000000000000000000000..bef1909e46a6e5fc96c4ff05d44becd8220caacd GIT binary patch literal 775882 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 W|07Wp$x@e-Fy)sNt!{Ks-IDw1~oy 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 + diff --git a/alova-vscode-extension-0.0.3/extension.vsixmanifest b/alova-vscode-extension-0.0.3/extension.vsixmanifest new file mode 100644 index 0000000..4e14d22 --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension.vsixmanifest @@ -0,0 +1,47 @@ + + + + + Alova + The vscode extension for alova.js + javascript + Other + Public + + + + + + + + + + + + + + + + + + + + + + + + extension/LICENSE.txt + extension/resources/icon.png + + + + + + + + + + + + + \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/.eslintignore b/alova-vscode-extension-0.0.3/extension/.eslintignore new file mode 100644 index 0000000..ce5a37a --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/.eslintignore @@ -0,0 +1,6 @@ +test/api-*/src/* +test/api-*/openapi*.* +test/api-*/swagger*.* +test/api-*/alova.config.* +!test/api-*/src/.gitkeep +design/**/* \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/.prettierignore b/alova-vscode-extension-0.0.3/extension/.prettierignore new file mode 100644 index 0000000..119571e --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/.prettierignore @@ -0,0 +1,3 @@ +/dist +pnpm-lock.yaml +**/*.handlebars \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/CHANGELOG.md b/alova-vscode-extension-0.0.3/extension/CHANGELOG.md new file mode 100644 index 0000000..096404d --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/CHANGELOG.md @@ -0,0 +1,9 @@ +# Change Log + +All notable changes to the "helloworld" extension will be documented in this file. + +Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. + +## [Unreleased] + +- Initial release diff --git a/alova-vscode-extension-0.0.3/extension/LICENSE.txt b/alova-vscode-extension-0.0.3/extension/LICENSE.txt new file mode 100644 index 0000000..c602816 --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 alovajs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/alova-vscode-extension-0.0.3/extension/README.md b/alova-vscode-extension-0.0.3/extension/README.md new file mode 100644 index 0000000..cd4a38d --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/README.md @@ -0,0 +1,3 @@ +# alova devtools + +Editor devtools for alova.js. [Detailed documentation](https://alova.js.org/next/tutorial/getting-started/extension-integration). diff --git a/alova-vscode-extension-0.0.3/extension/commitlint.config.cjs b/alova-vscode-extension-0.0.3/extension/commitlint.config.cjs new file mode 100644 index 0000000..c34aa79 --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/commitlint.config.cjs @@ -0,0 +1,3 @@ +module.exports = { + extends: ['@commitlint/config-conventional'] +}; diff --git a/alova-vscode-extension-0.0.3/extension/package.json b/alova-vscode-extension-0.0.3/extension/package.json new file mode 100644 index 0000000..0692f32 --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/package.json @@ -0,0 +1,128 @@ +{ + "name": "alova-vscode-extension", + "displayName": "Alova", + "description": "The vscode extension for alova.js", + "version": "0.0.3", + "engines": { + "vscode": "^1.89.0", + "node": ">=18.19.0", + "pnpm": ">=8.6.12" + }, + "categories": [ + "Other" + ], + "activationEvents": [ + "workspaceContains:**/*.ts", + "workspaceContains:**/*.js" + ], + "main": "./out/extension.js", + "icon": "resources/icon.png", + "contributes": { + "commands": [ + { + "command": "alova.refresh", + "category": "alova", + "title": "alova refresh" + } + ], + "icons": { + "alova-icon-id": { + "description": "alova icon", + "default": { + "fontPath": "./resources/logo.ttf", + "fontCharacter": "\\E900" + } + } + } + }, + "scripts": { + "vscode:prepublish": "pnpm run package", + "compile": "pnpm run check-types && pnpm run lint:fix && tsx esbuild.ts", + "watch": "npm-run-all -p watch:*", + "watch:esbuild": "tsx esbuild.ts --watch", + "watch:tsc": "tsc --noEmit --watch --project tsconfig.json", + "package": "pnpm run check-types && pnpm run lint:fix && tsx esbuild.ts --production", + "compile-tests": "tsc -p . --outDir out", + "watch-tests": "tsc -p . -w --outDir out", + "pretest": "pnpm run compile-tests && pnpm run compile && pnpm run lint", + "check-types": "tsc --noEmit", + "lint": "eslint . --ext .js,.ts", + "lint:fix": "npm run lint -- --fix", + "format": "prettier --check .", + "format:fix": "prettier --write .", + "test": "vscode-test", + "api-test": "tsx scripts/api-test.ts", + "commit": "git-cz && git push", + "prepare": "husky && pnpm api-test", + "pack:pre": "vsce package --no-dependencies --pre-release", + "release:pre": "vsce publish --no-dependencies --pre-release", + "pack": "vsce package --no-dependencies", + "release": "vsce publish --no-dependencies" + }, + "publisher": "Alova", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/alovajs/devtools.git" + }, + "bugs": { + "url": "https://github.com/alovajs/devtools/issues" + }, + "lint-staged": { + "*": "npm run format:fix", + "*.js,*.ts": "npm run lint:fix" + }, + "devDependencies": { + "@commitlint/cli": "^19.3.0", + "@commitlint/config-conventional": "^19.2.2", + "@types/js-yaml": "^4.0.9", + "@types/lodash": "^4.17.5", + "@types/mocha": "^10.0.6", + "@types/mustache": "^4.2.5", + "@types/node": "18.x", + "@types/node-fetch": "^2.6.11", + "@types/serialize-javascript": "^5.0.4", + "@types/swagger2openapi": "^7.0.4", + "@types/vscode": "^1.89.0", + "@typescript-eslint/eslint-plugin": "^7.13.0", + "@typescript-eslint/parser": "^7.13.0", + "@vscode/test-cli": "^0.0.9", + "@vscode/test-electron": "^2.3.9", + "@vscode/vsce": "^2.29.0", + "commitizen": "^4.3.0", + "cz-conventional-changelog": "^3.3.0", + "esbuild": "^0.23.0", + "esbuild-plugin-alias": "^0.2.1", + "eslint": "^8.57.0", + "eslint-config-airbnb": "^19.0.4", + "eslint-config-airbnb-typescript": "^18.0.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.1.3", + "husky": "^9.0.11", + "js-yaml": "^4.1.0", + "lint-staged": "^15.2.2", + "npm-run-all": "^4.1.5", + "prettier": "^3.2.5", + "prettier-plugin-organize-imports": "^3.2.4", + "prettier-plugin-sort-json": "^4.0.0", + "tsx": "^4.15.8", + "type-fest": "^4.20.0", + "typescript": "^5.4.5" + }, + "config": { + "commitizen": { + "path": "./node_modules/cz-conventional-changelog" + } + }, + "dependencies": { + "chokidar": "^3.6.0", + "cosmiconfig": "^9.0.0", + "handlebars": "^4.7.8", + "import-fresh": "^3.3.0", + "lodash": "^4.17.21", + "node-fetch": "^2.7.0", + "openapi-types": "^12.1.3", + "serialize-javascript": "^6.0.2", + "swagger2openapi": "^7.0.8" + } +} diff --git a/alova-vscode-extension-0.0.3/extension/resources/icon.png b/alova-vscode-extension-0.0.3/extension/resources/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7bb5c54d74666c6651ac2af86c28e065aa09b912 GIT binary patch literal 33114 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 NjDxSu_*;1n{|j*+;urt` literal 0 HcmV?d00001 diff --git a/alova-vscode-extension-0.0.3/extension/templates/apiDefinitions.handlebars b/alova-vscode-extension-0.0.3/extension/templates/apiDefinitions.handlebars new file mode 100644 index 0000000..5820553 --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/templates/apiDefinitions.handlebars @@ -0,0 +1,7 @@ +/// +{{{commentText}}} +{{#if (eq moduleType "ESModule")}}export default{{else if (eq moduleType "commonJs")}}module.exports ={{/if}} { +{{#pathsArr}} + "{{{key}}}": ["{{method}}", "{{{path}}}"], +{{/pathsArr}} +}; \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/comment.handlebars b/alova-vscode-extension-0.0.3/extension/templates/comment.handlebars new file mode 100644 index 0000000..4eafdcf --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/templates/comment.handlebars @@ -0,0 +1,19 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * {{info.title}} - version {{info.version}} + * + * {{info.description}} + * + * OpenAPI version: {{openapi}} + * + {{#info.contact}} + * Contact: {{#info.contact.name}}[{{info.contact.name}}]{{/info.contact.name}}{{#info.contact.url}}{{{info.contact.url}}}{{/info.contact.url}}{{^info.contact.url}}{{{info.contact.email}}}{{/info.contact.url}} + {{/info.contact}} + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/commonjs/createApis.handlebars b/alova-vscode-extension-0.0.3/extension/templates/commonjs/createApis.handlebars new file mode 100644 index 0000000..66a4715 --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/templates/commonjs/createApis.handlebars @@ -0,0 +1,72 @@ +{{{commentText}}} +const { Method } = require('alova'); +const apiDefinitions = require('./apiDefinitions'); +/** + * + * @param {(string|symbol)[]} array + * @param {Alova} alovaInstance + * @param {any} configMap + * @returns {()=>void} + */ +const createFunctionalProxy = (array, alovaInstance, configMap) => { + // create a new proxy instance + return new Proxy(function () {}, { + get(_, property) { + // record the target property, so that it can get the completed accessing paths + array.push(property); + // always return a new proxy to continue recording accessing paths. + return createFunctionalProxy(array, alovaInstance, configMap); + }, + apply(_, __, [config]) { + const apiItem = apiDefinitions[array.join('.')]; + if (!apiItem) { + throw new Error(`the api path of \`${apiItem}\` is not found`); + } + const [method, url] = apiItem; + const { pathParams, data } = config; + const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => { + const pathParam = pathParams[key]; + return pathParam; + }); + delete config.pathParams; + return new Method(method.toUpperCase(), alovaInstance, urlReplaced, config, data); + } + }); +}; +/** + * + * @param {Alova} alovaInstance + * @param {any} configMap + * @returns + */ +const createApis = (alovaInstance, configMap) => { + const Apis = new Proxy( + {}, + { + get(_, property) { + return createFunctionalProxy([property], alovaInstance, configMap); + } + } + ); + // 如果是全局定义 + globalThis.{{{global}}} = Apis; + return Apis; +} +/** + * @template T + * @typedef {typeof import('./index')['alovaInstance'] extends import('alova').Alova ? import('alova').AlovaMethodCreateConfig : never} MethodConfig + */ +/** + * @typedef {{#raw "{{ " }}{{/raw}}[P in keyof typeof import('./apiDefinitions')]?: MethodConfig

[0]['transformData']>[0] : any>{{#raw " }}" }}{{/raw}} MethodsConfigMap + */ +/** + * @template {MethodsConfigMap} Config + * @param {Config} config + */ +const withConfigType = config => config; + +module.exports = { + createApis, + withConfigType +}; + diff --git a/alova-vscode-extension-0.0.3/extension/templates/commonjs/index.handlebars b/alova-vscode-extension-0.0.3/extension/templates/commonjs/index.handlebars new file mode 100644 index 0000000..464e0bd --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/templates/commonjs/index.handlebars @@ -0,0 +1,35 @@ +const { createAlova } = require('alova'); +const GlobalFetch = require('alova/GlobalFetch'); +{{#vue}} +const vueHook = require('alova/vue'); +{{/vue}} +{{#react}} +const reactHook = require('alova/react'); +{{/react}} +const { createApis, withConfigType } = require('./createApis'); +const alovaInstance = createAlova({ + baseURL: "{{{baseUrl}}}", +{{#vue}} + statesHook: vueHook, +{{/vue}} +{{#react}} + statesHook: reactHook, +{{/react}} + requestAdapter: GlobalFetch(), + beforeRequest: method => {}, + responded: res => { + return res.json(); + } +}); +const $$userConfigMap = withConfigType({}); + +/** + * @type {{#raw "{ " }}{{/raw}}{{{global}}}{{#raw " }" }}{{/raw}} + */ +const Apis = createApis(alovaInstance, $$userConfigMap); + +module.exports = { + Apis, + alovaInstance, + $$userConfigMap +}; \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/commonjs/v3-createApis.handlebars b/alova-vscode-extension-0.0.3/extension/templates/commonjs/v3-createApis.handlebars new file mode 100644 index 0000000..45f0535 --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/templates/commonjs/v3-createApis.handlebars @@ -0,0 +1,75 @@ +{{{commentText}}} +const { Method } = require('alova'); +const apiDefinitions = require('./apiDefinitions'); +/** + * @typedef {import('alova').AlovaGenerics} AlovaGenerics + */ +/** + * + * @param {(string|symbol)[]} array + * @param {Alova} alovaInstance + * @param {any} configMap + * @returns {()=>void} + */ +const createFunctionalProxy = (array, alovaInstance, configMap) => { + // create a new proxy instance + return new Proxy(function () {}, { + get(_, property) { + // record the target property, so that it can get the completed accessing paths + array.push(property); + // always return a new proxy to continue recording accessing paths. + return createFunctionalProxy(array, alovaInstance, configMap); + }, + apply(_, __, [config]) { + const apiItem = apiDefinitions[array.join('.')]; + if (!apiItem) { + throw new Error(`the api path of \`${apiItem}\` is not found`); + } + const [method, url] = apiItem; + const { pathParams, data } = config; + const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => { + const pathParam = pathParams[key]; + return pathParam; + }); + delete config.pathParams; + return new Method(method.toUpperCase(), alovaInstance, urlReplaced, config, data); + } + }); +}; +/** + * + * @param {Alova} alovaInstance + * @param {any} configMap + * @returns + */ +const createApis = (alovaInstance, configMap) =>{ + const Apis = new Proxy( + {}, + { + get(_, property) { + return createFunctionalProxy([property], alovaInstance, configMap); + } + } + ); + // 如果是全局定义 + globalThis.{{{global}}} = Apis; + return Apis; +} +/** + * @template T + * @typedef {import('alova').AlovaMethodCreateConfig ? AG : any, any, T>} MethodConfig + */ +/** + * @typedef {{#raw "{{ " }}{{/raw}}[P in keyof typeof import('./apiDefinitions')]?: MethodConfig

[0]['transform']>[0] : any>{{#raw " }}" }}{{/raw}} MethodsConfigMap + */ +/** + * @template {MethodsConfigMap} Config + * @param {Config} config + */ +const withConfigType = config => config; + +module.exports = { + createApis, + withConfigType +}; + diff --git a/alova-vscode-extension-0.0.3/extension/templates/commonjs/v3-index.handlebars b/alova-vscode-extension-0.0.3/extension/templates/commonjs/v3-index.handlebars new file mode 100644 index 0000000..4a3909c --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/templates/commonjs/v3-index.handlebars @@ -0,0 +1,35 @@ +const { createAlova } = require('alova'); +const fetchAdapter = require('alova/fetch'); +{{#vue}} +const vueHook = require('alova/vue'); +{{/vue}} +{{#react}} +const reactHook = require('alova/react'); +{{/react}} +const { createApis, withConfigType } = require('./createApis'); +const alovaInstance = createAlova({ + baseURL: "{{{baseUrl}}}", +{{#vue}} + statesHook: vueHook, +{{/vue}} +{{#react}} + statesHook: reactHook, +{{/react}} + requestAdapter: fetchAdapter(), + beforeRequest: method => {}, + responded: res => { + return res.json(); + } +}); +const $$userConfigMap = withConfigType({}); + +/** + * @type {{#raw "{ " }}{{/raw}}{{{global}}}{{#raw " }" }}{{/raw}} + */ +const Apis = createApis(alovaInstance, $$userConfigMap); + +module.exports = { + Apis, + alovaInstance, + $$userConfigMap +}; \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/globals.d.handlebars b/alova-vscode-extension-0.0.3/extension/templates/globals.d.handlebars new file mode 100644 index 0000000..a9c2e56 --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/templates/globals.d.handlebars @@ -0,0 +1,114 @@ +{{{commentText}}} +import { Alova, AlovaMethodCreateConfig, Method } from 'alova'; +import type { $$userConfigMap, alovaInstance } from '.'; +import type apiDefinitions from './apiDefinitions'; + +type CollapsedAlova = typeof alovaInstance; +type UserMethodConfigMap = typeof $$userConfigMap; + +type Alova2MethodConfig = + CollapsedAlova extends Alova + ? Omit,"params"> + : never; + +// Extract the return type of transformData function that define in $$userConfigMap, if it not exists, use the default type. +type ExtractUserDefinedTransformed< + DefinitionKey extends keyof typeof apiDefinitions, + Default +> = DefinitionKey extends keyof UserMethodConfigMap + ? UserMethodConfigMap[DefinitionKey]['transformData'] extends (...args: any[]) => any + ? Awaited> + : Default + : Default; +type Alova2Method< + Responded, + DefinitionKey extends keyof typeof apiDefinitions, + CurrentConfig extends Alova2MethodConfig +> = + CollapsedAlova extends Alova + ? Method< + State, + Export, + CurrentConfig extends undefined + ? ExtractUserDefinedTransformed + : CurrentConfig['transformData'] extends (...args: any[]) => any + ? Awaited> + : ExtractUserDefinedTransformed, + any, + RequestConfig, + Response, + ResponseHeader + > + : never; + +{{#schemas}} +{{{.}}} +{{/schemas}} +declare global { + interface {{{global}}} { + {{#pathApis}} + {{{tag}}}: { + {{#apis}} + /** + * --- + * + * [{{{method}}}] {{{summary}}} + * + * **path:** {{{path}}} + * + {{#if pathParametersComment}} + * --- + * + * **Path Parameters** + * ```ts + * type PathParameters = {{{pathParametersComment}}} + * ``` + * + {{/if}} + {{#if queryParametersComment}} + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = {{{queryParametersComment}}} + * ``` + * + {{/if}} + {{#if requestComment}} + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = {{{requestComment}}} + * ``` + * + {{/if}} + {{#if responseComment}} + * --- + * + * **Response** + * ```ts + * type Response = {{{responseComment}}} + * ``` + {{/if}} + */ + {{{name}}}{{#or pathParameters queryParameters requestName }} & { + {{#if pathParameters}} + pathParams: {{{pathParameters}}}; + {{/if}} + {{#if queryParameters}} + params: {{{queryParameters}}}; + {{/if}} + {{#if requestName}} + data: {{{requestName}}}; + {{/if}} + }{{/or}}>( + config{{#or pathParameters queryParameters requestName }}{{else}}?{{/or}}: Config + ): Alova2Method<{{{responseName}}}, '{{{pathKey}}}', Config>; + {{/apis}} + }; + {{/pathApis}} + } + + var {{{global}}}: {{{global}}}; +} diff --git a/alova-vscode-extension-0.0.3/extension/templates/module/createApis.handlebars b/alova-vscode-extension-0.0.3/extension/templates/module/createApis.handlebars new file mode 100644 index 0000000..519e769 --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/templates/module/createApis.handlebars @@ -0,0 +1,67 @@ +{{{commentText}}} +import { Method } from 'alova'; +import apiDefinitions from './apiDefinitions'; +/** + * + * @param {(string|symbol)[]} array + * @param {Alova} alovaInstance + * @param {any} configMap + * @returns {()=>void} + */ +const createFunctionalProxy = (array, alovaInstance, configMap) => { + // create a new proxy instance + return new Proxy(function () {}, { + get(_, property) { + // record the target property, so that it can get the completed accessing paths + array.push(property); + // always return a new proxy to continue recording accessing paths. + return createFunctionalProxy(array, alovaInstance, configMap); + }, + apply(_, __, [config]) { + const apiItem = apiDefinitions[array.join('.')]; + if (!apiItem) { + throw new Error(`the api path of \`${apiItem}\` is not found`); + } + const [method, url] = apiItem; + const { pathParams, data } = config; + const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => { + const pathParam = pathParams[key]; + return pathParam; + }); + delete config.pathParams; + return new Method(method.toUpperCase(), alovaInstance, urlReplaced, config, data); + } + }); +}; +/** + * + * @param {Alova} alovaInstance + * @param {any} configMap + * @returns {{#raw "{ " }}{{/raw}}{{{global}}}{{#raw " }" }}{{/raw}} + */ +export const createApis = (alovaInstance, configMap) => { + const Apis = new Proxy( + {}, + { + get(_, property) { + return createFunctionalProxy([property], alovaInstance, configMap); + } + } + ); + // 如果是全局定义 + globalThis.{{{global}}} = Apis; + return Apis; +} + +/** + * @template T + * @typedef {typeof import('./index')['alovaInstance'] extends import('alova').Alova ? import('alova').AlovaMethodCreateConfig : never} MethodConfig + */ +/** + * @typedef {{#raw "{{ " }}{{/raw}}[P in keyof typeof import('./apiDefinitions').default]?: MethodConfig

[0]['transformData']>[0] : any>{{#raw " }}" }}{{/raw}} MethodsConfigMap + */ +/** + * @template {MethodsConfigMap} Config + * @param {Config} config + */ +export const withConfigType = config => config; \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/module/index.handlebars b/alova-vscode-extension-0.0.3/extension/templates/module/index.handlebars new file mode 100644 index 0000000..9e5376f --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/templates/module/index.handlebars @@ -0,0 +1,31 @@ +import { createAlova } from 'alova'; +import GlobalFetch from 'alova/GlobalFetch'; +{{#vue}} +import vueHook from 'alova/vue'; +{{/vue}} +{{#react}} +import reactHook from 'alova/react'; +{{/react}} +import { createApis, withConfigType } from './createApis'; + +export const alovaInstance = createAlova({ + baseURL: "{{{baseUrl}}}", +{{#vue}} + statesHook: vueHook, +{{/vue}} +{{#react}} + statesHook: reactHook, +{{/react}} + requestAdapter: GlobalFetch(), + beforeRequest: method => { }, + responded: res => { return res.json(); } +}); + +export const $$userConfigMap = withConfigType({}); + +/** + * @type {{#raw "{ " }}{{/raw}}{{{global}}}{{#raw " }" }}{{/raw}} + */ +const Apis = createApis(alovaInstance, $$userConfigMap); + +export default Apis; \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/module/v3-createApis.handlebars b/alova-vscode-extension-0.0.3/extension/templates/module/v3-createApis.handlebars new file mode 100644 index 0000000..148828b --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/templates/module/v3-createApis.handlebars @@ -0,0 +1,69 @@ +{{{commentText}}} +import { Method } from 'alova'; +import apiDefinitions from './apiDefinitions'; +/** + * @typedef {import('alova').AlovaGenerics} AlovaGenerics + */ +/** + * + * @param {(string|symbol)[]} array + * @param {Alova} alovaInstance + * @param {any} configMap + * @returns {()=>void} + */ +const createFunctionalProxy = (array, alovaInstance, configMap) => { + // create a new proxy instance + return new Proxy(function () {}, { + get(_, property) { + // record the target property, so that it can get the completed accessing paths + array.push(property); + // always return a new proxy to continue recording accessing paths. + return createFunctionalProxy(array, alovaInstance, configMap); + }, + apply(_, __, [config]) { + const apiItem = apiDefinitions[array.join('.')]; + if (!apiItem) { + throw new Error(`the api path of \`${apiItem}\` is not found`); + } + const [method, url] = apiItem; + const { pathParams, data } = config; + const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => { + const pathParam = pathParams[key]; + return pathParam; + }); + delete config.pathParams; + return new Method(method.toUpperCase(), alovaInstance, urlReplaced, config, data); + } + }); +}; +/** + * + * @param {Alova} alovaInstance + * @param {any} configMap + * @returns {{#raw "{ " }}{{/raw}}{{{global}}}{{#raw " }" }}{{/raw}} + */ +export const createApis = (alovaInstance, configMap) => { + const Apis = new Proxy( + {}, + { + get(_, property) { + return createFunctionalProxy([property], alovaInstance, configMap); + } + } + ); + // 如果是全局定义 + globalThis.{{{global}}} = Apis; + return Apis; +} +/** + * @template T + * @typedef {import('alova').AlovaMethodCreateConfig ? AG : any, any, T>} MethodConfig + */ +/** + * @typedef {{#raw "{{ " }}{{/raw}}[P in keyof typeof import('./apiDefinitions').default]?: MethodConfig

[0]['transform']>[0] : any>{{#raw " }}" }}{{/raw}} MethodsConfigMap + */ +/** + * @template {MethodsConfigMap} Config + * @param {Config} config + */ +export const withConfigType = config => config; \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/module/v3-index.handlebars b/alova-vscode-extension-0.0.3/extension/templates/module/v3-index.handlebars new file mode 100644 index 0000000..6952e81 --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/templates/module/v3-index.handlebars @@ -0,0 +1,33 @@ +import { createAlova } from 'alova'; +import fetchAdapter from 'alova/fetch'; +{{#vue}} +import vueHook from 'alova/vue'; +{{/vue}} +{{#react}} +import reactHook from 'alova/react'; +{{/react}} +import { createApis, withConfigType } from './createApis'; + +export const alovaInstance = createAlova({ + baseURL: "{{{baseUrl}}}", +{{#vue}} + statesHook: vueHook, +{{/vue}} +{{#react}} + statesHook: reactHook, +{{/react}} + requestAdapter: fetchAdapter(), + beforeRequest: method => { }, + responded: res => { + return res.json(); + } +}); + +export const $$userConfigMap = withConfigType({}); + +/** + * @type {{#raw "{ " }}{{/raw}}{{{global}}}{{#raw " }" }}{{/raw}} + */ +const Apis = createApis(alovaInstance, $$userConfigMap); + +export default Apis; \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/typescript/createApis.handlebars b/alova-vscode-extension-0.0.3/extension/templates/typescript/createApis.handlebars new file mode 100644 index 0000000..8fc3687 --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/templates/typescript/createApis.handlebars @@ -0,0 +1,61 @@ +{{{commentText}}} +import { Alova, Method, MethodType, AlovaMethodCreateConfig } from 'alova'; +import apiDefinitions from './apiDefinitions'; + +const createFunctionalProxy = ( + array: (string | symbol)[], + alovaInstance: Alova, + configMap: any +) => { + // create a new proxy instance + return new Proxy(function () {}, { + get(_, property) { + // record the target property, so that it can get the completed accessing paths + array.push(property); + // always return a new proxy to continue recording accessing paths. + return createFunctionalProxy(array, alovaInstance, configMap); + }, + apply(_, __, [config]) { + const apiItem = apiDefinitions[array.join('.')] as string[] | undefined; + if (!apiItem) { + throw new Error(`the api path of \`${apiItem}\` is not found`); + } + const [method, url] = apiItem; + const { pathParams, data } = config; + const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => { + const pathParam = pathParams[key]; + return pathParam; + }); + delete config.pathParams; + return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, config, data); + } + }); +}; + +export const createApis = (alovaInstance: Alova, configMap: any) =>{ + const Apis = new Proxy( + {} as {{{global}}}, + { + get(_, property) { + return createFunctionalProxy([property], alovaInstance, configMap); + } + } + ); + // 如果是全局定义 + (globalThis as any).{{{global}}} = Apis; + return Apis; +} +type MethodConfig = typeof import('./index')['alovaInstance'] extends Alova ? import('alova').AlovaMethodCreateConfig : never; +type APISofParameters = Tag extends keyof {{{global}}} + ? Url extends keyof {{{global}}}[Tag] + ? {{{global}}}[Tag][Url] extends (...args: any) => any + ? Parameters<{{{global}}}[Tag][Url]> + : any + : any + : any; +type MethodsConfigMap = { + [P in keyof typeof import('./apiDefinitions').default]?: MethodConfig< + P extends `${infer Tag}.${infer Url}` ? Parameters[0]['transformData']>[0] : any + >; +}; +export const withConfigType = (config: Config) => config; \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/typescript/index.handlebars b/alova-vscode-extension-0.0.3/extension/templates/typescript/index.handlebars new file mode 100644 index 0000000..2cc1a07 --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/templates/typescript/index.handlebars @@ -0,0 +1,30 @@ +import { createAlova } from 'alova'; +import GlobalFetch from 'alova/GlobalFetch'; +{{#vue}} +import vueHook from 'alova/vue'; +{{/vue}} +{{#react}} +import reactHook from 'alova/react'; +{{/react}} +import { createApis, withConfigType } from './createApis'; + +export const alovaInstance = createAlova({ + baseURL: "{{{baseUrl}}}", +{{#vue}} + statesHook: vueHook, +{{/vue}} +{{#react}} + statesHook: reactHook, +{{/react}} + requestAdapter: GlobalFetch(), + beforeRequest: method => { }, + responded: res => { + return res.json(); + } +}); + +export const $$userConfigMap = withConfigType({}); + +const Apis = createApis(alovaInstance, $$userConfigMap); + +export default Apis; \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/typescript/v3-createApis.handlebars b/alova-vscode-extension-0.0.3/extension/templates/typescript/v3-createApis.handlebars new file mode 100644 index 0000000..6504b05 --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/templates/typescript/v3-createApis.handlebars @@ -0,0 +1,61 @@ +{{{commentText}}} +import { Alova, Method, MethodType, AlovaMethodCreateConfig, AlovaGenerics } from 'alova'; +import apiDefinitions from './apiDefinitions'; + +const createFunctionalProxy = ( + array: (string | symbol)[], + alovaInstance: Alova, + configMap: any +) => { + // create a new proxy instance + return new Proxy(function () {}, { + get(_, property) { + // record the target property, so that it can get the completed accessing paths + array.push(property); + // always return a new proxy to continue recording accessing paths. + return createFunctionalProxy(array, alovaInstance, configMap); + }, + apply(_, __, [config]) { + const apiItem = apiDefinitions[array.join('.')] as string[] | undefined; + if (!apiItem) { + throw new Error(`the api path of \`${apiItem}\` is not found`); + } + const [method, url] = apiItem; + const { pathParams, data } = config; + const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => { + const pathParam = pathParams[key]; + return pathParam; + }); + delete config.pathParams; + return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, config, data); + } + }); +}; + +export const createApis = (alovaInstance: Alova, configMap: any) =>{ + const Apis = new Proxy( + {} as {{{global}}}, + { + get(_, property) { + return createFunctionalProxy([property], alovaInstance, configMap); + } + } + ); + // 如果是全局定义 + (globalThis as any).{{{global}}} = Apis; + return Apis; +} +type MethodConfig = AlovaMethodCreateConfig ? AG : any, any, T>; +type APISofParameters = Tag extends keyof {{{global}}} + ? Url extends keyof {{{global}}}[Tag] + ? {{{global}}}[Tag][Url] extends (...args: any) => any + ? Parameters<{{{global}}}[Tag][Url]> + : any + : any + : any; +type MethodsConfigMap = { + [P in keyof typeof import('./apiDefinitions').default]?: MethodConfig< + P extends `${infer Tag}.${infer Url}` ? Parameters[0]['transform']>[0] : any + >; +}; +export const withConfigType = (config: Config) => config; diff --git a/alova-vscode-extension-0.0.3/extension/templates/typescript/v3-index.handlebars b/alova-vscode-extension-0.0.3/extension/templates/typescript/v3-index.handlebars new file mode 100644 index 0000000..77aef01 --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/templates/typescript/v3-index.handlebars @@ -0,0 +1,30 @@ +import { createAlova } from 'alova'; +import fetchAdapter from 'alova/fetch'; +{{#vue}} +import vueHook from 'alova/vue'; +{{/vue}} +{{#react}} +import reactHook from 'alova/react'; +{{/react}} +import { createApis, withConfigType } from './createApis'; + +export const alovaInstance = createAlova({ + baseURL: "{{{baseUrl}}}", +{{#vue}} + statesHook: vueHook, +{{/vue}} +{{#react}} + statesHook: reactHook, +{{/react}} + requestAdapter: fetchAdapter(), + beforeRequest: method => { }, + responded: res => { + return res.json(); + } +}); + +export const $$userConfigMap = withConfigType({}); + +const Apis = createApis(alovaInstance, $$userConfigMap); + +export default Apis; \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/v3-globals.d.handlebars b/alova-vscode-extension-0.0.3/extension/templates/v3-globals.d.handlebars new file mode 100644 index 0000000..56e27d7 --- /dev/null +++ b/alova-vscode-extension-0.0.3/extension/templates/v3-globals.d.handlebars @@ -0,0 +1,146 @@ +{{{commentText}}} +import { Alova, AlovaMethodCreateConfig, AlovaGenerics, Method } from 'alova'; +import type { $$userConfigMap, alovaInstance } from '.'; +import type apiDefinitions from './apiDefinitions'; + +type CollapsedAlova = typeof alovaInstance; +type UserMethodConfigMap = typeof $$userConfigMap; + +type Alova2MethodConfig = + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Omit< + AlovaMethodCreateConfig< + AlovaGenerics, + any, + Responded + >, + 'params' + > + : never; + +// Extract the return type of transform function that define in $$userConfigMap, if it not exists, use the default type. +type ExtractUserDefinedTransformed< + DefinitionKey extends keyof typeof apiDefinitions, + Default +> = DefinitionKey extends keyof UserMethodConfigMap + ? UserMethodConfigMap[DefinitionKey]['transform'] extends (...args: any[]) => any + ? Awaited> + : Default + : Default; +type Alova2Method< + Responded, + DefinitionKey extends keyof typeof apiDefinitions, + CurrentConfig extends Alova2MethodConfig +> = + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Method< + AlovaGenerics< + CurrentConfig extends undefined + ? ExtractUserDefinedTransformed + : CurrentConfig['transform'] extends (...args: any[]) => any + ? Awaited> + : ExtractUserDefinedTransformed, + any, + RequestConfig, + Response, + ResponseHeader, + L1Cache, + L2Cache, + SE + > + > + : never; + +{{#schemas}} +{{{.}}} +{{/schemas}} +declare global { + interface {{{global}}} { + {{#pathApis}} + {{{tag}}}: { + {{#apis}} + /** + * --- + * + * [{{{method}}}] {{{summary}}} + * + * **path:** {{{path}}} + * + {{#if pathParametersComment}} + * --- + * + * **Path Parameters** + * ```ts + * type PathParameters = {{{pathParametersComment}}} + * ``` + * + {{/if}} + {{#if queryParametersComment}} + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = {{{queryParametersComment}}} + * ``` + * + {{/if}} + {{#if requestComment}} + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = {{{requestComment}}} + * ``` + * + {{/if}} + {{#if responseComment}} + * --- + * + * **Response** + * ```ts + * type Response = {{{responseComment}}} + * ``` + {{/if}} + */ + {{{name}}}{{#or pathParameters queryParameters requestName }} & { + {{#if pathParameters}} + pathParams: {{{pathParameters}}}; + {{/if}} + {{#if queryParameters}} + params: {{{queryParameters}}}; + {{/if}} + {{#if requestName}} + data: {{{requestName}}}; + {{/if}} + }{{/or}}>( + config{{#or pathParameters queryParameters requestName }}{{else}}?{{/or}}: Config + ): Alova2Method<{{{responseName}}}, '{{{pathKey}}}', Config>; + {{/apis}} + }; + {{/pathApis}} + } + + var {{{global}}}: {{{global}}}; +} diff --git a/src/extension.ts b/src/extension.ts index 3667767..e0b3a46 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -6,6 +6,7 @@ import setup from './commands/setup'; import showStatusBarIcon from './commands/showStatusBarIcon'; import Error from './components/error'; import { log } from './components/message'; +import './globalConfig'; const commands = [setup, autocomplete, generateApi, refresh, showStatusBarIcon]; diff --git a/src/functions/autocomplete.ts b/src/functions/autocomplete.ts index 6c48e60..7272863 100644 --- a/src/functions/autocomplete.ts +++ b/src/functions/autocomplete.ts @@ -1,7 +1,8 @@ import { CONFIG_POOL } from '@/modules/Configuration'; -import { TEMPLATE_DATA, getAlovaJsonPath } from '@/modules/TemplateFile'; +import { DEFAULT_CONFIG } from '@/wormhole'; +import { getAlovaJsonPath } from '@/wormhole/functions/alovaJson'; +import { Api } from '@/wormhole/functions/openApi2Data'; import path from 'node:path'; -import { Api } from './openApi2Data'; type AutoCompleteItem = { replaceText: string; @@ -55,7 +56,7 @@ export default (text: string, filePath: string): AutoCompleteItem[] => { return outputArr .map(output => { const apiPath = getAlovaJsonPath(config.workspaceRootDir, output); - const templateData = TEMPLATE_DATA.get(apiPath); + const templateData = DEFAULT_CONFIG.templateData.get(apiPath); if (!templateData) { return []; } diff --git a/src/functions/getTypescript.ts b/src/functions/getTypescript.ts index 81eac92..cf5dc73 100644 --- a/src/functions/getTypescript.ts +++ b/src/functions/getTypescript.ts @@ -2,7 +2,7 @@ import { createRequire } from 'node:module'; import path from 'node:path'; import * as vscode from 'vscode'; -export default () => { +export default async () => { // 获得所有工作区 const workspaceFolders = vscode.workspace.workspaceFolders || []; let typescript: typeof import('typescript') | null = null; diff --git a/src/functions/readConfig.ts b/src/functions/readConfig.ts index d552584..768a801 100644 --- a/src/functions/readConfig.ts +++ b/src/functions/readConfig.ts @@ -2,6 +2,7 @@ import Error from '@/components/error'; import message from '@/components/message'; import { CONFIG_POOL, Configuration } from '@/modules/Configuration'; import { getFileNameByPath } from '@/utils'; +import type { Config } from '@/wormhole'; import { readConfig as baseReadConfig } from '@/wormhole'; import chokidar, { FSWatcher } from 'chokidar'; import * as vscode from 'vscode'; @@ -43,7 +44,7 @@ export function createWatcher(workspaceRootPath: string) { }); } export async function readConfig(workspaceRootPath: string, isShowError = true, createWatch = true) { - let alovaConfig: AlovaConfig | null = null; + let alovaConfig: Config | null = null; if (createWatch) { // 如果监听器存在则先关闭 if (!WATCH_CONFIG.has(workspaceRootPath)) { diff --git a/src/globalConfig.ts b/src/globalConfig.ts index 1b6add1..1a64474 100644 --- a/src/globalConfig.ts +++ b/src/globalConfig.ts @@ -1,10 +1,13 @@ +import getTypescript from '@/functions/getTypescript'; import path from 'node:path'; import { pathToFileURL } from 'node:url'; - -export const frameworkName: ['vue', 'react'] = ['vue', 'react']; +import { DEFAULT_CONFIG } from './wormhole'; // work.js线程路径 export const WORK_PATH = pathToFileURL(path.join(__dirname, '/work.js')); // 渲染模板路径 export const TEMPLATE_PATH = path.join(__dirname, '../templates'); // alova临时文件路径 export const ALOVA_TEMP_PATH = path.join('node_modules/.alova'); +DEFAULT_CONFIG.alovaTempPath = ALOVA_TEMP_PATH; +DEFAULT_CONFIG.templatePath = TEMPLATE_PATH; +DEFAULT_CONFIG.getTypescript = getTypescript; diff --git a/src/utils/index.ts b/src/utils/index.ts index 08d6780..e69de29 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,156 +0,0 @@ -/* eslint-disable no-bitwise */ -import prettierConfig from '#/prettier.config.cjs'; -import Error from '@/components/error'; -import handlebars, { HelperOptions } from 'handlebars'; -import fetch from 'node-fetch'; -import fs, { promises } from 'node:fs'; -import path from 'node:path'; -import { Config as PrettierConfig } from 'prettier'; -import * as prettierBabel from 'prettier/plugins/babel'; -import * as prettierEsTree from 'prettier/plugins/estree'; -import * as prettierTs from 'prettier/plugins/typescript'; -import * as prettier from 'prettier/standalone'; - -export const getType = (obj: any) => Object.prototype.toString.call(obj).slice(8, -1).toLowerCase(); -handlebars.registerHelper('isType', function (this: any, value, type: string, options: HelperOptions) { - if (getType(value) === type) { - return options.fn(this); - } - return options.inverse(this); -}); -handlebars.registerHelper('and', function (this: any, ...rest) { - const args = Array.prototype.slice.call(rest, 0, -1); - const options = rest[rest.length - 1] as HelperOptions; - const result = args.every(arg => { - if (Array.isArray(arg)) { - return arg.length === 0; - } - return Boolean(arg); - }); - return result ? options.fn(this) : options.inverse(this); -}); -handlebars.registerHelper('or', function (this: any, ...rest) { - const args = Array.prototype.slice.call(rest, 0, -1); - const options = rest[rest.length - 1] as HelperOptions; - const result = args.some(arg => { - if (Array.isArray(arg)) { - return arg.length !== 0; - } - return Boolean(arg); - }); - return result ? options.fn(this) : options.inverse(this); -}); -handlebars.registerHelper('eq', (a, b) => a === b); -// 注册自定义助手函数 'raw' -handlebars.registerHelper( - 'raw', - text => - // 返回原始字符串,不进行 HTML 转义 - new handlebars.SafeString(text) -); -/** - * 读取并渲染 handlebars 文件 - * @param templatePath 模板文件路径 - * @param view - 渲染模板所需的数据对象 - * @returns 渲染后的内容 - */ -export async function readAndRenderTemplate(templatePath: string, view: any): Promise { - const data = await promises.readFile(templatePath, 'utf-8'); - return handlebars.compile(data)(view); -} -export async function format(text: string, config?: PrettierConfig) { - return prettier.format(text, { - ...(prettierConfig as PrettierConfig), - parser: 'typescript', // 指定使用 babel 解析器 - ...(config ?? {}), - plugins: [prettierTs, prettierEsTree, prettierBabel] - }); -} -/** - * 传入文本内容,在指定目录下生成自定义文件 - * @param distDir 待生成文件所在目录 - * @param fileName 待生成文件名 - * @param content 文件内容 - */ -export async function generateFile(distDir: string, fileName: string, content: string) { - if (!fs.existsSync(distDir)) { - fs.mkdirSync(distDir, { recursive: true }); - } - const filePath = path.join(distDir, fileName); - const formattedText = await format(content); - fs.writeFile(filePath, formattedText, (err: NodeJS.ErrnoException | null) => { - if (err) { - return console.error('Error writing file:', err); - } - console.log('File written successfully at', filePath); - }); -} -export async function fetchData(url: string) { - return fetch(url).then(response => { - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - return response.text(); - }); -} - -export function highPrecisionInterval(callback: () => void, intervalInMilliseconds: number, immediate = false) { - let isRunning = true; - if (immediate) { - callback(); - } - const timer = setInterval(callback, intervalInMilliseconds); - - return { - isRunning() { - return isRunning; - }, - clear() { - isRunning = false; - clearInterval(timer); - }, - time: intervalInMilliseconds, - immediate - }; -} -export const getFileNameByPath = (path: string) => { - const [, name] = /[/\\]([^/\\]+)([/\\])?$/.exec(path) ?? []; - return name ?? ''; -}; -// 去掉所有为空的undefined值 -export function removeUndefined(obj: T) { - const defaultObject = Array.isArray(obj) ? [] : {}; - if (typeof obj !== 'object' || !obj) { - return obj; - } - return Object.keys(obj).reduce((result, key) => { - const value = removeUndefined((obj as any)[key]); - if (value !== undefined) { - (result as any)[key] = value; - } - return result; - }, defaultObject) as T; -} - -// 生成唯一id -export function uuid() { - let dt = new Date().getTime(); - const id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { - const r = (dt + Math.random() * 16) % 16 | 0; - dt = Math.floor(dt / 16); - return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16); - }); - return id; -} -// 反序列化 -export function deserialize(serializedJavascript: string) { - // eslint-disable-next-line no-eval - return eval(`(${serializedJavascript})`); -} -export function isEmpty(value: any) { - return value === null || value === undefined || value === ''; -} -export function capitalizeFirstLetter(str: string) { - if (!str) return str; - return str.charAt(0).toUpperCase() + str.slice(1); -} diff --git a/src/utils/work.ts b/src/utils/work.ts deleted file mode 100644 index 20a0f58..0000000 --- a/src/utils/work.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** - * 注意:work.js 子线程不能使用任何vscode模块, - * work.js只是用来处理数据的,比如动态import等 - * import xxx from "vscode" 不能使用 - * 本文件只是专门提供给work.js使用工具包 - */ - -/** vscode主线程中不能使用动态import,但是work.js子线程可以使用动态import - * https://github.com/prettier/prettier-vscode/pull/3016 - * 主线程中使用:alovaWork.importEsmModule("foo") 代替import("foo") - * @param modulePath 模块路径 - * @returns 模块对象 - */ -// 加载ESM 模块 -export function loadEsmModule(modulePath: string | URL): Promise { - return new Function('modulePath', `return import(modulePath);`)(modulePath) as Promise; -} -export default { loadEsmModule }; diff --git a/src/wormhole/config.ts b/src/wormhole/config.ts new file mode 100644 index 0000000..f91f1a1 --- /dev/null +++ b/src/wormhole/config.ts @@ -0,0 +1,16 @@ +import { TEMPLATE_DATA } from '@/wormhole/modules/TemplateFile'; +import path from 'node:path'; + +export const DEFAULT_CONFIG = { + alovaTempPath: path.join('node_modules/.alova'), + templatePath: path.join(__dirname, '../../templates'), + getTypescript: async () => { + let ts: typeof import('typescript') | null = null; + try { + ts = (await import('typescript')).default; + } catch (error) {} + return ts; + }, + templateData: TEMPLATE_DATA +}; +export default { DEFAULT_CONFIG }; diff --git a/src/wormhole/createConfig.ts b/src/wormhole/createConfig.ts index 58ef02e..048386c 100644 --- a/src/wormhole/createConfig.ts +++ b/src/wormhole/createConfig.ts @@ -1,6 +1,6 @@ -import getAlovaVersion, { AlovaVersion } from '@/functions/getAlovaVersion'; -import getAutoTemplateType from '@/functions/getAutoTemplateType'; -import { TemplateFile } from '@/modules/TemplateFile'; +import getAlovaVersion, { AlovaVersion } from '@/wormhole/functions/getAlovaVersion'; +import getAutoTemplateType from '@/wormhole/functions/getAutoTemplateType'; +import TemplateFile from '@/wormhole/modules/TemplateFile'; export const createConfig = async (projectPath: string) => { const type = getAutoTemplateType(projectPath); @@ -8,7 +8,6 @@ export const createConfig = async (projectPath: string) => { const templateFile = new TemplateFile(type, alovaVersion); return templateFile.outputFile({}, 'alova.config', projectPath, { root: true, - ext: '.ts', hasVersion: false }); }; diff --git a/src/wormhole/functions/alovaJson.ts b/src/wormhole/functions/alovaJson.ts new file mode 100644 index 0000000..1f51698 --- /dev/null +++ b/src/wormhole/functions/alovaJson.ts @@ -0,0 +1,44 @@ +import { DEFAULT_CONFIG } from '@/wormhole'; +import type { TemplateData } from '@/wormhole/functions/openApi2Data'; +import { format } from '@/wormhole/utils'; +import fs from 'node:fs'; +import path from 'node:path'; + +export const writeAlovaJson = async (data: TemplateData, originPath: string, name = 'api.json') => { + // 将数据转换为 JSON 字符串 + const jsonData = await format(JSON.stringify(data, null, 2), { parser: 'json' }); + // 定义 JSON 文件的路径和名称 + const filePath = `${originPath}_${name}`; + const dirPath = filePath.split(/\/|\\/).slice(0, -1).join('/'); + if (!fs.existsSync(dirPath)) { + fs.mkdirSync(dirPath, { recursive: true }); + } + // 使用 fs.writeFile 将 JSON 数据写入文件 + fs.writeFile(filePath, jsonData, err => { + if (err) { + console.error('Error writing file:', err); + } else { + console.log('JSON file has been saved.'); + } + }); +}; +export const readAlovaJson = (originPath: string, name = 'api.json') => { + // 定义 JSON 文件的路径和名称 + const filePath = `${originPath}_${name}`; + return new Promise((resolve, reject) => { + if (!fs.existsSync(filePath)) { + reject(new Error('alovaJson not exists')); + return; + } + // 使用 fs.readFile 读取 JSON 文件 + fs.readFile(filePath, 'utf8', (err, data) => { + if (err) { + reject(err); + } else { + resolve(JSON.parse(data)); + } + }); + }); +}; +export const getAlovaJsonPath = (workspaceRootDir: string, outputPath: string) => + path.join(workspaceRootDir, DEFAULT_CONFIG.alovaTempPath, outputPath.split(/\/|\\/).join('_')); diff --git a/src/functions/generateApi.ts b/src/wormhole/functions/generateApi.ts similarity index 74% rename from src/functions/generateApi.ts rename to src/wormhole/functions/generateApi.ts index e248656..550f73f 100644 --- a/src/functions/generateApi.ts +++ b/src/wormhole/functions/generateApi.ts @@ -1,6 +1,8 @@ -import openApi2Data from '@/functions/openApi2Data'; -import { getAlovaJsonPath, TEMPLATE_DATA, TemplateFile, writeAlovaJson } from '@/modules/TemplateFile'; -import type { TemplateType } from '@/wormhole'; +import type { GeneratorConfig, TemplateType } from '@/wormhole'; +import { DEFAULT_CONFIG } from '@/wormhole'; +import { getAlovaJsonPath, writeAlovaJson } from '@/wormhole/functions/alovaJson'; +import openApi2Data from '@/wormhole/functions/openApi2Data'; +import TemplateFile from '@/wormhole/modules/TemplateFile'; import { isEqual } from 'lodash'; import fs from 'node:fs'; import path from 'node:path'; @@ -9,12 +11,12 @@ import getAlovaVersion, { AlovaVersion } from './getAlovaVersion'; import getFrameworkTag from './getFrameworkTag'; export default async function ( - workspaceRootDir: string, - outputPath: string, - data: OpenAPIV3_1.Document, - config: GeneratorConfig, - type: TemplateType, - force = false + workspaceRootDir: string, // 项目地址 + outputPath: string, // 输出路径 + data: OpenAPIV3_1.Document, // openapi数据 + config: GeneratorConfig, // generator配置 + type: TemplateType, // 模板类型 + force: boolean // 是否强制生成 ) { if (!data) { return; @@ -44,11 +46,11 @@ export default async function ( templateData.alovaVersion = alovaVersion; // 是否需要生成api文件 // 判断是否需要生成api文件 - if (!force && isEqual(templateData, TEMPLATE_DATA.get(alovaJsonPath))) { + if (!force && isEqual(templateData, DEFAULT_CONFIG.templateData.get(alovaJsonPath))) { return false; } // 保存templateData - TEMPLATE_DATA.set(alovaJsonPath, templateData); + DEFAULT_CONFIG.templateData.set(alovaJsonPath, templateData); // 生成alova.json文件 writeAlovaJson(templateData, alovaJsonPath); // 获取是否存在index.ts|index.js diff --git a/src/functions/getAlovaVersion.ts b/src/wormhole/functions/getAlovaVersion.ts similarity index 100% rename from src/functions/getAlovaVersion.ts rename to src/wormhole/functions/getAlovaVersion.ts diff --git a/src/functions/getAutoTemplateType.ts b/src/wormhole/functions/getAutoTemplateType.ts similarity index 100% rename from src/functions/getAutoTemplateType.ts rename to src/wormhole/functions/getAutoTemplateType.ts diff --git a/src/functions/getFrameworkTag.ts b/src/wormhole/functions/getFrameworkTag.ts similarity index 92% rename from src/functions/getFrameworkTag.ts rename to src/wormhole/functions/getFrameworkTag.ts index 99236f4..99470a6 100644 --- a/src/functions/getFrameworkTag.ts +++ b/src/wormhole/functions/getFrameworkTag.ts @@ -1,8 +1,8 @@ -import { frameworkName } from '@/globalConfig'; import { createRequire } from 'node:module'; import path from 'node:path'; import { PackageJson } from 'type-fest'; +export const frameworkName: ['vue', 'react'] = ['vue', 'react']; export default function (workspaceRootDir: string) { const workspacedRequire = createRequire(workspaceRootDir); const packageJson: PackageJson = workspacedRequire('./package.json'); diff --git a/src/functions/getOpenApiData.ts b/src/wormhole/functions/getOpenApiData.ts similarity index 97% rename from src/functions/getOpenApiData.ts rename to src/wormhole/functions/getOpenApiData.ts index aa16e44..48fced5 100644 --- a/src/functions/getOpenApiData.ts +++ b/src/wormhole/functions/getOpenApiData.ts @@ -1,6 +1,5 @@ -import Error from '@/components/error'; -import { fetchData } from '@/utils'; import type { PlatformType } from '@/wormhole'; +import { fetchData } from '@/wormhole/utils'; import importFresh from 'import-fresh'; import YAML from 'js-yaml'; import fs from 'node:fs'; diff --git a/src/functions/openApi2Data.ts b/src/wormhole/functions/openApi2Data.ts similarity index 96% rename from src/functions/openApi2Data.ts rename to src/wormhole/functions/openApi2Data.ts index 6c1f6ef..0816b8b 100644 --- a/src/functions/openApi2Data.ts +++ b/src/wormhole/functions/openApi2Data.ts @@ -1,10 +1,16 @@ import { log } from '@/components/message'; -import { findBy$ref, getStandardRefName, isReferenceObject, mergeObject, removeAll$ref } from '@/helper/openapi'; -import { convertToType, jsonSchema2TsStr } from '@/helper/schema2type'; -import { getStandardOperationId, getStandardTags } from '@/helper/standard'; -import { generateDefaultValues } from '@/helper/typeStr'; -import { format, removeUndefined } from '@/utils'; -import type { ApiDescriptor } from '@/wormhole'; +import type { ApiDescriptor, GeneratorConfig } from '@/wormhole'; +import { + findBy$ref, + getStandardRefName, + isReferenceObject, + mergeObject, + removeAll$ref +} from '@/wormhole/helper/openapi'; +import { convertToType, jsonSchema2TsStr } from '@/wormhole/helper/schema2type'; +import { getStandardOperationId, getStandardTags } from '@/wormhole/helper/standard'; +import { generateDefaultValues } from '@/wormhole/helper/typeStr'; +import { format, removeUndefined } from '@/wormhole/utils'; import { cloneDeep } from 'lodash'; import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'; import { AlovaVersion } from './getAlovaVersion'; diff --git a/src/wormhole/generate.ts b/src/wormhole/generate.ts index 74b89e8..ef6ef4f 100644 --- a/src/wormhole/generate.ts +++ b/src/wormhole/generate.ts @@ -1,7 +1,8 @@ -import generateApi from '@/functions/generateApi'; -import { Configuration } from '@/modules/Configuration'; +import generateApi from '@/wormhole/functions/generateApi'; +import Configuration from '@/wormhole/modules/Configuration'; +import type { Config, GenerateApiOptions } from './type'; -export const generate = async (projectPath: string, config?: AlovaConfig, options = { force: false }) => { +export const generate = async (projectPath: string, config: Config, options?: GenerateApiOptions) => { if (!config) { return; } @@ -21,7 +22,7 @@ export const generate = async (projectPath: string, config?: AlovaConfig, option openApiData[idx], generatorConfigArr[idx], templateTypeArr[idx] ?? 'commonjs', - options.force + options?.force ?? false ) ) ); diff --git a/src/helper/lodaders.ts b/src/wormhole/helper/lodaders.ts similarity index 91% rename from src/helper/lodaders.ts rename to src/wormhole/helper/lodaders.ts index b7b7cad..9771632 100644 --- a/src/helper/lodaders.ts +++ b/src/wormhole/helper/lodaders.ts @@ -1,17 +1,15 @@ -import Error from '@/components/error'; -import getTypescript from '@/functions/getTypescript'; -import { ALOVA_TEMP_PATH } from '@/globalConfig'; +import { DEFAULT_CONFIG } from '@/wormhole'; +import { loadEsmModule } from '@/wormhole/utils'; import { Loader, LoaderSync } from 'cosmiconfig'; import importFresh from 'import-fresh'; import { existsSync, mkdirSync } from 'node:fs'; import { rm, writeFile } from 'node:fs/promises'; import path from 'node:path'; import { pathToFileURL } from 'node:url'; -import { alovaWork } from './work'; let typescript: typeof import('typescript'); export const loadTs: Loader = async function loadTs(filepath, content) { - const ts = getTypescript(); + const ts = await DEFAULT_CONFIG.getTypescript(); if (typescript === undefined && ts) { typescript = ts; } @@ -40,7 +38,7 @@ export const loadJsSync: LoaderSync = importFresh; export const loadEsModule = async (filepath: string) => { const { href } = pathToFileURL(filepath); - return (await alovaWork.importEsmModule(`${href}?t=${Date.now()}`)).default; + return (await loadEsmModule(`${href}?t=${Date.now()}`)).default; }; export const createTempFile = async ( filepath: string, @@ -49,7 +47,7 @@ export const createTempFile = async ( callback?: (compiledFilepath: string) => T | Promise ) => { const parsedPath = path.parse(filepath); - const addPath = ALOVA_TEMP_PATH; + const addPath = DEFAULT_CONFIG.alovaTempPath; const dirPath = path.join(parsedPath.dir, parsedPath.dir.includes(addPath) ? '' : addPath); const compiledFilepath = path.join(dirPath, `${Date.now()}-${Math.random().toString(16).slice(2)}.${ext}`); if (!existsSync(dirPath)) { diff --git a/src/helper/openapi.ts b/src/wormhole/helper/openapi.ts similarity index 99% rename from src/helper/openapi.ts rename to src/wormhole/helper/openapi.ts index 1bd3106..a63e500 100644 --- a/src/helper/openapi.ts +++ b/src/wormhole/helper/openapi.ts @@ -1,4 +1,4 @@ -import { capitalizeFirstLetter } from '@/utils'; +import { capitalizeFirstLetter } from '@/wormhole/utils'; import { cloneDeep, isArray, isEqualWith, isObject, mergeWith, sortBy } from 'lodash'; import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'; import { isValidJSIdentifier, makeIdentifier } from './standard'; diff --git a/src/helper/schema2type.ts b/src/wormhole/helper/schema2type.ts similarity index 98% rename from src/helper/schema2type.ts rename to src/wormhole/helper/schema2type.ts index d52fc3b..3100dd3 100644 --- a/src/helper/schema2type.ts +++ b/src/wormhole/helper/schema2type.ts @@ -1,4 +1,4 @@ -import { format } from '@/utils'; +import { format } from '@/wormhole/utils'; import { OpenAPIV3_1 } from 'openapi-types'; import { findBy$ref, getStandardRefName, isReferenceObject } from './openapi'; import { isValidJSIdentifier } from './standard'; @@ -135,8 +135,8 @@ function parseSchema( } else { result = typeof schema.type === 'string' - ? ((schema.type || config.defaultType) ?? 'unknown') - : (config.defaultType ?? 'unknown'); + ? (schema.type || config.defaultType) ?? 'unknown' + : config.defaultType ?? 'unknown'; } } if (refPath) { diff --git a/src/helper/standard.ts b/src/wormhole/helper/standard.ts similarity index 100% rename from src/helper/standard.ts rename to src/wormhole/helper/standard.ts diff --git a/src/helper/typeStr.ts b/src/wormhole/helper/typeStr.ts similarity index 99% rename from src/helper/typeStr.ts rename to src/wormhole/helper/typeStr.ts index b918a37..29882d0 100644 --- a/src/helper/typeStr.ts +++ b/src/wormhole/helper/typeStr.ts @@ -1,4 +1,4 @@ -import { format } from '@/utils'; +import { format } from '@/wormhole/utils'; // 去除注释 function removeComments(content: string) { // 去除单行注释 diff --git a/src/wormhole/index.ts b/src/wormhole/index.ts index 47b7fee..8a764b5 100644 --- a/src/wormhole/index.ts +++ b/src/wormhole/index.ts @@ -1,3 +1,4 @@ +export * from './config'; export * from './createConfig'; export * from './generate'; export * from './readConfig'; diff --git a/src/modules/Configuration.ts b/src/wormhole/modules/Configuration.ts similarity index 56% rename from src/modules/Configuration.ts rename to src/wormhole/modules/Configuration.ts index 29eb4ce..2781f49 100644 --- a/src/modules/Configuration.ts +++ b/src/wormhole/modules/Configuration.ts @@ -1,26 +1,18 @@ -import generateApi from '@/commands/generateApi'; -import Error from '@/components/error'; -import getAutoTemplateType from '@/functions/getAutoTemplateType'; -import getOpenApiData from '@/functions/getOpenApiData'; -import { isValidJSIdentifier } from '@/helper/standard'; -import { getAlovaJsonPath, readAlovaJson, TEMPLATE_DATA } from '@/modules/TemplateFile'; -import { highPrecisionInterval, isEmpty } from '@/utils'; -import type { TemplateType } from '@/wormhole'; +import type { Config, GeneratorConfig, TemplateType } from '@/wormhole'; +import { DEFAULT_CONFIG } from '@/wormhole'; +import { getAlovaJsonPath, readAlovaJson } from '@/wormhole/functions/alovaJson'; +import getAutoTemplateType from '@/wormhole/functions/getAutoTemplateType'; +import getOpenApiData from '@/wormhole/functions/getOpenApiData'; +import { isValidJSIdentifier } from '@/wormhole/helper/standard'; +import { isEmpty } from '@/wormhole/utils'; import path from 'node:path'; -import * as vscode from 'vscode'; -export const CONFIG_POOL: Array = []; -export class Configuration { - config: AlovaConfig; +export default class Configuration { + config: Config; workspaceRootDir: string; - autoUpdateControl: ReturnType; - - // 是否应该开始更新api - shouldUpdate: boolean; - - constructor(config: AlovaConfig, workspaceRootDir: string) { + constructor(config: Config, workspaceRootDir: string) { // 配置文件 this.config = config; this.workspaceRootDir = workspaceRootDir; @@ -62,7 +54,6 @@ export class Configuration { const { interval } = this.config.autoUpdate; const time = Number(interval); if (Number.isNaN(time)) { - this.closeAutoUpdate(); throw new Error('autoUpdate.interval must be a number'); } if (time <= 0) { @@ -72,7 +63,7 @@ export class Configuration { } } - getTemplateType(generator: GeneratorConfig): TemplateType { + static getTemplateType(workspaceRootDir: string, generator: GeneratorConfig): TemplateType { let type: TemplateType; const configType = generator.type ?? 'auto'; // 根据配置文件中的type来判断模板类型 @@ -85,7 +76,7 @@ export class Configuration { type = 'module'; break; case 'auto': - type = getAutoTemplateType(this.workspaceRootDir); + type = getAutoTemplateType(workspaceRootDir); break; default: type = 'commonjs'; @@ -95,7 +86,7 @@ export class Configuration { } getAllTemplateType() { - return this.config.generator.map(generator => this.getTemplateType(generator)); + return this.config.generator.map(generator => Configuration.getTemplateType(this.workspaceRootDir, generator)); } getAllOutputPath() { @@ -103,16 +94,18 @@ export class Configuration { } // 获取openapi数据 - getOpenApiData(generator: GeneratorConfig) { - return getOpenApiData(this.workspaceRootDir, generator.input, generator.platform); + static getOpenApiData(workspaceRootDir: string, generator: GeneratorConfig) { + return getOpenApiData(workspaceRootDir, generator.input, generator.platform); } // 获取所有openapi数据 getAllOpenApiData() { - return Promise.all(this.config.generator.map(generator => this.getOpenApiData(generator))); + return Promise.all( + this.config.generator.map(generator => Configuration.getOpenApiData(this.workspaceRootDir, generator)) + ); } - private getAutoUpdateConfig() { + getAutoUpdateConfig() { const autoUpdateConfig = this.config.autoUpdate; let time = 60 * 5; // 默认五分钟 let immediate = false; @@ -126,53 +119,16 @@ export class Configuration { }; } - autoUpdate() { - const autoUpdateConfig = this.config.autoUpdate; - if (!autoUpdateConfig) { - return; - } - const { time, immediate } = this.getAutoUpdateConfig(); - this.autoUpdateControl = highPrecisionInterval( - () => { - vscode.commands.executeCommand(generateApi.commandId); - this.shouldUpdate = true; - }, - time * 1000, - immediate - ); - this.autoUpdateControl.time = time; - return this.autoUpdateControl; - } - - closeAutoUpdate() { - this.autoUpdateControl?.clear?.(); - } - - refreshAutoUpdate() { - const autoUpdateConfig = this.config.autoUpdate; - if (!autoUpdateConfig) { - this.closeAutoUpdate(); - return; - } - const { time, immediate } = this.getAutoUpdateConfig(); - const { time: oldTime, immediate: oldImmediate, isRunning } = this.autoUpdateControl || {}; - if (time === oldTime && oldImmediate === immediate && isRunning()) { - return; - } - this.closeAutoUpdate(); - this.autoUpdate(); - } - readAlovaJson() { const allAlovaJSon = this.config.generator.map(generator => { const alovaJsonPath = getAlovaJsonPath(this.workspaceRootDir, generator.output); return readAlovaJson(alovaJsonPath) .then(alovaJson => { - TEMPLATE_DATA.set(alovaJsonPath, alovaJson); + DEFAULT_CONFIG.templateData.set(alovaJsonPath, alovaJson); return alovaJson; }) .catch(() => { - TEMPLATE_DATA.delete(alovaJsonPath); + DEFAULT_CONFIG.templateData.delete(alovaJsonPath); return {}; }); }); diff --git a/src/modules/TemplateFile.ts b/src/wormhole/modules/TemplateFile.ts similarity index 52% rename from src/modules/TemplateFile.ts rename to src/wormhole/modules/TemplateFile.ts index cd608fc..1241b24 100644 --- a/src/modules/TemplateFile.ts +++ b/src/wormhole/modules/TemplateFile.ts @@ -1,16 +1,11 @@ -import Error from '@/components/error'; -import { AlovaVersion } from '@/functions/getAlovaVersion'; -import { TemplateData } from '@/functions/openApi2Data'; -import { ALOVA_TEMP_PATH, TEMPLATE_PATH } from '@/globalConfig'; -import { format, generateFile, readAndRenderTemplate } from '@/utils'; import type { TemplateType } from '@/wormhole'; +import { DEFAULT_CONFIG } from '@/wormhole'; +import type { AlovaVersion } from '@/wormhole/functions/getAlovaVersion'; +import type { TemplateData } from '@/wormhole/functions/openApi2Data'; +import { generateFile, readAndRenderTemplate } from '@/wormhole/utils'; import { cloneDeep, merge } from 'lodash'; -import fs from 'node:fs'; import path from 'node:path'; -export const TEMPLATE_DATA = new Map(); -export const getAlovaJsonPath = (workspaceRootDir: string, outputPath: string) => - path.join(workspaceRootDir, ALOVA_TEMP_PATH, outputPath.split(/\/|\\/).join('_')); interface RenderTemplateOptions { root?: boolean; hasVersion?: boolean; @@ -21,9 +16,8 @@ const DEFAULT_OPTIONS = { root: false, hasVersion: true }; -export class TemplateFile { - fileName: string; - +export const TEMPLATE_DATA = new Map(); +export default class TemplateFile { type: TemplateType; alovaVersion: AlovaVersion; @@ -34,11 +28,25 @@ export class TemplateFile { this.alovaVersion = alovaVersion; } + private getVersion() { + switch (this.alovaVersion) { + case 'v3': + return 'v3-'; + default: + return ''; + } + } + // 获取生成文件的后缀名 getExt() { return TemplateFile.getExt(this.type); } + // 获取模块类型 + getModuleType() { + return TemplateFile.getModuleType(this.type); + } + static getExt(type: TemplateType) { switch (type) { case 'typescript': @@ -64,57 +72,11 @@ export class TemplateFile { await generateFile(ouput, `${config?.outFileName ?? fileName}${config?.ext ?? this.getExt()}`, renderContent); } - private getVersion() { - switch (this.alovaVersion) { - case 'v3': - return 'v3-'; - default: - return ''; - } - } - readAndRenderTemplate(fileName: string, data: any, userConfig?: RenderTemplateOptions) { const config = merge(cloneDeep(DEFAULT_OPTIONS), userConfig); const fileVersion = config.hasVersion ? this.getVersion() : ''; const filePath = config?.root ? fileVersion + fileName : `${this.type}/${fileVersion}${fileName}`; - const templatePath = path.resolve(TEMPLATE_PATH, `./${filePath}.handlebars`); + const templatePath = path.resolve(DEFAULT_CONFIG.templatePath, `./${filePath}.handlebars`); return readAndRenderTemplate(templatePath, data); } } - -export const writeAlovaJson = async (data: TemplateData, originPath: string, name = 'api.json') => { - // 将数据转换为 JSON 字符串 - const jsonData = await format(JSON.stringify(data, null, 2), { parser: 'json' }); - // 定义 JSON 文件的路径和名称 - const filePath = `${originPath}_${name}`; - const dirPath = filePath.split(/\/|\\/).slice(0, -1).join('/'); - if (!fs.existsSync(dirPath)) { - fs.mkdirSync(dirPath, { recursive: true }); - } - // 使用 fs.writeFile 将 JSON 数据写入文件 - fs.writeFile(filePath, jsonData, err => { - if (err) { - console.error('Error writing file:', err); - } else { - console.log('JSON file has been saved.'); - } - }); -}; -export const readAlovaJson = (originPath: string, name = 'api.json') => { - // 定义 JSON 文件的路径和名称 - const filePath = `${originPath}_${name}`; - return new Promise((resolve, reject) => { - if (!fs.existsSync(filePath)) { - reject(new Error('alovaJson not exists')); - return; - } - // 使用 fs.readFile 读取 JSON 文件 - fs.readFile(filePath, 'utf8', (err, data) => { - if (err) { - reject(err); - } else { - resolve(JSON.parse(data)); - } - }); - }); -}; diff --git a/src/wormhole/readConfig.ts b/src/wormhole/readConfig.ts index 39593f2..e6355b5 100644 --- a/src/wormhole/readConfig.ts +++ b/src/wormhole/readConfig.ts @@ -1,6 +1,7 @@ -import { loadJs, loadTs } from '@/helper/lodaders'; import { cosmiconfig } from 'cosmiconfig'; import path from 'node:path'; +import { loadJs, loadTs } from './helper/lodaders'; +import type { Config } from './type'; const alovaExplorer = cosmiconfig('alova', { cache: false, @@ -19,6 +20,6 @@ export const readConfig = async (projectPath: string) => { if (searchResult?.isEmpty) { return null; } - return searchResult?.config as AlovaConfig | null; + return searchResult?.config as Config | null; }; export default readConfig; diff --git a/src/wormhole/type.ts b/src/wormhole/type.ts index cd250ed..7e17910 100644 --- a/src/wormhole/type.ts +++ b/src/wormhole/type.ts @@ -69,3 +69,6 @@ export type Config = { interval: number; }; }; +export type GenerateApiOptions = { + force?: boolean; +}; diff --git a/src/wormhole/utils/index.ts b/src/wormhole/utils/index.ts new file mode 100644 index 0000000..8cf11ea --- /dev/null +++ b/src/wormhole/utils/index.ts @@ -0,0 +1,162 @@ +/* eslint-disable no-bitwise */ +import prettierConfig from '#/prettier.config.cjs'; +import handlebars, { HelperOptions } from 'handlebars'; +import fetch from 'node-fetch'; +import fs, { promises } from 'node:fs'; +import path from 'node:path'; +import { Config as PrettierConfig } from 'prettier'; +import * as prettierBabel from 'prettier/plugins/babel'; +import * as prettierEsTree from 'prettier/plugins/estree'; +import * as prettierTs from 'prettier/plugins/typescript'; +import * as prettier from 'prettier/standalone'; + +export const getType = (obj: any) => Object.prototype.toString.call(obj).slice(8, -1).toLowerCase(); +handlebars.registerHelper('isType', function (this: any, value, type: string, options: HelperOptions) { + if (getType(value) === type) { + return options.fn(this); + } + return options.inverse(this); +}); +handlebars.registerHelper('and', function (this: any, ...rest) { + const args = Array.prototype.slice.call(rest, 0, -1); + const options = rest[rest.length - 1] as HelperOptions; + const result = args.every(arg => { + if (Array.isArray(arg)) { + return arg.length === 0; + } + return Boolean(arg); + }); + return result ? options.fn(this) : options.inverse(this); +}); +handlebars.registerHelper('or', function (this: any, ...rest) { + const args = Array.prototype.slice.call(rest, 0, -1); + const options = rest[rest.length - 1] as HelperOptions; + const result = args.some(arg => { + if (Array.isArray(arg)) { + return arg.length !== 0; + } + return Boolean(arg); + }); + return result ? options.fn(this) : options.inverse(this); +}); +handlebars.registerHelper('eq', (a, b) => a === b); +// 注册自定义助手函数 'raw' +handlebars.registerHelper( + 'raw', + text => + // 返回原始字符串,不进行 HTML 转义 + new handlebars.SafeString(text) +); +/** + * 读取并渲染 handlebars 文件 + * @param templatePath 模板文件路径 + * @param view - 渲染模板所需的数据对象 + * @returns 渲染后的内容 + */ +export async function readAndRenderTemplate(templatePath: string, view: any): Promise { + const data = await promises.readFile(templatePath, 'utf-8'); + return handlebars.compile(data)(view); +} +export async function format(text: string, config?: PrettierConfig) { + return prettier.format(text, { + ...(prettierConfig as PrettierConfig), + parser: 'typescript', // 指定使用 babel 解析器 + ...(config ?? {}), + plugins: [prettierTs, prettierEsTree, prettierBabel] + }); +} +/** + * 传入文本内容,在指定目录下生成自定义文件 + * @param distDir 待生成文件所在目录 + * @param fileName 待生成文件名 + * @param content 文件内容 + */ +export async function generateFile(distDir: string, fileName: string, content: string) { + if (!fs.existsSync(distDir)) { + fs.mkdirSync(distDir, { recursive: true }); + } + const filePath = path.join(distDir, fileName); + const formattedText = await format(content); + fs.writeFile(filePath, formattedText, (err: NodeJS.ErrnoException | null) => { + if (err) { + return console.error('Error writing file:', err); + } + console.log('File written successfully at', filePath); + }); +} +export async function fetchData(url: string) { + return fetch(url).then(response => { + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + return response.text(); + }); +} + +export function highPrecisionInterval(callback: () => void, intervalInMilliseconds: number, immediate = false) { + let isRunning = true; + if (immediate) { + callback(); + } + const timer = setInterval(callback, intervalInMilliseconds); + + return { + isRunning() { + return isRunning; + }, + clear() { + isRunning = false; + clearInterval(timer); + }, + time: intervalInMilliseconds, + immediate + }; +} +export const getFileNameByPath = (path: string) => { + const [, name] = /[/\\]([^/\\]+)([/\\])?$/.exec(path) ?? []; + return name ?? ''; +}; +// 去掉所有为空的undefined值 +export function removeUndefined(obj: T) { + const defaultObject = Array.isArray(obj) ? [] : {}; + if (typeof obj !== 'object' || !obj) { + return obj; + } + return Object.keys(obj).reduce((result, key) => { + const value = removeUndefined((obj as any)[key]); + if (value !== undefined) { + (result as any)[key] = value; + } + return result; + }, defaultObject) as T; +} + +// 生成唯一id +export function uuid() { + let dt = new Date().getTime(); + const id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { + const r = (dt + Math.random() * 16) % 16 | 0; + dt = Math.floor(dt / 16); + return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16); + }); + return id; +} +// 反序列化 +export function deserialize(serializedJavascript: string) { + // eslint-disable-next-line no-eval + return eval(`(${serializedJavascript})`); +} +export function isEmpty(value: any) { + return value === null || value === undefined || value === ''; +} +export function capitalizeFirstLetter(str: string) { + if (!str) return str; + return str.charAt(0).toUpperCase() + str.slice(1); +} +// 加载ESM 模块 +export function loadEsmModule(modulePath: string | URL): Promise { + return new Function('modulePath', `return import(modulePath);`)(modulePath) as Promise; +} +export default { + loadEsmModule +}; diff --git a/typings/index.d.ts b/typings/index.d.ts index e7395a9..0b1b9ae 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1,5 +1,3 @@ -declare type GeneratorConfig = import('@/wormhole').GeneratorConfig; -declare type AlovaConfig = import('@/wormhole').Config; declare interface Commonand { commandId: string; handler: (context: import('vscode').ExtensionContext) => (...args: U) => T | Promise; From 6c9620f6e4cce79e14a9d62cbe5087555ee2aeb4 Mon Sep 17 00:00:00 2001 From: czhlin <2324133088@qq.com> Date: Fri, 30 Aug 2024 13:36:47 +0800 Subject: [PATCH 04/47] =?UTF-8?q?chore:=20=E5=88=9D=E6=AD=A5=E5=88=86?= =?UTF-8?q?=E7=A6=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../[Content_Types].xml | 2 - .../extension.vsixmanifest | 47 ----- .../extension/.eslintignore | 6 - .../extension/.prettierignore | 3 - .../extension/CHANGELOG.md | 9 - .../extension/LICENSE.txt | 21 --- .../extension/README.md | 3 - .../extension/commitlint.config.cjs | 3 - .../extension/package.json | 128 ------------- .../extension/resources/icon.png | Bin 33114 -> 0 bytes .../extension/resources/logo.ttf | Bin 1456 -> 0 bytes .../templates/apiDefinitions.handlebars | 7 - .../extension/templates/comment.handlebars | 19 -- .../templates/commonjs/createApis.handlebars | 72 -------- .../templates/commonjs/index.handlebars | 35 ---- .../commonjs/v3-createApis.handlebars | 75 -------- .../templates/commonjs/v3-index.handlebars | 35 ---- .../extension/templates/globals.d.handlebars | 114 ------------ .../templates/module/createApis.handlebars | 67 ------- .../templates/module/index.handlebars | 31 ---- .../templates/module/v3-createApis.handlebars | 69 ------- .../templates/module/v3-index.handlebars | 33 ---- .../typescript/createApis.handlebars | 61 ------- .../templates/typescript/index.handlebars | 30 ---- .../typescript/v3-createApis.handlebars | 61 ------- .../templates/typescript/v3-index.handlebars | 30 ---- .../templates/v3-globals.d.handlebars | 146 --------------- src/commands/generateApi.ts | 12 +- src/commands/refresh.ts | 8 +- src/commands/setup.ts | 17 +- src/functions/autocomplete.ts | 2 +- src/functions/readConfig.ts | 169 +++++------------- src/helper/configuration.ts | 4 + src/utils/index.ts | 34 ++++ src/wormhole/generate.ts | 4 +- src/wormhole/readConfig.ts | 2 +- src/wormhole/type.ts | 1 + src/wormhole/utils/index.ts | 33 ---- 38 files changed, 100 insertions(+), 1293 deletions(-) delete mode 100644 alova-vscode-extension-0.0.3/[Content_Types].xml delete mode 100644 alova-vscode-extension-0.0.3/extension.vsixmanifest delete mode 100644 alova-vscode-extension-0.0.3/extension/.eslintignore delete mode 100644 alova-vscode-extension-0.0.3/extension/.prettierignore delete mode 100644 alova-vscode-extension-0.0.3/extension/CHANGELOG.md delete mode 100644 alova-vscode-extension-0.0.3/extension/LICENSE.txt delete mode 100644 alova-vscode-extension-0.0.3/extension/README.md delete mode 100644 alova-vscode-extension-0.0.3/extension/commitlint.config.cjs delete mode 100644 alova-vscode-extension-0.0.3/extension/package.json delete mode 100644 alova-vscode-extension-0.0.3/extension/resources/icon.png delete mode 100644 alova-vscode-extension-0.0.3/extension/resources/logo.ttf delete mode 100644 alova-vscode-extension-0.0.3/extension/templates/apiDefinitions.handlebars delete mode 100644 alova-vscode-extension-0.0.3/extension/templates/comment.handlebars delete mode 100644 alova-vscode-extension-0.0.3/extension/templates/commonjs/createApis.handlebars delete mode 100644 alova-vscode-extension-0.0.3/extension/templates/commonjs/index.handlebars delete mode 100644 alova-vscode-extension-0.0.3/extension/templates/commonjs/v3-createApis.handlebars delete mode 100644 alova-vscode-extension-0.0.3/extension/templates/commonjs/v3-index.handlebars delete mode 100644 alova-vscode-extension-0.0.3/extension/templates/globals.d.handlebars delete mode 100644 alova-vscode-extension-0.0.3/extension/templates/module/createApis.handlebars delete mode 100644 alova-vscode-extension-0.0.3/extension/templates/module/index.handlebars delete mode 100644 alova-vscode-extension-0.0.3/extension/templates/module/v3-createApis.handlebars delete mode 100644 alova-vscode-extension-0.0.3/extension/templates/module/v3-index.handlebars delete mode 100644 alova-vscode-extension-0.0.3/extension/templates/typescript/createApis.handlebars delete mode 100644 alova-vscode-extension-0.0.3/extension/templates/typescript/index.handlebars delete mode 100644 alova-vscode-extension-0.0.3/extension/templates/typescript/v3-createApis.handlebars delete mode 100644 alova-vscode-extension-0.0.3/extension/templates/typescript/v3-index.handlebars delete mode 100644 alova-vscode-extension-0.0.3/extension/templates/v3-globals.d.handlebars create mode 100644 src/helper/configuration.ts diff --git a/alova-vscode-extension-0.0.3/[Content_Types].xml b/alova-vscode-extension-0.0.3/[Content_Types].xml deleted file mode 100644 index 9c652e9..0000000 --- a/alova-vscode-extension-0.0.3/[Content_Types].xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/alova-vscode-extension-0.0.3/extension.vsixmanifest b/alova-vscode-extension-0.0.3/extension.vsixmanifest deleted file mode 100644 index 4e14d22..0000000 --- a/alova-vscode-extension-0.0.3/extension.vsixmanifest +++ /dev/null @@ -1,47 +0,0 @@ - - - - - Alova - The vscode extension for alova.js - javascript - Other - Public - - - - - - - - - - - - - - - - - - - - - - - - extension/LICENSE.txt - extension/resources/icon.png - - - - - - - - - - - - - \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/.eslintignore b/alova-vscode-extension-0.0.3/extension/.eslintignore deleted file mode 100644 index ce5a37a..0000000 --- a/alova-vscode-extension-0.0.3/extension/.eslintignore +++ /dev/null @@ -1,6 +0,0 @@ -test/api-*/src/* -test/api-*/openapi*.* -test/api-*/swagger*.* -test/api-*/alova.config.* -!test/api-*/src/.gitkeep -design/**/* \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/.prettierignore b/alova-vscode-extension-0.0.3/extension/.prettierignore deleted file mode 100644 index 119571e..0000000 --- a/alova-vscode-extension-0.0.3/extension/.prettierignore +++ /dev/null @@ -1,3 +0,0 @@ -/dist -pnpm-lock.yaml -**/*.handlebars \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/CHANGELOG.md b/alova-vscode-extension-0.0.3/extension/CHANGELOG.md deleted file mode 100644 index 096404d..0000000 --- a/alova-vscode-extension-0.0.3/extension/CHANGELOG.md +++ /dev/null @@ -1,9 +0,0 @@ -# Change Log - -All notable changes to the "helloworld" extension will be documented in this file. - -Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. - -## [Unreleased] - -- Initial release diff --git a/alova-vscode-extension-0.0.3/extension/LICENSE.txt b/alova-vscode-extension-0.0.3/extension/LICENSE.txt deleted file mode 100644 index c602816..0000000 --- a/alova-vscode-extension-0.0.3/extension/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 alovajs - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/alova-vscode-extension-0.0.3/extension/README.md b/alova-vscode-extension-0.0.3/extension/README.md deleted file mode 100644 index cd4a38d..0000000 --- a/alova-vscode-extension-0.0.3/extension/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# alova devtools - -Editor devtools for alova.js. [Detailed documentation](https://alova.js.org/next/tutorial/getting-started/extension-integration). diff --git a/alova-vscode-extension-0.0.3/extension/commitlint.config.cjs b/alova-vscode-extension-0.0.3/extension/commitlint.config.cjs deleted file mode 100644 index c34aa79..0000000 --- a/alova-vscode-extension-0.0.3/extension/commitlint.config.cjs +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - extends: ['@commitlint/config-conventional'] -}; diff --git a/alova-vscode-extension-0.0.3/extension/package.json b/alova-vscode-extension-0.0.3/extension/package.json deleted file mode 100644 index 0692f32..0000000 --- a/alova-vscode-extension-0.0.3/extension/package.json +++ /dev/null @@ -1,128 +0,0 @@ -{ - "name": "alova-vscode-extension", - "displayName": "Alova", - "description": "The vscode extension for alova.js", - "version": "0.0.3", - "engines": { - "vscode": "^1.89.0", - "node": ">=18.19.0", - "pnpm": ">=8.6.12" - }, - "categories": [ - "Other" - ], - "activationEvents": [ - "workspaceContains:**/*.ts", - "workspaceContains:**/*.js" - ], - "main": "./out/extension.js", - "icon": "resources/icon.png", - "contributes": { - "commands": [ - { - "command": "alova.refresh", - "category": "alova", - "title": "alova refresh" - } - ], - "icons": { - "alova-icon-id": { - "description": "alova icon", - "default": { - "fontPath": "./resources/logo.ttf", - "fontCharacter": "\\E900" - } - } - } - }, - "scripts": { - "vscode:prepublish": "pnpm run package", - "compile": "pnpm run check-types && pnpm run lint:fix && tsx esbuild.ts", - "watch": "npm-run-all -p watch:*", - "watch:esbuild": "tsx esbuild.ts --watch", - "watch:tsc": "tsc --noEmit --watch --project tsconfig.json", - "package": "pnpm run check-types && pnpm run lint:fix && tsx esbuild.ts --production", - "compile-tests": "tsc -p . --outDir out", - "watch-tests": "tsc -p . -w --outDir out", - "pretest": "pnpm run compile-tests && pnpm run compile && pnpm run lint", - "check-types": "tsc --noEmit", - "lint": "eslint . --ext .js,.ts", - "lint:fix": "npm run lint -- --fix", - "format": "prettier --check .", - "format:fix": "prettier --write .", - "test": "vscode-test", - "api-test": "tsx scripts/api-test.ts", - "commit": "git-cz && git push", - "prepare": "husky && pnpm api-test", - "pack:pre": "vsce package --no-dependencies --pre-release", - "release:pre": "vsce publish --no-dependencies --pre-release", - "pack": "vsce package --no-dependencies", - "release": "vsce publish --no-dependencies" - }, - "publisher": "Alova", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/alovajs/devtools.git" - }, - "bugs": { - "url": "https://github.com/alovajs/devtools/issues" - }, - "lint-staged": { - "*": "npm run format:fix", - "*.js,*.ts": "npm run lint:fix" - }, - "devDependencies": { - "@commitlint/cli": "^19.3.0", - "@commitlint/config-conventional": "^19.2.2", - "@types/js-yaml": "^4.0.9", - "@types/lodash": "^4.17.5", - "@types/mocha": "^10.0.6", - "@types/mustache": "^4.2.5", - "@types/node": "18.x", - "@types/node-fetch": "^2.6.11", - "@types/serialize-javascript": "^5.0.4", - "@types/swagger2openapi": "^7.0.4", - "@types/vscode": "^1.89.0", - "@typescript-eslint/eslint-plugin": "^7.13.0", - "@typescript-eslint/parser": "^7.13.0", - "@vscode/test-cli": "^0.0.9", - "@vscode/test-electron": "^2.3.9", - "@vscode/vsce": "^2.29.0", - "commitizen": "^4.3.0", - "cz-conventional-changelog": "^3.3.0", - "esbuild": "^0.23.0", - "esbuild-plugin-alias": "^0.2.1", - "eslint": "^8.57.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^18.0.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.1.3", - "husky": "^9.0.11", - "js-yaml": "^4.1.0", - "lint-staged": "^15.2.2", - "npm-run-all": "^4.1.5", - "prettier": "^3.2.5", - "prettier-plugin-organize-imports": "^3.2.4", - "prettier-plugin-sort-json": "^4.0.0", - "tsx": "^4.15.8", - "type-fest": "^4.20.0", - "typescript": "^5.4.5" - }, - "config": { - "commitizen": { - "path": "./node_modules/cz-conventional-changelog" - } - }, - "dependencies": { - "chokidar": "^3.6.0", - "cosmiconfig": "^9.0.0", - "handlebars": "^4.7.8", - "import-fresh": "^3.3.0", - "lodash": "^4.17.21", - "node-fetch": "^2.7.0", - "openapi-types": "^12.1.3", - "serialize-javascript": "^6.0.2", - "swagger2openapi": "^7.0.8" - } -} diff --git a/alova-vscode-extension-0.0.3/extension/resources/icon.png b/alova-vscode-extension-0.0.3/extension/resources/icon.png deleted file mode 100644 index 7bb5c54d74666c6651ac2af86c28e065aa09b912..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33114 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 NjDxSu_*;1n{|j*+;urt` diff --git a/alova-vscode-extension-0.0.3/extension/templates/apiDefinitions.handlebars b/alova-vscode-extension-0.0.3/extension/templates/apiDefinitions.handlebars deleted file mode 100644 index 5820553..0000000 --- a/alova-vscode-extension-0.0.3/extension/templates/apiDefinitions.handlebars +++ /dev/null @@ -1,7 +0,0 @@ -/// -{{{commentText}}} -{{#if (eq moduleType "ESModule")}}export default{{else if (eq moduleType "commonJs")}}module.exports ={{/if}} { -{{#pathsArr}} - "{{{key}}}": ["{{method}}", "{{{path}}}"], -{{/pathsArr}} -}; \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/comment.handlebars b/alova-vscode-extension-0.0.3/extension/templates/comment.handlebars deleted file mode 100644 index 4eafdcf..0000000 --- a/alova-vscode-extension-0.0.3/extension/templates/comment.handlebars +++ /dev/null @@ -1,19 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * {{info.title}} - version {{info.version}} - * - * {{info.description}} - * - * OpenAPI version: {{openapi}} - * - {{#info.contact}} - * Contact: {{#info.contact.name}}[{{info.contact.name}}]{{/info.contact.name}}{{#info.contact.url}}{{{info.contact.url}}}{{/info.contact.url}}{{^info.contact.url}}{{{info.contact.email}}}{{/info.contact.url}} - {{/info.contact}} - * - * NOTE: This file is auto generated by the alova's vscode plugin. - * - * https://alova.js.org/devtools/vscode - * - * **Do not edit the file manually.** - */ \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/commonjs/createApis.handlebars b/alova-vscode-extension-0.0.3/extension/templates/commonjs/createApis.handlebars deleted file mode 100644 index 66a4715..0000000 --- a/alova-vscode-extension-0.0.3/extension/templates/commonjs/createApis.handlebars +++ /dev/null @@ -1,72 +0,0 @@ -{{{commentText}}} -const { Method } = require('alova'); -const apiDefinitions = require('./apiDefinitions'); -/** - * - * @param {(string|symbol)[]} array - * @param {Alova} alovaInstance - * @param {any} configMap - * @returns {()=>void} - */ -const createFunctionalProxy = (array, alovaInstance, configMap) => { - // create a new proxy instance - return new Proxy(function () {}, { - get(_, property) { - // record the target property, so that it can get the completed accessing paths - array.push(property); - // always return a new proxy to continue recording accessing paths. - return createFunctionalProxy(array, alovaInstance, configMap); - }, - apply(_, __, [config]) { - const apiItem = apiDefinitions[array.join('.')]; - if (!apiItem) { - throw new Error(`the api path of \`${apiItem}\` is not found`); - } - const [method, url] = apiItem; - const { pathParams, data } = config; - const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => { - const pathParam = pathParams[key]; - return pathParam; - }); - delete config.pathParams; - return new Method(method.toUpperCase(), alovaInstance, urlReplaced, config, data); - } - }); -}; -/** - * - * @param {Alova} alovaInstance - * @param {any} configMap - * @returns - */ -const createApis = (alovaInstance, configMap) => { - const Apis = new Proxy( - {}, - { - get(_, property) { - return createFunctionalProxy([property], alovaInstance, configMap); - } - } - ); - // 如果是全局定义 - globalThis.{{{global}}} = Apis; - return Apis; -} -/** - * @template T - * @typedef {typeof import('./index')['alovaInstance'] extends import('alova').Alova ? import('alova').AlovaMethodCreateConfig : never} MethodConfig - */ -/** - * @typedef {{#raw "{{ " }}{{/raw}}[P in keyof typeof import('./apiDefinitions')]?: MethodConfig

[0]['transformData']>[0] : any>{{#raw " }}" }}{{/raw}} MethodsConfigMap - */ -/** - * @template {MethodsConfigMap} Config - * @param {Config} config - */ -const withConfigType = config => config; - -module.exports = { - createApis, - withConfigType -}; - diff --git a/alova-vscode-extension-0.0.3/extension/templates/commonjs/index.handlebars b/alova-vscode-extension-0.0.3/extension/templates/commonjs/index.handlebars deleted file mode 100644 index 464e0bd..0000000 --- a/alova-vscode-extension-0.0.3/extension/templates/commonjs/index.handlebars +++ /dev/null @@ -1,35 +0,0 @@ -const { createAlova } = require('alova'); -const GlobalFetch = require('alova/GlobalFetch'); -{{#vue}} -const vueHook = require('alova/vue'); -{{/vue}} -{{#react}} -const reactHook = require('alova/react'); -{{/react}} -const { createApis, withConfigType } = require('./createApis'); -const alovaInstance = createAlova({ - baseURL: "{{{baseUrl}}}", -{{#vue}} - statesHook: vueHook, -{{/vue}} -{{#react}} - statesHook: reactHook, -{{/react}} - requestAdapter: GlobalFetch(), - beforeRequest: method => {}, - responded: res => { - return res.json(); - } -}); -const $$userConfigMap = withConfigType({}); - -/** - * @type {{#raw "{ " }}{{/raw}}{{{global}}}{{#raw " }" }}{{/raw}} - */ -const Apis = createApis(alovaInstance, $$userConfigMap); - -module.exports = { - Apis, - alovaInstance, - $$userConfigMap -}; \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/commonjs/v3-createApis.handlebars b/alova-vscode-extension-0.0.3/extension/templates/commonjs/v3-createApis.handlebars deleted file mode 100644 index 45f0535..0000000 --- a/alova-vscode-extension-0.0.3/extension/templates/commonjs/v3-createApis.handlebars +++ /dev/null @@ -1,75 +0,0 @@ -{{{commentText}}} -const { Method } = require('alova'); -const apiDefinitions = require('./apiDefinitions'); -/** - * @typedef {import('alova').AlovaGenerics} AlovaGenerics - */ -/** - * - * @param {(string|symbol)[]} array - * @param {Alova} alovaInstance - * @param {any} configMap - * @returns {()=>void} - */ -const createFunctionalProxy = (array, alovaInstance, configMap) => { - // create a new proxy instance - return new Proxy(function () {}, { - get(_, property) { - // record the target property, so that it can get the completed accessing paths - array.push(property); - // always return a new proxy to continue recording accessing paths. - return createFunctionalProxy(array, alovaInstance, configMap); - }, - apply(_, __, [config]) { - const apiItem = apiDefinitions[array.join('.')]; - if (!apiItem) { - throw new Error(`the api path of \`${apiItem}\` is not found`); - } - const [method, url] = apiItem; - const { pathParams, data } = config; - const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => { - const pathParam = pathParams[key]; - return pathParam; - }); - delete config.pathParams; - return new Method(method.toUpperCase(), alovaInstance, urlReplaced, config, data); - } - }); -}; -/** - * - * @param {Alova} alovaInstance - * @param {any} configMap - * @returns - */ -const createApis = (alovaInstance, configMap) =>{ - const Apis = new Proxy( - {}, - { - get(_, property) { - return createFunctionalProxy([property], alovaInstance, configMap); - } - } - ); - // 如果是全局定义 - globalThis.{{{global}}} = Apis; - return Apis; -} -/** - * @template T - * @typedef {import('alova').AlovaMethodCreateConfig ? AG : any, any, T>} MethodConfig - */ -/** - * @typedef {{#raw "{{ " }}{{/raw}}[P in keyof typeof import('./apiDefinitions')]?: MethodConfig

[0]['transform']>[0] : any>{{#raw " }}" }}{{/raw}} MethodsConfigMap - */ -/** - * @template {MethodsConfigMap} Config - * @param {Config} config - */ -const withConfigType = config => config; - -module.exports = { - createApis, - withConfigType -}; - diff --git a/alova-vscode-extension-0.0.3/extension/templates/commonjs/v3-index.handlebars b/alova-vscode-extension-0.0.3/extension/templates/commonjs/v3-index.handlebars deleted file mode 100644 index 4a3909c..0000000 --- a/alova-vscode-extension-0.0.3/extension/templates/commonjs/v3-index.handlebars +++ /dev/null @@ -1,35 +0,0 @@ -const { createAlova } = require('alova'); -const fetchAdapter = require('alova/fetch'); -{{#vue}} -const vueHook = require('alova/vue'); -{{/vue}} -{{#react}} -const reactHook = require('alova/react'); -{{/react}} -const { createApis, withConfigType } = require('./createApis'); -const alovaInstance = createAlova({ - baseURL: "{{{baseUrl}}}", -{{#vue}} - statesHook: vueHook, -{{/vue}} -{{#react}} - statesHook: reactHook, -{{/react}} - requestAdapter: fetchAdapter(), - beforeRequest: method => {}, - responded: res => { - return res.json(); - } -}); -const $$userConfigMap = withConfigType({}); - -/** - * @type {{#raw "{ " }}{{/raw}}{{{global}}}{{#raw " }" }}{{/raw}} - */ -const Apis = createApis(alovaInstance, $$userConfigMap); - -module.exports = { - Apis, - alovaInstance, - $$userConfigMap -}; \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/globals.d.handlebars b/alova-vscode-extension-0.0.3/extension/templates/globals.d.handlebars deleted file mode 100644 index a9c2e56..0000000 --- a/alova-vscode-extension-0.0.3/extension/templates/globals.d.handlebars +++ /dev/null @@ -1,114 +0,0 @@ -{{{commentText}}} -import { Alova, AlovaMethodCreateConfig, Method } from 'alova'; -import type { $$userConfigMap, alovaInstance } from '.'; -import type apiDefinitions from './apiDefinitions'; - -type CollapsedAlova = typeof alovaInstance; -type UserMethodConfigMap = typeof $$userConfigMap; - -type Alova2MethodConfig = - CollapsedAlova extends Alova - ? Omit,"params"> - : never; - -// Extract the return type of transformData function that define in $$userConfigMap, if it not exists, use the default type. -type ExtractUserDefinedTransformed< - DefinitionKey extends keyof typeof apiDefinitions, - Default -> = DefinitionKey extends keyof UserMethodConfigMap - ? UserMethodConfigMap[DefinitionKey]['transformData'] extends (...args: any[]) => any - ? Awaited> - : Default - : Default; -type Alova2Method< - Responded, - DefinitionKey extends keyof typeof apiDefinitions, - CurrentConfig extends Alova2MethodConfig -> = - CollapsedAlova extends Alova - ? Method< - State, - Export, - CurrentConfig extends undefined - ? ExtractUserDefinedTransformed - : CurrentConfig['transformData'] extends (...args: any[]) => any - ? Awaited> - : ExtractUserDefinedTransformed, - any, - RequestConfig, - Response, - ResponseHeader - > - : never; - -{{#schemas}} -{{{.}}} -{{/schemas}} -declare global { - interface {{{global}}} { - {{#pathApis}} - {{{tag}}}: { - {{#apis}} - /** - * --- - * - * [{{{method}}}] {{{summary}}} - * - * **path:** {{{path}}} - * - {{#if pathParametersComment}} - * --- - * - * **Path Parameters** - * ```ts - * type PathParameters = {{{pathParametersComment}}} - * ``` - * - {{/if}} - {{#if queryParametersComment}} - * --- - * - * **Query Parameters** - * ```ts - * type QueryParameters = {{{queryParametersComment}}} - * ``` - * - {{/if}} - {{#if requestComment}} - * --- - * - * **RequestBody** - * ```ts - * type RequestBody = {{{requestComment}}} - * ``` - * - {{/if}} - {{#if responseComment}} - * --- - * - * **Response** - * ```ts - * type Response = {{{responseComment}}} - * ``` - {{/if}} - */ - {{{name}}}{{#or pathParameters queryParameters requestName }} & { - {{#if pathParameters}} - pathParams: {{{pathParameters}}}; - {{/if}} - {{#if queryParameters}} - params: {{{queryParameters}}}; - {{/if}} - {{#if requestName}} - data: {{{requestName}}}; - {{/if}} - }{{/or}}>( - config{{#or pathParameters queryParameters requestName }}{{else}}?{{/or}}: Config - ): Alova2Method<{{{responseName}}}, '{{{pathKey}}}', Config>; - {{/apis}} - }; - {{/pathApis}} - } - - var {{{global}}}: {{{global}}}; -} diff --git a/alova-vscode-extension-0.0.3/extension/templates/module/createApis.handlebars b/alova-vscode-extension-0.0.3/extension/templates/module/createApis.handlebars deleted file mode 100644 index 519e769..0000000 --- a/alova-vscode-extension-0.0.3/extension/templates/module/createApis.handlebars +++ /dev/null @@ -1,67 +0,0 @@ -{{{commentText}}} -import { Method } from 'alova'; -import apiDefinitions from './apiDefinitions'; -/** - * - * @param {(string|symbol)[]} array - * @param {Alova} alovaInstance - * @param {any} configMap - * @returns {()=>void} - */ -const createFunctionalProxy = (array, alovaInstance, configMap) => { - // create a new proxy instance - return new Proxy(function () {}, { - get(_, property) { - // record the target property, so that it can get the completed accessing paths - array.push(property); - // always return a new proxy to continue recording accessing paths. - return createFunctionalProxy(array, alovaInstance, configMap); - }, - apply(_, __, [config]) { - const apiItem = apiDefinitions[array.join('.')]; - if (!apiItem) { - throw new Error(`the api path of \`${apiItem}\` is not found`); - } - const [method, url] = apiItem; - const { pathParams, data } = config; - const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => { - const pathParam = pathParams[key]; - return pathParam; - }); - delete config.pathParams; - return new Method(method.toUpperCase(), alovaInstance, urlReplaced, config, data); - } - }); -}; -/** - * - * @param {Alova} alovaInstance - * @param {any} configMap - * @returns {{#raw "{ " }}{{/raw}}{{{global}}}{{#raw " }" }}{{/raw}} - */ -export const createApis = (alovaInstance, configMap) => { - const Apis = new Proxy( - {}, - { - get(_, property) { - return createFunctionalProxy([property], alovaInstance, configMap); - } - } - ); - // 如果是全局定义 - globalThis.{{{global}}} = Apis; - return Apis; -} - -/** - * @template T - * @typedef {typeof import('./index')['alovaInstance'] extends import('alova').Alova ? import('alova').AlovaMethodCreateConfig : never} MethodConfig - */ -/** - * @typedef {{#raw "{{ " }}{{/raw}}[P in keyof typeof import('./apiDefinitions').default]?: MethodConfig

[0]['transformData']>[0] : any>{{#raw " }}" }}{{/raw}} MethodsConfigMap - */ -/** - * @template {MethodsConfigMap} Config - * @param {Config} config - */ -export const withConfigType = config => config; \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/module/index.handlebars b/alova-vscode-extension-0.0.3/extension/templates/module/index.handlebars deleted file mode 100644 index 9e5376f..0000000 --- a/alova-vscode-extension-0.0.3/extension/templates/module/index.handlebars +++ /dev/null @@ -1,31 +0,0 @@ -import { createAlova } from 'alova'; -import GlobalFetch from 'alova/GlobalFetch'; -{{#vue}} -import vueHook from 'alova/vue'; -{{/vue}} -{{#react}} -import reactHook from 'alova/react'; -{{/react}} -import { createApis, withConfigType } from './createApis'; - -export const alovaInstance = createAlova({ - baseURL: "{{{baseUrl}}}", -{{#vue}} - statesHook: vueHook, -{{/vue}} -{{#react}} - statesHook: reactHook, -{{/react}} - requestAdapter: GlobalFetch(), - beforeRequest: method => { }, - responded: res => { return res.json(); } -}); - -export const $$userConfigMap = withConfigType({}); - -/** - * @type {{#raw "{ " }}{{/raw}}{{{global}}}{{#raw " }" }}{{/raw}} - */ -const Apis = createApis(alovaInstance, $$userConfigMap); - -export default Apis; \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/module/v3-createApis.handlebars b/alova-vscode-extension-0.0.3/extension/templates/module/v3-createApis.handlebars deleted file mode 100644 index 148828b..0000000 --- a/alova-vscode-extension-0.0.3/extension/templates/module/v3-createApis.handlebars +++ /dev/null @@ -1,69 +0,0 @@ -{{{commentText}}} -import { Method } from 'alova'; -import apiDefinitions from './apiDefinitions'; -/** - * @typedef {import('alova').AlovaGenerics} AlovaGenerics - */ -/** - * - * @param {(string|symbol)[]} array - * @param {Alova} alovaInstance - * @param {any} configMap - * @returns {()=>void} - */ -const createFunctionalProxy = (array, alovaInstance, configMap) => { - // create a new proxy instance - return new Proxy(function () {}, { - get(_, property) { - // record the target property, so that it can get the completed accessing paths - array.push(property); - // always return a new proxy to continue recording accessing paths. - return createFunctionalProxy(array, alovaInstance, configMap); - }, - apply(_, __, [config]) { - const apiItem = apiDefinitions[array.join('.')]; - if (!apiItem) { - throw new Error(`the api path of \`${apiItem}\` is not found`); - } - const [method, url] = apiItem; - const { pathParams, data } = config; - const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => { - const pathParam = pathParams[key]; - return pathParam; - }); - delete config.pathParams; - return new Method(method.toUpperCase(), alovaInstance, urlReplaced, config, data); - } - }); -}; -/** - * - * @param {Alova} alovaInstance - * @param {any} configMap - * @returns {{#raw "{ " }}{{/raw}}{{{global}}}{{#raw " }" }}{{/raw}} - */ -export const createApis = (alovaInstance, configMap) => { - const Apis = new Proxy( - {}, - { - get(_, property) { - return createFunctionalProxy([property], alovaInstance, configMap); - } - } - ); - // 如果是全局定义 - globalThis.{{{global}}} = Apis; - return Apis; -} -/** - * @template T - * @typedef {import('alova').AlovaMethodCreateConfig ? AG : any, any, T>} MethodConfig - */ -/** - * @typedef {{#raw "{{ " }}{{/raw}}[P in keyof typeof import('./apiDefinitions').default]?: MethodConfig

[0]['transform']>[0] : any>{{#raw " }}" }}{{/raw}} MethodsConfigMap - */ -/** - * @template {MethodsConfigMap} Config - * @param {Config} config - */ -export const withConfigType = config => config; \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/module/v3-index.handlebars b/alova-vscode-extension-0.0.3/extension/templates/module/v3-index.handlebars deleted file mode 100644 index 6952e81..0000000 --- a/alova-vscode-extension-0.0.3/extension/templates/module/v3-index.handlebars +++ /dev/null @@ -1,33 +0,0 @@ -import { createAlova } from 'alova'; -import fetchAdapter from 'alova/fetch'; -{{#vue}} -import vueHook from 'alova/vue'; -{{/vue}} -{{#react}} -import reactHook from 'alova/react'; -{{/react}} -import { createApis, withConfigType } from './createApis'; - -export const alovaInstance = createAlova({ - baseURL: "{{{baseUrl}}}", -{{#vue}} - statesHook: vueHook, -{{/vue}} -{{#react}} - statesHook: reactHook, -{{/react}} - requestAdapter: fetchAdapter(), - beforeRequest: method => { }, - responded: res => { - return res.json(); - } -}); - -export const $$userConfigMap = withConfigType({}); - -/** - * @type {{#raw "{ " }}{{/raw}}{{{global}}}{{#raw " }" }}{{/raw}} - */ -const Apis = createApis(alovaInstance, $$userConfigMap); - -export default Apis; \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/typescript/createApis.handlebars b/alova-vscode-extension-0.0.3/extension/templates/typescript/createApis.handlebars deleted file mode 100644 index 8fc3687..0000000 --- a/alova-vscode-extension-0.0.3/extension/templates/typescript/createApis.handlebars +++ /dev/null @@ -1,61 +0,0 @@ -{{{commentText}}} -import { Alova, Method, MethodType, AlovaMethodCreateConfig } from 'alova'; -import apiDefinitions from './apiDefinitions'; - -const createFunctionalProxy = ( - array: (string | symbol)[], - alovaInstance: Alova, - configMap: any -) => { - // create a new proxy instance - return new Proxy(function () {}, { - get(_, property) { - // record the target property, so that it can get the completed accessing paths - array.push(property); - // always return a new proxy to continue recording accessing paths. - return createFunctionalProxy(array, alovaInstance, configMap); - }, - apply(_, __, [config]) { - const apiItem = apiDefinitions[array.join('.')] as string[] | undefined; - if (!apiItem) { - throw new Error(`the api path of \`${apiItem}\` is not found`); - } - const [method, url] = apiItem; - const { pathParams, data } = config; - const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => { - const pathParam = pathParams[key]; - return pathParam; - }); - delete config.pathParams; - return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, config, data); - } - }); -}; - -export const createApis = (alovaInstance: Alova, configMap: any) =>{ - const Apis = new Proxy( - {} as {{{global}}}, - { - get(_, property) { - return createFunctionalProxy([property], alovaInstance, configMap); - } - } - ); - // 如果是全局定义 - (globalThis as any).{{{global}}} = Apis; - return Apis; -} -type MethodConfig = typeof import('./index')['alovaInstance'] extends Alova ? import('alova').AlovaMethodCreateConfig : never; -type APISofParameters = Tag extends keyof {{{global}}} - ? Url extends keyof {{{global}}}[Tag] - ? {{{global}}}[Tag][Url] extends (...args: any) => any - ? Parameters<{{{global}}}[Tag][Url]> - : any - : any - : any; -type MethodsConfigMap = { - [P in keyof typeof import('./apiDefinitions').default]?: MethodConfig< - P extends `${infer Tag}.${infer Url}` ? Parameters[0]['transformData']>[0] : any - >; -}; -export const withConfigType = (config: Config) => config; \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/typescript/index.handlebars b/alova-vscode-extension-0.0.3/extension/templates/typescript/index.handlebars deleted file mode 100644 index 2cc1a07..0000000 --- a/alova-vscode-extension-0.0.3/extension/templates/typescript/index.handlebars +++ /dev/null @@ -1,30 +0,0 @@ -import { createAlova } from 'alova'; -import GlobalFetch from 'alova/GlobalFetch'; -{{#vue}} -import vueHook from 'alova/vue'; -{{/vue}} -{{#react}} -import reactHook from 'alova/react'; -{{/react}} -import { createApis, withConfigType } from './createApis'; - -export const alovaInstance = createAlova({ - baseURL: "{{{baseUrl}}}", -{{#vue}} - statesHook: vueHook, -{{/vue}} -{{#react}} - statesHook: reactHook, -{{/react}} - requestAdapter: GlobalFetch(), - beforeRequest: method => { }, - responded: res => { - return res.json(); - } -}); - -export const $$userConfigMap = withConfigType({}); - -const Apis = createApis(alovaInstance, $$userConfigMap); - -export default Apis; \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/typescript/v3-createApis.handlebars b/alova-vscode-extension-0.0.3/extension/templates/typescript/v3-createApis.handlebars deleted file mode 100644 index 6504b05..0000000 --- a/alova-vscode-extension-0.0.3/extension/templates/typescript/v3-createApis.handlebars +++ /dev/null @@ -1,61 +0,0 @@ -{{{commentText}}} -import { Alova, Method, MethodType, AlovaMethodCreateConfig, AlovaGenerics } from 'alova'; -import apiDefinitions from './apiDefinitions'; - -const createFunctionalProxy = ( - array: (string | symbol)[], - alovaInstance: Alova, - configMap: any -) => { - // create a new proxy instance - return new Proxy(function () {}, { - get(_, property) { - // record the target property, so that it can get the completed accessing paths - array.push(property); - // always return a new proxy to continue recording accessing paths. - return createFunctionalProxy(array, alovaInstance, configMap); - }, - apply(_, __, [config]) { - const apiItem = apiDefinitions[array.join('.')] as string[] | undefined; - if (!apiItem) { - throw new Error(`the api path of \`${apiItem}\` is not found`); - } - const [method, url] = apiItem; - const { pathParams, data } = config; - const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => { - const pathParam = pathParams[key]; - return pathParam; - }); - delete config.pathParams; - return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, config, data); - } - }); -}; - -export const createApis = (alovaInstance: Alova, configMap: any) =>{ - const Apis = new Proxy( - {} as {{{global}}}, - { - get(_, property) { - return createFunctionalProxy([property], alovaInstance, configMap); - } - } - ); - // 如果是全局定义 - (globalThis as any).{{{global}}} = Apis; - return Apis; -} -type MethodConfig = AlovaMethodCreateConfig ? AG : any, any, T>; -type APISofParameters = Tag extends keyof {{{global}}} - ? Url extends keyof {{{global}}}[Tag] - ? {{{global}}}[Tag][Url] extends (...args: any) => any - ? Parameters<{{{global}}}[Tag][Url]> - : any - : any - : any; -type MethodsConfigMap = { - [P in keyof typeof import('./apiDefinitions').default]?: MethodConfig< - P extends `${infer Tag}.${infer Url}` ? Parameters[0]['transform']>[0] : any - >; -}; -export const withConfigType = (config: Config) => config; diff --git a/alova-vscode-extension-0.0.3/extension/templates/typescript/v3-index.handlebars b/alova-vscode-extension-0.0.3/extension/templates/typescript/v3-index.handlebars deleted file mode 100644 index 77aef01..0000000 --- a/alova-vscode-extension-0.0.3/extension/templates/typescript/v3-index.handlebars +++ /dev/null @@ -1,30 +0,0 @@ -import { createAlova } from 'alova'; -import fetchAdapter from 'alova/fetch'; -{{#vue}} -import vueHook from 'alova/vue'; -{{/vue}} -{{#react}} -import reactHook from 'alova/react'; -{{/react}} -import { createApis, withConfigType } from './createApis'; - -export const alovaInstance = createAlova({ - baseURL: "{{{baseUrl}}}", -{{#vue}} - statesHook: vueHook, -{{/vue}} -{{#react}} - statesHook: reactHook, -{{/react}} - requestAdapter: fetchAdapter(), - beforeRequest: method => { }, - responded: res => { - return res.json(); - } -}); - -export const $$userConfigMap = withConfigType({}); - -const Apis = createApis(alovaInstance, $$userConfigMap); - -export default Apis; \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3/extension/templates/v3-globals.d.handlebars b/alova-vscode-extension-0.0.3/extension/templates/v3-globals.d.handlebars deleted file mode 100644 index 56e27d7..0000000 --- a/alova-vscode-extension-0.0.3/extension/templates/v3-globals.d.handlebars +++ /dev/null @@ -1,146 +0,0 @@ -{{{commentText}}} -import { Alova, AlovaMethodCreateConfig, AlovaGenerics, Method } from 'alova'; -import type { $$userConfigMap, alovaInstance } from '.'; -import type apiDefinitions from './apiDefinitions'; - -type CollapsedAlova = typeof alovaInstance; -type UserMethodConfigMap = typeof $$userConfigMap; - -type Alova2MethodConfig = - CollapsedAlova extends Alova< - AlovaGenerics< - any, - any, - infer RequestConfig, - infer Response, - infer ResponseHeader, - infer L1Cache, - infer L2Cache, - infer SE - > - > - ? Omit< - AlovaMethodCreateConfig< - AlovaGenerics, - any, - Responded - >, - 'params' - > - : never; - -// Extract the return type of transform function that define in $$userConfigMap, if it not exists, use the default type. -type ExtractUserDefinedTransformed< - DefinitionKey extends keyof typeof apiDefinitions, - Default -> = DefinitionKey extends keyof UserMethodConfigMap - ? UserMethodConfigMap[DefinitionKey]['transform'] extends (...args: any[]) => any - ? Awaited> - : Default - : Default; -type Alova2Method< - Responded, - DefinitionKey extends keyof typeof apiDefinitions, - CurrentConfig extends Alova2MethodConfig -> = - CollapsedAlova extends Alova< - AlovaGenerics< - any, - any, - infer RequestConfig, - infer Response, - infer ResponseHeader, - infer L1Cache, - infer L2Cache, - infer SE - > - > - ? Method< - AlovaGenerics< - CurrentConfig extends undefined - ? ExtractUserDefinedTransformed - : CurrentConfig['transform'] extends (...args: any[]) => any - ? Awaited> - : ExtractUserDefinedTransformed, - any, - RequestConfig, - Response, - ResponseHeader, - L1Cache, - L2Cache, - SE - > - > - : never; - -{{#schemas}} -{{{.}}} -{{/schemas}} -declare global { - interface {{{global}}} { - {{#pathApis}} - {{{tag}}}: { - {{#apis}} - /** - * --- - * - * [{{{method}}}] {{{summary}}} - * - * **path:** {{{path}}} - * - {{#if pathParametersComment}} - * --- - * - * **Path Parameters** - * ```ts - * type PathParameters = {{{pathParametersComment}}} - * ``` - * - {{/if}} - {{#if queryParametersComment}} - * --- - * - * **Query Parameters** - * ```ts - * type QueryParameters = {{{queryParametersComment}}} - * ``` - * - {{/if}} - {{#if requestComment}} - * --- - * - * **RequestBody** - * ```ts - * type RequestBody = {{{requestComment}}} - * ``` - * - {{/if}} - {{#if responseComment}} - * --- - * - * **Response** - * ```ts - * type Response = {{{responseComment}}} - * ``` - {{/if}} - */ - {{{name}}}{{#or pathParameters queryParameters requestName }} & { - {{#if pathParameters}} - pathParams: {{{pathParameters}}}; - {{/if}} - {{#if queryParameters}} - params: {{{queryParameters}}}; - {{/if}} - {{#if requestName}} - data: {{{requestName}}}; - {{/if}} - }{{/or}}>( - config{{#or pathParameters queryParameters requestName }}{{else}}?{{/or}}: Config - ): Alova2Method<{{{responseName}}}, '{{{pathKey}}}', Config>; - {{/apis}} - }; - {{/pathApis}} - } - - var {{{global}}}: {{{global}}}; -} diff --git a/src/commands/generateApi.ts b/src/commands/generateApi.ts index edd08a4..2426d3b 100644 --- a/src/commands/generateApi.ts +++ b/src/commands/generateApi.ts @@ -1,22 +1,14 @@ import message from '@/components/message'; -import readConfig from '@/functions/readConfig'; -import { CONFIG_POOL } from '@/modules/Configuration'; +import { CONFIG_POOL } from '@/helper/configuration'; import { getFileNameByPath } from '@/utils'; import { generate } from '@/wormhole'; // 用于自动生成 export default { commandId: 'alova.generateApi', handler: () => async () => { - // 读取配置文件 - await readConfig(false); // 生成api文件 for (const configuration of CONFIG_POOL) { - // 过滤掉不需要更新的配置 - if (!configuration.shouldUpdate) { - continue; - } - configuration.shouldUpdate = false; - const result = await generate(configuration.workspaceRootDir, configuration.config); + const result = await generate(configuration.config, { projectPath: configuration.workspaceRootDir }); if (result?.some(item => !!item)) { message.info(`[${getFileNameByPath(configuration.workspaceRootDir)}]:Your API is updated`); } diff --git a/src/commands/refresh.ts b/src/commands/refresh.ts index 1b2c62e..c705402 100644 --- a/src/commands/refresh.ts +++ b/src/commands/refresh.ts @@ -1,8 +1,7 @@ import Error from '@/components/error'; import message from '@/components/message'; import { loading, reset } from '@/components/statusBar'; -import readConfig from '@/functions/readConfig'; -import { CONFIG_POOL } from '@/modules/Configuration'; +import { CONFIG_POOL } from '@/helper/configuration'; import { getFileNameByPath } from '@/utils'; import { generate } from '@/wormhole'; @@ -11,12 +10,9 @@ export default { handler: () => async () => { try { loading(); - // 读取配置文件 - await readConfig(); - // 生成api文件 for (const configuration of CONFIG_POOL) { - await generate(configuration.workspaceRootDir, configuration.config, { force: true }); + await generate(configuration.config, { force: true, projectPath: configuration.workspaceRootDir }); reset(); message.info(`[${getFileNameByPath(configuration.workspaceRootDir)}]:Your API is refresh`); } diff --git a/src/commands/setup.ts b/src/commands/setup.ts index 9431344..3ab0215 100644 --- a/src/commands/setup.ts +++ b/src/commands/setup.ts @@ -1,6 +1,7 @@ import autocomplete from '@/components/autocomplete'; import { outputChannel } from '@/components/message'; import readConfig from '@/functions/readConfig'; +import { highPrecisionInterval } from '@/utils'; import * as vscode from 'vscode'; import showStatusBarIcon from './showStatusBarIcon'; @@ -8,15 +9,15 @@ export default { commandId: 'alova.setup', handler: context => async () => { vscode.commands.executeCommand(showStatusBarIcon.commandId); - // 读取配置文件 - readConfig(true, false); context.subscriptions.push(autocomplete); context.subscriptions.push(outputChannel); - vscode.workspace.onDidChangeWorkspaceFolders(event => { - event.added.forEach(() => { - // 读取配置文件 - readConfig(true, false); - }); - }); + // 读取所有配置文件 + highPrecisionInterval(() => { + // 获得所有工作区 + const workspaceFolders = vscode.workspace.workspaceFolders || []; + for (const workspaceFolder of workspaceFolders) { + readConfig(`${workspaceFolder.uri.fsPath}/`); + } + }, 500); } } as Commonand; diff --git a/src/functions/autocomplete.ts b/src/functions/autocomplete.ts index 7272863..09485aa 100644 --- a/src/functions/autocomplete.ts +++ b/src/functions/autocomplete.ts @@ -1,4 +1,4 @@ -import { CONFIG_POOL } from '@/modules/Configuration'; +import { CONFIG_POOL } from '@/helper/configuration'; import { DEFAULT_CONFIG } from '@/wormhole'; import { getAlovaJsonPath } from '@/wormhole/functions/alovaJson'; import { Api } from '@/wormhole/functions/openApi2Data'; diff --git a/src/functions/readConfig.ts b/src/functions/readConfig.ts index 768a801..4cbc64e 100644 --- a/src/functions/readConfig.ts +++ b/src/functions/readConfig.ts @@ -1,134 +1,53 @@ -import Error from '@/components/error'; -import message from '@/components/message'; -import { CONFIG_POOL, Configuration } from '@/modules/Configuration'; -import { getFileNameByPath } from '@/utils'; -import type { Config } from '@/wormhole'; -import { readConfig as baseReadConfig } from '@/wormhole'; -import chokidar, { FSWatcher } from 'chokidar'; +import generateApi from '@/commands/generateApi'; +import { CONFIG_POOL } from '@/helper/configuration'; +import { highPrecisionInterval } from '@/utils'; +import { readConfig } from '@/wormhole'; +import Configuration from '@/wormhole/modules/Configuration'; import * as vscode from 'vscode'; -const WATCH_CONFIG: Map = new Map(); -const NO_CONFIG_WORKSPACE = new Set(); - -export function createWatcher(workspaceRootPath: string) { - return chokidar - .watch(`${workspaceRootPath}/*alova*`, { - ignored: [/node_modules/] - }) - .on('all', async eventName => { - if (!['add', 'change'].includes(eventName)) { - return; - } - let configItem: Configuration | undefined; - try { - const { config } = await readConfig(workspaceRootPath, false); - // 没有配置文件或者修改的不是当前的配置文件 - if (!config) { - return; - } - configItem = CONFIG_POOL.find(config => config.workspaceRootDir === workspaceRootPath); - if (!configItem) { - configItem = new Configuration(config, workspaceRootPath); - CONFIG_POOL.push(configItem); - } - // 替换配置 - configItem.config = config; - // 检查配置 - configItem.checkConfig(); - // 刷新定时器 - configItem?.refreshAutoUpdate?.(); - } catch (error: any) { - message.error(error.message); - configItem?.closeAutoUpdate?.(); - } - }); -} -export async function readConfig(workspaceRootPath: string, isShowError = true, createWatch = true) { - let alovaConfig: Config | null = null; - if (createWatch) { - // 如果监听器存在则先关闭 - if (!WATCH_CONFIG.has(workspaceRootPath)) { - const watch = createWatcher(workspaceRootPath); - // 加入新的监听器 - WATCH_CONFIG.set(workspaceRootPath, watch); - } +const AUTOUPDATE_CONFIG_MAP = new Map>(); +const AUTOUPDATE_MAP = new Map>(); +function refeshAutoUpdate(configuration: Configuration) { + const { time, immediate } = configuration.getAutoUpdateConfig(); + const oldConfig = AUTOUPDATE_CONFIG_MAP.get(configuration); + const oldTimer = AUTOUPDATE_MAP.get(configuration); + // 过滤掉已经配置的定时器 + if (oldConfig?.immediate === immediate && oldConfig.time === time && oldTimer?.isRunning()) { + return; } - alovaConfig = await baseReadConfig(workspaceRootPath); - try { - if (!alovaConfig) { - const idx = CONFIG_POOL.findIndex(config => config.workspaceRootDir === workspaceRootPath); - if (idx >= 0) { - // 关闭自动更新 - CONFIG_POOL[idx].closeAutoUpdate(); - // 移除配置 - CONFIG_POOL.splice(idx, 1); - } - if (NO_CONFIG_WORKSPACE.has(workspaceRootPath)) { - return { - config: alovaConfig - }; - } - NO_CONFIG_WORKSPACE.add(workspaceRootPath); - // 提示用户创建配置文件 - if (isShowError) { - throw new Error( - `[${getFileNameByPath(workspaceRootPath)}] Expected to create alova.config.js in root directory.` - ); - } - } - // 能读到配置文件,则移除没有配置文件的标记 - if (NO_CONFIG_WORKSPACE.has(workspaceRootPath) && alovaConfig) { - NO_CONFIG_WORKSPACE.delete(workspaceRootPath); - } - } catch (error: any) { - message.error(error.message); + oldTimer?.clear(); + AUTOUPDATE_MAP.set( + configuration, + highPrecisionInterval( + () => { + vscode.commands.executeCommand(generateApi.commandId); + }, + time * 1000, + immediate + ) + ); +} +function removeConfiguration(workspaceRootPath: string) { + const idx = CONFIG_POOL.findIndex(item => item.workspaceRootDir === workspaceRootPath); + if (idx >= 0) { + AUTOUPDATE_MAP.get(CONFIG_POOL[idx])?.clear(); + AUTOUPDATE_MAP.delete(CONFIG_POOL[idx]); + AUTOUPDATE_CONFIG_MAP.delete(CONFIG_POOL[idx]); + CONFIG_POOL.splice(idx, 1); } - return { - config: alovaConfig - }; } -export default async (isAutoUpdate: boolean = true, isShowError: boolean = true) => { - if (isAutoUpdate) { - // 关闭自动更新 - CONFIG_POOL.forEach(config => config.closeAutoUpdate()); - // 清空 - CONFIG_POOL.splice(0, CONFIG_POOL.length); - // 清空watch - await Promise.all([...WATCH_CONFIG.values()].map(watch => watch.close())); - WATCH_CONFIG.clear(); +export default async (workspaceRootPath: string) => { + const config = await readConfig(workspaceRootPath); + if (!config) { + removeConfiguration(workspaceRootPath); + return; } - // 获得所有工作区 - const workspaceFolders = vscode.workspace.workspaceFolders || []; - // 检查所有已存在配置 - CONFIG_POOL.map(config => config.checkConfig()); - // 读取所有已存在配置的缓存文件 - await Promise.all(CONFIG_POOL.map(config => config.readAlovaJson())); - const oldSize = NO_CONFIG_WORKSPACE.size; - for (const workspaceFolder of workspaceFolders) { - const workspaceRootPath = `${workspaceFolder.uri.fsPath}/`; - const { config: alovaConfig } = await readConfig(workspaceRootPath, isShowError); - // 过滤掉没有配置文件 - if (!alovaConfig) { - continue; - } - // 过滤掉存在的 - if (CONFIG_POOL.find(item => item.workspaceRootDir === workspaceRootPath)) { - continue; - } - const configuration = new Configuration(alovaConfig, workspaceRootPath); - // 检查新配置 - configuration.checkConfig(); - // 加入配置池子 + let configuration = CONFIG_POOL.find(item => item.workspaceRootDir === workspaceRootPath); + if (!configuration) { + configuration = new Configuration(config, workspaceRootPath); CONFIG_POOL.push(configuration); - // 读取新配置的缓存文件 - await configuration.readAlovaJson(); - configuration.refreshAutoUpdate(); - } - if ( - workspaceFolders.length > 0 && - NO_CONFIG_WORKSPACE.size === workspaceFolders.length && - oldSize === NO_CONFIG_WORKSPACE.size - ) { - throw new Error(`Expected to create alova.config.js in root directory.`); + } else { + configuration.config = config; } + refeshAutoUpdate(configuration); }; diff --git a/src/helper/configuration.ts b/src/helper/configuration.ts new file mode 100644 index 0000000..245b18a --- /dev/null +++ b/src/helper/configuration.ts @@ -0,0 +1,4 @@ +import Configuration from '@/wormhole/modules/Configuration'; + +export const CONFIG_POOL: Array = []; +export default { CONFIG_POOL }; diff --git a/src/utils/index.ts b/src/utils/index.ts index e69de29..6aff5ca 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -0,0 +1,34 @@ +/* eslint-disable no-bitwise */ +export function highPrecisionInterval(callback: () => void, intervalInMilliseconds: number, immediate = false) { + let isRunning = true; + if (immediate) { + callback(); + } + const timer = setInterval(callback, intervalInMilliseconds); + + return { + isRunning() { + return isRunning; + }, + clear() { + isRunning = false; + clearInterval(timer); + }, + time: intervalInMilliseconds, + immediate + }; +} +export const getFileNameByPath = (path: string) => { + const [, name] = /[/\\]([^/\\]+)([/\\])?$/.exec(path) ?? []; + return name ?? ''; +}; +// 生成唯一id +export function uuid() { + let dt = new Date().getTime(); + const id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { + const r = (dt + Math.random() * 16) % 16 | 0; + dt = Math.floor(dt / 16); + return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16); + }); + return id; +} diff --git a/src/wormhole/generate.ts b/src/wormhole/generate.ts index ef6ef4f..2455edd 100644 --- a/src/wormhole/generate.ts +++ b/src/wormhole/generate.ts @@ -2,11 +2,11 @@ import generateApi from '@/wormhole/functions/generateApi'; import Configuration from '@/wormhole/modules/Configuration'; import type { Config, GenerateApiOptions } from './type'; -export const generate = async (projectPath: string, config: Config, options?: GenerateApiOptions) => { +export const generate = async (config: Config, options?: GenerateApiOptions) => { if (!config) { return; } - const configuration = new Configuration(config, projectPath); + const configuration = new Configuration(config, options?.projectPath ?? process.cwd()); // 检查新配置 configuration.checkConfig(); const outputPathArr = configuration.getAllOutputPath(); diff --git a/src/wormhole/readConfig.ts b/src/wormhole/readConfig.ts index e6355b5..eafe4e3 100644 --- a/src/wormhole/readConfig.ts +++ b/src/wormhole/readConfig.ts @@ -14,7 +14,7 @@ const alovaExplorer = cosmiconfig('alova', { '.cts': loadTs } }); -export const readConfig = async (projectPath: string) => { +export const readConfig = async (projectPath: string = process.cwd()) => { const searchResult = await alovaExplorer.search(path.resolve(projectPath)); alovaExplorer.clearCaches(); if (searchResult?.isEmpty) { diff --git a/src/wormhole/type.ts b/src/wormhole/type.ts index 7e17910..2a03b4e 100644 --- a/src/wormhole/type.ts +++ b/src/wormhole/type.ts @@ -71,4 +71,5 @@ export type Config = { }; export type GenerateApiOptions = { force?: boolean; + projectPath?: string; }; diff --git a/src/wormhole/utils/index.ts b/src/wormhole/utils/index.ts index 8cf11ea..c618bf9 100644 --- a/src/wormhole/utils/index.ts +++ b/src/wormhole/utils/index.ts @@ -93,29 +93,6 @@ export async function fetchData(url: string) { }); } -export function highPrecisionInterval(callback: () => void, intervalInMilliseconds: number, immediate = false) { - let isRunning = true; - if (immediate) { - callback(); - } - const timer = setInterval(callback, intervalInMilliseconds); - - return { - isRunning() { - return isRunning; - }, - clear() { - isRunning = false; - clearInterval(timer); - }, - time: intervalInMilliseconds, - immediate - }; -} -export const getFileNameByPath = (path: string) => { - const [, name] = /[/\\]([^/\\]+)([/\\])?$/.exec(path) ?? []; - return name ?? ''; -}; // 去掉所有为空的undefined值 export function removeUndefined(obj: T) { const defaultObject = Array.isArray(obj) ? [] : {}; @@ -131,16 +108,6 @@ export function removeUndefined(obj: T) { }, defaultObject) as T; } -// 生成唯一id -export function uuid() { - let dt = new Date().getTime(); - const id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { - const r = (dt + Math.random() * 16) % 16 | 0; - dt = Math.floor(dt / 16); - return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16); - }); - return id; -} // 反序列化 export function deserialize(serializedJavascript: string) { // eslint-disable-next-line no-eval From 3ad72a6f028aa186cf224a28f0a4c4cbe7a11594 Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Tue, 3 Sep 2024 19:22:30 +0800 Subject: [PATCH 05/47] =?UTF-8?q?feat:=20=E5=88=86=E7=A6=BB=E5=87=BAwormho?= =?UTF-8?q?le=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .npmrc | 7 +- alova-vscode-extension-0.0.3.zip | Bin 775882 -> 0 bytes package.json | 1 + packages/wormhole/package.json | 14 +++ .../wormhole/src}/config.ts | 4 +- .../wormhole/src}/createConfig.ts | 6 +- .../wormhole/src}/functions/alovaJson.ts | 6 +- .../wormhole/src}/functions/generateApi.ts | 10 +- .../src}/functions/getAlovaVersion.ts | 0 .../src}/functions/getAutoTemplateType.ts | 2 +- .../src}/functions/getFrameworkTag.ts | 0 .../wormhole/src}/functions/getOpenApiData.ts | 4 +- .../wormhole/src}/functions/openApi2Data.ts | 22 ++-- .../wormhole/src}/generate.ts | 4 +- .../wormhole/src}/helper/lodaders.ts | 4 +- .../wormhole/src}/helper/openapi.ts | 2 +- .../wormhole/src}/helper/schema2type.ts | 2 +- .../wormhole/src}/helper/standard.ts | 0 .../wormhole/src}/helper/typeStr.ts | 2 +- packages/wormhole/src/index.ts | 8 ++ .../wormhole/src}/modules/Configuration.ts | 14 +-- .../wormhole/src}/modules/TemplateFile.ts | 11 +- packages/wormhole/src/readConfig.ts | 44 ++++++++ .../wormhole/src}/type.ts | 0 .../wormhole/src}/utils/index.ts | 0 pnpm-workspace.yaml | 1 + src/commands/generateApi.ts | 13 +-- src/commands/index.ts | 15 +++ src/commands/refresh.ts | 18 ++-- src/commands/setup.ts | 12 +-- src/components/autocomplete.ts | 4 +- src/components/message.ts | 1 - src/extension.ts | 10 +- src/functions/autocomplete.ts | 26 +---- src/globalConfig.ts | 4 +- src/helper/configuration.ts | 2 +- src/helper/work.ts | 95 ++++++++++++++++-- src/utils/work.ts | 45 +++++++++ src/work.ts | 42 ++++---- src/work/config.ts | 8 ++ src/work/generate.ts | 22 ++++ src/work/getApis.ts | 21 ++++ src/{functions => work}/readConfig.ts | 39 +++---- src/wormhole/index.ts | 5 - src/wormhole/readConfig.ts | 25 ----- tsconfig.json | 5 +- 46 files changed, 393 insertions(+), 187 deletions(-) delete mode 100644 alova-vscode-extension-0.0.3.zip create mode 100644 packages/wormhole/package.json rename {src/wormhole => packages/wormhole/src}/config.ts (69%) rename {src/wormhole => packages/wormhole/src}/createConfig.ts (63%) rename {src/wormhole => packages/wormhole/src}/functions/alovaJson.ts (90%) rename {src/wormhole => packages/wormhole/src}/functions/generateApi.ts (88%) rename {src/wormhole => packages/wormhole/src}/functions/getAlovaVersion.ts (100%) rename {src/wormhole => packages/wormhole/src}/functions/getAutoTemplateType.ts (91%) rename {src/wormhole => packages/wormhole/src}/functions/getFrameworkTag.ts (100%) rename {src/wormhole => packages/wormhole/src}/functions/getOpenApiData.ts (96%) rename {src/wormhole => packages/wormhole/src}/functions/openApi2Data.ts (96%) rename {src/wormhole => packages/wormhole/src}/generate.ts (88%) rename {src/wormhole => packages/wormhole/src}/helper/lodaders.ts (97%) rename {src/wormhole => packages/wormhole/src}/helper/openapi.ts (99%) rename {src/wormhole => packages/wormhole/src}/helper/schema2type.ts (99%) rename {src/wormhole => packages/wormhole/src}/helper/standard.ts (100%) rename {src/wormhole => packages/wormhole/src}/helper/typeStr.ts (99%) create mode 100644 packages/wormhole/src/index.ts rename {src/wormhole => packages/wormhole/src}/modules/Configuration.ts (89%) rename {src/wormhole => packages/wormhole/src}/modules/TemplateFile.ts (85%) create mode 100644 packages/wormhole/src/readConfig.ts rename {src/wormhole => packages/wormhole/src}/type.ts (100%) rename {src/wormhole => packages/wormhole/src}/utils/index.ts (100%) create mode 100644 src/commands/index.ts create mode 100644 src/utils/work.ts create mode 100644 src/work/config.ts create mode 100644 src/work/generate.ts create mode 100644 src/work/getApis.ts rename src/{functions => work}/readConfig.ts (59%) delete mode 100644 src/wormhole/index.ts delete mode 100644 src/wormhole/readConfig.ts diff --git a/.npmrc b/.npmrc index 37d1b60..a91159e 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1,6 @@ -enable-pre-post-scripts = true \ No newline at end of file +enable-pre-post-scripts = true +link-workspace-packages = true +prefer-workspace-packages = true +recursive-install = true +# 使用淘宝镜像源 +registry = https://registry.npmmirror.com \ No newline at end of file diff --git a/alova-vscode-extension-0.0.3.zip b/alova-vscode-extension-0.0.3.zip deleted file mode 100644 index bef1909e46a6e5fc96c4ff05d44becd8220caacd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 775882 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 W|07Wp$x@e-Fy)sNt!{Ks-IDw1~oy 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

E4Kfv4U%jvWWfJw-0r z*#pWdH?bwbRJg$Yfl(!&0s?HeS6qvR;4dYp z2nqt;LGUo1-IfYJ6E4Q&%o^t7Y+#E}uU!7c-lw@M7A{OZ-ALgVt4dOE(T}F@{bWuP zEti2I9Blj<3vb6iMdoSUW2g9rRUG$~WL0rw zupH@2J%*!a=Hw3I7#v9`&s@fHpLf6cy7jQI*#H2>BzuqNEvbaT5&5}iwQc!wz-OA3Q_Q(j9bUs7oWc#&`rm$Q=3*m@dA-N3uR zebdk`y{&wbx(s&UWJnRR1vmQ6MaE{krh;P^%Ifj48D58%q18L;oCp4Z#>ixpF3B&s<(zNyAx5N8-{cDVw4* zHO@by#riDR&9rgt&*=wj$5u>8)r7cSpWaBOVZJO305YPUQkhW~&To9m3IzxWVxr4> z6;ztKOimSLze}pb@rt)NYC-^Cs|tsDlqd~qmRRKX{lXrKNT%aXB3VnLDT_r_<$Of( zHp$Z`n#fVUUV)tlQEwQ(KXMCoSlA9uoF;-ejWX%bJx2qTbc(A5-rab&Rb*x7oZ7DP z%0Ge9{qb|EKQUuh3J4=12t7SGO6N7WwDms30GGs!PrmCdunB>?uOD;GEII>vZ+TPx_%3g-Gnhh;f zA8bN6qqHpDHD$3eO}S`ic1^7Rvcy4)J*i<(B2pze)Z$u}iDWEjnfj@nI5{*Ds#sDI zY~($(dI+^~b@Uvys+j2z`t(UlYvoDa+ye7*50oieH-btr6Z$%gC-XPB7+$riuQ^$G zrELnmfkhk5VZatM1V;VLySmL`xtKsMTRt*%T70Ol6D`=04f^&VkI=5O!aGIIve<>@ zGE5shz+E+5uNSb8qsYA3En{)b^~2hwfJP$4#HpYEuk$Qxl?eA|w^9>$X@P>J)B1Yb z5NOq#-NH{^KmGo!qKXyJzsgNl@&iaA%TU;k z=GrsEROP{UBuxHZ`XlGw$h9HlSzF8>dD)=NL4XWVSJ#Z^hU5<}5z|fb>p_D(f|Rp) z82|kXxYA;t=Y!&UB;2!+z>7o^{MLGNdT+`X)?+ zMX1CY%T{H94i?d}0`4Q$Y9|cE`Ymn8Y6XI15Lg*T5zJ``mpK~kj&-KJro9-NODLwv z1~2)*n)KJ7b4QvO>1h+$!qZ2}Z?cSlpsAwW%nN3hY-?m4$#0;9Q%oGZ7ISJi&Rfo< zR}l^@ZV`OM`nmTn2(GCc&M7IZt{aQg?(xtSTg_5r6KO<=ffk@YBSE{bZss&=B@x>j zZ!s76V}On&ZT|#J8!5`~Bif*M$g=k$z!_MD7mr_J@#P66OIF;#IdWYmbM#{>*@DW3 z>VLq7>VKMsi_#rT+tqah{b*wYyWF9vO8cKCHlWv^&UK?gp^fm$x)Bz4jMS?p(kRb( znIISEzod1Zpv2LiY~)fVk`ojY6nrH}S6{gp|1b9917%p%X@YTbNa9WDB%acf!JBS; z%}kK(MEV03P1G$%X;3lP_G?&`5NFC$`=;w+k5Wz zuFFREs@V=k{`T$|NVBl&ZSStv6hf6=`OBl*NZzhE1<x*K z5Vw4LPwZ{nwu?idB3guE%C=aG(2Hyoe`L8hZG7FzOeqV?MqJDpSV=YlRL{(`y_{BaZUpMFF$ey%TW@m$9z zl*A96>ob8brDILcv$hg?36ra8dOxFNtmuO**2fhr2lUcCo6F8ahE&26N)``wer+NZ zb=WVB417AWYp~!kNY_GUmDoEKJQwq00&)B*)G2@$a!^r42&LfShDfxVEYe!c?=;)O zd@puMH|uo)N<`0cb)&HYt2XuvV{$i*?A}rc~DT7>)Mx#+;rwi8Xt5Gm^an_??OcEz^94A}o02{>%_j*prB#a~KUd}05 zUio1d-*z$K3NL=TV86l$ycaA}_Uj(11cuZ@ zry}-C}G5tWVA&>VHDK153p(J+)-B;7!i~ zga2WxJ> za+QMNE2Uz&6S7yM^#LvyP@Vn9lIg=OEz%<$cBaUXAEnU{kH^^SG+@poY5OIf%_+W~*VZrPwt-ys6Qc(WdTCtKC;)_pD^PdQGS;>rU zUfLZl%-lR}&#Ug1j5t>rf~-0J;k8j~lBpQe9YAwzu-*{=$tMnypAN)R!SQ%KB9@{@ z6MA{cx7ts0J1wT+#f0r~$=pN^Ukz1Gz_%*L8xtA1s$xj*gXIzi1cR=meuA+tc^e9H zy^g3|SW7?)rQ_tkqyO}F6hW1!Lj_U^K-IfbJEAkNC?zKYl#~jH|PAIu! zNd8W%ws_fEycFCM{%e`~7a{e&MpXSemUd~7j1Av<)~L~Fj4g5>QO_E6IsG-ZNaqSz zbhlR+L{cEyS)>tCh|}H$*Fh?rrM>TbIy>&{gR`_@|DZo0bULHU2a9Or(&DAEbrd$A zukd|n2Ojq9kUznXoMn+F8I1||&C>)UIE+w%g!1i`ig4R(`+4ygyC>X|^b5qyaQ`xz zx;&zuHM)slH7jXcS<)o%!{Bd9DuQyY$Q^_r-f0|HCNa2jxP$V3>p;@_d z@1pkdg<5W0Jx@IvG}5g{my;w|0P`1po}%rh6ezUOea>YtyGdYC+IIQy0umABRgS>S zfM+m*^n?H}!o3w~FeEy5TpLYiXs+;Bf0zC_Fe6eqtGMp%A}lO4sj$IUp#0o21&)Q+ zY%LU{XHlusU^CvlsS#1b**9kD4FdO!Mi}P=|oAGU8Wy8a8lz`#^nlLRkH% zzWYi~-Pi)x<)wM;CCYppv58TAVz64H#h5I}f&_%(g0ZU<7Hpbx&eT$^O!Zc<@XVWz z7ULGSI2)6h)?$_g3~aTNJop~D2_A^^ z=iO&`pd|hOEIbe@JPx5h#{;oi^uPYUIYh8U54(lq&s<{{ z{%<{de?4;cRvDS)y`y0?rs3Q;inGE|9C|Z2irB$$OomzqWI7rG3vM{prtQOA9f?%o z7=Vj^AGnZH!`5+Ha*{7hS%c)VA-A8Z2b!)!9A(5z4=!zaIA1k!$zUdd*K7qp%bZpq zrs#XOSEFFe1O&+EO=>lt8M33m)gSEvsUjlr24q)QP$~4 z>2G*H4!0=B9Cu#7>z{Rx-W?5&+pC05ftz$s;b{$DvjliZ z5J?=oXN0b0WiBgqdbj&}^nCYPm1Zf=Tad=mS0a!rQzu~xgAxikp5u*n*`wOYK(9&&GfFta^PHegB4gHj zVb%6?<;^jeQMahvt;G2mbP|;ld3|b45-}@Fb+bukv1ZZ^=ZNaZ2;8)Qy>vI8(hfMg zCy8e#KmYurvz^o?D|WM3uLO?r}4Y^mL^a{5288RKC7JW zoHoXG!`YdUa`ezho6GW#E?J>BU>?fKh|ilS`0Iwsj6e{@0p$ga-~MzO!0i0cNM879 zN|Oi%7vX^TOU)XSBb;NP+J9sWWAYAb;7izA#7q2llVYQw4bQrp!1S)DKedR(6$&Bj zcH&Q{r9I|)43|?aVx~13Tg1Z4OzI_4T|lZkeS$yQR{zo2{^D={4ZfOBw@(}6`ucQP zN41|b2qDX5vpc%v`Mq&Ma6DRPyv7+wbNl);c@l^5P2%?El(5w~io$!hKd0o%U-oX` z67W;HbZ_UB_+fYqHj5pQJOs-$h$bn{&z;XHxeStJ+Phg$cc0b1au1n00kZ`KMS8WF z?i*+jDr;#+P%%vx?`e7!PnYgHka_q~kOoWY_9FG86Nc`4CCS_8kNUF{O6D7Gp4W5g zCG@YGAfdK(34SU&k(L6y8OtHvE0uJUgqA}FbL!oI=F)9My#aiDeW5XTFJ74Z;K4Ox z2cyu2{5hxI6)H1m>a{I(qlmUOLV1e3M)J8$0gdlu6m z0!^nR^1}hWT!Q}%aHEY(8WMvX#0~9*FDVA#Gsai4SH-g7uAC?a?U`fhAh19 zmC#;t2&eTpXLr_eX292lxA>|=oYd54ry(%pkb3If!Vd?(hoj!uP;~$$JG9xEjv#Mb zt5t`MEl_fuvf<9X!L|MMg`E({XLkFsShH8VxmC00$d+qIHw|{~AQZf-ej%0O)UEx* zpP|Mx^1E)3g2xVsD$58Mhp;AblpVo4>u`?SDg%{DKlMX4+ODUmRm)D0C#ZU=u-&Uz zb(|8L(SpI0BflC6MTu-zc=|=2ahI`9E3Ad=)vLSz*eZf9(AL+*I_;C)64W zD{Y4;Z{v+fU6q~xQuqzfYH<}{g6^DHciY!N5?d~=Bx@U?V)KSs0~{i7PC@zHB6Ek# z>h(+xa>1_lNgRq%cCQ4N()JlpXlf{}&0VRTW%O&^8qnJ$NTF|WASyRWh}?As43@vN z$h-t5h9fc8v4&vS6x-dx*bHPR<7AnAg# z{D$dtAMU%0v-`K!|9jS+P1(`;)eJ=y(GkZ*8Vj94DSJ|LBR!FrIS&Eueh>xAD{$ji zf=e8tX|W7%Rlw|o8|Ez6YxOPsOiJ|%<3%8gIn-lM3K_~t!}NKk6$m@|qjj%MU382u zeb|@X>ew{dSI6c*IgHC^%-%9XUsc`Mj~n)KsOD zRyiPvS%7+8eacnoK*Ns2UaVmsW@019mN;bS!R%)eQGlaEfip-Co!Wyo6Pt0n=XE0K zmCBCWG2lFS@FtGi)6a&HWym8p-r3zw_ZPUcdtm6pq+5e)TdPXuo^hFb9h7(0YWCdw z`of-*g}84pX_bL{ExcZwk_)B_%}zI8FTMJLtJ{j(C3@_3;ovj(P6qazbiibZ^g#AB z_lCFj9KHg3aBa^Wmi$3B#};kQyftiEpo9L9tqu|XPJs+k-=pDJdZ^M9?HETAIgRv+ zMvCz2Xb&@ESxE=R+hI~OP5Ktt9X9Yz<}{cW481X-V_ZJ`4pu{e0tuT=#{f}nIYLxj z;0r{JOPWrug!=BvpMmmD)WH9lrj?AvY`|5yna&Y^%u$$r12z(S%_b)0sYRZlW^&3vup?<;!^g2%IzjeY6jT3g5 z@uSr(Ia=H;OPB9!`Tlj$qJZ@QM~4mmsRui-=e*M*{LdfkcW#^{T(`$ZF*imr=jN;Y zl$1c2kY3EG-2>|&Lz6V$od9qbt>J}d1 z$flDO0(g{@1&%8oh2vVScZ(l{0i7cZKp_n^AXxaH;_H+V9G1m`!;Ge55jIDcfcQ?1 zW7;DfGM583n(ft*vE;Od!l6+qnud5yl|`Jg7-kjlP0nJ-0E=ViOl~TvI166=L%haevg{t{GA zr(E(5i~w9xEg=Jm%~W{}Wu!1B@uvf_i4%MdP`HZ35*yVzX^TGekQ9#zd_zoOiC`ew zYhg;{W_!c>j5{*~TY|wg&Jwj;_yZY#<3t&keZjShFrCeN#L~vzEXy+C=v=>1TYO$P zey*Ykw&zqR6?vYPec>-f;6Zhxr=47O!gHwISDq_kP!&c8s8xspqyZD-YUS6t6~an~ z^*YgVSWvtrKml%QQ9yw2AUVyLP=k#}W&(B#BjAc`XjXQYVmu|%VXy{zXmJ8@hy4&h zZ2_8AH;XBF^z;@=#cWDu5_~w+bpYVBzJ#^-ut;Oh$cnXtFBU#ycg3gd&I+r*b;^qw z$|?vzQZE3%;h8;aAm<(go3U}!Yqjda{LNq53tb{_8)dwFBYe)NC%52U*nww@sdyxv zR?q7(nX@9_0pBtrpkrcj4U~5*FvG}YYX@e>a>$`Kf4F`=+pI5$m~O3BJp|2>!&V_Yo=I@;5XQ>ObzjHd9Ore$iq9A4ax$(akgMN*V0;}=he3b01zi-& zar3L=b;wiZio4;56_gRcN^3J_5A!)YhppW7=T25U4x?cXwTv~1Cd8$CLWK?329V>B zG3}kKNLKmIY7>3nJ0wC(%eA^!A}%t`T7ejdSAzQTcyde<@aV*BUw@gSTVyCRy_rzk zW`S}OhL*u6y3J8^UQ?dA$b}e9Q?TDHat6@pu3|UIXye5pa%GRPL)hJsyAuLu^~;>v za+3Lc=2tO)>y|7kiohL7h1Ul`p$(St`OeDkoWjEM{@dWC zD7dEaO{!1gE2s~yw=A>hkzGX+%SuSyoB#$FWyLaV4ws$k`fb(0|;fce_(>fX-nJZ)TZZV`BF3%#NOPYXO zKZ)0C&O`P!wmVo)p*7ogo$q3;U~?@H7P8ZtFtu?6DPjm~zJjX0U2n9kHqgl@20z8lsItS37xa2~)m(lj!rkLmaVdr8?;g8N$nDq9OM zZ;a&aEMWw-nSSO#1_%rllRcs31hC1 z9+fIjX}2o-34QB&U%3IOENv7Endq42yLt|Hg`=m9{BcVkfy&vj>OOQG^In*KBxL}{>x>EyCAhedZ{%l5*Jx*U(Dk|^GMzirR%iz~q-8lM6leBWoYE||c z&5Fj<0G`3of<~Q1Pf%H)F*=d~Y1F8XY|Yy7#i$VCvjt6cxC)!4};VOcBo zm)o)_D5WQ`=3;-DLJodF5|ZP(p^DlC)c`;Cs)3ek&7h01*4eDdv}#4ezXLTaYrNT!oQ$laCvW$6%zUB(j8fJ zx!2tN(HdvtaYhn~E-B;W-d)`!;Zp|Gm<6eYH;`+=XGSh=X3Ndhug&T^!E$*+VG;bB z^eRqV>wPe%m4P2Fu9k6B`S}_gbtU}gf6uP{0OP{EvIv+PL`&*guaA4%&$qjwe*-6F zN*5Gd0Zu?cbY+3*!S*%XzV`1gU`zhkZ8RYsuLUu)w(*4kse6qVxzz2eJ(lsj(G(e= z4+(k~OUP+9_ArOfWE=eM#gXXZUpz-p=&Y?D8!vb|6Mk$15@DIUjorqNCJ4ot@gr+3 zp_geKhf7}cCyRhDPxh+`1G)E;8Rovk8D?Zo?{DK|3cJjK6?KyN2@+p>>hn27W@l#y z%d+n!!x(Bz@|$JI84@cDqLlxmi8Us(ApM2~9bfpF(wcuygnTT{#T&xm^aXvUK6 zQ|}1B-bSd$OOk!+y+@s24U3X!pL(w`m2Uxg3s%C<8@SiEw`3XT-39_;E_WCxe3hdY zSnGK2h$C^`LtvbDFt?1s5)oekDttvE#k)yf-WeJ4PR%3W;Ziz?z-K*ZjJJ~!`ys67 z)@$o-d$|{Hb60xS*rP5ED$-t`!M^U*g<@cFFa$(rn7~$`OXOBf13-?~K?DG+(UwNK z;TSTXw-U4h#FBG!xtR?2R(wEUGUF7mfN+{2q=-tn%G^TkuFRz>T9&MUM3eZ5-NT%U zy+bNG7vt-}1=;%AAb(S{VUceZ$Y2a_PGunz1-~H1n6h!HFrz`}N<2n002BywX2F(N zj@lXsz{9xc%o~1SMmc&LHF8@0j@&KS0{)uuG3GA_p~P@U@z}|Hz6|2EhOAa!#2w*- zB!#zJvu!@qT(iW_d$@f#T=l+VZ5eigGSAU;{tlP6^$wyPsh2_JGKsG%SlA-y`ylsF z%pTlNn4h_8yZQj(AB=$ufMeUT(RT=}zEj~+b||ExJA(V^sDcY`fnhn7>&Ro-v29dA z8Rbf9+bWmrUr z>PM^vkq+Yq)TX&_mwBA!q7ndlc60b^6Pd4iEG+vP%C{~f7DLvV!$kTX5c>S?zQJi`z z$*6)Un!_we;=pf>^Pnh?MXsFLqD(fMHSQM6aD4JWv4(y_DPRLOu6dP}RW`XDahDpld@NBUG?-hU z631|FqlPeHGrdB_`?(N;k#LD7h&5E!;m4n8d4RLahcp2=mPpW@Qf6D_jv;zsB%(>DTd@$$^^Gni0HjHc$`yjrv^{>yUpB03B} zA^F=Z#+7PRf6TJ`GKco`Kwl&zGSZILkN_h23MBooK_L&bGW9SMm`6@T|sov!z!WPzcz4 z1-=%bUm@$n?c(YS78vhA)YV)*N;Istde;DoDBeOVEa#560$E1rICI=$F`n(<6w%8x z>a)e5p=E7wGYwu-3wZTgE-o#z>;@@bZVz8$c-f6xF}um)|2;RE=6+hdNenVG;Q-_a z00Wr}TV9bhipGW}0@DN$tt8C%u1UMX)xZfP{isGxD*_Mi=qWuJkAg9-`Y6)qV*II( z`$m6D$@lDqzYHe&gBArkpl<@pKt%!l2^<5fd(RTQHt@6J(Z*#M-?rF4gwq9crNDw| z*@0(GP*~GV=#;6@FR@Ws9tA$YJLJU~KRx&xo4|Daaj9pXB%yp=<}B!ZgeQEE=Hz7c#yC94t-H5WCOlXyXaCB{A={3@R`SEj*F*uY4=hapXS9p}cc za>Ni+3hPBp15ozQf`foB@3#0bpWukw-8}Dw?Q~@cT;L$R$43ZVR+d-tbY1yhX$2|^ zZqdEPVz(&o4yM;9V6luitCag4(G-6Ej&vA>)8nvz9{abE0^3BxIf5a`_(N3=*DQ85 zkEglP_>nSIXHIF{Qo;6w{W zs5YmtEhU3{^gI?D$)C-9378EAg6Ei*yBA~&if|$LrHRfAM5ei6;Qkh=gfbsClCwRE z#vH4N<09fUsQV|^9XM#v;BrUl9`Oxn|l7!43WbVZ%$ zU$T1(c$RdTzK*B&aP1_G2 zqH!jUn`s1AnU$K6YK};PeQ9M1#F1st5n0okTS zG>U7tye(8vQB5)8!)%JvOT7NFY%Fb67=(&F8iGe%IN4hmrHeaG>JZCSGg$VX@^aPT3vs1TD@{@r74>*b!aY z&$A63mfVwzbZ&D635M0xjb2IDSCVs8x9i zLzPRYR%HW$sAa`uPH*t@R9Zp_a5lA}*&Q%KZ7epYER$6(hp!q{qL6S1V zf|5!TUmE*oZt#8NG3q|`7x|> zll0?yy@`AjB^Yrr`Vb5t?Z#FRRhQpU0uWx7F*fnPLWH*icmNol&h zOcUx~TjM7eEIo;jm(NZ8o2uqki7nE?QEyd-Wbu-BR>s_=wpt!hu}8mrgTI-!HD*aC z3~eLRaV^WKgOlbu2Xft8xSgle3w|mJhy3v^On{OQybn2zWE4ssh&XQQqBBr!`+o~= zc1wCIo;IEC$p8MHt3y?M(je=?w>J^j<$672ILZLGKbPQfQ=-lupw6L_zZuK!p-&TA zQFcJHO<&q&mqh5aIJ5#qpmV|&QVQGL#HC13y*Sa?TeaF0f<|g767PJa2`D8Y2cg>J zRD}V>>$TqklI=(&p))ZHDO?%yT{VsNeF?<6VQehDR~7~qIC;SQOYk{h6cB46v^;ak zqf)A5{B5NrBz{LF(J)!PnXY1)rY&vOAn!vY}FFS?b zHPDS`^1E7l+6n!xrZ*8%Pi|o20r-a29zDz7(blGu{k={72dDYOQ~w<;JFdBc4*?E% z6fGqL7&!$Ov@x#o^Q_a0542WBoNa9ANhDe^0Ez_|P@`6)DM|T=9wgTt`8X)5a5$@S ziE{6ehqL7R^x#RaF_D!mjH2Jc76zEh;&&CE)6QmriT+?N5tpP_8v9j>2}LD0O>Ssq zB;F=<3ly@fx?i`($V(U2`C5=CBuev&VcYEhz!tELePkfEp!m)1rJ@=+d~LHpe7-l=zNYDjU=lZ}3r#<9M2a^^=61 zd97GbM{(*LNOt| zf+4!IAcPsovALNa9Z*Wun6SQ+XC&ro<)9+>vVCkT^)~*E9o>M^iW^HJG>YX06ml{u z$y6W^JEw1hR(7PmpQ=D0%9kh*_)aU(hL!^d&Fn)myi{6?DdO99)K+~6Z30#7A#H+K zUY0R`e?QxKhT4=G16&}X5HN5oJdW{uH00cA^}FN^uJKKg-ypt6;aF*Wv=$9it@ez3 zvuTl0=u>1g#P)j&C2`T3%SuLC!on-gX2l#k2nHGBdAWk;m1%~ytU_kEw^d_sWaG?T zn_OmX(MR!E&jf?teEx=&h|5;u(GtaVk5QeYuz-X%xLTc)o1RFH%@}+rm{lPJthT^~ z29lHg@K(T}8SvXb_2UFS2%#NR;ANsoaEyZv7`SfQKjAt-#ZRpz@Smo|{xUB>a~9I$ zFw8%!)k2_6c)&V|HuOZp8B^H6R8KD;rlzMkL^Qp;xxNPI$u%yM4apu@W?;H!7Bae! zsj3t0I>>iqWaT>3ubpCHqf;YCn;m-3Sr+YU&0I!x@t>ZVXU#BAEFpz4hnIBth+_-DU#m?u4X6Ah^gL!S z80slvgtH39_|Gcbvtfy#+bWHK;4X`n-9#nZpFXJiU~_eo5A=EY4gzo(-}^1K=C!*@-~P+NuzVl1A~ z`l4>RR-N_H`nEpMXVt~cY`r%3&Dbh0x0HA({uO~msn~O&qh70lU4{BBX{V_=_B_O$ z#H33RRbZ91X2uyR@noe{Qy#BoS*DgMfB*xzwuhdUG@6ZDK+_KiEFgxD74vxT2%5Q$ zGnEH$T6zG@RB18D){E)#YoEgZ?kczGJljD{L0|k_ujQvaw=-~lja$b%U9Z)5iQfWW zv}>`e`YP9lp)^Is@pP-%okP!NkQ>&tDB#Z?MlI@Y}AKpbAuCM1;<-~d&~ z8O_F|mw&_0ScIf9G}nO+j2s@4PEQ+k#)cT&IG6@QDa>a$T_Kk03U5TVPr3p@b_Lq& zfJb&sL@&PqfVw)-1eGMYGaCyVKL}2OlT@cJH%IL_ngvIlae+FT=j!NXxN>WG?r5&o z>M(}~^hSb9`_S_|?jV25D=#)W9JjWlwn8_{iX*>3>6Pv4`n_^}dUAc>_!KKT88JHs zWMGuy0Olm%FIPIk`3&8peFnhxm;%WE-^PKsOfUqRC&6j}Enn=;mZd2RepG z#dZ&|LNx#dFTQcBti?~{kaQ71Jfk}4f*m7zg@$TgH)F^G6u9dNn&Xz34dc1zUI}6l zBJWuBMICIgWy4kr+QY^fp2pyjK$|hWKZTu43bKH>zz|wPT#Iq5e``;fieAY6F&ZVS z$~z!OMW z+!q?kY+fq1*du;R#^+9xE_vMPUwa0dOdXaHW%_rb2d#{W@nmV zvp@FYdPtC?x1kr9wlF3J{s3sBk`?!x;>wT{NtTg#pE^WXDn9^L`6Ki+h|&((L%^ie zeK*39(UP|*Yr{esC4|?A&CLTg;AlYoiMiR;#udsD@=seJbp<}OKBCm-<Z}gCjqikig_+GwI!uUpdOONfPriP53J*~J+n8Nn{gXtWr6Q@GENjm07+5tMSFDo_ND z*M-_MOC8s0Sk_D=`Y%zjny{NJ?{&KTjBh?Zd4Zm05VNUDE0GT=TJn&h=0l2>Jfvv; zA*H%BpHQ^$gc1%4mOS9jXx!o)?()3^d|6HM0ab+0irtpMQ;Y;pG2&+kx~3Om!njUqqPYxRE%zinVexN^bu{_!jFPNJbqm>?-4<`*Dp9d>ww78M+WSK0Hi4s!cx^ud+8}+txn(fR;K8Vg& zKMCL#USiks7nf$q-=L_VT>jrg^C-TJzyY?S&-P=adpuT=KBCK52@vr0Mgbmi5FLv+|XRA90tt%(ZdJsQ9uPID!K?uPjK%YH6C@i`Gr)h3vO>UG340cS@7GoZi z#|_panvqyKRS1Adp$X67w+!@Tv*1vW=CqTBA5E^}WZA|#;1d9?yT^xVLwoF+4zkC5!f3S>~WEN6z~JV zBUw2TN;5$jfhE-LSDr{9qzw`N5?WMi5{YTN{nIi7colv;+!IPOc+o~ zHbN}N*SWQ0!)-PwEkK}fV9f{wR$Y|n=`O&t0Vi@TCP^}Uc}gF#KP$o?T18U%Dqg0J zp@)|zD1~gjEkE6nWsMDoN;bu?nIC*m_|x5I?wsyy?V!Kh1unB4wnI?FK(k6~2jnq0 zg!+`gn`7aSSQE_0hG0H6CFKjvb+hbUFhwN5s4VOt{DuzL7Rrr+VXAGDt;P?kL&OD* zB-LeHst}Q@p>f^#>p%FLPPbt&Vh=*^p)!PPK*C~#IEf*>UW9&1>)N`t)hBEXSr~7s z7L#0IBaLfBZ#$=})7v_{&2$Z%Qjyot6nV|Yt)Y;)58>KHFE~Rkad*h90OFvc!4_vI z_2r37K_?mVR}cwhnxQZ*=iw=a4I15Cw`H=&5+DSOO0%LkqG&$K*=6j*n~r9h!`M~M zM{LGjS!t^_8ghQuP>l_FWZ7o;3mZ2}%D56A5_%cjp|92M1G>cky$xWL!8IDI>yv--wN@U+481cgd8EF_TD790G*(kO z(druysA5+D;=ut!^sx(nGRMbtC1j>jB7zzy?anW8)amNd$lPhQ-Z=88!asb#1{#VnOc zx?+R86^mndDv1WtZH>4CGW0({tY!L>rF;8rifXfK>q=q-2y@EYLt2^ZkI)+A1-MHUH7(|Zg;wuA?hBF8`b*C8YNu|LWi23o_L zW?9_+WdO&Uuk6Bm71#?$tklAL<-<=`lA~ceY+Tdj(w|XR^N)waQp^Zr{m%CD0j?ie zKtb%WVG9z_7M~ujUU__T>!3dbyC5hb!j|(d@5`JDBDjDpd6^?7uqG>iMx)eC8u%ZG zcb0Ec66awsVnAlk?ksl^b*Lv{??uO1fe6TKiv;Ptl1F0kk)JKCcXTZr3hN|!Wp-HJ4SOy zwsla?qvR=b$dC2%TgS?F8dyJ#II=A?$0quM#C0#s9L%KARLjFfR%arF0fusbAq+4S zr@nc5lTmSULCF$ff?Zd$}*e zv|ql&_>TK0l-va6@f|Pri=i8Tn|Rjg>FMc?Mf`wz=c7NiR=-WM@j2N)gPev%?)E8s z)h%+&zSXq4TYk&zDE*SlcSQ?ee;~vwR@>u89dj8tyqS?`&v9RuP>Uds|-g zxKOsNS!1mjAh1arOLcAx@?77yb91&C*@qSN!|3MPwfybBJKJBH+do+Z0_yrA#UlQ4 z5(KVwdV1GvZl9jsz1+9RMd(L!*Q%VJrWTn*DFpPD1$Os&scA3^QrE&pXNkYK!a{qy z*h=3bA*i=tM{w;2QOfdJFa3%|7J$bfal3kI{nyq%YX7vI)6-{l(%5lZKYOp*|2;ZA z9shB5zFKGhV-fUd$wqa0nw*|Sr>9>}PcJQUvsge!I2{Oki=Y1X-_7lx&Mb1r$JyE5 z_qQ)$v{~yW(2(K#&Zo0?{lkOdFYa!0?}ukEejp!?j^BJb8}twQpU#etP6pk+yT4Bf zOL*PszGXYQb9!pGtD|T2_8(iT%w9XA)A88Znel>$M~7#}ANt)lop*TVj@_Lj!XZ3bNYrV7_4r$QecX#a5)3#&Vr@uS) z>GNlf8jD%};N8*d&O3Ll z+kf9b93HzX>)EqsmTNt;i1qB*4*Qlr& zr>_ zoX+vEKX`Ne*8PFE(Ru%&KRE6j_T1-uz@4G{;s^E#%k+C^(Bo(QCtj!984TWZ4*F+< z{_tdQ=2C(zllS}Y`k&4^-ERMI=>EhT>K?s2I&^>hm-zMmeaHQQ=K*T?;f44< zdHt?`_S?zPuZVSLfO@{^@fqgYv0%jL$t5d}Lzi@QL^PECN}Zb;{NyL=>m7Z-lv&&`ODN=i9thri|ySub?GSB-W`jjGMdBIg6&-g=xEB9qe%iMJ3Unifs>tQ zYF9X080vzAl@BHIs0xXpGtV2$F-GKx<=%6c@E01vToPgHw~4tPTYp%@&!=r!B!-7nkl`zjX3o~i&(2#?WXh19bTAvU#~*viWlrPSmUHfq zSRjh~fa2@*%?Tw}8(y!AfO`A4wnJ7XA#pH}WW!*emeLJZFZFx>Pf-dk{?CIAxB90+ z*&Tiv&<$7aZ-Wgq(U-yItN1T56ueP?6~D|Ybt3vK-kT@;MwZ^~)U1{3_@lscaeD^M3&9)$4)z+iiKr|IrG8QI#W2viDM z6XX-)0pf8W5t_hJ-jW|gh)U*1!?+(Ycp)+9HiYnJ0e_|*L}u9DB}1=CdR|jR5vlHy zF8n!!KU?tU3;el&KcC=_4}k$lh=1>?*Cbn%98fZ#!Vb}bFiDH_%54%h8MnHdk@pmF z+3b}Ukk9xzZA`BG1a$v9sXeRjI^>F#vA3vqK#7rGug|!{^VaO=pyjL%sCPwe#(X@& zPz?ucm7UdvHvnOrLci4};l&9S`fX6F*dy;3{JBs615IL6C;OnDa!0-7K%GZ{Eu^`&gG&G^wzA-RdRX6eR>Qitr#7MI&FZ_xo}Q`*yK2FC6MU#(`pY6i@D*dWY~Kl! z;@lL#ataGxw*O+wWDRqp4%pPT*mtdFZ>cr_jp4|@1Fj|<0KTK@U;DIVk&aS*k&e=D zIk;H*BQ!f#P(7#VrZe*tFbD8rH@bc@<+eMkPtdTq^Q%oV%;5}Z07Jd%^~)jcTObEo z_;$#71XQ|w03gAxXZYl)vj zhxE3+p+f*kb$P43SIxG)uh;20(4P3+a~zkI#bT_pspDer(9k|cMzO@lj`*6^YG(np z_o;q!?W;@L0a|jOdi#o6g+v05zZhLB<~^kN$6Exn_?)nZp#KB|xe(>|Hx=EdLQSnt zy%i%|-OrQ+(c&g`DM4b_9TL!8arY@cMBO1J9B;cFB4OQ~3l!TW5^1@IL>+Z^i*Rst zKZ!3<&Znpv$D^w*#lZWtaqZvrkoai=-DDq7XT8>NeV>Xdp+oXCj@B5HP93FEndWus zHCwOKpM@i}*6XxhXQk4_J4)L}X?@onl1}2qqu1$}d_`?H+?X^WodmqxunuZ9`*q6f zK897#YqsqWYDh8;&poCvcU_;U`!(D)&Gq^#2HQd1 zG`137BZnNNUMFGLs8)l)|4gMj7d~Mze#ixlF|7MKg@uzd2}de?xESE;ln+qLDhyPw z#s-}Ap+kltVkpjbXCaKn`ZQ}@X$H~fvFvA^Hk zmT|s+k&K8UL;LLpCWT-~|Bm?@Z+I5a%sad#e{1BoQuPKc;e{Vf2YxgIwuO*%N^Mi4 zfZb>`&`6s$mT{7Dx;64ZU_`kA&$i`c<8#zY0151X&iZ!?I}&Q|@;MK0eBXN&+~|x8 z+joQ^P@`cznHe1}~yhtyBQ|1WX3bd3qP|(jt-)jgbKW0oW6|pwSdGIWu^3 z#qj8g8WVq!-Xs(s`@jO6dclq2xY!A}7dyOdC}!Xk+=v|BHVl5~%prz&wP#9KJ9$Z} z5~Ox@;p3qYGH#i2!Y?^l;02duelq2LK9_8UISJ`K&Ab`eqTVF+UY*-pt3}4Rvsgo&2rZUJr2etm*I-ovj8e|g33<1Gk_?uN7_7qeEg z--CF1YxSOH!2giI!wCsJA|y{lYMXzv4gKt`#Epn*zwY)fzZ#ol8pD=OV@8w^u7o$$ zHrzsGA-GvBivZOG?gZyfXknYc=;yM$qEH_TcT z07YkD*_3>Cba01BTv2$~@8jRk_;*MVEyK+L59`lNr`hv7e|wj_PQA~K1*LP(o}}Kc z&kcY2)sH6ZT~0^!Ixm2ZZsF#{bbjfG%DWC+rO>Elk%Po*0=D=p zv=^s!Z;}#G);mZt@@9$9vijU$3koIpXB8R5ZTZ`sr0mKfUn5(5I~nN)id71;VXT7J zDf3rQweSYF_kixTY-_!Ko!ZYat8F zX-TY9tyVoqYPISGguE7;=!p+S>kg?%;$#aMs(_~;L>UTyry!7(rM>r*DA16}s9dhi zr({_66&+nsjcf^`h$aYL3~-2qA)GvKxK?|!gnc7GhHJY58f0qzGR0YmajTZK(cAJ9 zHT&zLh_GInq;Ow+^@dciI9S)-B+bY)frCU2B=heg#d~r%I!MNVi>6Gs)7>RFH?)<# zP%XkIA{jXA_yI||9YXB!HuY@nin5u70Tf=)sCDeyY*m+*L#|Vs-G7smUw#LPz=fhs zK<3>{E6X=U$oAZ7lh?(=$7{b$GhhR-Ekb zr%ruqhe@G2iS6JsPaCUu?recP@@<-(JEWwCXV}99koPuJ-udIS0h$Xtjj?R_B6Zk2 zKBgZ1)4oUvl1t>$U#4g#2#haBY-q0c)yFhr18~j-yeV`MV?$sXUmJ{5a+ zkYo<|HBxZGAAE9zz;oEG)v7!8AERg0@p`mlgCfT&v&PPj5aKxkg;#gs?oeVgpwD62 zZ&UIyC0`=4m5{HYY9UtNgN@LLS&e9OH^;R}zA1Iz4r6dbV&aTI5MNK_8g zhO2%CH=4Z5K1j%C&=UX5obt4)a4Z-2lqAPT)+Y# zUxg8WRd#u?1m3V`3Ru-kG(1~3T!cwB7>*R*Tsb*oc0jpA#%`HPZ>O1 zf2!Uq)+OA2V{5&ZH>u}Yqx|nbEanzDYAisY&Cey<4p;4ls3RrKY-=>cHA2KSq^uow z_OxsleEbXKD_hfLzR&_JcCM=?d7C=qOO#K4o7VRnvXywh?9p#;cCpG7u*dB)4m~fm}Y=2a=os;!WoCrkyWb!Y*ulB)@zo!%~L&Ga|hSo z!_(Xc&2tX*V~Z`(gWFN4%eRK(0oD>wv1UW8n)Qd}5JiIYDS5NBS7jiB5X0UYY~Bbk z|Fr%I=f=x%6#De(t>OT&9ofF#QM>8xlBhAKbn%-=gn2y$%q60*EoW6uhKS4Q!Rik4 zfFQ^q#?6ZwjN$ZJoxW;w1JmH{g>3;Xgh2*iH0z2W99DKl1Yy&e$bP%jy+AaA z75c7`z`kpX_z=bx=$Y^5MandPtUoM#vK1&@*s&dfhaNxxBx-ODp+525^*Xr8saXN- zDlck&9psRW=m$sq@Dozs%MF8QIvOwGZK~dtZ&S5|GLdnqkUU;*$-4w}?u}O`d$bh+ za)o3HgGMIGV|a?a*VX1|P)>`xY}taHgmF@r=N`^EFJ*1mc%0am<7%MMPa zZuWgT+Rq^@IRk+pfS7s=G)t)|%dt42FpX1PHuEv{LcWuDxsQ||?XAREP|M5-m=h7WClL;y<3KEIMmAZKkkD|x{Ip_yl^C_Y5J z{v^U%Hcb>z_9=N=1Wlm8Khx1?Elu*c@ZI{B?--*#aj@DD7<;TR{fo48G&}5W(Qc7x z3^#~koC>DjE?^k^^d#GpC>|$pKIQgV;P-+7GB9Mzu6)K?D-3g9I?9HiWE4j*H)4$< z#`25;<-_SojFew%$&JH9q*z#p{EeGH9PVnfO0iQ=YcgoShgRgwP51*C;$cEydN1|!Q5YVm#^0XWxQ%`?!0`9^)mTkv8DU(Z(cgpI+$%d!1c7O@u|3SjVyw1Bg;B-9G{5_v$o0DWTg4@kB|&c~)ICEc}}UHzDXP-@g1 zgIHqJ95Y=r0~xX@KMa$czBUAi7exW$MNxqGHS~0O;YC4Scu|xW!VUW|MasD#B-{ca z;n(n6CxBe#i6Xa|;1-NCTkLB6HTIO~`UiZ@{2JG4zs7vUP`9u(L2)Q+Um`KC2cF2bd{fkwtW@Fy z_26K>1my4RoRm*ipI==vJGd1TV@9pFoIDHCoV9wblnn0QT9b)jXY5!K7$)gx7f#F9 zIG9$NZEL*+l8)B@`)hW-wZdh~wpMfCEzGm6)vqyd7IJI#(CU=HPd!B`#fJBTwPTeZ zq%tr!*6-=iF5OPRwA36mp2@=};5%pVeaZzJ!Fkg*JoWH$q4a~e?7dKYmAKtm9f&8p zXEmO+En?>gUV}p7FC>&Hi)sh7E`Q)E9wgsQj^X1+l77bM`n1rtU3d$Z4Aw}(2dOz4 zNK)d(y7xtYYkqMwbt}EpgL4_0+kko!ZSz1>4vmhg{vX=MKph|L(X$@})#!_rhCg8l6(-Gb5i2EmcJ7?%YsP z{e)tMPoScTE8&BUqxb57=3gT1PcD@FBGqQQ+1BcS;<#pRD79uo*1&3c8-NR~1L~|M z{*r=Y0tP_mTdTutYca9^h0d*Of*bx7@d zDjV3MN*tTRhg-A`)aD{3*#7w9sv4t;1U_5S*w68 zRn5U_HF(6%Vd1CXLLO`>Fn&N3|39?7Yk%5EvpD#A&!;e~505l-2>6CABJ&prGE5xE z*f^O9@HmRq#=^412ppV%&S&3WRdq`(fiv@*-F@LUeN|totE;Q)61?J%^X2zc|ABl` zktTO&Mzbth^i8knlgC%j=a*#N-SC~tqw^r5tWX2VV>UO*=pk<;PS+?(Hitnhx==$D zU-70v7;!nRBtS@M2KmVg-h<|cj9l^sz(2&|hHLsx(gYiVgH7@@r45-a*3jq6wYQ)) zEQVSn#)CX#+p+08#IhMOpG9nqJT=bnb=nAHz{N5RM_|ku(xrwk%Lu)-VbW&uk>s(bB<5PGC2I*kn_P z9hEF~p{Cr{#5o@zVEbk$jLUB}n$wJCIU_0vTL8k)u*Y0;UMl%bU*o!wSmc5{1M(I=V48Bf{;j zuCsKMg}H#Xxg4$=<1(b*5p8(c{T%3E)gapQg2fWFDZ)FU-PMegEsc1M_Q%^UPr3?t z5I!Q|DKVnrJ6Hvb*!T_^v6VDp9+5T)g9cDZn7a*Fr0d3V26k_E2ogh+U_e5)_^0$T zsv@Nnfio|~;sLEdqOYdNn5X#8*)oUX=hODVtKJtdZ9?WyB+o^MQ~FDT1GdgtM46jk z$Q;TX&7lZV%SF5slAy_)MHwqISkDz3i|fo4EBYYEN2Xk|Lj;Fj{|nu>7f%6|s#MmY z8mG2j@>0~AFyMpYu<|zvk~{LkvQ(}QxOzI1d9WQ#TzyE*oHP!Buud3;rY*UANMAj| z21$aQQiVm%g36umOu;%ku-Sq3Y8E|`H5QhV$!Sgm-Y?L(Wac6%+I+qL@7J`w;8A_) zfW`7Zy1enM5H`Le2%BJrbj|x~&W1banxRtX3dk2}OH0s0t!vI6UZ97j^^_dC13`)P zC3jpfQEz+(gD*+u0?o%3b@si!ML?~|`HOe=-Ds_pI!{Z_FY3&jnZZoc8SitmwbG__ zvYNKMOKj`#_MON&5=v=;s|6oq<3VvJ+1|P7siO!svS-kVW2|N1$ z&68>HF!CVfVkI(fGRcFLS#*5A$T}W3N6rjtvWpcPtR~FqBi-orIl2}Chk7p8*=Xf) zw&?Ro-tN_+62Kd{V)RO~01wFi6*tex1QubsUI3P&YE@llVgF~Q&`Kq3YS0b1*>t$Uzm^(Y&<7dZ|$^ZcioFSQBRr1vZH)^`?*J-!DHngVyR z_qog0unWA~y(u7iy08h0YpmtP0Iz2o&I%ST(a=tIFC>!lvESAv|w4|Y3vGw9<&LeG2_n-Hn%i-;M_DfM|H0=yhxcjpeWB2JQ^Gb)lBz9^SVl`78xVVtJzabwx%jj+#~)C?q>zIh&MK3jhUGxJL{m~SZA zq4;EC?I9o=0wQ?@_}%s*bCjZnR5I1k)naJz9I(jGi*>&7==<{C3#KL*8yT!bCQO(4 zy)J!oX`Za*K?iuSG>i1V=mmSzI)Zb$-Ygx{;zJb9&1~H!;=^EB#ODBzq7ol<#iE&O zY2V!t=G|A`@*ai+G{eHkHWyQMWXmoW=7@6n^V|<3ZhMjDv6?=iLU3fjU_o;@tt3!Y z>@2SV}f9`tfBnN#gIV;CoN-Omh$M?06 z1lY5kRar7~lPXdBQ%;S;tZTmBK$C?D%F|)8N3X4@DB)YXye&z1T z_tE2#R|cyuS->xqsETl$#6YxFH}HCcCn|6v2s8-VE!+lRG+%Z#-QJp?BqkeXSNkyv zZB6j%3HS{df^(F7SOvk{m+6GfZT$%S z6B!W;RrK<`PIfuqW~nzklQs<&@SUaijcX}dVxi6?lo%nC=bz!k%p2tp&t&WKh6>+M zP7D8j685|}NsRQh15*h{cy=8L(epFZ({X+Em~752RjW>TdKxKzONOWTWX zpL{3UTYP^6??!trI_=~x8f@|6;@&*;g5?6(GevldDW-a(bEKWkw#Qj^wdZoRm062_ z0vd4~=kUzmtYgZg+Iaxu8Jd~2IA&KT+h$n7`-uP@a8L*&O+&C0ieJO!JsR;aFIGAW z&?hFo_ys!S`hUXc5|^vFu?L%O&xxi_k33jzxd5*0U87T;Jy}7+O}ZBf3?rnrN~J=_ z<0%;uY|HI_Nk7>OzB#_$9Xd5aUGWG5 z?C1ck6=4#L1j~9*EY=%WCy6Ijzt16hDY{PXSc>gE1K-0T;`5V*YN ztWOvFzEUi4OM`B6{{zV33WNXtWe(|hTqL8fAXOuF-fLnf1esUY;Eh>JFN=`x!80@D zoF9Q{=0j=wSYJb~W5U}}1C0uz_^~4t0)QEo-h-*mcnsTxCq}^zbmp1hGE$GBtNBp%9F?Y{)lnO$=>BcwCih3qq^K2paSsn1#kG9HD< zx)GS*s79}Bw9)@*7RtX&##-fVSC=I1q#o_~xsFMwIR;(NH8F7T}Q~D$^;@ES5^I!8K4>mqPeZP~U94 z0@&?`gNy2ci2|xukfsp4H*nVl+vSOaCQ!vVt%2IshNd;G9Eb`#`vXVId9bTLL9Rb~3RDV+Bs9w0 zq^>n0u&)g%uKAnCM|9nDsnAsUhzm#PRP<7dzz#REy=BV^6cZ&JmCNZKVt4;B{BMEz z>(MVwaBzigs}z9#`9OoMfqFPlvP2iEUO)D^a)py3M)KX=Gw=FbXXx)$V61(Ca(}z#?Bfd$XZL+>`ar9F?{7&IkwpUF zGy{KwP1O>h@RvN#kb0KzRr53hf|`BnbCXOTeT846@p?R(RDKza< zI{(r&%HM#_&{&_8_x0E8idxV{d8XsSrYnri~x6?b{ zn=59QfyMxDCSE0%Q7TRQ9G*QTNIcEZsk{a!hBV*wtbvX&Ay8%{d%i}UkpnO7n(NesVn@@^;1fek52n4?CR9yp zl6(yasrtSXH49avpuO--9m>HR6l5jre1W9>^PLe8;VlMp9t@&3TC_{Lqf95yO(*n$ zzGG&-gE43_;@}irx@Lmknnr>(S^{Iz;-h#N4W!k`v;Yo^Ov{q430Z`MGki3`sl4++ z7BDc;1hj+}@pkJe(uHCm`-{eCb!Ti zmDNC3*>d~OaQkZ?uQ_}70wVv_XF9-&E-28#}kq?R#8oG@DK8Q|=<2$d*LW&4Yp&NS%6K#3VbNA*{ zV3tOYEHxlw2(F2#7Ri+(UW7&h*wBgSf7yvVKP20WN^+ZD!<)_XXC8%c#KZf05I4la zc!Fxe+^pGYuaed?bLA4>7LF-~qm~ACPm;X252NM16S%Nxl2jq~2-o=}4XiVQ8w_49 z8pU!{E}F%%Qx401c@9(c;l6U~+}@+W&0rNId^k7ZlgJVycLEPtPd>@-P0d811Wso* z6mjR7_+Z|hh6&Esg*JUP)XCHq)a*lFHpOz3@X8Y93ea}w$NCq8`b~nkeM3s<>tB#7 zWSdKe+_-w4(QoFU&TxkOZdK1GB^|o5McW+Ux;Z^)eEz&7=s-myD#-COEbaVkqUdV$@bs z>cXTdwP7BeAFR6Nz&)Cb9U1z}8ZdGe$E}j)3wT&#hDFdVW$z5~L2lhZ2d>%@SBlMca zW4CA&N7Ywn6BKF`{SRgT{bT@6oX)_X9#8n%f~zgpQ+lQ2Y@XxoIy-o~&d8mxp$Ri8 zwy&=<@oTEXp0Nd$fX|Jz=}VlbK*^*rzX4)FcwuA??p=g!O&7oW<1$aP{s6FMlB{5J9bb8n;w{g0=9Nl6FR`OLtL%nV zg%rWEZpwf0%4J=MBaZmUo3Lo)O;VkyAZ^l;P0Dwb^Qc)fqH_*h{Ayb64=>qpi3~bQ z6?*2mN1T>GK`p;~*=EI^FQF|`4f9AZ7te~)&U2(IjeO2E!e8G7c zo@2OAi5FWeP89#6n@x0HYkpbpucNXSG>fcQ4nTG~j=z9WpBpCnl8N`%5fY3w zl%aoBgoJqVC9OxtsHpS$->;flwXBcb!~l0%@Fjp4n_H7=EM#sFcy(ak>Sii7 zo$^M?pb&xWiCZgp+Ks=!`vGzjBf)0{OUPRK=mFAg$a}2j-c%aVs9X*vl+{Q#`FS;F z{XS1`7291+x*w%!aK{e>{`Bs?(?zkTwu5R0Qr^%rdD7oz@fF$x@iH&u&~a{hWpHHW zUV#LU<~5^NH6vm$mP90)Xw(GA4IZ=KRyhUj?Qg*h1i9~_99~0W!#7bw=P)z z+rrnMxQAwLsE&}G-c>x28vw-Z#IK;klP@s~og4t~7XJsA((=AkC1=vvl}m_h9JUju zp2ldt3^ke?bO6#n&=0}1Lj4}NIE%Zq6k+1v2mo9-T>EXMad64`+e(Yze*v7jH%O~{ zo!|txEhYHIfaU9(U(NIO=U9bL~NM*k_&D%mVE?({DPj0>dc>>~rcvD%(yIni=3d z-($9JgbvsC8LC|8aE-Aav(_${1i1TF7rN{6^0L`L8ax%H4sGPLJ~?t-8mV$nvMiul zzY9abkV0|ht1eBea25Figk?T?ZieSRb5k}^$b10B1dt&9ck2%qQqZ@Q&^elbgK}D* zc{4mWeItBh`VD-YiymYiV?&#QD~ncR}lCpQgswT zMUK_U@QhFw6we5-6A-{Nlv4p*xY^X$x4IVSO#wv+IL-HcMG3kkA}?SLC=wLJloY6! z&5J%qId>x&P@u<+xk5w#wURWn;5dJ}=FEM8h`#J|^9Ej!ZykDpV6%)w>Ps&Vx6c2o zhlWtR82Oao=3g=rW(ZJqY??ew&;vw9``ImLUKhMYJ9&eWML>5f^m)Y(r&m=H#;_#UtacqI$k4T7*oWM>5``C=+Omc{6EYv*T%I$GZx= zaEf=psx(3YYbBoFX!+q@3x%;36lTekiu6EiLMgqf-b&#b zum*Yj>TaO8(E!EI{Q~pN#Ez}IzXdxs6sG45WflVnV zbS@Z^j}GeT>xqO1dYaD}a0QDZqBS8<;0R%g#1YEDuEs}2bjg-&T5Mn^w}EYQcp~?& zC`3+2PBNkyu$gTZ;o-wF`Vs1_f*dA;sRUSKVM{DAHAZ(0ADR;i6Le}TO9sTf7u-f1 zxI|&J=XwiJ)WQK{}5{Y9=okF)^-T)QT(y zoH|oeKn@$44gtz=3s8o6Kp7^0GBo9HHZ_L|ywU7e8}^&*sy1xNFt<#RGqOp3Acw?Z zHFG9^*Eacun$obrt77^yV_?$CpDa57Y06wZUklHKQprk2Oh?#yn$(`ki5AC+(t?$o zBbvoh6}A*1tGgelw77AnAm`r_@ zXX5AehYy|0wsqCHv5cZ65-$dy(nM#g;=;N_YcC=`L{)texo%x_ZhpTW3_HfZivOb2&hOXOg;6v`q0S%e3+uf# z><#)i=&2elUqDWGaQXhG+v(UwaeSAieX=fXVI>g62{HLsjQ!s-_UDIRJN=vYz5ewT zFwvEju=;N=IybFLtNpGsG>UK3y!Q3w#h;khF^X$7=j!)s>r$yUl9|1JhkE$szrIjX ze{j>f>{#z^u0CKp<7Z1k8h{K=?SIRJ3+P{2#D2f-Tq(2A%z#O*-{+akOvmF)R=(#G zk$cs7-xDj_kV!rK2CY`{Uow@3u_vNKt7R1bFS!f)cIWb{J-F-`#T$|Kv2!`>wXF-B z8z3zy`E%!TaPz5W4}ZPs53&>V)a`V;MJdWM6kGexYtF7-pu4X7g4|N~_BV&;_rl{W zw-Y}0xeCSmG73=ptBh>z*mp8#d&hptR8rUBN4Aoh^)^!}w?bbX{*(24c9I?|TkB8R zU}g#bkf}M4{9UHMxF(zc8B`prR7E8(2{ zBg3bA8t_kr!!12y0Cf*|AkOWQM~gjVFef%XrDbS5)tU4#k7pQitU`0-!1K4m=BC43 zv&yE4dLSE`Rp5Iti#-VU>%(#xL|ghakNv!q;ymZINSkM666b0WQ76|3oZ`YDc0cQ- zT8ah;S_2Pjv~wr)|9$ugPN(N=ZuVI}Mk1x1xSfW{ipa4(f*IRM!D z{GSpC{*XUD_PG?zve-T@M5K5Wl_Jv?Xgr7&+E-R+KV5_Ua()#cv#+nCZ4afevis8H z1^oW!%kl#{YzxTQ&$<5tsu$Q8NIav7A-wAub4ei2GoBn@q0sGC%KH1>A_0n*+-8N%BwAdvTje*gryRN{8fNI}9Ea@d7x(vQ9Z81}1I ze+wM@phIDwS4H2H8>#qhR%yGM5?zreK)vD1i(8-V=>K&e464MFbd59a;}C9zP5zH;mQCll)3X;}=f4j-803F@|(#QY?l&iu>`v0$2q z(8*ldG0dMLeVQ&lydx!tG%w)YZov|D4(fN~rW9I4&b08E>!l>ii-fN%D^Yv#++ibMYS=MW* zqX(LBcQUaq}L3 z1wC#K@t5D7}*wxD)A^!{&%j47oz2F_caY%~&!_>T5>~h0ujW=g#Gz1&BZA_u(?6Ur%4*zlXsc zh4|0MM&=yD2Mp)lqcg>X2!k1f3oQKv!8d5-tMh>2qYwY?A@Ja%UorU+y7G02U;6sv z07GvM|8JeI7(&kN6b6Q76yg8lGlX*wdVCvU;V0;U3r_Ef?kyB{`Bw~~s5|=x{c*vR zXVHBG&mJ!N_i)2o3Loho77mvbVp;^#W?$W0EyD;#>Mo$$E?CHe@ZN?0-|$l_Z1EZT z%Wt_qKRT^e#_9~gKr|Mv$cHTri*|Bi~R=-mbj z{0Fn_aj5O#)OmC0h_`_B8Ls?n&ZqcKgx~NV%-`%8@*ntj2$#@1{~l`l9*org246?O z@_*c8_=vebpzX&)ShU9@2SaG{5x@56!iXR5VSJCCOCcuB02Ce{u)+gYc*F|0){o&= zEEImD(1TfcoF8I%L?PCs!931Ih-uHzl>jFpz)7a-`T~E=AD}37ImDe6;sy*|=wOKT zLtN_+Cnj9pVFuq-na>?en^U-;P(-NMl0r(OstcIQ`FCvKJAUkYh#_?QFQ^dV0z}RN!xe;l5k5t? zIErWrJ&zEiA|D!v9`7*34H98*A{>4MYrZ&ygau-!#Vz(|F@-f++~ao^fdfq~JlGsQAwb9y*JO!1V0n+ogb>h@ zP~8$Ca=E<45L2EZDxVq9)^z?&M{nI2$1s4gWi1$p&Kjgz{>fCA$)8_SZ{^E zvf^JI`u9lxF!3G+v+^*B0xX1sUSW?{A@&vi!I)MN7W)QS&)C#64(S=O#+~J-k4tIlXP?9*Z6~KOlJ)_ELM$iyqe-4=O=uo`*fM(d^)1xfIsv z6Is^EGQ0>^JZgh6eO-3z8Wl|Mq8;5?FZkT>d#Vxb#9p@0|2OVtv9#IDo_aYm0gbz; z()oB}U0jfTX%PpD*MFL5AMLwLvuxWeI<70@?O(0_+m2bhy~mqLTI$B`U1CYwi)8Y3 z|DxA_XBM9VFv*uqrSg=cRJpW1nYgt@98GSU!r&RCT@5d9Y-?zlWG_u7b^5l6meOQG z`(kj_N$$~iQKfs;`Pk_XZ`zj~YuK^PA`wn*CiDHk?sa>R`xv_3otMkDI~N_SOD;q5 zbw5(YZ@G;2#h{NL^ur*Rb=`m0AAIV=L_7rHD#&DZFRZsW@2{_hH&<<|e{*%+vU`_T zW=$@fd3Nuz(;f~k|5VMiZk4+F^F1wAwY2CIELph`;a~ym#4yAy}w`=&@W9@XB1fAzG#ud#l%f zi%^qXeh{3l`)zzhqnt!m5BKr=55qriu7;QB3r@znedN!tvDu#8=?{C93Mw9umUsd& z?`Ekv6Uuq-+=epUb)uCQh>Qy_czPBYKKvHxz1DlreCmJmq8J=<5<4pA2aC@A|`7v&i$kp)Dc^u6MY;hJ=`nk*E8_K1 z(*?|s>xW>cB`B3L4P6NRsO_;YydPu^p}^U%D;&prXPzo6_nk!7G}VLDd^U$Jq2&t) zVr-4;%3ZXy%wv2U11{jaRC>44_#!di%-LLL_6g$)(w2a@9-|#$sW5m`!N%~riN$4K zUwgnzMpK*bQh{RTq;jgit}0Uw(tC}tRQfj4!chdTf#+*qqmr>6Gpn~{7IH05FvDT# zsbz#LJ*f;oHa#|%pNMqk3cc7lxY2;>%S1@kq*)6X$kX{ca|vcEU%}>%i}GA^{kg8q zVImxz;m`XSSgXdLU+W;%jkd(W!dKGVyA?Ho!qyS9PjnXM6TjAVofQ&8?Jk&wg-uJw zq^Dx8hGwqX{fxRrQ_rL8;0Z;&fN_1>;~>F=wvbIzxHHkEYvLPX0*JOJ)4s^e`yw;(3&UrkPlg+_Ussg{%s)%CWbvrDN+j<30*U0NMYhsMP|igb3@OEJT$$F(_1uZb!`#*qoLRd*5RKd?v~v*}E3 zBi8;otSR6X0(kl6bSA-TE^!KTlV4NQhj#`crT7DL^ zrZWYQcFd$)Leu{_K=}wzUuWc~Wu0-0BFv26Emo$q)&Dho3S8PnC~;we^P9@eeVPJ? z(hYtREUAOxt?ojx#c#?cWe35j?LwNB)6l*EU!<Flu-Tz{ZUL99@|=a9>6<1*zW2(}I5peIKL}G&g}|)2r|Ra8=6-oalQ` zB$rC_9tXK*4-lP_VR%VZHZ|Kl0K7SKS-LX=b!Vmn1atkD&MMY*V`^GE>nW$l?j`w~ zmf18G%a!a1FLlEKWf50p{BZo;5;5O=d659mH1OFI7!jeaHtd>sXvi(8_TmO4e3na} zYtKEvZ^tB9Qm{9hWSik0lc$6wPKf~;n`!)fL=Ry9g&JXP(@J-B;bF6Rcw@FVn>NrE zGDCXjNam98grzgLhfn`r0Jgj=_}^3pfnUan9>PReEX{IUBxUfSG17*KbCLYcaly~i z+_c0Amo`A|XF=dyJeR4HET+UxM)_dc$|$YP#(HDISpUH&ZRolU4xOgv%e_QmMe~#< zq_j6VAngU-(sTUGH@ro#BoCb6;zsdtlZAkf(2HsUIk`S!ZlH)33$GRg#X3Z0BR99rn^t^*DnTGEHYN3V1;JSr4Eo0Th?$Q;8q~2xvAZ_lBmtGeqpM$8}cl z;1h5C@GDX?J3v#qbSQ%E96!`qVV=WqFM*I(p)2JyA-;yDy1AwI2ewvxpxNfRCthq} zXh8ku9ik~k;4@GHC61~wI&gp+HEj?(hjGPbSPuoIpejlLCV}p<2W5&#FL;W}Z-FeJ zO^dnZ)umKY{oG{trOhJt04f?gcji`SP;STBY`}_s!9@VDz@d`%@=jCw95N&lgcqNX zJtR(@9M>I&0-HS`VEEwjDW*w->&@=dHnoVM_}Z||^I;_nZn*|L3oU=N{d}V5&3STH zFVq^g2DiH@U$*Z(-;H>n>GH`Qh{=Kp{#^=FoQVgRh!keQVyOZv>%>oyN-41iJ=S$S zxrhK2ymiJBvm^ z)&s0|`ms1Uer>tx>W)g*U3y;Hf$TFB+l{wK=>qZjtpj_{hXbM}$p7ud_?7!W^=sgk zpi!8osNBQ5xrmy{eqnP39!yV(u(`64OgD#wT|LPMe~4}t0fR!7q)}aQ(sz1%G)H9l zo-gl1cOqE@(B98z*B9nUsm)T8kjnH-x4|$=s+3A#ElT=B`q~2(b2a4~9EU?R2fxdg zmYutOS?08v5H-N{+%cxjMjM*jpbT@C8IRy{&4Jo}5vGCoE|o0Bp6*X*0WkfLkj(B2 zPRQ(kFa-6ax7170i_4kA6c*iK)#5wIr0nvtmuAfpa|M@1dwZ^wsrmE2B=WpNWpZDyz5b?+-LgKe;J?>o%Lu$i)Fu!f zOr+Q0E$7Ok+64S7vtUQo0cJHoTK%+C3f|OCN+qpxB3X0D9$$-RoadSHy7Pfvapa@U zrGrs=ayLG$(ifhGp7O%eRbF`dJeZuamDOuU2S==aP_G`b z`r%RifYlCbhX<$d@ARn34o(ivY6laY{pclzqO|p58P1K)N%}YgjMwC$=xuMyDCu&M zNVP46lkVPE9{Bf#rt4@WOIBBU zV(YRg(mHTVTOA0rSry7I5>ak8!=}P6#uH|m=bR_YHl64y%g{?W=RbPDT*AXr7%);B z6+G|KWsheWYn>D5S}(W@v1&uDBrh3lATs5&=uG9qYY!DfsLaMZfI2*noRmpUr?b*7 zSrQTa@TtxU#F8(SwC=r3hV_@M@bpYc9%umcG`+IC=Yd8aQTp`vO!Qbh8~#aqQQ+Ow z-fytA*g>+`Xonp=ij>PNIyc|-xWdv%z2^MUBV(7HlTryL#rwhE)DBMBaF(-UC=4$Z zQa3i}jfAV)f$PBii5hy4nq3NFcI_nFF>%je*U|lnO7tnt8$LSZ9VJIYDJ5n-QG%Sa zvd-T=HpI90{PrQa0PJ`?xS{(U(iDpqZw@Rq!$c3}5qcrbIW`3wH<($TIl%L&Haz8R zCH;-rvE#afsEs0M+3PHGrP1RMFKoWv{LtgZ^NhGsf~Wz|)}}09Q(T&G+?{7{v0Q97 zE-w*N>G^i{b3XSqJV>&s-~s-u-^NxCKdrXANaW2F3_m0fwO~2ms`&ra7h<(QE|*Q| z{=0pPz=RCM1UlhUP>Nhhvqf$S&kbz|mw$1sR>@$&?||FJkVsx(NX&em;rCs2SG>#} zW^QJGOt%=r;)X%YfYhRm;NK2sU?EE{Cnn1kCRKNV^Rv(bxPlj|K%2kRkx*PO^muCy zno;?$9yg*qH+=}~4loXQ2_65*clB6#=Swnw!e&>l@tNy=mi@lY?Q(X=_O^v_Q$}Y9=%k@h;L&v4NdP zLA*HmnQdaTzOEvRA?xoz7B=20Ee1XghAiB@mGgz9|6}<{fz$HE$jp>5DlNt?OiTBA z+`u0LfKp`_{H$+eZ2Cf0eV?oPv#!K({sqEW>5cp|OXh82o@H>#J+SM==_Rzao7V^U zYyCn#&_V%hKc%}{Z%gv1kWSKn`@1*M7f#URZDsciG+yok+l4v8%_bsgDWta(&mv)| z1h1!mIlKuXBa*rfK|9Q+40?Y_HY?DA9^f^=MUFh1!k;h_{$?m~97D`<-EC&2C!}Sv zWCMGdbFH8UA34`5e(?3i{N> z6NB?0{J=kd0?qM4TOXn^O`l%yYG;FFZ*~0g3Qs3T&vtxC#J3mu1+XIm8d|K7PVt z&aB>$i4KVcq*()o*l#_Kzx(pVa5tLT)o7LjD68hQprPAUp-?)7YG-upJF6&n+Arp6i3Bnp(ttZL!WxwUQ%AbOtah3mY_%>VlGf3v6 zpSHowyo4XpgEr#>Ztjx{w;B0nT@JXpB7OYpl%Q%jmrr z^8qkEGs-f?Cy@K!sU~CG4v0^B*)iM!XNvZVaWfFLjQ)%%`Yy)fAge8Khn?uZH7;gM zD7hHFJDf=k7vp}wS;DCOE}Knxx4jw5sHPb2alBF^#kij3xVO`RszK3Gc)8yOpmZTs zFur08wMvX<{0#~t#??SFc!vXS{sC6jB^TFD69kIa*(Gp+%+W+Q&-0cUn%o%i3HvN~ zJ5)$ZWsd{%e4VWm=*`by9~uZS=}8k9b&<|~I4Xw=N?oFL?FKoV;oo@l9a>cO{q;=W zZSB7w2CqnuXKx;b-#j!Vy4b_5z6X29*h7=$iU9*Kcgq)`Lh&}!5uQ+u09*Z;juv=@ z&7lSO1z7+oqdgAbWm7}jAB{*nq3+wA5^q-K?)QpTzfmB!k z;eyT}VZ~+3;(~H@P!}`3c`+-?`VmvSqZmr6&MxN(dyo7o2@E{j$&&-d8)8{li$n&P zcqE?$Lo}dNZ^<7Q@+}}HUK?R8OlNM3Zdh8n21aAfTtpMJ4PcJ9+^Z~DoM_JfZtPE-qVq3wRo|! ziEomiLdD{YB#%-lN-IfUBw%$TBEvchO`pWBx0s_E!8)CCDJsN-Hcm3?OhR@*nJjE2 z$IpfgxDc-f92D)qw1fpeefs^^3&27od&0(bm;yV>-U5`}nh9DWIo2g00ZsQQN&FNf z6j&f?NU@CoUuS?d*P2OsMdlT1qA-xrf-E!D5~Y$SDLpV!E{h7$54B`-08SFcHhDkO zlk%*%i~=UIg$Py@uC8B(-xjnB+_t+ZE&OMQEndwFx}r z%T(mIwrW@8$8;lYC+5L2`i_@}bP^=e%fcA@6r?=9Tvo~;%1$fzj7zU4k@UysEODQs zP>6U^$Xzfp+=k@-6zM8@QoAnB8Z8T^;^@djsA*0IyqQbYJl)7K1XKZQj|G{$duIUz z{0AOAdJ7OM0LD|C1>{sBTl7exrb#2Q1tt2e2n*c}xZYe2xU}mN=>|CYO!k2Tnteo8 z{A5KO9W7)nwc7#Mg$AQT>O3ZQOxZK>`n9zkUtC${0f~UwPr)PcUYKg$WN(weUBEo zRQ3HW5n!e)DI1+{NM&Q@vz8He9&-&5-vE3PUCy-tEW*h9Wf4g@<-&>6Po*+UGEp#- zhKGY%Hr)V7mM$`t@|kLFq2eRUOJ$*2HR()NEl3p1CYpz7abf%(AmS@p&&Be&RO~^p zQz6OBHxAwkQ&lAT$kQTWScnfODP|#1bfEA)Delbhq?<3BOhsA+nk;0B$xny^=JSB- z>PhDSiJ`64{di}TfER($ONGW0`Ys&=P=oarBf5D5JjZ6Luo7oT6 z3`}1}Pf3|tz6`i4RO1CVCeGu|PWJl4&gDnz054v2IRyGwo{OIV06<*1Ex2O+8aDe{&a9M3QAWzTZS0uHy5 zrO~+UoOLX{plxS1z=N?5$nC4=d&}>``-m^@Lm#9>cO{z#plsn+=ArLPXvd;z0&T_2 z4B;o036lHVRrb7VUe3~pF2#d{dP&OpA{!F(a+%G~O-X0VCy-=m(&BLKSBep12@Q8j zU<&y2a_HSYpa@FB4p!5fwUy zI8nbk;z}Si4g(bGR!al}Q6hJd2z0s%CNf*=+m&lLEQiuSH(BjlBa8n9(EM-|4~%;b zz>DciKa&CrbOs>v;3TEO&8F}HT;(-gBN}kc1-%3Y^@I+^9N62rtF*R##0e?g)aPiS zrW?D;iEF9UcG{g;?#b)V&C`NM;Tjf zVv%E^xvf&PSuF=-3lITETY%v%@^X77VKk^zb|K3;auOvIN!AHHL7-t#7*bxG;3^N^ z5tR$LlPF7JU8G2zop7$|14^ng`Or({f4V8eRWcTK6n-*OvUdb9Sxi!;_K6u{`Tm6z zAQTjGlwN1{va_VHO4AAU5?`a9rZ*hb^ojU9$h}F6w#n=XVmI5S%NNTigvXSZ5ySSL z`5B&1CO-Qe$wLCCQDSsxoe#^RF+uDd{8H$3G#4ny`r;(RIfjpozTE7ugZRrtvZLZG zsL*Vf(!*I(-OiCJbs6i1%#&cZtED)7G}ok%`#R1pU4HmlY9Rw8hgAf4yKqLH)N{O<6H8RYcw&`C4$$5Ds?4iXDSmhexxaHtjN47i@%nb-!H{xD;hC7;4E zQ4vDe3F{3-k4j>IuS8Uv8J;v)^z~s7GAkJ+rlPYqqHjhK3nq;)p{$$2Jrs4raCT+r zhNs9{$#h+)zWQ5a9>Zr^=!;Y(&(LKk)C|%uQkT2pJBuX=`yioVJ4>RW$f5vI!Mc>u zd*|>hD#((>LUv}Zvjtxcy+dY~X*VuBS}z6pKiq zNh$qpH|1x#Gd3U9CZ?T^KZW-Lh9xK9$6q<$7gtLMo~%_ysX9f@fG2Y$=f#&e0}o5N zlZ=4b_}U;X77Yhr_(74%1M?L-HnW%=ThHkA=O>8Z z(CH70X>4fsF2QDaA%o?1b2~O0s)hELWD_LwtE(uiI|D9Klo?x`E`Xr_bL=7UA|jPb z({!?lBd=%;1z{_Ngb}0AbOh3X6%FMQhm~8TAj?t#(r0rsQ688kmDtdnHm6kBs3v!d zbki_A&?K?|&&Z`xCTUt((l5IC=xhk?I}`*nX9+%BXNnp=HEztA_`c#4m{64qgy@!R zU53-I(#z#|d*fsct1;gc62HpvRw@eUO>uLG*^$?sV0_bMI)zOA}Rxw^UahIRe8&mKPD~vErrN+lgr%I%&XNjc?ZIzdc zH>_6=N|kdnXzpx0eTa0VJd3UCMySGoo4s)57b(NEV0ch8UY@b!_LR+}U9(Pm3~&YH zsQ=0FmWGBN2!7iC3|xmgiYKxE^*D4r23b3}<4bn7gj{&o+;I&^UpjM290>`Od{}V5 z+ySpF`C^$$k%RVze6mn!=#=}AyEm~MEhu^fhy}cD!d3H62VZ)b4}76eSFV5JGh?SbrUW|@qtt&G2BXs>`CiIq-B3ku@2KzkdP zcwtN6UP(*XZV(}JgV>&Y@ldX>k-qzWKy;Kmg=8w>U+Cy;rUh*4!+QRDOXo?v>s2k< z2H@StZ3@FQ`&v{gApMZL;0yh8CB?NlFCQLk5zQ=1-& zB4sKh62O+v-1^ZSxal<|`paJE^Ajgb@~}J+R;14snZtmPYCKwQplilFE%$-PQUXj!^EqjxnFrPfCRz2OQ5LL!l{%O;WRdL~PtTA^?X z-i7mULHD$w`P18|ljjfS@o?_Opqw5^ z3DKVVz?^V~1hEi^H?(ZHpAu5~*9Jw0*1 z9^hV2%t!@4<0N>(+1r*0?ClB#c-yI%oLC<~+HY41z9;!Ij$VsC z&Pc+*Y!9Rea6lr!n)8vfXt8a6J6fdnCZsaDB5D#fBbD=q0+gFgR-O`wHp%=tH_=HI zIsZ~?c17Dpp(Z`!I-+Zfk02Jh+cNlv0pAiRei(2wK!daUGo{Y}16m=1z9@161=FNc zf&?SURcmD8kyL@5Kz;F&hV~qxX@gr@R}OW^XoO~{4h!39hLuOYSU6K|gkmp?IHT{} z0xJ;G!QQD%nlGOsezkONABK^X6iQ^#2^yr06Ha0h3xpBL`5FO{E9FhL8;uQIgI8I%>81;;8&h4+%xxJa7s?HR!IUg+xoGSa%POqU zP;Il8EQR&*QdnXs9?W25p~pHf%8yI&Ksjv_CCbE7SQEX`hO4M>%V(F%tjdaedwYAu za$AqZoI&+c>7jx#Sre3ncP-e@fRma7OKB2MiP8(c{1Ao95D@a8{nQt9%yxmWah<<{aMAC18I=1B;Zzo>(+7)Cz(h>N(2D6g$NYv zHE&d%l+EH^v7E|f7yo-vWI;-jf}FGm${PDKT!r0VgdF8_TOVuw>;neu3HXGkpzwWZ zGRPOmHT=j~_yTh64zfb#;5WJ*y4+f7RXzPw?F1s%^LZkELftG@pNnNpV*dX=XcntQ zbaouYtUut2?R}J<*K^a%CE%Bfd*~H%4`_Q3mq#yt(#bZPhYJr+j%qAU^Q5LU74+}x zfJ^V(%kY5*ds;=`tNbFXju&OJA_Pihrq?Wcql1a@(`In#(t_J?}YhbP(e@WNSiAlxlZ=3$t{#y32%7R}G^!Q(2R8WZ7pLq#E z#aH@n;cd_KHk*U0(5~zc`k(}hTk0_bChlF{S0jiY2V|(&d8_(jG(Rw_ZXj;?2<4rH?+GxBOFDJj~ui1Mn1bORm zycv(i6J0IY+<(pfSZz7wSb%3wy@6QopehwsN6az5{MQ#2n#H}n;>7gCHhn+fI_Tt5 z>;hvWRxGk&5xi9(_>s3zPw@`wC(_0~ILpQLg@*!vG#K!S=`erPgCC*Je4$7vG<1ba z(t_fWw9tCGyW?Q>g?@luj8I9>t0$F8T=A>iAWfm1kZM+MsO+u&5mk3>MWB^iuMZ<}~fQD30`g5f@%wqxjV+BIC3sUt-+EdWj_^I3J zc3(5_ULGn3%pa@9AFB#}3_3^v|0gB}Vdwdl3jr*7Yf&7NC@VuN4koa~>yf1NZt2)s z)$`}os$RLd;fwd7`-EOKAmPFb_`(X@cIZDn1`BC$7TWoJg|PFq;AU|g71?~jRq`z% z_IYx-ro}a*g!&3h;3|1$wc)*y$g!ada}E)Bsv%nrzpo6hZ2rEI(mX-(PK<`D$ZEsW zfVcW0%-s%N6W>%fo9J8_x%|8&K|p~!or)?G_jU2rhBpezwaFW4WC`zcX7tJ%1yaa_ zsGES@;_3kAXKD}8dQ&%yE<{f=J*1CDNIEgkgc}_+lH7Tr_rZClN233mjR%WEfLA_UIj7Zv8L~W z?D>L2vVa7Liv8l!e)+sI&)2)@@y{z(Om|L^t;zRzp&ILr&#R=#*P1r^S8<|iO+#xI z#s{16Sg&lxW5nL$U;{Y*YNG4EXyXIDx%r|sjnTiqjK}+v&3H_ioAEwWUF)0i{&Ht?%3evRMxW&BzcgtT9vYvU31 zZ#15a#}n*eMgL_y*Er*5~~-5-ztRs0`qJ=u)P z<5z`=)-0I%W?X5GU0vUdrjOqDr^RGlV<++WD>k32J=svpQ2m$xE^Yq(=Dc7wp+W5M zX#Dz@2`EPB8?8Ee{$ny4yUwdS>s5DB-c(27U^1${s^jmkt;wibo0K=uPxqH`W$czW zW4Ao6G-1#q-kFTbuO>|(VPQgGP_A65g+AIJuQHv3C3#9ew?2v?VZ2s)Fpl-IzR_O2 z+KkKN@}^YUj5p)W#ysDQE9=8}BgQp;4FiK^S=ZP>ym>?a&et_|7;g$@b7NwPZZ7_*CN_qkzmyoh4=X)BXH$_i;1&m z2yUC)IAHIysYSwly}UI=y=kUrEkN>M<9F*J~~kvk;!T+ zd{m!6?bEb&#Haij>Yk-(Lg2;Vqgqu-bsjmU)zY*%4E@PjhE)1s0+JabZ*>oh>$!6a zlvgAV$M3Y+t*ygx_s+NKFYkP-4zBxv=mTe*U~woi?-x9u-Ul|+UxTgmE08HR?-m^U z^=@Vs$Iq5Eer_F)pIg@Wxm|rVezs4>&-Ur7@pJcN{Mqi)#U|7e{q6{0uE`+C;eTpABJhd=vW7xqYtA^nrM!Lrs)**6q zTEh^VJU)QNjt^@XIX=Pg48jxa%kk+cgf>Mw7KUAnbPvW))sq9vIXQxylamgH(Bw%S zn>?`(F@*1*bSON*5Q}!OXcxP3(rsf1N%dM4!vn~uV;}2BHbyLHq~3xt)Z19Gj@_zv zk1)jSE~K1Rv2UlfV+=9r;0Qw))aemrA7g}udwPPUXdO;Z>lmI<1Uh_bQBE7C=&X7K zk+VaL9Kzb19ak~LRXIC>PM*<3oSkCM=`lsx7{a*D&M@N)7wXJ9#Sq7J*20|D0fr}( zgx_l6x7yI7GaH+-F~!D}IqTqeyI8wRzoC#-#gAK63q$z0h4XCH@Z%Ovi*w+=Dq z@BqU@439B9!4Qk$$gN|XAnO>vaSWZZ>bP(g0ZLj<6fg+(oD5Xaxbk+*4_Z5(I2iur9EXq&c78wc8^fwplxZ5&UVK(l>pVTeg5 zSP@6nMksC5c-jc1Z5mG-$J3_qv~k7Sv|?>sr8ccn8++NtRchN5!Wi4QR&89Xc9%k! zc$@Z+jU%yXBsPx3rjgi(7KYH2eFRO}$5aK8l}&46WAAN3lQtqqn+9Q@VX-sHL9}7F z4k^;Y5L<5JzP8&?xKqU)+d=r~AbfNXK01UkI!9Ov(P-xsvrmsO#68+UFzB4NF@mew zL8R5O5dU@%!aE4z9h|!k_Mt<4=(Mpd>WNK_*f5}O73y`V58b0WhPd^*Cop?mIt#k6 zYPBljzFPIbg7B~l;V~s0A7f}y#D)-NuU0+5jFS@#JD6RsVt9;^Q!E8|uvWFGtu|I^ z*D=JVY|7~3ce~L2+QHE&h89Jj*a7wB0M@W}aE$rXqXX>G!3pJ`V$Lb$oMO%y<-jD? z4q68kImYmmBGAEuHs-e}AG>+brhFT}X=CINK&^I&pjJDCg8~d%V+3|c?GP!<+96=- z+93@Z57XLVmx^_vQ%49fwG&u}+Q~^5BLIc9lT*rpOEINfbYX~fTCRGn zh9NdkKg7rpa?&<=L{o2g4Noz9_=nRjnmQYo?r+SZThl}6+0B^BEWPBV7fK< za+k*3J;IzL%0ZCt(sXu@>lmJ4*us#qanZZj|1R~v+d9JVgd%MWVP?7n*WEVew<*7k z`LzGKKz7x-Hs#p(nGWUPV7pyvpoYWbkuX;B1<;R$kp3wA)ub6_7FV_3%!x?&$v#t9|?X?kFvQWBgD2ew5Kiz25K zf#&TN<+L!TML8|ZX;V%cbJ~>C#vGe+Y|ODK2M)l)DnkBY73S}-dQij2!5M^y6an(; zuzGk(kv4=!lmi_-te&+f(uL5X901KjLbHcepqvkD^qtxPMyTl;;OxU1j`XnB!kjKe zu+9-q-Vws~5y7@~1jmSVWK#sNoOMh&Cva9Y(^)5!v zpgy5L3yFTKUW3EXs$>27!2w2K!L9mf3nOi4vkvr*Rfl_%RR^H9>h>{a+h-6W99yT= z8it1yImWO~5evgMMh*@jqz<0ep|#UfYM_M?(OS2TVGBbWLm12%LcMhcFlL=0Tv=y8 z3s`3-6sg0^oShzF1P*xXtPSHk>rg(xuyxisp$O)5sZIO&#?@$@zzVkNl+%Ik z&|bIeKs4F)7DZr}+4Xh{Bd{o4I;Of7oJ?J-P7#2IZi{lTqg^8UyRBLsLmR^`CczAM z=^oH+9b#eJc-!y1N%7#?AGf<;@HVdF=TK<(OyTraJLJP z*6rGqV`Gj@Id;3qZtz{;>7ZIgEMK+9&n;vv&?WisgqR9-WDOh=p8z7qXT%yn67{%+ z+yZ2290LGVkC9qE1_G;k4Be>`VyK?ref#97g%Mcl>IqOP)e}6Fswa4FJ)s-x39>>? zI#|DRiXrg?IyUkIs7buzA&pe6BS2N_$akn)*km0E>pGFqb-be2@w}+k;f$!(VJ}xt zYbV4NIKvS0Pl2AOo*o=i1h4%EbnQRDI&{T7h4Z?4dWLlNDc;&ni3M?r7n{=#UE-^U z$Pl1Q{2|`Y5AkMmc7!+nW8w$^B~U#(!R!4ARymtso)!6P77OUQ7bs-XE@tu zZDbhW?x>!%i3@-k9c;IQwL8=ac|!wy>)fcGaS;TG&;K7(*7a zga`*!TUENLxi!HbUXil*n8LZwryo$^z++aA@g-z(t>1O zbe9or`Ie@&ovg%7S0k$lEx{6Fnv^Lywrgqq_VdgPK!UOqyWM*~=X^M8H8Kf+z+f;K z%nSwtME4$|dk@jQN1fP1bnl@ew?`1~A#LxG(QXe>yhj7QhY;@}iuVZCJ%p85m%VRS zP}fGynZVme@b-~u*!u|IeuXsW3aR8({H>uD?&2?M)CAr>g11lD-EWYtjnxyZ`$!G@ z1nWM+x=*m~@00$G)gNH>i0OUA^gcnqPtfB8AtA~>KolQ%s2*ca4yY#w*pmb5$pQA{ zfO>L(Jvl%WA7CF2unz~+2b8<)1M0&8_TgY3_4<8M-w&{2gps5s`v7&`0|N2@fjl6K z0fKtyq4w=nNK;3RyF%(U8VL@oq)ekN^AOek!#ygD$U8)-%|1jM+98=Y4`B(hkDLbn z;xkz{k6e5~``3|&inm88hxm)yIhpy6&=PQj#@Qoephpd~TOKv>rAZ1q!f>>YsS=a^ilO3cqvg%9K@@Ym z>H#UasMpp|4f5)we7dBGR#63|7q5aUsEfa-Vb<}vj?ai!2c|nz_z+Z#{xv$gc!f%sQrlyP9q(?6vz96MJ$TgiNX*SJ+E-ILH(lhr^!K{*=2^b{d z$mxP8=5$f~bh-`HO-T>zHt~hDR+NaG?j9A}N3D}|yFHl5&K?q&gB-@$BMoj3$78RC zz1l+*?2*2PJjB^U+1%Od9-#J0IeYjGQnRy1DyEB7?*lzK`!w$RIPUw@&OWxYPu<=> zaPgPEIYhno5LI1N;r7wA@9e`0>5zKj92_0x*85u*?Le*#VvTEqR_>Cy#^aR zhp3O)U_N&D(bn&x#m+^$ntO0aDh_H6Hi}T5joOCYM0KV~Itl6mBoNkM{&aC)pj)e> zBwMSaM$kkhp@|vLV7GQek~|9PC~h`vl*3(;?Ohbj-F+0@ZT!U#kOsSreH8skX=$K_ z&>*3P?I?}Y8D94i=4l8`OiOi$h1nTaReWQy@Z?}oo!fq3#W+K9F6RU0>q9Sla zNr3up*Cj#QL#Z2N#%>qP8(myHyWJ{D*i|fBC)pb@foAV+caMZ_(EGbxkk7i^JyZtv zP(Rp1@qQo0`$PH~wTSK!%KAqrccT!}-9ssU548R69#Bemj{w~}LO~f!JV&JK9UX$D z{OHi77Z+c^LUVNJp@fQdmZQT83YZS3T8O2|} z7LC4PvG*&pK2HT^w}1W0K{!SC3)ow`o(kTxnd2~*xmD&ervX3kufja$c+9IZ$8}lV zW>uHDwFYw=timb{_|J2onA>DE=GC#1Cc`hPtj=60<}s&QXHJt6>8Ht>tm;7Bj!g}@ ztfpFBN~u93HYPjJKpmh2I4e-PfnYI@!B-Uzzo;;qdCYYY9IVi@S*@lz2C4L0Wp#&D z0aAz6s?26i4L+p*H?TVBsoP*)4ZGvk;ic+jbvO-x)q$=%tnRXEja6+(qF=Adyh;;5 zg*NI<_}p=r&6@B%;HJ(hb>`ZT0kC?2<7$IB*d?dJDi!8=%&kD%P@9dNg9^L~_SEs9 z2B%701~k|Ju7mJaplXNJDu_(T^b~fRtidWZ7>ha#Gh{g0Fv!ZAvIXW;n*bV&BNg-< zgxtZ>Hgg(PsICGncy*a&vziS_4%Af#;$dEc!AR7w^G==BJm$Fw0`#jcTX#Je3+ha> zirHQR`b0@Cg5?144R}QWTvn+?N3 zmn}9F5Drj;=P}2HyoSx1&~F=hU}LdnmAN&q&YCs&1jGVJuCj^^bvInrsCgAutueq80|S4NbY$z;M6H6g z(y-O!{J>%rEJal3c}O!ANsk1}3!duCX;hHn>o7bum(_sT)L}|E4yzG4c&@9k=&?$p z3NX~Gb!s_dWI(w!pvGDqNyc&QD$R9;D_b&=ru>j74VtJbs>6ToQu*b7Do>4rr_~2_ zJ2gTT;>fA7N(DH9TZftDv5Hegbh?1>YQ2W!SjQVcYpeznuTrbCY6a5mI;%8sK2@Bi z(`R4b3f`;QO`H*R9Bdc^w^;!y@qlp?M`a!{PhxpB=CEqLf^^YjUL6=l1G0gLaoPYK zLKmtP3wTfE8nc2ibF7~v6y@46z0xzl{ zDw?cr){qt|^(wScZ`5IixL&iLU1|ICS32xM2N!GAs#i;| z3=O!={PfI0JJ|KxL6N)Yn;I24ILET+l?r&Y;k48Aq60ZR&9YVCVP}!He2MPG%I{e0 z)~X#iTJ6M1|^Zv!q%;)&{^{o!r&07SFj{9tA_qTGp z9qlU5*LGAast5_WGeH!E#tgPy5$bByZPvE7qN0<2t)buL&Yg~5 z<~nyeUhg`0IxYv(U&X^+oDBKTZv`d17gLdZ6T{yjbu^W!AF!3ZAR4}n!iQX$i>GCB z`I~QZ`MJDr((&&1ul(_fAZhgs^bI$d0S@Q*XEqqa-#D5D(Jdqm#l`JtBocf?zh8KY z4Q2o$4Q5;hkspQ+@DxKSMLGsEf=h!L^57RU$PHcw&bx!Z34HaGvZivbgi`5a&1EU=NWfNx9Rs5<8J-`>(iojSv~$Z@idD@ts>&DZxW zt&hIVO8)#-uj`krE;&O#NKf{`%Vy}O!TK4x{)=UwSA#w3ho$Z1!_pGkzrH^4mR-EK z9q^(3XYHKgVXc?8gFdD$?7^_g!PKA49!v*L^L5K- zhwo1yn%nU9`ofscjr}*&w8ef;Pd#%uah-+GHH>0_(frao>scx=$#V?ls|;DB;b3D^uoxvcHj zYUA2${wE7{;umvuSPOPA#e2SfeJiZ&ka*|!w*tehkqD~JdIi&cK=X&&39Q*-*b*!e z5YZtqjq`hFuV-HyEPb-rMH~*(JSWX_UHwsI!o8i>X=(R+rClf;%=|DIq#t-$DG#!5 zqoGLfaGEMn$x2kPg6Nw_rdfVH%dbQJI2aB^lx8=w>;_~54zC1AMz^DJTB@0qY9b0k ze{hunnIXu->_lV;@|>m2Q6jYVJ$EVlK|o-#EZ0bl`Omd1a$u)!^v{5FGhPgv{bSJ6Qy^H5K(puk}CClfyJWzI=kfa0Ant^*6#UCgg+BF;V@US z-a8rc;rgRshigJUyoLkXz4`h1{XfTK-SHz-|E>=PL{p7^{@Q|SU}GKt0-hRZlC#o-6pDHRro>#BTTC@ z{O8(zb`eZ(5CSL!R+?t5FDG;l3}H6DMG%6^53gg;3a}_ZWJ8?@Ka`{mHh2Xo<`9A^b=cji=QG5UjM;5+a~lU!92M8DG1rzkDRowGM+ea_#AFggYV?6F z>XbUYdQd~_G#xqK!L=MKyUOH0nJS*7#>0^!IM|MNuWdV}Xc-*&9T|z>kp5U_+(pvZhO^qqx7-Z3%i?@N|v$m18o3sufvn+>8ysFnw-^?lTK^cwShgyx`Ha5Lk_MPHHm4=%I39$ zJ1RBiRK0wrSe-c&B2>7o;hvkD0+V4#Qh|#dz7~pa+w>|Srtx9~RU{&bS|XQzDn#mY z?AlM_I3j{Zo_8&V!R>W!HMU)>77;<&+FA+pL5V3(ZPXa-D#9R8&g3?kgisUg^uW%r z(^Od*x?vRRxZ9lOWo#6-fE*h~J=&4h!s9cS0!p64UBpy$h#5sxAH_@-a z@u1aU7-f_Wo*h*H7c!z52zb|0C@Rm5>GX$!*u~4@nGOjgGdub8n8v;fAhb_ zI#&d7q3&VMgIslC`o!T77R(v0BIq?Dm%N#P1xH(MVEHXE8P2gk9=B(})y2G0@qk(Pv7M!Zig~(MF%$jfFpx6CUSjv(Iu8ja<_xF2r?w zr7I+W>}BR{tE6-aRTR5cTGzkHQaAo6*eNMpkosoK_tCC*G!<~`5bP1oFc9UNvGr!W z9EWn&1vA{yRP^4Ad$Vr8&u3k#e%58T2|v|Uw`6qDdK`@XC=%hc<+0GefCnQPT^I{C zo`x%P$I}pVzpcsr2Dx{uYaZW0&4cTQD=oW{W{ALSC0qO1ahV6mzRsZaf&Rg1Kkl zcA>$H5!N;Vp0u)D;?$rN{$5bqI89eJ3^_)BL8SB^qURQF69{U0n=Dh)``Dt;yQZOP zGO&2>ecZP+qk}X!V0`&#R8WNr6Im0)R(&7ie)WcF5Ga4ArUHGksy?csOa-KQb%S%6 ztRQ*Xf~wh%hE#h2??sswu7fFt#8GX$n~LSy*j1KB4Xe<#%LVhvvh3>p0V=~XOshS# zcVJO^<|Bzx^~n`{vcQ1NQvuMj_i_6+DJP?g@^~7q2=fC0eRhCTMH~Y7;A6l=&!tD7 zpTI5Z*A%rM!Xn2q#lKf6A&*Nwo3J4pr8i>2jYgdbw_6aDEAC9V8I=NSCu~LX-7T6y zDS;HY5(#dyo$yN0OiGcp6T*EKX}go{8n|lO7MtvXufn9r@omISzZhFPE~D0l+-{9_ zdAZsd@^HtDi@w#uC$|)re2euaY`6_}h!Onu7a3l@J;jT<7>$J)h9((?h8c!N89qWl z0^ashN}-o&2U!zcwY6i8N?mKGwsTf=cHA_K(iuhw^?A(gmKpQ2oe@j;0bB|c@dLQ> zGvEhs-6KR29d&#jl%m!|K07;JF)0Oj zJ%8J)*(_d(m%EEK^df0R(h2iR}(z@3s_6sanG#GC54a_RSTB-x7&T^^?sV<~0BueB`wE`<38VC$f ztpWfS5(-SuogJG6X^cT%${4|=`BcpCWw`5@zZv&@2=hr@fy)?n@pb|pvVi+(py~ie zOM(R;=0KB$-i&)98`k@Wzy9{9wiBMbD%%yiQthM&GLvH2u2!ub2mUa(T(Mfoj^mb_ zE{k~dw0!imd?d>UJa}3@cv?Q7@+uDFcDdrXm14AA_Nw(-G1x9U4ZF%>$bm=%kW+W6 zF67vC*M*z2w#&BD^dQG^nwZn9+Eq!fPpK*o zxf7Ajuo1W0qg}5(Di*DfCq-w++b)@-l4G$DR=BWOWFc_ruvB8T?QqxW47p!4VHMl1 zZHFyaro}C9JKS}(T+`k0N};t~YYn;2CcROg54UlCNN$&+W#y`;bN44G;gP=f2dr!Z zz!~8L+uUW*HV<~W(+OH`DPaCKkKrwDxrhlfC`PbghdjVl&fWIqLhWuxJDAIQ$r9H@ zfWLij9M=yc!Fw6Tc#GkWKtM?;m&QU4s}GD{DMCt0-?n48xoj$qsi{kKWzIKb(a;0(T8L6G?E1cDN6m z$xkIw8p+x=j-^uy*o4=%lTys$EeFL)See<7N5#pu8I~eai%0B?9jKvi6Pa5=+mjd&z8hI)o4GoY$a_%qUDULY&^=Ul8b6@ zgdFG$e-Gf7@C@?M_Ye&zU5980&54gW3W&LrNwN-0U7~$>#)FPA^7? zL;Rg&aNj@t^$)=YXj8u#o@{$%w_?MhT5`%&uMUf6sa$C`aNcj1%FSA%S&X)wa-&{t z;F?=;s&dV(R_pL#*|jUhU>lb7x>}h$$Fmz9T;;cO3luE*B}i`h+axE%JYM@nockh{ zUxYkd`$d@hB9vcfI$1h@ZMfIU$+WY4UW|F+%DfQsdOnVdHbU9htd=WQDFXUMtWIi9J z*~6CUFJ*^(lxB}wX1M(Iwi>s1o0F88j@vR$!om0-P==&mf96N78PHvTsE6*jJDBtC z4U19LkENX7U;+9MEkmhby=G zGGw*oW!ur#7D(Vhs*XymBjzj_WxstuJO$YFImNrM~S}tfK2FMa-!cz1sG2 zr?;zCF_#*t)MZ3&S2O%zXQ;31maQKhTS0Hrt=@G7y?9l{tG|ofD_1SxggcI1u98lX zu!JRjsg|4n`Hu;ut)gRXmqFV#lP$;Ej<(4#XC|*+IaxxC32vIuPNl?@S|#?MKpk9~ z;uUv2S9QP?C3xF*>|#UJL$EDGi90odkOjH`CU(4Ml?Ib z{W?m>*Dvok>iMNhyVUGI))w>h*<0)cWGGh#8l^YNOBi}~zYRaxH6|V!Tq1eRnPJdv zzbO=xbb?NblZ8cBh8c#XZrV$)aE+K#!wZ>Sy>e<>G(y3vR}Fj&d9bAol(qukKn+I! z+^Fo|XMzac2^*{sVAOrFXlV99jby`=dG9)%36H_}7Fw+dw^_K$ZL|af8%sJvWq1Cu zhAB~Js9BzenZ>zSVZ$9>W5XZ0!+Jxsimp&Y!?hiDGC|cpjmWVb_=I3?czXL>qwulrAt+nTy8jSvt;5<7q z`|V4K~urno?UFmF2Iu<|XAR;e?;87fkBnS!0vYK5LC{}a?NyUYp~|(@flz}VF~yR{{myTCcNEn!*nqSXUbls$i2RVQ!-_*(z!Ze{D_S-e#C$;Obro-P+&RvUEs z0N$j5uu>>l5=m5tQN&;oHxntIBq)g_Fg5;>&=I6UN01INfVE0a0zir|u0@n~cDz)G z!;wX*linw9rO*GvN5S4??k7o?|NE<{9diBmTeuQWnXthng(d15*emfcHIpt0ROvw{ zxUVZ}2gRZ#dJspT&mV^Yof2-995(S25zXlG%=C0Zc1-nObWD{xgpIR^!wwdJkn}{q ztSW;;^Xau<3P8Z}B%YYS=kid(g<*IEOadBmyB+Sv?GR4elTz;Y!af`Fq&MlehgmzE zmtaC`DbTI-t>~~}nR>+o7L{+K={UHYnUn0E-6ZSZr==~x6}OKjCft=}EwYcqvHVE8 z8x3(m%`$;IJ6%1k-xIXYlcuzjo}WHj8Jt=&Y%&9YSe2hu<@XtGjp{Whz7E$L!f7qI zLM&pz;?0_KEDH35(-5-=Xer2#5=x_Lgn*^SyM8-XBNXzW7x&qOC%v%Wo=8YGxI8py zM!m4l0aqbQGUP{!)ChGY)!8gT#ms!faNSR>Pw zH^?GTov3A|s=m6S8_n7BqQdOjGrVh)E;3HPuq;NTpx8r(YdrFZHx_C57upNlTa=iCL|N08^N+qxL){&ntIqT5Jlqg9v;j?2oDf0879X$m*pn>#} z4YjcixXTd6*azaJ_j2Oj@d(ova5(r_o0oSr+3tHeCBA(WY;VnxwQh}{;IxRk>Q>1o zr!zR(C;o&b{P8*-;_3a?BOSHv(YZ4`mja>n@OVwD=i;M0 z6WjBc>-DuGu)PWcKYw-NwO4209xD&H_8>r0f9X7HugTnIf5Grvb?Z@{dV^Ry#7L03~H$kPDKWv;i}IB+&gbVaW=tAx>s{vu+>X;8#6uJ zg0q%cClEMiC^9}RmOoq&d-3@zAFQ%y60`U#X&Xxsh<)JMscM##C2{7mDwIXvfQgnr z!fz|;nh~?DMJ^AF=a0(2I9OG}sa=zYx8F4bnX8&zuHAW>{j`A=Y!vpn=TU}A>szOvVc+;<_)u~;>2R?j|j4qzmxLg2g%M^&!G`lwy zDqz!eWn2;eSS(a%kQ=$!Uwjno>x#wxt0p0+>!TB%WPv*%bVyq*u~UdyGyOf7jZLFu zSa1iucGI@gF-k_uD3uJnK3Ijmh>8OBh%^C8WYXP+RJDB6xgZ2vuu5^jPpTct|`oEcSK6Z%}**<6OLx{aX9$#5A&aCiA)eK2-_$#wqBP)!DD{4X0(M z8M#tR-(b9~T#6sw`43YHodPx4R(m;uN*GgK7?-si?F#exJhk8F%K*V_fblgGT;k(g zBs}!J+HhKrq4*}kmSAIly5~=W0Z_}>pTg9K4Iy}TYS-}WX|ALkp6QW??pbl<)Ec=*TL z_Xaawzd1YZ?tR{WWAw|@_*$3|e-#y|iupW@%lmIWpLS0Uq4&7Bjf08NaaswW$T&Of zp6tIl`{VP+!}lNFygkjez4NEpJTIH}cF!p_`{%=L>%2TaA3nNlabC7|C=Oy6mzOKC z)CfT9K$j4%2in)hTpw}+@;|?O|MvC!?umpzj!;VI)J|4RwKbo^=2vbkU>2zDgQc%% z1HlN+L~;!pg3(ec?WvK`JeYQkzCLJ{5ErJ8~(ViJ^wSg|2CWB=W}5D^TEUDE{Nt~5Z&G{*9Osz z6b=bD9jB#oxr%|r5-rZ#r>|LzNt&^#`^d2{6KnB{ek5#40fQ)dQ0voIHk}RQ+ga<= z*Oc%n1)}N?6`(8b}i+LGt z?C!MAAI<+*9rOII2rp*uPpiLuZdo08D?drK@OtuI;d};nk@NGUa~|Q<-{%Xwu)9^B z_uwA&^UJ{vUafPI`2D1Xk+%NDeQ7o3|^rv;VnjMxO={Zn4ej&PUZuJd!p>ir3K zoo`#`&gKpqK(X)kX>QU7(DLv&)g#Sb&xj26<%chQ)-xa=<9TAhBZNczKlpS3i5K_? zu@%oR@$nlxe#1u_9&LO)KZoaYd=@gK4ZisJV%Lp+Ut1r3&PPgx%_`1~TVrcWTgt0& zbvNbQ=X1QysyL|Wtd%Ar)3IQm*=h}sMR_DdbqKe2K{k6f5ivbqJb zlHSa0#LnOwSRXB)kPUPeYLq%8{2p*Wb=_$DSU;7IG-=vo|!xX3v5B$&k{cp@$Iy*05mU=dl<|_;)jOSmhhzjW$;@T z;)Ti083ICf|IAugs%zR8EJ}w)85zE;Zn+TPAx=C$y7{O+TNFUqhO~>sA6$u9mPPuB z(K4pSqF|nXS)6~dzOE$9ii z2;nd15FWT-ccPX|VxlY}&{~HOFBcy`*hxBxN^i+ZUfCHldRLd)$OeQ2n9ny%_*=*# z5*Oapt@#`h%Zg-_VDy-7Jwg`}CO{cih4>SLa<9L7w?kDjI#woUKoIL?b)_5@c5#&9 zX)0##)HVvngM3%d_EoHPrP4ZCqC;E8XwS**U=}C*U0usrK;NMIOjwK8Q`jT9@XKI$ zErab%nxUEyaWQ4QVwv$?_?C6y<8BAouHNS^&zaqrTAl?5*MVqoO9fVXg>EdQkTvZR z8WA!aozKLhI{J&kTVl0(Nne%|*OS=;^k&h1S1W%DrolxhR8!AYk3mm2Y-Y&sFwEbD zuN&=F^iI#F4t@_;n!U%e{ykMOmgjSG1y&F^Bx{A5CBh4&kyO>&`(rA4NguX$b#lw- zQJPQlP&3)J)^cAL|7=78s|B|MERV>-0%Yb4ovYB9EARq@>J~Cu>@&3Hjfe?1E=EQX zWYxTHMKKdZ+wW?fPv)q>smCxd~p0LIx4 zcFt}Xh^Yx7WFHsoT}@->(=J81Rn+%1DDgwe=mM>`i*}&k;(`Sd5T3LNdjOp3-D)#t z00H2?iExz(Gi%(ZQCcwA0f?MkMIi&1VYwL|ap@$Koe{A6R_a$SjVFeI zDX*MV=JvVM_IH!EUo2WtksAe=3qH!CxI(H9$t4kSw+r^fjYt_}G%^DDD3Wsdg9 z*SKi3aUIcdK&y(%=Y}?)QHsw|EzLu#oCp+8P0Nb7j~^DJR9^PgoM4n?6=ez>3Q9}u zppL&YVqZ2NW&UDw3!dSdMW$Zq&;?9Wwnj?v1PtX>i$s|o*R1@^QEt@*!)kw5NMJ5_ z)$|hBj|VNNy)<6Rg$agDO2Kmcqn=-K`c~HC-s9r@yuUM2@mo`|S$;rmfKrrlGVEd| zzpmac1Ad^3AjlQ2>Zzjhu5Rk@<($!oiyJ*pdcN{3Ns7$V7)9oz`pfPYII6F|U*M>o zHgk6@;B`8VZ^Plw!Dx)3^td0>1s$KJf)7dfjs^cfZVWg4+p#eJ0H2=?-CCZ+%Dyf4 ztbP~%)rmjZ;MqMKsh5npA27isPL>1$&EDi7m`SXOltIdK0uX=~R_>C9Z#qfBeG*`A z$8f~O!&tuBj z$cHa;w9Aj+)|N~jiJ2Bk;y_FXNidnkNqR0GLlOzl?_&(>E^kKJ+In0p#i5|71z{(Y zLzv%rrWGuWkhZ}^EQEsdc?iI6eP!BQc>GcLg8Hi`w8 zXqW05*9Ih~!fD$!uxQvuw#l|4TWvm>Hj8d@(WfnQ!?9Y?je?BLVxjC35q~Aj1QZW; zaja{1K3u-yPah%(H3gWJzM@l9gRFa z*w^WOcDF^AJb@Z-{aLJ~MQEsNiL!M5VC41M5@qxxVTl-tdo6nqU!ze?pl1TO&42~2 zHH(D_|3n#mLzpO|zl8-4aX7R{9{PY*+T=W%_s*m91n!k}8~EGo@31p8_4Y6<_v50! zxx<23wB<^@^JmX5{nhWC-zv1-RK}>khG@2_`{GzaOnu9nKtmA>@p6^jLOK% zKr2vrPw#n1ivf?C&o7Qi=vCh;DL}<2LxwT`_{jMVcoMMpOD#@5!^@e-sRLz-xeR`!V;T9`Sq z9Hjmi$XVIz|Amcbt#bMOq8(^FciU7FEm=N^pWCH`%m5 zOm};g<7m2`@#MzZkZX^b-0+or349@vn?(jd2HPE>hCeQ-e&G7X)|RhfA>zPx0ER>Z zG81e7yAh~5WVKdqRAYH9gr^h4+#j)Vi7{nj{hIdzrKZE}z@n`UI@u&O$j`%b9|HYsG0r6-5_hh~i2jhDt_Z*J3*LN8)J?NiUQ5JJL(m^byUW%!(sN*`H2>QDi<2kWsX3 zj2hl5ISVFzxwIoQs_cRVXqz8e>=BAjyBF~{(Tcf?Ur+Z0c+Q60Tkr_%|7-$2{Xrzy zki)?cXo-#B%nhWSabKk!WG8_qB{MEM7Wl(;wV;#A8Zs(|R(qn(;2dxa04d+P>9Hfy z!LRtJG-3N--48C!tJE@b%I)^)F28D@s+%=8`Dt;2mXV>g-`niNZJcUj>=dmmSnLx| zdYdIjZ4$PzXm7|qm4-#9ztF$9qI!BZJL_XrS_P*|71-=ke?ebE#KyDEu(RKrV9j>F zg^wF{OC_C^hRSyShy&F+U?Li}x{{KPVI*4nn&>f%B?;gPOH^P+<*`zaVVfSrC~aZg z+JbN~u~^omEi(eTfLW6(&tiT>=M6$`p0Z82ZL4!?Zd$EPh?gnlmPsruCV?Iz(4!pC zXA2JGny?ATQU^RCN=(_ee3w)MVl}D@2J0#t*~n6avd_(+BRe74frZ(7UzQ_+sU29R8e__7hXT48whXUU?>wPNHUb`>% zmL3Er(_G%5FgBDQS@6p?1(qYcGviMKn-KoYd@ZbgY8qmp0H!XP(AJjuAjpV_ zA5$tz^HbN_KGh>Jl6j$$h`rd|X+>;>$vlfm26{ z4El`&aHHg3HXn_Gq59h`I#6R;Z1Kb9c(v> ztViVcw)9;#-ublo3|x*pPcX{xAP(hQFf9zlBoPB2ZfBash5x#M(?2^Py_GIOd@C2; zp(kPiB*HJtQr(xbq5Cw7>tOb~pF}}4vR0&-F*6Qib3q)*RKv>HQpojf?sixPb(OFB zh=GtBhoXGvCy}XtWi3+KK4a$Kmd=R%$Z4)919-eQ!2r|Jr)Z-ptNP2wT>b4Gs?WzApPE$#xEbrZ=#q zA)=uPo6bLi&v06omigs}AAX$v@CBR|E@O2cAV92m6;E&H!sBuYOXyr(dzL&r!as>F z0HTaeQYfh`@Sb20jL8Avjg)~|u*k9kMY247(&jr@!3}AL_O%i+>_|Xu7W`RZ5>Er9 zZ1a3rv>lp5Gmg2A(mldWsECpLz{*qq?5z|{bzc%60^$G$Q zKwzt|9L7XaM{$DwOc2X>#E*}4B0<_1qL@&0m?W8@nfk*=3qoIv zfzCxa9cq3Zi}pCy4yDHG!nUg#QeXF@U~k7yh%ehG$f?pwvv_6P$~%5h4@gU&9Iq;^ zi^5`K`J27mH~E!ASRK(K5IVhn3nJ#G-@RA*l8nm(!E`9pFNi+z^4Z#mL(GCWy=Qzk zXh%ivSU!(?QJ=wX5gp`tdMx{Et|hqpl8h;I+&h8G;~m&_5-XhAZk~FfE8pny>EY|{ z*_)4tpWmDwy*Yhz_6PXp?1;tNak`@rOi$z4IEY4k6pMB)gZjr$j&td=7%|89^2xLa z@UO>9m7I!^KMTHzPa=u=O+J@y#pdsi70DbC$?Sg=>|zDO$_)AO6MS))vi>xV=5xcm zm2PR2Vj0;zeXy2xO!|v_8MsN2{}e<8NAa^`hupARWw>znwmyd z(Xb4LiZx|SqhK--Giu?>4?lb<<})l76hQ=ttd_Qed0MBg;q=Njt1a4vrlsVM?#c1t z{Xk6U_HxXjzH&it&<;=Jvt(|7HQe{!a4e>(pUiF(@nPlD_27_CDrUe zFHFaxlp?!$R`duNL+-SPyF7#9=;2B(R_tmWF-i)1R!9B{S%S z{Sswc>;UAMC90E+TgC9klsy4sfDSi1vx-JxUNDNI@^qFIzx?o}I6*+4K!Gsm5MZ0d z7c}~8lS|c3KY+ zA*yxhcXJ1%-^IPgI)6zQ?AsVw=ha8S4%V>Fvsmz>nrX4$j=@>>Du{*#Gp=vL8F(I1FaX^Si%&q4jAr^XNY4gSrri(V3j-Ui@V6TV{!~nj zKKqERPX~VJC%6rJb1R|&6ukD~qR)}h&$#=h9?&E6W)*2L6kYTa*3%#ok@W~JY%8Nn zBt1C*WEX<#jyMBy<14uj( z$T{HQ4Q8yUfW~UlVd6`ah#()t4V1OZKLND3!crAeC1cF|krF*%gn5F0Xhl%+363;R z)YE+a!~<@_UM$HNcvN0KYaeK#VB{AW$>8}{^`b+N5)x0c=RAm#q7X>=ys`i)Y)SrI zFR0TZPjat%F`Na!f8pwh&KhPM!&nW{K+#mxu`Y71l8V2yTPV@ivhTq1z40V{7;(M89)Js-R9SY2n z#-&;jy#+Q`9%Cd&&I9u2Be`sp{le)dhTzgU1+nIS1KeQ=k=nox0p zhn|l;>C0msAW2|)SyiMmtd>w^dp=;J&qZ2DrT7bs{>35s-g0!JcCs6_6I5eUe@Sg{ z0&9gfJGs$Sbo7lxMGrP3CpVfHFZDlNh*zY5r+rY_){h+A-Y6%&Bs%F4;eu&VOxdpI(nzS!C_bqKVYmJhnUt((S& z!B|}T5*6vOwgPPw6fQ);$2;g*p@)A9eO8F!I-x0kr!#Exv7q2-6?)}zxz7r!ZJAJ5 zSjNhrN3lHU6)$1iS^_p@6Jao&!4i?Oh-twjxPoXD3WAkvGFAZ`$>9R(f?tT@sHEk= zfpFNGEr+o`{8dg)^$h#9a=~7L<7_Mv0ep)pq(TS=EMl{chU|NXcSz)SNIZ_~Tj;#j;vtJ6u2^IE7)55@y3UL%Zz-U83F)aAgbm+&64>0 zv7oiEt5tx`9mm2nX8x%4;9rO3I2ke5w%yir1~zqIPLO~s*k|~;zA>$S z+QgWeIQb~p(V8ayt-7DZ^UVA$crMW3hTT@N($zvP&l`gYcxwy&`~G8482!rDmPvk< z5K4s1?#8M9{M+%dp+`YLiAb~VXu&j3md(+af3$>@f3F@e1YnucrM}Sm*RjwB@6)kh zsTAK5CxWHYcJ0 zP%U`cV@0;HSTJ2HXc;L;MoJP7L=t;&hw&Pcn4K(>L~^o@B%JS%L`nh}R!0u|ng0C# zw?l|B1BI)qF!>J25=Xh0?(v61on)dXbn*SBwCI|-FXf8!)D|q=x6t#pM=MofFOEau zM}1>)xq;?TCO-^q$QEMlJ4@w zsdgHWmk`>B2<<&YD_%or{)s>nIGaA9xHvaJmBuay&%#|^tS3AkJX{MVm+?s(m&r6-O=MSrm$$&*UXw;U%CL1YZ$PkP(keLp2gE zri2>OC@%CNBobZe;lBcn*5Hm&Nl|JA-cF;!sQO%sxpb;gmcDt$O1rX z`53e?bCmn%jGOka`>>t=qeENT8~%w{+D`_9!kZ<=K3&b&127q{;p>weUmxW7`Y_Me zFM`NV9#*p5SKRIx_JvW@Zl`grmQi|=mJa!X#eXy^A>V{$vT(7B6 z3y%+>C&%L6|6Xxw|325&leqc-&ND?a=$6+Z*}B1W+h&U5p397jATs(AN4*9!;=#=5 zr=9FMHW>W}MnBh?o>ODSSlk<$YVnQMx33VIe4Ujtmh0PRxxTUMliUG&<4*{IRVwx& zMph3l7lNP9eGH9teqL5@m@N+bSQN_@twUA9wCo`~le8hcRm9$B627(0e(D+|MFY4-eY{}bzyDSmV|Fkt9v zpcltW3)AP-3)3Z#?AoR2GPg91b4$~=+|o2U5zou{7sLl|J_>fSf)AePetb8krR?^P zsa?4@2E)Yz{EXn|Th4@WPu2ed;qF&dzo%7yabv2lKG0XceH83w4RgLwJo$aR%#%}2 zto>LebKT1(#H{`Mm2{TgfQg^Y`tx4l{Cw6gTDi=Y-eB&9Rtielrf7>)!?yWpZUUdO zmYd0aZ*?rIlUo4pSDITO4DI_k4Pm#TR)w!m(z03cA-4*UwO|GuWb#B zAZ)jXyf{q5^!1wktu6Bmp|kt!fEPhlh7$vLX2v|*uGz%{Yr7^Y3<{@`{)m@G7M#9W z1G2)hWwFuLRu|5Fodwsz?80F(e6mU-i*>V+I?IoFc^1F<@K(8XEN+(g&c$lJGYhW8 zbmm`A*7BbF9PjyXB3QPq-a5cYSt<89JIMlJpV55&2yvv>%;$qAHiW~c=AqqP-2?cS zrEVRp?$)(PMq+K34mB_j3Czupg8jAz%sa()4sQ6D?%w{v;nC}#-~96H@yY4icmI0- z;q14MzyJG>PyWSVC@x3i;OkX*9mSKIWIDV3c6a~qm+iP-rCO^un#CRd!+G*0>u~ou zTLm7Az)Qrldt44~P!Epaa;9BhslthJ9(#K!)n8J5*@l_Cs#PeiQ?hGos&J9lQpNkn z1}In=dF?MT0$mQoD6hOv(qR5Jp@SQ^^odPi-&XD?x07AJofL~!@?(XRIM{@p&<<{> zuEn%imeR;4;2Ru*3U_yF^Q@PF>ZNvOIpY40m2J4%8Ui=|{Z?8iiZ*gz+RIbmM|ykO>Ore>TFQ8eww$j`5za;75;;7tjs2VJ~|1 z%4uxXygo}`-P~(UdxJ+1)y)X6O2gytYHN1S{d8*PYIm>wY2t+X3q&S;z2 z=wj&uC8O=eR{mRM1JqdFaenp5?N5GOqKu=}lo9KDjoC)1qKvmW$~e|Wze}V4>qo&h z*Npy&8vVVOjqLm9Mm8H(IjD3riFj7#YECXe;S*P&N3=+W5IJ&B4Og&ol;?9Ze^VfC z-&1`XoI9F%HipoFJs+>k#XtT2ijn%du4}#i|47$lx1IpK0=hKt`(ks6L{3(d$ixql z>33-4eU3)HYBaJ>H1hjL!G2ytBR7ghetDilWR&vT^OPdd2!2?F2qxq&YRDr7C!3>Q z(%)E?V4e=#$8}Teak2P$34b@M@du%kp6uo;k8cn5j*j|f zX9H69DFsU4tpdG2^Tp&nRb zR@8f1Tl%I_p+ZeZ{`KTXZu+3@vi_mTsEWVod#xQ&sx(?=!o}Qk8Eoe!TU!Zk=XR1( zvtD%UR>{$j@$V;ko#Waaw}nqmy;H%bMzzyuY0TnZYd3odfRdAyeH|~iP-%4F#s;jp zS?|!z4D<#$7lv%TCNa`6{*OwsJ70eIBA=n`H<@9(9k?1o=2SXxkA%!|I&=?2i-x9S z6y#&2^ONxtK33`-V@E;&6`j*_9a^|=RAo*T-ntU*daYy7{Gj)SE#I34cywi+IC=c; za=c%9<;@YoYOP8(MG3yCf#_}(t5vsIV=8USv0cw9R%@OsE$TriwDr`j)-2{fNx}u= zc+Bng@p#v**4oEo&|^Z;J0ABr4A}7)FS3De^)zIR$Kz}gialwgmp=ZJ+nG9M0OzJ7 za>G}Tx@$f8S;DphKFsGopU4l>dG4clw82tnuGQa$vc~3hYJq>g2`;RaJEs+ieqhm}hLBp2X+F;*X zf!WfIX5k@qI;y0OsB34QLRP*MDp=M+E&Z71qxtMus5D1o~Whqo~3zB+01 zBl_eHgG3Bq6Ttw7-%LtYALR=b`~jQ*22WvsFbf|Fag^PQg4UTGY1uAX%II9QHh0K6 z8=$X&&+}jfVOWCe5rpQ7j!}k1;R%Fsc7qgzBY;ge7V2p(rNw#|ZX<#k!nskE5aV!Q`K$&}q@UNyk+;v$v+nD4!`Ifv zz*QYM>%RWZ5X|o46me6skOAm14*)|+DEFv*Yd(L1@R>g@CP%I$S5&|-_>U2gvLuS z15h@dCBnbXT<^j0ev$+c&6c#5DO3Ze=x)PVkx#TE-T#ioYAiq>PsV9X2Q#u1yaPXi z!wzUSFG#Iw+Qt!_B=NUk2*eWKCIjXE52K>bV#8X}mLp3Vf|a7*4tFQ*5YQQOJdm4` zEd%N@6NrTu!QJy16>mfLA$n8G&e^9sCD^qQJ6jP5%96wRz3bFrzsAORX%fEC?pb>T z@GVu=8}-xii3AQJ#yFVr#!tKDkek|BI75BRD>A!Mtv4Zs!tPD%7#E$ zYHMplQAC6sETa#2ljoOt2q9HbJkW#zK2fRosvVQ&7=kqwFK86ivMYv))?vg9OL}vr z(I<^H(HrsN<3Su<2BX{bu7mu|2X{#@Q_u2>ce12n5xrs@uVdX*`g4*f&9;9vX^|agcQF{-LH?}PpwkCkT)SPtDe3GtXaAkwV zqTVE(8-zx@sx^!YFZcwbKA{sY;1&OR^w-Av#87c59PVek%>o=lU0BDPoIST~>B+_7 zOFD!T5l1xj-<0mGa6K>*LRRH&gc6m&v-QCs0BMi{3!vZ%QmW?d+0|TUGeU@TkDVvL zB^KM*FiqG_t5oTZk4g=Uir{**qIl8yUZ!i&UXsVwH5SnwzoQUcgEQcdR4f#9N6Qvh zQ09|YL`f>`WUN9hKpcpqOo&F83K6q;Ao ze12NPKUYYR@^6FwR$Te+(O<`{&_hjSH058J?$u?!d~ep~a}yI}4V9|&c>f+~5M6W> zqDUKUZJpMDy7QYm)aCRnCsRF#P0*N!I<-t7&g+$&=ZF^0s|~rg^tZtvI#fk@m1I5R z6;G_k3E!~UbA-}Xw>A;f8pxrnkq>iBdz5D`XKm{90)h~sP!0485u_j!3x%?|m+URaYa@rEXJ!^KK(G07lFcoy z0r$18wx4ayBHBi{uvxg48vsK^D)I}j23-y|eG^n}r-~uC zODX_-Y!`=F(P4rI8uV(c)-$u9L&C#tlxjk7uzgAMF5CqWbS^u4d~+K^QFYwAWv=aq z)&5=sQiXb^dhJ-+6Pn5N#>sP(GXct}{6or#c#xx<=UTHet~lXZyEJ2>W%9|jMF)~5 zXn)2UR)4b+ggnWKp*gXvj6Blt3KKB&Zf${)cha}A)zZg=960GWX2@ZGU}9Mi?UEF? zki{V2yt3PVsbswXA~WQF$V#}~iMbi??pCZ~*jm!ZwKD>Fg**inZ0T_xbF_FUf}iMpe%OPL4(+Y?XyjG%0AJQvRVfn>4}Khh~#_; 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߼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 export const DEFAULT_CONFIG = { alovaTempPath: path.join('node_modules/.alova'), templatePath: path.join(__dirname, '../../templates'), + log: (...messageArr: any[]) => console.log(...messageArr), getTypescript: async () => { let ts: typeof import('typescript') | null = null; try { diff --git a/src/wormhole/createConfig.ts b/packages/wormhole/src/createConfig.ts similarity index 63% rename from src/wormhole/createConfig.ts rename to packages/wormhole/src/createConfig.ts index 048386c..4c8a8cf 100644 --- a/src/wormhole/createConfig.ts +++ b/packages/wormhole/src/createConfig.ts @@ -1,6 +1,6 @@ -import getAlovaVersion, { AlovaVersion } from '@/wormhole/functions/getAlovaVersion'; -import getAutoTemplateType from '@/wormhole/functions/getAutoTemplateType'; -import TemplateFile from '@/wormhole/modules/TemplateFile'; +import getAlovaVersion, { AlovaVersion } from './functions/getAlovaVersion'; +import getAutoTemplateType from './functions/getAutoTemplateType'; +import TemplateFile from './modules/TemplateFile'; export const createConfig = async (projectPath: string) => { const type = getAutoTemplateType(projectPath); diff --git a/src/wormhole/functions/alovaJson.ts b/packages/wormhole/src/functions/alovaJson.ts similarity index 90% rename from src/wormhole/functions/alovaJson.ts rename to packages/wormhole/src/functions/alovaJson.ts index 1f51698..4cab24d 100644 --- a/src/wormhole/functions/alovaJson.ts +++ b/packages/wormhole/src/functions/alovaJson.ts @@ -1,8 +1,8 @@ -import { DEFAULT_CONFIG } from '@/wormhole'; -import type { TemplateData } from '@/wormhole/functions/openApi2Data'; -import { format } from '@/wormhole/utils'; import fs from 'node:fs'; import path from 'node:path'; +import { DEFAULT_CONFIG } from '../config'; +import { format } from '../utils'; +import type { TemplateData } from './openApi2Data'; export const writeAlovaJson = async (data: TemplateData, originPath: string, name = 'api.json') => { // 将数据转换为 JSON 字符串 diff --git a/src/wormhole/functions/generateApi.ts b/packages/wormhole/src/functions/generateApi.ts similarity index 88% rename from src/wormhole/functions/generateApi.ts rename to packages/wormhole/src/functions/generateApi.ts index 550f73f..8ce2299 100644 --- a/src/wormhole/functions/generateApi.ts +++ b/packages/wormhole/src/functions/generateApi.ts @@ -1,14 +1,14 @@ -import type { GeneratorConfig, TemplateType } from '@/wormhole'; -import { DEFAULT_CONFIG } from '@/wormhole'; -import { getAlovaJsonPath, writeAlovaJson } from '@/wormhole/functions/alovaJson'; -import openApi2Data from '@/wormhole/functions/openApi2Data'; -import TemplateFile from '@/wormhole/modules/TemplateFile'; import { isEqual } from 'lodash'; import fs from 'node:fs'; import path from 'node:path'; import { OpenAPIV3_1 } from 'openapi-types'; +import type { GeneratorConfig, TemplateType } from '..'; +import { DEFAULT_CONFIG } from '../config'; +import TemplateFile from '../modules/TemplateFile'; +import { getAlovaJsonPath, writeAlovaJson } from './alovaJson'; import getAlovaVersion, { AlovaVersion } from './getAlovaVersion'; import getFrameworkTag from './getFrameworkTag'; +import openApi2Data from './openApi2Data'; export default async function ( workspaceRootDir: string, // 项目地址 diff --git a/src/wormhole/functions/getAlovaVersion.ts b/packages/wormhole/src/functions/getAlovaVersion.ts similarity index 100% rename from src/wormhole/functions/getAlovaVersion.ts rename to packages/wormhole/src/functions/getAlovaVersion.ts diff --git a/src/wormhole/functions/getAutoTemplateType.ts b/packages/wormhole/src/functions/getAutoTemplateType.ts similarity index 91% rename from src/wormhole/functions/getAutoTemplateType.ts rename to packages/wormhole/src/functions/getAutoTemplateType.ts index 77dc3c6..91d625e 100644 --- a/src/wormhole/functions/getAutoTemplateType.ts +++ b/packages/wormhole/src/functions/getAutoTemplateType.ts @@ -1,7 +1,7 @@ -import type { TemplateType } from '@/wormhole'; import { createRequire } from 'node:module'; import path from 'node:path'; import { PackageJson } from 'type-fest'; +import type { TemplateType } from '..'; export default (workspaceRootDir: string): TemplateType => { const workspacedRequire = createRequire(workspaceRootDir); diff --git a/src/wormhole/functions/getFrameworkTag.ts b/packages/wormhole/src/functions/getFrameworkTag.ts similarity index 100% rename from src/wormhole/functions/getFrameworkTag.ts rename to packages/wormhole/src/functions/getFrameworkTag.ts diff --git a/src/wormhole/functions/getOpenApiData.ts b/packages/wormhole/src/functions/getOpenApiData.ts similarity index 96% rename from src/wormhole/functions/getOpenApiData.ts rename to packages/wormhole/src/functions/getOpenApiData.ts index 48fced5..9957996 100644 --- a/src/wormhole/functions/getOpenApiData.ts +++ b/packages/wormhole/src/functions/getOpenApiData.ts @@ -1,11 +1,11 @@ -import type { PlatformType } from '@/wormhole'; -import { fetchData } from '@/wormhole/utils'; import importFresh from 'import-fresh'; import YAML from 'js-yaml'; import fs from 'node:fs'; import path from 'node:path'; import { OpenAPIV2, OpenAPIV3_1 } from 'openapi-types'; import swagger2openapi from 'swagger2openapi'; +import type { PlatformType } from '..'; +import { fetchData } from '../utils'; // 判断是否是swagger2.0 function isSwagger2(data: any): data is OpenAPIV2.Document { return !!data?.swagger; diff --git a/src/wormhole/functions/openApi2Data.ts b/packages/wormhole/src/functions/openApi2Data.ts similarity index 96% rename from src/wormhole/functions/openApi2Data.ts rename to packages/wormhole/src/functions/openApi2Data.ts index 0816b8b..5eeccda 100644 --- a/src/wormhole/functions/openApi2Data.ts +++ b/packages/wormhole/src/functions/openApi2Data.ts @@ -1,18 +1,12 @@ -import { log } from '@/components/message'; -import type { ApiDescriptor, GeneratorConfig } from '@/wormhole'; -import { - findBy$ref, - getStandardRefName, - isReferenceObject, - mergeObject, - removeAll$ref -} from '@/wormhole/helper/openapi'; -import { convertToType, jsonSchema2TsStr } from '@/wormhole/helper/schema2type'; -import { getStandardOperationId, getStandardTags } from '@/wormhole/helper/standard'; -import { generateDefaultValues } from '@/wormhole/helper/typeStr'; -import { format, removeUndefined } from '@/wormhole/utils'; import { cloneDeep } from 'lodash'; import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'; +import type { ApiDescriptor, GeneratorConfig } from '..'; +import { DEFAULT_CONFIG } from '../config'; +import { findBy$ref, getStandardRefName, isReferenceObject, mergeObject, removeAll$ref } from '../helper/openapi'; +import { convertToType, jsonSchema2TsStr } from '../helper/schema2type'; +import { getStandardOperationId, getStandardTags } from '../helper/standard'; +import { generateDefaultValues } from '../helper/typeStr'; +import { format, removeUndefined } from '../utils'; import { AlovaVersion } from './getAlovaVersion'; type Path = { @@ -303,7 +297,7 @@ export const transformPathObj = async ( let newApiDescriptor = apiDescriptor; let handleApiDone = false; try { - newApiDescriptor = handleApi(apiDescriptor, log); + newApiDescriptor = handleApi(apiDescriptor, DEFAULT_CONFIG.log); handleApiDone = true; } catch (error) { handleApiDone = false; diff --git a/src/wormhole/generate.ts b/packages/wormhole/src/generate.ts similarity index 88% rename from src/wormhole/generate.ts rename to packages/wormhole/src/generate.ts index 2455edd..baca56a 100644 --- a/src/wormhole/generate.ts +++ b/packages/wormhole/src/generate.ts @@ -1,5 +1,5 @@ -import generateApi from '@/wormhole/functions/generateApi'; -import Configuration from '@/wormhole/modules/Configuration'; +import generateApi from './functions/generateApi'; +import Configuration from './modules/Configuration'; import type { Config, GenerateApiOptions } from './type'; export const generate = async (config: Config, options?: GenerateApiOptions) => { diff --git a/src/wormhole/helper/lodaders.ts b/packages/wormhole/src/helper/lodaders.ts similarity index 97% rename from src/wormhole/helper/lodaders.ts rename to packages/wormhole/src/helper/lodaders.ts index 9771632..604a092 100644 --- a/src/wormhole/helper/lodaders.ts +++ b/packages/wormhole/src/helper/lodaders.ts @@ -1,11 +1,11 @@ -import { DEFAULT_CONFIG } from '@/wormhole'; -import { loadEsmModule } from '@/wormhole/utils'; import { Loader, LoaderSync } from 'cosmiconfig'; import importFresh from 'import-fresh'; import { existsSync, mkdirSync } from 'node:fs'; import { rm, writeFile } from 'node:fs/promises'; import path from 'node:path'; import { pathToFileURL } from 'node:url'; +import { DEFAULT_CONFIG } from '../config'; +import { loadEsmModule } from '../utils'; let typescript: typeof import('typescript'); export const loadTs: Loader = async function loadTs(filepath, content) { diff --git a/src/wormhole/helper/openapi.ts b/packages/wormhole/src/helper/openapi.ts similarity index 99% rename from src/wormhole/helper/openapi.ts rename to packages/wormhole/src/helper/openapi.ts index a63e500..a253079 100644 --- a/src/wormhole/helper/openapi.ts +++ b/packages/wormhole/src/helper/openapi.ts @@ -1,6 +1,6 @@ -import { capitalizeFirstLetter } from '@/wormhole/utils'; import { cloneDeep, isArray, isEqualWith, isObject, mergeWith, sortBy } from 'lodash'; import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'; +import { capitalizeFirstLetter } from '../utils'; import { isValidJSIdentifier, makeIdentifier } from './standard'; /** * 判断是否是$ref对象 diff --git a/src/wormhole/helper/schema2type.ts b/packages/wormhole/src/helper/schema2type.ts similarity index 99% rename from src/wormhole/helper/schema2type.ts rename to packages/wormhole/src/helper/schema2type.ts index 3100dd3..ec466aa 100644 --- a/src/wormhole/helper/schema2type.ts +++ b/packages/wormhole/src/helper/schema2type.ts @@ -1,5 +1,5 @@ -import { format } from '@/wormhole/utils'; import { OpenAPIV3_1 } from 'openapi-types'; +import { format } from '../utils'; import { findBy$ref, getStandardRefName, isReferenceObject } from './openapi'; import { isValidJSIdentifier } from './standard'; diff --git a/src/wormhole/helper/standard.ts b/packages/wormhole/src/helper/standard.ts similarity index 100% rename from src/wormhole/helper/standard.ts rename to packages/wormhole/src/helper/standard.ts diff --git a/src/wormhole/helper/typeStr.ts b/packages/wormhole/src/helper/typeStr.ts similarity index 99% rename from src/wormhole/helper/typeStr.ts rename to packages/wormhole/src/helper/typeStr.ts index 29882d0..305295f 100644 --- a/src/wormhole/helper/typeStr.ts +++ b/packages/wormhole/src/helper/typeStr.ts @@ -1,4 +1,4 @@ -import { format } from '@/wormhole/utils'; +import { format } from '../utils'; // 去除注释 function removeComments(content: string) { // 去除单行注释 diff --git a/packages/wormhole/src/index.ts b/packages/wormhole/src/index.ts new file mode 100644 index 0000000..ffd9b44 --- /dev/null +++ b/packages/wormhole/src/index.ts @@ -0,0 +1,8 @@ +export * from './config'; +export * from './createConfig'; +export * from './functions/alovaJson'; +export * from './functions/openApi2Data'; +export * from './generate'; +export { default as Configuration } from './modules/Configuration'; +export * from './readConfig'; +export * from './type'; diff --git a/src/wormhole/modules/Configuration.ts b/packages/wormhole/src/modules/Configuration.ts similarity index 89% rename from src/wormhole/modules/Configuration.ts rename to packages/wormhole/src/modules/Configuration.ts index 2781f49..bc97d68 100644 --- a/src/wormhole/modules/Configuration.ts +++ b/packages/wormhole/src/modules/Configuration.ts @@ -1,11 +1,11 @@ -import type { Config, GeneratorConfig, TemplateType } from '@/wormhole'; -import { DEFAULT_CONFIG } from '@/wormhole'; -import { getAlovaJsonPath, readAlovaJson } from '@/wormhole/functions/alovaJson'; -import getAutoTemplateType from '@/wormhole/functions/getAutoTemplateType'; -import getOpenApiData from '@/wormhole/functions/getOpenApiData'; -import { isValidJSIdentifier } from '@/wormhole/helper/standard'; -import { isEmpty } from '@/wormhole/utils'; import path from 'node:path'; +import type { Config, GeneratorConfig, TemplateType } from '..'; +import { DEFAULT_CONFIG } from '../config'; +import { getAlovaJsonPath, readAlovaJson } from '../functions/alovaJson'; +import getAutoTemplateType from '../functions/getAutoTemplateType'; +import getOpenApiData from '../functions/getOpenApiData'; +import { isValidJSIdentifier } from '../helper/standard'; +import { isEmpty } from '../utils'; export default class Configuration { config: Config; diff --git a/src/wormhole/modules/TemplateFile.ts b/packages/wormhole/src/modules/TemplateFile.ts similarity index 85% rename from src/wormhole/modules/TemplateFile.ts rename to packages/wormhole/src/modules/TemplateFile.ts index 1241b24..2690a31 100644 --- a/src/wormhole/modules/TemplateFile.ts +++ b/packages/wormhole/src/modules/TemplateFile.ts @@ -1,10 +1,9 @@ -import type { TemplateType } from '@/wormhole'; -import { DEFAULT_CONFIG } from '@/wormhole'; -import type { AlovaVersion } from '@/wormhole/functions/getAlovaVersion'; -import type { TemplateData } from '@/wormhole/functions/openApi2Data'; -import { generateFile, readAndRenderTemplate } from '@/wormhole/utils'; import { cloneDeep, merge } from 'lodash'; import path from 'node:path'; +import type { TemplateType } from '..'; +import { DEFAULT_CONFIG } from '../config'; +import type { AlovaVersion } from '../functions/getAlovaVersion'; +import { generateFile, readAndRenderTemplate } from '../utils'; interface RenderTemplateOptions { root?: boolean; @@ -16,7 +15,7 @@ const DEFAULT_OPTIONS = { root: false, hasVersion: true }; -export const TEMPLATE_DATA = new Map(); + export default class TemplateFile { type: TemplateType; diff --git a/packages/wormhole/src/readConfig.ts b/packages/wormhole/src/readConfig.ts new file mode 100644 index 0000000..60d22a6 --- /dev/null +++ b/packages/wormhole/src/readConfig.ts @@ -0,0 +1,44 @@ +import { cosmiconfig } from 'cosmiconfig'; +import path from 'node:path'; +import { DEFAULT_CONFIG } from './config'; +import { getAlovaJsonPath, readAlovaJson } from './functions/alovaJson'; +import { loadJs, loadTs } from './helper/lodaders'; +import Configuration from './modules/Configuration'; +import type { Config } from './type'; + +const alovaExplorer = cosmiconfig('alova', { + cache: false, + loaders: { + '.js': loadJs, + '.cjs': loadJs, + '.mjs': loadJs, + '.ts': loadTs, + '.mts': loadTs, + '.cts': loadTs + } +}); +export const readConfig = async (projectPath: string = process.cwd()) => { + const searchResult = await alovaExplorer.search(path.resolve(projectPath)); + alovaExplorer.clearCaches(); + if (searchResult?.isEmpty) { + return null; + } + const config = searchResult?.config as Config | null; + if (config) { + // 缓存文件地址 + readAndSaveAlovaJson(config, projectPath); + } + return config; +}; +export const readAndSaveAlovaJson = (config: Config, projectPath: string = process.cwd()) => { + const configuration = new Configuration(config, projectPath); + configuration.getAllOutputPath().forEach(outputPath => { + // 缓存文件地址 + const alovaJsonPath = getAlovaJsonPath(projectPath, outputPath); + readAlovaJson(alovaJsonPath).then(data => { + // 保存templateData + DEFAULT_CONFIG.templateData.set(alovaJsonPath, data); + }); + }); +}; +export default readConfig; diff --git a/src/wormhole/type.ts b/packages/wormhole/src/type.ts similarity index 100% rename from src/wormhole/type.ts rename to packages/wormhole/src/type.ts diff --git a/src/wormhole/utils/index.ts b/packages/wormhole/src/utils/index.ts similarity index 100% rename from src/wormhole/utils/index.ts rename to packages/wormhole/src/utils/index.ts diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index f91b06e..92a5978 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,2 +1,3 @@ packages: - 'test/*' + - 'packages/*' diff --git a/src/commands/generateApi.ts b/src/commands/generateApi.ts index 2426d3b..7a0d26a 100644 --- a/src/commands/generateApi.ts +++ b/src/commands/generateApi.ts @@ -1,16 +1,17 @@ import message from '@/components/message'; -import { CONFIG_POOL } from '@/helper/configuration'; +import { alovaWork } from '@/helper/work'; import { getFileNameByPath } from '@/utils'; -import { generate } from '@/wormhole'; // 用于自动生成 export default { commandId: 'alova.generateApi', handler: () => async () => { + console.log(8); + // 生成api文件 - for (const configuration of CONFIG_POOL) { - const result = await generate(configuration.config, { projectPath: configuration.workspaceRootDir }); - if (result?.some(item => !!item)) { - message.info(`[${getFileNameByPath(configuration.workspaceRootDir)}]:Your API is updated`); + const { resultArr } = await alovaWork.generate(); + for (const [workspaceRootDir, result] of resultArr) { + if (result) { + message.info(`[${getFileNameByPath(workspaceRootDir)}]:Your API is updated`); } } } diff --git a/src/commands/index.ts b/src/commands/index.ts new file mode 100644 index 0000000..bc97896 --- /dev/null +++ b/src/commands/index.ts @@ -0,0 +1,15 @@ +import autocomplete from './autocomplete'; +import generateApi from './generateApi'; +import refresh from './refresh'; +import setup from './setup'; +import showStatusBarIcon from './showStatusBarIcon'; + +export const commands = [setup, autocomplete, generateApi, refresh, showStatusBarIcon]; +export const commandsMap = { + setup, + autocomplete, + generateApi, + refresh, + showStatusBarIcon +}; +export type CommandKey = keyof typeof commandsMap; diff --git a/src/commands/refresh.ts b/src/commands/refresh.ts index c705402..66e98e6 100644 --- a/src/commands/refresh.ts +++ b/src/commands/refresh.ts @@ -1,23 +1,27 @@ import Error from '@/components/error'; import message from '@/components/message'; import { loading, reset } from '@/components/statusBar'; -import { CONFIG_POOL } from '@/helper/configuration'; +import { alovaWork } from '@/helper/work'; import { getFileNameByPath } from '@/utils'; -import { generate } from '@/wormhole'; export default { commandId: 'alova.refresh', handler: () => async () => { try { + await alovaWork.readConfig(); loading(); // 生成api文件 - for (const configuration of CONFIG_POOL) { - await generate(configuration.config, { force: true, projectPath: configuration.workspaceRootDir }); - reset(); - message.info(`[${getFileNameByPath(configuration.workspaceRootDir)}]:Your API is refresh`); + const { resultArr, errorArr } = await alovaWork.generate(true); + for (const [workspaceRootDir] of resultArr) { + message.info(`[${getFileNameByPath(workspaceRootDir)}]:Your API is refresh`); } + errorArr.forEach(([, error]) => { + throw error; + }); } catch (error: any) { - if ((error as Error).ERROR_CODE) { + console.log(error, 22); + + if ((error as Error)?.ERROR_CODE) { message.error(error.message); } } finally { diff --git a/src/commands/setup.ts b/src/commands/setup.ts index 3ab0215..ae7bb04 100644 --- a/src/commands/setup.ts +++ b/src/commands/setup.ts @@ -1,7 +1,6 @@ import autocomplete from '@/components/autocomplete'; import { outputChannel } from '@/components/message'; -import readConfig from '@/functions/readConfig'; -import { highPrecisionInterval } from '@/utils'; +import { alovaWork } from '@/helper/work'; import * as vscode from 'vscode'; import showStatusBarIcon from './showStatusBarIcon'; @@ -11,13 +10,6 @@ export default { vscode.commands.executeCommand(showStatusBarIcon.commandId); context.subscriptions.push(autocomplete); context.subscriptions.push(outputChannel); - // 读取所有配置文件 - highPrecisionInterval(() => { - // 获得所有工作区 - const workspaceFolders = vscode.workspace.workspaceFolders || []; - for (const workspaceFolder of workspaceFolders) { - readConfig(`${workspaceFolder.uri.fsPath}/`); - } - }, 500); + alovaWork.readConfig(); } } as Commonand; diff --git a/src/components/autocomplete.ts b/src/components/autocomplete.ts index d25bd2c..b498d7b 100644 --- a/src/components/autocomplete.ts +++ b/src/components/autocomplete.ts @@ -6,13 +6,13 @@ class AutoComplete extends vscode.CompletionItem {} export default vscode.languages.registerCompletionItemProvider( ['javascript', 'typescript', 'vue', 'javascriptreact', 'typescriptreact', 'svelte'], { - provideCompletionItems(document: vscode.TextDocument, position: vscode.Position) { + async provideCompletionItems(document: vscode.TextDocument, position: vscode.Position) { // 支持换行 代码从起始位置到输入位置 const text = document.lineAt(position).text.slice(0, position.character); // const linePrefix = ; if (/a->.*/.test(text)) { const [, value] = /a->(.*)[\s.>:-]?/.exec(text) || []; - return autocomplete(value.trim(), document.uri.fsPath).map(item => { + return (await autocomplete(value.trim(), document.uri.fsPath)).map(item => { const completionItem = new AutoComplete(item.path, vscode.CompletionItemKind.Function); completionItem.detail = `[${item.method}] ${item.summary}`; completionItem.documentation = new vscode.MarkdownString(item.documentation ?? item.replaceText); diff --git a/src/components/message.ts b/src/components/message.ts index e4137f8..6ce81c7 100644 --- a/src/components/message.ts +++ b/src/components/message.ts @@ -38,7 +38,6 @@ export function log(...messageArr: any[]) { outputChannel.append(`${message} `); }); outputChannel.append('\n'); - outputChannel.show(); } export default { info, diff --git a/src/extension.ts b/src/extension.ts index e0b3a46..782f45e 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,14 +1,8 @@ +import { commands } from '@/commands'; +import setup from '@/commands/setup'; import * as vscode from 'vscode'; -import autocomplete from './commands/autocomplete'; -import generateApi from './commands/generateApi'; -import refresh from './commands/refresh'; -import setup from './commands/setup'; -import showStatusBarIcon from './commands/showStatusBarIcon'; import Error from './components/error'; import { log } from './components/message'; -import './globalConfig'; - -const commands = [setup, autocomplete, generateApi, refresh, showStatusBarIcon]; export function activate(context: vscode.ExtensionContext) { // 插件注册 diff --git a/src/functions/autocomplete.ts b/src/functions/autocomplete.ts index 09485aa..831b264 100644 --- a/src/functions/autocomplete.ts +++ b/src/functions/autocomplete.ts @@ -1,8 +1,5 @@ -import { CONFIG_POOL } from '@/helper/configuration'; -import { DEFAULT_CONFIG } from '@/wormhole'; -import { getAlovaJsonPath } from '@/wormhole/functions/alovaJson'; -import { Api } from '@/wormhole/functions/openApi2Data'; -import path from 'node:path'; +import { alovaWork } from '@/helper/work'; +import type { Api } from '@alova/wormhole'; type AutoCompleteItem = { replaceText: string; @@ -47,20 +44,5 @@ const filterAutoCompleteItem = (text: string, apiArr: Api[]): AutoCompleteItem[] }); return autoCompleteArr; }; -export default (text: string, filePath: string): AutoCompleteItem[] => { - const config = CONFIG_POOL.find(item => filePath.includes(path.resolve(item.workspaceRootDir))); - if (!config) { - return []; - } - const outputArr = config?.getAllOutputPath() || []; - return outputArr - .map(output => { - const apiPath = getAlovaJsonPath(config.workspaceRootDir, output); - const templateData = DEFAULT_CONFIG.templateData.get(apiPath); - if (!templateData) { - return []; - } - return templateData.pathApis.map(item => filterAutoCompleteItem(text, item.apis)); - }) - .flat(2); -}; +export default async (text: string, filePath: string): Promise => + filterAutoCompleteItem(text, await alovaWork.getApis(filePath)); diff --git a/src/globalConfig.ts b/src/globalConfig.ts index 1a64474..555bcb9 100644 --- a/src/globalConfig.ts +++ b/src/globalConfig.ts @@ -1,7 +1,7 @@ -import getTypescript from '@/functions/getTypescript'; +import { getTypescript } from '@/utils/work'; +import { DEFAULT_CONFIG } from '@alova/wormhole'; import path from 'node:path'; import { pathToFileURL } from 'node:url'; -import { DEFAULT_CONFIG } from './wormhole'; // work.js线程路径 export const WORK_PATH = pathToFileURL(path.join(__dirname, '/work.js')); // 渲染模板路径 diff --git a/src/helper/configuration.ts b/src/helper/configuration.ts index 245b18a..2cb9a3f 100644 --- a/src/helper/configuration.ts +++ b/src/helper/configuration.ts @@ -1,4 +1,4 @@ -import Configuration from '@/wormhole/modules/Configuration'; +import Configuration from '@alova/wormhole/src/modules/Configuration'; export const CONFIG_POOL: Array = []; export default { CONFIG_POOL }; diff --git a/src/helper/work.ts b/src/helper/work.ts index f13bb0f..b15aa83 100644 --- a/src/helper/work.ts +++ b/src/helper/work.ts @@ -1,14 +1,42 @@ +import { commandsMap } from '@/commands'; import { WORK_PATH } from '@/globalConfig'; -import { deserialize, uuid } from '@/utils'; +import { uuid } from '@/utils'; +import type { Api } from '@alova/wormhole'; +import * as vscode from 'vscode'; import { Worker } from 'worker_threads'; -interface Task { +export interface Task { type: string; payload: { resolve: (data: any) => void; reject: (reason: any) => void; }; } +function toVscodeHelper(alovaWork: Worker, type: string, payload: any) { + switch (type) { + case 'executeCommand': { + const { data } = payload; + const commandId = commandsMap[data as keyof typeof commandsMap]?.commandId; + if (commandId) { + vscode.commands.executeCommand(commandId); + } + break; + } + case 'workspaceRootPathArr': { + const workspaceFolders = vscode.workspace.workspaceFolders || []; + const { data } = payload; + alovaWork.postMessage({ + type: 'workspaceRootPathArr', + taskId: data, + payload: workspaceFolders.map(item => `${item.uri.fsPath}/`) + }); + break; + } + default: { + console.log(type, payload); + } + } +} export default class AlovaWork { private alovaWork: Worker; @@ -18,16 +46,35 @@ export default class AlovaWork { this.alovaWork = new Worker(WORK_PATH); this.alovaWork.on('message', async ({ type, id, payload }) => { if (!this.taskMap.has(id)) { + toVscodeHelper(this.alovaWork, type, payload); return; } const task = this.taskMap.get(id) as Task; switch (type) { - case 'import': { + case 'readConfig': { + const { data, error } = payload; + if (!data && error) { + task.payload.reject(error); + } else { + task.payload.resolve(data); + } + break; + } + case 'generate': { + const { data, error } = payload; + if (!data && error) { + task.payload.reject(error); + } else { + task.payload.resolve(data); + } + break; + } + case 'getApis': { const { data, error } = payload; - if (!data) { + if (!data && error) { task.payload.reject(error); } else { - task.payload.resolve(deserialize(data)); + task.payload.resolve(data); } break; } @@ -42,15 +89,43 @@ export default class AlovaWork { }); } - importEsmModule(modulePath: string | URL) { - return new Promise((resolve, reject) => { + generate(force = false) { + return new Promise<{ + resultArr: Array<[string, boolean]>; + errorArr: Array<[string, any]>; + }>((resolve, reject) => { + const taskId = uuid(); + this.alovaWork.postMessage({ + type: 'generate', + id: taskId, + payload: force + }); + this.taskMap.set(taskId, { type: 'generate', payload: { resolve, reject } }); + }); + } + + readConfig() { + return new Promise((resolve, reject) => { + const taskId = uuid(); + const workspaceFolders = vscode.workspace.workspaceFolders || []; + this.alovaWork.postMessage({ + type: 'readConfig', + id: taskId, + payload: workspaceFolders.map(item => `${item.uri.fsPath}/`) + }); + this.taskMap.set(taskId, { type: 'readConfig', payload: { resolve, reject } }); + }); + } + + getApis(filePath: string) { + return new Promise((resolve, reject) => { const taskId = uuid(); this.alovaWork.postMessage({ - type: 'import', + type: 'getApis', id: taskId, - payload: modulePath + payload: filePath }); - this.taskMap.set(taskId, { type: 'import', payload: { resolve, reject } }); + this.taskMap.set(taskId, { type: 'getApis', payload: { resolve, reject } }); }); } } diff --git a/src/utils/work.ts b/src/utils/work.ts new file mode 100644 index 0000000..d81b7d1 --- /dev/null +++ b/src/utils/work.ts @@ -0,0 +1,45 @@ +import type { CommandKey } from '@/commands'; +import importFresh from 'import-fresh'; +import path from 'node:path'; +import { parentPort } from 'worker_threads'; +import { uuid } from '.'; +import { TASK_MAP } from '../work/config'; + +type MessageCallBack = () => T | Promise; +export async function postMessage(id: string | null, type: string, cb: MessageCallBack) { + let data: any; + let error: any; + try { + data = await cb(); + } catch (err) { + error = err; + } + parentPort?.postMessage({ + type, + payload: { data, error }, + id + }); +} +export function executeCommand(cmd: CommandKey) { + return postMessage(null, 'executeCommand', () => cmd); +} + +export const getTypescriptByWorkspace = async (workspaceRootPathArr: string[]) => { + let typescript: typeof import('typescript') | null = null; + for (const workspaceRootPath of workspaceRootPathArr) { + try { + typescript = importFresh(path.join(workspaceRootPath, './node_modules/typescript')); + } catch (error) {} + } + return typescript; +}; +export function getWorkspaceRootPathArr() { + return new Promise((resolve, reject) => { + const taskId = uuid(); + postMessage(null, 'workspaceRootPathArr', () => taskId); + TASK_MAP.set(taskId, { type: 'workspaceRootPathArr', payload: { resolve, reject } }); + }); +} +export async function getTypescript() { + return getTypescriptByWorkspace(await getWorkspaceRootPathArr()); +} diff --git a/src/work.ts b/src/work.ts index b5de690..ac9161a 100644 --- a/src/work.ts +++ b/src/work.ts @@ -1,26 +1,34 @@ -import { loadEsmModule } from '@/utils/work'; -import serialize from 'serialize-javascript'; +import generate from '@/work/generate'; +import getApis from '@/work/getApis'; +import readConfig from '@/work/readConfig'; import { parentPort } from 'worker_threads'; - +import './globalConfig'; +import type { Task } from './helper/work'; +import { postMessage } from './utils/work'; +import { TASK_MAP } from './work/config'; /** * work子线程,用来处理主线程不能处理的东西,不能引入vscode模块 */ -parentPort?.on('message', async ({ type, payload, id }) => { +parentPort?.on('message', async ({ type, payload, id, taskId }) => { switch (type) { - // 支持动态imort esm - case 'import': { - let data: any; - let error: any; - try { - data = serialize(await loadEsmModule(payload)); - } catch (err) { - error = err; + case 'readConfig': { + postMessage(id, type, () => readConfig(payload)); + break; + } + case 'generate': { + postMessage(id, type, () => generate(payload)); + break; + } + case 'getApis': { + postMessage(id, type, () => getApis(payload)); + break; + } + case 'workspaceRootPathArr': { + if (TASK_MAP.has(taskId)) { + const task = TASK_MAP.get(taskId) as Task; + task.payload.resolve(payload); + TASK_MAP.delete(taskId); } - parentPort?.postMessage({ - type, - payload: { data, error }, - id - }); break; } default: { diff --git a/src/work/config.ts b/src/work/config.ts new file mode 100644 index 0000000..bb05db3 --- /dev/null +++ b/src/work/config.ts @@ -0,0 +1,8 @@ +import type { Task } from '@/helper/work'; +import type { Configuration } from '@alova/wormhole'; + +export const TASK_MAP = new Map(); +export const CONFIG_POOL: Array = []; +export default { + CONFIG_POOL +}; diff --git a/src/work/generate.ts b/src/work/generate.ts new file mode 100644 index 0000000..8a13a37 --- /dev/null +++ b/src/work/generate.ts @@ -0,0 +1,22 @@ +import { generate } from '@alova/wormhole'; +import { CONFIG_POOL } from './config'; + +export default async (force: boolean) => { + const resultArr = []; + const errorArr = []; + for (const configuration of CONFIG_POOL) { + try { + const generateResult = await generate(configuration.config, { + force, + projectPath: configuration.workspaceRootDir + }); + resultArr.push([configuration.workspaceRootDir, generateResult?.some(item => !!item)]); + } catch (error) { + errorArr.push([configuration.workspaceRootDir, error]); + } + } + return { + resultArr, + errorArr + }; +}; diff --git a/src/work/getApis.ts b/src/work/getApis.ts new file mode 100644 index 0000000..e0b9386 --- /dev/null +++ b/src/work/getApis.ts @@ -0,0 +1,21 @@ +import { DEFAULT_CONFIG, getAlovaJsonPath } from '@alova/wormhole'; +import path from 'node:path'; +import { CONFIG_POOL } from './config'; + +export default (filePath: string) => { + const config = CONFIG_POOL.find(item => filePath.includes(path.resolve(item.workspaceRootDir))); + if (!config) { + return []; + } + const outputArr = config?.getAllOutputPath() || []; + return outputArr + .map(output => { + const apiPath = getAlovaJsonPath(config.workspaceRootDir, output); + const templateData = DEFAULT_CONFIG.templateData.get(apiPath); + if (!templateData) { + return []; + } + return templateData.pathApis.map(item => item.apis); + }) + .flat(2); +}; diff --git a/src/functions/readConfig.ts b/src/work/readConfig.ts similarity index 59% rename from src/functions/readConfig.ts rename to src/work/readConfig.ts index 4cbc64e..2139ab0 100644 --- a/src/functions/readConfig.ts +++ b/src/work/readConfig.ts @@ -1,12 +1,11 @@ -import generateApi from '@/commands/generateApi'; -import { CONFIG_POOL } from '@/helper/configuration'; import { highPrecisionInterval } from '@/utils'; -import { readConfig } from '@/wormhole'; -import Configuration from '@/wormhole/modules/Configuration'; -import * as vscode from 'vscode'; +import { executeCommand } from '@/utils/work'; +import { Configuration, readConfig } from '@alova/wormhole'; +import { CONFIG_POOL } from './config'; const AUTOUPDATE_CONFIG_MAP = new Map>(); const AUTOUPDATE_MAP = new Map>(); + function refeshAutoUpdate(configuration: Configuration) { const { time, immediate } = configuration.getAutoUpdateConfig(); const oldConfig = AUTOUPDATE_CONFIG_MAP.get(configuration); @@ -20,7 +19,7 @@ function refeshAutoUpdate(configuration: Configuration) { configuration, highPrecisionInterval( () => { - vscode.commands.executeCommand(generateApi.commandId); + executeCommand('generateApi'); }, time * 1000, immediate @@ -36,18 +35,20 @@ function removeConfiguration(workspaceRootPath: string) { CONFIG_POOL.splice(idx, 1); } } -export default async (workspaceRootPath: string) => { - const config = await readConfig(workspaceRootPath); - if (!config) { - removeConfiguration(workspaceRootPath); - return; - } - let configuration = CONFIG_POOL.find(item => item.workspaceRootDir === workspaceRootPath); - if (!configuration) { - configuration = new Configuration(config, workspaceRootPath); - CONFIG_POOL.push(configuration); - } else { - configuration.config = config; +export default async (workspaceRootPathArr: string[]) => { + for (const workspaceRootPath of workspaceRootPathArr) { + const config = await readConfig(workspaceRootPath); + if (!config) { + removeConfiguration(workspaceRootPath); + return; + } + let configuration = CONFIG_POOL.find(item => item.workspaceRootDir === workspaceRootPath); + if (!configuration) { + configuration = new Configuration(config, workspaceRootPath); + CONFIG_POOL.push(configuration); + } else { + configuration.config = config; + } + refeshAutoUpdate(configuration); } - refeshAutoUpdate(configuration); }; diff --git a/src/wormhole/index.ts b/src/wormhole/index.ts deleted file mode 100644 index 8a764b5..0000000 --- a/src/wormhole/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './config'; -export * from './createConfig'; -export * from './generate'; -export * from './readConfig'; -export * from './type'; diff --git a/src/wormhole/readConfig.ts b/src/wormhole/readConfig.ts deleted file mode 100644 index eafe4e3..0000000 --- a/src/wormhole/readConfig.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { cosmiconfig } from 'cosmiconfig'; -import path from 'node:path'; -import { loadJs, loadTs } from './helper/lodaders'; -import type { Config } from './type'; - -const alovaExplorer = cosmiconfig('alova', { - cache: false, - loaders: { - '.js': loadJs, - '.cjs': loadJs, - '.mjs': loadJs, - '.ts': loadTs, - '.mts': loadTs, - '.cts': loadTs - } -}); -export const readConfig = async (projectPath: string = process.cwd()) => { - const searchResult = await alovaExplorer.search(path.resolve(projectPath)); - alovaExplorer.clearCaches(); - if (searchResult?.isEmpty) { - return null; - } - return searchResult?.config as Config | null; -}; -export default readConfig; diff --git a/tsconfig.json b/tsconfig.json index 8702c2c..0b32384 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -23,9 +23,10 @@ "paths": { "~/*": ["./typings/*"], "@/*": ["./src/*"], - "#/*": ["./*"] + "#/*": ["./*"], + "@alova/*": ["./packages/*"] } }, "exclude": ["design/**", "test/**"], - "include": ["src/**/*.ts", "*.*js", "*.*ts", "scripts/**.*", "typings/**/*.d.ts"] + "include": ["src/**/*.ts", "packages/**/*.ts", "*.*js", "*.*ts", "scripts/**.*", "typings/**/*.d.ts"] } From b6a5aaaac7725be07221c36df386281a84fa7a28 Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Wed, 4 Sep 2024 13:26:16 +0800 Subject: [PATCH 06/47] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84work?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wormhole/src/functions/openApi2Data.ts | 32 +++- packages/wormhole/src/helper/schema2type.ts | 13 +- packages/wormhole/src/type.ts | 6 +- src/extension.ts | 1 - src/globalConfig.ts | 3 +- src/helper/work.ts | 167 +++++++++--------- src/utils/work.ts | 37 +++- src/work.ts | 12 +- 8 files changed, 158 insertions(+), 113 deletions(-) diff --git a/packages/wormhole/src/functions/openApi2Data.ts b/packages/wormhole/src/functions/openApi2Data.ts index 5eeccda..f2f49e2 100644 --- a/packages/wormhole/src/functions/openApi2Data.ts +++ b/packages/wormhole/src/functions/openApi2Data.ts @@ -268,8 +268,8 @@ export const transformPathObj = async ( const response200 = responses?.['200']; let requestBodyObject = requestBody as OpenAPIV3_1.RequestBodyObject; let responseObject = response200 as OpenAPIV3_1.ResponseObject; - let requestKey = ''; - let responseKey = ''; + let requestKey = 'application/json'; + let responseKey = 'application/json'; if (parameters) { apiDescriptor.parameters = []; const parametersArray = isReferenceObject(parameters) @@ -309,15 +309,29 @@ export const transformPathObj = async ( return null; } apiDescriptor = cloneDeep(newApiDescriptor); - if (apiDescriptor.requestBody && requestBody) { - pathObj.requestBody = requestBodyObject; - pathObj.requestBody.content[requestKey].schema = apiDescriptor.requestBody; + if (apiDescriptor.requestBody) { + pathObj.requestBody = requestBodyObject || { content: {} }; + const { content } = pathObj.requestBody; + if (!content[requestKey]) { + content[requestKey] = {}; + } + content[requestKey].schema = apiDescriptor.requestBody; } - if (apiDescriptor.responses && pathObj.responses?.['200'] && responseObject.content) { - pathObj.responses['200'] = responseObject; - responseObject.content[responseKey].schema = apiDescriptor.responses; + if (apiDescriptor.responses) { + if (!pathObj.responses) { + pathObj.responses = {}; + } + pathObj.responses['200'] = responseObject || { content: {} }; + if (!pathObj.responses['200'].content) { + pathObj.responses['200'].content = {}; + } + const { content } = pathObj.responses['200']; + if (!content[responseKey]) { + content[responseKey] = {}; + } + content[responseKey].schema = apiDescriptor.responses; } - if (apiDescriptor.parameters && parameters) { + if (apiDescriptor.parameters) { pathObj.parameters = apiDescriptor.parameters; } delete apiDescriptor.requestBody; diff --git a/packages/wormhole/src/helper/schema2type.ts b/packages/wormhole/src/helper/schema2type.ts index ec466aa..2e97d8d 100644 --- a/packages/wormhole/src/helper/schema2type.ts +++ b/packages/wormhole/src/helper/schema2type.ts @@ -60,11 +60,6 @@ export function comment(type: 'line' | 'docment') { if (!str) { return str; } - /** - * // console.log(str, 63); - * - */ - return startText + str.replace('*/*', '* / *').replace('/*', '/ *').replace('*/', '* /') + endText; } }; @@ -117,7 +112,13 @@ function parseSchema( result = parseArray(schema, openApi, config); break; case 'string': - result = 'string'; + // 根据 https://swagger.io/docs/specification/data-models/data-types/#string + // 针对binary,将类型更改为Blob,其余所有format值均可视为string + if (schema.format === 'binary') { + result = 'Blob'; + } else { + result = 'string'; + } break; case 'number': case 'integer': diff --git a/packages/wormhole/src/type.ts b/packages/wormhole/src/type.ts index 2a03b4e..47b8c28 100644 --- a/packages/wormhole/src/type.ts +++ b/packages/wormhole/src/type.ts @@ -15,6 +15,10 @@ export type ApiDescriptor = Omit void): ApiDescriptor; +} export type GeneratorConfig = { // openapi的json文件url地址 input: string; @@ -52,7 +56,7 @@ export type GeneratorConfig = { // 未指定此函数时则不转换apiDescripor对象 // apiDescriptor的格式与openapi文件的接口对象格式相同 // 对类型生成也同样适用 - handleApi(apiDescriptor: ApiDescriptor, log: (...args: any[]) => void): ApiDescriptor; + handleApi: HandleApi; }; export type Config = { // api生成设置,为数组,每项代表一个自动生成的规则,包含生成的输入输出目录、规范文件地址等等 diff --git a/src/extension.ts b/src/extension.ts index 782f45e..a815929 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -19,7 +19,6 @@ process.on('uncaughtException', (err: Error) => { }); process.on('unhandledRejection', (error: Error) => { const errMsg = error?.message ?? error ?? 'unhandledRejection'; - log(errMsg); if (error.ERROR_CODE) { vscode.window.showErrorMessage(errMsg); } diff --git a/src/globalConfig.ts b/src/globalConfig.ts index 555bcb9..87726a2 100644 --- a/src/globalConfig.ts +++ b/src/globalConfig.ts @@ -1,4 +1,4 @@ -import { getTypescript } from '@/utils/work'; +import { getTypescript, log } from '@/utils/work'; import { DEFAULT_CONFIG } from '@alova/wormhole'; import path from 'node:path'; import { pathToFileURL } from 'node:url'; @@ -10,4 +10,5 @@ export const TEMPLATE_PATH = path.join(__dirname, '../templates'); export const ALOVA_TEMP_PATH = path.join('node_modules/.alova'); DEFAULT_CONFIG.alovaTempPath = ALOVA_TEMP_PATH; DEFAULT_CONFIG.templatePath = TEMPLATE_PATH; +DEFAULT_CONFIG.log = log; DEFAULT_CONFIG.getTypescript = getTypescript; diff --git a/src/helper/work.ts b/src/helper/work.ts index b15aa83..8f97a48 100644 --- a/src/helper/work.ts +++ b/src/helper/work.ts @@ -1,10 +1,12 @@ import { commandsMap } from '@/commands'; +import { log } from '@/components/message'; import { WORK_PATH } from '@/globalConfig'; import { uuid } from '@/utils'; import type { Api } from '@alova/wormhole'; import * as vscode from 'vscode'; import { Worker } from 'worker_threads'; +type MessageCallBack = (data?: any) => T | Promise; export interface Task { type: string; payload: { @@ -12,31 +14,6 @@ export interface Task { reject: (reason: any) => void; }; } -function toVscodeHelper(alovaWork: Worker, type: string, payload: any) { - switch (type) { - case 'executeCommand': { - const { data } = payload; - const commandId = commandsMap[data as keyof typeof commandsMap]?.commandId; - if (commandId) { - vscode.commands.executeCommand(commandId); - } - break; - } - case 'workspaceRootPathArr': { - const workspaceFolders = vscode.workspace.workspaceFolders || []; - const { data } = payload; - alovaWork.postMessage({ - type: 'workspaceRootPathArr', - taskId: data, - payload: workspaceFolders.map(item => `${item.uri.fsPath}/`) - }); - break; - } - default: { - console.log(type, payload); - } - } -} export default class AlovaWork { private alovaWork: Worker; @@ -45,88 +22,116 @@ export default class AlovaWork { constructor() { this.alovaWork = new Worker(WORK_PATH); this.alovaWork.on('message', async ({ type, id, payload }) => { - if (!this.taskMap.has(id)) { - toVscodeHelper(this.alovaWork, type, payload); - return; - } - const task = this.taskMap.get(id) as Task; switch (type) { - case 'readConfig': { - const { data, error } = payload; - if (!data && error) { - task.payload.reject(error); - } else { - task.payload.resolve(data); - } + case 'readConfig': + case 'generate': + case 'getApis': { + this.doneTask(id, type, payload); break; } - case 'generate': { - const { data, error } = payload; - if (!data && error) { - task.payload.reject(error); - } else { - task.payload.resolve(data); - } + case 'executeCommand': { + this.doneTask(id, type, payload, data => { + const commandId = commandsMap[data as keyof typeof commandsMap]?.commandId; + if (commandId) { + vscode.commands.executeCommand(commandId); + } + }); break; } - case 'getApis': { - const { data, error } = payload; - if (!data && error) { - task.payload.reject(error); - } else { - task.payload.resolve(data); - } + case 'workspaceRootPathArr': { + this.postMessage(id, type, () => { + const workspaceFolders = vscode.workspace.workspaceFolders || []; + return workspaceFolders.map(item => `${item.uri.fsPath}/`); + }); + break; + } + case 'log': { + this.doneTask(id, type, payload, data => log(...data)); break; } default: { console.log(type, payload); } } - this.taskMap.delete(id); }); - this.alovaWork.on('error', error => { - console.log(error, 47); + } + + private async setTask(type: string, cb: MessageCallBack) { + let data: any; + let error: any; + try { + data = await cb(); + } catch (err) { + error = err; + } + return new Promise((resolve, reject) => { + if (!data && error) { + reject(error); + return; + } + const taskId = uuid(); + this.postMessage(taskId, type, () => data); + this.taskMap.set(taskId, { type, payload: { resolve, reject } }); + }); + } + + private async doneTask(id: string, type: string, payload: any, cb?: MessageCallBack) { + let { data, error } = payload ?? {}; + if (cb) { + try { + data = await cb(data); + } catch (err) { + error = err; + } + } + if (!this.taskMap.has(id)) { + return; + } + const task = this.taskMap.get(id) as Task; + if (task.type === type) { + if (!data && error) { + task.payload.reject(error); + } else { + task.payload.resolve(data); + } + } + this.taskMap.delete(id); + } + + private async postMessage(id: string | null, type: string, cb: MessageCallBack) { + let data: any; + let error: any; + try { + data = await cb(); + } catch (err) { + error = err; + } + if (!data && error) { + return; + } + this.alovaWork.postMessage({ + type, + id, + payload: data }); } generate(force = false) { - return new Promise<{ + return this.setTask<{ resultArr: Array<[string, boolean]>; errorArr: Array<[string, any]>; - }>((resolve, reject) => { - const taskId = uuid(); - this.alovaWork.postMessage({ - type: 'generate', - id: taskId, - payload: force - }); - this.taskMap.set(taskId, { type: 'generate', payload: { resolve, reject } }); - }); + }>('generate', () => force); } readConfig() { - return new Promise((resolve, reject) => { - const taskId = uuid(); + return this.setTask('readConfig', () => { const workspaceFolders = vscode.workspace.workspaceFolders || []; - this.alovaWork.postMessage({ - type: 'readConfig', - id: taskId, - payload: workspaceFolders.map(item => `${item.uri.fsPath}/`) - }); - this.taskMap.set(taskId, { type: 'readConfig', payload: { resolve, reject } }); + return workspaceFolders.map(item => `${item.uri.fsPath}/`); }); } getApis(filePath: string) { - return new Promise((resolve, reject) => { - const taskId = uuid(); - this.alovaWork.postMessage({ - type: 'getApis', - id: taskId, - payload: filePath - }); - this.taskMap.set(taskId, { type: 'getApis', payload: { resolve, reject } }); - }); + return this.setTask('getApis', () => filePath); } } export const alovaWork = new AlovaWork(); diff --git a/src/utils/work.ts b/src/utils/work.ts index d81b7d1..a89ec4e 100644 --- a/src/utils/work.ts +++ b/src/utils/work.ts @@ -1,4 +1,5 @@ import type { CommandKey } from '@/commands'; +import type { Task } from '@/helper/work'; import importFresh from 'import-fresh'; import path from 'node:path'; import { parentPort } from 'worker_threads'; @@ -20,6 +21,33 @@ export async function postMessage(id: string | null, type: string, cb: Messag id }); } +export async function doneTask(id: string | null, type: string, cb: MessageCallBack) { + let data: any; + let error: any; + try { + data = await cb(); + } catch (err) { + error = err; + } + if (id && TASK_MAP.has(id)) { + const task = TASK_MAP.get(id) as Task; + if (task.type === type) { + if (!data && error) { + task.payload.reject(error); + } else { + task.payload.resolve(data); + } + } + TASK_MAP.delete(id); + } +} +export async function setTask(type: string, cb: MessageCallBack) { + return new Promise((resolve, reject) => { + const taskId = uuid(); + postMessage(taskId, type, cb); + TASK_MAP.set(taskId, { type, payload: { resolve, reject } }); + }); +} export function executeCommand(cmd: CommandKey) { return postMessage(null, 'executeCommand', () => cmd); } @@ -34,12 +62,11 @@ export const getTypescriptByWorkspace = async (workspaceRootPathArr: string[]) = return typescript; }; export function getWorkspaceRootPathArr() { - return new Promise((resolve, reject) => { - const taskId = uuid(); - postMessage(null, 'workspaceRootPathArr', () => taskId); - TASK_MAP.set(taskId, { type: 'workspaceRootPathArr', payload: { resolve, reject } }); - }); + return setTask('workspaceRootPathArr', () => {}); } export async function getTypescript() { return getTypescriptByWorkspace(await getWorkspaceRootPathArr()); } +export async function log(...args: any[]) { + return postMessage(null, 'log', () => args); +} diff --git a/src/work.ts b/src/work.ts index ac9161a..5d88017 100644 --- a/src/work.ts +++ b/src/work.ts @@ -3,13 +3,11 @@ import getApis from '@/work/getApis'; import readConfig from '@/work/readConfig'; import { parentPort } from 'worker_threads'; import './globalConfig'; -import type { Task } from './helper/work'; -import { postMessage } from './utils/work'; -import { TASK_MAP } from './work/config'; +import { doneTask, postMessage } from './utils/work'; /** * work子线程,用来处理主线程不能处理的东西,不能引入vscode模块 */ -parentPort?.on('message', async ({ type, payload, id, taskId }) => { +parentPort?.on('message', async ({ id, type, payload }) => { switch (type) { case 'readConfig': { postMessage(id, type, () => readConfig(payload)); @@ -24,11 +22,7 @@ parentPort?.on('message', async ({ type, payload, id, taskId }) => { break; } case 'workspaceRootPathArr': { - if (TASK_MAP.has(taskId)) { - const task = TASK_MAP.get(taskId) as Task; - task.payload.resolve(payload); - TASK_MAP.delete(taskId); - } + doneTask(id, type, () => payload); break; } default: { From 93e478ec64763afcbd8b0498c11b38baacc9b5d0 Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Wed, 4 Sep 2024 18:08:28 +0800 Subject: [PATCH 07/47] =?UTF-8?q?feat:=20=E5=B0=86=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E6=8B=86=E5=88=86=E6=88=90=E4=B8=80=E4=B8=AA=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscodeignore | 2 ++ esbuild.ts | 3 +++ package.json | 5 +++++ packages/wormhole/package.json | 5 ++++- packages/wormhole/src/config.ts | 8 +++++-- packages/wormhole/src/createConfig.ts | 2 +- packages/wormhole/src/functions/alovaJson.ts | 10 +++++++-- .../wormhole/src/functions/getOpenApiData.ts | 5 +++-- packages/wormhole/src/helper/lodaders.ts | 8 +++---- .../wormhole/src/modules/Configuration.ts | 18 ++++++++-------- packages/wormhole/src/modules/TemplateFile.ts | 5 +---- packages/wormhole/src/utils/index.ts | 15 ++++++++----- pnpm-workspace.yaml | 1 + src/commands/createConfig.ts | 9 ++++++++ src/commands/generateApi.ts | 3 +-- src/commands/index.ts | 4 +++- src/commands/refresh.ts | 4 +--- src/functions/getTypescript.ts | 21 ------------------- src/globalConfig.ts | 16 ++++++++------ src/helper/work.ts | 16 ++++++++++++-- src/utils/work.ts | 7 +++++++ src/work.ts | 5 +++++ src/work/generate.ts | 5 +++-- src/work/generateConfig.ts | 3 +++ src/work/readConfig.ts | 6 +++++- ...fig.handlebars => alova.config.handlebars} | 2 +- templates/index.ts | 1 + templates/package.json | 13 ++++++++++++ tsconfig.json | 10 ++++++++- 29 files changed, 142 insertions(+), 70 deletions(-) create mode 100644 src/commands/createConfig.ts delete mode 100644 src/functions/getTypescript.ts create mode 100644 src/work/generateConfig.ts rename templates/{alovaconfig.handlebars => alova.config.handlebars} (97%) create mode 100644 templates/index.ts create mode 100644 templates/package.json diff --git a/.vscodeignore b/.vscodeignore index c3c3f4a..9fea3cb 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -14,5 +14,7 @@ vsc-extension-quickstart.md pnpm-lock.yaml pnpm-workspace.yaml design/** +templates/** +packages/** test/** .husky/** \ No newline at end of file diff --git a/esbuild.ts b/esbuild.ts index ccabf21..abcf05c 100644 --- a/esbuild.ts +++ b/esbuild.ts @@ -25,6 +25,9 @@ const esbuildProblemMatcherPlugin: Plugin = { async function main() { const ctx = await esbuild.context({ entryPoints: ['src/extension.ts', 'src/work.ts'], + loader: { + '.handlebars': 'text' + }, bundle: true, format: 'cjs', minify: production, diff --git a/package.json b/package.json index a82b7da..cc7e44a 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,11 @@ "command": "alova.refresh", "category": "alova", "title": "alova refresh" + }, + { + "command": "alova.create.config", + "category": "alova", + "title": "create alova config" } ], "icons": { diff --git a/packages/wormhole/package.json b/packages/wormhole/package.json index d66e0d1..d1398ee 100644 --- a/packages/wormhole/package.json +++ b/packages/wormhole/package.json @@ -10,5 +10,8 @@ }, "keywords": [], "author": "", - "license": "ISC" + "license": "ISC", + "dependencies": { + "@alova/templates": "workspace:^" + } } diff --git a/packages/wormhole/src/config.ts b/packages/wormhole/src/config.ts index eb1f122..134348a 100644 --- a/packages/wormhole/src/config.ts +++ b/packages/wormhole/src/config.ts @@ -13,6 +13,10 @@ export const DEFAULT_CONFIG = { } catch (error) {} return ts; }, - templateData: TEMPLATE_DATA + templateData: TEMPLATE_DATA, + Error: class extends Error {} }; -export default { DEFAULT_CONFIG }; +export function setGlobalConfig(config: Partial) { + Object.assign(DEFAULT_CONFIG, config); +} +export default { DEFAULT_CONFIG, setGlobalConfig }; diff --git a/packages/wormhole/src/createConfig.ts b/packages/wormhole/src/createConfig.ts index 4c8a8cf..7de3c54 100644 --- a/packages/wormhole/src/createConfig.ts +++ b/packages/wormhole/src/createConfig.ts @@ -2,7 +2,7 @@ import getAlovaVersion, { AlovaVersion } from './functions/getAlovaVersion'; import getAutoTemplateType from './functions/getAutoTemplateType'; import TemplateFile from './modules/TemplateFile'; -export const createConfig = async (projectPath: string) => { +export const createConfig = async (projectPath: string = process.cwd()) => { const type = getAutoTemplateType(projectPath); const alovaVersion: AlovaVersion = getAlovaVersion(projectPath); const templateFile = new TemplateFile(type, alovaVersion); diff --git a/packages/wormhole/src/functions/alovaJson.ts b/packages/wormhole/src/functions/alovaJson.ts index 4cab24d..4a2430a 100644 --- a/packages/wormhole/src/functions/alovaJson.ts +++ b/packages/wormhole/src/functions/alovaJson.ts @@ -27,7 +27,7 @@ export const readAlovaJson = (originPath: string, name = 'api.json') => { const filePath = `${originPath}_${name}`; return new Promise((resolve, reject) => { if (!fs.existsSync(filePath)) { - reject(new Error('alovaJson not exists')); + reject(new DEFAULT_CONFIG.Error('alovaJson not exists')); return; } // 使用 fs.readFile 读取 JSON 文件 @@ -35,7 +35,13 @@ export const readAlovaJson = (originPath: string, name = 'api.json') => { if (err) { reject(err); } else { - resolve(JSON.parse(data)); + let jsonData = {}; + try { + jsonData = JSON.parse(data); + } catch (error) { + jsonData = {}; + } + resolve(jsonData as TemplateData); } }); }); diff --git a/packages/wormhole/src/functions/getOpenApiData.ts b/packages/wormhole/src/functions/getOpenApiData.ts index 9957996..973bf95 100644 --- a/packages/wormhole/src/functions/getOpenApiData.ts +++ b/packages/wormhole/src/functions/getOpenApiData.ts @@ -5,6 +5,7 @@ import path from 'node:path'; import { OpenAPIV2, OpenAPIV3_1 } from 'openapi-types'; import swagger2openapi from 'swagger2openapi'; import type { PlatformType } from '..'; +import { DEFAULT_CONFIG } from '../config'; import { fetchData } from '../utils'; // 判断是否是swagger2.0 function isSwagger2(data: any): data is OpenAPIV2.Document { @@ -85,10 +86,10 @@ export default async function ( data = (await swagger2openapi.convertObj(data, { warnOnly: true })).openapi as OpenAPIV3_1.Document; } } catch (error) { - throw new Error(`Cannot read file from ${url}`); + throw new DEFAULT_CONFIG.Error(`Cannot read file from ${url}`); } if (!data) { - throw new Error(`Cannot read file from ${url}`); + throw new DEFAULT_CONFIG.Error(`Cannot read file from ${url}`); } return data; } diff --git a/packages/wormhole/src/helper/lodaders.ts b/packages/wormhole/src/helper/lodaders.ts index 604a092..48ddf97 100644 --- a/packages/wormhole/src/helper/lodaders.ts +++ b/packages/wormhole/src/helper/lodaders.ts @@ -14,7 +14,7 @@ export const loadTs: Loader = async function loadTs(filepath, content) { typescript = ts; } if (!typescript) { - throw new Error('typescript dependencie is required'); + throw new DEFAULT_CONFIG.Error('typescript dependencie is required'); } let transpiledContent; try { @@ -87,9 +87,9 @@ export const loadJs: Loader = async function loadJs(filepath, content) { (requireError instanceof SyntaxError && requireError.toString().includes('Cannot use import statement outside a module')) ) { - throw new Error(error.toString()); + throw new DEFAULT_CONFIG.Error(error.toString()); } - throw new Error(requireError.toString()); + throw new DEFAULT_CONFIG.Error(requireError.toString()); } } }; @@ -98,7 +98,7 @@ function resolveTsConfig(directory: string): any { if (filePath !== undefined) { const { config, error } = typescript.readConfigFile(filePath, path => typescript.sys.readFile(path)); if (error) { - throw new Error(`Error in ${filePath}: ${error.messageText.toString()}`); + throw new DEFAULT_CONFIG.Error(`Error in ${filePath}: ${error.messageText.toString()}`); } return config; } diff --git a/packages/wormhole/src/modules/Configuration.ts b/packages/wormhole/src/modules/Configuration.ts index bc97d68..2af988e 100644 --- a/packages/wormhole/src/modules/Configuration.ts +++ b/packages/wormhole/src/modules/Configuration.ts @@ -21,32 +21,32 @@ export default class Configuration { // 检测配置文件 checkConfig() { if (!this.config.generator?.length) { - throw new Error('No items found in the `config.generator`'); + throw new DEFAULT_CONFIG.Error('No items found in the `config.generator`'); } const globalKeySet = new Set(); const outputSet = new Set(); this.config.generator.forEach((item, _, arr) => { if (!item.input) { - throw new Error('Field input is required in `config.generator`'); + throw new DEFAULT_CONFIG.Error('Field input is required in `config.generator`'); } if (!item.output) { - throw new Error('Field output is required in `config.generator`'); + throw new DEFAULT_CONFIG.Error('Field output is required in `config.generator`'); } if (!isEmpty(item.global) && !isValidJSIdentifier(item.global)) { - throw new Error(`\`${item.global}\` does not match variable specification`); + throw new DEFAULT_CONFIG.Error(`\`${item.global}\` does not match variable specification`); } if (arr.length < 2) { return; } if (outputSet.has(path.join(item.output))) { - throw new Error(`output \`${item.output}\` is repated`); + throw new DEFAULT_CONFIG.Error(`output \`${item.output}\` is repated`); } outputSet.add(path.join(item.output)); if (!item.global) { - throw new Error('Field global is required in `config.generator`'); + throw new DEFAULT_CONFIG.Error('Field global is required in `config.generator`'); } if (globalKeySet.has(item.global)) { - throw new Error(`global \`${item.global}\` is repated`); + throw new DEFAULT_CONFIG.Error(`global \`${item.global}\` is repated`); } globalKeySet.add(item.global); }); @@ -54,11 +54,11 @@ export default class Configuration { const { interval } = this.config.autoUpdate; const time = Number(interval); if (Number.isNaN(time)) { - throw new Error('autoUpdate.interval must be a number'); + throw new DEFAULT_CONFIG.Error('autoUpdate.interval must be a number'); } if (time <= 0) { // 最少一秒钟 - throw new Error('Expected to set number which great than 1 in `config.autoUpdate.interval`'); + throw new DEFAULT_CONFIG.Error('Expected to set number which great than 1 in `config.autoUpdate.interval`'); } } } diff --git a/packages/wormhole/src/modules/TemplateFile.ts b/packages/wormhole/src/modules/TemplateFile.ts index 2690a31..634a15b 100644 --- a/packages/wormhole/src/modules/TemplateFile.ts +++ b/packages/wormhole/src/modules/TemplateFile.ts @@ -1,7 +1,5 @@ import { cloneDeep, merge } from 'lodash'; -import path from 'node:path'; import type { TemplateType } from '..'; -import { DEFAULT_CONFIG } from '../config'; import type { AlovaVersion } from '../functions/getAlovaVersion'; import { generateFile, readAndRenderTemplate } from '../utils'; @@ -75,7 +73,6 @@ export default class TemplateFile { const config = merge(cloneDeep(DEFAULT_OPTIONS), userConfig); const fileVersion = config.hasVersion ? this.getVersion() : ''; const filePath = config?.root ? fileVersion + fileName : `${this.type}/${fileVersion}${fileName}`; - const templatePath = path.resolve(DEFAULT_CONFIG.templatePath, `./${filePath}.handlebars`); - return readAndRenderTemplate(templatePath, data); + return readAndRenderTemplate(filePath, data); } } diff --git a/packages/wormhole/src/utils/index.ts b/packages/wormhole/src/utils/index.ts index c618bf9..1b54b7f 100644 --- a/packages/wormhole/src/utils/index.ts +++ b/packages/wormhole/src/utils/index.ts @@ -9,6 +9,7 @@ import * as prettierBabel from 'prettier/plugins/babel'; import * as prettierEsTree from 'prettier/plugins/estree'; import * as prettierTs from 'prettier/plugins/typescript'; import * as prettier from 'prettier/standalone'; +import { DEFAULT_CONFIG } from '../config'; export const getType = (obj: any) => Object.prototype.toString.call(obj).slice(8, -1).toLowerCase(); handlebars.registerHelper('isType', function (this: any, value, type: string, options: HelperOptions) { @@ -54,7 +55,14 @@ handlebars.registerHelper( * @returns 渲染后的内容 */ export async function readAndRenderTemplate(templatePath: string, view: any): Promise { - const data = await promises.readFile(templatePath, 'utf-8'); + let data = ''; + try { + data = await promises.readFile(path.resolve(DEFAULT_CONFIG.templatePath, `${templatePath}.handlebars`), 'utf-8'); + } catch (error) { + const importFn = (await import('@alova/templates')).default; + data = (await (importFn as any)(templatePath)).default; + } + return handlebars.compile(data)(view); } export async function format(text: string, config?: PrettierConfig) { @@ -87,7 +95,7 @@ export async function generateFile(distDir: string, fileName: string, content: s export async function fetchData(url: string) { return fetch(url).then(response => { if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); + throw new DEFAULT_CONFIG.Error(`HTTP error! status: ${response.status}`); } return response.text(); }); @@ -124,6 +132,3 @@ export function capitalizeFirstLetter(str: string) { export function loadEsmModule(modulePath: string | URL): Promise { return new Function('modulePath', `return import(modulePath);`)(modulePath) as Promise; } -export default { - loadEsmModule -}; diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 92a5978..90739c4 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,4 @@ packages: - 'test/*' - 'packages/*' + - 'templates' diff --git a/src/commands/createConfig.ts b/src/commands/createConfig.ts new file mode 100644 index 0000000..30dc391 --- /dev/null +++ b/src/commands/createConfig.ts @@ -0,0 +1,9 @@ +// 用于自动生成alova.config.js +import { alovaWork } from '@/helper/work'; + +export default { + commandId: 'alova.create.config', + handler: () => async () => { + alovaWork.generateConfig(); + } +} as Commonand; diff --git a/src/commands/generateApi.ts b/src/commands/generateApi.ts index 7a0d26a..9c0fa99 100644 --- a/src/commands/generateApi.ts +++ b/src/commands/generateApi.ts @@ -5,8 +5,7 @@ import { getFileNameByPath } from '@/utils'; export default { commandId: 'alova.generateApi', handler: () => async () => { - console.log(8); - + await alovaWork.readConfig(); // 生成api文件 const { resultArr } = await alovaWork.generate(); for (const [workspaceRootDir, result] of resultArr) { diff --git a/src/commands/index.ts b/src/commands/index.ts index bc97896..71e9aa7 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -1,15 +1,17 @@ import autocomplete from './autocomplete'; +import createConfig from './createConfig'; import generateApi from './generateApi'; import refresh from './refresh'; import setup from './setup'; import showStatusBarIcon from './showStatusBarIcon'; -export const commands = [setup, autocomplete, generateApi, refresh, showStatusBarIcon]; +export const commands = [setup, autocomplete, generateApi, refresh, showStatusBarIcon, createConfig]; export const commandsMap = { setup, autocomplete, generateApi, refresh, + createConfig, showStatusBarIcon }; export type CommandKey = keyof typeof commandsMap; diff --git a/src/commands/refresh.ts b/src/commands/refresh.ts index 66e98e6..fd6938e 100644 --- a/src/commands/refresh.ts +++ b/src/commands/refresh.ts @@ -8,7 +8,7 @@ export default { commandId: 'alova.refresh', handler: () => async () => { try { - await alovaWork.readConfig(); + await alovaWork.readConfig(true); loading(); // 生成api文件 const { resultArr, errorArr } = await alovaWork.generate(true); @@ -19,8 +19,6 @@ export default { throw error; }); } catch (error: any) { - console.log(error, 22); - if ((error as Error)?.ERROR_CODE) { message.error(error.message); } diff --git a/src/functions/getTypescript.ts b/src/functions/getTypescript.ts deleted file mode 100644 index cf5dc73..0000000 --- a/src/functions/getTypescript.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { createRequire } from 'node:module'; -import path from 'node:path'; -import * as vscode from 'vscode'; - -export default async () => { - // 获得所有工作区 - const workspaceFolders = vscode.workspace.workspaceFolders || []; - let typescript: typeof import('typescript') | null = null; - for (const workspaceFolder of workspaceFolders) { - try { - const workspaceRootPath = `${workspaceFolder.uri.fsPath}/`; - const workspacedRequire = createRequire(workspaceRootPath); - typescript = workspacedRequire('./node_modules/typescript'); - delete workspacedRequire.cache[path.resolve(workspaceRootPath, './package.json')]; - } catch (error: any) { - // log(error.message); - console.log(error); - } - } - return typescript; -}; diff --git a/src/globalConfig.ts b/src/globalConfig.ts index 87726a2..e25d8a4 100644 --- a/src/globalConfig.ts +++ b/src/globalConfig.ts @@ -1,14 +1,18 @@ +import Error from '@/components/error'; import { getTypescript, log } from '@/utils/work'; -import { DEFAULT_CONFIG } from '@alova/wormhole'; +import { setGlobalConfig } from '@alova/wormhole'; import path from 'node:path'; import { pathToFileURL } from 'node:url'; // work.js线程路径 export const WORK_PATH = pathToFileURL(path.join(__dirname, '/work.js')); // 渲染模板路径 -export const TEMPLATE_PATH = path.join(__dirname, '../templates'); +// export const TEMPLATE_PATH = path.join(__dirname, '../templates'); // alova临时文件路径 export const ALOVA_TEMP_PATH = path.join('node_modules/.alova'); -DEFAULT_CONFIG.alovaTempPath = ALOVA_TEMP_PATH; -DEFAULT_CONFIG.templatePath = TEMPLATE_PATH; -DEFAULT_CONFIG.log = log; -DEFAULT_CONFIG.getTypescript = getTypescript; +// 全局配置 +setGlobalConfig({ + alovaTempPath: ALOVA_TEMP_PATH, + log, + getTypescript, + Error +}); diff --git a/src/helper/work.ts b/src/helper/work.ts index 8f97a48..5891d27 100644 --- a/src/helper/work.ts +++ b/src/helper/work.ts @@ -1,4 +1,5 @@ import { commandsMap } from '@/commands'; +import Error from '@/components/error'; import { log } from '@/components/message'; import { WORK_PATH } from '@/globalConfig'; import { uuid } from '@/utils'; @@ -25,6 +26,7 @@ export default class AlovaWork { switch (type) { case 'readConfig': case 'generate': + case 'generateConfig': case 'getApis': { this.doneTask(id, type, payload); break; @@ -123,15 +125,25 @@ export default class AlovaWork { }>('generate', () => force); } - readConfig() { - return this.setTask('readConfig', () => { + async readConfig(isShowError = false) { + const hasConfig = await this.setTask('readConfig', () => { const workspaceFolders = vscode.workspace.workspaceFolders || []; return workspaceFolders.map(item => `${item.uri.fsPath}/`); }); + if (!hasConfig && isShowError) { + throw new Error('Expected to create alova.config.js in root directory.'); + } } getApis(filePath: string) { return this.setTask('getApis', () => filePath); } + + generateConfig() { + return this.setTask('generateConfig', () => { + const workspaceFolders = vscode.workspace.workspaceFolders || []; + return workspaceFolders.map(item => `${item.uri.fsPath}/`); + }); + } } export const alovaWork = new AlovaWork(); diff --git a/src/utils/work.ts b/src/utils/work.ts index a89ec4e..e949ebf 100644 --- a/src/utils/work.ts +++ b/src/utils/work.ts @@ -7,6 +7,13 @@ import { uuid } from '.'; import { TASK_MAP } from '../work/config'; type MessageCallBack = () => T | Promise; +export function createError(err: Error) { + return { + message: err.message, + stack: err.stack, + ERROR_CODE: (err as any).ERROR_CODE + }; +} export async function postMessage(id: string | null, type: string, cb: MessageCallBack) { let data: any; let error: any; diff --git a/src/work.ts b/src/work.ts index 5d88017..4e68a76 100644 --- a/src/work.ts +++ b/src/work.ts @@ -1,4 +1,5 @@ import generate from '@/work/generate'; +import generateConfig from '@/work/generateConfig'; import getApis from '@/work/getApis'; import readConfig from '@/work/readConfig'; import { parentPort } from 'worker_threads'; @@ -25,6 +26,10 @@ parentPort?.on('message', async ({ id, type, payload }) => { doneTask(id, type, () => payload); break; } + case 'generateConfig': { + postMessage(id, type, () => generateConfig(payload)); + break; + } default: { console.log(type, payload); } diff --git a/src/work/generate.ts b/src/work/generate.ts index 8a13a37..666c98d 100644 --- a/src/work/generate.ts +++ b/src/work/generate.ts @@ -1,4 +1,5 @@ import { generate } from '@alova/wormhole'; +import { createError } from '../utils/work'; import { CONFIG_POOL } from './config'; export default async (force: boolean) => { @@ -11,8 +12,8 @@ export default async (force: boolean) => { projectPath: configuration.workspaceRootDir }); resultArr.push([configuration.workspaceRootDir, generateResult?.some(item => !!item)]); - } catch (error) { - errorArr.push([configuration.workspaceRootDir, error]); + } catch (error: any) { + errorArr.push([configuration.workspaceRootDir, createError(error)]); } } return { diff --git a/src/work/generateConfig.ts b/src/work/generateConfig.ts new file mode 100644 index 0000000..a84d6a5 --- /dev/null +++ b/src/work/generateConfig.ts @@ -0,0 +1,3 @@ +import { createConfig } from '@alova/wormhole'; + +export default async (workspaceRootPathArr: string[]) => Promise.all(workspaceRootPathArr.map(createConfig)); diff --git a/src/work/readConfig.ts b/src/work/readConfig.ts index 2139ab0..306c722 100644 --- a/src/work/readConfig.ts +++ b/src/work/readConfig.ts @@ -15,6 +15,7 @@ function refeshAutoUpdate(configuration: Configuration) { return; } oldTimer?.clear(); + AUTOUPDATE_CONFIG_MAP.set(configuration, { immediate, time }); AUTOUPDATE_MAP.set( configuration, highPrecisionInterval( @@ -36,11 +37,12 @@ function removeConfiguration(workspaceRootPath: string) { } } export default async (workspaceRootPathArr: string[]) => { + let configNum = 0; for (const workspaceRootPath of workspaceRootPathArr) { const config = await readConfig(workspaceRootPath); if (!config) { removeConfiguration(workspaceRootPath); - return; + continue; } let configuration = CONFIG_POOL.find(item => item.workspaceRootDir === workspaceRootPath); if (!configuration) { @@ -50,5 +52,7 @@ export default async (workspaceRootPathArr: string[]) => { configuration.config = config; } refeshAutoUpdate(configuration); + configNum += 1; } + return configNum > 0; }; diff --git a/templates/alovaconfig.handlebars b/templates/alova.config.handlebars similarity index 97% rename from templates/alovaconfig.handlebars rename to templates/alova.config.handlebars index 7174a14..6bdbffc 100644 --- a/templates/alovaconfig.handlebars +++ b/templates/alova.config.handlebars @@ -1,4 +1,4 @@ -import { Config } from '@alova/wormhole'; +import type { Config } from '@alova/wormhole'; // For more config detailed visit: // https://alova.js.org/tutorial/getting-started/extension-integration diff --git a/templates/index.ts b/templates/index.ts new file mode 100644 index 0000000..835db6c --- /dev/null +++ b/templates/index.ts @@ -0,0 +1 @@ +export default (filePath: string) => import(`./${filePath}.handlebars`); diff --git a/templates/package.json b/templates/package.json new file mode 100644 index 0000000..165b21d --- /dev/null +++ b/templates/package.json @@ -0,0 +1,13 @@ +{ + "name": "@alova/templates", + "version": "1.0.0", + "description": "", + "main": "index.ts", + "module": "index.ts", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC" +} diff --git a/tsconfig.json b/tsconfig.json index 0b32384..01d31e4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -28,5 +28,13 @@ } }, "exclude": ["design/**", "test/**"], - "include": ["src/**/*.ts", "packages/**/*.ts", "*.*js", "*.*ts", "scripts/**.*", "typings/**/*.d.ts"] + "include": [ + "src/**/*.ts", + "./templates/index.ts", + "packages/**/*.ts", + "*.*js", + "*.*ts", + "scripts/**.*", + "typings/**/*.d.ts" + ] } From a967057f2576700bc63004c4cafd73754576dfc4 Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Wed, 4 Sep 2024 18:22:07 +0800 Subject: [PATCH 08/47] =?UTF-8?q?chore:=20templates=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E5=88=B0packages=E9=87=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates}/alova.config.handlebars | 0 .../templates}/apiDefinitions.handlebars | 0 {templates => packages/templates}/comment.handlebars | 0 .../templates}/commonjs/createApis.handlebars | 0 .../templates}/commonjs/index.handlebars | 0 .../templates}/commonjs/v3-createApis.handlebars | 0 .../templates}/commonjs/v3-index.handlebars | 0 {templates => packages/templates}/globals.d.handlebars | 0 {templates => packages/templates}/index.ts | 0 .../templates}/module/createApis.handlebars | 0 .../templates}/module/index.handlebars | 0 .../templates}/module/v3-createApis.handlebars | 0 .../templates}/module/v3-index.handlebars | 0 {templates => packages/templates}/package.json | 0 .../templates}/typescript/createApis.handlebars | 0 .../templates}/typescript/index.handlebars | 0 .../templates}/typescript/v3-createApis.handlebars | 0 .../templates}/typescript/v3-index.handlebars | 0 .../templates}/v3-globals.d.handlebars | 0 pnpm-workspace.yaml | 1 - src/globalConfig.ts | 6 +----- tsconfig.json | 10 +--------- 22 files changed, 2 insertions(+), 15 deletions(-) rename {templates => packages/templates}/alova.config.handlebars (100%) rename {templates => packages/templates}/apiDefinitions.handlebars (100%) rename {templates => packages/templates}/comment.handlebars (100%) rename {templates => packages/templates}/commonjs/createApis.handlebars (100%) rename {templates => packages/templates}/commonjs/index.handlebars (100%) rename {templates => packages/templates}/commonjs/v3-createApis.handlebars (100%) rename {templates => packages/templates}/commonjs/v3-index.handlebars (100%) rename {templates => packages/templates}/globals.d.handlebars (100%) rename {templates => packages/templates}/index.ts (100%) rename {templates => packages/templates}/module/createApis.handlebars (100%) rename {templates => packages/templates}/module/index.handlebars (100%) rename {templates => packages/templates}/module/v3-createApis.handlebars (100%) rename {templates => packages/templates}/module/v3-index.handlebars (100%) rename {templates => packages/templates}/package.json (100%) rename {templates => packages/templates}/typescript/createApis.handlebars (100%) rename {templates => packages/templates}/typescript/index.handlebars (100%) rename {templates => packages/templates}/typescript/v3-createApis.handlebars (100%) rename {templates => packages/templates}/typescript/v3-index.handlebars (100%) rename {templates => packages/templates}/v3-globals.d.handlebars (100%) diff --git a/templates/alova.config.handlebars b/packages/templates/alova.config.handlebars similarity index 100% rename from templates/alova.config.handlebars rename to packages/templates/alova.config.handlebars diff --git a/templates/apiDefinitions.handlebars b/packages/templates/apiDefinitions.handlebars similarity index 100% rename from templates/apiDefinitions.handlebars rename to packages/templates/apiDefinitions.handlebars diff --git a/templates/comment.handlebars b/packages/templates/comment.handlebars similarity index 100% rename from templates/comment.handlebars rename to packages/templates/comment.handlebars diff --git a/templates/commonjs/createApis.handlebars b/packages/templates/commonjs/createApis.handlebars similarity index 100% rename from templates/commonjs/createApis.handlebars rename to packages/templates/commonjs/createApis.handlebars diff --git a/templates/commonjs/index.handlebars b/packages/templates/commonjs/index.handlebars similarity index 100% rename from templates/commonjs/index.handlebars rename to packages/templates/commonjs/index.handlebars diff --git a/templates/commonjs/v3-createApis.handlebars b/packages/templates/commonjs/v3-createApis.handlebars similarity index 100% rename from templates/commonjs/v3-createApis.handlebars rename to packages/templates/commonjs/v3-createApis.handlebars diff --git a/templates/commonjs/v3-index.handlebars b/packages/templates/commonjs/v3-index.handlebars similarity index 100% rename from templates/commonjs/v3-index.handlebars rename to packages/templates/commonjs/v3-index.handlebars diff --git a/templates/globals.d.handlebars b/packages/templates/globals.d.handlebars similarity index 100% rename from templates/globals.d.handlebars rename to packages/templates/globals.d.handlebars diff --git a/templates/index.ts b/packages/templates/index.ts similarity index 100% rename from templates/index.ts rename to packages/templates/index.ts diff --git a/templates/module/createApis.handlebars b/packages/templates/module/createApis.handlebars similarity index 100% rename from templates/module/createApis.handlebars rename to packages/templates/module/createApis.handlebars diff --git a/templates/module/index.handlebars b/packages/templates/module/index.handlebars similarity index 100% rename from templates/module/index.handlebars rename to packages/templates/module/index.handlebars diff --git a/templates/module/v3-createApis.handlebars b/packages/templates/module/v3-createApis.handlebars similarity index 100% rename from templates/module/v3-createApis.handlebars rename to packages/templates/module/v3-createApis.handlebars diff --git a/templates/module/v3-index.handlebars b/packages/templates/module/v3-index.handlebars similarity index 100% rename from templates/module/v3-index.handlebars rename to packages/templates/module/v3-index.handlebars diff --git a/templates/package.json b/packages/templates/package.json similarity index 100% rename from templates/package.json rename to packages/templates/package.json diff --git a/templates/typescript/createApis.handlebars b/packages/templates/typescript/createApis.handlebars similarity index 100% rename from templates/typescript/createApis.handlebars rename to packages/templates/typescript/createApis.handlebars diff --git a/templates/typescript/index.handlebars b/packages/templates/typescript/index.handlebars similarity index 100% rename from templates/typescript/index.handlebars rename to packages/templates/typescript/index.handlebars diff --git a/templates/typescript/v3-createApis.handlebars b/packages/templates/typescript/v3-createApis.handlebars similarity index 100% rename from templates/typescript/v3-createApis.handlebars rename to packages/templates/typescript/v3-createApis.handlebars diff --git a/templates/typescript/v3-index.handlebars b/packages/templates/typescript/v3-index.handlebars similarity index 100% rename from templates/typescript/v3-index.handlebars rename to packages/templates/typescript/v3-index.handlebars diff --git a/templates/v3-globals.d.handlebars b/packages/templates/v3-globals.d.handlebars similarity index 100% rename from templates/v3-globals.d.handlebars rename to packages/templates/v3-globals.d.handlebars diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 90739c4..92a5978 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,4 +1,3 @@ packages: - 'test/*' - 'packages/*' - - 'templates' diff --git a/src/globalConfig.ts b/src/globalConfig.ts index e25d8a4..e584a23 100644 --- a/src/globalConfig.ts +++ b/src/globalConfig.ts @@ -1,3 +1,4 @@ +/* eslint-disable import/prefer-default-export */ import Error from '@/components/error'; import { getTypescript, log } from '@/utils/work'; import { setGlobalConfig } from '@alova/wormhole'; @@ -5,13 +6,8 @@ import path from 'node:path'; import { pathToFileURL } from 'node:url'; // work.js线程路径 export const WORK_PATH = pathToFileURL(path.join(__dirname, '/work.js')); -// 渲染模板路径 -// export const TEMPLATE_PATH = path.join(__dirname, '../templates'); -// alova临时文件路径 -export const ALOVA_TEMP_PATH = path.join('node_modules/.alova'); // 全局配置 setGlobalConfig({ - alovaTempPath: ALOVA_TEMP_PATH, log, getTypescript, Error diff --git a/tsconfig.json b/tsconfig.json index 01d31e4..0b32384 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -28,13 +28,5 @@ } }, "exclude": ["design/**", "test/**"], - "include": [ - "src/**/*.ts", - "./templates/index.ts", - "packages/**/*.ts", - "*.*js", - "*.*ts", - "scripts/**.*", - "typings/**/*.d.ts" - ] + "include": ["src/**/*.ts", "packages/**/*.ts", "*.*js", "*.*ts", "scripts/**.*", "typings/**/*.d.ts"] } From fcb2224151f6da942dd700e81354a6fc497b27c5 Mon Sep 17 00:00:00 2001 From: czhlin <2324133088@qq.com> Date: Thu, 5 Sep 2024 06:28:52 +0800 Subject: [PATCH 09/47] =?UTF-8?q?refactor(vscode-extension):=20=E5=B0=86vs?= =?UTF-8?q?code=E6=8F=92=E4=BB=B6=E7=A7=BB=E5=8A=A8=E5=88=B0packages?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E4=B8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 64 +------------- .../vscode-extension/.vscode-test.mjs | 0 .../vscode-extension/.vscode}/launch.json | 0 .../vscode-extension/.vscode}/tasks.json | 0 .../vscode-extension/.vscodeignore | 0 packages/vscode-extension/CHANGELOG.md | 9 ++ packages/vscode-extension/LICENSE | 21 +++++ packages/vscode-extension/README.md | 27 ++++++ .../vscode-extension/esbuild.ts | 0 packages/vscode-extension/package.json | 81 ++++++++++++++++++ .../vscode-extension/resources}/icon.png | Bin .../vscode-extension/resources}/logo.ttf | Bin .../src}/commands/autocomplete.ts | 0 .../src}/commands/createConfig.ts | 0 .../src}/commands/generateApi.ts | 0 .../vscode-extension/src}/commands/index.ts | 0 .../vscode-extension/src}/commands/refresh.ts | 0 .../vscode-extension/src}/commands/setup.ts | 0 .../src}/commands/showStatusBarIcon.ts | 0 .../src}/components/autocomplete.ts | 0 .../vscode-extension/src}/components/error.ts | 0 .../src}/components/message.ts | 0 .../src}/components/statusBar.ts | 0 .../vscode-extension/src}/extension.ts | 0 .../src}/functions/autocomplete.ts | 0 .../vscode-extension/src}/globalConfig.ts | 0 .../src}/helper/configuration.ts | 0 .../vscode-extension/src}/helper/work.ts | 0 .../vscode-extension/src}/utils/index.ts | 0 .../vscode-extension/src}/utils/work.ts | 0 .../vscode-extension/src}/work.ts | 0 .../vscode-extension/src}/work/config.ts | 0 .../vscode-extension/src}/work/generate.ts | 0 .../src}/work/generateConfig.ts | 0 .../vscode-extension/src}/work/getApis.ts | 0 .../vscode-extension/src}/work/readConfig.ts | 0 packages/vscode-extension/tsconfig.json | 10 +++ .../vscode-extension/typings}/index.d.ts | 0 .../vsc-extension-quickstart.md | 0 path.ts | 13 ++- tsconfig.json | 2 - 41 files changed, 156 insertions(+), 71 deletions(-) rename .vscode-test.mjs => packages/vscode-extension/.vscode-test.mjs (100%) rename {.vscode => packages/vscode-extension/.vscode}/launch.json (100%) rename {.vscode => packages/vscode-extension/.vscode}/tasks.json (100%) rename .vscodeignore => packages/vscode-extension/.vscodeignore (100%) create mode 100644 packages/vscode-extension/CHANGELOG.md create mode 100644 packages/vscode-extension/LICENSE create mode 100644 packages/vscode-extension/README.md rename esbuild.ts => packages/vscode-extension/esbuild.ts (100%) create mode 100644 packages/vscode-extension/package.json rename {resources => packages/vscode-extension/resources}/icon.png (100%) rename {resources => packages/vscode-extension/resources}/logo.ttf (100%) rename {src => packages/vscode-extension/src}/commands/autocomplete.ts (100%) rename {src => packages/vscode-extension/src}/commands/createConfig.ts (100%) rename {src => packages/vscode-extension/src}/commands/generateApi.ts (100%) rename {src => packages/vscode-extension/src}/commands/index.ts (100%) rename {src => packages/vscode-extension/src}/commands/refresh.ts (100%) rename {src => packages/vscode-extension/src}/commands/setup.ts (100%) rename {src => packages/vscode-extension/src}/commands/showStatusBarIcon.ts (100%) rename {src => packages/vscode-extension/src}/components/autocomplete.ts (100%) rename {src => packages/vscode-extension/src}/components/error.ts (100%) rename {src => packages/vscode-extension/src}/components/message.ts (100%) rename {src => packages/vscode-extension/src}/components/statusBar.ts (100%) rename {src => packages/vscode-extension/src}/extension.ts (100%) rename {src => packages/vscode-extension/src}/functions/autocomplete.ts (100%) rename {src => packages/vscode-extension/src}/globalConfig.ts (100%) rename {src => packages/vscode-extension/src}/helper/configuration.ts (100%) rename {src => packages/vscode-extension/src}/helper/work.ts (100%) rename {src => packages/vscode-extension/src}/utils/index.ts (100%) rename {src => packages/vscode-extension/src}/utils/work.ts (100%) rename {src => packages/vscode-extension/src}/work.ts (100%) rename {src => packages/vscode-extension/src}/work/config.ts (100%) rename {src => packages/vscode-extension/src}/work/generate.ts (100%) rename {src => packages/vscode-extension/src}/work/generateConfig.ts (100%) rename {src => packages/vscode-extension/src}/work/getApis.ts (100%) rename {src => packages/vscode-extension/src}/work/readConfig.ts (100%) create mode 100644 packages/vscode-extension/tsconfig.json rename {typings => packages/vscode-extension/typings}/index.d.ts (100%) rename vsc-extension-quickstart.md => packages/vscode-extension/vsc-extension-quickstart.md (100%) diff --git a/package.json b/package.json index cc7e44a..43b0d6e 100644 --- a/package.json +++ b/package.json @@ -1,70 +1,21 @@ { - "name": "alova-vscode-extension", + "name": "@alova/devtools", "displayName": "Alova", - "description": "The vscode extension for alova.js", + "description": "The devtools for alova.js", "version": "0.0.9", "engines": { - "vscode": "^1.89.0", "node": ">=18.19.0", "pnpm": ">=8.6.12" }, - "categories": [ - "Other" - ], - "activationEvents": [ - "workspaceContains:**/*.ts", - "workspaceContains:**/*.js" - ], - "main": "./out/extension.js", - "icon": "resources/icon.png", - "contributes": { - "commands": [ - { - "command": "alova.refresh", - "category": "alova", - "title": "alova refresh" - }, - { - "command": "alova.create.config", - "category": "alova", - "title": "create alova config" - } - ], - "icons": { - "alova-icon-id": { - "description": "alova icon", - "default": { - "fontPath": "./resources/logo.ttf", - "fontCharacter": "\\E900" - } - } - } - }, "scripts": { - "vscode:prepublish": "pnpm run package", - "compile": "pnpm run check-types && pnpm run lint:fix && tsx esbuild.ts", - "watch": "npm-run-all -p watch:*", - "watch:esbuild": "tsx esbuild.ts --watch", - "watch:tsc": "tsc --noEmit --watch --project tsconfig.json", - "package": "pnpm run check-types && pnpm run lint:fix && tsx esbuild.ts --production", - "compile-tests": "tsc -p . --outDir out", - "watch-tests": "tsc -p . -w --outDir out", - "pretest": "pnpm run compile-tests && pnpm run compile && pnpm run lint", - "check-types": "tsc --noEmit", "lint": "eslint . --ext .js,.ts", "lint:fix": "npm run lint -- --fix", "format": "prettier --check .", "format:fix": "prettier --write .", - "test": "vscode-test", "api-test": "tsx scripts/api-test.ts", "commit": "git-cz && git push", - "prepare": "husky && pnpm api-test", - "pack:pre": "vsce package --no-dependencies --pre-release", - "release:pre": "vsce publish --no-dependencies --pre-release", - "pack": "vsce package --no-dependencies", - "release": "vsce publish --no-dependencies" + "prepare": "husky && pnpm api-test" }, - "publisher": "Alova", "license": "MIT", "repository": { "type": "git", @@ -84,21 +35,14 @@ "@types/js-yaml": "^4.0.9", "@types/lodash": "^4.17.5", "@types/mocha": "^10.0.6", - "@types/mustache": "^4.2.5", "@types/node": "18.x", "@types/node-fetch": "^2.6.11", "@types/serialize-javascript": "^5.0.4", "@types/swagger2openapi": "^7.0.4", - "@types/vscode": "^1.89.0", "@typescript-eslint/eslint-plugin": "^7.13.0", "@typescript-eslint/parser": "^7.13.0", - "@vscode/test-cli": "^0.0.9", - "@vscode/test-electron": "^2.3.9", - "@vscode/vsce": "^2.29.0", "commitizen": "^4.3.0", "cz-conventional-changelog": "^3.3.0", - "esbuild": "^0.23.0", - "esbuild-plugin-alias": "^0.2.1", "eslint": "^8.57.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^18.0.0", @@ -121,14 +65,12 @@ } }, "dependencies": { - "chokidar": "^3.6.0", "cosmiconfig": "^9.0.0", "handlebars": "^4.7.8", "import-fresh": "^3.3.0", "lodash": "^4.17.21", "node-fetch": "^2.7.0", "openapi-types": "^12.1.3", - "serialize-javascript": "^6.0.2", "swagger2openapi": "^7.0.8" } } diff --git a/.vscode-test.mjs b/packages/vscode-extension/.vscode-test.mjs similarity index 100% rename from .vscode-test.mjs rename to packages/vscode-extension/.vscode-test.mjs diff --git a/.vscode/launch.json b/packages/vscode-extension/.vscode/launch.json similarity index 100% rename from .vscode/launch.json rename to packages/vscode-extension/.vscode/launch.json diff --git a/.vscode/tasks.json b/packages/vscode-extension/.vscode/tasks.json similarity index 100% rename from .vscode/tasks.json rename to packages/vscode-extension/.vscode/tasks.json diff --git a/.vscodeignore b/packages/vscode-extension/.vscodeignore similarity index 100% rename from .vscodeignore rename to packages/vscode-extension/.vscodeignore diff --git a/packages/vscode-extension/CHANGELOG.md b/packages/vscode-extension/CHANGELOG.md new file mode 100644 index 0000000..096404d --- /dev/null +++ b/packages/vscode-extension/CHANGELOG.md @@ -0,0 +1,9 @@ +# Change Log + +All notable changes to the "helloworld" extension will be documented in this file. + +Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. + +## [Unreleased] + +- Initial release diff --git a/packages/vscode-extension/LICENSE b/packages/vscode-extension/LICENSE new file mode 100644 index 0000000..c602816 --- /dev/null +++ b/packages/vscode-extension/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 alovajs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/vscode-extension/README.md b/packages/vscode-extension/README.md new file mode 100644 index 0000000..f28bcb8 --- /dev/null +++ b/packages/vscode-extension/README.md @@ -0,0 +1,27 @@ +# VSCode extension for alova + +## features + +1. Automatically generate request code and response data types, and experience IntelliSense for response in js projects. +2. Embed API documents in the code to experience the effect of checking and using APIs. +3. Update APIs regularly and actively notify front-end developers, no longer relying on server-side developers to notify. + +> [Detailed documentation](https://alova.js.org/tutorial/getting-started/extension-integration). + +## View API completed information + +You can view the complted API information in the Editor with the IntelliSense feature. + +![](https://alova.js.org/img/vscode-api-doc.png) + +## Quick access to API + +Using the trigger word `a->` to trigger apis quick positioning. + +### Search by url + +![](https://alova.js.org/img/vscode-query-with-url.png) + +### Search by description + +![](https://alova.js.org/img/vscode-query-with-description.png) diff --git a/esbuild.ts b/packages/vscode-extension/esbuild.ts similarity index 100% rename from esbuild.ts rename to packages/vscode-extension/esbuild.ts diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json new file mode 100644 index 0000000..821fd49 --- /dev/null +++ b/packages/vscode-extension/package.json @@ -0,0 +1,81 @@ +{ + "name": "alova-vscode-extension", + "displayName": "Alova", + "description": "The vscode extension for alova.js", + "version": "0.0.9", + "engines": { + "vscode": "^1.89.0", + "node": ">=18.19.0", + "pnpm": ">=8.6.12" + }, + "categories": [ + "Other" + ], + "activationEvents": [ + "workspaceContains:**/*.ts", + "workspaceContains:**/*.js" + ], + "main": "./out/extension.js", + "icon": "resources/icon.png", + "contributes": { + "commands": [ + { + "command": "alova.refresh", + "category": "alova", + "title": "alova refresh" + }, + { + "command": "alova.create.config", + "category": "alova", + "title": "create alova config" + } + ], + "icons": { + "alova-icon-id": { + "description": "alova icon", + "default": { + "fontPath": "./resources/logo.ttf", + "fontCharacter": "\\E900" + } + } + } + }, + "scripts": { + "vscode:prepublish": "pnpm run package", + "compile": "pnpm run check-types && pnpm run lint:fix && tsx esbuild.ts", + "watch": "npm-run-all -p watch:*", + "watch:esbuild": "tsx esbuild.ts --watch", + "watch:tsc": "tsc --noEmit --watch --project tsconfig.json", + "package": "pnpm run check-types && pnpm run lint:fix && tsx esbuild.ts --production", + "compile-tests": "tsc -p . --outDir out", + "watch-tests": "tsc -p . -w --outDir out", + "pretest": "pnpm run compile-tests && pnpm run compile && pnpm run lint", + "check-types": "tsc --noEmit", + "lint": "eslint . --ext .js,.ts", + "lint:fix": "npm run lint -- --fix", + "format": "prettier --check .", + "format:fix": "prettier --write .", + "test": "vscode-test", + "pack:pre": "vsce package --no-dependencies --pre-release", + "release:pre": "vsce publish --no-dependencies --pre-release", + "pack": "vsce package --no-dependencies", + "release": "vsce publish --no-dependencies" + }, + "publisher": "Alova", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/alovajs/devtools.git" + }, + "bugs": { + "url": "https://github.com/alovajs/devtools/issues" + }, + "devDependencies": { + "@types/vscode": "^1.89.0", + "@vscode/test-cli": "^0.0.9", + "@vscode/test-electron": "^2.3.9", + "@vscode/vsce": "^2.29.0", + "esbuild": "^0.23.0", + "esbuild-plugin-alias": "^0.2.1" + } +} diff --git a/resources/icon.png b/packages/vscode-extension/resources/icon.png similarity index 100% rename from resources/icon.png rename to packages/vscode-extension/resources/icon.png diff --git a/resources/logo.ttf b/packages/vscode-extension/resources/logo.ttf similarity index 100% rename from resources/logo.ttf rename to packages/vscode-extension/resources/logo.ttf diff --git a/src/commands/autocomplete.ts b/packages/vscode-extension/src/commands/autocomplete.ts similarity index 100% rename from src/commands/autocomplete.ts rename to packages/vscode-extension/src/commands/autocomplete.ts diff --git a/src/commands/createConfig.ts b/packages/vscode-extension/src/commands/createConfig.ts similarity index 100% rename from src/commands/createConfig.ts rename to packages/vscode-extension/src/commands/createConfig.ts diff --git a/src/commands/generateApi.ts b/packages/vscode-extension/src/commands/generateApi.ts similarity index 100% rename from src/commands/generateApi.ts rename to packages/vscode-extension/src/commands/generateApi.ts diff --git a/src/commands/index.ts b/packages/vscode-extension/src/commands/index.ts similarity index 100% rename from src/commands/index.ts rename to packages/vscode-extension/src/commands/index.ts diff --git a/src/commands/refresh.ts b/packages/vscode-extension/src/commands/refresh.ts similarity index 100% rename from src/commands/refresh.ts rename to packages/vscode-extension/src/commands/refresh.ts diff --git a/src/commands/setup.ts b/packages/vscode-extension/src/commands/setup.ts similarity index 100% rename from src/commands/setup.ts rename to packages/vscode-extension/src/commands/setup.ts diff --git a/src/commands/showStatusBarIcon.ts b/packages/vscode-extension/src/commands/showStatusBarIcon.ts similarity index 100% rename from src/commands/showStatusBarIcon.ts rename to packages/vscode-extension/src/commands/showStatusBarIcon.ts diff --git a/src/components/autocomplete.ts b/packages/vscode-extension/src/components/autocomplete.ts similarity index 100% rename from src/components/autocomplete.ts rename to packages/vscode-extension/src/components/autocomplete.ts diff --git a/src/components/error.ts b/packages/vscode-extension/src/components/error.ts similarity index 100% rename from src/components/error.ts rename to packages/vscode-extension/src/components/error.ts diff --git a/src/components/message.ts b/packages/vscode-extension/src/components/message.ts similarity index 100% rename from src/components/message.ts rename to packages/vscode-extension/src/components/message.ts diff --git a/src/components/statusBar.ts b/packages/vscode-extension/src/components/statusBar.ts similarity index 100% rename from src/components/statusBar.ts rename to packages/vscode-extension/src/components/statusBar.ts diff --git a/src/extension.ts b/packages/vscode-extension/src/extension.ts similarity index 100% rename from src/extension.ts rename to packages/vscode-extension/src/extension.ts diff --git a/src/functions/autocomplete.ts b/packages/vscode-extension/src/functions/autocomplete.ts similarity index 100% rename from src/functions/autocomplete.ts rename to packages/vscode-extension/src/functions/autocomplete.ts diff --git a/src/globalConfig.ts b/packages/vscode-extension/src/globalConfig.ts similarity index 100% rename from src/globalConfig.ts rename to packages/vscode-extension/src/globalConfig.ts diff --git a/src/helper/configuration.ts b/packages/vscode-extension/src/helper/configuration.ts similarity index 100% rename from src/helper/configuration.ts rename to packages/vscode-extension/src/helper/configuration.ts diff --git a/src/helper/work.ts b/packages/vscode-extension/src/helper/work.ts similarity index 100% rename from src/helper/work.ts rename to packages/vscode-extension/src/helper/work.ts diff --git a/src/utils/index.ts b/packages/vscode-extension/src/utils/index.ts similarity index 100% rename from src/utils/index.ts rename to packages/vscode-extension/src/utils/index.ts diff --git a/src/utils/work.ts b/packages/vscode-extension/src/utils/work.ts similarity index 100% rename from src/utils/work.ts rename to packages/vscode-extension/src/utils/work.ts diff --git a/src/work.ts b/packages/vscode-extension/src/work.ts similarity index 100% rename from src/work.ts rename to packages/vscode-extension/src/work.ts diff --git a/src/work/config.ts b/packages/vscode-extension/src/work/config.ts similarity index 100% rename from src/work/config.ts rename to packages/vscode-extension/src/work/config.ts diff --git a/src/work/generate.ts b/packages/vscode-extension/src/work/generate.ts similarity index 100% rename from src/work/generate.ts rename to packages/vscode-extension/src/work/generate.ts diff --git a/src/work/generateConfig.ts b/packages/vscode-extension/src/work/generateConfig.ts similarity index 100% rename from src/work/generateConfig.ts rename to packages/vscode-extension/src/work/generateConfig.ts diff --git a/src/work/getApis.ts b/packages/vscode-extension/src/work/getApis.ts similarity index 100% rename from src/work/getApis.ts rename to packages/vscode-extension/src/work/getApis.ts diff --git a/src/work/readConfig.ts b/packages/vscode-extension/src/work/readConfig.ts similarity index 100% rename from src/work/readConfig.ts rename to packages/vscode-extension/src/work/readConfig.ts diff --git a/packages/vscode-extension/tsconfig.json b/packages/vscode-extension/tsconfig.json new file mode 100644 index 0000000..d84a9f1 --- /dev/null +++ b/packages/vscode-extension/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "paths": { + "~/*": ["./typings/*"], + "@/*": ["./src/*"], + "#/*": ["../../*"] + } + } +} diff --git a/typings/index.d.ts b/packages/vscode-extension/typings/index.d.ts similarity index 100% rename from typings/index.d.ts rename to packages/vscode-extension/typings/index.d.ts diff --git a/vsc-extension-quickstart.md b/packages/vscode-extension/vsc-extension-quickstart.md similarity index 100% rename from vsc-extension-quickstart.md rename to packages/vscode-extension/vsc-extension-quickstart.md diff --git a/path.ts b/path.ts index 5bedd46..2ba75f0 100644 --- a/path.ts +++ b/path.ts @@ -1,13 +1,10 @@ import { resolve } from 'node:path'; -/** - * 代码根目录 - */ -export const srcPath = resolve(__dirname, './src'); -/** - * 资源根目录 - */ -export const resourcesPath = resolve(__dirname, './resources'); + /** * 项目根目录 */ export const projectPath = resolve(__dirname, '.'); + +export default { + projectPath +}; diff --git a/tsconfig.json b/tsconfig.json index 0b32384..8356af3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -21,8 +21,6 @@ "strictNullChecks": true, "allowJs": true, "paths": { - "~/*": ["./typings/*"], - "@/*": ["./src/*"], "#/*": ["./*"], "@alova/*": ["./packages/*"] } From 97a42d01c468c8c97fe34492760b8ab925937e03 Mon Sep 17 00:00:00 2001 From: czhlin <2324133088@qq.com> Date: Thu, 5 Sep 2024 07:55:27 +0800 Subject: [PATCH 10/47] =?UTF-8?q?fix:=20alova.config=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E5=8C=BA=E5=88=86=E9=A1=B9=E7=9B=AE=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/templates/alova.config.handlebars | 12 ++++++++---- packages/wormhole/src/createConfig.ts | 3 ++- packages/wormhole/src/functions/alovaJson.ts | 7 ++++++- packages/wormhole/src/functions/generateApi.ts | 2 ++ packages/wormhole/src/functions/openApi2Data.ts | 6 ++++-- packages/wormhole/src/readConfig.ts | 10 ++++++---- packages/wormhole/src/utils/index.ts | 2 +- 7 files changed, 29 insertions(+), 13 deletions(-) diff --git a/packages/templates/alova.config.handlebars b/packages/templates/alova.config.handlebars index 6bdbffc..433265f 100644 --- a/packages/templates/alova.config.handlebars +++ b/packages/templates/alova.config.handlebars @@ -1,8 +1,12 @@ -import type { Config } from '@alova/wormhole'; +{{#if (eq type "typescript")}}import type { Config } from '@alova/wormhole'; -// For more config detailed visit: + +{{/if}}// For more config detailed visit: // https://alova.js.org/tutorial/getting-started/extension-integration -export default { +{{#if (not type "typescript")}}/** + * @type {{#raw "{ " }}{{/raw}}import('@alova/wormhole').Config{{#raw " }" }}{{/raw}} + */{{/if}} + {{#if (eq moduleType "ESModule")}}export default {{#if (eq type "typescript")}}{{/if}}{{else if (eq moduleType "commonJs")}}module.exports ={{/if}}{{#raw "{ " }}{{/raw}} generator: [ { /** @@ -64,4 +68,4 @@ export default { * whether to automatically update the interface, enabled by default, check every 5 minutes, closed when set to `false` */ // autoUpdate: true -}; \ No newline at end of file +{{#raw "};" }}{{/raw}} \ No newline at end of file diff --git a/packages/wormhole/src/createConfig.ts b/packages/wormhole/src/createConfig.ts index 7de3c54..0ad5e56 100644 --- a/packages/wormhole/src/createConfig.ts +++ b/packages/wormhole/src/createConfig.ts @@ -4,9 +4,10 @@ import TemplateFile from './modules/TemplateFile'; export const createConfig = async (projectPath: string = process.cwd()) => { const type = getAutoTemplateType(projectPath); + const moduleType = TemplateFile.getModuleType(type); const alovaVersion: AlovaVersion = getAlovaVersion(projectPath); const templateFile = new TemplateFile(type, alovaVersion); - return templateFile.outputFile({}, 'alova.config', projectPath, { + return templateFile.outputFile({ type, moduleType }, 'alova.config', projectPath, { root: true, hasVersion: false }); diff --git a/packages/wormhole/src/functions/alovaJson.ts b/packages/wormhole/src/functions/alovaJson.ts index 4a2430a..cdeddfb 100644 --- a/packages/wormhole/src/functions/alovaJson.ts +++ b/packages/wormhole/src/functions/alovaJson.ts @@ -6,7 +6,12 @@ import type { TemplateData } from './openApi2Data'; export const writeAlovaJson = async (data: TemplateData, originPath: string, name = 'api.json') => { // 将数据转换为 JSON 字符串 - const jsonData = await format(JSON.stringify(data, null, 2), { parser: 'json' }); + let jsonData = ''; + try { + jsonData = await format(JSON.stringify(data, null, 2), { parser: 'json' }); + } catch (error) { + console.log(error, 13); + } // 定义 JSON 文件的路径和名称 const filePath = `${originPath}_${name}`; const dirPath = filePath.split(/\/|\\/).slice(0, -1).join('/'); diff --git a/packages/wormhole/src/functions/generateApi.ts b/packages/wormhole/src/functions/generateApi.ts index 8ce2299..952745f 100644 --- a/packages/wormhole/src/functions/generateApi.ts +++ b/packages/wormhole/src/functions/generateApi.ts @@ -42,6 +42,8 @@ export default async function ( }); // 模块类型 templateData.moduleType = TemplateFile.getModuleType(type); + // 模板类型 + templateData.type = type; // alova版本 templateData.alovaVersion = alovaVersion; // 是否需要生成api文件 diff --git a/packages/wormhole/src/functions/openApi2Data.ts b/packages/wormhole/src/functions/openApi2Data.ts index f2f49e2..f486307 100644 --- a/packages/wormhole/src/functions/openApi2Data.ts +++ b/packages/wormhole/src/functions/openApi2Data.ts @@ -1,6 +1,6 @@ import { cloneDeep } from 'lodash'; import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'; -import type { ApiDescriptor, GeneratorConfig } from '..'; +import type { ApiDescriptor, GeneratorConfig, TemplateType } from '..'; import { DEFAULT_CONFIG } from '../config'; import { findBy$ref, getStandardRefName, isReferenceObject, mergeObject, removeAll$ref } from '../helper/openapi'; import { convertToType, jsonSchema2TsStr } from '../helper/schema2type'; @@ -72,6 +72,7 @@ export interface TemplateData extends Omit { alovaVersion: AlovaVersion; commentText: string; useImportType: boolean; + type: TemplateType; } const remove$ref = ( originObj: OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject, @@ -360,7 +361,8 @@ export default async function openApi2Data( schemas: [], alovaVersion: 'v2', global: config.global ?? 'Apis', - useImportType: config?.useImportType ?? false + useImportType: config?.useImportType ?? false, + type: 'module' }; const schemasMap = new Map(); const searchMap = new Map(); diff --git a/packages/wormhole/src/readConfig.ts b/packages/wormhole/src/readConfig.ts index 60d22a6..65355b3 100644 --- a/packages/wormhole/src/readConfig.ts +++ b/packages/wormhole/src/readConfig.ts @@ -35,10 +35,12 @@ export const readAndSaveAlovaJson = (config: Config, projectPath: string = proce configuration.getAllOutputPath().forEach(outputPath => { // 缓存文件地址 const alovaJsonPath = getAlovaJsonPath(projectPath, outputPath); - readAlovaJson(alovaJsonPath).then(data => { - // 保存templateData - DEFAULT_CONFIG.templateData.set(alovaJsonPath, data); - }); + readAlovaJson(alovaJsonPath) + .then(data => { + // 保存templateData + DEFAULT_CONFIG.templateData.set(alovaJsonPath, data); + }) + .catch(() => {}); }); }; export default readConfig; diff --git a/packages/wormhole/src/utils/index.ts b/packages/wormhole/src/utils/index.ts index 1b54b7f..f2001d0 100644 --- a/packages/wormhole/src/utils/index.ts +++ b/packages/wormhole/src/utils/index.ts @@ -41,6 +41,7 @@ handlebars.registerHelper('or', function (this: any, ...rest) { return result ? options.fn(this) : options.inverse(this); }); handlebars.registerHelper('eq', (a, b) => a === b); +handlebars.registerHelper('not', (a, b) => a !== b); // 注册自定义助手函数 'raw' handlebars.registerHelper( 'raw', @@ -62,7 +63,6 @@ export async function readAndRenderTemplate(templatePath: string, view: any): Pr const importFn = (await import('@alova/templates')).default; data = (await (importFn as any)(templatePath)).default; } - return handlebars.compile(data)(view); } export async function format(text: string, config?: PrettierConfig) { From 81bdf5ba73aae3f8eda2cb937735c862abbeb4cb Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Thu, 5 Sep 2024 10:53:04 +0800 Subject: [PATCH 11/47] =?UTF-8?q?fix(templates):=20=E4=BF=AE=E5=A4=8Dcreat?= =?UTF-8?q?eApis=E6=A8=A1=E6=9D=BF=E4=B8=AD=E9=94=99=E8=AF=AF=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/templates/commonjs/createApis.handlebars | 2 +- packages/templates/commonjs/v3-createApis.handlebars | 2 +- packages/templates/module/createApis.handlebars | 2 +- packages/templates/module/v3-createApis.handlebars | 2 +- packages/templates/typescript/createApis.handlebars | 2 +- packages/templates/typescript/v3-createApis.handlebars | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/templates/commonjs/createApis.handlebars b/packages/templates/commonjs/createApis.handlebars index 7d67382..012049b 100644 --- a/packages/templates/commonjs/createApis.handlebars +++ b/packages/templates/commonjs/createApis.handlebars @@ -21,7 +21,7 @@ const createFunctionalProxy = (array, alovaInstance, configMap) => { const apiPathKey = array.join('.'); const apiItem = apiDefinitions[apiPathKey]; if (!apiItem) { - throw new Error(`the api path of \`${apiItem}\` is not found`); + throw new Error(`the api path of \`${apiPathKey}\` is not found`); } const mergedConfig = { ...configMap[apiPathKey], diff --git a/packages/templates/commonjs/v3-createApis.handlebars b/packages/templates/commonjs/v3-createApis.handlebars index c0a569b..e71dc5f 100644 --- a/packages/templates/commonjs/v3-createApis.handlebars +++ b/packages/templates/commonjs/v3-createApis.handlebars @@ -24,7 +24,7 @@ const createFunctionalProxy = (array, alovaInstance, configMap) => { const apiPathKey = array.join('.'); const apiItem = apiDefinitions[apiPathKey]; if (!apiItem) { - throw new Error(`the api path of \`${apiItem}\` is not found`); + throw new Error(`the api path of \`${apiPathKey}\` is not found`); } const mergedConfig = { ...configMap[apiPathKey], diff --git a/packages/templates/module/createApis.handlebars b/packages/templates/module/createApis.handlebars index b75d437..ad7ee77 100644 --- a/packages/templates/module/createApis.handlebars +++ b/packages/templates/module/createApis.handlebars @@ -21,7 +21,7 @@ const createFunctionalProxy = (array, alovaInstance, configMap) => { const apiPathKey = array.join('.'); const apiItem = apiDefinitions[apiPathKey]; if (!apiItem) { - throw new Error(`the api path of \`${apiItem}\` is not found`); + throw new Error(`the api path of \`${apiPathKey}\` is not found`); } const mergedConfig = { ...configMap[apiPathKey], diff --git a/packages/templates/module/v3-createApis.handlebars b/packages/templates/module/v3-createApis.handlebars index 4a2ed19..fe9d5be 100644 --- a/packages/templates/module/v3-createApis.handlebars +++ b/packages/templates/module/v3-createApis.handlebars @@ -24,7 +24,7 @@ const createFunctionalProxy = (array, alovaInstance, configMap) => { const apiPathKey = array.join('.'); const apiItem = apiDefinitions[apiPathKey]; if (!apiItem) { - throw new Error(`the api path of \`${apiItem}\` is not found`); + throw new Error(`the api path of \`${apiPathKey}\` is not found`); } const mergedConfig = { ...configMap[apiPathKey], diff --git a/packages/templates/typescript/createApis.handlebars b/packages/templates/typescript/createApis.handlebars index 9f1005d..d8e0b4c 100644 --- a/packages/templates/typescript/createApis.handlebars +++ b/packages/templates/typescript/createApis.handlebars @@ -20,7 +20,7 @@ const createFunctionalProxy = ( const apiPathKey = array.join('.') as keyof typeof apiDefinitions; const apiItem = apiDefinitions[apiPathKey]; if (!apiItem) { - throw new Error(`the api path of \`${apiItem}\` is not found`); + throw new Error(`the api path of \`${apiPathKey}\` is not found`); } const mergedConfig = { ...configMap[apiPathKey], diff --git a/packages/templates/typescript/v3-createApis.handlebars b/packages/templates/typescript/v3-createApis.handlebars index fb15eb1..42bdaa1 100644 --- a/packages/templates/typescript/v3-createApis.handlebars +++ b/packages/templates/typescript/v3-createApis.handlebars @@ -25,7 +25,7 @@ const createFunctionalProxy = ( const apiPathKey = array.join('.') as keyof typeof apiDefinitions; const apiItem = apiDefinitions[apiPathKey]; if (!apiItem) { - throw new Error(`the api path of \`${apiItem}\` is not found`); + throw new Error(`the api path of \`${apiPathKey}\` is not found`); } const mergedConfig = { ...configMap[apiPathKey], From aedc51ba808aa3747eaa16899e122eb9a0bdd11d Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Thu, 5 Sep 2024 11:57:02 +0800 Subject: [PATCH 12/47] =?UTF-8?q?chore:=20=E5=90=88=E5=B9=B6release=20v0.0?= =?UTF-8?q?.10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.cjs | 2 +- .gitignore | 1 - .../pnpm-lock.yaml | 217 + design/v2/api-design-js-global/pnpm-lock.yaml | 217 + design/v2/api-design-ts-global/pnpm-lock.yaml | 217 + .../pnpm-lock.yaml | 217 + design/v3/api-design-js-global/pnpm-lock.yaml | 217 + design/v3/api-design-ts-global/pnpm-lock.yaml | 217 + packages/vscode-extension/package.json | 12 +- packages/vscode-extension/resources/icon.png | Bin 33114 -> 123560 bytes .../src/components/statusBar.ts | 4 +- pnpm-lock.yaml | 7379 +++++++++++++++++ prettier.config.cjs | 2 +- 13 files changed, 8691 insertions(+), 11 deletions(-) create mode 100644 design/v2/api-design-js-global-commonjs/pnpm-lock.yaml create mode 100644 design/v2/api-design-js-global/pnpm-lock.yaml create mode 100644 design/v2/api-design-ts-global/pnpm-lock.yaml create mode 100644 design/v3/api-design-js-global-commonjs/pnpm-lock.yaml create mode 100644 design/v3/api-design-js-global/pnpm-lock.yaml create mode 100644 design/v3/api-design-ts-global/pnpm-lock.yaml create mode 100644 pnpm-lock.yaml diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 64e50ff..5be93a5 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -27,7 +27,7 @@ module.exports = { 'no-multi-assign': 'off', 'consistent-return': 'off', 'no-restricted-exports': 'off', - 'linebreak-style': ['error', 'unix'], + 'linebreak-style': 'off', 'no-unused-vars': 'off', 'import/order': 'off', 'import/no-relative-packages': 'off', diff --git a/.gitignore b/.gitignore index ec8e924..e818157 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ .spago bower_components node_modules -pnpm-lock.yaml # Generated files .psci diff --git a/design/v2/api-design-js-global-commonjs/pnpm-lock.yaml b/design/v2/api-design-js-global-commonjs/pnpm-lock.yaml new file mode 100644 index 0000000..2531579 --- /dev/null +++ b/design/v2/api-design-js-global-commonjs/pnpm-lock.yaml @@ -0,0 +1,217 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + alova: + specifier: ^2.20.5 + version: 2.20.5 + vue: + specifier: ^3.4.27 + version: 3.4.27 + +packages: + + '@babel/helper-string-parser@7.24.6': + resolution: {integrity: sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.24.6': + resolution: {integrity: sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.24.6': + resolution: {integrity: sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.24.6': + resolution: {integrity: sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==} + engines: {node: '>=6.9.0'} + + '@jridgewell/sourcemap-codec@1.4.15': + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + '@vue/compiler-core@3.4.27': + resolution: {integrity: sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==} + + '@vue/compiler-dom@3.4.27': + resolution: {integrity: sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==} + + '@vue/compiler-sfc@3.4.27': + resolution: {integrity: sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==} + + '@vue/compiler-ssr@3.4.27': + resolution: {integrity: sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==} + + '@vue/reactivity@3.4.27': + resolution: {integrity: sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==} + + '@vue/runtime-core@3.4.27': + resolution: {integrity: sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==} + + '@vue/runtime-dom@3.4.27': + resolution: {integrity: sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==} + + '@vue/server-renderer@3.4.27': + resolution: {integrity: sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==} + peerDependencies: + vue: 3.4.27 + + '@vue/shared@3.4.27': + resolution: {integrity: sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==} + + alova@2.20.5: + resolution: {integrity: sha512-hIIPGQCDajcU5NxDQykUOiwlFa1d2sEK7R9EET6pOtCoGdmw7bqjsDZT9gO0rhb42V7FDyMO9bOdazqNMKQvqg==} + engines: {node: '>= 0.12.0'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + + postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + engines: {node: ^10 || ^12 || >=14} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + vue@3.4.27: + resolution: {integrity: sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + +snapshots: + + '@babel/helper-string-parser@7.24.6': {} + + '@babel/helper-validator-identifier@7.24.6': {} + + '@babel/parser@7.24.6': + dependencies: + '@babel/types': 7.24.6 + + '@babel/types@7.24.6': + dependencies: + '@babel/helper-string-parser': 7.24.6 + '@babel/helper-validator-identifier': 7.24.6 + to-fast-properties: 2.0.0 + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@vue/compiler-core@3.4.27': + dependencies: + '@babel/parser': 7.24.6 + '@vue/shared': 3.4.27 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.0 + + '@vue/compiler-dom@3.4.27': + dependencies: + '@vue/compiler-core': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/compiler-sfc@3.4.27': + dependencies: + '@babel/parser': 7.24.6 + '@vue/compiler-core': 3.4.27 + '@vue/compiler-dom': 3.4.27 + '@vue/compiler-ssr': 3.4.27 + '@vue/shared': 3.4.27 + estree-walker: 2.0.2 + magic-string: 0.30.10 + postcss: 8.4.38 + source-map-js: 1.2.0 + + '@vue/compiler-ssr@3.4.27': + dependencies: + '@vue/compiler-dom': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/reactivity@3.4.27': + dependencies: + '@vue/shared': 3.4.27 + + '@vue/runtime-core@3.4.27': + dependencies: + '@vue/reactivity': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/runtime-dom@3.4.27': + dependencies: + '@vue/runtime-core': 3.4.27 + '@vue/shared': 3.4.27 + csstype: 3.1.3 + + '@vue/server-renderer@3.4.27(vue@3.4.27)': + dependencies: + '@vue/compiler-ssr': 3.4.27 + '@vue/shared': 3.4.27 + vue: 3.4.27 + + '@vue/shared@3.4.27': {} + + alova@2.20.5: {} + + csstype@3.1.3: {} + + entities@4.5.0: {} + + estree-walker@2.0.2: {} + + magic-string@0.30.10: + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + + nanoid@3.3.7: {} + + picocolors@1.0.1: {} + + postcss@8.4.38: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + + source-map-js@1.2.0: {} + + to-fast-properties@2.0.0: {} + + vue@3.4.27: + dependencies: + '@vue/compiler-dom': 3.4.27 + '@vue/compiler-sfc': 3.4.27 + '@vue/runtime-dom': 3.4.27 + '@vue/server-renderer': 3.4.27(vue@3.4.27) + '@vue/shared': 3.4.27 \ No newline at end of file diff --git a/design/v2/api-design-js-global/pnpm-lock.yaml b/design/v2/api-design-js-global/pnpm-lock.yaml new file mode 100644 index 0000000..2531579 --- /dev/null +++ b/design/v2/api-design-js-global/pnpm-lock.yaml @@ -0,0 +1,217 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + alova: + specifier: ^2.20.5 + version: 2.20.5 + vue: + specifier: ^3.4.27 + version: 3.4.27 + +packages: + + '@babel/helper-string-parser@7.24.6': + resolution: {integrity: sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.24.6': + resolution: {integrity: sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.24.6': + resolution: {integrity: sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.24.6': + resolution: {integrity: sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==} + engines: {node: '>=6.9.0'} + + '@jridgewell/sourcemap-codec@1.4.15': + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + '@vue/compiler-core@3.4.27': + resolution: {integrity: sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==} + + '@vue/compiler-dom@3.4.27': + resolution: {integrity: sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==} + + '@vue/compiler-sfc@3.4.27': + resolution: {integrity: sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==} + + '@vue/compiler-ssr@3.4.27': + resolution: {integrity: sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==} + + '@vue/reactivity@3.4.27': + resolution: {integrity: sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==} + + '@vue/runtime-core@3.4.27': + resolution: {integrity: sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==} + + '@vue/runtime-dom@3.4.27': + resolution: {integrity: sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==} + + '@vue/server-renderer@3.4.27': + resolution: {integrity: sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==} + peerDependencies: + vue: 3.4.27 + + '@vue/shared@3.4.27': + resolution: {integrity: sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==} + + alova@2.20.5: + resolution: {integrity: sha512-hIIPGQCDajcU5NxDQykUOiwlFa1d2sEK7R9EET6pOtCoGdmw7bqjsDZT9gO0rhb42V7FDyMO9bOdazqNMKQvqg==} + engines: {node: '>= 0.12.0'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + + postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + engines: {node: ^10 || ^12 || >=14} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + vue@3.4.27: + resolution: {integrity: sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + +snapshots: + + '@babel/helper-string-parser@7.24.6': {} + + '@babel/helper-validator-identifier@7.24.6': {} + + '@babel/parser@7.24.6': + dependencies: + '@babel/types': 7.24.6 + + '@babel/types@7.24.6': + dependencies: + '@babel/helper-string-parser': 7.24.6 + '@babel/helper-validator-identifier': 7.24.6 + to-fast-properties: 2.0.0 + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@vue/compiler-core@3.4.27': + dependencies: + '@babel/parser': 7.24.6 + '@vue/shared': 3.4.27 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.0 + + '@vue/compiler-dom@3.4.27': + dependencies: + '@vue/compiler-core': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/compiler-sfc@3.4.27': + dependencies: + '@babel/parser': 7.24.6 + '@vue/compiler-core': 3.4.27 + '@vue/compiler-dom': 3.4.27 + '@vue/compiler-ssr': 3.4.27 + '@vue/shared': 3.4.27 + estree-walker: 2.0.2 + magic-string: 0.30.10 + postcss: 8.4.38 + source-map-js: 1.2.0 + + '@vue/compiler-ssr@3.4.27': + dependencies: + '@vue/compiler-dom': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/reactivity@3.4.27': + dependencies: + '@vue/shared': 3.4.27 + + '@vue/runtime-core@3.4.27': + dependencies: + '@vue/reactivity': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/runtime-dom@3.4.27': + dependencies: + '@vue/runtime-core': 3.4.27 + '@vue/shared': 3.4.27 + csstype: 3.1.3 + + '@vue/server-renderer@3.4.27(vue@3.4.27)': + dependencies: + '@vue/compiler-ssr': 3.4.27 + '@vue/shared': 3.4.27 + vue: 3.4.27 + + '@vue/shared@3.4.27': {} + + alova@2.20.5: {} + + csstype@3.1.3: {} + + entities@4.5.0: {} + + estree-walker@2.0.2: {} + + magic-string@0.30.10: + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + + nanoid@3.3.7: {} + + picocolors@1.0.1: {} + + postcss@8.4.38: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + + source-map-js@1.2.0: {} + + to-fast-properties@2.0.0: {} + + vue@3.4.27: + dependencies: + '@vue/compiler-dom': 3.4.27 + '@vue/compiler-sfc': 3.4.27 + '@vue/runtime-dom': 3.4.27 + '@vue/server-renderer': 3.4.27(vue@3.4.27) + '@vue/shared': 3.4.27 \ No newline at end of file diff --git a/design/v2/api-design-ts-global/pnpm-lock.yaml b/design/v2/api-design-ts-global/pnpm-lock.yaml new file mode 100644 index 0000000..2531579 --- /dev/null +++ b/design/v2/api-design-ts-global/pnpm-lock.yaml @@ -0,0 +1,217 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + alova: + specifier: ^2.20.5 + version: 2.20.5 + vue: + specifier: ^3.4.27 + version: 3.4.27 + +packages: + + '@babel/helper-string-parser@7.24.6': + resolution: {integrity: sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.24.6': + resolution: {integrity: sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.24.6': + resolution: {integrity: sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.24.6': + resolution: {integrity: sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==} + engines: {node: '>=6.9.0'} + + '@jridgewell/sourcemap-codec@1.4.15': + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + '@vue/compiler-core@3.4.27': + resolution: {integrity: sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==} + + '@vue/compiler-dom@3.4.27': + resolution: {integrity: sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==} + + '@vue/compiler-sfc@3.4.27': + resolution: {integrity: sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==} + + '@vue/compiler-ssr@3.4.27': + resolution: {integrity: sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==} + + '@vue/reactivity@3.4.27': + resolution: {integrity: sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==} + + '@vue/runtime-core@3.4.27': + resolution: {integrity: sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==} + + '@vue/runtime-dom@3.4.27': + resolution: {integrity: sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==} + + '@vue/server-renderer@3.4.27': + resolution: {integrity: sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==} + peerDependencies: + vue: 3.4.27 + + '@vue/shared@3.4.27': + resolution: {integrity: sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==} + + alova@2.20.5: + resolution: {integrity: sha512-hIIPGQCDajcU5NxDQykUOiwlFa1d2sEK7R9EET6pOtCoGdmw7bqjsDZT9gO0rhb42V7FDyMO9bOdazqNMKQvqg==} + engines: {node: '>= 0.12.0'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + + postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + engines: {node: ^10 || ^12 || >=14} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + vue@3.4.27: + resolution: {integrity: sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + +snapshots: + + '@babel/helper-string-parser@7.24.6': {} + + '@babel/helper-validator-identifier@7.24.6': {} + + '@babel/parser@7.24.6': + dependencies: + '@babel/types': 7.24.6 + + '@babel/types@7.24.6': + dependencies: + '@babel/helper-string-parser': 7.24.6 + '@babel/helper-validator-identifier': 7.24.6 + to-fast-properties: 2.0.0 + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@vue/compiler-core@3.4.27': + dependencies: + '@babel/parser': 7.24.6 + '@vue/shared': 3.4.27 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.0 + + '@vue/compiler-dom@3.4.27': + dependencies: + '@vue/compiler-core': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/compiler-sfc@3.4.27': + dependencies: + '@babel/parser': 7.24.6 + '@vue/compiler-core': 3.4.27 + '@vue/compiler-dom': 3.4.27 + '@vue/compiler-ssr': 3.4.27 + '@vue/shared': 3.4.27 + estree-walker: 2.0.2 + magic-string: 0.30.10 + postcss: 8.4.38 + source-map-js: 1.2.0 + + '@vue/compiler-ssr@3.4.27': + dependencies: + '@vue/compiler-dom': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/reactivity@3.4.27': + dependencies: + '@vue/shared': 3.4.27 + + '@vue/runtime-core@3.4.27': + dependencies: + '@vue/reactivity': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/runtime-dom@3.4.27': + dependencies: + '@vue/runtime-core': 3.4.27 + '@vue/shared': 3.4.27 + csstype: 3.1.3 + + '@vue/server-renderer@3.4.27(vue@3.4.27)': + dependencies: + '@vue/compiler-ssr': 3.4.27 + '@vue/shared': 3.4.27 + vue: 3.4.27 + + '@vue/shared@3.4.27': {} + + alova@2.20.5: {} + + csstype@3.1.3: {} + + entities@4.5.0: {} + + estree-walker@2.0.2: {} + + magic-string@0.30.10: + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + + nanoid@3.3.7: {} + + picocolors@1.0.1: {} + + postcss@8.4.38: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + + source-map-js@1.2.0: {} + + to-fast-properties@2.0.0: {} + + vue@3.4.27: + dependencies: + '@vue/compiler-dom': 3.4.27 + '@vue/compiler-sfc': 3.4.27 + '@vue/runtime-dom': 3.4.27 + '@vue/server-renderer': 3.4.27(vue@3.4.27) + '@vue/shared': 3.4.27 \ No newline at end of file diff --git a/design/v3/api-design-js-global-commonjs/pnpm-lock.yaml b/design/v3/api-design-js-global-commonjs/pnpm-lock.yaml new file mode 100644 index 0000000..2531579 --- /dev/null +++ b/design/v3/api-design-js-global-commonjs/pnpm-lock.yaml @@ -0,0 +1,217 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + alova: + specifier: ^2.20.5 + version: 2.20.5 + vue: + specifier: ^3.4.27 + version: 3.4.27 + +packages: + + '@babel/helper-string-parser@7.24.6': + resolution: {integrity: sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.24.6': + resolution: {integrity: sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.24.6': + resolution: {integrity: sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.24.6': + resolution: {integrity: sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==} + engines: {node: '>=6.9.0'} + + '@jridgewell/sourcemap-codec@1.4.15': + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + '@vue/compiler-core@3.4.27': + resolution: {integrity: sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==} + + '@vue/compiler-dom@3.4.27': + resolution: {integrity: sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==} + + '@vue/compiler-sfc@3.4.27': + resolution: {integrity: sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==} + + '@vue/compiler-ssr@3.4.27': + resolution: {integrity: sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==} + + '@vue/reactivity@3.4.27': + resolution: {integrity: sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==} + + '@vue/runtime-core@3.4.27': + resolution: {integrity: sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==} + + '@vue/runtime-dom@3.4.27': + resolution: {integrity: sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==} + + '@vue/server-renderer@3.4.27': + resolution: {integrity: sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==} + peerDependencies: + vue: 3.4.27 + + '@vue/shared@3.4.27': + resolution: {integrity: sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==} + + alova@2.20.5: + resolution: {integrity: sha512-hIIPGQCDajcU5NxDQykUOiwlFa1d2sEK7R9EET6pOtCoGdmw7bqjsDZT9gO0rhb42V7FDyMO9bOdazqNMKQvqg==} + engines: {node: '>= 0.12.0'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + + postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + engines: {node: ^10 || ^12 || >=14} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + vue@3.4.27: + resolution: {integrity: sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + +snapshots: + + '@babel/helper-string-parser@7.24.6': {} + + '@babel/helper-validator-identifier@7.24.6': {} + + '@babel/parser@7.24.6': + dependencies: + '@babel/types': 7.24.6 + + '@babel/types@7.24.6': + dependencies: + '@babel/helper-string-parser': 7.24.6 + '@babel/helper-validator-identifier': 7.24.6 + to-fast-properties: 2.0.0 + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@vue/compiler-core@3.4.27': + dependencies: + '@babel/parser': 7.24.6 + '@vue/shared': 3.4.27 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.0 + + '@vue/compiler-dom@3.4.27': + dependencies: + '@vue/compiler-core': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/compiler-sfc@3.4.27': + dependencies: + '@babel/parser': 7.24.6 + '@vue/compiler-core': 3.4.27 + '@vue/compiler-dom': 3.4.27 + '@vue/compiler-ssr': 3.4.27 + '@vue/shared': 3.4.27 + estree-walker: 2.0.2 + magic-string: 0.30.10 + postcss: 8.4.38 + source-map-js: 1.2.0 + + '@vue/compiler-ssr@3.4.27': + dependencies: + '@vue/compiler-dom': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/reactivity@3.4.27': + dependencies: + '@vue/shared': 3.4.27 + + '@vue/runtime-core@3.4.27': + dependencies: + '@vue/reactivity': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/runtime-dom@3.4.27': + dependencies: + '@vue/runtime-core': 3.4.27 + '@vue/shared': 3.4.27 + csstype: 3.1.3 + + '@vue/server-renderer@3.4.27(vue@3.4.27)': + dependencies: + '@vue/compiler-ssr': 3.4.27 + '@vue/shared': 3.4.27 + vue: 3.4.27 + + '@vue/shared@3.4.27': {} + + alova@2.20.5: {} + + csstype@3.1.3: {} + + entities@4.5.0: {} + + estree-walker@2.0.2: {} + + magic-string@0.30.10: + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + + nanoid@3.3.7: {} + + picocolors@1.0.1: {} + + postcss@8.4.38: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + + source-map-js@1.2.0: {} + + to-fast-properties@2.0.0: {} + + vue@3.4.27: + dependencies: + '@vue/compiler-dom': 3.4.27 + '@vue/compiler-sfc': 3.4.27 + '@vue/runtime-dom': 3.4.27 + '@vue/server-renderer': 3.4.27(vue@3.4.27) + '@vue/shared': 3.4.27 \ No newline at end of file diff --git a/design/v3/api-design-js-global/pnpm-lock.yaml b/design/v3/api-design-js-global/pnpm-lock.yaml new file mode 100644 index 0000000..2531579 --- /dev/null +++ b/design/v3/api-design-js-global/pnpm-lock.yaml @@ -0,0 +1,217 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + alova: + specifier: ^2.20.5 + version: 2.20.5 + vue: + specifier: ^3.4.27 + version: 3.4.27 + +packages: + + '@babel/helper-string-parser@7.24.6': + resolution: {integrity: sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.24.6': + resolution: {integrity: sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.24.6': + resolution: {integrity: sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.24.6': + resolution: {integrity: sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==} + engines: {node: '>=6.9.0'} + + '@jridgewell/sourcemap-codec@1.4.15': + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + '@vue/compiler-core@3.4.27': + resolution: {integrity: sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==} + + '@vue/compiler-dom@3.4.27': + resolution: {integrity: sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==} + + '@vue/compiler-sfc@3.4.27': + resolution: {integrity: sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==} + + '@vue/compiler-ssr@3.4.27': + resolution: {integrity: sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==} + + '@vue/reactivity@3.4.27': + resolution: {integrity: sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==} + + '@vue/runtime-core@3.4.27': + resolution: {integrity: sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==} + + '@vue/runtime-dom@3.4.27': + resolution: {integrity: sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==} + + '@vue/server-renderer@3.4.27': + resolution: {integrity: sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==} + peerDependencies: + vue: 3.4.27 + + '@vue/shared@3.4.27': + resolution: {integrity: sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==} + + alova@2.20.5: + resolution: {integrity: sha512-hIIPGQCDajcU5NxDQykUOiwlFa1d2sEK7R9EET6pOtCoGdmw7bqjsDZT9gO0rhb42V7FDyMO9bOdazqNMKQvqg==} + engines: {node: '>= 0.12.0'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + + postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + engines: {node: ^10 || ^12 || >=14} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + vue@3.4.27: + resolution: {integrity: sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + +snapshots: + + '@babel/helper-string-parser@7.24.6': {} + + '@babel/helper-validator-identifier@7.24.6': {} + + '@babel/parser@7.24.6': + dependencies: + '@babel/types': 7.24.6 + + '@babel/types@7.24.6': + dependencies: + '@babel/helper-string-parser': 7.24.6 + '@babel/helper-validator-identifier': 7.24.6 + to-fast-properties: 2.0.0 + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@vue/compiler-core@3.4.27': + dependencies: + '@babel/parser': 7.24.6 + '@vue/shared': 3.4.27 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.0 + + '@vue/compiler-dom@3.4.27': + dependencies: + '@vue/compiler-core': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/compiler-sfc@3.4.27': + dependencies: + '@babel/parser': 7.24.6 + '@vue/compiler-core': 3.4.27 + '@vue/compiler-dom': 3.4.27 + '@vue/compiler-ssr': 3.4.27 + '@vue/shared': 3.4.27 + estree-walker: 2.0.2 + magic-string: 0.30.10 + postcss: 8.4.38 + source-map-js: 1.2.0 + + '@vue/compiler-ssr@3.4.27': + dependencies: + '@vue/compiler-dom': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/reactivity@3.4.27': + dependencies: + '@vue/shared': 3.4.27 + + '@vue/runtime-core@3.4.27': + dependencies: + '@vue/reactivity': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/runtime-dom@3.4.27': + dependencies: + '@vue/runtime-core': 3.4.27 + '@vue/shared': 3.4.27 + csstype: 3.1.3 + + '@vue/server-renderer@3.4.27(vue@3.4.27)': + dependencies: + '@vue/compiler-ssr': 3.4.27 + '@vue/shared': 3.4.27 + vue: 3.4.27 + + '@vue/shared@3.4.27': {} + + alova@2.20.5: {} + + csstype@3.1.3: {} + + entities@4.5.0: {} + + estree-walker@2.0.2: {} + + magic-string@0.30.10: + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + + nanoid@3.3.7: {} + + picocolors@1.0.1: {} + + postcss@8.4.38: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + + source-map-js@1.2.0: {} + + to-fast-properties@2.0.0: {} + + vue@3.4.27: + dependencies: + '@vue/compiler-dom': 3.4.27 + '@vue/compiler-sfc': 3.4.27 + '@vue/runtime-dom': 3.4.27 + '@vue/server-renderer': 3.4.27(vue@3.4.27) + '@vue/shared': 3.4.27 \ No newline at end of file diff --git a/design/v3/api-design-ts-global/pnpm-lock.yaml b/design/v3/api-design-ts-global/pnpm-lock.yaml new file mode 100644 index 0000000..2531579 --- /dev/null +++ b/design/v3/api-design-ts-global/pnpm-lock.yaml @@ -0,0 +1,217 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + alova: + specifier: ^2.20.5 + version: 2.20.5 + vue: + specifier: ^3.4.27 + version: 3.4.27 + +packages: + + '@babel/helper-string-parser@7.24.6': + resolution: {integrity: sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.24.6': + resolution: {integrity: sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.24.6': + resolution: {integrity: sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.24.6': + resolution: {integrity: sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==} + engines: {node: '>=6.9.0'} + + '@jridgewell/sourcemap-codec@1.4.15': + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + '@vue/compiler-core@3.4.27': + resolution: {integrity: sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==} + + '@vue/compiler-dom@3.4.27': + resolution: {integrity: sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==} + + '@vue/compiler-sfc@3.4.27': + resolution: {integrity: sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==} + + '@vue/compiler-ssr@3.4.27': + resolution: {integrity: sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==} + + '@vue/reactivity@3.4.27': + resolution: {integrity: sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==} + + '@vue/runtime-core@3.4.27': + resolution: {integrity: sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==} + + '@vue/runtime-dom@3.4.27': + resolution: {integrity: sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==} + + '@vue/server-renderer@3.4.27': + resolution: {integrity: sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==} + peerDependencies: + vue: 3.4.27 + + '@vue/shared@3.4.27': + resolution: {integrity: sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==} + + alova@2.20.5: + resolution: {integrity: sha512-hIIPGQCDajcU5NxDQykUOiwlFa1d2sEK7R9EET6pOtCoGdmw7bqjsDZT9gO0rhb42V7FDyMO9bOdazqNMKQvqg==} + engines: {node: '>= 0.12.0'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + + postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + engines: {node: ^10 || ^12 || >=14} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + vue@3.4.27: + resolution: {integrity: sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + +snapshots: + + '@babel/helper-string-parser@7.24.6': {} + + '@babel/helper-validator-identifier@7.24.6': {} + + '@babel/parser@7.24.6': + dependencies: + '@babel/types': 7.24.6 + + '@babel/types@7.24.6': + dependencies: + '@babel/helper-string-parser': 7.24.6 + '@babel/helper-validator-identifier': 7.24.6 + to-fast-properties: 2.0.0 + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@vue/compiler-core@3.4.27': + dependencies: + '@babel/parser': 7.24.6 + '@vue/shared': 3.4.27 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.0 + + '@vue/compiler-dom@3.4.27': + dependencies: + '@vue/compiler-core': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/compiler-sfc@3.4.27': + dependencies: + '@babel/parser': 7.24.6 + '@vue/compiler-core': 3.4.27 + '@vue/compiler-dom': 3.4.27 + '@vue/compiler-ssr': 3.4.27 + '@vue/shared': 3.4.27 + estree-walker: 2.0.2 + magic-string: 0.30.10 + postcss: 8.4.38 + source-map-js: 1.2.0 + + '@vue/compiler-ssr@3.4.27': + dependencies: + '@vue/compiler-dom': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/reactivity@3.4.27': + dependencies: + '@vue/shared': 3.4.27 + + '@vue/runtime-core@3.4.27': + dependencies: + '@vue/reactivity': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/runtime-dom@3.4.27': + dependencies: + '@vue/runtime-core': 3.4.27 + '@vue/shared': 3.4.27 + csstype: 3.1.3 + + '@vue/server-renderer@3.4.27(vue@3.4.27)': + dependencies: + '@vue/compiler-ssr': 3.4.27 + '@vue/shared': 3.4.27 + vue: 3.4.27 + + '@vue/shared@3.4.27': {} + + alova@2.20.5: {} + + csstype@3.1.3: {} + + entities@4.5.0: {} + + estree-walker@2.0.2: {} + + magic-string@0.30.10: + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + + nanoid@3.3.7: {} + + picocolors@1.0.1: {} + + postcss@8.4.38: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + + source-map-js@1.2.0: {} + + to-fast-properties@2.0.0: {} + + vue@3.4.27: + dependencies: + '@vue/compiler-dom': 3.4.27 + '@vue/compiler-sfc': 3.4.27 + '@vue/runtime-dom': 3.4.27 + '@vue/server-renderer': 3.4.27(vue@3.4.27) + '@vue/shared': 3.4.27 \ No newline at end of file diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index 821fd49..ea61dea 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -1,8 +1,8 @@ { "name": "alova-vscode-extension", "displayName": "Alova", - "description": "The vscode extension for alova.js", - "version": "0.0.9", + "description": "Generate and search APIs without API documentation any more", + "version": "0.0.10", "engines": { "vscode": "^1.89.0", "node": ">=18.19.0", @@ -21,13 +21,13 @@ "commands": [ { "command": "alova.refresh", - "category": "alova", - "title": "alova refresh" + "category": "Alova", + "title": "Generate APIs" }, { "command": "alova.create.config", - "category": "alova", - "title": "create alova config" + "category": "Alova", + "title": "Create alova config" } ], "icons": { diff --git a/packages/vscode-extension/resources/icon.png b/packages/vscode-extension/resources/icon.png index 7bb5c54d74666c6651ac2af86c28e065aa09b912..62cce6e4f38990952e8b83b2b8969c2cdbf7ad57 100644 GIT binary patch literal 123560 zcmeEt`8S(u)V7|U(@E87wQ6=+#Zj}E$J1)5np)I6RR|)Xq~;-~)lxO2tr`-^PCep$Hm3P zV{-3~6&KgZY|i(YQ|$k_Ueh|j{&50kWqg~fqEBR={g2;aw@qx$u)m_tc)sG|`islt z&Mlj;?4=eK#%s)BdZ$bWpcfnXXy5CvUo9`6L*Hrg!*8tx6zBad^XbJuD!=aEzSnH} zSM2#XW4Wx=~N=mJYKfXo|H22>9H~g*Ykly4@ z*})TrWB*P#d3{z^fU;*#@lAEF!7WA z8`o#$muIE9xSZ``7BUtiU1b^HHJ}UdsK#_X0QC@RU4B%aI)y@x*}Wd4>?|D}?ttLT z9sNf!OgeTyY%QO;os*@sG5y>Go*!9eKQDj)bGNWJqqogI%;E??YRZGry_X7rz_`5 z#{$wkrpF?J)!T@@&67mevXPisHO$dMqM7aquJ78PU+{5pxoQ~f^`1s#PrlD(ZGs{} zm^NpuHA=-gySG!-(%|T0rk?fE4t%aMV-?pig@8V6Ex z+o>6kk6|UwCTgr#adCamZ0Fph0@=3ylC(Kj(sJzxs$wBQL#br_7~OZf?6U3RV{x)(xqS3tZO za^O`)S6+@>7SE|UTKj0Jy|c48ADPH<0z}U70J73oWNelaIk$=T->N>r^?4n*YOBEp z(u(dOetKLkm8AYb4rE*Qez~`&#=ohtE%>!u@5Z!Mm14%tbV@EjXWPxW`iKP*nO-Kg zL^7PbkPuWCy4l}U?DD)TqDFQ?`%GQ39i z2gkomqnLmMzdyVjN(l~XOzzVRsQ3YOyHj6f)>z-!;PJ>5ls|H=8{YvbSx|bFXJx zr-qtqxkMStcpZ&H<>+tWP?U|Bmm#hncdx=}8hhK0Y!V3xSg@~`a${z`?*W9F>E+3) zn6CT&%U*!@15ZJ;d3;Tem9t~1_2Ob6brzRAxh?Ke4UaI@q47T%SmGO5s=fc+KdIF6 z45HQLJZRA^wV-Qru)lnSg@~Tv8am6xW&B$Q`x?J7uLwaKST72b4+k@|dcg&kOVyCQ zhBT>AocZ%Kxw0i8MxU*V0yS@sl9^FQn&%bFwl^je9=>4(KkK>`+I~ z#<3w3vH?Sg=)ysm@Yv#N)x}<)p@`Pp_kmessak3l8)`uLx}$+?i&9XLMhGR;wK_iF z%a3V(=Lt+GRb{MMOba!s;H2vfB`wW*jn}wqv*G<9^9h^nHw|`P#?JMV_v4;4jSiv< zw506$t&M$ycE-JOrYh7Y#p*KNqQ-N>7Kfo@LnEzBZSj?5)4I^Mm8QP?(`mE1wXl(? zUi{OFX0w6UJ3WU4{hp8PV9Afauv1_i!+6WSH)KIL!qv_4bM}l6RwaE2Ipc|+ut;qh zO~K_{%LUAZV4eHG0gaEMVVGjj(cVZFF-?S&Fkq&IBAbC;owa?MFde5n|2x;ekB$TW z+^<)YNqRX5$pouJuN2;;3F;MWAC<1lfd@_%+df~H?b)pY$7Cb_ZDd zeI6nECCQ*g@48g7hEe`l-?P1NG{owM%v?DH-jZ&@7CbX|PRP%4qi1?Hy%)$3^`D|< zU2$qOAE3qD29U@a(o_y8cUStTSA=0=*~BX!*AN@6pB$ZP*oIVG3xyG1)K%eUMEZhM zy~naa*H|H=n|R1kz8O2!e;sRpwgK~N`=)nkOFJY+c(ZuknOr{m6q`HoR9$xAl!eVN zckQ}DkakvkX(S_s68)`S%d3A1S-!s2g1&@NUJa5r#w2+$$6nvoX|)nfT%J1mMaX>m z8`r-b9DN}Ym#lN!HV%*^I?uX8roV!r#q=9%q?;>t>|Xzg>{-vkhSsw7FmT`FIxx1n zeyZj|lgV&$P9M2pr+8Mxy!!LIEWr&QSPK0~Ol>YSptTv6Z?P1_g}I`IENo* zPbHI$V8!^MWt5O5jOGAQMc?ui>k8`&(gAX>+?4*lT0MKlIA2RSGeX#H+0ZmR`(3{8 z-Nmh&w?)Z)rf&=CuL(aqW_H!=?$KQyE-szDVF^35PS&bXmVCNNN?~&7Z74r+)kE0a zi@RsNZ&M-WkYKiCUl668+&P&)^9 z9Drnd>Tk0V-RHj`ylsIgcqN&YY0)*b*ZGtl_1V|INXTN5xxk!GqYD14Fx8kiyth9) zLifSLuHA*m8(XJ&t7Ju_5b-d{WfxbbI7>6tg6rSZ^L*?pUr)bo&@2vcI!hx?mvj(C zI+!3ilcjJumvnSPham5Ue1R6n#>iQ0A9&i>b$;*J zyP>gOGX@`;B2(F(-hD{5jJ+nh;@U+11?)k0!QMb%N+@+miWZ7mHvplFkU}W#b!pha zof?Hq(o~_kYdSR2>qx?YBOl*ya0v7L#oADATQg~Fc;ahzr8l_w#_1<0JFWiZT7GYJ zMV;>D^WoY2l;9y`kap9$E*+xo&&{;lJNVtn1(BXF*vDiq0pusMxF0S|+Xq;k_5;hG z$Y2xw^V#QY`|YzVwNs_s}pJY#i4o2>l-SSp;c&-Gm3&-eX=+wpA!KbJj?aOiX$XX zhvcNS16!tSJrk$H5A zxG;58b=o##B(5%YKm>L(w%xg7=OS37Z1H}tlwSllk^`Azl#2jk_BS(fb?S=)Y}Vgz z?)2PAEvDH#EQnL3hd9<}0#@yc z3kYg_mnEYWjbc)UB)i^#58mYaf;%T%@ld{@vE z2Ac{>x+c7IC!ab}-2I*N*F_{Jx~sCB7-X0#wI^XNR=q1v%v^nC3Vx^yjmuwVtA$$?Wf z$IX6L{>hiycCa+o7;atfDzz7!SDU8{(C`T29`@I^J6~*zOCKtJc|jw`zd4Wfeq&<@ zrKcBC+g6h?wgYwOfIkDHK|U=xL1L`ErfC%a|H(rug33 z(^Ue1f$h}}Vq_XYI;6x|1Ol3Zrg0$#L>%&9WKKAz>!R(|s3M zV;2_o!jfBxKUG^js~rkU|Eqsrs?Mc5ECeQb&CyFKWAHx@Wn-n6;fv27_VzCh|Ht=T zb4PB>NI5fp)~Ba`eGiH2gD6->V*0CW_%VjRRp<#Ii_8l0+VvqO!EZS%9EIl zAEy0iz0v0GD-5l1WgT|j^OlYV7QiKNj8%`NN=R7Lqe>smzlxV3J zH9rOuj=;XSPn#fWr_b9q56U7|f zHgxPJ#4GB-K-Sa4OWznr1HN9|>N6qt1zEsy?1HI`zf_z&Jp?R!F!D9D@R03kaP^^*Yqu{iojSs=3aet^-pw?=?#*oDbicRW-Ke@vf@%_nai| z%ZfM|7*UUuIK@=w9EWY8XABP43cUMVwZdS;Qlfg$I}9a>a-#^=99foGDn!%EunanD z=vpAu%P$P2jBjek&-tTJI^2u5$D9JM`>XTV&h{!0?fkDv!Tm5D7gyY~cN>FbemhSs0ju7^Az{1QwScDl zZHKF_lq3AIl=$n26P@G(jnAxG=h(&X z>hZ_x?LkB{egZgJ8ba0R4jt09APp?>TW`z`E6iqp=9ktAkDb4K1qIV4G!JeqEWg@| zfep=T#cCA|@ho0ys0Q}qPw?O_CA%b+7!j^ViRZqkanH2dMJ;Jeq0n zRCr{`U`W!CtGWv%J+vFzOKq$wf8CdJDUX^YKb%A+f0{{%You04 zOAW!GiE2#k2^aMnZ+cA0<$~r=YT2YIT!~$D8_c!N!XKUFns|8d%UjVu;Ln-gzHO4n zkGk#$3u|@H+X&BYf9g=-J%hLUSu=mW+%ab3=542~mAdvfJ<2AVH|lMckW(^`7>*>1 z7e7>m4|0Q>1jwBfxx~RQTAvJ&?hV$He$dxbswr<<%YZzo5-1^3Yhj9UrXzdp0FL7O zYjAw}gwesTjtsOuyXceTJ~h9C_n16=2gvC1ddN59@C0}(dD=_c(4|_-nmNKVKJn%P z37{NtZC#1~CP;cNpt??k1koJfzd+X!`U29cylIT7ClIJ?E0X^so9wp=4NWSp>MUr-;t2YGJ!{?lsI?>{|cvd-EcriL_DK`bNJr_`TxMENg`1mJp z>^fS2m_OswqqVK~HQY5}bGME*P@T8DvdA#_%7Gj9f9UlY5wr4hXpRlHb)6U30+T~0 zrxF}w3!rVc(p7%t;fvyRh>^c4nvk>X zHsY}MQkU}Jzw`7#!r({lNBXDok>?A;W9TC@KKuHeFR)l-(hjoy{r%_NYQAk-@tqvM z)nI;XP80Xu_Pa*y6Wi(XBoA;aP(2+)9=zG%VyNb4xojyrI`kJ+p;Px|ga5maNr_#p z9kzuTS7Wb0vhA*vm#(zkcMf>l=};5qp>6r%d#$+=BBF15VveuC>-pKTVnjjfuElj} z^})E7JNW3Cw^s4dor5$hH;_uY_p)N}Q7k-%L-_JI4)x?`jP*m;=P_9%rwGu@o2>c! z()J&{=C8|?bh;}iUNsx^N#ZjsS@0vy4)y4&t3trqlj%IDn~fw-?TmbzQoEk+T~kOv z0IE_8J?*JUY82c$xF_7?oLm^*vWLuNrF^A>0Jh*jNP0u%yK$8Ta+sXqft=@f+>@4L z9&}~DYAa>q(OCa*%q~|yvMSv4>)qbHFufv`Rw8lV#Yq|$H1>wx+@DPyTe9yf*o^8< zYj|%h7_?kiI7I!42VimH8AAQ(#sVp`?D|OpsXmX0DcP~rg?Il=^*IHV0pjB7Cd`se zLISC1-E`^Y!D{(Fl_Xw4fa7hLZO6mq72acL{>dpa_5UK^Y+QJ2Y|DeLr~e-9Sh#)r zok7vFF=ueLK>z%v_UZP~yi^?fcXz$4D~s|7JVyMdyDo_)wQpYF@GF-uwas@!BUmM~ z{da}v5&68U21K6~;($mJD5CD}+lc2b+kwJCs=Ugm$A5dKBDu@9;*kWWVy5_k)^QBK zabnOwBIH3sowt#==4DHul`<8j<{ti zd3(}Bl{v2M2d^!~CD$DT^UARtCPW>;D)poNm9xMF#Jp~60tNC`C?}me<6L5xm7z9n z5vra8y?RUUb+wJ5wmL!fVpI6&q+dbUD8c=ScOfhsBa>AW60#fkA@{GQ3v( zWOlzM6Ed`^4)wTU$QR|iJQ1FC`%3|OC}H6I7eF~RCx5>G*Ll`Ao^nR6gBm9p8p6lP zNDx0X@blgb?IB!5Nq|T zj3~iyyvQU+8y!bO?)5?S$jlB1FpDL=i?idjd=od01@m`(##o|dj*dOC&_T)O8ZT+s zxp8PH_qBg79&oP9UAIN5-jN!;qJoxJ6||hZ1#lvlCIz-TOVI>NuSOP1m7Tw$QNLXj zx~$hWI7^7r0|*KOPWl+D{=2A!idYFw^Bnm`gLg2J z%Vi8>@kFMnV-a{YDMCILi#GR`ZOD#nj?i#M7mQ64LQs!IWH zyGr%$_Vqu~1a_Z~KuSv4swd%^hXYly_rQ!Fnd7-mAE3x(wKk{4_|fMB8I0;)j<`x4 zcPpnhI&!18i(za*A-(%|K2B=332J9FR2*0?ruI=L)c@=9aKnFI*wWv;8r%ddWmB0P2VC=%s)b^a$H$5Iw}1uf~!2TEda)c+);_e;m1# zP-gre>*D@ji1i8aIF9hYJ?7U52#MbAbaxwv%YIL3Zg?{!!}z5{^NrTR2`^jOXM3o! z#~EM?Zxu8q+hXK?ykNik^i%Om6l&=2wD6vledE*$-I%4ZPOkm1OuCPw90tW6_8|>Z z3Z-28@b8BKeCXH#T{+{S;rsaLr&7@Fe!lHSuVx;?fEyb+o5!{PcTOu*0T5>qWi4}X zL2I^Z&p~v4ADNv`;!t*<=S`T!9K*QI%+>nqJmiGJedeHSqV3I?(HV3cEmn9kjc0zR#(Vj0hMRP(bLTg3{z(YVc3!?T^*p)R}xL!&lET##OUhaY6 zOYna=6+HNO?h*VwUVpR4+M8EBVEH#G!Gd-FT942#N0NPVGegMEt9&r6IOJGon4>zn z;?wH_){Z*v0?MICq3rp(4NNfDDjn1coHl+1K*)kZ0{a&VJPfo%b_3@e&$};pi^j(E zZFvp2JErg&emjVYd-jbxeu7AjNv+Nz{G&VDG8Ja*t(-Y@n3**2u4IYnvWl>R9Gz_Y z%u$1gV>JlgcpHyRHLv@dWFPV{HObY~f;bkIgATH73g2=zs=l3W=Is{YOtsU<@PIqM zaT4!uQ895A%=jZWWO3_1I@`$J?M%d{k;YNwo$G zho@tHEONNuD$U`7>uG~6w)=qekDX6>@Y1bDZCRld{G#WEzCtAcgWrD5%MJLH0qN?r5@yB!+LApKKOOI3}T5+BF@kYrW6)Wx$!A}r?^`9}H& zNISGHY_Eq}L4iq{o7)6)d#WpcG;9{?PY@Lfx=HI@5D*XAes>KDt$qTTvdHQr%-+wY z|9RhH3K%*a{6qX8xv6cn5dEDRXI?uv(qD=^_Y*l_Hm3-km$(a4m6qJ!b7YLx+sdfT z*!MK31%&#+-0WcGzRklQY^yg_rXpJS5t7@+h}^9NUo*dec6JGD7UPsa=ab@l?2?Su z(F}9a$N-#ZtU7CkW`%Kd)UAN|!^Y~G-7-@MaU535$W1C4X2n4_BR7KX-tr|4R zD5qHujfGsy8%gqt6?TKpAts|KXLBJaB=k#DyHBB)h}M2hRd(8$f>Jb0_6j3I9{s~aQljiH)wrw34ACz>uoRt-hf zTICcc&zwqC?IvW;hM*iYK8Ur+lBwk7hxPY@)uyD@)d-d;16FRjA)&Z69W!+j5dsum zwM>N-!H1ugN?y*_BMrQdu%nH{#cwLkl_5x=8(x!Ybf1#&+6Fa7e0is3kSc9dr`e!z z9mHJq=FFEoIrtKJ#tWyXN%xCFruZ+rVy;ug^Ir-jdE4l+ava5B)O`Md&IzAaDgu_( z4?18PL;i^z>xGnoXN_MTznOD=@=BSVI=US1!PwOcb=l3aobK?1Jr3xfz>n2rJL&)g z@9~}dyGSLg7i-l|8|F%XFh_K5ObCv}4ZHhkp{7nHQ?S@DoY7X}*9a@BJnL=K!r!ci z9}PP3D{V(7IL6EP7-QF>etoDk2&ea?)&G$=SZ1n`;_|9t{$hR+(yOqqvvl15A>YV$ zp3o=dwlc!@ZiUNSAz1_K~=Va(# zgqLg?*<5=q+s;QtH_+H^*eodEeN6goL(#62_k{rM5Y#Z{U`bH} zsm>CX4__T5U(+zZTu}F%!wQ z(D=C^+@o%-#DPor%o6fPBj#YtS6q(zu!QZ<#O=PIoATw{UXoK8zPVs+YV~%ZRIZv1 zS#pZmiNGO?4H{2laETCVW11;01=sm#)@LD?JtR#yc{#QPU~Iip(5o)Bv5Ty2D%2G9 z>((lq{`0GmHU6>AndQ@>l{)(!9}Uv=AG1MLb?lq@7zUd?8SG4Dum090_vve92J(DD z*CRi?HFqe^dP7ApOB8R7oSwB#e)E2yVahpy*T|$kxjNbl;nY75xht*{OnG^f(oMfM z(`u=OO81=Jit1ASGucNyj6W{)(qQ`rj>X<-UkLk}k#r%yK#Y{SL~ilBFWOdYhA{uK zafbCn3V{7^MXSsp9m-sVzv0yK^BguN@ak`EE9SOD%|@vPk&}sxqp{2K)EkoKzq?MS zFZaI*kP38ssC0WI^pYroFWI})IH@Ropn=iD|MzT2+&{`D;3+f2qom9b3UEhhOjn36 z-&ei07QX%ab^)sW*J;{4k&uA-^F^b`0UJL1`1`=pnt`Oq%$8aMkYwE$<}gz<9B$`* z5yvuwFSQ-DS8}$W?s1UyCqsOHKcnA8OH+Ka-6rYIAH|^#!NGHvy38$x73_j{9INk< zgy=aw@{Q)uhgD9Fph4ar74;sO!-r-Un(8G(?({yo((4660M!wAbh42Ze#S?AD3cqs zdPWQ7s@f7oU@0`@G$#KAlT zt^g;5&2kNR@{DF-N{`8T&!WfW_*w!8R>RzNl3YD?V@&Q9j;y9B${yfp4L$rk))ajs!b zd{IlBnBVsNjAFUiW*}+=(x`AMzf=+P7>-MEcNxK3>`STmG7w=3_MRrh#Yq_TbNR8U

&3P=g={)$M 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

#$k(kfvvCWRz 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 WGjd7cyZtfnA0BSru8i-3fBip>1Wktk literal 33114 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 { delete statusBarItem.command; }; export const reset = () => { - statusBarItem.text = `$(alova-icon-id) alova`; - statusBarItem.tooltip = 'alova refresh'; + statusBarItem.text = `$(alova-icon-id) Alova`; + statusBarItem.tooltip = 'Generate APIs'; statusBarItem.command = 'alova.refresh'; }; export const statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..a7f27d7 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,7379 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + cosmiconfig: + specifier: ^9.0.0 + version: 9.0.0(typescript@5.4.5) + handlebars: + specifier: ^4.7.8 + version: 4.7.8 + import-fresh: + specifier: ^3.3.0 + version: 3.3.0 + lodash: + specifier: ^4.17.21 + version: 4.17.21 + node-fetch: + specifier: ^2.7.0 + version: 2.7.0 + openapi-types: + specifier: ^12.1.3 + version: 12.1.3 + swagger2openapi: + specifier: ^7.0.8 + version: 7.0.8 + devDependencies: + '@alova/wormhole': + specifier: workspace:^ + version: link:packages/wormhole + '@commitlint/cli': + specifier: ^19.3.0 + version: 19.3.0(@types/node@18.19.34)(typescript@5.4.5) + '@commitlint/config-conventional': + specifier: ^19.2.2 + version: 19.2.2 + '@types/js-yaml': + specifier: ^4.0.9 + version: 4.0.9 + '@types/lodash': + specifier: ^4.17.5 + version: 4.17.5 + '@types/mocha': + specifier: ^10.0.6 + version: 10.0.6 + '@types/node': + specifier: 18.x + version: 18.19.34 + '@types/node-fetch': + specifier: ^2.6.11 + version: 2.6.11 + '@types/serialize-javascript': + specifier: ^5.0.4 + version: 5.0.4 + '@types/swagger2openapi': + specifier: ^7.0.4 + version: 7.0.4 + '@typescript-eslint/eslint-plugin': + specifier: ^7.13.0 + version: 7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': + specifier: ^7.13.0 + version: 7.13.0(eslint@8.57.0)(typescript@5.4.5) + commitizen: + specifier: ^4.3.0 + version: 4.3.0(@types/node@18.19.34)(typescript@5.4.5) + cz-conventional-changelog: + specifier: ^3.3.0 + version: 3.3.0(@types/node@18.19.34)(typescript@5.4.5) + eslint: + specifier: ^8.57.0 + version: 8.57.0 + eslint-config-airbnb: + specifier: ^19.0.4 + version: 19.0.4(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react@7.34.2(eslint@8.57.0))(eslint@8.57.0) + eslint-config-airbnb-typescript: + specifier: ^18.0.0 + version: 18.0.0(@typescript-eslint/eslint-plugin@7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) + eslint-config-prettier: + specifier: ^9.1.0 + version: 9.1.0(eslint@8.57.0) + eslint-plugin-prettier: + specifier: ^5.1.3 + version: 5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.2) + husky: + specifier: ^9.0.11 + version: 9.0.11 + js-yaml: + specifier: ^4.1.0 + version: 4.1.0 + lint-staged: + specifier: ^15.2.2 + version: 15.2.7 + npm-run-all: + specifier: ^4.1.5 + version: 4.1.5 + prettier: + specifier: ^3.2.5 + version: 3.3.2 + prettier-plugin-organize-imports: + specifier: ^3.2.4 + version: 3.2.4(prettier@3.3.2)(typescript@5.4.5) + prettier-plugin-sort-json: + specifier: ^4.0.0 + version: 4.0.0(prettier@3.3.2) + tsx: + specifier: ^4.15.8 + version: 4.16.2 + type-fest: + specifier: ^4.20.0 + version: 4.20.0 + typescript: + specifier: ^5.4.5 + version: 5.4.5 + + packages/templates: {} + + packages/vscode-extension: + devDependencies: + '@types/vscode': + specifier: ^1.89.0 + version: 1.90.0 + '@vscode/test-cli': + specifier: ^0.0.9 + version: 0.0.9 + '@vscode/test-electron': + specifier: ^2.3.9 + version: 2.4.0 + '@vscode/vsce': + specifier: ^2.29.0 + version: 2.30.0 + esbuild: + specifier: ^0.23.0 + version: 0.23.0 + esbuild-plugin-alias: + specifier: ^0.2.1 + version: 0.2.1 + + packages/wormhole: + dependencies: + '@alova/templates': + specifier: workspace:^ + version: link:../templates + + test/api-js-commonjs-test: + dependencies: + '@alova/mock': + specifier: ^1.5.2 + version: 1.5.2 + alova: + specifier: ^2.21.3 + version: 2.21.3 + vue: + specifier: ^3.4.27 + version: 3.4.31(typescript@5.4.5) + + test/api-js-test: + dependencies: + alova: + specifier: ^2.20.5 + version: 2.21.3 + vue: + specifier: ^3.4.27 + version: 3.4.31(typescript@5.4.5) + + test/api-ts-test: + dependencies: + '@alova/mock': + specifier: ^1.5.2 + version: 1.5.2 + alova: + specifier: ^2.20.5 + version: 2.21.3 + vue: + specifier: ^3.4.27 + version: 3.4.31(typescript@5.4.5) + devDependencies: + openapi: + specifier: ^1.0.1 + version: 1.0.1 + typescript: + specifier: ^5.4.5 + version: 5.4.5 + + test/api-v3-js-commonjs-test: + dependencies: + '@alova/adapter-xhr': + specifier: 2.0.0-beta.8 + version: 2.0.0-beta.8(alova@3.0.0-beta.10) + alova: + specifier: 3.0.0-beta.10 + version: 3.0.0-beta.10 + vue: + specifier: ^3.4.27 + version: 3.4.31(typescript@5.4.5) + + test/api-v3-js-test: + dependencies: + alova: + specifier: 3.0.0-beta.10 + version: 3.0.0-beta.10 + vue: + specifier: ^3.4.27 + version: 3.4.31(typescript@5.4.5) + + test/api-v3-ts-test: + dependencies: + '@alova/adapter-xhr': + specifier: 2.0.0-beta.8 + version: 2.0.0-beta.8(alova@3.0.5) + '@alova/mock': + specifier: ^2.0.4 + version: 2.0.4(alova@3.0.5) + alova: + specifier: 3.0.5 + version: 3.0.5 + devDependencies: + typescript: + specifier: ^5.4.5 + version: 5.4.5 + +packages: + + '@alova/adapter-xhr@2.0.0-beta.8': + resolution: {integrity: sha512-5lYV2NfSwpQ2z9IthOdYNxSHv2r7RY2KU6WYHkU1P73wJHqfCzy2OraCJtljVS+go/Wl/zxYxl9b0iVjU5AS0w==} + peerDependencies: + alova: ^3.0.0-beta.10 + + '@alova/mock@1.5.2': + resolution: {integrity: sha512-qEkOgTgzbltkTG/3bn1cvekP6AlPuqpv/N3s5dpu15neMGk24p1qnruz+aeNtg4rMU92zNJ+FtGZF4QRd/vxog==} + + '@alova/mock@2.0.4': + resolution: {integrity: sha512-mBqzwtt0PUa41W8lAxacqnttfiqccCRldPSqyOzFDGD9n63sBGV3CFcne4oUe9YYwjgrXYqsWVY4FPWqltqLhw==} + peerDependencies: + alova: ^3.0.5 + + '@alova/shared@1.0.0-beta.7': + resolution: {integrity: sha512-tnELbw8fsvUUXDwgbIiWLg2oJuRaxwTvf54+f3JnOgCwSLa47dcO7aKvi0FGV26F8enxgTop7CUwP8LlHCtM7Q==} + + '@alova/shared@1.0.4': + resolution: {integrity: sha512-Tq47Wd5q76kPmGLXmPijb0AfsXW2aWR9Pid1KO1nz96BdWiKstx2t/ZLTNaGtQzYyB6M+puunaTTJbusJQPmkQ==} + + '@azure/abort-controller@1.1.0': + resolution: {integrity: sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==} + engines: {node: '>=12.0.0'} + + '@azure/abort-controller@2.1.2': + resolution: {integrity: sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==} + engines: {node: '>=18.0.0'} + + '@azure/core-auth@1.7.2': + resolution: {integrity: sha512-Igm/S3fDYmnMq1uKS38Ae1/m37B3zigdlZw+kocwEhh5GjyKjPrXKO2J6rzpC1wAxrNil/jX9BJRqBshyjnF3g==} + engines: {node: '>=18.0.0'} + + '@azure/core-client@1.9.2': + resolution: {integrity: sha512-kRdry/rav3fUKHl/aDLd/pDLcB+4pOFwPPTVEExuMyaI5r+JBbMWqRbCY1pn5BniDaU3lRxO9eaQ1AmSMehl/w==} + engines: {node: '>=18.0.0'} + + '@azure/core-rest-pipeline@1.16.2': + resolution: {integrity: sha512-Hnhm/PG9/SQ07JJyLDv3l9Qr8V3xgAe1hFoBYzt6LaalMxfL/ZqFaZf/bz5VN3pMcleCPwl8ivlS2Fjxq/iC8Q==} + engines: {node: '>=18.0.0'} + + '@azure/core-tracing@1.1.2': + resolution: {integrity: sha512-dawW9ifvWAWmUm9/h+/UQ2jrdvjCJ7VJEuCJ6XVNudzcOwm53BFZH4Q845vjfgoUAM8ZxokvVNxNxAITc502YA==} + engines: {node: '>=18.0.0'} + + '@azure/core-util@1.9.1': + resolution: {integrity: sha512-OLsq0etbHO1MA7j6FouXFghuHrAFGk+5C1imcpQ2e+0oZhYF07WLA+NW2Vqs70R7d+zOAWiWM3tbE1sXcDN66g==} + engines: {node: '>=18.0.0'} + + '@azure/identity@4.3.0': + resolution: {integrity: sha512-LHZ58/RsIpIWa4hrrE2YuJ/vzG1Jv9f774RfTTAVDZDriubvJ0/S5u4pnw4akJDlS0TiJb6VMphmVUFsWmgodQ==} + engines: {node: '>=18.0.0'} + + '@azure/logger@1.1.3': + resolution: {integrity: sha512-J8/cIKNQB1Fc9fuYqBVnrppiUtW+5WWJPCj/tAokC5LdSTwkWWttN+jsRgw9BLYD7JDBx7PceiqOBxJJ1tQz3Q==} + engines: {node: '>=18.0.0'} + + '@azure/msal-browser@3.18.0': + resolution: {integrity: sha512-jvK5bDUWbpOaJt2Io/rjcaOVcUzkqkrCme/WntdV1SMUc67AiTcEdKuY6G/nMQ7N5Cfsk9SfpugflQwDku53yg==} + engines: {node: '>=0.8.0'} + + '@azure/msal-common@14.13.0': + resolution: {integrity: sha512-b4M/tqRzJ4jGU91BiwCsLTqChveUEyFK3qY2wGfZ0zBswIBZjAxopx5CYt5wzZFKuN15HqRDYXQbztttuIC3nA==} + engines: {node: '>=0.8.0'} + + '@azure/msal-node@2.10.0': + resolution: {integrity: sha512-JxsSE0464a8IA/+q5EHKmchwNyUFJHtCH00tSXsLaOddwLjG6yVvTH6lGgPcWMhO7YWUXj/XVgVgeE9kZtsPUQ==} + engines: {node: '>=16'} + + '@babel/code-frame@7.24.7': + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.24.7': + resolution: {integrity: sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.24.7': + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.24.7': + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.24.7': + resolution: {integrity: sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/runtime@7.24.7': + resolution: {integrity: sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.24.7': + resolution: {integrity: sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + + '@commitlint/cli@19.3.0': + resolution: {integrity: sha512-LgYWOwuDR7BSTQ9OLZ12m7F/qhNY+NpAyPBgo4YNMkACE7lGuUnuQq1yi9hz1KA4+3VqpOYl8H1rY/LYK43v7g==} + engines: {node: '>=v18'} + hasBin: true + + '@commitlint/config-conventional@19.2.2': + resolution: {integrity: sha512-mLXjsxUVLYEGgzbxbxicGPggDuyWNkf25Ht23owXIH+zV2pv1eJuzLK3t1gDY5Gp6pxdE60jZnWUY5cvgL3ufw==} + engines: {node: '>=v18'} + + '@commitlint/config-validator@19.0.3': + resolution: {integrity: sha512-2D3r4PKjoo59zBc2auodrSCaUnCSALCx54yveOFwwP/i2kfEAQrygwOleFWswLqK0UL/F9r07MFi5ev2ohyM4Q==} + engines: {node: '>=v18'} + + '@commitlint/ensure@19.0.3': + resolution: {integrity: sha512-SZEpa/VvBLoT+EFZVb91YWbmaZ/9rPH3ESrINOl0HD2kMYsjvl0tF7nMHh0EpTcv4+gTtZBAe1y/SS6/OhfZzQ==} + engines: {node: '>=v18'} + + '@commitlint/execute-rule@19.0.0': + resolution: {integrity: sha512-mtsdpY1qyWgAO/iOK0L6gSGeR7GFcdW7tIjcNFxcWkfLDF5qVbPHKuGATFqRMsxcO8OUKNj0+3WOHB7EHm4Jdw==} + engines: {node: '>=v18'} + + '@commitlint/format@19.3.0': + resolution: {integrity: sha512-luguk5/aF68HiF4H23ACAfk8qS8AHxl4LLN5oxPc24H+2+JRPsNr1OS3Gaea0CrH7PKhArBMKBz5RX9sA5NtTg==} + engines: {node: '>=v18'} + + '@commitlint/is-ignored@19.2.2': + resolution: {integrity: sha512-eNX54oXMVxncORywF4ZPFtJoBm3Tvp111tg1xf4zWXGfhBPKpfKG6R+G3G4v5CPlRROXpAOpQ3HMhA9n1Tck1g==} + engines: {node: '>=v18'} + + '@commitlint/lint@19.2.2': + resolution: {integrity: sha512-xrzMmz4JqwGyKQKTpFzlN0dx0TAiT7Ran1fqEBgEmEj+PU98crOFtysJgY+QdeSagx6EDRigQIXJVnfrI0ratA==} + engines: {node: '>=v18'} + + '@commitlint/load@19.2.0': + resolution: {integrity: sha512-XvxxLJTKqZojCxaBQ7u92qQLFMMZc4+p9qrIq/9kJDy8DOrEa7P1yx7Tjdc2u2JxIalqT4KOGraVgCE7eCYJyQ==} + engines: {node: '>=v18'} + + '@commitlint/message@19.0.0': + resolution: {integrity: sha512-c9czf6lU+9oF9gVVa2lmKaOARJvt4soRsVmbR7Njwp9FpbBgste5i7l/2l5o8MmbwGh4yE1snfnsy2qyA2r/Fw==} + engines: {node: '>=v18'} + + '@commitlint/parse@19.0.3': + resolution: {integrity: sha512-Il+tNyOb8VDxN3P6XoBBwWJtKKGzHlitEuXA5BP6ir/3loWlsSqDr5aecl6hZcC/spjq4pHqNh0qPlfeWu38QA==} + engines: {node: '>=v18'} + + '@commitlint/read@19.2.1': + resolution: {integrity: sha512-qETc4+PL0EUv7Q36lJbPG+NJiBOGg7SSC7B5BsPWOmei+Dyif80ErfWQ0qXoW9oCh7GTpTNRoaVhiI8RbhuaNw==} + engines: {node: '>=v18'} + + '@commitlint/resolve-extends@19.1.0': + resolution: {integrity: sha512-z2riI+8G3CET5CPgXJPlzftH+RiWYLMYv4C9tSLdLXdr6pBNimSKukYP9MS27ejmscqCTVA4almdLh0ODD2KYg==} + engines: {node: '>=v18'} + + '@commitlint/rules@19.0.3': + resolution: {integrity: sha512-TspKb9VB6svklxNCKKwxhELn7qhtY1rFF8ls58DcFd0F97XoG07xugPjjbVnLqmMkRjZDbDIwBKt9bddOfLaPw==} + engines: {node: '>=v18'} + + '@commitlint/to-lines@19.0.0': + resolution: {integrity: sha512-vkxWo+VQU5wFhiP9Ub9Sre0FYe019JxFikrALVoD5UGa8/t3yOJEpEhxC5xKiENKKhUkTpEItMTRAjHw2SCpZw==} + engines: {node: '>=v18'} + + '@commitlint/top-level@19.0.0': + resolution: {integrity: sha512-KKjShd6u1aMGNkCkaX4aG1jOGdn7f8ZI8TR1VEuNqUOjWTOdcDSsmglinglJ18JTjuBX5I1PtjrhQCRcixRVFQ==} + engines: {node: '>=v18'} + + '@commitlint/types@19.0.3': + resolution: {integrity: sha512-tpyc+7i6bPG9mvaBbtKUeghfyZSDgWquIDfMgqYtTbmZ9Y9VzEm2je9EYcQ0aoz5o7NvGS+rcDec93yO08MHYA==} + engines: {node: '>=v18'} + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.23.0': + resolution: {integrity: sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.23.0': + resolution: {integrity: sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.23.0': + resolution: {integrity: sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.23.0': + resolution: {integrity: sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.23.0': + resolution: {integrity: sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.23.0': + resolution: {integrity: sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.23.0': + resolution: {integrity: sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.23.0': + resolution: {integrity: sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.23.0': + resolution: {integrity: sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.23.0': + resolution: {integrity: sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.23.0': + resolution: {integrity: sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.23.0': + resolution: {integrity: sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.23.0': + resolution: {integrity: sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.23.0': + resolution: {integrity: sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.23.0': + resolution: {integrity: sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.23.0': + resolution: {integrity: sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.23.0': + resolution: {integrity: sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.23.0': + resolution: {integrity: sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.23.0': + resolution: {integrity: sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.23.0': + resolution: {integrity: sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.23.0': + resolution: {integrity: sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.23.0': + resolution: {integrity: sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.23.0': + resolution: {integrity: sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.23.0': + resolution: {integrity: sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.4.0': + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.10.1': + resolution: {integrity: sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@eslint/js@8.57.0': + resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@exodus/schemasafe@1.3.0': + resolution: {integrity: sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==} + + '@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==} + engines: {node: '>=12.22'} + + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jest/types@26.6.2': + resolution: {integrity: sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==} + engines: {node: '>= 10.14.2'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.4.15': + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@pkgr/core@0.1.1': + resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + + '@types/conventional-commits-parser@5.0.0': + resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==} + + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + + '@types/jest@26.0.24': + resolution: {integrity: sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w==} + + '@types/js-yaml@4.0.9': + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/lodash@4.17.5': + resolution: {integrity: sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw==} + + '@types/mocha@10.0.6': + resolution: {integrity: sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==} + + '@types/node-fetch@2.6.11': + resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==} + + '@types/node@18.19.34': + resolution: {integrity: sha512-eXF4pfBNV5DAMKGbI02NnDtWrQ40hAN558/2vvS4gMpMIxaf6JmD7YjnZbq0Q9TDSSkKBamime8ewRoomHdt4g==} + + '@types/parse-json@4.0.2': + resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + + '@types/serialize-javascript@5.0.4': + resolution: {integrity: sha512-Z2R7UKFuNWCP8eoa2o9e5rkD3hmWxx/1L0CYz0k2BZzGh0PhEVMp9kfGiqEml/0IglwNERXZ2hwNzIrSz/KHTA==} + + '@types/swagger2openapi@7.0.4': + resolution: {integrity: sha512-ffMqzciTDihOKH4Q//9Ond1yb5JP1P5FC/aFPsLK4blea1Fwk2aYctiNCkAh5etDYFswFXS+5LV/vuGkf+PU6A==} + + '@types/vscode@1.90.0': + resolution: {integrity: sha512-oT+ZJL7qHS9Z8bs0+WKf/kQ27qWYR3trsXpq46YDjFqBsMLG4ygGGjPaJ2tyrH0wJzjOEmDyg9PDJBBhWg9pkQ==} + + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@15.0.19': + resolution: {integrity: sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA==} + + '@typescript-eslint/eslint-plugin@7.13.0': + resolution: {integrity: sha512-FX1X6AF0w8MdVFLSdqwqN/me2hyhuQg4ykN6ZpVhh1ij/80pTvDKclX1sZB9iqex8SjQfVhwMKs3JtnnMLzG9w==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + '@typescript-eslint/parser': ^7.0.0 + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@7.13.0': + resolution: {integrity: sha512-EjMfl69KOS9awXXe83iRN7oIEXy9yYdqWfqdrFAYAAr6syP8eLEFI7ZE4939antx2mNgPRW/o1ybm2SFYkbTVA==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@7.13.0': + resolution: {integrity: sha512-ZrMCe1R6a01T94ilV13egvcnvVJ1pxShkE0+NDjDzH4nvG1wXpwsVI5bZCvE7AEDH1mXEx5tJSVR68bLgG7Dng==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/type-utils@7.13.0': + resolution: {integrity: sha512-xMEtMzxq9eRkZy48XuxlBFzpVMDurUAfDu5Rz16GouAtXm0TaAoTFzqWUFPPuQYXI/CDaH/Bgx/fk/84t/Bc9A==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@7.13.0': + resolution: {integrity: sha512-QWuwm9wcGMAuTsxP+qz6LBBd3Uq8I5Nv8xb0mk54jmNoCyDspnMvVsOxI6IsMmway5d1S9Su2+sCKv1st2l6eA==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/typescript-estree@7.13.0': + resolution: {integrity: sha512-cAvBvUoobaoIcoqox1YatXOnSl3gx92rCZoMRPzMNisDiM12siGilSM4+dJAekuuHTibI2hVC2fYK79iSFvWjw==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@7.13.0': + resolution: {integrity: sha512-jceD8RgdKORVnB4Y6BqasfIkFhl4pajB1wVxrF4akxD2QPM8GNYjgGwEzYS+437ewlqqrg7Dw+6dhdpjMpeBFQ==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + + '@typescript-eslint/visitor-keys@7.13.0': + resolution: {integrity: sha512-nxn+dozQx+MK61nn/JP+M4eCkHDSxSLDpgE3WcQo0+fkjEolnaB5jswvIKC4K56By8MMgIho7f1PVxERHEo8rw==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@ungap/structured-clone@1.2.0': + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + + '@vscode/test-cli@0.0.9': + resolution: {integrity: sha512-vsl5/ueE3Jf0f6XzB0ECHHMsd5A0Yu6StElb8a+XsubZW7kHNAOw4Y3TSSuDzKEpLnJ92nbMy1Zl+KLGCE6NaA==} + engines: {node: '>=18'} + hasBin: true + + '@vscode/test-electron@2.4.0': + resolution: {integrity: sha512-yojuDFEjohx6Jb+x949JRNtSn6Wk2FAh4MldLE3ck9cfvCqzwxF32QsNy1T9Oe4oT+ZfFcg0uPUCajJzOmPlTA==} + engines: {node: '>=16'} + + '@vscode/vsce-sign-alpine-arm64@2.0.2': + resolution: {integrity: sha512-E80YvqhtZCLUv3YAf9+tIbbqoinWLCO/B3j03yQPbjT3ZIHCliKZlsy1peNc4XNZ5uIb87Jn0HWx/ZbPXviuAQ==} + cpu: [arm64] + os: [alpine] + + '@vscode/vsce-sign-alpine-x64@2.0.2': + resolution: {integrity: sha512-n1WC15MSMvTaeJ5KjWCzo0nzjydwxLyoHiMJHu1Ov0VWTZiddasmOQHekA47tFRycnt4FsQrlkSCTdgHppn6bw==} + cpu: [x64] + os: [alpine] + + '@vscode/vsce-sign-darwin-arm64@2.0.2': + resolution: {integrity: sha512-rz8F4pMcxPj8fjKAJIfkUT8ycG9CjIp888VY/6pq6cuI2qEzQ0+b5p3xb74CJnBbSC0p2eRVoe+WgNCAxCLtzQ==} + cpu: [arm64] + os: [darwin] + + '@vscode/vsce-sign-darwin-x64@2.0.2': + resolution: {integrity: sha512-MCjPrQ5MY/QVoZ6n0D92jcRb7eYvxAujG/AH2yM6lI0BspvJQxp0o9s5oiAM9r32r9tkLpiy5s2icsbwefAQIw==} + cpu: [x64] + os: [darwin] + + '@vscode/vsce-sign-linux-arm64@2.0.2': + resolution: {integrity: sha512-Ybeu7cA6+/koxszsORXX0OJk9N0GgfHq70Wqi4vv2iJCZvBrOWwcIrxKjvFtwyDgdeQzgPheH5nhLVl5eQy7WA==} + cpu: [arm64] + os: [linux] + + '@vscode/vsce-sign-linux-arm@2.0.2': + resolution: {integrity: sha512-Fkb5jpbfhZKVw3xwR6t7WYfwKZktVGNXdg1m08uEx1anO0oUPUkoQRsNm4QniL3hmfw0ijg00YA6TrxCRkPVOQ==} + cpu: [arm] + os: [linux] + + '@vscode/vsce-sign-linux-x64@2.0.2': + resolution: {integrity: sha512-NsPPFVtLaTlVJKOiTnO8Cl78LZNWy0Q8iAg+LlBiCDEgC12Gt4WXOSs2pmcIjDYzj2kY4NwdeN1mBTaujYZaPg==} + cpu: [x64] + os: [linux] + + '@vscode/vsce-sign-win32-arm64@2.0.2': + resolution: {integrity: sha512-wPs848ymZ3Ny+Y1Qlyi7mcT6VSigG89FWQnp2qRYCyMhdJxOpA4lDwxzlpL8fG6xC8GjQjGDkwbkWUcCobvksQ==} + cpu: [arm64] + os: [win32] + + '@vscode/vsce-sign-win32-x64@2.0.2': + resolution: {integrity: sha512-pAiRN6qSAhDM5SVOIxgx+2xnoVUePHbRNC7OD2aOR3WltTKxxF25OfpK8h8UQ7A0BuRkSgREbB59DBlFk4iAeg==} + cpu: [x64] + os: [win32] + + '@vscode/vsce-sign@2.0.4': + resolution: {integrity: sha512-0uL32egStKYfy60IqnynAChMTbL0oqpqk0Ew0YHiIb+fayuGZWADuIPHWUcY1GCnAA+VgchOPDMxnc2R3XGWEA==} + + '@vscode/vsce@2.30.0': + resolution: {integrity: sha512-MBYpXdCY1SCdc2u/y11kmJuSODKFyZRpeRTQq5p4rSg05QSjSy5pz6h/BGLNdSahgXfKRBATEkjAcJFdJuDz8Q==} + engines: {node: '>= 16'} + hasBin: true + + '@vue/compiler-core@3.4.31': + resolution: {integrity: sha512-skOiodXWTV3DxfDhB4rOf3OGalpITLlgCeOwb+Y9GJpfQ8ErigdBUHomBzvG78JoVE8MJoQsb+qhZiHfKeNeEg==} + + '@vue/compiler-dom@3.4.31': + resolution: {integrity: sha512-wK424WMXsG1IGMyDGyLqB+TbmEBFM78hIsOJ9QwUVLGrcSk0ak6zYty7Pj8ftm7nEtdU/DGQxAXp0/lM/2cEpQ==} + + '@vue/compiler-sfc@3.4.31': + resolution: {integrity: sha512-einJxqEw8IIJxzmnxmJBuK2usI+lJonl53foq+9etB2HAzlPjAS/wa7r0uUpXw5ByX3/0uswVSrjNb17vJm1kQ==} + + '@vue/compiler-ssr@3.4.31': + resolution: {integrity: sha512-RtefmITAje3fJ8FSg1gwgDhdKhZVntIVbwupdyZDSifZTRMiWxWehAOTCc8/KZDnBOcYQ4/9VWxsTbd3wT0hAA==} + + '@vue/reactivity@3.4.31': + resolution: {integrity: sha512-VGkTani8SOoVkZNds1PfJ/T1SlAIOf8E58PGAhIOUDYPC4GAmFA2u/E14TDAFcf3vVDKunc4QqCe/SHr8xC65Q==} + + '@vue/runtime-core@3.4.31': + resolution: {integrity: sha512-LDkztxeUPazxG/p8c5JDDKPfkCDBkkiNLVNf7XZIUnJ+66GVGkP+TIh34+8LtPisZ+HMWl2zqhIw0xN5MwU1cw==} + + '@vue/runtime-dom@3.4.31': + resolution: {integrity: sha512-2Auws3mB7+lHhTFCg8E9ZWopA6Q6L455EcU7bzcQ4x6Dn4cCPuqj6S2oBZgN2a8vJRS/LSYYxwFFq2Hlx3Fsaw==} + + '@vue/server-renderer@3.4.31': + resolution: {integrity: sha512-D5BLbdvrlR9PE3by9GaUp1gQXlCNadIZytMIb8H2h3FMWJd4oUfkUTEH2wAr3qxoRz25uxbTcbqd3WKlm9EHQA==} + peerDependencies: + vue: 3.4.31 + + '@vue/shared@3.4.31': + resolution: {integrity: sha512-Yp3wtJk//8cO4NItOPpi3QkLExAr/aLBGZMmTtW9WpdwBCJpRM6zj9WgWktXAl8IDIozwNMByT45JP3tO3ACWA==} + + JSONStream@1.3.5: + resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} + hasBin: true + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@7.1.1: + resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} + engines: {node: '>= 14'} + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ajv@8.16.0: + resolution: {integrity: sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==} + + alova@2.21.3: + resolution: {integrity: sha512-JJ62QB0yQUnZ2hGbXUQzhWRt6h9DLvt8q77Q1M/gnc//oTX2xSBxdw29c6FLs13KhmjCG6pb8OjoiJq6dkUO4w==} + engines: {node: '>= 0.12.0'} + + alova@3.0.0-beta.10: + resolution: {integrity: sha512-QtKFMdt2MO18cSfTLef6I+xPPexdoW3gUczOJqUNMXz/6K5VT7rKfheQfW0+9stvMTPBKBRMKR1gkyG7pmPDQw==} + engines: {node: '>= 18.0.0'} + + alova@3.0.5: + resolution: {integrity: sha512-cOE2nTPOp7sXLhf9cthdh90lT389C1akgJULMytuFeV1loriJr1YbT3LCw3qb/P3N+o/QtJ9WLH2ccr0vJ380A==} + engines: {node: '>= 18.0.0'} + + ansi-colors@4.1.1: + resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} + engines: {node: '>=6'} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-escapes@6.2.1: + resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==} + engines: {node: '>=14.16'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + + array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} + + array-ify@1.0.0: + resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} + + array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.5: + resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} + engines: {node: '>= 0.4'} + + array.prototype.toreversed@1.1.2: + resolution: {integrity: sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==} + + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} + + ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + at-least-node@1.0.0: + resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} + engines: {node: '>= 4.0.0'} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axe-core@4.7.0: + resolution: {integrity: sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==} + engines: {node: '>=4'} + + axobject-query@3.2.1: + resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==} + + azure-devops-node-api@12.5.0: + resolution: {integrity: sha512-R5eFskGvOm3U/GzeAuxRkUsAl0hrAwGgWn6zAd2KrZmrEhWZVqLew4OOupbQlXUuojUzpGtq62SmdhJ06N88og==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + bl@5.1.0: + resolution: {integrity: sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browser-stdout@1.3.1: + resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + + buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + c8@9.1.0: + resolution: {integrity: sha512-mBWcT5iqNir1zIkzSPyI3NCR9EZCVI3WUD+AVO17MVWTSFNyUueXE82qTeampNtTr+ilN/5Ua3j24LgbCKjDVg==} + engines: {node: '>=14.14.0'} + hasBin: true + + cachedir@2.3.0: + resolution: {integrity: sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==} + engines: {node: '>=6'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + call-me-maybe@1.0.2: + resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camel-case@4.1.2: + resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + capital-case@1.0.4: + resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + change-case@4.1.2: + resolution: {integrity: sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==} + + chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.0.0-rc.12: + resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} + engines: {node: '>= 6'} + + chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + + cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + + cli-cursor@4.0.0: + resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + + cli-truncate@4.0.0: + resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} + engines: {node: '>=18'} + + cli-width@3.0.0: + resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} + engines: {node: '>= 10'} + + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + + cockatiel@3.1.3: + resolution: {integrity: sha512-xC759TpZ69d7HhfDp8m2WkRwEUiCkxY8Ee2OQH/3H6zmy2D/5Sm+zSTbPRa+V2QyjDtpMvjOIAOVjA2gp6N1kQ==} + engines: {node: '>=16'} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + + commander@6.2.1: + resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} + engines: {node: '>= 6'} + + commitizen@4.3.0: + resolution: {integrity: sha512-H0iNtClNEhT0fotHvGV3E9tDejDeS04sN1veIebsKYGMuGscFaswRoYJKmT3eW85eIJAs0F28bG2+a/9wCOfPw==} + engines: {node: '>= 12'} + hasBin: true + + compare-func@2.0.0: + resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + confusing-browser-globals@1.0.11: + resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} + + constant-case@3.0.4: + resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==} + + conventional-changelog-angular@7.0.0: + resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} + engines: {node: '>=16'} + + conventional-changelog-conventionalcommits@7.0.2: + resolution: {integrity: sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==} + engines: {node: '>=16'} + + conventional-commit-types@3.0.0: + resolution: {integrity: sha512-SmmCYnOniSsAa9GqWOeLqc179lfr5TRu5b4QFDkbsrJ5TZjPJx85wtOr3zn+1dbeNiXDKGPbZ72IKbPhLXh/Lg==} + + conventional-commits-parser@5.0.0: + resolution: {integrity: sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==} + engines: {node: '>=16'} + hasBin: true + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cosmiconfig-typescript-loader@5.0.0: + resolution: {integrity: sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==} + engines: {node: '>=v16'} + peerDependencies: + '@types/node': '*' + cosmiconfig: '>=8.2' + typescript: '>=4' + + cosmiconfig@6.0.0: + resolution: {integrity: sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==} + engines: {node: '>=8'} + + cosmiconfig@9.0.0: + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + + cross-spawn@6.0.5: + resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} + engines: {node: '>=4.8'} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + css-select@5.1.0: + resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + cz-conventional-changelog@3.3.0: + resolution: {integrity: sha512-U466fIzU5U22eES5lTNiNbZ+d8dfcHcssH4o7QsdWaCcRs/feIPCxKYSWkYBNs5mny7MvEfwpTLWjvbm94hecw==} + engines: {node: '>= 10'} + + damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + + dargs@8.1.0: + resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==} + engines: {node: '>=12'} + + data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.5: + resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize@4.0.0: + resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} + engines: {node: '>=10'} + + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + dedent@0.7.0: + resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + detect-file@1.0.0: + resolution: {integrity: sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==} + engines: {node: '>=0.10.0'} + + detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + + detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + engines: {node: '>=8'} + + diff-sequences@26.6.2: + resolution: {integrity: sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==} + engines: {node: '>= 10.14.2'} + + diff@5.0.0: + resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} + engines: {node: '>=0.3.1'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.1.0: + resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + + dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + + dot-prop@5.3.0: + resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} + engines: {node: '>=8'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + + emoji-regex@10.3.0: + resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + + enhanced-resolve@5.17.0: + resolution: {integrity: sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==} + engines: {node: '>=10.13.0'} + + entities@2.1.0: + resolution: {integrity: sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + + es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-iterator-helpers@1.0.19: + resolution: {integrity: sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + + es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + + es6-promise@3.3.1: + resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==} + + esbuild-plugin-alias@0.2.1: + resolution: {integrity: sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ==} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + esbuild@0.23.0: + resolution: {integrity: sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-airbnb-base@15.0.0: + resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + eslint: ^7.32.0 || ^8.2.0 + eslint-plugin-import: ^2.25.2 + + eslint-config-airbnb-typescript@18.0.0: + resolution: {integrity: sha512-oc+Lxzgzsu8FQyFVa4QFaVKiitTYiiW3frB9KYW5OWdPrqFc7FzxgB20hP4cHMlr+MBzGcLl3jnCOVOydL9mIg==} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^7.0.0 + '@typescript-eslint/parser': ^7.0.0 + eslint: ^8.56.0 + + eslint-config-airbnb@19.0.4: + resolution: {integrity: sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==} + engines: {node: ^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.32.0 || ^8.2.0 + eslint-plugin-import: ^2.25.3 + eslint-plugin-jsx-a11y: ^6.5.1 + eslint-plugin-react: ^7.28.0 + eslint-plugin-react-hooks: ^4.3.0 + + eslint-config-prettier@9.1.0: + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-module-utils@2.8.1: + resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.29.1: + resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-jsx-a11y@6.8.0: + resolution: {integrity: sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + + eslint-plugin-prettier@5.1.3: + resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '*' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true + + eslint-plugin-react-hooks@4.6.2: + resolution: {integrity: sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + + eslint-plugin-react@7.34.2: + resolution: {integrity: sha512-2HCmrU+/JNigDN6tg55cRDKCQWicYAPB38JGSFDQt95jDm8rrvSUo7YPkOIm5l6ts1j1zCvysNcasvfTMQzUOw==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint@8.57.0: + resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + 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} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + + expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + + expand-tilde@2.0.2: + resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==} + engines: {node: '>=0.10.0'} + + external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + + figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-node-modules@2.1.3: + resolution: {integrity: sha512-UC2I2+nx1ZuOBclWVNdcnbDR5dlrOdVb7xNjmT/lHE+LsgztWks3dG7boJ37yTS/venXw84B/mAW9uHVoC5QRg==} + + find-root@1.1.0: + resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + find-up@7.0.0: + resolution: {integrity: sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==} + engines: {node: '>=18'} + + findup-sync@4.0.0: + resolution: {integrity: sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==} + engines: {node: '>= 8'} + + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + + foreground-child@3.2.0: + resolution: {integrity: sha512-CrWQNaEl1/6WeZoarcM9LHupTo3RpZO2Pdk1vktwzPiQTsJnAKJmm3TACKeG5UZbWDfaH2AbvYxzP96y0MT7fA==} + engines: {node: '>=14'} + + form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fs-extra@9.1.0: + resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} + engines: {node: '>=10'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.2.0: + resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} + engines: {node: '>=18'} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + + get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.7.5: + resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} + + git-raw-commits@4.0.0: + resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} + engines: {node: '>=16'} + hasBin: true + + github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@10.4.1: + resolution: {integrity: sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==} + engines: {node: '>=16 || 14 >=14.18'} + hasBin: true + + 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-directory@4.0.1: + resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} + engines: {node: '>=18'} + + global-modules@1.0.0: + resolution: {integrity: sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==} + engines: {node: '>=0.10.0'} + + global-prefix@1.0.2: + resolution: {integrity: sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==} + engines: {node: '>=0.10.0'} + + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true + + has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + header-case@2.0.4: + resolution: {integrity: sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==} + + homedir-polyfill@1.0.3: + resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} + engines: {node: '>=0.10.0'} + + hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + + hosted-git-info@4.1.0: + resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} + engines: {node: '>=10'} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + htmlparser2@8.0.2: + resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + http2-client@1.3.5: + resolution: {integrity: sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==} + + https-proxy-agent@7.0.4: + resolution: {integrity: sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==} + engines: {node: '>= 14'} + + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + husky@9.0.11: + resolution: {integrity: sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==} + engines: {node: '>=18'} + hasBin: true + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + + immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + import-meta-resolve@4.1.0: + resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + 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.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ini@4.1.1: + resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + inquirer@8.2.5: + resolution: {integrity: sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==} + engines: {node: '>=12.0.0'} + + internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-async-function@2.0.0: + resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} + engines: {node: '>= 0.4'} + + is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + + is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + + is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.0.2: + resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-fullwidth-code-point@4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + + is-fullwidth-code-point@5.0.0: + resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} + engines: {node: '>=18'} + + is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-interactive@1.0.0: + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} + + is-interactive@2.0.0: + resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} + engines: {node: '>=12'} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + + is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + + is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + + is-text-path@2.0.0: + resolution: {integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==} + engines: {node: '>=8'} + + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + is-unicode-supported@1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + + is-url@1.2.4: + resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} + + is-utf8@0.2.1: + resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + + is-weakset@2.0.3: + resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} + engines: {node: '>= 0.4'} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + + iterator.prototype@1.1.2: + resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} + + jackspeak@3.4.0: + resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==} + engines: {node: '>=14'} + + jest-diff@26.6.2: + resolution: {integrity: sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==} + engines: {node: '>= 10.14.2'} + + jest-get-type@26.3.0: + resolution: {integrity: sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==} + engines: {node: '>= 10.14.2'} + + jiti@1.21.6: + resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} + hasBin: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-better-errors@1.0.2: + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + + jsonwebtoken@9.0.2: + resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} + engines: {node: '>=12', npm: '>=6'} + + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + + jszip@3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + + jwa@1.4.1: + resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} + + jwa@2.0.0: + resolution: {integrity: sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==} + + jws@3.2.2: + resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} + + jws@4.0.0: + resolution: {integrity: sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==} + + keytar@7.9.0: + resolution: {integrity: sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + language-subtag-registry@0.3.23: + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} + + language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + + lilconfig@3.1.2: + resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + linkify-it@3.0.3: + resolution: {integrity: sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==} + + lint-staged@15.2.7: + resolution: {integrity: sha512-+FdVbbCZ+yoh7E/RosSdqKJyUM2OEjTciH0TFNkawKgvFp1zbGlEC39RADg+xKBG1R4mhoH2j85myBQZ5wR+lw==} + engines: {node: '>=18.12.0'} + hasBin: true + + listr2@8.2.1: + resolution: {integrity: sha512-irTfvpib/rNiD637xeevjO2l3Z5loZmuaRi0L0YE5LfijwVY96oyVn0DFD3o/teAok7nfobMG1THvvcHh/BP6g==} + engines: {node: '>=18.0.0'} + + load-json-file@4.0.0: + resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} + engines: {node: '>=4'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + + lodash.includes@4.3.0: + resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} + + lodash.isboolean@3.0.3: + resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + + lodash.isinteger@4.0.4: + resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + + lodash.isnumber@3.0.3: + resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + + lodash.kebabcase@4.1.1: + resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} + + lodash.map@4.6.0: + resolution: {integrity: sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.mergewith@4.6.2: + resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} + + lodash.once@4.1.1: + resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + + lodash.snakecase@4.1.1: + resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} + + lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + + lodash.upperfirst@4.3.1: + resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + log-symbols@5.1.0: + resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==} + engines: {node: '>=12'} + + log-update@6.0.0: + resolution: {integrity: sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==} + engines: {node: '>=18'} + + longest@2.0.1: + resolution: {integrity: sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==} + engines: {node: '>=0.10.0'} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + + lru-cache@10.2.2: + resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} + engines: {node: 14 || >=16.14} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + markdown-it@12.3.2: + resolution: {integrity: sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==} + hasBin: true + + mdurl@1.0.1: + resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} + + memorystream@0.3.1: + resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} + engines: {node: '>= 0.10.0'} + + meow@12.1.1: + resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} + engines: {node: '>=16.10'} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + merge@2.1.1: + resolution: {integrity: sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==} + + micromatch@4.0.7: + resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@5.0.1: + resolution: {integrity: sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==} + engines: {node: '>=10'} + + minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.7: + resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + + mocha@10.4.0: + resolution: {integrity: sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==} + engines: {node: '>= 14.0.0'} + hasBin: true + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mute-stream@0.0.8: + resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + napi-build-utils@1.0.2: + resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + nice-try@1.0.5: + resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + + no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + + node-abi@3.65.0: + resolution: {integrity: sha512-ThjYBfoDNr08AWx6hGaRbfPwxKV9kVzAzOzlLKbk2CuqXE2xnCh+cbAGnwM3t8Lq4v9rUB7VfondlkBckcJrVA==} + engines: {node: '>=10'} + + node-addon-api@4.3.0: + resolution: {integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==} + + node-fetch-h2@2.3.0: + resolution: {integrity: sha512-ofRW94Ab0T4AOh5Fk8t0h8OBWrmjb0SSB20xh1H8YnPV9EJ+f5AMoYSUQ2zgJ4Iq2HAK0I2l5/Nequ8YzFS3Hg==} + engines: {node: 4.x || >=6.0.0} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-readfiles@0.2.0: + resolution: {integrity: sha512-SU00ZarexNlE4Rjdm83vglt5Y9yiQ+XI1XpflWlb7q7UTN1JUItm69xMeiQCTxtTfnzt+83T8Cx+vI2ED++VDA==} + + normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + npm-run-all@4.1.5: + resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==} + engines: {node: '>= 4'} + hasBin: true + + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + oas-kit-common@1.0.8: + resolution: {integrity: sha512-pJTS2+T0oGIwgjGpw7sIRU8RQMcUoKCDWFLdBqKB2BNmGpbBMH2sdqAaOXUg8OzonZHU0L7vfJu1mJFEiYDWOQ==} + + oas-linter@3.2.2: + resolution: {integrity: sha512-KEGjPDVoU5K6swgo9hJVA/qYGlwfbFx+Kg2QB/kd7rzV5N8N5Mg6PlsoCMohVnQmo+pzJap/F610qTodKzecGQ==} + + oas-resolver@2.5.6: + resolution: {integrity: sha512-Yx5PWQNZomfEhPPOphFbZKi9W93CocQj18NlD2Pa4GWZzdZpSJvYwoiuurRI7m3SpcChrnO08hkuQDL3FGsVFQ==} + hasBin: true + + oas-schema-walker@1.1.5: + resolution: {integrity: sha512-2yucenq1a9YPmeNExoUa9Qwrt9RFkjqaMAA1X+U7sbb0AqBeTIdMHky9SQQ6iN94bO5NW0W4TRYXerG+BdAvAQ==} + + oas-validator@5.0.8: + resolution: {integrity: sha512-cu20/HE5N5HKqVygs3dt94eYJfBi0TsZvPVXDhbXQHiEityDN+RROTleefoKRKKJ9dFAF2JBkDHgvWj0sjKGmw==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-hash@2.2.0: + resolution: {integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==} + engines: {node: '>= 6'} + + object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + + object.entries@1.1.8: + resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.hasown@1.1.4: + resolution: {integrity: sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==} + engines: {node: '>= 0.4'} + + object.values@1.2.0: + resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} + engines: {node: '>= 0.4'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + + openapi-types@12.1.3: + resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} + + openapi@1.0.1: + resolution: {integrity: sha512-hiQ6/K2Q2eFqlOoPQb8V2hzsVsbv31ipMCKfuwZQmqf+MnLzVUcYMBy0h/Y+Sv/HeDCTN4mf0GoOmET4EoJS8A==} + hasBin: true + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + ora@5.4.1: + resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} + engines: {node: '>=10'} + + ora@7.0.1: + resolution: {integrity: sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw==} + engines: {node: '>=16'} + + os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + + param-case@3.0.4: + resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-json@4.0.0: + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} + engines: {node: '>=4'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse-passwd@1.0.0: + resolution: {integrity: sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==} + engines: {node: '>=0.10.0'} + + parse-semver@1.1.1: + resolution: {integrity: sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ==} + + parse5-htmlparser2-tree-adapter@7.0.0: + resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} + + parse5@7.1.2: + resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + + pascal-case@3.1.2: + resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + + path-case@3.0.4: + resolution: {integrity: sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@2.0.1: + resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} + engines: {node: '>=4'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-type@3.0.0: + resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} + engines: {node: '>=4'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pidtree@0.3.1: + resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==} + engines: {node: '>=0.10'} + hasBin: true + + pidtree@0.6.0: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} + engines: {node: '>=0.10'} + hasBin: true + + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + + postcss@8.4.39: + resolution: {integrity: sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==} + engines: {node: ^10 || ^12 || >=14} + + prebuild-install@7.1.2: + resolution: {integrity: sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==} + engines: {node: '>=10'} + hasBin: true + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} + + prettier-plugin-organize-imports@3.2.4: + resolution: {integrity: sha512-6m8WBhIp0dfwu0SkgfOxJqh+HpdyfqSSLfKKRZSFbDuEQXDDndb8fTpRWkUrX/uBenkex3MgnVk0J3b3Y5byog==} + peerDependencies: + '@volar/vue-language-plugin-pug': ^1.0.4 + '@volar/vue-typescript': ^1.0.4 + prettier: '>=2.0' + typescript: '>=2.9' + peerDependenciesMeta: + '@volar/vue-language-plugin-pug': + optional: true + '@volar/vue-typescript': + optional: true + + prettier-plugin-sort-json@4.0.0: + resolution: {integrity: sha512-zV5g+bWFD2zAqyQ8gCkwUTC49o9FxslaUdirwivt5GZHcf57hCocavykuyYqbExoEsuBOg8IU36OY7zmVEMOWA==} + engines: {node: '>=18.0.0'} + peerDependencies: + prettier: ^3.0.0 + + prettier@3.3.2: + resolution: {integrity: sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==} + engines: {node: '>=14'} + hasBin: true + + pretty-format@26.6.2: + resolution: {integrity: sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==} + engines: {node: '>= 10'} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qs@6.12.3: + resolution: {integrity: sha512-AWJm14H1vVaO/iNZ4/hO+HyaTehuy9nRqVdkTqlJt0HWvBiBIEXFmb4C0DGeYo3Xes9rrEW+TxHsaigCbN5ICQ==} + engines: {node: '>=0.6'} + + querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + rate-limiter-flexible@5.0.3: + resolution: {integrity: sha512-lWx2y8NBVlTOLPyqs+6y7dxfEpT6YFqKy3MzWbCy95sTTOhOuxufP2QvRyOHpfXpB9OUJPbVLybw3z3AVAS5fA==} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + + read-pkg@3.0.0: + resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} + engines: {node: '>=4'} + + read@1.0.7: + resolution: {integrity: sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==} + engines: {node: '>=0.8'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + reflect.getprototypeof@1.0.6: + resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==} + engines: {node: '>= 0.4'} + + reftools@1.1.9: + resolution: {integrity: sha512-OVede/NQE13xBQ+ob5CKd5KyeJYU2YInb1bmV4nRoOfquZPkAkxuOXicSe1PvqIuZZ4kD13sPKBbR7UFDmli6w==} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + engines: {node: '>= 0.4'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + resolve-dir@1.0.1: + resolution: {integrity: sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==} + engines: {node: '>=0.10.0'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + + resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + + restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + + restore-cursor@4.0.0: + resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + run-async@2.4.1: + resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} + engines: {node: '>=0.12.0'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + + safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + engines: {node: '>=0.4'} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sax@1.4.1: + resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.6.2: + resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} + engines: {node: '>=10'} + hasBin: true + + sentence-case@3.0.4: + resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==} + + serialize-javascript@6.0.0: + resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + + shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.8.1: + resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} + + should-equal@2.0.0: + resolution: {integrity: sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==} + + should-format@3.0.3: + resolution: {integrity: sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==} + + should-type-adaptors@1.1.0: + resolution: {integrity: sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==} + + should-type@1.4.0: + resolution: {integrity: sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==} + + should-util@1.0.1: + resolution: {integrity: sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==} + + should@13.2.3: + resolution: {integrity: sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==} + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slice-ansi@5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + + slice-ansi@7.1.0: + resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} + engines: {node: '>=18'} + + snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.18: + resolution: {integrity: sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stdin-discarder@0.1.0: + resolution: {integrity: sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + stoppable@1.1.0: + resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} + engines: {node: '>=4', npm: '>=6'} + + string-argv@0.3.2: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + engines: {node: '>=0.6.19'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string-width@6.1.0: + resolution: {integrity: sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==} + engines: {node: '>=16'} + + string-width@7.1.0: + resolution: {integrity: sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==} + engines: {node: '>=18'} + + string.prototype.matchall@4.0.11: + resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} + engines: {node: '>= 0.4'} + + string.prototype.padend@3.1.6: + resolution: {integrity: sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==} + engines: {node: '>= 0.4'} + + string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-color@9.4.0: + resolution: {integrity: sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==} + engines: {node: '>=12'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + swagger2openapi@7.0.8: + resolution: {integrity: sha512-upi/0ZGkYgEcLeGieoz8gT74oWHA0E7JivX7aN9mAf+Tc7BQoRBvnIGHoPDw+f9TXTW4s6kGYCZJtauP6OYp7g==} + hasBin: true + + synckit@0.8.8: + resolution: {integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==} + engines: {node: ^14.18.0 || >=16.0.0} + + tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + + tar-fs@2.1.1: + resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + + text-extensions@2.4.0: + resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==} + engines: {node: '>=8'} + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + + tmp@0.2.3: + resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} + engines: {node: '>=14.14'} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + ts-api-utils@1.3.0: + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@2.6.3: + resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + + tsx@4.16.2: + resolution: {integrity: sha512-C1uWweJDgdtX2x600HjaFaucXTilT7tgUZHbOE4+ypskZ1OP8CRCSDkCxG6Vya9EwaFIVagWwpaVAn5wzypaqQ==} + engines: {node: '>=18.0.0'} + hasBin: true + + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + + tunnel@0.0.6: + resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} + engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@4.20.0: + resolution: {integrity: sha512-MBh+PHUHHisjXf4tlx0CFWoMdjx8zCMLJHOjnV1prABYZFHqtFOyauCIK2/7w4oIfwkF8iNhLtnJEfVY2vn3iw==} + engines: {node: '>=16'} + + typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} + + typed-rest-client@1.8.11: + resolution: {integrity: sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA==} + + typescript@5.4.5: + resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} + engines: {node: '>=14.17'} + hasBin: true + + uc.micro@1.0.6: + resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} + + uglify-js@3.18.0: + resolution: {integrity: sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==} + engines: {node: '>=0.8.0'} + hasBin: true + + unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + + underscore@1.13.6: + resolution: {integrity: sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==} + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + unicorn-magic@0.1.0: + resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} + engines: {node: '>=18'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + upper-case-first@2.0.2: + resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==} + + upper-case@2.0.2: + resolution: {integrity: sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + url-join@4.0.1: + resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==} + + url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + v8-to-istanbul@9.2.0: + resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} + engines: {node: '>=10.12.0'} + + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + + vue@3.4.31: + resolution: {integrity: sha512-njqRrOy7W3YLAlVqSKpBebtZpDVg21FPoaq1I7f/+qqBThK9ChAIjkRWgeP6Eat+8C+iia4P3OYqpATP21BCoQ==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + + which-builtin-type@1.1.3: + resolution: {integrity: sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + + workerpool@6.2.1: + resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrap-ansi@9.0.0: + resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} + engines: {node: '>=18'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + xml2js@0.5.0: + resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} + engines: {node: '>=4.0.0'} + + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + + yaml@2.4.5: + resolution: {integrity: sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==} + engines: {node: '>= 14'} + hasBin: true + + yargs-parser@20.2.4: + resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs-unparser@2.0.0: + resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} + engines: {node: '>=10'} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + + yazl@2.5.1: + resolution: {integrity: sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yocto-queue@1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + +snapshots: + + '@alova/adapter-xhr@2.0.0-beta.8(alova@3.0.0-beta.10)': + dependencies: + '@alova/shared': 1.0.0-beta.7 + alova: 3.0.0-beta.10 + + '@alova/adapter-xhr@2.0.0-beta.8(alova@3.0.5)': + dependencies: + '@alova/shared': 1.0.0-beta.7 + alova: 3.0.5 + + '@alova/mock@1.5.2': {} + + '@alova/mock@2.0.4(alova@3.0.5)': + dependencies: + '@alova/shared': 1.0.4 + alova: 3.0.5 + + '@alova/shared@1.0.0-beta.7': {} + + '@alova/shared@1.0.4': {} + + '@azure/abort-controller@1.1.0': + dependencies: + tslib: 2.6.3 + + '@azure/abort-controller@2.1.2': + dependencies: + tslib: 2.6.3 + + '@azure/core-auth@1.7.2': + dependencies: + '@azure/abort-controller': 2.1.2 + '@azure/core-util': 1.9.1 + tslib: 2.6.3 + + '@azure/core-client@1.9.2': + dependencies: + '@azure/abort-controller': 2.1.2 + '@azure/core-auth': 1.7.2 + '@azure/core-rest-pipeline': 1.16.2 + '@azure/core-tracing': 1.1.2 + '@azure/core-util': 1.9.1 + '@azure/logger': 1.1.3 + tslib: 2.6.3 + transitivePeerDependencies: + - supports-color + + '@azure/core-rest-pipeline@1.16.2': + dependencies: + '@azure/abort-controller': 2.1.2 + '@azure/core-auth': 1.7.2 + '@azure/core-tracing': 1.1.2 + '@azure/core-util': 1.9.1 + '@azure/logger': 1.1.3 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.4 + tslib: 2.6.3 + transitivePeerDependencies: + - supports-color + + '@azure/core-tracing@1.1.2': + dependencies: + tslib: 2.6.3 + + '@azure/core-util@1.9.1': + dependencies: + '@azure/abort-controller': 2.1.2 + tslib: 2.6.3 + + '@azure/identity@4.3.0': + dependencies: + '@azure/abort-controller': 1.1.0 + '@azure/core-auth': 1.7.2 + '@azure/core-client': 1.9.2 + '@azure/core-rest-pipeline': 1.16.2 + '@azure/core-tracing': 1.1.2 + '@azure/core-util': 1.9.1 + '@azure/logger': 1.1.3 + '@azure/msal-browser': 3.18.0 + '@azure/msal-node': 2.10.0 + events: 3.3.0 + jws: 4.0.0 + open: 8.4.2 + stoppable: 1.1.0 + tslib: 2.6.3 + transitivePeerDependencies: + - supports-color + + '@azure/logger@1.1.3': + dependencies: + tslib: 2.6.3 + + '@azure/msal-browser@3.18.0': + dependencies: + '@azure/msal-common': 14.13.0 + + '@azure/msal-common@14.13.0': {} + + '@azure/msal-node@2.10.0': + dependencies: + '@azure/msal-common': 14.13.0 + jsonwebtoken: 9.0.2 + uuid: 8.3.2 + + '@babel/code-frame@7.24.7': + dependencies: + '@babel/highlight': 7.24.7 + picocolors: 1.0.1 + + '@babel/helper-string-parser@7.24.7': {} + + '@babel/helper-validator-identifier@7.24.7': {} + + '@babel/highlight@7.24.7': + dependencies: + '@babel/helper-validator-identifier': 7.24.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.1 + + '@babel/parser@7.24.7': + dependencies: + '@babel/types': 7.24.7 + + '@babel/runtime@7.24.7': + dependencies: + regenerator-runtime: 0.14.1 + + '@babel/types@7.24.7': + dependencies: + '@babel/helper-string-parser': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 + + '@bcoe/v8-coverage@0.2.3': {} + + '@commitlint/cli@19.3.0(@types/node@18.19.34)(typescript@5.4.5)': + dependencies: + '@commitlint/format': 19.3.0 + '@commitlint/lint': 19.2.2 + '@commitlint/load': 19.2.0(@types/node@18.19.34)(typescript@5.4.5) + '@commitlint/read': 19.2.1 + '@commitlint/types': 19.0.3 + execa: 8.0.1 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - typescript + + '@commitlint/config-conventional@19.2.2': + dependencies: + '@commitlint/types': 19.0.3 + conventional-changelog-conventionalcommits: 7.0.2 + + '@commitlint/config-validator@19.0.3': + dependencies: + '@commitlint/types': 19.0.3 + ajv: 8.16.0 + + '@commitlint/ensure@19.0.3': + dependencies: + '@commitlint/types': 19.0.3 + lodash.camelcase: 4.3.0 + lodash.kebabcase: 4.1.1 + lodash.snakecase: 4.1.1 + lodash.startcase: 4.4.0 + lodash.upperfirst: 4.3.1 + + '@commitlint/execute-rule@19.0.0': {} + + '@commitlint/format@19.3.0': + dependencies: + '@commitlint/types': 19.0.3 + chalk: 5.3.0 + + '@commitlint/is-ignored@19.2.2': + dependencies: + '@commitlint/types': 19.0.3 + semver: 7.6.2 + + '@commitlint/lint@19.2.2': + dependencies: + '@commitlint/is-ignored': 19.2.2 + '@commitlint/parse': 19.0.3 + '@commitlint/rules': 19.0.3 + '@commitlint/types': 19.0.3 + + '@commitlint/load@19.2.0(@types/node@18.19.34)(typescript@5.4.5)': + dependencies: + '@commitlint/config-validator': 19.0.3 + '@commitlint/execute-rule': 19.0.0 + '@commitlint/resolve-extends': 19.1.0 + '@commitlint/types': 19.0.3 + chalk: 5.3.0 + cosmiconfig: 9.0.0(typescript@5.4.5) + cosmiconfig-typescript-loader: 5.0.0(@types/node@18.19.34)(cosmiconfig@9.0.0(typescript@5.4.5))(typescript@5.4.5) + lodash.isplainobject: 4.0.6 + lodash.merge: 4.6.2 + lodash.uniq: 4.5.0 + transitivePeerDependencies: + - '@types/node' + - typescript + + '@commitlint/message@19.0.0': {} + + '@commitlint/parse@19.0.3': + dependencies: + '@commitlint/types': 19.0.3 + conventional-changelog-angular: 7.0.0 + conventional-commits-parser: 5.0.0 + + '@commitlint/read@19.2.1': + dependencies: + '@commitlint/top-level': 19.0.0 + '@commitlint/types': 19.0.3 + execa: 8.0.1 + git-raw-commits: 4.0.0 + minimist: 1.2.8 + + '@commitlint/resolve-extends@19.1.0': + dependencies: + '@commitlint/config-validator': 19.0.3 + '@commitlint/types': 19.0.3 + global-directory: 4.0.1 + import-meta-resolve: 4.1.0 + lodash.mergewith: 4.6.2 + resolve-from: 5.0.0 + + '@commitlint/rules@19.0.3': + dependencies: + '@commitlint/ensure': 19.0.3 + '@commitlint/message': 19.0.0 + '@commitlint/to-lines': 19.0.0 + '@commitlint/types': 19.0.3 + execa: 8.0.1 + + '@commitlint/to-lines@19.0.0': {} + + '@commitlint/top-level@19.0.0': + dependencies: + find-up: 7.0.0 + + '@commitlint/types@19.0.3': + dependencies: + '@types/conventional-commits-parser': 5.0.0 + chalk: 5.3.0 + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/aix-ppc64@0.23.0': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.23.0': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-arm@0.23.0': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/android-x64@0.23.0': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.23.0': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.23.0': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.23.0': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.23.0': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.23.0': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-arm@0.23.0': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.23.0': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.23.0': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.23.0': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.23.0': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.23.0': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.23.0': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/linux-x64@0.23.0': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.23.0': + optional: true + + '@esbuild/openbsd-arm64@0.23.0': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.23.0': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.23.0': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.23.0': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.23.0': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@esbuild/win32-x64@0.23.0': + optional: true + + '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)': + dependencies: + eslint: 8.57.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.10.1': {} + + '@eslint/eslintrc@2.1.4': + dependencies: + ajv: 6.12.6 + debug: 4.3.5 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@8.57.0': {} + + '@exodus/schemasafe@1.3.0': {} + + '@humanwhocodes/config-array@0.11.14': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.3.5 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/object-schema@2.0.3': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@istanbuljs/schema@0.1.3': {} + + '@jest/types@26.6.2': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 18.19.34 + '@types/yargs': 15.0.19 + chalk: 4.1.2 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@pkgr/core@0.1.1': {} + + '@types/conventional-commits-parser@5.0.0': + dependencies: + '@types/node': 18.19.34 + + '@types/istanbul-lib-coverage@2.0.6': {} + + '@types/istanbul-lib-report@3.0.3': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + + '@types/istanbul-reports@3.0.4': + dependencies: + '@types/istanbul-lib-report': 3.0.3 + + '@types/jest@26.0.24': + dependencies: + jest-diff: 26.6.2 + pretty-format: 26.6.2 + + '@types/js-yaml@4.0.9': {} + + '@types/json5@0.0.29': {} + + '@types/lodash@4.17.5': {} + + '@types/mocha@10.0.6': {} + + '@types/node-fetch@2.6.11': + dependencies: + '@types/node': 18.19.34 + form-data: 4.0.0 + + '@types/node@18.19.34': + dependencies: + undici-types: 5.26.5 + + '@types/parse-json@4.0.2': {} + + '@types/serialize-javascript@5.0.4': {} + + '@types/swagger2openapi@7.0.4': + dependencies: + '@types/node': 18.19.34 + openapi-types: 12.1.3 + + '@types/vscode@1.90.0': {} + + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@15.0.19': + dependencies: + '@types/yargs-parser': 21.0.3 + + '@typescript-eslint/eslint-plugin@7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)': + dependencies: + '@eslint-community/regexpp': 4.10.1 + '@typescript-eslint/parser': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/scope-manager': 7.13.0 + '@typescript-eslint/type-utils': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/utils': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.13.0 + eslint: 8.57.0 + graphemer: 1.4.0 + ignore: 5.3.1 + natural-compare: 1.4.0 + ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5)': + dependencies: + '@typescript-eslint/scope-manager': 7.13.0 + '@typescript-eslint/types': 7.13.0 + '@typescript-eslint/typescript-estree': 7.13.0(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.13.0 + debug: 4.3.5 + eslint: 8.57.0 + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@7.13.0': + dependencies: + '@typescript-eslint/types': 7.13.0 + '@typescript-eslint/visitor-keys': 7.13.0 + + '@typescript-eslint/type-utils@7.13.0(eslint@8.57.0)(typescript@5.4.5)': + dependencies: + '@typescript-eslint/typescript-estree': 7.13.0(typescript@5.4.5) + '@typescript-eslint/utils': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + debug: 4.3.5 + eslint: 8.57.0 + ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@7.13.0': {} + + '@typescript-eslint/typescript-estree@7.13.0(typescript@5.4.5)': + dependencies: + '@typescript-eslint/types': 7.13.0 + '@typescript-eslint/visitor-keys': 7.13.0 + debug: 4.3.5 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.4 + semver: 7.6.2 + ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@7.13.0(eslint@8.57.0)(typescript@5.4.5)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@typescript-eslint/scope-manager': 7.13.0 + '@typescript-eslint/types': 7.13.0 + '@typescript-eslint/typescript-estree': 7.13.0(typescript@5.4.5) + eslint: 8.57.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@7.13.0': + dependencies: + '@typescript-eslint/types': 7.13.0 + eslint-visitor-keys: 3.4.3 + + '@ungap/structured-clone@1.2.0': {} + + '@vscode/test-cli@0.0.9': + dependencies: + '@types/mocha': 10.0.6 + c8: 9.1.0 + chokidar: 3.6.0 + enhanced-resolve: 5.17.0 + glob: 10.4.1 + minimatch: 9.0.4 + mocha: 10.4.0 + supports-color: 9.4.0 + yargs: 17.7.2 + + '@vscode/test-electron@2.4.0': + dependencies: + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.4 + jszip: 3.10.1 + ora: 7.0.1 + semver: 7.6.2 + transitivePeerDependencies: + - supports-color + + '@vscode/vsce-sign-alpine-arm64@2.0.2': + optional: true + + '@vscode/vsce-sign-alpine-x64@2.0.2': + optional: true + + '@vscode/vsce-sign-darwin-arm64@2.0.2': + optional: true + + '@vscode/vsce-sign-darwin-x64@2.0.2': + optional: true + + '@vscode/vsce-sign-linux-arm64@2.0.2': + optional: true + + '@vscode/vsce-sign-linux-arm@2.0.2': + optional: true + + '@vscode/vsce-sign-linux-x64@2.0.2': + optional: true + + '@vscode/vsce-sign-win32-arm64@2.0.2': + optional: true + + '@vscode/vsce-sign-win32-x64@2.0.2': + optional: true + + '@vscode/vsce-sign@2.0.4': + optionalDependencies: + '@vscode/vsce-sign-alpine-arm64': 2.0.2 + '@vscode/vsce-sign-alpine-x64': 2.0.2 + '@vscode/vsce-sign-darwin-arm64': 2.0.2 + '@vscode/vsce-sign-darwin-x64': 2.0.2 + '@vscode/vsce-sign-linux-arm': 2.0.2 + '@vscode/vsce-sign-linux-arm64': 2.0.2 + '@vscode/vsce-sign-linux-x64': 2.0.2 + '@vscode/vsce-sign-win32-arm64': 2.0.2 + '@vscode/vsce-sign-win32-x64': 2.0.2 + + '@vscode/vsce@2.30.0': + dependencies: + '@azure/identity': 4.3.0 + '@vscode/vsce-sign': 2.0.4 + azure-devops-node-api: 12.5.0 + chalk: 2.4.2 + cheerio: 1.0.0-rc.12 + cockatiel: 3.1.3 + commander: 6.2.1 + form-data: 4.0.0 + glob: 7.2.3 + hosted-git-info: 4.1.0 + jsonc-parser: 3.3.1 + leven: 3.1.0 + markdown-it: 12.3.2 + mime: 1.6.0 + minimatch: 3.1.2 + parse-semver: 1.1.1 + read: 1.0.7 + semver: 7.6.2 + tmp: 0.2.3 + typed-rest-client: 1.8.11 + url-join: 4.0.1 + xml2js: 0.5.0 + yauzl: 2.10.0 + yazl: 2.5.1 + optionalDependencies: + keytar: 7.9.0 + transitivePeerDependencies: + - supports-color + + '@vue/compiler-core@3.4.31': + dependencies: + '@babel/parser': 7.24.7 + '@vue/shared': 3.4.31 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.0 + + '@vue/compiler-dom@3.4.31': + dependencies: + '@vue/compiler-core': 3.4.31 + '@vue/shared': 3.4.31 + + '@vue/compiler-sfc@3.4.31': + dependencies: + '@babel/parser': 7.24.7 + '@vue/compiler-core': 3.4.31 + '@vue/compiler-dom': 3.4.31 + '@vue/compiler-ssr': 3.4.31 + '@vue/shared': 3.4.31 + estree-walker: 2.0.2 + magic-string: 0.30.10 + postcss: 8.4.39 + source-map-js: 1.2.0 + + '@vue/compiler-ssr@3.4.31': + dependencies: + '@vue/compiler-dom': 3.4.31 + '@vue/shared': 3.4.31 + + '@vue/reactivity@3.4.31': + dependencies: + '@vue/shared': 3.4.31 + + '@vue/runtime-core@3.4.31': + dependencies: + '@vue/reactivity': 3.4.31 + '@vue/shared': 3.4.31 + + '@vue/runtime-dom@3.4.31': + dependencies: + '@vue/reactivity': 3.4.31 + '@vue/runtime-core': 3.4.31 + '@vue/shared': 3.4.31 + csstype: 3.1.3 + + '@vue/server-renderer@3.4.31(vue@3.4.31(typescript@5.4.5))': + dependencies: + '@vue/compiler-ssr': 3.4.31 + '@vue/shared': 3.4.31 + vue: 3.4.31(typescript@5.4.5) + + '@vue/shared@3.4.31': {} + + JSONStream@1.3.5: + dependencies: + jsonparse: 1.3.1 + through: 2.3.8 + + acorn-jsx@5.3.2(acorn@8.11.3): + dependencies: + acorn: 8.11.3 + + acorn@8.11.3: {} + + agent-base@7.1.1: + dependencies: + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.16.0: + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + + alova@2.21.3: {} + + alova@3.0.0-beta.10: + dependencies: + '@alova/shared': 1.0.0-beta.7 + + alova@3.0.5: + dependencies: + '@alova/shared': 1.0.4 + rate-limiter-flexible: 5.0.3 + + ansi-colors@4.1.1: {} + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-escapes@6.2.1: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.0.1: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + + array-buffer-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 + + array-ify@1.0.0: {} + + array-includes@3.1.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + is-string: 1.0.7 + + array-union@2.1.0: {} + + array.prototype.findlast@1.2.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + + array.prototype.findlastindex@1.2.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + + array.prototype.flat@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + + array.prototype.flatmap@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + + array.prototype.toreversed@1.1.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + + array.prototype.tosorted@1.1.4: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-shim-unscopables: 1.0.2 + + arraybuffer.prototype.slice@1.0.3: + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 + + ast-types-flow@0.0.8: {} + + asynckit@0.4.0: {} + + at-least-node@1.0.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + + axe-core@4.7.0: {} + + axobject-query@3.2.1: + dependencies: + dequal: 2.0.3 + + azure-devops-node-api@12.5.0: + dependencies: + tunnel: 0.0.6 + typed-rest-client: 1.8.11 + + balanced-match@1.0.2: {} + + base64-js@1.5.1: {} + + binary-extensions@2.3.0: {} + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + + bl@5.1.0: + dependencies: + buffer: 6.0.3 + inherits: 2.0.4 + readable-stream: 3.6.2 + + boolbase@1.0.0: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browser-stdout@1.3.1: {} + + buffer-crc32@0.2.13: {} + + buffer-equal-constant-time@1.0.1: {} + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + c8@9.1.0: + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@istanbuljs/schema': 0.1.3 + find-up: 5.0.0 + foreground-child: 3.2.0 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-reports: 3.1.7 + test-exclude: 6.0.0 + v8-to-istanbul: 9.2.0 + yargs: 17.7.2 + yargs-parser: 21.1.1 + + cachedir@2.3.0: {} + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + call-me-maybe@1.0.2: {} + + callsites@3.1.0: {} + + camel-case@4.1.2: + dependencies: + pascal-case: 3.1.2 + tslib: 2.6.3 + + camelcase@6.3.0: {} + + capital-case@1.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.6.3 + upper-case-first: 2.0.2 + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.3.0: {} + + change-case@4.1.2: + dependencies: + camel-case: 4.1.2 + capital-case: 1.0.4 + constant-case: 3.0.4 + dot-case: 3.0.4 + header-case: 2.0.4 + no-case: 3.0.4 + param-case: 3.0.4 + pascal-case: 3.1.2 + path-case: 3.0.4 + sentence-case: 3.0.4 + snake-case: 3.0.4 + tslib: 2.6.3 + + chardet@0.7.0: {} + + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.1.0 + css-what: 6.1.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + + cheerio@1.0.0-rc.12: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.1.0 + htmlparser2: 8.0.2 + parse5: 7.1.2 + parse5-htmlparser2-tree-adapter: 7.0.0 + + chokidar@3.5.3: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chownr@1.1.4: + optional: true + + cli-cursor@3.1.0: + dependencies: + restore-cursor: 3.1.0 + + cli-cursor@4.0.0: + dependencies: + restore-cursor: 4.0.0 + + cli-spinners@2.9.2: {} + + cli-truncate@4.0.0: + dependencies: + slice-ansi: 5.0.0 + string-width: 7.1.0 + + cli-width@3.0.0: {} + + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone@1.0.4: {} + + cockatiel@3.1.3: {} + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + colorette@2.0.20: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@12.1.0: {} + + commander@6.2.1: {} + + commitizen@4.3.0(@types/node@18.19.34)(typescript@5.4.5): + dependencies: + cachedir: 2.3.0 + cz-conventional-changelog: 3.3.0(@types/node@18.19.34)(typescript@5.4.5) + dedent: 0.7.0 + detect-indent: 6.1.0 + find-node-modules: 2.1.3 + find-root: 1.1.0 + fs-extra: 9.1.0 + glob: 7.2.3 + inquirer: 8.2.5 + is-utf8: 0.2.1 + lodash: 4.17.21 + minimist: 1.2.7 + strip-bom: 4.0.0 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - '@types/node' + - typescript + + compare-func@2.0.0: + dependencies: + array-ify: 1.0.0 + dot-prop: 5.3.0 + + concat-map@0.0.1: {} + + confusing-browser-globals@1.0.11: {} + + constant-case@3.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.6.3 + upper-case: 2.0.2 + + conventional-changelog-angular@7.0.0: + dependencies: + compare-func: 2.0.0 + + conventional-changelog-conventionalcommits@7.0.2: + dependencies: + compare-func: 2.0.0 + + conventional-commit-types@3.0.0: {} + + conventional-commits-parser@5.0.0: + dependencies: + JSONStream: 1.3.5 + is-text-path: 2.0.0 + meow: 12.1.1 + split2: 4.2.0 + + convert-source-map@2.0.0: {} + + core-util-is@1.0.3: {} + + cosmiconfig-typescript-loader@5.0.0(@types/node@18.19.34)(cosmiconfig@9.0.0(typescript@5.4.5))(typescript@5.4.5): + dependencies: + '@types/node': 18.19.34 + cosmiconfig: 9.0.0(typescript@5.4.5) + jiti: 1.21.6 + typescript: 5.4.5 + + cosmiconfig@6.0.0: + dependencies: + '@types/parse-json': 4.0.2 + import-fresh: 3.3.0 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.2 + + cosmiconfig@9.0.0(typescript@5.4.5): + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + optionalDependencies: + typescript: 5.4.5 + + cross-spawn@6.0.5: + dependencies: + nice-try: 1.0.5 + path-key: 2.0.1 + semver: 5.7.2 + shebang-command: 1.2.0 + which: 1.3.1 + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + css-select@5.1.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 5.0.3 + domutils: 3.1.0 + nth-check: 2.1.1 + + css-what@6.1.0: {} + + csstype@3.1.3: {} + + cz-conventional-changelog@3.3.0(@types/node@18.19.34)(typescript@5.4.5): + dependencies: + chalk: 2.4.2 + commitizen: 4.3.0(@types/node@18.19.34)(typescript@5.4.5) + conventional-commit-types: 3.0.0 + lodash.map: 4.6.0 + longest: 2.0.1 + word-wrap: 1.2.5 + optionalDependencies: + '@commitlint/load': 19.2.0(@types/node@18.19.34)(typescript@5.4.5) + transitivePeerDependencies: + - '@types/node' + - typescript + + damerau-levenshtein@1.0.8: {} + + dargs@8.1.0: {} + + data-view-buffer@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-offset@1.0.0: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.3.4(supports-color@8.1.1): + dependencies: + ms: 2.1.2 + optionalDependencies: + supports-color: 8.1.1 + + debug@4.3.5: + dependencies: + ms: 2.1.2 + + decamelize@4.0.0: {} + + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + optional: true + + dedent@0.7.0: {} + + deep-extend@0.6.0: + optional: true + + deep-is@0.1.4: {} + + defaults@1.0.4: + dependencies: + clone: 1.0.4 + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + define-lazy-prop@2.0.0: {} + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + delayed-stream@1.0.0: {} + + dequal@2.0.3: {} + + detect-file@1.0.0: {} + + detect-indent@6.1.0: {} + + detect-libc@2.0.3: + optional: true + + diff-sequences@26.6.2: {} + + diff@5.0.0: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.1.0: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dot-case@3.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.6.3 + + dot-prop@5.3.0: + dependencies: + is-obj: 2.0.0 + + eastasianwidth@0.2.0: {} + + ecdsa-sig-formatter@1.0.11: + dependencies: + safe-buffer: 5.2.1 + + emoji-regex@10.3.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + end-of-stream@1.4.4: + dependencies: + once: 1.4.0 + optional: true + + enhanced-resolve@5.17.0: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + + entities@2.1.0: {} + + entities@4.5.0: {} + + env-paths@2.2.1: {} + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + es-abstract@1.23.3: + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-set-tostringtag: 2.0.3 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-data-view: 1.0.1 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + is-string: 1.0.7 + is-typed-array: 1.1.13 + is-weakref: 1.0.2 + object-inspect: 1.13.1 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.6 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.15 + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + es-iterator-helpers@1.0.19: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-set-tostringtag: 2.0.3 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + globalthis: 1.0.4 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + internal-slot: 1.0.7 + iterator.prototype: 1.1.2 + safe-array-concat: 1.1.2 + + es-object-atoms@1.0.0: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.0.3: + dependencies: + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-shim-unscopables@1.0.2: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.2.1: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + + es6-promise@3.3.1: {} + + esbuild-plugin-alias@0.2.1: {} + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + esbuild@0.23.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.23.0 + '@esbuild/android-arm': 0.23.0 + '@esbuild/android-arm64': 0.23.0 + '@esbuild/android-x64': 0.23.0 + '@esbuild/darwin-arm64': 0.23.0 + '@esbuild/darwin-x64': 0.23.0 + '@esbuild/freebsd-arm64': 0.23.0 + '@esbuild/freebsd-x64': 0.23.0 + '@esbuild/linux-arm': 0.23.0 + '@esbuild/linux-arm64': 0.23.0 + '@esbuild/linux-ia32': 0.23.0 + '@esbuild/linux-loong64': 0.23.0 + '@esbuild/linux-mips64el': 0.23.0 + '@esbuild/linux-ppc64': 0.23.0 + '@esbuild/linux-riscv64': 0.23.0 + '@esbuild/linux-s390x': 0.23.0 + '@esbuild/linux-x64': 0.23.0 + '@esbuild/netbsd-x64': 0.23.0 + '@esbuild/openbsd-arm64': 0.23.0 + '@esbuild/openbsd-x64': 0.23.0 + '@esbuild/sunos-x64': 0.23.0 + '@esbuild/win32-arm64': 0.23.0 + '@esbuild/win32-ia32': 0.23.0 + '@esbuild/win32-x64': 0.23.0 + + escalade@3.1.2: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0): + dependencies: + confusing-browser-globals: 1.0.11 + eslint: 8.57.0 + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) + object.assign: 4.1.5 + object.entries: 1.1.8 + semver: 6.3.1 + + eslint-config-airbnb-typescript@18.0.0(@typescript-eslint/eslint-plugin@7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0): + dependencies: + '@typescript-eslint/eslint-plugin': 7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + eslint: 8.57.0 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) + transitivePeerDependencies: + - eslint-plugin-import + + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react@7.34.2(eslint@8.57.0))(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) + eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0) + eslint-plugin-react: 7.34.2(eslint@8.57.0) + eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) + object.assign: 4.1.5 + object.entries: 1.1.8 + + eslint-config-prettier@9.1.0(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.13.1 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0): + dependencies: + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) + hasown: 2.0.2 + is-core-module: 2.13.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.0 + semver: 6.3.1 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0): + dependencies: + '@babel/runtime': 7.24.7 + aria-query: 5.3.0 + array-includes: 3.1.8 + array.prototype.flatmap: 1.3.2 + ast-types-flow: 0.0.8 + axe-core: 4.7.0 + axobject-query: 3.2.1 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + es-iterator-helpers: 1.0.19 + eslint: 8.57.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.2 + object.entries: 1.1.8 + object.fromentries: 2.0.8 + + eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.2): + dependencies: + eslint: 8.57.0 + prettier: 3.3.2 + prettier-linter-helpers: 1.0.0 + synckit: 0.8.8 + optionalDependencies: + eslint-config-prettier: 9.1.0(eslint@8.57.0) + + eslint-plugin-react-hooks@4.6.2(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + + eslint-plugin-react@7.34.2(eslint@8.57.0): + dependencies: + array-includes: 3.1.8 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.2 + array.prototype.toreversed: 1.1.2 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.0.19 + eslint: 8.57.0 + estraverse: 5.3.0 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.2 + object.entries: 1.1.8 + object.fromentries: 2.0.8 + object.hasown: 1.1.4 + object.values: 1.2.0 + prop-types: 15.8.1 + resolve: 2.0.0-next.5 + semver: 6.3.1 + string.prototype.matchall: 4.0.11 + + eslint-scope@7.2.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint@8.57.0: + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/regexpp': 4.10.1 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.0 + '@humanwhocodes/config-array': 0.11.14 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.5 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.1 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + espree@9.6.1: + dependencies: + acorn: 8.11.3 + acorn-jsx: 5.3.2(acorn@8.11.3) + eslint-visitor-keys: 3.4.3 + + esprima@4.0.1: {} + + esquery@1.5.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@2.0.2: {} + + esutils@2.0.3: {} + + eventemitter3@5.0.1: {} + + events@3.3.0: {} + + execa@8.0.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + + expand-template@2.0.3: + optional: true + + expand-tilde@2.0.2: + dependencies: + homedir-polyfill: 1.0.3 + + external-editor@3.1.0: + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + + fast-deep-equal@3.1.3: {} + + fast-diff@1.3.0: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.7 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-safe-stringify@2.1.1: {} + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + fd-slicer@1.1.0: + dependencies: + pend: 1.2.0 + + figures@3.2.0: + dependencies: + escape-string-regexp: 1.0.5 + + file-entry-cache@6.0.1: + dependencies: + flat-cache: 3.2.0 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-node-modules@2.1.3: + dependencies: + findup-sync: 4.0.0 + merge: 2.1.1 + + find-root@1.1.0: {} + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + find-up@7.0.0: + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + unicorn-magic: 0.1.0 + + findup-sync@4.0.0: + dependencies: + detect-file: 1.0.0 + is-glob: 4.0.3 + micromatch: 4.0.7 + resolve-dir: 1.0.1 + + flat-cache@3.2.0: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + rimraf: 3.0.2 + + flat@5.0.2: {} + + flatted@3.3.1: {} + + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 + + foreground-child@3.2.0: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + + form-data@4.0.0: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + fs-constants@1.0.0: + optional: true + + fs-extra@9.1.0: + dependencies: + at-least-node: 1.0.0 + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + functions-have-names: 1.2.3 + + functions-have-names@1.2.3: {} + + get-caller-file@2.0.5: {} + + get-east-asian-width@1.2.0: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + get-stream@8.0.1: {} + + get-symbol-description@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + + get-tsconfig@4.7.5: + dependencies: + resolve-pkg-maps: 1.0.0 + + git-raw-commits@4.0.0: + dependencies: + dargs: 8.1.0 + meow: 12.1.1 + split2: 4.2.0 + + github-from-package@0.0.0: + optional: true + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@10.4.1: + dependencies: + foreground-child: 3.2.0 + jackspeak: 3.4.0 + minimatch: 9.0.4 + minipass: 7.1.2 + path-scurry: 1.11.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.0.1 + once: 1.4.0 + + global-directory@4.0.1: + dependencies: + ini: 4.1.1 + + global-modules@1.0.0: + dependencies: + global-prefix: 1.0.2 + is-windows: 1.0.2 + resolve-dir: 1.0.1 + + global-prefix@1.0.2: + dependencies: + expand-tilde: 2.0.2 + homedir-polyfill: 1.0.3 + ini: 1.3.8 + is-windows: 1.0.2 + which: 1.3.1 + + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.0.1 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.1 + merge2: 1.4.1 + slash: 3.0.0 + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + handlebars@4.7.8: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.18.0 + + has-bigints@1.0.2: {} + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.0.3 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + he@1.2.0: {} + + header-case@2.0.4: + dependencies: + capital-case: 1.0.4 + tslib: 2.6.3 + + homedir-polyfill@1.0.3: + dependencies: + parse-passwd: 1.0.0 + + hosted-git-info@2.8.9: {} + + hosted-git-info@4.1.0: + dependencies: + lru-cache: 6.0.0 + + html-escaper@2.0.2: {} + + htmlparser2@8.0.2: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + entities: 4.5.0 + + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.1 + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + + http2-client@1.3.5: {} + + https-proxy-agent@7.0.4: + dependencies: + agent-base: 7.1.1 + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + + human-signals@5.0.0: {} + + husky@9.0.11: {} + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + ieee754@1.2.1: {} + + ignore@5.3.1: {} + + immediate@3.0.6: {} + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-meta-resolve@4.1.0: {} + + imurmurhash@0.1.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + ini@1.3.8: {} + + ini@4.1.1: {} + + inquirer@8.2.5: + dependencies: + ansi-escapes: 4.3.2 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-width: 3.0.0 + external-editor: 3.1.0 + figures: 3.2.0 + lodash: 4.17.21 + mute-stream: 0.0.8 + ora: 5.4.1 + run-async: 2.4.1 + rxjs: 7.8.1 + string-width: 4.2.3 + strip-ansi: 6.0.1 + through: 2.3.8 + wrap-ansi: 7.0.0 + + internal-slot@1.0.7: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.0.6 + + is-array-buffer@3.0.4: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + + is-arrayish@0.2.1: {} + + is-async-function@2.0.0: + dependencies: + has-tostringtag: 1.0.2 + + is-bigint@1.0.4: + dependencies: + has-bigints: 1.0.2 + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-boolean-object@1.1.2: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-callable@1.2.7: {} + + is-core-module@2.13.1: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.1: + dependencies: + is-typed-array: 1.1.13 + + is-date-object@1.0.5: + dependencies: + has-tostringtag: 1.0.2 + + is-docker@2.2.1: {} + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.0.2: + dependencies: + call-bind: 1.0.7 + + is-fullwidth-code-point@3.0.0: {} + + is-fullwidth-code-point@4.0.0: {} + + is-fullwidth-code-point@5.0.0: + dependencies: + get-east-asian-width: 1.2.0 + + is-generator-function@1.0.10: + dependencies: + has-tostringtag: 1.0.2 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-interactive@1.0.0: {} + + is-interactive@2.0.0: {} + + is-map@2.0.3: {} + + is-negative-zero@2.0.3: {} + + is-number-object@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-obj@2.0.0: {} + + is-path-inside@3.0.3: {} + + is-plain-obj@2.1.0: {} + + is-regex@1.1.4: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.3: + dependencies: + call-bind: 1.0.7 + + is-stream@3.0.0: {} + + is-string@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-symbol@1.0.4: + dependencies: + has-symbols: 1.0.3 + + is-text-path@2.0.0: + dependencies: + text-extensions: 2.4.0 + + is-typed-array@1.1.13: + dependencies: + which-typed-array: 1.1.15 + + is-unicode-supported@0.1.0: {} + + is-unicode-supported@1.3.0: {} + + is-url@1.2.4: {} + + is-utf8@0.2.1: {} + + is-weakmap@2.0.2: {} + + is-weakref@1.0.2: + dependencies: + call-bind: 1.0.7 + + is-weakset@2.0.3: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + + is-windows@1.0.2: {} + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + isarray@1.0.0: {} + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-reports@3.1.7: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + iterator.prototype@1.1.2: + dependencies: + define-properties: 1.2.1 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + reflect.getprototypeof: 1.0.6 + set-function-name: 2.0.2 + + jackspeak@3.4.0: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jest-diff@26.6.2: + dependencies: + chalk: 4.1.2 + diff-sequences: 26.6.2 + jest-get-type: 26.3.0 + pretty-format: 26.6.2 + + jest-get-type@26.3.0: {} + + jiti@1.21.6: {} + + js-tokens@4.0.0: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-parse-better-errors@1.0.2: {} + + json-parse-even-better-errors@2.3.1: {} + + json-schema-traverse@0.4.1: {} + + json-schema-traverse@1.0.0: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + jsonc-parser@3.3.1: {} + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + jsonparse@1.3.1: {} + + jsonwebtoken@9.0.2: + dependencies: + jws: 3.2.2 + lodash.includes: 4.3.0 + lodash.isboolean: 3.0.3 + lodash.isinteger: 4.0.4 + lodash.isnumber: 3.0.3 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.once: 4.1.1 + ms: 2.1.3 + semver: 7.6.2 + + jsx-ast-utils@3.3.5: + dependencies: + array-includes: 3.1.8 + array.prototype.flat: 1.3.2 + object.assign: 4.1.5 + object.values: 1.2.0 + + jszip@3.10.1: + dependencies: + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + + jwa@1.4.1: + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + + jwa@2.0.0: + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + + jws@3.2.2: + dependencies: + jwa: 1.4.1 + safe-buffer: 5.2.1 + + jws@4.0.0: + dependencies: + jwa: 2.0.0 + safe-buffer: 5.2.1 + + keytar@7.9.0: + dependencies: + node-addon-api: 4.3.0 + prebuild-install: 7.1.2 + optional: true + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + language-subtag-registry@0.3.23: {} + + language-tags@1.0.9: + dependencies: + language-subtag-registry: 0.3.23 + + leven@3.1.0: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lie@3.3.0: + dependencies: + immediate: 3.0.6 + + lilconfig@3.1.2: {} + + lines-and-columns@1.2.4: {} + + linkify-it@3.0.3: + dependencies: + uc.micro: 1.0.6 + + lint-staged@15.2.7: + dependencies: + chalk: 5.3.0 + commander: 12.1.0 + debug: 4.3.5 + execa: 8.0.1 + lilconfig: 3.1.2 + listr2: 8.2.1 + micromatch: 4.0.7 + pidtree: 0.6.0 + string-argv: 0.3.2 + yaml: 2.4.5 + transitivePeerDependencies: + - supports-color + + listr2@8.2.1: + dependencies: + cli-truncate: 4.0.0 + colorette: 2.0.20 + eventemitter3: 5.0.1 + log-update: 6.0.0 + rfdc: 1.4.1 + wrap-ansi: 9.0.0 + + load-json-file@4.0.0: + dependencies: + graceful-fs: 4.2.11 + parse-json: 4.0.0 + pify: 3.0.0 + strip-bom: 3.0.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + locate-path@7.2.0: + dependencies: + p-locate: 6.0.0 + + lodash.camelcase@4.3.0: {} + + lodash.includes@4.3.0: {} + + lodash.isboolean@3.0.3: {} + + lodash.isinteger@4.0.4: {} + + lodash.isnumber@3.0.3: {} + + lodash.isplainobject@4.0.6: {} + + lodash.isstring@4.0.1: {} + + lodash.kebabcase@4.1.1: {} + + lodash.map@4.6.0: {} + + lodash.merge@4.6.2: {} + + lodash.mergewith@4.6.2: {} + + lodash.once@4.1.1: {} + + lodash.snakecase@4.1.1: {} + + lodash.startcase@4.4.0: {} + + lodash.uniq@4.5.0: {} + + lodash.upperfirst@4.3.1: {} + + lodash@4.17.21: {} + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + + log-symbols@5.1.0: + dependencies: + chalk: 5.3.0 + is-unicode-supported: 1.3.0 + + log-update@6.0.0: + dependencies: + ansi-escapes: 6.2.1 + cli-cursor: 4.0.0 + slice-ansi: 7.1.0 + strip-ansi: 7.1.0 + wrap-ansi: 9.0.0 + + longest@2.0.1: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lower-case@2.0.2: + dependencies: + tslib: 2.6.3 + + lru-cache@10.2.2: {} + + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + + magic-string@0.30.10: + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + + make-dir@4.0.0: + dependencies: + semver: 7.6.2 + + markdown-it@12.3.2: + dependencies: + argparse: 2.0.1 + entities: 2.1.0 + linkify-it: 3.0.3 + mdurl: 1.0.1 + uc.micro: 1.0.6 + + mdurl@1.0.1: {} + + memorystream@0.3.1: {} + + meow@12.1.1: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + merge@2.1.1: {} + + micromatch@4.0.7: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@1.6.0: {} + + mimic-fn@2.1.0: {} + + mimic-fn@4.0.0: {} + + mimic-response@3.1.0: + optional: true + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@5.0.1: + dependencies: + brace-expansion: 2.0.1 + + minimatch@9.0.4: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.7: {} + + minimist@1.2.8: {} + + minipass@7.1.2: {} + + mkdirp-classic@0.5.3: + optional: true + + mocha@10.4.0: + dependencies: + ansi-colors: 4.1.1 + browser-stdout: 1.3.1 + chokidar: 3.5.3 + debug: 4.3.4(supports-color@8.1.1) + diff: 5.0.0 + escape-string-regexp: 4.0.0 + find-up: 5.0.0 + glob: 8.1.0 + he: 1.2.0 + js-yaml: 4.1.0 + log-symbols: 4.1.0 + minimatch: 5.0.1 + ms: 2.1.3 + serialize-javascript: 6.0.0 + strip-json-comments: 3.1.1 + supports-color: 8.1.1 + workerpool: 6.2.1 + yargs: 16.2.0 + yargs-parser: 20.2.4 + yargs-unparser: 2.0.0 + + ms@2.1.2: {} + + ms@2.1.3: {} + + mute-stream@0.0.8: {} + + nanoid@3.3.7: {} + + napi-build-utils@1.0.2: + optional: true + + natural-compare@1.4.0: {} + + neo-async@2.6.2: {} + + nice-try@1.0.5: {} + + no-case@3.0.4: + dependencies: + lower-case: 2.0.2 + tslib: 2.6.3 + + node-abi@3.65.0: + dependencies: + semver: 7.6.2 + optional: true + + node-addon-api@4.3.0: + optional: true + + node-fetch-h2@2.3.0: + dependencies: + http2-client: 1.3.5 + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-readfiles@0.2.0: + dependencies: + es6-promise: 3.3.1 + + normalize-package-data@2.5.0: + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.8 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + + normalize-path@3.0.0: {} + + npm-run-all@4.1.5: + dependencies: + ansi-styles: 3.2.1 + chalk: 2.4.2 + cross-spawn: 6.0.5 + memorystream: 0.3.1 + minimatch: 3.1.2 + pidtree: 0.3.1 + read-pkg: 3.0.0 + shell-quote: 1.8.1 + string.prototype.padend: 3.1.6 + + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + oas-kit-common@1.0.8: + dependencies: + fast-safe-stringify: 2.1.1 + + oas-linter@3.2.2: + dependencies: + '@exodus/schemasafe': 1.3.0 + should: 13.2.3 + yaml: 1.10.2 + + oas-resolver@2.5.6: + dependencies: + node-fetch-h2: 2.3.0 + oas-kit-common: 1.0.8 + reftools: 1.1.9 + yaml: 1.10.2 + yargs: 17.7.2 + + oas-schema-walker@1.1.5: {} + + oas-validator@5.0.8: + dependencies: + call-me-maybe: 1.0.2 + oas-kit-common: 1.0.8 + oas-linter: 3.2.2 + oas-resolver: 2.5.6 + oas-schema-walker: 1.1.5 + reftools: 1.1.9 + should: 13.2.3 + yaml: 1.10.2 + + object-assign@4.1.1: {} + + object-hash@2.2.0: {} + + object-inspect@1.13.1: {} + + object-keys@1.1.1: {} + + object.assign@4.1.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + + object.entries@1.1.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + + object.hasown@1.1.4: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + object.values@1.2.0: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + + openapi-types@12.1.3: {} + + openapi@1.0.1: + dependencies: + '@types/jest': 26.0.24 + change-case: 4.1.2 + commander: 6.2.1 + cosmiconfig: 6.0.0 + is-url: 1.2.4 + js-yaml: 3.14.1 + node-fetch: 2.7.0 + object-hash: 2.2.0 + url-parse: 1.5.10 + transitivePeerDependencies: + - encoding + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + ora@5.4.1: + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.9.2 + is-interactive: 1.0.0 + is-unicode-supported: 0.1.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + + ora@7.0.1: + dependencies: + chalk: 5.3.0 + cli-cursor: 4.0.0 + cli-spinners: 2.9.2 + is-interactive: 2.0.0 + is-unicode-supported: 1.3.0 + log-symbols: 5.1.0 + stdin-discarder: 0.1.0 + string-width: 6.1.0 + strip-ansi: 7.1.0 + + os-tmpdir@1.0.2: {} + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-limit@4.0.0: + dependencies: + yocto-queue: 1.0.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-locate@6.0.0: + dependencies: + p-limit: 4.0.0 + + pako@1.0.11: {} + + param-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.6.3 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-json@4.0.0: + dependencies: + error-ex: 1.3.2 + json-parse-better-errors: 1.0.2 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.24.7 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + parse-passwd@1.0.0: {} + + parse-semver@1.1.1: + dependencies: + semver: 5.7.2 + + parse5-htmlparser2-tree-adapter@7.0.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.1.2 + + parse5@7.1.2: + dependencies: + entities: 4.5.0 + + pascal-case@3.1.2: + dependencies: + no-case: 3.0.4 + tslib: 2.6.3 + + path-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.6.3 + + path-exists@4.0.0: {} + + path-exists@5.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@2.0.1: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.2.2 + minipass: 7.1.2 + + path-type@3.0.0: + dependencies: + pify: 3.0.0 + + path-type@4.0.0: {} + + pend@1.2.0: {} + + picocolors@1.0.1: {} + + picomatch@2.3.1: {} + + pidtree@0.3.1: {} + + pidtree@0.6.0: {} + + pify@3.0.0: {} + + possible-typed-array-names@1.0.0: {} + + postcss@8.4.39: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + + prebuild-install@7.1.2: + dependencies: + detect-libc: 2.0.3 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + napi-build-utils: 1.0.2 + node-abi: 3.65.0 + pump: 3.0.0 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.1 + tunnel-agent: 0.6.0 + optional: true + + prelude-ls@1.2.1: {} + + prettier-linter-helpers@1.0.0: + dependencies: + fast-diff: 1.3.0 + + prettier-plugin-organize-imports@3.2.4(prettier@3.3.2)(typescript@5.4.5): + dependencies: + prettier: 3.3.2 + typescript: 5.4.5 + + prettier-plugin-sort-json@4.0.0(prettier@3.3.2): + dependencies: + prettier: 3.3.2 + + prettier@3.3.2: {} + + pretty-format@26.6.2: + dependencies: + '@jest/types': 26.6.2 + ansi-regex: 5.0.1 + ansi-styles: 4.3.0 + react-is: 17.0.2 + + process-nextick-args@2.0.1: {} + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + pump@3.0.0: + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + optional: true + + punycode@2.3.1: {} + + qs@6.12.3: + dependencies: + side-channel: 1.0.6 + + querystringify@2.2.0: {} + + queue-microtask@1.2.3: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + rate-limiter-flexible@5.0.3: {} + + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + optional: true + + react-is@16.13.1: {} + + react-is@17.0.2: {} + + read-pkg@3.0.0: + dependencies: + load-json-file: 4.0.0 + normalize-package-data: 2.5.0 + path-type: 3.0.0 + + read@1.0.7: + dependencies: + mute-stream: 0.0.8 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + reflect.getprototypeof@1.0.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + globalthis: 1.0.4 + which-builtin-type: 1.1.3 + + reftools@1.1.9: {} + + regenerator-runtime@0.14.1: {} + + regexp.prototype.flags@1.5.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + requires-port@1.0.0: {} + + resolve-dir@1.0.1: + dependencies: + expand-tilde: 2.0.2 + global-modules: 1.0.0 + + resolve-from@4.0.0: {} + + resolve-from@5.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@1.22.8: + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + resolve@2.0.0-next.5: + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + restore-cursor@3.1.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + + restore-cursor@4.0.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + + reusify@1.0.4: {} + + rfdc@1.4.1: {} + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + run-async@2.4.1: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + rxjs@7.8.1: + dependencies: + tslib: 2.6.3 + + safe-array-concat@1.1.2: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safe-regex-test@1.0.3: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-regex: 1.1.4 + + safer-buffer@2.1.2: {} + + sax@1.4.1: {} + + semver@5.7.2: {} + + semver@6.3.1: {} + + semver@7.6.2: {} + + sentence-case@3.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.6.3 + upper-case-first: 2.0.2 + + serialize-javascript@6.0.0: + dependencies: + randombytes: 2.1.0 + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + setimmediate@1.0.5: {} + + shebang-command@1.2.0: + dependencies: + shebang-regex: 1.0.0 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@1.0.0: {} + + shebang-regex@3.0.0: {} + + shell-quote@1.8.1: {} + + should-equal@2.0.0: + dependencies: + should-type: 1.4.0 + + should-format@3.0.3: + dependencies: + should-type: 1.4.0 + should-type-adaptors: 1.1.0 + + should-type-adaptors@1.1.0: + dependencies: + should-type: 1.4.0 + should-util: 1.0.1 + + should-type@1.4.0: {} + + should-util@1.0.1: {} + + should@13.2.3: + dependencies: + should-equal: 2.0.0 + should-format: 3.0.3 + should-type: 1.4.0 + should-type-adaptors: 1.1.0 + should-util: 1.0.1 + + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.1 + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + simple-concat@1.0.1: + optional: true + + simple-get@4.0.1: + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + optional: true + + slash@3.0.0: {} + + slice-ansi@5.0.0: + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 4.0.0 + + slice-ansi@7.1.0: + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 5.0.0 + + snake-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.6.3 + + source-map-js@1.2.0: {} + + source-map@0.6.1: {} + + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.18 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.18 + + spdx-license-ids@3.0.18: {} + + split2@4.2.0: {} + + sprintf-js@1.0.3: {} + + stdin-discarder@0.1.0: + dependencies: + bl: 5.1.0 + + stoppable@1.1.0: {} + + string-argv@0.3.2: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + string-width@6.1.0: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 10.3.0 + strip-ansi: 7.1.0 + + string-width@7.1.0: + dependencies: + emoji-regex: 10.3.0 + get-east-asian-width: 1.2.0 + strip-ansi: 7.1.0 + + string.prototype.matchall@4.0.11: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-symbols: 1.0.3 + internal-slot: 1.0.7 + regexp.prototype.flags: 1.5.2 + set-function-name: 2.0.2 + side-channel: 1.0.6 + + string.prototype.padend@3.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + string.prototype.trim@1.2.9: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + string.prototype.trimend@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + + strip-bom@3.0.0: {} + + strip-bom@4.0.0: {} + + strip-final-newline@3.0.0: {} + + strip-json-comments@2.0.1: + optional: true + + strip-json-comments@3.1.1: {} + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-color@9.4.0: {} + + supports-preserve-symlinks-flag@1.0.0: {} + + swagger2openapi@7.0.8: + dependencies: + call-me-maybe: 1.0.2 + node-fetch: 2.7.0 + node-fetch-h2: 2.3.0 + node-readfiles: 0.2.0 + oas-kit-common: 1.0.8 + oas-resolver: 2.5.6 + oas-schema-walker: 1.1.5 + oas-validator: 5.0.8 + reftools: 1.1.9 + yaml: 1.10.2 + yargs: 17.7.2 + transitivePeerDependencies: + - encoding + + synckit@0.8.8: + dependencies: + '@pkgr/core': 0.1.1 + tslib: 2.6.3 + + tapable@2.2.1: {} + + tar-fs@2.1.1: + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.0 + tar-stream: 2.2.0 + optional: true + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + optional: true + + test-exclude@6.0.0: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + + text-extensions@2.4.0: {} + + text-table@0.2.0: {} + + through@2.3.8: {} + + tmp@0.0.33: + dependencies: + os-tmpdir: 1.0.2 + + tmp@0.2.3: {} + + to-fast-properties@2.0.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + tr46@0.0.3: {} + + ts-api-utils@1.3.0(typescript@5.4.5): + dependencies: + typescript: 5.4.5 + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@2.6.3: {} + + tsx@4.16.2: + dependencies: + esbuild: 0.21.5 + get-tsconfig: 4.7.5 + optionalDependencies: + fsevents: 2.3.3 + + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + optional: true + + tunnel@0.0.6: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-fest@0.20.2: {} + + type-fest@0.21.3: {} + + type-fest@4.20.0: {} + + typed-array-buffer@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 + + typed-array-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-byte-offset@1.0.2: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-length@1.0.6: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 + + typed-rest-client@1.8.11: + dependencies: + qs: 6.12.3 + tunnel: 0.0.6 + underscore: 1.13.6 + + typescript@5.4.5: {} + + uc.micro@1.0.6: {} + + uglify-js@3.18.0: + optional: true + + unbox-primitive@1.0.2: + dependencies: + call-bind: 1.0.7 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + + underscore@1.13.6: {} + + undici-types@5.26.5: {} + + unicorn-magic@0.1.0: {} + + universalify@2.0.1: {} + + upper-case-first@2.0.2: + dependencies: + tslib: 2.6.3 + + upper-case@2.0.2: + dependencies: + tslib: 2.6.3 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + url-join@4.0.1: {} + + url-parse@1.5.10: + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + + util-deprecate@1.0.2: {} + + uuid@8.3.2: {} + + v8-to-istanbul@9.2.0: + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 2.0.0 + + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + + vue@3.4.31(typescript@5.4.5): + dependencies: + '@vue/compiler-dom': 3.4.31 + '@vue/compiler-sfc': 3.4.31 + '@vue/runtime-dom': 3.4.31 + '@vue/server-renderer': 3.4.31(vue@3.4.31(typescript@5.4.5)) + '@vue/shared': 3.4.31 + optionalDependencies: + typescript: 5.4.5 + + wcwidth@1.0.1: + dependencies: + defaults: 1.0.4 + + webidl-conversions@3.0.1: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which-boxed-primitive@1.0.2: + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + + which-builtin-type@1.1.3: + dependencies: + function.prototype.name: 1.1.6 + has-tostringtag: 1.0.2 + is-async-function: 2.0.0 + is-date-object: 1.0.5 + is-finalizationregistry: 1.0.2 + is-generator-function: 1.0.10 + is-regex: 1.1.4 + is-weakref: 1.0.2 + isarray: 2.0.5 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.2 + which-typed-array: 1.1.15 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.3 + + which-typed-array@1.1.15: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + + which@1.3.1: + dependencies: + isexe: 2.0.0 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wordwrap@1.0.0: {} + + workerpool@6.2.1: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + wrap-ansi@9.0.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 7.1.0 + strip-ansi: 7.1.0 + + wrappy@1.0.2: {} + + xml2js@0.5.0: + dependencies: + sax: 1.4.1 + xmlbuilder: 11.0.1 + + xmlbuilder@11.0.1: {} + + y18n@5.0.8: {} + + yallist@4.0.0: {} + + yaml@1.10.2: {} + + yaml@2.4.5: {} + + yargs-parser@20.2.4: {} + + yargs-parser@21.1.1: {} + + yargs-unparser@2.0.0: + dependencies: + camelcase: 6.3.0 + decamelize: 4.0.0 + flat: 5.0.2 + is-plain-obj: 2.1.0 + + yargs@16.2.0: + dependencies: + cliui: 7.0.4 + escalade: 3.1.2 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.4 + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.1.2 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yauzl@2.10.0: + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + + yazl@2.5.1: + dependencies: + buffer-crc32: 0.2.13 + + yocto-queue@0.1.0: {} + + yocto-queue@1.0.0: {} diff --git a/prettier.config.cjs b/prettier.config.cjs index 2851864..9171d71 100644 --- a/prettier.config.cjs +++ b/prettier.config.cjs @@ -27,7 +27,7 @@ module.exports = { insertPragma: false, // use lf for line breaks - endOfLine: 'lf', + endOfLine: 'auto', // Whether the curly braces of the object literal should start on a new line // eslint-disable-next-line no-dupe-keys From befe59c26bca712ff8af10d139f8f3c56cae53ad Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Fri, 6 Sep 2024 14:31:07 +0800 Subject: [PATCH 13/47] =?UTF-8?q?chore(wormhole):=20=E8=B0=83=E6=95=B4tsco?= =?UTF-8?q?nfig=EF=BC=8C=E7=A7=BB=E5=8A=A8templates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 2 +- packages/templates/package.json | 13 -------- packages/vscode-extension/tsconfig.json | 5 ++- packages/wormhole/package.json | 5 +-- .../wormhole/src/functions/openApi2Data.ts | 8 ++--- .../src}/templates/alova.config.handlebars | 0 .../src}/templates/apiDefinitions.handlebars | 0 .../src}/templates/comment.handlebars | 0 .../templates/commonjs/createApis.handlebars | 0 .../src}/templates/commonjs/index.handlebars | 0 .../commonjs/v3-createApis.handlebars | 0 .../templates/commonjs/v3-index.handlebars | 0 .../src}/templates/globals.d.handlebars | 0 .../{ => wormhole/src}/templates/index.ts | 0 .../templates/module/createApis.handlebars | 0 .../src}/templates/module/index.handlebars | 0 .../templates/module/v3-createApis.handlebars | 0 .../src}/templates/module/v3-index.handlebars | 0 .../typescript/createApis.handlebars | 0 .../templates/typescript/index.handlebars | 0 .../typescript/v3-createApis.handlebars | 0 .../templates/typescript/v3-index.handlebars | 0 .../src}/templates/v3-globals.d.handlebars | 0 packages/wormhole/src/utils/index.ts | 18 +++++++++-- prettier.config.cjs | 1 - tsconfig.base.json | 31 +++++++++++++++++++ tsconfig.json | 30 +++--------------- 27 files changed, 61 insertions(+), 52 deletions(-) delete mode 100644 packages/templates/package.json rename packages/{ => wormhole/src}/templates/alova.config.handlebars (100%) rename packages/{ => wormhole/src}/templates/apiDefinitions.handlebars (100%) rename packages/{ => wormhole/src}/templates/comment.handlebars (100%) rename packages/{ => wormhole/src}/templates/commonjs/createApis.handlebars (100%) rename packages/{ => wormhole/src}/templates/commonjs/index.handlebars (100%) rename packages/{ => wormhole/src}/templates/commonjs/v3-createApis.handlebars (100%) rename packages/{ => wormhole/src}/templates/commonjs/v3-index.handlebars (100%) rename packages/{ => wormhole/src}/templates/globals.d.handlebars (100%) rename packages/{ => wormhole/src}/templates/index.ts (100%) rename packages/{ => wormhole/src}/templates/module/createApis.handlebars (100%) rename packages/{ => wormhole/src}/templates/module/index.handlebars (100%) rename packages/{ => wormhole/src}/templates/module/v3-createApis.handlebars (100%) rename packages/{ => wormhole/src}/templates/module/v3-index.handlebars (100%) rename packages/{ => wormhole/src}/templates/typescript/createApis.handlebars (100%) rename packages/{ => wormhole/src}/templates/typescript/index.handlebars (100%) rename packages/{ => wormhole/src}/templates/typescript/v3-createApis.handlebars (100%) rename packages/{ => wormhole/src}/templates/typescript/v3-index.handlebars (100%) rename packages/{ => wormhole/src}/templates/v3-globals.d.handlebars (100%) create mode 100644 tsconfig.base.json diff --git a/.vscode/settings.json b/.vscode/settings.json index b225c4d..a2cd88d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,6 @@ // Place your settings in this file to overwrite default and user settings. { - "editor.formatOnSave": true, + // "editor.formatOnSave": true, "editor.tabSize": 2, "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.suggestSelection": "recentlyUsedByPrefix", diff --git a/packages/templates/package.json b/packages/templates/package.json deleted file mode 100644 index 165b21d..0000000 --- a/packages/templates/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "@alova/templates", - "version": "1.0.0", - "description": "", - "main": "index.ts", - "module": "index.ts", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [], - "author": "", - "license": "ISC" -} diff --git a/packages/vscode-extension/tsconfig.json b/packages/vscode-extension/tsconfig.json index d84a9f1..267f6b4 100644 --- a/packages/vscode-extension/tsconfig.json +++ b/packages/vscode-extension/tsconfig.json @@ -1,6 +1,9 @@ { - "extends": "../../tsconfig.json", + "extends": "../../tsconfig.base.json", + "include": ["src/**/*.ts", "./typings"], "compilerOptions": { + "outDir": "./dist", + "baseUrl": ".", "paths": { "~/*": ["./typings/*"], "@/*": ["./src/*"], diff --git a/packages/wormhole/package.json b/packages/wormhole/package.json index d1398ee..d66e0d1 100644 --- a/packages/wormhole/package.json +++ b/packages/wormhole/package.json @@ -10,8 +10,5 @@ }, "keywords": [], "author": "", - "license": "ISC", - "dependencies": { - "@alova/templates": "workspace:^" - } + "license": "ISC" } diff --git a/packages/wormhole/src/functions/openApi2Data.ts b/packages/wormhole/src/functions/openApi2Data.ts index f486307..14c35e2 100644 --- a/packages/wormhole/src/functions/openApi2Data.ts +++ b/packages/wormhole/src/functions/openApi2Data.ts @@ -38,13 +38,13 @@ interface PathApis { export const getApiDefultValue = (api: Api) => { const configStrArr: string[] = []; if (api.pathParametersComment) { - configStrArr.push(`pathParams: ${generateDefaultValues(api.pathParametersComment.replaceAll('*', ''))}`); + configStrArr.push(`pathParams: ${generateDefaultValues(api.pathParametersComment.replace(/\*/g, ''))}`); } if (api.queryParametersComment) { - configStrArr.push(`params: ${generateDefaultValues(api.queryParametersComment.replaceAll('*', ''))}`); + configStrArr.push(`params: ${generateDefaultValues(api.queryParametersComment.replace(/\*/g, ''))}`); } if (api.requestComment) { - configStrArr.push(`data: ${generateDefaultValues(api.requestComment.replaceAll('*', ''))}`); + configStrArr.push(`data: ${generateDefaultValues(api.requestComment.replace(/\*/g, ''))}`); } return format(`${api.global}.${api.pathKey}({${configStrArr.join(',\n')}})`, { printWidth: 40, // 缩短printWidth以强制换行 @@ -411,7 +411,7 @@ export default async function openApi2Data( ); const api: Api = { method: methodFormat, - summary: methodInfo.summary?.replaceAll('\n', '') ?? '', + summary: methodInfo.summary?.replace(/\n/g, '') ?? '', path, name: methodInfo.operationId ?? '', responseName, diff --git a/packages/templates/alova.config.handlebars b/packages/wormhole/src/templates/alova.config.handlebars similarity index 100% rename from packages/templates/alova.config.handlebars rename to packages/wormhole/src/templates/alova.config.handlebars diff --git a/packages/templates/apiDefinitions.handlebars b/packages/wormhole/src/templates/apiDefinitions.handlebars similarity index 100% rename from packages/templates/apiDefinitions.handlebars rename to packages/wormhole/src/templates/apiDefinitions.handlebars diff --git a/packages/templates/comment.handlebars b/packages/wormhole/src/templates/comment.handlebars similarity index 100% rename from packages/templates/comment.handlebars rename to packages/wormhole/src/templates/comment.handlebars diff --git a/packages/templates/commonjs/createApis.handlebars b/packages/wormhole/src/templates/commonjs/createApis.handlebars similarity index 100% rename from packages/templates/commonjs/createApis.handlebars rename to packages/wormhole/src/templates/commonjs/createApis.handlebars diff --git a/packages/templates/commonjs/index.handlebars b/packages/wormhole/src/templates/commonjs/index.handlebars similarity index 100% rename from packages/templates/commonjs/index.handlebars rename to packages/wormhole/src/templates/commonjs/index.handlebars diff --git a/packages/templates/commonjs/v3-createApis.handlebars b/packages/wormhole/src/templates/commonjs/v3-createApis.handlebars similarity index 100% rename from packages/templates/commonjs/v3-createApis.handlebars rename to packages/wormhole/src/templates/commonjs/v3-createApis.handlebars diff --git a/packages/templates/commonjs/v3-index.handlebars b/packages/wormhole/src/templates/commonjs/v3-index.handlebars similarity index 100% rename from packages/templates/commonjs/v3-index.handlebars rename to packages/wormhole/src/templates/commonjs/v3-index.handlebars diff --git a/packages/templates/globals.d.handlebars b/packages/wormhole/src/templates/globals.d.handlebars similarity index 100% rename from packages/templates/globals.d.handlebars rename to packages/wormhole/src/templates/globals.d.handlebars diff --git a/packages/templates/index.ts b/packages/wormhole/src/templates/index.ts similarity index 100% rename from packages/templates/index.ts rename to packages/wormhole/src/templates/index.ts diff --git a/packages/templates/module/createApis.handlebars b/packages/wormhole/src/templates/module/createApis.handlebars similarity index 100% rename from packages/templates/module/createApis.handlebars rename to packages/wormhole/src/templates/module/createApis.handlebars diff --git a/packages/templates/module/index.handlebars b/packages/wormhole/src/templates/module/index.handlebars similarity index 100% rename from packages/templates/module/index.handlebars rename to packages/wormhole/src/templates/module/index.handlebars diff --git a/packages/templates/module/v3-createApis.handlebars b/packages/wormhole/src/templates/module/v3-createApis.handlebars similarity index 100% rename from packages/templates/module/v3-createApis.handlebars rename to packages/wormhole/src/templates/module/v3-createApis.handlebars diff --git a/packages/templates/module/v3-index.handlebars b/packages/wormhole/src/templates/module/v3-index.handlebars similarity index 100% rename from packages/templates/module/v3-index.handlebars rename to packages/wormhole/src/templates/module/v3-index.handlebars diff --git a/packages/templates/typescript/createApis.handlebars b/packages/wormhole/src/templates/typescript/createApis.handlebars similarity index 100% rename from packages/templates/typescript/createApis.handlebars rename to packages/wormhole/src/templates/typescript/createApis.handlebars diff --git a/packages/templates/typescript/index.handlebars b/packages/wormhole/src/templates/typescript/index.handlebars similarity index 100% rename from packages/templates/typescript/index.handlebars rename to packages/wormhole/src/templates/typescript/index.handlebars diff --git a/packages/templates/typescript/v3-createApis.handlebars b/packages/wormhole/src/templates/typescript/v3-createApis.handlebars similarity index 100% rename from packages/templates/typescript/v3-createApis.handlebars rename to packages/wormhole/src/templates/typescript/v3-createApis.handlebars diff --git a/packages/templates/typescript/v3-index.handlebars b/packages/wormhole/src/templates/typescript/v3-index.handlebars similarity index 100% rename from packages/templates/typescript/v3-index.handlebars rename to packages/wormhole/src/templates/typescript/v3-index.handlebars diff --git a/packages/templates/v3-globals.d.handlebars b/packages/wormhole/src/templates/v3-globals.d.handlebars similarity index 100% rename from packages/templates/v3-globals.d.handlebars rename to packages/wormhole/src/templates/v3-globals.d.handlebars diff --git a/packages/wormhole/src/utils/index.ts b/packages/wormhole/src/utils/index.ts index f2001d0..452bfe6 100644 --- a/packages/wormhole/src/utils/index.ts +++ b/packages/wormhole/src/utils/index.ts @@ -1,5 +1,4 @@ /* eslint-disable no-bitwise */ -import prettierConfig from '#/prettier.config.cjs'; import handlebars, { HelperOptions } from 'handlebars'; import fetch from 'node-fetch'; import fs, { promises } from 'node:fs'; @@ -11,6 +10,21 @@ import * as prettierTs from 'prettier/plugins/typescript'; import * as prettier from 'prettier/standalone'; import { DEFAULT_CONFIG } from '../config'; +export const prettierConfig: PrettierConfig = { + printWidth: 120, + tabWidth: 2, + useTabs: false, + semi: true, + singleQuote: true, + trailingComma: 'none', + bracketSpacing: true, + insertPragma: false, + endOfLine: 'auto', + bracketSameLine: true, + arrowParens: 'avoid', + vueIndentScriptAndStyle: false, + singleAttributePerLine: true +}; export const getType = (obj: any) => Object.prototype.toString.call(obj).slice(8, -1).toLowerCase(); handlebars.registerHelper('isType', function (this: any, value, type: string, options: HelperOptions) { if (getType(value) === type) { @@ -60,7 +74,7 @@ export async function readAndRenderTemplate(templatePath: string, view: any): Pr try { data = await promises.readFile(path.resolve(DEFAULT_CONFIG.templatePath, `${templatePath}.handlebars`), 'utf-8'); } catch (error) { - const importFn = (await import('@alova/templates')).default; + const importFn = (await import('../templates/index.js')).default; data = (await (importFn as any)(templatePath)).default; } return handlebars.compile(data)(view); diff --git a/prettier.config.cjs b/prettier.config.cjs index 9171d71..59ba6ab 100644 --- a/prettier.config.cjs +++ b/prettier.config.cjs @@ -31,7 +31,6 @@ module.exports = { // Whether the curly braces of the object literal should start on a new line // eslint-disable-next-line no-dupe-keys - bracketSameLine: true, // Whether the arrow function parameters use parentheses arrowParens: 'avoid', diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 0000000..2b3f5bc --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,31 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "resolveJsonModule": true, + "target": "es2018", + "module": "esnext", + "moduleResolution": "bundler", + "strict": true, + "newLine": "LF", + "noImplicitAny": true, + "noEmitOnError": false, + "noUnusedLocals": true, + "noUnusedParameters": false, + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "strictPropertyInitialization": false, + "noFallthroughCasesInSwitch": false, + "skipLibCheck": true, + "allowJs": true, + "skipDefaultLibCheck": false, + "inlineSourceMap": false, + "importHelpers": true, + "removeComments": false, + "esModuleInterop": true, + "jsx": "preserve", + "paths": { + "#/*": ["./*"], + "@alova/*": ["./packages/src/*"] + } + } +} diff --git a/tsconfig.json b/tsconfig.json index 8356af3..7f224ec 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,30 +1,8 @@ { + "extends": "./tsconfig.base.json", + "exclude": ["design/**", "test/**"], "compilerOptions": { - "resolveJsonModule": true, - "module": "Node16", - "target": "ES2022", - "outDir": "out", - "strict": true, - "newLine": "LF", - "lib": ["ES2022"], - "noImplicitAny": true, - "noEmitOnError": false, - "noUnusedLocals": true, - "noUnusedParameters": false, - "allowUnreachableCode": false, - "allowUnusedLabels": false, - "strictPropertyInitialization": false, - "noFallthroughCasesInSwitch": false, - "skipLibCheck": true, - "skipDefaultLibCheck": false, - "esModuleInterop": true, - "strictNullChecks": true, - "allowJs": true, - "paths": { - "#/*": ["./*"], - "@alova/*": ["./packages/*"] - } + "outDir": "./dist" }, - "exclude": ["design/**", "test/**"], - "include": ["src/**/*.ts", "packages/**/*.ts", "*.*js", "*.*ts", "scripts/**.*", "typings/**/*.d.ts"] + "include": ["packages/**/*.ts", "*.*js", "*.*ts", "scripts/**.*", "typings/**/*.d.ts"] } From 800ec196d1c1b98125c7d3a7d23491ea5039c2df Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Fri, 6 Sep 2024 18:20:44 +0800 Subject: [PATCH 14/47] =?UTF-8?q?build(wormhole):=20=E4=BD=BF=E7=94=A8unbu?= =?UTF-8?q?ild=E6=89=93=E5=8C=85wormhole?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 2 +- package.json | 4 +- packages/vscode-extension/esbuild.ts | 122 +- packages/vscode-extension/package.json | 162 +- .../src/helper/configuration.ts | 4 - packages/vscode-extension/src/work/getApis.ts | 42 +- packages/vscode-extension/tsconfig.json | 32 +- packages/wormhole/build.config.ts | 30 + packages/wormhole/package.json | 25 +- packages/wormhole/src/createConfig.ts | 30 +- packages/wormhole/src/functions/alovaJson.ts | 110 +- .../wormhole/src/functions/generateApi.ts | 174 +- .../src/functions/getAutoTemplateType.ts | 28 +- .../wormhole/src/functions/getOpenApiData.ts | 190 +- .../wormhole/src/functions/openApi2Data.ts | 912 ++++---- packages/wormhole/src/generate.ts | 62 +- packages/wormhole/src/helper/lodaders.ts | 210 +- packages/wormhole/src/helper/openapi.ts | 582 ++--- packages/wormhole/src/helper/schema2type.ts | 674 +++--- packages/wormhole/src/helper/typeStr.ts | 348 +-- packages/wormhole/src/index.ts | 2 +- .../wormhole/src/modules/Configuration.ts | 274 +-- packages/wormhole/src/modules/TemplateFile.ts | 156 +- packages/wormhole/src/readConfig.ts | 92 +- packages/wormhole/src/templates/index.ts | 1 - packages/wormhole/src/utils/index.ts | 295 ++- packages/wormhole/tsconfig.json | 12 + .../{src/type.ts => typings/index.d.ts} | 158 +- pnpm-lock.yaml | 1880 ++++++++++++++++- tsconfig.base.json | 61 +- tsconfig.json | 16 +- 31 files changed, 4235 insertions(+), 2455 deletions(-) delete mode 100644 packages/vscode-extension/src/helper/configuration.ts create mode 100644 packages/wormhole/build.config.ts delete mode 100644 packages/wormhole/src/templates/index.ts create mode 100644 packages/wormhole/tsconfig.json rename packages/wormhole/{src/type.ts => typings/index.d.ts} (97%) diff --git a/.vscode/settings.json b/.vscode/settings.json index a2cd88d..b225c4d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,6 @@ // Place your settings in this file to overwrite default and user settings. { - // "editor.formatOnSave": true, + "editor.formatOnSave": true, "editor.tabSize": 2, "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.suggestSelection": "recentlyUsedByPrefix", diff --git a/package.json b/package.json index 43b0d6e..8d740ab 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,6 @@ "eslint": "^8.57.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^18.0.0", - "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", "husky": "^9.0.11", "js-yaml": "^4.1.0", @@ -55,9 +54,10 @@ "prettier": "^3.2.5", "prettier-plugin-organize-imports": "^3.2.4", "prettier-plugin-sort-json": "^4.0.0", + "tslib": "^2.7.0", "tsx": "^4.15.8", "type-fest": "^4.20.0", - "typescript": "^5.4.5" + "typescript": "^5.5.4" }, "config": { "commitizen": { diff --git a/packages/vscode-extension/esbuild.ts b/packages/vscode-extension/esbuild.ts index abcf05c..e6449ac 100644 --- a/packages/vscode-extension/esbuild.ts +++ b/packages/vscode-extension/esbuild.ts @@ -1,61 +1,61 @@ -import esbuild, { Plugin } from 'esbuild'; -import alias from 'esbuild-plugin-alias'; -import path from 'node:path'; - -const production = process.argv.includes('--production'); -const watch = process.argv.includes('--watch'); - -const esbuildProblemMatcherPlugin: Plugin = { - name: 'esbuild-problem-matcher', - - setup(build) { - build.onStart(() => { - console.log('[watch] build started'); - }); - build.onEnd(result => { - result.errors.forEach(({ text, location }) => { - console.error(`✘ [ERROR] ${text}`); - console.error(` ${location?.file ?? ''}:${location?.line ?? ''}:${location?.column ?? ''}:`); - }); - console.log('[watch] build finished'); - }); - } -}; - -async function main() { - const ctx = await esbuild.context({ - entryPoints: ['src/extension.ts', 'src/work.ts'], - loader: { - '.handlebars': 'text' - }, - bundle: true, - format: 'cjs', - minify: production, - sourcemap: !production, - sourcesContent: false, - platform: 'node', - outdir: 'out', - external: ['vscode', 'typescript'], - logLevel: 'silent', - plugins: [ - alias({ - '@': path.resolve(__dirname, './src'), - '~': path.resolve(__dirname, './typings'), - '#': path.resolve(__dirname, '.') - }) as Plugin, - /* add to the end of plugins array */ - esbuildProblemMatcherPlugin - ] - }); - if (watch) { - await ctx.watch(); - } else { - await ctx.rebuild(); - await ctx.dispose(); - } -} - -main().catch(e => { - console.error(e); - process.exit(1); -}); +import esbuild, { Plugin } from 'esbuild'; +import alias from 'esbuild-plugin-alias'; +import path from 'node:path'; + +const production = process.argv.includes('--production'); +const watch = process.argv.includes('--watch'); + +const esbuildProblemMatcherPlugin: Plugin = { + name: 'esbuild-problem-matcher', + + setup(build) { + build.onStart(() => { + console.log('[watch] build started'); + }); + build.onEnd(result => { + result.errors.forEach(({ text, location }) => { + console.error(`✘ [ERROR] ${text}`); + console.error(` ${location?.file ?? ''}:${location?.line ?? ''}:${location?.column ?? ''}:`); + }); + console.log('[watch] build finished'); + }); + } +}; + +async function main() { + const ctx = await esbuild.context({ + entryPoints: ['src/extension.ts', 'src/work.ts'], + loader: { + '.handlebars': 'text' + }, + bundle: true, + format: 'cjs', + minify: production, + sourcemap: !production, + sourcesContent: false, + platform: 'node', + outdir: 'out', + external: ['vscode', 'typescript'], + logLevel: 'silent', + plugins: [ + alias({ + '@': path.resolve(__dirname, './src'), + '~': path.resolve(__dirname, './typings'), + '#': path.resolve(__dirname, '.') + }) as Plugin, + /* add to the end of plugins array */ + esbuildProblemMatcherPlugin + ] + }); + if (watch) { + await ctx.watch(); + } else { + await ctx.rebuild(); + await ctx.dispose(); + } +} + +main().catch(e => { + console.error(e); + process.exit(1); +}); diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index ea61dea..5616064 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -1,81 +1,81 @@ -{ - "name": "alova-vscode-extension", - "displayName": "Alova", - "description": "Generate and search APIs without API documentation any more", - "version": "0.0.10", - "engines": { - "vscode": "^1.89.0", - "node": ">=18.19.0", - "pnpm": ">=8.6.12" - }, - "categories": [ - "Other" - ], - "activationEvents": [ - "workspaceContains:**/*.ts", - "workspaceContains:**/*.js" - ], - "main": "./out/extension.js", - "icon": "resources/icon.png", - "contributes": { - "commands": [ - { - "command": "alova.refresh", - "category": "Alova", - "title": "Generate APIs" - }, - { - "command": "alova.create.config", - "category": "Alova", - "title": "Create alova config" - } - ], - "icons": { - "alova-icon-id": { - "description": "alova icon", - "default": { - "fontPath": "./resources/logo.ttf", - "fontCharacter": "\\E900" - } - } - } - }, - "scripts": { - "vscode:prepublish": "pnpm run package", - "compile": "pnpm run check-types && pnpm run lint:fix && tsx esbuild.ts", - "watch": "npm-run-all -p watch:*", - "watch:esbuild": "tsx esbuild.ts --watch", - "watch:tsc": "tsc --noEmit --watch --project tsconfig.json", - "package": "pnpm run check-types && pnpm run lint:fix && tsx esbuild.ts --production", - "compile-tests": "tsc -p . --outDir out", - "watch-tests": "tsc -p . -w --outDir out", - "pretest": "pnpm run compile-tests && pnpm run compile && pnpm run lint", - "check-types": "tsc --noEmit", - "lint": "eslint . --ext .js,.ts", - "lint:fix": "npm run lint -- --fix", - "format": "prettier --check .", - "format:fix": "prettier --write .", - "test": "vscode-test", - "pack:pre": "vsce package --no-dependencies --pre-release", - "release:pre": "vsce publish --no-dependencies --pre-release", - "pack": "vsce package --no-dependencies", - "release": "vsce publish --no-dependencies" - }, - "publisher": "Alova", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/alovajs/devtools.git" - }, - "bugs": { - "url": "https://github.com/alovajs/devtools/issues" - }, - "devDependencies": { - "@types/vscode": "^1.89.0", - "@vscode/test-cli": "^0.0.9", - "@vscode/test-electron": "^2.3.9", - "@vscode/vsce": "^2.29.0", - "esbuild": "^0.23.0", - "esbuild-plugin-alias": "^0.2.1" - } -} +{ + "name": "alova-vscode-extension", + "displayName": "Alova", + "description": "Generate and search APIs without API documentation any more", + "version": "0.0.10", + "engines": { + "vscode": "^1.89.0", + "node": ">=18.19.0", + "pnpm": ">=8.6.12" + }, + "categories": [ + "Other" + ], + "activationEvents": [ + "workspaceContains:**/*.ts", + "workspaceContains:**/*.js" + ], + "main": "./out/extension.js", + "icon": "resources/icon.png", + "contributes": { + "commands": [ + { + "command": "alova.refresh", + "category": "Alova", + "title": "Generate APIs" + }, + { + "command": "alova.create.config", + "category": "Alova", + "title": "Create alova config" + } + ], + "icons": { + "alova-icon-id": { + "description": "alova icon", + "default": { + "fontPath": "./resources/logo.ttf", + "fontCharacter": "\\E900" + } + } + } + }, + "scripts": { + "vscode:prepublish": "pnpm run package", + "compile": "pnpm run check-types && pnpm run lint:fix && tsx esbuild.ts", + "watch": "npm-run-all -p watch:*", + "watch:esbuild": "tsx esbuild.ts --watch", + "watch:tsc": "tsc --noEmit --watch --project tsconfig.json", + "package": "pnpm run check-types && pnpm run lint:fix && tsx esbuild.ts --production", + "compile-tests": "tsc -p . --outDir out", + "watch-tests": "tsc -p . -w --outDir out", + "pretest": "pnpm run compile-tests && pnpm run compile && pnpm run lint", + "check-types": "tsc --noEmit", + "lint": "eslint . --ext .js,.ts", + "lint:fix": "npm run lint -- --fix", + "format": "prettier --check .", + "format:fix": "prettier --write .", + "test": "vscode-test", + "pack:pre": "vsce package --no-dependencies --pre-release", + "release:pre": "vsce publish --no-dependencies --pre-release", + "pack": "vsce package --no-dependencies", + "release": "vsce publish --no-dependencies" + }, + "publisher": "Alova", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/alovajs/devtools.git" + }, + "bugs": { + "url": "https://github.com/alovajs/devtools/issues" + }, + "devDependencies": { + "@types/vscode": "^1.89.0", + "@vscode/test-cli": "^0.0.9", + "@vscode/test-electron": "^2.3.9", + "@vscode/vsce": "^2.29.0", + "esbuild": "^0.23.0", + "esbuild-plugin-alias": "^0.2.1" + } +} diff --git a/packages/vscode-extension/src/helper/configuration.ts b/packages/vscode-extension/src/helper/configuration.ts deleted file mode 100644 index 2cb9a3f..0000000 --- a/packages/vscode-extension/src/helper/configuration.ts +++ /dev/null @@ -1,4 +0,0 @@ -import Configuration from '@alova/wormhole/src/modules/Configuration'; - -export const CONFIG_POOL: Array = []; -export default { CONFIG_POOL }; diff --git a/packages/vscode-extension/src/work/getApis.ts b/packages/vscode-extension/src/work/getApis.ts index e0b9386..a62b737 100644 --- a/packages/vscode-extension/src/work/getApis.ts +++ b/packages/vscode-extension/src/work/getApis.ts @@ -1,21 +1,21 @@ -import { DEFAULT_CONFIG, getAlovaJsonPath } from '@alova/wormhole'; -import path from 'node:path'; -import { CONFIG_POOL } from './config'; - -export default (filePath: string) => { - const config = CONFIG_POOL.find(item => filePath.includes(path.resolve(item.workspaceRootDir))); - if (!config) { - return []; - } - const outputArr = config?.getAllOutputPath() || []; - return outputArr - .map(output => { - const apiPath = getAlovaJsonPath(config.workspaceRootDir, output); - const templateData = DEFAULT_CONFIG.templateData.get(apiPath); - if (!templateData) { - return []; - } - return templateData.pathApis.map(item => item.apis); - }) - .flat(2); -}; +import { DEFAULT_CONFIG, getAlovaJsonPath } from '@alova/wormhole'; +import path from 'node:path'; +import { CONFIG_POOL } from './config'; + +export default (filePath: string) => { + const config = CONFIG_POOL.find(item => filePath.includes(path.resolve(item.workspaceRootDir))); + if (!config) { + return []; + } + const outputArr = config?.getAllOutputPath() || []; + return outputArr + .map(output => { + const apiPath = getAlovaJsonPath(config.workspaceRootDir, output); + const templateData = DEFAULT_CONFIG.templateData.get(apiPath); + if (!templateData) { + return []; + } + return templateData.pathApis.map(item => item.apis); + }) + .flat(2); +}; diff --git a/packages/vscode-extension/tsconfig.json b/packages/vscode-extension/tsconfig.json index 267f6b4..dd46f09 100644 --- a/packages/vscode-extension/tsconfig.json +++ b/packages/vscode-extension/tsconfig.json @@ -1,13 +1,19 @@ -{ - "extends": "../../tsconfig.base.json", - "include": ["src/**/*.ts", "./typings"], - "compilerOptions": { - "outDir": "./dist", - "baseUrl": ".", - "paths": { - "~/*": ["./typings/*"], - "@/*": ["./src/*"], - "#/*": ["../../*"] - } - } -} +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "resolveJsonModule": true, + "target": "ES2022", + "module": "Node16", + "moduleResolution": "NodeNext", + "outDir": "out", + "strictNullChecks": true, + "lib": ["ES2022"], + "paths": { + "~/*": ["./typings/*"], + "@/*": ["./src/*"], + "#/*": ["./*"] + } + }, + "exclude": ["design/**", "./node_modules", "test/**"], + "include": ["src/**/*.ts", "*.*js", "*.*ts", "scripts/**.*", "typings/**/*.d.ts"] +} diff --git a/packages/wormhole/build.config.ts b/packages/wormhole/build.config.ts new file mode 100644 index 0000000..077e660 --- /dev/null +++ b/packages/wormhole/build.config.ts @@ -0,0 +1,30 @@ +import path from 'node:path'; +import { defineBuildConfig } from 'unbuild'; + +export default defineBuildConfig({ + entries: ['src/index'], + clean: true, + declaration: true, + failOnWarn: false, + hooks: { + 'build:done': async () => { + // copy all things under src/templates to dist/templates + // https://github.com/unjs/unbuild/issues/266 + const { copy } = await import('fs-extra'); + await copy('src/templates', 'dist/templates'); + } + }, + rollup: { + alias: { + entries: { + '@': path.resolve(__dirname, './src'), + '~': path.resolve(__dirname, './typings'), + '#': path.join(__dirname) + } + }, + dts: { + respectExternal: false + }, + emitCJS: true + } +}); diff --git a/packages/wormhole/package.json b/packages/wormhole/package.json index d66e0d1..fae0e6d 100644 --- a/packages/wormhole/package.json +++ b/packages/wormhole/package.json @@ -3,12 +3,29 @@ "version": "1.0.0", "description": "generate api for alova.js", "homepage": "https://alova.js.org", - "main": "src/index.ts", - "module": "src/index.ts", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.cjs" + } + }, "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "build": "unbuild", + "dev": "pnpm run stub", + "stub": "unbuild --stub" }, "keywords": [], "author": "", - "license": "ISC" + "license": "ISC", + "devDependencies": { + "@types/fs-extra": "^11.0.4", + "unbuild": "^2.0.0" + }, + "dependencies": { + "fs-extra": "^11.2.0" + } } diff --git a/packages/wormhole/src/createConfig.ts b/packages/wormhole/src/createConfig.ts index 0ad5e56..74c0bb4 100644 --- a/packages/wormhole/src/createConfig.ts +++ b/packages/wormhole/src/createConfig.ts @@ -1,15 +1,15 @@ -import getAlovaVersion, { AlovaVersion } from './functions/getAlovaVersion'; -import getAutoTemplateType from './functions/getAutoTemplateType'; -import TemplateFile from './modules/TemplateFile'; - -export const createConfig = async (projectPath: string = process.cwd()) => { - const type = getAutoTemplateType(projectPath); - const moduleType = TemplateFile.getModuleType(type); - const alovaVersion: AlovaVersion = getAlovaVersion(projectPath); - const templateFile = new TemplateFile(type, alovaVersion); - return templateFile.outputFile({ type, moduleType }, 'alova.config', projectPath, { - root: true, - hasVersion: false - }); -}; -export default createConfig; +import getAlovaVersion, { AlovaVersion } from './functions/getAlovaVersion'; +import getAutoTemplateType from './functions/getAutoTemplateType'; +import TemplateFile from './modules/TemplateFile'; + +export const createConfig = async (projectPath: string = process.cwd()) => { + const type = getAutoTemplateType(projectPath); + const moduleType = TemplateFile.getModuleType(type); + const alovaVersion: AlovaVersion = getAlovaVersion(projectPath); + const templateFile = new TemplateFile(type, alovaVersion); + return templateFile.outputFile({ type, moduleType }, 'alova.config', projectPath, { + root: true, + hasVersion: false + }); +}; +export default createConfig; diff --git a/packages/wormhole/src/functions/alovaJson.ts b/packages/wormhole/src/functions/alovaJson.ts index cdeddfb..3598e38 100644 --- a/packages/wormhole/src/functions/alovaJson.ts +++ b/packages/wormhole/src/functions/alovaJson.ts @@ -1,55 +1,55 @@ -import fs from 'node:fs'; -import path from 'node:path'; -import { DEFAULT_CONFIG } from '../config'; -import { format } from '../utils'; -import type { TemplateData } from './openApi2Data'; - -export const writeAlovaJson = async (data: TemplateData, originPath: string, name = 'api.json') => { - // 将数据转换为 JSON 字符串 - let jsonData = ''; - try { - jsonData = await format(JSON.stringify(data, null, 2), { parser: 'json' }); - } catch (error) { - console.log(error, 13); - } - // 定义 JSON 文件的路径和名称 - const filePath = `${originPath}_${name}`; - const dirPath = filePath.split(/\/|\\/).slice(0, -1).join('/'); - if (!fs.existsSync(dirPath)) { - fs.mkdirSync(dirPath, { recursive: true }); - } - // 使用 fs.writeFile 将 JSON 数据写入文件 - fs.writeFile(filePath, jsonData, err => { - if (err) { - console.error('Error writing file:', err); - } else { - console.log('JSON file has been saved.'); - } - }); -}; -export const readAlovaJson = (originPath: string, name = 'api.json') => { - // 定义 JSON 文件的路径和名称 - const filePath = `${originPath}_${name}`; - return new Promise((resolve, reject) => { - if (!fs.existsSync(filePath)) { - reject(new DEFAULT_CONFIG.Error('alovaJson not exists')); - return; - } - // 使用 fs.readFile 读取 JSON 文件 - fs.readFile(filePath, 'utf8', (err, data) => { - if (err) { - reject(err); - } else { - let jsonData = {}; - try { - jsonData = JSON.parse(data); - } catch (error) { - jsonData = {}; - } - resolve(jsonData as TemplateData); - } - }); - }); -}; -export const getAlovaJsonPath = (workspaceRootDir: string, outputPath: string) => - path.join(workspaceRootDir, DEFAULT_CONFIG.alovaTempPath, outputPath.split(/\/|\\/).join('_')); +import { DEFAULT_CONFIG } from '@/config'; +import { format } from '@/utils'; +import fs from 'node:fs'; +import path from 'node:path'; +import type { TemplateData } from './openApi2Data'; + +export const writeAlovaJson = async (data: TemplateData, originPath: string, name = 'api.json') => { + // 将数据转换为 JSON 字符串 + let jsonData = ''; + try { + jsonData = await format(JSON.stringify(data, null, 2), { parser: 'json' }); + } catch (error) { + console.log(error, 13); + } + // 定义 JSON 文件的路径和名称 + const filePath = `${originPath}_${name}`; + const dirPath = filePath.split(/\/|\\/).slice(0, -1).join('/'); + if (!fs.existsSync(dirPath)) { + fs.mkdirSync(dirPath, { recursive: true }); + } + // 使用 fs.writeFile 将 JSON 数据写入文件 + fs.writeFile(filePath, jsonData, err => { + if (err) { + console.error('Error writing file:', err); + } else { + console.log('JSON file has been saved.'); + } + }); +}; +export const readAlovaJson = (originPath: string, name = 'api.json') => { + // 定义 JSON 文件的路径和名称 + const filePath = `${originPath}_${name}`; + return new Promise((resolve, reject) => { + if (!fs.existsSync(filePath)) { + reject(new DEFAULT_CONFIG.Error('alovaJson not exists')); + return; + } + // 使用 fs.readFile 读取 JSON 文件 + fs.readFile(filePath, 'utf8', (err, data) => { + if (err) { + reject(err); + } else { + let jsonData = {}; + try { + jsonData = JSON.parse(data); + } catch (error) { + jsonData = {}; + } + resolve(jsonData as TemplateData); + } + }); + }); +}; +export const getAlovaJsonPath = (workspaceRootDir: string, outputPath: string) => + path.join(workspaceRootDir, DEFAULT_CONFIG.alovaTempPath, outputPath.split(/\/|\\/).join('_')); diff --git a/packages/wormhole/src/functions/generateApi.ts b/packages/wormhole/src/functions/generateApi.ts index 952745f..1949bf0 100644 --- a/packages/wormhole/src/functions/generateApi.ts +++ b/packages/wormhole/src/functions/generateApi.ts @@ -1,87 +1,87 @@ -import { isEqual } from 'lodash'; -import fs from 'node:fs'; -import path from 'node:path'; -import { OpenAPIV3_1 } from 'openapi-types'; -import type { GeneratorConfig, TemplateType } from '..'; -import { DEFAULT_CONFIG } from '../config'; -import TemplateFile from '../modules/TemplateFile'; -import { getAlovaJsonPath, writeAlovaJson } from './alovaJson'; -import getAlovaVersion, { AlovaVersion } from './getAlovaVersion'; -import getFrameworkTag from './getFrameworkTag'; -import openApi2Data from './openApi2Data'; - -export default async function ( - workspaceRootDir: string, // 项目地址 - outputPath: string, // 输出路径 - data: OpenAPIV3_1.Document, // openapi数据 - config: GeneratorConfig, // generator配置 - type: TemplateType, // 模板类型 - force: boolean // 是否强制生成 -) { - if (!data) { - return; - } - // 输出目录 - const outputDir = path.join(workspaceRootDir, outputPath); - // 缓存文件地址 - const alovaJsonPath = getAlovaJsonPath(workspaceRootDir, outputPath); - // 获取alova版本 - const configVersion = Number(config.version); - const alovaVersion: AlovaVersion = Number.isNaN(configVersion) - ? getAlovaVersion(workspaceRootDir) - : `v${configVersion}`; - const templateFile = new TemplateFile(type, alovaVersion); - // 将openApi对象转成template对象 - const templateData = await openApi2Data(data, config); - // 框架技术栈标签 vue | react - templateData[getFrameworkTag(workspaceRootDir)] = true; - // 头部注释部分 - templateData.commentText = await templateFile.readAndRenderTemplate('comment', data, { - root: true, - hasVersion: false - }); - // 模块类型 - templateData.moduleType = TemplateFile.getModuleType(type); - // 模板类型 - templateData.type = type; - // alova版本 - templateData.alovaVersion = alovaVersion; - // 是否需要生成api文件 - // 判断是否需要生成api文件 - if (!force && isEqual(templateData, DEFAULT_CONFIG.templateData.get(alovaJsonPath))) { - return false; - } - // 保存templateData - DEFAULT_CONFIG.templateData.set(alovaJsonPath, templateData); - // 生成alova.json文件 - writeAlovaJson(templateData, alovaJsonPath); - // 获取是否存在index.ts|index.js - const indexIsExists = fs.existsSync(path.join(outputDir, `index${templateFile.getExt()}`)); - // mustache语法生成 - // 定义模版配置对象 - [ - !indexIsExists && { - fileName: 'index' - }, - { - fileName: 'createApis' - }, - { - fileName: 'apiDefinitions', - root: true, - hasVersion: false - }, - { - fileName: 'globals.d', - ext: '.ts', - root: true - } - ].forEach(item => { - if (!item) { - return; - } - const { fileName, ext, root, hasVersion } = item; - templateFile.outputFile(templateData, fileName, outputDir, { ext, root, hasVersion }); - }); - return true; -} +import { DEFAULT_CONFIG } from '@/config'; +import { isEqual } from 'lodash'; +import fs from 'node:fs'; +import path from 'node:path'; +import { OpenAPIV3_1 } from 'openapi-types'; +import type { GeneratorConfig, TemplateType } from '~/index'; +import TemplateFile from '../modules/TemplateFile'; +import { getAlovaJsonPath, writeAlovaJson } from './alovaJson'; +import getAlovaVersion, { AlovaVersion } from './getAlovaVersion'; +import getFrameworkTag from './getFrameworkTag'; +import openApi2Data from './openApi2Data'; + +export default async function ( + workspaceRootDir: string, // 项目地址 + outputPath: string, // 输出路径 + data: OpenAPIV3_1.Document, // openapi数据 + config: GeneratorConfig, // generator配置 + type: TemplateType, // 模板类型 + force: boolean // 是否强制生成 +) { + if (!data) { + return; + } + // 输出目录 + const outputDir = path.join(workspaceRootDir, outputPath); + // 缓存文件地址 + const alovaJsonPath = getAlovaJsonPath(workspaceRootDir, outputPath); + // 获取alova版本 + const configVersion = Number(config.version); + const alovaVersion: AlovaVersion = Number.isNaN(configVersion) + ? getAlovaVersion(workspaceRootDir) + : `v${configVersion}`; + const templateFile = new TemplateFile(type, alovaVersion); + // 将openApi对象转成template对象 + const templateData = await openApi2Data(data, config); + // 框架技术栈标签 vue | react + templateData[getFrameworkTag(workspaceRootDir)] = true; + // 头部注释部分 + templateData.commentText = await templateFile.readAndRenderTemplate('comment', data, { + root: true, + hasVersion: false + }); + // 模块类型 + templateData.moduleType = TemplateFile.getModuleType(type); + // 模板类型 + templateData.type = type; + // alova版本 + templateData.alovaVersion = alovaVersion; + // 是否需要生成api文件 + // 判断是否需要生成api文件 + if (!force && isEqual(templateData, DEFAULT_CONFIG.templateData.get(alovaJsonPath))) { + return false; + } + // 保存templateData + DEFAULT_CONFIG.templateData.set(alovaJsonPath, templateData); + // 生成alova.json文件 + writeAlovaJson(templateData, alovaJsonPath); + // 获取是否存在index.ts|index.js + const indexIsExists = fs.existsSync(path.join(outputDir, `index${templateFile.getExt()}`)); + // mustache语法生成 + // 定义模版配置对象 + [ + !indexIsExists && { + fileName: 'index' + }, + { + fileName: 'createApis' + }, + { + fileName: 'apiDefinitions', + root: true, + hasVersion: false + }, + { + fileName: 'globals.d', + ext: '.ts', + root: true + } + ].forEach(item => { + if (!item) { + return; + } + const { fileName, ext, root, hasVersion } = item; + templateFile.outputFile(templateData, fileName, outputDir, { ext, root, hasVersion }); + }); + return true; +} diff --git a/packages/wormhole/src/functions/getAutoTemplateType.ts b/packages/wormhole/src/functions/getAutoTemplateType.ts index 91d625e..be6790c 100644 --- a/packages/wormhole/src/functions/getAutoTemplateType.ts +++ b/packages/wormhole/src/functions/getAutoTemplateType.ts @@ -1,14 +1,14 @@ -import { createRequire } from 'node:module'; -import path from 'node:path'; -import { PackageJson } from 'type-fest'; -import type { TemplateType } from '..'; - -export default (workspaceRootDir: string): TemplateType => { - const workspacedRequire = createRequire(workspaceRootDir); - const packageJson: PackageJson = workspacedRequire('./package.json'); - delete workspacedRequire.cache[path.resolve(workspaceRootDir, './package.json')]; - if (packageJson?.devDependencies?.typescript) { - return 'typescript'; - } - return packageJson.type ?? 'module'; -}; +import { createRequire } from 'node:module'; +import path from 'node:path'; +import { PackageJson } from 'type-fest'; +import type { TemplateType } from '~/index'; + +export default (workspaceRootDir: string): TemplateType => { + const workspacedRequire = createRequire(workspaceRootDir); + const packageJson: PackageJson = workspacedRequire('./package.json'); + delete workspacedRequire.cache[path.resolve(workspaceRootDir, './package.json')]; + if (packageJson?.devDependencies?.typescript) { + return 'typescript'; + } + return packageJson.type ?? 'module'; +}; diff --git a/packages/wormhole/src/functions/getOpenApiData.ts b/packages/wormhole/src/functions/getOpenApiData.ts index 973bf95..dcfa61d 100644 --- a/packages/wormhole/src/functions/getOpenApiData.ts +++ b/packages/wormhole/src/functions/getOpenApiData.ts @@ -1,95 +1,95 @@ -import importFresh from 'import-fresh'; -import YAML from 'js-yaml'; -import fs from 'node:fs'; -import path from 'node:path'; -import { OpenAPIV2, OpenAPIV3_1 } from 'openapi-types'; -import swagger2openapi from 'swagger2openapi'; -import type { PlatformType } from '..'; -import { DEFAULT_CONFIG } from '../config'; -import { fetchData } from '../utils'; -// 判断是否是swagger2.0 -function isSwagger2(data: any): data is OpenAPIV2.Document { - return !!data?.swagger; -} -// 解析本地openapi文件 -function parseLocalFile(workspaceRootDir: string, filePath: string) { - const [, extname] = /\.([^.]+)$/.exec(filePath) ?? []; - switch (extname) { - case 'yaml': { - const file = fs.readFileSync(`${workspaceRootDir}${filePath}`, 'utf-8'); - const data = YAML.load(file) as any; - return data; - } - // json - default: { - const data = importFresh(path.resolve(workspaceRootDir, filePath)); - return data; - } - } -} -// 解析远程openapi文件 -async function parseRemoteFile(url: string, platformType?: PlatformType) { - const [, , extname] = /^http(s)?:\/\/.+\/.+\.([^.]+)$/.exec(url) ?? []; - // 没有扩展名并且有平台类型 - if (!extname && platformType) { - return getPlatformOpenApiData(url, platformType); - } - // 没有平台类型并且没有扩展名 - if (!platformType && !extname) { - return; - } - // 没有平台类型并且有扩展名 - const dataText = (await fetchData(url)) ?? ''; - switch (extname) { - case 'yaml': { - const data = YAML.load(dataText) as any; - return data; - } - // json - default: { - return JSON.parse(dataText); - } - } -} -// 解析平台openapi文件 -export async function getPlatformOpenApiData(url: string, platformType: PlatformType) { - switch (platformType) { - case 'swagger': { - const dataText = - (await fetchData(url) - .then(text => JSON.stringify(JSON.parse(text))) - .catch(() => fetchData(`${url}/openapi.json`)) - .catch(() => fetchData(`${url}/v2/swagger.json`))) ?? ''; - return JSON.parse(dataText); - } - default: - break; - } -} -// 解析openapi文件 -export default async function ( - workspaceRootDir: string, - url: string, - platformType?: PlatformType -): Promise { - let data: OpenAPIV3_1.Document | null = null; - try { - if (!/^http(s)?:\/\//.test(url)) { - // 本地文件 - data = parseLocalFile(workspaceRootDir, url); - } else { - // 远程文件 - data = await parseRemoteFile(url, platformType); - } - // 如果是swagger2的文件 - if (isSwagger2(data)) { - data = (await swagger2openapi.convertObj(data, { warnOnly: true })).openapi as OpenAPIV3_1.Document; - } - } catch (error) { - throw new DEFAULT_CONFIG.Error(`Cannot read file from ${url}`); - } - if (!data) { - throw new DEFAULT_CONFIG.Error(`Cannot read file from ${url}`); - } - return data; -} +import { DEFAULT_CONFIG } from '@/config'; +import { fetchData } from '@/utils'; +import importFresh from 'import-fresh'; +import YAML from 'js-yaml'; +import fs from 'node:fs'; +import path from 'node:path'; +import { OpenAPIV2, OpenAPIV3_1 } from 'openapi-types'; +import swagger2openapi from 'swagger2openapi'; +import type { PlatformType } from '~/index'; +// 判断是否是swagger2.0 +function isSwagger2(data: any): data is OpenAPIV2.Document { + return !!data?.swagger; +} +// 解析本地openapi文件 +function parseLocalFile(workspaceRootDir: string, filePath: string) { + const [, extname] = /\.([^.]+)$/.exec(filePath) ?? []; + switch (extname) { + case 'yaml': { + const file = fs.readFileSync(`${workspaceRootDir}${filePath}`, 'utf-8'); + const data = YAML.load(file) as any; + return data; + } + // json + default: { + const data = importFresh(path.resolve(workspaceRootDir, filePath)); + return data; + } + } +} +// 解析远程openapi文件 +async function parseRemoteFile(url: string, platformType?: PlatformType) { + const [, , extname] = /^http(s)?:\/\/.+\/.+\.([^.]+)$/.exec(url) ?? []; + // 没有扩展名并且有平台类型 + if (!extname && platformType) { + return getPlatformOpenApiData(url, platformType); + } + // 没有平台类型并且没有扩展名 + if (!platformType && !extname) { + return; + } + // 没有平台类型并且有扩展名 + const dataText = (await fetchData(url)) ?? ''; + switch (extname) { + case 'yaml': { + const data = YAML.load(dataText) as any; + return data; + } + // json + default: { + return JSON.parse(dataText); + } + } +} +// 解析平台openapi文件 +export async function getPlatformOpenApiData(url: string, platformType: PlatformType) { + switch (platformType) { + case 'swagger': { + const dataText = + (await fetchData(url) + .then(text => JSON.stringify(JSON.parse(text))) + .catch(() => fetchData(`${url}/openapi.json`)) + .catch(() => fetchData(`${url}/v2/swagger.json`))) ?? ''; + return JSON.parse(dataText); + } + default: + break; + } +} +// 解析openapi文件 +export default async function ( + workspaceRootDir: string, + url: string, + platformType?: PlatformType +): Promise { + let data: OpenAPIV3_1.Document | null = null; + try { + if (!/^http(s)?:\/\//.test(url)) { + // 本地文件 + data = parseLocalFile(workspaceRootDir, url); + } else { + // 远程文件 + data = await parseRemoteFile(url, platformType); + } + // 如果是swagger2的文件 + if (isSwagger2(data)) { + data = (await swagger2openapi.convertObj(data, { warnOnly: true })).openapi as OpenAPIV3_1.Document; + } + } catch (error) { + throw new DEFAULT_CONFIG.Error(`Cannot read file from ${url}`); + } + if (!data) { + throw new DEFAULT_CONFIG.Error(`Cannot read file from ${url}`); + } + return data; +} diff --git a/packages/wormhole/src/functions/openApi2Data.ts b/packages/wormhole/src/functions/openApi2Data.ts index 14c35e2..bb4dfbc 100644 --- a/packages/wormhole/src/functions/openApi2Data.ts +++ b/packages/wormhole/src/functions/openApi2Data.ts @@ -1,456 +1,456 @@ -import { cloneDeep } from 'lodash'; -import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'; -import type { ApiDescriptor, GeneratorConfig, TemplateType } from '..'; -import { DEFAULT_CONFIG } from '../config'; -import { findBy$ref, getStandardRefName, isReferenceObject, mergeObject, removeAll$ref } from '../helper/openapi'; -import { convertToType, jsonSchema2TsStr } from '../helper/schema2type'; -import { getStandardOperationId, getStandardTags } from '../helper/standard'; -import { generateDefaultValues } from '../helper/typeStr'; -import { format, removeUndefined } from '../utils'; -import { AlovaVersion } from './getAlovaVersion'; - -type Path = { - key: string; - method: string; - path: string; -}; -export interface Api { - method: string; - summary: string; - path: string; - pathParameters: string; - queryParameters: string; - pathParametersComment?: string; - queryParametersComment?: string; - responseComment?: string; - requestComment?: string; - name: string; - global: string; - responseName: string; - requestName?: string; - defaultValue?: string; - pathKey: string; -} -interface PathApis { - tag: string; - apis: Api[]; -} -export const getApiDefultValue = (api: Api) => { - const configStrArr: string[] = []; - if (api.pathParametersComment) { - configStrArr.push(`pathParams: ${generateDefaultValues(api.pathParametersComment.replace(/\*/g, ''))}`); - } - if (api.queryParametersComment) { - configStrArr.push(`params: ${generateDefaultValues(api.queryParametersComment.replace(/\*/g, ''))}`); - } - if (api.requestComment) { - configStrArr.push(`data: ${generateDefaultValues(api.requestComment.replace(/\*/g, ''))}`); - } - return format(`${api.global}.${api.pathKey}({${configStrArr.join(',\n')}})`, { - printWidth: 40, // 缩短printWidth以强制换行 - tabWidth: 2, - semi: false, // 去掉末尾分号 - useTabs: false, - trailingComma: 'none', - endOfLine: 'lf', - bracketSpacing: true, - arrowParens: 'always' - }); -}; -export interface TemplateData extends Omit { - // 定义模板数据类型 - // ... - vue?: boolean; - react?: boolean; - moduleType?: 'commonJs' | 'ESModule'; - defaultKey?: boolean; - baseUrl: string; - pathsArr: Path[]; - schemas?: string[]; - pathApis: PathApis[]; - global: string; - alovaVersion: AlovaVersion; - commentText: string; - useImportType: boolean; - type: TemplateType; -} -const remove$ref = ( - originObj: OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject, - openApi: OpenAPIV3_1.Document, - schemasMap?: Map, - preText: string = '', - searchMap: Map = new Map(), - map: Map = new Map() -): Promise => - convertToType(originObj, openApi, { - deep: false, - commentStyle: 'docment', - preText, - searchMap, - on$Ref(refOject) { - const type = getStandardRefName(refOject.$ref); - if (schemasMap && !schemasMap.has(type)) { - jsonSchema2TsStr( - refOject, - type, - openApi, - { - export: true, - on$RefTsStr(name, tsStr) { - schemasMap.set(name, tsStr); - } - }, - searchMap, - map - ).then(schema => { - schemasMap.set(type, schema); - }); - } - } - }); -const parseResponse = async ( - responses: OpenAPIV3_1.ResponsesObject | undefined, - openApi: OpenAPIV3_1.Document, - config: GeneratorConfig, - schemasMap: Map, - searchMap: Map, - removeMap: Map -) => { - const responseInfo = responses?.['200']; - if (!responseInfo) { - return { - responseName: 'unknown', - responseComment: 'unknown' - }; - } - const responseObject: OpenAPIV3_1.ResponseObject = isReferenceObject(responseInfo) - ? findBy$ref(responseInfo.$ref, openApi) - : responseInfo; - const key = getContentKey(responseObject.content ?? {}, config.responseMediaType); - const responseSchema = responseObject?.content?.[key]?.schema ?? {}; - const responseName = await remove$ref(responseSchema, openApi, schemasMap, '', removeMap); - return { - responseName, - responseComment: await convertToType(responseSchema, openApi, { deep: true, preText: '* ', searchMap }) - }; -}; -const parseRequestBody = async ( - requestBody: OpenAPIV3_1.RequestBodyObject | OpenAPIV3_1.ReferenceObject | undefined, - openApi: OpenAPIV3_1.Document, - config: GeneratorConfig, - schemasMap: Map, - searchMap: Map, - removeMap: Map -) => { - if (!requestBody) { - return { - requestName: '', - requestComment: '' - }; - } - const requestBodyObject: OpenAPIV3_1.RequestBodyObject = isReferenceObject(requestBody) - ? findBy$ref(requestBody.$ref, openApi) - : requestBody; - const key = getContentKey(requestBodyObject.content, config.bodyMediaType); - const requestBodySchema = requestBodyObject?.content?.[key]?.schema ?? {}; - const requestName = await remove$ref(requestBodySchema, openApi, schemasMap, '', removeMap); - return { - requestName, - requestComment: await convertToType(requestBodySchema, openApi, { deep: true, preText: '* ', searchMap }) - }; -}; -const getContentKey = (content: Record, requireKey: string, defaultKey = 'application/json') => { - let key = Object.keys(content ?? {})[0]; - if (requireKey && content?.[requireKey]) { - key = requireKey; - } - key = key ?? defaultKey; - return key; -}; -const parseParameters = async ( - parameters: (OpenAPIV3_1.ReferenceObject | OpenAPIV3_1.ParameterObject)[] | undefined, - openApi: OpenAPIV3_1.Document, - config: GeneratorConfig, - schemasMap: Map, - searchMap: Map, - removeMap: Map -) => { - const pathParameters: OpenAPIV3_1.SchemaObject = { - type: 'object' - }; - const queryParameters: OpenAPIV3_1.SchemaObject = { - type: 'object' - }; - for (const refParameter of parameters || []) { - const parameter = isReferenceObject(refParameter) - ? findBy$ref(refParameter.$ref, openApi) - : refParameter; - if (parameter.in === 'path') { - if (!pathParameters.properties) { - pathParameters.properties = {}; - } - if (!pathParameters.required) { - pathParameters.required = []; - } - if (parameter.required) { - pathParameters.required.push(parameter.name); - } - pathParameters.properties[parameter.name] = { - ...parameter.schema, - description: parameter.description || '', - deprecated: !!parameter.deprecated - }; - } - if (parameter.in === 'query') { - if (!queryParameters.properties) { - queryParameters.properties = {}; - } - if (!queryParameters.required) { - queryParameters.required = []; - } - if (parameter.required) { - queryParameters.required.push(parameter.name); - } - queryParameters.properties[parameter.name] = { - ...parameter.schema, - description: parameter.description || '', - deprecated: !!parameter.deprecated - }; - } - } - let pathParametersStr = ''; - let queryParametersStr = ''; - let pathParametersComment = ''; - let queryParametersComment = ''; - if (Object.keys(pathParameters.properties ?? {}).length) { - pathParametersStr = await remove$ref(pathParameters, openApi, schemasMap, '', removeMap); - pathParametersComment = await convertToType(pathParameters, openApi, { - deep: true, - preText: '* ', - searchMap - }); - } - if (Object.keys(queryParameters.properties ?? {}).length) { - queryParametersStr = await remove$ref(queryParameters, openApi, schemasMap, '', removeMap); - queryParametersComment = await convertToType(queryParameters, openApi, { - deep: true, - preText: '* ', - searchMap - }); - } - return { - pathParameters: pathParametersStr, - queryParameters: queryParametersStr, - pathParametersComment, - queryParametersComment - }; -}; -export const transformPathObj = async ( - url: string, - method: string, - pathObjOrigin: OpenAPIV3_1.OperationObject, - openApi: OpenAPIV3_1.Document, - config: GeneratorConfig -) => { - const { handleApi } = config; - const pathObj = cloneDeep(pathObjOrigin); - if (!handleApi || typeof handleApi !== 'function') { - return { ...pathObjOrigin, url, method }; - } - const { requestBody, responses, parameters } = pathObj; - let apiDescriptor: ApiDescriptor = { - ...pathObj, - requestBody: {}, - responses: {}, - parameters: [], - url, - method - }; - const response200 = responses?.['200']; - let requestBodyObject = requestBody as OpenAPIV3_1.RequestBodyObject; - let responseObject = response200 as OpenAPIV3_1.ResponseObject; - let requestKey = 'application/json'; - let responseKey = 'application/json'; - if (parameters) { - apiDescriptor.parameters = []; - const parametersArray = isReferenceObject(parameters) - ? findBy$ref(parameters.$ref, openApi, true) - : parameters ?? []; - for (const parameter of parametersArray) { - const parameterObject = removeAll$ref(parameter, openApi); - apiDescriptor.parameters.push(parameterObject); - } - } - if (requestBody) { - requestBodyObject = isReferenceObject(requestBody) ? findBy$ref(requestBody.$ref, openApi, true) : requestBody; - requestKey = getContentKey(requestBodyObject.content || {}, config.bodyMediaType); - const requestBodySchema = requestBodyObject.content?.[requestKey].schema ?? {}; - const requestBodySchemaObj = removeAll$ref(requestBodySchema, openApi); - apiDescriptor.requestBody = requestBodySchemaObj; - } - if (response200) { - responseObject = isReferenceObject(response200) ? findBy$ref(response200.$ref, openApi, true) : response200; - responseKey = getContentKey(responseObject.content || {}, config.responseMediaType); - const responseSchema = responseObject.content?.[responseKey].schema ?? {}; - const responseSchemaObj = removeAll$ref(responseSchema, openApi); - apiDescriptor.responses = responseSchemaObj; - } - let newApiDescriptor = apiDescriptor; - let handleApiDone = false; - try { - newApiDescriptor = handleApi(apiDescriptor, DEFAULT_CONFIG.log); - handleApiDone = true; - } catch (error) { - handleApiDone = false; - } - if (!handleApiDone) { - return { ...pathObj, url, method }; - } - if (!newApiDescriptor) { - return null; - } - apiDescriptor = cloneDeep(newApiDescriptor); - if (apiDescriptor.requestBody) { - pathObj.requestBody = requestBodyObject || { content: {} }; - const { content } = pathObj.requestBody; - if (!content[requestKey]) { - content[requestKey] = {}; - } - content[requestKey].schema = apiDescriptor.requestBody; - } - if (apiDescriptor.responses) { - if (!pathObj.responses) { - pathObj.responses = {}; - } - pathObj.responses['200'] = responseObject || { content: {} }; - if (!pathObj.responses['200'].content) { - pathObj.responses['200'].content = {}; - } - const { content } = pathObj.responses['200']; - if (!content[responseKey]) { - content[responseKey] = {}; - } - content[responseKey].schema = apiDescriptor.responses; - } - if (apiDescriptor.parameters) { - pathObj.parameters = apiDescriptor.parameters; - } - delete apiDescriptor.requestBody; - delete apiDescriptor.responses; - delete apiDescriptor.parameters; - Object.assign(pathObj, apiDescriptor); - const result = { - ...mergeObject(pathObjOrigin, pathObj, openApi), - url: apiDescriptor.url, - method: apiDescriptor.method - }; - return result; -}; -export default async function openApi2Data( - openApi: OpenAPIV3_1.Document, - config: GeneratorConfig -): Promise { - // 处理openApi中的数据 - // ... - const templateData: TemplateData = { - ...openApi, - baseUrl: '', - pathsArr: [], - pathApis: [], - commentText: '', - schemas: [], - alovaVersion: 'v2', - global: config.global ?? 'Apis', - useImportType: config?.useImportType ?? false, - type: 'module' - }; - const schemasMap = new Map(); - const searchMap = new Map(); - const removeMap = new Map(); - const operationIdSet = new Set(); - const paths = openApi.paths || []; - for (const [url, pathInfo] of Object.entries(paths)) { - if (!pathInfo) { - continue; - } - for (const [method, methodInfoOrigin] of Object.entries(pathInfo)) { - if (!['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace'].includes(method)) { - continue; - } - if (typeof methodInfoOrigin === 'string' || Array.isArray(methodInfoOrigin)) { - continue; - } - methodInfoOrigin.operationId = getStandardOperationId(methodInfoOrigin, url, method, operationIdSet); - methodInfoOrigin.tags = getStandardTags(methodInfoOrigin.tags); - const newMethodInfo = await transformPathObj(url, method, methodInfoOrigin, openApi, config); - if (!newMethodInfo) { - continue; - } - const { url: path, method: newMethod, ...methodInfo } = newMethodInfo; - const methodFormat = newMethod.toUpperCase(); - const allPromise = methodInfo.tags?.map(async tag => { - try { - const pathKey = `${tag}.${methodInfo.operationId}`; - const { queryParameters, queryParametersComment, pathParameters, pathParametersComment } = - await parseParameters(methodInfo.parameters, openApi, config, schemasMap, searchMap, removeMap); - const { responseName, responseComment } = await parseResponse( - methodInfo.responses, - openApi, - config, - schemasMap, - searchMap, - removeMap - ); - const { requestName, requestComment } = await parseRequestBody( - methodInfo.requestBody, - openApi, - config, - schemasMap, - searchMap, - removeMap - ); - const api: Api = { - method: methodFormat, - summary: methodInfo.summary?.replace(/\n/g, '') ?? '', - path, - name: methodInfo.operationId ?? '', - responseName, - requestName, - pathKey, - queryParameters, - queryParametersComment, - pathParameters, - pathParametersComment, - responseComment, - requestComment, - global: templateData.global - }; - templateData.pathsArr.push({ - key: pathKey, - method: methodFormat, - path - }); - let tagApis = templateData.pathApis.find(item => item.tag === tag); - if (!tagApis) { - templateData.pathApis.push( - (tagApis = { - tag, - apis: [] - }) - ); - } - api.defaultValue = await getApiDefultValue(api); - tagApis.apis.push(api); - } catch (error) { - console.log(error); - } - }); - if (allPromise) { - await Promise.all(allPromise); - } - } - } - templateData.baseUrl = openApi.servers?.[0]?.url || ''; - templateData.schemas = [...new Set(schemasMap.values())]; - return removeUndefined(templateData); -} +import { DEFAULT_CONFIG } from '@/config'; +import { findBy$ref, getStandardRefName, isReferenceObject, mergeObject, removeAll$ref } from '@/helper/openapi'; +import { convertToType, jsonSchema2TsStr } from '@/helper/schema2type'; +import { getStandardOperationId, getStandardTags } from '@/helper/standard'; +import { generateDefaultValues } from '@/helper/typeStr'; +import { format, removeUndefined } from '@/utils'; +import { cloneDeep } from 'lodash'; +import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'; +import type { ApiDescriptor, GeneratorConfig, TemplateType } from '~/index'; +import { AlovaVersion } from './getAlovaVersion'; + +type Path = { + key: string; + method: string; + path: string; +}; +export interface Api { + method: string; + summary: string; + path: string; + pathParameters: string; + queryParameters: string; + pathParametersComment?: string; + queryParametersComment?: string; + responseComment?: string; + requestComment?: string; + name: string; + global: string; + responseName: string; + requestName?: string; + defaultValue?: string; + pathKey: string; +} +interface PathApis { + tag: string; + apis: Api[]; +} +export const getApiDefultValue = (api: Api) => { + const configStrArr: string[] = []; + if (api.pathParametersComment) { + configStrArr.push(`pathParams: ${generateDefaultValues(api.pathParametersComment.replace(/\*/g, ''))}`); + } + if (api.queryParametersComment) { + configStrArr.push(`params: ${generateDefaultValues(api.queryParametersComment.replace(/\*/g, ''))}`); + } + if (api.requestComment) { + configStrArr.push(`data: ${generateDefaultValues(api.requestComment.replace(/\*/g, ''))}`); + } + return format(`${api.global}.${api.pathKey}({${configStrArr.join(',\n')}})`, { + printWidth: 40, // 缩短printWidth以强制换行 + tabWidth: 2, + semi: false, // 去掉末尾分号 + useTabs: false, + trailingComma: 'none', + endOfLine: 'lf', + bracketSpacing: true, + arrowParens: 'always' + }); +}; +export interface TemplateData extends Omit { + // 定义模板数据类型 + // ... + vue?: boolean; + react?: boolean; + moduleType?: 'commonJs' | 'ESModule'; + defaultKey?: boolean; + baseUrl: string; + pathsArr: Path[]; + schemas?: string[]; + pathApis: PathApis[]; + global: string; + alovaVersion: AlovaVersion; + commentText: string; + useImportType: boolean; + type: TemplateType; +} +const remove$ref = ( + originObj: OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject, + openApi: OpenAPIV3_1.Document, + schemasMap?: Map, + preText: string = '', + searchMap: Map = new Map(), + map: Map = new Map() +): Promise => + convertToType(originObj, openApi, { + deep: false, + commentStyle: 'docment', + preText, + searchMap, + on$Ref(refOject) { + const type = getStandardRefName(refOject.$ref); + if (schemasMap && !schemasMap.has(type)) { + jsonSchema2TsStr( + refOject, + type, + openApi, + { + export: true, + on$RefTsStr(name, tsStr) { + schemasMap.set(name, tsStr); + } + }, + searchMap, + map + ).then(schema => { + schemasMap.set(type, schema); + }); + } + } + }); +const parseResponse = async ( + responses: OpenAPIV3_1.ResponsesObject | undefined, + openApi: OpenAPIV3_1.Document, + config: GeneratorConfig, + schemasMap: Map, + searchMap: Map, + removeMap: Map +) => { + const responseInfo = responses?.['200']; + if (!responseInfo) { + return { + responseName: 'unknown', + responseComment: 'unknown' + }; + } + const responseObject: OpenAPIV3_1.ResponseObject = isReferenceObject(responseInfo) + ? findBy$ref(responseInfo.$ref, openApi) + : responseInfo; + const key = getContentKey(responseObject.content ?? {}, config.responseMediaType); + const responseSchema = responseObject?.content?.[key]?.schema ?? {}; + const responseName = await remove$ref(responseSchema, openApi, schemasMap, '', removeMap); + return { + responseName, + responseComment: await convertToType(responseSchema, openApi, { deep: true, preText: '* ', searchMap }) + }; +}; +const parseRequestBody = async ( + requestBody: OpenAPIV3_1.RequestBodyObject | OpenAPIV3_1.ReferenceObject | undefined, + openApi: OpenAPIV3_1.Document, + config: GeneratorConfig, + schemasMap: Map, + searchMap: Map, + removeMap: Map +) => { + if (!requestBody) { + return { + requestName: '', + requestComment: '' + }; + } + const requestBodyObject: OpenAPIV3_1.RequestBodyObject = isReferenceObject(requestBody) + ? findBy$ref(requestBody.$ref, openApi) + : requestBody; + const key = getContentKey(requestBodyObject.content, config.bodyMediaType); + const requestBodySchema = requestBodyObject?.content?.[key]?.schema ?? {}; + const requestName = await remove$ref(requestBodySchema, openApi, schemasMap, '', removeMap); + return { + requestName, + requestComment: await convertToType(requestBodySchema, openApi, { deep: true, preText: '* ', searchMap }) + }; +}; +const getContentKey = (content: Record, requireKey: string, defaultKey = 'application/json') => { + let key = Object.keys(content ?? {})[0]; + if (requireKey && content?.[requireKey]) { + key = requireKey; + } + key = key ?? defaultKey; + return key; +}; +const parseParameters = async ( + parameters: (OpenAPIV3_1.ReferenceObject | OpenAPIV3_1.ParameterObject)[] | undefined, + openApi: OpenAPIV3_1.Document, + config: GeneratorConfig, + schemasMap: Map, + searchMap: Map, + removeMap: Map +) => { + const pathParameters: OpenAPIV3_1.SchemaObject = { + type: 'object' + }; + const queryParameters: OpenAPIV3_1.SchemaObject = { + type: 'object' + }; + for (const refParameter of parameters || []) { + const parameter = isReferenceObject(refParameter) + ? findBy$ref(refParameter.$ref, openApi) + : refParameter; + if (parameter.in === 'path') { + if (!pathParameters.properties) { + pathParameters.properties = {}; + } + if (!pathParameters.required) { + pathParameters.required = []; + } + if (parameter.required) { + pathParameters.required.push(parameter.name); + } + pathParameters.properties[parameter.name] = { + ...parameter.schema, + description: parameter.description || '', + deprecated: !!parameter.deprecated + }; + } + if (parameter.in === 'query') { + if (!queryParameters.properties) { + queryParameters.properties = {}; + } + if (!queryParameters.required) { + queryParameters.required = []; + } + if (parameter.required) { + queryParameters.required.push(parameter.name); + } + queryParameters.properties[parameter.name] = { + ...parameter.schema, + description: parameter.description || '', + deprecated: !!parameter.deprecated + }; + } + } + let pathParametersStr = ''; + let queryParametersStr = ''; + let pathParametersComment = ''; + let queryParametersComment = ''; + if (Object.keys(pathParameters.properties ?? {}).length) { + pathParametersStr = await remove$ref(pathParameters, openApi, schemasMap, '', removeMap); + pathParametersComment = await convertToType(pathParameters, openApi, { + deep: true, + preText: '* ', + searchMap + }); + } + if (Object.keys(queryParameters.properties ?? {}).length) { + queryParametersStr = await remove$ref(queryParameters, openApi, schemasMap, '', removeMap); + queryParametersComment = await convertToType(queryParameters, openApi, { + deep: true, + preText: '* ', + searchMap + }); + } + return { + pathParameters: pathParametersStr, + queryParameters: queryParametersStr, + pathParametersComment, + queryParametersComment + }; +}; +export const transformPathObj = async ( + url: string, + method: string, + pathObjOrigin: OpenAPIV3_1.OperationObject, + openApi: OpenAPIV3_1.Document, + config: GeneratorConfig +) => { + const { handleApi } = config; + const pathObj = cloneDeep(pathObjOrigin); + if (!handleApi || typeof handleApi !== 'function') { + return { ...pathObjOrigin, url, method }; + } + const { requestBody, responses, parameters } = pathObj; + let apiDescriptor: ApiDescriptor = { + ...pathObj, + requestBody: {}, + responses: {}, + parameters: [], + url, + method + }; + const response200 = responses?.['200']; + let requestBodyObject = requestBody as OpenAPIV3_1.RequestBodyObject; + let responseObject = response200 as OpenAPIV3_1.ResponseObject; + let requestKey = 'application/json'; + let responseKey = 'application/json'; + if (parameters) { + apiDescriptor.parameters = []; + const parametersArray = isReferenceObject(parameters) + ? findBy$ref(parameters.$ref, openApi, true) + : parameters ?? []; + for (const parameter of parametersArray) { + const parameterObject = removeAll$ref(parameter, openApi); + apiDescriptor.parameters.push(parameterObject); + } + } + if (requestBody) { + requestBodyObject = isReferenceObject(requestBody) ? findBy$ref(requestBody.$ref, openApi, true) : requestBody; + requestKey = getContentKey(requestBodyObject.content || {}, config.bodyMediaType); + const requestBodySchema = requestBodyObject.content?.[requestKey].schema ?? {}; + const requestBodySchemaObj = removeAll$ref(requestBodySchema, openApi); + apiDescriptor.requestBody = requestBodySchemaObj; + } + if (response200) { + responseObject = isReferenceObject(response200) ? findBy$ref(response200.$ref, openApi, true) : response200; + responseKey = getContentKey(responseObject.content || {}, config.responseMediaType); + const responseSchema = responseObject.content?.[responseKey].schema ?? {}; + const responseSchemaObj = removeAll$ref(responseSchema, openApi); + apiDescriptor.responses = responseSchemaObj; + } + let newApiDescriptor = apiDescriptor; + let handleApiDone = false; + try { + newApiDescriptor = handleApi(apiDescriptor, DEFAULT_CONFIG.log); + handleApiDone = true; + } catch (error) { + handleApiDone = false; + } + if (!handleApiDone) { + return { ...pathObj, url, method }; + } + if (!newApiDescriptor) { + return null; + } + apiDescriptor = cloneDeep(newApiDescriptor); + if (apiDescriptor.requestBody) { + pathObj.requestBody = requestBodyObject || { content: {} }; + const { content } = pathObj.requestBody; + if (!content[requestKey]) { + content[requestKey] = {}; + } + content[requestKey].schema = apiDescriptor.requestBody; + } + if (apiDescriptor.responses) { + if (!pathObj.responses) { + pathObj.responses = {}; + } + pathObj.responses['200'] = responseObject || { content: {} }; + if (!pathObj.responses['200'].content) { + pathObj.responses['200'].content = {}; + } + const { content } = pathObj.responses['200']; + if (!content[responseKey]) { + content[responseKey] = {}; + } + content[responseKey].schema = apiDescriptor.responses; + } + if (apiDescriptor.parameters) { + pathObj.parameters = apiDescriptor.parameters; + } + delete apiDescriptor.requestBody; + delete apiDescriptor.responses; + delete apiDescriptor.parameters; + Object.assign(pathObj, apiDescriptor); + const result = { + ...mergeObject(pathObjOrigin, pathObj, openApi), + url: apiDescriptor.url, + method: apiDescriptor.method + }; + return result; +}; +export default async function openApi2Data( + openApi: OpenAPIV3_1.Document, + config: GeneratorConfig +): Promise { + // 处理openApi中的数据 + // ... + const templateData: TemplateData = { + ...openApi, + baseUrl: '', + pathsArr: [], + pathApis: [], + commentText: '', + schemas: [], + alovaVersion: 'v2', + global: config.global ?? 'Apis', + useImportType: config?.useImportType ?? false, + type: 'module' + }; + const schemasMap = new Map(); + const searchMap = new Map(); + const removeMap = new Map(); + const operationIdSet = new Set(); + const paths = openApi.paths || []; + for (const [url, pathInfo] of Object.entries(paths)) { + if (!pathInfo) { + continue; + } + for (const [method, methodInfoOrigin] of Object.entries(pathInfo)) { + if (!['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace'].includes(method)) { + continue; + } + if (typeof methodInfoOrigin === 'string' || Array.isArray(methodInfoOrigin)) { + continue; + } + methodInfoOrigin.operationId = getStandardOperationId(methodInfoOrigin, url, method, operationIdSet); + methodInfoOrigin.tags = getStandardTags(methodInfoOrigin.tags); + const newMethodInfo = await transformPathObj(url, method, methodInfoOrigin, openApi, config); + if (!newMethodInfo) { + continue; + } + const { url: path, method: newMethod, ...methodInfo } = newMethodInfo; + const methodFormat = newMethod.toUpperCase(); + const allPromise = methodInfo.tags?.map(async tag => { + try { + const pathKey = `${tag}.${methodInfo.operationId}`; + const { queryParameters, queryParametersComment, pathParameters, pathParametersComment } = + await parseParameters(methodInfo.parameters, openApi, config, schemasMap, searchMap, removeMap); + const { responseName, responseComment } = await parseResponse( + methodInfo.responses, + openApi, + config, + schemasMap, + searchMap, + removeMap + ); + const { requestName, requestComment } = await parseRequestBody( + methodInfo.requestBody, + openApi, + config, + schemasMap, + searchMap, + removeMap + ); + const api: Api = { + method: methodFormat, + summary: methodInfo.summary?.replace(/\n/g, '') ?? '', + path, + name: methodInfo.operationId ?? '', + responseName, + requestName, + pathKey, + queryParameters, + queryParametersComment, + pathParameters, + pathParametersComment, + responseComment, + requestComment, + global: templateData.global + }; + templateData.pathsArr.push({ + key: pathKey, + method: methodFormat, + path + }); + let tagApis = templateData.pathApis.find(item => item.tag === tag); + if (!tagApis) { + templateData.pathApis.push( + (tagApis = { + tag, + apis: [] + }) + ); + } + api.defaultValue = await getApiDefultValue(api); + tagApis.apis.push(api); + } catch (error) { + console.log(error); + } + }); + if (allPromise) { + await Promise.all(allPromise); + } + } + } + templateData.baseUrl = openApi.servers?.[0]?.url || ''; + templateData.schemas = [...new Set(schemasMap.values())]; + return removeUndefined(templateData); +} diff --git a/packages/wormhole/src/generate.ts b/packages/wormhole/src/generate.ts index baca56a..3a98b4b 100644 --- a/packages/wormhole/src/generate.ts +++ b/packages/wormhole/src/generate.ts @@ -1,31 +1,31 @@ -import generateApi from './functions/generateApi'; -import Configuration from './modules/Configuration'; -import type { Config, GenerateApiOptions } from './type'; - -export const generate = async (config: Config, options?: GenerateApiOptions) => { - if (!config) { - return; - } - const configuration = new Configuration(config, options?.projectPath ?? process.cwd()); - // 检查新配置 - configuration.checkConfig(); - const outputPathArr = configuration.getAllOutputPath(); - const templateTypeArr = configuration.getAllTemplateType(); - const openApiData = await configuration.getAllOpenApiData(); - const generatorConfigArr = configuration.config.generator; - const result = await Promise.all( - outputPathArr.map((outputPath, idx) => - // 生成api文件 - generateApi( - configuration.workspaceRootDir, - outputPath, - openApiData[idx], - generatorConfigArr[idx], - templateTypeArr[idx] ?? 'commonjs', - options?.force ?? false - ) - ) - ); - return result; -}; -export default generate; +import type { Config, GenerateApiOptions } from '~/index'; +import generateApi from './functions/generateApi'; +import Configuration from './modules/Configuration'; + +export const generate = async (config: Config, options?: GenerateApiOptions) => { + if (!config) { + return; + } + const configuration = new Configuration(config, options?.projectPath ?? process.cwd()); + // 检查新配置 + configuration.checkConfig(); + const outputPathArr = configuration.getAllOutputPath(); + const templateTypeArr = configuration.getAllTemplateType(); + const openApiData = await configuration.getAllOpenApiData(); + const generatorConfigArr = configuration.config.generator; + const result = await Promise.all( + outputPathArr.map((outputPath, idx) => + // 生成api文件 + generateApi( + configuration.workspaceRootDir, + outputPath, + openApiData[idx], + generatorConfigArr[idx], + templateTypeArr[idx] ?? 'commonjs', + options?.force ?? false + ) + ) + ); + return result; +}; +export default generate; diff --git a/packages/wormhole/src/helper/lodaders.ts b/packages/wormhole/src/helper/lodaders.ts index 48ddf97..c2eadec 100644 --- a/packages/wormhole/src/helper/lodaders.ts +++ b/packages/wormhole/src/helper/lodaders.ts @@ -1,105 +1,105 @@ -import { Loader, LoaderSync } from 'cosmiconfig'; -import importFresh from 'import-fresh'; -import { existsSync, mkdirSync } from 'node:fs'; -import { rm, writeFile } from 'node:fs/promises'; -import path from 'node:path'; -import { pathToFileURL } from 'node:url'; -import { DEFAULT_CONFIG } from '../config'; -import { loadEsmModule } from '../utils'; - -let typescript: typeof import('typescript'); -export const loadTs: Loader = async function loadTs(filepath, content) { - const ts = await DEFAULT_CONFIG.getTypescript(); - if (typescript === undefined && ts) { - typescript = ts; - } - if (!typescript) { - throw new DEFAULT_CONFIG.Error('typescript dependencie is required'); - } - let transpiledContent; - try { - const config = resolveTsConfig(path.dirname(filepath)) ?? {}; - config.compilerOptions = { - ...config.compilerOptions, - module: typescript.ModuleKind.ES2022, - moduleResolution: typescript.ModuleResolutionKind.Bundler, - target: typescript.ScriptTarget.ES2022, - noEmit: false - }; - transpiledContent = typescript.transpileModule(content, config).outputText; - } catch (error: any) { - error.message = `TypeScript Error in ${filepath}:\n${error.message}`; - throw error; - } - return createTempFile(filepath, transpiledContent, 'js', jsPath => loadJs(jsPath, transpiledContent)); -}; - -export const loadJsSync: LoaderSync = importFresh; - -export const loadEsModule = async (filepath: string) => { - const { href } = pathToFileURL(filepath); - return (await loadEsmModule(`${href}?t=${Date.now()}`)).default; -}; -export const createTempFile = async ( - filepath: string, - content: string, - ext: 'cjs' | 'mjs' | 'js', - callback?: (compiledFilepath: string) => T | Promise -) => { - const parsedPath = path.parse(filepath); - const addPath = DEFAULT_CONFIG.alovaTempPath; - const dirPath = path.join(parsedPath.dir, parsedPath.dir.includes(addPath) ? '' : addPath); - const compiledFilepath = path.join(dirPath, `${Date.now()}-${Math.random().toString(16).slice(2)}.${ext}`); - if (!existsSync(dirPath)) { - mkdirSync(dirPath, { recursive: true }); - } - let result = null; - try { - await writeFile(compiledFilepath, content); - result = await callback?.(compiledFilepath); - } finally { - if (existsSync(compiledFilepath)) { - await rm(compiledFilepath); - } - } - return result as T; -}; -export const loadJs: Loader = async function loadJs(filepath, content) { - try { - return await createTempFile(filepath, content, 'js', jspath => loadJsSync(jspath, '')); - } catch (requireError: any) { - try { - return await loadEsModule(filepath); - } catch (error: any) { - const errorStr = requireError.toString() + error.toString(); - if (errorStr.includes("SyntaxError: Unexpected token 'export'")) { - return createTempFile(filepath, content, 'mjs', mjsPath => loadEsModule(mjsPath)); - } - if ( - errorStr.includes( - 'contains "type": "module". To treat it as a CommonJS script, rename it to use the \'.cjs\' file extension' - ) - ) { - return createTempFile(filepath, content, 'cjs', cjsPath => loadJsSync(cjsPath, '')); - } - if ( - requireError.code === 'ERR_REQUIRE_ESM' || - (requireError instanceof SyntaxError && - requireError.toString().includes('Cannot use import statement outside a module')) - ) { - throw new DEFAULT_CONFIG.Error(error.toString()); - } - throw new DEFAULT_CONFIG.Error(requireError.toString()); - } - } -}; -function resolveTsConfig(directory: string): any { - const filePath = typescript.findConfigFile(directory, fileName => typescript.sys.fileExists(fileName)); - if (filePath !== undefined) { - const { config, error } = typescript.readConfigFile(filePath, path => typescript.sys.readFile(path)); - if (error) { - throw new DEFAULT_CONFIG.Error(`Error in ${filePath}: ${error.messageText.toString()}`); - } - return config; - } -} +import { DEFAULT_CONFIG } from '@/config'; +import { loadEsmModule } from '@/utils'; +import { Loader, LoaderSync } from 'cosmiconfig'; +import importFresh from 'import-fresh'; +import { existsSync, mkdirSync } from 'node:fs'; +import { rm, writeFile } from 'node:fs/promises'; +import path from 'node:path'; +import { pathToFileURL } from 'node:url'; + +let typescript: typeof import('typescript'); +export const loadTs: Loader = async function loadTs(filepath, content) { + const ts = await DEFAULT_CONFIG.getTypescript(); + if (typescript === undefined && ts) { + typescript = ts; + } + if (!typescript) { + throw new DEFAULT_CONFIG.Error('typescript dependencie is required'); + } + let transpiledContent; + try { + const config = resolveTsConfig(path.dirname(filepath)) ?? {}; + config.compilerOptions = { + ...config.compilerOptions, + module: typescript.ModuleKind.ES2022, + moduleResolution: typescript.ModuleResolutionKind.Bundler, + target: typescript.ScriptTarget.ES2022, + noEmit: false + }; + transpiledContent = typescript.transpileModule(content, config).outputText; + } catch (error: any) { + error.message = `TypeScript Error in ${filepath}:\n${error.message}`; + throw error; + } + return createTempFile(filepath, transpiledContent, 'js', jsPath => loadJs(jsPath, transpiledContent)); +}; + +export const loadJsSync: LoaderSync = importFresh; + +export const loadEsModule = async (filepath: string) => { + const { href } = pathToFileURL(filepath); + return (await loadEsmModule(`${href}?t=${Date.now()}`)).default; +}; +export const createTempFile = async ( + filepath: string, + content: string, + ext: 'cjs' | 'mjs' | 'js', + callback?: (compiledFilepath: string) => T | Promise +) => { + const parsedPath = path.parse(filepath); + const addPath = DEFAULT_CONFIG.alovaTempPath; + const dirPath = path.join(parsedPath.dir, parsedPath.dir.includes(addPath) ? '' : addPath); + const compiledFilepath = path.join(dirPath, `${Date.now()}-${Math.random().toString(16).slice(2)}.${ext}`); + if (!existsSync(dirPath)) { + mkdirSync(dirPath, { recursive: true }); + } + let result = null; + try { + await writeFile(compiledFilepath, content); + result = await callback?.(compiledFilepath); + } finally { + if (existsSync(compiledFilepath)) { + await rm(compiledFilepath); + } + } + return result as T; +}; +export const loadJs: Loader = async function loadJs(filepath, content) { + try { + return await createTempFile(filepath, content, 'js', jspath => loadJsSync(jspath, '')); + } catch (requireError: any) { + try { + return await loadEsModule(filepath); + } catch (error: any) { + const errorStr = requireError.toString() + error.toString(); + if (errorStr.includes("SyntaxError: Unexpected token 'export'")) { + return createTempFile(filepath, content, 'mjs', mjsPath => loadEsModule(mjsPath)); + } + if ( + errorStr.includes( + 'contains "type": "module". To treat it as a CommonJS script, rename it to use the \'.cjs\' file extension' + ) + ) { + return createTempFile(filepath, content, 'cjs', cjsPath => loadJsSync(cjsPath, '')); + } + if ( + requireError.code === 'ERR_REQUIRE_ESM' || + (requireError instanceof SyntaxError && + requireError.toString().includes('Cannot use import statement outside a module')) + ) { + throw new DEFAULT_CONFIG.Error(error.toString()); + } + throw new DEFAULT_CONFIG.Error(requireError.toString()); + } + } +}; +function resolveTsConfig(directory: string): any { + const filePath = typescript.findConfigFile(directory, fileName => typescript.sys.fileExists(fileName)); + if (filePath !== undefined) { + const { config, error } = typescript.readConfigFile(filePath, path => typescript.sys.readFile(path)); + if (error) { + throw new DEFAULT_CONFIG.Error(`Error in ${filePath}: ${error.messageText.toString()}`); + } + return config; + } +} diff --git a/packages/wormhole/src/helper/openapi.ts b/packages/wormhole/src/helper/openapi.ts index a253079..f30d5ff 100644 --- a/packages/wormhole/src/helper/openapi.ts +++ b/packages/wormhole/src/helper/openapi.ts @@ -1,291 +1,291 @@ -import { cloneDeep, isArray, isEqualWith, isObject, mergeWith, sortBy } from 'lodash'; -import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'; -import { capitalizeFirstLetter } from '../utils'; -import { isValidJSIdentifier, makeIdentifier } from './standard'; -/** - * 判断是否是$ref对象 - * @param obj 判断对象 - * @returns 是否是$ref对象 - */ -export function isReferenceObject(obj: any): obj is OpenAPIV3.ReferenceObject { - return !!(obj as OpenAPIV3.ReferenceObject)?.$ref; -} -function isBaseReferenceObject(obj: any): obj is { _$ref: string } & Record { - return !!(obj as { _$ref: string })?._$ref; -} - -/** - * - * @param path $ref查找路径 - * @param openApi openApi文档对象 - * @param isDeep 是否深拷贝 - * @returns 查找到的SchemaObject - */ -export const findBy$ref = ( - path: string, - openApi: OpenAPIV3_1.Document, - isDeep: boolean = false -) => { - const pathArr = path.split('/'); - let find: any = { - '#': openApi - }; - pathArr.forEach(key => { - if (find) { - find = find[key]; - } - }); - return (isDeep ? cloneDeep(find) : find) as T; -}; -/** - * - * @param path $ref路径 - * @param data 复用对象 - * @param openApi 插入的openapi文档对象 - */ -export const setComponentsBy$ref = (path: string, data: any, openApi: OpenAPIV3_1.Document) => { - const pathArr = path.split('/'); - let find: any = { - '#': openApi - }; - pathArr.forEach((key, idx) => { - if (idx + 1 === pathArr.length) { - find[key] = data; - return; - } - if (find[key]) { - find = find[key]; - } else { - find = find[key] = {}; - } - }); -}; -/** - * - * @param path $ref路径 - * @param toUpperCase 是否首字母大小 - * @returns 引用对象名称 - */ -export const get$refName = (path: string, toUpperCase: boolean = true) => { - const pathArr = path.split('/'); - const name = pathArr[pathArr.length - 1]; - if (!toUpperCase) { - return name; - } - return capitalizeFirstLetter(name); -}; -/** - * - * @param schemaOrigin 含$ref的对象 - * @param openApi openApi文档对象 - * @returns 去除了$ref的对象 - */ -export const removeAll$ref = ( - schemaOrigin: any, - openApi: OpenAPIV3_1.Document, - searchMap: Map = new Map() -) => { - const deepSchemaOrigin = cloneDeep(schemaOrigin); - let schema: OpenAPIV3_1.SchemaObject & Record; - if (isReferenceObject(deepSchemaOrigin)) { - if (searchMap.has(deepSchemaOrigin.$ref)) { - return searchMap.get(deepSchemaOrigin.$ref) as T; - } - schema = findBy$ref(deepSchemaOrigin.$ref, openApi, true); - // 做标记方便还原 - schema._$ref = deepSchemaOrigin.$ref; - searchMap.set(deepSchemaOrigin.$ref, schema); - } else { - schema = deepSchemaOrigin; - } - for (const key of Object.keys(schema)) { - if (schema[key] && typeof schema[key] === 'object') { - schema[key] = removeAll$ref(schema[key], openApi, searchMap); - } - } - return schema as T; -}; -/** - * - * @param objValue 待比较的对象 - * @param srcValue 源对象 - * @param openApi openApi文档对象 - * @returns 是否相等 - */ -export function isEqualObject(objValue: any, srcValue: any, openApi: OpenAPIV3_1.Document) { - const visited = new WeakMap(); - const ignoreKeyArr = ['_$ref']; - function customizer(objValueOrigin: any, otherValueOrigin: any) { - if (objValueOrigin === otherValueOrigin) { - return true; - } - let objValue = objValueOrigin; - let otherValue = otherValueOrigin; - if (isReferenceObject(objValueOrigin)) { - objValue = findBy$ref(objValueOrigin.$ref, openApi); - } - if (isReferenceObject(otherValueOrigin)) { - otherValue = findBy$ref(otherValueOrigin.$ref, openApi); - } - // 忽略数组顺序的影响 - if (isArray(objValue) && isArray(otherValue)) { - const sortObjValue = sortBy(objValue); - const sortOtherValue = sortBy(otherValue); - const keys = [...new Set([...Object.keys(sortObjValue), ...Object.keys(sortOtherValue)])].filter( - key => !ignoreKeyArr.includes(key) - ); - return keys.every(key => isEqualWith((sortObjValue as any)[key], (sortOtherValue as any)[key], customizer)); - } - // 如果是对象,递归比较 - if (isObject(objValue) && isObject(otherValue)) { - if (visited.has(objValue) && visited.get(objValue) === otherValue) { - return true; - } - visited.set(objValue, otherValue); - const keys = [...new Set([...Object.keys(objValue), ...Object.keys(otherValue)])].filter( - key => !ignoreKeyArr.includes(key) - ); - return keys.every(key => isEqualWith((objValue as any)[key], (otherValue as any)[key], customizer)); - } - } - return isEqualWith(objValue, srcValue, customizer); -} -/** - * - * @param path $ref路径 - * @param map 已存在的$ref路径 - * @returns 另一个版本的$ref路径 - */ -export function getNext$refKey(path: string, map: Array<[string, any]> = []) { - function getNameVersion(path: string) { - const name = getStandardRefName(path, false); - const [, nameVersion = 0] = /(\d+)$/.exec(name) ?? []; - return Number(nameVersion); - } - function getOnlyName(path: string) { - const name = getStandardRefName(path, false); - const [, onlyName] = /(.*?)(\d*)$/.exec(name) ?? []; - return onlyName; - } - function getOnlyPath(path: string) { - return path.split('/').slice(0, -1).join('/'); - } - const name = getOnlyName(path); - const basePath = getOnlyPath(path); - let nameVersion = getNameVersion(path); - map.forEach(([key]) => { - if (getOnlyName(key) === name && getOnlyPath(path) === basePath) { - nameVersion = Math.max(nameVersion, getNameVersion(key)); - } - }); - return `${basePath}/${name}${nameVersion + 1}`; -} -function isCircular(obj: any) { - const seenObjects = new WeakSet(); - - function detect(obj: any) { - if (obj && typeof obj === 'object') { - if (seenObjects.has(obj)) { - return true; - } - seenObjects.add(obj); - for (const key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - if (detect(obj[key])) { - return true; - } - } - } - } - return false; - } - - return detect(obj); -} -function unCircular(obj: Record, openApi: OpenAPIV3_1.Document, map: Array<[string, any]>) { - if (isBaseReferenceObject(obj)) { - const refObj = { $ref: obj._$ref }; - if (isEqualObject(obj, refObj, openApi)) { - return refObj; - } - for (const key in obj) { - if (isCircular(obj[key])) { - obj[key] = unCircular(obj[key], openApi, map); - } - } - const [path] = map.find(([, item]) => isEqualObject(item, obj, openApi)) ?? []; - if (path) { - return { - $ref: path - }; - } - const nextPath = getNext$refKey(refObj.$ref, map); - map.push([nextPath, obj]); - setComponentsBy$ref(nextPath, obj, openApi); - return { - $ref: nextPath - }; - } - for (const key in obj) { - if (isCircular(obj[key])) { - obj[key] = unCircular(obj[key], openApi, map); - } - } - return obj; -} -/** - * 合并openApi文档对象尽量以srcValue为准 - * @param objValue - * @param srcValue - * @param openApi - * @returns - */ -export const mergeObject = ( - objValue: any, - srcValue: any, - openApi: OpenAPIV3_1.Document, - map: Array<[string, any]> = [] -): T => { - function customizer(objValue: any, srcValue: any): any { - // 如果都是数组,并且srcValue为空数组,则直接返回srcValue - if (isArray(objValue) && isArray(srcValue) && !srcValue.length) { - return srcValue; - } - if (isEqualObject(objValue, srcValue, openApi)) { - return objValue; - } - // 处理循环引用 - if (isCircular(srcValue)) { - srcValue = unCircular(srcValue, openApi, map); - } - return srcValue; - } - return mergeWith(objValue, srcValue, customizer); -}; -const refPathMap = new Map(); -const refNameSet = new Set(); -export function getStandardRefName(refPath: string, toUpperCase: boolean = true) { - if (refPathMap.has(refPath)) { - return refPathMap.get(refPath) ?? ''; - } - const refName = get$refName(refPath, toUpperCase); - if (isValidJSIdentifier(refName)) { - refNameSet.add(refName); - refPathMap.set(refPath, refName); - return refName; - } - let newRefName = makeIdentifier(refName, 'snakeCase'); - if (toUpperCase) { - newRefName = capitalizeFirstLetter(newRefName); - } - if (refNameSet.has(newRefName)) { - let num = 1; - while (refNameSet.has(`${newRefName}${num}`)) { - num += 1; - } - newRefName = `${newRefName}${num}`; - } - refNameSet.add(newRefName); - refPathMap.set(refPath, newRefName); - return newRefName; -} +import { capitalizeFirstLetter } from '@/utils'; +import { cloneDeep, isArray, isEqualWith, isObject, mergeWith, sortBy } from 'lodash'; +import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'; +import { isValidJSIdentifier, makeIdentifier } from './standard'; +/** + * 判断是否是$ref对象 + * @param obj 判断对象 + * @returns 是否是$ref对象 + */ +export function isReferenceObject(obj: any): obj is OpenAPIV3.ReferenceObject { + return !!(obj as OpenAPIV3.ReferenceObject)?.$ref; +} +function isBaseReferenceObject(obj: any): obj is { _$ref: string } & Record { + return !!(obj as { _$ref: string })?._$ref; +} + +/** + * + * @param path $ref查找路径 + * @param openApi openApi文档对象 + * @param isDeep 是否深拷贝 + * @returns 查找到的SchemaObject + */ +export const findBy$ref = ( + path: string, + openApi: OpenAPIV3_1.Document, + isDeep: boolean = false +) => { + const pathArr = path.split('/'); + let find: any = { + '#': openApi + }; + pathArr.forEach(key => { + if (find) { + find = find[key]; + } + }); + return (isDeep ? cloneDeep(find) : find) as T; +}; +/** + * + * @param path $ref路径 + * @param data 复用对象 + * @param openApi 插入的openapi文档对象 + */ +export const setComponentsBy$ref = (path: string, data: any, openApi: OpenAPIV3_1.Document) => { + const pathArr = path.split('/'); + let find: any = { + '#': openApi + }; + pathArr.forEach((key, idx) => { + if (idx + 1 === pathArr.length) { + find[key] = data; + return; + } + if (find[key]) { + find = find[key]; + } else { + find = find[key] = {}; + } + }); +}; +/** + * + * @param path $ref路径 + * @param toUpperCase 是否首字母大小 + * @returns 引用对象名称 + */ +export const get$refName = (path: string, toUpperCase: boolean = true) => { + const pathArr = path.split('/'); + const name = pathArr[pathArr.length - 1]; + if (!toUpperCase) { + return name; + } + return capitalizeFirstLetter(name); +}; +/** + * + * @param schemaOrigin 含$ref的对象 + * @param openApi openApi文档对象 + * @returns 去除了$ref的对象 + */ +export const removeAll$ref = ( + schemaOrigin: any, + openApi: OpenAPIV3_1.Document, + searchMap: Map = new Map() +) => { + const deepSchemaOrigin = cloneDeep(schemaOrigin); + let schema: OpenAPIV3_1.SchemaObject & Record; + if (isReferenceObject(deepSchemaOrigin)) { + if (searchMap.has(deepSchemaOrigin.$ref)) { + return searchMap.get(deepSchemaOrigin.$ref) as T; + } + schema = findBy$ref(deepSchemaOrigin.$ref, openApi, true); + // 做标记方便还原 + schema._$ref = deepSchemaOrigin.$ref; + searchMap.set(deepSchemaOrigin.$ref, schema); + } else { + schema = deepSchemaOrigin; + } + for (const key of Object.keys(schema)) { + if (schema[key] && typeof schema[key] === 'object') { + schema[key] = removeAll$ref(schema[key], openApi, searchMap); + } + } + return schema as T; +}; +/** + * + * @param objValue 待比较的对象 + * @param srcValue 源对象 + * @param openApi openApi文档对象 + * @returns 是否相等 + */ +export function isEqualObject(objValue: any, srcValue: any, openApi: OpenAPIV3_1.Document) { + const visited = new WeakMap(); + const ignoreKeyArr = ['_$ref']; + function customizer(objValueOrigin: any, otherValueOrigin: any) { + if (objValueOrigin === otherValueOrigin) { + return true; + } + let objValue = objValueOrigin; + let otherValue = otherValueOrigin; + if (isReferenceObject(objValueOrigin)) { + objValue = findBy$ref(objValueOrigin.$ref, openApi); + } + if (isReferenceObject(otherValueOrigin)) { + otherValue = findBy$ref(otherValueOrigin.$ref, openApi); + } + // 忽略数组顺序的影响 + if (isArray(objValue) && isArray(otherValue)) { + const sortObjValue = sortBy(objValue); + const sortOtherValue = sortBy(otherValue); + const keys = [...new Set([...Object.keys(sortObjValue), ...Object.keys(sortOtherValue)])].filter( + key => !ignoreKeyArr.includes(key) + ); + return keys.every(key => isEqualWith((sortObjValue as any)[key], (sortOtherValue as any)[key], customizer)); + } + // 如果是对象,递归比较 + if (isObject(objValue) && isObject(otherValue)) { + if (visited.has(objValue) && visited.get(objValue) === otherValue) { + return true; + } + visited.set(objValue, otherValue); + const keys = [...new Set([...Object.keys(objValue), ...Object.keys(otherValue)])].filter( + key => !ignoreKeyArr.includes(key) + ); + return keys.every(key => isEqualWith((objValue as any)[key], (otherValue as any)[key], customizer)); + } + } + return isEqualWith(objValue, srcValue, customizer); +} +/** + * + * @param path $ref路径 + * @param map 已存在的$ref路径 + * @returns 另一个版本的$ref路径 + */ +export function getNext$refKey(path: string, map: Array<[string, any]> = []) { + function getNameVersion(path: string) { + const name = getStandardRefName(path, false); + const [, nameVersion = 0] = /(\d+)$/.exec(name) ?? []; + return Number(nameVersion); + } + function getOnlyName(path: string) { + const name = getStandardRefName(path, false); + const [, onlyName] = /(.*?)(\d*)$/.exec(name) ?? []; + return onlyName; + } + function getOnlyPath(path: string) { + return path.split('/').slice(0, -1).join('/'); + } + const name = getOnlyName(path); + const basePath = getOnlyPath(path); + let nameVersion = getNameVersion(path); + map.forEach(([key]) => { + if (getOnlyName(key) === name && getOnlyPath(path) === basePath) { + nameVersion = Math.max(nameVersion, getNameVersion(key)); + } + }); + return `${basePath}/${name}${nameVersion + 1}`; +} +function isCircular(obj: any) { + const seenObjects = new WeakSet(); + + function detect(obj: any) { + if (obj && typeof obj === 'object') { + if (seenObjects.has(obj)) { + return true; + } + seenObjects.add(obj); + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + if (detect(obj[key])) { + return true; + } + } + } + } + return false; + } + + return detect(obj); +} +function unCircular(obj: Record, openApi: OpenAPIV3_1.Document, map: Array<[string, any]>) { + if (isBaseReferenceObject(obj)) { + const refObj = { $ref: obj._$ref }; + if (isEqualObject(obj, refObj, openApi)) { + return refObj; + } + for (const key in obj) { + if (isCircular(obj[key])) { + obj[key] = unCircular(obj[key], openApi, map); + } + } + const [path] = map.find(([, item]) => isEqualObject(item, obj, openApi)) ?? []; + if (path) { + return { + $ref: path + }; + } + const nextPath = getNext$refKey(refObj.$ref, map); + map.push([nextPath, obj]); + setComponentsBy$ref(nextPath, obj, openApi); + return { + $ref: nextPath + }; + } + for (const key in obj) { + if (isCircular(obj[key])) { + obj[key] = unCircular(obj[key], openApi, map); + } + } + return obj; +} +/** + * 合并openApi文档对象尽量以srcValue为准 + * @param objValue + * @param srcValue + * @param openApi + * @returns + */ +export const mergeObject = ( + objValue: any, + srcValue: any, + openApi: OpenAPIV3_1.Document, + map: Array<[string, any]> = [] +): T => { + function customizer(objValue: any, srcValue: any): any { + // 如果都是数组,并且srcValue为空数组,则直接返回srcValue + if (isArray(objValue) && isArray(srcValue) && !srcValue.length) { + return srcValue; + } + if (isEqualObject(objValue, srcValue, openApi)) { + return objValue; + } + // 处理循环引用 + if (isCircular(srcValue)) { + srcValue = unCircular(srcValue, openApi, map); + } + return srcValue; + } + return mergeWith(objValue, srcValue, customizer); +}; +const refPathMap = new Map(); +const refNameSet = new Set(); +export function getStandardRefName(refPath: string, toUpperCase: boolean = true) { + if (refPathMap.has(refPath)) { + return refPathMap.get(refPath) ?? ''; + } + const refName = get$refName(refPath, toUpperCase); + if (isValidJSIdentifier(refName)) { + refNameSet.add(refName); + refPathMap.set(refPath, refName); + return refName; + } + let newRefName = makeIdentifier(refName, 'snakeCase'); + if (toUpperCase) { + newRefName = capitalizeFirstLetter(newRefName); + } + if (refNameSet.has(newRefName)) { + let num = 1; + while (refNameSet.has(`${newRefName}${num}`)) { + num += 1; + } + newRefName = `${newRefName}${num}`; + } + refNameSet.add(newRefName); + refPathMap.set(refPath, newRefName); + return newRefName; +} diff --git a/packages/wormhole/src/helper/schema2type.ts b/packages/wormhole/src/helper/schema2type.ts index 2e97d8d..7e7d47f 100644 --- a/packages/wormhole/src/helper/schema2type.ts +++ b/packages/wormhole/src/helper/schema2type.ts @@ -1,337 +1,337 @@ -import { OpenAPIV3_1 } from 'openapi-types'; -import { format } from '../utils'; -import { findBy$ref, getStandardRefName, isReferenceObject } from './openapi'; -import { isValidJSIdentifier } from './standard'; - -export interface Schema2TypeOptions { - deep?: boolean; // 是否递归解析 - shallowDeep?: boolean; // 只有最外层是解析的 - defaultType?: 'any' | 'unknown'; // 未匹配的时的默认类型 - commentStyle?: 'line' | 'docment'; // 注释风格 - preText?: string; // 注释前缀 - searchMap: Map; - visited?: Set; - on$Ref?: (refOject: OpenAPIV3_1.ReferenceObject) => void; -} -/** - * 生成注释字符串 - * @param type 注释风格 - * @returns 注释对象 - */ -export function comment(type: 'line' | 'docment') { - const startText = type === 'docment' ? '/**\n' : ''; - const endText = type === 'docment' ? '\n */\n' : '\n'; - let str = ''; - let idx = 0; - const preText = type === 'docment' ? ' *' : '//'; - const docmentKeyArr = [['[deprecated]', '@deprecated']]; - const docmentTransformeKeyArr: Array<[string, (text: string) => string]> = [ - [ - '[title]', - (text: string) => { - const [, nextText = ''] = /\[title\](.*)/.exec(text) ?? []; - return `${nextText.trim()}\n---`; - } - ] - ]; - const transformeText = (text: string) => { - text = text.trim(); - if (type === 'line') { - return text; - } - const docmentTransformeFn = docmentTransformeKeyArr.find(item => text.startsWith(item[0])); - if (docmentTransformeFn) { - return docmentTransformeFn[1](text); - } - return docmentKeyArr.find(item => item[0] === text)?.[1] ?? text; - }; - return { - add(text: string) { - if (idx) { - str += '\n'; - } - str += transformeText(text) - .split('\n') - .map(item => `${preText} ${item}`) - .join('\n'); - idx += 1; - }, - end() { - if (!str) { - return str; - } - return startText + str.replace('*/*', '* / *').replace('/*', '/ *').replace('*/', '* /') + endText; - } - }; -} -/** - * 将schema解析为ts类型字符串 - * @param schemaOrigin schema对象 - * @param openApi openApi对象 - * @param config 配置项 - * @returns ts类型字符串 - */ -function parseSchema( - schemaOrigin: OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject, - openApi: OpenAPIV3_1.Document, - config: Schema2TypeOptions -): string { - let schema: OpenAPIV3_1.SchemaObject = schemaOrigin; - let refPath = ''; - if (isReferenceObject(schemaOrigin)) { - refPath = schemaOrigin.$ref; - const nameType = getStandardRefName(schemaOrigin.$ref); - if (config.visited?.has(refPath)) { - return nameType; - } - config.visited?.add(refPath); - if (!config.deep && !config.shallowDeep) { - config.on$Ref?.(schemaOrigin); - return nameType; - } - if (config.searchMap.has(schemaOrigin.$ref)) { - return config.searchMap.get(schemaOrigin.$ref) as string; - } - config.on$Ref?.(schemaOrigin); - config.shallowDeep = false; - schema = findBy$ref(schemaOrigin.$ref, openApi); - } - let result: string; - if (schema.enum) { - result = parseEnum(schema); - if (refPath) { - config.searchMap.set(refPath, result); - } - return result; - } - switch (schema.type) { - case 'object': - result = parseObject(schema, openApi, config); - break; - case 'array': - result = parseArray(schema, openApi, config); - break; - case 'string': - // 根据 https://swagger.io/docs/specification/data-models/data-types/#string - // 针对binary,将类型更改为Blob,其余所有format值均可视为string - if (schema.format === 'binary') { - result = 'Blob'; - } else { - result = 'string'; - } - break; - case 'number': - case 'integer': - result = 'number'; - break; - case 'boolean': - result = 'boolean'; - break; - case 'null': - result = 'null'; - break; - default: - if (schema.oneOf) { - result = schema.oneOf.map(item => parseSchema(item, openApi, config)).join(' | '); - } else { - result = - typeof schema.type === 'string' - ? (schema.type || config.defaultType) ?? 'unknown' - : config.defaultType ?? 'unknown'; - } - } - if (refPath) { - config.searchMap.set(refPath, result); - } - return result; -} -/** - *将object类型的schema解析为ts类型字符串 - * @param schema schema对象 - * @param openApi openApi对象 - * @param config 配置项 - * @returns ts类型字符串 - */ -function parseObject( - schema: OpenAPIV3_1.SchemaObject, - openApi: OpenAPIV3_1.Document, - config: Schema2TypeOptions -): string { - const properties = schema.properties || {}; - const required = new Set(schema.required ?? []); - const lines: string[] = [`{`]; - for (const [key, valueOrigin] of Object.entries(properties)) { - const optionalFlag = required.has(key) ? '' : '?'; - let refPath = ''; - let value = valueOrigin as OpenAPIV3_1.SchemaObject; - if (isReferenceObject(valueOrigin)) { - refPath = valueOrigin.$ref; - value = findBy$ref(valueOrigin.$ref, openApi); - } - let type = parseSchema(valueOrigin, openApi, config); - if (!config.deep && refPath) { - type = getStandardRefName(refPath); - } - let valueStr = ''; - const doc = comment(config.commentStyle ?? 'line'); - if (value.title) { - doc.add(`[title] ${value.title}`); - } - if (value.description) { - doc.add(value.description); - } - if (required.has(key)) { - doc.add('[required]'); - } - if (value.deprecated) { - doc.add('[deprecated]'); - } - const keyValue = key.trim(); - valueStr = `${doc.end()}${isValidJSIdentifier(keyValue) ? keyValue : `"${keyValue}"`}${optionalFlag}: ${type};`; - valueStr.split('\n').forEach(line => lines.push(` ${line}`)); - } - lines.push(`}`); - if (lines.length > 2) { - return lines.join('\n'); - } - if (schema.additionalProperties && typeof schema.additionalProperties !== 'boolean') { - return `Record`; - } - return 'object'; -} -/** - * 将array类型的schema解析为ts类型字符串 - * @param schema schema对象 - * @param openApi openApi对象 - * @param config 配置项 - * @returns ts类型字符串 - */ -function parseArray( - schema: OpenAPIV3_1.ArraySchemaObject, - openApi: OpenAPIV3_1.Document, - config: Schema2TypeOptions -): string { - if (Array.isArray(schema.items)) { - const types = schema.items.map(item => parseSchema(item, openApi, config)); - return `[\n${types.map(type => `${type},\n`)}\n]`; - } - if (schema.items) { - let items = schema.items as OpenAPIV3_1.SchemaObject; - let refPath = ''; - if (isReferenceObject(schema.items)) { - items = findBy$ref(schema.items.$ref, openApi); - refPath = schema.items.$ref; - } - const type = parseSchema(schema.items, openApi, config); - if (!config.deep && refPath) { - return `${getStandardRefName(refPath)}[]`; - } - switch (items.type) { - case 'object': - return `Array<${type}>`; - case 'array': - return `${type}[]`; - default: - break; - } - if (items.oneOf || items.enum) { - return `(${type})[]`; - } - return `${type}[]`; - } - return '[]'; -} -/** - * 将enum类型的schema解析为ts类型字符串 - * @param schema schema对象 - * @returns ts类型字符串 - */ -function parseEnum(schema: OpenAPIV3_1.SchemaObject): string { - return schema.enum?.map?.((value: any) => JSON.stringify(value))?.join?.(' | ') || ''; -} -/** - * 将schema解析为格式化后的ts类型字符串 - * @param schemaOrigin schema对象 - * @param openApi openapi文档对象 - * @param config 配置项 - * @returns 格式化后的ts类型字符串 - */ -export async function convertToType( - schemaOrigin: OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject, - openApi: OpenAPIV3_1.Document, - config: Schema2TypeOptions -): Promise { - if (!schemaOrigin) { - return config.defaultType ?? 'unknown'; - } - if (!config.visited) { - config.visited = new Set(); - } - const tsStr = parseSchema(schemaOrigin, openApi, config); - // 格式化ts类型 - const tsStrFormat = await format(`type Ts = ${tsStr}`, { - semi: false // 去掉分号 - }); - const resultFormat = /type Ts =(.*)/s.exec(tsStrFormat)?.[1] ?? ''; - const tsStrArr = resultFormat.trim().split('\n'); - // 加前缀,便于生成注释 - return tsStrArr.map((line, idx) => (idx ? config.preText : '') + line).join('\n'); -} -interface JsonSchema2TsOptions { - export?: boolean; - on$RefTsStr?: (name: string, tsStr: string) => void; -} -/** - * 将schema对象解析为ts类型字符串 - * @param schema schema对象 - * @param name 类型名称 - * @param openApi openapi文档对象 - * @param options 配置项 - * @returns interface Ts字符串 - */ -export const jsonSchema2TsStr = async ( - schema: OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject, - name: string, - openApi: OpenAPIV3_1.Document, - options: JsonSchema2TsOptions = { export: false }, - searchMap: Map = new Map(), - map: Map = new Map(), - visited: Set = new Set() -): Promise => { - const tsStr = await convertToType(schema, openApi, { - shallowDeep: true, - defaultType: 'unknown', - commentStyle: 'docment', - preText: '', - searchMap, - async on$Ref(refObject) { - if (options.on$RefTsStr) { - const name = getStandardRefName(refObject.$ref); - if (map.has(name)) { - options.on$RefTsStr(name, map.get(name) ?? ''); - return; - } - if (visited.has(refObject.$ref)) { - return; - } - visited.add(refObject.$ref); - const result = await jsonSchema2TsStr( - findBy$ref(refObject.$ref, openApi), - name, - openApi, - options, - searchMap, - map, - visited - ); - map.set(name, result); - options.on$RefTsStr(name, result); - } - } - }); - let result = `type ${name} = ${tsStr}`; - if (options.export) { - result = `export ${result}`; - } - return result; -}; +import { format } from '@/utils'; +import { OpenAPIV3_1 } from 'openapi-types'; +import { findBy$ref, getStandardRefName, isReferenceObject } from './openapi'; +import { isValidJSIdentifier } from './standard'; + +export interface Schema2TypeOptions { + deep?: boolean; // 是否递归解析 + shallowDeep?: boolean; // 只有最外层是解析的 + defaultType?: 'any' | 'unknown'; // 未匹配的时的默认类型 + commentStyle?: 'line' | 'docment'; // 注释风格 + preText?: string; // 注释前缀 + searchMap: Map; + visited?: Set; + on$Ref?: (refOject: OpenAPIV3_1.ReferenceObject) => void; +} +/** + * 生成注释字符串 + * @param type 注释风格 + * @returns 注释对象 + */ +export function comment(type: 'line' | 'docment') { + const startText = type === 'docment' ? '/**\n' : ''; + const endText = type === 'docment' ? '\n */\n' : '\n'; + let str = ''; + let idx = 0; + const preText = type === 'docment' ? ' *' : '//'; + const docmentKeyArr = [['[deprecated]', '@deprecated']]; + const docmentTransformeKeyArr: Array<[string, (text: string) => string]> = [ + [ + '[title]', + (text: string) => { + const [, nextText = ''] = /\[title\](.*)/.exec(text) ?? []; + return `${nextText.trim()}\n---`; + } + ] + ]; + const transformeText = (text: string) => { + text = text.trim(); + if (type === 'line') { + return text; + } + const docmentTransformeFn = docmentTransformeKeyArr.find(item => text.startsWith(item[0])); + if (docmentTransformeFn) { + return docmentTransformeFn[1](text); + } + return docmentKeyArr.find(item => item[0] === text)?.[1] ?? text; + }; + return { + add(text: string) { + if (idx) { + str += '\n'; + } + str += transformeText(text) + .split('\n') + .map(item => `${preText} ${item}`) + .join('\n'); + idx += 1; + }, + end() { + if (!str) { + return str; + } + return startText + str.replace('*/*', '* / *').replace('/*', '/ *').replace('*/', '* /') + endText; + } + }; +} +/** + * 将schema解析为ts类型字符串 + * @param schemaOrigin schema对象 + * @param openApi openApi对象 + * @param config 配置项 + * @returns ts类型字符串 + */ +function parseSchema( + schemaOrigin: OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject, + openApi: OpenAPIV3_1.Document, + config: Schema2TypeOptions +): string { + let schema: OpenAPIV3_1.SchemaObject = schemaOrigin; + let refPath = ''; + if (isReferenceObject(schemaOrigin)) { + refPath = schemaOrigin.$ref; + const nameType = getStandardRefName(schemaOrigin.$ref); + if (config.visited?.has(refPath)) { + return nameType; + } + config.visited?.add(refPath); + if (!config.deep && !config.shallowDeep) { + config.on$Ref?.(schemaOrigin); + return nameType; + } + if (config.searchMap.has(schemaOrigin.$ref)) { + return config.searchMap.get(schemaOrigin.$ref) as string; + } + config.on$Ref?.(schemaOrigin); + config.shallowDeep = false; + schema = findBy$ref(schemaOrigin.$ref, openApi); + } + let result: string; + if (schema.enum) { + result = parseEnum(schema); + if (refPath) { + config.searchMap.set(refPath, result); + } + return result; + } + switch (schema.type) { + case 'object': + result = parseObject(schema, openApi, config); + break; + case 'array': + result = parseArray(schema, openApi, config); + break; + case 'string': + // 根据 https://swagger.io/docs/specification/data-models/data-types/#string + // 针对binary,将类型更改为Blob,其余所有format值均可视为string + if (schema.format === 'binary') { + result = 'Blob'; + } else { + result = 'string'; + } + break; + case 'number': + case 'integer': + result = 'number'; + break; + case 'boolean': + result = 'boolean'; + break; + case 'null': + result = 'null'; + break; + default: + if (schema.oneOf) { + result = schema.oneOf.map(item => parseSchema(item, openApi, config)).join(' | '); + } else { + result = + typeof schema.type === 'string' + ? (schema.type || config.defaultType) ?? 'unknown' + : config.defaultType ?? 'unknown'; + } + } + if (refPath) { + config.searchMap.set(refPath, result); + } + return result; +} +/** + *将object类型的schema解析为ts类型字符串 + * @param schema schema对象 + * @param openApi openApi对象 + * @param config 配置项 + * @returns ts类型字符串 + */ +function parseObject( + schema: OpenAPIV3_1.SchemaObject, + openApi: OpenAPIV3_1.Document, + config: Schema2TypeOptions +): string { + const properties = schema.properties || {}; + const required = new Set(schema.required ?? []); + const lines: string[] = [`{`]; + for (const [key, valueOrigin] of Object.entries(properties)) { + const optionalFlag = required.has(key) ? '' : '?'; + let refPath = ''; + let value = valueOrigin as OpenAPIV3_1.SchemaObject; + if (isReferenceObject(valueOrigin)) { + refPath = valueOrigin.$ref; + value = findBy$ref(valueOrigin.$ref, openApi); + } + let type = parseSchema(valueOrigin, openApi, config); + if (!config.deep && refPath) { + type = getStandardRefName(refPath); + } + let valueStr = ''; + const doc = comment(config.commentStyle ?? 'line'); + if (value.title) { + doc.add(`[title] ${value.title}`); + } + if (value.description) { + doc.add(value.description); + } + if (required.has(key)) { + doc.add('[required]'); + } + if (value.deprecated) { + doc.add('[deprecated]'); + } + const keyValue = key.trim(); + valueStr = `${doc.end()}${isValidJSIdentifier(keyValue) ? keyValue : `"${keyValue}"`}${optionalFlag}: ${type};`; + valueStr.split('\n').forEach(line => lines.push(` ${line}`)); + } + lines.push(`}`); + if (lines.length > 2) { + return lines.join('\n'); + } + if (schema.additionalProperties && typeof schema.additionalProperties !== 'boolean') { + return `Record`; + } + return 'object'; +} +/** + * 将array类型的schema解析为ts类型字符串 + * @param schema schema对象 + * @param openApi openApi对象 + * @param config 配置项 + * @returns ts类型字符串 + */ +function parseArray( + schema: OpenAPIV3_1.ArraySchemaObject, + openApi: OpenAPIV3_1.Document, + config: Schema2TypeOptions +): string { + if (Array.isArray(schema.items)) { + const types = schema.items.map(item => parseSchema(item, openApi, config)); + return `[\n${types.map(type => `${type},\n`)}\n]`; + } + if (schema.items) { + let items = schema.items as OpenAPIV3_1.SchemaObject; + let refPath = ''; + if (isReferenceObject(schema.items)) { + items = findBy$ref(schema.items.$ref, openApi); + refPath = schema.items.$ref; + } + const type = parseSchema(schema.items, openApi, config); + if (!config.deep && refPath) { + return `${getStandardRefName(refPath)}[]`; + } + switch (items.type) { + case 'object': + return `Array<${type}>`; + case 'array': + return `${type}[]`; + default: + break; + } + if (items.oneOf || items.enum) { + return `(${type})[]`; + } + return `${type}[]`; + } + return '[]'; +} +/** + * 将enum类型的schema解析为ts类型字符串 + * @param schema schema对象 + * @returns ts类型字符串 + */ +function parseEnum(schema: OpenAPIV3_1.SchemaObject): string { + return schema.enum?.map?.((value: any) => JSON.stringify(value))?.join?.(' | ') || ''; +} +/** + * 将schema解析为格式化后的ts类型字符串 + * @param schemaOrigin schema对象 + * @param openApi openapi文档对象 + * @param config 配置项 + * @returns 格式化后的ts类型字符串 + */ +export async function convertToType( + schemaOrigin: OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject, + openApi: OpenAPIV3_1.Document, + config: Schema2TypeOptions +): Promise { + if (!schemaOrigin) { + return config.defaultType ?? 'unknown'; + } + if (!config.visited) { + config.visited = new Set(); + } + const tsStr = parseSchema(schemaOrigin, openApi, config); + // 格式化ts类型 + const tsStrFormat = await format(`type Ts = ${tsStr}`, { + semi: false // 去掉分号 + }); + const resultFormat = /type Ts =(.*)/s.exec(tsStrFormat)?.[1] ?? ''; + const tsStrArr = resultFormat.trim().split('\n'); + // 加前缀,便于生成注释 + return tsStrArr.map((line, idx) => (idx ? config.preText : '') + line).join('\n'); +} +interface JsonSchema2TsOptions { + export?: boolean; + on$RefTsStr?: (name: string, tsStr: string) => void; +} +/** + * 将schema对象解析为ts类型字符串 + * @param schema schema对象 + * @param name 类型名称 + * @param openApi openapi文档对象 + * @param options 配置项 + * @returns interface Ts字符串 + */ +export const jsonSchema2TsStr = async ( + schema: OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject, + name: string, + openApi: OpenAPIV3_1.Document, + options: JsonSchema2TsOptions = { export: false }, + searchMap: Map = new Map(), + map: Map = new Map(), + visited: Set = new Set() +): Promise => { + const tsStr = await convertToType(schema, openApi, { + shallowDeep: true, + defaultType: 'unknown', + commentStyle: 'docment', + preText: '', + searchMap, + async on$Ref(refObject) { + if (options.on$RefTsStr) { + const name = getStandardRefName(refObject.$ref); + if (map.has(name)) { + options.on$RefTsStr(name, map.get(name) ?? ''); + return; + } + if (visited.has(refObject.$ref)) { + return; + } + visited.add(refObject.$ref); + const result = await jsonSchema2TsStr( + findBy$ref(refObject.$ref, openApi), + name, + openApi, + options, + searchMap, + map, + visited + ); + map.set(name, result); + options.on$RefTsStr(name, result); + } + } + }); + let result = `type ${name} = ${tsStr}`; + if (options.export) { + result = `export ${result}`; + } + return result; +}; diff --git a/packages/wormhole/src/helper/typeStr.ts b/packages/wormhole/src/helper/typeStr.ts index 305295f..f6ca97e 100644 --- a/packages/wormhole/src/helper/typeStr.ts +++ b/packages/wormhole/src/helper/typeStr.ts @@ -1,174 +1,174 @@ -import { format } from '../utils'; -// 去除注释 -function removeComments(content: string) { - // 去除单行注释 - content = content.replace(/\/\/.*$/gm, ''); - // 去除多行注释和文档注释 - content = content.replace(/\/\*[\s\S]*?\*\//g, ''); - return content; -} -const LEFT_BRACKET = ['(', '<', '{', '[']; -const RIGHT_BRACKET = [')', '>', '}', ']']; -function parseTypeBody(typeBody: string) { - const properties = []; - let bracketCount = 0; - let currentProperty = ''; - - for (let i = 0; i < typeBody.length; i += 1) { - const char = typeBody[i]; - if (LEFT_BRACKET.includes(char)) { - bracketCount += 1; - } else if (RIGHT_BRACKET.includes(char)) { - bracketCount -= 1; - } - currentProperty += char; - if (currentProperty.trim() && /\n/.test(char) && bracketCount === 0) { - properties.push(currentProperty.trim()); - currentProperty = ''; - } - } - if (currentProperty.trim()) { - properties.push(currentProperty.trim()); - } - const parsedProperties = properties - .map(prop => { - const [keyOrigin, ...valueOrigin] = prop.split(':'); - const key = keyOrigin.trim(); - const value = valueOrigin.join(':').trim(); - const isOptional = key.endsWith('?'); - const defaultValue = getDefaultValue(value); - return { key: key.replace('?', ''), value: defaultValue, isOptional }; - }) - .filter(prop => !prop.isOptional) - .map(prop => `${prop.key}:${prop.value}`) - .join(',\n'); - return `{\n${parsedProperties}\n}`; -} -function isSplitType(type: string, c: '&' | '|') { - if (!type.includes(c)) { - return false; - } - let bracketCount = 0; - for (let i = 0; i < type.length; i += 1) { - const char = type[i]; - if (LEFT_BRACKET.includes(char)) { - bracketCount += 1; - } else if (RIGHT_BRACKET.includes(char)) { - bracketCount -= 1; - } - if (bracketCount === 0 && char === c) { - return true; - } - } - return false; -} -function splitTypes(typeStr: string, c: '&' | '|'): string[] { - const result: string[] = []; - let bracketCount = 0; - let currentType = ''; - for (let i = 0; i < typeStr.length; i += 1) { - const char = typeStr[i]; - if (LEFT_BRACKET.includes(char)) { - bracketCount += 1; - } else if (RIGHT_BRACKET.includes(char)) { - bracketCount -= 1; - } - - if (char === c && bracketCount === 0) { - result.push(currentType.trim()); - currentType = ''; - } else { - currentType += char; - } - } - if (currentType.trim()) { - result.push(currentType.trim()); - } - return result; -} -function isIntersectionType(type: string) { - return isSplitType(type, '&'); -} -function isUnionType(type: string) { - return isSplitType(type, '|'); -} -function getDefaultValue(type: string): string { - if (isUnionType(type)) { - const types = splitTypes(type, '|'); - return getDefaultValue(types[0]); - } - if (isIntersectionType(type)) { - const types = splitTypes(type, '&'); - const mergedDefaults = types.map(t => getDefaultValue(t)); - return mergedDefaults.reduce((acc, curr) => { - if (curr.startsWith('{') && curr.endsWith('}')) { - const currProperties = curr.slice(1, -1).trim(); - if (acc === '{}') { - return `{ ${currProperties} }`; - } - return `${acc.slice(0, -1)}, ${currProperties} }`; - } - return acc; - }, '{}'); - } - if (type.startsWith('{') && type.endsWith('}')) { - return parseTypeBody(type.slice(1, -1)); - } - if (type.endsWith(')[]') && type.startsWith('(')) { - return '[]'; - } - if (type.endsWith('[]') || type.startsWith('Array<')) { - return '[]'; - } - - if (type.startsWith('[') && type.endsWith(']')) { - return parseTuple(type); - } - if ((type.startsWith("'") && type.endsWith("'")) || (type.startsWith('"') && type.endsWith('"'))) { - return type; - } - if (parseInt(type, 10)) { - return type; - } - switch (type) { - case 'string': - return '""'; - case 'number': - return '0'; - case 'boolean': - return 'false'; - case 'null': - case 'undefined': - return type; - default: - return '{}'; - } -} -function parseTuple(tupleType: string) { - const elements = tupleType - .slice(1, -1) - .split(',') - .map(el => el.trim()); - const parsedElements = elements.map(el => getDefaultValue(el)); - return `[${parsedElements.join(', ')}]`; -} -/** - * 从给定的 TypeScript 源代码生成类型和接口的默认值对象。 - * @param sourceCode - TypeScript 源代码字符串 - * @returns 包含类型和接口默认值的对象 - */ -export function generateDefaultValues : string>( - sourceCode: string, - isFormat?: T -): U { - const defaultValue = getDefaultValue(removeComments(sourceCode).trim()); - if (isFormat) { - return format(defaultValue, { - parser: 'json' - }) as U; - } - return defaultValue as U; -} -export default { - generateDefaultValues -}; +import { format } from '@/utils'; +// 去除注释 +function removeComments(content: string) { + // 去除单行注释 + content = content.replace(/\/\/.*$/gm, ''); + // 去除多行注释和文档注释 + content = content.replace(/\/\*[\s\S]*?\*\//g, ''); + return content; +} +const LEFT_BRACKET = ['(', '<', '{', '[']; +const RIGHT_BRACKET = [')', '>', '}', ']']; +function parseTypeBody(typeBody: string) { + const properties = []; + let bracketCount = 0; + let currentProperty = ''; + + for (let i = 0; i < typeBody.length; i += 1) { + const char = typeBody[i]; + if (LEFT_BRACKET.includes(char)) { + bracketCount += 1; + } else if (RIGHT_BRACKET.includes(char)) { + bracketCount -= 1; + } + currentProperty += char; + if (currentProperty.trim() && /\n/.test(char) && bracketCount === 0) { + properties.push(currentProperty.trim()); + currentProperty = ''; + } + } + if (currentProperty.trim()) { + properties.push(currentProperty.trim()); + } + const parsedProperties = properties + .map(prop => { + const [keyOrigin, ...valueOrigin] = prop.split(':'); + const key = keyOrigin.trim(); + const value = valueOrigin.join(':').trim(); + const isOptional = key.endsWith('?'); + const defaultValue = getDefaultValue(value); + return { key: key.replace('?', ''), value: defaultValue, isOptional }; + }) + .filter(prop => !prop.isOptional) + .map(prop => `${prop.key}:${prop.value}`) + .join(',\n'); + return `{\n${parsedProperties}\n}`; +} +function isSplitType(type: string, c: '&' | '|') { + if (!type.includes(c)) { + return false; + } + let bracketCount = 0; + for (let i = 0; i < type.length; i += 1) { + const char = type[i]; + if (LEFT_BRACKET.includes(char)) { + bracketCount += 1; + } else if (RIGHT_BRACKET.includes(char)) { + bracketCount -= 1; + } + if (bracketCount === 0 && char === c) { + return true; + } + } + return false; +} +function splitTypes(typeStr: string, c: '&' | '|'): string[] { + const result: string[] = []; + let bracketCount = 0; + let currentType = ''; + for (let i = 0; i < typeStr.length; i += 1) { + const char = typeStr[i]; + if (LEFT_BRACKET.includes(char)) { + bracketCount += 1; + } else if (RIGHT_BRACKET.includes(char)) { + bracketCount -= 1; + } + + if (char === c && bracketCount === 0) { + result.push(currentType.trim()); + currentType = ''; + } else { + currentType += char; + } + } + if (currentType.trim()) { + result.push(currentType.trim()); + } + return result; +} +function isIntersectionType(type: string) { + return isSplitType(type, '&'); +} +function isUnionType(type: string) { + return isSplitType(type, '|'); +} +function getDefaultValue(type: string): string { + if (isUnionType(type)) { + const types = splitTypes(type, '|'); + return getDefaultValue(types[0]); + } + if (isIntersectionType(type)) { + const types = splitTypes(type, '&'); + const mergedDefaults = types.map(t => getDefaultValue(t)); + return mergedDefaults.reduce((acc, curr) => { + if (curr.startsWith('{') && curr.endsWith('}')) { + const currProperties = curr.slice(1, -1).trim(); + if (acc === '{}') { + return `{ ${currProperties} }`; + } + return `${acc.slice(0, -1)}, ${currProperties} }`; + } + return acc; + }, '{}'); + } + if (type.startsWith('{') && type.endsWith('}')) { + return parseTypeBody(type.slice(1, -1)); + } + if (type.endsWith(')[]') && type.startsWith('(')) { + return '[]'; + } + if (type.endsWith('[]') || type.startsWith('Array<')) { + return '[]'; + } + + if (type.startsWith('[') && type.endsWith(']')) { + return parseTuple(type); + } + if ((type.startsWith("'") && type.endsWith("'")) || (type.startsWith('"') && type.endsWith('"'))) { + return type; + } + if (parseInt(type, 10)) { + return type; + } + switch (type) { + case 'string': + return '""'; + case 'number': + return '0'; + case 'boolean': + return 'false'; + case 'null': + case 'undefined': + return type; + default: + return '{}'; + } +} +function parseTuple(tupleType: string) { + const elements = tupleType + .slice(1, -1) + .split(',') + .map(el => el.trim()); + const parsedElements = elements.map(el => getDefaultValue(el)); + return `[${parsedElements.join(', ')}]`; +} +/** + * 从给定的 TypeScript 源代码生成类型和接口的默认值对象。 + * @param sourceCode - TypeScript 源代码字符串 + * @returns 包含类型和接口默认值的对象 + */ +export function generateDefaultValues : string>( + sourceCode: string, + isFormat?: T +): U { + const defaultValue = getDefaultValue(removeComments(sourceCode).trim()); + if (isFormat) { + return format(defaultValue, { + parser: 'json' + }) as U; + } + return defaultValue as U; +} +export default { + generateDefaultValues +}; diff --git a/packages/wormhole/src/index.ts b/packages/wormhole/src/index.ts index ffd9b44..23538c8 100644 --- a/packages/wormhole/src/index.ts +++ b/packages/wormhole/src/index.ts @@ -1,3 +1,4 @@ +export type * from '~/index'; export * from './config'; export * from './createConfig'; export * from './functions/alovaJson'; @@ -5,4 +6,3 @@ export * from './functions/openApi2Data'; export * from './generate'; export { default as Configuration } from './modules/Configuration'; export * from './readConfig'; -export * from './type'; diff --git a/packages/wormhole/src/modules/Configuration.ts b/packages/wormhole/src/modules/Configuration.ts index 2af988e..3841f6c 100644 --- a/packages/wormhole/src/modules/Configuration.ts +++ b/packages/wormhole/src/modules/Configuration.ts @@ -1,137 +1,137 @@ -import path from 'node:path'; -import type { Config, GeneratorConfig, TemplateType } from '..'; -import { DEFAULT_CONFIG } from '../config'; -import { getAlovaJsonPath, readAlovaJson } from '../functions/alovaJson'; -import getAutoTemplateType from '../functions/getAutoTemplateType'; -import getOpenApiData from '../functions/getOpenApiData'; -import { isValidJSIdentifier } from '../helper/standard'; -import { isEmpty } from '../utils'; - -export default class Configuration { - config: Config; - - workspaceRootDir: string; - - constructor(config: Config, workspaceRootDir: string) { - // 配置文件 - this.config = config; - this.workspaceRootDir = workspaceRootDir; - } - - // 检测配置文件 - checkConfig() { - if (!this.config.generator?.length) { - throw new DEFAULT_CONFIG.Error('No items found in the `config.generator`'); - } - const globalKeySet = new Set(); - const outputSet = new Set(); - this.config.generator.forEach((item, _, arr) => { - if (!item.input) { - throw new DEFAULT_CONFIG.Error('Field input is required in `config.generator`'); - } - if (!item.output) { - throw new DEFAULT_CONFIG.Error('Field output is required in `config.generator`'); - } - if (!isEmpty(item.global) && !isValidJSIdentifier(item.global)) { - throw new DEFAULT_CONFIG.Error(`\`${item.global}\` does not match variable specification`); - } - if (arr.length < 2) { - return; - } - if (outputSet.has(path.join(item.output))) { - throw new DEFAULT_CONFIG.Error(`output \`${item.output}\` is repated`); - } - outputSet.add(path.join(item.output)); - if (!item.global) { - throw new DEFAULT_CONFIG.Error('Field global is required in `config.generator`'); - } - if (globalKeySet.has(item.global)) { - throw new DEFAULT_CONFIG.Error(`global \`${item.global}\` is repated`); - } - globalKeySet.add(item.global); - }); - if (typeof this.config.autoUpdate === 'object') { - const { interval } = this.config.autoUpdate; - const time = Number(interval); - if (Number.isNaN(time)) { - throw new DEFAULT_CONFIG.Error('autoUpdate.interval must be a number'); - } - if (time <= 0) { - // 最少一秒钟 - throw new DEFAULT_CONFIG.Error('Expected to set number which great than 1 in `config.autoUpdate.interval`'); - } - } - } - - static getTemplateType(workspaceRootDir: string, generator: GeneratorConfig): TemplateType { - let type: TemplateType; - const configType = generator.type ?? 'auto'; - // 根据配置文件中的type来判断模板类型 - switch (configType) { - case 'ts': - case 'typescript': - type = 'typescript'; - break; - case 'module': - type = 'module'; - break; - case 'auto': - type = getAutoTemplateType(workspaceRootDir); - break; - default: - type = 'commonjs'; - break; - } - return type; - } - - getAllTemplateType() { - return this.config.generator.map(generator => Configuration.getTemplateType(this.workspaceRootDir, generator)); - } - - getAllOutputPath() { - return this.config.generator.map(generator => generator.output); - } - - // 获取openapi数据 - static getOpenApiData(workspaceRootDir: string, generator: GeneratorConfig) { - return getOpenApiData(workspaceRootDir, generator.input, generator.platform); - } - - // 获取所有openapi数据 - getAllOpenApiData() { - return Promise.all( - this.config.generator.map(generator => Configuration.getOpenApiData(this.workspaceRootDir, generator)) - ); - } - - getAutoUpdateConfig() { - const autoUpdateConfig = this.config.autoUpdate; - let time = 60 * 5; // 默认五分钟 - let immediate = false; - if (typeof autoUpdateConfig === 'object') { - time = Number(autoUpdateConfig.interval); - immediate = !!autoUpdateConfig.launchEditor; - } - return { - time, - immediate - }; - } - - readAlovaJson() { - const allAlovaJSon = this.config.generator.map(generator => { - const alovaJsonPath = getAlovaJsonPath(this.workspaceRootDir, generator.output); - return readAlovaJson(alovaJsonPath) - .then(alovaJson => { - DEFAULT_CONFIG.templateData.set(alovaJsonPath, alovaJson); - return alovaJson; - }) - .catch(() => { - DEFAULT_CONFIG.templateData.delete(alovaJsonPath); - return {}; - }); - }); - return Promise.all(allAlovaJSon); - } -} +import { DEFAULT_CONFIG } from '@/config'; +import { getAlovaJsonPath, readAlovaJson } from '@/functions/alovaJson'; +import getAutoTemplateType from '@/functions/getAutoTemplateType'; +import getOpenApiData from '@/functions/getOpenApiData'; +import { isValidJSIdentifier } from '@/helper/standard'; +import { isEmpty } from '@/utils'; +import path from 'node:path'; +import type { Config, GeneratorConfig, TemplateType } from '~/index'; + +export default class Configuration { + config: Config; + + workspaceRootDir: string; + + constructor(config: Config, workspaceRootDir: string) { + // 配置文件 + this.config = config; + this.workspaceRootDir = workspaceRootDir; + } + + // 检测配置文件 + checkConfig() { + if (!this.config.generator?.length) { + throw new DEFAULT_CONFIG.Error('No items found in the `config.generator`'); + } + const globalKeySet = new Set(); + const outputSet = new Set(); + this.config.generator.forEach((item, _, arr) => { + if (!item.input) { + throw new DEFAULT_CONFIG.Error('Field input is required in `config.generator`'); + } + if (!item.output) { + throw new DEFAULT_CONFIG.Error('Field output is required in `config.generator`'); + } + if (!isEmpty(item.global) && !isValidJSIdentifier(item.global)) { + throw new DEFAULT_CONFIG.Error(`\`${item.global}\` does not match variable specification`); + } + if (arr.length < 2) { + return; + } + if (outputSet.has(path.join(item.output))) { + throw new DEFAULT_CONFIG.Error(`output \`${item.output}\` is repated`); + } + outputSet.add(path.join(item.output)); + if (!item.global) { + throw new DEFAULT_CONFIG.Error('Field global is required in `config.generator`'); + } + if (globalKeySet.has(item.global)) { + throw new DEFAULT_CONFIG.Error(`global \`${item.global}\` is repated`); + } + globalKeySet.add(item.global); + }); + if (typeof this.config.autoUpdate === 'object') { + const { interval } = this.config.autoUpdate; + const time = Number(interval); + if (Number.isNaN(time)) { + throw new DEFAULT_CONFIG.Error('autoUpdate.interval must be a number'); + } + if (time <= 0) { + // 最少一秒钟 + throw new DEFAULT_CONFIG.Error('Expected to set number which great than 1 in `config.autoUpdate.interval`'); + } + } + } + + static getTemplateType(workspaceRootDir: string, generator: GeneratorConfig): TemplateType { + let type: TemplateType; + const configType = generator.type ?? 'auto'; + // 根据配置文件中的type来判断模板类型 + switch (configType) { + case 'ts': + case 'typescript': + type = 'typescript'; + break; + case 'module': + type = 'module'; + break; + case 'auto': + type = getAutoTemplateType(workspaceRootDir); + break; + default: + type = 'commonjs'; + break; + } + return type; + } + + getAllTemplateType() { + return this.config.generator.map(generator => Configuration.getTemplateType(this.workspaceRootDir, generator)); + } + + getAllOutputPath() { + return this.config.generator.map(generator => generator.output); + } + + // 获取openapi数据 + static getOpenApiData(workspaceRootDir: string, generator: GeneratorConfig) { + return getOpenApiData(workspaceRootDir, generator.input, generator.platform); + } + + // 获取所有openapi数据 + getAllOpenApiData() { + return Promise.all( + this.config.generator.map(generator => Configuration.getOpenApiData(this.workspaceRootDir, generator)) + ); + } + + getAutoUpdateConfig() { + const autoUpdateConfig = this.config.autoUpdate; + let time = 60 * 5; // 默认五分钟 + let immediate = false; + if (typeof autoUpdateConfig === 'object') { + time = Number(autoUpdateConfig.interval); + immediate = !!autoUpdateConfig.launchEditor; + } + return { + time, + immediate + }; + } + + readAlovaJson() { + const allAlovaJSon = this.config.generator.map(generator => { + const alovaJsonPath = getAlovaJsonPath(this.workspaceRootDir, generator.output); + return readAlovaJson(alovaJsonPath) + .then(alovaJson => { + DEFAULT_CONFIG.templateData.set(alovaJsonPath, alovaJson); + return alovaJson; + }) + .catch(() => { + DEFAULT_CONFIG.templateData.delete(alovaJsonPath); + return {}; + }); + }); + return Promise.all(allAlovaJSon); + } +} diff --git a/packages/wormhole/src/modules/TemplateFile.ts b/packages/wormhole/src/modules/TemplateFile.ts index 634a15b..4a43461 100644 --- a/packages/wormhole/src/modules/TemplateFile.ts +++ b/packages/wormhole/src/modules/TemplateFile.ts @@ -1,78 +1,78 @@ -import { cloneDeep, merge } from 'lodash'; -import type { TemplateType } from '..'; -import type { AlovaVersion } from '../functions/getAlovaVersion'; -import { generateFile, readAndRenderTemplate } from '../utils'; - -interface RenderTemplateOptions { - root?: boolean; - hasVersion?: boolean; - ext?: string; - outFileName?: string; -} -const DEFAULT_OPTIONS = { - root: false, - hasVersion: true -}; - -export default class TemplateFile { - type: TemplateType; - - alovaVersion: AlovaVersion; - - constructor(type: TemplateType, alovaVersion: AlovaVersion) { - // 根据type确定使用哪个模板文件夹下的模板 - this.type = type; - this.alovaVersion = alovaVersion; - } - - private getVersion() { - switch (this.alovaVersion) { - case 'v3': - return 'v3-'; - default: - return ''; - } - } - - // 获取生成文件的后缀名 - getExt() { - return TemplateFile.getExt(this.type); - } - - // 获取模块类型 - getModuleType() { - return TemplateFile.getModuleType(this.type); - } - - static getExt(type: TemplateType) { - switch (type) { - case 'typescript': - return '.ts'; - default: - return '.js'; - } - } - - static getModuleType(type: TemplateType) { - switch (type) { - case 'typescript': - case 'module': - return 'ESModule'; - default: - return 'commonJs'; - } - } - - async outputFile(data: Record, fileName: string, ouput: string, config?: RenderTemplateOptions) { - // 这里实现模板文件渲染工作,例如返回文件内容和文件名,然后再写入output的文件夹 - const renderContent = await this.readAndRenderTemplate(fileName, data, config); - await generateFile(ouput, `${config?.outFileName ?? fileName}${config?.ext ?? this.getExt()}`, renderContent); - } - - readAndRenderTemplate(fileName: string, data: any, userConfig?: RenderTemplateOptions) { - const config = merge(cloneDeep(DEFAULT_OPTIONS), userConfig); - const fileVersion = config.hasVersion ? this.getVersion() : ''; - const filePath = config?.root ? fileVersion + fileName : `${this.type}/${fileVersion}${fileName}`; - return readAndRenderTemplate(filePath, data); - } -} +import type { AlovaVersion } from '@/functions/getAlovaVersion'; +import { generateFile, readAndRenderTemplate } from '@/utils'; +import { cloneDeep, merge } from 'lodash'; +import type { TemplateType } from '~/index'; + +interface RenderTemplateOptions { + root?: boolean; + hasVersion?: boolean; + ext?: string; + outFileName?: string; +} +const DEFAULT_OPTIONS = { + root: false, + hasVersion: true +}; + +export default class TemplateFile { + type: TemplateType; + + alovaVersion: AlovaVersion; + + constructor(type: TemplateType, alovaVersion: AlovaVersion) { + // 根据type确定使用哪个模板文件夹下的模板 + this.type = type; + this.alovaVersion = alovaVersion; + } + + private getVersion() { + switch (this.alovaVersion) { + case 'v3': + return 'v3-'; + default: + return ''; + } + } + + // 获取生成文件的后缀名 + getExt() { + return TemplateFile.getExt(this.type); + } + + // 获取模块类型 + getModuleType() { + return TemplateFile.getModuleType(this.type); + } + + static getExt(type: TemplateType) { + switch (type) { + case 'typescript': + return '.ts'; + default: + return '.js'; + } + } + + static getModuleType(type: TemplateType) { + switch (type) { + case 'typescript': + case 'module': + return 'ESModule'; + default: + return 'commonJs'; + } + } + + async outputFile(data: Record, fileName: string, ouput: string, config?: RenderTemplateOptions) { + // 这里实现模板文件渲染工作,例如返回文件内容和文件名,然后再写入output的文件夹 + const renderContent = await this.readAndRenderTemplate(fileName, data, config); + await generateFile(ouput, `${config?.outFileName ?? fileName}${config?.ext ?? this.getExt()}`, renderContent); + } + + readAndRenderTemplate(fileName: string, data: any, userConfig?: RenderTemplateOptions) { + const config = merge(cloneDeep(DEFAULT_OPTIONS), userConfig); + const fileVersion = config.hasVersion ? this.getVersion() : ''; + const filePath = config?.root ? fileVersion + fileName : `${this.type}/${fileVersion}${fileName}`; + return readAndRenderTemplate(filePath, data); + } +} diff --git a/packages/wormhole/src/readConfig.ts b/packages/wormhole/src/readConfig.ts index 65355b3..bf35c23 100644 --- a/packages/wormhole/src/readConfig.ts +++ b/packages/wormhole/src/readConfig.ts @@ -1,46 +1,46 @@ -import { cosmiconfig } from 'cosmiconfig'; -import path from 'node:path'; -import { DEFAULT_CONFIG } from './config'; -import { getAlovaJsonPath, readAlovaJson } from './functions/alovaJson'; -import { loadJs, loadTs } from './helper/lodaders'; -import Configuration from './modules/Configuration'; -import type { Config } from './type'; - -const alovaExplorer = cosmiconfig('alova', { - cache: false, - loaders: { - '.js': loadJs, - '.cjs': loadJs, - '.mjs': loadJs, - '.ts': loadTs, - '.mts': loadTs, - '.cts': loadTs - } -}); -export const readConfig = async (projectPath: string = process.cwd()) => { - const searchResult = await alovaExplorer.search(path.resolve(projectPath)); - alovaExplorer.clearCaches(); - if (searchResult?.isEmpty) { - return null; - } - const config = searchResult?.config as Config | null; - if (config) { - // 缓存文件地址 - readAndSaveAlovaJson(config, projectPath); - } - return config; -}; -export const readAndSaveAlovaJson = (config: Config, projectPath: string = process.cwd()) => { - const configuration = new Configuration(config, projectPath); - configuration.getAllOutputPath().forEach(outputPath => { - // 缓存文件地址 - const alovaJsonPath = getAlovaJsonPath(projectPath, outputPath); - readAlovaJson(alovaJsonPath) - .then(data => { - // 保存templateData - DEFAULT_CONFIG.templateData.set(alovaJsonPath, data); - }) - .catch(() => {}); - }); -}; -export default readConfig; +import { cosmiconfig } from 'cosmiconfig'; +import path from 'node:path'; +import type { Config } from '~/index'; +import { DEFAULT_CONFIG } from './config'; +import { getAlovaJsonPath, readAlovaJson } from './functions/alovaJson'; +import { loadJs, loadTs } from './helper/lodaders'; +import Configuration from './modules/Configuration'; + +const alovaExplorer = cosmiconfig('alova', { + cache: false, + loaders: { + '.js': loadJs, + '.cjs': loadJs, + '.mjs': loadJs, + '.ts': loadTs, + '.mts': loadTs, + '.cts': loadTs + } +}); +export const readConfig = async (projectPath: string = process.cwd()) => { + const searchResult = await alovaExplorer.search(path.resolve(projectPath)); + alovaExplorer.clearCaches(); + if (searchResult?.isEmpty) { + return null; + } + const config = searchResult?.config as Config | null; + if (config) { + // 缓存文件地址 + readAndSaveAlovaJson(config, projectPath); + } + return config; +}; +export const readAndSaveAlovaJson = (config: Config, projectPath: string = process.cwd()) => { + const configuration = new Configuration(config, projectPath); + configuration.getAllOutputPath().forEach(outputPath => { + // 缓存文件地址 + const alovaJsonPath = getAlovaJsonPath(projectPath, outputPath); + readAlovaJson(alovaJsonPath) + .then(data => { + // 保存templateData + DEFAULT_CONFIG.templateData.set(alovaJsonPath, data); + }) + .catch(() => {}); + }); +}; +export default readConfig; diff --git a/packages/wormhole/src/templates/index.ts b/packages/wormhole/src/templates/index.ts deleted file mode 100644 index 835db6c..0000000 --- a/packages/wormhole/src/templates/index.ts +++ /dev/null @@ -1 +0,0 @@ -export default (filePath: string) => import(`./${filePath}.handlebars`); diff --git a/packages/wormhole/src/utils/index.ts b/packages/wormhole/src/utils/index.ts index 452bfe6..196dd64 100644 --- a/packages/wormhole/src/utils/index.ts +++ b/packages/wormhole/src/utils/index.ts @@ -1,148 +1,147 @@ -/* eslint-disable no-bitwise */ -import handlebars, { HelperOptions } from 'handlebars'; -import fetch from 'node-fetch'; -import fs, { promises } from 'node:fs'; -import path from 'node:path'; -import { Config as PrettierConfig } from 'prettier'; -import * as prettierBabel from 'prettier/plugins/babel'; -import * as prettierEsTree from 'prettier/plugins/estree'; -import * as prettierTs from 'prettier/plugins/typescript'; -import * as prettier from 'prettier/standalone'; -import { DEFAULT_CONFIG } from '../config'; - -export const prettierConfig: PrettierConfig = { - printWidth: 120, - tabWidth: 2, - useTabs: false, - semi: true, - singleQuote: true, - trailingComma: 'none', - bracketSpacing: true, - insertPragma: false, - endOfLine: 'auto', - bracketSameLine: true, - arrowParens: 'avoid', - vueIndentScriptAndStyle: false, - singleAttributePerLine: true -}; -export const getType = (obj: any) => Object.prototype.toString.call(obj).slice(8, -1).toLowerCase(); -handlebars.registerHelper('isType', function (this: any, value, type: string, options: HelperOptions) { - if (getType(value) === type) { - return options.fn(this); - } - return options.inverse(this); -}); -handlebars.registerHelper('and', function (this: any, ...rest) { - const args = Array.prototype.slice.call(rest, 0, -1); - const options = rest[rest.length - 1] as HelperOptions; - const result = args.every(arg => { - if (Array.isArray(arg)) { - return arg.length === 0; - } - return Boolean(arg); - }); - return result ? options.fn(this) : options.inverse(this); -}); -handlebars.registerHelper('or', function (this: any, ...rest) { - const args = Array.prototype.slice.call(rest, 0, -1); - const options = rest[rest.length - 1] as HelperOptions; - const result = args.some(arg => { - if (Array.isArray(arg)) { - return arg.length !== 0; - } - return Boolean(arg); - }); - return result ? options.fn(this) : options.inverse(this); -}); -handlebars.registerHelper('eq', (a, b) => a === b); -handlebars.registerHelper('not', (a, b) => a !== b); -// 注册自定义助手函数 'raw' -handlebars.registerHelper( - 'raw', - text => - // 返回原始字符串,不进行 HTML 转义 - new handlebars.SafeString(text) -); -/** - * 读取并渲染 handlebars 文件 - * @param templatePath 模板文件路径 - * @param view - 渲染模板所需的数据对象 - * @returns 渲染后的内容 - */ -export async function readAndRenderTemplate(templatePath: string, view: any): Promise { - let data = ''; - try { - data = await promises.readFile(path.resolve(DEFAULT_CONFIG.templatePath, `${templatePath}.handlebars`), 'utf-8'); - } catch (error) { - const importFn = (await import('../templates/index.js')).default; - data = (await (importFn as any)(templatePath)).default; - } - return handlebars.compile(data)(view); -} -export async function format(text: string, config?: PrettierConfig) { - return prettier.format(text, { - ...(prettierConfig as PrettierConfig), - parser: 'typescript', // 指定使用 babel 解析器 - ...(config ?? {}), - plugins: [prettierTs, prettierEsTree, prettierBabel] - }); -} -/** - * 传入文本内容,在指定目录下生成自定义文件 - * @param distDir 待生成文件所在目录 - * @param fileName 待生成文件名 - * @param content 文件内容 - */ -export async function generateFile(distDir: string, fileName: string, content: string) { - if (!fs.existsSync(distDir)) { - fs.mkdirSync(distDir, { recursive: true }); - } - const filePath = path.join(distDir, fileName); - const formattedText = await format(content); - fs.writeFile(filePath, formattedText, (err: NodeJS.ErrnoException | null) => { - if (err) { - return console.error('Error writing file:', err); - } - console.log('File written successfully at', filePath); - }); -} -export async function fetchData(url: string) { - return fetch(url).then(response => { - if (!response.ok) { - throw new DEFAULT_CONFIG.Error(`HTTP error! status: ${response.status}`); - } - return response.text(); - }); -} - -// 去掉所有为空的undefined值 -export function removeUndefined(obj: T) { - const defaultObject = Array.isArray(obj) ? [] : {}; - if (typeof obj !== 'object' || !obj) { - return obj; - } - return Object.keys(obj).reduce((result, key) => { - const value = removeUndefined((obj as any)[key]); - if (value !== undefined) { - (result as any)[key] = value; - } - return result; - }, defaultObject) as T; -} - -// 反序列化 -export function deserialize(serializedJavascript: string) { - // eslint-disable-next-line no-eval - return eval(`(${serializedJavascript})`); -} -export function isEmpty(value: any) { - return value === null || value === undefined || value === ''; -} -export function capitalizeFirstLetter(str: string) { - if (!str) return str; - return str.charAt(0).toUpperCase() + str.slice(1); -} -// 加载ESM 模块 -export function loadEsmModule(modulePath: string | URL): Promise { - return new Function('modulePath', `return import(modulePath);`)(modulePath) as Promise; -} +/* eslint-disable no-bitwise */ +import handlebars, { HelperOptions } from 'handlebars'; +import fetch from 'node-fetch'; +import fs, { promises } from 'node:fs'; +import path from 'node:path'; +import { Config as PrettierConfig } from 'prettier'; +import * as prettierBabel from 'prettier/plugins/babel'; +import * as prettierEsTree from 'prettier/plugins/estree'; +import * as prettierTs from 'prettier/plugins/typescript'; +import * as prettier from 'prettier/standalone'; +import { DEFAULT_CONFIG } from '../config'; + +export const prettierConfig: PrettierConfig = { + printWidth: 120, + tabWidth: 2, + useTabs: false, + semi: true, + singleQuote: true, + trailingComma: 'none', + bracketSpacing: true, + insertPragma: false, + endOfLine: 'auto', + bracketSameLine: true, + arrowParens: 'avoid', + vueIndentScriptAndStyle: false, + singleAttributePerLine: true +}; +export const getType = (obj: any) => Object.prototype.toString.call(obj).slice(8, -1).toLowerCase(); +handlebars.registerHelper('isType', function (this: any, value, type: string, options: HelperOptions) { + if (getType(value) === type) { + return options.fn(this); + } + return options.inverse(this); +}); +handlebars.registerHelper('and', function (this: any, ...rest) { + const args = Array.prototype.slice.call(rest, 0, -1); + const options = rest[rest.length - 1] as HelperOptions; + const result = args.every(arg => { + if (Array.isArray(arg)) { + return arg.length === 0; + } + return Boolean(arg); + }); + return result ? options.fn(this) : options.inverse(this); +}); +handlebars.registerHelper('or', function (this: any, ...rest) { + const args = Array.prototype.slice.call(rest, 0, -1); + const options = rest[rest.length - 1] as HelperOptions; + const result = args.some(arg => { + if (Array.isArray(arg)) { + return arg.length !== 0; + } + return Boolean(arg); + }); + return result ? options.fn(this) : options.inverse(this); +}); +handlebars.registerHelper('eq', (a, b) => a === b); +handlebars.registerHelper('not', (a, b) => a !== b); +// 注册自定义助手函数 'raw' +handlebars.registerHelper( + 'raw', + text => + // 返回原始字符串,不进行 HTML 转义 + new handlebars.SafeString(text) +); +/** + * 读取并渲染 handlebars 文件 + * @param templatePath 模板文件路径 + * @param view - 渲染模板所需的数据对象 + * @returns 渲染后的内容 + */ +export async function readAndRenderTemplate(templatePath: string, view: any): Promise { + let data = ''; + try { + data = await promises.readFile(path.resolve(DEFAULT_CONFIG.templatePath, `${templatePath}.handlebars`), 'utf-8'); + } catch (error) { + data = (await import(`./templates/${templatePath}.handlebars`)).default; + } + return handlebars.compile(data)(view); +} +export async function format(text: string, config?: PrettierConfig) { + return prettier.format(text, { + ...(prettierConfig as PrettierConfig), + parser: 'typescript', // 指定使用 babel 解析器 + ...(config ?? {}), + plugins: [prettierTs, prettierEsTree, prettierBabel] + }); +} +/** + * 传入文本内容,在指定目录下生成自定义文件 + * @param distDir 待生成文件所在目录 + * @param fileName 待生成文件名 + * @param content 文件内容 + */ +export async function generateFile(distDir: string, fileName: string, content: string) { + if (!fs.existsSync(distDir)) { + fs.mkdirSync(distDir, { recursive: true }); + } + const filePath = path.join(distDir, fileName); + const formattedText = await format(content); + fs.writeFile(filePath, formattedText, (err: NodeJS.ErrnoException | null) => { + if (err) { + return console.error('Error writing file:', err); + } + console.log('File written successfully at', filePath); + }); +} +export async function fetchData(url: string) { + return fetch(url).then(response => { + if (!response.ok) { + throw new DEFAULT_CONFIG.Error(`HTTP error! status: ${response.status}`); + } + return response.text(); + }); +} + +// 去掉所有为空的undefined值 +export function removeUndefined(obj: T) { + const defaultObject = Array.isArray(obj) ? [] : {}; + if (typeof obj !== 'object' || !obj) { + return obj; + } + return Object.keys(obj).reduce((result, key) => { + const value = removeUndefined((obj as any)[key]); + if (value !== undefined) { + (result as any)[key] = value; + } + return result; + }, defaultObject) as T; +} + +// 反序列化 +export function deserialize(serializedJavascript: string) { + // eslint-disable-next-line no-eval + return eval(`(${serializedJavascript})`); +} +export function isEmpty(value: any) { + return value === null || value === undefined || value === ''; +} +export function capitalizeFirstLetter(str: string) { + if (!str) return str; + return str.charAt(0).toUpperCase() + str.slice(1); +} +// 加载ESM 模块 +export function loadEsmModule(modulePath: string | URL): Promise { + return new Function('modulePath', `return import(modulePath);`)(modulePath) as Promise; +} diff --git a/packages/wormhole/tsconfig.json b/packages/wormhole/tsconfig.json new file mode 100644 index 0000000..4ca50de --- /dev/null +++ b/packages/wormhole/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "baseUrl": ".", + "paths": { + "~/*": ["./typings/*"], + "@/*": ["./src/*"], + "#/*": ["./*"] + } + }, + "include": ["src/**/*.ts", "./*.ts", "typings/**/*.d.ts"] +} diff --git a/packages/wormhole/src/type.ts b/packages/wormhole/typings/index.d.ts similarity index 97% rename from packages/wormhole/src/type.ts rename to packages/wormhole/typings/index.d.ts index 47b8c28..13e8a4b 100644 --- a/packages/wormhole/src/type.ts +++ b/packages/wormhole/typings/index.d.ts @@ -1,79 +1,79 @@ -// 查找对应的input属性值 -export type ConfigType = 'auto' | 'ts' | 'typescript' | 'module' | 'commonjs'; -// 模板类型 -export type TemplateType = 'typescript' | 'module' | 'commonjs'; -// 平台类型 -export type PlatformType = 'swagger' | 'knife4j' | 'yapi'; -export namespace OpenAPIV3_1 {} -export type SchemaObject = import('openapi-types').OpenAPIV3_1.SchemaObject; -export type Parameter = import('openapi-types').OpenAPIV3_1.ParameterObject; -export type OperationObject = import('openapi-types').OpenAPIV3_1.OperationObject; -export type ApiDescriptor = Omit & { - url: string; - method: string; - parameters?: Parameter[]; - requestBody?: SchemaObject; - responses?: SchemaObject; -}; -export interface HandleApi { - (apiDescriptor: ApiDescriptor): ApiDescriptor; - (apiDescriptor: ApiDescriptor, log: (...args: any[]) => void): ApiDescriptor; -} -export type GeneratorConfig = { - // openapi的json文件url地址 - input: string; - // input: 'http://localhost:3000/openapi.json', - // input: 'openapi/api.json' // 以当前项目为相对目录的本地地址 - // input: 'http://192.168.5.123:8080' // 没有指向openapi文件时,必须配合platform参数使用 - - // 支持openapi的平台,目前先支持swagger、knife4j、yapi,默认为空 - // 当指定了此参数后,input字段只需要指定文档的地址而不需要指定到openapi文件,减小使用门槛 - // 不同平台,它的openapi文件地址不一样,根据平台标识去对应地址下读取文件即可。 - platform: PlatformType; - - // 接口文件和类型文件的输出路径,多个generator不能重复的地址,否则生成的代码会相互覆盖,无意义 - output: string; - - // (具体看下面)指定生成的响应数据的mediaType,指定后以此数据类型来生成200状态码的响应ts格式,默认application/json - responseMediaType: string; - - // (具体看下面)指定生成的请求体数据的mediaType,指定后以此数据类型来生成请求体的ts格式,默认application/json - bodyMediaType: string; - - // 生成代码的类型,可选值为auto/ts/typescript/module/commonjs,默认为auto,会通过一定规则判断当前项目的类型 - // ts/typescript:意思相同,表示生成ts类型文件 - // module:生成esModule规范文件 - // commonjs:表示生成commonjs规范文件 - type: ConfigType; - // 指定alova版本 - version: Number; - // 多项目使用global字段 - global?: string; - // 是否使用import来导入类型,默认false - // 开启此选项后,生成的apiDefinitions.ts文件将使用import语法来导入类型,而不是/// - useImportType: boolean; - // (具体看下面)过滤或转换生成的api接口函数,返回一个新的apiDescriptor来生成api调用函数 - // 未指定此函数时则不转换apiDescripor对象 - // apiDescriptor的格式与openapi文件的接口对象格式相同 - // 对类型生成也同样适用 - handleApi: HandleApi; -}; -export type Config = { - // api生成设置,为数组,每项代表一个自动生成的规则,包含生成的输入输出目录、规范文件地址等等 - // 目前只支持openapi规范,包括openapi的2.0和3.0格式,但目前只做3.0规范 - generator: GeneratorConfig[]; - - // 是否自动更新接口,默认开启,每5分钟检查一次,false时关闭 - autoUpdate: - | boolean - | { - // 编辑器开启时更新,默认false - launchEditor: boolean; - // 自动更新间隔,单位毫秒 - interval: number; - }; -}; -export type GenerateApiOptions = { - force?: boolean; - projectPath?: string; -}; +// 查找对应的input属性值 +export type ConfigType = 'auto' | 'ts' | 'typescript' | 'module' | 'commonjs'; +// 模板类型 +export type TemplateType = 'typescript' | 'module' | 'commonjs'; +// 平台类型 +export type PlatformType = 'swagger' | 'knife4j' | 'yapi'; +export namespace OpenAPIV3_1 {} +export type SchemaObject = import('openapi-types').OpenAPIV3_1.SchemaObject; +export type Parameter = import('openapi-types').OpenAPIV3_1.ParameterObject; +export type OperationObject = import('openapi-types').OpenAPIV3_1.OperationObject; +export type ApiDescriptor = Omit & { + url: string; + method: string; + parameters?: Parameter[]; + requestBody?: SchemaObject; + responses?: SchemaObject; +}; +export interface HandleApi { + (apiDescriptor: ApiDescriptor): ApiDescriptor; + (apiDescriptor: ApiDescriptor, log: (...args: any[]) => void): ApiDescriptor; +} +export type GeneratorConfig = { + // openapi的json文件url地址 + input: string; + // input: 'http://localhost:3000/openapi.json', + // input: 'openapi/api.json' // 以当前项目为相对目录的本地地址 + // input: 'http://192.168.5.123:8080' // 没有指向openapi文件时,必须配合platform参数使用 + + // 支持openapi的平台,目前先支持swagger、knife4j、yapi,默认为空 + // 当指定了此参数后,input字段只需要指定文档的地址而不需要指定到openapi文件,减小使用门槛 + // 不同平台,它的openapi文件地址不一样,根据平台标识去对应地址下读取文件即可。 + platform: PlatformType; + + // 接口文件和类型文件的输出路径,多个generator不能重复的地址,否则生成的代码会相互覆盖,无意义 + output: string; + + // (具体看下面)指定生成的响应数据的mediaType,指定后以此数据类型来生成200状态码的响应ts格式,默认application/json + responseMediaType: string; + + // (具体看下面)指定生成的请求体数据的mediaType,指定后以此数据类型来生成请求体的ts格式,默认application/json + bodyMediaType: string; + + // 生成代码的类型,可选值为auto/ts/typescript/module/commonjs,默认为auto,会通过一定规则判断当前项目的类型 + // ts/typescript:意思相同,表示生成ts类型文件 + // module:生成esModule规范文件 + // commonjs:表示生成commonjs规范文件 + type: ConfigType; + // 指定alova版本 + version: Number; + // 多项目使用global字段 + global?: string; + // 是否使用import来导入类型,默认false + // 开启此选项后,生成的apiDefinitions.ts文件将使用import语法来导入类型,而不是/// + useImportType: boolean; + // (具体看下面)过滤或转换生成的api接口函数,返回一个新的apiDescriptor来生成api调用函数 + // 未指定此函数时则不转换apiDescripor对象 + // apiDescriptor的格式与openapi文件的接口对象格式相同 + // 对类型生成也同样适用 + handleApi: HandleApi; +}; +export type Config = { + // api生成设置,为数组,每项代表一个自动生成的规则,包含生成的输入输出目录、规范文件地址等等 + // 目前只支持openapi规范,包括openapi的2.0和3.0格式,但目前只做3.0规范 + generator: GeneratorConfig[]; + + // 是否自动更新接口,默认开启,每5分钟检查一次,false时关闭 + autoUpdate: + | boolean + | { + // 编辑器开启时更新,默认false + launchEditor: boolean; + // 自动更新间隔,单位毫秒 + interval: number; + }; +}; +export type GenerateApiOptions = { + force?: boolean; + projectPath?: string; +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a7f27d7..1190d2d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,7 +10,7 @@ importers: dependencies: cosmiconfig: specifier: ^9.0.0 - version: 9.0.0(typescript@5.4.5) + version: 9.0.0(typescript@5.5.4) handlebars: specifier: ^4.7.8 version: 4.7.8 @@ -35,7 +35,7 @@ importers: version: link:packages/wormhole '@commitlint/cli': specifier: ^19.3.0 - version: 19.3.0(@types/node@18.19.34)(typescript@5.4.5) + version: 19.3.0(@types/node@18.19.34)(typescript@5.5.4) '@commitlint/config-conventional': specifier: ^19.2.2 version: 19.2.2 @@ -62,28 +62,25 @@ importers: version: 7.0.4 '@typescript-eslint/eslint-plugin': specifier: ^7.13.0 - version: 7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) + version: 7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4) '@typescript-eslint/parser': specifier: ^7.13.0 - version: 7.13.0(eslint@8.57.0)(typescript@5.4.5) + version: 7.13.0(eslint@8.57.0)(typescript@5.5.4) commitizen: specifier: ^4.3.0 - version: 4.3.0(@types/node@18.19.34)(typescript@5.4.5) + version: 4.3.0(@types/node@18.19.34)(typescript@5.5.4) cz-conventional-changelog: specifier: ^3.3.0 - version: 3.3.0(@types/node@18.19.34)(typescript@5.4.5) + version: 3.3.0(@types/node@18.19.34)(typescript@5.5.4) eslint: specifier: ^8.57.0 version: 8.57.0 eslint-config-airbnb: specifier: ^19.0.4 - version: 19.0.4(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react@7.34.2(eslint@8.57.0))(eslint@8.57.0) + version: 19.0.4(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react@7.34.2(eslint@8.57.0))(eslint@8.57.0) eslint-config-airbnb-typescript: specifier: ^18.0.0 - version: 18.0.0(@typescript-eslint/eslint-plugin@7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) - eslint-config-prettier: - specifier: ^9.1.0 - version: 9.1.0(eslint@8.57.0) + version: 18.0.0(@typescript-eslint/eslint-plugin@7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4))(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0))(eslint@8.57.0) eslint-plugin-prettier: specifier: ^5.1.3 version: 5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.2) @@ -104,10 +101,13 @@ importers: version: 3.3.2 prettier-plugin-organize-imports: specifier: ^3.2.4 - version: 3.2.4(prettier@3.3.2)(typescript@5.4.5) + version: 3.2.4(prettier@3.3.2)(typescript@5.5.4) prettier-plugin-sort-json: specifier: ^4.0.0 version: 4.0.0(prettier@3.3.2) + tslib: + specifier: ^2.7.0 + version: 2.7.0 tsx: specifier: ^4.15.8 version: 4.16.2 @@ -115,10 +115,8 @@ importers: specifier: ^4.20.0 version: 4.20.0 typescript: - specifier: ^5.4.5 - version: 5.4.5 - - packages/templates: {} + specifier: ^5.5.4 + version: 5.5.4 packages/vscode-extension: devDependencies: @@ -143,9 +141,16 @@ importers: packages/wormhole: dependencies: - '@alova/templates': - specifier: workspace:^ - version: link:../templates + fs-extra: + specifier: ^11.2.0 + version: 11.2.0 + devDependencies: + '@types/fs-extra': + specifier: ^11.0.4 + version: 11.0.4 + unbuild: + specifier: ^2.0.0 + version: 2.0.0(typescript@5.5.4) test/api-js-commonjs-test: dependencies: @@ -157,7 +162,7 @@ importers: version: 2.21.3 vue: specifier: ^3.4.27 - version: 3.4.31(typescript@5.4.5) + version: 3.4.31(typescript@5.5.4) test/api-js-test: dependencies: @@ -166,7 +171,7 @@ importers: version: 2.21.3 vue: specifier: ^3.4.27 - version: 3.4.31(typescript@5.4.5) + version: 3.4.31(typescript@5.5.4) test/api-ts-test: dependencies: @@ -197,7 +202,7 @@ importers: version: 3.0.0-beta.10 vue: specifier: ^3.4.27 - version: 3.4.31(typescript@5.4.5) + version: 3.4.31(typescript@5.5.4) test/api-v3-js-test: dependencies: @@ -206,7 +211,7 @@ importers: version: 3.0.0-beta.10 vue: specifier: ^3.4.27 - version: 3.4.31(typescript@5.4.5) + version: 3.4.31(typescript@5.5.4) test/api-v3-ts-test: dependencies: @@ -245,6 +250,10 @@ packages: '@alova/shared@1.0.4': resolution: {integrity: sha512-Tq47Wd5q76kPmGLXmPijb0AfsXW2aWR9Pid1KO1nz96BdWiKstx2t/ZLTNaGtQzYyB6M+puunaTTJbusJQPmkQ==} + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + '@azure/abort-controller@1.1.0': resolution: {integrity: sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==} engines: {node: '>=12.0.0'} @@ -297,14 +306,56 @@ packages: resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} engines: {node: '>=6.9.0'} + '@babel/compat-data@7.25.4': + resolution: {integrity: sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.25.2': + resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.25.6': + resolution: {integrity: sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.25.2': + resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.24.7': + resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.25.2': + resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-simple-access@7.24.7': + resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.24.7': resolution: {integrity: sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.24.8': + resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.24.7': resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.24.8': + resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.25.6': + resolution: {integrity: sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==} + engines: {node: '>=6.9.0'} + '@babel/highlight@7.24.7': resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} engines: {node: '>=6.9.0'} @@ -314,14 +365,35 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.25.6': + resolution: {integrity: sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/runtime@7.24.7': resolution: {integrity: sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==} engines: {node: '>=6.9.0'} + '@babel/standalone@7.25.6': + resolution: {integrity: sha512-Kf2ZcZVqsKbtYhlA7sP0z5A3q5hmCVYMKMWRWNK/5OVwHIve3JY1djVRmIVAx8FMueLIfZGKQDIILK2w8zO4mg==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.25.0': + resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.25.6': + resolution: {integrity: sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==} + engines: {node: '>=6.9.0'} + '@babel/types@7.24.7': resolution: {integrity: sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==} engines: {node: '>=6.9.0'} + '@babel/types@7.25.6': + resolution: {integrity: sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==} + engines: {node: '>=6.9.0'} + '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} @@ -394,6 +466,12 @@ packages: resolution: {integrity: sha512-tpyc+7i6bPG9mvaBbtKUeghfyZSDgWquIDfMgqYtTbmZ9Y9VzEm2je9EYcQ0aoz5o7NvGS+rcDec93yO08MHYA==} engines: {node: '>=v18'} + '@esbuild/aix-ppc64@0.19.12': + resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.21.5': resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} @@ -406,6 +484,18 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.23.1': + resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.19.12': + resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.21.5': resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} engines: {node: '>=12'} @@ -418,6 +508,18 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.23.1': + resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.19.12': + resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.21.5': resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} engines: {node: '>=12'} @@ -430,6 +532,18 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.23.1': + resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.19.12': + resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.21.5': resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} engines: {node: '>=12'} @@ -442,6 +556,18 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.23.1': + resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.19.12': + resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.21.5': resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} engines: {node: '>=12'} @@ -454,6 +580,18 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.23.1': + resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.19.12': + resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.21.5': resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} engines: {node: '>=12'} @@ -466,6 +604,18 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.23.1': + resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.19.12': + resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.21.5': resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} engines: {node: '>=12'} @@ -478,6 +628,18 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.23.1': + resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.19.12': + resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.21.5': resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} engines: {node: '>=12'} @@ -490,6 +652,18 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.23.1': + resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.19.12': + resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.21.5': resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} engines: {node: '>=12'} @@ -502,6 +676,18 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.23.1': + resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.19.12': + resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.21.5': resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} engines: {node: '>=12'} @@ -514,6 +700,18 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.23.1': + resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.19.12': + resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.21.5': resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} engines: {node: '>=12'} @@ -526,6 +724,18 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.23.1': + resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.19.12': + resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.21.5': resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} engines: {node: '>=12'} @@ -538,6 +748,18 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.23.1': + resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.19.12': + resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.21.5': resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} engines: {node: '>=12'} @@ -550,6 +772,18 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.23.1': + resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.19.12': + resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.21.5': resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} engines: {node: '>=12'} @@ -562,6 +796,18 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.23.1': + resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.19.12': + resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.21.5': resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} engines: {node: '>=12'} @@ -574,6 +820,18 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.23.1': + resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.19.12': + resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.21.5': resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} engines: {node: '>=12'} @@ -586,6 +844,18 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.23.1': + resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.19.12': + resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.21.5': resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} engines: {node: '>=12'} @@ -598,6 +868,18 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.23.1': + resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.19.12': + resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.21.5': resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} engines: {node: '>=12'} @@ -610,12 +892,30 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.23.1': + resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.23.0': resolution: {integrity: sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.23.1': + resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.19.12': + resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.21.5': resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} engines: {node: '>=12'} @@ -628,6 +928,18 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.23.1': + resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.19.12': + resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.21.5': resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} engines: {node: '>=12'} @@ -640,6 +952,18 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.23.1': + resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.19.12': + resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.21.5': resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} engines: {node: '>=12'} @@ -652,6 +976,18 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.23.1': + resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.19.12': + resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.21.5': resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} engines: {node: '>=12'} @@ -664,6 +1000,18 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.23.1': + resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.19.12': + resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.21.5': resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} engines: {node: '>=12'} @@ -676,6 +1024,12 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.23.1': + resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.4.0': resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -722,10 +1076,18 @@ packages: resolution: {integrity: sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==} engines: {node: '>= 10.14.2'} + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + '@jridgewell/sourcemap-codec@1.4.15': resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} @@ -752,9 +1114,73 @@ packages: resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@rollup/plugin-alias@5.1.0': + resolution: {integrity: sha512-lpA3RZ9PdIG7qqhEfv79tBffNaoDuukFDrmhLqg9ifv99u/ehn+lOg30x2zmhf8AQqQUZaMk/B9fZraQ6/acDQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-commonjs@25.0.8': + resolution: {integrity: sha512-ZEZWTK5n6Qde0to4vS9Mr5x/0UZoqCxPVR9KRUjU4kA2sO7GEUn1fop0DAwpO6z0Nw/kJON9bDmSxdWxO/TT1A==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.68.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-json@6.1.0': + resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-node-resolve@15.2.3': + resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-replace@5.0.7': + resolution: {integrity: sha512-PqxSfuorkHz/SPpyngLyg5GCEkOcee9M1bkxiVDr41Pd61mqP1PLOoDPbpl44SB2mQGKwV/In74gqQmGITOhEQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/pluginutils@5.1.0': + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@trysound/sax@0.2.0': + resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} + engines: {node: '>=10.13.0'} + '@types/conventional-commits-parser@5.0.0': resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==} + '@types/estree@1.0.5': + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + + '@types/fs-extra@11.0.4': + resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} + '@types/istanbul-lib-coverage@2.0.6': resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} @@ -773,6 +1199,9 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@types/jsonfile@6.1.4': + resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} + '@types/lodash@4.17.5': resolution: {integrity: sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw==} @@ -788,6 +1217,9 @@ packages: '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + '@types/resolve@1.20.2': + resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + '@types/serialize-javascript@5.0.4': resolution: {integrity: sha512-Z2R7UKFuNWCP8eoa2o9e5rkD3hmWxx/1L0CYz0k2BZzGh0PhEVMp9kfGiqEml/0IglwNERXZ2hwNzIrSz/KHTA==} @@ -1088,6 +1520,13 @@ packages: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} + autoprefixer@10.4.20: + resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} @@ -1134,6 +1573,11 @@ packages: browser-stdout@1.3.1: resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + browserslist@4.23.3: + resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} @@ -1146,6 +1590,10 @@ packages: buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + c8@9.1.0: resolution: {integrity: sha512-mBWcT5iqNir1zIkzSPyI3NCR9EZCVI3WUD+AVO17MVWTSFNyUueXE82qTeampNtTr+ilN/5Ua3j24LgbCKjDVg==} engines: {node: '>=14.14.0'} @@ -1173,6 +1621,12 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} + caniuse-api@3.0.0: + resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} + + caniuse-lite@1.0.30001658: + resolution: {integrity: sha512-N2YVqWbJELVdrnsW5p+apoQyYt51aBMSsBZki1XZEfeBCexcM/sf4xiAHcXQBkuOwJBXtWF7aW1sYX6tKebPHw==} + capital-case@1.0.4: resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} @@ -1212,6 +1666,9 @@ packages: chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + citty@0.1.6: + resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} + cli-cursor@3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -1260,6 +1717,9 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + colord@2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} @@ -1275,20 +1735,34 @@ packages: resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} engines: {node: '>= 6'} + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + commitizen@4.3.0: resolution: {integrity: sha512-H0iNtClNEhT0fotHvGV3E9tDejDeS04sN1veIebsKYGMuGscFaswRoYJKmT3eW85eIJAs0F28bG2+a/9wCOfPw==} engines: {node: '>= 12'} hasBin: true + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + compare-func@2.0.0: resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + confbox@0.1.7: + resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + confusing-browser-globals@1.0.11: resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} + consola@3.2.3: + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} + constant-case@3.0.4: resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==} @@ -1343,13 +1817,54 @@ packages: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} + css-declaration-sorter@7.2.0: + resolution: {integrity: sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.0.9 + css-select@5.1.0: resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + css-what@6.1.0: resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} engines: {node: '>= 6'} + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + cssnano-preset-default@7.0.6: + resolution: {integrity: sha512-ZzrgYupYxEvdGGuqL+JKOY70s7+saoNlHSCK/OGn1vB2pQK8KSET8jvenzItcY+kA7NoWvfbb/YhlzuzNKjOhQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + cssnano-utils@5.0.0: + resolution: {integrity: sha512-Uij0Xdxc24L6SirFr25MlwC2rCFX6scyUmuKpzI+JQ7cyqDEwD42fJ0xfB3yLfOnRDU5LKGgjQ9FA6LYh76GWQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + cssnano@7.0.6: + resolution: {integrity: sha512-54woqx8SCbp8HwvNZYn68ZFAepuouZW4lTwiMVnBErM3VkO7/Sd4oTOt3Zz3bPx3kxQ36aISppyXj2Md4lg8bw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} @@ -1420,6 +1935,10 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} @@ -1435,6 +1954,9 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -1501,6 +2023,9 @@ packages: ecdsa-sig-formatter@1.0.11: resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + electron-to-chromium@1.5.16: + resolution: {integrity: sha512-2gQpi2WYobXmz2q23FrOBYTLcI1O/P4heW3eqX+ldmPVDQELRqhiebV380EhlGG12NtnX1qbK/FHpN0ba+7bLA==} + emoji-regex@10.3.0: resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} @@ -1568,6 +2093,11 @@ packages: esbuild-plugin-alias@0.2.1: resolution: {integrity: sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ==} + esbuild@0.19.12: + resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} + engines: {node: '>=12'} + hasBin: true + esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} @@ -1578,6 +2108,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.23.1: + resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==} + engines: {node: '>=18'} + hasBin: true + escalade@3.1.2: resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} engines: {node: '>=6'} @@ -1827,9 +2362,16 @@ packages: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} + fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + fs-extra@9.1.0: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} @@ -1852,6 +2394,10 @@ packages: functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -1917,6 +2463,10 @@ packages: resolution: {integrity: sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==} engines: {node: '>=0.10.0'} + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + globals@13.24.0: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} engines: {node: '>=8'} @@ -1929,6 +2479,10 @@ packages: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} + globby@13.2.2: + resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} @@ -1984,6 +2538,9 @@ packages: resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} engines: {node: '>=0.10.0'} + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} @@ -2086,6 +2643,10 @@ packages: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} + is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} + is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} @@ -2145,6 +2706,9 @@ packages: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} + is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + is-negative-zero@2.0.3: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} @@ -2169,6 +2733,9 @@ packages: resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} engines: {node: '>=8'} + is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} @@ -2285,6 +2852,11 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true + jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} @@ -2307,6 +2879,11 @@ packages: resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} hasBin: true + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + jsonc-parser@3.3.1: resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} @@ -2422,6 +2999,9 @@ packages: lodash.map@4.6.0: resolution: {integrity: sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==} + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -2473,6 +3053,9 @@ packages: resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} engines: {node: 14 || >=16.14} + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} @@ -2488,6 +3071,12 @@ packages: resolution: {integrity: sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==} hasBin: true + mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + + mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + mdurl@1.0.1: resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} @@ -2562,11 +3151,33 @@ packages: mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + mkdist@1.5.5: + resolution: {integrity: sha512-Kbj0Tt4uk6AN/XEV1W7EgBpJUmEXZgTWxbMKYIpO0hRXoTstFIJrJVqDgPjBz9AXXN3ZpxQBk2Q0n28Ze0Gh1w==} + hasBin: true + peerDependencies: + sass: ^1.77.8 + typescript: '>=5.5.4' + vue-tsc: ^1.8.27 || ^2.0.21 + peerDependenciesMeta: + sass: + optional: true + typescript: + optional: true + vue-tsc: + optional: true + + mlly@1.7.1: + resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} + mocha@10.4.0: resolution: {integrity: sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==} engines: {node: '>= 14.0.0'} hasBin: true + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} @@ -2619,6 +3230,9 @@ packages: node-readfiles@0.2.0: resolution: {integrity: sha512-SU00ZarexNlE4Rjdm83vglt5Y9yiQ+XI1XpflWlb7q7UTN1JUItm69xMeiQCTxtTfnzt+83T8Cx+vI2ED++VDA==} + node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -2626,6 +3240,10 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + npm-run-all@4.1.5: resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==} engines: {node: '>= 4'} @@ -2823,6 +3441,9 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + pend@1.2.0: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} @@ -2847,14 +3468,196 @@ packages: resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} engines: {node: '>=4'} + pkg-types@1.2.0: + resolution: {integrity: sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==} + possible-typed-array-names@1.0.0: resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} engines: {node: '>= 0.4'} + postcss-calc@10.0.2: + resolution: {integrity: sha512-DT/Wwm6fCKgpYVI7ZEWuPJ4az8hiEHtCUeYjZXqU7Ou4QqYh1Df2yCQ7Ca6N7xqKPFkxN3fhf+u9KSoOCJNAjg==} + engines: {node: ^18.12 || ^20.9 || >=22.0} + peerDependencies: + postcss: ^8.4.38 + + postcss-colormin@7.0.2: + resolution: {integrity: sha512-YntRXNngcvEvDbEjTdRWGU606eZvB5prmHG4BF0yLmVpamXbpsRJzevyy6MZVyuecgzI2AWAlvFi8DAeCqwpvA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-convert-values@7.0.4: + resolution: {integrity: sha512-e2LSXPqEHVW6aoGbjV9RsSSNDO3A0rZLCBxN24zvxF25WknMPpX8Dm9UxxThyEbaytzggRuZxaGXqaOhxQ514Q==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-comments@7.0.3: + resolution: {integrity: sha512-q6fjd4WU4afNhWOA2WltHgCbkRhZPgQe7cXF74fuVB/ge4QbM9HEaOIzGSiMvM+g/cOsNAUGdf2JDzqA2F8iLA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-duplicates@7.0.1: + resolution: {integrity: sha512-oZA+v8Jkpu1ct/xbbrntHRsfLGuzoP+cpt0nJe5ED2FQF8n8bJtn7Bo28jSmBYwqgqnqkuSXJfSUEE7if4nClQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-empty@7.0.0: + resolution: {integrity: sha512-e+QzoReTZ8IAwhnSdp/++7gBZ/F+nBq9y6PomfwORfP7q9nBpK5AMP64kOt0bA+lShBFbBDcgpJ3X4etHg4lzA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-overridden@7.0.0: + resolution: {integrity: sha512-GmNAzx88u3k2+sBTZrJSDauR0ccpE24omTQCVmaTTZFz1du6AasspjaUPMJ2ud4RslZpoFKyf+6MSPETLojc6w==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-merge-longhand@7.0.4: + resolution: {integrity: sha512-zer1KoZA54Q8RVHKOY5vMke0cCdNxMP3KBfDerjH/BYHh4nCIh+1Yy0t1pAEQF18ac/4z3OFclO+ZVH8azjR4A==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-merge-rules@7.0.4: + resolution: {integrity: sha512-ZsaamiMVu7uBYsIdGtKJ64PkcQt6Pcpep/uO90EpLS3dxJi6OXamIobTYcImyXGoW0Wpugh7DSD3XzxZS9JCPg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-font-values@7.0.0: + resolution: {integrity: sha512-2ckkZtgT0zG8SMc5aoNwtm5234eUx1GGFJKf2b1bSp8UflqaeFzR50lid4PfqVI9NtGqJ2J4Y7fwvnP/u1cQog==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-gradients@7.0.0: + resolution: {integrity: sha512-pdUIIdj/C93ryCHew0UgBnL2DtUS3hfFa5XtERrs4x+hmpMYGhbzo6l/Ir5de41O0GaKVpK1ZbDNXSY6GkXvtg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-params@7.0.2: + resolution: {integrity: sha512-nyqVLu4MFl9df32zTsdcLqCFfE/z2+f8GE1KHPxWOAmegSo6lpV2GNy5XQvrzwbLmiU7d+fYay4cwto1oNdAaQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-selectors@7.0.4: + resolution: {integrity: sha512-JG55VADcNb4xFCf75hXkzc1rNeURhlo7ugf6JjiiKRfMsKlDzN9CXHZDyiG6x/zGchpjQS+UAgb1d4nqXqOpmA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-normalize-charset@7.0.0: + resolution: {integrity: sha512-ABisNUXMeZeDNzCQxPxBCkXexvBrUHV+p7/BXOY+ulxkcjUZO0cp8ekGBwvIh2LbCwnWbyMPNJVtBSdyhM2zYQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-display-values@7.0.0: + resolution: {integrity: sha512-lnFZzNPeDf5uGMPYgGOw7v0BfB45+irSRz9gHQStdkkhiM0gTfvWkWB5BMxpn0OqgOQuZG/mRlZyJxp0EImr2Q==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-positions@7.0.0: + resolution: {integrity: sha512-I0yt8wX529UKIGs2y/9Ybs2CelSvItfmvg/DBIjTnoUSrPxSV7Z0yZ8ShSVtKNaV/wAY+m7bgtyVQLhB00A1NQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-repeat-style@7.0.0: + resolution: {integrity: sha512-o3uSGYH+2q30ieM3ppu9GTjSXIzOrRdCUn8UOMGNw7Af61bmurHTWI87hRybrP6xDHvOe5WlAj3XzN6vEO8jLw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-string@7.0.0: + resolution: {integrity: sha512-w/qzL212DFVOpMy3UGyxrND+Kb0fvCiBBujiaONIihq7VvtC7bswjWgKQU/w4VcRyDD8gpfqUiBQ4DUOwEJ6Qg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-timing-functions@7.0.0: + resolution: {integrity: sha512-tNgw3YV0LYoRwg43N3lTe3AEWZ66W7Dh7lVEpJbHoKOuHc1sLrzMLMFjP8SNULHaykzsonUEDbKedv8C+7ej6g==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-unicode@7.0.2: + resolution: {integrity: sha512-ztisabK5C/+ZWBdYC+Y9JCkp3M9qBv/XFvDtSw0d/XwfT3UaKeW/YTm/MD/QrPNxuecia46vkfEhewjwcYFjkg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-url@7.0.0: + resolution: {integrity: sha512-+d7+PpE+jyPX1hDQZYG+NaFD+Nd2ris6r8fPTBAjE8z/U41n/bib3vze8x7rKs5H1uEw5ppe9IojewouHk0klQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-whitespace@7.0.0: + resolution: {integrity: sha512-37/toN4wwZErqohedXYqWgvcHUGlT8O/m2jVkAfAe9Bd4MzRqlBmXrJRePH0e9Wgnz2X7KymTgTOaaFizQe3AQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-ordered-values@7.0.1: + resolution: {integrity: sha512-irWScWRL6nRzYmBOXReIKch75RRhNS86UPUAxXdmW/l0FcAsg0lvAXQCby/1lymxn/o0gVa6Rv/0f03eJOwHxw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-reduce-initial@7.0.2: + resolution: {integrity: sha512-pOnu9zqQww7dEKf62Nuju6JgsW2V0KRNBHxeKohU+JkHd/GAH5uvoObqFLqkeB2n20mr6yrlWDvo5UBU5GnkfA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-reduce-transforms@7.0.0: + resolution: {integrity: sha512-pnt1HKKZ07/idH8cpATX/ujMbtOGhUfE+m8gbqwJE05aTaNw8gbo34a2e3if0xc0dlu75sUOiqvwCGY3fzOHew==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-svgo@7.0.1: + resolution: {integrity: sha512-0WBUlSL4lhD9rA5k1e5D8EN5wCEyZD6HJk0jIvRxl+FDVOMlJ7DePHYWGGVc5QRqrJ3/06FTXM0bxjmJpmTPSA==} + engines: {node: ^18.12.0 || ^20.9.0 || >= 18} + peerDependencies: + postcss: ^8.4.31 + + postcss-unique-selectors@7.0.3: + resolution: {integrity: sha512-J+58u5Ic5T1QjP/LDV9g3Cx4CNOgB5vz+kM6+OxHHhFACdcDeKhBXjQmB7fnIZM12YSTvsL0Opwco83DmacW2g==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + postcss@8.4.39: resolution: {integrity: sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==} engines: {node: ^10 || ^12 || >=14} + postcss@8.4.45: + resolution: {integrity: sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==} + engines: {node: ^10 || ^12 || >=14} + prebuild-install@7.1.2: resolution: {integrity: sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==} engines: {node: '>=10'} @@ -2892,6 +3695,10 @@ packages: engines: {node: '>=14'} hasBin: true + pretty-bytes@6.1.1: + resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} + engines: {node: ^14.13.1 || >=16.0.0} + pretty-format@26.6.2: resolution: {integrity: sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==} engines: {node: '>= 10'} @@ -3022,6 +3829,18 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true + rollup-plugin-dts@6.1.1: + resolution: {integrity: sha512-aSHRcJ6KG2IHIioYlvAOcEq6U99sVtqDDKVhnwt70rW6tsz3tv5OSjEiWcgzfsHdLyGXZ/3b/7b/+Za3Y6r1XA==} + engines: {node: '>=16'} + peerDependencies: + rollup: ^3.29.4 || ^4 + typescript: ^4.5 || ^5.0 + + rollup@3.29.4: + resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} @@ -3052,6 +3871,9 @@ packages: sax@1.4.1: resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + scule@1.3.0: + resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -3065,6 +3887,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + sentence-case@3.0.4: resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==} @@ -3140,6 +3967,10 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + slash@4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + slice-ansi@5.0.0: resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} engines: {node: '>=12'} @@ -3259,6 +4090,12 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + stylehacks@7.0.4: + resolution: {integrity: sha512-i4zfNrGMt9SB4xRK9L83rlsFCgdGANfeDAYacO1pkqcE7cRHPdWHwnKZVz7WY17Veq/FvyYsRAU++Ga+qDFIww==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -3279,6 +4116,11 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + svgo@3.3.2: + resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==} + engines: {node: '>=14.0.0'} + hasBin: true + swagger2openapi@7.0.8: resolution: {integrity: sha512-upi/0ZGkYgEcLeGieoz8gT74oWHA0E7JivX7aN9mAf+Tc7BQoRBvnIGHoPDw+f9TXTW4s6kGYCZJtauP6OYp7g==} hasBin: true @@ -3343,6 +4185,9 @@ packages: tslib@2.6.3: resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + tsx@4.16.2: resolution: {integrity: sha512-C1uWweJDgdtX2x600HjaFaucXTilT7tgUZHbOE4+ypskZ1OP8CRCSDkCxG6Vya9EwaFIVagWwpaVAn5wzypaqQ==} engines: {node: '>=18.0.0'} @@ -3395,9 +4240,17 @@ packages: engines: {node: '>=14.17'} hasBin: true + typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + engines: {node: '>=14.17'} + hasBin: true + uc.micro@1.0.6: resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} + ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + uglify-js@3.18.0: resolution: {integrity: sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==} engines: {node: '>=0.8.0'} @@ -3406,6 +4259,15 @@ packages: unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + unbuild@2.0.0: + resolution: {integrity: sha512-JWCUYx3Oxdzvw2J9kTAp+DKE8df/BnH/JTSj6JyA4SH40ECdFu7FoJJcrm8G92B7TjofQ6GZGjJs50TRxoH6Wg==} + hasBin: true + peerDependencies: + typescript: ^5.1.6 + peerDependenciesMeta: + typescript: + optional: true + underscore@1.13.6: resolution: {integrity: sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==} @@ -3420,6 +4282,16 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} + untyped@1.4.2: + resolution: {integrity: sha512-nC5q0DnPEPVURPhfPQLahhSTnemVtPzdx7ofiRxXpOB2SYnb3MfdU3DVGyJdS8Lx+tBWeAePO8BfU/3EgksM7Q==} + hasBin: true + + update-browserslist-db@1.1.0: + resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + upper-case-first@2.0.2: resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==} @@ -3527,6 +4399,9 @@ packages: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} @@ -3596,6 +4471,11 @@ snapshots: '@alova/shared@1.0.4': {} + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + '@azure/abort-controller@1.1.0': dependencies: tslib: 2.6.3 @@ -3684,10 +4564,80 @@ snapshots: '@babel/highlight': 7.24.7 picocolors: 1.0.1 + '@babel/compat-data@7.25.4': {} + + '@babel/core@7.25.2': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.25.6 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helpers': 7.25.6 + '@babel/parser': 7.25.6 + '@babel/template': 7.25.0 + '@babel/traverse': 7.25.6 + '@babel/types': 7.25.6 + convert-source-map: 2.0.0 + debug: 4.3.5 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.25.6': + dependencies: + '@babel/types': 7.25.6 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 2.5.2 + + '@babel/helper-compilation-targets@7.25.2': + dependencies: + '@babel/compat-data': 7.25.4 + '@babel/helper-validator-option': 7.24.8 + browserslist: 4.23.3 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-module-imports@7.24.7': + dependencies: + '@babel/traverse': 7.25.6 + '@babel/types': 7.25.6 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-simple-access': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + '@babel/traverse': 7.25.6 + transitivePeerDependencies: + - supports-color + + '@babel/helper-simple-access@7.24.7': + dependencies: + '@babel/traverse': 7.25.6 + '@babel/types': 7.25.6 + transitivePeerDependencies: + - supports-color + '@babel/helper-string-parser@7.24.7': {} + '@babel/helper-string-parser@7.24.8': {} + '@babel/helper-validator-identifier@7.24.7': {} + '@babel/helper-validator-option@7.24.8': {} + + '@babel/helpers@7.25.6': + dependencies: + '@babel/template': 7.25.0 + '@babel/types': 7.25.6 + '@babel/highlight@7.24.7': dependencies: '@babel/helper-validator-identifier': 7.24.7 @@ -3699,23 +4649,53 @@ snapshots: dependencies: '@babel/types': 7.24.7 + '@babel/parser@7.25.6': + dependencies: + '@babel/types': 7.25.6 + '@babel/runtime@7.24.7': dependencies: regenerator-runtime: 0.14.1 + '@babel/standalone@7.25.6': {} + + '@babel/template@7.25.0': + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/parser': 7.25.6 + '@babel/types': 7.25.6 + + '@babel/traverse@7.25.6': + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.25.6 + '@babel/parser': 7.25.6 + '@babel/template': 7.25.0 + '@babel/types': 7.25.6 + debug: 4.3.5 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + '@babel/types@7.24.7': dependencies: '@babel/helper-string-parser': 7.24.7 '@babel/helper-validator-identifier': 7.24.7 to-fast-properties: 2.0.0 + '@babel/types@7.25.6': + dependencies: + '@babel/helper-string-parser': 7.24.8 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 + '@bcoe/v8-coverage@0.2.3': {} - '@commitlint/cli@19.3.0(@types/node@18.19.34)(typescript@5.4.5)': + '@commitlint/cli@19.3.0(@types/node@18.19.34)(typescript@5.5.4)': dependencies: '@commitlint/format': 19.3.0 '@commitlint/lint': 19.2.2 - '@commitlint/load': 19.2.0(@types/node@18.19.34)(typescript@5.4.5) + '@commitlint/load': 19.2.0(@types/node@18.19.34)(typescript@5.5.4) '@commitlint/read': 19.2.1 '@commitlint/types': 19.0.3 execa: 8.0.1 @@ -3762,15 +4742,15 @@ snapshots: '@commitlint/rules': 19.0.3 '@commitlint/types': 19.0.3 - '@commitlint/load@19.2.0(@types/node@18.19.34)(typescript@5.4.5)': + '@commitlint/load@19.2.0(@types/node@18.19.34)(typescript@5.5.4)': dependencies: '@commitlint/config-validator': 19.0.3 '@commitlint/execute-rule': 19.0.0 '@commitlint/resolve-extends': 19.1.0 '@commitlint/types': 19.0.3 chalk: 5.3.0 - cosmiconfig: 9.0.0(typescript@5.4.5) - cosmiconfig-typescript-loader: 5.0.0(@types/node@18.19.34)(cosmiconfig@9.0.0(typescript@5.4.5))(typescript@5.4.5) + cosmiconfig: 9.0.0(typescript@5.5.4) + cosmiconfig-typescript-loader: 5.0.0(@types/node@18.19.34)(cosmiconfig@9.0.0(typescript@5.5.4))(typescript@5.5.4) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -3822,127 +4802,253 @@ snapshots: '@types/conventional-commits-parser': 5.0.0 chalk: 5.3.0 + '@esbuild/aix-ppc64@0.19.12': + optional: true + '@esbuild/aix-ppc64@0.21.5': optional: true '@esbuild/aix-ppc64@0.23.0': optional: true + '@esbuild/aix-ppc64@0.23.1': + optional: true + + '@esbuild/android-arm64@0.19.12': + optional: true + '@esbuild/android-arm64@0.21.5': optional: true '@esbuild/android-arm64@0.23.0': optional: true + '@esbuild/android-arm64@0.23.1': + optional: true + + '@esbuild/android-arm@0.19.12': + optional: true + '@esbuild/android-arm@0.21.5': optional: true '@esbuild/android-arm@0.23.0': optional: true + '@esbuild/android-arm@0.23.1': + optional: true + + '@esbuild/android-x64@0.19.12': + optional: true + '@esbuild/android-x64@0.21.5': optional: true '@esbuild/android-x64@0.23.0': optional: true + '@esbuild/android-x64@0.23.1': + optional: true + + '@esbuild/darwin-arm64@0.19.12': + optional: true + '@esbuild/darwin-arm64@0.21.5': optional: true '@esbuild/darwin-arm64@0.23.0': optional: true + '@esbuild/darwin-arm64@0.23.1': + optional: true + + '@esbuild/darwin-x64@0.19.12': + optional: true + '@esbuild/darwin-x64@0.21.5': optional: true '@esbuild/darwin-x64@0.23.0': optional: true + '@esbuild/darwin-x64@0.23.1': + optional: true + + '@esbuild/freebsd-arm64@0.19.12': + optional: true + '@esbuild/freebsd-arm64@0.21.5': optional: true '@esbuild/freebsd-arm64@0.23.0': optional: true + '@esbuild/freebsd-arm64@0.23.1': + optional: true + + '@esbuild/freebsd-x64@0.19.12': + optional: true + '@esbuild/freebsd-x64@0.21.5': optional: true '@esbuild/freebsd-x64@0.23.0': optional: true + '@esbuild/freebsd-x64@0.23.1': + optional: true + + '@esbuild/linux-arm64@0.19.12': + optional: true + '@esbuild/linux-arm64@0.21.5': optional: true '@esbuild/linux-arm64@0.23.0': optional: true + '@esbuild/linux-arm64@0.23.1': + optional: true + + '@esbuild/linux-arm@0.19.12': + optional: true + '@esbuild/linux-arm@0.21.5': optional: true '@esbuild/linux-arm@0.23.0': optional: true + '@esbuild/linux-arm@0.23.1': + optional: true + + '@esbuild/linux-ia32@0.19.12': + optional: true + '@esbuild/linux-ia32@0.21.5': optional: true '@esbuild/linux-ia32@0.23.0': optional: true + '@esbuild/linux-ia32@0.23.1': + optional: true + + '@esbuild/linux-loong64@0.19.12': + optional: true + '@esbuild/linux-loong64@0.21.5': optional: true '@esbuild/linux-loong64@0.23.0': optional: true + '@esbuild/linux-loong64@0.23.1': + optional: true + + '@esbuild/linux-mips64el@0.19.12': + optional: true + '@esbuild/linux-mips64el@0.21.5': optional: true '@esbuild/linux-mips64el@0.23.0': optional: true + '@esbuild/linux-mips64el@0.23.1': + optional: true + + '@esbuild/linux-ppc64@0.19.12': + optional: true + '@esbuild/linux-ppc64@0.21.5': optional: true '@esbuild/linux-ppc64@0.23.0': optional: true + '@esbuild/linux-ppc64@0.23.1': + optional: true + + '@esbuild/linux-riscv64@0.19.12': + optional: true + '@esbuild/linux-riscv64@0.21.5': optional: true '@esbuild/linux-riscv64@0.23.0': optional: true + '@esbuild/linux-riscv64@0.23.1': + optional: true + + '@esbuild/linux-s390x@0.19.12': + optional: true + '@esbuild/linux-s390x@0.21.5': optional: true '@esbuild/linux-s390x@0.23.0': optional: true + '@esbuild/linux-s390x@0.23.1': + optional: true + + '@esbuild/linux-x64@0.19.12': + optional: true + '@esbuild/linux-x64@0.21.5': optional: true '@esbuild/linux-x64@0.23.0': optional: true + '@esbuild/linux-x64@0.23.1': + optional: true + + '@esbuild/netbsd-x64@0.19.12': + optional: true + '@esbuild/netbsd-x64@0.21.5': optional: true '@esbuild/netbsd-x64@0.23.0': optional: true + '@esbuild/netbsd-x64@0.23.1': + optional: true + '@esbuild/openbsd-arm64@0.23.0': optional: true + '@esbuild/openbsd-arm64@0.23.1': + optional: true + + '@esbuild/openbsd-x64@0.19.12': + optional: true + '@esbuild/openbsd-x64@0.21.5': optional: true '@esbuild/openbsd-x64@0.23.0': optional: true - '@esbuild/sunos-x64@0.21.5': + '@esbuild/openbsd-x64@0.23.1': + optional: true + + '@esbuild/sunos-x64@0.19.12': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.23.0': + optional: true + + '@esbuild/sunos-x64@0.23.1': optional: true - '@esbuild/sunos-x64@0.23.0': + '@esbuild/win32-arm64@0.19.12': optional: true '@esbuild/win32-arm64@0.21.5': @@ -3951,18 +5057,33 @@ snapshots: '@esbuild/win32-arm64@0.23.0': optional: true + '@esbuild/win32-arm64@0.23.1': + optional: true + + '@esbuild/win32-ia32@0.19.12': + optional: true + '@esbuild/win32-ia32@0.21.5': optional: true '@esbuild/win32-ia32@0.23.0': optional: true + '@esbuild/win32-ia32@0.23.1': + optional: true + + '@esbuild/win32-x64@0.19.12': + optional: true + '@esbuild/win32-x64@0.21.5': optional: true '@esbuild/win32-x64@0.23.0': optional: true + '@esbuild/win32-x64@0.23.1': + optional: true + '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)': dependencies: eslint: 8.57.0 @@ -4019,8 +5140,16 @@ snapshots: '@types/yargs': 15.0.19 chalk: 4.1.2 + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/resolve-uri@3.1.2': {} + '@jridgewell/set-array@1.2.1': {} + '@jridgewell/sourcemap-codec@1.4.15': {} '@jridgewell/trace-mapping@0.3.25': @@ -4045,10 +5174,68 @@ snapshots: '@pkgr/core@0.1.1': {} + '@rollup/plugin-alias@5.1.0(rollup@3.29.4)': + dependencies: + slash: 4.0.0 + optionalDependencies: + rollup: 3.29.4 + + '@rollup/plugin-commonjs@25.0.8(rollup@3.29.4)': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@3.29.4) + commondir: 1.0.1 + estree-walker: 2.0.2 + glob: 8.1.0 + is-reference: 1.2.1 + magic-string: 0.30.10 + optionalDependencies: + rollup: 3.29.4 + + '@rollup/plugin-json@6.1.0(rollup@3.29.4)': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@3.29.4) + optionalDependencies: + rollup: 3.29.4 + + '@rollup/plugin-node-resolve@15.2.3(rollup@3.29.4)': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@3.29.4) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-builtin-module: 3.2.1 + is-module: 1.0.0 + resolve: 1.22.8 + optionalDependencies: + rollup: 3.29.4 + + '@rollup/plugin-replace@5.0.7(rollup@3.29.4)': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@3.29.4) + magic-string: 0.30.10 + optionalDependencies: + rollup: 3.29.4 + + '@rollup/pluginutils@5.1.0(rollup@3.29.4)': + dependencies: + '@types/estree': 1.0.5 + estree-walker: 2.0.2 + picomatch: 2.3.1 + optionalDependencies: + rollup: 3.29.4 + + '@trysound/sax@0.2.0': {} + '@types/conventional-commits-parser@5.0.0': dependencies: '@types/node': 18.19.34 + '@types/estree@1.0.5': {} + + '@types/fs-extra@11.0.4': + dependencies: + '@types/jsonfile': 6.1.4 + '@types/node': 18.19.34 + '@types/istanbul-lib-coverage@2.0.6': {} '@types/istanbul-lib-report@3.0.3': @@ -4068,6 +5255,10 @@ snapshots: '@types/json5@0.0.29': {} + '@types/jsonfile@6.1.4': + dependencies: + '@types/node': 18.19.34 + '@types/lodash@4.17.5': {} '@types/mocha@10.0.6': {} @@ -4083,6 +5274,8 @@ snapshots: '@types/parse-json@4.0.2': {} + '@types/resolve@1.20.2': {} + '@types/serialize-javascript@5.0.4': {} '@types/swagger2openapi@7.0.4': @@ -4098,34 +5291,34 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/eslint-plugin@7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)': dependencies: '@eslint-community/regexpp': 4.10.1 - '@typescript-eslint/parser': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.13.0(eslint@8.57.0)(typescript@5.5.4) '@typescript-eslint/scope-manager': 7.13.0 - '@typescript-eslint/type-utils': 7.13.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/utils': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/type-utils': 7.13.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 7.13.0(eslint@8.57.0)(typescript@5.5.4) '@typescript-eslint/visitor-keys': 7.13.0 eslint: 8.57.0 graphemer: 1.4.0 ignore: 5.3.1 natural-compare: 1.4.0 - ts-api-utils: 1.3.0(typescript@5.4.5) + ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: - typescript: 5.4.5 + typescript: 5.5.4 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4)': dependencies: '@typescript-eslint/scope-manager': 7.13.0 '@typescript-eslint/types': 7.13.0 - '@typescript-eslint/typescript-estree': 7.13.0(typescript@5.4.5) + '@typescript-eslint/typescript-estree': 7.13.0(typescript@5.5.4) '@typescript-eslint/visitor-keys': 7.13.0 debug: 4.3.5 eslint: 8.57.0 optionalDependencies: - typescript: 5.4.5 + typescript: 5.5.4 transitivePeerDependencies: - supports-color @@ -4134,21 +5327,21 @@ snapshots: '@typescript-eslint/types': 7.13.0 '@typescript-eslint/visitor-keys': 7.13.0 - '@typescript-eslint/type-utils@7.13.0(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/type-utils@7.13.0(eslint@8.57.0)(typescript@5.5.4)': dependencies: - '@typescript-eslint/typescript-estree': 7.13.0(typescript@5.4.5) - '@typescript-eslint/utils': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/typescript-estree': 7.13.0(typescript@5.5.4) + '@typescript-eslint/utils': 7.13.0(eslint@8.57.0)(typescript@5.5.4) debug: 4.3.5 eslint: 8.57.0 - ts-api-utils: 1.3.0(typescript@5.4.5) + ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: - typescript: 5.4.5 + typescript: 5.5.4 transitivePeerDependencies: - supports-color '@typescript-eslint/types@7.13.0': {} - '@typescript-eslint/typescript-estree@7.13.0(typescript@5.4.5)': + '@typescript-eslint/typescript-estree@7.13.0(typescript@5.5.4)': dependencies: '@typescript-eslint/types': 7.13.0 '@typescript-eslint/visitor-keys': 7.13.0 @@ -4157,18 +5350,18 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.4 semver: 7.6.2 - ts-api-utils: 1.3.0(typescript@5.4.5) + ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: - typescript: 5.4.5 + typescript: 5.5.4 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@7.13.0(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/utils@7.13.0(eslint@8.57.0)(typescript@5.5.4)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@typescript-eslint/scope-manager': 7.13.0 '@typescript-eslint/types': 7.13.0 - '@typescript-eslint/typescript-estree': 7.13.0(typescript@5.4.5) + '@typescript-eslint/typescript-estree': 7.13.0(typescript@5.5.4) eslint: 8.57.0 transitivePeerDependencies: - supports-color @@ -4325,6 +5518,12 @@ snapshots: '@vue/shared': 3.4.31 vue: 3.4.31(typescript@5.4.5) + '@vue/server-renderer@3.4.31(vue@3.4.31(typescript@5.5.4))': + dependencies: + '@vue/compiler-ssr': 3.4.31 + '@vue/shared': 3.4.31 + vue: 3.4.31(typescript@5.5.4) + '@vue/shared@3.4.31': {} JSONStream@1.3.5: @@ -4488,6 +5687,16 @@ snapshots: at-least-node@1.0.0: {} + autoprefixer@10.4.20(postcss@8.4.45): + dependencies: + browserslist: 4.23.3 + caniuse-lite: 1.0.30001658 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.0.1 + postcss: 8.4.45 + postcss-value-parser: 4.2.0 + available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.0.0 @@ -4538,6 +5747,13 @@ snapshots: browser-stdout@1.3.1: {} + browserslist@4.23.3: + dependencies: + caniuse-lite: 1.0.30001658 + electron-to-chromium: 1.5.16 + node-releases: 2.0.18 + update-browserslist-db: 1.1.0(browserslist@4.23.3) + buffer-crc32@0.2.13: {} buffer-equal-constant-time@1.0.1: {} @@ -4552,6 +5768,8 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 + builtin-modules@3.3.0: {} + c8@9.1.0: dependencies: '@bcoe/v8-coverage': 0.2.3 @@ -4587,6 +5805,15 @@ snapshots: camelcase@6.3.0: {} + caniuse-api@3.0.0: + dependencies: + browserslist: 4.23.3 + caniuse-lite: 1.0.30001658 + lodash.memoize: 4.1.2 + lodash.uniq: 4.5.0 + + caniuse-lite@1.0.30001658: {} + capital-case@1.0.4: dependencies: no-case: 3.0.4 @@ -4669,6 +5896,10 @@ snapshots: chownr@1.1.4: optional: true + citty@0.1.6: + dependencies: + consola: 3.2.3 + cli-cursor@3.1.0: dependencies: restore-cursor: 3.1.0 @@ -4714,6 +5945,8 @@ snapshots: color-name@1.1.4: {} + colord@2.9.3: {} + colorette@2.0.20: {} combined-stream@1.0.8: @@ -4724,10 +5957,12 @@ snapshots: commander@6.2.1: {} - commitizen@4.3.0(@types/node@18.19.34)(typescript@5.4.5): + commander@7.2.0: {} + + commitizen@4.3.0(@types/node@18.19.34)(typescript@5.5.4): dependencies: cachedir: 2.3.0 - cz-conventional-changelog: 3.3.0(@types/node@18.19.34)(typescript@5.4.5) + cz-conventional-changelog: 3.3.0(@types/node@18.19.34)(typescript@5.5.4) dedent: 0.7.0 detect-indent: 6.1.0 find-node-modules: 2.1.3 @@ -4744,6 +5979,8 @@ snapshots: - '@types/node' - typescript + commondir@1.0.1: {} + compare-func@2.0.0: dependencies: array-ify: 1.0.0 @@ -4751,8 +5988,12 @@ snapshots: concat-map@0.0.1: {} + confbox@0.1.7: {} + confusing-browser-globals@1.0.11: {} + consola@3.2.3: {} + constant-case@3.0.4: dependencies: no-case: 3.0.4 @@ -4780,12 +6021,12 @@ snapshots: core-util-is@1.0.3: {} - cosmiconfig-typescript-loader@5.0.0(@types/node@18.19.34)(cosmiconfig@9.0.0(typescript@5.4.5))(typescript@5.4.5): + cosmiconfig-typescript-loader@5.0.0(@types/node@18.19.34)(cosmiconfig@9.0.0(typescript@5.5.4))(typescript@5.5.4): dependencies: '@types/node': 18.19.34 - cosmiconfig: 9.0.0(typescript@5.4.5) + cosmiconfig: 9.0.0(typescript@5.5.4) jiti: 1.21.6 - typescript: 5.4.5 + typescript: 5.5.4 cosmiconfig@6.0.0: dependencies: @@ -4795,14 +6036,14 @@ snapshots: path-type: 4.0.0 yaml: 1.10.2 - cosmiconfig@9.0.0(typescript@5.4.5): + cosmiconfig@9.0.0(typescript@5.5.4): dependencies: env-paths: 2.2.1 import-fresh: 3.3.0 js-yaml: 4.1.0 parse-json: 5.2.0 optionalDependencies: - typescript: 5.4.5 + typescript: 5.5.4 cross-spawn@6.0.5: dependencies: @@ -4818,6 +6059,10 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + css-declaration-sorter@7.2.0(postcss@8.4.45): + dependencies: + postcss: 8.4.45 + css-select@5.1.0: dependencies: boolbase: 1.0.0 @@ -4826,20 +6071,80 @@ snapshots: domutils: 3.1.0 nth-check: 2.1.1 + css-tree@2.2.1: + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.2.0 + + css-tree@2.3.1: + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.2.0 + css-what@6.1.0: {} + cssesc@3.0.0: {} + + cssnano-preset-default@7.0.6(postcss@8.4.45): + dependencies: + browserslist: 4.23.3 + css-declaration-sorter: 7.2.0(postcss@8.4.45) + cssnano-utils: 5.0.0(postcss@8.4.45) + postcss: 8.4.45 + postcss-calc: 10.0.2(postcss@8.4.45) + postcss-colormin: 7.0.2(postcss@8.4.45) + postcss-convert-values: 7.0.4(postcss@8.4.45) + postcss-discard-comments: 7.0.3(postcss@8.4.45) + postcss-discard-duplicates: 7.0.1(postcss@8.4.45) + postcss-discard-empty: 7.0.0(postcss@8.4.45) + postcss-discard-overridden: 7.0.0(postcss@8.4.45) + postcss-merge-longhand: 7.0.4(postcss@8.4.45) + postcss-merge-rules: 7.0.4(postcss@8.4.45) + postcss-minify-font-values: 7.0.0(postcss@8.4.45) + postcss-minify-gradients: 7.0.0(postcss@8.4.45) + postcss-minify-params: 7.0.2(postcss@8.4.45) + postcss-minify-selectors: 7.0.4(postcss@8.4.45) + postcss-normalize-charset: 7.0.0(postcss@8.4.45) + postcss-normalize-display-values: 7.0.0(postcss@8.4.45) + postcss-normalize-positions: 7.0.0(postcss@8.4.45) + postcss-normalize-repeat-style: 7.0.0(postcss@8.4.45) + postcss-normalize-string: 7.0.0(postcss@8.4.45) + postcss-normalize-timing-functions: 7.0.0(postcss@8.4.45) + postcss-normalize-unicode: 7.0.2(postcss@8.4.45) + postcss-normalize-url: 7.0.0(postcss@8.4.45) + postcss-normalize-whitespace: 7.0.0(postcss@8.4.45) + postcss-ordered-values: 7.0.1(postcss@8.4.45) + postcss-reduce-initial: 7.0.2(postcss@8.4.45) + postcss-reduce-transforms: 7.0.0(postcss@8.4.45) + postcss-svgo: 7.0.1(postcss@8.4.45) + postcss-unique-selectors: 7.0.3(postcss@8.4.45) + + cssnano-utils@5.0.0(postcss@8.4.45): + dependencies: + postcss: 8.4.45 + + cssnano@7.0.6(postcss@8.4.45): + dependencies: + cssnano-preset-default: 7.0.6(postcss@8.4.45) + lilconfig: 3.1.2 + postcss: 8.4.45 + + csso@5.0.5: + dependencies: + css-tree: 2.2.1 + csstype@3.1.3: {} - cz-conventional-changelog@3.3.0(@types/node@18.19.34)(typescript@5.4.5): + cz-conventional-changelog@3.3.0(@types/node@18.19.34)(typescript@5.5.4): dependencies: chalk: 2.4.2 - commitizen: 4.3.0(@types/node@18.19.34)(typescript@5.4.5) + commitizen: 4.3.0(@types/node@18.19.34)(typescript@5.5.4) conventional-commit-types: 3.0.0 lodash.map: 4.6.0 longest: 2.0.1 word-wrap: 1.2.5 optionalDependencies: - '@commitlint/load': 19.2.0(@types/node@18.19.34)(typescript@5.4.5) + '@commitlint/load': 19.2.0(@types/node@18.19.34)(typescript@5.5.4) transitivePeerDependencies: - '@types/node' - typescript @@ -4894,6 +6199,8 @@ snapshots: deep-is@0.1.4: {} + deepmerge@4.3.1: {} + defaults@1.0.4: dependencies: clone: 1.0.4 @@ -4912,6 +6219,8 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 + defu@6.1.4: {} + delayed-stream@1.0.0: {} dequal@2.0.3: {} @@ -4972,6 +6281,8 @@ snapshots: dependencies: safe-buffer: 5.2.1 + electron-to-chromium@1.5.16: {} + emoji-regex@10.3.0: {} emoji-regex@8.0.0: {} @@ -5094,6 +6405,32 @@ snapshots: esbuild-plugin-alias@0.2.1: {} + esbuild@0.19.12: + optionalDependencies: + '@esbuild/aix-ppc64': 0.19.12 + '@esbuild/android-arm': 0.19.12 + '@esbuild/android-arm64': 0.19.12 + '@esbuild/android-x64': 0.19.12 + '@esbuild/darwin-arm64': 0.19.12 + '@esbuild/darwin-x64': 0.19.12 + '@esbuild/freebsd-arm64': 0.19.12 + '@esbuild/freebsd-x64': 0.19.12 + '@esbuild/linux-arm': 0.19.12 + '@esbuild/linux-arm64': 0.19.12 + '@esbuild/linux-ia32': 0.19.12 + '@esbuild/linux-loong64': 0.19.12 + '@esbuild/linux-mips64el': 0.19.12 + '@esbuild/linux-ppc64': 0.19.12 + '@esbuild/linux-riscv64': 0.19.12 + '@esbuild/linux-s390x': 0.19.12 + '@esbuild/linux-x64': 0.19.12 + '@esbuild/netbsd-x64': 0.19.12 + '@esbuild/openbsd-x64': 0.19.12 + '@esbuild/sunos-x64': 0.19.12 + '@esbuild/win32-arm64': 0.19.12 + '@esbuild/win32-ia32': 0.19.12 + '@esbuild/win32-x64': 0.19.12 + esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 @@ -5147,35 +6484,62 @@ snapshots: '@esbuild/win32-ia32': 0.23.0 '@esbuild/win32-x64': 0.23.0 + esbuild@0.23.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.23.1 + '@esbuild/android-arm': 0.23.1 + '@esbuild/android-arm64': 0.23.1 + '@esbuild/android-x64': 0.23.1 + '@esbuild/darwin-arm64': 0.23.1 + '@esbuild/darwin-x64': 0.23.1 + '@esbuild/freebsd-arm64': 0.23.1 + '@esbuild/freebsd-x64': 0.23.1 + '@esbuild/linux-arm': 0.23.1 + '@esbuild/linux-arm64': 0.23.1 + '@esbuild/linux-ia32': 0.23.1 + '@esbuild/linux-loong64': 0.23.1 + '@esbuild/linux-mips64el': 0.23.1 + '@esbuild/linux-ppc64': 0.23.1 + '@esbuild/linux-riscv64': 0.23.1 + '@esbuild/linux-s390x': 0.23.1 + '@esbuild/linux-x64': 0.23.1 + '@esbuild/netbsd-x64': 0.23.1 + '@esbuild/openbsd-arm64': 0.23.1 + '@esbuild/openbsd-x64': 0.23.1 + '@esbuild/sunos-x64': 0.23.1 + '@esbuild/win32-arm64': 0.23.1 + '@esbuild/win32-ia32': 0.23.1 + '@esbuild/win32-x64': 0.23.1 + escalade@3.1.2: {} escape-string-regexp@1.0.5: {} escape-string-regexp@4.0.0: {} - eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0): + eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0))(eslint@8.57.0): dependencies: confusing-browser-globals: 1.0.11 eslint: 8.57.0 - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0) object.assign: 4.1.5 object.entries: 1.1.8 semver: 6.3.1 - eslint-config-airbnb-typescript@18.0.0(@typescript-eslint/eslint-plugin@7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0): + eslint-config-airbnb-typescript@18.0.0(@typescript-eslint/eslint-plugin@7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4))(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0))(eslint@8.57.0): dependencies: - '@typescript-eslint/eslint-plugin': 7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/parser': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/eslint-plugin': 7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/parser': 7.13.0(eslint@8.57.0)(typescript@5.5.4) eslint: 8.57.0 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0))(eslint@8.57.0) transitivePeerDependencies: - eslint-plugin-import - eslint-config-airbnb@19.0.4(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react@7.34.2(eslint@8.57.0))(eslint@8.57.0): + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react@7.34.2(eslint@8.57.0))(eslint@8.57.0): dependencies: eslint: 8.57.0 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0) eslint-plugin-react: 7.34.2(eslint@8.57.0) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) @@ -5185,6 +6549,7 @@ snapshots: eslint-config-prettier@9.1.0(eslint@8.57.0): dependencies: eslint: 8.57.0 + optional: true eslint-import-resolver-node@0.3.9: dependencies: @@ -5194,17 +6559,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.13.0(eslint@8.57.0)(typescript@5.5.4) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0): dependencies: array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 @@ -5214,7 +6579,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -5225,7 +6590,7 @@ snapshots: semver: 6.3.1 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.13.0(eslint@8.57.0)(typescript@5.5.4) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -5475,9 +6840,17 @@ snapshots: combined-stream: 1.0.8 mime-types: 2.1.35 + fraction.js@4.3.7: {} + fs-constants@1.0.0: optional: true + fs-extra@11.2.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + fs-extra@9.1.0: dependencies: at-least-node: 1.0.0 @@ -5501,6 +6874,8 @@ snapshots: functions-have-names@1.2.3: {} + gensync@1.0.0-beta.2: {} + get-caller-file@2.0.5: {} get-east-asian-width@1.2.0: {} @@ -5585,6 +6960,8 @@ snapshots: is-windows: 1.0.2 which: 1.3.1 + globals@11.12.0: {} + globals@13.24.0: dependencies: type-fest: 0.20.2 @@ -5603,6 +6980,14 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 + globby@13.2.2: + dependencies: + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.1 + merge2: 1.4.1 + slash: 4.0.0 + gopd@1.0.1: dependencies: get-intrinsic: 1.2.4 @@ -5653,6 +7038,8 @@ snapshots: dependencies: parse-passwd: 1.0.0 + hookable@5.5.3: {} + hosted-git-info@2.8.9: {} hosted-git-info@4.1.0: @@ -5766,6 +7153,10 @@ snapshots: call-bind: 1.0.7 has-tostringtag: 1.0.2 + is-builtin-module@3.2.1: + dependencies: + builtin-modules: 3.3.0 + is-callable@1.2.7: {} is-core-module@2.13.1: @@ -5810,6 +7201,8 @@ snapshots: is-map@2.0.3: {} + is-module@1.0.0: {} + is-negative-zero@2.0.3: {} is-number-object@1.0.7: @@ -5824,6 +7217,10 @@ snapshots: is-plain-obj@2.1.0: {} + is-reference@1.2.1: + dependencies: + '@types/estree': 1.0.5 + is-regex@1.1.4: dependencies: call-bind: 1.0.7 @@ -5933,6 +7330,8 @@ snapshots: dependencies: argparse: 2.0.1 + jsesc@2.5.2: {} + json-buffer@3.0.1: {} json-parse-better-errors@1.0.2: {} @@ -5949,6 +7348,8 @@ snapshots: dependencies: minimist: 1.2.8 + json5@2.2.3: {} + jsonc-parser@3.3.1: {} jsonfile@6.1.0: @@ -6100,6 +7501,8 @@ snapshots: lodash.map@4.6.0: {} + lodash.memoize@4.1.2: {} + lodash.merge@4.6.2: {} lodash.mergewith@4.6.2: {} @@ -6146,6 +7549,10 @@ snapshots: lru-cache@10.2.2: {} + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + lru-cache@6.0.0: dependencies: yallist: 4.0.0 @@ -6166,6 +7573,10 @@ snapshots: mdurl: 1.0.1 uc.micro: 1.0.6 + mdn-data@2.0.28: {} + + mdn-data@2.0.30: {} + mdurl@1.0.1: {} memorystream@0.3.1: {} @@ -6219,6 +7630,31 @@ snapshots: mkdirp-classic@0.5.3: optional: true + mkdist@1.5.5(typescript@5.5.4): + dependencies: + autoprefixer: 10.4.20(postcss@8.4.45) + citty: 0.1.6 + cssnano: 7.0.6(postcss@8.4.45) + defu: 6.1.4 + esbuild: 0.23.1 + fast-glob: 3.3.2 + jiti: 1.21.6 + mlly: 1.7.1 + pathe: 1.1.2 + pkg-types: 1.2.0 + postcss: 8.4.45 + postcss-nested: 6.2.0(postcss@8.4.45) + semver: 7.6.3 + optionalDependencies: + typescript: 5.5.4 + + mlly@1.7.1: + dependencies: + acorn: 8.11.3 + pathe: 1.1.2 + pkg-types: 1.2.0 + ufo: 1.5.4 + mocha@10.4.0: dependencies: ansi-colors: 4.1.1 @@ -6242,6 +7678,8 @@ snapshots: yargs-parser: 20.2.4 yargs-unparser: 2.0.0 + mri@1.2.0: {} + ms@2.1.2: {} ms@2.1.3: {} @@ -6284,6 +7722,8 @@ snapshots: dependencies: es6-promise: 3.3.1 + node-releases@2.0.18: {} + normalize-package-data@2.5.0: dependencies: hosted-git-info: 2.8.9 @@ -6293,6 +7733,8 @@ snapshots: normalize-path@3.0.0: {} + normalize-range@0.1.2: {} + npm-run-all@4.1.5: dependencies: ansi-styles: 3.2.1 @@ -6548,6 +7990,8 @@ snapshots: path-type@4.0.0: {} + pathe@1.1.2: {} + pend@1.2.0: {} picocolors@1.0.1: {} @@ -6560,14 +8004,187 @@ snapshots: pify@3.0.0: {} + pkg-types@1.2.0: + dependencies: + confbox: 0.1.7 + mlly: 1.7.1 + pathe: 1.1.2 + possible-typed-array-names@1.0.0: {} + postcss-calc@10.0.2(postcss@8.4.45): + dependencies: + postcss: 8.4.45 + postcss-selector-parser: 6.1.2 + postcss-value-parser: 4.2.0 + + postcss-colormin@7.0.2(postcss@8.4.45): + dependencies: + browserslist: 4.23.3 + caniuse-api: 3.0.0 + colord: 2.9.3 + postcss: 8.4.45 + postcss-value-parser: 4.2.0 + + postcss-convert-values@7.0.4(postcss@8.4.45): + dependencies: + browserslist: 4.23.3 + postcss: 8.4.45 + postcss-value-parser: 4.2.0 + + postcss-discard-comments@7.0.3(postcss@8.4.45): + dependencies: + postcss: 8.4.45 + postcss-selector-parser: 6.1.2 + + postcss-discard-duplicates@7.0.1(postcss@8.4.45): + dependencies: + postcss: 8.4.45 + + postcss-discard-empty@7.0.0(postcss@8.4.45): + dependencies: + postcss: 8.4.45 + + postcss-discard-overridden@7.0.0(postcss@8.4.45): + dependencies: + postcss: 8.4.45 + + postcss-merge-longhand@7.0.4(postcss@8.4.45): + dependencies: + postcss: 8.4.45 + postcss-value-parser: 4.2.0 + stylehacks: 7.0.4(postcss@8.4.45) + + postcss-merge-rules@7.0.4(postcss@8.4.45): + dependencies: + browserslist: 4.23.3 + caniuse-api: 3.0.0 + cssnano-utils: 5.0.0(postcss@8.4.45) + postcss: 8.4.45 + postcss-selector-parser: 6.1.2 + + postcss-minify-font-values@7.0.0(postcss@8.4.45): + dependencies: + postcss: 8.4.45 + postcss-value-parser: 4.2.0 + + postcss-minify-gradients@7.0.0(postcss@8.4.45): + dependencies: + colord: 2.9.3 + cssnano-utils: 5.0.0(postcss@8.4.45) + postcss: 8.4.45 + postcss-value-parser: 4.2.0 + + postcss-minify-params@7.0.2(postcss@8.4.45): + dependencies: + browserslist: 4.23.3 + cssnano-utils: 5.0.0(postcss@8.4.45) + postcss: 8.4.45 + postcss-value-parser: 4.2.0 + + postcss-minify-selectors@7.0.4(postcss@8.4.45): + dependencies: + cssesc: 3.0.0 + postcss: 8.4.45 + postcss-selector-parser: 6.1.2 + + postcss-nested@6.2.0(postcss@8.4.45): + dependencies: + postcss: 8.4.45 + postcss-selector-parser: 6.1.2 + + postcss-normalize-charset@7.0.0(postcss@8.4.45): + dependencies: + postcss: 8.4.45 + + postcss-normalize-display-values@7.0.0(postcss@8.4.45): + dependencies: + postcss: 8.4.45 + postcss-value-parser: 4.2.0 + + postcss-normalize-positions@7.0.0(postcss@8.4.45): + dependencies: + postcss: 8.4.45 + postcss-value-parser: 4.2.0 + + postcss-normalize-repeat-style@7.0.0(postcss@8.4.45): + dependencies: + postcss: 8.4.45 + postcss-value-parser: 4.2.0 + + postcss-normalize-string@7.0.0(postcss@8.4.45): + dependencies: + postcss: 8.4.45 + postcss-value-parser: 4.2.0 + + postcss-normalize-timing-functions@7.0.0(postcss@8.4.45): + dependencies: + postcss: 8.4.45 + postcss-value-parser: 4.2.0 + + postcss-normalize-unicode@7.0.2(postcss@8.4.45): + dependencies: + browserslist: 4.23.3 + postcss: 8.4.45 + postcss-value-parser: 4.2.0 + + postcss-normalize-url@7.0.0(postcss@8.4.45): + dependencies: + postcss: 8.4.45 + postcss-value-parser: 4.2.0 + + postcss-normalize-whitespace@7.0.0(postcss@8.4.45): + dependencies: + postcss: 8.4.45 + postcss-value-parser: 4.2.0 + + postcss-ordered-values@7.0.1(postcss@8.4.45): + dependencies: + cssnano-utils: 5.0.0(postcss@8.4.45) + postcss: 8.4.45 + postcss-value-parser: 4.2.0 + + postcss-reduce-initial@7.0.2(postcss@8.4.45): + dependencies: + browserslist: 4.23.3 + caniuse-api: 3.0.0 + postcss: 8.4.45 + + postcss-reduce-transforms@7.0.0(postcss@8.4.45): + dependencies: + postcss: 8.4.45 + postcss-value-parser: 4.2.0 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-svgo@7.0.1(postcss@8.4.45): + dependencies: + postcss: 8.4.45 + postcss-value-parser: 4.2.0 + svgo: 3.3.2 + + postcss-unique-selectors@7.0.3(postcss@8.4.45): + dependencies: + postcss: 8.4.45 + postcss-selector-parser: 6.1.2 + + postcss-value-parser@4.2.0: {} + postcss@8.4.39: dependencies: nanoid: 3.3.7 picocolors: 1.0.1 source-map-js: 1.2.0 + postcss@8.4.45: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + prebuild-install@7.1.2: dependencies: detect-libc: 2.0.3 @@ -6590,10 +8207,10 @@ snapshots: dependencies: fast-diff: 1.3.0 - prettier-plugin-organize-imports@3.2.4(prettier@3.3.2)(typescript@5.4.5): + prettier-plugin-organize-imports@3.2.4(prettier@3.3.2)(typescript@5.5.4): dependencies: prettier: 3.3.2 - typescript: 5.4.5 + typescript: 5.5.4 prettier-plugin-sort-json@4.0.0(prettier@3.3.2): dependencies: @@ -6601,6 +8218,8 @@ snapshots: prettier@3.3.2: {} + pretty-bytes@6.1.1: {} + pretty-format@26.6.2: dependencies: '@jest/types': 26.6.2 @@ -6748,6 +8367,18 @@ snapshots: dependencies: glob: 7.2.3 + rollup-plugin-dts@6.1.1(rollup@3.29.4)(typescript@5.5.4): + dependencies: + magic-string: 0.30.10 + rollup: 3.29.4 + typescript: 5.5.4 + optionalDependencies: + '@babel/code-frame': 7.24.7 + + rollup@3.29.4: + optionalDependencies: + fsevents: 2.3.3 + run-async@2.4.1: {} run-parallel@1.2.0: @@ -6756,7 +8387,7 @@ snapshots: rxjs@7.8.1: dependencies: - tslib: 2.6.3 + tslib: 2.7.0 safe-array-concat@1.1.2: dependencies: @@ -6779,12 +8410,16 @@ snapshots: sax@1.4.1: {} + scule@1.3.0: {} + semver@5.7.2: {} semver@6.3.1: {} semver@7.6.2: {} + semver@7.6.3: {} + sentence-case@3.0.4: dependencies: no-case: 3.0.4 @@ -6876,6 +8511,8 @@ snapshots: slash@3.0.0: {} + slash@4.0.0: {} + slice-ansi@5.0.0: dependencies: ansi-styles: 6.2.1 @@ -7013,6 +8650,12 @@ snapshots: strip-json-comments@3.1.1: {} + stylehacks@7.0.4(postcss@8.4.45): + dependencies: + browserslist: 4.23.3 + postcss: 8.4.45 + postcss-selector-parser: 6.1.2 + supports-color@5.5.0: dependencies: has-flag: 3.0.0 @@ -7029,6 +8672,16 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + svgo@3.3.2: + dependencies: + '@trysound/sax': 0.2.0 + commander: 7.2.0 + css-select: 5.1.0 + css-tree: 2.3.1 + css-what: 6.1.0 + csso: 5.0.5 + picocolors: 1.0.1 + swagger2openapi@7.0.8: dependencies: call-me-maybe: 1.0.2 @@ -7048,7 +8701,7 @@ snapshots: synckit@0.8.8: dependencies: '@pkgr/core': 0.1.1 - tslib: 2.6.3 + tslib: 2.7.0 tapable@2.2.1: {} @@ -7095,9 +8748,9 @@ snapshots: tr46@0.0.3: {} - ts-api-utils@1.3.0(typescript@5.4.5): + ts-api-utils@1.3.0(typescript@5.5.4): dependencies: - typescript: 5.4.5 + typescript: 5.5.4 tsconfig-paths@3.15.0: dependencies: @@ -7108,6 +8761,8 @@ snapshots: tslib@2.6.3: {} + tslib@2.7.0: {} + tsx@4.16.2: dependencies: esbuild: 0.21.5 @@ -7172,8 +8827,12 @@ snapshots: typescript@5.4.5: {} + typescript@5.5.4: {} + uc.micro@1.0.6: {} + ufo@1.5.4: {} + uglify-js@3.18.0: optional: true @@ -7184,6 +8843,39 @@ snapshots: has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 + unbuild@2.0.0(typescript@5.5.4): + dependencies: + '@rollup/plugin-alias': 5.1.0(rollup@3.29.4) + '@rollup/plugin-commonjs': 25.0.8(rollup@3.29.4) + '@rollup/plugin-json': 6.1.0(rollup@3.29.4) + '@rollup/plugin-node-resolve': 15.2.3(rollup@3.29.4) + '@rollup/plugin-replace': 5.0.7(rollup@3.29.4) + '@rollup/pluginutils': 5.1.0(rollup@3.29.4) + chalk: 5.3.0 + citty: 0.1.6 + consola: 3.2.3 + defu: 6.1.4 + esbuild: 0.19.12 + globby: 13.2.2 + hookable: 5.5.3 + jiti: 1.21.6 + magic-string: 0.30.10 + mkdist: 1.5.5(typescript@5.5.4) + mlly: 1.7.1 + pathe: 1.1.2 + pkg-types: 1.2.0 + pretty-bytes: 6.1.1 + rollup: 3.29.4 + rollup-plugin-dts: 6.1.1(rollup@3.29.4)(typescript@5.5.4) + scule: 1.3.0 + untyped: 1.4.2 + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - sass + - supports-color + - vue-tsc + underscore@1.13.6: {} undici-types@5.26.5: {} @@ -7192,6 +8884,24 @@ snapshots: universalify@2.0.1: {} + untyped@1.4.2: + dependencies: + '@babel/core': 7.25.2 + '@babel/standalone': 7.25.6 + '@babel/types': 7.24.7 + defu: 6.1.4 + jiti: 1.21.6 + mri: 1.2.0 + scule: 1.3.0 + transitivePeerDependencies: + - supports-color + + update-browserslist-db@1.1.0(browserslist@4.23.3): + dependencies: + browserslist: 4.23.3 + escalade: 3.1.2 + picocolors: 1.0.1 + upper-case-first@2.0.2: dependencies: tslib: 2.6.3 @@ -7236,6 +8946,16 @@ snapshots: optionalDependencies: typescript: 5.4.5 + vue@3.4.31(typescript@5.5.4): + dependencies: + '@vue/compiler-dom': 3.4.31 + '@vue/compiler-sfc': 3.4.31 + '@vue/runtime-dom': 3.4.31 + '@vue/server-renderer': 3.4.31(vue@3.4.31(typescript@5.5.4)) + '@vue/shared': 3.4.31 + optionalDependencies: + typescript: 5.5.4 + wcwidth@1.0.1: dependencies: defaults: 1.0.4 @@ -7328,6 +9048,8 @@ snapshots: y18n@5.0.8: {} + yallist@3.1.1: {} + yallist@4.0.0: {} yaml@1.10.2: {} diff --git a/tsconfig.base.json b/tsconfig.base.json index 2b3f5bc..7ec6acb 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1,31 +1,30 @@ -{ - "compilerOptions": { - "baseUrl": ".", - "resolveJsonModule": true, - "target": "es2018", - "module": "esnext", - "moduleResolution": "bundler", - "strict": true, - "newLine": "LF", - "noImplicitAny": true, - "noEmitOnError": false, - "noUnusedLocals": true, - "noUnusedParameters": false, - "allowUnreachableCode": false, - "allowUnusedLabels": false, - "strictPropertyInitialization": false, - "noFallthroughCasesInSwitch": false, - "skipLibCheck": true, - "allowJs": true, - "skipDefaultLibCheck": false, - "inlineSourceMap": false, - "importHelpers": true, - "removeComments": false, - "esModuleInterop": true, - "jsx": "preserve", - "paths": { - "#/*": ["./*"], - "@alova/*": ["./packages/src/*"] - } - } -} +{ + "compilerOptions": { + "resolveJsonModule": true, + "target": "es2018", + "module": "esnext", + "moduleResolution": "bundler", + "strict": true, + "newLine": "LF", + "noImplicitAny": true, + "noEmitOnError": false, + "noUnusedLocals": true, + "noUnusedParameters": false, + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "strictPropertyInitialization": false, + "noFallthroughCasesInSwitch": false, + "skipLibCheck": true, + "allowJs": true, + "skipDefaultLibCheck": false, + "esModuleInterop": true, + "inlineSourceMap": false, + "importHelpers": true, + "removeComments": false, + "jsx": "preserve", + "paths": { + "#/*": ["./*"], + "@alova/*": ["./packages/src/*"] + } + } +} diff --git a/tsconfig.json b/tsconfig.json index 7f224ec..3336c16 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,8 +1,8 @@ -{ - "extends": "./tsconfig.base.json", - "exclude": ["design/**", "test/**"], - "compilerOptions": { - "outDir": "./dist" - }, - "include": ["packages/**/*.ts", "*.*js", "*.*ts", "scripts/**.*", "typings/**/*.d.ts"] -} +{ + "extends": "./tsconfig.base.json", + "exclude": ["design/**", "test/**"], + "compilerOptions": { + "outDir": "./dist" + }, + "include": ["*.*js", "packages/**/*.ts", "*.*ts", "scripts/**.*", "typings/**/*.d.ts"] +} From afc602eeab39112ebf526b48c4f1f02287c88ef8 Mon Sep 17 00:00:00 2001 From: czhlin <2324133088@qq.com> Date: Sat, 7 Sep 2024 11:44:06 +0800 Subject: [PATCH 15/47] =?UTF-8?q?build(wormhole):=20=E4=BF=AE=E6=94=B9worm?= =?UTF-8?q?hole=E7=9A=84=E6=89=93=E5=8C=85=E9=85=8D=E7=BD=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- packages/vscode-extension/.vscode/tasks.json | 14 +- packages/vscode-extension/package.json | 161 +++++++++--------- packages/wormhole/build.config.ts | 39 ++++- packages/wormhole/package.json | 12 +- packages/wormhole/src/config.ts | 2 +- packages/wormhole/src/generate.ts | 2 +- .../wormhole/src/modules/Configuration.ts | 2 +- packages/wormhole/src/utils/index.ts | 5 - pnpm-lock.yaml | 33 +++- 10 files changed, 158 insertions(+), 114 deletions(-) diff --git a/package.json b/package.json index 8d740ab..5422b96 100644 --- a/package.json +++ b/package.json @@ -47,8 +47,8 @@ "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^18.0.0", "eslint-plugin-prettier": "^5.1.3", + "fast-glob": "^3.3.2", "husky": "^9.0.11", - "js-yaml": "^4.1.0", "lint-staged": "^15.2.2", "npm-run-all": "^4.1.5", "prettier": "^3.2.5", diff --git a/packages/vscode-extension/.vscode/tasks.json b/packages/vscode-extension/.vscode/tasks.json index 725ab2a..e6d85fe 100644 --- a/packages/vscode-extension/.vscode/tasks.json +++ b/packages/vscode-extension/.vscode/tasks.json @@ -5,7 +5,7 @@ "tasks": [ { "label": "watch", - "dependsOn": ["npm: watch:tsc", "npm: watch:esbuild"], + "dependsOn": ["npm: watch:esbuild"], "presentation": { "reveal": "never" }, @@ -26,18 +26,6 @@ "reveal": "never" } }, - { - "type": "npm", - "script": "watch:tsc", - "group": "build", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "label": "npm: watch:tsc", - "presentation": { - "group": "watch", - "reveal": "never" - } - }, { "type": "npm", "script": "watch-tests", diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index 5616064..94eb17e 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -1,81 +1,80 @@ -{ - "name": "alova-vscode-extension", - "displayName": "Alova", - "description": "Generate and search APIs without API documentation any more", - "version": "0.0.10", - "engines": { - "vscode": "^1.89.0", - "node": ">=18.19.0", - "pnpm": ">=8.6.12" - }, - "categories": [ - "Other" - ], - "activationEvents": [ - "workspaceContains:**/*.ts", - "workspaceContains:**/*.js" - ], - "main": "./out/extension.js", - "icon": "resources/icon.png", - "contributes": { - "commands": [ - { - "command": "alova.refresh", - "category": "Alova", - "title": "Generate APIs" - }, - { - "command": "alova.create.config", - "category": "Alova", - "title": "Create alova config" - } - ], - "icons": { - "alova-icon-id": { - "description": "alova icon", - "default": { - "fontPath": "./resources/logo.ttf", - "fontCharacter": "\\E900" - } - } - } - }, - "scripts": { - "vscode:prepublish": "pnpm run package", - "compile": "pnpm run check-types && pnpm run lint:fix && tsx esbuild.ts", - "watch": "npm-run-all -p watch:*", - "watch:esbuild": "tsx esbuild.ts --watch", - "watch:tsc": "tsc --noEmit --watch --project tsconfig.json", - "package": "pnpm run check-types && pnpm run lint:fix && tsx esbuild.ts --production", - "compile-tests": "tsc -p . --outDir out", - "watch-tests": "tsc -p . -w --outDir out", - "pretest": "pnpm run compile-tests && pnpm run compile && pnpm run lint", - "check-types": "tsc --noEmit", - "lint": "eslint . --ext .js,.ts", - "lint:fix": "npm run lint -- --fix", - "format": "prettier --check .", - "format:fix": "prettier --write .", - "test": "vscode-test", - "pack:pre": "vsce package --no-dependencies --pre-release", - "release:pre": "vsce publish --no-dependencies --pre-release", - "pack": "vsce package --no-dependencies", - "release": "vsce publish --no-dependencies" - }, - "publisher": "Alova", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/alovajs/devtools.git" - }, - "bugs": { - "url": "https://github.com/alovajs/devtools/issues" - }, - "devDependencies": { - "@types/vscode": "^1.89.0", - "@vscode/test-cli": "^0.0.9", - "@vscode/test-electron": "^2.3.9", - "@vscode/vsce": "^2.29.0", - "esbuild": "^0.23.0", - "esbuild-plugin-alias": "^0.2.1" - } -} +{ + "name": "alova-vscode-extension", + "displayName": "Alova", + "description": "Generate and search APIs without API documentation any more", + "version": "0.0.10", + "engines": { + "vscode": "^1.89.0", + "node": ">=18.19.0", + "pnpm": ">=8.6.12" + }, + "categories": [ + "Other" + ], + "activationEvents": [ + "workspaceContains:**/*.ts", + "workspaceContains:**/*.js" + ], + "main": "./out/extension.js", + "icon": "resources/icon.png", + "contributes": { + "commands": [ + { + "command": "alova.refresh", + "category": "Alova", + "title": "Generate APIs" + }, + { + "command": "alova.create.config", + "category": "Alova", + "title": "Create alova config" + } + ], + "icons": { + "alova-icon-id": { + "description": "alova icon", + "default": { + "fontPath": "./resources/logo.ttf", + "fontCharacter": "\\E900" + } + } + } + }, + "scripts": { + "vscode:prepublish": "pnpm run package", + "compile": "pnpm run check-types && pnpm run lint:fix && tsx esbuild.ts", + "watch": "npm-run-all -p watch:*", + "watch:esbuild": "tsx esbuild.ts --watch", + "package": "pnpm run check-types && pnpm run lint:fix && tsx esbuild.ts --production", + "compile-tests": "tsc -p . --outDir out", + "watch-tests": "tsc -p . -w --outDir out", + "pretest": "pnpm run compile-tests && pnpm run compile && pnpm run lint", + "check-types": "tsc --noEmit", + "lint": "eslint . --ext .js,.ts", + "lint:fix": "npm run lint -- --fix", + "format": "prettier --check .", + "format:fix": "prettier --write .", + "test": "vscode-test", + "pack:pre": "vsce package --no-dependencies --pre-release", + "release:pre": "vsce publish --no-dependencies --pre-release", + "pack": "vsce package --no-dependencies", + "release": "vsce publish --no-dependencies" + }, + "publisher": "Alova", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/alovajs/devtools.git" + }, + "bugs": { + "url": "https://github.com/alovajs/devtools/issues" + }, + "devDependencies": { + "@types/vscode": "^1.89.0", + "@vscode/test-cli": "^0.0.9", + "@vscode/test-electron": "^2.3.9", + "@vscode/vsce": "^2.29.0", + "esbuild": "^0.23.0", + "esbuild-plugin-alias": "^0.2.1" + } +} diff --git a/packages/wormhole/build.config.ts b/packages/wormhole/build.config.ts index 077e660..028f911 100644 --- a/packages/wormhole/build.config.ts +++ b/packages/wormhole/build.config.ts @@ -1,4 +1,7 @@ +import fglob from 'fast-glob'; +import fs from 'node:fs'; import path from 'node:path'; +import url from 'node:url'; import { defineBuildConfig } from 'unbuild'; export default defineBuildConfig({ @@ -7,20 +10,44 @@ export default defineBuildConfig({ declaration: true, failOnWarn: false, hooks: { - 'build:done': async () => { + 'build:done': async ctx => { + // fix:stub mode jiti path `file:///` + // https://github.com/unjs/unbuild/issues/248 + if (ctx.options.stub) { + fglob.sync('./dist/**/*.*js', { onlyFiles: true }).forEach(fileUrl => { + const filePath = path.resolve(__dirname, fileUrl); + fs.readFile(filePath, (err, data) => { + if (err) { + return err; + } + const str = data + .toString() + .replace(/file:\/\/\/(.+)/g, subStr => + path.relative(path.resolve(filePath, '..'), url.fileURLToPath(subStr)).replace(/\\/g, '/') + ); + fs.writeFile(filePath, str, err => { + if (err) { + return err; + } + }); + }); + }); + } // copy all things under src/templates to dist/templates // https://github.com/unjs/unbuild/issues/266 const { copy } = await import('fs-extra'); await copy('src/templates', 'dist/templates'); } }, + alias: { + '@': path.resolve(__dirname, './src'), + '~': path.resolve(__dirname, './typings'), + '#': path.join(__dirname) + }, + externals: ['typescript'], rollup: { alias: { - entries: { - '@': path.resolve(__dirname, './src'), - '~': path.resolve(__dirname, './typings'), - '#': path.join(__dirname) - } + entries: {} }, dts: { respectExternal: false diff --git a/packages/wormhole/package.json b/packages/wormhole/package.json index fae0e6d..f7ea531 100644 --- a/packages/wormhole/package.json +++ b/packages/wormhole/package.json @@ -23,9 +23,17 @@ "license": "ISC", "devDependencies": { "@types/fs-extra": "^11.0.4", - "unbuild": "^2.0.0" + "unbuild": "^2.0.0", + "openapi-types": "^12.1.3", + "fs-extra": "^11.2.0" }, "dependencies": { - "fs-extra": "^11.2.0" + "cosmiconfig": "^9.0.0", + "handlebars": "^4.7.8", + "import-fresh": "^3.3.0", + "lodash": "^4.17.21", + "node-fetch": "^2.7.0", + "js-yaml": "^4.1.0", + "swagger2openapi": "^7.0.8" } } diff --git a/packages/wormhole/src/config.ts b/packages/wormhole/src/config.ts index 134348a..c8125aa 100644 --- a/packages/wormhole/src/config.ts +++ b/packages/wormhole/src/config.ts @@ -4,7 +4,7 @@ import type { TemplateData } from './functions/openApi2Data'; export const TEMPLATE_DATA = new Map(); export const DEFAULT_CONFIG = { alovaTempPath: path.join('node_modules/.alova'), - templatePath: path.join(__dirname, '../../templates'), + templatePath: path.join(__dirname, './templates'), log: (...messageArr: any[]) => console.log(...messageArr), getTypescript: async () => { let ts: typeof import('typescript') | null = null; diff --git a/packages/wormhole/src/generate.ts b/packages/wormhole/src/generate.ts index 3a98b4b..ab8a6da 100644 --- a/packages/wormhole/src/generate.ts +++ b/packages/wormhole/src/generate.ts @@ -2,7 +2,7 @@ import type { Config, GenerateApiOptions } from '~/index'; import generateApi from './functions/generateApi'; import Configuration from './modules/Configuration'; -export const generate = async (config: Config, options?: GenerateApiOptions) => { +export const generate = async (config: Config, options?: GenerateApiOptions): Promise => { if (!config) { return; } diff --git a/packages/wormhole/src/modules/Configuration.ts b/packages/wormhole/src/modules/Configuration.ts index 3841f6c..982e7e9 100644 --- a/packages/wormhole/src/modules/Configuration.ts +++ b/packages/wormhole/src/modules/Configuration.ts @@ -89,7 +89,7 @@ export default class Configuration { return this.config.generator.map(generator => Configuration.getTemplateType(this.workspaceRootDir, generator)); } - getAllOutputPath() { + getAllOutputPath(): string[] { return this.config.generator.map(generator => generator.output); } diff --git a/packages/wormhole/src/utils/index.ts b/packages/wormhole/src/utils/index.ts index 196dd64..fae6e8f 100644 --- a/packages/wormhole/src/utils/index.ts +++ b/packages/wormhole/src/utils/index.ts @@ -129,11 +129,6 @@ export function removeUndefined(obj: T) { }, defaultObject) as T; } -// 反序列化 -export function deserialize(serializedJavascript: string) { - // eslint-disable-next-line no-eval - return eval(`(${serializedJavascript})`); -} export function isEmpty(value: any) { return value === null || value === undefined || value === ''; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1190d2d..39f8c1e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -84,6 +84,9 @@ importers: eslint-plugin-prettier: specifier: ^5.1.3 version: 5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.2) + fast-glob: + specifier: ^3.3.2 + version: 3.3.2 husky: specifier: ^9.0.11 version: 9.0.11 @@ -141,13 +144,37 @@ importers: packages/wormhole: dependencies: - fs-extra: - specifier: ^11.2.0 - version: 11.2.0 + cosmiconfig: + specifier: ^9.0.0 + version: 9.0.0(typescript@5.5.4) + handlebars: + specifier: ^4.7.8 + version: 4.7.8 + import-fresh: + specifier: ^3.3.0 + version: 3.3.0 + js-yaml: + specifier: ^4.1.0 + version: 4.1.0 + lodash: + specifier: ^4.17.21 + version: 4.17.21 + node-fetch: + specifier: ^2.7.0 + version: 2.7.0 + swagger2openapi: + specifier: ^7.0.8 + version: 7.0.8 devDependencies: '@types/fs-extra': specifier: ^11.0.4 version: 11.0.4 + fs-extra: + specifier: ^11.2.0 + version: 11.2.0 + openapi-types: + specifier: ^12.1.3 + version: 12.1.3 unbuild: specifier: ^2.0.0 version: 2.0.0(typescript@5.5.4) From 988bd1adee6a7e09a908b60b1e4c1e335bcb6ae9 Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Mon, 9 Sep 2024 17:06:20 +0800 Subject: [PATCH 16/47] =?UTF-8?q?fix(wormhole/openapi2data):=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8DhandleApi=E4=BF=AE=E6=94=B9=E6=97=B6unkown=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 同时优化了mergeObject方法,处理嵌套结构时,可以最大程度复用 --- .npmrc | 6 --- .../wormhole/src/functions/openApi2Data.ts | 19 ++++--- packages/wormhole/src/helper/openapi.ts | 52 ++++++++++++++++++- pnpm-lock.yaml | 3 -- 4 files changed, 62 insertions(+), 18 deletions(-) diff --git a/.npmrc b/.npmrc index a91159e..e69de29 100644 --- a/.npmrc +++ b/.npmrc @@ -1,6 +0,0 @@ -enable-pre-post-scripts = true -link-workspace-packages = true -prefer-workspace-packages = true -recursive-install = true -# 使用淘宝镜像源 -registry = https://registry.npmmirror.com \ No newline at end of file diff --git a/packages/wormhole/src/functions/openApi2Data.ts b/packages/wormhole/src/functions/openApi2Data.ts index bb4dfbc..3869248 100644 --- a/packages/wormhole/src/functions/openApi2Data.ts +++ b/packages/wormhole/src/functions/openApi2Data.ts @@ -4,7 +4,7 @@ import { convertToType, jsonSchema2TsStr } from '@/helper/schema2type'; import { getStandardOperationId, getStandardTags } from '@/helper/standard'; import { generateDefaultValues } from '@/helper/typeStr'; import { format, removeUndefined } from '@/utils'; -import { cloneDeep } from 'lodash'; +import { cloneDeep, isEmpty } from 'lodash'; import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'; import type { ApiDescriptor, GeneratorConfig, TemplateType } from '~/index'; import { AlovaVersion } from './getAlovaVersion'; @@ -161,6 +161,7 @@ const parseRequestBody = async ( }; const getContentKey = (content: Record, requireKey: string, defaultKey = 'application/json') => { let key = Object.keys(content ?? {})[0]; + requireKey = requireKey ?? defaultKey; if (requireKey && content?.[requireKey]) { key = requireKey; } @@ -250,13 +251,14 @@ export const transformPathObj = async ( method: string, pathObjOrigin: OpenAPIV3_1.OperationObject, openApi: OpenAPIV3_1.Document, - config: GeneratorConfig + config: GeneratorConfig, + map: Array<[string, any]> ) => { const { handleApi } = config; - const pathObj = cloneDeep(pathObjOrigin); if (!handleApi || typeof handleApi !== 'function') { return { ...pathObjOrigin, url, method }; } + const pathObj = cloneDeep(pathObjOrigin); const { requestBody, responses, parameters } = pathObj; let apiDescriptor: ApiDescriptor = { ...pathObj, @@ -310,7 +312,7 @@ export const transformPathObj = async ( return null; } apiDescriptor = cloneDeep(newApiDescriptor); - if (apiDescriptor.requestBody) { + if (!isEmpty(apiDescriptor.requestBody) || requestBody) { pathObj.requestBody = requestBodyObject || { content: {} }; const { content } = pathObj.requestBody; if (!content[requestKey]) { @@ -318,7 +320,7 @@ export const transformPathObj = async ( } content[requestKey].schema = apiDescriptor.requestBody; } - if (apiDescriptor.responses) { + if (!isEmpty(apiDescriptor.responses) || response200) { if (!pathObj.responses) { pathObj.responses = {}; } @@ -332,7 +334,7 @@ export const transformPathObj = async ( } content[responseKey].schema = apiDescriptor.responses; } - if (apiDescriptor.parameters) { + if (!isEmpty(apiDescriptor.parameters) || parameters) { pathObj.parameters = apiDescriptor.parameters; } delete apiDescriptor.requestBody; @@ -340,7 +342,7 @@ export const transformPathObj = async ( delete apiDescriptor.parameters; Object.assign(pathObj, apiDescriptor); const result = { - ...mergeObject(pathObjOrigin, pathObj, openApi), + ...mergeObject(pathObjOrigin, pathObj, openApi, map), url: apiDescriptor.url, method: apiDescriptor.method }; @@ -368,6 +370,7 @@ export default async function openApi2Data( const searchMap = new Map(); const removeMap = new Map(); const operationIdSet = new Set(); + const pathMap: Array<[string, any]> = []; const paths = openApi.paths || []; for (const [url, pathInfo] of Object.entries(paths)) { if (!pathInfo) { @@ -382,7 +385,7 @@ export default async function openApi2Data( } methodInfoOrigin.operationId = getStandardOperationId(methodInfoOrigin, url, method, operationIdSet); methodInfoOrigin.tags = getStandardTags(methodInfoOrigin.tags); - const newMethodInfo = await transformPathObj(url, method, methodInfoOrigin, openApi, config); + const newMethodInfo = await transformPathObj(url, method, methodInfoOrigin, openApi, config, pathMap); if (!newMethodInfo) { continue; } diff --git a/packages/wormhole/src/helper/openapi.ts b/packages/wormhole/src/helper/openapi.ts index f30d5ff..c4ba06e 100644 --- a/packages/wormhole/src/helper/openapi.ts +++ b/packages/wormhole/src/helper/openapi.ts @@ -202,6 +202,52 @@ function isCircular(obj: any) { return detect(obj); } +function hasBaseReferenceObject(obj: any) { + if (obj && typeof obj === 'object') { + if (isBaseReferenceObject(obj)) { + return true; + } + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + if (hasBaseReferenceObject(obj[key])) { + return true; + } + } + } + } + return false; +} +function removeBaseReference(obj: Record, openApi: OpenAPIV3_1.Document, map: Array<[string, any]>) { + if (isBaseReferenceObject(obj)) { + const refObj = { $ref: obj._$ref }; + if (isEqualObject(obj, refObj, openApi)) { + return refObj; + } + for (const key in obj) { + if (hasBaseReferenceObject(obj[key])) { + obj[key] = removeBaseReference(obj[key], openApi, map); + } + } + const [path] = map.find(([, item]) => isEqualObject(item, obj, openApi)) ?? []; + if (path) { + return { + $ref: path + }; + } + const nextPath = getNext$refKey(refObj.$ref, map); + map.push([nextPath, obj]); + setComponentsBy$ref(nextPath, obj, openApi); + return { + $ref: nextPath + }; + } + for (const key in obj) { + if (hasBaseReferenceObject(obj[key])) { + obj[key] = removeBaseReference(obj[key], openApi, map); + } + } + return obj; +} function unCircular(obj: Record, openApi: OpenAPIV3_1.Document, map: Array<[string, any]>) { if (isBaseReferenceObject(obj)) { const refObj = { $ref: obj._$ref }; @@ -258,9 +304,13 @@ export const mergeObject = ( if (isCircular(srcValue)) { srcValue = unCircular(srcValue, openApi, map); } + // 是否还有_$ref属性 + if (hasBaseReferenceObject(srcValue)) { + return removeBaseReference(srcValue, openApi, map); + } return srcValue; } - return mergeWith(objValue, srcValue, customizer); + return mergeWith(cloneDeep(objValue), srcValue, customizer); }; const refPathMap = new Map(); const refNameSet = new Set(); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 39f8c1e..1851485 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -90,9 +90,6 @@ importers: husky: specifier: ^9.0.11 version: 9.0.11 - js-yaml: - specifier: ^4.1.0 - version: 4.1.0 lint-staged: specifier: ^15.2.2 version: 15.2.7 From 9e2e687cc1da236c207dd751798484193e3de331 Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Mon, 9 Sep 2024 18:57:54 +0800 Subject: [PATCH 17/47] =?UTF-8?q?chore(whormhole):=20=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E9=9C=80=E8=A6=81=E5=AF=BC=E5=87=BA=E7=9A=84=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/functions/autocomplete.ts | 96 +++++++------- packages/vscode-extension/src/globalConfig.ts | 28 ++--- packages/vscode-extension/src/work/config.ts | 17 +-- .../vscode-extension/src/work/generate.ts | 46 +++---- packages/vscode-extension/src/work/getApis.ts | 16 +-- .../vscode-extension/src/work/readConfig.ts | 118 +++++++++--------- packages/wormhole/build.config.ts | 2 +- .../wormhole/src/functions/openApi2Data.ts | 19 +-- packages/wormhole/src/index.ts | 3 - packages/wormhole/src/readConfig.ts | 32 ++++- packages/wormhole/typings/index.d.ts | 18 +++ 11 files changed, 208 insertions(+), 187 deletions(-) diff --git a/packages/vscode-extension/src/functions/autocomplete.ts b/packages/vscode-extension/src/functions/autocomplete.ts index 831b264..c6047ca 100644 --- a/packages/vscode-extension/src/functions/autocomplete.ts +++ b/packages/vscode-extension/src/functions/autocomplete.ts @@ -1,48 +1,48 @@ -import { alovaWork } from '@/helper/work'; -import type { Api } from '@alova/wormhole'; - -type AutoCompleteItem = { - replaceText: string; - summary: string; - documentation?: string; - path: string; - method: string; -}; - -const filterAutoCompleteItem = (text: string, apiArr: Api[]): AutoCompleteItem[] => { - const autoCompleteArr: AutoCompleteItem[] = []; - const filter = (text: string, otherText: string) => otherText.includes(text); - apiArr.forEach(api => { - const replaceText = api.defaultValue ?? ''; - if (filter(text, api.path)) { - autoCompleteArr.push({ - replaceText, - summary: api.path, - path: api.path, - documentation: `${api.summary}\n\`\`\`typescript\n${replaceText}\`\`\``, - method: api.method - }); - } - if (filter(text, api.summary)) { - autoCompleteArr.push({ - replaceText, - summary: api.path, - path: api.summary, - documentation: `${api.summary}\n\`\`\`typescript\n${replaceText}\`\`\``, - method: api.method - }); - } - if (filter(text, `${api.global}.${api.pathKey}`)) { - autoCompleteArr.push({ - replaceText, - summary: api.path, - path: `${api.global}.${api.pathKey}`, - documentation: `${api.summary}\n\`\`\`typescript\n${replaceText}\`\`\``, - method: api.method - }); - } - }); - return autoCompleteArr; -}; -export default async (text: string, filePath: string): Promise => - filterAutoCompleteItem(text, await alovaWork.getApis(filePath)); +import { alovaWork } from '@/helper/work'; +import type { Api } from '@alova/wormhole'; + +type AutoCompleteItem = { + replaceText: string; + summary: string; + documentation?: string; + path: string; + method: string; +}; + +const filterAutoCompleteItem = (text: string, apiArr: Api[]): AutoCompleteItem[] => { + const autoCompleteArr: AutoCompleteItem[] = []; + const filter = (text: string, otherText: string) => otherText.includes(text); + apiArr.forEach(api => { + const replaceText = api.defaultValue ?? ''; + if (filter(text, api.path)) { + autoCompleteArr.push({ + replaceText, + summary: api.path, + path: api.path, + documentation: `${api.summary}\n\`\`\`typescript\n${replaceText}\`\`\``, + method: api.method + }); + } + if (filter(text, api.summary)) { + autoCompleteArr.push({ + replaceText, + summary: api.path, + path: api.summary, + documentation: `${api.summary}\n\`\`\`typescript\n${replaceText}\`\`\``, + method: api.method + }); + } + if (filter(text, `${api.global}.${api.pathKey}`)) { + autoCompleteArr.push({ + replaceText, + summary: api.path, + path: `${api.global}.${api.pathKey}`, + documentation: `${api.summary}\n\`\`\`typescript\n${replaceText}\`\`\``, + method: api.method + }); + } + }); + return autoCompleteArr; +}; +export default async (text: string, filePath: string): Promise => + filterAutoCompleteItem(text, await alovaWork.getApis(filePath)); diff --git a/packages/vscode-extension/src/globalConfig.ts b/packages/vscode-extension/src/globalConfig.ts index e584a23..b0a393b 100644 --- a/packages/vscode-extension/src/globalConfig.ts +++ b/packages/vscode-extension/src/globalConfig.ts @@ -1,14 +1,14 @@ -/* eslint-disable import/prefer-default-export */ -import Error from '@/components/error'; -import { getTypescript, log } from '@/utils/work'; -import { setGlobalConfig } from '@alova/wormhole'; -import path from 'node:path'; -import { pathToFileURL } from 'node:url'; -// work.js线程路径 -export const WORK_PATH = pathToFileURL(path.join(__dirname, '/work.js')); -// 全局配置 -setGlobalConfig({ - log, - getTypescript, - Error -}); +/* eslint-disable import/prefer-default-export */ +import Error from '@/components/error'; +import { getTypescript, log } from '@/utils/work'; +import { setGlobalConfig } from '@alova/wormhole'; +import path from 'node:path'; +import { pathToFileURL } from 'node:url'; +// work.js线程路径 +export const WORK_PATH = pathToFileURL(path.join(__dirname, '/work.js')); +// 全局配置 +setGlobalConfig({ + log, + getTypescript, + Error +}); diff --git a/packages/vscode-extension/src/work/config.ts b/packages/vscode-extension/src/work/config.ts index bb05db3..bc58034 100644 --- a/packages/vscode-extension/src/work/config.ts +++ b/packages/vscode-extension/src/work/config.ts @@ -1,8 +1,9 @@ -import type { Task } from '@/helper/work'; -import type { Configuration } from '@alova/wormhole'; - -export const TASK_MAP = new Map(); -export const CONFIG_POOL: Array = []; -export default { - CONFIG_POOL -}; +import type { Task } from '@/helper/work'; +import type { Config } from '@alova/wormhole'; + +export type ConfigObject = [string, Config]; +export const TASK_MAP = new Map(); +export const CONFIG_POOL: Array = []; +export default { + CONFIG_POOL +}; diff --git a/packages/vscode-extension/src/work/generate.ts b/packages/vscode-extension/src/work/generate.ts index 666c98d..02e72cd 100644 --- a/packages/vscode-extension/src/work/generate.ts +++ b/packages/vscode-extension/src/work/generate.ts @@ -1,23 +1,23 @@ -import { generate } from '@alova/wormhole'; -import { createError } from '../utils/work'; -import { CONFIG_POOL } from './config'; - -export default async (force: boolean) => { - const resultArr = []; - const errorArr = []; - for (const configuration of CONFIG_POOL) { - try { - const generateResult = await generate(configuration.config, { - force, - projectPath: configuration.workspaceRootDir - }); - resultArr.push([configuration.workspaceRootDir, generateResult?.some(item => !!item)]); - } catch (error: any) { - errorArr.push([configuration.workspaceRootDir, createError(error)]); - } - } - return { - resultArr, - errorArr - }; -}; +import { generate } from '@alova/wormhole'; +import { createError } from '@/utils/work'; +import { CONFIG_POOL } from './config'; + +export default async (force: boolean) => { + const resultArr = []; + const errorArr = []; + for (const [projectPath, config] of CONFIG_POOL) { + try { + const generateResult = await generate(config, { + force, + projectPath + }); + resultArr.push([projectPath, generateResult?.some(item => !!item)]); + } catch (error: any) { + errorArr.push([projectPath, createError(error)]); + } + } + return { + resultArr, + errorArr + }; +}; diff --git a/packages/vscode-extension/src/work/getApis.ts b/packages/vscode-extension/src/work/getApis.ts index a62b737..bb38a7a 100644 --- a/packages/vscode-extension/src/work/getApis.ts +++ b/packages/vscode-extension/src/work/getApis.ts @@ -1,21 +1,11 @@ -import { DEFAULT_CONFIG, getAlovaJsonPath } from '@alova/wormhole'; +import { getApis } from '@alova/wormhole'; import path from 'node:path'; import { CONFIG_POOL } from './config'; export default (filePath: string) => { - const config = CONFIG_POOL.find(item => filePath.includes(path.resolve(item.workspaceRootDir))); + const [projectPath, config] = CONFIG_POOL.find(([projectPath]) => filePath.includes(path.resolve(projectPath))) ?? []; if (!config) { return []; } - const outputArr = config?.getAllOutputPath() || []; - return outputArr - .map(output => { - const apiPath = getAlovaJsonPath(config.workspaceRootDir, output); - const templateData = DEFAULT_CONFIG.templateData.get(apiPath); - if (!templateData) { - return []; - } - return templateData.pathApis.map(item => item.apis); - }) - .flat(2); + return getApis(config, projectPath); }; diff --git a/packages/vscode-extension/src/work/readConfig.ts b/packages/vscode-extension/src/work/readConfig.ts index 306c722..374fe0f 100644 --- a/packages/vscode-extension/src/work/readConfig.ts +++ b/packages/vscode-extension/src/work/readConfig.ts @@ -1,58 +1,60 @@ -import { highPrecisionInterval } from '@/utils'; -import { executeCommand } from '@/utils/work'; -import { Configuration, readConfig } from '@alova/wormhole'; -import { CONFIG_POOL } from './config'; - -const AUTOUPDATE_CONFIG_MAP = new Map>(); -const AUTOUPDATE_MAP = new Map>(); - -function refeshAutoUpdate(configuration: Configuration) { - const { time, immediate } = configuration.getAutoUpdateConfig(); - const oldConfig = AUTOUPDATE_CONFIG_MAP.get(configuration); - const oldTimer = AUTOUPDATE_MAP.get(configuration); - // 过滤掉已经配置的定时器 - if (oldConfig?.immediate === immediate && oldConfig.time === time && oldTimer?.isRunning()) { - return; - } - oldTimer?.clear(); - AUTOUPDATE_CONFIG_MAP.set(configuration, { immediate, time }); - AUTOUPDATE_MAP.set( - configuration, - highPrecisionInterval( - () => { - executeCommand('generateApi'); - }, - time * 1000, - immediate - ) - ); -} -function removeConfiguration(workspaceRootPath: string) { - const idx = CONFIG_POOL.findIndex(item => item.workspaceRootDir === workspaceRootPath); - if (idx >= 0) { - AUTOUPDATE_MAP.get(CONFIG_POOL[idx])?.clear(); - AUTOUPDATE_MAP.delete(CONFIG_POOL[idx]); - AUTOUPDATE_CONFIG_MAP.delete(CONFIG_POOL[idx]); - CONFIG_POOL.splice(idx, 1); - } -} -export default async (workspaceRootPathArr: string[]) => { - let configNum = 0; - for (const workspaceRootPath of workspaceRootPathArr) { - const config = await readConfig(workspaceRootPath); - if (!config) { - removeConfiguration(workspaceRootPath); - continue; - } - let configuration = CONFIG_POOL.find(item => item.workspaceRootDir === workspaceRootPath); - if (!configuration) { - configuration = new Configuration(config, workspaceRootPath); - CONFIG_POOL.push(configuration); - } else { - configuration.config = config; - } - refeshAutoUpdate(configuration); - configNum += 1; - } - return configNum > 0; -}; +import { highPrecisionInterval } from '@/utils'; +import { executeCommand } from '@/utils/work'; +import { readConfig, getAutoUpdateConfig } from '@alova/wormhole'; +import { CONFIG_POOL } from './config'; +import type { ConfigObject } from './config'; + +const AUTOUPDATE_CONFIG_MAP = new Map(); +const AUTOUPDATE_MAP = new Map>(); + +function refeshAutoUpdate(configuration: ConfigObject) { + const [, config] = configuration; + const { time, immediate } = getAutoUpdateConfig(config); + const oldConfig = AUTOUPDATE_CONFIG_MAP.get(configuration); + const oldTimer = AUTOUPDATE_MAP.get(configuration); + // 过滤掉已经配置的定时器 + if (oldConfig?.immediate === immediate && oldConfig.time === time && oldTimer?.isRunning()) { + return; + } + oldTimer?.clear(); + AUTOUPDATE_CONFIG_MAP.set(configuration, { immediate, time }); + AUTOUPDATE_MAP.set( + configuration, + highPrecisionInterval( + () => { + executeCommand('generateApi'); + }, + time * 1000, + immediate + ) + ); +} +function removeConfiguration(workspaceRootPath: string) { + const idx = CONFIG_POOL.findIndex(([projectPath]) => projectPath === workspaceRootPath); + if (idx >= 0) { + AUTOUPDATE_MAP.get(CONFIG_POOL[idx])?.clear(); + AUTOUPDATE_MAP.delete(CONFIG_POOL[idx]); + AUTOUPDATE_CONFIG_MAP.delete(CONFIG_POOL[idx]); + CONFIG_POOL.splice(idx, 1); + } +} +export default async (workspaceRootPathArr: string[]) => { + let configNum = 0; + for (const workspaceRootPath of workspaceRootPathArr) { + const config = await readConfig(workspaceRootPath); + if (!config) { + removeConfiguration(workspaceRootPath); + continue; + } + let configuration = CONFIG_POOL.find(([projectPath]) => projectPath === workspaceRootPath); + if (!configuration) { + configuration = [workspaceRootPath, config]; + CONFIG_POOL.push(configuration); + } else { + configuration[1] = config; + } + refeshAutoUpdate(configuration); + configNum += 1; + } + return configNum > 0; +}; diff --git a/packages/wormhole/build.config.ts b/packages/wormhole/build.config.ts index 028f911..3431df0 100644 --- a/packages/wormhole/build.config.ts +++ b/packages/wormhole/build.config.ts @@ -7,7 +7,7 @@ import { defineBuildConfig } from 'unbuild'; export default defineBuildConfig({ entries: ['src/index'], clean: true, - declaration: true, + declaration: true, // 直接使用typings failOnWarn: false, hooks: { 'build:done': async ctx => { diff --git a/packages/wormhole/src/functions/openApi2Data.ts b/packages/wormhole/src/functions/openApi2Data.ts index 3869248..b9097c5 100644 --- a/packages/wormhole/src/functions/openApi2Data.ts +++ b/packages/wormhole/src/functions/openApi2Data.ts @@ -6,7 +6,7 @@ import { generateDefaultValues } from '@/helper/typeStr'; import { format, removeUndefined } from '@/utils'; import { cloneDeep, isEmpty } from 'lodash'; import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'; -import type { ApiDescriptor, GeneratorConfig, TemplateType } from '~/index'; +import type { Api, ApiDescriptor, GeneratorConfig, TemplateType } from '~/index'; import { AlovaVersion } from './getAlovaVersion'; type Path = { @@ -14,23 +14,6 @@ type Path = { method: string; path: string; }; -export interface Api { - method: string; - summary: string; - path: string; - pathParameters: string; - queryParameters: string; - pathParametersComment?: string; - queryParametersComment?: string; - responseComment?: string; - requestComment?: string; - name: string; - global: string; - responseName: string; - requestName?: string; - defaultValue?: string; - pathKey: string; -} interface PathApis { tag: string; apis: Api[]; diff --git a/packages/wormhole/src/index.ts b/packages/wormhole/src/index.ts index 23538c8..8b5d12f 100644 --- a/packages/wormhole/src/index.ts +++ b/packages/wormhole/src/index.ts @@ -1,8 +1,5 @@ export type * from '~/index'; export * from './config'; export * from './createConfig'; -export * from './functions/alovaJson'; -export * from './functions/openApi2Data'; export * from './generate'; -export { default as Configuration } from './modules/Configuration'; export * from './readConfig'; diff --git a/packages/wormhole/src/readConfig.ts b/packages/wormhole/src/readConfig.ts index bf35c23..950a2bb 100644 --- a/packages/wormhole/src/readConfig.ts +++ b/packages/wormhole/src/readConfig.ts @@ -30,7 +30,7 @@ export const readConfig = async (projectPath: string = process.cwd()) => { } return config; }; -export const readAndSaveAlovaJson = (config: Config, projectPath: string = process.cwd()) => { +const readAndSaveAlovaJson = (config: Config, projectPath: string = process.cwd()) => { const configuration = new Configuration(config, projectPath); configuration.getAllOutputPath().forEach(outputPath => { // 缓存文件地址 @@ -43,4 +43,34 @@ export const readAndSaveAlovaJson = (config: Config, projectPath: string = proce .catch(() => {}); }); }; +export const getAutoUpdateConfig = (config: Config) => { + const autoUpdateConfig = config.autoUpdate; + let time = 60 * 5; // 默认五分钟 + let immediate = false; + if (typeof autoUpdateConfig === 'object') { + time = Number(autoUpdateConfig.interval); + immediate = !!autoUpdateConfig.launchEditor; + } + return { + time, + immediate + }; +}; +export const getApis = (config: Config, projectPath: string = process.cwd()) => { + if (!config || !projectPath) { + return []; + } + const configuration = new Configuration(config, projectPath); + const outputArr = configuration.getAllOutputPath() ?? []; + return outputArr + .map(output => { + const apiPath = getAlovaJsonPath(projectPath, output); + const templateData = DEFAULT_CONFIG.templateData.get(apiPath); + if (!templateData) { + return []; + } + return templateData.pathApis.map(item => item.apis); + }) + .flat(2); +}; export default readConfig; diff --git a/packages/wormhole/typings/index.d.ts b/packages/wormhole/typings/index.d.ts index 13e8a4b..5b3f995 100644 --- a/packages/wormhole/typings/index.d.ts +++ b/packages/wormhole/typings/index.d.ts @@ -77,3 +77,21 @@ export type GenerateApiOptions = { force?: boolean; projectPath?: string; }; +// 生成的api描述信息 +export interface Api { + method: string; + summary: string; + path: string; + pathParameters: string; + queryParameters: string; + pathParametersComment?: string; + queryParametersComment?: string; + responseComment?: string; + requestComment?: string; + name: string; + global: string; + responseName: string; + requestName?: string; + defaultValue?: string; + pathKey: string; +} From d6377f57ce49fcf1c7d0c09b879ac6f08221d9a9 Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Tue, 10 Sep 2024 14:16:25 +0800 Subject: [PATCH 18/47] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0defaultRequire?= =?UTF-8?q?=EF=BC=8C=E9=BB=98=E8=AE=A4=E9=83=BD=E6=98=AFrequire=E9=80=89?= =?UTF-8?q?=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wormhole/src/functions/openApi2Data.ts | 31 ++++++++++++++----- packages/wormhole/src/helper/schema2type.ts | 30 +++++++++++++++--- packages/wormhole/src/helper/typeStr.ts | 5 ++- packages/wormhole/typings/index.d.ts | 2 ++ 4 files changed, 54 insertions(+), 14 deletions(-) diff --git a/packages/wormhole/src/functions/openApi2Data.ts b/packages/wormhole/src/functions/openApi2Data.ts index b9097c5..b85cd45 100644 --- a/packages/wormhole/src/functions/openApi2Data.ts +++ b/packages/wormhole/src/functions/openApi2Data.ts @@ -60,6 +60,7 @@ export interface TemplateData extends Omit { const remove$ref = ( originObj: OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject, openApi: OpenAPIV3_1.Document, + config: GeneratorConfig, schemasMap?: Map, preText: string = '', searchMap: Map = new Map(), @@ -70,6 +71,7 @@ const remove$ref = ( commentStyle: 'docment', preText, searchMap, + defaultRequire: config.defaultRequire, on$Ref(refOject) { const type = getStandardRefName(refOject.$ref); if (schemasMap && !schemasMap.has(type)) { @@ -79,6 +81,7 @@ const remove$ref = ( openApi, { export: true, + defaultRequire: config.defaultRequire, on$RefTsStr(name, tsStr) { schemasMap.set(name, tsStr); } @@ -111,10 +114,15 @@ const parseResponse = async ( : responseInfo; const key = getContentKey(responseObject.content ?? {}, config.responseMediaType); const responseSchema = responseObject?.content?.[key]?.schema ?? {}; - const responseName = await remove$ref(responseSchema, openApi, schemasMap, '', removeMap); + const responseName = await remove$ref(responseSchema, openApi, config, schemasMap, '', removeMap); return { responseName, - responseComment: await convertToType(responseSchema, openApi, { deep: true, preText: '* ', searchMap }) + responseComment: await convertToType(responseSchema, openApi, { + deep: true, + preText: '* ', + searchMap, + defaultRequire: config.defaultRequire + }) }; }; const parseRequestBody = async ( @@ -136,10 +144,15 @@ const parseRequestBody = async ( : requestBody; const key = getContentKey(requestBodyObject.content, config.bodyMediaType); const requestBodySchema = requestBodyObject?.content?.[key]?.schema ?? {}; - const requestName = await remove$ref(requestBodySchema, openApi, schemasMap, '', removeMap); + const requestName = await remove$ref(requestBodySchema, openApi, config, schemasMap, '', removeMap); return { requestName, - requestComment: await convertToType(requestBodySchema, openApi, { deep: true, preText: '* ', searchMap }) + requestComment: await convertToType(requestBodySchema, openApi, { + deep: true, + preText: '* ', + searchMap, + defaultRequire: config.defaultRequire + }) }; }; const getContentKey = (content: Record, requireKey: string, defaultKey = 'application/json') => { @@ -207,19 +220,21 @@ const parseParameters = async ( let pathParametersComment = ''; let queryParametersComment = ''; if (Object.keys(pathParameters.properties ?? {}).length) { - pathParametersStr = await remove$ref(pathParameters, openApi, schemasMap, '', removeMap); + pathParametersStr = await remove$ref(pathParameters, openApi, config, schemasMap, '', removeMap); pathParametersComment = await convertToType(pathParameters, openApi, { deep: true, preText: '* ', - searchMap + searchMap, + defaultRequire: config.defaultRequire }); } if (Object.keys(queryParameters.properties ?? {}).length) { - queryParametersStr = await remove$ref(queryParameters, openApi, schemasMap, '', removeMap); + queryParametersStr = await remove$ref(queryParameters, openApi, config, schemasMap, '', removeMap); queryParametersComment = await convertToType(queryParameters, openApi, { deep: true, preText: '* ', - searchMap + searchMap, + defaultRequire: config.defaultRequire }); } return { diff --git a/packages/wormhole/src/helper/schema2type.ts b/packages/wormhole/src/helper/schema2type.ts index 7e7d47f..30c2b56 100644 --- a/packages/wormhole/src/helper/schema2type.ts +++ b/packages/wormhole/src/helper/schema2type.ts @@ -1,5 +1,6 @@ import { format } from '@/utils'; -import { OpenAPIV3_1 } from 'openapi-types'; +import { isArray } from 'lodash'; +import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'; import { findBy$ref, getStandardRefName, isReferenceObject } from './openapi'; import { isValidJSIdentifier } from './standard'; @@ -9,6 +10,7 @@ export interface Schema2TypeOptions { defaultType?: 'any' | 'unknown'; // 未匹配的时的默认类型 commentStyle?: 'line' | 'docment'; // 注释风格 preText?: string; // 注释前缀 + defaultRequire?: boolean; // 没有nullbale或者require时默认为require searchMap: Map; visited?: Set; on$Ref?: (refOject: OpenAPIV3_1.ReferenceObject) => void; @@ -131,8 +133,18 @@ function parseSchema( result = 'null'; break; default: - if (schema.oneOf) { - result = schema.oneOf.map(item => parseSchema(item, openApi, config)).join(' | '); + if (isArray(schema.type)) { + result = schema.type + .map( + nextType => `(${parseSchema({ ...schema, type: nextType as (typeof schema)['type'] }, openApi, config)})` + ) + .join(' | '); + } else if (schema.oneOf) { + result = schema.oneOf.map(item => `(${parseSchema(item, openApi, config)})`).join(' | '); + } else if (schema.anyOf) { + result = schema.anyOf.map(item => `(${parseSchema(item, openApi, config)})`).join(' | '); + } else if (schema.allOf) { + result = schema.allOf.map(item => `(${parseSchema(item, openApi, config)})`).join(' & '); } else { result = typeof schema.type === 'string' @@ -140,6 +152,9 @@ function parseSchema( : config.defaultType ?? 'unknown'; } } + if ((schema as OpenAPIV3.SchemaObject).nullable) { + result = `${result} | null`; + } if (refPath) { config.searchMap.set(refPath, result); } @@ -161,7 +176,7 @@ function parseObject( const required = new Set(schema.required ?? []); const lines: string[] = [`{`]; for (const [key, valueOrigin] of Object.entries(properties)) { - const optionalFlag = required.has(key) ? '' : '?'; + const optionalFlag = required.has(key) || config.defaultRequire ? '' : '?'; let refPath = ''; let value = valueOrigin as OpenAPIV3_1.SchemaObject; if (isReferenceObject(valueOrigin)) { @@ -279,6 +294,7 @@ export async function convertToType( } interface JsonSchema2TsOptions { export?: boolean; + defaultRequire?: boolean; // 没有nullbale或者require时默认为require on$RefTsStr?: (name: string, tsStr: string) => void; } /** @@ -293,7 +309,10 @@ export const jsonSchema2TsStr = async ( schema: OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject, name: string, openApi: OpenAPIV3_1.Document, - options: JsonSchema2TsOptions = { export: false }, + options: JsonSchema2TsOptions = { + export: false, + defaultRequire: false + }, searchMap: Map = new Map(), map: Map = new Map(), visited: Set = new Set() @@ -304,6 +323,7 @@ export const jsonSchema2TsStr = async ( commentStyle: 'docment', preText: '', searchMap, + defaultRequire: options.defaultRequire, async on$Ref(refObject) { if (options.on$RefTsStr) { const name = getStandardRefName(refObject.$ref); diff --git a/packages/wormhole/src/helper/typeStr.ts b/packages/wormhole/src/helper/typeStr.ts index f6ca97e..7409619 100644 --- a/packages/wormhole/src/helper/typeStr.ts +++ b/packages/wormhole/src/helper/typeStr.ts @@ -111,8 +111,11 @@ function getDefaultValue(type: string): string { return acc; }, '{}'); } + if (type.startsWith('(') && type.endsWith(')')) { + return getDefaultValue(type.slice(1, -1).trim()); + } if (type.startsWith('{') && type.endsWith('}')) { - return parseTypeBody(type.slice(1, -1)); + return parseTypeBody(type.slice(1, -1).trim()); } if (type.endsWith(')[]') && type.startsWith('(')) { return '[]'; diff --git a/packages/wormhole/typings/index.d.ts b/packages/wormhole/typings/index.d.ts index 5b3f995..968e3de 100644 --- a/packages/wormhole/typings/index.d.ts +++ b/packages/wormhole/typings/index.d.ts @@ -52,6 +52,8 @@ export type GeneratorConfig = { // 是否使用import来导入类型,默认false // 开启此选项后,生成的apiDefinitions.ts文件将使用import语法来导入类型,而不是/// useImportType: boolean; + // 没有require时默认为require,只有nullable生效 + defaultRequire?: boolean; // (具体看下面)过滤或转换生成的api接口函数,返回一个新的apiDescriptor来生成api调用函数 // 未指定此函数时则不转换apiDescripor对象 // apiDescriptor的格式与openapi文件的接口对象格式相同 From af51cbaec5c274523871ccc784b4ce2682b1e2cb Mon Sep 17 00:00:00 2001 From: czhlin <2324133088@qq.com> Date: Wed, 11 Sep 2024 00:17:13 +0800 Subject: [PATCH 19/47] =?UTF-8?q?feat(wormhole):=20=E6=B7=BB=E5=8A=A0node?= =?UTF-8?q?=E5=91=BD=E5=90=8D=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/wormhole/bin/index.js | 40 +++++++++++++++++++ packages/wormhole/package.json | 12 ++++-- packages/wormhole/src/functions/alovaJson.ts | 2 +- .../wormhole/src/functions/generateApi.ts | 2 +- .../wormhole/src/functions/getAlovaVersion.ts | 7 +--- .../src/functions/getAutoTemplateType.ts | 7 +--- .../wormhole/src/functions/getFrameworkTag.ts | 7 +--- .../wormhole/src/functions/getOpenApiData.ts | 2 +- packages/wormhole/src/helper/schema2type.ts | 6 +-- packages/wormhole/src/utils/index.ts | 2 +- pnpm-lock.yaml | 3 ++ 11 files changed, 63 insertions(+), 27 deletions(-) create mode 100644 packages/wormhole/bin/index.js diff --git a/packages/wormhole/bin/index.js b/packages/wormhole/bin/index.js new file mode 100644 index 0000000..25f7ad9 --- /dev/null +++ b/packages/wormhole/bin/index.js @@ -0,0 +1,40 @@ +#!/usr/bin/env node +const { program } = require('commander'); +const package = require('../package.json'); +const { createConfig, readConfig, generate } = require('../dist/index.cjs'); + +program.name('@alova/wormhole').description('CLI to generate api for alova.js').version(package.version); + +program + .command('init') + .description('init alova.config') + .action(() => { + createConfig() + .then(() => { + console.log('alova.config生成成功!'); + }) + .catch(error => { + console.log(error); + }); + }); + +program + .command('gen') + .option('-f', 'force generate api') + .description('generate api for alova.js') + .action(option => { + readConfig() + .then(config => generate(config, { force: option.f })) + .then(([result]) => { + if (result) { + console.log('api文件生成成功!'); + } else { + console.log('api文件生成失败!,尝试强制生成【alova gen -f】'); + } + }) + .catch(error => { + console.log(error); + }); + }); + +program.parse(process.argv); // 表示使用 Commander 来处理命令行参数 diff --git a/packages/wormhole/package.json b/packages/wormhole/package.json index f7ea531..a1ce9dc 100644 --- a/packages/wormhole/package.json +++ b/packages/wormhole/package.json @@ -6,6 +6,9 @@ "main": "./dist/index.cjs", "module": "./dist/index.mjs", "types": "./dist/index.d.ts", + "bin": { + "alova": "./bin/index.js" + }, "exports": { ".": { "types": "./dist/index.d.ts", @@ -14,7 +17,7 @@ } }, "scripts": { - "build": "unbuild", + "build": "unbuild --minify", "dev": "pnpm run stub", "stub": "unbuild --stub" }, @@ -23,17 +26,18 @@ "license": "ISC", "devDependencies": { "@types/fs-extra": "^11.0.4", - "unbuild": "^2.0.0", + "fs-extra": "^11.2.0", "openapi-types": "^12.1.3", - "fs-extra": "^11.2.0" + "unbuild": "^2.0.0" }, "dependencies": { + "commander": "^12.1.0", "cosmiconfig": "^9.0.0", "handlebars": "^4.7.8", "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", "lodash": "^4.17.21", "node-fetch": "^2.7.0", - "js-yaml": "^4.1.0", "swagger2openapi": "^7.0.8" } } diff --git a/packages/wormhole/src/functions/alovaJson.ts b/packages/wormhole/src/functions/alovaJson.ts index 3598e38..17a0350 100644 --- a/packages/wormhole/src/functions/alovaJson.ts +++ b/packages/wormhole/src/functions/alovaJson.ts @@ -23,7 +23,7 @@ export const writeAlovaJson = async (data: TemplateData, originPath: string, nam if (err) { console.error('Error writing file:', err); } else { - console.log('JSON file has been saved.'); + // console.log('JSON file has been saved.'); } }); }; diff --git a/packages/wormhole/src/functions/generateApi.ts b/packages/wormhole/src/functions/generateApi.ts index 1949bf0..6b945d8 100644 --- a/packages/wormhole/src/functions/generateApi.ts +++ b/packages/wormhole/src/functions/generateApi.ts @@ -22,7 +22,7 @@ export default async function ( return; } // 输出目录 - const outputDir = path.join(workspaceRootDir, outputPath); + const outputDir = path.resolve(workspaceRootDir, outputPath); // 缓存文件地址 const alovaJsonPath = getAlovaJsonPath(workspaceRootDir, outputPath); // 获取alova版本 diff --git a/packages/wormhole/src/functions/getAlovaVersion.ts b/packages/wormhole/src/functions/getAlovaVersion.ts index 2d6b962..71e010b 100644 --- a/packages/wormhole/src/functions/getAlovaVersion.ts +++ b/packages/wormhole/src/functions/getAlovaVersion.ts @@ -1,13 +1,10 @@ -import { createRequire } from 'node:module'; +import importFresh from 'import-fresh'; import path from 'node:path'; import { PackageJson } from 'type-fest'; - export type AlovaVersion = `v${number}`; export default function (workspaceRootDir: string) { - const workspacedRequire = createRequire(workspaceRootDir); - const packageJson: PackageJson = workspacedRequire('./package.json'); - delete workspacedRequire.cache[path.resolve(workspaceRootDir, './package.json')]; + const packageJson: PackageJson = importFresh(path.resolve(workspaceRootDir, './package.json')); if (!packageJson) { return 'v2'; } diff --git a/packages/wormhole/src/functions/getAutoTemplateType.ts b/packages/wormhole/src/functions/getAutoTemplateType.ts index be6790c..52e626d 100644 --- a/packages/wormhole/src/functions/getAutoTemplateType.ts +++ b/packages/wormhole/src/functions/getAutoTemplateType.ts @@ -1,12 +1,9 @@ -import { createRequire } from 'node:module'; +import importFresh from 'import-fresh'; import path from 'node:path'; import { PackageJson } from 'type-fest'; import type { TemplateType } from '~/index'; - export default (workspaceRootDir: string): TemplateType => { - const workspacedRequire = createRequire(workspaceRootDir); - const packageJson: PackageJson = workspacedRequire('./package.json'); - delete workspacedRequire.cache[path.resolve(workspaceRootDir, './package.json')]; + const packageJson: PackageJson = importFresh(path.resolve(workspaceRootDir, './package.json')); if (packageJson?.devDependencies?.typescript) { return 'typescript'; } diff --git a/packages/wormhole/src/functions/getFrameworkTag.ts b/packages/wormhole/src/functions/getFrameworkTag.ts index 99470a6..3dbcd9e 100644 --- a/packages/wormhole/src/functions/getFrameworkTag.ts +++ b/packages/wormhole/src/functions/getFrameworkTag.ts @@ -1,12 +1,9 @@ -import { createRequire } from 'node:module'; +import importFresh from 'import-fresh'; import path from 'node:path'; import { PackageJson } from 'type-fest'; - export const frameworkName: ['vue', 'react'] = ['vue', 'react']; export default function (workspaceRootDir: string) { - const workspacedRequire = createRequire(workspaceRootDir); - const packageJson: PackageJson = workspacedRequire('./package.json'); - delete workspacedRequire.cache[path.resolve(workspaceRootDir, './package.json')]; + const packageJson: PackageJson = importFresh(path.resolve(workspaceRootDir, './package.json')); if (!packageJson) { return 'defaultKey'; } diff --git a/packages/wormhole/src/functions/getOpenApiData.ts b/packages/wormhole/src/functions/getOpenApiData.ts index dcfa61d..44426f0 100644 --- a/packages/wormhole/src/functions/getOpenApiData.ts +++ b/packages/wormhole/src/functions/getOpenApiData.ts @@ -16,7 +16,7 @@ function parseLocalFile(workspaceRootDir: string, filePath: string) { const [, extname] = /\.([^.]+)$/.exec(filePath) ?? []; switch (extname) { case 'yaml': { - const file = fs.readFileSync(`${workspaceRootDir}${filePath}`, 'utf-8'); + const file = fs.readFileSync(path.resolve(workspaceRootDir, filePath), 'utf-8'); const data = YAML.load(file) as any; return data; } diff --git a/packages/wormhole/src/helper/schema2type.ts b/packages/wormhole/src/helper/schema2type.ts index 30c2b56..b08758f 100644 --- a/packages/wormhole/src/helper/schema2type.ts +++ b/packages/wormhole/src/helper/schema2type.ts @@ -152,9 +152,6 @@ function parseSchema( : config.defaultType ?? 'unknown'; } } - if ((schema as OpenAPIV3.SchemaObject).nullable) { - result = `${result} | null`; - } if (refPath) { config.searchMap.set(refPath, result); } @@ -176,7 +173,8 @@ function parseObject( const required = new Set(schema.required ?? []); const lines: string[] = [`{`]; for (const [key, valueOrigin] of Object.entries(properties)) { - const optionalFlag = required.has(key) || config.defaultRequire ? '' : '?'; + const optionalFlag = + required.has(key) || (config.defaultRequire && !(schema as OpenAPIV3.SchemaObject).nullable) ? '' : '?'; let refPath = ''; let value = valueOrigin as OpenAPIV3_1.SchemaObject; if (isReferenceObject(valueOrigin)) { diff --git a/packages/wormhole/src/utils/index.ts b/packages/wormhole/src/utils/index.ts index fae6e8f..0941d24 100644 --- a/packages/wormhole/src/utils/index.ts +++ b/packages/wormhole/src/utils/index.ts @@ -102,7 +102,7 @@ export async function generateFile(distDir: string, fileName: string, content: s if (err) { return console.error('Error writing file:', err); } - console.log('File written successfully at', filePath); + // console.log('File written successfully at', filePath); }); } export async function fetchData(url: string) { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1851485..0cc34c6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -141,6 +141,9 @@ importers: packages/wormhole: dependencies: + commander: + specifier: ^12.1.0 + version: 12.1.0 cosmiconfig: specifier: ^9.0.0 version: 9.0.0(typescript@5.5.4) From 683c8f277bd7c4a2fb07442678e8bb85b5cce9f2 Mon Sep 17 00:00:00 2001 From: czhlin <2324133088@qq.com> Date: Wed, 11 Sep 2024 00:45:06 +0800 Subject: [PATCH 20/47] =?UTF-8?q?chore(wormhole):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E6=8F=90?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/wormhole/bin/index.js | 7 ++++++- packages/wormhole/src/generate.ts | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/wormhole/bin/index.js b/packages/wormhole/bin/index.js index 25f7ad9..e665ee9 100644 --- a/packages/wormhole/bin/index.js +++ b/packages/wormhole/bin/index.js @@ -24,7 +24,12 @@ program .description('generate api for alova.js') .action(option => { readConfig() - .then(config => generate(config, { force: option.f })) + .then(config => { + if (!config) { + throw Error('Expected to create alova.config.js in root directory.'); + } + return generate(config, { force: option.f }); + }) .then(([result]) => { if (result) { console.log('api文件生成成功!'); diff --git a/packages/wormhole/src/generate.ts b/packages/wormhole/src/generate.ts index ab8a6da..59832d2 100644 --- a/packages/wormhole/src/generate.ts +++ b/packages/wormhole/src/generate.ts @@ -2,9 +2,9 @@ import type { Config, GenerateApiOptions } from '~/index'; import generateApi from './functions/generateApi'; import Configuration from './modules/Configuration'; -export const generate = async (config: Config, options?: GenerateApiOptions): Promise => { +export const generate = async (config: Config, options?: GenerateApiOptions): Promise<(boolean | void)[]> => { if (!config) { - return; + return []; } const configuration = new Configuration(config, options?.projectPath ?? process.cwd()); // 检查新配置 From cf75e9ccc2be1afdd6b6abc928da1c9aef62b85f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E9=95=87?= Date: Thu, 12 Sep 2024 14:47:05 +0800 Subject: [PATCH 21/47] feat: add vitest as unit test tool, change file operation synchronous to promisify --- .eslintrc.cjs | 2 +- package.json | 4 +- packages/wormhole/__mocks__/fs.cjs | 17 + packages/wormhole/__mocks__/fs/promises.cjs | 17 + packages/wormhole/package.json | 3 +- packages/wormhole/src/createConfig.ts | 2 +- packages/wormhole/src/functions/alovaJson.ts | 59 +- .../wormhole/src/functions/generateApi.ts | 28 +- .../wormhole/src/functions/getAlovaVersion.ts | 2 +- .../src/functions/getAutoTemplateType.ts | 1 + .../wormhole/src/functions/getOpenApiData.ts | 9 +- packages/wormhole/src/generate.ts | 4 +- packages/wormhole/src/index.ts | 6 +- packages/wormhole/src/readConfig.ts | 7 +- packages/wormhole/src/utils/index.ts | 19 +- .../test/__snapshots__/generate.spec.ts.snap | 10881 ++++++++++++++++ packages/wormhole/test/config.spec.ts | 201 + packages/wormhole/test/generate.spec.ts | 208 + .../wormhole/test/openapis/openapi_300.yaml | 745 ++ .../wormhole/test/openapis/openapi_301.json | 655 + .../wormhole/test/openapis/swagger_2.json | 897 ++ .../test/output/openapi_300/apiDefinitions.ts | 48 + .../test/output/openapi_300/createApis.ts | 82 + .../test/output/openapi_300/globals.d.ts | 2660 ++++ .../wormhole/test/output/openapi_300/index.ts | 18 + packages/wormhole/tsconfig.json | 2 +- packages/wormhole/typings/index.d.ts | 18 +- packages/wormhole/vitest.config.ts | 11 + pnpm-lock.yaml | 513 + tsconfig.base.json | 6 +- vitest.workspace.ts | 3 + 31 files changed, 17036 insertions(+), 92 deletions(-) create mode 100644 packages/wormhole/__mocks__/fs.cjs create mode 100644 packages/wormhole/__mocks__/fs/promises.cjs create mode 100644 packages/wormhole/test/__snapshots__/generate.spec.ts.snap create mode 100644 packages/wormhole/test/config.spec.ts create mode 100644 packages/wormhole/test/generate.spec.ts create mode 100644 packages/wormhole/test/openapis/openapi_300.yaml create mode 100644 packages/wormhole/test/openapis/openapi_301.json create mode 100644 packages/wormhole/test/openapis/swagger_2.json create mode 100644 packages/wormhole/test/output/openapi_300/apiDefinitions.ts create mode 100644 packages/wormhole/test/output/openapi_300/createApis.ts create mode 100644 packages/wormhole/test/output/openapi_300/globals.d.ts create mode 100644 packages/wormhole/test/output/openapi_300/index.ts create mode 100644 packages/wormhole/vitest.config.ts create mode 100644 vitest.workspace.ts diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 5be93a5..8146fcc 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -4,7 +4,7 @@ module.exports = { es2021: true, node: true }, - ignorePatterns: ['out', '**/*.handlebars', 'test/api-*/**/*.*'], + ignorePatterns: ['out', '**/__mocks__', '**/*.handlebars', 'test/api-*/**/*.*'], extends: ['airbnb', 'airbnb-typescript', 'prettier'], parser: '@typescript-eslint/parser', parserOptions: { diff --git a/package.json b/package.json index 5422b96..4598f04 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "pnpm": ">=8.6.12" }, "scripts": { + "test": "vitest", "lint": "eslint . --ext .js,.ts", "lint:fix": "npm run lint -- --fix", "format": "prettier --check .", @@ -57,7 +58,8 @@ "tslib": "^2.7.0", "tsx": "^4.15.8", "type-fest": "^4.20.0", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "vitest": "^2.0.5" }, "config": { "commitizen": { diff --git a/packages/wormhole/__mocks__/fs.cjs b/packages/wormhole/__mocks__/fs.cjs new file mode 100644 index 0000000..586b9e8 --- /dev/null +++ b/packages/wormhole/__mocks__/fs.cjs @@ -0,0 +1,17 @@ +const { fs } = require('memfs'); +const originalFs = require('fs'); + +const realfsPatterns = [/\.handlebars$/, /openapis/]; +const isMatchRealFs = path => realfsPatterns.some(pattern => pattern.test(path)); + +module.exports = { + ...fs, + readFile(...args) { + // console.log('readFile', args, isMatchmemFs(args[0])); + return isMatchRealFs(args[0]) ? originalFs.readFile(...args) : fs.readFile(...args); + }, + readFileSync(...args) { + // console.log('readFileSync', args, isMatchmemFs(args[0])); + return isMatchRealFs(args[0]) ? originalFs.readFileSync(...args) : fs.readFileSync(...args); + } +}; diff --git a/packages/wormhole/__mocks__/fs/promises.cjs b/packages/wormhole/__mocks__/fs/promises.cjs new file mode 100644 index 0000000..986276c --- /dev/null +++ b/packages/wormhole/__mocks__/fs/promises.cjs @@ -0,0 +1,17 @@ +const { fs } = require('memfs'); +const originalFs = require('fs/promises'); + +const realfsPatterns = [/\.handlebars$/, /openapis/]; +const isMatchRealFs = path => realfsPatterns.some(pattern => pattern.test(path)); + +module.exports = { + ...fs.promises, + readFile(...args) { + // console.log('readFile promise', args, isMatchRealFs(args[0])); + return isMatchRealFs(args[0]) ? originalFs.readFile(...args) : fs.promises.readFile(...args); + }, + writeFile(...args) { + // console.log('writeFile promise', args[0], isMatchRealFs(args[0])); + return fs.promises.writeFile(...args); + } +}; diff --git a/packages/wormhole/package.json b/packages/wormhole/package.json index a1ce9dc..6beaa4a 100644 --- a/packages/wormhole/package.json +++ b/packages/wormhole/package.json @@ -23,10 +23,11 @@ }, "keywords": [], "author": "", - "license": "ISC", + "license": "MIT", "devDependencies": { "@types/fs-extra": "^11.0.4", "fs-extra": "^11.2.0", + "memfs": "^4.11.1", "openapi-types": "^12.1.3", "unbuild": "^2.0.0" }, diff --git a/packages/wormhole/src/createConfig.ts b/packages/wormhole/src/createConfig.ts index 74c0bb4..40bf3a6 100644 --- a/packages/wormhole/src/createConfig.ts +++ b/packages/wormhole/src/createConfig.ts @@ -2,7 +2,7 @@ import getAlovaVersion, { AlovaVersion } from './functions/getAlovaVersion'; import getAutoTemplateType from './functions/getAutoTemplateType'; import TemplateFile from './modules/TemplateFile'; -export const createConfig = async (projectPath: string = process.cwd()) => { +const createConfig = (projectPath = process.cwd()) => { const type = getAutoTemplateType(projectPath); const moduleType = TemplateFile.getModuleType(type); const alovaVersion: AlovaVersion = getAlovaVersion(projectPath); diff --git a/packages/wormhole/src/functions/alovaJson.ts b/packages/wormhole/src/functions/alovaJson.ts index 17a0350..6dd9be6 100644 --- a/packages/wormhole/src/functions/alovaJson.ts +++ b/packages/wormhole/src/functions/alovaJson.ts @@ -1,55 +1,40 @@ import { DEFAULT_CONFIG } from '@/config'; import { format } from '@/utils'; -import fs from 'node:fs'; +import fs from 'node:fs/promises'; import path from 'node:path'; import type { TemplateData } from './openApi2Data'; export const writeAlovaJson = async (data: TemplateData, originPath: string, name = 'api.json') => { // 将数据转换为 JSON 字符串 - let jsonData = ''; - try { - jsonData = await format(JSON.stringify(data, null, 2), { parser: 'json' }); - } catch (error) { - console.log(error, 13); - } + const jsonData = await format(JSON.stringify(data, null, 2), { parser: 'json' }); // 定义 JSON 文件的路径和名称 const filePath = `${originPath}_${name}`; const dirPath = filePath.split(/\/|\\/).slice(0, -1).join('/'); - if (!fs.existsSync(dirPath)) { - fs.mkdirSync(dirPath, { recursive: true }); + try { + await fs.access(dirPath); + } catch (error) { + await fs.mkdir(dirPath, { recursive: true }); } // 使用 fs.writeFile 将 JSON 数据写入文件 - fs.writeFile(filePath, jsonData, err => { - if (err) { - console.error('Error writing file:', err); - } else { - // console.log('JSON file has been saved.'); - } - }); + return fs.writeFile(filePath, jsonData); }; -export const readAlovaJson = (originPath: string, name = 'api.json') => { +export const readAlovaJson = async (originPath: string, name = 'api.json') => { // 定义 JSON 文件的路径和名称 const filePath = `${originPath}_${name}`; - return new Promise((resolve, reject) => { - if (!fs.existsSync(filePath)) { - reject(new DEFAULT_CONFIG.Error('alovaJson not exists')); - return; - } - // 使用 fs.readFile 读取 JSON 文件 - fs.readFile(filePath, 'utf8', (err, data) => { - if (err) { - reject(err); - } else { - let jsonData = {}; - try { - jsonData = JSON.parse(data); - } catch (error) { - jsonData = {}; - } - resolve(jsonData as TemplateData); - } - }); - }); + + try { + await fs.access(filePath); + } catch (error) { + throw new DEFAULT_CONFIG.Error('alovaJson not exists'); + } + + // 使用 fs.readFile 读取 JSON 文件 + const data = await fs.readFile(filePath, 'utf8'); + let jsonData = {} as TemplateData; + try { + jsonData = JSON.parse(data); + } catch (error) {} + return jsonData; }; export const getAlovaJsonPath = (workspaceRootDir: string, outputPath: string) => path.join(workspaceRootDir, DEFAULT_CONFIG.alovaTempPath, outputPath.split(/\/|\\/).join('_')); diff --git a/packages/wormhole/src/functions/generateApi.ts b/packages/wormhole/src/functions/generateApi.ts index 6b945d8..797bc57 100644 --- a/packages/wormhole/src/functions/generateApi.ts +++ b/packages/wormhole/src/functions/generateApi.ts @@ -1,6 +1,6 @@ import { DEFAULT_CONFIG } from '@/config'; import { isEqual } from 'lodash'; -import fs from 'node:fs'; +import fs from 'node:fs/promises'; import path from 'node:path'; import { OpenAPIV3_1 } from 'openapi-types'; import type { GeneratorConfig, TemplateType } from '~/index'; @@ -19,7 +19,7 @@ export default async function ( force: boolean // 是否强制生成 ) { if (!data) { - return; + return false; } // 输出目录 const outputDir = path.resolve(workspaceRootDir, outputPath); @@ -54,15 +54,22 @@ export default async function ( // 保存templateData DEFAULT_CONFIG.templateData.set(alovaJsonPath, templateData); // 生成alova.json文件 - writeAlovaJson(templateData, alovaJsonPath); + await writeAlovaJson(templateData, alovaJsonPath); // 获取是否存在index.ts|index.js - const indexIsExists = fs.existsSync(path.join(outputDir, `index${templateFile.getExt()}`)); + let indexIsExists = true; + try { + await fs.access(path.join(outputDir, `index${templateFile.getExt()}`)); + } catch (error) { + indexIsExists = false; + } // mustache语法生成 // 定义模版配置对象 - [ - !indexIsExists && { - fileName: 'index' - }, + const generatingPromises = [ + !indexIsExists + ? { + fileName: 'index' + } + : null, { fileName: 'createApis' }, @@ -76,12 +83,13 @@ export default async function ( ext: '.ts', root: true } - ].forEach(item => { + ].map(item => { if (!item) { return; } const { fileName, ext, root, hasVersion } = item; - templateFile.outputFile(templateData, fileName, outputDir, { ext, root, hasVersion }); + return templateFile.outputFile(templateData, fileName, outputDir, { ext, root, hasVersion }); }); + await Promise.all(generatingPromises); return true; } diff --git a/packages/wormhole/src/functions/getAlovaVersion.ts b/packages/wormhole/src/functions/getAlovaVersion.ts index 71e010b..e6e48de 100644 --- a/packages/wormhole/src/functions/getAlovaVersion.ts +++ b/packages/wormhole/src/functions/getAlovaVersion.ts @@ -1,8 +1,8 @@ import importFresh from 'import-fresh'; import path from 'node:path'; import { PackageJson } from 'type-fest'; -export type AlovaVersion = `v${number}`; +export type AlovaVersion = `v${number}`; export default function (workspaceRootDir: string) { const packageJson: PackageJson = importFresh(path.resolve(workspaceRootDir, './package.json')); if (!packageJson) { diff --git a/packages/wormhole/src/functions/getAutoTemplateType.ts b/packages/wormhole/src/functions/getAutoTemplateType.ts index 52e626d..9fcd8f5 100644 --- a/packages/wormhole/src/functions/getAutoTemplateType.ts +++ b/packages/wormhole/src/functions/getAutoTemplateType.ts @@ -2,6 +2,7 @@ import importFresh from 'import-fresh'; import path from 'node:path'; import { PackageJson } from 'type-fest'; import type { TemplateType } from '~/index'; + export default (workspaceRootDir: string): TemplateType => { const packageJson: PackageJson = importFresh(path.resolve(workspaceRootDir, './package.json')); if (packageJson?.devDependencies?.typescript) { diff --git a/packages/wormhole/src/functions/getOpenApiData.ts b/packages/wormhole/src/functions/getOpenApiData.ts index 44426f0..a37f5e6 100644 --- a/packages/wormhole/src/functions/getOpenApiData.ts +++ b/packages/wormhole/src/functions/getOpenApiData.ts @@ -2,7 +2,7 @@ import { DEFAULT_CONFIG } from '@/config'; import { fetchData } from '@/utils'; import importFresh from 'import-fresh'; import YAML from 'js-yaml'; -import fs from 'node:fs'; +import fs from 'node:fs/promises'; import path from 'node:path'; import { OpenAPIV2, OpenAPIV3_1 } from 'openapi-types'; import swagger2openapi from 'swagger2openapi'; @@ -12,11 +12,11 @@ function isSwagger2(data: any): data is OpenAPIV2.Document { return !!data?.swagger; } // 解析本地openapi文件 -function parseLocalFile(workspaceRootDir: string, filePath: string) { +async function parseLocalFile(workspaceRootDir: string, filePath: string) { const [, extname] = /\.([^.]+)$/.exec(filePath) ?? []; switch (extname) { case 'yaml': { - const file = fs.readFileSync(path.resolve(workspaceRootDir, filePath), 'utf-8'); + const file = await fs.readFile(path.resolve(workspaceRootDir, filePath), 'utf-8'); const data = YAML.load(file) as any; return data; } @@ -76,7 +76,7 @@ export default async function ( try { if (!/^http(s)?:\/\//.test(url)) { // 本地文件 - data = parseLocalFile(workspaceRootDir, url); + data = await parseLocalFile(workspaceRootDir, url); } else { // 远程文件 data = await parseRemoteFile(url, platformType); @@ -86,6 +86,7 @@ export default async function ( data = (await swagger2openapi.convertObj(data, { warnOnly: true })).openapi as OpenAPIV3_1.Document; } } catch (error) { + console.log(error, '222'); throw new DEFAULT_CONFIG.Error(`Cannot read file from ${url}`); } if (!data) { diff --git a/packages/wormhole/src/generate.ts b/packages/wormhole/src/generate.ts index 59832d2..b0b481f 100644 --- a/packages/wormhole/src/generate.ts +++ b/packages/wormhole/src/generate.ts @@ -2,9 +2,9 @@ import type { Config, GenerateApiOptions } from '~/index'; import generateApi from './functions/generateApi'; import Configuration from './modules/Configuration'; -export const generate = async (config: Config, options?: GenerateApiOptions): Promise<(boolean | void)[]> => { +const generate = async (config: Config, options?: GenerateApiOptions) => { if (!config) { - return []; + return [] as boolean[]; } const configuration = new Configuration(config, options?.projectPath ?? process.cwd()); // 检查新配置 diff --git a/packages/wormhole/src/index.ts b/packages/wormhole/src/index.ts index 8b5d12f..abe627c 100644 --- a/packages/wormhole/src/index.ts +++ b/packages/wormhole/src/index.ts @@ -1,5 +1,3 @@ -export type * from '~/index'; -export * from './config'; -export * from './createConfig'; -export * from './generate'; +export { default as createConfig } from './createConfig'; +export { default as generate } from './generate'; export * from './readConfig'; diff --git a/packages/wormhole/src/readConfig.ts b/packages/wormhole/src/readConfig.ts index 950a2bb..af9c142 100644 --- a/packages/wormhole/src/readConfig.ts +++ b/packages/wormhole/src/readConfig.ts @@ -17,7 +17,7 @@ const alovaExplorer = cosmiconfig('alova', { '.cts': loadTs } }); -export const readConfig = async (projectPath: string = process.cwd()) => { +export const readConfig = async (projectPath = process.cwd()) => { const searchResult = await alovaExplorer.search(path.resolve(projectPath)); alovaExplorer.clearCaches(); if (searchResult?.isEmpty) { @@ -30,7 +30,7 @@ export const readConfig = async (projectPath: string = process.cwd()) => { } return config; }; -const readAndSaveAlovaJson = (config: Config, projectPath: string = process.cwd()) => { +const readAndSaveAlovaJson = (config: Config, projectPath = process.cwd()) => { const configuration = new Configuration(config, projectPath); configuration.getAllOutputPath().forEach(outputPath => { // 缓存文件地址 @@ -56,7 +56,7 @@ export const getAutoUpdateConfig = (config: Config) => { immediate }; }; -export const getApis = (config: Config, projectPath: string = process.cwd()) => { +export const getApis = (config: Config, projectPath = process.cwd()) => { if (!config || !projectPath) { return []; } @@ -73,4 +73,3 @@ export const getApis = (config: Config, projectPath: string = process.cwd()) => }) .flat(2); }; -export default readConfig; diff --git a/packages/wormhole/src/utils/index.ts b/packages/wormhole/src/utils/index.ts index 0941d24..6cae549 100644 --- a/packages/wormhole/src/utils/index.ts +++ b/packages/wormhole/src/utils/index.ts @@ -1,7 +1,7 @@ /* eslint-disable no-bitwise */ import handlebars, { HelperOptions } from 'handlebars'; import fetch from 'node-fetch'; -import fs, { promises } from 'node:fs'; +import fs from 'node:fs/promises'; import path from 'node:path'; import { Config as PrettierConfig } from 'prettier'; import * as prettierBabel from 'prettier/plugins/babel'; @@ -69,10 +69,10 @@ handlebars.registerHelper( * @param view - 渲染模板所需的数据对象 * @returns 渲染后的内容 */ -export async function readAndRenderTemplate(templatePath: string, view: any): Promise { +export async function readAndRenderTemplate(templatePath: string, view: any) { let data = ''; try { - data = await promises.readFile(path.resolve(DEFAULT_CONFIG.templatePath, `${templatePath}.handlebars`), 'utf-8'); + data = await fs.readFile(path.resolve(DEFAULT_CONFIG.templatePath, `${templatePath}.handlebars`), 'utf-8'); } catch (error) { data = (await import(`./templates/${templatePath}.handlebars`)).default; } @@ -93,17 +93,14 @@ export async function format(text: string, config?: PrettierConfig) { * @param content 文件内容 */ export async function generateFile(distDir: string, fileName: string, content: string) { - if (!fs.existsSync(distDir)) { - fs.mkdirSync(distDir, { recursive: true }); + try { + await fs.access(distDir, fs.constants.F_OK); + } catch (error) { + await fs.mkdir(distDir, { recursive: true }); } const filePath = path.join(distDir, fileName); const formattedText = await format(content); - fs.writeFile(filePath, formattedText, (err: NodeJS.ErrnoException | null) => { - if (err) { - return console.error('Error writing file:', err); - } - // console.log('File written successfully at', filePath); - }); + await fs.writeFile(filePath, formattedText); } export async function fetchData(url: string) { return fetch(url).then(response => { diff --git a/packages/wormhole/test/__snapshots__/generate.spec.ts.snap b/packages/wormhole/test/__snapshots__/generate.spec.ts.snap new file mode 100644 index 0000000..884c3f1 --- /dev/null +++ b/packages/wormhole/test/__snapshots__/generate.spec.ts.snap @@ -0,0 +1,10881 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`generate API > should generate code with a variant of openapi file formats 1`] = ` +"/// +/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.57 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +export default { + 'clients.generateFromURL': ['GET', '/generate'], + 'servers.generateFromURL': ['GET', '/generate'], + 'documentation.generateFromURL': ['GET', '/generate'], + 'config.generateFromURL': ['GET', '/generate'], + 'clients.generate': ['POST', '/generate'], + 'servers.generate': ['POST', '/generate'], + 'documentation.generate': ['POST', '/generate'], + 'config.generate': ['POST', '/generate'], + 'clients.clientLanguages': ['GET', '/clients'], + 'documentation.clientLanguages': ['GET', '/clients'], + 'servers.serverLanguages': ['GET', '/servers'], + 'documentation.documentationLanguages': ['GET', '/documentation'], + 'clients.languages': ['GET', '/{type}/{version}'], + 'servers.languages': ['GET', '/{type}/{version}'], + 'documentation.languages': ['GET', '/{type}/{version}'], + 'config.languages': ['GET', '/{type}/{version}'], + 'clients.languagesMulti': ['GET', '/types'], + 'servers.languagesMulti': ['GET', '/types'], + 'documentation.languagesMulti': ['GET', '/types'], + 'config.languagesMulti': ['GET', '/types'], + 'clients.listOptions': ['GET', '/options'], + 'servers.listOptions': ['GET', '/options'], + 'documentation.listOptions': ['GET', '/options'], + 'config.listOptions': ['GET', '/options'], + 'clients.generateBundle': ['POST', '/model'], + 'servers.generateBundle': ['POST', '/model'], + 'documentation.generateBundle': ['POST', '/model'], + 'config.generateBundle': ['POST', '/model'], + 'documentation.renderTemplate': ['POST', '/render'] +}; +" +`; + +exports[`generate API > should generate code with a variant of openapi file formats 2`] = ` +"import { createAlova } from 'alova'; +import GlobalFetch from 'alova/GlobalFetch'; +import { createApis, withConfigType } from './createApis'; + +export const alovaInstance = createAlova({ + baseURL: '/api1', + requestAdapter: GlobalFetch(), + beforeRequest: method => {}, + responded: res => { + return res.json(); + } +}); + +export const $$userConfigMap = withConfigType({}); + +const Apis = createApis(alovaInstance, $$userConfigMap); + +export default Apis; +" +`; + +exports[`generate API > should generate code with a variant of openapi file formats 3`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.57 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, MethodType, AlovaMethodCreateConfig } from 'alova'; +import { Method } from 'alova'; +import apiDefinitions from './apiDefinitions'; + +const createFunctionalProxy = ( + array: (string | symbol)[], + alovaInstance: Alova, + configMap: any +) => { + // create a new proxy instance + return new Proxy(function () {}, { + get(_, property) { + // record the target property, so that it can get the completed accessing paths + array.push(property); + // always return a new proxy to continue recording accessing paths. + return createFunctionalProxy(array, alovaInstance, configMap); + }, + apply(_, __, [config]) { + const apiPathKey = array.join('.') as keyof typeof apiDefinitions; + const apiItem = apiDefinitions[apiPathKey]; + if (!apiItem) { + throw new Error(\`the api path of \\\`\${apiPathKey}\\\` is not found\`); + } + const mergedConfig = { + ...configMap[apiPathKey], + ...config + }; + const [method, url] = apiItem; + const { pathParams, data } = mergedConfig; + const urlReplaced = url.replace(/\\{([^}]+)\\}/g, (_, key) => { + const pathParam = pathParams[key]; + return pathParam; + }); + delete mergedConfig.pathParams; + return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data); + } + }); +}; + +export const createApis = (alovaInstance: Alova, configMap: any) => { + const Apis = new Proxy({} as Apis, { + get(_, property) { + return createFunctionalProxy([property], alovaInstance, configMap); + } + }); + // define global variable \`Apis\` + (globalThis as any).Apis = Apis; + return Apis; +}; +type MethodConfig = + (typeof import('./index'))['alovaInstance'] extends Alova + ? import('alova').AlovaMethodCreateConfig + : never; +type APISofParameters = Tag extends keyof Apis + ? Url extends keyof Apis[Tag] + ? Apis[Tag][Url] extends (...args: any) => any + ? Parameters + : any + : any + : any; +type MethodsConfigMap = { + [P in keyof typeof import('./apiDefinitions').default]?: MethodConfig< + P extends \`\${infer Tag}.\${infer Url}\` ? Parameters[0]['transformData']>[0] : any + >; +}; +export const withConfigType = (config: Config) => config; +" +`; + +exports[`generate API > should generate code with a variant of openapi file formats 4`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.57 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, AlovaMethodCreateConfig, Method } from 'alova'; +import type { $$userConfigMap, alovaInstance } from '.'; +import type apiDefinitions from './apiDefinitions'; + +type CollapsedAlova = typeof alovaInstance; +type UserMethodConfigMap = typeof $$userConfigMap; + +type Alova2MethodConfig = + CollapsedAlova extends Alova + ? Omit, 'params'> + : never; + +// Extract the return type of transformData function that define in $$userConfigMap, if it not exists, use the default type. +type ExtractUserDefinedTransformed< + DefinitionKey extends keyof typeof apiDefinitions, + Default +> = DefinitionKey extends keyof UserMethodConfigMap + ? UserMethodConfigMap[DefinitionKey]['transformData'] extends (...args: any[]) => any + ? Awaited> + : Default + : Default; +type Alova2Method< + Responded, + DefinitionKey extends keyof typeof apiDefinitions, + CurrentConfig extends Alova2MethodConfig +> = + CollapsedAlova extends Alova + ? Method< + State, + Export, + CurrentConfig extends undefined + ? ExtractUserDefinedTransformed + : CurrentConfig['transformData'] extends (...args: any[]) => any + ? Awaited> + : ExtractUserDefinedTransformed, + any, + RequestConfig, + Response, + ResponseHeader + > + : never; + +export type AuthorizationValue = { + /** + * Authorization value + */ + value?: string; + /** + * Authorization key + */ + keyName?: string; + /** + * Authorization type + */ + type?: 'query' | 'header'; +}; +export type Options = { + /** + * authorization + * --- + * adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + */ + auth?: string; + /** + * authorization + * --- + * adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + */ + authorizationValue?: AuthorizationValue; + /** + * api package + * --- + * package for generated api classes + */ + apiPackage?: string; + /** + * Template Version + * --- + * template version for generation + */ + templateVersion?: string; + /** + * model package + * --- + * package for generated models + */ + modelPackage?: string; + /** + * model name prefix + * --- + * Prefix that will be prepended to all model names. Default is the empty string. + */ + modelNamePrefix?: string; + /** + * model name suffix + * --- + * PrefixSuffix that will be appended to all model names. Default is the empty string. + */ + modelNameSuffix?: string; + /** + * System Properties + * --- + * sets specified system properties in key/value format + */ + systemProperties?: Record; + /** + * instantiation types + * --- + * sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + */ + instantiationTypes?: Record; + /** + * type mappings + * --- + * sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + */ + typeMappings?: Record; + /** + * additional properties + * --- + * sets additional properties that can be referenced by the mustache templates in key/value format. + */ + additionalProperties?: Record; + /** + * language specific primitives + * --- + * specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + */ + languageSpecificPrimitives?: string[]; + /** + * import mappings + * --- + * specifies mappings between a given class and the import that should be used for that class in key/value format. + */ + importMappings?: Record; + /** + * invoker package + * --- + * root package for generated code + */ + invokerPackage?: string; + /** + * group id + * --- + * groupId in generated pom.xml + */ + groupId?: string; + /** + * artifact id + * --- + * artifactId in generated pom.xml + */ + artifactId?: string; + /** + * artifact version + * --- + * artifact version generated in pom.xml + */ + artifactVersion?: string; + /** + * library + * --- + * library template (sub-template) + */ + library?: string; + /** + * git user id + * --- + * Git user ID, e.g. swagger-api. + */ + gitUserId?: string; + /** + * git repo id + * --- + * Git repo ID, e.g. swagger-codegen. + */ + gitRepoId?: string; + /** + * release note + * --- + * Release note, default to 'Minor update'. + */ + releaseNote?: string; + /** + * http user agent + * --- + * HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + */ + httpUserAgent?: string; + /** + * reserved words mappings + * --- + * pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + */ + reservedWordsMappings?: Record; + /** + * ignore file override location + * --- + * Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + */ + ignoreFileOverride?: string; + /** + * remove prefix of the operationId + * --- + * Remove prefix of operationId, e.g. config_getId => getId + */ + removeOperationIdPrefix?: boolean; + skipOverride?: boolean; +}; +export type GenerationRequest = { + /** + * language + * --- + * language to generate (required)456 + * [required] + */ + lang: string; + /** + * spec in json format. . Alternative to \`specURL\` + */ + spec?: object; + /** + * URL of the spec in json format. Alternative to \`spec\` + */ + specURL?: string; + /** + * type of the spec + */ + type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG'; + /** + * codegen version to use + */ + codegenVersion?: 'V2' | 'V3'; + options?: Options; +}; +export type CliOption = { + optionName?: string; + description?: string; + /** + * Data type is based on the types supported by the JSON-Schema + */ + type?: string; + enum?: Record; + default?: string; +}; +export type RenderRequest = { + /** + * template + * --- + * template as string + * [required] + */ + template: string; + /** + * context + * --- + * context as string + * [required] + */ + context: string; +}; +declare global { + interface Apis { + clients: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'client' or 'documentation' for given codegen version (defaults to V3) + * + * **path:** /clients + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * // flag to only return languages of type \`client\` + * clientOnly?: boolean + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + clientLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + /** + * flag to only return languages of type \`client\` + */ + clientOnly?: boolean; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'clients.listOptions', Config>; + /** + * --- + * + * [POST] 你好Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + servers: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'server' for given codegen version (defaults to V3) + * + * **path:** /servers + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + serverLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'servers.listOptions', Config>; + /** + * --- + * + * [POST] 你好Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + documentation: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'client' or 'documentation' for given codegen version (defaults to V3) + * + * **path:** /clients + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * // flag to only return languages of type \`client\` + * clientOnly?: boolean + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + clientLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + /** + * flag to only return languages of type \`client\` + */ + clientOnly?: boolean; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'documentation' for given codegen version (defaults to V3) + * + * **path:** /documentation + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + documentationLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'documentation.listOptions', Config>; + /** + * --- + * + * [POST] 你好Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] render a template using the provided data + * + * **path:** /render + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] template + * // template as string + * // [required] + * template: string + * // [title] context + * // context as string + * // [required] + * context: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + renderTemplate< + Config extends Alova2MethodConfig & { + data: RenderRequest; + } + >( + config: Config + ): Alova2Method; + }; + config: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'config.listOptions', Config>; + /** + * --- + * + * [POST] 你好Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + } + + var Apis: Apis; +} +" +`; + +exports[`generate API > should generate code with a variant of openapi file formats 5`] = ` +"/// +/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Petstore - version 1.0.7 + * + * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI version: 3.0.0 + * + * Contact: + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +export default { + 'pet.uploadFile': ['POST', '/pet/{petId}/uploadImage'], + 'pet.addPet': ['POST', '/pet'], + 'pet.updatePet': ['PUT', '/pet'], + 'pet.findPetsByStatus': ['GET', '/pet/findByStatus'], + 'pet.findPetsByTags': ['GET', '/pet/findByTags'], + 'pet.getPetById': ['GET', '/pet/{petId}'], + 'pet.updatePetWithForm': ['POST', '/pet/{petId}'], + 'pet.deletePet': ['DELETE', '/pet/{petId}'], + 'store.getInventory': ['GET', '/store/inventory'], + 'store.placeOrder': ['POST', '/store/order'], + 'store.getOrderById': ['GET', '/store/order/{orderId}'], + 'store.deleteOrder': ['DELETE', '/store/order/{orderId}'], + 'user.createUsersWithListInput': ['POST', '/user/createWithList'], + 'user.getUserByName': ['GET', '/user/{username}'], + 'user.updateUser': ['PUT', '/user/{username}'], + 'user.deleteUser': ['DELETE', '/user/{username}'], + 'user.loginUser': ['GET', '/user/login'], + 'user.logoutUser': ['GET', '/user/logout'], + 'user.createUsersWithArrayInput': ['POST', '/user/createWithArray'], + 'user.createUser': ['POST', '/user'] +}; +" +`; + +exports[`generate API > should generate code with a variant of openapi file formats 6`] = ` +"import { createAlova } from 'alova'; +import GlobalFetch from 'alova/GlobalFetch'; +import { createApis, withConfigType } from './createApis'; + +export const alovaInstance = createAlova({ + baseURL: 'https://petstore.swagger.io/v2', + requestAdapter: GlobalFetch(), + beforeRequest: method => {}, + responded: res => { + return res.json(); + } +}); + +export const $$userConfigMap = withConfigType({}); + +const Apis = createApis(alovaInstance, $$userConfigMap); + +export default Apis; +" +`; + +exports[`generate API > should generate code with a variant of openapi file formats 7`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Petstore - version 1.0.7 + * + * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI version: 3.0.0 + * + * Contact: + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, MethodType, AlovaMethodCreateConfig } from 'alova'; +import { Method } from 'alova'; +import apiDefinitions from './apiDefinitions'; + +const createFunctionalProxy = ( + array: (string | symbol)[], + alovaInstance: Alova, + configMap: any +) => { + // create a new proxy instance + return new Proxy(function () {}, { + get(_, property) { + // record the target property, so that it can get the completed accessing paths + array.push(property); + // always return a new proxy to continue recording accessing paths. + return createFunctionalProxy(array, alovaInstance, configMap); + }, + apply(_, __, [config]) { + const apiPathKey = array.join('.') as keyof typeof apiDefinitions; + const apiItem = apiDefinitions[apiPathKey]; + if (!apiItem) { + throw new Error(\`the api path of \\\`\${apiPathKey}\\\` is not found\`); + } + const mergedConfig = { + ...configMap[apiPathKey], + ...config + }; + const [method, url] = apiItem; + const { pathParams, data } = mergedConfig; + const urlReplaced = url.replace(/\\{([^}]+)\\}/g, (_, key) => { + const pathParam = pathParams[key]; + return pathParam; + }); + delete mergedConfig.pathParams; + return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data); + } + }); +}; + +export const createApis = (alovaInstance: Alova, configMap: any) => { + const Apis = new Proxy({} as Apis, { + get(_, property) { + return createFunctionalProxy([property], alovaInstance, configMap); + } + }); + // define global variable \`Apis\` + (globalThis as any).Apis = Apis; + return Apis; +}; +type MethodConfig = + (typeof import('./index'))['alovaInstance'] extends Alova + ? import('alova').AlovaMethodCreateConfig + : never; +type APISofParameters = Tag extends keyof Apis + ? Url extends keyof Apis[Tag] + ? Apis[Tag][Url] extends (...args: any) => any + ? Parameters + : any + : any + : any; +type MethodsConfigMap = { + [P in keyof typeof import('./apiDefinitions').default]?: MethodConfig< + P extends \`\${infer Tag}.\${infer Url}\` ? Parameters[0]['transformData']>[0] : any + >; +}; +export const withConfigType = (config: Config) => config; +" +`; + +exports[`generate API > should generate code with a variant of openapi file formats 8`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Petstore - version 1.0.7 + * + * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI version: 3.0.0 + * + * Contact: + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, AlovaMethodCreateConfig, Method } from 'alova'; +import type { $$userConfigMap, alovaInstance } from '.'; +import type apiDefinitions from './apiDefinitions'; + +type CollapsedAlova = typeof alovaInstance; +type UserMethodConfigMap = typeof $$userConfigMap; + +type Alova2MethodConfig = + CollapsedAlova extends Alova + ? Omit, 'params'> + : never; + +// Extract the return type of transformData function that define in $$userConfigMap, if it not exists, use the default type. +type ExtractUserDefinedTransformed< + DefinitionKey extends keyof typeof apiDefinitions, + Default +> = DefinitionKey extends keyof UserMethodConfigMap + ? UserMethodConfigMap[DefinitionKey]['transformData'] extends (...args: any[]) => any + ? Awaited> + : Default + : Default; +type Alova2Method< + Responded, + DefinitionKey extends keyof typeof apiDefinitions, + CurrentConfig extends Alova2MethodConfig +> = + CollapsedAlova extends Alova + ? Method< + State, + Export, + CurrentConfig extends undefined + ? ExtractUserDefinedTransformed + : CurrentConfig['transformData'] extends (...args: any[]) => any + ? Awaited> + : ExtractUserDefinedTransformed, + any, + RequestConfig, + Response, + ResponseHeader + > + : never; + +export type ApiResponse = { + code?: number; + type?: string; + message?: string; +}; +export type Category = { + id?: number; + name?: string; +}; +export type Tag = { + id?: number; + name?: string; +}; +export type Pet = { + id?: number; + category?: Category; + /** + * [required] + */ + name: string; + /** + * [required] + */ + photoUrls: string[]; + tags?: Tag[]; + /** + * pet status in the store + */ + status?: 'available' | 'pending' | 'sold'; +}; +export type Order = { + id?: number; + petId?: number; + quantity?: number; + shipDate?: string; + /** + * Order Status + */ + status?: 'placed' | 'approved' | 'delivered'; + complete?: boolean; +}; +export type User = { + id?: number; + username?: string; + firstName?: string; + lastName?: string; + email?: string; + password?: string; + phone?: string; + /** + * User Status + */ + userStatus?: number; +}; +declare global { + interface Apis { + pet: { + /** + * --- + * + * [POST] uploads an image + * + * **path:** /pet/{petId}/uploadImage + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // ID of pet to update + * // [required] + * petId: number + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // Additional data to pass to server + * additionalMetadata?: string + * // file to upload + * file?: Blob + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * code?: number + * type?: string + * message?: string + * } + * \`\`\` + */ + uploadFile< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of pet to update + * [required] + */ + petId: number; + }; + data: { + /** + * Additional data to pass to server + */ + additionalMetadata?: string; + /** + * file to upload + */ + file?: Blob; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Add a new pet to the store + * + * **path:** /pet + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * id?: number + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * status?: 'available' | 'pending' | 'sold' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + addPet< + Config extends Alova2MethodConfig & { + data: Pet; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [PUT] Update an existing pet + * + * **path:** /pet + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * id?: number + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * status?: 'available' | 'pending' | 'sold' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + updatePet< + Config extends Alova2MethodConfig & { + data: Pet; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Finds Pets by status + * + * **path:** /pet/findByStatus + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // Status values that need to be considered for filter + * // [required] + * status: ('available' | 'pending' | 'sold')[] + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Array<{ + * id?: number + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * status?: 'available' | 'pending' | 'sold' + * }> + * \`\`\` + */ + findPetsByStatus< + Config extends Alova2MethodConfig & { + params: { + /** + * Status values that need to be considered for filter + * [required] + */ + status: ('available' | 'pending' | 'sold')[]; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Finds Pets by tags + * + * **path:** /pet/findByTags + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // Tags to filter by + * // [required] + * tags: string[] + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Array<{ + * id?: number + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * status?: 'available' | 'pending' | 'sold' + * }> + * \`\`\` + */ + findPetsByTags< + Config extends Alova2MethodConfig & { + params: { + /** + * Tags to filter by + * [required] + */ + tags: string[]; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Find pet by ID + * + * **path:** /pet/{petId} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // ID of pet to return + * // [required] + * petId: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * id?: number + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * status?: 'available' | 'pending' | 'sold' + * } + * \`\`\` + */ + getPetById< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of pet to return + * [required] + */ + petId: number; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Updates a pet in the store with form data + * + * **path:** /pet/{petId} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // ID of pet that needs to be updated + * // [required] + * petId: number + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // Updated name of the pet + * name?: string + * // Updated status of the pet + * status?: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + updatePetWithForm< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of pet that needs to be updated + * [required] + */ + petId: number; + }; + data: { + /** + * Updated name of the pet + */ + name?: string; + /** + * Updated status of the pet + */ + status?: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [DELETE] Deletes a pet + * + * **path:** /pet/{petId} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // Pet id to delete + * // [required] + * petId: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + deletePet< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * Pet id to delete + * [required] + */ + petId: number; + }; + } + >( + config: Config + ): Alova2Method; + }; + store: { + /** + * --- + * + * [GET] Returns pet inventories by status + * + * **path:** /store/inventory + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record + * \`\`\` + */ + getInventory>>( + config?: Config + ): Alova2Method, 'store.getInventory', Config>; + /** + * --- + * + * [POST] Place an order for a pet + * + * **path:** /store/order + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * id?: number + * petId?: number + * quantity?: number + * shipDate?: string + * // Order Status + * status?: 'placed' | 'approved' | 'delivered' + * complete?: boolean + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * id?: number + * petId?: number + * quantity?: number + * shipDate?: string + * // Order Status + * status?: 'placed' | 'approved' | 'delivered' + * complete?: boolean + * } + * \`\`\` + */ + placeOrder< + Config extends Alova2MethodConfig & { + data: Order; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Find purchase order by ID + * + * **path:** /store/order/{orderId} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // ID of pet that needs to be fetched + * // [required] + * orderId: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * id?: number + * petId?: number + * quantity?: number + * shipDate?: string + * // Order Status + * status?: 'placed' | 'approved' | 'delivered' + * complete?: boolean + * } + * \`\`\` + */ + getOrderById< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of pet that needs to be fetched + * [required] + */ + orderId: number; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [DELETE] Delete purchase order by ID + * + * **path:** /store/order/{orderId} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // ID of the order that needs to be deleted + * // [required] + * orderId: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + deleteOrder< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of the order that needs to be deleted + * [required] + */ + orderId: number; + }; + } + >( + config: Config + ): Alova2Method; + }; + user: { + /** + * --- + * + * [POST] Creates list of users with given input array + * + * **path:** /user/createWithList + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = Array<{ + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * }> + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + createUsersWithListInput< + Config extends Alova2MethodConfig & { + data: User[]; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Get user by user name + * + * **path:** /user/{username} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // The name that needs to be fetched. Use user1 for testing. + * // [required] + * username: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * } + * \`\`\` + */ + getUserByName< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * The name that needs to be fetched. Use user1 for testing. + * [required] + */ + username: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [PUT] Updated user + * + * **path:** /user/{username} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // name that need to be updated + * // [required] + * username: string + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + updateUser< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * name that need to be updated + * [required] + */ + username: string; + }; + data: User; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [DELETE] Delete user + * + * **path:** /user/{username} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // The name that needs to be deleted + * // [required] + * username: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + deleteUser< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * The name that needs to be deleted + * [required] + */ + username: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Logs user into the system + * + * **path:** /user/login + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // The user name for login + * // [required] + * username: string + * // The password for login in clear text + * // [required] + * password: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string + * \`\`\` + */ + loginUser< + Config extends Alova2MethodConfig & { + params: { + /** + * The user name for login + * [required] + */ + username: string; + /** + * The password for login in clear text + * [required] + */ + password: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Logs out current logged in user session + * + * **path:** /user/logout + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + logoutUser>( + config?: Config + ): Alova2Method; + /** + * --- + * + * [POST] Creates list of users with given input array + * + * **path:** /user/createWithArray + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = Array<{ + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * }> + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + createUsersWithArrayInput< + Config extends Alova2MethodConfig & { + data: User[]; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Create user + * + * **path:** /user + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + createUser< + Config extends Alova2MethodConfig & { + data: User; + } + >( + config: Config + ): Alova2Method; + }; + } + + var Apis: Apis; +} +" +`; + +exports[`generate API > should generate code with a variant of openapi file formats 9`] = ` +"/// +/* tslint:disable */ +/* eslint-disable */ +/** + * OpenAPI Petstore - version 1.0.0 + * + * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI version: 3.0.0 + * + * Contact: + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +export default { + 'tag.pet24': ['POST', '/pet'], + 'pet.updatePet': ['PUT', '/pet'], + 'pet.findPetsByStatus': ['GET', '/pet/findByStatus'], + 'pet.findPetsByTags': ['GET', '/pet/findByTags'], + 'pet.getPetById': ['GET', '/pet/{petId}'], + 'pet.updatePetWithForm': ['POST', '/pet/{petId}'], + 'pet.deletePet': ['DELETE', '/pet/{petId}'], + 'pet.uploadFile': ['POST', '/pet/{petId}/uploadImage'], + 'store.getInventory': ['GET', '/store/inventory'], + 'store.placeOrder': ['POST', '/store/order'], + 'store.getOrderById': ['GET', '/store/order/{orderId}'], + 'store.deleteOrder': ['DELETE', '/store/order/{orderId}'], + 'user.createUser': ['POST', '/user'], + 'user.createUsersWithArrayInput': ['POST', '/user/createWithArray'], + 'user.createUsersWithListInput': ['POST', '/user/createWithList'], + 'user.loginUser': ['GET', '/user/login'], + 'user.logoutUser': ['GET', '/user/logout'], + 'user.getUserByName': ['GET', '/user/{username}'], + 'user.updateUser': ['PUT', '/user/{username}'], + 'user.deleteUser': ['DELETE', '/user/{username}'] +}; +" +`; + +exports[`generate API > should generate code with a variant of openapi file formats 10`] = ` +"import { createAlova } from 'alova'; +import GlobalFetch from 'alova/GlobalFetch'; +import { createApis, withConfigType } from './createApis'; + +export const alovaInstance = createAlova({ + baseURL: 'http://petstore.swagger.io/v2', + requestAdapter: GlobalFetch(), + beforeRequest: method => {}, + responded: res => { + return res.json(); + } +}); + +export const $$userConfigMap = withConfigType({}); + +const Apis = createApis(alovaInstance, $$userConfigMap); + +export default Apis; +" +`; + +exports[`generate API > should generate code with a variant of openapi file formats 11`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * OpenAPI Petstore - version 1.0.0 + * + * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI version: 3.0.0 + * + * Contact: + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, MethodType, AlovaMethodCreateConfig } from 'alova'; +import { Method } from 'alova'; +import apiDefinitions from './apiDefinitions'; + +const createFunctionalProxy = ( + array: (string | symbol)[], + alovaInstance: Alova, + configMap: any +) => { + // create a new proxy instance + return new Proxy(function () {}, { + get(_, property) { + // record the target property, so that it can get the completed accessing paths + array.push(property); + // always return a new proxy to continue recording accessing paths. + return createFunctionalProxy(array, alovaInstance, configMap); + }, + apply(_, __, [config]) { + const apiPathKey = array.join('.') as keyof typeof apiDefinitions; + const apiItem = apiDefinitions[apiPathKey]; + if (!apiItem) { + throw new Error(\`the api path of \\\`\${apiPathKey}\\\` is not found\`); + } + const mergedConfig = { + ...configMap[apiPathKey], + ...config + }; + const [method, url] = apiItem; + const { pathParams, data } = mergedConfig; + const urlReplaced = url.replace(/\\{([^}]+)\\}/g, (_, key) => { + const pathParam = pathParams[key]; + return pathParam; + }); + delete mergedConfig.pathParams; + return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data); + } + }); +}; + +export const createApis = (alovaInstance: Alova, configMap: any) => { + const Apis = new Proxy({} as Apis, { + get(_, property) { + return createFunctionalProxy([property], alovaInstance, configMap); + } + }); + // define global variable \`Apis\` + (globalThis as any).Apis = Apis; + return Apis; +}; +type MethodConfig = + (typeof import('./index'))['alovaInstance'] extends Alova + ? import('alova').AlovaMethodCreateConfig + : never; +type APISofParameters = Tag extends keyof Apis + ? Url extends keyof Apis[Tag] + ? Apis[Tag][Url] extends (...args: any) => any + ? Parameters + : any + : any + : any; +type MethodsConfigMap = { + [P in keyof typeof import('./apiDefinitions').default]?: MethodConfig< + P extends \`\${infer Tag}.\${infer Url}\` ? Parameters[0]['transformData']>[0] : any + >; +}; +export const withConfigType = (config: Config) => config; +" +`; + +exports[`generate API > should generate code with a variant of openapi file formats 12`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * OpenAPI Petstore - version 1.0.0 + * + * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI version: 3.0.0 + * + * Contact: + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, AlovaMethodCreateConfig, Method } from 'alova'; +import type { $$userConfigMap, alovaInstance } from '.'; +import type apiDefinitions from './apiDefinitions'; + +type CollapsedAlova = typeof alovaInstance; +type UserMethodConfigMap = typeof $$userConfigMap; + +type Alova2MethodConfig = + CollapsedAlova extends Alova + ? Omit, 'params'> + : never; + +// Extract the return type of transformData function that define in $$userConfigMap, if it not exists, use the default type. +type ExtractUserDefinedTransformed< + DefinitionKey extends keyof typeof apiDefinitions, + Default +> = DefinitionKey extends keyof UserMethodConfigMap + ? UserMethodConfigMap[DefinitionKey]['transformData'] extends (...args: any[]) => any + ? Awaited> + : Default + : Default; +type Alova2Method< + Responded, + DefinitionKey extends keyof typeof apiDefinitions, + CurrentConfig extends Alova2MethodConfig +> = + CollapsedAlova extends Alova + ? Method< + State, + Export, + CurrentConfig extends undefined + ? ExtractUserDefinedTransformed + : CurrentConfig['transformData'] extends (...args: any[]) => any + ? Awaited> + : ExtractUserDefinedTransformed, + any, + RequestConfig, + Response, + ResponseHeader + > + : never; + +export type Category = { + id?: number; + name?: string; +}; +export type Tag = { + id?: number; + name?: string; +}; +export type Pet = { + id?: number; + /** + * Pet category + * --- + * A category for a pet + */ + category?: Category; + /** + * [required] + */ + name: string; + /** + * [required] + */ + photoUrls: string[]; + tags?: Tag[]; + /** + * pet status in the store + * @deprecated + */ + status?: 'available' | 'pending' | 'sold'; +}; +export type ApiResponse = { + code?: number; + type?: string; + message?: string; +}; +export type Order = { + id?: number; + petId?: number; + quantity?: number; + shipDate?: string; + /** + * Order Status + */ + status?: 'placed' | 'approved' | 'delivered'; + complete?: boolean; +}; +export type User = { + id?: number; + username?: string; + firstName?: string; + lastName?: string; + email?: string; + password?: string; + phone?: string; + /** + * User Status + */ + userStatus?: number; +}; +declare global { + interface Apis { + tag: { + /** + * --- + * + * [POST] Add a new pet to the store 2 + * + * **path:** /pet + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * id?: number + * // [title] Pet category + * // A category for a pet + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * // [deprecated] + * status?: 'available' | 'pending' | 'sold' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * id?: number + * // [title] Pet category + * // A category for a pet + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * // [deprecated] + * status?: 'available' | 'pending' | 'sold' + * } + * \`\`\` + */ + pet24< + Config extends Alova2MethodConfig & { + data: Pet; + } + >( + config: Config + ): Alova2Method; + }; + pet: { + /** + * --- + * + * [PUT] Update an existing pet 2 + * + * **path:** /pet + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * id?: number + * // [title] Pet category + * // A category for a pet + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * // [deprecated] + * status?: 'available' | 'pending' | 'sold' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * id?: number + * // [title] Pet category + * // A category for a pet + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * // [deprecated] + * status?: 'available' | 'pending' | 'sold' + * } + * \`\`\` + */ + updatePet< + Config extends Alova2MethodConfig & { + data: Pet; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Finds Pets by status + * + * **path:** /pet/findByStatus + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // Status values that need to be considered for filter + * // [required] + * // [deprecated] + * status: ('available' | 'pending' | 'sold')[] + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Array<{ + * id?: number + * // [title] Pet category + * // A category for a pet + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * // [deprecated] + * status?: 'available' | 'pending' | 'sold' + * }> + * \`\`\` + */ + findPetsByStatus< + Config extends Alova2MethodConfig & { + params: { + /** + * Status values that need to be considered for filter + * [required] + * @deprecated + */ + status: ('available' | 'pending' | 'sold')[]; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Finds Pets by tags + * + * **path:** /pet/findByTags + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // Tags to filter by + * // [required] + * tags: string[] + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Array<{ + * id?: number + * // [title] Pet category + * // A category for a pet + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * // [deprecated] + * status?: 'available' | 'pending' | 'sold' + * }> + * \`\`\` + */ + findPetsByTags< + Config extends Alova2MethodConfig & { + params: { + /** + * Tags to filter by + * [required] + */ + tags: string[]; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Find pet by ID + * + * **path:** /pet/{petId} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // ID of pet to return + * // [required] + * petId: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * id?: number + * // [title] Pet category + * // A category for a pet + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * // [deprecated] + * status?: 'available' | 'pending' | 'sold' + * } + * \`\`\` + */ + getPetById< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of pet to return + * [required] + */ + petId: number; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Updates a pet in the store with form data + * + * **path:** /pet/{petId} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // ID of pet that needs to be updated + * // [required] + * petId: number + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // Updated name of the pet + * name?: string + * // Updated status of the pet + * status?: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + updatePetWithForm< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of pet that needs to be updated + * [required] + */ + petId: number; + }; + data: { + /** + * Updated name of the pet + */ + name?: string; + /** + * Updated status of the pet + */ + status?: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [DELETE] Deletes a pet + * + * **path:** /pet/{petId} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // Pet id to delete + * // [required] + * petId: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + deletePet< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * Pet id to delete + * [required] + */ + petId: number; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] uploads an image + * + * **path:** /pet/{petId}/uploadImage + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // ID of pet to update + * // [required] + * petId: number + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // Additional data to pass to server + * additionalMetadata?: string + * // file to upload + * file?: Blob + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * code?: number + * type?: string + * message?: string + * } + * \`\`\` + */ + uploadFile< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of pet to update + * [required] + */ + petId: number; + }; + data: { + /** + * Additional data to pass to server + */ + additionalMetadata?: string; + /** + * file to upload + */ + file?: Blob; + }; + } + >( + config: Config + ): Alova2Method; + }; + store: { + /** + * --- + * + * [GET] Returns pet inventories by status + * + * **path:** /store/inventory + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record + * \`\`\` + */ + getInventory>>( + config?: Config + ): Alova2Method, 'store.getInventory', Config>; + /** + * --- + * + * [POST] Place an order for a pet + * + * **path:** /store/order + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * id?: number + * petId?: number + * quantity?: number + * shipDate?: string + * // Order Status + * status?: 'placed' | 'approved' | 'delivered' + * complete?: boolean + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * id?: number + * petId?: number + * quantity?: number + * shipDate?: string + * // Order Status + * status?: 'placed' | 'approved' | 'delivered' + * complete?: boolean + * } + * \`\`\` + */ + placeOrder< + Config extends Alova2MethodConfig & { + data: Order; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Find purchase order by ID + * + * **path:** /store/order/{orderId} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // ID of pet that needs to be fetched + * // [required] + * orderId: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * id?: number + * petId?: number + * quantity?: number + * shipDate?: string + * // Order Status + * status?: 'placed' | 'approved' | 'delivered' + * complete?: boolean + * } + * \`\`\` + */ + getOrderById< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of pet that needs to be fetched + * [required] + */ + orderId: number; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [DELETE] Delete purchase order by ID + * + * **path:** /store/order/{orderId} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // ID of the order that needs to be deleted + * // [required] + * orderId: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + deleteOrder< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of the order that needs to be deleted + * [required] + */ + orderId: string; + }; + } + >( + config: Config + ): Alova2Method; + }; + user: { + /** + * --- + * + * [POST] Create user + * + * **path:** /user + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + createUser< + Config extends Alova2MethodConfig & { + data: User; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Creates list of users with given input array + * + * **path:** /user/createWithArray + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = Array<{ + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * }> + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + createUsersWithArrayInput< + Config extends Alova2MethodConfig & { + data: User[]; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Creates list of users with given input array + * + * **path:** /user/createWithList + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = Array<{ + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * }> + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + createUsersWithListInput< + Config extends Alova2MethodConfig & { + data: User[]; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Logs user into the system + * + * **path:** /user/login + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // The user name for login + * // [required] + * username: string + * // The password for login in clear text + * // [required] + * password: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string + * \`\`\` + */ + loginUser< + Config extends Alova2MethodConfig & { + params: { + /** + * The user name for login + * [required] + */ + username: string; + /** + * The password for login in clear text + * [required] + */ + password: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Logs out current logged in user session + * + * **path:** /user/logout + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + logoutUser>( + config?: Config + ): Alova2Method; + /** + * --- + * + * [GET] Get user by user name + * + * **path:** /user/{username} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // The name that needs to be fetched. Use user1 for testing. + * // [required] + * username: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * } + * \`\`\` + */ + getUserByName< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * The name that needs to be fetched. Use user1 for testing. + * [required] + */ + username: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [PUT] Updated user + * + * **path:** /user/{username} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // name that need to be deleted + * // [required] + * username: string + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + updateUser< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * name that need to be deleted + * [required] + */ + username: string; + }; + data: User; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [DELETE] Delete user + * + * **path:** /user/{username} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // The name that needs to be deleted + * // [required] + * username: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + deleteUser< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * The name that needs to be deleted + * [required] + */ + username: string; + }; + } + >( + config: Config + ): Alova2Method; + }; + } + + var Apis: Apis; +} +" +`; + +exports[`generate API > should generate target versioned code 1`] = ` +"/// +/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.57 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +export default { + 'clients.generateFromURL': ['GET', '/generate'], + 'servers.generateFromURL': ['GET', '/generate'], + 'documentation.generateFromURL': ['GET', '/generate'], + 'config.generateFromURL': ['GET', '/generate'], + 'clients.generate': ['POST', '/generate'], + 'servers.generate': ['POST', '/generate'], + 'documentation.generate': ['POST', '/generate'], + 'config.generate': ['POST', '/generate'], + 'clients.clientLanguages': ['GET', '/clients'], + 'documentation.clientLanguages': ['GET', '/clients'], + 'servers.serverLanguages': ['GET', '/servers'], + 'documentation.documentationLanguages': ['GET', '/documentation'], + 'clients.languages': ['GET', '/{type}/{version}'], + 'servers.languages': ['GET', '/{type}/{version}'], + 'documentation.languages': ['GET', '/{type}/{version}'], + 'config.languages': ['GET', '/{type}/{version}'], + 'clients.languagesMulti': ['GET', '/types'], + 'servers.languagesMulti': ['GET', '/types'], + 'documentation.languagesMulti': ['GET', '/types'], + 'config.languagesMulti': ['GET', '/types'], + 'clients.listOptions': ['GET', '/options'], + 'servers.listOptions': ['GET', '/options'], + 'documentation.listOptions': ['GET', '/options'], + 'config.listOptions': ['GET', '/options'], + 'clients.generateBundle': ['POST', '/model'], + 'servers.generateBundle': ['POST', '/model'], + 'documentation.generateBundle': ['POST', '/model'], + 'config.generateBundle': ['POST', '/model'], + 'documentation.renderTemplate': ['POST', '/render'] +}; +" +`; + +exports[`generate API > should generate target versioned code 2`] = ` +"import { createAlova } from 'alova'; +import GlobalFetch from 'alova/GlobalFetch'; +import { createApis, withConfigType } from './createApis'; + +export const alovaInstance = createAlova({ + baseURL: '/api1', + requestAdapter: GlobalFetch(), + beforeRequest: method => {}, + responded: res => { + return res.json(); + } +}); + +export const $$userConfigMap = withConfigType({}); + +const Apis = createApis(alovaInstance, $$userConfigMap); + +export default Apis; +" +`; + +exports[`generate API > should generate target versioned code 3`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.57 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, MethodType, AlovaMethodCreateConfig } from 'alova'; +import { Method } from 'alova'; +import apiDefinitions from './apiDefinitions'; + +const createFunctionalProxy = ( + array: (string | symbol)[], + alovaInstance: Alova, + configMap: any +) => { + // create a new proxy instance + return new Proxy(function () {}, { + get(_, property) { + // record the target property, so that it can get the completed accessing paths + array.push(property); + // always return a new proxy to continue recording accessing paths. + return createFunctionalProxy(array, alovaInstance, configMap); + }, + apply(_, __, [config]) { + const apiPathKey = array.join('.') as keyof typeof apiDefinitions; + const apiItem = apiDefinitions[apiPathKey]; + if (!apiItem) { + throw new Error(\`the api path of \\\`\${apiPathKey}\\\` is not found\`); + } + const mergedConfig = { + ...configMap[apiPathKey], + ...config + }; + const [method, url] = apiItem; + const { pathParams, data } = mergedConfig; + const urlReplaced = url.replace(/\\{([^}]+)\\}/g, (_, key) => { + const pathParam = pathParams[key]; + return pathParam; + }); + delete mergedConfig.pathParams; + return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data); + } + }); +}; + +export const createApis = (alovaInstance: Alova, configMap: any) => { + const Apis = new Proxy({} as Apis, { + get(_, property) { + return createFunctionalProxy([property], alovaInstance, configMap); + } + }); + // define global variable \`Apis\` + (globalThis as any).Apis = Apis; + return Apis; +}; +type MethodConfig = + (typeof import('./index'))['alovaInstance'] extends Alova + ? import('alova').AlovaMethodCreateConfig + : never; +type APISofParameters = Tag extends keyof Apis + ? Url extends keyof Apis[Tag] + ? Apis[Tag][Url] extends (...args: any) => any + ? Parameters + : any + : any + : any; +type MethodsConfigMap = { + [P in keyof typeof import('./apiDefinitions').default]?: MethodConfig< + P extends \`\${infer Tag}.\${infer Url}\` ? Parameters[0]['transformData']>[0] : any + >; +}; +export const withConfigType = (config: Config) => config; +" +`; + +exports[`generate API > should generate target versioned code 4`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.57 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, AlovaMethodCreateConfig, Method } from 'alova'; +import type { $$userConfigMap, alovaInstance } from '.'; +import type apiDefinitions from './apiDefinitions'; + +type CollapsedAlova = typeof alovaInstance; +type UserMethodConfigMap = typeof $$userConfigMap; + +type Alova2MethodConfig = + CollapsedAlova extends Alova + ? Omit, 'params'> + : never; + +// Extract the return type of transformData function that define in $$userConfigMap, if it not exists, use the default type. +type ExtractUserDefinedTransformed< + DefinitionKey extends keyof typeof apiDefinitions, + Default +> = DefinitionKey extends keyof UserMethodConfigMap + ? UserMethodConfigMap[DefinitionKey]['transformData'] extends (...args: any[]) => any + ? Awaited> + : Default + : Default; +type Alova2Method< + Responded, + DefinitionKey extends keyof typeof apiDefinitions, + CurrentConfig extends Alova2MethodConfig +> = + CollapsedAlova extends Alova + ? Method< + State, + Export, + CurrentConfig extends undefined + ? ExtractUserDefinedTransformed + : CurrentConfig['transformData'] extends (...args: any[]) => any + ? Awaited> + : ExtractUserDefinedTransformed, + any, + RequestConfig, + Response, + ResponseHeader + > + : never; + +export type AuthorizationValue = { + /** + * Authorization value + */ + value?: string; + /** + * Authorization key + */ + keyName?: string; + /** + * Authorization type + */ + type?: 'query' | 'header'; +}; +export type Options = { + /** + * authorization + * --- + * adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + */ + auth?: string; + /** + * authorization + * --- + * adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + */ + authorizationValue?: AuthorizationValue; + /** + * api package + * --- + * package for generated api classes + */ + apiPackage?: string; + /** + * Template Version + * --- + * template version for generation + */ + templateVersion?: string; + /** + * model package + * --- + * package for generated models + */ + modelPackage?: string; + /** + * model name prefix + * --- + * Prefix that will be prepended to all model names. Default is the empty string. + */ + modelNamePrefix?: string; + /** + * model name suffix + * --- + * PrefixSuffix that will be appended to all model names. Default is the empty string. + */ + modelNameSuffix?: string; + /** + * System Properties + * --- + * sets specified system properties in key/value format + */ + systemProperties?: Record; + /** + * instantiation types + * --- + * sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + */ + instantiationTypes?: Record; + /** + * type mappings + * --- + * sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + */ + typeMappings?: Record; + /** + * additional properties + * --- + * sets additional properties that can be referenced by the mustache templates in key/value format. + */ + additionalProperties?: Record; + /** + * language specific primitives + * --- + * specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + */ + languageSpecificPrimitives?: string[]; + /** + * import mappings + * --- + * specifies mappings between a given class and the import that should be used for that class in key/value format. + */ + importMappings?: Record; + /** + * invoker package + * --- + * root package for generated code + */ + invokerPackage?: string; + /** + * group id + * --- + * groupId in generated pom.xml + */ + groupId?: string; + /** + * artifact id + * --- + * artifactId in generated pom.xml + */ + artifactId?: string; + /** + * artifact version + * --- + * artifact version generated in pom.xml + */ + artifactVersion?: string; + /** + * library + * --- + * library template (sub-template) + */ + library?: string; + /** + * git user id + * --- + * Git user ID, e.g. swagger-api. + */ + gitUserId?: string; + /** + * git repo id + * --- + * Git repo ID, e.g. swagger-codegen. + */ + gitRepoId?: string; + /** + * release note + * --- + * Release note, default to 'Minor update'. + */ + releaseNote?: string; + /** + * http user agent + * --- + * HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + */ + httpUserAgent?: string; + /** + * reserved words mappings + * --- + * pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + */ + reservedWordsMappings?: Record; + /** + * ignore file override location + * --- + * Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + */ + ignoreFileOverride?: string; + /** + * remove prefix of the operationId + * --- + * Remove prefix of operationId, e.g. config_getId => getId + */ + removeOperationIdPrefix?: boolean; + skipOverride?: boolean; +}; +export type GenerationRequest = { + /** + * language + * --- + * language to generate (required)456 + * [required] + */ + lang: string; + /** + * spec in json format. . Alternative to \`specURL\` + */ + spec?: object; + /** + * URL of the spec in json format. Alternative to \`spec\` + */ + specURL?: string; + /** + * type of the spec + */ + type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG'; + /** + * codegen version to use + */ + codegenVersion?: 'V2' | 'V3'; + options?: Options; +}; +export type CliOption = { + optionName?: string; + description?: string; + /** + * Data type is based on the types supported by the JSON-Schema + */ + type?: string; + enum?: Record; + default?: string; +}; +export type RenderRequest = { + /** + * template + * --- + * template as string + * [required] + */ + template: string; + /** + * context + * --- + * context as string + * [required] + */ + context: string; +}; +declare global { + interface Apis { + clients: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'client' or 'documentation' for given codegen version (defaults to V3) + * + * **path:** /clients + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * // flag to only return languages of type \`client\` + * clientOnly?: boolean + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + clientLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + /** + * flag to only return languages of type \`client\` + */ + clientOnly?: boolean; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'clients.listOptions', Config>; + /** + * --- + * + * [POST] 你好Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + servers: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'server' for given codegen version (defaults to V3) + * + * **path:** /servers + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + serverLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'servers.listOptions', Config>; + /** + * --- + * + * [POST] 你好Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + documentation: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'client' or 'documentation' for given codegen version (defaults to V3) + * + * **path:** /clients + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * // flag to only return languages of type \`client\` + * clientOnly?: boolean + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + clientLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + /** + * flag to only return languages of type \`client\` + */ + clientOnly?: boolean; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'documentation' for given codegen version (defaults to V3) + * + * **path:** /documentation + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + documentationLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'documentation.listOptions', Config>; + /** + * --- + * + * [POST] 你好Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] render a template using the provided data + * + * **path:** /render + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] template + * // template as string + * // [required] + * template: string + * // [title] context + * // context as string + * // [required] + * context: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + renderTemplate< + Config extends Alova2MethodConfig & { + data: RenderRequest; + } + >( + config: Config + ): Alova2Method; + }; + config: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'config.listOptions', Config>; + /** + * --- + * + * [POST] 你好Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + } + + var Apis: Apis; +} +" +`; + +exports[`generate API > should generate target versioned code 5`] = ` +"/// +/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.57 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +export default { + 'clients.generateFromURL': ['GET', '/generate'], + 'servers.generateFromURL': ['GET', '/generate'], + 'documentation.generateFromURL': ['GET', '/generate'], + 'config.generateFromURL': ['GET', '/generate'], + 'clients.generate': ['POST', '/generate'], + 'servers.generate': ['POST', '/generate'], + 'documentation.generate': ['POST', '/generate'], + 'config.generate': ['POST', '/generate'], + 'clients.clientLanguages': ['GET', '/clients'], + 'documentation.clientLanguages': ['GET', '/clients'], + 'servers.serverLanguages': ['GET', '/servers'], + 'documentation.documentationLanguages': ['GET', '/documentation'], + 'clients.languages': ['GET', '/{type}/{version}'], + 'servers.languages': ['GET', '/{type}/{version}'], + 'documentation.languages': ['GET', '/{type}/{version}'], + 'config.languages': ['GET', '/{type}/{version}'], + 'clients.languagesMulti': ['GET', '/types'], + 'servers.languagesMulti': ['GET', '/types'], + 'documentation.languagesMulti': ['GET', '/types'], + 'config.languagesMulti': ['GET', '/types'], + 'clients.listOptions': ['GET', '/options'], + 'servers.listOptions': ['GET', '/options'], + 'documentation.listOptions': ['GET', '/options'], + 'config.listOptions': ['GET', '/options'], + 'clients.generateBundle': ['POST', '/model'], + 'servers.generateBundle': ['POST', '/model'], + 'documentation.generateBundle': ['POST', '/model'], + 'config.generateBundle': ['POST', '/model'], + 'documentation.renderTemplate': ['POST', '/render'] +}; +" +`; + +exports[`generate API > should generate target versioned code 6`] = ` +"import { createAlova } from 'alova'; +import fetchAdapter from 'alova/fetch'; +import { createApis, withConfigType } from './createApis'; + +export const alovaInstance = createAlova({ + baseURL: '/api1', + requestAdapter: fetchAdapter(), + beforeRequest: method => {}, + responded: res => { + return res.json(); + } +}); + +export const $$userConfigMap = withConfigType({}); + +const Apis = createApis(alovaInstance, $$userConfigMap); + +export default Apis; +" +`; + +exports[`generate API > should generate target versioned code 7`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.57 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, MethodType, AlovaGenerics, AlovaMethodCreateConfig } from 'alova'; +import { Method } from 'alova'; +import apiDefinitions from './apiDefinitions'; + +const createFunctionalProxy = (array: (string | symbol)[], alovaInstance: Alova, configMap: any) => { + // create a new proxy instance + return new Proxy(function () {}, { + get(_, property) { + // record the target property, so that it can get the completed accessing paths + array.push(property); + // always return a new proxy to continue recording accessing paths. + return createFunctionalProxy(array, alovaInstance, configMap); + }, + apply(_, __, [config]) { + const apiPathKey = array.join('.') as keyof typeof apiDefinitions; + const apiItem = apiDefinitions[apiPathKey]; + if (!apiItem) { + throw new Error(\`the api path of \\\`\${apiPathKey}\\\` is not found\`); + } + const mergedConfig = { + ...configMap[apiPathKey], + ...config + }; + const [method, url] = apiItem; + const { pathParams, data } = mergedConfig; + const urlReplaced = url.replace(/\\{([^}]+)\\}/g, (_, key) => { + const pathParam = pathParams[key]; + return pathParam; + }); + delete mergedConfig.pathParams; + return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data); + } + }); +}; + +export const createApis = (alovaInstance: Alova, configMap: any) => { + const Apis = new Proxy({} as Apis, { + get(_, property) { + return createFunctionalProxy([property], alovaInstance, configMap); + } + }); + // define global variable \`Apis\` + (globalThis as any).Apis = Apis; + return Apis; +}; +type MethodConfig = AlovaMethodCreateConfig< + (typeof import('./index'))['alovaInstance'] extends Alova ? AG : any, + any, + T +>; +type APISofParameters = Tag extends keyof Apis + ? Url extends keyof Apis[Tag] + ? Apis[Tag][Url] extends (...args: any) => any + ? Parameters + : any + : any + : any; +type MethodsConfigMap = { + [P in keyof typeof import('./apiDefinitions').default]?: MethodConfig< + P extends \`\${infer Tag}.\${infer Url}\` ? Parameters[0]['transform']>[0] : any + >; +}; +export const withConfigType = (config: Config) => config; +" +`; + +exports[`generate API > should generate target versioned code 8`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.57 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, AlovaMethodCreateConfig, AlovaGenerics, Method } from 'alova'; +import type { $$userConfigMap, alovaInstance } from '.'; +import type apiDefinitions from './apiDefinitions'; + +type CollapsedAlova = typeof alovaInstance; +type UserMethodConfigMap = typeof $$userConfigMap; + +type Alova2MethodConfig = + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Omit< + AlovaMethodCreateConfig< + AlovaGenerics, + any, + Responded + >, + 'params' + > + : never; + +// Extract the return type of transform function that define in $$userConfigMap, if it not exists, use the default type. +type ExtractUserDefinedTransformed< + DefinitionKey extends keyof typeof apiDefinitions, + Default +> = DefinitionKey extends keyof UserMethodConfigMap + ? UserMethodConfigMap[DefinitionKey]['transform'] extends (...args: any[]) => any + ? Awaited> + : Default + : Default; +type Alova2Method< + Responded, + DefinitionKey extends keyof typeof apiDefinitions, + CurrentConfig extends Alova2MethodConfig +> = + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Method< + AlovaGenerics< + CurrentConfig extends undefined + ? ExtractUserDefinedTransformed + : CurrentConfig['transform'] extends (...args: any[]) => any + ? Awaited> + : ExtractUserDefinedTransformed, + any, + RequestConfig, + Response, + ResponseHeader, + L1Cache, + L2Cache, + SE + > + > + : never; + +export type AuthorizationValue = { + /** + * Authorization value + */ + value?: string; + /** + * Authorization key + */ + keyName?: string; + /** + * Authorization type + */ + type?: 'query' | 'header'; +}; +export type Options = { + /** + * authorization + * --- + * adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + */ + auth?: string; + /** + * authorization + * --- + * adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + */ + authorizationValue?: AuthorizationValue; + /** + * api package + * --- + * package for generated api classes + */ + apiPackage?: string; + /** + * Template Version + * --- + * template version for generation + */ + templateVersion?: string; + /** + * model package + * --- + * package for generated models + */ + modelPackage?: string; + /** + * model name prefix + * --- + * Prefix that will be prepended to all model names. Default is the empty string. + */ + modelNamePrefix?: string; + /** + * model name suffix + * --- + * PrefixSuffix that will be appended to all model names. Default is the empty string. + */ + modelNameSuffix?: string; + /** + * System Properties + * --- + * sets specified system properties in key/value format + */ + systemProperties?: Record; + /** + * instantiation types + * --- + * sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + */ + instantiationTypes?: Record; + /** + * type mappings + * --- + * sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + */ + typeMappings?: Record; + /** + * additional properties + * --- + * sets additional properties that can be referenced by the mustache templates in key/value format. + */ + additionalProperties?: Record; + /** + * language specific primitives + * --- + * specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + */ + languageSpecificPrimitives?: string[]; + /** + * import mappings + * --- + * specifies mappings between a given class and the import that should be used for that class in key/value format. + */ + importMappings?: Record; + /** + * invoker package + * --- + * root package for generated code + */ + invokerPackage?: string; + /** + * group id + * --- + * groupId in generated pom.xml + */ + groupId?: string; + /** + * artifact id + * --- + * artifactId in generated pom.xml + */ + artifactId?: string; + /** + * artifact version + * --- + * artifact version generated in pom.xml + */ + artifactVersion?: string; + /** + * library + * --- + * library template (sub-template) + */ + library?: string; + /** + * git user id + * --- + * Git user ID, e.g. swagger-api. + */ + gitUserId?: string; + /** + * git repo id + * --- + * Git repo ID, e.g. swagger-codegen. + */ + gitRepoId?: string; + /** + * release note + * --- + * Release note, default to 'Minor update'. + */ + releaseNote?: string; + /** + * http user agent + * --- + * HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + */ + httpUserAgent?: string; + /** + * reserved words mappings + * --- + * pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + */ + reservedWordsMappings?: Record; + /** + * ignore file override location + * --- + * Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + */ + ignoreFileOverride?: string; + /** + * remove prefix of the operationId + * --- + * Remove prefix of operationId, e.g. config_getId => getId + */ + removeOperationIdPrefix?: boolean; + skipOverride?: boolean; +}; +export type GenerationRequest = { + /** + * language + * --- + * language to generate (required)456 + * [required] + */ + lang: string; + /** + * spec in json format. . Alternative to \`specURL\` + */ + spec?: object; + /** + * URL of the spec in json format. Alternative to \`spec\` + */ + specURL?: string; + /** + * type of the spec + */ + type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG'; + /** + * codegen version to use + */ + codegenVersion?: 'V2' | 'V3'; + options?: Options; +}; +export type CliOption = { + optionName?: string; + description?: string; + /** + * Data type is based on the types supported by the JSON-Schema + */ + type?: string; + enum?: Record; + default?: string; +}; +export type RenderRequest = { + /** + * template + * --- + * template as string + * [required] + */ + template: string; + /** + * context + * --- + * context as string + * [required] + */ + context: string; +}; +declare global { + interface Apis { + clients: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'client' or 'documentation' for given codegen version (defaults to V3) + * + * **path:** /clients + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * // flag to only return languages of type \`client\` + * clientOnly?: boolean + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + clientLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + /** + * flag to only return languages of type \`client\` + */ + clientOnly?: boolean; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'clients.listOptions', Config>; + /** + * --- + * + * [POST] 你好Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + servers: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'server' for given codegen version (defaults to V3) + * + * **path:** /servers + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + serverLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'servers.listOptions', Config>; + /** + * --- + * + * [POST] 你好Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + documentation: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'client' or 'documentation' for given codegen version (defaults to V3) + * + * **path:** /clients + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * // flag to only return languages of type \`client\` + * clientOnly?: boolean + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + clientLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + /** + * flag to only return languages of type \`client\` + */ + clientOnly?: boolean; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'documentation' for given codegen version (defaults to V3) + * + * **path:** /documentation + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + documentationLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'documentation.listOptions', Config>; + /** + * --- + * + * [POST] 你好Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] render a template using the provided data + * + * **path:** /render + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] template + * // template as string + * // [required] + * template: string + * // [title] context + * // context as string + * // [required] + * context: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + renderTemplate< + Config extends Alova2MethodConfig & { + data: RenderRequest; + } + >( + config: Config + ): Alova2Method; + }; + config: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'config.listOptions', Config>; + /** + * --- + * + * [POST] 你好Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + } + + var Apis: Apis; +} +" +`; diff --git a/packages/wormhole/test/config.spec.ts b/packages/wormhole/test/config.spec.ts new file mode 100644 index 0000000..8596a1e --- /dev/null +++ b/packages/wormhole/test/config.spec.ts @@ -0,0 +1,201 @@ +import createConfig from '@/createConfig'; +import { readConfig } from '@/readConfig'; +import fs from 'node:fs/promises'; +import { resolve } from 'node:path'; + +vi.mock('node:fs'); +vi.mock('node:fs/promises'); +let type = 'typescript'; +vi.mock('@/functions/getAutoTemplateType', () => ({ + __esModule: true, + default() { + return type; + } +})); +beforeEach(async () => { + try { + await Promise.all([ + fs.unlink(resolve(process.cwd(), 'alova.config.ts')), + fs.unlink(resolve(process.cwd(), 'alova.config.js')) + ]); + } catch (error) {} +}); + +describe.skip('config', () => { + test('should create config file under project root path', async () => { + // generate typescript file + type = 'typescript'; + await createConfig(); + const tsConfigPath = resolve(process.cwd(), 'alova.config.ts'); + const initialTsConfig = await fs.readFile(tsConfigPath, { + encoding: 'utf-8' + }); + expect(initialTsConfig).toMatch(`import type { Config } from '@alova/wormhole';`); + expect(initialTsConfig).toMatch(`export default {`); + expect(initialTsConfig).toMatch(`input: 'http://localhost:3000',`); + + // generate typescript file with alias `ts` + type = 'ts'; + await createConfig(); + const tsConfigPath2 = resolve(process.cwd(), 'alova.config.ts'); + const initialTsConfig2 = await fs.readFile(tsConfigPath2, { + encoding: 'utf-8' + }); + expect(initialTsConfig2).toMatch(`import type { Config } from '@alova/wormhole';`); + expect(initialTsConfig2).toMatch(`export default {`); + expect(initialTsConfig2).toMatch(`input: 'http://localhost:3000',`); + + // generate commonjs file + type = 'commonjs'; + await createConfig(); + const initialCjsConfig = await fs.readFile(resolve(process.cwd(), 'alova.config.js'), { + encoding: 'utf-8' + }); + expect(initialCjsConfig).toMatch(`@type { import('@alova/wormhole').Config }`); + expect(initialCjsConfig).toMatch(`module.exports = {`); + + // generate module file + type = 'module'; + await createConfig(); + const initialEsmoduleConfig = await fs.readFile(resolve(process.cwd(), 'alova.config.js'), { + encoding: 'utf-8' + }); + expect(initialEsmoduleConfig).toMatch(`@type { import('@alova/wormhole').Config }`); + expect(initialEsmoduleConfig).toMatch(`export default {`); + }); + + test('should create config file under custom path', async () => { + type = 'commonjs'; + const customPath = '/mockdir_config'; + await createConfig(customPath); + const configPath = resolve(customPath, 'alova.config.js'); + const initialConfig = await fs.readFile(configPath, { + encoding: 'utf-8' + }); + expect(!!initialConfig).toBeTruthy(); + }); + + const configMap = { + ts: { + file: 'alova.config.ts', + content: `import type { Config } from '@alova/wormhole'; +export default { + generator: [ + { + input: 'http://localhost:3000', + output: 'src/api', + type: 'ts', + version: 'v3', + handleApi: () => 1 + } + ] +}` + }, + module: { + file: 'alova.config.js', + content: `export default { + generator: [ + { + input: 'http://localhost:3000', + output: 'src/api', + type: 'module', + version: 'v3', + handleApi: () => 1 + } + ] +}` + }, + commonjs: { + file: 'alova.config.js', + content: `module.exports = { + generator: [ + { + input: 'http://localhost:3000', + output: 'src/api', + type: 'commonjs', + version: 'v3', + handleApi: () => 1 + } + ] +}` + } + }; + test('should read config file under project root path', async () => { + // write mock config file + const projectRoot = process.cwd(); + try { + await fs.access(projectRoot); + } catch (error) { + await fs.mkdir(projectRoot, { recursive: true }); + } + await fs.writeFile(resolve(projectRoot, configMap.ts.file), configMap.ts.content, 'utf-8'); + + // read ts file + const tsConfig = await readConfig(); + expect(tsConfig).toStrictEqual({ + generator: [ + { + input: 'http://localhost:3000', + output: 'src/api', + type: 'ts', + version: 'v3', + handleApi: () => 1 + } + ] + }); + await fs.unlink(resolve(projectRoot, configMap.ts.file)); // delete ts file + + // read module config file + await fs.writeFile(resolve(projectRoot, configMap.module.file), configMap.module.content, 'utf-8'); + const moduleConfig = await readConfig(); + expect(moduleConfig).toStrictEqual({ + generator: [ + { + input: 'http://localhost:3000', + output: 'src/api', + type: 'module', + version: 'v3', + handleApi: () => 1 + } + ] + }); + + // read commonjs config file + await fs.writeFile(resolve(projectRoot, configMap.commonjs.file), configMap.commonjs.content, 'utf-8'); + const cjsConfig = await readConfig(); + expect(cjsConfig).toStrictEqual({ + generator: [ + { + input: 'http://localhost:3000', + output: 'src/api', + type: 'commonjs', + version: 'v3', + handleApi: () => 1 + } + ] + }); + }); + + test('should read config file under target path', async () => { + // read ts file + const customPath = resolve(__dirname, './mockdir_config2'); + try { + await fs.access(customPath); + } catch (error) { + await fs.mkdir(customPath, { recursive: true }); + } + await fs.writeFile(resolve(customPath, configMap.ts.file), configMap.ts.content, 'utf-8'); + const tsConfig = await readConfig(customPath); + expect(tsConfig).toMatchObject({ + generator: [ + { + input: 'http://localhost:3000', + output: 'src/api', + type: 'ts', + version: 'v3', + handleApi: () => 1 + } + ] + }); + }); +}); diff --git a/packages/wormhole/test/generate.spec.ts b/packages/wormhole/test/generate.spec.ts new file mode 100644 index 0000000..374ba8b --- /dev/null +++ b/packages/wormhole/test/generate.spec.ts @@ -0,0 +1,208 @@ +import generate from '@/generate'; +import fs from 'node:fs/promises'; +import { resolve } from 'node:path'; + +vi.mock('node:fs'); +vi.mock('node:fs/promises'); +describe('generate API', () => { + test('should throw error when necessary items are not specified', async () => { + await expect(generate({} as any)).rejects.toThrow('No items found in the `config.generator`'); + await expect( + generate({ + generator: [{} as any] + }) + ).rejects.toThrow('Field input is required in `config.generator`'); + await expect( + generate({ + generator: [ + { + input: 'http://localhost:3000/openapi.json' + } + ] + } as any) + ).rejects.toThrow('Field output is required in `config.generator`'); + await expect( + generate({ + generator: [ + { + input: 'http://localhost:3000/openapi.json', + output: './src/api', + global: '1243sadf' + } + ] + }) + ).rejects.toThrow('does not match variable specification'); + await expect( + generate({ + generator: [ + { + input: 'http://localhost:3000/openapi.json', + output: './src/api', + global: 'asdf&*^^&%' + } + ] + }) + ).rejects.toThrow('does not match variable specification'); + await expect( + generate({ + generator: [ + { + input: 'http://localhost:3000/openapi.json', + output: './src/api', + global: 'asdf__$$123' + }, + { + input: 'http://localhost:3000/openapi2.json', + output: './src/api' + } + ] + }) + ).rejects.toThrow('output `./src/api` is repated'); + await expect( + generate({ + generator: [ + { + input: 'http://localhost:3000/openapi.json', + output: './src/api', + global: 'asdf__$$123' + }, + { + input: 'http://localhost:3000/openapi2.json', + output: './src/api2' + } + ] + }) + ).rejects.toThrow('Field global is required in `config.generator`'); + await expect( + generate({ + generator: [ + { + input: 'http://localhost:3000/openapi.json', + output: './src/api', + global: 'asdf__$$123' + }, + { + input: 'http://localhost:3000/openapi2.json', + output: './src/api2', + global: 'asdf__$$123' + } + ] + }) + ).rejects.toThrow('global `asdf__$$123` is repated'); + await expect( + generate({ + generator: [ + { + input: 'http://localhost:3000/openapi.json', + output: './src/api' + } + ], + autoUpdate: { + interval: 'abc' as any + } + }) + ).rejects.toThrow('autoUpdate.interval must be a number'); + await expect( + generate({ + generator: [ + { + input: 'http://localhost:3000/openapi.json', + output: './src/api' + } + ], + autoUpdate: { + interval: -1 + } + }) + ).rejects.toThrow('Expected to set number which great than 1 in `config.autoUpdate.interval`'); + }); + + test('should throw error when generating from a file that does not exists', async () => { + await expect( + generate({ + generator: [ + { + input: 'http://localhost:3000/openapi.json', + output: './src/api' + } + ] + }) + ).rejects.toThrow('Cannot read file from http://localhost:3000/openapi.json'); + }); + + test('should generate code with a variant of openapi file formats', async () => { + const outputDir = resolve(__dirname, './mock_output/openapi_301'); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir + } + ] + }); + expect(await fs.readFile(resolve(outputDir, 'apiDefinitions.ts'), 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(resolve(outputDir, 'index.ts'), 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(resolve(outputDir, 'createApis.ts'), 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(resolve(outputDir, 'globals.d.ts'), 'utf-8')).toMatchSnapshot(); + + const outputDir2 = resolve(__dirname, './mock_output/swagger_2'); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/swagger_2.json'), + output: outputDir2 + } + ] + }); + expect(await fs.readFile(resolve(outputDir2, 'apiDefinitions.ts'), 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(resolve(outputDir2, 'index.ts'), 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(resolve(outputDir2, 'createApis.ts'), 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(resolve(outputDir2, 'globals.d.ts'), 'utf-8')).toMatchSnapshot(); + + const outputDir3 = resolve(__dirname, './mock_output/openapi_300'); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/openapi_300.yaml'), + output: outputDir3 + } + ] + }); + expect(await fs.readFile(resolve(outputDir3, 'apiDefinitions.ts'), 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(resolve(outputDir3, 'index.ts'), 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(resolve(outputDir3, 'createApis.ts'), 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(resolve(outputDir3, 'globals.d.ts'), 'utf-8')).toMatchSnapshot(); + }); + + test('should generate target versioned code', async () => { + const outputDir = resolve(__dirname, './mock_output/openapi_301'); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir, + version: 2 + } + ] + }); + expect(await fs.readFile(resolve(outputDir, 'apiDefinitions.ts'), 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(resolve(outputDir, 'index.ts'), 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(resolve(outputDir, 'createApis.ts'), 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(resolve(outputDir, 'globals.d.ts'), 'utf-8')).toMatchSnapshot(); + + const outputDir2 = resolve(__dirname, './mock_output/openapi_301'); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir2, + version: 3 + } + ] + }); + expect(await fs.readFile(resolve(outputDir2, 'apiDefinitions.ts'), 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(resolve(outputDir2, 'index.ts'), 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(resolve(outputDir2, 'createApis.ts'), 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(resolve(outputDir2, 'globals.d.ts'), 'utf-8')).toMatchSnapshot(); + }); +}); diff --git a/packages/wormhole/test/openapis/openapi_300.yaml b/packages/wormhole/test/openapis/openapi_300.yaml new file mode 100644 index 0000000..aa1b8ee --- /dev/null +++ b/packages/wormhole/test/openapis/openapi_300.yaml @@ -0,0 +1,745 @@ +openapi: 3.0.0 +servers: + - url: 'http://petstore.swagger.io/v2' +info: + description: >- + This is a sample server Petstore server. For this sample, you can use the api key + `special-key` to test the authorization filters. + version: 1.0.0 + title: OpenAPI Petstore + contact: + name: OpenAPI-Generator Contributors + url: 'https://github.com/OpenAPITools/openapi-generator' + email: 'openapitools@googlegroups.com' + license: + name: Apache-2.0 + url: 'https://www.apache.org/licenses/LICENSE-2.0.html' +tags: + - name: pet + description: Everything about your Pets + - name: store + description: Access to Petstore orders + - name: user + description: Operations about user +paths: + /pet: + post: + tags: + - tag + summary: Add a new pet to the store 2 + description: '' + operationId: 增加pet24 + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '405': + description: Invalid input + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + $ref: '#/components/requestBodies/Pet' + put: + tags: + - pet + summary: Update an existing pet 2 + description: '' + operationId: updatePet + externalDocs: + url: 'http://petstore.swagger.io/v2/doc/updatePet' + description: 'API documentation for the updatePet operation' + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + '405': + description: Validation exception + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + $ref: '#/components/requestBodies/Pet' + /pet/findByStatus: + get: + tags: + - pet + summary: Finds Pets by status + description: Multiple status values can be provided with comma separated strings + operationId: findPetsByStatus + parameters: + - name: status + in: query + description: Status values that need to be considered for filter + required: true + style: form + explode: false + deprecated: true + schema: + type: array + items: + type: string + enum: + - available + - pending + - sold + default: available + responses: + '200': + description: successful operation + content: + application/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid status value + security: + - petstore_auth: + - 'read:pets' + /pet/findByTags: + get: + tags: + - pet + summary: Finds Pets by tags + description: >- + Multiple tags can be provided with comma separated strings. Use tag1, + tag2, tag3 for testing. + operationId: findPetsByTags + parameters: + - name: tags + in: query + description: Tags to filter by + required: true + style: form + explode: false + schema: + type: array + items: + type: string + responses: + '200': + description: successful operation + content: + application/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid tag value + security: + - petstore_auth: + - 'read:pets' + deprecated: true + '/pet/{petId}': + get: + tags: + - pet + summary: Find pet by ID + description: Returns a single pet + operationId: getPetById + parameters: + - name: petId + in: path + description: ID of pet to return + required: true + schema: + type: integer + format: int64 + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + security: + - api_key: [] + post: + tags: + - pet + summary: Updates a pet in the store with form data + description: '' + operationId: updatePetWithForm + parameters: + - name: petId + in: path + description: ID of pet that needs to be updated + required: true + schema: + type: integer + format: int64 + responses: + '405': + description: Invalid input + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + content: + application/x-www-form-urlencoded: + schema: + type: object + properties: + name: + description: Updated name of the pet + type: string + status: + description: Updated status of the pet + type: string + delete: + tags: + - pet + summary: Deletes a pet + description: '' + operationId: deletePet + parameters: + - name: api_key + in: header + required: false + schema: + type: string + - name: petId + in: path + description: Pet id to delete + required: true + schema: + type: integer + format: int64 + responses: + '400': + description: Invalid pet value + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + '/pet/{petId}/uploadImage': + post: + tags: + - pet + summary: uploads an image + description: '' + operationId: uploadFile + parameters: + - name: petId + in: path + description: ID of pet to update + required: true + schema: + type: integer + format: int64 + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + additionalMetadata: + description: Additional data to pass to server + type: string + file: + description: file to upload + type: string + format: binary + /store/inventory: + get: + tags: + - store + summary: Returns pet inventories by status + description: Returns a map of status codes to quantities + operationId: getInventory + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: object + additionalProperties: + type: integer + format: int32 + security: + - api_key: [] + /store/order: + post: + tags: + - store + summary: Place an order for a pet + description: '' + operationId: placeOrder + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Order' + application/json: + schema: + $ref: '#/components/schemas/Order' + '400': + description: Invalid Order + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Order' + description: order placed for purchasing the pet + required: true + '/store/order/{orderId}': + get: + tags: + - store + summary: Find purchase order by ID + description: >- + For valid response try integer IDs with value <= 5 or > 10. Other values + will generate exceptions + operationId: getOrderById + parameters: + - name: orderId + in: path + description: ID of pet that needs to be fetched + required: true + schema: + type: integer + format: int64 + minimum: 1 + maximum: 5 + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Order' + application/json: + schema: + $ref: '#/components/schemas/Order' + '400': + description: Invalid ID supplied + '404': + description: Order not found + delete: + tags: + - store + summary: Delete purchase order by ID + description: >- + For valid response try integer IDs with value < 1000. Anything above + 1000 or nonintegers will generate API errors + operationId: deleteOrder + parameters: + - name: orderId + in: path + description: ID of the order that needs to be deleted + required: true + schema: + type: string + responses: + '400': + description: Invalid ID supplied + '404': + description: Order not found + /user: + post: + tags: + - user + summary: Create user + description: This can only be done by the logged in user. + operationId: createUser + responses: + default: + description: successful operation + security: + - api_key: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/User' + description: Created user object + required: true + /user/createWithArray: + post: + tags: + - user + summary: Creates list of users with given input array + description: '' + operationId: createUsersWithArrayInput + responses: + default: + description: successful operation + security: + - api_key: [] + requestBody: + $ref: '#/components/requestBodies/UserArray' + /user/createWithList: + post: + tags: + - user + summary: Creates list of users with given input array + description: '' + operationId: createUsersWithListInput + responses: + default: + description: successful operation + security: + - api_key: [] + requestBody: + $ref: '#/components/requestBodies/UserArray' + /user/login: + get: + tags: + - user + summary: Logs user into the system + description: '' + operationId: loginUser + parameters: + - name: username + in: query + description: The user name for login + required: true + schema: + type: string + pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$' + - name: password + in: query + description: The password for login in clear text + required: true + schema: + type: string + responses: + '200': + description: successful operation + headers: + Set-Cookie: + description: >- + Cookie authentication key for use with the `api_key` + apiKey authentication. + schema: + type: string + example: AUTH_KEY=abcde12345; Path=/; HttpOnly + X-Rate-Limit: + description: calls per hour allowed by the user + schema: + type: integer + format: int32 + X-Expires-After: + description: date in UTC when token expires + schema: + type: string + format: date-time + content: + application/xml: + schema: + type: string + application/json: + schema: + type: string + '400': + description: Invalid username/password supplied + /user/logout: + get: + tags: + - user + summary: Logs out current logged in user session + description: '' + operationId: logoutUser + responses: + default: + description: successful operation + security: + - api_key: [] + '/user/{username}': + get: + tags: + - user + summary: Get user by user name + description: '' + operationId: getUserByName + parameters: + - name: username + in: path + description: The name that needs to be fetched. Use user1 for testing. + required: true + schema: + type: string + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/User' + application/json: + schema: + $ref: '#/components/schemas/User' + '400': + description: Invalid username supplied + '404': + description: User not found + put: + tags: + - user + summary: Updated user + description: This can only be done by the logged in user. + operationId: updateUser + parameters: + - name: username + in: path + description: name that need to be deleted + required: true + schema: + type: string + responses: + '400': + description: Invalid user supplied + '404': + description: User not found + security: + - api_key: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/User' + description: Updated user object + required: true + delete: + tags: + - user + summary: Delete user + description: This can only be done by the logged in user. + operationId: deleteUser + parameters: + - name: username + in: path + description: The name that needs to be deleted + required: true + schema: + type: string + responses: + '400': + description: Invalid username supplied + '404': + description: User not found + security: + - api_key: [] +externalDocs: + description: Find out more about Swagger + url: 'http://swagger.io' +components: + requestBodies: + UserArray: + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/User' + description: List of user object + required: true + Pet: + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + description: Pet object that needs to be added to the store + required: true + securitySchemes: + petstore_auth: + type: oauth2 + flows: + implicit: + authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog' + scopes: + 'write:pets': modify pets in your account + 'read:pets': read your pets + api_key: + type: apiKey + name: api_key + in: header + schemas: + Order: + title: Pet Order + description: An order for a pets from the pet store + type: object + properties: + id: + type: integer + format: int64 + petId: + type: integer + format: int64 + quantity: + type: integer + format: int32 + shipDate: + type: string + format: date-time + status: + type: string + description: Order Status + enum: + - placed + - approved + - delivered + complete: + type: boolean + default: false + xml: + name: Order + Category: + title: Pet category + description: A category for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$' + xml: + name: Category + User: + title: a User + description: A User who is purchasing from the pet store + type: object + properties: + id: + type: integer + format: int64 + username: + type: string + firstName: + type: string + lastName: + type: string + email: + type: string + password: + type: string + phone: + type: string + userStatus: + type: integer + format: int32 + description: User Status + xml: + name: User + Tag: + title: Pet Tag + description: A tag for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + xml: + name: Tag + Pet: + title: a Pet + description: A pet for sale in the pet store + type: object + required: + - name + - photoUrls + properties: + id: + type: integer + format: int64 + category: + $ref: '#/components/schemas/Category' + name: + type: string + example: doggie + photoUrls: + type: array + xml: + name: photoUrl + wrapped: true + items: + type: string + tags: + type: array + xml: + name: tag + wrapped: true + items: + $ref: '#/components/schemas/Tag' + status: + type: string + description: pet status in the store + deprecated: true + enum: + - available + - pending + - sold + xml: + name: Pet + ApiResponse: + title: An uploaded response + description: Describes the result of uploading an image resource + type: object + properties: + code: + type: integer + format: int32 + type: + type: string + message: + type: string diff --git a/packages/wormhole/test/openapis/openapi_301.json b/packages/wormhole/test/openapis/openapi_301.json new file mode 100644 index 0000000..09c9aa6 --- /dev/null +++ b/packages/wormhole/test/openapis/openapi_301.json @@ -0,0 +1,655 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "Swagger Generator", + "description": "This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/).", + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + }, + "version": "3.0.57" + }, + "servers": [ + { + "url": "/api1" + } + ], + "tags": [ + { + "name": "clients" + }, + { + "name": "servers" + }, + { + "name": "documentation" + }, + { + "name": "config" + } + ], + "paths": { + "/generate": { + "get": { + "tags": ["clients", "servers", "documentation", "config"], + "summary": "Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL.", + "operationId": "generateFromURL", + "parameters": [ + { + "name": "codegenOptionsURL", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/octet-stream": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + } + }, + "x-swagger-router-controller": "io.swagger.v3.generator.online.GeneratorController" + }, + "post": { + "tags": ["clients", "servers", "documentation", "config"], + "summary": "Generates and download code. GenerationRequest input provided as request body.", + "operationId": "generate", + "parameters": [ + { + "name": "codegenOptionsURL", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerationRequest" + } + } + } + }, + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/octet-stream": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + } + }, + "x-swagger-router-controller": "io.swagger.v3.generator.online.GeneratorController" + } + }, + "/clients": { + "get": { + "tags": ["clients", "documentation"], + "summary": "Deprecated, use '/{type}/{version}' instead. List generator languages of type 'client' or 'documentation' for given codegen version (defaults to V3)", + "operationId": "clientLanguages", + "parameters": [ + { + "$ref": "#/components/parameters/version" + }, + { + "name": "clientOnly", + "in": "query", + "description": "flag to only return languages of type `client`", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "deprecated": true, + "x-swagger-router-controller": "io.swagger.v3.generator.online.GeneratorController" + } + }, + "/servers": { + "get": { + "tags": ["servers"], + "summary": "Deprecated, use '/{type}/{version}' instead. List generator languages of type 'server' for given codegen version (defaults to V3)", + "operationId": "serverLanguages", + "parameters": [ + { + "$ref": "#/components/parameters/version" + } + ], + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "deprecated": true, + "x-swagger-router-controller": "io.swagger.v3.generator.online.GeneratorController" + } + }, + "/documentation": { + "get": { + "tags": ["documentation"], + "summary": "Deprecated, use '/{type}/{version}' instead. List generator languages of type 'documentation' for given codegen version (defaults to V3)", + "operationId": "documentationLanguages", + "parameters": [ + { + "$ref": "#/components/parameters/version" + } + ], + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "deprecated": true, + "x-swagger-router-controller": "io.swagger.v3.generator.online.GeneratorController" + } + }, + "/{type}/{version}": { + "get": { + "tags": ["clients", "servers", "documentation", "config"], + "summary": "List generator languages of the given type and version", + "operationId": "languages", + "parameters": [ + { + "$ref": "#/components/parameters/type" + }, + { + "name": "version", + "in": "path", + "description": "generator version used by codegen engine", + "required": true, + "schema": { + "type": "string", + "enum": ["V2", "V3"] + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "x-swagger-router-controller": "io.swagger.v3.generator.online.GeneratorController" + } + }, + "/types": { + "get": { + "tags": ["clients", "servers", "documentation", "config"], + "summary": "List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages", + "operationId": "languagesMulti", + "parameters": [ + { + "$ref": "#/components/parameters/types" + }, + { + "$ref": "#/components/parameters/version" + } + ], + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "x-swagger-router-controller": "io.swagger.v3.generator.online.GeneratorController" + } + }, + "/options": { + "get": { + "tags": ["clients", "servers", "documentation", "config"], + "summary": "Returns options for a given language and version (defaults to V3)", + "operationId": "listOptions", + "parameters": [ + { + "name": "language", + "in": "query", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "$ref": "#/components/parameters/version" + } + ], + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/CliOption" + } + } + } + } + } + }, + "x-swagger-router-controller": "io.swagger.v3.generator.online.GeneratorController" + } + }, + "/model": { + "post": { + "tags": ["clients", "servers", "documentation", "config"], + "summary": "你好Generates the intermediate model (\"bundle\") and returns it as a JSON. body.", + "operationId": "generateBundle", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerationRequest" + } + } + } + }, + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerationRequest" + } + } + } + } + }, + "x-swagger-router-controller": "io.swagger.v3.generator.online.GeneratorController" + } + }, + "/render": { + "post": { + "tags": ["documentation"], + "summary": "render a template using the provided data", + "operationId": "renderTemplate", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RenderRequest" + } + } + } + }, + "responses": { + "200": { + "description": "successful operation" + } + }, + "x-swagger-router-controller": "io.swagger.v3.generator.online.GeneratorController24334" + } + } + }, + "components": { + "schemas": { + "GenerationRequest": { + "required": ["lang"], + "type": "object", + "properties": { + "lang": { + "title": "language", + "type": "string", + "description": "language to generate (required)456", + "example": "java" + }, + "spec": { + "type": "object", + "description": "spec in json format. . Alternative to `specURL`" + }, + "specURL": { + "type": "string", + "description": "URL of the spec in json format. Alternative to `spec`" + }, + "type": { + "type": "string", + "description": "type of the spec", + "enum": ["CLIENT", "SERVER", "DOCUMENTATION", "CONFIG"] + }, + "codegenVersion": { + "type": "string", + "description": "codegen version to use", + "enum": ["V2", "V3"] + }, + "options": { + "$ref": "#/components/schemas/Options" + } + }, + "x-swagger-router-model": "io.swagger.codegen.v3.service.GenerationRequest" + }, + "AuthorizationValue": { + "title": "authorization", + "type": "object", + "properties": { + "value": { + "type": "string", + "description": "Authorization value" + }, + "keyName": { + "type": "string", + "description": "Authorization key" + }, + "type": { + "type": "string", + "description": "Authorization type", + "enum": ["query", "header"] + } + }, + "description": "adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object", + "x-swagger-router-model": "io.swagger.v3.parser.core.models.AuthorizationValue" + }, + "Options": { + "type": "object", + "properties": { + "auth": { + "title": "authorization", + "type": "string", + "description": "adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values" + }, + "authorizationValue": { + "$ref": "#/components/schemas/AuthorizationValue" + }, + "apiPackage": { + "title": "api package", + "type": "string", + "description": "package for generated api classes" + }, + "templateVersion": { + "title": "Template Version", + "type": "string", + "description": "template version for generation" + }, + "modelPackage": { + "title": "model package", + "type": "string", + "description": "package for generated models" + }, + "modelNamePrefix": { + "title": "model name prefix", + "type": "string", + "description": "Prefix that will be prepended to all model names. Default is the empty string." + }, + "modelNameSuffix": { + "title": "model name suffix", + "type": "string", + "description": "PrefixSuffix that will be appended to all model names. Default is the empty string." + }, + "systemProperties": { + "title": "System Properties", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "sets specified system properties in key/value format" + }, + "instantiationTypes": { + "title": "instantiation types", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code." + }, + "typeMappings": { + "title": "type mappings", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String." + }, + "additionalProperties": { + "title": "additional properties", + "type": "object", + "additionalProperties": { + "type": "object" + }, + "description": "sets additional properties that can be referenced by the mustache templates in key/value format." + }, + "languageSpecificPrimitives": { + "title": "language specific primitives", + "type": "array", + "description": "specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option.", + "items": { + "type": "string" + } + }, + "importMappings": { + "title": "import mappings", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "specifies mappings between a given class and the import that should be used for that class in key/value format." + }, + "invokerPackage": { + "title": "invoker package", + "type": "string", + "description": "root package for generated code" + }, + "groupId": { + "title": "group id", + "type": "string", + "description": "groupId in generated pom.xml" + }, + "artifactId": { + "title": "artifact id", + "type": "string", + "description": "artifactId in generated pom.xml" + }, + "artifactVersion": { + "title": "artifact version", + "type": "string", + "description": "artifact version generated in pom.xml" + }, + "library": { + "title": "library", + "type": "string", + "description": "library template (sub-template)" + }, + "gitUserId": { + "title": "git user id", + "type": "string", + "description": "Git user ID, e.g. swagger-api." + }, + "gitRepoId": { + "title": "git repo id", + "type": "string", + "description": "Git repo ID, e.g. swagger-codegen." + }, + "releaseNote": { + "title": "release note", + "type": "string", + "description": "Release note, default to 'Minor update'." + }, + "httpUserAgent": { + "title": "http user agent", + "type": "string", + "description": "HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}'" + }, + "reservedWordsMappings": { + "title": "reserved words mappings", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier." + }, + "ignoreFileOverride": { + "title": "ignore file override location", + "type": "string", + "description": "Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation." + }, + "removeOperationIdPrefix": { + "title": "remove prefix of the operationId", + "type": "boolean", + "description": "Remove prefix of operationId, e.g. config_getId => getId" + }, + "skipOverride": { + "type": "boolean" + } + }, + "x-swagger-router-model": "io.swagger.codegen.v3.service.Options" + }, + "CliOption": { + "type": "object", + "properties": { + "optionName": { + "type": "string" + }, + "description": { + "type": "string" + }, + "type": { + "type": "string", + "description": "Data type is based on the types supported by the JSON-Schema" + }, + "enum": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "default": { + "type": "string" + } + } + }, + "RenderRequest": { + "required": ["context", "template"], + "type": "object", + "properties": { + "template": { + "title": "template", + "type": "string", + "description": "template as string", + "example": "{{!mustache}}" + }, + "context": { + "title": "context", + "type": "string", + "description": "context as string", + "example": "{}" + } + }, + "x-swagger-router-model": "io.swagger.codegen.v3.service.RenderRequest" + }, + "RenderResponse": { + "required": ["value"], + "type": "object", + "properties": { + "value": { + "type": "string" + } + }, + "x-swagger-router-model": "io.swagger.codegen.v3.service.RenderResponse" + } + }, + "parameters": { + "version": { + "name": "version", + "in": "query", + "description": "generator version used by codegen engine", + "schema": { + "type": "string", + "enum": ["V2", "V3"] + } + }, + "type": { + "name": "type", + "in": "path", + "description": "generator type", + "required": true, + "schema": { + "type": "string", + "enum": ["client", "server", "documentation", "config"] + } + }, + "types": { + "name": "types", + "in": "query", + "description": "comma-separated list of generator types", + "required": true, + "style": "form", + "explode": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": ["client", "server", "documentation", "config"] + } + } + } + } + } +} diff --git a/packages/wormhole/test/openapis/swagger_2.json b/packages/wormhole/test/openapis/swagger_2.json new file mode 100644 index 0000000..ba84820 --- /dev/null +++ b/packages/wormhole/test/openapis/swagger_2.json @@ -0,0 +1,897 @@ +{ + "swagger": "2.0", + "info": { + "description": "This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.", + "version": "1.0.7", + "title": "Swagger Petstore", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "email": "apiteam@swagger.io" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + } + }, + "host": "petstore.swagger.io", + "basePath": "/v2", + "tags": [ + { + "name": "pet", + "description": "Everything about your Pets", + "externalDocs": { + "description": "Find out more", + "url": "http://swagger.io" + } + }, + { + "name": "store", + "description": "Access to Petstore orders" + }, + { + "name": "user", + "description": "Operations about user", + "externalDocs": { + "description": "Find out more about our store", + "url": "http://swagger.io" + } + } + ], + "schemes": ["https", "http"], + "paths": { + "/pet/{petId}/uploadImage": { + "post": { + "tags": ["pet"], + "summary": "uploads an image", + "description": "", + "operationId": "uploadFile", + "consumes": ["multipart/form-data"], + "produces": ["application/json"], + "parameters": [ + { + "name": "petId", + "in": "path", + "description": "ID of pet to update", + "required": true, + "type": "integer", + "format": "int64" + }, + { + "name": "additionalMetadata", + "in": "formData", + "description": "Additional data to pass to server", + "required": false, + "type": "string" + }, + { + "name": "file", + "in": "formData", + "description": "file to upload", + "required": false, + "type": "file" + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/ApiResponse" + } + } + }, + "security": [ + { + "petstore_auth": ["write:pets", "read:pets"] + } + ] + } + }, + "/pet": { + "post": { + "tags": ["pet"], + "summary": "Add a new pet to the store", + "description": "", + "operationId": "addPet", + "consumes": ["application/json", "application/xml"], + "produces": ["application/json", "application/xml"], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "Pet object that needs to be added to the store", + "required": true, + "schema": { + "$ref": "#/definitions/Pet" + } + } + ], + "responses": { + "405": { + "description": "Invalid input" + } + }, + "security": [ + { + "petstore_auth": ["write:pets", "read:pets"] + } + ] + }, + "put": { + "tags": ["pet"], + "summary": "Update an existing pet", + "description": "", + "operationId": "updatePet", + "consumes": ["application/json", "application/xml"], + "produces": ["application/json", "application/xml"], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "Pet object that needs to be added to the store", + "required": true, + "schema": { + "$ref": "#/definitions/Pet" + } + } + ], + "responses": { + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Pet not found" + }, + "405": { + "description": "Validation exception" + } + }, + "security": [ + { + "petstore_auth": ["write:pets", "read:pets"] + } + ] + } + }, + "/pet/findByStatus": { + "get": { + "tags": ["pet"], + "summary": "Finds Pets by status", + "description": "Multiple status values can be provided with comma separated strings", + "operationId": "findPetsByStatus", + "produces": ["application/json", "application/xml"], + "parameters": [ + { + "name": "status", + "in": "query", + "description": "Status values that need to be considered for filter", + "required": true, + "type": "array", + "items": { + "type": "string", + "enum": ["available", "pending", "sold"], + "default": "available" + }, + "collectionFormat": "multi" + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Pet" + } + } + }, + "400": { + "description": "Invalid status value" + } + }, + "security": [ + { + "petstore_auth": ["write:pets", "read:pets"] + } + ] + } + }, + "/pet/findByTags": { + "get": { + "tags": ["pet"], + "summary": "Finds Pets by tags", + "description": "Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.", + "operationId": "findPetsByTags", + "produces": ["application/json", "application/xml"], + "parameters": [ + { + "name": "tags", + "in": "query", + "description": "Tags to filter by", + "required": true, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Pet" + } + } + }, + "400": { + "description": "Invalid tag value" + } + }, + "security": [ + { + "petstore_auth": ["write:pets", "read:pets"] + } + ], + "deprecated": true + } + }, + "/pet/{petId}": { + "get": { + "tags": ["pet"], + "summary": "Find pet by ID", + "description": "Returns a single pet", + "operationId": "getPetById", + "produces": ["application/json", "application/xml"], + "parameters": [ + { + "name": "petId", + "in": "path", + "description": "ID of pet to return", + "required": true, + "type": "integer", + "format": "int64" + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/Pet" + } + }, + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Pet not found" + } + }, + "security": [ + { + "api_key": [] + } + ] + }, + "post": { + "tags": ["pet"], + "summary": "Updates a pet in the store with form data", + "description": "", + "operationId": "updatePetWithForm", + "consumes": ["application/x-www-form-urlencoded"], + "produces": ["application/json", "application/xml"], + "parameters": [ + { + "name": "petId", + "in": "path", + "description": "ID of pet that needs to be updated", + "required": true, + "type": "integer", + "format": "int64" + }, + { + "name": "name", + "in": "formData", + "description": "Updated name of the pet", + "required": false, + "type": "string" + }, + { + "name": "status", + "in": "formData", + "description": "Updated status of the pet", + "required": false, + "type": "string" + } + ], + "responses": { + "405": { + "description": "Invalid input" + } + }, + "security": [ + { + "petstore_auth": ["write:pets", "read:pets"] + } + ] + }, + "delete": { + "tags": ["pet"], + "summary": "Deletes a pet", + "description": "", + "operationId": "deletePet", + "produces": ["application/json", "application/xml"], + "parameters": [ + { + "name": "api_key", + "in": "header", + "required": false, + "type": "string" + }, + { + "name": "petId", + "in": "path", + "description": "Pet id to delete", + "required": true, + "type": "integer", + "format": "int64" + } + ], + "responses": { + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Pet not found" + } + }, + "security": [ + { + "petstore_auth": ["write:pets", "read:pets"] + } + ] + } + }, + "/store/inventory": { + "get": { + "tags": ["store"], + "summary": "Returns pet inventories by status", + "description": "Returns a map of status codes to quantities", + "operationId": "getInventory", + "produces": ["application/json"], + "parameters": [], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "object", + "additionalProperties": { + "type": "integer", + "format": "int32" + } + } + } + }, + "security": [ + { + "api_key": [] + } + ] + } + }, + "/store/order": { + "post": { + "tags": ["store"], + "summary": "Place an order for a pet", + "description": "", + "operationId": "placeOrder", + "consumes": ["application/json"], + "produces": ["application/json", "application/xml"], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "order placed for purchasing the pet", + "required": true, + "schema": { + "$ref": "#/definitions/Order" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/Order" + } + }, + "400": { + "description": "Invalid Order" + } + } + } + }, + "/store/order/{orderId}": { + "get": { + "tags": ["store"], + "summary": "Find purchase order by ID", + "description": "For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions", + "operationId": "getOrderById", + "produces": ["application/json", "application/xml"], + "parameters": [ + { + "name": "orderId", + "in": "path", + "description": "ID of pet that needs to be fetched", + "required": true, + "type": "integer", + "maximum": 10, + "minimum": 1, + "format": "int64" + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/Order" + } + }, + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Order not found" + } + } + }, + "delete": { + "tags": ["store"], + "summary": "Delete purchase order by ID", + "description": "For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors", + "operationId": "deleteOrder", + "produces": ["application/json", "application/xml"], + "parameters": [ + { + "name": "orderId", + "in": "path", + "description": "ID of the order that needs to be deleted", + "required": true, + "type": "integer", + "minimum": 1, + "format": "int64" + } + ], + "responses": { + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Order not found" + } + } + } + }, + "/user/createWithList": { + "post": { + "tags": ["user"], + "summary": "Creates list of users with given input array", + "description": "", + "operationId": "createUsersWithListInput", + "consumes": ["application/json"], + "produces": ["application/json", "application/xml"], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "List of user object", + "required": true, + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/User" + } + } + } + ], + "responses": { + "default": { + "description": "successful operation" + } + } + } + }, + "/user/{username}": { + "get": { + "tags": ["user"], + "summary": "Get user by user name", + "description": "", + "operationId": "getUserByName", + "produces": ["application/json", "application/xml"], + "parameters": [ + { + "name": "username", + "in": "path", + "description": "The name that needs to be fetched. Use user1 for testing. ", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/User" + } + }, + "400": { + "description": "Invalid username supplied" + }, + "404": { + "description": "User not found" + } + } + }, + "put": { + "tags": ["user"], + "summary": "Updated user", + "description": "This can only be done by the logged in user.", + "operationId": "updateUser", + "consumes": ["application/json"], + "produces": ["application/json", "application/xml"], + "parameters": [ + { + "name": "username", + "in": "path", + "description": "name that need to be updated", + "required": true, + "type": "string" + }, + { + "in": "body", + "name": "body", + "description": "Updated user object", + "required": true, + "schema": { + "$ref": "#/definitions/User" + } + } + ], + "responses": { + "400": { + "description": "Invalid user supplied" + }, + "404": { + "description": "User not found" + } + } + }, + "delete": { + "tags": ["user"], + "summary": "Delete user", + "description": "This can only be done by the logged in user.", + "operationId": "deleteUser", + "produces": ["application/json", "application/xml"], + "parameters": [ + { + "name": "username", + "in": "path", + "description": "The name that needs to be deleted", + "required": true, + "type": "string" + } + ], + "responses": { + "400": { + "description": "Invalid username supplied" + }, + "404": { + "description": "User not found" + } + } + } + }, + "/user/login": { + "get": { + "tags": ["user"], + "summary": "Logs user into the system", + "description": "", + "operationId": "loginUser", + "produces": ["application/json", "application/xml"], + "parameters": [ + { + "name": "username", + "in": "query", + "description": "The user name for login", + "required": true, + "type": "string" + }, + { + "name": "password", + "in": "query", + "description": "The password for login in clear text", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "successful operation", + "headers": { + "X-Expires-After": { + "type": "string", + "format": "date-time", + "description": "date in UTC when token expires" + }, + "X-Rate-Limit": { + "type": "integer", + "format": "int32", + "description": "calls per hour allowed by the user" + } + }, + "schema": { + "type": "string" + } + }, + "400": { + "description": "Invalid username/password supplied" + } + } + } + }, + "/user/logout": { + "get": { + "tags": ["user"], + "summary": "Logs out current logged in user session", + "description": "", + "operationId": "logoutUser", + "produces": ["application/json", "application/xml"], + "parameters": [], + "responses": { + "default": { + "description": "successful operation" + } + } + } + }, + "/user/createWithArray": { + "post": { + "tags": ["user"], + "summary": "Creates list of users with given input array", + "description": "", + "operationId": "createUsersWithArrayInput", + "consumes": ["application/json"], + "produces": ["application/json", "application/xml"], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "List of user object", + "required": true, + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/User" + } + } + } + ], + "responses": { + "default": { + "description": "successful operation" + } + } + } + }, + "/user": { + "post": { + "tags": ["user"], + "summary": "Create user", + "description": "This can only be done by the logged in user.", + "operationId": "createUser", + "consumes": ["application/json"], + "produces": ["application/json", "application/xml"], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "Created user object", + "required": true, + "schema": { + "$ref": "#/definitions/User" + } + } + ], + "responses": { + "default": { + "description": "successful operation" + } + } + } + } + }, + "securityDefinitions": { + "api_key": { + "type": "apiKey", + "name": "api_key", + "in": "header" + }, + "petstore_auth": { + "type": "oauth2", + "authorizationUrl": "https://petstore.swagger.io/oauth/authorize", + "flow": "implicit", + "scopes": { + "read:pets": "read your pets", + "write:pets": "modify pets in your account" + } + } + }, + "definitions": { + "ApiResponse": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "type": { + "type": "string" + }, + "message": { + "type": "string" + } + } + }, + "Category": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + } + }, + "xml": { + "name": "Category" + } + }, + "Pet": { + "type": "object", + "required": ["name", "photoUrls"], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "category": { + "$ref": "#/definitions/Category" + }, + "name": { + "type": "string", + "example": "doggie" + }, + "photoUrls": { + "type": "array", + "xml": { + "wrapped": true + }, + "items": { + "type": "string", + "xml": { + "name": "photoUrl" + } + } + }, + "tags": { + "type": "array", + "xml": { + "wrapped": true + }, + "items": { + "xml": { + "name": "tag" + }, + "$ref": "#/definitions/Tag" + } + }, + "status": { + "type": "string", + "description": "pet status in the store", + "enum": ["available", "pending", "sold"] + } + }, + "xml": { + "name": "Pet" + } + }, + "Tag": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + } + }, + "xml": { + "name": "Tag" + } + }, + "Order": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "petId": { + "type": "integer", + "format": "int64" + }, + "quantity": { + "type": "integer", + "format": "int32" + }, + "shipDate": { + "type": "string", + "format": "date-time" + }, + "status": { + "type": "string", + "description": "Order Status", + "enum": ["placed", "approved", "delivered"] + }, + "complete": { + "type": "boolean" + } + }, + "xml": { + "name": "Order" + } + }, + "User": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "username": { + "type": "string" + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "email": { + "type": "string" + }, + "password": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "userStatus": { + "type": "integer", + "format": "int32", + "description": "User Status" + } + }, + "xml": { + "name": "User" + } + } + }, + "externalDocs": { + "description": "Find out more about Swagger", + "url": "http://swagger.io" + } +} diff --git a/packages/wormhole/test/output/openapi_300/apiDefinitions.ts b/packages/wormhole/test/output/openapi_300/apiDefinitions.ts new file mode 100644 index 0000000..d1f6468 --- /dev/null +++ b/packages/wormhole/test/output/openapi_300/apiDefinitions.ts @@ -0,0 +1,48 @@ +/// +/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.57 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +export default { + 'clients.generateFromURL': ['GET', '/generate'], + 'servers.generateFromURL': ['GET', '/generate'], + 'documentation.generateFromURL': ['GET', '/generate'], + 'config.generateFromURL': ['GET', '/generate'], + 'clients.generate': ['POST', '/generate'], + 'servers.generate': ['POST', '/generate'], + 'documentation.generate': ['POST', '/generate'], + 'config.generate': ['POST', '/generate'], + 'clients.clientLanguages': ['GET', '/clients'], + 'documentation.clientLanguages': ['GET', '/clients'], + 'servers.serverLanguages': ['GET', '/servers'], + 'documentation.documentationLanguages': ['GET', '/documentation'], + 'clients.languages': ['GET', '/{type}/{version}'], + 'servers.languages': ['GET', '/{type}/{version}'], + 'documentation.languages': ['GET', '/{type}/{version}'], + 'config.languages': ['GET', '/{type}/{version}'], + 'clients.languagesMulti': ['GET', '/types'], + 'servers.languagesMulti': ['GET', '/types'], + 'documentation.languagesMulti': ['GET', '/types'], + 'config.languagesMulti': ['GET', '/types'], + 'clients.listOptions': ['GET', '/options'], + 'servers.listOptions': ['GET', '/options'], + 'documentation.listOptions': ['GET', '/options'], + 'config.listOptions': ['GET', '/options'], + 'clients.generateBundle': ['POST', '/model'], + 'servers.generateBundle': ['POST', '/model'], + 'documentation.generateBundle': ['POST', '/model'], + 'config.generateBundle': ['POST', '/model'], + 'documentation.renderTemplate': ['POST', '/render'] +}; diff --git a/packages/wormhole/test/output/openapi_300/createApis.ts b/packages/wormhole/test/output/openapi_300/createApis.ts new file mode 100644 index 0000000..02388de --- /dev/null +++ b/packages/wormhole/test/output/openapi_300/createApis.ts @@ -0,0 +1,82 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.57 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, MethodType, AlovaMethodCreateConfig } from 'alova'; +import { Method } from 'alova'; +import apiDefinitions from './apiDefinitions'; + +const createFunctionalProxy = ( + array: (string | symbol)[], + alovaInstance: Alova, + configMap: any +) => { + // create a new proxy instance + return new Proxy(function () {}, { + get(_, property) { + // record the target property, so that it can get the completed accessing paths + array.push(property); + // always return a new proxy to continue recording accessing paths. + return createFunctionalProxy(array, alovaInstance, configMap); + }, + apply(_, __, [config]) { + const apiPathKey = array.join('.') as keyof typeof apiDefinitions; + const apiItem = apiDefinitions[apiPathKey]; + if (!apiItem) { + throw new Error(`the api path of \`${apiPathKey}\` is not found`); + } + const mergedConfig = { + ...configMap[apiPathKey], + ...config + }; + const [method, url] = apiItem; + const { pathParams, data } = mergedConfig; + const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => { + const pathParam = pathParams[key]; + return pathParam; + }); + delete mergedConfig.pathParams; + return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data); + } + }); +}; + +export const createApis = (alovaInstance: Alova, configMap: any) => { + const Apis = new Proxy({} as Apis, { + get(_, property) { + return createFunctionalProxy([property], alovaInstance, configMap); + } + }); + // define global variable `Apis` + (globalThis as any).Apis = Apis; + return Apis; +}; +type MethodConfig = + (typeof import('./index'))['alovaInstance'] extends Alova + ? import('alova').AlovaMethodCreateConfig + : never; +type APISofParameters = Tag extends keyof Apis + ? Url extends keyof Apis[Tag] + ? Apis[Tag][Url] extends (...args: any) => any + ? Parameters + : any + : any + : any; +type MethodsConfigMap = { + [P in keyof typeof import('./apiDefinitions').default]?: MethodConfig< + P extends `${infer Tag}.${infer Url}` ? Parameters[0]['transformData']>[0] : any + >; +}; +export const withConfigType = (config: Config) => config; diff --git a/packages/wormhole/test/output/openapi_300/globals.d.ts b/packages/wormhole/test/output/openapi_300/globals.d.ts new file mode 100644 index 0000000..4be21dd --- /dev/null +++ b/packages/wormhole/test/output/openapi_300/globals.d.ts @@ -0,0 +1,2660 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.57 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, AlovaMethodCreateConfig, Method } from 'alova'; +import type { $$userConfigMap, alovaInstance } from '.'; +import type apiDefinitions from './apiDefinitions'; + +type CollapsedAlova = typeof alovaInstance; +type UserMethodConfigMap = typeof $$userConfigMap; + +type Alova2MethodConfig = + CollapsedAlova extends Alova + ? Omit, 'params'> + : never; + +// Extract the return type of transformData function that define in $$userConfigMap, if it not exists, use the default type. +type ExtractUserDefinedTransformed< + DefinitionKey extends keyof typeof apiDefinitions, + Default +> = DefinitionKey extends keyof UserMethodConfigMap + ? UserMethodConfigMap[DefinitionKey]['transformData'] extends (...args: any[]) => any + ? Awaited> + : Default + : Default; +type Alova2Method< + Responded, + DefinitionKey extends keyof typeof apiDefinitions, + CurrentConfig extends Alova2MethodConfig +> = + CollapsedAlova extends Alova + ? Method< + State, + Export, + CurrentConfig extends undefined + ? ExtractUserDefinedTransformed + : CurrentConfig['transformData'] extends (...args: any[]) => any + ? Awaited> + : ExtractUserDefinedTransformed, + any, + RequestConfig, + Response, + ResponseHeader + > + : never; + +export type AuthorizationValue = { + /** + * Authorization value + */ + value?: string; + /** + * Authorization key + */ + keyName?: string; + /** + * Authorization type + */ + type?: 'query' | 'header'; +}; +export type Options = { + /** + * authorization + * --- + * adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + */ + auth?: string; + /** + * authorization + * --- + * adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + */ + authorizationValue?: AuthorizationValue; + /** + * api package + * --- + * package for generated api classes + */ + apiPackage?: string; + /** + * Template Version + * --- + * template version for generation + */ + templateVersion?: string; + /** + * model package + * --- + * package for generated models + */ + modelPackage?: string; + /** + * model name prefix + * --- + * Prefix that will be prepended to all model names. Default is the empty string. + */ + modelNamePrefix?: string; + /** + * model name suffix + * --- + * PrefixSuffix that will be appended to all model names. Default is the empty string. + */ + modelNameSuffix?: string; + /** + * System Properties + * --- + * sets specified system properties in key/value format + */ + systemProperties?: Record; + /** + * instantiation types + * --- + * sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + */ + instantiationTypes?: Record; + /** + * type mappings + * --- + * sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + */ + typeMappings?: Record; + /** + * additional properties + * --- + * sets additional properties that can be referenced by the mustache templates in key/value format. + */ + additionalProperties?: Record; + /** + * language specific primitives + * --- + * specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + */ + languageSpecificPrimitives?: string[]; + /** + * import mappings + * --- + * specifies mappings between a given class and the import that should be used for that class in key/value format. + */ + importMappings?: Record; + /** + * invoker package + * --- + * root package for generated code + */ + invokerPackage?: string; + /** + * group id + * --- + * groupId in generated pom.xml + */ + groupId?: string; + /** + * artifact id + * --- + * artifactId in generated pom.xml + */ + artifactId?: string; + /** + * artifact version + * --- + * artifact version generated in pom.xml + */ + artifactVersion?: string; + /** + * library + * --- + * library template (sub-template) + */ + library?: string; + /** + * git user id + * --- + * Git user ID, e.g. swagger-api. + */ + gitUserId?: string; + /** + * git repo id + * --- + * Git repo ID, e.g. swagger-codegen. + */ + gitRepoId?: string; + /** + * release note + * --- + * Release note, default to 'Minor update'. + */ + releaseNote?: string; + /** + * http user agent + * --- + * HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + */ + httpUserAgent?: string; + /** + * reserved words mappings + * --- + * pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + */ + reservedWordsMappings?: Record; + /** + * ignore file override location + * --- + * Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + */ + ignoreFileOverride?: string; + /** + * remove prefix of the operationId + * --- + * Remove prefix of operationId, e.g. config_getId => getId + */ + removeOperationIdPrefix?: boolean; + skipOverride?: boolean; +}; +export type GenerationRequest = { + /** + * language + * --- + * language to generate (required)456 + * [required] + */ + lang: string; + /** + * spec in json format. . Alternative to `specURL` + */ + spec?: object; + /** + * URL of the spec in json format. Alternative to `spec` + */ + specURL?: string; + /** + * type of the spec + */ + type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG'; + /** + * codegen version to use + */ + codegenVersion?: 'V2' | 'V3'; + options?: Options; +}; +export type CliOption = { + optionName?: string; + description?: string; + /** + * Data type is based on the types supported by the JSON-Schema + */ + type?: string; + enum?: Record; + default?: string; +}; +export type RenderRequest = { + /** + * template + * --- + * template as string + * [required] + */ + template: string; + /** + * context + * --- + * context as string + * [required] + */ + context: string; +}; +declare global { + interface Apis { + clients: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = Blob + * ``` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * ``` + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to `specURL` + * spec?: object + * // URL of the spec in json format. Alternative to `spec` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = Blob + * ``` + */ + generate< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'client' or 'documentation' for given codegen version (defaults to V3) + * + * **path:** /clients + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * // flag to only return languages of type `client` + * clientOnly?: boolean + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = string[] + * ``` + */ + clientLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + /** + * flag to only return languages of type `client` + */ + clientOnly?: boolean; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * ```ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = string[] + * ``` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = string[] + * ``` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * ``` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'clients.listOptions', Config>; + /** + * --- + * + * [POST] 你好Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to `specURL` + * spec?: object + * // URL of the spec in json format. Alternative to `spec` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to `specURL` + * spec?: object + * // URL of the spec in json format. Alternative to `spec` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * ``` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + servers: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = Blob + * ``` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * ``` + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to `specURL` + * spec?: object + * // URL of the spec in json format. Alternative to `spec` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = Blob + * ``` + */ + generate< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'server' for given codegen version (defaults to V3) + * + * **path:** /servers + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = string[] + * ``` + */ + serverLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * ```ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = string[] + * ``` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = string[] + * ``` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * ``` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'servers.listOptions', Config>; + /** + * --- + * + * [POST] 你好Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to `specURL` + * spec?: object + * // URL of the spec in json format. Alternative to `spec` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to `specURL` + * spec?: object + * // URL of the spec in json format. Alternative to `spec` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * ``` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + documentation: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = Blob + * ``` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * ``` + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to `specURL` + * spec?: object + * // URL of the spec in json format. Alternative to `spec` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = Blob + * ``` + */ + generate< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'client' or 'documentation' for given codegen version (defaults to V3) + * + * **path:** /clients + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * // flag to only return languages of type `client` + * clientOnly?: boolean + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = string[] + * ``` + */ + clientLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + /** + * flag to only return languages of type `client` + */ + clientOnly?: boolean; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'documentation' for given codegen version (defaults to V3) + * + * **path:** /documentation + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = string[] + * ``` + */ + documentationLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * ```ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = string[] + * ``` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = string[] + * ``` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * ``` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'documentation.listOptions', Config>; + /** + * --- + * + * [POST] 你好Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to `specURL` + * spec?: object + * // URL of the spec in json format. Alternative to `spec` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to `specURL` + * spec?: object + * // URL of the spec in json format. Alternative to `spec` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * ``` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] render a template using the provided data + * + * **path:** /render + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = { + * // [title] template + * // template as string + * // [required] + * template: string + * // [title] context + * // context as string + * // [required] + * context: string + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = unknown + * ``` + */ + renderTemplate< + Config extends Alova2MethodConfig & { + data: RenderRequest; + } + >( + config: Config + ): Alova2Method; + }; + config: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = Blob + * ``` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * ``` + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to `specURL` + * spec?: object + * // URL of the spec in json format. Alternative to `spec` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = Blob + * ``` + */ + generate< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * ```ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = string[] + * ``` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = string[] + * ``` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * ``` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'config.listOptions', Config>; + /** + * --- + * + * [POST] 你好Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to `specURL` + * spec?: object + * // URL of the spec in json format. Alternative to `spec` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to `specURL` + * spec?: object + * // URL of the spec in json format. Alternative to `spec` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * ``` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + } + + var Apis: Apis; +} diff --git a/packages/wormhole/test/output/openapi_300/index.ts b/packages/wormhole/test/output/openapi_300/index.ts new file mode 100644 index 0000000..277abd6 --- /dev/null +++ b/packages/wormhole/test/output/openapi_300/index.ts @@ -0,0 +1,18 @@ +import { createAlova } from 'alova'; +import GlobalFetch from 'alova/GlobalFetch'; +import { createApis, withConfigType } from './createApis'; + +export const alovaInstance = createAlova({ + baseURL: '/api1', + requestAdapter: GlobalFetch(), + beforeRequest: method => {}, + responded: res => { + return res.json(); + } +}); + +export const $$userConfigMap = withConfigType({}); + +const Apis = createApis(alovaInstance, $$userConfigMap); + +export default Apis; diff --git a/packages/wormhole/tsconfig.json b/packages/wormhole/tsconfig.json index 4ca50de..b619d17 100644 --- a/packages/wormhole/tsconfig.json +++ b/packages/wormhole/tsconfig.json @@ -8,5 +8,5 @@ "#/*": ["./*"] } }, - "include": ["src/**/*.ts", "./*.ts", "typings/**/*.d.ts"] + "include": ["src/**/*.ts", "test/**/*", "./*.ts", "typings/**/*.d.ts"] } diff --git a/packages/wormhole/typings/index.d.ts b/packages/wormhole/typings/index.d.ts index 968e3de..8a8b588 100644 --- a/packages/wormhole/typings/index.d.ts +++ b/packages/wormhole/typings/index.d.ts @@ -29,36 +29,36 @@ export type GeneratorConfig = { // 支持openapi的平台,目前先支持swagger、knife4j、yapi,默认为空 // 当指定了此参数后,input字段只需要指定文档的地址而不需要指定到openapi文件,减小使用门槛 // 不同平台,它的openapi文件地址不一样,根据平台标识去对应地址下读取文件即可。 - platform: PlatformType; + platform?: PlatformType; // 接口文件和类型文件的输出路径,多个generator不能重复的地址,否则生成的代码会相互覆盖,无意义 output: string; // (具体看下面)指定生成的响应数据的mediaType,指定后以此数据类型来生成200状态码的响应ts格式,默认application/json - responseMediaType: string; + responseMediaType?: string; // (具体看下面)指定生成的请求体数据的mediaType,指定后以此数据类型来生成请求体的ts格式,默认application/json - bodyMediaType: string; + bodyMediaType?: string; // 生成代码的类型,可选值为auto/ts/typescript/module/commonjs,默认为auto,会通过一定规则判断当前项目的类型 // ts/typescript:意思相同,表示生成ts类型文件 // module:生成esModule规范文件 // commonjs:表示生成commonjs规范文件 - type: ConfigType; + type?: ConfigType; // 指定alova版本 - version: Number; + version?: number; // 多项目使用global字段 global?: string; // 是否使用import来导入类型,默认false // 开启此选项后,生成的apiDefinitions.ts文件将使用import语法来导入类型,而不是/// - useImportType: boolean; + useImportType?: boolean; // 没有require时默认为require,只有nullable生效 defaultRequire?: boolean; // (具体看下面)过滤或转换生成的api接口函数,返回一个新的apiDescriptor来生成api调用函数 // 未指定此函数时则不转换apiDescripor对象 // apiDescriptor的格式与openapi文件的接口对象格式相同 // 对类型生成也同样适用 - handleApi: HandleApi; + handleApi?: HandleApi; }; export type Config = { // api生成设置,为数组,每项代表一个自动生成的规则,包含生成的输入输出目录、规范文件地址等等 @@ -66,11 +66,11 @@ export type Config = { generator: GeneratorConfig[]; // 是否自动更新接口,默认开启,每5分钟检查一次,false时关闭 - autoUpdate: + autoUpdate?: | boolean | { // 编辑器开启时更新,默认false - launchEditor: boolean; + launchEditor?: boolean; // 自动更新间隔,单位毫秒 interval: number; }; diff --git a/packages/wormhole/vitest.config.ts b/packages/wormhole/vitest.config.ts new file mode 100644 index 0000000..74936c8 --- /dev/null +++ b/packages/wormhole/vitest.config.ts @@ -0,0 +1,11 @@ +import { resolve } from 'node:path'; +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + alias: { + '@': resolve(__dirname, 'src') + }, + globals: true + } +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0cc34c6..2248f79 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -117,6 +117,9 @@ importers: typescript: specifier: ^5.5.4 version: 5.5.4 + vitest: + specifier: ^2.0.5 + version: 2.0.5(@types/node@18.19.34) packages/vscode-extension: devDependencies: @@ -172,6 +175,9 @@ importers: fs-extra: specifier: ^11.2.0 version: 11.2.0 + memfs: + specifier: ^4.11.1 + version: 4.11.1 openapi-types: specifier: ^12.1.3 version: 12.1.3 @@ -1121,6 +1127,24 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jsonjoy.com/base64@1.1.2': + resolution: {integrity: sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pack@1.1.0': + resolution: {integrity: sha512-zlQONA+msXPPwHWZMKFVS78ewFczIll5lXiVPwFPCZUsrOKdxc2AvxU1HoNBmMRhqDZUR9HkC3UOm+6pME6Xsg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/util@1.3.0': + resolution: {integrity: sha512-Cebt4Vk7k1xHy87kHY7KSPLT77A7Ev7IfOblyLZhtYEhrdQ6fX4EoLq3xOQ3O/DRMEh2ok5nyC180E+ABS8Wmw==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -1195,6 +1219,86 @@ packages: rollup: optional: true + '@rollup/rollup-android-arm-eabi@4.21.2': + resolution: {integrity: sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.21.2': + resolution: {integrity: sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.21.2': + resolution: {integrity: sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.21.2': + resolution: {integrity: sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-linux-arm-gnueabihf@4.21.2': + resolution: {integrity: sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.21.2': + resolution: {integrity: sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.21.2': + resolution: {integrity: sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.21.2': + resolution: {integrity: sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.21.2': + resolution: {integrity: sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.21.2': + resolution: {integrity: sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.21.2': + resolution: {integrity: sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.21.2': + resolution: {integrity: sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.21.2': + resolution: {integrity: sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.21.2': + resolution: {integrity: sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.21.2': + resolution: {integrity: sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.21.2': + resolution: {integrity: sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==} + cpu: [x64] + os: [win32] + '@trysound/sax@0.2.0': resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} @@ -1323,6 +1427,24 @@ packages: '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + '@vitest/expect@2.0.5': + resolution: {integrity: sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==} + + '@vitest/pretty-format@2.0.5': + resolution: {integrity: sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==} + + '@vitest/runner@2.0.5': + resolution: {integrity: sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==} + + '@vitest/snapshot@2.0.5': + resolution: {integrity: sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==} + + '@vitest/spy@2.0.5': + resolution: {integrity: sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==} + + '@vitest/utils@2.0.5': + resolution: {integrity: sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==} + '@vscode/test-cli@0.0.9': resolution: {integrity: sha512-vsl5/ueE3Jf0f6XzB0ECHHMsd5A0Yu6StElb8a+XsubZW7kHNAOw4Y3TSSuDzKEpLnJ92nbMy1Zl+KLGCE6NaA==} engines: {node: '>=18'} @@ -1537,6 +1659,10 @@ packages: resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} engines: {node: '>= 0.4'} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} @@ -1626,6 +1752,10 @@ packages: engines: {node: '>=14.14.0'} hasBin: true + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + cachedir@2.3.0: resolution: {integrity: sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==} engines: {node: '>=6'} @@ -1657,6 +1787,10 @@ packages: capital-case@1.0.4: resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} + chai@5.1.1: + resolution: {integrity: sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==} + engines: {node: '>=12'} + chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -1675,6 +1809,10 @@ packages: chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + cheerio-select@2.1.0: resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} @@ -1955,6 +2093,10 @@ packages: dedent@0.7.0: resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} @@ -2285,6 +2427,9 @@ packages: estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -2433,6 +2578,9 @@ packages: resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} engines: {node: '>=18'} + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + get-intrinsic@1.2.4: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} @@ -2601,6 +2749,10 @@ packages: engines: {node: '>=18'} hasBin: true + hyperdyperid@1.2.0: + resolution: {integrity: sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==} + engines: {node: '>=10.18'} + iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -3073,6 +3225,9 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + loupe@3.1.1: + resolution: {integrity: sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==} + lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} @@ -3107,6 +3262,10 @@ packages: mdurl@1.0.1: resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} + memfs@4.11.1: + resolution: {integrity: sha512-LZcMTBAgqUUKNXZagcZxvXXfgF1bHX7Y7nQ0QyEiNbRJgE29GhgPd8Yna1VQcLlPiHt/5RFJMWYN9Uv/VPNvjQ==} + engines: {node: '>= 4.0.0'} + memorystream@0.3.1: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} @@ -3471,6 +3630,10 @@ packages: pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + pend@1.2.0: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} @@ -3868,6 +4031,11 @@ packages: engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true + rollup@4.21.2: + resolution: {integrity: sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} @@ -3977,6 +4145,9 @@ packages: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} engines: {node: '>= 0.4'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -4036,6 +4207,12 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + stdin-discarder@0.1.0: resolution: {integrity: sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -4178,9 +4355,30 @@ packages: text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + thingies@1.21.0: + resolution: {integrity: sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==} + engines: {node: '>=10.18'} + peerDependencies: + tslib: ^2 + through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinypool@1.0.1: + resolution: {integrity: sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -4200,6 +4398,12 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + tree-dump@1.0.2: + resolution: {integrity: sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + ts-api-utils@1.3.0: resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} engines: {node: '>=16'} @@ -4348,6 +4552,67 @@ packages: validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + vite-node@2.0.5: + resolution: {integrity: sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite@5.4.3: + resolution: {integrity: sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitest@2.0.5: + resolution: {integrity: sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.0.5 + '@vitest/ui': 2.0.5 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + vue@3.4.31: resolution: {integrity: sha512-njqRrOy7W3YLAlVqSKpBebtZpDVg21FPoaq1I7f/+qqBThK9ChAIjkRWgeP6Eat+8C+iia4P3OYqpATP21BCoQ==} peerDependencies: @@ -4389,6 +4654,11 @@ packages: engines: {node: '>= 8'} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} @@ -5184,6 +5454,22 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.4.15 + '@jsonjoy.com/base64@1.1.2(tslib@2.7.0)': + dependencies: + tslib: 2.7.0 + + '@jsonjoy.com/json-pack@1.1.0(tslib@2.7.0)': + dependencies: + '@jsonjoy.com/base64': 1.1.2(tslib@2.7.0) + '@jsonjoy.com/util': 1.3.0(tslib@2.7.0) + hyperdyperid: 1.2.0 + thingies: 1.21.0(tslib@2.7.0) + tslib: 2.7.0 + + '@jsonjoy.com/util@1.3.0(tslib@2.7.0)': + dependencies: + tslib: 2.7.0 + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -5250,6 +5536,54 @@ snapshots: optionalDependencies: rollup: 3.29.4 + '@rollup/rollup-android-arm-eabi@4.21.2': + optional: true + + '@rollup/rollup-android-arm64@4.21.2': + optional: true + + '@rollup/rollup-darwin-arm64@4.21.2': + optional: true + + '@rollup/rollup-darwin-x64@4.21.2': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.21.2': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.21.2': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.21.2': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.21.2': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.21.2': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.21.2': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.21.2': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.21.2': + optional: true + + '@rollup/rollup-linux-x64-musl@4.21.2': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.21.2': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.21.2': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.21.2': + optional: true + '@trysound/sax@0.2.0': {} '@types/conventional-commits-parser@5.0.0': @@ -5401,6 +5735,39 @@ snapshots: '@ungap/structured-clone@1.2.0': {} + '@vitest/expect@2.0.5': + dependencies: + '@vitest/spy': 2.0.5 + '@vitest/utils': 2.0.5 + chai: 5.1.1 + tinyrainbow: 1.2.0 + + '@vitest/pretty-format@2.0.5': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/runner@2.0.5': + dependencies: + '@vitest/utils': 2.0.5 + pathe: 1.1.2 + + '@vitest/snapshot@2.0.5': + dependencies: + '@vitest/pretty-format': 2.0.5 + magic-string: 0.30.10 + pathe: 1.1.2 + + '@vitest/spy@2.0.5': + dependencies: + tinyspy: 3.0.2 + + '@vitest/utils@2.0.5': + dependencies: + '@vitest/pretty-format': 2.0.5 + estree-walker: 3.0.3 + loupe: 3.1.1 + tinyrainbow: 1.2.0 + '@vscode/test-cli@0.0.9': dependencies: '@types/mocha': 10.0.6 @@ -5708,6 +6075,8 @@ snapshots: is-array-buffer: 3.0.4 is-shared-array-buffer: 1.0.3 + assertion-error@2.0.1: {} + ast-types-flow@0.0.8: {} asynckit@0.4.0: {} @@ -5811,6 +6180,8 @@ snapshots: yargs: 17.7.2 yargs-parser: 21.1.1 + cac@6.7.14: {} + cachedir@2.3.0: {} call-bind@1.0.7: @@ -5847,6 +6218,14 @@ snapshots: tslib: 2.6.3 upper-case-first: 2.0.2 + chai@5.1.1: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.1 + pathval: 2.0.0 + chalk@2.4.2: dependencies: ansi-styles: 3.2.1 @@ -5877,6 +6256,8 @@ snapshots: chardet@0.7.0: {} + check-error@2.1.1: {} + cheerio-select@2.1.0: dependencies: boolbase: 1.0.0 @@ -6221,6 +6602,8 @@ snapshots: dedent@0.7.0: {} + deep-eql@5.0.2: {} + deep-extend@0.6.0: optional: true @@ -6748,6 +7131,10 @@ snapshots: estree-walker@2.0.2: {} + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.5 + esutils@2.0.3: {} eventemitter3@5.0.1: {} @@ -6907,6 +7294,8 @@ snapshots: get-east-asian-width@1.2.0: {} + get-func-name@2.0.2: {} + get-intrinsic@1.2.4: dependencies: es-errors: 1.3.0 @@ -7102,6 +7491,8 @@ snapshots: husky@9.0.11: {} + hyperdyperid@1.2.0: {} + iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 @@ -7570,6 +7961,10 @@ snapshots: dependencies: js-tokens: 4.0.0 + loupe@3.1.1: + dependencies: + get-func-name: 2.0.2 + lower-case@2.0.2: dependencies: tslib: 2.6.3 @@ -7606,6 +8001,13 @@ snapshots: mdurl@1.0.1: {} + memfs@4.11.1: + dependencies: + '@jsonjoy.com/json-pack': 1.1.0(tslib@2.7.0) + '@jsonjoy.com/util': 1.3.0(tslib@2.7.0) + tree-dump: 1.0.2(tslib@2.7.0) + tslib: 2.7.0 + memorystream@0.3.1: {} meow@12.1.1: {} @@ -8019,6 +8421,8 @@ snapshots: pathe@1.1.2: {} + pathval@2.0.0: {} + pend@1.2.0: {} picocolors@1.0.1: {} @@ -8406,6 +8810,28 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + rollup@4.21.2: + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.21.2 + '@rollup/rollup-android-arm64': 4.21.2 + '@rollup/rollup-darwin-arm64': 4.21.2 + '@rollup/rollup-darwin-x64': 4.21.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.21.2 + '@rollup/rollup-linux-arm-musleabihf': 4.21.2 + '@rollup/rollup-linux-arm64-gnu': 4.21.2 + '@rollup/rollup-linux-arm64-musl': 4.21.2 + '@rollup/rollup-linux-powerpc64le-gnu': 4.21.2 + '@rollup/rollup-linux-riscv64-gnu': 4.21.2 + '@rollup/rollup-linux-s390x-gnu': 4.21.2 + '@rollup/rollup-linux-x64-gnu': 4.21.2 + '@rollup/rollup-linux-x64-musl': 4.21.2 + '@rollup/rollup-win32-arm64-msvc': 4.21.2 + '@rollup/rollup-win32-ia32-msvc': 4.21.2 + '@rollup/rollup-win32-x64-msvc': 4.21.2 + fsevents: 2.3.3 + run-async@2.4.1: {} run-parallel@1.2.0: @@ -8522,6 +8948,8 @@ snapshots: get-intrinsic: 1.2.4 object-inspect: 1.13.1 + siginfo@2.0.0: {} + signal-exit@3.0.7: {} signal-exit@4.1.0: {} @@ -8577,6 +9005,10 @@ snapshots: sprintf-js@1.0.3: {} + stackback@0.0.2: {} + + std-env@3.7.0: {} + stdin-discarder@0.1.0: dependencies: bl: 5.1.0 @@ -8759,8 +9191,20 @@ snapshots: text-table@0.2.0: {} + thingies@1.21.0(tslib@2.7.0): + dependencies: + tslib: 2.7.0 + through@2.3.8: {} + tinybench@2.9.0: {} + + tinypool@1.0.1: {} + + tinyrainbow@1.2.0: {} + + tinyspy@3.0.2: {} + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 @@ -8775,6 +9219,10 @@ snapshots: tr46@0.0.3: {} + tree-dump@1.0.2(tslib@2.7.0): + dependencies: + tslib: 2.7.0 + ts-api-utils@1.3.0(typescript@5.5.4): dependencies: typescript: 5.5.4 @@ -8963,6 +9411,66 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 + vite-node@2.0.5(@types/node@18.19.34): + dependencies: + cac: 6.7.14 + debug: 4.3.5 + pathe: 1.1.2 + tinyrainbow: 1.2.0 + vite: 5.4.3(@types/node@18.19.34) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite@5.4.3(@types/node@18.19.34): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.45 + rollup: 4.21.2 + optionalDependencies: + '@types/node': 18.19.34 + fsevents: 2.3.3 + + vitest@2.0.5(@types/node@18.19.34): + dependencies: + '@ampproject/remapping': 2.3.0 + '@vitest/expect': 2.0.5 + '@vitest/pretty-format': 2.0.5 + '@vitest/runner': 2.0.5 + '@vitest/snapshot': 2.0.5 + '@vitest/spy': 2.0.5 + '@vitest/utils': 2.0.5 + chai: 5.1.1 + debug: 4.3.5 + execa: 8.0.1 + magic-string: 0.30.10 + pathe: 1.1.2 + std-env: 3.7.0 + tinybench: 2.9.0 + tinypool: 1.0.1 + tinyrainbow: 1.2.0 + vite: 5.4.3(@types/node@18.19.34) + vite-node: 2.0.5(@types/node@18.19.34) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 18.19.34 + transitivePeerDependencies: + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vue@3.4.31(typescript@5.4.5): dependencies: '@vue/compiler-dom': 3.4.31 @@ -9040,6 +9548,11 @@ snapshots: dependencies: isexe: 2.0.0 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + word-wrap@1.2.5: {} wordwrap@1.0.0: {} diff --git a/tsconfig.base.json b/tsconfig.base.json index 7ec6acb..706976d 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -21,10 +21,6 @@ "inlineSourceMap": false, "importHelpers": true, "removeComments": false, - "jsx": "preserve", - "paths": { - "#/*": ["./*"], - "@alova/*": ["./packages/src/*"] - } + "types": ["vitest/globals"] } } diff --git a/vitest.workspace.ts b/vitest.workspace.ts new file mode 100644 index 0000000..2746826 --- /dev/null +++ b/vitest.workspace.ts @@ -0,0 +1,3 @@ +import { defineWorkspace } from 'vitest/config'; + +export default defineWorkspace(['packages/*']); From ad607fa8bc2fefe0e55f8b5ff8928dbb2a898a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E9=95=87?= Date: Fri, 13 Sep 2024 15:00:22 +0800 Subject: [PATCH 22/47] fix: transform to FormData when data contains blob --- package.json | 3 ++- packages/wormhole/package.json | 2 +- .../src/templates/commonjs/createApis.handlebars | 14 +++++++++++++- .../templates/commonjs/v3-createApis.handlebars | 14 +++++++++++++- .../src/templates/module/createApis.handlebars | 14 +++++++++++++- .../src/templates/module/v3-createApis.handlebars | 14 +++++++++++++- .../src/templates/typescript/createApis.handlebars | 14 +++++++++++++- .../templates/typescript/v3-createApis.handlebars | 14 +++++++++++++- 8 files changed, 81 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 4598f04..d168bf9 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,9 @@ { "name": "@alova/devtools", "displayName": "Alova", - "description": "The devtools for alova.js", + "description": "devtool kits for alova.js", "version": "0.0.9", + "private": true, "engines": { "node": ">=18.19.0", "pnpm": ">=8.6.12" diff --git a/packages/wormhole/package.json b/packages/wormhole/package.json index 6beaa4a..8830280 100644 --- a/packages/wormhole/package.json +++ b/packages/wormhole/package.json @@ -1,7 +1,7 @@ { "name": "@alova/wormhole", "version": "1.0.0", - "description": "generate api for alova.js", + "description": "More modern openAPI generating solution for alova.js", "homepage": "https://alova.js.org", "main": "./dist/index.cjs", "module": "./dist/index.mjs", diff --git a/packages/wormhole/src/templates/commonjs/createApis.handlebars b/packages/wormhole/src/templates/commonjs/createApis.handlebars index 012049b..ea90ab4 100644 --- a/packages/wormhole/src/templates/commonjs/createApis.handlebars +++ b/packages/wormhole/src/templates/commonjs/createApis.handlebars @@ -28,12 +28,24 @@ const createFunctionalProxy = (array, alovaInstance, configMap) => { ...config }; const [method, url] = apiItem; - const { pathParams, data } = mergedConfig; + const pathParams = mergedConfig.pathParams; const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => { const pathParam = pathParams[key]; return pathParam; }); delete mergedConfig.pathParams; + let data = mergedConfig.data; + if (Object.prototype.toString.call(data) === '[object Object]') { + let hasBlobData = false; + const formData = new FormData(); + for (const key in data) { + formData.append(key, data[key]); + if (data[key] instanceof Blob) { + hasBlobData = true; + } + } + data = hasBlobData ? formData : data; + } return new Method(method.toUpperCase(), alovaInstance, urlReplaced, mergedConfig, data); } }); diff --git a/packages/wormhole/src/templates/commonjs/v3-createApis.handlebars b/packages/wormhole/src/templates/commonjs/v3-createApis.handlebars index e71dc5f..b286a23 100644 --- a/packages/wormhole/src/templates/commonjs/v3-createApis.handlebars +++ b/packages/wormhole/src/templates/commonjs/v3-createApis.handlebars @@ -31,12 +31,24 @@ const createFunctionalProxy = (array, alovaInstance, configMap) => { ...config }; const [method, url] = apiItem; - const { pathParams, data } = mergedConfig; + const pathParams = mergedConfig.pathParams; const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => { const pathParam = pathParams[key]; return pathParam; }); delete mergedConfig.pathParams; + let data = mergedConfig.data; + if (Object.prototype.toString.call(data) === '[object Object]') { + let hasBlobData = false; + const formData = new FormData(); + for (const key in data) { + formData.append(key, data[key]); + if (data[key] instanceof Blob) { + hasBlobData = true; + } + } + data = hasBlobData ? formData : data; + } return new Method(method.toUpperCase(), alovaInstance, urlReplaced, mergedConfig, data); } }); diff --git a/packages/wormhole/src/templates/module/createApis.handlebars b/packages/wormhole/src/templates/module/createApis.handlebars index ad7ee77..e707f79 100644 --- a/packages/wormhole/src/templates/module/createApis.handlebars +++ b/packages/wormhole/src/templates/module/createApis.handlebars @@ -28,12 +28,24 @@ const createFunctionalProxy = (array, alovaInstance, configMap) => { ...config }; const [method, url] = apiItem; - const { pathParams, data } = mergedConfig; + const pathParams = mergedConfig.pathParams; const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => { const pathParam = pathParams[key]; return pathParam; }); delete mergedConfig.pathParams; + let data = mergedConfig.data; + if (Object.prototype.toString.call(data) === '[object Object]') { + let hasBlobData = false; + const formData = new FormData(); + for (const key in data) { + formData.append(key, data[key]); + if (data[key] instanceof Blob) { + hasBlobData = true; + } + } + data = hasBlobData ? formData : data; + } return new Method(method.toUpperCase(), alovaInstance, urlReplaced, mergedConfig, data); } }); diff --git a/packages/wormhole/src/templates/module/v3-createApis.handlebars b/packages/wormhole/src/templates/module/v3-createApis.handlebars index fe9d5be..20f3016 100644 --- a/packages/wormhole/src/templates/module/v3-createApis.handlebars +++ b/packages/wormhole/src/templates/module/v3-createApis.handlebars @@ -31,12 +31,24 @@ const createFunctionalProxy = (array, alovaInstance, configMap) => { ...config }; const [method, url] = apiItem; - const { pathParams, data } = mergedConfig; + const pathParams = mergedConfig.pathParams; const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => { const pathParam = pathParams[key]; return pathParam; }); delete mergedConfig.pathParams; + let data = mergedConfig.data; + if (Object.prototype.toString.call(data) === '[object Object]') { + let hasBlobData = false; + const formData = new FormData(); + for (const key in data) { + formData.append(key, data[key]); + if (data[key] instanceof Blob) { + hasBlobData = true; + } + } + data = hasBlobData ? formData : data; + } return new Method(method.toUpperCase(), alovaInstance, urlReplaced, mergedConfig, data); } }); diff --git a/packages/wormhole/src/templates/typescript/createApis.handlebars b/packages/wormhole/src/templates/typescript/createApis.handlebars index d8e0b4c..d15bc0c 100644 --- a/packages/wormhole/src/templates/typescript/createApis.handlebars +++ b/packages/wormhole/src/templates/typescript/createApis.handlebars @@ -27,12 +27,24 @@ const createFunctionalProxy = ( ...config }; const [method, url] = apiItem; - const { pathParams, data } = mergedConfig; + const pathParams = mergedConfig.pathParams; const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => { const pathParam = pathParams[key]; return pathParam; }); delete mergedConfig.pathParams; + let data = mergedConfig.data; + if (Object.prototype.toString.call(data) === '[object Object]') { + let hasBlobData = false; + const formData = new FormData(); + for (const key in data) { + formData.append(key, data[key]); + if (data[key] instanceof Blob) { + hasBlobData = true; + } + } + data = hasBlobData ? formData : data; + } return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data); } }); diff --git a/packages/wormhole/src/templates/typescript/v3-createApis.handlebars b/packages/wormhole/src/templates/typescript/v3-createApis.handlebars index 42bdaa1..f568035 100644 --- a/packages/wormhole/src/templates/typescript/v3-createApis.handlebars +++ b/packages/wormhole/src/templates/typescript/v3-createApis.handlebars @@ -32,12 +32,24 @@ const createFunctionalProxy = ( ...config }; const [method, url] = apiItem; - const { pathParams, data } = mergedConfig; + const pathParams = mergedConfig.pathParams; const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => { const pathParam = pathParams[key]; return pathParam; }); delete mergedConfig.pathParams; + let data = mergedConfig.data; + if (Object.prototype.toString.call(data) === '[object Object]') { + let hasBlobData = false; + const formData = new FormData(); + for (const key in data) { + formData.append(key, data[key]); + if (data[key] instanceof Blob) { + hasBlobData = true; + } + } + data = hasBlobData ? formData : data; + } return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data); } }); From 64e0bb9f96c5b92bc91b4faf9b6791a8dc003692 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E9=95=87?= Date: Wed, 18 Sep 2024 17:48:26 +0800 Subject: [PATCH 23/47] fix: detect `FormData` existence --- packages/wormhole/src/templates/commonjs/createApis.handlebars | 2 +- .../wormhole/src/templates/commonjs/v3-createApis.handlebars | 2 +- packages/wormhole/src/templates/module/createApis.handlebars | 2 +- packages/wormhole/src/templates/module/v3-createApis.handlebars | 2 +- .../wormhole/src/templates/typescript/createApis.handlebars | 2 +- .../wormhole/src/templates/typescript/v3-createApis.handlebars | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/wormhole/src/templates/commonjs/createApis.handlebars b/packages/wormhole/src/templates/commonjs/createApis.handlebars index ea90ab4..8f51b41 100644 --- a/packages/wormhole/src/templates/commonjs/createApis.handlebars +++ b/packages/wormhole/src/templates/commonjs/createApis.handlebars @@ -35,7 +35,7 @@ const createFunctionalProxy = (array, alovaInstance, configMap) => { }); delete mergedConfig.pathParams; let data = mergedConfig.data; - if (Object.prototype.toString.call(data) === '[object Object]') { + if (Object.prototype.toString.call(data) === '[object Object]' && typeof FormData !== 'undefined') { let hasBlobData = false; const formData = new FormData(); for (const key in data) { diff --git a/packages/wormhole/src/templates/commonjs/v3-createApis.handlebars b/packages/wormhole/src/templates/commonjs/v3-createApis.handlebars index b286a23..63df902 100644 --- a/packages/wormhole/src/templates/commonjs/v3-createApis.handlebars +++ b/packages/wormhole/src/templates/commonjs/v3-createApis.handlebars @@ -38,7 +38,7 @@ const createFunctionalProxy = (array, alovaInstance, configMap) => { }); delete mergedConfig.pathParams; let data = mergedConfig.data; - if (Object.prototype.toString.call(data) === '[object Object]') { + if (Object.prototype.toString.call(data) === '[object Object]' && typeof FormData !== 'undefined') { let hasBlobData = false; const formData = new FormData(); for (const key in data) { diff --git a/packages/wormhole/src/templates/module/createApis.handlebars b/packages/wormhole/src/templates/module/createApis.handlebars index e707f79..5fd67f8 100644 --- a/packages/wormhole/src/templates/module/createApis.handlebars +++ b/packages/wormhole/src/templates/module/createApis.handlebars @@ -35,7 +35,7 @@ const createFunctionalProxy = (array, alovaInstance, configMap) => { }); delete mergedConfig.pathParams; let data = mergedConfig.data; - if (Object.prototype.toString.call(data) === '[object Object]') { + if (Object.prototype.toString.call(data) === '[object Object]' && typeof FormData !== 'undefined') { let hasBlobData = false; const formData = new FormData(); for (const key in data) { diff --git a/packages/wormhole/src/templates/module/v3-createApis.handlebars b/packages/wormhole/src/templates/module/v3-createApis.handlebars index 20f3016..d24d400 100644 --- a/packages/wormhole/src/templates/module/v3-createApis.handlebars +++ b/packages/wormhole/src/templates/module/v3-createApis.handlebars @@ -38,7 +38,7 @@ const createFunctionalProxy = (array, alovaInstance, configMap) => { }); delete mergedConfig.pathParams; let data = mergedConfig.data; - if (Object.prototype.toString.call(data) === '[object Object]') { + if (Object.prototype.toString.call(data) === '[object Object]' && typeof FormData !== 'undefined') { let hasBlobData = false; const formData = new FormData(); for (const key in data) { diff --git a/packages/wormhole/src/templates/typescript/createApis.handlebars b/packages/wormhole/src/templates/typescript/createApis.handlebars index d15bc0c..964e7a3 100644 --- a/packages/wormhole/src/templates/typescript/createApis.handlebars +++ b/packages/wormhole/src/templates/typescript/createApis.handlebars @@ -34,7 +34,7 @@ const createFunctionalProxy = ( }); delete mergedConfig.pathParams; let data = mergedConfig.data; - if (Object.prototype.toString.call(data) === '[object Object]') { + if (Object.prototype.toString.call(data) === '[object Object]' && typeof FormData !== 'undefined') { let hasBlobData = false; const formData = new FormData(); for (const key in data) { diff --git a/packages/wormhole/src/templates/typescript/v3-createApis.handlebars b/packages/wormhole/src/templates/typescript/v3-createApis.handlebars index f568035..207d5b1 100644 --- a/packages/wormhole/src/templates/typescript/v3-createApis.handlebars +++ b/packages/wormhole/src/templates/typescript/v3-createApis.handlebars @@ -39,7 +39,7 @@ const createFunctionalProxy = ( }); delete mergedConfig.pathParams; let data = mergedConfig.data; - if (Object.prototype.toString.call(data) === '[object Object]') { + if (Object.prototype.toString.call(data) === '[object Object]' && typeof FormData !== 'undefined') { let hasBlobData = false; const formData = new FormData(); for (const key in data) { From 500513938d4f9009db39a7eb0e0ba847ebdb747e Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Thu, 19 Sep 2024 19:00:42 +0800 Subject: [PATCH 24/47] =?UTF-8?q?test(=E6=B7=BB=E5=8A=A0readconfig=20?= =?UTF-8?q?=E6=B5=8B=E8=AF=95):=20=E4=BF=AE=E5=A4=8Dreadconfig=E6=B2=A1?= =?UTF-8?q?=E6=B3=95=E8=B7=91=E9=80=9A=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 + packages/wormhole/src/index.ts | 2 + .../test/__snapshots__/generate.spec.ts.snap | 74 +++- packages/wormhole/test/config.spec.ts | 347 +++++++++++------- packages/wormhole/test/util.ts | 26 ++ packages/wormhole/typings/vitest.d.ts | 10 + pnpm-lock.yaml | 85 +++++ 7 files changed, 409 insertions(+), 137 deletions(-) create mode 100644 packages/wormhole/test/util.ts create mode 100644 packages/wormhole/typings/vitest.d.ts diff --git a/package.json b/package.json index d168bf9..d5c074d 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "@types/mocha": "^10.0.6", "@types/node": "18.x", "@types/node-fetch": "^2.6.11", + "@types/rimraf": "^4.0.5", "@types/serialize-javascript": "^5.0.4", "@types/swagger2openapi": "^7.0.4", "@typescript-eslint/eslint-plugin": "^7.13.0", @@ -56,6 +57,7 @@ "prettier": "^3.2.5", "prettier-plugin-organize-imports": "^3.2.4", "prettier-plugin-sort-json": "^4.0.0", + "rimraf": "^6.0.1", "tslib": "^2.7.0", "tsx": "^4.15.8", "type-fest": "^4.20.0", diff --git a/packages/wormhole/src/index.ts b/packages/wormhole/src/index.ts index abe627c..e36ea55 100644 --- a/packages/wormhole/src/index.ts +++ b/packages/wormhole/src/index.ts @@ -1,3 +1,5 @@ +export type * from '~/index'; +export { setGlobalConfig } from './config'; export { default as createConfig } from './createConfig'; export { default as generate } from './generate'; export * from './readConfig'; diff --git a/packages/wormhole/test/__snapshots__/generate.spec.ts.snap b/packages/wormhole/test/__snapshots__/generate.spec.ts.snap index 884c3f1..8281268 100644 --- a/packages/wormhole/test/__snapshots__/generate.spec.ts.snap +++ b/packages/wormhole/test/__snapshots__/generate.spec.ts.snap @@ -119,12 +119,24 @@ const createFunctionalProxy = ( ...config }; const [method, url] = apiItem; - const { pathParams, data } = mergedConfig; + const pathParams = mergedConfig.pathParams; const urlReplaced = url.replace(/\\{([^}]+)\\}/g, (_, key) => { const pathParam = pathParams[key]; return pathParam; }); delete mergedConfig.pathParams; + let data = mergedConfig.data; + if (Object.prototype.toString.call(data) === '[object Object]' && typeof FormData !== 'undefined') { + let hasBlobData = false; + const formData = new FormData(); + for (const key in data) { + formData.append(key, data[key]); + if (data[key] instanceof Blob) { + hasBlobData = true; + } + } + data = hasBlobData ? formData : data; + } return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data); } }); @@ -2936,12 +2948,24 @@ const createFunctionalProxy = ( ...config }; const [method, url] = apiItem; - const { pathParams, data } = mergedConfig; + const pathParams = mergedConfig.pathParams; const urlReplaced = url.replace(/\\{([^}]+)\\}/g, (_, key) => { const pathParam = pathParams[key]; return pathParam; }); delete mergedConfig.pathParams; + let data = mergedConfig.data; + if (Object.prototype.toString.call(data) === '[object Object]' && typeof FormData !== 'undefined') { + let hasBlobData = false; + const formData = new FormData(); + for (const key in data) { + formData.append(key, data[key]); + if (data[key] instanceof Blob) { + hasBlobData = true; + } + } + data = hasBlobData ? formData : data; + } return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data); } }); @@ -4094,12 +4118,24 @@ const createFunctionalProxy = ( ...config }; const [method, url] = apiItem; - const { pathParams, data } = mergedConfig; + const pathParams = mergedConfig.pathParams; const urlReplaced = url.replace(/\\{([^}]+)\\}/g, (_, key) => { const pathParam = pathParams[key]; return pathParam; }); delete mergedConfig.pathParams; + let data = mergedConfig.data; + if (Object.prototype.toString.call(data) === '[object Object]' && typeof FormData !== 'undefined') { + let hasBlobData = false; + const formData = new FormData(); + for (const key in data) { + formData.append(key, data[key]); + if (data[key] instanceof Blob) { + hasBlobData = true; + } + } + data = hasBlobData ? formData : data; + } return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data); } }); @@ -5322,12 +5358,24 @@ const createFunctionalProxy = ( ...config }; const [method, url] = apiItem; - const { pathParams, data } = mergedConfig; + const pathParams = mergedConfig.pathParams; const urlReplaced = url.replace(/\\{([^}]+)\\}/g, (_, key) => { const pathParam = pathParams[key]; return pathParam; }); delete mergedConfig.pathParams; + let data = mergedConfig.data; + if (Object.prototype.toString.call(data) === '[object Object]' && typeof FormData !== 'undefined') { + let hasBlobData = false; + const formData = new FormData(); + for (const key in data) { + formData.append(key, data[key]); + if (data[key] instanceof Blob) { + hasBlobData = true; + } + } + data = hasBlobData ? formData : data; + } return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data); } }); @@ -8081,12 +8129,12 @@ export default { exports[`generate API > should generate target versioned code 6`] = ` "import { createAlova } from 'alova'; -import fetchAdapter from 'alova/fetch'; +import GlobalFetch from 'alova/GlobalFetch'; import { createApis, withConfigType } from './createApis'; export const alovaInstance = createAlova({ baseURL: '/api1', - requestAdapter: fetchAdapter(), + requestAdapter: GlobalFetch(), beforeRequest: method => {}, responded: res => { return res.json(); @@ -8142,12 +8190,24 @@ const createFunctionalProxy = (array: (string | symbol)[], alovaInstance: Alova< ...config }; const [method, url] = apiItem; - const { pathParams, data } = mergedConfig; + const pathParams = mergedConfig.pathParams; const urlReplaced = url.replace(/\\{([^}]+)\\}/g, (_, key) => { const pathParam = pathParams[key]; return pathParam; }); delete mergedConfig.pathParams; + let data = mergedConfig.data; + if (Object.prototype.toString.call(data) === '[object Object]' && typeof FormData !== 'undefined') { + let hasBlobData = false; + const formData = new FormData(); + for (const key in data) { + formData.append(key, data[key]); + if (data[key] instanceof Blob) { + hasBlobData = true; + } + } + data = hasBlobData ? formData : data; + } return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data); } }); diff --git a/packages/wormhole/test/config.spec.ts b/packages/wormhole/test/config.spec.ts index 8596a1e..9f261f3 100644 --- a/packages/wormhole/test/config.spec.ts +++ b/packages/wormhole/test/config.spec.ts @@ -2,29 +2,185 @@ import createConfig from '@/createConfig'; import { readConfig } from '@/readConfig'; import fs from 'node:fs/promises'; import { resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { rimraf } from 'rimraf'; +import type { Config } from '~/index'; +import { initExpect } from './util'; -vi.mock('node:fs'); -vi.mock('node:fs/promises'); -let type = 'typescript'; -vi.mock('@/functions/getAutoTemplateType', () => ({ +initExpect(); + +const requireResult = new Map | null | Error>(); +vi.mock('import-fresh', () => ({ __esModule: true, - default() { - return type; + default(path: string) { + if (!requireResult.get(path)) { + throw new Error(`require ${path} not found`); + } + const result = requireResult.get(path); + if (result instanceof Error) { + throw result; + } + return result; } })); -beforeEach(async () => { - try { - await Promise.all([ - fs.unlink(resolve(process.cwd(), 'alova.config.ts')), - fs.unlink(resolve(process.cwd(), 'alova.config.js')) - ]); - } catch (error) {} + +const importResult = new Map | null | Error>(); +vi.mock('@/utils', async () => { + const utils = await vi.importActual('@/utils'); + return { + ...utils, + loadEsmModule(path: string) { + path = (/^file:\/\//.test(path) ? fileURLToPath(path) : path).replace(/\?.*$/, ''); + if (!importResult.get(path)) { + return Promise.reject(new Error(`import ${path} not found`)); + } + const result = importResult.get(path); + if (result instanceof Error) { + return Promise.reject(result); + } + return Promise.resolve({ + default: result + }); + } + }; +}); +const configMap: Record< + 'ts' | 'module' | 'commonjs', + { file: string; content: string; expectedConfig: Config; transformContent?: string } +> = { + ts: { + file: 'alova.config.ts', + content: `import type { Config } from '@alova/wormhole'; +export default { +generator: [ + { + input: 'http://localhost:3000', + output: 'src/api', + type: 'ts', + version: 3, + handleApi: api =>api + } +] +}`, + expectedConfig: { + generator: [ + { + input: 'http://localhost:3000', + output: 'src/api', + type: 'ts', + version: 3, + handleApi: api => api + } + ] + }, + transformContent: `export default { + generator: [ + { + input: 'http://localhost:3000', + output: 'src/api', + type: 'ts', + version: 3, + handleApi: api => api + } + ] +};` + }, + module: { + file: 'alova.config.js', + content: `export default { +generator: [ + { + input: 'http://localhost:3000', + output: 'src/api', + type: 'module', + version: 3, + handleApi: api => api + } +] +}`, + expectedConfig: { + generator: [ + { + input: 'http://localhost:3000', + output: 'src/api', + type: 'module', + version: 3, + handleApi: api => api + } + ] + } + }, + commonjs: { + file: 'alova.config.js', + content: `module.exports = { +generator: [ + { + input: 'http://localhost:3000', + output: 'src/api', + type: 'commonjs', + version: 3, + handleApi: api => api + } +] +}`, + expectedConfig: { + generator: [ + { + input: 'http://localhost:3000', + output: 'src/api', + type: 'commonjs', + version: 3, + handleApi: api => api + } + ] + } + } +}; +vi.mock('node:fs/promises', async () => { + const fs = await vi.importActual('node:fs/promises'); + function writeFile(filePath: string, content: string, options: any) { + const configItem = Object.values(configMap).find(item => item.content === content) ?? configMap.ts; + const pureFilePath = filePath.replace(/\?.*$/, ''); + const isCjs = pureFilePath.endsWith('.cjs') || (pureFilePath.endsWith('.js') && content.includes('module.exports')); + const isMjs = pureFilePath.endsWith('.mjs') || (pureFilePath.endsWith('.js') && content.includes('export default')); + if (isCjs) { + requireResult.set(filePath, configItem.expectedConfig); + } + if (isMjs) { + importResult.set(filePath, configItem.expectedConfig); + } + return fs.writeFile(filePath, content, options); + } + return { + ...fs, + writeFile, + default: { + ...(fs as any).default, + writeFile + } + }; +}); +afterEach(async () => { + requireResult.clear(); + importResult.clear(); + await Promise.all([ + rimraf(resolve(process.cwd(), 'alova.config.ts')), + rimraf(resolve(process.cwd(), 'alova.config.js')), + rimraf(resolve(process.cwd(), 'node_modules/.alova')) + ]); }); -describe.skip('config', () => { +describe('config', () => { test('should create config file under project root path', async () => { // generate typescript file - type = 'typescript'; + requireResult.set(resolve(process.cwd(), './package.json'), { + devDependencies: { + typescript: '^5.4.5' + }, + dependencies: { + alova: '3.0.5' + } + }); await createConfig(); const tsConfigPath = resolve(process.cwd(), 'alova.config.ts'); const initialTsConfig = await fs.readFile(tsConfigPath, { @@ -33,20 +189,13 @@ describe.skip('config', () => { expect(initialTsConfig).toMatch(`import type { Config } from '@alova/wormhole';`); expect(initialTsConfig).toMatch(`export default {`); expect(initialTsConfig).toMatch(`input: 'http://localhost:3000',`); - - // generate typescript file with alias `ts` - type = 'ts'; - await createConfig(); - const tsConfigPath2 = resolve(process.cwd(), 'alova.config.ts'); - const initialTsConfig2 = await fs.readFile(tsConfigPath2, { - encoding: 'utf-8' - }); - expect(initialTsConfig2).toMatch(`import type { Config } from '@alova/wormhole';`); - expect(initialTsConfig2).toMatch(`export default {`); - expect(initialTsConfig2).toMatch(`input: 'http://localhost:3000',`); - // generate commonjs file - type = 'commonjs'; + requireResult.set(resolve(process.cwd(), './package.json'), { + type: 'commonjs', + dependencies: { + alova: '3.0.5' + } + }); await createConfig(); const initialCjsConfig = await fs.readFile(resolve(process.cwd(), 'alova.config.js'), { encoding: 'utf-8' @@ -55,7 +204,11 @@ describe.skip('config', () => { expect(initialCjsConfig).toMatch(`module.exports = {`); // generate module file - type = 'module'; + requireResult.set(resolve(process.cwd(), './package.json'), { + dependencies: { + alova: '3.0.5' + } + }); await createConfig(); const initialEsmoduleConfig = await fs.readFile(resolve(process.cwd(), 'alova.config.js'), { encoding: 'utf-8' @@ -65,61 +218,25 @@ describe.skip('config', () => { }); test('should create config file under custom path', async () => { - type = 'commonjs'; const customPath = '/mockdir_config'; - await createConfig(customPath); - const configPath = resolve(customPath, 'alova.config.js'); - const initialConfig = await fs.readFile(configPath, { - encoding: 'utf-8' - }); - expect(!!initialConfig).toBeTruthy(); - }); - - const configMap = { - ts: { - file: 'alova.config.ts', - content: `import type { Config } from '@alova/wormhole'; -export default { - generator: [ - { - input: 'http://localhost:3000', - output: 'src/api', - type: 'ts', - version: 'v3', - handleApi: () => 1 - } - ] -}` - }, - module: { - file: 'alova.config.js', - content: `export default { - generator: [ - { - input: 'http://localhost:3000', - output: 'src/api', - type: 'module', - version: 'v3', - handleApi: () => 1 - } - ] -}` - }, - commonjs: { - file: 'alova.config.js', - content: `module.exports = { - generator: [ - { - input: 'http://localhost:3000', - output: 'src/api', + // 设置package.json 文件 + requireResult.set(resolve(customPath, './package.json'), { type: 'commonjs', - version: 'v3', - handleApi: () => 1 - } - ] -}` + dependencies: { + alova: '3.0.5' + } + }); + try { + await createConfig(customPath); + const configPath = resolve(customPath, 'alova.config.js'); + const initialConfig = await fs.readFile(configPath, { + encoding: 'utf-8' + }); + expect(!!initialConfig).toBeTruthy(); + } finally { + await rimraf(resolve(customPath)); // 清除临时目录 } - }; + }); test('should read config file under project root path', async () => { // write mock config file const projectRoot = process.cwd(); @@ -128,52 +245,26 @@ export default { } catch (error) { await fs.mkdir(projectRoot, { recursive: true }); } - await fs.writeFile(resolve(projectRoot, configMap.ts.file), configMap.ts.content, 'utf-8'); - // read ts file + await fs.writeFile(resolve(projectRoot, configMap.ts.file), configMap.ts.content, 'utf-8'); + requireResult.set(projectRoot, null); // require()=> throw error + importResult.set(projectRoot, configMap.ts.expectedConfig); // import()=> return config const tsConfig = await readConfig(); - expect(tsConfig).toStrictEqual({ - generator: [ - { - input: 'http://localhost:3000', - output: 'src/api', - type: 'ts', - version: 'v3', - handleApi: () => 1 - } - ] - }); - await fs.unlink(resolve(projectRoot, configMap.ts.file)); // delete ts file + + expect(tsConfig).toBeDeepEqual(configMap.ts.expectedConfig); // read module config file await fs.writeFile(resolve(projectRoot, configMap.module.file), configMap.module.content, 'utf-8'); + requireResult.set(projectRoot, null); // require()=> throw error + importResult.set(projectRoot, configMap.module.expectedConfig); // import()=> return config const moduleConfig = await readConfig(); - expect(moduleConfig).toStrictEqual({ - generator: [ - { - input: 'http://localhost:3000', - output: 'src/api', - type: 'module', - version: 'v3', - handleApi: () => 1 - } - ] - }); - + expect(moduleConfig).toBeDeepEqual(configMap.module.expectedConfig); // read commonjs config file await fs.writeFile(resolve(projectRoot, configMap.commonjs.file), configMap.commonjs.content, 'utf-8'); + requireResult.set(projectRoot, configMap.commonjs.expectedConfig); // require()=> return config + importResult.set(projectRoot, null); // import()=> throw error const cjsConfig = await readConfig(); - expect(cjsConfig).toStrictEqual({ - generator: [ - { - input: 'http://localhost:3000', - output: 'src/api', - type: 'commonjs', - version: 'v3', - handleApi: () => 1 - } - ] - }); + expect(cjsConfig).toBeDeepEqual(configMap.commonjs.expectedConfig); }); test('should read config file under target path', async () => { @@ -185,17 +276,13 @@ export default { await fs.mkdir(customPath, { recursive: true }); } await fs.writeFile(resolve(customPath, configMap.ts.file), configMap.ts.content, 'utf-8'); - const tsConfig = await readConfig(customPath); - expect(tsConfig).toMatchObject({ - generator: [ - { - input: 'http://localhost:3000', - output: 'src/api', - type: 'ts', - version: 'v3', - handleApi: () => 1 - } - ] - }); + requireResult.set(customPath, null); // require()=> throw error + importResult.set(customPath, configMap.ts.expectedConfig); // import()=> return config + try { + const tsConfig = await readConfig(customPath); + expect(tsConfig).toMatchObject(configMap.ts.expectedConfig); + } finally { + await rimraf(customPath); // 清除临时目录 + } }); }); diff --git a/packages/wormhole/test/util.ts b/packages/wormhole/test/util.ts new file mode 100644 index 0000000..d94057d --- /dev/null +++ b/packages/wormhole/test/util.ts @@ -0,0 +1,26 @@ +import isEqualWith from 'lodash/isEqualWith'; +import { expect } from 'vitest'; +// 自定义比较器函数,忽略函数的比较 +function customizer(objValue: any, othValue: any) { + if (typeof objValue === 'function' && typeof othValue === 'function') { + return objValue.toString() === othValue.toString(); // 比较函数内容 + } +} +export const isEqualObject = (objValue: any, othValue: any) => isEqualWith(objValue, othValue, customizer); +export const initExpect = () => { + expect.extend({ + toBeDeepEqual(received, expected) { + const pass = isEqualObject(received, expected); + if (pass) { + return { + message: () => `expected ${received} not to be deep equal ${expected}`, + pass: true + }; + } + return { + message: () => `expected ${received} to be deep equal ${expected}`, + pass: false + }; + } + }); +}; diff --git a/packages/wormhole/typings/vitest.d.ts b/packages/wormhole/typings/vitest.d.ts new file mode 100644 index 0000000..6aeaa69 --- /dev/null +++ b/packages/wormhole/typings/vitest.d.ts @@ -0,0 +1,10 @@ +import type { Assertion } from 'vitest'; + +interface CustomMatchers extends Assertion { + toBeDeepEqual(expected: R): void; +} + +declare module 'vitest' { + interface Assertion extends CustomMatchers {} + interface AsymmetricMatchersContaining extends CustomMatchers {} +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2248f79..749d64a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -54,6 +54,9 @@ importers: '@types/node-fetch': specifier: ^2.6.11 version: 2.6.11 + '@types/rimraf': + specifier: ^4.0.5 + version: 4.0.5 '@types/serialize-javascript': specifier: ^5.0.4 version: 5.0.4 @@ -105,6 +108,9 @@ importers: prettier-plugin-sort-json: specifier: ^4.0.0 version: 4.0.0(prettier@3.3.2) + rimraf: + specifier: ^6.0.1 + version: 6.0.1 tslib: specifier: ^2.7.0 version: 2.7.0 @@ -1243,46 +1249,55 @@ packages: resolution: {integrity: sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.21.2': resolution: {integrity: sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.21.2': resolution: {integrity: sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.21.2': resolution: {integrity: sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-powerpc64le-gnu@4.21.2': resolution: {integrity: sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-gnu@4.21.2': resolution: {integrity: sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-s390x-gnu@4.21.2': resolution: {integrity: sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.21.2': resolution: {integrity: sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.21.2': resolution: {integrity: sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-win32-arm64-msvc@4.21.2': resolution: {integrity: sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==} @@ -1351,6 +1366,10 @@ packages: '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + '@types/rimraf@4.0.5': + resolution: {integrity: sha512-DTCZoIQotB2SUJnYgrEx43cQIUYOlNZz0AZPbKU4PSLYTUdML5Gox0++z4F9kQocxStrCmRNhi4x5x/UlwtKUA==} + deprecated: This is a stub types definition. rimraf provides its own type definitions, so you do not need this installed. + '@types/serialize-javascript@5.0.4': resolution: {integrity: sha512-Z2R7UKFuNWCP8eoa2o9e5rkD3hmWxx/1L0CYz0k2BZzGh0PhEVMp9kfGiqEml/0IglwNERXZ2hwNzIrSz/KHTA==} @@ -2617,6 +2636,11 @@ packages: engines: {node: '>=16 || 14 >=14.18'} hasBin: true + glob@11.0.0: + resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==} + engines: {node: 20 || >=22} + hasBin: true + glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported @@ -3008,6 +3032,10 @@ packages: resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==} engines: {node: '>=14'} + jackspeak@4.0.1: + resolution: {integrity: sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog==} + engines: {node: 20 || >=22} + jest-diff@26.6.2: resolution: {integrity: sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==} engines: {node: '>= 10.14.2'} @@ -3235,6 +3263,10 @@ packages: resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} engines: {node: 14 || >=16.14} + lru-cache@11.0.1: + resolution: {integrity: sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -3313,6 +3345,10 @@ packages: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} + minimatch@10.0.1: + resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} + engines: {node: 20 || >=22} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -3551,6 +3587,9 @@ packages: resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + package-json-from-dist@1.0.0: + resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + pako@1.0.11: resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} @@ -3619,6 +3658,10 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + path-scurry@2.0.0: + resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} + engines: {node: 20 || >=22} + path-type@3.0.0: resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} engines: {node: '>=4'} @@ -4019,6 +4062,11 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true + rimraf@6.0.1: + resolution: {integrity: sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==} + engines: {node: 20 || >=22} + hasBin: true + rollup-plugin-dts@6.1.1: resolution: {integrity: sha512-aSHRcJ6KG2IHIioYlvAOcEq6U99sVtqDDKVhnwt70rW6tsz3tv5OSjEiWcgzfsHdLyGXZ/3b/7b/+Za3Y6r1XA==} engines: {node: '>=16'} @@ -5637,6 +5685,10 @@ snapshots: '@types/resolve@1.20.2': {} + '@types/rimraf@4.0.5': + dependencies: + rimraf: 6.0.1 + '@types/serialize-javascript@5.0.4': {} '@types/swagger2openapi@7.0.4': @@ -7341,6 +7393,15 @@ snapshots: minipass: 7.1.2 path-scurry: 1.11.1 + glob@11.0.0: + dependencies: + foreground-child: 3.2.0 + jackspeak: 4.0.1 + minimatch: 10.0.1 + minipass: 7.1.2 + package-json-from-dist: 1.0.0 + path-scurry: 2.0.0 + glob@7.2.3: dependencies: fs.realpath: 1.0.0 @@ -7726,6 +7787,12 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 + jackspeak@4.0.1: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + jest-diff@26.6.2: dependencies: chalk: 4.1.2 @@ -7971,6 +8038,8 @@ snapshots: lru-cache@10.2.2: {} + lru-cache@11.0.1: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -8038,6 +8107,10 @@ snapshots: mimic-response@3.1.0: optional: true + minimatch@10.0.1: + dependencies: + brace-expansion: 2.0.1 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -8346,6 +8419,8 @@ snapshots: dependencies: p-limit: 4.0.0 + package-json-from-dist@1.0.0: {} + pako@1.0.11: {} param-case@3.0.4: @@ -8413,6 +8488,11 @@ snapshots: lru-cache: 10.2.2 minipass: 7.1.2 + path-scurry@2.0.0: + dependencies: + lru-cache: 11.0.1 + minipass: 7.1.2 + path-type@3.0.0: dependencies: pify: 3.0.0 @@ -8798,6 +8878,11 @@ snapshots: dependencies: glob: 7.2.3 + rimraf@6.0.1: + dependencies: + glob: 11.0.0 + package-json-from-dist: 1.0.0 + rollup-plugin-dts@6.1.1(rollup@3.29.4)(typescript@5.5.4): dependencies: magic-string: 0.30.10 From ea44acabc9eee300e492e7fbabaab05293aed0b9 Mon Sep 17 00:00:00 2001 From: JOU Amjs Date: Sun, 13 Oct 2024 23:33:28 +0800 Subject: [PATCH 25/47] test: add `generate` unit tests --- packages/wormhole/__mocks__/fs.cjs | 2 - packages/wormhole/bin/index.js | 0 packages/wormhole/package.json | 2 +- packages/wormhole/test/generate.spec.ts | 284 ++++++++++++++++++ .../test/openapis/endless_loop_openapi.yaml | 136 +++++++++ .../test/openapis/file_upload_openapi.yaml | 144 +++++++++ .../test/openapis/multiple_tag_openapi.yaml | 166 ++++++++++ .../non_variable_specification_openapi.yaml | 207 +++++++++++++ .../test/openapis/tag_general_openapi.yaml | 163 ++++++++++ 9 files changed, 1101 insertions(+), 3 deletions(-) mode change 100644 => 100755 packages/wormhole/bin/index.js create mode 100644 packages/wormhole/test/openapis/endless_loop_openapi.yaml create mode 100644 packages/wormhole/test/openapis/file_upload_openapi.yaml create mode 100644 packages/wormhole/test/openapis/multiple_tag_openapi.yaml create mode 100644 packages/wormhole/test/openapis/non_variable_specification_openapi.yaml create mode 100644 packages/wormhole/test/openapis/tag_general_openapi.yaml diff --git a/packages/wormhole/__mocks__/fs.cjs b/packages/wormhole/__mocks__/fs.cjs index 586b9e8..61b7afd 100644 --- a/packages/wormhole/__mocks__/fs.cjs +++ b/packages/wormhole/__mocks__/fs.cjs @@ -7,11 +7,9 @@ const isMatchRealFs = path => realfsPatterns.some(pattern => pattern.test(path)) module.exports = { ...fs, readFile(...args) { - // console.log('readFile', args, isMatchmemFs(args[0])); return isMatchRealFs(args[0]) ? originalFs.readFile(...args) : fs.readFile(...args); }, readFileSync(...args) { - // console.log('readFileSync', args, isMatchmemFs(args[0])); return isMatchRealFs(args[0]) ? originalFs.readFileSync(...args) : fs.readFileSync(...args); } }; diff --git a/packages/wormhole/bin/index.js b/packages/wormhole/bin/index.js old mode 100644 new mode 100755 diff --git a/packages/wormhole/package.json b/packages/wormhole/package.json index 8830280..e77eb3b 100644 --- a/packages/wormhole/package.json +++ b/packages/wormhole/package.json @@ -17,7 +17,7 @@ } }, "scripts": { - "build": "unbuild --minify", + "build": "unbuild", "dev": "pnpm run stub", "stub": "unbuild --stub" }, diff --git a/packages/wormhole/test/generate.spec.ts b/packages/wormhole/test/generate.spec.ts index 374ba8b..a3807c8 100644 --- a/packages/wormhole/test/generate.spec.ts +++ b/packages/wormhole/test/generate.spec.ts @@ -4,6 +4,7 @@ import { resolve } from 'node:path'; vi.mock('node:fs'); vi.mock('node:fs/promises'); +const getSalt = () => `_${Math.random().toString(36).slice(2)}`; describe('generate API', () => { test('should throw error when necessary items are not specified', async () => { await expect(generate({} as any)).rejects.toThrow('No items found in the `config.generator`'); @@ -205,4 +206,287 @@ describe('generate API', () => { expect(await fs.readFile(resolve(outputDir2, 'createApis.ts'), 'utf-8')).toMatchSnapshot(); expect(await fs.readFile(resolve(outputDir2, 'globals.d.ts'), 'utf-8')).toMatchSnapshot(); }); + + test('should auto detect generating module codes if not set `type`', async () => { + // default type: auto + // generate ts modules + const outputDir = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir + } + ] + }); + await expect(fs.readFile(resolve(outputDir, 'createApis.ts'), 'utf-8')).resolves.not.toBeUndefined(); + + // auto: esm + const packageJson = { + name: 'test-pkg', + type: undefined as string | undefined, + version: '1.0.0', + devDependencies: {} + }; + const tempPkgFile = resolve(__dirname, './package.json'); + const { writeFileSync, unlinkSync } = await vi.importActual('node:fs'); + writeFileSync(tempPkgFile, JSON.stringify(packageJson)); + const outputDir2 = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); + await generate( + { + generator: [ + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir2 + } + ] + }, + { + projectPath: __dirname + } + ); + const fileContentEsm = await fs.readFile(resolve(outputDir2, 'createApis.js'), 'utf-8'); + expect(fileContentEsm).toMatch('export const createApis'); + + // auto: cjs + packageJson.type = 'commonjs'; + writeFileSync(tempPkgFile, JSON.stringify(packageJson)); + const outputDir3 = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); + await generate( + { + generator: [ + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir3 + } + ] + }, + { + projectPath: __dirname + } + ); + const fileContentCjs = await fs.readFile(resolve(outputDir3, 'createApis.js'), 'utf-8'); + expect(fileContentCjs).toMatch(`module.exports = { + createApis, + withConfigType +};`); + + unlinkSync(tempPkgFile); + }); + + test('should generate corresponding module codes dependent to `type`', async () => { + // ts + const outputDir = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir, + type: 'typescript' + } + ] + }); + await expect(fs.readFile(resolve(outputDir, 'createApis.ts'), 'utf-8')).resolves.not.toBeUndefined(); + + const outputDirTs = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDirTs, + type: 'ts' + } + ] + }); + await expect(fs.readFile(resolve(outputDirTs, 'createApis.ts'), 'utf-8')).resolves.not.toBeUndefined(); + + // esm + const outputDir2 = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir2, + type: 'module' + } + ] + }); + const fileContentEsm = await fs.readFile(resolve(outputDir2, 'createApis.js'), 'utf-8'); + expect(fileContentEsm).toMatch('export const createApis'); + + // cjs + const outputDir3 = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir3, + type: 'commonjs' + } + ] + }); + const fileContentCjs = await fs.readFile(resolve(outputDir3, 'createApis.js'), 'utf-8'); + expect(fileContentCjs).toMatch(`module.exports = { + createApis, + withConfigType +};`); + }); + + test('should set the right global variable name', async () => { + const outputDir = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir + } + ] + }); + const fileContent = await fs.readFile(resolve(outputDir, 'createApis.ts'), 'utf-8'); + expect(fileContent).toMatch('(globalThis as any).Apis = Apis;'); + + const outputDir2 = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir2, + type: 'module', + global: 'ApisEsm' + } + ] + }); + const fileContentEsm = await fs.readFile(resolve(outputDir2, 'createApis.js'), 'utf-8'); + expect(fileContentEsm).toMatch('globalThis.ApisEsm = Apis;'); + + const outputDir3 = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); + const outputDir4 = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir3, + type: 'commonjs', + global: 'ApisCjs' + }, + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir4, + type: 'module', + global: 'ApisEsm2' + } + ] + }); + const fileContentCjs = await fs.readFile(resolve(outputDir3, 'createApis.js'), 'utf-8'); + expect(fileContentCjs).toMatch('globalThis.ApisCjs = Apis;'); + const fileContentEsm2 = await fs.readFile(resolve(outputDir4, 'createApis.js'), 'utf-8'); + expect(fileContentEsm2).toMatch('globalThis.ApisEsm2 = Apis;'); + }); + + test('should preprocess non-variable-specification characters', async () => { + const outputDir = resolve(__dirname, `./mock_output/non_variable_specification_openapi${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/non_variable_specification_openapi.yaml'), + output: outputDir + } + ] + }); + const indexFile = await fs.readFile(resolve(outputDir, 'index.ts'), 'utf-8'); + expect(indexFile).toMatch("baseURL: ''"); + const apiDefinitionsFile = await fs.readFile(resolve(outputDir, 'apiDefinitions.ts'), 'utf-8'); + expect(apiDefinitionsFile).toMatch("'_24pet.pet24': ['POST', '/pet']"); // non-variable specification tag + expect(apiDefinitionsFile).toMatch("pet.put_pet': ['PUT', '/pet']"); // `operationId` is not defined + }); + + test('should classify the apis that have no tags to `general` tag', async () => { + const outputDir = resolve(__dirname, `./mock_output/tag_general_openapi${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/tag_general_openapi.yaml'), + output: outputDir + } + ] + }); + const apiDefinitionsFile = await fs.readFile(resolve(outputDir, 'apiDefinitions.ts'), 'utf-8'); + expect(apiDefinitionsFile).toMatch("'general.addPet': ['POST', '/pet']"); + expect(apiDefinitionsFile).toMatch("general.updatePet': ['PUT', '/pet']"); + }); + + test('should generate the same api with different tag when has multiple tags', async () => { + const outputDir = resolve(__dirname, `./mock_output/multiple_tag_openapi${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/multiple_tag_openapi.yaml'), + output: outputDir + } + ] + }); + const apiDefinitionsFile = await fs.readFile(resolve(outputDir, 'apiDefinitions.ts'), 'utf-8'); + expect(apiDefinitionsFile).toMatch("'pet.addPet': ['POST', '/pet']"); + expect(apiDefinitionsFile).toMatch("'store.addPet': ['POST', '/pet']"); + const globalsFile = await fs.readFile(resolve(outputDir, 'globals.d.ts'), 'utf-8'); + expect(globalsFile).toMatch("Alova2Method"); + expect(globalsFile).toMatch("Alova2Method"); + }); + + test('should stop endless loop when encounter circular reference in component', async () => { + const outputDir = resolve(__dirname, `./mock_output/endless_loop_openapi${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/endless_loop_openapi.yaml'), + output: outputDir + } + ] + }); + const globalsFile = await fs.readFile(resolve(outputDir, 'globals.d.ts'), 'utf-8'); + expect(globalsFile).toMatch(`type Response = { + * id?: number + * // [title] Pet category + * // A category for a pet + * category?: { + * id?: number + * name?: string + * // [title] Pet Tag + * // A tag for a pet + * tag?: { + * id?: number + * name?: string + * // [title] a Pet + * // A pet for sale in the pet store + * pet?: Pet + * } + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array + * // pet status in the store + * // [deprecated] + * status?: 'available' | 'pending' | 'sold' + * }`); + }); + + test('should automatically convert object that contains `Blob` to `FormData`', async () => { + const outputDir = resolve(__dirname, `./mock_output/file_upload_openapi${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/file_upload_openapi.yaml'), + output: outputDir + } + ] + }); + const globalsFile = await fs.readFile(resolve(outputDir, 'globals.d.ts'), 'utf-8'); + expect(globalsFile).toMatch('file: Blob'); + }); + + test('should `handleApi` handler change all descriptors', async () => {}); + + test('should only effect component type of modified descriptor when this component is refered by multiple descriptor', async () => {}); }); diff --git a/packages/wormhole/test/openapis/endless_loop_openapi.yaml b/packages/wormhole/test/openapis/endless_loop_openapi.yaml new file mode 100644 index 0000000..ef713ed --- /dev/null +++ b/packages/wormhole/test/openapis/endless_loop_openapi.yaml @@ -0,0 +1,136 @@ +openapi: 3.0.0 +info: + description: >- + This is a sample server Petstore server. For this sample, you can use the api key + `special-key` to test the authorization filters. + version: 1.0.0 + title: OpenAPI +tags: + - name: pet + description: Everything about your Pets + - name: store + description: Access to Petstore orders + - name: user + description: Operations about user +paths: + /pet: + post: + summary: Add a new pet to the store 2 + description: '' + operationId: addPet + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '405': + description: Invalid input + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + $ref: '#/components/requestBodies/Pet' +externalDocs: + description: Find out more about Swagger + url: 'http://swagger.io' +components: + requestBodies: + Pet: + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + description: Pet object that needs to be added to the store + required: true + securitySchemes: + petstore_auth: + type: oauth2 + flows: + implicit: + authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog' + scopes: + 'write:pets': modify pets in your account + 'read:pets': read your pets + api_key: + type: apiKey + name: api_key + in: header + schemas: + Tag: + title: Pet Tag + description: A tag for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + pet: + $ref: '#/components/schemas/Pet' + xml: + name: Tag + Category: + title: Pet category + description: A category for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$' + tag: + $ref: '#/components/schemas/Tag' + xml: + name: Category + Pet: + title: a Pet + description: A pet for sale in the pet store + type: object + required: + - name + - photoUrls + properties: + id: + type: integer + format: int64 + category: + $ref: '#/components/schemas/Category' + name: + type: string + example: doggie + photoUrls: + type: array + xml: + name: photoUrl + wrapped: true + items: + type: string + tags: + type: array + xml: + name: tag + wrapped: true + items: + $ref: '#/components/schemas/Tag' + status: + type: string + description: pet status in the store + deprecated: true + enum: + - available + - pending + - sold + xml: + name: Pet diff --git a/packages/wormhole/test/openapis/file_upload_openapi.yaml b/packages/wormhole/test/openapis/file_upload_openapi.yaml new file mode 100644 index 0000000..19fd348 --- /dev/null +++ b/packages/wormhole/test/openapis/file_upload_openapi.yaml @@ -0,0 +1,144 @@ +openapi: 3.0.0 +info: + description: >- + This is a sample server Petstore server. For this sample, you can use the api key + `special-key` to test the authorization filters. + version: 1.0.0 + title: OpenAPI +tags: + - name: pet + description: Everything about your Pets + - name: store + description: Access to Petstore orders + - name: user + description: Operations about user +paths: + /pet: + post: + tags: + - pet + summary: Add a new pet to the store 2 + description: '' + operationId: addPet + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '405': + description: Invalid input + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + $ref: '#/components/requestBodies/Pet' +externalDocs: + description: Find out more about Swagger + url: 'http://swagger.io' +components: + requestBodies: + Pet: + content: + application/json: + schema: + title: Pet Tag + description: A tag for a pet + type: object + required: + - file + properties: + file: + type: string + format: binary + xml: + name: Tag + application/xml: + schema: + $ref: '#/components/schemas/Pet' + description: Pet object that needs to be added to the store + required: true + securitySchemes: + petstore_auth: + type: oauth2 + flows: + implicit: + authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog' + scopes: + 'write:pets': modify pets in your account + 'read:pets': read your pets + api_key: + type: apiKey + name: api_key + in: header + schemas: + Tag: + title: Pet Tag + description: A tag for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + xml: + name: Tag + Category: + title: Pet category + description: A category for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$' + xml: + name: Category + Pet: + title: a Pet + description: A pet for sale in the pet store + type: object + required: + - name + - photoUrls + properties: + id: + type: integer + format: int64 + category: + $ref: '#/components/schemas/Category' + name: + type: string + example: doggie + photoUrls: + type: array + xml: + name: photoUrl + wrapped: true + items: + type: string + tags: + type: array + xml: + name: tag + wrapped: true + items: + $ref: '#/components/schemas/Tag' + status: + type: string + description: pet status in the store + deprecated: true + enum: + - available + - pending + - sold + xml: + name: Pet diff --git a/packages/wormhole/test/openapis/multiple_tag_openapi.yaml b/packages/wormhole/test/openapis/multiple_tag_openapi.yaml new file mode 100644 index 0000000..3474bb0 --- /dev/null +++ b/packages/wormhole/test/openapis/multiple_tag_openapi.yaml @@ -0,0 +1,166 @@ +openapi: 3.0.0 +info: + description: >- + This is a sample server Petstore server. For this sample, you can use the api key + `special-key` to test the authorization filters. + version: 1.0.0 + title: OpenAPI +tags: + - name: pet + description: Everything about your Pets + - name: store + description: Access to Petstore orders + - name: user + description: Operations about user +paths: + /pet: + post: + tags: + - pet + - store + summary: Add a new pet to the store 2 + description: '' + operationId: addPet + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '405': + description: Invalid input + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + $ref: '#/components/requestBodies/Pet' + put: + tags: + - 中文标签ภาษาไทยこんにちは + summary: Update an existing pet 2 + description: '' + operationId: updatePet + externalDocs: + url: 'http://petstore.swagger.io/v2/doc/updatePet' + description: 'API documentation for the updatePet operation' + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + '405': + description: Validation exception + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + $ref: '#/components/requestBodies/Pet' +externalDocs: + description: Find out more about Swagger + url: 'http://swagger.io' +components: + requestBodies: + Pet: + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + description: Pet object that needs to be added to the store + required: true + securitySchemes: + petstore_auth: + type: oauth2 + flows: + implicit: + authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog' + scopes: + 'write:pets': modify pets in your account + 'read:pets': read your pets + api_key: + type: apiKey + name: api_key + in: header + schemas: + Tag: + title: Pet Tag + description: A tag for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + xml: + name: Tag + Category: + title: Pet category + description: A category for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$' + xml: + name: Category + Pet: + title: a Pet + description: A pet for sale in the pet store + type: object + required: + - name + - photoUrls + properties: + id: + type: integer + format: int64 + category: + $ref: '#/components/schemas/Category' + name: + type: string + example: doggie + photoUrls: + type: array + xml: + name: photoUrl + wrapped: true + items: + type: string + tags: + type: array + xml: + name: tag + wrapped: true + items: + $ref: '#/components/schemas/Tag' + status: + type: string + description: pet status in the store + deprecated: true + enum: + - available + - pending + - sold + xml: + name: Pet diff --git a/packages/wormhole/test/openapis/non_variable_specification_openapi.yaml b/packages/wormhole/test/openapis/non_variable_specification_openapi.yaml new file mode 100644 index 0000000..ce287f3 --- /dev/null +++ b/packages/wormhole/test/openapis/non_variable_specification_openapi.yaml @@ -0,0 +1,207 @@ +openapi: 3.0.0 +info: + description: >- + This is a sample server Petstore server. For this sample, you can use the api key + `special-key` to test the authorization filters. + version: 1.0.0 + title: OpenAPI你好 +tags: + - name: pet + description: Everything about your Pets + - name: store + description: Access to Petstore orders + - name: user + description: Operations about user +paths: + /pet: + post: + tags: + - 你好24pet + summary: Add a new pet to the store 2 + description: '' + operationId: 增加pet24 + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '405': + description: Invalid input + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + $ref: '#/components/requestBodies/Pet' + put: + tags: + - 中文标签ภาษาไทย24petこんにちは + summary: Update an existing pet 2 + description: '' + externalDocs: + url: 'http://petstore.swagger.io/v2/doc/updatePet' + description: 'API documentation for the updatePet operation' + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + '405': + description: Validation exception + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + $ref: '#/components/requestBodies/Pet' + /user: + post: + summary: Create user + description: This can only be done by the logged in user. + operationId: createUser + responses: + default: + description: successful operation + security: + - api_key: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/User' + description: Created user object + required: true +externalDocs: + description: Find out more about Swagger + url: 'http://swagger.io' +components: + requestBodies: + Pet: + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + description: Pet object that needs to be added to the store + required: true + securitySchemes: + petstore_auth: + type: oauth2 + flows: + implicit: + authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog' + scopes: + 'write:pets': modify pets in your account + 'read:pets': read your pets + api_key: + type: apiKey + name: api_key + in: header + schemas: + Tag: + title: Pet Tag + description: A tag for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + xml: + name: Tag + Category: + title: Pet category + description: A category for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$' + xml: + name: Category + Pet: + title: a Pet + description: A pet for sale in the pet store + type: object + required: + - name + - photoUrls + properties: + id: + type: integer + format: int64 + category: + $ref: '#/components/schemas/Category' + name: + type: string + example: doggie + photoUrls: + type: array + xml: + name: photoUrl + wrapped: true + items: + type: string + tags: + type: array + xml: + name: tag + wrapped: true + items: + $ref: '#/components/schemas/Tag' + status: + type: string + description: pet status in the store + deprecated: true + enum: + - available + - pending + - sold + xml: + name: Pet + User: + title: a User + description: A User who is purchasing from the pet store + type: object + properties: + id: + type: integer + format: int64 + username: + type: string + firstName: + type: string + lastName: + type: string + email: + type: string + password: + type: string + phone: + type: string + userStatus: + type: integer + format: int32 + description: User Status + xml: + name: User diff --git a/packages/wormhole/test/openapis/tag_general_openapi.yaml b/packages/wormhole/test/openapis/tag_general_openapi.yaml new file mode 100644 index 0000000..e667bed --- /dev/null +++ b/packages/wormhole/test/openapis/tag_general_openapi.yaml @@ -0,0 +1,163 @@ +openapi: 3.0.0 +info: + description: >- + This is a sample server Petstore server. For this sample, you can use the api key + `special-key` to test the authorization filters. + version: 1.0.0 + title: OpenAPI你好 +tags: + - name: pet + description: Everything about your Pets + - name: store + description: Access to Petstore orders + - name: user + description: Operations about user +paths: + /pet: + post: + summary: Add a new pet to the store 2 + description: '' + operationId: addPet + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '405': + description: Invalid input + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + $ref: '#/components/requestBodies/Pet' + put: + tags: + - 中文标签ภาษาไทยこんにちは + summary: Update an existing pet 2 + description: '' + operationId: updatePet + externalDocs: + url: 'http://petstore.swagger.io/v2/doc/updatePet' + description: 'API documentation for the updatePet operation' + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + '405': + description: Validation exception + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + $ref: '#/components/requestBodies/Pet' +externalDocs: + description: Find out more about Swagger + url: 'http://swagger.io' +components: + requestBodies: + Pet: + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + description: Pet object that needs to be added to the store + required: true + securitySchemes: + petstore_auth: + type: oauth2 + flows: + implicit: + authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog' + scopes: + 'write:pets': modify pets in your account + 'read:pets': read your pets + api_key: + type: apiKey + name: api_key + in: header + schemas: + Tag: + title: Pet Tag + description: A tag for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + xml: + name: Tag + Category: + title: Pet category + description: A category for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$' + xml: + name: Category + Pet: + title: a Pet + description: A pet for sale in the pet store + type: object + required: + - name + - photoUrls + properties: + id: + type: integer + format: int64 + category: + $ref: '#/components/schemas/Category' + name: + type: string + example: doggie + photoUrls: + type: array + xml: + name: photoUrl + wrapped: true + items: + type: string + tags: + type: array + xml: + name: tag + wrapped: true + items: + $ref: '#/components/schemas/Tag' + status: + type: string + description: pet status in the store + deprecated: true + enum: + - available + - pending + - sold + xml: + name: Pet From 6ec8235ec534c8a6d694fcce6d026ec8426b1dad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E9=95=87?= Date: Mon, 14 Oct 2024 11:31:56 +0800 Subject: [PATCH 26/47] test: add all `generate` tests --- .../wormhole/src/functions/getAlovaVersion.ts | 4 +- .../wormhole/src/functions/getOpenApiData.ts | 1 - .../test/__snapshots__/generate.spec.ts.snap | 3901 ++++++++++++++++- packages/wormhole/test/config.spec.ts | 9 +- packages/wormhole/test/generate.spec.ts | 305 +- packages/wormhole/typings/index.d.ts | 4 +- 6 files changed, 4108 insertions(+), 116 deletions(-) diff --git a/packages/wormhole/src/functions/getAlovaVersion.ts b/packages/wormhole/src/functions/getAlovaVersion.ts index e6e48de..e01ad12 100644 --- a/packages/wormhole/src/functions/getAlovaVersion.ts +++ b/packages/wormhole/src/functions/getAlovaVersion.ts @@ -6,7 +6,7 @@ export type AlovaVersion = `v${number}`; export default function (workspaceRootDir: string) { const packageJson: PackageJson = importFresh(path.resolve(workspaceRootDir, './package.json')); if (!packageJson) { - return 'v2'; + return 'v3'; } // 依赖中找 const alovaVersion = packageJson.dependencies?.alova; @@ -19,5 +19,5 @@ export default function (workspaceRootDir: string) { export const getVersion = (version?: string): AlovaVersion => { const execArr = /(\d+)\./.exec(version ?? '') ?? []; - return `v${Number(execArr[1]) || 2}`; + return `v${Number(execArr[1]) || 3}`; }; diff --git a/packages/wormhole/src/functions/getOpenApiData.ts b/packages/wormhole/src/functions/getOpenApiData.ts index a37f5e6..f1b9b1a 100644 --- a/packages/wormhole/src/functions/getOpenApiData.ts +++ b/packages/wormhole/src/functions/getOpenApiData.ts @@ -86,7 +86,6 @@ export default async function ( data = (await swagger2openapi.convertObj(data, { warnOnly: true })).openapi as OpenAPIV3_1.Document; } } catch (error) { - console.log(error, '222'); throw new DEFAULT_CONFIG.Error(`Cannot read file from ${url}`); } if (!data) { diff --git a/packages/wormhole/test/__snapshots__/generate.spec.ts.snap b/packages/wormhole/test/__snapshots__/generate.spec.ts.snap index 8281268..e870b92 100644 --- a/packages/wormhole/test/__snapshots__/generate.spec.ts.snap +++ b/packages/wormhole/test/__snapshots__/generate.spec.ts.snap @@ -1,5 +1,3613 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`generate API > should generate code from an url 1`] = ` +"/// +/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Petstore - version 1.0.7 + * + * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI version: 3.0.0 + * + * Contact: + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +export default { + 'pet.uploadFile': ['POST', '/pet/{petId}/uploadImage'], + 'pet.addPet': ['POST', '/pet'], + 'pet.updatePet': ['PUT', '/pet'], + 'pet.findPetsByStatus': ['GET', '/pet/findByStatus'], + 'pet.findPetsByTags': ['GET', '/pet/findByTags'], + 'pet.getPetById': ['GET', '/pet/{petId}'], + 'pet.updatePetWithForm': ['POST', '/pet/{petId}'], + 'pet.deletePet': ['DELETE', '/pet/{petId}'], + 'store.getInventory': ['GET', '/store/inventory'], + 'store.placeOrder': ['POST', '/store/order'], + 'store.getOrderById': ['GET', '/store/order/{orderId}'], + 'store.deleteOrder': ['DELETE', '/store/order/{orderId}'], + 'user.createUsersWithListInput': ['POST', '/user/createWithList'], + 'user.getUserByName': ['GET', '/user/{username}'], + 'user.updateUser': ['PUT', '/user/{username}'], + 'user.deleteUser': ['DELETE', '/user/{username}'], + 'user.loginUser': ['GET', '/user/login'], + 'user.logoutUser': ['GET', '/user/logout'], + 'user.createUsersWithArrayInput': ['POST', '/user/createWithArray'], + 'user.createUser': ['POST', '/user'] +}; +" +`; + +exports[`generate API > should generate code from an url 2`] = ` +"import { createAlova } from 'alova'; +import fetchAdapter from 'alova/fetch'; +import { createApis, withConfigType } from './createApis'; + +export const alovaInstance = createAlova({ + baseURL: 'https://petstore.swagger.io/v2', + requestAdapter: fetchAdapter(), + beforeRequest: method => {}, + responded: res => { + return res.json(); + } +}); + +export const $$userConfigMap = withConfigType({}); + +const Apis = createApis(alovaInstance, $$userConfigMap); + +export default Apis; +" +`; + +exports[`generate API > should generate code from an url 3`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Petstore - version 1.0.7 + * + * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI version: 3.0.0 + * + * Contact: + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, MethodType, AlovaGenerics, AlovaMethodCreateConfig } from 'alova'; +import { Method } from 'alova'; +import apiDefinitions from './apiDefinitions'; + +const createFunctionalProxy = (array: (string | symbol)[], alovaInstance: Alova, configMap: any) => { + // create a new proxy instance + return new Proxy(function () {}, { + get(_, property) { + // record the target property, so that it can get the completed accessing paths + array.push(property); + // always return a new proxy to continue recording accessing paths. + return createFunctionalProxy(array, alovaInstance, configMap); + }, + apply(_, __, [config]) { + const apiPathKey = array.join('.') as keyof typeof apiDefinitions; + const apiItem = apiDefinitions[apiPathKey]; + if (!apiItem) { + throw new Error(\`the api path of \\\`\${apiPathKey}\\\` is not found\`); + } + const mergedConfig = { + ...configMap[apiPathKey], + ...config + }; + const [method, url] = apiItem; + const pathParams = mergedConfig.pathParams; + const urlReplaced = url.replace(/\\{([^}]+)\\}/g, (_, key) => { + const pathParam = pathParams[key]; + return pathParam; + }); + delete mergedConfig.pathParams; + let data = mergedConfig.data; + if (Object.prototype.toString.call(data) === '[object Object]' && typeof FormData !== 'undefined') { + let hasBlobData = false; + const formData = new FormData(); + for (const key in data) { + formData.append(key, data[key]); + if (data[key] instanceof Blob) { + hasBlobData = true; + } + } + data = hasBlobData ? formData : data; + } + return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data); + } + }); +}; + +export const createApis = (alovaInstance: Alova, configMap: any) => { + const Apis = new Proxy({} as Apis, { + get(_, property) { + return createFunctionalProxy([property], alovaInstance, configMap); + } + }); + // define global variable \`Apis\` + (globalThis as any).Apis = Apis; + return Apis; +}; +type MethodConfig = AlovaMethodCreateConfig< + (typeof import('./index'))['alovaInstance'] extends Alova ? AG : any, + any, + T +>; +type APISofParameters = Tag extends keyof Apis + ? Url extends keyof Apis[Tag] + ? Apis[Tag][Url] extends (...args: any) => any + ? Parameters + : any + : any + : any; +type MethodsConfigMap = { + [P in keyof typeof import('./apiDefinitions').default]?: MethodConfig< + P extends \`\${infer Tag}.\${infer Url}\` ? Parameters[0]['transform']>[0] : any + >; +}; +export const withConfigType = (config: Config) => config; +" +`; + +exports[`generate API > should generate code from an url 4`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Petstore - version 1.0.7 + * + * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI version: 3.0.0 + * + * Contact: + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, AlovaMethodCreateConfig, AlovaGenerics, Method } from 'alova'; +import type { $$userConfigMap, alovaInstance } from '.'; +import type apiDefinitions from './apiDefinitions'; + +type CollapsedAlova = typeof alovaInstance; +type UserMethodConfigMap = typeof $$userConfigMap; + +type Alova2MethodConfig = + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Omit< + AlovaMethodCreateConfig< + AlovaGenerics, + any, + Responded + >, + 'params' + > + : never; + +// Extract the return type of transform function that define in $$userConfigMap, if it not exists, use the default type. +type ExtractUserDefinedTransformed< + DefinitionKey extends keyof typeof apiDefinitions, + Default +> = DefinitionKey extends keyof UserMethodConfigMap + ? UserMethodConfigMap[DefinitionKey]['transform'] extends (...args: any[]) => any + ? Awaited> + : Default + : Default; +type Alova2Method< + Responded, + DefinitionKey extends keyof typeof apiDefinitions, + CurrentConfig extends Alova2MethodConfig +> = + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Method< + AlovaGenerics< + CurrentConfig extends undefined + ? ExtractUserDefinedTransformed + : CurrentConfig['transform'] extends (...args: any[]) => any + ? Awaited> + : ExtractUserDefinedTransformed, + any, + RequestConfig, + Response, + ResponseHeader, + L1Cache, + L2Cache, + SE + > + > + : never; + +export type ApiResponse = { + code?: number; + type?: string; + message?: string; +}; +export type Category = { + id?: number; + name?: string; +}; +export type Tag = { + id?: number; + name?: string; +}; +export type Pet = { + id?: number; + category?: Category; + /** + * [required] + */ + name: string; + /** + * [required] + */ + photoUrls: string[]; + tags?: Tag[]; + /** + * pet status in the store + */ + status?: 'available' | 'pending' | 'sold'; +}; +export type Order = { + id?: number; + petId?: number; + quantity?: number; + shipDate?: string; + /** + * Order Status + */ + status?: 'placed' | 'approved' | 'delivered'; + complete?: boolean; +}; +export type User = { + id?: number; + username?: string; + firstName?: string; + lastName?: string; + email?: string; + password?: string; + phone?: string; + /** + * User Status + */ + userStatus?: number; +}; +declare global { + interface Apis { + pet: { + /** + * --- + * + * [POST] uploads an image + * + * **path:** /pet/{petId}/uploadImage + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // ID of pet to update + * // [required] + * petId: number + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // Additional data to pass to server + * additionalMetadata?: string + * // file to upload + * file?: Blob + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * code?: number + * type?: string + * message?: string + * } + * \`\`\` + */ + uploadFile< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of pet to update + * [required] + */ + petId: number; + }; + data: { + /** + * Additional data to pass to server + */ + additionalMetadata?: string; + /** + * file to upload + */ + file?: Blob; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Add a new pet to the store + * + * **path:** /pet + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * id?: number + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * status?: 'available' | 'pending' | 'sold' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + addPet< + Config extends Alova2MethodConfig & { + data: Pet; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [PUT] Update an existing pet + * + * **path:** /pet + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * id?: number + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * status?: 'available' | 'pending' | 'sold' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + updatePet< + Config extends Alova2MethodConfig & { + data: Pet; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Finds Pets by status + * + * **path:** /pet/findByStatus + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // Status values that need to be considered for filter + * // [required] + * status: ('available' | 'pending' | 'sold')[] + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Array<{ + * id?: number + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * status?: 'available' | 'pending' | 'sold' + * }> + * \`\`\` + */ + findPetsByStatus< + Config extends Alova2MethodConfig & { + params: { + /** + * Status values that need to be considered for filter + * [required] + */ + status: ('available' | 'pending' | 'sold')[]; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Finds Pets by tags + * + * **path:** /pet/findByTags + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // Tags to filter by + * // [required] + * tags: string[] + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Array<{ + * id?: number + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * status?: 'available' | 'pending' | 'sold' + * }> + * \`\`\` + */ + findPetsByTags< + Config extends Alova2MethodConfig & { + params: { + /** + * Tags to filter by + * [required] + */ + tags: string[]; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Find pet by ID + * + * **path:** /pet/{petId} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // ID of pet to return + * // [required] + * petId: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * id?: number + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * status?: 'available' | 'pending' | 'sold' + * } + * \`\`\` + */ + getPetById< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of pet to return + * [required] + */ + petId: number; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Updates a pet in the store with form data + * + * **path:** /pet/{petId} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // ID of pet that needs to be updated + * // [required] + * petId: number + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // Updated name of the pet + * name?: string + * // Updated status of the pet + * status?: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + updatePetWithForm< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of pet that needs to be updated + * [required] + */ + petId: number; + }; + data: { + /** + * Updated name of the pet + */ + name?: string; + /** + * Updated status of the pet + */ + status?: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [DELETE] Deletes a pet + * + * **path:** /pet/{petId} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // Pet id to delete + * // [required] + * petId: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + deletePet< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * Pet id to delete + * [required] + */ + petId: number; + }; + } + >( + config: Config + ): Alova2Method; + }; + store: { + /** + * --- + * + * [GET] Returns pet inventories by status + * + * **path:** /store/inventory + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record + * \`\`\` + */ + getInventory>>( + config?: Config + ): Alova2Method, 'store.getInventory', Config>; + /** + * --- + * + * [POST] Place an order for a pet + * + * **path:** /store/order + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * id?: number + * petId?: number + * quantity?: number + * shipDate?: string + * // Order Status + * status?: 'placed' | 'approved' | 'delivered' + * complete?: boolean + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * id?: number + * petId?: number + * quantity?: number + * shipDate?: string + * // Order Status + * status?: 'placed' | 'approved' | 'delivered' + * complete?: boolean + * } + * \`\`\` + */ + placeOrder< + Config extends Alova2MethodConfig & { + data: Order; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Find purchase order by ID + * + * **path:** /store/order/{orderId} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // ID of pet that needs to be fetched + * // [required] + * orderId: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * id?: number + * petId?: number + * quantity?: number + * shipDate?: string + * // Order Status + * status?: 'placed' | 'approved' | 'delivered' + * complete?: boolean + * } + * \`\`\` + */ + getOrderById< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of pet that needs to be fetched + * [required] + */ + orderId: number; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [DELETE] Delete purchase order by ID + * + * **path:** /store/order/{orderId} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // ID of the order that needs to be deleted + * // [required] + * orderId: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + deleteOrder< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of the order that needs to be deleted + * [required] + */ + orderId: number; + }; + } + >( + config: Config + ): Alova2Method; + }; + user: { + /** + * --- + * + * [POST] Creates list of users with given input array + * + * **path:** /user/createWithList + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = Array<{ + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * }> + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + createUsersWithListInput< + Config extends Alova2MethodConfig & { + data: User[]; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Get user by user name + * + * **path:** /user/{username} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // The name that needs to be fetched. Use user1 for testing. + * // [required] + * username: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * } + * \`\`\` + */ + getUserByName< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * The name that needs to be fetched. Use user1 for testing. + * [required] + */ + username: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [PUT] Updated user + * + * **path:** /user/{username} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // name that need to be updated + * // [required] + * username: string + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + updateUser< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * name that need to be updated + * [required] + */ + username: string; + }; + data: User; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [DELETE] Delete user + * + * **path:** /user/{username} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // The name that needs to be deleted + * // [required] + * username: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + deleteUser< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * The name that needs to be deleted + * [required] + */ + username: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Logs user into the system + * + * **path:** /user/login + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // The user name for login + * // [required] + * username: string + * // The password for login in clear text + * // [required] + * password: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string + * \`\`\` + */ + loginUser< + Config extends Alova2MethodConfig & { + params: { + /** + * The user name for login + * [required] + */ + username: string; + /** + * The password for login in clear text + * [required] + */ + password: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Logs out current logged in user session + * + * **path:** /user/logout + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + logoutUser>( + config?: Config + ): Alova2Method; + /** + * --- + * + * [POST] Creates list of users with given input array + * + * **path:** /user/createWithArray + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = Array<{ + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * }> + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + createUsersWithArrayInput< + Config extends Alova2MethodConfig & { + data: User[]; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Create user + * + * **path:** /user + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + createUser< + Config extends Alova2MethodConfig & { + data: User; + } + >( + config: Config + ): Alova2Method; + }; + } + + var Apis: Apis; +} +" +`; + +exports[`generate API > should generate code from an url 5`] = ` +"/// +/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.62 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +export default { + 'clients.generateFromURL': ['GET', '/generate'], + 'servers.generateFromURL': ['GET', '/generate'], + 'documentation.generateFromURL': ['GET', '/generate'], + 'config.generateFromURL': ['GET', '/generate'], + 'clients.generate': ['POST', '/generate'], + 'servers.generate': ['POST', '/generate'], + 'documentation.generate': ['POST', '/generate'], + 'config.generate': ['POST', '/generate'], + 'clients.clientLanguages': ['GET', '/clients'], + 'documentation.clientLanguages': ['GET', '/clients'], + 'servers.serverLanguages': ['GET', '/servers'], + 'documentation.documentationLanguages': ['GET', '/documentation'], + 'clients.languages': ['GET', '/{type}/{version}'], + 'servers.languages': ['GET', '/{type}/{version}'], + 'documentation.languages': ['GET', '/{type}/{version}'], + 'config.languages': ['GET', '/{type}/{version}'], + 'clients.languagesMulti': ['GET', '/types'], + 'servers.languagesMulti': ['GET', '/types'], + 'documentation.languagesMulti': ['GET', '/types'], + 'config.languagesMulti': ['GET', '/types'], + 'clients.listOptions': ['GET', '/options'], + 'servers.listOptions': ['GET', '/options'], + 'documentation.listOptions': ['GET', '/options'], + 'config.listOptions': ['GET', '/options'], + 'clients.generateBundle': ['POST', '/model'], + 'servers.generateBundle': ['POST', '/model'], + 'documentation.generateBundle': ['POST', '/model'], + 'config.generateBundle': ['POST', '/model'], + 'documentation.renderTemplate': ['POST', '/render'] +}; +" +`; + +exports[`generate API > should generate code from an url 6`] = ` +"import { createAlova } from 'alova'; +import fetchAdapter from 'alova/fetch'; +import { createApis, withConfigType } from './createApis'; + +export const alovaInstance = createAlova({ + baseURL: '/api', + requestAdapter: fetchAdapter(), + beforeRequest: method => {}, + responded: res => { + return res.json(); + } +}); + +export const $$userConfigMap = withConfigType({}); + +const Apis = createApis(alovaInstance, $$userConfigMap); + +export default Apis; +" +`; + +exports[`generate API > should generate code from an url 7`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.62 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, MethodType, AlovaGenerics, AlovaMethodCreateConfig } from 'alova'; +import { Method } from 'alova'; +import apiDefinitions from './apiDefinitions'; + +const createFunctionalProxy = (array: (string | symbol)[], alovaInstance: Alova, configMap: any) => { + // create a new proxy instance + return new Proxy(function () {}, { + get(_, property) { + // record the target property, so that it can get the completed accessing paths + array.push(property); + // always return a new proxy to continue recording accessing paths. + return createFunctionalProxy(array, alovaInstance, configMap); + }, + apply(_, __, [config]) { + const apiPathKey = array.join('.') as keyof typeof apiDefinitions; + const apiItem = apiDefinitions[apiPathKey]; + if (!apiItem) { + throw new Error(\`the api path of \\\`\${apiPathKey}\\\` is not found\`); + } + const mergedConfig = { + ...configMap[apiPathKey], + ...config + }; + const [method, url] = apiItem; + const pathParams = mergedConfig.pathParams; + const urlReplaced = url.replace(/\\{([^}]+)\\}/g, (_, key) => { + const pathParam = pathParams[key]; + return pathParam; + }); + delete mergedConfig.pathParams; + let data = mergedConfig.data; + if (Object.prototype.toString.call(data) === '[object Object]' && typeof FormData !== 'undefined') { + let hasBlobData = false; + const formData = new FormData(); + for (const key in data) { + formData.append(key, data[key]); + if (data[key] instanceof Blob) { + hasBlobData = true; + } + } + data = hasBlobData ? formData : data; + } + return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data); + } + }); +}; + +export const createApis = (alovaInstance: Alova, configMap: any) => { + const Apis = new Proxy({} as Apis, { + get(_, property) { + return createFunctionalProxy([property], alovaInstance, configMap); + } + }); + // define global variable \`Apis\` + (globalThis as any).Apis = Apis; + return Apis; +}; +type MethodConfig = AlovaMethodCreateConfig< + (typeof import('./index'))['alovaInstance'] extends Alova ? AG : any, + any, + T +>; +type APISofParameters = Tag extends keyof Apis + ? Url extends keyof Apis[Tag] + ? Apis[Tag][Url] extends (...args: any) => any + ? Parameters + : any + : any + : any; +type MethodsConfigMap = { + [P in keyof typeof import('./apiDefinitions').default]?: MethodConfig< + P extends \`\${infer Tag}.\${infer Url}\` ? Parameters[0]['transform']>[0] : any + >; +}; +export const withConfigType = (config: Config) => config; +" +`; + +exports[`generate API > should generate code from an url 8`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.62 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, AlovaMethodCreateConfig, AlovaGenerics, Method } from 'alova'; +import type { $$userConfigMap, alovaInstance } from '.'; +import type apiDefinitions from './apiDefinitions'; + +type CollapsedAlova = typeof alovaInstance; +type UserMethodConfigMap = typeof $$userConfigMap; + +type Alova2MethodConfig = + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Omit< + AlovaMethodCreateConfig< + AlovaGenerics, + any, + Responded + >, + 'params' + > + : never; + +// Extract the return type of transform function that define in $$userConfigMap, if it not exists, use the default type. +type ExtractUserDefinedTransformed< + DefinitionKey extends keyof typeof apiDefinitions, + Default +> = DefinitionKey extends keyof UserMethodConfigMap + ? UserMethodConfigMap[DefinitionKey]['transform'] extends (...args: any[]) => any + ? Awaited> + : Default + : Default; +type Alova2Method< + Responded, + DefinitionKey extends keyof typeof apiDefinitions, + CurrentConfig extends Alova2MethodConfig +> = + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Method< + AlovaGenerics< + CurrentConfig extends undefined + ? ExtractUserDefinedTransformed + : CurrentConfig['transform'] extends (...args: any[]) => any + ? Awaited> + : ExtractUserDefinedTransformed, + any, + RequestConfig, + Response, + ResponseHeader, + L1Cache, + L2Cache, + SE + > + > + : never; + +export type AuthorizationValue = { + /** + * Authorization value + */ + value?: string; + /** + * Authorization key + */ + keyName?: string; + /** + * Authorization type + */ + type?: 'query' | 'header'; +}; +export type Options = { + /** + * authorization + * --- + * adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + */ + auth?: string; + /** + * authorization + * --- + * adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + */ + authorizationValue?: AuthorizationValue; + /** + * api package + * --- + * package for generated api classes + */ + apiPackage?: string; + /** + * Template Version + * --- + * template version for generation + */ + templateVersion?: string; + /** + * model package + * --- + * package for generated models + */ + modelPackage?: string; + /** + * model name prefix + * --- + * Prefix that will be prepended to all model names. Default is the empty string. + */ + modelNamePrefix?: string; + /** + * model name suffix + * --- + * PrefixSuffix that will be appended to all model names. Default is the empty string. + */ + modelNameSuffix?: string; + /** + * System Properties + * --- + * sets specified system properties in key/value format + */ + systemProperties?: Record; + /** + * instantiation types + * --- + * sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + */ + instantiationTypes?: Record; + /** + * type mappings + * --- + * sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + */ + typeMappings?: Record; + /** + * additional properties + * --- + * sets additional properties that can be referenced by the mustache templates in key/value format. + */ + additionalProperties?: Record; + /** + * language specific primitives + * --- + * specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + */ + languageSpecificPrimitives?: string[]; + /** + * import mappings + * --- + * specifies mappings between a given class and the import that should be used for that class in key/value format. + */ + importMappings?: Record; + /** + * invoker package + * --- + * root package for generated code + */ + invokerPackage?: string; + /** + * group id + * --- + * groupId in generated pom.xml + */ + groupId?: string; + /** + * artifact id + * --- + * artifactId in generated pom.xml + */ + artifactId?: string; + /** + * artifact version + * --- + * artifact version generated in pom.xml + */ + artifactVersion?: string; + /** + * library + * --- + * library template (sub-template) + */ + library?: string; + /** + * git user id + * --- + * Git user ID, e.g. swagger-api. + */ + gitUserId?: string; + /** + * git repo id + * --- + * Git repo ID, e.g. swagger-codegen. + */ + gitRepoId?: string; + /** + * release note + * --- + * Release note, default to 'Minor update'. + */ + releaseNote?: string; + /** + * http user agent + * --- + * HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + */ + httpUserAgent?: string; + /** + * reserved words mappings + * --- + * pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + */ + reservedWordsMappings?: Record; + /** + * ignore file override location + * --- + * Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + */ + ignoreFileOverride?: string; + /** + * remove prefix of the operationId + * --- + * Remove prefix of operationId, e.g. config_getId => getId + */ + removeOperationIdPrefix?: boolean; + skipOverride?: boolean; +}; +export type GenerationRequest = { + /** + * language + * --- + * language to generate (required) + * [required] + */ + lang: string; + /** + * spec in json format. . Alternative to \`specURL\` + */ + spec?: object; + /** + * URL of the spec in json format. Alternative to \`spec\` + */ + specURL?: string; + /** + * type of the spec + */ + type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG'; + /** + * codegen version to use + */ + codegenVersion?: 'V2' | 'V3'; + options?: Options; +}; +export type CliOption = { + optionName?: string; + description?: string; + /** + * Data type is based on the types supported by the JSON-Schema + */ + type?: string; + enum?: Record; + default?: string; +}; +export type RenderRequest = { + /** + * template + * --- + * template as string + * [required] + */ + template: string; + /** + * context + * --- + * context as string + * [required] + */ + context: string; +}; +declare global { + interface Apis { + clients: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'client' or 'documentation' for given codegen version (defaults to V3) + * + * **path:** /clients + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * // flag to only return languages of type \`client\` + * clientOnly?: boolean + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + clientLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + /** + * flag to only return languages of type \`client\` + */ + clientOnly?: boolean; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'clients.listOptions', Config>; + /** + * --- + * + * [POST] Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = object + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + servers: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'server' for given codegen version (defaults to V3) + * + * **path:** /servers + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + serverLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'servers.listOptions', Config>; + /** + * --- + * + * [POST] Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = object + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + documentation: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'client' or 'documentation' for given codegen version (defaults to V3) + * + * **path:** /clients + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * // flag to only return languages of type \`client\` + * clientOnly?: boolean + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + clientLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + /** + * flag to only return languages of type \`client\` + */ + clientOnly?: boolean; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'documentation' for given codegen version (defaults to V3) + * + * **path:** /documentation + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + documentationLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'documentation.listOptions', Config>; + /** + * --- + * + * [POST] Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = object + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] render a template using the provided data + * + * **path:** /render + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] template + * // template as string + * // [required] + * template: string + * // [title] context + * // context as string + * // [required] + * context: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + renderTemplate< + Config extends Alova2MethodConfig & { + data: RenderRequest; + } + >( + config: Config + ): Alova2Method; + }; + config: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'config.listOptions', Config>; + /** + * --- + * + * [POST] Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = object + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + } + + var Apis: Apis; +} +" +`; + exports[`generate API > should generate code with a variant of openapi file formats 1`] = ` "/// /* tslint:disable */ @@ -54,12 +3662,12 @@ export default { exports[`generate API > should generate code with a variant of openapi file formats 2`] = ` "import { createAlova } from 'alova'; -import GlobalFetch from 'alova/GlobalFetch'; +import fetchAdapter from 'alova/fetch'; import { createApis, withConfigType } from './createApis'; export const alovaInstance = createAlova({ baseURL: '/api1', - requestAdapter: GlobalFetch(), + requestAdapter: fetchAdapter(), beforeRequest: method => {}, responded: res => { return res.json(); @@ -91,15 +3699,11 @@ exports[`generate API > should generate code with a variant of openapi file form * * **Do not edit the file manually.** */ -import type { Alova, MethodType, AlovaMethodCreateConfig } from 'alova'; +import type { Alova, MethodType, AlovaGenerics, AlovaMethodCreateConfig } from 'alova'; import { Method } from 'alova'; import apiDefinitions from './apiDefinitions'; -const createFunctionalProxy = ( - array: (string | symbol)[], - alovaInstance: Alova, - configMap: any -) => { +const createFunctionalProxy = (array: (string | symbol)[], alovaInstance: Alova, configMap: any) => { // create a new proxy instance return new Proxy(function () {}, { get(_, property) { @@ -142,20 +3746,21 @@ const createFunctionalProxy = ( }); }; -export const createApis = (alovaInstance: Alova, configMap: any) => { +export const createApis = (alovaInstance: Alova, configMap: any) => { const Apis = new Proxy({} as Apis, { get(_, property) { return createFunctionalProxy([property], alovaInstance, configMap); } }); // define global variable \`Apis\` - (globalThis as any).Apis = Apis; - return Apis; -}; -type MethodConfig = - (typeof import('./index'))['alovaInstance'] extends Alova - ? import('alova').AlovaMethodCreateConfig - : never; + (globalThis as any).Apis = Apis; + return Apis; +}; +type MethodConfig = AlovaMethodCreateConfig< + (typeof import('./index'))['alovaInstance'] extends Alova ? AG : any, + any, + T +>; type APISofParameters = Tag extends keyof Apis ? Url extends keyof Apis[Tag] ? Apis[Tag][Url] extends (...args: any) => any @@ -165,7 +3770,7 @@ type APISofParameters = Tag extends keyo : any; type MethodsConfigMap = { [P in keyof typeof import('./apiDefinitions').default]?: MethodConfig< - P extends \`\${infer Tag}.\${infer Url}\` ? Parameters[0]['transformData']>[0] : any + P extends \`\${infer Tag}.\${infer Url}\` ? Parameters[0]['transform']>[0] : any >; }; export const withConfigType = (config: Config) => config; @@ -189,7 +3794,7 @@ exports[`generate API > should generate code with a variant of openapi file form * * **Do not edit the file manually.** */ -import type { Alova, AlovaMethodCreateConfig, Method } from 'alova'; +import type { Alova, AlovaMethodCreateConfig, AlovaGenerics, Method } from 'alova'; import type { $$userConfigMap, alovaInstance } from '.'; import type apiDefinitions from './apiDefinitions'; @@ -197,17 +3802,35 @@ type CollapsedAlova = typeof alovaInstance; type UserMethodConfigMap = typeof $$userConfigMap; type Alova2MethodConfig = - CollapsedAlova extends Alova - ? Omit, 'params'> + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Omit< + AlovaMethodCreateConfig< + AlovaGenerics, + any, + Responded + >, + 'params' + > : never; -// Extract the return type of transformData function that define in $$userConfigMap, if it not exists, use the default type. +// Extract the return type of transform function that define in $$userConfigMap, if it not exists, use the default type. type ExtractUserDefinedTransformed< DefinitionKey extends keyof typeof apiDefinitions, Default > = DefinitionKey extends keyof UserMethodConfigMap - ? UserMethodConfigMap[DefinitionKey]['transformData'] extends (...args: any[]) => any - ? Awaited> + ? UserMethodConfigMap[DefinitionKey]['transform'] extends (...args: any[]) => any + ? Awaited> : Default : Default; type Alova2Method< @@ -215,19 +3838,33 @@ type Alova2Method< DefinitionKey extends keyof typeof apiDefinitions, CurrentConfig extends Alova2MethodConfig > = - CollapsedAlova extends Alova + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > ? Method< - State, - Export, - CurrentConfig extends undefined - ? ExtractUserDefinedTransformed - : CurrentConfig['transformData'] extends (...args: any[]) => any - ? Awaited> - : ExtractUserDefinedTransformed, - any, - RequestConfig, - Response, - ResponseHeader + AlovaGenerics< + CurrentConfig extends undefined + ? ExtractUserDefinedTransformed + : CurrentConfig['transform'] extends (...args: any[]) => any + ? Awaited> + : ExtractUserDefinedTransformed, + any, + RequestConfig, + Response, + ResponseHeader, + L1Cache, + L2Cache, + SE + > > : never; @@ -2882,12 +6519,12 @@ export default { exports[`generate API > should generate code with a variant of openapi file formats 6`] = ` "import { createAlova } from 'alova'; -import GlobalFetch from 'alova/GlobalFetch'; +import fetchAdapter from 'alova/fetch'; import { createApis, withConfigType } from './createApis'; export const alovaInstance = createAlova({ baseURL: 'https://petstore.swagger.io/v2', - requestAdapter: GlobalFetch(), + requestAdapter: fetchAdapter(), beforeRequest: method => {}, responded: res => { return res.json(); @@ -2920,15 +6557,11 @@ exports[`generate API > should generate code with a variant of openapi file form * * **Do not edit the file manually.** */ -import type { Alova, MethodType, AlovaMethodCreateConfig } from 'alova'; +import type { Alova, MethodType, AlovaGenerics, AlovaMethodCreateConfig } from 'alova'; import { Method } from 'alova'; import apiDefinitions from './apiDefinitions'; -const createFunctionalProxy = ( - array: (string | symbol)[], - alovaInstance: Alova, - configMap: any -) => { +const createFunctionalProxy = (array: (string | symbol)[], alovaInstance: Alova, configMap: any) => { // create a new proxy instance return new Proxy(function () {}, { get(_, property) { @@ -2971,7 +6604,7 @@ const createFunctionalProxy = ( }); }; -export const createApis = (alovaInstance: Alova, configMap: any) => { +export const createApis = (alovaInstance: Alova, configMap: any) => { const Apis = new Proxy({} as Apis, { get(_, property) { return createFunctionalProxy([property], alovaInstance, configMap); @@ -2981,10 +6614,11 @@ export const createApis = (alovaInstance: Alova, config (globalThis as any).Apis = Apis; return Apis; }; -type MethodConfig = - (typeof import('./index'))['alovaInstance'] extends Alova - ? import('alova').AlovaMethodCreateConfig - : never; +type MethodConfig = AlovaMethodCreateConfig< + (typeof import('./index'))['alovaInstance'] extends Alova ? AG : any, + any, + T +>; type APISofParameters = Tag extends keyof Apis ? Url extends keyof Apis[Tag] ? Apis[Tag][Url] extends (...args: any) => any @@ -2994,7 +6628,7 @@ type APISofParameters = Tag extends keyo : any; type MethodsConfigMap = { [P in keyof typeof import('./apiDefinitions').default]?: MethodConfig< - P extends \`\${infer Tag}.\${infer Url}\` ? Parameters[0]['transformData']>[0] : any + P extends \`\${infer Tag}.\${infer Url}\` ? Parameters[0]['transform']>[0] : any >; }; export const withConfigType = (config: Config) => config; @@ -3019,7 +6653,7 @@ exports[`generate API > should generate code with a variant of openapi file form * * **Do not edit the file manually.** */ -import type { Alova, AlovaMethodCreateConfig, Method } from 'alova'; +import type { Alova, AlovaMethodCreateConfig, AlovaGenerics, Method } from 'alova'; import type { $$userConfigMap, alovaInstance } from '.'; import type apiDefinitions from './apiDefinitions'; @@ -3027,17 +6661,35 @@ type CollapsedAlova = typeof alovaInstance; type UserMethodConfigMap = typeof $$userConfigMap; type Alova2MethodConfig = - CollapsedAlova extends Alova - ? Omit, 'params'> + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Omit< + AlovaMethodCreateConfig< + AlovaGenerics, + any, + Responded + >, + 'params' + > : never; -// Extract the return type of transformData function that define in $$userConfigMap, if it not exists, use the default type. +// Extract the return type of transform function that define in $$userConfigMap, if it not exists, use the default type. type ExtractUserDefinedTransformed< DefinitionKey extends keyof typeof apiDefinitions, Default > = DefinitionKey extends keyof UserMethodConfigMap - ? UserMethodConfigMap[DefinitionKey]['transformData'] extends (...args: any[]) => any - ? Awaited> + ? UserMethodConfigMap[DefinitionKey]['transform'] extends (...args: any[]) => any + ? Awaited> : Default : Default; type Alova2Method< @@ -3045,19 +6697,33 @@ type Alova2Method< DefinitionKey extends keyof typeof apiDefinitions, CurrentConfig extends Alova2MethodConfig > = - CollapsedAlova extends Alova + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > ? Method< - State, - Export, - CurrentConfig extends undefined - ? ExtractUserDefinedTransformed - : CurrentConfig['transformData'] extends (...args: any[]) => any - ? Awaited> - : ExtractUserDefinedTransformed, - any, - RequestConfig, - Response, - ResponseHeader + AlovaGenerics< + CurrentConfig extends undefined + ? ExtractUserDefinedTransformed + : CurrentConfig['transform'] extends (...args: any[]) => any + ? Awaited> + : ExtractUserDefinedTransformed, + any, + RequestConfig, + Response, + ResponseHeader, + L1Cache, + L2Cache, + SE + > > : never; @@ -4052,12 +7718,12 @@ export default { exports[`generate API > should generate code with a variant of openapi file formats 10`] = ` "import { createAlova } from 'alova'; -import GlobalFetch from 'alova/GlobalFetch'; +import fetchAdapter from 'alova/fetch'; import { createApis, withConfigType } from './createApis'; export const alovaInstance = createAlova({ baseURL: 'http://petstore.swagger.io/v2', - requestAdapter: GlobalFetch(), + requestAdapter: fetchAdapter(), beforeRequest: method => {}, responded: res => { return res.json(); @@ -4090,15 +7756,11 @@ exports[`generate API > should generate code with a variant of openapi file form * * **Do not edit the file manually.** */ -import type { Alova, MethodType, AlovaMethodCreateConfig } from 'alova'; +import type { Alova, MethodType, AlovaGenerics, AlovaMethodCreateConfig } from 'alova'; import { Method } from 'alova'; import apiDefinitions from './apiDefinitions'; -const createFunctionalProxy = ( - array: (string | symbol)[], - alovaInstance: Alova, - configMap: any -) => { +const createFunctionalProxy = (array: (string | symbol)[], alovaInstance: Alova, configMap: any) => { // create a new proxy instance return new Proxy(function () {}, { get(_, property) { @@ -4141,7 +7803,7 @@ const createFunctionalProxy = ( }); }; -export const createApis = (alovaInstance: Alova, configMap: any) => { +export const createApis = (alovaInstance: Alova, configMap: any) => { const Apis = new Proxy({} as Apis, { get(_, property) { return createFunctionalProxy([property], alovaInstance, configMap); @@ -4151,10 +7813,11 @@ export const createApis = (alovaInstance: Alova, config (globalThis as any).Apis = Apis; return Apis; }; -type MethodConfig = - (typeof import('./index'))['alovaInstance'] extends Alova - ? import('alova').AlovaMethodCreateConfig - : never; +type MethodConfig = AlovaMethodCreateConfig< + (typeof import('./index'))['alovaInstance'] extends Alova ? AG : any, + any, + T +>; type APISofParameters = Tag extends keyof Apis ? Url extends keyof Apis[Tag] ? Apis[Tag][Url] extends (...args: any) => any @@ -4164,7 +7827,7 @@ type APISofParameters = Tag extends keyo : any; type MethodsConfigMap = { [P in keyof typeof import('./apiDefinitions').default]?: MethodConfig< - P extends \`\${infer Tag}.\${infer Url}\` ? Parameters[0]['transformData']>[0] : any + P extends \`\${infer Tag}.\${infer Url}\` ? Parameters[0]['transform']>[0] : any >; }; export const withConfigType = (config: Config) => config; @@ -4189,7 +7852,7 @@ exports[`generate API > should generate code with a variant of openapi file form * * **Do not edit the file manually.** */ -import type { Alova, AlovaMethodCreateConfig, Method } from 'alova'; +import type { Alova, AlovaMethodCreateConfig, AlovaGenerics, Method } from 'alova'; import type { $$userConfigMap, alovaInstance } from '.'; import type apiDefinitions from './apiDefinitions'; @@ -4197,17 +7860,35 @@ type CollapsedAlova = typeof alovaInstance; type UserMethodConfigMap = typeof $$userConfigMap; type Alova2MethodConfig = - CollapsedAlova extends Alova - ? Omit, 'params'> + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Omit< + AlovaMethodCreateConfig< + AlovaGenerics, + any, + Responded + >, + 'params' + > : never; -// Extract the return type of transformData function that define in $$userConfigMap, if it not exists, use the default type. +// Extract the return type of transform function that define in $$userConfigMap, if it not exists, use the default type. type ExtractUserDefinedTransformed< DefinitionKey extends keyof typeof apiDefinitions, Default > = DefinitionKey extends keyof UserMethodConfigMap - ? UserMethodConfigMap[DefinitionKey]['transformData'] extends (...args: any[]) => any - ? Awaited> + ? UserMethodConfigMap[DefinitionKey]['transform'] extends (...args: any[]) => any + ? Awaited> : Default : Default; type Alova2Method< @@ -4215,19 +7896,33 @@ type Alova2Method< DefinitionKey extends keyof typeof apiDefinitions, CurrentConfig extends Alova2MethodConfig > = - CollapsedAlova extends Alova + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > ? Method< - State, - Export, - CurrentConfig extends undefined - ? ExtractUserDefinedTransformed - : CurrentConfig['transformData'] extends (...args: any[]) => any - ? Awaited> - : ExtractUserDefinedTransformed, - any, - RequestConfig, - Response, - ResponseHeader + AlovaGenerics< + CurrentConfig extends undefined + ? ExtractUserDefinedTransformed + : CurrentConfig['transform'] extends (...args: any[]) => any + ? Awaited> + : ExtractUserDefinedTransformed, + any, + RequestConfig, + Response, + ResponseHeader, + L1Cache, + L2Cache, + SE + > > : never; @@ -5293,12 +8988,12 @@ export default { exports[`generate API > should generate target versioned code 2`] = ` "import { createAlova } from 'alova'; -import GlobalFetch from 'alova/GlobalFetch'; +import fetchAdapter from 'alova/fetch'; import { createApis, withConfigType } from './createApis'; export const alovaInstance = createAlova({ baseURL: '/api1', - requestAdapter: GlobalFetch(), + requestAdapter: fetchAdapter(), beforeRequest: method => {}, responded: res => { return res.json(); @@ -8129,12 +11824,12 @@ export default { exports[`generate API > should generate target versioned code 6`] = ` "import { createAlova } from 'alova'; -import GlobalFetch from 'alova/GlobalFetch'; +import fetchAdapter from 'alova/fetch'; import { createApis, withConfigType } from './createApis'; export const alovaInstance = createAlova({ baseURL: '/api1', - requestAdapter: GlobalFetch(), + requestAdapter: fetchAdapter(), beforeRequest: method => {}, responded: res => { return res.json(); diff --git a/packages/wormhole/test/config.spec.ts b/packages/wormhole/test/config.spec.ts index 9f261f3..3b6868a 100644 --- a/packages/wormhole/test/config.spec.ts +++ b/packages/wormhole/test/config.spec.ts @@ -5,9 +5,6 @@ import { resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; import { rimraf } from 'rimraf'; import type { Config } from '~/index'; -import { initExpect } from './util'; - -initExpect(); const requireResult = new Map | null | Error>(); vi.mock('import-fresh', () => ({ @@ -251,20 +248,20 @@ describe('config', () => { importResult.set(projectRoot, configMap.ts.expectedConfig); // import()=> return config const tsConfig = await readConfig(); - expect(tsConfig).toBeDeepEqual(configMap.ts.expectedConfig); + expect(tsConfig).toStrictEqual(configMap.ts.expectedConfig); // read module config file await fs.writeFile(resolve(projectRoot, configMap.module.file), configMap.module.content, 'utf-8'); requireResult.set(projectRoot, null); // require()=> throw error importResult.set(projectRoot, configMap.module.expectedConfig); // import()=> return config const moduleConfig = await readConfig(); - expect(moduleConfig).toBeDeepEqual(configMap.module.expectedConfig); + expect(moduleConfig).toStrictEqual(configMap.module.expectedConfig); // read commonjs config file await fs.writeFile(resolve(projectRoot, configMap.commonjs.file), configMap.commonjs.content, 'utf-8'); requireResult.set(projectRoot, configMap.commonjs.expectedConfig); // require()=> return config importResult.set(projectRoot, null); // import()=> throw error const cjsConfig = await readConfig(); - expect(cjsConfig).toBeDeepEqual(configMap.commonjs.expectedConfig); + expect(cjsConfig).toStrictEqual(configMap.commonjs.expectedConfig); }); test('should read config file under target path', async () => { diff --git a/packages/wormhole/test/generate.spec.ts b/packages/wormhole/test/generate.spec.ts index a3807c8..3193f66 100644 --- a/packages/wormhole/test/generate.spec.ts +++ b/packages/wormhole/test/generate.spec.ts @@ -175,6 +175,37 @@ describe('generate API', () => { expect(await fs.readFile(resolve(outputDir3, 'globals.d.ts'), 'utf-8')).toMatchSnapshot(); }); + test('should generate code from an url', async () => { + const outputDir = resolve(__dirname, `./mock_output/swagger_petstore${getSalt()}`); + await generate({ + generator: [ + { + input: 'https://petstore.swagger.io/v2/swagger.json', + output: outputDir + } + ] + }); + expect(await fs.readFile(resolve(outputDir, 'apiDefinitions.ts'), 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(resolve(outputDir, 'index.ts'), 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(resolve(outputDir, 'createApis.ts'), 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(resolve(outputDir, 'globals.d.ts'), 'utf-8')).toMatchSnapshot(); + + const outputDir2 = resolve(__dirname, `./mock_output/generator_file${getSalt()}`); + await generate({ + generator: [ + { + input: 'https://generator3.swagger.io', + platform: 'swagger', + output: outputDir2 + } + ] + }); + expect(await fs.readFile(resolve(outputDir2, 'apiDefinitions.ts'), 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(resolve(outputDir2, 'index.ts'), 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(resolve(outputDir2, 'createApis.ts'), 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(resolve(outputDir2, 'globals.d.ts'), 'utf-8')).toMatchSnapshot(); + }); + test('should generate target versioned code', async () => { const outputDir = resolve(__dirname, './mock_output/openapi_301'); await generate({ @@ -207,6 +238,67 @@ describe('generate API', () => { expect(await fs.readFile(resolve(outputDir2, 'globals.d.ts'), 'utf-8')).toMatchSnapshot(); }); + test('should generate correspoding `mediaType` parameters', async () => { + // default mediaType: application/json + const outputDir = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir + } + ] + }); + + let globalsDeclarationFile = await fs.readFile(resolve(outputDir, 'globals.d.ts'), 'utf-8'); + expect(globalsDeclarationFile).toMatch(`generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >`); + expect(globalsDeclarationFile).toMatch(`: Alova2Method;`); + + // custom mediaType: application/json + const outputDir2 = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir2, + bodyMediaType: 'application/json', + responseMediaType: 'application/json' + } + ] + }); + + globalsDeclarationFile = await fs.readFile(resolve(outputDir2, 'globals.d.ts'), 'utf-8'); + expect(globalsDeclarationFile).toMatch(`generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >`); + expect(globalsDeclarationFile).toMatch(`: Alova2Method;`); + + // custom mediaType: application/xml + const outputDir3 = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir3, + bodyMediaType: 'application/xml', + responseMediaType: 'application/xml' + } + ] + }); + + globalsDeclarationFile = await fs.readFile(resolve(outputDir3, 'globals.d.ts'), 'utf-8'); + expect(globalsDeclarationFile).toMatch(`generateBundle< + Config extends Alova2MethodConfig + >`); + expect(globalsDeclarationFile).toMatch(`: Alova2Method;`); + }); + test('should auto detect generating module codes if not set `type`', async () => { // default type: auto // generate ts modules @@ -486,7 +578,216 @@ describe('generate API', () => { expect(globalsFile).toMatch('file: Blob'); }); - test('should `handleApi` handler change all descriptors', async () => {}); + test('should generate the right types according to `$ref` type', async () => { + const outputDir = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir + } + ] + }); + + const globalsFile = await fs.readFile(resolve(outputDir, 'globals.d.ts'), 'utf-8'); + expect(globalsFile).toMatch(`generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method;`); + expect(globalsFile).toMatch(`clientLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + /** + * flag to only return languages of type \`client\` + */ + clientOnly?: boolean; + }; + } + >`); + }); + + test('should `handleApi` handler change all descriptors', async () => { + const outputDir = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir, + handleApi: apiDescriptor => { + if (apiDescriptor.url === '/documentation') { + apiDescriptor.responses = { + type: 'object', + properties: { + attr1: { + type: 'string' + }, + attr2: { + type: 'number' + } + } + }; + return apiDescriptor; + } + if (apiDescriptor.url === '/clients') { + apiDescriptor.operationId = 'customClients'; + apiDescriptor.parameters?.push( + { + name: 'token', + in: 'path', + description: 'client token', + schema: { + type: 'string' + } + }, + { + name: 'id', + in: 'query', + description: 'client id', + required: true, + schema: { + type: 'number' + } + } + ); + apiDescriptor.url += '/suffix'; + return apiDescriptor; + } + if (apiDescriptor.url === '/model' && apiDescriptor.method.toUpperCase() === 'POST') { + apiDescriptor.tags = ['clients']; + apiDescriptor.requestBody = { + type: 'object', + properties: { + attr1: { + type: 'string' + } + } + }; + return apiDescriptor; + } + } + } + ] + }); + const globalsFile = await fs.readFile(resolve(outputDir, 'globals.d.ts'), 'utf-8'); + // check only generate specified apis + expect(globalsFile).toMatch(`documentationLanguages< + Config extends Alova2MethodConfig<{ + attr1?: string; + attr2?: number; + }>`); + expect(globalsFile).toMatch(`customClients< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * client token + */ + token?: string; + }; + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + /** + * flag to only return languages of type \`client\` + */ + clientOnly?: boolean; + /** + * client id + * [required] + */ + id: number; + }; + } + >`); + expect(globalsFile).toMatch(`generateBundle< + Config extends Alova2MethodConfig & { + data: { + attr1?: string; + }; + } + >`); + expect(globalsFile).not.toMatch('serverLanguages'); + expect(globalsFile).not.toMatch('listOptions'); + expect(globalsFile).not.toMatch('generateFromURL'); + + const apiDefinitionsFile = await fs.readFile(resolve(outputDir, 'apiDefinitions.ts'), 'utf-8'); + expect(apiDefinitionsFile).toMatch(`export default { + 'clients.customClients': ['GET', '/clients/suffix'], + 'documentation.customClients': ['GET', '/clients/suffix'], + 'documentation.documentationLanguages': ['GET', '/documentation'], + 'clients.generateBundle': ['POST', '/model'] +};`); + }); + + test('should only effect component type of modified descriptor when this component is refered by multiple descriptor', async () => { + const outputDir = resolve(__dirname, `./mock_output/openapi_300${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/openapi_300.yaml'), + output: outputDir, + handleApi: apiDescriptor => { + if (apiDescriptor.url === '/pet') { + if (apiDescriptor.method.toUpperCase() === 'POST' && apiDescriptor.responses?.properties) { + apiDescriptor.responses.properties.customAttr = { + type: 'array', + items: { + type: 'string' + } + }; + } else if (apiDescriptor.method.toUpperCase() === 'PUT' && apiDescriptor.responses?.properties) { + apiDescriptor.responses.properties.customAttr2 = { + type: 'string', + description: 'custom test attr 2' + }; + } + return apiDescriptor; + } + return apiDescriptor; + } + } + ] + }); - test('should only effect component type of modified descriptor when this component is refered by multiple descriptor', async () => {}); + const globalsFile = await fs.readFile(resolve(outputDir, 'globals.d.ts'), 'utf-8'); + // generate separated `Pet1` from `Pet` + expect(globalsFile).toMatch(`pet24< + Config extends Alova2MethodConfig & { + data: Pet; + } + >( + config: Config + ): Alova2Method;`); + // generate separated `Pet2` from `Pet` + expect(globalsFile).toMatch(`updatePet< + Config extends Alova2MethodConfig & { + data: Pet; + } + >( + config: Config + ): Alova2Method;`); + // the unmodified api still reference `Pet` + expect(globalsFile).toMatch(`findPetsByStatus< + Config extends Alova2MethodConfig & { + params: { + /** + * Status values that need to be considered for filter + * [required] + * @deprecated + */ + status: ('available' | 'pending' | 'sold')[]; + }; + } + >( + config: Config + ): Alova2Method;`); + }); }); diff --git a/packages/wormhole/typings/index.d.ts b/packages/wormhole/typings/index.d.ts index 8a8b588..94c2a26 100644 --- a/packages/wormhole/typings/index.d.ts +++ b/packages/wormhole/typings/index.d.ts @@ -16,8 +16,8 @@ export type ApiDescriptor = Omit void): ApiDescriptor; + (apiDescriptor: ApiDescriptor): ApiDescriptor | void | undefined | null; + (apiDescriptor: ApiDescriptor, log: (...args: any[]) => void): ApiDescriptor | void | undefined | null; } export type GeneratorConfig = { // openapi的json文件url地址 From da6498798e6ff4f6c3690acf5a8fb8cee8fc851b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E9=95=87?= Date: Thu, 24 Oct 2024 14:00:15 +0800 Subject: [PATCH 27/47] feat: add features workspaces & import statement in config file, tests finish --- package.json | 19 +- packages/vscode-extension/package.json | 4 +- packages/wormhole/bin/index.js | 45 - packages/wormhole/build.config.ts | 57 - packages/wormhole/package.json | 62 +- packages/wormhole/src/bin/actions.ts | 39 + packages/wormhole/src/bin/cli.ts | 23 + packages/wormhole/src/config.ts | 4 +- packages/wormhole/src/createConfig.ts | 12 +- packages/wormhole/src/functions/alovaJson.ts | 13 +- .../wormhole/src/functions/generateApi.ts | 11 +- .../src/functions/getAutoTemplateType.ts | 2 +- .../wormhole/src/functions/getOpenApiData.ts | 2 +- .../wormhole/src/functions/openApi2Data.ts | 20 +- packages/wormhole/src/generate.ts | 14 +- packages/wormhole/src/helper/lodaders.ts | 105 - packages/wormhole/src/index.ts | 2 +- packages/wormhole/src/interface.type.ts | 102 + .../wormhole/src/modules/Configuration.ts | 2 +- packages/wormhole/src/modules/TemplateFile.ts | 2 +- packages/wormhole/src/readConfig.ts | 61 +- packages/wormhole/src/resolveWorkspaces.ts | 87 + packages/wormhole/src/utils/index.ts | 46 +- .../test/__snapshots__/generate.spec.ts.snap | 10 +- packages/wormhole/test/cli.spec.ts | 59 + packages/wormhole/test/config.spec.ts | 278 +- packages/wormhole/test/generate.spec.ts | 83 +- .../test/openapis/multiple_media_type.yaml | 160 + packages/wormhole/test/workspaces.spec.ts | 238 + packages/wormhole/tsconfig.build.json | 8 + packages/wormhole/tsconfig.json | 2 + packages/wormhole/typings/index.d.ts | 224 +- packages/wormhole/typings/vitest.d.ts | 10 - path.ts | 10 - pnpm-lock.yaml | 4102 ++++++----------- tsconfig.base.json | 5 +- 36 files changed, 2538 insertions(+), 3385 deletions(-) delete mode 100755 packages/wormhole/bin/index.js delete mode 100644 packages/wormhole/build.config.ts create mode 100644 packages/wormhole/src/bin/actions.ts create mode 100644 packages/wormhole/src/bin/cli.ts delete mode 100644 packages/wormhole/src/helper/lodaders.ts create mode 100644 packages/wormhole/src/interface.type.ts create mode 100644 packages/wormhole/src/resolveWorkspaces.ts create mode 100644 packages/wormhole/test/cli.spec.ts create mode 100644 packages/wormhole/test/openapis/multiple_media_type.yaml create mode 100644 packages/wormhole/test/workspaces.spec.ts create mode 100644 packages/wormhole/tsconfig.build.json delete mode 100644 packages/wormhole/typings/vitest.d.ts delete mode 100644 path.ts diff --git a/package.json b/package.json index d5c074d..f9177be 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "format:fix": "prettier --write .", "api-test": "tsx scripts/api-test.ts", "commit": "git-cz && git push", - "prepare": "husky && pnpm api-test" + "prepare": "husky" }, "license": "MIT", "repository": { @@ -31,26 +31,22 @@ "*.js,*.ts": "npm run lint:fix" }, "devDependencies": { - "@alova/wormhole": "workspace:^", "@commitlint/cli": "^19.3.0", "@commitlint/config-conventional": "^19.2.2", "@types/js-yaml": "^4.0.9", "@types/lodash": "^4.17.5", - "@types/mocha": "^10.0.6", - "@types/node": "18.x", - "@types/node-fetch": "^2.6.11", + "@types/node": "^18.19.0", "@types/rimraf": "^4.0.5", "@types/serialize-javascript": "^5.0.4", - "@types/swagger2openapi": "^7.0.4", "@typescript-eslint/eslint-plugin": "^7.13.0", "@typescript-eslint/parser": "^7.13.0", "commitizen": "^4.3.0", "cz-conventional-changelog": "^3.3.0", + "dts-bundle-generator": "^9.5.1", "eslint": "^8.57.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^18.0.0", "eslint-plugin-prettier": "^5.1.3", - "fast-glob": "^3.3.2", "husky": "^9.0.11", "lint-staged": "^15.2.2", "npm-run-all": "^4.1.5", @@ -68,14 +64,5 @@ "commitizen": { "path": "./node_modules/cz-conventional-changelog" } - }, - "dependencies": { - "cosmiconfig": "^9.0.0", - "handlebars": "^4.7.8", - "import-fresh": "^3.3.0", - "lodash": "^4.17.21", - "node-fetch": "^2.7.0", - "openapi-types": "^12.1.3", - "swagger2openapi": "^7.0.8" } } diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index 94eb17e..f5987d2 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -73,8 +73,6 @@ "@types/vscode": "^1.89.0", "@vscode/test-cli": "^0.0.9", "@vscode/test-electron": "^2.3.9", - "@vscode/vsce": "^2.29.0", - "esbuild": "^0.23.0", - "esbuild-plugin-alias": "^0.2.1" + "@vscode/vsce": "^2.29.0" } } diff --git a/packages/wormhole/bin/index.js b/packages/wormhole/bin/index.js deleted file mode 100755 index e665ee9..0000000 --- a/packages/wormhole/bin/index.js +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env node -const { program } = require('commander'); -const package = require('../package.json'); -const { createConfig, readConfig, generate } = require('../dist/index.cjs'); - -program.name('@alova/wormhole').description('CLI to generate api for alova.js').version(package.version); - -program - .command('init') - .description('init alova.config') - .action(() => { - createConfig() - .then(() => { - console.log('alova.config生成成功!'); - }) - .catch(error => { - console.log(error); - }); - }); - -program - .command('gen') - .option('-f', 'force generate api') - .description('generate api for alova.js') - .action(option => { - readConfig() - .then(config => { - if (!config) { - throw Error('Expected to create alova.config.js in root directory.'); - } - return generate(config, { force: option.f }); - }) - .then(([result]) => { - if (result) { - console.log('api文件生成成功!'); - } else { - console.log('api文件生成失败!,尝试强制生成【alova gen -f】'); - } - }) - .catch(error => { - console.log(error); - }); - }); - -program.parse(process.argv); // 表示使用 Commander 来处理命令行参数 diff --git a/packages/wormhole/build.config.ts b/packages/wormhole/build.config.ts deleted file mode 100644 index 3431df0..0000000 --- a/packages/wormhole/build.config.ts +++ /dev/null @@ -1,57 +0,0 @@ -import fglob from 'fast-glob'; -import fs from 'node:fs'; -import path from 'node:path'; -import url from 'node:url'; -import { defineBuildConfig } from 'unbuild'; - -export default defineBuildConfig({ - entries: ['src/index'], - clean: true, - declaration: true, // 直接使用typings - failOnWarn: false, - hooks: { - 'build:done': async ctx => { - // fix:stub mode jiti path `file:///` - // https://github.com/unjs/unbuild/issues/248 - if (ctx.options.stub) { - fglob.sync('./dist/**/*.*js', { onlyFiles: true }).forEach(fileUrl => { - const filePath = path.resolve(__dirname, fileUrl); - fs.readFile(filePath, (err, data) => { - if (err) { - return err; - } - const str = data - .toString() - .replace(/file:\/\/\/(.+)/g, subStr => - path.relative(path.resolve(filePath, '..'), url.fileURLToPath(subStr)).replace(/\\/g, '/') - ); - fs.writeFile(filePath, str, err => { - if (err) { - return err; - } - }); - }); - }); - } - // copy all things under src/templates to dist/templates - // https://github.com/unjs/unbuild/issues/266 - const { copy } = await import('fs-extra'); - await copy('src/templates', 'dist/templates'); - } - }, - alias: { - '@': path.resolve(__dirname, './src'), - '~': path.resolve(__dirname, './typings'), - '#': path.join(__dirname) - }, - externals: ['typescript'], - rollup: { - alias: { - entries: {} - }, - dts: { - respectExternal: false - }, - emitCJS: true - } -}); diff --git a/packages/wormhole/package.json b/packages/wormhole/package.json index e77eb3b..5b5104b 100644 --- a/packages/wormhole/package.json +++ b/packages/wormhole/package.json @@ -3,42 +3,58 @@ "version": "1.0.0", "description": "More modern openAPI generating solution for alova.js", "homepage": "https://alova.js.org", - "main": "./dist/index.cjs", - "module": "./dist/index.mjs", + "main": "./dist/index.js", "types": "./dist/index.d.ts", "bin": { - "alova": "./bin/index.js" - }, - "exports": { - ".": { - "types": "./dist/index.d.ts", - "import": "./dist/index.mjs", - "require": "./dist/index.cjs" - } + "alova": "./dist/bin/cli.js" }, "scripts": { - "build": "unbuild", - "dev": "pnpm run stub", - "stub": "unbuild --stub" + "build": "npm run build:ts && npm run build:dts", + "build:ts": "tsc --build tsconfig.build.json", + "build:dts": "dts-bundle-generator -o typings/index.d.ts src/index.ts --no-check --no-banner --project tsconfig.build.json" }, - "keywords": [], - "author": "", + "keywords": [ + "openapi", + "auto-generating", + "api", + "apis", + "fetch", + "axios", + "axios", + "request", + "fetch-api", + "superagent", + "alova", + "wormhole" + ], + "author": "chenzhilin", "license": "MIT", - "devDependencies": { - "@types/fs-extra": "^11.0.4", - "fs-extra": "^11.2.0", - "memfs": "^4.11.1", - "openapi-types": "^12.1.3", - "unbuild": "^2.0.0" + "repository": { + "type": "git", + "url": "https://github.com/alovajs/devtools.git" + }, + "bugs": { + "url": "https://github.com/alovajs/devtools/issues" }, + "files": [ + "dist", + "typings" + ], "dependencies": { + "alova": "^3.1.0", "commander": "^12.1.0", - "cosmiconfig": "^9.0.0", + "esbuild": "^0.24.0", + "glob": "^11.0.0", "handlebars": "^4.7.8", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "lodash": "^4.17.21", - "node-fetch": "^2.7.0", + "openapi-types": "^12.1.3", + "ora": "^8.1.0", "swagger2openapi": "^7.0.8" + }, + "devDependencies": { + "@types/swagger2openapi": "^7.0.4", + "memfs": "^4.11.1" } } diff --git a/packages/wormhole/src/bin/actions.ts b/packages/wormhole/src/bin/actions.ts new file mode 100644 index 0000000..f88cac3 --- /dev/null +++ b/packages/wormhole/src/bin/actions.ts @@ -0,0 +1,39 @@ +import { createConfig, generate, readConfig, resolveWorkspaces } from '@/index'; +import { TemplateType } from '@/interface.type'; +import ora from 'ora'; + +export const actionInit = async ({ type, path: projectPath }: { type?: TemplateType; path?: string }) => { + const spinner = ora('Initializing configuration file...').start(); + await createConfig({ type, projectPath }); + spinner.succeed('alova configuration file is initialized!'); +}; + +export const actionGen = async ({ + workspace = true, + path: projectPath, + force +}: { + workspace?: boolean; + path?: string; + force?: boolean; +}) => { + let workspacePaths: (string | undefined)[] = [undefined]; + if (workspace) { + workspacePaths = await resolveWorkspaces(projectPath); + } + for (const dir of workspacePaths) { + const spinner = ora(`Generating...`).start(); + const config = await readConfig(dir); + const results = await generate(config, { + force, + projectPath + }); + results.forEach(result => { + if (result) { + spinner.succeed(`workspace \`${dir}\` is generated!`); + } else { + spinner.fail(`workspace \`${dir}\` is failed, try to force generate with \`alova gen -f\`!`); + } + }); + } +}; diff --git a/packages/wormhole/src/bin/cli.ts b/packages/wormhole/src/bin/cli.ts new file mode 100644 index 0000000..8c6579c --- /dev/null +++ b/packages/wormhole/src/bin/cli.ts @@ -0,0 +1,23 @@ +#!/usr/bin/env node +import { Command } from 'commander'; +import { actionGen, actionInit } from './actions'; +const pkg = require('../../package.json'); + +const program = new Command(); +program.name('alova').description('CLI to generate api for alova.js').version(pkg.version); +program + .command('init') + .description('init a configuration file') + .option('-t, --type [type]', 'type of configuration') + .option('-p, --path [path]', 'init configuration path') + .action(actionInit); + +program + .command('gen') + .option('-f, --force', 'force generate api') + .option('-p, --path [path]', 'generating path') + .option('-w, --workspace', 'generating path') + .description('generate api for alova.js') + .action(actionGen); + +program.parse(process.argv); diff --git a/packages/wormhole/src/config.ts b/packages/wormhole/src/config.ts index c8125aa..00d3659 100644 --- a/packages/wormhole/src/config.ts +++ b/packages/wormhole/src/config.ts @@ -10,11 +10,11 @@ export const DEFAULT_CONFIG = { let ts: typeof import('typescript') | null = null; try { ts = (await import('typescript')).default; - } catch (error) {} + } catch {} return ts; }, templateData: TEMPLATE_DATA, - Error: class extends Error {} + Error }; export function setGlobalConfig(config: Partial) { Object.assign(DEFAULT_CONFIG, config); diff --git a/packages/wormhole/src/createConfig.ts b/packages/wormhole/src/createConfig.ts index 40bf3a6..8e9e391 100644 --- a/packages/wormhole/src/createConfig.ts +++ b/packages/wormhole/src/createConfig.ts @@ -1,9 +1,17 @@ +import path from 'node:path'; import getAlovaVersion, { AlovaVersion } from './functions/getAlovaVersion'; import getAutoTemplateType from './functions/getAutoTemplateType'; +import { TemplateType } from './interface.type'; import TemplateFile from './modules/TemplateFile'; -const createConfig = (projectPath = process.cwd()) => { - const type = getAutoTemplateType(projectPath); +interface ConfigCreationOptions { + projectPath?: string; + type?: TemplateType; +} + +const createConfig = ({ projectPath = '', type }: ConfigCreationOptions = {}) => { + projectPath = path.isAbsolute(projectPath) ? projectPath : path.resolve(process.cwd(), projectPath); + type = type || getAutoTemplateType(projectPath); const moduleType = TemplateFile.getModuleType(type); const alovaVersion: AlovaVersion = getAlovaVersion(projectPath); const templateFile = new TemplateFile(type, alovaVersion); diff --git a/packages/wormhole/src/functions/alovaJson.ts b/packages/wormhole/src/functions/alovaJson.ts index 6dd9be6..b0be9a1 100644 --- a/packages/wormhole/src/functions/alovaJson.ts +++ b/packages/wormhole/src/functions/alovaJson.ts @@ -1,5 +1,5 @@ import { DEFAULT_CONFIG } from '@/config'; -import { format } from '@/utils'; +import { existsPromise, format } from '@/utils'; import fs from 'node:fs/promises'; import path from 'node:path'; import type { TemplateData } from './openApi2Data'; @@ -10,9 +10,7 @@ export const writeAlovaJson = async (data: TemplateData, originPath: string, nam // 定义 JSON 文件的路径和名称 const filePath = `${originPath}_${name}`; const dirPath = filePath.split(/\/|\\/).slice(0, -1).join('/'); - try { - await fs.access(dirPath); - } catch (error) { + if (!(await existsPromise(dirPath))) { await fs.mkdir(dirPath, { recursive: true }); } // 使用 fs.writeFile 将 JSON 数据写入文件 @@ -21,11 +19,8 @@ export const writeAlovaJson = async (data: TemplateData, originPath: string, nam export const readAlovaJson = async (originPath: string, name = 'api.json') => { // 定义 JSON 文件的路径和名称 const filePath = `${originPath}_${name}`; - - try { - await fs.access(filePath); - } catch (error) { - throw new DEFAULT_CONFIG.Error('alovaJson not exists'); + if (!(await existsPromise(filePath))) { + throw new DEFAULT_CONFIG.Error('alovaJson is not exists'); } // 使用 fs.readFile 读取 JSON 文件 diff --git a/packages/wormhole/src/functions/generateApi.ts b/packages/wormhole/src/functions/generateApi.ts index 797bc57..525093a 100644 --- a/packages/wormhole/src/functions/generateApi.ts +++ b/packages/wormhole/src/functions/generateApi.ts @@ -1,9 +1,9 @@ import { DEFAULT_CONFIG } from '@/config'; +import type { GeneratorConfig, TemplateType } from '@/interface.type'; +import { existsPromise } from '@/utils'; import { isEqual } from 'lodash'; -import fs from 'node:fs/promises'; import path from 'node:path'; import { OpenAPIV3_1 } from 'openapi-types'; -import type { GeneratorConfig, TemplateType } from '~/index'; import TemplateFile from '../modules/TemplateFile'; import { getAlovaJsonPath, writeAlovaJson } from './alovaJson'; import getAlovaVersion, { AlovaVersion } from './getAlovaVersion'; @@ -56,12 +56,7 @@ export default async function ( // 生成alova.json文件 await writeAlovaJson(templateData, alovaJsonPath); // 获取是否存在index.ts|index.js - let indexIsExists = true; - try { - await fs.access(path.join(outputDir, `index${templateFile.getExt()}`)); - } catch (error) { - indexIsExists = false; - } + const indexIsExists = await existsPromise(path.join(outputDir, `index${templateFile.getExt()}`)); // mustache语法生成 // 定义模版配置对象 const generatingPromises = [ diff --git a/packages/wormhole/src/functions/getAutoTemplateType.ts b/packages/wormhole/src/functions/getAutoTemplateType.ts index 9fcd8f5..10fd369 100644 --- a/packages/wormhole/src/functions/getAutoTemplateType.ts +++ b/packages/wormhole/src/functions/getAutoTemplateType.ts @@ -1,7 +1,7 @@ +import type { TemplateType } from '@/interface.type'; import importFresh from 'import-fresh'; import path from 'node:path'; import { PackageJson } from 'type-fest'; -import type { TemplateType } from '~/index'; export default (workspaceRootDir: string): TemplateType => { const packageJson: PackageJson = importFresh(path.resolve(workspaceRootDir, './package.json')); diff --git a/packages/wormhole/src/functions/getOpenApiData.ts b/packages/wormhole/src/functions/getOpenApiData.ts index f1b9b1a..46f8f9b 100644 --- a/packages/wormhole/src/functions/getOpenApiData.ts +++ b/packages/wormhole/src/functions/getOpenApiData.ts @@ -1,4 +1,5 @@ import { DEFAULT_CONFIG } from '@/config'; +import type { PlatformType } from '@/interface.type'; import { fetchData } from '@/utils'; import importFresh from 'import-fresh'; import YAML from 'js-yaml'; @@ -6,7 +7,6 @@ import fs from 'node:fs/promises'; import path from 'node:path'; import { OpenAPIV2, OpenAPIV3_1 } from 'openapi-types'; import swagger2openapi from 'swagger2openapi'; -import type { PlatformType } from '~/index'; // 判断是否是swagger2.0 function isSwagger2(data: any): data is OpenAPIV2.Document { return !!data?.swagger; diff --git a/packages/wormhole/src/functions/openApi2Data.ts b/packages/wormhole/src/functions/openApi2Data.ts index b85cd45..ea2712f 100644 --- a/packages/wormhole/src/functions/openApi2Data.ts +++ b/packages/wormhole/src/functions/openApi2Data.ts @@ -3,10 +3,10 @@ import { findBy$ref, getStandardRefName, isReferenceObject, mergeObject, removeA import { convertToType, jsonSchema2TsStr } from '@/helper/schema2type'; import { getStandardOperationId, getStandardTags } from '@/helper/standard'; import { generateDefaultValues } from '@/helper/typeStr'; +import type { Api, ApiDescriptor, GeneratorConfig, TemplateType } from '@/interface.type'; import { format, removeUndefined } from '@/utils'; import { cloneDeep, isEmpty } from 'lodash'; import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'; -import type { Api, ApiDescriptor, GeneratorConfig, TemplateType } from '~/index'; import { AlovaVersion } from './getAlovaVersion'; type Path = { @@ -112,7 +112,7 @@ const parseResponse = async ( const responseObject: OpenAPIV3_1.ResponseObject = isReferenceObject(responseInfo) ? findBy$ref(responseInfo.$ref, openApi) : responseInfo; - const key = getContentKey(responseObject.content ?? {}, config.responseMediaType); + const key = getContentKey(responseObject.content, config.responseMediaType); const responseSchema = responseObject?.content?.[key]?.schema ?? {}; const responseName = await remove$ref(responseSchema, openApi, config, schemasMap, '', removeMap); return { @@ -155,13 +155,11 @@ const parseRequestBody = async ( }) }; }; -const getContentKey = (content: Record, requireKey: string, defaultKey = 'application/json') => { - let key = Object.keys(content ?? {})[0]; - requireKey = requireKey ?? defaultKey; - if (requireKey && content?.[requireKey]) { +const getContentKey = (content: Record = {}, requireKey = 'application/json') => { + let key = Object.keys(content)[0] || requireKey; + if (content[requireKey]) { key = requireKey; } - key = key ?? defaultKey; return key; }; const parseParameters = async ( @@ -275,7 +273,7 @@ export const transformPathObj = async ( apiDescriptor.parameters = []; const parametersArray = isReferenceObject(parameters) ? findBy$ref(parameters.$ref, openApi, true) - : parameters ?? []; + : (parameters ?? []); for (const parameter of parametersArray) { const parameterObject = removeAll$ref(parameter, openApi); apiDescriptor.parameters.push(parameterObject); @@ -283,19 +281,19 @@ export const transformPathObj = async ( } if (requestBody) { requestBodyObject = isReferenceObject(requestBody) ? findBy$ref(requestBody.$ref, openApi, true) : requestBody; - requestKey = getContentKey(requestBodyObject.content || {}, config.bodyMediaType); + requestKey = getContentKey(requestBodyObject.content, config.bodyMediaType); const requestBodySchema = requestBodyObject.content?.[requestKey].schema ?? {}; const requestBodySchemaObj = removeAll$ref(requestBodySchema, openApi); apiDescriptor.requestBody = requestBodySchemaObj; } if (response200) { responseObject = isReferenceObject(response200) ? findBy$ref(response200.$ref, openApi, true) : response200; - responseKey = getContentKey(responseObject.content || {}, config.responseMediaType); + responseKey = getContentKey(responseObject.content, config.responseMediaType); const responseSchema = responseObject.content?.[responseKey].schema ?? {}; const responseSchemaObj = removeAll$ref(responseSchema, openApi); apiDescriptor.responses = responseSchemaObj; } - let newApiDescriptor = apiDescriptor; + let newApiDescriptor: ApiDescriptor | void | undefined | null = apiDescriptor; let handleApiDone = false; try { newApiDescriptor = handleApi(apiDescriptor, DEFAULT_CONFIG.log); diff --git a/packages/wormhole/src/generate.ts b/packages/wormhole/src/generate.ts index b0b481f..3258946 100644 --- a/packages/wormhole/src/generate.ts +++ b/packages/wormhole/src/generate.ts @@ -1,12 +1,18 @@ -import type { Config, GenerateApiOptions } from '~/index'; +import type { Config, GenerateApiOptions } from '@/interface.type'; import generateApi from './functions/generateApi'; import Configuration from './modules/Configuration'; -const generate = async (config: Config, options?: GenerateApiOptions) => { +/** + * generate apis based on config + * @param config generating config + * @param rules config rules + * @returns + */ +const generate = async (config: Config, rules?: GenerateApiOptions) => { if (!config) { return [] as boolean[]; } - const configuration = new Configuration(config, options?.projectPath ?? process.cwd()); + const configuration = new Configuration(config, rules?.projectPath ?? process.cwd()); // 检查新配置 configuration.checkConfig(); const outputPathArr = configuration.getAllOutputPath(); @@ -22,7 +28,7 @@ const generate = async (config: Config, options?: GenerateApiOptions) => { openApiData[idx], generatorConfigArr[idx], templateTypeArr[idx] ?? 'commonjs', - options?.force ?? false + rules?.force ?? false ) ) ); diff --git a/packages/wormhole/src/helper/lodaders.ts b/packages/wormhole/src/helper/lodaders.ts deleted file mode 100644 index c2eadec..0000000 --- a/packages/wormhole/src/helper/lodaders.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { DEFAULT_CONFIG } from '@/config'; -import { loadEsmModule } from '@/utils'; -import { Loader, LoaderSync } from 'cosmiconfig'; -import importFresh from 'import-fresh'; -import { existsSync, mkdirSync } from 'node:fs'; -import { rm, writeFile } from 'node:fs/promises'; -import path from 'node:path'; -import { pathToFileURL } from 'node:url'; - -let typescript: typeof import('typescript'); -export const loadTs: Loader = async function loadTs(filepath, content) { - const ts = await DEFAULT_CONFIG.getTypescript(); - if (typescript === undefined && ts) { - typescript = ts; - } - if (!typescript) { - throw new DEFAULT_CONFIG.Error('typescript dependencie is required'); - } - let transpiledContent; - try { - const config = resolveTsConfig(path.dirname(filepath)) ?? {}; - config.compilerOptions = { - ...config.compilerOptions, - module: typescript.ModuleKind.ES2022, - moduleResolution: typescript.ModuleResolutionKind.Bundler, - target: typescript.ScriptTarget.ES2022, - noEmit: false - }; - transpiledContent = typescript.transpileModule(content, config).outputText; - } catch (error: any) { - error.message = `TypeScript Error in ${filepath}:\n${error.message}`; - throw error; - } - return createTempFile(filepath, transpiledContent, 'js', jsPath => loadJs(jsPath, transpiledContent)); -}; - -export const loadJsSync: LoaderSync = importFresh; - -export const loadEsModule = async (filepath: string) => { - const { href } = pathToFileURL(filepath); - return (await loadEsmModule(`${href}?t=${Date.now()}`)).default; -}; -export const createTempFile = async ( - filepath: string, - content: string, - ext: 'cjs' | 'mjs' | 'js', - callback?: (compiledFilepath: string) => T | Promise -) => { - const parsedPath = path.parse(filepath); - const addPath = DEFAULT_CONFIG.alovaTempPath; - const dirPath = path.join(parsedPath.dir, parsedPath.dir.includes(addPath) ? '' : addPath); - const compiledFilepath = path.join(dirPath, `${Date.now()}-${Math.random().toString(16).slice(2)}.${ext}`); - if (!existsSync(dirPath)) { - mkdirSync(dirPath, { recursive: true }); - } - let result = null; - try { - await writeFile(compiledFilepath, content); - result = await callback?.(compiledFilepath); - } finally { - if (existsSync(compiledFilepath)) { - await rm(compiledFilepath); - } - } - return result as T; -}; -export const loadJs: Loader = async function loadJs(filepath, content) { - try { - return await createTempFile(filepath, content, 'js', jspath => loadJsSync(jspath, '')); - } catch (requireError: any) { - try { - return await loadEsModule(filepath); - } catch (error: any) { - const errorStr = requireError.toString() + error.toString(); - if (errorStr.includes("SyntaxError: Unexpected token 'export'")) { - return createTempFile(filepath, content, 'mjs', mjsPath => loadEsModule(mjsPath)); - } - if ( - errorStr.includes( - 'contains "type": "module". To treat it as a CommonJS script, rename it to use the \'.cjs\' file extension' - ) - ) { - return createTempFile(filepath, content, 'cjs', cjsPath => loadJsSync(cjsPath, '')); - } - if ( - requireError.code === 'ERR_REQUIRE_ESM' || - (requireError instanceof SyntaxError && - requireError.toString().includes('Cannot use import statement outside a module')) - ) { - throw new DEFAULT_CONFIG.Error(error.toString()); - } - throw new DEFAULT_CONFIG.Error(requireError.toString()); - } - } -}; -function resolveTsConfig(directory: string): any { - const filePath = typescript.findConfigFile(directory, fileName => typescript.sys.fileExists(fileName)); - if (filePath !== undefined) { - const { config, error } = typescript.readConfigFile(filePath, path => typescript.sys.readFile(path)); - if (error) { - throw new DEFAULT_CONFIG.Error(`Error in ${filePath}: ${error.messageText.toString()}`); - } - return config; - } -} diff --git a/packages/wormhole/src/index.ts b/packages/wormhole/src/index.ts index e36ea55..573d577 100644 --- a/packages/wormhole/src/index.ts +++ b/packages/wormhole/src/index.ts @@ -1,5 +1,5 @@ -export type * from '~/index'; export { setGlobalConfig } from './config'; export { default as createConfig } from './createConfig'; export { default as generate } from './generate'; export * from './readConfig'; +export { default as resolveWorkspaces } from './resolveWorkspaces'; diff --git a/packages/wormhole/src/interface.type.ts b/packages/wormhole/src/interface.type.ts new file mode 100644 index 0000000..2b13987 --- /dev/null +++ b/packages/wormhole/src/interface.type.ts @@ -0,0 +1,102 @@ +import type { OpenAPIV3_1 } from 'openapi-types'; + +// 查找对应的input属性值 +export type ConfigType = 'auto' | 'ts' | 'typescript' | 'module' | 'commonjs'; +// 模板类型 +export type TemplateType = 'typescript' | 'module' | 'commonjs'; +// 平台类型 +export type PlatformType = 'swagger' | 'knife4j' | 'yapi'; +export type SchemaObject = OpenAPIV3_1.SchemaObject; +export type Parameter = OpenAPIV3_1.ParameterObject; +export type OperationObject = OpenAPIV3_1.OperationObject; +export type ApiDescriptor = Omit & { + url: string; + method: string; + parameters?: Parameter[]; + requestBody?: SchemaObject; + responses?: SchemaObject; +}; +export interface HandleApi { + (apiDescriptor: ApiDescriptor): ApiDescriptor | void | undefined | null; + (apiDescriptor: ApiDescriptor, log: (...args: any[]) => void): ApiDescriptor | void | undefined | null; +} +export type GeneratorConfig = { + // openapi的json文件url地址 + input: string; + // input: 'http://localhost:3000/openapi.json', + // input: 'openapi/api.json' // 以当前项目为相对目录的本地地址 + // input: 'http://192.168.5.123:8080' // 没有指向openapi文件时,必须配合platform参数使用 + + // 支持openapi的平台,目前先支持swagger、knife4j、yapi,默认为空 + // 当指定了此参数后,input字段只需要指定文档的地址而不需要指定到openapi文件,减小使用门槛 + // 不同平台,它的openapi文件地址不一样,根据平台标识去对应地址下读取文件即可。 + platform?: PlatformType; + + // 接口文件和类型文件的输出路径,多个generator不能重复的地址,否则生成的代码会相互覆盖,无意义 + output: string; + + // (具体看下面)指定生成的响应数据的mediaType,指定后以此数据类型来生成200状态码的响应ts格式,默认application/json + responseMediaType?: string; + + // (具体看下面)指定生成的请求体数据的mediaType,指定后以此数据类型来生成请求体的ts格式,默认application/json + bodyMediaType?: string; + + // 生成代码的类型,可选值为auto/ts/typescript/module/commonjs,默认为auto,会通过一定规则判断当前项目的类型 + // ts/typescript:意思相同,表示生成ts类型文件 + // module:生成esModule规范文件 + // commonjs:表示生成commonjs规范文件 + type?: ConfigType; + // 指定alova版本 + version?: number; + // 多项目使用global字段 + global?: string; + // 是否使用import来导入类型,默认false + // 开启此选项后,生成的apiDefinitions.ts文件将使用import语法来导入类型,而不是/// + useImportType?: boolean; + // 没有require时默认为require,只有nullable生效 + defaultRequire?: boolean; + // (具体看下面)过滤或转换生成的api接口函数,返回一个新的apiDescriptor来生成api调用函数 + // 未指定此函数时则不转换apiDescripor对象 + // apiDescriptor的格式与openapi文件的接口对象格式相同 + // 对类型生成也同样适用 + handleApi?: HandleApi; +}; +export type Config = { + // api生成设置,为数组,每项代表一个自动生成的规则,包含生成的输入输出目录、规范文件地址等等 + // 目前只支持openapi规范,包括openapi的2.0和3.0格式,但目前只做3.0规范 + generator: GeneratorConfig[]; + + // 是否自动更新接口,默认开启,每5分钟检查一次,false时关闭 + autoUpdate?: + | boolean + | { + // 编辑器开启时更新,默认false + launchEditor?: boolean; + // 自动更新间隔,单位毫秒 + interval: number; + }; +}; +export type GenerateApiOptions = { + force?: boolean; + projectPath?: string; +}; +/** + * 生成的api描述信息 + */ +export interface Api { + method: string; + summary: string; + path: string; + pathParameters: string; + queryParameters: string; + pathParametersComment?: string; + queryParametersComment?: string; + responseComment?: string; + requestComment?: string; + name: string; + global: string; + responseName: string; + requestName?: string; + defaultValue?: string; + pathKey: string; +} diff --git a/packages/wormhole/src/modules/Configuration.ts b/packages/wormhole/src/modules/Configuration.ts index 982e7e9..f35d5d3 100644 --- a/packages/wormhole/src/modules/Configuration.ts +++ b/packages/wormhole/src/modules/Configuration.ts @@ -3,9 +3,9 @@ import { getAlovaJsonPath, readAlovaJson } from '@/functions/alovaJson'; import getAutoTemplateType from '@/functions/getAutoTemplateType'; import getOpenApiData from '@/functions/getOpenApiData'; import { isValidJSIdentifier } from '@/helper/standard'; +import type { Config, GeneratorConfig, TemplateType } from '@/interface.type'; import { isEmpty } from '@/utils'; import path from 'node:path'; -import type { Config, GeneratorConfig, TemplateType } from '~/index'; export default class Configuration { config: Config; diff --git a/packages/wormhole/src/modules/TemplateFile.ts b/packages/wormhole/src/modules/TemplateFile.ts index 4a43461..1e9c19d 100644 --- a/packages/wormhole/src/modules/TemplateFile.ts +++ b/packages/wormhole/src/modules/TemplateFile.ts @@ -1,7 +1,7 @@ import type { AlovaVersion } from '@/functions/getAlovaVersion'; +import type { TemplateType } from '@/interface.type'; import { generateFile, readAndRenderTemplate } from '@/utils'; import { cloneDeep, merge } from 'lodash'; -import type { TemplateType } from '~/index'; interface RenderTemplateOptions { root?: boolean; diff --git a/packages/wormhole/src/readConfig.ts b/packages/wormhole/src/readConfig.ts index af9c142..ad0e475 100644 --- a/packages/wormhole/src/readConfig.ts +++ b/packages/wormhole/src/readConfig.ts @@ -1,48 +1,35 @@ -import { cosmiconfig } from 'cosmiconfig'; +import type { Config } from '@/interface.type'; +import esbuild from 'esbuild'; +import { unlink } from 'node:fs/promises'; import path from 'node:path'; -import type { Config } from '~/index'; import { DEFAULT_CONFIG } from './config'; -import { getAlovaJsonPath, readAlovaJson } from './functions/alovaJson'; -import { loadJs, loadTs } from './helper/lodaders'; +import { getAlovaJsonPath } from './functions/alovaJson'; import Configuration from './modules/Configuration'; +import { resolveConfigFile } from './utils'; -const alovaExplorer = cosmiconfig('alova', { - cache: false, - loaders: { - '.js': loadJs, - '.cjs': loadJs, - '.mjs': loadJs, - '.ts': loadTs, - '.mts': loadTs, - '.cts': loadTs - } -}); export const readConfig = async (projectPath = process.cwd()) => { - const searchResult = await alovaExplorer.search(path.resolve(projectPath)); - alovaExplorer.clearCaches(); - if (searchResult?.isEmpty) { - return null; - } - const config = searchResult?.config as Config | null; - if (config) { - // 缓存文件地址 - readAndSaveAlovaJson(config, projectPath); + const configFile = await resolveConfigFile(projectPath); + if (!configFile) { + throw new DEFAULT_CONFIG.Error(`Cannot found config file from path ${projectPath}`); } - return config; -}; -const readAndSaveAlovaJson = (config: Config, projectPath = process.cwd()) => { - const configuration = new Configuration(config, projectPath); - configuration.getAllOutputPath().forEach(outputPath => { - // 缓存文件地址 - const alovaJsonPath = getAlovaJsonPath(projectPath, outputPath); - readAlovaJson(alovaJsonPath) - .then(data => { - // 保存templateData - DEFAULT_CONFIG.templateData.set(alovaJsonPath, data); - }) - .catch(() => {}); + const configTmpFileName = `alova_tmp_${Date.now()}.js`; + const outfile = path.join(projectPath, configTmpFileName); + await esbuild.build({ + entryPoints: [configFile], + bundle: true, + format: 'cjs', + platform: 'node', + outfile, + logLevel: 'silent' }); + + const module = require(outfile); + const config: Config = module.default || module; + await unlink(outfile); + + return config; }; + export const getAutoUpdateConfig = (config: Config) => { const autoUpdateConfig = config.autoUpdate; let time = 60 * 5; // 默认五分钟 diff --git a/packages/wormhole/src/resolveWorkspaces.ts b/packages/wormhole/src/resolveWorkspaces.ts new file mode 100644 index 0000000..58bf1a3 --- /dev/null +++ b/packages/wormhole/src/resolveWorkspaces.ts @@ -0,0 +1,87 @@ +import { glob } from 'glob'; +import yaml from 'js-yaml'; +import nodefs from 'node:fs'; +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { existsPromise, resolveConfigFile } from './utils'; + +/** + * 查找所有包含 alova.config.js 文件的目录 + * @param rootPath 根目录 + * @returns 包含 alova.config.js 文件的目录数组 + */ +export default async function resolveWorkspaces(rootPath = process.cwd()) { + const resultDirs: string[] = []; + + // 检查根目录是否有 alova.config.js + const rootConfigPath = await resolveConfigFile(rootPath); + if (rootConfigPath) { + resultDirs.push(rootPath); + } + + // 根据 package.json 的 workspaces 或 pnpm-workspace.yaml 来查找子包 + const packageJsonPath = path.join(rootPath, 'package.json'); + const pnpmWorkspacePathYaml = path.join(rootPath, 'pnpm-workspace.yaml'); + const pnpmWorkspacePathYml = path.join(rootPath, 'pnpm-workspace.yml'); + + let workspaces: string[] = []; + // 如果存在 package.json,读取 workspaces + if (await existsPromise(packageJsonPath)) { + const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8')); + if (packageJson.workspaces) { + workspaces = Array.isArray(packageJson.workspaces) ? packageJson.workspaces : packageJson.workspaces.packages; + } + } + + // 如果存在 pnpm-workspace.yaml,读取其中的路径 + const pnpmWorkspacePath = (await existsPromise(pnpmWorkspacePathYaml)) + ? pnpmWorkspacePathYaml + : (await existsPromise(pnpmWorkspacePathYml)) + ? pnpmWorkspacePathYml + : undefined; + if (pnpmWorkspacePath) { + const pnpmConfig = yaml.load(await fs.readFile(pnpmWorkspacePath, 'utf-8')) as { packages: string[] }; + if (pnpmConfig.packages) { + workspaces = workspaces.concat(pnpmConfig.packages); + } + } + + // 去重处理 + workspaces = [...new Set(workspaces)]; + + // 遍历每个子包,检查是否存在 alova.config.js + for (const workspace of workspaces) { + const workspaceDirs = await globPaths(rootPath, workspace); + for (const dir of workspaceDirs) { + const configFile = await resolveConfigFile(dir); + if (configFile) { + resultDirs.push(dir); + } + } + } + + return resultDirs; +} + +/** + * 解析 workspace 路径 + * @param {string} rootPath 根目录 + * @param {string} workspacePattern workspace 定义的路径模式 + * @returns {Promise} 解析后的路径列表 + */ +async function globPaths(rootPath: string, workspacePattern: string): Promise { + const resolvedPaths: string[] = []; + const dirs = await glob(workspacePattern, { + ignore: 'node_modules/**', + cwd: rootPath, + fs: { + ...nodefs, + promises: fs + } + }); // 使用 glob 模块处理通配符 + for (const dir of dirs) { + const absDir = path.resolve(rootPath, dir); + resolvedPaths.push(absDir); + } + return resolvedPaths; +} diff --git a/packages/wormhole/src/utils/index.ts b/packages/wormhole/src/utils/index.ts index 6cae549..eb1c448 100644 --- a/packages/wormhole/src/utils/index.ts +++ b/packages/wormhole/src/utils/index.ts @@ -1,6 +1,6 @@ -/* eslint-disable no-bitwise */ +import { createAlova } from 'alova'; +import adapterFetch from 'alova/fetch'; import handlebars, { HelperOptions } from 'handlebars'; -import fetch from 'node-fetch'; import fs from 'node:fs/promises'; import path from 'node:path'; import { Config as PrettierConfig } from 'prettier'; @@ -93,9 +93,7 @@ export async function format(text: string, config?: PrettierConfig) { * @param content 文件内容 */ export async function generateFile(distDir: string, fileName: string, content: string) { - try { - await fs.access(distDir, fs.constants.F_OK); - } catch (error) { + if (!(await existsPromise(distDir))) { await fs.mkdir(distDir, { recursive: true }); } const filePath = path.join(distDir, fileName); @@ -103,12 +101,14 @@ export async function generateFile(distDir: string, fileName: string, content: s await fs.writeFile(filePath, formattedText); } export async function fetchData(url: string) { - return fetch(url).then(response => { - if (!response.ok) { - throw new DEFAULT_CONFIG.Error(`HTTP error! status: ${response.status}`); - } - return response.text(); - }); + return createAlova({ requestAdapter: adapterFetch() }) + .Get(url) + .then(response => { + if (!response.ok) { + throw new DEFAULT_CONFIG.Error(`HTTP error! status: ${response.status}`); + } + return response.text(); + }); } // 去掉所有为空的undefined值 @@ -133,7 +133,23 @@ export function capitalizeFirstLetter(str: string) { if (!str) return str; return str.charAt(0).toUpperCase() + str.slice(1); } -// 加载ESM 模块 -export function loadEsmModule(modulePath: string | URL): Promise { - return new Function('modulePath', `return import(modulePath);`)(modulePath) as Promise; -} + +export const existsPromise = async (path: string, mode?: number) => { + try { + await fs.access(path, mode); + return true; + } catch { + return false; + } +}; + +export const resolveConfigFile = async (projectPath: string) => { + const extensions = ['js', 'cjs', 'mjs', 'ts', 'mts', 'cts']; + for (const ext of extensions) { + const configFile = path.join(projectPath, `alova.config.${ext}`); + if (await existsPromise(configFile)) { + return configFile; + } + } + return null; +}; diff --git a/packages/wormhole/test/__snapshots__/generate.spec.ts.snap b/packages/wormhole/test/__snapshots__/generate.spec.ts.snap index e870b92..6ede04c 100644 --- a/packages/wormhole/test/__snapshots__/generate.spec.ts.snap +++ b/packages/wormhole/test/__snapshots__/generate.spec.ts.snap @@ -1204,7 +1204,7 @@ exports[`generate API > should generate code from an url 5`] = ` /* tslint:disable */ /* eslint-disable */ /** - * Swagger Generator - version 3.0.62 + * Swagger Generator - version 3.0.63 * * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). * @@ -1277,7 +1277,7 @@ exports[`generate API > should generate code from an url 7`] = ` "/* tslint:disable */ /* eslint-disable */ /** - * Swagger Generator - version 3.0.62 + * Swagger Generator - version 3.0.63 * * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). * @@ -1372,7 +1372,7 @@ exports[`generate API > should generate code from an url 8`] = ` "/* tslint:disable */ /* eslint-disable */ /** - * Swagger Generator - version 3.0.62 + * Swagger Generator - version 3.0.63 * * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). * @@ -8994,7 +8994,7 @@ import { createApis, withConfigType } from './createApis'; export const alovaInstance = createAlova({ baseURL: '/api1', requestAdapter: fetchAdapter(), - beforeRequest: method => {}, + beforeRequest: method => { method.config.headers.token = '123' }, responded: res => { return res.json(); } @@ -11830,7 +11830,7 @@ import { createApis, withConfigType } from './createApis'; export const alovaInstance = createAlova({ baseURL: '/api1', requestAdapter: fetchAdapter(), - beforeRequest: method => {}, + beforeRequest: method => { method.config.headers.token = '123' }, responded: res => { return res.json(); } diff --git a/packages/wormhole/test/cli.spec.ts b/packages/wormhole/test/cli.spec.ts new file mode 100644 index 0000000..f4ef9ec --- /dev/null +++ b/packages/wormhole/test/cli.spec.ts @@ -0,0 +1,59 @@ +import { actionGen, actionInit } from '@/bin/actions'; +import { createConfig, generate, readConfig, resolveWorkspaces } from '@/index'; + +const generatingConfig = { + generator: [ + { + input: 'http://localhost:3000/', + output: 'src/api', + type: 'module', + version: 3 + } + ] +}; +vi.mock('@/index', () => ({ + __esModule: true, + createConfig: vi.fn(), + generate: vi.fn().mockImplementation(({ generator }) => Array.from({ length: generator.length }).map(() => true)), + readConfig: vi.fn().mockImplementation(() => generatingConfig), + resolveWorkspaces: vi.fn().mockImplementation(() => ['./packages/test-pkg-1', './packages/test-pkg-2']) +})); + +describe('cli', () => { + test('should get the right `init` cli args', async () => { + await actionInit({ type: 'commonjs' }); + expect(createConfig).toBeCalledWith({ type: 'commonjs' }); + + await actionInit({ path: '/mock_path' }); + expect(createConfig).toBeCalledWith({ projectPath: '/mock_path' }); + }); + + test('should get the right `gen` cli args', async () => { + await actionGen({}); + expect(resolveWorkspaces).toHaveBeenCalledTimes(1); + expect(resolveWorkspaces).toHaveBeenCalledWith(undefined); + expect(readConfig).toHaveBeenCalledTimes(2); + expect(readConfig).toHaveBeenNthCalledWith(1, './packages/test-pkg-1'); + expect(readConfig).toHaveBeenNthCalledWith(2, './packages/test-pkg-2'); + expect(generate).toHaveBeenCalledTimes(2); + expect(generate).toHaveBeenNthCalledWith(1, generatingConfig, { + force: undefined, + projectPath: undefined + }); + expect(generate).toHaveBeenNthCalledWith(2, generatingConfig, { + force: undefined, + projectPath: undefined + }); + + vi.clearAllMocks(); + await actionGen({ workspace: false, path: '/mock_path', force: true }); + expect(resolveWorkspaces).not.toHaveBeenCalled(); + expect(readConfig).toHaveBeenCalledTimes(1); + expect(readConfig).toHaveBeenNthCalledWith(1, undefined); + expect(generate).toHaveBeenCalledTimes(1); + expect(generate).toHaveBeenNthCalledWith(1, generatingConfig, { + force: true, + projectPath: '/mock_path' + }); + }); +}); diff --git a/packages/wormhole/test/config.spec.ts b/packages/wormhole/test/config.spec.ts index 3b6868a..a291781 100644 --- a/packages/wormhole/test/config.spec.ts +++ b/packages/wormhole/test/config.spec.ts @@ -1,10 +1,10 @@ import createConfig from '@/createConfig'; +import type { Config } from '@/interface.type'; import { readConfig } from '@/readConfig'; +import { existsPromise } from '@/utils'; import fs from 'node:fs/promises'; import { resolve } from 'node:path'; -import { fileURLToPath } from 'node:url'; import { rimraf } from 'rimraf'; -import type { Config } from '~/index'; const requireResult = new Map | null | Error>(); vi.mock('import-fresh', () => ({ @@ -21,150 +21,113 @@ vi.mock('import-fresh', () => ({ } })); -const importResult = new Map | null | Error>(); -vi.mock('@/utils', async () => { - const utils = await vi.importActual('@/utils'); - return { - ...utils, - loadEsmModule(path: string) { - path = (/^file:\/\//.test(path) ? fileURLToPath(path) : path).replace(/\?.*$/, ''); - if (!importResult.get(path)) { - return Promise.reject(new Error(`import ${path} not found`)); - } - const result = importResult.get(path); - if (result instanceof Error) { - return Promise.reject(result); - } - return Promise.resolve({ - default: result - }); - } - }; -}); -const configMap: Record< - 'ts' | 'module' | 'commonjs', - { file: string; content: string; expectedConfig: Config; transformContent?: string } -> = { - ts: { - file: 'alova.config.ts', - content: `import type { Config } from '@alova/wormhole'; -export default { -generator: [ +const configMap: Record = { - input: 'http://localhost:3000', - output: 'src/api', - type: 'ts', - version: 3, - handleApi: api =>api - } -] + ts: { + file: 'alova.config.ts', + content: `import type { Config } from '@alova/wormhole'; +import pkg from './package.json'; +export default { + generator: [ + { + input: 'http://localhost:3000/' + pkg.name, + output: 'src/api', + type: 'ts', + version: 3 + } + ] }`, - expectedConfig: { - generator: [ - { - input: 'http://localhost:3000', - output: 'src/api', - type: 'ts', - version: 3, - handleApi: api => api - } - ] - }, - transformContent: `export default { - generator: [ - { - input: 'http://localhost:3000', + expectedConfig: { + generator: [ + { + input: 'http://localhost:3000/@alova/devtools', output: 'src/api', type: 'ts', - version: 3, - handleApi: api => api - } - ] -};` - }, - module: { - file: 'alova.config.js', - content: `export default { -generator: [ - { - input: 'http://localhost:3000', - output: 'src/api', - type: 'module', - version: 3, - handleApi: api => api - } -] -}`, - expectedConfig: { - generator: [ - { - input: 'http://localhost:3000', - output: 'src/api', - type: 'module', - version: 3, - handleApi: api => api - } - ] + version: 3 + } + ] + } + }, + tsWithoutImport: { + file: 'alova.config.ts', + content: `import type { Config } from '@alova/wormhole'; +export default { + generator: [ + { + input: 'http://localhost:3000/', + output: 'src/api', + type: 'ts', + version: 3 } - }, - commonjs: { - file: 'alova.config.js', - content: `module.exports = { -generator: [ - { - input: 'http://localhost:3000', - output: 'src/api', - type: 'commonjs', - version: 3, - handleApi: api => api - } -] + ] }`, - expectedConfig: { - generator: [ - { - input: 'http://localhost:3000', - output: 'src/api', - type: 'commonjs', - version: 3, - handleApi: api => api - } - ] - } - } -}; -vi.mock('node:fs/promises', async () => { - const fs = await vi.importActual('node:fs/promises'); - function writeFile(filePath: string, content: string, options: any) { - const configItem = Object.values(configMap).find(item => item.content === content) ?? configMap.ts; - const pureFilePath = filePath.replace(/\?.*$/, ''); - const isCjs = pureFilePath.endsWith('.cjs') || (pureFilePath.endsWith('.js') && content.includes('module.exports')); - const isMjs = pureFilePath.endsWith('.mjs') || (pureFilePath.endsWith('.js') && content.includes('export default')); - if (isCjs) { - requireResult.set(filePath, configItem.expectedConfig); + expectedConfig: { + generator: [ + { + input: 'http://localhost:3000/', + output: 'src/api', + type: 'ts', + version: 3 + } + ] + } + }, + module: { + file: 'alova.config.js', + content: `import pkg from './package.json'; +export default { + generator: [ + { + input: 'http://localhost:3000/' + pkg.name, + output: 'src/api', + type: 'module', + version: 3 } - if (isMjs) { - importResult.set(filePath, configItem.expectedConfig); + ] +}`, + expectedConfig: { + generator: [ + { + input: 'http://localhost:3000/@alova/devtools', + output: 'src/api', + type: 'module', + version: 3 + } + ] + } + }, + commonjs: { + file: 'alova.config.js', + content: `const pkg = require('./package.json'); +module.exports = { + generator: [ + { + input: 'http://localhost:3000/' + pkg.name, + output: 'src/api', + type: 'commonjs', + version: 3 } - return fs.writeFile(filePath, content, options); - } - return { - ...fs, - writeFile, - default: { - ...(fs as any).default, - writeFile + ] +}`, + expectedConfig: { + generator: [ + { + input: 'http://localhost:3000/@alova/devtools', + output: 'src/api', + type: 'commonjs', + version: 3 + } + ] + } } }; -}); + afterEach(async () => { - requireResult.clear(); - importResult.clear(); await Promise.all([ rimraf(resolve(process.cwd(), 'alova.config.ts')), rimraf(resolve(process.cwd(), 'alova.config.js')), rimraf(resolve(process.cwd(), 'node_modules/.alova')) - ]); + ]).catch(() => {}); }); describe('config', () => { @@ -212,9 +175,18 @@ describe('config', () => { }); expect(initialEsmoduleConfig).toMatch(`@type { import('@alova/wormhole').Config }`); expect(initialEsmoduleConfig).toMatch(`export default {`); + + // generate file with target type + await createConfig({ type: 'typescript' }); + const initialTypedConfig = await fs.readFile(resolve(process.cwd(), 'alova.config.ts'), { + encoding: 'utf-8' + }); + expect(initialTypedConfig).toMatch(`import type { Config } from '@alova/wormhole';`); + expect(initialTypedConfig).toMatch(`export default {`); + expect(initialTypedConfig).toMatch(`input: 'http://localhost:3000',`); }); - test('should create config file under custom path', async () => { + test('should create config file under a custom absolute path', async () => { const customPath = '/mockdir_config'; // 设置package.json 文件 requireResult.set(resolve(customPath, './package.json'), { @@ -224,7 +196,7 @@ describe('config', () => { } }); try { - await createConfig(customPath); + await createConfig({ projectPath: customPath }); const configPath = resolve(customPath, 'alova.config.js'); const initialConfig = await fs.readFile(configPath, { encoding: 'utf-8' @@ -234,18 +206,37 @@ describe('config', () => { await rimraf(resolve(customPath)); // 清除临时目录 } }); + + test('should create config file under a custom relative path', async () => { + const customPath = './mockdir_config'; + // 设置package.json 文件 + requireResult.set(resolve(process.cwd(), customPath, './package.json'), { + type: 'commonjs', + dependencies: { + alova: '3.0.8' + } + }); + try { + await createConfig({ projectPath: customPath }); + const configPath = resolve(process.cwd(), customPath, 'alova.config.js'); + const initialConfig = await fs.readFile(configPath, { + encoding: 'utf-8' + }); + expect(!!initialConfig).toBeTruthy(); + } finally { + await rimraf(resolve(process.cwd(), customPath)); // 清除临时目录 + } + }); + test('should read config file under project root path', async () => { // write mock config file const projectRoot = process.cwd(); - try { - await fs.access(projectRoot); - } catch (error) { + if (!(await existsPromise(projectRoot))) { await fs.mkdir(projectRoot, { recursive: true }); } // read ts file await fs.writeFile(resolve(projectRoot, configMap.ts.file), configMap.ts.content, 'utf-8'); requireResult.set(projectRoot, null); // require()=> throw error - importResult.set(projectRoot, configMap.ts.expectedConfig); // import()=> return config const tsConfig = await readConfig(); expect(tsConfig).toStrictEqual(configMap.ts.expectedConfig); @@ -253,13 +244,11 @@ describe('config', () => { // read module config file await fs.writeFile(resolve(projectRoot, configMap.module.file), configMap.module.content, 'utf-8'); requireResult.set(projectRoot, null); // require()=> throw error - importResult.set(projectRoot, configMap.module.expectedConfig); // import()=> return config const moduleConfig = await readConfig(); - expect(moduleConfig).toStrictEqual(configMap.module.expectedConfig); + expect(moduleConfig).toEqual(configMap.module.expectedConfig); // read commonjs config file await fs.writeFile(resolve(projectRoot, configMap.commonjs.file), configMap.commonjs.content, 'utf-8'); requireResult.set(projectRoot, configMap.commonjs.expectedConfig); // require()=> return config - importResult.set(projectRoot, null); // import()=> throw error const cjsConfig = await readConfig(); expect(cjsConfig).toStrictEqual(configMap.commonjs.expectedConfig); }); @@ -267,17 +256,14 @@ describe('config', () => { test('should read config file under target path', async () => { // read ts file const customPath = resolve(__dirname, './mockdir_config2'); - try { - await fs.access(customPath); - } catch (error) { + if (!(await existsPromise(customPath))) { await fs.mkdir(customPath, { recursive: true }); } - await fs.writeFile(resolve(customPath, configMap.ts.file), configMap.ts.content, 'utf-8'); + await fs.writeFile(resolve(customPath, configMap.tsWithoutImport.file), configMap.tsWithoutImport.content, 'utf-8'); requireResult.set(customPath, null); // require()=> throw error - importResult.set(customPath, configMap.ts.expectedConfig); // import()=> return config try { const tsConfig = await readConfig(customPath); - expect(tsConfig).toMatchObject(configMap.ts.expectedConfig); + expect(tsConfig).toStrictEqual(configMap.tsWithoutImport.expectedConfig); } finally { await rimraf(customPath); // 清除临时目录 } diff --git a/packages/wormhole/test/generate.spec.ts b/packages/wormhole/test/generate.spec.ts index 3193f66..997e6cf 100644 --- a/packages/wormhole/test/generate.spec.ts +++ b/packages/wormhole/test/generate.spec.ts @@ -133,7 +133,7 @@ describe('generate API', () => { test('should generate code with a variant of openapi file formats', async () => { const outputDir = resolve(__dirname, './mock_output/openapi_301'); - await generate({ + const results = await generate({ generator: [ { input: resolve(__dirname, './openapis/openapi_301.json'), @@ -141,6 +141,7 @@ describe('generate API', () => { } ] }); + expect(results).toStrictEqual([true]); expect(await fs.readFile(resolve(outputDir, 'apiDefinitions.ts'), 'utf-8')).toMatchSnapshot(); expect(await fs.readFile(resolve(outputDir, 'index.ts'), 'utf-8')).toMatchSnapshot(); expect(await fs.readFile(resolve(outputDir, 'createApis.ts'), 'utf-8')).toMatchSnapshot(); @@ -175,6 +176,51 @@ describe('generate API', () => { expect(await fs.readFile(resolve(outputDir3, 'globals.d.ts'), 'utf-8')).toMatchSnapshot(); }); + test("shouldn't replace `index` file if it is generated", async () => { + const outputDir = resolve(__dirname, './mock_output/openapi_301'); + const config = { + generator: [ + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir + } + ] + }; + const indexOriginalContent = `beforeRequest: method => {}`; + const indexReplacingContent = `beforeRequest: method => { method.config.headers.token = '123' }`; + const globalsOriginalContent = `type UserMethodConfigMap = typeof $$userConfigMap;`; + const globalsReplacingContent = `type UserMethodConfigMap = number`; + const indexContent = () => fs.readFile(resolve(outputDir, 'index.ts'), 'utf-8'); + const globalsContent = () => fs.readFile(resolve(outputDir, 'globals.d.ts'), 'utf-8'); + + // generate first time + await generate(config); + await expect(indexContent()).resolves.toMatch(indexOriginalContent); + await expect(globalsContent()).resolves.toMatch(globalsOriginalContent); + + // modify generated files + await fs.writeFile( + resolve(outputDir, 'index.ts'), + (await indexContent()).replace(indexOriginalContent, indexReplacingContent) + ); + await fs.writeFile( + resolve(outputDir, 'globals.d.ts'), + (await globalsContent()).replace(globalsOriginalContent, globalsReplacingContent) + ); + // generate again + await generate(config); + // if `force` is false, it will not re-generate when openapi file is not changed + await expect(indexContent()).resolves.toMatch(indexReplacingContent); + await expect(globalsContent()).resolves.toMatch(globalsReplacingContent); + + // force generate even if openapi file is not changed + // but only index.ts will keep modified content + await generate(config, { force: true }); + // if `force` is false, it will not re-generate when openapi file is not changed + await expect(indexContent()).resolves.toMatch(indexReplacingContent); + await expect(globalsContent()).resolves.toMatch(globalsOriginalContent); + }); + test('should generate code from an url', async () => { const outputDir = resolve(__dirname, `./mock_output/swagger_petstore${getSalt()}`); await generate({ @@ -238,7 +284,7 @@ describe('generate API', () => { expect(await fs.readFile(resolve(outputDir2, 'globals.d.ts'), 'utf-8')).toMatchSnapshot(); }); - test('should generate correspoding `mediaType` parameters', async () => { + test('should generate the existing `mediaType` if the target `mediaType` is not matched', async () => { // default mediaType: application/json const outputDir = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); await generate({ @@ -280,6 +326,7 @@ describe('generate API', () => { expect(globalsDeclarationFile).toMatch(`: Alova2Method;`); // custom mediaType: application/xml + // but if there is not `application/xml` in the schema, it will be refer to the first mediaType in the schema, so here will still generate with mediaType `application/json` const outputDir3 = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); await generate({ generator: [ @@ -294,9 +341,34 @@ describe('generate API', () => { globalsDeclarationFile = await fs.readFile(resolve(outputDir3, 'globals.d.ts'), 'utf-8'); expect(globalsDeclarationFile).toMatch(`generateBundle< - Config extends Alova2MethodConfig + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } >`); - expect(globalsDeclarationFile).toMatch(`: Alova2Method;`); + expect(globalsDeclarationFile).toMatch(`: Alova2Method;`); + }); + + test('should generate correspoding `mediaType` parameters if matched target `mediaType`', async () => { + const outputDir = resolve(__dirname, `./mock_output/multiple_media_type${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/multiple_media_type.yaml'), + output: outputDir, + bodyMediaType: 'application/xml', + responseMediaType: 'application/xml' + } + ] + }); + + const globalsDeclarationFile = await fs.readFile(resolve(outputDir, 'globals.d.ts'), 'utf-8'); + expect(globalsDeclarationFile).toMatch(`pet24< + Config extends Alova2MethodConfig & { + data: Category; + } + >( + config: Config + ): Alova2Method;`); }); test('should auto detect generating module codes if not set `type`', async () => { @@ -453,7 +525,7 @@ describe('generate API', () => { const outputDir3 = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); const outputDir4 = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); - await generate({ + const results = await generate({ generator: [ { input: resolve(__dirname, './openapis/openapi_301.json'), @@ -469,6 +541,7 @@ describe('generate API', () => { } ] }); + expect(results).toStrictEqual([true, true]); const fileContentCjs = await fs.readFile(resolve(outputDir3, 'createApis.js'), 'utf-8'); expect(fileContentCjs).toMatch('globalThis.ApisCjs = Apis;'); const fileContentEsm2 = await fs.readFile(resolve(outputDir4, 'createApis.js'), 'utf-8'); diff --git a/packages/wormhole/test/openapis/multiple_media_type.yaml b/packages/wormhole/test/openapis/multiple_media_type.yaml new file mode 100644 index 0000000..5d8b49e --- /dev/null +++ b/packages/wormhole/test/openapis/multiple_media_type.yaml @@ -0,0 +1,160 @@ +openapi: 3.0.0 +info: + description: >- + This is a sample server Petstore server. For this sample, you can use the api key + `special-key` to test the authorization filters. + version: 1.0.0 + title: OpenAPI +tags: + - name: pet + description: Everything about your Pets + - name: store + description: Access to Petstore orders + - name: user + description: Operations about user +paths: + /pet: + post: + tags: + - pet + summary: Add a new pet to the store 2 + description: '' + operationId: pet24 + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Tag' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '405': + description: Invalid input + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + requestBody: + $ref: '#/components/requestBodies/Pet' +externalDocs: + description: Find out more about Swagger + url: 'http://swagger.io' +components: + requestBodies: + Pet: + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Category' + description: Pet object that needs to be added to the store + required: true + securitySchemes: + petstore_auth: + type: oauth2 + flows: + implicit: + authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog' + scopes: + 'write:pets': modify pets in your account + 'read:pets': read your pets + api_key: + type: apiKey + name: api_key + in: header + schemas: + Tag: + title: Pet Tag + description: A tag for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + xml: + name: Tag + Category: + title: Pet category + description: A category for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$' + xml: + name: Category + Pet: + title: a Pet + description: A pet for sale in the pet store + type: object + required: + - name + - photoUrls + properties: + id: + type: integer + format: int64 + category: + $ref: '#/components/schemas/Category' + name: + type: string + example: doggie + photoUrls: + type: array + xml: + name: photoUrl + wrapped: true + items: + type: string + tags: + type: array + xml: + name: tag + wrapped: true + items: + $ref: '#/components/schemas/Tag' + status: + type: string + description: pet status in the store + deprecated: true + enum: + - available + - pending + - sold + xml: + name: Pet + User: + title: a User + description: A User who is purchasing from the pet store + type: object + properties: + id: + type: integer + format: int64 + username: + type: string + firstName: + type: string + lastName: + type: string + email: + type: string + password: + type: string + phone: + type: string + userStatus: + type: integer + format: int32 + description: User Status + xml: + name: User diff --git a/packages/wormhole/test/workspaces.spec.ts b/packages/wormhole/test/workspaces.spec.ts new file mode 100644 index 0000000..9ff33cf --- /dev/null +++ b/packages/wormhole/test/workspaces.spec.ts @@ -0,0 +1,238 @@ +import resolveWorkspaces from '@/resolveWorkspaces'; +import { existsPromise } from '@/utils'; +import fs from 'node:fs/promises'; +import path from 'node:path'; + +vi.mock('node:fs'); +vi.mock('node:fs/promises'); +/** + * 根据给定的文件结构对象创建文件和目录 + * @param {string} rootPath 根路径 + * @param {Record} structure 文件结构对象 + */ +async function createProjectStructure(structure: Record, rootPath = process.cwd()) { + if (!(await existsPromise(rootPath))) { + await fs.mkdir(rootPath, { recursive: true }); + } + // 遍历文件结构 + for (const key in structure) { + const item = structure[key]; + const itemPath = path.join(rootPath, key); + + if (typeof item === 'string') { + // 如果是字符串,创建文件并写入内容 + await fs.writeFile(itemPath, item); + } else if (typeof item === 'object' && item !== null) { + // 如果是对象,创建目录并递归处理其内容 + if (!(await existsPromise(itemPath))) { + await fs.mkdir(itemPath); + } + createProjectStructure(item, itemPath); + } + } + return () => fs.rm(rootPath, { recursive: true, force: true }); +} +afterEach(async () => { + await fs.rm(process.cwd(), { recursive: true, force: true }); +}); + +describe('resolve workspaces', () => { + test("shouldn't resolve any workspace when not found config in projects", async () => { + await createProjectStructure({ + 'package.json': JSON.stringify({ + name: 'test-pkg', + version: '0.0.1' + }), + src: {}, + packages: { + 'test-pkg-1': { + 'package.json': JSON.stringify({ + name: 'test-pkg-1', + version: '0.0.1' + }), + 'alova.config.ts': '' + }, + 'test-pkg-2': { + 'package.json': JSON.stringify({ + name: 'test-pkg-2', + version: '0.0.1' + }), + 'alova.config.js': '' + } + } + }); + await expect(resolveWorkspaces()).resolves.toStrictEqual([]); + }); + test('should resolve a single workspace(root) when project is not monorepo', async () => { + const rootPath = process.cwd(); + await createProjectStructure({ + 'package.json': JSON.stringify({ + name: 'test-pkg', + version: '0.0.1' + }), + 'alova.config.ts': '', + src: {}, + packages: { + 'test-pkg-1': { + 'package.json': JSON.stringify({ + name: 'test-pkg-1', + version: '0.0.1' + }), + 'alova.config.ts': '' + }, + 'test-pkg-2': { + 'package.json': JSON.stringify({ + name: 'test-pkg-2', + version: '0.0.1' + }), + 'alova.config.js': '' + } + } + }); + await expect(resolveWorkspaces()).resolves.toStrictEqual([rootPath]); + }); + test('should resolve multiple workspaces when `workspaces` column in `package.json` is set', async () => { + const rootPath = process.cwd(); + const globMatches = [path.join(rootPath, 'packages/test-pkg-2'), path.join(rootPath, 'packages/test-pkg-1')]; + await createProjectStructure({ + 'package.json': JSON.stringify({ + name: 'test-pkg', + version: '0.0.1', + workspaces: ['packages/*'] + }), + 'alova.config.ts': '', + src: {}, + packages: { + 'test-pkg-1': { + 'package.json': JSON.stringify({ + name: 'test-pkg-1', + version: '0.0.1' + }), + 'alova.config.ts': '' + }, + 'test-pkg-2': { + 'package.json': JSON.stringify({ + name: 'test-pkg-2', + version: '0.0.1' + }), + 'alova.config.js': '' + } + } + }); + + await expect(resolveWorkspaces()).resolves.toStrictEqual([rootPath, ...globMatches]); + }); + + test('should resolve multiple workspaces when `pnpm-workspace.yml` is exist', async () => { + const rootPath = process.cwd(); + const globMatches = [path.join(rootPath, 'packages/test-pkg-2'), path.join(rootPath, 'packages/test-pkg-1')]; + await createProjectStructure({ + 'package.json': JSON.stringify({ + name: 'test-pkg', + version: '0.0.1' + }), + 'pnpm-workspace.yml': ` +packages: + - packages/*`, + 'alova.config.ts': '', + src: {}, + packages: { + 'test-pkg-1': { + 'package.json': JSON.stringify({ + name: 'test-pkg-1', + version: '0.0.1' + }), + 'alova.config.ts': '' + }, + 'test-pkg-2': { + 'package.json': JSON.stringify({ + name: 'test-pkg-2', + version: '0.0.1' + }), + 'alova.config.js': '' + } + } + }); + + await expect(resolveWorkspaces()).resolves.toStrictEqual([rootPath, ...globMatches]); + }); + + test('should concat the workspaces of `package.json` and `pnpm-workspace.yaml`', async () => { + const rootPath = process.cwd(); + await createProjectStructure({ + 'package.json': JSON.stringify({ + name: 'test-pkg', + version: '0.0.1', + workspaces: ['packages/*'] + }), + 'pnpm-workspace.yaml': ` +packages: + - test/*`, + src: {}, + packages: { + 'test-pkg-1': { + 'package.json': JSON.stringify({ + name: 'test-pkg-1', + version: '0.0.1' + }), + 'alova.config.ts': '' + }, + 'test-pkg-2': { + 'package.json': JSON.stringify({ + name: 'test-pkg-2', + version: '0.0.1' + }) + } + }, + test: { + 'test-pkg-3': { + 'package.json': JSON.stringify({ + name: 'test', + version: '0.0.1' + }), + 'alova.config.cjs': '' + } + } + }); + + await expect(resolveWorkspaces()).resolves.toStrictEqual([ + path.join(rootPath, 'packages/test-pkg-1'), + path.join(rootPath, 'test/test-pkg-3') + ]); + }); + + test('should resolve workspaces under custom root path', async () => { + const rootPath = path.resolve(__dirname, './mock_workspace'); + const globMatches = [path.join(rootPath, 'packages/test-pkg-2'), path.join(rootPath, 'packages/test-pkg-1')]; + await createProjectStructure( + { + 'package.json': JSON.stringify({ + name: 'test-pkg', + version: '0.0.1', + workspaces: ['packages/*'] + }), + 'alova.config.ts': '', + src: {}, + packages: { + 'test-pkg-1': { + 'package.json': JSON.stringify({ + name: 'test-pkg-1', + version: '0.0.1' + }), + 'alova.config.ts': '' + }, + 'test-pkg-2': { + 'package.json': JSON.stringify({ + name: 'test-pkg-2', + version: '0.0.1' + }), + 'alova.config.js': '' + } + } + }, + rootPath + ); + + await expect(resolveWorkspaces(rootPath)).resolves.toStrictEqual([rootPath, ...globMatches]); + }); +}); diff --git a/packages/wormhole/tsconfig.build.json b/packages/wormhole/tsconfig.build.json new file mode 100644 index 0000000..fbbc6f0 --- /dev/null +++ b/packages/wormhole/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "types": [] + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/wormhole/tsconfig.json b/packages/wormhole/tsconfig.json index b619d17..e91d6fc 100644 --- a/packages/wormhole/tsconfig.json +++ b/packages/wormhole/tsconfig.json @@ -2,6 +2,8 @@ "extends": "../../tsconfig.base.json", "compilerOptions": { "baseUrl": ".", + "module": "CommonJS", + "resolveJsonModule": false, "paths": { "~/*": ["./typings/*"], "@/*": ["./src/*"], diff --git a/packages/wormhole/typings/index.d.ts b/packages/wormhole/typings/index.d.ts index 94c2a26..1c1dad9 100644 --- a/packages/wormhole/typings/index.d.ts +++ b/packages/wormhole/typings/index.d.ts @@ -1,99 +1,125 @@ -// 查找对应的input属性值 -export type ConfigType = 'auto' | 'ts' | 'typescript' | 'module' | 'commonjs'; -// 模板类型 -export type TemplateType = 'typescript' | 'module' | 'commonjs'; -// 平台类型 -export type PlatformType = 'swagger' | 'knife4j' | 'yapi'; -export namespace OpenAPIV3_1 {} -export type SchemaObject = import('openapi-types').OpenAPIV3_1.SchemaObject; -export type Parameter = import('openapi-types').OpenAPIV3_1.ParameterObject; -export type OperationObject = import('openapi-types').OpenAPIV3_1.OperationObject; -export type ApiDescriptor = Omit & { - url: string; - method: string; - parameters?: Parameter[]; - requestBody?: SchemaObject; - responses?: SchemaObject; -}; -export interface HandleApi { - (apiDescriptor: ApiDescriptor): ApiDescriptor | void | undefined | null; - (apiDescriptor: ApiDescriptor, log: (...args: any[]) => void): ApiDescriptor | void | undefined | null; -} -export type GeneratorConfig = { - // openapi的json文件url地址 - input: string; - // input: 'http://localhost:3000/openapi.json', - // input: 'openapi/api.json' // 以当前项目为相对目录的本地地址 - // input: 'http://192.168.5.123:8080' // 没有指向openapi文件时,必须配合platform参数使用 - - // 支持openapi的平台,目前先支持swagger、knife4j、yapi,默认为空 - // 当指定了此参数后,input字段只需要指定文档的地址而不需要指定到openapi文件,减小使用门槛 - // 不同平台,它的openapi文件地址不一样,根据平台标识去对应地址下读取文件即可。 - platform?: PlatformType; - - // 接口文件和类型文件的输出路径,多个generator不能重复的地址,否则生成的代码会相互覆盖,无意义 - output: string; - - // (具体看下面)指定生成的响应数据的mediaType,指定后以此数据类型来生成200状态码的响应ts格式,默认application/json - responseMediaType?: string; - - // (具体看下面)指定生成的请求体数据的mediaType,指定后以此数据类型来生成请求体的ts格式,默认application/json - bodyMediaType?: string; - - // 生成代码的类型,可选值为auto/ts/typescript/module/commonjs,默认为auto,会通过一定规则判断当前项目的类型 - // ts/typescript:意思相同,表示生成ts类型文件 - // module:生成esModule规范文件 - // commonjs:表示生成commonjs规范文件 - type?: ConfigType; - // 指定alova版本 - version?: number; - // 多项目使用global字段 - global?: string; - // 是否使用import来导入类型,默认false - // 开启此选项后,生成的apiDefinitions.ts文件将使用import语法来导入类型,而不是/// - useImportType?: boolean; - // 没有require时默认为require,只有nullable生效 - defaultRequire?: boolean; - // (具体看下面)过滤或转换生成的api接口函数,返回一个新的apiDescriptor来生成api调用函数 - // 未指定此函数时则不转换apiDescripor对象 - // apiDescriptor的格式与openapi文件的接口对象格式相同 - // 对类型生成也同样适用 - handleApi?: HandleApi; -}; -export type Config = { - // api生成设置,为数组,每项代表一个自动生成的规则,包含生成的输入输出目录、规范文件地址等等 - // 目前只支持openapi规范,包括openapi的2.0和3.0格式,但目前只做3.0规范 - generator: GeneratorConfig[]; - - // 是否自动更新接口,默认开启,每5分钟检查一次,false时关闭 - autoUpdate?: - | boolean - | { - // 编辑器开启时更新,默认false - launchEditor?: boolean; - // 自动更新间隔,单位毫秒 - interval: number; - }; -}; -export type GenerateApiOptions = { - force?: boolean; - projectPath?: string; -}; -// 生成的api描述信息 -export interface Api { - method: string; - summary: string; - path: string; - pathParameters: string; - queryParameters: string; - pathParametersComment?: string; - queryParametersComment?: string; - responseComment?: string; - requestComment?: string; - name: string; - global: string; - responseName: string; - requestName?: string; - defaultValue?: string; - pathKey: string; -} +import { OpenAPIV3_1 } from 'openapi-types'; + +export type ConfigType = 'auto' | 'ts' | 'typescript' | 'module' | 'commonjs'; +export type TemplateType = 'typescript' | 'module' | 'commonjs'; +export type PlatformType = 'swagger' | 'knife4j' | 'yapi'; +export type SchemaObject = OpenAPIV3_1.SchemaObject; +export type Parameter = OpenAPIV3_1.ParameterObject; +export type OperationObject = OpenAPIV3_1.OperationObject; +export type ApiDescriptor = Omit & { + url: string; + method: string; + parameters?: Parameter[]; + requestBody?: SchemaObject; + responses?: SchemaObject; +}; +export interface HandleApi { + (apiDescriptor: ApiDescriptor): ApiDescriptor | void | undefined | null; + (apiDescriptor: ApiDescriptor, log: (...args: any[]) => void): ApiDescriptor | void | undefined | null; +} +export type GeneratorConfig = { + input: string; + platform?: PlatformType; + output: string; + responseMediaType?: string; + bodyMediaType?: string; + type?: ConfigType; + version?: number; + global?: string; + useImportType?: boolean; + defaultRequire?: boolean; + handleApi?: HandleApi; +}; +export type Config = { + generator: GeneratorConfig[]; + autoUpdate?: + | boolean + | { + launchEditor?: boolean; + interval: number; + }; +}; +export type GenerateApiOptions = { + force?: boolean; + projectPath?: string; +}; +/** + * 生成的api描述信息 + */ +export interface Api { + method: string; + summary: string; + path: string; + pathParameters: string; + queryParameters: string; + pathParametersComment?: string; + queryParametersComment?: string; + responseComment?: string; + requestComment?: string; + name: string; + global: string; + responseName: string; + requestName?: string; + defaultValue?: string; + pathKey: string; +} +export type AlovaVersion = `v${number}`; +export type Path = { + key: string; + method: string; + path: string; +}; +export interface PathApis { + tag: string; + apis: Api[]; +} +export interface TemplateData extends Omit { + vue?: boolean; + react?: boolean; + moduleType?: 'commonJs' | 'ESModule'; + defaultKey?: boolean; + baseUrl: string; + pathsArr: Path[]; + schemas?: string[]; + pathApis: PathApis[]; + global: string; + alovaVersion: AlovaVersion; + commentText: string; + useImportType: boolean; + type: TemplateType; +} +declare const DEFAULT_CONFIG: { + alovaTempPath: string; + templatePath: string; + log: (...messageArr: any[]) => void; + getTypescript: () => Promise; + templateData: Map; + Error: ErrorConstructor; +}; +export declare function setGlobalConfig(config: Partial): void; +export interface ConfigCreationOptions { + projectPath?: string; + type?: TemplateType; +} +export declare const createConfig: ({ projectPath, type }?: ConfigCreationOptions) => Promise; +/** + * generate apis based on config + * @param config generating config + * @param rules config rules + * @returns + */ +export declare const generate: (config: Config, rules?: GenerateApiOptions) => Promise; +export declare const readConfig: (projectPath?: string) => Promise; +export declare const getAutoUpdateConfig: (config: Config) => { + time: number; + immediate: boolean; +}; +export declare const getApis: (config: Config, projectPath?: string) => Api[]; +/** + * 查找所有包含 alova.config.js 文件的目录 + * @param rootPath 根目录 + * @returns 包含 alova.config.js 文件的目录数组 + */ +export function resolveWorkspaces(rootPath?: string): Promise; + +export {}; diff --git a/packages/wormhole/typings/vitest.d.ts b/packages/wormhole/typings/vitest.d.ts deleted file mode 100644 index 6aeaa69..0000000 --- a/packages/wormhole/typings/vitest.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { Assertion } from 'vitest'; - -interface CustomMatchers extends Assertion { - toBeDeepEqual(expected: R): void; -} - -declare module 'vitest' { - interface Assertion extends CustomMatchers {} - interface AsymmetricMatchersContaining extends CustomMatchers {} -} diff --git a/path.ts b/path.ts deleted file mode 100644 index 2ba75f0..0000000 --- a/path.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { resolve } from 'node:path'; - -/** - * 项目根目录 - */ -export const projectPath = resolve(__dirname, '.'); - -export default { - projectPath -}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 749d64a..2ba8786 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,155 +7,121 @@ settings: importers: .: - dependencies: - cosmiconfig: - specifier: ^9.0.0 - version: 9.0.0(typescript@5.5.4) - handlebars: - specifier: ^4.7.8 - version: 4.7.8 - import-fresh: - specifier: ^3.3.0 - version: 3.3.0 - lodash: - specifier: ^4.17.21 - version: 4.17.21 - node-fetch: - specifier: ^2.7.0 - version: 2.7.0 - openapi-types: - specifier: ^12.1.3 - version: 12.1.3 - swagger2openapi: - specifier: ^7.0.8 - version: 7.0.8 devDependencies: - '@alova/wormhole': - specifier: workspace:^ - version: link:packages/wormhole '@commitlint/cli': specifier: ^19.3.0 - version: 19.3.0(@types/node@18.19.34)(typescript@5.5.4) + version: 19.5.0(@types/node@18.19.59)(typescript@5.6.3) '@commitlint/config-conventional': specifier: ^19.2.2 - version: 19.2.2 + version: 19.5.0 '@types/js-yaml': specifier: ^4.0.9 version: 4.0.9 '@types/lodash': specifier: ^4.17.5 - version: 4.17.5 - '@types/mocha': - specifier: ^10.0.6 - version: 10.0.6 + version: 4.17.12 '@types/node': - specifier: 18.x - version: 18.19.34 - '@types/node-fetch': - specifier: ^2.6.11 - version: 2.6.11 + specifier: ^18.19.0 + version: 18.19.59 '@types/rimraf': specifier: ^4.0.5 version: 4.0.5 '@types/serialize-javascript': specifier: ^5.0.4 version: 5.0.4 - '@types/swagger2openapi': - specifier: ^7.0.4 - version: 7.0.4 '@typescript-eslint/eslint-plugin': specifier: ^7.13.0 - version: 7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4) + version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3) '@typescript-eslint/parser': specifier: ^7.13.0 - version: 7.13.0(eslint@8.57.0)(typescript@5.5.4) + version: 7.18.0(eslint@8.57.1)(typescript@5.6.3) commitizen: specifier: ^4.3.0 - version: 4.3.0(@types/node@18.19.34)(typescript@5.5.4) + version: 4.3.1(@types/node@18.19.59)(typescript@5.6.3) cz-conventional-changelog: specifier: ^3.3.0 - version: 3.3.0(@types/node@18.19.34)(typescript@5.5.4) + version: 3.3.0(@types/node@18.19.59)(typescript@5.6.3) + dts-bundle-generator: + specifier: ^9.5.1 + version: 9.5.1 eslint: specifier: ^8.57.0 - version: 8.57.0 + version: 8.57.1 eslint-config-airbnb: specifier: ^19.0.4 - version: 19.0.4(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react@7.34.2(eslint@8.57.0))(eslint@8.57.0) + version: 19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.1(eslint@8.57.1))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.1))(eslint-plugin-react@7.37.2(eslint@8.57.1))(eslint@8.57.1) eslint-config-airbnb-typescript: specifier: ^18.0.0 - version: 18.0.0(@typescript-eslint/eslint-plugin@7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4))(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0))(eslint@8.57.0) + version: 18.0.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-prettier: specifier: ^5.1.3 - version: 5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.2) - fast-glob: - specifier: ^3.3.2 - version: 3.3.2 + version: 5.2.1(eslint@8.57.1)(prettier@3.3.3) husky: specifier: ^9.0.11 - version: 9.0.11 + version: 9.1.6 lint-staged: specifier: ^15.2.2 - version: 15.2.7 + version: 15.2.10 npm-run-all: specifier: ^4.1.5 version: 4.1.5 prettier: specifier: ^3.2.5 - version: 3.3.2 + version: 3.3.3 prettier-plugin-organize-imports: specifier: ^3.2.4 - version: 3.2.4(prettier@3.3.2)(typescript@5.5.4) + version: 3.2.4(prettier@3.3.3)(typescript@5.6.3) prettier-plugin-sort-json: specifier: ^4.0.0 - version: 4.0.0(prettier@3.3.2) + version: 4.0.0(prettier@3.3.3) rimraf: specifier: ^6.0.1 version: 6.0.1 tslib: specifier: ^2.7.0 - version: 2.7.0 + version: 2.8.0 tsx: specifier: ^4.15.8 - version: 4.16.2 + version: 4.19.1 type-fest: specifier: ^4.20.0 - version: 4.20.0 + version: 4.26.1 typescript: specifier: ^5.5.4 - version: 5.5.4 + version: 5.6.3 vitest: specifier: ^2.0.5 - version: 2.0.5(@types/node@18.19.34) + version: 2.1.3(@types/node@18.19.59) packages/vscode-extension: devDependencies: '@types/vscode': specifier: ^1.89.0 - version: 1.90.0 + version: 1.94.0 '@vscode/test-cli': specifier: ^0.0.9 version: 0.0.9 '@vscode/test-electron': specifier: ^2.3.9 - version: 2.4.0 + version: 2.4.1 '@vscode/vsce': specifier: ^2.29.0 - version: 2.30.0 - esbuild: - specifier: ^0.23.0 - version: 0.23.0 - esbuild-plugin-alias: - specifier: ^0.2.1 - version: 0.2.1 + version: 2.32.0 packages/wormhole: dependencies: + alova: + specifier: ^3.1.0 + version: 3.1.1 commander: specifier: ^12.1.0 version: 12.1.0 - cosmiconfig: - specifier: ^9.0.0 - version: 9.0.0(typescript@5.5.4) + esbuild: + specifier: ^0.24.0 + version: 0.24.0 + glob: + specifier: ^11.0.0 + version: 11.0.0 handlebars: specifier: ^4.7.8 version: 4.7.8 @@ -168,28 +134,22 @@ importers: lodash: specifier: ^4.17.21 version: 4.17.21 - node-fetch: - specifier: ^2.7.0 - version: 2.7.0 + openapi-types: + specifier: ^12.1.3 + version: 12.1.3 + ora: + specifier: ^8.1.0 + version: 8.1.0 swagger2openapi: specifier: ^7.0.8 version: 7.0.8 devDependencies: - '@types/fs-extra': - specifier: ^11.0.4 - version: 11.0.4 - fs-extra: - specifier: ^11.2.0 - version: 11.2.0 + '@types/swagger2openapi': + specifier: ^7.0.4 + version: 7.0.4 memfs: specifier: ^4.11.1 - version: 4.11.1 - openapi-types: - specifier: ^12.1.3 - version: 12.1.3 - unbuild: - specifier: ^2.0.0 - version: 2.0.0(typescript@5.5.4) + version: 4.14.0 test/api-js-commonjs-test: dependencies: @@ -198,19 +158,19 @@ importers: version: 1.5.2 alova: specifier: ^2.21.3 - version: 2.21.3 + version: 2.21.5 vue: specifier: ^3.4.27 - version: 3.4.31(typescript@5.5.4) + version: 3.5.12(typescript@5.6.3) test/api-js-test: dependencies: alova: specifier: ^2.20.5 - version: 2.21.3 + version: 2.21.5 vue: specifier: ^3.4.27 - version: 3.4.31(typescript@5.5.4) + version: 3.5.12(typescript@5.6.3) test/api-ts-test: dependencies: @@ -219,17 +179,17 @@ importers: version: 1.5.2 alova: specifier: ^2.20.5 - version: 2.21.3 + version: 2.21.5 vue: specifier: ^3.4.27 - version: 3.4.31(typescript@5.4.5) + version: 3.5.12(typescript@5.6.3) devDependencies: openapi: specifier: ^1.0.1 version: 1.0.1 typescript: specifier: ^5.4.5 - version: 5.4.5 + version: 5.6.3 test/api-v3-js-commonjs-test: dependencies: @@ -241,7 +201,7 @@ importers: version: 3.0.0-beta.10 vue: specifier: ^3.4.27 - version: 3.4.31(typescript@5.5.4) + version: 3.5.12(typescript@5.6.3) test/api-v3-js-test: dependencies: @@ -250,7 +210,7 @@ importers: version: 3.0.0-beta.10 vue: specifier: ^3.4.27 - version: 3.4.31(typescript@5.5.4) + version: 3.5.12(typescript@5.6.3) test/api-v3-ts-test: dependencies: @@ -259,14 +219,14 @@ importers: version: 2.0.0-beta.8(alova@3.0.5) '@alova/mock': specifier: ^2.0.4 - version: 2.0.4(alova@3.0.5) + version: 2.0.8(alova@3.0.5) alova: specifier: 3.0.5 version: 3.0.5 devDependencies: typescript: specifier: ^5.4.5 - version: 5.4.5 + version: 5.6.3 packages: @@ -278,285 +238,192 @@ packages: '@alova/mock@1.5.2': resolution: {integrity: sha512-qEkOgTgzbltkTG/3bn1cvekP6AlPuqpv/N3s5dpu15neMGk24p1qnruz+aeNtg4rMU92zNJ+FtGZF4QRd/vxog==} - '@alova/mock@2.0.4': - resolution: {integrity: sha512-mBqzwtt0PUa41W8lAxacqnttfiqccCRldPSqyOzFDGD9n63sBGV3CFcne4oUe9YYwjgrXYqsWVY4FPWqltqLhw==} + '@alova/mock@2.0.8': + resolution: {integrity: sha512-sqN//lQY9S7uK1tolM1EQEF+jYbCqttGObpRfgQvLuL67sJo2FNP/pD3wLFxCKyn/9pceTJCbpnZiuOGLr+XFg==} peerDependencies: - alova: ^3.0.5 + alova: ^3.0.20 '@alova/shared@1.0.0-beta.7': resolution: {integrity: sha512-tnELbw8fsvUUXDwgbIiWLg2oJuRaxwTvf54+f3JnOgCwSLa47dcO7aKvi0FGV26F8enxgTop7CUwP8LlHCtM7Q==} - '@alova/shared@1.0.4': - resolution: {integrity: sha512-Tq47Wd5q76kPmGLXmPijb0AfsXW2aWR9Pid1KO1nz96BdWiKstx2t/ZLTNaGtQzYyB6M+puunaTTJbusJQPmkQ==} - - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - - '@azure/abort-controller@1.1.0': - resolution: {integrity: sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==} - engines: {node: '>=12.0.0'} + '@alova/shared@1.0.7': + resolution: {integrity: sha512-yBCNbt+E2gOtNfx9dLXDcmjudnWrwlHJnMKFD6CLKe6KTc6G0QUFeIS/1Kn4+iBalD38nY8ckCMW98+hmjr7Bg==} '@azure/abort-controller@2.1.2': resolution: {integrity: sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==} engines: {node: '>=18.0.0'} - '@azure/core-auth@1.7.2': - resolution: {integrity: sha512-Igm/S3fDYmnMq1uKS38Ae1/m37B3zigdlZw+kocwEhh5GjyKjPrXKO2J6rzpC1wAxrNil/jX9BJRqBshyjnF3g==} + '@azure/core-auth@1.9.0': + resolution: {integrity: sha512-FPwHpZywuyasDSLMqJ6fhbOK3TqUdviZNF8OqRGA4W5Ewib2lEEZ+pBsYcBa88B2NGO/SEnYPGhyBqNlE8ilSw==} engines: {node: '>=18.0.0'} '@azure/core-client@1.9.2': resolution: {integrity: sha512-kRdry/rav3fUKHl/aDLd/pDLcB+4pOFwPPTVEExuMyaI5r+JBbMWqRbCY1pn5BniDaU3lRxO9eaQ1AmSMehl/w==} engines: {node: '>=18.0.0'} - '@azure/core-rest-pipeline@1.16.2': - resolution: {integrity: sha512-Hnhm/PG9/SQ07JJyLDv3l9Qr8V3xgAe1hFoBYzt6LaalMxfL/ZqFaZf/bz5VN3pMcleCPwl8ivlS2Fjxq/iC8Q==} + '@azure/core-rest-pipeline@1.17.0': + resolution: {integrity: sha512-62Vv8nC+uPId3j86XJ0WI+sBf0jlqTqPUFCBNrGtlaUeQUIXWV/D8GE5A1d+Qx8H7OQojn2WguC8kChD6v0shA==} engines: {node: '>=18.0.0'} - '@azure/core-tracing@1.1.2': - resolution: {integrity: sha512-dawW9ifvWAWmUm9/h+/UQ2jrdvjCJ7VJEuCJ6XVNudzcOwm53BFZH4Q845vjfgoUAM8ZxokvVNxNxAITc502YA==} + '@azure/core-tracing@1.2.0': + resolution: {integrity: sha512-UKTiEJPkWcESPYJz3X5uKRYyOcJD+4nYph+KpfdPRnQJVrZfk0KJgdnaAWKfhsBBtAf/D58Az4AvCJEmWgIBAg==} engines: {node: '>=18.0.0'} - '@azure/core-util@1.9.1': - resolution: {integrity: sha512-OLsq0etbHO1MA7j6FouXFghuHrAFGk+5C1imcpQ2e+0oZhYF07WLA+NW2Vqs70R7d+zOAWiWM3tbE1sXcDN66g==} + '@azure/core-util@1.11.0': + resolution: {integrity: sha512-DxOSLua+NdpWoSqULhjDyAZTXFdP/LKkqtYuxxz1SCN289zk3OG8UOpnCQAz/tygyACBtWp/BoO72ptK7msY8g==} engines: {node: '>=18.0.0'} - '@azure/identity@4.3.0': - resolution: {integrity: sha512-LHZ58/RsIpIWa4hrrE2YuJ/vzG1Jv9f774RfTTAVDZDriubvJ0/S5u4pnw4akJDlS0TiJb6VMphmVUFsWmgodQ==} + '@azure/identity@4.5.0': + resolution: {integrity: sha512-EknvVmtBuSIic47xkOqyNabAme0RYTw52BTMz8eBgU1ysTyMrD1uOoM+JdS0J/4Yfp98IBT3osqq3BfwSaNaGQ==} engines: {node: '>=18.0.0'} - '@azure/logger@1.1.3': - resolution: {integrity: sha512-J8/cIKNQB1Fc9fuYqBVnrppiUtW+5WWJPCj/tAokC5LdSTwkWWttN+jsRgw9BLYD7JDBx7PceiqOBxJJ1tQz3Q==} + '@azure/logger@1.1.4': + resolution: {integrity: sha512-4IXXzcCdLdlXuCG+8UKEwLA1T1NHqUfanhXYHiQTn+6sfWCZXduqbtXDGceg3Ce5QxTGo7EqmbV6Bi+aqKuClQ==} engines: {node: '>=18.0.0'} - '@azure/msal-browser@3.18.0': - resolution: {integrity: sha512-jvK5bDUWbpOaJt2Io/rjcaOVcUzkqkrCme/WntdV1SMUc67AiTcEdKuY6G/nMQ7N5Cfsk9SfpugflQwDku53yg==} + '@azure/msal-browser@3.26.1': + resolution: {integrity: sha512-y78sr9g61aCAH9fcLO1um+oHFXc1/5Ap88RIsUSuzkm0BHzFnN+PXGaQeuM1h5Qf5dTnWNOd6JqkskkMPAhh7Q==} engines: {node: '>=0.8.0'} - '@azure/msal-common@14.13.0': - resolution: {integrity: sha512-b4M/tqRzJ4jGU91BiwCsLTqChveUEyFK3qY2wGfZ0zBswIBZjAxopx5CYt5wzZFKuN15HqRDYXQbztttuIC3nA==} + '@azure/msal-common@14.15.0': + resolution: {integrity: sha512-ImAQHxmpMneJ/4S8BRFhjt1MZ3bppmpRPYYNyzeQPeFN288YKbb8TmmISQEbtfkQ1BPASvYZU5doIZOPBAqENQ==} engines: {node: '>=0.8.0'} - '@azure/msal-node@2.10.0': - resolution: {integrity: sha512-JxsSE0464a8IA/+q5EHKmchwNyUFJHtCH00tSXsLaOddwLjG6yVvTH6lGgPcWMhO7YWUXj/XVgVgeE9kZtsPUQ==} + '@azure/msal-node@2.15.0': + resolution: {integrity: sha512-gVPW8YLz92ZeCibQH2QUw96odJoiM3k/ZPH3f2HxptozmH6+OnyyvKXo/Egg39HAM230akarQKHf0W74UHlh0Q==} engines: {node: '>=16'} - '@babel/code-frame@7.24.7': - resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} - engines: {node: '>=6.9.0'} - - '@babel/compat-data@7.25.4': - resolution: {integrity: sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==} - engines: {node: '>=6.9.0'} - - '@babel/core@7.25.2': - resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==} - engines: {node: '>=6.9.0'} - - '@babel/generator@7.25.6': - resolution: {integrity: sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-compilation-targets@7.25.2': - resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-imports@7.24.7': - resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-transforms@7.25.2': - resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-simple-access@7.24.7': - resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.24.7': - resolution: {integrity: sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.24.8': - resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.24.7': - resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + '@babel/code-frame@7.25.9': + resolution: {integrity: sha512-z88xeGxnzehn2sqZ8UdGQEvYErF1odv2CftxInpSYJt6uHuPe9YjahKZITGs3l5LeI9d2ROG+obuDAoSlqbNfQ==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.24.8': - resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.25.6': - resolution: {integrity: sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==} + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} - '@babel/highlight@7.24.7': - resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} + '@babel/highlight@7.25.9': + resolution: {integrity: sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.24.7': - resolution: {integrity: sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/parser@7.25.6': - resolution: {integrity: sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==} + '@babel/parser@7.25.9': + resolution: {integrity: sha512-aI3jjAAO1fh7vY/pBGsn1i9LDbRP43+asrRlkPuTXW5yHXtd1NgTEMudbBoDDxrf1daEEfPJqR+JBMakzrR4Dg==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/runtime@7.24.7': - resolution: {integrity: sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==} - engines: {node: '>=6.9.0'} - - '@babel/standalone@7.25.6': - resolution: {integrity: sha512-Kf2ZcZVqsKbtYhlA7sP0z5A3q5hmCVYMKMWRWNK/5OVwHIve3JY1djVRmIVAx8FMueLIfZGKQDIILK2w8zO4mg==} - engines: {node: '>=6.9.0'} - - '@babel/template@7.25.0': - resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.25.6': - resolution: {integrity: sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.24.7': - resolution: {integrity: sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.25.6': - resolution: {integrity: sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==} + '@babel/types@7.25.9': + resolution: {integrity: sha512-OwS2CM5KocvQ/k7dFJa8i5bNGJP0hXWfVCfDkqRFP1IreH1JDC7wG6eCYCi0+McbfT8OR/kNqsI0UU0xP9H6PQ==} engines: {node: '>=6.9.0'} '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - '@commitlint/cli@19.3.0': - resolution: {integrity: sha512-LgYWOwuDR7BSTQ9OLZ12m7F/qhNY+NpAyPBgo4YNMkACE7lGuUnuQq1yi9hz1KA4+3VqpOYl8H1rY/LYK43v7g==} + '@commitlint/cli@19.5.0': + resolution: {integrity: sha512-gaGqSliGwB86MDmAAKAtV9SV1SHdmN8pnGq4EJU4+hLisQ7IFfx4jvU4s+pk6tl0+9bv6yT+CaZkufOinkSJIQ==} engines: {node: '>=v18'} hasBin: true - '@commitlint/config-conventional@19.2.2': - resolution: {integrity: sha512-mLXjsxUVLYEGgzbxbxicGPggDuyWNkf25Ht23owXIH+zV2pv1eJuzLK3t1gDY5Gp6pxdE60jZnWUY5cvgL3ufw==} + '@commitlint/config-conventional@19.5.0': + resolution: {integrity: sha512-OBhdtJyHNPryZKg0fFpZNOBM1ZDbntMvqMuSmpfyP86XSfwzGw4CaoYRG4RutUPg0BTK07VMRIkNJT6wi2zthg==} engines: {node: '>=v18'} - '@commitlint/config-validator@19.0.3': - resolution: {integrity: sha512-2D3r4PKjoo59zBc2auodrSCaUnCSALCx54yveOFwwP/i2kfEAQrygwOleFWswLqK0UL/F9r07MFi5ev2ohyM4Q==} + '@commitlint/config-validator@19.5.0': + resolution: {integrity: sha512-CHtj92H5rdhKt17RmgALhfQt95VayrUo2tSqY9g2w+laAXyk7K/Ef6uPm9tn5qSIwSmrLjKaXK9eiNuxmQrDBw==} engines: {node: '>=v18'} - '@commitlint/ensure@19.0.3': - resolution: {integrity: sha512-SZEpa/VvBLoT+EFZVb91YWbmaZ/9rPH3ESrINOl0HD2kMYsjvl0tF7nMHh0EpTcv4+gTtZBAe1y/SS6/OhfZzQ==} + '@commitlint/ensure@19.5.0': + resolution: {integrity: sha512-Kv0pYZeMrdg48bHFEU5KKcccRfKmISSm9MvgIgkpI6m+ohFTB55qZlBW6eYqh/XDfRuIO0x4zSmvBjmOwWTwkg==} engines: {node: '>=v18'} - '@commitlint/execute-rule@19.0.0': - resolution: {integrity: sha512-mtsdpY1qyWgAO/iOK0L6gSGeR7GFcdW7tIjcNFxcWkfLDF5qVbPHKuGATFqRMsxcO8OUKNj0+3WOHB7EHm4Jdw==} + '@commitlint/execute-rule@19.5.0': + resolution: {integrity: sha512-aqyGgytXhl2ejlk+/rfgtwpPexYyri4t8/n4ku6rRJoRhGZpLFMqrZ+YaubeGysCP6oz4mMA34YSTaSOKEeNrg==} engines: {node: '>=v18'} - '@commitlint/format@19.3.0': - resolution: {integrity: sha512-luguk5/aF68HiF4H23ACAfk8qS8AHxl4LLN5oxPc24H+2+JRPsNr1OS3Gaea0CrH7PKhArBMKBz5RX9sA5NtTg==} + '@commitlint/format@19.5.0': + resolution: {integrity: sha512-yNy088miE52stCI3dhG/vvxFo9e4jFkU1Mj3xECfzp/bIS/JUay4491huAlVcffOoMK1cd296q0W92NlER6r3A==} engines: {node: '>=v18'} - '@commitlint/is-ignored@19.2.2': - resolution: {integrity: sha512-eNX54oXMVxncORywF4ZPFtJoBm3Tvp111tg1xf4zWXGfhBPKpfKG6R+G3G4v5CPlRROXpAOpQ3HMhA9n1Tck1g==} + '@commitlint/is-ignored@19.5.0': + resolution: {integrity: sha512-0XQ7Llsf9iL/ANtwyZ6G0NGp5Y3EQ8eDQSxv/SRcfJ0awlBY4tHFAvwWbw66FVUaWICH7iE5en+FD9TQsokZ5w==} engines: {node: '>=v18'} - '@commitlint/lint@19.2.2': - resolution: {integrity: sha512-xrzMmz4JqwGyKQKTpFzlN0dx0TAiT7Ran1fqEBgEmEj+PU98crOFtysJgY+QdeSagx6EDRigQIXJVnfrI0ratA==} + '@commitlint/lint@19.5.0': + resolution: {integrity: sha512-cAAQwJcRtiBxQWO0eprrAbOurtJz8U6MgYqLz+p9kLElirzSCc0vGMcyCaA1O7AqBuxo11l1XsY3FhOFowLAAg==} engines: {node: '>=v18'} - '@commitlint/load@19.2.0': - resolution: {integrity: sha512-XvxxLJTKqZojCxaBQ7u92qQLFMMZc4+p9qrIq/9kJDy8DOrEa7P1yx7Tjdc2u2JxIalqT4KOGraVgCE7eCYJyQ==} + '@commitlint/load@19.5.0': + resolution: {integrity: sha512-INOUhkL/qaKqwcTUvCE8iIUf5XHsEPCLY9looJ/ipzi7jtGhgmtH7OOFiNvwYgH7mA8osUWOUDV8t4E2HAi4xA==} engines: {node: '>=v18'} - '@commitlint/message@19.0.0': - resolution: {integrity: sha512-c9czf6lU+9oF9gVVa2lmKaOARJvt4soRsVmbR7Njwp9FpbBgste5i7l/2l5o8MmbwGh4yE1snfnsy2qyA2r/Fw==} + '@commitlint/message@19.5.0': + resolution: {integrity: sha512-R7AM4YnbxN1Joj1tMfCyBryOC5aNJBdxadTZkuqtWi3Xj0kMdutq16XQwuoGbIzL2Pk62TALV1fZDCv36+JhTQ==} engines: {node: '>=v18'} - '@commitlint/parse@19.0.3': - resolution: {integrity: sha512-Il+tNyOb8VDxN3P6XoBBwWJtKKGzHlitEuXA5BP6ir/3loWlsSqDr5aecl6hZcC/spjq4pHqNh0qPlfeWu38QA==} + '@commitlint/parse@19.5.0': + resolution: {integrity: sha512-cZ/IxfAlfWYhAQV0TwcbdR1Oc0/r0Ik1GEessDJ3Lbuma/MRO8FRQX76eurcXtmhJC//rj52ZSZuXUg0oIX0Fw==} engines: {node: '>=v18'} - '@commitlint/read@19.2.1': - resolution: {integrity: sha512-qETc4+PL0EUv7Q36lJbPG+NJiBOGg7SSC7B5BsPWOmei+Dyif80ErfWQ0qXoW9oCh7GTpTNRoaVhiI8RbhuaNw==} + '@commitlint/read@19.5.0': + resolution: {integrity: sha512-TjS3HLPsLsxFPQj6jou8/CZFAmOP2y+6V4PGYt3ihbQKTY1Jnv0QG28WRKl/d1ha6zLODPZqsxLEov52dhR9BQ==} engines: {node: '>=v18'} - '@commitlint/resolve-extends@19.1.0': - resolution: {integrity: sha512-z2riI+8G3CET5CPgXJPlzftH+RiWYLMYv4C9tSLdLXdr6pBNimSKukYP9MS27ejmscqCTVA4almdLh0ODD2KYg==} + '@commitlint/resolve-extends@19.5.0': + resolution: {integrity: sha512-CU/GscZhCUsJwcKTJS9Ndh3AKGZTNFIOoQB2n8CmFnizE0VnEuJoum+COW+C1lNABEeqk6ssfc1Kkalm4bDklA==} engines: {node: '>=v18'} - '@commitlint/rules@19.0.3': - resolution: {integrity: sha512-TspKb9VB6svklxNCKKwxhELn7qhtY1rFF8ls58DcFd0F97XoG07xugPjjbVnLqmMkRjZDbDIwBKt9bddOfLaPw==} + '@commitlint/rules@19.5.0': + resolution: {integrity: sha512-hDW5TPyf/h1/EufSHEKSp6Hs+YVsDMHazfJ2azIk9tHPXS6UqSz1dIRs1gpqS3eMXgtkT7JH6TW4IShdqOwhAw==} engines: {node: '>=v18'} - '@commitlint/to-lines@19.0.0': - resolution: {integrity: sha512-vkxWo+VQU5wFhiP9Ub9Sre0FYe019JxFikrALVoD5UGa8/t3yOJEpEhxC5xKiENKKhUkTpEItMTRAjHw2SCpZw==} + '@commitlint/to-lines@19.5.0': + resolution: {integrity: sha512-R772oj3NHPkodOSRZ9bBVNq224DOxQtNef5Pl8l2M8ZnkkzQfeSTr4uxawV2Sd3ui05dUVzvLNnzenDBO1KBeQ==} engines: {node: '>=v18'} - '@commitlint/top-level@19.0.0': - resolution: {integrity: sha512-KKjShd6u1aMGNkCkaX4aG1jOGdn7f8ZI8TR1VEuNqUOjWTOdcDSsmglinglJ18JTjuBX5I1PtjrhQCRcixRVFQ==} + '@commitlint/top-level@19.5.0': + resolution: {integrity: sha512-IP1YLmGAk0yWrImPRRc578I3dDUI5A2UBJx9FbSOjxe9sTlzFiwVJ+zeMLgAtHMtGZsC8LUnzmW1qRemkFU4ng==} engines: {node: '>=v18'} - '@commitlint/types@19.0.3': - resolution: {integrity: sha512-tpyc+7i6bPG9mvaBbtKUeghfyZSDgWquIDfMgqYtTbmZ9Y9VzEm2je9EYcQ0aoz5o7NvGS+rcDec93yO08MHYA==} + '@commitlint/types@19.5.0': + resolution: {integrity: sha512-DSHae2obMSMkAtTBSOulg5X7/z+rGLxcXQIkg3OmWvY6wifojge5uVMydfhUvs7yQj+V7jNmRZ2Xzl8GJyqRgg==} engines: {node: '>=v18'} - '@esbuild/aix-ppc64@0.19.12': - resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - '@esbuild/aix-ppc64@0.21.5': resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.23.0': - resolution: {integrity: sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==} + '@esbuild/aix-ppc64@0.23.1': + resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.23.1': - resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} + '@esbuild/aix-ppc64@0.24.0': + resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.19.12': - resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm64@0.21.5': resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} engines: {node: '>=12'} cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.23.0': - resolution: {integrity: sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm64@0.23.1': resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.19.12': - resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} - engines: {node: '>=12'} - cpu: [arm] + '@esbuild/android-arm64@0.24.0': + resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==} + engines: {node: '>=18'} + cpu: [arm64] os: [android] '@esbuild/android-arm@0.21.5': @@ -565,22 +432,16 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.23.0': - resolution: {integrity: sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - '@esbuild/android-arm@0.23.1': resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.19.12': - resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} - engines: {node: '>=12'} - cpu: [x64] + '@esbuild/android-arm@0.24.0': + resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==} + engines: {node: '>=18'} + cpu: [arm] os: [android] '@esbuild/android-x64@0.21.5': @@ -589,46 +450,34 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.23.0': - resolution: {integrity: sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==} + '@esbuild/android-x64@0.23.1': + resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/android-x64@0.23.1': - resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==} + '@esbuild/android-x64@0.24.0': + resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.19.12': - resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-arm64@0.21.5': resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.23.0': - resolution: {integrity: sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-arm64@0.23.1': resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.19.12': - resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} - engines: {node: '>=12'} - cpu: [x64] + '@esbuild/darwin-arm64@0.24.0': + resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==} + engines: {node: '>=18'} + cpu: [arm64] os: [darwin] '@esbuild/darwin-x64@0.21.5': @@ -637,46 +486,34 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.23.0': - resolution: {integrity: sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==} + '@esbuild/darwin-x64@0.23.1': + resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.23.1': - resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==} + '@esbuild/darwin-x64@0.24.0': + resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.19.12': - resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-arm64@0.21.5': resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.23.0': - resolution: {integrity: sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-arm64@0.23.1': resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.19.12': - resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} - engines: {node: '>=12'} - cpu: [x64] + '@esbuild/freebsd-arm64@0.24.0': + resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==} + engines: {node: '>=18'} + cpu: [arm64] os: [freebsd] '@esbuild/freebsd-x64@0.21.5': @@ -685,46 +522,34 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.23.0': - resolution: {integrity: sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==} + '@esbuild/freebsd-x64@0.23.1': + resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.23.1': - resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==} + '@esbuild/freebsd-x64@0.24.0': + resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.19.12': - resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm64@0.21.5': resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} engines: {node: '>=12'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.23.0': - resolution: {integrity: sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm64@0.23.1': resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.19.12': - resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} - engines: {node: '>=12'} - cpu: [arm] + '@esbuild/linux-arm64@0.24.0': + resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==} + engines: {node: '>=18'} + cpu: [arm64] os: [linux] '@esbuild/linux-arm@0.21.5': @@ -733,22 +558,16 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.23.0': - resolution: {integrity: sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - '@esbuild/linux-arm@0.23.1': resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.19.12': - resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} - engines: {node: '>=12'} - cpu: [ia32] + '@esbuild/linux-arm@0.24.0': + resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==} + engines: {node: '>=18'} + cpu: [arm] os: [linux] '@esbuild/linux-ia32@0.21.5': @@ -757,22 +576,16 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.23.0': - resolution: {integrity: sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-ia32@0.23.1': resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.19.12': - resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} - engines: {node: '>=12'} - cpu: [loong64] + '@esbuild/linux-ia32@0.24.0': + resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==} + engines: {node: '>=18'} + cpu: [ia32] os: [linux] '@esbuild/linux-loong64@0.21.5': @@ -781,22 +594,16 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.23.0': - resolution: {integrity: sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-loong64@0.23.1': resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.19.12': - resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} - engines: {node: '>=12'} - cpu: [mips64el] + '@esbuild/linux-loong64@0.24.0': + resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==} + engines: {node: '>=18'} + cpu: [loong64] os: [linux] '@esbuild/linux-mips64el@0.21.5': @@ -805,22 +612,16 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.23.0': - resolution: {integrity: sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-mips64el@0.23.1': resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.19.12': - resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} - engines: {node: '>=12'} - cpu: [ppc64] + '@esbuild/linux-mips64el@0.24.0': + resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==} + engines: {node: '>=18'} + cpu: [mips64el] os: [linux] '@esbuild/linux-ppc64@0.21.5': @@ -829,22 +630,16 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.23.0': - resolution: {integrity: sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-ppc64@0.23.1': resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.19.12': - resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} - engines: {node: '>=12'} - cpu: [riscv64] + '@esbuild/linux-ppc64@0.24.0': + resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==} + engines: {node: '>=18'} + cpu: [ppc64] os: [linux] '@esbuild/linux-riscv64@0.21.5': @@ -853,22 +648,16 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.23.0': - resolution: {integrity: sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-riscv64@0.23.1': resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.19.12': - resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} - engines: {node: '>=12'} - cpu: [s390x] + '@esbuild/linux-riscv64@0.24.0': + resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==} + engines: {node: '>=18'} + cpu: [riscv64] os: [linux] '@esbuild/linux-s390x@0.21.5': @@ -877,22 +666,16 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.23.0': - resolution: {integrity: sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-s390x@0.23.1': resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.19.12': - resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} - engines: {node: '>=12'} - cpu: [x64] + '@esbuild/linux-s390x@0.24.0': + resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==} + engines: {node: '>=18'} + cpu: [s390x] os: [linux] '@esbuild/linux-x64@0.21.5': @@ -901,23 +684,17 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.23.0': - resolution: {integrity: sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - '@esbuild/linux-x64@0.23.1': resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-x64@0.19.12': - resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} - engines: {node: '>=12'} + '@esbuild/linux-x64@0.24.0': + resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==} + engines: {node: '>=18'} cpu: [x64] - os: [netbsd] + os: [linux] '@esbuild/netbsd-x64@0.21.5': resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} @@ -925,23 +702,17 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.23.0': - resolution: {integrity: sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - '@esbuild/netbsd-x64@0.23.1': resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.23.0': - resolution: {integrity: sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==} + '@esbuild/netbsd-x64@0.24.0': + resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==} engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] + cpu: [x64] + os: [netbsd] '@esbuild/openbsd-arm64@0.23.1': resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==} @@ -949,10 +720,10 @@ packages: cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.19.12': - resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} - engines: {node: '>=12'} - cpu: [x64] + '@esbuild/openbsd-arm64@0.24.0': + resolution: {integrity: sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==} + engines: {node: '>=18'} + cpu: [arm64] os: [openbsd] '@esbuild/openbsd-x64@0.21.5': @@ -961,23 +732,17 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.23.0': - resolution: {integrity: sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - '@esbuild/openbsd-x64@0.23.1': resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/sunos-x64@0.19.12': - resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} - engines: {node: '>=12'} + '@esbuild/openbsd-x64@0.24.0': + resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==} + engines: {node: '>=18'} cpu: [x64] - os: [sunos] + os: [openbsd] '@esbuild/sunos-x64@0.21.5': resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} @@ -985,46 +750,34 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.23.0': - resolution: {integrity: sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==} + '@esbuild/sunos-x64@0.23.1': + resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.23.1': - resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==} + '@esbuild/sunos-x64@0.24.0': + resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.19.12': - resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-arm64@0.21.5': resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} engines: {node: '>=12'} cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.23.0': - resolution: {integrity: sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-arm64@0.23.1': resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.19.12': - resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} - engines: {node: '>=12'} - cpu: [ia32] + '@esbuild/win32-arm64@0.24.0': + resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==} + engines: {node: '>=18'} + cpu: [arm64] os: [win32] '@esbuild/win32-ia32@0.21.5': @@ -1033,22 +786,16 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.23.0': - resolution: {integrity: sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-ia32@0.23.1': resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.19.12': - resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} - engines: {node: '>=12'} - cpu: [x64] + '@esbuild/win32-ia32@0.24.0': + resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==} + engines: {node: '>=18'} + cpu: [ia32] os: [win32] '@esbuild/win32-x64@0.21.5': @@ -1057,14 +804,14 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.23.0': - resolution: {integrity: sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==} + '@esbuild/win32-x64@0.23.1': + resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.23.1': - resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==} + '@esbuild/win32-x64@0.24.0': + resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -1075,23 +822,23 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.10.1': - resolution: {integrity: sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==} + '@eslint-community/regexpp@4.11.1': + resolution: {integrity: sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} '@eslint/eslintrc@2.1.4': resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@eslint/js@8.57.0': - resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} + '@eslint/js@8.57.1': + resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} '@exodus/schemasafe@1.3.0': resolution: {integrity: sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==} - '@humanwhocodes/config-array@0.11.14': - resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} + '@humanwhocodes/config-array@0.13.0': + resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} engines: {node: '>=10.10.0'} deprecated: Use @eslint/config-array instead @@ -1115,20 +862,12 @@ packages: resolution: {integrity: sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==} engines: {node: '>= 10.14.2'} - '@jridgewell/gen-mapping@0.3.5': - resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} - engines: {node: '>=6.0.0'} - '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.4.15': - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} @@ -1145,8 +884,8 @@ packages: peerDependencies: tslib: '2' - '@jsonjoy.com/util@1.3.0': - resolution: {integrity: sha512-Cebt4Vk7k1xHy87kHY7KSPLT77A7Ev7IfOblyLZhtYEhrdQ6fX4EoLq3xOQ3O/DRMEh2ok5nyC180E+ABS8Wmw==} + '@jsonjoy.com/util@1.5.0': + resolution: {integrity: sha512-ojoNsrIuPI9g6o8UxhraZQSyF2ByJanAY4cTFbc8Mf2AXEF4aQRGY1dJxyJpuyav8r9FGflEt/Ff3u5Nt6YMPA==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' @@ -1171,161 +910,103 @@ packages: resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@rollup/plugin-alias@5.1.0': - resolution: {integrity: sha512-lpA3RZ9PdIG7qqhEfv79tBffNaoDuukFDrmhLqg9ifv99u/ehn+lOg30x2zmhf8AQqQUZaMk/B9fZraQ6/acDQ==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/plugin-commonjs@25.0.8': - resolution: {integrity: sha512-ZEZWTK5n6Qde0to4vS9Mr5x/0UZoqCxPVR9KRUjU4kA2sO7GEUn1fop0DAwpO6z0Nw/kJON9bDmSxdWxO/TT1A==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^2.68.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/plugin-json@6.1.0': - resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/plugin-node-resolve@15.2.3': - resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^2.78.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/plugin-replace@5.0.7': - resolution: {integrity: sha512-PqxSfuorkHz/SPpyngLyg5GCEkOcee9M1bkxiVDr41Pd61mqP1PLOoDPbpl44SB2mQGKwV/In74gqQmGITOhEQ==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/pluginutils@5.1.0': - resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/rollup-android-arm-eabi@4.21.2': - resolution: {integrity: sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==} + '@rollup/rollup-android-arm-eabi@4.24.0': + resolution: {integrity: sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.21.2': - resolution: {integrity: sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==} + '@rollup/rollup-android-arm64@4.24.0': + resolution: {integrity: sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.21.2': - resolution: {integrity: sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==} + '@rollup/rollup-darwin-arm64@4.24.0': + resolution: {integrity: sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.21.2': - resolution: {integrity: sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==} + '@rollup/rollup-darwin-x64@4.24.0': + resolution: {integrity: sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-linux-arm-gnueabihf@4.21.2': - resolution: {integrity: sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==} + '@rollup/rollup-linux-arm-gnueabihf@4.24.0': + resolution: {integrity: sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==} cpu: [arm] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.21.2': - resolution: {integrity: sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==} + '@rollup/rollup-linux-arm-musleabihf@4.24.0': + resolution: {integrity: sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==} cpu: [arm] os: [linux] libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.21.2': - resolution: {integrity: sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==} + '@rollup/rollup-linux-arm64-gnu@4.24.0': + resolution: {integrity: sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==} cpu: [arm64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.21.2': - resolution: {integrity: sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==} + '@rollup/rollup-linux-arm64-musl@4.24.0': + resolution: {integrity: sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==} cpu: [arm64] os: [linux] libc: [musl] - '@rollup/rollup-linux-powerpc64le-gnu@4.21.2': - resolution: {integrity: sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==} + '@rollup/rollup-linux-powerpc64le-gnu@4.24.0': + resolution: {integrity: sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==} cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-gnu@4.21.2': - resolution: {integrity: sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==} + '@rollup/rollup-linux-riscv64-gnu@4.24.0': + resolution: {integrity: sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==} cpu: [riscv64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-s390x-gnu@4.21.2': - resolution: {integrity: sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==} + '@rollup/rollup-linux-s390x-gnu@4.24.0': + resolution: {integrity: sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==} cpu: [s390x] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.21.2': - resolution: {integrity: sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==} + '@rollup/rollup-linux-x64-gnu@4.24.0': + resolution: {integrity: sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==} cpu: [x64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.21.2': - resolution: {integrity: sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==} + '@rollup/rollup-linux-x64-musl@4.24.0': + resolution: {integrity: sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==} cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-win32-arm64-msvc@4.21.2': - resolution: {integrity: sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==} + '@rollup/rollup-win32-arm64-msvc@4.24.0': + resolution: {integrity: sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.21.2': - resolution: {integrity: sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==} + '@rollup/rollup-win32-ia32-msvc@4.24.0': + resolution: {integrity: sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.21.2': - resolution: {integrity: sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==} + '@rollup/rollup-win32-x64-msvc@4.24.0': + resolution: {integrity: sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==} cpu: [x64] os: [win32] - '@trysound/sax@0.2.0': - resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} - engines: {node: '>=10.13.0'} + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} '@types/conventional-commits-parser@5.0.0': resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==} - '@types/estree@1.0.5': - resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - - '@types/fs-extra@11.0.4': - resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} '@types/istanbul-lib-coverage@2.0.6': resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} @@ -1345,27 +1026,18 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - '@types/jsonfile@6.1.4': - resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} - - '@types/lodash@4.17.5': - resolution: {integrity: sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw==} - - '@types/mocha@10.0.6': - resolution: {integrity: sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==} + '@types/lodash@4.17.12': + resolution: {integrity: sha512-sviUmCE8AYdaF/KIHLDJBQgeYzPBI0vf/17NaYehBJfYD1j6/L95Slh07NlyK2iNyBNaEkb3En2jRt+a8y3xZQ==} - '@types/node-fetch@2.6.11': - resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==} + '@types/mocha@10.0.9': + resolution: {integrity: sha512-sicdRoWtYevwxjOHNMPTl3vSfJM6oyW8o1wXeI7uww6b6xHg8eBznQDNSGBCDJmsE8UMxP05JgZRtsKbTqt//Q==} - '@types/node@18.19.34': - resolution: {integrity: sha512-eXF4pfBNV5DAMKGbI02NnDtWrQ40hAN558/2vvS4gMpMIxaf6JmD7YjnZbq0Q9TDSSkKBamime8ewRoomHdt4g==} + '@types/node@18.19.59': + resolution: {integrity: sha512-vizm2EqwV/7Zay+A6J3tGl9Lhr7CjZe2HmWS988sefiEmsyP9CeXEleho6i4hJk/8UtZAo0bWN4QPZZr83RxvQ==} '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} - '@types/resolve@1.20.2': - resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} - '@types/rimraf@4.0.5': resolution: {integrity: sha512-DTCZoIQotB2SUJnYgrEx43cQIUYOlNZz0AZPbKU4PSLYTUdML5Gox0++z4F9kQocxStrCmRNhi4x5x/UlwtKUA==} deprecated: This is a stub types definition. rimraf provides its own type definitions, so you do not need this installed. @@ -1376,8 +1048,8 @@ packages: '@types/swagger2openapi@7.0.4': resolution: {integrity: sha512-ffMqzciTDihOKH4Q//9Ond1yb5JP1P5FC/aFPsLK4blea1Fwk2aYctiNCkAh5etDYFswFXS+5LV/vuGkf+PU6A==} - '@types/vscode@1.90.0': - resolution: {integrity: sha512-oT+ZJL7qHS9Z8bs0+WKf/kQ27qWYR3trsXpq46YDjFqBsMLG4ygGGjPaJ2tyrH0wJzjOEmDyg9PDJBBhWg9pkQ==} + '@types/vscode@1.94.0': + resolution: {integrity: sha512-UyQOIUT0pb14XSqJskYnRwD2aG0QrPVefIfrW1djR+/J4KeFQ0i1+hjZoaAmeNf3Z2jleK+R2hv+EboG/m8ruw==} '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} @@ -1385,8 +1057,8 @@ packages: '@types/yargs@15.0.19': resolution: {integrity: sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA==} - '@typescript-eslint/eslint-plugin@7.13.0': - resolution: {integrity: sha512-FX1X6AF0w8MdVFLSdqwqN/me2hyhuQg4ykN6ZpVhh1ij/80pTvDKclX1sZB9iqex8SjQfVhwMKs3JtnnMLzG9w==} + '@typescript-eslint/eslint-plugin@7.18.0': + resolution: {integrity: sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: '@typescript-eslint/parser': ^7.0.0 @@ -1396,8 +1068,8 @@ packages: typescript: optional: true - '@typescript-eslint/parser@7.13.0': - resolution: {integrity: sha512-EjMfl69KOS9awXXe83iRN7oIEXy9yYdqWfqdrFAYAAr6syP8eLEFI7ZE4939antx2mNgPRW/o1ybm2SFYkbTVA==} + '@typescript-eslint/parser@7.18.0': + resolution: {integrity: sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -1406,12 +1078,12 @@ packages: typescript: optional: true - '@typescript-eslint/scope-manager@7.13.0': - resolution: {integrity: sha512-ZrMCe1R6a01T94ilV13egvcnvVJ1pxShkE0+NDjDzH4nvG1wXpwsVI5bZCvE7AEDH1mXEx5tJSVR68bLgG7Dng==} + '@typescript-eslint/scope-manager@7.18.0': + resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/type-utils@7.13.0': - resolution: {integrity: sha512-xMEtMzxq9eRkZy48XuxlBFzpVMDurUAfDu5Rz16GouAtXm0TaAoTFzqWUFPPuQYXI/CDaH/Bgx/fk/84t/Bc9A==} + '@typescript-eslint/type-utils@7.18.0': + resolution: {integrity: sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -1420,12 +1092,12 @@ packages: typescript: optional: true - '@typescript-eslint/types@7.13.0': - resolution: {integrity: sha512-QWuwm9wcGMAuTsxP+qz6LBBd3Uq8I5Nv8xb0mk54jmNoCyDspnMvVsOxI6IsMmway5d1S9Su2+sCKv1st2l6eA==} + '@typescript-eslint/types@7.18.0': + resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/typescript-estree@7.13.0': - resolution: {integrity: sha512-cAvBvUoobaoIcoqox1YatXOnSl3gx92rCZoMRPzMNisDiM12siGilSM4+dJAekuuHTibI2hVC2fYK79iSFvWjw==} + '@typescript-eslint/typescript-estree@7.18.0': + resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: typescript: '*' @@ -1433,44 +1105,56 @@ packages: typescript: optional: true - '@typescript-eslint/utils@7.13.0': - resolution: {integrity: sha512-jceD8RgdKORVnB4Y6BqasfIkFhl4pajB1wVxrF4akxD2QPM8GNYjgGwEzYS+437ewlqqrg7Dw+6dhdpjMpeBFQ==} + '@typescript-eslint/utils@7.18.0': + resolution: {integrity: sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 - '@typescript-eslint/visitor-keys@7.13.0': - resolution: {integrity: sha512-nxn+dozQx+MK61nn/JP+M4eCkHDSxSLDpgE3WcQo0+fkjEolnaB5jswvIKC4K56By8MMgIho7f1PVxERHEo8rw==} + '@typescript-eslint/visitor-keys@7.18.0': + resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==} engines: {node: ^18.18.0 || >=20.0.0} '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} - '@vitest/expect@2.0.5': - resolution: {integrity: sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==} + '@vitest/expect@2.1.3': + resolution: {integrity: sha512-SNBoPubeCJhZ48agjXruCI57DvxcsivVDdWz+SSsmjTT4QN/DfHk3zB/xKsJqMs26bLZ/pNRLnCf0j679i0uWQ==} + + '@vitest/mocker@2.1.3': + resolution: {integrity: sha512-eSpdY/eJDuOvuTA3ASzCjdithHa+GIF1L4PqtEELl6Qa3XafdMLBpBlZCIUCX2J+Q6sNmjmxtosAG62fK4BlqQ==} + peerDependencies: + '@vitest/spy': 2.1.3 + msw: ^2.3.5 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true - '@vitest/pretty-format@2.0.5': - resolution: {integrity: sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==} + '@vitest/pretty-format@2.1.3': + resolution: {integrity: sha512-XH1XdtoLZCpqV59KRbPrIhFCOO0hErxrQCMcvnQete3Vibb9UeIOX02uFPfVn3Z9ZXsq78etlfyhnkmIZSzIwQ==} - '@vitest/runner@2.0.5': - resolution: {integrity: sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==} + '@vitest/runner@2.1.3': + resolution: {integrity: sha512-JGzpWqmFJ4fq5ZKHtVO3Xuy1iF2rHGV4d/pdzgkYHm1+gOzNZtqjvyiaDGJytRyMU54qkxpNzCx+PErzJ1/JqQ==} - '@vitest/snapshot@2.0.5': - resolution: {integrity: sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==} + '@vitest/snapshot@2.1.3': + resolution: {integrity: sha512-qWC2mWc7VAXmjAkEKxrScWHWFyCQx/cmiZtuGqMi+WwqQJ2iURsVY4ZfAK6dVo6K2smKRU6l3BPwqEBvhnpQGg==} - '@vitest/spy@2.0.5': - resolution: {integrity: sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==} + '@vitest/spy@2.1.3': + resolution: {integrity: sha512-Nb2UzbcUswzeSP7JksMDaqsI43Sj5+Kry6ry6jQJT4b5gAK+NS9NED6mDb8FlMRCX8m5guaHCDZmqYMMWRy5nQ==} - '@vitest/utils@2.0.5': - resolution: {integrity: sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==} + '@vitest/utils@2.1.3': + resolution: {integrity: sha512-xpiVfDSg1RrYT0tX6czgerkpcKFmFOF/gCr30+Mve5V2kewCy4Prn1/NDMSRwaSmT7PRaOF83wu+bEtsY1wrvA==} '@vscode/test-cli@0.0.9': resolution: {integrity: sha512-vsl5/ueE3Jf0f6XzB0ECHHMsd5A0Yu6StElb8a+XsubZW7kHNAOw4Y3TSSuDzKEpLnJ92nbMy1Zl+KLGCE6NaA==} engines: {node: '>=18'} hasBin: true - '@vscode/test-electron@2.4.0': - resolution: {integrity: sha512-yojuDFEjohx6Jb+x949JRNtSn6Wk2FAh4MldLE3ck9cfvCqzwxF32QsNy1T9Oe4oT+ZfFcg0uPUCajJzOmPlTA==} + '@vscode/test-electron@2.4.1': + resolution: {integrity: sha512-Gc6EdaLANdktQ1t+zozoBVRynfIsMKMc94Svu1QreOBC8y76x4tvaK32TljrLi1LI2+PK58sDVbL7ALdqf3VRQ==} engines: {node: '>=16'} '@vscode/vsce-sign-alpine-arm64@2.0.2': @@ -1521,39 +1205,39 @@ packages: '@vscode/vsce-sign@2.0.4': resolution: {integrity: sha512-0uL32egStKYfy60IqnynAChMTbL0oqpqk0Ew0YHiIb+fayuGZWADuIPHWUcY1GCnAA+VgchOPDMxnc2R3XGWEA==} - '@vscode/vsce@2.30.0': - resolution: {integrity: sha512-MBYpXdCY1SCdc2u/y11kmJuSODKFyZRpeRTQq5p4rSg05QSjSy5pz6h/BGLNdSahgXfKRBATEkjAcJFdJuDz8Q==} + '@vscode/vsce@2.32.0': + resolution: {integrity: sha512-3EFJfsgrSftIqt3EtdRcAygy/OJ3hstyI1cDmIgkU9CFZW5C+3djr6mfosndCUqcVYuyjmxOK1xmFp/Bq7+NIg==} engines: {node: '>= 16'} hasBin: true - '@vue/compiler-core@3.4.31': - resolution: {integrity: sha512-skOiodXWTV3DxfDhB4rOf3OGalpITLlgCeOwb+Y9GJpfQ8ErigdBUHomBzvG78JoVE8MJoQsb+qhZiHfKeNeEg==} + '@vue/compiler-core@3.5.12': + resolution: {integrity: sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw==} - '@vue/compiler-dom@3.4.31': - resolution: {integrity: sha512-wK424WMXsG1IGMyDGyLqB+TbmEBFM78hIsOJ9QwUVLGrcSk0ak6zYty7Pj8ftm7nEtdU/DGQxAXp0/lM/2cEpQ==} + '@vue/compiler-dom@3.5.12': + resolution: {integrity: sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg==} - '@vue/compiler-sfc@3.4.31': - resolution: {integrity: sha512-einJxqEw8IIJxzmnxmJBuK2usI+lJonl53foq+9etB2HAzlPjAS/wa7r0uUpXw5ByX3/0uswVSrjNb17vJm1kQ==} + '@vue/compiler-sfc@3.5.12': + resolution: {integrity: sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw==} - '@vue/compiler-ssr@3.4.31': - resolution: {integrity: sha512-RtefmITAje3fJ8FSg1gwgDhdKhZVntIVbwupdyZDSifZTRMiWxWehAOTCc8/KZDnBOcYQ4/9VWxsTbd3wT0hAA==} + '@vue/compiler-ssr@3.5.12': + resolution: {integrity: sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA==} - '@vue/reactivity@3.4.31': - resolution: {integrity: sha512-VGkTani8SOoVkZNds1PfJ/T1SlAIOf8E58PGAhIOUDYPC4GAmFA2u/E14TDAFcf3vVDKunc4QqCe/SHr8xC65Q==} + '@vue/reactivity@3.5.12': + resolution: {integrity: sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg==} - '@vue/runtime-core@3.4.31': - resolution: {integrity: sha512-LDkztxeUPazxG/p8c5JDDKPfkCDBkkiNLVNf7XZIUnJ+66GVGkP+TIh34+8LtPisZ+HMWl2zqhIw0xN5MwU1cw==} + '@vue/runtime-core@3.5.12': + resolution: {integrity: sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw==} - '@vue/runtime-dom@3.4.31': - resolution: {integrity: sha512-2Auws3mB7+lHhTFCg8E9ZWopA6Q6L455EcU7bzcQ4x6Dn4cCPuqj6S2oBZgN2a8vJRS/LSYYxwFFq2Hlx3Fsaw==} + '@vue/runtime-dom@3.5.12': + resolution: {integrity: sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA==} - '@vue/server-renderer@3.4.31': - resolution: {integrity: sha512-D5BLbdvrlR9PE3by9GaUp1gQXlCNadIZytMIb8H2h3FMWJd4oUfkUTEH2wAr3qxoRz25uxbTcbqd3WKlm9EHQA==} + '@vue/server-renderer@3.5.12': + resolution: {integrity: sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg==} peerDependencies: - vue: 3.4.31 + vue: 3.5.12 - '@vue/shared@3.4.31': - resolution: {integrity: sha512-Yp3wtJk//8cO4NItOPpi3QkLExAr/aLBGZMmTtW9WpdwBCJpRM6zj9WgWktXAl8IDIozwNMByT45JP3tO3ACWA==} + '@vue/shared@3.5.12': + resolution: {integrity: sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg==} JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} @@ -1564,8 +1248,8 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn@8.11.3: - resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + acorn@8.13.0: + resolution: {integrity: sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==} engines: {node: '>=0.4.0'} hasBin: true @@ -1576,11 +1260,11 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - ajv@8.16.0: - resolution: {integrity: sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==} + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} - alova@2.21.3: - resolution: {integrity: sha512-JJ62QB0yQUnZ2hGbXUQzhWRt6h9DLvt8q77Q1M/gnc//oTX2xSBxdw29c6FLs13KhmjCG6pb8OjoiJq6dkUO4w==} + alova@2.21.5: + resolution: {integrity: sha512-7CqSpxvjMCCMznXkzum/drugXxPpD+C0peYbFT3LqUkxyQ0RDdhcboDUbnfrUResi0Y8Cla7f3R1KFw0ywivow==} engines: {node: '>= 0.12.0'} alova@3.0.0-beta.10: @@ -1591,24 +1275,28 @@ packages: resolution: {integrity: sha512-cOE2nTPOp7sXLhf9cthdh90lT389C1akgJULMytuFeV1loriJr1YbT3LCw3qb/P3N+o/QtJ9WLH2ccr0vJ380A==} engines: {node: '>= 18.0.0'} - ansi-colors@4.1.1: - resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} + alova@3.1.1: + resolution: {integrity: sha512-1LviUBEa6tNg4hVnnY0wtY7OGdzwl4uzASCTbMxXyiVkraJg3mt/e/5i0xGR6CeOkAS2hpmxDKsrE3rJEUnAKA==} + engines: {node: '>= 18.0.0'} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} - ansi-escapes@6.2.1: - resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==} - engines: {node: '>=14.16'} + ansi-escapes@7.0.0: + resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==} + engines: {node: '>=18'} ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} engines: {node: '>=12'} ansi-styles@3.2.1: @@ -1633,8 +1321,9 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - aria-query@5.3.0: - resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} array-buffer-byte-length@1.0.1: resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} @@ -1667,9 +1356,6 @@ packages: resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} engines: {node: '>= 0.4'} - array.prototype.toreversed@1.1.2: - resolution: {integrity: sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==} - array.prototype.tosorted@1.1.4: resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} engines: {node: '>= 0.4'} @@ -1692,23 +1378,17 @@ packages: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} - autoprefixer@10.4.20: - resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} - engines: {node: ^10 || ^12 || >=14} - hasBin: true - peerDependencies: - postcss: ^8.1.0 - available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axe-core@4.7.0: - resolution: {integrity: sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==} + axe-core@4.10.2: + resolution: {integrity: sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==} engines: {node: '>=4'} - axobject-query@3.2.1: - resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==} + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} azure-devops-node-api@12.5.0: resolution: {integrity: sha512-R5eFskGvOm3U/GzeAuxRkUsAl0hrAwGgWn6zAd2KrZmrEhWZVqLew4OOupbQlXUuojUzpGtq62SmdhJ06N88og==} @@ -1745,11 +1425,6 @@ packages: browser-stdout@1.3.1: resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} - browserslist@4.23.3: - resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} @@ -1762,10 +1437,6 @@ packages: buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - builtin-modules@3.3.0: - resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} - engines: {node: '>=6'} - c8@9.1.0: resolution: {integrity: sha512-mBWcT5iqNir1zIkzSPyI3NCR9EZCVI3WUD+AVO17MVWTSFNyUueXE82qTeampNtTr+ilN/5Ua3j24LgbCKjDVg==} engines: {node: '>=14.14.0'} @@ -1797,17 +1468,11 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-api@3.0.0: - resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} - - caniuse-lite@1.0.30001658: - resolution: {integrity: sha512-N2YVqWbJELVdrnsW5p+apoQyYt51aBMSsBZki1XZEfeBCexcM/sf4xiAHcXQBkuOwJBXtWF7aW1sYX6tKebPHw==} - capital-case@1.0.4: resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} - chai@5.1.1: - resolution: {integrity: sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==} + chai@5.1.2: + resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} engines: {node: '>=12'} chalk@2.4.2: @@ -1835,13 +1500,9 @@ packages: cheerio-select@2.1.0: resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} - cheerio@1.0.0-rc.12: - resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} - engines: {node: '>= 6'} - - chokidar@3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} - engines: {node: '>= 8.10.0'} + cheerio@1.0.0: + resolution: {integrity: sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==} + engines: {node: '>=18.17'} chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} @@ -1850,9 +1511,6 @@ packages: chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} - citty@0.1.6: - resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} - cli-cursor@3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -1861,6 +1519,10 @@ packages: resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + cli-cursor@5.0.0: + resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} + engines: {node: '>=18'} + cli-spinners@2.9.2: resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} engines: {node: '>=6'} @@ -1884,8 +1546,8 @@ packages: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} - cockatiel@3.1.3: - resolution: {integrity: sha512-xC759TpZ69d7HhfDp8m2WkRwEUiCkxY8Ee2OQH/3H6zmy2D/5Sm+zSTbPRa+V2QyjDtpMvjOIAOVjA2gp6N1kQ==} + cockatiel@3.2.1: + resolution: {integrity: sha512-gfrHV6ZPkquExvMh9IOkKsBzNDk6sDuZ6DdBGUBkvFnTCqCxzpuq48RySgP0AnaqQkw2zynOFj9yly6T1Q2G5Q==} engines: {node: '>=16'} color-convert@1.9.3: @@ -1901,9 +1563,6 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - colord@2.9.3: - resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} - colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} @@ -1919,34 +1578,20 @@ packages: resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} engines: {node: '>= 6'} - commander@7.2.0: - resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} - engines: {node: '>= 10'} - - commitizen@4.3.0: - resolution: {integrity: sha512-H0iNtClNEhT0fotHvGV3E9tDejDeS04sN1veIebsKYGMuGscFaswRoYJKmT3eW85eIJAs0F28bG2+a/9wCOfPw==} + commitizen@4.3.1: + resolution: {integrity: sha512-gwAPAVTy/j5YcOOebcCRIijn+mSjWJC+IYKivTu6aG8Ei/scoXgfsMRnuAk6b0GRste2J4NGxVdMN3ZpfNaVaw==} engines: {node: '>= 12'} hasBin: true - commondir@1.0.1: - resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - compare-func@2.0.0: resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - confbox@0.1.7: - resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} - confusing-browser-globals@1.0.11: resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} - consola@3.2.3: - resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} - engines: {node: ^14.18.0 || >=16.10.0} - constant-case@3.0.4: resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==} @@ -1972,8 +1617,8 @@ packages: core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - cosmiconfig-typescript-loader@5.0.0: - resolution: {integrity: sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==} + cosmiconfig-typescript-loader@5.1.0: + resolution: {integrity: sha512-7PtBB+6FdsOvZyJtlF3hEPpACq7RQX6BVGsgC7/lfVXnKMvNCu/XY3ykreqG5w/rBNdu2z8LCIKoF3kpHHdHlA==} engines: {node: '>=v16'} peerDependencies: '@types/node': '*' @@ -2001,54 +1646,13 @@ packages: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} - css-declaration-sorter@7.2.0: - resolution: {integrity: sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==} - engines: {node: ^14 || ^16 || >=18} - peerDependencies: - postcss: ^8.0.9 - css-select@5.1.0: resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} - css-tree@2.2.1: - resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} - engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} - - css-tree@2.3.1: - resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} - engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} - css-what@6.1.0: resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} engines: {node: '>= 6'} - cssesc@3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} - hasBin: true - - cssnano-preset-default@7.0.6: - resolution: {integrity: sha512-ZzrgYupYxEvdGGuqL+JKOY70s7+saoNlHSCK/OGn1vB2pQK8KSET8jvenzItcY+kA7NoWvfbb/YhlzuzNKjOhQ==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - cssnano-utils@5.0.0: - resolution: {integrity: sha512-Uij0Xdxc24L6SirFr25MlwC2rCFX6scyUmuKpzI+JQ7cyqDEwD42fJ0xfB3yLfOnRDU5LKGgjQ9FA6LYh76GWQ==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - cssnano@7.0.6: - resolution: {integrity: sha512-54woqx8SCbp8HwvNZYn68ZFAepuouZW4lTwiMVnBErM3VkO7/Sd4oTOt3Zz3bPx3kxQ36aISppyXj2Md4lg8bw==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - csso@5.0.5: - resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} - engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} - csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} @@ -2083,17 +1687,8 @@ packages: supports-color: optional: true - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - debug@4.3.5: - resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -2123,10 +1718,6 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} - defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} @@ -2142,17 +1733,10 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} - defu@6.1.4: - resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} - dequal@2.0.3: - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} - engines: {node: '>=6'} - detect-file@1.0.0: resolution: {integrity: sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==} engines: {node: '>=0.10.0'} @@ -2169,8 +1753,8 @@ packages: resolution: {integrity: sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==} engines: {node: '>= 10.14.2'} - diff@5.0.0: - resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} + diff@5.2.0: + resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} engines: {node: '>=0.3.1'} dir-glob@3.0.1: @@ -2205,17 +1789,19 @@ packages: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} engines: {node: '>=8'} + dts-bundle-generator@9.5.1: + resolution: {integrity: sha512-DxpJOb2FNnEyOzMkG11sxO2dmxPjthoVWxfKqWYJ/bI/rT1rvTMktF5EKjAYrRZu6Z6t3NhOUZ0sZ5ZXevOfbA==} + engines: {node: '>=14.0.0'} + hasBin: true + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} ecdsa-sig-formatter@1.0.11: resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} - electron-to-chromium@1.5.16: - resolution: {integrity: sha512-2gQpi2WYobXmz2q23FrOBYTLcI1O/P4heW3eqX+ldmPVDQELRqhiebV380EhlGG12NtnX1qbK/FHpN0ba+7bLA==} - - emoji-regex@10.3.0: - resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + emoji-regex@10.4.0: + resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -2223,11 +1809,14 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + encoding-sniffer@0.2.0: + resolution: {integrity: sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==} + end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - enhanced-resolve@5.17.0: - resolution: {integrity: sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==} + enhanced-resolve@5.17.1: + resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} engines: {node: '>=10.13.0'} entities@2.1.0: @@ -2241,6 +1830,10 @@ packages: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} + environment@1.1.0: + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} + engines: {node: '>=18'} + error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} @@ -2256,8 +1849,8 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-iterator-helpers@1.0.19: - resolution: {integrity: sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==} + es-iterator-helpers@1.1.0: + resolution: {integrity: sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==} engines: {node: '>= 0.4'} es-object-atoms@1.0.0: @@ -2278,31 +1871,23 @@ packages: es6-promise@3.3.1: resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==} - esbuild-plugin-alias@0.2.1: - resolution: {integrity: sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ==} - - esbuild@0.19.12: - resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} - engines: {node: '>=12'} - hasBin: true - esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} hasBin: true - esbuild@0.23.0: - resolution: {integrity: sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==} + esbuild@0.23.1: + resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==} engines: {node: '>=18'} hasBin: true - esbuild@0.23.1: - resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==} + esbuild@0.24.0: + resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==} engines: {node: '>=18'} hasBin: true - escalade@3.1.2: - resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} escape-string-regexp@1.0.5: @@ -2337,17 +1922,11 @@ packages: eslint-plugin-react: ^7.28.0 eslint-plugin-react-hooks: ^4.3.0 - eslint-config-prettier@9.1.0: - resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} - eslint-module-utils@2.8.1: - resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} + eslint-module-utils@2.12.0: + resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -2367,24 +1946,24 @@ packages: eslint-import-resolver-webpack: optional: true - eslint-plugin-import@2.29.1: - resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} + eslint-plugin-import@2.31.0: + resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 peerDependenciesMeta: '@typescript-eslint/parser': optional: true - eslint-plugin-jsx-a11y@6.8.0: - resolution: {integrity: sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==} + eslint-plugin-jsx-a11y@6.10.1: + resolution: {integrity: sha512-zHByM9WTUMnfsDTafGXRiqxp6lFtNoSOWBY6FonVRn3A+BUwN1L/tdBXT40BcBJi0cZjOGTXZ0eD/rTG9fEJ0g==} engines: {node: '>=4.0'} peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 - eslint-plugin-prettier@5.1.3: - resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} + eslint-plugin-prettier@5.2.1: + resolution: {integrity: sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: '@types/eslint': '>=8.0.0' @@ -2403,11 +1982,11 @@ packages: peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - eslint-plugin-react@7.34.2: - resolution: {integrity: sha512-2HCmrU+/JNigDN6tg55cRDKCQWicYAPB38JGSFDQt95jDm8rrvSUo7YPkOIm5l6ts1j1zCvysNcasvfTMQzUOw==} + eslint-plugin-react@7.37.2: + resolution: {integrity: sha512-EsTAnj9fLVr/GZleBLFbj/sSuXeWmp1eXIN60ceYnZveqEaUCyW4X+Vh4WTdUhCkW4xutXYqTXCUSyqD4rB75w==} engines: {node: '>=4'} peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 eslint-scope@7.2.2: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} @@ -2417,9 +1996,10 @@ packages: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint@8.57.0: - resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} + eslint@8.57.1: + resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true espree@9.6.1: @@ -2431,8 +2011,8 @@ packages: engines: {node: '>=4'} hasBin: true - esquery@1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} esrecurse@4.3.0: @@ -2495,6 +2075,9 @@ packages: fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + fast-uri@3.0.3: + resolution: {integrity: sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==} + fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} @@ -2545,24 +2128,17 @@ packages: for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - foreground-child@3.2.0: - resolution: {integrity: sha512-CrWQNaEl1/6WeZoarcM9LHupTo3RpZO2Pdk1vktwzPiQTsJnAKJmm3TACKeG5UZbWDfaH2AbvYxzP96y0MT7fA==} + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} - form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + form-data@4.0.1: + resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} engines: {node: '>= 6'} - fraction.js@4.3.7: - resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} - fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - fs-extra@11.2.0: - resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} - engines: {node: '>=14.14'} - fs-extra@9.1.0: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} @@ -2585,21 +2161,14 @@ packages: functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-east-asian-width@1.2.0: - resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} + get-east-asian-width@1.3.0: + resolution: {integrity: sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==} engines: {node: '>=18'} - get-func-name@2.0.2: - resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} - get-intrinsic@1.2.4: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} @@ -2612,8 +2181,8 @@ packages: resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} engines: {node: '>= 0.4'} - get-tsconfig@4.7.5: - resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} + get-tsconfig@4.8.1: + resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} git-raw-commits@4.0.0: resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} @@ -2631,9 +2200,8 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - glob@10.4.1: - resolution: {integrity: sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==} - engines: {node: '>=16 || 14 >=14.18'} + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true glob@11.0.0: @@ -2662,10 +2230,6 @@ packages: resolution: {integrity: sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==} engines: {node: '>=0.10.0'} - globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - globals@13.24.0: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} engines: {node: '>=8'} @@ -2678,10 +2242,6 @@ packages: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} - globby@13.2.2: - resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} @@ -2737,9 +2297,6 @@ packages: resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} engines: {node: '>=0.10.0'} - hookable@5.5.3: - resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} - hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} @@ -2750,8 +2307,8 @@ packages: html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - htmlparser2@8.0.2: - resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + htmlparser2@9.1.0: + resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==} http-proxy-agent@7.0.2: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} @@ -2760,16 +2317,16 @@ packages: http2-client@1.3.5: resolution: {integrity: sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==} - https-proxy-agent@7.0.4: - resolution: {integrity: sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==} + https-proxy-agent@7.0.5: + resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==} engines: {node: '>= 14'} human-signals@5.0.0: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} - husky@9.0.11: - resolution: {integrity: sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==} + husky@9.1.6: + resolution: {integrity: sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A==} engines: {node: '>=18'} hasBin: true @@ -2781,11 +2338,15 @@ packages: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - ignore@5.3.1: - resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} immediate@3.0.6: @@ -2846,16 +2407,13 @@ packages: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} - is-builtin-module@3.2.1: - resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} - engines: {node: '>=6'} - is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} - is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + is-core-module@2.15.1: + resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} + engines: {node: '>= 0.4'} is-data-view@1.0.1: resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} @@ -2909,9 +2467,6 @@ packages: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} - is-module@1.0.0: - resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} - is-negative-zero@2.0.3: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} @@ -2936,9 +2491,6 @@ packages: resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} engines: {node: '>=8'} - is-reference@1.2.1: - resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} - is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} @@ -2979,6 +2531,10 @@ packages: resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} engines: {node: '>=12'} + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + is-url@1.2.4: resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} @@ -3025,15 +2581,15 @@ packages: resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} engines: {node: '>=8'} - iterator.prototype@1.1.2: - resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} + iterator.prototype@1.1.3: + resolution: {integrity: sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==} + engines: {node: '>= 0.4'} - jackspeak@3.4.0: - resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==} - engines: {node: '>=14'} + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - jackspeak@4.0.1: - resolution: {integrity: sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog==} + jackspeak@4.0.2: + resolution: {integrity: sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==} engines: {node: 20 || >=22} jest-diff@26.6.2: @@ -3059,11 +2615,6 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true - jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} - hasBin: true - json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} @@ -3086,11 +2637,6 @@ packages: resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} hasBin: true - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - jsonc-parser@3.3.1: resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} @@ -3158,13 +2704,13 @@ packages: linkify-it@3.0.3: resolution: {integrity: sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==} - lint-staged@15.2.7: - resolution: {integrity: sha512-+FdVbbCZ+yoh7E/RosSdqKJyUM2OEjTciH0TFNkawKgvFp1zbGlEC39RADg+xKBG1R4mhoH2j85myBQZ5wR+lw==} + lint-staged@15.2.10: + resolution: {integrity: sha512-5dY5t743e1byO19P9I4b3x8HJwalIznL5E1FWYnU6OWw33KxNBSLAc6Cy7F2PsFEO8FKnLwjwm5hx7aMF0jzZg==} engines: {node: '>=18.12.0'} hasBin: true - listr2@8.2.1: - resolution: {integrity: sha512-irTfvpib/rNiD637xeevjO2l3Z5loZmuaRi0L0YE5LfijwVY96oyVn0DFD3o/teAok7nfobMG1THvvcHh/BP6g==} + listr2@8.2.5: + resolution: {integrity: sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==} engines: {node: '>=18.0.0'} load-json-file@4.0.0: @@ -3206,9 +2752,6 @@ packages: lodash.map@4.6.0: resolution: {integrity: sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==} - lodash.memoize@4.1.2: - resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} - lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -3241,8 +2784,12 @@ packages: resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==} engines: {node: '>=12'} - log-update@6.0.0: - resolution: {integrity: sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==} + log-symbols@6.0.0: + resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} + engines: {node: '>=18'} + + log-update@6.1.0: + resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} engines: {node: '>=18'} longest@2.0.1: @@ -3253,29 +2800,25 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true - loupe@3.1.1: - resolution: {integrity: sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==} + loupe@3.1.2: + resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} - lru-cache@10.2.2: - resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} - engines: {node: 14 || >=16.14} + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} lru-cache@11.0.1: resolution: {integrity: sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==} engines: {node: 20 || >=22} - lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} - magic-string@0.30.10: - resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + magic-string@0.30.12: + resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} @@ -3285,17 +2828,11 @@ packages: resolution: {integrity: sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==} hasBin: true - mdn-data@2.0.28: - resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} - - mdn-data@2.0.30: - resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} - mdurl@1.0.1: resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} - memfs@4.11.1: - resolution: {integrity: sha512-LZcMTBAgqUUKNXZagcZxvXXfgF1bHX7Y7nQ0QyEiNbRJgE29GhgPd8Yna1VQcLlPiHt/5RFJMWYN9Uv/VPNvjQ==} + memfs@4.14.0: + resolution: {integrity: sha512-JUeY0F/fQZgIod31Ja1eJgiSxLn7BfQlCnqhwXFBzFHEw63OdLK7VJUJ7bnzNsWgCyoUP5tEp1VRY8rDaYzqOA==} engines: {node: '>= 4.0.0'} memorystream@0.3.1: @@ -3316,8 +2853,8 @@ packages: merge@2.1.1: resolution: {integrity: sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==} - micromatch@4.0.7: - resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} mime-db@1.52.0: @@ -3341,6 +2878,10 @@ packages: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} + mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} @@ -3352,12 +2893,12 @@ packages: minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - minimatch@5.0.1: - resolution: {integrity: sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==} + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} engines: {node: '>=10'} - minimatch@9.0.4: - resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} minimist@1.2.7: @@ -3373,36 +2914,11 @@ packages: mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} - mkdist@1.5.5: - resolution: {integrity: sha512-Kbj0Tt4uk6AN/XEV1W7EgBpJUmEXZgTWxbMKYIpO0hRXoTstFIJrJVqDgPjBz9AXXN3ZpxQBk2Q0n28Ze0Gh1w==} - hasBin: true - peerDependencies: - sass: ^1.77.8 - typescript: '>=5.5.4' - vue-tsc: ^1.8.27 || ^2.0.21 - peerDependenciesMeta: - sass: - optional: true - typescript: - optional: true - vue-tsc: - optional: true - - mlly@1.7.1: - resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} - - mocha@10.4.0: - resolution: {integrity: sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==} + mocha@10.7.3: + resolution: {integrity: sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==} engines: {node: '>= 14.0.0'} hasBin: true - mri@1.2.0: - resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} - engines: {node: '>=4'} - - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -3429,8 +2945,8 @@ packages: no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} - node-abi@3.65.0: - resolution: {integrity: sha512-ThjYBfoDNr08AWx6hGaRbfPwxKV9kVzAzOzlLKbk2CuqXE2xnCh+cbAGnwM3t8Lq4v9rUB7VfondlkBckcJrVA==} + node-abi@3.71.0: + resolution: {integrity: sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==} engines: {node: '>=10'} node-addon-api@4.3.0: @@ -3452,9 +2968,6 @@ packages: node-readfiles@0.2.0: resolution: {integrity: sha512-SU00ZarexNlE4Rjdm83vglt5Y9yiQ+XI1XpflWlb7q7UTN1JUItm69xMeiQCTxtTfnzt+83T8Cx+vI2ED++VDA==} - node-releases@2.0.18: - resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} - normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -3462,10 +2975,6 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - normalize-range@0.1.2: - resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} - engines: {node: '>=0.10.0'} - npm-run-all@4.1.5: resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==} engines: {node: '>= 4'} @@ -3502,8 +3011,9 @@ packages: resolution: {integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==} engines: {node: '>= 6'} - object-inspect@1.13.1: - resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} @@ -3525,10 +3035,6 @@ packages: resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} engines: {node: '>= 0.4'} - object.hasown@1.1.4: - resolution: {integrity: sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==} - engines: {node: '>= 0.4'} - object.values@1.2.0: resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} engines: {node: '>= 0.4'} @@ -3544,6 +3050,10 @@ packages: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} + onetime@7.0.0: + resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} + engines: {node: '>=18'} + open@8.4.2: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} @@ -3567,6 +3077,10 @@ packages: resolution: {integrity: sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw==} engines: {node: '>=16'} + ora@8.1.0: + resolution: {integrity: sha512-GQEkNkH/GHOhPFXcqZs3IDahXEQcQxsSjEkK4KvEEST4t7eNzoMjxTzef+EZ+JluDEV+Raoi3WQ2CflnRdSVnQ==} + engines: {node: '>=18'} + os-tmpdir@1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} @@ -3587,8 +3101,8 @@ packages: resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - package-json-from-dist@1.0.0: - resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} pako@1.0.11: resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} @@ -3615,11 +3129,14 @@ packages: parse-semver@1.1.1: resolution: {integrity: sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ==} - parse5-htmlparser2-tree-adapter@7.0.0: - resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} + parse5-htmlparser2-tree-adapter@7.1.0: + resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} + + parse5-parser-stream@7.1.2: + resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==} - parse5@7.1.2: - resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + parse5@7.2.0: + resolution: {integrity: sha512-ZkDsAOcxsUMZ4Lz5fVciOehNcJ+Gb8gTzcA4yl3wnc273BAybYWrQ+Ks/OjCjSEpjvQkDSeZbybK9qj2VHHdGA==} pascal-case@3.1.2: resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} @@ -3677,218 +3194,36 @@ packages: resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} engines: {node: '>= 14.16'} - pend@1.2.0: - resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - - picocolors@1.0.1: - resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - pidtree@0.3.1: - resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==} - engines: {node: '>=0.10'} - hasBin: true - - pidtree@0.6.0: - resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} - engines: {node: '>=0.10'} - hasBin: true - - pify@3.0.0: - resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} - engines: {node: '>=4'} - - pkg-types@1.2.0: - resolution: {integrity: sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==} - - possible-typed-array-names@1.0.0: - resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} - engines: {node: '>= 0.4'} - - postcss-calc@10.0.2: - resolution: {integrity: sha512-DT/Wwm6fCKgpYVI7ZEWuPJ4az8hiEHtCUeYjZXqU7Ou4QqYh1Df2yCQ7Ca6N7xqKPFkxN3fhf+u9KSoOCJNAjg==} - engines: {node: ^18.12 || ^20.9 || >=22.0} - peerDependencies: - postcss: ^8.4.38 - - postcss-colormin@7.0.2: - resolution: {integrity: sha512-YntRXNngcvEvDbEjTdRWGU606eZvB5prmHG4BF0yLmVpamXbpsRJzevyy6MZVyuecgzI2AWAlvFi8DAeCqwpvA==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-convert-values@7.0.4: - resolution: {integrity: sha512-e2LSXPqEHVW6aoGbjV9RsSSNDO3A0rZLCBxN24zvxF25WknMPpX8Dm9UxxThyEbaytzggRuZxaGXqaOhxQ514Q==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-discard-comments@7.0.3: - resolution: {integrity: sha512-q6fjd4WU4afNhWOA2WltHgCbkRhZPgQe7cXF74fuVB/ge4QbM9HEaOIzGSiMvM+g/cOsNAUGdf2JDzqA2F8iLA==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-discard-duplicates@7.0.1: - resolution: {integrity: sha512-oZA+v8Jkpu1ct/xbbrntHRsfLGuzoP+cpt0nJe5ED2FQF8n8bJtn7Bo28jSmBYwqgqnqkuSXJfSUEE7if4nClQ==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-discard-empty@7.0.0: - resolution: {integrity: sha512-e+QzoReTZ8IAwhnSdp/++7gBZ/F+nBq9y6PomfwORfP7q9nBpK5AMP64kOt0bA+lShBFbBDcgpJ3X4etHg4lzA==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-discard-overridden@7.0.0: - resolution: {integrity: sha512-GmNAzx88u3k2+sBTZrJSDauR0ccpE24omTQCVmaTTZFz1du6AasspjaUPMJ2ud4RslZpoFKyf+6MSPETLojc6w==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-merge-longhand@7.0.4: - resolution: {integrity: sha512-zer1KoZA54Q8RVHKOY5vMke0cCdNxMP3KBfDerjH/BYHh4nCIh+1Yy0t1pAEQF18ac/4z3OFclO+ZVH8azjR4A==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-merge-rules@7.0.4: - resolution: {integrity: sha512-ZsaamiMVu7uBYsIdGtKJ64PkcQt6Pcpep/uO90EpLS3dxJi6OXamIobTYcImyXGoW0Wpugh7DSD3XzxZS9JCPg==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-minify-font-values@7.0.0: - resolution: {integrity: sha512-2ckkZtgT0zG8SMc5aoNwtm5234eUx1GGFJKf2b1bSp8UflqaeFzR50lid4PfqVI9NtGqJ2J4Y7fwvnP/u1cQog==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-minify-gradients@7.0.0: - resolution: {integrity: sha512-pdUIIdj/C93ryCHew0UgBnL2DtUS3hfFa5XtERrs4x+hmpMYGhbzo6l/Ir5de41O0GaKVpK1ZbDNXSY6GkXvtg==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-minify-params@7.0.2: - resolution: {integrity: sha512-nyqVLu4MFl9df32zTsdcLqCFfE/z2+f8GE1KHPxWOAmegSo6lpV2GNy5XQvrzwbLmiU7d+fYay4cwto1oNdAaQ==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-minify-selectors@7.0.4: - resolution: {integrity: sha512-JG55VADcNb4xFCf75hXkzc1rNeURhlo7ugf6JjiiKRfMsKlDzN9CXHZDyiG6x/zGchpjQS+UAgb1d4nqXqOpmA==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-nested@6.2.0: - resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} - engines: {node: '>=12.0'} - peerDependencies: - postcss: ^8.2.14 - - postcss-normalize-charset@7.0.0: - resolution: {integrity: sha512-ABisNUXMeZeDNzCQxPxBCkXexvBrUHV+p7/BXOY+ulxkcjUZO0cp8ekGBwvIh2LbCwnWbyMPNJVtBSdyhM2zYQ==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-normalize-display-values@7.0.0: - resolution: {integrity: sha512-lnFZzNPeDf5uGMPYgGOw7v0BfB45+irSRz9gHQStdkkhiM0gTfvWkWB5BMxpn0OqgOQuZG/mRlZyJxp0EImr2Q==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-normalize-positions@7.0.0: - resolution: {integrity: sha512-I0yt8wX529UKIGs2y/9Ybs2CelSvItfmvg/DBIjTnoUSrPxSV7Z0yZ8ShSVtKNaV/wAY+m7bgtyVQLhB00A1NQ==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-normalize-repeat-style@7.0.0: - resolution: {integrity: sha512-o3uSGYH+2q30ieM3ppu9GTjSXIzOrRdCUn8UOMGNw7Af61bmurHTWI87hRybrP6xDHvOe5WlAj3XzN6vEO8jLw==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-normalize-string@7.0.0: - resolution: {integrity: sha512-w/qzL212DFVOpMy3UGyxrND+Kb0fvCiBBujiaONIihq7VvtC7bswjWgKQU/w4VcRyDD8gpfqUiBQ4DUOwEJ6Qg==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-normalize-timing-functions@7.0.0: - resolution: {integrity: sha512-tNgw3YV0LYoRwg43N3lTe3AEWZ66W7Dh7lVEpJbHoKOuHc1sLrzMLMFjP8SNULHaykzsonUEDbKedv8C+7ej6g==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-normalize-unicode@7.0.2: - resolution: {integrity: sha512-ztisabK5C/+ZWBdYC+Y9JCkp3M9qBv/XFvDtSw0d/XwfT3UaKeW/YTm/MD/QrPNxuecia46vkfEhewjwcYFjkg==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-normalize-url@7.0.0: - resolution: {integrity: sha512-+d7+PpE+jyPX1hDQZYG+NaFD+Nd2ris6r8fPTBAjE8z/U41n/bib3vze8x7rKs5H1uEw5ppe9IojewouHk0klQ==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-normalize-whitespace@7.0.0: - resolution: {integrity: sha512-37/toN4wwZErqohedXYqWgvcHUGlT8O/m2jVkAfAe9Bd4MzRqlBmXrJRePH0e9Wgnz2X7KymTgTOaaFizQe3AQ==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-ordered-values@7.0.1: - resolution: {integrity: sha512-irWScWRL6nRzYmBOXReIKch75RRhNS86UPUAxXdmW/l0FcAsg0lvAXQCby/1lymxn/o0gVa6Rv/0f03eJOwHxw==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - - postcss-reduce-initial@7.0.2: - resolution: {integrity: sha512-pOnu9zqQww7dEKf62Nuju6JgsW2V0KRNBHxeKohU+JkHd/GAH5uvoObqFLqkeB2n20mr6yrlWDvo5UBU5GnkfA==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 + pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - postcss-reduce-transforms@7.0.0: - resolution: {integrity: sha512-pnt1HKKZ07/idH8cpATX/ujMbtOGhUfE+m8gbqwJE05aTaNw8gbo34a2e3if0xc0dlu75sUOiqvwCGY3fzOHew==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - postcss-selector-parser@6.1.2: - resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} - engines: {node: '>=4'} + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} - postcss-svgo@7.0.1: - resolution: {integrity: sha512-0WBUlSL4lhD9rA5k1e5D8EN5wCEyZD6HJk0jIvRxl+FDVOMlJ7DePHYWGGVc5QRqrJ3/06FTXM0bxjmJpmTPSA==} - engines: {node: ^18.12.0 || ^20.9.0 || >= 18} - peerDependencies: - postcss: ^8.4.31 + pidtree@0.3.1: + resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==} + engines: {node: '>=0.10'} + hasBin: true - postcss-unique-selectors@7.0.3: - resolution: {integrity: sha512-J+58u5Ic5T1QjP/LDV9g3Cx4CNOgB5vz+kM6+OxHHhFACdcDeKhBXjQmB7fnIZM12YSTvsL0Opwco83DmacW2g==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 + pidtree@0.6.0: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} + engines: {node: '>=0.10'} + hasBin: true - postcss-value-parser@4.2.0: - resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} - postcss@8.4.39: - resolution: {integrity: sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==} - engines: {node: ^10 || ^12 || >=14} + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} - postcss@8.4.45: - resolution: {integrity: sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==} + postcss@8.4.47: + resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} engines: {node: ^10 || ^12 || >=14} prebuild-install@7.1.2: @@ -3923,15 +3258,11 @@ packages: peerDependencies: prettier: ^3.0.0 - prettier@3.3.2: - resolution: {integrity: sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==} + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} engines: {node: '>=14'} hasBin: true - pretty-bytes@6.1.1: - resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} - engines: {node: ^14.13.1 || >=16.0.0} - pretty-format@26.6.2: resolution: {integrity: sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==} engines: {node: '>= 10'} @@ -3942,15 +3273,15 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} - pump@3.0.0: - resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + pump@3.0.2: + resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - qs@6.12.3: - resolution: {integrity: sha512-AWJm14H1vVaO/iNZ4/hO+HyaTehuy9nRqVdkTqlJt0HWvBiBIEXFmb4C0DGeYo3Xes9rrEW+TxHsaigCbN5ICQ==} + qs@6.13.0: + resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} engines: {node: '>=0.6'} querystringify@2.2.0: @@ -3962,8 +3293,8 @@ packages: randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - rate-limiter-flexible@5.0.3: - resolution: {integrity: sha512-lWx2y8NBVlTOLPyqs+6y7dxfEpT6YFqKy3MzWbCy95sTTOhOuxufP2QvRyOHpfXpB9OUJPbVLybw3z3AVAS5fA==} + rate-limiter-flexible@5.0.4: + resolution: {integrity: sha512-ftYHrIfSqWYDIJZ4yPTrgOduByAp+86gUS9iklv0JoXVM8eQCAjTnydCj1hAT4MmhmkSw86NaFEJ28m/LC1pKA==} rc@1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} @@ -4001,11 +3332,8 @@ packages: reftools@1.1.9: resolution: {integrity: sha512-OVede/NQE13xBQ+ob5CKd5KyeJYU2YInb1bmV4nRoOfquZPkAkxuOXicSe1PvqIuZZ4kD13sPKBbR7UFDmli6w==} - regenerator-runtime@0.14.1: - resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - - regexp.prototype.flags@1.5.2: - resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + regexp.prototype.flags@1.5.3: + resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} engines: {node: '>= 0.4'} require-directory@2.1.1: @@ -4050,6 +3378,10 @@ packages: resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + restore-cursor@5.1.0: + resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} + engines: {node: '>=18'} + reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -4067,20 +3399,8 @@ packages: engines: {node: 20 || >=22} hasBin: true - rollup-plugin-dts@6.1.1: - resolution: {integrity: sha512-aSHRcJ6KG2IHIioYlvAOcEq6U99sVtqDDKVhnwt70rW6tsz3tv5OSjEiWcgzfsHdLyGXZ/3b/7b/+Za3Y6r1XA==} - engines: {node: '>=16'} - peerDependencies: - rollup: ^3.29.4 || ^4 - typescript: ^4.5 || ^5.0 - - rollup@3.29.4: - resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==} - engines: {node: '>=14.18.0', npm: '>=8.0.0'} - hasBin: true - - rollup@4.21.2: - resolution: {integrity: sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==} + rollup@4.24.0: + resolution: {integrity: sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -4114,9 +3434,6 @@ packages: sax@1.4.1: resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} - scule@1.3.0: - resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} - semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -4125,11 +3442,6 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.6.2: - resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} - engines: {node: '>=10'} - hasBin: true - semver@7.6.3: resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} engines: {node: '>=10'} @@ -4138,8 +3450,8 @@ packages: sentence-case@3.0.4: resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==} - serialize-javascript@6.0.0: - resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} @@ -4213,10 +3525,6 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} - slash@4.0.0: - resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} - engines: {node: '>=12'} - slice-ansi@5.0.0: resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} engines: {node: '>=12'} @@ -4228,8 +3536,8 @@ packages: snake-case@3.0.4: resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} - source-map-js@1.2.0: - resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} source-map@0.6.1: @@ -4245,8 +3553,8 @@ packages: spdx-expression-parse@3.0.1: resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - spdx-license-ids@3.0.18: - resolution: {integrity: sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==} + spdx-license-ids@3.0.20: + resolution: {integrity: sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==} split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} @@ -4265,6 +3573,10 @@ packages: resolution: {integrity: sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + stdin-discarder@0.2.2: + resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} + engines: {node: '>=18'} + stoppable@1.1.0: resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} engines: {node: '>=4', npm: '>=6'} @@ -4285,10 +3597,14 @@ packages: resolution: {integrity: sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==} engines: {node: '>=16'} - string-width@7.1.0: - resolution: {integrity: sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==} + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} + string.prototype.includes@2.0.1: + resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} + engines: {node: '>= 0.4'} + string.prototype.matchall@4.0.11: resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} engines: {node: '>= 0.4'} @@ -4297,6 +3613,9 @@ packages: resolution: {integrity: sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==} engines: {node: '>= 0.4'} + string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + string.prototype.trim@1.2.9: resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} engines: {node: '>= 0.4'} @@ -4342,12 +3661,6 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - stylehacks@7.0.4: - resolution: {integrity: sha512-i4zfNrGMt9SB4xRK9L83rlsFCgdGANfeDAYacO1pkqcE7cRHPdWHwnKZVz7WY17Veq/FvyYsRAU++Ga+qDFIww==} - engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} - peerDependencies: - postcss: ^8.4.31 - supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -4368,17 +3681,12 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - svgo@3.3.2: - resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==} - engines: {node: '>=14.0.0'} - hasBin: true - swagger2openapi@7.0.8: resolution: {integrity: sha512-upi/0ZGkYgEcLeGieoz8gT74oWHA0E7JivX7aN9mAf+Tc7BQoRBvnIGHoPDw+f9TXTW4s6kGYCZJtauP6OYp7g==} hasBin: true - synckit@0.8.8: - resolution: {integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==} + synckit@0.9.2: + resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==} engines: {node: ^14.18.0 || >=16.0.0} tapable@2.2.1: @@ -4415,6 +3723,9 @@ packages: tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + tinyexec@0.3.1: + resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} + tinypool@1.0.1: resolution: {integrity: sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -4435,10 +3746,6 @@ packages: resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} engines: {node: '>=14.14'} - to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -4461,14 +3768,11 @@ packages: tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} - tslib@2.6.3: - resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + tslib@2.8.0: + resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==} - tslib@2.7.0: - resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} - - tsx@4.16.2: - resolution: {integrity: sha512-C1uWweJDgdtX2x600HjaFaucXTilT7tgUZHbOE4+ypskZ1OP8CRCSDkCxG6Vya9EwaFIVagWwpaVAn5wzypaqQ==} + tsx@4.19.1: + resolution: {integrity: sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==} engines: {node: '>=18.0.0'} hasBin: true @@ -4491,8 +3795,8 @@ packages: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} - type-fest@4.20.0: - resolution: {integrity: sha512-MBh+PHUHHisjXf4tlx0CFWoMdjx8zCMLJHOjnV1prABYZFHqtFOyauCIK2/7w4oIfwkF8iNhLtnJEfVY2vn3iw==} + type-fest@4.26.1: + resolution: {integrity: sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==} engines: {node: '>=16'} typed-array-buffer@1.0.2: @@ -4514,45 +3818,32 @@ packages: typed-rest-client@1.8.11: resolution: {integrity: sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA==} - typescript@5.4.5: - resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} - engines: {node: '>=14.17'} - hasBin: true - - typescript@5.5.4: - resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + typescript@5.6.3: + resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} engines: {node: '>=14.17'} hasBin: true uc.micro@1.0.6: resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} - ufo@1.5.4: - resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} - - uglify-js@3.18.0: - resolution: {integrity: sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==} + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} engines: {node: '>=0.8.0'} hasBin: true unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} - unbuild@2.0.0: - resolution: {integrity: sha512-JWCUYx3Oxdzvw2J9kTAp+DKE8df/BnH/JTSj6JyA4SH40ECdFu7FoJJcrm8G92B7TjofQ6GZGjJs50TRxoH6Wg==} - hasBin: true - peerDependencies: - typescript: ^5.1.6 - peerDependenciesMeta: - typescript: - optional: true - - underscore@1.13.6: - resolution: {integrity: sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==} + underscore@1.13.7: + resolution: {integrity: sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==} undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici@6.20.1: + resolution: {integrity: sha512-AjQF1QsmqfJys+LXfGTNum+qw4S88CojRInG/6t31W/1fk6G59s92bnAvGz5Cmur+kQv2SURXEvvudLmbrE8QA==} + engines: {node: '>=18.17'} + unicorn-magic@0.1.0: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} engines: {node: '>=18'} @@ -4561,16 +3852,6 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} - untyped@1.4.2: - resolution: {integrity: sha512-nC5q0DnPEPVURPhfPQLahhSTnemVtPzdx7ofiRxXpOB2SYnb3MfdU3DVGyJdS8Lx+tBWeAePO8BfU/3EgksM7Q==} - hasBin: true - - update-browserslist-db@1.1.0: - resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - upper-case-first@2.0.2: resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==} @@ -4593,20 +3874,20 @@ packages: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true - v8-to-istanbul@9.2.0: - resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} + v8-to-istanbul@9.3.0: + resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} - vite-node@2.0.5: - resolution: {integrity: sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==} + vite-node@2.1.3: + resolution: {integrity: sha512-I1JadzO+xYX887S39Do+paRePCKoiDrWRRjp9kkG5he0t7RXNvPAJPCQSJqbGN4uCrFFeS3Kj3sLqY8NMYBEdA==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true - vite@5.4.3: - resolution: {integrity: sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==} + vite@5.4.10: + resolution: {integrity: sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -4636,15 +3917,15 @@ packages: terser: optional: true - vitest@2.0.5: - resolution: {integrity: sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==} + vitest@2.1.3: + resolution: {integrity: sha512-Zrxbg/WiIvUP2uEzelDNTXmEMJXuzJ1kCpbDvaKByFA9MNeO95V+7r/3ti0qzJzrxdyuUw5VduN7k+D3VmVOSA==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 2.0.5 - '@vitest/ui': 2.0.5 + '@vitest/browser': 2.1.3 + '@vitest/ui': 2.1.3 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -4661,8 +3942,8 @@ packages: jsdom: optional: true - vue@3.4.31: - resolution: {integrity: sha512-njqRrOy7W3YLAlVqSKpBebtZpDVg21FPoaq1I7f/+qqBThK9ChAIjkRWgeP6Eat+8C+iia4P3OYqpATP21BCoQ==} + vue@3.5.12: + resolution: {integrity: sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg==} peerDependencies: typescript: '*' peerDependenciesMeta: @@ -4675,14 +3956,22 @@ packages: webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} - which-builtin-type@1.1.3: - resolution: {integrity: sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==} + which-builtin-type@1.1.4: + resolution: {integrity: sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==} engines: {node: '>= 0.4'} which-collection@1.0.2: @@ -4714,8 +4003,8 @@ packages: wordwrap@1.0.0: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} - workerpool@6.2.1: - resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} + workerpool@6.5.1: + resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==} wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} @@ -4744,9 +4033,6 @@ packages: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} - yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} @@ -4754,13 +4040,13 @@ packages: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} - yaml@2.4.5: - resolution: {integrity: sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==} + yaml@2.5.1: + resolution: {integrity: sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==} engines: {node: '>= 14'} hasBin: true - yargs-parser@20.2.4: - resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} + yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} engines: {node: '>=10'} yargs-parser@21.1.1: @@ -4789,8 +4075,8 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - yocto-queue@1.0.0: - resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + yocto-queue@1.1.1: + resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==} engines: {node: '>=12.20'} snapshots: @@ -4807,295 +4093,181 @@ snapshots: '@alova/mock@1.5.2': {} - '@alova/mock@2.0.4(alova@3.0.5)': + '@alova/mock@2.0.8(alova@3.0.5)': dependencies: - '@alova/shared': 1.0.4 + '@alova/shared': 1.0.7 alova: 3.0.5 '@alova/shared@1.0.0-beta.7': {} - '@alova/shared@1.0.4': {} - - '@ampproject/remapping@2.3.0': - dependencies: - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 - - '@azure/abort-controller@1.1.0': - dependencies: - tslib: 2.6.3 + '@alova/shared@1.0.7': {} '@azure/abort-controller@2.1.2': dependencies: - tslib: 2.6.3 + tslib: 2.8.0 - '@azure/core-auth@1.7.2': + '@azure/core-auth@1.9.0': dependencies: '@azure/abort-controller': 2.1.2 - '@azure/core-util': 1.9.1 - tslib: 2.6.3 + '@azure/core-util': 1.11.0 + tslib: 2.8.0 '@azure/core-client@1.9.2': dependencies: '@azure/abort-controller': 2.1.2 - '@azure/core-auth': 1.7.2 - '@azure/core-rest-pipeline': 1.16.2 - '@azure/core-tracing': 1.1.2 - '@azure/core-util': 1.9.1 - '@azure/logger': 1.1.3 - tslib: 2.6.3 + '@azure/core-auth': 1.9.0 + '@azure/core-rest-pipeline': 1.17.0 + '@azure/core-tracing': 1.2.0 + '@azure/core-util': 1.11.0 + '@azure/logger': 1.1.4 + tslib: 2.8.0 transitivePeerDependencies: - supports-color - '@azure/core-rest-pipeline@1.16.2': + '@azure/core-rest-pipeline@1.17.0': dependencies: '@azure/abort-controller': 2.1.2 - '@azure/core-auth': 1.7.2 - '@azure/core-tracing': 1.1.2 - '@azure/core-util': 1.9.1 - '@azure/logger': 1.1.3 + '@azure/core-auth': 1.9.0 + '@azure/core-tracing': 1.2.0 + '@azure/core-util': 1.11.0 + '@azure/logger': 1.1.4 http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.4 - tslib: 2.6.3 + https-proxy-agent: 7.0.5 + tslib: 2.8.0 transitivePeerDependencies: - supports-color - '@azure/core-tracing@1.1.2': + '@azure/core-tracing@1.2.0': dependencies: - tslib: 2.6.3 + tslib: 2.8.0 - '@azure/core-util@1.9.1': + '@azure/core-util@1.11.0': dependencies: '@azure/abort-controller': 2.1.2 - tslib: 2.6.3 + tslib: 2.8.0 - '@azure/identity@4.3.0': + '@azure/identity@4.5.0': dependencies: - '@azure/abort-controller': 1.1.0 - '@azure/core-auth': 1.7.2 + '@azure/abort-controller': 2.1.2 + '@azure/core-auth': 1.9.0 '@azure/core-client': 1.9.2 - '@azure/core-rest-pipeline': 1.16.2 - '@azure/core-tracing': 1.1.2 - '@azure/core-util': 1.9.1 - '@azure/logger': 1.1.3 - '@azure/msal-browser': 3.18.0 - '@azure/msal-node': 2.10.0 + '@azure/core-rest-pipeline': 1.17.0 + '@azure/core-tracing': 1.2.0 + '@azure/core-util': 1.11.0 + '@azure/logger': 1.1.4 + '@azure/msal-browser': 3.26.1 + '@azure/msal-node': 2.15.0 events: 3.3.0 jws: 4.0.0 open: 8.4.2 stoppable: 1.1.0 - tslib: 2.6.3 + tslib: 2.8.0 transitivePeerDependencies: - supports-color - '@azure/logger@1.1.3': + '@azure/logger@1.1.4': dependencies: - tslib: 2.6.3 + tslib: 2.8.0 - '@azure/msal-browser@3.18.0': + '@azure/msal-browser@3.26.1': dependencies: - '@azure/msal-common': 14.13.0 + '@azure/msal-common': 14.15.0 - '@azure/msal-common@14.13.0': {} + '@azure/msal-common@14.15.0': {} - '@azure/msal-node@2.10.0': + '@azure/msal-node@2.15.0': dependencies: - '@azure/msal-common': 14.13.0 + '@azure/msal-common': 14.15.0 jsonwebtoken: 9.0.2 uuid: 8.3.2 - '@babel/code-frame@7.24.7': - dependencies: - '@babel/highlight': 7.24.7 - picocolors: 1.0.1 - - '@babel/compat-data@7.25.4': {} - - '@babel/core@7.25.2': - dependencies: - '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.24.7 - '@babel/generator': 7.25.6 - '@babel/helper-compilation-targets': 7.25.2 - '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) - '@babel/helpers': 7.25.6 - '@babel/parser': 7.25.6 - '@babel/template': 7.25.0 - '@babel/traverse': 7.25.6 - '@babel/types': 7.25.6 - convert-source-map: 2.0.0 - debug: 4.3.5 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/generator@7.25.6': - dependencies: - '@babel/types': 7.25.6 - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 - jsesc: 2.5.2 - - '@babel/helper-compilation-targets@7.25.2': - dependencies: - '@babel/compat-data': 7.25.4 - '@babel/helper-validator-option': 7.24.8 - browserslist: 4.23.3 - lru-cache: 5.1.1 - semver: 6.3.1 - - '@babel/helper-module-imports@7.24.7': - dependencies: - '@babel/traverse': 7.25.6 - '@babel/types': 7.25.6 - transitivePeerDependencies: - - supports-color - - '@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-module-imports': 7.24.7 - '@babel/helper-simple-access': 7.24.7 - '@babel/helper-validator-identifier': 7.24.7 - '@babel/traverse': 7.25.6 - transitivePeerDependencies: - - supports-color - - '@babel/helper-simple-access@7.24.7': + '@babel/code-frame@7.25.9': dependencies: - '@babel/traverse': 7.25.6 - '@babel/types': 7.25.6 - transitivePeerDependencies: - - supports-color - - '@babel/helper-string-parser@7.24.7': {} - - '@babel/helper-string-parser@7.24.8': {} - - '@babel/helper-validator-identifier@7.24.7': {} + '@babel/highlight': 7.25.9 + picocolors: 1.1.1 - '@babel/helper-validator-option@7.24.8': {} + '@babel/helper-string-parser@7.25.9': {} - '@babel/helpers@7.25.6': - dependencies: - '@babel/template': 7.25.0 - '@babel/types': 7.25.6 + '@babel/helper-validator-identifier@7.25.9': {} - '@babel/highlight@7.24.7': + '@babel/highlight@7.25.9': dependencies: - '@babel/helper-validator-identifier': 7.24.7 + '@babel/helper-validator-identifier': 7.25.9 chalk: 2.4.2 js-tokens: 4.0.0 - picocolors: 1.0.1 - - '@babel/parser@7.24.7': - dependencies: - '@babel/types': 7.24.7 - - '@babel/parser@7.25.6': - dependencies: - '@babel/types': 7.25.6 - - '@babel/runtime@7.24.7': - dependencies: - regenerator-runtime: 0.14.1 - - '@babel/standalone@7.25.6': {} - - '@babel/template@7.25.0': - dependencies: - '@babel/code-frame': 7.24.7 - '@babel/parser': 7.25.6 - '@babel/types': 7.25.6 - - '@babel/traverse@7.25.6': - dependencies: - '@babel/code-frame': 7.24.7 - '@babel/generator': 7.25.6 - '@babel/parser': 7.25.6 - '@babel/template': 7.25.0 - '@babel/types': 7.25.6 - debug: 4.3.5 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color + picocolors: 1.1.1 - '@babel/types@7.24.7': + '@babel/parser@7.25.9': dependencies: - '@babel/helper-string-parser': 7.24.7 - '@babel/helper-validator-identifier': 7.24.7 - to-fast-properties: 2.0.0 + '@babel/types': 7.25.9 - '@babel/types@7.25.6': + '@babel/types@7.25.9': dependencies: - '@babel/helper-string-parser': 7.24.8 - '@babel/helper-validator-identifier': 7.24.7 - to-fast-properties: 2.0.0 + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 '@bcoe/v8-coverage@0.2.3': {} - '@commitlint/cli@19.3.0(@types/node@18.19.34)(typescript@5.5.4)': + '@commitlint/cli@19.5.0(@types/node@18.19.59)(typescript@5.6.3)': dependencies: - '@commitlint/format': 19.3.0 - '@commitlint/lint': 19.2.2 - '@commitlint/load': 19.2.0(@types/node@18.19.34)(typescript@5.5.4) - '@commitlint/read': 19.2.1 - '@commitlint/types': 19.0.3 - execa: 8.0.1 + '@commitlint/format': 19.5.0 + '@commitlint/lint': 19.5.0 + '@commitlint/load': 19.5.0(@types/node@18.19.59)(typescript@5.6.3) + '@commitlint/read': 19.5.0 + '@commitlint/types': 19.5.0 + tinyexec: 0.3.1 yargs: 17.7.2 transitivePeerDependencies: - '@types/node' - typescript - '@commitlint/config-conventional@19.2.2': + '@commitlint/config-conventional@19.5.0': dependencies: - '@commitlint/types': 19.0.3 + '@commitlint/types': 19.5.0 conventional-changelog-conventionalcommits: 7.0.2 - '@commitlint/config-validator@19.0.3': + '@commitlint/config-validator@19.5.0': dependencies: - '@commitlint/types': 19.0.3 - ajv: 8.16.0 + '@commitlint/types': 19.5.0 + ajv: 8.17.1 - '@commitlint/ensure@19.0.3': + '@commitlint/ensure@19.5.0': dependencies: - '@commitlint/types': 19.0.3 + '@commitlint/types': 19.5.0 lodash.camelcase: 4.3.0 lodash.kebabcase: 4.1.1 lodash.snakecase: 4.1.1 lodash.startcase: 4.4.0 lodash.upperfirst: 4.3.1 - '@commitlint/execute-rule@19.0.0': {} + '@commitlint/execute-rule@19.5.0': {} - '@commitlint/format@19.3.0': + '@commitlint/format@19.5.0': dependencies: - '@commitlint/types': 19.0.3 + '@commitlint/types': 19.5.0 chalk: 5.3.0 - '@commitlint/is-ignored@19.2.2': + '@commitlint/is-ignored@19.5.0': dependencies: - '@commitlint/types': 19.0.3 - semver: 7.6.2 + '@commitlint/types': 19.5.0 + semver: 7.6.3 - '@commitlint/lint@19.2.2': + '@commitlint/lint@19.5.0': dependencies: - '@commitlint/is-ignored': 19.2.2 - '@commitlint/parse': 19.0.3 - '@commitlint/rules': 19.0.3 - '@commitlint/types': 19.0.3 + '@commitlint/is-ignored': 19.5.0 + '@commitlint/parse': 19.5.0 + '@commitlint/rules': 19.5.0 + '@commitlint/types': 19.5.0 - '@commitlint/load@19.2.0(@types/node@18.19.34)(typescript@5.5.4)': + '@commitlint/load@19.5.0(@types/node@18.19.59)(typescript@5.6.3)': dependencies: - '@commitlint/config-validator': 19.0.3 - '@commitlint/execute-rule': 19.0.0 - '@commitlint/resolve-extends': 19.1.0 - '@commitlint/types': 19.0.3 + '@commitlint/config-validator': 19.5.0 + '@commitlint/execute-rule': 19.5.0 + '@commitlint/resolve-extends': 19.5.0 + '@commitlint/types': 19.5.0 chalk: 5.3.0 - cosmiconfig: 9.0.0(typescript@5.5.4) - cosmiconfig-typescript-loader: 5.0.0(@types/node@18.19.34)(cosmiconfig@9.0.0(typescript@5.5.4))(typescript@5.5.4) + cosmiconfig: 9.0.0(typescript@5.6.3) + cosmiconfig-typescript-loader: 5.1.0(@types/node@18.19.59)(cosmiconfig@9.0.0(typescript@5.6.3))(typescript@5.6.3) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -5103,346 +4275,276 @@ snapshots: - '@types/node' - typescript - '@commitlint/message@19.0.0': {} + '@commitlint/message@19.5.0': {} - '@commitlint/parse@19.0.3': + '@commitlint/parse@19.5.0': dependencies: - '@commitlint/types': 19.0.3 + '@commitlint/types': 19.5.0 conventional-changelog-angular: 7.0.0 conventional-commits-parser: 5.0.0 - '@commitlint/read@19.2.1': + '@commitlint/read@19.5.0': dependencies: - '@commitlint/top-level': 19.0.0 - '@commitlint/types': 19.0.3 - execa: 8.0.1 + '@commitlint/top-level': 19.5.0 + '@commitlint/types': 19.5.0 git-raw-commits: 4.0.0 minimist: 1.2.8 + tinyexec: 0.3.1 - '@commitlint/resolve-extends@19.1.0': + '@commitlint/resolve-extends@19.5.0': dependencies: - '@commitlint/config-validator': 19.0.3 - '@commitlint/types': 19.0.3 + '@commitlint/config-validator': 19.5.0 + '@commitlint/types': 19.5.0 global-directory: 4.0.1 import-meta-resolve: 4.1.0 lodash.mergewith: 4.6.2 resolve-from: 5.0.0 - '@commitlint/rules@19.0.3': + '@commitlint/rules@19.5.0': dependencies: - '@commitlint/ensure': 19.0.3 - '@commitlint/message': 19.0.0 - '@commitlint/to-lines': 19.0.0 - '@commitlint/types': 19.0.3 - execa: 8.0.1 + '@commitlint/ensure': 19.5.0 + '@commitlint/message': 19.5.0 + '@commitlint/to-lines': 19.5.0 + '@commitlint/types': 19.5.0 - '@commitlint/to-lines@19.0.0': {} + '@commitlint/to-lines@19.5.0': {} - '@commitlint/top-level@19.0.0': + '@commitlint/top-level@19.5.0': dependencies: find-up: 7.0.0 - '@commitlint/types@19.0.3': + '@commitlint/types@19.5.0': dependencies: '@types/conventional-commits-parser': 5.0.0 chalk: 5.3.0 - '@esbuild/aix-ppc64@0.19.12': - optional: true - '@esbuild/aix-ppc64@0.21.5': optional: true - '@esbuild/aix-ppc64@0.23.0': - optional: true - '@esbuild/aix-ppc64@0.23.1': optional: true - '@esbuild/android-arm64@0.19.12': + '@esbuild/aix-ppc64@0.24.0': optional: true '@esbuild/android-arm64@0.21.5': optional: true - '@esbuild/android-arm64@0.23.0': - optional: true - '@esbuild/android-arm64@0.23.1': optional: true - '@esbuild/android-arm@0.19.12': + '@esbuild/android-arm64@0.24.0': optional: true '@esbuild/android-arm@0.21.5': optional: true - '@esbuild/android-arm@0.23.0': - optional: true - '@esbuild/android-arm@0.23.1': optional: true - '@esbuild/android-x64@0.19.12': + '@esbuild/android-arm@0.24.0': optional: true '@esbuild/android-x64@0.21.5': optional: true - '@esbuild/android-x64@0.23.0': - optional: true - '@esbuild/android-x64@0.23.1': optional: true - '@esbuild/darwin-arm64@0.19.12': + '@esbuild/android-x64@0.24.0': optional: true '@esbuild/darwin-arm64@0.21.5': optional: true - '@esbuild/darwin-arm64@0.23.0': - optional: true - '@esbuild/darwin-arm64@0.23.1': optional: true - '@esbuild/darwin-x64@0.19.12': + '@esbuild/darwin-arm64@0.24.0': optional: true '@esbuild/darwin-x64@0.21.5': optional: true - '@esbuild/darwin-x64@0.23.0': - optional: true - '@esbuild/darwin-x64@0.23.1': optional: true - '@esbuild/freebsd-arm64@0.19.12': + '@esbuild/darwin-x64@0.24.0': optional: true '@esbuild/freebsd-arm64@0.21.5': optional: true - '@esbuild/freebsd-arm64@0.23.0': - optional: true - '@esbuild/freebsd-arm64@0.23.1': optional: true - '@esbuild/freebsd-x64@0.19.12': + '@esbuild/freebsd-arm64@0.24.0': optional: true '@esbuild/freebsd-x64@0.21.5': optional: true - '@esbuild/freebsd-x64@0.23.0': - optional: true - '@esbuild/freebsd-x64@0.23.1': optional: true - '@esbuild/linux-arm64@0.19.12': + '@esbuild/freebsd-x64@0.24.0': optional: true '@esbuild/linux-arm64@0.21.5': optional: true - '@esbuild/linux-arm64@0.23.0': - optional: true - '@esbuild/linux-arm64@0.23.1': optional: true - '@esbuild/linux-arm@0.19.12': + '@esbuild/linux-arm64@0.24.0': optional: true '@esbuild/linux-arm@0.21.5': optional: true - '@esbuild/linux-arm@0.23.0': - optional: true - '@esbuild/linux-arm@0.23.1': optional: true - '@esbuild/linux-ia32@0.19.12': + '@esbuild/linux-arm@0.24.0': optional: true '@esbuild/linux-ia32@0.21.5': optional: true - '@esbuild/linux-ia32@0.23.0': - optional: true - '@esbuild/linux-ia32@0.23.1': optional: true - '@esbuild/linux-loong64@0.19.12': + '@esbuild/linux-ia32@0.24.0': optional: true '@esbuild/linux-loong64@0.21.5': optional: true - '@esbuild/linux-loong64@0.23.0': - optional: true - '@esbuild/linux-loong64@0.23.1': optional: true - '@esbuild/linux-mips64el@0.19.12': + '@esbuild/linux-loong64@0.24.0': optional: true '@esbuild/linux-mips64el@0.21.5': optional: true - '@esbuild/linux-mips64el@0.23.0': - optional: true - '@esbuild/linux-mips64el@0.23.1': optional: true - '@esbuild/linux-ppc64@0.19.12': + '@esbuild/linux-mips64el@0.24.0': optional: true '@esbuild/linux-ppc64@0.21.5': optional: true - '@esbuild/linux-ppc64@0.23.0': - optional: true - '@esbuild/linux-ppc64@0.23.1': optional: true - '@esbuild/linux-riscv64@0.19.12': + '@esbuild/linux-ppc64@0.24.0': optional: true '@esbuild/linux-riscv64@0.21.5': optional: true - '@esbuild/linux-riscv64@0.23.0': - optional: true - '@esbuild/linux-riscv64@0.23.1': optional: true - '@esbuild/linux-s390x@0.19.12': + '@esbuild/linux-riscv64@0.24.0': optional: true '@esbuild/linux-s390x@0.21.5': optional: true - '@esbuild/linux-s390x@0.23.0': - optional: true - '@esbuild/linux-s390x@0.23.1': optional: true - '@esbuild/linux-x64@0.19.12': + '@esbuild/linux-s390x@0.24.0': optional: true '@esbuild/linux-x64@0.21.5': optional: true - '@esbuild/linux-x64@0.23.0': - optional: true - '@esbuild/linux-x64@0.23.1': optional: true - '@esbuild/netbsd-x64@0.19.12': + '@esbuild/linux-x64@0.24.0': optional: true '@esbuild/netbsd-x64@0.21.5': optional: true - '@esbuild/netbsd-x64@0.23.0': - optional: true - '@esbuild/netbsd-x64@0.23.1': optional: true - '@esbuild/openbsd-arm64@0.23.0': + '@esbuild/netbsd-x64@0.24.0': optional: true '@esbuild/openbsd-arm64@0.23.1': optional: true - '@esbuild/openbsd-x64@0.19.12': + '@esbuild/openbsd-arm64@0.24.0': optional: true '@esbuild/openbsd-x64@0.21.5': optional: true - '@esbuild/openbsd-x64@0.23.0': - optional: true - '@esbuild/openbsd-x64@0.23.1': optional: true - '@esbuild/sunos-x64@0.19.12': + '@esbuild/openbsd-x64@0.24.0': optional: true '@esbuild/sunos-x64@0.21.5': optional: true - '@esbuild/sunos-x64@0.23.0': - optional: true - '@esbuild/sunos-x64@0.23.1': optional: true - '@esbuild/win32-arm64@0.19.12': + '@esbuild/sunos-x64@0.24.0': optional: true '@esbuild/win32-arm64@0.21.5': optional: true - '@esbuild/win32-arm64@0.23.0': - optional: true - '@esbuild/win32-arm64@0.23.1': optional: true - '@esbuild/win32-ia32@0.19.12': + '@esbuild/win32-arm64@0.24.0': optional: true '@esbuild/win32-ia32@0.21.5': optional: true - '@esbuild/win32-ia32@0.23.0': - optional: true - '@esbuild/win32-ia32@0.23.1': optional: true - '@esbuild/win32-x64@0.19.12': + '@esbuild/win32-ia32@0.24.0': optional: true '@esbuild/win32-x64@0.21.5': optional: true - '@esbuild/win32-x64@0.23.0': + '@esbuild/win32-x64@0.23.1': optional: true - '@esbuild/win32-x64@0.23.1': + '@esbuild/win32-x64@0.24.0': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)': + '@eslint-community/eslint-utils@4.4.0(eslint@8.57.1)': dependencies: - eslint: 8.57.0 + eslint: 8.57.1 eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.10.1': {} + '@eslint-community/regexpp@4.11.1': {} '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 - debug: 4.3.5 + debug: 4.3.7(supports-color@8.1.1) espree: 9.6.1 globals: 13.24.0 - ignore: 5.3.1 + ignore: 5.3.2 import-fresh: 3.3.0 js-yaml: 4.1.0 minimatch: 3.1.2 @@ -5450,14 +4552,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@8.57.0': {} + '@eslint/js@8.57.1': {} '@exodus/schemasafe@1.3.0': {} - '@humanwhocodes/config-array@0.11.14': + '@humanwhocodes/config-array@0.13.0': dependencies: '@humanwhocodes/object-schema': 2.0.3 - debug: 4.3.5 + debug: 4.3.7(supports-color@8.1.1) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -5481,42 +4583,34 @@ snapshots: dependencies: '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 18.19.34 + '@types/node': 18.19.59 '@types/yargs': 15.0.19 chalk: 4.1.2 - '@jridgewell/gen-mapping@0.3.5': - dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.25 - '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/set-array@1.2.1': {} - - '@jridgewell/sourcemap-codec@1.4.15': {} + '@jridgewell/sourcemap-codec@1.5.0': {} '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/sourcemap-codec': 1.5.0 - '@jsonjoy.com/base64@1.1.2(tslib@2.7.0)': + '@jsonjoy.com/base64@1.1.2(tslib@2.8.0)': dependencies: - tslib: 2.7.0 + tslib: 2.8.0 - '@jsonjoy.com/json-pack@1.1.0(tslib@2.7.0)': + '@jsonjoy.com/json-pack@1.1.0(tslib@2.8.0)': dependencies: - '@jsonjoy.com/base64': 1.1.2(tslib@2.7.0) - '@jsonjoy.com/util': 1.3.0(tslib@2.7.0) + '@jsonjoy.com/base64': 1.1.2(tslib@2.8.0) + '@jsonjoy.com/util': 1.5.0(tslib@2.8.0) hyperdyperid: 1.2.0 - thingies: 1.21.0(tslib@2.7.0) - tslib: 2.7.0 + thingies: 1.21.0(tslib@2.8.0) + tslib: 2.8.0 - '@jsonjoy.com/util@1.3.0(tslib@2.7.0)': + '@jsonjoy.com/util@1.5.0(tslib@2.8.0)': dependencies: - tslib: 2.7.0 + tslib: 2.8.0 '@nodelib/fs.scandir@2.1.5': dependencies: @@ -5535,115 +4629,61 @@ snapshots: '@pkgr/core@0.1.1': {} - '@rollup/plugin-alias@5.1.0(rollup@3.29.4)': - dependencies: - slash: 4.0.0 - optionalDependencies: - rollup: 3.29.4 - - '@rollup/plugin-commonjs@25.0.8(rollup@3.29.4)': - dependencies: - '@rollup/pluginutils': 5.1.0(rollup@3.29.4) - commondir: 1.0.1 - estree-walker: 2.0.2 - glob: 8.1.0 - is-reference: 1.2.1 - magic-string: 0.30.10 - optionalDependencies: - rollup: 3.29.4 - - '@rollup/plugin-json@6.1.0(rollup@3.29.4)': - dependencies: - '@rollup/pluginutils': 5.1.0(rollup@3.29.4) - optionalDependencies: - rollup: 3.29.4 - - '@rollup/plugin-node-resolve@15.2.3(rollup@3.29.4)': - dependencies: - '@rollup/pluginutils': 5.1.0(rollup@3.29.4) - '@types/resolve': 1.20.2 - deepmerge: 4.3.1 - is-builtin-module: 3.2.1 - is-module: 1.0.0 - resolve: 1.22.8 - optionalDependencies: - rollup: 3.29.4 - - '@rollup/plugin-replace@5.0.7(rollup@3.29.4)': - dependencies: - '@rollup/pluginutils': 5.1.0(rollup@3.29.4) - magic-string: 0.30.10 - optionalDependencies: - rollup: 3.29.4 - - '@rollup/pluginutils@5.1.0(rollup@3.29.4)': - dependencies: - '@types/estree': 1.0.5 - estree-walker: 2.0.2 - picomatch: 2.3.1 - optionalDependencies: - rollup: 3.29.4 - - '@rollup/rollup-android-arm-eabi@4.21.2': + '@rollup/rollup-android-arm-eabi@4.24.0': optional: true - '@rollup/rollup-android-arm64@4.21.2': + '@rollup/rollup-android-arm64@4.24.0': optional: true - '@rollup/rollup-darwin-arm64@4.21.2': + '@rollup/rollup-darwin-arm64@4.24.0': optional: true - '@rollup/rollup-darwin-x64@4.21.2': + '@rollup/rollup-darwin-x64@4.24.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.21.2': + '@rollup/rollup-linux-arm-gnueabihf@4.24.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.21.2': + '@rollup/rollup-linux-arm-musleabihf@4.24.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.21.2': + '@rollup/rollup-linux-arm64-gnu@4.24.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.21.2': + '@rollup/rollup-linux-arm64-musl@4.24.0': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.21.2': + '@rollup/rollup-linux-powerpc64le-gnu@4.24.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.21.2': + '@rollup/rollup-linux-riscv64-gnu@4.24.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.21.2': + '@rollup/rollup-linux-s390x-gnu@4.24.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.21.2': + '@rollup/rollup-linux-x64-gnu@4.24.0': optional: true - '@rollup/rollup-linux-x64-musl@4.21.2': + '@rollup/rollup-linux-x64-musl@4.24.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.21.2': + '@rollup/rollup-win32-arm64-msvc@4.24.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.21.2': + '@rollup/rollup-win32-ia32-msvc@4.24.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.21.2': + '@rollup/rollup-win32-x64-msvc@4.24.0': optional: true - '@trysound/sax@0.2.0': {} + '@rtsao/scc@1.1.0': {} '@types/conventional-commits-parser@5.0.0': dependencies: - '@types/node': 18.19.34 - - '@types/estree@1.0.5': {} + '@types/node': 18.19.59 - '@types/fs-extra@11.0.4': - dependencies: - '@types/jsonfile': 6.1.4 - '@types/node': 18.19.34 + '@types/estree@1.0.6': {} '@types/istanbul-lib-coverage@2.0.6': {} @@ -5664,27 +4704,16 @@ snapshots: '@types/json5@0.0.29': {} - '@types/jsonfile@6.1.4': - dependencies: - '@types/node': 18.19.34 - - '@types/lodash@4.17.5': {} - - '@types/mocha@10.0.6': {} + '@types/lodash@4.17.12': {} - '@types/node-fetch@2.6.11': - dependencies: - '@types/node': 18.19.34 - form-data: 4.0.0 + '@types/mocha@10.0.9': {} - '@types/node@18.19.34': + '@types/node@18.19.59': dependencies: undici-types: 5.26.5 '@types/parse-json@4.0.2': {} - '@types/resolve@1.20.2': {} - '@types/rimraf@4.0.5': dependencies: rimraf: 6.0.1 @@ -5693,10 +4722,10 @@ snapshots: '@types/swagger2openapi@7.0.4': dependencies: - '@types/node': 18.19.34 + '@types/node': 18.19.59 openapi-types: 12.1.3 - '@types/vscode@1.90.0': {} + '@types/vscode@1.94.0': {} '@types/yargs-parser@21.0.3': {} @@ -5704,141 +4733,148 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)': + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3)': dependencies: - '@eslint-community/regexpp': 4.10.1 - '@typescript-eslint/parser': 7.13.0(eslint@8.57.0)(typescript@5.5.4) - '@typescript-eslint/scope-manager': 7.13.0 - '@typescript-eslint/type-utils': 7.13.0(eslint@8.57.0)(typescript@5.5.4) - '@typescript-eslint/utils': 7.13.0(eslint@8.57.0)(typescript@5.5.4) - '@typescript-eslint/visitor-keys': 7.13.0 - eslint: 8.57.0 + '@eslint-community/regexpp': 4.11.1 + '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 7.18.0 + eslint: 8.57.1 graphemer: 1.4.0 - ignore: 5.3.1 + ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 1.3.0(typescript@5.5.4) + ts-api-utils: 1.3.0(typescript@5.6.3) optionalDependencies: - typescript: 5.5.4 + typescript: 5.6.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4)': + '@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3)': dependencies: - '@typescript-eslint/scope-manager': 7.13.0 - '@typescript-eslint/types': 7.13.0 - '@typescript-eslint/typescript-estree': 7.13.0(typescript@5.5.4) - '@typescript-eslint/visitor-keys': 7.13.0 - debug: 4.3.5 - eslint: 8.57.0 + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 7.18.0 + debug: 4.3.7(supports-color@8.1.1) + eslint: 8.57.1 optionalDependencies: - typescript: 5.5.4 + typescript: 5.6.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@7.13.0': + '@typescript-eslint/scope-manager@7.18.0': dependencies: - '@typescript-eslint/types': 7.13.0 - '@typescript-eslint/visitor-keys': 7.13.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/visitor-keys': 7.18.0 - '@typescript-eslint/type-utils@7.13.0(eslint@8.57.0)(typescript@5.5.4)': + '@typescript-eslint/type-utils@7.18.0(eslint@8.57.1)(typescript@5.6.3)': dependencies: - '@typescript-eslint/typescript-estree': 7.13.0(typescript@5.5.4) - '@typescript-eslint/utils': 7.13.0(eslint@8.57.0)(typescript@5.5.4) - debug: 4.3.5 - eslint: 8.57.0 - ts-api-utils: 1.3.0(typescript@5.5.4) + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.3) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.6.3) + debug: 4.3.7(supports-color@8.1.1) + eslint: 8.57.1 + ts-api-utils: 1.3.0(typescript@5.6.3) optionalDependencies: - typescript: 5.5.4 + typescript: 5.6.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@7.13.0': {} + '@typescript-eslint/types@7.18.0': {} - '@typescript-eslint/typescript-estree@7.13.0(typescript@5.5.4)': + '@typescript-eslint/typescript-estree@7.18.0(typescript@5.6.3)': dependencies: - '@typescript-eslint/types': 7.13.0 - '@typescript-eslint/visitor-keys': 7.13.0 - debug: 4.3.5 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/visitor-keys': 7.18.0 + debug: 4.3.7(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 - minimatch: 9.0.4 - semver: 7.6.2 - ts-api-utils: 1.3.0(typescript@5.5.4) + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.6.3) optionalDependencies: - typescript: 5.5.4 + typescript: 5.6.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@7.13.0(eslint@8.57.0)(typescript@5.5.4)': + '@typescript-eslint/utils@7.18.0(eslint@8.57.1)(typescript@5.6.3)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@typescript-eslint/scope-manager': 7.13.0 - '@typescript-eslint/types': 7.13.0 - '@typescript-eslint/typescript-estree': 7.13.0(typescript@5.5.4) - eslint: 8.57.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.3) + eslint: 8.57.1 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/visitor-keys@7.13.0': + '@typescript-eslint/visitor-keys@7.18.0': dependencies: - '@typescript-eslint/types': 7.13.0 + '@typescript-eslint/types': 7.18.0 eslint-visitor-keys: 3.4.3 '@ungap/structured-clone@1.2.0': {} - '@vitest/expect@2.0.5': + '@vitest/expect@2.1.3': dependencies: - '@vitest/spy': 2.0.5 - '@vitest/utils': 2.0.5 - chai: 5.1.1 + '@vitest/spy': 2.1.3 + '@vitest/utils': 2.1.3 + chai: 5.1.2 tinyrainbow: 1.2.0 - '@vitest/pretty-format@2.0.5': + '@vitest/mocker@2.1.3(@vitest/spy@2.1.3)(vite@5.4.10(@types/node@18.19.59))': + dependencies: + '@vitest/spy': 2.1.3 + estree-walker: 3.0.3 + magic-string: 0.30.12 + optionalDependencies: + vite: 5.4.10(@types/node@18.19.59) + + '@vitest/pretty-format@2.1.3': dependencies: tinyrainbow: 1.2.0 - '@vitest/runner@2.0.5': + '@vitest/runner@2.1.3': dependencies: - '@vitest/utils': 2.0.5 + '@vitest/utils': 2.1.3 pathe: 1.1.2 - '@vitest/snapshot@2.0.5': + '@vitest/snapshot@2.1.3': dependencies: - '@vitest/pretty-format': 2.0.5 - magic-string: 0.30.10 + '@vitest/pretty-format': 2.1.3 + magic-string: 0.30.12 pathe: 1.1.2 - '@vitest/spy@2.0.5': + '@vitest/spy@2.1.3': dependencies: tinyspy: 3.0.2 - '@vitest/utils@2.0.5': + '@vitest/utils@2.1.3': dependencies: - '@vitest/pretty-format': 2.0.5 - estree-walker: 3.0.3 - loupe: 3.1.1 + '@vitest/pretty-format': 2.1.3 + loupe: 3.1.2 tinyrainbow: 1.2.0 '@vscode/test-cli@0.0.9': dependencies: - '@types/mocha': 10.0.6 + '@types/mocha': 10.0.9 c8: 9.1.0 chokidar: 3.6.0 - enhanced-resolve: 5.17.0 - glob: 10.4.1 - minimatch: 9.0.4 - mocha: 10.4.0 + enhanced-resolve: 5.17.1 + glob: 10.4.5 + minimatch: 9.0.5 + mocha: 10.7.3 supports-color: 9.4.0 yargs: 17.7.2 - '@vscode/test-electron@2.4.0': + '@vscode/test-electron@2.4.1': dependencies: http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.4 + https-proxy-agent: 7.0.5 jszip: 3.10.1 ora: 7.0.1 - semver: 7.6.2 + semver: 7.6.3 transitivePeerDependencies: - supports-color @@ -5881,16 +4917,16 @@ snapshots: '@vscode/vsce-sign-win32-arm64': 2.0.2 '@vscode/vsce-sign-win32-x64': 2.0.2 - '@vscode/vsce@2.30.0': + '@vscode/vsce@2.32.0': dependencies: - '@azure/identity': 4.3.0 + '@azure/identity': 4.5.0 '@vscode/vsce-sign': 2.0.4 azure-devops-node-api: 12.5.0 chalk: 2.4.2 - cheerio: 1.0.0-rc.12 - cockatiel: 3.1.3 + cheerio: 1.0.0 + cockatiel: 3.2.1 commander: 6.2.1 - form-data: 4.0.0 + form-data: 4.0.1 glob: 7.2.3 hosted-git-info: 4.1.0 jsonc-parser: 3.3.1 @@ -5900,7 +4936,7 @@ snapshots: minimatch: 3.1.2 parse-semver: 1.1.1 read: 1.0.7 - semver: 7.6.2 + semver: 7.6.3 tmp: 0.2.3 typed-rest-client: 1.8.11 url-join: 4.0.1 @@ -5912,80 +4948,74 @@ snapshots: transitivePeerDependencies: - supports-color - '@vue/compiler-core@3.4.31': + '@vue/compiler-core@3.5.12': dependencies: - '@babel/parser': 7.24.7 - '@vue/shared': 3.4.31 + '@babel/parser': 7.25.9 + '@vue/shared': 3.5.12 entities: 4.5.0 estree-walker: 2.0.2 - source-map-js: 1.2.0 + source-map-js: 1.2.1 - '@vue/compiler-dom@3.4.31': + '@vue/compiler-dom@3.5.12': dependencies: - '@vue/compiler-core': 3.4.31 - '@vue/shared': 3.4.31 + '@vue/compiler-core': 3.5.12 + '@vue/shared': 3.5.12 - '@vue/compiler-sfc@3.4.31': + '@vue/compiler-sfc@3.5.12': dependencies: - '@babel/parser': 7.24.7 - '@vue/compiler-core': 3.4.31 - '@vue/compiler-dom': 3.4.31 - '@vue/compiler-ssr': 3.4.31 - '@vue/shared': 3.4.31 + '@babel/parser': 7.25.9 + '@vue/compiler-core': 3.5.12 + '@vue/compiler-dom': 3.5.12 + '@vue/compiler-ssr': 3.5.12 + '@vue/shared': 3.5.12 estree-walker: 2.0.2 - magic-string: 0.30.10 - postcss: 8.4.39 - source-map-js: 1.2.0 + magic-string: 0.30.12 + postcss: 8.4.47 + source-map-js: 1.2.1 - '@vue/compiler-ssr@3.4.31': + '@vue/compiler-ssr@3.5.12': dependencies: - '@vue/compiler-dom': 3.4.31 - '@vue/shared': 3.4.31 + '@vue/compiler-dom': 3.5.12 + '@vue/shared': 3.5.12 - '@vue/reactivity@3.4.31': + '@vue/reactivity@3.5.12': dependencies: - '@vue/shared': 3.4.31 + '@vue/shared': 3.5.12 - '@vue/runtime-core@3.4.31': + '@vue/runtime-core@3.5.12': dependencies: - '@vue/reactivity': 3.4.31 - '@vue/shared': 3.4.31 + '@vue/reactivity': 3.5.12 + '@vue/shared': 3.5.12 - '@vue/runtime-dom@3.4.31': + '@vue/runtime-dom@3.5.12': dependencies: - '@vue/reactivity': 3.4.31 - '@vue/runtime-core': 3.4.31 - '@vue/shared': 3.4.31 + '@vue/reactivity': 3.5.12 + '@vue/runtime-core': 3.5.12 + '@vue/shared': 3.5.12 csstype: 3.1.3 - '@vue/server-renderer@3.4.31(vue@3.4.31(typescript@5.4.5))': + '@vue/server-renderer@3.5.12(vue@3.5.12(typescript@5.6.3))': dependencies: - '@vue/compiler-ssr': 3.4.31 - '@vue/shared': 3.4.31 - vue: 3.4.31(typescript@5.4.5) + '@vue/compiler-ssr': 3.5.12 + '@vue/shared': 3.5.12 + vue: 3.5.12(typescript@5.6.3) - '@vue/server-renderer@3.4.31(vue@3.4.31(typescript@5.5.4))': - dependencies: - '@vue/compiler-ssr': 3.4.31 - '@vue/shared': 3.4.31 - vue: 3.4.31(typescript@5.5.4) - - '@vue/shared@3.4.31': {} + '@vue/shared@3.5.12': {} JSONStream@1.3.5: dependencies: jsonparse: 1.3.1 through: 2.3.8 - acorn-jsx@5.3.2(acorn@8.11.3): + acorn-jsx@5.3.2(acorn@8.13.0): dependencies: - acorn: 8.11.3 + acorn: 8.13.0 - acorn@8.11.3: {} + acorn@8.13.0: {} agent-base@7.1.1: dependencies: - debug: 4.3.5 + debug: 4.3.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -5996,14 +5026,14 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 - ajv@8.16.0: + ajv@8.17.1: dependencies: fast-deep-equal: 3.1.3 + fast-uri: 3.0.3 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - uri-js: 4.4.1 - alova@2.21.3: {} + alova@2.21.5: {} alova@3.0.0-beta.10: dependencies: @@ -6011,20 +5041,27 @@ snapshots: alova@3.0.5: dependencies: - '@alova/shared': 1.0.4 - rate-limiter-flexible: 5.0.3 + '@alova/shared': 1.0.7 + rate-limiter-flexible: 5.0.4 + + alova@3.1.1: + dependencies: + '@alova/shared': 1.0.7 + rate-limiter-flexible: 5.0.4 - ansi-colors@4.1.1: {} + ansi-colors@4.1.3: {} ansi-escapes@4.3.2: dependencies: type-fest: 0.21.3 - ansi-escapes@6.2.1: {} + ansi-escapes@7.0.0: + dependencies: + environment: 1.1.0 ansi-regex@5.0.1: {} - ansi-regex@6.0.1: {} + ansi-regex@6.1.0: {} ansi-styles@3.2.1: dependencies: @@ -6047,9 +5084,7 @@ snapshots: argparse@2.0.1: {} - aria-query@5.3.0: - dependencies: - dequal: 2.0.3 + aria-query@5.3.2: {} array-buffer-byte-length@1.0.1: dependencies: @@ -6101,13 +5136,6 @@ snapshots: es-abstract: 1.23.3 es-shim-unscopables: 1.0.2 - array.prototype.toreversed@1.1.2: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.23.3 - es-shim-unscopables: 1.0.2 - array.prototype.tosorted@1.1.4: dependencies: call-bind: 1.0.7 @@ -6135,25 +5163,13 @@ snapshots: at-least-node@1.0.0: {} - autoprefixer@10.4.20(postcss@8.4.45): - dependencies: - browserslist: 4.23.3 - caniuse-lite: 1.0.30001658 - fraction.js: 4.3.7 - normalize-range: 0.1.2 - picocolors: 1.0.1 - postcss: 8.4.45 - postcss-value-parser: 4.2.0 - available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.0.0 - axe-core@4.7.0: {} + axe-core@4.10.2: {} - axobject-query@3.2.1: - dependencies: - dequal: 2.0.3 + axobject-query@4.1.0: {} azure-devops-node-api@12.5.0: dependencies: @@ -6195,13 +5211,6 @@ snapshots: browser-stdout@1.3.1: {} - browserslist@4.23.3: - dependencies: - caniuse-lite: 1.0.30001658 - electron-to-chromium: 1.5.16 - node-releases: 2.0.18 - update-browserslist-db: 1.1.0(browserslist@4.23.3) - buffer-crc32@0.2.13: {} buffer-equal-constant-time@1.0.1: {} @@ -6216,19 +5225,17 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 - builtin-modules@3.3.0: {} - c8@9.1.0: dependencies: '@bcoe/v8-coverage': 0.2.3 '@istanbuljs/schema': 0.1.3 find-up: 5.0.0 - foreground-child: 3.2.0 + foreground-child: 3.3.0 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-reports: 3.1.7 test-exclude: 6.0.0 - v8-to-istanbul: 9.2.0 + v8-to-istanbul: 9.3.0 yargs: 17.7.2 yargs-parser: 21.1.1 @@ -6251,31 +5258,22 @@ snapshots: camel-case@4.1.2: dependencies: pascal-case: 3.1.2 - tslib: 2.6.3 + tslib: 2.8.0 camelcase@6.3.0: {} - caniuse-api@3.0.0: - dependencies: - browserslist: 4.23.3 - caniuse-lite: 1.0.30001658 - lodash.memoize: 4.1.2 - lodash.uniq: 4.5.0 - - caniuse-lite@1.0.30001658: {} - capital-case@1.0.4: dependencies: no-case: 3.0.4 - tslib: 2.6.3 + tslib: 2.8.0 upper-case-first: 2.0.2 - chai@5.1.1: + chai@5.1.2: dependencies: assertion-error: 2.0.1 check-error: 2.1.1 deep-eql: 5.0.2 - loupe: 3.1.1 + loupe: 3.1.2 pathval: 2.0.0 chalk@2.4.2: @@ -6304,7 +5302,7 @@ snapshots: path-case: 3.0.4 sentence-case: 3.0.4 snake-case: 3.0.4 - tslib: 2.6.3 + tslib: 2.8.0 chardet@0.7.0: {} @@ -6319,28 +5317,20 @@ snapshots: domhandler: 5.0.3 domutils: 3.1.0 - cheerio@1.0.0-rc.12: - dependencies: - cheerio-select: 2.1.0 - dom-serializer: 2.0.0 - domhandler: 5.0.3 - domutils: 3.1.0 - htmlparser2: 8.0.2 - parse5: 7.1.2 - parse5-htmlparser2-tree-adapter: 7.0.0 - - chokidar@3.5.3: - dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - + cheerio@1.0.0: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.1.0 + encoding-sniffer: 0.2.0 + htmlparser2: 9.1.0 + parse5: 7.2.0 + parse5-htmlparser2-tree-adapter: 7.1.0 + parse5-parser-stream: 7.1.2 + undici: 6.20.1 + whatwg-mimetype: 4.0.0 + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -6356,10 +5346,6 @@ snapshots: chownr@1.1.4: optional: true - citty@0.1.6: - dependencies: - consola: 3.2.3 - cli-cursor@3.1.0: dependencies: restore-cursor: 3.1.0 @@ -6368,12 +5354,16 @@ snapshots: dependencies: restore-cursor: 4.0.0 + cli-cursor@5.0.0: + dependencies: + restore-cursor: 5.1.0 + cli-spinners@2.9.2: {} cli-truncate@4.0.0: dependencies: slice-ansi: 5.0.0 - string-width: 7.1.0 + string-width: 7.2.0 cli-width@3.0.0: {} @@ -6391,7 +5381,7 @@ snapshots: clone@1.0.4: {} - cockatiel@3.1.3: {} + cockatiel@3.2.1: {} color-convert@1.9.3: dependencies: @@ -6405,8 +5395,6 @@ snapshots: color-name@1.1.4: {} - colord@2.9.3: {} - colorette@2.0.20: {} combined-stream@1.0.8: @@ -6417,12 +5405,10 @@ snapshots: commander@6.2.1: {} - commander@7.2.0: {} - - commitizen@4.3.0(@types/node@18.19.34)(typescript@5.5.4): + commitizen@4.3.1(@types/node@18.19.59)(typescript@5.6.3): dependencies: cachedir: 2.3.0 - cz-conventional-changelog: 3.3.0(@types/node@18.19.34)(typescript@5.5.4) + cz-conventional-changelog: 3.3.0(@types/node@18.19.59)(typescript@5.6.3) dedent: 0.7.0 detect-indent: 6.1.0 find-node-modules: 2.1.3 @@ -6439,8 +5425,6 @@ snapshots: - '@types/node' - typescript - commondir@1.0.1: {} - compare-func@2.0.0: dependencies: array-ify: 1.0.0 @@ -6448,16 +5432,12 @@ snapshots: concat-map@0.0.1: {} - confbox@0.1.7: {} - confusing-browser-globals@1.0.11: {} - consola@3.2.3: {} - constant-case@3.0.4: dependencies: no-case: 3.0.4 - tslib: 2.6.3 + tslib: 2.8.0 upper-case: 2.0.2 conventional-changelog-angular@7.0.0: @@ -6481,12 +5461,12 @@ snapshots: core-util-is@1.0.3: {} - cosmiconfig-typescript-loader@5.0.0(@types/node@18.19.34)(cosmiconfig@9.0.0(typescript@5.5.4))(typescript@5.5.4): + cosmiconfig-typescript-loader@5.1.0(@types/node@18.19.59)(cosmiconfig@9.0.0(typescript@5.6.3))(typescript@5.6.3): dependencies: - '@types/node': 18.19.34 - cosmiconfig: 9.0.0(typescript@5.5.4) + '@types/node': 18.19.59 + cosmiconfig: 9.0.0(typescript@5.6.3) jiti: 1.21.6 - typescript: 5.5.4 + typescript: 5.6.3 cosmiconfig@6.0.0: dependencies: @@ -6496,14 +5476,14 @@ snapshots: path-type: 4.0.0 yaml: 1.10.2 - cosmiconfig@9.0.0(typescript@5.5.4): + cosmiconfig@9.0.0(typescript@5.6.3): dependencies: env-paths: 2.2.1 import-fresh: 3.3.0 js-yaml: 4.1.0 parse-json: 5.2.0 optionalDependencies: - typescript: 5.5.4 + typescript: 5.6.3 cross-spawn@6.0.5: dependencies: @@ -6519,10 +5499,6 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - css-declaration-sorter@7.2.0(postcss@8.4.45): - dependencies: - postcss: 8.4.45 - css-select@5.1.0: dependencies: boolbase: 1.0.0 @@ -6531,80 +5507,20 @@ snapshots: domutils: 3.1.0 nth-check: 2.1.1 - css-tree@2.2.1: - dependencies: - mdn-data: 2.0.28 - source-map-js: 1.2.0 - - css-tree@2.3.1: - dependencies: - mdn-data: 2.0.30 - source-map-js: 1.2.0 - css-what@6.1.0: {} - cssesc@3.0.0: {} - - cssnano-preset-default@7.0.6(postcss@8.4.45): - dependencies: - browserslist: 4.23.3 - css-declaration-sorter: 7.2.0(postcss@8.4.45) - cssnano-utils: 5.0.0(postcss@8.4.45) - postcss: 8.4.45 - postcss-calc: 10.0.2(postcss@8.4.45) - postcss-colormin: 7.0.2(postcss@8.4.45) - postcss-convert-values: 7.0.4(postcss@8.4.45) - postcss-discard-comments: 7.0.3(postcss@8.4.45) - postcss-discard-duplicates: 7.0.1(postcss@8.4.45) - postcss-discard-empty: 7.0.0(postcss@8.4.45) - postcss-discard-overridden: 7.0.0(postcss@8.4.45) - postcss-merge-longhand: 7.0.4(postcss@8.4.45) - postcss-merge-rules: 7.0.4(postcss@8.4.45) - postcss-minify-font-values: 7.0.0(postcss@8.4.45) - postcss-minify-gradients: 7.0.0(postcss@8.4.45) - postcss-minify-params: 7.0.2(postcss@8.4.45) - postcss-minify-selectors: 7.0.4(postcss@8.4.45) - postcss-normalize-charset: 7.0.0(postcss@8.4.45) - postcss-normalize-display-values: 7.0.0(postcss@8.4.45) - postcss-normalize-positions: 7.0.0(postcss@8.4.45) - postcss-normalize-repeat-style: 7.0.0(postcss@8.4.45) - postcss-normalize-string: 7.0.0(postcss@8.4.45) - postcss-normalize-timing-functions: 7.0.0(postcss@8.4.45) - postcss-normalize-unicode: 7.0.2(postcss@8.4.45) - postcss-normalize-url: 7.0.0(postcss@8.4.45) - postcss-normalize-whitespace: 7.0.0(postcss@8.4.45) - postcss-ordered-values: 7.0.1(postcss@8.4.45) - postcss-reduce-initial: 7.0.2(postcss@8.4.45) - postcss-reduce-transforms: 7.0.0(postcss@8.4.45) - postcss-svgo: 7.0.1(postcss@8.4.45) - postcss-unique-selectors: 7.0.3(postcss@8.4.45) - - cssnano-utils@5.0.0(postcss@8.4.45): - dependencies: - postcss: 8.4.45 - - cssnano@7.0.6(postcss@8.4.45): - dependencies: - cssnano-preset-default: 7.0.6(postcss@8.4.45) - lilconfig: 3.1.2 - postcss: 8.4.45 - - csso@5.0.5: - dependencies: - css-tree: 2.2.1 - csstype@3.1.3: {} - cz-conventional-changelog@3.3.0(@types/node@18.19.34)(typescript@5.5.4): + cz-conventional-changelog@3.3.0(@types/node@18.19.59)(typescript@5.6.3): dependencies: chalk: 2.4.2 - commitizen: 4.3.0(@types/node@18.19.34)(typescript@5.5.4) + commitizen: 4.3.1(@types/node@18.19.59)(typescript@5.6.3) conventional-commit-types: 3.0.0 lodash.map: 4.6.0 longest: 2.0.1 word-wrap: 1.2.5 optionalDependencies: - '@commitlint/load': 19.2.0(@types/node@18.19.34)(typescript@5.5.4) + '@commitlint/load': 19.5.0(@types/node@18.19.59)(typescript@5.6.3) transitivePeerDependencies: - '@types/node' - typescript @@ -6635,16 +5551,12 @@ snapshots: dependencies: ms: 2.1.3 - debug@4.3.4(supports-color@8.1.1): + debug@4.3.7(supports-color@8.1.1): dependencies: - ms: 2.1.2 + ms: 2.1.3 optionalDependencies: supports-color: 8.1.1 - debug@4.3.5: - dependencies: - ms: 2.1.2 - decamelize@4.0.0: {} decompress-response@6.0.0: @@ -6661,8 +5573,6 @@ snapshots: deep-is@0.1.4: {} - deepmerge@4.3.1: {} - defaults@1.0.4: dependencies: clone: 1.0.4 @@ -6681,12 +5591,8 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 - defu@6.1.4: {} - delayed-stream@1.0.0: {} - dequal@2.0.3: {} - detect-file@1.0.0: {} detect-indent@6.1.0: {} @@ -6696,7 +5602,7 @@ snapshots: diff-sequences@26.6.2: {} - diff@5.0.0: {} + diff@5.2.0: {} dir-glob@3.0.1: dependencies: @@ -6731,32 +5637,40 @@ snapshots: dot-case@3.0.4: dependencies: no-case: 3.0.4 - tslib: 2.6.3 + tslib: 2.8.0 dot-prop@5.3.0: dependencies: is-obj: 2.0.0 + dts-bundle-generator@9.5.1: + dependencies: + typescript: 5.6.3 + yargs: 17.7.2 + eastasianwidth@0.2.0: {} ecdsa-sig-formatter@1.0.11: dependencies: safe-buffer: 5.2.1 - electron-to-chromium@1.5.16: {} - - emoji-regex@10.3.0: {} + emoji-regex@10.4.0: {} emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} + encoding-sniffer@0.2.0: + dependencies: + iconv-lite: 0.6.3 + whatwg-encoding: 3.1.1 + end-of-stream@1.4.4: dependencies: once: 1.4.0 optional: true - enhanced-resolve@5.17.0: + enhanced-resolve@5.17.1: dependencies: graceful-fs: 4.2.11 tapable: 2.2.1 @@ -6767,6 +5681,8 @@ snapshots: env-paths@2.2.1: {} + environment@1.1.0: {} + error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 @@ -6804,10 +5720,10 @@ snapshots: is-string: 1.0.7 is-typed-array: 1.1.13 is-weakref: 1.0.2 - object-inspect: 1.13.1 + object-inspect: 1.13.2 object-keys: 1.1.1 object.assign: 4.1.5 - regexp.prototype.flags: 1.5.2 + regexp.prototype.flags: 1.5.3 safe-array-concat: 1.1.2 safe-regex-test: 1.0.3 string.prototype.trim: 1.2.9 @@ -6826,7 +5742,7 @@ snapshots: es-errors@1.3.0: {} - es-iterator-helpers@1.0.19: + es-iterator-helpers@1.1.0: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 @@ -6840,7 +5756,7 @@ snapshots: has-proto: 1.0.3 has-symbols: 1.0.3 internal-slot: 1.0.7 - iterator.prototype: 1.1.2 + iterator.prototype: 1.1.3 safe-array-concat: 1.1.2 es-object-atoms@1.0.0: @@ -6865,34 +5781,6 @@ snapshots: es6-promise@3.3.1: {} - esbuild-plugin-alias@0.2.1: {} - - esbuild@0.19.12: - optionalDependencies: - '@esbuild/aix-ppc64': 0.19.12 - '@esbuild/android-arm': 0.19.12 - '@esbuild/android-arm64': 0.19.12 - '@esbuild/android-x64': 0.19.12 - '@esbuild/darwin-arm64': 0.19.12 - '@esbuild/darwin-x64': 0.19.12 - '@esbuild/freebsd-arm64': 0.19.12 - '@esbuild/freebsd-x64': 0.19.12 - '@esbuild/linux-arm': 0.19.12 - '@esbuild/linux-arm64': 0.19.12 - '@esbuild/linux-ia32': 0.19.12 - '@esbuild/linux-loong64': 0.19.12 - '@esbuild/linux-mips64el': 0.19.12 - '@esbuild/linux-ppc64': 0.19.12 - '@esbuild/linux-riscv64': 0.19.12 - '@esbuild/linux-s390x': 0.19.12 - '@esbuild/linux-x64': 0.19.12 - '@esbuild/netbsd-x64': 0.19.12 - '@esbuild/openbsd-x64': 0.19.12 - '@esbuild/sunos-x64': 0.19.12 - '@esbuild/win32-arm64': 0.19.12 - '@esbuild/win32-ia32': 0.19.12 - '@esbuild/win32-x64': 0.19.12 - esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 @@ -6919,33 +5807,6 @@ snapshots: '@esbuild/win32-ia32': 0.21.5 '@esbuild/win32-x64': 0.21.5 - esbuild@0.23.0: - optionalDependencies: - '@esbuild/aix-ppc64': 0.23.0 - '@esbuild/android-arm': 0.23.0 - '@esbuild/android-arm64': 0.23.0 - '@esbuild/android-x64': 0.23.0 - '@esbuild/darwin-arm64': 0.23.0 - '@esbuild/darwin-x64': 0.23.0 - '@esbuild/freebsd-arm64': 0.23.0 - '@esbuild/freebsd-x64': 0.23.0 - '@esbuild/linux-arm': 0.23.0 - '@esbuild/linux-arm64': 0.23.0 - '@esbuild/linux-ia32': 0.23.0 - '@esbuild/linux-loong64': 0.23.0 - '@esbuild/linux-mips64el': 0.23.0 - '@esbuild/linux-ppc64': 0.23.0 - '@esbuild/linux-riscv64': 0.23.0 - '@esbuild/linux-s390x': 0.23.0 - '@esbuild/linux-x64': 0.23.0 - '@esbuild/netbsd-x64': 0.23.0 - '@esbuild/openbsd-arm64': 0.23.0 - '@esbuild/openbsd-x64': 0.23.0 - '@esbuild/sunos-x64': 0.23.0 - '@esbuild/win32-arm64': 0.23.0 - '@esbuild/win32-ia32': 0.23.0 - '@esbuild/win32-x64': 0.23.0 - esbuild@0.23.1: optionalDependencies: '@esbuild/aix-ppc64': 0.23.1 @@ -6973,145 +5834,167 @@ snapshots: '@esbuild/win32-ia32': 0.23.1 '@esbuild/win32-x64': 0.23.1 - escalade@3.1.2: {} + esbuild@0.24.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.24.0 + '@esbuild/android-arm': 0.24.0 + '@esbuild/android-arm64': 0.24.0 + '@esbuild/android-x64': 0.24.0 + '@esbuild/darwin-arm64': 0.24.0 + '@esbuild/darwin-x64': 0.24.0 + '@esbuild/freebsd-arm64': 0.24.0 + '@esbuild/freebsd-x64': 0.24.0 + '@esbuild/linux-arm': 0.24.0 + '@esbuild/linux-arm64': 0.24.0 + '@esbuild/linux-ia32': 0.24.0 + '@esbuild/linux-loong64': 0.24.0 + '@esbuild/linux-mips64el': 0.24.0 + '@esbuild/linux-ppc64': 0.24.0 + '@esbuild/linux-riscv64': 0.24.0 + '@esbuild/linux-s390x': 0.24.0 + '@esbuild/linux-x64': 0.24.0 + '@esbuild/netbsd-x64': 0.24.0 + '@esbuild/openbsd-arm64': 0.24.0 + '@esbuild/openbsd-x64': 0.24.0 + '@esbuild/sunos-x64': 0.24.0 + '@esbuild/win32-arm64': 0.24.0 + '@esbuild/win32-ia32': 0.24.0 + '@esbuild/win32-x64': 0.24.0 + + escalade@3.2.0: {} escape-string-regexp@1.0.5: {} escape-string-regexp@4.0.0: {} - eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0))(eslint@8.57.0): + eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1): dependencies: confusing-browser-globals: 1.0.11 - eslint: 8.57.0 - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0) + eslint: 8.57.1 + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1) object.assign: 4.1.5 object.entries: 1.1.8 semver: 6.3.1 - eslint-config-airbnb-typescript@18.0.0(@typescript-eslint/eslint-plugin@7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4))(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0))(eslint@8.57.0): + eslint-config-airbnb-typescript@18.0.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1): dependencies: - '@typescript-eslint/eslint-plugin': 7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4) - '@typescript-eslint/parser': 7.13.0(eslint@8.57.0)(typescript@5.5.4) - eslint: 8.57.0 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0))(eslint@8.57.0) + '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.6.3) + eslint: 8.57.1 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1) transitivePeerDependencies: - eslint-plugin-import - eslint-config-airbnb@19.0.4(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react@7.34.2(eslint@8.57.0))(eslint@8.57.0): + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.1(eslint@8.57.1))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.1))(eslint-plugin-react@7.37.2(eslint@8.57.1))(eslint@8.57.1): dependencies: - eslint: 8.57.0 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0) - eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0) - eslint-plugin-react: 7.34.2(eslint@8.57.0) - eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) + eslint: 8.57.1 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1) + eslint-plugin-jsx-a11y: 6.10.1(eslint@8.57.1) + eslint-plugin-react: 7.37.2(eslint@8.57.1) + eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) object.assign: 4.1.5 object.entries: 1.1.8 - eslint-config-prettier@9.1.0(eslint@8.57.0): - dependencies: - eslint: 8.57.0 - optional: true - eslint-import-resolver-node@0.3.9: dependencies: debug: 3.2.7 - is-core-module: 2.13.1 + is-core-module: 2.15.1 resolve: 1.22.8 transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): + eslint-module-utils@2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 7.13.0(eslint@8.57.0)(typescript@5.5.4) - eslint: 8.57.0 + '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.6.3) + eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1): dependencies: + '@rtsao/scc': 1.1.0 array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 array.prototype.flat: 1.3.2 array.prototype.flatmap: 1.3.2 debug: 3.2.7 doctrine: 2.1.0 - eslint: 8.57.0 + eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) hasown: 2.0.2 - is-core-module: 2.13.1 + is-core-module: 2.15.1 is-glob: 4.0.3 minimatch: 3.1.2 object.fromentries: 2.0.8 object.groupby: 1.0.3 object.values: 1.2.0 semver: 6.3.1 + string.prototype.trimend: 1.0.8 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 7.13.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.6.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0): + eslint-plugin-jsx-a11y@6.10.1(eslint@8.57.1): dependencies: - '@babel/runtime': 7.24.7 - aria-query: 5.3.0 + aria-query: 5.3.2 array-includes: 3.1.8 array.prototype.flatmap: 1.3.2 ast-types-flow: 0.0.8 - axe-core: 4.7.0 - axobject-query: 3.2.1 + axe-core: 4.10.2 + axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - es-iterator-helpers: 1.0.19 - eslint: 8.57.0 + es-iterator-helpers: 1.1.0 + eslint: 8.57.1 hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 minimatch: 3.1.2 - object.entries: 1.1.8 object.fromentries: 2.0.8 + safe-regex-test: 1.0.3 + string.prototype.includes: 2.0.1 - eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.2): + eslint-plugin-prettier@5.2.1(eslint@8.57.1)(prettier@3.3.3): dependencies: - eslint: 8.57.0 - prettier: 3.3.2 + eslint: 8.57.1 + prettier: 3.3.3 prettier-linter-helpers: 1.0.0 - synckit: 0.8.8 - optionalDependencies: - eslint-config-prettier: 9.1.0(eslint@8.57.0) + synckit: 0.9.2 - eslint-plugin-react-hooks@4.6.2(eslint@8.57.0): + eslint-plugin-react-hooks@4.6.2(eslint@8.57.1): dependencies: - eslint: 8.57.0 + eslint: 8.57.1 - eslint-plugin-react@7.34.2(eslint@8.57.0): + eslint-plugin-react@7.37.2(eslint@8.57.1): dependencies: array-includes: 3.1.8 array.prototype.findlast: 1.2.5 array.prototype.flatmap: 1.3.2 - array.prototype.toreversed: 1.1.2 array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 - es-iterator-helpers: 1.0.19 - eslint: 8.57.0 + es-iterator-helpers: 1.1.0 + eslint: 8.57.1 estraverse: 5.3.0 + hasown: 2.0.2 jsx-ast-utils: 3.3.5 minimatch: 3.1.2 object.entries: 1.1.8 object.fromentries: 2.0.8 - object.hasown: 1.1.4 object.values: 1.2.0 prop-types: 15.8.1 resolve: 2.0.0-next.5 semver: 6.3.1 string.prototype.matchall: 4.0.11 + string.prototype.repeat: 1.0.0 eslint-scope@7.2.2: dependencies: @@ -7120,26 +6003,26 @@ snapshots: eslint-visitor-keys@3.4.3: {} - eslint@8.57.0: + eslint@8.57.1: dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@eslint-community/regexpp': 4.10.1 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + '@eslint-community/regexpp': 4.11.1 '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.57.0 - '@humanwhocodes/config-array': 0.11.14 + '@eslint/js': 8.57.1 + '@humanwhocodes/config-array': 0.13.0 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 '@ungap/structured-clone': 1.2.0 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.5 + debug: 4.3.7(supports-color@8.1.1) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 - esquery: 1.5.0 + esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 6.0.1 @@ -7147,7 +6030,7 @@ snapshots: glob-parent: 6.0.2 globals: 13.24.0 graphemer: 1.4.0 - ignore: 5.3.1 + ignore: 5.3.2 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 @@ -7165,13 +6048,13 @@ snapshots: espree@9.6.1: dependencies: - acorn: 8.11.3 - acorn-jsx: 5.3.2(acorn@8.11.3) + acorn: 8.13.0 + acorn-jsx: 5.3.2(acorn@8.13.0) eslint-visitor-keys: 3.4.3 esprima@4.0.1: {} - esquery@1.5.0: + esquery@1.6.0: dependencies: estraverse: 5.3.0 @@ -7185,7 +6068,7 @@ snapshots: estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 esutils@2.0.3: {} @@ -7228,7 +6111,7 @@ snapshots: '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 - micromatch: 4.0.7 + micromatch: 4.0.8 fast-json-stable-stringify@2.1.0: {} @@ -7236,6 +6119,8 @@ snapshots: fast-safe-stringify@2.1.1: {} + fast-uri@3.0.3: {} + fastq@1.17.1: dependencies: reusify: 1.0.4 @@ -7278,7 +6163,7 @@ snapshots: dependencies: detect-file: 1.0.0 is-glob: 4.0.3 - micromatch: 4.0.7 + micromatch: 4.0.8 resolve-dir: 1.0.1 flat-cache@3.2.0: @@ -7295,28 +6180,20 @@ snapshots: dependencies: is-callable: 1.2.7 - foreground-child@3.2.0: + foreground-child@3.3.0: dependencies: cross-spawn: 7.0.3 signal-exit: 4.1.0 - form-data@4.0.0: + form-data@4.0.1: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 mime-types: 2.1.35 - fraction.js@4.3.7: {} - fs-constants@1.0.0: optional: true - fs-extra@11.2.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.1 - fs-extra@9.1.0: dependencies: at-least-node: 1.0.0 @@ -7340,13 +6217,9 @@ snapshots: functions-have-names@1.2.3: {} - gensync@1.0.0-beta.2: {} - get-caller-file@2.0.5: {} - get-east-asian-width@1.2.0: {} - - get-func-name@2.0.2: {} + get-east-asian-width@1.3.0: {} get-intrinsic@1.2.4: dependencies: @@ -7364,7 +6237,7 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.2.4 - get-tsconfig@4.7.5: + get-tsconfig@4.8.1: dependencies: resolve-pkg-maps: 1.0.0 @@ -7385,21 +6258,22 @@ snapshots: dependencies: is-glob: 4.0.3 - glob@10.4.1: + glob@10.4.5: dependencies: - foreground-child: 3.2.0 - jackspeak: 3.4.0 - minimatch: 9.0.4 + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 minipass: 7.1.2 + package-json-from-dist: 1.0.1 path-scurry: 1.11.1 glob@11.0.0: dependencies: - foreground-child: 3.2.0 - jackspeak: 4.0.1 + foreground-child: 3.3.0 + jackspeak: 4.0.2 minimatch: 10.0.1 minipass: 7.1.2 - package-json-from-dist: 1.0.0 + package-json-from-dist: 1.0.1 path-scurry: 2.0.0 glob@7.2.3: @@ -7416,7 +6290,7 @@ snapshots: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 5.0.1 + minimatch: 5.1.6 once: 1.4.0 global-directory@4.0.1: @@ -7437,8 +6311,6 @@ snapshots: is-windows: 1.0.2 which: 1.3.1 - globals@11.12.0: {} - globals@13.24.0: dependencies: type-fest: 0.20.2 @@ -7453,18 +6325,10 @@ snapshots: array-union: 2.1.0 dir-glob: 3.0.1 fast-glob: 3.3.2 - ignore: 5.3.1 + ignore: 5.3.2 merge2: 1.4.1 slash: 3.0.0 - globby@13.2.2: - dependencies: - dir-glob: 3.0.1 - fast-glob: 3.3.2 - ignore: 5.3.1 - merge2: 1.4.1 - slash: 4.0.0 - gopd@1.0.1: dependencies: get-intrinsic: 1.2.4 @@ -7480,7 +6344,7 @@ snapshots: source-map: 0.6.1 wordwrap: 1.0.0 optionalDependencies: - uglify-js: 3.18.0 + uglify-js: 3.19.3 has-bigints@1.0.2: {} @@ -7509,14 +6373,12 @@ snapshots: header-case@2.0.4: dependencies: capital-case: 1.0.4 - tslib: 2.6.3 + tslib: 2.8.0 homedir-polyfill@1.0.3: dependencies: parse-passwd: 1.0.0 - hookable@5.5.3: {} - hosted-git-info@2.8.9: {} hosted-git-info@4.1.0: @@ -7525,7 +6387,7 @@ snapshots: html-escaper@2.0.2: {} - htmlparser2@8.0.2: + htmlparser2@9.1.0: dependencies: domelementtype: 2.3.0 domhandler: 5.0.3 @@ -7535,22 +6397,22 @@ snapshots: http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.1 - debug: 4.3.5 + debug: 4.3.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color http2-client@1.3.5: {} - https-proxy-agent@7.0.4: + https-proxy-agent@7.0.5: dependencies: agent-base: 7.1.1 - debug: 4.3.5 + debug: 4.3.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color human-signals@5.0.0: {} - husky@9.0.11: {} + husky@9.1.6: {} hyperdyperid@1.2.0: {} @@ -7558,9 +6420,13 @@ snapshots: dependencies: safer-buffer: 2.1.2 + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + ieee754@1.2.1: {} - ignore@5.3.1: {} + ignore@5.3.2: {} immediate@3.0.6: {} @@ -7632,13 +6498,9 @@ snapshots: call-bind: 1.0.7 has-tostringtag: 1.0.2 - is-builtin-module@3.2.1: - dependencies: - builtin-modules: 3.3.0 - is-callable@1.2.7: {} - is-core-module@2.13.1: + is-core-module@2.15.1: dependencies: hasown: 2.0.2 @@ -7664,7 +6526,7 @@ snapshots: is-fullwidth-code-point@5.0.0: dependencies: - get-east-asian-width: 1.2.0 + get-east-asian-width: 1.3.0 is-generator-function@1.0.10: dependencies: @@ -7680,8 +6542,6 @@ snapshots: is-map@2.0.3: {} - is-module@1.0.0: {} - is-negative-zero@2.0.3: {} is-number-object@1.0.7: @@ -7696,10 +6556,6 @@ snapshots: is-plain-obj@2.1.0: {} - is-reference@1.2.1: - dependencies: - '@types/estree': 1.0.5 - is-regex@1.1.4: dependencies: call-bind: 1.0.7 @@ -7733,6 +6589,8 @@ snapshots: is-unicode-supported@1.3.0: {} + is-unicode-supported@2.1.0: {} + is-url@1.2.4: {} is-utf8@0.2.1: {} @@ -7773,7 +6631,7 @@ snapshots: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 - iterator.prototype@1.1.2: + iterator.prototype@1.1.3: dependencies: define-properties: 1.2.1 get-intrinsic: 1.2.4 @@ -7781,17 +6639,15 @@ snapshots: reflect.getprototypeof: 1.0.6 set-function-name: 2.0.2 - jackspeak@3.4.0: + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 optionalDependencies: '@pkgjs/parseargs': 0.11.0 - jackspeak@4.0.1: + jackspeak@4.0.2: dependencies: '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 jest-diff@26.6.2: dependencies: @@ -7815,8 +6671,6 @@ snapshots: dependencies: argparse: 2.0.1 - jsesc@2.5.2: {} - json-buffer@3.0.1: {} json-parse-better-errors@1.0.2: {} @@ -7833,8 +6687,6 @@ snapshots: dependencies: minimist: 1.2.8 - json5@2.2.3: {} - jsonc-parser@3.3.1: {} jsonfile@6.1.0: @@ -7856,7 +6708,7 @@ snapshots: lodash.isstring: 4.0.1 lodash.once: 4.1.1 ms: 2.1.3 - semver: 7.6.2 + semver: 7.6.3 jsx-ast-utils@3.3.5: dependencies: @@ -7929,27 +6781,27 @@ snapshots: dependencies: uc.micro: 1.0.6 - lint-staged@15.2.7: + lint-staged@15.2.10: dependencies: chalk: 5.3.0 commander: 12.1.0 - debug: 4.3.5 + debug: 4.3.7(supports-color@8.1.1) execa: 8.0.1 lilconfig: 3.1.2 - listr2: 8.2.1 - micromatch: 4.0.7 + listr2: 8.2.5 + micromatch: 4.0.8 pidtree: 0.6.0 string-argv: 0.3.2 - yaml: 2.4.5 + yaml: 2.5.1 transitivePeerDependencies: - supports-color - listr2@8.2.1: + listr2@8.2.5: dependencies: cli-truncate: 4.0.0 colorette: 2.0.20 eventemitter3: 5.0.1 - log-update: 6.0.0 + log-update: 6.1.0 rfdc: 1.4.1 wrap-ansi: 9.0.0 @@ -7986,8 +6838,6 @@ snapshots: lodash.map@4.6.0: {} - lodash.memoize@4.1.2: {} - lodash.merge@4.6.2: {} lodash.mergewith@4.6.2: {} @@ -8014,10 +6864,15 @@ snapshots: chalk: 5.3.0 is-unicode-supported: 1.3.0 - log-update@6.0.0: + log-symbols@6.0.0: dependencies: - ansi-escapes: 6.2.1 - cli-cursor: 4.0.0 + chalk: 5.3.0 + is-unicode-supported: 1.3.0 + + log-update@6.1.0: + dependencies: + ansi-escapes: 7.0.0 + cli-cursor: 5.0.0 slice-ansi: 7.1.0 strip-ansi: 7.1.0 wrap-ansi: 9.0.0 @@ -8028,33 +6883,27 @@ snapshots: dependencies: js-tokens: 4.0.0 - loupe@3.1.1: - dependencies: - get-func-name: 2.0.2 + loupe@3.1.2: {} lower-case@2.0.2: dependencies: - tslib: 2.6.3 + tslib: 2.8.0 - lru-cache@10.2.2: {} + lru-cache@10.4.3: {} lru-cache@11.0.1: {} - lru-cache@5.1.1: - dependencies: - yallist: 3.1.1 - lru-cache@6.0.0: dependencies: yallist: 4.0.0 - magic-string@0.30.10: + magic-string@0.30.12: dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/sourcemap-codec': 1.5.0 make-dir@4.0.0: dependencies: - semver: 7.6.2 + semver: 7.6.3 markdown-it@12.3.2: dependencies: @@ -8064,18 +6913,14 @@ snapshots: mdurl: 1.0.1 uc.micro: 1.0.6 - mdn-data@2.0.28: {} - - mdn-data@2.0.30: {} - mdurl@1.0.1: {} - memfs@4.11.1: + memfs@4.14.0: dependencies: - '@jsonjoy.com/json-pack': 1.1.0(tslib@2.7.0) - '@jsonjoy.com/util': 1.3.0(tslib@2.7.0) - tree-dump: 1.0.2(tslib@2.7.0) - tslib: 2.7.0 + '@jsonjoy.com/json-pack': 1.1.0(tslib@2.8.0) + '@jsonjoy.com/util': 1.5.0(tslib@2.8.0) + tree-dump: 1.0.2(tslib@2.8.0) + tslib: 2.8.0 memorystream@0.3.1: {} @@ -8087,7 +6932,7 @@ snapshots: merge@2.1.1: {} - micromatch@4.0.7: + micromatch@4.0.8: dependencies: braces: 3.0.3 picomatch: 2.3.1 @@ -8104,6 +6949,8 @@ snapshots: mimic-fn@4.0.0: {} + mimic-function@5.0.1: {} + mimic-response@3.1.0: optional: true @@ -8115,11 +6962,11 @@ snapshots: dependencies: brace-expansion: 1.1.11 - minimatch@5.0.1: + minimatch@5.1.6: dependencies: brace-expansion: 2.0.1 - minimatch@9.0.4: + minimatch@9.0.5: dependencies: brace-expansion: 2.0.1 @@ -8132,58 +6979,29 @@ snapshots: mkdirp-classic@0.5.3: optional: true - mkdist@1.5.5(typescript@5.5.4): - dependencies: - autoprefixer: 10.4.20(postcss@8.4.45) - citty: 0.1.6 - cssnano: 7.0.6(postcss@8.4.45) - defu: 6.1.4 - esbuild: 0.23.1 - fast-glob: 3.3.2 - jiti: 1.21.6 - mlly: 1.7.1 - pathe: 1.1.2 - pkg-types: 1.2.0 - postcss: 8.4.45 - postcss-nested: 6.2.0(postcss@8.4.45) - semver: 7.6.3 - optionalDependencies: - typescript: 5.5.4 - - mlly@1.7.1: - dependencies: - acorn: 8.11.3 - pathe: 1.1.2 - pkg-types: 1.2.0 - ufo: 1.5.4 - - mocha@10.4.0: + mocha@10.7.3: dependencies: - ansi-colors: 4.1.1 + ansi-colors: 4.1.3 browser-stdout: 1.3.1 - chokidar: 3.5.3 - debug: 4.3.4(supports-color@8.1.1) - diff: 5.0.0 + chokidar: 3.6.0 + debug: 4.3.7(supports-color@8.1.1) + diff: 5.2.0 escape-string-regexp: 4.0.0 find-up: 5.0.0 glob: 8.1.0 he: 1.2.0 js-yaml: 4.1.0 log-symbols: 4.1.0 - minimatch: 5.0.1 + minimatch: 5.1.6 ms: 2.1.3 - serialize-javascript: 6.0.0 + serialize-javascript: 6.0.2 strip-json-comments: 3.1.1 supports-color: 8.1.1 - workerpool: 6.2.1 + workerpool: 6.5.1 yargs: 16.2.0 - yargs-parser: 20.2.4 + yargs-parser: 20.2.9 yargs-unparser: 2.0.0 - mri@1.2.0: {} - - ms@2.1.2: {} - ms@2.1.3: {} mute-stream@0.0.8: {} @@ -8202,11 +7020,11 @@ snapshots: no-case@3.0.4: dependencies: lower-case: 2.0.2 - tslib: 2.6.3 + tslib: 2.8.0 - node-abi@3.65.0: + node-abi@3.71.0: dependencies: - semver: 7.6.2 + semver: 7.6.3 optional: true node-addon-api@4.3.0: @@ -8224,8 +7042,6 @@ snapshots: dependencies: es6-promise: 3.3.1 - node-releases@2.0.18: {} - normalize-package-data@2.5.0: dependencies: hosted-git-info: 2.8.9 @@ -8235,8 +7051,6 @@ snapshots: normalize-path@3.0.0: {} - normalize-range@0.1.2: {} - npm-run-all@4.1.5: dependencies: ansi-styles: 3.2.1 @@ -8292,7 +7106,7 @@ snapshots: object-hash@2.2.0: {} - object-inspect@1.13.1: {} + object-inspect@1.13.2: {} object-keys@1.1.1: {} @@ -8322,12 +7136,6 @@ snapshots: define-properties: 1.2.1 es-abstract: 1.23.3 - object.hasown@1.1.4: - dependencies: - define-properties: 1.2.1 - es-abstract: 1.23.3 - es-object-atoms: 1.0.0 - object.values@1.2.0: dependencies: call-bind: 1.0.7 @@ -8346,6 +7154,10 @@ snapshots: dependencies: mimic-fn: 4.0.0 + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + open@8.4.2: dependencies: define-lazy-prop: 2.0.0 @@ -8401,6 +7213,18 @@ snapshots: string-width: 6.1.0 strip-ansi: 7.1.0 + ora@8.1.0: + dependencies: + chalk: 5.3.0 + cli-cursor: 5.0.0 + cli-spinners: 2.9.2 + is-interactive: 2.0.0 + is-unicode-supported: 2.1.0 + log-symbols: 6.0.0 + stdin-discarder: 0.2.2 + string-width: 7.2.0 + strip-ansi: 7.1.0 + os-tmpdir@1.0.2: {} p-limit@3.1.0: @@ -8409,7 +7233,7 @@ snapshots: p-limit@4.0.0: dependencies: - yocto-queue: 1.0.0 + yocto-queue: 1.1.1 p-locate@5.0.0: dependencies: @@ -8419,14 +7243,14 @@ snapshots: dependencies: p-limit: 4.0.0 - package-json-from-dist@1.0.0: {} + package-json-from-dist@1.0.1: {} pako@1.0.11: {} param-case@3.0.4: dependencies: dot-case: 3.0.4 - tslib: 2.6.3 + tslib: 2.8.0 parent-module@1.0.1: dependencies: @@ -8439,7 +7263,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.24.7 + '@babel/code-frame': 7.25.9 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -8450,24 +7274,28 @@ snapshots: dependencies: semver: 5.7.2 - parse5-htmlparser2-tree-adapter@7.0.0: + parse5-htmlparser2-tree-adapter@7.1.0: dependencies: domhandler: 5.0.3 - parse5: 7.1.2 + parse5: 7.2.0 + + parse5-parser-stream@7.1.2: + dependencies: + parse5: 7.2.0 - parse5@7.1.2: + parse5@7.2.0: dependencies: entities: 4.5.0 pascal-case@3.1.2: dependencies: no-case: 3.0.4 - tslib: 2.6.3 + tslib: 2.8.0 path-case@3.0.4: dependencies: dot-case: 3.0.4 - tslib: 2.6.3 + tslib: 2.8.0 path-exists@4.0.0: {} @@ -8485,7 +7313,7 @@ snapshots: path-scurry@1.11.1: dependencies: - lru-cache: 10.2.2 + lru-cache: 10.4.3 minipass: 7.1.2 path-scurry@2.0.0: @@ -8505,7 +7333,7 @@ snapshots: pend@1.2.0: {} - picocolors@1.0.1: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -8515,186 +7343,13 @@ snapshots: pify@3.0.0: {} - pkg-types@1.2.0: - dependencies: - confbox: 0.1.7 - mlly: 1.7.1 - pathe: 1.1.2 - possible-typed-array-names@1.0.0: {} - postcss-calc@10.0.2(postcss@8.4.45): - dependencies: - postcss: 8.4.45 - postcss-selector-parser: 6.1.2 - postcss-value-parser: 4.2.0 - - postcss-colormin@7.0.2(postcss@8.4.45): - dependencies: - browserslist: 4.23.3 - caniuse-api: 3.0.0 - colord: 2.9.3 - postcss: 8.4.45 - postcss-value-parser: 4.2.0 - - postcss-convert-values@7.0.4(postcss@8.4.45): - dependencies: - browserslist: 4.23.3 - postcss: 8.4.45 - postcss-value-parser: 4.2.0 - - postcss-discard-comments@7.0.3(postcss@8.4.45): - dependencies: - postcss: 8.4.45 - postcss-selector-parser: 6.1.2 - - postcss-discard-duplicates@7.0.1(postcss@8.4.45): - dependencies: - postcss: 8.4.45 - - postcss-discard-empty@7.0.0(postcss@8.4.45): - dependencies: - postcss: 8.4.45 - - postcss-discard-overridden@7.0.0(postcss@8.4.45): - dependencies: - postcss: 8.4.45 - - postcss-merge-longhand@7.0.4(postcss@8.4.45): - dependencies: - postcss: 8.4.45 - postcss-value-parser: 4.2.0 - stylehacks: 7.0.4(postcss@8.4.45) - - postcss-merge-rules@7.0.4(postcss@8.4.45): - dependencies: - browserslist: 4.23.3 - caniuse-api: 3.0.0 - cssnano-utils: 5.0.0(postcss@8.4.45) - postcss: 8.4.45 - postcss-selector-parser: 6.1.2 - - postcss-minify-font-values@7.0.0(postcss@8.4.45): - dependencies: - postcss: 8.4.45 - postcss-value-parser: 4.2.0 - - postcss-minify-gradients@7.0.0(postcss@8.4.45): - dependencies: - colord: 2.9.3 - cssnano-utils: 5.0.0(postcss@8.4.45) - postcss: 8.4.45 - postcss-value-parser: 4.2.0 - - postcss-minify-params@7.0.2(postcss@8.4.45): - dependencies: - browserslist: 4.23.3 - cssnano-utils: 5.0.0(postcss@8.4.45) - postcss: 8.4.45 - postcss-value-parser: 4.2.0 - - postcss-minify-selectors@7.0.4(postcss@8.4.45): - dependencies: - cssesc: 3.0.0 - postcss: 8.4.45 - postcss-selector-parser: 6.1.2 - - postcss-nested@6.2.0(postcss@8.4.45): - dependencies: - postcss: 8.4.45 - postcss-selector-parser: 6.1.2 - - postcss-normalize-charset@7.0.0(postcss@8.4.45): - dependencies: - postcss: 8.4.45 - - postcss-normalize-display-values@7.0.0(postcss@8.4.45): - dependencies: - postcss: 8.4.45 - postcss-value-parser: 4.2.0 - - postcss-normalize-positions@7.0.0(postcss@8.4.45): - dependencies: - postcss: 8.4.45 - postcss-value-parser: 4.2.0 - - postcss-normalize-repeat-style@7.0.0(postcss@8.4.45): - dependencies: - postcss: 8.4.45 - postcss-value-parser: 4.2.0 - - postcss-normalize-string@7.0.0(postcss@8.4.45): - dependencies: - postcss: 8.4.45 - postcss-value-parser: 4.2.0 - - postcss-normalize-timing-functions@7.0.0(postcss@8.4.45): - dependencies: - postcss: 8.4.45 - postcss-value-parser: 4.2.0 - - postcss-normalize-unicode@7.0.2(postcss@8.4.45): - dependencies: - browserslist: 4.23.3 - postcss: 8.4.45 - postcss-value-parser: 4.2.0 - - postcss-normalize-url@7.0.0(postcss@8.4.45): - dependencies: - postcss: 8.4.45 - postcss-value-parser: 4.2.0 - - postcss-normalize-whitespace@7.0.0(postcss@8.4.45): - dependencies: - postcss: 8.4.45 - postcss-value-parser: 4.2.0 - - postcss-ordered-values@7.0.1(postcss@8.4.45): - dependencies: - cssnano-utils: 5.0.0(postcss@8.4.45) - postcss: 8.4.45 - postcss-value-parser: 4.2.0 - - postcss-reduce-initial@7.0.2(postcss@8.4.45): - dependencies: - browserslist: 4.23.3 - caniuse-api: 3.0.0 - postcss: 8.4.45 - - postcss-reduce-transforms@7.0.0(postcss@8.4.45): - dependencies: - postcss: 8.4.45 - postcss-value-parser: 4.2.0 - - postcss-selector-parser@6.1.2: - dependencies: - cssesc: 3.0.0 - util-deprecate: 1.0.2 - - postcss-svgo@7.0.1(postcss@8.4.45): - dependencies: - postcss: 8.4.45 - postcss-value-parser: 4.2.0 - svgo: 3.3.2 - - postcss-unique-selectors@7.0.3(postcss@8.4.45): - dependencies: - postcss: 8.4.45 - postcss-selector-parser: 6.1.2 - - postcss-value-parser@4.2.0: {} - - postcss@8.4.39: - dependencies: - nanoid: 3.3.7 - picocolors: 1.0.1 - source-map-js: 1.2.0 - - postcss@8.4.45: + postcss@8.4.47: dependencies: nanoid: 3.3.7 - picocolors: 1.0.1 - source-map-js: 1.2.0 + picocolors: 1.1.1 + source-map-js: 1.2.1 prebuild-install@7.1.2: dependencies: @@ -8704,8 +7359,8 @@ snapshots: minimist: 1.2.8 mkdirp-classic: 0.5.3 napi-build-utils: 1.0.2 - node-abi: 3.65.0 - pump: 3.0.0 + node-abi: 3.71.0 + pump: 3.0.2 rc: 1.2.8 simple-get: 4.0.1 tar-fs: 2.1.1 @@ -8718,18 +7373,16 @@ snapshots: dependencies: fast-diff: 1.3.0 - prettier-plugin-organize-imports@3.2.4(prettier@3.3.2)(typescript@5.5.4): + prettier-plugin-organize-imports@3.2.4(prettier@3.3.3)(typescript@5.6.3): dependencies: - prettier: 3.3.2 - typescript: 5.5.4 + prettier: 3.3.3 + typescript: 5.6.3 - prettier-plugin-sort-json@4.0.0(prettier@3.3.2): + prettier-plugin-sort-json@4.0.0(prettier@3.3.3): dependencies: - prettier: 3.3.2 - - prettier@3.3.2: {} + prettier: 3.3.3 - pretty-bytes@6.1.1: {} + prettier@3.3.3: {} pretty-format@26.6.2: dependencies: @@ -8746,7 +7399,7 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 - pump@3.0.0: + pump@3.0.2: dependencies: end-of-stream: 1.4.4 once: 1.4.0 @@ -8754,7 +7407,7 @@ snapshots: punycode@2.3.1: {} - qs@6.12.3: + qs@6.13.0: dependencies: side-channel: 1.0.6 @@ -8766,7 +7419,7 @@ snapshots: dependencies: safe-buffer: 5.2.1 - rate-limiter-flexible@5.0.3: {} + rate-limiter-flexible@5.0.4: {} rc@1.2.8: dependencies: @@ -8818,13 +7471,11 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.2.4 globalthis: 1.0.4 - which-builtin-type: 1.1.3 + which-builtin-type: 1.1.4 reftools@1.1.9: {} - regenerator-runtime@0.14.1: {} - - regexp.prototype.flags@1.5.2: + regexp.prototype.flags@1.5.3: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 @@ -8850,13 +7501,13 @@ snapshots: resolve@1.22.8: dependencies: - is-core-module: 2.13.1 + is-core-module: 2.15.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 resolve@2.0.0-next.5: dependencies: - is-core-module: 2.13.1 + is-core-module: 2.15.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 @@ -8870,6 +7521,11 @@ snapshots: onetime: 5.1.2 signal-exit: 3.0.7 + restore-cursor@5.1.0: + dependencies: + onetime: 7.0.0 + signal-exit: 4.1.0 + reusify@1.0.4: {} rfdc@1.4.1: {} @@ -8881,40 +7537,28 @@ snapshots: rimraf@6.0.1: dependencies: glob: 11.0.0 - package-json-from-dist: 1.0.0 - - rollup-plugin-dts@6.1.1(rollup@3.29.4)(typescript@5.5.4): - dependencies: - magic-string: 0.30.10 - rollup: 3.29.4 - typescript: 5.5.4 - optionalDependencies: - '@babel/code-frame': 7.24.7 - - rollup@3.29.4: - optionalDependencies: - fsevents: 2.3.3 + package-json-from-dist: 1.0.1 - rollup@4.21.2: + rollup@4.24.0: dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.21.2 - '@rollup/rollup-android-arm64': 4.21.2 - '@rollup/rollup-darwin-arm64': 4.21.2 - '@rollup/rollup-darwin-x64': 4.21.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.21.2 - '@rollup/rollup-linux-arm-musleabihf': 4.21.2 - '@rollup/rollup-linux-arm64-gnu': 4.21.2 - '@rollup/rollup-linux-arm64-musl': 4.21.2 - '@rollup/rollup-linux-powerpc64le-gnu': 4.21.2 - '@rollup/rollup-linux-riscv64-gnu': 4.21.2 - '@rollup/rollup-linux-s390x-gnu': 4.21.2 - '@rollup/rollup-linux-x64-gnu': 4.21.2 - '@rollup/rollup-linux-x64-musl': 4.21.2 - '@rollup/rollup-win32-arm64-msvc': 4.21.2 - '@rollup/rollup-win32-ia32-msvc': 4.21.2 - '@rollup/rollup-win32-x64-msvc': 4.21.2 + '@rollup/rollup-android-arm-eabi': 4.24.0 + '@rollup/rollup-android-arm64': 4.24.0 + '@rollup/rollup-darwin-arm64': 4.24.0 + '@rollup/rollup-darwin-x64': 4.24.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.24.0 + '@rollup/rollup-linux-arm-musleabihf': 4.24.0 + '@rollup/rollup-linux-arm64-gnu': 4.24.0 + '@rollup/rollup-linux-arm64-musl': 4.24.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.24.0 + '@rollup/rollup-linux-riscv64-gnu': 4.24.0 + '@rollup/rollup-linux-s390x-gnu': 4.24.0 + '@rollup/rollup-linux-x64-gnu': 4.24.0 + '@rollup/rollup-linux-x64-musl': 4.24.0 + '@rollup/rollup-win32-arm64-msvc': 4.24.0 + '@rollup/rollup-win32-ia32-msvc': 4.24.0 + '@rollup/rollup-win32-x64-msvc': 4.24.0 fsevents: 2.3.3 run-async@2.4.1: {} @@ -8925,7 +7569,7 @@ snapshots: rxjs@7.8.1: dependencies: - tslib: 2.7.0 + tslib: 2.8.0 safe-array-concat@1.1.2: dependencies: @@ -8948,23 +7592,19 @@ snapshots: sax@1.4.1: {} - scule@1.3.0: {} - semver@5.7.2: {} semver@6.3.1: {} - semver@7.6.2: {} - semver@7.6.3: {} sentence-case@3.0.4: dependencies: no-case: 3.0.4 - tslib: 2.6.3 + tslib: 2.8.0 upper-case-first: 2.0.2 - serialize-javascript@6.0.0: + serialize-javascript@6.0.2: dependencies: randombytes: 2.1.0 @@ -9031,7 +7671,7 @@ snapshots: call-bind: 1.0.7 es-errors: 1.3.0 get-intrinsic: 1.2.4 - object-inspect: 1.13.1 + object-inspect: 1.13.2 siginfo@2.0.0: {} @@ -9051,8 +7691,6 @@ snapshots: slash@3.0.0: {} - slash@4.0.0: {} - slice-ansi@5.0.0: dependencies: ansi-styles: 6.2.1 @@ -9066,25 +7704,25 @@ snapshots: snake-case@3.0.4: dependencies: dot-case: 3.0.4 - tslib: 2.6.3 + tslib: 2.8.0 - source-map-js@1.2.0: {} + source-map-js@1.2.1: {} source-map@0.6.1: {} spdx-correct@3.2.0: dependencies: spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.18 + spdx-license-ids: 3.0.20 spdx-exceptions@2.5.0: {} spdx-expression-parse@3.0.1: dependencies: spdx-exceptions: 2.5.0 - spdx-license-ids: 3.0.18 + spdx-license-ids: 3.0.20 - spdx-license-ids@3.0.18: {} + spdx-license-ids@3.0.20: {} split2@4.2.0: {} @@ -9098,6 +7736,8 @@ snapshots: dependencies: bl: 5.1.0 + stdin-discarder@0.2.2: {} + stoppable@1.1.0: {} string-argv@0.3.2: {} @@ -9117,15 +7757,21 @@ snapshots: string-width@6.1.0: dependencies: eastasianwidth: 0.2.0 - emoji-regex: 10.3.0 + emoji-regex: 10.4.0 strip-ansi: 7.1.0 - string-width@7.1.0: + string-width@7.2.0: dependencies: - emoji-regex: 10.3.0 - get-east-asian-width: 1.2.0 + emoji-regex: 10.4.0 + get-east-asian-width: 1.3.0 strip-ansi: 7.1.0 + string.prototype.includes@2.0.1: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + string.prototype.matchall@4.0.11: dependencies: call-bind: 1.0.7 @@ -9137,7 +7783,7 @@ snapshots: gopd: 1.0.1 has-symbols: 1.0.3 internal-slot: 1.0.7 - regexp.prototype.flags: 1.5.2 + regexp.prototype.flags: 1.5.3 set-function-name: 2.0.2 side-channel: 1.0.6 @@ -9148,6 +7794,11 @@ snapshots: es-abstract: 1.23.3 es-object-atoms: 1.0.0 + string.prototype.repeat@1.0.0: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.23.3 + string.prototype.trim@1.2.9: dependencies: call-bind: 1.0.7 @@ -9181,7 +7832,7 @@ snapshots: strip-ansi@7.1.0: dependencies: - ansi-regex: 6.0.1 + ansi-regex: 6.1.0 strip-bom@3.0.0: {} @@ -9194,12 +7845,6 @@ snapshots: strip-json-comments@3.1.1: {} - stylehacks@7.0.4(postcss@8.4.45): - dependencies: - browserslist: 4.23.3 - postcss: 8.4.45 - postcss-selector-parser: 6.1.2 - supports-color@5.5.0: dependencies: has-flag: 3.0.0 @@ -9216,16 +7861,6 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svgo@3.3.2: - dependencies: - '@trysound/sax': 0.2.0 - commander: 7.2.0 - css-select: 5.1.0 - css-tree: 2.3.1 - css-what: 6.1.0 - csso: 5.0.5 - picocolors: 1.0.1 - swagger2openapi@7.0.8: dependencies: call-me-maybe: 1.0.2 @@ -9242,10 +7877,10 @@ snapshots: transitivePeerDependencies: - encoding - synckit@0.8.8: + synckit@0.9.2: dependencies: '@pkgr/core': 0.1.1 - tslib: 2.7.0 + tslib: 2.8.0 tapable@2.2.1: {} @@ -9253,7 +7888,7 @@ snapshots: dependencies: chownr: 1.1.4 mkdirp-classic: 0.5.3 - pump: 3.0.0 + pump: 3.0.2 tar-stream: 2.2.0 optional: true @@ -9276,14 +7911,16 @@ snapshots: text-table@0.2.0: {} - thingies@1.21.0(tslib@2.7.0): + thingies@1.21.0(tslib@2.8.0): dependencies: - tslib: 2.7.0 + tslib: 2.8.0 through@2.3.8: {} tinybench@2.9.0: {} + tinyexec@0.3.1: {} + tinypool@1.0.1: {} tinyrainbow@1.2.0: {} @@ -9296,21 +7933,19 @@ snapshots: tmp@0.2.3: {} - to-fast-properties@2.0.0: {} - to-regex-range@5.0.1: dependencies: is-number: 7.0.0 tr46@0.0.3: {} - tree-dump@1.0.2(tslib@2.7.0): + tree-dump@1.0.2(tslib@2.8.0): dependencies: - tslib: 2.7.0 + tslib: 2.8.0 - ts-api-utils@1.3.0(typescript@5.5.4): + ts-api-utils@1.3.0(typescript@5.6.3): dependencies: - typescript: 5.5.4 + typescript: 5.6.3 tsconfig-paths@3.15.0: dependencies: @@ -9319,14 +7954,12 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 - tslib@2.6.3: {} - - tslib@2.7.0: {} + tslib@2.8.0: {} - tsx@4.16.2: + tsx@4.19.1: dependencies: - esbuild: 0.21.5 - get-tsconfig: 4.7.5 + esbuild: 0.23.1 + get-tsconfig: 4.8.1 optionalDependencies: fsevents: 2.3.3 @@ -9345,7 +7978,7 @@ snapshots: type-fest@0.21.3: {} - type-fest@4.20.0: {} + type-fest@4.26.1: {} typed-array-buffer@1.0.2: dependencies: @@ -9381,19 +8014,15 @@ snapshots: typed-rest-client@1.8.11: dependencies: - qs: 6.12.3 + qs: 6.13.0 tunnel: 0.0.6 - underscore: 1.13.6 + underscore: 1.13.7 - typescript@5.4.5: {} - - typescript@5.5.4: {} + typescript@5.6.3: {} uc.micro@1.0.6: {} - ufo@1.5.4: {} - - uglify-js@3.18.0: + uglify-js@3.19.3: optional: true unbox-primitive@1.0.2: @@ -9403,72 +8032,23 @@ snapshots: has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 - unbuild@2.0.0(typescript@5.5.4): - dependencies: - '@rollup/plugin-alias': 5.1.0(rollup@3.29.4) - '@rollup/plugin-commonjs': 25.0.8(rollup@3.29.4) - '@rollup/plugin-json': 6.1.0(rollup@3.29.4) - '@rollup/plugin-node-resolve': 15.2.3(rollup@3.29.4) - '@rollup/plugin-replace': 5.0.7(rollup@3.29.4) - '@rollup/pluginutils': 5.1.0(rollup@3.29.4) - chalk: 5.3.0 - citty: 0.1.6 - consola: 3.2.3 - defu: 6.1.4 - esbuild: 0.19.12 - globby: 13.2.2 - hookable: 5.5.3 - jiti: 1.21.6 - magic-string: 0.30.10 - mkdist: 1.5.5(typescript@5.5.4) - mlly: 1.7.1 - pathe: 1.1.2 - pkg-types: 1.2.0 - pretty-bytes: 6.1.1 - rollup: 3.29.4 - rollup-plugin-dts: 6.1.1(rollup@3.29.4)(typescript@5.5.4) - scule: 1.3.0 - untyped: 1.4.2 - optionalDependencies: - typescript: 5.5.4 - transitivePeerDependencies: - - sass - - supports-color - - vue-tsc - - underscore@1.13.6: {} + underscore@1.13.7: {} undici-types@5.26.5: {} + undici@6.20.1: {} + unicorn-magic@0.1.0: {} universalify@2.0.1: {} - untyped@1.4.2: - dependencies: - '@babel/core': 7.25.2 - '@babel/standalone': 7.25.6 - '@babel/types': 7.24.7 - defu: 6.1.4 - jiti: 1.21.6 - mri: 1.2.0 - scule: 1.3.0 - transitivePeerDependencies: - - supports-color - - update-browserslist-db@1.1.0(browserslist@4.23.3): - dependencies: - browserslist: 4.23.3 - escalade: 3.1.2 - picocolors: 1.0.1 - upper-case-first@2.0.2: dependencies: - tslib: 2.6.3 + tslib: 2.8.0 upper-case@2.0.2: dependencies: - tslib: 2.6.3 + tslib: 2.8.0 uri-js@4.4.1: dependencies: @@ -9485,7 +8065,7 @@ snapshots: uuid@8.3.2: {} - v8-to-istanbul@9.2.0: + v8-to-istanbul@9.3.0: dependencies: '@jridgewell/trace-mapping': 0.3.25 '@types/istanbul-lib-coverage': 2.0.6 @@ -9496,13 +8076,12 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - vite-node@2.0.5(@types/node@18.19.34): + vite-node@2.1.3(@types/node@18.19.59): dependencies: cac: 6.7.14 - debug: 4.3.5 + debug: 4.3.7(supports-color@8.1.1) pathe: 1.1.2 - tinyrainbow: 1.2.0 - vite: 5.4.3(@types/node@18.19.34) + vite: 5.4.10(@types/node@18.19.59) transitivePeerDependencies: - '@types/node' - less @@ -9514,41 +8093,42 @@ snapshots: - supports-color - terser - vite@5.4.3(@types/node@18.19.34): + vite@5.4.10(@types/node@18.19.59): dependencies: esbuild: 0.21.5 - postcss: 8.4.45 - rollup: 4.21.2 + postcss: 8.4.47 + rollup: 4.24.0 optionalDependencies: - '@types/node': 18.19.34 + '@types/node': 18.19.59 fsevents: 2.3.3 - vitest@2.0.5(@types/node@18.19.34): - dependencies: - '@ampproject/remapping': 2.3.0 - '@vitest/expect': 2.0.5 - '@vitest/pretty-format': 2.0.5 - '@vitest/runner': 2.0.5 - '@vitest/snapshot': 2.0.5 - '@vitest/spy': 2.0.5 - '@vitest/utils': 2.0.5 - chai: 5.1.1 - debug: 4.3.5 - execa: 8.0.1 - magic-string: 0.30.10 + vitest@2.1.3(@types/node@18.19.59): + dependencies: + '@vitest/expect': 2.1.3 + '@vitest/mocker': 2.1.3(@vitest/spy@2.1.3)(vite@5.4.10(@types/node@18.19.59)) + '@vitest/pretty-format': 2.1.3 + '@vitest/runner': 2.1.3 + '@vitest/snapshot': 2.1.3 + '@vitest/spy': 2.1.3 + '@vitest/utils': 2.1.3 + chai: 5.1.2 + debug: 4.3.7(supports-color@8.1.1) + magic-string: 0.30.12 pathe: 1.1.2 std-env: 3.7.0 tinybench: 2.9.0 + tinyexec: 0.3.1 tinypool: 1.0.1 tinyrainbow: 1.2.0 - vite: 5.4.3(@types/node@18.19.34) - vite-node: 2.0.5(@types/node@18.19.34) + vite: 5.4.10(@types/node@18.19.59) + vite-node: 2.1.3(@types/node@18.19.59) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 18.19.34 + '@types/node': 18.19.59 transitivePeerDependencies: - less - lightningcss + - msw - sass - sass-embedded - stylus @@ -9556,25 +8136,15 @@ snapshots: - supports-color - terser - vue@3.4.31(typescript@5.4.5): - dependencies: - '@vue/compiler-dom': 3.4.31 - '@vue/compiler-sfc': 3.4.31 - '@vue/runtime-dom': 3.4.31 - '@vue/server-renderer': 3.4.31(vue@3.4.31(typescript@5.4.5)) - '@vue/shared': 3.4.31 - optionalDependencies: - typescript: 5.4.5 - - vue@3.4.31(typescript@5.5.4): + vue@3.5.12(typescript@5.6.3): dependencies: - '@vue/compiler-dom': 3.4.31 - '@vue/compiler-sfc': 3.4.31 - '@vue/runtime-dom': 3.4.31 - '@vue/server-renderer': 3.4.31(vue@3.4.31(typescript@5.5.4)) - '@vue/shared': 3.4.31 + '@vue/compiler-dom': 3.5.12 + '@vue/compiler-sfc': 3.5.12 + '@vue/runtime-dom': 3.5.12 + '@vue/server-renderer': 3.5.12(vue@3.5.12(typescript@5.6.3)) + '@vue/shared': 3.5.12 optionalDependencies: - typescript: 5.5.4 + typescript: 5.6.3 wcwidth@1.0.1: dependencies: @@ -9582,6 +8152,12 @@ snapshots: webidl-conversions@3.0.1: {} + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + + whatwg-mimetype@4.0.0: {} + whatwg-url@5.0.0: dependencies: tr46: 0.0.3 @@ -9595,7 +8171,7 @@ snapshots: is-string: 1.0.7 is-symbol: 1.0.4 - which-builtin-type@1.1.3: + which-builtin-type@1.1.4: dependencies: function.prototype.name: 1.1.6 has-tostringtag: 1.0.2 @@ -9642,7 +8218,7 @@ snapshots: wordwrap@1.0.0: {} - workerpool@6.2.1: {} + workerpool@6.5.1: {} wrap-ansi@7.0.0: dependencies: @@ -9659,7 +8235,7 @@ snapshots: wrap-ansi@9.0.0: dependencies: ansi-styles: 6.2.1 - string-width: 7.1.0 + string-width: 7.2.0 strip-ansi: 7.1.0 wrappy@1.0.2: {} @@ -9673,15 +8249,13 @@ snapshots: y18n@5.0.8: {} - yallist@3.1.1: {} - yallist@4.0.0: {} yaml@1.10.2: {} - yaml@2.4.5: {} + yaml@2.5.1: {} - yargs-parser@20.2.4: {} + yargs-parser@20.2.9: {} yargs-parser@21.1.1: {} @@ -9695,17 +8269,17 @@ snapshots: yargs@16.2.0: dependencies: cliui: 7.0.4 - escalade: 3.1.2 + escalade: 3.2.0 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 y18n: 5.0.8 - yargs-parser: 20.2.4 + yargs-parser: 20.2.9 yargs@17.7.2: dependencies: cliui: 8.0.1 - escalade: 3.1.2 + escalade: 3.2.0 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 @@ -9723,4 +8297,4 @@ snapshots: yocto-queue@0.1.0: {} - yocto-queue@1.0.0: {} + yocto-queue@1.1.1: {} diff --git a/tsconfig.base.json b/tsconfig.base.json index 706976d..3d2f6ab 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1,9 +1,8 @@ { "compilerOptions": { "resolveJsonModule": true, - "target": "es2018", + "target": "ES2021", "module": "esnext", - "moduleResolution": "bundler", "strict": true, "newLine": "LF", "noImplicitAny": true, @@ -15,11 +14,9 @@ "strictPropertyInitialization": false, "noFallthroughCasesInSwitch": false, "skipLibCheck": true, - "allowJs": true, "skipDefaultLibCheck": false, "esModuleInterop": true, "inlineSourceMap": false, - "importHelpers": true, "removeComments": false, "types": ["vitest/globals"] } From e7bf76a9508aa3de176d96a922067808536f2780 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E9=95=87?= Date: Thu, 24 Oct 2024 14:03:31 +0800 Subject: [PATCH 28/47] chore: husky cli fix --- .husky/commit-msg | 3 --- .husky/pre-commit | 3 --- package.json | 2 +- packages/wormhole/src/helper/schema2type.ts | 4 ++-- 4 files changed, 3 insertions(+), 9 deletions(-) diff --git a/.husky/commit-msg b/.husky/commit-msg index 80416c7..70bd3dd 100644 --- a/.husky/commit-msg +++ b/.husky/commit-msg @@ -1,4 +1 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" - npx --no-install commitlint --edit "$1" diff --git a/.husky/pre-commit b/.husky/pre-commit index 40ab0d3..617cc95 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,5 +1,2 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" - # Ensure files are linted before commit pnpm lint-staged diff --git a/package.json b/package.json index f9177be..6b68b29 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@alova/devtools", "displayName": "Alova", "description": "devtool kits for alova.js", - "version": "0.0.9", + "version": "0.0.0", "private": true, "engines": { "node": ">=18.19.0", diff --git a/packages/wormhole/src/helper/schema2type.ts b/packages/wormhole/src/helper/schema2type.ts index b08758f..74f5fd6 100644 --- a/packages/wormhole/src/helper/schema2type.ts +++ b/packages/wormhole/src/helper/schema2type.ts @@ -148,8 +148,8 @@ function parseSchema( } else { result = typeof schema.type === 'string' - ? (schema.type || config.defaultType) ?? 'unknown' - : config.defaultType ?? 'unknown'; + ? ((schema.type || config.defaultType) ?? 'unknown') + : (config.defaultType ?? 'unknown'); } } if (refPath) { From e73bfebd747869d413d560774452cd4c6f28dfff Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Thu, 24 Oct 2024 21:28:00 +0800 Subject: [PATCH 29/47] =?UTF-8?q?feat(vscode-extension):=20=E5=AE=8C?= =?UTF-8?q?=E6=88=90wormhole=E5=88=86=E7=A6=BB=E9=80=82=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/vscode-extension/esbuild.ts | 2 +- packages/vscode-extension/package.json | 7 +++- .../src/commands/generateApi.ts | 4 ++- .../src/components/autocomplete.ts | 3 +- .../vscode-extension/src/components/error.ts | 8 ++++- packages/vscode-extension/src/globalConfig.ts | 7 ++-- packages/vscode-extension/src/helper/work.ts | 5 +-- packages/vscode-extension/src/utils/work.ts | 29 ++++++--------- .../src/work/generateConfig.ts | 3 +- .../vscode-extension/src/work/readConfig.ts | 4 ++- packages/wormhole/package.json | 2 +- packages/wormhole/src/config.ts | 25 ++++++------- packages/wormhole/src/functions/alovaJson.ts | 3 +- .../wormhole/src/functions/generateApi.ts | 3 +- .../wormhole/src/functions/getFrameworkTag.ts | 1 + .../wormhole/src/functions/getOpenApiData.ts | 4 ++- .../wormhole/src/functions/openApi2Data.ts | 3 +- .../wormhole/src/modules/Configuration.ts | 3 +- packages/wormhole/src/readConfig.ts | 36 +++++++++++-------- packages/wormhole/src/utils/index.ts | 5 +-- packages/wormhole/typings/index.d.ts | 1 - pnpm-lock.yaml | 15 ++++++++ 22 files changed, 105 insertions(+), 68 deletions(-) diff --git a/packages/vscode-extension/esbuild.ts b/packages/vscode-extension/esbuild.ts index e6449ac..aa72152 100644 --- a/packages/vscode-extension/esbuild.ts +++ b/packages/vscode-extension/esbuild.ts @@ -35,7 +35,7 @@ async function main() { sourcesContent: false, platform: 'node', outdir: 'out', - external: ['vscode', 'typescript'], + external: ['vscode', 'typescript', 'esbuild'], logLevel: 'silent', plugins: [ alias({ diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index f5987d2..c8c8eaa 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -73,6 +73,11 @@ "@types/vscode": "^1.89.0", "@vscode/test-cli": "^0.0.9", "@vscode/test-electron": "^2.3.9", - "@vscode/vsce": "^2.29.0" + "@vscode/vsce": "^2.29.0", + "esbuild": "^0.24.0", + "esbuild-plugin-alias": "^0.2.1" + }, + "dependencies": { + "@alova/wormhole": "workspace:^" } } diff --git a/packages/vscode-extension/src/commands/generateApi.ts b/packages/vscode-extension/src/commands/generateApi.ts index 9c0fa99..a003c2b 100644 --- a/packages/vscode-extension/src/commands/generateApi.ts +++ b/packages/vscode-extension/src/commands/generateApi.ts @@ -4,7 +4,9 @@ import { getFileNameByPath } from '@/utils'; // 用于自动生成 export default { commandId: 'alova.generateApi', - handler: () => async () => { + handler: () => async path => { + console.log(path); + await alovaWork.readConfig(); // 生成api文件 const { resultArr } = await alovaWork.generate(); diff --git a/packages/vscode-extension/src/components/autocomplete.ts b/packages/vscode-extension/src/components/autocomplete.ts index b498d7b..bbd725a 100644 --- a/packages/vscode-extension/src/components/autocomplete.ts +++ b/packages/vscode-extension/src/components/autocomplete.ts @@ -1,5 +1,6 @@ import autocomplete from '@/functions/autocomplete'; import * as vscode from 'vscode'; +import autocompleteCommand from '@/commands/autocomplete'; const triggerCharacters: string[] = [' ', '.', '>', ':', '-']; class AutoComplete extends vscode.CompletionItem {} @@ -21,7 +22,7 @@ export default vscode.languages.registerCompletionItemProvider( completionItem.preselect = true; completionItem.insertText = ''; completionItem.command = { - command: 'alova.autocomplete', + command: autocompleteCommand.commandId, title: 'Alova completions...', arguments: [item.replaceText] }; diff --git a/packages/vscode-extension/src/components/error.ts b/packages/vscode-extension/src/components/error.ts index e755a73..f6f6edf 100644 --- a/packages/vscode-extension/src/components/error.ts +++ b/packages/vscode-extension/src/components/error.ts @@ -1,3 +1,9 @@ -export default class extends Error { +export default class AlovaError extends Error { ERROR_CODE = 'error'; + + constructor(message?: string) { + super(message); + this.name = 'AlovaError'; + } } +export const AlovaErrorConstructor = AlovaError as unknown as ErrorConstructor; diff --git a/packages/vscode-extension/src/globalConfig.ts b/packages/vscode-extension/src/globalConfig.ts index b0a393b..e2785c2 100644 --- a/packages/vscode-extension/src/globalConfig.ts +++ b/packages/vscode-extension/src/globalConfig.ts @@ -1,6 +1,6 @@ /* eslint-disable import/prefer-default-export */ -import Error from '@/components/error'; -import { getTypescript, log } from '@/utils/work'; +import { AlovaErrorConstructor } from '@/components/error'; +import { log } from '@/utils/work'; import { setGlobalConfig } from '@alova/wormhole'; import path from 'node:path'; import { pathToFileURL } from 'node:url'; @@ -9,6 +9,5 @@ export const WORK_PATH = pathToFileURL(path.join(__dirname, '/work.js')); // 全局配置 setGlobalConfig({ log, - getTypescript, - Error + Error: AlovaErrorConstructor }); diff --git a/packages/vscode-extension/src/helper/work.ts b/packages/vscode-extension/src/helper/work.ts index 5891d27..1dd5057 100644 --- a/packages/vscode-extension/src/helper/work.ts +++ b/packages/vscode-extension/src/helper/work.ts @@ -33,9 +33,10 @@ export default class AlovaWork { } case 'executeCommand': { this.doneTask(id, type, payload, data => { - const commandId = commandsMap[data as keyof typeof commandsMap]?.commandId; + const { cmd, args } = data; + const commandId = commandsMap[cmd as keyof typeof commandsMap]?.commandId; if (commandId) { - vscode.commands.executeCommand(commandId); + vscode.commands.executeCommand(commandId, ...args); } }); break; diff --git a/packages/vscode-extension/src/utils/work.ts b/packages/vscode-extension/src/utils/work.ts index e949ebf..c46ea52 100644 --- a/packages/vscode-extension/src/utils/work.ts +++ b/packages/vscode-extension/src/utils/work.ts @@ -1,18 +1,17 @@ import type { CommandKey } from '@/commands'; import type { Task } from '@/helper/work'; -import importFresh from 'import-fresh'; -import path from 'node:path'; import { parentPort } from 'worker_threads'; import { uuid } from '.'; import { TASK_MAP } from '../work/config'; +import AlovaError from '@/components/error'; type MessageCallBack = () => T | Promise; -export function createError(err: Error) { +export function createError(err: AlovaError) { return { message: err.message, stack: err.stack, - ERROR_CODE: (err as any).ERROR_CODE - }; + ERROR_CODE: err.ERROR_CODE + } as AlovaError; } export async function postMessage(id: string | null, type: string, cb: MessageCallBack) { let data: any; @@ -55,25 +54,17 @@ export async function setTask(type: string, cb: MessageCallBack) TASK_MAP.set(taskId, { type, payload: { resolve, reject } }); }); } -export function executeCommand(cmd: CommandKey) { - return postMessage(null, 'executeCommand', () => cmd); +export function executeCommand(cmd: CommandKey, ...args: T) { + return postMessage(null, 'executeCommand', () => ({ + cmd, + args + })); } -export const getTypescriptByWorkspace = async (workspaceRootPathArr: string[]) => { - let typescript: typeof import('typescript') | null = null; - for (const workspaceRootPath of workspaceRootPathArr) { - try { - typescript = importFresh(path.join(workspaceRootPath, './node_modules/typescript')); - } catch (error) {} - } - return typescript; -}; export function getWorkspaceRootPathArr() { return setTask('workspaceRootPathArr', () => {}); } -export async function getTypescript() { - return getTypescriptByWorkspace(await getWorkspaceRootPathArr()); -} + export async function log(...args: any[]) { return postMessage(null, 'log', () => args); } diff --git a/packages/vscode-extension/src/work/generateConfig.ts b/packages/vscode-extension/src/work/generateConfig.ts index a84d6a5..65e25e4 100644 --- a/packages/vscode-extension/src/work/generateConfig.ts +++ b/packages/vscode-extension/src/work/generateConfig.ts @@ -1,3 +1,4 @@ import { createConfig } from '@alova/wormhole'; -export default async (workspaceRootPathArr: string[]) => Promise.all(workspaceRootPathArr.map(createConfig)); +export default async (workspaceRootPathArr: string[]) => + Promise.all(workspaceRootPathArr.map(workspaceRootPath => createConfig({ projectPath: workspaceRootPath }))); diff --git a/packages/vscode-extension/src/work/readConfig.ts b/packages/vscode-extension/src/work/readConfig.ts index 374fe0f..a29f69f 100644 --- a/packages/vscode-extension/src/work/readConfig.ts +++ b/packages/vscode-extension/src/work/readConfig.ts @@ -16,13 +16,15 @@ function refeshAutoUpdate(configuration: ConfigObject) { if (oldConfig?.immediate === immediate && oldConfig.time === time && oldTimer?.isRunning()) { return; } + console.log(19, oldConfig, oldTimer?.isRunning()); + oldTimer?.clear(); AUTOUPDATE_CONFIG_MAP.set(configuration, { immediate, time }); AUTOUPDATE_MAP.set( configuration, highPrecisionInterval( () => { - executeCommand('generateApi'); + executeCommand('generateApi', configuration[0]); }, time * 1000, immediate diff --git a/packages/wormhole/package.json b/packages/wormhole/package.json index 5b5104b..0d81293 100644 --- a/packages/wormhole/package.json +++ b/packages/wormhole/package.json @@ -4,7 +4,7 @@ "description": "More modern openAPI generating solution for alova.js", "homepage": "https://alova.js.org", "main": "./dist/index.js", - "types": "./dist/index.d.ts", + "types": "./typings/index.d.ts", "bin": { "alova": "./dist/bin/cli.js" }, diff --git a/packages/wormhole/src/config.ts b/packages/wormhole/src/config.ts index 00d3659..65a8ace 100644 --- a/packages/wormhole/src/config.ts +++ b/packages/wormhole/src/config.ts @@ -1,22 +1,23 @@ import path from 'node:path'; import type { TemplateData } from './functions/openApi2Data'; -export const TEMPLATE_DATA = new Map(); -export const DEFAULT_CONFIG = { +declare global { + // eslint-disable-next-line vars-on-top, no-var + var ALOVA_WORMHOLE_CONFIG: typeof DEFAULT_CONFIG; +} + +const DEFAULT_CONFIG = { alovaTempPath: path.join('node_modules/.alova'), templatePath: path.join(__dirname, './templates'), log: (...messageArr: any[]) => console.log(...messageArr), - getTypescript: async () => { - let ts: typeof import('typescript') | null = null; - try { - ts = (await import('typescript')).default; - } catch {} - return ts; - }, - templateData: TEMPLATE_DATA, + templateData: new Map(), Error }; +global.ALOVA_WORMHOLE_CONFIG = DEFAULT_CONFIG; +export function getGlobalConfig() { + return global.ALOVA_WORMHOLE_CONFIG; +} export function setGlobalConfig(config: Partial) { - Object.assign(DEFAULT_CONFIG, config); + Object.assign(global.ALOVA_WORMHOLE_CONFIG, config); } -export default { DEFAULT_CONFIG, setGlobalConfig }; +export default { getGlobalConfig, setGlobalConfig }; diff --git a/packages/wormhole/src/functions/alovaJson.ts b/packages/wormhole/src/functions/alovaJson.ts index b0be9a1..fccb52c 100644 --- a/packages/wormhole/src/functions/alovaJson.ts +++ b/packages/wormhole/src/functions/alovaJson.ts @@ -1,9 +1,10 @@ -import { DEFAULT_CONFIG } from '@/config'; +import { getGlobalConfig } from '@/config'; import { existsPromise, format } from '@/utils'; import fs from 'node:fs/promises'; import path from 'node:path'; import type { TemplateData } from './openApi2Data'; +const DEFAULT_CONFIG = getGlobalConfig(); export const writeAlovaJson = async (data: TemplateData, originPath: string, name = 'api.json') => { // 将数据转换为 JSON 字符串 const jsonData = await format(JSON.stringify(data, null, 2), { parser: 'json' }); diff --git a/packages/wormhole/src/functions/generateApi.ts b/packages/wormhole/src/functions/generateApi.ts index 525093a..331d445 100644 --- a/packages/wormhole/src/functions/generateApi.ts +++ b/packages/wormhole/src/functions/generateApi.ts @@ -1,4 +1,4 @@ -import { DEFAULT_CONFIG } from '@/config'; +import { getGlobalConfig } from '@/config'; import type { GeneratorConfig, TemplateType } from '@/interface.type'; import { existsPromise } from '@/utils'; import { isEqual } from 'lodash'; @@ -10,6 +10,7 @@ import getAlovaVersion, { AlovaVersion } from './getAlovaVersion'; import getFrameworkTag from './getFrameworkTag'; import openApi2Data from './openApi2Data'; +const DEFAULT_CONFIG = getGlobalConfig(); export default async function ( workspaceRootDir: string, // 项目地址 outputPath: string, // 输出路径 diff --git a/packages/wormhole/src/functions/getFrameworkTag.ts b/packages/wormhole/src/functions/getFrameworkTag.ts index 3dbcd9e..3ec1f2a 100644 --- a/packages/wormhole/src/functions/getFrameworkTag.ts +++ b/packages/wormhole/src/functions/getFrameworkTag.ts @@ -1,6 +1,7 @@ import importFresh from 'import-fresh'; import path from 'node:path'; import { PackageJson } from 'type-fest'; + export const frameworkName: ['vue', 'react'] = ['vue', 'react']; export default function (workspaceRootDir: string) { const packageJson: PackageJson = importFresh(path.resolve(workspaceRootDir, './package.json')); diff --git a/packages/wormhole/src/functions/getOpenApiData.ts b/packages/wormhole/src/functions/getOpenApiData.ts index 46f8f9b..632e45c 100644 --- a/packages/wormhole/src/functions/getOpenApiData.ts +++ b/packages/wormhole/src/functions/getOpenApiData.ts @@ -1,4 +1,4 @@ -import { DEFAULT_CONFIG } from '@/config'; +import { getGlobalConfig } from '@/config'; import type { PlatformType } from '@/interface.type'; import { fetchData } from '@/utils'; import importFresh from 'import-fresh'; @@ -7,6 +7,8 @@ import fs from 'node:fs/promises'; import path from 'node:path'; import { OpenAPIV2, OpenAPIV3_1 } from 'openapi-types'; import swagger2openapi from 'swagger2openapi'; + +const DEFAULT_CONFIG = getGlobalConfig(); // 判断是否是swagger2.0 function isSwagger2(data: any): data is OpenAPIV2.Document { return !!data?.swagger; diff --git a/packages/wormhole/src/functions/openApi2Data.ts b/packages/wormhole/src/functions/openApi2Data.ts index ea2712f..37a7fb2 100644 --- a/packages/wormhole/src/functions/openApi2Data.ts +++ b/packages/wormhole/src/functions/openApi2Data.ts @@ -1,4 +1,4 @@ -import { DEFAULT_CONFIG } from '@/config'; +import { getGlobalConfig } from '@/config'; import { findBy$ref, getStandardRefName, isReferenceObject, mergeObject, removeAll$ref } from '@/helper/openapi'; import { convertToType, jsonSchema2TsStr } from '@/helper/schema2type'; import { getStandardOperationId, getStandardTags } from '@/helper/standard'; @@ -9,6 +9,7 @@ import { cloneDeep, isEmpty } from 'lodash'; import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'; import { AlovaVersion } from './getAlovaVersion'; +const DEFAULT_CONFIG = getGlobalConfig(); type Path = { key: string; method: string; diff --git a/packages/wormhole/src/modules/Configuration.ts b/packages/wormhole/src/modules/Configuration.ts index f35d5d3..fc8cec3 100644 --- a/packages/wormhole/src/modules/Configuration.ts +++ b/packages/wormhole/src/modules/Configuration.ts @@ -1,4 +1,4 @@ -import { DEFAULT_CONFIG } from '@/config'; +import { getGlobalConfig } from '@/config'; import { getAlovaJsonPath, readAlovaJson } from '@/functions/alovaJson'; import getAutoTemplateType from '@/functions/getAutoTemplateType'; import getOpenApiData from '@/functions/getOpenApiData'; @@ -7,6 +7,7 @@ import type { Config, GeneratorConfig, TemplateType } from '@/interface.type'; import { isEmpty } from '@/utils'; import path from 'node:path'; +const DEFAULT_CONFIG = getGlobalConfig(); export default class Configuration { config: Config; diff --git a/packages/wormhole/src/readConfig.ts b/packages/wormhole/src/readConfig.ts index ad0e475..f8a6671 100644 --- a/packages/wormhole/src/readConfig.ts +++ b/packages/wormhole/src/readConfig.ts @@ -2,31 +2,39 @@ import type { Config } from '@/interface.type'; import esbuild from 'esbuild'; import { unlink } from 'node:fs/promises'; import path from 'node:path'; -import { DEFAULT_CONFIG } from './config'; +import { getGlobalConfig } from './config'; import { getAlovaJsonPath } from './functions/alovaJson'; import Configuration from './modules/Configuration'; import { resolveConfigFile } from './utils'; +const DEFAULT_CONFIG = getGlobalConfig(); export const readConfig = async (projectPath = process.cwd()) => { + const time = Date.now(); + console.log(time, 13); + const configFile = await resolveConfigFile(projectPath); if (!configFile) { throw new DEFAULT_CONFIG.Error(`Cannot found config file from path ${projectPath}`); } - const configTmpFileName = `alova_tmp_${Date.now()}.js`; + const configTmpFileName = `alova_tmp_${time}.js`; const outfile = path.join(projectPath, configTmpFileName); await esbuild.build({ entryPoints: [configFile], bundle: true, format: 'cjs', + external: ['esbuild'], platform: 'node', outfile, logLevel: 'silent' }); - + // eslint-disable-next-line import/no-dynamic-require, global-require const module = require(outfile); - const config: Config = module.default || module; - await unlink(outfile); + const config: Config = module.default || module; + unlink(outfile); + // 读取缓存文件并保存 + const configuration = new Configuration(config, projectPath); + configuration.readAlovaJson(); return config; }; @@ -49,14 +57,12 @@ export const getApis = (config: Config, projectPath = process.cwd()) => { } const configuration = new Configuration(config, projectPath); const outputArr = configuration.getAllOutputPath() ?? []; - return outputArr - .map(output => { - const apiPath = getAlovaJsonPath(projectPath, output); - const templateData = DEFAULT_CONFIG.templateData.get(apiPath); - if (!templateData) { - return []; - } - return templateData.pathApis.map(item => item.apis); - }) - .flat(2); + return outputArr.flatMap(output => { + const apiPath = getAlovaJsonPath(projectPath, output); + const templateData = DEFAULT_CONFIG.templateData.get(apiPath); + if (!templateData) { + return []; + } + return templateData.pathApis.flatMap(item => item.apis); + }); }; diff --git a/packages/wormhole/src/utils/index.ts b/packages/wormhole/src/utils/index.ts index eb1c448..e78e397 100644 --- a/packages/wormhole/src/utils/index.ts +++ b/packages/wormhole/src/utils/index.ts @@ -8,8 +8,9 @@ import * as prettierBabel from 'prettier/plugins/babel'; import * as prettierEsTree from 'prettier/plugins/estree'; import * as prettierTs from 'prettier/plugins/typescript'; import * as prettier from 'prettier/standalone'; -import { DEFAULT_CONFIG } from '../config'; +import { getGlobalConfig } from '../config'; +const DEFAULT_CONFIG = getGlobalConfig(); export const prettierConfig: PrettierConfig = { printWidth: 120, tabWidth: 2, @@ -74,7 +75,7 @@ export async function readAndRenderTemplate(templatePath: string, view: any) { try { data = await fs.readFile(path.resolve(DEFAULT_CONFIG.templatePath, `${templatePath}.handlebars`), 'utf-8'); } catch (error) { - data = (await import(`./templates/${templatePath}.handlebars`)).default; + data = (await import(`../templates/${templatePath}.handlebars`)).default; } return handlebars.compile(data)(view); } diff --git a/packages/wormhole/typings/index.d.ts b/packages/wormhole/typings/index.d.ts index 1c1dad9..4889d76 100644 --- a/packages/wormhole/typings/index.d.ts +++ b/packages/wormhole/typings/index.d.ts @@ -92,7 +92,6 @@ declare const DEFAULT_CONFIG: { alovaTempPath: string; templatePath: string; log: (...messageArr: any[]) => void; - getTypescript: () => Promise; templateData: Map; Error: ErrorConstructor; }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2ba8786..41606be 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -94,6 +94,10 @@ importers: version: 2.1.3(@types/node@18.19.59) packages/vscode-extension: + dependencies: + '@alova/wormhole': + specifier: workspace:^ + version: link:../wormhole devDependencies: '@types/vscode': specifier: ^1.89.0 @@ -107,6 +111,12 @@ importers: '@vscode/vsce': specifier: ^2.29.0 version: 2.32.0 + esbuild: + specifier: ^0.24.0 + version: 0.24.0 + esbuild-plugin-alias: + specifier: ^0.2.1 + version: 0.2.1 packages/wormhole: dependencies: @@ -1871,6 +1881,9 @@ packages: es6-promise@3.3.1: resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==} + esbuild-plugin-alias@0.2.1: + resolution: {integrity: sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ==} + esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} @@ -5781,6 +5794,8 @@ snapshots: es6-promise@3.3.1: {} + esbuild-plugin-alias@0.2.1: {} + esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 From 481f3af5265961b780c80f75251cc6a48d6a05db Mon Sep 17 00:00:00 2001 From: czhlin <2324133088@qq.com> Date: Fri, 25 Oct 2024 02:23:34 +0800 Subject: [PATCH 30/47] =?UTF-8?q?feat:=20=E8=A7=A3=E5=86=B3wormhole?= =?UTF-8?q?=E6=89=93=E5=8C=85=E5=90=8Eesbuild=E6=89=BE=E4=B8=8D=E5=88=B0?= =?UTF-8?q?=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + packages/vscode-extension/esbuild.ts | 18 +- packages/vscode-extension/package.json | 5 +- .../src/commands/generateApi.ts | 8 +- .../vscode-extension/src/commands/refresh.ts | 5 +- .../vscode-extension/src/commands/setup.ts | 6 + packages/vscode-extension/src/extension.ts | 1 + packages/vscode-extension/src/helper/work.ts | 36 +- packages/vscode-extension/src/utils/vscode.ts | 14 + packages/vscode-extension/src/work.ts | 6 +- .../vscode-extension/src/work/generate.ts | 10 +- .../vscode-extension/src/work/readConfig.ts | 13 +- packages/wormhole/src/readConfig.ts | 8 +- .../test/__snapshots__/generate.spec.ts.snap | 4818 +++++++++++++++++ packages/wormhole/test/package.json | 6 + pnpm-lock.yaml | 57 +- 16 files changed, 4955 insertions(+), 57 deletions(-) create mode 100644 packages/vscode-extension/src/utils/vscode.ts create mode 100644 packages/wormhole/test/package.json diff --git a/package.json b/package.json index 6b68b29..7fc2875 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "eslint": "^8.57.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^18.0.0", + "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", "husky": "^9.0.11", "lint-staged": "^15.2.2", diff --git a/packages/vscode-extension/esbuild.ts b/packages/vscode-extension/esbuild.ts index aa72152..631ba85 100644 --- a/packages/vscode-extension/esbuild.ts +++ b/packages/vscode-extension/esbuild.ts @@ -1,6 +1,7 @@ import esbuild, { Plugin } from 'esbuild'; import alias from 'esbuild-plugin-alias'; import path from 'node:path'; +import { copy } from 'esbuild-plugin-copy'; const production = process.argv.includes('--production'); const watch = process.argv.includes('--watch'); @@ -35,7 +36,7 @@ async function main() { sourcesContent: false, platform: 'node', outdir: 'out', - external: ['vscode', 'typescript', 'esbuild'], + external: ['vscode', 'esbuild'], logLevel: 'silent', plugins: [ alias({ @@ -43,6 +44,21 @@ async function main() { '~': path.resolve(__dirname, './typings'), '#': path.resolve(__dirname, '.') }) as Plugin, + copy({ + // this is equal to process.cwd(), which means we use cwd path as base path to resolve `to` path + // if not specified, this plugin uses ESBuild.build outdir/outfile options as base path. + assets: [ + { + from: ['./node_modules/esbuild/**/*'], + to: ['node_modules/esbuild'] + }, + { + from: ['./node_modules/@esbuild/**/*'], + to: ['node_modules/@esbuild/'] + } + ], + watch: true + }), /* add to the end of plugins array */ esbuildProblemMatcherPlugin ] diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index c8c8eaa..321b297 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -70,12 +70,15 @@ "url": "https://github.com/alovajs/devtools/issues" }, "devDependencies": { + "@esbuild/linux-x64": "^0.24.0", + "@esbuild/win32-x64": "^0.24.0", "@types/vscode": "^1.89.0", "@vscode/test-cli": "^0.0.9", "@vscode/test-electron": "^2.3.9", "@vscode/vsce": "^2.29.0", "esbuild": "^0.24.0", - "esbuild-plugin-alias": "^0.2.1" + "esbuild-plugin-alias": "^0.2.1", + "esbuild-plugin-copy": "^2.1.1" }, "dependencies": { "@alova/wormhole": "workspace:^" diff --git a/packages/vscode-extension/src/commands/generateApi.ts b/packages/vscode-extension/src/commands/generateApi.ts index a003c2b..2307ca2 100644 --- a/packages/vscode-extension/src/commands/generateApi.ts +++ b/packages/vscode-extension/src/commands/generateApi.ts @@ -4,12 +4,10 @@ import { getFileNameByPath } from '@/utils'; // 用于自动生成 export default { commandId: 'alova.generateApi', - handler: () => async path => { - console.log(path); - - await alovaWork.readConfig(); + handler: () => async (projectPath: string) => { + await alovaWork.readConfig(false, projectPath); // 生成api文件 - const { resultArr } = await alovaWork.generate(); + const { resultArr } = await alovaWork.generate(false, projectPath); for (const [workspaceRootDir, result] of resultArr) { if (result) { message.info(`[${getFileNameByPath(workspaceRootDir)}]:Your API is updated`); diff --git a/packages/vscode-extension/src/commands/refresh.ts b/packages/vscode-extension/src/commands/refresh.ts index fd6938e..dc4f0a9 100644 --- a/packages/vscode-extension/src/commands/refresh.ts +++ b/packages/vscode-extension/src/commands/refresh.ts @@ -18,8 +18,9 @@ export default { errorArr.forEach(([, error]) => { throw error; }); - } catch (error: any) { - if ((error as Error)?.ERROR_CODE) { + } catch (err) { + const error = err as Error; + if (error?.ERROR_CODE) { message.error(error.message); } } finally { diff --git a/packages/vscode-extension/src/commands/setup.ts b/packages/vscode-extension/src/commands/setup.ts index ae7bb04..2f5713e 100644 --- a/packages/vscode-extension/src/commands/setup.ts +++ b/packages/vscode-extension/src/commands/setup.ts @@ -10,6 +10,12 @@ export default { vscode.commands.executeCommand(showStatusBarIcon.commandId); context.subscriptions.push(autocomplete); context.subscriptions.push(outputChannel); + vscode.workspace.onDidChangeWorkspaceFolders(event => { + event.added.forEach(workspacePath => { + console.log(workspacePath, 15); + alovaWork.readConfig(false, `${workspacePath.uri.fsPath}/`); + }); + }); alovaWork.readConfig(); } } as Commonand; diff --git a/packages/vscode-extension/src/extension.ts b/packages/vscode-extension/src/extension.ts index a815929..782f45e 100644 --- a/packages/vscode-extension/src/extension.ts +++ b/packages/vscode-extension/src/extension.ts @@ -19,6 +19,7 @@ process.on('uncaughtException', (err: Error) => { }); process.on('unhandledRejection', (error: Error) => { const errMsg = error?.message ?? error ?? 'unhandledRejection'; + log(errMsg); if (error.ERROR_CODE) { vscode.window.showErrorMessage(errMsg); } diff --git a/packages/vscode-extension/src/helper/work.ts b/packages/vscode-extension/src/helper/work.ts index 1dd5057..8676755 100644 --- a/packages/vscode-extension/src/helper/work.ts +++ b/packages/vscode-extension/src/helper/work.ts @@ -1,10 +1,9 @@ -import { commandsMap } from '@/commands'; import Error from '@/components/error'; import { log } from '@/components/message'; import { WORK_PATH } from '@/globalConfig'; import { uuid } from '@/utils'; +import { getWorkspacePaths, executeCommand } from '@/utils/vscode'; import type { Api } from '@alova/wormhole'; -import * as vscode from 'vscode'; import { Worker } from 'worker_threads'; type MessageCallBack = (data?: any) => T | Promise; @@ -33,18 +32,8 @@ export default class AlovaWork { } case 'executeCommand': { this.doneTask(id, type, payload, data => { - const { cmd, args } = data; - const commandId = commandsMap[cmd as keyof typeof commandsMap]?.commandId; - if (commandId) { - vscode.commands.executeCommand(commandId, ...args); - } - }); - break; - } - case 'workspaceRootPathArr': { - this.postMessage(id, type, () => { - const workspaceFolders = vscode.workspace.workspaceFolders || []; - return workspaceFolders.map(item => `${item.uri.fsPath}/`); + const { cmd = '', args = [] } = data ?? {}; + executeCommand(cmd, ...args); }); break; } @@ -119,18 +108,18 @@ export default class AlovaWork { }); } - generate(force = false) { + generate(force = false, projectPath?: string) { return this.setTask<{ resultArr: Array<[string, boolean]>; errorArr: Array<[string, any]>; - }>('generate', () => force); + }>('generate', () => ({ + force, + projectPath + })); } - async readConfig(isShowError = false) { - const hasConfig = await this.setTask('readConfig', () => { - const workspaceFolders = vscode.workspace.workspaceFolders || []; - return workspaceFolders.map(item => `${item.uri.fsPath}/`); - }); + async readConfig(isShowError = false, projectPath?: string | string[]) { + const hasConfig = await this.setTask('readConfig', () => [projectPath ?? getWorkspacePaths()].flat()); if (!hasConfig && isShowError) { throw new Error('Expected to create alova.config.js in root directory.'); } @@ -141,10 +130,7 @@ export default class AlovaWork { } generateConfig() { - return this.setTask('generateConfig', () => { - const workspaceFolders = vscode.workspace.workspaceFolders || []; - return workspaceFolders.map(item => `${item.uri.fsPath}/`); - }); + return this.setTask('generateConfig', () => getWorkspacePaths()); } } export const alovaWork = new AlovaWork(); diff --git a/packages/vscode-extension/src/utils/vscode.ts b/packages/vscode-extension/src/utils/vscode.ts new file mode 100644 index 0000000..5abafea --- /dev/null +++ b/packages/vscode-extension/src/utils/vscode.ts @@ -0,0 +1,14 @@ +import * as vscode from 'vscode'; +import { CommandKey, commandsMap } from '@/commands'; +// 获取workspacePath文件 +export const getWorkspacePaths = () => { + const workspaceFolders = vscode.workspace.workspaceFolders || []; + return workspaceFolders.map(item => `${item.uri.fsPath}/`); +}; +// 执行Command +export const executeCommand = (cmd: CommandKey, ...args: T) => { + const commandId = commandsMap[cmd]?.commandId; + if (commandId) { + vscode.commands.executeCommand(commandId, ...args); + } +}; diff --git a/packages/vscode-extension/src/work.ts b/packages/vscode-extension/src/work.ts index 4e68a76..0ba0b18 100644 --- a/packages/vscode-extension/src/work.ts +++ b/packages/vscode-extension/src/work.ts @@ -4,7 +4,7 @@ import getApis from '@/work/getApis'; import readConfig from '@/work/readConfig'; import { parentPort } from 'worker_threads'; import './globalConfig'; -import { doneTask, postMessage } from './utils/work'; +import { postMessage } from './utils/work'; /** * work子线程,用来处理主线程不能处理的东西,不能引入vscode模块 */ @@ -22,10 +22,6 @@ parentPort?.on('message', async ({ id, type, payload }) => { postMessage(id, type, () => getApis(payload)); break; } - case 'workspaceRootPathArr': { - doneTask(id, type, () => payload); - break; - } case 'generateConfig': { postMessage(id, type, () => generateConfig(payload)); break; diff --git a/packages/vscode-extension/src/work/generate.ts b/packages/vscode-extension/src/work/generate.ts index 02e72cd..8770f6b 100644 --- a/packages/vscode-extension/src/work/generate.ts +++ b/packages/vscode-extension/src/work/generate.ts @@ -2,10 +2,18 @@ import { generate } from '@alova/wormhole'; import { createError } from '@/utils/work'; import { CONFIG_POOL } from './config'; -export default async (force: boolean) => { +interface GenerateOption { + force?: boolean; + projectPath?: string; +} +export default async (option?: GenerateOption) => { const resultArr = []; const errorArr = []; + const { force = false, projectPath: projectPathValue } = option ?? {}; for (const [projectPath, config] of CONFIG_POOL) { + if (projectPathValue && projectPathValue !== projectPath) { + continue; + } try { const generateResult = await generate(config, { force, diff --git a/packages/vscode-extension/src/work/readConfig.ts b/packages/vscode-extension/src/work/readConfig.ts index a29f69f..4b7944e 100644 --- a/packages/vscode-extension/src/work/readConfig.ts +++ b/packages/vscode-extension/src/work/readConfig.ts @@ -1,6 +1,6 @@ import { highPrecisionInterval } from '@/utils'; -import { executeCommand } from '@/utils/work'; -import { readConfig, getAutoUpdateConfig } from '@alova/wormhole'; +import { executeCommand, log } from '@/utils/work'; +import { readConfig, getAutoUpdateConfig, Config } from '@alova/wormhole'; import { CONFIG_POOL } from './config'; import type { ConfigObject } from './config'; @@ -16,8 +16,6 @@ function refeshAutoUpdate(configuration: ConfigObject) { if (oldConfig?.immediate === immediate && oldConfig.time === time && oldTimer?.isRunning()) { return; } - console.log(19, oldConfig, oldTimer?.isRunning()); - oldTimer?.clear(); AUTOUPDATE_CONFIG_MAP.set(configuration, { immediate, time }); AUTOUPDATE_MAP.set( @@ -43,7 +41,12 @@ function removeConfiguration(workspaceRootPath: string) { export default async (workspaceRootPathArr: string[]) => { let configNum = 0; for (const workspaceRootPath of workspaceRootPathArr) { - const config = await readConfig(workspaceRootPath); + let config: Config | null = null; + try { + config = await readConfig(workspaceRootPath); + } catch (error: any) { + log(error.message); + } if (!config) { removeConfiguration(workspaceRootPath); continue; diff --git a/packages/wormhole/src/readConfig.ts b/packages/wormhole/src/readConfig.ts index f8a6671..6d6d264 100644 --- a/packages/wormhole/src/readConfig.ts +++ b/packages/wormhole/src/readConfig.ts @@ -9,20 +9,16 @@ import { resolveConfigFile } from './utils'; const DEFAULT_CONFIG = getGlobalConfig(); export const readConfig = async (projectPath = process.cwd()) => { - const time = Date.now(); - console.log(time, 13); - const configFile = await resolveConfigFile(projectPath); if (!configFile) { throw new DEFAULT_CONFIG.Error(`Cannot found config file from path ${projectPath}`); } - const configTmpFileName = `alova_tmp_${time}.js`; + const configTmpFileName = `alova_tmp_${Date.now()}.js`; const outfile = path.join(projectPath, configTmpFileName); await esbuild.build({ entryPoints: [configFile], bundle: true, format: 'cjs', - external: ['esbuild'], platform: 'node', outfile, logLevel: 'silent' @@ -31,7 +27,7 @@ export const readConfig = async (projectPath = process.cwd()) => { const module = require(outfile); const config: Config = module.default || module; - unlink(outfile); + await unlink(outfile); // 读取缓存文件并保存 const configuration = new Configuration(config, projectPath); configuration.readAlovaJson(); diff --git a/packages/wormhole/test/__snapshots__/generate.spec.ts.snap b/packages/wormhole/test/__snapshots__/generate.spec.ts.snap index 6ede04c..de713e3 100644 --- a/packages/wormhole/test/__snapshots__/generate.spec.ts.snap +++ b/packages/wormhole/test/__snapshots__/generate.spec.ts.snap @@ -8934,6 +8934,4824 @@ declare global { " `; +exports[`generate API > should generate correspoding \`mediaType\` parameters if matched target \`mediaType\` 1`] = ` +"/// +/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.63 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +export default { + 'clients.generateFromURL': ['GET', '/generate'], + 'servers.generateFromURL': ['GET', '/generate'], + 'documentation.generateFromURL': ['GET', '/generate'], + 'config.generateFromURL': ['GET', '/generate'], + 'clients.generate': ['POST', '/generate'], + 'servers.generate': ['POST', '/generate'], + 'documentation.generate': ['POST', '/generate'], + 'config.generate': ['POST', '/generate'], + 'clients.clientLanguages': ['GET', '/clients'], + 'documentation.clientLanguages': ['GET', '/clients'], + 'servers.serverLanguages': ['GET', '/servers'], + 'documentation.documentationLanguages': ['GET', '/documentation'], + 'clients.languages': ['GET', '/{type}/{version}'], + 'servers.languages': ['GET', '/{type}/{version}'], + 'documentation.languages': ['GET', '/{type}/{version}'], + 'config.languages': ['GET', '/{type}/{version}'], + 'clients.languagesMulti': ['GET', '/types'], + 'servers.languagesMulti': ['GET', '/types'], + 'documentation.languagesMulti': ['GET', '/types'], + 'config.languagesMulti': ['GET', '/types'], + 'clients.listOptions': ['GET', '/options'], + 'servers.listOptions': ['GET', '/options'], + 'documentation.listOptions': ['GET', '/options'], + 'config.listOptions': ['GET', '/options'], + 'clients.generateBundle': ['POST', '/model'], + 'servers.generateBundle': ['POST', '/model'], + 'documentation.generateBundle': ['POST', '/model'], + 'config.generateBundle': ['POST', '/model'], + 'documentation.renderTemplate': ['POST', '/render'] +}; +" +`; + +exports[`generate API > should generate correspoding \`mediaType\` parameters if matched target \`mediaType\` 2`] = ` +"import { createAlova } from 'alova'; +import fetchAdapter from 'alova/fetch'; +import { createApis, withConfigType } from './createApis'; + +export const alovaInstance = createAlova({ + baseURL: '/api', + requestAdapter: fetchAdapter(), + beforeRequest: method => {}, + responded: res => { + return res.json(); + } +}); + +export const $$userConfigMap = withConfigType({}); + +const Apis = createApis(alovaInstance, $$userConfigMap); + +export default Apis; +" +`; + +exports[`generate API > should generate correspoding \`mediaType\` parameters if matched target \`mediaType\` 3`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.63 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, MethodType, AlovaGenerics, AlovaMethodCreateConfig } from 'alova'; +import { Method } from 'alova'; +import apiDefinitions from './apiDefinitions'; + +const createFunctionalProxy = (array: (string | symbol)[], alovaInstance: Alova, configMap: any) => { + // create a new proxy instance + return new Proxy(function () {}, { + get(_, property) { + // record the target property, so that it can get the completed accessing paths + array.push(property); + // always return a new proxy to continue recording accessing paths. + return createFunctionalProxy(array, alovaInstance, configMap); + }, + apply(_, __, [config]) { + const apiPathKey = array.join('.') as keyof typeof apiDefinitions; + const apiItem = apiDefinitions[apiPathKey]; + if (!apiItem) { + throw new Error(\`the api path of \\\`\${apiPathKey}\\\` is not found\`); + } + const mergedConfig = { + ...configMap[apiPathKey], + ...config + }; + const [method, url] = apiItem; + const pathParams = mergedConfig.pathParams; + const urlReplaced = url.replace(/\\{([^}]+)\\}/g, (_, key) => { + const pathParam = pathParams[key]; + return pathParam; + }); + delete mergedConfig.pathParams; + let data = mergedConfig.data; + if (Object.prototype.toString.call(data) === '[object Object]' && typeof FormData !== 'undefined') { + let hasBlobData = false; + const formData = new FormData(); + for (const key in data) { + formData.append(key, data[key]); + if (data[key] instanceof Blob) { + hasBlobData = true; + } + } + data = hasBlobData ? formData : data; + } + return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data); + } + }); +}; + +export const createApis = (alovaInstance: Alova, configMap: any) => { + const Apis = new Proxy({} as Apis, { + get(_, property) { + return createFunctionalProxy([property], alovaInstance, configMap); + } + }); + // define global variable \`Apis\` + (globalThis as any).Apis = Apis; + return Apis; +}; +type MethodConfig = AlovaMethodCreateConfig< + (typeof import('./index'))['alovaInstance'] extends Alova ? AG : any, + any, + T +>; +type APISofParameters = Tag extends keyof Apis + ? Url extends keyof Apis[Tag] + ? Apis[Tag][Url] extends (...args: any) => any + ? Parameters + : any + : any + : any; +type MethodsConfigMap = { + [P in keyof typeof import('./apiDefinitions').default]?: MethodConfig< + P extends \`\${infer Tag}.\${infer Url}\` ? Parameters[0]['transform']>[0] : any + >; +}; +export const withConfigType = (config: Config) => config; +" +`; + +exports[`generate API > should generate correspoding \`mediaType\` parameters if matched target \`mediaType\` 4`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.63 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, AlovaMethodCreateConfig, AlovaGenerics, Method } from 'alova'; +import type { $$userConfigMap, alovaInstance } from '.'; +import type apiDefinitions from './apiDefinitions'; + +type CollapsedAlova = typeof alovaInstance; +type UserMethodConfigMap = typeof $$userConfigMap; + +type Alova2MethodConfig = + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Omit< + AlovaMethodCreateConfig< + AlovaGenerics, + any, + Responded + >, + 'params' + > + : never; + +// Extract the return type of transform function that define in $$userConfigMap, if it not exists, use the default type. +type ExtractUserDefinedTransformed< + DefinitionKey extends keyof typeof apiDefinitions, + Default +> = DefinitionKey extends keyof UserMethodConfigMap + ? UserMethodConfigMap[DefinitionKey]['transform'] extends (...args: any[]) => any + ? Awaited> + : Default + : Default; +type Alova2Method< + Responded, + DefinitionKey extends keyof typeof apiDefinitions, + CurrentConfig extends Alova2MethodConfig +> = + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Method< + AlovaGenerics< + CurrentConfig extends undefined + ? ExtractUserDefinedTransformed + : CurrentConfig['transform'] extends (...args: any[]) => any + ? Awaited> + : ExtractUserDefinedTransformed, + any, + RequestConfig, + Response, + ResponseHeader, + L1Cache, + L2Cache, + SE + > + > + : never; + +export type AuthorizationValue = { + /** + * Authorization value + */ + value?: string; + /** + * Authorization key + */ + keyName?: string; + /** + * Authorization type + */ + type?: 'query' | 'header'; +}; +export type Options = { + /** + * authorization + * --- + * adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + */ + auth?: string; + /** + * authorization + * --- + * adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + */ + authorizationValue?: AuthorizationValue; + /** + * api package + * --- + * package for generated api classes + */ + apiPackage?: string; + /** + * Template Version + * --- + * template version for generation + */ + templateVersion?: string; + /** + * model package + * --- + * package for generated models + */ + modelPackage?: string; + /** + * model name prefix + * --- + * Prefix that will be prepended to all model names. Default is the empty string. + */ + modelNamePrefix?: string; + /** + * model name suffix + * --- + * PrefixSuffix that will be appended to all model names. Default is the empty string. + */ + modelNameSuffix?: string; + /** + * System Properties + * --- + * sets specified system properties in key/value format + */ + systemProperties?: Record; + /** + * instantiation types + * --- + * sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + */ + instantiationTypes?: Record; + /** + * type mappings + * --- + * sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + */ + typeMappings?: Record; + /** + * additional properties + * --- + * sets additional properties that can be referenced by the mustache templates in key/value format. + */ + additionalProperties?: Record; + /** + * language specific primitives + * --- + * specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + */ + languageSpecificPrimitives?: string[]; + /** + * import mappings + * --- + * specifies mappings between a given class and the import that should be used for that class in key/value format. + */ + importMappings?: Record; + /** + * invoker package + * --- + * root package for generated code + */ + invokerPackage?: string; + /** + * group id + * --- + * groupId in generated pom.xml + */ + groupId?: string; + /** + * artifact id + * --- + * artifactId in generated pom.xml + */ + artifactId?: string; + /** + * artifact version + * --- + * artifact version generated in pom.xml + */ + artifactVersion?: string; + /** + * library + * --- + * library template (sub-template) + */ + library?: string; + /** + * git user id + * --- + * Git user ID, e.g. swagger-api. + */ + gitUserId?: string; + /** + * git repo id + * --- + * Git repo ID, e.g. swagger-codegen. + */ + gitRepoId?: string; + /** + * release note + * --- + * Release note, default to 'Minor update'. + */ + releaseNote?: string; + /** + * http user agent + * --- + * HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + */ + httpUserAgent?: string; + /** + * reserved words mappings + * --- + * pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + */ + reservedWordsMappings?: Record; + /** + * ignore file override location + * --- + * Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + */ + ignoreFileOverride?: string; + /** + * remove prefix of the operationId + * --- + * Remove prefix of operationId, e.g. config_getId => getId + */ + removeOperationIdPrefix?: boolean; + skipOverride?: boolean; +}; +export type GenerationRequest = { + /** + * language + * --- + * language to generate (required) + * [required] + */ + lang: string; + /** + * spec in json format. . Alternative to \`specURL\` + */ + spec?: object; + /** + * URL of the spec in json format. Alternative to \`spec\` + */ + specURL?: string; + /** + * type of the spec + */ + type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG'; + /** + * codegen version to use + */ + codegenVersion?: 'V2' | 'V3'; + options?: Options; +}; +export type CliOption = { + optionName?: string; + description?: string; + /** + * Data type is based on the types supported by the JSON-Schema + */ + type?: string; + enum?: Record; + default?: string; +}; +export type RenderRequest = { + /** + * template + * --- + * template as string + * [required] + */ + template: string; + /** + * context + * --- + * context as string + * [required] + */ + context: string; +}; +declare global { + interface Apis { + clients: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'client' or 'documentation' for given codegen version (defaults to V3) + * + * **path:** /clients + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * // flag to only return languages of type \`client\` + * clientOnly?: boolean + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + clientLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + /** + * flag to only return languages of type \`client\` + */ + clientOnly?: boolean; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'clients.listOptions', Config>; + /** + * --- + * + * [POST] Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = object + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + servers: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'server' for given codegen version (defaults to V3) + * + * **path:** /servers + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + serverLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'servers.listOptions', Config>; + /** + * --- + * + * [POST] Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = object + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + documentation: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'client' or 'documentation' for given codegen version (defaults to V3) + * + * **path:** /clients + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * // flag to only return languages of type \`client\` + * clientOnly?: boolean + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + clientLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + /** + * flag to only return languages of type \`client\` + */ + clientOnly?: boolean; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'documentation' for given codegen version (defaults to V3) + * + * **path:** /documentation + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + documentationLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'documentation.listOptions', Config>; + /** + * --- + * + * [POST] Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = object + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] render a template using the provided data + * + * **path:** /render + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] template + * // template as string + * // [required] + * template: string + * // [title] context + * // context as string + * // [required] + * context: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + renderTemplate< + Config extends Alova2MethodConfig & { + data: RenderRequest; + } + >( + config: Config + ): Alova2Method; + }; + config: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'config.listOptions', Config>; + /** + * --- + * + * [POST] Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = object + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + } + + var Apis: Apis; +} +" +`; + +exports[`generate API > should generate corresponding module codes dependent to \`type\` 1`] = ` +"/// +/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.63 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +export default { + 'clients.generateFromURL': ['GET', '/generate'], + 'servers.generateFromURL': ['GET', '/generate'], + 'documentation.generateFromURL': ['GET', '/generate'], + 'config.generateFromURL': ['GET', '/generate'], + 'clients.generate': ['POST', '/generate'], + 'servers.generate': ['POST', '/generate'], + 'documentation.generate': ['POST', '/generate'], + 'config.generate': ['POST', '/generate'], + 'clients.clientLanguages': ['GET', '/clients'], + 'documentation.clientLanguages': ['GET', '/clients'], + 'servers.serverLanguages': ['GET', '/servers'], + 'documentation.documentationLanguages': ['GET', '/documentation'], + 'clients.languages': ['GET', '/{type}/{version}'], + 'servers.languages': ['GET', '/{type}/{version}'], + 'documentation.languages': ['GET', '/{type}/{version}'], + 'config.languages': ['GET', '/{type}/{version}'], + 'clients.languagesMulti': ['GET', '/types'], + 'servers.languagesMulti': ['GET', '/types'], + 'documentation.languagesMulti': ['GET', '/types'], + 'config.languagesMulti': ['GET', '/types'], + 'clients.listOptions': ['GET', '/options'], + 'servers.listOptions': ['GET', '/options'], + 'documentation.listOptions': ['GET', '/options'], + 'config.listOptions': ['GET', '/options'], + 'clients.generateBundle': ['POST', '/model'], + 'servers.generateBundle': ['POST', '/model'], + 'documentation.generateBundle': ['POST', '/model'], + 'config.generateBundle': ['POST', '/model'], + 'documentation.renderTemplate': ['POST', '/render'] +}; +" +`; + +exports[`generate API > should generate corresponding module codes dependent to \`type\` 2`] = ` +"import { createAlova } from 'alova'; +import fetchAdapter from 'alova/fetch'; +import { createApis, withConfigType } from './createApis'; + +export const alovaInstance = createAlova({ + baseURL: '/api', + requestAdapter: fetchAdapter(), + beforeRequest: method => {}, + responded: res => { + return res.json(); + } +}); + +export const $$userConfigMap = withConfigType({}); + +const Apis = createApis(alovaInstance, $$userConfigMap); + +export default Apis; +" +`; + +exports[`generate API > should generate corresponding module codes dependent to \`type\` 3`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.63 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, MethodType, AlovaGenerics, AlovaMethodCreateConfig } from 'alova'; +import { Method } from 'alova'; +import apiDefinitions from './apiDefinitions'; + +const createFunctionalProxy = (array: (string | symbol)[], alovaInstance: Alova, configMap: any) => { + // create a new proxy instance + return new Proxy(function () {}, { + get(_, property) { + // record the target property, so that it can get the completed accessing paths + array.push(property); + // always return a new proxy to continue recording accessing paths. + return createFunctionalProxy(array, alovaInstance, configMap); + }, + apply(_, __, [config]) { + const apiPathKey = array.join('.') as keyof typeof apiDefinitions; + const apiItem = apiDefinitions[apiPathKey]; + if (!apiItem) { + throw new Error(\`the api path of \\\`\${apiPathKey}\\\` is not found\`); + } + const mergedConfig = { + ...configMap[apiPathKey], + ...config + }; + const [method, url] = apiItem; + const pathParams = mergedConfig.pathParams; + const urlReplaced = url.replace(/\\{([^}]+)\\}/g, (_, key) => { + const pathParam = pathParams[key]; + return pathParam; + }); + delete mergedConfig.pathParams; + let data = mergedConfig.data; + if (Object.prototype.toString.call(data) === '[object Object]' && typeof FormData !== 'undefined') { + let hasBlobData = false; + const formData = new FormData(); + for (const key in data) { + formData.append(key, data[key]); + if (data[key] instanceof Blob) { + hasBlobData = true; + } + } + data = hasBlobData ? formData : data; + } + return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data); + } + }); +}; + +export const createApis = (alovaInstance: Alova, configMap: any) => { + const Apis = new Proxy({} as Apis, { + get(_, property) { + return createFunctionalProxy([property], alovaInstance, configMap); + } + }); + // define global variable \`Apis\` + (globalThis as any).Apis = Apis; + return Apis; +}; +type MethodConfig = AlovaMethodCreateConfig< + (typeof import('./index'))['alovaInstance'] extends Alova ? AG : any, + any, + T +>; +type APISofParameters = Tag extends keyof Apis + ? Url extends keyof Apis[Tag] + ? Apis[Tag][Url] extends (...args: any) => any + ? Parameters + : any + : any + : any; +type MethodsConfigMap = { + [P in keyof typeof import('./apiDefinitions').default]?: MethodConfig< + P extends \`\${infer Tag}.\${infer Url}\` ? Parameters[0]['transform']>[0] : any + >; +}; +export const withConfigType = (config: Config) => config; +" +`; + +exports[`generate API > should generate corresponding module codes dependent to \`type\` 4`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.63 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, AlovaMethodCreateConfig, AlovaGenerics, Method } from 'alova'; +import type { $$userConfigMap, alovaInstance } from '.'; +import type apiDefinitions from './apiDefinitions'; + +type CollapsedAlova = typeof alovaInstance; +type UserMethodConfigMap = typeof $$userConfigMap; + +type Alova2MethodConfig = + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Omit< + AlovaMethodCreateConfig< + AlovaGenerics, + any, + Responded + >, + 'params' + > + : never; + +// Extract the return type of transform function that define in $$userConfigMap, if it not exists, use the default type. +type ExtractUserDefinedTransformed< + DefinitionKey extends keyof typeof apiDefinitions, + Default +> = DefinitionKey extends keyof UserMethodConfigMap + ? UserMethodConfigMap[DefinitionKey]['transform'] extends (...args: any[]) => any + ? Awaited> + : Default + : Default; +type Alova2Method< + Responded, + DefinitionKey extends keyof typeof apiDefinitions, + CurrentConfig extends Alova2MethodConfig +> = + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Method< + AlovaGenerics< + CurrentConfig extends undefined + ? ExtractUserDefinedTransformed + : CurrentConfig['transform'] extends (...args: any[]) => any + ? Awaited> + : ExtractUserDefinedTransformed, + any, + RequestConfig, + Response, + ResponseHeader, + L1Cache, + L2Cache, + SE + > + > + : never; + +export type AuthorizationValue = { + /** + * Authorization value + */ + value?: string; + /** + * Authorization key + */ + keyName?: string; + /** + * Authorization type + */ + type?: 'query' | 'header'; +}; +export type Options = { + /** + * authorization + * --- + * adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + */ + auth?: string; + /** + * authorization + * --- + * adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + */ + authorizationValue?: AuthorizationValue; + /** + * api package + * --- + * package for generated api classes + */ + apiPackage?: string; + /** + * Template Version + * --- + * template version for generation + */ + templateVersion?: string; + /** + * model package + * --- + * package for generated models + */ + modelPackage?: string; + /** + * model name prefix + * --- + * Prefix that will be prepended to all model names. Default is the empty string. + */ + modelNamePrefix?: string; + /** + * model name suffix + * --- + * PrefixSuffix that will be appended to all model names. Default is the empty string. + */ + modelNameSuffix?: string; + /** + * System Properties + * --- + * sets specified system properties in key/value format + */ + systemProperties?: Record; + /** + * instantiation types + * --- + * sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + */ + instantiationTypes?: Record; + /** + * type mappings + * --- + * sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + */ + typeMappings?: Record; + /** + * additional properties + * --- + * sets additional properties that can be referenced by the mustache templates in key/value format. + */ + additionalProperties?: Record; + /** + * language specific primitives + * --- + * specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + */ + languageSpecificPrimitives?: string[]; + /** + * import mappings + * --- + * specifies mappings between a given class and the import that should be used for that class in key/value format. + */ + importMappings?: Record; + /** + * invoker package + * --- + * root package for generated code + */ + invokerPackage?: string; + /** + * group id + * --- + * groupId in generated pom.xml + */ + groupId?: string; + /** + * artifact id + * --- + * artifactId in generated pom.xml + */ + artifactId?: string; + /** + * artifact version + * --- + * artifact version generated in pom.xml + */ + artifactVersion?: string; + /** + * library + * --- + * library template (sub-template) + */ + library?: string; + /** + * git user id + * --- + * Git user ID, e.g. swagger-api. + */ + gitUserId?: string; + /** + * git repo id + * --- + * Git repo ID, e.g. swagger-codegen. + */ + gitRepoId?: string; + /** + * release note + * --- + * Release note, default to 'Minor update'. + */ + releaseNote?: string; + /** + * http user agent + * --- + * HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + */ + httpUserAgent?: string; + /** + * reserved words mappings + * --- + * pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + */ + reservedWordsMappings?: Record; + /** + * ignore file override location + * --- + * Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + */ + ignoreFileOverride?: string; + /** + * remove prefix of the operationId + * --- + * Remove prefix of operationId, e.g. config_getId => getId + */ + removeOperationIdPrefix?: boolean; + skipOverride?: boolean; +}; +export type GenerationRequest = { + /** + * language + * --- + * language to generate (required) + * [required] + */ + lang: string; + /** + * spec in json format. . Alternative to \`specURL\` + */ + spec?: object; + /** + * URL of the spec in json format. Alternative to \`spec\` + */ + specURL?: string; + /** + * type of the spec + */ + type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG'; + /** + * codegen version to use + */ + codegenVersion?: 'V2' | 'V3'; + options?: Options; +}; +export type CliOption = { + optionName?: string; + description?: string; + /** + * Data type is based on the types supported by the JSON-Schema + */ + type?: string; + enum?: Record; + default?: string; +}; +export type RenderRequest = { + /** + * template + * --- + * template as string + * [required] + */ + template: string; + /** + * context + * --- + * context as string + * [required] + */ + context: string; +}; +declare global { + interface Apis { + clients: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'client' or 'documentation' for given codegen version (defaults to V3) + * + * **path:** /clients + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * // flag to only return languages of type \`client\` + * clientOnly?: boolean + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + clientLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + /** + * flag to only return languages of type \`client\` + */ + clientOnly?: boolean; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'clients.listOptions', Config>; + /** + * --- + * + * [POST] Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = object + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + servers: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'server' for given codegen version (defaults to V3) + * + * **path:** /servers + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + serverLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'servers.listOptions', Config>; + /** + * --- + * + * [POST] Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = object + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + documentation: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'client' or 'documentation' for given codegen version (defaults to V3) + * + * **path:** /clients + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * // flag to only return languages of type \`client\` + * clientOnly?: boolean + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + clientLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + /** + * flag to only return languages of type \`client\` + */ + clientOnly?: boolean; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'documentation' for given codegen version (defaults to V3) + * + * **path:** /documentation + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + documentationLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'documentation.listOptions', Config>; + /** + * --- + * + * [POST] Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = object + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] render a template using the provided data + * + * **path:** /render + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] template + * // template as string + * // [required] + * template: string + * // [title] context + * // context as string + * // [required] + * context: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + renderTemplate< + Config extends Alova2MethodConfig & { + data: RenderRequest; + } + >( + config: Config + ): Alova2Method; + }; + config: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'config.listOptions', Config>; + /** + * --- + * + * [POST] Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = object + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + } + + var Apis: Apis; +} +" +`; + exports[`generate API > should generate target versioned code 1`] = ` "/// /* tslint:disable */ diff --git a/packages/wormhole/test/package.json b/packages/wormhole/test/package.json new file mode 100644 index 0000000..e977916 --- /dev/null +++ b/packages/wormhole/test/package.json @@ -0,0 +1,6 @@ +{ + "name": "test-pkg", + "type": "commonjs", + "version": "1.0.0", + "devDependencies": {} +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 41606be..6b0404e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -53,9 +53,12 @@ importers: eslint-config-airbnb-typescript: specifier: ^18.0.0 version: 18.0.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1) + eslint-config-prettier: + specifier: ^9.1.0 + version: 9.1.0(eslint@8.57.1) eslint-plugin-prettier: specifier: ^5.1.3 - version: 5.2.1(eslint@8.57.1)(prettier@3.3.3) + version: 5.2.1(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.3.3) husky: specifier: ^9.0.11 version: 9.1.6 @@ -99,6 +102,12 @@ importers: specifier: workspace:^ version: link:../wormhole devDependencies: + '@esbuild/linux-x64': + specifier: ^0.24.0 + version: 0.24.0 + '@esbuild/win32-x64': + specifier: ^0.24.0 + version: 0.24.0 '@types/vscode': specifier: ^1.89.0 version: 1.94.0 @@ -117,6 +126,9 @@ importers: esbuild-plugin-alias: specifier: ^0.2.1 version: 0.2.1 + esbuild-plugin-copy: + specifier: ^2.1.1 + version: 2.1.1(esbuild@0.24.0) packages/wormhole: dependencies: @@ -1884,6 +1896,11 @@ packages: esbuild-plugin-alias@0.2.1: resolution: {integrity: sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ==} + esbuild-plugin-copy@2.1.1: + resolution: {integrity: sha512-Bk66jpevTcV8KMFzZI1P7MZKZ+uDcrZm2G2egZ2jNIvVnivDpodZI+/KnpL3Jnap0PBdIHU7HwFGB8r+vV5CVw==} + peerDependencies: + esbuild: '>= 0.14.0' + esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} @@ -1935,6 +1952,12 @@ packages: eslint-plugin-react: ^7.28.0 eslint-plugin-react-hooks: ^4.3.0 + eslint-config-prettier@9.1.0: + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} @@ -2152,6 +2175,10 @@ packages: fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + fs-extra@9.1.0: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} @@ -4481,8 +4508,7 @@ snapshots: '@esbuild/linux-x64@0.23.1': optional: true - '@esbuild/linux-x64@0.24.0': - optional: true + '@esbuild/linux-x64@0.24.0': {} '@esbuild/netbsd-x64@0.21.5': optional: true @@ -4541,8 +4567,7 @@ snapshots: '@esbuild/win32-x64@0.23.1': optional: true - '@esbuild/win32-x64@0.24.0': - optional: true + '@esbuild/win32-x64@0.24.0': {} '@eslint-community/eslint-utils@4.4.0(eslint@8.57.1)': dependencies: @@ -5796,6 +5821,14 @@ snapshots: esbuild-plugin-alias@0.2.1: {} + esbuild-plugin-copy@2.1.1(esbuild@0.24.0): + dependencies: + chalk: 4.1.2 + chokidar: 3.6.0 + esbuild: 0.24.0 + fs-extra: 10.1.0 + globby: 11.1.0 + esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 @@ -5911,6 +5944,10 @@ snapshots: object.assign: 4.1.5 object.entries: 1.1.8 + eslint-config-prettier@9.1.0(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + eslint-import-resolver-node@0.3.9: dependencies: debug: 3.2.7 @@ -5978,12 +6015,14 @@ snapshots: safe-regex-test: 1.0.3 string.prototype.includes: 2.0.1 - eslint-plugin-prettier@5.2.1(eslint@8.57.1)(prettier@3.3.3): + eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.3.3): dependencies: eslint: 8.57.1 prettier: 3.3.3 prettier-linter-helpers: 1.0.0 synckit: 0.9.2 + optionalDependencies: + eslint-config-prettier: 9.1.0(eslint@8.57.1) eslint-plugin-react-hooks@4.6.2(eslint@8.57.1): dependencies: @@ -6209,6 +6248,12 @@ snapshots: fs-constants@1.0.0: optional: true + fs-extra@10.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + fs-extra@9.1.0: dependencies: at-least-node: 1.0.0 From 6667ced587a1567c79bf1b35b9acd264ada19498 Mon Sep 17 00:00:00 2001 From: czhlin <2324133088@qq.com> Date: Fri, 25 Oct 2024 09:02:41 +0800 Subject: [PATCH 31/47] =?UTF-8?q?fix(wormhole):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95=E4=B8=ADtoMatch=E5=A4=84?= =?UTF-8?q?=E7=90=86=E5=A4=9A=E8=A1=8C=E6=96=87=E6=9C=AC=E9=97=AE=E9=A2=98?= =?UTF-8?q?/s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/wormhole/test/generate.spec.ts | 97 +++++++++++++++++-------- packages/wormhole/test/util.ts | 4 + 2 files changed, 69 insertions(+), 32 deletions(-) diff --git a/packages/wormhole/test/generate.spec.ts b/packages/wormhole/test/generate.spec.ts index 997e6cf..2ea835d 100644 --- a/packages/wormhole/test/generate.spec.ts +++ b/packages/wormhole/test/generate.spec.ts @@ -1,6 +1,7 @@ import generate from '@/generate'; import fs from 'node:fs/promises'; import { resolve } from 'node:path'; +import { createStrReg } from './util'; vi.mock('node:fs'); vi.mock('node:fs/promises'); @@ -297,11 +298,13 @@ describe('generate API', () => { }); let globalsDeclarationFile = await fs.readFile(resolve(outputDir, 'globals.d.ts'), 'utf-8'); - expect(globalsDeclarationFile).toMatch(`generateBundle< + expect(globalsDeclarationFile).toMatch( + createStrReg(`generateBundle< Config extends Alova2MethodConfig & { data: GenerationRequest; } - >`); + >`) + ); expect(globalsDeclarationFile).toMatch(`: Alova2Method;`); // custom mediaType: application/json @@ -318,11 +321,13 @@ describe('generate API', () => { }); globalsDeclarationFile = await fs.readFile(resolve(outputDir2, 'globals.d.ts'), 'utf-8'); - expect(globalsDeclarationFile).toMatch(`generateBundle< + expect(globalsDeclarationFile).toMatch( + createStrReg(`generateBundle< Config extends Alova2MethodConfig & { data: GenerationRequest; } - >`); + >`) + ); expect(globalsDeclarationFile).toMatch(`: Alova2Method;`); // custom mediaType: application/xml @@ -340,11 +345,13 @@ describe('generate API', () => { }); globalsDeclarationFile = await fs.readFile(resolve(outputDir3, 'globals.d.ts'), 'utf-8'); - expect(globalsDeclarationFile).toMatch(`generateBundle< + expect(globalsDeclarationFile).toMatch( + createStrReg(`generateBundle< Config extends Alova2MethodConfig & { data: GenerationRequest; } - >`); + >`) + ); expect(globalsDeclarationFile).toMatch(`: Alova2Method;`); }); @@ -362,13 +369,15 @@ describe('generate API', () => { }); const globalsDeclarationFile = await fs.readFile(resolve(outputDir, 'globals.d.ts'), 'utf-8'); - expect(globalsDeclarationFile).toMatch(`pet24< + expect(globalsDeclarationFile).toMatch( + createStrReg(`pet24< Config extends Alova2MethodConfig & { data: Category; } >( config: Config - ): Alova2Method;`); + ): Alova2Method;`) + ); }); test('should auto detect generating module codes if not set `type`', async () => { @@ -430,10 +439,12 @@ describe('generate API', () => { } ); const fileContentCjs = await fs.readFile(resolve(outputDir3, 'createApis.js'), 'utf-8'); - expect(fileContentCjs).toMatch(`module.exports = { + expect(fileContentCjs).toMatch( + createStrReg(`module.exports = { createApis, withConfigType -};`); +};`) + ); unlinkSync(tempPkgFile); }); @@ -490,10 +501,12 @@ describe('generate API', () => { ] }); const fileContentCjs = await fs.readFile(resolve(outputDir3, 'createApis.js'), 'utf-8'); - expect(fileContentCjs).toMatch(`module.exports = { + expect(fileContentCjs).toMatch( + createStrReg(`module.exports = { createApis, withConfigType -};`); +};`) + ); }); test('should set the right global variable name', async () => { @@ -609,7 +622,8 @@ describe('generate API', () => { ] }); const globalsFile = await fs.readFile(resolve(outputDir, 'globals.d.ts'), 'utf-8'); - expect(globalsFile).toMatch(`type Response = { + expect(globalsFile).toMatch( + createStrReg(`type Response = { * id?: number * // [title] Pet category * // A category for a pet @@ -634,7 +648,8 @@ describe('generate API', () => { * // pet status in the store * // [deprecated] * status?: 'available' | 'pending' | 'sold' - * }`); + * }`) + ); }); test('should automatically convert object that contains `Blob` to `FormData`', async () => { @@ -663,14 +678,17 @@ describe('generate API', () => { }); const globalsFile = await fs.readFile(resolve(outputDir, 'globals.d.ts'), 'utf-8'); - expect(globalsFile).toMatch(`generateBundle< + expect(globalsFile).toMatch( + createStrReg(`generateBundle< Config extends Alova2MethodConfig & { data: GenerationRequest; } >( config: Config - ): Alova2Method;`); - expect(globalsFile).toMatch(`clientLanguages< + ): Alova2Method;`) + ); + expect(globalsFile).toMatch( + createStrReg(`clientLanguages< Config extends Alova2MethodConfig & { params: { /** @@ -683,7 +701,8 @@ describe('generate API', () => { clientOnly?: boolean; }; } - >`); + >`) + ); }); test('should `handleApi` handler change all descriptors', async () => { @@ -750,12 +769,15 @@ describe('generate API', () => { }); const globalsFile = await fs.readFile(resolve(outputDir, 'globals.d.ts'), 'utf-8'); // check only generate specified apis - expect(globalsFile).toMatch(`documentationLanguages< + expect(globalsFile).toMatch( + createStrReg(`documentationLanguages< Config extends Alova2MethodConfig<{ attr1?: string; attr2?: number; - }>`); - expect(globalsFile).toMatch(`customClients< + }>`) + ); + expect(globalsFile).toMatch( + createStrReg(`customClients< Config extends Alova2MethodConfig & { pathParams: { /** @@ -779,25 +801,30 @@ describe('generate API', () => { id: number; }; } - >`); - expect(globalsFile).toMatch(`generateBundle< + >`) + ); + expect(globalsFile).toMatch( + createStrReg(`generateBundle< Config extends Alova2MethodConfig & { data: { attr1?: string; }; } - >`); + >`) + ); expect(globalsFile).not.toMatch('serverLanguages'); expect(globalsFile).not.toMatch('listOptions'); expect(globalsFile).not.toMatch('generateFromURL'); const apiDefinitionsFile = await fs.readFile(resolve(outputDir, 'apiDefinitions.ts'), 'utf-8'); - expect(apiDefinitionsFile).toMatch(`export default { + expect(apiDefinitionsFile).toMatch( + createStrReg(`export default { 'clients.customClients': ['GET', '/clients/suffix'], 'documentation.customClients': ['GET', '/clients/suffix'], 'documentation.documentationLanguages': ['GET', '/documentation'], 'clients.generateBundle': ['POST', '/model'] -};`); +};`) + ); }); test('should only effect component type of modified descriptor when this component is refered by multiple descriptor', async () => { @@ -832,23 +859,28 @@ describe('generate API', () => { const globalsFile = await fs.readFile(resolve(outputDir, 'globals.d.ts'), 'utf-8'); // generate separated `Pet1` from `Pet` - expect(globalsFile).toMatch(`pet24< + expect(globalsFile).toMatch( + createStrReg(`pet24< Config extends Alova2MethodConfig & { data: Pet; } >( config: Config - ): Alova2Method;`); + ): Alova2Method;`) + ); // generate separated `Pet2` from `Pet` - expect(globalsFile).toMatch(`updatePet< + expect(globalsFile).toMatch( + createStrReg(`updatePet< Config extends Alova2MethodConfig & { data: Pet; } >( config: Config - ): Alova2Method;`); + ): Alova2Method;`) + ); // the unmodified api still reference `Pet` - expect(globalsFile).toMatch(`findPetsByStatus< + expect(globalsFile).toMatch( + createStrReg(`findPetsByStatus< Config extends Alova2MethodConfig & { params: { /** @@ -861,6 +893,7 @@ describe('generate API', () => { } >( config: Config - ): Alova2Method;`); + ): Alova2Method;`) + ); }); }); diff --git a/packages/wormhole/test/util.ts b/packages/wormhole/test/util.ts index d94057d..c3dbb43 100644 --- a/packages/wormhole/test/util.ts +++ b/packages/wormhole/test/util.ts @@ -24,3 +24,7 @@ export const initExpect = () => { } }); }; +export const createStrReg = (str: string) => { + str = str.replace(/([[\](){}.*+|\\/^$?])/g, '\\$1').replace(/\s/g, '\\s+'); + return new RegExp(str); +}; From f7a5cc19a12ec8edb0595988c2d6e213035f8f1c Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Fri, 25 Oct 2024 18:41:16 +0800 Subject: [PATCH 32/47] =?UTF-8?q?feat(vscode-extension):=20=E5=8E=BB?= =?UTF-8?q?=E9=99=A4work=E6=A8=A1=E5=BC=8F=E3=80=81=E5=8E=BB=E6=8E=89?= =?UTF-8?q?=E4=BE=9D=E8=B5=96esbuild=EF=BC=8C=E6=94=B9=E4=B8=BA=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E6=8F=90=E4=BE=9B@alova/wormhole=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/vscode-extension/esbuild.ts | 23 +-- packages/vscode-extension/package.json | 8 +- .../src/commands/createConfig.ts | 5 +- .../src/commands/generateApi.ts | 7 +- .../vscode-extension/src/commands/refresh.ts | 16 +-- .../vscode-extension/src/commands/setup.ts | 12 +- packages/vscode-extension/src/extension.ts | 1 + .../src/functions/autocomplete.ts | 4 +- .../src/{work => functions}/generate.ts | 12 +- .../src/{work => functions}/generateConfig.ts | 2 +- .../src/{work => functions}/getApis.ts | 4 +- .../src/functions/getWormhole.ts | 20 +++ .../src/functions/readConfig.ts | 82 +++++++++++ packages/vscode-extension/src/globalConfig.ts | 9 +- .../src/{work => helper}/config.ts | 2 - packages/vscode-extension/src/helper/work.ts | 136 ------------------ .../vscode-extension/src/helper/wormhole.ts | 6 + packages/vscode-extension/src/utils/work.ts | 70 --------- packages/vscode-extension/src/work.ts | 33 ----- .../vscode-extension/src/work/readConfig.ts | 65 --------- packages/wormhole/package.json | 10 +- packages/wormhole/scripts/build-copy.ts | 4 + packages/wormhole/src/readConfig.ts | 2 + packages/wormhole/test/package.json | 6 - packages/wormhole/test/util.ts | 2 +- packages/wormhole/tsconfig.json | 2 +- packages/wormhole/typings/index.d.ts | 1 + pnpm-lock.yaml | 124 ++++++++++++---- scripts/api-test.ts | 3 +- test/api-common/alova.config.js | 5 +- test/api-js-commonjs-test/package.json | 3 + test/api-js-test/package.json | 3 + test/api-ts-test/package.json | 1 + test/api-v3-js-commonjs-test/package.json | 3 + test/api-v3-js-test/package.json | 3 + test/api-v3-ts-test/package.json | 1 + tsconfig.json | 4 +- 37 files changed, 285 insertions(+), 409 deletions(-) rename packages/vscode-extension/src/{work => functions}/generate.ts (65%) rename packages/vscode-extension/src/{work => functions}/generateConfig.ts (77%) rename packages/vscode-extension/src/{work => functions}/getApis.ts (72%) create mode 100644 packages/vscode-extension/src/functions/getWormhole.ts create mode 100644 packages/vscode-extension/src/functions/readConfig.ts rename packages/vscode-extension/src/{work => helper}/config.ts (63%) delete mode 100644 packages/vscode-extension/src/helper/work.ts create mode 100644 packages/vscode-extension/src/helper/wormhole.ts delete mode 100644 packages/vscode-extension/src/utils/work.ts delete mode 100644 packages/vscode-extension/src/work.ts delete mode 100644 packages/vscode-extension/src/work/readConfig.ts create mode 100644 packages/wormhole/scripts/build-copy.ts delete mode 100644 packages/wormhole/test/package.json diff --git a/packages/vscode-extension/esbuild.ts b/packages/vscode-extension/esbuild.ts index 631ba85..4b0932f 100644 --- a/packages/vscode-extension/esbuild.ts +++ b/packages/vscode-extension/esbuild.ts @@ -1,7 +1,6 @@ import esbuild, { Plugin } from 'esbuild'; import alias from 'esbuild-plugin-alias'; import path from 'node:path'; -import { copy } from 'esbuild-plugin-copy'; const production = process.argv.includes('--production'); const watch = process.argv.includes('--watch'); @@ -25,10 +24,7 @@ const esbuildProblemMatcherPlugin: Plugin = { async function main() { const ctx = await esbuild.context({ - entryPoints: ['src/extension.ts', 'src/work.ts'], - loader: { - '.handlebars': 'text' - }, + entryPoints: ['src/extension.ts'], bundle: true, format: 'cjs', minify: production, @@ -36,7 +32,7 @@ async function main() { sourcesContent: false, platform: 'node', outdir: 'out', - external: ['vscode', 'esbuild'], + external: ['vscode'], logLevel: 'silent', plugins: [ alias({ @@ -44,21 +40,6 @@ async function main() { '~': path.resolve(__dirname, './typings'), '#': path.resolve(__dirname, '.') }) as Plugin, - copy({ - // this is equal to process.cwd(), which means we use cwd path as base path to resolve `to` path - // if not specified, this plugin uses ESBuild.build outdir/outfile options as base path. - assets: [ - { - from: ['./node_modules/esbuild/**/*'], - to: ['node_modules/esbuild'] - }, - { - from: ['./node_modules/@esbuild/**/*'], - to: ['node_modules/@esbuild/'] - } - ], - watch: true - }), /* add to the end of plugins array */ esbuildProblemMatcherPlugin ] diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index 321b297..261e3bd 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -70,17 +70,15 @@ "url": "https://github.com/alovajs/devtools/issues" }, "devDependencies": { - "@esbuild/linux-x64": "^0.24.0", - "@esbuild/win32-x64": "^0.24.0", "@types/vscode": "^1.89.0", "@vscode/test-cli": "^0.0.9", "@vscode/test-electron": "^2.3.9", "@vscode/vsce": "^2.29.0", "esbuild": "^0.24.0", - "esbuild-plugin-alias": "^0.2.1", - "esbuild-plugin-copy": "^2.1.1" + "esbuild-plugin-alias": "^0.2.1" }, "dependencies": { - "@alova/wormhole": "workspace:^" + "@alova/wormhole": "workspace:^", + "import-fresh": "^3.3.0" } } diff --git a/packages/vscode-extension/src/commands/createConfig.ts b/packages/vscode-extension/src/commands/createConfig.ts index 30dc391..65c6ea0 100644 --- a/packages/vscode-extension/src/commands/createConfig.ts +++ b/packages/vscode-extension/src/commands/createConfig.ts @@ -1,9 +1,10 @@ // 用于自动生成alova.config.js -import { alovaWork } from '@/helper/work'; +import generateConfig from '@/functions/generateConfig'; +import { getWorkspacePaths } from '@/utils/vscode'; export default { commandId: 'alova.create.config', handler: () => async () => { - alovaWork.generateConfig(); + generateConfig(getWorkspacePaths()); } } as Commonand; diff --git a/packages/vscode-extension/src/commands/generateApi.ts b/packages/vscode-extension/src/commands/generateApi.ts index 2307ca2..9b41ff1 100644 --- a/packages/vscode-extension/src/commands/generateApi.ts +++ b/packages/vscode-extension/src/commands/generateApi.ts @@ -1,13 +1,14 @@ import message from '@/components/message'; -import { alovaWork } from '@/helper/work'; +import readConfig from '@/functions/readConfig'; +import generate from '@/functions/generate'; import { getFileNameByPath } from '@/utils'; // 用于自动生成 export default { commandId: 'alova.generateApi', handler: () => async (projectPath: string) => { - await alovaWork.readConfig(false, projectPath); + await readConfig(projectPath); // 生成api文件 - const { resultArr } = await alovaWork.generate(false, projectPath); + const { resultArr } = await generate({ projectPath }); for (const [workspaceRootDir, result] of resultArr) { if (result) { message.info(`[${getFileNameByPath(workspaceRootDir)}]:Your API is updated`); diff --git a/packages/vscode-extension/src/commands/refresh.ts b/packages/vscode-extension/src/commands/refresh.ts index dc4f0a9..d47cfae 100644 --- a/packages/vscode-extension/src/commands/refresh.ts +++ b/packages/vscode-extension/src/commands/refresh.ts @@ -1,28 +1,28 @@ import Error from '@/components/error'; import message from '@/components/message'; import { loading, reset } from '@/components/statusBar'; -import { alovaWork } from '@/helper/work'; +import generate from '@/functions/generate'; +import readConfig, { updatedConfigPool } from '@/functions/readConfig'; import { getFileNameByPath } from '@/utils'; +import { getWorkspacePaths } from '@/utils/vscode'; export default { commandId: 'alova.refresh', handler: () => async () => { try { - await alovaWork.readConfig(true); loading(); + if (!(await readConfig(getWorkspacePaths()))) { + throw new Error('Expected to create alova.config.js in root directory.'); + } + updatedConfigPool(); // 生成api文件 - const { resultArr, errorArr } = await alovaWork.generate(true); + const { resultArr, errorArr } = await generate({ force: true }); for (const [workspaceRootDir] of resultArr) { message.info(`[${getFileNameByPath(workspaceRootDir)}]:Your API is refresh`); } errorArr.forEach(([, error]) => { throw error; }); - } catch (err) { - const error = err as Error; - if (error?.ERROR_CODE) { - message.error(error.message); - } } finally { reset(); } diff --git a/packages/vscode-extension/src/commands/setup.ts b/packages/vscode-extension/src/commands/setup.ts index 2f5713e..1aae31b 100644 --- a/packages/vscode-extension/src/commands/setup.ts +++ b/packages/vscode-extension/src/commands/setup.ts @@ -1,8 +1,9 @@ import autocomplete from '@/components/autocomplete'; import { outputChannel } from '@/components/message'; -import { alovaWork } from '@/helper/work'; +import readConfig, { updatedConfigPool } from '@/functions/readConfig'; import * as vscode from 'vscode'; import showStatusBarIcon from './showStatusBarIcon'; +import { getWorkspacePaths } from '@/utils/vscode'; export default { commandId: 'alova.setup', @@ -12,10 +13,13 @@ export default { context.subscriptions.push(outputChannel); vscode.workspace.onDidChangeWorkspaceFolders(event => { event.added.forEach(workspacePath => { - console.log(workspacePath, 15); - alovaWork.readConfig(false, `${workspacePath.uri.fsPath}/`); + readConfig(`${workspacePath.uri.fsPath}/`); + }); + event.removed.forEach(() => { + readConfig(getWorkspacePaths()); + updatedConfigPool(); }); }); - alovaWork.readConfig(); + readConfig(getWorkspacePaths()); } } as Commonand; diff --git a/packages/vscode-extension/src/extension.ts b/packages/vscode-extension/src/extension.ts index 782f45e..20458e0 100644 --- a/packages/vscode-extension/src/extension.ts +++ b/packages/vscode-extension/src/extension.ts @@ -1,3 +1,4 @@ +import './globalConfig'; import { commands } from '@/commands'; import setup from '@/commands/setup'; import * as vscode from 'vscode'; diff --git a/packages/vscode-extension/src/functions/autocomplete.ts b/packages/vscode-extension/src/functions/autocomplete.ts index c6047ca..9bbdd40 100644 --- a/packages/vscode-extension/src/functions/autocomplete.ts +++ b/packages/vscode-extension/src/functions/autocomplete.ts @@ -1,5 +1,5 @@ -import { alovaWork } from '@/helper/work'; import type { Api } from '@alova/wormhole'; +import getApis from './getApis'; type AutoCompleteItem = { replaceText: string; @@ -45,4 +45,4 @@ const filterAutoCompleteItem = (text: string, apiArr: Api[]): AutoCompleteItem[] return autoCompleteArr; }; export default async (text: string, filePath: string): Promise => - filterAutoCompleteItem(text, await alovaWork.getApis(filePath)); + filterAutoCompleteItem(text, getApis(filePath)); diff --git a/packages/vscode-extension/src/work/generate.ts b/packages/vscode-extension/src/functions/generate.ts similarity index 65% rename from packages/vscode-extension/src/work/generate.ts rename to packages/vscode-extension/src/functions/generate.ts index 8770f6b..7a3072d 100644 --- a/packages/vscode-extension/src/work/generate.ts +++ b/packages/vscode-extension/src/functions/generate.ts @@ -1,14 +1,14 @@ -import { generate } from '@alova/wormhole'; -import { createError } from '@/utils/work'; -import { CONFIG_POOL } from './config'; +import { generate } from '@/helper/wormhole'; +import { CONFIG_POOL } from '@/helper/config'; +import AlovaError from '@/components/error'; interface GenerateOption { force?: boolean; projectPath?: string; } export default async (option?: GenerateOption) => { - const resultArr = []; - const errorArr = []; + const resultArr: Array<[string, boolean]> = []; + const errorArr: Array<[string, AlovaError]> = []; const { force = false, projectPath: projectPathValue } = option ?? {}; for (const [projectPath, config] of CONFIG_POOL) { if (projectPathValue && projectPathValue !== projectPath) { @@ -21,7 +21,7 @@ export default async (option?: GenerateOption) => { }); resultArr.push([projectPath, generateResult?.some(item => !!item)]); } catch (error: any) { - errorArr.push([projectPath, createError(error)]); + errorArr.push([projectPath, error]); } } return { diff --git a/packages/vscode-extension/src/work/generateConfig.ts b/packages/vscode-extension/src/functions/generateConfig.ts similarity index 77% rename from packages/vscode-extension/src/work/generateConfig.ts rename to packages/vscode-extension/src/functions/generateConfig.ts index 65e25e4..6612fc3 100644 --- a/packages/vscode-extension/src/work/generateConfig.ts +++ b/packages/vscode-extension/src/functions/generateConfig.ts @@ -1,4 +1,4 @@ -import { createConfig } from '@alova/wormhole'; +import { createConfig } from '@/helper/wormhole'; export default async (workspaceRootPathArr: string[]) => Promise.all(workspaceRootPathArr.map(workspaceRootPath => createConfig({ projectPath: workspaceRootPath }))); diff --git a/packages/vscode-extension/src/work/getApis.ts b/packages/vscode-extension/src/functions/getApis.ts similarity index 72% rename from packages/vscode-extension/src/work/getApis.ts rename to packages/vscode-extension/src/functions/getApis.ts index bb38a7a..ecb502c 100644 --- a/packages/vscode-extension/src/work/getApis.ts +++ b/packages/vscode-extension/src/functions/getApis.ts @@ -1,6 +1,6 @@ -import { getApis } from '@alova/wormhole'; +import { getApis } from '@/helper/wormhole'; import path from 'node:path'; -import { CONFIG_POOL } from './config'; +import { CONFIG_POOL } from '@/helper/config'; export default (filePath: string) => { const [projectPath, config] = CONFIG_POOL.find(([projectPath]) => filePath.includes(path.resolve(projectPath))) ?? []; diff --git a/packages/vscode-extension/src/functions/getWormhole.ts b/packages/vscode-extension/src/functions/getWormhole.ts new file mode 100644 index 0000000..efb96e8 --- /dev/null +++ b/packages/vscode-extension/src/functions/getWormhole.ts @@ -0,0 +1,20 @@ +import path from 'node:path'; +import importFresh from 'import-fresh'; +import { getWorkspacePaths } from '@/utils/vscode'; +import message from '@/components/message'; + +export default () => { + let wormhole: typeof import('@alova/wormhole') | null = null; + for (const workspaceRootPath of getWorkspacePaths()) { + try { + wormhole = importFresh(path.join(workspaceRootPath, './node_modules/@alova/wormhole')); + } catch (error) {} + } + if (!wormhole) { + const errorText = '@alova/wormhole is not found, please install it first.'; + message.log(errorText); + message.error(errorText); + throw new Error(errorText); + } + return wormhole; +}; diff --git a/packages/vscode-extension/src/functions/readConfig.ts b/packages/vscode-extension/src/functions/readConfig.ts new file mode 100644 index 0000000..d1d68ff --- /dev/null +++ b/packages/vscode-extension/src/functions/readConfig.ts @@ -0,0 +1,82 @@ +import { highPrecisionInterval } from '@/utils'; +import { log } from '@/components/message'; +import { executeCommand, getWorkspacePaths } from '@/utils/vscode'; +import { readConfig, getAutoUpdateConfig } from '@/helper/wormhole'; +import type { Config } from '@alova/wormhole'; +import { CONFIG_POOL } from '@/helper/config'; +import type { ConfigObject } from '@/helper/config'; + +const AUTOUPDATE_MAP = new Map< + string, + { time: number; immediate: boolean; timer: ReturnType } +>(); + +function refeshAutoUpdate(configuration: ConfigObject) { + const [, config] = configuration; + const { time, immediate, isStop } = getAutoUpdateConfig(config); + const oldConfig = AUTOUPDATE_MAP.get(configuration[0]); + // 过滤掉已经配置的定时器 + if (oldConfig?.immediate === immediate && oldConfig?.time === time && oldConfig?.timer?.isRunning()) { + return; + } + if (!isStop) { + // 设置定时器 + AUTOUPDATE_MAP.set(configuration[0], { + time, + immediate, + timer: highPrecisionInterval( + () => { + executeCommand('generateApi', configuration[0]); + }, + time * 1000, + immediate + ) + }); + } else { + // 移除定时器 + AUTOUPDATE_MAP.delete(configuration[0]); + } + // 关闭之前的定时器 + oldConfig?.timer?.clear?.(); +} +function removeConfiguration(workspaceRootPath: string) { + const idx = CONFIG_POOL.findIndex(([projectPath]) => projectPath === workspaceRootPath); + if (idx >= 0) { + // 关闭定时器 + AUTOUPDATE_MAP.get(CONFIG_POOL[idx][0])?.timer?.clear(); + AUTOUPDATE_MAP.delete(CONFIG_POOL[idx][0]); + CONFIG_POOL.splice(idx, 1); + } +} +export default async (workspaceRootPathArr: string | string[]) => { + let configNum = 0; + const workspaceRootPaths = [workspaceRootPathArr].flat(); + for (const workspaceRootPath of workspaceRootPaths) { + let config: Config | null = null; + try { + config = await readConfig(workspaceRootPath); + } catch (error: any) { + log(error.message); + } + if (!config) { + removeConfiguration(workspaceRootPath); + continue; + } + let configuration = CONFIG_POOL.find(([projectPath]) => projectPath === workspaceRootPath); + if (!configuration) { + configuration = [workspaceRootPath, config]; + CONFIG_POOL.push(configuration); + } else { + configuration[1] = config; + } + refeshAutoUpdate(configuration); + configNum += 1; + } + return configNum > 0; +}; +export const updatedConfigPool = () => { + const workspaceRootPaths = getWorkspacePaths(); + CONFIG_POOL.filter(([projectPath]) => !workspaceRootPaths.includes(projectPath)).forEach(([projectPath]) => + removeConfiguration(projectPath) + ); +}; diff --git a/packages/vscode-extension/src/globalConfig.ts b/packages/vscode-extension/src/globalConfig.ts index e2785c2..0399861 100644 --- a/packages/vscode-extension/src/globalConfig.ts +++ b/packages/vscode-extension/src/globalConfig.ts @@ -1,11 +1,6 @@ -/* eslint-disable import/prefer-default-export */ import { AlovaErrorConstructor } from '@/components/error'; -import { log } from '@/utils/work'; -import { setGlobalConfig } from '@alova/wormhole'; -import path from 'node:path'; -import { pathToFileURL } from 'node:url'; -// work.js线程路径 -export const WORK_PATH = pathToFileURL(path.join(__dirname, '/work.js')); +import { log } from '@/components/message'; +import { setGlobalConfig } from '@/helper/wormhole'; // 全局配置 setGlobalConfig({ log, diff --git a/packages/vscode-extension/src/work/config.ts b/packages/vscode-extension/src/helper/config.ts similarity index 63% rename from packages/vscode-extension/src/work/config.ts rename to packages/vscode-extension/src/helper/config.ts index bc58034..715fdfd 100644 --- a/packages/vscode-extension/src/work/config.ts +++ b/packages/vscode-extension/src/helper/config.ts @@ -1,8 +1,6 @@ -import type { Task } from '@/helper/work'; import type { Config } from '@alova/wormhole'; export type ConfigObject = [string, Config]; -export const TASK_MAP = new Map(); export const CONFIG_POOL: Array = []; export default { CONFIG_POOL diff --git a/packages/vscode-extension/src/helper/work.ts b/packages/vscode-extension/src/helper/work.ts deleted file mode 100644 index 8676755..0000000 --- a/packages/vscode-extension/src/helper/work.ts +++ /dev/null @@ -1,136 +0,0 @@ -import Error from '@/components/error'; -import { log } from '@/components/message'; -import { WORK_PATH } from '@/globalConfig'; -import { uuid } from '@/utils'; -import { getWorkspacePaths, executeCommand } from '@/utils/vscode'; -import type { Api } from '@alova/wormhole'; -import { Worker } from 'worker_threads'; - -type MessageCallBack = (data?: any) => T | Promise; -export interface Task { - type: string; - payload: { - resolve: (data: any) => void; - reject: (reason: any) => void; - }; -} -export default class AlovaWork { - private alovaWork: Worker; - - private taskMap = new Map(); - - constructor() { - this.alovaWork = new Worker(WORK_PATH); - this.alovaWork.on('message', async ({ type, id, payload }) => { - switch (type) { - case 'readConfig': - case 'generate': - case 'generateConfig': - case 'getApis': { - this.doneTask(id, type, payload); - break; - } - case 'executeCommand': { - this.doneTask(id, type, payload, data => { - const { cmd = '', args = [] } = data ?? {}; - executeCommand(cmd, ...args); - }); - break; - } - case 'log': { - this.doneTask(id, type, payload, data => log(...data)); - break; - } - default: { - console.log(type, payload); - } - } - }); - } - - private async setTask(type: string, cb: MessageCallBack) { - let data: any; - let error: any; - try { - data = await cb(); - } catch (err) { - error = err; - } - return new Promise((resolve, reject) => { - if (!data && error) { - reject(error); - return; - } - const taskId = uuid(); - this.postMessage(taskId, type, () => data); - this.taskMap.set(taskId, { type, payload: { resolve, reject } }); - }); - } - - private async doneTask(id: string, type: string, payload: any, cb?: MessageCallBack) { - let { data, error } = payload ?? {}; - if (cb) { - try { - data = await cb(data); - } catch (err) { - error = err; - } - } - if (!this.taskMap.has(id)) { - return; - } - const task = this.taskMap.get(id) as Task; - if (task.type === type) { - if (!data && error) { - task.payload.reject(error); - } else { - task.payload.resolve(data); - } - } - this.taskMap.delete(id); - } - - private async postMessage(id: string | null, type: string, cb: MessageCallBack) { - let data: any; - let error: any; - try { - data = await cb(); - } catch (err) { - error = err; - } - if (!data && error) { - return; - } - this.alovaWork.postMessage({ - type, - id, - payload: data - }); - } - - generate(force = false, projectPath?: string) { - return this.setTask<{ - resultArr: Array<[string, boolean]>; - errorArr: Array<[string, any]>; - }>('generate', () => ({ - force, - projectPath - })); - } - - async readConfig(isShowError = false, projectPath?: string | string[]) { - const hasConfig = await this.setTask('readConfig', () => [projectPath ?? getWorkspacePaths()].flat()); - if (!hasConfig && isShowError) { - throw new Error('Expected to create alova.config.js in root directory.'); - } - } - - getApis(filePath: string) { - return this.setTask('getApis', () => filePath); - } - - generateConfig() { - return this.setTask('generateConfig', () => getWorkspacePaths()); - } -} -export const alovaWork = new AlovaWork(); diff --git a/packages/vscode-extension/src/helper/wormhole.ts b/packages/vscode-extension/src/helper/wormhole.ts new file mode 100644 index 0000000..8dd42d7 --- /dev/null +++ b/packages/vscode-extension/src/helper/wormhole.ts @@ -0,0 +1,6 @@ +import getWormhole from '@/functions/getWormhole'; + +const wormhole = getWormhole(); +const { setGlobalConfig, readConfig, createConfig, generate, getApis, getAutoUpdateConfig } = wormhole; +export { setGlobalConfig, readConfig, createConfig, generate, getApis, getAutoUpdateConfig }; +export default wormhole; diff --git a/packages/vscode-extension/src/utils/work.ts b/packages/vscode-extension/src/utils/work.ts deleted file mode 100644 index c46ea52..0000000 --- a/packages/vscode-extension/src/utils/work.ts +++ /dev/null @@ -1,70 +0,0 @@ -import type { CommandKey } from '@/commands'; -import type { Task } from '@/helper/work'; -import { parentPort } from 'worker_threads'; -import { uuid } from '.'; -import { TASK_MAP } from '../work/config'; -import AlovaError from '@/components/error'; - -type MessageCallBack = () => T | Promise; -export function createError(err: AlovaError) { - return { - message: err.message, - stack: err.stack, - ERROR_CODE: err.ERROR_CODE - } as AlovaError; -} -export async function postMessage(id: string | null, type: string, cb: MessageCallBack) { - let data: any; - let error: any; - try { - data = await cb(); - } catch (err) { - error = err; - } - parentPort?.postMessage({ - type, - payload: { data, error }, - id - }); -} -export async function doneTask(id: string | null, type: string, cb: MessageCallBack) { - let data: any; - let error: any; - try { - data = await cb(); - } catch (err) { - error = err; - } - if (id && TASK_MAP.has(id)) { - const task = TASK_MAP.get(id) as Task; - if (task.type === type) { - if (!data && error) { - task.payload.reject(error); - } else { - task.payload.resolve(data); - } - } - TASK_MAP.delete(id); - } -} -export async function setTask(type: string, cb: MessageCallBack) { - return new Promise((resolve, reject) => { - const taskId = uuid(); - postMessage(taskId, type, cb); - TASK_MAP.set(taskId, { type, payload: { resolve, reject } }); - }); -} -export function executeCommand(cmd: CommandKey, ...args: T) { - return postMessage(null, 'executeCommand', () => ({ - cmd, - args - })); -} - -export function getWorkspaceRootPathArr() { - return setTask('workspaceRootPathArr', () => {}); -} - -export async function log(...args: any[]) { - return postMessage(null, 'log', () => args); -} diff --git a/packages/vscode-extension/src/work.ts b/packages/vscode-extension/src/work.ts deleted file mode 100644 index 0ba0b18..0000000 --- a/packages/vscode-extension/src/work.ts +++ /dev/null @@ -1,33 +0,0 @@ -import generate from '@/work/generate'; -import generateConfig from '@/work/generateConfig'; -import getApis from '@/work/getApis'; -import readConfig from '@/work/readConfig'; -import { parentPort } from 'worker_threads'; -import './globalConfig'; -import { postMessage } from './utils/work'; -/** - * work子线程,用来处理主线程不能处理的东西,不能引入vscode模块 - */ -parentPort?.on('message', async ({ id, type, payload }) => { - switch (type) { - case 'readConfig': { - postMessage(id, type, () => readConfig(payload)); - break; - } - case 'generate': { - postMessage(id, type, () => generate(payload)); - break; - } - case 'getApis': { - postMessage(id, type, () => getApis(payload)); - break; - } - case 'generateConfig': { - postMessage(id, type, () => generateConfig(payload)); - break; - } - default: { - console.log(type, payload); - } - } -}); diff --git a/packages/vscode-extension/src/work/readConfig.ts b/packages/vscode-extension/src/work/readConfig.ts deleted file mode 100644 index 4b7944e..0000000 --- a/packages/vscode-extension/src/work/readConfig.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { highPrecisionInterval } from '@/utils'; -import { executeCommand, log } from '@/utils/work'; -import { readConfig, getAutoUpdateConfig, Config } from '@alova/wormhole'; -import { CONFIG_POOL } from './config'; -import type { ConfigObject } from './config'; - -const AUTOUPDATE_CONFIG_MAP = new Map(); -const AUTOUPDATE_MAP = new Map>(); - -function refeshAutoUpdate(configuration: ConfigObject) { - const [, config] = configuration; - const { time, immediate } = getAutoUpdateConfig(config); - const oldConfig = AUTOUPDATE_CONFIG_MAP.get(configuration); - const oldTimer = AUTOUPDATE_MAP.get(configuration); - // 过滤掉已经配置的定时器 - if (oldConfig?.immediate === immediate && oldConfig.time === time && oldTimer?.isRunning()) { - return; - } - oldTimer?.clear(); - AUTOUPDATE_CONFIG_MAP.set(configuration, { immediate, time }); - AUTOUPDATE_MAP.set( - configuration, - highPrecisionInterval( - () => { - executeCommand('generateApi', configuration[0]); - }, - time * 1000, - immediate - ) - ); -} -function removeConfiguration(workspaceRootPath: string) { - const idx = CONFIG_POOL.findIndex(([projectPath]) => projectPath === workspaceRootPath); - if (idx >= 0) { - AUTOUPDATE_MAP.get(CONFIG_POOL[idx])?.clear(); - AUTOUPDATE_MAP.delete(CONFIG_POOL[idx]); - AUTOUPDATE_CONFIG_MAP.delete(CONFIG_POOL[idx]); - CONFIG_POOL.splice(idx, 1); - } -} -export default async (workspaceRootPathArr: string[]) => { - let configNum = 0; - for (const workspaceRootPath of workspaceRootPathArr) { - let config: Config | null = null; - try { - config = await readConfig(workspaceRootPath); - } catch (error: any) { - log(error.message); - } - if (!config) { - removeConfiguration(workspaceRootPath); - continue; - } - let configuration = CONFIG_POOL.find(([projectPath]) => projectPath === workspaceRootPath); - if (!configuration) { - configuration = [workspaceRootPath, config]; - CONFIG_POOL.push(configuration); - } else { - configuration[1] = config; - } - refeshAutoUpdate(configuration); - configNum += 1; - } - return configNum > 0; -}; diff --git a/packages/wormhole/package.json b/packages/wormhole/package.json index 0d81293..0d4e492 100644 --- a/packages/wormhole/package.json +++ b/packages/wormhole/package.json @@ -9,8 +9,9 @@ "alova": "./dist/bin/cli.js" }, "scripts": { - "build": "npm run build:ts && npm run build:dts", - "build:ts": "tsc --build tsconfig.build.json", + "build": "npm run build:ts && npm run build:dts && npm run build:copy", + "build:copy": "tsx ./scripts/build-copy.ts", + "build:ts": "tsc --build tsconfig.build.json && tsc-alias -p tsconfig.build.json", "build:dts": "dts-bundle-generator -o typings/index.d.ts src/index.ts --no-check --no-banner --project tsconfig.build.json" }, "keywords": [ @@ -54,7 +55,10 @@ "swagger2openapi": "^7.0.8" }, "devDependencies": { + "@types/fs-extra": "^11.0.4", "@types/swagger2openapi": "^7.0.4", - "memfs": "^4.11.1" + "fs-extra": "^11.2.0", + "memfs": "^4.11.1", + "tsc-alias": "^1.8.10" } } diff --git a/packages/wormhole/scripts/build-copy.ts b/packages/wormhole/scripts/build-copy.ts new file mode 100644 index 0000000..a0c711d --- /dev/null +++ b/packages/wormhole/scripts/build-copy.ts @@ -0,0 +1,4 @@ +import { copy } from 'fs-extra'; +import { resolve } from 'node:path'; + +copy(resolve(__dirname, '../src/templates'), resolve(__dirname, '../dist/templates')); diff --git a/packages/wormhole/src/readConfig.ts b/packages/wormhole/src/readConfig.ts index 6d6d264..bda3d45 100644 --- a/packages/wormhole/src/readConfig.ts +++ b/packages/wormhole/src/readConfig.ts @@ -38,12 +38,14 @@ export const getAutoUpdateConfig = (config: Config) => { const autoUpdateConfig = config.autoUpdate; let time = 60 * 5; // 默认五分钟 let immediate = false; + const isStop = !autoUpdateConfig; if (typeof autoUpdateConfig === 'object') { time = Number(autoUpdateConfig.interval); immediate = !!autoUpdateConfig.launchEditor; } return { time, + isStop, immediate }; }; diff --git a/packages/wormhole/test/package.json b/packages/wormhole/test/package.json deleted file mode 100644 index e977916..0000000 --- a/packages/wormhole/test/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "test-pkg", - "type": "commonjs", - "version": "1.0.0", - "devDependencies": {} -} diff --git a/packages/wormhole/test/util.ts b/packages/wormhole/test/util.ts index c3dbb43..b68416c 100644 --- a/packages/wormhole/test/util.ts +++ b/packages/wormhole/test/util.ts @@ -25,6 +25,6 @@ export const initExpect = () => { }); }; export const createStrReg = (str: string) => { - str = str.replace(/([[\](){}.*+|\\/^$?])/g, '\\$1').replace(/\s/g, '\\s+'); + str = str.replace(/([[\](){}.*+|\\/^$?])/g, '\\$1').replace(/\s+/g, '\\s+'); return new RegExp(str); }; diff --git a/packages/wormhole/tsconfig.json b/packages/wormhole/tsconfig.json index e91d6fc..3b429d9 100644 --- a/packages/wormhole/tsconfig.json +++ b/packages/wormhole/tsconfig.json @@ -10,5 +10,5 @@ "#/*": ["./*"] } }, - "include": ["src/**/*.ts", "test/**/*", "./*.ts", "typings/**/*.d.ts"] + "include": ["src/**/*.ts", "test/**/*", "./*.ts", "typings/**/*.d.ts", "./scripts/**/*"] } diff --git a/packages/wormhole/typings/index.d.ts b/packages/wormhole/typings/index.d.ts index 4889d76..dd93b22 100644 --- a/packages/wormhole/typings/index.d.ts +++ b/packages/wormhole/typings/index.d.ts @@ -111,6 +111,7 @@ export declare const generate: (config: Config, rules?: GenerateApiOptions) => P export declare const readConfig: (projectPath?: string) => Promise; export declare const getAutoUpdateConfig: (config: Config) => { time: number; + isStop: boolean; immediate: boolean; }; export declare const getApis: (config: Config, projectPath?: string) => Api[]; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6b0404e..aaef5c4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -101,13 +101,10 @@ importers: '@alova/wormhole': specifier: workspace:^ version: link:../wormhole + import-fresh: + specifier: ^3.3.0 + version: 3.3.0 devDependencies: - '@esbuild/linux-x64': - specifier: ^0.24.0 - version: 0.24.0 - '@esbuild/win32-x64': - specifier: ^0.24.0 - version: 0.24.0 '@types/vscode': specifier: ^1.89.0 version: 1.94.0 @@ -126,9 +123,6 @@ importers: esbuild-plugin-alias: specifier: ^0.2.1 version: 0.2.1 - esbuild-plugin-copy: - specifier: ^2.1.1 - version: 2.1.1(esbuild@0.24.0) packages/wormhole: dependencies: @@ -166,12 +160,21 @@ importers: specifier: ^7.0.8 version: 7.0.8 devDependencies: + '@types/fs-extra': + specifier: ^11.0.4 + version: 11.0.4 '@types/swagger2openapi': specifier: ^7.0.4 version: 7.0.4 + fs-extra: + specifier: ^11.2.0 + version: 11.2.0 memfs: specifier: ^4.11.1 version: 4.14.0 + tsc-alias: + specifier: ^1.8.10 + version: 1.8.10 test/api-js-commonjs-test: dependencies: @@ -184,6 +187,10 @@ importers: vue: specifier: ^3.4.27 version: 3.5.12(typescript@5.6.3) + devDependencies: + '@alova/wormhole': + specifier: workspace:^ + version: link:../../packages/wormhole test/api-js-test: dependencies: @@ -193,6 +200,10 @@ importers: vue: specifier: ^3.4.27 version: 3.5.12(typescript@5.6.3) + devDependencies: + '@alova/wormhole': + specifier: workspace:^ + version: link:../../packages/wormhole test/api-ts-test: dependencies: @@ -206,6 +217,9 @@ importers: specifier: ^3.4.27 version: 3.5.12(typescript@5.6.3) devDependencies: + '@alova/wormhole': + specifier: workspace:^ + version: link:../../packages/wormhole openapi: specifier: ^1.0.1 version: 1.0.1 @@ -224,6 +238,10 @@ importers: vue: specifier: ^3.4.27 version: 3.5.12(typescript@5.6.3) + devDependencies: + '@alova/wormhole': + specifier: workspace:^ + version: link:../../packages/wormhole test/api-v3-js-test: dependencies: @@ -233,6 +251,10 @@ importers: vue: specifier: ^3.4.27 version: 3.5.12(typescript@5.6.3) + devDependencies: + '@alova/wormhole': + specifier: workspace:^ + version: link:../../packages/wormhole test/api-v3-ts-test: dependencies: @@ -246,6 +268,9 @@ importers: specifier: 3.0.5 version: 3.0.5 devDependencies: + '@alova/wormhole': + specifier: workspace:^ + version: link:../../packages/wormhole typescript: specifier: ^5.4.5 version: 5.6.3 @@ -1030,6 +1055,9 @@ packages: '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/fs-extra@11.0.4': + resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} + '@types/istanbul-lib-coverage@2.0.6': resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} @@ -1048,6 +1076,9 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@types/jsonfile@6.1.4': + resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} + '@types/lodash@4.17.12': resolution: {integrity: sha512-sviUmCE8AYdaF/KIHLDJBQgeYzPBI0vf/17NaYehBJfYD1j6/L95Slh07NlyK2iNyBNaEkb3En2jRt+a8y3xZQ==} @@ -1600,6 +1631,10 @@ packages: resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} engines: {node: '>= 6'} + commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + commitizen@4.3.1: resolution: {integrity: sha512-gwAPAVTy/j5YcOOebcCRIijn+mSjWJC+IYKivTu6aG8Ei/scoXgfsMRnuAk6b0GRste2J4NGxVdMN3ZpfNaVaw==} engines: {node: '>= 12'} @@ -1896,11 +1931,6 @@ packages: esbuild-plugin-alias@0.2.1: resolution: {integrity: sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ==} - esbuild-plugin-copy@2.1.1: - resolution: {integrity: sha512-Bk66jpevTcV8KMFzZI1P7MZKZ+uDcrZm2G2egZ2jNIvVnivDpodZI+/KnpL3Jnap0PBdIHU7HwFGB8r+vV5CVw==} - peerDependencies: - esbuild: '>= 0.14.0' - esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} @@ -2175,9 +2205,9 @@ packages: fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - fs-extra@10.1.0: - resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} - engines: {node: '>=12'} + fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} fs-extra@9.1.0: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} @@ -2965,6 +2995,10 @@ packages: mute-stream@0.0.8: resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + mylas@2.1.13: + resolution: {integrity: sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg==} + engines: {node: '>=12.0.0'} + nanoid@3.3.7: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -3258,6 +3292,10 @@ packages: resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} engines: {node: '>=4'} + plimit-lit@1.6.1: + resolution: {integrity: sha512-B7+VDyb8Tl6oMJT9oSO2CW8XC/T4UcJGrwOVoNGwOQsQYhlpfajmrMj5xeejqaASq3V/EqThyOeATEOMuSEXiA==} + engines: {node: '>=12'} + possible-typed-array-names@1.0.0: resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} engines: {node: '>= 0.4'} @@ -3327,6 +3365,10 @@ packages: querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + queue-lit@1.5.2: + resolution: {integrity: sha512-tLc36IOPeMAubu8BkW8YDBV+WyIgKlYU7zUNs0J5Vk9skSZ4JfGlPOqplP0aHdfv7HL0B2Pg6nwiq60Qc6M2Hw==} + engines: {node: '>=12'} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -3805,6 +3847,10 @@ packages: peerDependencies: typescript: '>=4.2.0' + tsc-alias@1.8.10: + resolution: {integrity: sha512-Ibv4KAWfFkFdKJxnWfVtdOmB0Zi1RJVxcbPGiCDsFpCQSsmpWyuzHG3rQyI5YkobWwxFPEyQfu1hdo4qLG2zPw==} + hasBin: true + tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} @@ -4508,7 +4554,8 @@ snapshots: '@esbuild/linux-x64@0.23.1': optional: true - '@esbuild/linux-x64@0.24.0': {} + '@esbuild/linux-x64@0.24.0': + optional: true '@esbuild/netbsd-x64@0.21.5': optional: true @@ -4567,7 +4614,8 @@ snapshots: '@esbuild/win32-x64@0.23.1': optional: true - '@esbuild/win32-x64@0.24.0': {} + '@esbuild/win32-x64@0.24.0': + optional: true '@eslint-community/eslint-utils@4.4.0(eslint@8.57.1)': dependencies: @@ -4723,6 +4771,11 @@ snapshots: '@types/estree@1.0.6': {} + '@types/fs-extra@11.0.4': + dependencies: + '@types/jsonfile': 6.1.4 + '@types/node': 18.19.59 + '@types/istanbul-lib-coverage@2.0.6': {} '@types/istanbul-lib-report@3.0.3': @@ -4742,6 +4795,10 @@ snapshots: '@types/json5@0.0.29': {} + '@types/jsonfile@6.1.4': + dependencies: + '@types/node': 18.19.59 + '@types/lodash@4.17.12': {} '@types/mocha@10.0.9': {} @@ -5443,6 +5500,8 @@ snapshots: commander@6.2.1: {} + commander@9.5.0: {} + commitizen@4.3.1(@types/node@18.19.59)(typescript@5.6.3): dependencies: cachedir: 2.3.0 @@ -5821,14 +5880,6 @@ snapshots: esbuild-plugin-alias@0.2.1: {} - esbuild-plugin-copy@2.1.1(esbuild@0.24.0): - dependencies: - chalk: 4.1.2 - chokidar: 3.6.0 - esbuild: 0.24.0 - fs-extra: 10.1.0 - globby: 11.1.0 - esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 @@ -6248,7 +6299,7 @@ snapshots: fs-constants@1.0.0: optional: true - fs-extra@10.1.0: + fs-extra@11.2.0: dependencies: graceful-fs: 4.2.11 jsonfile: 6.1.0 @@ -7066,6 +7117,8 @@ snapshots: mute-stream@0.0.8: {} + mylas@2.1.13: {} + nanoid@3.3.7: {} napi-build-utils@1.0.2: @@ -7403,6 +7456,10 @@ snapshots: pify@3.0.0: {} + plimit-lit@1.6.1: + dependencies: + queue-lit: 1.5.2 + possible-typed-array-names@1.0.0: {} postcss@8.4.47: @@ -7473,6 +7530,8 @@ snapshots: querystringify@2.2.0: {} + queue-lit@1.5.2: {} + queue-microtask@1.2.3: {} randombytes@2.1.0: @@ -8007,6 +8066,15 @@ snapshots: dependencies: typescript: 5.6.3 + tsc-alias@1.8.10: + dependencies: + chokidar: 3.6.0 + commander: 9.5.0 + globby: 11.1.0 + mylas: 2.1.13 + normalize-path: 3.0.0 + plimit-lit: 1.6.1 + tsconfig-paths@3.15.0: dependencies: '@types/json5': 0.0.29 diff --git a/scripts/api-test.ts b/scripts/api-test.ts index bdcc259..6084e55 100644 --- a/scripts/api-test.ts +++ b/scripts/api-test.ts @@ -1,6 +1,7 @@ import fs from 'node:fs'; import path from 'node:path'; -import { projectPath } from '../path'; + +const projectPath = path.resolve(__dirname, '../'); const DESIGN_NO_DIR = ['api-common']; /** diff --git a/test/api-common/alova.config.js b/test/api-common/alova.config.js index 2731593..e80b87d 100644 --- a/test/api-common/alova.config.js +++ b/test/api-common/alova.config.js @@ -1,3 +1,6 @@ +/** + * @type {import('@alova/wormhole').Config} + */ // alova.config.js module.exports = { // api生成设置,为数组,每项代表一个自动生成的规则,包含生成的输入输出目录、规范文件地址等等 @@ -36,7 +39,7 @@ module.exports = { // 未指定此函数时则不转换apiDescripor对象 // apiDescriptor的格式与openapi文件的接口对象格式相同 // 对类型生成也同样适用123 - handleApi: apiDescriptor => { + handleApi: (apiDescriptor, log) => { // 返回空表示过滤掉此api // if (!apiDescriptor.url.startsWith('/generate')) { // return; diff --git a/test/api-js-commonjs-test/package.json b/test/api-js-commonjs-test/package.json index 7d52973..c893188 100644 --- a/test/api-js-commonjs-test/package.json +++ b/test/api-js-commonjs-test/package.json @@ -15,5 +15,8 @@ "@alova/mock": "^1.5.2", "alova": "^2.21.3", "vue": "^3.4.27" + }, + "devDependencies": { + "@alova/wormhole": "workspace:^" } } diff --git a/test/api-js-test/package.json b/test/api-js-test/package.json index 951854d..0254cc1 100644 --- a/test/api-js-test/package.json +++ b/test/api-js-test/package.json @@ -13,5 +13,8 @@ "dependencies": { "alova": "^2.20.5", "vue": "^3.4.27" + }, + "devDependencies": { + "@alova/wormhole": "workspace:^" } } diff --git a/test/api-ts-test/package.json b/test/api-ts-test/package.json index a440665..ca8f3cc 100644 --- a/test/api-ts-test/package.json +++ b/test/api-ts-test/package.json @@ -17,6 +17,7 @@ "vue": "^3.4.27" }, "devDependencies": { + "@alova/wormhole": "workspace:^", "openapi": "^1.0.1", "typescript": "^5.4.5" } diff --git a/test/api-v3-js-commonjs-test/package.json b/test/api-v3-js-commonjs-test/package.json index f0d62b7..2902b17 100644 --- a/test/api-v3-js-commonjs-test/package.json +++ b/test/api-v3-js-commonjs-test/package.json @@ -15,5 +15,8 @@ "@alova/adapter-xhr": "2.0.0-beta.8", "alova": "3.0.0-beta.10", "vue": "^3.4.27" + }, + "devDependencies": { + "@alova/wormhole": "workspace:^" } } diff --git a/test/api-v3-js-test/package.json b/test/api-v3-js-test/package.json index 4696fcb..ebede26 100644 --- a/test/api-v3-js-test/package.json +++ b/test/api-v3-js-test/package.json @@ -13,5 +13,8 @@ "dependencies": { "alova": "3.0.0-beta.10", "vue": "^3.4.27" + }, + "devDependencies": { + "@alova/wormhole": "workspace:^" } } diff --git a/test/api-v3-ts-test/package.json b/test/api-v3-ts-test/package.json index 4ec7965..e1fa480 100644 --- a/test/api-v3-ts-test/package.json +++ b/test/api-v3-ts-test/package.json @@ -10,6 +10,7 @@ "author": "", "license": "ISC", "devDependencies": { + "@alova/wormhole": "workspace:^", "typescript": "^5.4.5" }, "dependencies": { diff --git a/tsconfig.json b/tsconfig.json index 3336c16..2bef1e8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,9 @@ "extends": "./tsconfig.base.json", "exclude": ["design/**", "test/**"], "compilerOptions": { - "outDir": "./dist" + "outDir": "./dist", + "moduleResolution": "node", + "resolveJsonModule": true }, "include": ["*.*js", "packages/**/*.ts", "*.*ts", "scripts/**.*", "typings/**/*.d.ts"] } From ea7076dae28485d4c3cdbeffc98cfd4e94b6120d Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Fri, 25 Oct 2024 19:17:35 +0800 Subject: [PATCH 33/47] =?UTF-8?q?fix(wormhole):=20=E4=BF=AE=E5=A4=8Dbin/ac?= =?UTF-8?q?itons=20ora=20=E6=98=AFesm=E6=A8=A1=E5=9D=97=E9=9C=80=E8=A6=81?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E5=8A=A8=E6=80=81import=E5=8A=A0=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/wormhole/src/bin/actions.ts | 5 ++++- packages/wormhole/src/bin/cli.ts | 1 + packages/wormhole/src/utils/index.ts | 5 +++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/wormhole/src/bin/actions.ts b/packages/wormhole/src/bin/actions.ts index f88cac3..1d97f55 100644 --- a/packages/wormhole/src/bin/actions.ts +++ b/packages/wormhole/src/bin/actions.ts @@ -1,8 +1,10 @@ import { createConfig, generate, readConfig, resolveWorkspaces } from '@/index'; import { TemplateType } from '@/interface.type'; -import ora from 'ora'; +import { loadEsmModule } from '@/utils'; +const getOra = () => loadEsmModule('ora'); export const actionInit = async ({ type, path: projectPath }: { type?: TemplateType; path?: string }) => { + const ora = (await getOra()).default; const spinner = ora('Initializing configuration file...').start(); await createConfig({ type, projectPath }); spinner.succeed('alova configuration file is initialized!'); @@ -21,6 +23,7 @@ export const actionGen = async ({ if (workspace) { workspacePaths = await resolveWorkspaces(projectPath); } + const ora = (await getOra()).default; for (const dir of workspacePaths) { const spinner = ora(`Generating...`).start(); const config = await readConfig(dir); diff --git a/packages/wormhole/src/bin/cli.ts b/packages/wormhole/src/bin/cli.ts index 8c6579c..d98f6aa 100644 --- a/packages/wormhole/src/bin/cli.ts +++ b/packages/wormhole/src/bin/cli.ts @@ -1,6 +1,7 @@ #!/usr/bin/env node import { Command } from 'commander'; import { actionGen, actionInit } from './actions'; + const pkg = require('../../package.json'); const program = new Command(); diff --git a/packages/wormhole/src/utils/index.ts b/packages/wormhole/src/utils/index.ts index e78e397..5d850c9 100644 --- a/packages/wormhole/src/utils/index.ts +++ b/packages/wormhole/src/utils/index.ts @@ -154,3 +154,8 @@ export const resolveConfigFile = async (projectPath: string) => { } return null; }; + +// 加载ESM 模块 +export function loadEsmModule(modulePath: string | URL): Promise { + return new Function('modulePath', `return import(modulePath);`)(modulePath) as Promise; +} From 9e6868cbdac2b04c0d2354f691944e34d883fbc5 Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Tue, 5 Nov 2024 16:03:39 +0800 Subject: [PATCH 34/47] =?UTF-8?q?fix(vscode-extension):=20getWormhole?= =?UTF-8?q?=E6=94=B9=E6=88=90=E8=BF=94=E5=9B=9E=E4=BB=A3=E7=90=86=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1=EF=BC=8C=E8=A7=A3=E5=86=B3=E6=97=A0=E6=B3=95=E6=BF=80?= =?UTF-8?q?=E6=B4=BB=E6=8F=92=E4=BB=B6=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vscode-extension/src/components/error.ts | 5 ++- .../src/functions/generate.ts | 4 +-- .../src/functions/generateConfig.ts | 4 +-- .../vscode-extension/src/functions/getApis.ts | 4 +-- .../src/functions/getWormhole.ts | 34 ++++++++++++++----- .../src/functions/readConfig.ts | 13 ++++--- packages/vscode-extension/src/globalConfig.ts | 4 +-- .../vscode-extension/src/helper/wormhole.ts | 5 +-- 8 files changed, 47 insertions(+), 26 deletions(-) diff --git a/packages/vscode-extension/src/components/error.ts b/packages/vscode-extension/src/components/error.ts index f6f6edf..eac39bc 100644 --- a/packages/vscode-extension/src/components/error.ts +++ b/packages/vscode-extension/src/components/error.ts @@ -1,9 +1,12 @@ export default class AlovaError extends Error { ERROR_CODE = 'error'; - constructor(message?: string) { + force = false; + + constructor(message?: string, force: boolean = false) { super(message); this.name = 'AlovaError'; + this.force = force; } } export const AlovaErrorConstructor = AlovaError as unknown as ErrorConstructor; diff --git a/packages/vscode-extension/src/functions/generate.ts b/packages/vscode-extension/src/functions/generate.ts index 7a3072d..e1b5ead 100644 --- a/packages/vscode-extension/src/functions/generate.ts +++ b/packages/vscode-extension/src/functions/generate.ts @@ -1,4 +1,4 @@ -import { generate } from '@/helper/wormhole'; +import wormhole from '@/helper/wormhole'; import { CONFIG_POOL } from '@/helper/config'; import AlovaError from '@/components/error'; @@ -15,7 +15,7 @@ export default async (option?: GenerateOption) => { continue; } try { - const generateResult = await generate(config, { + const generateResult = await wormhole.generate(config, { force, projectPath }); diff --git a/packages/vscode-extension/src/functions/generateConfig.ts b/packages/vscode-extension/src/functions/generateConfig.ts index 6612fc3..40f33dc 100644 --- a/packages/vscode-extension/src/functions/generateConfig.ts +++ b/packages/vscode-extension/src/functions/generateConfig.ts @@ -1,4 +1,4 @@ -import { createConfig } from '@/helper/wormhole'; +import womhole from '@/helper/wormhole'; export default async (workspaceRootPathArr: string[]) => - Promise.all(workspaceRootPathArr.map(workspaceRootPath => createConfig({ projectPath: workspaceRootPath }))); + Promise.all(workspaceRootPathArr.map(workspaceRootPath => womhole.createConfig({ projectPath: workspaceRootPath }))); diff --git a/packages/vscode-extension/src/functions/getApis.ts b/packages/vscode-extension/src/functions/getApis.ts index ecb502c..273f8ab 100644 --- a/packages/vscode-extension/src/functions/getApis.ts +++ b/packages/vscode-extension/src/functions/getApis.ts @@ -1,4 +1,4 @@ -import { getApis } from '@/helper/wormhole'; +import wormhole from '@/helper/wormhole'; import path from 'node:path'; import { CONFIG_POOL } from '@/helper/config'; @@ -7,5 +7,5 @@ export default (filePath: string) => { if (!config) { return []; } - return getApis(config, projectPath); + return wormhole.getApis(config, projectPath); }; diff --git a/packages/vscode-extension/src/functions/getWormhole.ts b/packages/vscode-extension/src/functions/getWormhole.ts index efb96e8..d4afca3 100644 --- a/packages/vscode-extension/src/functions/getWormhole.ts +++ b/packages/vscode-extension/src/functions/getWormhole.ts @@ -1,20 +1,36 @@ import path from 'node:path'; import importFresh from 'import-fresh'; import { getWorkspacePaths } from '@/utils/vscode'; -import message from '@/components/message'; +import Error from '@/components/error'; -export default () => { - let wormhole: typeof import('@alova/wormhole') | null = null; +type Wormhole = typeof import('@alova/wormhole'); +const NO_ERROR_KEYS: Array = ['setGlobalConfig']; + +const getWormhole = () => { + let wormhole: Wormhole | null = null; for (const workspaceRootPath of getWorkspacePaths()) { try { wormhole = importFresh(path.join(workspaceRootPath, './node_modules/@alova/wormhole')); + break; } catch (error) {} } - if (!wormhole) { - const errorText = '@alova/wormhole is not found, please install it first.'; - message.log(errorText); - message.error(errorText); - throw new Error(errorText); - } return wormhole; }; + +export default () => + new Proxy( + {}, + { + get(_, key: keyof Wormhole) { + const wormhole = getWormhole(); + if (wormhole) { + return wormhole[key]; + } + return () => { + if (!NO_ERROR_KEYS.includes(key)) { + throw new Error('@alova/wormhole is not found, please install it first.', true); + } + }; + } + } + ) as Wormhole; diff --git a/packages/vscode-extension/src/functions/readConfig.ts b/packages/vscode-extension/src/functions/readConfig.ts index d1d68ff..a57a118 100644 --- a/packages/vscode-extension/src/functions/readConfig.ts +++ b/packages/vscode-extension/src/functions/readConfig.ts @@ -1,10 +1,11 @@ import { highPrecisionInterval } from '@/utils'; import { log } from '@/components/message'; import { executeCommand, getWorkspacePaths } from '@/utils/vscode'; -import { readConfig, getAutoUpdateConfig } from '@/helper/wormhole'; +import wormhole from '@/helper/wormhole'; import type { Config } from '@alova/wormhole'; import { CONFIG_POOL } from '@/helper/config'; import type { ConfigObject } from '@/helper/config'; +import Error from '@/components/error'; const AUTOUPDATE_MAP = new Map< string, @@ -13,7 +14,7 @@ const AUTOUPDATE_MAP = new Map< function refeshAutoUpdate(configuration: ConfigObject) { const [, config] = configuration; - const { time, immediate, isStop } = getAutoUpdateConfig(config); + const { time, immediate, isStop } = wormhole.getAutoUpdateConfig(config); const oldConfig = AUTOUPDATE_MAP.get(configuration[0]); // 过滤掉已经配置的定时器 if (oldConfig?.immediate === immediate && oldConfig?.time === time && oldConfig?.timer?.isRunning()) { @@ -54,8 +55,12 @@ export default async (workspaceRootPathArr: string | string[]) => { for (const workspaceRootPath of workspaceRootPaths) { let config: Config | null = null; try { - config = await readConfig(workspaceRootPath); - } catch (error: any) { + config = await wormhole.readConfig(workspaceRootPath); + } catch (err) { + const error = err as Error; + if (error.force) { + throw error; + } log(error.message); } if (!config) { diff --git a/packages/vscode-extension/src/globalConfig.ts b/packages/vscode-extension/src/globalConfig.ts index 0399861..9fb8ec1 100644 --- a/packages/vscode-extension/src/globalConfig.ts +++ b/packages/vscode-extension/src/globalConfig.ts @@ -1,8 +1,8 @@ import { AlovaErrorConstructor } from '@/components/error'; import { log } from '@/components/message'; -import { setGlobalConfig } from '@/helper/wormhole'; +import wormhole from '@/helper/wormhole'; // 全局配置 -setGlobalConfig({ +wormhole.setGlobalConfig({ log, Error: AlovaErrorConstructor }); diff --git a/packages/vscode-extension/src/helper/wormhole.ts b/packages/vscode-extension/src/helper/wormhole.ts index 8dd42d7..d03a4dc 100644 --- a/packages/vscode-extension/src/helper/wormhole.ts +++ b/packages/vscode-extension/src/helper/wormhole.ts @@ -1,6 +1,3 @@ import getWormhole from '@/functions/getWormhole'; -const wormhole = getWormhole(); -const { setGlobalConfig, readConfig, createConfig, generate, getApis, getAutoUpdateConfig } = wormhole; -export { setGlobalConfig, readConfig, createConfig, generate, getApis, getAutoUpdateConfig }; -export default wormhole; +export default getWormhole(); From 0a50bbad993b9c48d448bd55fe2fe7af2c4c7472 Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Tue, 5 Nov 2024 17:39:23 +0800 Subject: [PATCH 35/47] =?UTF-8?q?feat(vscode-extension):=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0wormhole=E6=B2=A1=E6=9C=89=E5=AE=89=E8=A3=85=E6=97=B6?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E6=8C=89=E9=92=AE=E7=BD=AE=E7=81=B0=E6=95=88?= =?UTF-8?q?=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/commands/createConfig.ts | 4 ++-- .../vscode-extension/src/commands/refresh.ts | 4 ++-- .../src/commands/showStatusBarIcon.ts | 2 +- .../src/components/statusBar.ts | 12 +++++++++--- .../src/functions/generateConfig.ts | 3 +-- .../src/functions/getWormhole.ts | 5 ++++- packages/vscode-extension/src/utils/vscode.ts | 17 +++++++++++++++++ 7 files changed, 36 insertions(+), 11 deletions(-) diff --git a/packages/vscode-extension/src/commands/createConfig.ts b/packages/vscode-extension/src/commands/createConfig.ts index 65c6ea0..8b9d737 100644 --- a/packages/vscode-extension/src/commands/createConfig.ts +++ b/packages/vscode-extension/src/commands/createConfig.ts @@ -1,10 +1,10 @@ // 用于自动生成alova.config.js import generateConfig from '@/functions/generateConfig'; -import { getWorkspacePaths } from '@/utils/vscode'; +import { getCurrentWorkspacePath } from '@/utils/vscode'; export default { commandId: 'alova.create.config', handler: () => async () => { - generateConfig(getWorkspacePaths()); + generateConfig(getCurrentWorkspacePath()); } } as Commonand; diff --git a/packages/vscode-extension/src/commands/refresh.ts b/packages/vscode-extension/src/commands/refresh.ts index d47cfae..b94c421 100644 --- a/packages/vscode-extension/src/commands/refresh.ts +++ b/packages/vscode-extension/src/commands/refresh.ts @@ -1,6 +1,6 @@ import Error from '@/components/error'; import message from '@/components/message'; -import { loading, reset } from '@/components/statusBar'; +import { loading, enable } from '@/components/statusBar'; import generate from '@/functions/generate'; import readConfig, { updatedConfigPool } from '@/functions/readConfig'; import { getFileNameByPath } from '@/utils'; @@ -24,7 +24,7 @@ export default { throw error; }); } finally { - reset(); + enable(); } } } as Commonand; diff --git a/packages/vscode-extension/src/commands/showStatusBarIcon.ts b/packages/vscode-extension/src/commands/showStatusBarIcon.ts index dc92354..b97d7bf 100644 --- a/packages/vscode-extension/src/commands/showStatusBarIcon.ts +++ b/packages/vscode-extension/src/commands/showStatusBarIcon.ts @@ -3,7 +3,7 @@ import * as statusBar from '@/components/statusBar'; export default { commandId: 'alova.showStatusBarIcon', handler: context => async () => { - statusBar.reset(); + statusBar.enable(); statusBar.statusBarItem.show(); context.subscriptions.push(statusBar.statusBarItem); } diff --git a/packages/vscode-extension/src/components/statusBar.ts b/packages/vscode-extension/src/components/statusBar.ts index 8934de1..ae15a7b 100644 --- a/packages/vscode-extension/src/components/statusBar.ts +++ b/packages/vscode-extension/src/components/statusBar.ts @@ -1,14 +1,20 @@ import * as vscode from 'vscode'; // 创建状态栏项 - export const loading = (text: string = '') => { statusBarItem.text = `$(sync~spin) ${text} Loading...`; statusBarItem.tooltip = 'loading'; - delete statusBarItem.command; + statusBarItem.command = undefined; }; -export const reset = () => { +export const enable = () => { statusBarItem.text = `$(alova-icon-id) Alova`; statusBarItem.tooltip = 'Generate APIs'; statusBarItem.command = 'alova.refresh'; + statusBarItem.color = undefined; +}; +export const disable = () => { + statusBarItem.text = `$(alova-icon-id) Alova`; + statusBarItem.tooltip = '@alova/wormhole is not found'; + statusBarItem.color = '#808080'; // 设置颜色为灰色 + statusBarItem.command = undefined; }; export const statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100); diff --git a/packages/vscode-extension/src/functions/generateConfig.ts b/packages/vscode-extension/src/functions/generateConfig.ts index 40f33dc..5ed805a 100644 --- a/packages/vscode-extension/src/functions/generateConfig.ts +++ b/packages/vscode-extension/src/functions/generateConfig.ts @@ -1,4 +1,3 @@ import womhole from '@/helper/wormhole'; -export default async (workspaceRootPathArr: string[]) => - Promise.all(workspaceRootPathArr.map(workspaceRootPath => womhole.createConfig({ projectPath: workspaceRootPath }))); +export default async (workspaceRootPath: string) => womhole.createConfig({ projectPath: workspaceRootPath }); diff --git a/packages/vscode-extension/src/functions/getWormhole.ts b/packages/vscode-extension/src/functions/getWormhole.ts index d4afca3..c668615 100644 --- a/packages/vscode-extension/src/functions/getWormhole.ts +++ b/packages/vscode-extension/src/functions/getWormhole.ts @@ -2,11 +2,12 @@ import path from 'node:path'; import importFresh from 'import-fresh'; import { getWorkspacePaths } from '@/utils/vscode'; import Error from '@/components/error'; +import { enable, disable } from '@/components/statusBar'; type Wormhole = typeof import('@alova/wormhole'); const NO_ERROR_KEYS: Array = ['setGlobalConfig']; -const getWormhole = () => { +export const getWormhole = () => { let wormhole: Wormhole | null = null; for (const workspaceRootPath of getWorkspacePaths()) { try { @@ -24,8 +25,10 @@ export default () => get(_, key: keyof Wormhole) { const wormhole = getWormhole(); if (wormhole) { + enable(); return wormhole[key]; } + disable(); return () => { if (!NO_ERROR_KEYS.includes(key)) { throw new Error('@alova/wormhole is not found, please install it first.', true); diff --git a/packages/vscode-extension/src/utils/vscode.ts b/packages/vscode-extension/src/utils/vscode.ts index 5abafea..11642ca 100644 --- a/packages/vscode-extension/src/utils/vscode.ts +++ b/packages/vscode-extension/src/utils/vscode.ts @@ -12,3 +12,20 @@ export const executeCommand = (cmd: CommandKey, ...args: T) => vscode.commands.executeCommand(commandId, ...args); } }; +// 获取当前workspacePath +export const getCurrentWorkspacePath = () => { + // 获取当前活动编辑器 + const editor = vscode.window.activeTextEditor; + if (!editor) { + return getWorkspacePaths()[0]; + } + // 获取当前打开文件的路径 + const filePath = editor.document.uri.fsPath; + + // 获取当前文件所在的工作区根目录 + const workspaceFolder = vscode.workspace.getWorkspaceFolder(editor.document.uri); + if (!workspaceFolder) { + return filePath; + } + return `${workspaceFolder.uri.fsPath}/`; +}; From 937559c69f4e6f5eb219559d698b11a0c5ff7665 Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Wed, 6 Nov 2024 17:31:09 +0800 Subject: [PATCH 36/47] =?UTF-8?q?feat(vscode-extension):=201.@alova/wormho?= =?UTF-8?q?le=E7=A6=81=E7=94=A8=E7=8A=B6=E6=80=81=202.handleApi=E8=B0=83?= =?UTF-8?q?=E8=AF=95=203.=E6=94=AF=E6=8C=81monorepo=E6=9F=A5=E6=89=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 我这边也基本测完了,这是我整理的几个优化点,然后就可以发布了。 --- packages/vscode-extension/package.json | 1 + .../src/commands/createConfig.ts | 6 +- .../vscode-extension/src/commands/setup.ts | 14 +- .../vscode-extension/src/components/event.ts | 59 + .../src/components/message.ts | 57 +- .../src/components/statusBar.ts | 10 +- packages/vscode-extension/src/extension.ts | 17 +- .../src/functions/generateConfig.ts | 2 +- .../src/functions/getWormhole.ts | 47 +- .../src/functions/readConfig.ts | 73 +- packages/vscode-extension/src/globalConfig.ts | 8 - .../vscode-extension/src/helper/autoUpdate.ts | 51 + .../vscode-extension/src/helper/config.ts | 6 +- packages/vscode-extension/src/utils/index.ts | 15 + packages/vscode-extension/src/utils/vscode.ts | 18 +- packages/wormhole/src/config.ts | 1 - packages/wormhole/src/functions/alovaJson.ts | 4 +- .../wormhole/src/functions/openApi2Data.ts | 4 +- packages/wormhole/src/interface.type.ts | 1 - .../test/__snapshots__/generate.spec.ts.snap | 3608 +++++++++++++++++ packages/wormhole/typings/index.d.ts | 2 - packages/wormhole/vitest.config.ts | 1 + pnpm-lock.yaml | 3 + 23 files changed, 3887 insertions(+), 121 deletions(-) create mode 100644 packages/vscode-extension/src/components/event.ts delete mode 100644 packages/vscode-extension/src/globalConfig.ts create mode 100644 packages/vscode-extension/src/helper/autoUpdate.ts diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index 261e3bd..0ad6d75 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -79,6 +79,7 @@ }, "dependencies": { "@alova/wormhole": "workspace:^", + "glob": "^11.0.0", "import-fresh": "^3.3.0" } } diff --git a/packages/vscode-extension/src/commands/createConfig.ts b/packages/vscode-extension/src/commands/createConfig.ts index 8b9d737..31e960d 100644 --- a/packages/vscode-extension/src/commands/createConfig.ts +++ b/packages/vscode-extension/src/commands/createConfig.ts @@ -1,10 +1,10 @@ -// 用于自动生成alova.config.js +// 用于生成alova.config.js import generateConfig from '@/functions/generateConfig'; -import { getCurrentWorkspacePath } from '@/utils/vscode'; +import { getCurrentDirectory } from '@/utils/vscode'; export default { commandId: 'alova.create.config', handler: () => async () => { - generateConfig(getCurrentWorkspacePath()); + generateConfig(getCurrentDirectory()); } } as Commonand; diff --git a/packages/vscode-extension/src/commands/setup.ts b/packages/vscode-extension/src/commands/setup.ts index 1aae31b..a7243b0 100644 --- a/packages/vscode-extension/src/commands/setup.ts +++ b/packages/vscode-extension/src/commands/setup.ts @@ -1,9 +1,10 @@ import autocomplete from '@/components/autocomplete'; import { outputChannel } from '@/components/message'; -import readConfig, { updatedConfigPool } from '@/functions/readConfig'; +import readConfig from '@/functions/readConfig'; import * as vscode from 'vscode'; import showStatusBarIcon from './showStatusBarIcon'; import { getWorkspacePaths } from '@/utils/vscode'; +import { registerEvent } from '@/components/event'; export default { commandId: 'alova.setup', @@ -11,15 +12,8 @@ export default { vscode.commands.executeCommand(showStatusBarIcon.commandId); context.subscriptions.push(autocomplete); context.subscriptions.push(outputChannel); - vscode.workspace.onDidChangeWorkspaceFolders(event => { - event.added.forEach(workspacePath => { - readConfig(`${workspacePath.uri.fsPath}/`); - }); - event.removed.forEach(() => { - readConfig(getWorkspacePaths()); - updatedConfigPool(); - }); - }); + registerEvent(); + // 读取所有配置文件 readConfig(getWorkspacePaths()); } } as Commonand; diff --git a/packages/vscode-extension/src/components/event.ts b/packages/vscode-extension/src/components/event.ts new file mode 100644 index 0000000..80985bf --- /dev/null +++ b/packages/vscode-extension/src/components/event.ts @@ -0,0 +1,59 @@ +import readConfig, { updatedConfigPool } from '@/functions/readConfig'; +import { getWormhole } from '@/functions/getWormhole'; +import * as vscode from 'vscode'; +import { getWorkspacePaths, getCurrentWorkspacePath } from '@/utils/vscode'; +import { debounce } from '@/utils'; +import Error from './error'; +import { log } from './message'; + +export function registerEvent() { + // 监听workspace目录变化 + vscode.workspace.onDidChangeWorkspaceFolders(event => { + event.added.forEach(workspacePath => { + readConfig(`${workspacePath.uri.fsPath}/`); + }); + event.removed.forEach(() => { + readConfig(getWorkspacePaths()); + updatedConfigPool(); + }); + }); + // 监听package.json文件变化 + vscode.workspace.onDidChangeTextDocument( + debounce(event => { + const filePath = event.document.uri.fsPath; + if (event.contentChanges.length === 0) { + return; + } + if (/package\.json$/.test(filePath) && getWormhole()) { + readConfig(getCurrentWorkspacePath(filePath)); + updatedConfigPool(); + } + }, 1000) + ); + // 监听alova.config配置文件变化 + vscode.workspace.onDidSaveTextDocument(event => { + const filePath = event.uri.fsPath; + if (/alova\.config\.[cm]?[jt]s$/.test(filePath)) { + readConfig(getCurrentWorkspacePath(filePath)); + updatedConfigPool(); + } + }); + // 监听错误 + process.on('uncaughtException', (err: Error) => { + log(err.message); + if (err.ERROR_CODE) { + vscode.window.showErrorMessage(err.message); + } + }); + // 监听未处理的promise rejection + process.on('unhandledRejection', (error: Error) => { + const errMsg = error?.message ?? error ?? 'unhandledRejection'; + log(errMsg); + if (error.ERROR_CODE) { + vscode.window.showErrorMessage(errMsg); + } + }); +} +export default { + registerEvent +}; diff --git a/packages/vscode-extension/src/components/message.ts b/packages/vscode-extension/src/components/message.ts index 6ce81c7..6bf921f 100644 --- a/packages/vscode-extension/src/components/message.ts +++ b/packages/vscode-extension/src/components/message.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ import util from 'node:util'; import * as vscode from 'vscode'; // 创建一个输出通道 @@ -30,7 +31,21 @@ export function error(message: string) { export function warning(message: string) { return vscode.window.showWarningMessage(message); } -export function log(...messageArr: any[]) { + +export function output(type: 'log' | 'warn' | 'error', ...messageArr: any[]) { + switch (type) { + case 'log': + outputChannel.append(`🟢 [LOG] `); + break; + case 'warn': + outputChannel.append(`🟡 [WARN] `); + break; + case 'error': + outputChannel.append(`🔴 [ERROR] `); + break; + default: + break; + } messageArr.forEach(message => { if (typeof message === 'object') { message = util.inspect(message, { showHidden: true, depth: null, colors: false }); @@ -39,10 +54,50 @@ export function log(...messageArr: any[]) { }); outputChannel.append('\n'); } + +export function log(...messageArr: any[]) { + output('log', ...messageArr); +} + +export function logError(...messageArr: any[]) { + output('error', ...messageArr); +} +export function logWarn(...messageArr: any[]) { + output('warn', ...messageArr); +} + +const consoleLog = console.log; +const consoleWarn = console.warn; +const consoleError = console.error; + +Object.defineProperties(console, { + log: { + value: (...messageArr: any[]) => { + log(...messageArr); + consoleLog(...messageArr); + } + }, + warn: { + value: (...messageArr: any[]) => { + logWarn(...messageArr); + consoleWarn(...messageArr); + } + }, + error: { + value: (...messageArr: any[]) => { + logError(...messageArr); + consoleError(...messageArr); + } + } +}); + export default { info, error, + output, warning, log, + logError, + logWarn, outputChannel }; diff --git a/packages/vscode-extension/src/components/statusBar.ts b/packages/vscode-extension/src/components/statusBar.ts index ae15a7b..7bedbca 100644 --- a/packages/vscode-extension/src/components/statusBar.ts +++ b/packages/vscode-extension/src/components/statusBar.ts @@ -1,20 +1,28 @@ import * as vscode from 'vscode'; // 创建状态栏项 +type StatusBarItemType = 'loading' | 'enable' | 'disable'; export const loading = (text: string = '') => { + BAR_STATE.value = 'loading'; statusBarItem.text = `$(sync~spin) ${text} Loading...`; statusBarItem.tooltip = 'loading'; statusBarItem.command = undefined; }; export const enable = () => { + BAR_STATE.value = 'enable'; statusBarItem.text = `$(alova-icon-id) Alova`; statusBarItem.tooltip = 'Generate APIs'; statusBarItem.command = 'alova.refresh'; statusBarItem.color = undefined; }; export const disable = () => { + BAR_STATE.value = 'disable'; statusBarItem.text = `$(alova-icon-id) Alova`; - statusBarItem.tooltip = '@alova/wormhole is not found'; + statusBarItem.tooltip = 'module `@alova/wormhole` not found'; statusBarItem.color = '#808080'; // 设置颜色为灰色 statusBarItem.command = undefined; }; export const statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100); + +export const BAR_STATE: { value: StatusBarItemType } = { + value: 'enable' +}; diff --git a/packages/vscode-extension/src/extension.ts b/packages/vscode-extension/src/extension.ts index 20458e0..30b470d 100644 --- a/packages/vscode-extension/src/extension.ts +++ b/packages/vscode-extension/src/extension.ts @@ -1,9 +1,6 @@ -import './globalConfig'; import { commands } from '@/commands'; import setup from '@/commands/setup'; import * as vscode from 'vscode'; -import Error from './components/error'; -import { log } from './components/message'; export function activate(context: vscode.ExtensionContext) { // 插件注册 @@ -12,19 +9,7 @@ export function activate(context: vscode.ExtensionContext) { }); vscode.commands.executeCommand(setup.commandId); } -process.on('uncaughtException', (err: Error) => { - log(err.message); - if (err.ERROR_CODE) { - vscode.window.showErrorMessage(err.message); - } -}); -process.on('unhandledRejection', (error: Error) => { - const errMsg = error?.message ?? error ?? 'unhandledRejection'; - log(errMsg); - if (error.ERROR_CODE) { - vscode.window.showErrorMessage(errMsg); - } -}); + export default { activate }; diff --git a/packages/vscode-extension/src/functions/generateConfig.ts b/packages/vscode-extension/src/functions/generateConfig.ts index 5ed805a..d75dcc0 100644 --- a/packages/vscode-extension/src/functions/generateConfig.ts +++ b/packages/vscode-extension/src/functions/generateConfig.ts @@ -1,3 +1,3 @@ import womhole from '@/helper/wormhole'; -export default async (workspaceRootPath: string) => womhole.createConfig({ projectPath: workspaceRootPath }); +export default async (projectPath: string) => womhole.createConfig({ projectPath }); diff --git a/packages/vscode-extension/src/functions/getWormhole.ts b/packages/vscode-extension/src/functions/getWormhole.ts index c668615..84f8dd2 100644 --- a/packages/vscode-extension/src/functions/getWormhole.ts +++ b/packages/vscode-extension/src/functions/getWormhole.ts @@ -1,20 +1,48 @@ import path from 'node:path'; import importFresh from 'import-fresh'; import { getWorkspacePaths } from '@/utils/vscode'; -import Error from '@/components/error'; -import { enable, disable } from '@/components/statusBar'; +import Error, { AlovaErrorConstructor } from '@/components/error'; +import { enable, disable, BAR_STATE } from '@/components/statusBar'; +import { TEMPLATE_DATA } from '@/helper/config'; +import { existsSync } from 'node:fs'; +import { removeConfiguration } from '@/helper/autoUpdate'; +import { globSync } from 'glob'; type Wormhole = typeof import('@alova/wormhole'); -const NO_ERROR_KEYS: Array = ['setGlobalConfig']; - export const getWormhole = () => { let wormhole: Wormhole | null = null; for (const workspaceRootPath of getWorkspacePaths()) { - try { - wormhole = importFresh(path.join(workspaceRootPath, './node_modules/@alova/wormhole')); + if (wormhole) { break; + } + try { + const configPaths = globSync('**/alova.config.{js,cjs,mjs,ts,mts,cts}', { + ignore: 'node_modules/**', + cwd: workspaceRootPath, + absolute: true + }).concat(path.join(workspaceRootPath, './alova.config.js')); + for (const configPath of configPaths) { + const wormholePath = path.join(path.dirname(configPath), './node_modules/@alova/wormhole'); + if (existsSync(wormholePath)) { + wormhole = importFresh(wormholePath); + break; + } + } } catch (error) {} } + if (wormhole && BAR_STATE.value !== 'loading') { + enable(); + } + if (wormhole) { + // 全局配置 + wormhole.setGlobalConfig({ + Error: AlovaErrorConstructor, + templateData: TEMPLATE_DATA + }); + } + if (!wormhole) { + disable(); + } return wormhole; }; @@ -25,14 +53,11 @@ export default () => get(_, key: keyof Wormhole) { const wormhole = getWormhole(); if (wormhole) { - enable(); return wormhole[key]; } - disable(); return () => { - if (!NO_ERROR_KEYS.includes(key)) { - throw new Error('@alova/wormhole is not found, please install it first.', true); - } + removeConfiguration(); + throw new Error('module `@alova/wormhole` is not found, please install it first.', true); }; } } diff --git a/packages/vscode-extension/src/functions/readConfig.ts b/packages/vscode-extension/src/functions/readConfig.ts index a57a118..f3d4e97 100644 --- a/packages/vscode-extension/src/functions/readConfig.ts +++ b/packages/vscode-extension/src/functions/readConfig.ts @@ -1,61 +1,28 @@ -import { highPrecisionInterval } from '@/utils'; import { log } from '@/components/message'; -import { executeCommand, getWorkspacePaths } from '@/utils/vscode'; +import { getWorkspacePaths } from '@/utils/vscode'; import wormhole from '@/helper/wormhole'; +import { removeConfiguration, refeshAutoUpdate } from '@/helper/autoUpdate'; import type { Config } from '@alova/wormhole'; import { CONFIG_POOL } from '@/helper/config'; -import type { ConfigObject } from '@/helper/config'; import Error from '@/components/error'; -const AUTOUPDATE_MAP = new Map< - string, - { time: number; immediate: boolean; timer: ReturnType } ->(); - -function refeshAutoUpdate(configuration: ConfigObject) { - const [, config] = configuration; - const { time, immediate, isStop } = wormhole.getAutoUpdateConfig(config); - const oldConfig = AUTOUPDATE_MAP.get(configuration[0]); - // 过滤掉已经配置的定时器 - if (oldConfig?.immediate === immediate && oldConfig?.time === time && oldConfig?.timer?.isRunning()) { - return; - } - if (!isStop) { - // 设置定时器 - AUTOUPDATE_MAP.set(configuration[0], { - time, - immediate, - timer: highPrecisionInterval( - () => { - executeCommand('generateApi', configuration[0]); - }, - time * 1000, - immediate - ) - }); - } else { - // 移除定时器 - AUTOUPDATE_MAP.delete(configuration[0]); - } - // 关闭之前的定时器 - oldConfig?.timer?.clear?.(); -} -function removeConfiguration(workspaceRootPath: string) { - const idx = CONFIG_POOL.findIndex(([projectPath]) => projectPath === workspaceRootPath); - if (idx >= 0) { - // 关闭定时器 - AUTOUPDATE_MAP.get(CONFIG_POOL[idx][0])?.timer?.clear(); - AUTOUPDATE_MAP.delete(CONFIG_POOL[idx][0]); - CONFIG_POOL.splice(idx, 1); - } -} +export const resolveWorkspaces = async (workspaceRootPaths?: string | string[]) => { + const workspacePaths = workspaceRootPaths ? [workspaceRootPaths].flat() : getWorkspacePaths(); + const dirs = ( + await Promise.allSettled(workspacePaths.map(workspacePath => wormhole.resolveWorkspaces(workspacePath))) + ) + .filter(item => item.status === 'fulfilled') + .map(item => item.value) + .flat(); + return dirs; +}; export default async (workspaceRootPathArr: string | string[]) => { let configNum = 0; - const workspaceRootPaths = [workspaceRootPathArr].flat(); - for (const workspaceRootPath of workspaceRootPaths) { + const dirs = await resolveWorkspaces([workspaceRootPathArr].flat()); + for (const dir of dirs) { let config: Config | null = null; try { - config = await wormhole.readConfig(workspaceRootPath); + config = await wormhole.readConfig(dir); } catch (err) { const error = err as Error; if (error.force) { @@ -64,12 +31,12 @@ export default async (workspaceRootPathArr: string | string[]) => { log(error.message); } if (!config) { - removeConfiguration(workspaceRootPath); + removeConfiguration(dir); continue; } - let configuration = CONFIG_POOL.find(([projectPath]) => projectPath === workspaceRootPath); + let configuration = CONFIG_POOL.find(([projectPath]) => projectPath === dir); if (!configuration) { - configuration = [workspaceRootPath, config]; + configuration = [dir, config]; CONFIG_POOL.push(configuration); } else { configuration[1] = config; @@ -79,8 +46,8 @@ export default async (workspaceRootPathArr: string | string[]) => { } return configNum > 0; }; -export const updatedConfigPool = () => { - const workspaceRootPaths = getWorkspacePaths(); +export const updatedConfigPool = async () => { + const workspaceRootPaths = await resolveWorkspaces(); CONFIG_POOL.filter(([projectPath]) => !workspaceRootPaths.includes(projectPath)).forEach(([projectPath]) => removeConfiguration(projectPath) ); diff --git a/packages/vscode-extension/src/globalConfig.ts b/packages/vscode-extension/src/globalConfig.ts deleted file mode 100644 index 9fb8ec1..0000000 --- a/packages/vscode-extension/src/globalConfig.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { AlovaErrorConstructor } from '@/components/error'; -import { log } from '@/components/message'; -import wormhole from '@/helper/wormhole'; -// 全局配置 -wormhole.setGlobalConfig({ - log, - Error: AlovaErrorConstructor -}); diff --git a/packages/vscode-extension/src/helper/autoUpdate.ts b/packages/vscode-extension/src/helper/autoUpdate.ts new file mode 100644 index 0000000..717115d --- /dev/null +++ b/packages/vscode-extension/src/helper/autoUpdate.ts @@ -0,0 +1,51 @@ +import { highPrecisionInterval } from '@/utils'; +import { executeCommand } from '@/utils/vscode'; +import wormhole from '@/helper/wormhole'; +import { CONFIG_POOL } from '@/helper/config'; +import type { ConfigObject } from '@/helper/config'; + +const AUTOUPDATE_MAP = new Map< + string, + { time: number; immediate: boolean; timer: ReturnType } +>(); + +export function refeshAutoUpdate(configuration: ConfigObject) { + const [, config] = configuration; + const { time, immediate, isStop } = wormhole.getAutoUpdateConfig(config); + const oldConfig = AUTOUPDATE_MAP.get(configuration[0]); + // 过滤掉已经配置的定时器 + if (oldConfig?.immediate === immediate && oldConfig?.time === time && oldConfig?.timer?.isRunning()) { + return; + } + if (!isStop) { + // 设置定时器 + AUTOUPDATE_MAP.set(configuration[0], { + time, + immediate, + timer: highPrecisionInterval( + () => { + executeCommand('generateApi', configuration[0]); + }, + time * 1000, + immediate + ) + }); + } else { + // 移除定时器 + AUTOUPDATE_MAP.delete(configuration[0]); + } + // 关闭之前的定时器 + oldConfig?.timer?.clear?.(); +} +export function removeConfiguration(dir?: string | string[]) { + const dirs = dir ? (Array.isArray(dir) ? dir : [dir]) : CONFIG_POOL.map(([dir]) => dir); + for (const dir of dirs) { + const idx = CONFIG_POOL.findIndex(([projectPath]) => projectPath === dir); + if (idx >= 0) { + // 关闭定时器 + AUTOUPDATE_MAP.get(CONFIG_POOL[idx][0])?.timer?.clear(); + AUTOUPDATE_MAP.delete(CONFIG_POOL[idx][0]); + CONFIG_POOL.splice(idx, 1); + } + } +} diff --git a/packages/vscode-extension/src/helper/config.ts b/packages/vscode-extension/src/helper/config.ts index 715fdfd..bc95d82 100644 --- a/packages/vscode-extension/src/helper/config.ts +++ b/packages/vscode-extension/src/helper/config.ts @@ -1,7 +1,5 @@ -import type { Config } from '@alova/wormhole'; +import type { Config, TemplateData } from '@alova/wormhole'; export type ConfigObject = [string, Config]; export const CONFIG_POOL: Array = []; -export default { - CONFIG_POOL -}; +export const TEMPLATE_DATA: Map = new Map(); diff --git a/packages/vscode-extension/src/utils/index.ts b/packages/vscode-extension/src/utils/index.ts index 6aff5ca..d478076 100644 --- a/packages/vscode-extension/src/utils/index.ts +++ b/packages/vscode-extension/src/utils/index.ts @@ -32,3 +32,18 @@ export function uuid() { }); return id; } +export function debounce any>(func: T, delay: number) { + let timeout: NodeJS.Timeout; + + return function (...args: Parameters) { + // 清除上一个计时器 + if (timeout) { + clearTimeout(timeout); + } + + // 设置新的计时器,延迟执行传入的函数 + timeout = setTimeout(() => { + func(...args); + }, delay); + } as T; +} diff --git a/packages/vscode-extension/src/utils/vscode.ts b/packages/vscode-extension/src/utils/vscode.ts index 11642ca..23d637d 100644 --- a/packages/vscode-extension/src/utils/vscode.ts +++ b/packages/vscode-extension/src/utils/vscode.ts @@ -1,3 +1,4 @@ +import path from 'node:path'; import * as vscode from 'vscode'; import { CommandKey, commandsMap } from '@/commands'; // 获取workspacePath文件 @@ -13,19 +14,26 @@ export const executeCommand = (cmd: CommandKey, ...args: T) => } }; // 获取当前workspacePath -export const getCurrentWorkspacePath = () => { +export const getCurrentWorkspacePath = (filePath?: string) => { // 获取当前活动编辑器 const editor = vscode.window.activeTextEditor; if (!editor) { return getWorkspacePaths()[0]; } - // 获取当前打开文件的路径 - const filePath = editor.document.uri.fsPath; - + filePath = filePath ?? editor.document.uri.fsPath; // 获取当前文件所在的工作区根目录 - const workspaceFolder = vscode.workspace.getWorkspaceFolder(editor.document.uri); + const workspaceFolder = vscode.workspace.getWorkspaceFolder(vscode.Uri.file(filePath)); if (!workspaceFolder) { return filePath; } return `${workspaceFolder.uri.fsPath}/`; }; + +export const getCurrentDirectory = () => { + // 获取当前活动编辑器 + const editor = vscode.window.activeTextEditor; + if (!editor) { + return getWorkspacePaths()[0]; + } + return path.dirname(editor.document.uri.fsPath); +}; diff --git a/packages/wormhole/src/config.ts b/packages/wormhole/src/config.ts index 65a8ace..683c656 100644 --- a/packages/wormhole/src/config.ts +++ b/packages/wormhole/src/config.ts @@ -9,7 +9,6 @@ declare global { const DEFAULT_CONFIG = { alovaTempPath: path.join('node_modules/.alova'), templatePath: path.join(__dirname, './templates'), - log: (...messageArr: any[]) => console.log(...messageArr), templateData: new Map(), Error }; diff --git a/packages/wormhole/src/functions/alovaJson.ts b/packages/wormhole/src/functions/alovaJson.ts index fccb52c..59df5bd 100644 --- a/packages/wormhole/src/functions/alovaJson.ts +++ b/packages/wormhole/src/functions/alovaJson.ts @@ -29,7 +29,9 @@ export const readAlovaJson = async (originPath: string, name = 'api.json') => { let jsonData = {} as TemplateData; try { jsonData = JSON.parse(data); - } catch (error) {} + } catch (error) { + jsonData = DEFAULT_CONFIG.templateData.get(originPath) ?? jsonData; + } return jsonData; }; export const getAlovaJsonPath = (workspaceRootDir: string, outputPath: string) => diff --git a/packages/wormhole/src/functions/openApi2Data.ts b/packages/wormhole/src/functions/openApi2Data.ts index 37a7fb2..18cfb8f 100644 --- a/packages/wormhole/src/functions/openApi2Data.ts +++ b/packages/wormhole/src/functions/openApi2Data.ts @@ -1,4 +1,3 @@ -import { getGlobalConfig } from '@/config'; import { findBy$ref, getStandardRefName, isReferenceObject, mergeObject, removeAll$ref } from '@/helper/openapi'; import { convertToType, jsonSchema2TsStr } from '@/helper/schema2type'; import { getStandardOperationId, getStandardTags } from '@/helper/standard'; @@ -9,7 +8,6 @@ import { cloneDeep, isEmpty } from 'lodash'; import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'; import { AlovaVersion } from './getAlovaVersion'; -const DEFAULT_CONFIG = getGlobalConfig(); type Path = { key: string; method: string; @@ -297,7 +295,7 @@ export const transformPathObj = async ( let newApiDescriptor: ApiDescriptor | void | undefined | null = apiDescriptor; let handleApiDone = false; try { - newApiDescriptor = handleApi(apiDescriptor, DEFAULT_CONFIG.log); + newApiDescriptor = handleApi(apiDescriptor); handleApiDone = true; } catch (error) { handleApiDone = false; diff --git a/packages/wormhole/src/interface.type.ts b/packages/wormhole/src/interface.type.ts index 2b13987..ef3d54c 100644 --- a/packages/wormhole/src/interface.type.ts +++ b/packages/wormhole/src/interface.type.ts @@ -18,7 +18,6 @@ export type ApiDescriptor = Omit void): ApiDescriptor | void | undefined | null; } export type GeneratorConfig = { // openapi的json文件url地址 diff --git a/packages/wormhole/test/__snapshots__/generate.spec.ts.snap b/packages/wormhole/test/__snapshots__/generate.spec.ts.snap index de713e3..439bf9c 100644 --- a/packages/wormhole/test/__snapshots__/generate.spec.ts.snap +++ b/packages/wormhole/test/__snapshots__/generate.spec.ts.snap @@ -19452,3 +19452,3611 @@ declare global { } " `; + +exports[`generate API > should generate the existing \`mediaType\` if the target \`mediaType\` is not matched 1`] = ` +"/// +/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.63 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +export default { + 'clients.generateFromURL': ['GET', '/generate'], + 'servers.generateFromURL': ['GET', '/generate'], + 'documentation.generateFromURL': ['GET', '/generate'], + 'config.generateFromURL': ['GET', '/generate'], + 'clients.generate': ['POST', '/generate'], + 'servers.generate': ['POST', '/generate'], + 'documentation.generate': ['POST', '/generate'], + 'config.generate': ['POST', '/generate'], + 'clients.clientLanguages': ['GET', '/clients'], + 'documentation.clientLanguages': ['GET', '/clients'], + 'servers.serverLanguages': ['GET', '/servers'], + 'documentation.documentationLanguages': ['GET', '/documentation'], + 'clients.languages': ['GET', '/{type}/{version}'], + 'servers.languages': ['GET', '/{type}/{version}'], + 'documentation.languages': ['GET', '/{type}/{version}'], + 'config.languages': ['GET', '/{type}/{version}'], + 'clients.languagesMulti': ['GET', '/types'], + 'servers.languagesMulti': ['GET', '/types'], + 'documentation.languagesMulti': ['GET', '/types'], + 'config.languagesMulti': ['GET', '/types'], + 'clients.listOptions': ['GET', '/options'], + 'servers.listOptions': ['GET', '/options'], + 'documentation.listOptions': ['GET', '/options'], + 'config.listOptions': ['GET', '/options'], + 'clients.generateBundle': ['POST', '/model'], + 'servers.generateBundle': ['POST', '/model'], + 'documentation.generateBundle': ['POST', '/model'], + 'config.generateBundle': ['POST', '/model'], + 'documentation.renderTemplate': ['POST', '/render'] +}; +" +`; + +exports[`generate API > should generate the existing \`mediaType\` if the target \`mediaType\` is not matched 2`] = ` +"import { createAlova } from 'alova'; +import fetchAdapter from 'alova/fetch'; +import { createApis, withConfigType } from './createApis'; + +export const alovaInstance = createAlova({ + baseURL: '/api', + requestAdapter: fetchAdapter(), + beforeRequest: method => {}, + responded: res => { + return res.json(); + } +}); + +export const $$userConfigMap = withConfigType({}); + +const Apis = createApis(alovaInstance, $$userConfigMap); + +export default Apis; +" +`; + +exports[`generate API > should generate the existing \`mediaType\` if the target \`mediaType\` is not matched 3`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.63 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, MethodType, AlovaGenerics, AlovaMethodCreateConfig } from 'alova'; +import { Method } from 'alova'; +import apiDefinitions from './apiDefinitions'; + +const createFunctionalProxy = (array: (string | symbol)[], alovaInstance: Alova, configMap: any) => { + // create a new proxy instance + return new Proxy(function () {}, { + get(_, property) { + // record the target property, so that it can get the completed accessing paths + array.push(property); + // always return a new proxy to continue recording accessing paths. + return createFunctionalProxy(array, alovaInstance, configMap); + }, + apply(_, __, [config]) { + const apiPathKey = array.join('.') as keyof typeof apiDefinitions; + const apiItem = apiDefinitions[apiPathKey]; + if (!apiItem) { + throw new Error(\`the api path of \\\`\${apiPathKey}\\\` is not found\`); + } + const mergedConfig = { + ...configMap[apiPathKey], + ...config + }; + const [method, url] = apiItem; + const pathParams = mergedConfig.pathParams; + const urlReplaced = url.replace(/\\{([^}]+)\\}/g, (_, key) => { + const pathParam = pathParams[key]; + return pathParam; + }); + delete mergedConfig.pathParams; + let data = mergedConfig.data; + if (Object.prototype.toString.call(data) === '[object Object]' && typeof FormData !== 'undefined') { + let hasBlobData = false; + const formData = new FormData(); + for (const key in data) { + formData.append(key, data[key]); + if (data[key] instanceof Blob) { + hasBlobData = true; + } + } + data = hasBlobData ? formData : data; + } + return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data); + } + }); +}; + +export const createApis = (alovaInstance: Alova, configMap: any) => { + const Apis = new Proxy({} as Apis, { + get(_, property) { + return createFunctionalProxy([property], alovaInstance, configMap); + } + }); + // define global variable \`Apis\` + (globalThis as any).Apis = Apis; + return Apis; +}; +type MethodConfig = AlovaMethodCreateConfig< + (typeof import('./index'))['alovaInstance'] extends Alova ? AG : any, + any, + T +>; +type APISofParameters = Tag extends keyof Apis + ? Url extends keyof Apis[Tag] + ? Apis[Tag][Url] extends (...args: any) => any + ? Parameters + : any + : any + : any; +type MethodsConfigMap = { + [P in keyof typeof import('./apiDefinitions').default]?: MethodConfig< + P extends \`\${infer Tag}.\${infer Url}\` ? Parameters[0]['transform']>[0] : any + >; +}; +export const withConfigType = (config: Config) => config; +" +`; + +exports[`generate API > should generate the existing \`mediaType\` if the target \`mediaType\` is not matched 4`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.63 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, AlovaMethodCreateConfig, AlovaGenerics, Method } from 'alova'; +import type { $$userConfigMap, alovaInstance } from '.'; +import type apiDefinitions from './apiDefinitions'; + +type CollapsedAlova = typeof alovaInstance; +type UserMethodConfigMap = typeof $$userConfigMap; + +type Alova2MethodConfig = + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Omit< + AlovaMethodCreateConfig< + AlovaGenerics, + any, + Responded + >, + 'params' + > + : never; + +// Extract the return type of transform function that define in $$userConfigMap, if it not exists, use the default type. +type ExtractUserDefinedTransformed< + DefinitionKey extends keyof typeof apiDefinitions, + Default +> = DefinitionKey extends keyof UserMethodConfigMap + ? UserMethodConfigMap[DefinitionKey]['transform'] extends (...args: any[]) => any + ? Awaited> + : Default + : Default; +type Alova2Method< + Responded, + DefinitionKey extends keyof typeof apiDefinitions, + CurrentConfig extends Alova2MethodConfig +> = + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Method< + AlovaGenerics< + CurrentConfig extends undefined + ? ExtractUserDefinedTransformed + : CurrentConfig['transform'] extends (...args: any[]) => any + ? Awaited> + : ExtractUserDefinedTransformed, + any, + RequestConfig, + Response, + ResponseHeader, + L1Cache, + L2Cache, + SE + > + > + : never; + +export type AuthorizationValue = { + /** + * Authorization value + */ + value?: string; + /** + * Authorization key + */ + keyName?: string; + /** + * Authorization type + */ + type?: 'query' | 'header'; +}; +export type Options = { + /** + * authorization + * --- + * adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + */ + auth?: string; + /** + * authorization + * --- + * adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + */ + authorizationValue?: AuthorizationValue; + /** + * api package + * --- + * package for generated api classes + */ + apiPackage?: string; + /** + * Template Version + * --- + * template version for generation + */ + templateVersion?: string; + /** + * model package + * --- + * package for generated models + */ + modelPackage?: string; + /** + * model name prefix + * --- + * Prefix that will be prepended to all model names. Default is the empty string. + */ + modelNamePrefix?: string; + /** + * model name suffix + * --- + * PrefixSuffix that will be appended to all model names. Default is the empty string. + */ + modelNameSuffix?: string; + /** + * System Properties + * --- + * sets specified system properties in key/value format + */ + systemProperties?: Record; + /** + * instantiation types + * --- + * sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + */ + instantiationTypes?: Record; + /** + * type mappings + * --- + * sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + */ + typeMappings?: Record; + /** + * additional properties + * --- + * sets additional properties that can be referenced by the mustache templates in key/value format. + */ + additionalProperties?: Record; + /** + * language specific primitives + * --- + * specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + */ + languageSpecificPrimitives?: string[]; + /** + * import mappings + * --- + * specifies mappings between a given class and the import that should be used for that class in key/value format. + */ + importMappings?: Record; + /** + * invoker package + * --- + * root package for generated code + */ + invokerPackage?: string; + /** + * group id + * --- + * groupId in generated pom.xml + */ + groupId?: string; + /** + * artifact id + * --- + * artifactId in generated pom.xml + */ + artifactId?: string; + /** + * artifact version + * --- + * artifact version generated in pom.xml + */ + artifactVersion?: string; + /** + * library + * --- + * library template (sub-template) + */ + library?: string; + /** + * git user id + * --- + * Git user ID, e.g. swagger-api. + */ + gitUserId?: string; + /** + * git repo id + * --- + * Git repo ID, e.g. swagger-codegen. + */ + gitRepoId?: string; + /** + * release note + * --- + * Release note, default to 'Minor update'. + */ + releaseNote?: string; + /** + * http user agent + * --- + * HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + */ + httpUserAgent?: string; + /** + * reserved words mappings + * --- + * pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + */ + reservedWordsMappings?: Record; + /** + * ignore file override location + * --- + * Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + */ + ignoreFileOverride?: string; + /** + * remove prefix of the operationId + * --- + * Remove prefix of operationId, e.g. config_getId => getId + */ + removeOperationIdPrefix?: boolean; + skipOverride?: boolean; +}; +export type GenerationRequest = { + /** + * language + * --- + * language to generate (required) + * [required] + */ + lang: string; + /** + * spec in json format. . Alternative to \`specURL\` + */ + spec?: object; + /** + * URL of the spec in json format. Alternative to \`spec\` + */ + specURL?: string; + /** + * type of the spec + */ + type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG'; + /** + * codegen version to use + */ + codegenVersion?: 'V2' | 'V3'; + options?: Options; +}; +export type CliOption = { + optionName?: string; + description?: string; + /** + * Data type is based on the types supported by the JSON-Schema + */ + type?: string; + enum?: Record; + default?: string; +}; +export type RenderRequest = { + /** + * template + * --- + * template as string + * [required] + */ + template: string; + /** + * context + * --- + * context as string + * [required] + */ + context: string; +}; +declare global { + interface Apis { + clients: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'client' or 'documentation' for given codegen version (defaults to V3) + * + * **path:** /clients + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * // flag to only return languages of type \`client\` + * clientOnly?: boolean + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + clientLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + /** + * flag to only return languages of type \`client\` + */ + clientOnly?: boolean; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'clients.listOptions', Config>; + /** + * --- + * + * [POST] Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = object + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + servers: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'server' for given codegen version (defaults to V3) + * + * **path:** /servers + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + serverLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'servers.listOptions', Config>; + /** + * --- + * + * [POST] Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = object + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + documentation: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'client' or 'documentation' for given codegen version (defaults to V3) + * + * **path:** /clients + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * // flag to only return languages of type \`client\` + * clientOnly?: boolean + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + clientLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + /** + * flag to only return languages of type \`client\` + */ + clientOnly?: boolean; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'documentation' for given codegen version (defaults to V3) + * + * **path:** /documentation + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + documentationLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'documentation.listOptions', Config>; + /** + * --- + * + * [POST] Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = object + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] render a template using the provided data + * + * **path:** /render + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] template + * // template as string + * // [required] + * template: string + * // [title] context + * // context as string + * // [required] + * context: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + renderTemplate< + Config extends Alova2MethodConfig & { + data: RenderRequest; + } + >( + config: Config + ): Alova2Method; + }; + config: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'config.listOptions', Config>; + /** + * --- + * + * [POST] Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required) + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = object + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + } + + var Apis: Apis; +} +" +`; + +exports[`generate API > should preprocess non-variable-specification characters 1`] = ` +"/// +/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Petstore - version 1.0.7 + * + * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI version: 3.0.0 + * + * Contact: + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +export default { + 'pet.uploadFile': ['POST', '/pet/{petId}/uploadImage'], + 'pet.addPet': ['POST', '/pet'], + 'pet.updatePet': ['PUT', '/pet'], + 'pet.findPetsByStatus': ['GET', '/pet/findByStatus'], + 'pet.findPetsByTags': ['GET', '/pet/findByTags'], + 'pet.getPetById': ['GET', '/pet/{petId}'], + 'pet.updatePetWithForm': ['POST', '/pet/{petId}'], + 'pet.deletePet': ['DELETE', '/pet/{petId}'], + 'store.getInventory': ['GET', '/store/inventory'], + 'store.placeOrder': ['POST', '/store/order'], + 'store.getOrderById': ['GET', '/store/order/{orderId}'], + 'store.deleteOrder': ['DELETE', '/store/order/{orderId}'], + 'user.createUsersWithListInput': ['POST', '/user/createWithList'], + 'user.getUserByName': ['GET', '/user/{username}'], + 'user.updateUser': ['PUT', '/user/{username}'], + 'user.deleteUser': ['DELETE', '/user/{username}'], + 'user.loginUser': ['GET', '/user/login'], + 'user.logoutUser': ['GET', '/user/logout'], + 'user.createUsersWithArrayInput': ['POST', '/user/createWithArray'], + 'user.createUser': ['POST', '/user'] +}; +" +`; + +exports[`generate API > should preprocess non-variable-specification characters 2`] = ` +"import { createAlova } from 'alova'; +import fetchAdapter from 'alova/fetch'; +import { createApis, withConfigType } from './createApis'; + +export const alovaInstance = createAlova({ + baseURL: 'https://petstore.swagger.io/v2', + requestAdapter: fetchAdapter(), + beforeRequest: method => {}, + responded: res => { + return res.json(); + } +}); + +export const $$userConfigMap = withConfigType({}); + +const Apis = createApis(alovaInstance, $$userConfigMap); + +export default Apis; +" +`; + +exports[`generate API > should preprocess non-variable-specification characters 3`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Petstore - version 1.0.7 + * + * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI version: 3.0.0 + * + * Contact: + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, MethodType, AlovaGenerics, AlovaMethodCreateConfig } from 'alova'; +import { Method } from 'alova'; +import apiDefinitions from './apiDefinitions'; + +const createFunctionalProxy = (array: (string | symbol)[], alovaInstance: Alova, configMap: any) => { + // create a new proxy instance + return new Proxy(function () {}, { + get(_, property) { + // record the target property, so that it can get the completed accessing paths + array.push(property); + // always return a new proxy to continue recording accessing paths. + return createFunctionalProxy(array, alovaInstance, configMap); + }, + apply(_, __, [config]) { + const apiPathKey = array.join('.') as keyof typeof apiDefinitions; + const apiItem = apiDefinitions[apiPathKey]; + if (!apiItem) { + throw new Error(\`the api path of \\\`\${apiPathKey}\\\` is not found\`); + } + const mergedConfig = { + ...configMap[apiPathKey], + ...config + }; + const [method, url] = apiItem; + const pathParams = mergedConfig.pathParams; + const urlReplaced = url.replace(/\\{([^}]+)\\}/g, (_, key) => { + const pathParam = pathParams[key]; + return pathParam; + }); + delete mergedConfig.pathParams; + let data = mergedConfig.data; + if (Object.prototype.toString.call(data) === '[object Object]' && typeof FormData !== 'undefined') { + let hasBlobData = false; + const formData = new FormData(); + for (const key in data) { + formData.append(key, data[key]); + if (data[key] instanceof Blob) { + hasBlobData = true; + } + } + data = hasBlobData ? formData : data; + } + return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data); + } + }); +}; + +export const createApis = (alovaInstance: Alova, configMap: any) => { + const Apis = new Proxy({} as Apis, { + get(_, property) { + return createFunctionalProxy([property], alovaInstance, configMap); + } + }); + // define global variable \`Apis\` + (globalThis as any).Apis = Apis; + return Apis; +}; +type MethodConfig = AlovaMethodCreateConfig< + (typeof import('./index'))['alovaInstance'] extends Alova ? AG : any, + any, + T +>; +type APISofParameters = Tag extends keyof Apis + ? Url extends keyof Apis[Tag] + ? Apis[Tag][Url] extends (...args: any) => any + ? Parameters + : any + : any + : any; +type MethodsConfigMap = { + [P in keyof typeof import('./apiDefinitions').default]?: MethodConfig< + P extends \`\${infer Tag}.\${infer Url}\` ? Parameters[0]['transform']>[0] : any + >; +}; +export const withConfigType = (config: Config) => config; +" +`; + +exports[`generate API > should preprocess non-variable-specification characters 4`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Petstore - version 1.0.7 + * + * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI version: 3.0.0 + * + * Contact: + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, AlovaMethodCreateConfig, AlovaGenerics, Method } from 'alova'; +import type { $$userConfigMap, alovaInstance } from '.'; +import type apiDefinitions from './apiDefinitions'; + +type CollapsedAlova = typeof alovaInstance; +type UserMethodConfigMap = typeof $$userConfigMap; + +type Alova2MethodConfig = + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Omit< + AlovaMethodCreateConfig< + AlovaGenerics, + any, + Responded + >, + 'params' + > + : never; + +// Extract the return type of transform function that define in $$userConfigMap, if it not exists, use the default type. +type ExtractUserDefinedTransformed< + DefinitionKey extends keyof typeof apiDefinitions, + Default +> = DefinitionKey extends keyof UserMethodConfigMap + ? UserMethodConfigMap[DefinitionKey]['transform'] extends (...args: any[]) => any + ? Awaited> + : Default + : Default; +type Alova2Method< + Responded, + DefinitionKey extends keyof typeof apiDefinitions, + CurrentConfig extends Alova2MethodConfig +> = + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Method< + AlovaGenerics< + CurrentConfig extends undefined + ? ExtractUserDefinedTransformed + : CurrentConfig['transform'] extends (...args: any[]) => any + ? Awaited> + : ExtractUserDefinedTransformed, + any, + RequestConfig, + Response, + ResponseHeader, + L1Cache, + L2Cache, + SE + > + > + : never; + +export type ApiResponse = { + code?: number; + type?: string; + message?: string; +}; +export type Category = { + id?: number; + name?: string; +}; +export type Tag = { + id?: number; + name?: string; +}; +export type Pet = { + id?: number; + category?: Category; + /** + * [required] + */ + name: string; + /** + * [required] + */ + photoUrls: string[]; + tags?: Tag[]; + /** + * pet status in the store + */ + status?: 'available' | 'pending' | 'sold'; +}; +export type Order = { + id?: number; + petId?: number; + quantity?: number; + shipDate?: string; + /** + * Order Status + */ + status?: 'placed' | 'approved' | 'delivered'; + complete?: boolean; +}; +export type User = { + id?: number; + username?: string; + firstName?: string; + lastName?: string; + email?: string; + password?: string; + phone?: string; + /** + * User Status + */ + userStatus?: number; +}; +declare global { + interface Apis { + pet: { + /** + * --- + * + * [POST] uploads an image + * + * **path:** /pet/{petId}/uploadImage + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // ID of pet to update + * // [required] + * petId: number + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // Additional data to pass to server + * additionalMetadata?: string + * // file to upload + * file?: Blob + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * code?: number + * type?: string + * message?: string + * } + * \`\`\` + */ + uploadFile< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of pet to update + * [required] + */ + petId: number; + }; + data: { + /** + * Additional data to pass to server + */ + additionalMetadata?: string; + /** + * file to upload + */ + file?: Blob; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Add a new pet to the store + * + * **path:** /pet + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * id?: number + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * status?: 'available' | 'pending' | 'sold' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + addPet< + Config extends Alova2MethodConfig & { + data: Pet; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [PUT] Update an existing pet + * + * **path:** /pet + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * id?: number + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * status?: 'available' | 'pending' | 'sold' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + updatePet< + Config extends Alova2MethodConfig & { + data: Pet; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Finds Pets by status + * + * **path:** /pet/findByStatus + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // Status values that need to be considered for filter + * // [required] + * status: ('available' | 'pending' | 'sold')[] + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Array<{ + * id?: number + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * status?: 'available' | 'pending' | 'sold' + * }> + * \`\`\` + */ + findPetsByStatus< + Config extends Alova2MethodConfig & { + params: { + /** + * Status values that need to be considered for filter + * [required] + */ + status: ('available' | 'pending' | 'sold')[]; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Finds Pets by tags + * + * **path:** /pet/findByTags + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // Tags to filter by + * // [required] + * tags: string[] + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Array<{ + * id?: number + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * status?: 'available' | 'pending' | 'sold' + * }> + * \`\`\` + */ + findPetsByTags< + Config extends Alova2MethodConfig & { + params: { + /** + * Tags to filter by + * [required] + */ + tags: string[]; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Find pet by ID + * + * **path:** /pet/{petId} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // ID of pet to return + * // [required] + * petId: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * id?: number + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * status?: 'available' | 'pending' | 'sold' + * } + * \`\`\` + */ + getPetById< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of pet to return + * [required] + */ + petId: number; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Updates a pet in the store with form data + * + * **path:** /pet/{petId} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // ID of pet that needs to be updated + * // [required] + * petId: number + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // Updated name of the pet + * name?: string + * // Updated status of the pet + * status?: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + updatePetWithForm< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of pet that needs to be updated + * [required] + */ + petId: number; + }; + data: { + /** + * Updated name of the pet + */ + name?: string; + /** + * Updated status of the pet + */ + status?: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [DELETE] Deletes a pet + * + * **path:** /pet/{petId} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // Pet id to delete + * // [required] + * petId: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + deletePet< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * Pet id to delete + * [required] + */ + petId: number; + }; + } + >( + config: Config + ): Alova2Method; + }; + store: { + /** + * --- + * + * [GET] Returns pet inventories by status + * + * **path:** /store/inventory + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record + * \`\`\` + */ + getInventory>>( + config?: Config + ): Alova2Method, 'store.getInventory', Config>; + /** + * --- + * + * [POST] Place an order for a pet + * + * **path:** /store/order + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * id?: number + * petId?: number + * quantity?: number + * shipDate?: string + * // Order Status + * status?: 'placed' | 'approved' | 'delivered' + * complete?: boolean + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * id?: number + * petId?: number + * quantity?: number + * shipDate?: string + * // Order Status + * status?: 'placed' | 'approved' | 'delivered' + * complete?: boolean + * } + * \`\`\` + */ + placeOrder< + Config extends Alova2MethodConfig & { + data: Order; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Find purchase order by ID + * + * **path:** /store/order/{orderId} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // ID of pet that needs to be fetched + * // [required] + * orderId: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * id?: number + * petId?: number + * quantity?: number + * shipDate?: string + * // Order Status + * status?: 'placed' | 'approved' | 'delivered' + * complete?: boolean + * } + * \`\`\` + */ + getOrderById< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of pet that needs to be fetched + * [required] + */ + orderId: number; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [DELETE] Delete purchase order by ID + * + * **path:** /store/order/{orderId} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // ID of the order that needs to be deleted + * // [required] + * orderId: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + deleteOrder< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of the order that needs to be deleted + * [required] + */ + orderId: number; + }; + } + >( + config: Config + ): Alova2Method; + }; + user: { + /** + * --- + * + * [POST] Creates list of users with given input array + * + * **path:** /user/createWithList + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = Array<{ + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * }> + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + createUsersWithListInput< + Config extends Alova2MethodConfig & { + data: User[]; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Get user by user name + * + * **path:** /user/{username} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // The name that needs to be fetched. Use user1 for testing. + * // [required] + * username: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * } + * \`\`\` + */ + getUserByName< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * The name that needs to be fetched. Use user1 for testing. + * [required] + */ + username: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [PUT] Updated user + * + * **path:** /user/{username} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // name that need to be updated + * // [required] + * username: string + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + updateUser< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * name that need to be updated + * [required] + */ + username: string; + }; + data: User; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [DELETE] Delete user + * + * **path:** /user/{username} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // The name that needs to be deleted + * // [required] + * username: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + deleteUser< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * The name that needs to be deleted + * [required] + */ + username: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Logs user into the system + * + * **path:** /user/login + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // The user name for login + * // [required] + * username: string + * // The password for login in clear text + * // [required] + * password: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string + * \`\`\` + */ + loginUser< + Config extends Alova2MethodConfig & { + params: { + /** + * The user name for login + * [required] + */ + username: string; + /** + * The password for login in clear text + * [required] + */ + password: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Logs out current logged in user session + * + * **path:** /user/logout + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + logoutUser>( + config?: Config + ): Alova2Method; + /** + * --- + * + * [POST] Creates list of users with given input array + * + * **path:** /user/createWithArray + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = Array<{ + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * }> + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + createUsersWithArrayInput< + Config extends Alova2MethodConfig & { + data: User[]; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Create user + * + * **path:** /user + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + createUser< + Config extends Alova2MethodConfig & { + data: User; + } + >( + config: Config + ): Alova2Method; + }; + } + + var Apis: Apis; +} +" +`; diff --git a/packages/wormhole/typings/index.d.ts b/packages/wormhole/typings/index.d.ts index dd93b22..e7b0d9f 100644 --- a/packages/wormhole/typings/index.d.ts +++ b/packages/wormhole/typings/index.d.ts @@ -15,7 +15,6 @@ export type ApiDescriptor = Omit void): ApiDescriptor | void | undefined | null; } export type GeneratorConfig = { input: string; @@ -91,7 +90,6 @@ export interface TemplateData extends Omit { declare const DEFAULT_CONFIG: { alovaTempPath: string; templatePath: string; - log: (...messageArr: any[]) => void; templateData: Map; Error: ErrorConstructor; }; diff --git a/packages/wormhole/vitest.config.ts b/packages/wormhole/vitest.config.ts index 74936c8..57dc024 100644 --- a/packages/wormhole/vitest.config.ts +++ b/packages/wormhole/vitest.config.ts @@ -3,6 +3,7 @@ import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { + poolMatchGlobs: [['**/test/cli.spec.ts', 'vmThreads']], // https://github.com/vitest-dev/vitest/issues/960 alias: { '@': resolve(__dirname, 'src') }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aaef5c4..0cc3f2d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -101,6 +101,9 @@ importers: '@alova/wormhole': specifier: workspace:^ version: link:../wormhole + glob: + specifier: ^11.0.0 + version: 11.0.0 import-fresh: specifier: ^3.3.0 version: 3.3.0 From 21a3ca318dc65d8bea4a3f0e5174ffdfcd17dd9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E9=95=87?= Date: Thu, 7 Nov 2024 15:06:29 +0800 Subject: [PATCH 37/47] feat: wormhole and devtools splited is completed --- .eslintignore | 6 - .eslintrc.cjs | 52 - .gitignore | 8 +- .vscode/launch.json | 23 + .vscode/tasks.json | 25 + eslint.config.mjs | 98 ++ package.json | 21 +- packages/vscode-extension/.vscode-test.mjs | 2 +- packages/vscode-extension/.vscode/launch.json | 2 +- packages/vscode-extension/.vscodeignore | 2 +- packages/vscode-extension/esbuild.ts | 2 +- packages/vscode-extension/package.json | 18 +- packages/vscode-extension/resources/logo.svg | 1 + .../src/commands/generateApi.ts | 1 + .../vscode-extension/src/commands/index.ts | 2 +- .../vscode-extension/src/commands/refresh.ts | 2 +- .../vscode-extension/src/commands/setup.ts | 4 +- .../src/functions/getWormhole.ts | 14 +- packages/vscode-extension/test/config.spec.ts | 45 + packages/vscode-extension/tsconfig.json | 3 +- packages/wormhole/README.md | 49 + packages/wormhole/package.json | 11 +- packages/wormhole/scripts/build-copy.ts | 4 - packages/wormhole/src/bin/actions.ts | 5 +- packages/wormhole/src/functions/alovaJson.ts | 2 +- .../wormhole/src/functions/getOpenApiData.ts | 2 +- .../wormhole/src/functions/openApi2Data.ts | 4 +- packages/wormhole/src/interface.type.ts | 2 + .../wormhole/src/modules/Configuration.ts | 13 +- packages/wormhole/src/readConfig.ts | 2 +- .../templates/commonjs/createApis.handlebars | 2 +- .../commonjs/v3-createApis.handlebars | 2 +- .../templates/module/createApis.handlebars | 2 +- .../templates/module/v3-createApis.handlebars | 2 +- .../typescript/createApis.handlebars | 2 +- .../typescript/v3-createApis.handlebars | 2 +- packages/wormhole/src/utils/index.ts | 9 +- packages/wormhole/test/config.spec.ts | 6 +- packages/wormhole/test/generate.spec.ts | 42 + .../wormhole/test/output/openapi_300/index.ts | 1 + packages/wormhole/tsconfig.json | 2 + packages/wormhole/typings/index.d.ts | 2 + pnpm-lock.yaml | 1262 ++++++++++------- test/api-v3-ts-test/alova.config.ts | 68 + .../openapi1.json | 0 test/api-v3-ts-test/package.json | 10 +- test/api-v3-ts-test/src/api/apiDefinitions.ts | 40 + test/api-v3-ts-test/src/api/createApis.ts | 92 ++ test/api-v3-ts-test/src/api/globals.d.ts | 1033 ++++++++++++++ test/api-v3-ts-test/src/api/index.ts | 18 + test/api-v3-ts-test/src/main.ts | 12 + tsconfig.base.json | 3 +- tsconfig.json | 2 +- vitest.workspace.ts | 2 +- 54 files changed, 2346 insertions(+), 695 deletions(-) delete mode 100644 .eslintignore delete mode 100644 .eslintrc.cjs create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json create mode 100644 eslint.config.mjs create mode 100644 packages/vscode-extension/resources/logo.svg create mode 100644 packages/vscode-extension/test/config.spec.ts create mode 100644 packages/wormhole/README.md delete mode 100644 packages/wormhole/scripts/build-copy.ts create mode 100644 test/api-v3-ts-test/alova.config.ts rename test/{api-common => api-v3-ts-test}/openapi1.json (100%) create mode 100644 test/api-v3-ts-test/src/api/apiDefinitions.ts create mode 100644 test/api-v3-ts-test/src/api/createApis.ts create mode 100644 test/api-v3-ts-test/src/api/globals.d.ts create mode 100644 test/api-v3-ts-test/src/api/index.ts create mode 100644 test/api-v3-ts-test/src/main.ts diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index ce5a37a..0000000 --- a/.eslintignore +++ /dev/null @@ -1,6 +0,0 @@ -test/api-*/src/* -test/api-*/openapi*.* -test/api-*/swagger*.* -test/api-*/alova.config.* -!test/api-*/src/.gitkeep -design/**/* \ No newline at end of file diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index 8146fcc..0000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,52 +0,0 @@ -module.exports = { - env: { - browser: true, - es2021: true, - node: true - }, - ignorePatterns: ['out', '**/__mocks__', '**/*.handlebars', 'test/api-*/**/*.*'], - extends: ['airbnb', 'airbnb-typescript', 'prettier'], - parser: '@typescript-eslint/parser', - parserOptions: { - ecmaVersion: 'latest', - project: './tsconfig.json', // 确保路径正确 - tsconfigRootDir: __dirname - }, - plugins: ['@typescript-eslint', 'prettier'], - rules: { - 'prettier/prettier': 'error', - - // eslint-airbnb - 'import/extensions': 'off', - 'import/no-extraneous-dependencies': 'off', - 'no-param-reassign': 'off', - 'no-restricted-syntax': 'off', - 'no-underscore-dangle': 'off', - 'import/no-mutable-exports': 'off', - 'no-nested-ternary': 'off', - 'no-multi-assign': 'off', - 'consistent-return': 'off', - 'no-restricted-exports': 'off', - 'linebreak-style': 'off', - 'no-unused-vars': 'off', - 'import/order': 'off', - 'import/no-relative-packages': 'off', - 'guard-for-in': 'off', - 'max-classes-per-file': 'off', - 'no-await-in-loop': 'off', - 'func-names': 'off', - 'no-continue': 'off', - // @typescript-eslint - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/no-unused-vars': ['error', { destructuredArrayIgnorePattern: '^_' }], - '@typescript-eslint/no-empty-function': 'off', - '@typescript-eslint/ban-ts-comment': 'off', - '@typescript-eslint/no-var-requires': 'off', - '@typescript-eslint/no-this-alias': 'off', - '@typescript-eslint/no-unused-expressions': 'off', - '@typescript-eslint/no-implied-eval': 'off', - '@typescript-eslint/no-shadow': 'off', - '@typescript-eslint/no-use-before-define': 'off', - 'no-empty': 'off' - } -}; diff --git a/.gitignore b/.gitignore index e818157..d79ebe1 100644 --- a/.gitignore +++ b/.gitignore @@ -11,10 +11,4 @@ dist *.vsix .vscode-test/ -# 忽略test下的生成文件 -test/api-*/src/* -test/api-*/*openapi*.* -test/api-*/*swagger*.* -test/api-*/alova.config.* -!test/api-*/src/.gitkeep -!test/api-common/* \ No newline at end of file +alova_tmp_* \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..c46d6c2 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,23 @@ +// A launch configuration that compiles the extension and then opens it inside a new window +// Use IntelliSense to learn about possible attributes. +// Hover to view descriptions of existing attributes. +// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Run Extension", + "type": "extensionHost", + "request": "launch", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}/packages/vscode-extension", + "-u", + "tdd", + "--disable-extensions" + ], + "cwd": "${workspaceFolder}/packages/vscode-extension", + "outFiles": ["${workspaceFolder}/packages/vscode-extension/out/**/*.js"], + "preLaunchTask": "${defaultBuildTask}" + } + ] +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..3a74500 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,25 @@ +// See https://go.microsoft.com/fwlink/?LinkId=733558 +// for the documentation about the tasks.json format +{ + "version": "2.0.0", + "tasks": [ + { + "label": "watch", + "type": "npm", + "script": "watch:esbuild", + "problemMatcher": "$esbuild-watch", + "isBackground": true, + "options": { + "cwd": "${workspaceFolder}/packages/vscode-extension" + }, + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "group": "watch", + "reveal": "never" + } + } + ] +} diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..cb741d4 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,98 @@ +import { FlatCompat } from '@eslint/eslintrc'; +import typescriptEslint from '@typescript-eslint/eslint-plugin'; +import tsParser from '@typescript-eslint/parser'; +import prettier from 'eslint-plugin-prettier'; +import globals from 'globals'; + +const { dirname } = import.meta; +const compat = new FlatCompat({ + baseDirectory: dirname +}); + +export default [ + { + ignores: [ + '**/out', + '**/dist', + '**/__mocks__', + '**/*.handlebars', + '**/.vscode-test', + '**/.vscode-test.mjs', + '*.{js,mjs,cjs}', + 'packages/wormhole/typings', + 'design', + 'test-demos/**/*' + ] + }, + ...compat.extends('airbnb', 'airbnb-typescript', 'prettier'), + { + files: ['**/*.{js,mjs,cjs,ts,tsx}'], + plugins: { + '@typescript-eslint': typescriptEslint, + prettier + }, + + languageOptions: { + globals: { + ...globals.browser, + ...globals.node + }, + + parser: tsParser, + ecmaVersion: 'latest', + sourceType: 'commonjs', + + parserOptions: { + project: './tsconfig.json', + tsconfigRootDir: dirname + } + }, + + rules: { + 'prettier/prettier': 'error', + + // eslint-airbnb + 'import/extensions': 'off', + 'import/no-extraneous-dependencies': 'off', + 'no-param-reassign': 'off', + 'no-restricted-syntax': 'off', + 'no-underscore-dangle': 'off', + 'import/no-mutable-exports': 'off', + 'no-nested-ternary': 'off', + 'no-multi-assign': 'off', + 'consistent-return': 'off', + 'no-restricted-exports': 'off', + 'linebreak-style': 'off', + 'no-unused-vars': 'off', + 'import/order': 'off', + 'import/no-relative-packages': 'off', + 'guard-for-in': 'off', + 'max-classes-per-file': 'off', + 'no-await-in-loop': 'off', + 'func-names': 'off', + 'no-continue': 'off', + 'no-empty': 'off', + + // @typescript-eslint + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + args: 'after-used', + argsIgnorePattern: '^_', + varsIgnorePattern: 'Unused' + } + ], + '@typescript-eslint/no-empty-function': 'off', + '@typescript-eslint/ban-ts-comment': 'off', + '@typescript-eslint/no-var-requires': 'off', + '@typescript-eslint/no-this-alias': 'off', + '@typescript-eslint/no-unused-expressions': 'off', + '@typescript-eslint/no-implied-eval': 'off', + '@typescript-eslint/no-shadow': 'off', + '@typescript-eslint/no-use-before-define': 'off', + '@typescript-eslint/lines-between-class-members': 'off', + '@typescript-eslint/no-throw-literal': 'off' + } + } +]; diff --git a/package.json b/package.json index 7fc2875..ead21da 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "@alova/devtools", + "name": "alova-devtools", "displayName": "Alova", "description": "devtool kits for alova.js", "version": "0.0.0", @@ -10,13 +10,14 @@ }, "scripts": { "test": "vitest", - "lint": "eslint . --ext .js,.ts", + "lint": "eslint", "lint:fix": "npm run lint -- --fix", "format": "prettier --check .", "format:fix": "prettier --write .", "api-test": "tsx scripts/api-test.ts", "commit": "git-cz && git push", - "prepare": "husky" + "prepare": "husky", + "watch:extension": "pnpm --filter=alova-vscode-extension watch:esbuild" }, "license": "MIT", "repository": { @@ -38,18 +39,20 @@ "@types/node": "^18.19.0", "@types/rimraf": "^4.0.5", "@types/serialize-javascript": "^5.0.4", - "@typescript-eslint/eslint-plugin": "^7.13.0", - "@typescript-eslint/parser": "^7.13.0", + "@typescript-eslint/eslint-plugin": "^8.13.0", + "@typescript-eslint/parser": "^8.13.0", + "changeset": "^0.2.6", "commitizen": "^4.3.0", "cz-conventional-changelog": "^3.3.0", "dts-bundle-generator": "^9.5.1", - "eslint": "^8.57.0", + "eslint": "^9.14.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^18.0.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.1.3", + "eslint-plugin-prettier": "^5.2.1", "husky": "^9.0.11", "lint-staged": "^15.2.2", + "ncp": "^2.0.0", "npm-run-all": "^4.1.5", "prettier": "^3.2.5", "prettier-plugin-organize-imports": "^3.2.4", @@ -65,5 +68,9 @@ "commitizen": { "path": "./node_modules/cz-conventional-changelog" } + }, + "dependencies": { + "@eslint/eslintrc": "^3.1.0", + "globals": "^15.12.0" } } diff --git a/packages/vscode-extension/.vscode-test.mjs b/packages/vscode-extension/.vscode-test.mjs index 5edeb1e..d4d4d5d 100644 --- a/packages/vscode-extension/.vscode-test.mjs +++ b/packages/vscode-extension/.vscode-test.mjs @@ -1,5 +1,5 @@ import { defineConfig } from '@vscode/test-cli'; export default defineConfig({ - files: 'out/test/**/*.test.js' + files: 'out/test/**/*.spec.js' }); diff --git a/packages/vscode-extension/.vscode/launch.json b/packages/vscode-extension/.vscode/launch.json index a0ca3cb..ce12f6c 100644 --- a/packages/vscode-extension/.vscode/launch.json +++ b/packages/vscode-extension/.vscode/launch.json @@ -9,7 +9,7 @@ "name": "Run Extension", "type": "extensionHost", "request": "launch", - "args": ["--extensionDevelopmentPath=${workspaceFolder}"], + "args": ["--extensionDevelopmentPath=${workspaceFolder}", "-u", "tdd", "--disable-extensions"], "outFiles": ["${workspaceFolder}/out/**/*.js"], "preLaunchTask": "${defaultBuildTask}" } diff --git a/packages/vscode-extension/.vscodeignore b/packages/vscode-extension/.vscodeignore index 9fea3cb..83ee56e 100644 --- a/packages/vscode-extension/.vscodeignore +++ b/packages/vscode-extension/.vscodeignore @@ -1,6 +1,6 @@ .vscode/** .vscode-test/** -dist/** +out/** src/** .gitignore .yarnrc diff --git a/packages/vscode-extension/esbuild.ts b/packages/vscode-extension/esbuild.ts index 4b0932f..079ba4a 100644 --- a/packages/vscode-extension/esbuild.ts +++ b/packages/vscode-extension/esbuild.ts @@ -32,7 +32,7 @@ async function main() { sourcesContent: false, platform: 'node', outdir: 'out', - external: ['vscode'], + external: ['vscode', '@alova/wormhole'], logLevel: 'silent', plugins: [ alias({ diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index 0ad6d75..40ee1c8 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -12,10 +12,9 @@ "Other" ], "activationEvents": [ - "workspaceContains:**/*.ts", - "workspaceContains:**/*.js" + "workspaceContains:package.json" ], - "main": "./out/extension.js", + "main": "out/extension.js", "icon": "resources/icon.png", "contributes": { "commands": [ @@ -41,14 +40,12 @@ } }, "scripts": { - "vscode:prepublish": "pnpm run package", + "vscode:prepublish": "pnpm run check-types && pnpm run lint:fix && tsx esbuild.ts --production", "compile": "pnpm run check-types && pnpm run lint:fix && tsx esbuild.ts", "watch": "npm-run-all -p watch:*", "watch:esbuild": "tsx esbuild.ts --watch", - "package": "pnpm run check-types && pnpm run lint:fix && tsx esbuild.ts --production", - "compile-tests": "tsc -p . --outDir out", + "pretest": "tsc -p . --outDir out && tsx esbuild.ts", "watch-tests": "tsc -p . -w --outDir out", - "pretest": "pnpm run compile-tests && pnpm run compile && pnpm run lint", "check-types": "tsc --noEmit", "lint": "eslint . --ext .js,.ts", "lint:fix": "npm run lint -- --fix", @@ -70,15 +67,18 @@ "url": "https://github.com/alovajs/devtools/issues" }, "devDependencies": { + "@types/mocha": "^10.0.9", + "@types/sinon": "^17.0.3", "@types/vscode": "^1.89.0", "@vscode/test-cli": "^0.0.9", "@vscode/test-electron": "^2.3.9", "@vscode/vsce": "^2.29.0", "esbuild": "^0.24.0", - "esbuild-plugin-alias": "^0.2.1" + "esbuild-plugin-alias": "^0.2.1", + "sinon": "^19.0.2" }, "dependencies": { - "@alova/wormhole": "workspace:^", + "@alova/wormhole": "workspace:*", "glob": "^11.0.0", "import-fresh": "^3.3.0" } diff --git a/packages/vscode-extension/resources/logo.svg b/packages/vscode-extension/resources/logo.svg new file mode 100644 index 0000000..a37539c --- /dev/null +++ b/packages/vscode-extension/resources/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/vscode-extension/src/commands/generateApi.ts b/packages/vscode-extension/src/commands/generateApi.ts index 9b41ff1..e183121 100644 --- a/packages/vscode-extension/src/commands/generateApi.ts +++ b/packages/vscode-extension/src/commands/generateApi.ts @@ -2,6 +2,7 @@ import message from '@/components/message'; import readConfig from '@/functions/readConfig'; import generate from '@/functions/generate'; import { getFileNameByPath } from '@/utils'; + // 用于自动生成 export default { commandId: 'alova.generateApi', diff --git a/packages/vscode-extension/src/commands/index.ts b/packages/vscode-extension/src/commands/index.ts index 71e9aa7..a447631 100644 --- a/packages/vscode-extension/src/commands/index.ts +++ b/packages/vscode-extension/src/commands/index.ts @@ -5,7 +5,6 @@ import refresh from './refresh'; import setup from './setup'; import showStatusBarIcon from './showStatusBarIcon'; -export const commands = [setup, autocomplete, generateApi, refresh, showStatusBarIcon, createConfig]; export const commandsMap = { setup, autocomplete, @@ -14,4 +13,5 @@ export const commandsMap = { createConfig, showStatusBarIcon }; +export const commands = Object.values(commandsMap); export type CommandKey = keyof typeof commandsMap; diff --git a/packages/vscode-extension/src/commands/refresh.ts b/packages/vscode-extension/src/commands/refresh.ts index b94c421..a3226ac 100644 --- a/packages/vscode-extension/src/commands/refresh.ts +++ b/packages/vscode-extension/src/commands/refresh.ts @@ -18,7 +18,7 @@ export default { // 生成api文件 const { resultArr, errorArr } = await generate({ force: true }); for (const [workspaceRootDir] of resultArr) { - message.info(`[${getFileNameByPath(workspaceRootDir)}]:Your API is refresh`); + message.info(`[${getFileNameByPath(workspaceRootDir)}]: Your API is updated`); } errorArr.forEach(([, error]) => { throw error; diff --git a/packages/vscode-extension/src/commands/setup.ts b/packages/vscode-extension/src/commands/setup.ts index a7243b0..d13dee5 100644 --- a/packages/vscode-extension/src/commands/setup.ts +++ b/packages/vscode-extension/src/commands/setup.ts @@ -1,10 +1,10 @@ import autocomplete from '@/components/autocomplete'; +import { registerEvent } from '@/components/event'; import { outputChannel } from '@/components/message'; import readConfig from '@/functions/readConfig'; +import { getWorkspacePaths } from '@/utils/vscode'; import * as vscode from 'vscode'; import showStatusBarIcon from './showStatusBarIcon'; -import { getWorkspacePaths } from '@/utils/vscode'; -import { registerEvent } from '@/components/event'; export default { commandId: 'alova.setup', diff --git a/packages/vscode-extension/src/functions/getWormhole.ts b/packages/vscode-extension/src/functions/getWormhole.ts index 84f8dd2..dd07be4 100644 --- a/packages/vscode-extension/src/functions/getWormhole.ts +++ b/packages/vscode-extension/src/functions/getWormhole.ts @@ -1,12 +1,12 @@ -import path from 'node:path'; -import importFresh from 'import-fresh'; -import { getWorkspacePaths } from '@/utils/vscode'; import Error, { AlovaErrorConstructor } from '@/components/error'; -import { enable, disable, BAR_STATE } from '@/components/statusBar'; -import { TEMPLATE_DATA } from '@/helper/config'; -import { existsSync } from 'node:fs'; +import { BAR_STATE, disable, enable } from '@/components/statusBar'; import { removeConfiguration } from '@/helper/autoUpdate'; +import { TEMPLATE_DATA } from '@/helper/config'; +import { getWorkspacePaths } from '@/utils/vscode'; import { globSync } from 'glob'; +import importFresh from 'import-fresh'; +import { existsSync } from 'node:fs'; +import path from 'node:path'; type Wormhole = typeof import('@alova/wormhole'); export const getWormhole = () => { @@ -28,7 +28,7 @@ export const getWormhole = () => { break; } } - } catch (error) {} + } catch {} } if (wormhole && BAR_STATE.value !== 'loading') { enable(); diff --git a/packages/vscode-extension/test/config.spec.ts b/packages/vscode-extension/test/config.spec.ts new file mode 100644 index 0000000..51ace4e --- /dev/null +++ b/packages/vscode-extension/test/config.spec.ts @@ -0,0 +1,45 @@ +import * as wormhole from '@alova/wormhole'; +import * as assert from 'assert'; +import sinon from 'sinon'; +import * as vscode from 'vscode'; + +suite('alova.create.config command', function () { + this.timeout(1000000); // 设置超时时间,避免 VSCode 启动超时 + vscode.window.showInformationMessage('Start all tests.'); + + let mockCreateConfig: sinon.SinonStub; + this.beforeEach(() => { + // 创建 spy 和 stub + mockCreateConfig = sinon.stub(wormhole, 'createConfig'); + }); + + this.afterEach(() => { + // 恢复所有 stub + sinon.restore(); + }); + + test('should call generateConfig with workspace paths', async () => { + // await new Promise(resolve => { + // setTimeout(resolve, 10000); + // }); + // 模拟 getWorkspacePaths 返回的路径 + // const mockPaths = ['/path/to/project']; + mockCreateConfig.returns(Promise.resolve(undefined)); + + // 执行命令 + await vscode.commands.executeCommand('alova.create.config'); + + // 验证 generateConfig 是否被正确调用 + assert.ok(mockCreateConfig.calledOnce); + }); + + // test('should handle empty workspace paths gracefully', async () => { + // // 模拟 getWorkspacePaths 返回空数组 + // mockReadConfig.returns([]); + + // await vscode.commands.executeCommand('alova.create.config'); + + // assert(mockReadConfig.calledOnce, 'getWorkspacePaths should be called once'); + // assert(mockCreateConfig.calledOnceWith([]), 'generateConfig should be called with an empty array'); + // }); +}); diff --git a/packages/vscode-extension/tsconfig.json b/packages/vscode-extension/tsconfig.json index dd46f09..c762b6b 100644 --- a/packages/vscode-extension/tsconfig.json +++ b/packages/vscode-extension/tsconfig.json @@ -14,6 +14,5 @@ "#/*": ["./*"] } }, - "exclude": ["design/**", "./node_modules", "test/**"], - "include": ["src/**/*.ts", "*.*js", "*.*ts", "scripts/**.*", "typings/**/*.d.ts"] + "include": ["src/**/*.ts", "test/**/*.ts", "typings/**/*.d.ts"] } diff --git a/packages/wormhole/README.md b/packages/wormhole/README.md new file mode 100644 index 0000000..bf453b7 --- /dev/null +++ b/packages/wormhole/README.md @@ -0,0 +1,49 @@ +# More modern openAPI generating solution for alova.js + +

+ +

+ +

Workflow-Streamlined next-generation request tools.
Extremely improve your API using efficiency and save brainpower Just one step

+ +--- + +## Usage + +This is a more modern openAPI generating solution for alova.js. + +Please to [@alova/wormhole documentation](https://alova.js.org/api/wormhole) for more details. + +## Join the community + +- [Follow us on X to get the latest updates](https://x.com/alovajs) + +- [Join the Discord](https://discord.gg/S47QGJgkVb) + +- [Join the WeChat group](https://alova.js.org/img/wechat_qrcode.jpg) + +## We need your support + +If you like alova, we are very grateful for giving us a star in the upper right corner, which is a recognition and encouragement for our work. + +## Welcome to contribute + +We are honored to receive active participation from developers around the world in Issues and Discussions. + +We hope to make alova a common project for everyone who is willing to participate, rather than the alova team. We encourage everyone to become a contributor to the alova community with an open and inclusive attitude. Even if you are a junior developer, as long as your ideas meet the development guidelines of alova, please participate generously. + +Effective contributions will win you a certain reputation in the Alova community. Before contributing, please be sure to read the [Contribution Guide](https://github.com/alovajs/alova/blob/main/CONTRIBUTING.md) in detail to ensure your contribution is effective. + +## Changelog + +[Link](https://github.com/alovajs/alova/releases) + +## Contributors + + + + + +## LICENSE + +[MIT](https://en.wikipedia.org/wiki/MIT_License) diff --git a/packages/wormhole/package.json b/packages/wormhole/package.json index 0d4e492..7db3b7b 100644 --- a/packages/wormhole/package.json +++ b/packages/wormhole/package.json @@ -6,11 +6,11 @@ "main": "./dist/index.js", "types": "./typings/index.d.ts", "bin": { - "alova": "./dist/bin/cli.js" + "alova": "dist/bin/cli.js" }, "scripts": { "build": "npm run build:ts && npm run build:dts && npm run build:copy", - "build:copy": "tsx ./scripts/build-copy.ts", + "build:copy": "ncp ./src/templates ./dist/templates", "build:ts": "tsc --build tsconfig.build.json && tsc-alias -p tsconfig.build.json", "build:dts": "dts-bundle-generator -o typings/index.d.ts src/index.ts --no-check --no-banner --project tsconfig.build.json" }, @@ -32,7 +32,7 @@ "license": "MIT", "repository": { "type": "git", - "url": "https://github.com/alovajs/devtools.git" + "url": "git+https://github.com/alovajs/devtools.git" }, "bugs": { "url": "https://github.com/alovajs/devtools/issues" @@ -41,6 +41,9 @@ "dist", "typings" ], + "publishConfig": { + "access": "public" + }, "dependencies": { "alova": "^3.1.0", "commander": "^12.1.0", @@ -51,7 +54,7 @@ "js-yaml": "^4.1.0", "lodash": "^4.17.21", "openapi-types": "^12.1.3", - "ora": "^8.1.0", + "ora": "^5.4.1", "swagger2openapi": "^7.0.8" }, "devDependencies": { diff --git a/packages/wormhole/scripts/build-copy.ts b/packages/wormhole/scripts/build-copy.ts deleted file mode 100644 index a0c711d..0000000 --- a/packages/wormhole/scripts/build-copy.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { copy } from 'fs-extra'; -import { resolve } from 'node:path'; - -copy(resolve(__dirname, '../src/templates'), resolve(__dirname, '../dist/templates')); diff --git a/packages/wormhole/src/bin/actions.ts b/packages/wormhole/src/bin/actions.ts index 1d97f55..f88cac3 100644 --- a/packages/wormhole/src/bin/actions.ts +++ b/packages/wormhole/src/bin/actions.ts @@ -1,10 +1,8 @@ import { createConfig, generate, readConfig, resolveWorkspaces } from '@/index'; import { TemplateType } from '@/interface.type'; -import { loadEsmModule } from '@/utils'; +import ora from 'ora'; -const getOra = () => loadEsmModule('ora'); export const actionInit = async ({ type, path: projectPath }: { type?: TemplateType; path?: string }) => { - const ora = (await getOra()).default; const spinner = ora('Initializing configuration file...').start(); await createConfig({ type, projectPath }); spinner.succeed('alova configuration file is initialized!'); @@ -23,7 +21,6 @@ export const actionGen = async ({ if (workspace) { workspacePaths = await resolveWorkspaces(projectPath); } - const ora = (await getOra()).default; for (const dir of workspacePaths) { const spinner = ora(`Generating...`).start(); const config = await readConfig(dir); diff --git a/packages/wormhole/src/functions/alovaJson.ts b/packages/wormhole/src/functions/alovaJson.ts index 59df5bd..6016d66 100644 --- a/packages/wormhole/src/functions/alovaJson.ts +++ b/packages/wormhole/src/functions/alovaJson.ts @@ -29,7 +29,7 @@ export const readAlovaJson = async (originPath: string, name = 'api.json') => { let jsonData = {} as TemplateData; try { jsonData = JSON.parse(data); - } catch (error) { + } catch { jsonData = DEFAULT_CONFIG.templateData.get(originPath) ?? jsonData; } return jsonData; diff --git a/packages/wormhole/src/functions/getOpenApiData.ts b/packages/wormhole/src/functions/getOpenApiData.ts index 632e45c..a9f5ebc 100644 --- a/packages/wormhole/src/functions/getOpenApiData.ts +++ b/packages/wormhole/src/functions/getOpenApiData.ts @@ -87,7 +87,7 @@ export default async function ( if (isSwagger2(data)) { data = (await swagger2openapi.convertObj(data, { warnOnly: true })).openapi as OpenAPIV3_1.Document; } - } catch (error) { + } catch { throw new DEFAULT_CONFIG.Error(`Cannot read file from ${url}`); } if (!data) { diff --git a/packages/wormhole/src/functions/openApi2Data.ts b/packages/wormhole/src/functions/openApi2Data.ts index 18cfb8f..b7ea53e 100644 --- a/packages/wormhole/src/functions/openApi2Data.ts +++ b/packages/wormhole/src/functions/openApi2Data.ts @@ -50,6 +50,7 @@ export interface TemplateData extends Omit { pathsArr: Path[]; schemas?: string[]; pathApis: PathApis[]; + globalHost: string; global: string; alovaVersion: AlovaVersion; commentText: string; @@ -297,7 +298,7 @@ export const transformPathObj = async ( try { newApiDescriptor = handleApi(apiDescriptor); handleApiDone = true; - } catch (error) { + } catch { handleApiDone = false; } if (!handleApiDone) { @@ -358,6 +359,7 @@ export default async function openApi2Data( schemas: [], alovaVersion: 'v2', global: config.global ?? 'Apis', + globalHost: config.globalHost ?? 'globalThis', useImportType: config?.useImportType ?? false, type: 'module' }; diff --git a/packages/wormhole/src/interface.type.ts b/packages/wormhole/src/interface.type.ts index ef3d54c..855a1b5 100644 --- a/packages/wormhole/src/interface.type.ts +++ b/packages/wormhole/src/interface.type.ts @@ -49,6 +49,8 @@ export type GeneratorConfig = { version?: number; // 多项目使用global字段 global?: string; + // global挂载的父级对象,默认为globalThis + globalHost?: string; // 是否使用import来导入类型,默认false // 开启此选项后,生成的apiDefinitions.ts文件将使用import语法来导入类型,而不是/// useImportType?: boolean; diff --git a/packages/wormhole/src/modules/Configuration.ts b/packages/wormhole/src/modules/Configuration.ts index fc8cec3..61757fa 100644 --- a/packages/wormhole/src/modules/Configuration.ts +++ b/packages/wormhole/src/modules/Configuration.ts @@ -33,8 +33,9 @@ export default class Configuration { if (!item.output) { throw new DEFAULT_CONFIG.Error('Field output is required in `config.generator`'); } - if (!isEmpty(item.global) && !isValidJSIdentifier(item.global)) { - throw new DEFAULT_CONFIG.Error(`\`${item.global}\` does not match variable specification`); + const { global } = item; + if (!isEmpty(global) && !isValidJSIdentifier(global)) { + throw new DEFAULT_CONFIG.Error(`\`${global}\` does not match variable specification`); } if (arr.length < 2) { return; @@ -43,13 +44,13 @@ export default class Configuration { throw new DEFAULT_CONFIG.Error(`output \`${item.output}\` is repated`); } outputSet.add(path.join(item.output)); - if (!item.global) { + if (!global) { throw new DEFAULT_CONFIG.Error('Field global is required in `config.generator`'); } - if (globalKeySet.has(item.global)) { - throw new DEFAULT_CONFIG.Error(`global \`${item.global}\` is repated`); + if (globalKeySet.has(global)) { + throw new DEFAULT_CONFIG.Error(`global \`${global}\` is repated`); } - globalKeySet.add(item.global); + globalKeySet.add(global); }); if (typeof this.config.autoUpdate === 'object') { const { interval } = this.config.autoUpdate; diff --git a/packages/wormhole/src/readConfig.ts b/packages/wormhole/src/readConfig.ts index bda3d45..525d506 100644 --- a/packages/wormhole/src/readConfig.ts +++ b/packages/wormhole/src/readConfig.ts @@ -13,7 +13,7 @@ export const readConfig = async (projectPath = process.cwd()) => { if (!configFile) { throw new DEFAULT_CONFIG.Error(`Cannot found config file from path ${projectPath}`); } - const configTmpFileName = `alova_tmp_${Date.now()}.js`; + const configTmpFileName = `alova_tmp_${Date.now()}.cjs`; const outfile = path.join(projectPath, configTmpFileName); await esbuild.build({ entryPoints: [configFile], diff --git a/packages/wormhole/src/templates/commonjs/createApis.handlebars b/packages/wormhole/src/templates/commonjs/createApis.handlebars index 8f51b41..46c58bf 100644 --- a/packages/wormhole/src/templates/commonjs/createApis.handlebars +++ b/packages/wormhole/src/templates/commonjs/createApis.handlebars @@ -66,7 +66,7 @@ const createApis = (alovaInstance, configMap) => { } ); // define global variable `Apis` - globalThis.{{{global}}} = Apis; + ({{{globalHost}}}).{{{global}}} = Apis; return Apis; } /** diff --git a/packages/wormhole/src/templates/commonjs/v3-createApis.handlebars b/packages/wormhole/src/templates/commonjs/v3-createApis.handlebars index 63df902..bb23b99 100644 --- a/packages/wormhole/src/templates/commonjs/v3-createApis.handlebars +++ b/packages/wormhole/src/templates/commonjs/v3-createApis.handlebars @@ -69,7 +69,7 @@ const createApis = (alovaInstance, configMap) =>{ } ); // define global variable `Apis` - globalThis.{{{global}}} = Apis; + ({{{globalHost}}}).{{{global}}} = Apis; return Apis; } /** diff --git a/packages/wormhole/src/templates/module/createApis.handlebars b/packages/wormhole/src/templates/module/createApis.handlebars index 5fd67f8..e548443 100644 --- a/packages/wormhole/src/templates/module/createApis.handlebars +++ b/packages/wormhole/src/templates/module/createApis.handlebars @@ -66,7 +66,7 @@ export const createApis = (alovaInstance, configMap) => { } ); // define global variable `Apis` - globalThis.{{{global}}} = Apis; + ({{{globalHost}}}).{{{global}}} = Apis; return Apis; } diff --git a/packages/wormhole/src/templates/module/v3-createApis.handlebars b/packages/wormhole/src/templates/module/v3-createApis.handlebars index d24d400..0a6d38f 100644 --- a/packages/wormhole/src/templates/module/v3-createApis.handlebars +++ b/packages/wormhole/src/templates/module/v3-createApis.handlebars @@ -69,7 +69,7 @@ export const createApis = (alovaInstance, configMap) => { } ); // define global variable `Apis` - globalThis.{{{global}}} = Apis; + ({{{globalHost}}}).{{{global}}} = Apis; return Apis; } /** diff --git a/packages/wormhole/src/templates/typescript/createApis.handlebars b/packages/wormhole/src/templates/typescript/createApis.handlebars index 964e7a3..b794c8d 100644 --- a/packages/wormhole/src/templates/typescript/createApis.handlebars +++ b/packages/wormhole/src/templates/typescript/createApis.handlebars @@ -60,7 +60,7 @@ export const createApis = (alovaInstance: Alova, config } ); // define global variable `Apis` - (globalThis as any).{{{global}}} = Apis; + (({{{globalHost}}}) as any).{{{global}}} = Apis; return Apis; } type MethodConfig = typeof import('./index')['alovaInstance'] extends Alova ? import('alova').AlovaMethodCreateConfig : never; diff --git a/packages/wormhole/src/templates/typescript/v3-createApis.handlebars b/packages/wormhole/src/templates/typescript/v3-createApis.handlebars index 207d5b1..8dd6607 100644 --- a/packages/wormhole/src/templates/typescript/v3-createApis.handlebars +++ b/packages/wormhole/src/templates/typescript/v3-createApis.handlebars @@ -65,7 +65,7 @@ export const createApis = (alovaInstance: Alova, configMap: any) } ); // define global variable `Apis` - (globalThis as any).{{{global}}} = Apis; + (({{{globalHost}}}) as any).{{{global}}} = Apis; return Apis; } type MethodConfig = AlovaMethodCreateConfig ? AG : any, any, T>; diff --git a/packages/wormhole/src/utils/index.ts b/packages/wormhole/src/utils/index.ts index 5d850c9..5523627 100644 --- a/packages/wormhole/src/utils/index.ts +++ b/packages/wormhole/src/utils/index.ts @@ -1,3 +1,4 @@ +import { getGlobalConfig } from '@/config'; import { createAlova } from 'alova'; import adapterFetch from 'alova/fetch'; import handlebars, { HelperOptions } from 'handlebars'; @@ -8,7 +9,6 @@ import * as prettierBabel from 'prettier/plugins/babel'; import * as prettierEsTree from 'prettier/plugins/estree'; import * as prettierTs from 'prettier/plugins/typescript'; import * as prettier from 'prettier/standalone'; -import { getGlobalConfig } from '../config'; const DEFAULT_CONFIG = getGlobalConfig(); export const prettierConfig: PrettierConfig = { @@ -74,7 +74,7 @@ export async function readAndRenderTemplate(templatePath: string, view: any) { let data = ''; try { data = await fs.readFile(path.resolve(DEFAULT_CONFIG.templatePath, `${templatePath}.handlebars`), 'utf-8'); - } catch (error) { + } catch { data = (await import(`../templates/${templatePath}.handlebars`)).default; } return handlebars.compile(data)(view); @@ -154,8 +154,3 @@ export const resolveConfigFile = async (projectPath: string) => { } return null; }; - -// 加载ESM 模块 -export function loadEsmModule(modulePath: string | URL): Promise { - return new Function('modulePath', `return import(modulePath);`)(modulePath) as Promise; -} diff --git a/packages/wormhole/test/config.spec.ts b/packages/wormhole/test/config.spec.ts index a291781..f2f1642 100644 --- a/packages/wormhole/test/config.spec.ts +++ b/packages/wormhole/test/config.spec.ts @@ -40,7 +40,7 @@ export default { expectedConfig: { generator: [ { - input: 'http://localhost:3000/@alova/devtools', + input: 'http://localhost:3000/alova-devtools', output: 'src/api', type: 'ts', version: 3 @@ -88,7 +88,7 @@ export default { expectedConfig: { generator: [ { - input: 'http://localhost:3000/@alova/devtools', + input: 'http://localhost:3000/alova-devtools', output: 'src/api', type: 'module', version: 3 @@ -112,7 +112,7 @@ module.exports = { expectedConfig: { generator: [ { - input: 'http://localhost:3000/@alova/devtools', + input: 'http://localhost:3000/alova-devtools', output: 'src/api', type: 'commonjs', version: 3 diff --git a/packages/wormhole/test/generate.spec.ts b/packages/wormhole/test/generate.spec.ts index 2ea835d..9ef0e8b 100644 --- a/packages/wormhole/test/generate.spec.ts +++ b/packages/wormhole/test/generate.spec.ts @@ -561,6 +561,48 @@ describe('generate API', () => { expect(fileContentEsm2).toMatch('globalThis.ApisEsm2 = Apis;'); }); + test('should set the right globalHost variable name', async () => { + const outputDir = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir, + type: 'module', + globalHost: 'globalHost' + } + ] + }); + const fileContentEsm = await fs.readFile(resolve(outputDir, 'createApis.js'), 'utf-8'); + expect(fileContentEsm).toMatch('globalHost.Apis = Apis;'); + + const outputDir3 = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); + const outputDir4 = resolve(__dirname, `./mock_output/openapi_301${getSalt()}`); + const results = await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir3, + type: 'commonjs', + global: 'ApisCjs', + globalHost: 'parentCjs' + }, + { + input: resolve(__dirname, './openapis/openapi_301.json'), + output: outputDir4, + type: 'ts', + global: 'ApisEsm', + globalHost: 'globalThis ? globalThis : parentTs' + } + ] + }); + expect(results).toStrictEqual([true, true]); + const fileContentCjs = await fs.readFile(resolve(outputDir3, 'createApis.js'), 'utf-8'); + expect(fileContentCjs).toMatch('parentCjs.ApisCjs = Apis;'); + const fileContentEsm2 = await fs.readFile(resolve(outputDir4, 'createApis.ts'), 'utf-8'); + expect(fileContentEsm2).toMatch('((globalThis ? globalThis : parentTs) as any).ApisEsm = Apis;'); + }); + test('should preprocess non-variable-specification characters', async () => { const outputDir = resolve(__dirname, `./mock_output/non_variable_specification_openapi${getSalt()}`); await generate({ diff --git a/packages/wormhole/test/output/openapi_300/index.ts b/packages/wormhole/test/output/openapi_300/index.ts index 277abd6..ac704f2 100644 --- a/packages/wormhole/test/output/openapi_300/index.ts +++ b/packages/wormhole/test/output/openapi_300/index.ts @@ -1,3 +1,4 @@ +/* eslint-disable */ import { createAlova } from 'alova'; import GlobalFetch from 'alova/GlobalFetch'; import { createApis, withConfigType } from './createApis'; diff --git a/packages/wormhole/tsconfig.json b/packages/wormhole/tsconfig.json index 3b429d9..fd2813e 100644 --- a/packages/wormhole/tsconfig.json +++ b/packages/wormhole/tsconfig.json @@ -4,6 +4,8 @@ "baseUrl": ".", "module": "CommonJS", "resolveJsonModule": false, + "esModuleInterop": true, + "types": ["vitest/globals"], "paths": { "~/*": ["./typings/*"], "@/*": ["./src/*"], diff --git a/packages/wormhole/typings/index.d.ts b/packages/wormhole/typings/index.d.ts index e7b0d9f..e785094 100644 --- a/packages/wormhole/typings/index.d.ts +++ b/packages/wormhole/typings/index.d.ts @@ -25,6 +25,7 @@ export type GeneratorConfig = { type?: ConfigType; version?: number; global?: string; + globalHost?: string; useImportType?: boolean; defaultRequire?: boolean; handleApi?: HandleApi; @@ -81,6 +82,7 @@ export interface TemplateData extends Omit { pathsArr: Path[]; schemas?: string[]; pathApis: PathApis[]; + globalHost: string; global: string; alovaVersion: AlovaVersion; commentText: string; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0cc3f2d..bac1e2b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,10 +7,17 @@ settings: importers: .: + dependencies: + '@eslint/eslintrc': + specifier: ^3.1.0 + version: 3.1.0 + globals: + specifier: ^15.12.0 + version: 15.12.0 devDependencies: '@commitlint/cli': specifier: ^19.3.0 - version: 19.5.0(@types/node@18.19.59)(typescript@5.6.3) + version: 19.5.0(@types/node@18.19.64)(typescript@5.6.3) '@commitlint/config-conventional': specifier: ^19.2.2 version: 19.5.0 @@ -19,10 +26,10 @@ importers: version: 4.0.9 '@types/lodash': specifier: ^4.17.5 - version: 4.17.12 + version: 4.17.13 '@types/node': specifier: ^18.19.0 - version: 18.19.59 + version: 18.19.64 '@types/rimraf': specifier: ^4.0.5 version: 4.0.5 @@ -30,41 +37,47 @@ importers: specifier: ^5.0.4 version: 5.0.4 '@typescript-eslint/eslint-plugin': - specifier: ^7.13.0 - version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3) + specifier: ^8.13.0 + version: 8.13.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3) '@typescript-eslint/parser': - specifier: ^7.13.0 - version: 7.18.0(eslint@8.57.1)(typescript@5.6.3) + specifier: ^8.13.0 + version: 8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3) + changeset: + specifier: ^0.2.6 + version: 0.2.6 commitizen: specifier: ^4.3.0 - version: 4.3.1(@types/node@18.19.59)(typescript@5.6.3) + version: 4.3.1(@types/node@18.19.64)(typescript@5.6.3) cz-conventional-changelog: specifier: ^3.3.0 - version: 3.3.0(@types/node@18.19.59)(typescript@5.6.3) + version: 3.3.0(@types/node@18.19.64)(typescript@5.6.3) dts-bundle-generator: specifier: ^9.5.1 version: 9.5.1 eslint: - specifier: ^8.57.0 - version: 8.57.1 + specifier: ^9.14.0 + version: 9.14.0(jiti@1.21.6) eslint-config-airbnb: specifier: ^19.0.4 - version: 19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.1(eslint@8.57.1))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.1))(eslint-plugin-react@7.37.2(eslint@8.57.1))(eslint@8.57.1) + version: 19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.14.0(jiti@1.21.6)))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.14.0(jiti@1.21.6)))(eslint-plugin-react-hooks@4.6.2(eslint@9.14.0(jiti@1.21.6)))(eslint-plugin-react@7.37.2(eslint@9.14.0(jiti@1.21.6)))(eslint@9.14.0(jiti@1.21.6)) eslint-config-airbnb-typescript: specifier: ^18.0.0 - version: 18.0.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1) + version: 18.0.0(@typescript-eslint/eslint-plugin@8.13.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.14.0(jiti@1.21.6)))(eslint@9.14.0(jiti@1.21.6)) eslint-config-prettier: specifier: ^9.1.0 - version: 9.1.0(eslint@8.57.1) + version: 9.1.0(eslint@9.14.0(jiti@1.21.6)) eslint-plugin-prettier: - specifier: ^5.1.3 - version: 5.2.1(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.3.3) + specifier: ^5.2.1 + version: 5.2.1(eslint-config-prettier@9.1.0(eslint@9.14.0(jiti@1.21.6)))(eslint@9.14.0(jiti@1.21.6))(prettier@3.3.3) husky: specifier: ^9.0.11 version: 9.1.6 lint-staged: specifier: ^15.2.2 version: 15.2.10 + ncp: + specifier: ^2.0.0 + version: 2.0.0 npm-run-all: specifier: ^4.1.5 version: 4.1.5 @@ -82,10 +95,10 @@ importers: version: 6.0.1 tslib: specifier: ^2.7.0 - version: 2.8.0 + version: 2.8.1 tsx: specifier: ^4.15.8 - version: 4.19.1 + version: 4.19.2 type-fest: specifier: ^4.20.0 version: 4.26.1 @@ -94,12 +107,12 @@ importers: version: 5.6.3 vitest: specifier: ^2.0.5 - version: 2.1.3(@types/node@18.19.59) + version: 2.1.4(@types/node@18.19.64) packages/vscode-extension: dependencies: '@alova/wormhole': - specifier: workspace:^ + specifier: workspace:* version: link:../wormhole glob: specifier: ^11.0.0 @@ -108,9 +121,15 @@ importers: specifier: ^3.3.0 version: 3.3.0 devDependencies: + '@types/mocha': + specifier: ^10.0.9 + version: 10.0.9 + '@types/sinon': + specifier: ^17.0.3 + version: 17.0.3 '@types/vscode': specifier: ^1.89.0 - version: 1.94.0 + version: 1.95.0 '@vscode/test-cli': specifier: ^0.0.9 version: 0.0.9 @@ -126,12 +145,15 @@ importers: esbuild-plugin-alias: specifier: ^0.2.1 version: 0.2.1 + sinon: + specifier: ^19.0.2 + version: 19.0.2 packages/wormhole: dependencies: alova: specifier: ^3.1.0 - version: 3.1.1 + version: 3.2.1 commander: specifier: ^12.1.0 version: 12.1.0 @@ -157,8 +179,8 @@ importers: specifier: ^12.1.3 version: 12.1.3 ora: - specifier: ^8.1.0 - version: 8.1.0 + specifier: ^5.4.1 + version: 5.4.1 swagger2openapi: specifier: ^7.0.8 version: 7.0.8 @@ -262,18 +284,18 @@ importers: test/api-v3-ts-test: dependencies: '@alova/adapter-xhr': - specifier: 2.0.0-beta.8 - version: 2.0.0-beta.8(alova@3.0.5) + specifier: 2.0.10 + version: 2.0.10(alova@3.2.2) '@alova/mock': - specifier: ^2.0.4 - version: 2.0.8(alova@3.0.5) + specifier: ^2.0.9 + version: 2.0.9(alova@3.2.2) alova: - specifier: 3.0.5 - version: 3.0.5 + specifier: 3.2.2 + version: 3.2.2 devDependencies: '@alova/wormhole': - specifier: workspace:^ - version: link:../../packages/wormhole + specifier: ^1.0.0 + version: 1.0.0 typescript: specifier: ^5.4.5 version: 5.6.3 @@ -285,19 +307,28 @@ packages: peerDependencies: alova: ^3.0.0-beta.10 + '@alova/adapter-xhr@2.0.10': + resolution: {integrity: sha512-8nu+YcNJo0rq7zUB22cl+SDnWzKx/METrzjrDoUMspeZ8PI2ThDkCiwk96KfmN5EGMHIVPuhcbvIwGyXlErH0A==} + peerDependencies: + alova: ^3.0.20 + '@alova/mock@1.5.2': resolution: {integrity: sha512-qEkOgTgzbltkTG/3bn1cvekP6AlPuqpv/N3s5dpu15neMGk24p1qnruz+aeNtg4rMU92zNJ+FtGZF4QRd/vxog==} - '@alova/mock@2.0.8': - resolution: {integrity: sha512-sqN//lQY9S7uK1tolM1EQEF+jYbCqttGObpRfgQvLuL67sJo2FNP/pD3wLFxCKyn/9pceTJCbpnZiuOGLr+XFg==} + '@alova/mock@2.0.9': + resolution: {integrity: sha512-mjGwIcTZXkjGTkvI7FtSArIov/BF/G0lxz29ukOWHcFyCRsyWLrgY/68fv8Vbu6npAF9RwNXsgiB4WVW0NbXmA==} peerDependencies: alova: ^3.0.20 '@alova/shared@1.0.0-beta.7': resolution: {integrity: sha512-tnELbw8fsvUUXDwgbIiWLg2oJuRaxwTvf54+f3JnOgCwSLa47dcO7aKvi0FGV26F8enxgTop7CUwP8LlHCtM7Q==} - '@alova/shared@1.0.7': - resolution: {integrity: sha512-yBCNbt+E2gOtNfx9dLXDcmjudnWrwlHJnMKFD6CLKe6KTc6G0QUFeIS/1Kn4+iBalD38nY8ckCMW98+hmjr7Bg==} + '@alova/shared@1.1.0': + resolution: {integrity: sha512-sCX5cVKYGrYJ8hGZ9fxqyKAsNGXd2frB4/UG3SKTXqCgs4OyROz1SYhh16iaKT1NaKrQ3444bS2BS/7kTwFpVA==} + + '@alova/wormhole@1.0.0': + resolution: {integrity: sha512-5mROBgzhWtb1RH/Psc+KqT4CeVYMErVAPooa4p8eF6Q0R4JPSJPsu5s+hZm3ynYErVO16NdvroqIO9H3zkEXfQ==} + hasBin: true '@azure/abort-controller@2.1.2': resolution: {integrity: sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==} @@ -343,8 +374,8 @@ packages: resolution: {integrity: sha512-gVPW8YLz92ZeCibQH2QUw96odJoiM3k/ZPH3f2HxptozmH6+OnyyvKXo/Egg39HAM230akarQKHf0W74UHlh0Q==} engines: {node: '>=16'} - '@babel/code-frame@7.25.9': - resolution: {integrity: sha512-z88xeGxnzehn2sqZ8UdGQEvYErF1odv2CftxInpSYJt6uHuPe9YjahKZITGs3l5LeI9d2ROG+obuDAoSlqbNfQ==} + '@babel/code-frame@7.26.2': + resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} '@babel/helper-string-parser@7.25.9': @@ -355,17 +386,13 @@ packages: resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} - '@babel/highlight@7.25.9': - resolution: {integrity: sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.25.9': - resolution: {integrity: sha512-aI3jjAAO1fh7vY/pBGsn1i9LDbRP43+asrRlkPuTXW5yHXtd1NgTEMudbBoDDxrf1daEEfPJqR+JBMakzrR4Dg==} + '@babel/parser@7.26.2': + resolution: {integrity: sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/types@7.25.9': - resolution: {integrity: sha512-OwS2CM5KocvQ/k7dFJa8i5bNGJP0hXWfVCfDkqRFP1IreH1JDC7wG6eCYCi0+McbfT8OR/kNqsI0UU0xP9H6PQ==} + '@babel/types@7.26.0': + resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} engines: {node: '>=6.9.0'} '@bcoe/v8-coverage@0.2.3': @@ -866,39 +893,62 @@ packages: cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.4.0': - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + '@eslint-community/eslint-utils@4.4.1': + resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.11.1': - resolution: {integrity: sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==} + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/eslintrc@2.1.4': - resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/config-array@0.18.0': + resolution: {integrity: sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@8.57.1': - resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/core@0.7.0': + resolution: {integrity: sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.1.0': + resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.14.0': + resolution: {integrity: sha512-pFoEtFWCPyDOl+C6Ift+wC7Ro89otjigCf5vcuWqWgqNSQbRrpjSvdeE6ofLz4dHmyxD5f7gIdGT4+p36L6Twg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.4': + resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.2.2': + resolution: {integrity: sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@exodus/schemasafe@1.3.0': resolution: {integrity: sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==} - '@humanwhocodes/config-array@0.13.0': - resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} - engines: {node: '>=10.10.0'} - deprecated: Use @eslint/config-array instead + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.6': + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + engines: {node: '>=18.18.0'} '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - '@humanwhocodes/object-schema@2.0.3': - resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} - deprecated: Use @eslint/object-schema instead + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + + '@humanwhocodes/retry@0.4.1': + resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==} + engines: {node: '>=18.18'} '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} @@ -960,98 +1010,120 @@ packages: resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@rollup/rollup-android-arm-eabi@4.24.0': - resolution: {integrity: sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==} + '@rollup/rollup-android-arm-eabi@4.24.4': + resolution: {integrity: sha512-jfUJrFct/hTA0XDM5p/htWKoNNTbDLY0KRwEt6pyOA6k2fmk0WVwl65PdUdJZgzGEHWx+49LilkcSaumQRyNQw==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.24.0': - resolution: {integrity: sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==} + '@rollup/rollup-android-arm64@4.24.4': + resolution: {integrity: sha512-j4nrEO6nHU1nZUuCfRKoCcvh7PIywQPUCBa2UsootTHvTHIoIu2BzueInGJhhvQO/2FTRdNYpf63xsgEqH9IhA==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.24.0': - resolution: {integrity: sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==} + '@rollup/rollup-darwin-arm64@4.24.4': + resolution: {integrity: sha512-GmU/QgGtBTeraKyldC7cDVVvAJEOr3dFLKneez/n7BvX57UdhOqDsVwzU7UOnYA7AAOt+Xb26lk79PldDHgMIQ==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.24.0': - resolution: {integrity: sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==} + '@rollup/rollup-darwin-x64@4.24.4': + resolution: {integrity: sha512-N6oDBiZCBKlwYcsEPXGDE4g9RoxZLK6vT98M8111cW7VsVJFpNEqvJeIPfsCzbf0XEakPslh72X0gnlMi4Ddgg==} cpu: [x64] os: [darwin] - '@rollup/rollup-linux-arm-gnueabihf@4.24.0': - resolution: {integrity: sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==} + '@rollup/rollup-freebsd-arm64@4.24.4': + resolution: {integrity: sha512-py5oNShCCjCyjWXCZNrRGRpjWsF0ic8f4ieBNra5buQz0O/U6mMXCpC1LvrHuhJsNPgRt36tSYMidGzZiJF6mw==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.24.4': + resolution: {integrity: sha512-L7VVVW9FCnTTp4i7KrmHeDsDvjB4++KOBENYtNYAiYl96jeBThFfhP6HVxL74v4SiZEVDH/1ILscR5U9S4ms4g==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.24.4': + resolution: {integrity: sha512-10ICosOwYChROdQoQo589N5idQIisxjaFE/PAnX2i0Zr84mY0k9zul1ArH0rnJ/fpgiqfu13TFZR5A5YJLOYZA==} cpu: [arm] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.24.0': - resolution: {integrity: sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==} + '@rollup/rollup-linux-arm-musleabihf@4.24.4': + resolution: {integrity: sha512-ySAfWs69LYC7QhRDZNKqNhz2UKN8LDfbKSMAEtoEI0jitwfAG2iZwVqGACJT+kfYvvz3/JgsLlcBP+WWoKCLcw==} cpu: [arm] os: [linux] libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.24.0': - resolution: {integrity: sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==} + '@rollup/rollup-linux-arm64-gnu@4.24.4': + resolution: {integrity: sha512-uHYJ0HNOI6pGEeZ/5mgm5arNVTI0nLlmrbdph+pGXpC9tFHFDQmDMOEqkmUObRfosJqpU8RliYoGz06qSdtcjg==} cpu: [arm64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.24.0': - resolution: {integrity: sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==} + '@rollup/rollup-linux-arm64-musl@4.24.4': + resolution: {integrity: sha512-38yiWLemQf7aLHDgTg85fh3hW9stJ0Muk7+s6tIkSUOMmi4Xbv5pH/5Bofnsb6spIwD5FJiR+jg71f0CH5OzoA==} cpu: [arm64] os: [linux] libc: [musl] - '@rollup/rollup-linux-powerpc64le-gnu@4.24.0': - resolution: {integrity: sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==} + '@rollup/rollup-linux-powerpc64le-gnu@4.24.4': + resolution: {integrity: sha512-q73XUPnkwt9ZNF2xRS4fvneSuaHw2BXuV5rI4cw0fWYVIWIBeDZX7c7FWhFQPNTnE24172K30I+dViWRVD9TwA==} cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-gnu@4.24.0': - resolution: {integrity: sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==} + '@rollup/rollup-linux-riscv64-gnu@4.24.4': + resolution: {integrity: sha512-Aie/TbmQi6UXokJqDZdmTJuZBCU3QBDA8oTKRGtd4ABi/nHgXICulfg1KI6n9/koDsiDbvHAiQO3YAUNa/7BCw==} cpu: [riscv64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-s390x-gnu@4.24.0': - resolution: {integrity: sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==} + '@rollup/rollup-linux-s390x-gnu@4.24.4': + resolution: {integrity: sha512-P8MPErVO/y8ohWSP9JY7lLQ8+YMHfTI4bAdtCi3pC2hTeqFJco2jYspzOzTUB8hwUWIIu1xwOrJE11nP+0JFAQ==} cpu: [s390x] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.24.0': - resolution: {integrity: sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==} + '@rollup/rollup-linux-x64-gnu@4.24.4': + resolution: {integrity: sha512-K03TljaaoPK5FOyNMZAAEmhlyO49LaE4qCsr0lYHUKyb6QacTNF9pnfPpXnFlFD3TXuFbFbz7tJ51FujUXkXYA==} cpu: [x64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.24.0': - resolution: {integrity: sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==} + '@rollup/rollup-linux-x64-musl@4.24.4': + resolution: {integrity: sha512-VJYl4xSl/wqG2D5xTYncVWW+26ICV4wubwN9Gs5NrqhJtayikwCXzPL8GDsLnaLU3WwhQ8W02IinYSFJfyo34Q==} cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-win32-arm64-msvc@4.24.0': - resolution: {integrity: sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==} + '@rollup/rollup-win32-arm64-msvc@4.24.4': + resolution: {integrity: sha512-ku2GvtPwQfCqoPFIJCqZ8o7bJcj+Y54cZSr43hHca6jLwAiCbZdBUOrqE6y29QFajNAzzpIOwsckaTFmN6/8TA==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.24.0': - resolution: {integrity: sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==} + '@rollup/rollup-win32-ia32-msvc@4.24.4': + resolution: {integrity: sha512-V3nCe+eTt/W6UYNr/wGvO1fLpHUrnlirlypZfKCT1fG6hWfqhPgQV/K/mRBXBpxc0eKLIF18pIOFVPh0mqHjlg==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.24.0': - resolution: {integrity: sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==} + '@rollup/rollup-win32-x64-msvc@4.24.4': + resolution: {integrity: sha512-LTw1Dfd0mBIEqUVCxbvTE/LLo+9ZxVC9k99v1v4ahg9Aak6FpqOfNu5kRkeTAn0wphoC4JU7No1/rL+bBCEwhg==} cpu: [x64] os: [win32] '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + '@sinonjs/commons@3.0.1': + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + + '@sinonjs/fake-timers@13.0.5': + resolution: {integrity: sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==} + + '@sinonjs/samsam@8.0.2': + resolution: {integrity: sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==} + + '@sinonjs/text-encoding@0.7.3': + resolution: {integrity: sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==} + '@types/conventional-commits-parser@5.0.0': resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==} @@ -1076,20 +1148,23 @@ packages: '@types/js-yaml@4.0.9': resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} '@types/jsonfile@6.1.4': resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} - '@types/lodash@4.17.12': - resolution: {integrity: sha512-sviUmCE8AYdaF/KIHLDJBQgeYzPBI0vf/17NaYehBJfYD1j6/L95Slh07NlyK2iNyBNaEkb3En2jRt+a8y3xZQ==} + '@types/lodash@4.17.13': + resolution: {integrity: sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==} '@types/mocha@10.0.9': resolution: {integrity: sha512-sicdRoWtYevwxjOHNMPTl3vSfJM6oyW8o1wXeI7uww6b6xHg8eBznQDNSGBCDJmsE8UMxP05JgZRtsKbTqt//Q==} - '@types/node@18.19.59': - resolution: {integrity: sha512-vizm2EqwV/7Zay+A6J3tGl9Lhr7CjZe2HmWS988sefiEmsyP9CeXEleho6i4hJk/8UtZAo0bWN4QPZZr83RxvQ==} + '@types/node@18.19.64': + resolution: {integrity: sha512-955mDqvO2vFf/oL7V3WiUtiz+BugyX8uVbaT2H8oj3+8dRyH2FLiNdowe7eNqRM7IOIZvzDH76EoAT+gwm6aIQ==} '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} @@ -1101,11 +1176,17 @@ packages: '@types/serialize-javascript@5.0.4': resolution: {integrity: sha512-Z2R7UKFuNWCP8eoa2o9e5rkD3hmWxx/1L0CYz0k2BZzGh0PhEVMp9kfGiqEml/0IglwNERXZ2hwNzIrSz/KHTA==} + '@types/sinon@17.0.3': + resolution: {integrity: sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==} + + '@types/sinonjs__fake-timers@8.1.5': + resolution: {integrity: sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==} + '@types/swagger2openapi@7.0.4': resolution: {integrity: sha512-ffMqzciTDihOKH4Q//9Ond1yb5JP1P5FC/aFPsLK4blea1Fwk2aYctiNCkAh5etDYFswFXS+5LV/vuGkf+PU6A==} - '@types/vscode@1.94.0': - resolution: {integrity: sha512-UyQOIUT0pb14XSqJskYnRwD2aG0QrPVefIfrW1djR+/J4KeFQ0i1+hjZoaAmeNf3Z2jleK+R2hv+EboG/m8ruw==} + '@types/vscode@1.95.0': + resolution: {integrity: sha512-0LBD8TEiNbet3NvWsmn59zLzOFu/txSlGxnv5yAFHCrhG9WvAnR3IvfHzMOs2aeWqgvNjq9pO99IUw8d3n+unw==} '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} @@ -1113,75 +1194,70 @@ packages: '@types/yargs@15.0.19': resolution: {integrity: sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA==} - '@typescript-eslint/eslint-plugin@7.18.0': - resolution: {integrity: sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/eslint-plugin@8.13.0': + resolution: {integrity: sha512-nQtBLiZYMUPkclSeC3id+x4uVd1SGtHuElTxL++SfP47jR0zfkZBJHc+gL4qPsgTuypz0k8Y2GheaDYn6Gy3rg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^7.0.0 - eslint: ^8.56.0 + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/parser@7.18.0': - resolution: {integrity: sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/parser@8.13.0': + resolution: {integrity: sha512-w0xp+xGg8u/nONcGw1UXAr6cjCPU1w0XVyBs6Zqaj5eLmxkKQAByTdV/uGgNN5tVvN/kKpoQlP2cL7R+ajZZIQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.56.0 + eslint: ^8.57.0 || ^9.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/scope-manager@7.18.0': - resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/scope-manager@8.13.0': + resolution: {integrity: sha512-XsGWww0odcUT0gJoBZ1DeulY1+jkaHUciUq4jKNv4cpInbvvrtDoyBH9rE/n2V29wQJPk8iCH1wipra9BhmiMA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@7.18.0': - resolution: {integrity: sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/type-utils@8.13.0': + resolution: {integrity: sha512-Rqnn6xXTR316fP4D2pohZenJnp+NwQ1mo7/JM+J1LWZENSLkJI8ID8QNtlvFeb0HnFSK94D6q0cnMX6SbE5/vA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.56.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/types@7.18.0': - resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/types@8.13.0': + resolution: {integrity: sha512-4cyFErJetFLckcThRUFdReWJjVsPCqyBlJTi6IDEpc1GWCIIZRFxVppjWLIMcQhNGhdWJJRYFHpHoDWvMlDzng==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@7.18.0': - resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/typescript-estree@8.13.0': + resolution: {integrity: sha512-v7SCIGmVsRK2Cy/LTLGN22uea6SaUIlpBcO/gnMGT/7zPtxp90bphcGf4fyrCQl3ZtiBKqVTG32hb668oIYy1g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/utils@7.18.0': - resolution: {integrity: sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/utils@8.13.0': + resolution: {integrity: sha512-A1EeYOND6Uv250nybnLZapeXpYMl8tkzYUxqmoKAWnI4sei3ihf2XdZVd+vVOmHGcp3t+P7yRrNsyyiXTvShFQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.56.0 + eslint: ^8.57.0 || ^9.0.0 - '@typescript-eslint/visitor-keys@7.18.0': - resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/visitor-keys@8.13.0': + resolution: {integrity: sha512-7N/+lztJqH4Mrf0lb10R/CbI1EaAMMGyF5y0oJvFoAhafwgiRA7TXyd8TFn8FC8k5y2dTsYogg238qavRGNnlw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@ungap/structured-clone@1.2.0': - resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + '@vitest/expect@2.1.4': + resolution: {integrity: sha512-DOETT0Oh1avie/D/o2sgMHGrzYUFFo3zqESB2Hn70z6QB1HrS2IQ9z5DfyTqU8sg4Bpu13zZe9V4+UTNQlUeQA==} - '@vitest/expect@2.1.3': - resolution: {integrity: sha512-SNBoPubeCJhZ48agjXruCI57DvxcsivVDdWz+SSsmjTT4QN/DfHk3zB/xKsJqMs26bLZ/pNRLnCf0j679i0uWQ==} - - '@vitest/mocker@2.1.3': - resolution: {integrity: sha512-eSpdY/eJDuOvuTA3ASzCjdithHa+GIF1L4PqtEELl6Qa3XafdMLBpBlZCIUCX2J+Q6sNmjmxtosAG62fK4BlqQ==} + '@vitest/mocker@2.1.4': + resolution: {integrity: sha512-Ky/O1Lc0QBbutJdW0rqLeFNbuLEyS+mIPiNdlVlp2/yhJ0SbyYqObS5IHdhferJud8MbbwMnexg4jordE5cCoQ==} peerDependencies: - '@vitest/spy': 2.1.3 - msw: ^2.3.5 + msw: ^2.4.9 vite: ^5.0.0 peerDependenciesMeta: msw: @@ -1189,20 +1265,20 @@ packages: vite: optional: true - '@vitest/pretty-format@2.1.3': - resolution: {integrity: sha512-XH1XdtoLZCpqV59KRbPrIhFCOO0hErxrQCMcvnQete3Vibb9UeIOX02uFPfVn3Z9ZXsq78etlfyhnkmIZSzIwQ==} + '@vitest/pretty-format@2.1.4': + resolution: {integrity: sha512-L95zIAkEuTDbUX1IsjRl+vyBSLh3PwLLgKpghl37aCK9Jvw0iP+wKwIFhfjdUtA2myLgjrG6VU6JCFLv8q/3Ww==} - '@vitest/runner@2.1.3': - resolution: {integrity: sha512-JGzpWqmFJ4fq5ZKHtVO3Xuy1iF2rHGV4d/pdzgkYHm1+gOzNZtqjvyiaDGJytRyMU54qkxpNzCx+PErzJ1/JqQ==} + '@vitest/runner@2.1.4': + resolution: {integrity: sha512-sKRautINI9XICAMl2bjxQM8VfCMTB0EbsBc/EDFA57V6UQevEKY/TOPOF5nzcvCALltiLfXWbq4MaAwWx/YxIA==} - '@vitest/snapshot@2.1.3': - resolution: {integrity: sha512-qWC2mWc7VAXmjAkEKxrScWHWFyCQx/cmiZtuGqMi+WwqQJ2iURsVY4ZfAK6dVo6K2smKRU6l3BPwqEBvhnpQGg==} + '@vitest/snapshot@2.1.4': + resolution: {integrity: sha512-3Kab14fn/5QZRog5BPj6Rs8dc4B+mim27XaKWFWHWA87R56AKjHTGcBFKpvZKDzC4u5Wd0w/qKsUIio3KzWW4Q==} - '@vitest/spy@2.1.3': - resolution: {integrity: sha512-Nb2UzbcUswzeSP7JksMDaqsI43Sj5+Kry6ry6jQJT4b5gAK+NS9NED6mDb8FlMRCX8m5guaHCDZmqYMMWRy5nQ==} + '@vitest/spy@2.1.4': + resolution: {integrity: sha512-4JOxa+UAizJgpZfaCPKK2smq9d8mmjZVPMt2kOsg/R8QkoRzydHH1qHxIYNvr1zlEaFj4SXiaaJWxq/LPLKaLg==} - '@vitest/utils@2.1.3': - resolution: {integrity: sha512-xpiVfDSg1RrYT0tX6czgerkpcKFmFOF/gCr30+Mve5V2kewCy4Prn1/NDMSRwaSmT7PRaOF83wu+bEtsY1wrvA==} + '@vitest/utils@2.1.4': + resolution: {integrity: sha512-MXDnZn0Awl2S86PSNIim5PWXgIAx8CIkzu35mBdSApUip6RFOGXBCf3YFyeEu8n1IHk4bWD46DeYFu9mQlFIRg==} '@vscode/test-cli@0.0.9': resolution: {integrity: sha512-vsl5/ueE3Jf0f6XzB0ECHHMsd5A0Yu6StElb8a+XsubZW7kHNAOw4Y3TSSuDzKEpLnJ92nbMy1Zl+KLGCE6NaA==} @@ -1258,8 +1334,8 @@ packages: cpu: [x64] os: [win32] - '@vscode/vsce-sign@2.0.4': - resolution: {integrity: sha512-0uL32egStKYfy60IqnynAChMTbL0oqpqk0Ew0YHiIb+fayuGZWADuIPHWUcY1GCnAA+VgchOPDMxnc2R3XGWEA==} + '@vscode/vsce-sign@2.0.5': + resolution: {integrity: sha512-GfYWrsT/vypTMDMgWDm75iDmAOMe7F71sZECJ+Ws6/xyIfmB3ELVnVN+LwMFAvmXY+e6eWhR2EzNGF/zAhWY3Q==} '@vscode/vsce@2.32.0': resolution: {integrity: sha512-3EFJfsgrSftIqt3EtdRcAygy/OJ3hstyI1cDmIgkU9CFZW5C+3djr6mfosndCUqcVYuyjmxOK1xmFp/Bq7+NIg==} @@ -1304,8 +1380,8 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn@8.13.0: - resolution: {integrity: sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==} + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} engines: {node: '>=0.4.0'} hasBin: true @@ -1327,12 +1403,12 @@ packages: resolution: {integrity: sha512-QtKFMdt2MO18cSfTLef6I+xPPexdoW3gUczOJqUNMXz/6K5VT7rKfheQfW0+9stvMTPBKBRMKR1gkyG7pmPDQw==} engines: {node: '>= 18.0.0'} - alova@3.0.5: - resolution: {integrity: sha512-cOE2nTPOp7sXLhf9cthdh90lT389C1akgJULMytuFeV1loriJr1YbT3LCw3qb/P3N+o/QtJ9WLH2ccr0vJ380A==} + alova@3.2.1: + resolution: {integrity: sha512-MA6QE8akeALobBOV9yMqJrwNaqxXodoI28lGkmtJsIEmTYvZMe7Ya+qFwJtOM/1rOQoD7I2Uu1wVrlvVAwrVtw==} engines: {node: '>= 18.0.0'} - alova@3.1.1: - resolution: {integrity: sha512-1LviUBEa6tNg4hVnnY0wtY7OGdzwl4uzASCTbMxXyiVkraJg3mt/e/5i0xGR6CeOkAS2hpmxDKsrE3rJEUnAKA==} + alova@3.2.2: + resolution: {integrity: sha512-f3xG3w7yMFIh3+F4gQRasIUzvQ/CR2jW6x5eRcRa79w5iqarp/1uq6kBJC4VmErKahbPWO1dYlmoXw0ihP16lA==} engines: {node: '>= 18.0.0'} ansi-colors@4.1.3: @@ -1546,6 +1622,9 @@ packages: change-case@4.1.2: resolution: {integrity: sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==} + changeset@0.2.6: + resolution: {integrity: sha512-d21ym9zLPOKMVhIa8ulJo5IV3QR2NNdK6BWuwg48qJA0XSQaMeDjo1UGThcTn7YDmU08j3UpKyFNvb3zplk8mw==} + chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} @@ -1817,6 +1896,10 @@ packages: resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} engines: {node: '>=0.3.1'} + diff@7.0.0: + resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} + engines: {node: '>=0.3.1'} + dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -1825,10 +1908,6 @@ packages: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} - doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - dom-serializer@2.0.0: resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} @@ -1909,8 +1988,8 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-iterator-helpers@1.1.0: - resolution: {integrity: sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==} + es-iterator-helpers@1.2.0: + resolution: {integrity: sha512-tpxqxncxnpw3c93u8n3VOzACmRFoVmWJqbWXvX/JfKbkhBw1oslgPrUfeSt2psuqyEJFD6N/9lg5i7bsKpoq+Q==} engines: {node: '>= 0.4'} es-object-atoms@1.0.0: @@ -2025,8 +2104,8 @@ packages: '@typescript-eslint/parser': optional: true - eslint-plugin-jsx-a11y@6.10.1: - resolution: {integrity: sha512-zHByM9WTUMnfsDTafGXRiqxp6lFtNoSOWBY6FonVRn3A+BUwN1L/tdBXT40BcBJi0cZjOGTXZ0eD/rTG9fEJ0g==} + eslint-plugin-jsx-a11y@6.10.2: + resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} engines: {node: '>=4.0'} peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 @@ -2057,23 +2136,31 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-scope@8.2.0: + resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint@8.57.1: - resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. + eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.14.0: + resolution: {integrity: sha512-c2FHsVBr87lnUtjP4Yhvk4yEhKrQavGafRA/Se1ouse8PfbfC/Qh9Mxa00yWsZRlqeUB9raXip0aiiUZkgnr9g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true - espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} @@ -2121,6 +2208,10 @@ packages: resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==} engines: {node: '>=0.10.0'} + expect-type@1.1.0: + resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} + engines: {node: '>=12.0.0'} + external-editor@3.1.0: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} engines: {node: '>=4'} @@ -2157,9 +2248,9 @@ packages: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} engines: {node: '>=8'} - file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} @@ -2183,9 +2274,9 @@ packages: resolution: {integrity: sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==} engines: {node: '>= 8'} - flat-cache@3.2.0: - resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} - engines: {node: ^10.12.0 || >=12.0.0} + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} flat@5.0.2: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} @@ -2303,9 +2394,13 @@ packages: resolution: {integrity: sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==} engines: {node: '>=0.10.0'} - globals@13.24.0: - resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} - engines: {node: '>=8'} + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@15.12.0: + resolution: {integrity: sha512-1+gLErljJFhbOVyaetcwJiJ4+eLe45S2E7P5UiZ9xGfeq3ATQf5DOv9G7MH3gGbKQLkzmNh2DxfZwLdw+j6oTQ==} + engines: {node: '>=18'} globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} @@ -2556,10 +2651,6 @@ packages: resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} engines: {node: '>=8'} - is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - is-plain-obj@2.1.0: resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} engines: {node: '>=8'} @@ -2604,10 +2695,6 @@ packages: resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} engines: {node: '>=12'} - is-unicode-supported@2.1.0: - resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} - engines: {node: '>=18'} - is-url@1.2.4: resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} @@ -2731,6 +2818,9 @@ packages: jszip@3.10.1: resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + just-extend@6.2.0: + resolution: {integrity: sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==} + jwa@1.4.1: resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} @@ -2801,6 +2891,9 @@ packages: lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + lodash.get@4.4.2: + resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} + lodash.includes@4.3.0: resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} @@ -2857,10 +2950,6 @@ packages: resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==} engines: {node: '>=12'} - log-symbols@6.0.0: - resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} - engines: {node: '>=18'} - log-update@6.1.0: resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} engines: {node: '>=18'} @@ -2882,8 +2971,8 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.0.1: - resolution: {integrity: sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==} + lru-cache@11.0.2: + resolution: {integrity: sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==} engines: {node: 20 || >=22} lru-cache@6.0.0: @@ -2987,8 +3076,8 @@ packages: mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} - mocha@10.7.3: - resolution: {integrity: sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==} + mocha@10.8.2: + resolution: {integrity: sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==} engines: {node: '>= 14.0.0'} hasBin: true @@ -3013,12 +3102,19 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + ncp@2.0.0: + resolution: {integrity: sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==} + hasBin: true + neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} nice-try@1.0.5: resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + nise@6.1.1: + resolution: {integrity: sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==} + no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} @@ -3154,10 +3250,6 @@ packages: resolution: {integrity: sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw==} engines: {node: '>=16'} - ora@8.1.0: - resolution: {integrity: sha512-GQEkNkH/GHOhPFXcqZs3IDahXEQcQxsSjEkK4KvEEST4t7eNzoMjxTzef+EZ+JluDEV+Raoi3WQ2CflnRdSVnQ==} - engines: {node: '>=18'} - os-tmpdir@1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} @@ -3212,8 +3304,8 @@ packages: parse5-parser-stream@7.1.2: resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==} - parse5@7.2.0: - resolution: {integrity: sha512-ZkDsAOcxsUMZ4Lz5fVciOehNcJ+Gb8gTzcA4yl3wnc273BAybYWrQ+Ks/OjCjSEpjvQkDSeZbybK9qj2VHHdGA==} + parse5@7.2.1: + resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==} pascal-case@3.1.2: resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} @@ -3256,6 +3348,10 @@ packages: resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} engines: {node: 20 || >=22} + path-to-regexp@8.2.0: + resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} + engines: {node: '>=16'} + path-type@3.0.0: resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} engines: {node: '>=4'} @@ -3474,18 +3570,13 @@ packages: rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} - rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true - rimraf@6.0.1: resolution: {integrity: sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==} engines: {node: 20 || >=22} hasBin: true - rollup@4.24.0: - resolution: {integrity: sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==} + rollup@4.24.4: + resolution: {integrity: sha512-vGorVWIsWfX3xbcyAS+I047kFKapHYivmkaT63Smj77XwvLSJos6M1xGqZnBPFQFBRZDOcG1QnYEIxAvTr/HjA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -3606,6 +3697,9 @@ packages: simple-get@4.0.1: resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + sinon@19.0.2: + resolution: {integrity: sha512-euuToqM+PjO4UgXeLETsfQiuoyPXlqFezr6YZDFwHR3t4qaX0fZUe1MfPMznTL5f8BWrVS89KduLdMUsxFCO6g==} + slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -3658,10 +3752,6 @@ packages: resolution: {integrity: sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - stdin-discarder@0.2.2: - resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} - engines: {node: '>=18'} - stoppable@1.1.0: resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} engines: {node: '>=4', npm: '>=6'} @@ -3844,8 +3934,8 @@ packages: peerDependencies: tslib: '2' - ts-api-utils@1.3.0: - resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + ts-api-utils@1.4.0: + resolution: {integrity: sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==} engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' @@ -3857,11 +3947,11 @@ packages: tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} - tslib@2.8.0: - resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==} + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - tsx@4.19.1: - resolution: {integrity: sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==} + tsx@4.19.2: + resolution: {integrity: sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==} engines: {node: '>=18.0.0'} hasBin: true @@ -3876,9 +3966,13 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + type-detect@4.1.0: + resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} + engines: {node: '>=4'} type-fest@0.21.3: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} @@ -3915,6 +4009,9 @@ packages: uc.micro@1.0.6: resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} + udc@1.0.1: + resolution: {integrity: sha512-jv+D9de1flsum5QkFtBdjyppCQAdz9kTck/0xST5Vx48T9LL2BYnw0Iw77dSKDQ9KZ/PS3qPO1vfXHDpLZlxcQ==} + uglify-js@3.19.3: resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} engines: {node: '>=0.8.0'} @@ -3970,8 +4067,8 @@ packages: validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} - vite-node@2.1.3: - resolution: {integrity: sha512-I1JadzO+xYX887S39Do+paRePCKoiDrWRRjp9kkG5he0t7RXNvPAJPCQSJqbGN4uCrFFeS3Kj3sLqY8NMYBEdA==} + vite-node@2.1.4: + resolution: {integrity: sha512-kqa9v+oi4HwkG6g8ufRnb5AeplcRw8jUF6/7/Qz1qRQOXHImG8YnLbB+LLszENwFnoBl9xIf9nVdCFzNd7GQEg==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -4006,15 +4103,15 @@ packages: terser: optional: true - vitest@2.1.3: - resolution: {integrity: sha512-Zrxbg/WiIvUP2uEzelDNTXmEMJXuzJ1kCpbDvaKByFA9MNeO95V+7r/3ti0qzJzrxdyuUw5VduN7k+D3VmVOSA==} + vitest@2.1.4: + resolution: {integrity: sha512-eDjxbVAJw1UJJCHr5xr/xM86Zx+YxIEXGAR+bmnEID7z9qWfoxpHw0zdobz+TQAFOLT+nEXz3+gx6nUJ7RgmlQ==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 2.1.3 - '@vitest/ui': 2.1.3 + '@vitest/browser': 2.1.4 + '@vitest/ui': 2.1.4 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -4175,31 +4272,47 @@ snapshots: '@alova/shared': 1.0.0-beta.7 alova: 3.0.0-beta.10 - '@alova/adapter-xhr@2.0.0-beta.8(alova@3.0.5)': + '@alova/adapter-xhr@2.0.10(alova@3.2.2)': dependencies: - '@alova/shared': 1.0.0-beta.7 - alova: 3.0.5 + '@alova/shared': 1.1.0 + alova: 3.2.2 '@alova/mock@1.5.2': {} - '@alova/mock@2.0.8(alova@3.0.5)': + '@alova/mock@2.0.9(alova@3.2.2)': dependencies: - '@alova/shared': 1.0.7 - alova: 3.0.5 + '@alova/shared': 1.1.0 + alova: 3.2.2 '@alova/shared@1.0.0-beta.7': {} - '@alova/shared@1.0.7': {} + '@alova/shared@1.1.0': {} + + '@alova/wormhole@1.0.0': + dependencies: + alova: 3.2.2 + commander: 12.1.0 + esbuild: 0.24.0 + glob: 11.0.0 + handlebars: 4.7.8 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + lodash: 4.17.21 + openapi-types: 12.1.3 + ora: 5.4.1 + swagger2openapi: 7.0.8 + transitivePeerDependencies: + - encoding '@azure/abort-controller@2.1.2': dependencies: - tslib: 2.8.0 + tslib: 2.8.1 '@azure/core-auth@1.9.0': dependencies: '@azure/abort-controller': 2.1.2 '@azure/core-util': 1.11.0 - tslib: 2.8.0 + tslib: 2.8.1 '@azure/core-client@1.9.2': dependencies: @@ -4209,7 +4322,7 @@ snapshots: '@azure/core-tracing': 1.2.0 '@azure/core-util': 1.11.0 '@azure/logger': 1.1.4 - tslib: 2.8.0 + tslib: 2.8.1 transitivePeerDependencies: - supports-color @@ -4222,18 +4335,18 @@ snapshots: '@azure/logger': 1.1.4 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.5 - tslib: 2.8.0 + tslib: 2.8.1 transitivePeerDependencies: - supports-color '@azure/core-tracing@1.2.0': dependencies: - tslib: 2.8.0 + tslib: 2.8.1 '@azure/core-util@1.11.0': dependencies: '@azure/abort-controller': 2.1.2 - tslib: 2.8.0 + tslib: 2.8.1 '@azure/identity@4.5.0': dependencies: @@ -4250,13 +4363,13 @@ snapshots: jws: 4.0.0 open: 8.4.2 stoppable: 1.1.0 - tslib: 2.8.0 + tslib: 2.8.1 transitivePeerDependencies: - supports-color '@azure/logger@1.1.4': dependencies: - tslib: 2.8.0 + tslib: 2.8.1 '@azure/msal-browser@3.26.1': dependencies: @@ -4270,38 +4383,32 @@ snapshots: jsonwebtoken: 9.0.2 uuid: 8.3.2 - '@babel/code-frame@7.25.9': + '@babel/code-frame@7.26.2': dependencies: - '@babel/highlight': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + js-tokens: 4.0.0 picocolors: 1.1.1 '@babel/helper-string-parser@7.25.9': {} '@babel/helper-validator-identifier@7.25.9': {} - '@babel/highlight@7.25.9': - dependencies: - '@babel/helper-validator-identifier': 7.25.9 - chalk: 2.4.2 - js-tokens: 4.0.0 - picocolors: 1.1.1 - - '@babel/parser@7.25.9': + '@babel/parser@7.26.2': dependencies: - '@babel/types': 7.25.9 + '@babel/types': 7.26.0 - '@babel/types@7.25.9': + '@babel/types@7.26.0': dependencies: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 '@bcoe/v8-coverage@0.2.3': {} - '@commitlint/cli@19.5.0(@types/node@18.19.59)(typescript@5.6.3)': + '@commitlint/cli@19.5.0(@types/node@18.19.64)(typescript@5.6.3)': dependencies: '@commitlint/format': 19.5.0 '@commitlint/lint': 19.5.0 - '@commitlint/load': 19.5.0(@types/node@18.19.59)(typescript@5.6.3) + '@commitlint/load': 19.5.0(@types/node@18.19.64)(typescript@5.6.3) '@commitlint/read': 19.5.0 '@commitlint/types': 19.5.0 tinyexec: 0.3.1 @@ -4348,7 +4455,7 @@ snapshots: '@commitlint/rules': 19.5.0 '@commitlint/types': 19.5.0 - '@commitlint/load@19.5.0(@types/node@18.19.59)(typescript@5.6.3)': + '@commitlint/load@19.5.0(@types/node@18.19.64)(typescript@5.6.3)': dependencies: '@commitlint/config-validator': 19.5.0 '@commitlint/execute-rule': 19.5.0 @@ -4356,7 +4463,7 @@ snapshots: '@commitlint/types': 19.5.0 chalk: 5.3.0 cosmiconfig: 9.0.0(typescript@5.6.3) - cosmiconfig-typescript-loader: 5.1.0(@types/node@18.19.59)(cosmiconfig@9.0.0(typescript@5.6.3))(typescript@5.6.3) + cosmiconfig-typescript-loader: 5.1.0(@types/node@18.19.64)(cosmiconfig@9.0.0(typescript@5.6.3))(typescript@5.6.3) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -4620,19 +4727,29 @@ snapshots: '@esbuild/win32-x64@0.24.0': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@8.57.1)': + '@eslint-community/eslint-utils@4.4.1(eslint@9.14.0(jiti@1.21.6))': dependencies: - eslint: 8.57.1 + eslint: 9.14.0(jiti@1.21.6) eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.11.1': {} + '@eslint-community/regexpp@4.12.1': {} + + '@eslint/config-array@0.18.0': + dependencies: + '@eslint/object-schema': 2.1.4 + debug: 4.3.7(supports-color@8.1.1) + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/core@0.7.0': {} - '@eslint/eslintrc@2.1.4': + '@eslint/eslintrc@3.1.0': dependencies: ajv: 6.12.6 debug: 4.3.7(supports-color@8.1.1) - espree: 9.6.1 - globals: 13.24.0 + espree: 10.3.0 + globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.0 js-yaml: 4.1.0 @@ -4641,21 +4758,28 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@8.57.1': {} + '@eslint/js@9.14.0': {} + + '@eslint/object-schema@2.1.4': {} + + '@eslint/plugin-kit@0.2.2': + dependencies: + levn: 0.4.1 '@exodus/schemasafe@1.3.0': {} - '@humanwhocodes/config-array@0.13.0': + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.6': dependencies: - '@humanwhocodes/object-schema': 2.0.3 - debug: 4.3.7(supports-color@8.1.1) - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.3.1 '@humanwhocodes/module-importer@1.0.1': {} - '@humanwhocodes/object-schema@2.0.3': {} + '@humanwhocodes/retry@0.3.1': {} + + '@humanwhocodes/retry@0.4.1': {} '@isaacs/cliui@8.0.2': dependencies: @@ -4672,7 +4796,7 @@ snapshots: dependencies: '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 18.19.59 + '@types/node': 18.19.64 '@types/yargs': 15.0.19 chalk: 4.1.2 @@ -4685,21 +4809,21 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 - '@jsonjoy.com/base64@1.1.2(tslib@2.8.0)': + '@jsonjoy.com/base64@1.1.2(tslib@2.8.1)': dependencies: - tslib: 2.8.0 + tslib: 2.8.1 - '@jsonjoy.com/json-pack@1.1.0(tslib@2.8.0)': + '@jsonjoy.com/json-pack@1.1.0(tslib@2.8.1)': dependencies: - '@jsonjoy.com/base64': 1.1.2(tslib@2.8.0) - '@jsonjoy.com/util': 1.5.0(tslib@2.8.0) + '@jsonjoy.com/base64': 1.1.2(tslib@2.8.1) + '@jsonjoy.com/util': 1.5.0(tslib@2.8.1) hyperdyperid: 1.2.0 - thingies: 1.21.0(tslib@2.8.0) - tslib: 2.8.0 + thingies: 1.21.0(tslib@2.8.1) + tslib: 2.8.1 - '@jsonjoy.com/util@1.5.0(tslib@2.8.0)': + '@jsonjoy.com/util@1.5.0(tslib@2.8.1)': dependencies: - tslib: 2.8.0 + tslib: 2.8.1 '@nodelib/fs.scandir@2.1.5': dependencies: @@ -4718,66 +4842,88 @@ snapshots: '@pkgr/core@0.1.1': {} - '@rollup/rollup-android-arm-eabi@4.24.0': + '@rollup/rollup-android-arm-eabi@4.24.4': + optional: true + + '@rollup/rollup-android-arm64@4.24.4': + optional: true + + '@rollup/rollup-darwin-arm64@4.24.4': optional: true - '@rollup/rollup-android-arm64@4.24.0': + '@rollup/rollup-darwin-x64@4.24.4': optional: true - '@rollup/rollup-darwin-arm64@4.24.0': + '@rollup/rollup-freebsd-arm64@4.24.4': optional: true - '@rollup/rollup-darwin-x64@4.24.0': + '@rollup/rollup-freebsd-x64@4.24.4': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.24.0': + '@rollup/rollup-linux-arm-gnueabihf@4.24.4': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.24.0': + '@rollup/rollup-linux-arm-musleabihf@4.24.4': optional: true - '@rollup/rollup-linux-arm64-gnu@4.24.0': + '@rollup/rollup-linux-arm64-gnu@4.24.4': optional: true - '@rollup/rollup-linux-arm64-musl@4.24.0': + '@rollup/rollup-linux-arm64-musl@4.24.4': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.24.0': + '@rollup/rollup-linux-powerpc64le-gnu@4.24.4': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.24.0': + '@rollup/rollup-linux-riscv64-gnu@4.24.4': optional: true - '@rollup/rollup-linux-s390x-gnu@4.24.0': + '@rollup/rollup-linux-s390x-gnu@4.24.4': optional: true - '@rollup/rollup-linux-x64-gnu@4.24.0': + '@rollup/rollup-linux-x64-gnu@4.24.4': optional: true - '@rollup/rollup-linux-x64-musl@4.24.0': + '@rollup/rollup-linux-x64-musl@4.24.4': optional: true - '@rollup/rollup-win32-arm64-msvc@4.24.0': + '@rollup/rollup-win32-arm64-msvc@4.24.4': optional: true - '@rollup/rollup-win32-ia32-msvc@4.24.0': + '@rollup/rollup-win32-ia32-msvc@4.24.4': optional: true - '@rollup/rollup-win32-x64-msvc@4.24.0': + '@rollup/rollup-win32-x64-msvc@4.24.4': optional: true '@rtsao/scc@1.1.0': {} + '@sinonjs/commons@3.0.1': + dependencies: + type-detect: 4.0.8 + + '@sinonjs/fake-timers@13.0.5': + dependencies: + '@sinonjs/commons': 3.0.1 + + '@sinonjs/samsam@8.0.2': + dependencies: + '@sinonjs/commons': 3.0.1 + lodash.get: 4.4.2 + type-detect: 4.1.0 + + '@sinonjs/text-encoding@0.7.3': {} + '@types/conventional-commits-parser@5.0.0': dependencies: - '@types/node': 18.19.59 + '@types/node': 18.19.64 '@types/estree@1.0.6': {} '@types/fs-extra@11.0.4': dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 18.19.59 + '@types/node': 18.19.64 '@types/istanbul-lib-coverage@2.0.6': {} @@ -4796,17 +4942,19 @@ snapshots: '@types/js-yaml@4.0.9': {} + '@types/json-schema@7.0.15': {} + '@types/json5@0.0.29': {} '@types/jsonfile@6.1.4': dependencies: - '@types/node': 18.19.59 + '@types/node': 18.19.64 - '@types/lodash@4.17.12': {} + '@types/lodash@4.17.13': {} '@types/mocha@10.0.9': {} - '@types/node@18.19.59': + '@types/node@18.19.64': dependencies: undici-types: 5.26.5 @@ -4818,12 +4966,18 @@ snapshots: '@types/serialize-javascript@5.0.4': {} + '@types/sinon@17.0.3': + dependencies: + '@types/sinonjs__fake-timers': 8.1.5 + + '@types/sinonjs__fake-timers@8.1.5': {} + '@types/swagger2openapi@7.0.4': dependencies: - '@types/node': 18.19.59 + '@types/node': 18.19.64 openapi-types: 12.1.3 - '@types/vscode@1.94.0': {} + '@types/vscode@1.95.0': {} '@types/yargs-parser@21.0.3': {} @@ -4831,126 +4985,124 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3)': + '@typescript-eslint/eslint-plugin@8.13.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3)': dependencies: - '@eslint-community/regexpp': 4.11.1 - '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.6.3) - '@typescript-eslint/scope-manager': 7.18.0 - '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.1)(typescript@5.6.3) - '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.6.3) - '@typescript-eslint/visitor-keys': 7.18.0 - eslint: 8.57.1 + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.13.0 + '@typescript-eslint/type-utils': 8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3) + '@typescript-eslint/utils': 8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.13.0 + eslint: 9.14.0(jiti@1.21.6) graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 1.3.0(typescript@5.6.3) + ts-api-utils: 1.4.0(typescript@5.6.3) optionalDependencies: typescript: 5.6.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3)': + '@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3)': dependencies: - '@typescript-eslint/scope-manager': 7.18.0 - '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.3) - '@typescript-eslint/visitor-keys': 7.18.0 + '@typescript-eslint/scope-manager': 8.13.0 + '@typescript-eslint/types': 8.13.0 + '@typescript-eslint/typescript-estree': 8.13.0(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.13.0 debug: 4.3.7(supports-color@8.1.1) - eslint: 8.57.1 + eslint: 9.14.0(jiti@1.21.6) optionalDependencies: typescript: 5.6.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@7.18.0': + '@typescript-eslint/scope-manager@8.13.0': dependencies: - '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/visitor-keys': 7.18.0 + '@typescript-eslint/types': 8.13.0 + '@typescript-eslint/visitor-keys': 8.13.0 - '@typescript-eslint/type-utils@7.18.0(eslint@8.57.1)(typescript@5.6.3)': + '@typescript-eslint/type-utils@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3)': dependencies: - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.3) - '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 8.13.0(typescript@5.6.3) + '@typescript-eslint/utils': 8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3) debug: 4.3.7(supports-color@8.1.1) - eslint: 8.57.1 - ts-api-utils: 1.3.0(typescript@5.6.3) + ts-api-utils: 1.4.0(typescript@5.6.3) optionalDependencies: typescript: 5.6.3 transitivePeerDependencies: + - eslint - supports-color - '@typescript-eslint/types@7.18.0': {} + '@typescript-eslint/types@8.13.0': {} - '@typescript-eslint/typescript-estree@7.18.0(typescript@5.6.3)': + '@typescript-eslint/typescript-estree@8.13.0(typescript@5.6.3)': dependencies: - '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/visitor-keys': 7.18.0 + '@typescript-eslint/types': 8.13.0 + '@typescript-eslint/visitor-keys': 8.13.0 debug: 4.3.7(supports-color@8.1.1) - globby: 11.1.0 + fast-glob: 3.3.2 is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.6.3 - ts-api-utils: 1.3.0(typescript@5.6.3) + ts-api-utils: 1.4.0(typescript@5.6.3) optionalDependencies: typescript: 5.6.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@7.18.0(eslint@8.57.1)(typescript@5.6.3)': + '@typescript-eslint/utils@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) - '@typescript-eslint/scope-manager': 7.18.0 - '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.3) - eslint: 8.57.1 + '@eslint-community/eslint-utils': 4.4.1(eslint@9.14.0(jiti@1.21.6)) + '@typescript-eslint/scope-manager': 8.13.0 + '@typescript-eslint/types': 8.13.0 + '@typescript-eslint/typescript-estree': 8.13.0(typescript@5.6.3) + eslint: 9.14.0(jiti@1.21.6) transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/visitor-keys@7.18.0': + '@typescript-eslint/visitor-keys@8.13.0': dependencies: - '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/types': 8.13.0 eslint-visitor-keys: 3.4.3 - '@ungap/structured-clone@1.2.0': {} - - '@vitest/expect@2.1.3': + '@vitest/expect@2.1.4': dependencies: - '@vitest/spy': 2.1.3 - '@vitest/utils': 2.1.3 + '@vitest/spy': 2.1.4 + '@vitest/utils': 2.1.4 chai: 5.1.2 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.3(@vitest/spy@2.1.3)(vite@5.4.10(@types/node@18.19.59))': + '@vitest/mocker@2.1.4(vite@5.4.10(@types/node@18.19.64))': dependencies: - '@vitest/spy': 2.1.3 + '@vitest/spy': 2.1.4 estree-walker: 3.0.3 magic-string: 0.30.12 optionalDependencies: - vite: 5.4.10(@types/node@18.19.59) + vite: 5.4.10(@types/node@18.19.64) - '@vitest/pretty-format@2.1.3': + '@vitest/pretty-format@2.1.4': dependencies: tinyrainbow: 1.2.0 - '@vitest/runner@2.1.3': + '@vitest/runner@2.1.4': dependencies: - '@vitest/utils': 2.1.3 + '@vitest/utils': 2.1.4 pathe: 1.1.2 - '@vitest/snapshot@2.1.3': + '@vitest/snapshot@2.1.4': dependencies: - '@vitest/pretty-format': 2.1.3 + '@vitest/pretty-format': 2.1.4 magic-string: 0.30.12 pathe: 1.1.2 - '@vitest/spy@2.1.3': + '@vitest/spy@2.1.4': dependencies: tinyspy: 3.0.2 - '@vitest/utils@2.1.3': + '@vitest/utils@2.1.4': dependencies: - '@vitest/pretty-format': 2.1.3 + '@vitest/pretty-format': 2.1.4 loupe: 3.1.2 tinyrainbow: 1.2.0 @@ -4962,7 +5114,7 @@ snapshots: enhanced-resolve: 5.17.1 glob: 10.4.5 minimatch: 9.0.5 - mocha: 10.7.3 + mocha: 10.8.2 supports-color: 9.4.0 yargs: 17.7.2 @@ -5003,7 +5155,7 @@ snapshots: '@vscode/vsce-sign-win32-x64@2.0.2': optional: true - '@vscode/vsce-sign@2.0.4': + '@vscode/vsce-sign@2.0.5': optionalDependencies: '@vscode/vsce-sign-alpine-arm64': 2.0.2 '@vscode/vsce-sign-alpine-x64': 2.0.2 @@ -5018,7 +5170,7 @@ snapshots: '@vscode/vsce@2.32.0': dependencies: '@azure/identity': 4.5.0 - '@vscode/vsce-sign': 2.0.4 + '@vscode/vsce-sign': 2.0.5 azure-devops-node-api: 12.5.0 chalk: 2.4.2 cheerio: 1.0.0 @@ -5048,7 +5200,7 @@ snapshots: '@vue/compiler-core@3.5.12': dependencies: - '@babel/parser': 7.25.9 + '@babel/parser': 7.26.2 '@vue/shared': 3.5.12 entities: 4.5.0 estree-walker: 2.0.2 @@ -5061,7 +5213,7 @@ snapshots: '@vue/compiler-sfc@3.5.12': dependencies: - '@babel/parser': 7.25.9 + '@babel/parser': 7.26.2 '@vue/compiler-core': 3.5.12 '@vue/compiler-dom': 3.5.12 '@vue/compiler-ssr': 3.5.12 @@ -5105,11 +5257,11 @@ snapshots: jsonparse: 1.3.1 through: 2.3.8 - acorn-jsx@5.3.2(acorn@8.13.0): + acorn-jsx@5.3.2(acorn@8.14.0): dependencies: - acorn: 8.13.0 + acorn: 8.14.0 - acorn@8.13.0: {} + acorn@8.14.0: {} agent-base@7.1.1: dependencies: @@ -5137,14 +5289,14 @@ snapshots: dependencies: '@alova/shared': 1.0.0-beta.7 - alova@3.0.5: + alova@3.2.1: dependencies: - '@alova/shared': 1.0.7 + '@alova/shared': 1.1.0 rate-limiter-flexible: 5.0.4 - alova@3.1.1: + alova@3.2.2: dependencies: - '@alova/shared': 1.0.7 + '@alova/shared': 1.1.0 rate-limiter-flexible: 5.0.4 ansi-colors@4.1.3: {} @@ -5356,14 +5508,14 @@ snapshots: camel-case@4.1.2: dependencies: pascal-case: 3.1.2 - tslib: 2.8.0 + tslib: 2.8.1 camelcase@6.3.0: {} capital-case@1.0.4: dependencies: no-case: 3.0.4 - tslib: 2.8.0 + tslib: 2.8.1 upper-case-first: 2.0.2 chai@5.1.2: @@ -5400,7 +5552,12 @@ snapshots: path-case: 3.0.4 sentence-case: 3.0.4 snake-case: 3.0.4 - tslib: 2.8.0 + tslib: 2.8.1 + + changeset@0.2.6: + dependencies: + udc: 1.0.1 + underscore: 1.13.7 chardet@0.7.0: {} @@ -5423,7 +5580,7 @@ snapshots: domutils: 3.1.0 encoding-sniffer: 0.2.0 htmlparser2: 9.1.0 - parse5: 7.2.0 + parse5: 7.2.1 parse5-htmlparser2-tree-adapter: 7.1.0 parse5-parser-stream: 7.1.2 undici: 6.20.1 @@ -5505,10 +5662,10 @@ snapshots: commander@9.5.0: {} - commitizen@4.3.1(@types/node@18.19.59)(typescript@5.6.3): + commitizen@4.3.1(@types/node@18.19.64)(typescript@5.6.3): dependencies: cachedir: 2.3.0 - cz-conventional-changelog: 3.3.0(@types/node@18.19.59)(typescript@5.6.3) + cz-conventional-changelog: 3.3.0(@types/node@18.19.64)(typescript@5.6.3) dedent: 0.7.0 detect-indent: 6.1.0 find-node-modules: 2.1.3 @@ -5537,7 +5694,7 @@ snapshots: constant-case@3.0.4: dependencies: no-case: 3.0.4 - tslib: 2.8.0 + tslib: 2.8.1 upper-case: 2.0.2 conventional-changelog-angular@7.0.0: @@ -5561,9 +5718,9 @@ snapshots: core-util-is@1.0.3: {} - cosmiconfig-typescript-loader@5.1.0(@types/node@18.19.59)(cosmiconfig@9.0.0(typescript@5.6.3))(typescript@5.6.3): + cosmiconfig-typescript-loader@5.1.0(@types/node@18.19.64)(cosmiconfig@9.0.0(typescript@5.6.3))(typescript@5.6.3): dependencies: - '@types/node': 18.19.59 + '@types/node': 18.19.64 cosmiconfig: 9.0.0(typescript@5.6.3) jiti: 1.21.6 typescript: 5.6.3 @@ -5611,16 +5768,16 @@ snapshots: csstype@3.1.3: {} - cz-conventional-changelog@3.3.0(@types/node@18.19.59)(typescript@5.6.3): + cz-conventional-changelog@3.3.0(@types/node@18.19.64)(typescript@5.6.3): dependencies: chalk: 2.4.2 - commitizen: 4.3.1(@types/node@18.19.59)(typescript@5.6.3) + commitizen: 4.3.1(@types/node@18.19.64)(typescript@5.6.3) conventional-commit-types: 3.0.0 lodash.map: 4.6.0 longest: 2.0.1 word-wrap: 1.2.5 optionalDependencies: - '@commitlint/load': 19.5.0(@types/node@18.19.59)(typescript@5.6.3) + '@commitlint/load': 19.5.0(@types/node@18.19.64)(typescript@5.6.3) transitivePeerDependencies: - '@types/node' - typescript @@ -5704,6 +5861,8 @@ snapshots: diff@5.2.0: {} + diff@7.0.0: {} + dir-glob@3.0.1: dependencies: path-type: 4.0.0 @@ -5712,10 +5871,6 @@ snapshots: dependencies: esutils: 2.0.3 - doctrine@3.0.0: - dependencies: - esutils: 2.0.3 - dom-serializer@2.0.0: dependencies: domelementtype: 2.3.0 @@ -5737,7 +5892,7 @@ snapshots: dot-case@3.0.4: dependencies: no-case: 3.0.4 - tslib: 2.8.0 + tslib: 2.8.1 dot-prop@5.3.0: dependencies: @@ -5842,7 +5997,7 @@ snapshots: es-errors@1.3.0: {} - es-iterator-helpers@1.1.0: + es-iterator-helpers@1.2.0: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 @@ -5852,6 +6007,7 @@ snapshots: function-bind: 1.1.2 get-intrinsic: 1.2.4 globalthis: 1.0.4 + gopd: 1.0.1 has-property-descriptors: 1.0.2 has-proto: 1.0.3 has-symbols: 1.0.3 @@ -5969,38 +6125,38 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1): + eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.14.0(jiti@1.21.6)))(eslint@9.14.0(jiti@1.21.6)): dependencies: confusing-browser-globals: 1.0.11 - eslint: 8.57.1 - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1) + eslint: 9.14.0(jiti@1.21.6) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.14.0(jiti@1.21.6)) object.assign: 4.1.5 object.entries: 1.1.8 semver: 6.3.1 - eslint-config-airbnb-typescript@18.0.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1): + eslint-config-airbnb-typescript@18.0.0(@typescript-eslint/eslint-plugin@8.13.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.14.0(jiti@1.21.6)))(eslint@9.14.0(jiti@1.21.6)): dependencies: - '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3) - '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.6.3) - eslint: 8.57.1 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1) + '@typescript-eslint/eslint-plugin': 8.13.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3) + '@typescript-eslint/parser': 8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3) + eslint: 9.14.0(jiti@1.21.6) + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.14.0(jiti@1.21.6)))(eslint@9.14.0(jiti@1.21.6)) transitivePeerDependencies: - eslint-plugin-import - eslint-config-airbnb@19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.1(eslint@8.57.1))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.1))(eslint-plugin-react@7.37.2(eslint@8.57.1))(eslint@8.57.1): + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.14.0(jiti@1.21.6)))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.14.0(jiti@1.21.6)))(eslint-plugin-react-hooks@4.6.2(eslint@9.14.0(jiti@1.21.6)))(eslint-plugin-react@7.37.2(eslint@9.14.0(jiti@1.21.6)))(eslint@9.14.0(jiti@1.21.6)): dependencies: - eslint: 8.57.1 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1) - eslint-plugin-jsx-a11y: 6.10.1(eslint@8.57.1) - eslint-plugin-react: 7.37.2(eslint@8.57.1) - eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) + eslint: 9.14.0(jiti@1.21.6) + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.14.0(jiti@1.21.6)))(eslint@9.14.0(jiti@1.21.6)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.14.0(jiti@1.21.6)) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.14.0(jiti@1.21.6)) + eslint-plugin-react: 7.37.2(eslint@9.14.0(jiti@1.21.6)) + eslint-plugin-react-hooks: 4.6.2(eslint@9.14.0(jiti@1.21.6)) object.assign: 4.1.5 object.entries: 1.1.8 - eslint-config-prettier@9.1.0(eslint@8.57.1): + eslint-config-prettier@9.1.0(eslint@9.14.0(jiti@1.21.6)): dependencies: - eslint: 8.57.1 + eslint: 9.14.0(jiti@1.21.6) eslint-import-resolver-node@0.3.9: dependencies: @@ -6010,17 +6166,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint@9.14.0(jiti@1.21.6)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.6.3) - eslint: 8.57.1 + '@typescript-eslint/parser': 8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3) + eslint: 9.14.0(jiti@1.21.6) eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(eslint@9.14.0(jiti@1.21.6)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -6029,9 +6185,9 @@ snapshots: array.prototype.flatmap: 1.3.2 debug: 3.2.7 doctrine: 2.1.0 - eslint: 8.57.1 + eslint: 9.14.0(jiti@1.21.6) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint@9.14.0(jiti@1.21.6)) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -6043,13 +6199,13 @@ snapshots: string.prototype.trimend: 1.0.8 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/parser': 8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-jsx-a11y@6.10.1(eslint@8.57.1): + eslint-plugin-jsx-a11y@6.10.2(eslint@9.14.0(jiti@1.21.6)): dependencies: aria-query: 5.3.2 array-includes: 3.1.8 @@ -6059,8 +6215,7 @@ snapshots: axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - es-iterator-helpers: 1.1.0 - eslint: 8.57.1 + eslint: 9.14.0(jiti@1.21.6) hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -6069,28 +6224,28 @@ snapshots: safe-regex-test: 1.0.3 string.prototype.includes: 2.0.1 - eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.3.3): + eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@9.14.0(jiti@1.21.6)))(eslint@9.14.0(jiti@1.21.6))(prettier@3.3.3): dependencies: - eslint: 8.57.1 + eslint: 9.14.0(jiti@1.21.6) prettier: 3.3.3 prettier-linter-helpers: 1.0.0 synckit: 0.9.2 optionalDependencies: - eslint-config-prettier: 9.1.0(eslint@8.57.1) + eslint-config-prettier: 9.1.0(eslint@9.14.0(jiti@1.21.6)) - eslint-plugin-react-hooks@4.6.2(eslint@8.57.1): + eslint-plugin-react-hooks@4.6.2(eslint@9.14.0(jiti@1.21.6)): dependencies: - eslint: 8.57.1 + eslint: 9.14.0(jiti@1.21.6) - eslint-plugin-react@7.37.2(eslint@8.57.1): + eslint-plugin-react@7.37.2(eslint@9.14.0(jiti@1.21.6)): dependencies: array-includes: 3.1.8 array.prototype.findlast: 1.2.5 array.prototype.flatmap: 1.3.2 array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 - es-iterator-helpers: 1.1.0 - eslint: 8.57.1 + es-iterator-helpers: 1.2.0 + eslint: 9.14.0(jiti@1.21.6) estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -6104,61 +6259,62 @@ snapshots: string.prototype.matchall: 4.0.11 string.prototype.repeat: 1.0.0 - eslint-scope@7.2.2: + eslint-scope@8.2.0: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 eslint-visitor-keys@3.4.3: {} - eslint@8.57.1: + eslint-visitor-keys@4.2.0: {} + + eslint@9.14.0(jiti@1.21.6): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) - '@eslint-community/regexpp': 4.11.1 - '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.57.1 - '@humanwhocodes/config-array': 0.13.0 + '@eslint-community/eslint-utils': 4.4.1(eslint@9.14.0(jiti@1.21.6)) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.18.0 + '@eslint/core': 0.7.0 + '@eslint/eslintrc': 3.1.0 + '@eslint/js': 9.14.0 + '@eslint/plugin-kit': 0.2.2 + '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 - '@nodelib/fs.walk': 1.2.8 - '@ungap/structured-clone': 1.2.0 + '@humanwhocodes/retry': 0.4.1 + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 debug: 4.3.7(supports-color@8.1.1) - doctrine: 3.0.0 escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 + eslint-scope: 8.2.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 + file-entry-cache: 8.0.0 find-up: 5.0.0 glob-parent: 6.0.2 - globals: 13.24.0 - graphemer: 1.4.0 ignore: 5.3.2 imurmurhash: 0.1.4 is-glob: 4.0.3 - is-path-inside: 3.0.3 - js-yaml: 4.1.0 json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 lodash.merge: 4.6.2 minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.4 - strip-ansi: 6.0.1 text-table: 0.2.0 + optionalDependencies: + jiti: 1.21.6 transitivePeerDependencies: - supports-color - espree@9.6.1: + espree@10.3.0: dependencies: - acorn: 8.13.0 - acorn-jsx: 5.3.2(acorn@8.13.0) - eslint-visitor-keys: 3.4.3 + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) + eslint-visitor-keys: 4.2.0 esprima@4.0.1: {} @@ -6203,6 +6359,8 @@ snapshots: dependencies: homedir-polyfill: 1.0.3 + expect-type@1.1.0: {} + external-editor@3.1.0: dependencies: chardet: 0.7.0 @@ -6241,9 +6399,9 @@ snapshots: dependencies: escape-string-regexp: 1.0.5 - file-entry-cache@6.0.1: + file-entry-cache@8.0.0: dependencies: - flat-cache: 3.2.0 + flat-cache: 4.0.1 fill-range@7.1.1: dependencies: @@ -6274,11 +6432,10 @@ snapshots: micromatch: 4.0.8 resolve-dir: 1.0.1 - flat-cache@3.2.0: + flat-cache@4.0.1: dependencies: flatted: 3.3.1 keyv: 4.5.4 - rimraf: 3.0.2 flat@5.0.2: {} @@ -6425,9 +6582,9 @@ snapshots: is-windows: 1.0.2 which: 1.3.1 - globals@13.24.0: - dependencies: - type-fest: 0.20.2 + globals@14.0.0: {} + + globals@15.12.0: {} globalthis@1.0.4: dependencies: @@ -6487,7 +6644,7 @@ snapshots: header-case@2.0.4: dependencies: capital-case: 1.0.4 - tslib: 2.8.0 + tslib: 2.8.1 homedir-polyfill@1.0.3: dependencies: @@ -6666,8 +6823,6 @@ snapshots: is-obj@2.0.0: {} - is-path-inside@3.0.3: {} - is-plain-obj@2.1.0: {} is-regex@1.1.4: @@ -6703,8 +6858,6 @@ snapshots: is-unicode-supported@1.3.0: {} - is-unicode-supported@2.1.0: {} - is-url@1.2.4: {} is-utf8@0.2.1: {} @@ -6838,6 +6991,8 @@ snapshots: readable-stream: 2.3.8 setimmediate: 1.0.5 + just-extend@6.2.0: {} + jwa@1.4.1: dependencies: buffer-equal-constant-time: 1.0.1 @@ -6936,6 +7091,8 @@ snapshots: lodash.camelcase@4.3.0: {} + lodash.get@4.4.2: {} + lodash.includes@4.3.0: {} lodash.isboolean@3.0.3: {} @@ -6978,11 +7135,6 @@ snapshots: chalk: 5.3.0 is-unicode-supported: 1.3.0 - log-symbols@6.0.0: - dependencies: - chalk: 5.3.0 - is-unicode-supported: 1.3.0 - log-update@6.1.0: dependencies: ansi-escapes: 7.0.0 @@ -7001,11 +7153,11 @@ snapshots: lower-case@2.0.2: dependencies: - tslib: 2.8.0 + tslib: 2.8.1 lru-cache@10.4.3: {} - lru-cache@11.0.1: {} + lru-cache@11.0.2: {} lru-cache@6.0.0: dependencies: @@ -7031,10 +7183,10 @@ snapshots: memfs@4.14.0: dependencies: - '@jsonjoy.com/json-pack': 1.1.0(tslib@2.8.0) - '@jsonjoy.com/util': 1.5.0(tslib@2.8.0) - tree-dump: 1.0.2(tslib@2.8.0) - tslib: 2.8.0 + '@jsonjoy.com/json-pack': 1.1.0(tslib@2.8.1) + '@jsonjoy.com/util': 1.5.0(tslib@2.8.1) + tree-dump: 1.0.2(tslib@2.8.1) + tslib: 2.8.1 memorystream@0.3.1: {} @@ -7093,7 +7245,7 @@ snapshots: mkdirp-classic@0.5.3: optional: true - mocha@10.7.3: + mocha@10.8.2: dependencies: ansi-colors: 4.1.3 browser-stdout: 1.3.1 @@ -7129,14 +7281,24 @@ snapshots: natural-compare@1.4.0: {} + ncp@2.0.0: {} + neo-async@2.6.2: {} nice-try@1.0.5: {} + nise@6.1.1: + dependencies: + '@sinonjs/commons': 3.0.1 + '@sinonjs/fake-timers': 13.0.5 + '@sinonjs/text-encoding': 0.7.3 + just-extend: 6.2.0 + path-to-regexp: 8.2.0 + no-case@3.0.4: dependencies: lower-case: 2.0.2 - tslib: 2.8.0 + tslib: 2.8.1 node-abi@3.71.0: dependencies: @@ -7329,18 +7491,6 @@ snapshots: string-width: 6.1.0 strip-ansi: 7.1.0 - ora@8.1.0: - dependencies: - chalk: 5.3.0 - cli-cursor: 5.0.0 - cli-spinners: 2.9.2 - is-interactive: 2.0.0 - is-unicode-supported: 2.1.0 - log-symbols: 6.0.0 - stdin-discarder: 0.2.2 - string-width: 7.2.0 - strip-ansi: 7.1.0 - os-tmpdir@1.0.2: {} p-limit@3.1.0: @@ -7366,7 +7516,7 @@ snapshots: param-case@3.0.4: dependencies: dot-case: 3.0.4 - tslib: 2.8.0 + tslib: 2.8.1 parent-module@1.0.1: dependencies: @@ -7379,7 +7529,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.25.9 + '@babel/code-frame': 7.26.2 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -7393,25 +7543,25 @@ snapshots: parse5-htmlparser2-tree-adapter@7.1.0: dependencies: domhandler: 5.0.3 - parse5: 7.2.0 + parse5: 7.2.1 parse5-parser-stream@7.1.2: dependencies: - parse5: 7.2.0 + parse5: 7.2.1 - parse5@7.2.0: + parse5@7.2.1: dependencies: entities: 4.5.0 pascal-case@3.1.2: dependencies: no-case: 3.0.4 - tslib: 2.8.0 + tslib: 2.8.1 path-case@3.0.4: dependencies: dot-case: 3.0.4 - tslib: 2.8.0 + tslib: 2.8.1 path-exists@4.0.0: {} @@ -7434,9 +7584,11 @@ snapshots: path-scurry@2.0.0: dependencies: - lru-cache: 11.0.1 + lru-cache: 11.0.2 minipass: 7.1.2 + path-to-regexp@8.2.0: {} + path-type@3.0.0: dependencies: pify: 3.0.0 @@ -7652,35 +7804,33 @@ snapshots: rfdc@1.4.1: {} - rimraf@3.0.2: - dependencies: - glob: 7.2.3 - rimraf@6.0.1: dependencies: glob: 11.0.0 package-json-from-dist: 1.0.1 - rollup@4.24.0: + rollup@4.24.4: dependencies: '@types/estree': 1.0.6 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.24.0 - '@rollup/rollup-android-arm64': 4.24.0 - '@rollup/rollup-darwin-arm64': 4.24.0 - '@rollup/rollup-darwin-x64': 4.24.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.24.0 - '@rollup/rollup-linux-arm-musleabihf': 4.24.0 - '@rollup/rollup-linux-arm64-gnu': 4.24.0 - '@rollup/rollup-linux-arm64-musl': 4.24.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.24.0 - '@rollup/rollup-linux-riscv64-gnu': 4.24.0 - '@rollup/rollup-linux-s390x-gnu': 4.24.0 - '@rollup/rollup-linux-x64-gnu': 4.24.0 - '@rollup/rollup-linux-x64-musl': 4.24.0 - '@rollup/rollup-win32-arm64-msvc': 4.24.0 - '@rollup/rollup-win32-ia32-msvc': 4.24.0 - '@rollup/rollup-win32-x64-msvc': 4.24.0 + '@rollup/rollup-android-arm-eabi': 4.24.4 + '@rollup/rollup-android-arm64': 4.24.4 + '@rollup/rollup-darwin-arm64': 4.24.4 + '@rollup/rollup-darwin-x64': 4.24.4 + '@rollup/rollup-freebsd-arm64': 4.24.4 + '@rollup/rollup-freebsd-x64': 4.24.4 + '@rollup/rollup-linux-arm-gnueabihf': 4.24.4 + '@rollup/rollup-linux-arm-musleabihf': 4.24.4 + '@rollup/rollup-linux-arm64-gnu': 4.24.4 + '@rollup/rollup-linux-arm64-musl': 4.24.4 + '@rollup/rollup-linux-powerpc64le-gnu': 4.24.4 + '@rollup/rollup-linux-riscv64-gnu': 4.24.4 + '@rollup/rollup-linux-s390x-gnu': 4.24.4 + '@rollup/rollup-linux-x64-gnu': 4.24.4 + '@rollup/rollup-linux-x64-musl': 4.24.4 + '@rollup/rollup-win32-arm64-msvc': 4.24.4 + '@rollup/rollup-win32-ia32-msvc': 4.24.4 + '@rollup/rollup-win32-x64-msvc': 4.24.4 fsevents: 2.3.3 run-async@2.4.1: {} @@ -7691,7 +7841,7 @@ snapshots: rxjs@7.8.1: dependencies: - tslib: 2.8.0 + tslib: 2.8.1 safe-array-concat@1.1.2: dependencies: @@ -7723,7 +7873,7 @@ snapshots: sentence-case@3.0.4: dependencies: no-case: 3.0.4 - tslib: 2.8.0 + tslib: 2.8.1 upper-case-first: 2.0.2 serialize-javascript@6.0.2: @@ -7811,6 +7961,15 @@ snapshots: simple-concat: 1.0.1 optional: true + sinon@19.0.2: + dependencies: + '@sinonjs/commons': 3.0.1 + '@sinonjs/fake-timers': 13.0.5 + '@sinonjs/samsam': 8.0.2 + diff: 7.0.0 + nise: 6.1.1 + supports-color: 7.2.0 + slash@3.0.0: {} slice-ansi@5.0.0: @@ -7826,7 +7985,7 @@ snapshots: snake-case@3.0.4: dependencies: dot-case: 3.0.4 - tslib: 2.8.0 + tslib: 2.8.1 source-map-js@1.2.1: {} @@ -7858,8 +8017,6 @@ snapshots: dependencies: bl: 5.1.0 - stdin-discarder@0.2.2: {} - stoppable@1.1.0: {} string-argv@0.3.2: {} @@ -8002,7 +8159,7 @@ snapshots: synckit@0.9.2: dependencies: '@pkgr/core': 0.1.1 - tslib: 2.8.0 + tslib: 2.8.1 tapable@2.2.1: {} @@ -8033,9 +8190,9 @@ snapshots: text-table@0.2.0: {} - thingies@1.21.0(tslib@2.8.0): + thingies@1.21.0(tslib@2.8.1): dependencies: - tslib: 2.8.0 + tslib: 2.8.1 through@2.3.8: {} @@ -8061,11 +8218,11 @@ snapshots: tr46@0.0.3: {} - tree-dump@1.0.2(tslib@2.8.0): + tree-dump@1.0.2(tslib@2.8.1): dependencies: - tslib: 2.8.0 + tslib: 2.8.1 - ts-api-utils@1.3.0(typescript@5.6.3): + ts-api-utils@1.4.0(typescript@5.6.3): dependencies: typescript: 5.6.3 @@ -8085,9 +8242,9 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 - tslib@2.8.0: {} + tslib@2.8.1: {} - tsx@4.19.1: + tsx@4.19.2: dependencies: esbuild: 0.23.1 get-tsconfig: 4.8.1 @@ -8105,7 +8262,9 @@ snapshots: dependencies: prelude-ls: 1.2.1 - type-fest@0.20.2: {} + type-detect@4.0.8: {} + + type-detect@4.1.0: {} type-fest@0.21.3: {} @@ -8153,6 +8312,8 @@ snapshots: uc.micro@1.0.6: {} + udc@1.0.1: {} + uglify-js@3.19.3: optional: true @@ -8175,11 +8336,11 @@ snapshots: upper-case-first@2.0.2: dependencies: - tslib: 2.8.0 + tslib: 2.8.1 upper-case@2.0.2: dependencies: - tslib: 2.8.0 + tslib: 2.8.1 uri-js@4.4.1: dependencies: @@ -8207,12 +8368,12 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - vite-node@2.1.3(@types/node@18.19.59): + vite-node@2.1.4(@types/node@18.19.64): dependencies: cac: 6.7.14 debug: 4.3.7(supports-color@8.1.1) pathe: 1.1.2 - vite: 5.4.10(@types/node@18.19.59) + vite: 5.4.10(@types/node@18.19.64) transitivePeerDependencies: - '@types/node' - less @@ -8224,26 +8385,27 @@ snapshots: - supports-color - terser - vite@5.4.10(@types/node@18.19.59): + vite@5.4.10(@types/node@18.19.64): dependencies: esbuild: 0.21.5 postcss: 8.4.47 - rollup: 4.24.0 + rollup: 4.24.4 optionalDependencies: - '@types/node': 18.19.59 + '@types/node': 18.19.64 fsevents: 2.3.3 - vitest@2.1.3(@types/node@18.19.59): + vitest@2.1.4(@types/node@18.19.64): dependencies: - '@vitest/expect': 2.1.3 - '@vitest/mocker': 2.1.3(@vitest/spy@2.1.3)(vite@5.4.10(@types/node@18.19.59)) - '@vitest/pretty-format': 2.1.3 - '@vitest/runner': 2.1.3 - '@vitest/snapshot': 2.1.3 - '@vitest/spy': 2.1.3 - '@vitest/utils': 2.1.3 + '@vitest/expect': 2.1.4 + '@vitest/mocker': 2.1.4(vite@5.4.10(@types/node@18.19.64)) + '@vitest/pretty-format': 2.1.4 + '@vitest/runner': 2.1.4 + '@vitest/snapshot': 2.1.4 + '@vitest/spy': 2.1.4 + '@vitest/utils': 2.1.4 chai: 5.1.2 debug: 4.3.7(supports-color@8.1.1) + expect-type: 1.1.0 magic-string: 0.30.12 pathe: 1.1.2 std-env: 3.7.0 @@ -8251,11 +8413,11 @@ snapshots: tinyexec: 0.3.1 tinypool: 1.0.1 tinyrainbow: 1.2.0 - vite: 5.4.10(@types/node@18.19.59) - vite-node: 2.1.3(@types/node@18.19.59) + vite: 5.4.10(@types/node@18.19.64) + vite-node: 2.1.4(@types/node@18.19.64) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 18.19.59 + '@types/node': 18.19.64 transitivePeerDependencies: - less - lightningcss diff --git a/test/api-v3-ts-test/alova.config.ts b/test/api-v3-ts-test/alova.config.ts new file mode 100644 index 0000000..db45b24 --- /dev/null +++ b/test/api-v3-ts-test/alova.config.ts @@ -0,0 +1,68 @@ +import type { Config } from '@alova/wormhole'; + +// For more config detailed visit: +// https://alova.js.org/tutorial/getting-started/extension-integration + +export default { + generator: [ + { + /** + * file input. support: + * 1. openapi json file url + * 2. local file + */ + input: 'https://petstore.swagger.io', + + /** + * input file platform. Currently only swagger is supported. + * When this parameter is specified, the input field only needs to specify the document address without specifying the openapi file + */ + platform: 'swagger', + + /** + * output path of interface file and type file. + * Multiple generators cannot have the same address, otherwise the generated code will overwrite each other. + */ + output: 'src/api' + + /** + * the mediaType of the generated response data. default is `application/json` + */ + // responseMediaType: 'application/json', + + /** + * the bodyMediaType of the generated request body data. default is `application/json` + */ + // bodyMediaType: 'application/json', + + /** + * the generated api version. options are `2` or `3`, default is `auto`. + */ + // version: 'auto', + + /** + * type of generated code. The options ​​are `auto/ts/typescript/module/commonjs`. + */ + // type: 'auto', + + /** + * exported global api name, you can access the generated api globally through this name, default is `Apis`. + * it is required when multiple generators are configured, and it cannot be repeated + */ + // global: 'Apis', + + /** + * filter or convert the generated api information, return an apiDescriptor, if this function is not specified, the apiDescripor object is not converted + */ + // handleApi: apiDescriptor => { + // return apiDescriptor; + // } + } + ] + + /** + * extension only + * whether to automatically update the interface, enabled by default, check every 5 minutes, closed when set to `false` + */ + // autoUpdate: true +}; diff --git a/test/api-common/openapi1.json b/test/api-v3-ts-test/openapi1.json similarity index 100% rename from test/api-common/openapi1.json rename to test/api-v3-ts-test/openapi1.json diff --git a/test/api-v3-ts-test/package.json b/test/api-v3-ts-test/package.json index e1fa480..1ab86b4 100644 --- a/test/api-v3-ts-test/package.json +++ b/test/api-v3-ts-test/package.json @@ -4,18 +4,18 @@ "description": "", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "tsx src/main.ts" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { - "@alova/wormhole": "workspace:^", + "@alova/wormhole": "^1.0.0", "typescript": "^5.4.5" }, "dependencies": { - "@alova/adapter-xhr": "2.0.0-beta.8", - "@alova/mock": "^2.0.4", - "alova": "3.0.5" + "@alova/adapter-xhr": "2.0.10", + "@alova/mock": "^2.0.9", + "alova": "3.2.2" } } diff --git a/test/api-v3-ts-test/src/api/apiDefinitions.ts b/test/api-v3-ts-test/src/api/apiDefinitions.ts new file mode 100644 index 0000000..61effaa --- /dev/null +++ b/test/api-v3-ts-test/src/api/apiDefinitions.ts @@ -0,0 +1,40 @@ +/// +/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Petstore - version 1.0.7 + * + * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI version: 3.0.0 + * + * Contact: + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +export default { + 'pet.uploadFile': ['POST', '/pet/{petId}/uploadImage'], + 'pet.addPet': ['POST', '/pet'], + 'pet.updatePet': ['PUT', '/pet'], + 'pet.findPetsByStatus': ['GET', '/pet/findByStatus'], + 'pet.findPetsByTags': ['GET', '/pet/findByTags'], + 'pet.getPetById': ['GET', '/pet/{petId}'], + 'pet.updatePetWithForm': ['POST', '/pet/{petId}'], + 'pet.deletePet': ['DELETE', '/pet/{petId}'], + 'store.getInventory': ['GET', '/store/inventory'], + 'store.placeOrder': ['POST', '/store/order'], + 'store.getOrderById': ['GET', '/store/order/{orderId}'], + 'store.deleteOrder': ['DELETE', '/store/order/{orderId}'], + 'user.createUsersWithListInput': ['POST', '/user/createWithList'], + 'user.getUserByName': ['GET', '/user/{username}'], + 'user.updateUser': ['PUT', '/user/{username}'], + 'user.deleteUser': ['DELETE', '/user/{username}'], + 'user.loginUser': ['GET', '/user/login'], + 'user.logoutUser': ['GET', '/user/logout'], + 'user.createUsersWithArrayInput': ['POST', '/user/createWithArray'], + 'user.createUser': ['POST', '/user'] +}; diff --git a/test/api-v3-ts-test/src/api/createApis.ts b/test/api-v3-ts-test/src/api/createApis.ts new file mode 100644 index 0000000..b09e30d --- /dev/null +++ b/test/api-v3-ts-test/src/api/createApis.ts @@ -0,0 +1,92 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Petstore - version 1.0.7 + * + * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI version: 3.0.0 + * + * Contact: + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, MethodType, AlovaGenerics, AlovaMethodCreateConfig } from 'alova'; +import { Method } from 'alova'; +import apiDefinitions from './apiDefinitions'; + +const createFunctionalProxy = (array: (string | symbol)[], alovaInstance: Alova, configMap: any) => { + // create a new proxy instance + return new Proxy(function () {}, { + get(_, property) { + // record the target property, so that it can get the completed accessing paths + array.push(property); + // always return a new proxy to continue recording accessing paths. + return createFunctionalProxy(array, alovaInstance, configMap); + }, + apply(_, __, [config]) { + const apiPathKey = array.join('.') as keyof typeof apiDefinitions; + const apiItem = apiDefinitions[apiPathKey]; + if (!apiItem) { + throw new Error(`the api path of \`${apiPathKey}\` is not found`); + } + const mergedConfig = { + ...configMap[apiPathKey], + ...config + }; + const [method, url] = apiItem; + const pathParams = mergedConfig.pathParams; + const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => { + const pathParam = pathParams[key]; + return pathParam; + }); + delete mergedConfig.pathParams; + let data = mergedConfig.data; + if (Object.prototype.toString.call(data) === '[object Object]' && typeof FormData !== 'undefined') { + let hasBlobData = false; + const formData = new FormData(); + for (const key in data) { + formData.append(key, data[key]); + if (data[key] instanceof Blob) { + hasBlobData = true; + } + } + data = hasBlobData ? formData : data; + } + return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data); + } + }); +}; + +export const createApis = (alovaInstance: Alova, configMap: any) => { + const Apis = new Proxy({} as Apis, { + get(_, property) { + return createFunctionalProxy([property], alovaInstance, configMap); + } + }); + // define global variable `Apis` + (globalThis as any).Apis = Apis; + return Apis; +}; +type MethodConfig = AlovaMethodCreateConfig< + (typeof import('./index'))['alovaInstance'] extends Alova ? AG : any, + any, + T +>; +type APISofParameters = Tag extends keyof Apis + ? Url extends keyof Apis[Tag] + ? Apis[Tag][Url] extends (...args: any) => any + ? Parameters + : any + : any + : any; +type MethodsConfigMap = { + [P in keyof typeof import('./apiDefinitions').default]?: MethodConfig< + P extends `${infer Tag}.${infer Url}` ? Parameters[0]['transform']>[0] : any + >; +}; +export const withConfigType = (config: Config) => config; diff --git a/test/api-v3-ts-test/src/api/globals.d.ts b/test/api-v3-ts-test/src/api/globals.d.ts new file mode 100644 index 0000000..cde730e --- /dev/null +++ b/test/api-v3-ts-test/src/api/globals.d.ts @@ -0,0 +1,1033 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Petstore - version 1.0.7 + * + * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI version: 3.0.0 + * + * Contact: + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, AlovaMethodCreateConfig, AlovaGenerics, Method } from 'alova'; +import type { $$userConfigMap, alovaInstance } from '.'; +import type apiDefinitions from './apiDefinitions'; + +type CollapsedAlova = typeof alovaInstance; +type UserMethodConfigMap = typeof $$userConfigMap; + +type Alova2MethodConfig = + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Omit< + AlovaMethodCreateConfig< + AlovaGenerics, + any, + Responded + >, + 'params' + > + : never; + +// Extract the return type of transform function that define in $$userConfigMap, if it not exists, use the default type. +type ExtractUserDefinedTransformed< + DefinitionKey extends keyof typeof apiDefinitions, + Default +> = DefinitionKey extends keyof UserMethodConfigMap + ? UserMethodConfigMap[DefinitionKey]['transform'] extends (...args: any[]) => any + ? Awaited> + : Default + : Default; +type Alova2Method< + Responded, + DefinitionKey extends keyof typeof apiDefinitions, + CurrentConfig extends Alova2MethodConfig +> = + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Method< + AlovaGenerics< + CurrentConfig extends undefined + ? ExtractUserDefinedTransformed + : CurrentConfig['transform'] extends (...args: any[]) => any + ? Awaited> + : ExtractUserDefinedTransformed, + any, + RequestConfig, + Response, + ResponseHeader, + L1Cache, + L2Cache, + SE + > + > + : never; + +export type ApiResponse = { + code?: number; + type?: string; + message?: string; +}; +export type Category = { + id?: number; + name?: string; +}; +export type Tag = { + id?: number; + name?: string; +}; +export type Pet = { + id?: number; + category?: Category; + /** + * [required] + */ + name: string; + /** + * [required] + */ + photoUrls: string[]; + tags?: Tag[]; + /** + * pet status in the store + */ + status?: 'available' | 'pending' | 'sold'; +}; +export type Order = { + id?: number; + petId?: number; + quantity?: number; + shipDate?: string; + /** + * Order Status + */ + status?: 'placed' | 'approved' | 'delivered'; + complete?: boolean; +}; +export type User = { + id?: number; + username?: string; + firstName?: string; + lastName?: string; + email?: string; + password?: string; + phone?: string; + /** + * User Status + */ + userStatus?: number; +}; +declare global { + interface Apis { + pet: { + /** + * --- + * + * [POST] uploads an image + * + * **path:** /pet/{petId}/uploadImage + * + * --- + * + * **Path Parameters** + * ```ts + * type PathParameters = { + * // ID of pet to update + * // [required] + * petId: number + * } + * ``` + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = { + * // Additional data to pass to server + * additionalMetadata?: string + * // file to upload + * file?: Blob + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = { + * code?: number + * type?: string + * message?: string + * } + * ``` + */ + uploadFile< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of pet to update + * [required] + */ + petId: number; + }; + data: { + /** + * Additional data to pass to server + */ + additionalMetadata?: string; + /** + * file to upload + */ + file?: Blob; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Add a new pet to the store + * + * **path:** /pet + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = { + * id?: number + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * status?: 'available' | 'pending' | 'sold' + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = unknown + * ``` + */ + addPet< + Config extends Alova2MethodConfig & { + data: Pet; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [PUT] Update an existing pet + * + * **path:** /pet + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = { + * id?: number + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * status?: 'available' | 'pending' | 'sold' + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = unknown + * ``` + */ + updatePet< + Config extends Alova2MethodConfig & { + data: Pet; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Finds Pets by status + * + * **path:** /pet/findByStatus + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // Status values that need to be considered for filter + * // [required] + * status: ('available' | 'pending' | 'sold')[] + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = Array<{ + * id?: number + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * status?: 'available' | 'pending' | 'sold' + * }> + * ``` + */ + findPetsByStatus< + Config extends Alova2MethodConfig & { + params: { + /** + * Status values that need to be considered for filter + * [required] + */ + status: ('available' | 'pending' | 'sold')[]; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Finds Pets by tags + * + * **path:** /pet/findByTags + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // Tags to filter by + * // [required] + * tags: string[] + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = Array<{ + * id?: number + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * status?: 'available' | 'pending' | 'sold' + * }> + * ``` + */ + findPetsByTags< + Config extends Alova2MethodConfig & { + params: { + /** + * Tags to filter by + * [required] + */ + tags: string[]; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Find pet by ID + * + * **path:** /pet/{petId} + * + * --- + * + * **Path Parameters** + * ```ts + * type PathParameters = { + * // ID of pet to return + * // [required] + * petId: number + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = { + * id?: number + * category?: { + * id?: number + * name?: string + * } + * // [required] + * name: string + * // [required] + * photoUrls: string[] + * tags?: Array<{ + * id?: number + * name?: string + * }> + * // pet status in the store + * status?: 'available' | 'pending' | 'sold' + * } + * ``` + */ + getPetById< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of pet to return + * [required] + */ + petId: number; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Updates a pet in the store with form data + * + * **path:** /pet/{petId} + * + * --- + * + * **Path Parameters** + * ```ts + * type PathParameters = { + * // ID of pet that needs to be updated + * // [required] + * petId: number + * } + * ``` + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = { + * // Updated name of the pet + * name?: string + * // Updated status of the pet + * status?: string + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = unknown + * ``` + */ + updatePetWithForm< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of pet that needs to be updated + * [required] + */ + petId: number; + }; + data: { + /** + * Updated name of the pet + */ + name?: string; + /** + * Updated status of the pet + */ + status?: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [DELETE] Deletes a pet + * + * **path:** /pet/{petId} + * + * --- + * + * **Path Parameters** + * ```ts + * type PathParameters = { + * // Pet id to delete + * // [required] + * petId: number + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = unknown + * ``` + */ + deletePet< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * Pet id to delete + * [required] + */ + petId: number; + }; + } + >( + config: Config + ): Alova2Method; + }; + store: { + /** + * --- + * + * [GET] Returns pet inventories by status + * + * **path:** /store/inventory + * + * --- + * + * **Response** + * ```ts + * type Response = Record + * ``` + */ + getInventory>>( + config?: Config + ): Alova2Method, 'store.getInventory', Config>; + /** + * --- + * + * [POST] Place an order for a pet + * + * **path:** /store/order + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = { + * id?: number + * petId?: number + * quantity?: number + * shipDate?: string + * // Order Status + * status?: 'placed' | 'approved' | 'delivered' + * complete?: boolean + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = { + * id?: number + * petId?: number + * quantity?: number + * shipDate?: string + * // Order Status + * status?: 'placed' | 'approved' | 'delivered' + * complete?: boolean + * } + * ``` + */ + placeOrder< + Config extends Alova2MethodConfig & { + data: Order; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Find purchase order by ID + * + * **path:** /store/order/{orderId} + * + * --- + * + * **Path Parameters** + * ```ts + * type PathParameters = { + * // ID of pet that needs to be fetched + * // [required] + * orderId: number + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = { + * id?: number + * petId?: number + * quantity?: number + * shipDate?: string + * // Order Status + * status?: 'placed' | 'approved' | 'delivered' + * complete?: boolean + * } + * ``` + */ + getOrderById< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of pet that needs to be fetched + * [required] + */ + orderId: number; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [DELETE] Delete purchase order by ID + * + * **path:** /store/order/{orderId} + * + * --- + * + * **Path Parameters** + * ```ts + * type PathParameters = { + * // ID of the order that needs to be deleted + * // [required] + * orderId: number + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = unknown + * ``` + */ + deleteOrder< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * ID of the order that needs to be deleted + * [required] + */ + orderId: number; + }; + } + >( + config: Config + ): Alova2Method; + }; + user: { + /** + * --- + * + * [POST] Creates list of users with given input array + * + * **path:** /user/createWithList + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = Array<{ + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * }> + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = unknown + * ``` + */ + createUsersWithListInput< + Config extends Alova2MethodConfig & { + data: User[]; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Get user by user name + * + * **path:** /user/{username} + * + * --- + * + * **Path Parameters** + * ```ts + * type PathParameters = { + * // The name that needs to be fetched. Use user1 for testing. + * // [required] + * username: string + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = { + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * } + * ``` + */ + getUserByName< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * The name that needs to be fetched. Use user1 for testing. + * [required] + */ + username: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [PUT] Updated user + * + * **path:** /user/{username} + * + * --- + * + * **Path Parameters** + * ```ts + * type PathParameters = { + * // name that need to be updated + * // [required] + * username: string + * } + * ``` + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = { + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = unknown + * ``` + */ + updateUser< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * name that need to be updated + * [required] + */ + username: string; + }; + data: User; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [DELETE] Delete user + * + * **path:** /user/{username} + * + * --- + * + * **Path Parameters** + * ```ts + * type PathParameters = { + * // The name that needs to be deleted + * // [required] + * username: string + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = unknown + * ``` + */ + deleteUser< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * The name that needs to be deleted + * [required] + */ + username: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Logs user into the system + * + * **path:** /user/login + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * // The user name for login + * // [required] + * username: string + * // The password for login in clear text + * // [required] + * password: string + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = string + * ``` + */ + loginUser< + Config extends Alova2MethodConfig & { + params: { + /** + * The user name for login + * [required] + */ + username: string; + /** + * The password for login in clear text + * [required] + */ + password: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Logs out current logged in user session + * + * **path:** /user/logout + * + * --- + * + * **Response** + * ```ts + * type Response = unknown + * ``` + */ + logoutUser>( + config?: Config + ): Alova2Method; + /** + * --- + * + * [POST] Creates list of users with given input array + * + * **path:** /user/createWithArray + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = Array<{ + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * }> + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = unknown + * ``` + */ + createUsersWithArrayInput< + Config extends Alova2MethodConfig & { + data: User[]; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Create user + * + * **path:** /user + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = { + * id?: number + * username?: string + * firstName?: string + * lastName?: string + * email?: string + * password?: string + * phone?: string + * // User Status + * userStatus?: number + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = unknown + * ``` + */ + createUser< + Config extends Alova2MethodConfig & { + data: User; + } + >( + config: Config + ): Alova2Method; + }; + } + + var Apis: Apis; +} diff --git a/test/api-v3-ts-test/src/api/index.ts b/test/api-v3-ts-test/src/api/index.ts new file mode 100644 index 0000000..eb6e93d --- /dev/null +++ b/test/api-v3-ts-test/src/api/index.ts @@ -0,0 +1,18 @@ +import { createAlova } from 'alova'; +import fetchAdapter from 'alova/fetch'; +import { createApis, withConfigType } from './createApis'; + +export const alovaInstance = createAlova({ + baseURL: '', + requestAdapter: fetchAdapter(), + beforeRequest: method => {}, + responded: res => { + return res.json(); + } +}); + +export const $$userConfigMap = withConfigType({}); + +const Apis = createApis(alovaInstance, $$userConfigMap); + +export default Apis; diff --git a/test/api-v3-ts-test/src/main.ts b/test/api-v3-ts-test/src/main.ts new file mode 100644 index 0000000..04846ef --- /dev/null +++ b/test/api-v3-ts-test/src/main.ts @@ -0,0 +1,12 @@ +import './api'; + +async function main() { + const res1 = await Apis.user.getUserByName({ + pathParams: { + username: 'abc' + } + }); + console.log(res1); +} + +main(); diff --git a/tsconfig.base.json b/tsconfig.base.json index 3d2f6ab..35a308c 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -17,7 +17,6 @@ "skipDefaultLibCheck": false, "esModuleInterop": true, "inlineSourceMap": false, - "removeComments": false, - "types": ["vitest/globals"] + "removeComments": false } } diff --git a/tsconfig.json b/tsconfig.json index 2bef1e8..3a4c96d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "./tsconfig.base.json", - "exclude": ["design/**", "test/**"], + "exclude": ["design/**"], "compilerOptions": { "outDir": "./dist", "moduleResolution": "node", diff --git a/vitest.workspace.ts b/vitest.workspace.ts index 2746826..ab45296 100644 --- a/vitest.workspace.ts +++ b/vitest.workspace.ts @@ -1,3 +1,3 @@ import { defineWorkspace } from 'vitest/config'; -export default defineWorkspace(['packages/*']); +export default defineWorkspace(['packages/*/vitest.config.ts']); From 986e113dbd1fa9f1096c861973b7f704258d9343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E9=95=87?= Date: Thu, 7 Nov 2024 16:20:21 +0800 Subject: [PATCH 38/47] fix: initial version --- .changeset/config.json | 14 + .changeset/slow-kids-yell.md | 5 + .coveralls.yml | 2 + .github/FUNDING.yml | 3 + .github/ISSUE_TEMPLATE/01.bug_report.yml | 115 + .../ISSUE_TEMPLATE/02.bug_report_zh-CN.yml | 115 + .github/ISSUE_TEMPLATE/config.yml | 29 + .github/labeler.yml | 10 + .github/workflows/label.yml | 15 + .github/workflows/pr.yml | 43 + .github/workflows/release.yml | 74 + .gitignore | 3 + eslint.config.mjs | 2 +- package.json | 20 +- packages/vscode-extension/package.json | 4 - packages/wormhole/src/bin/cli.ts | 2 + .../test/__snapshots__/generate.spec.ts.snap | 2696 +++++++++++++++++ packages/wormhole/tsconfig.json | 2 +- .../{vitest.config.ts => vitest.config.mts} | 0 pnpm-lock.yaml | 585 +++- scripts/bump-version.ts | 52 + tsconfig.json | 9 +- vitest.config.mts | 10 + vitest.workspace.ts | 2 +- 24 files changed, 3783 insertions(+), 29 deletions(-) create mode 100644 .changeset/config.json create mode 100644 .changeset/slow-kids-yell.md create mode 100644 .coveralls.yml create mode 100644 .github/FUNDING.yml create mode 100644 .github/ISSUE_TEMPLATE/01.bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/02.bug_report_zh-CN.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/labeler.yml create mode 100644 .github/workflows/label.yml create mode 100644 .github/workflows/pr.yml create mode 100644 .github/workflows/release.yml rename packages/wormhole/{vitest.config.ts => vitest.config.mts} (100%) create mode 100644 scripts/bump-version.ts create mode 100644 vitest.config.mts diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..2840e87 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", + "changelog": ["@changesets/changelog-github", { "repo": "alovajs/devtools" }], + "commit": false, + "fixed": [], + "linked": [], + "ignore": ["alova-vscode-extension"], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "minor", + "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": { + "onlyUpdatePeerDependentsWhenOutOfRange": true + } +} diff --git a/.changeset/slow-kids-yell.md b/.changeset/slow-kids-yell.md new file mode 100644 index 0000000..c95fdf1 --- /dev/null +++ b/.changeset/slow-kids-yell.md @@ -0,0 +1,5 @@ +--- +'@alova/wormhole': patch +--- + +initial version diff --git a/.coveralls.yml b/.coveralls.yml new file mode 100644 index 0000000..769dd06 --- /dev/null +++ b/.coveralls.yml @@ -0,0 +1,2 @@ +service_name: github-action +repo_token: k4mCwLORlEDAb7wQcYXgMbvAwx2CadBOE diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..06b3953 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +github: alovajs +open_collective: alova +custom: https://afdian.net/a/huzhen555 diff --git a/.github/ISSUE_TEMPLATE/01.bug_report.yml b/.github/ISSUE_TEMPLATE/01.bug_report.yml new file mode 100644 index 0000000..ff07ea8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/01.bug_report.yml @@ -0,0 +1,115 @@ +name: "\U0001F41E Bug Report" +description: Create a report to help us improve alova +title: '[Bug]: ' +labels: + - 'bug:need-confirm' + - 'lang:english' +assignees: + - MeetinaXD +body: + - type: markdown + attributes: + value: | + :wave: Hi, thank you very much for your support for alova, it is really important! + + **We hope to build alova into a project shared by everyone, and encourage every developer to become a contributor to the alova community with an open and inclusive attitude. If you are willing, you can try to participate in the contribution by submitting PR, so that your code can provide value for developers all over the world. For specific contributions, please [refer to the contribution guide](https://github.com/alovajs/alova/blob/main/CONTRIBUTING.md)!** + + :warning: Before submitting a bug report, please read the following: + - Before submitting a bug, you can first look for a solution through the [official documentation](https://alova.js.org); + - Confirm that you have searched the [historical issues](https://github.com/alovajs/alova/issues) and have not found the same problem. + - If it is a question or doubt, you can post it on [Discussions](https://github.com/alovajs/alova/discussions), which will help the author manage the alova community better. + - Join the [Discord](https://discord.gg/S47QGJgkVb) or [WeChat group](https://alova.js.org/img/wechat_qrcode.jpg) for online discussions. + + - type: checkboxes + id: is-this-a-bug + attributes: + label: Is this a Bug? + description: ':warning: If you want to report a proposal or have difficulties in use, please return to the New Issue page and check other options.' + options: + - label: I have confirmed that I want to report a Bug + required: true + + - type: checkboxes + id: have-been-report-before + attributes: + label: Has this issue been reported before? + description: ':warning: Please search the Issue to confirm that the issue you are about to submit has not been reported before' + options: + - label: I have confirmed that this Issue has not been reported before + required: true + + - type: input + id: version + attributes: + label: Alova Version + description: Please fill in the version number in node_modules/alova/package.json + placeholder: e.g. 3.0.0 + validations: + required: true + + - type: dropdown + id: framework + attributes: + label: Framework + description: Please choose the framework of the impact of this issue. + multiple: false + options: + - 'React' + - 'Vue' + - 'Svelte' + - 'Nodejs' + - 'Deno' + - 'Bun' + - 'Other Framework' + validations: + required: true + + - type: textarea + id: description + attributes: + label: Problem Description + description: Describe in detail the circumstances under which the problem occurred. You can use Markdown syntax to provide key code snippets. + validations: + required: true + + - type: textarea + id: expect + attributes: + label: Expected Behavior + description: Clearly and briefly describe the desired effect + + - type: input + id: reproduce + attributes: + label: Reproduction Link + description: | + Providing a reproducible project will help the resolver solve the problem faster. You can choose one from the [official example collection](https://alova.js.org/category/examples/) as a template. + You can also reproduce it on your own on [codesandbox](https://codesandbox.io), [stackBlitz](https://stackblitz.com). + You can also provide a GitHub repository link. + Please do not fill in invalid links, otherwise the issue will be closed. + + - type: textarea + id: reproduce-steps + attributes: + label: Reproduction Steps + description: How do we need to do to reproduce the problem you encountered? Please provide the simplest operation steps to help us quickly reproduce the problem + placeholder: | + For example: + 1. Click the button + 2. The request is not sent + validations: + required: true + + - type: textarea + id: browsers + attributes: + label: System Information + description: 'Paste the output of the following command: `npx envinfo --system --npmPackages alova,vue,react,svelte --binaries --browsers`' + render: shell + placeholder: System, Binaries, Browsers + + - type: textarea + id: remark + attributes: + label: Additional Information + description: If there is any background information about the problem and other useful context information. Such as the solutions you have tried diff --git a/.github/ISSUE_TEMPLATE/02.bug_report_zh-CN.yml b/.github/ISSUE_TEMPLATE/02.bug_report_zh-CN.yml new file mode 100644 index 0000000..89367aa --- /dev/null +++ b/.github/ISSUE_TEMPLATE/02.bug_report_zh-CN.yml @@ -0,0 +1,115 @@ +name: "\U0001F41E 问题反馈" +description: 使用中文报告问题,帮助 alova 变得更好 +title: '[Bug]: ' +labels: + - 'bug:need-confirm' + - 'lang:chinese' +assignees: + - MeetinaXD +body: + - type: markdown + attributes: + value: | + :wave: Hi,你好,非常感谢你对 alova 的支持,它真的很重要! + + **我们期望将 alova 打造成大家共同的项目,以开放包容的态度鼓励每位开发者成为 alova 社区的贡献者,如果你愿意,可尝试通过提交 PR 参与贡献,让你的代码为全世界的开发者提供价值,具体贡献请 [参阅贡献指南](https://github.com/alovajs/alova/blob/main/CONTRIBUTING.zh-CN.md)!** + + :warning: 在报告 Bug 前,请阅读以下内容: + - 报告前先通过 [官方文档](https://alova.js.org) 寻找解决办法。 + - 确认已搜索过 [历史 issue](https://github.com/alovajs/alova/issues),并且没有发现同样的问题。 + - 如果使用上有困惑,可移步到 [Discussions](https://github.com/alovajs/alova/discussions) 发帖讨论,这有助于作者更好地打理alova社区。 + - 可加入 [Discord](https://discord.gg/S47QGJgkVb) 或 [微信群](https://alova.js.org/img/wechat_qrcode.jpg)在线交流。 + + - type: checkboxes + id: is-this-a-bug + attributes: + label: 这是否是一个 Bug? + description: ':warning: 如果你要报告一个提案,或有使用上的困惑,请返回 Issue 新建页面查看其他选项。' + options: + - label: 我已经确认我要报告的是一个 Bug + required: true + + - type: checkboxes + id: have-been-report-before + attributes: + label: 这个问题是否已经存在? + description: ':warning: 提交前请在 Issue 中搜索你要提交的问题是否已经存在' + options: + - label: 我已经确认这个 Issue 没有被报告过 + required: true + + - type: input + id: version + attributes: + label: Alova 版本 + description: 请填写 node_modules/alova/package.json 里的版本号 + placeholder: 比如 2.9.0 + validations: + required: true + + - type: dropdown + id: framework + attributes: + label: 前端框架 + description: 请选择与这个问题相关的前端框架 + multiple: false + options: + - 'React' + - 'Vue' + - 'Svelte' + - 'Nodejs' + - 'Deno' + - 'Bun' + - '其他框架' + validations: + required: true + + - type: textarea + id: description + attributes: + label: 问题描述 + description: 详细地描述在什么情况下,遇到了什么问题。可使用 Markdown 语法提供关键代码片段。 + validations: + required: true + + - type: textarea + id: expect + attributes: + label: 期望的表现 + description: 清晰简要地描述期望达成的效果 + + - type: input + id: reproduce + attributes: + label: 复现链接 + description: | + 提供一个可复现的项目有助于解决者更快地解决问题,你可以在 [官方示例集](https://alova.js.org/category/examples/) 中选择一个作为模板。 + 也可以自行在 [codesandbox](https://codesandbox.io)、[stackBlitz](https://stackblitz.com) 中复现。 + 你也可以提供 GitHub 仓库链接。 + 请不要填写无效的链接,否则 issue 会被关闭。 + + - type: textarea + id: reproduce-steps + attributes: + label: 复现步骤 + description: 我们需要怎么做才能复现你遇到的问题?请提供一个最简单的操作步骤,方便我们快速复现问题 + placeholder: | + 例如: + 1. 点击按钮 + 2. 请求未发出 + validations: + required: true + + - type: textarea + id: browsers + attributes: + label: 系统信息 + description: 粘贴以下命令的输出:`npx envinfo --system --npmPackages "alova,vue,react,svelte" --binaries --browsers` + render: shell + placeholder: System, Binaries, Browsers + + - type: textarea + id: remark + attributes: + label: 补充说明 + description: 如出现问题的背景和其他有用上下文信息。如尝试过的解决方法 diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..0a21919 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,29 @@ +blank_issues_enabled: false +contact_links: + - name: "\U0001F680 Feature Request" + url: https://github.com/orgs/alovajs/discussions/new?category=feature-request + about: Suggest new features for consideration. + + - name: Questions & Discussions + url: https://github.com/orgs/alovajs/discussions/new?category=q-a + about: Use GitHub discussions for your questions and discussions. + + - name: "\U0001F41E Extension Bug Report" + url: https://github.com/alovajs/devtools/issues/new + about: vscode extension bug report. + + - name: "\U0001F680 Extension Feature Request" + url: https://github.com/alovajs/devtools/issues/new + about: vscode extension feature request. + + - name: Official Documentation + url: https://alova.js.org + about: Before submitting a bug, you can first look for a solution through the official documentation + + - name: Discord Chat + url: https://discord.gg/S47QGJgkVb + about: Ask questions and discuss with other users in real time. + + - name: 加入微信群 + url: https://alova.js.org/img/wechat_qrcode.jpg + about: 在微信群聊中和我们交流. diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 0000000..69e356d --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,10 @@ +# See https://github.com/actions/labeler + +'🚨 action': + - .github/workflows/** + +'wormhole': + - packages/wormhole/** + +'vscode': + - packages/vscode-extension/** diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml new file mode 100644 index 0000000..98b4d0f --- /dev/null +++ b/.github/workflows/label.yml @@ -0,0 +1,15 @@ +# Automatically labels PRs based on the configuration file +# you are probably looking for 👉 `.github/labeler.yml` +name: Label PRs + +on: + - pull_request_target + +jobs: + triage: + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v4 + with: + repo-token: '${{ secrets.GITHUB_TOKEN }}' + sync-labels: true diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 0000000..205c98d --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,43 @@ +name: pull_request check + +# trigger condition: pull_request to any branch +on: + pull_request: + paths-ignore: + - '.vscode/**' + - '**/*.md' + - '.github/**' + - '.changeset/**' + +jobs: + quality: + runs-on: ubuntu-latest + if: ${{ !contains(github.event.pull_request.head.ref, 'changeset-release') }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + persist-credentials: false + + # install pnpm version by `packageManager` in package.json + - name: Setup PNPM + uses: pnpm/action-setup@v4.0.0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + registry-url: 'https://registry.npmjs.org' + cache: 'pnpm' + + - name: Install deps + run: pnpm install + + - name: Lint check + run: pnpm run lint + + - name: Format + run: pnpm run format + + - name: Unit tests + run: pnpm run test diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..1e00545 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,74 @@ +name: Release + +# trigger condition: pull_request to any branch +on: + push: + branches: + - main + +jobs: + quality: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + persist-credentials: false + + # install pnpm version by `packageManager` in package.json + - name: Setup PNPM + uses: pnpm/action-setup@v4.0.0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + registry-url: 'https://registry.npmjs.org' + cache: 'pnpm' + + - name: Install deps + run: pnpm install + + - name: Lint check + run: pnpm run lint + + - name: Format + run: pnpm run format + + release: + runs-on: ubuntu-latest + needs: [quality] + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + persist-credentials: false + + # install pnpm version by `packageManager` in package.json + - name: Setup PNPM + uses: pnpm/action-setup@v4.0.0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + registry-url: 'https://registry.npmjs.org' + cache: 'pnpm' + + - name: Install deps + run: pnpm install + + - name: Create Release Pull Request or Publish + id: changesets + uses: changesets/action@v1.4.7 + with: + # Note: pnpm install after versioning is necessary to refresh lockfile + version: pnpm run changeset:version + publish: pnpm run release + commit: 'ci: release' + title: 'ci: release' + env: + # Needs access to push to main + GITHUB_TOKEN: ${{ secrets.ALOVA_GITHUB_TOKEN }} + # Needs access to publish to npm + NPM_TOKEN: ${{ secrets.NPM_ALOVA_PUBLISH_TOKEN }} diff --git a/.gitignore b/.gitignore index d79ebe1..67c5c1b 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,7 @@ dist *.vsix .vscode-test/ +# testing +/coverage + alova_tmp_* \ No newline at end of file diff --git a/eslint.config.mjs b/eslint.config.mjs index cb741d4..d3e7a16 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -21,7 +21,7 @@ export default [ '*.{js,mjs,cjs}', 'packages/wormhole/typings', 'design', - 'test-demos/**/*' + 'test/**/*' ] }, ...compat.extends('airbnb', 'airbnb-typescript', 'prettier'), diff --git a/package.json b/package.json index ead21da..157d7e4 100644 --- a/package.json +++ b/package.json @@ -6,18 +6,26 @@ "private": true, "engines": { "node": ">=18.19.0", - "pnpm": ">=8.6.12" + "pnpm": ">=9.1.0" }, + "packageManager": "pnpm@9.1.0", "scripts": { - "test": "vitest", + "test": "vitest run", + "test:coverage": "vitest run --coverage", "lint": "eslint", "lint:fix": "npm run lint -- --fix", "format": "prettier --check .", "format:fix": "prettier --write .", "api-test": "tsx scripts/api-test.ts", - "commit": "git-cz && git push", + "commit": "tsx scripts/bump-version.ts && git-cz && git push", "prepare": "husky", - "watch:extension": "pnpm --filter=alova-vscode-extension watch:esbuild" + "coveralls": "pnpm run test:coverage && coveralls < coverage/lcov.info", + "changeset": "changeset", + "changeset:alpha": "changeset pre enter alpha", + "changeset:beta": "changeset pre enter beta", + "changeset:pre.exit": "changeset pre exit", + "changeset:version": "changeset version", + "release": "pnpm run coveralls && changeset publish && pnpm --filter=alova-vscode-extension release" }, "license": "MIT", "repository": { @@ -32,6 +40,8 @@ "*.js,*.ts": "npm run lint:fix" }, "devDependencies": { + "@changesets/changelog-github": "^0.5.0", + "@changesets/cli": "^2.27.9", "@commitlint/cli": "^19.3.0", "@commitlint/config-conventional": "^19.2.2", "@types/js-yaml": "^4.0.9", @@ -41,7 +51,7 @@ "@types/serialize-javascript": "^5.0.4", "@typescript-eslint/eslint-plugin": "^8.13.0", "@typescript-eslint/parser": "^8.13.0", - "changeset": "^0.2.6", + "@vitest/coverage-v8": "^2.1.4", "commitizen": "^4.3.0", "cz-conventional-changelog": "^3.3.0", "dts-bundle-generator": "^9.5.1", diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index 40ee1c8..591ce86 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -47,10 +47,6 @@ "pretest": "tsc -p . --outDir out && tsx esbuild.ts", "watch-tests": "tsc -p . -w --outDir out", "check-types": "tsc --noEmit", - "lint": "eslint . --ext .js,.ts", - "lint:fix": "npm run lint -- --fix", - "format": "prettier --check .", - "format:fix": "prettier --write .", "test": "vscode-test", "pack:pre": "vsce package --no-dependencies --pre-release", "release:pre": "vsce publish --no-dependencies --pre-release", diff --git a/packages/wormhole/src/bin/cli.ts b/packages/wormhole/src/bin/cli.ts index d98f6aa..bb093b4 100644 --- a/packages/wormhole/src/bin/cli.ts +++ b/packages/wormhole/src/bin/cli.ts @@ -1,4 +1,5 @@ #!/usr/bin/env node +/* c8 ignore start */ import { Command } from 'commander'; import { actionGen, actionInit } from './actions'; @@ -22,3 +23,4 @@ program .action(actionGen); program.parse(process.argv); +/* c8 ignore stop */ diff --git a/packages/wormhole/test/__snapshots__/generate.spec.ts.snap b/packages/wormhole/test/__snapshots__/generate.spec.ts.snap index 439bf9c..183ba64 100644 --- a/packages/wormhole/test/__snapshots__/generate.spec.ts.snap +++ b/packages/wormhole/test/__snapshots__/generate.spec.ts.snap @@ -19453,6 +19453,2702 @@ declare global { " `; +exports[`generate API > should generate target versioned code 9`] = ` +"/* tslint:disable */ +/* eslint-disable */ +/** + * Swagger Generator - version 3.0.57 + * + * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, AlovaMethodCreateConfig, AlovaGenerics, Method } from 'alova'; +import type { $$userConfigMap, alovaInstance } from '.'; +import type apiDefinitions from './apiDefinitions'; + +type CollapsedAlova = typeof alovaInstance; +type UserMethodConfigMap = typeof $$userConfigMap; + +type Alova2MethodConfig = + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Omit< + AlovaMethodCreateConfig< + AlovaGenerics, + any, + Responded + >, + 'params' + > + : never; + +// Extract the return type of transform function that define in $$userConfigMap, if it not exists, use the default type. +type ExtractUserDefinedTransformed< + DefinitionKey extends keyof typeof apiDefinitions, + Default +> = DefinitionKey extends keyof UserMethodConfigMap + ? UserMethodConfigMap[DefinitionKey]['transform'] extends (...args: any[]) => any + ? Awaited> + : Default + : Default; +type Alova2Method< + Responded, + DefinitionKey extends keyof typeof apiDefinitions, + CurrentConfig extends Alova2MethodConfig +> = + CollapsedAlova extends Alova< + AlovaGenerics< + any, + any, + infer RequestConfig, + infer Response, + infer ResponseHeader, + infer L1Cache, + infer L2Cache, + infer SE + > + > + ? Method< + AlovaGenerics< + CurrentConfig extends undefined + ? ExtractUserDefinedTransformed + : CurrentConfig['transform'] extends (...args: any[]) => any + ? Awaited> + : ExtractUserDefinedTransformed, + any, + RequestConfig, + Response, + ResponseHeader, + L1Cache, + L2Cache, + SE + > + > + : never; + +export type AuthorizationValue = { + /** + * Authorization value + */ + value?: string; + /** + * Authorization key + */ + keyName?: string; + /** + * Authorization type + */ + type?: 'query' | 'header'; +}; +export type Options = { + /** + * authorization + * --- + * adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + */ + auth?: string; + /** + * authorization + * --- + * adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + */ + authorizationValue?: AuthorizationValue; + /** + * api package + * --- + * package for generated api classes + */ + apiPackage?: string; + /** + * Template Version + * --- + * template version for generation + */ + templateVersion?: string; + /** + * model package + * --- + * package for generated models + */ + modelPackage?: string; + /** + * model name prefix + * --- + * Prefix that will be prepended to all model names. Default is the empty string. + */ + modelNamePrefix?: string; + /** + * model name suffix + * --- + * PrefixSuffix that will be appended to all model names. Default is the empty string. + */ + modelNameSuffix?: string; + /** + * System Properties + * --- + * sets specified system properties in key/value format + */ + systemProperties?: Record; + /** + * instantiation types + * --- + * sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + */ + instantiationTypes?: Record; + /** + * type mappings + * --- + * sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + */ + typeMappings?: Record; + /** + * additional properties + * --- + * sets additional properties that can be referenced by the mustache templates in key/value format. + */ + additionalProperties?: Record; + /** + * language specific primitives + * --- + * specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + */ + languageSpecificPrimitives?: string[]; + /** + * import mappings + * --- + * specifies mappings between a given class and the import that should be used for that class in key/value format. + */ + importMappings?: Record; + /** + * invoker package + * --- + * root package for generated code + */ + invokerPackage?: string; + /** + * group id + * --- + * groupId in generated pom.xml + */ + groupId?: string; + /** + * artifact id + * --- + * artifactId in generated pom.xml + */ + artifactId?: string; + /** + * artifact version + * --- + * artifact version generated in pom.xml + */ + artifactVersion?: string; + /** + * library + * --- + * library template (sub-template) + */ + library?: string; + /** + * git user id + * --- + * Git user ID, e.g. swagger-api. + */ + gitUserId?: string; + /** + * git repo id + * --- + * Git repo ID, e.g. swagger-codegen. + */ + gitRepoId?: string; + /** + * release note + * --- + * Release note, default to 'Minor update'. + */ + releaseNote?: string; + /** + * http user agent + * --- + * HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + */ + httpUserAgent?: string; + /** + * reserved words mappings + * --- + * pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + */ + reservedWordsMappings?: Record; + /** + * ignore file override location + * --- + * Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + */ + ignoreFileOverride?: string; + /** + * remove prefix of the operationId + * --- + * Remove prefix of operationId, e.g. config_getId => getId + */ + removeOperationIdPrefix?: boolean; + skipOverride?: boolean; +}; +export type GenerationRequest = { + /** + * language + * --- + * language to generate (required)456 + * [required] + */ + lang: string; + /** + * spec in json format. . Alternative to \`specURL\` + */ + spec?: object; + /** + * URL of the spec in json format. Alternative to \`spec\` + */ + specURL?: string; + /** + * type of the spec + */ + type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG'; + /** + * codegen version to use + */ + codegenVersion?: 'V2' | 'V3'; + options?: Options; +}; +export type CliOption = { + optionName?: string; + description?: string; + /** + * Data type is based on the types supported by the JSON-Schema + */ + type?: string; + enum?: Record; + default?: string; +}; +export type RenderRequest = { + /** + * template + * --- + * template as string + * [required] + */ + template: string; + /** + * context + * --- + * context as string + * [required] + */ + context: string; +}; +declare global { + interface Apis { + clients: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'client' or 'documentation' for given codegen version (defaults to V3) + * + * **path:** /clients + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * // flag to only return languages of type \`client\` + * clientOnly?: boolean + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + clientLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + /** + * flag to only return languages of type \`client\` + */ + clientOnly?: boolean; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'clients.listOptions', Config>; + /** + * --- + * + * [POST] 你好Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + servers: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'server' for given codegen version (defaults to V3) + * + * **path:** /servers + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + serverLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'servers.listOptions', Config>; + /** + * --- + * + * [POST] 你好Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + documentation: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'client' or 'documentation' for given codegen version (defaults to V3) + * + * **path:** /clients + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * // flag to only return languages of type \`client\` + * clientOnly?: boolean + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + clientLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + /** + * flag to only return languages of type \`client\` + */ + clientOnly?: boolean; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Deprecated, use '/{type}/{version}' instead. List generator languages of type 'documentation' for given codegen version (defaults to V3) + * + * **path:** /documentation + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + documentationLanguages< + Config extends Alova2MethodConfig & { + params: { + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'documentation.listOptions', Config>; + /** + * --- + * + * [POST] 你好Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] render a template using the provided data + * + * **path:** /render + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] template + * // template as string + * // [required] + * template: string + * // [title] context + * // context as string + * // [required] + * context: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = unknown + * \`\`\` + */ + renderTemplate< + Config extends Alova2MethodConfig & { + data: RenderRequest; + } + >( + config: Config + ): Alova2Method; + }; + config: { + /** + * --- + * + * [GET] Generates and download code. GenerationRequest input provided as JSON available at URL specified in parameter codegenOptionsURL. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateFromURL< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] Generates and download code. GenerationRequest input provided as request body. + * + * **path:** /generate + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // [required] + * codegenOptionsURL: string + * } + * \`\`\` + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generate< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of the given type and version + * + * **path:** /{type}/{version} + * + * --- + * + * **Path Parameters** + * \`\`\`ts + * type PathParameters = { + * // generator type + * // [required] + * type: 'client' | 'server' | 'documentation' | 'config' + * // generator version used by codegen engine + * // [required] + * version: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languages< + Config extends Alova2MethodConfig & { + pathParams: { + /** + * generator type + * [required] + */ + type: 'client' | 'server' | 'documentation' | 'config'; + /** + * generator version used by codegen engine + * [required] + */ + version: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages + * + * **path:** /types + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // comma-separated list of generator types + * // [required] + * types: ('client' | 'server' | 'documentation' | 'config')[] + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + languagesMulti< + Config extends Alova2MethodConfig & { + params: { + /** + * comma-separated list of generator types + * [required] + */ + types: ('client' | 'server' | 'documentation' | 'config')[]; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] Returns options for a given language and version (defaults to V3) + * + * **path:** /options + * + * --- + * + * **Query Parameters** + * \`\`\`ts + * type QueryParameters = { + * // language + * language?: string + * // generator version used by codegen engine + * version?: 'V2' | 'V3' + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = Record< + * string, + * { + * optionName?: string + * description?: string + * // Data type is based on the types supported by the JSON-Schema + * type?: string + * enum?: Record + * default?: string + * } + * > + * \`\`\` + */ + listOptions< + Config extends Alova2MethodConfig> & { + params: { + /** + * language + */ + language?: string; + /** + * generator version used by codegen engine + */ + version?: 'V2' | 'V3'; + }; + } + >( + config: Config + ): Alova2Method, 'config.listOptions', Config>; + /** + * --- + * + * [POST] 你好Generates the intermediate model ("bundle") and returns it as a JSON. body. + * + * **path:** /model + * + * --- + * + * **RequestBody** + * \`\`\`ts + * type RequestBody = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + * + * --- + * + * **Response** + * \`\`\`ts + * type Response = { + * // [title] language + * // language to generate (required)456 + * // [required] + * lang: string + * // spec in json format. . Alternative to \`specURL\` + * spec?: object + * // URL of the spec in json format. Alternative to \`spec\` + * specURL?: string + * // type of the spec + * type?: 'CLIENT' | 'SERVER' | 'DOCUMENTATION' | 'CONFIG' + * // codegen version to use + * codegenVersion?: 'V2' | 'V3' + * options?: { + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + * auth?: string + * // [title] authorization + * // adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object + * authorizationValue?: { + * // Authorization value + * value?: string + * // Authorization key + * keyName?: string + * // Authorization type + * type?: 'query' | 'header' + * } + * // [title] api package + * // package for generated api classes + * apiPackage?: string + * // [title] Template Version + * // template version for generation + * templateVersion?: string + * // [title] model package + * // package for generated models + * modelPackage?: string + * // [title] model name prefix + * // Prefix that will be prepended to all model names. Default is the empty string. + * modelNamePrefix?: string + * // [title] model name suffix + * // PrefixSuffix that will be appended to all model names. Default is the empty string. + * modelNameSuffix?: string + * // [title] System Properties + * // sets specified system properties in key/value format + * systemProperties?: Record + * // [title] instantiation types + * // sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code. + * instantiationTypes?: Record + * // [title] type mappings + * // sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String. + * typeMappings?: Record + * // [title] additional properties + * // sets additional properties that can be referenced by the mustache templates in key/value format. + * additionalProperties?: Record + * // [title] language specific primitives + * // specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option. + * languageSpecificPrimitives?: string[] + * // [title] import mappings + * // specifies mappings between a given class and the import that should be used for that class in key/value format. + * importMappings?: Record + * // [title] invoker package + * // root package for generated code + * invokerPackage?: string + * // [title] group id + * // groupId in generated pom.xml + * groupId?: string + * // [title] artifact id + * // artifactId in generated pom.xml + * artifactId?: string + * // [title] artifact version + * // artifact version generated in pom.xml + * artifactVersion?: string + * // [title] library + * // library template (sub-template) + * library?: string + * // [title] git user id + * // Git user ID, e.g. swagger-api. + * gitUserId?: string + * // [title] git repo id + * // Git repo ID, e.g. swagger-codegen. + * gitRepoId?: string + * // [title] release note + * // Release note, default to 'Minor update'. + * releaseNote?: string + * // [title] http user agent + * // HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}' + * httpUserAgent?: string + * // [title] reserved words mappings + * // pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier. + * reservedWordsMappings?: Record + * // [title] ignore file override location + * // Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation. + * ignoreFileOverride?: string + * // [title] remove prefix of the operationId + * // Remove prefix of operationId, e.g. config_getId => getId + * removeOperationIdPrefix?: boolean + * skipOverride?: boolean + * } + * } + * \`\`\` + */ + generateBundle< + Config extends Alova2MethodConfig & { + data: GenerationRequest; + } + >( + config: Config + ): Alova2Method; + }; + } + + var Apis: Apis; +} +" +`; + exports[`generate API > should generate the existing \`mediaType\` if the target \`mediaType\` is not matched 1`] = ` "/// /* tslint:disable */ diff --git a/packages/wormhole/tsconfig.json b/packages/wormhole/tsconfig.json index fd2813e..d93a154 100644 --- a/packages/wormhole/tsconfig.json +++ b/packages/wormhole/tsconfig.json @@ -12,5 +12,5 @@ "#/*": ["./*"] } }, - "include": ["src/**/*.ts", "test/**/*", "./*.ts", "typings/**/*.d.ts", "./scripts/**/*"] + "include": ["src/**/*.ts", "test/**/*", "./*.ts", "typings/**/*.d.ts", "./scripts/**/*", "vitest.config.mts"] } diff --git a/packages/wormhole/vitest.config.ts b/packages/wormhole/vitest.config.mts similarity index 100% rename from packages/wormhole/vitest.config.ts rename to packages/wormhole/vitest.config.mts diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bac1e2b..7bc63d6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,6 +15,12 @@ importers: specifier: ^15.12.0 version: 15.12.0 devDependencies: + '@changesets/changelog-github': + specifier: ^0.5.0 + version: 0.5.0 + '@changesets/cli': + specifier: ^2.27.9 + version: 2.27.9 '@commitlint/cli': specifier: ^19.3.0 version: 19.5.0(@types/node@18.19.64)(typescript@5.6.3) @@ -42,9 +48,9 @@ importers: '@typescript-eslint/parser': specifier: ^8.13.0 version: 8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.3) - changeset: - specifier: ^0.2.6 - version: 0.2.6 + '@vitest/coverage-v8': + specifier: ^2.1.4 + version: 2.1.4(vitest@2.1.4(@types/node@18.19.64)) commitizen: specifier: ^4.3.0 version: 4.3.1(@types/node@18.19.64)(typescript@5.6.3) @@ -330,6 +336,10 @@ packages: resolution: {integrity: sha512-5mROBgzhWtb1RH/Psc+KqT4CeVYMErVAPooa4p8eF6Q0R4JPSJPsu5s+hZm3ynYErVO16NdvroqIO9H3zkEXfQ==} hasBin: true + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + '@azure/abort-controller@2.1.2': resolution: {integrity: sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==} engines: {node: '>=18.0.0'} @@ -391,6 +401,10 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/runtime@7.26.0': + resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} + engines: {node: '>=6.9.0'} + '@babel/types@7.26.0': resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} engines: {node: '>=6.9.0'} @@ -398,6 +412,67 @@ packages: '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + '@changesets/apply-release-plan@7.0.5': + resolution: {integrity: sha512-1cWCk+ZshEkSVEZrm2fSj1Gz8sYvxgUL4Q78+1ZZqeqfuevPTPk033/yUZ3df8BKMohkqqHfzj0HOOrG0KtXTw==} + + '@changesets/assemble-release-plan@6.0.4': + resolution: {integrity: sha512-nqICnvmrwWj4w2x0fOhVj2QEGdlUuwVAwESrUo5HLzWMI1rE5SWfsr9ln+rDqWB6RQ2ZyaMZHUcU7/IRaUJS+Q==} + + '@changesets/changelog-git@0.2.0': + resolution: {integrity: sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==} + + '@changesets/changelog-github@0.5.0': + resolution: {integrity: sha512-zoeq2LJJVcPJcIotHRJEEA2qCqX0AQIeFE+L21L8sRLPVqDhSXY8ZWAt2sohtBpFZkBwu+LUwMSKRr2lMy3LJA==} + + '@changesets/cli@2.27.9': + resolution: {integrity: sha512-q42a/ZbDnxPpCb5Wkm6tMVIxgeI9C/bexntzTeCFBrQEdpisQqk8kCHllYZMDjYtEc1ZzumbMJAG8H0Z4rdvjg==} + hasBin: true + + '@changesets/config@3.0.3': + resolution: {integrity: sha512-vqgQZMyIcuIpw9nqFIpTSNyc/wgm/Lu1zKN5vECy74u95Qx/Wa9g27HdgO4NkVAaq+BGA8wUc/qvbvVNs93n6A==} + + '@changesets/errors@0.2.0': + resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} + + '@changesets/get-dependents-graph@2.1.2': + resolution: {integrity: sha512-sgcHRkiBY9i4zWYBwlVyAjEM9sAzs4wYVwJUdnbDLnVG3QwAaia1Mk5P8M7kraTOZN+vBET7n8KyB0YXCbFRLQ==} + + '@changesets/get-github-info@0.6.0': + resolution: {integrity: sha512-v/TSnFVXI8vzX9/w3DU2Ol+UlTZcu3m0kXTjTT4KlAdwSvwutcByYwyYn9hwerPWfPkT2JfpoX0KgvCEi8Q/SA==} + + '@changesets/get-release-plan@4.0.4': + resolution: {integrity: sha512-SicG/S67JmPTrdcc9Vpu0wSQt7IiuN0dc8iR5VScnnTVPfIaLvKmEGRvIaF0kcn8u5ZqLbormZNTO77bCEvyWw==} + + '@changesets/get-version-range-type@0.4.0': + resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} + + '@changesets/git@3.0.1': + resolution: {integrity: sha512-pdgHcYBLCPcLd82aRcuO0kxCDbw/yISlOtkmwmE8Odo1L6hSiZrBOsRl84eYG7DRCab/iHnOkWqExqc4wxk2LQ==} + + '@changesets/logger@0.1.1': + resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} + + '@changesets/parse@0.4.0': + resolution: {integrity: sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==} + + '@changesets/pre@2.0.1': + resolution: {integrity: sha512-vvBJ/If4jKM4tPz9JdY2kGOgWmCowUYOi5Ycv8dyLnEE8FgpYYUo1mgJZxcdtGGP3aG8rAQulGLyyXGSLkIMTQ==} + + '@changesets/read@0.6.1': + resolution: {integrity: sha512-jYMbyXQk3nwP25nRzQQGa1nKLY0KfoOV7VLgwucI0bUO8t8ZLCr6LZmgjXsiKuRDc+5A6doKPr9w2d+FEJ55zQ==} + + '@changesets/should-skip-package@0.1.1': + resolution: {integrity: sha512-H9LjLbF6mMHLtJIc/eHR9Na+MifJ3VxtgP/Y+XLn4BF7tDTEN1HNYtH6QMcjP1uxp9sjaFYmW8xqloaCi/ckTg==} + + '@changesets/types@4.1.0': + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + + '@changesets/types@6.0.0': + resolution: {integrity: sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==} + + '@changesets/write@0.3.2': + resolution: {integrity: sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==} + '@commitlint/cli@19.5.0': resolution: {integrity: sha512-gaGqSliGwB86MDmAAKAtV9SV1SHdmN8pnGq4EJU4+hLisQ7IFfx4jvU4s+pk6tl0+9bv6yT+CaZkufOinkSJIQ==} engines: {node: '>=v18'} @@ -962,10 +1037,18 @@ packages: resolution: {integrity: sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==} engines: {node: '>= 10.14.2'} + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} @@ -990,6 +1073,12 @@ packages: peerDependencies: tslib: '2' + '@manypkg/find-root@1.1.0': + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + + '@manypkg/get-packages@1.1.3': + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -1163,6 +1252,9 @@ packages: '@types/mocha@10.0.9': resolution: {integrity: sha512-sicdRoWtYevwxjOHNMPTl3vSfJM6oyW8o1wXeI7uww6b6xHg8eBznQDNSGBCDJmsE8UMxP05JgZRtsKbTqt//Q==} + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + '@types/node@18.19.64': resolution: {integrity: sha512-955mDqvO2vFf/oL7V3WiUtiz+BugyX8uVbaT2H8oj3+8dRyH2FLiNdowe7eNqRM7IOIZvzDH76EoAT+gwm6aIQ==} @@ -1251,6 +1343,15 @@ packages: resolution: {integrity: sha512-7N/+lztJqH4Mrf0lb10R/CbI1EaAMMGyF5y0oJvFoAhafwgiRA7TXyd8TFn8FC8k5y2dTsYogg238qavRGNnlw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@vitest/coverage-v8@2.1.4': + resolution: {integrity: sha512-FPKQuJfR6VTfcNMcGpqInmtJuVXFSCd9HQltYncfR01AzXhLucMEtQ5SinPdZxsT5x/5BK7I5qFJ5/ApGCmyTQ==} + peerDependencies: + '@vitest/browser': 2.1.4 + vitest: 2.1.4 + peerDependenciesMeta: + '@vitest/browser': + optional: true + '@vitest/expect@2.1.4': resolution: {integrity: sha512-DOETT0Oh1avie/D/o2sgMHGrzYUFFo3zqESB2Hn70z6QB1HrS2IQ9z5DfyTqU8sg4Bpu13zZe9V4+UTNQlUeQA==} @@ -1531,6 +1632,10 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -1622,9 +1727,6 @@ packages: change-case@4.1.2: resolution: {integrity: sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==} - changeset@0.2.6: - resolution: {integrity: sha512-d21ym9zLPOKMVhIa8ulJo5IV3QR2NNdK6BWuwg48qJA0XSQaMeDjo1UGThcTn7YDmU08j3UpKyFNvb3zplk8mw==} - chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} @@ -1646,6 +1748,10 @@ packages: chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + cli-cursor@3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -1777,6 +1883,9 @@ packages: typescript: optional: true + cross-spawn@5.1.0: + resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} + cross-spawn@6.0.5: resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} engines: {node: '>=4.8'} @@ -1818,6 +1927,9 @@ packages: resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} engines: {node: '>= 0.4'} + dataloader@1.4.0: + resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} + debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -1928,6 +2040,10 @@ packages: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} engines: {node: '>=8'} + dotenv@8.6.0: + resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==} + engines: {node: '>=10'} + dts-bundle-generator@9.5.1: resolution: {integrity: sha512-DxpJOb2FNnEyOzMkG11sxO2dmxPjthoVWxfKqWYJ/bI/rT1rvTMktF5EKjAYrRZu6Z6t3NhOUZ0sZ5ZXevOfbA==} engines: {node: '>=14.0.0'} @@ -1958,6 +2074,10 @@ packages: resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} engines: {node: '>=10.13.0'} + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + entities@2.1.0: resolution: {integrity: sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==} @@ -2212,6 +2332,9 @@ packages: resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} engines: {node: '>=12.0.0'} + extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + external-editor@3.1.0: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} engines: {node: '>=4'} @@ -2262,6 +2385,10 @@ packages: find-root@1.1.0: resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -2303,6 +2430,14 @@ packages: resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} engines: {node: '>=14.14'} + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + fs-extra@9.1.0: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} @@ -2489,6 +2624,9 @@ packages: resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==} engines: {node: '>= 14'} + human-id@1.0.2: + resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} + human-signals@5.0.0: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} @@ -2675,6 +2813,10 @@ packages: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} + is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + is-symbol@1.0.4: resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} engines: {node: '>= 0.4'} @@ -2737,6 +2879,10 @@ packages: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} + istanbul-lib-source-maps@5.0.6: + resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} + engines: {node: '>=10'} + istanbul-reports@3.1.7: resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} engines: {node: '>=8'} @@ -2800,6 +2946,9 @@ packages: jsonc-parser@3.3.1: resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} @@ -2880,6 +3029,10 @@ packages: resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} engines: {node: '>=4'} + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -2975,6 +3128,9 @@ packages: resolution: {integrity: sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==} engines: {node: 20 || >=22} + lru-cache@4.1.5: + resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} + lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} @@ -2982,6 +3138,9 @@ packages: magic-string@0.30.12: resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} + magicast@0.3.5: + resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} + make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} @@ -3081,6 +3240,10 @@ packages: engines: {node: '>= 14.0.0'} hasBin: true + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -3254,6 +3417,17 @@ packages: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} + outdent@0.5.0: + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + + p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -3262,6 +3436,10 @@ packages: resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} @@ -3270,9 +3448,20 @@ packages: resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + package-manager-detector@0.2.2: + resolution: {integrity: sha512-VgXbyrSNsml4eHWIvxxG/nTL4wgybMTXCV2Un/+yEc3aDKKU6nQBZjbeP3Pl3qm9Qg92X/1ng4ffvCeD/zwHgg==} + pako@1.0.11: resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} @@ -3391,6 +3580,10 @@ packages: resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} engines: {node: '>=4'} + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + plimit-lit@1.6.1: resolution: {integrity: sha512-B7+VDyb8Tl6oMJT9oSO2CW8XC/T4UcJGrwOVoNGwOQsQYhlpfajmrMj5xeejqaASq3V/EqThyOeATEOMuSEXiA==} engines: {node: '>=12'} @@ -3435,6 +3628,11 @@ packages: peerDependencies: prettier: ^3.0.0 + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + prettier@3.3.3: resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} engines: {node: '>=14'} @@ -3450,6 +3648,9 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + pseudomap@1.0.2: + resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} + pump@3.0.2: resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} @@ -3491,6 +3692,10 @@ packages: resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} engines: {node: '>=4'} + read-yaml-file@1.1.0: + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} + engines: {node: '>=6'} + read@1.0.7: resolution: {integrity: sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==} engines: {node: '>=0.8'} @@ -3513,6 +3718,9 @@ packages: reftools@1.1.9: resolution: {integrity: sha512-OVede/NQE13xBQ+ob5CKd5KyeJYU2YInb1bmV4nRoOfquZPkAkxuOXicSe1PvqIuZZ4kD13sPKBbR7UFDmli6w==} + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + regexp.prototype.flags@1.5.3: resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} engines: {node: '>= 0.4'} @@ -3723,6 +3931,9 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + spawndamnit@2.0.0: + resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==} + spdx-correct@3.2.0: resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} @@ -3875,10 +4086,18 @@ packages: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} + term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + test-exclude@6.0.0: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} + test-exclude@7.0.1: + resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} + engines: {node: '>=18'} + text-extensions@2.4.0: resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==} engines: {node: '>=8'} @@ -4009,9 +4228,6 @@ packages: uc.micro@1.0.6: resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} - udc@1.0.1: - resolution: {integrity: sha512-jv+D9de1flsum5QkFtBdjyppCQAdz9kTck/0xST5Vx48T9LL2BYnw0Iw77dSKDQ9KZ/PS3qPO1vfXHDpLZlxcQ==} - uglify-js@3.19.3: resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} engines: {node: '>=0.8.0'} @@ -4034,6 +4250,10 @@ packages: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} engines: {node: '>=18'} + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} @@ -4219,6 +4439,9 @@ packages: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} + yallist@2.1.2: + resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} + yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} @@ -4304,6 +4527,11 @@ snapshots: transitivePeerDependencies: - encoding + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + '@azure/abort-controller@2.1.2': dependencies: tslib: 2.8.1 @@ -4397,6 +4625,10 @@ snapshots: dependencies: '@babel/types': 7.26.0 + '@babel/runtime@7.26.0': + dependencies: + regenerator-runtime: 0.14.1 + '@babel/types@7.26.0': dependencies: '@babel/helper-string-parser': 7.25.9 @@ -4404,6 +4636,163 @@ snapshots: '@bcoe/v8-coverage@0.2.3': {} + '@changesets/apply-release-plan@7.0.5': + dependencies: + '@changesets/config': 3.0.3 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.1 + '@changesets/should-skip-package': 0.1.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.6.3 + + '@changesets/assemble-release-plan@6.0.4': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/should-skip-package': 0.1.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + semver: 7.6.3 + + '@changesets/changelog-git@0.2.0': + dependencies: + '@changesets/types': 6.0.0 + + '@changesets/changelog-github@0.5.0': + dependencies: + '@changesets/get-github-info': 0.6.0 + '@changesets/types': 6.0.0 + dotenv: 8.6.0 + transitivePeerDependencies: + - encoding + + '@changesets/cli@2.27.9': + dependencies: + '@changesets/apply-release-plan': 7.0.5 + '@changesets/assemble-release-plan': 6.0.4 + '@changesets/changelog-git': 0.2.0 + '@changesets/config': 3.0.3 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/get-release-plan': 4.0.4 + '@changesets/git': 3.0.1 + '@changesets/logger': 0.1.1 + '@changesets/pre': 2.0.1 + '@changesets/read': 0.6.1 + '@changesets/should-skip-package': 0.1.1 + '@changesets/types': 6.0.0 + '@changesets/write': 0.3.2 + '@manypkg/get-packages': 1.1.3 + ansi-colors: 4.1.3 + ci-info: 3.9.0 + enquirer: 2.4.1 + external-editor: 3.1.0 + fs-extra: 7.0.1 + mri: 1.2.0 + p-limit: 2.3.0 + package-manager-detector: 0.2.2 + picocolors: 1.1.1 + resolve-from: 5.0.0 + semver: 7.6.3 + spawndamnit: 2.0.0 + term-size: 2.2.1 + + '@changesets/config@3.0.3': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/logger': 0.1.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.8 + + '@changesets/errors@0.2.0': + dependencies: + extendable-error: 0.1.7 + + '@changesets/get-dependents-graph@2.1.2': + dependencies: + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + picocolors: 1.1.1 + semver: 7.6.3 + + '@changesets/get-github-info@0.6.0': + dependencies: + dataloader: 1.4.0 + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + + '@changesets/get-release-plan@4.0.4': + dependencies: + '@changesets/assemble-release-plan': 6.0.4 + '@changesets/config': 3.0.3 + '@changesets/pre': 2.0.1 + '@changesets/read': 0.6.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/get-version-range-type@0.4.0': {} + + '@changesets/git@3.0.1': + dependencies: + '@changesets/errors': 0.2.0 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.8 + spawndamnit: 2.0.0 + + '@changesets/logger@0.1.1': + dependencies: + picocolors: 1.1.1 + + '@changesets/parse@0.4.0': + dependencies: + '@changesets/types': 6.0.0 + js-yaml: 3.14.1 + + '@changesets/pre@2.0.1': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + + '@changesets/read@0.6.1': + dependencies: + '@changesets/git': 3.0.1 + '@changesets/logger': 0.1.1 + '@changesets/parse': 0.4.0 + '@changesets/types': 6.0.0 + fs-extra: 7.0.1 + p-filter: 2.1.0 + picocolors: 1.1.1 + + '@changesets/should-skip-package@0.1.1': + dependencies: + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/types@4.1.0': {} + + '@changesets/types@6.0.0': {} + + '@changesets/write@0.3.2': + dependencies: + '@changesets/types': 6.0.0 + fs-extra: 7.0.1 + human-id: 1.0.2 + prettier: 2.8.8 + '@commitlint/cli@19.5.0(@types/node@18.19.64)(typescript@5.6.3)': dependencies: '@commitlint/format': 19.5.0 @@ -4800,8 +5189,16 @@ snapshots: '@types/yargs': 15.0.19 chalk: 4.1.2 + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/resolve-uri@3.1.2': {} + '@jridgewell/set-array@1.2.1': {} + '@jridgewell/sourcemap-codec@1.5.0': {} '@jridgewell/trace-mapping@0.3.25': @@ -4825,6 +5222,22 @@ snapshots: dependencies: tslib: 2.8.1 + '@manypkg/find-root@1.1.0': + dependencies: + '@babel/runtime': 7.26.0 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + + '@manypkg/get-packages@1.1.3': + dependencies: + '@babel/runtime': 7.26.0 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -4954,6 +5367,8 @@ snapshots: '@types/mocha@10.0.9': {} + '@types/node@12.20.55': {} + '@types/node@18.19.64': dependencies: undici-types: 5.26.5 @@ -5066,6 +5481,24 @@ snapshots: '@typescript-eslint/types': 8.13.0 eslint-visitor-keys: 3.4.3 + '@vitest/coverage-v8@2.1.4(vitest@2.1.4(@types/node@18.19.64))': + dependencies: + '@ampproject/remapping': 2.3.0 + '@bcoe/v8-coverage': 0.2.3 + debug: 4.3.7(supports-color@8.1.1) + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.1.7 + magic-string: 0.30.12 + magicast: 0.3.5 + std-env: 3.7.0 + test-exclude: 7.0.1 + tinyrainbow: 1.2.0 + vitest: 2.1.4(@types/node@18.19.64) + transitivePeerDependencies: + - supports-color + '@vitest/expect@2.1.4': dependencies: '@vitest/spy': 2.1.4 @@ -5430,6 +5863,10 @@ snapshots: base64-js@1.5.1: {} + better-path-resolve@1.0.0: + dependencies: + is-windows: 1.0.2 + binary-extensions@2.3.0: {} bl@4.1.0: @@ -5554,11 +5991,6 @@ snapshots: snake-case: 3.0.4 tslib: 2.8.1 - changeset@0.2.6: - dependencies: - udc: 1.0.1 - underscore: 1.13.7 - chardet@0.7.0: {} check-error@2.1.1: {} @@ -5601,6 +6033,8 @@ snapshots: chownr@1.1.4: optional: true + ci-info@3.9.0: {} + cli-cursor@3.1.0: dependencies: restore-cursor: 3.1.0 @@ -5742,6 +6176,12 @@ snapshots: optionalDependencies: typescript: 5.6.3 + cross-spawn@5.1.0: + dependencies: + lru-cache: 4.1.5 + shebang-command: 1.2.0 + which: 1.3.1 + cross-spawn@6.0.5: dependencies: nice-try: 1.0.5 @@ -5804,6 +6244,8 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.1 + dataloader@1.4.0: {} + debug@3.2.7: dependencies: ms: 2.1.3 @@ -5898,6 +6340,8 @@ snapshots: dependencies: is-obj: 2.0.0 + dotenv@8.6.0: {} + dts-bundle-generator@9.5.1: dependencies: typescript: 5.6.3 @@ -5930,6 +6374,11 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.2.1 + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + entities@2.1.0: {} entities@4.5.0: {} @@ -6361,6 +6810,8 @@ snapshots: expect-type@1.1.0: {} + extendable-error@0.1.7: {} + external-editor@3.1.0: dependencies: chardet: 0.7.0 @@ -6414,6 +6865,11 @@ snapshots: find-root@1.1.0: {} + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + find-up@5.0.0: dependencies: locate-path: 6.0.0 @@ -6465,6 +6921,18 @@ snapshots: jsonfile: 6.1.0 universalify: 2.0.1 + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + fs-extra@9.1.0: dependencies: at-least-node: 1.0.0 @@ -6681,6 +7149,8 @@ snapshots: transitivePeerDependencies: - supports-color + human-id@1.0.2: {} + human-signals@5.0.0: {} husky@9.1.6: {} @@ -6842,6 +7312,10 @@ snapshots: dependencies: has-tostringtag: 1.0.2 + is-subdir@1.2.0: + dependencies: + better-path-resolve: 1.0.0 + is-symbol@1.0.4: dependencies: has-symbols: 1.0.3 @@ -6893,6 +7367,14 @@ snapshots: make-dir: 4.0.0 supports-color: 7.2.0 + istanbul-lib-source-maps@5.0.6: + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + debug: 4.3.7(supports-color@8.1.1) + istanbul-lib-coverage: 3.2.2 + transitivePeerDependencies: + - supports-color + istanbul-reports@3.1.7: dependencies: html-escaper: 2.0.2 @@ -6956,6 +7438,10 @@ snapshots: jsonc-parser@3.3.1: {} + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + jsonfile@6.1.0: dependencies: universalify: 2.0.1 @@ -7081,6 +7567,10 @@ snapshots: pify: 3.0.0 strip-bom: 3.0.0 + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + locate-path@6.0.0: dependencies: p-locate: 5.0.0 @@ -7159,6 +7649,11 @@ snapshots: lru-cache@11.0.2: {} + lru-cache@4.1.5: + dependencies: + pseudomap: 1.0.2 + yallist: 2.1.2 + lru-cache@6.0.0: dependencies: yallist: 4.0.0 @@ -7167,6 +7662,12 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 + magicast@0.3.5: + dependencies: + '@babel/parser': 7.26.2 + '@babel/types': 7.26.0 + source-map-js: 1.2.1 + make-dir@4.0.0: dependencies: semver: 7.6.3 @@ -7268,6 +7769,8 @@ snapshots: yargs-parser: 20.2.9 yargs-unparser: 2.0.0 + mri@1.2.0: {} + ms@2.1.3: {} mute-stream@0.0.8: {} @@ -7493,6 +7996,16 @@ snapshots: os-tmpdir@1.0.2: {} + outdent@0.5.0: {} + + p-filter@2.1.0: + dependencies: + p-map: 2.1.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 @@ -7501,6 +8014,10 @@ snapshots: dependencies: yocto-queue: 1.1.1 + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + p-locate@5.0.0: dependencies: p-limit: 3.1.0 @@ -7509,8 +8026,14 @@ snapshots: dependencies: p-limit: 4.0.0 + p-map@2.1.0: {} + + p-try@2.2.0: {} + package-json-from-dist@1.0.1: {} + package-manager-detector@0.2.2: {} + pako@1.0.11: {} param-case@3.0.4: @@ -7611,6 +8134,8 @@ snapshots: pify@3.0.0: {} + pify@4.0.1: {} + plimit-lit@1.6.1: dependencies: queue-lit: 1.5.2 @@ -7654,6 +8179,8 @@ snapshots: dependencies: prettier: 3.3.3 + prettier@2.8.8: {} + prettier@3.3.3: {} pretty-format@26.6.2: @@ -7671,6 +8198,8 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 + pseudomap@1.0.2: {} + pump@3.0.2: dependencies: end-of-stream: 1.4.4 @@ -7713,6 +8242,13 @@ snapshots: normalize-package-data: 2.5.0 path-type: 3.0.0 + read-yaml-file@1.1.0: + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.1 + pify: 4.0.1 + strip-bom: 3.0.0 + read@1.0.7: dependencies: mute-stream: 0.0.8 @@ -7749,6 +8285,8 @@ snapshots: reftools@1.1.9: {} + regenerator-runtime@0.14.1: {} + regexp.prototype.flags@1.5.3: dependencies: call-bind: 1.0.7 @@ -7991,6 +8529,11 @@ snapshots: source-map@0.6.1: {} + spawndamnit@2.0.0: + dependencies: + cross-spawn: 5.1.0 + signal-exit: 3.0.7 + spdx-correct@3.2.0: dependencies: spdx-expression-parse: 3.0.1 @@ -8180,12 +8723,20 @@ snapshots: readable-stream: 3.6.2 optional: true + term-size@2.2.1: {} + test-exclude@6.0.0: dependencies: '@istanbuljs/schema': 0.1.3 glob: 7.2.3 minimatch: 3.1.2 + test-exclude@7.0.1: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 10.4.5 + minimatch: 9.0.5 + text-extensions@2.4.0: {} text-table@0.2.0: {} @@ -8312,8 +8863,6 @@ snapshots: uc.micro@1.0.6: {} - udc@1.0.1: {} - uglify-js@3.19.3: optional: true @@ -8332,6 +8881,8 @@ snapshots: unicorn-magic@0.1.0: {} + universalify@0.1.2: {} + universalify@2.0.1: {} upper-case-first@2.0.2: @@ -8542,6 +9093,8 @@ snapshots: y18n@5.0.8: {} + yallist@2.1.2: {} + yallist@4.0.0: {} yaml@1.10.2: {} diff --git a/scripts/bump-version.ts b/scripts/bump-version.ts new file mode 100644 index 0000000..e75e097 --- /dev/null +++ b/scripts/bump-version.ts @@ -0,0 +1,52 @@ +import { exec, spawn } from 'node:child_process'; +import readline from 'node:readline'; + +// Create readline interface instance +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}); + +// Ask the user whether to execute changeset +function askConfirmation(query: string) { + return new Promise(resolve => { + rl.question(query, answer => { + answer = answer || 'y'; + resolve(answer.toLowerCase() === 'y'); + }); + }); +} + +// Run the specified shell command +function runCommand(command: string) { + return new Promise((resolve, reject) => { + const childProcess = exec(command, (error, stdout, stderr) => { + if (error) { + reject(error); + } + resolve(stdout || stderr); + }); + childProcess.stdout?.pipe(process.stdout); + childProcess.stderr?.pipe(process.stderr); + }); +} + +async function main() { + // Ask questions and process answers + const confirm = await askConfirmation('❓Do you need to bump a version?(Y/n)').finally(() => { + rl.close(); + }); + if (confirm) { + // Run the pnpm changeset command + const changesetProcess = spawn('pnpm', ['changeset'], { stdio: 'inherit', shell: true }); + await new Promise(resolve => { + changesetProcess.on('close', async code => { + resolve(code); + }); + }); + const changesetPath = '.changeset'; + await runCommand(`git add ${changesetPath}`); + } +} + +main(); diff --git a/tsconfig.json b/tsconfig.json index 3a4c96d..e952ffc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,5 +6,12 @@ "moduleResolution": "node", "resolveJsonModule": true }, - "include": ["*.*js", "packages/**/*.ts", "*.*ts", "scripts/**.*", "typings/**/*.d.ts"] + "include": [ + "*.*js", + "packages/**/*.ts", + "*.*ts", + "scripts/**.*", + "typings/**/*.d.ts", + "packages/wormhole/vitest.config.mts" + ] } diff --git a/vitest.config.mts b/vitest.config.mts new file mode 100644 index 0000000..70b9d66 --- /dev/null +++ b/vitest.config.mts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + coverage: { + include: ['packages/wormhole/src/**/*'], + reporter: ['lcov', 'html'] + } + } +}); diff --git a/vitest.workspace.ts b/vitest.workspace.ts index ab45296..8371803 100644 --- a/vitest.workspace.ts +++ b/vitest.workspace.ts @@ -1,3 +1,3 @@ import { defineWorkspace } from 'vitest/config'; -export default defineWorkspace(['packages/*/vitest.config.ts']); +export default defineWorkspace(['packages/*/vitest.config.ts', 'packages/*/vitest.config.mts']); From e7baff4a2058dfa87accd5a4de245ee420fa384a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E9=95=87?= Date: Thu, 7 Nov 2024 16:23:17 +0800 Subject: [PATCH 39/47] ci: add secret VSCE_PAT to env --- .github/workflows/release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1e00545..b33df43 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -72,3 +72,5 @@ jobs: GITHUB_TOKEN: ${{ secrets.ALOVA_GITHUB_TOKEN }} # Needs access to publish to npm NPM_TOKEN: ${{ secrets.NPM_ALOVA_PUBLISH_TOKEN }} + # publish vscode extension to marketplace + VSCE_PAT: ${{ secrets.VSCODE_EXTENSION_TOKEN }} From a9f2f74a828b80d29e5df3da2576a533d33c0c11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E9=95=87?= Date: Thu, 7 Nov 2024 16:27:39 +0800 Subject: [PATCH 40/47] test: correct test error --- .github/ISSUE_TEMPLATE/01.bug_report.yml | 115 ------------------ .../ISSUE_TEMPLATE/02.bug_report_zh-CN.yml | 115 ------------------ .github/ISSUE_TEMPLATE/config.yml | 29 ----- packages/wormhole/test/config.spec.ts | 2 +- 4 files changed, 1 insertion(+), 260 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/01.bug_report.yml delete mode 100644 .github/ISSUE_TEMPLATE/02.bug_report_zh-CN.yml delete mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/01.bug_report.yml b/.github/ISSUE_TEMPLATE/01.bug_report.yml deleted file mode 100644 index ff07ea8..0000000 --- a/.github/ISSUE_TEMPLATE/01.bug_report.yml +++ /dev/null @@ -1,115 +0,0 @@ -name: "\U0001F41E Bug Report" -description: Create a report to help us improve alova -title: '[Bug]: ' -labels: - - 'bug:need-confirm' - - 'lang:english' -assignees: - - MeetinaXD -body: - - type: markdown - attributes: - value: | - :wave: Hi, thank you very much for your support for alova, it is really important! - - **We hope to build alova into a project shared by everyone, and encourage every developer to become a contributor to the alova community with an open and inclusive attitude. If you are willing, you can try to participate in the contribution by submitting PR, so that your code can provide value for developers all over the world. For specific contributions, please [refer to the contribution guide](https://github.com/alovajs/alova/blob/main/CONTRIBUTING.md)!** - - :warning: Before submitting a bug report, please read the following: - - Before submitting a bug, you can first look for a solution through the [official documentation](https://alova.js.org); - - Confirm that you have searched the [historical issues](https://github.com/alovajs/alova/issues) and have not found the same problem. - - If it is a question or doubt, you can post it on [Discussions](https://github.com/alovajs/alova/discussions), which will help the author manage the alova community better. - - Join the [Discord](https://discord.gg/S47QGJgkVb) or [WeChat group](https://alova.js.org/img/wechat_qrcode.jpg) for online discussions. - - - type: checkboxes - id: is-this-a-bug - attributes: - label: Is this a Bug? - description: ':warning: If you want to report a proposal or have difficulties in use, please return to the New Issue page and check other options.' - options: - - label: I have confirmed that I want to report a Bug - required: true - - - type: checkboxes - id: have-been-report-before - attributes: - label: Has this issue been reported before? - description: ':warning: Please search the Issue to confirm that the issue you are about to submit has not been reported before' - options: - - label: I have confirmed that this Issue has not been reported before - required: true - - - type: input - id: version - attributes: - label: Alova Version - description: Please fill in the version number in node_modules/alova/package.json - placeholder: e.g. 3.0.0 - validations: - required: true - - - type: dropdown - id: framework - attributes: - label: Framework - description: Please choose the framework of the impact of this issue. - multiple: false - options: - - 'React' - - 'Vue' - - 'Svelte' - - 'Nodejs' - - 'Deno' - - 'Bun' - - 'Other Framework' - validations: - required: true - - - type: textarea - id: description - attributes: - label: Problem Description - description: Describe in detail the circumstances under which the problem occurred. You can use Markdown syntax to provide key code snippets. - validations: - required: true - - - type: textarea - id: expect - attributes: - label: Expected Behavior - description: Clearly and briefly describe the desired effect - - - type: input - id: reproduce - attributes: - label: Reproduction Link - description: | - Providing a reproducible project will help the resolver solve the problem faster. You can choose one from the [official example collection](https://alova.js.org/category/examples/) as a template. - You can also reproduce it on your own on [codesandbox](https://codesandbox.io), [stackBlitz](https://stackblitz.com). - You can also provide a GitHub repository link. - Please do not fill in invalid links, otherwise the issue will be closed. - - - type: textarea - id: reproduce-steps - attributes: - label: Reproduction Steps - description: How do we need to do to reproduce the problem you encountered? Please provide the simplest operation steps to help us quickly reproduce the problem - placeholder: | - For example: - 1. Click the button - 2. The request is not sent - validations: - required: true - - - type: textarea - id: browsers - attributes: - label: System Information - description: 'Paste the output of the following command: `npx envinfo --system --npmPackages alova,vue,react,svelte --binaries --browsers`' - render: shell - placeholder: System, Binaries, Browsers - - - type: textarea - id: remark - attributes: - label: Additional Information - description: If there is any background information about the problem and other useful context information. Such as the solutions you have tried diff --git a/.github/ISSUE_TEMPLATE/02.bug_report_zh-CN.yml b/.github/ISSUE_TEMPLATE/02.bug_report_zh-CN.yml deleted file mode 100644 index 89367aa..0000000 --- a/.github/ISSUE_TEMPLATE/02.bug_report_zh-CN.yml +++ /dev/null @@ -1,115 +0,0 @@ -name: "\U0001F41E 问题反馈" -description: 使用中文报告问题,帮助 alova 变得更好 -title: '[Bug]: ' -labels: - - 'bug:need-confirm' - - 'lang:chinese' -assignees: - - MeetinaXD -body: - - type: markdown - attributes: - value: | - :wave: Hi,你好,非常感谢你对 alova 的支持,它真的很重要! - - **我们期望将 alova 打造成大家共同的项目,以开放包容的态度鼓励每位开发者成为 alova 社区的贡献者,如果你愿意,可尝试通过提交 PR 参与贡献,让你的代码为全世界的开发者提供价值,具体贡献请 [参阅贡献指南](https://github.com/alovajs/alova/blob/main/CONTRIBUTING.zh-CN.md)!** - - :warning: 在报告 Bug 前,请阅读以下内容: - - 报告前先通过 [官方文档](https://alova.js.org) 寻找解决办法。 - - 确认已搜索过 [历史 issue](https://github.com/alovajs/alova/issues),并且没有发现同样的问题。 - - 如果使用上有困惑,可移步到 [Discussions](https://github.com/alovajs/alova/discussions) 发帖讨论,这有助于作者更好地打理alova社区。 - - 可加入 [Discord](https://discord.gg/S47QGJgkVb) 或 [微信群](https://alova.js.org/img/wechat_qrcode.jpg)在线交流。 - - - type: checkboxes - id: is-this-a-bug - attributes: - label: 这是否是一个 Bug? - description: ':warning: 如果你要报告一个提案,或有使用上的困惑,请返回 Issue 新建页面查看其他选项。' - options: - - label: 我已经确认我要报告的是一个 Bug - required: true - - - type: checkboxes - id: have-been-report-before - attributes: - label: 这个问题是否已经存在? - description: ':warning: 提交前请在 Issue 中搜索你要提交的问题是否已经存在' - options: - - label: 我已经确认这个 Issue 没有被报告过 - required: true - - - type: input - id: version - attributes: - label: Alova 版本 - description: 请填写 node_modules/alova/package.json 里的版本号 - placeholder: 比如 2.9.0 - validations: - required: true - - - type: dropdown - id: framework - attributes: - label: 前端框架 - description: 请选择与这个问题相关的前端框架 - multiple: false - options: - - 'React' - - 'Vue' - - 'Svelte' - - 'Nodejs' - - 'Deno' - - 'Bun' - - '其他框架' - validations: - required: true - - - type: textarea - id: description - attributes: - label: 问题描述 - description: 详细地描述在什么情况下,遇到了什么问题。可使用 Markdown 语法提供关键代码片段。 - validations: - required: true - - - type: textarea - id: expect - attributes: - label: 期望的表现 - description: 清晰简要地描述期望达成的效果 - - - type: input - id: reproduce - attributes: - label: 复现链接 - description: | - 提供一个可复现的项目有助于解决者更快地解决问题,你可以在 [官方示例集](https://alova.js.org/category/examples/) 中选择一个作为模板。 - 也可以自行在 [codesandbox](https://codesandbox.io)、[stackBlitz](https://stackblitz.com) 中复现。 - 你也可以提供 GitHub 仓库链接。 - 请不要填写无效的链接,否则 issue 会被关闭。 - - - type: textarea - id: reproduce-steps - attributes: - label: 复现步骤 - description: 我们需要怎么做才能复现你遇到的问题?请提供一个最简单的操作步骤,方便我们快速复现问题 - placeholder: | - 例如: - 1. 点击按钮 - 2. 请求未发出 - validations: - required: true - - - type: textarea - id: browsers - attributes: - label: 系统信息 - description: 粘贴以下命令的输出:`npx envinfo --system --npmPackages "alova,vue,react,svelte" --binaries --browsers` - render: shell - placeholder: System, Binaries, Browsers - - - type: textarea - id: remark - attributes: - label: 补充说明 - description: 如出现问题的背景和其他有用上下文信息。如尝试过的解决方法 diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 0a21919..0000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,29 +0,0 @@ -blank_issues_enabled: false -contact_links: - - name: "\U0001F680 Feature Request" - url: https://github.com/orgs/alovajs/discussions/new?category=feature-request - about: Suggest new features for consideration. - - - name: Questions & Discussions - url: https://github.com/orgs/alovajs/discussions/new?category=q-a - about: Use GitHub discussions for your questions and discussions. - - - name: "\U0001F41E Extension Bug Report" - url: https://github.com/alovajs/devtools/issues/new - about: vscode extension bug report. - - - name: "\U0001F680 Extension Feature Request" - url: https://github.com/alovajs/devtools/issues/new - about: vscode extension feature request. - - - name: Official Documentation - url: https://alova.js.org - about: Before submitting a bug, you can first look for a solution through the official documentation - - - name: Discord Chat - url: https://discord.gg/S47QGJgkVb - about: Ask questions and discuss with other users in real time. - - - name: 加入微信群 - url: https://alova.js.org/img/wechat_qrcode.jpg - about: 在微信群聊中和我们交流. diff --git a/packages/wormhole/test/config.spec.ts b/packages/wormhole/test/config.spec.ts index f2f1642..dca3771 100644 --- a/packages/wormhole/test/config.spec.ts +++ b/packages/wormhole/test/config.spec.ts @@ -187,7 +187,7 @@ describe('config', () => { }); test('should create config file under a custom absolute path', async () => { - const customPath = '/mockdir_config'; + const customPath = './mockdir_config_0'; // 设置package.json 文件 requireResult.set(resolve(customPath, './package.json'), { type: 'commonjs', From 86dca8fb61baef62d02b539f3ccf8e22d6829ca6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E9=95=87?= Date: Thu, 7 Nov 2024 17:37:52 +0800 Subject: [PATCH 41/47] chore: translate Chinese to English in all files --- packages/vscode-extension/package.json | 2 +- packages/vscode-extension/resources/icon.png | Bin 123560 -> 34093 bytes packages/vscode-extension/resources/logo.ttf | Bin 1456 -> 1756 bytes .../src/commands/createConfig.ts | 2 +- .../src/commands/generateApi.ts | 6 +- .../vscode-extension/src/commands/refresh.ts | 4 +- .../vscode-extension/src/commands/setup.ts | 2 +- .../src/commands/showStatusBarIcon.ts | 2 +- .../src/components/autocomplete.ts | 8 +- .../vscode-extension/src/components/event.ts | 20 ++-- .../src/components/message.ts | 4 +- .../src/components/statusBar.ts | 4 +- packages/vscode-extension/src/extension.ts | 2 +- .../src/functions/getWormhole.ts | 3 +- .../vscode-extension/src/helper/autoUpdate.ts | 21 ++-- packages/vscode-extension/src/utils/index.ts | 6 +- packages/vscode-extension/src/utils/vscode.ts | 14 +-- packages/vscode-extension/test/config.spec.ts | 14 +-- packages/wormhole/src/functions/alovaJson.ts | 15 ++- .../wormhole/src/functions/generateApi.ts | 63 +++++++---- .../wormhole/src/functions/getAlovaVersion.ts | 8 +- .../wormhole/src/functions/getFrameworkTag.ts | 8 +- .../wormhole/src/functions/getOpenApiData.ts | 39 ++++--- .../wormhole/src/functions/openApi2Data.ts | 12 ++- packages/wormhole/src/generate.ts | 5 +- packages/wormhole/src/helper/openapi.ts | 66 ++++++------ packages/wormhole/src/helper/schema2type.ts | 98 ++++++++++-------- packages/wormhole/src/helper/standard.ts | 8 +- packages/wormhole/src/helper/typeStr.ts | 15 +-- packages/wormhole/src/interface.type.ts | 83 +++++++++------ .../wormhole/src/modules/Configuration.ts | 21 ++-- packages/wormhole/src/modules/TemplateFile.ts | 12 ++- packages/wormhole/src/readConfig.ts | 6 +- packages/wormhole/src/resolveWorkspaces.ts | 35 ++++--- packages/wormhole/src/utils/index.ts | 28 ++--- packages/wormhole/test/config.spec.ts | 25 ++++- packages/wormhole/test/util.ts | 5 +- packages/wormhole/test/workspaces.spec.ts | 14 +-- packages/wormhole/typings/index.d.ts | 8 +- 39 files changed, 410 insertions(+), 278 deletions(-) diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index 591ce86..8d19231 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -34,7 +34,7 @@ "description": "alova icon", "default": { "fontPath": "./resources/logo.ttf", - "fontCharacter": "\\E900" + "fontCharacter": "\\E64B" } } } diff --git a/packages/vscode-extension/resources/icon.png b/packages/vscode-extension/resources/icon.png index 62cce6e4f38990952e8b83b2b8969c2cdbf7ad57..454c13835a45c6560a8681591a1788cd27f6f8ba 100644 GIT binary patch literal 34093 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 ZJS>rsZflbmYPJ7_;Wfn7F9wf7{tpBOD@FhS literal 123560 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

&3P=g={)$M z#;yU)Zo@^W3%N&S^g&`FW&mNtn3a+hQl3}PLMRlsE=m4jSQ%V+GjrXU!i6 z-woZS*@qlzu3nBU>Z#bhj_P~ZR5lx8RGO!5M5~hrluD2#rB>vbj9r`$F}<5oKG~vv z@V++HF+Xaw{0btsk@>~oaZR{+66l+pkV$uLZJ5Pve~-#1QKX6k~fC5YUD?{ZriPw z+FX`>68pPPNQacn4>vRAqa(5m#*F51iHqZJ=^Q?_FT7y*xH zq+^YzFaFhpbzi&CZ6X4x-`iVvv|Bh6qlB=AW~KCN8a;O#7BLsid8`{Ju?+lMcuF~D z*%DGO2CIBTEmyOw_~9Nl+bB+*tY?$*Up^jAs@`%^l^B|@#{Jy0_C=z+0|5O{i2;q! za8yG}I{v9F+g)Y(`bEta2iskD%#i-rc;FEn5NgFFaiIRV>w3E$W(%7nCv z?VIe_i5G#TQ@zfwv##`8zTH$8Xx4r3de&OO+^KuOh9sk2gQ$+;ne{WF%0t-=lA{Rb z$M}7gG6v1M4<%d_Qp4V&Y730{`0cc(koP~(N+BZtBCT#C}vydQQ(borj zb6CFEd;#0}()wPns!Xc@jgxDA=4>dA_fza$A?wypzzq1kG92 zS<)I-TFnVJAnr?0R0CWBGMBDl^_;VC24F9CDUiOzX2FxZ-DmNwhn-`+c2iUGiJ4*- z6RzK}se1)nitGB)EBQ(&Z}8}asQuYfppmDA>Y0B$ylk7)zi3lu{Y9r-WunD)bAG&0 zL|QFEkfKwN87+tjcNtym|FKm)qm|;%Ad|k=fI(a1rOB&x*>^-6yYKD4LC*M`3Kp#Y z!`Bht*wH?tUbkM(?}~s1L01+K5Y@!1j?0J`nuF<;X6jdNDgLX6luEStQWbn;|yX^7#pgU7LU;=>&(T&R?_6)1c}3#kSG!^0iWM zHhIb6n+5nRtd2OMwn^L=k(EpdhkGVYP_MIo(4q&$BknkQkCcy;jIeg}h#az9;E?6c z8bxe>oX?xLqIvR%1N7~M&w1>0O_8oAttl3(7{nnfCnZ!2%WR4vH029*>Lx5 zLn~ZE6KqySDa2z|K}zN24+n14IcAT!KqzKKc>Q+I%~MrxH`@vy?+Hm z{+h+lk*9G{jo+mAjmjVRy%`mT!G=FWrv7I9w6|A|WV_lX*d^ALIO9Y&kBN6h+MfUM z8d-)ausyeBYWeYm;)@>R3B4Ud{|iLnL~Kj3F#f7@YkptGlR(K+3)E~TkF zAcWRL;gkEY5=xhzb-ZZ3ApeT_3hv=FzCB2dN@FRn^zH}GmOHE>9Gqa&oh(tN*(?L7T-6j3nM8w@|i~$lR>Izu#l6U|3eT~dNli? zS-5k((tz|IsUBiQSN=F@9W6a@(&Xp{ZA?xYv`K$!^y@-w2FvT9JHFr1Caqda+&cDR z_6iWoc#w1Gp|`H&Z0$JpgisT6ov1^HDFqKy)s;_)NZ$()w6vVm^20>~?7PrQ);P z3>8Abg~6x>Y0F92k5D9JDvVKw(h?udDcJ)~7Anz>~y7R~-YC2WVHxaGVT|Eh(zRG#F>zq?# zBEqdl&nop}=soRJlI|*aU#@#?qef4ohM*y;h5y5J)cnKlIkk_rhB{_DvUsaxAlB|f zQmvj)Z(4MGV>#vG&md+*bC&ID|1!_>OvsdOA@KUxmxBLhZoD>34Qxf_BhA8h0o^7< zS`R5tvrSbYKHap1oDK?f0k4j$sf=5%B0hK-!p(mAIch9v_(Lg0CM`p|X@^RyoPDGx zWt_b|!t))2-4Q~+D{iB_^p8`t`E(D}sP2_{b(22r#`VkI0`HnUqN=oGaY?}yLVp!U z%GYB$O9rbw&GQLWe_+Bl1y{4>8dplr|A)&FR-F!UQ3Q^0898XEWy%_rU(CLflb5q@`@w210oKB2zta*e@7H{*x zF0$9Ibp-aOao&1nrs?K^a;kPjw8xuaRrQlY=jNiSuDO+FS!-z0N$W26kdRxACiBa0 z;%pO2Qyc8f7~;uAPMGfjOD06Re7mu=z>VT0xzobF>JQxOSOKbjyyf%qik_m9;GhS{GN*Cw%j)5m7BlsL6BKqu>o*yG&W{hSf@3|lwtl0& zO%_*D}Koyo9K>tTT9> z=D}QLd2t@IH|K!Qihb+qvkY;A&GFd)Qh%BVY@`!aHY-QpP7QN2;?|t%!lnfS2KCJQ zrr+(N1IXqy^}Zl8d+!>!@VH9v@)F3V+A0!*dsp!__%m``a)|^lOHF)p{ktfoHD}{kJ?+uWK>4^$>byFrD%WB#(M0X z`XF~?6??B$AT!&A?k3uQIm*&{%0}(oPE+2CixSm=#t%n5X=6;|pYO8YMoe_-hA*JG zkIrMl7wuQ9gz;~C?zWstzZBcfXHKb14zv~`hwBpd^G=8?Pdz-3&TKB2j1j$XTD!CN zW((+}K}5pC(0zSt_zS;lwK`ZYrAC~A84z#xYm?t^^H7O>u<3ISM<5$$qbL%aqQk$` znEx3WZ5F6Ly6N<-{VB?^AhW3;IMnZb5>VFJtGN8Dg>f&I+mP9ffZw*N(+KQo%jCNqsTy-e8HqRby3=VxQ}3f;p(6vQ({VQ=Z%Q@G9s!QD%Dy5&A4K>K;K=eAsvivF_ir;ZU`Knyp*F zIr!E4B2D0O>=Ent6wa)0f)TZ<*m5w6q$spW7+f9Ptb%kW)VK?6Rg}ud`=PxHzDUvG z5&lI1*22Z|=TeMeI4TgNQDlgEPU@v^qfl^TFVQk@%GJL9UL$f1OB)yoWR%xQ|Gx`S=xS2%~8KSN1mh-(aCWXkK2{N1x9 z|Ij+Gc2>E+9*%nd!02aCj)MtE_BvD{yugugi97vW$m42d@I5{Kv+t`&ve65}#oR~P z-SlMwTDa9`iS%XE%&-rl8aehFHLPPFZfazyn1LMdQ}$ro_6Paf`}B^Iqdpm$Eg)=- zR{{20RJ0$mVm8}l*2VJOXFs<`M5Yxcp_$e^w0$Uo-M zy2b^kP79o&RpRBPD9#O_$fjAL0D^i#K#40;!a3CV7a~SvK0+{te0YZSfZ1=n%v&0s z=<*1jwBBOCp(K>kyf?`2O|enCM4XjfJwvx5eo>%lU4*xroyS|7-N7#=j^Cp2(1VIg zfAv5R&x;eF7uW%xh9Q@dZLMy&!qI~LMJrv9DY9IB@gtaqKy$&bVb4>s_3!e>2sMAC zVqFB`eOd|Du~*+WV!ayPJ8#Wbzx-`ajX@x$#9_q;#U;y3DYdP{#hlq-Mrq}$be)p{ z%yz#60ZbaO(~RM0@ba++FNdvqsH-80qmcm~LK9~?52R(tsc2P1jg+BEZzRSQ*q^bG z-VVDtSyF2*c6HH4HXn;k6y7Y@&sfoZR}48lA2%#-ktAkrW^f)5c@7hPx~lq#k@u+p z8Hd@U$79RRD$i@O@7{bYQh-81P4o4KHGR{%C6y)(l~Bb6?Z43*{lYZJuF}i7weE4N zKz~&xim{jH{fW*f%7_soMw;zQ?3`l{+x#t$0o%2szdH!@zKR($yOj~)A@s$?7SmVj zv$lT@mJj4N_txP1!0#R9TD0BZ9&cqDv1sG+=}`~kQ`;lMlD%N|j{2MQZ%-;EMRLBr zD_U)t`(kkPlF9amj3wNFit=N1REyX0#IHJKPmis4W5Q*HWm&Vz7VLdArvD=lx1jvA zoNa}mA9Ks=lQnyX<qG9fVjik_@R1&Z zz0>_Kl^e}|Q>~t7b+0Q!OecDNL#JeHSL7e~zg|w&2XL7xh(d3TL41utedWvLAWeRD zaVbr+Dg#f{$d#(yGX$s2c`5{!qv{$CD>n;B1#w?+ds8U_Zap54BlQA{*miv3OPhO5 zczl%u9@aq!4)g!mJ!D6%>dr{Ec?{Y(ATH-Jn(x8=XLJ>uUFmTZyc(kL)R6kc{Ez>++Vn3my1Rt&f7JU!d zK7&=!J6tZ8H!q|x4Qc7xtHaVhb)P}*UnSo8_@tAzD`aGXd*6XDR$u^6wvpxADswaDB9+y+jKL=j% z@GHJhPKD_Jog5zA*>fOA#Gq}R-#}$rxL=9e$yAm7*HBTaQvWC2h!lDQB5JsadCi&9H14*&+ag}* zfP~^`n0q%Z2tLeX5%)jI;eg@e!vUp|EZYg`+~_u5;VXxMA_R!jcAwRpQ{i{6*yx`1$hJXBZff5Y0~ z$wInVN6|Jxb!tpg@4JWycU|_W_M4hs~x|>E~M#QFzcTz&^& zt72qEDDS%V_z+fwCi7&vNwlo+yDy%qgq}O4INtr_mSsh0@X1X5lg}@To_B@UEk=98 zf6cuVa`A(jvYvDv{u%*`n=h`}VOsBwzmYFSx4Elq>#9qXEQ{;QDX|-xMUI=*NZUk^ zhv2ha?Dl$PumIDpy?gb@-1Egm$AAl@-gitv$yvFf;6bm)m{{!*?vah@Cmlg(ETI@@ zGvr$%KeQ8YsfcW7hX3Z$J?f)a2ZZml4V6w#GLmF&UmLA{q0%cWTriO=cfk0k5xZXl zu66bR$=t6<(oPp)dCEQRP-!#mtE5i}?5J!RjyP^Ul+MSEN5-mwK_71{=%acF@4Js5q1y-?ge&OAv#;lzFnb%cIfa%G+q-V&Zkx2)t|m+@<8}S(*Q8tua^BC$S*F(?II$)& z_-rdNMe<;jGbKHxRCa1dz>OqQ0&J|@cR|IjhC|C>W7li(&Lr1y19gk zt@yg#iK&kL{5~cyDQm|#?eNp1J|Ly3i@0#ObI@{i$?fn)KbrtqC)uw_`)e*!d{*1G z#>W)&pX>WhGfPwK$sohWP*|Yp+l2*2hc0>X+eGoLYr9Q0vvvBFL(~uWJ1aL(za<`A z1~1!szjKocASq=L-jS~ULPt0A)^C@QLM($yTkWm(4%d^`S2IxG}E6VkuY1cT4e&Md35N9q&DBXyox zjx@T(tj`iw+n&xtm}IxrpkgWI8K5r`d@XIzQQu~}A-n$a>Lp(nmtQVV)QT_!U7tWVhBhT!Yhop5;tqg^ieM;{mN(;|_pCsW0PKmmgXZ zS8B8cPE1O63$ z0&BwM2HJ|dJc_&hfQ`Z}{2~*`1^Bxa#Yq9iWbZ0NrkKwZ3SAD5EndK3svX=qBL(U0`}=!R&#L zo)&=CgQV~fM+P6-^X84)UD}q2+v^r{kB6l7)o#`(js36ZI+d&@Nq|O=IlmW#j@nml z>{Qj*G;%kF*$Fb$VJV)Oxa+wgdk(>&!sH;V>i4krs~LAEcpz<>dgpQb=uUs!pR2>1 zX@TuXa2kS(mPhF>3-01%v59RD-IPSOUdd-Hr3)R6CX zGv9obd)t2m-wL9N#j)<*yoJq|7-X{nsn#Psy2=ui0dS3bg}P8dfT^gVmV9$@H@Ulx z`bW)g#!B)pvkzSef4Zq|jXsIz8TI`8Mz0^qS@)r^ui`wl?!X6nJj@4|7#grk*RN{z z?WLj#v1&LQyP$PVj2tx=B!KfE2O*)CA>vq(J3h}z;5mr54%>o07c=-dCtQJf=!V^^ zagpwbijKvMH0)w!{0CkyHw03dB%@wBaMFA{x*P|R-%?oZw;6x>F5};95%Nf5R492; z-30O$XA8C_95xV?H)MonW}=2OLGcQS)_BpM4tXv*e^`z$?LGJUGu2?tJeiXxng4X! zX1BX;_icD~*J<$%*CYRIK*#^yA?Wwn$e^ifH2>?DL-B_~!k)(;F7@;LI5+&P!`!wk zo!nz>63cRQ5e-}+r`?4`SBgbcDAV|**l#0Oj>J(uiL{@1#-(4l%)7Z)mhbveMe$ZM z+21l*!uYpL;k>owaWapQ7((Tpi=U0ysR1hc8}zV5@i%qQbrH1u+0|g~ikybL8@hlqqWR7;C_hx> zqerEsKlp%{siTBet#dG?3eeTzqO?rWEz+CU^eEY3FK&HBIQ0B>ts-EDa2OlEJ8hSs zovoYIukj4c&5~9cX<=5D0*7Xn2BC^1Er*~)^+SRqoy$vO()3c-1 zI1To*C8I-o@;l{B{zd@1e;+AU4bD{yEU@bI=B0hDV8|f%gOyJVIs?wfZBp)1B?3U6 zSyuI@2mn|u=s;+N?JToX+G9VTu=zYp8K_1SHb}FJDCdgwnU@d|G=d_d+q#@DPNb;X)VClf`^XC^2V;_if%Avv1oWm^81rX zze=fHWc3W7-Rp#ussF8aeYSMh@eJ+f+b6-tf;Uei>_L|9JqM4>s#ju7(&UW!~TuzPkoa&VPquzzmKGpIsx)&IcO)m`(F z%w{UM{R&)EJ#ID0h<>u2cG6v_Rfb++=vo-_>!@mfLU~K)PvhN2z#yk+GWK@K)|e<7 z-}vqKQ-DzJ_*L~*h1H(LXX<6U@bNEb#Pvd?^)sy2UEy(74HM)v^Dz56o&%^aOkgX$ z%;yg|U#RU=Cu|sg?Z=YL8e^AfC&@Y*_REnt=swGoavbBrpA(u0^K$ooAusDlONYv8 z#0o-adRDWI-`C$7<)i$|ZS16$Cs2v!*Y@Gh1& zVoT?W!BFi?G(|zEiK-Ie#@G;8yj}MzA$7*Wx1^bMyQb?Ico^j{p2jqk-BKGhQJ9mG zJ65##m}=SfhF}uA!IYB!Y}y4DCvu~s#rY3;&}g?~uxx{3HFl@T(DTy^>(b&-@;y^~ zIj#BKi#rbRV`JMZB@r%w^&L)Hgl;}!ZV|hpKYqB%%r&>=2`^M{d|k&K_pq5;aZ3jr zyX>dKI5Z8w4t{v@=uEC5oQ>D`t@^6VV*puS@qz66F87ULLZe2bQEao197K=mggq_N z8qSkde#GW2J8 zm8o?ocDy2u=T8`n8B9ZdU79MvtJ1ghZ>(%n_aNcRyf;wdxrApRobbBwpQT%8P7!qj zRu=lHejGHY2=%;o={qvaa(t#1u^x#Tkr05v?c{`qoR8F>A zXjTTs@|}-k`3573=>=ZGK#4${@bc(QO;`sB*h;pNgVY)l@`d%#ns(D@#{@B zIn{rawnG*5c6Je*g+5$qgNn#NYqG;3Db&5!UV^LEir8ZC2pKgxvJUPi5Z)q);G;z` zR!UCs^^ejKm83OadYNNmLWfus8`>{!kr5P?jwLl~<0|yNS8XUJB@Q~1cJKFC^gms6 z`L1tRDE~(v_5n3L`{%jF9-On<1qFolq))RQeo!0s`wO0fHO;iFIR<-*ws;w`FR**> zHTm%PhW4@~z%48I5C-_Vp@_C)f%c1-`LKJq48Np5= zLfVHG^`Vu9ld)K5+L^xT!2DY|hho|KNE~b+kYpzgI@GytrDQvF3t)&ZI}Ay>DuQaB z+Klic5$AvK+9@wYhf*_U?w7p?oc!Sz-c^y9sA~bF0RhuyJrt&&3Ha>M?lm4{n_SDY zB$ry0L}Z9)f4SsuhD{Ow9_+TSHbBxe)}_cbcQn{lJN0)ZB(ovocYFl{4mU=Oxt^zU zfuSA#3Dthig~*EM=OJsrp2L22WQbnmdL^JTJf-{n3%cP3Y3E4DCnSsx>In@x>prfz zDK@zw!!{0dw`U(pW3bGD->IReR92!i;6opZa)VD;0Nb*~etJ{HFlfaey6>eud2Qh3 zg>WwWqwwqcuf3~`%hhmEIb+EH=dQ_$`9_?J7*}N*@i#!+`J32a372D1>6$y3VpmZURnDLIxF&583Jp>StWl{=)#ql8?4Jqv) zIiOdJm<&pTw#_2FSO)_uL{1q zQ7K^TO(Mf0tV%RMmJ!=C=iJdMO3*+rhPMO)~JnO+XhtJiw3l6P{W+9G-p}3Z0?my|k z?~N@*LF15SllVy%(WK7x%6@rge4*~qoz(8^r3K+Cr~PTG|5QZ-wS*Hp=?3BcRUb`^ zBtaGD?U8hY3RPMNh@~V*K=Qnzs=oW&|CiZV%03B3TNn z2JxzaAYjO-2sp;$CQ!Nzif&)U<|{fZXd(n4;`d@x0RH}Z??H^IanWw9l@ zVZOG-T^b#4T!@PPyc}u{^-%if;4{k5*a5FQB%;Xh>tF0kMnuA(4j~=np@g)Ri5kqa-n$4b^;}bYG*++0@M~rYo%F`k?BIc?`(fAd9I`Ru)6&84A2(or{-QOEoxNz z)RpXc724~jo-Y-r^gh}jN>!T9l_Eq&jBjLNdar3dFYBEGlTASF71Kac@qw{qX-P zwjYbBq#x(UPCZK}sRyV^|I2Pl+&JA%Z{C+;Np=(jTDp~ZWg&5BT%L}pmDl3j%tKY+{;g8TiUj z2kv<}!w~OBX^JQ$f#!3~CB{(EG%jE_t+oKVvQW95ZL}#ibCE~AoK?Nt{W1LG4{88k zV+g!YkbK^K@TM@G&xRL~J_lIBWj_O91LcCiV6Y!x9VlQInuaC0-TUcH!4)UBP~Hr&ef;XAJWZuntI! zy^3VX>6R;vwjOJ`!o-sgFZ%GrsMN^+DIWI~r*9WyX?JFUe@OI&Tnf-vu>TVB_X>_z z(H~VJx%^V$k@-6u2{`8;Rv;>(w;>{NSQF?n7?*l%*_ex*_CFYoJj`3RvXJ2mFLkx#QrhW{Fu>M*DO z8+$aZCtoHeYlSoOL9B4csWLm=ryu2kHHZ#Ltk+WVRP{qi);iVx<=VvErp|K_Re z@GZ%VDSNrsH>`#@ryX1S`gzo-`+Lp5#=}}ww0Q#qNA1M9`G7MT$5(Y0$Z2>367j=& z=gX1`nol69@zdD4XH5*I^!>-{LjJ|n>>pmx3ndh|H1@FF)&m*@2E?1CjqAme)5NFO*S?qGGFHb< zAG)$Vq1E#ysF3l5aX8V|wP*iRY3zxLhXtk;RVmrm4MW<$bLLc`zSg_xC37CwDV$mP zqv@6|*z_82lf~Sr7ECr!D3kLr(4n?MAvZaeJS?l}mL5qI-H6sZU^`-blL$^hF$_SUCP>m2ywb;iC9}6nPa8L zfceGriY-`Ma5nVRFX3=Pq&hkfxY;kXqL-x%Olz;cZZFQ%e~-vGwD_jB{dz^NYSVNR z7QK=^gf(yfEA+G_-3n`A2X=0!r4eWa8@K-3yGx{Ez|-MME(6q=6#)Tf|~96a?(&-PC^0d2}k>SPR8BhyYn`?y9 z6;P8xjaelEK(H7r(3A>0JgnUD;>^A^2+fy6_Altm(gP7wJ7~mNwzSysHpjU`^FMA& zZM1#pye{{>-h^NF|HU0)QvJRa^m?8_#ko3dg*ji^O*<@CpT5O~pH&NGVMu9j%$nWF zm?uvh_U3=U+;w?Vi*gvbPouC4)lXn2wpBJam?rE{xNXM_Y-zh~e0&xRv9xDV;>eud zNvO`Xao|j4SHtItPw56}0jX+S?d%2PIeb{2p1y-k?dRK^D*4c&JUVwfIV^d&J5?9m zs#6#2cEy#-Jah^iDl*Vu9{h@WcLr}bJ^FdDoBM-Vz_H&u=@ZhiD$Ea|{@1$F>0%7a ziv+dyizvH}HFU0|HsYpu@d}J;Cp8tjr%HpJhNwRNUz#W6L65?9Od1y>QWE{MjgOk& zU0wg>jA1X!po#Z@DZf%uAm=jegvAV1K}})>86$k`77w~l#U=$J_9wF%dxeiK15ou4 zSp%%hrETf_p(GPF*GtYI5Rrv8F^_b?{)w06GiORM%bArVUst}GT#;M&7X^JN4>|ne zxKm{q@^aEdDOI^8OTmVR%dhX32&2&~3PC{YbD)$ia=hy8fW2KDKd?)-?|<_3c+K8t zq|nz<2l{IQ;CHiR9mg};wjp=TKgji44gQ^5iC*fD3{-cQR5}W|QtUU9&1NA@3b{Gt z-8o8R7_!psazD?`VpbjoZ%1X%W7Cl8b8)FzoPQ#BQy~Oqw^O?ACRS%(xMHbb?~D}x z<~uUQvYdZTe$Y|5nbXi**U zQeK;KE`9YkJCscoy69M&Go9il>7!A)GHI4>GM3*KFF`I=zSnd~)C01^U>coqG{cAe z3CbuW8mnUsh`}XO4Iq1sr3`e8Yo%uu+{kyx8Z&Cv9w8!Yo|$w}Zx>#bHC^*$EJVg0 z$@)2&dAX7G^*-?4BqgYLG##_=w^~4|pHHeRyjO$M6)KAf{&XI+zDXA4g+4anm28;j z`p6ql5&EG_4bz`4am>L{Wki0nR)X209PA@t1&!D5Y%c!xBDTrNbqbjfN6VPFKd(eiuDOUX>C^s*`DH0W;;!W;oH2@kSuPD|Ds-r?N9cUa61?ct$bwZiHQ%gkoE5~Xse0Rvk;X8q4!?;=|6IXf9m3q59*;hD zT3`~mnIX2yk39W)3{QW_zTx7nIX+6};cE@;C}Zb>-xTvWGcyLn;9wsFJa9|aI`}Mg zN{gNM6`XsJ>2NN*8RXhFY!j&#{pmg*P18542=^QX+33EnCB9zM7+%O z>=I#E5dlA>`tkFUAHyW_f+|^)Iz%r)S(_g^FaQO!4tYj<7WL^1z`Ch&O|JPa2s1~X zKQn(pO?{uiM-K*O*7R(lB8sld#{3F;IhiQEC+dU6Q5y^Af9wAiY&Rb7oL)8g?88wh zK0{KdrV41)KJkP->X)s(QZ!&GeesZ|82XV`oEpcmTe=am$Q&fJ2&jV1z{bb|28Gn2 zXD5#~{+5#{!vUQ$y&ir3#Ky2nQh`W*AdF;(H3Zcj1#vR>N+w64!V+gbeKgYJZ}q9R3#e{y`sONm<9baTt>dyTtgH;ZHld5&pcj`uo6gz=}#Yu`( ztWgoLe|FXhZ&sx<8xKQSN&aKrNDw9C6;`*Rg`6*0>lCso4l{bh#fUVA4uzb2rB)M_ zuM)U0`ts-1BxFIQ2O^{cjv{I-8Q086`E1u*UOGaNOe`Mq#5~gNtS6kMOv^l7EQIbD zul$q122NVZKoB_*LqhG?@=G7kZd_&ZdY)Aa&h$H!g4^|)JBAtp*z=rj<&!ZS#~j#Y zTJamzbD-55KxC>`5YBL4u~lCUwBMgud-`re4)evB)MeWOhypSf^H^SZQ8@T2FzLlv zN;Pw#|1?k4TPxZ2!arOhv^17P96L^zcu}bfHH;f}S5yt9ZgqolmJ=ftrksLeD(Y@p z+3G%)oEZkRWUQiN0x9FYg$i+*J-*uJOnZGVektRoXh)9iRJ}vj8N7qm@+A|;-xIR$ z8+rwE3=qwpIW8kI)+_%A|EMR(^NGf`Pm@X#${m+9@N+c`h^x(dK6Uml(u1B3H`(?j zvvp$Y985}XJ8H>kSCN|Wm*1SQ%tCJLO1{NJ^K?=P$$;D#Wep z$&cQ-UeL8wB|*C9@^8`#j`74uyxF9Ob&@(gYYuOpExv_iDC1PWJxl3pN>SzR`0NY; zK~-~2AN6rOFQRd`n)S6^_1}{B62!F9*STHYJ{m@@g*Zt8e3%dDE za-)O89)R)a-85fATR~Lett79hi&Ao5L#{|4pnI4dw7ghJPmngAFc{pAkE;AI%r#1P_A-24XBD+>#r^5} zp+IzprMi9kIghMp5)-*z(l!%Nh{=qM%A|{%a_(?wz;zb0sXyO(4r&d>?i+?{XZa_T zOPABVb1=OZd#EAL|F?vo&=+z&hsMS%fU!<11J?GGw(q~kN(#h%oVeCI`hT2X z@Dv8wW=;)NvO|%K&$6TjVgNl`!5HL^tao$?^O_=iKqY1&ikWkTXi7EExE2HMI+k8;*esysAGV49YB{Dpbr({MRSaM_F6LIS$p^><>u_sYpdyDQh_KXDk^tIhHa ztUbsflLw8d6h>OuDsU?bY}veWR{MG3%Vi?!`0q1mm2@VgX7?kZngO^uZy;N@=O~N& zk~ghHyL<#}@B!Uz@wkYkq-cr)x*7>}LT|91j}I+HdN9xttP(uRsF5F^{ST3lUFcc_ zu#q%mV|24lG?Or*cYp2ErB2m-C8YhNF)ezuvWR9c%9ZC+*idjV^&106px`c;x1!fe z^!F=4foE;5Ob%?-<8sMd)NLCHtTzi<1omKAbf9$XAFuS z{^>t_-wx@QO49_b!A5=k=O^sSam=-IzB-6=1N5q>c>?DYt_Vf{kcVYs5P5%7hQ6>- zOhFjpevRlN@_H}w1WCadrh3E-1K6NHD@u=unR9$Svu+pEd2)}nWD52qRG16Tpjr=(J+f|!FtmFv};mYEN89szQE1%i$(Xm%<9J;khQwU4381 z3?1Ua&cs~&=1IBHPky0RmS8ixod`7v6d|aXw(&IhE$2ZxLDK0PmXAkYnC?&Wm@Ngr z^d$^%c+?WbP|xarR>pcDu#ee0*ylMH+9j|%iZqS%reZO}hmYABqyn;~^xjWVJZD-z zoy|$Y`(}F3_TbYg|8fq=U}t67v3}`-L~Aq+`3Gh~(I19QkFVa{ zyn|Z1k@9d>c3R>Uur8~iJGxiK7ah${GO;F`{s{o{Ut{_rYEBKB@pq)1puX4i9$nC; zd1NZyg<%7K^)Pv#3!^UJaf%cw!>fm1l#;L1#L2Bf;BRFtqRlIWh4sn5HrQ?+u)qVr zy5QtUhdYJu@-%gSf@zM_5wB9Z1~8xzq(1xBt$7!cDJ>XoOhdhX&lz@VM`T?AYutyst7hIl5+udOKoHXqTY1hO?DcT2r>qO z^qz=#)z1v*)43$B5>vNnCGwZk{k;GAyZZ5~wls46&cd%e!&03vTtR;B}6f%ZIT`YER5RQjolt9J3$8UG#VPl+7`d!7$IA;@REGcYg|JL}aFnEwAx2 zCQl$hPqdJeFKR%n+(bxiy?9nGu9_bnID2kY_vXF{2mC8)2yOb`#4dG4-q6hHtKz1; z##`((!*iGZBqOouufciyFvPyb5%U#?}9FG^oTuo%lhWp7xBdq!Eh+*(i3%a zEq)jUn>)~x@g~h32pceegY@SRO&T!o&26*S!&f~$;g62Y=3rwV(=i3s&c7ssF-z7X zMGhka!8o?Ngj{6#>AN1`JfKEt&+GT}9Q57#kvZ(F<6Z@tp06Wumx zQQ*~QWa3He86C|ye5920uHp1~mI!aaTwlrtx4wI_L?t9>IX#nqx=rcbF+z&rx52)MPxLY*?W|Kuw7R!J1)jz@f== zDwcskXnVk#D8A21x z>Ezlm-M}bjxmkt^pd8X!%2?_3b>)>KMi<39Js<{FFMtqM^Hn#MT1}PKUd?v7V&U4S zJ4nqCgrP=$mBpky$TxbJlG(=cT_yUBU`y#YJQsy~*5r?}UiNCUFK+^OezDTl;VYu@ z9?{`hb;Zy=E3C|yhHhC&a53l^+J&iv0O~pHB^;=$N%(%1n*>T5?_7K`kC_ve1UTH3 zk#?sijqFl)zDw}zr&E72d~FU55LEj%7?gheo|=I*pYX9?TR^BXlDTS3f-}sCzH8}W zeJ9Zj&|`~ar9+$~lJ7s;;8DD9t%1~_72DixQZf7u)Vzpgqg1*JFQ}qTJ}x}3nIw8t zaSc49T5e^M-5k;@**hcfBXRCT&ktF0*P<9 zWoK7P>HSg@c1FUnjoXO#3~XILsRtDwIUi2aKp!inN0(s0}By!La0$r|y&AezhF0OG3N*KIH_~74_6x6Cd`S+j{{?28XMMPANqc3EaOTjS^W3q6i;&XJB_?DdsTTV`;kx#kyF%i z2ZA(Gb~8a$R;CW~D)Ei5b}3k|NqYQh;ZMm=?+?58Kf(kxyGll4NbAA+AP61XM#8R{ z*$`iK_81@y&EjK!3%4Zy2e+8-Iwzl_!;rY)bZN~&*#|A*R!Fvj(`yhHN3GVAav>r% zO%gp-Dvr2Ju_s~Rf8JklmcZI9Py$2hKf2d$u@HPC+Bu;EH@EZ>Y(@I)F-I+I?_WF! z=RD$lGobSTxHMF+=D=VzCXle9_p^CRpYvwCwtr(zGwxM|3Lgr$`}kzAWPoJNtF`V& zcgI!O)pg~uF%@TA=xcQ*6wW5>hX+y!5|tcZ-CzBLb-~|}$gXeP)(`3^t=T;ah?i2I zBK0i<`ja<$(M`t7pes`{F86lZOXK&XG@BXDM!naj(u|-rsOYK;wdacfG3i{aZu6-la=SOE`Fa7N^9#L*r`<&Fp%91Q#% zu(fRXc6b=m(Dt1C!OM#GwE>qiz=SQU6A{1@UxS*6Irl@e4&Ak345rq385z=jn% zAk_`LaFWZGevLS3^n~W{#{VJ^f62_QmEa;oe{~4d?9-^{I2%oOQJx;|LRbxBhwj_9 z(ElOF|IVrj9IO-W-9{*wRZY?reYq!@EH%a%&X^kZVt*MCT=w8?@S7**4+$TRb@SPN zm#P2a6%VIi2K{trlO>AX&gc<*Te)VVESR!tm}U4&iK9l%6_hUT^P3AukLgWyT6xHq z%s&(mNpHPtyWthS)HL1{uCjQ^w%vRtTH~CSrk`Bfh{<)0b9uKOJwPnXlUHd`xI5*) zNq70jJKsA(({?T0_MT{+%C1SUzzWunqh!NvcLh|S6I5Gin9aybNauflBtL{R&q+Lp z0uM5b0k39ld@N{fbw;d)lU(fd4XjTv#wCofTgHsxe?2o3e}z~3S5}h5SCA_+U3@VL zMXjfgggL*2zP5dk$UOLWI5>TW2rs&LqFXQL1?D&KbA7S|*(8%Ag~<$Z=v z1D2nm&Q{*9-=~{S{!56(9#o~5^=9dja-fzLvDos9Qm@nSf#vp$X7S_UuI4Jmfu_b& zITJW@n&|>9{yHkhU2wl99 zsK<$LLn$ccvB3Af$4^kNPt>?_HC)V6=-8d3!R;2c_7U7l6Ot9*WrWuJdPF0=U0n66 zC7pk+D*H$G9a6j?9R(u_cf-ngqXaE0S`gB@>vmn%$Na(>17-}E{3GtA$e6Uyqr846 z^lc{u6?t;A#O*e3@m3gL5X64`bpx8?op8x_+%rHbymEJX_K_y9}Yql^d#72Dep}|1Ll&N4S6h=;jrnTGqLp<$APCHTQEPx%gwg zd8)@78Q))f@dcPl;8I%D&hdYj6R2u!bmia-8}3JO{E=HPVWq;C<=C5Gp?NSKra@p*ifAgmqJ=2^ugT%WCZZW7EhHP^sD#yDJO>UfaJkd5m89+v{6~-Wek8)w8 z^t`N`A-;KiH9w@d*>Ud&uX7w>&u0iu$I-L!=f8Tx=s>E@s;nZ*{oxi*!z8iTPwP9)ki;Yw70ED6ZU3$t@m2_?YN*MBjhQp4*JUOuc zcafiWQLr!WH=*Bknkn%2v_)yZ#`E=eyyRKD(+V7kt%5ZYhx98`|7)4#(`mmlY9F2&~lYoQ^^{K(F-t2V|LktRjdGw;e3mpj5s_A0ToWxQ>GpdE*C z_|YpRiv-rRZ<_M!bzC&cMnc+uqcatx+M5hM6qNXhusUfwZOkq?$;FR9YB7e6ZeX<_ zeHU=2O7~WPC4QKb97DlwvyZbNs*Ch*Ns`O1-Y`vt0+O5ir`^QNX%Ob&!-5ijliOOu zEqv?BOZl+avLt-QMVtzjI@k3%H`d{ zRw4`oxO{zmHorUGj~C;iviplyl3%A+=b%|ar|4JQcU6KuudbtIJ)7g$+Jd(DQMXla zN05_`*U&Kko}suzWU{UXR2v|@k2@$bbme2BMEcc_MD<_8vsYqJK8_~-qm&tVTgz`;rq(jug=|!y9DwK4;NH2 z+t;BK;ki-Vltn$ec-2+msv5ryWq0$>{&BqKwICD?-J@i5oo7x2#Zw^6#!ZodSTm8I zD*c;DDLLZ%jsK=G)N+6>>NQ|yH)apo8Tk4)sY@iPBh*a)exO&wYJFTE$eHx|jy6;e z{N&eiZ0e{Z`LJYuL^n*7aLiT_E$Fq}=1&wg}>f2glA$JFTd9|ljjz(j08S3_~zsj~< z;A~0v<6Ptx$}rXEb8el6vxMJnl7mTJ8(0TS5zpCmZJ5%o{1ry|EZRiL4 zc=q#Xx>M55d{f=DtnJY*I|@$(!E#rIEo6x0HM(nM&O>UpeDf!n&l>uBB=Rrxnd7+X z`J(aXL+r`eWq7B7c%Zu7rN)$Ll=u8v+7(G^X6#wFzAXo5?9U{>xl7pI8=1t|f{4-+ z5T{Qb-LUh3Qj`>L+LO2R;Yn}30LbdXN;~La+Bop4;5giRaM_Q(bF%WzK$$xOpRe9~ zv%y1WwjL0QZ}EUbO^^69ZVRwQS>3{d`J3NwexlKCqWrKR%Gy*;5RpP;3#Diho!-#f zdA#Ywp=JKnl-|+8lXnkWdb2wTq>jk?A!Q1lh|n6RaqWc)Jq!Lh|MWTS6FUtwq0Z92 zN`~7Fwk_^85pB7|k=2Rjak5kAn@%v2naV{h=U2SHS)u0JUo14ptW7BioGIJYQKnsg z;L(IUpvnM?NoE@Idhg~G$eK8HX!ca3The7{o%<0LsI2Jrj|#4A4vZsQBsXTLn01t#Q2!r-u>2j-e_sP@q7r6|$P@pBi=X@R)D2W*)iSA)tb z0h+6B1?8O@c4UJu>|#P+p@8~c7OJO70zz8+sp@^2E;8WA8bqBlfmHcOf=Uzs8xkVe zO|di;Y9*m&u^5q){9cs;E83lO${ybUt1lBeEoH9w?#2w#F`(7&VP>!F>4VDqZLJFKQnXKizD-eJ=_3dIb8NHUxj60$xoz z!*{gC`$i3tQgFpOxj4SpbhUABV1l<_R`SCD$OpI;id|2zr+Tgf&TpKOH;{LgOI_QQ z^rgLivWW3&OLY*JkSDTjM5}`ZBP4$@_t=@m{o~r7=$bpqbmbpWk zeo+`s89M%6|8GviS;xWQ76;Pbp z?}#r`-%5Xi8vo6*VS#d0`3p?~DjV2S@XCnh5{KcL1zeBItCz}jZT*PM$7&>#Q<}@e zv$hE<-;Q`0ub+)#;f+ANL`cmsB&6FkOF7r#g%a&Qnc8sEzlrb%0~h4y&uKu^!`H*5 zX%qN)kz;50&VpftyThU+Lh~O!!2#o|bmLs^r)T1K+Y9w~wFD7#J2SbC$(3@Mhr5LM zF=Vd3QC}c@jT*ptSRcbw!f8v@Z=E^W#?Ho}7c=SpUQ;Z7_{h;>5Y%rY{>sK^wR^R$ z782|JrI_%HN*TU4(u>Wr7p>yUT@lkK8+OJg^?WgN>jAsJuSupH^0D7|SZ8tNo}l75 zqfZ-FptoP=7#2EHy5@@=GqyCi(bS%K!fSRBE^oRyU|_ZTaBM=*NVcw_4Rp*1STm#zcpZt8wPFhVlGl z>aJFd>Re)i_lHJ3Ox|Cy>b!Mk(M}&qHM9;>iGsR<=4uZ0=lalWac@yAEna2AAGr6= z(^w4}=T05=tcUlA?cC?M%fx=5+XCeb@GIA9d!z#WLSmoGagPgt!ipw!8Jv(&7Q}1h zLp*!FJ4;R->ogxh11G+*KZo+*fs-G*WBNMEZ)}{nqPTjD{>Pe`(PMt(6veMHf7( z6(grxj@`6XkPZ4Sk>blsJO)0^ofgAmxlXY;Ci?WRpv=@9Qemtl^kHwCJVyX0mm+@F zY`opRVM2n+*>tDw zds%ijy&PKi>;D$_sr9W$$qh(!EPZ-wsTZ5o z_^PbBpzwNLQEAMz~&}}~)1zoGB4&ls3Y>SkWA0&*Tl~3OLOg2xSGErE4Rydm*2iUD(^YBiHYU%C3 zjr++h;ph0I2P$9hyJr|*pENaH(W%?uZfqz zk_n<67=^7pZ}X^TTZ_oQd>9}lx*jVzX(Z$3lg>9_|__* z;{W8T*>ia36hXOp$Kc=uz_65PS9cjO+gDrvGR@+rA6bgM`@1;`pKrM}rd4t|XIm%U z_=RtrrVXOPKi6p2TKqbv@QC7*N}g%_U`*Odq|OB*b0->X3G8a(ovxE?-*O4hgDMs` z=1!q9JSM;ru*@ zz>6SG%QZZpFLo{frkC0CR3Yb;lhjM+Z`pL9V76!yn}VrfKC3$II*L$#jpj6ckptG| zp-=JS=BDDuZ3wCY}1WtKFMSP4K z(Sdj5ftFz{f*8AFz;nysg7_;Q;XGtxPjc`&dnF@guBP#7isGTv*c?Z?>bJDChi>mi z!J{#2(J~n^ERF;j8qZ`l|MZQeDIA^MH+u&mp#etv8j<8uP~NO&M!*FxKA(3+?8Mil zsK^sd6rC6iwI}_&L2|EuwihYb2wC;0z|?vwBUzU7jyd@Yj;;^=nV6&Alyd64V_@%C z&G%j_GF!RYyF);vbLj4vp+{lkY|t_|o*-esypk1k8P?hCe-Q@DvF* z_ag8|3{}5IObJW!UG(LM$(FV61sHaVt@^kC4P$(@TwXx+s0PTJ4qbsW4l69MCdiAN zONwCr)12u&%99MMn=#sYpRUTixbeZi_+94^h$w=&nt~72J25PyPlSN>hW+( zYsjfdxV+y9P@7TQ{<+!g#jnp8X(EZ(_s`96j$*Co5>NnG0c^n|>`EFqB?^G&WwBpqfnzkseLzLi~C! zQsy5eu*NX2OTU8Cy#DSy&hIeU|A9e!h=CZE>)WiLsY!(Y%r3`GP5{R0lcsBZYLyb- zUnJI}k@aN9S!CU%%04l_p=n9UOF(rG`?V4$zxm`QqJ!I>gWDC9Zfv5`y6$U6nQ;20 zwGP?a{ps90`+i6r%rpfi1SajW!P@4~W7|Eo&i0~>_~EiM17jB1T5kH73}a>Td$Q%{ ziTU_aP5Yd(y&+EJN%^etA!|Ngr*ZOV87&B%JBkz8PTw|j3gB`<`0aG^6>g-5AduuQSP;ZdW~Ud4t#o z>J=@PCWNma#ne{A>(=yhC?>`Ydf#3Z_X)={>e}YipL{V6#~eg_5+As4Si2r|4(Sx8 z+yxxtdwQ6qr^0L-c!-ZYhhm*Vs3)!F-zRJibj9O*HHUs0`&s$d7B*>1D$_gP*RV|` zWoA1HJfVmngk~iriztrrY8am9{-?nUM6GS7bI?<-{VFy-+v6zpmS4x5gKxiZk?V3d zRqQ$|FMlvb29%Uv&S9Y~$!@aZCu^4vYi{`25-I9}8^)r!g*TZR9WUx9gdh@lQyk@O zS9Q>D5{~P)K$1?f`k)J};wd>61^4o5M4jQ4EwVrL&I&9bM#|oZe-6d9UW%-F@3}%1 z{=5f#f|(_tD7gU-yEg|**PHu=l=1cE^}wDM#xmA(QL9XIF~Y5?xS#)bW2HMO_VQ9+ zYzm#xe73Q=B3q`lymi@ep*nq{bLH>%Q&U%QRjn1hLS(^ar`p1CQK1$4nttKlvA*R# zq_pySj5NyOK~9i=m;hCG=VBNMLbF8<@^5fR1qC?*YA~tp%oqi^C#Am`5gvogMVqVm zIX^d0#bOEc^Jc;J*q+|6J;orn;WkHUP}oabL`s=+J?cqQES(pV95192qI zW^3C6iR2Gkw-~${OR%6_0BNHlWa-Q1#SsJJ9O9YZlF-9)8;;ukKKl5JKWg{>af517 zA?_=&Hc*-m63;$-kCRN>qIBB#OKVUf?;$}hO6P%zLR+lhVOs+)*piXi7K5DiMnw!~ zEmoC6mdSVP@tYm?Z%>CyGOF+dG3++}GRTg^KdGsCKE_fW$_!WQj^p{o@Z2%#ZM@$7 z7E5C|5j@1XqJvXV-h0)dH`44POYvI@6I7J7`EyNFmD|>KH`n36r0WaIJ4pOr)>A)8 z@_*i3KGL0Nu?VB&*v5vsb3Q$c`ZpDUv-(HPf+W5bM(j=dBg+ASw{I7Ye?C2sDRH1O z8`bEgs^hd9MI^d)vaAAmn))H=8mV~zS|C}NIh%txRk|ETOT5=>D@UzQ9o6&3Gy?Rn ztKKJ50Z=i&Bgd#mBCliJ6hjQO`-pltwJ^8V*oU@5DoZ5>zt5qO3e0F#kF$C;czAM7 zXy}F#^4N%6Lxg|qmYx0b*yH?>_{$Jow7qVMB%NUOLU-A?woxMSspE~0v+j7U;a)a& z#9ZN-ca9k_6#V!!zdgt&!OX5-{zq6Dt5!{RLD)wx&X-uT8aH**SCnUmo%#;qZ)hHu z9jA~bjjH(an6L-ysV=wNB$g=J!K@jIr-g>Z5BsU+a)17L)#a#QFpT+xx zEzpYgy)G2Cu8psB&5y-Y0kph>=h+spMlU2&PDB${(}lgpDxWz<*#|BJR{r$wKCZOy zR*Q+z;{(n8)*6(OC4fh(k6&iwcFkK-#8J*!mN=_{1z8=nKBnZ8Q2uJ_7kSf;Eu4b5 z-cVpO_esvJ>d;KT8B^U4j7V`iS39={v#@PxL+xj>Q6+d%_0v}!%;Ucus%BVih4}CI zN?*QE%LfiK@lU%G%%o0LaD0KsF9Rqu2uyNt^FA^z?RobSATs)`wR8@n-_(5QO@96i zkj3IYqM<&4HcM1(GGFAIqVeMWCT+m7piTWnoKQC?cxx{TkocGOmdgkXE9gUFz$J-@*B%N05d<{U_mG|rF3k!1W zvSzNcLDoO`7(AH2V04%C@Mc|EIxuLtUTnKzl@98M0bM@}M`4fx{4K|8UCjl^p|xV_N52Fyo^mmHTokWDhf0cJ z6o7vHo}5#{U#rhCshOtv6<+EW0!jLYEY~NWr{2fcW^{*LWkj|+*Cp<=kbkmk$(ndl zGgBFMrSq1j{LoPuDZk3ta`+4_1Jy7^+>h8-&+F#=#UuJJSos3)v>x!@ktvO-$^6Kq zb9>A}{_2^olrHp^=zipFnqIPfVr-pj%CVE(F%Zf_>eJ&s3(<*(oy$PT_7<54D<*qU zqPsZaw-){2m^|!#nRx7CB64XkC+<}c-C&~TDl_P8xbT~i91*h7tAFD54 zannSl4g9n#JdLPSIG9%KYE7UJy0o>*PJZPTrDM+YPMjyA&QJhjuhw9TA0{#* zkPV4f-}ARZd&QS~|9mEEITR^t9fU3D>ycs5hAsb%udlBzYY zGeVuD7Afb6Ruh~>rP$Qav>3Ah5r=7gw18??ni=mS^;&}o&ieo^`=cK~J9GiBsQ`zS z0ML^mhf~w>*s&wKF+OI8Y;HP|?E};jC(DD*3B((dsFhE6?k?+!(t# z1Jpj6e1VjkgAN|<062AdWwOpIl-4c7=4L089YvFOu4#W>(OPA1H zCu7}n$ot!jV@@}gJV~x#I`iJDII2BkG|z);!!}iE@;WbIFk^HqWdz6IV&7@AIh@Oa zuL&V_(8FiEWZ(7aB*pW= z?6X=crQ0L-j@=zHvgeb<0d@zSk@?N=bMKVLpOa#3A2lm2n18la4p*qMD3)5xHuF4e zo=5^H`|dff)}vaBmDgzWWh=;7AlXd;*IfY1!)LHKRk#3>+$SYZa@k)>lK$dHTwt^{ zmOWFzp44#5w^x0n_Iz#Sbl0S+tif5h1>>DbRlteU!i8(Wk&2l2H!c=CC`wo~d!Gig zg@yR^-)W;0YWjZ}wz4_#=)dr~gGhPXz3z>DC zruJO@5}~@?_OO4>J&^rqa)DuW)!yW#F$=zkKkA&`?p^pif4=^ecfAJv7kaew!`?yV zMO#&tB;HX~itgvunUCfA-4o(W3w(?9R4Q#h#JoHlpi}&-w7NBL`_}8h=vzkL3jxDc zfEEP3GXah*1`KNXlD}wRn33Tl#RN!=jB0p`YUJdDD}~47H8<^Io){2@PWYbl+0>BL zTkZW|kf{r)vkT`>gN9ooT{8o_sDcjW#vb#~*?ZKjJr7~y8KW(& zyzMs>ET}cIM+rRnq5(q1duLqsWv!KQ(Q=YA;i-l*iI2TS!dq4gCl{}b#Sd38FSJHV ze%YJ7P&ANd>-R`a5_NHY1yWfd=6m+S=f_l!X3XgK(}tAXevcBMG`)%N+871|+n&F# zXE%BU5(~%w9;Tn#3W;rdLMO?TGU=P;&rLqvIW^s1ef6|*PaOC83hU8%nhMt`814y> zTi|Xn;oF|lOk8l)edQ_kv-01E=_G*zo+IDQai`=-5Kq*%0bLHeuxOWGaVo{Z;OZ&O zg@8LEH)^}5CCi7gru-UO3$E?Sv)BGZpRe=X0&nQu6yV2UdqF{|QmDw}PnZ|=QX>uI zklOx;b4m4HOv6Grbv-Z;Bp`{%>n<)jTHq-La@v6(YbB0EreckgSU*x(pZu&FKCHuI z6@XSfYxi?ruayt?b3;6=kfcXw7J~Byumf(y>sEuUwj`t38aAJLdZup_c1zEIcZEG4 z;+)gO(}*Jy*6X%tfmc^{sm;TGi>74yn>o%|#DFJ78~9J#Du*2Jr3PPl&{(PQEdKTP zpk1iSZ@P(;?W60iS0M*eQ?w-~MEqQVelik?QfXtP9~gdh`{6ojqT++abk?s=cHtg- z9IN~DS#42iVy*XU4XQ>K&}KXh!z&RW^X0ig6)&khKz%BH)}K#k0J%O>e9_|)VHOqk zntBNSdYq%jOGxBhSkW8GlA8OrBv3@DLgbsEAOS}_t25^yD;Ey*km)tSxQsgJG^?tK zyIoO#x{bo)Q4Ws#c>rhDR@)<_e#4J55s{Sg*ldXT2sLkSknOu9@pJ=HHaPRZ#dI|5 zwtLk*+c}TT+!6zAK7^)cX}b1HhbgSi_rzP4|3%VOu7~|SqhUW{d{`>Bujf?chc^dQ z;_U5%FtZ-g;LoyysIW|g&EA9A`{Bzgg!xbUNP4?ppU;qZL`k3KAa!qg#p6U5A=%#1 zV&Mu?8ua^7K8IX4T@7I{wJqPA7rcP7tZNtrKjtrhAx7yyq8K~cP4Xf<2AsjZFO45G z*8;k~CS6fd#7;-z<`#so^5Kj34}G*XD2V5qeGK8^BM}Flo!MxxCLXNF(AT@J_3|s> z6eM50S~-GRdZm*4iJnoVGwg3$-;k>Lm5cd!y4Bu${0Z@Xp$1Ai;+P{=b|Z zn~cxjoy%AVPERt6Bjq3)*-&OpIIgbHoNCNwPk!m%alG^OQ5m2TvZcIVc@NlVMUCCX zJ$DuEw>-ULT=X4r;dlwW+EERcjw(plt+uHMSkNB=RkSPD#WX5TL(nAvb&5IVNPy5V z6$*YjWodl=rA;nlelPH?H2q$~!`l17HY+mYwKPY3M!4Shy}AQqYYdlt`c4YE85S<* ztr=cvjkLTn4s7<9#V0y04J3&$L3&vadSUZgPC7 z2V0AoF3^VCpb$3oKZGR$1cG+vf~ui1Fc$F%-l@=pjkdUV+x!d4+h+343{YGD(5ykO z+OP$U(B8Bs75Hor+_!~l+juLhsx()_V+LM37$^x>J&EcM0y2$j3!(o|FznKP- zLz?<*_Evwdm9H*TvRY~~aYxGbx7NcsW(@40DBr3NmG%2SXBK}{zguK#3ntjIlw8~g zXFxbkrLNH%o=YJQuBD&|!dbEZa2D@PZF54FOerFCKl%?w%&a-x$8&AG(J`%x??6v4=G&rjG-;vXNTIoap19ax6onX<^SerL_ZacDbk@ zG1TY{+ZfkaIx~s`dwxNX2yqp$;MV`3T@jaGJTlH!6ft7p zKUH~{6C@Kyf5q|N{0+OGG(^ycfIjsjuZ(zObyB|8q}sIdP20K2^)+vHxUXYxK4WwCSq0i%W?fpx@v(MK^Qj|nv;72pO8v!z zO^MP2cMazNw>DDXzxynn8SHbI$|sZ>!_Edua}LW(eIf9xh>`SHOG*#FGpJ?IOiO7` zDEIbti51&Vx#B|dOP@@CoHvt{UM%p0Kq# z6O_6ncTf+jb&=b9_gr(E2}hk`R_)=lFw-=+yuv4H{K?>2j-z&z26_$poVUO^bv-cu z3^gS_(EW2DZy3e2@6;Zewi8NY?(vcO_R(0-axZGL@qj$S2MyxDaTNQQkF4x>Eqp<& z*nBoQ0}|m9O<7~1LRrKaROWI>Adouf5TxVxFQXF}v$|aY;(zYJ5|n{|LlQcFdp5B< zDU{A)EHg@80rt!Iv&0m9_RzLjv))&=|qJ@({wTzqHrHP5`ha+X`YZ?A02KPfwChOnCBT2q3PzU+Z z_ub|PZd>}Ph^L!N+smKVj@$q874H~2?*o1PYGwWwKal)0SRF9D+wWe2CO~?dZP5=p zjOhyR)d}6t3zpsvu(~HYM=^P=TP|iU8>%{VRnWs-FpirVD+fSn#S)y=R9v#P=FsM{ zMjH!gYI;JeaV$iyao@meGy;|Y>RXz5=XJD8c*p+hTgb?C^6Cv}>4CbjEH~FEI}hjr z-Mj#hOv(2;ZL-h-sj3p{md2B7#x;#jJ4d0pG2uRWEYQxt=QGQ_3!;;AS2%A-DwU^h`#tatwb;zKzKX1;J$-L2(Aq-Gg>QxC^YP z`1`3Kqq9iNB&+i$@W49=pPf=+P1r`rVgijI0-1%tTbmPX8cN6YN8g4$mB&Sa~D=3iefSJ#ur zou-xlIJO<57XbInT7T@-k>5Y0-HUc6Fgf480NS`+_b5fl0Xs@6OsSmpzq6hE{9Tv| zj?Io#c72A@xBMKY40~2d`F^?Q#=@Wyt1X+gH%sPGE7n9pF?!A0Aw0vfm{nAr>PeGC zE+_D$r2AVF6nfVfx(%B%))*Yju0<}HCoHxrEMZg>D5*S zF=-C|+J$$`ME~CHwmjRw{4X1nh~!sCLdpoghE#`t_-RG<_N_)SWub+41ol4Ou#OGubY#C){Evrnh!U(rayWqAaF^u-Io5O5^McH@|JkK31u8J{IXx%IO_-B}WIzpk|`0U}&DdT0uIlwlJ-g2AomCzE~= zzAD{GgO{t(Pf~gGwfU)M1H)_~+NMk#ZyWja^&;3_ z&9b>J_H%bs#!E>s|Zff6ZrEx~{{jLX!JE-z=7>Wp~7WL+3n zH_s!Ar{~Fbi;~X`+KWE^)Vj%E%rexwKI^-W?&9X)vW_~AGYq4|&Z-pyrFR}CKfhUT zAcE~9M;ws@gi~OK#Zt?K{mR|BC?Hnp(f%nnG9Y`De9YgKExx9PRSKoNGd0}SkA2DO z%cG^;l_hyTpeEdtJ-aw+_Z0S}%b-`x;jJJ+h>bBe+KGfFB0Fl!4%3O$iqxd=vLHhL{wQI7#K(;H0A;94W7G0^lfeBjx(h5cLk@qdNA5vGUAZ9Gne31zq6}`ESy7nY0Gcg}QVDw93g+r=?)x9EPP}Kq&2P53HQ_ z_iVxF>_IZiEbql)5`=&GSZO(sO3}2fS%#Tb;?T(BWHm3Q_R^Lsy+6LyevTH1*}mRJ zpB-F@KThDNJIqwXzBMhAET8RhTh(aRcDv=)4%X2@>gm}PQg2GPDv1M%JOE^!Mzgfn zvyXVEZQzYiR>hN2?wdIvWHswDMuXbIdx7if1M0f!Va~dpn%M2z7E7lJgg;?{(>Sw? zJ$`AIz&n)s@qK0k{Ryuy&J;7KP3MsF+Ww0`IV+LzTB+(KqF4WhztQk z-{ajETpR-ClfW7B!mXO0LI(3NG!j#n--9~)?_C2j7q)`F+txyPBchMV52An5c3tT@_6d=n6f@{Fdcf#0@W8_bz<2Y}K(G40cx zuVi@uQ*zq0!&b!;b(!K5_G7>CkOoTtTob113RV|y-`Xo!bgjrh*73avP&&804v*^# z`^(afYtI4sFqV@khSz)dt|6afPC9Dz7(j8Ppr33X2vmCGAj08GN^!xK!`E+4QwC+@ zUM_RMPs;U_EJmLu-j8#|YT5iGNxAU;*ck#jgj(WyFTSRXPI&NdMD<& zX6BXyB+MOxq}o6P8y|T6~DiHY_@a68&IjCk7zyXkOOg?#A zUd9`=%j)+(bOHaspV2; z#2GX?%?@H?lSy})uJbu_wHYj_=QEE$VeQI)Sj&pq-qLSgm0p+Y4pVYMo_PqOYpEDN z>az?&gD~+h9tzMk$z@D*&EGefL_=jSxTO&LQ%|@OlQ{=sy`x-6RE_4%f)cW2if4U& zchi(tS4q;bR*|%uz0=rCTebu_AzxeXR5%X^)VE9D|iXL0Tp4IH}M@%@NR z-4w`XX^%*Gw*RjNGFE=og|nZ8SDGL7qoMyk_!L@aZ{}*7UfwZi=3FGuuQBbk|wKE^WNXsijGDy0ik=9?EE=psz7%vo}%G9Wh_# zUtTCNc67uZza4&RYE1W~MYJ!CASbOsNY%i$t#;L}e07)Npeww{Z^I=G-PSmM~w-P3*+=g2V5wdY&ZnhUB8{e(th? z&<`CgO8L%Uj>ZeN=xC9wdYDFcmQ%kkDXzI_lkDm>b77gLJ>>xX%#GH4wxT>RKFnbT z7;*1J@9a&liabZtFueBi^H=u1!JQc!tCB@EdByxue6MDBWu`nMADvSW}DlR=QjF%f!Ek(!DkAkCWU+1GSFXB z9Z+5hy7_Dq?=>=7q*Qkb*=q*U=N=)eMt&CFGuGqw|m#suoyrr?k#wu@lUS?dAnxgQBlEU*72Eh7VG{>MoA$B^39RgT{W*@wIDD2 zt;RvKXZKa8d>uT*$g2WIrFow^qjCRwunsJVxbV4CwMk81ttSM~-1j#sAh1wqt{Dpv zME|{0Qt3+!M1w!ZHzGS(sG5dqsQvfX5&g%qw9W4RYEe3{omSggl4a*ViTU*u>eC;; z$7-Z7BaVMO!9^>{-umfluBso!R88qUPf9{cd)wv*ITa%M2q*Kipc1M`1LT+lQlVB` z*JpSGc2ak_Zta!Y#A3vJ94OY;*pFZwD)*)hedt@$J?Sh%JM?Pu3+`3RWhF})qRfvU zq1Xs0Zzf2RX5EB_u~4gZB6C%+03HP+lj`}5EMw9g0-1Zwc(E@+cp7kO1@8N5Pi&#h z=9&dlM*C}mdV{xIbD#PxZruJNknNHCuuseZ& zkp$L>b^NDf;lA!^a@tlGw20>{#saPKsl41ijrQlzBpXcF;Y-lTY**B?kb`5NeXb1M z%Wi?X<=lH1wQqfx@yLdv3(BfRQS|-TQW^Is_0IVCYto$MWQ(UcyE$Uo#+lzo>JBZe z2q>JMr0KXdBZe@00M z#$Awl{Wsav+VWY2K1fkIY?0aV^n9y@q1n8{(bIJEt37$}J?UllkO9ibL|+m})7>6} zEMEQzM?*t@>v%*ZjbO26?#GqlzK(tk9b05y^*=& zs!dd+)DxSPpkW6zclP1cX_-A_ncH&akl=gM!q!>L_=EWcfxCM3PSL%-#Zwi6hW_}K zPb*M|z2J|2O~}gjvkrcsy>)?VZzWR)%`1Ezy*ecmJH@;8VpOzGzRjkO6)fa)P~;-d z+#lHuOiFyhq;3Fnk+J{L5WOG4;w(J*F3yejQ*hS{r&je~GpnhKY3Cc5c^MpUIj`14IJ8a(2xG)S=OUz2 zPExza8|o@(Vb^L59k%_Ob$W_k)p8D35Tjk-H~xFe1;bGpB)ZFW9XFIii3TcifRb8I z@G?VDDVOSQWb&~WX-qBKsXogOJP`9F@2h65#&n$i4K8WS%->5aH5prhl3Oj46+U#l z9Ius0-{atdG)39t_7efC#}aPYTD>R5I+RvE#?_pHV(q(Pq4O^KLtR=@G)(iwnY3|) z*2z^cSM7ahNAdMuc2R!eeW;xr#a2^D-%+=X2 zs$h)&$|oRgn~V5g!&tfy@2@X4{PiMuWRFx}NP%IhBd?L_<00_Lh@&C#BwxtxC1v)rQj3zn`OwX^Lg*$BymQvRa{9~{9z+PpwEg7A* z)=sdKIu%jXb*|hUcwIQ-RDBK=-V)2$3Y+j7OvpLo)WaHdAyQzvVLKf#>+gHBX>u0W zLZA}=GgQ#HVEQ z5=K&VC*7KhA6H{OXbti4Liw!HCNHRnGS2GDKhg3TV5Xd$cf3M{u}GB8XhGl3ZXsPn z&ekhfKi!`JT@RsTBc|~!ZO7Cn>8Fh2UWoy=Mtg9gVI{(W7nq8))g>DgflK_omlIFR`Z8XaO|wQH~(So8}_=MX#)&)uCfwrD~pLyXM~GU72?YNN+3tr1^KU&yP!uxWL)Td?V*5^K3!ufY<{1af95- zHlqfohr_YjfX(vq za?7qi4xt;8&ldA)*K1IEE;k|{Q2KA_h^7r~v$u-(=-z=)9C>n35$HY7Nur$Zb1c{9 zOez8X9u^E8{CpC&rfLdB*W8h{ZLt*mUm=C>`OrnH>n>BH9~S8!>^kDEx`f&b|JphW z5xO+LLk)F$HQ!sE9l)3ibFZ8Z;F;m;iN0nX zoR!CujL_5jw>9wz+aL9nj0{Ln8eQrh=4EN8ID1#0c`d-&n}(9IR=qNOif?r9dY z6D}xCZ5R>4f?%i3SpBmnFMg%%eZtsS0WjLZs9c=7^Jj+QJ2^ikU96Y&Jkmk}g?w`F zYALmJjHB6@F$7Ec;cpA$$(1XlN^*Dd--Gm7#<5AxYrfkij!gGHj^%1m$jkOvBuQs9 zxXiMzX2t&c${MBbO8=ys@=B=aJ6tw8>w{uS$-Ow^qT}7mZ7vO{XeVFFz{3+0jB{q` zC?*j)L~8^g1Z0=<=ErZE?^ZgTvXk{48^2RCkGZOi+8rMb8zY`?=x_&MCp7Gkbq>F= z7l4yh5SYvsOBg|6!RR<%Sis8~ieBr;)B!vli{pePaj*`n2!97JPAT`*9TcT8=|e^D zVw9D$Ao+0^``dqt~U5OJG#tT*V%({`?gdMZM5wmzpu>71T-Y8|_#^>fb z#Vv1k+n?%LZlv0cf?O~NoAEVswwH1B9eH`5&~Fj@Kz6&)0&++bBImRyqjEliJvfaj zV_4!Y;KoO|A?V06 zd={?+-Twj=0}gkRQ$)JWRXa|CV4qiSoUzrcGpOhwo23i|Suq)4OT`+PwoZRI;tht2kP)+RI+S^IRBz&dDGjCWiHLd6MPV(E>%v z`sW}brt2a+`sw6ty{1|UA7+olTDx`Q<=m&fZR)wJ^V0hC5Qn#0^N8ngmZK1Z>rUt%tn5qt_!8v8) z;kl{IfOzb1enxeW!aROaC4IH+E_Of1x8JU-`wA7lBHxp`=Bw<;hUcl~?4x8@^O6Yy z#~$B$6DY5oVIjYhNOt@tS-)i zwSk_VhB=qZYxh2UJ?(ajS{!f%xvrVoiQ>KSRzvrmDF)ln2KxB=eyPq^Hl7zGdIzPsO#`xn)8B?Ta)2fD^WZgpznRfpApn zcmk5-etwskhNYWM-ZI4u)lP~q^hLnY)-Jm@*Lr1>_5*Ed3Y$36?C8 zN`Dc`iA_20tM2#9>ZY8;y)P-uxbvbv&+ufaG^1U@QiTuHtRU=5VoZjfgz{t4!#j^^5unk>iQF!}A9>_#zCNlaqy;&QsvXs5Y$!!ShW^f+OSnaXG+g;3FH?hua*# z6LSXw($7KQUTW+|RO@R0rv*4yMEV4LP9dlL3fADIOOP3M0*O!5O&+t7kAf-|YV$=seC0;oxbNFFp7PCc*0+9fX1^O3>QGD9 zFucVEJRkpC@p@eKbjApUpe%hvmIukOBTOP+hNyKegC{iV7_VRX*Z!lh!ckAGPZ+`a zohfW_f4+F`*~!uMThgqjIy_^;rVL5&%oCLslD&ApQ@8v;`5a>AvdFQgI`$cn9fpG@ks#Uez5=v)1VrAxo%7kgPrDF?oC~ z@*q^Eoh`hm$;1Hb+Z#EYZ7ca61d=otrgzj!c^CWvl-4`=<}nnhV0P&Jg{jKVZ2%Fc zGQ)x_14Gbs>FYZtzUEte_3hix^&ugRgs(CKMmU#*;^E47%RmcHPZ+oZ*5hIzf+mCW z9DY$OL8E=_6%t>O+WK71{FRq!49kD{WiJ(qRbu1iUJEgh)xW081-t%31}j&Yjo_Dv zewh_ZINicXWHKfc%Sl!&4F*CBu7TR4N~LeVU)e^Y)>N4@y@p}FuIAL%z) zC`KXomCEQ`=sLg3$%0IQCEtCFetT5>>v_+<@#5iEeFQQ0k9c54$IQ==w}a$ff1R z5&H?cMN@ZmFRZxVjqp0fz2`XY1?WlQUIfh^8ek}*r7b>d?-uKE!}ua?Vz%aocHs^n zp)t}$-T$PKR;#s7#aAE(r*E%hiMR*yd=N}3zbk8R&lwx@>L@3_znR|L3cIkMfO2p> zW7L$g**%-box04oNonQ#U{r zC>7-<_@I2h-od?3m}~&P1))JjaWjOmz3-o|6&HFXU@&bDH~>fG<)3Wu^W$b&jP@%V z|A5)EDKP0A5je@`qf4`{dT&>6X^T_>U)IBSspaP&>#Oa(?a7&kF_MQ5mn&!^QpQL2yp>gq`a03l1fW zd9t%VUBcv->W3uU1z1c-G#6H(d*P|390N`pnGJxbbacCsi{|R zVXIVX5`In^{*GC5!8Y1k`OYYK-$L}9|KEcc-t9fszf^8?L!Vy7cPlklt>sXE&poR( zwd}|Dm$;MlCg#sCfBY|3VxQOhbY}%IyX?}5B*g*$3e^Gh|0itw+r&XuWL)t<-~t07azHb z4Qm`FFIppk2^E1o!7R>InufQ*oQ1XP8{?v1yOOG@LFqKg+*|`9ODEw-W1Ml4wlmlKo9wch_;kq@N`}m*BUH_}pP2&!Dc% zg_?Za_vNy;h4q-z(9$r6fVN(D!SmU>Y~`gZJnvucMZf(2zl-ss&TFr;sXe&I+0-f; z;hn(02YWO_(P`d{PgbjLYZ;*ThYuSje=rTvvV41IXyLDd)z-2s4_8Z>eSe)reOY}Z z{?~`~zHcU{*A^Rk!*LpFMh;%9E}BMEcZ=e?bn!PmhybSI-|BxGw#0{t$=aCBTtmon z%xBH0XPodCAiVB2DfYgn#EG1ciiS5GitJl5DyJA$+#hv;Uh;Y#$}vOtZ_jTFNZKKA zI+$>F^CNmDZALV29%)96K90I(q+711llHK;9SeDl`>5nQba&E5zqAR^$ER&E3>W{v zEcSD*=1r$Dyf}5DHxT$^i|kA;9XQ`5k82IN4p_W6C)(5VF_OHShAEV+W+SB7E)JOf zH3$2HZ*kXR`KBtqbX-)Yh%$z8x@0fj{ObD#zWi;oCc4yfBJid*wIOL752iO>{B3vb zyEd0rWZpM&4w~%iuU>sN)WxD!dJ9Uk=9vO8lN`#1up7fzl1u?ZwOTmEV~2y(6vZhQ zCeyEMkI6P?vA z^~)1I!~WYam5s~feZ{*bU-+#s`KsjRWOSdd3Jc80HFUBUl~ z9qz6L`2RP9n}P$f;4|p<5-eO6uWbrp&-VUA{pHCuk&pp%&8r`CL#w<8U)54~aA3<4 z+mjmE)%|-c18(M9W*;e?g?QnQV1?RyGaAojCbEPa}DS`8CR^ z2iogLUY&`&qN9we1{};vbjW@eBp*~6IYcc2zwC3Ehpcm zNgu|gE~gq%Oq7eIU;YHobCK9u?Jhp-mgHlr97PBpV>C;FD3%eg07WW&w5p4vT=WU8 zvAB#g>oqqhZA`0ROX@=)_keT?LOT_vJTDq9cOq!^eapC8EgY8;xV_zOwUae`jc4Xr|dh4_L)Np8Oj;#9|5*zJGk-Z<>`1 z(fPT*hkf9GD3zB-eV%;4YV0kt)`^~=&7zjj`pNknoxYT_fLN>c1HW*Ao$}*CZZyAZ z(At^DTt-%|-GqaAjuPCsHBmXsK^cr|D=OLsI&gnNxpDG)xR70IVEyFEic3}vXAx3> z1HTY_;;CP)EnGpH~AKpSQ@@fch=bVcXu8g`|xpmR+vFnxP;NN5Rm zIYe3M6r=K>wrA#i1sRHe-v9JLJNN_zdu=EFb;cmVAC5&1+X@#<@@0wdF&|5r3!5bL z`;n+%^;gF-&}ROQ%{K{A!tz$w4`FyPH34Y%5vYrwjC@xVnZF{nVAs;NNqU91`pVG6 z1?P|?FPtC>>((zh)gZ4FB1zl&#cXm=V z?yURw(&q?B_@>jFsY_nO{mw??5{nXn`Bi?NYXa3_y_-G zg2mcK`ARy9j#(kX5r?OIi~aEG%137uOe2T`g=Gc7H$HdO+gF_beXLLvx6RgYBbGjy z^^k5;d1x2^??=$<@xmt8VE({e%t-N{A;K6q9nX||F zW;&(!J&nhi*B+W#o!*s&OPqPJ>C6-!$lYRNxjuBpZeBfi(dH?$GBudKdv4hFiK0s3 z@VW&@w<3K4-L!;k0-fYUZLA2%ict~&EM<&_sKS0M57d#9#ZO9_z_U~WVh%AN6g||K z<`pwbHOI23eoq`#_eiVBhQ=fvFeHKgvChL8XQ^ivqaob;6tpYFbqGEj#=fworMh_RC%lcUYyJ)~YtkuS=CK()x-xzJtB;$zR9gn`EtVMVEZ z%x{;&{@{2TnT4|(hi~Pu330HBOFn-Wvl*KH$1roQQE^8 zNE?`I7ysDJC-!vqjo(#oh^woIYm-mJ<4abQX9qvkuE20Z;{MBXYPj@?RuNd{$?!%9 z*XrC{uPX=qTUavEOtx!u`v+epfqY6UPy1J)u^R{fij;BPejBlJB&zn*=>Q8rc;n`z zF%jy4Ru?tFZSXByKQWp|U}#yrmPk5DJJj`Qvg$r9W!&E(_JVL##a-LG<_aOk^7q>c zR&Bm-F&)su>y zu%uw_Z?t=ku09b;xraSzaEHu6_Wr#$d&{f`oe#8Ms`Xda_>)SOab`^t&3K{4Ir4$) z>u3NWRB9_CM^&rKxeLQYHxC5xqZEI-j{wTVhn^%OIdxbM`09=o5gOxoRAB zJMBla1_*N3bdB&2$#;whmWCyKQIX6sRTHs?u+G++N| zGqXz}#(J#zW|qTDfOnRj_-A#$#QwRKn7s(AQciiiCAoE6&q35QcTBc&#J~L!jM{w99b&-og-~H zqF{C5mL!W%Bd0}ztfxM8Q0agyb_Y)9or$~?vh97J$siI8D+v+UPNLTaAv_f)90o zrgzA_20tPR<-o%5<`eXu#eUu1Dm=|!eH{rIJ1@P8n;e+qU?_wlRL?s@u9(JGErQ`Q zwIR8fTPzyny(L+~oO#i8vBkoS&)p)tGD%KZS%1a7L%!GbExqAO3T221wRUtjpIGG6kGOVl;Lb}t9?zB_L6J~G zeGRVQNZo+&v-|tZS&H!^#N4Ec%BK$cT(B5>lQ^(Es5&8^YqK?2?=d{r&sag!Q0AW1 z8=%PGNi5XIC+6sQ>HGB7i5RO5nWW9!(Og&mmj<_!tZ>{yrGKAuEL5KO9{(miAfvgz zs|7F_%D38^oC3MH9J;aZcI)3oO zp>qUq;+T=eV&1M6d(=Fo^2k+-HqnP@k(f2`tOrN*Z8Cd#Bl6eMxpH#$r;voMFWDhv z;KhRK4G$(>YzjcD9{bLpbLYWkd6HS##Kj0+QP?4RH8x_xIQz&&lZ;;QO579I%7>R5 znDux=#K|SLu9MrTGzCaP_ci}$j*a|Um$iFq;PX@WRmsAzsR3vdaS7~YemUZkxu*K{ zt4Y+_LnYUpu~s8nIc)R01UAsIS8HgYBymK$wmaH1um@%w`}x?P`-8%nGRRZ3b6R-t zJL{Ks9fyS*hEY}T%D_DrbJB{eAEwm-@GEW~ekjBaHWLF2b2{kV&-jHr=|C zhn+ju(P~}BG26H6+8WAB&OA*DrAB(rke)+o^hDAtYYs0ArX6yxdI zA&x~L9pOi*HPZY;?MR8^x%XNwb+%WKpxZhsWv|npSMj>Ej0Xw}I+H9@YaxAa$Gxt+ zTX>Z7e;PyOcIs+0mPG8V#_W-yYGl|SV%B^ahmiF%xp5$To331vNW{?b){ z9u{!uJa?{x6YPbyUi&GyR@KDGzhugr3d0hOXNXnyyE*7Wf`7I3+b`%B z`Od<73m~JWREmk~biF{RJcPGe2VeW2hW1O~sfh|!c8;k(5O!eHQJaZnOCS0hS~>F* z?Iys(a1ok1?n{;T3@6zUpH+Yy;i!lrCH;rhOkt+vlw9~WE+JyB_*$zf;))!kR#{AE zwR=l2DIa4E#Xe?o^R7EueWEZ4xepuF{?Rora8B{y7S?LoNtJd!UNwIXRQxoDwU6Hm zi#s_OVuibERSx|kq4PFw0!a2Tj9esx50M%SZLmQf`H{klM-NH9<5#GRt;$bs}Vqr10uocP5eIbh>x(N?RA~;_8 zKxz)IM7FMfecr#ta57#M4YBfd#&WymG4Q6{@i1ap63*mQb(td>%wRM%%}H6{ zulcU#xIwww6@E&1*)O55_$7l^psH6c<&my}6f@F+@ir7wE_%T_BJhf^LPAI3CjP{i zA3D#sam!W?($iQ?X`vvN@88JTSM=bE;^6O0R>><9B^(_YG<2)Q+00;jBqHDWV~QKIpL(BI9e4mK{{BA_3Y^M zCJuBr7mO|4;h1t%I&!V=0*{<|uFsX912Y_>vx&Ws zoejMa-A)-rmnPZ4s8c2asu_wm=Cv?KRF3Q!)QpI*#`DzWx%3ab-}q8J#Hni3$nCq3#OHx_a9c!1r>M8o5pf| zFCbHkqtq*FZYL@=Uy<1uh3Hu7p@$DNN?mFq=@Js;tM&&@hkkFZl_Th1dj zJNawx5pqp6_;+62>;0mLKGPUS_3Ryu7OQj9H z|Flqx4KDjsUh!7e_55DZ+xhW?jENC&tU5W&SIp&Ya7BLGEh`8*

#$k(kfvvCWRz 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 WGjd7cyZtfnA0BSru8i-3fBip>1Wktk diff --git a/packages/vscode-extension/resources/logo.ttf b/packages/vscode-extension/resources/logo.ttf index 6de66a29c926dd360ce6d803347e88c9c53190b1..ab842db9dd16e9bed543c8c681568f5f09c3c92f 100644 GIT binary patch literal 1756 zcmd^9&u<$=6#m}s#?Fs+H*uT<0diL%I4BKHYUKxtLISi+R8oE<4S@p^-8ySK)!J*> zo2ub}j5wiIf(u84L=LDD5A z-+S|BW;GB1eQ3hO^y;}+o^!7}{w5$#k==ah+*E$?{F#9ERodqZ6|Z))@%a_nx7cf? zV6Qm)!IQgyNezB3``-41fBgpWZ|rkr65VfGW5i#vkCiLY?d~8fcucy#-sPIuI7|OSwB4##@%#4|uLIU8z$n$iMpS8*xnAN^`g36IX7jL#*DYo}Jhb)| zb5Ap3hU~2)Kc?Pr7XLz@6$^gfn5!zFW`;JceX~ik8-`-pR3-z@Xj`$p`~X%TH|6ie zG?rkTS~NNCow*5!S4ap8B3AIQDep5+hZ zg^>ojOtKGXFBea5Sab+A%ECkxur=Kr%6! zomrM8$;i+^+Lr9NWM}4OEliHz}B)OwYo)~u6hZ#act^*({YJ9}1t z_n_ttB=LyGCizi~E#e7{yZ932HBOL!TH{_E$7zlGn6ak*QmcpSWbuy1f__}n*no{M zH8#nAr?Ex+lg3>b#!ZbAOW5TT>oNYn)LT^7(V$M{ba8?Y z?DTz6t5j8E<-e$5AybV2WR7 dKOKE8-e*NUfbFK<;RiKC3^8E^VJTGZe*mI<{S^QJ literal 1456 zcma)6O>7%Q6#m}sdL7#vJ8t}gqS9JXWk;w=?AEbMDWwupC4(ZQ(&mB$-8fq(lD!)_ zPLzmBEf=VAq2fe(?ujBU9Jp|ZdO#K8gg7D&AS5azPH=!KYrb7iY*XdHSTpmz@4fH6 zS?`;L07&32bd=wEd*NK_MC2thUvu7UcI=J(^7kJBa+3D-mc6;beTsIlPqf;*xBlqV z_h|2M{<-GZtEFd`76H9Ye{GFK^s)X8?T56_taW-jaRS;;xMbR1)5e@6Y5z#u>exFQ zu)uu!Z?p@p-EsEch&=<03FiNB!`tlfoE(w+fgidKxsM2-?Q7qW`FOC)?>H~9AZ~03 zkNw|q1$YYmpnrfXIwzgMe{nPlAqc7k^CW$Poh3utzy|VZTofLoEGY z@&r;*T%VEg><;+0K#0Qw;DPBh#w-LN0Jt?OpckVUGX3PbVT5&;& zW>m~L`5_TaOMVzD)0c&+*_13+Yo|rb95dGHQd_K+q*y9O z&8V48XL9xFak6YFV-!PbX8!SiCYd zqbc}~|LEc<=qv4&akc-MQp=iU`FqEx<;KNPP(%CG_v0@xEP3zm^RsgY^11b5ED<*> z|8jErM9M!qX&8}+H94jIG&7Ys{6Ib#5?^ln7vxc6q`2kpi8h|hzpj$W;~<&*aHKt) zWisu~DB0oCwmk7~G)9UC>GrZ00ee<+x7Q?m4T4mEA(4=`HbW^SBz;?y-7{Y25HcHhSDw$*o|QYa@JsrNIO6 NjDxSu_*;1n{|j*+;urt` diff --git a/packages/vscode-extension/src/commands/createConfig.ts b/packages/vscode-extension/src/commands/createConfig.ts index 31e960d..95f8a73 100644 --- a/packages/vscode-extension/src/commands/createConfig.ts +++ b/packages/vscode-extension/src/commands/createConfig.ts @@ -1,4 +1,4 @@ -// 用于生成alova.config.js +// Used to generate alova.config.js import generateConfig from '@/functions/generateConfig'; import { getCurrentDirectory } from '@/utils/vscode'; diff --git a/packages/vscode-extension/src/commands/generateApi.ts b/packages/vscode-extension/src/commands/generateApi.ts index e183121..3951d97 100644 --- a/packages/vscode-extension/src/commands/generateApi.ts +++ b/packages/vscode-extension/src/commands/generateApi.ts @@ -1,14 +1,14 @@ import message from '@/components/message'; -import readConfig from '@/functions/readConfig'; import generate from '@/functions/generate'; +import readConfig from '@/functions/readConfig'; import { getFileNameByPath } from '@/utils'; -// 用于自动生成 +// for automatic generation export default { commandId: 'alova.generateApi', handler: () => async (projectPath: string) => { await readConfig(projectPath); - // 生成api文件 + // Generate api file const { resultArr } = await generate({ projectPath }); for (const [workspaceRootDir, result] of resultArr) { if (result) { diff --git a/packages/vscode-extension/src/commands/refresh.ts b/packages/vscode-extension/src/commands/refresh.ts index a3226ac..d36a1b6 100644 --- a/packages/vscode-extension/src/commands/refresh.ts +++ b/packages/vscode-extension/src/commands/refresh.ts @@ -1,6 +1,6 @@ import Error from '@/components/error'; import message from '@/components/message'; -import { loading, enable } from '@/components/statusBar'; +import { enable, loading } from '@/components/statusBar'; import generate from '@/functions/generate'; import readConfig, { updatedConfigPool } from '@/functions/readConfig'; import { getFileNameByPath } from '@/utils'; @@ -15,7 +15,7 @@ export default { throw new Error('Expected to create alova.config.js in root directory.'); } updatedConfigPool(); - // 生成api文件 + // Generate api file const { resultArr, errorArr } = await generate({ force: true }); for (const [workspaceRootDir] of resultArr) { message.info(`[${getFileNameByPath(workspaceRootDir)}]: Your API is updated`); diff --git a/packages/vscode-extension/src/commands/setup.ts b/packages/vscode-extension/src/commands/setup.ts index d13dee5..42c72ba 100644 --- a/packages/vscode-extension/src/commands/setup.ts +++ b/packages/vscode-extension/src/commands/setup.ts @@ -13,7 +13,7 @@ export default { context.subscriptions.push(autocomplete); context.subscriptions.push(outputChannel); registerEvent(); - // 读取所有配置文件 + // Read all configuration files readConfig(getWorkspacePaths()); } } as Commonand; diff --git a/packages/vscode-extension/src/commands/showStatusBarIcon.ts b/packages/vscode-extension/src/commands/showStatusBarIcon.ts index b97d7bf..92822aa 100644 --- a/packages/vscode-extension/src/commands/showStatusBarIcon.ts +++ b/packages/vscode-extension/src/commands/showStatusBarIcon.ts @@ -1,5 +1,5 @@ import * as statusBar from '@/components/statusBar'; -// 显示状态栏项 +// Show status bar items export default { commandId: 'alova.showStatusBarIcon', handler: context => async () => { diff --git a/packages/vscode-extension/src/components/autocomplete.ts b/packages/vscode-extension/src/components/autocomplete.ts index bbd725a..d21f88c 100644 --- a/packages/vscode-extension/src/components/autocomplete.ts +++ b/packages/vscode-extension/src/components/autocomplete.ts @@ -1,6 +1,6 @@ +import autocompleteCommand from '@/commands/autocomplete'; import autocomplete from '@/functions/autocomplete'; import * as vscode from 'vscode'; -import autocompleteCommand from '@/commands/autocomplete'; const triggerCharacters: string[] = [' ', '.', '>', ':', '-']; class AutoComplete extends vscode.CompletionItem {} @@ -8,7 +8,7 @@ export default vscode.languages.registerCompletionItemProvider( ['javascript', 'typescript', 'vue', 'javascriptreact', 'typescriptreact', 'svelte'], { async provideCompletionItems(document: vscode.TextDocument, position: vscode.Position) { - // 支持换行 代码从起始位置到输入位置 + // Support newline code from starting position to input position const text = document.lineAt(position).text.slice(0, position.character); // const linePrefix = ; if (/a->.*/.test(text)) { @@ -17,7 +17,7 @@ export default vscode.languages.registerCompletionItemProvider( const completionItem = new AutoComplete(item.path, vscode.CompletionItemKind.Function); completionItem.detail = `[${item.method}] ${item.summary}`; completionItem.documentation = new vscode.MarkdownString(item.documentation ?? item.replaceText); - // 代码替换位置,查找位置会同步应用 + // Code replacement position, search position will be applied synchronously completionItem.filterText = item.path; completionItem.preselect = true; completionItem.insertText = ''; @@ -31,5 +31,5 @@ export default vscode.languages.registerCompletionItemProvider( } } }, - ...triggerCharacters // 触发自动补全的字符 + ...triggerCharacters // Characters that trigger auto-completion ); diff --git a/packages/vscode-extension/src/components/event.ts b/packages/vscode-extension/src/components/event.ts index 80985bf..090a700 100644 --- a/packages/vscode-extension/src/components/event.ts +++ b/packages/vscode-extension/src/components/event.ts @@ -1,13 +1,13 @@ -import readConfig, { updatedConfigPool } from '@/functions/readConfig'; import { getWormhole } from '@/functions/getWormhole'; -import * as vscode from 'vscode'; -import { getWorkspacePaths, getCurrentWorkspacePath } from '@/utils/vscode'; +import readConfig, { updatedConfigPool } from '@/functions/readConfig'; import { debounce } from '@/utils'; +import { getCurrentWorkspacePath, getWorkspacePaths } from '@/utils/vscode'; +import * as vscode from 'vscode'; import Error from './error'; import { log } from './message'; export function registerEvent() { - // 监听workspace目录变化 + // listener workspace directory changes vscode.workspace.onDidChangeWorkspaceFolders(event => { event.added.forEach(workspacePath => { readConfig(`${workspacePath.uri.fsPath}/`); @@ -17,7 +17,8 @@ export function registerEvent() { updatedConfigPool(); }); }); - // 监听package.json文件变化 + // listener package.json file changes + vscode.workspace.onDidChangeTextDocument( debounce(event => { const filePath = event.document.uri.fsPath; @@ -30,7 +31,8 @@ export function registerEvent() { } }, 1000) ); - // 监听alova.config配置文件变化 + // listener alova.config configuration file changes + vscode.workspace.onDidSaveTextDocument(event => { const filePath = event.uri.fsPath; if (/alova\.config\.[cm]?[jt]s$/.test(filePath)) { @@ -38,14 +40,16 @@ export function registerEvent() { updatedConfigPool(); } }); - // 监听错误 + // Listen for errors + process.on('uncaughtException', (err: Error) => { log(err.message); if (err.ERROR_CODE) { vscode.window.showErrorMessage(err.message); } }); - // 监听未处理的promise rejection + // Listen for unhandled promise rejection + process.on('unhandledRejection', (error: Error) => { const errMsg = error?.message ?? error ?? 'unhandledRejection'; log(errMsg); diff --git a/packages/vscode-extension/src/components/message.ts b/packages/vscode-extension/src/components/message.ts index 6bf921f..d6ed9c1 100644 --- a/packages/vscode-extension/src/components/message.ts +++ b/packages/vscode-extension/src/components/message.ts @@ -1,7 +1,7 @@ /* eslint-disable no-console */ import util from 'node:util'; import * as vscode from 'vscode'; -// 创建一个输出通道 +// Create an output channel export const outputChannel = vscode.window.createOutputChannel('Alova'); export function info(message: string, duration?: number) { if (!duration) { @@ -17,7 +17,7 @@ export function info(message: string, duration?: number) { new Promise(resolve => { const timeout = setTimeout(() => { resolve(message); - }, duration); // 自动关闭时间(毫秒) + }, duration); // Automatic shutdown time (milliseconds) token.onCancellationRequested(() => { clearTimeout(timeout); resolve(message); diff --git a/packages/vscode-extension/src/components/statusBar.ts b/packages/vscode-extension/src/components/statusBar.ts index 7bedbca..40462f5 100644 --- a/packages/vscode-extension/src/components/statusBar.ts +++ b/packages/vscode-extension/src/components/statusBar.ts @@ -1,5 +1,5 @@ import * as vscode from 'vscode'; -// 创建状态栏项 +// Create status bar item type StatusBarItemType = 'loading' | 'enable' | 'disable'; export const loading = (text: string = '') => { BAR_STATE.value = 'loading'; @@ -18,7 +18,7 @@ export const disable = () => { BAR_STATE.value = 'disable'; statusBarItem.text = `$(alova-icon-id) Alova`; statusBarItem.tooltip = 'module `@alova/wormhole` not found'; - statusBarItem.color = '#808080'; // 设置颜色为灰色 + statusBarItem.color = '#808080'; // Set color to gray statusBarItem.command = undefined; }; export const statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100); diff --git a/packages/vscode-extension/src/extension.ts b/packages/vscode-extension/src/extension.ts index 30b470d..e6c309b 100644 --- a/packages/vscode-extension/src/extension.ts +++ b/packages/vscode-extension/src/extension.ts @@ -3,7 +3,7 @@ import setup from '@/commands/setup'; import * as vscode from 'vscode'; export function activate(context: vscode.ExtensionContext) { - // 插件注册 + // commands registration commands.forEach(({ commandId, handler }) => { context.subscriptions.push(vscode.commands.registerCommand(commandId, handler(context))); }); diff --git a/packages/vscode-extension/src/functions/getWormhole.ts b/packages/vscode-extension/src/functions/getWormhole.ts index dd07be4..34a31e7 100644 --- a/packages/vscode-extension/src/functions/getWormhole.ts +++ b/packages/vscode-extension/src/functions/getWormhole.ts @@ -34,7 +34,8 @@ export const getWormhole = () => { enable(); } if (wormhole) { - // 全局配置 + // Global configuration + wormhole.setGlobalConfig({ Error: AlovaErrorConstructor, templateData: TEMPLATE_DATA diff --git a/packages/vscode-extension/src/helper/autoUpdate.ts b/packages/vscode-extension/src/helper/autoUpdate.ts index 717115d..d3be7f2 100644 --- a/packages/vscode-extension/src/helper/autoUpdate.ts +++ b/packages/vscode-extension/src/helper/autoUpdate.ts @@ -1,8 +1,8 @@ +import type { ConfigObject } from '@/helper/config'; +import { CONFIG_POOL } from '@/helper/config'; +import wormhole from '@/helper/wormhole'; import { highPrecisionInterval } from '@/utils'; import { executeCommand } from '@/utils/vscode'; -import wormhole from '@/helper/wormhole'; -import { CONFIG_POOL } from '@/helper/config'; -import type { ConfigObject } from '@/helper/config'; const AUTOUPDATE_MAP = new Map< string, @@ -13,12 +13,14 @@ export function refeshAutoUpdate(configuration: ConfigObject) { const [, config] = configuration; const { time, immediate, isStop } = wormhole.getAutoUpdateConfig(config); const oldConfig = AUTOUPDATE_MAP.get(configuration[0]); - // 过滤掉已经配置的定时器 + // Filter out configured timers + if (oldConfig?.immediate === immediate && oldConfig?.time === time && oldConfig?.timer?.isRunning()) { return; } if (!isStop) { - // 设置定时器 + // Set timer + AUTOUPDATE_MAP.set(configuration[0], { time, immediate, @@ -31,10 +33,12 @@ export function refeshAutoUpdate(configuration: ConfigObject) { ) }); } else { - // 移除定时器 + // Remove timer + AUTOUPDATE_MAP.delete(configuration[0]); } - // 关闭之前的定时器 + // Close previous timer + oldConfig?.timer?.clear?.(); } export function removeConfiguration(dir?: string | string[]) { @@ -42,7 +46,8 @@ export function removeConfiguration(dir?: string | string[]) { for (const dir of dirs) { const idx = CONFIG_POOL.findIndex(([projectPath]) => projectPath === dir); if (idx >= 0) { - // 关闭定时器 + // off timer + AUTOUPDATE_MAP.get(CONFIG_POOL[idx][0])?.timer?.clear(); AUTOUPDATE_MAP.delete(CONFIG_POOL[idx][0]); CONFIG_POOL.splice(idx, 1); diff --git a/packages/vscode-extension/src/utils/index.ts b/packages/vscode-extension/src/utils/index.ts index d478076..736b03a 100644 --- a/packages/vscode-extension/src/utils/index.ts +++ b/packages/vscode-extension/src/utils/index.ts @@ -22,7 +22,7 @@ export const getFileNameByPath = (path: string) => { const [, name] = /[/\\]([^/\\]+)([/\\])?$/.exec(path) ?? []; return name ?? ''; }; -// 生成唯一id +// Generate unique id export function uuid() { let dt = new Date().getTime(); const id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { @@ -36,12 +36,12 @@ export function debounce any>(func: T, delay: number let timeout: NodeJS.Timeout; return function (...args: Parameters) { - // 清除上一个计时器 + // Clear previous timer if (timeout) { clearTimeout(timeout); } - // 设置新的计时器,延迟执行传入的函数 + // Set a new timer to delay execution of the passed function timeout = setTimeout(() => { func(...args); }, delay); diff --git a/packages/vscode-extension/src/utils/vscode.ts b/packages/vscode-extension/src/utils/vscode.ts index 23d637d..3fc09c1 100644 --- a/packages/vscode-extension/src/utils/vscode.ts +++ b/packages/vscode-extension/src/utils/vscode.ts @@ -1,27 +1,27 @@ +import { CommandKey, commandsMap } from '@/commands'; import path from 'node:path'; import * as vscode from 'vscode'; -import { CommandKey, commandsMap } from '@/commands'; -// 获取workspacePath文件 +// Get workspace path file export const getWorkspacePaths = () => { const workspaceFolders = vscode.workspace.workspaceFolders || []; return workspaceFolders.map(item => `${item.uri.fsPath}/`); }; -// 执行Command +// Execute command export const executeCommand = (cmd: CommandKey, ...args: T) => { const commandId = commandsMap[cmd]?.commandId; if (commandId) { vscode.commands.executeCommand(commandId, ...args); } }; -// 获取当前workspacePath +// Get the current workspace path export const getCurrentWorkspacePath = (filePath?: string) => { - // 获取当前活动编辑器 + // Get the currently active editor const editor = vscode.window.activeTextEditor; if (!editor) { return getWorkspacePaths()[0]; } filePath = filePath ?? editor.document.uri.fsPath; - // 获取当前文件所在的工作区根目录 + // Get the workspace root directory where the current file is located const workspaceFolder = vscode.workspace.getWorkspaceFolder(vscode.Uri.file(filePath)); if (!workspaceFolder) { return filePath; @@ -30,7 +30,7 @@ export const getCurrentWorkspacePath = (filePath?: string) => { }; export const getCurrentDirectory = () => { - // 获取当前活动编辑器 + // Get the currently active editor const editor = vscode.window.activeTextEditor; if (!editor) { return getWorkspacePaths()[0]; diff --git a/packages/vscode-extension/test/config.spec.ts b/packages/vscode-extension/test/config.spec.ts index 51ace4e..3a0c217 100644 --- a/packages/vscode-extension/test/config.spec.ts +++ b/packages/vscode-extension/test/config.spec.ts @@ -4,17 +4,17 @@ import sinon from 'sinon'; import * as vscode from 'vscode'; suite('alova.create.config command', function () { - this.timeout(1000000); // 设置超时时间,避免 VSCode 启动超时 + this.timeout(1000000); // Set a timeout to avoid VSCode startup timeout vscode.window.showInformationMessage('Start all tests.'); let mockCreateConfig: sinon.SinonStub; this.beforeEach(() => { - // 创建 spy 和 stub + // Create spies and stubs mockCreateConfig = sinon.stub(wormhole, 'createConfig'); }); this.afterEach(() => { - // 恢复所有 stub + // Restore all stubs sinon.restore(); }); @@ -22,19 +22,19 @@ suite('alova.create.config command', function () { // await new Promise(resolve => { // setTimeout(resolve, 10000); // }); - // 模拟 getWorkspacePaths 返回的路径 + // Mock the paths returned by getWorkspacePaths // const mockPaths = ['/path/to/project']; mockCreateConfig.returns(Promise.resolve(undefined)); - // 执行命令 + // execute command await vscode.commands.executeCommand('alova.create.config'); - // 验证 generateConfig 是否被正确调用 + // Verify that generateConfig is called correctly assert.ok(mockCreateConfig.calledOnce); }); // test('should handle empty workspace paths gracefully', async () => { - // // 模拟 getWorkspacePaths 返回空数组 + // //Mock getWorkspacePaths to return an empty array // mockReadConfig.returns([]); // await vscode.commands.executeCommand('alova.create.config'); diff --git a/packages/wormhole/src/functions/alovaJson.ts b/packages/wormhole/src/functions/alovaJson.ts index 6016d66..fcdba68 100644 --- a/packages/wormhole/src/functions/alovaJson.ts +++ b/packages/wormhole/src/functions/alovaJson.ts @@ -6,25 +6,30 @@ import type { TemplateData } from './openApi2Data'; const DEFAULT_CONFIG = getGlobalConfig(); export const writeAlovaJson = async (data: TemplateData, originPath: string, name = 'api.json') => { - // 将数据转换为 JSON 字符串 + // Convert data to JSON string + const jsonData = await format(JSON.stringify(data, null, 2), { parser: 'json' }); - // 定义 JSON 文件的路径和名称 + // Define the path and name of the JSON file + const filePath = `${originPath}_${name}`; const dirPath = filePath.split(/\/|\\/).slice(0, -1).join('/'); if (!(await existsPromise(dirPath))) { await fs.mkdir(dirPath, { recursive: true }); } - // 使用 fs.writeFile 将 JSON 数据写入文件 + // Use fs.writeFile to write JSON data to a file + return fs.writeFile(filePath, jsonData); }; export const readAlovaJson = async (originPath: string, name = 'api.json') => { - // 定义 JSON 文件的路径和名称 + // Define the path and name of the JSON file + const filePath = `${originPath}_${name}`; if (!(await existsPromise(filePath))) { throw new DEFAULT_CONFIG.Error('alovaJson is not exists'); } - // 使用 fs.readFile 读取 JSON 文件 + // Read JSON files using fs.readFile + const data = await fs.readFile(filePath, 'utf8'); let jsonData = {} as TemplateData; try { diff --git a/packages/wormhole/src/functions/generateApi.ts b/packages/wormhole/src/functions/generateApi.ts index 331d445..3931d3f 100644 --- a/packages/wormhole/src/functions/generateApi.ts +++ b/packages/wormhole/src/functions/generateApi.ts @@ -12,54 +12,73 @@ import openApi2Data from './openApi2Data'; const DEFAULT_CONFIG = getGlobalConfig(); export default async function ( - workspaceRootDir: string, // 项目地址 - outputPath: string, // 输出路径 - data: OpenAPIV3_1.Document, // openapi数据 - config: GeneratorConfig, // generator配置 - type: TemplateType, // 模板类型 - force: boolean // 是否强制生成 + workspaceRootDir: string, // Project address + + outputPath: string, // Output path + + data: OpenAPIV3_1.Document, // Openapidata + + config: GeneratorConfig, // Generator configuration + + type: TemplateType, // template type + + force: boolean // Whether to force generation ) { if (!data) { return false; } - // 输出目录 + // Output directory + const outputDir = path.resolve(workspaceRootDir, outputPath); - // 缓存文件地址 + // Cache file address + const alovaJsonPath = getAlovaJsonPath(workspaceRootDir, outputPath); - // 获取alova版本 + // Get alova version + const configVersion = Number(config.version); const alovaVersion: AlovaVersion = Number.isNaN(configVersion) ? getAlovaVersion(workspaceRootDir) : `v${configVersion}`; const templateFile = new TemplateFile(type, alovaVersion); - // 将openApi对象转成template对象 + // Convert open api object to template object + const templateData = await openApi2Data(data, config); - // 框架技术栈标签 vue | react + // Framework technology stack tag vue | react + templateData[getFrameworkTag(workspaceRootDir)] = true; - // 头部注释部分 + // Header annotation section + templateData.commentText = await templateFile.readAndRenderTemplate('comment', data, { root: true, hasVersion: false }); - // 模块类型 + // module type + templateData.moduleType = TemplateFile.getModuleType(type); - // 模板类型 + // template type + templateData.type = type; - // alova版本 + // Alova version + templateData.alovaVersion = alovaVersion; - // 是否需要生成api文件 - // 判断是否需要生成api文件 + // Do you need to generate api files? + // Determine whether api files need to be generated + if (!force && isEqual(templateData, DEFAULT_CONFIG.templateData.get(alovaJsonPath))) { return false; } - // 保存templateData + // Save template data + DEFAULT_CONFIG.templateData.set(alovaJsonPath, templateData); - // 生成alova.json文件 + // Generate alova.json file + await writeAlovaJson(templateData, alovaJsonPath); - // 获取是否存在index.ts|index.js + // Get whether index.ts|index.js exists + const indexIsExists = await existsPromise(path.join(outputDir, `index${templateFile.getExt()}`)); - // mustache语法生成 - // 定义模版配置对象 + // mustache grammar generation + // Define template configuration objects + const generatingPromises = [ !indexIsExists ? { diff --git a/packages/wormhole/src/functions/getAlovaVersion.ts b/packages/wormhole/src/functions/getAlovaVersion.ts index e01ad12..d90db1f 100644 --- a/packages/wormhole/src/functions/getAlovaVersion.ts +++ b/packages/wormhole/src/functions/getAlovaVersion.ts @@ -8,12 +8,12 @@ export default function (workspaceRootDir: string) { if (!packageJson) { return 'v3'; } - // 依赖中找 + // Find in dependencies const alovaVersion = packageJson.dependencies?.alova; - // dev依赖中找 - // 优先级: 生产依赖 > 开发依赖 + // Find in dev dependencies + // Priority: Production dependencies > Development dependencies const alovaDevVersion = packageJson.devDependencies?.alova; - // 框架技术栈标签 vue | react + // Framework technology stack tag vue | react return getVersion(alovaVersion ?? alovaDevVersion); } diff --git a/packages/wormhole/src/functions/getFrameworkTag.ts b/packages/wormhole/src/functions/getFrameworkTag.ts index 3ec1f2a..5bc31cb 100644 --- a/packages/wormhole/src/functions/getFrameworkTag.ts +++ b/packages/wormhole/src/functions/getFrameworkTag.ts @@ -8,11 +8,11 @@ export default function (workspaceRootDir: string) { if (!packageJson) { return 'defaultKey'; } - // 框架技术栈标签 vue | react - // 依赖中找 + // Framework technology stack tag vue | react + // Find in dependencies const frameTag = frameworkName.find(framework => packageJson.dependencies?.[framework]); - // dev依赖中找 - // 优先级: 生产依赖 > 开发依赖 + // Find in dev dependencies + // Priority: Production dependencies > Development dependencies const devFrameTag = frameworkName.find(framework => packageJson.devDependencies?.[framework]); return frameTag ?? devFrameTag ?? 'defaultKey'; } diff --git a/packages/wormhole/src/functions/getOpenApiData.ts b/packages/wormhole/src/functions/getOpenApiData.ts index a9f5ebc..b891685 100644 --- a/packages/wormhole/src/functions/getOpenApiData.ts +++ b/packages/wormhole/src/functions/getOpenApiData.ts @@ -9,11 +9,13 @@ import { OpenAPIV2, OpenAPIV3_1 } from 'openapi-types'; import swagger2openapi from 'swagger2openapi'; const DEFAULT_CONFIG = getGlobalConfig(); -// 判断是否是swagger2.0 +// Determine whether it is swagger2.0 + function isSwagger2(data: any): data is OpenAPIV2.Document { return !!data?.swagger; } -// 解析本地openapi文件 +// Parse local openapi files + async function parseLocalFile(workspaceRootDir: string, filePath: string) { const [, extname] = /\.([^.]+)$/.exec(filePath) ?? []; switch (extname) { @@ -22,38 +24,45 @@ async function parseLocalFile(workspaceRootDir: string, filePath: string) { const data = YAML.load(file) as any; return data; } - // json + // Json + default: { const data = importFresh(path.resolve(workspaceRootDir, filePath)); return data; } } } -// 解析远程openapi文件 +// Parse remote openapi files + async function parseRemoteFile(url: string, platformType?: PlatformType) { const [, , extname] = /^http(s)?:\/\/.+\/.+\.([^.]+)$/.exec(url) ?? []; - // 没有扩展名并且有平台类型 + // no extension and platform type + if (!extname && platformType) { return getPlatformOpenApiData(url, platformType); } - // 没有平台类型并且没有扩展名 + // No platform type and no extension + if (!platformType && !extname) { return; } - // 没有平台类型并且有扩展名 + // There is no platform type and there is an extension + const dataText = (await fetchData(url)) ?? ''; switch (extname) { case 'yaml': { const data = YAML.load(dataText) as any; return data; } - // json + // Json + default: { return JSON.parse(dataText); } } } -// 解析平台openapi文件 +// Parse platform openapi files + export async function getPlatformOpenApiData(url: string, platformType: PlatformType) { switch (platformType) { case 'swagger': { @@ -68,7 +77,8 @@ export async function getPlatformOpenApiData(url: string, platformType: Platform break; } } -// 解析openapi文件 +// Parse openapi files + export default async function ( workspaceRootDir: string, url: string, @@ -77,13 +87,16 @@ export default async function ( let data: OpenAPIV3_1.Document | null = null; try { if (!/^http(s)?:\/\//.test(url)) { - // 本地文件 + // local file + data = await parseLocalFile(workspaceRootDir, url); } else { - // 远程文件 + // remote file + data = await parseRemoteFile(url, platformType); } - // 如果是swagger2的文件 + // If it is a swagger2 file + if (isSwagger2(data)) { data = (await swagger2openapi.convertObj(data, { warnOnly: true })).openapi as OpenAPIV3_1.Document; } diff --git a/packages/wormhole/src/functions/openApi2Data.ts b/packages/wormhole/src/functions/openApi2Data.ts index b7ea53e..df3c3b0 100644 --- a/packages/wormhole/src/functions/openApi2Data.ts +++ b/packages/wormhole/src/functions/openApi2Data.ts @@ -29,9 +29,11 @@ export const getApiDefultValue = (api: Api) => { configStrArr.push(`data: ${generateDefaultValues(api.requestComment.replace(/\*/g, ''))}`); } return format(`${api.global}.${api.pathKey}({${configStrArr.join(',\n')}})`, { - printWidth: 40, // 缩短printWidth以强制换行 + printWidth: 40, // Shorten print width to force line breaks + tabWidth: 2, - semi: false, // 去掉末尾分号 + semi: false, // Remove the trailing semicolon + useTabs: false, trailingComma: 'none', endOfLine: 'lf', @@ -40,8 +42,9 @@ export const getApiDefultValue = (api: Api) => { }); }; export interface TemplateData extends Omit { - // 定义模板数据类型 + // Define template data types // ... + vue?: boolean; react?: boolean; moduleType?: 'commonJs' | 'ESModule'; @@ -348,8 +351,9 @@ export default async function openApi2Data( openApi: OpenAPIV3_1.Document, config: GeneratorConfig ): Promise { - // 处理openApi中的数据 + // Processing data in openApi // ... + const templateData: TemplateData = { ...openApi, baseUrl: '', diff --git a/packages/wormhole/src/generate.ts b/packages/wormhole/src/generate.ts index 3258946..a1e9663 100644 --- a/packages/wormhole/src/generate.ts +++ b/packages/wormhole/src/generate.ts @@ -13,7 +13,8 @@ const generate = async (config: Config, rules?: GenerateApiOptions) => { return [] as boolean[]; } const configuration = new Configuration(config, rules?.projectPath ?? process.cwd()); - // 检查新配置 + + // Check new configuration configuration.checkConfig(); const outputPathArr = configuration.getAllOutputPath(); const templateTypeArr = configuration.getAllTemplateType(); @@ -21,7 +22,7 @@ const generate = async (config: Config, rules?: GenerateApiOptions) => { const generatorConfigArr = configuration.config.generator; const result = await Promise.all( outputPathArr.map((outputPath, idx) => - // 生成api文件 + // Generate api file generateApi( configuration.workspaceRootDir, outputPath, diff --git a/packages/wormhole/src/helper/openapi.ts b/packages/wormhole/src/helper/openapi.ts index c4ba06e..b98e076 100644 --- a/packages/wormhole/src/helper/openapi.ts +++ b/packages/wormhole/src/helper/openapi.ts @@ -3,9 +3,9 @@ import { cloneDeep, isArray, isEqualWith, isObject, mergeWith, sortBy } from 'lo import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'; import { isValidJSIdentifier, makeIdentifier } from './standard'; /** - * 判断是否是$ref对象 - * @param obj 判断对象 - * @returns 是否是$ref对象 + * Determine whether it is a $ref object + * @param obj Judgment object + * @returns Whether it is a $ref object */ export function isReferenceObject(obj: any): obj is OpenAPIV3.ReferenceObject { return !!(obj as OpenAPIV3.ReferenceObject)?.$ref; @@ -16,10 +16,10 @@ function isBaseReferenceObject(obj: any): obj is { _$ref: string } & Record( path: string, @@ -39,9 +39,9 @@ export const findBy$ref = ( }; /** * - * @param path $ref路径 - * @param data 复用对象 - * @param openApi 插入的openapi文档对象 + * @param path $ref path + * @param data Reuse object + * @param openApi Inserted openapi document object */ export const setComponentsBy$ref = (path: string, data: any, openApi: OpenAPIV3_1.Document) => { const pathArr = path.split('/'); @@ -62,9 +62,9 @@ export const setComponentsBy$ref = (path: string, data: any, openApi: OpenAPIV3_ }; /** * - * @param path $ref路径 - * @param toUpperCase 是否首字母大小 - * @returns 引用对象名称 + * @param path $ref path + * @param toUpperCase Whether the initial letter size + * @returns Reference object name */ export const get$refName = (path: string, toUpperCase: boolean = true) => { const pathArr = path.split('/'); @@ -76,9 +76,9 @@ export const get$refName = (path: string, toUpperCase: boolean = true) => { }; /** * - * @param schemaOrigin 含$ref的对象 - * @param openApi openApi文档对象 - * @returns 去除了$ref的对象 + * @param schemaOrigin Object with $ref + * @param openApi openApi document object + * @returns Removed $ref object */ export const removeAll$ref = ( schemaOrigin: any, @@ -92,7 +92,8 @@ export const removeAll$ref = ( return searchMap.get(deepSchemaOrigin.$ref) as T; } schema = findBy$ref(deepSchemaOrigin.$ref, openApi, true); - // 做标记方便还原 + // Mark for easy restoration + schema._$ref = deepSchemaOrigin.$ref; searchMap.set(deepSchemaOrigin.$ref, schema); } else { @@ -107,10 +108,10 @@ export const removeAll$ref = ( }; /** * - * @param objValue 待比较的对象 - * @param srcValue 源对象 - * @param openApi openApi文档对象 - * @returns 是否相等 + * @param objValue object to be compared + * @param srcValue source object + * @param openApi openApi document object + * @returns Are they equal? */ export function isEqualObject(objValue: any, srcValue: any, openApi: OpenAPIV3_1.Document) { const visited = new WeakMap(); @@ -127,7 +128,8 @@ export function isEqualObject(objValue: any, srcValue: any, openApi: OpenAPIV3_1 if (isReferenceObject(otherValueOrigin)) { otherValue = findBy$ref(otherValueOrigin.$ref, openApi); } - // 忽略数组顺序的影响 + // Ignore the effect of array order + if (isArray(objValue) && isArray(otherValue)) { const sortObjValue = sortBy(objValue); const sortOtherValue = sortBy(otherValue); @@ -136,7 +138,8 @@ export function isEqualObject(objValue: any, srcValue: any, openApi: OpenAPIV3_1 ); return keys.every(key => isEqualWith((sortObjValue as any)[key], (sortOtherValue as any)[key], customizer)); } - // 如果是对象,递归比较 + // If it is an object, compare recursively + if (isObject(objValue) && isObject(otherValue)) { if (visited.has(objValue) && visited.get(objValue) === otherValue) { return true; @@ -152,9 +155,9 @@ export function isEqualObject(objValue: any, srcValue: any, openApi: OpenAPIV3_1 } /** * - * @param path $ref路径 - * @param map 已存在的$ref路径 - * @returns 另一个版本的$ref路径 + * @param path $ref path + * @param map Existing $ref path + * @returns Another version of the $ref path */ export function getNext$refKey(path: string, map: Array<[string, any]> = []) { function getNameVersion(path: string) { @@ -280,7 +283,7 @@ function unCircular(obj: Record, openApi: OpenAPIV3_1.Document, map return obj; } /** - * 合并openApi文档对象尽量以srcValue为准 + * When merging openApi document objects, try to use srcValue as the standard. * @param objValue * @param srcValue * @param openApi @@ -293,18 +296,21 @@ export const mergeObject = ( map: Array<[string, any]> = [] ): T => { function customizer(objValue: any, srcValue: any): any { - // 如果都是数组,并且srcValue为空数组,则直接返回srcValue + // If they are all arrays and the src value is an empty array, the src value will be returned directly. + if (isArray(objValue) && isArray(srcValue) && !srcValue.length) { return srcValue; } if (isEqualObject(objValue, srcValue, openApi)) { return objValue; } - // 处理循环引用 + // Handle circular references + if (isCircular(srcValue)) { srcValue = unCircular(srcValue, openApi, map); } - // 是否还有_$ref属性 + // Is there also a $ref attribute? + if (hasBaseReferenceObject(srcValue)) { return removeBaseReference(srcValue, openApi, map); } diff --git a/packages/wormhole/src/helper/schema2type.ts b/packages/wormhole/src/helper/schema2type.ts index 74f5fd6..74e795a 100644 --- a/packages/wormhole/src/helper/schema2type.ts +++ b/packages/wormhole/src/helper/schema2type.ts @@ -5,20 +5,26 @@ import { findBy$ref, getStandardRefName, isReferenceObject } from './openapi'; import { isValidJSIdentifier } from './standard'; export interface Schema2TypeOptions { - deep?: boolean; // 是否递归解析 - shallowDeep?: boolean; // 只有最外层是解析的 - defaultType?: 'any' | 'unknown'; // 未匹配的时的默认类型 - commentStyle?: 'line' | 'docment'; // 注释风格 - preText?: string; // 注释前缀 - defaultRequire?: boolean; // 没有nullbale或者require时默认为require + deep?: boolean; // Whether to parse recursively + + shallowDeep?: boolean; // Only the outermost layer is analytic + + defaultType?: 'any' | 'unknown'; // Default type when not matched + + commentStyle?: 'line' | 'docment'; // Comment style + + preText?: string; // annotation prefix + + defaultRequire?: boolean; // If there is no nullbale or require, the default is require. + searchMap: Map; visited?: Set; on$Ref?: (refOject: OpenAPIV3_1.ReferenceObject) => void; } /** - * 生成注释字符串 - * @param type 注释风格 - * @returns 注释对象 + * Generate comment string + * @param type Comment style + * @returns annotation object */ export function comment(type: 'line' | 'docment') { const startText = type === 'docment' ? '/**\n' : ''; @@ -67,11 +73,11 @@ export function comment(type: 'line' | 'docment') { }; } /** - * 将schema解析为ts类型字符串 - * @param schemaOrigin schema对象 - * @param openApi openApi对象 - * @param config 配置项 - * @returns ts类型字符串 + * Parse schema into ts type string + * @param schemaOrigin schema object + * @param openApi openApi object + * @param config Configuration items + * @returns ts type string */ function parseSchema( schemaOrigin: OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject, @@ -114,8 +120,9 @@ function parseSchema( result = parseArray(schema, openApi, config); break; case 'string': - // 根据 https://swagger.io/docs/specification/data-models/data-types/#string - // 针对binary,将类型更改为Blob,其余所有format值均可视为string + // According to https://swagger.io/docs/specification/data-models/data-types/#string + // For binary, change the type to Blob, all other format values can be treated as string + if (schema.format === 'binary') { result = 'Blob'; } else { @@ -158,11 +165,11 @@ function parseSchema( return result; } /** - *将object类型的schema解析为ts类型字符串 - * @param schema schema对象 - * @param openApi openApi对象 - * @param config 配置项 - * @returns ts类型字符串 + *Parse object type schema into ts type string + * @param schema schema object + * @param openApi openApi object + * @param config Configuration items + * @returns ts type string */ function parseObject( schema: OpenAPIV3_1.SchemaObject, @@ -213,11 +220,11 @@ function parseObject( return 'object'; } /** - * 将array类型的schema解析为ts类型字符串 - * @param schema schema对象 - * @param openApi openApi对象 - * @param config 配置项 - * @returns ts类型字符串 + * Parse array type schema into ts type string + * @param schema schema object + * @param openApi openApi object + * @param config Configuration items + * @returns ts type string */ function parseArray( schema: OpenAPIV3_1.ArraySchemaObject, @@ -255,19 +262,19 @@ function parseArray( return '[]'; } /** - * 将enum类型的schema解析为ts类型字符串 - * @param schema schema对象 - * @returns ts类型字符串 + * Parse enum type schema into ts type string + * @param schema schema object + * @returns ts type string */ function parseEnum(schema: OpenAPIV3_1.SchemaObject): string { return schema.enum?.map?.((value: any) => JSON.stringify(value))?.join?.(' | ') || ''; } /** - * 将schema解析为格式化后的ts类型字符串 - * @param schemaOrigin schema对象 - * @param openApi openapi文档对象 - * @param config 配置项 - * @returns 格式化后的ts类型字符串 + * Parse the schema into a formatted ts type string + * @param schemaOrigin schema object + * @param openApi openapi document object + * @param config Configuration items + * @returns Formatted ts type string */ export async function convertToType( schemaOrigin: OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject, @@ -281,27 +288,30 @@ export async function convertToType( config.visited = new Set(); } const tsStr = parseSchema(schemaOrigin, openApi, config); - // 格式化ts类型 + // Format ts type + const tsStrFormat = await format(`type Ts = ${tsStr}`, { - semi: false // 去掉分号 + semi: false // remove semicolon }); const resultFormat = /type Ts =(.*)/s.exec(tsStrFormat)?.[1] ?? ''; const tsStrArr = resultFormat.trim().split('\n'); - // 加前缀,便于生成注释 + // Add prefix to facilitate generating comments + return tsStrArr.map((line, idx) => (idx ? config.preText : '') + line).join('\n'); } interface JsonSchema2TsOptions { export?: boolean; - defaultRequire?: boolean; // 没有nullbale或者require时默认为require + defaultRequire?: boolean; // If there is no nullbale or require, the default is require. + on$RefTsStr?: (name: string, tsStr: string) => void; } /** - * 将schema对象解析为ts类型字符串 - * @param schema schema对象 - * @param name 类型名称 - * @param openApi openapi文档对象 - * @param options 配置项 - * @returns interface Ts字符串 + * Parse the schema object into a ts type string + * @param schema schema object + * @param name Type name + * @param openApi openapi document object + * @param options Configuration items + * @returns interface Ts string */ export const jsonSchema2TsStr = async ( schema: OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject, diff --git a/packages/wormhole/src/helper/standard.ts b/packages/wormhole/src/helper/standard.ts index fd1bb51..8f9b010 100644 --- a/packages/wormhole/src/helper/standard.ts +++ b/packages/wormhole/src/helper/standard.ts @@ -67,10 +67,10 @@ const reservedWords = new Set([ 'yield' ]); export const makeIdentifier = (str: string, style: 'camelCas' | 'snakeCase') => { - // 移除所有非字母、数字、下划线和美元符号的字符,同时拆分单词 + // Removes all characters that are not letters, numbers, underscores, and dollar signs while splitting words const words = str.split(/[^a-zA-Z0-9_$]+/).filter(Boolean); - // 将单词转换为小驼峰形式 + // Convert words to camelCase form let identifier = ''; switch (style) { case 'camelCas': @@ -91,12 +91,12 @@ export const makeIdentifier = (str: string, style: 'camelCas' | 'snakeCase') => break; } - // 如果字符串以数字开头,用下划线替换 + // If the string starts with a number, replace it with an underscore if (/^[0-9]/.test(identifier)) { identifier = `_${identifier}`; } - // 如果是保留字,添加一个后缀 + // If it is a reserved word, add a suffix if (reservedWords.has(identifier)) { identifier += '_'; } diff --git a/packages/wormhole/src/helper/typeStr.ts b/packages/wormhole/src/helper/typeStr.ts index 7409619..ec6ff1c 100644 --- a/packages/wormhole/src/helper/typeStr.ts +++ b/packages/wormhole/src/helper/typeStr.ts @@ -1,9 +1,12 @@ import { format } from '@/utils'; -// 去除注释 +// Remove comments + function removeComments(content: string) { - // 去除单行注释 + // Remove single line comments + content = content.replace(/\/\/.*$/gm, ''); - // 去除多行注释和文档注释 + // Remove multi-line comments and documentation comments + content = content.replace(/\/\*[\s\S]*?\*\//g, ''); return content; } @@ -156,9 +159,9 @@ function parseTuple(tupleType: string) { return `[${parsedElements.join(', ')}]`; } /** - * 从给定的 TypeScript 源代码生成类型和接口的默认值对象。 - * @param sourceCode - TypeScript 源代码字符串 - * @returns 包含类型和接口默认值的对象 + * Generates default value objects for types and interfaces from the given TypeScript source code. + * @param sourceCode -TypeScript source code string + * @returns Object containing type and interface default values */ export function generateDefaultValues : string>( sourceCode: string, diff --git a/packages/wormhole/src/interface.type.ts b/packages/wormhole/src/interface.type.ts index 855a1b5..30a9b2b 100644 --- a/packages/wormhole/src/interface.type.ts +++ b/packages/wormhole/src/interface.type.ts @@ -1,10 +1,13 @@ import type { OpenAPIV3_1 } from 'openapi-types'; -// 查找对应的input属性值 +// Find the corresponding input attribute value + export type ConfigType = 'auto' | 'ts' | 'typescript' | 'module' | 'commonjs'; -// 模板类型 +// template type + export type TemplateType = 'typescript' | 'module' | 'commonjs'; -// 平台类型 +// platform type + export type PlatformType = 'swagger' | 'knife4j' | 'yapi'; export type SchemaObject = OpenAPIV3_1.SchemaObject; export type Parameter = OpenAPIV3_1.ParameterObject; @@ -20,60 +23,76 @@ export interface HandleApi { (apiDescriptor: ApiDescriptor): ApiDescriptor | void | undefined | null; } export type GeneratorConfig = { - // openapi的json文件url地址 + // Openapi json file url address + input: string; // input: 'http://localhost:3000/openapi.json', - // input: 'openapi/api.json' // 以当前项目为相对目录的本地地址 - // input: 'http://192.168.5.123:8080' // 没有指向openapi文件时,必须配合platform参数使用 + // input: 'openapi/api.json' //Take the current project as the local address of the relative directory + // input: 'http://192.168.5.123:8080' //When it does not point to the openapi file, it must be used with the platform parameter + + // Platforms that support openapi. Currently, swagger, knife4j, and yapi are supported. The default is empty. + // When this parameter is specified, the input field only needs to specify the address of the document and does not need to be specified to the openapi file, reducing the usage threshold. + // Different platforms have different openapi file addresses. Just read the file at the corresponding address according to the platform identification. - // 支持openapi的平台,目前先支持swagger、knife4j、yapi,默认为空 - // 当指定了此参数后,input字段只需要指定文档的地址而不需要指定到openapi文件,减小使用门槛 - // 不同平台,它的openapi文件地址不一样,根据平台标识去对应地址下读取文件即可。 platform?: PlatformType; - // 接口文件和类型文件的输出路径,多个generator不能重复的地址,否则生成的代码会相互覆盖,无意义 + // The output path of the interface file and type file, multiple generators cannot have repeated addresses, otherwise the generated codes will cover each other, which is meaningless. + output: string; - // (具体看下面)指定生成的响应数据的mediaType,指定后以此数据类型来生成200状态码的响应ts格式,默认application/json + // (See below for details) Specify the media type of the generated response data. After specifying, use this data type to generate the response ts format of the 200 status code. The default is application/json. + responseMediaType?: string; - // (具体看下面)指定生成的请求体数据的mediaType,指定后以此数据类型来生成请求体的ts格式,默认application/json + // (See below for details) Specify the media type of the generated request body data. After specifying, use this data type to generate the ts format of the request body. The default is application/json. + bodyMediaType?: string; - // 生成代码的类型,可选值为auto/ts/typescript/module/commonjs,默认为auto,会通过一定规则判断当前项目的类型 - // ts/typescript:意思相同,表示生成ts类型文件 - // module:生成esModule规范文件 - // commonjs:表示生成commonjs规范文件 + // The type of generated code. The optional value is auto/ts/typescript/module/commonjs. The default is auto. The type of the current project will be determined through certain rules. + // ts/typescript: The same meaning means generating ts type files + // module: generate esModule specification file + // commonjs: means generating commonjs specification file + type?: ConfigType; - // 指定alova版本 + // Specify alova version + version?: number; - // 多项目使用global字段 + // Multiple projects use global fields + global?: string; - // global挂载的父级对象,默认为globalThis + // The parent object of Global mounting, the default is global this + globalHost?: string; - // 是否使用import来导入类型,默认false - // 开启此选项后,生成的apiDefinitions.ts文件将使用import语法来导入类型,而不是/// + // Whether to use import to import the type, the default is false + // When this option is turned on, the generated apiDefinitions.ts file will use import syntax to import types instead of /// + useImportType?: boolean; - // 没有require时默认为require,只有nullable生效 + // When there is no require, it defaults to require, and only nullable takes effect. + defaultRequire?: boolean; - // (具体看下面)过滤或转换生成的api接口函数,返回一个新的apiDescriptor来生成api调用函数 - // 未指定此函数时则不转换apiDescripor对象 - // apiDescriptor的格式与openapi文件的接口对象格式相同 - // 对类型生成也同样适用 + // (See below for details) Filter or convert the generated api interface function and return a new apiDescriptor to generate the api calling function + // When this function is not specified, the apiDescriptor object is not converted. + // The format of apiDescriptor is the same as the interface object format of the openapi file + // The same goes for type generation + handleApi?: HandleApi; }; export type Config = { - // api生成设置,为数组,每项代表一个自动生成的规则,包含生成的输入输出目录、规范文件地址等等 - // 目前只支持openapi规范,包括openapi的2.0和3.0格式,但目前只做3.0规范 + // API generation settings are arrays. Each item represents an automatically generated rule, including the generated input and output directories, specification file addresses, etc. + // Currently, only OpenAPI specifications are supported, including OpenAPI 2.0 and 3.0 formats, but currently only 3.0 specifications are supported. + generator: GeneratorConfig[]; - // 是否自动更新接口,默认开启,每5分钟检查一次,false时关闭 + // Whether to automatically update the interface, enabled by default, checked every 5 minutes, closed when false + autoUpdate?: | boolean | { - // 编辑器开启时更新,默认false + // Updated when the editor is opened, default false + launchEditor?: boolean; - // 自动更新间隔,单位毫秒 + // Automatic update interval in milliseconds + interval: number; }; }; @@ -82,7 +101,7 @@ export type GenerateApiOptions = { projectPath?: string; }; /** - * 生成的api描述信息 + * Generated api description information */ export interface Api { method: string; diff --git a/packages/wormhole/src/modules/Configuration.ts b/packages/wormhole/src/modules/Configuration.ts index 61757fa..ba1cf91 100644 --- a/packages/wormhole/src/modules/Configuration.ts +++ b/packages/wormhole/src/modules/Configuration.ts @@ -14,12 +14,14 @@ export default class Configuration { workspaceRootDir: string; constructor(config: Config, workspaceRootDir: string) { - // 配置文件 + // Configuration file + this.config = config; this.workspaceRootDir = workspaceRootDir; } - // 检测配置文件 + // Detect configuration file + checkConfig() { if (!this.config.generator?.length) { throw new DEFAULT_CONFIG.Error('No items found in the `config.generator`'); @@ -59,7 +61,8 @@ export default class Configuration { throw new DEFAULT_CONFIG.Error('autoUpdate.interval must be a number'); } if (time <= 0) { - // 最少一秒钟 + // at least one second + throw new DEFAULT_CONFIG.Error('Expected to set number which great than 1 in `config.autoUpdate.interval`'); } } @@ -68,7 +71,8 @@ export default class Configuration { static getTemplateType(workspaceRootDir: string, generator: GeneratorConfig): TemplateType { let type: TemplateType; const configType = generator.type ?? 'auto'; - // 根据配置文件中的type来判断模板类型 + // Determine the template type based on the type in the configuration file + switch (configType) { case 'ts': case 'typescript': @@ -95,12 +99,14 @@ export default class Configuration { return this.config.generator.map(generator => generator.output); } - // 获取openapi数据 + // Get openapi data + static getOpenApiData(workspaceRootDir: string, generator: GeneratorConfig) { return getOpenApiData(workspaceRootDir, generator.input, generator.platform); } - // 获取所有openapi数据 + // Get all openapi data + getAllOpenApiData() { return Promise.all( this.config.generator.map(generator => Configuration.getOpenApiData(this.workspaceRootDir, generator)) @@ -109,7 +115,8 @@ export default class Configuration { getAutoUpdateConfig() { const autoUpdateConfig = this.config.autoUpdate; - let time = 60 * 5; // 默认五分钟 + let time = 60 * 5; // Default five minutes + let immediate = false; if (typeof autoUpdateConfig === 'object') { time = Number(autoUpdateConfig.interval); diff --git a/packages/wormhole/src/modules/TemplateFile.ts b/packages/wormhole/src/modules/TemplateFile.ts index 1e9c19d..c6f8089 100644 --- a/packages/wormhole/src/modules/TemplateFile.ts +++ b/packages/wormhole/src/modules/TemplateFile.ts @@ -20,7 +20,8 @@ export default class TemplateFile { alovaVersion: AlovaVersion; constructor(type: TemplateType, alovaVersion: AlovaVersion) { - // 根据type确定使用哪个模板文件夹下的模板 + // Determine which template folder to use based on type. + this.type = type; this.alovaVersion = alovaVersion; } @@ -34,12 +35,14 @@ export default class TemplateFile { } } - // 获取生成文件的后缀名 + // Get the suffix name of the generated file + getExt() { return TemplateFile.getExt(this.type); } - // 获取模块类型 + // Get module type + getModuleType() { return TemplateFile.getModuleType(this.type); } @@ -64,7 +67,8 @@ export default class TemplateFile { } async outputFile(data: Record, fileName: string, ouput: string, config?: RenderTemplateOptions) { - // 这里实现模板文件渲染工作,例如返回文件内容和文件名,然后再写入output的文件夹 + // Here, the template file rendering work is implemented, such as returning the file content and file name, and then writing it to the output folder. + const renderContent = await this.readAndRenderTemplate(fileName, data, config); await generateFile(ouput, `${config?.outFileName ?? fileName}${config?.ext ?? this.getExt()}`, renderContent); } diff --git a/packages/wormhole/src/readConfig.ts b/packages/wormhole/src/readConfig.ts index 525d506..2455601 100644 --- a/packages/wormhole/src/readConfig.ts +++ b/packages/wormhole/src/readConfig.ts @@ -28,7 +28,8 @@ export const readConfig = async (projectPath = process.cwd()) => { const config: Config = module.default || module; await unlink(outfile); - // 读取缓存文件并保存 + // Read the cache file and save it + const configuration = new Configuration(config, projectPath); configuration.readAlovaJson(); return config; @@ -36,7 +37,8 @@ export const readConfig = async (projectPath = process.cwd()) => { export const getAutoUpdateConfig = (config: Config) => { const autoUpdateConfig = config.autoUpdate; - let time = 60 * 5; // 默认五分钟 + let time = 60 * 5; // Default five minutes + let immediate = false; const isStop = !autoUpdateConfig; if (typeof autoUpdateConfig === 'object') { diff --git a/packages/wormhole/src/resolveWorkspaces.ts b/packages/wormhole/src/resolveWorkspaces.ts index 58bf1a3..dce0012 100644 --- a/packages/wormhole/src/resolveWorkspaces.ts +++ b/packages/wormhole/src/resolveWorkspaces.ts @@ -6,26 +6,29 @@ import path from 'node:path'; import { existsPromise, resolveConfigFile } from './utils'; /** - * 查找所有包含 alova.config.js 文件的目录 - * @param rootPath 根目录 - * @returns 包含 alova.config.js 文件的目录数组 + * Find all directories containing alova.config.js files + * @param rootPath root directory + * @returns Array of directories containing alova.config.js files */ export default async function resolveWorkspaces(rootPath = process.cwd()) { const resultDirs: string[] = []; - // 检查根目录是否有 alova.config.js + // Check if there is alova.config.js in the root directory + const rootConfigPath = await resolveConfigFile(rootPath); if (rootConfigPath) { resultDirs.push(rootPath); } - // 根据 package.json 的 workspaces 或 pnpm-workspace.yaml 来查找子包 + // Find subpackages based on workspaces in package.json or pnpm-workspace.yaml + const packageJsonPath = path.join(rootPath, 'package.json'); const pnpmWorkspacePathYaml = path.join(rootPath, 'pnpm-workspace.yaml'); const pnpmWorkspacePathYml = path.join(rootPath, 'pnpm-workspace.yml'); let workspaces: string[] = []; - // 如果存在 package.json,读取 workspaces + // If package.json exists, read workspaces + if (await existsPromise(packageJsonPath)) { const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8')); if (packageJson.workspaces) { @@ -33,7 +36,8 @@ export default async function resolveWorkspaces(rootPath = process.cwd()) { } } - // 如果存在 pnpm-workspace.yaml,读取其中的路径 + // If pnpm-workspace.yaml exists, read the path in it + const pnpmWorkspacePath = (await existsPromise(pnpmWorkspacePathYaml)) ? pnpmWorkspacePathYaml : (await existsPromise(pnpmWorkspacePathYml)) @@ -46,10 +50,12 @@ export default async function resolveWorkspaces(rootPath = process.cwd()) { } } - // 去重处理 + // Deduplication + workspaces = [...new Set(workspaces)]; - // 遍历每个子包,检查是否存在 alova.config.js + // Iterate through each sub-package and check if alova.config.js exists + for (const workspace of workspaces) { const workspaceDirs = await globPaths(rootPath, workspace); for (const dir of workspaceDirs) { @@ -64,10 +70,10 @@ export default async function resolveWorkspaces(rootPath = process.cwd()) { } /** - * 解析 workspace 路径 - * @param {string} rootPath 根目录 - * @param {string} workspacePattern workspace 定义的路径模式 - * @returns {Promise} 解析后的路径列表 + * Parse workspace path + * @param {string} rootPath root directory + * @param {string} workspacePattern Path pattern defined by workspace + * @returns {Promise} Parsed path list */ async function globPaths(rootPath: string, workspacePattern: string): Promise { const resolvedPaths: string[] = []; @@ -78,7 +84,8 @@ async function globPaths(rootPath: string, workspacePattern: string): Promise a === b); handlebars.registerHelper('not', (a, b) => a !== b); -// 注册自定义助手函数 'raw' +// Register custom helper function 'raw' + handlebars.registerHelper( 'raw', text => - // 返回原始字符串,不进行 HTML 转义 + // Returns the original string without HTML escaping + new handlebars.SafeString(text) ); /** - * 读取并渲染 handlebars 文件 - * @param templatePath 模板文件路径 - * @param view - 渲染模板所需的数据对象 - * @returns 渲染后的内容 + * Read and render the handlebars file + * @param templatePath Template file path + * @param view -Data objects required to render the template + * @returns Rendered content */ export async function readAndRenderTemplate(templatePath: string, view: any) { let data = ''; @@ -82,16 +84,17 @@ export async function readAndRenderTemplate(templatePath: string, view: any) { export async function format(text: string, config?: PrettierConfig) { return prettier.format(text, { ...(prettierConfig as PrettierConfig), - parser: 'typescript', // 指定使用 babel 解析器 + parser: 'typescript', // Specify to use babel parser + ...(config ?? {}), plugins: [prettierTs, prettierEsTree, prettierBabel] }); } /** - * 传入文本内容,在指定目录下生成自定义文件 - * @param distDir 待生成文件所在目录 - * @param fileName 待生成文件名 - * @param content 文件内容 + * Pass in text content and generate a custom file in the specified directory + * @param distDir The directory where the file to be generated is located + * @param fileName File name to be generated + * @param content File content */ export async function generateFile(distDir: string, fileName: string, content: string) { if (!(await existsPromise(distDir))) { @@ -112,7 +115,8 @@ export async function fetchData(url: string) { }); } -// 去掉所有为空的undefined值 +// Remove all empty undefined values + export function removeUndefined(obj: T) { const defaultObject = Array.isArray(obj) ? [] : {}; if (typeof obj !== 'object' || !obj) { diff --git a/packages/wormhole/test/config.spec.ts b/packages/wormhole/test/config.spec.ts index dca3771..a48a5e9 100644 --- a/packages/wormhole/test/config.spec.ts +++ b/packages/wormhole/test/config.spec.ts @@ -133,6 +133,7 @@ afterEach(async () => { describe('config', () => { test('should create config file under project root path', async () => { // generate typescript file + requireResult.set(resolve(process.cwd(), './package.json'), { devDependencies: { typescript: '^5.4.5' @@ -150,6 +151,7 @@ describe('config', () => { expect(initialTsConfig).toMatch(`export default {`); expect(initialTsConfig).toMatch(`input: 'http://localhost:3000',`); // generate commonjs file + requireResult.set(resolve(process.cwd(), './package.json'), { type: 'commonjs', dependencies: { @@ -164,6 +166,7 @@ describe('config', () => { expect(initialCjsConfig).toMatch(`module.exports = {`); // generate module file + requireResult.set(resolve(process.cwd(), './package.json'), { dependencies: { alova: '3.0.5' @@ -177,6 +180,7 @@ describe('config', () => { expect(initialEsmoduleConfig).toMatch(`export default {`); // generate file with target type + await createConfig({ type: 'typescript' }); const initialTypedConfig = await fs.readFile(resolve(process.cwd(), 'alova.config.ts'), { encoding: 'utf-8' @@ -188,7 +192,8 @@ describe('config', () => { test('should create config file under a custom absolute path', async () => { const customPath = './mockdir_config_0'; - // 设置package.json 文件 + // Set up package.json file + requireResult.set(resolve(customPath, './package.json'), { type: 'commonjs', dependencies: { @@ -203,13 +208,14 @@ describe('config', () => { }); expect(!!initialConfig).toBeTruthy(); } finally { - await rimraf(resolve(customPath)); // 清除临时目录 + await rimraf(resolve(customPath)); // clear temporary directory } }); test('should create config file under a custom relative path', async () => { const customPath = './mockdir_config'; - // 设置package.json 文件 + // Set up package.json file + requireResult.set(resolve(process.cwd(), customPath, './package.json'), { type: 'commonjs', dependencies: { @@ -224,48 +230,57 @@ describe('config', () => { }); expect(!!initialConfig).toBeTruthy(); } finally { - await rimraf(resolve(process.cwd(), customPath)); // 清除临时目录 + await rimraf(resolve(process.cwd(), customPath)); // clear temporary directory } }); test('should read config file under project root path', async () => { // write mock config file + const projectRoot = process.cwd(); if (!(await existsPromise(projectRoot))) { await fs.mkdir(projectRoot, { recursive: true }); } // read ts file + await fs.writeFile(resolve(projectRoot, configMap.ts.file), configMap.ts.content, 'utf-8'); requireResult.set(projectRoot, null); // require()=> throw error + const tsConfig = await readConfig(); expect(tsConfig).toStrictEqual(configMap.ts.expectedConfig); // read module config file + await fs.writeFile(resolve(projectRoot, configMap.module.file), configMap.module.content, 'utf-8'); requireResult.set(projectRoot, null); // require()=> throw error + const moduleConfig = await readConfig(); expect(moduleConfig).toEqual(configMap.module.expectedConfig); // read commonjs config file + await fs.writeFile(resolve(projectRoot, configMap.commonjs.file), configMap.commonjs.content, 'utf-8'); requireResult.set(projectRoot, configMap.commonjs.expectedConfig); // require()=> return config + const cjsConfig = await readConfig(); expect(cjsConfig).toStrictEqual(configMap.commonjs.expectedConfig); }); test('should read config file under target path', async () => { // read ts file + const customPath = resolve(__dirname, './mockdir_config2'); if (!(await existsPromise(customPath))) { await fs.mkdir(customPath, { recursive: true }); } await fs.writeFile(resolve(customPath, configMap.tsWithoutImport.file), configMap.tsWithoutImport.content, 'utf-8'); requireResult.set(customPath, null); // require()=> throw error + try { const tsConfig = await readConfig(customPath); expect(tsConfig).toStrictEqual(configMap.tsWithoutImport.expectedConfig); } finally { - await rimraf(customPath); // 清除临时目录 + await rimraf(customPath); // clear temporary directory } }); }); diff --git a/packages/wormhole/test/util.ts b/packages/wormhole/test/util.ts index b68416c..9ba56fa 100644 --- a/packages/wormhole/test/util.ts +++ b/packages/wormhole/test/util.ts @@ -1,9 +1,10 @@ import isEqualWith from 'lodash/isEqualWith'; import { expect } from 'vitest'; -// 自定义比较器函数,忽略函数的比较 + +// Customize the comparator function and ignore the comparison of the function function customizer(objValue: any, othValue: any) { if (typeof objValue === 'function' && typeof othValue === 'function') { - return objValue.toString() === othValue.toString(); // 比较函数内容 + return objValue.toString() === othValue.toString(); // Compare function content } } export const isEqualObject = (objValue: any, othValue: any) => isEqualWith(objValue, othValue, customizer); diff --git a/packages/wormhole/test/workspaces.spec.ts b/packages/wormhole/test/workspaces.spec.ts index 9ff33cf..39bcc1d 100644 --- a/packages/wormhole/test/workspaces.spec.ts +++ b/packages/wormhole/test/workspaces.spec.ts @@ -6,24 +6,26 @@ import path from 'node:path'; vi.mock('node:fs'); vi.mock('node:fs/promises'); /** - * 根据给定的文件结构对象创建文件和目录 - * @param {string} rootPath 根路径 - * @param {Record} structure 文件结构对象 + * Create files and directories based on the given file structure object + * @param {string} rootPath root path + * @param {Record} structure file structure object */ async function createProjectStructure(structure: Record, rootPath = process.cwd()) { if (!(await existsPromise(rootPath))) { await fs.mkdir(rootPath, { recursive: true }); } - // 遍历文件结构 + + // Traverse the file structure for (const key in structure) { const item = structure[key]; const itemPath = path.join(rootPath, key); if (typeof item === 'string') { - // 如果是字符串,创建文件并写入内容 + // If it is a string, create the file and write the content await fs.writeFile(itemPath, item); } else if (typeof item === 'object' && item !== null) { - // 如果是对象,创建目录并递归处理其内容 + // If an object, create the directory and process its contents recursively + if (!(await existsPromise(itemPath))) { await fs.mkdir(itemPath); } diff --git a/packages/wormhole/typings/index.d.ts b/packages/wormhole/typings/index.d.ts index e785094..73a7c73 100644 --- a/packages/wormhole/typings/index.d.ts +++ b/packages/wormhole/typings/index.d.ts @@ -44,7 +44,7 @@ export type GenerateApiOptions = { projectPath?: string; }; /** - * 生成的api描述信息 + * Generated api description information */ export interface Api { method: string; @@ -116,9 +116,9 @@ export declare const getAutoUpdateConfig: (config: Config) => { }; export declare const getApis: (config: Config, projectPath?: string) => Api[]; /** - * 查找所有包含 alova.config.js 文件的目录 - * @param rootPath 根目录 - * @returns 包含 alova.config.js 文件的目录数组 + * Find all directories containing alova.config.js files + * @param rootPath root directory + * @returns Array of directories containing alova.config.js files */ export function resolveWorkspaces(rootPath?: string): Promise; From 18de3d7da85ccbd6db7ef2878cb37d1f645a3cc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E9=95=87?= Date: Fri, 8 Nov 2024 12:00:12 +0800 Subject: [PATCH 42/47] docs: fill the comments --- README.md | 30 +- packages/vscode-extension/package.json | 2 +- .../src/functions/getWormhole.ts | 3 +- packages/wormhole/src/bin/actions.ts | 12 +- packages/wormhole/src/bin/cli.ts | 8 +- packages/wormhole/src/createConfig.ts | 5 + packages/wormhole/src/generate.ts | 6 +- packages/wormhole/src/interface.type.ts | 157 +- packages/wormhole/src/readConfig.ts | 6 + packages/wormhole/src/resolveWorkspaces.ts | 20 +- packages/wormhole/test/cli.spec.ts | 4 +- packages/wormhole/test/config.spec.ts | 3 +- packages/wormhole/test/generate.spec.ts | 2 +- packages/wormhole/typings/index.d.ts | 138 +- test/api-common/alova.config.js | 2 +- test/api-common/package.json | 22 + test/api-common/src/api/apiDefinitions.js | 26 + test/api-common/src/api/createApis.js | 103 + test/api-common/src/api/globals.d.ts | 1783 +++++++++++++++++ test/api-common/src/api/index.js | 25 + test/api-v3-ts-test/src/api/index.ts | 2 +- 21 files changed, 2274 insertions(+), 85 deletions(-) create mode 100644 test/api-common/package.json create mode 100644 test/api-common/src/api/apiDefinitions.js create mode 100644 test/api-common/src/api/createApis.js create mode 100644 test/api-common/src/api/globals.d.ts create mode 100644 test/api-common/src/api/index.js diff --git a/README.md b/README.md index f28bcb8..efa16ae 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# VSCode extension for alova +# Devtools for alova.js ## features @@ -6,7 +6,13 @@ 2. Embed API documents in the code to experience the effect of checking and using APIs. 3. Update APIs regularly and actively notify front-end developers, no longer relying on server-side developers to notify. -> [Detailed documentation](https://alova.js.org/tutorial/getting-started/extension-integration). +![image](https://github.com/user-attachments/assets/4e72912d-dd77-47d6-a9be-5f1a3bce6a2b) + +In the past, when the backend developer delivered the API to you, you had to open the intermediate API docs to query and copy the key information into your project, and you had to constantly switch between the intermediate API docs and your editor. But now, alova's devtools can eliminate the intermediate API docs for you, shortening the collaboration distance between the frontend and the backend like a wormhole. Through it, you can quickly find the required API in the editor and display the comprehensive document of this API, and quickly comprehensive parameter transfer by referring to the API parameter table, giving you a different API integration experience. + +![image](https://github.com/user-attachments/assets/2c7d7fd7-7998-4995-b777-f37c22dd3742) + +> Visit [Detailed documentation](https://alova.js.org/tutorial/getting-started/extension-integration) for more information. ## View API completed information @@ -25,3 +31,23 @@ Using the trigger word `a->` to trigger apis quick positioning. ### Search by description ![](https://alova.js.org/img/vscode-query-with-description.png) + +## Welcome to contribute + +We are honored to receive active participation from developers around the world in Issues and Discussions. + +We hope to make alova a common project for everyone who is willing to participate, rather than the alova team. We encourage everyone to become a contributor to the alova community with an open and inclusive attitude. Even if you are a junior developer, as long as your ideas meet the development guidelines of alova, please participate generously. + +## Changelog + +[Changelog](https://github.com/alovajs/devtools/releases) + +## Contributors + + + + + +## LICENSE + +[MIT](https://en.wikipedia.org/wiki/MIT_License) diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index 8d19231..a9f1e3c 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -2,7 +2,7 @@ "name": "alova-vscode-extension", "displayName": "Alova", "description": "Generate and search APIs without API documentation any more", - "version": "0.0.10", + "version": "0.1.0", "engines": { "vscode": "^1.89.0", "node": ">=18.19.0", diff --git a/packages/vscode-extension/src/functions/getWormhole.ts b/packages/vscode-extension/src/functions/getWormhole.ts index 34a31e7..1e672bb 100644 --- a/packages/vscode-extension/src/functions/getWormhole.ts +++ b/packages/vscode-extension/src/functions/getWormhole.ts @@ -35,7 +35,6 @@ export const getWormhole = () => { } if (wormhole) { // Global configuration - wormhole.setGlobalConfig({ Error: AlovaErrorConstructor, templateData: TEMPLATE_DATA @@ -58,7 +57,7 @@ export default () => } return () => { removeConfiguration(); - throw new Error('module `@alova/wormhole` is not found, please install it first.', true); + throw new Error('module `@alova/wormhole` is not found, please install by `npm i @alova/wormhole`', true); }; } } diff --git a/packages/wormhole/src/bin/actions.ts b/packages/wormhole/src/bin/actions.ts index f88cac3..d17a30d 100644 --- a/packages/wormhole/src/bin/actions.ts +++ b/packages/wormhole/src/bin/actions.ts @@ -2,31 +2,31 @@ import { createConfig, generate, readConfig, resolveWorkspaces } from '@/index'; import { TemplateType } from '@/interface.type'; import ora from 'ora'; -export const actionInit = async ({ type, path: projectPath }: { type?: TemplateType; path?: string }) => { +export const actionInit = async ({ type, cwd }: { type?: TemplateType; cwd?: string }) => { const spinner = ora('Initializing configuration file...').start(); - await createConfig({ type, projectPath }); + await createConfig({ type, projectPath: cwd }); spinner.succeed('alova configuration file is initialized!'); }; export const actionGen = async ({ workspace = true, - path: projectPath, + cwd, force }: { workspace?: boolean; - path?: string; + cwd?: string; force?: boolean; }) => { let workspacePaths: (string | undefined)[] = [undefined]; if (workspace) { - workspacePaths = await resolveWorkspaces(projectPath); + workspacePaths = await resolveWorkspaces(cwd); } for (const dir of workspacePaths) { const spinner = ora(`Generating...`).start(); const config = await readConfig(dir); const results = await generate(config, { force, - projectPath + projectPath: cwd }); results.forEach(result => { if (result) { diff --git a/packages/wormhole/src/bin/cli.ts b/packages/wormhole/src/bin/cli.ts index bb093b4..7c6499c 100644 --- a/packages/wormhole/src/bin/cli.ts +++ b/packages/wormhole/src/bin/cli.ts @@ -10,15 +10,15 @@ program.name('alova').description('CLI to generate api for alova.js').version(pk program .command('init') .description('init a configuration file') - .option('-t, --type [type]', 'type of configuration') - .option('-p, --path [path]', 'init configuration path') + .option('-t, --type ', 'type of configuration, options are `typescript`, `ts`, `commonjs`, `module`') + .option('-c, --cwd ', 'current working directory') .action(actionInit); program .command('gen') .option('-f, --force', 'force generate api') - .option('-p, --path [path]', 'generating path') - .option('-w, --workspace', 'generating path') + .option('-c, --cwd ', 'current working directory') + .option('-w, --workspace', 'run as workspace') .description('generate api for alova.js') .action(actionGen); diff --git a/packages/wormhole/src/createConfig.ts b/packages/wormhole/src/createConfig.ts index 8e9e391..d794ff6 100644 --- a/packages/wormhole/src/createConfig.ts +++ b/packages/wormhole/src/createConfig.ts @@ -9,6 +9,11 @@ interface ConfigCreationOptions { type?: TemplateType; } +/** + * create a templated configuration file + * @param options config file create options + * @returns Promise + */ const createConfig = ({ projectPath = '', type }: ConfigCreationOptions = {}) => { projectPath = path.isAbsolute(projectPath) ? projectPath : path.resolve(process.cwd(), projectPath); type = type || getAutoTemplateType(projectPath); diff --git a/packages/wormhole/src/generate.ts b/packages/wormhole/src/generate.ts index a1e9663..0333535 100644 --- a/packages/wormhole/src/generate.ts +++ b/packages/wormhole/src/generate.ts @@ -3,10 +3,10 @@ import generateApi from './functions/generateApi'; import Configuration from './modules/Configuration'; /** - * generate apis based on config + * Generate relevant API information based on the configuration object. Generally, it needs to be used with `readConfig()`. * @param config generating config - * @param rules config rules - * @returns + * @param rules config rules that contains `force`, `projectPath` + * @returns An array that contains the result of `generator` items in configuration whether generation is successful. */ const generate = async (config: Config, rules?: GenerateApiOptions) => { if (!config) { diff --git a/packages/wormhole/src/interface.type.ts b/packages/wormhole/src/interface.type.ts index 30a9b2b..23027d0 100644 --- a/packages/wormhole/src/interface.type.ts +++ b/packages/wormhole/src/interface.type.ts @@ -1,13 +1,16 @@ import type { OpenAPIV3_1 } from 'openapi-types'; -// Find the corresponding input attribute value - +/** + * Find the corresponding input attribute value + */ export type ConfigType = 'auto' | 'ts' | 'typescript' | 'module' | 'commonjs'; -// template type - +/** + * template type + */ export type TemplateType = 'typescript' | 'module' | 'commonjs'; -// platform type - +/** + * platform type + */ export type PlatformType = 'swagger' | 'knife4j' | 'yapi'; export type SchemaObject = OpenAPIV3_1.SchemaObject; export type Parameter = OpenAPIV3_1.ParameterObject; @@ -23,76 +26,144 @@ export interface HandleApi { (apiDescriptor: ApiDescriptor): ApiDescriptor | void | undefined | null; } export type GeneratorConfig = { - // Openapi json file url address + /** + * Openapi file path, it supports json and yaml file, and network url + * @requires true + * + * @example + * input: 'http://localhost:3000/openapi.json' + * input: 'openapi/api.json' -> Take the current project as the local address of the relative directory + * input: 'http://192.168.5.123:8080' -> When it does not point to the openapi file, it must be used with the `platform` parameter + */ input: string; - // input: 'http://localhost:3000/openapi.json', - // input: 'openapi/api.json' //Take the current project as the local address of the relative directory - // input: 'http://192.168.5.123:8080' //When it does not point to the openapi file, it must be used with the platform parameter - - // Platforms that support openapi. Currently, swagger, knife4j, and yapi are supported. The default is empty. - // When this parameter is specified, the input field only needs to specify the address of the document and does not need to be specified to the openapi file, reducing the usage threshold. - // Different platforms have different openapi file addresses. Just read the file at the corresponding address according to the platform identification. + /** + * Platforms that support openapi. Currently `swagger` are supported. The default is empty. + * When this parameter is specified, the input field only needs to specify the url of the document and doesn't need to be specified to the openapi file, reducing the usage threshold. + * @defualt undefined + */ platform?: PlatformType; - // The output path of the interface file and type file, multiple generators cannot have repeated addresses, otherwise the generated codes will cover each other, which is meaningless. - + /** + * The output path of the interface file and type file, multiple generators cannot have repeated addresses, otherwise the generated codes will cover each other, which is meaningless. + * @requires true + */ output: string; - // (See below for details) Specify the media type of the generated response data. After specifying, use this data type to generate the response ts format of the 200 status code. The default is application/json. + /** + * Specify the media type of the generated response data. After specifying, use this data type to generate the response ts format of the 2xx status code. + * @defualt 'application/json' + */ responseMediaType?: string; - // (See below for details) Specify the media type of the generated request body data. After specifying, use this data type to generate the ts format of the request body. The default is application/json. - + /** + * Specify the media type of the generated request body data. After specifying, use this data type to generate the ts format of the request body. + * @default 'application/json' + */ bodyMediaType?: string; - // The type of generated code. The optional value is auto/ts/typescript/module/commonjs. The default is auto. The type of the current project will be determined through certain rules. - // ts/typescript: The same meaning means generating ts type files - // module: generate esModule specification file - // commonjs: means generating commonjs specification file - + /** + * The type of generated code. The optional value is `auto/ts/typescript/module/commonjs`. + * default is `auto`, it means the type of current project will be determined through certain rules. + * + * @param type + * 1. ts/typescript: The same meaning means generating ts type files + * 2. module: generate esModule specification file + * 3. commonjs: means generating commonjs specification file + * + * @default 'auto' + */ type?: ConfigType; - // Specify alova version + /** + * Specify alova version, 2 or 3, if not specified, it will be automatically determined through the alova version in `package.json` + */ version?: number; - // Multiple projects use global fields + /** + * Globally exported api name, you can access the automatically generated api globally through this name. + * it is required when multiple generators are configured, and it cannot be repeated + * + * @default 'Apis' + */ global?: string; - // The parent object of Global mounting, the default is global this + /** + * The host object of global mounting, default is `globalThis`, it means `window` in browser and `global` in nodejs + * + * @default 'globalThis' + */ globalHost?: string; - // Whether to use import to import the type, the default is false - // When this option is turned on, the generated apiDefinitions.ts file will use import syntax to import types instead of /// + /** + * Whether to use `import` statement to import the type. When this option is set to `true`, the generated apiDefinitions.ts file will use `import` statement to import types instead of /// + * + * @default false + */ useImportType?: boolean; - // When there is no require, it defaults to require, and only nullable takes effect. + /** + * When there is no require, it defaults to require, and only nullable takes effect. + */ defaultRequire?: boolean; - // (See below for details) Filter or convert the generated api interface function and return a new apiDescriptor to generate the api calling function - // When this function is not specified, the apiDescriptor object is not converted. - // The format of apiDescriptor is the same as the interface object format of the openapi file - // The same goes for type generation + /** + * Filter or convert the generated api function and return a new `apiDescriptor` to generate the api. + * When this function is not specified, `apiDescriptor` object is not converted. + * The type of `apiDescriptor` is the same as the api item of openapi file. + * + * @see https://spec.openapis.org/oas/v3.1.0.html#operation-object + * + * @example + * ```js + * // Do not generate the apis that starts with `/user` + * handleApi(apiDescriptor) { + * if (apiDescriptor.path.startsWith('/user')) { + * return; + * } + * return apiDescriptor; + * } + * ``` + * + * ```js + * // modify the api's parameters + * handleApi(apiDescriptor) { + * apiDescriptor.parameters = (apiDescriptor.parameters || []).filter( + * param => param.in === 'header' && param.name === 'token' + * ); + * delete apiDescriptor.requestBody.id; + * apiDescriptor.url = apiDescriptor.url.replace('/user', ''); + * return apiDescriptor; + * } + * ``` + */ handleApi?: HandleApi; }; export type Config = { - // API generation settings are arrays. Each item represents an automatically generated rule, including the generated input and output directories, specification file addresses, etc. - // Currently, only OpenAPI specifications are supported, including OpenAPI 2.0 and 3.0 formats, but currently only 3.0 specifications are supported. - + /** + * API generation settings are arrays. Each item represents an automatically generated rule, including the generated input and output directories, specification file addresses, etc. + * Currently, only OpenAPI specifications are supported, including OpenAPI 2.0 and 3.0 specifications. + */ generator: GeneratorConfig[]; - // Whether to automatically update the interface, enabled by default, checked every 5 minutes, closed when false - + /** + * Whether to automatically update the interface. + * default is `true`, checked every 5 minutes, set `false` to close it + * + * @default true + */ autoUpdate?: | boolean | { - // Updated when the editor is opened, default false - + /** + * Updated when the editor is opened + */ launchEditor?: boolean; - // Automatic update interval in milliseconds - + /** + * Automatic update interval in milliseconds + */ interval: number; }; }; diff --git a/packages/wormhole/src/readConfig.ts b/packages/wormhole/src/readConfig.ts index 2455601..b2d5b8d 100644 --- a/packages/wormhole/src/readConfig.ts +++ b/packages/wormhole/src/readConfig.ts @@ -8,6 +8,12 @@ import Configuration from './modules/Configuration'; import { resolveConfigFile } from './utils'; const DEFAULT_CONFIG = getGlobalConfig(); + +/** + * Read the alova.config configuration file and return the parsed configuration object. + * @param projectPath The project path where the configuration file is located. The default value is `process.cwd()`. + * @returns a promise instance that contains configuration object. + */ export const readConfig = async (projectPath = process.cwd()) => { const configFile = await resolveConfigFile(projectPath); if (!configFile) { diff --git a/packages/wormhole/src/resolveWorkspaces.ts b/packages/wormhole/src/resolveWorkspaces.ts index dce0012..238820b 100644 --- a/packages/wormhole/src/resolveWorkspaces.ts +++ b/packages/wormhole/src/resolveWorkspaces.ts @@ -6,25 +6,25 @@ import path from 'node:path'; import { existsPromise, resolveConfigFile } from './utils'; /** - * Find all directories containing alova.config.js files - * @param rootPath root directory - * @returns Array of directories containing alova.config.js files + * Search for all directories containing alova.config configuration files under the monorepo project. It will search for configuration files based on `workspaces` in `package.json` or subpackages defined in `pnpm-workspace.yaml` + * @param projectPath The project path to search, defaults to `process.cwd()`. + * @returns An array of relative paths to directories containing alova.config configuration files. */ -export default async function resolveWorkspaces(rootPath = process.cwd()) { +export default async function resolveWorkspaces(projectPath = process.cwd()) { const resultDirs: string[] = []; // Check if there is alova.config.js in the root directory - const rootConfigPath = await resolveConfigFile(rootPath); + const rootConfigPath = await resolveConfigFile(projectPath); if (rootConfigPath) { - resultDirs.push(rootPath); + resultDirs.push(projectPath); } // Find subpackages based on workspaces in package.json or pnpm-workspace.yaml - const packageJsonPath = path.join(rootPath, 'package.json'); - const pnpmWorkspacePathYaml = path.join(rootPath, 'pnpm-workspace.yaml'); - const pnpmWorkspacePathYml = path.join(rootPath, 'pnpm-workspace.yml'); + const packageJsonPath = path.join(projectPath, 'package.json'); + const pnpmWorkspacePathYaml = path.join(projectPath, 'pnpm-workspace.yaml'); + const pnpmWorkspacePathYml = path.join(projectPath, 'pnpm-workspace.yml'); let workspaces: string[] = []; // If package.json exists, read workspaces @@ -57,7 +57,7 @@ export default async function resolveWorkspaces(rootPath = process.cwd()) { // Iterate through each sub-package and check if alova.config.js exists for (const workspace of workspaces) { - const workspaceDirs = await globPaths(rootPath, workspace); + const workspaceDirs = await globPaths(projectPath, workspace); for (const dir of workspaceDirs) { const configFile = await resolveConfigFile(dir); if (configFile) { diff --git a/packages/wormhole/test/cli.spec.ts b/packages/wormhole/test/cli.spec.ts index f4ef9ec..63970e9 100644 --- a/packages/wormhole/test/cli.spec.ts +++ b/packages/wormhole/test/cli.spec.ts @@ -24,7 +24,7 @@ describe('cli', () => { await actionInit({ type: 'commonjs' }); expect(createConfig).toBeCalledWith({ type: 'commonjs' }); - await actionInit({ path: '/mock_path' }); + await actionInit({ cwd: '/mock_path' }); expect(createConfig).toBeCalledWith({ projectPath: '/mock_path' }); }); @@ -46,7 +46,7 @@ describe('cli', () => { }); vi.clearAllMocks(); - await actionGen({ workspace: false, path: '/mock_path', force: true }); + await actionGen({ workspace: false, cwd: '/mock_path', force: true }); expect(resolveWorkspaces).not.toHaveBeenCalled(); expect(readConfig).toHaveBeenCalledTimes(1); expect(readConfig).toHaveBeenNthCalledWith(1, undefined); diff --git a/packages/wormhole/test/config.spec.ts b/packages/wormhole/test/config.spec.ts index a48a5e9..0d230bd 100644 --- a/packages/wormhole/test/config.spec.ts +++ b/packages/wormhole/test/config.spec.ts @@ -1,6 +1,5 @@ -import createConfig from '@/createConfig'; +import { createConfig, readConfig } from '@/index'; import type { Config } from '@/interface.type'; -import { readConfig } from '@/readConfig'; import { existsPromise } from '@/utils'; import fs from 'node:fs/promises'; import { resolve } from 'node:path'; diff --git a/packages/wormhole/test/generate.spec.ts b/packages/wormhole/test/generate.spec.ts index 9ef0e8b..c4c1d7b 100644 --- a/packages/wormhole/test/generate.spec.ts +++ b/packages/wormhole/test/generate.spec.ts @@ -1,4 +1,4 @@ -import generate from '@/generate'; +import { generate } from '@/index'; import fs from 'node:fs/promises'; import { resolve } from 'node:path'; import { createStrReg } from './util'; diff --git a/packages/wormhole/typings/index.d.ts b/packages/wormhole/typings/index.d.ts index 73a7c73..2de3d68 100644 --- a/packages/wormhole/typings/index.d.ts +++ b/packages/wormhole/typings/index.d.ts @@ -1,7 +1,16 @@ import { OpenAPIV3_1 } from 'openapi-types'; +/** + * Find the corresponding input attribute value + */ export type ConfigType = 'auto' | 'ts' | 'typescript' | 'module' | 'commonjs'; +/** + * template type + */ export type TemplateType = 'typescript' | 'module' | 'commonjs'; +/** + * platform type + */ export type PlatformType = 'swagger' | 'knife4j' | 'yapi'; export type SchemaObject = OpenAPIV3_1.SchemaObject; export type Parameter = OpenAPIV3_1.ParameterObject; @@ -17,25 +26,130 @@ export interface HandleApi { (apiDescriptor: ApiDescriptor): ApiDescriptor | void | undefined | null; } export type GeneratorConfig = { + /** + * Openapi file path, it supports json and yaml file, and network url + * @requires true + * + * @example + * input: 'http://localhost:3000/openapi.json' + * input: 'openapi/api.json' -> Take the current project as the local address of the relative directory + * input: 'http://192.168.5.123:8080' -> When it does not point to the openapi file, it must be used with the `platform` parameter + */ input: string; + /** + * Platforms that support openapi. Currently `swagger` are supported. The default is empty. + * When this parameter is specified, the input field only needs to specify the url of the document and doesn't need to be specified to the openapi file, reducing the usage threshold. + * @defualt undefined + */ platform?: PlatformType; + /** + * The output path of the interface file and type file, multiple generators cannot have repeated addresses, otherwise the generated codes will cover each other, which is meaningless. + * @requires true + */ output: string; + /** + * Specify the media type of the generated response data. After specifying, use this data type to generate the response ts format of the 2xx status code. + * @defualt 'application/json' + */ responseMediaType?: string; + /** + * Specify the media type of the generated request body data. After specifying, use this data type to generate the ts format of the request body. + * @default 'application/json' + */ bodyMediaType?: string; + /** + * The type of generated code. The optional value is `auto/ts/typescript/module/commonjs`. + * default is `auto`, it means the type of current project will be determined through certain rules. + * + * @param type + * 1. ts/typescript: The same meaning means generating ts type files + * 2. module: generate esModule specification file + * 3. commonjs: means generating commonjs specification file + * + * @default 'auto' + */ type?: ConfigType; + /** + * Specify alova version, 2 or 3, if not specified, it will be automatically determined through the alova version in `package.json` + */ version?: number; + /** + * Globally exported api name, you can access the automatically generated api globally through this name. + * it is required when multiple generators are configured, and it cannot be repeated + * + * @default 'Apis' + */ global?: string; + /** + * The host object of global mounting, default is `globalThis`, it means `window` in browser and `global` in nodejs + * + * @default 'globalThis' + */ globalHost?: string; + /** + * Whether to use `import` statement to import the type. When this option is set to `true`, the generated apiDefinitions.ts file will use `import` statement to import types instead of /// + * + * @default false + */ useImportType?: boolean; + /** + * When there is no require, it defaults to require, and only nullable takes effect. + */ defaultRequire?: boolean; + /** + * Filter or convert the generated api function and return a new `apiDescriptor` to generate the api. + * When this function is not specified, `apiDescriptor` object is not converted. + * The type of `apiDescriptor` is the same as the api item of openapi file. + * + * @see https://spec.openapis.org/oas/v3.1.0.html#operation-object + * + * @example + * ```js + * // Do not generate the apis that starts with `/user` + * handleApi(apiDescriptor) { + * if (apiDescriptor.path.startsWith('/user')) { + * return; + * } + * return apiDescriptor; + * } + * ``` + * + * ```js + * // modify the api's parameters + * handleApi(apiDescriptor) { + * apiDescriptor.parameters = (apiDescriptor.parameters || []).filter( + * param => param.in === 'header' && param.name === 'token' + * ); + * delete apiDescriptor.requestBody.id; + * apiDescriptor.url = apiDescriptor.url.replace('/user', ''); + * return apiDescriptor; + * } + * ``` + */ handleApi?: HandleApi; }; export type Config = { + /** + * API generation settings are arrays. Each item represents an automatically generated rule, including the generated input and output directories, specification file addresses, etc. + * Currently, only OpenAPI specifications are supported, including OpenAPI 2.0 and 3.0 specifications. + */ generator: GeneratorConfig[]; + /** + * Whether to automatically update the interface. + * default is `true`, checked every 5 minutes, set `false` to close it + * + * @default true + */ autoUpdate?: | boolean | { + /** + * Updated when the editor is opened + */ launchEditor?: boolean; + /** + * Automatic update interval in milliseconds + */ interval: number; }; }; @@ -100,14 +214,24 @@ export interface ConfigCreationOptions { projectPath?: string; type?: TemplateType; } +/** + * create a templated configuration file + * @param options config file create options + * @returns Promise + */ export declare const createConfig: ({ projectPath, type }?: ConfigCreationOptions) => Promise; /** - * generate apis based on config + * Generate relevant API information based on the configuration object. Generally, it needs to be used with `readConfig()`. * @param config generating config - * @param rules config rules - * @returns + * @param rules config rules that contains `force`, `projectPath` + * @returns An array that contains the result of `generator` items in configuration whether generation is successful. */ export declare const generate: (config: Config, rules?: GenerateApiOptions) => Promise; +/** + * Read the alova.config configuration file and return the parsed configuration object. + * @param projectPath The project path where the configuration file is located. The default value is `process.cwd()`. + * @returns a promise instance that contains configuration object. + */ export declare const readConfig: (projectPath?: string) => Promise; export declare const getAutoUpdateConfig: (config: Config) => { time: number; @@ -116,10 +240,10 @@ export declare const getAutoUpdateConfig: (config: Config) => { }; export declare const getApis: (config: Config, projectPath?: string) => Api[]; /** - * Find all directories containing alova.config.js files - * @param rootPath root directory - * @returns Array of directories containing alova.config.js files + * Search for all directories containing alova.config configuration files under the monorepo project. It will search for configuration files based on `workspaces` in `package.json` or subpackages defined in `pnpm-workspace.yaml` + * @param projectPath The project path to search, defaults to `process.cwd()`. + * @returns An array of relative paths to directories containing alova.config configuration files. */ -export function resolveWorkspaces(rootPath?: string): Promise; +export function resolveWorkspaces(projectPath?: string): Promise; export {}; diff --git a/test/api-common/alova.config.js b/test/api-common/alova.config.js index e80b87d..28f2ff0 100644 --- a/test/api-common/alova.config.js +++ b/test/api-common/alova.config.js @@ -10,7 +10,7 @@ module.exports = { // openapi的json文件url地址 // input: 'https://petstore.swagger.io', // input: 'https://generator3.swagger.io', - input: './openapi.yaml', + input: './cycle-swagger.json', // input: 'http://localhost:3000/openapi.json', // input: 'openapi/api.json' // 以当前项目为相对目录的本地地址 // input: 'http://192.168.5.123:8080' // 没有指向openapi文件时,必须配合platform参数使用 diff --git a/test/api-common/package.json b/test/api-common/package.json new file mode 100644 index 0000000..632dbdc --- /dev/null +++ b/test/api-common/package.json @@ -0,0 +1,22 @@ +{ + "name": "api-common", + "version": "1.0.0", + "description": "", + "main": "index.js", + "type": "commonjs", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "gen": "openapi --input ./openapi.yaml --output ./src/api" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@alova/mock": "^1.5.2", + "alova": "^2.21.3", + "vue": "^3.4.27" + }, + "devDependencies": { + "@alova/wormhole": "workspace:^" + } +} diff --git a/test/api-common/src/api/apiDefinitions.js b/test/api-common/src/api/apiDefinitions.js new file mode 100644 index 0000000..d6ed639 --- /dev/null +++ b/test/api-common/src/api/apiDefinitions.js @@ -0,0 +1,26 @@ +/// +/* tslint:disable */ +/* eslint-disable */ +/** + * 接口文档 公共/第三方 - version 0.0 + * + * + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +module.exports = { + 'Dept.post_api_dept_add': ['POST', '/api/Dept/Add'], + 'Dept.delete_api_dept_delete': ['DELETE', '/api/Dept/Delete'], + 'Dept.post_api_dept_download': ['POST', '/api/Dept/Download'], + 'Dept.get_api_dept_getinfo': ['GET', '/api/Dept/GetInfo'], + 'Dept.get_api_dept_getlist': ['GET', '/api/Dept/GetList'], + 'Dept.get_api_dept_select': ['GET', '/api/Dept/Select'], + 'Dept.put_api_dept_update': ['PUT', '/api/Dept/Update'] +}; diff --git a/test/api-common/src/api/createApis.js b/test/api-common/src/api/createApis.js new file mode 100644 index 0000000..1d19e9c --- /dev/null +++ b/test/api-common/src/api/createApis.js @@ -0,0 +1,103 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 接口文档 公共/第三方 - version 0.0 + * + * + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +const { Method } = require('alova'); +const apiDefinitions = require('./apiDefinitions'); +/** + * + * @param {(string|symbol)[]} array + * @param {Alova} alovaInstance + * @param {any} configMap + * @returns {()=>void} + */ +const createFunctionalProxy = (array, alovaInstance, configMap) => { + // create a new proxy instance + return new Proxy(function () {}, { + get(_, property) { + // record the target property, so that it can get the completed accessing paths + array.push(property); + // always return a new proxy to continue recording accessing paths. + return createFunctionalProxy(array, alovaInstance, configMap); + }, + apply(_, __, [config]) { + const apiPathKey = array.join('.'); + const apiItem = apiDefinitions[apiPathKey]; + if (!apiItem) { + throw new Error(`the api path of \`${apiPathKey}\` is not found`); + } + const mergedConfig = { + ...configMap[apiPathKey], + ...config + }; + const [method, url] = apiItem; + const pathParams = mergedConfig.pathParams; + const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => { + const pathParam = pathParams[key]; + return pathParam; + }); + delete mergedConfig.pathParams; + let data = mergedConfig.data; + if (Object.prototype.toString.call(data) === '[object Object]' && typeof FormData !== 'undefined') { + let hasBlobData = false; + const formData = new FormData(); + for (const key in data) { + formData.append(key, data[key]); + if (data[key] instanceof Blob) { + hasBlobData = true; + } + } + data = hasBlobData ? formData : data; + } + return new Method(method.toUpperCase(), alovaInstance, urlReplaced, mergedConfig, data); + } + }); +}; +/** + * + * @param {Alova} alovaInstance + * @param {any} configMap + * @returns + */ +const createApis = (alovaInstance, configMap) => { + const Apis = new Proxy( + {}, + { + get(_, property) { + return createFunctionalProxy([property], alovaInstance, configMap); + } + } + ); + // define global variable `Apis` + globalThis.Apis = Apis; + return Apis; +}; +/** + * @template T + * @typedef {typeof import('./index')['alovaInstance'] extends import('alova').Alova ? import('alova').AlovaMethodCreateConfig : never} MethodConfig + */ +/** + * @typedef {{ [P in keyof typeof import('./apiDefinitions')]?: MethodConfig

[0]['transformData']>[0] : any> }} MethodsConfigMap + */ +/** + * @template {MethodsConfigMap} Config + * @param {Config} config + */ +const withConfigType = config => config; + +module.exports = { + createApis, + withConfigType +}; diff --git a/test/api-common/src/api/globals.d.ts b/test/api-common/src/api/globals.d.ts new file mode 100644 index 0000000..b9406d7 --- /dev/null +++ b/test/api-common/src/api/globals.d.ts @@ -0,0 +1,1783 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 接口文档 公共/第三方 - version 0.0 + * + * + * + * OpenAPI version: 3.0.1 + * + * + * NOTE: This file is auto generated by the alova's vscode plugin. + * + * https://alova.js.org/devtools/vscode + * + * **Do not edit the file manually.** + */ +import type { Alova, AlovaMethodCreateConfig, Method } from 'alova'; +import type { $$userConfigMap, alovaInstance } from '.'; +import type apiDefinitions from './apiDefinitions'; + +type CollapsedAlova = typeof alovaInstance; +type UserMethodConfigMap = typeof $$userConfigMap; + +type Alova2MethodConfig = + CollapsedAlova extends Alova + ? Omit, 'params'> + : never; + +// Extract the return type of transformData function that define in $$userConfigMap, if it not exists, use the default type. +type ExtractUserDefinedTransformed< + DefinitionKey extends keyof typeof apiDefinitions, + Default +> = DefinitionKey extends keyof UserMethodConfigMap + ? UserMethodConfigMap[DefinitionKey]['transformData'] extends (...args: any[]) => any + ? Awaited> + : Default + : Default; +type Alova2Method< + Responded, + DefinitionKey extends keyof typeof apiDefinitions, + CurrentConfig extends Alova2MethodConfig +> = + CollapsedAlova extends Alova + ? Method< + State, + Export, + CurrentConfig extends undefined + ? ExtractUserDefinedTransformed + : CurrentConfig['transformData'] extends (...args: any[]) => any + ? Awaited> + : ExtractUserDefinedTransformed, + any, + RequestConfig, + Response, + ResponseHeader + > + : never; + +export type UserThirdType = 1 | 2; +export type UserSex = 0 | 1 | 2; +export type UserWeiXin = { + /** + * 主键 + */ + id?: number; + /** + * 用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。 + */ + subscribe?: number; + /** + * 用户的标识,对当前公众号唯一 + */ + openId?: string; + /** + * 用户的昵称 + */ + nickName?: string; + sex?: UserSex; + /** + * 用户所在城市 + */ + city?: string; + /** + * 用户所在国家 + */ + country?: string; + /** + * 用户所在省份 + */ + province?: string; + /** + * 用户的语言,简体中文为zh_CN + */ + language?: string; + /** + * 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。 + */ + headImgUrl?: string; + /** + * 用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间 + */ + subscribeTime?: number; + /** + * 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。 + */ + unionId?: string; + /** + * 公众号运营者对粉丝的备注,公众号运营者可在微信公众平台用户管理界面对粉丝添加备注 + */ + remark?: string; + /** + * 用户所在的分组ID(兼容旧的用户分组接口) + */ + groupId?: number; + /** + * 用户被打上的标签ID列表 + */ + tagidList?: string; + /** + * 返回用户关注的渠道来源,ADD_SCENE_SEARCH 公众号搜索,ADD_SCENE_ACCOUNT_MIGRATION 公众号迁移,ADD_SCENE_PROFILE_CARD 名片分享,ADD_SCENE_QR_CODE 扫描二维码,ADD_SCENE_PROFILE_LINK 图文页内名称点击,ADD_SCENE_PROFILE_ITEM 图文页右上角菜单,ADD_SCENE_PAID 支付后关注,ADD_SCENE_WECHAT_ADVERTISEMENT 微信广告,ADD_SCENE_OTHERS 其他 + */ + subscribeScene?: string; + /** + * 二维码扫码场景(开发者自定义) + */ + qrScene?: number; + /** + * 二维码扫码场景描述(开发者自定义) + */ + qrSceneStr?: string; + /** + * 归属公众号 + */ + appId?: string; + /** + * 创建时间 + */ + createTime?: string; + /** + * 电话 + */ + phone?: string; + /** + * 地址 + */ + address?: string; + /** + * 状态 + */ + state?: boolean; + /** + * 用户集合 + */ + users?: User[]; +}; +export type UserThird = { + /** + * 用户ID + */ + userId?: number; + /** + * 菜单ID + */ + thirdId?: number; + type?: UserThirdType; + /** + * 微信关注 + */ + userWeiXin?: UserWeiXin; +}; +export type UserType = 1 | 20 | 80 | 90 | 100; +export type MenuType = 1 | 2 | 3 | 4; +export type Menu = { + /** + * 主键 + */ + id?: number; + /** + * 创建者名称 + */ + createBy?: string; + /** + * 创建时间 + */ + createTime?: string; + /** + * 更新者名称 + */ + updateBy?: string; + /** + * 最后更新时间 + */ + updateTime?: string; + /** + * 菜单标题 + */ + title?: string; + /** + * 组件路径 + */ + path?: string; + /** + * 权限标识符 + */ + perm?: string; + /** + * 是否iframe + */ + iFrame?: boolean; + /** + * 组件 + */ + component?: string; + /** + * 组件名称 + */ + componentName?: string; + /** + * 父级菜单ID + */ + parentId?: number; + /** + * 排序 + */ + sort?: number; + /** + * icon图标 + */ + icon?: string; + type?: MenuType; + /** + * 是否缓存 + */ + keepAlive?: boolean; + /** + * 是否隐藏 + */ + hidden?: boolean; + /** + * 跳转路由 + */ + redirect?: string; + /** + * 根目录始终显示 + */ + alwaysShow?: boolean; + /** + * 状态 + */ + state?: boolean; + /** + * 子菜单集合 + */ + children?: Menu[]; + /** + * 是否已删除 + */ + isDeleted?: boolean; + /** + * 菜单集合 + */ + roles?: Role[]; +}; +export type Role = { + /** + * 主键 + */ + id?: number; + /** + * 创建者名称 + */ + createBy?: string; + /** + * 创建时间 + */ + createTime?: string; + /** + * 更新者名称 + */ + updateBy?: string; + /** + * 最后更新时间 + */ + updateTime?: string; + /** + * 角色名称 + */ + name?: string; + type?: UserType; + /** + * 是否已删除 + */ + isDeleted?: boolean; + /** + * 系统默认配置 + */ + isSys?: boolean; + /** + * 备注 + */ + remark?: string; + /** + * 角色代码 + */ + code?: string; + /** + * 排序 + */ + sort?: number; + /** + * 用户 + */ + users?: User[]; + /** + * 菜单集合 + */ + menus?: Menu[]; +}; +export type UserDept = { + /** + * 用户ID + */ + userId?: number; + /** + * 部门Id + */ + deptId?: number; + /** + * 是否单位管理 + */ + isSys?: boolean; + /** + * 是否接收消息 + */ + isMsg?: boolean; + /** + * 系统用户 + */ + user?: User; + /** + * 公司 + */ + dept?: Dept; +}; +export type Dept = { + /** + * 主键 + */ + id?: number; + /** + * 创建者名称 + */ + createBy?: string; + /** + * 创建时间 + */ + createTime?: string; + /** + * 更新者名称 + */ + updateBy?: string; + /** + * 最后更新时间 + */ + updateTime?: string; + /** + * 单位名称 + */ + name?: string; + /** + * 简写名称 + */ + easyName?: string; + /** + * 父级部门ID + */ + parentId?: number; + /** + * 地址 + */ + address?: string; + /** + * 是否删除 + */ + isDeleted?: boolean; + /** + * 默认联系电话 + */ + phone?: string; + /** + * 默认联系人 + */ + man?: string; + /** + * 备注 + */ + remark?: string; + /** + * 状态 + */ + state?: boolean; + /** + * 排序 + */ + sort?: number; + /** + * 用户集合 + */ + users?: User[]; + /** + * 关系集合 + */ + userDepts?: UserDept[]; + /** + * 子菜单集合 + */ + children?: Dept[]; +}; +export type User = { + /** + * 主键 + */ + id?: number; + /** + * 创建者名称 + */ + createBy?: string; + /** + * 创建时间 + */ + createTime?: string; + /** + * 更新者名称 + */ + updateBy?: string; + /** + * 最后更新时间 + */ + updateTime?: string; + /** + * 账号 + */ + account?: string; + /** + * 昵称 + */ + nickName?: string; + /** + * 状态 + */ + state?: boolean; + /** + * 密码 + */ + password?: string; + /** + * 头像路径 + */ + avatar?: string; + /** + * 最后修改密码时间 + */ + passwordReSetTime?: string; + /** + * 是否已删除 + */ + isDeleted?: boolean; + /** + * 客户单位 + */ + roleId?: number; + /** + * 登录时间 + */ + loginTime?: string; + /** + * 登录时间 + */ + lastLogin?: boolean; + /** + * 电话 + */ + phone?: string; + /** + * 关系集合 + */ + userThirds?: UserThird[]; + /** + * 部门集合 + */ + depts?: Dept[]; + /** + * 角色 + */ + role?: Role; + /** + * 关系集合 + */ + userDepts?: UserDept[]; +}; +export type AddDeptParam = { + /** + * 主键 + */ + id?: number; + /** + * 创建者名称 + */ + createBy?: string; + /** + * 创建时间 + */ + createTime?: string; + /** + * 更新者名称 + */ + updateBy?: string; + /** + * 最后更新时间 + */ + updateTime?: string; + /** + * 单位名称 + */ + name?: string; + /** + * 简写名称 + */ + easyName?: string; + /** + * 父级部门ID + */ + parentId?: number; + /** + * 地址 + */ + address?: string; + /** + * 是否删除 + */ + isDeleted?: boolean; + /** + * 默认联系电话 + */ + phone?: string; + /** + * 默认联系人 + */ + man?: string; + /** + * 备注 + */ + remark?: string; + /** + * 状态 + */ + state?: boolean; + /** + * 排序 + */ + sort?: number; + /** + * 用户集合 + */ + users?: User[]; + /** + * 关系集合 + */ + userDepts?: UserDept[]; + /** + * 子菜单集合 + */ + children?: Dept[]; +}; +export type DeptParam = { + keyWord?: string; +}; +export type DeptInfo = { + /** + * 主键 + */ + id?: number; + /** + * 创建者名称 + */ + createBy?: string; + /** + * 创建时间 + */ + createTime?: string; + /** + * 更新者名称 + */ + updateBy?: string; + /** + * 最后更新时间 + */ + updateTime?: string; + /** + * 单位名称 + */ + name?: string; + /** + * 简写名称 + */ + easyName?: string; + /** + * 父级部门ID + */ + parentId?: number; + /** + * 地址 + */ + address?: string; + /** + * 是否删除 + */ + isDeleted?: boolean; + /** + * 默认联系电话 + */ + phone?: string; + /** + * 默认联系人 + */ + man?: string; + /** + * 备注 + */ + remark?: string; + /** + * 状态 + */ + state?: boolean; + /** + * 排序 + */ + sort?: number; + /** + * 用户集合 + */ + users?: User[]; + /** + * 关系集合 + */ + userDepts?: UserDept[]; + /** + * 子菜单集合 + */ + children?: Dept[]; +}; +export type DeptSelect = { + /** + * 主键Id! + */ + id?: number; + /** + * 单位名称 + */ + name?: string; + /** + * 地址 + */ + address?: string; + /** + * 父级部门ID + */ + parentId?: number; +}; +declare global { + interface Apis { + Dept: { + /** + * --- + * + * [POST] 新增 + * + * **path:** /api/Dept/Add + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = { + * // 主键 + * id?: number + * // 创建者名称 + * createBy?: string + * // 创建时间 + * createTime?: string + * // 更新者名称 + * updateBy?: string + * // 最后更新时间 + * updateTime?: string + * // 单位名称 + * name?: string + * // 简写名称 + * easyName?: string + * // 父级部门ID + * parentId?: number + * // 地址 + * address?: string + * // 是否删除 + * isDeleted?: boolean + * // 默认联系电话 + * phone?: string + * // 默认联系人 + * man?: string + * // 备注 + * remark?: string + * // 状态 + * state?: boolean + * // 排序 + * sort?: number + * // 用户集合 + * users?: Array<{ + * // 主键 + * id?: number + * // 创建者名称 + * createBy?: string + * // 创建时间 + * createTime?: string + * // 更新者名称 + * updateBy?: string + * // 最后更新时间 + * updateTime?: string + * // 账号 + * account?: string + * // 昵称 + * nickName?: string + * // 状态 + * state?: boolean + * // 密码 + * password?: string + * // 头像路径 + * avatar?: string + * // 最后修改密码时间 + * passwordReSetTime?: string + * // 是否已删除 + * isDeleted?: boolean + * // 客户单位 + * roleId?: number + * // 登录时间 + * loginTime?: string + * // 登录时间 + * lastLogin?: boolean + * // 电话 + * phone?: string + * // 关系集合 + * userThirds?: Array<{ + * // 用户ID + * userId?: number + * // 菜单ID + * thirdId?: number + * type?: 1 | 2 + * // 微信关注 + * userWeiXin?: { + * // 主键 + * id?: number + * // 用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。 + * subscribe?: number + * // 用户的标识,对当前公众号唯一 + * openId?: string + * // 用户的昵称 + * nickName?: string + * sex?: 0 | 1 | 2 + * // 用户所在城市 + * city?: string + * // 用户所在国家 + * country?: string + * // 用户所在省份 + * province?: string + * // 用户的语言,简体中文为zh_CN + * language?: string + * // 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。 + * headImgUrl?: string + * // 用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间 + * subscribeTime?: number + * // 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。 + * unionId?: string + * // 公众号运营者对粉丝的备注,公众号运营者可在微信公众平台用户管理界面对粉丝添加备注 + * remark?: string + * // 用户所在的分组ID(兼容旧的用户分组接口) + * groupId?: number + * // 用户被打上的标签ID列表 + * tagidList?: string + * // 返回用户关注的渠道来源,ADD_SCENE_SEARCH 公众号搜索,ADD_SCENE_ACCOUNT_MIGRATION 公众号迁移,ADD_SCENE_PROFILE_CARD 名片分享,ADD_SCENE_QR_CODE 扫描二维码,ADD_SCENE_PROFILE_LINK 图文页内名称点击,ADD_SCENE_PROFILE_ITEM 图文页右上角菜单,ADD_SCENE_PAID 支付后关注,ADD_SCENE_WECHAT_ADVERTISEMENT 微信广告,ADD_SCENE_OTHERS 其他 + * subscribeScene?: string + * // 二维码扫码场景(开发者自定义) + * qrScene?: number + * // 二维码扫码场景描述(开发者自定义) + * qrSceneStr?: string + * // 归属公众号 + * appId?: string + * // 创建时间 + * createTime?: string + * // 电话 + * phone?: string + * // 地址 + * address?: string + * // 状态 + * state?: boolean + * // 用户集合 + * users?: Array + * } + * }> + * // 部门集合 + * depts?: Array<{ + * // 主键 + * id?: number + * // 创建者名称 + * createBy?: string + * // 创建时间 + * createTime?: string + * // 更新者名称 + * updateBy?: string + * // 最后更新时间 + * updateTime?: string + * // 单位名称 + * name?: string + * // 简写名称 + * easyName?: string + * // 父级部门ID + * parentId?: number + * // 地址 + * address?: string + * // 是否删除 + * isDeleted?: boolean + * // 默认联系电话 + * phone?: string + * // 默认联系人 + * man?: string + * // 备注 + * remark?: string + * // 状态 + * state?: boolean + * // 排序 + * sort?: number + * // 用户集合 + * users?: Array + * // 关系集合 + * userDepts?: Array<{ + * // 用户ID + * userId?: number + * // 部门Id + * deptId?: number + * // 是否单位管理 + * isSys?: boolean + * // 是否接收消息 + * isMsg?: boolean + * // 系统用户 + * user?: User + * // 公司 + * dept?: Dept + * }> + * // 子菜单集合 + * children?: Array + * }> + * // 角色 + * role?: { + * // 主键 + * id?: number + * // 创建者名称 + * createBy?: string + * // 创建时间 + * createTime?: string + * // 更新者名称 + * updateBy?: string + * // 最后更新时间 + * updateTime?: string + * // 角色名称 + * name?: string + * type?: 1 | 20 | 80 | 90 | 100 + * // 是否已删除 + * isDeleted?: boolean + * // 系统默认配置 + * isSys?: boolean + * // 备注 + * remark?: string + * // 角色代码 + * code?: string + * // 排序 + * sort?: number + * // 用户 + * users?: Array + * // 菜单集合 + * menus?: Array<{ + * // 主键 + * id?: number + * // 创建者名称 + * createBy?: string + * // 创建时间 + * createTime?: string + * // 更新者名称 + * updateBy?: string + * // 最后更新时间 + * updateTime?: string + * // 菜单标题 + * title?: string + * // 组件路径 + * path?: string + * // 权限标识符 + * perm?: string + * // 是否iframe + * iFrame?: boolean + * // 组件 + * component?: string + * // 组件名称 + * componentName?: string + * // 父级菜单ID + * parentId?: number + * // 排序 + * sort?: number + * // icon图标 + * icon?: string + * type?: 1 | 2 | 3 | 4 + * // 是否缓存 + * keepAlive?: boolean + * // 是否隐藏 + * hidden?: boolean + * // 跳转路由 + * redirect?: string + * // 根目录始终显示 + * alwaysShow?: boolean + * // 状态 + * state?: boolean + * // 子菜单集合 + * children?: Array

+ * // 是否已删除 + * isDeleted?: boolean + * // 菜单集合 + * roles?: Array + * }> + * } + * // 关系集合 + * userDepts?: Array + * }> + * // 关系集合 + * userDepts?: Array + * // 子菜单集合 + * children?: Array + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = number + * ``` + */ + post_api_dept_add< + Config extends Alova2MethodConfig & { + data: AddDeptParam; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [DELETE] 删除 + * + * **path:** /api/Dept/Delete + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = number[] + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = number + * ``` + */ + delete_api_dept_delete< + Config extends Alova2MethodConfig & { + data: number[]; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [POST] 导出 + * + * **path:** /api/Dept/Download + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = { + * keyWord?: string + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = unknown + * ``` + */ + post_api_dept_download< + Config extends Alova2MethodConfig & { + data: DeptParam; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] 查询详情 + * + * **path:** /api/Dept/GetInfo + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * id?: number + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = { + * // 主键 + * id?: number + * // 创建者名称 + * createBy?: string + * // 创建时间 + * createTime?: string + * // 更新者名称 + * updateBy?: string + * // 最后更新时间 + * updateTime?: string + * // 单位名称 + * name?: string + * // 简写名称 + * easyName?: string + * // 父级部门ID + * parentId?: number + * // 地址 + * address?: string + * // 是否删除 + * isDeleted?: boolean + * // 默认联系电话 + * phone?: string + * // 默认联系人 + * man?: string + * // 备注 + * remark?: string + * // 状态 + * state?: boolean + * // 排序 + * sort?: number + * // 用户集合 + * users?: Array<{ + * // 主键 + * id?: number + * // 创建者名称 + * createBy?: string + * // 创建时间 + * createTime?: string + * // 更新者名称 + * updateBy?: string + * // 最后更新时间 + * updateTime?: string + * // 账号 + * account?: string + * // 昵称 + * nickName?: string + * // 状态 + * state?: boolean + * // 密码 + * password?: string + * // 头像路径 + * avatar?: string + * // 最后修改密码时间 + * passwordReSetTime?: string + * // 是否已删除 + * isDeleted?: boolean + * // 客户单位 + * roleId?: number + * // 登录时间 + * loginTime?: string + * // 登录时间 + * lastLogin?: boolean + * // 电话 + * phone?: string + * // 关系集合 + * userThirds?: Array<{ + * // 用户ID + * userId?: number + * // 菜单ID + * thirdId?: number + * type?: 1 | 2 + * // 微信关注 + * userWeiXin?: { + * // 主键 + * id?: number + * // 用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。 + * subscribe?: number + * // 用户的标识,对当前公众号唯一 + * openId?: string + * // 用户的昵称 + * nickName?: string + * sex?: 0 | 1 | 2 + * // 用户所在城市 + * city?: string + * // 用户所在国家 + * country?: string + * // 用户所在省份 + * province?: string + * // 用户的语言,简体中文为zh_CN + * language?: string + * // 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。 + * headImgUrl?: string + * // 用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间 + * subscribeTime?: number + * // 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。 + * unionId?: string + * // 公众号运营者对粉丝的备注,公众号运营者可在微信公众平台用户管理界面对粉丝添加备注 + * remark?: string + * // 用户所在的分组ID(兼容旧的用户分组接口) + * groupId?: number + * // 用户被打上的标签ID列表 + * tagidList?: string + * // 返回用户关注的渠道来源,ADD_SCENE_SEARCH 公众号搜索,ADD_SCENE_ACCOUNT_MIGRATION 公众号迁移,ADD_SCENE_PROFILE_CARD 名片分享,ADD_SCENE_QR_CODE 扫描二维码,ADD_SCENE_PROFILE_LINK 图文页内名称点击,ADD_SCENE_PROFILE_ITEM 图文页右上角菜单,ADD_SCENE_PAID 支付后关注,ADD_SCENE_WECHAT_ADVERTISEMENT 微信广告,ADD_SCENE_OTHERS 其他 + * subscribeScene?: string + * // 二维码扫码场景(开发者自定义) + * qrScene?: number + * // 二维码扫码场景描述(开发者自定义) + * qrSceneStr?: string + * // 归属公众号 + * appId?: string + * // 创建时间 + * createTime?: string + * // 电话 + * phone?: string + * // 地址 + * address?: string + * // 状态 + * state?: boolean + * // 用户集合 + * users?: Array + * } + * }> + * // 部门集合 + * depts?: Array<{ + * // 主键 + * id?: number + * // 创建者名称 + * createBy?: string + * // 创建时间 + * createTime?: string + * // 更新者名称 + * updateBy?: string + * // 最后更新时间 + * updateTime?: string + * // 单位名称 + * name?: string + * // 简写名称 + * easyName?: string + * // 父级部门ID + * parentId?: number + * // 地址 + * address?: string + * // 是否删除 + * isDeleted?: boolean + * // 默认联系电话 + * phone?: string + * // 默认联系人 + * man?: string + * // 备注 + * remark?: string + * // 状态 + * state?: boolean + * // 排序 + * sort?: number + * // 用户集合 + * users?: Array + * // 关系集合 + * userDepts?: Array<{ + * // 用户ID + * userId?: number + * // 部门Id + * deptId?: number + * // 是否单位管理 + * isSys?: boolean + * // 是否接收消息 + * isMsg?: boolean + * // 系统用户 + * user?: User + * // 公司 + * dept?: Dept + * }> + * // 子菜单集合 + * children?: Array + * }> + * // 角色 + * role?: { + * // 主键 + * id?: number + * // 创建者名称 + * createBy?: string + * // 创建时间 + * createTime?: string + * // 更新者名称 + * updateBy?: string + * // 最后更新时间 + * updateTime?: string + * // 角色名称 + * name?: string + * type?: 1 | 20 | 80 | 90 | 100 + * // 是否已删除 + * isDeleted?: boolean + * // 系统默认配置 + * isSys?: boolean + * // 备注 + * remark?: string + * // 角色代码 + * code?: string + * // 排序 + * sort?: number + * // 用户 + * users?: Array + * // 菜单集合 + * menus?: Array<{ + * // 主键 + * id?: number + * // 创建者名称 + * createBy?: string + * // 创建时间 + * createTime?: string + * // 更新者名称 + * updateBy?: string + * // 最后更新时间 + * updateTime?: string + * // 菜单标题 + * title?: string + * // 组件路径 + * path?: string + * // 权限标识符 + * perm?: string + * // 是否iframe + * iFrame?: boolean + * // 组件 + * component?: string + * // 组件名称 + * componentName?: string + * // 父级菜单ID + * parentId?: number + * // 排序 + * sort?: number + * // icon图标 + * icon?: string + * type?: 1 | 2 | 3 | 4 + * // 是否缓存 + * keepAlive?: boolean + * // 是否隐藏 + * hidden?: boolean + * // 跳转路由 + * redirect?: string + * // 根目录始终显示 + * alwaysShow?: boolean + * // 状态 + * state?: boolean + * // 子菜单集合 + * children?: Array + * // 是否已删除 + * isDeleted?: boolean + * // 菜单集合 + * roles?: Array + * }> + * } + * // 关系集合 + * userDepts?: Array + * }> + * // 关系集合 + * userDepts?: Array<{ + * // 用户ID + * userId?: number + * // 部门Id + * deptId?: number + * // 是否单位管理 + * isSys?: boolean + * // 是否接收消息 + * isMsg?: boolean + * // 系统用户 + * user?: User + * // 公司 + * dept?: Dept + * }> + * // 子菜单集合 + * children?: Array<{ + * // 主键 + * id?: number + * // 创建者名称 + * createBy?: string + * // 创建时间 + * createTime?: string + * // 更新者名称 + * updateBy?: string + * // 最后更新时间 + * updateTime?: string + * // 单位名称 + * name?: string + * // 简写名称 + * easyName?: string + * // 父级部门ID + * parentId?: number + * // 地址 + * address?: string + * // 是否删除 + * isDeleted?: boolean + * // 默认联系电话 + * phone?: string + * // 默认联系人 + * man?: string + * // 备注 + * remark?: string + * // 状态 + * state?: boolean + * // 排序 + * sort?: number + * // 用户集合 + * users?: Array + * // 关系集合 + * userDepts?: Array<{ + * // 用户ID + * userId?: number + * // 部门Id + * deptId?: number + * // 是否单位管理 + * isSys?: boolean + * // 是否接收消息 + * isMsg?: boolean + * // 系统用户 + * user?: User + * // 公司 + * dept?: Dept + * }> + * // 子菜单集合 + * children?: Array + * }> + * } + * ``` + */ + get_api_dept_getinfo< + Config extends Alova2MethodConfig & { + params: { + id?: number; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] 列表 + * + * **path:** /api/Dept/GetList + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * KeyWord?: string + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = Array<{ + * // 主键 + * id?: number + * // 创建者名称 + * createBy?: string + * // 创建时间 + * createTime?: string + * // 更新者名称 + * updateBy?: string + * // 最后更新时间 + * updateTime?: string + * // 单位名称 + * name?: string + * // 简写名称 + * easyName?: string + * // 父级部门ID + * parentId?: number + * // 地址 + * address?: string + * // 是否删除 + * isDeleted?: boolean + * // 默认联系电话 + * phone?: string + * // 默认联系人 + * man?: string + * // 备注 + * remark?: string + * // 状态 + * state?: boolean + * // 排序 + * sort?: number + * // 用户集合 + * users?: Array + * // 关系集合 + * userDepts?: Array<{ + * // 用户ID + * userId?: number + * // 部门Id + * deptId?: number + * // 是否单位管理 + * isSys?: boolean + * // 是否接收消息 + * isMsg?: boolean + * // 系统用户 + * user?: User + * // 公司 + * dept?: Dept + * }> + * // 子菜单集合 + * children?: Array + * }> + * ``` + */ + get_api_dept_getlist< + Config extends Alova2MethodConfig & { + params: { + KeyWord?: string; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [GET] 下拉框 + * + * **path:** /api/Dept/Select + * + * --- + * + * **Query Parameters** + * ```ts + * type QueryParameters = { + * parentId?: number + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = Array<{ + * // 主键Id! + * id?: number + * // 单位名称 + * name?: string + * // 地址 + * address?: string + * // 父级部门ID + * parentId?: number + * }> + * ``` + */ + get_api_dept_select< + Config extends Alova2MethodConfig & { + params: { + parentId?: number; + }; + } + >( + config: Config + ): Alova2Method; + /** + * --- + * + * [PUT] 编辑 + * + * **path:** /api/Dept/Update + * + * --- + * + * **RequestBody** + * ```ts + * type RequestBody = { + * // 主键 + * id?: number + * // 创建者名称 + * createBy?: string + * // 创建时间 + * createTime?: string + * // 更新者名称 + * updateBy?: string + * // 最后更新时间 + * updateTime?: string + * // 单位名称 + * name?: string + * // 简写名称 + * easyName?: string + * // 父级部门ID + * parentId?: number + * // 地址 + * address?: string + * // 是否删除 + * isDeleted?: boolean + * // 默认联系电话 + * phone?: string + * // 默认联系人 + * man?: string + * // 备注 + * remark?: string + * // 状态 + * state?: boolean + * // 排序 + * sort?: number + * // 用户集合 + * users?: Array<{ + * // 主键 + * id?: number + * // 创建者名称 + * createBy?: string + * // 创建时间 + * createTime?: string + * // 更新者名称 + * updateBy?: string + * // 最后更新时间 + * updateTime?: string + * // 账号 + * account?: string + * // 昵称 + * nickName?: string + * // 状态 + * state?: boolean + * // 密码 + * password?: string + * // 头像路径 + * avatar?: string + * // 最后修改密码时间 + * passwordReSetTime?: string + * // 是否已删除 + * isDeleted?: boolean + * // 客户单位 + * roleId?: number + * // 登录时间 + * loginTime?: string + * // 登录时间 + * lastLogin?: boolean + * // 电话 + * phone?: string + * // 关系集合 + * userThirds?: Array<{ + * // 用户ID + * userId?: number + * // 菜单ID + * thirdId?: number + * type?: 1 | 2 + * // 微信关注 + * userWeiXin?: { + * // 主键 + * id?: number + * // 用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。 + * subscribe?: number + * // 用户的标识,对当前公众号唯一 + * openId?: string + * // 用户的昵称 + * nickName?: string + * sex?: 0 | 1 | 2 + * // 用户所在城市 + * city?: string + * // 用户所在国家 + * country?: string + * // 用户所在省份 + * province?: string + * // 用户的语言,简体中文为zh_CN + * language?: string + * // 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。 + * headImgUrl?: string + * // 用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间 + * subscribeTime?: number + * // 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。 + * unionId?: string + * // 公众号运营者对粉丝的备注,公众号运营者可在微信公众平台用户管理界面对粉丝添加备注 + * remark?: string + * // 用户所在的分组ID(兼容旧的用户分组接口) + * groupId?: number + * // 用户被打上的标签ID列表 + * tagidList?: string + * // 返回用户关注的渠道来源,ADD_SCENE_SEARCH 公众号搜索,ADD_SCENE_ACCOUNT_MIGRATION 公众号迁移,ADD_SCENE_PROFILE_CARD 名片分享,ADD_SCENE_QR_CODE 扫描二维码,ADD_SCENE_PROFILE_LINK 图文页内名称点击,ADD_SCENE_PROFILE_ITEM 图文页右上角菜单,ADD_SCENE_PAID 支付后关注,ADD_SCENE_WECHAT_ADVERTISEMENT 微信广告,ADD_SCENE_OTHERS 其他 + * subscribeScene?: string + * // 二维码扫码场景(开发者自定义) + * qrScene?: number + * // 二维码扫码场景描述(开发者自定义) + * qrSceneStr?: string + * // 归属公众号 + * appId?: string + * // 创建时间 + * createTime?: string + * // 电话 + * phone?: string + * // 地址 + * address?: string + * // 状态 + * state?: boolean + * // 用户集合 + * users?: Array + * } + * }> + * // 部门集合 + * depts?: Array<{ + * // 主键 + * id?: number + * // 创建者名称 + * createBy?: string + * // 创建时间 + * createTime?: string + * // 更新者名称 + * updateBy?: string + * // 最后更新时间 + * updateTime?: string + * // 单位名称 + * name?: string + * // 简写名称 + * easyName?: string + * // 父级部门ID + * parentId?: number + * // 地址 + * address?: string + * // 是否删除 + * isDeleted?: boolean + * // 默认联系电话 + * phone?: string + * // 默认联系人 + * man?: string + * // 备注 + * remark?: string + * // 状态 + * state?: boolean + * // 排序 + * sort?: number + * // 用户集合 + * users?: Array + * // 关系集合 + * userDepts?: Array<{ + * // 用户ID + * userId?: number + * // 部门Id + * deptId?: number + * // 是否单位管理 + * isSys?: boolean + * // 是否接收消息 + * isMsg?: boolean + * // 系统用户 + * user?: User + * // 公司 + * dept?: Dept + * }> + * // 子菜单集合 + * children?: Array + * }> + * // 角色 + * role?: { + * // 主键 + * id?: number + * // 创建者名称 + * createBy?: string + * // 创建时间 + * createTime?: string + * // 更新者名称 + * updateBy?: string + * // 最后更新时间 + * updateTime?: string + * // 角色名称 + * name?: string + * type?: 1 | 20 | 80 | 90 | 100 + * // 是否已删除 + * isDeleted?: boolean + * // 系统默认配置 + * isSys?: boolean + * // 备注 + * remark?: string + * // 角色代码 + * code?: string + * // 排序 + * sort?: number + * // 用户 + * users?: Array + * // 菜单集合 + * menus?: Array<{ + * // 主键 + * id?: number + * // 创建者名称 + * createBy?: string + * // 创建时间 + * createTime?: string + * // 更新者名称 + * updateBy?: string + * // 最后更新时间 + * updateTime?: string + * // 菜单标题 + * title?: string + * // 组件路径 + * path?: string + * // 权限标识符 + * perm?: string + * // 是否iframe + * iFrame?: boolean + * // 组件 + * component?: string + * // 组件名称 + * componentName?: string + * // 父级菜单ID + * parentId?: number + * // 排序 + * sort?: number + * // icon图标 + * icon?: string + * type?: 1 | 2 | 3 | 4 + * // 是否缓存 + * keepAlive?: boolean + * // 是否隐藏 + * hidden?: boolean + * // 跳转路由 + * redirect?: string + * // 根目录始终显示 + * alwaysShow?: boolean + * // 状态 + * state?: boolean + * // 子菜单集合 + * children?: Array + * // 是否已删除 + * isDeleted?: boolean + * // 菜单集合 + * roles?: Array + * }> + * } + * // 关系集合 + * userDepts?: Array + * }> + * // 关系集合 + * userDepts?: Array + * // 子菜单集合 + * children?: Array + * } + * ``` + * + * --- + * + * **Response** + * ```ts + * type Response = number + * ``` + */ + put_api_dept_update< + Config extends Alova2MethodConfig & { + data: AddDeptParam; + } + >( + config: Config + ): Alova2Method; + }; + } + + var Apis: Apis; +} diff --git a/test/api-common/src/api/index.js b/test/api-common/src/api/index.js new file mode 100644 index 0000000..d8339c7 --- /dev/null +++ b/test/api-common/src/api/index.js @@ -0,0 +1,25 @@ +const { createAlova } = require('alova'); +const GlobalFetch = require('alova/GlobalFetch'); +const vueHook = require('alova/vue'); +const { createApis, withConfigType } = require('./createApis'); +const alovaInstance = createAlova({ + baseURL: 'http://petstore.swagger.io/v2', + statesHook: vueHook, + requestAdapter: GlobalFetch(), + beforeRequest: method => {}, + responded: res => { + return res.json(); + } +}); +const $$userConfigMap = withConfigType({}); + +/** + * @type { Apis } + */ +const Apis = createApis(alovaInstance, $$userConfigMap); + +module.exports = { + Apis, + alovaInstance, + $$userConfigMap +}; diff --git a/test/api-v3-ts-test/src/api/index.ts b/test/api-v3-ts-test/src/api/index.ts index eb6e93d..ad00e85 100644 --- a/test/api-v3-ts-test/src/api/index.ts +++ b/test/api-v3-ts-test/src/api/index.ts @@ -3,7 +3,7 @@ import fetchAdapter from 'alova/fetch'; import { createApis, withConfigType } from './createApis'; export const alovaInstance = createAlova({ - baseURL: '', + baseURL: 'https://petstore.swagger.io/v2', requestAdapter: fetchAdapter(), beforeRequest: method => {}, responded: res => { From f24565dbd4f902e17fc4c53019f63fd12f97ec3a Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Fri, 8 Nov 2024 12:18:48 +0800 Subject: [PATCH 43/47] feat(wormhole): support response data types starting with 2xx in openapi files as generation sources --- .../wormhole/src/functions/openApi2Data.ts | 23 +- packages/wormhole/src/helper/openapi.ts | 11 + packages/wormhole/test/generate.spec.ts | 98 +++ .../test/openapis/openapi_success_key.json | 646 ++++++++++++++++++ 4 files changed, 771 insertions(+), 7 deletions(-) create mode 100644 packages/wormhole/test/openapis/openapi_success_key.json diff --git a/packages/wormhole/src/functions/openApi2Data.ts b/packages/wormhole/src/functions/openApi2Data.ts index df3c3b0..1dc3c97 100644 --- a/packages/wormhole/src/functions/openApi2Data.ts +++ b/packages/wormhole/src/functions/openApi2Data.ts @@ -1,4 +1,11 @@ -import { findBy$ref, getStandardRefName, isReferenceObject, mergeObject, removeAll$ref } from '@/helper/openapi'; +import { + findBy$ref, + getResponseSuccessKey, + getStandardRefName, + isReferenceObject, + mergeObject, + removeAll$ref +} from '@/helper/openapi'; import { convertToType, jsonSchema2TsStr } from '@/helper/schema2type'; import { getStandardOperationId, getStandardTags } from '@/helper/standard'; import { generateDefaultValues } from '@/helper/typeStr'; @@ -105,7 +112,8 @@ const parseResponse = async ( searchMap: Map, removeMap: Map ) => { - const responseInfo = responses?.['200']; + const successKey = getResponseSuccessKey(responses); + const responseInfo = responses?.[successKey]; if (!responseInfo) { return { responseName: 'unknown', @@ -267,7 +275,8 @@ export const transformPathObj = async ( url, method }; - const response200 = responses?.['200']; + const successKey = getResponseSuccessKey(responses); + const response200 = responses?.[successKey]; let requestBodyObject = requestBody as OpenAPIV3_1.RequestBodyObject; let responseObject = response200 as OpenAPIV3_1.ResponseObject; let requestKey = 'application/json'; @@ -323,11 +332,11 @@ export const transformPathObj = async ( if (!pathObj.responses) { pathObj.responses = {}; } - pathObj.responses['200'] = responseObject || { content: {} }; - if (!pathObj.responses['200'].content) { - pathObj.responses['200'].content = {}; + pathObj.responses[successKey] = responseObject || { content: {} }; + if (!pathObj.responses[successKey].content) { + pathObj.responses[successKey].content = {}; } - const { content } = pathObj.responses['200']; + const { content } = pathObj.responses[successKey]; if (!content[responseKey]) { content[responseKey] = {}; } diff --git a/packages/wormhole/src/helper/openapi.ts b/packages/wormhole/src/helper/openapi.ts index b98e076..9f9a308 100644 --- a/packages/wormhole/src/helper/openapi.ts +++ b/packages/wormhole/src/helper/openapi.ts @@ -345,3 +345,14 @@ export function getStandardRefName(refPath: string, toUpperCase: boolean = true) refPathMap.set(refPath, newRefName); return newRefName; } + +export function getResponseSuccessKey(responsesObject?: OpenAPIV3_1.ResponsesObject) { + if (!responsesObject) { + return 200; + } + const successKeys = Object.keys(responsesObject) + .map(key => Number(key)) + .filter(key => !Number.isNaN(key) && key >= 200 && key < 300) + .sort((a, b) => a - b); + return successKeys[0] ?? 200; +} diff --git a/packages/wormhole/test/generate.spec.ts b/packages/wormhole/test/generate.spec.ts index 9ef0e8b..1fdcb39 100644 --- a/packages/wormhole/test/generate.spec.ts +++ b/packages/wormhole/test/generate.spec.ts @@ -938,4 +938,102 @@ describe('generate API', () => { ): Alova2Method;`) ); }); + + test('the response data type starting with 2xx in the openapi file should be used as the generation source', async () => { + const outputDir = resolve(__dirname, `./mock_output/openapi_success_key${getSalt()}`); + await generate({ + generator: [ + { + input: resolve(__dirname, './openapis/openapi_success_key.json'), + output: outputDir + } + ] + }); + + const globalsFile = await fs.readFile(resolve(outputDir, 'globals.d.ts'), 'utf-8'); + // generate 200 `Blob` from Response + expect(globalsFile).toMatch( + createStrReg(` + * **Response** + * \`\`\`ts + * type Response = Blob + * \`\`\` + */ + generateCase1< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method;`) + ); + // generate 201 `string` from Response + expect(globalsFile).toMatch( + createStrReg(` + * **Response** + * \`\`\`ts + * type Response = string + * \`\`\` + */ + generateCase2< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method;`) + ); + // generate 299 `string[]` from Response + expect(globalsFile).toMatch( + createStrReg(` + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + generateCase3< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method;`) + ); + // generate 200 `string[]` from Response 200、201、299 + expect(globalsFile).toMatch( + createStrReg(` + * **Response** + * \`\`\`ts + * type Response = string[] + * \`\`\` + */ + generateCase4< + Config extends Alova2MethodConfig & { + params: { + /** + * [required] + */ + codegenOptionsURL: string; + }; + } + >( + config: Config + ): Alova2Method;`) + ); + }); }); diff --git a/packages/wormhole/test/openapis/openapi_success_key.json b/packages/wormhole/test/openapis/openapi_success_key.json new file mode 100644 index 0000000..c2a7804 --- /dev/null +++ b/packages/wormhole/test/openapis/openapi_success_key.json @@ -0,0 +1,646 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "Swagger Generator", + "description": "This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/).", + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + }, + "version": "3.0.57" + }, + "servers": [ + { + "url": "/api1" + } + ], + "tags": [ + { + "name": "clients" + }, + { + "name": "servers" + }, + { + "name": "documentation" + }, + { + "name": "config" + } + ], + "paths": { + "/generate": { + "get": { + "tags": ["clients"], + "operationId": "generateCase1", + "parameters": [ + { + "name": "codegenOptionsURL", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/octet-stream": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + } + } + }, + "post": { + "tags": ["clients"], + "operationId": "generateCase2", + "parameters": [ + { + "name": "codegenOptionsURL", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "201": { + "description": "successful operation", + "content": { + "application/octet-stream": { + "schema": { + "type": "string" + } + } + } + } + } + } + }, + "/clients": { + "get": { + "tags": ["clients"], + "operationId": "generateCase3", + "parameters": [ + { + "name": "codegenOptionsURL", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "299": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + } + }, + "/documentation": { + "get": { + "tags": ["clients"], + "operationId": "generateCase4", + "parameters": [ + { + "name": "codegenOptionsURL", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "201": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "number" + } + } + } + } + }, + "299": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "boolean" + } + } + } + } + } + } + } + }, + "/{type}/{version}": { + "get": { + "tags": ["clients", "servers", "documentation", "config"], + "summary": "List generator languages of the given type and version", + "operationId": "languages", + "parameters": [ + { + "$ref": "#/components/parameters/type" + }, + { + "name": "version", + "in": "path", + "description": "generator version used by codegen engine", + "required": true, + "schema": { + "type": "string", + "enum": ["V2", "V3"] + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "x-swagger-router-controller": "io.swagger.v3.generator.online.GeneratorController" + } + }, + "/types": { + "get": { + "tags": ["clients", "servers", "documentation", "config"], + "summary": "List generator languages of version defined in 'version parameter (defaults to V3) and type included in 'types' parameter; all languages", + "operationId": "languagesMulti", + "parameters": [ + { + "$ref": "#/components/parameters/types" + }, + { + "$ref": "#/components/parameters/version" + } + ], + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "x-swagger-router-controller": "io.swagger.v3.generator.online.GeneratorController" + } + }, + "/options": { + "get": { + "tags": ["clients", "servers", "documentation", "config"], + "summary": "Returns options for a given language and version (defaults to V3)", + "operationId": "listOptions", + "parameters": [ + { + "name": "language", + "in": "query", + "description": "language", + "schema": { + "type": "string" + } + }, + { + "$ref": "#/components/parameters/version" + } + ], + "responses": { + "201": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/CliOption" + } + } + } + } + }, + "202": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Options" + } + } + } + } + } + }, + "x-swagger-router-controller": "io.swagger.v3.generator.online.GeneratorController" + } + }, + "/model": { + "post": { + "tags": ["clients", "servers", "documentation", "config"], + "summary": "你好Generates the intermediate model (\"bundle\") and returns it as a JSON. body.", + "operationId": "generateBundle", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerationRequest" + } + } + } + }, + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerationRequest" + } + } + } + } + }, + "x-swagger-router-controller": "io.swagger.v3.generator.online.GeneratorController" + } + }, + "/render": { + "post": { + "tags": ["documentation"], + "summary": "render a template using the provided data", + "operationId": "renderTemplate", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RenderRequest" + } + } + } + }, + "responses": { + "200": { + "description": "successful operation" + } + }, + "x-swagger-router-controller": "io.swagger.v3.generator.online.GeneratorController24334" + } + } + }, + "components": { + "schemas": { + "GenerationRequest": { + "required": ["lang"], + "type": "object", + "properties": { + "lang": { + "title": "language", + "type": "string", + "description": "language to generate (required)456", + "example": "java" + }, + "spec": { + "type": "object", + "description": "spec in json format. . Alternative to `specURL`" + }, + "specURL": { + "type": "string", + "description": "URL of the spec in json format. Alternative to `spec`" + }, + "type": { + "type": "string", + "description": "type of the spec", + "enum": ["CLIENT", "SERVER", "DOCUMENTATION", "CONFIG"] + }, + "codegenVersion": { + "type": "string", + "description": "codegen version to use", + "enum": ["V2", "V3"] + }, + "options": { + "$ref": "#/components/schemas/Options" + } + }, + "x-swagger-router-model": "io.swagger.codegen.v3.service.GenerationRequest" + }, + "AuthorizationValue": { + "title": "authorization", + "type": "object", + "properties": { + "value": { + "type": "string", + "description": "Authorization value" + }, + "keyName": { + "type": "string", + "description": "Authorization key" + }, + "type": { + "type": "string", + "description": "Authorization type", + "enum": ["query", "header"] + } + }, + "description": "adds authorization headers when fetching the open api definitions remotely. Pass in an authorizationValue object", + "x-swagger-router-model": "io.swagger.v3.parser.core.models.AuthorizationValue" + }, + "Options": { + "type": "object", + "properties": { + "auth": { + "title": "authorization", + "type": "string", + "description": "adds authorization headers when fetching the open api definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values" + }, + "authorizationValue": { + "$ref": "#/components/schemas/AuthorizationValue" + }, + "apiPackage": { + "title": "api package", + "type": "string", + "description": "package for generated api classes" + }, + "templateVersion": { + "title": "Template Version", + "type": "string", + "description": "template version for generation" + }, + "modelPackage": { + "title": "model package", + "type": "string", + "description": "package for generated models" + }, + "modelNamePrefix": { + "title": "model name prefix", + "type": "string", + "description": "Prefix that will be prepended to all model names. Default is the empty string." + }, + "modelNameSuffix": { + "title": "model name suffix", + "type": "string", + "description": "PrefixSuffix that will be appended to all model names. Default is the empty string." + }, + "systemProperties": { + "title": "System Properties", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "sets specified system properties in key/value format" + }, + "instantiationTypes": { + "title": "instantiation types", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "sets instantiation type mappings in key/value format. For example (in Java): array=ArrayList,map=HashMap. In other words array types will get instantiated as ArrayList in generated code." + }, + "typeMappings": { + "title": "type mappings", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "sets mappings between swagger spec types and generated code types in key/value format. For example: array=List,map=Map,string=String." + }, + "additionalProperties": { + "title": "additional properties", + "type": "object", + "additionalProperties": { + "type": "object" + }, + "description": "sets additional properties that can be referenced by the mustache templates in key/value format." + }, + "languageSpecificPrimitives": { + "title": "language specific primitives", + "type": "array", + "description": "specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double. You can also have multiple occurrences of this option.", + "items": { + "type": "string" + } + }, + "importMappings": { + "title": "import mappings", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "specifies mappings between a given class and the import that should be used for that class in key/value format." + }, + "invokerPackage": { + "title": "invoker package", + "type": "string", + "description": "root package for generated code" + }, + "groupId": { + "title": "group id", + "type": "string", + "description": "groupId in generated pom.xml" + }, + "artifactId": { + "title": "artifact id", + "type": "string", + "description": "artifactId in generated pom.xml" + }, + "artifactVersion": { + "title": "artifact version", + "type": "string", + "description": "artifact version generated in pom.xml" + }, + "library": { + "title": "library", + "type": "string", + "description": "library template (sub-template)" + }, + "gitUserId": { + "title": "git user id", + "type": "string", + "description": "Git user ID, e.g. swagger-api." + }, + "gitRepoId": { + "title": "git repo id", + "type": "string", + "description": "Git repo ID, e.g. swagger-codegen." + }, + "releaseNote": { + "title": "release note", + "type": "string", + "description": "Release note, default to 'Minor update'." + }, + "httpUserAgent": { + "title": "http user agent", + "type": "string", + "description": "HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}'" + }, + "reservedWordsMappings": { + "title": "reserved words mappings", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "pecifies how a reserved name should be escaped to. Otherwise, the default _ is used. For example id=identifier." + }, + "ignoreFileOverride": { + "title": "ignore file override location", + "type": "string", + "description": "Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation." + }, + "removeOperationIdPrefix": { + "title": "remove prefix of the operationId", + "type": "boolean", + "description": "Remove prefix of operationId, e.g. config_getId => getId" + }, + "skipOverride": { + "type": "boolean" + } + }, + "x-swagger-router-model": "io.swagger.codegen.v3.service.Options" + }, + "CliOption": { + "type": "object", + "properties": { + "optionName": { + "type": "string" + }, + "description": { + "type": "string" + }, + "type": { + "type": "string", + "description": "Data type is based on the types supported by the JSON-Schema" + }, + "enum": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "default": { + "type": "string" + } + } + }, + "RenderRequest": { + "required": ["context", "template"], + "type": "object", + "properties": { + "template": { + "title": "template", + "type": "string", + "description": "template as string", + "example": "{{!mustache}}" + }, + "context": { + "title": "context", + "type": "string", + "description": "context as string", + "example": "{}" + } + }, + "x-swagger-router-model": "io.swagger.codegen.v3.service.RenderRequest" + }, + "RenderResponse": { + "required": ["value"], + "type": "object", + "properties": { + "value": { + "type": "string" + } + }, + "x-swagger-router-model": "io.swagger.codegen.v3.service.RenderResponse" + } + }, + "parameters": { + "version": { + "name": "version", + "in": "query", + "description": "generator version used by codegen engine", + "schema": { + "type": "string", + "enum": ["V2", "V3"] + } + }, + "type": { + "name": "type", + "in": "path", + "description": "generator type", + "required": true, + "schema": { + "type": "string", + "enum": ["client", "server", "documentation", "config"] + } + }, + "types": { + "name": "types", + "in": "query", + "description": "comma-separated list of generator types", + "required": true, + "style": "form", + "explode": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": ["client", "server", "documentation", "config"] + } + } + } + } + } +} From 9f32cef6608a619731a55ab4ebd86b54dc33dbf4 Mon Sep 17 00:00:00 2001 From: chenzhilin Date: Fri, 8 Nov 2024 12:40:28 +0800 Subject: [PATCH 44/47] fix(vscode-extension): fix alova status button status problem --- packages/vscode-extension/src/commands/refresh.ts | 5 ++++- packages/vscode-extension/src/commands/setup.ts | 5 ++++- packages/vscode-extension/src/components/event.ts | 14 ++++++++------ .../vscode-extension/src/functions/getWormhole.ts | 8 ++++---- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/packages/vscode-extension/src/commands/refresh.ts b/packages/vscode-extension/src/commands/refresh.ts index d36a1b6..18e2c49 100644 --- a/packages/vscode-extension/src/commands/refresh.ts +++ b/packages/vscode-extension/src/commands/refresh.ts @@ -2,6 +2,7 @@ import Error from '@/components/error'; import message from '@/components/message'; import { enable, loading } from '@/components/statusBar'; import generate from '@/functions/generate'; +import { getWormhole } from '@/functions/getWormhole'; import readConfig, { updatedConfigPool } from '@/functions/readConfig'; import { getFileNameByPath } from '@/utils'; import { getWorkspacePaths } from '@/utils/vscode'; @@ -24,7 +25,9 @@ export default { throw error; }); } finally { - enable(); + if (getWormhole()) { + enable(); + } } } } as Commonand; diff --git a/packages/vscode-extension/src/commands/setup.ts b/packages/vscode-extension/src/commands/setup.ts index 42c72ba..45e6d8f 100644 --- a/packages/vscode-extension/src/commands/setup.ts +++ b/packages/vscode-extension/src/commands/setup.ts @@ -1,6 +1,7 @@ import autocomplete from '@/components/autocomplete'; import { registerEvent } from '@/components/event'; import { outputChannel } from '@/components/message'; +import { getWormhole } from '@/functions/getWormhole'; import readConfig from '@/functions/readConfig'; import { getWorkspacePaths } from '@/utils/vscode'; import * as vscode from 'vscode'; @@ -14,6 +15,8 @@ export default { context.subscriptions.push(outputChannel); registerEvent(); // Read all configuration files - readConfig(getWorkspacePaths()); + if (getWormhole()) { + readConfig(getWorkspacePaths()); + } } } as Commonand; diff --git a/packages/vscode-extension/src/components/event.ts b/packages/vscode-extension/src/components/event.ts index 090a700..5ef9f30 100644 --- a/packages/vscode-extension/src/components/event.ts +++ b/packages/vscode-extension/src/components/event.ts @@ -10,11 +10,15 @@ export function registerEvent() { // listener workspace directory changes vscode.workspace.onDidChangeWorkspaceFolders(event => { event.added.forEach(workspacePath => { - readConfig(`${workspacePath.uri.fsPath}/`); + if (getWormhole()) { + readConfig(`${workspacePath.uri.fsPath}/`); + } }); event.removed.forEach(() => { - readConfig(getWorkspacePaths()); - updatedConfigPool(); + if (getWormhole()) { + readConfig(getWorkspacePaths()); + updatedConfigPool(); + } }); }); // listener package.json file changes @@ -27,7 +31,6 @@ export function registerEvent() { } if (/package\.json$/.test(filePath) && getWormhole()) { readConfig(getCurrentWorkspacePath(filePath)); - updatedConfigPool(); } }, 1000) ); @@ -35,9 +38,8 @@ export function registerEvent() { vscode.workspace.onDidSaveTextDocument(event => { const filePath = event.uri.fsPath; - if (/alova\.config\.[cm]?[jt]s$/.test(filePath)) { + if (/alova\.config\.[cm]?[jt]s$/.test(filePath) && getWormhole()) { readConfig(getCurrentWorkspacePath(filePath)); - updatedConfigPool(); } }); // Listen for errors diff --git a/packages/vscode-extension/src/functions/getWormhole.ts b/packages/vscode-extension/src/functions/getWormhole.ts index 34a31e7..9f00d74 100644 --- a/packages/vscode-extension/src/functions/getWormhole.ts +++ b/packages/vscode-extension/src/functions/getWormhole.ts @@ -33,6 +33,10 @@ export const getWormhole = () => { if (wormhole && BAR_STATE.value !== 'loading') { enable(); } + if (!wormhole) { + disable(); + removeConfiguration(); + } if (wormhole) { // Global configuration @@ -41,9 +45,6 @@ export const getWormhole = () => { templateData: TEMPLATE_DATA }); } - if (!wormhole) { - disable(); - } return wormhole; }; @@ -57,7 +58,6 @@ export default () => return wormhole[key]; } return () => { - removeConfiguration(); throw new Error('module `@alova/wormhole` is not found, please install it first.', true); }; } From 7e7c32dae9c5e8729740b07f3caeea3b63c87c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E9=95=87?= Date: Fri, 8 Nov 2024 13:29:59 +0800 Subject: [PATCH 45/47] chore: update pnpm-lock.yaml --- pnpm-lock.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7bc63d6..e279248 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -207,6 +207,22 @@ importers: specifier: ^1.8.10 version: 1.8.10 + test/api-common: + dependencies: + '@alova/mock': + specifier: ^1.5.2 + version: 1.5.2 + alova: + specifier: ^2.21.3 + version: 2.21.5 + vue: + specifier: ^3.4.27 + version: 3.5.12(typescript@5.6.3) + devDependencies: + '@alova/wormhole': + specifier: workspace:^ + version: link:../../packages/wormhole + test/api-js-commonjs-test: dependencies: '@alova/mock': From b18e7d49b757777110112661f5ef159acf475ede Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E9=95=87?= Date: Fri, 8 Nov 2024 13:54:52 +0800 Subject: [PATCH 46/47] ci: ci flows debug --- .changeset/config.json | 10 +++++++++- .changeset/cyan-rats-stare.md | 5 +++++ package.json | 2 +- packages/vscode-extension/.vscodeignore | 1 - packages/vscode-extension/package.json | 5 +++-- test/api-common/package.json | 1 + test/api-js-commonjs-test/package.json | 1 + test/api-js-test/package.json | 1 + test/api-ts-test/package.json | 1 + test/api-v3-js-commonjs-test/package.json | 1 + test/api-v3-js-test/package.json | 1 + test/api-v3-ts-test/package.json | 1 + 12 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 .changeset/cyan-rats-stare.md diff --git a/.changeset/config.json b/.changeset/config.json index 2840e87..6630327 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -4,7 +4,15 @@ "commit": false, "fixed": [], "linked": [], - "ignore": ["alova-vscode-extension"], + "ignore": [ + "api-v3-js-commonjs-test", + "api-js-commonjs-test", + "api-v3-js-test", + "api-v3-ts-test", + "api-js-test", + "api-ts-test", + "api-common" + ], "access": "public", "baseBranch": "main", "updateInternalDependencies": "minor", diff --git a/.changeset/cyan-rats-stare.md b/.changeset/cyan-rats-stare.md new file mode 100644 index 0000000..5343923 --- /dev/null +++ b/.changeset/cyan-rats-stare.md @@ -0,0 +1,5 @@ +--- +'alova-vscode-extension': major +--- + +the first GA version diff --git a/package.json b/package.json index 157d7e4..9995aff 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "changeset:beta": "changeset pre enter beta", "changeset:pre.exit": "changeset pre exit", "changeset:version": "changeset version", - "release": "pnpm run coveralls && changeset publish && pnpm --filter=alova-vscode-extension release" + "release": "changeset publish && pnpm --filter=alova-vscode-extension release" }, "license": "MIT", "repository": { diff --git a/packages/vscode-extension/.vscodeignore b/packages/vscode-extension/.vscodeignore index 83ee56e..5948ae9 100644 --- a/packages/vscode-extension/.vscodeignore +++ b/packages/vscode-extension/.vscodeignore @@ -1,6 +1,5 @@ .vscode/** .vscode-test/** -out/** src/** .gitignore .yarnrc diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index a9f1e3c..e10e76e 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -3,6 +3,7 @@ "displayName": "Alova", "description": "Generate and search APIs without API documentation any more", "version": "0.1.0", + "private": true, "engines": { "vscode": "^1.89.0", "node": ">=18.19.0", @@ -40,8 +41,8 @@ } }, "scripts": { - "vscode:prepublish": "pnpm run check-types && pnpm run lint:fix && tsx esbuild.ts --production", - "compile": "pnpm run check-types && pnpm run lint:fix && tsx esbuild.ts", + "vscode:prepublish": "pnpm run check-types && tsx esbuild.ts --production", + "compile": "pnpm run check-types && tsx esbuild.ts", "watch": "npm-run-all -p watch:*", "watch:esbuild": "tsx esbuild.ts --watch", "pretest": "tsc -p . --outDir out && tsx esbuild.ts", diff --git a/test/api-common/package.json b/test/api-common/package.json index 632dbdc..7085ff8 100644 --- a/test/api-common/package.json +++ b/test/api-common/package.json @@ -4,6 +4,7 @@ "description": "", "main": "index.js", "type": "commonjs", + "private": true, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "gen": "openapi --input ./openapi.yaml --output ./src/api" diff --git a/test/api-js-commonjs-test/package.json b/test/api-js-commonjs-test/package.json index c893188..239ed86 100644 --- a/test/api-js-commonjs-test/package.json +++ b/test/api-js-commonjs-test/package.json @@ -4,6 +4,7 @@ "description": "", "main": "index.js", "type": "commonjs", + "private": true, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "gen": "openapi --input ./openapi.yaml --output ./src/api" diff --git a/test/api-js-test/package.json b/test/api-js-test/package.json index 0254cc1..88e0a06 100644 --- a/test/api-js-test/package.json +++ b/test/api-js-test/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "description": "", "main": "index.js", + "private": true, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "gen": "openapi --input ./openapi.yaml --output ./src/api" diff --git a/test/api-ts-test/package.json b/test/api-ts-test/package.json index ca8f3cc..873638f 100644 --- a/test/api-ts-test/package.json +++ b/test/api-ts-test/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "description": "", "main": "index.js", + "private": true, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "gen": "openapi --input ./openapi.yaml --output ./src/api", diff --git a/test/api-v3-js-commonjs-test/package.json b/test/api-v3-js-commonjs-test/package.json index 2902b17..994b79c 100644 --- a/test/api-v3-js-commonjs-test/package.json +++ b/test/api-v3-js-commonjs-test/package.json @@ -4,6 +4,7 @@ "description": "", "main": "index.js", "type": "commonjs", + "private": true, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "gen": "openapi --input ./openapi.yaml --output ./src/api" diff --git a/test/api-v3-js-test/package.json b/test/api-v3-js-test/package.json index ebede26..7c49239 100644 --- a/test/api-v3-js-test/package.json +++ b/test/api-v3-js-test/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "description": "", "main": "index.js", + "private": true, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "gen": "openapi --input ./openapi.yaml --output ./src/api" diff --git a/test/api-v3-ts-test/package.json b/test/api-v3-ts-test/package.json index 1ab86b4..bf71fbf 100644 --- a/test/api-v3-ts-test/package.json +++ b/test/api-v3-ts-test/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "description": "", "main": "index.js", + "private": true, "scripts": { "test": "tsx src/main.ts" }, From 3c60f92d53c1b60e683cbd2a529b4b08cd111335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E9=95=87?= Date: Fri, 8 Nov 2024 14:08:31 +0800 Subject: [PATCH 47/47] test: update snapshot file --- .../test/__snapshots__/generate.spec.ts.snap | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/wormhole/test/__snapshots__/generate.spec.ts.snap b/packages/wormhole/test/__snapshots__/generate.spec.ts.snap index 183ba64..6eff6ce 100644 --- a/packages/wormhole/test/__snapshots__/generate.spec.ts.snap +++ b/packages/wormhole/test/__snapshots__/generate.spec.ts.snap @@ -1204,7 +1204,7 @@ exports[`generate API > should generate code from an url 5`] = ` /* tslint:disable */ /* eslint-disable */ /** - * Swagger Generator - version 3.0.63 + * Swagger Generator - version 3.0.64 * * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). * @@ -1277,7 +1277,7 @@ exports[`generate API > should generate code from an url 7`] = ` "/* tslint:disable */ /* eslint-disable */ /** - * Swagger Generator - version 3.0.63 + * Swagger Generator - version 3.0.64 * * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). * @@ -1372,7 +1372,7 @@ exports[`generate API > should generate code from an url 8`] = ` "/* tslint:disable */ /* eslint-disable */ /** - * Swagger Generator - version 3.0.63 + * Swagger Generator - version 3.0.64 * * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). * @@ -8939,7 +8939,7 @@ exports[`generate API > should generate correspoding \`mediaType\` parameters if /* tslint:disable */ /* eslint-disable */ /** - * Swagger Generator - version 3.0.63 + * Swagger Generator - version 3.0.64 * * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). * @@ -9012,7 +9012,7 @@ exports[`generate API > should generate correspoding \`mediaType\` parameters if "/* tslint:disable */ /* eslint-disable */ /** - * Swagger Generator - version 3.0.63 + * Swagger Generator - version 3.0.64 * * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). * @@ -9107,7 +9107,7 @@ exports[`generate API > should generate correspoding \`mediaType\` parameters if "/* tslint:disable */ /* eslint-disable */ /** - * Swagger Generator - version 3.0.63 + * Swagger Generator - version 3.0.64 * * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). * @@ -11348,7 +11348,7 @@ exports[`generate API > should generate corresponding module codes dependent to /* tslint:disable */ /* eslint-disable */ /** - * Swagger Generator - version 3.0.63 + * Swagger Generator - version 3.0.64 * * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). * @@ -11421,7 +11421,7 @@ exports[`generate API > should generate corresponding module codes dependent to "/* tslint:disable */ /* eslint-disable */ /** - * Swagger Generator - version 3.0.63 + * Swagger Generator - version 3.0.64 * * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). * @@ -11516,7 +11516,7 @@ exports[`generate API > should generate corresponding module codes dependent to "/* tslint:disable */ /* eslint-disable */ /** - * Swagger Generator - version 3.0.63 + * Swagger Generator - version 3.0.64 * * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). * @@ -22154,7 +22154,7 @@ exports[`generate API > should generate the existing \`mediaType\` if the target /* tslint:disable */ /* eslint-disable */ /** - * Swagger Generator - version 3.0.63 + * Swagger Generator - version 3.0.64 * * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). * @@ -22227,7 +22227,7 @@ exports[`generate API > should generate the existing \`mediaType\` if the target "/* tslint:disable */ /* eslint-disable */ /** - * Swagger Generator - version 3.0.63 + * Swagger Generator - version 3.0.64 * * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). * @@ -22322,7 +22322,7 @@ exports[`generate API > should generate the existing \`mediaType\` if the target "/* tslint:disable */ /* eslint-disable */ /** - * Swagger Generator - version 3.0.63 + * Swagger Generator - version 3.0.64 * * This is an online swagger codegen server. You can find out more at https://github.com/swagger-api/swagger-codegen or on [irc.freenode.net, #swagger](http://swagger.io/irc/). *

E4Kfv4U%jvWWfJw-0r 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%0AJQvRVfn>4}Khh~#_; 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߼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