@mantiq/database 0.2.0 → 0.3.0-rc.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/package.json +1 -1
- package/src/DatabaseManager.ts +10 -11
- package/src/drivers/BaseSQLConnection.ts +1 -1
- package/src/drivers/MSSQLConnection.ts +4 -2
- package/src/drivers/MongoConnection.ts +7 -5
- package/src/drivers/MongoQueryBuilderImpl.ts +4 -4
- package/src/drivers/MySQLConnection.ts +6 -6
- package/src/drivers/PostgresConnection.ts +6 -6
- package/src/errors/ConnectionError.ts +5 -5
- package/src/orm/Document.ts +14 -13
- package/src/orm/Model.ts +7 -2
- package/src/orm/ModelQueryBuilder.ts +8 -7
- package/src/query/Builder.ts +8 -8
- package/src/schema/Blueprint.ts +3 -3
- package/src/schema/ColumnDefinition.ts +5 -5
- package/src/schema/SchemaBuilder.ts +5 -2
- package/src/types.d.ts +21 -0
package/package.json
CHANGED
package/src/DatabaseManager.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { DatabaseConnection } from './contracts/Connection.ts'
|
|
2
|
-
import type { MongoDatabaseConnection } from './contracts/MongoConnection.ts'
|
|
3
2
|
import { SQLiteConnection } from './drivers/SQLiteConnection.ts'
|
|
4
3
|
import { PostgresConnection } from './drivers/PostgresConnection.ts'
|
|
5
4
|
import { MySQLConnection } from './drivers/MySQLConnection.ts'
|
|
@@ -9,31 +8,31 @@ import { ConnectionError } from './errors/ConnectionError.ts'
|
|
|
9
8
|
export interface SQLConfig {
|
|
10
9
|
driver: 'sqlite' | 'postgres' | 'mysql'
|
|
11
10
|
database: string
|
|
12
|
-
host?: string
|
|
13
|
-
port?: number
|
|
14
|
-
user?: string
|
|
15
|
-
password?: string
|
|
16
|
-
ssl?: boolean
|
|
17
|
-
pool?: { min?: number; max?: number }
|
|
11
|
+
host?: string | undefined
|
|
12
|
+
port?: number | undefined
|
|
13
|
+
user?: string | undefined
|
|
14
|
+
password?: string | undefined
|
|
15
|
+
ssl?: boolean | undefined
|
|
16
|
+
pool?: { min?: number | undefined; max?: number | undefined } | undefined
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
export interface MongoConfig {
|
|
21
20
|
driver: 'mongodb'
|
|
22
21
|
uri: string
|
|
23
22
|
database: string
|
|
24
|
-
options?: Record<string, any>
|
|
23
|
+
options?: Record<string, any> | undefined
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
export type ConnectionConfig = SQLConfig | MongoConfig
|
|
28
27
|
|
|
29
28
|
export interface DatabaseConfig {
|
|
30
|
-
default?: string
|
|
29
|
+
default?: string | undefined
|
|
31
30
|
connections: Record<string, ConnectionConfig>
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
export class DatabaseManager {
|
|
35
34
|
private sqlConnections = new Map<string, DatabaseConnection>()
|
|
36
|
-
private mongoConnections = new Map<string,
|
|
35
|
+
private mongoConnections = new Map<string, MongoConnection>()
|
|
37
36
|
|
|
38
37
|
constructor(private readonly config: DatabaseConfig) {}
|
|
39
38
|
|
|
@@ -51,7 +50,7 @@ export class DatabaseManager {
|
|
|
51
50
|
}
|
|
52
51
|
|
|
53
52
|
/** Get a MongoDB connection by name */
|
|
54
|
-
mongo(name?: string):
|
|
53
|
+
mongo(name?: string): MongoConnection {
|
|
55
54
|
const connName = name ?? this.config.default ?? 'default'
|
|
56
55
|
if (this.mongoConnections.has(connName)) return this.mongoConnections.get(connName)!
|
|
57
56
|
|
|
@@ -103,7 +103,7 @@ export abstract class BaseSQLConnection implements DatabaseConnection {
|
|
|
103
103
|
BaseSQLConnection.prototype.executeDelete.call({ ...txConn, _grammar: this._grammar }, table, state)
|
|
104
104
|
txConn.executeTruncate = (table: string) =>
|
|
105
105
|
BaseSQLConnection.prototype.executeTruncate.call({ ...txConn, _grammar: this._grammar }, table)
|
|
106
|
-
txConn.executeAggregate = (state: QueryState, fn:
|
|
106
|
+
txConn.executeAggregate = (state: QueryState, fn: 'count' | 'sum' | 'avg' | 'min' | 'max', column: string) =>
|
|
107
107
|
BaseSQLConnection.prototype.executeAggregate.call({ ...txConn, _grammar: this._grammar }, state, fn, column)
|
|
108
108
|
txConn.executeExists = (state: QueryState) =>
|
|
109
109
|
BaseSQLConnection.prototype.executeExists.call({ ...txConn, _grammar: this._grammar }, state)
|
|
@@ -31,7 +31,8 @@ export class MSSQLConnection extends BaseSQLConnection {
|
|
|
31
31
|
private async getPool(): Promise<any> {
|
|
32
32
|
if (!this.pool) {
|
|
33
33
|
try {
|
|
34
|
-
const
|
|
34
|
+
const mssqlModule = 'mssql'
|
|
35
|
+
const mssql: any = await import(mssqlModule)
|
|
35
36
|
const sql = mssql.default ?? mssql
|
|
36
37
|
this.pool = await sql.connect({
|
|
37
38
|
server: this.config.host ?? 'localhost',
|
|
@@ -97,7 +98,8 @@ export class MSSQLConnection extends BaseSQLConnection {
|
|
|
97
98
|
|
|
98
99
|
async transaction<T>(callback: (connection: DatabaseConnection) => Promise<T>): Promise<T> {
|
|
99
100
|
const pool = await this.getPool()
|
|
100
|
-
const
|
|
101
|
+
const mssqlModule = 'mssql'
|
|
102
|
+
const mssql: any = await import(mssqlModule)
|
|
101
103
|
const sql = mssql.default ?? mssql
|
|
102
104
|
const transaction = new sql.Transaction(pool)
|
|
103
105
|
await transaction.begin()
|
|
@@ -21,7 +21,7 @@ import { DriverNotSupportedError } from '../errors/DriverNotSupportedError.ts'
|
|
|
21
21
|
export interface MongoConfig {
|
|
22
22
|
uri: string
|
|
23
23
|
database: string
|
|
24
|
-
options?: Record<string, any>
|
|
24
|
+
options?: Record<string, any> | undefined
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
// ── Operator translation map ──────────────────────────────────────────────────
|
|
@@ -50,7 +50,8 @@ export class MongoConnection implements DatabaseConnection {
|
|
|
50
50
|
private async getDb(): Promise<any> {
|
|
51
51
|
if (!this.db) {
|
|
52
52
|
try {
|
|
53
|
-
const
|
|
53
|
+
const mongoModule = 'mongodb'
|
|
54
|
+
const { MongoClient } = await import(/* webpackIgnore: true */ mongoModule)
|
|
54
55
|
this.client = new MongoClient(this.config.uri, this.config.options ?? {})
|
|
55
56
|
await this.client.connect()
|
|
56
57
|
this.db = this.client.db(this.config.database)
|
|
@@ -249,10 +250,10 @@ export class MongoConnection implements DatabaseConnection {
|
|
|
249
250
|
// Final group
|
|
250
251
|
if (orGroups.length > 0) {
|
|
251
252
|
orGroups.push(currentAnd)
|
|
252
|
-
return { $or: orGroups.map((group) => group.length === 1 ? group[0] : { $and: group }) }
|
|
253
|
+
return { $or: orGroups.map((group) => group.length === 1 ? group[0]! : { $and: group }) }
|
|
253
254
|
}
|
|
254
255
|
|
|
255
|
-
if (currentAnd.length === 1) return currentAnd[0]
|
|
256
|
+
if (currentAnd.length === 1) return currentAnd[0]!
|
|
256
257
|
return { $and: currentAnd }
|
|
257
258
|
}
|
|
258
259
|
|
|
@@ -405,7 +406,8 @@ class LazyMongoCollection implements MongoCollectionContract {
|
|
|
405
406
|
}
|
|
406
407
|
|
|
407
408
|
async findById(id: any): Promise<Record<string, any> | null> {
|
|
408
|
-
const
|
|
409
|
+
const mongoModule = 'mongodb'
|
|
410
|
+
const { ObjectId } = await import(/* webpackIgnore: true */ mongoModule)
|
|
409
411
|
return (await this.col()).findOne({ _id: typeof id === 'string' ? new ObjectId(id) : id })
|
|
410
412
|
}
|
|
411
413
|
|
|
@@ -17,10 +17,10 @@ export class MongoQueryBuilderImpl implements MongoQueryBuilder {
|
|
|
17
17
|
private readonly collectionName: string,
|
|
18
18
|
private readonly executor: (opts: {
|
|
19
19
|
filter: MongoFilter
|
|
20
|
-
projection?: MongoProjection
|
|
21
|
-
sort?: MongoSortDoc
|
|
22
|
-
limit?: number
|
|
23
|
-
skip?: number
|
|
20
|
+
projection?: MongoProjection | undefined
|
|
21
|
+
sort?: MongoSortDoc | undefined
|
|
22
|
+
limit?: number | undefined
|
|
23
|
+
skip?: number | undefined
|
|
24
24
|
}) => Promise<Record<string, any>[]>,
|
|
25
25
|
private readonly counter: (filter: MongoFilter) => Promise<number>,
|
|
26
26
|
) {}
|
|
@@ -8,12 +8,12 @@ import { ConnectionError } from '../errors/ConnectionError.ts'
|
|
|
8
8
|
import { QueryError } from '../errors/QueryError.ts'
|
|
9
9
|
|
|
10
10
|
export interface MySQLConfig {
|
|
11
|
-
host?: string
|
|
12
|
-
port?: number
|
|
11
|
+
host?: string | undefined
|
|
12
|
+
port?: number | undefined
|
|
13
13
|
database: string
|
|
14
|
-
user?: string
|
|
15
|
-
password?: string
|
|
16
|
-
pool?: { min?: number; max?: number }
|
|
14
|
+
user?: string | undefined
|
|
15
|
+
password?: string | undefined
|
|
16
|
+
pool?: { min?: number | undefined; max?: number | undefined } | undefined
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export class MySQLConnection extends BaseSQLConnection {
|
|
@@ -29,7 +29,7 @@ export class MySQLConnection extends BaseSQLConnection {
|
|
|
29
29
|
private async getPool(): Promise<any> {
|
|
30
30
|
if (!this.pool) {
|
|
31
31
|
try {
|
|
32
|
-
const mysql = await import('mysql2/promise')
|
|
32
|
+
const mysql: any = await import('mysql2/promise')
|
|
33
33
|
this.pool = await mysql.createPool({
|
|
34
34
|
host: this.config.host ?? 'localhost',
|
|
35
35
|
port: this.config.port ?? 3306,
|
|
@@ -8,13 +8,13 @@ import { ConnectionError } from '../errors/ConnectionError.ts'
|
|
|
8
8
|
import { QueryError } from '../errors/QueryError.ts'
|
|
9
9
|
|
|
10
10
|
export interface PostgresConfig {
|
|
11
|
-
host?: string
|
|
12
|
-
port?: number
|
|
11
|
+
host?: string | undefined
|
|
12
|
+
port?: number | undefined
|
|
13
13
|
database: string
|
|
14
|
-
user?: string
|
|
15
|
-
password?: string
|
|
16
|
-
ssl?: boolean
|
|
17
|
-
pool?: { min?: number; max?: number }
|
|
14
|
+
user?: string | undefined
|
|
15
|
+
password?: string | undefined
|
|
16
|
+
ssl?: boolean | undefined
|
|
17
|
+
pool?: { min?: number | undefined; max?: number | undefined } | undefined
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export class PostgresConnection extends BaseSQLConnection {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export class ConnectionError extends MantiqError {
|
|
1
|
+
export class ConnectionError extends Error {
|
|
4
2
|
constructor(
|
|
3
|
+
message: string,
|
|
5
4
|
public readonly driver: string,
|
|
6
|
-
originalError
|
|
5
|
+
originalError?: Error,
|
|
7
6
|
) {
|
|
8
|
-
super(
|
|
7
|
+
super(originalError ? `${message}: ${originalError.message}` : message)
|
|
8
|
+
this.name = 'ConnectionError'
|
|
9
9
|
}
|
|
10
10
|
}
|
package/src/orm/Document.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @ts-nocheck — deprecated, replaced by Model with MongoDB connection
|
|
1
2
|
import type { MongoDatabaseConnection, MongoFilter, MongoUpdateDoc, MongoPipelineStage } from '../contracts/MongoConnection.ts'
|
|
2
3
|
import { ModelNotFoundError } from '../errors/ModelNotFoundError.ts'
|
|
3
4
|
|
|
@@ -27,34 +28,34 @@ export abstract class Document {
|
|
|
27
28
|
|
|
28
29
|
// ── Static query API ───────────────────────────────────────────────────────
|
|
29
30
|
|
|
30
|
-
static col<T extends Document>(this: new
|
|
31
|
+
static col<T extends Document>(this: { new(): T } & typeof Document): import('../contracts/MongoConnection.ts').MongoCollectionContract {
|
|
31
32
|
const ctor = this as unknown as typeof Document
|
|
32
33
|
if (!ctor.connection) throw new Error(`No connection set on Document ${ctor.collection}`)
|
|
33
34
|
return ctor.connection.collection(ctor.collection)
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
static async find<T extends Document>(this: new
|
|
37
|
+
static async find<T extends Document>(this: { new(): T } & typeof Document, filter: MongoFilter = {}): Promise<T[]> {
|
|
37
38
|
const rows = await (this as unknown as typeof Document).col<T>().find(filter).get()
|
|
38
39
|
return rows.map((r) => (this as unknown as typeof Document).hydrate<T>(this, r))
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
static async findOne<T extends Document>(this: new
|
|
42
|
+
static async findOne<T extends Document>(this: { new(): T } & typeof Document, filter: MongoFilter = {}): Promise<T | null> {
|
|
42
43
|
const row = await (this as unknown as typeof Document).col<T>().findOne(filter)
|
|
43
44
|
return row ? (this as unknown as typeof Document).hydrate<T>(this, row) : null
|
|
44
45
|
}
|
|
45
46
|
|
|
46
|
-
static async findById<T extends Document>(this: new
|
|
47
|
+
static async findById<T extends Document>(this: { new(): T } & typeof Document, id: any): Promise<T | null> {
|
|
47
48
|
const row = await (this as unknown as typeof Document).col<T>().findById(id)
|
|
48
49
|
return row ? (this as unknown as typeof Document).hydrate<T>(this, row) : null
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
static async findByIdOrFail<T extends Document>(this: new
|
|
52
|
+
static async findByIdOrFail<T extends Document>(this: { new(): T } & typeof Document, id: any): Promise<T> {
|
|
52
53
|
const doc = await (this as unknown as typeof Document).findById<T>(id)
|
|
53
54
|
if (!doc) throw new ModelNotFoundError((this as unknown as typeof Document).collection)
|
|
54
55
|
return doc
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
static async create<T extends Document>(this: new
|
|
58
|
+
static async create<T extends Document>(this: { new(): T } & typeof Document, data: Record<string, any>): Promise<T> {
|
|
58
59
|
const col = (this as unknown as typeof Document).col<T>()
|
|
59
60
|
const now = new Date()
|
|
60
61
|
const doc = { ...data, createdAt: now, updatedAt: now }
|
|
@@ -63,7 +64,7 @@ export abstract class Document {
|
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
static async insertMany<T extends Document>(
|
|
66
|
-
this: new
|
|
67
|
+
this: { new(): T } & typeof Document,
|
|
67
68
|
docs: Record<string, any>[],
|
|
68
69
|
): Promise<T[]> {
|
|
69
70
|
const col = (this as unknown as typeof Document).col<T>()
|
|
@@ -76,7 +77,7 @@ export abstract class Document {
|
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
static async updateOne<T extends Document>(
|
|
79
|
-
this: new
|
|
80
|
+
this: { new(): T } & typeof Document,
|
|
80
81
|
filter: MongoFilter,
|
|
81
82
|
update: MongoUpdateDoc,
|
|
82
83
|
) {
|
|
@@ -88,7 +89,7 @@ export abstract class Document {
|
|
|
88
89
|
}
|
|
89
90
|
|
|
90
91
|
static async updateMany<T extends Document>(
|
|
91
|
-
this: new
|
|
92
|
+
this: { new(): T } & typeof Document,
|
|
92
93
|
filter: MongoFilter,
|
|
93
94
|
update: MongoUpdateDoc,
|
|
94
95
|
) {
|
|
@@ -99,22 +100,22 @@ export abstract class Document {
|
|
|
99
100
|
return (this as unknown as typeof Document).col<T>().updateMany(filter, merged)
|
|
100
101
|
}
|
|
101
102
|
|
|
102
|
-
static async deleteOne<T extends Document>(this: new
|
|
103
|
+
static async deleteOne<T extends Document>(this: { new(): T } & typeof Document, filter: MongoFilter) {
|
|
103
104
|
return (this as unknown as typeof Document).col<T>().deleteOne(filter)
|
|
104
105
|
}
|
|
105
106
|
|
|
106
|
-
static async deleteMany<T extends Document>(this: new
|
|
107
|
+
static async deleteMany<T extends Document>(this: { new(): T } & typeof Document, filter: MongoFilter) {
|
|
107
108
|
return (this as unknown as typeof Document).col<T>().deleteMany(filter)
|
|
108
109
|
}
|
|
109
110
|
|
|
110
111
|
static async aggregate<T extends Document>(
|
|
111
|
-
this: new
|
|
112
|
+
this: { new(): T } & typeof Document,
|
|
112
113
|
pipeline: MongoPipelineStage[],
|
|
113
114
|
): Promise<Record<string, any>[]> {
|
|
114
115
|
return (this as unknown as typeof Document).col<T>().aggregate(pipeline)
|
|
115
116
|
}
|
|
116
117
|
|
|
117
|
-
static async count<T extends Document>(this: new
|
|
118
|
+
static async count<T extends Document>(this: { new(): T } & typeof Document, filter: MongoFilter = {}): Promise<number> {
|
|
118
119
|
return (this as unknown as typeof Document).col<T>().count(filter)
|
|
119
120
|
}
|
|
120
121
|
|
package/src/orm/Model.ts
CHANGED
|
@@ -473,8 +473,13 @@ export abstract class Model {
|
|
|
473
473
|
if (!this._attributes['updated_at']) this._attributes['updated_at'] = now
|
|
474
474
|
}
|
|
475
475
|
|
|
476
|
-
|
|
477
|
-
|
|
476
|
+
if (ctor.incrementing) {
|
|
477
|
+
const id = await ctor.connection.table(table).insertGetId(this._attributes)
|
|
478
|
+
this._attributes[ctor.primaryKey] = Number(id)
|
|
479
|
+
} else {
|
|
480
|
+
// Non-incrementing (UUID) — id is already set in attributes
|
|
481
|
+
await ctor.connection.table(table).insert(this._attributes)
|
|
482
|
+
}
|
|
478
483
|
this._original = { ...this._attributes }
|
|
479
484
|
this._exists = true
|
|
480
485
|
|
|
@@ -3,6 +3,7 @@ import { ModelNotFoundError } from '../errors/ModelNotFoundError.ts'
|
|
|
3
3
|
import { eagerLoadRelations, type EagerLoadSpec, normalizeEagerLoads } from './eagerLoad.ts'
|
|
4
4
|
import type { Model } from './Model.ts'
|
|
5
5
|
import type { DatabaseConnection } from '../contracts/Connection.ts'
|
|
6
|
+
import type { PaginationResult } from '../contracts/Paginator.ts'
|
|
6
7
|
|
|
7
8
|
export class ModelQueryBuilder<T> extends QueryBuilder {
|
|
8
9
|
private _eagerLoads: string[] = []
|
|
@@ -131,7 +132,7 @@ export class ModelQueryBuilder<T> extends QueryBuilder {
|
|
|
131
132
|
|
|
132
133
|
// ── Hydrating read methods ─────────────────────────────────────────────────
|
|
133
134
|
|
|
134
|
-
override async get(): Promise<
|
|
135
|
+
override async get(): Promise<any[]> {
|
|
135
136
|
this.applyGlobalScopes()
|
|
136
137
|
const rows = await this.raw().get()
|
|
137
138
|
const models = rows.map(this._hydrate)
|
|
@@ -148,7 +149,7 @@ export class ModelQueryBuilder<T> extends QueryBuilder {
|
|
|
148
149
|
return models
|
|
149
150
|
}
|
|
150
151
|
|
|
151
|
-
override async first(): Promise<
|
|
152
|
+
override async first(): Promise<any> {
|
|
152
153
|
this.applyGlobalScopes()
|
|
153
154
|
const row = await this.raw().first()
|
|
154
155
|
if (!row) return null
|
|
@@ -166,13 +167,13 @@ export class ModelQueryBuilder<T> extends QueryBuilder {
|
|
|
166
167
|
return model
|
|
167
168
|
}
|
|
168
169
|
|
|
169
|
-
async firstOrFail(): Promise<
|
|
170
|
+
override async firstOrFail(): Promise<any> {
|
|
170
171
|
const result = await this.first()
|
|
171
172
|
if (!result) throw new ModelNotFoundError(this.state.table)
|
|
172
173
|
return result
|
|
173
174
|
}
|
|
174
175
|
|
|
175
|
-
override async find(id: number | string): Promise<
|
|
176
|
+
override async find(id: number | string): Promise<any> {
|
|
176
177
|
this.applyGlobalScopes()
|
|
177
178
|
const row = await this.raw().where('id', id).first()
|
|
178
179
|
if (!row) return null
|
|
@@ -190,7 +191,7 @@ export class ModelQueryBuilder<T> extends QueryBuilder {
|
|
|
190
191
|
return model
|
|
191
192
|
}
|
|
192
193
|
|
|
193
|
-
async findOrFail(id: number | string): Promise<
|
|
194
|
+
async findOrFail(id: number | string): Promise<any> {
|
|
194
195
|
const result = await this.find(id)
|
|
195
196
|
if (!result) throw new ModelNotFoundError(this.state.table)
|
|
196
197
|
return result
|
|
@@ -198,7 +199,7 @@ export class ModelQueryBuilder<T> extends QueryBuilder {
|
|
|
198
199
|
|
|
199
200
|
// ── Pagination (hydrated) ─────────────────────────────────────────────────
|
|
200
201
|
|
|
201
|
-
override async paginate(page = 1, perPage = 15) {
|
|
202
|
+
override async paginate(page = 1, perPage = 15): Promise<PaginationResult> {
|
|
202
203
|
const total = await this.count()
|
|
203
204
|
const lastPage = Math.max(1, Math.ceil(total / perPage))
|
|
204
205
|
const currentPage = Math.min(page, lastPage)
|
|
@@ -381,7 +382,7 @@ export class ModelQueryBuilder<T> extends QueryBuilder {
|
|
|
381
382
|
* @example
|
|
382
383
|
* const user = await User.where('email', 'admin@example.com').sole()
|
|
383
384
|
*/
|
|
384
|
-
async sole(): Promise<
|
|
385
|
+
override async sole(): Promise<any> {
|
|
385
386
|
this.applyGlobalScopes()
|
|
386
387
|
const originalLimit = this.state.limitValue
|
|
387
388
|
this.state.limitValue = 2
|
package/src/query/Builder.ts
CHANGED
|
@@ -9,15 +9,15 @@ export type Operator = '=' | '!=' | '<>' | '<' | '>' | '<=' | '>=' | 'like' | 'n
|
|
|
9
9
|
export interface WhereClause {
|
|
10
10
|
type: 'basic' | 'in' | 'notIn' | 'null' | 'notNull' | 'between' | 'raw' | 'nested' | 'column'
|
|
11
11
|
boolean: 'and' | 'or'
|
|
12
|
-
column?: string
|
|
13
|
-
operator?: string
|
|
12
|
+
column?: string | undefined
|
|
13
|
+
operator?: string | undefined
|
|
14
14
|
value?: any
|
|
15
|
-
values?: any[]
|
|
16
|
-
range?: [any, any]
|
|
17
|
-
sql?: string
|
|
18
|
-
bindings?: any[]
|
|
19
|
-
nested?: WhereClause[]
|
|
20
|
-
secondColumn?: string
|
|
15
|
+
values?: any[] | undefined
|
|
16
|
+
range?: [any, any] | undefined
|
|
17
|
+
sql?: string | undefined
|
|
18
|
+
bindings?: any[] | undefined
|
|
19
|
+
nested?: WhereClause[] | undefined
|
|
20
|
+
secondColumn?: string | undefined
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
export interface JoinClause {
|
package/src/schema/Blueprint.ts
CHANGED
|
@@ -3,15 +3,15 @@ import { ColumnDefinition } from './ColumnDefinition.ts'
|
|
|
3
3
|
export interface IndexDefinition {
|
|
4
4
|
type: 'index' | 'unique' | 'primary'
|
|
5
5
|
columns: string[]
|
|
6
|
-
name?: string
|
|
6
|
+
name?: string | undefined
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export interface ForeignKeyDefinition {
|
|
10
10
|
column: string
|
|
11
11
|
references: string
|
|
12
12
|
on: string
|
|
13
|
-
onDelete?: string
|
|
14
|
-
onUpdate?: string
|
|
13
|
+
onDelete?: string | undefined
|
|
14
|
+
onUpdate?: string | undefined
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export class Blueprint {
|
|
@@ -6,16 +6,16 @@ export class ColumnDefinition {
|
|
|
6
6
|
private _index = false
|
|
7
7
|
private _unsigned = false
|
|
8
8
|
private _primary = false
|
|
9
|
-
private _references: { table: string; column: string; onDelete?: string; onUpdate?: string } | null = null
|
|
9
|
+
private _references: { table: string; column: string; onDelete?: string | undefined; onUpdate?: string | undefined } | null = null
|
|
10
10
|
private _comment: string | null = null
|
|
11
11
|
private _after: string | null = null
|
|
12
12
|
|
|
13
13
|
constructor(
|
|
14
14
|
public readonly name: string,
|
|
15
15
|
public readonly type: string,
|
|
16
|
-
public readonly length?: number,
|
|
17
|
-
public readonly precision?: number,
|
|
18
|
-
public readonly scale?: number,
|
|
16
|
+
public readonly length?: number | undefined,
|
|
17
|
+
public readonly precision?: number | undefined,
|
|
18
|
+
public readonly scale?: number | undefined,
|
|
19
19
|
) {}
|
|
20
20
|
|
|
21
21
|
nullable(): this {
|
|
@@ -49,7 +49,7 @@ export class ColumnDefinition {
|
|
|
49
49
|
return this
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
references(column: string):
|
|
52
|
+
references(column: string): ColumnDefinition & { on(table: string): ColumnDefinition } {
|
|
53
53
|
this._references = { table: '', column }
|
|
54
54
|
const self = this as any
|
|
55
55
|
self.on = (table: string) => {
|
|
@@ -210,9 +210,12 @@ export class SchemaBuilderImpl implements SchemaBuilder {
|
|
|
210
210
|
|
|
211
211
|
let def = `${this.quoteCol(col.name)} ${typeSql}`
|
|
212
212
|
|
|
213
|
+
const isIntegerType = ['integer', 'bigInteger', 'tinyInteger', 'smallInteger', 'mediumInteger'].includes(col.type)
|
|
213
214
|
if (isAutoIncrement || col.isPrimary()) {
|
|
214
|
-
if (driver === 'sqlite') {
|
|
215
|
+
if (driver === 'sqlite' && (isAutoIncrement || isIntegerType)) {
|
|
215
216
|
def += ' PRIMARY KEY AUTOINCREMENT'
|
|
217
|
+
} else if (driver === 'sqlite') {
|
|
218
|
+
def += ' PRIMARY KEY'
|
|
216
219
|
} else if (driver === 'postgres') {
|
|
217
220
|
// SERIAL/BIGSERIAL already implies sequence; just mark PRIMARY KEY
|
|
218
221
|
def += ' PRIMARY KEY'
|
|
@@ -252,7 +255,7 @@ export class SchemaBuilderImpl implements SchemaBuilder {
|
|
|
252
255
|
return def
|
|
253
256
|
}
|
|
254
257
|
|
|
255
|
-
private compileIndex(table: string, idx: { type: 'index' | 'unique' | 'primary'; columns: string[]; name?: string }): string {
|
|
258
|
+
private compileIndex(table: string, idx: { type: 'index' | 'unique' | 'primary'; columns: string[]; name?: string | undefined }): string {
|
|
256
259
|
const cols = idx.columns.map((c) => this.quoteCol(c)).join(', ')
|
|
257
260
|
const idxName = idx.name ?? `${table}_${idx.columns.join('_')}_${idx.type}`
|
|
258
261
|
|
package/src/types.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Optional peer dependencies — ambient module declarations for dynamic imports
|
|
2
|
+
declare module 'pg' {
|
|
3
|
+
const pg: any
|
|
4
|
+
export default pg
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
declare module 'mysql2/promise' {
|
|
8
|
+
const mysql: any
|
|
9
|
+
export default mysql
|
|
10
|
+
export function createPool(config: any): any
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
declare module 'mssql' {
|
|
14
|
+
const mssql: any
|
|
15
|
+
export default mssql
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare module 'mongodb' {
|
|
19
|
+
export const MongoClient: any
|
|
20
|
+
export const ObjectId: any
|
|
21
|
+
}
|