ilana-orm 1.0.7 → 1.0.8

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.
Files changed (2) hide show
  1. package/cli/ilana.js +117 -452
  2. package/package.json +1 -1
package/cli/ilana.js CHANGED
@@ -108,6 +108,122 @@ function pluralize(str) {
108
108
  return str + 's';
109
109
  }
110
110
 
111
+ function getESModuleConfigTemplate() {
112
+ return `import 'dotenv/config';
113
+ import Database from 'ilana-orm/database/connection';
114
+
115
+ const config = {
116
+ default: process.env.DB_CONNECTION || 'mysql',
117
+ timezone: process.env.DB_TIMEZONE || 'UTC',
118
+
119
+ connections: {
120
+ sqlite: {
121
+ client: 'sqlite3',
122
+ connection: {
123
+ filename: process.env.DB_FILENAME || './database.sqlite'
124
+ },
125
+ useNullAsDefault: true
126
+ },
127
+
128
+ mysql: {
129
+ client: 'mysql2',
130
+ connection: {
131
+ host: process.env.DB_HOST || 'localhost',
132
+ port: process.env.DB_PORT || 3306,
133
+ user: process.env.DB_USERNAME || 'root',
134
+ password: process.env.DB_PASSWORD || '',
135
+ database: process.env.DB_DATABASE || 'your_database',
136
+ timezone: process.env.DB_TIMEZONE || 'UTC'
137
+ }
138
+ },
139
+
140
+ postgres: {
141
+ client: 'pg',
142
+ connection: {
143
+ host: process.env.DB_HOST || 'localhost',
144
+ port: process.env.DB_PORT || 5432,
145
+ user: process.env.DB_USERNAME || 'postgres',
146
+ password: process.env.DB_PASSWORD || '',
147
+ database: process.env.DB_DATABASE || 'your_database'
148
+ }
149
+ }
150
+ },
151
+
152
+ migrations: {
153
+ directory: './database/migrations',
154
+ tableName: 'migrations'
155
+ },
156
+
157
+ seeds: {
158
+ directory: './database/seeds'
159
+ }
160
+ };
161
+
162
+ // Auto-initialize database connections
163
+ Database.configure(config);
164
+
165
+ export default config;
166
+ `;
167
+ }
168
+
169
+ function getCommonJSConfigTemplate() {
170
+ return `require('dotenv').config();
171
+ const Database = require('ilana-orm/database/connection');
172
+
173
+ const config = {
174
+ default: process.env.DB_CONNECTION || 'mysql',
175
+ timezone: process.env.DB_TIMEZONE || 'UTC',
176
+
177
+ connections: {
178
+ sqlite: {
179
+ client: 'sqlite3',
180
+ connection: {
181
+ filename: process.env.DB_FILENAME || './database.sqlite'
182
+ },
183
+ useNullAsDefault: true
184
+ },
185
+
186
+ mysql: {
187
+ client: 'mysql2',
188
+ connection: {
189
+ host: process.env.DB_HOST || 'localhost',
190
+ port: process.env.DB_PORT || 3306,
191
+ user: process.env.DB_USERNAME || 'root',
192
+ password: process.env.DB_PASSWORD || '',
193
+ database: process.env.DB_DATABASE || 'your_database',
194
+ timezone: process.env.DB_TIMEZONE || 'UTC'
195
+ }
196
+ },
197
+
198
+ postgres: {
199
+ client: 'pg',
200
+ connection: {
201
+ host: process.env.DB_HOST || 'localhost',
202
+ port: process.env.DB_PORT || 5432,
203
+ user: process.env.DB_USERNAME || 'postgres',
204
+ password: process.env.DB_PASSWORD || '',
205
+ database: process.env.DB_DATABASE || 'your_database'
206
+ }
207
+ }
208
+ },
209
+
210
+ migrations: {
211
+ directory: './database/migrations',
212
+ tableName: 'migrations'
213
+ },
214
+
215
+ seeds: {
216
+ directory: './database/seeds'
217
+ }
218
+ };
219
+
220
+ // Auto-initialize database connections
221
+ Database.configure(config);
222
+
223
+ module.exports = config;
224
+ `;
225
+ }
226
+
111
227
  function generateModel(name, options = {}) {
112
228
  const className = toPascalCase(name);
113
229
  const tableName = pluralize(toSnakeCase(name));
@@ -438,124 +554,6 @@ const commands = {
438
554
  fs.writeFileSync(configPath, configTemplate);
439
555
  console.log(`Created config file: ${configPath}`);
440
556
  }
441
- },
442
- };
443
-
444
- function getESModuleConfigTemplate() {
445
- return `import 'dotenv/config';
446
- import Database from 'ilana-orm/database/connection.js';
447
-
448
- const config = {
449
- default: process.env.DB_CONNECTION || 'mysql',
450
- timezone: process.env.DB_TIMEZONE || 'UTC',
451
-
452
- connections: {
453
- sqlite: {
454
- client: 'sqlite3',
455
- connection: {
456
- filename: process.env.DB_FILENAME || './database.sqlite'
457
- },
458
- useNullAsDefault: true
459
- },
460
-
461
- mysql: {
462
- client: 'mysql2',
463
- connection: {
464
- host: process.env.DB_HOST || 'localhost',
465
- port: process.env.DB_PORT || 3306,
466
- user: process.env.DB_USERNAME || 'root',
467
- password: process.env.DB_PASSWORD || '',
468
- database: process.env.DB_DATABASE || 'your_database',
469
- timezone: process.env.DB_TIMEZONE || 'UTC'
470
- }
471
- },
472
-
473
- postgres: {
474
- client: 'pg',
475
- connection: {
476
- host: process.env.DB_HOST || 'localhost',
477
- port: process.env.DB_PORT || 5432,
478
- user: process.env.DB_USERNAME || 'postgres',
479
- password: process.env.DB_PASSWORD || '',
480
- database: process.env.DB_DATABASE || 'your_database'
481
- }
482
- }
483
- },
484
-
485
- migrations: {
486
- directory: './database/migrations',
487
- tableName: 'migrations'
488
- },
489
-
490
- seeds: {
491
- directory: './database/seeds'
492
- }
493
- };
494
-
495
- // Auto-initialize database connections
496
- Database.configure(config);
497
-
498
- export default config;
499
- `;
500
- }
501
-
502
- function getCommonJSConfigTemplate() {
503
- return `require('dotenv').config();
504
- const Database = require('ilana-orm/database/connection');
505
-
506
- const config = {
507
- default: process.env.DB_CONNECTION || 'mysql',
508
- timezone: process.env.DB_TIMEZONE || 'UTC',
509
-
510
- connections: {
511
- sqlite: {
512
- client: 'sqlite3',
513
- connection: {
514
- filename: process.env.DB_FILENAME || './database.sqlite'
515
- },
516
- useNullAsDefault: true
517
- },
518
-
519
- mysql: {
520
- client: 'mysql2',
521
- connection: {
522
- host: process.env.DB_HOST || 'localhost',
523
- port: process.env.DB_PORT || 3306,
524
- user: process.env.DB_USERNAME || 'root',
525
- password: process.env.DB_PASSWORD || '',
526
- database: process.env.DB_DATABASE || 'your_database',
527
- timezone: process.env.DB_TIMEZONE || 'UTC'
528
- }
529
- },
530
-
531
- postgres: {
532
- client: 'pg',
533
- connection: {
534
- host: process.env.DB_HOST || 'localhost',
535
- port: process.env.DB_PORT || 5432,
536
- user: process.env.DB_USERNAME || 'postgres',
537
- password: process.env.DB_PASSWORD || '',
538
- database: process.env.DB_DATABASE || 'your_database'
539
- }
540
- }
541
- },
542
-
543
- migrations: {
544
- directory: './database/migrations',
545
- tableName: 'migrations'
546
- },
547
-
548
- seeds: {
549
- directory: './database/seeds'
550
- }
551
- };
552
-
553
- // Auto-initialize database connections
554
- Database.configure(config);
555
-
556
- module.exports = config;
557
- `;
558
- }
559
557
 
