@object-ui/cli 17.5.0 → 17.6.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.
@@ -1,9 +1,9 @@
1
1
  // src/commands/serve.ts
2
- import { createServer } from "vite";
2
+ import { createServer, createLogger } from "vite";
3
3
  import react from "@vitejs/plugin-react";
4
- import { existsSync as existsSync3, mkdirSync as mkdirSync2 } from "fs";
5
- import { join as join3, resolve, relative } from "path";
6
- import chalk2 from "chalk";
4
+ import { mkdirSync as mkdirSync2 } from "fs";
5
+ import { join as join5 } from "path";
6
+ import chalk3 from "chalk";
7
7
  import { execSync } from "child_process";
8
8
 
9
9
  // src/utils/app-generator.ts
@@ -142,7 +142,7 @@ function buildRoutedAppDependencies() {
142
142
  react: REACT_RANGE,
143
143
  "react-dom": REACT_RANGE,
144
144
  "react-router-dom": "^7.18.2",
145
- "lucide-react": "^1.29.0",
145
+ "lucide-react": "^1.31.0",
146
146
  ...Object.fromEntries(PLATFORM_RUNTIME_PACKAGES.map((name) => [name, range]))
147
147
  };
148
148
  }
@@ -778,66 +778,304 @@ export default App;`;
778
778
  return files;
779
779
  }
780
780
 
781
- // src/commands/serve.ts
782
- async function serve(schemaPath, options) {
783
- const cwd = process.cwd();
784
- const pagesDir = join3(cwd, "pages");
785
- const hasPagesDir = existsSync3(pagesDir);
786
- let routes = [];
787
- let schema = null;
788
- let useFileSystemRouting = false;
789
- if (hasPagesDir) {
790
- console.log(chalk2.blue("\u{1F4C1} Detected pages/ directory - using file-system routing"));
791
- routes = scanPagesDirectory(pagesDir);
792
- useFileSystemRouting = true;
793
- if (routes.length === 0) {
794
- throw new Error("No schema files found in pages/ directory");
795
- }
796
- console.log(chalk2.green(`\u2713 Found ${routes.length} route(s)`));
797
- routes.forEach((route) => {
798
- console.log(chalk2.dim(` ${route.path} \u2192 ${relative(cwd, route.filePath)}`));
799
- });
800
- } else {
801
- const fullSchemaPath = resolve(cwd, schemaPath);
802
- if (!existsSync3(fullSchemaPath)) {
803
- throw new Error(`Schema file not found: ${schemaPath}
804
- Run 'objectui init' to create a sample schema.`);
781
+ // src/utils/project-source.ts
782
+ import { existsSync as existsSync3, statSync as statSync2 } from "fs";
783
+ import { basename, dirname as dirname3, join as join3, relative, resolve } from "path";
784
+ import chalk2 from "chalk";
785
+ function readAppConfig(path, warnings) {
786
+ try {
787
+ return parseSchemaFile(path);
788
+ } catch (error) {
789
+ warnings.push(
790
+ `Failed to parse app config ${path}: ${error instanceof Error ? error.message : error}`
791
+ );
792
+ return null;
793
+ }
794
+ }
795
+ function resolveProjectSource(cwd, schemaArg) {
796
+ const warnings = [];
797
+ const absoluteSchemaPath = resolve(cwd, schemaArg);
798
+ if (existsSync3(absoluteSchemaPath)) {
799
+ const argumentStats = statSync2(absoluteSchemaPath);
800
+ if (argumentStats.isFile()) {
801
+ const projectRoot = dirname3(absoluteSchemaPath);
802
+ const pagesDir = join3(projectRoot, "pages");
803
+ if (existsSync3(pagesDir)) {
804
+ return {
805
+ mode: "routes",
806
+ projectRoot,
807
+ pagesDir,
808
+ pagesDirOrigin: "schema-dir",
809
+ routes: scanRoutes(pagesDir),
810
+ appConfig: readAppConfig(absoluteSchemaPath, warnings),
811
+ appConfigPath: absoluteSchemaPath,
812
+ warnings
813
+ };
814
+ }
815
+ } else if (argumentStats.isDirectory()) {
816
+ const fromDirectory = resolveDirectoryArgument(absoluteSchemaPath, warnings);
817
+ if (fromDirectory) return fromDirectory;
805
818
  }
806
- console.log(chalk2.blue("\u{1F4CB} Loading schema:"), chalk2.cyan(schemaPath));
819
+ }
820
+ const localPagesDir = join3(cwd, "pages");
821
+ if (existsSync3(localPagesDir)) {
822
+ const localAppConfigPath = join3(cwd, "app.json");
823
+ const hasLocalAppConfig = existsSync3(localAppConfigPath);
824
+ return {
825
+ mode: "routes",
826
+ projectRoot: cwd,
827
+ pagesDir: localPagesDir,
828
+ pagesDirOrigin: "cwd",
829
+ routes: scanRoutes(localPagesDir),
830
+ appConfig: hasLocalAppConfig ? readAppConfig(localAppConfigPath, warnings) : null,
831
+ appConfigPath: hasLocalAppConfig ? localAppConfigPath : null,
832
+ warnings
833
+ };
834
+ }
835
+ if (!existsSync3(absoluteSchemaPath)) {
836
+ throw new Error(
837
+ `Schema file not found: ${schemaArg}
838
+ Run 'objectui init' to create a sample schema.`
839
+ );
840
+ }
841
+ if (statSync2(absoluteSchemaPath).isDirectory()) {
842
+ throw new Error(
843
+ `Not a project directory: ${schemaArg}
844
+ A directory argument must be a 'pages' directory, or contain one, for file-system routing \u2014 ${absoluteSchemaPath} is neither.
845
+ Pass a JSON/YAML schema file instead, or run 'objectui init' to create a project.`
846
+ );
847
+ }
848
+ let schema;
849
+ try {
850
+ schema = parseSchemaFile(absoluteSchemaPath);
851
+ } catch (error) {
852
+ throw new Error(`Invalid schema file: ${error instanceof Error ? error.message : error}`);
853
+ }
854
+ return {
855
+ mode: "schema",
856
+ projectRoot: dirname3(absoluteSchemaPath),
857
+ schemaFile: absoluteSchemaPath,
858
+ schema,
859
+ warnings
860
+ };
861
+ }
862
+ function resolveDirectoryArgument(argumentDir, warnings) {
863
+ const isPagesDir = basename(argumentDir) === "pages";
864
+ const pagesDir = isPagesDir ? argumentDir : join3(argumentDir, "pages");
865
+ if (!isPagesDir && !(existsSync3(pagesDir) && statSync2(pagesDir).isDirectory())) {
866
+ return null;
867
+ }
868
+ const projectRoot = isPagesDir ? dirname3(argumentDir) : argumentDir;
869
+ const appConfigPath = join3(projectRoot, "app.json");
870
+ const hasAppConfig = existsSync3(appConfigPath) && statSync2(appConfigPath).isFile();
871
+ return {
872
+ mode: "routes",
873
+ projectRoot,
874
+ pagesDir,
875
+ pagesDirOrigin: "argument-dir",
876
+ routes: scanRoutes(pagesDir),
877
+ appConfig: hasAppConfig ? readAppConfig(appConfigPath, warnings) : null,
878
+ appConfigPath: hasAppConfig ? appConfigPath : null,
879
+ warnings
880
+ };
881
+ }
882
+ function scanRoutes(pagesDir) {
883
+ const routes = scanPagesDirectory(pagesDir);
884
+ if (routes.length === 0) {
885
+ throw new Error(`No schema files found in ${pagesDir}`);
886
+ }
887
+ return routes;
888
+ }
889
+ function reportProjectSource(source, cwd) {
890
+ for (const warning of source.warnings) {
891
+ console.warn(chalk2.yellow(`\u26A0 ${warning}`));
892
+ }
893
+ if (source.mode === "schema") {
894
+ console.log(chalk2.blue("\u{1F4CB} Loading schema:"), chalk2.cyan(relative(cwd, source.schemaFile) || source.schemaFile));
895
+ return;
896
+ }
897
+ console.log(chalk2.blue(`\u{1F4C2} Detected project structure at ${source.projectRoot}`));
898
+ if (source.appConfigPath && source.appConfig) {
899
+ console.log(chalk2.blue(`\u2699\uFE0F Loaded App Config from ${relative(cwd, source.appConfigPath) || source.appConfigPath}`));
900
+ }
901
+ console.log(chalk2.blue(`\u{1F4C1} Using file-system routing from ${source.pagesDir}`));
902
+ console.log(chalk2.green(`\u2713 Found ${source.routes.length} route(s)`));
903
+ for (const route of source.routes) {
904
+ console.log(chalk2.dim(` ${route.path} \u2192 ${relative(cwd, route.filePath)}`));
905
+ }
906
+ }
907
+
908
+ // src/utils/workspace-vite.ts
909
+ import { existsSync as existsSync4, readFileSync as readFileSync3, statSync as statSync3, unlinkSync } from "fs";
910
+ import { createRequire } from "module";
911
+ import { dirname as dirname4, join as join4 } from "path";
912
+ import { globSync } from "glob";
913
+ import { load as loadYaml } from "js-yaml";
914
+ var PLATFORM_SCOPE = "@object-ui/";
915
+ var BARREL_EXTENSIONS = [".mjs", ".js", ".mts", ".ts", ".jsx", ".tsx"];
916
+ function isWorkspaceRoot(cwd) {
917
+ return existsSync4(join4(cwd, "pnpm-workspace.yaml"));
918
+ }
919
+ function workspacePatterns(cwd) {
920
+ const manifestPath = join4(cwd, "pnpm-workspace.yaml");
921
+ if (!existsSync4(manifestPath)) return [];
922
+ const parsed = loadYaml(readFileSync3(manifestPath, "utf-8"));
923
+ const patterns = parsed?.packages;
924
+ if (!Array.isArray(patterns)) return [];
925
+ return patterns.filter((p) => typeof p === "string");
926
+ }
927
+ function workspacePackageDirs(cwd) {
928
+ const patterns = workspacePatterns(cwd);
929
+ const include = patterns.filter((p) => !p.startsWith("!"));
930
+ const exclude = patterns.filter((p) => p.startsWith("!")).map((p) => p.slice(1));
931
+ if (include.length === 0) return [];
932
+ const matches = globSync(include, {
933
+ cwd,
934
+ absolute: true,
935
+ ignore: ["**/node_modules/**", ...exclude]
936
+ });
937
+ return matches.filter((dir) => existsSync4(join4(dir, "package.json")) && statSync3(dir).isDirectory()).sort();
938
+ }
939
+ function findSourceBarrel(srcDir) {
940
+ for (const ext of BARREL_EXTENSIONS) {
941
+ const candidate = join4(srcDir, `index${ext}`);
942
+ if (existsSync4(candidate)) return candidate;
943
+ }
944
+ return void 0;
945
+ }
946
+ function workspaceSourceAliases(cwd) {
947
+ const aliases = {};
948
+ for (const dir of workspacePackageDirs(cwd)) {
949
+ let name;
807
950
  try {
808
- schema = parseSchemaFile(fullSchemaPath);
809
- } catch (error) {
810
- throw new Error(`Invalid schema file: ${error instanceof Error ? error.message : error}`);
951
+ name = JSON.parse(readFileSync3(join4(dir, "package.json"), "utf-8")).name;
952
+ } catch {
953
+ continue;
811
954
  }
955
+ if (typeof name !== "string" || !name.startsWith(PLATFORM_SCOPE)) continue;
956
+ const srcDir = join4(dir, "src");
957
+ if (!existsSync4(srcDir) || !findSourceBarrel(srcDir)) continue;
958
+ aliases[name] = srcDir;
959
+ }
960
+ return aliases;
961
+ }
962
+ function resolveLucideAlias(cwd) {
963
+ const require2 = createRequire(join4(cwd, "package.json"));
964
+ try {
965
+ return dirname4(require2.resolve("lucide-react/package.json", { paths: [join4(cwd, "packages/components")] }));
966
+ } catch {
967
+ return void 0;
968
+ }
969
+ }
970
+ async function loadTempAppPostcssPlugins() {
971
+ try {
972
+ const [tailwindPostcss, autoprefixer] = await Promise.all([
973
+ import("@tailwindcss/postcss"),
974
+ import("autoprefixer")
975
+ ]);
976
+ return [tailwindPostcss.default(), autoprefixer.default()];
977
+ } catch (error) {
978
+ throw new Error(
979
+ `Failed to load the Tailwind CSS PostCSS pipeline: ${error instanceof Error ? error.message : error}
980
+ Both '@tailwindcss/postcss' and 'autoprefixer' are dependencies of @object-ui/cli \u2014 a
981
+ broken install of the CLI is the likeliest cause; reinstall it and try again.
982
+ (Refusing to start unstyled: that failure is silent in the browser.)`
983
+ );
984
+ }
985
+ }
986
+ async function prepareWorkspaceTempApp(cwd, tmpDir) {
987
+ const postcssPath = join4(tmpDir, "postcss.config.js");
988
+ if (existsSync4(postcssPath)) {
989
+ unlinkSync(postcssPath);
990
+ }
991
+ const alias = { ...workspaceSourceAliases(cwd) };
992
+ const lucide = resolveLucideAlias(cwd);
993
+ if (lucide) {
994
+ alias["lucide-react"] = lucide;
812
995
  }
813
- const tmpDir = join3(cwd, ".objectui-tmp");
996
+ return {
997
+ resolve: { alias },
998
+ css: { postcss: { plugins: await loadTempAppPostcssPlugins() } }
999
+ };
1000
+ }
1001
+
1002
+ // src/commands/serve.ts
1003
+ function resolveServeOpenOption(open) {
1004
+ return open !== false;
1005
+ }
1006
+ var BROWSER_OPEN_SPAWN_ENOENT = /^Error: spawn (\S+) ENOENT/;
1007
+ function createServeLogger(base) {
1008
+ return {
1009
+ info: (msg, opts) => base.info(msg, opts),
1010
+ warn: (msg, opts) => base.warn(msg, opts),
1011
+ warnOnce: (msg, opts) => base.warnOnce(msg, opts),
1012
+ error(msg, opts) {
1013
+ const match = BROWSER_OPEN_SPAWN_ENOENT.exec(msg);
1014
+ if (match) {
1015
+ const [, command] = match;
1016
+ console.log(
1017
+ chalk3.dim(
1018
+ ` (could not open the browser automatically \u2014 '${command}' is not available in this environment; open the URL above manually)`
1019
+ )
1020
+ );
1021
+ return;
1022
+ }
1023
+ base.error(msg, opts);
1024
+ },
1025
+ clearScreen: (type) => base.clearScreen(type),
1026
+ hasErrorLogged: (error) => base.hasErrorLogged(error),
1027
+ get hasWarned() {
1028
+ return base.hasWarned;
1029
+ }
1030
+ };
1031
+ }
1032
+ async function serve(schemaPath, options) {
1033
+ const cwd = process.cwd();
1034
+ const source = resolveProjectSource(cwd, schemaPath);
1035
+ reportProjectSource(source, cwd);
1036
+ const tmpDir = join5(cwd, ".objectui-tmp");
814
1037
  mkdirSync2(tmpDir, { recursive: true });
815
- if (useFileSystemRouting) {
816
- createTempAppWithRouting(tmpDir, routes);
1038
+ if (source.mode === "routes") {
1039
+ createTempAppWithRouting(tmpDir, source.routes, source.appConfig);
817
1040
  } else {
818
- createTempApp(tmpDir, schema);
1041
+ createTempApp(tmpDir, source.schema);
819
1042
  }
820
- console.log(chalk2.blue("\u{1F4E6} Installing dependencies..."));
821
- console.log(chalk2.dim(" This may take a moment on first run..."));
822
- try {
823
- execSync("npm install --silent --prefer-offline", {
824
- cwd: tmpDir,
825
- stdio: "inherit"
826
- });
827
- console.log(chalk2.green("\u2713 Dependencies installed"));
828
- } catch {
829
- throw new Error("Failed to install dependencies. Please check your internet connection and try again.");
1043
+ const isMonorepo = isWorkspaceRoot(cwd);
1044
+ if (isMonorepo) {
1045
+ console.log(chalk3.blue("\u{1F4E6} Detected monorepo - using root node_modules"));
1046
+ } else {
1047
+ console.log(chalk3.blue("\u{1F4E6} Installing dependencies..."));
1048
+ console.log(chalk3.dim(" This may take a moment on first run..."));
1049
+ try {
1050
+ execSync("npm install --silent --prefer-offline", {
1051
+ cwd: tmpDir,
1052
+ stdio: "inherit"
1053
+ });
1054
+ console.log(chalk3.green("\u2713 Dependencies installed"));
1055
+ } catch {
1056
+ throw new Error("Failed to install dependencies. Please check your internet connection and try again.");
1057
+ }
1058
+ }
1059
+ console.log(chalk3.green("\u2713 Schema loaded successfully"));
1060
+ console.log(chalk3.blue("\u{1F680} Starting development server...\n"));
1061
+ if (isMonorepo) {
1062
+ console.log(chalk3.blue("\u{1F4E6} Detected monorepo - configuring workspace aliases"));
830
1063
  }
831
- console.log(chalk2.green("\u2713 Schema loaded successfully"));
832
- console.log(chalk2.blue("\u{1F680} Starting development server...\n"));
1064
+ const workspaceConfig = isMonorepo ? await prepareWorkspaceTempApp(cwd, tmpDir) : {};
833
1065
  const viteConfig = {
834
1066
  root: tmpDir,
835
1067
  server: {
836
1068
  port: parseInt(options.port),
837
1069
  host: options.host,
838
- open: true
1070
+ open: resolveServeOpenOption(options.open),
1071
+ fs: {
1072
+ // Allow serving the workspace sources the aliases point at
1073
+ allow: [cwd]
1074
+ }
839
1075
  },
840
- plugins: [react()]
1076
+ plugins: [react()],
1077
+ customLogger: createServeLogger(createLogger()),
1078
+ ...workspaceConfig
841
1079
  };
842
1080
  const server = await createServer(viteConfig);
843
1081
  await server.listen();
@@ -845,18 +1083,18 @@ Run 'objectui init' to create a sample schema.`);
845
1083
  const protocol = server.config.server.https ? "https" : "http";
