@collie-lang/cli 1.1.1 → 1.2.0
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/index.js +300 -382
- package/dist/index.js.map +1 -1
- package/package.json +18 -22
- package/LICENSE +0 -21
- package/dist/index.cjs +0 -2588
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -2
package/dist/index.js
CHANGED
|
@@ -1,42 +1,64 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
18
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
19
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
20
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
21
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
22
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
23
|
+
mod
|
|
24
|
+
));
|
|
2
25
|
|
|
3
26
|
// src/index.ts
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
import prompts2 from "prompts";
|
|
27
|
+
var import_node_child_process2 = require("child_process");
|
|
28
|
+
var import_promises8 = __toESM(require("fs/promises"));
|
|
29
|
+
var import_node_fs3 = require("fs");
|
|
30
|
+
var import_node_path8 = __toESM(require("path"));
|
|
31
|
+
var import_typescript = __toESM(require("typescript"));
|
|
32
|
+
var import_fast_glob4 = __toESM(require("fast-glob"));
|
|
33
|
+
var import_diff = require("diff");
|
|
34
|
+
var import_picocolors7 = __toESM(require("picocolors"));
|
|
35
|
+
var import_prompts2 = __toESM(require("prompts"));
|
|
14
36
|
|
|
15
37
|
// src/formatter.ts
|
|
16
|
-
|
|
17
|
-
|
|
38
|
+
var import_promises = __toESM(require("fs/promises"));
|
|
39
|
+
var import_compiler = require("@collie-lang/compiler");
|
|
18
40
|
function formatSource(source, options = {}) {
|
|
19
|
-
return formatCollie(source, options);
|
|
41
|
+
return (0, import_compiler.formatCollie)(source, options);
|
|
20
42
|
}
|
|
21
43
|
|
|
22
44
|
// src/watcher.ts
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
45
|
+
var import_chokidar = __toESM(require("chokidar"));
|
|
46
|
+
var import_compiler2 = require("@collie-lang/compiler");
|
|
47
|
+
var import_promises2 = __toESM(require("fs/promises"));
|
|
48
|
+
var import_node_path2 = __toESM(require("path"));
|
|
49
|
+
var import_picocolors = __toESM(require("picocolors"));
|
|
28
50
|
|
|
29
51
|
// src/fs-utils.ts
|
|
30
|
-
|
|
52
|
+
var import_node_path = __toESM(require("path"));
|
|
31
53
|
function resolveOutputPath(filepath, baseDir, outDir) {
|
|
32
54
|
const outputBase = outDir ?? baseDir;
|
|
33
|
-
const relative =
|
|
34
|
-
const ext =
|
|
55
|
+
const relative = import_node_path.default.relative(baseDir, filepath);
|
|
56
|
+
const ext = import_node_path.default.extname(relative);
|
|
35
57
|
const withoutExt = ext ? relative.slice(0, -ext.length) : relative;
|
|
36
|
-
return
|
|
58
|
+
return import_node_path.default.join(outputBase, `${withoutExt}.tsx`);
|
|
37
59
|
}
|
|
38
60
|
function toDisplayPath(target) {
|
|
39
|
-
const relative =
|
|
61
|
+
const relative = import_node_path.default.relative(process.cwd(), target);
|
|
40
62
|
if (!relative || relative.startsWith("..") || relative.startsWith("..\\")) {
|
|
41
63
|
return target;
|
|
42
64
|
}
|
|
@@ -45,21 +67,21 @@ function toDisplayPath(target) {
|
|
|
45
67
|
|
|
46
68
|
// src/watcher.ts
|
|
47
69
|
async function watch(inputPath, options = {}) {
|
|
48
|
-
const resolvedInput =
|
|
70
|
+
const resolvedInput = import_node_path2.default.resolve(process.cwd(), inputPath);
|
|
49
71
|
let stats;
|
|
50
72
|
try {
|
|
51
|
-
stats = await
|
|
73
|
+
stats = await import_promises2.default.stat(resolvedInput);
|
|
52
74
|
} catch {
|
|
53
75
|
throw new Error(`Input path does not exist: ${inputPath}`);
|
|
54
76
|
}
|
|
55
77
|
const isDirectory = stats.isDirectory();
|
|
56
78
|
const ext = normalizeExtension(options.ext);
|
|
57
|
-
const baseDir = isDirectory ? resolvedInput :
|
|
58
|
-
const outDir = options.outDir ?
|
|
59
|
-
const pattern = isDirectory ?
|
|
60
|
-
console.log(
|
|
79
|
+
const baseDir = isDirectory ? resolvedInput : import_node_path2.default.dirname(resolvedInput);
|
|
80
|
+
const outDir = options.outDir ? import_node_path2.default.resolve(process.cwd(), options.outDir) : void 0;
|
|
81
|
+
const pattern = isDirectory ? import_node_path2.default.join(resolvedInput, `**/*${ext}`) : resolvedInput;
|
|
82
|
+
console.log(import_picocolors.default.cyan(`Watching ${toDisplayPath(resolvedInput)} for changes...
|
|
61
83
|
`));
|
|
62
|
-
const watcher =
|
|
84
|
+
const watcher = import_chokidar.default.watch(pattern, {
|
|
63
85
|
ignored: /node_modules/,
|
|
64
86
|
persistent: true,
|
|
65
87
|
ignoreInitial: false
|
|
@@ -69,7 +91,7 @@ async function watch(inputPath, options = {}) {
|
|
|
69
91
|
});
|
|
70
92
|
watcher.on("change", (file) => {
|
|
71
93
|
if (options.verbose) {
|
|
72
|
-
console.log(
|
|
94
|
+
console.log(import_picocolors.default.gray(`[${getTimestamp()}] Changed: ${toDisplayPath(file)}`));
|
|
73
95
|
}
|
|
74
96
|
void compileFile(file, baseDir, outDir, options);
|
|
75
97
|
});
|
|
@@ -77,20 +99,20 @@ async function watch(inputPath, options = {}) {
|
|
|
77
99
|
void deleteCompiledFile(file, baseDir, outDir, options);
|
|
78
100
|
});
|
|
79
101
|
watcher.on("ready", () => {
|
|
80
|
-
console.log(
|
|
102
|
+
console.log(import_picocolors.default.green("\nWatching for file changes...\n"));
|
|
81
103
|
});
|
|
82
104
|
await new Promise((resolve, reject) => {
|
|
83
105
|
watcher.on("close", resolve);
|
|
84
106
|
watcher.on("error", (error) => {
|
|
85
107
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
86
|
-
console.error(
|
|
108
|
+
console.error(import_picocolors.default.red(`[collie] Watcher error: ${err.message}`));
|
|
87
109
|
reject(err);
|
|
88
110
|
});
|
|
89
111
|
process.once("SIGINT", () => {
|
|
90
|
-
console.log(
|
|
112
|
+
console.log(import_picocolors.default.yellow("\nStopping watch mode..."));
|
|
91
113
|
watcher.close().catch((error) => {
|
|
92
114
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
93
|
-
console.error(
|
|
115
|
+
console.error(import_picocolors.default.red(`[collie] Failed to stop watcher: ${err.message}`));
|
|
94
116
|
reject(err);
|
|
95
117
|
});
|
|
96
118
|
});
|
|
@@ -98,44 +120,44 @@ async function watch(inputPath, options = {}) {
|
|
|
98
120
|
}
|
|
99
121
|
async function compileFile(filepath, baseDir, outDir, options) {
|
|
100
122
|
try {
|
|
101
|
-
const source = await
|
|
102
|
-
const componentName =
|
|
123
|
+
const source = await import_promises2.default.readFile(filepath, "utf8");
|
|
124
|
+
const componentName = import_node_path2.default.basename(filepath, import_node_path2.default.extname(filepath));
|
|
103
125
|
const compileOptions = {
|
|
104
126
|
filename: filepath,
|
|
105
127
|
componentNameHint: componentName,
|
|
106
128
|
jsxRuntime: options.jsxRuntime ?? "automatic"
|
|
107
129
|
};
|
|
108
|
-
const result = compileToTsx(source, compileOptions);
|
|
130
|
+
const result = (0, import_compiler2.compileToTsx)(source, compileOptions);
|
|
109
131
|
const errors = result.diagnostics.filter((d) => d.severity === "error");
|
|
110
132
|
if (errors.length) {
|
|
111
133
|
logDiagnostics(filepath, errors);
|
|
112
134
|
return;
|
|
113
135
|
}
|
|
114
136
|
const outputPath = resolveOutputPath(filepath, baseDir, outDir);
|
|
115
|
-
await
|
|
116
|
-
await
|
|
137
|
+
await import_promises2.default.mkdir(import_node_path2.default.dirname(outputPath), { recursive: true });
|
|
138
|
+
await import_promises2.default.writeFile(outputPath, result.code, "utf8");
|
|
117
139
|
if (options.sourcemap && result.map) {
|
|
118
|
-
await
|
|
140
|
+
await import_promises2.default.writeFile(`${outputPath}.map`, JSON.stringify(result.map), "utf8");
|
|
119
141
|
}
|
|
120
|
-
console.log(
|
|
142
|
+
console.log(import_picocolors.default.green(`[${getTimestamp()}] Compiled ${toDisplayPath(filepath)} \u2192 ${toDisplayPath(outputPath)}`));
|
|
121
143
|
const warnings = result.diagnostics.filter((d) => d.severity === "warning");
|
|
122
144
|
if (warnings.length) {
|
|
123
145
|
logDiagnostics(filepath, warnings);
|
|
124
146
|
}
|
|
125
147
|
} catch (error) {
|
|
126
148
|
const message = error instanceof Error ? error.message : String(error);
|
|
127
|
-
console.error(
|
|
149
|
+
console.error(import_picocolors.default.red(`[collie] Failed to compile ${toDisplayPath(filepath)}: ${message}`));
|
|
128
150
|
}
|
|
129
151
|
}
|
|
130
152
|
async function deleteCompiledFile(filepath, baseDir, outDir, options) {
|
|
131
153
|
try {
|
|
132
154
|
const outputPath = resolveOutputPath(filepath, baseDir, outDir);
|
|
133
|
-
await
|
|
155
|
+
await import_promises2.default.unlink(outputPath);
|
|
134
156
|
if (options.sourcemap) {
|
|
135
|
-
await
|
|
157
|
+
await import_promises2.default.unlink(`${outputPath}.map`).catch(() => {
|
|
136
158
|
});
|
|
137
159
|
}
|
|
138
|
-
console.log(
|
|
160
|
+
console.log(import_picocolors.default.yellow(`[${getTimestamp()}] Deleted ${toDisplayPath(outputPath)}`));
|
|
139
161
|
} catch {
|
|
140
162
|
}
|
|
141
163
|
}
|
|
@@ -146,7 +168,7 @@ function logDiagnostics(file, diagnostics) {
|
|
|
146
168
|
const location = range ? `${range.start.line}:${range.start.col}` : "";
|
|
147
169
|
const prefix = location ? `${toDisplayPath(fileLabel)}:${location}` : toDisplayPath(fileLabel);
|
|
148
170
|
const code = diag.code ? ` (${diag.code})` : "";
|
|
149
|
-
const writer = diag.severity === "warning" ?
|
|
171
|
+
const writer = diag.severity === "warning" ? import_picocolors.default.yellow : import_picocolors.default.red;
|
|
150
172
|
console[diag.severity === "warning" ? "warn" : "error"](
|
|
151
173
|
writer(`${prefix ? `${prefix}: ` : ""}${diag.severity}${code}: ${diag.message}`)
|
|
152
174
|
);
|
|
@@ -163,27 +185,27 @@ function getTimestamp() {
|
|
|
163
185
|
}
|
|
164
186
|
|
|
165
187
|
// src/builder.ts
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
188
|
+
var import_fast_glob = __toESM(require("fast-glob"));
|
|
189
|
+
var import_compiler3 = require("@collie-lang/compiler");
|
|
190
|
+
var import_promises3 = __toESM(require("fs/promises"));
|
|
191
|
+
var import_node_path3 = __toESM(require("path"));
|
|
192
|
+
var import_picocolors3 = __toESM(require("picocolors"));
|
|
171
193
|
|
|
172
194
|
// src/output.ts
|
|
173
|
-
|
|
195
|
+
var import_picocolors2 = __toESM(require("picocolors"));
|
|
174
196
|
var SUMMARY_STYLES = {
|
|
175
|
-
success: { icon: "\u2714", color:
|
|
176
|
-
warning: { icon: "\u26A0", color:
|
|
177
|
-
error: { icon: "\u2716", color:
|
|
197
|
+
success: { icon: "\u2714", color: import_picocolors2.default.green },
|
|
198
|
+
warning: { icon: "\u26A0", color: import_picocolors2.default.yellow },
|
|
199
|
+
error: { icon: "\u2716", color: import_picocolors2.default.red }
|
|
178
200
|
};
|
|
179
201
|
function printSummary(kind, message, detail, nextStep) {
|
|
180
202
|
const style = SUMMARY_STYLES[kind];
|
|
181
203
|
console.log(style.color(`${style.icon} ${message}`));
|
|
182
204
|
if (detail) {
|
|
183
|
-
console.log(
|
|
205
|
+
console.log(import_picocolors2.default.dim(`Changed: ${detail}`));
|
|
184
206
|
}
|
|
185
207
|
if (nextStep) {
|
|
186
|
-
console.log(
|
|
208
|
+
console.log(import_picocolors2.default.dim(`Next: ${nextStep}`));
|
|
187
209
|
}
|
|
188
210
|
}
|
|
189
211
|
function formatDiagnosticLine(diag, fallbackFile) {
|
|
@@ -196,17 +218,17 @@ function formatDiagnosticLine(diag, fallbackFile) {
|
|
|
196
218
|
|
|
197
219
|
// src/builder.ts
|
|
198
220
|
async function build(input, options = {}) {
|
|
199
|
-
const resolvedInput =
|
|
221
|
+
const resolvedInput = import_node_path3.default.resolve(process.cwd(), input);
|
|
200
222
|
let stats;
|
|
201
223
|
try {
|
|
202
|
-
stats = await
|
|
224
|
+
stats = await import_promises3.default.stat(resolvedInput);
|
|
203
225
|
} catch {
|
|
204
226
|
throw new Error(`Input path does not exist: ${input}`);
|
|
205
227
|
}
|
|
206
228
|
const isDirectory = stats.isDirectory();
|
|
207
|
-
const baseDir = isDirectory ? resolvedInput :
|
|
208
|
-
const outDir = options.outDir ?
|
|
209
|
-
const files = isDirectory ? (await
|
|
229
|
+
const baseDir = isDirectory ? resolvedInput : import_node_path3.default.dirname(resolvedInput);
|
|
230
|
+
const outDir = options.outDir ? import_node_path3.default.resolve(process.cwd(), options.outDir) : void 0;
|
|
231
|
+
const files = isDirectory ? (await (0, import_fast_glob.default)("**/*.collie", { cwd: resolvedInput, absolute: true })).sort() : [resolvedInput];
|
|
210
232
|
if (!files.length) {
|
|
211
233
|
if (!options.quiet) {
|
|
212
234
|
printSummary(
|
|
@@ -219,7 +241,7 @@ async function build(input, options = {}) {
|
|
|
219
241
|
return { totalFiles: 0, successfulFiles: 0, errors: [] };
|
|
220
242
|
}
|
|
221
243
|
if (!options.quiet) {
|
|
222
|
-
console.log(
|
|
244
|
+
console.log(import_picocolors3.default.cyan(`Compiling ${toDisplayPath(resolvedInput)}...`));
|
|
223
245
|
console.log("");
|
|
224
246
|
}
|
|
225
247
|
const result = {
|
|
@@ -232,7 +254,7 @@ async function build(input, options = {}) {
|
|
|
232
254
|
if (compileResult.success) {
|
|
233
255
|
result.successfulFiles++;
|
|
234
256
|
if (!options.quiet) {
|
|
235
|
-
console.log(
|
|
257
|
+
console.log(import_picocolors3.default.green(`\u2714 ${toDisplayPath(file)} \u2192 ${toDisplayPath(compileResult.outputPath)}`));
|
|
236
258
|
}
|
|
237
259
|
if (options.verbose) {
|
|
238
260
|
logDiagnostics2(file, compileResult.diagnostics.filter((d) => d.severity === "warning"));
|
|
@@ -266,23 +288,23 @@ async function build(input, options = {}) {
|
|
|
266
288
|
}
|
|
267
289
|
async function compileSingleFile(filepath, baseDir, outDir, options) {
|
|
268
290
|
try {
|
|
269
|
-
const source = await
|
|
270
|
-
const componentName =
|
|
291
|
+
const source = await import_promises3.default.readFile(filepath, "utf8");
|
|
292
|
+
const componentName = import_node_path3.default.basename(filepath, import_node_path3.default.extname(filepath));
|
|
271
293
|
const compileOptions = {
|
|
272
294
|
filename: filepath,
|
|
273
295
|
componentNameHint: componentName,
|
|
274
296
|
jsxRuntime: options.jsxRuntime ?? "automatic"
|
|
275
297
|
};
|
|
276
|
-
const result =
|
|
298
|
+
const result = (0, import_compiler3.compileToTsx)(source, compileOptions);
|
|
277
299
|
const errors = result.diagnostics.filter((d) => d.severity === "error");
|
|
278
300
|
if (errors.length) {
|
|
279
301
|
return { success: false, diagnostics: errors };
|
|
280
302
|
}
|
|
281
303
|
const outputPath = resolveOutputPath(filepath, baseDir, outDir);
|
|
282
|
-
await
|
|
283
|
-
await
|
|
304
|
+
await import_promises3.default.mkdir(import_node_path3.default.dirname(outputPath), { recursive: true });
|
|
305
|
+
await import_promises3.default.writeFile(outputPath, result.code, "utf8");
|
|
284
306
|
if (options.sourcemap && result.map) {
|
|
285
|
-
await
|
|
307
|
+
await import_promises3.default.writeFile(`${outputPath}.map`, JSON.stringify(result.map), "utf8");
|
|
286
308
|
}
|
|
287
309
|
return { success: true, outputPath, diagnostics: result.diagnostics };
|
|
288
310
|
} catch (error) {
|
|
@@ -309,19 +331,19 @@ function logDiagnostics2(file, diagnostics, force = false) {
|
|
|
309
331
|
}
|
|
310
332
|
const displayFile = diag.file ? toDisplayPath(diag.file) : toDisplayPath(file);
|
|
311
333
|
const message = formatDiagnosticLine({ ...diag, file: displayFile }, toDisplayPath(file));
|
|
312
|
-
const writer = diag.severity === "warning" ?
|
|
334
|
+
const writer = diag.severity === "warning" ? import_picocolors3.default.yellow : import_picocolors3.default.red;
|
|
313
335
|
console[diag.severity === "warning" ? "warn" : "error"](writer(message));
|
|
314
336
|
}
|
|
315
337
|
}
|
|
316
338
|
|
|
317
339
|
// src/checker.ts
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
340
|
+
var import_fast_glob2 = __toESM(require("fast-glob"));
|
|
341
|
+
var import_compiler4 = require("@collie-lang/compiler");
|
|
342
|
+
var import_promises4 = __toESM(require("fs/promises"));
|
|
343
|
+
var import_node_path4 = __toESM(require("path"));
|
|
344
|
+
var import_picocolors4 = __toESM(require("picocolors"));
|
|
323
345
|
async function scanTemplates(patterns) {
|
|
324
|
-
const files = await
|
|
346
|
+
const files = await (0, import_fast_glob2.default)(patterns, {
|
|
325
347
|
absolute: true,
|
|
326
348
|
onlyFiles: true,
|
|
327
349
|
dot: false,
|
|
@@ -336,16 +358,16 @@ async function scanTemplates(patterns) {
|
|
|
336
358
|
for (const file of files) {
|
|
337
359
|
const displayPath = toDisplayPath(file);
|
|
338
360
|
try {
|
|
339
|
-
const source = await
|
|
361
|
+
const source = await import_promises4.default.readFile(file, "utf8");
|
|
340
362
|
lineCache.set(displayPath, source.split(/\r?\n/));
|
|
341
|
-
const parseResult = parseCollie(source, { filename: file });
|
|
363
|
+
const parseResult = (0, import_compiler4.parseCollie)(source, { filename: file });
|
|
342
364
|
for (const diag of parseResult.diagnostics) {
|
|
343
365
|
const range = diag.range ?? diag.span;
|
|
344
366
|
const normalized = {
|
|
345
367
|
...diag,
|
|
346
|
-
file: diag.file ? toDisplayPath(
|
|
368
|
+
file: diag.file ? toDisplayPath(import_node_path4.default.isAbsolute(diag.file) ? diag.file : import_node_path4.default.resolve(import_node_path4.default.dirname(file), diag.file)) : displayPath,
|
|
347
369
|
filePath: diag.filePath ? toDisplayPath(
|
|
348
|
-
|
|
370
|
+
import_node_path4.default.isAbsolute(diag.filePath) ? diag.filePath : import_node_path4.default.resolve(import_node_path4.default.dirname(file), diag.filePath)
|
|
349
371
|
) : displayPath,
|
|
350
372
|
range
|
|
351
373
|
};
|
|
@@ -451,7 +473,7 @@ async function check(patterns, options = {}) {
|
|
|
451
473
|
if ((options.format ?? "text") === "json") {
|
|
452
474
|
console.log(JSON.stringify(result, null, 2));
|
|
453
475
|
} else {
|
|
454
|
-
console.log(
|
|
476
|
+
console.log(import_picocolors4.default.cyan(`Checking ${scan.files.length} file${scan.files.length === 1 ? "" : "s"}...
|
|
455
477
|
`));
|
|
456
478
|
printTextDiagnostics(result, options, scan.lineCache);
|
|
457
479
|
}
|
|
@@ -462,7 +484,7 @@ function printTextDiagnostics(result, options, lineCache) {
|
|
|
462
484
|
if (hasDiagnostics) {
|
|
463
485
|
for (const diag of result.diagnostics) {
|
|
464
486
|
const message = formatDiagnosticLine(diag);
|
|
465
|
-
const writer = diag.severity === "warning" ?
|
|
487
|
+
const writer = diag.severity === "warning" ? import_picocolors4.default.yellow : import_picocolors4.default.red;
|
|
466
488
|
console.log(writer(message));
|
|
467
489
|
const range = diag.range ?? diag.span;
|
|
468
490
|
const fileLabel = diag.filePath ?? diag.file;
|
|
@@ -474,8 +496,8 @@ function printTextDiagnostics(result, options, lineCache) {
|
|
|
474
496
|
const markerStart = Math.max(0, range.start.col - 1);
|
|
475
497
|
const width = Math.max(1, range.end.col - range.start.col);
|
|
476
498
|
const indicator = `${" ".repeat(markerStart)}${"^".repeat(width)}`;
|
|
477
|
-
console.log(
|
|
478
|
-
console.log(
|
|
499
|
+
console.log(import_picocolors4.default.dim(` ${text}`));
|
|
500
|
+
console.log(import_picocolors4.default.dim(` ${indicator}`));
|
|
479
501
|
}
|
|
480
502
|
}
|
|
481
503
|
if (options.verbose) {
|
|
@@ -508,13 +530,12 @@ function printTextDiagnostics(result, options, lineCache) {
|
|
|
508
530
|
}
|
|
509
531
|
|
|
510
532
|
// src/creator.ts
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
import pc5 from "picocolors";
|
|
533
|
+
var import_prompts = __toESM(require("prompts"));
|
|
534
|
+
var import_promises5 = __toESM(require("fs/promises"));
|
|
535
|
+
var import_node_fs = require("fs");
|
|
536
|
+
var import_node_path5 = __toESM(require("path"));
|
|
537
|
+
var import_node_child_process = require("child_process");
|
|
538
|
+
var import_picocolors5 = __toESM(require("picocolors"));
|
|
518
539
|
var TEMPLATE_MAP = {
|
|
519
540
|
vite: {
|
|
520
541
|
label: "Vite + React",
|
|
@@ -523,21 +544,9 @@ var TEMPLATE_MAP = {
|
|
|
523
544
|
ts: "vite-react-ts",
|
|
524
545
|
js: "vite-react-js"
|
|
525
546
|
}
|
|
526
|
-
},
|
|
527
|
-
"nextjs-app-router": {
|
|
528
|
-
label: "Next.js App Router",
|
|
529
|
-
description: "Next.js 14 App Router starter wired with @collie-lang/next",
|
|
530
|
-
variants: {
|
|
531
|
-
ts: "nextjs-app-router-ts",
|
|
532
|
-
js: "nextjs-app-router-js"
|
|
533
|
-
}
|
|
534
547
|
}
|
|
535
548
|
};
|
|
536
|
-
var TEMPLATE_ALIASES = {
|
|
537
|
-
next: { template: "nextjs-app-router" },
|
|
538
|
-
nextjs: { template: "nextjs-app-router", forcedTypescript: true },
|
|
539
|
-
"nextjs-app": { template: "nextjs-app-router", forcedTypescript: true }
|
|
540
|
-
};
|
|
549
|
+
var TEMPLATE_ALIASES = {};
|
|
541
550
|
function formatTemplateList() {
|
|
542
551
|
return Object.entries(TEMPLATE_MAP).map(([key, meta]) => {
|
|
543
552
|
const variantInfo = [
|
|
@@ -553,38 +562,38 @@ function formatTemplateList() {
|
|
|
553
562
|
}
|
|
554
563
|
async function create(options = {}) {
|
|
555
564
|
const resolved = await promptForOptions(options);
|
|
556
|
-
const targetDir =
|
|
557
|
-
if (existsSync(targetDir)) {
|
|
565
|
+
const targetDir = import_node_path5.default.resolve(process.cwd(), resolved.projectName);
|
|
566
|
+
if ((0, import_node_fs.existsSync)(targetDir)) {
|
|
558
567
|
const overwrite = await confirmOverwrite(resolved.projectName);
|
|
559
568
|
if (!overwrite) {
|
|
560
|
-
console.log(
|
|
569
|
+
console.log(import_picocolors5.default.yellow("Cancelled"));
|
|
561
570
|
return;
|
|
562
571
|
}
|
|
563
|
-
await
|
|
572
|
+
await import_promises5.default.rm(targetDir, { recursive: true, force: true });
|
|
564
573
|
}
|
|
565
|
-
console.log(
|
|
574
|
+
console.log(import_picocolors5.default.cyan(`
|
|
566
575
|
Creating project in ${targetDir}...
|
|
567
576
|
`));
|
|
568
577
|
const templateDir = getTemplateDir(resolved.template, resolved.typescript);
|
|
569
578
|
await copyTemplate(templateDir, targetDir, resolved.projectName);
|
|
570
|
-
console.log(
|
|
579
|
+
console.log(import_picocolors5.default.green("\u2714 Copied template files"));
|
|
571
580
|
if (!resolved.noGit) {
|
|
572
581
|
try {
|
|
573
582
|
await runCommand("git", ["init"], targetDir);
|
|
574
|
-
console.log(
|
|
583
|
+
console.log(import_picocolors5.default.green("\u2714 Initialized git repository"));
|
|
575
584
|
} catch (error) {
|
|
576
585
|
const message = error instanceof Error ? error.message : String(error);
|
|
577
|
-
console.log(
|
|
586
|
+
console.log(import_picocolors5.default.yellow(`\u26A0 Failed to initialize git: ${message}`));
|
|
578
587
|
}
|
|
579
588
|
}
|
|
580
589
|
if (!resolved.noInstall) {
|
|
581
|
-
console.log(
|
|
590
|
+
console.log(import_picocolors5.default.cyan(`\u2714 Installing dependencies with ${resolved.packageManager}...`));
|
|
582
591
|
try {
|
|
583
592
|
await installDependencies(resolved.packageManager, targetDir);
|
|
584
593
|
} catch (error) {
|
|
585
594
|
const message = error instanceof Error ? error.message : String(error);
|
|
586
|
-
console.log(
|
|
587
|
-
console.log(
|
|
595
|
+
console.log(import_picocolors5.default.yellow(`\u26A0 Failed to install dependencies: ${message}`));
|
|
596
|
+
console.log(import_picocolors5.default.yellow(" Run the install command manually once you're ready."));
|
|
588
597
|
}
|
|
589
598
|
}
|
|
590
599
|
printSuccessMessage(resolved);
|
|
@@ -639,9 +648,9 @@ async function promptForOptions(options) {
|
|
|
639
648
|
initial: detected === "pnpm" ? 0 : detected === "npm" ? 1 : 2
|
|
640
649
|
});
|
|
641
650
|
}
|
|
642
|
-
const answers = questions.length > 0 ? await
|
|
651
|
+
const answers = questions.length > 0 ? await (0, import_prompts.default)(questions, {
|
|
643
652
|
onCancel: () => {
|
|
644
|
-
console.log(
|
|
653
|
+
console.log(import_picocolors5.default.yellow("\nCancelled"));
|
|
645
654
|
process.exit(0);
|
|
646
655
|
}
|
|
647
656
|
}) : {};
|
|
@@ -692,7 +701,7 @@ Usage: collie create <project-name> --template <template>`
|
|
|
692
701
|
);
|
|
693
702
|
}
|
|
694
703
|
async function confirmOverwrite(projectName) {
|
|
695
|
-
const { overwrite } = await
|
|
704
|
+
const { overwrite } = await (0, import_prompts.default)({
|
|
696
705
|
type: "confirm",
|
|
697
706
|
name: "overwrite",
|
|
698
707
|
message: `Directory ${projectName} already exists. Overwrite?`,
|
|
@@ -703,8 +712,8 @@ async function confirmOverwrite(projectName) {
|
|
|
703
712
|
function getTemplateDir(template, typescript) {
|
|
704
713
|
const meta = TEMPLATE_MAP[template];
|
|
705
714
|
const variant = typescript ? meta.variants.ts : meta.variants.js;
|
|
706
|
-
const dir =
|
|
707
|
-
if (!existsSync(dir)) {
|
|
715
|
+
const dir = import_node_path5.default.resolve(__dirname, "..", "templates", variant);
|
|
716
|
+
if (!(0, import_node_fs.existsSync)(dir)) {
|
|
708
717
|
throw new Error(
|
|
709
718
|
`Template '${template}' with ${typescript ? "TypeScript" : "JavaScript"} is not available.`
|
|
710
719
|
);
|
|
@@ -712,25 +721,25 @@ function getTemplateDir(template, typescript) {
|
|
|
712
721
|
return dir;
|
|
713
722
|
}
|
|
714
723
|
async function copyTemplate(templateDir, targetDir, projectName) {
|
|
715
|
-
await
|
|
724
|
+
await import_promises5.default.mkdir(targetDir, { recursive: true });
|
|
716
725
|
await copyDirectory(templateDir, targetDir, { projectName });
|
|
717
726
|
}
|
|
718
727
|
async function copyDirectory(source, target, context) {
|
|
719
|
-
const entries = await
|
|
728
|
+
const entries = await import_promises5.default.readdir(source, { withFileTypes: true });
|
|
720
729
|
for (const entry of entries) {
|
|
721
|
-
const srcPath =
|
|
730
|
+
const srcPath = import_node_path5.default.join(source, entry.name);
|
|
722
731
|
const destName = entry.name.endsWith(".template") ? entry.name.replace(/\.template$/, "") : entry.name;
|
|
723
|
-
const destPath =
|
|
732
|
+
const destPath = import_node_path5.default.join(target, destName);
|
|
724
733
|
if (entry.isDirectory()) {
|
|
725
|
-
await
|
|
734
|
+
await import_promises5.default.mkdir(destPath, { recursive: true });
|
|
726
735
|
await copyDirectory(srcPath, destPath, context);
|
|
727
736
|
} else {
|
|
728
|
-
const buffer = await
|
|
737
|
+
const buffer = await import_promises5.default.readFile(srcPath);
|
|
729
738
|
if (entry.name.endsWith(".template")) {
|
|
730
739
|
const content = buffer.toString("utf8").replace(/__PROJECT_NAME__/g, context.projectName);
|
|
731
|
-
await
|
|
740
|
+
await import_promises5.default.writeFile(destPath, content, "utf8");
|
|
732
741
|
} else {
|
|
733
|
-
await
|
|
742
|
+
await import_promises5.default.writeFile(destPath, buffer);
|
|
734
743
|
}
|
|
735
744
|
}
|
|
736
745
|
}
|
|
@@ -741,7 +750,7 @@ async function installDependencies(packageManager, cwd) {
|
|
|
741
750
|
}
|
|
742
751
|
function runCommand(command, args, cwd) {
|
|
743
752
|
return new Promise((resolve, reject) => {
|
|
744
|
-
const child = spawn(command, args, { cwd, stdio: "inherit" });
|
|
753
|
+
const child = (0, import_node_child_process.spawn)(command, args, { cwd, stdio: "inherit" });
|
|
745
754
|
child.on("error", reject);
|
|
746
755
|
child.on("close", (code) => {
|
|
747
756
|
if (code === 0) resolve();
|
|
@@ -760,35 +769,25 @@ function printSuccessMessage(config) {
|
|
|
760
769
|
const cdCommand = `cd ${config.projectName}`;
|
|
761
770
|
const installCommand = config.packageManager === "npm" ? "npm install" : `${config.packageManager} install`;
|
|
762
771
|
const devCommand = config.packageManager === "npm" ? "npm run dev" : `${config.packageManager} dev`;
|
|
763
|
-
console.log(
|
|
772
|
+
console.log(import_picocolors5.default.green(`
|
|
764
773
|
\u{1F389} Success! Created ${config.projectName}
|
|
765
774
|
`));
|
|
766
775
|
console.log("Next steps:");
|
|
767
|
-
console.log(
|
|
776
|
+
console.log(import_picocolors5.default.cyan(` ${cdCommand}`));
|
|
768
777
|
if (config.noInstall) {
|
|
769
|
-
console.log(
|
|
778
|
+
console.log(import_picocolors5.default.cyan(` ${installCommand}`));
|
|
770
779
|
}
|
|
771
|
-
console.log(
|
|
772
|
-
console.log(
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
// src/nextjs-setup.ts
|
|
776
|
-
import fs6 from "fs/promises";
|
|
777
|
-
import { existsSync as existsSync2 } from "fs";
|
|
778
|
-
import path6 from "path";
|
|
779
|
-
import pc6 from "picocolors";
|
|
780
|
-
import { detectNextDirectory } from "@collie-lang/next";
|
|
781
|
-
function hasNextDependency(pkg) {
|
|
782
|
-
return Boolean(pkg?.dependencies?.next || pkg?.devDependencies?.next);
|
|
780
|
+
console.log(import_picocolors5.default.cyan(` ${devCommand}`));
|
|
781
|
+
console.log(import_picocolors5.default.gray("\nHappy coding with Collie! \u{1F415}\n"));
|
|
783
782
|
}
|
|
784
783
|
|
|
785
784
|
// src/converter.ts
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
785
|
+
var import_promises6 = __toESM(require("fs/promises"));
|
|
786
|
+
var import_node_path6 = __toESM(require("path"));
|
|
787
|
+
var import_compiler5 = require("@collie-lang/compiler");
|
|
789
788
|
async function convertFile(filepath, options = {}) {
|
|
790
|
-
const source = await
|
|
791
|
-
const result = convertTsxToCollie(source, { filename: filepath });
|
|
789
|
+
const source = await import_promises6.default.readFile(filepath, "utf8");
|
|
790
|
+
const result = (0, import_compiler5.convertTsxToCollie)(source, { filename: filepath });
|
|
792
791
|
const { collie, warnings } = result;
|
|
793
792
|
let outputPath;
|
|
794
793
|
if (options.write) {
|
|
@@ -796,13 +795,13 @@ async function convertFile(filepath, options = {}) {
|
|
|
796
795
|
if (!options.overwrite) {
|
|
797
796
|
const exists = await fileExists(outputPath);
|
|
798
797
|
if (exists) {
|
|
799
|
-
throw new Error(`${
|
|
798
|
+
throw new Error(`${import_node_path6.default.relative(process.cwd(), outputPath)} already exists. Use --overwrite to replace.`);
|
|
800
799
|
}
|
|
801
800
|
}
|
|
802
|
-
await
|
|
803
|
-
await
|
|
801
|
+
await import_promises6.default.mkdir(import_node_path6.default.dirname(outputPath), { recursive: true });
|
|
802
|
+
await import_promises6.default.writeFile(outputPath, collie, "utf8");
|
|
804
803
|
if (options.removeOriginal) {
|
|
805
|
-
await
|
|
804
|
+
await import_promises6.default.unlink(filepath);
|
|
806
805
|
}
|
|
807
806
|
}
|
|
808
807
|
return { collie, warnings, outputPath };
|
|
@@ -812,7 +811,7 @@ function resolveOutputPath2(filepath) {
|
|
|
812
811
|
}
|
|
813
812
|
async function fileExists(filepath) {
|
|
814
813
|
try {
|
|
815
|
-
await
|
|
814
|
+
await import_promises6.default.access(filepath);
|
|
816
815
|
return true;
|
|
817
816
|
} catch {
|
|
818
817
|
return false;
|
|
@@ -820,14 +819,13 @@ async function fileExists(filepath) {
|
|
|
820
819
|
}
|
|
821
820
|
|
|
822
821
|
// src/doctor.ts
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
822
|
+
var import_compiler6 = require("@collie-lang/compiler");
|
|
823
|
+
var import_fast_glob3 = __toESM(require("fast-glob"));
|
|
824
|
+
var import_promises7 = __toESM(require("fs/promises"));
|
|
825
|
+
var import_node_fs2 = require("fs");
|
|
826
|
+
var import_node_path7 = __toESM(require("path"));
|
|
827
|
+
var import_picocolors6 = __toESM(require("picocolors"));
|
|
829
828
|
var VITE_CONFIG_FILES = ["vite.config.ts", "vite.config.js", "vite.config.mts", "vite.config.mjs"];
|
|
830
|
-
var NEXT_CONFIG_FILES = ["next.config.ts", "next.config.mjs", "next.config.js"];
|
|
831
829
|
var DECLARATION_CANDIDATES = ["src/collie.d.ts", "app/collie.d.ts", "collie.d.ts"];
|
|
832
830
|
async function runDoctor(options = {}) {
|
|
833
831
|
const cwd = options.cwd ?? process.cwd();
|
|
@@ -847,12 +845,6 @@ async function runDoctor(options = {}) {
|
|
|
847
845
|
results.push(viteDependency);
|
|
848
846
|
}
|
|
849
847
|
results.push(await checkViteConfig(context));
|
|
850
|
-
} else if (buildInfo.type === "nextjs") {
|
|
851
|
-
const nextDependency = checkDependency(context, "@collie-lang/next", "Collie Next.js integration", ["nextjs"]);
|
|
852
|
-
if (nextDependency) {
|
|
853
|
-
results.push(nextDependency);
|
|
854
|
-
}
|
|
855
|
-
results.push(await checkNextConfig(context));
|
|
856
848
|
}
|
|
857
849
|
results.push(await checkTypeDeclarations(context));
|
|
858
850
|
results.push(await checkCollieFiles(context));
|
|
@@ -875,16 +867,16 @@ function filterDiagnostics(results, filter) {
|
|
|
875
867
|
});
|
|
876
868
|
}
|
|
877
869
|
function printDoctorResults(results) {
|
|
878
|
-
console.log(
|
|
879
|
-
console.log(
|
|
870
|
+
console.log(import_picocolors6.default.bold("collie doctor"));
|
|
871
|
+
console.log(import_picocolors6.default.dim("Diagnosing your environment..."));
|
|
880
872
|
console.log("");
|
|
881
873
|
let errors = 0;
|
|
882
874
|
let warnings = 0;
|
|
883
875
|
for (const result of results) {
|
|
884
|
-
const icon = result.status === "pass" ?
|
|
876
|
+
const icon = result.status === "pass" ? import_picocolors6.default.green("\u2714") : result.status === "warn" ? import_picocolors6.default.yellow("\u26A0") : import_picocolors6.default.red("\u2716");
|
|
885
877
|
console.log(`${icon} ${result.check}: ${result.message}`);
|
|
886
878
|
if (result.fix) {
|
|
887
|
-
console.log(
|
|
879
|
+
console.log(import_picocolors6.default.dim(` Fix: ${result.fix}`));
|
|
888
880
|
}
|
|
889
881
|
console.log("");
|
|
890
882
|
if (result.status === "fail") {
|
|
@@ -963,19 +955,6 @@ function detectBuildSystem(context) {
|
|
|
963
955
|
};
|
|
964
956
|
}
|
|
965
957
|
const hasVite = hasDependency(context.packageJson, "vite");
|
|
966
|
-
const hasNext = hasDependency(context.packageJson, "next");
|
|
967
|
-
if (hasVite && hasNext) {
|
|
968
|
-
return {
|
|
969
|
-
type: "vite",
|
|
970
|
-
result: {
|
|
971
|
-
id: "build-system",
|
|
972
|
-
check: "Build system",
|
|
973
|
-
status: "warn",
|
|
974
|
-
message: "Both Vite and Next.js detected (defaulting to Vite)",
|
|
975
|
-
tags: ["build"]
|
|
976
|
-
}
|
|
977
|
-
};
|
|
978
|
-
}
|
|
979
958
|
if (hasVite) {
|
|
980
959
|
return {
|
|
981
960
|
type: "vite",
|
|
@@ -988,26 +967,14 @@ function detectBuildSystem(context) {
|
|
|
988
967
|
}
|
|
989
968
|
};
|
|
990
969
|
}
|
|
991
|
-
if (hasNext) {
|
|
992
|
-
return {
|
|
993
|
-
type: "nextjs",
|
|
994
|
-
result: {
|
|
995
|
-
id: "build-system",
|
|
996
|
-
check: "Build system",
|
|
997
|
-
status: "pass",
|
|
998
|
-
message: "Next.js detected",
|
|
999
|
-
tags: ["build", "nextjs"]
|
|
1000
|
-
}
|
|
1001
|
-
};
|
|
1002
|
-
}
|
|
1003
970
|
return {
|
|
1004
971
|
type: null,
|
|
1005
972
|
result: {
|
|
1006
973
|
id: "build-system",
|
|
1007
974
|
check: "Build system",
|
|
1008
975
|
status: "warn",
|
|
1009
|
-
message: "No Vite
|
|
1010
|
-
fix: "Install Vite
|
|
976
|
+
message: "No Vite dependency found",
|
|
977
|
+
fix: "Install Vite for the best Collie experience.",
|
|
1011
978
|
tags: ["build"]
|
|
1012
979
|
}
|
|
1013
980
|
};
|
|
@@ -1037,9 +1004,9 @@ function checkDependency(context, dependency, label, tags) {
|
|
|
1037
1004
|
}
|
|
1038
1005
|
async function checkViteConfig(context) {
|
|
1039
1006
|
for (const filename of VITE_CONFIG_FILES) {
|
|
1040
|
-
const configPath =
|
|
1041
|
-
if (!
|
|
1042
|
-
const contents = await
|
|
1007
|
+
const configPath = import_node_path7.default.join(context.cwd, filename);
|
|
1008
|
+
if (!(0, import_node_fs2.existsSync)(configPath)) continue;
|
|
1009
|
+
const contents = await import_promises7.default.readFile(configPath, "utf8");
|
|
1043
1010
|
const hasPlugin = /@collie-lang\/vite/.test(contents) && /collie\s*\(/.test(contents);
|
|
1044
1011
|
if (hasPlugin) {
|
|
1045
1012
|
return {
|
|
@@ -1068,43 +1035,10 @@ async function checkViteConfig(context) {
|
|
|
1068
1035
|
tags: ["vite", "config"]
|
|
1069
1036
|
};
|
|
1070
1037
|
}
|
|
1071
|
-
async function checkNextConfig(context) {
|
|
1072
|
-
for (const filename of NEXT_CONFIG_FILES) {
|
|
1073
|
-
const configPath = path8.join(context.cwd, filename);
|
|
1074
|
-
if (!existsSync3(configPath)) continue;
|
|
1075
|
-
const contents = await fs8.readFile(configPath, "utf8");
|
|
1076
|
-
const hasLoader = /@collie-lang\/next/.test(contents) || /withCollie\s*\(/.test(contents);
|
|
1077
|
-
if (hasLoader) {
|
|
1078
|
-
return {
|
|
1079
|
-
id: "next-config",
|
|
1080
|
-
check: "Next.js config",
|
|
1081
|
-
status: "pass",
|
|
1082
|
-
message: `Collie loader configured in ${filename}`,
|
|
1083
|
-
tags: ["nextjs", "config"]
|
|
1084
|
-
};
|
|
1085
|
-
}
|
|
1086
|
-
return {
|
|
1087
|
-
id: "next-config",
|
|
1088
|
-
check: "Next.js config",
|
|
1089
|
-
status: "fail",
|
|
1090
|
-
message: `Found ${filename} but Collie loader not configured`,
|
|
1091
|
-
fix: "Wrap your Next.js config with withCollie() or run collie init --nextjs.",
|
|
1092
|
-
tags: ["nextjs", "config"]
|
|
1093
|
-
};
|
|
1094
|
-
}
|
|
1095
|
-
return {
|
|
1096
|
-
id: "next-config",
|
|
1097
|
-
check: "Next.js config",
|
|
1098
|
-
status: "fail",
|
|
1099
|
-
message: "Next.js config not found",
|
|
1100
|
-
fix: "Create next.config.js and configure withCollie().",
|
|
1101
|
-
tags: ["nextjs", "config"]
|
|
1102
|
-
};
|
|
1103
|
-
}
|
|
1104
1038
|
async function checkTypeDeclarations(context) {
|
|
1105
1039
|
for (const relativePath of DECLARATION_CANDIDATES) {
|
|
1106
|
-
const fullPath =
|
|
1107
|
-
if (
|
|
1040
|
+
const fullPath = import_node_path7.default.join(context.cwd, relativePath);
|
|
1041
|
+
if ((0, import_node_fs2.existsSync)(fullPath)) {
|
|
1108
1042
|
return {
|
|
1109
1043
|
id: "type-declarations",
|
|
1110
1044
|
check: "Type declarations",
|
|
@@ -1124,7 +1058,7 @@ async function checkTypeDeclarations(context) {
|
|
|
1124
1058
|
};
|
|
1125
1059
|
}
|
|
1126
1060
|
async function checkCollieFiles(context) {
|
|
1127
|
-
const files = await
|
|
1061
|
+
const files = await (0, import_fast_glob3.default)("**/*.collie", {
|
|
1128
1062
|
cwd: context.cwd,
|
|
1129
1063
|
ignore: ["node_modules/**", "dist/**", ".next/**"],
|
|
1130
1064
|
absolute: false
|
|
@@ -1152,7 +1086,7 @@ async function testCompilation() {
|
|
|
1152
1086
|
"\n"
|
|
1153
1087
|
);
|
|
1154
1088
|
try {
|
|
1155
|
-
const result = compileToJsx(template, { componentNameHint: "DoctorCheck" });
|
|
1089
|
+
const result = (0, import_compiler6.compileToJsx)(template, { componentNameHint: "DoctorCheck" });
|
|
1156
1090
|
const hasError = result.diagnostics.some((diag) => diag.severity === "error");
|
|
1157
1091
|
if (hasError) {
|
|
1158
1092
|
return {
|
|
@@ -1184,8 +1118,8 @@ async function testCompilation() {
|
|
|
1184
1118
|
}
|
|
1185
1119
|
async function readPackageJson(cwd) {
|
|
1186
1120
|
try {
|
|
1187
|
-
const pkgPath =
|
|
1188
|
-
const raw = await
|
|
1121
|
+
const pkgPath = import_node_path7.default.join(cwd, "package.json");
|
|
1122
|
+
const raw = await import_promises7.default.readFile(pkgPath, "utf8");
|
|
1189
1123
|
return JSON.parse(raw);
|
|
1190
1124
|
} catch {
|
|
1191
1125
|
return null;
|
|
@@ -1231,21 +1165,14 @@ var CLI_DEPENDENCY_SPECS = CLI_PACKAGE_INFO.dependencies;
|
|
|
1231
1165
|
var DEFAULT_DEPENDENCY_RANGE = CLI_PACKAGE_VERSION === "latest" ? "latest" : `^${CLI_PACKAGE_VERSION}`;
|
|
1232
1166
|
var COLLIE_COMPILER_DEPENDENCY = formatCollieDependency("@collie-lang/compiler");
|
|
1233
1167
|
var COLLIE_VITE_DEPENDENCY = formatCollieDependency("@collie-lang/vite");
|
|
1234
|
-
var COLLIE_NEXT_DEPENDENCY = formatCollieDependency("@collie-lang/next");
|
|
1235
|
-
var COLLIE_NEXT_VERSION_RANGE = normalizeDependencyRange(
|
|
1236
|
-
CLI_DEPENDENCY_SPECS["@collie-lang/next"],
|
|
1237
|
-
DEFAULT_DEPENDENCY_RANGE
|
|
1238
|
-
);
|
|
1239
1168
|
var COLLIE_CORE_PACKAGES = ["@collie-lang/compiler", "@collie-lang/config"];
|
|
1240
1169
|
var COLLIE_VITE_PACKAGES = [
|
|
1241
1170
|
...COLLIE_CORE_PACKAGES,
|
|
1242
|
-
"@collie-lang/vite"
|
|
1243
|
-
"@collie-lang/html-runtime"
|
|
1171
|
+
"@collie-lang/vite"
|
|
1244
1172
|
];
|
|
1245
|
-
var COLLIE_NEXT_PACKAGES = [...COLLIE_CORE_PACKAGES, "@collie-lang/next"];
|
|
1246
1173
|
var PROMPT_OPTIONS = {
|
|
1247
1174
|
onCancel: () => {
|
|
1248
|
-
console.log(
|
|
1175
|
+
console.log(import_picocolors7.default.yellow("\nCancelled"));
|
|
1249
1176
|
process.exit(0);
|
|
1250
1177
|
}
|
|
1251
1178
|
};
|
|
@@ -1301,7 +1228,7 @@ async function main() {
|
|
|
1301
1228
|
printCliError(
|
|
1302
1229
|
`Exceeded maximum warnings: ${result.warningCount} warning${result.warningCount === 1 ? "" : "s"} (limit ${maxWarnings})`
|
|
1303
1230
|
);
|
|
1304
|
-
console.error(
|
|
1231
|
+
console.error(import_picocolors7.default.dim("Next: fix warnings or raise --max-warnings."));
|
|
1305
1232
|
process.exitCode = 1;
|
|
1306
1233
|
}
|
|
1307
1234
|
return;
|
|
@@ -1343,7 +1270,7 @@ async function main() {
|
|
|
1343
1270
|
}
|
|
1344
1271
|
const filePath = getFlag(rest, "--file");
|
|
1345
1272
|
const cwdFlag = getFlag(rest, "--cwd");
|
|
1346
|
-
const cwd = cwdFlag ?
|
|
1273
|
+
const cwd = cwdFlag ? import_node_path8.default.resolve(process.cwd(), cwdFlag) : filePath ? import_node_path8.default.dirname(import_node_path8.default.resolve(process.cwd(), filePath)) : process.cwd();
|
|
1347
1274
|
let loadAndNormalizeConfig;
|
|
1348
1275
|
try {
|
|
1349
1276
|
({ loadAndNormalizeConfig } = await import("@collie-lang/config"));
|
|
@@ -1371,7 +1298,7 @@ async function main() {
|
|
|
1371
1298
|
}
|
|
1372
1299
|
const templateListRequested = hasFlag(flagArgs, "--list-templates");
|
|
1373
1300
|
if (templateListRequested) {
|
|
1374
|
-
console.log(
|
|
1301
|
+
console.log(import_picocolors7.default.bold("Available templates:\n"));
|
|
1375
1302
|
console.log(formatTemplateList());
|
|
1376
1303
|
console.log("\nRun collie create <project-name> --template <template> to scaffold with a specific option.\n");
|
|
1377
1304
|
return;
|
|
@@ -1405,7 +1332,7 @@ async function main() {
|
|
|
1405
1332
|
if (removeOriginal && !write) {
|
|
1406
1333
|
throw new Error("--remove-original can only be used with --write.");
|
|
1407
1334
|
}
|
|
1408
|
-
const files = await
|
|
1335
|
+
const files = await (0, import_fast_glob4.default)(patterns, {
|
|
1409
1336
|
absolute: false,
|
|
1410
1337
|
onlyFiles: true,
|
|
1411
1338
|
unique: true
|
|
@@ -1423,10 +1350,10 @@ async function main() {
|
|
|
1423
1350
|
const result = await convertFile(file, options);
|
|
1424
1351
|
if (write) {
|
|
1425
1352
|
const target = result.outputPath ?? file.replace(/\.[tj]sx?$/, ".collie");
|
|
1426
|
-
console.log(
|
|
1353
|
+
console.log(import_picocolors7.default.green(`\u2714 Converted ${file} \u2192 ${target}`));
|
|
1427
1354
|
converted++;
|
|
1428
1355
|
} else {
|
|
1429
|
-
console.log(
|
|
1356
|
+
console.log(import_picocolors7.default.gray(`// Converted from ${file}
|
|
1430
1357
|
`));
|
|
1431
1358
|
process.stdout.write(result.collie);
|
|
1432
1359
|
if (!result.collie.endsWith("\n")) {
|
|
@@ -1435,11 +1362,11 @@ async function main() {
|
|
|
1435
1362
|
console.log("");
|
|
1436
1363
|
}
|
|
1437
1364
|
for (const warning of result.warnings) {
|
|
1438
|
-
console.warn(
|
|
1365
|
+
console.warn(import_picocolors7.default.yellow(`\u26A0 ${file}: ${warning}`));
|
|
1439
1366
|
}
|
|
1440
1367
|
} catch (error) {
|
|
1441
1368
|
const message = error instanceof Error ? error.message : String(error);
|
|
1442
|
-
console.error(
|
|
1369
|
+
console.error(import_picocolors7.default.red(`\u2716 Failed to convert ${file}: ${message}`));
|
|
1443
1370
|
process.exitCode = 1;
|
|
1444
1371
|
failed++;
|
|
1445
1372
|
}
|
|
@@ -1472,7 +1399,7 @@ async function main() {
|
|
|
1472
1399
|
const filtered = filterDiagnostics(results, subsystem);
|
|
1473
1400
|
if (subsystem && filtered.length === 0) {
|
|
1474
1401
|
printCliError(`Unknown subsystem for --check: ${subsystem}`);
|
|
1475
|
-
console.error(
|
|
1402
|
+
console.error(import_picocolors7.default.dim("Next: run collie doctor to list available checks."));
|
|
1476
1403
|
process.exit(1);
|
|
1477
1404
|
}
|
|
1478
1405
|
if (jsonOutput) {
|
|
@@ -1560,7 +1487,7 @@ async function main() {
|
|
|
1560
1487
|
throw new Error(`Unexpected argument(s): ${extraArgs.join(", ")}`);
|
|
1561
1488
|
}
|
|
1562
1489
|
const frameworkValue = getFlag(rest, "--framework");
|
|
1563
|
-
const framework = (frameworkValue === "vite"
|
|
1490
|
+
const framework = (frameworkValue === "vite" ? frameworkValue : void 0) ?? (hasFlag(rest, "--vite") ? "vite" : void 0);
|
|
1564
1491
|
const typescriptFlag = hasFlag(rest, "--typescript");
|
|
1565
1492
|
const javascriptFlag = hasFlag(rest, "--javascript");
|
|
1566
1493
|
if (typescriptFlag && javascriptFlag) {
|
|
@@ -1602,7 +1529,7 @@ async function main() {
|
|
|
1602
1529
|
process.exit(1);
|
|
1603
1530
|
}
|
|
1604
1531
|
function printHelp() {
|
|
1605
|
-
console.log(`${
|
|
1532
|
+
console.log(`${import_picocolors7.default.bold("collie")}
|
|
1606
1533
|
|
|
1607
1534
|
Usage:
|
|
1608
1535
|
collie <command> [options]
|
|
@@ -1701,7 +1628,7 @@ function formatTemplateLocation2(template) {
|
|
|
1701
1628
|
function printTemplateDiagnostics(diagnostics) {
|
|
1702
1629
|
for (const diag of diagnostics) {
|
|
1703
1630
|
const message = formatDiagnosticLine(diag);
|
|
1704
|
-
const writer = diag.severity === "warning" ?
|
|
1631
|
+
const writer = diag.severity === "warning" ? import_picocolors7.default.yellow : import_picocolors7.default.red;
|
|
1705
1632
|
console.log(writer(message));
|
|
1706
1633
|
}
|
|
1707
1634
|
if (diagnostics.length) {
|
|
@@ -1716,18 +1643,18 @@ async function runInit(options = {}) {
|
|
|
1716
1643
|
const framework = options.framework ?? detectedFramework;
|
|
1717
1644
|
const projectType = framework ? mapFrameworkToProjectType(framework) : await promptProjectType();
|
|
1718
1645
|
const existingConfig = findExistingCollieConfig(projectRoot);
|
|
1719
|
-
const targetPath = existingConfig ??
|
|
1720
|
-
const relativeTarget =
|
|
1721
|
-
console.log(
|
|
1722
|
-
console.log(
|
|
1646
|
+
const targetPath = existingConfig ?? import_node_path8.default.join(projectRoot, "collie.config.ts");
|
|
1647
|
+
const relativeTarget = import_node_path8.default.relative(projectRoot, targetPath) || import_node_path8.default.basename(targetPath);
|
|
1648
|
+
console.log(import_picocolors7.default.bold("collie init"));
|
|
1649
|
+
console.log(import_picocolors7.default.dim("This creates a Collie config and applies framework wiring when possible."));
|
|
1723
1650
|
if (framework) {
|
|
1724
|
-
console.log(
|
|
1651
|
+
console.log(import_picocolors7.default.dim(`Detected ${formatFrameworkLabel(framework)} project.`));
|
|
1725
1652
|
} else {
|
|
1726
|
-
console.log(
|
|
1653
|
+
console.log(import_picocolors7.default.dim("No framework detected."));
|
|
1727
1654
|
}
|
|
1728
|
-
console.log(
|
|
1729
|
-
console.log(
|
|
1730
|
-
console.log(
|
|
1655
|
+
console.log(import_picocolors7.default.dim(`CSS strategy: ${formatCssDetection(cssDetection)}.`));
|
|
1656
|
+
console.log(import_picocolors7.default.dim(`Override in ${relativeTarget} via css.strategy and css.diagnostics.unknownClass.`));
|
|
1657
|
+
console.log(import_picocolors7.default.dim(`Project type: ${describeProjectType(projectType)}.`));
|
|
1731
1658
|
console.log("");
|
|
1732
1659
|
const configLabel = framework === "vite" ? "Vite-ready" : "Collie";
|
|
1733
1660
|
const confirmMessage = existingConfig ? `${relativeTarget} already exists. Replace it with a ${configLabel} config?` : `Create ${relativeTarget}?`;
|
|
@@ -1737,12 +1664,12 @@ async function runInit(options = {}) {
|
|
|
1737
1664
|
printSummary("warning", "No changes made", detail, "run collie init when you are ready");
|
|
1738
1665
|
return;
|
|
1739
1666
|
}
|
|
1740
|
-
const contents = buildInitConfig(projectType,
|
|
1741
|
-
await
|
|
1742
|
-
const typeDeclarationsPath =
|
|
1667
|
+
const contents = buildInitConfig(projectType, import_node_path8.default.extname(targetPath).toLowerCase(), cssDetection);
|
|
1668
|
+
await import_promises8.default.writeFile(targetPath, contents, "utf8");
|
|
1669
|
+
const typeDeclarationsPath = import_node_path8.default.join(projectRoot, "src", "collie.d.ts");
|
|
1743
1670
|
let typeDeclarationsStatus = "skipped";
|
|
1744
1671
|
if (projectType !== "html" && shouldWriteTypeDeclarations(projectRoot, options)) {
|
|
1745
|
-
if (
|
|
1672
|
+
if ((0, import_node_fs3.existsSync)(typeDeclarationsPath)) {
|
|
1746
1673
|
typeDeclarationsStatus = "exists";
|
|
1747
1674
|
} else {
|
|
1748
1675
|
await ensureCollieDeclaration(projectRoot);
|
|
@@ -1761,32 +1688,32 @@ async function runInit(options = {}) {
|
|
|
1761
1688
|
}
|
|
1762
1689
|
printSummary("success", "Initialized Collie config", `created ${relativeTarget}`);
|
|
1763
1690
|
if (typeDeclarationsStatus !== "skipped") {
|
|
1764
|
-
const declarationLabel =
|
|
1691
|
+
const declarationLabel = import_node_path8.default.relative(projectRoot, typeDeclarationsPath) || import_node_path8.default.basename(typeDeclarationsPath);
|
|
1765
1692
|
if (typeDeclarationsStatus === "created") {
|
|
1766
|
-
console.log(
|
|
1693
|
+
console.log(import_picocolors7.default.green(`\u2714 Added ${declarationLabel} for .collie typings`));
|
|
1767
1694
|
} else {
|
|
1768
|
-
console.log(
|
|
1695
|
+
console.log(import_picocolors7.default.dim(`- ${declarationLabel} already exists`));
|
|
1769
1696
|
}
|
|
1770
1697
|
} else if (projectType !== "html") {
|
|
1771
1698
|
console.log(
|
|
1772
|
-
|
|
1699
|
+
import_picocolors7.default.dim("Skipping .collie typings (no TypeScript config found). Add src/collie.d.ts if you enable TypeScript.")
|
|
1773
1700
|
);
|
|
1774
1701
|
}
|
|
1775
1702
|
if (framework === "vite") {
|
|
1776
1703
|
if (viteConfigStatus === "patched" && viteConfigPath) {
|
|
1777
|
-
console.log(
|
|
1704
|
+
console.log(import_picocolors7.default.green(`\u2714 Updated ${import_node_path8.default.relative(projectRoot, viteConfigPath) || import_node_path8.default.basename(viteConfigPath)}`));
|
|
1778
1705
|
} else if (viteConfigStatus === "already-configured" && viteConfigPath) {
|
|
1779
1706
|
console.log(
|
|
1780
|
-
|
|
1707
|
+
import_picocolors7.default.dim(`- ${import_node_path8.default.relative(projectRoot, viteConfigPath) || import_node_path8.default.basename(viteConfigPath)} already includes collie()`)
|
|
1781
1708
|
);
|
|
1782
1709
|
} else if (viteConfigStatus === "manual" && viteConfigPath) {
|
|
1783
1710
|
console.log(
|
|
1784
|
-
|
|
1785
|
-
`\u26A0 Could not patch ${
|
|
1711
|
+
import_picocolors7.default.yellow(
|
|
1712
|
+
`\u26A0 Could not patch ${import_node_path8.default.relative(projectRoot, viteConfigPath) || import_node_path8.default.basename(viteConfigPath)}. Add collie() manually to the Vite plugins array.`
|
|
1786
1713
|
)
|
|
1787
1714
|
);
|
|
1788
1715
|
} else if (viteConfigStatus === "not-found") {
|
|
1789
|
-
console.log(
|
|
1716
|
+
console.log(import_picocolors7.default.yellow("\u26A0 Vite config not found. Add the Collie plugin to vite.config.ts manually."));
|
|
1790
1717
|
}
|
|
1791
1718
|
}
|
|
1792
1719
|
if (framework === "vite") {
|
|
@@ -1794,36 +1721,32 @@ async function runInit(options = {}) {
|
|
|
1794
1721
|
printNextSteps(pkgManager, targetPath);
|
|
1795
1722
|
}
|
|
1796
1723
|
if (!framework) {
|
|
1797
|
-
console.log(
|
|
1724
|
+
console.log(import_picocolors7.default.dim(`Tip: update the project type in ${relativeTarget} if needed.`));
|
|
1798
1725
|
}
|
|
1799
1726
|
}
|
|
1800
1727
|
async function readProjectPackage(projectRoot) {
|
|
1801
|
-
const packageJsonPath =
|
|
1802
|
-
if (!
|
|
1728
|
+
const packageJsonPath = import_node_path8.default.join(projectRoot, "package.json");
|
|
1729
|
+
if (!(0, import_node_fs3.existsSync)(packageJsonPath)) {
|
|
1803
1730
|
return null;
|
|
1804
1731
|
}
|
|
1805
|
-
const raw = await
|
|
1732
|
+
const raw = await import_promises8.default.readFile(packageJsonPath, "utf8");
|
|
1806
1733
|
return JSON.parse(raw);
|
|
1807
1734
|
}
|
|
1808
1735
|
function detectFrameworkFromPackage(pkg) {
|
|
1809
|
-
if (hasNextDependency(pkg)) {
|
|
1810
|
-
return "nextjs";
|
|
1811
|
-
}
|
|
1812
1736
|
if (getViteDependencyInfo(pkg)) {
|
|
1813
1737
|
return "vite";
|
|
1814
1738
|
}
|
|
1815
1739
|
return null;
|
|
1816
1740
|
}
|
|
1817
1741
|
function mapFrameworkToProjectType(framework) {
|
|
1818
|
-
return
|
|
1742
|
+
return "react-vite";
|
|
1819
1743
|
}
|
|
1820
1744
|
function formatFrameworkLabel(framework) {
|
|
1821
|
-
return
|
|
1745
|
+
return "Vite";
|
|
1822
1746
|
}
|
|
1823
1747
|
function describeProjectType(projectType) {
|
|
1824
1748
|
const labels = {
|
|
1825
1749
|
"react-vite": "React (Vite)",
|
|
1826
|
-
"react-next": "React (Next.js)",
|
|
1827
1750
|
"react-generic": "React (generic)",
|
|
1828
1751
|
html: "HTML (no framework)"
|
|
1829
1752
|
};
|
|
@@ -1836,14 +1759,14 @@ function shouldWriteTypeDeclarations(projectRoot, options) {
|
|
|
1836
1759
|
if (options.typescript === true) {
|
|
1837
1760
|
return true;
|
|
1838
1761
|
}
|
|
1839
|
-
return
|
|
1762
|
+
return (0, import_node_fs3.existsSync)(import_node_path8.default.join(projectRoot, "tsconfig.json"));
|
|
1840
1763
|
}
|
|
1841
1764
|
async function detectCssStrategy(projectRoot, packageJson) {
|
|
1842
1765
|
const reasons = [];
|
|
1843
1766
|
try {
|
|
1844
1767
|
let tailwindDetected = false;
|
|
1845
1768
|
for (const filename of TAILWIND_CONFIG_FILES) {
|
|
1846
|
-
if (
|
|
1769
|
+
if ((0, import_node_fs3.existsSync)(import_node_path8.default.join(projectRoot, filename))) {
|
|
1847
1770
|
reasons.push(`${filename} found`);
|
|
1848
1771
|
tailwindDetected = true;
|
|
1849
1772
|
}
|
|
@@ -1891,11 +1814,11 @@ function hasTailwindDependency(pkg) {
|
|
|
1891
1814
|
}
|
|
1892
1815
|
async function scanPostcssForTailwind(projectRoot) {
|
|
1893
1816
|
for (const filename of POSTCSS_CONFIG_FILES) {
|
|
1894
|
-
const fullPath =
|
|
1895
|
-
if (!
|
|
1817
|
+
const fullPath = import_node_path8.default.join(projectRoot, filename);
|
|
1818
|
+
if (!(0, import_node_fs3.existsSync)(fullPath)) {
|
|
1896
1819
|
continue;
|
|
1897
1820
|
}
|
|
1898
|
-
const contents = await
|
|
1821
|
+
const contents = await import_promises8.default.readFile(fullPath, "utf8");
|
|
1899
1822
|
if (contents.includes("tailwindcss")) {
|
|
1900
1823
|
return filename;
|
|
1901
1824
|
}
|
|
@@ -1903,10 +1826,10 @@ async function scanPostcssForTailwind(projectRoot) {
|
|
|
1903
1826
|
return null;
|
|
1904
1827
|
}
|
|
1905
1828
|
async function scanTopLevelCssForTailwind(projectRoot) {
|
|
1906
|
-
const files = await
|
|
1829
|
+
const files = await (0, import_fast_glob4.default)("*.css", { cwd: projectRoot, onlyFiles: true });
|
|
1907
1830
|
for (const filename of files) {
|
|
1908
|
-
const fullPath =
|
|
1909
|
-
const contents = await
|
|
1831
|
+
const fullPath = import_node_path8.default.join(projectRoot, filename);
|
|
1832
|
+
const contents = await import_promises8.default.readFile(fullPath, "utf8");
|
|
1910
1833
|
if (/\@tailwind\s+(base|components|utilities)\b/.test(contents)) {
|
|
1911
1834
|
return filename;
|
|
1912
1835
|
}
|
|
@@ -1948,15 +1871,15 @@ function buildInitConfig(projectType, ext, cssDetection) {
|
|
|
1948
1871
|
}
|
|
1949
1872
|
function findExistingCollieConfig(root) {
|
|
1950
1873
|
for (const filename of COLLIE_CONFIG_FILES) {
|
|
1951
|
-
const candidate =
|
|
1952
|
-
if (
|
|
1874
|
+
const candidate = import_node_path8.default.join(root, filename);
|
|
1875
|
+
if ((0, import_node_fs3.existsSync)(candidate)) {
|
|
1953
1876
|
return candidate;
|
|
1954
1877
|
}
|
|
1955
1878
|
}
|
|
1956
1879
|
return null;
|
|
1957
1880
|
}
|
|
1958
1881
|
async function promptForConfirmation(message, initial) {
|
|
1959
|
-
const response = await
|
|
1882
|
+
const response = await (0, import_prompts2.default)(
|
|
1960
1883
|
{
|
|
1961
1884
|
type: "confirm",
|
|
1962
1885
|
name: "confirmed",
|
|
@@ -1968,14 +1891,13 @@ async function promptForConfirmation(message, initial) {
|
|
|
1968
1891
|
return Boolean(response.confirmed);
|
|
1969
1892
|
}
|
|
1970
1893
|
async function promptProjectType() {
|
|
1971
|
-
const response = await
|
|
1894
|
+
const response = await (0, import_prompts2.default)(
|
|
1972
1895
|
{
|
|
1973
1896
|
type: "select",
|
|
1974
1897
|
name: "projectType",
|
|
1975
1898
|
message: "What type of project should this config describe?",
|
|
1976
1899
|
choices: [
|
|
1977
1900
|
{ title: "React (Vite)", value: "react-vite" },
|
|
1978
|
-
{ title: "React (Next.js)", value: "react-next" },
|
|
1979
1901
|
{ title: "React (generic)", value: "react-generic" },
|
|
1980
1902
|
{ title: "HTML (no framework)", value: "html" }
|
|
1981
1903
|
],
|
|
@@ -1992,7 +1914,7 @@ async function runPreflight(command, options = {}) {
|
|
|
1992
1914
|
preflightCompleted = true;
|
|
1993
1915
|
const projectRoot = findProjectRoot(process.cwd());
|
|
1994
1916
|
if (!projectRoot) {
|
|
1995
|
-
console.log(
|
|
1917
|
+
console.log(import_picocolors7.default.dim("Skipping dependency preflight (no package.json found)."));
|
|
1996
1918
|
return true;
|
|
1997
1919
|
}
|
|
1998
1920
|
let packageJson = null;
|
|
@@ -2000,11 +1922,11 @@ async function runPreflight(command, options = {}) {
|
|
|
2000
1922
|
packageJson = await readProjectPackage(projectRoot);
|
|
2001
1923
|
} catch (error) {
|
|
2002
1924
|
const message = error instanceof Error ? error.message : String(error);
|
|
2003
|
-
console.log(
|
|
1925
|
+
console.log(import_picocolors7.default.yellow(`Skipping dependency preflight: failed to read package.json (${message}).`));
|
|
2004
1926
|
return true;
|
|
2005
1927
|
}
|
|
2006
1928
|
if (!packageJson) {
|
|
2007
|
-
console.log(
|
|
1929
|
+
console.log(import_picocolors7.default.dim("Skipping dependency preflight (package.json not found)."));
|
|
2008
1930
|
return true;
|
|
2009
1931
|
}
|
|
2010
1932
|
const detectedFramework = detectFrameworkFromPackage(packageJson);
|
|
@@ -2021,25 +1943,25 @@ async function runPreflight(command, options = {}) {
|
|
|
2021
1943
|
const prompt = `Missing required Collie packages: ${missing.join(", ")}. Install now?`;
|
|
2022
1944
|
const shouldInstall = await promptForConfirmation(prompt, true);
|
|
2023
1945
|
if (!shouldInstall) {
|
|
2024
|
-
console.log(
|
|
1946
|
+
console.log(import_picocolors7.default.yellow("Skipped installing Collie dependencies."));
|
|
2025
1947
|
console.log(
|
|
2026
|
-
|
|
1948
|
+
import_picocolors7.default.dim(`Next: ${formatInstallCommand(packageManager, missing)} && collie ${command}`)
|
|
2027
1949
|
);
|
|
2028
1950
|
return false;
|
|
2029
1951
|
}
|
|
2030
1952
|
const specs = missing.map((dep) => resolveDependencySpec(dep));
|
|
2031
|
-
console.log(
|
|
1953
|
+
console.log(import_picocolors7.default.cyan(`Installing ${missing.length} Collie package${missing.length === 1 ? "" : "s"}...`));
|
|
2032
1954
|
await installDevDependencies(packageManager, projectRoot, specs);
|
|
2033
|
-
console.log(
|
|
1955
|
+
console.log(import_picocolors7.default.green(`\u2714 Installed ${missing.length} Collie package${missing.length === 1 ? "" : "s"}.`));
|
|
2034
1956
|
return true;
|
|
2035
1957
|
}
|
|
2036
1958
|
function findProjectRoot(startDir) {
|
|
2037
1959
|
let current = startDir;
|
|
2038
1960
|
while (true) {
|
|
2039
|
-
if (
|
|
1961
|
+
if ((0, import_node_fs3.existsSync)(import_node_path8.default.join(current, "package.json"))) {
|
|
2040
1962
|
return current;
|
|
2041
1963
|
}
|
|
2042
|
-
const parent =
|
|
1964
|
+
const parent = import_node_path8.default.dirname(current);
|
|
2043
1965
|
if (parent === current) {
|
|
2044
1966
|
return null;
|
|
2045
1967
|
}
|
|
@@ -2050,9 +1972,6 @@ function getRequiredPackages(command, framework) {
|
|
|
2050
1972
|
if (command === "check") {
|
|
2051
1973
|
return ["@collie-lang/compiler"];
|
|
2052
1974
|
}
|
|
2053
|
-
if (framework === "nextjs") {
|
|
2054
|
-
return [...COLLIE_NEXT_PACKAGES];
|
|
2055
|
-
}
|
|
2056
1975
|
if (framework === "vite") {
|
|
2057
1976
|
return [...COLLIE_VITE_PACKAGES];
|
|
2058
1977
|
}
|
|
@@ -2068,8 +1987,8 @@ function isDependencySatisfied(projectRoot, packageJson, dependency) {
|
|
|
2068
1987
|
if (listed) {
|
|
2069
1988
|
return true;
|
|
2070
1989
|
}
|
|
2071
|
-
const modulePath =
|
|
2072
|
-
return
|
|
1990
|
+
const modulePath = import_node_path8.default.join(projectRoot, "node_modules", ...dependency.split("/"));
|
|
1991
|
+
return (0, import_node_fs3.existsSync)(modulePath);
|
|
2073
1992
|
}
|
|
2074
1993
|
function resolveDependencySpec(packageName) {
|
|
2075
1994
|
const range = normalizeDependencyRange(CLI_DEPENDENCY_SPECS[packageName], "latest");
|
|
@@ -2086,8 +2005,8 @@ function formatInstallCommand(packageManager, dependencies) {
|
|
|
2086
2005
|
return `npm install -D ${specs.join(" ")}`;
|
|
2087
2006
|
}
|
|
2088
2007
|
function detectPackageManager2(root) {
|
|
2089
|
-
if (
|
|
2090
|
-
if (
|
|
2008
|
+
if ((0, import_node_fs3.existsSync)(import_node_path8.default.join(root, "pnpm-lock.yaml"))) return "pnpm";
|
|
2009
|
+
if ((0, import_node_fs3.existsSync)(import_node_path8.default.join(root, "yarn.lock"))) return "yarn";
|
|
2091
2010
|
return "npm";
|
|
2092
2011
|
}
|
|
2093
2012
|
async function installDevDependencies(packageManager, cwd, deps) {
|
|
@@ -2099,7 +2018,7 @@ async function installDevDependencies(packageManager, cwd, deps) {
|
|
|
2099
2018
|
await runCommand2(packageManager, argsByManager[packageManager], cwd);
|
|
2100
2019
|
}
|
|
2101
2020
|
async function patchViteConfig(configPath) {
|
|
2102
|
-
const original = await
|
|
2021
|
+
const original = await import_promises8.default.readFile(configPath, "utf8");
|
|
2103
2022
|
const hasImport = original.includes("@collie-lang/vite");
|
|
2104
2023
|
const hasPlugin = /\bcollie\s*\(/.test(original);
|
|
2105
2024
|
if (hasImport && hasPlugin) {
|
|
@@ -2110,37 +2029,37 @@ async function patchViteConfig(configPath) {
|
|
|
2110
2029
|
if (!result.changed) {
|
|
2111
2030
|
return "already-configured";
|
|
2112
2031
|
}
|
|
2113
|
-
await
|
|
2032
|
+
await import_promises8.default.writeFile(configPath, result.code, "utf8");
|
|
2114
2033
|
return "patched";
|
|
2115
2034
|
} catch (error) {
|
|
2116
2035
|
return "manual";
|
|
2117
2036
|
}
|
|
2118
2037
|
}
|
|
2119
2038
|
function transformViteConfig(source) {
|
|
2120
|
-
const sourceFile =
|
|
2039
|
+
const sourceFile = import_typescript.default.createSourceFile(
|
|
2121
2040
|
"vite.config.ts",
|
|
2122
2041
|
source,
|
|
2123
|
-
|
|
2042
|
+
import_typescript.default.ScriptTarget.Latest,
|
|
2124
2043
|
true,
|
|
2125
|
-
|
|
2044
|
+
import_typescript.default.ScriptKind.TS
|
|
2126
2045
|
);
|
|
2127
2046
|
let needsImport = !source.includes("@collie-lang/vite");
|
|
2128
2047
|
let needsPlugin = !/\bcollie\s*\(/.test(source);
|
|
2129
2048
|
let changed = false;
|
|
2130
|
-
const printer =
|
|
2049
|
+
const printer = import_typescript.default.createPrinter({ newLine: import_typescript.default.NewLineKind.LineFeed });
|
|
2131
2050
|
const transformer = (context) => {
|
|
2132
2051
|
return (rootNode) => {
|
|
2133
2052
|
function visit(node) {
|
|
2134
|
-
if (needsImport &&
|
|
2053
|
+
if (needsImport && import_typescript.default.isImportDeclaration(node)) {
|
|
2135
2054
|
return node;
|
|
2136
2055
|
}
|
|
2137
|
-
if (
|
|
2056
|
+
if (import_typescript.default.isCallExpression(node) && import_typescript.default.isIdentifier(node.expression) && node.expression.text === "defineConfig" && node.arguments.length > 0) {
|
|
2138
2057
|
const configArg = node.arguments[0];
|
|
2139
|
-
if (
|
|
2058
|
+
if (import_typescript.default.isObjectLiteralExpression(configArg)) {
|
|
2140
2059
|
const updatedConfig = updateConfigObject(configArg);
|
|
2141
2060
|
if (updatedConfig !== configArg) {
|
|
2142
2061
|
changed = true;
|
|
2143
|
-
return
|
|
2062
|
+
return import_typescript.default.factory.updateCallExpression(
|
|
2144
2063
|
node,
|
|
2145
2064
|
node.expression,
|
|
2146
2065
|
node.typeArguments,
|
|
@@ -2149,42 +2068,42 @@ function transformViteConfig(source) {
|
|
|
2149
2068
|
}
|
|
2150
2069
|
}
|
|
2151
2070
|
}
|
|
2152
|
-
return
|
|
2071
|
+
return import_typescript.default.visitEachChild(node, visit, context);
|
|
2153
2072
|
}
|
|
2154
2073
|
function updateConfigObject(configObj) {
|
|
2155
2074
|
let pluginsProperty;
|
|
2156
2075
|
const otherProperties = [];
|
|
2157
2076
|
for (const prop of configObj.properties) {
|
|
2158
|
-
if (
|
|
2077
|
+
if (import_typescript.default.isPropertyAssignment(prop) && import_typescript.default.isIdentifier(prop.name) && prop.name.text === "plugins") {
|
|
2159
2078
|
pluginsProperty = prop;
|
|
2160
2079
|
} else {
|
|
2161
2080
|
otherProperties.push(prop);
|
|
2162
2081
|
}
|
|
2163
2082
|
}
|
|
2164
2083
|
let updatedPluginsArray;
|
|
2165
|
-
if (pluginsProperty &&
|
|
2084
|
+
if (pluginsProperty && import_typescript.default.isArrayLiteralExpression(pluginsProperty.initializer)) {
|
|
2166
2085
|
updatedPluginsArray = ensurePluginOrdering(pluginsProperty.initializer);
|
|
2167
2086
|
if (updatedPluginsArray === pluginsProperty.initializer) {
|
|
2168
2087
|
return configObj;
|
|
2169
2088
|
}
|
|
2170
2089
|
} else if (needsPlugin) {
|
|
2171
|
-
updatedPluginsArray =
|
|
2090
|
+
updatedPluginsArray = import_typescript.default.factory.createArrayLiteralExpression(
|
|
2172
2091
|
[createCollieCall()],
|
|
2173
2092
|
false
|
|
2174
2093
|
);
|
|
2175
2094
|
} else {
|
|
2176
2095
|
return configObj;
|
|
2177
2096
|
}
|
|
2178
|
-
const updatedPluginsProperty =
|
|
2097
|
+
const updatedPluginsProperty = import_typescript.default.factory.createPropertyAssignment(
|
|
2179
2098
|
"plugins",
|
|
2180
2099
|
updatedPluginsArray
|
|
2181
2100
|
);
|
|
2182
2101
|
if (pluginsProperty) {
|
|
2183
2102
|
const allProperties = [...otherProperties, updatedPluginsProperty];
|
|
2184
|
-
return
|
|
2103
|
+
return import_typescript.default.factory.updateObjectLiteralExpression(configObj, allProperties);
|
|
2185
2104
|
} else {
|
|
2186
2105
|
const allProperties = [...otherProperties, updatedPluginsProperty];
|
|
2187
|
-
return
|
|
2106
|
+
return import_typescript.default.factory.updateObjectLiteralExpression(configObj, allProperties);
|
|
2188
2107
|
}
|
|
2189
2108
|
}
|
|
2190
2109
|
function ensurePluginOrdering(array) {
|
|
@@ -2194,7 +2113,7 @@ function transformViteConfig(source) {
|
|
|
2194
2113
|
let reactIndex = -1;
|
|
2195
2114
|
let collieIndex = -1;
|
|
2196
2115
|
elements.forEach((elem, idx) => {
|
|
2197
|
-
if (
|
|
2116
|
+
if (import_typescript.default.isCallExpression(elem) && import_typescript.default.isIdentifier(elem.expression)) {
|
|
2198
2117
|
if (elem.expression.text === "react") {
|
|
2199
2118
|
hasReact = true;
|
|
2200
2119
|
reactIndex = idx;
|
|
@@ -2212,37 +2131,37 @@ function transformViteConfig(source) {
|
|
|
2212
2131
|
const colliePlugin = newElements[collieIndex];
|
|
2213
2132
|
newElements[collieIndex] = reactPlugin;
|
|
2214
2133
|
newElements[reactIndex] = colliePlugin;
|
|
2215
|
-
return
|
|
2134
|
+
return import_typescript.default.factory.createArrayLiteralExpression(newElements, isMultiLine);
|
|
2216
2135
|
}
|
|
2217
2136
|
return array;
|
|
2218
2137
|
}
|
|
2219
2138
|
if (!hasCollie && needsPlugin) {
|
|
2220
2139
|
const newElements = [...elements, createCollieCall()];
|
|
2221
|
-
return
|
|
2140
|
+
return import_typescript.default.factory.createArrayLiteralExpression(newElements, isMultiLine);
|
|
2222
2141
|
}
|
|
2223
2142
|
return array;
|
|
2224
2143
|
}
|
|
2225
2144
|
function createCollieCall() {
|
|
2226
|
-
return
|
|
2227
|
-
|
|
2145
|
+
return import_typescript.default.factory.createCallExpression(
|
|
2146
|
+
import_typescript.default.factory.createIdentifier("collie"),
|
|
2228
2147
|
void 0,
|
|
2229
2148
|
[]
|
|
2230
2149
|
);
|
|
2231
2150
|
}
|
|
2232
|
-
const visited =
|
|
2151
|
+
const visited = import_typescript.default.visitNode(rootNode, visit);
|
|
2233
2152
|
if (needsImport && changed) {
|
|
2234
|
-
const collieImport =
|
|
2153
|
+
const collieImport = import_typescript.default.factory.createImportDeclaration(
|
|
2235
2154
|
void 0,
|
|
2236
|
-
|
|
2155
|
+
import_typescript.default.factory.createImportClause(
|
|
2237
2156
|
false,
|
|
2238
|
-
|
|
2157
|
+
import_typescript.default.factory.createIdentifier("collie"),
|
|
2239
2158
|
void 0
|
|
2240
2159
|
),
|
|
2241
|
-
|
|
2160
|
+
import_typescript.default.factory.createStringLiteral("@collie-lang/vite", true)
|
|
2242
2161
|
);
|
|
2243
2162
|
let lastImportIndex = -1;
|
|
2244
2163
|
for (let i = 0; i < visited.statements.length; i++) {
|
|
2245
|
-
if (
|
|
2164
|
+
if (import_typescript.default.isImportDeclaration(visited.statements[i])) {
|
|
2246
2165
|
lastImportIndex = i;
|
|
2247
2166
|
}
|
|
2248
2167
|
}
|
|
@@ -2252,12 +2171,12 @@ function transformViteConfig(source) {
|
|
|
2252
2171
|
} else {
|
|
2253
2172
|
statements.unshift(collieImport);
|
|
2254
2173
|
}
|
|
2255
|
-
return
|
|
2174
|
+
return import_typescript.default.factory.updateSourceFile(visited, statements);
|
|
2256
2175
|
}
|
|
2257
2176
|
return visited;
|
|
2258
2177
|
};
|
|
2259
2178
|
};
|
|
2260
|
-
const result =
|
|
2179
|
+
const result = import_typescript.default.transform(sourceFile, [transformer]);
|
|
2261
2180
|
const transformedSourceFile = result.transformed[0];
|
|
2262
2181
|
result.dispose();
|
|
2263
2182
|
if (!changed) {
|
|
@@ -2267,9 +2186,9 @@ function transformViteConfig(source) {
|
|
|
2267
2186
|
return { code: output, changed: true };
|
|
2268
2187
|
}
|
|
2269
2188
|
async function ensureCollieDeclaration(root) {
|
|
2270
|
-
const target =
|
|
2271
|
-
if (
|
|
2272
|
-
await
|
|
2189
|
+
const target = import_node_path8.default.join(root, "src", "collie.d.ts");
|
|
2190
|
+
if ((0, import_node_fs3.existsSync)(target)) return;
|
|
2191
|
+
await import_promises8.default.mkdir(import_node_path8.default.dirname(target), { recursive: true });
|
|
2273
2192
|
const declaration = `// Allows importing Collie templates as React components.
|
|
2274
2193
|
// Customize this typing if your templates expose specific props.
|
|
2275
2194
|
declare module "*.collie" {
|
|
@@ -2278,12 +2197,12 @@ declare module "*.collie" {
|
|
|
2278
2197
|
export default component;
|
|
2279
2198
|
}
|
|
2280
2199
|
`;
|
|
2281
|
-
await
|
|
2200
|
+
await import_promises8.default.writeFile(target, declaration, "utf8");
|
|
2282
2201
|
}
|
|
2283
2202
|
function findViteConfigFile(root) {
|
|
2284
2203
|
for (const file of VITE_CONFIG_FILES2) {
|
|
2285
|
-
const candidate =
|
|
2286
|
-
if (
|
|
2204
|
+
const candidate = import_node_path8.default.join(root, file);
|
|
2205
|
+
if ((0, import_node_fs3.existsSync)(candidate)) {
|
|
2287
2206
|
return candidate;
|
|
2288
2207
|
}
|
|
2289
2208
|
}
|
|
@@ -2291,9 +2210,8 @@ function findViteConfigFile(root) {
|
|
|
2291
2210
|
}
|
|
2292
2211
|
function readCliPackageInfo() {
|
|
2293
2212
|
try {
|
|
2294
|
-
const
|
|
2295
|
-
const
|
|
2296
|
-
const raw = readFileSync(pkgPath, "utf8");
|
|
2213
|
+
const pkgPath = import_node_path8.default.resolve(__dirname, "..", "package.json");
|
|
2214
|
+
const raw = (0, import_node_fs3.readFileSync)(pkgPath, "utf8");
|
|
2297
2215
|
const pkg = JSON.parse(raw);
|
|
2298
2216
|
const version = typeof pkg.version === "string" ? pkg.version : "latest";
|
|
2299
2217
|
const dependencies = pkg && typeof pkg === "object" && pkg.dependencies && typeof pkg.dependencies === "object" ? pkg.dependencies : {};
|
|
@@ -2325,10 +2243,10 @@ function getViteDependencyInfo(pkg) {
|
|
|
2325
2243
|
function printNextSteps(pkgManager, configPath) {
|
|
2326
2244
|
const devCommand = formatDevCommand(pkgManager);
|
|
2327
2245
|
console.log("");
|
|
2328
|
-
console.log(
|
|
2246
|
+
console.log(import_picocolors7.default.green("Next steps:"));
|
|
2329
2247
|
console.log(` - Create a Collie template under src (e.g. src/Hello.collie).`);
|
|
2330
2248
|
console.log(` - Import it in your React app and run ${devCommand} to start Vite.`);
|
|
2331
|
-
console.log(` - Need to adjust plugins later? Edit ${
|
|
2249
|
+
console.log(` - Need to adjust plugins later? Edit ${import_node_path8.default.basename(configPath)}.`);
|
|
2332
2250
|
}
|
|
2333
2251
|
function formatDevCommand(pkgManager) {
|
|
2334
2252
|
if (pkgManager === "pnpm") return "pnpm dev";
|
|
@@ -2337,7 +2255,7 @@ function formatDevCommand(pkgManager) {
|
|
|
2337
2255
|
}
|
|
2338
2256
|
function runCommand2(command, args, cwd) {
|
|
2339
2257
|
return new Promise((resolve, reject) => {
|
|
2340
|
-
const child =
|
|
2258
|
+
const child = (0, import_node_child_process2.spawn)(command, args, { cwd, stdio: "inherit" });
|
|
2341
2259
|
child.on("error", reject);
|
|
2342
2260
|
child.on("close", (code) => {
|
|
2343
2261
|
if (code === 0) resolve();
|
|
@@ -2352,7 +2270,7 @@ async function runFormat(args) {
|
|
|
2352
2270
|
}
|
|
2353
2271
|
const indent = flags.indent ?? 2;
|
|
2354
2272
|
const cwd = process.cwd();
|
|
2355
|
-
const files = await
|
|
2273
|
+
const files = await (0, import_fast_glob4.default)(patterns, { cwd, onlyFiles: true, unique: true });
|
|
2356
2274
|
if (!files.length) {
|
|
2357
2275
|
printSummary("warning", "No files matched the provided patterns", void 0, "check the glob and try again");
|
|
2358
2276
|
return;
|
|
@@ -2364,10 +2282,10 @@ async function runFormat(args) {
|
|
|
2364
2282
|
for (const file of files) {
|
|
2365
2283
|
let contents;
|
|
2366
2284
|
try {
|
|
2367
|
-
contents = await
|
|
2285
|
+
contents = await import_promises8.default.readFile(file, "utf8");
|
|
2368
2286
|
} catch (error) {
|
|
2369
2287
|
const message = error instanceof Error ? error.message : String(error);
|
|
2370
|
-
console.error(
|
|
2288
|
+
console.error(import_picocolors7.default.red(`\u2716 Failed to read ${file}: ${message}`));
|
|
2371
2289
|
failures++;
|
|
2372
2290
|
continue;
|
|
2373
2291
|
}
|
|
@@ -2376,7 +2294,7 @@ async function runFormat(args) {
|
|
|
2376
2294
|
result = formatSource(contents, { indent });
|
|
2377
2295
|
} catch (error) {
|
|
2378
2296
|
const message = error instanceof Error ? error.message : String(error);
|
|
2379
|
-
console.error(
|
|
2297
|
+
console.error(import_picocolors7.default.red(`\u2716 Failed to format ${file}: ${message}`));
|
|
2380
2298
|
failures++;
|
|
2381
2299
|
continue;
|
|
2382
2300
|
}
|
|
@@ -2391,20 +2309,20 @@ async function runFormat(args) {
|
|
|
2391
2309
|
}
|
|
2392
2310
|
if (flags.check) {
|
|
2393
2311
|
if (changed) {
|
|
2394
|
-
console.log(
|
|
2312
|
+
console.log(import_picocolors7.default.red(`\u2716 ${file} needs formatting`));
|
|
2395
2313
|
needsFormatting++;
|
|
2396
2314
|
} else {
|
|
2397
|
-
console.log(
|
|
2315
|
+
console.log(import_picocolors7.default.green(`\u2714 ${file} is formatted`));
|
|
2398
2316
|
}
|
|
2399
2317
|
continue;
|
|
2400
2318
|
}
|
|
2401
2319
|
if (flags.write) {
|
|
2402
2320
|
if (changed) {
|
|
2403
|
-
await
|
|
2321
|
+
await import_promises8.default.writeFile(file, result.formatted, "utf8");
|
|
2404
2322
|
written++;
|
|
2405
|
-
console.log(
|
|
2323
|
+
console.log(import_picocolors7.default.green(`\u2714 Formatted ${file}`));
|
|
2406
2324
|
} else {
|
|
2407
|
-
console.log(
|
|
2325
|
+
console.log(import_picocolors7.default.dim(`- ${file} already formatted`));
|
|
2408
2326
|
}
|
|
2409
2327
|
continue;
|
|
2410
2328
|
}
|
|
@@ -2420,7 +2338,7 @@ async function runFormat(args) {
|
|
|
2420
2338
|
`${needsFormatting} file${needsFormatting === 1 ? "" : "s"} need formatting`,
|
|
2421
2339
|
"no files changed"
|
|
2422
2340
|
);
|
|
2423
|
-
console.log(
|
|
2341
|
+
console.log(import_picocolors7.default.dim("Run: collie format --write to fix"));
|
|
2424
2342
|
process.exitCode = 1;
|
|
2425
2343
|
} else if (failures > 0) {
|
|
2426
2344
|
printSummary(
|
|
@@ -2502,18 +2420,18 @@ function printDiagnostics(file, diagnostics) {
|
|
|
2502
2420
|
for (const diag of diagnostics) {
|
|
2503
2421
|
const message = formatDiagnosticLine({ ...diag, file }, file);
|
|
2504
2422
|
if (diag.severity === "warning") {
|
|
2505
|
-
console.warn(
|
|
2423
|
+
console.warn(import_picocolors7.default.yellow(message));
|
|
2506
2424
|
} else {
|
|
2507
|
-
console.error(
|
|
2425
|
+
console.error(import_picocolors7.default.red(message));
|
|
2508
2426
|
}
|
|
2509
2427
|
}
|
|
2510
2428
|
}
|
|
2511
2429
|
function printDiff(file, before, after) {
|
|
2512
|
-
console.log(
|
|
2513
|
-
const diff = diffLines(before, after);
|
|
2430
|
+
console.log(import_picocolors7.default.cyan(`diff -- ${file}`));
|
|
2431
|
+
const diff = (0, import_diff.diffLines)(before, after);
|
|
2514
2432
|
for (const part of diff) {
|
|
2515
2433
|
const prefix = part.added ? "+" : part.removed ? "-" : " ";
|
|
2516
|
-
const color = part.added ?
|
|
2434
|
+
const color = part.added ? import_picocolors7.default.green : part.removed ? import_picocolors7.default.red : import_picocolors7.default.dim;
|
|
2517
2435
|
const lines = part.value.split("\n");
|
|
2518
2436
|
for (let i = 0; i < lines.length; i++) {
|
|
2519
2437
|
const line = lines[i];
|
|
@@ -2554,7 +2472,7 @@ function validateFormatFlag(value) {
|
|
|
2554
2472
|
throw new Error('Invalid --format flag. Use "text" or "json".');
|
|
2555
2473
|
}
|
|
2556
2474
|
function printCliError(message) {
|
|
2557
|
-
console.error(
|
|
2475
|
+
console.error(import_picocolors7.default.red(`\u2716 ${message}`));
|
|
2558
2476
|
}
|
|
2559
2477
|
main().catch((error) => {
|
|
2560
2478
|
printCliError(error instanceof Error ? error.message : String(error));
|