@aklinker1/check 2.1.0 → 2.1.2

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.
Files changed (41) hide show
  1. package/bin/check.mjs +1 -1
  2. package/dist/cli.d.ts +1 -1
  3. package/dist/cli.js +37 -0
  4. package/dist/index.d.ts +63 -5
  5. package/dist/index.js +3 -0
  6. package/dist/src-CKPF6CV1.js +451 -0
  7. package/package.json +23 -38
  8. package/dist/cli.mjs +0 -34
  9. package/dist/index.mjs +0 -135
  10. package/dist/tasklist/index.d.ts +0 -8
  11. package/dist/tasklist/index.mjs +0 -78
  12. package/dist/tools/eslint.d.ts +0 -3
  13. package/dist/tools/eslint.mjs +0 -41
  14. package/dist/tools/eslint.test.d.ts +0 -1
  15. package/dist/tools/eslint.test.mjs +0 -35
  16. package/dist/tools/index.d.ts +0 -1
  17. package/dist/tools/index.mjs +0 -14
  18. package/dist/tools/markdownlint.d.ts +0 -3
  19. package/dist/tools/markdownlint.mjs +0 -34
  20. package/dist/tools/markdownlint.test.d.ts +0 -1
  21. package/dist/tools/markdownlint.test.mjs +0 -72
  22. package/dist/tools/oxlint.d.ts +0 -3
  23. package/dist/tools/oxlint.mjs +0 -49
  24. package/dist/tools/oxlint.test.d.ts +0 -1
  25. package/dist/tools/oxlint.test.mjs +0 -57
  26. package/dist/tools/prettier.d.ts +0 -3
  27. package/dist/tools/prettier.mjs +0 -40
  28. package/dist/tools/prettier.test.d.ts +0 -1
  29. package/dist/tools/prettier.test.mjs +0 -78
  30. package/dist/tools/publint.d.ts +0 -3
  31. package/dist/tools/publint.mjs +0 -28
  32. package/dist/tools/publint.test.d.ts +0 -1
  33. package/dist/tools/publint.test.mjs +0 -33
  34. package/dist/tools/typescript.d.ts +0 -3
  35. package/dist/tools/typescript.mjs +0 -47
  36. package/dist/tools/typescript.test.d.ts +0 -1
  37. package/dist/tools/typescript.test.mjs +0 -51
  38. package/dist/types.d.ts +0 -55
  39. package/dist/types.mjs +0 -0
  40. package/dist/utils.d.ts +0 -11
  41. package/dist/utils.mjs +0 -50
