Skip to content

Commit cf79201

Browse files
authored
feat: Add oxfmt support (#11)
1 parent f4068f4 commit cf79201

22 files changed

Lines changed: 290 additions & 139 deletions

.oxfmtrc.jsonc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"$schema": "./node_modules/oxfmt/configuration_schema.json",
3+
"ignorePatterns": ["CHANGELOG.md"],
4+
"sortImports": {},
5+
"proseWrap": "always",
6+
"sortPackageJson": {
7+
"sortScripts": true,
8+
},
9+
}

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Check
22

3-
An opinionated CLI tool to run all your checks all at once. The command will only exit with code 0 when no problems exist.
3+
An opinionated CLI tool to run all your checks all at once. The command will only exit with code 0
4+
when no problems exist.
45

56
https://github.com/aklinker1/check/assets/10101283/c8089e5c-e25f-4f59-8897-d2a6f97a3139
67

bun.lock

Lines changed: 43 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,41 @@
11
{
22
"name": "@aklinker1/check",
33
"version": "2.2.0",
4-
"packageManager": "bun@1.3.2",
4+
"keywords": [
5+
"check",
6+
"eslint",
7+
"format",
8+
"lint",
9+
"oxfmt",
10+
"prettier",
11+
"publint",
12+
"typescript"
13+
],
14+
"homepage": "https://github.com/aklinker1/check",
15+
"license": "MIT",
16+
"author": {
17+
"name": "Aaron Klinker",
18+
"email": "aaronklinker1+npm@gmail.com"
19+
},
20+
"repository": {
21+
"url": "https://github.com/aklinker1/check"
22+
},
23+
"bin": {
24+
"check": "bin/check.mjs"
25+
},
26+
"files": [
27+
"bin",
28+
"dist"
29+
],
530
"type": "module",
31+
"module": "./dist/index.js",
32+
"types": "./dist/index.d.ts",
33+
"exports": {
34+
".": {
35+
"types": "./dist/index.d.ts",
36+
"import": "./dist/index.js"
37+
}
38+
},
639
"scripts": {
740
"build": "tsdown src/index.ts src/cli.ts",
841
"check": "bun src/cli.ts",
@@ -15,42 +48,11 @@
1548
"devDependencies": {
1649
"@types/bun": "latest",
1750
"@typescript/native-preview": "^7.0.0-dev.20251114.1",
51+
"oxfmt": "^0.40.0",
1852
"oxlint": "^1.22.0",
1953
"publint": "^0.3.14",
2054
"tsdown": "^0.15.9",
2155
"typescript": "^5.9.3"
2256
},
23-
"repository": {
24-
"url": "https://github.com/aklinker1/check"
25-
},
26-
"license": "MIT",
27-
"homepage": "https://github.com/aklinker1/check",
28-
"author": {
29-
"name": "Aaron Klinker",
30-
"email": "aaronklinker1+npm@gmail.com"
31-
},
32-
"keywords": [
33-
"lint",
34-
"format",
35-
"check",
36-
"eslint",
37-
"publint",
38-
"prettier",
39-
"typescript"
40-
],
41-
"exports": {
42-
".": {
43-
"types": "./dist/index.d.ts",
44-
"import": "./dist/index.js"
45-
}
46-
},
47-
"module": "./dist/index.js",
48-
"types": "./dist/index.d.ts",
49-
"files": [
50-
"bin",
51-
"dist"
52-
],
53-
"bin": {
54-
"check": "bin/check.mjs"
55-
}
57+
"packageManager": "bun@1.3.2"
5658
}

src/cli.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { isCI } from "ci-info";
2+
23
import { check } from ".";
34
import { version } from "../package.json" with { type: "json" };
45
import { ALL_TOOLS } from "./tools";
@@ -22,8 +23,7 @@ const help = `\x1b[34m\x1b[1mcheck\x1b[0m runs all your project checks at once,
2223
\x1b[36m-h\x1b[0m, \x1b[36m--help\x1b[0m Show this help message and exit`;
2324

2425
const args = process.argv.slice(2);
25-
const boolArg = (arg: string): boolean | undefined =>
26-
args.includes(arg) || undefined;
26+
const boolArg = (arg: string): boolean | undefined => args.includes(arg) || undefined;
2727

2828
const showHelp = boolArg("-h") || boolArg("--help");
2929
if (showHelp) {

src/index.ts

Lines changed: 32 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,24 @@
1-
import { ALL_TOOLS } from "./tools";
2-
import type { CheckOptions, Tool, Problem, ToolDefinition } from "./types";
3-
import {
4-
bold,
5-
cyan,
6-
debug as debugLog,
7-
dim,
8-
humanMs,
9-
isDebug,
10-
red,
11-
yellow,
12-
} from "./utils";
13-
import { createTaskList } from "./tasklist";
1+
import { readFile } from "node:fs/promises";
142
import { relative, resolve, sep, join } from "node:path";
3+
154
import { isCI } from "ci-info";
16-
import { readFile } from "node:fs/promises";
5+
6+
import { createTaskList } from "./tasklist";
7+
import { ALL_TOOLS } from "./tools";
8+
import type { CheckOptions, Tool, Problem, ToolDefinition } from "./types";
9+
import { bold, cyan, debug as debugLog, dim, humanMs, isDebug, red, yellow } from "./utils";
1710

1811
export type * from "./types";
1912

2013
export async function check(options: CheckOptions = {}): Promise<never> {
2114
const { debug, fix = !isCI, root = process.cwd() } = options;
22-
const packageJson = JSON.parse(
23-
await readFile(join(root, "package.json"), "utf8"),
24-
);
15+
const packageJson = JSON.parse(await readFile(join(root, "package.json"), "utf8"));
2516
if (debug) {
2617
process.env.DEBUG = "true";
2718
}
2819
console.log();
2920
debugLog("Options:" + JSON.stringify(options));
30-
debugLog(
31-
"Resolved options:" + JSON.stringify({ debug, fix, root, packageJson }),
32-
);
21+
debugLog("Resolved options:" + JSON.stringify({ debug, fix, root, packageJson }));
3322

3423
const tools = await findInstalledTools({ root, packageJson });
3524
if (tools.length === 0) {
@@ -41,28 +30,25 @@ export async function check(options: CheckOptions = {}): Promise<never> {
4130
console.log();
4231
process.exit(1);
4332
}
44-
const results = await createTaskList(
45-
tools,
46-
async ({ input: tool, fail, succeed, warn }) => {
47-
const startTime = performance.now();
48-
// Run checks
49-
const fn = fix ? (tool.fix ?? tool.check) : tool.check;
50-
const problems = await fn();
51-
// Ensure problems are absolute paths relative to the root dir
52-
problems.forEach((problem) => {
53-
problem.file = resolve(root ?? process.cwd(), problem.file);
54-
});
55-
const duration = humanMs(performance.now() - startTime);
56-
57-
const title = `${tool.name} ${dim(`(${duration})`)}`;
58-
const errorCount = problems.filter((p) => p.kind === "error").length;
59-
if (errorCount > 0) fail(title);
60-
else if (problems.length > 0) warn(title);
61-
else succeed(title);
62-
63-
return problems;
64-
},
65-
);
33+
const results = await createTaskList(tools, async ({ input: tool, fail, succeed, warn }) => {
34+
const startTime = performance.now();
35+
// Run checks
36+
const fn = fix ? (tool.fix ?? tool.check) : tool.check;
37+
const problems = await fn();
38+
// Ensure problems are absolute paths relative to the root dir
39+
problems.forEach((problem) => {
40+
problem.file = resolve(root ?? process.cwd(), problem.file);
41+
});
42+
const duration = humanMs(performance.now() - startTime);
43+
44+
const title = `${tool.name} ${dim(`(${duration})`)}`;
45+
const errorCount = problems.filter((p) => p.kind === "error").length;
46+
if (errorCount > 0) fail(title);
47+
else if (problems.length > 0) warn(title);
48+
else succeed(title);
49+
50+
return problems;
51+
});
6652

6753
const problems = results.flat();
6854
console.log();
@@ -97,10 +83,7 @@ export async function check(options: CheckOptions = {}): Promise<never> {
9783
return acc;
9884
}, {}),
9985
);
100-
const maxLength = files.reduce(
101-
(prev, [file]) => Math.max(prev, file.length),
102-
0,
103-
);
86+
const maxLength = files.reduce((prev, [file]) => Math.max(prev, file.length), 0);
10487
console.log();
10588
console.log("Across " + plural(files.length, "File:", "Files:"));
10689
files.forEach(([file, count]) => {
@@ -112,14 +95,11 @@ export async function check(options: CheckOptions = {}): Promise<never> {
11295
process.exit(problems.length);
11396
}
11497

115-
async function findInstalledTools(
116-
opts: Parameters<ToolDefinition>[0],
117-
): Promise<Tool[]> {
98+
async function findInstalledTools(opts: Parameters<ToolDefinition>[0]): Promise<Tool[]> {
11899
const status = await Promise.all(
119100
ALL_TOOLS.map(async (def) => {
120101
const tool = await def(opts);
121-
const isInstalled =
122-
!!opts.packageJson.devDependencies?.[tool.packageName];
102+
const isInstalled = !!opts.packageJson.devDependencies?.[tool.packageName];
123103
return { tool, isInstalled };
124104
}),
125105
);
@@ -135,9 +115,7 @@ async function findInstalledTools(
135115
const skipped = getTools(false);
136116
debugLog(`Skipping: ${skipped || "(none)"} `);
137117
}
138-
return status
139-
.filter(({ isInstalled }) => isInstalled)
140-
.map((item) => item.tool);
118+
return status.filter(({ isInstalled }) => isInstalled).map((item) => item.tool);
141119
}
142120

143121
function plural(count: number, singular: string, plural: string): string {

src/tasklist/index.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
import { cyan, dim, green, red, yellow } from "../utils";
21
import readline from "node:readline";
32

4-
export async function createTaskList<
5-
TInput extends { name: string },
6-
TResult = void,
7-
>(
3+
import { cyan, dim, green, red, yellow } from "../utils";
4+
5+
export async function createTaskList<TInput extends { name: string }, TResult = void>(
86
inputs: TInput[],
97
run: (ctx: {
108
input: TInput;

src/tools/eslint.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { describe, it, expect } from "bun:test";
2+
23
import { parseOutput } from "./eslint";
34

45
describe("ESLint", () => {

src/tools/eslint.ts

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,23 @@ export const eslint: ToolDefinition = ({ root }) => {
1414
};
1515

1616
export const parseOutput: OutputParser = ({ stdout, stderr }) => {
17-
return `${stdout}\n${stderr}`
18-
.split(/\r?\n/)
19-
.reduce<Problem[]>((acc, line) => {
20-
const groups =
21-
/^(?<file>.*?): line (?<line>[0-9]+), col (?<column>[0-9]+), (?<kind>\S+) - (?<message>.*?) \((?<rule>\S*?)\)$/.exec(
22-
line,
23-
)?.groups;
24-
if (groups) {
25-
acc.push({
26-
file: groups.file,
27-
kind: groups.kind === "Warning" ? "warning" : "error",
28-
message: groups.message,
29-
location: {
30-
line: parseInt(groups.line, 10),
31-
column: parseInt(groups.column, 10),
32-
},
33-
rule: groups.rule,
34-
});
35-
}
36-
return acc;
37-
}, []);
17+
return `${stdout}\n${stderr}`.split(/\r?\n/).reduce<Problem[]>((acc, line) => {
18+
const groups =
19+
/^(?<file>.*?): line (?<line>[0-9]+), col (?<column>[0-9]+), (?<kind>\S+) - (?<message>.*?) \((?<rule>\S*?)\)$/.exec(
20+
line,
21+
)?.groups;
22+
if (groups) {
23+
acc.push({
24+
file: groups.file,
25+
kind: groups.kind === "Warning" ? "warning" : "error",
26+
message: groups.message,
27+
location: {
28+
line: parseInt(groups.line, 10),
29+
column: parseInt(groups.column, 10),
30+
},
31+
rule: groups.rule,
32+
});
33+
}
34+
return acc;
35+
}, []);
3836
};

0 commit comments

Comments
 (0)