@collie-lang/cli 1.1.1 → 1.3.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 +391 -387
- 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;
|
|
@@ -1205,7 +1139,7 @@ function formatDependencyVersion(spec) {
|
|
|
1205
1139
|
}
|
|
1206
1140
|
|
|
1207
1141
|
// src/index.ts
|
|
1208
|
-
var
|
|
1142
|
+
var VITE_CONFIG_PATTERNS = ["vite.config.ts", "vite.config.js", "vite.config.mjs", "vite.config.cjs"];
|
|
1209
1143
|
var TAILWIND_CONFIG_FILES = [
|
|
1210
1144
|
"tailwind.config.js",
|
|
1211
1145
|
"tailwind.config.cjs",
|
|
@@ -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) {
|
|
@@ -1711,23 +1638,65 @@ function printTemplateDiagnostics(diagnostics) {
|
|
|
1711
1638
|
async function runInit(options = {}) {
|
|
1712
1639
|
const projectRoot = process.cwd();
|
|
1713
1640
|
const packageJson = await readProjectPackage(projectRoot);
|
|
1641
|
+
const viteConfigPath = findViteConfigPath(projectRoot);
|
|
1642
|
+
if (!viteConfigPath) {
|
|
1643
|
+
printCliError("No Vite config found. collie init currently requires a Vite project.");
|
|
1644
|
+
console.error(import_picocolors7.default.dim("Expected one of: vite.config.ts, vite.config.js, vite.config.mjs, vite.config.cjs"));
|
|
1645
|
+
process.exit(1);
|
|
1646
|
+
}
|
|
1647
|
+
if (!packageJson) {
|
|
1648
|
+
printCliError("No package.json found. collie init requires a Node.js project.");
|
|
1649
|
+
process.exit(1);
|
|
1650
|
+
}
|
|
1651
|
+
const missing = computeMissingCollieDeps(packageJson);
|
|
1652
|
+
const hasAnyMissing = missing.missingRuntime.length > 0 || missing.missingDev.length > 0;
|
|
1653
|
+
if (hasAnyMissing) {
|
|
1654
|
+
const packageManager = options.packageManager ?? detectPackageManager2(projectRoot);
|
|
1655
|
+
const versionSpec = getCollieVersionSpec(packageJson);
|
|
1656
|
+
const runtimeSpecs = missing.missingRuntime.map((pkg) => {
|
|
1657
|
+
return versionSpec ? `${pkg}@${versionSpec}` : pkg;
|
|
1658
|
+
});
|
|
1659
|
+
const devSpecs = missing.missingDev.map((pkg) => {
|
|
1660
|
+
return versionSpec ? `${pkg}@${versionSpec}` : pkg;
|
|
1661
|
+
});
|
|
1662
|
+
if (options.noInstall) {
|
|
1663
|
+
const allMissing = [...missing.missingRuntime, ...missing.missingDev];
|
|
1664
|
+
console.log(import_picocolors7.default.yellow(`\u26A0 Missing required Collie packages: ${allMissing.join(", ")}`));
|
|
1665
|
+
console.log(import_picocolors7.default.dim("\nTo install, run:"));
|
|
1666
|
+
if (runtimeSpecs.length > 0) {
|
|
1667
|
+
const cmd = packageManager === "npm" ? `npm i ${runtimeSpecs.join(" ")}` : packageManager === "pnpm" ? `pnpm add ${runtimeSpecs.join(" ")}` : `yarn add ${runtimeSpecs.join(" ")}`;
|
|
1668
|
+
console.log(import_picocolors7.default.dim(` ${cmd}`));
|
|
1669
|
+
}
|
|
1670
|
+
if (devSpecs.length > 0) {
|
|
1671
|
+
const cmd = packageManager === "npm" ? `npm i -D ${devSpecs.join(" ")}` : packageManager === "pnpm" ? `pnpm add -D ${devSpecs.join(" ")}` : `yarn add -D ${devSpecs.join(" ")}`;
|
|
1672
|
+
console.log(import_picocolors7.default.dim(` ${cmd}`));
|
|
1673
|
+
}
|
|
1674
|
+
console.log("");
|
|
1675
|
+
} else {
|
|
1676
|
+
const totalMissing = missing.missingRuntime.length + missing.missingDev.length;
|
|
1677
|
+
console.log(import_picocolors7.default.cyan(`Installing ${totalMissing} missing Collie package${totalMissing === 1 ? "" : "s"}...`));
|
|
1678
|
+
await installPackages(packageManager, runtimeSpecs, devSpecs, projectRoot);
|
|
1679
|
+
console.log(import_picocolors7.default.green(`\u2714 Installed ${totalMissing} package${totalMissing === 1 ? "" : "s"}.`));
|
|
1680
|
+
console.log("");
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1714
1683
|
const detectedFramework = packageJson ? detectFrameworkFromPackage(packageJson) : null;
|
|
1715
1684
|
const cssDetection = await detectCssStrategy(projectRoot, packageJson);
|
|
1716
1685
|
const framework = options.framework ?? detectedFramework;
|
|
1717
1686
|
const projectType = framework ? mapFrameworkToProjectType(framework) : await promptProjectType();
|
|
1718
1687
|
const existingConfig = findExistingCollieConfig(projectRoot);
|
|
1719
|
-
const targetPath = existingConfig ??
|
|
1720
|
-
const relativeTarget =
|
|
1721
|
-
console.log(
|
|
1722
|
-
console.log(
|
|
1688
|
+
const targetPath = existingConfig ?? import_node_path8.default.join(projectRoot, "collie.config.ts");
|
|
1689
|
+
const relativeTarget = import_node_path8.default.relative(projectRoot, targetPath) || import_node_path8.default.basename(targetPath);
|
|
1690
|
+
console.log(import_picocolors7.default.bold("collie init"));
|
|
1691
|
+
console.log(import_picocolors7.default.dim("This creates a Collie config and applies framework wiring when possible."));
|
|
1723
1692
|
if (framework) {
|
|
1724
|
-
console.log(
|
|
1693
|
+
console.log(import_picocolors7.default.dim(`Detected ${formatFrameworkLabel(framework)} project.`));
|
|
1725
1694
|
} else {
|
|
1726
|
-
console.log(
|
|
1695
|
+
console.log(import_picocolors7.default.dim("No framework detected."));
|
|
1727
1696
|
}
|
|
1728
|
-
console.log(
|
|
1729
|
-
console.log(
|
|
1730
|
-
console.log(
|
|
1697
|
+
console.log(import_picocolors7.default.dim(`CSS strategy: ${formatCssDetection(cssDetection)}.`));
|
|
1698
|
+
console.log(import_picocolors7.default.dim(`Override in ${relativeTarget} via css.strategy and css.diagnostics.unknownClass.`));
|
|
1699
|
+
console.log(import_picocolors7.default.dim(`Project type: ${describeProjectType(projectType)}.`));
|
|
1731
1700
|
console.log("");
|
|
1732
1701
|
const configLabel = framework === "vite" ? "Vite-ready" : "Collie";
|
|
1733
1702
|
const confirmMessage = existingConfig ? `${relativeTarget} already exists. Replace it with a ${configLabel} config?` : `Create ${relativeTarget}?`;
|
|
@@ -1737,12 +1706,12 @@ async function runInit(options = {}) {
|
|
|
1737
1706
|
printSummary("warning", "No changes made", detail, "run collie init when you are ready");
|
|
1738
1707
|
return;
|
|
1739
1708
|
}
|
|
1740
|
-
const contents = buildInitConfig(projectType,
|
|
1741
|
-
await
|
|
1742
|
-
const typeDeclarationsPath =
|
|
1709
|
+
const contents = buildInitConfig(projectType, import_node_path8.default.extname(targetPath).toLowerCase(), cssDetection);
|
|
1710
|
+
await import_promises8.default.writeFile(targetPath, contents, "utf8");
|
|
1711
|
+
const typeDeclarationsPath = import_node_path8.default.join(projectRoot, "src", "collie.d.ts");
|
|
1743
1712
|
let typeDeclarationsStatus = "skipped";
|
|
1744
1713
|
if (projectType !== "html" && shouldWriteTypeDeclarations(projectRoot, options)) {
|
|
1745
|
-
if (
|
|
1714
|
+
if ((0, import_node_fs3.existsSync)(typeDeclarationsPath)) {
|
|
1746
1715
|
typeDeclarationsStatus = "exists";
|
|
1747
1716
|
} else {
|
|
1748
1717
|
await ensureCollieDeclaration(projectRoot);
|
|
@@ -1750,9 +1719,7 @@ async function runInit(options = {}) {
|
|
|
1750
1719
|
}
|
|
1751
1720
|
}
|
|
1752
1721
|
let viteConfigStatus = "skipped";
|
|
1753
|
-
let viteConfigPath = null;
|
|
1754
1722
|
if (framework === "vite") {
|
|
1755
|
-
viteConfigPath = findViteConfigFile(projectRoot);
|
|
1756
1723
|
if (viteConfigPath) {
|
|
1757
1724
|
viteConfigStatus = await patchViteConfig(viteConfigPath);
|
|
1758
1725
|
} else {
|
|
@@ -1761,32 +1728,32 @@ async function runInit(options = {}) {
|
|
|
1761
1728
|
}
|
|
1762
1729
|
printSummary("success", "Initialized Collie config", `created ${relativeTarget}`);
|
|
1763
1730
|
if (typeDeclarationsStatus !== "skipped") {
|
|
1764
|
-
const declarationLabel =
|
|
1731
|
+
const declarationLabel = import_node_path8.default.relative(projectRoot, typeDeclarationsPath) || import_node_path8.default.basename(typeDeclarationsPath);
|
|
1765
1732
|
if (typeDeclarationsStatus === "created") {
|
|
1766
|
-
console.log(
|
|
1733
|
+
console.log(import_picocolors7.default.green(`\u2714 Added ${declarationLabel} for .collie typings`));
|
|
1767
1734
|
} else {
|
|
1768
|
-
console.log(
|
|
1735
|
+
console.log(import_picocolors7.default.dim(`- ${declarationLabel} already exists`));
|
|
1769
1736
|
}
|
|
1770
1737
|
} else if (projectType !== "html") {
|
|
1771
1738
|
console.log(
|
|
1772
|
-
|
|
1739
|
+
import_picocolors7.default.dim("Skipping .collie typings (no TypeScript config found). Add src/collie.d.ts if you enable TypeScript.")
|
|
1773
1740
|
);
|
|
1774
1741
|
}
|
|
1775
1742
|
if (framework === "vite") {
|
|
1776
1743
|
if (viteConfigStatus === "patched" && viteConfigPath) {
|
|
1777
|
-
console.log(
|
|
1744
|
+
console.log(import_picocolors7.default.green(`\u2714 Updated ${import_node_path8.default.relative(projectRoot, viteConfigPath) || import_node_path8.default.basename(viteConfigPath)}`));
|
|
1778
1745
|
} else if (viteConfigStatus === "already-configured" && viteConfigPath) {
|
|
1779
1746
|
console.log(
|
|
1780
|
-
|
|
1747
|
+
import_picocolors7.default.dim(`- ${import_node_path8.default.relative(projectRoot, viteConfigPath) || import_node_path8.default.basename(viteConfigPath)} already includes collie()`)
|
|
1781
1748
|
);
|
|
1782
1749
|
} else if (viteConfigStatus === "manual" && viteConfigPath) {
|
|
1783
1750
|
console.log(
|
|
1784
|
-
|
|
1785
|
-
`\u26A0 Could not patch ${
|
|
1751
|
+
import_picocolors7.default.yellow(
|
|
1752
|
+
`\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
1753
|
)
|
|
1787
1754
|
);
|
|
1788
1755
|
} else if (viteConfigStatus === "not-found") {
|
|
1789
|
-
console.log(
|
|
1756
|
+
console.log(import_picocolors7.default.yellow("\u26A0 Vite config not found. Add the Collie plugin to vite.config.ts manually."));
|
|
1790
1757
|
}
|
|
1791
1758
|
}
|
|
1792
1759
|
if (framework === "vite") {
|
|
@@ -1794,36 +1761,32 @@ async function runInit(options = {}) {
|
|
|
1794
1761
|
printNextSteps(pkgManager, targetPath);
|
|
1795
1762
|
}
|
|
1796
1763
|
if (!framework) {
|
|
1797
|
-
console.log(
|
|
1764
|
+
console.log(import_picocolors7.default.dim(`Tip: update the project type in ${relativeTarget} if needed.`));
|
|
1798
1765
|
}
|
|
1799
1766
|
}
|
|
1800
1767
|
async function readProjectPackage(projectRoot) {
|
|
1801
|
-
const packageJsonPath =
|
|
1802
|
-
if (!
|
|
1768
|
+
const packageJsonPath = import_node_path8.default.join(projectRoot, "package.json");
|
|
1769
|
+
if (!(0, import_node_fs3.existsSync)(packageJsonPath)) {
|
|
1803
1770
|
return null;
|
|
1804
1771
|
}
|
|
1805
|
-
const raw = await
|
|
1772
|
+
const raw = await import_promises8.default.readFile(packageJsonPath, "utf8");
|
|
1806
1773
|
return JSON.parse(raw);
|
|
1807
1774
|
}
|
|
1808
1775
|
function detectFrameworkFromPackage(pkg) {
|
|
1809
|
-
if (hasNextDependency(pkg)) {
|
|
1810
|
-
return "nextjs";
|
|
1811
|
-
}
|
|
1812
1776
|
if (getViteDependencyInfo(pkg)) {
|
|
1813
1777
|
return "vite";
|
|
1814
1778
|
}
|
|
1815
1779
|
return null;
|
|
1816
1780
|
}
|
|
1817
1781
|
function mapFrameworkToProjectType(framework) {
|
|
1818
|
-
return
|
|
1782
|
+
return "react-vite";
|
|
1819
1783
|
}
|
|
1820
1784
|
function formatFrameworkLabel(framework) {
|
|
1821
|
-
return
|
|
1785
|
+
return "Vite";
|
|
1822
1786
|
}
|
|
1823
1787
|
function describeProjectType(projectType) {
|
|
1824
1788
|
const labels = {
|
|
1825
1789
|
"react-vite": "React (Vite)",
|
|
1826
|
-
"react-next": "React (Next.js)",
|
|
1827
1790
|
"react-generic": "React (generic)",
|
|
1828
1791
|
html: "HTML (no framework)"
|
|
1829
1792
|
};
|
|
@@ -1836,14 +1799,14 @@ function shouldWriteTypeDeclarations(projectRoot, options) {
|
|
|
1836
1799
|
if (options.typescript === true) {
|
|
1837
1800
|
return true;
|
|
1838
1801
|
}
|
|
1839
|
-
return
|
|
1802
|
+
return (0, import_node_fs3.existsSync)(import_node_path8.default.join(projectRoot, "tsconfig.json"));
|
|
1840
1803
|
}
|
|
1841
1804
|
async function detectCssStrategy(projectRoot, packageJson) {
|
|
1842
1805
|
const reasons = [];
|
|
1843
1806
|
try {
|
|
1844
1807
|
let tailwindDetected = false;
|
|
1845
1808
|
for (const filename of TAILWIND_CONFIG_FILES) {
|
|
1846
|
-
if (
|
|
1809
|
+
if ((0, import_node_fs3.existsSync)(import_node_path8.default.join(projectRoot, filename))) {
|
|
1847
1810
|
reasons.push(`${filename} found`);
|
|
1848
1811
|
tailwindDetected = true;
|
|
1849
1812
|
}
|
|
@@ -1891,11 +1854,11 @@ function hasTailwindDependency(pkg) {
|
|
|
1891
1854
|
}
|
|
1892
1855
|
async function scanPostcssForTailwind(projectRoot) {
|
|
1893
1856
|
for (const filename of POSTCSS_CONFIG_FILES) {
|
|
1894
|
-
const fullPath =
|
|
1895
|
-
if (!
|
|
1857
|
+
const fullPath = import_node_path8.default.join(projectRoot, filename);
|
|
1858
|
+
if (!(0, import_node_fs3.existsSync)(fullPath)) {
|
|
1896
1859
|
continue;
|
|
1897
1860
|
}
|
|
1898
|
-
const contents = await
|
|
1861
|
+
const contents = await import_promises8.default.readFile(fullPath, "utf8");
|
|
1899
1862
|
if (contents.includes("tailwindcss")) {
|
|
1900
1863
|
return filename;
|
|
1901
1864
|
}
|
|
@@ -1903,10 +1866,10 @@ async function scanPostcssForTailwind(projectRoot) {
|
|
|
1903
1866
|
return null;
|
|
1904
1867
|
}
|
|
1905
1868
|
async function scanTopLevelCssForTailwind(projectRoot) {
|
|
1906
|
-
const files = await
|
|
1869
|
+
const files = await (0, import_fast_glob4.default)("*.css", { cwd: projectRoot, onlyFiles: true });
|
|
1907
1870
|
for (const filename of files) {
|
|
1908
|
-
const fullPath =
|
|
1909
|
-
const contents = await
|
|
1871
|
+
const fullPath = import_node_path8.default.join(projectRoot, filename);
|
|
1872
|
+
const contents = await import_promises8.default.readFile(fullPath, "utf8");
|
|
1910
1873
|
if (/\@tailwind\s+(base|components|utilities)\b/.test(contents)) {
|
|
1911
1874
|
return filename;
|
|
1912
1875
|
}
|
|
@@ -1948,15 +1911,15 @@ function buildInitConfig(projectType, ext, cssDetection) {
|
|
|
1948
1911
|
}
|
|
1949
1912
|
function findExistingCollieConfig(root) {
|
|
1950
1913
|
for (const filename of COLLIE_CONFIG_FILES) {
|
|
1951
|
-
const candidate =
|
|
1952
|
-
if (
|
|
1914
|
+
const candidate = import_node_path8.default.join(root, filename);
|
|
1915
|
+
if ((0, import_node_fs3.existsSync)(candidate)) {
|
|
1953
1916
|
return candidate;
|
|
1954
1917
|
}
|
|
1955
1918
|
}
|
|
1956
1919
|
return null;
|
|
1957
1920
|
}
|
|
1958
1921
|
async function promptForConfirmation(message, initial) {
|
|
1959
|
-
const response = await
|
|
1922
|
+
const response = await (0, import_prompts2.default)(
|
|
1960
1923
|
{
|
|
1961
1924
|
type: "confirm",
|
|
1962
1925
|
name: "confirmed",
|
|
@@ -1968,14 +1931,13 @@ async function promptForConfirmation(message, initial) {
|
|
|
1968
1931
|
return Boolean(response.confirmed);
|
|
1969
1932
|
}
|
|
1970
1933
|
async function promptProjectType() {
|
|
1971
|
-
const response = await
|
|
1934
|
+
const response = await (0, import_prompts2.default)(
|
|
1972
1935
|
{
|
|
1973
1936
|
type: "select",
|
|
1974
1937
|
name: "projectType",
|
|
1975
1938
|
message: "What type of project should this config describe?",
|
|
1976
1939
|
choices: [
|
|
1977
1940
|
{ title: "React (Vite)", value: "react-vite" },
|
|
1978
|
-
{ title: "React (Next.js)", value: "react-next" },
|
|
1979
1941
|
{ title: "React (generic)", value: "react-generic" },
|
|
1980
1942
|
{ title: "HTML (no framework)", value: "html" }
|
|
1981
1943
|
],
|
|
@@ -1992,7 +1954,7 @@ async function runPreflight(command, options = {}) {
|
|
|
1992
1954
|
preflightCompleted = true;
|
|
1993
1955
|
const projectRoot = findProjectRoot(process.cwd());
|
|
1994
1956
|
if (!projectRoot) {
|
|
1995
|
-
console.log(
|
|
1957
|
+
console.log(import_picocolors7.default.dim("Skipping dependency preflight (no package.json found)."));
|
|
1996
1958
|
return true;
|
|
1997
1959
|
}
|
|
1998
1960
|
let packageJson = null;
|
|
@@ -2000,11 +1962,11 @@ async function runPreflight(command, options = {}) {
|
|
|
2000
1962
|
packageJson = await readProjectPackage(projectRoot);
|
|
2001
1963
|
} catch (error) {
|
|
2002
1964
|
const message = error instanceof Error ? error.message : String(error);
|
|
2003
|
-
console.log(
|
|
1965
|
+
console.log(import_picocolors7.default.yellow(`Skipping dependency preflight: failed to read package.json (${message}).`));
|
|
2004
1966
|
return true;
|
|
2005
1967
|
}
|
|
2006
1968
|
if (!packageJson) {
|
|
2007
|
-
console.log(
|
|
1969
|
+
console.log(import_picocolors7.default.dim("Skipping dependency preflight (package.json not found)."));
|
|
2008
1970
|
return true;
|
|
2009
1971
|
}
|
|
2010
1972
|
const detectedFramework = detectFrameworkFromPackage(packageJson);
|
|
@@ -2021,25 +1983,25 @@ async function runPreflight(command, options = {}) {
|
|
|
2021
1983
|
const prompt = `Missing required Collie packages: ${missing.join(", ")}. Install now?`;
|
|
2022
1984
|
const shouldInstall = await promptForConfirmation(prompt, true);
|
|
2023
1985
|
if (!shouldInstall) {
|
|
2024
|
-
console.log(
|
|
1986
|
+
console.log(import_picocolors7.default.yellow("Skipped installing Collie dependencies."));
|
|
2025
1987
|
console.log(
|
|
2026
|
-
|
|
1988
|
+
import_picocolors7.default.dim(`Next: ${formatInstallCommand(packageManager, missing)} && collie ${command}`)
|
|
2027
1989
|
);
|
|
2028
1990
|
return false;
|
|
2029
1991
|
}
|
|
2030
1992
|
const specs = missing.map((dep) => resolveDependencySpec(dep));
|
|
2031
|
-
console.log(
|
|
1993
|
+
console.log(import_picocolors7.default.cyan(`Installing ${missing.length} Collie package${missing.length === 1 ? "" : "s"}...`));
|
|
2032
1994
|
await installDevDependencies(packageManager, projectRoot, specs);
|
|
2033
|
-
console.log(
|
|
1995
|
+
console.log(import_picocolors7.default.green(`\u2714 Installed ${missing.length} Collie package${missing.length === 1 ? "" : "s"}.`));
|
|
2034
1996
|
return true;
|
|
2035
1997
|
}
|
|
2036
1998
|
function findProjectRoot(startDir) {
|
|
2037
1999
|
let current = startDir;
|
|
2038
2000
|
while (true) {
|
|
2039
|
-
if (
|
|
2001
|
+
if ((0, import_node_fs3.existsSync)(import_node_path8.default.join(current, "package.json"))) {
|
|
2040
2002
|
return current;
|
|
2041
2003
|
}
|
|
2042
|
-
const parent =
|
|
2004
|
+
const parent = import_node_path8.default.dirname(current);
|
|
2043
2005
|
if (parent === current) {
|
|
2044
2006
|
return null;
|
|
2045
2007
|
}
|
|
@@ -2050,9 +2012,6 @@ function getRequiredPackages(command, framework) {
|
|
|
2050
2012
|
if (command === "check") {
|
|
2051
2013
|
return ["@collie-lang/compiler"];
|
|
2052
2014
|
}
|
|
2053
|
-
if (framework === "nextjs") {
|
|
2054
|
-
return [...COLLIE_NEXT_PACKAGES];
|
|
2055
|
-
}
|
|
2056
2015
|
if (framework === "vite") {
|
|
2057
2016
|
return [...COLLIE_VITE_PACKAGES];
|
|
2058
2017
|
}
|
|
@@ -2068,8 +2027,8 @@ function isDependencySatisfied(projectRoot, packageJson, dependency) {
|
|
|
2068
2027
|
if (listed) {
|
|
2069
2028
|
return true;
|
|
2070
2029
|
}
|
|
2071
|
-
const modulePath =
|
|
2072
|
-
return
|
|
2030
|
+
const modulePath = import_node_path8.default.join(projectRoot, "node_modules", ...dependency.split("/"));
|
|
2031
|
+
return (0, import_node_fs3.existsSync)(modulePath);
|
|
2073
2032
|
}
|
|
2074
2033
|
function resolveDependencySpec(packageName) {
|
|
2075
2034
|
const range = normalizeDependencyRange(CLI_DEPENDENCY_SPECS[packageName], "latest");
|
|
@@ -2086,8 +2045,8 @@ function formatInstallCommand(packageManager, dependencies) {
|
|
|
2086
2045
|
return `npm install -D ${specs.join(" ")}`;
|
|
2087
2046
|
}
|
|
2088
2047
|
function detectPackageManager2(root) {
|
|
2089
|
-
if (
|
|
2090
|
-
if (
|
|
2048
|
+
if ((0, import_node_fs3.existsSync)(import_node_path8.default.join(root, "pnpm-lock.yaml"))) return "pnpm";
|
|
2049
|
+
if ((0, import_node_fs3.existsSync)(import_node_path8.default.join(root, "yarn.lock"))) return "yarn";
|
|
2091
2050
|
return "npm";
|
|
2092
2051
|
}
|
|
2093
2052
|
async function installDevDependencies(packageManager, cwd, deps) {
|
|
@@ -2099,7 +2058,7 @@ async function installDevDependencies(packageManager, cwd, deps) {
|
|
|
2099
2058
|
await runCommand2(packageManager, argsByManager[packageManager], cwd);
|
|
2100
2059
|
}
|
|
2101
2060
|
async function patchViteConfig(configPath) {
|
|
2102
|
-
const original = await
|
|
2061
|
+
const original = await import_promises8.default.readFile(configPath, "utf8");
|
|
2103
2062
|
const hasImport = original.includes("@collie-lang/vite");
|
|
2104
2063
|
const hasPlugin = /\bcollie\s*\(/.test(original);
|
|
2105
2064
|
if (hasImport && hasPlugin) {
|
|
@@ -2110,37 +2069,37 @@ async function patchViteConfig(configPath) {
|
|
|
2110
2069
|
if (!result.changed) {
|
|
2111
2070
|
return "already-configured";
|
|
2112
2071
|
}
|
|
2113
|
-
await
|
|
2072
|
+
await import_promises8.default.writeFile(configPath, result.code, "utf8");
|
|
2114
2073
|
return "patched";
|
|
2115
2074
|
} catch (error) {
|
|
2116
2075
|
return "manual";
|
|
2117
2076
|
}
|
|
2118
2077
|
}
|
|
2119
2078
|
function transformViteConfig(source) {
|
|
2120
|
-
const sourceFile =
|
|
2079
|
+
const sourceFile = import_typescript.default.createSourceFile(
|
|
2121
2080
|
"vite.config.ts",
|
|
2122
2081
|
source,
|
|
2123
|
-
|
|
2082
|
+
import_typescript.default.ScriptTarget.Latest,
|
|
2124
2083
|
true,
|
|
2125
|
-
|
|
2084
|
+
import_typescript.default.ScriptKind.TS
|
|
2126
2085
|
);
|
|
2127
2086
|
let needsImport = !source.includes("@collie-lang/vite");
|
|
2128
2087
|
let needsPlugin = !/\bcollie\s*\(/.test(source);
|
|
2129
2088
|
let changed = false;
|
|
2130
|
-
const printer =
|
|
2089
|
+
const printer = import_typescript.default.createPrinter({ newLine: import_typescript.default.NewLineKind.LineFeed });
|
|
2131
2090
|
const transformer = (context) => {
|
|
2132
2091
|
return (rootNode) => {
|
|
2133
2092
|
function visit(node) {
|
|
2134
|
-
if (needsImport &&
|
|
2093
|
+
if (needsImport && import_typescript.default.isImportDeclaration(node)) {
|
|
2135
2094
|
return node;
|
|
2136
2095
|
}
|
|
2137
|
-
if (
|
|
2096
|
+
if (import_typescript.default.isCallExpression(node) && import_typescript.default.isIdentifier(node.expression) && node.expression.text === "defineConfig" && node.arguments.length > 0) {
|
|
2138
2097
|
const configArg = node.arguments[0];
|
|
2139
|
-
if (
|
|
2098
|
+
if (import_typescript.default.isObjectLiteralExpression(configArg)) {
|
|
2140
2099
|
const updatedConfig = updateConfigObject(configArg);
|
|
2141
2100
|
if (updatedConfig !== configArg) {
|
|
2142
2101
|
changed = true;
|
|
2143
|
-
return
|
|
2102
|
+
return import_typescript.default.factory.updateCallExpression(
|
|
2144
2103
|
node,
|
|
2145
2104
|
node.expression,
|
|
2146
2105
|
node.typeArguments,
|
|
@@ -2149,42 +2108,42 @@ function transformViteConfig(source) {
|
|
|
2149
2108
|
}
|
|
2150
2109
|
}
|
|
2151
2110
|
}
|
|
2152
|
-
return
|
|
2111
|
+
return import_typescript.default.visitEachChild(node, visit, context);
|
|
2153
2112
|
}
|
|
2154
2113
|
function updateConfigObject(configObj) {
|
|
2155
2114
|
let pluginsProperty;
|
|
2156
2115
|
const otherProperties = [];
|
|
2157
2116
|
for (const prop of configObj.properties) {
|
|
2158
|
-
if (
|
|
2117
|
+
if (import_typescript.default.isPropertyAssignment(prop) && import_typescript.default.isIdentifier(prop.name) && prop.name.text === "plugins") {
|
|
2159
2118
|
pluginsProperty = prop;
|
|
2160
2119
|
} else {
|
|
2161
2120
|
otherProperties.push(prop);
|
|
2162
2121
|
}
|
|
2163
2122
|
}
|
|
2164
2123
|
let updatedPluginsArray;
|
|
2165
|
-
if (pluginsProperty &&
|
|
2124
|
+
if (pluginsProperty && import_typescript.default.isArrayLiteralExpression(pluginsProperty.initializer)) {
|
|
2166
2125
|
updatedPluginsArray = ensurePluginOrdering(pluginsProperty.initializer);
|
|
2167
2126
|
if (updatedPluginsArray === pluginsProperty.initializer) {
|
|
2168
2127
|
return configObj;
|
|
2169
2128
|
}
|
|
2170
2129
|
} else if (needsPlugin) {
|
|
2171
|
-
updatedPluginsArray =
|
|
2130
|
+
updatedPluginsArray = import_typescript.default.factory.createArrayLiteralExpression(
|
|
2172
2131
|
[createCollieCall()],
|
|
2173
2132
|
false
|
|
2174
2133
|
);
|
|
2175
2134
|
} else {
|
|
2176
2135
|
return configObj;
|
|
2177
2136
|
}
|
|
2178
|
-
const updatedPluginsProperty =
|
|
2137
|
+
const updatedPluginsProperty = import_typescript.default.factory.createPropertyAssignment(
|
|
2179
2138
|
"plugins",
|
|
2180
2139
|
updatedPluginsArray
|
|
2181
2140
|
);
|
|
2182
2141
|
if (pluginsProperty) {
|
|
2183
2142
|
const allProperties = [...otherProperties, updatedPluginsProperty];
|
|
2184
|
-
return
|
|
2143
|
+
return import_typescript.default.factory.updateObjectLiteralExpression(configObj, allProperties);
|
|
2185
2144
|
} else {
|
|
2186
2145
|
const allProperties = [...otherProperties, updatedPluginsProperty];
|
|
2187
|
-
return
|
|
2146
|
+
return import_typescript.default.factory.updateObjectLiteralExpression(configObj, allProperties);
|
|
2188
2147
|
}
|
|
2189
2148
|
}
|
|
2190
2149
|
function ensurePluginOrdering(array) {
|
|
@@ -2194,7 +2153,7 @@ function transformViteConfig(source) {
|
|
|
2194
2153
|
let reactIndex = -1;
|
|
2195
2154
|
let collieIndex = -1;
|
|
2196
2155
|
elements.forEach((elem, idx) => {
|
|
2197
|
-
if (
|
|
2156
|
+
if (import_typescript.default.isCallExpression(elem) && import_typescript.default.isIdentifier(elem.expression)) {
|
|
2198
2157
|
if (elem.expression.text === "react") {
|
|
2199
2158
|
hasReact = true;
|
|
2200
2159
|
reactIndex = idx;
|
|
@@ -2212,37 +2171,37 @@ function transformViteConfig(source) {
|
|
|
2212
2171
|
const colliePlugin = newElements[collieIndex];
|
|
2213
2172
|
newElements[collieIndex] = reactPlugin;
|
|
2214
2173
|
newElements[reactIndex] = colliePlugin;
|
|
2215
|
-
return
|
|
2174
|
+
return import_typescript.default.factory.createArrayLiteralExpression(newElements, isMultiLine);
|
|
2216
2175
|
}
|
|
2217
2176
|
return array;
|
|
2218
2177
|
}
|
|
2219
2178
|
if (!hasCollie && needsPlugin) {
|
|
2220
2179
|
const newElements = [...elements, createCollieCall()];
|
|
2221
|
-
return
|
|
2180
|
+
return import_typescript.default.factory.createArrayLiteralExpression(newElements, isMultiLine);
|
|
2222
2181
|
}
|
|
2223
2182
|
return array;
|
|
2224
2183
|
}
|
|
2225
2184
|
function createCollieCall() {
|
|
2226
|
-
return
|
|
2227
|
-
|
|
2185
|
+
return import_typescript.default.factory.createCallExpression(
|
|
2186
|
+
import_typescript.default.factory.createIdentifier("collie"),
|
|
2228
2187
|
void 0,
|
|
2229
2188
|
[]
|
|
2230
2189
|
);
|
|
2231
2190
|
}
|
|
2232
|
-
const visited =
|
|
2191
|
+
const visited = import_typescript.default.visitNode(rootNode, visit);
|
|
2233
2192
|
if (needsImport && changed) {
|
|
2234
|
-
const collieImport =
|
|
2193
|
+
const collieImport = import_typescript.default.factory.createImportDeclaration(
|
|
2235
2194
|
void 0,
|
|
2236
|
-
|
|
2195
|
+
import_typescript.default.factory.createImportClause(
|
|
2237
2196
|
false,
|
|
2238
|
-
|
|
2197
|
+
import_typescript.default.factory.createIdentifier("collie"),
|
|
2239
2198
|
void 0
|
|
2240
2199
|
),
|
|
2241
|
-
|
|
2200
|
+
import_typescript.default.factory.createStringLiteral("@collie-lang/vite", true)
|
|
2242
2201
|
);
|
|
2243
2202
|
let lastImportIndex = -1;
|
|
2244
2203
|
for (let i = 0; i < visited.statements.length; i++) {
|
|
2245
|
-
if (
|
|
2204
|
+
if (import_typescript.default.isImportDeclaration(visited.statements[i])) {
|
|
2246
2205
|
lastImportIndex = i;
|
|
2247
2206
|
}
|
|
2248
2207
|
}
|
|
@@ -2252,12 +2211,12 @@ function transformViteConfig(source) {
|
|
|
2252
2211
|
} else {
|
|
2253
2212
|
statements.unshift(collieImport);
|
|
2254
2213
|
}
|
|
2255
|
-
return
|
|
2214
|
+
return import_typescript.default.factory.updateSourceFile(visited, statements);
|
|
2256
2215
|
}
|
|
2257
2216
|
return visited;
|
|
2258
2217
|
};
|
|
2259
2218
|
};
|
|
2260
|
-
const result =
|
|
2219
|
+
const result = import_typescript.default.transform(sourceFile, [transformer]);
|
|
2261
2220
|
const transformedSourceFile = result.transformed[0];
|
|
2262
2221
|
result.dispose();
|
|
2263
2222
|
if (!changed) {
|
|
@@ -2267,9 +2226,9 @@ function transformViteConfig(source) {
|
|
|
2267
2226
|
return { code: output, changed: true };
|
|
2268
2227
|
}
|
|
2269
2228
|
async function ensureCollieDeclaration(root) {
|
|
2270
|
-
const target =
|
|
2271
|
-
if (
|
|
2272
|
-
await
|
|
2229
|
+
const target = import_node_path8.default.join(root, "src", "collie.d.ts");
|
|
2230
|
+
if ((0, import_node_fs3.existsSync)(target)) return;
|
|
2231
|
+
await import_promises8.default.mkdir(import_node_path8.default.dirname(target), { recursive: true });
|
|
2273
2232
|
const declaration = `// Allows importing Collie templates as React components.
|
|
2274
2233
|
// Customize this typing if your templates expose specific props.
|
|
2275
2234
|
declare module "*.collie" {
|
|
@@ -2278,22 +2237,67 @@ declare module "*.collie" {
|
|
|
2278
2237
|
export default component;
|
|
2279
2238
|
}
|
|
2280
2239
|
`;
|
|
2281
|
-
await
|
|
2240
|
+
await import_promises8.default.writeFile(target, declaration, "utf8");
|
|
2282
2241
|
}
|
|
2283
|
-
function
|
|
2284
|
-
for (const
|
|
2285
|
-
const candidate =
|
|
2286
|
-
if (
|
|
2242
|
+
function findViteConfigPath(projectRoot) {
|
|
2243
|
+
for (const filename of VITE_CONFIG_PATTERNS) {
|
|
2244
|
+
const candidate = import_node_path8.default.join(projectRoot, filename);
|
|
2245
|
+
if ((0, import_node_fs3.existsSync)(candidate)) {
|
|
2287
2246
|
return candidate;
|
|
2288
2247
|
}
|
|
2289
2248
|
}
|
|
2290
2249
|
return null;
|
|
2291
2250
|
}
|
|
2251
|
+
function getCollieVersionSpec(packageJson) {
|
|
2252
|
+
if (!packageJson) return null;
|
|
2253
|
+
const cliSpec = packageJson.dependencies?.["@collie-lang/cli"] || packageJson.devDependencies?.["@collie-lang/cli"];
|
|
2254
|
+
if (!cliSpec) return null;
|
|
2255
|
+
if (cliSpec.startsWith("workspace:") || cliSpec.startsWith("file:")) {
|
|
2256
|
+
return null;
|
|
2257
|
+
}
|
|
2258
|
+
return cliSpec;
|
|
2259
|
+
}
|
|
2260
|
+
function computeMissingCollieDeps(packageJson) {
|
|
2261
|
+
const missingRuntime = [];
|
|
2262
|
+
const missingDev = [];
|
|
2263
|
+
if (!packageJson) {
|
|
2264
|
+
return { missingRuntime, missingDev };
|
|
2265
|
+
}
|
|
2266
|
+
const deps = packageJson.dependencies || {};
|
|
2267
|
+
const devDeps = packageJson.devDependencies || {};
|
|
2268
|
+
const reactInDeps = "@collie-lang/react" in deps;
|
|
2269
|
+
const reactInDevDeps = "@collie-lang/react" in devDeps;
|
|
2270
|
+
if (!reactInDeps) {
|
|
2271
|
+
missingRuntime.push("@collie-lang/react");
|
|
2272
|
+
}
|
|
2273
|
+
const requiredDevPackages = [
|
|
2274
|
+
"@collie-lang/vite",
|
|
2275
|
+
"@collie-lang/compiler",
|
|
2276
|
+
"@collie-lang/config"
|
|
2277
|
+
];
|
|
2278
|
+
for (const pkg of requiredDevPackages) {
|
|
2279
|
+
const inDeps = pkg in deps;
|
|
2280
|
+
const inDevDeps = pkg in devDeps;
|
|
2281
|
+
if (!inDeps && !inDevDeps) {
|
|
2282
|
+
missingDev.push(pkg);
|
|
2283
|
+
}
|
|
2284
|
+
}
|
|
2285
|
+
return { missingRuntime, missingDev };
|
|
2286
|
+
}
|
|
2287
|
+
async function installPackages(packageManager, runtimePkgs, devPkgs, cwd) {
|
|
2288
|
+
if (runtimePkgs.length > 0) {
|
|
2289
|
+
const args = packageManager === "npm" ? ["install", ...runtimePkgs] : packageManager === "pnpm" ? ["add", ...runtimePkgs] : ["add", ...runtimePkgs];
|
|
2290
|
+
await runCommand2(packageManager, args, cwd);
|
|
2291
|
+
}
|
|
2292
|
+
if (devPkgs.length > 0) {
|
|
2293
|
+
const args = packageManager === "npm" ? ["install", "-D", ...devPkgs] : packageManager === "pnpm" ? ["add", "-D", ...devPkgs] : ["add", "-D", ...devPkgs];
|
|
2294
|
+
await runCommand2(packageManager, args, cwd);
|
|
2295
|
+
}
|
|
2296
|
+
}
|
|
2292
2297
|
function readCliPackageInfo() {
|
|
2293
2298
|
try {
|
|
2294
|
-
const
|
|
2295
|
-
const
|
|
2296
|
-
const raw = readFileSync(pkgPath, "utf8");
|
|
2299
|
+
const pkgPath = import_node_path8.default.resolve(__dirname, "..", "package.json");
|
|
2300
|
+
const raw = (0, import_node_fs3.readFileSync)(pkgPath, "utf8");
|
|
2297
2301
|
const pkg = JSON.parse(raw);
|
|
2298
2302
|
const version = typeof pkg.version === "string" ? pkg.version : "latest";
|
|
2299
2303
|
const dependencies = pkg && typeof pkg === "object" && pkg.dependencies && typeof pkg.dependencies === "object" ? pkg.dependencies : {};
|
|
@@ -2325,10 +2329,10 @@ function getViteDependencyInfo(pkg) {
|
|
|
2325
2329
|
function printNextSteps(pkgManager, configPath) {
|
|
2326
2330
|
const devCommand = formatDevCommand(pkgManager);
|
|
2327
2331
|
console.log("");
|
|
2328
|
-
console.log(
|
|
2332
|
+
console.log(import_picocolors7.default.green("Next steps:"));
|
|
2329
2333
|
console.log(` - Create a Collie template under src (e.g. src/Hello.collie).`);
|
|
2330
2334
|
console.log(` - Import it in your React app and run ${devCommand} to start Vite.`);
|
|
2331
|
-
console.log(` - Need to adjust plugins later? Edit ${
|
|
2335
|
+
console.log(` - Need to adjust plugins later? Edit ${import_node_path8.default.basename(configPath)}.`);
|
|
2332
2336
|
}
|
|
2333
2337
|
function formatDevCommand(pkgManager) {
|
|
2334
2338
|
if (pkgManager === "pnpm") return "pnpm dev";
|
|
@@ -2337,7 +2341,7 @@ function formatDevCommand(pkgManager) {
|
|
|
2337
2341
|
}
|
|
2338
2342
|
function runCommand2(command, args, cwd) {
|
|
2339
2343
|
return new Promise((resolve, reject) => {
|
|
2340
|
-
const child =
|
|
2344
|
+
const child = (0, import_node_child_process2.spawn)(command, args, { cwd, stdio: "inherit" });
|
|
2341
2345
|
child.on("error", reject);
|
|
2342
2346
|
child.on("close", (code) => {
|
|
2343
2347
|
if (code === 0) resolve();
|
|
@@ -2352,7 +2356,7 @@ async function runFormat(args) {
|
|
|
2352
2356
|
}
|
|
2353
2357
|
const indent = flags.indent ?? 2;
|
|
2354
2358
|
const cwd = process.cwd();
|
|
2355
|
-
const files = await
|
|
2359
|
+
const files = await (0, import_fast_glob4.default)(patterns, { cwd, onlyFiles: true, unique: true });
|
|
2356
2360
|
if (!files.length) {
|
|
2357
2361
|
printSummary("warning", "No files matched the provided patterns", void 0, "check the glob and try again");
|
|
2358
2362
|
return;
|
|
@@ -2364,10 +2368,10 @@ async function runFormat(args) {
|
|
|
2364
2368
|
for (const file of files) {
|
|
2365
2369
|
let contents;
|
|
2366
2370
|
try {
|
|
2367
|
-
contents = await
|
|
2371
|
+
contents = await import_promises8.default.readFile(file, "utf8");
|
|
2368
2372
|
} catch (error) {
|
|
2369
2373
|
const message = error instanceof Error ? error.message : String(error);
|
|
2370
|
-
console.error(
|
|
2374
|
+
console.error(import_picocolors7.default.red(`\u2716 Failed to read ${file}: ${message}`));
|
|
2371
2375
|
failures++;
|
|
2372
2376
|
continue;
|
|
2373
2377
|
}
|
|
@@ -2376,7 +2380,7 @@ async function runFormat(args) {
|
|
|
2376
2380
|
result = formatSource(contents, { indent });
|
|
2377
2381
|
} catch (error) {
|
|
2378
2382
|
const message = error instanceof Error ? error.message : String(error);
|
|
2379
|
-
console.error(
|
|
2383
|
+
console.error(import_picocolors7.default.red(`\u2716 Failed to format ${file}: ${message}`));
|
|
2380
2384
|
failures++;
|
|
2381
2385
|
continue;
|
|
2382
2386
|
}
|
|
@@ -2391,20 +2395,20 @@ async function runFormat(args) {
|
|
|
2391
2395
|
}
|
|
2392
2396
|
if (flags.check) {
|
|
2393
2397
|
if (changed) {
|
|
2394
|
-
console.log(
|
|
2398
|
+
console.log(import_picocolors7.default.red(`\u2716 ${file} needs formatting`));
|
|
2395
2399
|
needsFormatting++;
|
|
2396
2400
|
} else {
|
|
2397
|
-
console.log(
|
|
2401
|
+
console.log(import_picocolors7.default.green(`\u2714 ${file} is formatted`));
|
|
2398
2402
|
}
|
|
2399
2403
|
continue;
|
|
2400
2404
|
}
|
|
2401
2405
|
if (flags.write) {
|
|
2402
2406
|
if (changed) {
|
|
2403
|
-
await
|
|
2407
|
+
await import_promises8.default.writeFile(file, result.formatted, "utf8");
|
|
2404
2408
|
written++;
|
|
2405
|
-
console.log(
|
|
2409
|
+
console.log(import_picocolors7.default.green(`\u2714 Formatted ${file}`));
|
|
2406
2410
|
} else {
|
|
2407
|
-
console.log(
|
|
2411
|
+
console.log(import_picocolors7.default.dim(`- ${file} already formatted`));
|
|
2408
2412
|
}
|
|
2409
2413
|
continue;
|
|
2410
2414
|
}
|
|
@@ -2420,7 +2424,7 @@ async function runFormat(args) {
|
|
|
2420
2424
|
`${needsFormatting} file${needsFormatting === 1 ? "" : "s"} need formatting`,
|
|
2421
2425
|
"no files changed"
|
|
2422
2426
|
);
|
|
2423
|
-
console.log(
|
|
2427
|
+
console.log(import_picocolors7.default.dim("Run: collie format --write to fix"));
|
|
2424
2428
|
process.exitCode = 1;
|
|
2425
2429
|
} else if (failures > 0) {
|
|
2426
2430
|
printSummary(
|
|
@@ -2502,18 +2506,18 @@ function printDiagnostics(file, diagnostics) {
|
|
|
2502
2506
|
for (const diag of diagnostics) {
|
|
2503
2507
|
const message = formatDiagnosticLine({ ...diag, file }, file);
|
|
2504
2508
|
if (diag.severity === "warning") {
|
|
2505
|
-
console.warn(
|
|
2509
|
+
console.warn(import_picocolors7.default.yellow(message));
|
|
2506
2510
|
} else {
|
|
2507
|
-
console.error(
|
|
2511
|
+
console.error(import_picocolors7.default.red(message));
|
|
2508
2512
|
}
|
|
2509
2513
|
}
|
|
2510
2514
|
}
|
|
2511
2515
|
function printDiff(file, before, after) {
|
|
2512
|
-
console.log(
|
|
2513
|
-
const diff = diffLines(before, after);
|
|
2516
|
+
console.log(import_picocolors7.default.cyan(`diff -- ${file}`));
|
|
2517
|
+
const diff = (0, import_diff.diffLines)(before, after);
|
|
2514
2518
|
for (const part of diff) {
|
|
2515
2519
|
const prefix = part.added ? "+" : part.removed ? "-" : " ";
|
|
2516
|
-
const color = part.added ?
|
|
2520
|
+
const color = part.added ? import_picocolors7.default.green : part.removed ? import_picocolors7.default.red : import_picocolors7.default.dim;
|
|
2517
2521
|
const lines = part.value.split("\n");
|
|
2518
2522
|
for (let i = 0; i < lines.length; i++) {
|
|
2519
2523
|
const line = lines[i];
|
|
@@ -2554,7 +2558,7 @@ function validateFormatFlag(value) {
|
|
|
2554
2558
|
throw new Error('Invalid --format flag. Use "text" or "json".');
|
|
2555
2559
|
}
|
|
2556
2560
|
function printCliError(message) {
|
|
2557
|
-
console.error(
|
|
2561
|
+
console.error(import_picocolors7.default.red(`\u2716 ${message}`));
|
|
2558
2562
|
}
|
|
2559
2563
|
main().catch((error) => {
|
|
2560
2564
|
printCliError(error instanceof Error ? error.message : String(error));
|