workers-qb 1.6.6 → 1.7.0

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/dist/index.d.mts CHANGED
@@ -178,6 +178,10 @@ type AsyncType<T> = Promise<T>;
178
178
  type SyncType<T> = T;
179
179
  type MaybeAsync<IsAsync extends boolean, T> = IsAsync extends true ? AsyncType<T> : SyncType<T>;
180
180
 
181
+ declare function defaultLogger(query: RawQuery, meta: QueryLoggerMeta): any;
182
+ declare function asyncLoggerWrapper<Async extends boolean = true>(query: Query<any, Async> | Query<any, Async>[], loggerFunction: CallableFunction | undefined, innerFunction: () => any): Promise<any>;
183
+ declare function syncLoggerWrapper<Async extends boolean = false>(query: Query<any, Async> | Query<any, Async>[], loggerFunction: CallableFunction | undefined, innerFunction: () => any): any;
184
+
181
185
  declare class SelectBuilder<GenericResultWrapper, GenericResult = DefaultReturnObject, IsAsync extends boolean = true> {
182
186
  _debugger: boolean;
183
187
  _options: Partial<SelectAll>;
@@ -203,10 +207,6 @@ declare class SelectBuilder<GenericResultWrapper, GenericResult = DefaultReturnO
203
207
  count(): MaybeAsync<IsAsync, CountResult<GenericResultWrapper>>;
204
208
  }
205
209
 
206
- declare function defaultLogger(query: RawQuery, meta: QueryLoggerMeta): any;
207
- declare function asyncLoggerWrapper<Async extends boolean = true>(query: Query<any, Async> | Query<any, Async>[], loggerFunction: CallableFunction | undefined, innerFunction: () => any): Promise<any>;
208
- declare function syncLoggerWrapper<Async extends boolean = false>(query: Query<any, Async> | Query<any, Async>[], loggerFunction: CallableFunction | undefined, innerFunction: () => any): any;
209
-
210
210
  declare class QueryBuilder<GenericResultWrapper, IsAsync extends boolean = true> {
211
211
  protected options: QueryBuilderOptions<IsAsync>;
212
212
  loggerWrapper: typeof asyncLoggerWrapper;
@@ -253,16 +253,53 @@ declare class QueryBuilder<GenericResultWrapper, IsAsync extends boolean = true>
253
253
  protected _returning(value?: string | Array<string>): string;
254
254
  }
255
255
 
256
+ type MigrationEntry = {
257
+ id: number;
258
+ name: string;
259
+ applied_at: Date;
260
+ };
261
+ type Migration = {
262
+ name: string;
263
+ sql: string;
264
+ };
265
+ type MigrationOptions = {
266
+ migrations: Array<Migration>;
267
+ tableName?: string;
268
+ };
269
+ declare class syncMigrationsBuilder<GenericResultWrapper> {
270
+ _builder: QueryBuilder<GenericResultWrapper, false>;
271
+ _migrations: Array<Migration>;
272
+ _tableName: string;
273
+ constructor(options: MigrationOptions, builder: QueryBuilder<GenericResultWrapper, false>);
274
+ initialize(): void;
275
+ getApplied(): Array<MigrationEntry>;
276
+ getUnapplied(): Array<Migration>;
277
+ apply(): Array<Migration>;
278
+ }
279
+ declare class asyncMigrationsBuilder<GenericResultWrapper> {
280
+ _builder: QueryBuilder<GenericResultWrapper, true>;
281
+ _migrations: Array<Migration>;
282
+ _tableName: string;
283
+ constructor(options: MigrationOptions, builder: QueryBuilder<GenericResultWrapper, true>);
284
+ initialize(): Promise<void>;
285
+ getApplied(): Promise<Array<MigrationEntry>>;
286
+ getUnapplied(): Promise<Array<Migration>>;
287
+ apply(): Promise<Array<Migration>>;
288
+ }
289
+
256
290
  declare class D1QB extends QueryBuilder<D1Result> {
257
291
  db: any;
258
292
  constructor(db: any, options?: QueryBuilderOptions);
293
+ migrations(options: MigrationOptions): asyncMigrationsBuilder<D1Result>;
259
294
  execute(query: Query): Promise<any>;
260
295
  batchExecute(queryArray: Query[]): Promise<any>;
261
296
  }
262
297
 
