lamix 4.2.9 → 4.2.11

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
@@ -106,6 +106,185 @@ npm i lamix
106
106
 
107
107
  npm install mysql2 # or pg or sqlite3
108
108
 
109
- ```bash
110
109
  # TO See All the Available CLI Commands Run in Terminal
111
110
  npx lamix
111
+
112
+ #Basic CRUD & Query
113
+
114
+ const User = require('./models/User');
115
+
116
+ # Create new user
117
+ const user = await User.create({ name: 'Alice', email: 'alice@example.com', password: 'secret' });
118
+
119
+ # Fill & save (update)
120
+ user.name = 'Alice Smith'; // you can also use user.fill({ name: 'Alice Smith' })
121
+ await user.save();
122
+
123
+ # Find by primary key
124
+ const user1 = await User.find(1);
125
+ const user2 = await User.findOrFail(param.id);
126
+
127
+ # Query with where
128
+ const someUsers = await User.where('email', 'alice@example.com').get();
129
+
130
+ # First match
131
+ const firstUser = await User.where('name', 'Alice').first();
132
+ const firstOrFail = await User.where('name', 'Alice').firstOrFail();
133
+
134
+ const user = await User.findBy('email', 'jane@example.com');
135
+ # by default Field password is Auto encrypted when creating
136
+ const isValid = await user.checkPassword('user_input_password');
137
+ # Delete (soft delete if enabled)
138
+ await user.delete();
139
+
140
+ # destroy (delete Multiple ids)
141
+ await user.destroy();
142
+
143
+ # update (by default)
144
+ await user.update({ body });
145
+
146
+ # or update
147
+ await user.fill({ body });
148
+ await user.save();
149
+
150
+ # Restore (if softDeletes enabled)
151
+ await user.restore();
152
+
153
+ # List all (excluding trashed, by default)
154
+ const allUsers = await User.all();
155
+
156
+ # Query including soft-deleted (trashed) records
157
+ const withTrashed = await User.withTrashed().where('id', 1).first();
158
+
159
+ #QueryBuilder Advanced Features
160
+
161
+ const qb = User.query();
162
+
163
+ # Select specific columns
164
+ const names = await User.query().select('id', 'name').get();
165
+
166
+ # Aggregates
167
+ const cnt = await User.query().count(); // count(*)
168
+ const sumId = await User.query().sum('id');
169
+ const avgId = await User.query().avg('id');
170
+ const minId = await User.query().min('id');
171
+ const maxId = await User.query().max('id');
172
+
173
+ # status a column (returns status of boolean values)
174
+ const usersAll = await User.all();
175
+ const users = await User.query().where('status', true).get();
176
+ const usersorderbyid = await User.query().where('status', true).orderBy('id', 'desc').get();
177
+ const usersorderbycreateAt = await User.query().where('status', true).orderBy('created_at', 'desc').get();
178
+
179
+ # Pluck a column (returns array of values)
180
+ const Pluckemails = await User.query().pluck('email');
181
+
182
+ # Pagination
183
+ const page1 = await User.query().paginate(1, 10);
184
+ // page1 = { total, perPage, page, lastPage, data: [users...] }
185
+
186
+ # Where In
187
+ const usersIn = await User.query().whereIn('id', [1, 2, 3]).get();
188
+
189
+ // Where Null / Not Null
190
+ const withNull = await User.query().whereNull('deleted_at').get();
191
+ const notNull = await User.query().whereNotNull('deleted_at').get();
192
+
193
+ # Where Between
194
+ const inRange = await User.query().whereBetween('id', [10, 20]).get();
195
+
196
+ # Ordering, grouping, having
197
+ const grouped = await User.query()
198
+ .select('user_id', 'COUNT(*) as cnt')
199
+ .groupBy('user_id')
200
+ .having('cnt', '>', 1)
201
+ .get();
202
+
203
+ # Joins
204
+ const withPosts = await User.query()
205
+ .select('users.*', 'posts.title as post_title')
206
+ .join('INNER', 'posts', 'users.id', '=', 'posts.user_id')
207
+ .get();
208
+
209
+ # Using “forUpdate” (locking)
210
+ await User.query().where('id', 5).forUpdate().get();
211
+
212
+ # Raw queries
213
+ const rows = await User.raw('SELECT * FROM users WHERE id = ?', [5]);
214
+
215
+ # Caching
216
+ const cachedRows = await User.raw('SELECT * FROM users', []).then(rows => rows);
217
+ const cached = await DB.cached('SELECT * FROM users WHERE id = ?', [5], 60000);
218
+
219
+ #You can use relations:
220
+
221
+ const user = await User.find(1);
222
+ const posts = await user.posts().get(); // all posts for the user
223
+
224
+ # Eager load in a query with Relations:
225
+ const usersWithPosts = await User.query().with('posts').get();
226
+ # Each user will have a `posts` field with array of post models.
227
+
228
+ # Many-to-many example
229
+ # Suppose you have an intermediate pivot table user_roles (user_id, role_id)
230
+ # and models User and Role, with pivot user_roles.
231
+ #
232
+
233
+ # Then:
234
+ const user = await User.find(2);
235
+ const roles = await user.roles().get();
236
+
237
+ # Eager load with Relations:
238
+ const usersWithRoles = await User.query().with('roles').get();
239
+
240
+ # Eager load with Many to Many Relations:
241
+ const usersWith_Roles_posts_comments = await User.query().with(['roles', 'posts', 'comments' ]).get();
242
+ #OR with Many to Many Relations:
243
+ const users_With_Roles_posts_comments = await User.with(['roles', 'posts', 'comments' ]).get();
244
+
245
+ # Find by field
246
+ const user = await User.findBy('email', 'jane@example.com');
247
+
248
+ # Check hashed password
249
+ const isValid = await user.checkPassword('password');
250
+
251
+ # models/User.js(Example)
252
+ const { BaseModel} = require('lamix');
253
+
254
+ class User extends BaseModel {
255
+ static table = 'users';
256
+ static primaryKey = 'id';
257
+ static timestamps = true;
258
+ static softDeletes = false; # Optional if you don't need it
259
+ static fillable = ['name', 'email', 'password']; # password is Auto encrypted when creating.
260
+ static rules = { # Optional if you don't need it
261
+ name: 'required|string',
262
+ email: 'required|email|unique:users,email',
263
+ password: 'required|string|min:6',
264
+ phone: 'nullable|phone',
265
+ status: 'boolean'
266
+ };
267
+
268
+ profile() {
269
+ const Profile = require('./Profile');
270
+ return this.hasOne(Profile).onDelete('restrict');
271
+ }
272
+
273
+
274
+ // Many-to-many: User ↔ Role via pivot user_roles (user_id, role_id)
275
+ roles() {
276
+ const Role = require('./Role');
277
+ return this.belongsToMany(
278
+ Role,
279
+ 'user_roles',
280
+ 'user_id',
281
+ 'role_id'
282
+ ).onDelete('detach');
283
+ }
284
+
285
+ // One-to-many: User -> Post
286
+ posts() {
287
+ const Post = require('./Post');
288
+ return this.hasMany(Post', 'user_id', 'id').onDelete('cascade');
289
+ }
290
+ }
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  const fs = require('fs');
4
4
  const path = require('path');
@@ -7,7 +7,10 @@ export class DB {
7
7
  static eventHandlers: {
8
8
  query: any[];
9
9
  error: any[];
10
+ reconnect: any[];
10
11
  };
12
+ static _grammar: any;
13
+ static _als: AsyncLocalStorage<any>;
11
14
  static initFromEnv({ driver, config, retryAttempts }?: {
12
15
  driver?: string;
13
16
  config?: any;
@@ -17,17 +20,22 @@ export class DB {
17
20
  static _emit(event: any, payload: any): void;
18
21
  static _ensureModule(): any;
19
22
  static connect(): Promise<any>;
23
+ static getConnection(): Promise<any>;
24
+ static reconnect(): Promise<any>;
20
25
  static end(): Promise<void>;
21
- static _pgConvert(sql: any, params: any): {
22
- text: any;
23
- values: any;
24
- };
25
- static _extractTable(sql: any): string;
26
- static _tableExists(table: any): Promise<boolean>;
27
- static raw(sql: any, params?: any[], options?: {}): Promise<any>;
26
+ static run(sql: any, bindings: any, executor: any, { isWrite }?: {
27
+ isWrite?: boolean;
28
+ }): Promise<any>;
29
+ static raw(sql: any, bindings?: any[]): Promise<any>;
30
+ static affectingStatement(sql: any, bindings?: any[]): Promise<any>;
31
+ static select(sql: any, bindings?: any[]): Promise<any>;
32
+ static statement(sql: any, bindings?: any[]): Promise<any>;
33
+ static insert(sql: any, bindings?: any[]): Promise<any>;
34
+ static update(sql: any, bindings?: any[]): Promise<any>;
35
+ static delete(sql: any, bindings?: any[]): Promise<any>;
28
36
  static transaction(fn: any): Promise<any>;
29
37
  static escapeId(id: any): any;
30
- static cached(sql: any, params?: any[], ttl?: number): Promise<any>;
38
+ static cached(sql: any, bindings?: any[], ttl?: number): Promise<any>;
31
39
  }
32
40
  export class Model {
33
41
  static table: any;
@@ -520,6 +528,7 @@ declare class SimpleCache {
520
528
  del(k: any): void;
521
529
  clear(): void;
522
530
  }
531
+ import { AsyncLocalStorage } from "node:async_hooks";
523
532
  declare class HasManyThrough extends Relation {
524
533
  constructor(parent: any, relatedClass: any, throughClass: any, firstKey: any, secondKey: any, localKey: any, secondLocalKey: any);
525
534
  throughClass: any;
@@ -2,6 +2,7 @@
2
2
 
3
3
  const util = require('util');
4
4
  const { performance } = require('perf_hooks');
5
+ const { AsyncLocalStorage } = require('async_hooks');
5
6
  require('dotenv').config();
6
7
 
7
8
  /* ---------------- Utilities ---------------- */
@@ -10,6 +11,8 @@ function tryRequire(name) {
10
11
  try { return require(name); } catch { return null; }
11
12
  }
12
13
 
14
+ const sleep = ms => new Promise(r => setTimeout(r, ms));
15
+
13
16
  /* ---------------- Errors ---------------- */
14
17
 
15
18
  class DBError extends Error {
@@ -17,6 +20,7 @@ class DBError extends Error {
17
20
  super(message);
18
21
  this.name = 'DBError';
19
22
  this.meta = meta;
23
+ if (meta.err?.stack) this.stack += `\nCaused by: ${meta.err.stack}`;
20
24
  }
21
25
  }
22
26
 
@@ -33,20 +37,45 @@ class SimpleCache {
33
37
  }
34
38
  return e.v;
35
39
  }
36
- set(k, v, ttl = 0) { this.map.set(k, { v, ts: Date.now(), ttl }); }
40
+ set(k, v, ttl = 0) {
41
+ this.map.set(k, { v, ts: Date.now(), ttl });
42
+ }
37
43
  del(k) { this.map.delete(k); }
38
44
  clear() { this.map.clear(); }
39
45
  }
40
46
 
47
+ /* ---------------- Grammar ---------------- */
48
+
49
+ class Grammar {
50
+ prepare(sql, bindings) {
51
+ return { sql, bindings };
52
+ }
53
+ }
54
+
55
+ class PostgresGrammar extends Grammar {
56
+ prepare(sql, bindings) {
57
+ let i = 0;
58
+ return {
59
+ sql: sql.replace(/\?/g, () => `$${++i}`),
60
+ bindings
61
+ };
62
+ }
63
+ }
64
+
41
65
  /* ---------------- DB Core ---------------- */
42
66
 
43
67
  class DB {
44
68
  static driver = null;
45
69
  static config = null;
46
70
  static pool = null;
71
+
47
72
  static cache = new SimpleCache();
48
73
  static retryAttempts = 1;
49
- static eventHandlers = { query: [], error: [] };
74
+
75
+ static eventHandlers = { query: [], error: [], reconnect: [] };
76
+
77
+ static _grammar = null;
78
+ static _als = new AsyncLocalStorage();
50
79
 
51
80
  /* ---------- Init ---------- */
52
81
 
@@ -58,6 +87,9 @@ class DB {
58
87
  this.driver = driver.toLowerCase();
59
88
  this.retryAttempts = Math.max(1, Number(retryAttempts));
60
89
 
90
+ this._grammar =
91
+ this.driver === 'pg' ? new PostgresGrammar() : new Grammar();
92
+
61
93
  if (config) {
62
94
  this.config = config;
63
95
  return;
@@ -128,7 +160,7 @@ class DB {
128
160
  throw new DBError(`Unsupported driver: ${this.driver}`);
129
161
  }
130
162
 
131
- /* ---------- Connect ---------- */
163
+ /* ---------- Connection ---------- */
132
164
 
133
165
  static async connect() {
134
166
  if (this.pool) return this.pool;
@@ -137,26 +169,25 @@ class DB {
137
169
 
138
170
  if (this.driver === 'mysql') {
139
171
  this.pool = driver.createPool(this.config);
140
- return this.pool;
141
172
  }
142
173
 
143
174
  if (this.driver === 'pg') {
144
175
  const { Pool } = driver;
145
176
  this.pool = new Pool(this.config);
146
- return this.pool;
147
177
  }
148
178
 
149
179
  if (this.driver === 'sqlite') {
150
180
  const db = new driver.Database(this.config.filename);
151
-
152
181
  db.runAsync = util.promisify(db.run.bind(db));
153
- db.getAsync = util.promisify(db.get.bind(db));
154
182
  db.allAsync = util.promisify(db.all.bind(db));
155
183
  db.execAsync = util.promisify(db.exec.bind(db));
156
184
 
185
+ await db.execAsync('PRAGMA journal_mode=WAL');
186
+ await db.execAsync('PRAGMA busy_timeout=5000');
187
+
157
188
  this.pool = {
158
189
  __sqlite_db: db,
159
- query: async (sql, params = []) => {
190
+ async query(sql, params = []) {
160
191
  const isSelect = /^\s*(select|pragma)/i.test(sql);
161
192
  if (isSelect) return [await db.allAsync(sql, params)];
162
193
  const r = await db.runAsync(sql, params);
@@ -164,9 +195,21 @@ class DB {
164
195
  },
165
196
  close: () => new Promise((r, j) => db.close(e => e ? j(e) : r()))
166
197
  };
167
-
168
- return this.pool;
169
198
  }
199
+
200
+ return this.pool;
201
+ }
202
+
203
+ static async getConnection() {
204
+ const store = this._als.getStore();
205
+ if (store?.conn) return store.conn;
206
+ return this.connect();
207
+ }
208
+
209
+ static async reconnect() {
210
+ await this.end();
211
+ this._emit('reconnect', {});
212
+ return this.connect();
170
213
  }
171
214
 
172
215
  static async end() {
@@ -179,159 +222,130 @@ class DB {
179
222
  }
180
223
  }
181
224
 
182
- /* ---------- Query ---------- */
183
-
184
- static _pgConvert(sql, params) {
185
- let i = 0;
186
- return {
187
- text: sql.replace(/\?/g, () => `$${++i}`),
188
- values: params
189
- };
190
- }
191
-
192
- static _extractTable(sql) {
193
- if (typeof sql !== 'string') return null;
194
-
195
- const cleaned = sql
196
- .replace(/`|"|\[|\]/g, '')
197
- .replace(/\s+/g, ' ')
198
- .trim()
199
- .toLowerCase();
200
-
201
- const match =
202
- cleaned.match(/\bfrom\s+([a-z0-9_]+)/) ||
203
- cleaned.match(/\binto\s+([a-z0-9_]+)/) ||
204
- cleaned.match(/\bupdate\s+([a-z0-9_]+)/);
205
-
206
- return match ? match[1] : null;
207
- }
208
-
209
- static async _tableExists(table) {
210
- if (!table) return true;
211
-
212
- const pool = await this.connect();
213
-
214
- if (this.driver === 'mysql') {
215
- const [rows] = await pool.query(
216
- `SELECT 1 FROM information_schema.tables
217
- WHERE table_schema = DATABASE() AND table_name = ? LIMIT 1`,
218
- [table]
219
- );
220
- return rows.length > 0;
221
- }
222
-
223
- if (this.driver === 'pg') {
224
- const res = await pool.query(
225
- `SELECT 1 FROM information_schema.tables
226
- WHERE table_schema = 'public' AND table_name = $1 LIMIT 1`,
227
- [table]
228
- );
229
- return res.rows.length > 0;
230
- }
231
-
232
- if (this.driver === 'sqlite') {
233
- const [rows] = await pool.query(
234
- `SELECT 1 FROM sqlite_master WHERE type='table' AND name=? LIMIT 1`,
235
- [table]
236
- );
237
- return rows.length > 0;
238
- }
239
-
240
- return true;
241
- }
242
-
243
- static async raw(sql, params = [], options = {}) {
244
- const { checkTable = false } = options;
245
- if (checkTable) {
246
- const table = this._extractTable(sql);
247
- if (table) {
248
- const exists = await this._tableExists(table);
249
- if (!exists) {
250
- throw new DBError(`Table does not exist: ${table}`, { sql });
251
- }
252
- }
253
- }
225
+ /* ---------- Core Runner ---------- */
254
226
 
227
+ static async run(sql, bindings, executor, { isWrite = false } = {}) {
255
228
  let attempt = 0;
256
229
 
257
230
  while (++attempt <= this.retryAttempts) {
258
- const pool = await this.connect();
259
231
  const start = performance.now();
260
232
 
261
233
  try {
262
- this._emit('query', { sql, params });
263
-
264
- if (this.driver === 'pg') {
265
- const q = this._pgConvert(sql, params);
266
- const r = await pool.query(q.text, q.values);
267
- return r.rows;
268
- }
269
-
270
- const [rows] = await pool.query(sql, params);
271
- return rows;
272
-
234
+ const result = await executor();
235
+ this._emit('query', {
236
+ sql,
237
+ bindings,
238
+ time: performance.now() - start,
239
+ driver: this.driver
240
+ });
241
+ return result;
273
242
  } catch (err) {
274
- this._emit('error', { err, sql, params, attempt });
275
-
276
- if (attempt < this.retryAttempts &&
277
- /dead|lost|timeout|reset/i.test(err.message)) {
278
- await this.end();
279
- await new Promise(r => setTimeout(r, 100 * attempt));
243
+ this._emit('error', { err, sql, bindings, attempt });
244
+
245
+ const canRetry =
246
+ !isWrite ||
247
+ this._als.getStore()?.inTransaction;
248
+
249
+ if (
250
+ canRetry &&
251
+ attempt < this.retryAttempts &&
252
+ /dead|lost|timeout|reset|closed/i.test(err.message)
253
+ ) {
254
+ await this.reconnect();
255
+ await sleep(100 * attempt);
280
256
  continue;
281
257
  }
282
258
 
283
- throw new DBError('DB raw() failed', { sql, params, err });
259
+ throw new DBError('DB query failed', { sql, bindings, err });
284
260
  }
285
261
  }
286
262
  }
287
263
 
264
+ /* ---------- Queries ---------- */
265
+
266
+ static async raw(sql, bindings = []) {
267
+ const pool = await this.getConnection();
268
+ const prepared = this._grammar.prepare(sql, bindings);
269
+
270
+ return this.run(sql, bindings, async () => {
271
+ if (this.driver === 'pg') {
272
+ const r = await pool.query(prepared.sql, prepared.bindings);
273
+ return r.rows;
274
+ }
275
+ const [rows] = await pool.query(prepared.sql, prepared.bindings);
276
+ return rows;
277
+ });
278
+ }
279
+
280
+ static async affectingStatement(sql, bindings = []) {
281
+ const pool = await this.getConnection();
282
+ const prepared = this._grammar.prepare(sql, bindings);
283
+
284
+ return this.run(sql, bindings, async () => {
285
+ if (this.driver === 'pg') {
286
+ const r = await pool.query(prepared.sql, prepared.bindings);
287
+ return { affectedRows: r.rowCount };
288
+ }
289
+ const [r] = await pool.query(prepared.sql, prepared.bindings);
290
+ return r;
291
+ }, { isWrite: true });
292
+ }
293
+
294
+ static select(sql, bindings = []) { return this.raw(sql, bindings); }
295
+ static statement(sql, bindings = []) { return this.affectingStatement(sql, bindings); }
296
+ static insert(sql, bindings = []) {
297
+ return this.affectingStatement(sql, bindings)
298
+ .then(r => r.insertId ?? true);
299
+ }
300
+ static update(sql, bindings = []) {
301
+ return this.affectingStatement(sql, bindings)
302
+ .then(r => r.affectedRows ?? 0);
303
+ }
304
+ static delete(sql, bindings = []) { return this.update(sql, bindings); }
305
+
288
306
  /* ---------- Transactions ---------- */
289
307
 
290
308
  static async transaction(fn) {
291
309
  const pool = await this.connect();
292
310
 
293
- if (this.driver === 'mysql') {
294
- const c = await pool.getConnection();
295
- try {
296
- await c.beginTransaction();
297
- const r = await fn(c);
298
- await c.commit();
299
- return r;
300
- } catch (e) {
301
- await c.rollback();
302
- throw e;
303
- } finally {
304
- c.release();
305
- }
306
- }
311
+ return this._als.run({ inTransaction: true }, async () => {
312
+ let conn;
307
313
 
308
- if (this.driver === 'pg') {
309
- const c = await pool.connect();
310
314
  try {
311
- await c.query('BEGIN');
312
- const r = await fn(c);
313
- await c.query('COMMIT');
314
- return r;
315
- } catch (e) {
316
- await c.query('ROLLBACK');
317
- throw e;
318
- } finally {
319
- c.release();
320
- }
321
- }
315
+ if (this.driver === 'mysql') {
316
+ conn = await pool.getConnection();
317
+ await conn.beginTransaction();
318
+ this._als.getStore().conn = conn;
319
+ const r = await fn(conn);
320
+ await conn.commit();
321
+ return r;
322
+ }
322
323
 
323
- if (this.driver === 'sqlite') {
324
- const db = pool.__sqlite_db;
325
- try {
326
- await db.execAsync('BEGIN');
327
- const r = await fn(pool);
328
- await db.execAsync('COMMIT');
329
- return r;
324
+ if (this.driver === 'pg') {
325
+ conn = await pool.connect();
326
+ await conn.query('BEGIN');
327
+ this._als.getStore().conn = conn;
328
+ const r = await fn(conn);
329
+ await conn.query('COMMIT');
330
+ return r;
331
+ }
332
+
333
+ if (this.driver === 'sqlite') {
334
+ await pool.__sqlite_db.execAsync('BEGIN');
335
+ this._als.getStore().conn = pool;
336
+ const r = await fn(pool);
337
+ await pool.__sqlite_db.execAsync('COMMIT');
338
+ return r;
339
+ }
330
340
  } catch (e) {
331
- await db.execAsync('ROLLBACK');
341
+ try {
342
+ await conn?.query?.('ROLLBACK');
343
+ } catch {}
332
344
  throw e;
345
+ } finally {
346
+ conn?.release?.();
333
347
  }
334
- }
348
+ });
335
349
  }
336
350
 
337
351
  /* ---------- Helpers ---------- */
@@ -344,11 +358,11 @@ class DB {
344
358
  : `\`${id.replace(/`/g, '``')}\``;
345
359
  }