846
1084
  const displayHost = host === "0.0.0.0" ? "localhost" : host;
847
1085
  console.log();
848
- console.log(chalk2.green("\u2713 Server started successfully!"));
1086
+ console.log(chalk3.green("\u2713 Server started successfully!"));
849
1087
  console.log();
850
- console.log(chalk2.bold(" Local: ") + chalk2.cyan(`${protocol}://${displayHost}:${port}`));
1088
+ console.log(chalk3.bold(" Local: ") + chalk3.cyan(`${protocol}://${displayHost}:${port}`));
851
1089
  console.log();
852
- console.log(chalk2.dim(" Press Ctrl+C to stop the server"));
1090
+ console.log(chalk3.dim(" Press Ctrl+C to stop the server"));
853
1091
  console.log();
854
1092
  }
855
1093
 
856
1094
  // src/commands/init.ts
857
- import { existsSync as existsSync4, writeFileSync as writeFileSync2, mkdirSync as mkdirSync3 } from "fs";
858
- import { dirname as dirname3, join as join4 } from "path";
859
- import chalk3 from "chalk";
1095
+ import { existsSync as existsSync5, writeFileSync as writeFileSync2, mkdirSync as mkdirSync3 } from "fs";
1096
+ import { dirname as dirname5, join as join6 } from "path";
1097
+ import chalk4 from "chalk";
860
1098
  var templates = {
861
1099
  simple: {
862
1100
  type: "div",
@@ -1370,46 +1608,48 @@ export default function App() {
1370
1608
  }
1371
1609
  async function init(name, options) {
1372
1610
  const cwd = process.cwd();
1373
- const projectDir = join4(cwd, name);
1374
- if (existsSync4(projectDir) && name !== ".") {
1611
+ const projectDir = join6(cwd, name);
1612
+ if (existsSync5(projectDir) && name !== ".") {
1375
1613
  throw new Error(`Directory "${name}" already exists. Please choose a different name.`);
1376
1614
  }
1377
1615
  const targetDir = name === "." ? cwd : projectDir;
1378
1616
  if (name !== ".") {
1379
1617
  mkdirSync3(projectDir, { recursive: true });
1380
1618
  }
1381
- console.log(chalk3.blue("\u{1F3A8} Creating Object UI application..."));
1382
- console.log(chalk3.dim(` Template: ${options.template}`));
1619
+ console.log(chalk4.blue("\u{1F3A8} Creating Object UI application..."));
1620
+ console.log(chalk4.dim(` Template: ${options.template}`));
1383
1621
  console.log();
1384
1622
  for (const [relativePath, contents] of Object.entries(
1385
1623
  buildInitFiles(name, options.template)
1386
1624
  )) {
1387
- const target = join4(targetDir, relativePath);
1388
- mkdirSync3(dirname3(target), { recursive: true });
1625
+ const target = join6(targetDir, relativePath);
1626
+ mkdirSync3(dirname5(target), { recursive: true });
1389
1627
  writeFileSync2(target, contents);
1390
- console.log(chalk3.green(`\u2713 Created ${relativePath}`));
1628
+ console.log(chalk4.green(`\u2713 Created ${relativePath}`));
1391
1629
  }
1392
1630
  console.log();
1393
- console.log(chalk3.green("\u2728 Application created successfully!"));
1631
+ console.log(chalk4.green("\u2728 Application created successfully!"));
1394
1632
  console.log();
1395
- console.log(chalk3.bold("Next steps:"));
1633
+ console.log(chalk4.bold("Next steps:"));
1396
1634
  console.log();
1397
1635
  if (name !== ".") {
1398
- console.log(chalk3.cyan(` cd ${name}`));
1636
+ console.log(chalk4.cyan(` cd ${name}`));
1399
1637
  }
1400
- console.log(chalk3.cyan(" npm install"));
1401
- console.log(chalk3.cyan(" npm run dev"));
1638
+ console.log(chalk4.cyan(" npm install"));
1639
+ console.log(chalk4.cyan(" npm run dev"));
1402
1640
  console.log();
1403
- console.log(chalk3.dim(" The development server will start on http://localhost:3000"));
1641
+ console.log(chalk4.dim(" The development server will start on http://localhost:3000"));
1404
1642
  console.log();
1405
1643
  }
1406
1644
 
1407
1645
  export {
1408
- parseSchemaFile,
1409
- scanPagesDirectory,
1410
1646
  createTempApp,
1411
1647
  createTempAppWithRouting,
1648
+ resolveProjectSource,
1649
+ reportProjectSource,
1650
+ isWorkspaceRoot,
1651
+ prepareWorkspaceTempApp,
1412
1652
  serve,
1413
1653
  init
1414
1654
  };
1415
- //# sourceMappingURL=chunk-2MZA766D.js.map
1655
+ //# sourceMappingURL=chunk-AP2INOE7.js.map