mango-orm 1.1.2 → 1.1.4

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.
@@ -27,12 +27,13 @@ switch (command) {
27
27
  }
28
28
  function showHelp() {
29
29
  console.log(chalk.bold("Usage:"));
30
- console.log(" npm run migration:generate <name> [outputDir]\n");
30
+ console.log(" mango generate <name> [outputDir]");
31
+ console.log(" npx mango generate <name> [outputDir]\n");
31
32
  console.log(chalk.bold("Commands:"));
32
33
  console.log(chalk.cyan(" generate, g") + " Generate a new migration file");
33
34
  console.log(chalk.cyan(" help, -h") + " Show this help message\n");
34
35
  console.log(chalk.bold("Examples:"));
35
- console.log(" npm run migration:generate create_users_table");
36
- console.log(" npm run migration:generate add_email_column");
37
- console.log(" npm run migration:generate create_posts_table ./db/migrations\n");
36
+ console.log(" mango generate create_users_table");
37
+ console.log(" mango generate add_email_column");
38
+ console.log(" mango generate create_posts_table ./db/migrations\n");
38
39
  }
@@ -0,0 +1,114 @@
1
+ import * as sql from "mysql";
2
+ declare class MangoType {
3
+ private query;
4
+ constructor();
5
+ int(): this;
6
+ bigInt(): this;
7
+ float(): this;
8
+ char(length: number): this;
9
+ text(): this;
10
+ date(): this;
11
+ dateTime(): this;
12
+ timeStamp(): this;
13
+ boolean(): this;
14
+ tinyInt(length: number): this;
15
+ autoIncrement(): this;
16
+ primaryKey(): this;
17
+ varchar(length: number): this;
18
+ notNull(): this;
19
+ unique(): this;
20
+ getQuery(): string;
21
+ }
22
+ declare class MangoQuery {
23
+ private db;
24
+ query: string;
25
+ supplies: any;
26
+ config(db: sql.Pool): void;
27
+ execute<T>(): Promise<T>;
28
+ customQuery<T>(query: string, supplies: any[]): Promise<T>;
29
+ }
30
+ declare class MangoTable<T> {
31
+ private db;
32
+ private tableName;
33
+ private tableFields;
34
+ private query;
35
+ constructor(db: sql.Pool, name: string, fields?: string[]);
36
+ addColumns(fields: Record<string, MangoType>): this;
37
+ removeColumns(fields: string[]): this;
38
+ selectAll(): this;
39
+ selectColumns(columns: string[]): this;
40
+ selectDistinctColumns(columns: string[]): this;
41
+ orderBy(columnName: string): this;
42
+ sort(sort?: number): this;
43
+ limit(length: number): this;
44
+ offset(length: number): this;
45
+ insertOne(data: Record<string, any>): this;
46
+ insertMany(fields: string[], data?: any[][]): this;
47
+ getFields(): string[];
48
+ getName(): string;
49
+ truncate(): this;
50
+ where(field: string, operator: string, value: any): this;
51
+ and(field: string, operator: string, value: any): this;
52
+ or(field: string, operator: string, value: any): this;
53
+ update(data: Record<string, any>): this;
54
+ join(type: 'INNER' | 'LEFT' | 'RIGHT' | 'FULL', table: string, condition: {
55
+ left: string;
56
+ operator: string;
57
+ right: string;
58
+ }): this;
59
+ delete(): this;
60
+ whereIn(field: string, values: any[]): this;
61
+ whereNotIn(field: string, values: any[]): this;
62
+ getQuery(): MangoQuery;
63
+ execute(): Promise<T[]>;
64
+ customQuery<Type>(query: string, supplies: any[]): Promise<Type[]>;
65
+ }
66
+ declare class Mango {
67
+ private db;
68
+ private tables;
69
+ private query;
70
+ connect({ host, user, password, database, connectionLimit, waitForConnection, queueLimit, connectTimeout, charset, }: {
71
+ host: any;
72
+ user: any;
73
+ password: any;
74
+ database: any;
75
+ connectionLimit?: number;
76
+ waitForConnection?: boolean;
77
+ queueLimit?: number;
78
+ connectTimeout?: number;
79
+ charset?: string;
80
+ }): Promise<this>;
81
+ disconnect(): Promise<void>;
82
+ types(): MangoType;
83
+ selectTable<T = any>(name: string): MangoTable<T>;
84
+ getTables(): MangoTable<any>[];
85
+ createTable<T>(name: string, fields: Record<string, MangoType>): Promise<MangoTable<T>>;
86
+ dropTable(name: string): Promise<void>;
87
+ haveTable(name: string): boolean;
88
+ customQuery<Type>(query: string, supplies: any[]): Promise<Type>;
89
+ }
90
+ interface IMangoMigrationType {
91
+ name: string;
92
+ timestamp: number;
93
+ up: (mango: Mango) => Promise<void>;
94
+ down: (mango: Mango) => Promise<void>;
95
+ }
96
+ declare class MangoMigration {
97
+ private mango;
98
+ private mango_migration_table_name;
99
+ private migrations;
100
+ private initialize;
101
+ constructor(mango: Mango);
102
+ private addOneMigrationToDB;
103
+ private addManyMigrationToDB;
104
+ private deleteOneMigrationFromDB;
105
+ private deleteManyMigrationFromDB;
106
+ add(migration: IMangoMigrationType): MangoMigration;
107
+ private getExecutedMigrations;
108
+ migrateUp(): Promise<void>;
109
+ migrateUpToLatest(): Promise<void>;
110
+ migrateDown(): Promise<void>;
111
+ migrateDownToOldest(): Promise<void>;
112
+ status(): Promise<void>;
113
+ }
114
+ export { Mango, MangoType, MangoTable, MangoMigration, IMangoMigrationType };
@@ -1,135 +1,84 @@
1
- /*
2
- Requires sql for connection
3
- */
4
1
  import * as sql from "mysql";
