@famgia/omnify-cli 0.0.1

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/dist/index.js ADDED
@@ -0,0 +1,701 @@
1
+ #!/usr/bin/env node
2
+ #!/usr/bin/env node
3
+
4
+ // src/index.ts
5
+ import { Command } from "commander";
6
+ import { OmnifyError as OmnifyError5 } from "@famgia/omnify-core";
7
+
8
+ // src/commands/init.ts
9
+ import { existsSync, mkdirSync, writeFileSync } from "fs";
10
+ import { resolve } from "path";
11
+
12
+ // src/output/logger.ts
13
+ import pc from "picocolors";
14
+ import { formatError, getExitCode } from "@famgia/omnify-core";
15
+ var Logger = class {
16
+ _verbose;
17
+ _quiet;
18
+ _startTime;
19
+ constructor(options = {}) {
20
+ this._verbose = options.verbose ?? false;
21
+ this._quiet = options.quiet ?? false;
22
+ this._startTime = Date.now();
23
+ }
24
+ /**
25
+ * Enable or disable verbose mode.
26
+ */
27
+ setVerbose(verbose) {
28
+ this._verbose = verbose;
29
+ }
30
+ /**
31
+ * Enable or disable quiet mode.
32
+ */
33
+ setQuiet(quiet) {
34
+ this._quiet = quiet;
35
+ }
36
+ /**
37
+ * Log an info message.
38
+ */
39
+ info(message) {
40
+ if (!this._quiet) {
41
+ console.log(message);
42
+ }
43
+ }
44
+ /**
45
+ * Log a success message.
46
+ */
47
+ success(message) {
48
+ if (!this._quiet) {
49
+ console.log(pc.green("\u2713") + " " + message);
50
+ }
51
+ }
52
+ /**
53
+ * Log a warning message.
54
+ */
55
+ warn(message) {
56
+ if (!this._quiet) {
57
+ console.log(pc.yellow("\u26A0") + " " + pc.yellow(message));
58
+ }
59
+ }
60
+ /**
61
+ * Log an error message.
62
+ */
63
+ error(message) {
64
+ console.error(pc.red("\u2717") + " " + pc.red(message));
65
+ }
66
+ /**
67
+ * Log a debug message (only in verbose mode).
68
+ */
69
+ debug(message) {
70
+ if (this._verbose && !this._quiet) {
71
+ console.log(pc.dim(" " + message));
72
+ }
73
+ }
74
+ /**
75
+ * Log a step message.
76
+ */
77
+ step(message) {
78
+ if (!this._quiet) {
79
+ console.log(pc.cyan("\u2192") + " " + message);
80
+ }
81
+ }
82
+ /**
83
+ * Log a header.
84
+ */
85
+ header(message) {
86
+ if (!this._quiet) {
87
+ console.log();
88
+ console.log(pc.bold(message));
89
+ console.log();
90
+ }
91
+ }
92
+ /**
93
+ * Log a list item.
94
+ */
95
+ list(items) {
96
+ if (!this._quiet) {
97
+ for (const item of items) {
98
+ console.log(" \u2022 " + item);
99
+ }
100
+ }
101
+ }
102
+ /**
103
+ * Log a timing message.
104
+ */
105
+ timing(message) {
106
+ if (this._verbose && !this._quiet) {
107
+ const elapsed = Date.now() - this._startTime;
108
+ console.log(pc.dim(` [${elapsed}ms] ${message}`));
109
+ }
110
+ }
111
+ /**
112
+ * Log an empty line.
113
+ */
114
+ newline() {
115
+ if (!this._quiet) {
116
+ console.log();
117
+ }
118
+ }
119
+ /**
120
+ * Format and log an OmnifyError.
121
+ */
122
+ formatError(error) {
123
+ const formatted = formatError(error, { color: true });
124
+ console.error(formatted);
125
+ }
126
+ /**
127
+ * Get exit code for an error.
128
+ */
129
+ getExitCode(error) {
130
+ return getExitCode(error);
131
+ }
132
+ };
133
+ var logger = new Logger();
134
+
135
+ // src/commands/init.ts
136
+ var EXAMPLE_SCHEMA = `# Example User schema
137
+ # See https://omnify.dev/docs/schemas for documentation
138
+
139
+ name: User
140
+ displayName: User Account
141
+ kind: object
142
+
143
+ properties:
144
+ email:
145
+ type: Email
146
+ unique: true
147
+ displayName: Email Address
148
+
149
+ name:
150
+ type: String
151
+ displayName: Full Name
152
+
153
+ bio:
154
+ type: Text
155
+ nullable: true
156
+ displayName: Biography
157
+
158
+ options:
159
+ timestamps: true
160
+ softDelete: true
161
+ `;
162
+ var EXAMPLE_CONFIG = `import { defineConfig } from '@famgia/omnify-cli';
163
+
164
+ export default defineConfig({
165
+ // Schema files location
166
+ schemasDir: './schemas',
167
+
168
+ // Database configuration
169
+ database: {
170
+ driver: 'mysql',
171
+ // Development database URL for Atlas diff operations
172
+ // devUrl: 'mysql://root@localhost:3306/omnify_dev',
173
+ },
174
+
175
+ // Output configuration
176
+ output: {
177
+ laravel: {
178
+ migrationsPath: 'database/migrations',
179
+ },
180
+ typescript: {
181
+ path: 'types',
182
+ singleFile: true,
183
+ },
184
+ },
185
+
186
+ // Plugins for custom types
187
+ plugins: [
188
+ // '@famgia/omnify-japan',
189
+ ],
190
+ });
191
+ `;
192
+ async function runInit(options) {
193
+ const cwd = process.cwd();
194
+ logger.header("Initializing Omnify Project");
195
+ const configPath = resolve(cwd, "omnify.config.ts");
196
+ if (existsSync(configPath) && !options.force) {
197
+ logger.warn("omnify.config.ts already exists. Use --force to overwrite.");
198
+ return;
199
+ }
200
+ const schemasDir = resolve(cwd, "schemas");
201
+ if (!existsSync(schemasDir)) {
202
+ mkdirSync(schemasDir, { recursive: true });
203
+ logger.step("Created schemas/ directory");
204
+ } else {
205
+ logger.debug("schemas/ directory already exists");
206
+ }
207
+ const examplePath = resolve(schemasDir, "User.yaml");
208
+ if (!existsSync(examplePath) || options.force) {
209
+ writeFileSync(examplePath, EXAMPLE_SCHEMA);
210
+ logger.step("Created example schema: schemas/User.yaml");
211
+ } else {
212
+ logger.debug("Example schema already exists");
213
+ }
214
+ writeFileSync(configPath, EXAMPLE_CONFIG);
215
+ logger.step("Created omnify.config.ts");
216
+ logger.newline();
217
+ logger.success("Project initialized successfully!");
218
+ logger.newline();
219
+ logger.info("Next steps:");
220
+ logger.list([
221
+ "Edit omnify.config.ts to configure your database",
222
+ "Add your schema files to the schemas/ directory",
223
+ 'Run "omnify validate" to check your schemas',
224
+ 'Run "omnify diff" to preview changes',
225
+ 'Run "omnify generate" to create migrations and types'
226
+ ]);
227
+ }
228
+ function registerInitCommand(program2) {
229
+ program2.command("init").description("Initialize a new omnify project").option("-f, --force", "Overwrite existing files").action(async (options) => {
230
+ try {
231
+ await runInit(options);
232
+ } catch (error) {
233
+ if (error instanceof Error) {
234
+ logger.error(error.message);
235
+ }
236
+ process.exit(1);
237
+ }
238
+ });
239
+ }
240
+
241
+ // src/commands/validate.ts
242
+ import { resolve as resolve3, dirname as dirname2 } from "path";
243
+ import { loadSchemas, validateSchemas, OmnifyError as OmnifyError2 } from "@famgia/omnify-core";
244
+
245
+ // src/config/loader.ts
246
+ import { existsSync as existsSync2 } from "fs";
247
+ import { resolve as resolve2, dirname } from "path";
248
+ import { createJiti } from "jiti";
249
+ import { configError, configNotFoundError } from "@famgia/omnify-core";
250
+ var CONFIG_FILES = [
251
+ "omnify.config.ts",
252
+ "omnify.config.js",
253
+ "omnify.config.mjs",
254
+ "omnify.config.cjs"
255
+ ];
256
+ function findConfigFile(startDir) {
257
+ const cwd = resolve2(startDir);
258
+ for (const filename of CONFIG_FILES) {
259
+ const configPath = resolve2(cwd, filename);
260
+ if (existsSync2(configPath)) {
261
+ return configPath;
262
+ }
263
+ }
264
+ return null;
265
+ }
266
+ async function loadConfigFile(configPath) {
267
+ const jiti = createJiti(configPath, {
268
+ interopDefault: true,
269
+ moduleCache: false
270
+ });
271
+ try {
272
+ const module = await jiti.import(configPath);
273
+ const config = module;
274
+ if ("default" in config) {
275
+ return config.default;
276
+ }
277
+ return config;
278
+ } catch (error) {
279
+ const message = error instanceof Error ? error.message : String(error);
280
+ throw configError(
281
+ `Failed to load config file: ${message}. Check your omnify.config.ts for syntax errors.`,
282
+ "E002"
283
+ );
284
+ }
285
+ }
286
+ async function resolvePlugins(plugins, configPath) {
287
+ if (!plugins || plugins.length === 0) {
288
+ return [];
289
+ }
290
+ const resolved = [];
291
+ const configDir = configPath ? dirname(configPath) : process.cwd();
292
+ for (const plugin of plugins) {
293
+ if (typeof plugin === "string") {
294
+ const jiti = createJiti(configDir, {
295
+ interopDefault: true,
296
+ moduleCache: false
297
+ });
298
+ try {
299
+ const module = await jiti.import(plugin);
300
+ const loadedPlugin = module.default ?? module;
301
+ resolved.push(loadedPlugin);
302
+ } catch (error) {
303
+ const message = error instanceof Error ? error.message : String(error);
304
+ throw configError(
305
+ `Failed to load plugin '${plugin}': ${message}. Ensure the plugin is installed: npm install ${plugin}`,
306
+ "E301"
307
+ );
308
+ }
309
+ } else {
310
+ resolved.push(plugin);
311
+ }
312
+ }
313
+ return resolved;
314
+ }
315
+ async function resolveConfig(userConfig, configPath) {
316
+ const plugins = await resolvePlugins(userConfig.plugins, configPath);
317
+ const databaseConfig = {
318
+ driver: userConfig.database.driver,
319
+ enableFieldComments: userConfig.database.enableFieldComments ?? false
320
+ };
321
+ const database = userConfig.database.devUrl !== void 0 ? { ...databaseConfig, devUrl: userConfig.database.devUrl } : databaseConfig;
322
+ const laravelConfig = {
323
+ migrationsPath: userConfig.output?.laravel?.migrationsPath ?? "database/migrations"
324
+ };
325
+ const laravel = buildLaravelConfig(laravelConfig, userConfig.output?.laravel);
326
+ const typescript = {
327
+ path: userConfig.output?.typescript?.path ?? "types",
328
+ singleFile: userConfig.output?.typescript?.singleFile ?? true,
329
+ generateEnums: userConfig.output?.typescript?.generateEnums ?? true,
330
+ generateRelationships: userConfig.output?.typescript?.generateRelationships ?? true
331
+ };
332
+ const result = {
333
+ schemasDir: userConfig.schemasDir ?? "./schemas",
334
+ database,
335
+ output: {
336
+ laravel,
337
+ typescript
338
+ },
339
+ plugins,
340
+ verbose: userConfig.verbose ?? false,
341
+ lockFilePath: userConfig.lockFilePath ?? ".omnify.lock"
342
+ };
343
+ return result;
344
+ }
345
+ function buildLaravelConfig(base, userLaravel) {
346
+ const config = { ...base };
347
+ if (userLaravel?.modelsPath !== void 0) {
348
+ config.modelsPath = userLaravel.modelsPath;
349
+ }
350
+ if (userLaravel?.modelsNamespace !== void 0) {
351
+ config.modelsNamespace = userLaravel.modelsNamespace;
352
+ }
353
+ if (userLaravel?.factoriesPath !== void 0) {
354
+ config.factoriesPath = userLaravel.factoriesPath;
355
+ }
356
+ if (userLaravel?.enumsPath !== void 0) {
357
+ config.enumsPath = userLaravel.enumsPath;
358
+ }
359
+ if (userLaravel?.enumsNamespace !== void 0) {
360
+ config.enumsNamespace = userLaravel.enumsNamespace;
361
+ }
362
+ return config;
363
+ }
364
+ function validateConfig(config, rootDir) {
365
+ const schemaPath = resolve2(rootDir, config.schemasDir);
366
+ if (!existsSync2(schemaPath)) {
367
+ throw configError(
368
+ `Schema directory not found: ${schemaPath}. Create the '${config.schemasDir}' directory or update schemasDir in config.`,
369
+ "E002"
370
+ );
371
+ }
372
+ }
373
+ function requireDevUrl(config) {
374
+ if (!config.database.devUrl) {
375
+ throw configError(
376
+ `database.devUrl is required for diff and generate operations. Add devUrl to your database config, e.g., "mysql://root@localhost:3306/omnify_dev"`,
377
+ "E003"
378
+ );
379
+ }
380
+ }
381
+ async function loadConfig(startDir = process.cwd()) {
382
+ const cwd = resolve2(startDir);
383
+ const configPath = findConfigFile(cwd);
384
+ if (configPath) {
385
+ const userConfig = await loadConfigFile(configPath);
386
+ const config = await resolveConfig(userConfig, configPath);
387
+ return {
388
+ config,
389
+ configPath
390
+ };
391
+ }
392
+ throw configNotFoundError(resolve2(cwd, "omnify.config.ts"));
393
+ }
394
+ function defineConfig(config) {
395
+ return config;
396
+ }
397
+
398
+ // src/commands/validate.ts
399
+ async function runValidate(options) {
400
+ logger.setVerbose(options.verbose ?? false);
401
+ logger.header("Validating Schemas");
402
+ logger.debug("Loading configuration...");
403
+ logger.timing("Config load start");
404
+ const { config, configPath } = await loadConfig();
405
+ logger.timing("Config loaded");
406
+ const rootDir = configPath ? dirname2(configPath) : process.cwd();
407
+ validateConfig(config, rootDir);
408
+ const schemaPath = resolve3(rootDir, config.schemasDir);
409
+ logger.step(`Loading schemas from ${schemaPath}`);
410
+ logger.timing("Schema load start");
411
+ const schemas = await loadSchemas(schemaPath);
412
+ const schemaCount = Object.keys(schemas).length;
413
+ logger.timing("Schemas loaded");
414
+ if (schemaCount === 0) {
415
+ logger.warn("No schema files found");
416
+ return;
417
+ }
418
+ logger.debug(`Found ${schemaCount} schema(s)`);
419
+ logger.step("Validating schemas...");
420
+ logger.timing("Validation start");
421
+ const result = validateSchemas(schemas);
422
+ logger.timing("Validation complete");
423
+ if (result.valid) {
424
+ logger.success(`All ${schemaCount} schema(s) are valid`);
425
+ } else {
426
+ logger.error(`Found ${result.errors.length} validation error(s)`);
427
+ logger.newline();
428
+ for (const error of result.errors) {
429
+ const omnifyError = OmnifyError2.fromInfo(error);
430
+ logger.formatError(omnifyError);
431
+ logger.newline();
432
+ }
433
+ process.exit(2);
434
+ }
435
+ }
436
+ function registerValidateCommand(program2) {
437
+ program2.command("validate").description("Validate schema files").option("-v, --verbose", "Show detailed output").action(async (options) => {
438
+ try {
439
+ await runValidate(options);
440
+ } catch (error) {
441
+ if (error instanceof OmnifyError2) {
442
+ logger.formatError(error);
443
+ process.exit(logger.getExitCode(error));
444
+ } else if (error instanceof Error) {
445
+ logger.error(error.message);
446
+ process.exit(1);
447
+ }
448
+ process.exit(1);
449
+ }
450
+ });
451
+ }
452
+
453
+ // src/commands/diff.ts
454
+ import { resolve as resolve4, dirname as dirname3 } from "path";
455
+ import { loadSchemas as loadSchemas2, validateSchemas as validateSchemas2, OmnifyError as OmnifyError3 } from "@famgia/omnify-core";
456
+
457
+ // src/operations/diff.ts
458
+ import {
459
+ generatePreview,
460
+ formatPreview
461
+ } from "@famgia/omnify-atlas";
462
+ async function runDiffOperation(options) {
463
+ const { schemas, devUrl, driver, workDir } = options;
464
+ const preview = await generatePreview(schemas, {
465
+ driver,
466
+ devUrl,
467
+ workDir
468
+ }, {
469
+ warnDestructive: true,
470
+ showSql: true
471
+ });
472
+ const formattedPreview = formatPreview(preview, "text");
473
+ return {
474
+ hasChanges: preview.hasChanges,
475
+ hasDestructiveChanges: preview.hasDestructiveChanges,
476
+ preview,
477
+ formattedPreview,
478
+ sql: preview.sql
479
+ };
480
+ }
481
+
482
+ // src/commands/diff.ts
483
+ import pc2 from "picocolors";
484
+ async function runDiff(options) {
485
+ logger.setVerbose(options.verbose ?? false);
486
+ logger.header("Checking for Schema Changes");
487
+ logger.debug("Loading configuration...");
488
+ const { config, configPath } = await loadConfig();
489
+ const rootDir = configPath ? dirname3(configPath) : process.cwd();
490
+ validateConfig(config, rootDir);
491
+ requireDevUrl(config);
492
+ const schemaPath = resolve4(rootDir, config.schemasDir);
493
+ logger.step(`Loading schemas from ${schemaPath}`);
494
+ const schemas = await loadSchemas2(schemaPath);
495
+ const schemaCount = Object.keys(schemas).length;
496
+ if (schemaCount === 0) {
497
+ logger.warn("No schema files found");
498
+ return;
499
+ }
500
+ logger.debug(`Found ${schemaCount} schema(s)`);
501
+ logger.step("Validating schemas...");
502
+ const validationResult = validateSchemas2(schemas);
503
+ if (!validationResult.valid) {
504
+ logger.error("Schema validation failed. Fix errors before running diff.");
505
+ for (const error of validationResult.errors) {
506
+ const omnifyError = OmnifyError3.fromInfo(error);
507
+ logger.formatError(omnifyError);
508
+ }
509
+ process.exit(2);
510
+ }
511
+ logger.step("Running Atlas diff...");
512
+ const lockPath = resolve4(rootDir, config.lockFilePath);
513
+ const diffResult = await runDiffOperation({
514
+ schemas,
515
+ devUrl: config.database.devUrl,
516
+ lockFilePath: lockPath,
517
+ driver: config.database.driver,
518
+ workDir: rootDir
519
+ });
520
+ if (!diffResult.hasChanges) {
521
+ logger.success("No changes detected");
522
+ return;
523
+ }
524
+ logger.newline();
525
+ console.log(pc2.bold("Changes detected:"));
526
+ console.log();
527
+ console.log(diffResult.formattedPreview);
528
+ if (diffResult.hasDestructiveChanges) {
529
+ logger.newline();
530
+ logger.warn("This preview contains destructive changes. Review carefully.");
531
+ }
532
+ if (options.check) {
533
+ logger.newline();
534
+ logger.info("Changes detected (--check mode)");
535
+ process.exit(1);
536
+ }
537
+ logger.newline();
538
+ logger.info('Run "omnify generate" to create migrations');
539
+ }
540
+ function registerDiffCommand(program2) {
541
+ program2.command("diff").description("Show pending schema changes").option("-v, --verbose", "Show detailed output").option("--check", "Exit with code 1 if changes exist (for CI)").action(async (options) => {
542
+ try {
543
+ await runDiff(options);
544
+ } catch (error) {
545
+ if (error instanceof OmnifyError3) {
546
+ logger.formatError(error);
547
+ process.exit(logger.getExitCode(error));
548
+ } else if (error instanceof Error) {
549
+ logger.error(error.message);
550
+ process.exit(1);
551
+ }
552
+ process.exit(1);
553
+ }
554
+ });
555
+ }
556
+
557
+ // src/commands/generate.ts
558
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
559
+ import { resolve as resolve5, dirname as dirname4 } from "path";
560
+ import { loadSchemas as loadSchemas3, validateSchemas as validateSchemas3, OmnifyError as OmnifyError4 } from "@famgia/omnify-core";
561
+ import { updateLockFile } from "@famgia/omnify-atlas";
562
+ import { generateMigrations, generateTypeScript } from "@famgia/omnify-laravel";
563
+ async function runGenerate(options) {
564
+ logger.setVerbose(options.verbose ?? false);
565
+ logger.header("Generating Outputs");
566
+ logger.debug("Loading configuration...");
567
+ const { config, configPath } = await loadConfig();
568
+ const rootDir = configPath ? dirname4(configPath) : process.cwd();
569
+ validateConfig(config, rootDir);
570
+ requireDevUrl(config);
571
+ const schemaPath = resolve5(rootDir, config.schemasDir);
572
+ logger.step(`Loading schemas from ${schemaPath}`);
573
+ const schemas = await loadSchemas3(schemaPath);
574
+ const schemaCount = Object.keys(schemas).length;
575
+ if (schemaCount === 0) {
576
+ logger.warn("No schema files found");
577
+ return;
578
+ }
579
+ logger.debug(`Found ${schemaCount} schema(s)`);
580
+ logger.step("Validating schemas...");
581
+ const validationResult = validateSchemas3(schemas);
582
+ if (!validationResult.valid) {
583
+ logger.error("Schema validation failed. Fix errors before generating.");
584
+ for (const error of validationResult.errors) {
585
+ const omnifyError = OmnifyError4.fromInfo(error);
586
+ logger.formatError(omnifyError);
587
+ }
588
+ process.exit(2);
589
+ }
590
+ logger.step("Checking for changes...");
591
+ const lockPath = resolve5(rootDir, config.lockFilePath);
592
+ const diffResult = await runDiffOperation({
593
+ schemas,
594
+ devUrl: config.database.devUrl,
595
+ lockFilePath: lockPath,
596
+ driver: config.database.driver,
597
+ workDir: rootDir
598
+ });
599
+ if (!diffResult.hasChanges && !options.force) {
600
+ logger.success("No changes to generate");
601
+ return;
602
+ }
603
+ let migrationsGenerated = 0;
604
+ let typesGenerated = 0;
605
+ if (!options.typesOnly) {
606
+ logger.step("Generating Laravel migrations...");
607
+ const migrationsDir = resolve5(rootDir, config.output.laravel.migrationsPath);
608
+ if (!existsSync3(migrationsDir)) {
609
+ mkdirSync2(migrationsDir, { recursive: true });
610
+ logger.debug(`Created directory: ${migrationsDir}`);
611
+ }
612
+ const migrations = generateMigrations(schemas);
613
+ for (const migration of migrations) {
614
+ const filePath = resolve5(migrationsDir, migration.fileName);
615
+ writeFileSync2(filePath, migration.content);
616
+ logger.debug(`Created: ${migration.fileName}`);
617
+ migrationsGenerated++;
618
+ }
619
+ logger.success(`Generated ${migrationsGenerated} migration(s)`);
620
+ }
621
+ if (!options.migrationsOnly) {
622
+ logger.step("Generating TypeScript types...");
623
+ const typesDir = resolve5(rootDir, config.output.typescript.path);
624
+ if (!existsSync3(typesDir)) {
625
+ mkdirSync2(typesDir, { recursive: true });
626
+ logger.debug(`Created directory: ${typesDir}`);
627
+ }
628
+ const typeFiles = generateTypeScript(schemas, {
629
+ singleFile: config.output.typescript.singleFile
630
+ });
631
+ for (const file of typeFiles) {
632
+ const filePath = resolve5(typesDir, file.fileName);
633
+ writeFileSync2(filePath, file.content);
634
+ logger.debug(`Created: ${file.fileName}`);
635
+ typesGenerated++;
636
+ }
637
+ logger.success(`Generated ${typesGenerated} TypeScript file(s)`);
638
+ }
639
+ logger.step("Updating lock file...");
640
+ await updateLockFile(lockPath, schemas);
641
+ logger.debug(`Updated: ${config.lockFilePath}`);
642
+ logger.newline();
643
+ logger.success("Generation complete!");
644
+ if (migrationsGenerated > 0) {
645
+ logger.info(` Migrations: ${config.output.laravel.migrationsPath}/`);
646
+ }
647
+ if (typesGenerated > 0) {
648
+ logger.info(` Types: ${config.output.typescript.path}/`);
649
+ }
650
+ }
651
+ function registerGenerateCommand(program2) {
652
+ program2.command("generate").description("Generate Laravel migrations and TypeScript types").option("-v, --verbose", "Show detailed output").option("--migrations-only", "Only generate migrations").option("--types-only", "Only generate TypeScript types").option("-f, --force", "Generate even if no changes detected").action(async (options) => {
653
+ try {
654
+ await runGenerate(options);
655
+ } catch (error) {
656
+ if (error instanceof OmnifyError4) {
657
+ logger.formatError(error);
658
+ process.exit(logger.getExitCode(error));
659
+ } else if (error instanceof Error) {
660
+ logger.error(error.message);
661
+ process.exit(1);
662
+ }
663
+ process.exit(1);
664
+ }
665
+ });
666
+ }
667
+
668
+ // src/index.ts
669
+ var VERSION = "0.0.1";
670
+ var program = new Command();
671
+ program.name("omnify").description("Schema-first database migrations for Laravel and TypeScript").version(VERSION);
672
+ registerInitCommand(program);
673
+ registerValidateCommand(program);
674
+ registerDiffCommand(program);
675
+ registerGenerateCommand(program);
676
+ process.on("uncaughtException", (error) => {
677
+ if (error instanceof OmnifyError5) {
678
+ logger.formatError(error);
679
+ process.exit(logger.getExitCode(error));
680
+ } else {
681
+ logger.error(error.message);
682
+ process.exit(1);
683
+ }
684
+ });
685
+ process.on("unhandledRejection", (reason) => {
686
+ if (reason instanceof OmnifyError5) {
687
+ logger.formatError(reason);
688
+ process.exit(logger.getExitCode(reason));
689
+ } else if (reason instanceof Error) {
690
+ logger.error(reason.message);
691
+ } else {
692
+ logger.error(String(reason));
693
+ }
694
+ process.exit(1);
695
+ });
696
+ program.parse();
697
+ export {
698
+ defineConfig,
699
+ loadConfig
700
+ };
701
+ //# sourceMappingURL=index.js.map