workers-qb 1.4.3 → 1.5.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/README.md CHANGED
@@ -10,10 +10,12 @@ traditional ORM.
10
10
  `workers-qb` is not intended to provide ORM-like functionality, rather to make it easier to interact with the database
11
11
  from code for direct SQL access using convenient wrapper methods.
12
12
 
13
- Currently, 2 databases are supported:
13
+ Currently, 3 databases are supported:
14
14
 
15
- - [Cloudflare D1](https://developers.cloudflare.com/d1/)
16
- - [PostgreSQL (using node-postgres)](https://developers.cloudflare.com/workers/databases/connect-to-postgres/)
15
+ - [Cloudflare D1](https://workers-qb.massadas.com/databases/cloudflare-d1/)
16
+ - [Cloudflare Durable Objects](https://workers-qb.massadas.com/databases/cloudflare-do/)
17
+ - [PostgreSQL (using node-postgres)](https://workers-qb.massadas.com/databases/postgresql/)
18
+ - [Bring your own Database](https://workers-qb.massadas.com/databases/bring-your-own-database/)
17
19
 
18
20
  ## Features
19
21
 
@@ -22,11 +24,9 @@ Currently, 2 databases are supported:
22
24
  - [x] [Type Checks for data read](https://workers-qb.massadas.com/type-check/)
23
25
  - [x] [Create/drop tables](https://workers-qb.massadas.com/basic-queries/#dropping-and-creating-tables)
24
26
  - [x] [Insert/Bulk Inserts/Update/Select/Delete/Join queries](https://workers-qb.massadas.com/basic-queries/)
27
+ - [x] [Modular selects](https://workers-qb.massadas.com/modular-selects/)
25
28
  - [x] [On Conflict for Inserts and Updates](https://workers-qb.massadas.com/advanced-queries/onConflict/)
26
29
  - [x] [Upsert](https://workers-qb.massadas.com/advanced-queries/upsert/)
27
- - [x] [Support for Cloudflare Workers D1](https://workers-qb.massadas.com/databases/cloudflare-d1/)
28
- - [x] [Support for Cloudflare Workers PostgreSQL (using node-postgres)](https://workers-qb.massadas.com/databases/postgresql/)
29
- - [ ] Named parameters (waiting for full support in D1)
30
30
 
31
31
  ## Installation
32
32
 
package/dist/index.d.mts CHANGED
@@ -1,5 +1,3 @@
1
- import { SqlStorage } from '@cloudflare/workers-types/experimental';
2
-
3
1
  declare enum OrderTypes {
4
2
  ASC = "ASC",
5
3
  DESC = "DESC"
@@ -33,12 +31,14 @@ declare class Query<Result = any> {
33
31
  fetchType?: FetchTypes;
34
32
  constructor(executeMethod: (query: Query<Result>) => Promise<Result>, query: string, args?: Primitive[], fetchType?: FetchTypes);
35
33
  execute(): Promise<Result>;
34
+ toObject(): RawQuery;
36
35
  }
37
36
  declare class QueryWithExtra<GenericResultWrapper, Result = any> extends Query<Result> {
38
37
  private countQuery;
39
38
  constructor(executeMethod: (query: Query<Result>) => Promise<Result>, query: string, countQuery: string, args?: Primitive[], fetchType?: FetchTypes);
40
39
  count(): Promise<CountResult<GenericResultWrapper>>;
41
40
  }
41
+ declare function trimQuery(query: string): string;
42
42
 
43
43
  type OmitIndexSignature<ObjectType> = {
44
44
  [KeyType in keyof ObjectType as {} extends Record<KeyType, unknown> ? never : KeyType]: ObjectType[KeyType];
@@ -55,6 +55,12 @@ type SimpleMerge<Destination, Source> = {
55
55
  type Merge<Destination, Source> = Simplify<SimpleMerge<PickIndexSignature<Destination>, PickIndexSignature<Source>> & SimpleMerge<OmitIndexSignature<Destination>, OmitIndexSignature<Source>>>;
56
56
 
57
57
  type Primitive = null | string | number | boolean | bigint | Raw;
58
+ type QueryLoggerMeta = {
59
+ duration?: number;
60
+ };
61
+ type QueryBuilderOptions = {
62
+ logger?: (query: RawQuery, meta: QueryLoggerMeta) => void | Promise<void>;
63
+ };
58
64
  type DefaultObject = Record<string, Primitive>;
59
65
  type DefaultReturnObject = Record<string, null | string | number | boolean | bigint>;
60
66
  type Where = {
@@ -169,8 +175,9 @@ type CountResult<GenericResultWrapper> = OneResult<GenericResultWrapper, {
169
175
  declare class SelectBuilder<GenericResultWrapper, GenericResult = DefaultReturnObject> {
170
176
  _debugger: boolean;
171
177
  private _options;
172
- private _queryBuilder;
173
- constructor(options: Partial<SelectAll>, queryBuilder: (params: SelectAll) => QueryWithExtra<GenericResultWrapper>);
178
+ private _fetchAll;
179
+ private _fetchOne;
180
+ constructor(options: Partial<SelectAll>, fetchAll: (params: SelectAll) => QueryWithExtra<GenericResultWrapper>, fetchOne: (params: SelectOne) => QueryWithExtra<GenericResultWrapper>);
174
181
  setDebugger(state: boolean): void;
175
182
  tableName(tableName: SelectAll['tableName']): SelectBuilder<GenericResultWrapper, GenericResult>;
176
183
  fields(fields: SelectAll['fields']): SelectBuilder<GenericResultWrapper, GenericResult>;
@@ -182,14 +189,19 @@ declare class SelectBuilder<GenericResultWrapper, GenericResult = DefaultReturnO
182
189
  offset(offset: SelectAll['offset']): SelectBuilder<GenericResultWrapper, GenericResult>;
183
190
  limit(limit: SelectAll['limit']): SelectBuilder<GenericResultWrapper, GenericResult>;
184
191
  private _parseArray;
185
- getQuery(): Query<ArrayResult<GenericResultWrapper, GenericResult>>;
192
+ getQueryAll(): Query<ArrayResult<GenericResultWrapper, GenericResult>>;
193
+ getQueryOne(): Query<OneResult<GenericResultWrapper, GenericResult>>;
186
194
  execute(): Promise<ArrayResult<GenericResultWrapper, GenericResult>>;
195
+ all(): Promise<ArrayResult<GenericResultWrapper, GenericResult>>;
196
+ one(): Promise<OneResult<GenericResultWrapper, GenericResult>>;
187
197
  count(): Promise<CountResult<GenericResultWrapper>>;
188
198
  }
189
199
 
190
200
  declare class QueryBuilder<GenericResultWrapper> {
191
- _debugger: boolean;
201
+ protected options: QueryBuilderOptions;
202
+ constructor(options?: QueryBuilderOptions);
192
203
  setDebugger(state: boolean): void;
204
+ loggerWrapper(query: Query | Query[], innerFunction: () => any): Promise<any>;
193
205
  execute(query: Query): Promise<any>;
194
206
  batchExecute(queryArray: Query[]): Promise<any[]>;
195
207
  createTable<GenericResult = undefined>(params: {
@@ -233,39 +245,23 @@ declare class QueryBuilder<GenericResultWrapper> {
233
245
 
234
246
  declare class D1QB extends QueryBuilder<D1Result> {
235
247
  db: any;
236
- constructor(db: any);
248
+ constructor(db: any, options?: QueryBuilderOptions);
237
249
  execute(query: Query): Promise<any>;
238
250
  batchExecute(queryArray: Query[]): Promise<any>;
239
251
  }
240
252
 
241
253
  declare class PGQB extends QueryBuilder<PGResult> {
242
254
  db: any;
243
- constructor(db: any);
255
+ constructor(db: any, options?: QueryBuilderOptions);
244
256
  connect(): Promise<void>;
245
257
  close(): Promise<void>;
246
- execute(query: Query): Promise<{
247
- command: any;
248
- lastRowId: any;
249
- rowCount: any;
250
- results: any;
251
- } | {
252
- command: any;
253
- lastRowId: any;
254
- rowCount: any;
255
- results?: undefined;
256
- }>;
258
+ execute(query: Query): Promise<any>;
257
259
  }
258
260
 
259
261
  declare class DOQB extends QueryBuilder<{}> {
260
- db: SqlStorage;
261
- constructor(db: SqlStorage);
262
- execute(query: Query): Promise<{
263
- results: Record<string, string | number | ArrayBuffer | null> | undefined;
264
- } | {
265
- results: Record<string, string | number | ArrayBuffer | null>[];
266
- }>;
267
- }
268
- declare class DurableObjectDatabaseQB extends DOQB {
262
+ db: any;
263
+ constructor(db: any, options?: QueryBuilderOptions);
264
+ execute(query: Query): Promise<any>;
269
265
  }
270
266
 
271
- export { type ArrayResult, ConflictTypes, type ConflictUpsert, type CountResult, type D1Meta, D1QB, type D1Result, DOQB, type DefaultObject, type DefaultReturnObject, type Delete, type DeleteReturning, type DeleteWithoutReturning, DurableObjectDatabaseQB, FetchTypes, type Insert, type InsertMultiple, type InsertOne, type InsertWithoutReturning, type Join, JoinTypes, type OneResult, OrderTypes, PGQB, type PGResult, type Primitive, Query, QueryBuilder, QueryWithExtra, Raw, type RawQuery, type RawQueryFetchAll, type RawQueryFetchOne, type RawQueryWithoutFetching, type SelectAll, type SelectOne, type Update, type UpdateReturning, type UpdateWithoutReturning, type Where, type test };
267
+ export { type ArrayResult, 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 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 Update, type UpdateReturning, type UpdateWithoutReturning, type Where, type test, trimQuery };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,3 @@
1
- import { SqlStorage } from '@cloudflare/workers-types/experimental';
2
-
3
1
  declare enum OrderTypes {
4
2
  ASC = "ASC",
5
3
  DESC = "DESC"
@@ -33,12 +31,14 @@ declare class Query<Result = any> {
33
31
  fetchType?: FetchTypes;
34
32
  constructor(executeMethod: (query: Query<Result>) => Promise<Result>, query: string, args?: Primitive[], fetchType?: FetchTypes);
35
33
  execute(): Promise<Result>;
34
+ toObject(): RawQuery;
36
35
  }
37
36
  declare class QueryWithExtra<GenericResultWrapper, Result = any> extends Query<Result> {
38
37
  private countQuery;
39
38
  constructor(executeMethod: (query: Query<Result>) => Promise<Result>, query: string, countQuery: string, args?: Primitive[], fetchType?: FetchTypes);
40
39
  count(): Promise<CountResult<GenericResultWrapper>>;
41
40
  }
41
+ declare function trimQuery(query: string): string;
42
42
 
43
43
  type OmitIndexSignature<ObjectType> = {
44
44
  [KeyType in keyof ObjectType as {} extends Record<KeyType, unknown> ? never : KeyType]: ObjectType[KeyType];
@@ -55,6 +55,12 @@ type SimpleMerge<Destination, Source> = {
55
55
  type Merge<Destination, Source> = Simplify<SimpleMerge<PickIndexSignature<Destination>, PickIndexSignature<Source>> & SimpleMerge<OmitIndexSignature<Destination>, OmitIndexSignature<Source>>>;
56
56
 
57
57
  type Primitive = null | string | number | boolean | bigint | Raw;
58
+ type QueryLoggerMeta = {
59
+ duration?: number;
60
+ };
61
+ type QueryBuilderOptions = {
62
+ logger?: (query: RawQuery, meta: QueryLoggerMeta) => void | Promise<void>;
63
+ };
58
64
  type DefaultObject = Record<string, Primitive>;
59
65
  type DefaultReturnObject = Record<string, null | string | number | boolean | bigint>;
60
66
  type Where = {
@@ -169,8 +175,9 @@ type CountResult<GenericResultWrapper> = OneResult<GenericResultWrapper, {
169
175
  declare class SelectBuilder<GenericResultWrapper, GenericResult = DefaultReturnObject> {
170
176
  _debugger: boolean;
171
177
  private _options;
172
- private _queryBuilder;
173
- constructor(options: Partial<SelectAll>, queryBuilder: (params: SelectAll) => QueryWithExtra<GenericResultWrapper>);
178
+ private _fetchAll;
179
+ private _fetchOne;
180
+ constructor(options: Partial<SelectAll>, fetchAll: (params: SelectAll) => QueryWithExtra<GenericResultWrapper>, fetchOne: (params: SelectOne) => QueryWithExtra<GenericResultWrapper>);
174
181
  setDebugger(state: boolean): void;
175
182
  tableName(tableName: SelectAll['tableName']): SelectBuilder<GenericResultWrapper, GenericResult>;
176
183
  fields(fields: SelectAll['fields']): SelectBuilder<GenericResultWrapper, GenericResult>;
@@ -182,14 +189,19 @@ declare class SelectBuilder<GenericResultWrapper, GenericResult = DefaultReturnO
182
189
  offset(offset: SelectAll['offset']): SelectBuilder<GenericResultWrapper, GenericResult>;
183
190
  limit(limit: SelectAll['limit']): SelectBuilder<GenericResultWrapper, GenericResult>;
184
191
  private _parseArray;
185
- getQuery(): Query<ArrayResult<GenericResultWrapper, GenericResult>>;
192
+ getQueryAll(): Query<ArrayResult<GenericResultWrapper, GenericResult>>;
193
+ getQueryOne(): Query<OneResult<GenericResultWrapper, GenericResult>>;
186
194
  execute(): Promise<ArrayResult<GenericResultWrapper, GenericResult>>;
195
+ all(): Promise<ArrayResult<GenericResultWrapper, GenericResult>>;
196
+ one(): Promise<OneResult<GenericResultWrapper, GenericResult>>;
187
197
  count(): Promise<CountResult<GenericResultWrapper>>;
188
198
  }
189
199
 
190
200
  declare class QueryBuilder<GenericResultWrapper> {
191
- _debugger: boolean;
201
+ protected options: QueryBuilderOptions;
202
+ constructor(options?: QueryBuilderOptions);
192
203
  setDebugger(state: boolean): void;
204
+ loggerWrapper(query: Query | Query[], innerFunction: () => any): Promise<any>;
193
205
  execute(query: Query): Promise<any>;
194
206
  batchExecute(queryArray: Query[]): Promise<any[]>;
195
207
  createTable<GenericResult = undefined>(params: {
@@ -233,39 +245,23 @@ declare class QueryBuilder<GenericResultWrapper> {
233
245
 
234
246
  declare class D1QB extends QueryBuilder<D1Result> {
235
247
  db: any;
236
- constructor(db: any);
248
+ constructor(db: any, options?: QueryBuilderOptions);
237
249
  execute(query: Query): Promise<any>;
238
250
  batchExecute(queryArray: Query[]): Promise<any>;
239
251
  }
240
252
 
241
253
  declare class PGQB extends QueryBuilder<PGResult> {
242
254
  db: any;
243
- constructor(db: any);
255
+ constructor(db: any, options?: QueryBuilderOptions);
244
256
  connect(): Promise<void>;
245
257
  close(): Promise<void>;
246
- execute(query: Query): Promise<{
247
- command: any;
248
- lastRowId: any;
249
- rowCount: any;
250
- results: any;
251
- } | {
252
- command: any;
253
- lastRowId: any;
254
- rowCount: any;
255
- results?: undefined;
256
- }>;
258
+ execute(query: Query): Promise<any>;
257
259
  }
258
260
 
259
261
  declare class DOQB extends QueryBuilder<{}> {
260
- db: SqlStorage;
261
- constructor(db: SqlStorage);
262
- execute(query: Query): Promise<{
263
- results: Record<string, string | number | ArrayBuffer | null> | undefined;
264
- } | {
265
- results: Record<string, string | number | ArrayBuffer | null>[];
266
- }>;
267
- }
268
- declare class DurableObjectDatabaseQB extends DOQB {
262
+ db: any;
263
+ constructor(db: any, options?: QueryBuilderOptions);
264
+ execute(query: Query): Promise<any>;
269
265
  }
270
266
 
271
- export { type ArrayResult, ConflictTypes, type ConflictUpsert, type CountResult, type D1Meta, D1QB, type D1Result, DOQB, type DefaultObject, type DefaultReturnObject, type Delete, type DeleteReturning, type DeleteWithoutReturning, DurableObjectDatabaseQB, FetchTypes, type Insert, type InsertMultiple, type InsertOne, type InsertWithoutReturning, type Join, JoinTypes, type OneResult, OrderTypes, PGQB, type PGResult, type Primitive, Query, QueryBuilder, QueryWithExtra, Raw, type RawQuery, type RawQueryFetchAll, type RawQueryFetchOne, type RawQueryWithoutFetching, type SelectAll, type SelectOne, type Update, type UpdateReturning, type UpdateWithoutReturning, type Where, type test };
267
+ export { type ArrayResult, 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 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 Update, type UpdateReturning, type UpdateWithoutReturning, type Where, type test, trimQuery };
package/dist/index.js CHANGED
@@ -23,7 +23,6 @@ __export(src_exports, {
23
23
  ConflictTypes: () => ConflictTypes,
24
24
  D1QB: () => D1QB,
25
25
  DOQB: () => DOQB,
26
- DurableObjectDatabaseQB: () => DurableObjectDatabaseQB,
27
26
  FetchTypes: () => FetchTypes,
28
27
  JoinTypes: () => JoinTypes,
29
28
  OrderTypes: () => OrderTypes,
@@ -31,7 +30,8 @@ __export(src_exports, {
31
30
  Query: () => Query,
32
31
  QueryBuilder: () => QueryBuilder,
33
32
  QueryWithExtra: () => QueryWithExtra,
34
- Raw: () => Raw
33
+ Raw: () => Raw,
34
+ trimQuery: () => trimQuery
35
35
  });
36
36
  module.exports = __toCommonJS(src_exports);
37
37
 
@@ -76,13 +76,20 @@ var Query = class {
76
76
  fetchType;
77
77
  constructor(executeMethod, query, args, fetchType) {
78
78
  this.executeMethod = executeMethod;
79
- this.query = query;
79
+ this.query = trimQuery(query);
80
80
  this.arguments = args;
81
81
  this.fetchType = fetchType;
82
82
  }
83
83
  async execute() {
84
84
  return this.executeMethod(this);
85
85
  }
86
+ toObject() {
87
+ return {
88
+ query: this.query,
89
+ args: this.arguments,
90
+ fetchType: this.fetchType
91
+ };
92
+ }
86
93
  };
87
94
  var QueryWithExtra = class extends Query {
88
95
  countQuery;
@@ -96,15 +103,20 @@ var QueryWithExtra = class extends Query {
96
103
  );
97
104
  }
98
105
  };
106
+ function trimQuery(query) {
107
+ return query.replace(/\s\s+/g, " ");
108
+ }
99
109
 
100
110
  // src/modularBuilder.ts
101
111
  var SelectBuilder = class _SelectBuilder {
102
112
  _debugger = false;
103
113
  _options = {};
104
- _queryBuilder;
105
- constructor(options, queryBuilder) {
114
+ _fetchAll;
115
+ _fetchOne;
116
+ constructor(options, fetchAll, fetchOne) {
106
117
  this._options = options;
107
- this._queryBuilder = queryBuilder;
118
+ this._fetchAll = fetchAll;
119
+ this._fetchOne = fetchOne;
108
120
  }
109
121
  setDebugger(state) {
110
122
  this._debugger = state;
@@ -115,7 +127,8 @@ var SelectBuilder = class _SelectBuilder {
115
127
  ...this._options,
116
128
  tableName
117
129
  },
118
- this._queryBuilder
130
+ this._fetchAll,
131
+ this._fetchOne
119
132
  );
120
133
  }
121
134
  fields(fields) {
@@ -143,7 +156,8 @@ var SelectBuilder = class _SelectBuilder {
143
156
  params
144
157
  }
145
158
  },
146
- this._queryBuilder
159
+ this._fetchAll,
160
+ this._fetchOne
147
161
  );
148
162
  }
149
163
  join(join) {
@@ -164,7 +178,8 @@ var SelectBuilder = class _SelectBuilder {
164
178
  ...this._options,
165
179
  offset
166
180
  },
167
- this._queryBuilder
181
+ this._fetchAll,
182
+ this._fetchOne
168
183
  );
169
184
  }
170
185
  limit(limit) {
@@ -173,7 +188,8 @@ var SelectBuilder = class _SelectBuilder {
173
188
  ...this._options,
174
189
  limit
175
190
  },
176
- this._queryBuilder
191
+ this._fetchAll,
192
+ this._fetchOne
177
193
  );
178
194
  }
179
195
  _parseArray(fieldName, option, value) {
@@ -191,25 +207,65 @@ var SelectBuilder = class _SelectBuilder {
191
207
  ...this._options,
192
208
  [fieldName]: val
193
209
  },
194
- this._queryBuilder
210
+ this._fetchAll,
211
+ this._fetchOne
195
212
  );
196
213
  }
197
- getQuery() {
198
- return this._queryBuilder(this._options);
214
+ getQueryAll() {
215
+ return this._fetchAll(this._options);
216
+ }
217
+ getQueryOne() {
218
+ return this._fetchOne(this._options);
199
219
  }
200
220
  async execute() {
201
- return this._queryBuilder(this._options).execute();
221
+ return this._fetchAll(this._options).execute();
222
+ }
223
+ async all() {
224
+ return this._fetchAll(this._options).execute();
225
+ }
226
+ async one() {
227
+ return this._fetchOne(this._options).execute();
202
228
  }
203
229
  async count() {
204
- return this._queryBuilder(this._options).count();
230
+ return this._fetchOne(this._options).count();
205
231
  }
206
232
  };
207
233
 
208
234
  // src/builder.ts
209
235
  var QueryBuilder = class {
210
- _debugger = false;
236
+ options;
237
+ constructor(options) {
238
+ this.options = options || {};
239
+ }
211
240
  setDebugger(state) {
212
- this._debugger = state;
241
+ if (state === true) {
242
+ if (this.options.logger) {
243
+ return;
244
+ }
245
+ this.options.logger = (query, meta) => {
246
+ console.log(`[workers-qb][${meta.duration}ms] ${JSON.stringify(query)}`);
247
+ };
248
+ } else {
249
+ this.options.logger = void 0;
250
+ }
251
+ }
252
+ async loggerWrapper(query, innerFunction) {
253
+ const start = Date.now();
254
+ try {
255
+ return await innerFunction();
256
+ } catch (e) {
257
+ throw e;
258
+ } finally {
259
+ if (this.options.logger) {
260
+ if (Array.isArray(query)) {
261
+ for (const q of query) {
262
+ await this.options.logger(q.toObject(), { duration: Date.now() - start });
263
+ }
264
+ } else {
265
+ await this.options.logger(query.toObject(), { duration: Date.now() - start });
266
+ }
267
+ }
268
+ }
213
269
  }
214
270
  async execute(query) {
215
271
  throw new Error("Execute method not implemented");
@@ -238,6 +294,9 @@ var QueryBuilder = class {
238
294
  },
239
295
  (params) => {
240
296
  return this.fetchAll(params);
297
+ },
298
+ (params) => {
299
+ return this.fetchOne(params);
241
300
  }
242
301
  );
243
302
  }
@@ -507,84 +566,74 @@ var QueryBuilder = class {
507
566
  // src/databases/d1.ts
508
567
  var D1QB = class extends QueryBuilder {
509
568
  db;
510
- constructor(db) {
511
- super();
569
+ constructor(db, options) {
570
+ super(options);
512
571
  this.db = db;
513
572
  }
514
573
  async execute(query) {
515
- let stmt = this.db.prepare(query.query);
516
- if (this._debugger) {
517
- console.log({
518
- "workers-qb": {
519
- query: query.query,
520
- arguments: query.arguments,
521
- fetchType: query.fetchType
522
- }
523
- });
524
- }
525
- if (query.arguments) {
526
- stmt = stmt.bind(...query.arguments);
527
- }
528
- if (query.fetchType === "ONE" /* ONE */ || query.fetchType === "ALL" /* ALL */) {
529
- const resp = await stmt.all();
530
- return {
531
- changes: resp.meta?.changes,
532
- duration: resp.meta?.duration,
533
- last_row_id: resp.meta?.last_row_id,
534
- served_by: resp.meta?.served_by,
535
- meta: resp.meta,
536
- success: resp.success,
537
- results: query.fetchType === "ONE" /* ONE */ ? resp.results[0] : resp.results
538
- };
539
- }
540
- return stmt.run();
541
- }
542
- async batchExecute(queryArray) {
543
- if (this._debugger) {
544
- console.log({
545
- "workers-qb": queryArray
546
- });
547
- }
548
- const statements = queryArray.map((query) => {
574
+ return await this.loggerWrapper(query, async () => {
549
575
  let stmt = this.db.prepare(query.query);
550
576
  if (query.arguments) {
551
577
  stmt = stmt.bind(...query.arguments);
552
578
  }
553
- return stmt;
579
+ if (query.fetchType === "ONE" /* ONE */ || query.fetchType === "ALL" /* ALL */) {
580
+ const resp = await stmt.all();
581
+ return {
582
+ changes: resp.meta?.changes,
583
+ duration: resp.meta?.duration,
584
+ last_row_id: resp.meta?.last_row_id,
585
+ served_by: resp.meta?.served_by,
586
+ meta: resp.meta,
587
+ success: resp.success,
588
+ results: query.fetchType === "ONE" /* ONE */ ? resp.results[0] : resp.results
589
+ };
590
+ }
591
+ return stmt.run();
554
592
  });
555
- const responses = await this.db.batch(statements);
556
- return responses.map(
557
- (resp, i) => {
558
- if (queryArray && queryArray[i] !== void 0 && queryArray[i]?.fetchType) {
559
- return {
560
- changes: resp.meta?.changes,
561
- duration: resp.meta?.duration,
562
- last_row_id: resp.meta?.last_row_id,
563
- served_by: resp.meta?.served_by,
564
- meta: resp.meta,
565
- success: resp.success,
566
- results: queryArray[i]?.fetchType === "ONE" /* ONE */ ? resp.results?.[0] : resp.results
567
- };
568
- } else {
569
- return {
570
- changes: resp.meta?.changes,
571
- duration: resp.meta?.duration,
572
- last_row_id: resp.meta?.last_row_id,
573
- served_by: resp.meta?.served_by,
574
- meta: resp.meta,
575
- success: resp.success
576
- };
593
+ }
594
+ async batchExecute(queryArray) {
595
+ return await this.loggerWrapper(queryArray, async () => {
596
+ const statements = queryArray.map((query) => {
597
+ let stmt = this.db.prepare(query.query);
598
+ if (query.arguments) {
599
+ stmt = stmt.bind(...query.arguments);
577
600
  }
578
- }
579
- );
601
+ return stmt;
602
+ });
603
+ const responses = await this.db.batch(statements);
604
+ return responses.map(
605
+ (resp, i) => {
606
+ if (queryArray && queryArray[i] !== void 0 && queryArray[i]?.fetchType) {
607
+ return {
608
+ changes: resp.meta?.changes,
609
+ duration: resp.meta?.duration,
610
+ last_row_id: resp.meta?.last_row_id,
611
+ served_by: resp.meta?.served_by,
612
+ meta: resp.meta,
613
+ success: resp.success,
614
+ results: queryArray[i]?.fetchType === "ONE" /* ONE */ ? resp.results?.[0] : resp.results
615
+ };
616
+ } else {
617
+ return {
618
+ changes: resp.meta?.changes,
619
+ duration: resp.meta?.duration,
620
+ last_row_id: resp.meta?.last_row_id,
621
+ served_by: resp.meta?.served_by,
622
+ meta: resp.meta,
623
+ success: resp.success
624
+ };
625
+ }
626
+ }
627
+ );
628
+ });
580
629
  }
581
630
  };
582
631
 
583
632
  // src/databases/pg.ts
584
633
  var PGQB = class extends QueryBuilder {
585
634
  db;
586
- constructor(db) {
587
- super();
635
+ constructor(db, options) {
636
+ super(options);
588
637
  this.db = db;
589
638
  }
590
639
  async connect() {
@@ -594,87 +643,74 @@ var PGQB = class extends QueryBuilder {
594
643
  await this.db.end();
595
644
  }
596
645
  async execute(query) {
597
- const queryString = query.query.replaceAll("?", "$");
598
- if (this._debugger) {
599
- console.log({
600
- "workers-qb": query
601
- });
602
- }
603
- let result;
604
- if (query.arguments) {
605
- result = await this.db.query({
606
- values: query.arguments,
607
- text: queryString
608
- });
609
- } else {
610
- result = await this.db.query({
611
- text: queryString
612
- });
613
- }
614
- if (query.fetchType === "ONE" /* ONE */ || query.fetchType === "ALL" /* ALL */) {
646
+ return await this.loggerWrapper(query, async () => {
647
+ const queryString = query.query.replaceAll("?", "$");
648
+ let result;
649
+ if (query.arguments) {
650
+ result = await this.db.query({
651
+ values: query.arguments,
652
+ text: queryString
653
+ });
654
+ } else {
655
+ result = await this.db.query({
656
+ text: queryString
657
+ });
658
+ }
659
+ if (query.fetchType === "ONE" /* ONE */ || query.fetchType === "ALL" /* ALL */) {
660
+ return {
661
+ command: result.command,
662
+ lastRowId: result.oid,
663
+ rowCount: result.rowCount,
664
+ results: query.fetchType === "ONE" /* ONE */ ? result.rows[0] : result.rows
665
+ };
666
+ }
615
667
  return {
616
668
  command: result.command,
617
669
  lastRowId: result.oid,
618
- rowCount: result.rowCount,
619
- results: query.fetchType === "ONE" /* ONE */ ? result.rows[0] : result.rows
670
+ rowCount: result.rowCount
620
671
  };
621
- }
622
- return {
623
- command: result.command,
624
- lastRowId: result.oid,
625
- rowCount: result.rowCount
626
- };
672
+ });
627
673
  }
628
674
  };
629
675
 
630
676
  // src/databases/do.ts
631
677
  var DOQB = class extends QueryBuilder {
632
678
  db;
633
- constructor(db) {
634
- super();
679
+ constructor(db, options) {
680
+ super(options);
635
681
  this.db = db;
636
682
  }
637
683
  async execute(query) {
638
- if (this._debugger) {
639
- console.log({
640
- "workers-qb": {
641
- query: query.query,
642
- arguments: query.arguments,
643
- fetchType: query.fetchType
684
+ return await this.loggerWrapper(query, async () => {
685
+ if (query.arguments) {
686
+ let stmt = this.db.prepare(query.query);
687
+ const result = stmt(...query.arguments);
688
+ if (query.fetchType == "ONE" /* ONE */) {
689
+ return {
690
+ results: Array.from(result)[0]
691
+ };
644
692
  }
645
- });
646
- }
647
- if (query.arguments) {
648
- let stmt = this.db.prepare(query.query);
649
- const result = stmt(...query.arguments);
693
+ return {
694
+ results: Array.from(result)
695
+ };
696
+ }
697
+ const cursor = this.db.exec(query.query);
650
698
  if (query.fetchType == "ONE" /* ONE */) {
651
699
  return {
652
- results: Array.from(result)[0]
700
+ results: Array.from(cursor)[0]
653
701
  };
654
702
  }
655
703
  return {
656
- results: Array.from(result)
657
- };
658
- }
659
- const cursor = this.db.exec(query.query);
660
- if (query.fetchType == "ONE" /* ONE */) {
661
- return {
662
- results: Array.from(cursor)[0]
704
+ results: Array.from(cursor)
663
705
  };
664
- }
665
- return {
666
- results: Array.from(cursor)
667
- };
706
+ });
668
707
  }
669
708
  };
670
- var DurableObjectDatabaseQB = class extends DOQB {
671
- };
672
709
  // Annotate the CommonJS export names for ESM import in node:
673
710
  0 && (module.exports = {
674
711
  ConflictTypes,
675
712
  D1QB,
676
713
  DOQB,
677
- DurableObjectDatabaseQB,
678
714
  FetchTypes,
679
715
  JoinTypes,
680
716
  OrderTypes,
@@ -682,5 +718,6 @@ var DurableObjectDatabaseQB = class extends DOQB {
682
718
  Query,
683
719
  QueryBuilder,
684
720
  QueryWithExtra,
685
- Raw
721
+ Raw,
722
+ trimQuery
686
723
  });
package/dist/index.mjs CHANGED
@@ -39,13 +39,20 @@ var Query = class {
39
39
  fetchType;
40
40
  constructor(executeMethod, query, args, fetchType) {
41
41
  this.executeMethod = executeMethod;
42
- this.query = query;
42
+ this.query = trimQuery(query);
43
43
  this.arguments = args;
44
44
  this.fetchType = fetchType;
45
45
  }
46
46
  async execute() {
47
47
  return this.executeMethod(this);
48
48
  }
49
+ toObject() {
50
+ return {
51
+ query: this.query,
52
+ args: this.arguments,
53
+ fetchType: this.fetchType
54
+ };
55
+ }
49
56
  };
50
57
  var QueryWithExtra = class extends Query {
51
58
  countQuery;
@@ -59,15 +66,20 @@ var QueryWithExtra = class extends Query {
59
66
  );
60
67
  }
61
68
  };
69
+ function trimQuery(query) {
70
+ return query.replace(/\s\s+/g, " ");
71
+ }
62
72
 
63
73
  // src/modularBuilder.ts
64
74
  var SelectBuilder = class _SelectBuilder {
65
75
  _debugger = false;
66
76
  _options = {};
67
- _queryBuilder;
68
- constructor(options, queryBuilder) {
77
+ _fetchAll;
78
+ _fetchOne;
79
+ constructor(options, fetchAll, fetchOne) {
69
80
  this._options = options;
70
- this._queryBuilder = queryBuilder;
81
+ this._fetchAll = fetchAll;
82
+ this._fetchOne = fetchOne;
71
83
  }
72
84
  setDebugger(state) {
73
85
  this._debugger = state;
@@ -78,7 +90,8 @@ var SelectBuilder = class _SelectBuilder {
78
90
  ...this._options,
79
91
  tableName
80
92
  },
81
- this._queryBuilder
93
+ this._fetchAll,
94
+ this._fetchOne
82
95
  );
83
96
  }
84
97
  fields(fields) {
@@ -106,7 +119,8 @@ var SelectBuilder = class _SelectBuilder {
106
119
  params
107
120
  }
108
121
  },
109
- this._queryBuilder
122
+ this._fetchAll,
123
+ this._fetchOne
110
124
  );
111
125
  }
112
126
  join(join) {
@@ -127,7 +141,8 @@ var SelectBuilder = class _SelectBuilder {
127
141
  ...this._options,
128
142
  offset
129
143
  },
130
- this._queryBuilder
144
+ this._fetchAll,
145
+ this._fetchOne
131
146
  );
132
147
  }
133
148
  limit(limit) {
@@ -136,7 +151,8 @@ var SelectBuilder = class _SelectBuilder {
136
151
  ...this._options,
137
152
  limit
138
153
  },
139
- this._queryBuilder
154
+ this._fetchAll,
155
+ this._fetchOne
140
156
  );
141
157
  }
142
158
  _parseArray(fieldName, option, value) {
@@ -154,25 +170,65 @@ var SelectBuilder = class _SelectBuilder {
154
170
  ...this._options,
155
171
  [fieldName]: val
156
172
  },
157
- this._queryBuilder
173
+ this._fetchAll,
174
+ this._fetchOne
158
175
  );
159
176
  }
160
- getQuery() {
161
- return this._queryBuilder(this._options);
177
+ getQueryAll() {
178
+ return this._fetchAll(this._options);
179
+ }
180
+ getQueryOne() {
181
+ return this._fetchOne(this._options);
162
182
  }
163
183
  async execute() {
164
- return this._queryBuilder(this._options).execute();
184
+ return this._fetchAll(this._options).execute();
185
+ }
186
+ async all() {
187
+ return this._fetchAll(this._options).execute();
188
+ }
189
+ async one() {
190
+ return this._fetchOne(this._options).execute();
165
191
  }
166
192
  async count() {
167
- return this._queryBuilder(this._options).count();
193
+ return this._fetchOne(this._options).count();
168
194
  }
169
195
  };
170
196
 
171
197
  // src/builder.ts
172
198
  var QueryBuilder = class {
173
- _debugger = false;
199
+ options;
200
+ constructor(options) {
201
+ this.options = options || {};
202
+ }
174
203
  setDebugger(state) {
175
- this._debugger = state;
204
+ if (state === true) {
205
+ if (this.options.logger) {
206
+ return;
207
+ }
208
+ this.options.logger = (query, meta) => {
209
+ console.log(`[workers-qb][${meta.duration}ms] ${JSON.stringify(query)}`);
210
+ };
211
+ } else {
212
+ this.options.logger = void 0;
213
+ }
214
+ }
215
+ async loggerWrapper(query, innerFunction) {
216
+ const start = Date.now();
217
+ try {
218
+ return await innerFunction();
219
+ } catch (e) {
220
+ throw e;
221
+ } finally {
222
+ if (this.options.logger) {
223
+ if (Array.isArray(query)) {
224
+ for (const q of query) {
225
+ await this.options.logger(q.toObject(), { duration: Date.now() - start });
226
+ }
227
+ } else {
228
+ await this.options.logger(query.toObject(), { duration: Date.now() - start });
229
+ }
230
+ }
231
+ }
176
232
  }
177
233
  async execute(query) {
178
234
  throw new Error("Execute method not implemented");
@@ -201,6 +257,9 @@ var QueryBuilder = class {
201
257
  },
202
258
  (params) => {
203
259
  return this.fetchAll(params);
260
+ },
261
+ (params) => {
262
+ return this.fetchOne(params);
204
263
  }
205
264
  );
206
265
  }
@@ -470,84 +529,74 @@ var QueryBuilder = class {
470
529
  // src/databases/d1.ts
471
530
  var D1QB = class extends QueryBuilder {
472
531
  db;
473
- constructor(db) {
474
- super();
532
+ constructor(db, options) {
533
+ super(options);
475
534
  this.db = db;
476
535
  }
477
536
  async execute(query) {
478
- let stmt = this.db.prepare(query.query);
479
- if (this._debugger) {
480
- console.log({
481
- "workers-qb": {
482
- query: query.query,
483
- arguments: query.arguments,
484
- fetchType: query.fetchType
485
- }
486
- });
487
- }
488
- if (query.arguments) {
489
- stmt = stmt.bind(...query.arguments);
490
- }
491
- if (query.fetchType === "ONE" /* ONE */ || query.fetchType === "ALL" /* ALL */) {
492
- const resp = await stmt.all();
493
- return {
494
- changes: resp.meta?.changes,
495
- duration: resp.meta?.duration,
496
- last_row_id: resp.meta?.last_row_id,
497
- served_by: resp.meta?.served_by,
498
- meta: resp.meta,
499
- success: resp.success,
500
- results: query.fetchType === "ONE" /* ONE */ ? resp.results[0] : resp.results
501
- };
502
- }
503
- return stmt.run();
504
- }
505
- async batchExecute(queryArray) {
506
- if (this._debugger) {
507
- console.log({
508
- "workers-qb": queryArray
509
- });
510
- }
511
- const statements = queryArray.map((query) => {
537
+ return await this.loggerWrapper(query, async () => {
512
538
  let stmt = this.db.prepare(query.query);
513
539
  if (query.arguments) {
514
540
  stmt = stmt.bind(...query.arguments);
515
541
  }
516
- return stmt;
542
+ if (query.fetchType === "ONE" /* ONE */ || query.fetchType === "ALL" /* ALL */) {
543
+ const resp = await stmt.all();
544
+ return {
545
+ changes: resp.meta?.changes,
546
+ duration: resp.meta?.duration,
547
+ last_row_id: resp.meta?.last_row_id,
548
+ served_by: resp.meta?.served_by,
549
+ meta: resp.meta,
550
+ success: resp.success,
551
+ results: query.fetchType === "ONE" /* ONE */ ? resp.results[0] : resp.results
552
+ };
553
+ }
554
+ return stmt.run();
517
555
  });
518
- const responses = await this.db.batch(statements);
519
- return responses.map(
520
- (resp, i) => {
521
- if (queryArray && queryArray[i] !== void 0 && queryArray[i]?.fetchType) {
522
- return {
523
- changes: resp.meta?.changes,
524
- duration: resp.meta?.duration,
525
- last_row_id: resp.meta?.last_row_id,
526
- served_by: resp.meta?.served_by,
527
- meta: resp.meta,
528
- success: resp.success,
529
- results: queryArray[i]?.fetchType === "ONE" /* ONE */ ? resp.results?.[0] : resp.results
530
- };
531
- } else {
532
- return {
533
- changes: resp.meta?.changes,
534
- duration: resp.meta?.duration,
535
- last_row_id: resp.meta?.last_row_id,
536
- served_by: resp.meta?.served_by,
537
- meta: resp.meta,
538
- success: resp.success
539
- };
556
+ }
557
+ async batchExecute(queryArray) {
558
+ return await this.loggerWrapper(queryArray, async () => {
559
+ const statements = queryArray.map((query) => {
560
+ let stmt = this.db.prepare(query.query);
561
+ if (query.arguments) {
562
+ stmt = stmt.bind(...query.arguments);
540
563
  }
541
- }
542
- );
564
+ return stmt;
565
+ });
566
+ const responses = await this.db.batch(statements);
567
+ return responses.map(
568
+ (resp, i) => {
569
+ if (queryArray && queryArray[i] !== void 0 && queryArray[i]?.fetchType) {
570
+ return {
571
+ changes: resp.meta?.changes,
572
+ duration: resp.meta?.duration,
573
+ last_row_id: resp.meta?.last_row_id,
574
+ served_by: resp.meta?.served_by,
575
+ meta: resp.meta,
576
+ success: resp.success,
577
+ results: queryArray[i]?.fetchType === "ONE" /* ONE */ ? resp.results?.[0] : resp.results
578
+ };
579
+ } else {
580
+ return {
581
+ changes: resp.meta?.changes,
582
+ duration: resp.meta?.duration,
583
+ last_row_id: resp.meta?.last_row_id,
584
+ served_by: resp.meta?.served_by,
585
+ meta: resp.meta,
586
+ success: resp.success
587
+ };
588
+ }
589
+ }
590
+ );
591
+ });
543
592
  }
544
593
  };
545
594
 
546
595
  // src/databases/pg.ts
547
596
  var PGQB = class extends QueryBuilder {
548
597
  db;
549
- constructor(db) {
550
- super();
598
+ constructor(db, options) {
599
+ super(options);
551
600
  this.db = db;
552
601
  }
553
602
  async connect() {
@@ -557,86 +606,73 @@ var PGQB = class extends QueryBuilder {
557
606
  await this.db.end();
558
607
  }
559
608
  async execute(query) {
560
- const queryString = query.query.replaceAll("?", "$");
561
- if (this._debugger) {
562
- console.log({
563
- "workers-qb": query
564
- });
565
- }
566
- let result;
567
- if (query.arguments) {
568
- result = await this.db.query({
569
- values: query.arguments,
570
- text: queryString
571
- });
572
- } else {
573
- result = await this.db.query({
574
- text: queryString
575
- });
576
- }
577
- if (query.fetchType === "ONE" /* ONE */ || query.fetchType === "ALL" /* ALL */) {
609
+ return await this.loggerWrapper(query, async () => {
610
+ const queryString = query.query.replaceAll("?", "$");
611
+ let result;
612
+ if (query.arguments) {
613
+ result = await this.db.query({
614
+ values: query.arguments,
615
+ text: queryString
616
+ });
617
+ } else {
618
+ result = await this.db.query({
619
+ text: queryString
620
+ });
621
+ }
622
+ if (query.fetchType === "ONE" /* ONE */ || query.fetchType === "ALL" /* ALL */) {
623
+ return {
624
+ command: result.command,
625
+ lastRowId: result.oid,
626
+ rowCount: result.rowCount,
627
+ results: query.fetchType === "ONE" /* ONE */ ? result.rows[0] : result.rows
628
+ };
629
+ }
578
630
  return {
579
631
  command: result.command,
580
632
  lastRowId: result.oid,
581
- rowCount: result.rowCount,
582
- results: query.fetchType === "ONE" /* ONE */ ? result.rows[0] : result.rows
633
+ rowCount: result.rowCount
583
634
  };
584
- }
585
- return {
586
- command: result.command,
587
- lastRowId: result.oid,
588
- rowCount: result.rowCount
589
- };
635
+ });
590
636
  }
591
637
  };
592
638
 
593
639
  // src/databases/do.ts
594
640
  var DOQB = class extends QueryBuilder {
595
641
  db;
596
- constructor(db) {
597
- super();
642
+ constructor(db, options) {
643
+ super(options);
598
644
  this.db = db;
599
645
  }
600
646
  async execute(query) {
601
- if (this._debugger) {
602
- console.log({
603
- "workers-qb": {
604
- query: query.query,
605
- arguments: query.arguments,
606
- fetchType: query.fetchType
647
+ return await this.loggerWrapper(query, async () => {
648
+ if (query.arguments) {
649
+ let stmt = this.db.prepare(query.query);
650
+ const result = stmt(...query.arguments);
651
+ if (query.fetchType == "ONE" /* ONE */) {
652
+ return {
653
+ results: Array.from(result)[0]
654
+ };
607
655
  }
608
- });
609
- }
610
- if (query.arguments) {
611
- let stmt = this.db.prepare(query.query);
612
- const result = stmt(...query.arguments);
656
+ return {
657
+ results: Array.from(result)
658
+ };
659
+ }
660
+ const cursor = this.db.exec(query.query);
613
661
  if (query.fetchType == "ONE" /* ONE */) {
614
662
  return {
615
- results: Array.from(result)[0]
663
+ results: Array.from(cursor)[0]
616
664
  };
617
665
  }
618
666
  return {
619
- results: Array.from(result)
620
- };
621
- }
622
- const cursor = this.db.exec(query.query);
623
- if (query.fetchType == "ONE" /* ONE */) {
624
- return {
625
- results: Array.from(cursor)[0]
667
+ results: Array.from(cursor)
626
668
  };
627
- }
628
- return {
629
- results: Array.from(cursor)
630
- };
669
+ });
631
670
  }
632
671
  };
633
- var DurableObjectDatabaseQB = class extends DOQB {
634
- };
635
672
  export {
636
673
  ConflictTypes,
637
674
  D1QB,
638
675
  DOQB,
639
- DurableObjectDatabaseQB,
640
676
  FetchTypes,
641
677
  JoinTypes,
642
678
  OrderTypes,
@@ -644,5 +680,6 @@ export {
644
680
  Query,
645
681
  QueryBuilder,
646
682
  QueryWithExtra,
647
- Raw
683
+ Raw,
684
+ trimQuery
648
685
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "workers-qb",
3
- "version": "1.4.3",
3
+ "version": "1.5.1",
4
4
  "description": "Zero dependencies Query Builder for Cloudflare Workers",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",