cli-z-develop 0.14.9 → 0.14.10
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/index.js +61 -55
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -19,13 +19,13 @@ import zt from "semver";
|
|
|
19
19
|
import { run as Ft } from "npm-check-updates";
|
|
20
20
|
import Jt from "p-limit";
|
|
21
21
|
import { generateTypescriptBundleApi as Ut, validateSwagger as Bt, getParsedSwagger as Gt, generateTypescriptApi as _t } from "@lonely9/api-generate";
|
|
22
|
-
import { highlight as
|
|
22
|
+
import { highlight as Vt } from "cli-highlight";
|
|
23
23
|
import { ESLint as Ye } from "eslint";
|
|
24
|
-
import { readFileSync as
|
|
24
|
+
import { readFileSync as Wt } from "fs";
|
|
25
25
|
import qt from "prettier";
|
|
26
26
|
import Zt from "minimist";
|
|
27
27
|
const Qe = "dev", et = "test", tt = "release", Ht = "production", Kt = "master";
|
|
28
|
-
var E = /* @__PURE__ */ ((e) => (e[e.DEV = Qe] = "DEV", e[e.TEST = et] = "TEST", e[e.RELEASE = tt] = "RELEASE", e[e.PROD = Ht] = "PROD", e))(E || {}), $ = /* @__PURE__ */ ((e) => (e[e.DEV = Qe] = "DEV", e[e.TEST = et] = "TEST", e[e.RELEASE = tt] = "RELEASE", e[e.MASTER = Kt] = "MASTER", e))($ || {}),
|
|
28
|
+
var E = /* @__PURE__ */ ((e) => (e[e.DEV = Qe] = "DEV", e[e.TEST = et] = "TEST", e[e.RELEASE = tt] = "RELEASE", e[e.PROD = Ht] = "PROD", e))(E || {}), $ = /* @__PURE__ */ ((e) => (e[e.DEV = Qe] = "DEV", e[e.TEST = et] = "TEST", e[e.RELEASE = tt] = "RELEASE", e[e.MASTER = Kt] = "MASTER", e))($ || {}), W = /* @__PURE__ */ ((e) => (e.H5 = "h5", e.NPM = "npm", e.SERVER = "server", e))(W || {});
|
|
29
29
|
const at = [
|
|
30
30
|
{
|
|
31
31
|
name: `开发环境 - ${E.DEV}`,
|
|
@@ -129,7 +129,7 @@ function ot(e, t) {
|
|
|
129
129
|
const { red: _e, green: ca, blue: cs, magenta: ua, yellow: la } = N;
|
|
130
130
|
function ye(...e) {
|
|
131
131
|
}
|
|
132
|
-
function
|
|
132
|
+
function Ve(...e) {
|
|
133
133
|
console.log(la(...e));
|
|
134
134
|
}
|
|
135
135
|
function q(...e) {
|
|
@@ -143,11 +143,11 @@ function p(e, t = !1) {
|
|
|
143
143
|
let a = e;
|
|
144
144
|
e instanceof Error ? (a = e.message, le.isAxiosError(e) && (a = `请求失败:${e.message}`), console.log(_e(a)), console.log(ua(e.stack))) : console.log(_e(e)), t || process.exit(1);
|
|
145
145
|
}
|
|
146
|
-
function
|
|
146
|
+
function We(e) {
|
|
147
147
|
return A(e) ? It(e).isDirectory() : !1;
|
|
148
148
|
}
|
|
149
149
|
function ut(e = process.cwd()) {
|
|
150
|
-
return
|
|
150
|
+
return We(e) ? Rt(e).filter((a) => We(m.resolve(e, a))) : [];
|
|
151
151
|
}
|
|
152
152
|
async function d(e, t = {
|
|
153
153
|
removeTailLinkBreak: !0,
|
|
@@ -279,7 +279,7 @@ const wa = {
|
|
|
279
279
|
"**/*.{vue,js,jsx,cjs,mjs,ts,tsx,cts,mts}": "eslint --fix",
|
|
280
280
|
"**/*.md": "markdownlint --fix"
|
|
281
281
|
}
|
|
282
|
-
}, ya = "cli-z-develop", va = "0.14.
|
|
282
|
+
}, ya = "cli-z-develop", va = "0.14.10", $a = "技术团队开发流程管理工具", Na = "dist/index.js", Aa = { z: "bin/z.js", "z-develop": "bin/z.js" }, ba = { prepare: "[ -n '$z' ] && z init prepare || echo 'Warning: z not exist at global'", dev: "vite build --watch", test: "bun src/main.ts", "test:debug": "DEBUG=true bun src/main.ts", "dev:debug": "DEBUG=true vite build --watch", build: "vite build", "build:w": "vite build --watch", eslint: "eslint '**/*.{ts,js}' --fix", prettier: "prettier -wu .", upload: "npm run build && npm publish --access public --registry https://registry.npmjs.org/", "upload:patch": "npm version patch && npm run upload", "upload:minor": "npm version minor && npm run upload", "upload:major": "npm version major && npm run upload" }, ja = "module", Sa = "z", ka = { "@lonely9/eslint-config-team": "^1.3.8", "@tsconfig/node22": "^22.0.5", "@types/fs-extra": "^11.0.4", "@types/inquirer": "^9.0.9", "@types/minimist": "^1.2.5", "@types/node": "^22.15.29", "@types/semver": "^7.7.1", "@types/shelljs": "^0.10.0", "@typescript-eslint/eslint-plugin": "^8.58.2", "@typescript-eslint/parser": "^8.58.2", eslint: "^9.39.2", jiti: "^2.6.1", prettier: "^3.8.2", typescript: "^5.9.3", vite: "^7.3.1", "vue-tsc": "^3.2.6" }, Ea = { "@inquirer/prompts": "^8.4.1", "@lonely9/api-generate": "^0.2.9", axios: "^1.15.0", chalk: "^5.6.2", "cli-highlight": "^2.1.11", commander: "^14.0.3", dayjs: "^1.11.20", eslint: "^9.39.2", "fs-extra": "^11.3.4", "inquirer-select-pro": "^1.0.0-alpha.9", "lint-staged": "^16.4.0", minimist: "^1.2.8", "npm-check-updates": "^19.3.1", ora: "^9.3.0", "p-limit": "^7.3.0", prettier: "^3.8.2", semver: "^7.7.4", shelljs: "^0.10.0" }, re = {
|
|
283
283
|
name: ya,
|
|
284
284
|
version: va,
|
|
285
285
|
description: $a,
|
|
@@ -333,7 +333,7 @@ function ge(e) {
|
|
|
333
333
|
function B(e) {
|
|
334
334
|
return e ? x.constants[e] : x.constants;
|
|
335
335
|
}
|
|
336
|
-
let _ = null,
|
|
336
|
+
let _ = null, V = null;
|
|
337
337
|
function Pe() {
|
|
338
338
|
if (_)
|
|
339
339
|
return _;
|
|
@@ -341,18 +341,18 @@ function Pe() {
|
|
|
341
341
|
return A(e) || p(`当前目录(${L.pwd()})不存在${e}文件,请在项目根目录执行该命令。`), _ = I.readJsonSync(e), _;
|
|
342
342
|
}
|
|
343
343
|
function ie() {
|
|
344
|
-
if (
|
|
345
|
-
return
|
|
344
|
+
if (V)
|
|
345
|
+
return V;
|
|
346
346
|
const e = nt();
|
|
347
347
|
return A(e) || p(
|
|
348
348
|
`当前目录(${L.pwd()})不存在${e}文件,请在项目根目录执行该命令,或者初始化项目(z init .)。`
|
|
349
|
-
),
|
|
349
|
+
), V = I.readJsonSync(e), V;
|
|
350
350
|
}
|
|
351
351
|
function mt(e) {
|
|
352
|
-
|
|
353
|
-
...
|
|
352
|
+
V ? V = {
|
|
353
|
+
...V,
|
|
354
354
|
...e
|
|
355
|
-
} :
|
|
355
|
+
} : V = e, I.writeJSONSync(nt(), V, { spaces: 2 });
|
|
356
356
|
}
|
|
357
357
|
function Ta(e) {
|
|
358
358
|
_ ? _ = {
|
|
@@ -595,12 +595,12 @@ function _a() {
|
|
|
595
595
|
url: `${z()}/user`
|
|
596
596
|
});
|
|
597
597
|
}
|
|
598
|
-
function
|
|
598
|
+
function Va() {
|
|
599
599
|
return b({
|
|
600
600
|
url: `${z()}/groups`
|
|
601
601
|
});
|
|
602
602
|
}
|
|
603
|
-
function
|
|
603
|
+
function Wa(e) {
|
|
604
604
|
return b({
|
|
605
605
|
url: `${z()}/projects`,
|
|
606
606
|
method: "post",
|
|
@@ -664,7 +664,7 @@ function ei() {
|
|
|
664
664
|
return A(e) ? I.readJSONSync(e) : { groups: [] };
|
|
665
665
|
}
|
|
666
666
|
async function ti() {
|
|
667
|
-
const e = await
|
|
667
|
+
const e = await Va(), t = Qt.map((a) => {
|
|
668
668
|
const n = e.find((i) => i.name === a);
|
|
669
669
|
return n ? {
|
|
670
670
|
name: n.name,
|
|
@@ -1115,10 +1115,10 @@ async function qe(e, t) {
|
|
|
1115
1115
|
} catch {
|
|
1116
1116
|
}
|
|
1117
1117
|
if (i.length === 0)
|
|
1118
|
-
return
|
|
1118
|
+
return Ve("文件太大,无法生成commit msg"), t.stop(), await Ce();
|
|
1119
1119
|
const s = await d(`git diff HEAD -- ${i.map((r) => `"${r}"`).join(" ")}`);
|
|
1120
1120
|
if (!s)
|
|
1121
|
-
return
|
|
1121
|
+
return Ve("无法获取文件差异信息"), t.stop(), await Ce();
|
|
1122
1122
|
const o = await Ni({
|
|
1123
1123
|
type: "commit-message-v2",
|
|
1124
1124
|
input: s
|
|
@@ -1250,7 +1250,7 @@ async function zi() {
|
|
|
1250
1250
|
await d("npm install --registry https://registry.npmmirror.com/"), r.succeed("依赖安装完成");
|
|
1251
1251
|
const c = y("项目推送中").start();
|
|
1252
1252
|
await d('git add . && git commit -m "chore: 项目初始化"'), await d("git tag v0.0.1");
|
|
1253
|
-
const u = await
|
|
1253
|
+
const u = await Wa({
|
|
1254
1254
|
name: e.projectName,
|
|
1255
1255
|
description: e.projectDesc,
|
|
1256
1256
|
path: e.projectName,
|
|
@@ -1324,20 +1324,20 @@ const Ji = async (e) => {
|
|
|
1324
1324
|
};
|
|
1325
1325
|
function Ui(e, t) {
|
|
1326
1326
|
const a = Pe();
|
|
1327
|
-
if (ie()?.repository?.url || p(".z/project.json中缺少repository.url"), t ===
|
|
1327
|
+
if (ie()?.repository?.url || p(".z/project.json中缺少repository.url"), t === W.H5) {
|
|
1328
1328
|
const i = `build:${e}`;
|
|
1329
1329
|
a?.scripts[i] || p(`项目package.json文件scripts不存在命令${i}。`);
|
|
1330
1330
|
}
|
|
1331
|
-
t ===
|
|
1331
|
+
t === W.NPM && (a?.scripts.build || p("项目package.json文件scripts不存在命令build。")), t === W.SERVER && (a?.scripts.build || p("项目package.json文件scripts不存在命令build。"));
|
|
1332
1332
|
}
|
|
1333
1333
|
async function yt(e, t) {
|
|
1334
1334
|
ae(), K();
|
|
1335
1335
|
let a = e, n = t.platform;
|
|
1336
1336
|
const i = ie();
|
|
1337
|
-
if (i.language === w.JAVA && (n =
|
|
1337
|
+
if (i.language === w.JAVA && (n = W.SERVER), a && !Object.values($).includes(a) && p("仅支持发布指定环境分支"), n && !Object.values(W).includes(n) && p("发布平台错误"), n || (n = await k({
|
|
1338
1338
|
message: "请选择平台",
|
|
1339
1339
|
choices: Xt
|
|
1340
|
-
})), n ===
|
|
1340
|
+
})), n === W.NPM && (a = $.MASTER), !a) {
|
|
1341
1341
|
const u = await k({
|
|
1342
1342
|
message: "请选择部署环境",
|
|
1343
1343
|
choices: at
|
|
@@ -1497,8 +1497,8 @@ async function Gi(e, t) {
|
|
|
1497
1497
|
skipGroupNotification: t.skipGroupNotification
|
|
1498
1498
|
});
|
|
1499
1499
|
}
|
|
1500
|
-
P.command("merge").alias("m").description("合并当前分支到指定远程分支,并部署。").argument("[branch]", "目标分支名称").option("--deploy-platform <platform>", `合并成功后要部署的平台。可选值:${Object.values(
|
|
1501
|
-
P.command("deploy").alias("d").description("部署到指定环境").argument("[branchName]", `部署环境。可选值:${Object.values($).join("/")}`).option("--platform <platform>", `部署平台。可选值:${Object.values(
|
|
1500
|
+
P.command("merge").alias("m").description("合并当前分支到指定远程分支,并部署。").argument("[branch]", "目标分支名称").option("--deploy-platform <platform>", `合并成功后要部署的平台。可选值:${Object.values(W).join("/")}`).option("--deploy-skip-selection-notification", "部署时,是否跳过选择部署通知人环节").option("--skip-group-notification", "是否跳过选择部署通知群聊环节").option("--keep-branch-after-merge-master", "在合并到主分支之后,是否保留分支。默认否").action((...e) => M(Gi, ...e));
|
|
1501
|
+
P.command("deploy").alias("d").description("部署到指定环境").argument("[branchName]", `部署环境。可选值:${Object.values($).join("/")}`).option("--platform <platform>", `部署平台。可选值:${Object.values(W).join("/")}`).option("--module <module>", "部署模块。Java项目适用,填入要部署的模块名称,多个使用逗号分隔").option("--skip-selection-notification", "是否跳过选择部署通知人环节").option("--skip-group-notification", "是否跳过选择部署通知群聊环节").action((...e) => M(yt, ...e));
|
|
1502
1502
|
async function _i() {
|
|
1503
1503
|
try {
|
|
1504
1504
|
await d("java -jar ./.z/checkstyle.jar -c ./.z/checkstyle.xml .", {
|
|
@@ -1508,7 +1508,7 @@ async function _i() {
|
|
|
1508
1508
|
p("checkstyle执行出错"), process.exit(1);
|
|
1509
1509
|
}
|
|
1510
1510
|
}
|
|
1511
|
-
async function
|
|
1511
|
+
async function Vi() {
|
|
1512
1512
|
A(m.resolve("node_modules", ".bin", "markdownlint")) || p("该项目未安装markdownlint,请安装后重试");
|
|
1513
1513
|
const e = y("markdownlint执行中...").start();
|
|
1514
1514
|
try {
|
|
@@ -1519,7 +1519,7 @@ async function Wi() {
|
|
|
1519
1519
|
e.fail("markdownlint校验出错"), process.exit(1);
|
|
1520
1520
|
}
|
|
1521
1521
|
}
|
|
1522
|
-
function
|
|
1522
|
+
function Wi() {
|
|
1523
1523
|
const e = ie();
|
|
1524
1524
|
if (e["lint-staged"])
|
|
1525
1525
|
return e["lint-staged"];
|
|
@@ -1530,7 +1530,7 @@ async function qi() {
|
|
|
1530
1530
|
await Mt({
|
|
1531
1531
|
concurrent: 4,
|
|
1532
1532
|
debug: !1,
|
|
1533
|
-
config:
|
|
1533
|
+
config: Wi(),
|
|
1534
1534
|
quiet: !0,
|
|
1535
1535
|
relative: !0
|
|
1536
1536
|
}) ? (e.succeed("代码风格检测通过!"), process.exit(0)) : (e.fail("代码风格检测未通过!"), process.exit(1));
|
|
@@ -1688,7 +1688,7 @@ async function en(e, t) {
|
|
|
1688
1688
|
choices: i
|
|
1689
1689
|
});
|
|
1690
1690
|
}
|
|
1691
|
-
n === "commit-msg" ? await Hi() : n === "commit-files" ? await qi() : n === "prettier" ? await Yi() : n === "eslint" && [w.JAVASCRIPT, w.MARKDOWN].includes(a.language) ? await Xi(t) : n === "type-check" && [w.JAVASCRIPT, w.MARKDOWN].includes(a.language) ? Qi() : n === "dependency-check" && [w.JAVASCRIPT, w.MARKDOWN].includes(a.language) ? await Ki() : n === "checkstyle" && a.language === w.JAVA ? await _i() : n === "markdown-lint" && a.language === w.MARKDOWN && await
|
|
1691
|
+
n === "commit-msg" ? await Hi() : n === "commit-files" ? await qi() : n === "prettier" ? await Yi() : n === "eslint" && [w.JAVASCRIPT, w.MARKDOWN].includes(a.language) ? await Xi(t) : n === "type-check" && [w.JAVASCRIPT, w.MARKDOWN].includes(a.language) ? Qi() : n === "dependency-check" && [w.JAVASCRIPT, w.MARKDOWN].includes(a.language) ? await Ki() : n === "checkstyle" && a.language === w.JAVA ? await _i() : n === "markdown-lint" && a.language === w.MARKDOWN && await Vi();
|
|
1692
1692
|
}
|
|
1693
1693
|
P.command("run").alias("r").description("执行 eslint / prettier / type-check / dependency-check / checkstyle / markdown-lint。").argument(
|
|
1694
1694
|
"[type]",
|
|
@@ -2472,7 +2472,7 @@ ${e.map(t).join(`
|
|
|
2472
2472
|
const { apis: i } = await Gt(n, {
|
|
2473
2473
|
throwOnValidateError: !t
|
|
2474
2474
|
});
|
|
2475
|
-
a.push(...i.map((s) => ({ name: s.path
|
|
2475
|
+
a.push(...i.map((s) => ({ name: `${s.path}${s.summary ? `(${s.summary})` : ""}`, value: s.path })));
|
|
2476
2476
|
}
|
|
2477
2477
|
return H({
|
|
2478
2478
|
message: "请选择需要生成的API",
|
|
@@ -2482,7 +2482,12 @@ ${e.map(t).join(`
|
|
|
2482
2482
|
clearInputWhenSelected: !0,
|
|
2483
2483
|
multiple: !0,
|
|
2484
2484
|
validate: (n) => n.length ? !0 : "至少选择一个API",
|
|
2485
|
-
filter: !0
|
|
2485
|
+
filter: !0,
|
|
2486
|
+
theme: {
|
|
2487
|
+
style: {
|
|
2488
|
+
renderSelectedOptions: (n) => n.map((i) => i.value).join(", ")
|
|
2489
|
+
}
|
|
2490
|
+
}
|
|
2486
2491
|
});
|
|
2487
2492
|
}, En = async (e, t, a) => {
|
|
2488
2493
|
const n = y("API 开始生成...").start();
|
|
@@ -2495,9 +2500,10 @@ ${e.map(t).join(`
|
|
|
2495
2500
|
swaggerJson: i,
|
|
2496
2501
|
merge: !0,
|
|
2497
2502
|
controller: t,
|
|
2498
|
-
throwOnValidateError: !a
|
|
2503
|
+
throwOnValidateError: !a,
|
|
2504
|
+
importMethods: !1
|
|
2499
2505
|
});
|
|
2500
|
-
console.log(
|
|
2506
|
+
console.log(Vt(o, { language: "typescript", ignoreIllegals: !0 }));
|
|
2501
2507
|
}
|
|
2502
2508
|
n.start().succeed("API 生成成功");
|
|
2503
2509
|
} catch (i) {
|
|
@@ -2519,39 +2525,39 @@ ${e.map(t).join(`
|
|
|
2519
2525
|
const t = await Rn.lintFiles(e);
|
|
2520
2526
|
await Ye.outputFixes(t);
|
|
2521
2527
|
for (const a of e) {
|
|
2522
|
-
const n = m.resolve(a), i =
|
|
2528
|
+
const n = m.resolve(a), i = Wt(n, "utf-8"), s = await qt.format(i, {
|
|
2523
2529
|
filepath: n
|
|
2524
2530
|
});
|
|
2525
2531
|
xt(n, s);
|
|
2526
2532
|
}
|
|
2527
|
-
}, Cn = async (e, t, a
|
|
2528
|
-
const i = e.map((
|
|
2529
|
-
if (
|
|
2530
|
-
const
|
|
2531
|
-
await En(e,
|
|
2533
|
+
}, Cn = async (e, t, a) => {
|
|
2534
|
+
const { dir: n, skipSwaggerValidate: i } = t, s = e.map((o) => o.swaggerJson);
|
|
2535
|
+
if (a === "single") {
|
|
2536
|
+
const o = await kn(s, i);
|
|
2537
|
+
await En(e, o, i);
|
|
2532
2538
|
} else {
|
|
2533
|
-
const
|
|
2534
|
-
|
|
2535
|
-
swaggerJson:
|
|
2536
|
-
throwOnValidateError: !
|
|
2539
|
+
const o = y("API 开始生成...").start(), r = await Ut(
|
|
2540
|
+
s.map((f) => ({
|
|
2541
|
+
swaggerJson: f,
|
|
2542
|
+
throwOnValidateError: !i
|
|
2537
2543
|
}))
|
|
2538
2544
|
);
|
|
2539
|
-
|
|
2540
|
-
const
|
|
2541
|
-
Ue.mkdirSync(
|
|
2542
|
-
const
|
|
2543
|
-
|
|
2544
|
-
for (const
|
|
2545
|
-
const { path:
|
|
2546
|
-
|
|
2545
|
+
o.stop();
|
|
2546
|
+
const c = await Tn(n), u = m.resolve(c);
|
|
2547
|
+
Ue.mkdirSync(u, { recursive: !0 });
|
|
2548
|
+
const l = [];
|
|
2549
|
+
o.start(), o.text = "API 生成中...";
|
|
2550
|
+
for (const f of r) {
|
|
2551
|
+
const { path: h, content: g } = f, v = m.resolve(u, h);
|
|
2552
|
+
l.push(v), Ue.writeFileSync(v, g);
|
|
2547
2553
|
}
|
|
2548
|
-
|
|
2554
|
+
o.text = "开始格式化代码", await In(l), o.text = "代码格式化完成", o.succeed(`API 已生成到 ${c} 目录下`);
|
|
2549
2555
|
}
|
|
2550
2556
|
};
|
|
2551
2557
|
async function xn(e, t) {
|
|
2552
2558
|
ae(), K();
|
|
2553
|
-
const { moduleList: a } = await yn(), { module: n, env: i,
|
|
2554
|
-
await Cn(
|
|
2559
|
+
const { moduleList: a } = await yn(), { module: n, env: i, skipSwaggerValidate: s = !1 } = t, o = await $n(n, a), r = await Nn(i), c = await Sn(a, o, r, s), u = await vn(e);
|
|
2560
|
+
await Cn(c, t, u), process.exit(0);
|
|
2555
2561
|
}
|
|
2556
2562
|
P.command("api").alias("a").description("选择对应的服务端项目,获取接口并转成ts接口代码及类型").argument("[type]", "可选值为service单个服务, controller单个controller, single单个接口").option("--module [module]", "模块名称。多个使用逗号隔开").option("--env [env]", "指定环境。dev/test/release").option("--controller-name [controllerName]", "controller名称").option("--api-name [apiName]", "api名称").option("--skip-swagger-validate [skipSwaggerValidate]", "是否跳过 swagger 校验").action((...e) => M(xn, ...e));
|
|
2557
2563
|
function Pn() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cli-z-develop",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.10",
|
|
4
4
|
"description": "技术团队开发流程管理工具",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@inquirer/prompts": "^8.4.1",
|
|
47
|
-
"@lonely9/api-generate": "^0.2.
|
|
47
|
+
"@lonely9/api-generate": "^0.2.9",
|
|
48
48
|
"axios": "^1.15.0",
|
|
49
49
|
"chalk": "^5.6.2",
|
|
50
50
|
"cli-highlight": "^2.1.11",
|