11import { createServer } from 'vite' ;
22import react from '@vitejs/plugin-react' ;
3- import { existsSync , mkdirSync } from 'fs' ;
4- import { join , resolve } from 'path' ;
3+ import { existsSync , mkdirSync , unlinkSync , statSync } from 'fs' ;
4+ import { join , resolve , dirname } from 'path' ;
55import chalk from 'chalk' ;
66import { execSync } from 'child_process' ;
7+ import { createRequire } from 'module' ;
78import { scanPagesDirectory , createTempAppWithRouting , createTempApp , parseSchemaFile , type RouteInfo } from '../utils/app-generator.js' ;
89
910interface DevOptions {
@@ -15,22 +16,62 @@ interface DevOptions {
1516export async function dev ( schemaPath : string , options : DevOptions ) {
1617 const cwd = process . cwd ( ) ;
1718
18- // Check if pages directory exists for file-system routing
19- const pagesDir = join ( cwd , 'pages' ) ;
20- const hasPagesDir = existsSync ( pagesDir ) ;
19+ // Resolve the actual project root and schema file
20+ let projectRoot = cwd ;
21+ let targetSchemaPath = schemaPath ;
22+ let hasPagesDir = false ;
23+ let pagesDir = '' ;
24+ let appConfig : unknown = null ;
25+
26+ // 1. Determine Project Root & Mode
27+ const absoluteSchemaPath = resolve ( cwd , schemaPath ) ;
28+
29+ if ( existsSync ( absoluteSchemaPath ) && statSync ( absoluteSchemaPath ) . isFile ( ) ) {
30+ // If input is a file (e.g. examples/showcase/app.json)
31+ const fileDir = dirname ( absoluteSchemaPath ) ;
32+ const potentialPagesDir = join ( fileDir , 'pages' ) ;
33+
34+ if ( existsSync ( potentialPagesDir ) ) {
35+ console . log ( chalk . blue ( `📂 Detected project structure at ${ fileDir } ` ) ) ;
36+ projectRoot = fileDir ;
37+ hasPagesDir = true ;
38+ pagesDir = potentialPagesDir ;
39+
40+ // Try to load app.json as config
41+ try {
42+ appConfig = parseSchemaFile ( absoluteSchemaPath ) ;
43+ console . log ( chalk . blue ( '⚙️ Loaded App Config from app.json' ) ) ;
44+ } catch ( e ) {
45+ console . warn ( 'Failed to parse app config' ) ;
46+ }
47+ }
48+ }
49+
50+ // Fallback: Check detect pages dir in current cwd if not found above
51+ if ( ! hasPagesDir ) {
52+ const localPagesDir = join ( cwd , 'pages' ) ;
53+ if ( existsSync ( localPagesDir ) ) {
54+ hasPagesDir = true ;
55+ pagesDir = localPagesDir ;
56+ // Try to find app.json in cwd
57+ // TODO: Load app.json if exists
58+ }
59+ }
60+
61+ const require = createRequire ( join ( cwd , 'package.json' ) ) ;
2162
2263 let routes : RouteInfo [ ] = [ ] ;
2364 let schema : unknown = null ;
2465 let useFileSystemRouting = false ;
2566
2667 if ( hasPagesDir ) {
2768 // File-system based routing
28- console . log ( chalk . blue ( '📁 Detected pages/ directory - using file-system routing' ) ) ;
69+ console . log ( chalk . blue ( `📁 Using file-system routing from ${ pagesDir } ` ) ) ;
2970 routes = scanPagesDirectory ( pagesDir ) ;
3071 useFileSystemRouting = true ;
3172
3273 if ( routes . length === 0 ) {
33- throw new Error ( ' No schema files found in pages/ directory' ) ;
74+ throw new Error ( ` No schema files found in ${ pagesDir } ` ) ;
3475 }
3576
3677 console . log ( chalk . green ( `✓ Found ${ routes . length } route(s)` ) ) ;
@@ -40,33 +81,30 @@ export async function dev(schemaPath: string, options: DevOptions) {
4081 } else {
4182 // Single schema file mode
4283 const fullSchemaPath = resolve ( cwd , schemaPath ) ;
43-
44- // Check if schema file exists
84+ // ... (rest of the logic)
4585 if ( ! existsSync ( fullSchemaPath ) ) {
4686 throw new Error ( `Schema file not found: ${ schemaPath } \nRun 'objectui init' to create a sample schema.` ) ;
4787 }
48-
4988 console . log ( chalk . blue ( '📋 Loading schema:' ) , chalk . cyan ( schemaPath ) ) ;
50-
51- // Read and validate schema
5289 try {
5390 schema = parseSchemaFile ( fullSchemaPath ) ;
5491 } catch ( error ) {
55- throw new Error ( `Invalid schema file: ${ error instanceof Error ? error . message : error } ` ) ;
92+ throw new Error ( `Invalid schema file: ${ error instanceof Error ? error . message : error } ` ) ;
5693 }
5794 }
5895
59- // Create temporary app directory
96+ // Create temporary app directory (always in cwd to keep node_modules access)
6097 const tmpDir = join ( cwd , '.objectui-tmp' ) ;
6198 mkdirSync ( tmpDir , { recursive : true } ) ;
6299
63100 // Create temporary app files
64101 if ( useFileSystemRouting ) {
65- createTempAppWithRouting ( tmpDir , routes ) ;
102+ createTempAppWithRouting ( tmpDir , routes , appConfig ) ;
66103 } else {
67104 createTempApp ( tmpDir , schema ) ;
68105 }
69106
107+
70108 // Install dependencies
71109 const isMonorepo = existsSync ( join ( cwd , 'pnpm-workspace.yaml' ) ) ;
72110
@@ -90,16 +128,61 @@ export async function dev(schemaPath: string, options: DevOptions) {
90128 console . log ( chalk . blue ( '🚀 Starting development server...\n' ) ) ;
91129
92130 // Create Vite config
93- const viteConfig = {
131+ const viteConfig : any = {
94132 root : tmpDir ,
95133 server : {
96134 port : parseInt ( options . port ) ,
97135 host : options . host ,
98136 open : options . open !== false ,
137+ fs : {
138+ // Allow serving files from workspace root
139+ allow : [ cwd ] ,
140+ }
141+ } ,
142+ resolve : {
143+ alias : { }
99144 } ,
100145 plugins : [ react ( ) ] ,
101146 } ;
102147
148+ if ( isMonorepo ) {
149+ console . log ( chalk . blue ( '📦 Detected monorepo - configuring workspace aliases' ) ) ;
150+
151+ // Remove postcss.config.js to prevent interference with programmatic config
152+ const postcssPath = join ( tmpDir , 'postcss.config.js' ) ;
153+ if ( existsSync ( postcssPath ) ) {
154+ unlinkSync ( postcssPath ) ;
155+ }
156+
157+ // Add aliases for workspace packages
158+ viteConfig . resolve . alias = {
159+ '@object-ui/react' : join ( cwd , 'packages/react/src/index.ts' ) ,
160+ '@object-ui/components' : join ( cwd , 'packages/components/src/index.ts' ) ,
161+ '@object-ui/core' : join ( cwd , 'packages/core/src/index.ts' ) ,
162+ '@object-ui/types' : join ( cwd , 'packages/types/src/index.ts' ) ,
163+ } ;
164+
165+ // Debug aliases
166+ // console.log('Aliases:', viteConfig.resolve.alias);
167+
168+ // Configure PostCSS programmatically reusing root dependencies
169+ try {
170+ const tailwindcss = require ( 'tailwindcss' ) ;
171+ const autoprefixer = require ( 'autoprefixer' ) ;
172+
173+ viteConfig . css = {
174+ postcss : {
175+ plugins : [
176+ tailwindcss ( join ( tmpDir , 'tailwind.config.js' ) ) ,
177+ autoprefixer ( ) ,
178+ ] ,
179+ } ,
180+ } ;
181+ } catch ( e ) {
182+ console . warn ( chalk . yellow ( '⚠️ Failed to load PostCSS plugins from root node_modules. Styles might not work correctly.' ) ) ;
183+ }
184+ }
185+
103186 // Create Vite server
104187 const server = await createServer ( viteConfig ) ;
105188
0 commit comments