560
558
  // Create .env file if it doesn't exist
561
559
  const envPath = '.env';
@@ -600,6 +598,7 @@ DB_TIMEZONE=UTC
600
598
  console.log('2. Run: ilana make:model User -m');
601
599
  console.log('3. Run: ilana migrate');
602
600
  },
601
+
603
602
  async 'make:migration'(name, ...flags) {
604
603
  if (!name) {
605
604
  console.error('Migration name is required');
@@ -700,329 +699,6 @@ DB_TIMEZONE=UTC
700
699
  generateModel(name, options);
701
700
  },
702
701
 
703
- async migrate(...args) {
704
- await initializeDatabase();
705
- const runner = new MigrationRunner();
706
-
707
- let connection;
708
- let onlyFile;
709
- let toFile;
710
-
711
- for (let i = 0; i < args.length; i++) {
712
- const arg = args[i];
713
- if (arg === '--connection' && args[i + 1]) {
714
- connection = args[i + 1];
715
- i++;
716
- } else if (arg.startsWith('--connection=')) {
717
- connection = arg.split('=')[1];
718
- } else if (arg === '--only' && args[i + 1]) {
719
- onlyFile = args[i + 1];
720
- i++;
721
- } else if (arg.startsWith('--only=')) {
722
- onlyFile = arg.split('=')[1];
723
- } else if (arg === '--to' && args[i + 1]) {
724
- toFile = args[i + 1];
725
- i++;
726
- } else if (arg.startsWith('--to=')) {
727
- toFile = arg.split('=')[1];
728
- } else if (!arg.startsWith('--')) {
729
- connection = arg;
730
- }
731
- }
732
-
733
- await runner.migrate(connection, onlyFile, toFile);
734
- process.exit(0);
735
- },
736
-
737
- async 'migrate:fresh'(...args) {
738
- await initializeDatabase();
739
- const runner = new MigrationRunner();
740
-
741
- let connection;
742
- let withSeed = false;
743
-
744
- for (const arg of args) {
745
- if (arg === '--seed') {
746
- withSeed = true;
747
- } else if (arg.startsWith('--connection=')) {
748
- connection = arg.split('=')[1];
749
- } else if (!arg.startsWith('--')) {
750
- connection = arg;
751
- }
752
- }
753
-
754
- await runner.fresh(connection);
755
-
756
- if (withSeed) {
757
- await commands.seed();
758
- }
759
-
760
- process.exit(0);
761
- },
762
-
763
- async 'migrate:list'(connection) {
764
- await initializeDatabase();
765
- const runner = new MigrationRunner();
766
- await runner.list(connection);
767
- process.exit(0);
768
- },
769
-
770
- async 'migrate:unlock'(connection) {
771
- await initializeDatabase();
772
- const runner = new MigrationRunner();
773
- await runner.unlock(connection);
774
- process.exit(0);
775
- },
776
-
777
- async 'migrate:rollback'(...args) {
778
- await initializeDatabase();
779
- const runner = new MigrationRunner();
780
-
781
- let steps = 1;
782
- let connection;
783
- let toFile;
784
-
785
- for (let i = 0; i < args.length; i++) {
786
- const arg = args[i];
787
- if (arg === '--step' && args[i + 1]) {
788
- steps = parseInt(args[i + 1]);
789
- i++;
790
- } else if (arg.startsWith('--step=')) {
791
- steps = parseInt(arg.split('=')[1]);
792
- } else if (arg === '--connection' && args[i + 1]) {
793
- connection = args[i + 1];
794
- i++;
795
- } else if (arg.startsWith('--connection=')) {
796
- connection = arg.split('=')[1];
797
- } else if (arg === '--to' && args[i + 1]) {
798
- toFile = args[i + 1];
799
- i++;
800
- } else if (arg.startsWith('--to=')) {
801
- toFile = arg.split('=')[1];
802
- } else if (!isNaN(parseInt(arg))) {
803
- steps = parseInt(arg);
804
- } else if (!arg.startsWith('--')) {
805
- connection = arg;
806
- }
807
- }
808
-
809
- await runner.rollback(steps, connection, toFile);
810
- process.exit(0);
811
- },
812
-
813
- async 'migrate:reset'(connection) {
814
- await initializeDatabase();
815
- const runner = new MigrationRunner();
816
- await runner.reset(connection);
817
- process.exit(0);
818
- },
819
-
820
- async 'migrate:refresh'(connection) {
821
- await initializeDatabase();
822
- const runner = new MigrationRunner();
823
- await runner.refresh(connection);
824
- process.exit(0);
825
- },
826
-
827
- async 'migrate:status'(connection) {
828
- await initializeDatabase();
829
- const runner = new MigrationRunner();
830
- await runner.status(connection);
831
- process.exit(0);
832
- },
833
-
834
- async seed(...args) {
835
- await initializeDatabase();
836
-
837
- let seederName;
838
- let connection;
839
-
840
- for (let i = 0; i < args.length; i++) {
841
- const arg = args[i];
842
- if (arg === '--class' && args[i + 1]) {
843
- seederName = args[i + 1];
844
- i++;
845
- } else if (arg.startsWith('--class=')) {
846
- seederName = arg.split('=')[1];
847
- } else if (arg === '--connection' && args[i + 1]) {
848
- connection = args[i + 1];
849
- i++;
850
- } else if (arg.startsWith('--connection=')) {
851
- connection = arg.split('=')[1];
852
- } else if (!arg.startsWith('--')) {
853
- if (!seederName) seederName = arg;
854
- else connection = arg;
855
- }
856
- }
857
-
858
- const seedsPath = path.join(process.cwd(), 'database/seeds');
859
- if (!fs.existsSync(seedsPath)) {
860
- console.log('No seeds directory found');
861
- process.exit(0);
862
- }
863
-
864
- const seedFiles = fs.readdirSync(seedsPath)
865
- .filter(file => file.endsWith('.ts') || file.endsWith('.js'))
866
- .sort();
867
-
868
- if (seedFiles.length === 0) {
869
- console.log('No seed files found');
870
- process.exit(0);
871
- }
872
-
873
- const filesToRun = seederName
874
- ? seedFiles.filter(file => file.includes(seederName))
875
- : seedFiles;
876
-
877
- console.log(`Running ${filesToRun.length} seeders...`);
878
-
879
- for (const file of filesToRun) {
880
- console.log(`Seeding: ${file}`);
881
- const filepath = path.join(seedsPath, file);
882
- delete require.cache[filepath];
883
-
884
- let seederModule;
885
- try {
886
- seederModule = require(filepath);
887
- } catch (error) {
888
- if (error.code === 'ERR_REQUIRE_ESM') {
889
- // Handle ES modules
890
- seederModule = await import(filepath);
891
- } else {
892
- throw error;
893
- }
894
- }
895
-
896
- const SeederClass = seederModule.default || seederModule;
897
- const seeder = new SeederClass();
898
-
899
- if (connection) {
900
- seeder.connection = connection;
901
- }
902
-
903
- if (typeof seeder.run === 'function') {
904
- await seeder.run();
905
- }
906
-
907
- console.log(`Seeded: ${file}`);
908
- }
909
-
910
- console.log('Seeding completed');
911
- process.exit(0);
912
- },
913
-
914
- async 'db:seed'(seederName) {
915
- return commands.seed(seederName);
916
- },
917
-
918
- async 'db:wipe'(connection) {
919
- await initializeDatabase();
920
- const runner = new MigrationRunner();
921
- await runner.wipe(connection);
922
- process.exit(0);
923
- },
924
-
925
- async 'make:observer'(name, ...flags) {
926
- if (!name) {
927
- console.error('Observer name is required');
928
- console.log('Usage: ilana make:observer <ObserverName> [--model=ModelName]');
929
- process.exit(1);
930
- }
931
-
932
- let modelName = '';
933
-
934
- for (const flag of flags) {
935
- if (flag.startsWith('--model=')) {
936
- modelName = flag.split('=')[1];
937
- }
938
- }
939
-
940
- const className = toPascalCase(name.replace('Observer', ''));
941
- const fileName = `${className}Observer${getFileExtension()}`;
942
- const filePath = path.join(process.cwd(), 'observers', fileName);
943
-
944
- if (!fs.existsSync(path.dirname(filePath))) {
945
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
946
- }
947
-
948
- const template = isTypeScriptProject() ?
949
- `${modelName ? `import ${modelName} from '../models/${modelName}.js';\n\n` : ''}export default class ${className}Observer {
950
- async creating(model: ${modelName || 'any'}): Promise<void> {}
951
- async created(model: ${modelName || 'any'}): Promise<void> {}
952
- async updating(model: ${modelName || 'any'}): Promise<void> {}
953
- async updated(model: ${modelName || 'any'}): Promise<void> {}
954
- async saving(model: ${modelName || 'any'}): Promise<void> {}
955
- async saved(model: ${modelName || 'any'}): Promise<void> {}
956
- async deleting(model: ${modelName || 'any'}): Promise<void> {}
957
- async deleted(model: ${modelName || 'any'}): Promise<void> {}
958
- }
959
- ` :
960
- `${modelName ? `const ${modelName} = require('../models/${modelName}');\n\n` : ''}class ${className}Observer {
961
- async creating(model) {}
962
- async created(model) {}
963
- async updating(model) {}
964
- async updated(model) {}
965
- async saving(model) {}
966
- async saved(model) {}
967
- async deleting(model) {}
968
- async deleted(model) {}
969
- }
970
-
971
- module.exports = ${className}Observer;
972
- `;
973
-
974
- fs.writeFileSync(filePath, template);
975
- console.log(`Created observer: observers/${fileName}`);
976
-
977
- if (modelName) {
978
- console.log(`Observer configured for model: ${modelName}`);
979
- }
980
- },
981
-
982
- async 'make:cast'(name) {
983
- if (!name) {
984
- console.error('Cast name is required');
985
- process.exit(1);
986
- }
987
-
988
- const className = toPascalCase(name.replace('Cast', ''));
989
- const fileName = `${className}Cast${getFileExtension()}`;
990
- const filePath = path.join(process.cwd(), 'casts', fileName);
991
-
992
- if (!fs.existsSync(path.dirname(filePath))) {
993
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
994
- }
995
-
996
- const template = isTypeScriptProject() ?
997
- `import { CustomCast } from 'ilana-orm/orm/Model.js';
998
-
999
- export default class ${className}Cast implements CustomCast {
1000
- get(value: any): any {
1001
- return value;
1002
- }
1003
-
1004
- set(value: any): any {
1005
- return value;
1006
- }
1007
- }
1008
- ` :
1009
- `class ${className}Cast {
1010
- get(value) {
1011
- return value;
1012
- }
1013
-
1014
- set(value) {
1015
- return value;
1016
- }
1017
- }
1018
-
1019
- module.exports = ${className}Cast;
1020
- `;
1021
-
1022
- fs.writeFileSync(filePath, template);
1023
- console.log(`Created cast: casts/${fileName}`);
1024
- },
1025
-
1026
702
  help() {
1027
703
  console.log(`
1028
704
  Ilana ORM CLI
@@ -1039,13 +715,6 @@ Available commands:
1039
715
  -mfs Generate model + migration + factory + seeder
1040
716
 
1041
717
  make:migration <name> Create a new migration file
1042
- migrate [connection] Run all pending migrations
1043
- migrate:rollback [steps] [connection] Rollback the last batch of migrations
1044
- migrate:reset [connection] Rollback all migrations
1045
- migrate:refresh [connection] Reset and re-run all migrations
1046
- migrate:status [connection] Show migration status
1047
- seed [name] Run database seeders
1048
- db:seed [name] Alias for seed command
1049
718
  help Show this help message
1050
719
 
1051
720
  Examples:
@@ -1056,10 +725,6 @@ Examples:
1056
725
  ilana make:model Permission --all
1057
726
  ilana make:model UserPost --pivot
1058
727
  ilana make:migration create_users_table
1059
- ilana migrate
1060
- ilana migrate mysql
1061
- ilana migrate:rollback 2 postgres
1062
- ilana seed UserSeeder
1063
728
  `);
1064
729
  }
1065
730
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ilana-orm",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "A fully-featured, Eloquent-style ORM for Node.js with TypeScript support",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",