package/bin/check.mjs CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import "../dist/cli.mjs";
2
+ import "../dist/cli.js";
package/dist/cli.d.ts CHANGED
@@ -1 +1 @@
1
- export {};
1
+ export { };
package/dist/cli.js ADDED
@@ -0,0 +1,37 @@
1
+ import { i as ALL_TOOLS, t as check } from "./src-CKPF6CV1.js";
2
+ import { isCI } from "ci-info";
3
+
4
+ //#region package.json
5
+ var version = "2.1.2";
6
+
7
+ //#endregion
8
+ //#region src/cli.ts
9
+ const help = `\x1b[34m\x1b[1mcheck\x1b[0m runs all your project checks at once, standardizing and combining the output. \x1b[2m(${version})\x1b[0m
10
+
11
+ \x1b[1mSupported Tools:\x1b[0m
12
+ ${ALL_TOOLS.map((tool) => `\x1b[32m${tool.name}\x1b[0m`).sort().join(", ")}
13
+
14
+ \x1b[1mUsage:\x1b[0m
15
+ \x1b[1mcheck\x1b[0m \x1b[1m\x1b[36m[flags]\x1b[0m [root]
16
+
17
+ \x1b[1mArguments:\x1b[0m
18
+ root Directory to run commands from (default: .)
19
+
20
+ \x1b[1mFlags\x1b[0m:
21
+ \x1b[36m-f\x1b[0m, \x1b[36m--fix\x1b[0m Fix problems when possible (default: false in CI, true everywhere else)
22
+ \x1b[36m-d\x1b[0m, \x1b[36m--debug\x1b[0m Enable debug logs
23
+ \x1b[36m-h\x1b[0m, \x1b[36m--help\x1b[0m Show this help message and exit`;
24
+ const args = process.argv.slice(2);
25
+ const boolArg = (arg) => args.includes(arg) || void 0;
26
+ if (boolArg("-h") || boolArg("--help")) {
27
+ console.log(help);
28
+ process.exit(0);
29
+ }
30
+ await check({
31
+ fix: boolArg("-f") ?? boolArg("--fix") ?? !isCI,
32
+ debug: boolArg("-d") ?? boolArg("--debug") ?? false,
33
+ root: args.find((arg) => !arg.startsWith("-")) ?? "."
34
+ });
35
+
36
+ //#endregion
37
+ export { };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,63 @@
1
- import type { CheckOptions, Problem } from "./types";
2
- export type * from "./types";
3
- export declare function check(options?: CheckOptions): Promise<void>;
4
- export declare function renderProblemGroup(problems: Problem[]): string;
5
- export declare function renderProblem(problem: Problem): string;
1
+ //#region src/types.d.ts
2
+ interface CheckOptions {
3
+ /**
4
+ * Set to true to fix problems that can be automatically fixed.
5
+ *
6
+ * Defaults to `true` outside CI, and `false` inside CI.
7
+ */
8
+ fix?: boolean;
9
+ /**
10
+ * Directory to run commands in.
11
+ */
12
+ root?: string;
13
+ /**
14
+ * Set to true to enable debug logs.
15
+ */
16
+ debug?: boolean;
17
+ }
18
+ type ToolDefinition = (opts: {
19
+ root: string;
20
+ packageJson: any;
21
+ }) => Promise<Tool> | Tool;
22
+ interface Tool {
23
+ /**
24
+ * Name of tool shown in the console output.
25
+ */
26
+ name: string;
27
+ /**
28
+ * The name of the package in your `package.json`. If present, this tool will be ran.
29
+ */
30
+ packageName: string;
31
+ /**
32
+ * Run the tool, only checking for problems.
33
+ */
34
+ check: () => Promise<Problem[]>;
35
+ /**
36
+ * Run the tool, but fix problems if possible. If the tool doesn't support fixing problems, `check` will be called instead.
37
+ */
38
+ fix?: () => Promise<Problem[]>;
39
+ }
40
+ interface Problem {
41
+ location?: CodeLocation;
42
+ message: string;
43
+ file: string;
44
+ kind: ProblemKind;
45
+ rule?: string;
46
+ }
47
+ interface CodeLocation {
48
+ line: number;
49
+ column: number;
50
+ }
51
+ type ProblemKind = "warning" | "error";
52
+ type OutputParser = (data: {
53
+ code: number;
54
+ stdout: string;
55
+ stderr: string;
56
+ }) => Problem[];
57
+ //#endregion
58
+ //#region src/index.d.ts
59
+ declare function check(options?: CheckOptions): Promise<never>;
60
+ declare function renderProblemGroup(problems: Problem[]): string;
61
+ declare function renderProblem(problem: Problem): string;
62
+ //#endregion
63
+ export { CheckOptions, CodeLocation, OutputParser, Problem, ProblemKind, Tool, ToolDefinition, check, renderProblem, renderProblemGroup };
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ import { n as renderProblem, r as renderProblemGroup, t as check } from "./src-CKPF6CV1.js";
2
+
3
+ export { check, renderProblem, renderProblemGroup };
@@ -0,0 +1,451 @@
1
+ import { isCI } from "ci-info";
2
+ import { spawn } from "node:child_process";
3
+ import readline from "node:readline";
4
+ import { join, relative, resolve, sep } from "node:path";
5
+ import { readFile } from "node:fs/promises";
6
+
7
+ //#region src/utils.ts
8
+ function exec(cmd, opts) {
9
+ return new Promise((resolve$1, reject) => {
10
+ const child = spawn(cmd, {
11
+ ...opts,
12
+ shell: true
13
+ });
14
+ let stderr = "";
15
+ let stdout = "";
16
+ child.stdout.on("data", (data) => {
17
+ stdout += data.toString();
18
+ });
19
+ child.stderr.on("data", (data) => {
20
+ stderr += data.toString();
21
+ });
22
+ child.on("error", (error) => {
23
+ reject(error);
24
+ });
25
+ child.on("close", (exitCode) => {
26
+ resolve$1({
27
+ stderr,
28
+ stdout,
29
+ exitCode
30
+ });
31
+ });
32
+ });
33
+ }
34
+ async function execAndParse(cmd, cwd, parser) {
35
+ const res = await exec(cmd, { cwd });
36
+ if (res.exitCode == null) throw Error("Exit code was null");
37
+ if (isDebug()) console.debug({
38
+ cmd,
39
+ cwd,
40
+ ...res
41
+ });
42
+ return parser({
43
+ code: res.exitCode,
44
+ stderr: res.stderr,
45
+ stdout: res.stdout
46
+ });
47
+ }
48
+ function isDebug() {
49
+ return process.env.DEBUG === "true" || process.env.DEBUG === "1";
50
+ }
51
+ const bold = (str) => `\x1b[1m${str}\x1b[0m`;
52
+ const dim = (str) => `\x1b[2m${str}\x1b[0m`;
53
+ const red = (str) => `\x1b[31m${str}\x1b[0m`;
54
+ const green = (str) => `\x1b[32m${str}\x1b[0m`;
55
+ const yellow = (str) => `\x1b[33m${str}\x1b[0m`;
56
+ const cyan = (str) => `\x1b[36m${str}\x1b[0m`;
57
+ function humanMs(ms) {
58
+ const minutes = Math.floor(ms / 6e4);
59
+ const seconds = (ms % 6e4 / 1e3).toFixed(minutes > 0 ? 0 : 3);
60
+ return `${minutes > 0 ? `${minutes}m ` : ""}${seconds}s`;
61
+ }
62
+ function debug(message) {
63
+ if (isDebug()) console.debug(dim("⚙ " + message));
64
+ }
65
+
66
+ //#endregion
67
+ //#region src/tools/eslint.ts
68
+ const eslint = ({ root }) => {
69
+ const checkCmd = `eslint . --ext .js,.ts,.jsx,.tsx,.mjs,.mts,.cjs,.cts,.vue --format compact --max-warnings 0`;
70
+ const fixCmd = `${checkCmd} --fix`;
71
+ return {
72
+ name: "ESLint",
73
+ packageName: "eslint",
74
+ check: () => execAndParse(checkCmd, root, parseOutput$5),
75
+ fix: () => execAndParse(fixCmd, root, parseOutput$5)
76
+ };
77
+ };
78
+ const parseOutput$5 = ({ stdout, stderr }) => {
79
+ return `${stdout}\n${stderr}`.split(/\r?\n/).reduce((acc, line) => {
80
+ const groups = /^(?<file>.*?): line (?<line>[0-9]+), col (?<column>[0-9]+), (?<kind>\S+) - (?<message>.*?) \((?<rule>\S*?)\)$/.exec(line)?.groups;
81
+ if (groups) acc.push({
82
+ file: groups.file,
83
+ kind: groups.kind === "Warning" ? "warning" : "error",
84
+ message: groups.message,
85
+ location: {
86
+ line: parseInt(groups.line, 10),
87
+ column: parseInt(groups.column, 10)
88
+ },
89
+ rule: groups.rule
90
+ });
91
+ return acc;
92
+ }, []);
93
+ };
94
+
95
+ //#endregion
96
+ //#region src/tools/markdownlint.ts
97
+ const markdownlint = ({ root }) => {
98
+ const checkCmd = "markdownlint . --json --ignore='**/dist/**' --ignore='**/node_modules/**' --ignore='**/.output/**' --ignore='**/coverage/**'";
99
+ const fixCmd = `${checkCmd} --fix`;
100
+ return {
101
+ name: "Markdownlint",
102
+ packageName: "markdownlint-cli",
103
+ check: () => execAndParse(checkCmd, root, parseOutput$4),
104
+ fix: () => execAndParse(fixCmd, root, parseOutput$4)
105
+ };
106
+ };
107
+ const parseOutput$4 = ({ stderr: _stderr }) => {
108
+ const stderr = _stderr.trim();
109
+ if (!stderr) return [];
110
+ return JSON.parse(stderr).map((warning) => ({
111
+ location: {
112
+ line: warning.lineNumber,
113
+ column: warning.errorRange?.[0] ?? 0
114
+ },
115
+ message: warning.ruleDescription,
116
+ file: warning.fileName,
117
+ kind: "warning",
118
+ rule: warning.ruleNames[0]
119
+ }));
120
+ };
121
+
122
+ //#endregion
123
+ //#region src/tools/oxlint.ts
124
+ const oxlint = ({ root }) => {
125
+ const checkCmd = "oxlint . --format=unix --deny-warnings --ignore-path=.oxlintignore --ignore-pattern='**/dist/**' --ignore-pattern='**/node_modules/**' --ignore-pattern='**/.output/**' --ignore-pattern='**/coverage/**'";
126
+ const fixCmd = `${checkCmd} --fix`;
127
+ return {
128
+ name: "Oxlint",
129
+ packageName: "oxlint",
130
+ check: () => execAndParse(checkCmd, root, parseOutput$3),
131
+ fix: () => execAndParse(fixCmd, root, parseOutput$3)
132
+ };
133
+ };
134
+ const parseOutput$3 = ({ stdout }) => {
135
+ if (stdout.trim()) return stdout.split(/\r?\n/).reduce((acc, line) => {
136
+ const groups = /^(?<file>.+?):(?<line>[0-9]+):(?<column>[0-9]+):\s?(?<message>.*?)\s?\[(?<kind>Warning|Error)\/?(?<rule>.*?)\]\s?$/.exec(line)?.groups;
137
+ if (groups) acc.push({
138
+ file: groups.file,
139
+ kind: groups.kind === "Error" ? "error" : "warning",
140
+ message: groups.message,
141
+ rule: groups.rule || void 0,
142
+ location: {
143
+ line: parseInt(groups.line, 10),
144
+ column: parseInt(groups.column, 10)
145
+ }
146
+ });
147
+ return acc;
148
+ }, []);
149
+ return stdout.trim().split(/\r?\n/).map((line) => line.trim()).filter((line) => !!line && !line.includes(" ")).map((line) => ({
150
+ file: line.trim(),
151
+ kind: "warning",
152
+ message: "Not formatted."
153
+ }));
154
+ };
155
+
156
+ //#endregion
157
+ //#region src/tools/prettier.ts
158
+ const prettier = ({ root }) => {
159
+ const checkCmd = "prettier . --list-different";
160
+ const fixCmd = "prettier . -w";
161
+ return {
162
+ name: "Prettier",
163
+ packageName: "prettier",
164
+ check: () => execAndParse(checkCmd, root, parseOutput$2),
165
+ fix: () => execAndParse(fixCmd, root, parseOutput$2)
166
+ };
167
+ };
168
+ const parseOutput$2 = ({ stdout, stderr }) => {
169
+ if (stderr.trim()) return stderr.split(/\r?\n/).reduce((acc, line) => {
170
+ const groups = /^\[(?<kind>.+?)\]\s?(?<file>.+?):\s?(?<message>.*?)\s?\((?<line>[0-9]+):(?<column>[0-9]+)\)$/.exec(line)?.groups;
171
+ if (groups) acc.push({
172
+ file: groups.file,
173
+ kind: groups.kind === "error" ? "error" : "warning",
174
+ message: groups.message,
175
+ location: {
176
+ line: parseInt(groups.line, 10),
177
+ column: parseInt(groups.column, 10)
178
+ }
179
+ });
180
+ return acc;
181
+ }, []);
182
+ return stdout.trim().split(/\r?\n/).map((line) => line.trim()).filter((line) => !!line && !line.includes(" ")).map((line) => ({
183
+ file: line.trim(),
184
+ kind: "warning",
185
+ message: "Not formatted."
186
+ }));
187
+ };
188
+
189
+ //#endregion
190
+ //#region src/tools/publint.ts
191
+ const publint = ({ root }) => {
192
+ const cmd = "publint";
193
+ return {
194
+ name: "Publint",
195
+ packageName: "publint",
196
+ check: () => execAndParse(cmd, root, parseOutput$1)
197
+ };
198
+ };
199
+ const parseOutput$1 = ({ stdout }) => {
200
+ let kind = "warning";
201
+ return stdout.split(/\r?\n/).reduce((acc, line) => {
202
+ if (line.includes("Errors:")) {
203
+ kind = "error";
204
+ return acc;
205
+ }
206
+ const groups = /^[0-9]+\.\s?(?<message>.*)$/.exec(line)?.groups;
207
+ if (groups == null) return acc;
208
+ acc.push({
209
+ kind,
210
+ message: groups.message,
211
+ file: "package.json"
212
+ });
213
+ return acc;
214
+ }, []);
215
+ };
216
+
217
+ //#endregion
218
+ //#region src/tools/typescript.ts
219
+ const typescript = async ({ root, packageJson }) => {
220
+ const tsc = {
221
+ name: "TypeScript",
222
+ cmd: "tsc --noEmit --pretty false",
223
+ packageName: "typescript"
224
+ };
225
+ const vueTsc = {
226
+ name: "TypeScript (Vue)",
227
+ cmd: "vue-tsc --noEmit --pretty false",
228
+ packageName: "vue-tsc"
229
+ };
230
+ const isVueTsc = packageJson.devDependencies?.["vue-tsc"] !== void 0;
231
+ debug("TypeScript: Is vue-tsc installed? " + isVueTsc);
232
+ const mod = isVueTsc ? vueTsc : tsc;
233
+ return {
234
+ name: mod.name,
235
+ packageName: mod.packageName,
236
+ check: async () => execAndParse(mod.cmd, root, parseOutput)
237
+ };
238
+ };
239
+ const parseOutput = ({ stdout }) => {
240
+ return stdout.split(/\r?\n/).reduce((acc, line) => {
241
+ const groups = /^(?<file>\S+?)\((?<line>[0-9]+),(?<column>[0-9]+)\): \w+? (?<rule>TS[0-9]+): (?<message>.*)$/.exec(line)?.groups;
242
+ if (groups) acc.push({
243
+ file: groups.file,
244
+ kind: "error",
245
+ message: groups.message,
246
+ location: {
247
+ line: parseInt(groups.line, 10),
248
+ column: parseInt(groups.column, 10)
249
+ },
250
+ rule: groups.rule
251
+ });
252
+ return acc;
253
+ }, []);
254
+ };
255
+
256
+ //#endregion
257
+ //#region src/tools/index.ts
258
+ const ALL_TOOLS = [
259
+ eslint,
260
+ markdownlint,
261
+ oxlint,
262
+ prettier,
263
+ publint,
264
+ typescript
265
+ ];
266
+
267
+ //#endregion
268
+ //#region src/tasklist/index.ts
269
+ async function createTaskList(inputs, run) {
270
+ const states = inputs.map((item) => ({
271
+ title: item.name,
272
+ state: "pending"
273
+ }));
274
+ const isTty = process.stderr.isTTY;
275
+ let tick = 0;
276
+ const render = (opts) => {
277
+ if (isTty && !opts?.firstRender) readline.moveCursor(process.stderr, 0, -1 * states.length);
278
+ if (isTty || opts?.firstRender || opts?.lastRender) states.forEach(({ state, title }) => {
279
+ readline.clearLine(process.stderr, 0);
280
+ const frames = SPINNER_FRAMES[state];
281
+ process.stderr.write(`${frames[tick % frames.length]} ${title}\n`);
282
+ });
283
+ tick++;
284
+ };
285
+ render({ firstRender: true });
286
+ const renderInterval = setInterval(render, SPINNER_INTERVAL_MS);
287
+ try {
288
+ const result = await Promise.all(inputs.map(async (input, i) => {
289
+ const succeed = (title) => {
290
+ if (title != null) states[i].title = title;
291
+ states[i].state = "success";
292
+ render();
293
+ };
294
+ const warn = (title) => {
295
+ if (title != null) states[i].title = title;
296
+ states[i].state = "warning";
297
+ render();
298
+ };
299
+ const fail = (title) => {
300
+ if (title != null) states[i].title = title;
301
+ states[i].state = "error";
302
+ render();
303
+ };
304
+ try {
305
+ states[i].state = "in-progress";
306
+ render();
307
+ const res = await run({
308
+ input,
309
+ succeed,
310
+ warn,
311
+ fail
312
+ });
313
+ if (states[i].state === "in-progress") states[i].state = "success";
314
+ render();
315
+ return res;
316
+ } catch (err) {
317
+ if (err instanceof Error) fail(err.message);
318
+ else fail(String(err));
319
+ render();
320
+ throw err;
321
+ }
322
+ }));
323
+ render({ lastRender: true });
324
+ return result;
325
+ } finally {
326
+ clearInterval(renderInterval);
327
+ }
328
+ }
329
+ const SPINNER_INTERVAL_MS = 80;
330
+ const SPINNER_FRAMES = {
331
+ pending: [dim("□")],
332
+ "in-progress": [
333
+ "⠋",
334
+ "⠙",
335
+ "⠹",
336
+ "⠸",
337
+ "⠼",
338
+ "⠴",
339
+ "⠦",
340
+ "⠧",
341
+ "⠇",
342
+ "⠏"
343
+ ].map(cyan),
344
+ success: [green("✔")],
345
+ warning: [yellow("⚠")],
346
+ error: [red("✗")]
347
+ };
348
+
349
+ //#endregion
350
+ //#region src/index.ts
351
+ async function check(options = {}) {
352
+ const { debug: debug$1, fix = !isCI, root = process.cwd() } = options;
353
+ const packageJson = JSON.parse(await readFile(join(root, "package.json"), "utf8"));
354
+ if (debug$1) process.env.DEBUG = "true";
355
+ console.log();
356
+ debug("Options:" + JSON.stringify(options));
357
+ debug("Resolved options:" + JSON.stringify({
358
+ debug: debug$1,
359
+ fix,
360
+ root,
361
+ packageJson
362
+ }));
363
+ const tools = await findInstalledTools({
364
+ root,
365
+ packageJson
366
+ });
367
+ if (tools.length === 0) {
368
+ if (isDebug()) console.log("No tools detected!");
369
+ else console.log("No tools detected! Run with --debug for more info");
370
+ console.log();
371
+ process.exit(1);
372
+ }
373
+ const problems = (await createTaskList(tools, async ({ input: tool, fail, succeed, warn }) => {
374
+ const startTime = performance.now();
375
+ const problems$1 = await (fix ? tool.fix ?? tool.check : tool.check)();
376
+ problems$1.forEach((problem) => {
377
+ problem.file = resolve(root ?? process.cwd(), problem.file);
378
+ });
379
+ const duration = humanMs(performance.now() - startTime);
380
+ const title = `${tool.name} ${dim(`(${duration})`)}`;
381
+ if (problems$1.filter((p) => p.kind === "error").length > 0) fail(title);
382
+ else if (problems$1.length > 0) warn(title);
383
+ else succeed(title);
384
+ return problems$1;
385
+ })).flat();
386
+ console.log();
387
+ if (problems.length === 0) process.exit(0);
388
+ console.log(plural(problems.length, "Problem:", "Problems:"));
389
+ problems.sort((l, r) => {
390
+ const nameCompare = l.file.localeCompare(r.file);
391
+ if (nameCompare !== 0) return nameCompare;
392
+ const lineCompare = (l.location?.line ?? 0) - (r.location?.line ?? 0);
393
+ if (lineCompare !== 0) return lineCompare;
394
+ return (l.location?.column ?? 0) - (r.location?.column ?? 0);
395
+ });
396
+ const groupedProblems = problems.reduce((acc, problem) => {
397
+ const locationHash = `${problem.file}:${problem.location?.line}:${problem.location?.column}`;
398
+ const list = acc.get(locationHash) ?? [];
399
+ list.push(problem);
400
+ acc.set(locationHash, list);
401
+ return acc;
402
+ }, /* @__PURE__ */ new Map());
403
+ console.log([...groupedProblems.values()].map(renderProblemGroup).join("\n"));
404
+ const files = Object.entries(problems.reduce((acc, problem) => {
405
+ const file = "." + sep + relative(process.cwd(), problem.file);
406
+ acc[file] ??= 0;
407
+ acc[file]++;
408
+ return acc;
409
+ }, {}));
410
+ const maxLength = files.reduce((prev, [file]) => Math.max(prev, file.length), 0);
411
+ console.log();
412
+ console.log("Across " + plural(files.length, "File:", "Files:"));
413
+ files.forEach(([file, count]) => {
414
+ console.log(`${cyan(file.padEnd(maxLength, " "))} ${count}`);
415
+ });
416
+ console.log();
417
+ process.exit(problems.length);
418
+ }
419
+ async function findInstalledTools(opts) {
420
+ const status = await Promise.all(ALL_TOOLS.map(async (def) => {
421
+ const tool = await def(opts);
422
+ return {
423
+ tool,
424
+ isInstalled: !!opts.packageJson.devDependencies?.[tool.packageName]
425
+ };
426
+ }));
427
+ if (isDebug()) {
428
+ const getTools = (isInstalled) => status.filter((item) => item.isInstalled === isInstalled).map((item) => item.tool.name).join(", ");
429
+ debug(`Installed: ${getTools(true) || "(none)"}`);
430
+ debug(`Skipping: ${getTools(false) || "(none)"} `);
431
+ }
432
+ return status.filter(({ isInstalled }) => isInstalled).map((item) => item.tool);
433
+ }
434
+ function plural(count, singular, plural$1) {
435
+ return `${count} ${count === 1 ? singular : plural$1} `;
436
+ }
437
+ function renderProblemGroup(problems) {
438
+ const renderedProblems = problems.map(renderProblem);
439
+ const problem = problems[0];
440
+ const path = relative(process.cwd(), problem.file);
441
+ const link = dim(`→ .${sep}${problem.location ? `${path}:${problem.location.line}:${problem.location.column}` : path}`);
442
+ return `${renderedProblems.join("\n")}\n ${link}`;
443
+ }
444
+ function renderProblem(problem) {
445
+ const icon = problem.kind === "warning" ? bold(yellow("⚠")) : bold(red("✗"));
446
+ const source = problem.rule ? dim(` (${problem.rule})`) : "";
447
+ return `${icon} ${problem.message}${source}`;
448
+ }
449
+
450
+ //#endregion
451
+ export { ALL_TOOLS as i, renderProblem as n, renderProblemGroup as r, check as t };
package/package.json CHANGED
@@ -1,11 +1,28 @@
1
1
  {
2
2
  "name": "@aklinker1/check",
3
- "version": "2.1.0",
4
- "packageManager": "bun@1.2.11",
3
+ "version": "2.1.2",
4
+ "packageManager": "bun@1.3.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "build": "tsdown src/index.ts src/cli.ts",
8
+ "check": "bun src/cli.ts",
9
+ "prepack": "bun run build",
10
+ "prepublish": "bun run build"
11
+ },
12
+ "dependencies": {
13
+ "ci-info": "*"
14
+ },
15
+ "devDependencies": {
16
+ "@types/bun": "latest",
17
+ "oxlint": "^1.22.0",
18
+ "publint": "^0.3.14",
19
+ "tsdown": "^0.15.9",
20
+ "typescript": "^5.9.3"
21
+ },
5
22
  "repository": {
6
- "type": "git",
7
23
  "url": "https://github.com/aklinker1/check"
8
24
  },
25
+ "license": "MIT",
9
26
  "homepage": "https://github.com/aklinker1/check",
10
27
  "author": {
11
28
  "name": "Aaron Klinker",
@@ -20,14 +37,13 @@
20
37
  "prettier",
21
38
  "typescript"
22
39
  ],
23
- "type": "module",
24
40
  "exports": {
25
41
  ".": {
26
42
  "types": "./dist/index.d.ts",
27
- "import": "./dist/index.mjs"
43
+ "import": "./dist/index.js"
28
44
  }
29
45
  },
30
- "module": "./dist/index.mjs",
46
+ "module": "./dist/index.js",
31
47
  "types": "./dist/index.d.ts",
32
48
  "files": [
33
49
  "bin",
@@ -35,36 +51,5 @@
35
51
  ],
36
52
  "bin": {
37
53
  "check": "bin/check.mjs"
38
- },
39
- "dependencies": {
40
- "@antfu/utils": "^0.7.7",
41
- "citty": "^0.1.6",
42
- "ci-info": "^4.0.0"
43
- },
44
- "devDependencies": {
45
- "@types/bun": "latest",
46
- "publint": "^0.2.7",
47
- "typescript": "^5.0.0",
48
- "unbuild": "latest"
49
- },
50
- "unbuild": {
51
- "entries": [
52
- {
53
- "builder": "mkdist",
54
- "input": "./src/",
55
- "outDir": "./dist"
56
- }
57
- ],
58
- "declaration": true
59
- },
60
- "changelog": {
61
- "excludeAuthors": [
62
- "aaronklinker1@gmail.com"
63
- ]
64
- },
65
- "scripts": {
66
- "build": "bunx --bun unbuild",
67
- "check": "bun src/cli.ts",
68
- "prepublish": "bun run build"
69
54
  }
70
- }
55
+ }
package/dist/cli.mjs DELETED
@@ -1,34 +0,0 @@
1
- import { defineCommand, runMain } from "citty";
2
- import { check } from "./index.mjs";
3
- const main = defineCommand({
4
- meta: {
5
- name: "check",
6
- description: "@aklinker1/check"
7
- },
8
- args: {
9
- root: {
10
- type: "positional",
11
- description: "Root directory to run commands from",
12
- required: false
13
- },
14
- fix: {
15
- type: "boolean",
16
- alias: "f",
17
- description: "Fix problems if possible instead of just reporting them"
18
- },
19
- debug: {
20
- type: "boolean",
21
- alias: "d",
22
- description: "Enable debug logs"
23
- },
24
- binDir: {
25
- type: "string",
26
- alias: "b",
27
- description: "Directory where binaries are located"
28
- }
29
- },
30
- async run(ctx) {
31
- await check(ctx.args);
32
- }
33
- });
34
- runMain(main);