@object-ui/cli 17.5.0 → 17.7.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/CHANGELOG.md +2376 -0
- package/README.md +15 -24
- package/dist/{chunk-2MZA766D.js → chunk-VMMIGYU3.js} +390 -151
- package/dist/chunk-VMMIGYU3.js.map +1 -0
- package/dist/cli.js +1161 -582
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -1
- package/package.json +9 -7
- package/dist/chunk-2MZA766D.js.map +0 -1
|
@@ -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 {
|
|
5
|
-
import { join as
|
|
6
|
-
import
|
|
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.
|
|
145
|
+
"lucide-react": "^1.43.0",
|
|
146
146
|
...Object.fromEntries(PLATFORM_RUNTIME_PACKAGES.map((name) => [name, range]))
|
|
147
147
|
};
|
|
148
148
|
}
|
|
@@ -536,10 +536,9 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
|
536
536
|
let layoutWrapperEnd = "";
|
|
537
537
|
if (appConfig) {
|
|
538
538
|
const layoutCode = `
|
|
539
|
-
import type {
|
|
539
|
+
import type { ReactNode } from 'react';
|
|
540
540
|
import { Link, useLocation } from 'react-router-dom';
|
|
541
|
-
import
|
|
542
|
-
import { Moon, Sun } from "lucide-react"
|
|
541
|
+
import { ChevronsUpDown, Monitor, Moon, Sun } from "lucide-react"
|
|
543
542
|
import { useTheme } from "./theme-provider"
|
|
544
543
|
import {
|
|
545
544
|
DropdownMenu,
|
|
@@ -564,7 +563,9 @@ import {
|
|
|
564
563
|
Separator,
|
|
565
564
|
Collapsible,
|
|
566
565
|
CollapsibleTrigger,
|
|
567
|
-
CollapsibleContent
|
|
566
|
+
CollapsibleContent,
|
|
567
|
+
LazyIcon,
|
|
568
|
+
isLucideIconName
|
|
568
569
|
} from '@object-ui/components';
|
|
569
570
|
|
|
570
571
|
/** One entry of \`app.json\`'s \`menu\`, as this layout reads it. */
|
|
@@ -582,21 +583,20 @@ type AppConfig = {
|
|
|
582
583
|
menu?: MenuItem[];
|
|
583
584
|
};
|
|
584
585
|
|
|
585
|
-
//
|
|
586
|
-
//
|
|
587
|
-
//
|
|
588
|
-
//
|
|
589
|
-
//
|
|
590
|
-
//
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
586
|
+
// An authored \`icon\` name is resolved by the platform seam
|
|
587
|
+
// (\`@object-ui/components\`), never by a lookup this template rolls itself.
|
|
588
|
+
// That is objectui#5935's ruling \u2014 one tokeniser and one icon-name vocabulary
|
|
589
|
+
// for every container \u2014 and this generated layout is a container like any
|
|
590
|
+
// other, even though it runs in the user's app rather than in this repo.
|
|
591
|
+
//
|
|
592
|
+
// \`isLucideIconName\` is asked FIRST because this call site has a better
|
|
593
|
+
// fallback than the seam's: a sidebar entry with an unresolvable icon renders
|
|
594
|
+
// no glyph at all, where \`LazyIcon\` alone would substitute a stray database
|
|
595
|
+
// icon. The seam exports the predicate for exactly this ("ask first, then
|
|
596
|
+
// choose"), so preferring it costs no second vocabulary.
|
|
596
597
|
const DynamicIcon = ({ name, className }: { name: string; className?: string }) => {
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
return <Icon className={className} />;
|
|
598
|
+
if (!isLucideIconName(name)) return null;
|
|
599
|
+
return <LazyIcon name={name} className={className} />;
|
|
600
600
|
};
|
|
601
601
|
|
|
602
602
|
export function ModeToggle() {
|
|
@@ -614,20 +614,20 @@ export function ModeToggle() {
|
|
|
614
614
|
<span className="truncate font-semibold">Switch Theme</span>
|
|
615
615
|
<span className="truncate text-xs">Light / Dark</span>
|
|
616
616
|
</div>
|
|
617
|
-
<
|
|
617
|
+
<ChevronsUpDown className="ml-auto size-4" />
|
|
618
618
|
</SidebarMenuButton>
|
|
619
619
|
</DropdownMenuTrigger>
|
|
620
620
|
<DropdownMenuContent className="w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg" side="bottom" align="end" sideOffset={4}>
|
|
621
621
|
<DropdownMenuItem onClick={() => setTheme("light")}>
|
|
622
|
-
<
|
|
622
|
+
<Sun className="mr-2 size-4" />
|
|
623
623
|
Light
|
|
624
624
|
</DropdownMenuItem>
|
|
625
625
|
<DropdownMenuItem onClick={() => setTheme("dark")}>
|
|
626
|
-
<
|
|
626
|
+
<Moon className="mr-2 size-4" />
|
|
627
627
|
Dark
|
|
628
628
|
</DropdownMenuItem>
|
|
629
629
|
<DropdownMenuItem onClick={() => setTheme("system")}>
|
|
630
|
-
<
|
|
630
|
+
<Monitor className="mr-2 size-4" />
|
|
631
631
|
System
|
|
632
632
|
</DropdownMenuItem>
|
|
633
633
|
</DropdownMenuContent>
|
|
@@ -778,66 +778,304 @@ export default App;`;
|
|
|
778
778
|
return files;
|
|
779
779
|
}
|
|
780
780
|
|
|
781
|
-
// src/
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
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
|
-
|
|
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
|
-
|
|
809
|
-
} catch
|
|
810
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
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
|
-
|
|
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:
|
|
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,31 +1083,31 @@ 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(
|
|
1086
|
+
console.log(chalk3.green("\u2713 Server started successfully!"));
|
|
849
1087
|
console.log();
|
|
850
|
-
console.log(
|
|
1088
|
+
console.log(chalk3.bold(" Local: ") + chalk3.cyan(`${protocol}://${displayHost}:${port}`));
|
|
851
1089
|
console.log();
|
|
852
|
-
console.log(
|
|
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
|
|
858
|
-
import { dirname as
|
|
859
|
-
import
|
|
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",
|
|
863
1101
|
className: "min-h-screen flex items-center justify-center bg-gradient-to-br from-blue-50 to-indigo-100",
|
|
864
|
-
|
|
1102
|
+
children: {
|
|
865
1103
|
type: "card",
|
|
866
1104
|
className: "w-full max-w-md shadow-lg",
|
|
867
1105
|
title: "Welcome to Object UI",
|
|
868
1106
|
description: "Start building your application with JSON schemas",
|
|
869
|
-
|
|
1107
|
+
children: {
|
|
870
1108
|
type: "div",
|
|
871
1109
|
className: "p-6 space-y-4",
|
|
872
|
-
|
|
1110
|
+
children: [
|
|
873
1111
|
{
|
|
874
1112
|
type: "text",
|
|
875
1113
|
content: "This is a simple example. Edit app.json to customize your application.",
|
|
@@ -887,19 +1125,19 @@ var templates = {
|
|
|
887
1125
|
form: {
|
|
888
1126
|
type: "div",
|
|
889
1127
|
className: "min-h-screen flex items-center justify-center bg-gradient-to-br from-purple-50 to-pink-100 p-4",
|
|
890
|
-
|
|
1128
|
+
children: {
|
|
891
1129
|
type: "card",
|
|
892
1130
|
className: "w-full max-w-2xl shadow-xl",
|
|
893
1131
|
title: "Contact Form",
|
|
894
1132
|
description: "Fill out the form below to get in touch",
|
|
895
|
-
|
|
1133
|
+
children: {
|
|
896
1134
|
type: "div",
|
|
897
1135
|
className: "p-6 space-y-6",
|
|
898
|
-
|
|
1136
|
+
children: [
|
|
899
1137
|
{
|
|
900
1138
|
type: "div",
|
|
901
1139
|
className: "grid grid-cols-2 gap-4",
|
|
902
|
-
|
|
1140
|
+
children: [
|
|
903
1141
|
{
|
|
904
1142
|
type: "input",
|
|
905
1143
|
label: "First Name",
|
|
@@ -936,7 +1174,7 @@ var templates = {
|
|
|
936
1174
|
{
|
|
937
1175
|
type: "div",
|
|
938
1176
|
className: "flex gap-3",
|
|
939
|
-
|
|
1177
|
+
children: [
|
|
940
1178
|
{
|
|
941
1179
|
type: "button",
|
|
942
1180
|
label: "Submit",
|
|
@@ -957,21 +1195,21 @@ var templates = {
|
|
|
957
1195
|
dashboard: {
|
|
958
1196
|
type: "div",
|
|
959
1197
|
className: "min-h-screen bg-muted/10",
|
|
960
|
-
|
|
1198
|
+
children: [
|
|
961
1199
|
{
|
|
962
1200
|
type: "div",
|
|
963
1201
|
className: "border-b bg-background",
|
|
964
|
-
|
|
1202
|
+
children: {
|
|
965
1203
|
type: "div",
|
|
966
1204
|
className: "container mx-auto px-6 py-4",
|
|
967
|
-
|
|
1205
|
+
children: {
|
|
968
1206
|
type: "div",
|
|
969
1207
|
className: "flex items-center justify-between",
|
|
970
|
-
|
|
1208
|
+
children: [
|
|
971
1209
|
{
|
|
972
1210
|
type: "div",
|
|
973
1211
|
className: "text-2xl font-bold",
|
|
974
|
-
|
|
1212
|
+
children: { type: "text", content: "Dashboard" }
|
|
975
1213
|
},
|
|
976
1214
|
{
|
|
977
1215
|
type: "button",
|
|
@@ -985,37 +1223,37 @@ var templates = {
|
|
|
985
1223
|
{
|
|
986
1224
|
type: "div",
|
|
987
1225
|
className: "container mx-auto p-6 space-y-6",
|
|
988
|
-
|
|
1226
|
+
children: [
|
|
989
1227
|
{
|
|
990
1228
|
type: "div",
|
|
991
1229
|
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-4",
|
|
992
|
-
|
|
1230
|
+
children: [
|
|
993
1231
|
{
|
|
994
1232
|
type: "card",
|
|
995
1233
|
className: "shadow-sm",
|
|
996
|
-
|
|
1234
|
+
children: [
|
|
997
1235
|
{
|
|
998
1236
|
type: "div",
|
|
999
1237
|
className: "p-6 pb-2",
|
|
1000
|
-
|
|
1238
|
+
children: {
|
|
1001
1239
|
type: "div",
|
|
1002
1240
|
className: "text-sm font-medium text-muted-foreground",
|
|
1003
|
-
|
|
1241
|
+
children: { type: "text", content: "Total Revenue" }
|
|
1004
1242
|
}
|
|
1005
1243
|
},
|
|
1006
1244
|
{
|
|
1007
1245
|
type: "div",
|
|
1008
1246
|
className: "p-6 pt-0",
|
|
1009
|
-
|
|
1247
|
+
children: [
|
|
1010
1248
|
{
|
|
1011
1249
|
type: "div",
|
|
1012
1250
|
className: "text-2xl font-bold",
|
|
1013
|
-
|
|
1251
|
+
children: { type: "text", content: "$45,231.89" }
|
|
1014
1252
|
},
|
|
1015
1253
|
{
|
|
1016
1254
|
type: "div",
|
|
1017
1255
|
className: "text-xs text-muted-foreground mt-1",
|
|
1018
|
-
|
|
1256
|
+
children: { type: "text", content: "+20.1% from last month" }
|
|
1019
1257
|
}
|
|
1020
1258
|
]
|
|
1021
1259
|
}
|
|
@@ -1024,29 +1262,29 @@ var templates = {
|
|
|
1024
1262
|
{
|
|
1025
1263
|
type: "card",
|
|
1026
1264
|
className: "shadow-sm",
|
|
1027
|
-
|
|
1265
|
+
children: [
|
|
1028
1266
|
{
|
|
1029
1267
|
type: "div",
|
|
1030
1268
|
className: "p-6 pb-2",
|
|
1031
|
-
|
|
1269
|
+
children: {
|
|
1032
1270
|
type: "div",
|
|
1033
1271
|
className: "text-sm font-medium text-muted-foreground",
|
|
1034
|
-
|
|
1272
|
+
children: { type: "text", content: "Active Users" }
|
|
1035
1273
|
}
|
|
1036
1274
|
},
|
|
1037
1275
|
{
|
|
1038
1276
|
type: "div",
|
|
1039
1277
|
className: "p-6 pt-0",
|
|
1040
|
-
|
|
1278
|
+
children: [
|
|
1041
1279
|
{
|
|
1042
1280
|
type: "div",
|
|
1043
1281
|
className: "text-2xl font-bold",
|
|
1044
|
-
|
|
1282
|
+
children: { type: "text", content: "+2,350" }
|
|
1045
1283
|
},
|
|
1046
1284
|
{
|
|
1047
1285
|
type: "div",
|
|
1048
1286
|
className: "text-xs text-muted-foreground mt-1",
|
|
1049
|
-
|
|
1287
|
+
children: { type: "text", content: "+180.1% from last month" }
|
|
1050
1288
|
}
|
|
1051
1289
|
]
|
|
1052
1290
|
}
|
|
@@ -1055,29 +1293,29 @@ var templates = {
|
|
|
1055
1293
|
{
|
|
1056
1294
|
type: "card",
|
|
1057
1295
|
className: "shadow-sm",
|
|
1058
|
-
|
|
1296
|
+
children: [
|
|
1059
1297
|
{
|
|
1060
1298
|
type: "div",
|
|
1061
1299
|
className: "p-6 pb-2",
|
|
1062
|
-
|
|
1300
|
+
children: {
|
|
1063
1301
|
type: "div",
|
|
1064
1302
|
className: "text-sm font-medium text-muted-foreground",
|
|
1065
|
-
|
|
1303
|
+
children: { type: "text", content: "Sales" }
|
|
1066
1304
|
}
|
|
1067
1305
|
},
|
|
1068
1306
|
{
|
|
1069
1307
|
type: "div",
|
|
1070
1308
|
className: "p-6 pt-0",
|
|
1071
|
-
|
|
1309
|
+
children: [
|
|
1072
1310
|
{
|
|
1073
1311
|
type: "div",
|
|
1074
1312
|
className: "text-2xl font-bold",
|
|
1075
|
-
|
|
1313
|
+
children: { type: "text", content: "+12,234" }
|
|
1076
1314
|
},
|
|
1077
1315
|
{
|
|
1078
1316
|
type: "div",
|
|
1079
1317
|
className: "text-xs text-muted-foreground mt-1",
|
|
1080
|
-
|
|
1318
|
+
children: { type: "text", content: "+19% from last month" }
|
|
1081
1319
|
}
|
|
1082
1320
|
]
|
|
1083
1321
|
}
|
|
@@ -1086,29 +1324,29 @@ var templates = {
|
|
|
1086
1324
|
{
|
|
1087
1325
|
type: "card",
|
|
1088
1326
|
className: "shadow-sm",
|
|
1089
|
-
|
|
1327
|
+
children: [
|
|
1090
1328
|
{
|
|
1091
1329
|
type: "div",
|
|
1092
1330
|
className: "p-6 pb-2",
|
|
1093
|
-
|
|
1331
|
+
children: {
|
|
1094
1332
|
type: "div",
|
|
1095
1333
|
className: "text-sm font-medium text-muted-foreground",
|
|
1096
|
-
|
|
1334
|
+
children: { type: "text", content: "Active Now" }
|
|
1097
1335
|
}
|
|
1098
1336
|
},
|
|
1099
1337
|
{
|
|
1100
1338
|
type: "div",
|
|
1101
1339
|
className: "p-6 pt-0",
|
|
1102
|
-
|
|
1340
|
+
children: [
|
|
1103
1341
|
{
|
|
1104
1342
|
type: "div",
|
|
1105
1343
|
className: "text-2xl font-bold",
|
|
1106
|
-
|
|
1344
|
+
children: { type: "text", content: "+573" }
|
|
1107
1345
|
},
|
|
1108
1346
|
{
|
|
1109
1347
|
type: "div",
|
|
1110
1348
|
className: "text-xs text-muted-foreground mt-1",
|
|
1111
|
-
|
|
1349
|
+
children: { type: "text", content: "+201 since last hour" }
|
|
1112
1350
|
}
|
|
1113
1351
|
]
|
|
1114
1352
|
}
|
|
@@ -1121,27 +1359,27 @@ var templates = {
|
|
|
1121
1359
|
className: "shadow-sm",
|
|
1122
1360
|
title: "Recent Activity",
|
|
1123
1361
|
description: "Your latest updates and notifications",
|
|
1124
|
-
|
|
1362
|
+
children: {
|
|
1125
1363
|
type: "div",
|
|
1126
1364
|
className: "p-6 pt-0 space-y-4",
|
|
1127
|
-
|
|
1365
|
+
children: [
|
|
1128
1366
|
{
|
|
1129
1367
|
type: "div",
|
|
1130
1368
|
className: "flex items-center gap-4 border-b pb-4",
|
|
1131
|
-
|
|
1369
|
+
children: [
|
|
1132
1370
|
{
|
|
1133
1371
|
type: "div",
|
|
1134
1372
|
className: "flex-1",
|
|
1135
|
-
|
|
1373
|
+
children: [
|
|
1136
1374
|
{
|
|
1137
1375
|
type: "div",
|
|
1138
1376
|
className: "font-medium",
|
|
1139
|
-
|
|
1377
|
+
children: { type: "text", content: "New user registration" }
|
|
1140
1378
|
},
|
|
1141
1379
|
{
|
|
1142
1380
|
type: "div",
|
|
1143
1381
|
className: "text-sm text-muted-foreground",
|
|
1144
|
-
|
|
1382
|
+
children: { type: "text", content: "2 minutes ago" }
|
|
1145
1383
|
}
|
|
1146
1384
|
]
|
|
1147
1385
|
}
|
|
@@ -1150,20 +1388,20 @@ var templates = {
|
|
|
1150
1388
|
{
|
|
1151
1389
|
type: "div",
|
|
1152
1390
|
className: "flex items-center gap-4 border-b pb-4",
|
|
1153
|
-
|
|
1391
|
+
children: [
|
|
1154
1392
|
{
|
|
1155
1393
|
type: "div",
|
|
1156
1394
|
className: "flex-1",
|
|
1157
|
-
|
|
1395
|
+
children: [
|
|
1158
1396
|
{
|
|
1159
1397
|
type: "div",
|
|
1160
1398
|
className: "font-medium",
|
|
1161
|
-
|
|
1399
|
+
children: { type: "text", content: "Payment received" }
|
|
1162
1400
|
},
|
|
1163
1401
|
{
|
|
1164
1402
|
type: "div",
|
|
1165
1403
|
className: "text-sm text-muted-foreground",
|
|
1166
|
-
|
|
1404
|
+
children: { type: "text", content: "15 minutes ago" }
|
|
1167
1405
|
}
|
|
1168
1406
|
]
|
|
1169
1407
|
}
|
|
@@ -1172,20 +1410,20 @@ var templates = {
|
|
|
1172
1410
|
{
|
|
1173
1411
|
type: "div",
|
|
1174
1412
|
className: "flex items-center gap-4",
|
|
1175
|
-
|
|
1413
|
+
children: [
|
|
1176
1414
|
{
|
|
1177
1415
|
type: "div",
|
|
1178
1416
|
className: "flex-1",
|
|
1179
|
-
|
|
1417
|
+
children: [
|
|
1180
1418
|
{
|
|
1181
1419
|
type: "div",
|
|
1182
1420
|
className: "font-medium",
|
|
1183
|
-
|
|
1421
|
+
children: { type: "text", content: "New order placed" }
|
|
1184
1422
|
},
|
|
1185
1423
|
{
|
|
1186
1424
|
type: "div",
|
|
1187
1425
|
className: "text-sm text-muted-foreground",
|
|
1188
|
-
|
|
1426
|
+
children: { type: "text", content: "1 hour ago" }
|
|
1189
1427
|
}
|
|
1190
1428
|
]
|
|
1191
1429
|
}
|
|
@@ -1370,46 +1608,47 @@ export default function App() {
|
|
|
1370
1608
|
}
|
|
1371
1609
|
async function init(name, options) {
|
|
1372
1610
|
const cwd = process.cwd();
|
|
1373
|
-
const projectDir =
|
|
1374
|
-
if (
|
|
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;
|
|
1616
|
+
const files = buildInitFiles(name, options.template);
|
|
1378
1617
|
if (name !== ".") {
|
|
1379
1618
|
mkdirSync3(projectDir, { recursive: true });
|
|
1380
1619
|
}
|
|
1381
|
-
console.log(
|
|
1382
|
-
console.log(
|
|
1620
|
+
console.log(chalk4.blue("\u{1F3A8} Creating Object UI application..."));
|
|
1621
|
+
console.log(chalk4.dim(` Template: ${options.template}`));
|
|
1383
1622
|
console.log();
|
|
1384
|
-
for (const [relativePath, contents] of Object.entries(
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
const target = join4(targetDir, relativePath);
|
|
1388
|
-
mkdirSync3(dirname3(target), { recursive: true });
|
|
1623
|
+
for (const [relativePath, contents] of Object.entries(files)) {
|
|
1624
|
+
const target = join6(targetDir, relativePath);
|
|
1625
|
+
mkdirSync3(dirname5(target), { recursive: true });
|
|
1389
1626
|
writeFileSync2(target, contents);
|
|
1390
|
-
console.log(
|
|
1627
|
+
console.log(chalk4.green(`\u2713 Created ${relativePath}`));
|
|
1391
1628
|
}
|
|
1392
1629
|
console.log();
|
|
1393
|
-
console.log(
|
|
1630
|
+
console.log(chalk4.green("\u2728 Application created successfully!"));
|
|
1394
1631
|
console.log();
|
|
1395
|
-
console.log(
|
|
1632
|
+
console.log(chalk4.bold("Next steps:"));
|
|
1396
1633
|
console.log();
|
|
1397
1634
|
if (name !== ".") {
|
|
1398
|
-
console.log(
|
|
1635
|
+
console.log(chalk4.cyan(` cd ${name}`));
|
|
1399
1636
|
}
|
|
1400
|
-
console.log(
|
|
1401
|
-
console.log(
|
|
1637
|
+
console.log(chalk4.cyan(" npm install"));
|
|
1638
|
+
console.log(chalk4.cyan(" npm run dev"));
|
|
1402
1639
|
console.log();
|
|
1403
|
-
console.log(
|
|
1640
|
+
console.log(chalk4.dim(" The development server will start on http://localhost:3000"));
|
|
1404
1641
|
console.log();
|
|
1405
1642
|
}
|
|
1406
1643
|
|
|
1407
1644
|
export {
|
|
1408
|
-
parseSchemaFile,
|
|
1409
|
-
scanPagesDirectory,
|
|
1410
1645
|
createTempApp,
|
|
1411
1646
|
createTempAppWithRouting,
|
|
1647
|
+
resolveProjectSource,
|
|
1648
|
+
reportProjectSource,
|
|
1649
|
+
isWorkspaceRoot,
|
|
1650
|
+
prepareWorkspaceTempApp,
|
|
1412
1651
|
serve,
|
|
1413
1652
|
init
|
|
1414
1653
|
};
|
|
1415
|
-
//# sourceMappingURL=chunk-
|
|
1654
|
+
//# sourceMappingURL=chunk-VMMIGYU3.js.map
|