@anaemia/cli 0.3.3 → 0.3.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/dist/commands/create.js +5 -40
- package/dist/commands/dev.js +2 -5
- package/dist/utils/flatten-ws-message.js +9 -0
- package/dist/utils/ts-to-js.js +39 -0
- package/package.json +5 -4
- package/src/commands/create.ts +6 -46
- package/src/commands/dev.ts +2 -3
- package/src/utils/flatten-ws-message.ts +6 -0
- package/src/utils/ts-to-js.ts +46 -0
- package/test/commands/create.test.mjs +73 -0
- package/test/commands/dev.test.mjs +17 -0
- package/test/fetch-template.test.mjs +23 -0
- package/src/types/rspack-dev-server.d.ts +0 -15
package/dist/commands/create.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import logger from "../utils/logger.js";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import fs from "fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import fs from "node:fs";
|
|
4
4
|
import pc from "picocolors";
|
|
5
5
|
import { generateSharedComponent, scaffoldFeature, scaffoldHook, scaffoldPage } from "../scaffold.js";
|
|
6
6
|
import prompts from "prompts";
|
|
7
|
-
import { transform } from "sucrase";
|
|
8
7
|
import { fileURLToPath } from "node:url";
|
|
9
8
|
import { fetchTemplate } from "../utils/fetch-template.js";
|
|
9
|
+
import { convertTypeScriptToJs } from "../utils/ts-to-js.js";
|
|
10
10
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
11
|
const __dirname = path.dirname(__filename);
|
|
12
12
|
export function register(cli) {
|
|
@@ -91,12 +91,9 @@ export function register(cli) {
|
|
|
91
91
|
else {
|
|
92
92
|
fs.mkdirSync(targetPath, { recursive: true });
|
|
93
93
|
}
|
|
94
|
-
|
|
95
|
-
if (!fs.existsSync(templatePath)) {
|
|
96
|
-
templatePath = path.resolve(__dirname, "../templates/base-app");
|
|
97
|
-
}
|
|
94
|
+
const templatePath = path.resolve(__dirname, "../templates/base-app");
|
|
98
95
|
if (fs.existsSync(templatePath)) {
|
|
99
|
-
logger.info("unpacking
|
|
96
|
+
logger.info("unpacking local template...");
|
|
100
97
|
fs.cpSync(templatePath, targetPath, {
|
|
101
98
|
recursive: true,
|
|
102
99
|
filter: (src) => !["node_modules", "dist", ".anaemia", ".rspack"].includes(path.basename(src)),
|
|
@@ -121,39 +118,7 @@ export function register(cli) {
|
|
|
121
118
|
removeGitKeepFiles(targetPath);
|
|
122
119
|
if (response.variant === "js") {
|
|
123
120
|
logger.info("converting workspace assets to vanilla JavaScript...");
|
|
124
|
-
const convertTypeScriptToJs = (dir) => {
|
|
125
|
-
const files = fs.readdirSync(dir);
|
|
126
|
-
for (const file of files) {
|
|
127
|
-
const fullPath = path.join(dir, file);
|
|
128
|
-
const stat = fs.statSync(fullPath);
|
|
129
|
-
if (stat.isDirectory()) {
|
|
130
|
-
convertTypeScriptToJs(fullPath);
|
|
131
|
-
}
|
|
132
|
-
else if (file.endsWith(".ts") || file.endsWith(".tsx")) {
|
|
133
|
-
const isTsx = file.endsWith(".tsx");
|
|
134
|
-
const code = fs.readFileSync(fullPath, "utf8");
|
|
135
|
-
try {
|
|
136
|
-
const compiled = transform(code, {
|
|
137
|
-
transforms: isTsx ? ["typescript", "jsx"] : ["typescript"],
|
|
138
|
-
jsxRuntime: "preserve",
|
|
139
|
-
production: true,
|
|
140
|
-
});
|
|
141
|
-
const newExt = isTsx ? ".jsx" : ".js";
|
|
142
|
-
const newPath = fullPath.replace(/\.tsx?$/, newExt);
|
|
143
|
-
fs.writeFileSync(newPath, compiled.code, "utf8");
|
|
144
|
-
fs.unlinkSync(fullPath);
|
|
145
|
-
}
|
|
146
|
-
catch {
|
|
147
|
-
logger.warn(`failed to strip types from ${file}, skipping...`);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
};
|
|
152
121
|
convertTypeScriptToJs(targetPath);
|
|
153
|
-
const tsconfigPath = path.join(targetPath, "tsconfig.json");
|
|
154
|
-
if (fs.existsSync(tsconfigPath)) {
|
|
155
|
-
fs.unlinkSync(tsconfigPath);
|
|
156
|
-
}
|
|
157
122
|
}
|
|
158
123
|
const pkgJsonPath = path.join(targetPath, "package.json");
|
|
159
124
|
if (fs.existsSync(pkgJsonPath)) {
|
package/dist/commands/dev.js
CHANGED
|
@@ -8,6 +8,7 @@ import { WebSocketServer } from "ws";
|
|
|
8
8
|
import { WebSocket as NodeWS } from "ws";
|
|
9
9
|
import { loadUserConfig } from "../utils/config.js";
|
|
10
10
|
import logger from "../utils/logger.js";
|
|
11
|
+
import { flattenWsMessage } from "../utils/flatten-ws-message.js";
|
|
11
12
|
export function register(cli) {
|
|
12
13
|
cli.command("dev", "launch local development environment").action(async () => {
|
|
13
14
|
process.env.NODE_ENV = "development";
|
|
@@ -22,11 +23,7 @@ export function register(cli) {
|
|
|
22
23
|
wss.on("connection", (clientWs) => {
|
|
23
24
|
const rspackSocket = new NodeWS(`ws://localhost:${targetPort + 1}/ws`);
|
|
24
25
|
rspackSocket.on("message", (data) => {
|
|
25
|
-
|
|
26
|
-
if (Buffer.isBuffer(flattened))
|
|
27
|
-
clientWs.send(flattened.toString("utf-8"));
|
|
28
|
-
else
|
|
29
|
-
clientWs.send(String(flattened));
|
|
26
|
+
clientWs.send(flattenWsMessage(data));
|
|
30
27
|
});
|
|
31
28
|
rspackSocket.on("error", (err) => {
|
|
32
29
|
console.warn("[anaemia hmr] rspack socket error:", err.message);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function flattenWsMessage(data) {
|
|
2
|
+
if (Array.isArray(data))
|
|
3
|
+
return Buffer.concat(data).toString("utf-8");
|
|
4
|
+
if (Buffer.isBuffer(data))
|
|
5
|
+
return data.toString("utf-8");
|
|
6
|
+
if (data instanceof ArrayBuffer)
|
|
7
|
+
return Buffer.from(data).toString("utf-8");
|
|
8
|
+
return String(data);
|
|
9
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { transform } from "sucrase";
|
|
4
|
+
import logger from "./logger.js";
|
|
5
|
+
export function convertTypeScriptToJs(dir) {
|
|
6
|
+
const files = fs.readdirSync(dir);
|
|
7
|
+
for (const file of files) {
|
|
8
|
+
const fullPath = path.join(dir, file);
|
|
9
|
+
const stat = fs.statSync(fullPath);
|
|
10
|
+
if (stat.isDirectory()) {
|
|
11
|
+
convertTypeScriptToJs(fullPath);
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
if (!file.endsWith(".ts") && !file.endsWith(".tsx"))
|
|
15
|
+
continue;
|
|
16
|
+
const isTsx = file.endsWith(".tsx");
|
|
17
|
+
const code = fs.readFileSync(fullPath, "utf8");
|
|
18
|
+
try {
|
|
19
|
+
const compiled = transform(code, {
|
|
20
|
+
transforms: isTsx ? ["typescript", "jsx"] : ["typescript"],
|
|
21
|
+
jsxRuntime: "preserve",
|
|
22
|
+
production: true,
|
|
23
|
+
});
|
|
24
|
+
const cleaned = compiled.code
|
|
25
|
+
.replace(/\n{3,}/g, "\n\n")
|
|
26
|
+
.trimStart();
|
|
27
|
+
const newPath = fullPath.replace(/\.tsx?$/, isTsx ? ".jsx" : ".js");
|
|
28
|
+
fs.writeFileSync(newPath, cleaned, "utf8");
|
|
29
|
+
fs.unlinkSync(fullPath);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
logger.warn(`failed to strip types from ${file}, skipping...`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const tsconfigPath = path.join(dir, "tsconfig.json");
|
|
36
|
+
if (fs.existsSync(tsconfigPath)) {
|
|
37
|
+
fs.unlinkSync(tsconfigPath);
|
|
38
|
+
}
|
|
39
|
+
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anaemia/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"anaemia": "./dist/index.js"
|
|
7
7
|
},
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@anaemia/bundler": "^0.3.
|
|
10
|
-
"@anaemia/core": "^0.3.
|
|
9
|
+
"@anaemia/bundler": "^0.3.4",
|
|
10
|
+
"@anaemia/core": "^0.3.4",
|
|
11
11
|
"@rspack/core": "^2.0.5",
|
|
12
12
|
"@rspack/dev-server": "2.0.1",
|
|
13
13
|
"cac": "^7.0.0",
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"scripts": {
|
|
29
29
|
"build": "tsc",
|
|
30
|
-
"dev": "tsc --watch"
|
|
30
|
+
"dev": "tsc --watch",
|
|
31
|
+
"test": "pnpm run build && node --test test/*.test.mjs test/commands/*.test.mjs"
|
|
31
32
|
}
|
|
32
33
|
}
|
package/src/commands/create.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { CAC } from "cac";
|
|
2
2
|
import logger from "../utils/logger.js";
|
|
3
|
-
import path from "path";
|
|
4
|
-
import fs from "fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import fs from "node:fs";
|
|
5
5
|
import pc from "picocolors";
|
|
6
6
|
import { generateSharedComponent, scaffoldFeature, scaffoldHook, scaffoldPage } from "../scaffold.js";
|
|
7
7
|
import prompts from "prompts";
|
|
8
|
-
import { transform } from "sucrase";
|
|
9
8
|
import { fileURLToPath } from "node:url";
|
|
10
9
|
import { fetchTemplate } from "../utils/fetch-template.js";
|
|
10
|
+
import { convertTypeScriptToJs } from "../utils/ts-to-js.js";
|
|
11
11
|
|
|
12
12
|
const __filename = fileURLToPath(import.meta.url);
|
|
13
13
|
const __dirname = path.dirname(__filename);
|
|
@@ -110,13 +110,10 @@ export function register(cli: CAC) {
|
|
|
110
110
|
fs.mkdirSync(targetPath, { recursive: true });
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
|
|
114
|
-
if (!fs.existsSync(templatePath)) {
|
|
115
|
-
templatePath = path.resolve(__dirname, "../templates/base-app");
|
|
116
|
-
}
|
|
113
|
+
const templatePath = path.resolve(__dirname, "../templates/base-app");
|
|
117
114
|
|
|
118
115
|
if (fs.existsSync(templatePath)) {
|
|
119
|
-
logger.info("unpacking
|
|
116
|
+
logger.info("unpacking local template...");
|
|
120
117
|
fs.cpSync(templatePath, targetPath, {
|
|
121
118
|
recursive: true,
|
|
122
119
|
filter: (src) => !["node_modules", "dist", ".anaemia", ".rspack"].includes(path.basename(src)),
|
|
@@ -137,49 +134,12 @@ export function register(cli: CAC) {
|
|
|
137
134
|
}
|
|
138
135
|
}
|
|
139
136
|
};
|
|
137
|
+
|
|
140
138
|
removeGitKeepFiles(targetPath);
|
|
141
139
|
|
|
142
140
|
if (response.variant === "js") {
|
|
143
141
|
logger.info("converting workspace assets to vanilla JavaScript...");
|
|
144
|
-
|
|
145
|
-
const convertTypeScriptToJs = (dir: string) => {
|
|
146
|
-
const files = fs.readdirSync(dir);
|
|
147
|
-
|
|
148
|
-
for (const file of files) {
|
|
149
|
-
const fullPath = path.join(dir, file);
|
|
150
|
-
const stat = fs.statSync(fullPath);
|
|
151
|
-
|
|
152
|
-
if (stat.isDirectory()) {
|
|
153
|
-
convertTypeScriptToJs(fullPath);
|
|
154
|
-
} else if (file.endsWith(".ts") || file.endsWith(".tsx")) {
|
|
155
|
-
const isTsx = file.endsWith(".tsx");
|
|
156
|
-
const code = fs.readFileSync(fullPath, "utf8");
|
|
157
|
-
|
|
158
|
-
try {
|
|
159
|
-
const compiled = transform(code, {
|
|
160
|
-
transforms: isTsx ? ["typescript", "jsx"] : ["typescript"],
|
|
161
|
-
jsxRuntime: "preserve",
|
|
162
|
-
production: true,
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
const newExt = isTsx ? ".jsx" : ".js";
|
|
166
|
-
const newPath = fullPath.replace(/\.tsx?$/, newExt);
|
|
167
|
-
|
|
168
|
-
fs.writeFileSync(newPath, compiled.code, "utf8");
|
|
169
|
-
fs.unlinkSync(fullPath);
|
|
170
|
-
} catch {
|
|
171
|
-
logger.warn(`failed to strip types from ${file}, skipping...`);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
};
|
|
176
|
-
|
|
177
142
|
convertTypeScriptToJs(targetPath);
|
|
178
|
-
|
|
179
|
-
const tsconfigPath = path.join(targetPath, "tsconfig.json");
|
|
180
|
-
if (fs.existsSync(tsconfigPath)) {
|
|
181
|
-
fs.unlinkSync(tsconfigPath);
|
|
182
|
-
}
|
|
183
143
|
}
|
|
184
144
|
|
|
185
145
|
const pkgJsonPath = path.join(targetPath, "package.json");
|
package/src/commands/dev.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { WebSocket as NodeWS } from "ws";
|
|
|
10
10
|
import { loadUserConfig } from "../utils/config.js";
|
|
11
11
|
import logger from "../utils/logger.js";
|
|
12
12
|
import { ChildProcess } from "node:child_process";
|
|
13
|
+
import { flattenWsMessage } from "../utils/flatten-ws-message.js";
|
|
13
14
|
|
|
14
15
|
export function register(cli: CAC) {
|
|
15
16
|
cli.command("dev", "launch local development environment").action(async () => {
|
|
@@ -31,9 +32,7 @@ export function register(cli: CAC) {
|
|
|
31
32
|
const rspackSocket = new NodeWS(`ws://localhost:${targetPort + 1}/ws`);
|
|
32
33
|
|
|
33
34
|
rspackSocket.on("message", (data) => {
|
|
34
|
-
|
|
35
|
-
if (Buffer.isBuffer(flattened)) clientWs.send(flattened.toString("utf-8"));
|
|
36
|
-
else clientWs.send(String(flattened));
|
|
35
|
+
clientWs.send(flattenWsMessage(data));
|
|
37
36
|
});
|
|
38
37
|
|
|
39
38
|
rspackSocket.on("error", (err) => {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export function flattenWsMessage(data: Buffer | Buffer[] | ArrayBuffer | string): string {
|
|
2
|
+
if (Array.isArray(data)) return Buffer.concat(data).toString("utf-8");
|
|
3
|
+
if (Buffer.isBuffer(data)) return data.toString("utf-8");
|
|
4
|
+
if (data instanceof ArrayBuffer) return Buffer.from(data).toString("utf-8");
|
|
5
|
+
return String(data);
|
|
6
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { transform } from "sucrase";
|
|
4
|
+
import logger from "./logger.js";
|
|
5
|
+
|
|
6
|
+
export function convertTypeScriptToJs(dir: string): void {
|
|
7
|
+
const files = fs.readdirSync(dir);
|
|
8
|
+
|
|
9
|
+
for (const file of files) {
|
|
10
|
+
const fullPath = path.join(dir, file);
|
|
11
|
+
const stat = fs.statSync(fullPath);
|
|
12
|
+
|
|
13
|
+
if (stat.isDirectory()) {
|
|
14
|
+
convertTypeScriptToJs(fullPath);
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (!file.endsWith(".ts") && !file.endsWith(".tsx")) continue;
|
|
19
|
+
|
|
20
|
+
const isTsx = file.endsWith(".tsx");
|
|
21
|
+
const code = fs.readFileSync(fullPath, "utf8");
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
const compiled = transform(code, {
|
|
25
|
+
transforms: isTsx ? ["typescript", "jsx"] : ["typescript"],
|
|
26
|
+
jsxRuntime: "preserve",
|
|
27
|
+
production: true,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const cleaned = compiled.code
|
|
31
|
+
.replace(/\n{3,}/g, "\n\n")
|
|
32
|
+
.trimStart();
|
|
33
|
+
|
|
34
|
+
const newPath = fullPath.replace(/\.tsx?$/, isTsx ? ".jsx" : ".js");
|
|
35
|
+
fs.writeFileSync(newPath, cleaned, "utf8");
|
|
36
|
+
fs.unlinkSync(fullPath);
|
|
37
|
+
} catch {
|
|
38
|
+
logger.warn(`failed to strip types from ${file}, skipping...`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const tsconfigPath = path.join(dir, "tsconfig.json");
|
|
43
|
+
if (fs.existsSync(tsconfigPath)) {
|
|
44
|
+
fs.unlinkSync(tsconfigPath);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import os from "node:os";
|
|
6
|
+
|
|
7
|
+
function createTmpDir() {
|
|
8
|
+
return fs.mkdtempSync(path.join(os.tmpdir(), "anaemia-create-test-"));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
test("convertTypeScriptToJs strips types from .ts files", async () => {
|
|
12
|
+
const dir = createTmpDir();
|
|
13
|
+
try {
|
|
14
|
+
fs.writeFileSync(path.join(dir, "index.ts"), `const x: string = "hello";\nexport default x;\n`);
|
|
15
|
+
|
|
16
|
+
const { convertTypeScriptToJs } = await import("../../dist/utils/ts-to-js.js");
|
|
17
|
+
convertTypeScriptToJs(dir);
|
|
18
|
+
|
|
19
|
+
assert.ok(!fs.existsSync(path.join(dir, "index.ts")), "ts file should be removed");
|
|
20
|
+
assert.ok(fs.existsSync(path.join(dir, "index.js")), "js file should exist");
|
|
21
|
+
const content = fs.readFileSync(path.join(dir, "index.js"), "utf-8");
|
|
22
|
+
assert.ok(!content.includes(": string"), "type annotation should be stripped");
|
|
23
|
+
} finally {
|
|
24
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("convertTypeScriptToJs strips types from .tsx files", async () => {
|
|
29
|
+
const dir = createTmpDir();
|
|
30
|
+
try {
|
|
31
|
+
fs.writeFileSync(path.join(dir, "Component.tsx"), `export default function Comp(props: { name: string }) {\n return <div>{props.name}</div>;\n}\n`);
|
|
32
|
+
|
|
33
|
+
const { convertTypeScriptToJs } = await import("../../dist/utils/ts-to-js.js");
|
|
34
|
+
convertTypeScriptToJs(dir);
|
|
35
|
+
|
|
36
|
+
assert.ok(!fs.existsSync(path.join(dir, "Component.tsx")));
|
|
37
|
+
assert.ok(fs.existsSync(path.join(dir, "Component.jsx")));
|
|
38
|
+
const content = fs.readFileSync(path.join(dir, "Component.jsx"), "utf-8");
|
|
39
|
+
assert.ok(!content.includes(": string"));
|
|
40
|
+
} finally {
|
|
41
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("convertTypeScriptToJs cleans up leading blank lines", async () => {
|
|
46
|
+
const dir = createTmpDir();
|
|
47
|
+
try {
|
|
48
|
+
fs.writeFileSync(path.join(dir, "root.tsx"), `import { JSX } from "solid-js";\n\nexport default function Root(props: { children: JSX.Element }) {\n return <>{props.children}</>;\n}\n`);
|
|
49
|
+
|
|
50
|
+
const { convertTypeScriptToJs } = await import("../../dist/utils/ts-to-js.js");
|
|
51
|
+
convertTypeScriptToJs(dir);
|
|
52
|
+
|
|
53
|
+
const content = fs.readFileSync(path.join(dir, "root.jsx"), "utf-8");
|
|
54
|
+
assert.ok(!content.startsWith("\n"), "file should not start with blank lines");
|
|
55
|
+
} finally {
|
|
56
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("convertTypeScriptToJs removes tsconfig.json", async () => {
|
|
61
|
+
const dir = createTmpDir();
|
|
62
|
+
try {
|
|
63
|
+
fs.writeFileSync(path.join(dir, "tsconfig.json"), JSON.stringify({ compilerOptions: {} }));
|
|
64
|
+
fs.writeFileSync(path.join(dir, "index.ts"), `export const x = 1;\n`);
|
|
65
|
+
|
|
66
|
+
const { convertTypeScriptToJs } = await import("../../dist/utils/ts-to-js.js");
|
|
67
|
+
convertTypeScriptToJs(dir);
|
|
68
|
+
|
|
69
|
+
assert.ok(!fs.existsSync(path.join(dir, "tsconfig.json")));
|
|
70
|
+
} finally {
|
|
71
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
72
|
+
}
|
|
73
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { flattenWsMessage } from "../../dist/utils/flatten-ws-message.js";
|
|
4
|
+
|
|
5
|
+
test("flattenWsMessage handles a plain string", () => {
|
|
6
|
+
assert.equal(flattenWsMessage("hello"), "hello");
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
test("flattenWsMessage handles a single Buffer", () => {
|
|
10
|
+
const buf = Buffer.from("hello");
|
|
11
|
+
assert.equal(flattenWsMessage(buf), "hello");
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test("flattenWsMessage concatenates a Buffer array", () => {
|
|
15
|
+
const bufs = [Buffer.from("hel"), Buffer.from("lo")];
|
|
16
|
+
assert.equal(flattenWsMessage(bufs), "hello");
|
|
17
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
|
|
7
|
+
import { fetchTemplate } from "../dist/utils/fetch-template.js";
|
|
8
|
+
|
|
9
|
+
test("fetchTemplate extracts template contents directly into target directory", async () => {
|
|
10
|
+
const targetDir = fs.mkdtempSync(path.join(os.tmpdir(), "anaemia-template-"));
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
await fetchTemplate(targetDir);
|
|
14
|
+
|
|
15
|
+
const files = fs.readdirSync(targetDir);
|
|
16
|
+
assert.ok(files.includes("package.json"), "missing package.json");
|
|
17
|
+
assert.ok(files.includes("src"), "missing src directory");
|
|
18
|
+
assert.ok(files.includes("anaemia.config.ts"), "missing anaemia.config.ts");
|
|
19
|
+
assert.ok(!files.includes("base-app"), "base-app subdirectory should not exist");
|
|
20
|
+
} finally {
|
|
21
|
+
fs.rmSync(targetDir, { recursive: true, force: true });
|
|
22
|
+
}
|
|
23
|
+
});
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
// fuck you typescript
|
|
2
|
-
|
|
3
|
-
declare module "@rspack/dev-server" {
|
|
4
|
-
import type { Compiler, MultiCompiler, DevServer } from "@rspack/core";
|
|
5
|
-
|
|
6
|
-
export type DevServerConfiguration = DevServer;
|
|
7
|
-
|
|
8
|
-
export class RspackDevServer {
|
|
9
|
-
constructor(config: DevServer, compiler: Compiler | MultiCompiler);
|
|
10
|
-
start(): Promise<void>;
|
|
11
|
-
stop(): Promise<void>;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export default RspackDevServer;
|
|
15
|
-
}
|