fenge 0.7.7 → 0.8.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/CHANGELOG.md +22 -0
- package/README.md +1 -21
- package/package.json +5 -9
- package/src/bin/fenge.cli.js +5 -22
- package/src/command/format.js +9 -8
- package/src/command/lint.js +5 -4
- package/src/utils.js +16 -13
- package/types/index.d.ts +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# fenge
|
|
2
2
|
|
|
3
|
+
## 0.8.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 8e6f32a: refactor(fenge)!: remove `@fenge/types`, drop support for type patches
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 57b9b81: chore: upgrade deps
|
|
12
|
+
- Updated dependencies [aa7d44f]
|
|
13
|
+
- Updated dependencies [57b9b81]
|
|
14
|
+
- Updated dependencies [fa9dc89]
|
|
15
|
+
- @fenge/eslint-config@0.6.9
|
|
16
|
+
- @fenge/prettier-config@0.3.1
|
|
17
|
+
|
|
18
|
+
## 0.7.8
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- Updated dependencies [3c6eafe]
|
|
23
|
+
- @fenge/eslint-config@0.6.8
|
|
24
|
+
|
|
3
25
|
## 0.7.7
|
|
4
26
|
|
|
5
27
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -126,7 +126,7 @@ In summary, Type Safety, Formatting, and Linting are three indispensable aspects
|
|
|
126
126
|
|
|
127
127
|
Based on the philosophy outlined above, this tool offers the following features:
|
|
128
128
|
|
|
129
|
-
- 💪 **Enhanced Type Safety**: This tool provides the strictest `tsconfig` settings
|
|
129
|
+
- 💪 **Enhanced Type Safety**: This tool provides the strictest `tsconfig` settings to bolster the type safety of TypeScript projects. It is also compatible with pure JavaScript projects.
|
|
130
130
|
- 💃 **Formatting**: This tool ensures code consistency across your codebase and minimizes merge conflicts by automatically formatting code. It additionally supports the sorting of imports and `package.json` files.
|
|
131
131
|
- 📏 **Linting**: This tool comes equipped with a comprehensive set of rules for static code analysis, which helps catch errors and prevent poor coding practices in JavaScript.
|
|
132
132
|
- 🪝 **Git Hooks**: After installation, committing code via Git triggers automatic formatting and linting checks. No additional package installations are required.
|
|
@@ -195,26 +195,6 @@ tsc -p ./tsconfig.build.json --noEmit
|
|
|
195
195
|
|
|
196
196
|
For more beat practices, please refer to [@fenge/tsconfig](https://www.npmjs.com/package/@fenge/tsconfig).
|
|
197
197
|
|
|
198
|
-
#### Import type patch
|
|
199
|
-
|
|
200
|
-
Add a [triple-slash-directive](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html) `/// <reference types="fenge/types" />` at the top of the ts file that serves as the entry point for your application or package. This will make the entire project more type-safe. The built-in type patch `fenge/types` re-exports from [@fenge/types](https://www.npmjs.com/package/@fenge/types).
|
|
201
|
-
|
|
202
|
-
Application/Package Entry Point (eg: `src/main.ts` or `src/app.ts`)
|
|
203
|
-
|
|
204
|
-
```ts
|
|
205
|
-
/// <reference types="fenge/types" />
|
|
206
|
-
import foo from "./foo";
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
Other File (eg: `src/other-file.ts`)
|
|
210
|
-
|
|
211
|
-
<!-- prettier-ignore-start -->
|
|
212
|
-
```ts
|
|
213
|
-
console.log(JSON.parse('{"foo":"foo"}').bar.length);
|
|
214
|
-
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ❌ Object is of type 'unknown'.
|
|
215
|
-
```
|
|
216
|
-
<!-- prettier-ignore-end -->
|
|
217
|
-
|
|
218
198
|
### Formatting & Linting
|
|
219
199
|
|
|
220
200
|
Here are some main commands to format or lint code.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fenge",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "A CLI tool for code quality",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -32,9 +32,6 @@
|
|
|
32
32
|
"exports": {
|
|
33
33
|
"./eslint-config": "./src/re-export/eslint.config.js",
|
|
34
34
|
"./prettier-config": "./src/re-export/prettier.config.js",
|
|
35
|
-
"./types": {
|
|
36
|
-
"types": "./types/index.d.ts"
|
|
37
|
-
},
|
|
38
35
|
"./tsconfig": "./tsconfig/index.json",
|
|
39
36
|
"./tsconfig.json": "./tsconfig/index.json",
|
|
40
37
|
"./tsconfig/esm": "./tsconfig/esm.json",
|
|
@@ -47,15 +44,14 @@
|
|
|
47
44
|
"commander": "13.1.0",
|
|
48
45
|
"eslint": "9.22.0",
|
|
49
46
|
"lilconfig": "3.1.3",
|
|
50
|
-
"lint-staged": "15.5.
|
|
47
|
+
"lint-staged": "15.5.2",
|
|
51
48
|
"ora": "8.2.0",
|
|
52
49
|
"prettier": "3.5.3",
|
|
53
50
|
"yoctocolors": "2.1.1",
|
|
54
|
-
"@fenge/eslint-config": "0.6.7",
|
|
55
|
-
"@fenge/prettier-config": "0.3.0",
|
|
56
51
|
"@fenge/tsconfig": "0.5.0",
|
|
57
|
-
"
|
|
58
|
-
"
|
|
52
|
+
"prettier-ignore": "0.3.0",
|
|
53
|
+
"@fenge/eslint-config": "0.6.9",
|
|
54
|
+
"@fenge/prettier-config": "0.3.1"
|
|
59
55
|
},
|
|
60
56
|
"devDependencies": {
|
|
61
57
|
"@types/node": "22.14.1"
|
package/src/bin/fenge.cli.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// @ts-check
|
|
3
|
-
import os from "node:os";
|
|
4
3
|
import process from "node:process";
|
|
5
4
|
import { initAction, setup } from "@fenge/tsconfig/setup";
|
|
6
5
|
import { Command } from "commander";
|
|
@@ -10,22 +9,6 @@ import { install } from "../command/install.js";
|
|
|
10
9
|
import { lint } from "../command/lint.js";
|
|
11
10
|
import { uninstall } from "../command/uninstall.js";
|
|
12
11
|
|
|
13
|
-
/**
|
|
14
|
-
* @param {{code: number|null, signal: NodeJS.Signals | null}} param
|
|
15
|
-
* @returns {never}
|
|
16
|
-
*/
|
|
17
|
-
function exit({ code, signal }) {
|
|
18
|
-
if (code !== null) {
|
|
19
|
-
process.exit(code);
|
|
20
|
-
} else if (signal !== null) {
|
|
21
|
-
process.exit(128 + os.constants.signals[signal]);
|
|
22
|
-
} else {
|
|
23
|
-
throw new Error(
|
|
24
|
-
"Internal Error. Code and signal should not be null at the same time.",
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
12
|
const program = new Command().enablePositionalOptions();
|
|
30
13
|
|
|
31
14
|
program
|
|
@@ -53,13 +36,13 @@ program
|
|
|
53
36
|
.argument("[paths...]", "dir or file paths to format and lint")
|
|
54
37
|
.action(async (paths, options) => {
|
|
55
38
|
let result = await format(paths, options);
|
|
56
|
-
if (result
|
|
39
|
+
if (result === 0) {
|
|
57
40
|
result = await lint(paths, options);
|
|
58
|
-
if (result
|
|
41
|
+
if (result === 0) {
|
|
59
42
|
result = await format(paths, options);
|
|
60
43
|
}
|
|
61
44
|
}
|
|
62
|
-
exit(result);
|
|
45
|
+
process.exit(result);
|
|
63
46
|
});
|
|
64
47
|
|
|
65
48
|
program
|
|
@@ -78,7 +61,7 @@ program
|
|
|
78
61
|
"print what command will be executed under the hood instead of executing",
|
|
79
62
|
)
|
|
80
63
|
.argument("[paths...]", "dir or file paths to lint")
|
|
81
|
-
.action(async (paths, options) => exit(await lint(paths, options)));
|
|
64
|
+
.action(async (paths, options) => process.exit(await lint(paths, options)));
|
|
82
65
|
|
|
83
66
|
program
|
|
84
67
|
.command("format")
|
|
@@ -95,7 +78,7 @@ program
|
|
|
95
78
|
"print what command will be executed under the hood instead of executing",
|
|
96
79
|
)
|
|
97
80
|
.argument("[paths...]", "dir or file paths to format")
|
|
98
|
-
.action(async (paths, options) => exit(await format(paths, options)));
|
|
81
|
+
.action(async (paths, options) => process.exit(await format(paths, options)));
|
|
99
82
|
|
|
100
83
|
program
|
|
101
84
|
.command("install")
|
package/src/command/format.js
CHANGED
|
@@ -8,23 +8,24 @@ import { dir, execAsync, getBinPath } from "../utils.js";
|
|
|
8
8
|
* @param {Array<string>} paths
|
|
9
9
|
* @param {{update?: boolean, write?: boolean, dryRun?: boolean, config?: string, default?: boolean}} options
|
|
10
10
|
*/
|
|
11
|
-
export async function format(
|
|
12
|
-
|
|
11
|
+
export async function format(
|
|
12
|
+
paths = [],
|
|
13
|
+
{
|
|
13
14
|
update = false,
|
|
14
15
|
write = false,
|
|
15
16
|
dryRun = false,
|
|
16
17
|
config,
|
|
17
18
|
default: useDefaultConfig = false,
|
|
18
|
-
} =
|
|
19
|
-
|
|
20
|
-
const ignores = [".gitignore", ".prettierignore", prettierignore]
|
|
21
|
-
.map((p) => path.resolve(p))
|
|
22
|
-
.flatMap((p) => ["--ignore-path", p]);
|
|
19
|
+
} = {},
|
|
20
|
+
) {
|
|
23
21
|
return execAsync(
|
|
24
22
|
[
|
|
25
23
|
// "node",
|
|
26
24
|
await getPrettierPath(useDefaultConfig),
|
|
27
|
-
|
|
25
|
+
// setup 3 ignore files
|
|
26
|
+
...[".gitignore", ".prettierignore", prettierignore]
|
|
27
|
+
.map((p) => path.resolve(p))
|
|
28
|
+
.flatMap((p) => ["--ignore-path", p]),
|
|
28
29
|
"--log-level",
|
|
29
30
|
"warn",
|
|
30
31
|
"--config",
|
package/src/command/lint.js
CHANGED
|
@@ -7,16 +7,17 @@ import { dir, execAsync, getBinPath } from "../utils.js";
|
|
|
7
7
|
* @param {Array<string>} paths
|
|
8
8
|
* @param {{update?: boolean, fix?: boolean, dryRun?: boolean, config?: string, default?: boolean, timing?: boolean}} options
|
|
9
9
|
*/
|
|
10
|
-
export async function lint(
|
|
11
|
-
|
|
10
|
+
export async function lint(
|
|
11
|
+
paths = [],
|
|
12
|
+
{
|
|
12
13
|
update = false,
|
|
13
14
|
fix = false,
|
|
14
15
|
dryRun = false,
|
|
15
16
|
config,
|
|
16
17
|
default: useDefaultConfig = false,
|
|
17
18
|
timing = false,
|
|
18
|
-
} =
|
|
19
|
-
|
|
19
|
+
} = {},
|
|
20
|
+
) {
|
|
20
21
|
return execAsync(
|
|
21
22
|
[
|
|
22
23
|
// "node",
|
package/src/utils.js
CHANGED
|
@@ -3,6 +3,7 @@ import { Buffer } from "node:buffer";
|
|
|
3
3
|
import childProcess from "node:child_process";
|
|
4
4
|
import fs from "node:fs/promises";
|
|
5
5
|
import { createRequire } from "node:module";
|
|
6
|
+
import os from "node:os";
|
|
6
7
|
import path from "node:path";
|
|
7
8
|
import process from "node:process";
|
|
8
9
|
import { fileURLToPath } from "node:url";
|
|
@@ -58,21 +59,20 @@ function getSpentTime(startTime) {
|
|
|
58
59
|
/**
|
|
59
60
|
* @param {string[]} command
|
|
60
61
|
* @param {{topic: string, dryRun: boolean, env: Record<string, string>}} options
|
|
61
|
-
* @returns {Promise<
|
|
62
|
+
* @returns {Promise<number>}
|
|
62
63
|
*/
|
|
63
64
|
export function execAsync(command, { topic, dryRun, env }) {
|
|
65
|
+
const [cmd, ...args] = command;
|
|
66
|
+
if (!cmd) {
|
|
67
|
+
return Promise.reject(new Error("cmd not found"));
|
|
68
|
+
}
|
|
69
|
+
if (dryRun) {
|
|
70
|
+
process.stdout.write(`${colors.green(cmd)} ${args.join(" ")};\n\n`);
|
|
71
|
+
return Promise.resolve(0);
|
|
72
|
+
}
|
|
73
|
+
|
|
64
74
|
return new Promise((resolve, reject) => {
|
|
65
75
|
const startTime = Date.now();
|
|
66
|
-
|
|
67
|
-
const [cmd, ...args] = command;
|
|
68
|
-
if (!cmd) {
|
|
69
|
-
return reject(new Error("cmd not found"));
|
|
70
|
-
}
|
|
71
|
-
if (dryRun) {
|
|
72
|
-
process.stdout.write(`${colors.green(cmd)} ${args.join(" ")};\n\n`);
|
|
73
|
-
return resolve({ code: 0, signal: null });
|
|
74
|
-
}
|
|
75
|
-
|
|
76
76
|
const spinner = ora(`${topic}...`).start();
|
|
77
77
|
/**
|
|
78
78
|
* @type {childProcess.ChildProcessWithoutNullStreams | undefined}
|
|
@@ -106,8 +106,11 @@ export function execAsync(command, { topic, dryRun, env }) {
|
|
|
106
106
|
}
|
|
107
107
|
process.stdout.write(stdout);
|
|
108
108
|
process.stderr.write(stderr);
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
// When the cp exited, we should clean cp and the buffer to prevent memory leak.
|
|
110
|
+
stdout = Buffer.alloc(0);
|
|
111
|
+
stderr = Buffer.alloc(0);
|
|
112
|
+
cp = undefined;
|
|
113
|
+
resolve(code ?? (signal ? 128 + os.constants.signals[signal] : 1));
|
|
111
114
|
});
|
|
112
115
|
|
|
113
116
|
/**
|
package/types/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import "@fenge/types";
|