@akanjs/devkit 3.1.1-rc.1 → 3.1.1-rc.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.
- package/biomeBase.test.ts +2 -2
- package/executors.test.ts +21 -1
- package/lint/gritRules.test.ts +3 -3
- package/linter.test.ts +18 -1
- package/linter.ts +10 -6
- package/package.json +2 -2
package/biomeBase.test.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { biomeBaseConfig } from "./biomeBase";
|
|
|
7
7
|
import { Linter, parseBiomeReport } from "./linter";
|
|
8
8
|
|
|
9
9
|
const devkitDir = import.meta.dir;
|
|
10
|
-
const
|
|
10
|
+
const [biome, ...biomeArgs] = Linter.biomeCommand(path.resolve(devkitDir, "../../.."));
|
|
11
11
|
|
|
12
12
|
const hookProbe = `export const Early = ({ id }: { id?: string }) => {
|
|
13
13
|
if (!id) return null;
|
|
@@ -28,7 +28,7 @@ afterAll(async () => {
|
|
|
28
28
|
|
|
29
29
|
const runBiome = (args: string[], cwd: string) =>
|
|
30
30
|
new Promise<string>((resolve, reject) => {
|
|
31
|
-
const proc = spawn(
|
|
31
|
+
const proc = spawn(biome, [...biomeArgs, ...args], { cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
32
32
|
let stdout = "";
|
|
33
33
|
let stderr = "";
|
|
34
34
|
proc.stdout.on("data", (chunk: Buffer) => (stdout += chunk.toString()));
|
package/executors.test.ts
CHANGED
|
@@ -1383,7 +1383,13 @@ describe("SysExecutor scan", () => {
|
|
|
1383
1383
|
expect(await lib.readFile("srvkit/index.ts")).toBe(
|
|
1384
1384
|
["a9", "a10", "aa", "aB"].map((name) => `export * from "./${name}";\n`).join(""),
|
|
1385
1385
|
);
|
|
1386
|
-
for (const file of [
|
|
1386
|
+
for (const file of [
|
|
1387
|
+
"ui/index.ts",
|
|
1388
|
+
"srvkit/index.ts",
|
|
1389
|
+
"lib/post/index.ts",
|
|
1390
|
+
"akan.lib.json",
|
|
1391
|
+
"env/env.server.type.ts",
|
|
1392
|
+
]) {
|
|
1387
1393
|
const generated = await lib.readFile(file);
|
|
1388
1394
|
expect(await formatWithBiome(generated, `libs/biomestable/${file}`)).toBe(generated);
|
|
1389
1395
|
}
|
|
@@ -1392,6 +1398,20 @@ describe("SysExecutor scan", () => {
|
|
|
1392
1398
|
expect(await devSync.syncForBatch(events)).toEqual({ changedFiles: [], errors: [] });
|
|
1393
1399
|
});
|
|
1394
1400
|
|
|
1401
|
+
test.skipIf(!hasBiome)(
|
|
1402
|
+
"writes env.server.type.ts the way Biome prints it, spreading libs in dependency order",
|
|
1403
|
+
async () => {
|
|
1404
|
+
const { default: getContent } = (await import("../cli/templates/env/_env.server.type")) as {
|
|
1405
|
+
default: (scanInfo: unknown) => { content: string };
|
|
1406
|
+
};
|
|
1407
|
+
const libs = ["util", "shared", "shopAdmin", "shop", "a10", "a9"];
|
|
1408
|
+
const { content } = getContent({ getLibs: () => libs });
|
|
1409
|
+
|
|
1410
|
+
expect(await formatWithBiome(content, "apps/biomestable/env/env.server.type.ts")).toBe(content);
|
|
1411
|
+
expect([...content.matchAll(/\.\.\.(\w+)Option/g)].map(([, lib]) => lib)).toEqual(libs);
|
|
1412
|
+
},
|
|
1413
|
+
);
|
|
1414
|
+
|
|
1395
1415
|
test("refuses a hand-written ui/index.tsx beside the generated barrel, naming the file and the fix", async () => {
|
|
1396
1416
|
const { lib } = await createScannableLib("shadowedbarrel", {
|
|
1397
1417
|
files: {
|
package/lint/gritRules.test.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { Linter } from "../linter";
|
|
|
11
11
|
const lintDir = import.meta.dir;
|
|
12
12
|
const fixturesDir = path.join(lintDir, "__fixtures__");
|
|
13
13
|
const workspaceRoot = path.resolve(lintDir, "../../../..");
|
|
14
|
-
const
|
|
14
|
+
const [biome, ...biomeArgs] = Linter.biomeCommand(workspaceRoot);
|
|
15
15
|
|
|
16
16
|
interface BiomeDiagnostic {
|
|
17
17
|
severity: string;
|
|
@@ -42,7 +42,7 @@ afterAll(async () => {
|
|
|
42
42
|
|
|
43
43
|
const runBiome = (args: string[], cwd: string) =>
|
|
44
44
|
new Promise<string>((resolve, reject) => {
|
|
45
|
-
const proc = spawn(
|
|
45
|
+
const proc = spawn(biome, [...biomeArgs, ...args], { cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
46
46
|
let stdout = "";
|
|
47
47
|
let stderr = "";
|
|
48
48
|
proc.stdout.on("data", (chunk: Buffer) => (stdout += chunk.toString()));
|
|
@@ -127,7 +127,7 @@ const fixtures = await collectCases();
|
|
|
127
127
|
|
|
128
128
|
describe("grit lint rules", () => {
|
|
129
129
|
test("the harness found the biome binary and at least one fixture", () => {
|
|
130
|
-
expect(
|
|
130
|
+
expect(biome).toBe(process.execPath);
|
|
131
131
|
expect(fixtures.length).toBeGreaterThan(0);
|
|
132
132
|
});
|
|
133
133
|
|
package/linter.test.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
|
-
import {
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { type BiomeReport, Linter, parseBiomeReport } from "./linter";
|
|
5
|
+
import { hasBiome } from "./testHelpers";
|
|
3
6
|
|
|
4
7
|
const reportOf = (diagnostics: BiomeReport["diagnostics"]): string =>
|
|
5
8
|
JSON.stringify({ summary: { errors: diagnostics?.length ?? 0, warnings: 0 }, diagnostics });
|
|
@@ -77,3 +80,17 @@ describe("parseBiomeReport", () => {
|
|
|
77
80
|
expect(() => parseBiomeReport(" \n")).toThrow("No Biome JSON output");
|
|
78
81
|
});
|
|
79
82
|
});
|
|
83
|
+
|
|
84
|
+
describe("Linter", () => {
|
|
85
|
+
test.skipIf(!hasBiome || process.platform === "win32")("runs Biome where no node is on PATH", async () => {
|
|
86
|
+
const pathBefore = process.env.PATH;
|
|
87
|
+
process.env.PATH = path.join(tmpdir(), "akan-path-without-node");
|
|
88
|
+
try {
|
|
89
|
+
const { results, errors } = await new Linter(import.meta.dir).lintFile(path.join(import.meta.dir, "linter.ts"));
|
|
90
|
+
expect(results).toHaveLength(1);
|
|
91
|
+
expect(errors).toEqual([]);
|
|
92
|
+
} finally {
|
|
93
|
+
process.env.PATH = pathBefore;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
});
|
package/linter.ts
CHANGED
|
@@ -113,18 +113,21 @@ const emptyResult = (filePath: string): LintResult => ({
|
|
|
113
113
|
});
|
|
114
114
|
|
|
115
115
|
export class Linter {
|
|
116
|
-
//?
|
|
117
|
-
|
|
116
|
+
//? The package's bin is npm's `#!/usr/bin/env node` wrapper, which picks the platform binary; run through the Bun
|
|
117
|
+
//? running akan, it works in an image with no Node (exit 127 otherwise). A Biome on PATH is the fallback.
|
|
118
|
+
static biomeCommand(root: string): [string, ...string[]] {
|
|
119
|
+
const wrapper = path.join(root, "node_modules", "@biomejs", "biome", "bin", "biome");
|
|
120
|
+
return existsSync(wrapper) ? [process.execPath, wrapper] : ["biome"];
|
|
121
|
+
}
|
|
118
122
|
|
|
119
123
|
lintRoot: string;
|
|
120
124
|
configPath: string;
|
|
121
|
-
#
|
|
125
|
+
#biomeCommand: [string, ...string[]];
|
|
122
126
|
|
|
123
127
|
constructor(cwdPath: string) {
|
|
124
128
|
this.lintRoot = this.#findBiomeRootPath(cwdPath);
|
|
125
129
|
this.configPath = Linter.#configPathIn(this.lintRoot) ?? path.join(this.lintRoot, "biome.json");
|
|
126
|
-
|
|
127
|
-
this.#biomeBin = existsSync(localBiomeBin) ? localBiomeBin : "biome";
|
|
130
|
+
this.#biomeCommand = Linter.biomeCommand(this.lintRoot);
|
|
128
131
|
}
|
|
129
132
|
|
|
130
133
|
static #configPathIn(dir: string): string | null {
|
|
@@ -158,7 +161,8 @@ export class Linter {
|
|
|
158
161
|
stderr: string;
|
|
159
162
|
code: number | null;
|
|
160
163
|
}>((resolve, reject) => {
|
|
161
|
-
const
|
|
164
|
+
const [command, ...prefixArgs] = this.#biomeCommand;
|
|
165
|
+
const proc = spawn(command, [...prefixArgs, ...args], {
|
|
162
166
|
cwd: this.lintRoot,
|
|
163
167
|
stdio: ["pipe", "pipe", "pipe"],
|
|
164
168
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akanjs/devkit",
|
|
3
|
-
"version": "3.1.1-rc.
|
|
3
|
+
"version": "3.1.1-rc.2",
|
|
4
4
|
"sourceType": "module",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"@earendil-works/pi-tui": "1.3.0",
|
|
49
49
|
"@inquirer/prompts": "^8.7.3",
|
|
50
50
|
"@tailwindcss/node": "^4.3.3",
|
|
51
|
-
"akanjs": "3.1.1-rc.
|
|
51
|
+
"akanjs": "3.1.1-rc.2",
|
|
52
52
|
"chalk": "^6.0.1",
|
|
53
53
|
"commander": "^15.0.0",
|
|
54
54
|
"dayjs": "^1.11.23",
|