fenge 0.1.2 → 0.1.4
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 +15 -0
- package/README.md +39 -34
- package/package.json +4 -4
- package/src/bin/cli.js +1 -0
- package/src/command/format.js +8 -4
- package/src/command/lint.js +8 -4
- package/src/config/eslint.config.js +9 -1
- package/src/config/prettier.config.js +9 -1
- package/src/utils.js +6 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# fenge
|
|
2
2
|
|
|
3
|
+
## 0.1.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 3783bd5: feat(fenge): `format` and `lint` properties in `fenge.config.js` are additionally accepting a function now
|
|
8
|
+
|
|
9
|
+
## 0.1.3
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- a9afc71: feat(fenge): support `--config` option
|
|
14
|
+
- Updated dependencies [9e94865]
|
|
15
|
+
- @fenge/prettier-config@0.1.1
|
|
16
|
+
- @fenge/eslint-config@0.1.3
|
|
17
|
+
|
|
3
18
|
## 0.1.2
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -195,16 +195,18 @@ $ fenge -u
|
|
|
195
195
|
|
|
196
196
|
This tool does not require a configuration file. However, you can add a `fenge.config.js` file to customize formatting and linting rules. This file should export an object with two properties:
|
|
197
197
|
|
|
198
|
-
- `format`: Accept a [Prettier Config](https://prettier.io/docs/en/configuration.html).
|
|
199
|
-
- `lint`: Accept a [ESLint Flat Config](https://eslint.org/docs/latest/use/configure/configuration-files).
|
|
198
|
+
- `format`: Accept a function that returns a [Prettier Config](https://prettier.io/docs/en/configuration.html).
|
|
199
|
+
- `lint`: Accept a function that returns an [ESLint Flat Config](https://eslint.org/docs/latest/use/configure/configuration-files).
|
|
200
|
+
|
|
201
|
+
> Tips: These two functions can be async or sync. So you can add `async` or not in font of the function.
|
|
200
202
|
|
|
201
203
|
```js
|
|
202
204
|
export default {
|
|
203
|
-
format: {
|
|
205
|
+
format: async () => ({
|
|
204
206
|
semi: false,
|
|
205
207
|
singleQuote: true,
|
|
206
|
-
},
|
|
207
|
-
lint: [
|
|
208
|
+
}),
|
|
209
|
+
lint: async () => [
|
|
208
210
|
{
|
|
209
211
|
files: ["**/*.{js,cjs,mjs,jsx}", "**/*.{ts,cts,mts,tsx}"],
|
|
210
212
|
rules: {
|
|
@@ -219,37 +221,40 @@ Usually, we recommend reusing the built-in configurations rather than writing th
|
|
|
219
221
|
|
|
220
222
|
```js
|
|
221
223
|
// @ts-check
|
|
222
|
-
// See https://www.npmjs.com/package/@fenge/eslint-config for eslint-config detail usage
|
|
223
|
-
import { Builder } from "fenge/eslint-config";
|
|
224
|
-
// See https://www.npmjs.com/package/@fenge/prettier-config for prettier-config detail usage
|
|
225
|
-
import prettierConfig from "fenge/prettier-config";
|
|
226
|
-
|
|
227
224
|
export default {
|
|
228
|
-
format: {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
225
|
+
format: async () => {
|
|
226
|
+
// See https://www.npmjs.com/package/@fenge/prettier-config for prettier-config detail usage
|
|
227
|
+
const prettierConfig = (await import("fenge/prettier-config")).default;
|
|
228
|
+
return {
|
|
229
|
+
...prettierConfig,
|
|
230
|
+
// add config below to override the default behavior
|
|
231
|
+
semi: false,
|
|
232
|
+
};
|
|
233
|
+
},
|
|
234
|
+
lint: async () => {
|
|
235
|
+
// See https://www.npmjs.com/package/@fenge/eslint-config for eslint-config detail usage
|
|
236
|
+
const Builder = (await import("fenge/eslint-config")).Builder;
|
|
237
|
+
return new Builder()
|
|
238
|
+
.enablePackagejson({
|
|
239
|
+
pick: ["packagejson/top-types"], // only these rules will work for package.json files
|
|
240
|
+
})
|
|
241
|
+
.enableJavascript({
|
|
242
|
+
omit: ["no-var"], // these rules will not work for js files
|
|
243
|
+
})
|
|
244
|
+
.enableTypescript({
|
|
245
|
+
project: "tsconfig.json", // tsconfig.json path
|
|
246
|
+
extend: {
|
|
247
|
+
// apply additional rules for ts files
|
|
248
|
+
"@typescript-eslint/no-explicit-any": "error",
|
|
249
|
+
"@typescript-eslint/consistent-type-assertions": [
|
|
250
|
+
"error",
|
|
251
|
+
{ assertionStyle: "never" },
|
|
252
|
+
],
|
|
253
|
+
"@typescript-eslint/no-non-null-assertion": "error",
|
|
254
|
+
},
|
|
255
|
+
})
|
|
256
|
+
.toConfig();
|
|
232
257
|
},
|
|
233
|
-
lint: new Builder()
|
|
234
|
-
.enablePackagejson({
|
|
235
|
-
pick: ["packagejson/top-types"], // only these rules will work for package.json files
|
|
236
|
-
})
|
|
237
|
-
.enableJavascript({
|
|
238
|
-
omit: ["no-var"], // these rules will not work for js files
|
|
239
|
-
})
|
|
240
|
-
.enableTypescript({
|
|
241
|
-
project: "tsconfig.json", // tsconfig.json path
|
|
242
|
-
extend: {
|
|
243
|
-
// apply additional rules for ts files
|
|
244
|
-
"@typescript-eslint/no-explicit-any": "error",
|
|
245
|
-
"@typescript-eslint/consistent-type-assertions": [
|
|
246
|
-
"error",
|
|
247
|
-
{ assertionStyle: "never" },
|
|
248
|
-
],
|
|
249
|
-
"@typescript-eslint/no-non-null-assertion": "error",
|
|
250
|
-
},
|
|
251
|
-
})
|
|
252
|
-
.toConfig(),
|
|
253
258
|
};
|
|
254
259
|
```
|
|
255
260
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fenge",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "A CLI tool for code quality",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -48,11 +48,11 @@
|
|
|
48
48
|
"lint-staged": "15.2.10",
|
|
49
49
|
"ora": "8.1.1",
|
|
50
50
|
"prettier": "3.3.3",
|
|
51
|
-
"@fenge/eslint-config": "0.1.
|
|
52
|
-
"@fenge/prettier-config": "0.1.0",
|
|
51
|
+
"@fenge/eslint-config": "0.1.3",
|
|
53
52
|
"@fenge/tsconfig": "0.1.0",
|
|
54
53
|
"@fenge/types": "0.1.0",
|
|
55
|
-
"prettier-ignore": "0.1.3"
|
|
54
|
+
"prettier-ignore": "0.1.3",
|
|
55
|
+
"@fenge/prettier-config": "0.1.1"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@types/node": "22.7.5"
|
package/src/bin/cli.js
CHANGED
|
@@ -26,6 +26,7 @@ program
|
|
|
26
26
|
"automatically format code only, will not fix linting problems",
|
|
27
27
|
)
|
|
28
28
|
.option("-u, --update", "automatically format code and fix linting problems")
|
|
29
|
+
.option("-c, --config <path>", "path to configuration file")
|
|
29
30
|
.option(
|
|
30
31
|
"-d, --dry-run",
|
|
31
32
|
"print what command will be executed under the hood instead of executing",
|
package/src/command/format.js
CHANGED
|
@@ -6,12 +6,14 @@ import { dir, execAsync, getBinPath } from "../utils.js";
|
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* @param {Array<string>} paths
|
|
9
|
-
* @param {{update?: boolean, write?: boolean, dryRun?: boolean}} options
|
|
9
|
+
* @param {{update?: boolean, write?: boolean, dryRun?: boolean, config?: string}} options
|
|
10
10
|
*/
|
|
11
11
|
export async function format(paths = [], options = {}) {
|
|
12
|
-
const { update = false, write = false, dryRun = false } = options;
|
|
12
|
+
const { update = false, write = false, dryRun = false, config } = options;
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
if (config) {
|
|
15
|
+
process.env["FENGE_CONFIG"] = config;
|
|
16
|
+
}
|
|
15
17
|
const ignores = [".gitignore", ".prettierignore", prettierignore]
|
|
16
18
|
.map((p) => path.resolve(p))
|
|
17
19
|
.flatMap((p) => ["--ignore-path", p]);
|
|
@@ -27,7 +29,9 @@ export async function format(paths = [], options = {}) {
|
|
|
27
29
|
"--ignore-unknown",
|
|
28
30
|
"--no-error-on-unmatched-pattern", // Not a good option name. It's for skipping formatting symlinks. https://github.com/prettier/prettier/pull/15533
|
|
29
31
|
...(update || write ? ["--write"] : ["--check"]),
|
|
30
|
-
...(paths.length <= 0 ? ["."] : paths).map((p) =>
|
|
32
|
+
...(paths.length <= 0 ? ["."] : paths).map((p) =>
|
|
33
|
+
path.resolve(process.cwd(), p),
|
|
34
|
+
),
|
|
31
35
|
],
|
|
32
36
|
{ topic: "💃 Checking formatting", dryRun },
|
|
33
37
|
);
|
package/src/command/lint.js
CHANGED
|
@@ -5,12 +5,14 @@ import { dir, execAsync, getBinPath } from "../utils.js";
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @param {Array<string>} paths
|
|
8
|
-
* @param {{update?: boolean, fix?: boolean, dryRun?: boolean}} options
|
|
8
|
+
* @param {{update?: boolean, fix?: boolean, dryRun?: boolean, config?: string}} options
|
|
9
9
|
*/
|
|
10
10
|
export async function lint(paths = [], options = {}) {
|
|
11
|
-
const { update = false, fix = false, dryRun = false } = options;
|
|
11
|
+
const { update = false, fix = false, dryRun = false, config } = options;
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
if (config) {
|
|
14
|
+
process.env["FENGE_CONFIG"] = config;
|
|
15
|
+
}
|
|
14
16
|
process.env["ESLINT_USE_FLAT_CONFIG"] = "true"; // TODO remove it once upgrade to eslint 9
|
|
15
17
|
return execAsync(
|
|
16
18
|
[
|
|
@@ -19,7 +21,9 @@ export async function lint(paths = [], options = {}) {
|
|
|
19
21
|
"--config",
|
|
20
22
|
path.join(dir(import.meta.url), "..", "config", "eslint.config.js"),
|
|
21
23
|
...(update || fix ? ["--fix"] : []),
|
|
22
|
-
...(paths.length <= 0 ? ["."] : paths).map((p) =>
|
|
24
|
+
...(paths.length <= 0 ? ["."] : paths).map((p) =>
|
|
25
|
+
path.resolve(process.cwd(), p),
|
|
26
|
+
),
|
|
23
27
|
],
|
|
24
28
|
{ topic: "📏 Checking linting", dryRun },
|
|
25
29
|
);
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
+
import process from "node:process";
|
|
2
3
|
import { resolveConfig } from "../utils.js";
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
async function getLintConfig() {
|
|
6
|
+
const lint = (await resolveConfig("fenge", process.env["FENGE_CONFIG"]))
|
|
7
|
+
?.config?.lint;
|
|
8
|
+
if (!lint) return undefined;
|
|
9
|
+
return typeof lint === "function" ? await lint() : lint;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default (await getLintConfig()) ??
|
|
5
13
|
(await resolveConfig("eslint"))?.config ??
|
|
6
14
|
(await import("../re-export/eslint.config.js")).default;
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
+
import process from "node:process";
|
|
2
3
|
import { resolveConfig } from "../utils.js";
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
async function getFormatConfig() {
|
|
6
|
+
const format = (await resolveConfig("fenge", process.env["FENGE_CONFIG"]))
|
|
7
|
+
?.config?.format;
|
|
8
|
+
if (!format) return undefined;
|
|
9
|
+
return typeof format === "function" ? await format() : format;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default (await getFormatConfig()) ??
|
|
5
13
|
(await resolveConfig("prettier"))?.config ??
|
|
6
14
|
(await import("../re-export/prettier.config.js")).default;
|
package/src/utils.js
CHANGED
|
@@ -31,11 +31,13 @@ export function dir(importMetaUrl) {
|
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* @param {string} module
|
|
34
|
+
* @param {string} [loadPath]
|
|
34
35
|
*/
|
|
35
|
-
export async function resolveConfig(module) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
export async function resolveConfig(module, loadPath) {
|
|
37
|
+
const searcher = lilconfig(module, { stopDir: process.cwd() });
|
|
38
|
+
return loadPath
|
|
39
|
+
? await searcher.load(loadPath)
|
|
40
|
+
: await searcher.search(process.cwd());
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
/**
|