ilana-orm 1.0.5 → 1.0.7

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/README.md CHANGED
@@ -150,10 +150,13 @@ touch ilana.config.js
150
150
 
151
151
  ### 2. Configure Database
152
152
 
153
- Create `ilana.config.js` in your project root:
153
+ **For CommonJS projects**, create `ilana.config.js` in your project root:
154
+
155
+ **For ES Module projects** (with `"type": "module"` in package.json), create `ilana.config.mjs`:
154
156
 
155
157
  ```javascript
156
- module.exports = {
158
+ // ilana.config.mjs
159
+ export default {
157
160
  default: "sqlite",
158
161
 
159
162
  connections: {
@@ -212,11 +215,18 @@ This creates:
212
215
 
213
216
  ### 4. Define the Model
214
217
 
215
- **JavaScript:**
218
+ **JavaScript (CommonJS):**
216
219
 
217
220
  ```javascript
218
221
  // models/User.js
219
222
  const Model = require("ilana-orm/orm/Model");
223
+ ```
224
+
225
+ **JavaScript (ES Modules):**
226
+
227
+ ```javascript
228
+ // models/User.js
229
+ import Model from "ilana-orm/orm/Model";
220
230
 
221
231
  class User extends Model {
222
232
  static table = "users";
@@ -246,7 +256,8 @@ class User extends Model {
246
256
  }
247
257
  }
248
258
 
249
- module.exports = User;
259
+ export default User; // For ES modules
260
+ // module.exports = User; // For CommonJS
250
261
  ```
251
262
 
252
263
  **TypeScript (auto-generated when `tsconfig.json` detected):**
@@ -294,8 +305,14 @@ npx ilana migrate
294
305
 
295
306
  ### 6. Start Using the Model
296
307
 
308
+ **CommonJS:**
297
309
  ```javascript
298
310
  const User = require("./models/User");
311
+ ```
312
+
313
+ **ES Modules:**
314
+ ```javascript
315
+ import User from "./models/User.js";
299
316
 
300
317
  // Create user