5
2
  import chalk from "chalk";
6
- /**
7
- * MangoType - Schema builder for defining table column types
8
- * Provides chainable methods to build SQL column definitions
9
- *
10
- * @example
11
- * const type = new MangoType();
12
- * type.varchar(255).notNull().unique();
13
- */
14
3
  class MangoType {
15
4
  constructor() {
16
5
  this.query = "";
17
6
  }
18
- /** Define an INT column */
19
7
  int() {
20
8
  this.query += " INT ";
21
9
  return this;
22
10
  }
23
- /** Define a BIGINT column */
24
11
  bigInt() {
25
12
  this.query += " BIGINT ";
26
13
  return this;
27
14
  }
28
- /** Define a FLOAT column */
29
15
  float() {
30
16
  this.query += " FLOAT ";
31
17
  return this;
32
18
  }
33
- /**
34
- * Define a CHAR column with fixed length
35
- * @param length - The fixed character length
36
- */
37
19
  char(length) {
38
20
  this.query += ` CHAR(${length}) `;
39
21
  return this;
40
22
  }
41
- /** Define a TEXT column for large text data */
42
23
  text() {
43
24
  this.query += " TEXT ";
44
25
  return this;
45
26
  }
46
- /** Define a DATE column (YYYY-MM-DD) */
47
27
  date() {
48
28
  this.query += " DATE ";
49
29
  return this;
50
30
  }
51
- /** Define a DATETIME column (YYYY-MM-DD HH:MM:SS) */
52
31
  dateTime() {
53
32
  this.query += " DATETIME ";
54
33
  return this;
55
34
  }
56
- /** Define a TIMESTAMP column (auto-updated on changes) */
57
35
  timeStamp() {
58
36
  this.query += " TIMESTAMP ";
59
37
  return this;
60
38
  }
61
- /** Define a BOOLEAN column (stored as TINYINT(1)) */
62
39
  boolean() {
63
40
  this.query += " BOOLEAN ";
64
41
  return this;
65
42
  }
66
- /**
67
- * Define a TINYINT column
68
- * @param length - Display width (e.g., TINYINT(1))
69
- */
70
43
  tinyInt(length) {
71
44
  this.query += ` TINYINT(${length})`;
72
45
  return this;
73
46
  }
74
- /** Make column auto-incrementing (use with INT/BIGINT) */
75
47
  autoIncrement() {
76
48
  this.query += " AUTO_INCREMENT ";
77
49
  return this;
78
50
  }
79
- /** Mark column as primary key */
80
51
  primaryKey() {
81
52
  this.query += " PRIMARY KEY ";
82
53
  return this;
83
54
  }
84
- /**
85
- * Define a VARCHAR column with variable length
86
- * @param length - Maximum character length (e.g., 255)
87
- */
88
55
  varchar(length) {
89
56
  this.query += ` VARCHAR(${length}) `;
90
57
  return this;
91
58
  }
92
- /** Make column NOT NULL (required field) */
93
59
  notNull() {
94
60
  this.query += ` NOT NULL `;
95
61
  return this;
96
62
  }
97
- /** Add UNIQUE constraint (no duplicate values) */
98
63
  unique() {
99
64
  this.query += " UNIQUE ";
100
65
  return this;
101
66
  }
102
- /** Get the built SQL column definition */
103
67
  getQuery() {
104
68
  return this.query;
105
69
  }
106
70
  }
