@dune2/cli 1.0.0 → 1.0.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/chunk-ENF3KHSQ.js +19 -0
- package/dist/chunk-ENF3KHSQ.js.map +1 -0
- package/dist/chunk-OZFFB6QC.js +27 -0
- package/dist/chunk-OZFFB6QC.js.map +1 -0
- package/dist/{chunk-YZLVO3MA.js → chunk-XGRSH7MZ.js} +2 -2
- package/dist/cli.js +6 -6
- package/dist/cli.js.map +1 -1
- package/dist/{generateApi-S77LKSZT.js → generateApi-6GDO7LS5.js} +21 -16
- package/dist/generateApi-6GDO7LS5.js.map +1 -0
- package/dist/index.d.ts +3 -5
- package/dist/index.js +14 -7
- package/dist/index.js.map +1 -1
- package/dist/{initConfig-NHHN2HCE.js → initConfig-JLWK42R5.js} +4 -4
- package/dist/{interactive-BVOA3VKY.js → interactive-VUY3CMIF.js} +2 -2
- package/dist/normalizeConfig.d.ts +1 -1
- package/dist/normalizeConfig.js +1 -1
- package/dist/prettier.cjs +2 -3
- package/dist/prettier.cjs.map +1 -1
- package/dist/prettier.js +1 -2
- package/dist/prettier.js.map +1 -1
- package/dist/{types-CqBxoc6L.d.ts → types-BzjIgVkF.d.ts} +1 -66
- package/package.json +4 -8
- package/readme.md +49 -17
- package/dist/chunk-DORNSRHQ.js +0 -36
- package/dist/chunk-DORNSRHQ.js.map +0 -1
- package/dist/chunk-VS4LDXR3.js +0 -85
- package/dist/chunk-VS4LDXR3.js.map +0 -1
- package/dist/generateApi-S77LKSZT.js.map +0 -1
- /package/dist/{chunk-YZLVO3MA.js.map → chunk-XGRSH7MZ.js.map} +0 -0
- /package/dist/{initConfig-NHHN2HCE.js.map → initConfig-JLWK42R5.js.map} +0 -0
- /package/dist/{interactive-BVOA3VKY.js.map → interactive-VUY3CMIF.js.map} +0 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// src/shared/index.ts
|
|
2
|
+
import cac from "cac";
|
|
3
|
+
import debug from "debug";
|
|
4
|
+
var cli = cac("dune");
|
|
5
|
+
var createLogger = (name) => {
|
|
6
|
+
const info = debug(`${cli.name}:${name}`);
|
|
7
|
+
return {
|
|
8
|
+
...info,
|
|
9
|
+
info,
|
|
10
|
+
error: info.extend("error")
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
debug.enable(`${cli.name}:*`);
|
|
14
|
+
|
|
15
|
+
export {
|
|
16
|
+
cli,
|
|
17
|
+
createLogger
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=chunk-ENF3KHSQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shared/index.ts"],"sourcesContent":["import cac from \"cac\";\nimport debug from \"debug\";\n\nexport const cli = cac(\"dune\");\n\nexport const createLogger = (name: string) => {\n const info = debug(`${cli.name}:${name}`);\n return {\n ...info,\n info,\n error: info.extend(\"error\"),\n };\n};\n\ndebug.enable(`${cli.name}:*`);\n"],"mappings":";AAAA,OAAO,SAAS;AAChB,OAAO,WAAW;AAEX,IAAM,MAAM,IAAI,MAAM;AAEtB,IAAM,eAAe,CAAC,SAAiB;AAC5C,QAAM,OAAO,MAAM,GAAG,IAAI,IAAI,IAAI,IAAI,EAAE;AACxC,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA,OAAO,KAAK,OAAO,OAAO;AAAA,EAC5B;AACF;AAEA,MAAM,OAAO,GAAG,IAAI,IAAI,IAAI;","names":[]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// src/shared/config/normalizeConfig.ts
|
|
2
|
+
import path from "path";
|
|
3
|
+
function normalizeConfig(config) {
|
|
4
|
+
config.cwd ??= process.cwd();
|
|
5
|
+
config.cacheDir ??= path.join(config.cwd, "node_modules/.cache/dune-cli");
|
|
6
|
+
config.api ??= [];
|
|
7
|
+
config.api = config.api.map(apiConfigNormalizer);
|
|
8
|
+
return config;
|
|
9
|
+
}
|
|
10
|
+
function apiConfigNormalizer(item) {
|
|
11
|
+
item.output ??= "./src/apis";
|
|
12
|
+
item.RequestBuilderImportPath ??= `import { RequestBuilder } from '@dune2/tools/rq';`;
|
|
13
|
+
item.enableTs ??= true;
|
|
14
|
+
item.enabled ??= true;
|
|
15
|
+
item.format ??= true;
|
|
16
|
+
item.responseSchemaTransformer ??= (schema) => {
|
|
17
|
+
var _a;
|
|
18
|
+
return ((_a = schema.properties) == null ? void 0 : _a.data) ?? schema;
|
|
19
|
+
};
|
|
20
|
+
return item;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export {
|
|
24
|
+
normalizeConfig,
|
|
25
|
+
apiConfigNormalizer
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=chunk-OZFFB6QC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shared/config/normalizeConfig.ts"],"sourcesContent":["import path from \"path\";\nimport { ApiConfig, Config } from \"./types\";\nexport function normalizeConfig(config: Config): Config {\n config.cwd ??= process.cwd();\n config.cacheDir ??= path.join(config.cwd, \"node_modules/.cache/dune-cli\");\n\n //#region api 配置标准化\n config.api ??= [];\n config.api = config.api.map(apiConfigNormalizer);\n //#endregion\n return config;\n}\nexport function apiConfigNormalizer(item: ApiConfig) {\n item.output ??= \"./src/apis\";\n item.RequestBuilderImportPath ??= `import { RequestBuilder } from '@dune2/tools/rq';`;\n item.enableTs ??= true;\n item.enabled ??= true;\n item.format ??= true;\n item.responseSchemaTransformer ??= (schema) =>\n schema.properties?.data ?? schema;\n return item;\n}\n"],"mappings":";AAAA,OAAO,UAAU;AAEV,SAAS,gBAAgB,QAAwB;AACtD,SAAO,QAAQ,QAAQ,IAAI;AAC3B,SAAO,aAAa,KAAK,KAAK,OAAO,KAAK,8BAA8B;AAGxE,SAAO,QAAQ,CAAC;AAChB,SAAO,MAAM,OAAO,IAAI,IAAI,mBAAmB;AAE/C,SAAO;AACT;AACO,SAAS,oBAAoB,MAAiB;AACnD,OAAK,WAAW;AAChB,OAAK,6BAA6B;AAClC,OAAK,aAAa;AAClB,OAAK,YAAY;AACjB,OAAK,WAAW;AAChB,OAAK,8BAA8B,CAAC,WAAQ;AAlB9C;AAmBI,yBAAO,eAAP,mBAAmB,SAAQ;AAAA;AAC7B,SAAO;AACT;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
normalizeConfig
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-OZFFB6QC.js";
|
|
4
4
|
|
|
5
5
|
// src/shared/config/index.ts
|
|
6
6
|
import { createJiti } from "jiti";
|
|
@@ -25,4 +25,4 @@ export {
|
|
|
25
25
|
configName,
|
|
26
26
|
getConfig
|
|
27
27
|
};
|
|
28
|
-
//# sourceMappingURL=chunk-
|
|
28
|
+
//# sourceMappingURL=chunk-XGRSH7MZ.js.map
|
package/dist/cli.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
cli
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ENF3KHSQ.js";
|
|
5
5
|
|
|
6
6
|
// package.json
|
|
7
|
-
var version = "0.
|
|
7
|
+
var version = "1.0.1";
|
|
8
8
|
|
|
9
9
|
// src/cli.ts
|
|
10
10
|
cli.command("generateApi", "\u751F\u6210 api \u6587\u4EF6").example("dune generateApi").action(async () => {
|
|
11
|
-
const { generateApi } = await import("./generateApi-
|
|
11
|
+
const { generateApi } = await import("./generateApi-6GDO7LS5.js");
|
|
12
12
|
await generateApi();
|
|
13
13
|
});
|
|
14
14
|
cli.command("init", "\u521D\u59CB\u5316\u914D\u7F6E\u6587\u4EF6").example("dune init").action(async () => {
|
|
15
|
-
const { initConfig } = await import("./initConfig-
|
|
15
|
+
const { initConfig } = await import("./initConfig-JLWK42R5.js");
|
|
16
16
|
await initConfig();
|
|
17
17
|
});
|
|
18
18
|
cli.command("interactive", "\u4EA4\u4E92\u5F0F\u64CD\u4F5C").example("dune interactive").alias("i").action(async (args) => {
|
|
19
|
-
const { interactive } = await import("./interactive-
|
|
19
|
+
const { interactive } = await import("./interactive-VUY3CMIF.js");
|
|
20
20
|
await interactive(args);
|
|
21
21
|
});
|
|
22
22
|
cli.command("").action(async (args) => {
|
|
23
|
-
const { interactive } = await import("./interactive-
|
|
23
|
+
const { interactive } = await import("./interactive-VUY3CMIF.js");
|
|
24
24
|
await interactive(args);
|
|
25
25
|
});
|
|
26
26
|
cli.version(version);
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../package.json","../src/cli.ts"],"sourcesContent":["{\n \"name\": \"@dune2/cli\",\n \"version\": \"0.
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/cli.ts"],"sourcesContent":["{\n \"name\": \"@dune2/cli\",\n \"version\": \"1.0.1\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/liaoyinglong/next-tools.git\",\n \"directory\": \"packages/cli\"\n },\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"import\": \"./dist/index.js\"\n },\n \"./cli\": {\n \"import\": \"./dist/cli.js\"\n },\n \"./normalizeConfig\": {\n \"import\": \"./dist/normalizeConfig.js\"\n },\n \"./prettier\": {\n \"import\": \"./dist/prettier.js\",\n \"require\": \"./dist/prettier.cjs\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"types\": \"dist/index.d.ts\",\n \"bin\": {\n \"dune\": \"./dist/cli.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"shx rm -rf ./dist && tsup --splitting\",\n \"dev\": \"pnpm run build --watch\",\n \"lint\": \"tsc --diagnostics --noEmit\",\n \"test\": \"vitest run\",\n \"test:u\": \"vitest -u\"\n },\n \"dependencies\": {\n \"@apidevtools/swagger-parser\": \"^12\",\n \"cac\": \"^6.7.14\",\n \"debug\": \"^4.3.4\",\n \"enquirer\": \"^2.3.6\",\n \"es-toolkit\": \"^1\",\n \"fs-extra\": \"^11.2.0\",\n \"jiti\": \"^2.4.2\",\n \"json-schema-to-typescript\": \"15.0.0\",\n \"p-map\": \"^7.0.2\"\n },\n \"devDependencies\": {\n \"@types/debug\": \"^4.1.7\",\n \"openapi-types\": \"^12.0.2\",\n \"prettier\": \"^3\",\n \"tsup\": \"8\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n }\n}\n","#!/usr/bin/env node\nimport { version } from \"../package.json\";\nimport { cli } from \"./shared\";\n\n//#region api 相关\ncli\n .command(\"generateApi\", \"生成 api 文件\")\n .example(\"dune generateApi\")\n .action(async () => {\n const { generateApi } = await import(\"./commands/generateApi\");\n await generateApi();\n });\n//#endregion\n\ncli\n .command(\"init\", \"初始化配置文件\")\n .example(\"dune init\")\n .action(async () => {\n const { initConfig } = await import(\"./commands/initConfig\");\n await initConfig();\n });\n\ncli\n .command(\"interactive\", \"交互式操作\")\n .example(\"dune interactive\")\n .alias(\"i\")\n .action(async (args) => {\n const { interactive } = await import(\"./commands/interactive\");\n await interactive(args);\n });\n\n// make default command run interactive\ncli.command(\"\").action(async (args) => {\n const { interactive } = await import(\"./commands/interactive\");\n await interactive(args);\n});\n\ncli.version(version);\ncli.help();\n\n(async () => {\n try {\n // Parse CLI args without running the command\n cli.parse(process.argv, { run: false });\n // Run the command yourself\n // You only need `await` when your command action returns a Promise\n await cli.runMatchedCommand();\n } catch (error) {\n // Handle error here..\n // e.g.\n // console.error(error.stack)\n // process.exit(1)\n }\n})();\n"],"mappings":";;;;;;AAEE,cAAW;;;ACGb,IACG,QAAQ,eAAe,+BAAW,EAClC,QAAQ,kBAAkB,EAC1B,OAAO,YAAY;AAClB,QAAM,EAAE,YAAY,IAAI,MAAM,OAAO,2BAAwB;AAC7D,QAAM,YAAY;AACpB,CAAC;AAGH,IACG,QAAQ,QAAQ,4CAAS,EACzB,QAAQ,WAAW,EACnB,OAAO,YAAY;AAClB,QAAM,EAAE,WAAW,IAAI,MAAM,OAAO,0BAAuB;AAC3D,QAAM,WAAW;AACnB,CAAC;AAEH,IACG,QAAQ,eAAe,gCAAO,EAC9B,QAAQ,kBAAkB,EAC1B,MAAM,GAAG,EACT,OAAO,OAAO,SAAS;AACtB,QAAM,EAAE,YAAY,IAAI,MAAM,OAAO,2BAAwB;AAC7D,QAAM,YAAY,IAAI;AACxB,CAAC;AAGH,IAAI,QAAQ,EAAE,EAAE,OAAO,OAAO,SAAS;AACrC,QAAM,EAAE,YAAY,IAAI,MAAM,OAAO,2BAAwB;AAC7D,QAAM,YAAY,IAAI;AACxB,CAAC;AAED,IAAI,QAAQ,OAAO;AACnB,IAAI,KAAK;AAAA,CAER,YAAY;AACX,MAAI;AAEF,QAAI,MAAM,QAAQ,MAAM,EAAE,KAAK,MAAM,CAAC;AAGtC,UAAM,IAAI,kBAAkB;AAAA,EAC9B,SAAS,OAAO;AAAA,EAKhB;AACF,GAAG;","names":[]}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getConfig
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-XGRSH7MZ.js";
|
|
4
|
+
import "./chunk-OZFFB6QC.js";
|
|
5
5
|
import {
|
|
6
6
|
createLogger
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-ENF3KHSQ.js";
|
|
8
8
|
|
|
9
9
|
// src/commands/generateApi/index.ts
|
|
10
10
|
import SwaggerParser from "@apidevtools/swagger-parser";
|
|
11
|
+
import { camelCase, cloneDeep, merge } from "es-toolkit";
|
|
11
12
|
import fs from "fs-extra";
|
|
12
13
|
import { compile } from "json-schema-to-typescript";
|
|
13
|
-
import _ from "lodash";
|
|
14
14
|
import * as os from "os";
|
|
15
15
|
import pMap from "p-map";
|
|
16
16
|
import path from "path";
|
|
@@ -90,7 +90,7 @@ async function generateApi() {
|
|
|
90
90
|
}
|
|
91
91
|
for (const apiConfig of apiConfigs) {
|
|
92
92
|
log2.info("\u5F00\u59CB\u89E3\u6790 %s", apiConfig.swaggerJSONPath);
|
|
93
|
-
const dereferenceConfig =
|
|
93
|
+
const dereferenceConfig = merge(
|
|
94
94
|
{
|
|
95
95
|
resolve: {
|
|
96
96
|
http: {
|
|
@@ -98,7 +98,7 @@ async function generateApi() {
|
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
},
|
|
101
|
-
apiConfig.dereferenceSwaggerConfig
|
|
101
|
+
apiConfig.dereferenceSwaggerConfig || {}
|
|
102
102
|
);
|
|
103
103
|
const parsed = await SwaggerParser.dereference(
|
|
104
104
|
apiConfig.swaggerJSONPath,
|
|
@@ -149,7 +149,7 @@ async function generateApiRequestCode(options) {
|
|
|
149
149
|
return options.url;
|
|
150
150
|
})();
|
|
151
151
|
const seeUrl = apiConfig.swaggerUiUrl ? `${apiConfig.swaggerUiUrl}#/${((_a = operationObject.tags) == null ? void 0 : _a.join("/")) ?? ""}/${operationObject.operationId}` : "";
|
|
152
|
-
let requestBuilderName =
|
|
152
|
+
let requestBuilderName = camelCase(`${options.url}_${method}_api`);
|
|
153
153
|
if (!/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(requestBuilderName)) {
|
|
154
154
|
requestBuilderName = `_${requestBuilderName}`;
|
|
155
155
|
}
|
|
@@ -192,7 +192,7 @@ export namespace ${requestBuilderName} {
|
|
|
192
192
|
|
|
193
193
|
${responseParamsTypeCode}
|
|
194
194
|
};`);
|
|
195
|
-
if (isGenerateFieldsMap &&
|
|
195
|
+
if (isGenerateFieldsMap && Object.keys(requestParamsTypeCode.fieldsMap).length > 0) {
|
|
196
196
|
code.push(`
|
|
197
197
|
export const ${requestBuilderName}FieldsMap = ${JSON.stringify(
|
|
198
198
|
requestParamsTypeCode.fieldsMap
|
|
@@ -206,6 +206,7 @@ function getUrlPathParams(parameters) {
|
|
|
206
206
|
return parameters.filter((item) => item.in === "path").map((item) => item.name);
|
|
207
207
|
}
|
|
208
208
|
async function compileRequestParams(operationObject, generateFieldsMap = false) {
|
|
209
|
+
var _a, _b;
|
|
209
210
|
let schema;
|
|
210
211
|
if (operationObject.requestBody) {
|
|
211
212
|
schema = operationObject.requestBody.content["application/json"].schema;
|
|
@@ -217,8 +218,11 @@ async function compileRequestParams(operationObject, generateFieldsMap = false)
|
|
|
217
218
|
if (!["query", "path"].includes(item.in)) {
|
|
218
219
|
return;
|
|
219
220
|
}
|
|
220
|
-
if (
|
|
221
|
-
|
|
221
|
+
if (item.schema && "type" in item.schema && item.schema.type === "object") {
|
|
222
|
+
Object.assign(
|
|
223
|
+
extraProperties,
|
|
224
|
+
item.schema.properties || {}
|
|
225
|
+
);
|
|
222
226
|
} else {
|
|
223
227
|
parameters.push(item);
|
|
224
228
|
}
|
|
@@ -258,11 +262,11 @@ async function compileRequestParams(operationObject, generateFieldsMap = false)
|
|
|
258
262
|
});
|
|
259
263
|
const isPageSearchRequest = (data) => {
|
|
260
264
|
const keys = ["pageNum", "pageSize", "count"];
|
|
261
|
-
return
|
|
265
|
+
return data.type === "object" && (data.required || []).filter((item) => keys.includes(item)).length === keys.length;
|
|
262
266
|
};
|
|
263
267
|
if (generateFieldsMap) {
|
|
264
|
-
const params = isPageSearchRequest(schema) ?
|
|
265
|
-
|
|
268
|
+
const params = isPageSearchRequest(schema) ? ((_b = (_a = schema.properties) == null ? void 0 : _a.params) == null ? void 0 : _b.properties) || {} : schema.properties;
|
|
269
|
+
Object.keys(params || {}).forEach((field) => {
|
|
266
270
|
fieldsMap[field] = field;
|
|
267
271
|
});
|
|
268
272
|
}
|
|
@@ -286,7 +290,7 @@ async function compileResponseParams(operationObject, apiConfig) {
|
|
|
286
290
|
const schema = temp2.schema;
|
|
287
291
|
let data = apiConfig.responseSchemaTransformer(schema);
|
|
288
292
|
if (data) {
|
|
289
|
-
data =
|
|
293
|
+
data = cloneDeep(data);
|
|
290
294
|
markCircularToRef(data);
|
|
291
295
|
try {
|
|
292
296
|
code = await compile(data, "Res", {
|
|
@@ -296,7 +300,8 @@ async function compileResponseParams(operationObject, apiConfig) {
|
|
|
296
300
|
// format: false,
|
|
297
301
|
});
|
|
298
302
|
const isPageSearchResponse = (data2) => {
|
|
299
|
-
|
|
303
|
+
var _a, _b;
|
|
304
|
+
return data2.type === "object" && ((_b = (_a = data2.properties) == null ? void 0 : _a.result) == null ? void 0 : _b.type) === "array";
|
|
300
305
|
};
|
|
301
306
|
if (isPageSearchResponse(data)) {
|
|
302
307
|
code += `${os.EOL}export type ResultItem = Res['result'][0]`;
|
|
@@ -336,4 +341,4 @@ export {
|
|
|
336
341
|
generateApiRequestCode,
|
|
337
342
|
markCircularToRef
|
|
338
343
|
};
|
|
339
|
-
//# sourceMappingURL=generateApi-
|
|
344
|
+
//# sourceMappingURL=generateApi-6GDO7LS5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/generateApi/index.ts","../src/shared/formatFile.ts","../src/shared/promptConfigEnable.ts"],"sourcesContent":["import SwaggerParser from \"@apidevtools/swagger-parser\";\nimport { camelCase, cloneDeep, merge } from \"es-toolkit\";\nimport fs from \"fs-extra\";\nimport { compile } from \"json-schema-to-typescript\";\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 dereferenceConfig = merge(\n {\n resolve: {\n http: {\n timeout: 30 * 1000,\n },\n },\n },\n apiConfig.dereferenceSwaggerConfig || {},\n );\n const parsed = (await SwaggerParser.dereference(\n apiConfig.swaggerJSONPath,\n dereferenceConfig,\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 \"// do not edit this file manually, it will be overwritten by @dune2/cli\",\n apiConfig.RequestBuilderImportPath!,\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 ${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 isGenerateFieldsMap = [\"post\", \"put\"].includes(method);\n // 请求参数类型\n // 响应参数类型\n const [requestParamsTypeCode, responseParamsTypeCode] = await Promise.all([\n compileRequestParams(operationObject, isGenerateFieldsMap),\n compileResponseParams(operationObject, apiConfig),\n ]);\n\n code.push(`\nexport namespace ${requestBuilderName} {\n ${requestParamsTypeCode.code}\n \n ${responseParamsTypeCode}\n};`);\n\n if (\n isGenerateFieldsMap &&\n Object.keys(requestParamsTypeCode.fieldsMap).length > 0\n ) {\n // 生成表单 fieldsMap\n code.push(`\nexport const ${requestBuilderName}FieldsMap = ${JSON.stringify(\n requestParamsTypeCode.fieldsMap,\n )} as const\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 (\n item.schema &&\n \"type\" in item.schema &&\n item.schema.type === \"object\"\n ) {\n // swagger get 请求上 有些参数是 object 类型 应该拍平\n Object.assign(\n extraProperties,\n (item.schema as OpenAPIV3.SchemaObject).properties || {},\n );\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 data.type === \"object\" &&\n (data.required || []).filter((item) => keys.includes(item)).length ===\n keys.length\n );\n };\n\n if (generateFieldsMap) {\n // 分页查询接口取 params 字段\n const params = isPageSearchRequest(schema)\n ? schema.properties?.params?.properties || {}\n : schema.properties;\n Object.keys(params || {}).forEach((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 data.type === \"object\" && 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 if (obj && typeof obj === \"object\") {\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 }\n return map;\n}\n","import { createLogger } from \".\";\nimport * as child_process from \"child_process\";\n\nconst log = createLogger(\"formatFile\");\n\nexport function formatFile(filename: string) {\n // 格式化代码\n log.info(`尝试格式化代码: %s`, filename);\n child_process.exec(`prettier --write '${filename}'`, (error) => {\n if (error) {\n log.error(`格式化代码失败: ${error}`);\n log.error(`请手动执行: prettier --write ${filename}`);\n log.error(`或者在配置文件中关闭格式化功能`);\n } else {\n log.info(`格式化代码成功: %s`, filename);\n }\n });\n}\n","import enquirer from \"enquirer\";\nimport { ApiConfig } from \"./config\";\nconst { prompt } = enquirer;\n\ninterface Opt<T> {\n configArr: (T & { enabled?: boolean })[];\n getChoiceItem: (item: T) => {\n name: string;\n message?: string;\n value?: string;\n hint?: string;\n };\n checkIsEnabled: (enabledArr: string[], item: T) => boolean;\n}\n\nexport async function promptConfigEnable<T>(opt: Opt<T>) {\n const { configArr, getChoiceItem } = opt;\n // 只有一条配置的时候不用选择\n if (configArr.length <= 1) {\n return configArr;\n }\n\n const choices = [\n {\n name: \"全部\",\n message: \"全部\",\n choices: configArr.map((item) => {\n return getChoiceItem(item);\n }),\n },\n ];\n const res = await prompt<{ enabled: string[] }>({\n type: \"multiselect\",\n message: \"选择要生效的配置项\",\n // @ts-ignore\n hint: \"(空格选中,回车确认)\",\n name: \"enabled\",\n validate(value) {\n return value.length === 0 ? `至少选择一项` : true;\n },\n choices,\n });\n\n configArr.forEach((item) => {\n item.enabled = opt.checkIsEnabled(res.enabled, item);\n });\n\n return configArr.filter((c) => c.enabled);\n}\n\nexport function promptApiConfigEnable(configArr: ApiConfig[] | undefined) {\n return promptConfigEnable({\n configArr: configArr ?? [],\n getChoiceItem: (item) => {\n return {\n name: item.output!,\n hint: `swaggerJSONPath: ${item.swaggerJSONPath}`,\n };\n },\n checkIsEnabled: (enabledArr, item) => {\n return enabledArr.includes(item.output!);\n },\n });\n}\n"],"mappings":"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","names":["log","schema","data"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as Config } from './types-
|
|
2
|
-
export { A as ApiConfig
|
|
1
|
+
import { C as Config } from './types-BzjIgVkF.js';
|
|
2
|
+
export { A as ApiConfig } from './types-BzjIgVkF.js';
|
|
3
3
|
import '@apidevtools/swagger-parser';
|
|
4
4
|
import 'openapi-types';
|
|
5
5
|
|
|
@@ -38,6 +38,4 @@ declare function letterToNumber(letters: string | number): number;
|
|
|
38
38
|
*/
|
|
39
39
|
declare function numberToLetter(n: number): string;
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
export { Config, configName, defaultJsonSorter, defineConfig, getConfig, letterToNumber, numberToLetter, resolveSheetId };
|
|
41
|
+
export { Config, configName, defaultJsonSorter, defineConfig, getConfig, letterToNumber, numberToLetter };
|
package/dist/index.js
CHANGED
|
@@ -2,11 +2,19 @@ import {
|
|
|
2
2
|
configName,
|
|
3
3
|
defineConfig,
|
|
4
4
|
getConfig
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
} from "./chunk-XGRSH7MZ.js";
|
|
6
|
+
import "./chunk-OZFFB6QC.js";
|
|
7
|
+
|
|
8
|
+
// src/shared/defaultJsonSorter.ts
|
|
9
|
+
function defaultJsonSorter(obj) {
|
|
10
|
+
const keys = Object.keys(obj);
|
|
11
|
+
const sortedKeys = keys.sort();
|
|
12
|
+
const sortedObj = sortedKeys.reduce((acc, key) => {
|
|
13
|
+
acc[key] = obj[key];
|
|
14
|
+
return acc;
|
|
15
|
+
}, {});
|
|
16
|
+
return sortedObj;
|
|
17
|
+
}
|
|
10
18
|
|
|
11
19
|
// src/shared/letters.ts
|
|
12
20
|
function letterToNumber(letters) {
|
|
@@ -41,7 +49,6 @@ export {
|
|
|
41
49
|
defineConfig,
|
|
42
50
|
getConfig,
|
|
43
51
|
letterToNumber,
|
|
44
|
-
numberToLetter
|
|
45
|
-
resolveSheetId
|
|
52
|
+
numberToLetter
|
|
46
53
|
};
|
|
47
54
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shared/letters.ts"],"sourcesContent":["/**\n *\n * - input : A\n * output : 0\n * - input : Z\n * output : 25\n * - input : AA\n * output : 26\n * - input : a\n * output : 0\n */\nexport function letterToNumber(letters: string | number) {\n if (typeof letters === \"number\" || !Number.isNaN(+letters)) {\n return +letters;\n }\n\n let n = 0;\n letters = letters.toUpperCase();\n for (let p = 0; p < letters.length; p++) {\n n = letters[p].charCodeAt(0) - 64 + n * 26;\n }\n\n return Math.max(0, n - 1);\n}\n\n/**\n * fork from https://github.com/matthewmueller/number-to-letter\n */\nconst alphabet = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\nconst base = alphabet.length;\n/**\n * numberToLetter(0) // A\n * numberToLetter(25) // Z\n * numberToLetter(26) // AA\n * numberToLetter(51) // AZ\n * numberToLetter(52) // BA\n * numberToLetter(676) // ZA\n * numberToLetter(701) // ZZ\n * numberToLetter(702) // AAA\n */\nexport function numberToLetter(n: number) {\n const digits: number[] = [];\n\n do {\n const v = n % base;\n digits.push(v);\n n = Math.floor(n / base);\n } while (n-- > 0);\n\n const chars: string[] = [];\n while (digits.length) {\n chars.push(alphabet[digits.pop()!]);\n }\n\n return chars.join(\"\");\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/shared/defaultJsonSorter.ts","../src/shared/letters.ts"],"sourcesContent":["/**\n * 对 JSON 对象的键进行排序\n * @param obj 要排序的 JSON 对象\n * @returns 排序后的 JSON 对象\n */\nexport function defaultJsonSorter<T extends Record<string, any>>(obj: T) {\n const keys = Object.keys(obj);\n const sortedKeys = keys.sort(); // 使用原生 sort 方法对键进行排序\n const sortedObj = sortedKeys.reduce((acc, key) => {\n acc[key as keyof T] = obj[key];\n return acc;\n }, {} as T);\n\n return sortedObj as T;\n}\n","/**\n *\n * - input : A\n * output : 0\n * - input : Z\n * output : 25\n * - input : AA\n * output : 26\n * - input : a\n * output : 0\n */\nexport function letterToNumber(letters: string | number) {\n if (typeof letters === \"number\" || !Number.isNaN(+letters)) {\n return +letters;\n }\n\n let n = 0;\n letters = letters.toUpperCase();\n for (let p = 0; p < letters.length; p++) {\n n = letters[p].charCodeAt(0) - 64 + n * 26;\n }\n\n return Math.max(0, n - 1);\n}\n\n/**\n * fork from https://github.com/matthewmueller/number-to-letter\n */\nconst alphabet = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\nconst base = alphabet.length;\n/**\n * numberToLetter(0) // A\n * numberToLetter(25) // Z\n * numberToLetter(26) // AA\n * numberToLetter(51) // AZ\n * numberToLetter(52) // BA\n * numberToLetter(676) // ZA\n * numberToLetter(701) // ZZ\n * numberToLetter(702) // AAA\n */\nexport function numberToLetter(n: number) {\n const digits: number[] = [];\n\n do {\n const v = n % base;\n digits.push(v);\n n = Math.floor(n / base);\n } while (n-- > 0);\n\n const chars: string[] = [];\n while (digits.length) {\n chars.push(alphabet[digits.pop()!]);\n }\n\n return chars.join(\"\");\n}\n"],"mappings":";;;;;;;;AAKO,SAAS,kBAAiD,KAAQ;AACvE,QAAM,OAAO,OAAO,KAAK,GAAG;AAC5B,QAAM,aAAa,KAAK,KAAK;AAC7B,QAAM,YAAY,WAAW,OAAO,CAAC,KAAK,QAAQ;AAChD,QAAI,GAAc,IAAI,IAAI,GAAG;AAC7B,WAAO;AAAA,EACT,GAAG,CAAC,CAAM;AAEV,SAAO;AACT;;;ACHO,SAAS,eAAe,SAA0B;AACvD,MAAI,OAAO,YAAY,YAAY,CAAC,OAAO,MAAM,CAAC,OAAO,GAAG;AAC1D,WAAO,CAAC;AAAA,EACV;AAEA,MAAI,IAAI;AACR,YAAU,QAAQ,YAAY;AAC9B,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,QAAI,QAAQ,CAAC,EAAE,WAAW,CAAC,IAAI,KAAK,IAAI;AAAA,EAC1C;AAEA,SAAO,KAAK,IAAI,GAAG,IAAI,CAAC;AAC1B;AAKA,IAAM,WAAW;AACjB,IAAM,OAAO,SAAS;AAWf,SAAS,eAAe,GAAW;AACxC,QAAM,SAAmB,CAAC;AAE1B,KAAG;AACD,UAAM,IAAI,IAAI;AACd,WAAO,KAAK,CAAC;AACb,QAAI,KAAK,MAAM,IAAI,IAAI;AAAA,EACzB,SAAS,MAAM;AAEf,QAAM,QAAkB,CAAC;AACzB,SAAO,OAAO,QAAQ;AACpB,UAAM,KAAK,SAAS,OAAO,IAAI,CAAE,CAAC;AAAA,EACpC;AAEA,SAAO,MAAM,KAAK,EAAE;AACtB;","names":[]}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
configName,
|
|
3
3
|
getConfig
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-XGRSH7MZ.js";
|
|
5
|
+
import "./chunk-OZFFB6QC.js";
|
|
6
6
|
import {
|
|
7
7
|
createLogger
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-ENF3KHSQ.js";
|
|
9
9
|
|
|
10
10
|
// src/commands/initConfig.ts
|
|
11
11
|
import fs from "fs-extra";
|
|
@@ -31,4 +31,4 @@ var initConfig = async () => {
|
|
|
31
31
|
export {
|
|
32
32
|
initConfig
|
|
33
33
|
};
|
|
34
|
-
//# sourceMappingURL=initConfig-
|
|
34
|
+
//# sourceMappingURL=initConfig-JLWK42R5.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
cli,
|
|
3
3
|
createLogger
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ENF3KHSQ.js";
|
|
5
5
|
|
|
6
6
|
// src/commands/interactive.ts
|
|
7
7
|
import enquirer from "enquirer";
|
|
@@ -40,4 +40,4 @@ var interactive = async (args) => {
|
|
|
40
40
|
export {
|
|
41
41
|
interactive
|
|
42
42
|
};
|
|
43
|
-
//# sourceMappingURL=interactive-
|
|
43
|
+
//# sourceMappingURL=interactive-VUY3CMIF.js.map
|
package/dist/normalizeConfig.js
CHANGED
package/dist/prettier.cjs
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true})
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/prettier.ts
|
|
2
2
|
var _babel = require('prettier/plugins/babel');
|
|
3
3
|
|
|
4
4
|
// src/shared/defaultJsonSorter.ts
|
|
5
|
-
var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash);
|
|
6
5
|
function defaultJsonSorter(obj) {
|
|
7
6
|
const keys = Object.keys(obj);
|
|
8
|
-
const sortedKeys =
|
|
7
|
+
const sortedKeys = keys.sort();
|
|
9
8
|
const sortedObj = sortedKeys.reduce((acc, key) => {
|
|
10
9
|
acc[key] = obj[key];
|
|
11
10
|
return acc;
|
package/dist/prettier.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/Leon.Liao-zd/work/github/next-tools/packages/cli/dist/prettier.cjs","../src/prettier.ts","../src/shared/defaultJsonSorter.ts"],"names":[],"mappings":"AAAA;ACCA,+CAA2C;ADC3C;AACA;
|
|
1
|
+
{"version":3,"sources":["/Users/Leon.Liao-zd/work/github/next-tools/packages/cli/dist/prettier.cjs","../src/prettier.ts","../src/shared/defaultJsonSorter.ts"],"names":[],"mappings":"AAAA;ACCA,+CAA2C;ADC3C;AACA;AEEO,SAAS,iBAAA,CAAiD,GAAA,EAAQ;AACvE,EAAA,MAAM,KAAA,EAAO,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA;AAC5B,EAAA,MAAM,WAAA,EAAa,IAAA,CAAK,IAAA,CAAK,CAAA;AAC7B,EAAA,MAAM,UAAA,EAAY,UAAA,CAAW,MAAA,CAAO,CAAC,GAAA,EAAK,GAAA,EAAA,GAAQ;AAChD,IAAA,GAAA,CAAI,GAAc,EAAA,EAAI,GAAA,CAAI,GAAG,CAAA;AAC7B,IAAA,OAAO,GAAA;AAAA,EACT,CAAA,EAAG,CAAC,CAAM,CAAA;AAEV,EAAA,OAAO,SAAA;AACT;AFDA;AACA;ACVA,IAAM,YAAA,EAAc,YAAA;AAEpB,IAAM,WAAA,EAAa,cAAA,CAAgB,IAAA;AAG5B,IAAM,UAAA,EAAiC;AAAA,EAC5C;AAAA,IACE,IAAA,EAAM,gBAAA;AAAA,IACN,OAAA,EAAS,CAAC,MAAM,CAAA;AAAA,IAChB,UAAA,EAAY,CAAC,WAAW;AAAA,EAC1B;AACF,CAAA;AAQO,IAAM,QAAA,EAA6B;AAAA,EACxC,IAAA,EAAM;AAAA,IACJ,GAAG,UAAA;AAAA,IACH,UAAA,CAAW,IAAA,EAAM,OAAA,EAAS;AACxB,MAAA,GAAA,CAAI,UAAA,CAAW,UAAA,EAAY;AACzB,QAAA,KAAA,EAAO,UAAA,CAAW,UAAA,CAAW,IAAA,EAAM,OAAO,CAAA;AAAA,MAC5C;AACA,MAAA,MAAM,WAAA,EAAa,OAAA,CAAQ,QAAA,CAAS,QAAA,CAAS,WAAW,CAAA;AACxD,MAAA,GAAA,CAAI,UAAA,EAAY;AACd,QAAA,IAAI;AACF,UAAA,IAAI,IAAA,EAAM,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AACzB,UAAA,IAAI,OAAA,EAAS,iBAAA,CAAkB,GAAG,CAAA;AAClC,UAAA,KAAA,EAAO,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,IAAA,EAAM,CAAC,CAAA;AAAA,QACvC,EAAA,MAAA,CAAS,KAAA,EAAO;AACd,UAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,mCAAA,EAAa,KAAK,CAAA,CAAA;AAChC,QAAA;AACF,MAAA;AACO,MAAA;AACT,IAAA;AACF,EAAA;AACF;ADEkE;AACA;AACA;AACA","file":"/Users/Leon.Liao-zd/work/github/next-tools/packages/cli/dist/prettier.cjs","sourcesContent":[null,"import { Plugin } from \"prettier\";\nimport { parsers as prettierParsers } from \"prettier/plugins/babel\";\nimport { defaultJsonSorter } from \"./shared/defaultJsonSorter\";\n\nconst i18nJsonExt = \".i18n.json\";\n\nconst jsonParser = prettierParsers.json;\n\n// 配置 i18n.json\nexport const languages: Plugin[\"languages\"] = [\n {\n name: \"dune-i18n-json\",\n parsers: [\"json\"],\n extensions: [i18nJsonExt],\n },\n];\n\n/**\n * 格式化 *.i18n.json 文件\n * 按照 key 排序\n * 对齐 cli 生成的 i18n.json 文件顺序\n * 方便查看和比较\n */\nexport const parsers: Plugin[\"parsers\"] = {\n json: {\n ...jsonParser,\n preprocess(text, options) {\n if (jsonParser.preprocess) {\n text = jsonParser.preprocess(text, options);\n }\n const isI18nJson = options.filepath.endsWith(i18nJsonExt);\n if (isI18nJson) {\n try {\n let obj = JSON.parse(text);\n let newObj = defaultJsonSorter(obj);\n text = JSON.stringify(newObj, null, 2);\n } catch (error) {\n console.log(`JSON 格式错误:${error}`);\n }\n }\n return text;\n },\n },\n};\n","/**\n * 对 JSON 对象的键进行排序\n * @param obj 要排序的 JSON 对象\n * @returns 排序后的 JSON 对象\n */\nexport function defaultJsonSorter<T extends Record<string, any>>(obj: T) {\n const keys = Object.keys(obj);\n const sortedKeys = keys.sort(); // 使用原生 sort 方法对键进行排序\n const sortedObj = sortedKeys.reduce((acc, key) => {\n acc[key as keyof T] = obj[key];\n return acc;\n }, {} as T);\n\n return sortedObj as T;\n}\n"]}
|
package/dist/prettier.js
CHANGED
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
import { parsers as prettierParsers } from "prettier/plugins/babel";
|
|
3
3
|
|
|
4
4
|
// src/shared/defaultJsonSorter.ts
|
|
5
|
-
import _ from "lodash";
|
|
6
5
|
function defaultJsonSorter(obj) {
|
|
7
6
|
const keys = Object.keys(obj);
|
|
8
|
-
const sortedKeys =
|
|
7
|
+
const sortedKeys = keys.sort();
|
|
9
8
|
const sortedObj = sortedKeys.reduce((acc, key) => {
|
|
10
9
|
acc[key] = obj[key];
|
|
11
10
|
return acc;
|
package/dist/prettier.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/prettier.ts","../src/shared/defaultJsonSorter.ts"],"sourcesContent":["import { Plugin } from \"prettier\";\nimport { parsers as prettierParsers } from \"prettier/plugins/babel\";\nimport { defaultJsonSorter } from \"./shared/defaultJsonSorter\";\n\nconst i18nJsonExt = \".i18n.json\";\n\nconst jsonParser = prettierParsers.json;\n\n// 配置 i18n.json\nexport const languages: Plugin[\"languages\"] = [\n {\n name: \"dune-i18n-json\",\n parsers: [\"json\"],\n extensions: [i18nJsonExt],\n },\n];\n\n/**\n * 格式化 *.i18n.json 文件\n * 按照 key 排序\n * 对齐 cli 生成的 i18n.json 文件顺序\n * 方便查看和比较\n */\nexport const parsers: Plugin[\"parsers\"] = {\n json: {\n ...jsonParser,\n preprocess(text, options) {\n if (jsonParser.preprocess) {\n text = jsonParser.preprocess(text, options);\n }\n const isI18nJson = options.filepath.endsWith(i18nJsonExt);\n if (isI18nJson) {\n try {\n let obj = JSON.parse(text);\n let newObj = defaultJsonSorter(obj);\n text = JSON.stringify(newObj, null, 2);\n } catch (error) {\n console.log(`JSON 格式错误:${error}`);\n }\n }\n return text;\n },\n },\n};\n","
|
|
1
|
+
{"version":3,"sources":["../src/prettier.ts","../src/shared/defaultJsonSorter.ts"],"sourcesContent":["import { Plugin } from \"prettier\";\nimport { parsers as prettierParsers } from \"prettier/plugins/babel\";\nimport { defaultJsonSorter } from \"./shared/defaultJsonSorter\";\n\nconst i18nJsonExt = \".i18n.json\";\n\nconst jsonParser = prettierParsers.json;\n\n// 配置 i18n.json\nexport const languages: Plugin[\"languages\"] = [\n {\n name: \"dune-i18n-json\",\n parsers: [\"json\"],\n extensions: [i18nJsonExt],\n },\n];\n\n/**\n * 格式化 *.i18n.json 文件\n * 按照 key 排序\n * 对齐 cli 生成的 i18n.json 文件顺序\n * 方便查看和比较\n */\nexport const parsers: Plugin[\"parsers\"] = {\n json: {\n ...jsonParser,\n preprocess(text, options) {\n if (jsonParser.preprocess) {\n text = jsonParser.preprocess(text, options);\n }\n const isI18nJson = options.filepath.endsWith(i18nJsonExt);\n if (isI18nJson) {\n try {\n let obj = JSON.parse(text);\n let newObj = defaultJsonSorter(obj);\n text = JSON.stringify(newObj, null, 2);\n } catch (error) {\n console.log(`JSON 格式错误:${error}`);\n }\n }\n return text;\n },\n },\n};\n","/**\n * 对 JSON 对象的键进行排序\n * @param obj 要排序的 JSON 对象\n * @returns 排序后的 JSON 对象\n */\nexport function defaultJsonSorter<T extends Record<string, any>>(obj: T) {\n const keys = Object.keys(obj);\n const sortedKeys = keys.sort(); // 使用原生 sort 方法对键进行排序\n const sortedObj = sortedKeys.reduce((acc, key) => {\n acc[key as keyof T] = obj[key];\n return acc;\n }, {} as T);\n\n return sortedObj as T;\n}\n"],"mappings":";AACA,SAAS,WAAW,uBAAuB;;;ACIpC,SAAS,kBAAiD,KAAQ;AACvE,QAAM,OAAO,OAAO,KAAK,GAAG;AAC5B,QAAM,aAAa,KAAK,KAAK;AAC7B,QAAM,YAAY,WAAW,OAAO,CAAC,KAAK,QAAQ;AAChD,QAAI,GAAc,IAAI,IAAI,GAAG;AAC7B,WAAO;AAAA,EACT,GAAG,CAAC,CAAM;AAEV,SAAO;AACT;;;ADVA,IAAM,cAAc;AAEpB,IAAM,aAAa,gBAAgB;AAG5B,IAAM,YAAiC;AAAA,EAC5C;AAAA,IACE,MAAM;AAAA,IACN,SAAS,CAAC,MAAM;AAAA,IAChB,YAAY,CAAC,WAAW;AAAA,EAC1B;AACF;AAQO,IAAM,UAA6B;AAAA,EACxC,MAAM;AAAA,IACJ,GAAG;AAAA,IACH,WAAW,MAAM,SAAS;AACxB,UAAI,WAAW,YAAY;AACzB,eAAO,WAAW,WAAW,MAAM,OAAO;AAAA,MAC5C;AACA,YAAM,aAAa,QAAQ,SAAS,SAAS,WAAW;AACxD,UAAI,YAAY;AACd,YAAI;AACF,cAAI,MAAM,KAAK,MAAM,IAAI;AACzB,cAAI,SAAS,kBAAkB,GAAG;AAClC,iBAAO,KAAK,UAAU,QAAQ,MAAM,CAAC;AAAA,QACvC,SAAS,OAAO;AACd,kBAAQ,IAAI,sCAAa,KAAK,EAAE;AAAA,QAClC;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;","names":[]}
|
|
@@ -1,70 +1,6 @@
|
|
|
1
1
|
import SwaggerParser from '@apidevtools/swagger-parser';
|
|
2
2
|
import { OpenAPIV3 } from 'openapi-types';
|
|
3
3
|
|
|
4
|
-
interface I18nConfig {
|
|
5
|
-
i18nDir?: string;
|
|
6
|
-
i18nFileName?: string;
|
|
7
|
-
defaultLocale?: string;
|
|
8
|
-
/**
|
|
9
|
-
* 可以是 id 或者 url,如果是 url 则会自动解析出 id
|
|
10
|
-
* id: 1C9-Dol3oO20W9_FhiVlxNsDhOaaejJIgAZYRkonGmfk
|
|
11
|
-
* url: https://docs.google.com/spreadsheets/d/1C9-Dol3oO20W9_FhiVlxNsDhOaaejJIgAZYRkonGmfk/edit#gid=1740568548
|
|
12
|
-
*/
|
|
13
|
-
sheetId?: string;
|
|
14
|
-
sheetRange?: string;
|
|
15
|
-
/**
|
|
16
|
-
* 对应 语言、i18nKey 所在的列标识符 如(A,B,C...)
|
|
17
|
-
* 传入时将忽略默认的配置
|
|
18
|
-
* @default {key: "B", zh: "C", en: "D", in: "E",}
|
|
19
|
-
*/
|
|
20
|
-
position?: {
|
|
21
|
-
key: string;
|
|
22
|
-
[key: string]: string;
|
|
23
|
-
};
|
|
24
|
-
/**
|
|
25
|
-
* 从 Google Sheets 哪一行开始解析
|
|
26
|
-
* 默认从第2行开始,模板文件第一行是表头
|
|
27
|
-
* @default 2
|
|
28
|
-
*/
|
|
29
|
-
parseStartIndex?: number;
|
|
30
|
-
/**
|
|
31
|
-
* 包括的文件
|
|
32
|
-
* glob 语法
|
|
33
|
-
*/
|
|
34
|
-
include?: string[];
|
|
35
|
-
/**
|
|
36
|
-
* 是否禁用提取功能,某些项是不需要提取的,只需要同不Google sheet
|
|
37
|
-
* @default false
|
|
38
|
-
*/
|
|
39
|
-
disableExtract?: boolean;
|
|
40
|
-
/**
|
|
41
|
-
* 翻译文案支持 namespace
|
|
42
|
-
* key 为 namespace
|
|
43
|
-
* value 为 对应的文件夹路径
|
|
44
|
-
* 使用场景:根据不同的业务模块,将翻译的key添加不同的前缀,并修改对应代码
|
|
45
|
-
*/
|
|
46
|
-
namespace?: Record<string, string | string[]>;
|
|
47
|
-
/**
|
|
48
|
-
* namespace 分隔符
|
|
49
|
-
* @default "."
|
|
50
|
-
*/
|
|
51
|
-
namespaceSeparator?: string;
|
|
52
|
-
translatePlatform?: {
|
|
53
|
-
/**
|
|
54
|
-
* 是否启用翻译平台
|
|
55
|
-
*/
|
|
56
|
-
enable?: boolean;
|
|
57
|
-
/**
|
|
58
|
-
* 在翻译平台注册的
|
|
59
|
-
* 项目名称
|
|
60
|
-
*/
|
|
61
|
-
project?: string;
|
|
62
|
-
/**
|
|
63
|
-
* 翻译平台的 url
|
|
64
|
-
*/
|
|
65
|
-
url?: string;
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
4
|
interface ApiConfig {
|
|
69
5
|
/**
|
|
70
6
|
* swagger JSON 的路径 可以是 本地 可以是远程
|
|
@@ -126,8 +62,7 @@ interface ApiConfig {
|
|
|
126
62
|
dereferenceSwaggerConfig?: SwaggerParser.Options;
|
|
127
63
|
}
|
|
128
64
|
interface Config {
|
|
129
|
-
i18n?: I18nConfig[];
|
|
130
65
|
api?: ApiConfig[];
|
|
131
66
|
}
|
|
132
67
|
|
|
133
|
-
export type { ApiConfig as A, Config as C
|
|
68
|
+
export type { ApiConfig as A, Config as C };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dune2/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/liaoyinglong/next-tools.git",
|
|
@@ -31,22 +31,18 @@
|
|
|
31
31
|
"dist"
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@apidevtools/swagger-parser": "^
|
|
34
|
+
"@apidevtools/swagger-parser": "^12",
|
|
35
35
|
"cac": "^6.7.14",
|
|
36
36
|
"debug": "^4.3.4",
|
|
37
37
|
"enquirer": "^2.3.6",
|
|
38
|
+
"es-toolkit": "^1",
|
|
38
39
|
"fs-extra": "^11.2.0",
|
|
39
40
|
"jiti": "^2.4.2",
|
|
40
41
|
"json-schema-to-typescript": "15.0.0",
|
|
41
|
-
"
|
|
42
|
-
"p-map": "^7.0.2",
|
|
43
|
-
"path-to-regexp": "7.1.0",
|
|
44
|
-
"picocolors": "^1.0.0"
|
|
42
|
+
"p-map": "^7.0.2"
|
|
45
43
|
},
|
|
46
44
|
"devDependencies": {
|
|
47
45
|
"@types/debug": "^4.1.7",
|
|
48
|
-
"@types/lodash": "^4.14.186",
|
|
49
|
-
"gaxios": "*",
|
|
50
46
|
"openapi-types": "^12.0.2",
|
|
51
47
|
"prettier": "^3",
|
|
52
48
|
"tsup": "8"
|
package/readme.md
CHANGED
|
@@ -1,33 +1,65 @@
|
|
|
1
|
-
|
|
1
|
+
# CLI 工具
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
-
|
|
3
|
+
一个基于 CAC 的命令行工具,主要用于 API 代码生成和配置管理。
|
|
4
|
+
|
|
5
|
+
## 功能特性
|
|
6
|
+
|
|
7
|
+
- 从 Swagger/OpenAPI 规范生成 API 请求代码
|
|
8
|
+
- 自动生成 TypeScript 类型定义
|
|
9
|
+
- 支持配置文件初始化
|
|
10
|
+
- 交互式命令选择界面
|
|
11
|
+
|
|
12
|
+
## 安装与使用
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @dune2/cli
|
|
16
|
+
```
|
|
8
17
|
|
|
9
18
|
## 支持的命令
|
|
10
19
|
|
|
11
20
|
```shell
|
|
12
21
|
Commands:
|
|
13
|
-
|
|
14
|
-
extract 提取代码中的文案
|
|
15
|
-
upload 上传翻译文件
|
|
16
|
-
generateApi 生成api文件
|
|
22
|
+
generateApi 生成 API 文件
|
|
17
23
|
init 初始化配置文件
|
|
18
24
|
interactive 交互式操作
|
|
19
25
|
```
|
|
20
26
|
|
|
21
|
-
|
|
27
|
+
### 主要命令详解
|
|
28
|
+
|
|
29
|
+
#### `dune generateApi`
|
|
30
|
+
|
|
31
|
+
从 Swagger/OpenAPI 规范生成 API 请求代码,包括:
|
|
32
|
+
|
|
33
|
+
- 自动生成 TypeScript 类型定义
|
|
34
|
+
- 支持 URL 路径参数处理
|
|
35
|
+
- 生成请求构造器
|
|
36
|
+
- 支持响应类型推断
|
|
37
|
+
- 自动格式化生成的代码
|
|
38
|
+
|
|
39
|
+
#### `dune init`
|
|
40
|
+
|
|
41
|
+
初始化项目配置文件,创建 `dune.config.ts` 配置文件模板:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { defineConfig } from "@dune2/cli";
|
|
45
|
+
|
|
46
|
+
export default defineConfig({
|
|
47
|
+
i18n: [],
|
|
48
|
+
api: [],
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
#### `dune interactive` 或 `dune i`
|
|
22
53
|
|
|
23
|
-
|
|
54
|
+
进入交互式命令选择界面,提供友好的命令选择体验。
|
|
24
55
|
|
|
25
|
-
|
|
56
|
+
## 交互式模式
|
|
26
57
|
|
|
27
|
-
|
|
58
|
+
运行 `dune` 或 `dune interactive` 进入交互式选择模式,使用上下键选择要执行的命令,回车键确认执行。
|
|
28
59
|
|
|
29
|
-
|
|
60
|
+
## 配置文件
|
|
30
61
|
|
|
31
|
-
|
|
62
|
+
工具会在项目根目录查找 `dune.config.ts` 配置文件,支持:
|
|
32
63
|
|
|
33
|
-
|
|
64
|
+
- API 配置:Swagger 文档路径、输出目录等
|
|
65
|
+
- 国际化配置:多语言支持相关配置
|
package/dist/chunk-DORNSRHQ.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
// src/shared/index.ts
|
|
2
|
-
import cac from "cac";
|
|
3
|
-
import debug from "debug";
|
|
4
|
-
import path from "path";
|
|
5
|
-
import fs from "fs-extra";
|
|
6
|
-
var cli = cac("dune");
|
|
7
|
-
var createLogger = (name) => {
|
|
8
|
-
const info = debug(`${cli.name}:${name}`);
|
|
9
|
-
return {
|
|
10
|
-
...info,
|
|
11
|
-
info,
|
|
12
|
-
error: info.extend("error")
|
|
13
|
-
};
|
|
14
|
-
};
|
|
15
|
-
debug.enable(`${cli.name}:*`);
|
|
16
|
-
var homeConfigDir = (() => {
|
|
17
|
-
const isWin = process.platform === "win32";
|
|
18
|
-
const USER_HOME_DIR = isWin ? process.env.USERPROFILE : process.env.HOME;
|
|
19
|
-
const configDir = path.join(USER_HOME_DIR, ".config", cli.name);
|
|
20
|
-
if (!fs.existsSync(configDir)) {
|
|
21
|
-
fs.mkdirSync(configDir);
|
|
22
|
-
}
|
|
23
|
-
return homeConfigDir2;
|
|
24
|
-
function homeConfigDir2(p) {
|
|
25
|
-
if (!p) {
|
|
26
|
-
return configDir;
|
|
27
|
-
}
|
|
28
|
-
return path.join(configDir, p);
|
|
29
|
-
}
|
|
30
|
-
})();
|
|
31
|
-
|
|
32
|
-
export {
|
|
33
|
-
cli,
|
|
34
|
-
createLogger
|
|
35
|
-
};
|
|
36
|
-
//# sourceMappingURL=chunk-DORNSRHQ.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shared/index.ts"],"sourcesContent":["import cac from \"cac\";\nimport debug from \"debug\";\nimport path from \"path\";\nimport fs from \"fs-extra\";\n\nexport const cli = cac(\"dune\");\n\nexport const createLogger = (name: string) => {\n const info = debug(`${cli.name}:${name}`);\n return {\n ...info,\n info,\n error: info.extend(\"error\"),\n };\n};\n\ndebug.enable(`${cli.name}:*`);\n\n/**\n * same with chacheDir\n * homeDir();\n * //=> '~/name'\n *\n * homeDir('bar.js')\n * //=> '~/name/bar.js'\n */\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport const homeConfigDir = (() => {\n const isWin = process.platform === \"win32\";\n const USER_HOME_DIR = isWin ? process.env.USERPROFILE : process.env.HOME;\n const configDir = path.join(USER_HOME_DIR!, \".config\", cli.name);\n\n if (!fs.existsSync(configDir)) {\n fs.mkdirSync(configDir);\n }\n return homeConfigDir;\n\n function homeConfigDir(p?: string): string {\n if (!p) {\n return configDir;\n }\n return path.join(configDir, p);\n }\n})();\n"],"mappings":";AAAA,OAAO,SAAS;AAChB,OAAO,WAAW;AAClB,OAAO,UAAU;AACjB,OAAO,QAAQ;AAER,IAAM,MAAM,IAAI,MAAM;AAEtB,IAAM,eAAe,CAAC,SAAiB;AAC5C,QAAM,OAAO,MAAM,GAAG,IAAI,IAAI,IAAI,IAAI,EAAE;AACxC,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA,OAAO,KAAK,OAAO,OAAO;AAAA,EAC5B;AACF;AAEA,MAAM,OAAO,GAAG,IAAI,IAAI,IAAI;AAWrB,IAAM,iBAAiB,MAAM;AAClC,QAAM,QAAQ,QAAQ,aAAa;AACnC,QAAM,gBAAgB,QAAQ,QAAQ,IAAI,cAAc,QAAQ,IAAI;AACpE,QAAM,YAAY,KAAK,KAAK,eAAgB,WAAW,IAAI,IAAI;AAE/D,MAAI,CAAC,GAAG,WAAW,SAAS,GAAG;AAC7B,OAAG,UAAU,SAAS;AAAA,EACxB;AACA,SAAOA;AAEP,WAASA,eAAc,GAAoB;AACzC,QAAI,CAAC,GAAG;AACN,aAAO;AAAA,IACT;AACA,WAAO,KAAK,KAAK,WAAW,CAAC;AAAA,EAC/B;AACF,GAAG;","names":["homeConfigDir"]}
|
package/dist/chunk-VS4LDXR3.js
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
// src/shared/config/normalizeConfig.ts
|
|
2
|
-
import _2 from "lodash";
|
|
3
|
-
import path from "path";
|
|
4
|
-
|
|
5
|
-
// src/shared/defaultJsonSorter.ts
|
|
6
|
-
import _ from "lodash";
|
|
7
|
-
function defaultJsonSorter(obj) {
|
|
8
|
-
const keys = Object.keys(obj);
|
|
9
|
-
const sortedKeys = _.sortBy(keys);
|
|
10
|
-
const sortedObj = sortedKeys.reduce((acc, key) => {
|
|
11
|
-
acc[key] = obj[key];
|
|
12
|
-
return acc;
|
|
13
|
-
}, {});
|
|
14
|
-
return sortedObj;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// src/shared/resolveSheetId.ts
|
|
18
|
-
import { match } from "path-to-regexp";
|
|
19
|
-
function resolveSheetId(str) {
|
|
20
|
-
var _a;
|
|
21
|
-
if (!str || !(str == null ? void 0 : str.startsWith("http"))) {
|
|
22
|
-
return str;
|
|
23
|
-
}
|
|
24
|
-
const url = new URL(str);
|
|
25
|
-
const matched = match("/spreadsheets/d{/:id}*", {
|
|
26
|
-
decode: decodeURIComponent
|
|
27
|
-
})(url.pathname);
|
|
28
|
-
return matched ? (_a = matched.params.id) == null ? void 0 : _a[0] : str;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// src/shared/config/normalizeConfig.ts
|
|
32
|
-
function normalizeConfig(config) {
|
|
33
|
-
var _a;
|
|
34
|
-
const defaultI18nConfig = {
|
|
35
|
-
i18nDir: "./src/i18n",
|
|
36
|
-
i18nFileName: "{locale}.i18n.json",
|
|
37
|
-
position: { key: "B", zh: "C", en: "D", in: "E" },
|
|
38
|
-
parseStartIndex: 2
|
|
39
|
-
};
|
|
40
|
-
config.cwd ??= process.cwd();
|
|
41
|
-
config.cacheDir ??= path.join(config.cwd, "node_modules/.cache/dune-cli");
|
|
42
|
-
if (!config.i18n || !((_a = config.i18n) == null ? void 0 : _a.length)) {
|
|
43
|
-
config.i18n = [defaultI18nConfig];
|
|
44
|
-
}
|
|
45
|
-
config.i18n = config.i18n.map((item) => {
|
|
46
|
-
var _a2;
|
|
47
|
-
item = Object.assign({}, defaultI18nConfig, item);
|
|
48
|
-
item.cwd ??= config.cwd;
|
|
49
|
-
item.locales = Object.keys(item.position).filter((item2) => item2 !== "key");
|
|
50
|
-
item.sheetId = resolveSheetId(item.sheetId);
|
|
51
|
-
item.jsonSorter = defaultJsonSorter;
|
|
52
|
-
item.enabled ??= true;
|
|
53
|
-
item.defaultLocale ??= "zh";
|
|
54
|
-
item.namespaceSeparator ??= ".";
|
|
55
|
-
const defaultTranslatePlatform = {
|
|
56
|
-
url: "https://test-transfer.duneproject.xyz",
|
|
57
|
-
enable: !!((_a2 = item.translatePlatform) == null ? void 0 : _a2.project)
|
|
58
|
-
};
|
|
59
|
-
_2.defaults(item.translatePlatform, defaultTranslatePlatform);
|
|
60
|
-
return item;
|
|
61
|
-
});
|
|
62
|
-
config.api ??= [];
|
|
63
|
-
config.api = config.api.map(apiConfigNormalizer);
|
|
64
|
-
return config;
|
|
65
|
-
}
|
|
66
|
-
function apiConfigNormalizer(item) {
|
|
67
|
-
item.output ??= "./src/apis";
|
|
68
|
-
item.RequestBuilderImportPath ??= `import { RequestBuilder } from '@dune2/tools/rq';`;
|
|
69
|
-
item.enableTs ??= true;
|
|
70
|
-
item.enabled ??= true;
|
|
71
|
-
item.format ??= true;
|
|
72
|
-
item.responseSchemaTransformer ??= (schema) => {
|
|
73
|
-
var _a;
|
|
74
|
-
return ((_a = schema.properties) == null ? void 0 : _a.data) ?? schema;
|
|
75
|
-
};
|
|
76
|
-
return item;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export {
|
|
80
|
-
defaultJsonSorter,
|
|
81
|
-
resolveSheetId,
|
|
82
|
-
normalizeConfig,
|
|
83
|
-
apiConfigNormalizer
|
|
84
|
-
};
|
|
85
|
-
//# sourceMappingURL=chunk-VS4LDXR3.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shared/config/normalizeConfig.ts","../src/shared/defaultJsonSorter.ts","../src/shared/resolveSheetId.ts"],"sourcesContent":["import _ from \"lodash\";\nimport path from \"path\";\nimport { defaultJsonSorter } from \"../defaultJsonSorter\";\nimport { resolveSheetId } from \"../resolveSheetId\";\nimport { ApiConfig, Config, I18nConfig } from \"./types\";\nexport function normalizeConfig(config: Config): Config {\n const defaultI18nConfig: I18nConfig = {\n i18nDir: \"./src/i18n\",\n i18nFileName: \"{locale}.i18n.json\",\n position: { key: \"B\", zh: \"C\", en: \"D\", in: \"E\" },\n parseStartIndex: 2,\n };\n config.cwd ??= process.cwd();\n config.cacheDir ??= path.join(config.cwd, \"node_modules/.cache/dune-cli\");\n\n //#region i18n 配置标准化\n if (!config.i18n || !config.i18n?.length) {\n config.i18n = [defaultI18nConfig];\n }\n\n // 格式化 i18n 配置\n config.i18n = config.i18n.map((item) => {\n item = Object.assign({}, defaultI18nConfig, item);\n item.cwd ??= config.cwd;\n item.locales = Object.keys(item.position!).filter((item) => item !== \"key\");\n item.sheetId = resolveSheetId(item.sheetId);\n item.jsonSorter = defaultJsonSorter;\n item.enabled ??= true;\n item.defaultLocale ??= \"zh\";\n\n //#region namespace\n item.namespaceSeparator ??= \".\";\n //#endregion\n\n const defaultTranslatePlatform: I18nConfig[\"translatePlatform\"] = {\n url: \"https://test-transfer.duneproject.xyz\",\n enable: !!item.translatePlatform?.project,\n };\n _.defaults(item.translatePlatform, defaultTranslatePlatform);\n return item;\n });\n //#endregion\n\n //#region api 配置标准化\n config.api ??= [];\n config.api = config.api.map(apiConfigNormalizer);\n //#endregion\n return config;\n}\nexport function apiConfigNormalizer(item: ApiConfig) {\n item.output ??= \"./src/apis\";\n item.RequestBuilderImportPath ??= `import { RequestBuilder } from '@dune2/tools/rq';`;\n item.enableTs ??= true;\n item.enabled ??= true;\n item.format ??= true;\n item.responseSchemaTransformer ??= (schema) =>\n schema.properties?.data ?? schema;\n return item;\n}\n","import _ from \"lodash\";\n\n/**\n * 对 JSON 对象的键进行排序\n * @param obj 要排序的 JSON 对象\n * @returns 排序后的 JSON 对象\n */\nexport function defaultJsonSorter<T extends Record<string, any>>(obj: T) {\n const keys = Object.keys(obj);\n const sortedKeys = _.sortBy(keys); // 使用 lodash 库的 sortBy 方法对键进行排序\n const sortedObj = sortedKeys.reduce((acc, key) => {\n acc[key as keyof T] = obj[key];\n return acc;\n }, {} as T);\n\n return sortedObj as T;\n}\n","/**\n * input:\n * \"https://docs.google.com/spreadsheets/d/1C9-Dol3oO20W9_FhiVlxNsDhOaaejJIgAZYRkonGmfk/edit#gid=1740568548\"\n * output:\n * \"1C9-Dol3oO20W9_FhiVlxNsDhOaaejJIgAZYRkonGmfk\"\n * --\n * input: \"1C9-Dol3oO20W9_FhiVlxNsDhOaaejJIgAZYRkonGmfk\"\n * output: \"1C9-Dol3oO20W9_FhiVlxNsDhOaaejJIgAZYRkonGmfk\"\n */\nimport { match } from \"path-to-regexp\";\n\nexport function resolveSheetId(str?: string) {\n if (!str || !str?.startsWith(\"http\")) {\n return str;\n }\n const url = new URL(str);\n const matched = match<{ id: string[] }>(\"/spreadsheets/d{/:id}*\", {\n decode: decodeURIComponent,\n })(url.pathname);\n\n return matched ? matched.params.id?.[0] : str;\n}\n"],"mappings":";AAAA,OAAOA,QAAO;AACd,OAAO,UAAU;;;ACDjB,OAAO,OAAO;AAOP,SAAS,kBAAiD,KAAQ;AACvE,QAAM,OAAO,OAAO,KAAK,GAAG;AAC5B,QAAM,aAAa,EAAE,OAAO,IAAI;AAChC,QAAM,YAAY,WAAW,OAAO,CAAC,KAAK,QAAQ;AAChD,QAAI,GAAc,IAAI,IAAI,GAAG;AAC7B,WAAO;AAAA,EACT,GAAG,CAAC,CAAM;AAEV,SAAO;AACT;;;ACPA,SAAS,aAAa;AAEf,SAAS,eAAe,KAAc;AAX7C;AAYE,MAAI,CAAC,OAAO,EAAC,2BAAK,WAAW,UAAS;AACpC,WAAO;AAAA,EACT;AACA,QAAM,MAAM,IAAI,IAAI,GAAG;AACvB,QAAM,UAAU,MAAwB,0BAA0B;AAAA,IAChE,QAAQ;AAAA,EACV,CAAC,EAAE,IAAI,QAAQ;AAEf,SAAO,WAAU,aAAQ,OAAO,OAAf,mBAAoB,KAAK;AAC5C;;;AFhBO,SAAS,gBAAgB,QAAwB;AALxD;AAME,QAAM,oBAAgC;AAAA,IACpC,SAAS;AAAA,IACT,cAAc;AAAA,IACd,UAAU,EAAE,KAAK,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI;AAAA,IAChD,iBAAiB;AAAA,EACnB;AACA,SAAO,QAAQ,QAAQ,IAAI;AAC3B,SAAO,aAAa,KAAK,KAAK,OAAO,KAAK,8BAA8B;AAGxE,MAAI,CAAC,OAAO,QAAQ,GAAC,YAAO,SAAP,mBAAa,SAAQ;AACxC,WAAO,OAAO,CAAC,iBAAiB;AAAA,EAClC;AAGA,SAAO,OAAO,OAAO,KAAK,IAAI,CAAC,SAAS;AArB1C,QAAAC;AAsBI,WAAO,OAAO,OAAO,CAAC,GAAG,mBAAmB,IAAI;AAChD,SAAK,QAAQ,OAAO;AACpB,SAAK,UAAU,OAAO,KAAK,KAAK,QAAS,EAAE,OAAO,CAACC,UAASA,UAAS,KAAK;AAC1E,SAAK,UAAU,eAAe,KAAK,OAAO;AAC1C,SAAK,aAAa;AAClB,SAAK,YAAY;AACjB,SAAK,kBAAkB;AAGvB,SAAK,uBAAuB;AAG5B,UAAM,2BAA4D;AAAA,MAChE,KAAK;AAAA,MACL,QAAQ,CAAC,GAACD,MAAA,KAAK,sBAAL,gBAAAA,IAAwB;AAAA,IACpC;AACA,IAAAE,GAAE,SAAS,KAAK,mBAAmB,wBAAwB;AAC3D,WAAO;AAAA,EACT,CAAC;AAID,SAAO,QAAQ,CAAC;AAChB,SAAO,MAAM,OAAO,IAAI,IAAI,mBAAmB;AAE/C,SAAO;AACT;AACO,SAAS,oBAAoB,MAAiB;AACnD,OAAK,WAAW;AAChB,OAAK,6BAA6B;AAClC,OAAK,aAAa;AAClB,OAAK,YAAY;AACjB,OAAK,WAAW;AAChB,OAAK,8BAA8B,CAAC,WAAQ;AAvD9C;AAwDI,yBAAO,eAAP,mBAAmB,SAAQ;AAAA;AAC7B,SAAO;AACT;","names":["_","_a","item","_"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/generateApi/index.ts","../src/shared/formatFile.ts","../src/shared/promptConfigEnable.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 dereferenceConfig = _.merge(\n {\n resolve: {\n http: {\n timeout: 30 * 1000,\n },\n },\n },\n apiConfig.dereferenceSwaggerConfig,\n );\n const parsed = (await SwaggerParser.dereference(\n apiConfig.swaggerJSONPath,\n dereferenceConfig,\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 \"// do not edit this file manually, it will be overwritten by @dune2/cli\",\n apiConfig.RequestBuilderImportPath!,\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 ${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 isGenerateFieldsMap = [\"post\", \"put\"].includes(method);\n // 请求参数类型\n // 响应参数类型\n const [requestParamsTypeCode, responseParamsTypeCode] = await Promise.all([\n compileRequestParams(operationObject, isGenerateFieldsMap),\n compileResponseParams(operationObject, apiConfig),\n ]);\n\n code.push(`\nexport namespace ${requestBuilderName} {\n ${requestParamsTypeCode.code}\n \n ${responseParamsTypeCode}\n};`);\n\n if (isGenerateFieldsMap && !_.isEmpty(requestParamsTypeCode.fieldsMap)) {\n // 生成表单 fieldsMap\n code.push(`\nexport const ${requestBuilderName}FieldsMap = ${JSON.stringify(\n requestParamsTypeCode.fieldsMap,\n )} as const\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 if (obj && typeof obj === \"object\") {\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 }\n return map;\n}\n","import { createLogger } from \".\";\nimport * as child_process from \"child_process\";\n\nconst log = createLogger(\"formatFile\");\n\nexport function formatFile(filename: string) {\n // 格式化代码\n log.info(`尝试格式化代码: %s`, filename);\n child_process.exec(`prettier --write '${filename}'`, (error) => {\n if (error) {\n log.error(`格式化代码失败: ${error}`);\n log.error(`请手动执行: prettier --write ${filename}`);\n log.error(`或者在配置文件中关闭格式化功能`);\n } else {\n log.info(`格式化代码成功: %s`, filename);\n }\n });\n}\n","import enquirer from \"enquirer\";\nimport { ApiConfig, I18nConfig } from \"./config\";\nconst { prompt } = enquirer;\n\ninterface Opt<T> {\n configArr: (T & { enabled?: boolean })[];\n getChoiceItem: (item: T) => {\n name: string;\n message?: string;\n value?: string;\n hint?: string;\n };\n checkIsEnabled: (enabledArr: string[], item: T) => boolean;\n}\n\nexport async function promptConfigEnable<T>(opt: Opt<T>) {\n const { configArr, getChoiceItem } = opt;\n // 只有一条配置的时候不用选择\n if (configArr.length <= 1) {\n return configArr;\n }\n\n const choices = [\n {\n name: \"全部\",\n message: \"全部\",\n choices: configArr.map((item) => {\n return getChoiceItem(item);\n }),\n },\n ];\n const res = await prompt<{ enabled: string[] }>({\n type: \"multiselect\",\n message: \"选择要生效的配置项\",\n // @ts-ignore\n hint: \"(空格选中,回车确认)\",\n name: \"enabled\",\n validate(value) {\n return value.length === 0 ? `至少选择一项` : true;\n },\n choices,\n });\n\n configArr.forEach((item) => {\n item.enabled = opt.checkIsEnabled(res.enabled, item);\n });\n\n return configArr.filter((c) => c.enabled);\n}\n\nexport function promptI18nConfigEnable(configArr: I18nConfig[] | undefined) {\n return promptConfigEnable({\n configArr: configArr ?? [],\n getChoiceItem: (item) => {\n return {\n name: item.i18nDir!,\n hint: `sheetRange: ${item.sheetRange}`,\n };\n },\n checkIsEnabled: (enabledArr, item) => {\n return enabledArr.includes(item.i18nDir!);\n },\n });\n}\n\nexport function promptApiConfigEnable(configArr: ApiConfig[] | undefined) {\n return promptConfigEnable({\n configArr: configArr ?? [],\n getChoiceItem: (item) => {\n return {\n name: item.output!,\n hint: `swaggerJSONPath: ${item.swaggerJSONPath}`,\n };\n },\n checkIsEnabled: (enabledArr, item) => {\n return enabledArr.includes(item.output!);\n },\n });\n}\n"],"mappings":"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","names":["log","schema","_","data"]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|