346
360
 
347
- static async cached(sql, params = [], ttl = 0) {
348
- const key = JSON.stringify([sql, params]);
361
+ static async cached(sql, bindings = [], ttl = 0) {
362
+ const key = JSON.stringify([sql, bindings]);
349
363
  const hit = this.cache.get(key);
350
364
  if (hit) return hit;
351
- const rows = await this.raw(sql, params);
365
+ const rows = await this.raw(sql, bindings);
352
366
  this.cache.set(key, rows, ttl);
353
367
  return rows;
354
368
  }
@@ -356,6 +370,7 @@ class DB {
356
370
 
357
371
  const escapeId = s => DB.escapeId(s);
358
372
 
373
+
359
374
  // -----------------------------
360
375
  // MAIN Validator
361
376
  // -----------------------------
package/package.json CHANGED
@@ -1,21 +1,17 @@
1
1
  {
2
2
  "name": "lamix",
3
- "version": "4.2.9",
3
+ "version": "4.2.11",
4
4
  "description": "lamix - ORM for Node-express js",
5
- "main": "index.js",
6
- "types": "index.d.ts",
5
+ "main": "./lib",
7
6
  "exports": {
8
7
  ".": {
9
- "import": "./index.js",
10
- "require": "./index.js",
11
- "types": "./index.d.ts"
8
+ "require": "./lib/index.js",
9
+ "types": "./lib/index.d.ts"
12
10
  }
13
11
  },
14
12
  "files": [
15
- "index.js",
16
- "index.d.ts",
17
- "artisan.js",
18
- "artisan.d.ts",
13
+ "lib",
14
+ "bin",
19
15
  "README.md",
20
16
  "examples"
21
17
  ],
@@ -24,7 +20,7 @@
24
20
  "url": "https://github.com/andrewkhabweri-spec/lamix.git"
25
21
  },
26
22
  "bin": {
27
- "lamix": "./artisan.js"
23
+ "lamix": "./bin/cli.js"
28
24
  },
29
25
  "scripts": {
30
26
  "build": "tsc && echo 'Build complete'"
@@ -43,21 +39,14 @@
43
39
  "orm",
44
40
  "nodejs",
45
41
  "database",
46
- "laravel-inspired"
42
+ "sql"
47
43
  ],
48
44
  "author": {
49
45
  "name": "Andrew Khabweri",
50
46
  "email": "andrewkhabweri@gmail.com"
51
47
  },
52
- "tsdown": {
53
- "entry": [
54
- "index.d.ts"
55
- ],
56
- "outDir": ".",
57
- "clean": true,
58
- "dts": true,
59
- "sourcemaps": true,
60
- "theme": "default"
61
- },
62
- "license": "MIT"
48
+ "license": "MIT",
49
+ "engines": {
50
+ "node": ">= 0.8.0"
51
+ }
63
52
  }
File without changes