workers-qb 1.6.7 → 1.8.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/README.md CHANGED
@@ -19,12 +19,13 @@ Currently, 3 databases are supported:
19
19
 
20
20
  ## Features
21
21
 
22
- - [x] Zero dependencies.
22
+ - [x] Zero dependencies
23
23
  - [x] Fully typed/TypeScript support
24
+ - [x] [Migrations](https://workers-qb.massadas.com/migrations/)
24
25
  - [x] [Type Checks for data read](https://workers-qb.massadas.com/type-check/)
25
26
  - [x] [Create/drop tables](https://workers-qb.massadas.com/basic-queries/#dropping-and-creating-tables)
26
27
  - [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/)
28
+ - [x] [Modular selects](https://workers-qb.massadas.com/modular-selects/) (qb.select(...).where(...).where(...).one())
28
29
  - [x] [On Conflict for Inserts and Updates](https://workers-qb.massadas.com/advanced-queries/onConflict/)
29
30
  - [x] [Upsert](https://workers-qb.massadas.com/advanced-queries/upsert/)
30
31
 
@@ -40,7 +41,7 @@ npm install workers-qb --save
40
41
  import { D1QB } from 'workers-qb'
41
42
 
42
43
  export interface Env {
43
- DB: any
44
+ DB: D1Database
44
45
  }
45
46
 
46
47
  export default {
@@ -65,7 +66,7 @@ export default {
65
66
  .execute()
66
67
 
67
68
  // Or in a modular approach
68
- const employeeList = await qb.select<Employee>('employees').where('active = ?', true).execute()
69
+ const employeeListModular = await qb.select<Employee>('employees').where('active = ?', true).execute()
69
70
 
70
71
  // You get IDE type hints on each employee data, like:
71
72
  // employeeList.results[0].name
@@ -77,6 +78,26 @@ export default {
77
78
  }
78
79
  ```
79
80
 
81
+ ## Example for Cloudflare Durable Objects
82
+
83
+ ```ts
84
+ import { DOQB } from 'workers-qb'
85
+
86
+ export class DOSRS extends DurableObject {
87
+ getEmployees() {
88
+ const qb = new DOQB(this.ctx.storage.sql)
89
+
90
+ const fetched = qb
91
+ .fetchAll({
92
+ tableName: 'employees',
93
+ })
94
+ .execute()
95
+
96
+ return fetched.results
97
+ }
98
+ }
99
+ ```
100
+
80
101
  ## Example for Cloudflare Workers with PostgreSQL
81
102
 
82
103
  Remember to close the connection using `ctx.waitUntil(qb.close());` or `await qb.close();` at the end of your request.
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>;
@@ -188,6 +192,7 @@ declare class SelectBuilder<GenericResultWrapper, GenericResult = DefaultReturnO
188
192
  tableName(tableName: SelectAll['tableName']): SelectBuilder<GenericResultWrapper, GenericResult, IsAsync>;
189
193
  fields(fields: SelectAll['fields']): SelectBuilder<GenericResultWrapper, GenericResult, IsAsync>;
190
194
  where(conditions: string | Array<string>, params?: Primitive | Primitive[]): SelectBuilder<GenericResultWrapper, GenericResult, IsAsync>;
195
+ whereIn<T extends string | Array<string>, P extends T extends Array<string> ? Primitive[][] : Primitive[]>(fields: T, values: P): SelectBuilder<GenericResultWrapper, GenericResult, IsAsync>;
191
196
  join(join: SelectAll['join']): SelectBuilder<GenericResultWrapper, GenericResult, IsAsync>;
192
197
  groupBy(groupBy: SelectAll['groupBy']): SelectBuilder<GenericResultWrapper, GenericResult, IsAsync>;
193
198
  having(having: SelectAll['having']): SelectBuilder<GenericResultWrapper, GenericResult, IsAsync>;
@@ -203,10 +208,6 @@ declare class SelectBuilder<GenericResultWrapper, GenericResult = DefaultReturnO
203
208
  count(): MaybeAsync<IsAsync, CountResult<GenericResultWrapper>>;
204
209
  }
205
210
 
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
211
  declare class QueryBuilder<GenericResultWrapper, IsAsync extends boolean = true> {
211
212
  protected options: QueryBuilderOptions<IsAsync>;
212
213
  loggerWrapper: typeof asyncLoggerWrapper;
@@ -253,16 +254,53 @@ declare class QueryBuilder<GenericResultWrapper, IsAsync extends boolean = true>
253
254
  protected _returning(value?: string | Array<string>): string;
254
255
  }
255
256
 
257
+ type MigrationEntry = {
258
+ id: number;
259
+ name: string;
260
+ applied_at: Date;
261
+ };
262
+ type Migration = {
263
+ name: string;
264
+ sql: string;
265
+ };
266
+ type MigrationOptions = {
267
+ migrations: Array<Migration>;
268
+ tableName?: string;
269
+ };
270
+ declare class syncMigrationsBuilder<GenericResultWrapper> {
271
+ _builder: QueryBuilder<GenericResultWrapper, false>;
272
+ _migrations: Array<Migration>;
273
+ _tableName: string;
274
+ constructor(options: MigrationOptions, builder: QueryBuilder<GenericResultWrapper, false>);
275
+ initialize(): void;
276
+ getApplied(): Array<MigrationEntry>;
277
+ getUnapplied(): Array<Migration>;
278
+ apply(): Array<Migration>;
279
+ }
280
+ declare class asyncMigrationsBuilder<GenericResultWrapper> {
281
+ _builder: QueryBuilder<GenericResultWrapper, true>;
282
+ _migrations: Array<Migration>;
283
+ _tableName: string;
284
+ constructor(options: MigrationOptions, builder: QueryBuilder<GenericResultWrapper, true>);
285
+ initialize(): Promise<void>;
286
+ getApplied(): Promise<Array<MigrationEntry>>;
287
+ getUnapplied(): Promise<Array<Migration>>;
288
+ apply(): Promise<Array<Migration>>;
289
+ }
290
+
256
291
  declare class D1QB extends QueryBuilder<D1Result> {
257
292
  db: any;
258
293
  constructor(db: any, options?: QueryBuilderOptions);
294
+ migrations(options: MigrationOptions): asyncMigrationsBuilder<D1Result>;
259
295
  execute(query: Query): Promise<any>;
260
296
  batchExecute(queryArray: Query[]): Promise<any>;
261
297
  }
262
298
 
263
299
  declare class PGQB extends QueryBuilder<PGResult> {
264
300
  db: any;
301
+ _migrationsBuilder: typeof asyncMigrationsBuilder;
265
302
  constructor(db: any, options?: QueryBuilderOptions);
303
+ migrations(options: MigrationOptions): asyncMigrationsBuilder<PGResult>;
266
304
  connect(): Promise<void>;
267
305
  close(): Promise<void>;
268
306
  execute(query: Query): Promise<any>;
@@ -272,7 +310,8 @@ declare class DOQB extends QueryBuilder<{}, false> {
272
310
  db: any;
273
311
  loggerWrapper: typeof syncLoggerWrapper;
274
312
  constructor(db: any, options?: QueryBuilderOptions<false>);
313
+ migrations(options: MigrationOptions): syncMigrationsBuilder<{}>;
275
314
  execute(query: Query<any, false>): any;
276
315
  }
277
316
 
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 };
317
+ 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>;
@@ -188,6 +192,7 @@ declare class SelectBuilder<GenericResultWrapper, GenericResult = DefaultReturnO
188
192
  tableName(tableName: SelectAll['tableName']): SelectBuilder<GenericResultWrapper, GenericResult, IsAsync>;
189
193
  fields(fields: SelectAll['fields']): SelectBuilder<GenericResultWrapper, GenericResult, IsAsync>;
190
194
  where(conditions: string | Array<string>, params?: Primitive | Primitive[]): SelectBuilder<GenericResultWrapper, GenericResult, IsAsync>;
195
+ whereIn<T extends string | Array<string>, P extends T extends Array<string> ? Primitive[][] : Primitive[]>(fields: T, values: P): SelectBuilder<GenericResultWrapper, GenericResult, IsAsync>;
191
196
  join(join: SelectAll['join']): SelectBuilder<GenericResultWrapper, GenericResult, IsAsync>;
192
197
  groupBy(groupBy: SelectAll['groupBy']): SelectBuilder<GenericResultWrapper, GenericResult, IsAsync>;
193
198
  having(having: SelectAll['having']): SelectBuilder<GenericResultWrapper, GenericResult, IsAsync>;
@@ -203,10 +208,6 @@ declare class SelectBuilder<GenericResultWrapper, GenericResult = DefaultReturnO
203
208
  count(): MaybeAsync<IsAsync, CountResult<GenericResultWrapper>>;
204
209
  }
205
210
 
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
211
  declare class QueryBuilder<GenericResultWrapper, IsAsync extends boolean = true> {
211
212
  protected options: QueryBuilderOptions<IsAsync>;
212
213
  loggerWrapper: typeof asyncLoggerWrapper;
@@ -253,16 +254,53 @@ declare class QueryBuilder<GenericResultWrapper, IsAsync extends boolean = true>
253
254
  protected _returning(value?: string | Array<string>): string;
254
255
  }
255
256
 
257
+ type MigrationEntry = {
258
+ id: number;
259
+ name: string;
260
+ applied_at: Date;
261
+ };
262
+ type Migration = {
263
+ name: string;
264
+ sql: string;
265
+ };
266
+ type MigrationOptions = {
267
+ migrations: Array<Migration>;
268
+ tableName?: string;
269
+ };
270
+ declare class syncMigrationsBuilder<GenericResultWrapper> {
271
+ _builder: QueryBuilder<GenericResultWrapper, false>;
272
+ _migrations: Array<Migration>;
273
+ _tableName: string;
274
+ constructor(options: MigrationOptions, builder: QueryBuilder<GenericResultWrapper, false>);
275
+ initialize(): void;
276
+ getApplied(): Array<MigrationEntry>;
277
+ getUnapplied(): Array<Migration>;
278
+ apply(): Array<Migration>;
279
+ }
280
+ declare class asyncMigrationsBuilder<GenericResultWrapper> {
281
+ _builder: QueryBuilder<GenericResultWrapper, true>;
282
+ _migrations: Array<Migration>;
283
+ _tableName: string;
284
+ constructor(options: MigrationOptions, builder: QueryBuilder<GenericResultWrapper, true>);
285
+ initialize(): Promise<void>;
286
+ getApplied(): Promise<Array<MigrationEntry>>;
287
+ getUnapplied(): Promise<Array<Migration>>;
288
+ apply(): Promise<Array<Migration>>;
289
+ }
290
+
256
291
  declare class D1QB extends QueryBuilder<D1Result> {
257
292
  db: any;
258
293
  constructor(db: any, options?: QueryBuilderOptions);
294
+ migrations(options: MigrationOptions): asyncMigrationsBuilder<D1Result>;
259
295
  execute(query: Query): Promise<any>;
260
296
  batchExecute(queryArray: Query[]): Promise<any>;
261
297
  }
262
298
 
263
299
  declare class PGQB extends QueryBuilder<PGResult> {
264
300
  db: any;
301
+ _migrationsBuilder: typeof asyncMigrationsBuilder;
265
302
  constructor(db: any, options?: QueryBuilderOptions);
303
+ migrations(options: MigrationOptions): asyncMigrationsBuilder<PGResult>;
266
304
  connect(): Promise<void>;
267
305
  close(): Promise<void>;
268
306
  execute(query: Query): Promise<any>;
@@ -272,7 +310,8 @@ declare class DOQB extends QueryBuilder<{}, false> {
272
310
  db: any;
273
311
  loggerWrapper: typeof syncLoggerWrapper;
274
312
  constructor(db: any, options?: QueryBuilderOptions<false>);
313
+ migrations(options: MigrationOptions): syncMigrationsBuilder<{}>;
275
314
  execute(query: Query<any, false>): any;
276
315
  }
277
316
 
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 };
317
+ 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
@@ -163,6 +160,52 @@ var SelectBuilder = class _SelectBuilder {
163
160
  this._fetchOne
164
161
  );
165
162
  }
163
+ whereIn(fields, values) {
164
+ let whereInCondition;
165
+ let whereInParams;
166
+ const seperateWithComma = (prev, next) => prev + ", " + next;
167
+ if (values.length === 0) {
168
+ return new _SelectBuilder(
169
+ {
170
+ ...this._options
171
+ },
172
+ this._fetchAll,
173
+ this._fetchOne
174
+ );
175
+ }
176
+ if (!Array.isArray(fields)) {
177
+ whereInCondition = `(${fields}) IN (VALUES `;
178
+ whereInCondition += values.map(() => "(?)").reduce(seperateWithComma);
179
+ whereInCondition += ")";
180
+ whereInParams = values;
181
+ } else {
182
+ const fieldLength = fields.length;
183
+ whereInCondition = `(${fields.map((val) => val).reduce(seperateWithComma)}) IN (VALUES `;
184
+ const valuesString = `(${[...new Array(fieldLength).keys()].map(() => "?").reduce(seperateWithComma)})`;
185
+ whereInCondition += [...new Array(fieldLength).keys()].map(() => valuesString).reduce(seperateWithComma);
186
+ whereInCondition += ")";
187
+ whereInParams = values.flat();
188
+ }
189
+ let conditions = [whereInCondition];
190
+ let params = whereInParams;
191
+ if (this._options.where?.conditions) {
192
+ conditions = this._options.where?.conditions.concat(conditions);
193
+ }
194
+ if (this._options.where?.params) {
195
+ params = this._options.where?.params.concat(params);
196
+ }
197
+ return new _SelectBuilder(
198
+ {
199
+ ...this._options,
200
+ where: {
201
+ conditions,
202
+ params
203
+ }
204
+ },
205
+ this._fetchAll,
206
+ this._fetchOne
207
+ );
208
+ }
166
209
  join(join) {
167
210
  return this._parseArray("join", this._options.join, join);
168
211
  }
@@ -234,45 +277,50 @@ var SelectBuilder = class _SelectBuilder {
234
277
  }
235
278
  };
236
279
 
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
- }
280
+ // src/tools.ts
281
+ var Raw = class {
282
+ isRaw = true;
283
+ content;
284
+ constructor(content) {
285
+ this.content = content;
257
286
  }
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
- }
287
+ };
288
+ var Query = class {
289
+ executeMethod;
290
+ query;
291
+ arguments;
292
+ fetchType;
293
+ constructor(executeMethod, query, args, fetchType) {
294
+ this.executeMethod = executeMethod;
295
+ this.query = trimQuery(query);
296
+ this.arguments = args;
297
+ this.fetchType = fetchType;
298
+ }
299
+ execute() {
300
+ return this.executeMethod(this);
301
+ }
302
+ toObject() {
303
+ return {
304
+ query: this.query,
305
+ args: this.arguments,
306
+ fetchType: this.fetchType
307
+ };
308
+ }
309
+ };
310
+ var QueryWithExtra = class extends Query {
311
+ countQuery;
312
+ constructor(executeMethod, query, countQuery, args, fetchType) {
313
+ super(executeMethod, query, args, fetchType);
314
+ this.countQuery = countQuery;
315
+ }
316
+ count() {
317
+ return this.executeMethod(
318
+ new Query(this.executeMethod, this.countQuery, this.arguments, "ONE" /* ONE */)
319
+ );
275
320
  }
321
+ };
322
+ function trimQuery(query) {
323
+ return query.replace(/\s\s+/g, " ");
276
324
  }
277
325
 
278
326
  // src/builder.ts
@@ -308,9 +356,12 @@ var QueryBuilder = class {
308
356
  );
309
357
  }
310
358
  dropTable(params) {
311
- return new Query((q) => {
312
- return this.execute(q);
313
- }, `DROP TABLE ${params.ifExists ? "IF EXISTS" : ""} ${params.tableName}`);
359
+ return new Query(
360
+ (q) => {
361
+ return this.execute(q);
362
+ },
363
+ `DROP TABLE ${params.ifExists ? "IF EXISTS" : ""} ${params.tableName}`
364
+ );
314
365
  }
315
366
  select(tableName) {
316
367
  return new SelectBuilder(
@@ -593,6 +644,114 @@ var QueryBuilder = class {
593
644
  }
594
645
  };
595
646
 
647
+ // src/migrations.ts
648
+ var syncMigrationsBuilder = class {
649
+ _builder;
650
+ _migrations;
651
+ _tableName;
652
+ constructor(options, builder) {
653
+ this._tableName = options.tableName || "migrations";
654
+ this._migrations = options.migrations;
655
+ this._builder = builder;
656
+ }
657
+ initialize() {
658
+ this._builder.createTable({
659
+ tableName: this._tableName,
660
+ schema: `id INTEGER PRIMARY KEY AUTOINCREMENT,
661
+ name TEXT UNIQUE,
662
+ applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL`,
663
+ ifNotExists: true
664
+ }).execute();
665
+ return;
666
+ }
667
+ getApplied() {
668
+ this.initialize();
669
+ const result = this._builder.fetchAll({
670
+ tableName: this._tableName,
671
+ orderBy: "id"
672
+ }).execute();
673
+ return result.results || [];
674
+ }
675
+ getUnapplied() {
676
+ const appliedMigrations = this.getApplied().map((migration) => {
677
+ return migration.name;
678
+ });
679
+ const unappliedMigrations = [];
680
+ for (const migration of this._migrations) {
681
+ if (!appliedMigrations.includes(migration.name)) {
682
+ unappliedMigrations.push(migration);
683
+ }
684
+ }
685
+ return unappliedMigrations;
686
+ }
687
+ apply() {
688
+ const appliedMigrations = [];
689
+ for (const migration of this.getUnapplied()) {
690
+ this._builder.raw({
691
+ query: `
692
+ ${migration.sql}
693
+ INSERT INTO ${this._tableName} (name)
694
+ values ('${migration.name}');`
695
+ }).execute();
696
+ appliedMigrations.push(migration);
697
+ }
698
+ return appliedMigrations;
699
+ }
700
+ };
701
+ var asyncMigrationsBuilder = class {
702
+ _builder;
703
+ _migrations;
704
+ _tableName;
705
+ constructor(options, builder) {
706
+ this._tableName = options.tableName || "migrations";
707
+ this._migrations = options.migrations;
708
+ this._builder = builder;
709
+ }
710
+ async initialize() {
711
+ await this._builder.createTable({
712
+ tableName: this._tableName,
713
+ schema: `id INTEGER PRIMARY KEY AUTOINCREMENT,
714
+ name TEXT UNIQUE,
715
+ applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL`,
716
+ ifNotExists: true
717
+ }).execute();
718
+ return;
719
+ }
720
+ async getApplied() {
721
+ await this.initialize();
722
+ const result = await this._builder.fetchAll({
723
+ tableName: this._tableName,
724
+ orderBy: "id"
725
+ }).execute();
726
+ return result.results || [];
727
+ }
728
+ async getUnapplied() {
729
+ const appliedMigrations = (await this.getApplied()).map((migration) => {
730
+ return migration.name;
731
+ });
732
+ const unappliedMigrations = [];
733
+ for (const migration of this._migrations) {
734
+ if (!appliedMigrations.includes(migration.name)) {
735
+ unappliedMigrations.push(migration);
736
+ }
737
+ }
738
+ return unappliedMigrations;
739
+ }
740
+ async apply() {
741
+ const appliedMigrations = [];
742
+ for (const migration of await this.getUnapplied()) {
743
+ await this._builder.raw({
744
+ query: `
745
+ ${migration.sql}
746
+ INSERT INTO ${this._tableName} (name)
747
+ values ('${migration.name}');`
748
+ }).execute();
749
+ appliedMigrations.push(migration);
750
+ }
751
+ return appliedMigrations;
752
+ }
753
+ };
754
+
596
755
  // src/databases/d1.ts
597
756
  var D1QB = class extends QueryBuilder {
598
757
  db;
@@ -600,6 +759,9 @@ var D1QB = class extends QueryBuilder {
600
759
  super(options);
601
760
  this.db = db;
602
761
  }
762
+ migrations(options) {
763
+ return new asyncMigrationsBuilder(options, this);
764
+ }
603
765
  async execute(query) {
604
766
  return await this.loggerWrapper(query, this.options.logger, async () => {
605
767
  let stmt = this.db.prepare(query.query);
@@ -662,10 +824,14 @@ var D1QB = class extends QueryBuilder {
662
824
  // src/databases/pg.ts
663
825
  var PGQB = class extends QueryBuilder {
664
826
  db;
827
+ _migrationsBuilder = asyncMigrationsBuilder;
665
828
  constructor(db, options) {
666
829
  super(options);
667
830
  this.db = db;
668
831
  }
832
+ migrations(options) {
833
+ return new asyncMigrationsBuilder(options, this);
834
+ }
669
835
  async connect() {
670
836
  await this.db.connect();
671
837
  }
@@ -711,6 +877,9 @@ var DOQB = class extends QueryBuilder {
711
877
  super(options);
712
878
  this.db = db;
713
879
  }
880
+ migrations(options) {
881
+ return new syncMigrationsBuilder(options, this);
882
+ }
714
883
  execute(query) {
715
884
  return this.loggerWrapper(query, this.options.logger, () => {
716
885
  let cursor;
@@ -745,7 +914,9 @@ var DOQB = class extends QueryBuilder {
745
914
  QueryWithExtra,
746
915
  Raw,
747
916
  asyncLoggerWrapper,
917
+ asyncMigrationsBuilder,
748
918
  defaultLogger,
749
919
  syncLoggerWrapper,
920
+ syncMigrationsBuilder,
750
921
  trimQuery
751
922
  });
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
@@ -123,6 +118,52 @@ var SelectBuilder = class _SelectBuilder {
123
118
  this._fetchOne
124
119
  );
125
120
  }
121
+ whereIn(fields, values) {
122
+ let whereInCondition;
123
+ let whereInParams;
124
+ const seperateWithComma = (prev, next) => prev + ", " + next;
125
+ if (values.length === 0) {
126
+ return new _SelectBuilder(
127
+ {
128
+ ...this._options
129
+ },
130
+ this._fetchAll,
131
+ this._fetchOne
132
+ );
133
+ }
134
+ if (!Array.isArray(fields)) {
135
+ whereInCondition = `(${fields}) IN (VALUES `;
136
+ whereInCondition += values.map(() => "(?)").reduce(seperateWithComma);
137
+ whereInCondition += ")";
138
+ whereInParams = values;
139
+ } else {
140
+ const fieldLength = fields.length;
141
+ whereInCondition = `(${fields.map((val) => val).reduce(seperateWithComma)}) IN (VALUES `;
142
+ const valuesString = `(${[...new Array(fieldLength).keys()].map(() => "?").reduce(seperateWithComma)})`;
143
+ whereInCondition += [...new Array(fieldLength).keys()].map(() => valuesString).reduce(seperateWithComma);
144
+ whereInCondition += ")";
145
+ whereInParams = values.flat();
146
+ }
147
+ let conditions = [whereInCondition];
148
+ let params = whereInParams;
149
+ if (this._options.where?.conditions) {
150
+ conditions = this._options.where?.conditions.concat(conditions);
151
+ }
152
+ if (this._options.where?.params) {
153
+ params = this._options.where?.params.concat(params);
154
+ }
155
+ return new _SelectBuilder(
156
+ {
157
+ ...this._options,
158
+ where: {
159
+ conditions,
160
+ params
161
+ }
162
+ },
163
+ this._fetchAll,
164
+ this._fetchOne
165
+ );
166
+ }
126
167
  join(join) {
127
168
  return this._parseArray("join", this._options.join, join);
128
169
  }
@@ -194,45 +235,50 @@ var SelectBuilder = class _SelectBuilder {
194
235
  }
195
236
  };
196
237
 
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
- }
238
+ // src/tools.ts
239
+ var Raw = class {
240
+ isRaw = true;
241
+ content;
242
+ constructor(content) {
243
+ this.content = content;
217
244
  }
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
- }
245
+ };
246
+ var Query = class {
247
+ executeMethod;
248
+ query;
249
+ arguments;
250
+ fetchType;
251
+ constructor(executeMethod, query, args, fetchType) {
252
+ this.executeMethod = executeMethod;
253
+ this.query = trimQuery(query);
254
+ this.arguments = args;
255
+ this.fetchType = fetchType;
256
+ }
257
+ execute() {
258
+ return this.executeMethod(this);
259
+ }
260
+ toObject() {
261
+ return {
262
+ query: this.query,
263
+ args: this.arguments,
264
+ fetchType: this.fetchType
265
+ };
266
+ }
267
+ };
268
+ var QueryWithExtra = class extends Query {
269
+ countQuery;
270
+ constructor(executeMethod, query, countQuery, args, fetchType) {
271
+ super(executeMethod, query, args, fetchType);
272
+ this.countQuery = countQuery;
273
+ }
274
+ count() {
275
+ return this.executeMethod(
276
+ new Query(this.executeMethod, this.countQuery, this.arguments, "ONE" /* ONE */)
277
+ );
235
278
  }
279
+ };
280
+ function trimQuery(query) {
281
+ return query.replace(/\s\s+/g, " ");
236
282
  }
237
283
 
238
284
  // src/builder.ts
@@ -268,9 +314,12 @@ var QueryBuilder = class {
268
314
  );
269
315
  }
270
316
  dropTable(params) {
271
- return new Query((q) => {
272
- return this.execute(q);
273
- }, `DROP TABLE ${params.ifExists ? "IF EXISTS" : ""} ${params.tableName}`);
317
+ return new Query(
318
+ (q) => {
319
+ return this.execute(q);
320
+ },
321
+ `DROP TABLE ${params.ifExists ? "IF EXISTS" : ""} ${params.tableName}`
322
+ );
274
323
  }
275
324
  select(tableName) {
276
325
  return new SelectBuilder(
@@ -553,6 +602,114 @@ var QueryBuilder = class {
553
602
  }
554
603
  };
555
604
 
605
+ // src/migrations.ts
606
+ var syncMigrationsBuilder = class {
607
+ _builder;
608
+ _migrations;
609
+ _tableName;
610
+ constructor(options, builder) {
611
+ this._tableName = options.tableName || "migrations";
612
+ this._migrations = options.migrations;
613
+ this._builder = builder;
614
+ }
615
+ initialize() {
616
+ this._builder.createTable({
617
+ tableName: this._tableName,
618
+ schema: `id INTEGER PRIMARY KEY AUTOINCREMENT,
619
+ name TEXT UNIQUE,
620
+ applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL`,
621
+ ifNotExists: true
622
+ }).execute();
623
+ return;
624
+ }
625
+ getApplied() {
626
+ this.initialize();
627
+ const result = this._builder.fetchAll({
628
+ tableName: this._tableName,
629
+ orderBy: "id"
630
+ }).execute();
631
+ return result.results || [];
632
+ }
633
+ getUnapplied() {
634
+ const appliedMigrations = this.getApplied().map((migration) => {
635
+ return migration.name;
636
+ });
637
+ const unappliedMigrations = [];
638
+ for (const migration of this._migrations) {
639
+ if (!appliedMigrations.includes(migration.name)) {
640
+ unappliedMigrations.push(migration);
641
+ }
642
+ }
643
+ return unappliedMigrations;
644
+ }
645
+ apply() {
646
+ const appliedMigrations = [];
647
+ for (const migration of this.getUnapplied()) {
648
+ this._builder.raw({
649
+ query: `
650
+ ${migration.sql}
651
+ INSERT INTO ${this._tableName} (name)
652
+ values ('${migration.name}');`
653
+ }).execute();
654
+ appliedMigrations.push(migration);
655
+ }
656
+ return appliedMigrations;
657
+ }
658
+ };
659
+ var asyncMigrationsBuilder = class {
660
+ _builder;
661
+ _migrations;
662
+ _tableName;
663
+ constructor(options, builder) {
664
+ this._tableName = options.tableName || "migrations";
665
+ this._migrations = options.migrations;
666
+ this._builder = builder;
667
+ }
668
+ async initialize() {
669
+ await this._builder.createTable({
670
+ tableName: this._tableName,
671
+ schema: `id INTEGER PRIMARY KEY AUTOINCREMENT,
672
+ name TEXT UNIQUE,
673
+ applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL`,
674
+ ifNotExists: true
675
+ }).execute();
676
+ return;
677
+ }
678
+ async getApplied() {
679
+ await this.initialize();
680
+ const result = await this._builder.fetchAll({
681
+ tableName: this._tableName,
682
+ orderBy: "id"
683
+ }).execute();
684
+ return result.results || [];
685
+ }
686
+ async getUnapplied() {
687
+ const appliedMigrations = (await this.getApplied()).map((migration) => {
688
+ return migration.name;
689
+ });
690
+ const unappliedMigrations = [];
691
+ for (const migration of this._migrations) {
692
+ if (!appliedMigrations.includes(migration.name)) {
693
+ unappliedMigrations.push(migration);
694
+ }
695
+ }
696
+ return unappliedMigrations;
697
+ }
698
+ async apply() {
699
+ const appliedMigrations = [];
700
+ for (const migration of await this.getUnapplied()) {
701
+ await this._builder.raw({
702
+ query: `
703
+ ${migration.sql}
704
+ INSERT INTO ${this._tableName} (name)
705
+ values ('${migration.name}');`
706
+ }).execute();
707
+ appliedMigrations.push(migration);
708
+ }
709
+ return appliedMigrations;
710
+ }
711
+ };
712
+
556
713
  // src/databases/d1.ts
557
714
  var D1QB = class extends QueryBuilder {
558
715
  db;
@@ -560,6 +717,9 @@ var D1QB = class extends QueryBuilder {
560
717
  super(options);
561
718
  this.db = db;
562
719
  }
720
+ migrations(options) {
721
+ return new asyncMigrationsBuilder(options, this);
722
+ }
563
723
  async execute(query) {
564
724
  return await this.loggerWrapper(query, this.options.logger, async () => {
565
725
  let stmt = this.db.prepare(query.query);
@@ -622,10 +782,14 @@ var D1QB = class extends QueryBuilder {
622
782
  // src/databases/pg.ts
623
783
  var PGQB = class extends QueryBuilder {
624
784
  db;
785
+ _migrationsBuilder = asyncMigrationsBuilder;
625
786
  constructor(db, options) {
626
787
  super(options);
627
788
  this.db = db;
628
789
  }
790
+ migrations(options) {
791
+ return new asyncMigrationsBuilder(options, this);
792
+ }
629
793
  async connect() {
630
794
  await this.db.connect();
631
795
  }
@@ -671,6 +835,9 @@ var DOQB = class extends QueryBuilder {
671
835
  super(options);
672
836
  this.db = db;
673
837
  }
838
+ migrations(options) {
839
+ return new syncMigrationsBuilder(options, this);
840
+ }
674
841
  execute(query) {
675
842
  return this.loggerWrapper(query, this.options.logger, () => {
676
843
  let cursor;
@@ -704,7 +871,9 @@ export {
704
871
  QueryWithExtra,
705
872
  Raw,
706
873
  asyncLoggerWrapper,
874
+ asyncMigrationsBuilder,
707
875
  defaultLogger,
708
876
  syncLoggerWrapper,
877
+ syncMigrationsBuilder,
709
878
  trimQuery
710
879
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "workers-qb",
3
- "version": "1.6.7",
3
+ "version": "1.8.0",
4
4
  "description": "Zero dependencies Query Builder for Cloudflare Workers",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -12,11 +12,9 @@
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)",
19
- "prepare": "husky install"
15
+ "lint": "npx @biomejs/biome check src/ tests/ || (npx @biomejs/biome check --write src/ tests/; exit 1)",
16
+ "test": "vitest run --root tests",
17
+ "prepare": "husky"
20
18
  },
21
19
  "publishConfig": {
22
20
  "access": "public"
@@ -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.1.8",
66
+ "wrangler": "^3.86.0"
98
67
  }
99
68
  }