workers-qb 0.1.7 → 0.1.8

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
@@ -1,15 +1,19 @@
1
1
  # workers-qb
2
2
 
3
- Zero dependencies Query Builder for [Cloudflare D1](https://blog.cloudflare.com/introducing-d1/)
4
- [Workers](https://developers.cloudflare.com/workers/)
3
+ Zero dependencies Query Builder for [Cloudflare Workers](https://developers.cloudflare.com/workers/)
5
4
 
6
- This module provides a simple standardized interface while keeping the
7
- benefits and speed of using raw queries over a traditional ORM.
5
+ This module provides a simple standardized interface while keeping the benefits and speed of using raw queries over a
6
+ traditional ORM.
8
7
 
9
- `workers-qb` is not intended to provide ORM-like functionality, rather to make it easier to interact with the database from
10
- code for direct SQL access using convenient wrapper methods.
8
+ `workers-qb` is not intended to provide ORM-like functionality, rather to make it easier to interact with the database
9
+ from code for direct SQL access using convenient wrapper methods.
11
10
 
12
- Read the documentation [Here](https://workers-qb.massadas.com/)!
11
+ Currently, 2 databases are supported:
12
+
13
+ - [Cloudflare D1](https://developers.cloudflare.com/d1/)
14
+ - [PostgreSQL (using node-postgres)](https://developers.cloudflare.com/workers/databases/connect-to-postgres/)
15
+
16
+ Read the documentation [workers-qb.massadas.com](https://workers-qb.massadas.com/)!
13
17
 
14
18
  ## Features
15
19
 
@@ -21,30 +25,86 @@ Read the documentation [Here](https://workers-qb.massadas.com/)!
21
25
  - [x] Create/drop tables
22
26
  - [x] Keep where conditions simple in code
23
27
  - [x] Bulk insert
28
+ - [x] Workers D1 Support
29
+ - [x] Workers PostgreSQL Support
24
30
  - [ ] Named parameters (waiting for full support in D1)
25
31
 
26
32
  ## Installation
27
33
 
28
34
  ```
29
- npm install workers-qb
35
+ npm install workers-qb --save
30
36
  ```
31
37
 
32
- ## Basic Usage
38
+ ## Example Cloudflare D1 Usage
33
39
 
34
40
  ```ts
35
41
  import { D1QB } from 'workers-qb'
36
- const qb = new D1QB(env.DB)
37
42
 
38
- const fetched = await qb.fetchOne({
39
- tableName: 'employees',
40
- fields: 'count(*) as count',
41
- where: {
42
- conditions: 'active = ?1',
43
- params: [true],
43
+ export interface Env {
44
+ DB: any
45
+ }
46
+
47
+ export default {
48
+ async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
49
+ const qb = new D1QB(env.DB)
50
+
51
+ const fetched = await qb.fetchOne({
52
+ tableName: 'employees',
53
+ fields: 'count(*) as count',
54
+ where: {
55
+ conditions: 'active = ?1',
56
+ params: [true],
57
+ },
58
+ })
59
+
60
+ return Response.json({
61
+ activeEmployees: fetched.results?.count || 0,
62
+ })
44
63
  },
45
- })
64
+ }
65
+ ```
66
+
67
+ ## Example Cloudflare Workers with PostgreSQL Usage
68
+
69
+ Remember to close the connection using `ctx.waitUntil(qb.close());` or `await qb.close();` at the end of your request.
70
+ You may also reuse this connection to execute multiple queries, or share it between multiple requests if you are using
71
+ a connection pool in front of your PostgreSQL.
46
72
 
47
- console.log(`Company has ${fetched.results.count} active employees`)
73
+ You must also enable `node_compat = true` in your `wrangler.toml`
74
+
75
+ You need to install `node-postgres`:
76
+
77
+ ```bash
78
+ npm install pg --save
79
+ ```
80
+
81
+ ```ts
82
+ import { PGQB } from 'workers-qb'
83
+
84
+ export interface Env {
85
+ DB_URL: string
86
+ }
87
+
88
+ export default {
89
+ async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
90
+ const qb = new PGQB(env.DB_URL)
91
+ await qb.connect()
92
+
93
+ const fetched = await qb.fetchOne({
94
+ tableName: 'employees',
95
+ fields: 'count(*) as count',
96
+ where: {
97
+ conditions: 'active = ?1',
98
+ params: [true],
99
+ },
100
+ })
101
+
102
+ ctx.waitUntil(qb.close())
103
+ return Response.json({
104
+ activeEmployees: fetched.results?.count || 0,
105
+ })
106
+ },
107
+ }
48
108
  ```
49
109
 
50
110
  #### Fetching a single record
@@ -189,108 +249,3 @@ const dropped = await qb.dropTable({
189
249
  tableName: 'testTable',
190
250
  })
191
251
  ```
192
-
193
- ## Development
194
-
195
- ### Set up tools and environment
196
-
197
- You need to have [Node.js](https://nodejs.org/en/download/) installed. Node includes npm as its default package manager.
198
-
199
- Open the whole package folder with a good code editor, preferably [Visual Studio Code](https://code.visualstudio.com/download). Consider installing VS Code extensions [ES Lint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) and [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode).
200
-
201
- In the VS Code top menu: **Terminal** -> **New Terminal**
202
-
203
- ### Install dependencies
204
-
205
- Install dependencies with npm:
206
-
207
- ```bash
208
- npm i
209
- ```
210
-
211
- ### Write your code
212
-
213
- Write your code in **src** folder, and unit test in **test** folder.
214
-
215
- The VS Code shortcuts for formatting of a code file are: <kbd>Shift</kbd> + <kbd>Alt</kbd> + <kbd>F</kbd> (Windows); <kbd>Shift</kbd> + <kbd>Option (Alt)</kbd> + <kbd>F</kbd> (MacOS); <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>I</kbd> (Linux).
216
-
217
- ### Test
218
-
219
- Test your code with Jest framework:
220
-
221
- ```bash
222
- npm run test
223
- ```
224
-
225
- **Note:** This project uses [husky](https://typicode.github.io/husky/), [pinst](https://github.com/typicode/pinst) and [commitlint](https://commitlint.js.org/) to automatically execute test and [lint commit message](https://www.conventionalcommits.org/) before every commit.
226
-
227
- ### Build
228
-
229
- Build production (distribution) files in your **dist** folder:
230
-
231
- ```bash
232
- npm run build
233
- ```
234
-
235
- It generates CommonJS (in **dist/cjs** folder), ES Modules (in **dist/esm** folder), bundled and minified UMD (in **dist/umd** folder), as well as TypeScript declaration files (in **dist/types** folder).
236
-
237
- ### Try it before publishing
238
-
239
- Run:
240
-
241
- ```bash
242
- npm link
243
- ```
244
-
245
- [npm link](https://docs.npmjs.com/cli/v6/commands/npm-link) will create a symlink in the global folder, which may be **{prefix}/lib/node_modules/workers-qb** or **C:\Users\<username>\AppData\Roaming\npm\node_modules\workers-qb**.
246
-
247
- Create an empty folder elsewhere, you don't even need to `npm init` (to generate **package.json**). Open the folder with VS Code, open a terminal and just run:
248
-
249
- ```bash
250
- npm link workers-qb
251
- ```
252
-
253
- This will create a symbolic link from globally-installed workers-qb to **node_modules/** of the current folder.
254
-
255
- You can then create a, for example, **testsql.ts** file with the content:
256
-
257
- ```ts
258
- import { D1QB } from 'workers-qb'
259
- const qb = new D1QB(env.DB)
260
-
261
- console.log('Creating table...')
262
- const created = await qb.createTable({
263
- tableName: 'testTable',
264
- schema: `
265
- id INTEGER PRIMARY KEY AUTOINCREMENT,
266
- name TEXT NOT NULL
267
- `,
268
- ifNotExists: true,
269
- })
270
- console.log(created)
271
-
272
- console.log('Inserting rows...')
273
- const inserted = await qb.insert({
274
- tableName: 'testTable',
275
- data: {
276
- name: 'my name',
277
- },
278
- returning: '*',
279
- })
280
- console.log(inserted)
281
-
282
- console.log('Selecting rows...')
283
- const selected = await qb.fetchAll({
284
- tableName: 'testTable',
285
- fields: '*',
286
- })
287
- console.log(selected)
288
- ```
289
-
290
- If you don't see any linting errors in VS Code, if you put your mouse cursor over `D1QB` and see its type, then it's all good.
291
-
292
- Whenever you want to uninstall the globally-installed workers-qb and remove the symlink in the global folder, run:
293
-
294
- ```bash
295
- npm uninstall workers-qb -g
296
- ```
package/dist/Builder.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { Delete, Insert, Join, Result, ResultOne, SelectAll, SelectOne, Update } from './interfaces';
1
+ import { Delete, Insert, Join, SelectAll, SelectOne, Update } from './interfaces';
2
2
  import { ConflictTypes, FetchTypes, OrderTypes } from './enums';
3
3
  import { Raw } from './tools';
4
- export declare class QueryBuilder {
4
+ export declare class QueryBuilder<GenericResult, GenericResultOne> {
5
5
  execute(params: {
6
6
  query: string;
7
7
  arguments?: (string | number | boolean | null | Raw)[];
@@ -11,16 +11,16 @@ export declare class QueryBuilder {
11
11
  tableName: string;
12
12
  schema: string;
13
13
  ifNotExists?: boolean;
14
- }): Promise<Result>;
14
+ }): Promise<GenericResult>;
15
15
  dropTable(params: {
16
16
  tableName: string;
17
17
  ifExists?: boolean;
18
- }): Promise<Result>;
19
- fetchOne(params: SelectOne): Promise<ResultOne>;
20
- fetchAll(params: SelectAll): Promise<Result>;
21
- insert(params: Insert): Promise<Result>;
22
- update(params: Update): Promise<Result>;
23
- delete(params: Delete): Promise<Result>;
18
+ }): Promise<GenericResult>;
19
+ fetchOne(params: SelectOne): Promise<GenericResultOne>;
20
+ fetchAll(params: SelectAll): Promise<GenericResult>;
21
+ insert(params: Insert): Promise<GenericResult>;
22
+ update(params: Update): Promise<GenericResult>;
23
+ delete(params: Delete): Promise<GenericResult>;
24
24
  _parse_arguments(row: Record<string, string | boolean | number | null | Raw>): Array<any>;
25
25
  _onConflict(resolution?: string | ConflictTypes): string;
26
26
  _insert(params: Insert): string;
@@ -0,0 +1,13 @@
1
+ import { QueryBuilder } from '../Builder';
2
+ import { FetchTypes } from '../enums';
3
+ import { Raw } from '../tools';
4
+ import { D1Result, D1ResultOne } from '../interfaces';
5
+ export declare class D1QB extends QueryBuilder<D1Result, D1ResultOne> {
6
+ private db;
7
+ constructor(db: any);
8
+ execute(params: {
9
+ query: string;
10
+ arguments?: (string | number | boolean | null | Raw)[];
11
+ fetchType?: FetchTypes;
12
+ }): Promise<any>;
13
+ }
@@ -0,0 +1,16 @@
1
+ import { QueryBuilder } from '../Builder';
2
+ import { FetchTypes } from '../enums';
3
+ import { Raw } from '../tools';
4
+ import { PGResult, PGResultOne } from '../interfaces';
5
+ export declare class PGQB extends QueryBuilder<PGResult, PGResultOne> {
6
+ private dbUrl;
7
+ private client;
8
+ constructor(dbUrl: string);
9
+ connect(): Promise<void>;
10
+ close(): Promise<void>;
11
+ execute(params: {
12
+ query: String;
13
+ arguments?: (string | number | boolean | null | Raw)[];
14
+ fetchType?: FetchTypes;
15
+ }): Promise<any>;
16
+ }
@@ -40,19 +40,31 @@ export interface Delete {
40
40
  where: Where;
41
41
  returning?: string | Array<string>;
42
42
  }
43
- export interface Result {
43
+ export interface D1Result {
44
44
  changes?: number;
45
45
  duration: number;
46
- lastRowId?: number;
46
+ lastRowId?: string | number;
47
47
  results?: Array<Record<string, string | boolean | number | null>>;
48
48
  served_by: string;
49
49
  success: boolean;
50
50
  }
51
- export interface ResultOne {
51
+ export interface D1ResultOne {
52
52
  changes?: number;
53
53
  duration: number;
54
- lastRowId?: number;
54
+ lastRowId?: string | number;
55
55
  results?: Record<string, string | boolean | number | null>;
56
56
  served_by: string;
57
57
  success: boolean;
58
58
  }
59
+ export interface PGResult {
60
+ command: string;
61
+ lastRowId?: string | number;
62
+ rowCount: number;
63
+ results?: Array<Record<string, string | boolean | number | null>>;
64
+ }
65
+ export interface PGResultOne {
66
+ command: string;
67
+ lastRowId?: string | number;
68
+ rowCount: number;
69
+ results?: Record<string, string | boolean | number | null>;
70
+ }
@@ -1,5 +1,6 @@
1
1
  export * from './Builder';
2
- export * from './Databases';
2
+ export * from './databases/d1';
3
+ export * from './databases/pg';
3
4
  export * from './enums';
4
5
  export * from './interfaces';
5
6
  export * from './tools';
@@ -1 +1 @@
1
- "use strict";var e,t,r,s;exports.OrderTypes=void 0,(e=exports.OrderTypes||(exports.OrderTypes={})).ASC="ASC",e.DESC="DESC",exports.FetchTypes=void 0,(t=exports.FetchTypes||(exports.FetchTypes={})).ONE="ONE",t.ALL="ALL",exports.ConflictTypes=void 0,(r=exports.ConflictTypes||(exports.ConflictTypes={})).ROLLBACK="ROLLBACK",r.ABORT="ABORT",r.FAIL="FAIL",r.IGNORE="IGNORE",r.REPLACE="REPLACE",exports.JoinTypes=void 0,(s=exports.JoinTypes||(exports.JoinTypes={})).INNER="INNER",s.LEFT="LEFT",s.CROSS="CROSS";class n{isRaw=!0;content;constructor(e){this.content=e}}class i{async execute(e){throw new Error("Execute method not implemented")}async createTable(e){return this.execute({query:`CREATE TABLE ${e.ifNotExists?"IF NOT EXISTS":""} ${e.tableName}\n (\n ${e.schema}\n )`})}async dropTable(e){return this.execute({query:`DROP TABLE ${e.ifExists?"IF EXISTS":""} ${e.tableName}`})}async fetchOne(e){const t=await this.execute({query:this._select({...e,limit:1}),arguments:e.where?e.where.params:void 0,fetchType:exports.FetchTypes.ALL});return{...t,results:t.results[0]}}async fetchAll(e){return this.execute({query:this._select(e),arguments:e.where?e.where.params:void 0,fetchType:exports.FetchTypes.ALL})}async insert(e){let t=[];if(Array.isArray(e.data))for(const r of e.data)t=t.concat(this._parse_arguments(r));else t=t.concat(this._parse_arguments(e.data));return this.execute({query:this._insert(e),arguments:t,fetchType:exports.FetchTypes.ALL})}async update(e){let t=this._parse_arguments(e.data);return e.where&&e.where.params&&(t=e.where.params.concat(t)),this.execute({query:this._update(e),arguments:t,fetchType:exports.FetchTypes.ALL})}async delete(e){return this.execute({query:this._delete(e),arguments:e.where?e.where.params:void 0,fetchType:exports.FetchTypes.ALL})}_parse_arguments(e){return Object.values(e).map((e=>e instanceof n?e.content:e))}_onConflict(e){return e?`OR ${e} `:""}_insert(e){const t=[];Array.isArray(e.data)||(e.data=[e.data]);const r=Object.keys(e.data[0]).join(", ");let s=1;for(const r of e.data){const e=[];Object.entries(r).forEach((([t,r])=>{r instanceof n?e.push(r.content):e.push(`?${s}`),s+=1})),t.push(`(${e.join(", ")})`)}return`INSERT ${this._onConflict(e.onConflict)}INTO ${e.tableName} (${r}) VALUES ${t.join(", ")}`+this._returning(e.returning)}_update(e){const t=e.where&&e.where.params?Object.keys(e.where.params).length:0,r=[];return Object.entries(e.data).forEach((([e,s],i)=>{s instanceof n?r.push(`${e} = ${s.content}`):r.push(`${e} = ?${t+i+1}`)})),`UPDATE ${this._onConflict(e.onConflict)}${e.tableName} SET ${r.join(", ")}`+this._where(e.where?.conditions)+this._returning(e.returning)}_delete(e){return`DELETE FROM ${e.tableName}`+this._where(e.where?.conditions)+this._returning(e.returning)}_select(e){return`SELECT ${this._fields(e.fields)} FROM ${e.tableName}`+this._join(e.join)+this._where(e.where?.conditions)+this._groupBy(e.groupBy)+this._having(e.having)+this._orderBy(e.orderBy)+this._limit(e.limit)+this._offset(e.offset)}_fields(e){return"string"==typeof e?e:e.join(", ")}_where(e){return e?"string"==typeof e?` WHERE ${e}`:` WHERE ${e.join(" AND ")}`:""}_join(e){if(!e)return"";Array.isArray(e)||(e=[e]);const t=[];return e.forEach((e=>{const r=e.type?`${e.type} `:"";t.push(`${r}JOIN ${e.table} ON ${e.on}`)}))," "+t.join(" ")}_groupBy(e){return e?"string"==typeof e?` GROUP BY ${e}`:` GROUP BY ${e.join(", ")}`:""}_having(e){return e?` HAVING ${e}`:""}_orderBy(e){if(!e)return"";if("string"==typeof e)return` ORDER BY ${e}`;if(Array.isArray(e))return` ORDER BY ${e.join(", ")}`;const t=[];return Object.entries(e).forEach((([e,r])=>{t.push(`${e} ${r}`)})),` ORDER BY ${t.join(", ")}`}_limit(e){return e?` LIMIT ${e}`:""}_offset(e){return e?` OFFSET ${e}`:""}_returning(e){return e?"string"==typeof e?` RETURNING ${e}`:` RETURNING ${e.join(", ")}`:""}}exports.D1QB=class extends i{db;constructor(e){super(),this.db=e}async execute(e){let t=this.db.prepare(e.query);if(e.arguments){const r=e.arguments.map((e=>e instanceof n?e.content:e));t=t.bind(...r)}return e.fetchType===exports.FetchTypes.ONE?t.first():e.fetchType===exports.FetchTypes.ALL?t.all():t.run()}},exports.QueryBuilder=i,exports.Raw=n;
1
+ "use strict";var e,t,r,s;exports.OrderTypes=void 0,(e=exports.OrderTypes||(exports.OrderTypes={})).ASC="ASC",e.DESC="DESC",exports.FetchTypes=void 0,(t=exports.FetchTypes||(exports.FetchTypes={})).ONE="ONE",t.ALL="ALL",exports.ConflictTypes=void 0,(r=exports.ConflictTypes||(exports.ConflictTypes={})).ROLLBACK="ROLLBACK",r.ABORT="ABORT",r.FAIL="FAIL",r.IGNORE="IGNORE",r.REPLACE="REPLACE",exports.JoinTypes=void 0,(s=exports.JoinTypes||(exports.JoinTypes={})).INNER="INNER",s.LEFT="LEFT",s.CROSS="CROSS";class n{isRaw=!0;content;constructor(e){this.content=e}}class i{async execute(e){throw new Error("Execute method not implemented")}async createTable(e){return this.execute({query:`CREATE TABLE ${e.ifNotExists?"IF NOT EXISTS":""} ${e.tableName}\n (\n ${e.schema}\n )`})}async dropTable(e){return this.execute({query:`DROP TABLE ${e.ifExists?"IF EXISTS":""} ${e.tableName}`})}async fetchOne(e){const t=await this.execute({query:this._select({...e,limit:1}),arguments:e.where?e.where.params:void 0,fetchType:exports.FetchTypes.ALL});return{...t,results:t.results.length>0?t.results[0]:null}}async fetchAll(e){return this.execute({query:this._select(e),arguments:e.where?e.where.params:void 0,fetchType:exports.FetchTypes.ALL})}async insert(e){let t=[];if(Array.isArray(e.data))for(const r of e.data)t=t.concat(this._parse_arguments(r));else t=t.concat(this._parse_arguments(e.data));return this.execute({query:this._insert(e),arguments:t,fetchType:exports.FetchTypes.ALL})}async update(e){let t=this._parse_arguments(e.data);return e.where&&e.where.params&&(t=e.where.params.concat(t)),this.execute({query:this._update(e),arguments:t,fetchType:exports.FetchTypes.ALL})}async delete(e){return this.execute({query:this._delete(e),arguments:e.where?e.where.params:void 0,fetchType:exports.FetchTypes.ALL})}_parse_arguments(e){return Object.values(e).map((e=>e instanceof n?e.content:e))}_onConflict(e){return e?`OR ${e} `:""}_insert(e){const t=[];Array.isArray(e.data)||(e.data=[e.data]);const r=Object.keys(e.data[0]).join(", ");let s=1;for(const r of e.data){const e=[];Object.values(r).forEach((t=>{t instanceof n?e.push(t.content):e.push(`?${s}`),s+=1})),t.push(`(${e.join(", ")})`)}return`INSERT ${this._onConflict(e.onConflict)}INTO ${e.tableName} (${r}) VALUES ${t.join(", ")}`+this._returning(e.returning)}_update(e){const t=e.where&&e.where.params?Object.keys(e.where.params).length:0,r=[];return Object.entries(e.data).forEach((([e,s],i)=>{s instanceof n?r.push(`${e} = ${s.content}`):r.push(`${e} = ?${t+i+1}`)})),`UPDATE ${this._onConflict(e.onConflict)}${e.tableName} SET ${r.join(", ")}`+this._where(e.where?.conditions)+this._returning(e.returning)}_delete(e){return`DELETE FROM ${e.tableName}`+this._where(e.where?.conditions)+this._returning(e.returning)}_select(e){return`SELECT ${this._fields(e.fields)} FROM ${e.tableName}`+this._join(e.join)+this._where(e.where?.conditions)+this._groupBy(e.groupBy)+this._having(e.having)+this._orderBy(e.orderBy)+this._limit(e.limit)+this._offset(e.offset)}_fields(e){return"string"==typeof e?e:e.join(", ")}_where(e){return e?"string"==typeof e?` WHERE ${e}`:` WHERE ${e.join(" AND ")}`:""}_join(e){if(!e)return"";Array.isArray(e)||(e=[e]);const t=[];return e.forEach((e=>{const r=e.type?`${e.type} `:"";t.push(`${r}JOIN ${e.table} ON ${e.on}`)}))," "+t.join(" ")}_groupBy(e){return e?"string"==typeof e?` GROUP BY ${e}`:` GROUP BY ${e.join(", ")}`:""}_having(e){return e?` HAVING ${e}`:""}_orderBy(e){if(!e)return"";if("string"==typeof e)return` ORDER BY ${e}`;if(Array.isArray(e))return` ORDER BY ${e.join(", ")}`;const t=[];return Object.entries(e).forEach((([e,r])=>{t.push(`${e} ${r}`)})),` ORDER BY ${t.join(", ")}`}_limit(e){return e?` LIMIT ${e}`:""}_offset(e){return e?` OFFSET ${e}`:""}_returning(e){return e?"string"==typeof e?` RETURNING ${e}`:` RETURNING ${e.join(", ")}`:""}}let o;try{o=require("pg")}catch(e){o=null}exports.D1QB=class extends i{db;constructor(e){super(),this.db=e}async execute(e){let t=this.db.prepare(e.query);if(e.arguments){const r=e.arguments.map((e=>e instanceof n?e.content:e));t=t.bind(...r)}return e.fetchType===exports.FetchTypes.ONE?t.first():e.fetchType===exports.FetchTypes.ALL?t.all():t.run()}},exports.PGQB=class extends i{dbUrl;client;constructor(e){if(null===o)throw new Error('You must have "pg" installed, in order to use PGQB!');super(),this.dbUrl=e,this.client=new o.Client(this.dbUrl)}async connect(){await this.client.connect()}async close(){await this.client.end()}async execute(e){const t=e.query.replaceAll("?","$");let r;if(e.arguments){const s=e.arguments.map((e=>e instanceof n?e.content:e));r=await this.client.query({values:s,text:t})}else r=await this.client.query({text:t});return e.fetchType===exports.FetchTypes.ONE||e.fetchType===exports.FetchTypes.ALL?{command:r.command,lastRowId:r.oid,rowCount:r.rowCount,results:r.rows}:null}},exports.QueryBuilder=i,exports.Raw=n;
@@ -1 +1 @@
1
- var e,t,r,n;!function(e){e.ASC="ASC",e.DESC="DESC"}(e||(e={})),function(e){e.ONE="ONE",e.ALL="ALL"}(t||(t={})),function(e){e.ROLLBACK="ROLLBACK",e.ABORT="ABORT",e.FAIL="FAIL",e.IGNORE="IGNORE",e.REPLACE="REPLACE"}(r||(r={})),function(e){e.INNER="INNER",e.LEFT="LEFT",e.CROSS="CROSS"}(n||(n={}));class s{isRaw=!0;content;constructor(e){this.content=e}}class i{async execute(e){throw new Error("Execute method not implemented")}async createTable(e){return this.execute({query:`CREATE TABLE ${e.ifNotExists?"IF NOT EXISTS":""} ${e.tableName}\n (\n ${e.schema}\n )`})}async dropTable(e){return this.execute({query:`DROP TABLE ${e.ifExists?"IF EXISTS":""} ${e.tableName}`})}async fetchOne(e){const r=await this.execute({query:this._select({...e,limit:1}),arguments:e.where?e.where.params:void 0,fetchType:t.ALL});return{...r,results:r.results[0]}}async fetchAll(e){return this.execute({query:this._select(e),arguments:e.where?e.where.params:void 0,fetchType:t.ALL})}async insert(e){let r=[];if(Array.isArray(e.data))for(const t of e.data)r=r.concat(this._parse_arguments(t));else r=r.concat(this._parse_arguments(e.data));return this.execute({query:this._insert(e),arguments:r,fetchType:t.ALL})}async update(e){let r=this._parse_arguments(e.data);return e.where&&e.where.params&&(r=e.where.params.concat(r)),this.execute({query:this._update(e),arguments:r,fetchType:t.ALL})}async delete(e){return this.execute({query:this._delete(e),arguments:e.where?e.where.params:void 0,fetchType:t.ALL})}_parse_arguments(e){return Object.values(e).map((e=>e instanceof s?e.content:e))}_onConflict(e){return e?`OR ${e} `:""}_insert(e){const t=[];Array.isArray(e.data)||(e.data=[e.data]);const r=Object.keys(e.data[0]).join(", ");let n=1;for(const r of e.data){const e=[];Object.entries(r).forEach((([t,r])=>{r instanceof s?e.push(r.content):e.push(`?${n}`),n+=1})),t.push(`(${e.join(", ")})`)}return`INSERT ${this._onConflict(e.onConflict)}INTO ${e.tableName} (${r}) VALUES ${t.join(", ")}`+this._returning(e.returning)}_update(e){const t=e.where&&e.where.params?Object.keys(e.where.params).length:0,r=[];return Object.entries(e.data).forEach((([e,n],i)=>{n instanceof s?r.push(`${e} = ${n.content}`):r.push(`${e} = ?${t+i+1}`)})),`UPDATE ${this._onConflict(e.onConflict)}${e.tableName} SET ${r.join(", ")}`+this._where(e.where?.conditions)+this._returning(e.returning)}_delete(e){return`DELETE FROM ${e.tableName}`+this._where(e.where?.conditions)+this._returning(e.returning)}_select(e){return`SELECT ${this._fields(e.fields)} FROM ${e.tableName}`+this._join(e.join)+this._where(e.where?.conditions)+this._groupBy(e.groupBy)+this._having(e.having)+this._orderBy(e.orderBy)+this._limit(e.limit)+this._offset(e.offset)}_fields(e){return"string"==typeof e?e:e.join(", ")}_where(e){return e?"string"==typeof e?` WHERE ${e}`:` WHERE ${e.join(" AND ")}`:""}_join(e){if(!e)return"";Array.isArray(e)||(e=[e]);const t=[];return e.forEach((e=>{const r=e.type?`${e.type} `:"";t.push(`${r}JOIN ${e.table} ON ${e.on}`)}))," "+t.join(" ")}_groupBy(e){return e?"string"==typeof e?` GROUP BY ${e}`:` GROUP BY ${e.join(", ")}`:""}_having(e){return e?` HAVING ${e}`:""}_orderBy(e){if(!e)return"";if("string"==typeof e)return` ORDER BY ${e}`;if(Array.isArray(e))return` ORDER BY ${e.join(", ")}`;const t=[];return Object.entries(e).forEach((([e,r])=>{t.push(`${e} ${r}`)})),` ORDER BY ${t.join(", ")}`}_limit(e){return e?` LIMIT ${e}`:""}_offset(e){return e?` OFFSET ${e}`:""}_returning(e){return e?"string"==typeof e?` RETURNING ${e}`:` RETURNING ${e.join(", ")}`:""}}class a extends i{db;constructor(e){super(),this.db=e}async execute(e){let r=this.db.prepare(e.query);if(e.arguments){const t=e.arguments.map((e=>e instanceof s?e.content:e));r=r.bind(...t)}return e.fetchType===t.ONE?r.first():e.fetchType===t.ALL?r.all():r.run()}}export{r as ConflictTypes,a as D1QB,t as FetchTypes,n as JoinTypes,e as OrderTypes,i as QueryBuilder,s as Raw};
1
+ var e,t,r,n;!function(e){e.ASC="ASC",e.DESC="DESC"}(e||(e={})),function(e){e.ONE="ONE",e.ALL="ALL"}(t||(t={})),function(e){e.ROLLBACK="ROLLBACK",e.ABORT="ABORT",e.FAIL="FAIL",e.IGNORE="IGNORE",e.REPLACE="REPLACE"}(r||(r={})),function(e){e.INNER="INNER",e.LEFT="LEFT",e.CROSS="CROSS"}(n||(n={}));class s{isRaw=!0;content;constructor(e){this.content=e}}class i{async execute(e){throw new Error("Execute method not implemented")}async createTable(e){return this.execute({query:`CREATE TABLE ${e.ifNotExists?"IF NOT EXISTS":""} ${e.tableName}\n (\n ${e.schema}\n )`})}async dropTable(e){return this.execute({query:`DROP TABLE ${e.ifExists?"IF EXISTS":""} ${e.tableName}`})}async fetchOne(e){const r=await this.execute({query:this._select({...e,limit:1}),arguments:e.where?e.where.params:void 0,fetchType:t.ALL});return{...r,results:r.results.length>0?r.results[0]:null}}async fetchAll(e){return this.execute({query:this._select(e),arguments:e.where?e.where.params:void 0,fetchType:t.ALL})}async insert(e){let r=[];if(Array.isArray(e.data))for(const t of e.data)r=r.concat(this._parse_arguments(t));else r=r.concat(this._parse_arguments(e.data));return this.execute({query:this._insert(e),arguments:r,fetchType:t.ALL})}async update(e){let r=this._parse_arguments(e.data);return e.where&&e.where.params&&(r=e.where.params.concat(r)),this.execute({query:this._update(e),arguments:r,fetchType:t.ALL})}async delete(e){return this.execute({query:this._delete(e),arguments:e.where?e.where.params:void 0,fetchType:t.ALL})}_parse_arguments(e){return Object.values(e).map((e=>e instanceof s?e.content:e))}_onConflict(e){return e?`OR ${e} `:""}_insert(e){const t=[];Array.isArray(e.data)||(e.data=[e.data]);const r=Object.keys(e.data[0]).join(", ");let n=1;for(const r of e.data){const e=[];Object.values(r).forEach((t=>{t instanceof s?e.push(t.content):e.push(`?${n}`),n+=1})),t.push(`(${e.join(", ")})`)}return`INSERT ${this._onConflict(e.onConflict)}INTO ${e.tableName} (${r}) VALUES ${t.join(", ")}`+this._returning(e.returning)}_update(e){const t=e.where&&e.where.params?Object.keys(e.where.params).length:0,r=[];return Object.entries(e.data).forEach((([e,n],i)=>{n instanceof s?r.push(`${e} = ${n.content}`):r.push(`${e} = ?${t+i+1}`)})),`UPDATE ${this._onConflict(e.onConflict)}${e.tableName} SET ${r.join(", ")}`+this._where(e.where?.conditions)+this._returning(e.returning)}_delete(e){return`DELETE FROM ${e.tableName}`+this._where(e.where?.conditions)+this._returning(e.returning)}_select(e){return`SELECT ${this._fields(e.fields)} FROM ${e.tableName}`+this._join(e.join)+this._where(e.where?.conditions)+this._groupBy(e.groupBy)+this._having(e.having)+this._orderBy(e.orderBy)+this._limit(e.limit)+this._offset(e.offset)}_fields(e){return"string"==typeof e?e:e.join(", ")}_where(e){return e?"string"==typeof e?` WHERE ${e}`:` WHERE ${e.join(" AND ")}`:""}_join(e){if(!e)return"";Array.isArray(e)||(e=[e]);const t=[];return e.forEach((e=>{const r=e.type?`${e.type} `:"";t.push(`${r}JOIN ${e.table} ON ${e.on}`)}))," "+t.join(" ")}_groupBy(e){return e?"string"==typeof e?` GROUP BY ${e}`:` GROUP BY ${e.join(", ")}`:""}_having(e){return e?` HAVING ${e}`:""}_orderBy(e){if(!e)return"";if("string"==typeof e)return` ORDER BY ${e}`;if(Array.isArray(e))return` ORDER BY ${e.join(", ")}`;const t=[];return Object.entries(e).forEach((([e,r])=>{t.push(`${e} ${r}`)})),` ORDER BY ${t.join(", ")}`}_limit(e){return e?` LIMIT ${e}`:""}_offset(e){return e?` OFFSET ${e}`:""}_returning(e){return e?"string"==typeof e?` RETURNING ${e}`:` RETURNING ${e.join(", ")}`:""}}class a extends i{db;constructor(e){super(),this.db=e}async execute(e){let r=this.db.prepare(e.query);if(e.arguments){const t=e.arguments.map((e=>e instanceof s?e.content:e));r=r.bind(...t)}return e.fetchType===t.ONE?r.first():e.fetchType===t.ALL?r.all():r.run()}}let c;try{c=require("pg")}catch(e){c=null}class o extends i{dbUrl;client;constructor(e){if(null===c)throw new Error('You must have "pg" installed, in order to use PGQB!');super(),this.dbUrl=e,this.client=new c.Client(this.dbUrl)}async connect(){await this.client.connect()}async close(){await this.client.end()}async execute(e){const r=e.query.replaceAll("?","$");let n;if(e.arguments){const t=e.arguments.map((e=>e instanceof s?e.content:e));n=await this.client.query({values:t,text:r})}else n=await this.client.query({text:r});return e.fetchType===t.ONE||e.fetchType===t.ALL?{command:n.command,lastRowId:n.oid,rowCount:n.rowCount,results:n.rows}:null}}export{r as ConflictTypes,a as D1QB,t as FetchTypes,n as JoinTypes,e as OrderTypes,o as PGQB,i as QueryBuilder,s as Raw};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "workers-qb",
3
- "version": "0.1.7",
4
- "description": "Zero dependencies Query Builder for Cloudflare D1 Workers",
3
+ "version": "0.1.8",
4
+ "description": "Zero dependencies Query Builder for Cloudflare Workers",
5
5
  "main": "./dist/workers-qb.js",
6
6
  "types": "./dist/workers-qb.d.ts",
7
7
  "exports": {
@@ -21,7 +21,6 @@
21
21
  "prepublishOnly": "pinst --disable",
22
22
  "postpublish": "pinst --enable",
23
23
  "build": "rollup -c",
24
- "clean": "node tools/cleanup",
25
24
  "package": "npm run build && npm pack",
26
25
  "test": "jest --no-cache --runInBand",
27
26
  "test:cov": "jest --coverage --no-cache --runInBand",
@@ -69,6 +68,8 @@
69
68
  "devDependencies": {
70
69
  "@commitlint/cli": "^13.1.0",
71
70
  "@commitlint/config-conventional": "^13.1.0",
71
+ "@rollup/plugin-terser": "^0.2.1",
72
+ "@rollup/plugin-typescript": "^10.0.1",
72
73
  "@types/jest": "^27.0.1",
73
74
  "@typescript-eslint/eslint-plugin": "^4.31.1",
74
75
  "@typescript-eslint/parser": "^4.31.1",
@@ -79,11 +80,12 @@
79
80
  "jest": "^28.1.2",
80
81
  "pinst": "^2.1.6",
81
82
  "prettier": "^2.4.0",
82
- "ts-jest": "^28.0.5",
83
- "@rollup/plugin-terser": "^0.2.1",
84
- "@rollup/plugin-typescript": "^10.0.1",
85
83
  "rollup": "^3.8.1",
86
84
  "rollup-plugin-bundle-size": "^1.0.3",
85
+ "ts-jest": "^28.0.5",
87
86
  "typescript": "^4.8.4"
87
+ },
88
+ "optionalDependencies": {
89
+ "pg": "^8.11.0"
88
90
  }
89
91
  }
@@ -1,12 +0,0 @@
1
- import { QueryBuilder } from './Builder';
2
- import { FetchTypes } from './enums';
3
- import { Raw } from './tools';
4
- export declare class D1QB extends QueryBuilder {
5
- private db;
6
- constructor(db: any);
7
- execute(params: {
8
- query: string;
9
- arguments?: (string | number | boolean | null | Raw)[];
10
- fetchType?: FetchTypes;
11
- }): Promise<any>;
12
- }