camelmind 0.2.2 → 0.2.3
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 +192 -14
- package/package.json +1 -1
- package/template/_package.json +4 -0
package/dist/index.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { Command } from "commander";
|
|
5
|
-
import { fileURLToPath as
|
|
6
|
-
import
|
|
7
|
-
import
|
|
5
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
6
|
+
import path3 from "path";
|
|
7
|
+
import fs3 from "fs";
|
|
8
8
|
|
|
9
9
|
// src/commands/init.ts
|
|
10
10
|
import path from "path";
|
|
@@ -135,11 +135,188 @@ async function init(projectName, options) {
|
|
|
135
135
|
`);
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
// src/commands/
|
|
138
|
+
// src/commands/update.ts
|
|
139
|
+
import path2 from "path";
|
|
140
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
141
|
+
import { execSync as execSync2 } from "child_process";
|
|
142
|
+
import fs2 from "fs-extra";
|
|
139
143
|
import chalk2 from "chalk";
|
|
140
144
|
import ora2 from "ora";
|
|
145
|
+
import prompts2 from "prompts";
|
|
146
|
+
var __dirname2 = path2.dirname(fileURLToPath2(import.meta.url));
|
|
147
|
+
var TEMPLATE_DIR2 = path2.join(__dirname2, "../template");
|
|
148
|
+
var FRAMEWORK_DIRS = ["app", "components", "lib", "public", "scripts"];
|
|
149
|
+
var FRAMEWORK_FILES = [
|
|
150
|
+
"next.config.ts",
|
|
151
|
+
"postcss.config.mjs",
|
|
152
|
+
"tsconfig.json",
|
|
153
|
+
"eslint.config.mjs",
|
|
154
|
+
"proxy.ts"
|
|
155
|
+
];
|
|
156
|
+
async function walkFiles(dir) {
|
|
157
|
+
if (!await fs2.pathExists(dir)) return [];
|
|
158
|
+
const entries = await fs2.readdir(dir, { withFileTypes: true });
|
|
159
|
+
const files = [];
|
|
160
|
+
for (const entry of entries) {
|
|
161
|
+
if (entry.name === "node_modules" || entry.name === ".next" || entry.name === ".git") {
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
const fullPath = path2.join(dir, entry.name);
|
|
165
|
+
if (entry.isDirectory()) {
|
|
166
|
+
files.push(...await walkFiles(fullPath));
|
|
167
|
+
} else if (entry.isFile()) {
|
|
168
|
+
files.push(fullPath);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return files;
|
|
172
|
+
}
|
|
173
|
+
function mergePackageJson(current, template) {
|
|
174
|
+
return {
|
|
175
|
+
...current,
|
|
176
|
+
scripts: {
|
|
177
|
+
...template.scripts,
|
|
178
|
+
...current.scripts
|
|
179
|
+
},
|
|
180
|
+
dependencies: {
|
|
181
|
+
...current.dependencies,
|
|
182
|
+
...template.dependencies
|
|
183
|
+
},
|
|
184
|
+
devDependencies: {
|
|
185
|
+
...current.devDependencies,
|
|
186
|
+
...template.devDependencies
|
|
187
|
+
},
|
|
188
|
+
overrides: {
|
|
189
|
+
...current.overrides,
|
|
190
|
+
...template.overrides
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
async function copyWithBackup(source, target, backupRoot, projectRoot) {
|
|
195
|
+
if (await fs2.pathExists(target)) {
|
|
196
|
+
await backupFile(target, backupRoot, projectRoot);
|
|
197
|
+
}
|
|
198
|
+
await fs2.ensureDir(path2.dirname(target));
|
|
199
|
+
await fs2.copy(source, target, { overwrite: true });
|
|
200
|
+
}
|
|
201
|
+
async function backupFile(file, backupRoot, projectRoot) {
|
|
202
|
+
const rel = path2.relative(projectRoot, file);
|
|
203
|
+
await fs2.ensureDir(path2.dirname(path2.join(backupRoot, rel)));
|
|
204
|
+
await fs2.copy(file, path2.join(backupRoot, rel), { overwrite: true });
|
|
205
|
+
}
|
|
206
|
+
async function updatePackageJson(projectRoot, backupRoot, dryRun) {
|
|
207
|
+
const projectPkgPath = path2.join(projectRoot, "package.json");
|
|
208
|
+
const templatePkgPath = path2.join(TEMPLATE_DIR2, "_package.json");
|
|
209
|
+
const current = await fs2.readJson(projectPkgPath);
|
|
210
|
+
const template = await fs2.readJson(templatePkgPath);
|
|
211
|
+
const merged = mergePackageJson(current, template);
|
|
212
|
+
if (dryRun) return;
|
|
213
|
+
await backupFile(projectPkgPath, backupRoot, projectRoot);
|
|
214
|
+
await fs2.writeJson(projectPkgPath, merged, { spaces: 2 });
|
|
215
|
+
await fs2.appendFile(projectPkgPath, "\n");
|
|
216
|
+
}
|
|
217
|
+
async function plannedTemplateFiles() {
|
|
218
|
+
const files = [];
|
|
219
|
+
for (const dir of FRAMEWORK_DIRS) {
|
|
220
|
+
const dirPath = path2.join(TEMPLATE_DIR2, dir);
|
|
221
|
+
const dirFiles = await walkFiles(dirPath);
|
|
222
|
+
files.push(...dirFiles.map((file) => path2.relative(TEMPLATE_DIR2, file)));
|
|
223
|
+
}
|
|
224
|
+
files.push(...FRAMEWORK_FILES);
|
|
225
|
+
return files.sort();
|
|
226
|
+
}
|
|
227
|
+
async function update(targetDir, options) {
|
|
228
|
+
const projectRoot = path2.resolve(process.cwd(), targetDir ?? ".");
|
|
229
|
+
const packageJsonPath = path2.join(projectRoot, "package.json");
|
|
230
|
+
const configPath = path2.join(projectRoot, "camelmind.config.ts");
|
|
231
|
+
if (!await fs2.pathExists(TEMPLATE_DIR2)) {
|
|
232
|
+
console.error(chalk2.red("Template directory not found in the installed CamelMind package."));
|
|
233
|
+
process.exit(1);
|
|
234
|
+
}
|
|
235
|
+
if (!await fs2.pathExists(packageJsonPath) || !await fs2.pathExists(configPath)) {
|
|
236
|
+
console.error(chalk2.red("Run this command from a CamelMind project root, or pass the project directory."));
|
|
237
|
+
process.exit(1);
|
|
238
|
+
}
|
|
239
|
+
const files = await plannedTemplateFiles();
|
|
240
|
+
const backupRoot = path2.join(
|
|
241
|
+
projectRoot,
|
|
242
|
+
".camelmind-update-backup",
|
|
243
|
+
(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")
|
|
244
|
+
);
|
|
245
|
+
console.log(`
|
|
246
|
+
${chalk2.hex("#D8A15B").bold("CamelMind update")}
|
|
247
|
+
|
|
248
|
+
Project: ${chalk2.cyan(projectRoot)}
|
|
249
|
+
Files: ${chalk2.cyan(String(files.length))} framework files + package.json
|
|
250
|
+
Backup: ${chalk2.cyan(path2.relative(projectRoot, backupRoot))}
|
|
251
|
+
`);
|
|
252
|
+
if (options.dryRun) {
|
|
253
|
+
console.log(chalk2.bold(" Dry run \u2014 files that would be refreshed:\n"));
|
|
254
|
+
for (const file of files) console.log(` ${file}`);
|
|
255
|
+
console.log(" package.json");
|
|
256
|
+
console.log("");
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (!options.yes) {
|
|
260
|
+
const { proceed } = await prompts2(
|
|
261
|
+
{
|
|
262
|
+
type: "confirm",
|
|
263
|
+
name: "proceed",
|
|
264
|
+
message: "Refresh CamelMind framework files and merge package updates?",
|
|
265
|
+
initial: true
|
|
266
|
+
},
|
|
267
|
+
{ onCancel: () => process.exit(0) }
|
|
268
|
+
);
|
|
269
|
+
if (!proceed) {
|
|
270
|
+
console.log(chalk2.gray("\n Update cancelled.\n"));
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
const spinner = ora2("Refreshing CamelMind framework files...").start();
|
|
275
|
+
try {
|
|
276
|
+
for (const rel of files) {
|
|
277
|
+
await copyWithBackup(
|
|
278
|
+
path2.join(TEMPLATE_DIR2, rel),
|
|
279
|
+
path2.join(projectRoot, rel),
|
|
280
|
+
backupRoot,
|
|
281
|
+
projectRoot
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
await updatePackageJson(projectRoot, backupRoot, false);
|
|
285
|
+
spinner.succeed("CamelMind files refreshed");
|
|
286
|
+
} catch (err) {
|
|
287
|
+
spinner.fail("Update failed");
|
|
288
|
+
console.error(chalk2.red(`
|
|
289
|
+
${String(err)}
|
|
290
|
+
`));
|
|
291
|
+
process.exit(1);
|
|
292
|
+
}
|
|
293
|
+
if (options.install) {
|
|
294
|
+
const installSpinner = ora2("Installing updated dependencies...").start();
|
|
295
|
+
try {
|
|
296
|
+
execSync2("npm install", {
|
|
297
|
+
cwd: projectRoot,
|
|
298
|
+
stdio: "ignore"
|
|
299
|
+
});
|
|
300
|
+
installSpinner.succeed("Dependencies installed");
|
|
301
|
+
} catch {
|
|
302
|
+
installSpinner.warn("Dependency install failed \u2014 run npm install inside your project");
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
console.log(`
|
|
306
|
+
${chalk2.green("Done.")} Review the changes, then run:
|
|
307
|
+
|
|
308
|
+
${chalk2.cyan("npm run lint")}
|
|
309
|
+
${chalk2.cyan("npm run build")}
|
|
310
|
+
|
|
311
|
+
Backup saved in ${chalk2.cyan(path2.relative(projectRoot, backupRoot))}
|
|
312
|
+
`);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// src/commands/version.ts
|
|
316
|
+
import chalk3 from "chalk";
|
|
317
|
+
import ora3 from "ora";
|
|
141
318
|
async function checkVersion(currentVersion) {
|
|
142
|
-
const spinner =
|
|
319
|
+
const spinner = ora3("Checking latest version...").start();
|
|
143
320
|
let latestVersion;
|
|
144
321
|
try {
|
|
145
322
|
const res = await fetch("https://registry.npmjs.org/camelmind/latest");
|
|
@@ -150,7 +327,7 @@ async function checkVersion(currentVersion) {
|
|
|
150
327
|
} catch {
|
|
151
328
|
spinner.fail("Could not reach the npm registry");
|
|
152
329
|
console.log(`
|
|
153
|
-
Installed: ${
|
|
330
|
+
Installed: ${chalk3.cyan(currentVersion)}
|
|
154
331
|
`);
|
|
155
332
|
return;
|
|
156
333
|
}
|
|
@@ -158,28 +335,29 @@ async function checkVersion(currentVersion) {
|
|
|
158
335
|
const [latMajor, latMinor, latPatch] = latestVersion.split(".").map(Number);
|
|
159
336
|
const isOutdated = latMajor > curMajor || latMajor === curMajor && latMinor > curMinor || latMajor === curMajor && latMinor === curMinor && latPatch > curPatch;
|
|
160
337
|
console.log(`
|
|
161
|
-
Installed ${
|
|
162
|
-
Latest ${isOutdated ?
|
|
338
|
+
Installed ${chalk3.cyan(currentVersion)}
|
|
339
|
+
Latest ${isOutdated ? chalk3.yellow(latestVersion) : chalk3.green(latestVersion)}
|
|
163
340
|
`);
|
|
164
341
|
if (isOutdated) {
|
|
165
342
|
console.log(
|
|
166
|
-
` ${
|
|
343
|
+
` ${chalk3.yellow("\u26A0")} A new version is available. To update an existing site, run:
|
|
167
344
|
|
|
168
|
-
${
|
|
345
|
+
${chalk3.cyan("npx camelmind@latest update")}
|
|
169
346
|
`
|
|
170
347
|
);
|
|
171
348
|
} else {
|
|
172
|
-
console.log(` ${
|
|
349
|
+
console.log(` ${chalk3.green("\u2713")} You're up to date.
|
|
173
350
|
`);
|
|
174
351
|
}
|
|
175
352
|
}
|
|
176
353
|
|
|
177
354
|
// src/index.ts
|
|
178
|
-
var
|
|
179
|
-
var pkgPath =
|
|
180
|
-
var pkg = JSON.parse(
|
|
355
|
+
var __dirname3 = path3.dirname(fileURLToPath3(import.meta.url));
|
|
356
|
+
var pkgPath = path3.join(__dirname3, "../package.json");
|
|
357
|
+
var pkg = JSON.parse(fs3.readFileSync(pkgPath, "utf-8"));
|
|
181
358
|
var program = new Command();
|
|
182
359
|
program.name("camelmind").description("CamelMind CLI \u2014 scaffold and manage documentation sites").version(pkg.version);
|
|
183
360
|
program.command("init [project-name]").description("Create a new CamelMind documentation site").option("--no-install", "Skip installing npm dependencies").action(init);
|
|
184
361
|
program.command("version").description("Show installed version and check for updates").action(() => checkVersion(pkg.version));
|
|
362
|
+
program.command("update [project-dir]").description("Update an existing CamelMind site to the latest platform files").option("--no-install", "Skip installing npm dependencies").option("--dry-run", "Show what would change without writing files").option("-y, --yes", "Skip the confirmation prompt").action(update);
|
|
185
363
|
program.parse();
|
package/package.json
CHANGED
package/template/_package.json
CHANGED