@utoo/lint 0.2.1 → 0.2.3
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/README.md +72 -11
- package/bin/fishlint.js +429 -64
- package/bin/migrate.js +8 -6
- package/index.cjs +298 -143
- package/index.d.ts +5 -1
- package/index.js +298 -143
- package/lib/config-loader.cjs +95 -0
- package/lib/config-loader.js +89 -0
- package/lib/load-config.js +23 -0
- package/package.json +15 -6
- package/schema.json +1 -1
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
const { spawnSync } = require("node:child_process");
|
|
2
|
+
const { readFileSync, statSync } = require("node:fs");
|
|
3
|
+
const { dirname, extname, join, resolve: resolvePath } = require("node:path");
|
|
4
|
+
|
|
5
|
+
const CONFIG_FILENAMES = [
|
|
6
|
+
"utlint.config.ts",
|
|
7
|
+
"utlint.config.json",
|
|
8
|
+
"utoo.json",
|
|
9
|
+
"utoo-lint.json"
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
const TYPESCRIPT_CONFIG_EXTENSIONS = new Set([".ts", ".mts", ".cts"]);
|
|
13
|
+
const JAVASCRIPT_CONFIG_EXTENSIONS = new Set([".js", ".mjs", ".cjs"]);
|
|
14
|
+
const loaderPath = join(__dirname, "load-config.js");
|
|
15
|
+
|
|
16
|
+
function findConfigPath(directory) {
|
|
17
|
+
let current = resolvePath(directory);
|
|
18
|
+
while (true) {
|
|
19
|
+
for (const filename of CONFIG_FILENAMES) {
|
|
20
|
+
const candidate = resolvePath(current, filename);
|
|
21
|
+
if (isFile(candidate)) {
|
|
22
|
+
return candidate;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const parent = dirname(current);
|
|
26
|
+
if (parent === current) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
current = parent;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function isFile(path) {
|
|
34
|
+
try {
|
|
35
|
+
return statSync(path).isFile();
|
|
36
|
+
} catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function readConfig(path, cwd, cache) {
|
|
42
|
+
const configPath = resolvePath(cwd ?? process.cwd(), path);
|
|
43
|
+
if (cache?.has(configPath)) {
|
|
44
|
+
return cache.get(configPath);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
let config;
|
|
48
|
+
if (isExecutableConfigPath(configPath)) {
|
|
49
|
+
config = readExecutableConfig(configPath, cwd);
|
|
50
|
+
} else {
|
|
51
|
+
try {
|
|
52
|
+
config = JSON.parse(readFileSync(configPath, "utf8"));
|
|
53
|
+
} catch (error) {
|
|
54
|
+
throw configReadError(configPath, error.message);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
cache?.set(configPath, config);
|
|
59
|
+
return config;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function isExecutableConfigPath(path) {
|
|
63
|
+
const extension = extname(path);
|
|
64
|
+
return TYPESCRIPT_CONFIG_EXTENSIONS.has(extension) || JAVASCRIPT_CONFIG_EXTENSIONS.has(extension);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function readExecutableConfig(path, cwd) {
|
|
68
|
+
const result = spawnSync(process.execPath, [loaderPath, path], {
|
|
69
|
+
cwd: cwd ?? process.cwd(),
|
|
70
|
+
encoding: "utf8",
|
|
71
|
+
stdio: ["ignore", "pipe", "pipe", "pipe"]
|
|
72
|
+
});
|
|
73
|
+
if (result.error) {
|
|
74
|
+
throw configReadError(path, result.error.message);
|
|
75
|
+
}
|
|
76
|
+
if (result.status !== 0) {
|
|
77
|
+
throw configReadError(path, (result.stderr ?? "").trim() || "config loader failed");
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
return JSON.parse(result.output?.[3] ?? "");
|
|
81
|
+
} catch (error) {
|
|
82
|
+
throw configReadError(path, error.message);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function configReadError(path, message) {
|
|
87
|
+
return new Error(`utoo-lint unable to read config ${path}: ${message}`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
module.exports = {
|
|
91
|
+
CONFIG_FILENAMES,
|
|
92
|
+
findConfigPath,
|
|
93
|
+
isExecutableConfigPath,
|
|
94
|
+
readConfig
|
|
95
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { readFileSync, statSync } from "node:fs";
|
|
3
|
+
import { dirname, extname, resolve as resolvePath } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
export const CONFIG_FILENAMES = [
|
|
7
|
+
"utlint.config.ts",
|
|
8
|
+
"utlint.config.json",
|
|
9
|
+
"utoo.json",
|
|
10
|
+
"utoo-lint.json"
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
const TYPESCRIPT_CONFIG_EXTENSIONS = new Set([".ts", ".mts", ".cts"]);
|
|
14
|
+
const JAVASCRIPT_CONFIG_EXTENSIONS = new Set([".js", ".mjs", ".cjs"]);
|
|
15
|
+
const loaderPath = fileURLToPath(new URL("./load-config.js", import.meta.url));
|
|
16
|
+
|
|
17
|
+
export function findConfigPath(directory) {
|
|
18
|
+
let current = resolvePath(directory);
|
|
19
|
+
while (true) {
|
|
20
|
+
for (const filename of CONFIG_FILENAMES) {
|
|
21
|
+
const candidate = resolvePath(current, filename);
|
|
22
|
+
if (isFile(candidate)) {
|
|
23
|
+
return candidate;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const parent = dirname(current);
|
|
27
|
+
if (parent === current) {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
current = parent;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function isFile(path) {
|
|
35
|
+
try {
|
|
36
|
+
return statSync(path).isFile();
|
|
37
|
+
} catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function readConfig(path, cwd, cache) {
|
|
43
|
+
const configPath = resolvePath(cwd ?? process.cwd(), path);
|
|
44
|
+
if (cache?.has(configPath)) {
|
|
45
|
+
return cache.get(configPath);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let config;
|
|
49
|
+
if (isExecutableConfigPath(configPath)) {
|
|
50
|
+
config = readExecutableConfig(configPath, cwd);
|
|
51
|
+
} else {
|
|
52
|
+
try {
|
|
53
|
+
config = JSON.parse(readFileSync(configPath, "utf8"));
|
|
54
|
+
} catch (error) {
|
|
55
|
+
throw configReadError(configPath, error.message);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
cache?.set(configPath, config);
|
|
60
|
+
return config;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function isExecutableConfigPath(path) {
|
|
64
|
+
const extension = extname(path);
|
|
65
|
+
return TYPESCRIPT_CONFIG_EXTENSIONS.has(extension) || JAVASCRIPT_CONFIG_EXTENSIONS.has(extension);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function readExecutableConfig(path, cwd) {
|
|
69
|
+
const result = spawnSync(process.execPath, [loaderPath, path], {
|
|
70
|
+
cwd: cwd ?? process.cwd(),
|
|
71
|
+
encoding: "utf8",
|
|
72
|
+
stdio: ["ignore", "pipe", "pipe", "pipe"]
|
|
73
|
+
});
|
|
74
|
+
if (result.error) {
|
|
75
|
+
throw configReadError(path, result.error.message);
|
|
76
|
+
}
|
|
77
|
+
if (result.status !== 0) {
|
|
78
|
+
throw configReadError(path, (result.stderr ?? "").trim() || "config loader failed");
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
return JSON.parse(result.output?.[3] ?? "");
|
|
82
|
+
} catch (error) {
|
|
83
|
+
throw configReadError(path, error.message);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function configReadError(path, message) {
|
|
88
|
+
return new Error(`utoo-lint unable to read config ${path}: ${message}`);
|
|
89
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { dirname } from "node:path";
|
|
2
|
+
import { writeFileSync } from "node:fs";
|
|
3
|
+
import { createJiti } from "jiti";
|
|
4
|
+
|
|
5
|
+
const configPath = process.argv[2];
|
|
6
|
+
|
|
7
|
+
try {
|
|
8
|
+
if (!configPath) {
|
|
9
|
+
throw new TypeError("missing config path");
|
|
10
|
+
}
|
|
11
|
+
const jiti = createJiti(dirname(configPath));
|
|
12
|
+
const value = await jiti.import(configPath, { default: true });
|
|
13
|
+
const json = JSON.stringify(value);
|
|
14
|
+
if (json === undefined) {
|
|
15
|
+
throw new TypeError("config did not export a JSON-serializable value");
|
|
16
|
+
}
|
|
17
|
+
// fd 3 is a private serialization channel created by config-loader. Config
|
|
18
|
+
// code may write to stdout without corrupting the JSON payload.
|
|
19
|
+
writeFileSync(3, json);
|
|
20
|
+
} catch (error) {
|
|
21
|
+
console.error(error?.stack ?? error?.message ?? String(error));
|
|
22
|
+
process.exitCode = 1;
|
|
23
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@utoo/lint",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Experimental JavaScript and TypeScript linter powered by Yuku",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
},
|
|
13
13
|
"homepage": "https://github.com/fireairforce/utoo-lint#readme",
|
|
14
14
|
"type": "module",
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=18.0.0"
|
|
17
|
+
},
|
|
15
18
|
"types": "./index.d.ts",
|
|
16
19
|
"exports": {
|
|
17
20
|
".": {
|
|
@@ -70,14 +73,20 @@
|
|
|
70
73
|
"use-at-your-own-risk.js"
|
|
71
74
|
],
|
|
72
75
|
"optionalDependencies": {
|
|
73
|
-
"@utoo/lint-darwin-arm64": "0.2.
|
|
74
|
-
"@utoo/lint-darwin-x64": "0.2.
|
|
75
|
-
"@utoo/lint-linux-arm64": "0.2.
|
|
76
|
-
"@utoo/lint-linux-x64": "0.2.
|
|
77
|
-
"@utoo/lint-win32-x64": "0.2.
|
|
76
|
+
"@utoo/lint-darwin-arm64": "0.2.3",
|
|
77
|
+
"@utoo/lint-darwin-x64": "0.2.3",
|
|
78
|
+
"@utoo/lint-linux-arm64": "0.2.3",
|
|
79
|
+
"@utoo/lint-linux-x64": "0.2.3",
|
|
80
|
+
"@utoo/lint-win32-x64": "0.2.3"
|
|
81
|
+
},
|
|
82
|
+
"dependencies": {
|
|
83
|
+
"jiti": "2.7.0"
|
|
78
84
|
},
|
|
79
85
|
"publishConfig": {
|
|
80
86
|
"access": "public",
|
|
81
87
|
"registry": "https://registry.npmjs.org/"
|
|
88
|
+
},
|
|
89
|
+
"scripts": {
|
|
90
|
+
"test": "node --test --test-concurrency=1 test/*.test.mjs"
|
|
82
91
|
}
|
|
83
92
|
}
|