301
318
  const user = await User.create({
package/cli/ilana.js CHANGED
@@ -31,26 +31,39 @@ const defaultConfig = {
31
31
 
32
32
  // Load configuration and auto-initialize
33
33
  async function loadConfig() {
34
- const configPath = path.join(process.cwd(), 'ilana.config.js');
35
- if (fs.existsSync(configPath)) {
36
- delete require.cache[configPath];
34
+ const configPathJs = path.join(process.cwd(), 'ilana.config.js');
35
+ const configPathMjs = path.join(process.cwd(), 'ilana.config.mjs');
36
+
37
+ // Try .mjs first (ES modules)
38
+ if (fs.existsSync(configPathMjs)) {
39
+ try {
40
+ const configModule = await import(configPathMjs);
41
+ const config = configModule.default || configModule;
42
+ return config;
43
+ } catch (error) {
44
+ console.error('Error loading ilana.config.mjs:', error.message);
45
+ process.exit(1);
46
+ }
47
+ }
48
+
49
+ // Try .js (CommonJS)
50
+ if (fs.existsSync(configPathJs)) {
51
+ delete require.cache[configPathJs];
37
52
  try {
38
- const config = require(configPath);
39
- // Config file already initializes database
53
+ const config = require(configPathJs);
40
54
  return config;
41
55
  } catch (error) {
42
56
  if (error.code === 'ERR_REQUIRE_ESM') {
43
- // Handle ES modules
44
- const configModule = await import(configPath);
45
- const config = configModule.default || configModule;
46
- return config;
57
+ console.error('Found ilana.config.js but project uses ES modules. Rename to ilana.config.mjs');
58
+ process.exit(1);
47
59
  } else {
48
60
  throw error;
49
61
  }
50
62
  }
51
63
  }
52
- // No config file found - don't initialize with hardcoded default
53
- console.error('No ilana.config.js found. Run "npx ilana setup" first.');
64
+
65
+ // No config file found
66
+ console.error('No ilana.config.js or ilana.config.mjs found. Run "npx ilana setup" first.');
54
67
  process.exit(1);
55
68
  }
56
69
 
@@ -130,9 +143,11 @@ function generateModel(name, options = {}) {
130
143
  }
131
144
 
132
145
  function getModelTemplate(className, tableName) {
146
+ const isESModule = isESModuleProject();
147
+
133
148
  if (isTypeScriptProject()) {
134
- return `import Model from 'ilana-orm/orm/Model.js';
135
- // import { MoneyCast, EncryptedCast } from 'ilana-orm/orm/CustomCasts.js';
149
+ return `import Model from 'ilana-orm/orm/Model';
150
+ // import { MoneyCast, EncryptedCast } from 'ilana-orm/orm/CustomCasts';
136
151
 
137
152
  export default class ${className} extends Model {
138
153
  protected static table = '${tableName}';
@@ -175,6 +190,53 @@ export default class ${className} extends Model {
175
190
  `;
176
191
  }
177
192
 
193
+ if (isESModule) {
194
+ return `import Model from 'ilana-orm/orm/Model';
195
+ // import { MoneyCast, EncryptedCast } from 'ilana-orm/orm/CustomCasts';
196
+
197
+ class ${className} extends Model {
198
+ static table = '${tableName}';
199
+ static timestamps = true;
200
+ static softDeletes = false;
201
+
202
+ // For UUID primary keys, uncomment:
203
+ // static keyType = 'string';
204
+ // static incrementing = false;
205
+
206
+ fillable = [];
207
+ hidden = [];
208
+ appends = [];
209
+ casts = {
210
+ // Basic casts
211
+ // is_active: 'boolean',
212
+ // metadata: 'json',
213
+ // tags: 'array',
214
+
215
+ // Custom casts
216
+ // price: new MoneyCast(),
217
+ // secret: new EncryptedCast('your-key'),
218
+ };
219
+
220
+ // Define relationships here
221
+ // example() {
222
+ // return this.hasMany(RelatedModel, 'foreign_key');
223
+ // }
224
+
225
+ // Define scopes here
226
+ // static scopeActive(query) {
227
+ // query.where('is_active', true);
228
+ // }
229
+
230
+ // Register for polymorphic relationships
231
+ // static {
232
+ // this.register();
233
+ // }
234
+ }
235
+
236
+ export default ${className};
237
+ `;
238
+ }
239
+
178
240
  return `const Model = require('ilana-orm/orm/Model');
179
241
  // const { MoneyCast, EncryptedCast } = require('ilana-orm/orm/CustomCasts');
180
242
 
@@ -222,8 +284,10 @@ module.exports = ${className};
222
284
  }
223
285
 
224
286
  function getPivotModelTemplate(className, tableName) {
287
+ const isESModule = isESModuleProject();
288
+
225
289
  if (isTypeScriptProject()) {
226
- return `import Model from 'ilana-orm/orm/Model.js';
290
+ return `import Model from 'ilana-orm/orm/Model';
227
291
 
228
292
  export default class ${className} extends Model {
229
293
  protected static table = '${tableName}';
@@ -236,6 +300,22 @@ export default class ${className} extends Model {
236
300
  `;
237
301
  }
238
302
 
303
+ if (isESModule) {
304
+ return `import Model from 'ilana-orm/orm/Model';
305
+
306
+ class ${className} extends Model {
307
+ static table = '${tableName}';
308
+ static timestamps = true;
309
+
310
+ fillable = [];
311
+
312
+ // Define pivot relationships here
313
+ }
314
+
315
+ export default ${className};
316
+ `;
317
+ }
318
+
239
319
  return `const Model = require('ilana-orm/orm/Model');
240
320
 
241
321
  class ${className} extends Model {
@@ -350,10 +430,16 @@ const commands = {
350
430
  }
351
431
 
352
432
  // Create config file if it doesn't exist
353
- const configPath = 'ilana.config.js';
433
+ const isESModule = isESModuleProject();
434
+ const configPath = isESModule ? 'ilana.config.mjs' : 'ilana.config.js';
435
+
354
436
  if (!fs.existsSync(configPath)) {
355
- const isESModule = isESModuleProject();
356
437
  const configTemplate = isESModule ? getESModuleConfigTemplate() : getCommonJSConfigTemplate();
438
+ fs.writeFileSync(configPath, configTemplate);
439
+ console.log(`Created config file: ${configPath}`);
440
+ }
441
+ },
442
+ };
357
443
 
358
444
  function getESModuleConfigTemplate() {
359
445
  return `import 'dotenv/config';
@@ -470,9 +556,6 @@ Database.configure(config);
470
556
  module.exports = config;
471
557
  `;
472
558
  }
473
- fs.writeFileSync(configPath, configTemplate);
474
- console.log(`Created config file: ${configPath}`);
475
- }
476
559
 
477
560
  // Create .env file if it doesn't exist
478
561
  const envPath = '.env';
@@ -0,0 +1,7 @@
1
+ // connection.mjs - ES Module wrapper
2
+ import { createRequire } from 'module';
3
+ const require = createRequire(import.meta.url);
4
+
5
+ const Database = require('./connection.js');
6
+
7
+ export default Database;
@@ -0,0 +1,44 @@
1
+ // ilana.config.mjs - ES Module config example
2
+ export default {
3
+ default: "sqlite",
4
+
5
+ connections: {
6
+ sqlite: {
7
+ client: "sqlite3",
8
+ connection: {
9
+ filename: "./database.sqlite",
10
+ },
11
+ },
12
+
13
+ mysql: {
14
+ client: "mysql2",
15
+ connection: {
16
+ host: "localhost",
17
+ port: 3306,
18
+ user: "your_username",
19
+ password: "your_password",
20
+ database: "your_database",
21
+ },
22
+ },
23
+
24
+ postgres: {
25
+ client: "pg",
26
+ connection: {
27
+ host: "localhost",
28
+ port: 5432,
29
+ user: "your_username",
30
+ password: "your_password",
31
+ database: "your_database",
32
+ },
33
+ },
34
+ },
35
+
36
+ migrations: {
37
+ directory: "./migrations",
38
+ tableName: "migrations",
39
+ },
40
+
41
+ seeds: {
42
+ directory: "./seeds",
43
+ },
44
+ };
package/index.mjs ADDED
@@ -0,0 +1,33 @@
1
+ // index.mjs - ES Module wrapper
2
+ import { createRequire } from 'module';
3
+ const require = createRequire(import.meta.url);
4
+
5
+ const exports = require('./index.js');
6
+
7
+ export const {
8
+ Model,
9
+ QueryBuilder,
10
+ Collection,
11
+ Database,
12
+ DB,
13
+ SchemaBuilder,
14
+ MigrationRunner,
15
+ Seeder,
16
+ Factory,
17
+ defineFactory,
18
+ Relation,
19
+ HasOne,
20
+ HasMany,
21
+ BelongsTo,
22
+ BelongsToMany,
23
+ HasManyThrough,
24
+ MorphTo,
25
+ MorphMany,
26
+ MoneyCast,
27
+ EncryptedCast,
28
+ JsonCast,
29
+ ArrayCast,
30
+ DateCast
31
+ } = exports;
32
+
33
+ export default exports.Model;
@@ -0,0 +1,7 @@
1
+ // Collection.mjs - ES Module wrapper
2
+ import { createRequire } from 'module';
3
+ const require = createRequire(import.meta.url);
4
+
5
+ const Collection = require('./Collection.js');
6
+
7
+ export default Collection;
package/orm/Model.js CHANGED
@@ -8,10 +8,14 @@ const Database = require('../database/connection');
8
8
  (function autoLoadConfig() {
9
9
  const fs = require('fs');
10
10
  const path = require('path');
11
- const configPath = path.join(process.cwd(), 'ilana.config.js');
12
- if (fs.existsSync(configPath)) {
13
- delete require.cache[configPath];
14
- require(configPath);
11
+ const configPathJs = path.join(process.cwd(), 'ilana.config.js');
12
+ const configPathMjs = path.join(process.cwd(), 'ilana.config.mjs');
13
+
14
+ if (fs.existsSync(configPathJs)) {
15
+ delete require.cache[configPathJs];
16
+ require(configPathJs);
17
+ } else if (fs.existsSync(configPathMjs)) {
18
+ // For ES modules, we'll handle this in the _getConfig method
15
19
  }
16
20
  })();
17
21
 
@@ -371,9 +375,19 @@ class Model {
371
375
  _getConfig() {
372
376
  try {
373
377
  const path = require('path');
374
- const configPath = path.join(process.cwd(), 'ilana.config.js');
375
- delete require.cache[configPath];
376
- return require(configPath);
378
+ const fs = require('fs');
379
+ const configPathJs = path.join(process.cwd(), 'ilana.config.js');
380
+ const configPathMjs = path.join(process.cwd(), 'ilana.config.mjs');
381
+
382
+ if (fs.existsSync(configPathJs)) {
383
+ delete require.cache[configPathJs];
384
+ return require(configPathJs);
385
+ } else if (fs.existsSync(configPathMjs)) {
386
+ // For ES modules, return a promise or handle async import
387
+ // For now, return null and let the caller handle it
388
+ return null;
389
+ }
390
+ return null;
377
391
  } catch (e) {
378
392
  return null;
379
393
  }
package/orm/Model.mjs ADDED
@@ -0,0 +1,7 @@
1
+ // Model.mjs - ES Module wrapper
2
+ import { createRequire } from 'module';
3
+ const require = createRequire(import.meta.url);
4
+
5
+ const Model = require('./Model.js');
6
+
7
+ export default Model;
@@ -0,0 +1,7 @@
1
+ // ModelRegistry.mjs - ES Module wrapper
2
+ import { createRequire } from 'module';
3
+ const require = createRequire(import.meta.url);
4
+
5
+ const ModelRegistry = require('./ModelRegistry.js');
6
+
7
+ export default ModelRegistry;
@@ -0,0 +1,7 @@
1
+ // QueryBuilder.mjs - ES Module wrapper
2
+ import { createRequire } from 'module';
3
+ const require = createRequire(import.meta.url);
4
+
5
+ const QueryBuilder = require('./QueryBuilder.js');
6
+
7
+ export default QueryBuilder;
@@ -0,0 +1,7 @@
1
+ // Relation.mjs - ES Module wrapper
2
+ import { createRequire } from 'module';
3
+ const require = createRequire(import.meta.url);
4
+
5
+ const Relations = require('./Relation.js');
6
+
7
+ export const { Relation, HasOne, HasMany, BelongsTo, BelongsToMany, HasManyThrough, MorphTo, MorphMany } = Relations;
package/package.json CHANGED
@@ -1,9 +1,36 @@
1
1
  {
2
2
  "name": "ilana-orm",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
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",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./index.mjs",
10
+ "require": "./index.js",
11
+ "types": "./index.d.ts"
12
+ },
13
+ "./orm/Model": {
14
+ "import": "./orm/Model.mjs",
15
+ "require": "./orm/Model.js",
16
+ "types": "./orm/Model.d.ts"
17
+ },
18
+ "./orm/QueryBuilder": {
19
+ "import": "./orm/QueryBuilder.mjs",
20
+ "require": "./orm/QueryBuilder.js",
21
+ "types": "./orm/QueryBuilder.d.ts"
22
+ },
23
+ "./orm/Collection": {
24
+ "import": "./orm/Collection.mjs",
25
+ "require": "./orm/Collection.js",
26
+ "types": "./orm/Collection.d.ts"
27
+ },
28
+ "./database/connection": {
29
+ "import": "./database/connection.mjs",
30
+ "require": "./database/connection.js",
31
+ "types": "./database/connection.d.ts"
32
+ }
33
+ },
7
34
  "bin": {
8
35
  "ilana": "cli/ilana.js"
9
36
  },
@@ -39,11 +66,14 @@
39
66
  },
40
67
  "files": [
41
68
  "*.js",
69
+ "*.mjs",
42
70
  "*.d.ts",
43
71
  "cli/**/*.js",
44
72
  "database/**/*.js",
73
+ "database/**/*.mjs",
45
74
  "database/**/*.d.ts",
46
75
  "orm/**/*.js",
76
+ "orm/**/*.mjs",
47
77
  "orm/**/*.d.ts",
48
78
  "README.md",
49
79
  "LICENSE",