@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mantiq/database",
3
- "version": "0.2.0",
3
+ "version": "0.3.0-rc.1",
4
4
  "description": "Query builder, ORM, migrations, seeders, factories — with SQLite, Postgres, MySQL and MongoDB support",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -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, MongoDatabaseConnection>()
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): MongoDatabaseConnection {
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: string, column: string) =>
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 mssql = await import('mssql')
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 mssql = await import('mssql')
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 { MongoClient } = await import('mongodb')
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 { ObjectId } = await import('mongodb')
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
- import { MantiqError } from '@mantiq/core'
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: Error,
5
+ originalError?: Error,
7
6
  ) {
8
- super(`Failed to connect to ${driver} database: ${originalError.message}`)
7
+ super(originalError ? `${message}: ${originalError.message}` : message)
8
+ this.name = 'ConnectionError'
9
9
  }
10
10
  }
@@ -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 () => T): import('../contracts/MongoConnection.ts').MongoCollectionContract {
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 () => T, filter: MongoFilter = {}): Promise<T[]> {
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 () => T, filter: MongoFilter = {}): Promise<T | null> {
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 () => T, id: any): Promise<T | null> {
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 () => T, id: any): Promise<T> {
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 () => T, data: Record<string, any>): Promise<T> {
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 () => T,
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 () => T,
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 () => T,
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 () => T, filter: MongoFilter) {
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 () => T, filter: MongoFilter) {
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 () => T,
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 () => T, filter: MongoFilter = {}): Promise<number> {
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
- const id = await ctor.connection.table(table).insertGetId(this._attributes)
477
- this._attributes[ctor.primaryKey] = ctor.incrementing ? Number(id) : id
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<T[]> {
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<T | null> {
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<T> {
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<T | null> {
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<T> {
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<T> {
385
+ override async sole(): Promise<any> {
385
386
  this.applyGlobalScopes()
386
387
  const originalLimit = this.state.limitValue
387
388
  this.state.limitValue = 2
@@ -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 {
@@ -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): this & { on(table: string): this } {
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
+ }