107
- /**
108
- * MangoQuery - Internal query executor
109
- * Handles SQL query execution and prepared statements
110
- * Automatically resets state after execution to prevent query contamination
111
- */
112
71
  class MangoQuery {
113
72
  constructor() {
114
73
  this.query = "";
115
- this.supplies = []; // Prepared statement parameters
74
+ this.supplies = [];
116
75
  }
117
- /**
118
- * Configure the database connection pool
119
- * @param db - MySQL connection pool instance
120
- */
121
76
  config(db) {
122
77
  this.db = db;
123
78
  }
124
- /**
125
- * Execute the built query with prepared statements
126
- * Automatically resets query and supplies after execution
127
- * @returns Promise resolving to query results
128
- */
129
79
  execute() {
130
80
  return new Promise((resolve, reject) => {
131
81
  this.db.query(this.query, this.supplies, (err, result) => {
132
- // Reset state BEFORE resolving to prevent contamination
133
82
  this.query = "";
134
83
  this.supplies = [];
135
84
  if (err)
@@ -139,13 +88,6 @@ class MangoQuery {
139
88
  });
140
89
  });
141
90
  }
142
- /**
143
- * Execute a custom SQL query with parameters
144
- * Use for complex queries not covered by the query builder
145
- * @param query - Raw SQL query string
146
- * @param supplies - Array of parameter values
147
- * @returns Promise resolving to query results
148
- */
149
91
  customQuery(query, supplies) {
150
92
  return new Promise((resolve, reject) => {
151
93
  this.db.query(query, supplies, (err, result) => {
@@ -157,53 +99,21 @@ class MangoQuery {
157
99
  });
158
100
  }
159
101
  }
160
- /**
161
- * MangoTable<T> - Main query builder class for table operations
162
- * Provides chainable methods for building SQL queries
163
- * Generic type T represents the shape of table rows
164
- *
165
- * @example
166
- * const users = new MangoTable(db, 'users', ['id', 'name', 'email']);
167
- * const result = await users.selectAll().where('id', '=', 1).execute();
168
- */
169
102
  class MangoTable {
170
- /**
171
- * Create a new table instance
172
- * @param db - MySQL connection pool
173
- * @param name - Table name (no spaces allowed)
174
- * @param fields - Array of column names in the table
175
- */
176
103
  constructor(db, name, fields = []) {
177
104
  this.query = new MangoQuery();
178
- // Validate that fields are provided
179
105
  if (fields.length == 0 || (fields.length == 1 && fields[0] === "")) {
180
106
  throw new Error("no fields provided for table " + name);
181
107
  }
182
108
  this.db = db;
183
- // Validate table name doesn't contain spaces
184
109
  if (Array.from(name.split(" ")).length > 1) {
185
110
  throw new Error("No spaces in table name allowed:");
186
111
  }
187
112
  this.tableName = name.toLowerCase();
188
- this.tableFields = [...fields]; // Clone to prevent external mutations
189
- // Initialize query executor
190
- // this.query = new MangoQuery();
113
+ this.tableFields = [...fields];
191
114
  this.query.config(db);
192
115
  }
193
- /**
194
- * Add new columns to an existing table
195
- * Updates internal field list for validation
196
- * @param fields - Object mapping column names to MangoType definitions
197
- * @returns this for method chaining
198
- *
199
- * @example
200
- * table.addColumns({
201
- * age: mango.types().int().notNull(),
202
- * status: mango.types().varchar(50)
203
- * }).execute();
204
- */
205
116
  addColumns(fields) {
206
- // Early return if no fields provided
207
117
  if (Object.entries(fields).length === 0)
208
118
  return this;
209
119
  this.query.query += "ALTER TABLE " + this.tableName + "\n";
@@ -211,7 +121,6 @@ class MangoTable {
211
121
  this.query.query += entries
212
122
  .map(([key, value]) => {
213
123
  let QUERY = " ADD COLUMN ";
214
- // Validate column name doesn't contain spaces
215
124
  if (Array.from(key.split(" ")).length > 1) {
216
125
  throw new Error("Field/Column name cannot have spaces: " +
217
126
  key +
@@ -224,28 +133,16 @@ class MangoTable {
224
133
  })
225
134
  .join(",\n");
226
135
  this.query.query += ";\n";
227
- // Update internal field list for future validations
228
136
  entries.forEach(([key]) => this.tableFields.push(key));
229
137
  return this;
230
138
  }
231
- /**
232
- * Remove columns from the table
233
- * Validates columns exist before removal
234
- * @param fields - Array of column names to remove
235
- * @returns this for method chaining
236
- *
237
- * @example
238
- * table.removeColumns(['old_field', 'deprecated_col']).execute();
239
- */
240
139
  removeColumns(fields) {
241
- // Early return if no fields provided
242
140
  if (fields.length === 0)
243
141
  return this;
244
142
  this.query.query += "ALTER TABLE " + this.tableName + "\n";
245
143
  this.query.query += fields
246
144
  .map((field) => {
247
145
  let QUERY = " DROP COLUMN ";
248
- // Validate field exists in table
249
146
  if (!this.tableFields.includes(field)) {
250
147
  throw new Error("field/column : " +
251
148
  field +
@@ -257,38 +154,18 @@ class MangoTable {
257
154
  })
258
155
  .join(",\n");
259
156
  this.query.query += ";\n";
260
- // Remove fields from internal tracking
261
157
  this.tableFields = this.tableFields.filter((value) => !fields.includes(value));
262
158
  return this;
263
159
  }
264
- /**
265
- * Select all columns from the table
266
- * @returns this for method chaining
267
- *
268
- * @example
269
- * await table.selectAll().where('active', '=', true).execute();
270
- */
271
160
  selectAll() {
272
161
  this.query.query = `SELECT * from ${this.tableName}`;
273
162
  return this;
274
163
  }
275
- /**
276
- * Select specific columns from the table
277
- * Validates all columns exist before building query
278
- * @param columns - Array of column names to select
279
- * @returns this for method chaining
280
- *
281
- * @example
282
- * await table.selectColumns(['id', 'name', 'email']).execute();
283
- */
284
164
  selectColumns(columns) {
285
- // Early return if no columns specified
286
165
  if (columns.length === 0)
287
166
  return this;
288
167
  this.query.query = `SELECT `;
289
- // Build column list with proper comma separation
290
168
  for (let i = 0; i < columns.length; i++) {
291
- // Validate each column exists in table
292
169
  if (!this.tableFields.includes(columns[i])) {
293
170
  throw new Error("Table field: " +
294
171
  columns[i] +
@@ -296,7 +173,6 @@ class MangoTable {
296
173
  this.tableName);
297
174
  }
298
175
  this.query.query += " " + columns[i];
299
- // Add comma between columns, but not after the last one
300
176
  if (i < columns.length - 1) {
301
177
  this.query.query += " , ";
302
178
  }
@@ -399,26 +275,10 @@ class MangoTable {
399
275
  this.query.query = " TRUNCATE TABLE " + this.tableName;
400
276
  return this;
401
277
  }
402
- /**
403
- * Add WHERE clause to filter query results
404
- * Use with comparison operators to filter rows
405
- * Supports falsy values (0, false, empty string)
406
- * @param field - Column name to filter on
407
- * @param operator - SQL comparison operator (=, !=, <, >, LIKE, etc.)
408
- * @param value - Value to compare against (any type)
409
- * @returns this for method chaining
410
- *
411
- * @example
412
- * table.selectAll().where('age', '>=', 18).execute();
413
- * table.selectAll().where('active', '=', false).execute(); // Works with false!
414
- * table.selectAll().where('count', '=', 0).execute(); // Works with 0!
415
- */
416
278
  where(field, operator, value) {
417
- // Validate field exists in table
418
279
  if (!this.tableFields.includes(field)) {
419
280
  throw new Error(`Field/Column: ${field} does not exist in table: ${this.tableName}`);
420
281
  }
421
- // Validate operator is allowed
422
282
  const validOperators = [
423
283
  "=",
424
284
  "!=",
@@ -437,25 +297,10 @@ class MangoTable {
437
297
  if (!validOperators.includes(operator.toUpperCase())) {
438
298
  throw new Error(`Invalid operator: ${operator}`);
439
299
  }
440
- // Build WHERE clause with placeholder
441
300
  this.query.query += ` WHERE ${field} ${operator} ? `;
442
301
  this.query.supplies.push(value);
443
302
  return this;
444
303
  }
445
- /**
446
- * Add AND condition to existing WHERE clause
447
- * Chain multiple conditions together
448
- * @param field - Column name
449
- * @param operator - SQL comparison operator
450
- * @param value - Value to compare (any type including 0, false)
451
- * @returns this for method chaining
452
- *
453
- * @example
454
- * table.selectAll()
455
- * .where('age', '>=', 18)
456
- * .and('active', '=', true)
457
- * .execute();
458
- */
459
304
  and(field, operator, value) {
460
305
  if (!this.tableFields.includes(field)) {
461
306
  throw new Error(`Field/Column: ${field} does not exist in table: ${this.tableName}`);
@@ -482,20 +327,6 @@ class MangoTable {
482
327
  this.query.supplies.push(value);
483
328
  return this;
484
329
  }
485
- /**
486
- * Add OR condition to existing WHERE clause
487
- * Combine alternative conditions
488
- * @param field - Column name
489
- * @param operator - SQL comparison operator
490
- * @param value - Value to compare (any type including 0, false)
491
- * @returns this for method chaining
492
- *
493
- * @example
494
- * table.selectAll()
495
- * .where('role', '=', 'admin')
496
- * .or('role', '=', 'moderator')
497
- * .execute();
498
- */
499
330
  or(field, operator, value) {
500
331
  if (!this.tableFields.includes(field)) {
501
332
  throw new Error(`Field/Column: ${field} does not exist in table: ${this.tableName}`);
@@ -584,26 +415,9 @@ class MangoTable {
584
415
  return this.query.customQuery(query, supplies);
585
416
  }
586
417
  }
587
- /**
588
- * Mango - Main ORM class for MySQL database operations
589
- * Manages connection pool and provides table instances
590
- * Auto-discovers existing tables on connection
591
- *
592
- * @example
593
- * const mango = new Mango();
594
- * await mango.connect({
595
- * host: 'localhost',
596
- * user: 'root',
597
- * password: 'pass',
598
- * database: 'mydb'
599
- * });
600
- *
601
- * const users = mango.selectTable('users');
602
- * const results = await users.selectAll().execute();
603
- */
604
418
  class Mango {
605
419
  constructor() {
606
- this.tables = []; // Cached table instances
420
+ this.tables = [];
607
421
  this.query = new MangoQuery();
608
422
  }
609
423
  async connect({ host, user, password, database, connectionLimit = 10, waitForConnection = true, queueLimit = 0, connectTimeout = 10000, charset = "utf8mb4", }) {
@@ -640,27 +454,9 @@ class Mango {
640
454
  });
641
455
  });
642
456
  }
643
- /**
644
- * Get a new MangoType instance for schema building
645
- * Use when creating or modifying table columns
646
- * @returns New MangoType instance for chaining
647
- *
648
- * @example
649
- * const idField = mango.types().int().autoIncrement().primaryKey();
650
- */
651
457
  types() {
652
458
  return new MangoType();
653
459
  }
654
- /**
655
- * Get a table instance by name
656
- * Returns strongly-typed table if generic provided
657
- * @param name - Name of the table
658
- * @returns MangoTable instance for building queries
659
- *
660
- * @example
661
- * interface User { id: number; name: string; email: string }
662
- * const users = mango.selectTable<User>('users');
663
- */
664
460
  selectTable(name) {
665
461
  for (const table of this.tables) {
666
462
  if (table.getName() == name.toLowerCase()) {
@@ -669,10 +465,6 @@ class Mango {
669
465
  }
670
466
  throw new Error("Table not found: " + name);
671
467
  }
672
- /**
673
- * Get all discovered table instances
674
- * @returns Array of all MangoTable instances
675
- */
676
468
  getTables() {
677
469
  return [...this.tables];
678
470
  }
@@ -691,14 +483,12 @@ class Mango {
691
483
  }
692
484
  });
693
485
  this.query.query += "\n)";
694
- // console.log(this.query.query);
695
486
  await this.query.execute();
696
487
  this.query.query = "";
697
488
  this.tables.push(table);
698
489
  return table;
699
490
  }
700
491
  async dropTable(name) {
701
- // Find and remove from tables array first
702
492
  for (let i = 0; i < this.tables.length; i++) {
703
493
  if (this.tables[i].getName() === name.toLowerCase()) {
704
494
  this.query.query = "DROP TABLE " + name.toLowerCase();
@@ -929,5 +719,4 @@ class MangoMigration {
929
719
  }
930
720
  }
931
721
  ;
932
- export { Mango, MangoType, MangoTable };
933
- export { MangoMigration };
722
+ export { Mango, MangoType, MangoTable, MangoMigration };
@@ -4,7 +4,7 @@ import path from "path";
4
4
  const generateMangoMigrationFile = (migrationFilename, outputDir = './migrations') => {
5
5
  const timestamp = Date.now();
6
6
  const filepath = path.join(outputDir, `${timestamp}_${migrationFilename}.ts`);
7
- const template = `import { IMangoMigrationType, Mango } from "../src/mango.js";
7
+ const template = `import { IMangoMigrationType, Mango } from "mango-orm;
8
8
 
9
9
  export const ${migrationFilename}: IMangoMigrationType = {
10
10
  name: "${migrationFilename}",
package/package.json CHANGED
@@ -1,21 +1,19 @@
1
1
  {
2
2
  "name": "mango-orm",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "type": "module",
5
5
  "description": "A lightweight, type-safe MySQL ORM for Node.js and TypeScript with database migrations",
6
- "main": "dist/src/mango.js",
7
- "types": "dist/src/mango.d.ts",
6
+ "main": "dist/mango.js",
7
+ "types": "dist/mango.d.ts",
8
+ "bin": {
9
+ "mango": "./dist/cli.js"
10
+ },
8
11
  "scripts": {
9
12
  "build": "tsc",
10
- "dev": "tsc --watch",
11
- "test": "tsc && node dist/test/test.js",
12
- "test:ops": "tsc && node dist/test/test-operations.js",
13
- "prepublishOnly": "pnpm build",
14
- "migration:generate": "tsc && node dist/src/cli.js generate",
15
- "migration:help": "tsc && node dist/src/cli.js help"
13
+ "prepublishOnly": "pnpm build"
16
14
  },
17
15
  "files": [
18
- "dist/src",
16
+ "dist",
19
17
  "README.md",
20
18
  "LICENSE"
21
19
  ],
@@ -1,302 +0,0 @@
1
- import * as sql from "mysql";
2
- /**
3
- * MangoType - Schema builder for defining table column types
4
- * Provides chainable methods to build SQL column definitions
5
- *
6
- * @example
7
- * const type = new MangoType();
8
- * type.varchar(255).notNull().unique();
9
- */
10
- declare class MangoType {
11
- private query;
12
- constructor();
13
- /** Define an INT column */
14
- int(): this;
15
- /** Define a BIGINT column */
16
- bigInt(): this;
17
- /** Define a FLOAT column */
18
- float(): this;
19
- /**
20
- * Define a CHAR column with fixed length
21
- * @param length - The fixed character length
22
- */
23
- char(length: number): this;
24
- /** Define a TEXT column for large text data */
25
- text(): this;
26
- /** Define a DATE column (YYYY-MM-DD) */
27
- date(): this;
28
- /** Define a DATETIME column (YYYY-MM-DD HH:MM:SS) */
29
- dateTime(): this;
30
- /** Define a TIMESTAMP column (auto-updated on changes) */
31
- timeStamp(): this;
32
- /** Define a BOOLEAN column (stored as TINYINT(1)) */
33
- boolean(): this;
34
- /**
35
- * Define a TINYINT column
36
- * @param length - Display width (e.g., TINYINT(1))
37
- */
38
- tinyInt(length: number): this;
39
- /** Make column auto-incrementing (use with INT/BIGINT) */
40
- autoIncrement(): this;
41
- /** Mark column as primary key */
42
- primaryKey(): this;
43
- /**
44
- * Define a VARCHAR column with variable length
45
- * @param length - Maximum character length (e.g., 255)
46
- */
47
- varchar(length: number): this;
48
- /** Make column NOT NULL (required field) */
49
- notNull(): this;
50
- /** Add UNIQUE constraint (no duplicate values) */
51
- unique(): this;
52
- /** Get the built SQL column definition */
53
- getQuery(): string;
54
- }
55
- /**
56
- * MangoQuery - Internal query executor
57
- * Handles SQL query execution and prepared statements
58
- * Automatically resets state after execution to prevent query contamination
59
- */
60
- declare class MangoQuery {
61
- private db;
62
- query: string;
63
- supplies: any;
64
- /**
65
- * Configure the database connection pool
66
- * @param db - MySQL connection pool instance
67
- */
68
- config(db: sql.Pool): void;
69
- /**
70
- * Execute the built query with prepared statements
71
- * Automatically resets query and supplies after execution
72
- * @returns Promise resolving to query results
73
- */
74
- execute<T>(): Promise<T>;
75
- /**
76
- * Execute a custom SQL query with parameters
77
- * Use for complex queries not covered by the query builder
78
- * @param query - Raw SQL query string
79
- * @param supplies - Array of parameter values
80
- * @returns Promise resolving to query results
81
- */
82
- customQuery<T>(query: string, supplies: any[]): Promise<T>;
83
- }
84
- /**
85
- * MangoTable<T> - Main query builder class for table operations
86
- * Provides chainable methods for building SQL queries
87
- * Generic type T represents the shape of table rows
88
- *
89
- * @example
90
- * const users = new MangoTable(db, 'users', ['id', 'name', 'email']);
91
- * const result = await users.selectAll().where('id', '=', 1).execute();
92
- */
93
- declare class MangoTable<T> {
94
- private db;
95
- private tableName;
96
- private tableFields;
97
- private query;
98
- /**
99
- * Create a new table instance
100
- * @param db - MySQL connection pool
101
- * @param name - Table name (no spaces allowed)
102
- * @param fields - Array of column names in the table
103
- */
104
- constructor(db: sql.Pool, name: string, fields?: string[]);
105
- /**
106
- * Add new columns to an existing table
107
- * Updates internal field list for validation
108
- * @param fields - Object mapping column names to MangoType definitions
109
- * @returns this for method chaining
110
- *
111
- * @example
112
- * table.addColumns({
113
- * age: mango.types().int().notNull(),
114
- * status: mango.types().varchar(50)
115
- * }).execute();
116
- */
117
- addColumns(fields: Record<string, MangoType>): this;
118
- /**
119
- * Remove columns from the table
120
- * Validates columns exist before removal
121
- * @param fields - Array of column names to remove
122
- * @returns this for method chaining
123
- *
124
- * @example
125
- * table.removeColumns(['old_field', 'deprecated_col']).execute();
126
- */
127
- removeColumns(fields: string[]): this;
128
- /**
129
- * Select all columns from the table
130
- * @returns this for method chaining
131
- *
132
- * @example
133
- * await table.selectAll().where('active', '=', true).execute();
134
- */
135
- selectAll(): this;
136
- /**
137
- * Select specific columns from the table
138
- * Validates all columns exist before building query
139
- * @param columns - Array of column names to select
140
- * @returns this for method chaining
141
- *
142
- * @example
143
- * await table.selectColumns(['id', 'name', 'email']).execute();
144
- */
145
- selectColumns(columns: string[]): this;
146
- selectDistinctColumns(columns: string[]): this;
147
- orderBy(columnName: string): this;
148
- sort(sort?: number): this;
149
- limit(length: number): this;
150
- offset(length: number): this;
151
- insertOne(data: Record<string, any>): this;
152
- insertMany(fields: string[], data?: any[][]): this;
153
- getFields(): string[];
154
- getName(): string;
155
- truncate(): this;
156
- /**
157
- * Add WHERE clause to filter query results
158
- * Use with comparison operators to filter rows
159
- * Supports falsy values (0, false, empty string)
160
- * @param field - Column name to filter on
161
- * @param operator - SQL comparison operator (=, !=, <, >, LIKE, etc.)
162
- * @param value - Value to compare against (any type)
163
- * @returns this for method chaining
164
- *
165
- * @example
166
- * table.selectAll().where('age', '>=', 18).execute();
167
- * table.selectAll().where('active', '=', false).execute(); // Works with false!
168
- * table.selectAll().where('count', '=', 0).execute(); // Works with 0!
169
- */
170
- where(field: string, operator: string, value: any): this;
171
- /**
172
- * Add AND condition to existing WHERE clause
173
- * Chain multiple conditions together
174
- * @param field - Column name
175
- * @param operator - SQL comparison operator
176
- * @param value - Value to compare (any type including 0, false)
177
- * @returns this for method chaining
178
- *
179
- * @example
180
- * table.selectAll()
181
- * .where('age', '>=', 18)
182
- * .and('active', '=', true)
183
- * .execute();
184
- */
185
- and(field: string, operator: string, value: any): this;
186
- /**
187
- * Add OR condition to existing WHERE clause
188
- * Combine alternative conditions
189
- * @param field - Column name
190
- * @param operator - SQL comparison operator
191
- * @param value - Value to compare (any type including 0, false)
192
- * @returns this for method chaining
193
- *
194
- * @example
195
- * table.selectAll()
196
- * .where('role', '=', 'admin')
197
- * .or('role', '=', 'moderator')
198
- * .execute();
199
- */
200
- or(field: string, operator: string, value: any): this;
201
- update(data: Record<string, any>): this;
202
- join(type: 'INNER' | 'LEFT' | 'RIGHT' | 'FULL', table: string, condition: {
203
- left: string;
204
- operator: string;
205
- right: string;
206
- }): this;
207
- delete(): this;
208
- whereIn(field: string, values: any[]): this;
209
- whereNotIn(field: string, values: any[]): this;
210
- getQuery(): MangoQuery;
211
- execute(): Promise<T[]>;
212
- customQuery<Type>(query: string, supplies: any[]): Promise<Type[]>;
213
- }
214
- /**
215
- * Mango - Main ORM class for MySQL database operations
216
- * Manages connection pool and provides table instances
217
- * Auto-discovers existing tables on connection
218
- *
219
- * @example
220
- * const mango = new Mango();
221
- * await mango.connect({
222
- * host: 'localhost',
223
- * user: 'root',
224
- * password: 'pass',
225
- * database: 'mydb'
226
- * });
227
- *
228
- * const users = mango.selectTable('users');
229
- * const results = await users.selectAll().execute();
230
- */
231
- declare class Mango {
232
- private db;
233
- private tables;
234
- private query;
235
- connect({ host, user, password, database, connectionLimit, waitForConnection, queueLimit, connectTimeout, charset, }: {
236
- host: any;
237
- user: any;
238
- password: any;
239
- database: any;
240
- connectionLimit?: number;
241
- waitForConnection?: boolean;
242
- queueLimit?: number;
243
- connectTimeout?: number;
244
- charset?: string;
245
- }): Promise<this>;
246
- disconnect(): Promise<void>;
247
- /**
248
- * Get a new MangoType instance for schema building
249
- * Use when creating or modifying table columns
250
- * @returns New MangoType instance for chaining
251
- *
252
- * @example
253
- * const idField = mango.types().int().autoIncrement().primaryKey();
254
- */
255
- types(): MangoType;
256
- /**
257
- * Get a table instance by name
258
- * Returns strongly-typed table if generic provided
259
- * @param name - Name of the table
260
- * @returns MangoTable instance for building queries
261
- *
262
- * @example
263
- * interface User { id: number; name: string; email: string }
264
- * const users = mango.selectTable<User>('users');
265
- */
266
- selectTable<T = any>(name: string): MangoTable<T>;
267
- /**
268
- * Get all discovered table instances
269
- * @returns Array of all MangoTable instances
270
- */
271
- getTables(): MangoTable<any>[];
272
- createTable<T>(name: string, fields: Record<string, MangoType>): Promise<MangoTable<T>>;
273
- dropTable(name: string): Promise<void>;
274
- haveTable(name: string): boolean;
275
- customQuery<Type>(query: string, supplies: any[]): Promise<Type>;
276
- }
277
- interface IMangoMigrationType {
278
- name: string;
279
- timestamp: number;
280
- up: (mango: Mango) => Promise<void>;
281
- down: (mango: Mango) => Promise<void>;
282
- }
283
- declare class MangoMigration {
284
- private mango;
285
- private mango_migration_table_name;
286
- private migrations;
287
- initialize(): Promise<void>;
288
- constructor(mango: Mango);
289
- addOneMigrationToDB(migration: IMangoMigrationType): Promise<void>;
290
- addManyMigrationToDB(migration: IMangoMigrationType[]): Promise<void>;
291
- deleteOneMigrationFromDB(migration: IMangoMigrationType): Promise<void>;
292
- deleteManyMigrationFromDB(migrations: IMangoMigrationType[]): Promise<void>;
293
- add(migration: IMangoMigrationType): MangoMigration;
294
- getExecutedMigrations(): Promise<string[]>;
295
- migrateUp(): Promise<void>;
296
- migrateUpToLatest(): Promise<void>;
297
- migrateDown(): Promise<void>;
298
- migrateDownToOldest(): Promise<void>;
299
- status(): Promise<void>;
300
- }
301
- export { Mango, MangoType, MangoTable };
302
- export { MangoMigration, IMangoMigrationType };
File without changes