@ubean/cli 0.6.2 → 0.6.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.
Files changed (4) hide show
  1. package/README.md +676 -0
  2. package/README.zh-CN.md +635 -0
  3. package/dist/cli.js +13 -142
  4. package/package.json +14 -14
package/dist/cli.js CHANGED
@@ -3,7 +3,7 @@ import { existsSync, mkdirSync, readFileSync } from "node:fs";
3
3
  import { basename, join, relative, resolve } from "pathe";
4
4
  import { getLogger, setDebugLogging, setMinLevel } from "@ubean/shared/logger";
5
5
  import { defineCommand, runMain } from "citty";
6
- import { BUILTIN_MODULES, isBuiltinDisabled, loadUbeanConfig, resolveModules, resolvePrerenderConfig, resolveSsrConfig } from "@ubean/config";
6
+ import { checkProjectDependencies, loadUbeanConfig, resolveModules, resolvePrerenderConfig, resolveSsrConfig } from "@ubean/config";
7
7
  import { readFile, rm } from "node:fs/promises";
8
8
  import { generateOpenApiTypesFromServer, generateTypes } from "@ubean/build/codegen";
9
9
  import { buildWithEnvironments } from "@ubean/build/production";
@@ -15,7 +15,6 @@ import { DEVTOOLS_PASS_THROUGH_PREFIXES, createCloudflarePreviewRunner, createVi
15
15
  import { ubeanVite } from "@ubean/build/vue";
16
16
  import { ubeanIslandsPlugin } from "@ubean/islands/vite";
17
17
  import { findAvailablePort, findUserViteConfig, getLanAddresses, isLoopbackHost, isWildcardHost } from "@ubean/shared/node";
18
- import { execSync } from "node:child_process";
19
18
  import { createServer as createServer$1 } from "node:http";
20
19
  //#region src/shared/exit.ts
21
20
  /**
@@ -1414,147 +1413,10 @@ async function ensureBuildDir(cwd, buildDir) {
1414
1413
  const fullPath = join(cwd, buildDir);
1415
1414
  if (!existsSync(fullPath)) mkdirSync(fullPath, { recursive: true });
1416
1415
  }
1417
- /**
1418
- * Detects the package manager used in the project by inspecting lockfiles.
1419
- * Priority: pnpm > yarn > bun > npm (npm as default fallback).
1420
- *
1421
- * 导出供单测复用(OPT-04 4c)。
1422
- */
1423
- function detectPackageManager(cwd) {
1424
- if (existsSync(join(cwd, "pnpm-lock.yaml"))) return "pnpm";
1425
- if (existsSync(join(cwd, "yarn.lock"))) return "yarn";
1426
- if (existsSync(join(cwd, "bun.lockb")) || existsSync(join(cwd, "bun.lock"))) return "bun";
1427
- return "npm";
1428
- }
1429
- /**
1430
- * Builds the install command args for a given package manager and package list.
1431
- * Examples:
1432
- * pnpm → ['add', '@ubean/integrations@^0.1.3']
1433
- * npm → ['install', '@ubean/integrations@^0.1.3']
1434
- *
1435
- * 导出供单测复用(OPT-04 4c)。
1436
- */
1437
- function buildInstallCommand(pm, packages) {
1438
- switch (pm) {
1439
- case "pnpm": return {
1440
- cmd: "pnpm",
1441
- args: ["add", ...packages]
1442
- };
1443
- case "yarn": return {
1444
- cmd: "yarn",
1445
- args: ["add", ...packages]
1446
- };
1447
- case "bun": return {
1448
- cmd: "bun",
1449
- args: ["add", ...packages]
1450
- };
1451
- default: return {
1452
- cmd: "npm",
1453
- args: ["install", ...packages]
1454
- };
1455
- }
1456
- }
1457
- /**
1458
- * Extracts the bare package name from a module path.
1459
- * '@ubean/integrations/pwa' → '@ubean/integrations'
1460
- * '@ubean/icon/vite' → '@ubean/icon'
1461
- *
1462
- * 导出供单测复用(OPT-04 4c)。
1463
- */
1464
- function extractPackageName(modulePath) {
1465
- if (modulePath.startsWith("@")) return modulePath.split("/").slice(0, 2).join("/");
1466
- return modulePath.split("/")[0];
1467
- }
1468
- /**
1469
- * Reads the `ubean` package version from the project's package.json so we can
1470
- * install matching versions of `@ubean/*` extension packages.
1471
- * Returns `null` if ubean isn't declared or version can't be parsed.
1472
- *
1473
- * 导出供单测复用(OPT-04 4c)。
1474
- */
1475
- function getUbeanVersion(cwd) {
1476
- try {
1477
- const pkgPath = join(cwd, "package.json");
1478
- if (!existsSync(pkgPath)) return null;
1479
- const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
1480
- const spec = pkg.dependencies?.ubean || pkg.devDependencies?.ubean;
1481
- if (!spec) return null;
1482
- const match = spec.match(/\d+\.\d+\.\d+/);
1483
- return match ? match[0] : null;
1484
- } catch {
1485
- return null;
1486
- }
1487
- }
1488
- /**
1489
- * Probes whether a module is importable (i.e., installed in node_modules).
1490
- * Uses dynamic import — same mechanism as `loadBuiltinModule` so detection
1491
- * behavior matches what the runtime will actually encounter.
1492
- */
1493
- async function isModuleInstalled(modulePath) {
1494
- try {
1495
- await import(
1496
- /* @vite-ignore */
1497
- modulePath
1498
- );
1499
- return true;
1500
- } catch {
1501
- return false;
1502
- }
1503
- }
1504
- /**
1505
- * Detects built-in modules enabled in config but not installed, and
1506
- * auto-installs them using the project's package manager.
1507
- *
1508
- * Behavior:
1509
- * - When `autoInstall` is `false`, only prints warnings with install commands.
1510
- * - When `autoInstall` is `true` and a package.json exists, runs the install.
1511
- * - Version pinning: installs `@ubean/<pkg>@^<ubean-version>` to keep in sync.
1512
- * - Failures fall back to warnings (non-fatal — prepare should still proceed).
1513
- */
1514
- async function ensureBuiltinModules(cwd, config, autoInstall) {
1515
- const missing = [];
1516
- for (const builtin of BUILTIN_MODULES) {
1517
- const configValue = config[builtin.key];
1518
- if (isBuiltinDisabled(configValue)) continue;
1519
- const packageName = extractPackageName(builtin.modulePath);
1520
- if (!await isModuleInstalled(builtin.modulePath)) missing.push({
1521
- key: builtin.key,
1522
- packageName
1523
- });
1524
- }
1525
- if (missing.length === 0) return;
1526
- const pm = detectPackageManager(cwd);
1527
- const ubeanVersion = getUbeanVersion(cwd);
1528
- const packagesToInstall = missing.map((m) => ubeanVersion ? `${m.packageName}@^${ubeanVersion}` : m.packageName);
1529
- if (!autoInstall || !existsSync(join(cwd, "package.json"))) {
1530
- for (const m of missing) {
1531
- const versionSuffix = ubeanVersion ? `@^${ubeanVersion}` : "";
1532
- logger$2.warn(`Built-in module "${m.key}" is enabled but \`${m.packageName}\` is not installed. Run: ${pm} add ${m.packageName}${versionSuffix}`);
1533
- }
1534
- return;
1535
- }
1536
- logger$2.info(`Auto-installing missing built-in module packages: ${packagesToInstall.join(", ")}`);
1537
- logger$2.info(`Using package manager: ${pm}`);
1538
- const { cmd, args } = buildInstallCommand(pm, packagesToInstall);
1539
- try {
1540
- execSync([cmd, ...args].join(" "), {
1541
- cwd,
1542
- stdio: "inherit",
1543
- env: { ...process.env }
1544
- });
1545
- logger$2.info(`Installed: ${packagesToInstall.join(", ")}`);
1546
- } catch (err) {
1547
- logger$2.error(`Failed to auto-install packages: ${err instanceof Error ? err.message : String(err)}`);
1548
- for (const m of missing) {
1549
- const versionSuffix = ubeanVersion ? `@^${ubeanVersion}` : "";
1550
- logger$2.warn(`Please install manually: ${pm} add ${m.packageName}${versionSuffix}`);
1551
- }
1552
- }
1553
- }
1554
1416
  const prepareCommand = {
1555
1417
  meta: {
1556
1418
  name: "prepare",
1557
- description: "Generate type definitions and prepare the project (runs automatically before dev/build)"
1419
+ description: "Generate type definitions and check project dependencies"
1558
1420
  },
1559
1421
  args: {
1560
1422
  cwd: {
@@ -1564,7 +1426,7 @@ const prepareCommand = {
1564
1426
  },
1565
1427
  install: {
1566
1428
  type: "boolean",
1567
- description: "Auto-install missing built-in module packages (use --no-install to skip)",
1429
+ description: "Prompt to install missing project dependencies (use --no-install to only warn)",
1568
1430
  default: true
1569
1431
  }
1570
1432
  },
@@ -1572,7 +1434,16 @@ const prepareCommand = {
1572
1434
  const cwd = resolve(args.cwd || process.cwd());
1573
1435
  logger$2.info(`Preparing ubean project at ${cwd}...`);
1574
1436
  const config = await loadUbeanConfig(cwd);
1575
- await ensureBuiltinModules(cwd, config, args.install !== false);
1437
+ await checkProjectDependencies({
1438
+ cwd,
1439
+ config,
1440
+ srcDir: config.srcDir,
1441
+ mode: args.install !== false ? "prompt" : "warn",
1442
+ logger: {
1443
+ info: (message) => logger$2.info(message),
1444
+ warn: (message) => logger$2.warn(message)
1445
+ }
1446
+ });
1576
1447
  const typesDir = ".ubean";
1577
1448
  await ensureBuildDir(cwd, typesDir);
1578
1449
  logger$2.info("Scanning project files...");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ubean/cli",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "description": "CLI for ubean (ubean-next binary: dev, build, prepare, init, preview, page, env, config, devtools, api/layout/middleware/cron/plugin scaffolds) plus the Vite dev server runner",
5
5
  "bin": {
6
6
  "ubean-next": "./bin/ubean-next.mjs"
@@ -24,29 +24,29 @@
24
24
  }
25
25
  },
26
26
  "dependencies": {
27
- "@ubean/build": "0.6.2",
28
- "@ubean/config": "0.6.2",
29
- "@ubean/i18n": "0.6.2",
30
- "@ubean/islands": "0.6.2",
31
- "@ubean/preset": "0.6.2",
32
- "@ubean/scan": "0.6.2",
33
- "@ubean/shared": "0.6.2",
27
+ "@ubean/build": "0.6.3",
28
+ "@ubean/config": "0.6.3",
29
+ "@ubean/i18n": "0.6.3",
30
+ "@ubean/islands": "0.6.3",
31
+ "@ubean/preset": "0.6.3",
32
+ "@ubean/scan": "0.6.3",
33
+ "@ubean/shared": "0.6.3",
34
34
  "citty": "^0.2.2",
35
35
  "kolorist": "^1.8.0",
36
36
  "pathe": "^2.0.3"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/node": "^26.6.5",
40
- "env-runner": "0.3.3",
40
+ "env-runner": "0.3.4",
41
41
  "typescript": "npm:typescript-native-bridge@latest",
42
- "vite": "npm:@voidzero-dev/vite-plus-core@1.1.0",
43
- "vite-plus": "1.1.0"
42
+ "vite": "npm:@voidzero-dev/vite-plus-core@1.3.0",
43
+ "vite-plus": "1.3.0"
44
44
  },
45
45
  "peerDependencies": {
46
- "@ubean/content": "0.6.2",
47
- "@ubean/devtools": "0.6.2",
46
+ "@ubean/content": "0.6.3",
47
+ "@ubean/devtools": "0.6.3",
48
48
  "@vitejs/plugin-vue": "^6.0.8",
49
- "vite": "npm:@voidzero-dev/vite-plus-core@1.1.0"
49
+ "vite": "npm:@voidzero-dev/vite-plus-core@1.3.0"
50
50
  },
51
51
  "peerDependenciesMeta": {
52
52
  "@ubean/content": {