@dune2/cli 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth-777GVVSS.js +8 -0
- package/dist/auth-777GVVSS.js.map +1 -0
- package/dist/chunk-2DSIJDNZ.js +22 -0
- package/dist/chunk-2DSIJDNZ.js.map +1 -0
- package/dist/chunk-2SEEW5WZ.js +67 -0
- package/dist/chunk-2SEEW5WZ.js.map +1 -0
- package/dist/{chunk-4BXCANQI.js → chunk-555YTWSW.js} +2 -2
- package/dist/{chunk-4BXCANQI.js.map → chunk-555YTWSW.js.map} +1 -1
- package/dist/chunk-6UFZ6KLX.js +124 -0
- package/dist/chunk-6UFZ6KLX.js.map +1 -0
- package/dist/chunk-ADQ6JLT6.js +196 -0
- package/dist/chunk-ADQ6JLT6.js.map +1 -0
- package/dist/chunk-IKJLPHF7.js +117 -0
- package/dist/chunk-IKJLPHF7.js.map +1 -0
- package/dist/chunk-KNC7XY4Z.js +130 -0
- package/dist/chunk-KNC7XY4Z.js.map +1 -0
- package/dist/chunk-Q7UJ456X.js +24 -0
- package/dist/chunk-Q7UJ456X.js.map +1 -0
- package/dist/cli.js +54 -837
- package/dist/cli.js.map +1 -1
- package/dist/download-ZZKXRKW5.js +49 -0
- package/dist/download-ZZKXRKW5.js.map +1 -0
- package/dist/extract-DGQMSBR5.js +113 -0
- package/dist/extract-DGQMSBR5.js.map +1 -0
- package/dist/generateApi-A4RH4WFR.js +272 -0
- package/dist/generateApi-A4RH4WFR.js.map +1 -0
- package/dist/index.d.ts +2 -7
- package/dist/index.js +8 -7
- package/dist/initConfig-QRYGDQR7.js +36 -0
- package/dist/initConfig-QRYGDQR7.js.map +1 -0
- package/dist/interactive-HNOHT33A.js +43 -0
- package/dist/interactive-HNOHT33A.js.map +1 -0
- package/dist/namespace-4FUD4GZ2.js +137 -0
- package/dist/namespace-4FUD4GZ2.js.map +1 -0
- package/dist/normalizeConfig.js +1 -1
- package/dist/upload-OUXQZAW4.js +92 -0
- package/dist/upload-OUXQZAW4.js.map +1 -0
- package/package.json +4 -5
- package/dist/chunk-COPEAFHL.js +0 -490
- package/dist/chunk-COPEAFHL.js.map +0 -1
- package/dist/uploadToTranslatePlatform-GK4VUXIU.js +0 -45
- package/dist/uploadToTranslatePlatform-GK4VUXIU.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/generateApi/index.ts"],"sourcesContent":["import SwaggerParser from \"@apidevtools/swagger-parser\";\nimport fs from \"fs-extra\";\nimport { compile } from \"json-schema-to-typescript\";\nimport _ from \"lodash\";\nimport { OpenAPIV3 } from \"openapi-types\";\nimport * as os from \"os\";\nimport pMap from \"p-map\";\nimport path from \"path\";\nimport { createLogger } from \"../../shared\";\nimport { ApiConfig, getConfig } from \"../../shared/config\";\nimport { formatFile } from \"../../shared/formatFile\";\nimport { promptApiConfigEnable } from \"../../shared/promptConfigEnable\";\n\nconst log = createLogger(\"generateApi\");\n\nexport async function generateApi() {\n const config = await getConfig();\n const apiConfigs = await promptApiConfigEnable(config.api);\n\n for (const apiConfig of apiConfigs) {\n log.info(`清除旧的api文件: ${apiConfig.output}`);\n await fs.emptydir(apiConfig.output!);\n }\n\n for (const apiConfig of apiConfigs) {\n log.info(\"开始解析 %s\", apiConfig.swaggerJSONPath);\n const parsed = (await SwaggerParser.dereference(apiConfig.swaggerJSONPath, {\n resolve: {\n http: {\n timeout: 30 * 1000,\n },\n },\n })) as OpenAPIV3.Document;\n\n await pMap(Object.entries(parsed.paths), async ([url, pathItemObject]) => {\n log.info(\"开始生成 %s\", url);\n if (pathItemObject) {\n await pMap(\n [\"get\", \"put\", \"post\", \"delete\", \"patch\"],\n async (method) => {\n const operationObject = pathItemObject[method];\n if (operationObject) {\n const code = await generateApiRequestCode({\n url: url,\n method: method,\n operationObject: operationObject,\n apiConfig,\n });\n const outputPath = path\n .join(\n apiConfig.output!,\n url,\n apiConfig.enableTs ? `${method}.ts` : `${method}.js`\n )\n .replace(/:/g, \"_\");\n await fs.ensureFile(outputPath);\n await fs.writeFile(outputPath, code);\n }\n }\n );\n }\n });\n\n if (apiConfig.format) {\n await formatFile(apiConfig.output!);\n }\n }\n\n log.info(\"generateApi Done\");\n}\n\n/**\n * 根据请求方法,生成请求代码\n */\nexport async function generateApiRequestCode(options: {\n url: string;\n method: string;\n operationObject: OpenAPIV3.OperationObject;\n apiConfig: ApiConfig;\n}): Promise<string> {\n const { method, operationObject, apiConfig } = options;\n\n const url = (() => {\n if (typeof apiConfig.urlTransformer === \"string\") {\n return `${apiConfig.urlTransformer}${options.url}`;\n }\n if (typeof apiConfig.urlTransformer === \"function\") {\n return apiConfig.urlTransformer(options.url);\n }\n return options.url;\n })();\n\n const seeUrl = apiConfig.swaggerUiUrl\n ? `${apiConfig.swaggerUiUrl}#/${operationObject.tags?.join(\"/\") ?? \"\"}/${\n operationObject.operationId\n }`\n : \"\";\n\n // 生成的请求构造器的名称,需要使用原始url\n let requestBuilderName = _.camelCase(`${options.url}_${method}_api`);\n\n // 判断是否有效的js变量\n if (!/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(requestBuilderName)) {\n // 不是有效的js变量,使用 _ + 数字\n requestBuilderName = `_${requestBuilderName}`;\n }\n\n //#region url上参数 例如 /api/v1/users/{userId}\n const urlPathParams = getUrlPathParams(\n (operationObject.parameters as never) ?? []\n );\n const urlPathParamsCode = urlPathParams.length\n ? `urlPathParams: ${JSON.stringify(urlPathParams)},`\n : \"\";\n //#endregion\n\n let code: string[] = [\n \"// 这个文件由 @dune2/cli 自动生成,不要手动修改,否则会被覆盖\",\n apiConfig.RequestBuilderImportPath!,\n apiConfig.requestFnImportPath!,\n apiConfig.queryClientImportPath!,\n\n \"/**\",\n ` * ${operationObject.summary}`,\n ` * @tags ${operationObject.tags?.join(\",\")}`,\n seeUrl && ` * @see ${seeUrl}`,\n ` */`,\n ].filter(Boolean);\n\n // builder 代码\n let builderCode = `\\\nexport const ${requestBuilderName} = new RequestBuilder({\n url: '${url}',\n method: '${method}',\n ${apiConfig.requestFnImportPath ? \"requestFn,\" : \"\"}\n ${urlPathParamsCode}\n ${apiConfig.queryClientImportPath ? \"queryClient,\" : \"\"}\n});`\n // 移除空行\n .replace(/,\\n\\s*}/, \",\" + os.EOL + \"}\");\n if (apiConfig.enableTs) {\n builderCode = builderCode.replace(\n \"new RequestBuilder(\",\n `new RequestBuilder<${requestBuilderName}.Req, ${requestBuilderName}.Res>(`\n );\n }\n code.push(builderCode);\n\n if (apiConfig.enableTs) {\n // post和put请求需要生成表单fieldsMap\n const isGenrateFieldsMap = [\"post\", \"put\"].includes(method);\n // 请求参数类型\n // 响应参数类型\n const [requestParamsTypeCode, responseParamsTypeCode] = await Promise.all([\n compileRequestParams(operationObject, isGenrateFieldsMap),\n compileResponseParams(operationObject, apiConfig),\n ]);\n\n code.push(`\nexport namespace ${requestBuilderName} {\n ${requestParamsTypeCode.code}\n \n ${responseParamsTypeCode}\n};`);\n\n if (isGenrateFieldsMap && !_.isEmpty(requestParamsTypeCode.fieldsMap)) {\n // 生成表单fieldsMap\n code.push(`\nexport const ${requestBuilderName}FieldsMap = ${JSON.stringify(\n requestParamsTypeCode.fieldsMap\n )}\n`);\n }\n }\n\n return code.join(os.EOL);\n}\n\nfunction getUrlPathParams(parameters: OpenAPIV3.ParameterObject[]) {\n return parameters\n .filter((item) => item.in === \"path\")\n .map((item) => item.name);\n}\n\n/**\n * 这个方法还不完善,只能处理简单的请求参数\n */\nasync function compileRequestParams(\n operationObject: OpenAPIV3.OperationObject,\n generateFieldsMap = false\n) {\n let schema;\n if (operationObject.requestBody) {\n //TODO: 这里也需要处理其他类型\n schema = (operationObject.requestBody as OpenAPIV3.RequestBodyObject)\n .content[\"application/json\"].schema;\n } else if (operationObject.parameters) {\n const extraProperties = {};\n const parameters: OpenAPIV3.ParameterObject[] = [];\n (operationObject.parameters as OpenAPIV3.ParameterObject[]).forEach(\n (item) => {\n if (![\"query\", \"path\"].includes(item.in)) {\n return;\n }\n if (_.get(item.schema, \"type\") === \"object\") {\n // swagger get 请求上 有些参数是 object 类型 应该拍平\n _.assign(extraProperties, _.get(item.schema, \"properties\", {}));\n } else {\n parameters.push(item);\n }\n }\n );\n\n // 必填参数中忽略 分页相关的参数\n const required = parameters\n .filter(\n (p) => p.required && ![\"pageNum\", \"pageSize\", \"count\"].includes(p.name)\n )\n .map((p) => p.name);\n const properties = Object.fromEntries(\n parameters\n // 后端 swagger 可能出现没有 schema 的情况,这里过滤掉\n .filter((p) => !!p.schema)\n .map((p) => {\n //TODO: 这里也要处理 ref 类型\n const schema = p.schema as OpenAPIV3.SchemaObject;\n return [\n p.name,\n {\n ...schema,\n description: p.description,\n // enum: schema.enum ?? [],\n },\n ];\n })\n );\n schema = {\n required,\n type: \"object\",\n properties: { ...properties, ...extraProperties },\n };\n }\n\n let code = \"\";\n const fieldsMap: Record<string, string> = {};\n if (schema) {\n try {\n code = await compile(schema, \"Req\", {\n bannerComment: \"\",\n ignoreMinAndMaxItems: !!1,\n additionalProperties: false,\n // format: false,\n });\n\n // 判断接口是否是分页请求\n const isPageSearchRequest = (data: any) => {\n // 入参有这些字段就认为是分页查询接口\n const keys = [\"pageNum\", \"pageSize\", \"count\"];\n return (\n _.get(data, \"type\") === \"object\" &&\n _.get(data, \"required\", []).filter((item) => keys.includes(item))\n .length === keys.length\n );\n };\n\n if (generateFieldsMap) {\n // 分页查询接口取params字段\n const params = isPageSearchRequest(schema)\n ? _.get(schema, \"properties.params.properties\", {})\n : schema.properties;\n _.forEach(params, (_, field) => {\n fieldsMap[field] = field;\n });\n }\n } catch (e) {\n log.error(\"生成请求参数类型失败,请检查 %o\", {\n summary: operationObject.summary,\n message: e.message,\n });\n }\n }\n\n return {\n code: code || \"export type Req = any;\",\n fieldsMap,\n };\n}\n\nasync function compileResponseParams(\n operationObject: OpenAPIV3.OperationObject,\n apiConfig: ApiConfig\n) {\n const temp = operationObject.responses[\"200\"] as OpenAPIV3.ResponseObject;\n let code = \"\";\n if (temp?.content) {\n // FIXME: 可能需要处理其他的content类型\n const temp2 = temp.content[\"application/json\"] || temp.content[\"*/*\"];\n const schema = temp2.schema as OpenAPIV3.SchemaObject;\n let data = apiConfig.responseSchemaTransformer!(schema);\n if (data) {\n // 这里需要深度clone的原因是:\n // 解析出来的scheme会尽可能的被复用,导致影响到下次解析\n data = _.cloneDeep(data);\n markCircularToRef(data);\n try {\n code = await compile(data, \"Res\", {\n bannerComment: \"\",\n ignoreMinAndMaxItems: !!1,\n additionalProperties: false,\n // format: false,\n });\n\n // 通过响应数据判断是否是分页查询接口\n const isPageSearchResponse = (data: any) => {\n // 有result字段且为数组,就认为是分页查询接口\n return (\n _.get(data, \"type\") === \"object\" &&\n _.get(data, \"properties.result.type\") === \"array\"\n );\n };\n\n // 新增后端分页查询返回的数据类型\n if (isPageSearchResponse(data)) {\n code += `${os.EOL}export type ResultItem = Res['result'][0]`;\n }\n } catch (e) {\n log.error(\"转换响应参数类型失败, 请检查 %o\", {\n summary: operationObject.summary,\n error: e.message,\n });\n }\n } else {\n log.error(\"responseSchemaTransformer 返回值为空, 请检查\");\n }\n }\n\n return code ? code : \"export type Res = any;\";\n}\n\nexport function markCircularToRef(\n obj,\n parentMark = \"#\",\n map = new Map([[obj, parentMark]]),\n set = new Set([obj])\n) {\n Object.keys(obj).forEach((key) => {\n const value = obj[key];\n if (typeof value === \"object\" && !Array.isArray(value)) {\n if (set.has(value)) {\n obj[key] = { $ref: map.get(value) };\n return;\n }\n const tempMark = parentMark + \"/\" + key;\n set.add(value);\n map.set(value, tempMark);\n markCircularToRef(value, tempMark, map, set);\n }\n });\n return map;\n}\n"],"mappings":"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","names":["schema","_","data"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ declare class GoogleSheet {
|
|
|
20
20
|
private initPromise;
|
|
21
21
|
private initImpl;
|
|
22
22
|
/**
|
|
23
|
-
* 调用sheets其他方法的时候需要先初始化
|
|
23
|
+
* 调用 sheets 其他方法的时候需要先初始化
|
|
24
24
|
*/
|
|
25
25
|
init(): Promise<void>;
|
|
26
26
|
get: (options: sheets_v4.Params$Resource$Spreadsheets$Values$Get) => Promise<GaxiosResponse<sheets_v4.Schema$ValueRange>>;
|
|
@@ -71,9 +71,4 @@ declare function numberToLetter(n: number): string;
|
|
|
71
71
|
|
|
72
72
|
declare function resolveSheetId(str?: string): string | undefined;
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
* 从 翻译平台下载翻译文件
|
|
76
|
-
*/
|
|
77
|
-
declare function downloadFromPlatform(): Promise<void>;
|
|
78
|
-
|
|
79
|
-
export { Config, configName, defaultJsonSorter, defineConfig, downloadFromPlatform, getConfig, googleSheet, letterToNumber, numberToLetter, resolveSheetId };
|
|
74
|
+
export { Config, configName, defaultJsonSorter, defineConfig, getConfig, googleSheet, letterToNumber, numberToLetter, resolveSheetId };
|
package/dist/index.js
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
|
-
configName,
|
|
3
|
-
defineConfig,
|
|
4
|
-
downloadFromPlatform,
|
|
5
|
-
getConfig,
|
|
6
2
|
googleSheet,
|
|
7
3
|
letterToNumber,
|
|
8
4
|
numberToLetter
|
|
9
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-6UFZ6KLX.js";
|
|
6
|
+
import "./chunk-KNC7XY4Z.js";
|
|
7
|
+
import {
|
|
8
|
+
configName,
|
|
9
|
+
defineConfig,
|
|
10
|
+
getConfig
|
|
11
|
+
} from "./chunk-2DSIJDNZ.js";
|
|
10
12
|
import {
|
|
11
13
|
defaultJsonSorter,
|
|
12
14
|
resolveSheetId
|
|
13
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-555YTWSW.js";
|
|
14
16
|
import "./chunk-UGSBKD2I.js";
|
|
15
17
|
export {
|
|
16
18
|
configName,
|
|
17
19
|
defaultJsonSorter,
|
|
18
20
|
defineConfig,
|
|
19
|
-
downloadFromPlatform,
|
|
20
21
|
getConfig,
|
|
21
22
|
googleSheet,
|
|
22
23
|
letterToNumber,
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {
|
|
2
|
+
configName,
|
|
3
|
+
getConfig
|
|
4
|
+
} from "./chunk-2DSIJDNZ.js";
|
|
5
|
+
import "./chunk-555YTWSW.js";
|
|
6
|
+
import {
|
|
7
|
+
createLogger
|
|
8
|
+
} from "./chunk-UGSBKD2I.js";
|
|
9
|
+
|
|
10
|
+
// src/commands/initConfig.ts
|
|
11
|
+
import fs from "fs-extra";
|
|
12
|
+
import path from "path";
|
|
13
|
+
var log = createLogger("initConfig");
|
|
14
|
+
var tpl = `/**
|
|
15
|
+
* @param {import('@dune2/cli').Config} config
|
|
16
|
+
*/
|
|
17
|
+
function defineConfig(config) {
|
|
18
|
+
return config;
|
|
19
|
+
}
|
|
20
|
+
module.exports = defineConfig({ i18n: [], api:[] });
|
|
21
|
+
`;
|
|
22
|
+
var initConfig = async () => {
|
|
23
|
+
const config = await getConfig();
|
|
24
|
+
const configPath = path.join(config.cwd, configName);
|
|
25
|
+
log.info(`config file path: ${configPath}`);
|
|
26
|
+
if (await fs.pathExists(configPath)) {
|
|
27
|
+
log.info(`config file already exists, skip`);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
await fs.writeFile(configPath, tpl);
|
|
31
|
+
log.info(`config file created`);
|
|
32
|
+
};
|
|
33
|
+
export {
|
|
34
|
+
initConfig
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=initConfig-QRYGDQR7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/initConfig.ts"],"sourcesContent":["import { createLogger } from \"../shared\";\nimport { getConfig, configName } from \"../shared/config\";\nimport fs from \"fs-extra\";\nimport path from \"path\";\n\nconst log = createLogger(\"initConfig\");\n\nconst tpl = `\\\n/**\n * @param {import('@dune2/cli').Config} config\n */\nfunction defineConfig(config) {\n return config;\n}\nmodule.exports = defineConfig({ i18n: [], api:[] });\n`;\n\nexport const initConfig = async () => {\n const config = await getConfig();\n const configPath = path.join(config.cwd!, configName);\n log.info(`config file path: ${configPath}`);\n if (await fs.pathExists(configPath)) {\n log.info(`config file already exists, skip`);\n return;\n }\n await fs.writeFile(configPath, tpl);\n log.info(`config file created`);\n};\n"],"mappings":";;;;;;;;;;AAEA,OAAO,QAAQ;AACf,OAAO,UAAU;AAEjB,IAAM,MAAM,aAAa,YAAY;AAErC,IAAM,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUL,IAAM,aAAa,YAAY;AACpC,QAAM,SAAS,MAAM,UAAU;AAC/B,QAAM,aAAa,KAAK,KAAK,OAAO,KAAM,UAAU;AACpD,MAAI,KAAK,qBAAqB,UAAU,EAAE;AAC1C,MAAI,MAAM,GAAG,WAAW,UAAU,GAAG;AACnC,QAAI,KAAK,kCAAkC;AAC3C;AAAA,EACF;AACA,QAAM,GAAG,UAAU,YAAY,GAAG;AAClC,MAAI,KAAK,qBAAqB;AAChC;","names":[]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cli,
|
|
3
|
+
createLogger
|
|
4
|
+
} from "./chunk-UGSBKD2I.js";
|
|
5
|
+
|
|
6
|
+
// src/commands/interactive.ts
|
|
7
|
+
import enquirer from "enquirer";
|
|
8
|
+
var { prompt } = enquirer;
|
|
9
|
+
var log = createLogger("interactive");
|
|
10
|
+
var interactive = async (args) => {
|
|
11
|
+
var _a;
|
|
12
|
+
const commands = cli.commands.filter((command2) => {
|
|
13
|
+
if (command2.name) {
|
|
14
|
+
return !command2.name.startsWith("@@") && command2.name !== "interactive";
|
|
15
|
+
}
|
|
16
|
+
return false;
|
|
17
|
+
});
|
|
18
|
+
const commandMap = /* @__PURE__ */ new Map();
|
|
19
|
+
const res = await prompt({
|
|
20
|
+
type: "autocomplete",
|
|
21
|
+
name: "command",
|
|
22
|
+
message: "\u9009\u62E9\u8981\u6267\u884C\u7684\u547D\u4EE4\uFF1A",
|
|
23
|
+
choices: commands.map((command2) => {
|
|
24
|
+
commandMap.set(command2.name, command2);
|
|
25
|
+
return {
|
|
26
|
+
name: command2.name,
|
|
27
|
+
value: command2.name,
|
|
28
|
+
message: command2.description,
|
|
29
|
+
hint: `\u7B49\u540C\u547D\u4EE4 ${cli.name} ${command2.name}`
|
|
30
|
+
};
|
|
31
|
+
})
|
|
32
|
+
});
|
|
33
|
+
const command = commandMap.get(res.command);
|
|
34
|
+
if (!command) {
|
|
35
|
+
log.error("\u672A\u627E\u5230\u547D\u4EE4 %s", res.command);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
(_a = command.commandAction) == null ? void 0 : _a.apply(cli, args);
|
|
39
|
+
};
|
|
40
|
+
export {
|
|
41
|
+
interactive
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=interactive-HNOHT33A.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/interactive.ts"],"sourcesContent":["import { cli, createLogger } from \"../shared\";\nimport enquirer from \"enquirer\";\nconst { prompt } = enquirer;\n\nconst log = createLogger(\"interactive\");\n\nexport const interactive = async (args: any) => {\n const commands = cli.commands.filter((command) => {\n if (command.name) {\n return !command.name.startsWith(\"@@\") && command.name !== \"interactive\";\n }\n return false;\n });\n\n const commandMap = new Map<string, typeof commands[number]>();\n const res = await prompt<{ command: string }>({\n type: \"autocomplete\",\n name: \"command\",\n message: \"选择要执行的命令:\",\n choices: commands.map((command) => {\n commandMap.set(command.name, command);\n return {\n name: command.name,\n value: command.name,\n message: command.description,\n hint: `等同命令 ${cli.name} ${command.name}`,\n };\n }),\n });\n const command = commandMap.get(res.command);\n if (!command) {\n log.error(\"未找到命令 %s\", res.command);\n return;\n }\n command.commandAction?.apply(cli, args);\n};\n"],"mappings":";;;;;;AACA,OAAO,cAAc;AACrB,IAAM,EAAE,OAAO,IAAI;AAEnB,IAAM,MAAM,aAAa,aAAa;AAE/B,IAAM,cAAc,OAAO,SAAc;AANhD;AAOE,QAAM,WAAW,IAAI,SAAS,OAAO,CAACA,aAAY;AAChD,QAAIA,SAAQ,MAAM;AAChB,aAAO,CAACA,SAAQ,KAAK,WAAW,IAAI,KAAKA,SAAQ,SAAS;AAAA,IAC5D;AACA,WAAO;AAAA,EACT,CAAC;AAED,QAAM,aAAa,oBAAI,IAAqC;AAC5D,QAAM,MAAM,MAAM,OAA4B;AAAA,IAC5C,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS,SAAS,IAAI,CAACA,aAAY;AACjC,iBAAW,IAAIA,SAAQ,MAAMA,QAAO;AACpC,aAAO;AAAA,QACL,MAAMA,SAAQ;AAAA,QACd,OAAOA,SAAQ;AAAA,QACf,SAASA,SAAQ;AAAA,QACjB,MAAM,4BAAQ,IAAI,IAAI,IAAIA,SAAQ,IAAI;AAAA,MACxC;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACD,QAAM,UAAU,WAAW,IAAI,IAAI,OAAO;AAC1C,MAAI,CAAC,SAAS;AACZ,QAAI,MAAM,qCAAY,IAAI,OAAO;AACjC;AAAA,EACF;AACA,gBAAQ,kBAAR,mBAAuB,MAAM,KAAK;AACpC;","names":["command"]}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import {
|
|
2
|
+
formatFile
|
|
3
|
+
} from "./chunk-Q7UJ456X.js";
|
|
4
|
+
import {
|
|
5
|
+
getConfig
|
|
6
|
+
} from "./chunk-2DSIJDNZ.js";
|
|
7
|
+
import "./chunk-555YTWSW.js";
|
|
8
|
+
import {
|
|
9
|
+
createLogger
|
|
10
|
+
} from "./chunk-UGSBKD2I.js";
|
|
11
|
+
|
|
12
|
+
// src/commands/namespace.ts
|
|
13
|
+
import enquirer from "enquirer";
|
|
14
|
+
import fs from "fs-extra";
|
|
15
|
+
import { globby } from "globby";
|
|
16
|
+
import _ from "lodash";
|
|
17
|
+
import pMap from "p-map";
|
|
18
|
+
import pc from "picocolors";
|
|
19
|
+
|
|
20
|
+
// src/shared/autoNamespaceByReg.ts
|
|
21
|
+
function autoNamespaceByReg(code, namespace2) {
|
|
22
|
+
let hasChanged = false;
|
|
23
|
+
code = code.replace(/\Wt`(.+?)`/gm, (match, p1) => {
|
|
24
|
+
if (/\S\.\S/.test(p1)) {
|
|
25
|
+
return match;
|
|
26
|
+
}
|
|
27
|
+
hasChanged = true;
|
|
28
|
+
return match.replace(p1, `${namespace2}.${p1}`);
|
|
29
|
+
});
|
|
30
|
+
code = code.replace(/\Wt\(['"](.+?)['"][),]/gm, (match, p1) => {
|
|
31
|
+
if (/\S\.\S/.test(p1)) {
|
|
32
|
+
return match;
|
|
33
|
+
}
|
|
34
|
+
hasChanged = true;
|
|
35
|
+
return match.replace(p1, `${namespace2}.${p1}`);
|
|
36
|
+
});
|
|
37
|
+
if (hasChanged) {
|
|
38
|
+
return code;
|
|
39
|
+
}
|
|
40
|
+
return "";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// src/commands/namespace.ts
|
|
44
|
+
var { prompt } = enquirer;
|
|
45
|
+
var log = createLogger("namespace");
|
|
46
|
+
async function namespace(params) {
|
|
47
|
+
var _a, _b;
|
|
48
|
+
const { mode = "swc" } = params;
|
|
49
|
+
const config = await getConfig();
|
|
50
|
+
let i18nConfigs = (_a = config.i18n) == null ? void 0 : _a.filter((item) => !item.disableExtract);
|
|
51
|
+
if (!i18nConfigs) {
|
|
52
|
+
log.info("\u6CA1\u6709\u914D\u7F6E i18n");
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const { i18nDir } = await prompt({
|
|
56
|
+
type: "select",
|
|
57
|
+
name: "i18nDir",
|
|
58
|
+
message: "\u9009\u62E9\u8981\u751F\u6548\u7684\u914D\u7F6E\u9879",
|
|
59
|
+
choices: i18nConfigs.map((item) => {
|
|
60
|
+
return {
|
|
61
|
+
name: item.i18nDir,
|
|
62
|
+
hint: `sheetRange: ${item.sheetRange}`
|
|
63
|
+
};
|
|
64
|
+
})
|
|
65
|
+
});
|
|
66
|
+
let i18nConfig = i18nConfigs.find((item) => item.i18nDir === i18nDir);
|
|
67
|
+
if (!i18nConfig) {
|
|
68
|
+
log.info("\u6CA1\u6709\u627E\u5230\u5BF9\u5E94\u7684\u914D\u7F6E");
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const { namespaces } = await prompt({
|
|
72
|
+
type: "multiselect",
|
|
73
|
+
message: "\u9009\u62E9\u8981\u751F\u6548\u7684\u914D\u7F6E\u9879",
|
|
74
|
+
//@ts-ignore
|
|
75
|
+
hint: "(\u7A7A\u683C\u9009\u4E2D\uFF0C\u56DE\u8F66\u786E\u8BA4)",
|
|
76
|
+
name: "namespaces",
|
|
77
|
+
validate(value) {
|
|
78
|
+
return value.length === 0 ? `\u81F3\u5C11\u9009\u62E9\u4E00\u9879` : true;
|
|
79
|
+
},
|
|
80
|
+
choices: _.map(i18nConfig.namespace, (v, k) => {
|
|
81
|
+
return {
|
|
82
|
+
name: k
|
|
83
|
+
};
|
|
84
|
+
})
|
|
85
|
+
});
|
|
86
|
+
const autoNamespace = await (() => {
|
|
87
|
+
if (mode === "swc") {
|
|
88
|
+
log.info("\u4F7F\u7528 swc \u6765\u5904\u7406");
|
|
89
|
+
return import("@dune2/wasm").then((m) => m.autoNamespace);
|
|
90
|
+
}
|
|
91
|
+
log.info("\u4F7F\u7528 reg \u6765\u5904\u7406");
|
|
92
|
+
return autoNamespaceByReg;
|
|
93
|
+
})();
|
|
94
|
+
for (const namespace2 of namespaces) {
|
|
95
|
+
const namespaceConfig = (_b = i18nConfig.namespace) == null ? void 0 : _b[namespace2];
|
|
96
|
+
const suffix = `**/**.{js,jsx,ts,tsx}`;
|
|
97
|
+
const combined = _.map(_.castArray(namespaceConfig), (v) => {
|
|
98
|
+
v = v.endsWith("/") ? v : v + "/";
|
|
99
|
+
return v + suffix;
|
|
100
|
+
});
|
|
101
|
+
log.info("\u6B63\u5728\u5904\u7406 namespace: %s", pc.green(namespace2));
|
|
102
|
+
log.info("\u9884\u8BA1\u5904\u7406\u7684\u6587\u4EF6\u8DEF\u5F84: %s", pc.green(combined.join("\n")));
|
|
103
|
+
const files = await globby(
|
|
104
|
+
[
|
|
105
|
+
"!**/node_modules/**",
|
|
106
|
+
"!**.d.ts",
|
|
107
|
+
"!**/.next/**",
|
|
108
|
+
"!**/out/**"
|
|
109
|
+
//
|
|
110
|
+
].concat(combined),
|
|
111
|
+
{ cwd: i18nConfig.cwd }
|
|
112
|
+
);
|
|
113
|
+
log.info("\u9884\u8BA1\u5171\u5904\u7406 %s \u4E2A\u6587\u4EF6", pc.green(files.length));
|
|
114
|
+
let transformedFileSet = /* @__PURE__ */ new Set();
|
|
115
|
+
await pMap(files, async (file) => {
|
|
116
|
+
const content = await fs.readFile(file, "utf-8");
|
|
117
|
+
const newContent = await autoNamespace(
|
|
118
|
+
content,
|
|
119
|
+
namespace2,
|
|
120
|
+
i18nConfig.namespaceSeparator
|
|
121
|
+
);
|
|
122
|
+
if (newContent) {
|
|
123
|
+
await fs.writeFile(file, newContent);
|
|
124
|
+
await formatFile(file);
|
|
125
|
+
transformedFileSet.add(file);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
log.info(
|
|
129
|
+
"\u5DF2\u4E3A %s \u4E2A\u6587\u4EF6 \u81EA\u52A8\u6DFB\u52A0 namespace",
|
|
130
|
+
pc.green(transformedFileSet.size)
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
export {
|
|
135
|
+
namespace
|
|
136
|
+
};
|
|
137
|
+
//# sourceMappingURL=namespace-4FUD4GZ2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/namespace.ts","../src/shared/autoNamespaceByReg.ts"],"sourcesContent":["import enquirer from \"enquirer\";\nimport fs from \"fs-extra\";\nimport { globby } from \"globby\";\nimport _ from \"lodash\";\nimport pMap from \"p-map\";\nimport pc from \"picocolors\";\nimport { createLogger } from \"../shared\";\nimport { autoNamespaceByReg } from \"../shared/autoNamespaceByReg\";\nimport { getConfig } from \"../shared/config\";\nimport { formatFile } from \"../shared/formatFile\";\n\nconst { prompt } = enquirer;\n\nconst log = createLogger(\"namespace\");\ninterface Params {\n /**\n * 生成模式\n *\n * - swc 指的是用swc 插件来添加 前缀\n *\n * swc 生成的代码更加规范,但是会有一些问题\n *\n * - reg 指的是用正则来添加 前缀\n *\n * reg 目前只能初始 t function 的调用,不能处理 Trans 组件的复杂\n * @default swc\n */\n mode?: \"swc\" | \"reg\";\n}\n\nexport async function namespace(params: Params) {\n const { mode = \"swc\" } = params;\n const config = await getConfig();\n\n // 不允许提取的 配置 不需要选择\n let i18nConfigs = config.i18n?.filter((item) => !item.disableExtract);\n if (!i18nConfigs) {\n log.info(\"没有配置 i18n\");\n return;\n }\n\n // 选择 生效的 i18n 配置\n const { i18nDir } = await prompt<{ i18nDir: string }>({\n type: \"select\",\n name: \"i18nDir\",\n message: \"选择要生效的配置项\",\n choices: i18nConfigs.map((item) => {\n return {\n name: item.i18nDir!,\n hint: `sheetRange: ${item.sheetRange}`,\n };\n }),\n });\n let i18nConfig = i18nConfigs.find((item) => item.i18nDir === i18nDir);\n if (!i18nConfig) {\n log.info(\"没有找到对应的配置\");\n return;\n }\n\n // 选择 生效的 namespace\n const { namespaces } = await prompt<{ namespaces: string[] }>({\n type: \"multiselect\",\n message: \"选择要生效的配置项\",\n //@ts-ignore\n hint: \"(空格选中,回车确认)\",\n name: \"namespaces\",\n validate(value) {\n return value.length === 0 ? `至少选择一项` : true;\n },\n choices: _.map(i18nConfig.namespace, (v, k) => {\n return {\n name: k,\n };\n }),\n });\n\n const autoNamespace = await (() => {\n if (mode === \"swc\") {\n log.info(\"使用 swc 来处理\");\n return import(\"@dune2/wasm\").then((m) => m.autoNamespace);\n }\n log.info(\"使用 reg 来处理\");\n return autoNamespaceByReg;\n })();\n\n for (const namespace of namespaces) {\n const namespaceConfig = i18nConfig.namespace?.[namespace];\n\n const suffix = `**/**.{js,jsx,ts,tsx}`;\n const combined = _.map(_.castArray(namespaceConfig), (v) => {\n v = v.endsWith(\"/\") ? v : v + \"/\";\n return v + suffix;\n });\n log.info(\"正在处理 namespace: %s\", pc.green(namespace));\n log.info(\"预计处理的文件路径: %s\", pc.green(combined.join(\"\\n\")));\n\n const files = await globby(\n [\n \"!**/node_modules/**\",\n \"!**.d.ts\",\n \"!**/.next/**\",\n \"!**/out/**\",\n //\n ].concat(combined),\n { cwd: i18nConfig.cwd }\n );\n\n log.info(\"预计共处理 %s 个文件\", pc.green(files.length));\n\n let transformedFileSet = new Set<string>();\n\n await pMap(files, async (file) => {\n const content = await fs.readFile(file, \"utf-8\");\n\n const newContent = await autoNamespace(\n content,\n namespace,\n i18nConfig!.namespaceSeparator!\n );\n\n if (newContent) {\n await fs.writeFile(file, newContent);\n await formatFile(file);\n transformedFileSet.add(file);\n }\n });\n log.info(\n \"已为 %s 个文件 自动添加 namespace\",\n pc.green(transformedFileSet.size)\n );\n }\n}\n","/**\n * 目前 支持 . 分割的 namespace\n */\nexport function autoNamespaceByReg(code: string, namespace: string) {\n let hasChanged = false;\n\n /**\n * replace case:\n * t`login` => t`Merchants.login`\n * t`hello ${name}` => t`Merchants.hello ${name}`\n */\n code = code.replace(/\\Wt`(.+?)`/gm, (match, p1) => {\n // 如果 当前 有 $b. 则不替换\n if (/\\S\\.\\S/.test(p1)) {\n return match;\n }\n hasChanged = true;\n return match.replace(p1, `${namespace}.${p1}`);\n });\n\n /**\n * replace case:\n * t('login') => t('Merchants.login')\n * t(\"login\") => t('Merchants.login')\n */\n code = code.replace(/\\Wt\\(['\"](.+?)['\"][),]/gm, (match, p1) => {\n // 如果 当前 有 $b. 则不替换\n if (/\\S\\.\\S/.test(p1)) {\n return match;\n }\n hasChanged = true;\n return match.replace(p1, `${namespace}.${p1}`);\n });\n\n /**\n * 第二个方法已经满足这种情况了,先注释掉\n * replace case:\n * t('login',{ id:'1' }) => t('Merchants.login',{ id:'1' })\n * t(\"login\",{ id:'1' }) => t('Merchants.login',{ id:'1' })\n */\n // code = code.replace(/\\Wt\\(([\"'])(.+?)\\1(,|.*\\))/gm, (match, p1, p2, p3) => {\n // // 如果 当前 有 $b. 则不替换\n // if (/\\S\\.\\S/.test(p2)) {\n // return match;\n // }\n // hasChanged = true;\n // return `t('${namespace}.${p2}'${p3}`;\n // });\n\n if (hasChanged) {\n return code;\n }\n return \"\";\n}\n"],"mappings":"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","names":["namespace","namespace"]}
|
package/dist/normalizeConfig.js
CHANGED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveSheetData
|
|
3
|
+
} from "./chunk-IKJLPHF7.js";
|
|
4
|
+
import {
|
|
5
|
+
googleSheet,
|
|
6
|
+
letterToNumber
|
|
7
|
+
} from "./chunk-6UFZ6KLX.js";
|
|
8
|
+
import "./chunk-KNC7XY4Z.js";
|
|
9
|
+
import {
|
|
10
|
+
I18nData,
|
|
11
|
+
sleep
|
|
12
|
+
} from "./chunk-ADQ6JLT6.js";
|
|
13
|
+
import {
|
|
14
|
+
promptI18nConfigEnable
|
|
15
|
+
} from "./chunk-2SEEW5WZ.js";
|
|
16
|
+
import {
|
|
17
|
+
getConfig
|
|
18
|
+
} from "./chunk-2DSIJDNZ.js";
|
|
19
|
+
import "./chunk-555YTWSW.js";
|
|
20
|
+
import {
|
|
21
|
+
createLogger
|
|
22
|
+
} from "./chunk-UGSBKD2I.js";
|
|
23
|
+
|
|
24
|
+
// src/commands/upload.ts
|
|
25
|
+
import _ from "lodash";
|
|
26
|
+
import pMap from "p-map";
|
|
27
|
+
var log = createLogger("upload");
|
|
28
|
+
async function batchUpdateKeys(config) {
|
|
29
|
+
let sheetData = await resolveSheetData(config);
|
|
30
|
+
const allKeys = [];
|
|
31
|
+
const i18nDataMap = /* @__PURE__ */ new Map();
|
|
32
|
+
await pMap(config.locales ?? [], async (locale) => {
|
|
33
|
+
const i18nData = new I18nData(locale, config);
|
|
34
|
+
i18nDataMap.set(locale, i18nData);
|
|
35
|
+
const data = await i18nData.loadData();
|
|
36
|
+
allKeys.push(...Object.keys(data));
|
|
37
|
+
});
|
|
38
|
+
let needSyncKeys = Array.from(new Set(allKeys)).filter((key) => {
|
|
39
|
+
return !sheetData.keySet.has(key);
|
|
40
|
+
});
|
|
41
|
+
needSyncKeys = _.sortBy(needSyncKeys);
|
|
42
|
+
if (needSyncKeys.length) {
|
|
43
|
+
log.info(`\u5373\u5C06\u540C\u6B65\u672C\u5730\u65B0\u589E\u52A0 ${needSyncKeys.length} \u4E2A i18nKey \u5230\u4E91\u7AEF`);
|
|
44
|
+
await googleSheet.updateColumn(
|
|
45
|
+
config.sheetId,
|
|
46
|
+
config.sheetRange,
|
|
47
|
+
letterToNumber(config.position.key),
|
|
48
|
+
sheetData.nextAppendRowIndex,
|
|
49
|
+
needSyncKeys
|
|
50
|
+
);
|
|
51
|
+
log.info("\u540C\u6B65\u65B0\u589E\u52A0i18nKey\u6210\u529F");
|
|
52
|
+
for (const lang of config.locales) {
|
|
53
|
+
const langFile = i18nDataMap.get(lang);
|
|
54
|
+
const needSyncValues = [];
|
|
55
|
+
needSyncKeys.forEach((k) => {
|
|
56
|
+
if (langFile) {
|
|
57
|
+
needSyncValues.push(langFile.data[k]);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
log.info(
|
|
61
|
+
`\u5373\u5C06\u540C\u6B65\u672C\u5730 ${lang} \u65B0\u589E\u52A0 ${needSyncValues.length} \u4E2A\u503C\u5230\u4E91\u7AEF`
|
|
62
|
+
);
|
|
63
|
+
await googleSheet.updateColumn(
|
|
64
|
+
config.sheetId,
|
|
65
|
+
config.sheetRange,
|
|
66
|
+
letterToNumber(config.position[lang]),
|
|
67
|
+
sheetData.nextAppendRowIndex,
|
|
68
|
+
needSyncValues
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
await sleep(1e3);
|
|
72
|
+
sheetData = await resolveSheetData(config);
|
|
73
|
+
log.info(`\u5DF2\u91CD\u65B0\u83B7\u53D6 ${config.sheetRange} \u7684\u6570\u636E`);
|
|
74
|
+
}
|
|
75
|
+
return { sheetData, i18nDataMap };
|
|
76
|
+
}
|
|
77
|
+
async function upload() {
|
|
78
|
+
const config = await getConfig();
|
|
79
|
+
let i18nConfigs = await promptI18nConfigEnable(config.i18n);
|
|
80
|
+
for (const configItem of i18nConfigs) {
|
|
81
|
+
const { sheetData, i18nDataMap } = await batchUpdateKeys(configItem);
|
|
82
|
+
await pMap(configItem.locales ?? [], async (locale) => {
|
|
83
|
+
const i18nData = i18nDataMap.get(locale);
|
|
84
|
+
await i18nData.trySaveToGoogle(sheetData);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
log.info("\u4E0A\u4F20\u6210\u529F");
|
|
88
|
+
}
|
|
89
|
+
export {
|
|
90
|
+
upload
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=upload-OUXQZAW4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/upload.ts"],"sourcesContent":["import _ from \"lodash\";\nimport pMap from \"p-map\";\nimport { createLogger } from \"../shared\";\nimport { getConfig, I18nConfig } from \"../shared/config\";\nimport { googleSheet } from \"../shared/google/sheet\";\nimport { I18nData } from \"../shared/i18nData\";\nimport { letterToNumber } from \"../shared/letters\";\nimport { promptI18nConfigEnable } from \"../shared/promptConfigEnable\";\nimport { resolveSheetData } from \"../shared/resolveSheetData\";\nimport { sleep } from \"../shared/sleep\";\n\nconst log = createLogger(\"upload\");\n\n/**\n * 检测有本地有新增的key 则将新增的key更新到云端\n * 无则跳过\n */\nasync function batchUpdateKeys(config: I18nConfig) {\n let sheetData = await resolveSheetData(config);\n\n const allKeys: string[] = [];\n const i18nDataMap = new Map<string, I18nData>();\n await pMap(config.locales ?? [], async (locale) => {\n const i18nData = new I18nData(locale, config);\n i18nDataMap.set(locale, i18nData);\n const data = await i18nData.loadData();\n allKeys.push(...Object.keys(data));\n });\n\n let needSyncKeys = Array.from(new Set(allKeys)).filter((key) => {\n // 本地有新的key 服务器没有\n return !sheetData.keySet.has(key);\n });\n needSyncKeys = _.sortBy(needSyncKeys);\n\n if (needSyncKeys.length) {\n log.info(`即将同步本地新增加 ${needSyncKeys.length} 个 i18nKey 到云端`);\n await googleSheet.updateColumn(\n config.sheetId!,\n config.sheetRange!,\n letterToNumber(config.position!.key),\n sheetData.nextAppendRowIndex,\n needSyncKeys\n );\n log.info(\"同步新增加i18nKey成功\");\n\n // 批量同步新增的key的values到云端\n for (const lang of config.locales!) {\n const langFile = i18nDataMap.get(lang);\n const needSyncValues: string[] = [];\n needSyncKeys.forEach((k) => {\n if (langFile) {\n needSyncValues.push(langFile.data[k]);\n }\n });\n log.info(\n `即将同步本地 ${lang} 新增加 ${needSyncValues.length} 个值到云端`\n );\n await googleSheet.updateColumn(\n config.sheetId!,\n config.sheetRange!,\n letterToNumber(config.position![lang]),\n sheetData.nextAppendRowIndex,\n needSyncValues\n );\n }\n\n await sleep(1000);\n sheetData = await resolveSheetData(config);\n log.info(`已重新获取 ${config.sheetRange} 的数据`);\n }\n\n return { sheetData, i18nDataMap };\n}\n\nexport async function upload() {\n const config = await getConfig();\n let i18nConfigs = await promptI18nConfigEnable(config.i18n);\n\n for (const configItem of i18nConfigs) {\n const { sheetData, i18nDataMap } = await batchUpdateKeys(configItem);\n await pMap(configItem.locales ?? [], async (locale) => {\n const i18nData = i18nDataMap.get(locale)!;\n await i18nData.trySaveToGoogle(sheetData);\n });\n }\n\n log.info(\"上传成功\");\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,OAAO;AACd,OAAO,UAAU;AAUjB,IAAM,MAAM,aAAa,QAAQ;AAMjC,eAAe,gBAAgB,QAAoB;AACjD,MAAI,YAAY,MAAM,iBAAiB,MAAM;AAE7C,QAAM,UAAoB,CAAC;AAC3B,QAAM,cAAc,oBAAI,IAAsB;AAC9C,QAAM,KAAK,OAAO,WAAW,CAAC,GAAG,OAAO,WAAW;AACjD,UAAM,WAAW,IAAI,SAAS,QAAQ,MAAM;AAC5C,gBAAY,IAAI,QAAQ,QAAQ;AAChC,UAAM,OAAO,MAAM,SAAS,SAAS;AACrC,YAAQ,KAAK,GAAG,OAAO,KAAK,IAAI,CAAC;AAAA,EACnC,CAAC;AAED,MAAI,eAAe,MAAM,KAAK,IAAI,IAAI,OAAO,CAAC,EAAE,OAAO,CAAC,QAAQ;AAE9D,WAAO,CAAC,UAAU,OAAO,IAAI,GAAG;AAAA,EAClC,CAAC;AACD,iBAAe,EAAE,OAAO,YAAY;AAEpC,MAAI,aAAa,QAAQ;AACvB,QAAI,KAAK,0DAAa,aAAa,MAAM,oCAAgB;AACzD,UAAM,YAAY;AAAA,MAChB,OAAO;AAAA,MACP,OAAO;AAAA,MACP,eAAe,OAAO,SAAU,GAAG;AAAA,MACnC,UAAU;AAAA,MACV;AAAA,IACF;AACA,QAAI,KAAK,mDAAgB;AAGzB,eAAW,QAAQ,OAAO,SAAU;AAClC,YAAM,WAAW,YAAY,IAAI,IAAI;AACrC,YAAM,iBAA2B,CAAC;AAClC,mBAAa,QAAQ,CAAC,MAAM;AAC1B,YAAI,UAAU;AACZ,yBAAe,KAAK,SAAS,KAAK,CAAC,CAAC;AAAA,QACtC;AAAA,MACF,CAAC;AACD,UAAI;AAAA,QACF,wCAAU,IAAI,uBAAQ,eAAe,MAAM;AAAA,MAC7C;AACA,YAAM,YAAY;AAAA,QAChB,OAAO;AAAA,QACP,OAAO;AAAA,QACP,eAAe,OAAO,SAAU,IAAI,CAAC;AAAA,QACrC,UAAU;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAEA,UAAM,MAAM,GAAI;AAChB,gBAAY,MAAM,iBAAiB,MAAM;AACzC,QAAI,KAAK,kCAAS,OAAO,UAAU,qBAAM;AAAA,EAC3C;AAEA,SAAO,EAAE,WAAW,YAAY;AAClC;AAEA,eAAsB,SAAS;AAC7B,QAAM,SAAS,MAAM,UAAU;AAC/B,MAAI,cAAc,MAAM,uBAAuB,OAAO,IAAI;AAE1D,aAAW,cAAc,aAAa;AACpC,UAAM,EAAE,WAAW,YAAY,IAAI,MAAM,gBAAgB,UAAU;AACnE,UAAM,KAAK,WAAW,WAAW,CAAC,GAAG,OAAO,WAAW;AACrD,YAAM,WAAW,YAAY,IAAI,MAAM;AACvC,YAAM,SAAS,gBAAgB,SAAS;AAAA,IAC1C,CAAC;AAAA,EACH;AAEA,MAAI,KAAK,0BAAM;AACjB;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dune2/cli",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/liaoyinglong/next-tools.git",
|
|
@@ -32,7 +32,6 @@
|
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@apidevtools/swagger-parser": "^10.1.0",
|
|
35
|
-
"axios": "^1.6.2",
|
|
36
35
|
"cac": "^6.7.14",
|
|
37
36
|
"cli-table3": "^0.6.3",
|
|
38
37
|
"connect": "^3.7.0",
|
|
@@ -40,13 +39,13 @@
|
|
|
40
39
|
"enquirer": "^2.3.6",
|
|
41
40
|
"fs-extra": "^11.2.0",
|
|
42
41
|
"globby": "^14.0.1",
|
|
43
|
-
"googleapis": "
|
|
42
|
+
"googleapis": "108.0.0",
|
|
44
43
|
"joycon": "^3.1.1",
|
|
45
|
-
"json-schema-to-typescript": "
|
|
44
|
+
"json-schema-to-typescript": "15.0.0",
|
|
46
45
|
"lodash": "^4.17.21",
|
|
47
46
|
"open": "^10.1.0",
|
|
48
47
|
"p-map": "^7.0.2",
|
|
49
|
-
"path-to-regexp": "
|
|
48
|
+
"path-to-regexp": "7.1.0",
|
|
50
49
|
"picocolors": "^1.0.0",
|
|
51
50
|
"@dune2/wasm": "0.4.0"
|
|
52
51
|
},
|