@famgia/omnify-gui 1.0.2 → 1.0.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.
@@ -916,13 +916,11 @@ function createApp(config) {
916
916
  app.use("/api/preview", previewRouter);
917
917
  app.use("/api/config", configRouter);
918
918
  app.use("/api/versions", versionsRouter);
919
- if (process.env.NODE_ENV === "production") {
920
- const clientDist = join2(__dirname, "../client");
921
- app.use(express.static(clientDist));
922
- app.get("*", (_req, res) => {
923
- res.sendFile(join2(clientDist, "index.html"));
924
- });
925
- }
919
+ const clientDist = join2(__dirname, "../client");
920
+ app.use(express.static(clientDist));
921
+ app.get("*", (_req, res) => {
922
+ res.sendFile(join2(clientDist, "index.html"));
923
+ });
926
924
  app.use((err, _req, res, _next) => {
927
925
  console.error("Server error:", err);
928
926
  const response = {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/server/index.ts","../../src/server/app.ts","../../src/server/api/schemas.ts","../../src/server/services/schemaService.ts","../../src/server/api/validate.ts","../../src/server/services/validationService.ts","../../src/server/api/preview.ts","../../src/server/services/previewService.ts","../../src/server/api/config.ts","../../src/shared/constants.ts","../../src/server/api/versions.ts","../../src/server/services/versionService.ts","../../src/server/ws/handler.ts","../../src/server/watcher/fileWatcher.ts"],"sourcesContent":["/**\n * @famgia/omnify-gui - Server Entry Point\n *\n * Starts the local development server for Omnify GUI.\n */\n\nimport { createServer } from 'http';\nimport { join, resolve } from 'path';\nimport open from 'open';\nimport { loadConfig } from '@famgia/omnify-cli';\nimport { createApp } from './app.js';\nimport { createWsHandler } from './ws/handler.js';\nimport { createFileWatcher } from './watcher/fileWatcher.js';\nimport { DEFAULT_PORT, DEFAULT_HOST } from '../shared/constants.js';\n\n// fileURLToPath and dirname imported for potential future use with static files\n// Currently not needed as Vite handles static serving\n\nasync function main(): Promise<void> {\n const port = Number(process.env.PORT) || DEFAULT_PORT;\n const host = process.env.HOST ?? DEFAULT_HOST;\n const cwd = process.cwd();\n\n // Resolve schemas directory from omnify config or environment variable\n let schemasDir: string;\n\n if (process.env.SCHEMAS_DIR) {\n schemasDir = process.env.SCHEMAS_DIR;\n } else {\n try {\n const { config } = await loadConfig(cwd);\n schemasDir = resolve(cwd, config.schemasDir);\n } catch {\n // Fall back to default if no config file found\n schemasDir = join(cwd, 'schemas');\n }\n }\n\n console.log('Starting Omnify GUI...');\n console.log(` Schemas directory: ${schemasDir}`);\n\n // Create Express app\n const app = createApp({ schemasDir, cwd });\n\n // Create HTTP server\n const server = createServer(app);\n\n // Create WebSocket handler\n const wsHandler = createWsHandler(server);\n\n // Create file watcher\n const watcher = createFileWatcher(schemasDir, wsHandler);\n\n // Start server\n server.listen(port, host, () => {\n const url = `http://${host}:${port}`;\n console.log(` GUI running at: ${url}`);\n console.log(' Press Ctrl+C to stop\\n');\n\n // Auto-open browser in development\n if (process.env.NODE_ENV !== 'production') {\n open(url).catch(() => {\n // Ignore errors if browser fails to open\n });\n }\n });\n\n // Graceful shutdown\n const shutdown = (): void => {\n console.log('\\nShutting down...');\n watcher.close();\n wsHandler.close();\n server.close(() => {\n console.log('Server closed');\n process.exit(0);\n });\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n\nmain().catch((error: unknown) => {\n console.error('Failed to start server:', error);\n process.exit(1);\n});\n","/**\n * Express application configuration\n */\n\nimport express, { type Express, type Request, type Response, type NextFunction } from 'express';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport { schemasRouter } from './api/schemas.js';\nimport { validateRouter } from './api/validate.js';\nimport { previewRouter } from './api/preview.js';\nimport { configRouter } from './api/config.js';\nimport { versionsRouter } from './api/versions.js';\nimport { initVersionStore } from './services/versionService.js';\nimport type { ApiResponse } from '../shared/types.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport interface AppConfig {\n schemasDir: string;\n cwd: string;\n}\n\nexport function createApp(config: AppConfig): Express {\n const app = express();\n\n // Store config in app locals for access in routes\n app.locals.config = config;\n\n // Initialize version store with project root and schemas directory\n initVersionStore(config.cwd, config.schemasDir);\n\n // Middleware\n app.use(express.json());\n\n // API routes\n app.use('/api/schemas', schemasRouter);\n app.use('/api/validate', validateRouter);\n app.use('/api/preview', previewRouter);\n app.use('/api/config', configRouter);\n app.use('/api/versions', versionsRouter);\n\n // Serve static files in production\n if (process.env.NODE_ENV === 'production') {\n const clientDist = join(__dirname, '../client');\n app.use(express.static(clientDist));\n\n // SPA fallback\n app.get('*', (_req: Request, res: Response) => {\n res.sendFile(join(clientDist, 'index.html'));\n });\n }\n\n // Error handler\n app.use((err: Error, _req: Request, res: Response, _next: NextFunction) => {\n console.error('Server error:', err);\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'INTERNAL_ERROR',\n message: err.message,\n },\n };\n res.status(500).json(response);\n });\n\n return app;\n}\n","/**\n * Schema CRUD API routes\n */\n\nimport { Router, type Request, type Response, type IRouter } from 'express';\nimport { schemaService } from '../services/schemaService.js';\nimport type { ApiResponse, GuiSchema } from '../../shared/types.js';\nimport type { AppConfig } from '../app.js';\n\nexport const schemasRouter: IRouter = Router();\n\n// GET /api/schemas - List all schemas\nschemasRouter.get('/', async (req: Request, res: Response) => {\n try {\n const config = req.app.locals.config as AppConfig;\n const schemas = await schemaService.loadAll(config.schemasDir);\n const response: ApiResponse<Record<string, GuiSchema>> = {\n success: true,\n data: schemas,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'LOAD_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n\n// GET /api/schemas/:name - Get single schema\nschemasRouter.get('/:name', async (req: Request, res: Response) => {\n try {\n const config = req.app.locals.config as AppConfig;\n const { name } = req.params;\n const schema = await schemaService.load(config.schemasDir, name!);\n\n if (!schema) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'NOT_FOUND',\n message: `Schema \"${name}\" not found`,\n },\n };\n res.status(404).json(response);\n return;\n }\n\n const response: ApiResponse<GuiSchema> = {\n success: true,\n data: schema,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'LOAD_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n\n// POST /api/schemas - Create new schema\nschemasRouter.post('/', async (req: Request, res: Response) => {\n try {\n const config = req.app.locals.config as AppConfig;\n const schema = req.body as GuiSchema;\n\n if (!schema.name) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'VALIDATION_ERROR',\n message: 'Schema name is required',\n },\n };\n res.status(400).json(response);\n return;\n }\n\n const saved = await schemaService.save(config.schemasDir, schema);\n const response: ApiResponse<GuiSchema> = {\n success: true,\n data: saved,\n };\n res.status(201).json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'SAVE_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n\n// PUT /api/schemas/:name - Update schema\nschemasRouter.put('/:name', async (req: Request, res: Response) => {\n try {\n const config = req.app.locals.config as AppConfig;\n const { name } = req.params;\n const schema = req.body as GuiSchema;\n\n // Ensure name matches\n schema.name = name!;\n\n const saved = await schemaService.save(config.schemasDir, schema);\n const response: ApiResponse<GuiSchema> = {\n success: true,\n data: saved,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'SAVE_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n\n// DELETE /api/schemas/:name - Delete schema\nschemasRouter.delete('/:name', async (req: Request, res: Response) => {\n try {\n const config = req.app.locals.config as AppConfig;\n const { name } = req.params;\n\n await schemaService.delete(config.schemasDir, name!);\n const response: ApiResponse = {\n success: true,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'DELETE_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n","/**\n * Schema CRUD service using omnify-core\n */\n\nimport { loadSchemas } from '@famgia/omnify-core';\nimport { writeFile, unlink } from 'fs/promises';\nimport { join } from 'path';\nimport { stringify } from 'yaml';\nimport type { GuiSchema, GuiEnumValue } from '../../shared/types.js';\n\n/**\n * Convert enum values from various formats to GuiEnumValue[]\n */\nfunction normalizeEnumValues(values: unknown): GuiEnumValue[] | undefined {\n if (!values || !Array.isArray(values)) return undefined;\n\n return values.map((v) => {\n // Already an object with value property\n if (typeof v === 'object' && v !== null && 'value' in v) {\n const obj = v as Record<string, unknown>;\n return {\n value: String(obj.value),\n label: obj.label ? String(obj.label) : undefined,\n extra: obj.extra as GuiEnumValue['extra'],\n };\n }\n // Simple string value\n return { value: String(v) };\n });\n}\n\nclass SchemaService {\n private cache: Map<string, Record<string, GuiSchema>> = new Map();\n\n async loadAll(schemasDir: string): Promise<Record<string, GuiSchema>> {\n try {\n const schemas = await loadSchemas(schemasDir);\n const guiSchemas: Record<string, GuiSchema> = {};\n\n for (const [name, schema] of Object.entries(schemas)) {\n guiSchemas[name] = {\n name: schema.name,\n kind: schema.kind ?? 'object',\n displayName: schema.displayName,\n filePath: schema.filePath,\n relativePath: schema.relativePath,\n properties: schema.properties as GuiSchema['properties'],\n options: schema.options as GuiSchema['options'],\n values: normalizeEnumValues(schema.values),\n isDirty: false,\n validationErrors: [],\n };\n }\n\n this.cache.set(schemasDir, guiSchemas);\n return guiSchemas;\n } catch (error) {\n // Return empty if no schemas found\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return {};\n }\n throw error;\n }\n }\n\n async load(schemasDir: string, name: string): Promise<GuiSchema | null> {\n const schemas = await this.loadAll(schemasDir);\n return schemas[name] ?? null;\n }\n\n async save(schemasDir: string, schema: GuiSchema): Promise<GuiSchema> {\n const { isDirty: _isDirty, validationErrors: _validationErrors, filePath: _filePath, ...schemaData } = schema;\n const fileName = `${schema.name}.yaml`;\n const targetPath = join(schemasDir, fileName);\n\n // Convert to YAML\n const yamlContent = stringify(schemaData, {\n lineWidth: 120,\n defaultKeyType: 'PLAIN',\n defaultStringType: 'PLAIN',\n });\n\n await writeFile(targetPath, yamlContent, 'utf-8');\n\n // Return updated schema with file path\n return {\n ...schemaData,\n filePath: targetPath,\n isDirty: false,\n validationErrors: [],\n };\n }\n\n async delete(schemasDir: string, name: string): Promise<void> {\n const fileName = `${name}.yaml`;\n const targetPath = join(schemasDir, fileName);\n await unlink(targetPath);\n\n // Clear cache\n this.cache.delete(schemasDir);\n }\n\n clearCache(schemasDir?: string): void {\n if (schemasDir) {\n this.cache.delete(schemasDir);\n } else {\n this.cache.clear();\n }\n }\n}\n\nexport const schemaService = new SchemaService();\n","/**\n * Schema validation API routes\n */\n\nimport { Router, type Request, type Response, type IRouter } from 'express';\nimport { validationService } from '../services/validationService.js';\nimport type { ApiResponse, GuiSchema, ValidationError } from '../../shared/types.js';\nimport type { AppConfig } from '../app.js';\n\nexport const validateRouter: IRouter = Router();\n\ninterface ValidateRequest {\n schema?: GuiSchema;\n schemas?: Record<string, GuiSchema>;\n}\n\ninterface ValidateResult {\n valid: boolean;\n errors: ValidationError[];\n}\n\n// POST /api/validate - Validate schema(s)\nvalidateRouter.post('/', async (req: Request, res: Response) => {\n try {\n const config = req.app.locals.config as AppConfig;\n const body = req.body as ValidateRequest;\n\n let result: ValidateResult;\n\n if (body.schema) {\n // Validate single schema\n result = await validationService.validateSchema(body.schema, config.schemasDir);\n } else if (body.schemas) {\n // Validate all schemas\n result = await validationService.validateAll(body.schemas);\n } else {\n // Load and validate all from disk\n result = await validationService.validateFromDisk(config.schemasDir);\n }\n\n const response: ApiResponse<ValidateResult> = {\n success: true,\n data: result,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'VALIDATION_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n","/**\n * Schema validation service using omnify-core\n */\n\nimport { loadSchemas, validateSchemas, OmnifyError } from '@famgia/omnify-core';\nimport type { LoadedSchema, SchemaCollection, SchemaOptions } from '@famgia/omnify-types';\nimport type { GuiSchema, ValidationError } from '../../shared/types.js';\n\ninterface ValidateResult {\n valid: boolean;\n errors: ValidationError[];\n}\n\n/**\n * Convert GuiSchema to LoadedSchema format\n * Handles exactOptionalPropertyTypes by only setting defined properties\n */\nfunction toLoadedSchema(schema: GuiSchema): LoadedSchema {\n // Start with required fields only\n const result = {\n name: schema.name,\n kind: schema.kind,\n filePath: schema.filePath,\n relativePath: schema.relativePath ?? schema.name + '.yaml',\n } as LoadedSchema;\n\n // Only add optional fields if they're defined\n if (schema.displayName !== undefined) {\n (result as { displayName: string }).displayName = schema.displayName;\n }\n if (schema.properties !== undefined) {\n (result as { properties: LoadedSchema['properties'] }).properties = schema.properties as LoadedSchema['properties'];\n }\n if (schema.options !== undefined) {\n (result as { options: SchemaOptions }).options = schema.options as SchemaOptions;\n }\n if (schema.values !== undefined) {\n (result as { values: readonly string[] }).values = schema.values;\n }\n\n return result;\n}\n\nclass ValidationService {\n async validateSchema(schema: GuiSchema, schemasDir: string): Promise<ValidateResult> {\n try {\n // Load all schemas to validate references\n const allSchemas = await loadSchemas(schemasDir);\n\n // Convert GuiSchema to LoadedSchema format\n const loadedSchema = toLoadedSchema(schema);\n\n // Create mutable copy and add the schema\n const schemasToValidate: Record<string, LoadedSchema> = { ...allSchemas };\n schemasToValidate[schema.name] = loadedSchema;\n\n // Validate all schemas together\n const result = validateSchemas(schemasToValidate);\n\n // Filter errors for this schema from schema results\n const schemaResult = result.schemas.find((s) => s.schemaName === schema.name);\n const schemaErrors: ValidationError[] = [];\n\n if (schemaResult) {\n for (const e of schemaResult.errors) {\n schemaErrors.push({\n path: this.getErrorPath(e, schema.name),\n message: e.message,\n severity: 'error' as const,\n });\n }\n }\n\n return {\n valid: schemaErrors.length === 0,\n errors: schemaErrors,\n };\n } catch (error) {\n return {\n valid: false,\n errors: [\n {\n path: schema.name,\n message: (error as Error).message,\n severity: 'error',\n },\n ],\n };\n }\n }\n\n async validateAll(schemas: Record<string, GuiSchema>): Promise<ValidateResult> {\n try {\n // Convert GuiSchemas to LoadedSchemas\n const loadedSchemas: SchemaCollection = {};\n for (const [name, schema] of Object.entries(schemas)) {\n (loadedSchemas as Record<string, LoadedSchema>)[name] = toLoadedSchema(schema);\n }\n\n const result = validateSchemas(loadedSchemas);\n\n const errors: ValidationError[] = [];\n for (const schemaResult of result.schemas) {\n for (const e of schemaResult.errors) {\n errors.push({\n path: this.getErrorPath(e, schemaResult.schemaName),\n message: e.message,\n severity: 'error' as const,\n });\n }\n }\n\n return {\n valid: result.valid,\n errors,\n };\n } catch (error) {\n return {\n valid: false,\n errors: [\n {\n path: 'root',\n message: (error as Error).message,\n severity: 'error',\n },\n ],\n };\n }\n }\n\n async validateFromDisk(schemasDir: string): Promise<ValidateResult> {\n try {\n const schemas = await loadSchemas(schemasDir);\n\n // Convert to GuiSchemas\n const guiSchemas: Record<string, GuiSchema> = {};\n for (const [name, schema] of Object.entries(schemas)) {\n guiSchemas[name] = {\n name: schema.name,\n kind: schema.kind ?? 'object',\n displayName: schema.displayName,\n filePath: schema.filePath,\n relativePath: schema.relativePath,\n properties: schema.properties as GuiSchema['properties'],\n options: schema.options as GuiSchema['options'],\n values: schema.values,\n };\n }\n\n return this.validateAll(guiSchemas);\n } catch (error) {\n return {\n valid: false,\n errors: [\n {\n path: 'root',\n message: (error as Error).message,\n severity: 'error',\n },\n ],\n };\n }\n }\n\n private getErrorPath(error: OmnifyError, schemaName: string): string {\n // Try to extract property name from the error message or details\n const details = error.details;\n if (details && 'propertyName' in details && details.propertyName) {\n return `${schemaName}.${String(details.propertyName)}`;\n }\n return schemaName;\n }\n}\n\nexport const validationService = new ValidationService();\n","/**\n * Code preview API routes\n */\n\nimport { Router, type Request, type Response, type IRouter } from 'express';\nimport { previewService } from '../services/previewService.js';\nimport type { ApiResponse, PreviewResult, PreviewType } from '../../shared/types.js';\nimport type { AppConfig } from '../app.js';\n\nexport const previewRouter: IRouter = Router();\n\n// GET /api/preview/:type - Get code preview for all schemas\npreviewRouter.get('/:type', async (req: Request, res: Response) => {\n try {\n const config = req.app.locals.config as AppConfig;\n const { type } = req.params;\n\n if (!['laravel', 'typescript', 'sql'].includes(type!)) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'INVALID_TYPE',\n message: `Invalid preview type: ${type}. Valid types: laravel, typescript, sql`,\n },\n };\n res.status(400).json(response);\n return;\n }\n\n const previews = await previewService.generateAll(config.schemasDir, type as PreviewType);\n const response: ApiResponse<PreviewResult[]> = {\n success: true,\n data: previews,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'PREVIEW_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n\n// GET /api/preview/:type/:name - Get code preview for single schema\npreviewRouter.get('/:type/:name', async (req: Request, res: Response) => {\n try {\n const config = req.app.locals.config as AppConfig;\n const { type, name } = req.params;\n\n if (!['laravel', 'typescript', 'sql'].includes(type!)) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'INVALID_TYPE',\n message: `Invalid preview type: ${type}. Valid types: laravel, typescript, sql`,\n },\n };\n res.status(400).json(response);\n return;\n }\n\n const preview = await previewService.generateForSchema(\n config.schemasDir,\n name!,\n type as PreviewType\n );\n\n if (!preview) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'NOT_FOUND',\n message: `Schema \"${name}\" not found`,\n },\n };\n res.status(404).json(response);\n return;\n }\n\n const response: ApiResponse<PreviewResult> = {\n success: true,\n data: preview,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'PREVIEW_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n","/**\n * Code preview generation service\n */\n\nimport { loadSchemas } from '@famgia/omnify-core';\nimport { generateMigrations as generateLaravelMigrations } from '@famgia/omnify-laravel';\nimport { generateMigrations as generateSqlMigrations } from '@famgia/omnify-sql';\nimport type { PreviewResult, PreviewType } from '../../shared/types.js';\n\ninterface EnumSchema {\n kind: 'enum';\n values?: readonly string[];\n}\n\ninterface ObjectSchema {\n kind: 'object';\n properties?: Record<string, { type: string; nullable?: boolean }>;\n}\n\nclass PreviewService {\n async generateAll(schemasDir: string, type: PreviewType): Promise<PreviewResult[]> {\n const schemas = await loadSchemas(schemasDir);\n const previews: PreviewResult[] = [];\n\n switch (type) {\n case 'laravel': {\n const migrations = await generateLaravelMigrations(schemas);\n for (const migration of migrations) {\n previews.push({\n type: 'laravel',\n content: migration.content,\n fileName: migration.fileName,\n });\n }\n break;\n }\n\n case 'sql': {\n const migrations = generateSqlMigrations(schemas, { dialect: 'mysql' });\n for (const migration of migrations) {\n previews.push({\n type: 'sql',\n content: migration.content,\n fileName: migration.fileName,\n });\n }\n break;\n }\n\n case 'typescript': {\n // Generate TypeScript interfaces from schemas\n for (const [name, schema] of Object.entries(schemas)) {\n if (schema.kind === 'enum') {\n previews.push({\n type: 'typescript',\n content: this.generateEnumType(name, schema as EnumSchema),\n fileName: `${name}.ts`,\n });\n } else {\n previews.push({\n type: 'typescript',\n content: this.generateInterfaceType(name, schema as ObjectSchema),\n fileName: `${name}.ts`,\n });\n }\n }\n break;\n }\n }\n\n return previews;\n }\n\n async generateForSchema(\n schemasDir: string,\n schemaName: string,\n type: PreviewType\n ): Promise<PreviewResult | null> {\n const schemas = await loadSchemas(schemasDir);\n const schema = schemas[schemaName];\n\n if (!schema) {\n return null;\n }\n\n switch (type) {\n case 'laravel': {\n const migrations = await generateLaravelMigrations({ [schemaName]: schema });\n const migration = migrations[0];\n return migration\n ? {\n type: 'laravel',\n content: migration.content,\n fileName: migration.fileName,\n }\n : null;\n }\n\n case 'sql': {\n const migrations = generateSqlMigrations({ [schemaName]: schema }, { dialect: 'mysql' });\n const migration = migrations[0];\n return migration\n ? {\n type: 'sql',\n content: migration.content,\n fileName: migration.fileName,\n }\n : null;\n }\n\n case 'typescript': {\n if (schema.kind === 'enum') {\n return {\n type: 'typescript',\n content: this.generateEnumType(schemaName, schema as EnumSchema),\n fileName: `${schemaName}.ts`,\n };\n }\n return {\n type: 'typescript',\n content: this.generateInterfaceType(schemaName, schema as ObjectSchema),\n fileName: `${schemaName}.ts`,\n };\n }\n }\n }\n\n private generateEnumType(name: string, schema: EnumSchema): string {\n const values = schema.values ?? [];\n return `export type ${name} = ${values.map((v) => `'${v}'`).join(' | ') || 'never'};\\n`;\n }\n\n private generateInterfaceType(name: string, schema: ObjectSchema): string {\n const lines: string[] = [`export interface ${name} {`];\n\n if (schema.properties) {\n for (const [propName, prop] of Object.entries(schema.properties)) {\n const tsType = this.mapToTsType(prop.type);\n const optional = prop.nullable ? '?' : '';\n lines.push(` ${propName}${optional}: ${tsType};`);\n }\n }\n\n lines.push('}');\n return lines.join('\\n') + '\\n';\n }\n\n private mapToTsType(omnifyType: string): string {\n const typeMap: Record<string, string> = {\n String: 'string',\n Int: 'number',\n BigInt: 'number',\n Float: 'number',\n Decimal: 'number',\n Boolean: 'boolean',\n Text: 'string',\n LongText: 'string',\n Date: 'string',\n Time: 'string',\n Timestamp: 'string',\n Json: 'Record<string, unknown>',\n Email: 'string',\n Password: 'string',\n File: 'string',\n MultiFile: 'string[]',\n Point: '{ lat: number; lng: number }',\n Coordinates: '{ latitude: number; longitude: number }',\n };\n\n return typeMap[omnifyType] ?? 'unknown';\n }\n}\n\nexport const previewService = new PreviewService();\n","/**\n * Config API routes\n */\n\nimport { Router, type Request, type Response, type IRouter } from 'express';\nimport type { ApiResponse, GuiConfig } from '../../shared/types.js';\nimport type { AppConfig } from '../app.js';\nimport { DEFAULT_PORT, DEFAULT_HOST } from '../../shared/constants.js';\n\nexport const configRouter: IRouter = Router();\n\n// GET /api/config - Get current configuration\nconfigRouter.get('/', (req: Request, res: Response) => {\n const appConfig = req.app.locals.config as AppConfig;\n\n const config: GuiConfig = {\n schemasDir: appConfig.schemasDir,\n port: Number(process.env.PORT) || DEFAULT_PORT,\n host: process.env.HOST ?? DEFAULT_HOST,\n };\n\n const response: ApiResponse<GuiConfig> = {\n success: true,\n data: config,\n };\n res.json(response);\n});\n","/**\n * Shared constants for @famgia/omnify-gui\n */\n\nexport const DEFAULT_PORT = 3456;\nexport const DEFAULT_HOST = 'localhost';\n\nexport const API_ROUTES = {\n SCHEMAS: '/api/schemas',\n SCHEMA: '/api/schemas/:name',\n VALIDATE: '/api/validate',\n PREVIEW: '/api/preview/:type',\n CONFIG: '/api/config',\n} as const;\n\nexport const WS_EVENTS = {\n // Server → Client\n SCHEMA_CHANGED: 'schema:changed',\n SCHEMA_VALIDATED: 'schema:validated',\n SCHEMAS_RELOADED: 'schemas:reloaded',\n CONNECTION_READY: 'connection:ready',\n\n // Client → Server\n SCHEMA_SAVE: 'schema:save',\n SCHEMA_VALIDATE: 'schema:validate',\n} as const;\n\nexport const PROPERTY_TYPES = [\n 'String',\n 'Int',\n 'BigInt',\n 'Float',\n 'Decimal',\n 'Boolean',\n 'Text',\n 'LongText',\n 'Date',\n 'Time',\n 'Timestamp',\n 'Json',\n 'Email',\n 'Password',\n 'File',\n 'MultiFile',\n 'Point',\n 'Coordinates',\n 'Enum',\n 'Select',\n 'Lookup',\n] as const;\n\nexport const RELATION_TYPES = [\n 'OneToOne',\n 'OneToMany',\n 'ManyToOne',\n 'ManyToMany',\n] as const;\n\nexport const POLYMORPHIC_RELATION_TYPES = [\n 'MorphTo',\n 'MorphOne',\n 'MorphMany',\n 'MorphToMany',\n 'MorphedByMany',\n] as const;\n\nexport const REFERENTIAL_ACTIONS = [\n 'CASCADE',\n 'SET NULL',\n 'SET DEFAULT',\n 'RESTRICT',\n 'NO ACTION',\n] as const;\n","/**\n * Version history API routes\n */\n\nimport { Router, type Request, type Response, type Router as RouterType } from 'express';\nimport type { ApiResponse } from '../../shared/types.js';\nimport {\n listVersions,\n getVersion,\n getLatestVersion,\n diffVersions,\n getPendingChanges,\n type PendingChangesResult,\n} from '../services/versionService.js';\nimport type { VersionSummary, VersionFile, VersionDiff } from '@famgia/omnify-core';\n\nexport const versionsRouter: RouterType = Router();\n\n/**\n * GET /api/versions - List all versions\n */\nversionsRouter.get('/', async (_req: Request, res: Response) => {\n try {\n const versions = await listVersions();\n const response: ApiResponse<VersionSummary[]> = {\n success: true,\n data: versions,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'VERSION_LIST_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n\n/**\n * GET /api/versions/pending - Get pending changes (current vs latest)\n */\nversionsRouter.get('/pending', async (_req: Request, res: Response) => {\n try {\n const pending = await getPendingChanges();\n const response: ApiResponse<PendingChangesResult> = {\n success: true,\n data: pending,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'PENDING_CHANGES_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n\n/**\n * GET /api/versions/latest - Get latest version\n */\nversionsRouter.get('/latest', async (_req: Request, res: Response) => {\n try {\n const version = await getLatestVersion();\n const response: ApiResponse<VersionFile | null> = {\n success: true,\n data: version,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'VERSION_READ_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n\n/**\n * GET /api/versions/:version - Get specific version\n */\nversionsRouter.get('/:version', async (req: Request, res: Response) => {\n try {\n const versionNum = parseInt(req.params.version, 10);\n if (isNaN(versionNum)) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'INVALID_VERSION',\n message: 'Version must be a number',\n },\n };\n res.status(400).json(response);\n return;\n }\n\n const version = await getVersion(versionNum);\n if (!version) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'VERSION_NOT_FOUND',\n message: `Version ${versionNum} not found`,\n },\n };\n res.status(404).json(response);\n return;\n }\n\n const response: ApiResponse<VersionFile> = {\n success: true,\n data: version,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'VERSION_READ_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n\n/**\n * GET /api/versions/diff/:from/:to - Get diff between versions\n */\nversionsRouter.get('/diff/:from/:to', async (req: Request, res: Response) => {\n try {\n const fromVersion = parseInt(req.params.from, 10);\n const toVersion = parseInt(req.params.to, 10);\n\n if (isNaN(fromVersion) || isNaN(toVersion)) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'INVALID_VERSION',\n message: 'Version numbers must be integers',\n },\n };\n res.status(400).json(response);\n return;\n }\n\n const diff = await diffVersions(fromVersion, toVersion);\n if (!diff) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'DIFF_ERROR',\n message: 'Could not compute diff. One or both versions may not exist.',\n },\n };\n res.status(404).json(response);\n return;\n }\n\n const response: ApiResponse<VersionDiff> = {\n success: true,\n data: diff,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'DIFF_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n","/**\n * Version history service for GUI\n */\n\nimport { loadSchemas } from '@famgia/omnify-core';\nimport {\n createVersionStore,\n type VersionStore,\n type VersionSummary,\n type VersionFile,\n type VersionDiff,\n type VersionChange,\n type VersionSchemaSnapshot,\n type VersionPropertySnapshot,\n} from '@famgia/omnify-core';\n\nlet store: VersionStore | null = null;\nlet schemasDir: string | null = null;\n\n/**\n * Initialize the version store with the project base directory.\n */\nexport function initVersionStore(baseDir: string, schemasDirPath: string): void {\n store = createVersionStore({ baseDir, maxVersions: 100 });\n schemasDir = schemasDirPath;\n}\n\n/**\n * Get the version store instance.\n */\nfunction getStore(): VersionStore {\n if (!store) {\n throw new Error('Version store not initialized. Call initVersionStore first.');\n }\n return store;\n}\n\n/**\n * List all versions.\n */\nexport async function listVersions(): Promise<VersionSummary[]> {\n return getStore().listVersions();\n}\n\n/**\n * Get a specific version.\n */\nexport async function getVersion(version: number): Promise<VersionFile | null> {\n return getStore().readVersion(version);\n}\n\n/**\n * Get the latest version.\n */\nexport async function getLatestVersion(): Promise<VersionFile | null> {\n return getStore().readLatestVersion();\n}\n\n/**\n * Get diff between two versions.\n */\nexport async function diffVersions(fromVersion: number, toVersion: number): Promise<VersionDiff | null> {\n return getStore().diffVersions(fromVersion, toVersion);\n}\n\n/**\n * Get the version store for direct access.\n */\nexport function getVersionStore(): VersionStore {\n return getStore();\n}\n\n/**\n * Convert property to version snapshot format.\n */\nfunction propertyToSnapshot(prop: Record<string, unknown>): VersionPropertySnapshot {\n return {\n type: prop.type as string,\n ...(prop.displayName !== undefined && { displayName: prop.displayName as string }),\n ...(prop.description !== undefined && { description: prop.description as string }),\n ...(prop.nullable !== undefined && { nullable: prop.nullable as boolean }),\n ...(prop.unique !== undefined && { unique: prop.unique as boolean }),\n ...(prop.default !== undefined && { default: prop.default }),\n ...(prop.length !== undefined && { length: prop.length as number }),\n ...(prop.unsigned !== undefined && { unsigned: prop.unsigned as boolean }),\n ...(prop.precision !== undefined && { precision: prop.precision as number }),\n ...(prop.scale !== undefined && { scale: prop.scale as number }),\n ...(prop.enum !== undefined && { enum: prop.enum as readonly string[] }),\n ...(prop.relation !== undefined && { relation: prop.relation as string }),\n ...(prop.target !== undefined && { target: prop.target as string }),\n ...(prop.targets !== undefined && { targets: prop.targets as readonly string[] }),\n ...(prop.morphName !== undefined && { morphName: prop.morphName as string }),\n ...(prop.onDelete !== undefined && { onDelete: prop.onDelete as string }),\n ...(prop.onUpdate !== undefined && { onUpdate: prop.onUpdate as string }),\n ...(prop.mappedBy !== undefined && { mappedBy: prop.mappedBy as string }),\n ...(prop.inversedBy !== undefined && { inversedBy: prop.inversedBy as string }),\n ...(prop.joinTable !== undefined && { joinTable: prop.joinTable as string }),\n ...(prop.owning !== undefined && { owning: prop.owning as boolean }),\n };\n}\n\n/**\n * Convert loaded schemas to version snapshot format.\n */\nfunction schemasToSnapshot(\n schemas: Record<string, { name: string; kind?: string; properties?: Record<string, unknown>; options?: Record<string, unknown>; values?: readonly string[] }>\n): Record<string, VersionSchemaSnapshot> {\n const snapshot: Record<string, VersionSchemaSnapshot> = {};\n\n for (const [name, schema] of Object.entries(schemas)) {\n const properties: Record<string, VersionPropertySnapshot> = {};\n if (schema.properties) {\n for (const [propName, prop] of Object.entries(schema.properties)) {\n properties[propName] = propertyToSnapshot(prop as Record<string, unknown>);\n }\n }\n\n const opts = schema.options as Record<string, unknown> | undefined;\n snapshot[name] = {\n name: schema.name,\n kind: (schema.kind ?? 'object') as 'object' | 'enum',\n ...(Object.keys(properties).length > 0 && { properties }),\n ...(schema.values && { values: schema.values }),\n ...(opts && {\n options: {\n ...(opts.id !== undefined && { id: opts.id as boolean }),\n ...(opts.idType !== undefined && { idType: opts.idType as string }),\n ...(opts.timestamps !== undefined && { timestamps: opts.timestamps as boolean }),\n ...(opts.softDelete !== undefined && { softDelete: opts.softDelete as boolean }),\n ...(opts.tableName !== undefined && { tableName: opts.tableName as string }),\n ...(opts.translations !== undefined && { translations: opts.translations as boolean }),\n ...(opts.authenticatable !== undefined && { authenticatable: opts.authenticatable as boolean }),\n },\n }),\n };\n }\n\n return snapshot;\n}\n\n/**\n * Result of computing pending changes.\n */\nexport interface PendingChangesResult {\n hasChanges: boolean;\n changes: readonly VersionChange[];\n currentSchemaCount: number;\n previousSchemaCount: number;\n latestVersion: number | null;\n}\n\n/**\n * Get pending changes (current schemas vs latest version).\n */\nexport async function getPendingChanges(): Promise<PendingChangesResult> {\n if (!schemasDir) {\n throw new Error('Schemas directory not initialized');\n }\n\n const storeInstance = getStore();\n\n // Load current schemas\n const currentSchemas = await loadSchemas(schemasDir);\n const currentSnapshot = schemasToSnapshot(currentSchemas);\n\n // Get latest version\n const latestVersion = await storeInstance.readLatestVersion();\n\n if (!latestVersion) {\n // No previous version, all schemas are new\n const changes: VersionChange[] = Object.keys(currentSnapshot).map((name) => ({\n action: 'schema_added' as const,\n schema: name,\n }));\n\n return {\n hasChanges: changes.length > 0,\n changes,\n currentSchemaCount: Object.keys(currentSnapshot).length,\n previousSchemaCount: 0,\n latestVersion: null,\n };\n }\n\n // Compute diff from latest version to current\n const changes = storeInstance.computeSnapshotDiff(latestVersion.snapshot, currentSnapshot);\n\n return {\n hasChanges: changes.length > 0,\n changes,\n currentSchemaCount: Object.keys(currentSnapshot).length,\n previousSchemaCount: Object.keys(latestVersion.snapshot).length,\n latestVersion: latestVersion.version,\n };\n}\n","/**\n * WebSocket handler for real-time updates\n */\n\nimport { WebSocketServer, WebSocket } from 'ws';\nimport type { Server } from 'http';\nimport type { ServerEvent, ClientEvent } from '../../shared/events.js';\n\nexport interface WsHandler {\n broadcast: (event: ServerEvent) => void;\n close: () => void;\n}\n\nexport function createWsHandler(server: Server): WsHandler {\n const wss = new WebSocketServer({ server, path: '/ws' });\n const clients = new Set<WebSocket>();\n\n wss.on('connection', (ws: WebSocket) => {\n clients.add(ws);\n console.log(' WebSocket client connected');\n\n // Send ready event\n const readyEvent: ServerEvent = {\n type: 'connection:ready',\n payload: {\n schemasDir: process.env.SCHEMAS_DIR ?? 'schemas',\n schemaCount: 0,\n },\n };\n ws.send(JSON.stringify(readyEvent));\n\n ws.on('message', (data: Buffer) => {\n try {\n const event = JSON.parse(data.toString()) as ClientEvent;\n handleClientEvent(event, ws);\n } catch {\n console.error('Invalid WebSocket message');\n }\n });\n\n ws.on('close', () => {\n clients.delete(ws);\n console.log(' WebSocket client disconnected');\n });\n\n ws.on('error', (error: Error) => {\n console.error('WebSocket error:', error);\n clients.delete(ws);\n });\n });\n\n function handleClientEvent(_event: ClientEvent, _ws: WebSocket): void {\n // Handle client events (save, validate requests)\n // These are handled by the REST API, but could be used for\n // real-time validation feedback\n }\n\n function broadcast(event: ServerEvent): void {\n const message = JSON.stringify(event);\n for (const client of clients) {\n if (client.readyState === WebSocket.OPEN) {\n client.send(message);\n }\n }\n }\n\n function close(): void {\n for (const client of clients) {\n client.close();\n }\n wss.close();\n }\n\n return { broadcast, close };\n}\n","/**\n * File system watcher for schema changes\n */\n\nimport chokidar from 'chokidar';\nimport { basename } from 'path';\nimport { schemaService } from '../services/schemaService.js';\nimport type { WsHandler } from '../ws/handler.js';\nimport type { ServerEvent } from '../../shared/events.js';\n\nexport interface FileWatcher {\n close: () => void;\n}\n\nexport function createFileWatcher(schemasDir: string, wsHandler: WsHandler): FileWatcher {\n const watcher = chokidar.watch(`${schemasDir}/*.yaml`, {\n persistent: true,\n ignoreInitial: true,\n awaitWriteFinish: {\n stabilityThreshold: 200,\n pollInterval: 100,\n },\n });\n\n watcher.on('add', (filePath: string) => {\n console.log(` Schema added: ${basename(filePath)}`);\n void notifySchemaChange(filePath, 'file');\n });\n\n watcher.on('change', (filePath: string) => {\n console.log(` Schema changed: ${basename(filePath)}`);\n void notifySchemaChange(filePath, 'file');\n });\n\n watcher.on('unlink', (filePath: string) => {\n console.log(` Schema deleted: ${basename(filePath)}`);\n void notifyReload();\n });\n\n async function notifySchemaChange(\n filePath: string,\n source: 'file' | 'editor'\n ): Promise<void> {\n try {\n // Clear cache and reload\n schemaService.clearCache(schemasDir);\n const schemas = await schemaService.loadAll(schemasDir);\n\n // Find the changed schema\n const name = basename(filePath, '.yaml');\n const schema = schemas[name];\n\n if (schema) {\n const event: ServerEvent = {\n type: 'schema:changed',\n payload: { name, schema, source },\n };\n wsHandler.broadcast(event);\n }\n } catch (error) {\n console.error('Error notifying schema change:', error);\n }\n }\n\n async function notifyReload(): Promise<void> {\n try {\n schemaService.clearCache(schemasDir);\n const schemas = await schemaService.loadAll(schemasDir);\n\n const event: ServerEvent = {\n type: 'schemas:reloaded',\n payload: { schemas },\n };\n wsHandler.broadcast(event);\n } catch (error) {\n console.error('Error notifying reload:', error);\n }\n }\n\n return {\n close: () => watcher.close(),\n };\n}\n"],"mappings":"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","names":["join","join","schemasDir","response","Router","loadSchemas","schemasDir","Router","Router","loadSchemas","schemasDir","Router","response","Router","Router","Router","loadSchemas","loadSchemas","changes","Router","response","join","schemasDir","schemasDir","join"]}
1
+ {"version":3,"sources":["../../src/server/index.ts","../../src/server/app.ts","../../src/server/api/schemas.ts","../../src/server/services/schemaService.ts","../../src/server/api/validate.ts","../../src/server/services/validationService.ts","../../src/server/api/preview.ts","../../src/server/services/previewService.ts","../../src/server/api/config.ts","../../src/shared/constants.ts","../../src/server/api/versions.ts","../../src/server/services/versionService.ts","../../src/server/ws/handler.ts","../../src/server/watcher/fileWatcher.ts"],"sourcesContent":["/**\n * @famgia/omnify-gui - Server Entry Point\n *\n * Starts the local development server for Omnify GUI.\n */\n\nimport { createServer } from 'http';\nimport { join, resolve } from 'path';\nimport open from 'open';\nimport { loadConfig } from '@famgia/omnify-cli';\nimport { createApp } from './app.js';\nimport { createWsHandler } from './ws/handler.js';\nimport { createFileWatcher } from './watcher/fileWatcher.js';\nimport { DEFAULT_PORT, DEFAULT_HOST } from '../shared/constants.js';\n\n// fileURLToPath and dirname imported for potential future use with static files\n// Currently not needed as Vite handles static serving\n\nasync function main(): Promise<void> {\n const port = Number(process.env.PORT) || DEFAULT_PORT;\n const host = process.env.HOST ?? DEFAULT_HOST;\n const cwd = process.cwd();\n\n // Resolve schemas directory from omnify config or environment variable\n let schemasDir: string;\n\n if (process.env.SCHEMAS_DIR) {\n schemasDir = process.env.SCHEMAS_DIR;\n } else {\n try {\n const { config } = await loadConfig(cwd);\n schemasDir = resolve(cwd, config.schemasDir);\n } catch {\n // Fall back to default if no config file found\n schemasDir = join(cwd, 'schemas');\n }\n }\n\n console.log('Starting Omnify GUI...');\n console.log(` Schemas directory: ${schemasDir}`);\n\n // Create Express app\n const app = createApp({ schemasDir, cwd });\n\n // Create HTTP server\n const server = createServer(app);\n\n // Create WebSocket handler\n const wsHandler = createWsHandler(server);\n\n // Create file watcher\n const watcher = createFileWatcher(schemasDir, wsHandler);\n\n // Start server\n server.listen(port, host, () => {\n const url = `http://${host}:${port}`;\n console.log(` GUI running at: ${url}`);\n console.log(' Press Ctrl+C to stop\\n');\n\n // Auto-open browser in development\n if (process.env.NODE_ENV !== 'production') {\n open(url).catch(() => {\n // Ignore errors if browser fails to open\n });\n }\n });\n\n // Graceful shutdown\n const shutdown = (): void => {\n console.log('\\nShutting down...');\n watcher.close();\n wsHandler.close();\n server.close(() => {\n console.log('Server closed');\n process.exit(0);\n });\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n\nmain().catch((error: unknown) => {\n console.error('Failed to start server:', error);\n process.exit(1);\n});\n","/**\n * Express application configuration\n */\n\nimport express, { type Express, type Request, type Response, type NextFunction } from 'express';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport { schemasRouter } from './api/schemas.js';\nimport { validateRouter } from './api/validate.js';\nimport { previewRouter } from './api/preview.js';\nimport { configRouter } from './api/config.js';\nimport { versionsRouter } from './api/versions.js';\nimport { initVersionStore } from './services/versionService.js';\nimport type { ApiResponse } from '../shared/types.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport interface AppConfig {\n schemasDir: string;\n cwd: string;\n}\n\nexport function createApp(config: AppConfig): Express {\n const app = express();\n\n // Store config in app locals for access in routes\n app.locals.config = config;\n\n // Initialize version store with project root and schemas directory\n initVersionStore(config.cwd, config.schemasDir);\n\n // Middleware\n app.use(express.json());\n\n // API routes\n app.use('/api/schemas', schemasRouter);\n app.use('/api/validate', validateRouter);\n app.use('/api/preview', previewRouter);\n app.use('/api/config', configRouter);\n app.use('/api/versions', versionsRouter);\n\n // Serve static files (client build)\n const clientDist = join(__dirname, '../client');\n app.use(express.static(clientDist));\n\n // SPA fallback - serve index.html for all non-API routes\n app.get('*', (_req: Request, res: Response) => {\n res.sendFile(join(clientDist, 'index.html'));\n });\n\n // Error handler\n app.use((err: Error, _req: Request, res: Response, _next: NextFunction) => {\n console.error('Server error:', err);\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'INTERNAL_ERROR',\n message: err.message,\n },\n };\n res.status(500).json(response);\n });\n\n return app;\n}\n","/**\n * Schema CRUD API routes\n */\n\nimport { Router, type Request, type Response, type IRouter } from 'express';\nimport { schemaService } from '../services/schemaService.js';\nimport type { ApiResponse, GuiSchema } from '../../shared/types.js';\nimport type { AppConfig } from '../app.js';\n\nexport const schemasRouter: IRouter = Router();\n\n// GET /api/schemas - List all schemas\nschemasRouter.get('/', async (req: Request, res: Response) => {\n try {\n const config = req.app.locals.config as AppConfig;\n const schemas = await schemaService.loadAll(config.schemasDir);\n const response: ApiResponse<Record<string, GuiSchema>> = {\n success: true,\n data: schemas,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'LOAD_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n\n// GET /api/schemas/:name - Get single schema\nschemasRouter.get('/:name', async (req: Request, res: Response) => {\n try {\n const config = req.app.locals.config as AppConfig;\n const { name } = req.params;\n const schema = await schemaService.load(config.schemasDir, name!);\n\n if (!schema) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'NOT_FOUND',\n message: `Schema \"${name}\" not found`,\n },\n };\n res.status(404).json(response);\n return;\n }\n\n const response: ApiResponse<GuiSchema> = {\n success: true,\n data: schema,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'LOAD_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n\n// POST /api/schemas - Create new schema\nschemasRouter.post('/', async (req: Request, res: Response) => {\n try {\n const config = req.app.locals.config as AppConfig;\n const schema = req.body as GuiSchema;\n\n if (!schema.name) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'VALIDATION_ERROR',\n message: 'Schema name is required',\n },\n };\n res.status(400).json(response);\n return;\n }\n\n const saved = await schemaService.save(config.schemasDir, schema);\n const response: ApiResponse<GuiSchema> = {\n success: true,\n data: saved,\n };\n res.status(201).json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'SAVE_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n\n// PUT /api/schemas/:name - Update schema\nschemasRouter.put('/:name', async (req: Request, res: Response) => {\n try {\n const config = req.app.locals.config as AppConfig;\n const { name } = req.params;\n const schema = req.body as GuiSchema;\n\n // Ensure name matches\n schema.name = name!;\n\n const saved = await schemaService.save(config.schemasDir, schema);\n const response: ApiResponse<GuiSchema> = {\n success: true,\n data: saved,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'SAVE_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n\n// DELETE /api/schemas/:name - Delete schema\nschemasRouter.delete('/:name', async (req: Request, res: Response) => {\n try {\n const config = req.app.locals.config as AppConfig;\n const { name } = req.params;\n\n await schemaService.delete(config.schemasDir, name!);\n const response: ApiResponse = {\n success: true,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'DELETE_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n","/**\n * Schema CRUD service using omnify-core\n */\n\nimport { loadSchemas } from '@famgia/omnify-core';\nimport { writeFile, unlink } from 'fs/promises';\nimport { join } from 'path';\nimport { stringify } from 'yaml';\nimport type { GuiSchema, GuiEnumValue } from '../../shared/types.js';\n\n/**\n * Convert enum values from various formats to GuiEnumValue[]\n */\nfunction normalizeEnumValues(values: unknown): GuiEnumValue[] | undefined {\n if (!values || !Array.isArray(values)) return undefined;\n\n return values.map((v) => {\n // Already an object with value property\n if (typeof v === 'object' && v !== null && 'value' in v) {\n const obj = v as Record<string, unknown>;\n return {\n value: String(obj.value),\n label: obj.label ? String(obj.label) : undefined,\n extra: obj.extra as GuiEnumValue['extra'],\n };\n }\n // Simple string value\n return { value: String(v) };\n });\n}\n\nclass SchemaService {\n private cache: Map<string, Record<string, GuiSchema>> = new Map();\n\n async loadAll(schemasDir: string): Promise<Record<string, GuiSchema>> {\n try {\n const schemas = await loadSchemas(schemasDir);\n const guiSchemas: Record<string, GuiSchema> = {};\n\n for (const [name, schema] of Object.entries(schemas)) {\n guiSchemas[name] = {\n name: schema.name,\n kind: schema.kind ?? 'object',\n displayName: schema.displayName,\n filePath: schema.filePath,\n relativePath: schema.relativePath,\n properties: schema.properties as GuiSchema['properties'],\n options: schema.options as GuiSchema['options'],\n values: normalizeEnumValues(schema.values),\n isDirty: false,\n validationErrors: [],\n };\n }\n\n this.cache.set(schemasDir, guiSchemas);\n return guiSchemas;\n } catch (error) {\n // Return empty if no schemas found\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return {};\n }\n throw error;\n }\n }\n\n async load(schemasDir: string, name: string): Promise<GuiSchema | null> {\n const schemas = await this.loadAll(schemasDir);\n return schemas[name] ?? null;\n }\n\n async save(schemasDir: string, schema: GuiSchema): Promise<GuiSchema> {\n const { isDirty: _isDirty, validationErrors: _validationErrors, filePath: _filePath, ...schemaData } = schema;\n const fileName = `${schema.name}.yaml`;\n const targetPath = join(schemasDir, fileName);\n\n // Convert to YAML\n const yamlContent = stringify(schemaData, {\n lineWidth: 120,\n defaultKeyType: 'PLAIN',\n defaultStringType: 'PLAIN',\n });\n\n await writeFile(targetPath, yamlContent, 'utf-8');\n\n // Return updated schema with file path\n return {\n ...schemaData,\n filePath: targetPath,\n isDirty: false,\n validationErrors: [],\n };\n }\n\n async delete(schemasDir: string, name: string): Promise<void> {\n const fileName = `${name}.yaml`;\n const targetPath = join(schemasDir, fileName);\n await unlink(targetPath);\n\n // Clear cache\n this.cache.delete(schemasDir);\n }\n\n clearCache(schemasDir?: string): void {\n if (schemasDir) {\n this.cache.delete(schemasDir);\n } else {\n this.cache.clear();\n }\n }\n}\n\nexport const schemaService = new SchemaService();\n","/**\n * Schema validation API routes\n */\n\nimport { Router, type Request, type Response, type IRouter } from 'express';\nimport { validationService } from '../services/validationService.js';\nimport type { ApiResponse, GuiSchema, ValidationError } from '../../shared/types.js';\nimport type { AppConfig } from '../app.js';\n\nexport const validateRouter: IRouter = Router();\n\ninterface ValidateRequest {\n schema?: GuiSchema;\n schemas?: Record<string, GuiSchema>;\n}\n\ninterface ValidateResult {\n valid: boolean;\n errors: ValidationError[];\n}\n\n// POST /api/validate - Validate schema(s)\nvalidateRouter.post('/', async (req: Request, res: Response) => {\n try {\n const config = req.app.locals.config as AppConfig;\n const body = req.body as ValidateRequest;\n\n let result: ValidateResult;\n\n if (body.schema) {\n // Validate single schema\n result = await validationService.validateSchema(body.schema, config.schemasDir);\n } else if (body.schemas) {\n // Validate all schemas\n result = await validationService.validateAll(body.schemas);\n } else {\n // Load and validate all from disk\n result = await validationService.validateFromDisk(config.schemasDir);\n }\n\n const response: ApiResponse<ValidateResult> = {\n success: true,\n data: result,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'VALIDATION_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n","/**\n * Schema validation service using omnify-core\n */\n\nimport { loadSchemas, validateSchemas, OmnifyError } from '@famgia/omnify-core';\nimport type { LoadedSchema, SchemaCollection, SchemaOptions } from '@famgia/omnify-types';\nimport type { GuiSchema, ValidationError } from '../../shared/types.js';\n\ninterface ValidateResult {\n valid: boolean;\n errors: ValidationError[];\n}\n\n/**\n * Convert GuiSchema to LoadedSchema format\n * Handles exactOptionalPropertyTypes by only setting defined properties\n */\nfunction toLoadedSchema(schema: GuiSchema): LoadedSchema {\n // Start with required fields only\n const result = {\n name: schema.name,\n kind: schema.kind,\n filePath: schema.filePath,\n relativePath: schema.relativePath ?? schema.name + '.yaml',\n } as LoadedSchema;\n\n // Only add optional fields if they're defined\n if (schema.displayName !== undefined) {\n (result as { displayName: string }).displayName = schema.displayName;\n }\n if (schema.properties !== undefined) {\n (result as { properties: LoadedSchema['properties'] }).properties = schema.properties as LoadedSchema['properties'];\n }\n if (schema.options !== undefined) {\n (result as { options: SchemaOptions }).options = schema.options as SchemaOptions;\n }\n if (schema.values !== undefined) {\n (result as { values: readonly string[] }).values = schema.values;\n }\n\n return result;\n}\n\nclass ValidationService {\n async validateSchema(schema: GuiSchema, schemasDir: string): Promise<ValidateResult> {\n try {\n // Load all schemas to validate references\n const allSchemas = await loadSchemas(schemasDir);\n\n // Convert GuiSchema to LoadedSchema format\n const loadedSchema = toLoadedSchema(schema);\n\n // Create mutable copy and add the schema\n const schemasToValidate: Record<string, LoadedSchema> = { ...allSchemas };\n schemasToValidate[schema.name] = loadedSchema;\n\n // Validate all schemas together\n const result = validateSchemas(schemasToValidate);\n\n // Filter errors for this schema from schema results\n const schemaResult = result.schemas.find((s) => s.schemaName === schema.name);\n const schemaErrors: ValidationError[] = [];\n\n if (schemaResult) {\n for (const e of schemaResult.errors) {\n schemaErrors.push({\n path: this.getErrorPath(e, schema.name),\n message: e.message,\n severity: 'error' as const,\n });\n }\n }\n\n return {\n valid: schemaErrors.length === 0,\n errors: schemaErrors,\n };\n } catch (error) {\n return {\n valid: false,\n errors: [\n {\n path: schema.name,\n message: (error as Error).message,\n severity: 'error',\n },\n ],\n };\n }\n }\n\n async validateAll(schemas: Record<string, GuiSchema>): Promise<ValidateResult> {\n try {\n // Convert GuiSchemas to LoadedSchemas\n const loadedSchemas: SchemaCollection = {};\n for (const [name, schema] of Object.entries(schemas)) {\n (loadedSchemas as Record<string, LoadedSchema>)[name] = toLoadedSchema(schema);\n }\n\n const result = validateSchemas(loadedSchemas);\n\n const errors: ValidationError[] = [];\n for (const schemaResult of result.schemas) {\n for (const e of schemaResult.errors) {\n errors.push({\n path: this.getErrorPath(e, schemaResult.schemaName),\n message: e.message,\n severity: 'error' as const,\n });\n }\n }\n\n return {\n valid: result.valid,\n errors,\n };\n } catch (error) {\n return {\n valid: false,\n errors: [\n {\n path: 'root',\n message: (error as Error).message,\n severity: 'error',\n },\n ],\n };\n }\n }\n\n async validateFromDisk(schemasDir: string): Promise<ValidateResult> {\n try {\n const schemas = await loadSchemas(schemasDir);\n\n // Convert to GuiSchemas\n const guiSchemas: Record<string, GuiSchema> = {};\n for (const [name, schema] of Object.entries(schemas)) {\n guiSchemas[name] = {\n name: schema.name,\n kind: schema.kind ?? 'object',\n displayName: schema.displayName,\n filePath: schema.filePath,\n relativePath: schema.relativePath,\n properties: schema.properties as GuiSchema['properties'],\n options: schema.options as GuiSchema['options'],\n values: schema.values,\n };\n }\n\n return this.validateAll(guiSchemas);\n } catch (error) {\n return {\n valid: false,\n errors: [\n {\n path: 'root',\n message: (error as Error).message,\n severity: 'error',\n },\n ],\n };\n }\n }\n\n private getErrorPath(error: OmnifyError, schemaName: string): string {\n // Try to extract property name from the error message or details\n const details = error.details;\n if (details && 'propertyName' in details && details.propertyName) {\n return `${schemaName}.${String(details.propertyName)}`;\n }\n return schemaName;\n }\n}\n\nexport const validationService = new ValidationService();\n","/**\n * Code preview API routes\n */\n\nimport { Router, type Request, type Response, type IRouter } from 'express';\nimport { previewService } from '../services/previewService.js';\nimport type { ApiResponse, PreviewResult, PreviewType } from '../../shared/types.js';\nimport type { AppConfig } from '../app.js';\n\nexport const previewRouter: IRouter = Router();\n\n// GET /api/preview/:type - Get code preview for all schemas\npreviewRouter.get('/:type', async (req: Request, res: Response) => {\n try {\n const config = req.app.locals.config as AppConfig;\n const { type } = req.params;\n\n if (!['laravel', 'typescript', 'sql'].includes(type!)) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'INVALID_TYPE',\n message: `Invalid preview type: ${type}. Valid types: laravel, typescript, sql`,\n },\n };\n res.status(400).json(response);\n return;\n }\n\n const previews = await previewService.generateAll(config.schemasDir, type as PreviewType);\n const response: ApiResponse<PreviewResult[]> = {\n success: true,\n data: previews,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'PREVIEW_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n\n// GET /api/preview/:type/:name - Get code preview for single schema\npreviewRouter.get('/:type/:name', async (req: Request, res: Response) => {\n try {\n const config = req.app.locals.config as AppConfig;\n const { type, name } = req.params;\n\n if (!['laravel', 'typescript', 'sql'].includes(type!)) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'INVALID_TYPE',\n message: `Invalid preview type: ${type}. Valid types: laravel, typescript, sql`,\n },\n };\n res.status(400).json(response);\n return;\n }\n\n const preview = await previewService.generateForSchema(\n config.schemasDir,\n name!,\n type as PreviewType\n );\n\n if (!preview) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'NOT_FOUND',\n message: `Schema \"${name}\" not found`,\n },\n };\n res.status(404).json(response);\n return;\n }\n\n const response: ApiResponse<PreviewResult> = {\n success: true,\n data: preview,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'PREVIEW_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n","/**\n * Code preview generation service\n */\n\nimport { loadSchemas } from '@famgia/omnify-core';\nimport { generateMigrations as generateLaravelMigrations } from '@famgia/omnify-laravel';\nimport { generateMigrations as generateSqlMigrations } from '@famgia/omnify-sql';\nimport type { PreviewResult, PreviewType } from '../../shared/types.js';\n\ninterface EnumSchema {\n kind: 'enum';\n values?: readonly string[];\n}\n\ninterface ObjectSchema {\n kind: 'object';\n properties?: Record<string, { type: string; nullable?: boolean }>;\n}\n\nclass PreviewService {\n async generateAll(schemasDir: string, type: PreviewType): Promise<PreviewResult[]> {\n const schemas = await loadSchemas(schemasDir);\n const previews: PreviewResult[] = [];\n\n switch (type) {\n case 'laravel': {\n const migrations = await generateLaravelMigrations(schemas);\n for (const migration of migrations) {\n previews.push({\n type: 'laravel',\n content: migration.content,\n fileName: migration.fileName,\n });\n }\n break;\n }\n\n case 'sql': {\n const migrations = generateSqlMigrations(schemas, { dialect: 'mysql' });\n for (const migration of migrations) {\n previews.push({\n type: 'sql',\n content: migration.content,\n fileName: migration.fileName,\n });\n }\n break;\n }\n\n case 'typescript': {\n // Generate TypeScript interfaces from schemas\n for (const [name, schema] of Object.entries(schemas)) {\n if (schema.kind === 'enum') {\n previews.push({\n type: 'typescript',\n content: this.generateEnumType(name, schema as EnumSchema),\n fileName: `${name}.ts`,\n });\n } else {\n previews.push({\n type: 'typescript',\n content: this.generateInterfaceType(name, schema as ObjectSchema),\n fileName: `${name}.ts`,\n });\n }\n }\n break;\n }\n }\n\n return previews;\n }\n\n async generateForSchema(\n schemasDir: string,\n schemaName: string,\n type: PreviewType\n ): Promise<PreviewResult | null> {\n const schemas = await loadSchemas(schemasDir);\n const schema = schemas[schemaName];\n\n if (!schema) {\n return null;\n }\n\n switch (type) {\n case 'laravel': {\n const migrations = await generateLaravelMigrations({ [schemaName]: schema });\n const migration = migrations[0];\n return migration\n ? {\n type: 'laravel',\n content: migration.content,\n fileName: migration.fileName,\n }\n : null;\n }\n\n case 'sql': {\n const migrations = generateSqlMigrations({ [schemaName]: schema }, { dialect: 'mysql' });\n const migration = migrations[0];\n return migration\n ? {\n type: 'sql',\n content: migration.content,\n fileName: migration.fileName,\n }\n : null;\n }\n\n case 'typescript': {\n if (schema.kind === 'enum') {\n return {\n type: 'typescript',\n content: this.generateEnumType(schemaName, schema as EnumSchema),\n fileName: `${schemaName}.ts`,\n };\n }\n return {\n type: 'typescript',\n content: this.generateInterfaceType(schemaName, schema as ObjectSchema),\n fileName: `${schemaName}.ts`,\n };\n }\n }\n }\n\n private generateEnumType(name: string, schema: EnumSchema): string {\n const values = schema.values ?? [];\n return `export type ${name} = ${values.map((v) => `'${v}'`).join(' | ') || 'never'};\\n`;\n }\n\n private generateInterfaceType(name: string, schema: ObjectSchema): string {\n const lines: string[] = [`export interface ${name} {`];\n\n if (schema.properties) {\n for (const [propName, prop] of Object.entries(schema.properties)) {\n const tsType = this.mapToTsType(prop.type);\n const optional = prop.nullable ? '?' : '';\n lines.push(` ${propName}${optional}: ${tsType};`);\n }\n }\n\n lines.push('}');\n return lines.join('\\n') + '\\n';\n }\n\n private mapToTsType(omnifyType: string): string {\n const typeMap: Record<string, string> = {\n String: 'string',\n Int: 'number',\n BigInt: 'number',\n Float: 'number',\n Decimal: 'number',\n Boolean: 'boolean',\n Text: 'string',\n LongText: 'string',\n Date: 'string',\n Time: 'string',\n Timestamp: 'string',\n Json: 'Record<string, unknown>',\n Email: 'string',\n Password: 'string',\n File: 'string',\n MultiFile: 'string[]',\n Point: '{ lat: number; lng: number }',\n Coordinates: '{ latitude: number; longitude: number }',\n };\n\n return typeMap[omnifyType] ?? 'unknown';\n }\n}\n\nexport const previewService = new PreviewService();\n","/**\n * Config API routes\n */\n\nimport { Router, type Request, type Response, type IRouter } from 'express';\nimport type { ApiResponse, GuiConfig } from '../../shared/types.js';\nimport type { AppConfig } from '../app.js';\nimport { DEFAULT_PORT, DEFAULT_HOST } from '../../shared/constants.js';\n\nexport const configRouter: IRouter = Router();\n\n// GET /api/config - Get current configuration\nconfigRouter.get('/', (req: Request, res: Response) => {\n const appConfig = req.app.locals.config as AppConfig;\n\n const config: GuiConfig = {\n schemasDir: appConfig.schemasDir,\n port: Number(process.env.PORT) || DEFAULT_PORT,\n host: process.env.HOST ?? DEFAULT_HOST,\n };\n\n const response: ApiResponse<GuiConfig> = {\n success: true,\n data: config,\n };\n res.json(response);\n});\n","/**\n * Shared constants for @famgia/omnify-gui\n */\n\nexport const DEFAULT_PORT = 3456;\nexport const DEFAULT_HOST = 'localhost';\n\nexport const API_ROUTES = {\n SCHEMAS: '/api/schemas',\n SCHEMA: '/api/schemas/:name',\n VALIDATE: '/api/validate',\n PREVIEW: '/api/preview/:type',\n CONFIG: '/api/config',\n} as const;\n\nexport const WS_EVENTS = {\n // Server → Client\n SCHEMA_CHANGED: 'schema:changed',\n SCHEMA_VALIDATED: 'schema:validated',\n SCHEMAS_RELOADED: 'schemas:reloaded',\n CONNECTION_READY: 'connection:ready',\n\n // Client → Server\n SCHEMA_SAVE: 'schema:save',\n SCHEMA_VALIDATE: 'schema:validate',\n} as const;\n\nexport const PROPERTY_TYPES = [\n 'String',\n 'Int',\n 'BigInt',\n 'Float',\n 'Decimal',\n 'Boolean',\n 'Text',\n 'LongText',\n 'Date',\n 'Time',\n 'Timestamp',\n 'Json',\n 'Email',\n 'Password',\n 'File',\n 'MultiFile',\n 'Point',\n 'Coordinates',\n 'Enum',\n 'Select',\n 'Lookup',\n] as const;\n\nexport const RELATION_TYPES = [\n 'OneToOne',\n 'OneToMany',\n 'ManyToOne',\n 'ManyToMany',\n] as const;\n\nexport const POLYMORPHIC_RELATION_TYPES = [\n 'MorphTo',\n 'MorphOne',\n 'MorphMany',\n 'MorphToMany',\n 'MorphedByMany',\n] as const;\n\nexport const REFERENTIAL_ACTIONS = [\n 'CASCADE',\n 'SET NULL',\n 'SET DEFAULT',\n 'RESTRICT',\n 'NO ACTION',\n] as const;\n","/**\n * Version history API routes\n */\n\nimport { Router, type Request, type Response, type Router as RouterType } from 'express';\nimport type { ApiResponse } from '../../shared/types.js';\nimport {\n listVersions,\n getVersion,\n getLatestVersion,\n diffVersions,\n getPendingChanges,\n type PendingChangesResult,\n} from '../services/versionService.js';\nimport type { VersionSummary, VersionFile, VersionDiff } from '@famgia/omnify-core';\n\nexport const versionsRouter: RouterType = Router();\n\n/**\n * GET /api/versions - List all versions\n */\nversionsRouter.get('/', async (_req: Request, res: Response) => {\n try {\n const versions = await listVersions();\n const response: ApiResponse<VersionSummary[]> = {\n success: true,\n data: versions,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'VERSION_LIST_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n\n/**\n * GET /api/versions/pending - Get pending changes (current vs latest)\n */\nversionsRouter.get('/pending', async (_req: Request, res: Response) => {\n try {\n const pending = await getPendingChanges();\n const response: ApiResponse<PendingChangesResult> = {\n success: true,\n data: pending,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'PENDING_CHANGES_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n\n/**\n * GET /api/versions/latest - Get latest version\n */\nversionsRouter.get('/latest', async (_req: Request, res: Response) => {\n try {\n const version = await getLatestVersion();\n const response: ApiResponse<VersionFile | null> = {\n success: true,\n data: version,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'VERSION_READ_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n\n/**\n * GET /api/versions/:version - Get specific version\n */\nversionsRouter.get('/:version', async (req: Request, res: Response) => {\n try {\n const versionNum = parseInt(req.params.version, 10);\n if (isNaN(versionNum)) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'INVALID_VERSION',\n message: 'Version must be a number',\n },\n };\n res.status(400).json(response);\n return;\n }\n\n const version = await getVersion(versionNum);\n if (!version) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'VERSION_NOT_FOUND',\n message: `Version ${versionNum} not found`,\n },\n };\n res.status(404).json(response);\n return;\n }\n\n const response: ApiResponse<VersionFile> = {\n success: true,\n data: version,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'VERSION_READ_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n\n/**\n * GET /api/versions/diff/:from/:to - Get diff between versions\n */\nversionsRouter.get('/diff/:from/:to', async (req: Request, res: Response) => {\n try {\n const fromVersion = parseInt(req.params.from, 10);\n const toVersion = parseInt(req.params.to, 10);\n\n if (isNaN(fromVersion) || isNaN(toVersion)) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'INVALID_VERSION',\n message: 'Version numbers must be integers',\n },\n };\n res.status(400).json(response);\n return;\n }\n\n const diff = await diffVersions(fromVersion, toVersion);\n if (!diff) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'DIFF_ERROR',\n message: 'Could not compute diff. One or both versions may not exist.',\n },\n };\n res.status(404).json(response);\n return;\n }\n\n const response: ApiResponse<VersionDiff> = {\n success: true,\n data: diff,\n };\n res.json(response);\n } catch (error) {\n const response: ApiResponse = {\n success: false,\n error: {\n code: 'DIFF_ERROR',\n message: (error as Error).message,\n },\n };\n res.status(500).json(response);\n }\n});\n","/**\n * Version history service for GUI\n */\n\nimport { loadSchemas } from '@famgia/omnify-core';\nimport {\n createVersionStore,\n type VersionStore,\n type VersionSummary,\n type VersionFile,\n type VersionDiff,\n type VersionChange,\n type VersionSchemaSnapshot,\n type VersionPropertySnapshot,\n} from '@famgia/omnify-core';\n\nlet store: VersionStore | null = null;\nlet schemasDir: string | null = null;\n\n/**\n * Initialize the version store with the project base directory.\n */\nexport function initVersionStore(baseDir: string, schemasDirPath: string): void {\n store = createVersionStore({ baseDir, maxVersions: 100 });\n schemasDir = schemasDirPath;\n}\n\n/**\n * Get the version store instance.\n */\nfunction getStore(): VersionStore {\n if (!store) {\n throw new Error('Version store not initialized. Call initVersionStore first.');\n }\n return store;\n}\n\n/**\n * List all versions.\n */\nexport async function listVersions(): Promise<VersionSummary[]> {\n return getStore().listVersions();\n}\n\n/**\n * Get a specific version.\n */\nexport async function getVersion(version: number): Promise<VersionFile | null> {\n return getStore().readVersion(version);\n}\n\n/**\n * Get the latest version.\n */\nexport async function getLatestVersion(): Promise<VersionFile | null> {\n return getStore().readLatestVersion();\n}\n\n/**\n * Get diff between two versions.\n */\nexport async function diffVersions(fromVersion: number, toVersion: number): Promise<VersionDiff | null> {\n return getStore().diffVersions(fromVersion, toVersion);\n}\n\n/**\n * Get the version store for direct access.\n */\nexport function getVersionStore(): VersionStore {\n return getStore();\n}\n\n/**\n * Convert property to version snapshot format.\n */\nfunction propertyToSnapshot(prop: Record<string, unknown>): VersionPropertySnapshot {\n return {\n type: prop.type as string,\n ...(prop.displayName !== undefined && { displayName: prop.displayName as string }),\n ...(prop.description !== undefined && { description: prop.description as string }),\n ...(prop.nullable !== undefined && { nullable: prop.nullable as boolean }),\n ...(prop.unique !== undefined && { unique: prop.unique as boolean }),\n ...(prop.default !== undefined && { default: prop.default }),\n ...(prop.length !== undefined && { length: prop.length as number }),\n ...(prop.unsigned !== undefined && { unsigned: prop.unsigned as boolean }),\n ...(prop.precision !== undefined && { precision: prop.precision as number }),\n ...(prop.scale !== undefined && { scale: prop.scale as number }),\n ...(prop.enum !== undefined && { enum: prop.enum as readonly string[] }),\n ...(prop.relation !== undefined && { relation: prop.relation as string }),\n ...(prop.target !== undefined && { target: prop.target as string }),\n ...(prop.targets !== undefined && { targets: prop.targets as readonly string[] }),\n ...(prop.morphName !== undefined && { morphName: prop.morphName as string }),\n ...(prop.onDelete !== undefined && { onDelete: prop.onDelete as string }),\n ...(prop.onUpdate !== undefined && { onUpdate: prop.onUpdate as string }),\n ...(prop.mappedBy !== undefined && { mappedBy: prop.mappedBy as string }),\n ...(prop.inversedBy !== undefined && { inversedBy: prop.inversedBy as string }),\n ...(prop.joinTable !== undefined && { joinTable: prop.joinTable as string }),\n ...(prop.owning !== undefined && { owning: prop.owning as boolean }),\n };\n}\n\n/**\n * Convert loaded schemas to version snapshot format.\n */\nfunction schemasToSnapshot(\n schemas: Record<string, { name: string; kind?: string; properties?: Record<string, unknown>; options?: Record<string, unknown>; values?: readonly string[] }>\n): Record<string, VersionSchemaSnapshot> {\n const snapshot: Record<string, VersionSchemaSnapshot> = {};\n\n for (const [name, schema] of Object.entries(schemas)) {\n const properties: Record<string, VersionPropertySnapshot> = {};\n if (schema.properties) {\n for (const [propName, prop] of Object.entries(schema.properties)) {\n properties[propName] = propertyToSnapshot(prop as Record<string, unknown>);\n }\n }\n\n const opts = schema.options as Record<string, unknown> | undefined;\n snapshot[name] = {\n name: schema.name,\n kind: (schema.kind ?? 'object') as 'object' | 'enum',\n ...(Object.keys(properties).length > 0 && { properties }),\n ...(schema.values && { values: schema.values }),\n ...(opts && {\n options: {\n ...(opts.id !== undefined && { id: opts.id as boolean }),\n ...(opts.idType !== undefined && { idType: opts.idType as string }),\n ...(opts.timestamps !== undefined && { timestamps: opts.timestamps as boolean }),\n ...(opts.softDelete !== undefined && { softDelete: opts.softDelete as boolean }),\n ...(opts.tableName !== undefined && { tableName: opts.tableName as string }),\n ...(opts.translations !== undefined && { translations: opts.translations as boolean }),\n ...(opts.authenticatable !== undefined && { authenticatable: opts.authenticatable as boolean }),\n },\n }),\n };\n }\n\n return snapshot;\n}\n\n/**\n * Result of computing pending changes.\n */\nexport interface PendingChangesResult {\n hasChanges: boolean;\n changes: readonly VersionChange[];\n currentSchemaCount: number;\n previousSchemaCount: number;\n latestVersion: number | null;\n}\n\n/**\n * Get pending changes (current schemas vs latest version).\n */\nexport async function getPendingChanges(): Promise<PendingChangesResult> {\n if (!schemasDir) {\n throw new Error('Schemas directory not initialized');\n }\n\n const storeInstance = getStore();\n\n // Load current schemas\n const currentSchemas = await loadSchemas(schemasDir);\n const currentSnapshot = schemasToSnapshot(currentSchemas);\n\n // Get latest version\n const latestVersion = await storeInstance.readLatestVersion();\n\n if (!latestVersion) {\n // No previous version, all schemas are new\n const changes: VersionChange[] = Object.keys(currentSnapshot).map((name) => ({\n action: 'schema_added' as const,\n schema: name,\n }));\n\n return {\n hasChanges: changes.length > 0,\n changes,\n currentSchemaCount: Object.keys(currentSnapshot).length,\n previousSchemaCount: 0,\n latestVersion: null,\n };\n }\n\n // Compute diff from latest version to current\n const changes = storeInstance.computeSnapshotDiff(latestVersion.snapshot, currentSnapshot);\n\n return {\n hasChanges: changes.length > 0,\n changes,\n currentSchemaCount: Object.keys(currentSnapshot).length,\n previousSchemaCount: Object.keys(latestVersion.snapshot).length,\n latestVersion: latestVersion.version,\n };\n}\n","/**\n * WebSocket handler for real-time updates\n */\n\nimport { WebSocketServer, WebSocket } from 'ws';\nimport type { Server } from 'http';\nimport type { ServerEvent, ClientEvent } from '../../shared/events.js';\n\nexport interface WsHandler {\n broadcast: (event: ServerEvent) => void;\n close: () => void;\n}\n\nexport function createWsHandler(server: Server): WsHandler {\n const wss = new WebSocketServer({ server, path: '/ws' });\n const clients = new Set<WebSocket>();\n\n wss.on('connection', (ws: WebSocket) => {\n clients.add(ws);\n console.log(' WebSocket client connected');\n\n // Send ready event\n const readyEvent: ServerEvent = {\n type: 'connection:ready',\n payload: {\n schemasDir: process.env.SCHEMAS_DIR ?? 'schemas',\n schemaCount: 0,\n },\n };\n ws.send(JSON.stringify(readyEvent));\n\n ws.on('message', (data: Buffer) => {\n try {\n const event = JSON.parse(data.toString()) as ClientEvent;\n handleClientEvent(event, ws);\n } catch {\n console.error('Invalid WebSocket message');\n }\n });\n\n ws.on('close', () => {\n clients.delete(ws);\n console.log(' WebSocket client disconnected');\n });\n\n ws.on('error', (error: Error) => {\n console.error('WebSocket error:', error);\n clients.delete(ws);\n });\n });\n\n function handleClientEvent(_event: ClientEvent, _ws: WebSocket): void {\n // Handle client events (save, validate requests)\n // These are handled by the REST API, but could be used for\n // real-time validation feedback\n }\n\n function broadcast(event: ServerEvent): void {\n const message = JSON.stringify(event);\n for (const client of clients) {\n if (client.readyState === WebSocket.OPEN) {\n client.send(message);\n }\n }\n }\n\n function close(): void {\n for (const client of clients) {\n client.close();\n }\n wss.close();\n }\n\n return { broadcast, close };\n}\n","/**\n * File system watcher for schema changes\n */\n\nimport chokidar from 'chokidar';\nimport { basename } from 'path';\nimport { schemaService } from '../services/schemaService.js';\nimport type { WsHandler } from '../ws/handler.js';\nimport type { ServerEvent } from '../../shared/events.js';\n\nexport interface FileWatcher {\n close: () => void;\n}\n\nexport function createFileWatcher(schemasDir: string, wsHandler: WsHandler): FileWatcher {\n const watcher = chokidar.watch(`${schemasDir}/*.yaml`, {\n persistent: true,\n ignoreInitial: true,\n awaitWriteFinish: {\n stabilityThreshold: 200,\n pollInterval: 100,\n },\n });\n\n watcher.on('add', (filePath: string) => {\n console.log(` Schema added: ${basename(filePath)}`);\n void notifySchemaChange(filePath, 'file');\n });\n\n watcher.on('change', (filePath: string) => {\n console.log(` Schema changed: ${basename(filePath)}`);\n void notifySchemaChange(filePath, 'file');\n });\n\n watcher.on('unlink', (filePath: string) => {\n console.log(` Schema deleted: ${basename(filePath)}`);\n void notifyReload();\n });\n\n async function notifySchemaChange(\n filePath: string,\n source: 'file' | 'editor'\n ): Promise<void> {\n try {\n // Clear cache and reload\n schemaService.clearCache(schemasDir);\n const schemas = await schemaService.loadAll(schemasDir);\n\n // Find the changed schema\n const name = basename(filePath, '.yaml');\n const schema = schemas[name];\n\n if (schema) {\n const event: ServerEvent = {\n type: 'schema:changed',\n payload: { name, schema, source },\n };\n wsHandler.broadcast(event);\n }\n } catch (error) {\n console.error('Error notifying schema change:', error);\n }\n }\n\n async function notifyReload(): Promise<void> {\n try {\n schemaService.clearCache(schemasDir);\n const schemas = await schemaService.loadAll(schemasDir);\n\n const event: ServerEvent = {\n type: 'schemas:reloaded',\n payload: { schemas },\n };\n wsHandler.broadcast(event);\n } catch (error) {\n console.error('Error notifying reload:', error);\n }\n }\n\n return {\n close: () => watcher.close(),\n };\n}\n"],"mappings":"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","names":["join","join","schemasDir","response","Router","loadSchemas","schemasDir","Router","Router","loadSchemas","schemasDir","Router","response","Router","Router","Router","loadSchemas","loadSchemas","changes","Router","response","join","schemasDir","schemasDir","join"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@famgia/omnify-gui",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Visual GUI for Omnify schema configuration",
5
5
  "type": "module",
6
6
  "main": "./dist/server/index.js",
@@ -26,10 +26,10 @@
26
26
  "ws": "^8.18.0",
27
27
  "yaml": "^2.5.0",
28
28
  "@famgia/omnify-cli": "0.0.11",
29
- "@famgia/omnify-laravel": "0.0.11",
30
29
  "@famgia/omnify-core": "0.0.9",
31
- "@famgia/omnify-types": "0.0.9",
32
- "@famgia/omnify-sql": "0.0.3"
30
+ "@famgia/omnify-laravel": "0.0.11",
31
+ "@famgia/omnify-sql": "0.0.3",
32
+ "@famgia/omnify-types": "0.0.9"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@ant-design/icons": "^5.5.0",