263
298
  declare class PGQB extends QueryBuilder<PGResult> {
264
299
  db: any;
300
+ _migrationsBuilder: typeof asyncMigrationsBuilder;
265
301
  constructor(db: any, options?: QueryBuilderOptions);
302
+ migrations(options: MigrationOptions): asyncMigrationsBuilder<PGResult>;
266
303
  connect(): Promise<void>;
267
304
  close(): Promise<void>;
268
305
  execute(query: Query): Promise<any>;
@@ -272,7 +309,8 @@ declare class DOQB extends QueryBuilder<{}, false> {
272
309
  db: any;
273
310
  loggerWrapper: typeof syncLoggerWrapper;
274
311
  constructor(db: any, options?: QueryBuilderOptions<false>);
312
+ migrations(options: MigrationOptions): syncMigrationsBuilder<{}>;
275
313
  execute(query: Query<any, false>): any;
276
314
  }
277
315
 
278
- export { type ArrayResult, type AsyncType, ConflictTypes, type ConflictUpsert, type CountResult, type D1Meta, D1QB, type D1Result, DOQB, type DefaultObject, type DefaultReturnObject, type Delete, type DeleteReturning, type DeleteWithoutReturning, FetchTypes, type Insert, type InsertMultiple, type InsertOne, type InsertWithoutReturning, type Join, JoinTypes, type MaybeAsync, type OneResult, OrderTypes, PGQB, type PGResult, type Primitive, Query, QueryBuilder, type QueryBuilderOptions, type QueryLoggerMeta, QueryWithExtra, Raw, type RawQuery, type RawQueryFetchAll, type RawQueryFetchOne, type RawQueryWithoutFetching, type SelectAll, type SelectOne, type SyncType, type Update, type UpdateReturning, type UpdateWithoutReturning, type Where, asyncLoggerWrapper, defaultLogger, syncLoggerWrapper, type test, trimQuery };
316
+ export { type ArrayResult, type AsyncType, ConflictTypes, type ConflictUpsert, type CountResult, type D1Meta, D1QB, type D1Result, DOQB, type DefaultObject, type DefaultReturnObject, type Delete, type DeleteReturning, type DeleteWithoutReturning, FetchTypes, type Insert, type InsertMultiple, type InsertOne, type InsertWithoutReturning, type Join, JoinTypes, type MaybeAsync, type Migration, type MigrationEntry, type MigrationOptions, type OneResult, OrderTypes, PGQB, type PGResult, type Primitive, Query, QueryBuilder, type QueryBuilderOptions, type QueryLoggerMeta, QueryWithExtra, Raw, type RawQuery, type RawQueryFetchAll, type RawQueryFetchOne, type RawQueryWithoutFetching, type SelectAll, type SelectOne, type SyncType, type Update, type UpdateReturning, type UpdateWithoutReturning, type Where, asyncLoggerWrapper, asyncMigrationsBuilder, defaultLogger, syncLoggerWrapper, syncMigrationsBuilder, type test, trimQuery };
package/dist/index.d.ts CHANGED
@@ -178,6 +178,10 @@ type AsyncType<T> = Promise<T>;
178
178
  type SyncType<T> = T;
179
179
  type MaybeAsync<IsAsync extends boolean, T> = IsAsync extends true ? AsyncType<T> : SyncType<T>;
180
180
 
181
+ declare function defaultLogger(query: RawQuery, meta: QueryLoggerMeta): any;
182
+ declare function asyncLoggerWrapper<Async extends boolean = true>(query: Query<any, Async> | Query<any, Async>[], loggerFunction: CallableFunction | undefined, innerFunction: () => any): Promise<any>;
183
+ declare function syncLoggerWrapper<Async extends boolean = false>(query: Query<any, Async> | Query<any, Async>[], loggerFunction: CallableFunction | undefined, innerFunction: () => any): any;
184
+
181
185
  declare class SelectBuilder<GenericResultWrapper, GenericResult = DefaultReturnObject, IsAsync extends boolean = true> {
182
186
  _debugger: boolean;
183
187
  _options: Partial<SelectAll>;
@@ -203,10 +207,6 @@ declare class SelectBuilder<GenericResultWrapper, GenericResult = DefaultReturnO
203
207
  count(): MaybeAsync<IsAsync, CountResult<GenericResultWrapper>>;
204
208
  }
205
209
 
206
- declare function defaultLogger(query: RawQuery, meta: QueryLoggerMeta): any;
207
- declare function asyncLoggerWrapper<Async extends boolean = true>(query: Query<any, Async> | Query<any, Async>[], loggerFunction: CallableFunction | undefined, innerFunction: () => any): Promise<any>;
208
- declare function syncLoggerWrapper<Async extends boolean = false>(query: Query<any, Async> | Query<any, Async>[], loggerFunction: CallableFunction | undefined, innerFunction: () => any): any;
209
-
210
210
  declare class QueryBuilder<GenericResultWrapper, IsAsync extends boolean = true> {
211
211
  protected options: QueryBuilderOptions<IsAsync>;
212
212
  loggerWrapper: typeof asyncLoggerWrapper;
@@ -253,16 +253,53 @@ declare class QueryBuilder<GenericResultWrapper, IsAsync extends boolean = true>
253
253
  protected _returning(value?: string | Array<string>): string;
254
254
  }
255
255
 
256
+ type MigrationEntry = {
257
+ id: number;
258
+ name: string;
259
+ applied_at: Date;
260
+ };
261
+ type Migration = {
262
+ name: string;
263
+ sql: string;
264
+ };
265
+ type MigrationOptions = {
266
+ migrations: Array<Migration>;
267
+ tableName?: string;
268
+ };
269
+ declare class syncMigrationsBuilder<GenericResultWrapper> {
270
+ _builder: QueryBuilder<GenericResultWrapper, false>;
271
+ _migrations: Array<Migration>;
272
+ _tableName: string;
273
+ constructor(options: MigrationOptions, builder: QueryBuilder<GenericResultWrapper, false>);
274
+ initialize(): void;
275
+ getApplied(): Array<MigrationEntry>;
276
+ getUnapplied(): Array<Migration>;
277
+ apply(): Array<Migration>;
278
+ }
279
+ declare class asyncMigrationsBuilder<GenericResultWrapper> {
280
+ _builder: QueryBuilder<GenericResultWrapper, true>;
281
+ _migrations: Array<Migration>;
282
+ _tableName: string;
283
+ constructor(options: MigrationOptions, builder: QueryBuilder<GenericResultWrapper, true>);
284
+ initialize(): Promise<void>;
285
+ getApplied(): Promise<Array<MigrationEntry>>;
286
+ getUnapplied(): Promise<Array<Migration>>;
287
+ apply(): Promise<Array<Migration>>;
288
+ }
289
+
256
290
  declare class D1QB extends QueryBuilder<D1Result> {
257
291
  db: any;
258
292
  constructor(db: any, options?: QueryBuilderOptions);
293
+ migrations(options: MigrationOptions): asyncMigrationsBuilder<D1Result>;
259
294
  execute(query: Query): Promise<any>;
260
295
  batchExecute(queryArray: Query[]): Promise<any>;
261
296
  }
262
297
 
263
298
  declare class PGQB extends QueryBuilder<PGResult> {
264
299
  db: any;
300
+ _migrationsBuilder: typeof asyncMigrationsBuilder;
265
301
  constructor(db: any, options?: QueryBuilderOptions);
302
+ migrations(options: MigrationOptions): asyncMigrationsBuilder<PGResult>;
266
303
  connect(): Promise<void>;
267
304
  close(): Promise<void>;
268
305
  execute(query: Query): Promise<any>;
@@ -272,7 +309,8 @@ declare class DOQB extends QueryBuilder<{}, false> {
272
309
  db: any;
273
310
  loggerWrapper: typeof syncLoggerWrapper;
274
311
  constructor(db: any, options?: QueryBuilderOptions<false>);
312
+ migrations(options: MigrationOptions): syncMigrationsBuilder<{}>;
275
313
  execute(query: Query<any, false>): any;
276
314
  }
277
315
 
278
- export { type ArrayResult, type AsyncType, ConflictTypes, type ConflictUpsert, type CountResult, type D1Meta, D1QB, type D1Result, DOQB, type DefaultObject, type DefaultReturnObject, type Delete, type DeleteReturning, type DeleteWithoutReturning, FetchTypes, type Insert, type InsertMultiple, type InsertOne, type InsertWithoutReturning, type Join, JoinTypes, type MaybeAsync, type OneResult, OrderTypes, PGQB, type PGResult, type Primitive, Query, QueryBuilder, type QueryBuilderOptions, type QueryLoggerMeta, QueryWithExtra, Raw, type RawQuery, type RawQueryFetchAll, type RawQueryFetchOne, type RawQueryWithoutFetching, type SelectAll, type SelectOne, type SyncType, type Update, type UpdateReturning, type UpdateWithoutReturning, type Where, asyncLoggerWrapper, defaultLogger, syncLoggerWrapper, type test, trimQuery };
316
+ export { type ArrayResult, type AsyncType, ConflictTypes, type ConflictUpsert, type CountResult, type D1Meta, D1QB, type D1Result, DOQB, type DefaultObject, type DefaultReturnObject, type Delete, type DeleteReturning, type DeleteWithoutReturning, FetchTypes, type Insert, type InsertMultiple, type InsertOne, type InsertWithoutReturning, type Join, JoinTypes, type MaybeAsync, type Migration, type MigrationEntry, type MigrationOptions, type OneResult, OrderTypes, PGQB, type PGResult, type Primitive, Query, QueryBuilder, type QueryBuilderOptions, type QueryLoggerMeta, QueryWithExtra, Raw, type RawQuery, type RawQueryFetchAll, type RawQueryFetchOne, type RawQueryWithoutFetching, type SelectAll, type SelectOne, type SyncType, type Update, type UpdateReturning, type UpdateWithoutReturning, type Where, asyncLoggerWrapper, asyncMigrationsBuilder, defaultLogger, syncLoggerWrapper, syncMigrationsBuilder, type test, trimQuery };
package/dist/index.js CHANGED
@@ -32,8 +32,10 @@ __export(src_exports, {
32
32
  QueryWithExtra: () => QueryWithExtra,
33
33
  Raw: () => Raw,
34
34
  asyncLoggerWrapper: () => asyncLoggerWrapper,
35
+ asyncMigrationsBuilder: () => asyncMigrationsBuilder,
35
36
  defaultLogger: () => defaultLogger,
36
37
  syncLoggerWrapper: () => syncLoggerWrapper,
38
+ syncMigrationsBuilder: () => syncMigrationsBuilder,
37
39
  trimQuery: () => trimQuery
38
40
  });
39
41
  module.exports = __toCommonJS(src_exports);
@@ -64,50 +66,45 @@ var JoinTypes = /* @__PURE__ */ ((JoinTypes2) => {
64
66
  return JoinTypes2;
65
67
  })(JoinTypes || {});
66
68
 
67
- // src/tools.ts
68
- var Raw = class {
69
- isRaw = true;
70
- content;
71
- constructor(content) {
72
- this.content = content;
73
- }
74
- };
75
- var Query = class {
76
- executeMethod;
77
- query;
78
- arguments;
79
- fetchType;
80
- constructor(executeMethod, query, args, fetchType) {
81
- this.executeMethod = executeMethod;
82
- this.query = trimQuery(query);
83
- this.arguments = args;
84
- this.fetchType = fetchType;
85
- }
86
- execute() {
87
- return this.executeMethod(this);
88
- }
89
- toObject() {
90
- return {
91
- query: this.query,
92
- args: this.arguments,
93
- fetchType: this.fetchType
94
- };
95
- }
96
- };
97
- var QueryWithExtra = class extends Query {
98
- countQuery;
99
- constructor(executeMethod, query, countQuery, args, fetchType) {
100
- super(executeMethod, query, args, fetchType);
101
- this.countQuery = countQuery;
69
+ // src/logger.ts
70
+ function defaultLogger(query, meta) {
71
+ console.log(`[workers-qb][${meta.duration}ms] ${JSON.stringify(query)}`);
72
+ }
73
+ async function asyncLoggerWrapper(query, loggerFunction, innerFunction) {
74
+ const start = Date.now();
75
+ try {
76
+ return await innerFunction();
77
+ } catch (e) {
78
+ throw e;
79
+ } finally {
80
+ if (loggerFunction) {
81
+ if (Array.isArray(query)) {
82
+ for (const q of query) {
83
+ await loggerFunction(q.toObject(), { duration: Date.now() - start });
84
+ }
85
+ } else {
86
+ await loggerFunction(query.toObject(), { duration: Date.now() - start });
87
+ }
88
+ }
102
89
  }
103
- count() {
104
- return this.executeMethod(
105
- new Query(this.executeMethod, this.countQuery, this.arguments, "ONE" /* ONE */)
106
- );
90
+ }
91
+ function syncLoggerWrapper(query, loggerFunction, innerFunction) {
92
+ const start = Date.now();
93
+ try {
94
+ return innerFunction();
95
+ } catch (e) {
96
+ throw e;
97
+ } finally {
98
+ if (loggerFunction) {
99
+ if (Array.isArray(query)) {
100
+ for (const q of query) {
101
+ loggerFunction(q.toObject(), { duration: Date.now() - start });
102
+ }
103
+ } else {
104
+ loggerFunction(query.toObject(), { duration: Date.now() - start });
105
+ }
106
+ }
107
107
  }
108
- };
109
- function trimQuery(query) {
110
- return query.replace(/\s\s+/g, " ");
111
108
  }
112
109
 
113
110
  // src/modularBuilder.ts
@@ -234,45 +231,50 @@ var SelectBuilder = class _SelectBuilder {
234
231
  }
235
232
  };
236
233
 
237
- // src/logger.ts
238
- function defaultLogger(query, meta) {
239
- console.log(`[workers-qb][${meta.duration}ms] ${JSON.stringify(query)}`);
240
- }
241
- async function asyncLoggerWrapper(query, loggerFunction, innerFunction) {
242
- const start = Date.now();
243
- try {
244
- return await innerFunction();
245
- } catch (e) {
246
- throw e;
247
- } finally {
248
- if (loggerFunction) {
249
- if (Array.isArray(query)) {
250
- for (const q of query) {
251
- await loggerFunction(q.toObject(), { duration: Date.now() - start });
252
- }
253
- } else {
254
- await loggerFunction(query.toObject(), { duration: Date.now() - start });
255
- }
256
- }
234
+ // src/tools.ts
235
+ var Raw = class {
236
+ isRaw = true;
237
+ content;
238
+ constructor(content) {
239
+ this.content = content;
257
240
  }
258
- }
259
- function syncLoggerWrapper(query, loggerFunction, innerFunction) {
260
- const start = Date.now();
261
- try {
262
- return innerFunction();
263
- } catch (e) {
264
- throw e;
265
- } finally {
266
- if (loggerFunction) {
267
- if (Array.isArray(query)) {
268
- for (const q of query) {
269
- loggerFunction(q.toObject(), { duration: Date.now() - start });
270
- }
271
- } else {
272
- loggerFunction(query.toObject(), { duration: Date.now() - start });
273
- }
274
- }
241
+ };
242
+ var Query = class {
243
+ executeMethod;
244
+ query;
245
+ arguments;
246
+ fetchType;
247
+ constructor(executeMethod, query, args, fetchType) {
248
+ this.executeMethod = executeMethod;
249
+ this.query = trimQuery(query);
250
+ this.arguments = args;
251
+ this.fetchType = fetchType;
275
252
  }
253
+ execute() {
254
+ return this.executeMethod(this);
255
+ }
256
+ toObject() {
257
+ return {
258
+ query: this.query,
259
+ args: this.arguments,
260
+ fetchType: this.fetchType
261
+ };
262
+ }
263
+ };
264
+ var QueryWithExtra = class extends Query {
265
+ countQuery;
266
+ constructor(executeMethod, query, countQuery, args, fetchType) {
267
+ super(executeMethod, query, args, fetchType);
268
+ this.countQuery = countQuery;
269
+ }
270
+ count() {
271
+ return this.executeMethod(
272
+ new Query(this.executeMethod, this.countQuery, this.arguments, "ONE" /* ONE */)
273
+ );
274
+ }
275
+ };
276
+ function trimQuery(query) {
277
+ return query.replace(/\s\s+/g, " ");
276
278
  }
277
279
 
278
280
  // src/builder.ts
@@ -308,9 +310,12 @@ var QueryBuilder = class {
308
310
  );
309
311
  }
310
312
  dropTable(params) {
311
- return new Query((q) => {
312
- return this.execute(q);
313
- }, `DROP TABLE ${params.ifExists ? "IF EXISTS" : ""} ${params.tableName}`);
313
+ return new Query(
314
+ (q) => {
315
+ return this.execute(q);
316
+ },
317
+ `DROP TABLE ${params.ifExists ? "IF EXISTS" : ""} ${params.tableName}`
318
+ );
314
319
  }
315
320
  select(tableName) {
316
321
  return new SelectBuilder(
@@ -524,8 +529,9 @@ var QueryBuilder = class {
524
529
  conditions = value.conditions;
525
530
  }
526
531
  if (typeof conditions === "string") return ` WHERE ${conditions.toString()}`;
527
- if (conditions.length > 0) {
528
- return ` WHERE ${conditions.join(" AND ")}`;
532
+ if (conditions.length === 1) return ` WHERE ${conditions[0].toString()}`;
533
+ if (conditions.length > 1) {
534
+ return ` WHERE (${conditions.join(") AND (")})`;
529
535
  }
530
536
  return "";
531
537
  }
@@ -592,6 +598,114 @@ var QueryBuilder = class {
592
598
  }
593
599
  };
594
600
 
601
+ // src/migrations.ts
602
+ var syncMigrationsBuilder = class {
603
+ _builder;
604
+ _migrations;
605
+ _tableName;
606
+ constructor(options, builder) {
607
+ this._tableName = options.tableName || "migrations";
608
+ this._migrations = options.migrations;
609
+ this._builder = builder;
610
+ }
611
+ initialize() {
612
+ this._builder.createTable({
613
+ tableName: this._tableName,
614
+ schema: `id INTEGER PRIMARY KEY AUTOINCREMENT,
615
+ name TEXT UNIQUE,
616
+ applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL`,
617
+ ifNotExists: true
618
+ }).execute();
619
+ return;
620
+ }
621
+ getApplied() {
622
+ this.initialize();
623
+ const result = this._builder.fetchAll({
624
+ tableName: this._tableName,
625
+ orderBy: "id"
626
+ }).execute();
627
+ return result.results || [];
628
+ }
629
+ getUnapplied() {
630
+ const appliedMigrations = this.getApplied().map((migration) => {
631
+ return migration.name;
632
+ });
633
+ const unappliedMigrations = [];
634
+ for (const migration of this._migrations) {
635
+ if (!appliedMigrations.includes(migration.name)) {
636
+ unappliedMigrations.push(migration);
637
+ }
638
+ }
639
+ return unappliedMigrations;
640
+ }
641
+ apply() {
642
+ const appliedMigrations = [];
643
+ for (const migration of this.getUnapplied()) {
644
+ this._builder.raw({
645
+ query: `
646
+ ${migration.sql}
647
+ INSERT INTO ${this._tableName} (name)
648
+ values ('${migration.name}');`
649
+ }).execute();
650
+ appliedMigrations.push(migration);
651
+ }
652
+ return appliedMigrations;
653
+ }
654
+ };
655
+ var asyncMigrationsBuilder = class {
656
+ _builder;
657
+ _migrations;
658
+ _tableName;
659
+ constructor(options, builder) {
660
+ this._tableName = options.tableName || "migrations";
661
+ this._migrations = options.migrations;
662
+ this._builder = builder;
663
+ }
664
+ async initialize() {
665
+ await this._builder.createTable({
666
+ tableName: this._tableName,
667
+ schema: `id INTEGER PRIMARY KEY AUTOINCREMENT,
668
+ name TEXT UNIQUE,
669
+ applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL`,
670
+ ifNotExists: true
671
+ }).execute();
672
+ return;
673
+ }
674
+ async getApplied() {
675
+ await this.initialize();
676
+ const result = await this._builder.fetchAll({
677
+ tableName: this._tableName,
678
+ orderBy: "id"
679
+ }).execute();
680
+ return result.results || [];
681
+ }
682
+ async getUnapplied() {
683
+ const appliedMigrations = (await this.getApplied()).map((migration) => {
684
+ return migration.name;
685
+ });
686
+ const unappliedMigrations = [];
687
+ for (const migration of this._migrations) {
688
+ if (!appliedMigrations.includes(migration.name)) {
689
+ unappliedMigrations.push(migration);
690
+ }
691
+ }
692
+ return unappliedMigrations;
693
+ }
694
+ async apply() {
695
+ const appliedMigrations = [];
696
+ for (const migration of await this.getUnapplied()) {
697
+ await this._builder.raw({
698
+ query: `
699
+ ${migration.sql}
700
+ INSERT INTO ${this._tableName} (name)
701
+ values ('${migration.name}');`
702
+ }).execute();
703
+ appliedMigrations.push(migration);
704
+ }
705
+ return appliedMigrations;
706
+ }
707
+ };
708
+
595
709
  // src/databases/d1.ts
596
710
  var D1QB = class extends QueryBuilder {
597
711
  db;
@@ -599,6 +713,9 @@ var D1QB = class extends QueryBuilder {
599
713
  super(options);
600
714
  this.db = db;
601
715
  }
716
+ migrations(options) {
717
+ return new asyncMigrationsBuilder(options, this);
718
+ }
602
719
  async execute(query) {
603
720
  return await this.loggerWrapper(query, this.options.logger, async () => {
604
721
  let stmt = this.db.prepare(query.query);
@@ -661,10 +778,14 @@ var D1QB = class extends QueryBuilder {
661
778
  // src/databases/pg.ts
662
779
  var PGQB = class extends QueryBuilder {
663
780
  db;
781
+ _migrationsBuilder = asyncMigrationsBuilder;
664
782
  constructor(db, options) {
665
783
  super(options);
666
784
  this.db = db;
667
785
  }
786
+ migrations(options) {
787
+ return new asyncMigrationsBuilder(options, this);
788
+ }
668
789
  async connect() {
669
790
  await this.db.connect();
670
791
  }
@@ -710,6 +831,9 @@ var DOQB = class extends QueryBuilder {
710
831
  super(options);
711
832
  this.db = db;
712
833
  }
834
+ migrations(options) {
835
+ return new syncMigrationsBuilder(options, this);
836
+ }
713
837
  execute(query) {
714
838
  return this.loggerWrapper(query, this.options.logger, () => {
715
839
  let cursor;
@@ -744,7 +868,9 @@ var DOQB = class extends QueryBuilder {
744
868
  QueryWithExtra,
745
869
  Raw,
746
870
  asyncLoggerWrapper,
871
+ asyncMigrationsBuilder,
747
872
  defaultLogger,
748
873
  syncLoggerWrapper,
874
+ syncMigrationsBuilder,
749
875
  trimQuery
750
876
  });
package/dist/index.mjs CHANGED
@@ -24,50 +24,45 @@ var JoinTypes = /* @__PURE__ */ ((JoinTypes2) => {
24
24
  return JoinTypes2;
25
25
  })(JoinTypes || {});
26
26
 
27
- // src/tools.ts
28
- var Raw = class {
29
- isRaw = true;
30
- content;
31
- constructor(content) {
32
- this.content = content;
33
- }
34
- };
35
- var Query = class {
36
- executeMethod;
37
- query;
38
- arguments;
39
- fetchType;
40
- constructor(executeMethod, query, args, fetchType) {
41
- this.executeMethod = executeMethod;
42
- this.query = trimQuery(query);
43
- this.arguments = args;
44
- this.fetchType = fetchType;
45
- }
46
- execute() {
47
- return this.executeMethod(this);
48
- }
49
- toObject() {
50
- return {
51
- query: this.query,
52
- args: this.arguments,
53
- fetchType: this.fetchType
54
- };
55
- }
56
- };
57
- var QueryWithExtra = class extends Query {
58
- countQuery;
59
- constructor(executeMethod, query, countQuery, args, fetchType) {
60
- super(executeMethod, query, args, fetchType);
61
- this.countQuery = countQuery;
27
+ // src/logger.ts
28
+ function defaultLogger(query, meta) {
29
+ console.log(`[workers-qb][${meta.duration}ms] ${JSON.stringify(query)}`);
30
+ }
31
+ async function asyncLoggerWrapper(query, loggerFunction, innerFunction) {
32
+ const start = Date.now();
33
+ try {
34
+ return await innerFunction();
35
+ } catch (e) {
36
+ throw e;
37
+ } finally {
38
+ if (loggerFunction) {
39
+ if (Array.isArray(query)) {
40
+ for (const q of query) {
41
+ await loggerFunction(q.toObject(), { duration: Date.now() - start });
42
+ }
43
+ } else {
44
+ await loggerFunction(query.toObject(), { duration: Date.now() - start });
45
+ }
46
+ }
62
47
  }
63
- count() {
64
- return this.executeMethod(
65
- new Query(this.executeMethod, this.countQuery, this.arguments, "ONE" /* ONE */)
66
- );
48
+ }
49
+ function syncLoggerWrapper(query, loggerFunction, innerFunction) {
50
+ const start = Date.now();
51
+ try {
52
+ return innerFunction();
53
+ } catch (e) {
54
+ throw e;
55
+ } finally {
56
+ if (loggerFunction) {
57
+ if (Array.isArray(query)) {
58
+ for (const q of query) {
59
+ loggerFunction(q.toObject(), { duration: Date.now() - start });
60
+ }
61
+ } else {
62
+ loggerFunction(query.toObject(), { duration: Date.now() - start });
63
+ }
64
+ }
67
65
  }
68
- };
69
- function trimQuery(query) {
70
- return query.replace(/\s\s+/g, " ");
71
66
  }
72
67
 
73
68
  // src/modularBuilder.ts
@@ -194,45 +189,50 @@ var SelectBuilder = class _SelectBuilder {
194
189
  }
195
190
  };
196
191
 
197
- // src/logger.ts
198
- function defaultLogger(query, meta) {
199
- console.log(`[workers-qb][${meta.duration}ms] ${JSON.stringify(query)}`);
200
- }
201
- async function asyncLoggerWrapper(query, loggerFunction, innerFunction) {
202
- const start = Date.now();
203
- try {
204
- return await innerFunction();
205
- } catch (e) {
206
- throw e;
207
- } finally {
208
- if (loggerFunction) {
209
- if (Array.isArray(query)) {
210
- for (const q of query) {
211
- await loggerFunction(q.toObject(), { duration: Date.now() - start });
212
- }
213
- } else {
214
- await loggerFunction(query.toObject(), { duration: Date.now() - start });
215
- }
216
- }
192
+ // src/tools.ts
193
+ var Raw = class {
194
+ isRaw = true;
195
+ content;
196
+ constructor(content) {
197
+ this.content = content;
217
198
  }
218
- }
219
- function syncLoggerWrapper(query, loggerFunction, innerFunction) {
220
- const start = Date.now();
221
- try {
222
- return innerFunction();
223
- } catch (e) {
224
- throw e;
225
- } finally {
226
- if (loggerFunction) {
227
- if (Array.isArray(query)) {
228
- for (const q of query) {
229
- loggerFunction(q.toObject(), { duration: Date.now() - start });
230
- }
231
- } else {
232
- loggerFunction(query.toObject(), { duration: Date.now() - start });
233
- }
234
- }
199
+ };
200
+ var Query = class {
201
+ executeMethod;
202
+ query;
203
+ arguments;
204
+ fetchType;
205
+ constructor(executeMethod, query, args, fetchType) {
206
+ this.executeMethod = executeMethod;
207
+ this.query = trimQuery(query);
208
+ this.arguments = args;
209
+ this.fetchType = fetchType;
235
210
  }
211
+ execute() {
212
+ return this.executeMethod(this);
213
+ }
214
+ toObject() {
215
+ return {
216
+ query: this.query,
217
+ args: this.arguments,
218
+ fetchType: this.fetchType
219
+ };
220
+ }
221
+ };
222
+ var QueryWithExtra = class extends Query {
223
+ countQuery;
224
+ constructor(executeMethod, query, countQuery, args, fetchType) {
225
+ super(executeMethod, query, args, fetchType);
226
+ this.countQuery = countQuery;
227
+ }
228
+ count() {
229
+ return this.executeMethod(
230
+ new Query(this.executeMethod, this.countQuery, this.arguments, "ONE" /* ONE */)
231
+ );
232
+ }
233
+ };
234
+ function trimQuery(query) {
235
+ return query.replace(/\s\s+/g, " ");
236
236
  }
237
237
 
238
238
  // src/builder.ts
@@ -268,9 +268,12 @@ var QueryBuilder = class {
268
268
  );
269
269
  }
270
270
  dropTable(params) {
271
- return new Query((q) => {
272
- return this.execute(q);
273
- }, `DROP TABLE ${params.ifExists ? "IF EXISTS" : ""} ${params.tableName}`);
271
+ return new Query(
272
+ (q) => {
273
+ return this.execute(q);
274
+ },
275
+ `DROP TABLE ${params.ifExists ? "IF EXISTS" : ""} ${params.tableName}`
276
+ );
274
277
  }
275
278
  select(tableName) {
276
279
  return new SelectBuilder(
@@ -484,8 +487,9 @@ var QueryBuilder = class {
484
487
  conditions = value.conditions;
485
488
  }
486
489
  if (typeof conditions === "string") return ` WHERE ${conditions.toString()}`;
487
- if (conditions.length > 0) {
488
- return ` WHERE ${conditions.join(" AND ")}`;
490
+ if (conditions.length === 1) return ` WHERE ${conditions[0].toString()}`;
491
+ if (conditions.length > 1) {
492
+ return ` WHERE (${conditions.join(") AND (")})`;
489
493
  }
490
494
  return "";
491
495
  }
@@ -552,6 +556,114 @@ var QueryBuilder = class {
552
556
  }
553
557
  };
554
558
 
559
+ // src/migrations.ts
560
+ var syncMigrationsBuilder = class {
561
+ _builder;
562
+ _migrations;
563
+ _tableName;
564
+ constructor(options, builder) {
565
+ this._tableName = options.tableName || "migrations";
566
+ this._migrations = options.migrations;
567
+ this._builder = builder;
568
+ }
569
+ initialize() {
570
+ this._builder.createTable({
571
+ tableName: this._tableName,
572
+ schema: `id INTEGER PRIMARY KEY AUTOINCREMENT,
573
+ name TEXT UNIQUE,
574
+ applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL`,
575
+ ifNotExists: true
576
+ }).execute();
577
+ return;
578
+ }
579
+ getApplied() {
580
+ this.initialize();
581
+ const result = this._builder.fetchAll({
582
+ tableName: this._tableName,
583
+ orderBy: "id"
584
+ }).execute();
585
+ return result.results || [];
586
+ }
587
+ getUnapplied() {
588
+ const appliedMigrations = this.getApplied().map((migration) => {
589
+ return migration.name;
590
+ });
591
+ const unappliedMigrations = [];
592
+ for (const migration of this._migrations) {
593
+ if (!appliedMigrations.includes(migration.name)) {
594
+ unappliedMigrations.push(migration);
595
+ }
596
+ }
597
+ return unappliedMigrations;
598
+ }
599
+ apply() {
600
+ const appliedMigrations = [];
601
+ for (const migration of this.getUnapplied()) {
602
+ this._builder.raw({
603
+ query: `
604
+ ${migration.sql}
605
+ INSERT INTO ${this._tableName} (name)
606
+ values ('${migration.name}');`
607
+ }).execute();
608
+ appliedMigrations.push(migration);
609
+ }
610
+ return appliedMigrations;
611
+ }
612
+ };
613
+ var asyncMigrationsBuilder = class {
614
+ _builder;
615
+ _migrations;
616
+ _tableName;
617
+ constructor(options, builder) {
618
+ this._tableName = options.tableName || "migrations";
619
+ this._migrations = options.migrations;
620
+ this._builder = builder;
621
+ }
622
+ async initialize() {
623
+ await this._builder.createTable({
624
+ tableName: this._tableName,
625
+ schema: `id INTEGER PRIMARY KEY AUTOINCREMENT,
626
+ name TEXT UNIQUE,
627
+ applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL`,
628
+ ifNotExists: true
629
+ }).execute();
630
+ return;
631
+ }
632
+ async getApplied() {
633
+ await this.initialize();
634
+ const result = await this._builder.fetchAll({
635
+ tableName: this._tableName,
636
+ orderBy: "id"
637
+ }).execute();
638
+ return result.results || [];
639
+ }
640
+ async getUnapplied() {
641
+ const appliedMigrations = (await this.getApplied()).map((migration) => {
642
+ return migration.name;
643
+ });
644
+ const unappliedMigrations = [];
645
+ for (const migration of this._migrations) {
646
+ if (!appliedMigrations.includes(migration.name)) {
647
+ unappliedMigrations.push(migration);
648
+ }
649
+ }
650
+ return unappliedMigrations;
651
+ }
652
+ async apply() {
653
+ const appliedMigrations = [];
654
+ for (const migration of await this.getUnapplied()) {
655
+ await this._builder.raw({
656
+ query: `
657
+ ${migration.sql}
658
+ INSERT INTO ${this._tableName} (name)
659
+ values ('${migration.name}');`
660
+ }).execute();
661
+ appliedMigrations.push(migration);
662
+ }
663
+ return appliedMigrations;
664
+ }
665
+ };
666
+
555
667
  // src/databases/d1.ts
556
668
  var D1QB = class extends QueryBuilder {
557
669
  db;
@@ -559,6 +671,9 @@ var D1QB = class extends QueryBuilder {
559
671
  super(options);
560
672
  this.db = db;
561
673
  }
674
+ migrations(options) {
675
+ return new asyncMigrationsBuilder(options, this);
676
+ }
562
677
  async execute(query) {
563
678
  return await this.loggerWrapper(query, this.options.logger, async () => {
564
679
  let stmt = this.db.prepare(query.query);
@@ -621,10 +736,14 @@ var D1QB = class extends QueryBuilder {
621
736
  // src/databases/pg.ts
622
737
  var PGQB = class extends QueryBuilder {
623
738
  db;
739
+ _migrationsBuilder = asyncMigrationsBuilder;
624
740
  constructor(db, options) {
625
741
  super(options);
626
742
  this.db = db;
627
743
  }
744
+ migrations(options) {
745
+ return new asyncMigrationsBuilder(options, this);
746
+ }
628
747
  async connect() {
629
748
  await this.db.connect();
630
749
  }
@@ -670,6 +789,9 @@ var DOQB = class extends QueryBuilder {
670
789
  super(options);
671
790
  this.db = db;
672
791
  }
792
+ migrations(options) {
793
+ return new syncMigrationsBuilder(options, this);
794
+ }
673
795
  execute(query) {
674
796
  return this.loggerWrapper(query, this.options.logger, () => {
675
797
  let cursor;
@@ -703,7 +825,9 @@ export {
703
825
  QueryWithExtra,
704
826
  Raw,
705
827
  asyncLoggerWrapper,
828
+ asyncMigrationsBuilder,
706
829
  defaultLogger,
707
830
  syncLoggerWrapper,
831
+ syncMigrationsBuilder,
708
832
  trimQuery
709
833
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "workers-qb",
3
- "version": "1.6.6",
3
+ "version": "1.7.0",
4
4
  "description": "Zero dependencies Query Builder for Cloudflare Workers",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -12,10 +12,8 @@
12
12
  ],
13
13
  "scripts": {
14
14
  "build": "tsup src/index.ts --format cjs,esm --dts",
15
- "lint": "tsc -p tsconfig.json",
16
- "test": "jest --config jest.config.cjs --no-cache --runInBand",
17
- "test:cov": "jest --config jest.config.cjs --coverage --no-cache --runInBand",
18
- "prettify": "prettier --check . || (prettier -w .; exit 1)",
15
+ "lint": "npx @biomejs/biome check src/ tests/ || (npx @biomejs/biome check --write src/ tests/; exit 1)",
16
+ "test": "vitest run --root tests",
19
17
  "prepare": "husky install"
20
18
  },
21
19
  "publishConfig": {
@@ -27,6 +25,8 @@
27
25
  "workers",
28
26
  "serverless",
29
27
  "cloudflare d1",
28
+ "cloudflare DO",
29
+ "cloudflare Durable Objects",
30
30
  "d1sql",
31
31
  "sql builder",
32
32
  "query builder",
@@ -56,44 +56,13 @@
56
56
  "url": "https://github.com/G4brym/workers-qb/issues"
57
57
  },
58
58
  "devDependencies": {
59
- "@cloudflare/workers-types": "^4.20240815.0",
60
- "@types/jest": "^29.5.12",
61
- "@typescript-eslint/eslint-plugin": "^4.31.1",
62
- "@typescript-eslint/parser": "^4.31.1",
63
- "changesets": "^1.0.2",
64
- "eslint": "^7.32.0",
65
- "eslint-config-prettier": "^8.3.0",
66
- "eslint-plugin-prettier": "^4.0.0",
67
- "husky": "^7.0.2",
68
- "jest": "^29.7.0",
69
- "pinst": "^2.1.6",
70
- "prettier": "^2.4.0",
71
- "ts-jest": "^29.1.4",
72
- "tsup": "^8.1.0",
73
- "typescript": "^5.4.5"
74
- },
75
- "prettier": {
76
- "semi": false,
77
- "singleQuote": true,
78
- "trailingComma": "es5",
79
- "arrowParens": "always",
80
- "printWidth": 120
81
- },
82
- "eslintConfig": {
83
- "parser": "@typescript-eslint/parser",
84
- "extends": [
85
- "plugin:@typescript-eslint/recommended",
86
- "prettier"
87
- ],
88
- "parserOptions": {
89
- "sourceType": "module"
90
- },
91
- "rules": {
92
- "prettier/prettier": "error"
93
- },
94
- "plugins": [
95
- "@typescript-eslint",
96
- "prettier"
97
- ]
59
+ "@biomejs/biome": "1.9.4",
60
+ "@cloudflare/vitest-pool-workers": "^0.5.26",
61
+ "@cloudflare/workers-types": "^4.20241106.0",
62
+ "husky": "^9.1.6",
63
+ "tsup": "^8.3.5",
64
+ "typescript": "^5.6.3",
65
+ "vitest": "2.0.5",
66
+ "wrangler": "^3.86.0"
98
67
  }
99
68
  }