@done-coding/cli-utils 0.3.0-alpha.0 → 0.3.1-alpha.0
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/es/index.mjs +193 -83
- package/package.json +11 -4
- package/types/config-file.d.ts +31 -0
- package/types/editor.d.ts +13 -0
- package/types/index.d.ts +4 -0
- package/types/json5.d.ts +3 -0
- package/types/lodash.d.ts +4 -0
package/es/index.mjs
CHANGED
|
@@ -1,39 +1,46 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
import { default as
|
|
4
|
-
import
|
|
5
|
-
import
|
|
2
|
+
import D from "chalk";
|
|
3
|
+
import { default as ce } from "chalk";
|
|
4
|
+
import a from "node:path";
|
|
5
|
+
import O, { existsSync as h, mkdirSync as k, writeFileSync as g, readFileSync as m } from "node:fs";
|
|
6
6
|
import l from "crypto";
|
|
7
7
|
import H from "prompts";
|
|
8
|
-
import
|
|
9
|
-
import { hideBin as
|
|
8
|
+
import E from "yargs";
|
|
9
|
+
import { hideBin as F } from "yargs/helpers";
|
|
10
|
+
import { execSync as y } from "node:child_process";
|
|
11
|
+
import v from "json5";
|
|
12
|
+
export * from "json5";
|
|
13
|
+
import { default as ue } from "json5";
|
|
14
|
+
import { default as pe } from "lodash.get";
|
|
15
|
+
import { default as ge } from "lodash.set";
|
|
16
|
+
import { default as ye } from "lodash.curry";
|
|
10
17
|
const i = Object.assign(
|
|
11
|
-
(
|
|
18
|
+
(e, ...o) => console.log(...o.map((r) => D[e](r))),
|
|
12
19
|
{
|
|
13
20
|
/** 成功 */
|
|
14
|
-
success: (...
|
|
21
|
+
success: (...e) => i("green", ...e),
|
|
15
22
|
/** /步骤 */
|
|
16
|
-
stage: (...
|
|
23
|
+
stage: (...e) => i("blue", ...e),
|
|
17
24
|
/** 提示信息 */
|
|
18
|
-
info: (...
|
|
25
|
+
info: (...e) => i("cyan", ...e),
|
|
19
26
|
/** 警告 */
|
|
20
|
-
warn: (...
|
|
27
|
+
warn: (...e) => i("yellow", ...e),
|
|
21
28
|
/** 错误 */
|
|
22
|
-
error: (...
|
|
29
|
+
error: (...e) => i("red", ...e),
|
|
23
30
|
/** 跳过 */
|
|
24
|
-
skip: (...
|
|
31
|
+
skip: (...e) => i("gray", ...e)
|
|
25
32
|
}
|
|
26
|
-
),
|
|
27
|
-
const
|
|
28
|
-
for (;
|
|
29
|
-
const
|
|
30
|
-
if (
|
|
31
|
-
return
|
|
33
|
+
), G = (e, o = process.cwd()) => {
|
|
34
|
+
const r = a.resolve(o).split(a.sep).map((t, n, c) => n ? a.join(c.slice(0, n).join(a.sep), t) : t);
|
|
35
|
+
for (; r.length; ) {
|
|
36
|
+
const t = r.pop(), n = a.join(t, e);
|
|
37
|
+
if (O.existsSync(n))
|
|
38
|
+
return t;
|
|
32
39
|
}
|
|
33
|
-
},
|
|
34
|
-
function
|
|
40
|
+
}, C = "aes-256-cbc", S = 16, p = "hex", d = ":";
|
|
41
|
+
function $(e) {
|
|
35
42
|
return l.pbkdf2Sync(
|
|
36
|
-
|
|
43
|
+
e,
|
|
37
44
|
"done-coding-cli-salt",
|
|
38
45
|
// 使用固定的盐值
|
|
39
46
|
1e4,
|
|
@@ -43,88 +50,191 @@ function y(r) {
|
|
|
43
50
|
"sha256"
|
|
44
51
|
);
|
|
45
52
|
}
|
|
46
|
-
function
|
|
47
|
-
text:
|
|
48
|
-
secretKey:
|
|
53
|
+
function Q({
|
|
54
|
+
text: e,
|
|
55
|
+
secretKey: o
|
|
49
56
|
}) {
|
|
50
57
|
try {
|
|
51
|
-
const
|
|
52
|
-
let
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
return `${
|
|
56
|
-
} catch (
|
|
58
|
+
const r = $(o), t = l.randomBytes(S), n = l.createCipheriv(C, r, t);
|
|
59
|
+
let c = n.update(e);
|
|
60
|
+
c = Buffer.concat([c, n.final()]);
|
|
61
|
+
const u = t.toString(p), s = c.toString(p);
|
|
62
|
+
return `${u}${d}${s}`;
|
|
63
|
+
} catch (r) {
|
|
57
64
|
return i.error(
|
|
58
|
-
`加密失败: ${
|
|
65
|
+
`加密失败: ${r instanceof Error ? r.message : String(r)}`
|
|
59
66
|
), "";
|
|
60
67
|
}
|
|
61
68
|
}
|
|
62
|
-
function
|
|
63
|
-
encryptedText:
|
|
64
|
-
secretKey:
|
|
69
|
+
function X({
|
|
70
|
+
encryptedText: e,
|
|
71
|
+
secretKey: o
|
|
65
72
|
}) {
|
|
66
73
|
try {
|
|
67
|
-
if (!
|
|
74
|
+
if (!e.includes(d))
|
|
68
75
|
return "";
|
|
69
|
-
const
|
|
70
|
-
if (
|
|
76
|
+
const r = $(o), [t, n] = e.split(d);
|
|
77
|
+
if (t.length !== S * 2)
|
|
71
78
|
return "";
|
|
72
|
-
const
|
|
73
|
-
let
|
|
74
|
-
return
|
|
75
|
-
} catch (
|
|
79
|
+
const c = Buffer.from(t, p), u = Buffer.from(n, p), s = l.createDecipheriv(C, r, c);
|
|
80
|
+
let f = s.update(u);
|
|
81
|
+
return f = Buffer.concat([f, s.final()]), f.toString();
|
|
82
|
+
} catch (r) {
|
|
76
83
|
return i.error(
|
|
77
|
-
`解密失败: ${
|
|
84
|
+
`解密失败: ${r instanceof Error ? r.message : String(r)}`
|
|
78
85
|
), "";
|
|
79
86
|
}
|
|
80
87
|
}
|
|
81
|
-
const
|
|
82
|
-
const [
|
|
83
|
-
return H(
|
|
84
|
-
onCancel(
|
|
85
|
-
return i.error(`退出${
|
|
88
|
+
const x = (...e) => {
|
|
89
|
+
const [o, r = {}] = e;
|
|
90
|
+
return H(o, {
|
|
91
|
+
onCancel(t) {
|
|
92
|
+
return i.error(`退出${t == null ? void 0 : t.name}输入`), process.exit(1);
|
|
86
93
|
},
|
|
87
|
-
...
|
|
94
|
+
...r
|
|
88
95
|
});
|
|
89
|
-
},
|
|
90
|
-
|
|
91
|
-
},
|
|
92
|
-
const
|
|
93
|
-
return
|
|
94
|
-
},
|
|
95
|
-
usage:
|
|
96
|
-
version:
|
|
97
|
-
demandCommandCount:
|
|
98
|
-
options:
|
|
99
|
-
positionals:
|
|
100
|
-
subcommands:
|
|
96
|
+
}, R = (e, o) => {
|
|
97
|
+
e ? i.error(e) : i.error(o.message), o != null && o.stack && i.error(o.stack), process.exit(1);
|
|
98
|
+
}, T = () => {
|
|
99
|
+
const e = F(process.argv);
|
|
100
|
+
return E(e);
|
|
101
|
+
}, j = (e, {
|
|
102
|
+
usage: o,
|
|
103
|
+
version: r,
|
|
104
|
+
demandCommandCount: t,
|
|
105
|
+
options: n,
|
|
106
|
+
positionals: c,
|
|
107
|
+
subcommands: u
|
|
101
108
|
}) => {
|
|
102
|
-
let
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
return
|
|
106
|
-
},
|
|
107
|
-
const
|
|
108
|
-
return
|
|
109
|
-
},
|
|
110
|
-
const { command:
|
|
111
|
-
}, ...
|
|
109
|
+
let s = e.strict();
|
|
110
|
+
o && (s = s.usage(`Usage: ${o}`)), t && (s = s.demandCommand(t));
|
|
111
|
+
const f = "help";
|
|
112
|
+
return s = s.help(f), r ? s = s.version(r).alias("h", f).alias("v", "version") : s = s.alias("h", f), n && (s = s.options(n)), c && (s = Object.entries(c).reduce((w, [P, b]) => w.positional(P, b), s)), u && (s = s.command(u)), s;
|
|
113
|
+
}, Z = async ({ handler: e, ...o }) => {
|
|
114
|
+
const r = await j(T(), o).fail(R).argv;
|
|
115
|
+
return e ? e(r) : r;
|
|
116
|
+
}, ee = (e) => {
|
|
117
|
+
const { command: o, describe: r, handler: t = () => {
|
|
118
|
+
}, ...n } = e;
|
|
112
119
|
return {
|
|
113
|
-
command:
|
|
114
|
-
describe:
|
|
115
|
-
builder(
|
|
116
|
-
return
|
|
120
|
+
command: o,
|
|
121
|
+
describe: r,
|
|
122
|
+
builder(c) {
|
|
123
|
+
return j(c, n);
|
|
117
124
|
},
|
|
118
|
-
handler:
|
|
125
|
+
handler: t
|
|
119
126
|
};
|
|
120
127
|
};
|
|
128
|
+
var _ = /* @__PURE__ */ ((e) => (e.VSCODE = "VsCode", e.CURSOR = "Cursor", e.OTHER = "其他", e))(_ || {});
|
|
129
|
+
const A = async () => {
|
|
130
|
+
const { editorType: e } = await x([
|
|
131
|
+
{
|
|
132
|
+
name: "editorType",
|
|
133
|
+
type: "select",
|
|
134
|
+
message: "编辑器类型",
|
|
135
|
+
choices: [
|
|
136
|
+
"Cursor",
|
|
137
|
+
"VsCode",
|
|
138
|
+
"其他"
|
|
139
|
+
/* OTHER */
|
|
140
|
+
].map((o) => ({
|
|
141
|
+
title: o,
|
|
142
|
+
value: o
|
|
143
|
+
}))
|
|
144
|
+
}
|
|
145
|
+
]);
|
|
146
|
+
return e;
|
|
147
|
+
}, B = {
|
|
148
|
+
Cursor: "cursor",
|
|
149
|
+
VsCode: "code"
|
|
150
|
+
}, N = (e, o, r) => {
|
|
151
|
+
try {
|
|
152
|
+
y(`${e} -v`, { stdio: "ignore" }), y(`${e} ${o}`);
|
|
153
|
+
} catch {
|
|
154
|
+
r();
|
|
155
|
+
}
|
|
156
|
+
}, V = (e, o) => {
|
|
157
|
+
const r = (t) => i.info(`
|
|
158
|
+
${t}, 请用编辑器打开 ${e} 进行编辑
|
|
159
|
+
`);
|
|
160
|
+
switch (o) {
|
|
161
|
+
case "Cursor":
|
|
162
|
+
case "VsCode": {
|
|
163
|
+
const t = B[o];
|
|
164
|
+
N(t, e, () => {
|
|
165
|
+
r(`${t}命令未安装`);
|
|
166
|
+
});
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
default:
|
|
170
|
+
r("其他编辑器");
|
|
171
|
+
}
|
|
172
|
+
}, re = ({
|
|
173
|
+
configPathDefault: e
|
|
174
|
+
}) => ({
|
|
175
|
+
/** 必须保留 */
|
|
176
|
+
rootDir: {
|
|
177
|
+
type: "string",
|
|
178
|
+
alias: "r",
|
|
179
|
+
describe: "运行目录",
|
|
180
|
+
/** 必须设置默认值 */
|
|
181
|
+
default: process.cwd()
|
|
182
|
+
},
|
|
183
|
+
/** 必须保留 */
|
|
184
|
+
configPath: {
|
|
185
|
+
type: "string",
|
|
186
|
+
alias: "c",
|
|
187
|
+
describe: "配置文件相对路径",
|
|
188
|
+
/** 必须设置默认值 */
|
|
189
|
+
default: e
|
|
190
|
+
}
|
|
191
|
+
}), L = async (e, o) => {
|
|
192
|
+
const { configPath: r, rootDir: t } = o, n = a.resolve(t, r), c = a.dirname(n);
|
|
193
|
+
return h(c) || k(c, {
|
|
194
|
+
recursive: !0
|
|
195
|
+
}), n.endsWith(".json5") ? (i.info(`json5模式写入 ${n}`), g(n, v.stringify(e, null, 2)), n) : (i.info(`json模式写入 ${n}`), g(n, JSON.stringify(e, null, 2)), n);
|
|
196
|
+
}, te = async (e, o, {
|
|
197
|
+
onFileGenerated: r
|
|
198
|
+
} = {}) => {
|
|
199
|
+
const t = await L(e, o);
|
|
200
|
+
r == null || r(t);
|
|
201
|
+
const n = await A();
|
|
202
|
+
V(o.configPath, n);
|
|
203
|
+
}, oe = async (e) => {
|
|
204
|
+
const { configPath: o, rootDir: r } = e, t = a.resolve(r, o);
|
|
205
|
+
if (!h(t)) {
|
|
206
|
+
i.warn(`配置文件不存在 ${t}`);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
return t.endsWith(".json5") ? (i.info(`json5模式解析 ${t}`), v.parse(m(t, "utf8"))) : (i.info(`json模式解析 ${t}`), JSON.parse(m(t, "utf8")));
|
|
210
|
+
}, ne = async () => {
|
|
211
|
+
const { useDefaultConfig: e } = await x({
|
|
212
|
+
name: "useDefaultConfig",
|
|
213
|
+
type: "confirm",
|
|
214
|
+
message: "使用默认模板配置",
|
|
215
|
+
initial: !0
|
|
216
|
+
});
|
|
217
|
+
return e;
|
|
218
|
+
};
|
|
121
219
|
export {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
220
|
+
_ as EditorTypeEnum,
|
|
221
|
+
ye as _curry,
|
|
222
|
+
pe as _get,
|
|
223
|
+
ge as _set,
|
|
224
|
+
ce as chalk,
|
|
225
|
+
Z as createMainCommand,
|
|
226
|
+
ee as createSubcommand,
|
|
227
|
+
X as decryptAES,
|
|
228
|
+
Q as encryptAES,
|
|
229
|
+
re as getConfigFileCommonOptions,
|
|
230
|
+
A as getEditorType,
|
|
231
|
+
ne as getUseDefaultConfig,
|
|
232
|
+
L as initConfigFile,
|
|
233
|
+
te as initHandlerCommon,
|
|
234
|
+
ue as json5,
|
|
127
235
|
i as log,
|
|
128
|
-
|
|
129
|
-
|
|
236
|
+
G as lookForParentTarget,
|
|
237
|
+
V as openFileInEditor,
|
|
238
|
+
oe as readConfigFile,
|
|
239
|
+
x as xPrompts
|
|
130
240
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@done-coding/cli-utils",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1-alpha.0",
|
|
4
4
|
"description": "cli utils",
|
|
5
5
|
"private": false,
|
|
6
6
|
"module": "es/index.mjs",
|
|
@@ -14,8 +14,7 @@
|
|
|
14
14
|
"files": [
|
|
15
15
|
"es",
|
|
16
16
|
"lib",
|
|
17
|
-
"types"
|
|
18
|
-
"gif"
|
|
17
|
+
"types"
|
|
19
18
|
],
|
|
20
19
|
"scripts": {
|
|
21
20
|
"clean": "rimraf es lib types",
|
|
@@ -38,6 +37,10 @@
|
|
|
38
37
|
"license": "MIT",
|
|
39
38
|
"sideEffects": false,
|
|
40
39
|
"devDependencies": {
|
|
40
|
+
"@types/json5": "^2.2.0",
|
|
41
|
+
"@types/lodash.curry": "^4.1.8",
|
|
42
|
+
"@types/lodash.get": "^4.4.9",
|
|
43
|
+
"@types/lodash.set": "^4.3.9",
|
|
41
44
|
"@types/node": "^18.0.0",
|
|
42
45
|
"@types/prompts": "^2.4.6",
|
|
43
46
|
"@types/yargs": "^17.0.28",
|
|
@@ -51,8 +54,12 @@
|
|
|
51
54
|
},
|
|
52
55
|
"dependencies": {
|
|
53
56
|
"chalk": "^5.3.0",
|
|
57
|
+
"json5": "^2.2.3",
|
|
58
|
+
"lodash.curry": "^4.1.1",
|
|
59
|
+
"lodash.get": "^4.4.2",
|
|
60
|
+
"lodash.set": "^4.3.2",
|
|
54
61
|
"prompts": "^2.4.2",
|
|
55
62
|
"yargs": "^17.7.2"
|
|
56
63
|
},
|
|
57
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "ec6957606bbae68d7268159b38b9d36dab4a2731"
|
|
58
65
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { CliHandlerArgv, YargsOptions } from "./cli";
|
|
2
|
+
/** 配置文件通用选项 */
|
|
3
|
+
export interface ConfigFileCommonOptions {
|
|
4
|
+
/**
|
|
5
|
+
* 相对于路径
|
|
6
|
+
* ---
|
|
7
|
+
* 绝对路径 path.resolve(rootDir, configPath)
|
|
8
|
+
*/
|
|
9
|
+
configPath: string;
|
|
10
|
+
/** 项目根目录 */
|
|
11
|
+
rootDir: string;
|
|
12
|
+
}
|
|
13
|
+
/** 初始化文件选项 */
|
|
14
|
+
export type InitConfigFileOptions = ConfigFileCommonOptions;
|
|
15
|
+
/** 读取配置文件选项 */
|
|
16
|
+
export type ReadConfigFileOptions = ConfigFileCommonOptions;
|
|
17
|
+
/** 获取配置文件通用选项 */
|
|
18
|
+
export declare const getConfigFileCommonOptions: ({ configPathDefault, }: {
|
|
19
|
+
configPathDefault: string;
|
|
20
|
+
}) => Record<keyof ConfigFileCommonOptions, YargsOptions>;
|
|
21
|
+
/** 初始化配置文件 */
|
|
22
|
+
export declare const initConfigFile: <T>(content: T, argv: CliHandlerArgv<InitConfigFileOptions>) => Promise<string>;
|
|
23
|
+
/** 初始化配置文件通用处理器 */
|
|
24
|
+
export declare const initHandlerCommon: <T>(content: T, argv: CliHandlerArgv<InitConfigFileOptions>, { onFileGenerated, }?: {
|
|
25
|
+
/** 文件已生成 */
|
|
26
|
+
onFileGenerated?: ((path: string) => void) | undefined;
|
|
27
|
+
}) => Promise<void>;
|
|
28
|
+
/** 读取配置文件 */
|
|
29
|
+
export declare const readConfigFile: <T>(argv: CliHandlerArgv<ReadConfigFileOptions>) => Promise<T | undefined>;
|
|
30
|
+
/** 获取是否使用默认配置 */
|
|
31
|
+
export declare const getUseDefaultConfig: () => Promise<any>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** 编辑器类型枚举 */
|
|
2
|
+
export declare enum EditorTypeEnum {
|
|
3
|
+
/** vscode */
|
|
4
|
+
VSCODE = "VsCode",
|
|
5
|
+
/** cursor */
|
|
6
|
+
CURSOR = "Cursor",
|
|
7
|
+
/** 其他编辑器 */
|
|
8
|
+
OTHER = "\u5176\u4ED6"
|
|
9
|
+
}
|
|
10
|
+
/** 获取编辑器类型 */
|
|
11
|
+
export declare const getEditorType: () => Promise<any>;
|
|
12
|
+
/** 用编辑器打开文件 */
|
|
13
|
+
export declare const openFileInEditor: (path: string, editorType: EditorTypeEnum) => void;
|
package/types/index.d.ts
CHANGED
package/types/json5.d.ts
ADDED