@taylordb/query-builder 0.9.0 → 0.9.2

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.
Files changed (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +42 -0
  3. package/dist/cjs/__tests__/query-builder.spec.js +126 -23
  4. package/dist/cjs/__tests__/query-builder.spec.js.map +1 -1
  5. package/dist/cjs/aggregation-query-builder.d.ts +92 -0
  6. package/dist/cjs/aggregation-query-builder.js +92 -0
  7. package/dist/cjs/aggregation-query-builder.js.map +1 -1
  8. package/dist/cjs/batch-query-builder.d.ts +36 -0
  9. package/dist/cjs/batch-query-builder.js +36 -0
  10. package/dist/cjs/batch-query-builder.js.map +1 -1
  11. package/dist/cjs/delete-query-builder.d.ts +17 -0
  12. package/dist/cjs/delete-query-builder.js +17 -0
  13. package/dist/cjs/delete-query-builder.js.map +1 -1
  14. package/dist/cjs/executor.d.ts +4 -1
  15. package/dist/cjs/executor.js +20 -35
  16. package/dist/cjs/executor.js.map +1 -1
  17. package/dist/cjs/insert-query-builder.d.ts +68 -0
  18. package/dist/cjs/insert-query-builder.js +71 -0
  19. package/dist/cjs/insert-query-builder.js.map +1 -1
  20. package/dist/cjs/query-builder.d.ts +224 -5
  21. package/dist/cjs/query-builder.js +219 -5
  22. package/dist/cjs/query-builder.js.map +1 -1
  23. package/dist/cjs/selection-builder.d.ts +11 -0
  24. package/dist/cjs/selection-builder.js +11 -0
  25. package/dist/cjs/selection-builder.js.map +1 -1
  26. package/dist/cjs/{subscription-manager.d.ts → socket-connection.d.ts} +5 -4
  27. package/dist/cjs/{subscription-manager.js → socket-connection.js} +55 -9
  28. package/dist/cjs/socket-connection.js.map +1 -0
  29. package/dist/cjs/update-query-builder.d.ts +32 -0
  30. package/dist/cjs/update-query-builder.js +32 -0
  31. package/dist/cjs/update-query-builder.js.map +1 -1
  32. package/dist/cjs/where-query-builder.d.ts +59 -0
  33. package/dist/cjs/where-query-builder.js +6 -0
  34. package/dist/cjs/where-query-builder.js.map +1 -1
  35. package/dist/cjs/with-resolver.d.ts +5 -0
  36. package/dist/cjs/with-resolver.js +17 -0
  37. package/dist/cjs/with-resolver.js.map +1 -0
  38. package/dist/esm/__tests__/query-builder.spec.js +126 -23
  39. package/dist/esm/__tests__/query-builder.spec.js.map +1 -1
  40. package/dist/esm/aggregation-query-builder.d.ts +92 -0
  41. package/dist/esm/aggregation-query-builder.js +92 -0
  42. package/dist/esm/aggregation-query-builder.js.map +1 -1
  43. package/dist/esm/batch-query-builder.d.ts +36 -0
  44. package/dist/esm/batch-query-builder.js +36 -0
  45. package/dist/esm/batch-query-builder.js.map +1 -1
  46. package/dist/esm/delete-query-builder.d.ts +17 -0
  47. package/dist/esm/delete-query-builder.js +17 -0
  48. package/dist/esm/delete-query-builder.js.map +1 -1
  49. package/dist/esm/executor.d.ts +4 -1
  50. package/dist/esm/executor.js +20 -35
  51. package/dist/esm/executor.js.map +1 -1
  52. package/dist/esm/insert-query-builder.d.ts +68 -0
  53. package/dist/esm/insert-query-builder.js +71 -0
  54. package/dist/esm/insert-query-builder.js.map +1 -1
  55. package/dist/esm/query-builder.d.ts +224 -5
  56. package/dist/esm/query-builder.js +217 -4
  57. package/dist/esm/query-builder.js.map +1 -1
  58. package/dist/esm/selection-builder.d.ts +11 -0
  59. package/dist/esm/selection-builder.js +11 -0
  60. package/dist/esm/selection-builder.js.map +1 -1
  61. package/dist/esm/{subscription-manager.d.ts → socket-connection.d.ts} +5 -4
  62. package/dist/esm/{subscription-manager.js → socket-connection.js} +53 -7
  63. package/dist/esm/socket-connection.js.map +1 -0
  64. package/dist/esm/update-query-builder.d.ts +32 -0
  65. package/dist/esm/update-query-builder.js +32 -0
  66. package/dist/esm/update-query-builder.js.map +1 -1
  67. package/dist/esm/where-query-builder.d.ts +59 -0
  68. package/dist/esm/where-query-builder.js +6 -0
  69. package/dist/esm/where-query-builder.js.map +1 -1
  70. package/dist/esm/with-resolver.d.ts +5 -0
  71. package/dist/esm/with-resolver.js +14 -0
  72. package/dist/esm/with-resolver.js.map +1 -0
  73. package/dist/tsconfig.esm.tsbuildinfo +1 -1
  74. package/package.json +4 -2
  75. package/dist/cjs/subscription-manager.js.map +0 -1
  76. package/dist/esm/subscription-manager.js.map +0 -1
@@ -1,5 +1,11 @@
1
1
  import { QueryBuilder } from './query-builder.js';
2
2
  import { SelectionBuilder } from './selection-builder.js';
3
+ /**
4
+ * A query builder for creating new records in the database.
5
+ * @template DB - The database type.
6
+ * @template TableName - The name of the table to insert into.
7
+ * @template Selection - The type of the selected fields.
8
+ */
3
9
  export class InsertQueryBuilder {
4
10
  #node;
5
11
  #executor;
@@ -7,12 +13,47 @@ export class InsertQueryBuilder {
7
13
  this.#node = node;
8
14
  this.#executor = executor;
9
15
  }
16
+ /**
17
+ * The values to insert into the table.
18
+ * @param values - An object or array of objects representing the records to create.
19
+ * @returns The `InsertQueryBuilder` instance for chaining.
20
+ *
21
+ * @example Single Record Insertion
22
+ * ```typescript
23
+ * const newUser = await qb
24
+ * .insertInto('users')
25
+ * .values({ name: 'John Doe', email: 'john.doe@example.com' })
26
+ * .executeTakeFirst();
27
+ * ```
28
+ *
29
+ * @example Multiple Record Insertion
30
+ * ```typescript
31
+ * const newUsers = await qb
32
+ * .insertInto('users')
33
+ * .values([{ name: 'John Doe' }, { name: 'Jane Doe' }])
34
+ * .execute();
35
+ * ```
36
+ */
10
37
  values(values) {
11
38
  return new InsertQueryBuilder({
12
39
  ...this.#node,
13
40
  createdRecords: Array.isArray(values) ? values : [values],
14
41
  }, this.#executor);
15
42
  }
43
+ /**
44
+ * The fields to return after the insert operation.
45
+ * @param fields - An array of field names to return.
46
+ * @returns The `InsertQueryBuilder` instance for chaining.
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * const newUser = await qb
51
+ * .insertInto('users')
52
+ * .values({ name: 'John Doe' })
53
+ * .returning(['id', 'name'])
54
+ * .executeTakeFirst();
55
+ * ```
56
+ */
16
57
  returning(fields) {
17
58
  const newSelects = fields.map(field => {
18
59
  if (typeof field === 'function') {
@@ -28,9 +69,39 @@ export class InsertQueryBuilder {
28
69
  returning: [...this.#node.returning, ...newSelects],
29
70
  }, this.#executor);
30
71
  }
72
+ /**
73
+ * Executes the insert query.
74
+ * @returns A promise that resolves with an array of the selected fields from the inserted records.
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * const newUsers = await qb
79
+ * .insertInto('users')
80
+ * .values([{ name: 'John Doe' }, { name: 'Jane Doe' }])
81
+ * .returning(['id', 'name'])
82
+ * .execute();
83
+ * ```
84
+ */
31
85
  async execute() {
32
86
  return (await this.#executor.execute(this))[0];
33
87
  }
88
+ /**
89
+ * Executes the insert query and returns the first result.
90
+ * @returns A promise that resolves with the first inserted record, or `null` if no records were inserted.
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * const newUser = await qb
95
+ * .insertInto('users')
96
+ * .values({ name: 'John Doe' })
97
+ * .returning(['id', 'name'])
98
+ * .executeTakeFirst();
99
+ * ```
100
+ */
101
+ async executeTakeFirst() {
102
+ const response = await this.execute();
103
+ return response[0] ?? null;
104
+ }
34
105
  compile() {
35
106
  const query = 'mutation ($metadata: JSON) { execute(metadata: $metadata) }';
36
107
  const metadata = [this._prepareMetadata()];
@@ -1 +1 @@
1
- {"version":3,"file":"insert-query-builder.js","sourceRoot":"","sources":["../../src/insert-query-builder.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,MAAM,OAAO,kBAAkB;IAK7B,KAAK,CAAa;IAClB,SAAS,CAAW;IAEpB,YAAY,IAAgB,EAAE,QAAkB;QAC9C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC5B,CAAC;IAED,MAAM,CACJ,MAA+D;QAE/D,OAAO,IAAI,kBAAkB,CAC3B;YACE,GAAG,IAAI,CAAC,KAAK;YACb,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;SAC1D,EACD,IAAI,CAAC,SAAS,CACf,CAAC;IACJ,CAAC;IAED,SAAS,CACP,MAAe;QAMf,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YACpC,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;gBAChC,MAAM,OAAO,GAAG,IAAI,gBAAgB,CAAgB,IAAI,CAAC,SAAS,CAAC,CAAC;gBACpE,aAAa;gBACb,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;gBAChC,OAAO,QAAQ,CAAC,KAAK,CAAC;YACxB,CAAC;YACD,OAAO,KAAe,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,OAAO,IAAI,kBAAkB,CAC3B;YACE,GAAG,IAAI,CAAC,KAAK;YACb,SAAS,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,GAAG,UAAU,CAAC;SACpD,EACD,IAAI,CAAC,SAAS,CACf,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO;QACX,OAAO,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC;IAED,OAAO;QACL,MAAM,KAAK,GAAG,6DAA6D,CAAC;QAE5E,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;QAE3C,OAAO;YACL,KAAK;YACL,SAAS,EAAE;gBACT,QAAQ;aACT;SACF,CAAC;IACJ,CAAC;IAED,gBAAgB;QACd,MAAM,YAAY,GAAG,CAAC,OAA+B,EAAS,EAAE;YAC9D,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;gBACzB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;oBAC9B,OAAO,KAAK,CAAC;gBACf,CAAC;gBACD,MAAM,eAAe,GAAG,IAAI,YAAY,CACtC,KAAkB,EAClB,IAAI,CAAC,SAAS,CACf,CAAC;gBACF,OAAO,eAAe,CAAC,gBAAgB,EAAE,CAAC;YAC5C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,kBAAkB,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM;YACpD,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;YACpC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEX,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS;YAC/B,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc;YACzC,SAAS,EAAE,kBAAkB;SAC9B,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"insert-query-builder.js","sourceRoot":"","sources":["../../src/insert-query-builder.ts"],"names":[],"mappings":"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"}
@@ -9,22 +9,166 @@ import { Executor } from './executor.js';
9
9
  import { InsertQueryBuilder } from './insert-query-builder.js';
10
10
  import { UpdateQueryBuilder } from './update-query-builder.js';
11
11
  import { FilterableQueryBuilder } from './where-query-builder.js';
12
+ /**
13
+ * The main query builder class for constructing and executing select queries.
14
+ * @template DB - The database type.
15
+ * @template TableName - The name of the table to query.
16
+ * @template Selection - The type of the selected fields.
17
+ * @template LinkName - The name of the link field if this is a subquery.
18
+ */
12
19
  export declare class QueryBuilder<DB extends AnyDB, TableName extends keyof DB, Selection = object, LinkName = null> extends FilterableQueryBuilder<DB, TableName> {
13
20
  _node: QueryNode;
14
21
  constructor(node: QueryNode, executor: Executor);
22
+ /**
23
+ * Selects a set of fields from the table.
24
+ * @param fields - An array of field names to select.
25
+ * @returns A new `QueryBuilder` instance with the specified fields selected.
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * const users = await qb
30
+ * .selectFrom('users')
31
+ * .select(['id', 'name'])
32
+ * .execute();
33
+ * ```
34
+ */
15
35
  select<const TFields extends readonly NonLinkColumnNames<DB[TableName]>[]>(fields: TFields): QueryBuilder<DB, TableName, ResolveSelection<DB, TableName, TFields, Selection>>;
36
+ /**
37
+ * Selects all fields from the table.
38
+ * @returns A new `QueryBuilder` instance with all fields selected.
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * const users = await qb
43
+ * .selectFrom('users')
44
+ * .selectAll()
45
+ * .execute();
46
+ * ```
47
+ */
16
48
  selectAll(): QueryBuilder<DB, TableName, Selection & {
17
49
  [K in keyof DB[TableName]]: InferDataType<DB[TableName][K]>;
18
50
  }>;
51
+ /**
52
+ * Includes related records from a linked table.
53
+ * This method has two overloads:
54
+ * 1. Pass an array of link field names to include all fields from the related records.
55
+ * 2. Pass an object to specify subqueries for each link field.
56
+ *
57
+ * @param relations - The relations to include.
58
+ * @returns A new `QueryBuilder` instance with the specified relations included.
59
+ *
60
+ * @example
61
+ * ```typescript
62
+ * const usersWithPosts = await qb
63
+ * .selectFrom('users')
64
+ * .select(['id', 'name'])
65
+ * .with(['posts']) // Assuming 'posts' is a link field on the 'users' table
66
+ * .execute();
67
+ * ```
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * const usersWithPublishedPosts = await qb
72
+ * .selectFrom('users')
73
+ * .select(['id', 'name'])
74
+ * .with({
75
+ * posts: (qb) => qb.select(['title', 'content']).where('isPublished', '=', true),
76
+ * })
77
+ * .execute();
78
+ * ```
79
+ */
19
80
  with<const TArg extends (LinkColumnNames<DB[TableName]> & string) | readonly (LinkColumnNames<DB[TableName]> & string)[]>(relations: TArg): QueryBuilder<DB, TableName, ResolveWithPlain<DB, TableName, TArg, Selection>>;
20
81
  with<const TArg extends {
21
82
  [K in LinkColumnNames<DB[TableName]>]?: (qb: QueryBuilder<DB, DB[TableName][K] extends LinkColumnType<any, boolean> ? DB[TableName][K]['linkedTo'] : never, object, K>) => QueryBuilder<DB, any, any, any>;
22
83
  }>(relations: TArg): QueryBuilder<DB, TableName, ResolveWithObject<TArg, Selection>>;
84
+ /**
85
+ * Sets the maximum number of records to return.
86
+ * @param count - The maximum number of records.
87
+ * @returns A new `QueryBuilder` instance with the limit applied.
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * const users = await qb
92
+ * .selectFrom('users')
93
+ * .select(['id', 'name'])
94
+ * .limit(10)
95
+ * .execute();
96
+ * ```
97
+ */
23
98
  limit(count: number): QueryBuilder<DB, TableName, Selection, LinkName>;
99
+ /**
100
+ * Sets the number of records to skip.
101
+ * @param count - The number of records to skip.
102
+ * @returns A new `QueryBuilder` instance with the offset applied.
103
+ *
104
+ * @example
105
+ * ```typescript
106
+ * const users = await qb
107
+ * .selectFrom('users')
108
+ * .select(['id', 'name'])
109
+ * .offset(10)
110
+ * .execute();
111
+ * ```
112
+ */
24
113
  offset(count: number): QueryBuilder<DB, TableName, Selection, LinkName>;
114
+ /**
115
+ * Paginates the results.
116
+ * @param page - The page number to retrieve.
117
+ * @param limit - The number of records per page.
118
+ * @returns A new `QueryBuilder` instance with pagination applied.
119
+ *
120
+ * @example
121
+ * ```typescript
122
+ * const users = await qb
123
+ * .selectFrom('users')
124
+ * .select(['id', 'name'])
125
+ * .paginate(2, 25) // Retrieves page 2 with 25 records per page
126
+ * .execute();
127
+ * ```
128
+ */
25
129
  paginate(page: number, limit: number): QueryBuilder<DB, TableName, Selection, LinkName>;
130
+ /**
131
+ * Sorts the results by a specified field.
132
+ * @param field - The field to sort by.
133
+ * @param direction - The sort direction ('asc' or 'desc').
134
+ * @returns A new `QueryBuilder` instance with the sorting applied.
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * const users = await qb
139
+ * .selectFrom('users')
140
+ * .select(['id', 'name'])
141
+ * .orderBy('name', 'asc')
142
+ * .execute();
143
+ * ```
144
+ */
26
145
  orderBy(field: keyof DB[TableName], direction?: 'asc' | 'desc'): QueryBuilder<DB, TableName, Selection, LinkName>;
146
+ /**
147
+ * Executes the select query.
148
+ * @returns A promise that resolves with an array of the selected records.
149
+ *
150
+ * @example
151
+ * ```typescript
152
+ * const users = await qb
153
+ * .selectFrom('users')
154
+ * .select(['id', 'name'])
155
+ * .execute();
156
+ * ```
157
+ */
27
158
  execute(): Promise<Selection[]>;
159
+ /**
160
+ * Executes the select query and returns the first result.
161
+ * @returns A promise that resolves with the first record, or `null` if no records were found.
162
+ *
163
+ * @example
164
+ * ```typescript
165
+ * const user = await qb
166
+ * .selectFrom('users')
167
+ * .where('id', '=', 1)
168
+ * .select(['id', 'name'])
169
+ * .executeTakeFirst();
170
+ * ```
171
+ */
28
172
  executeTakeFirst(): Promise<Selection | null>;
29
173
  subscribe(callback: (result: Selection[]) => void): Promise<{
30
174
  unsubscribe: () => Promise<void>;
@@ -37,19 +181,94 @@ export declare class QueryBuilder<DB extends AnyDB, TableName extends keyof DB,
37
181
  isSelectionQueryNode(node: QueryNode): node is SelectionQueryNode;
38
182
  isRootQueryNode(node: QueryNode): node is RootQueryNode;
39
183
  }
40
- export declare class RootQueryBuilder<DB extends AnyDB> {
184
+ /**
185
+ * The root query builder class that provides entry points for all query types.
186
+ */
187
+ export declare class BaseRootQueryBuilder<DB extends AnyDB> {
41
188
  #private;
42
- constructor(config: {
43
- baseUrl: string;
44
- apiKey: string;
45
- });
189
+ constructor(executor: Executor);
190
+ /**
191
+ * Creates a new select query builder for the specified table.
192
+ * @param from - The name of the table to select from.
193
+ * @returns A new `QueryBuilder` instance.
194
+ *
195
+ * @example
196
+ * ```typescript
197
+ * const qb = createQueryBuilder<MyDatabase>({ ... });
198
+ * const userQuery = qb.selectFrom('users');
199
+ * ```
200
+ */
46
201
  selectFrom<TableName extends keyof Omit<DB, 'selectTable' | 'attachmentTable' | 'collaboratorsTable'> & string>(from: TableName): QueryBuilder<DB, TableName>;
202
+ /**
203
+ * Creates a new insert query builder for the specified table.
204
+ * @param into - The name of the table to insert into.
205
+ * @returns A new `InsertQueryBuilder` instance.
206
+ *
207
+ * @example
208
+ * ```typescript
209
+ * const qb = createQueryBuilder<MyDatabase>({ ... });
210
+ * const insertQuery = qb.insertInto('users');
211
+ * ```
212
+ */
47
213
  insertInto<TableName extends keyof Omit<DB, 'selectTable' | 'attachmentTable' | 'collaboratorsTable'> & string>(into: TableName): InsertQueryBuilder<DB, TableName>;
214
+ /**
215
+ * Creates a new update query builder for the specified table.
216
+ * @param tableName - The name of the table to update.
217
+ * @returns A new `UpdateQueryBuilder` instance.
218
+ *
219
+ * @example
220
+ * ```typescript
221
+ * const qb = createQueryBuilder<MyDatabase>({ ... });
222
+ * const updateQuery = qb.update('users');
223
+ * ```
224
+ */
48
225
  update<TableName extends keyof Omit<DB, 'selectTable' | 'attachmentTable' | 'collaboratorsTable'> & string>(tableName: TableName): UpdateQueryBuilder<DB, TableName>;
226
+ /**
227
+ * Creates a new delete query builder for the specified table.
228
+ * @param tableName - The name of the table to delete from.
229
+ * @returns A new `DeleteQueryBuilder` instance.
230
+ *
231
+ * @example
232
+ * ```typescript
233
+ * const qb = createQueryBuilder<MyDatabase>({ ... });
234
+ * const deleteQuery = qb.deleteFrom('users');
235
+ * ```
236
+ */
49
237
  deleteFrom<TableName extends keyof Omit<DB, 'selectTable' | 'attachmentTable' | 'collaboratorsTable'> & string>(tableName: TableName): DeleteQueryBuilder<DB, TableName>;
238
+ /**
239
+ * Creates a new batch query builder.
240
+ * @param builders - An array of query builders to execute in a batch.
241
+ * @returns A new `BatchQueryBuilder` instance.
242
+ *
243
+ * @example
244
+ * ```typescript
245
+ * const qb = createQueryBuilder<MyDatabase>({ ... });
246
+ * const batchQuery = qb.batch([
247
+ * qb.selectFrom('users').select(['id', 'name']),
248
+ * qb.insertInto('users').values({ name: 'New User' }),
249
+ * ]);
250
+ * const [users, newUser] = await batchQuery.execute();
251
+ * ```
252
+ */
50
253
  batch<const TBuilders extends readonly AnyQueryBuilder[]>(builders: TBuilders): AreAllBuildersSubscribable<TBuilders> extends true ? BatchQueryBuilder<TBuilders> : Omit<BatchQueryBuilder<TBuilders>, 'subscribe'>;
254
+ /**
255
+ * Creates a new aggregation query builder for the specified table.
256
+ * @param tableName - The name of the table to aggregate from.
257
+ * @returns A new `AggregationQueryBuilder` instance.
258
+ *
259
+ * @example
260
+ * ```typescript
261
+ * const qb = createQueryBuilder<MyDatabase>({ ... });
262
+ * const aggregateQuery = qb.aggregateFrom('users');
263
+ * ```
264
+ */
51
265
  aggregateFrom<TableName extends keyof Omit<DB, 'selectTable' | 'attachmentTable' | 'collaboratorsTable'> & string>(tableName: TableName): AggregationQueryBuilder<DB, TableName>;
52
266
  }
267
+ export declare class RootQueryBuilder<DB extends AnyDB> extends BaseRootQueryBuilder<DB> {
268
+ #private;
269
+ constructor(executor: Executor);
270
+ transaction<T>(callback: (qb: BaseRootQueryBuilder<DB>) => Promise<T>): Promise<T>;
271
+ }
53
272
  export declare function createQueryBuilder<DB extends AnyDB>(config: {
54
273
  baseUrl: string;
55
274
  apiKey: string;
@@ -8,6 +8,13 @@ import { SelectionBuilder } from './selection-builder.js';
8
8
  import { UpdateQueryBuilder } from './update-query-builder.js';
9
9
  import { FilterableQueryBuilder } from './where-query-builder.js';
10
10
  const DEFAULT_LIMIT = 50;
11
+ /**
12
+ * The main query builder class for constructing and executing select queries.
13
+ * @template DB - The database type.
14
+ * @template TableName - The name of the table to query.
15
+ * @template Selection - The type of the selected fields.
16
+ * @template LinkName - The name of the link field if this is a subquery.
17
+ */
11
18
  export class QueryBuilder extends FilterableQueryBuilder {
12
19
  constructor(node, executor) {
13
20
  super(node, executor);
@@ -16,12 +23,37 @@ export class QueryBuilder extends FilterableQueryBuilder {
16
23
  pagination: { limit: DEFAULT_LIMIT, offset: 0, ...node.pagination },
17
24
  };
18
25
  }
26
+ /**
27
+ * Selects a set of fields from the table.
28
+ * @param fields - An array of field names to select.
29
+ * @returns A new `QueryBuilder` instance with the specified fields selected.
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * const users = await qb
34
+ * .selectFrom('users')
35
+ * .select(['id', 'name'])
36
+ * .execute();
37
+ * ```
38
+ */
19
39
  select(fields) {
20
40
  return new QueryBuilder({
21
41
  ...this._node,
22
42
  fields: [...this._node.fields, ...fields],
23
43
  }, this._executor);
24
44
  }
45
+ /**
46
+ * Selects all fields from the table.
47
+ * @returns A new `QueryBuilder` instance with all fields selected.
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * const users = await qb
52
+ * .selectFrom('users')
53
+ * .selectAll()
54
+ * .execute();
55
+ * ```
56
+ */
25
57
  selectAll() {
26
58
  return new QueryBuilder({
27
59
  ...this._node,
@@ -55,21 +87,79 @@ export class QueryBuilder extends FilterableQueryBuilder {
55
87
  fields: [...this._node.fields, ...newSelects],
56
88
  }, this._executor);
57
89
  }
90
+ /**
91
+ * Sets the maximum number of records to return.
92
+ * @param count - The maximum number of records.
93
+ * @returns A new `QueryBuilder` instance with the limit applied.
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * const users = await qb
98
+ * .selectFrom('users')
99
+ * .select(['id', 'name'])
100
+ * .limit(10)
101
+ * .execute();
102
+ * ```
103
+ */
58
104
  limit(count) {
59
105
  return new QueryBuilder({
60
106
  ...this._node,
61
107
  pagination: { ...this._node.pagination, limit: count },
62
108
  }, this._executor);
63
109
  }
110
+ /**
111
+ * Sets the number of records to skip.
112
+ * @param count - The number of records to skip.
113
+ * @returns A new `QueryBuilder` instance with the offset applied.
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * const users = await qb
118
+ * .selectFrom('users')
119
+ * .select(['id', 'name'])
120
+ * .offset(10)
121
+ * .execute();
122
+ * ```
123
+ */
64
124
  offset(count) {
65
125
  return new QueryBuilder({
66
126
  ...this._node,
67
127
  pagination: { ...this._node.pagination, offset: count },
68
128
  }, this._executor);
69
129
  }
130
+ /**
131
+ * Paginates the results.
132
+ * @param page - The page number to retrieve.
133
+ * @param limit - The number of records per page.
134
+ * @returns A new `QueryBuilder` instance with pagination applied.
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * const users = await qb
139
+ * .selectFrom('users')
140
+ * .select(['id', 'name'])
141
+ * .paginate(2, 25) // Retrieves page 2 with 25 records per page
142
+ * .execute();
143
+ * ```
144
+ */
70
145
  paginate(page, limit) {
71
146
  return this.offset((page - 1) * limit).limit(limit);
72
147
  }
148
+ /**
149
+ * Sorts the results by a specified field.
150
+ * @param field - The field to sort by.
151
+ * @param direction - The sort direction ('asc' or 'desc').
152
+ * @returns A new `QueryBuilder` instance with the sorting applied.
153
+ *
154
+ * @example
155
+ * ```typescript
156
+ * const users = await qb
157
+ * .selectFrom('users')
158
+ * .select(['id', 'name'])
159
+ * .orderBy('name', 'asc')
160
+ * .execute();
161
+ * ```
162
+ */
73
163
  orderBy(field, direction = 'asc') {
74
164
  const newSorting = {
75
165
  field: field,
@@ -80,10 +170,35 @@ export class QueryBuilder extends FilterableQueryBuilder {
80
170
  sorting: [...(this._node.sorting || []), newSorting],
81
171
  }, this._executor);
82
172
  }
173
+ /**
174
+ * Executes the select query.
175
+ * @returns A promise that resolves with an array of the selected records.
176
+ *
177
+ * @example
178
+ * ```typescript
179
+ * const users = await qb
180
+ * .selectFrom('users')
181
+ * .select(['id', 'name'])
182
+ * .execute();
183
+ * ```
184
+ */
83
185
  async execute() {
84
186
  const response = await this._executor.execute(this);
85
187
  return response[0];
86
188
  }
189
+ /**
190
+ * Executes the select query and returns the first result.
191
+ * @returns A promise that resolves with the first record, or `null` if no records were found.
192
+ *
193
+ * @example
194
+ * ```typescript
195
+ * const user = await qb
196
+ * .selectFrom('users')
197
+ * .where('id', '=', 1)
198
+ * .select(['id', 'name'])
199
+ * .executeTakeFirst();
200
+ * ```
201
+ */
87
202
  async executeTakeFirst() {
88
203
  const response = await this._executor.execute(this);
89
204
  return response[0]?.[0] ?? null;
@@ -144,11 +259,25 @@ export class QueryBuilder extends FilterableQueryBuilder {
144
259
  return node.queryType === 'root';
145
260
  }
146
261
  }
147
- export class RootQueryBuilder {
262
+ /**
263
+ * The root query builder class that provides entry points for all query types.
264
+ */
265
+ export class BaseRootQueryBuilder {
148
266
  #executor;
149
- constructor(config) {
150
- this.#executor = new Executor(config.baseUrl, config.apiKey);
267
+ constructor(executor) {
268
+ this.#executor = executor;
151
269
  }
270
+ /**
271
+ * Creates a new select query builder for the specified table.
272
+ * @param from - The name of the table to select from.
273
+ * @returns A new `QueryBuilder` instance.
274
+ *
275
+ * @example
276
+ * ```typescript
277
+ * const qb = createQueryBuilder<MyDatabase>({ ... });
278
+ * const userQuery = qb.selectFrom('users');
279
+ * ```
280
+ */
152
281
  selectFrom(from) {
153
282
  return new QueryBuilder({
154
283
  tableName: from,
@@ -158,6 +287,17 @@ export class RootQueryBuilder {
158
287
  queryType: 'root',
159
288
  }, this.#executor);
160
289
  }
290
+ /**
291
+ * Creates a new insert query builder for the specified table.
292
+ * @param into - The name of the table to insert into.
293
+ * @returns A new `InsertQueryBuilder` instance.
294
+ *
295
+ * @example
296
+ * ```typescript
297
+ * const qb = createQueryBuilder<MyDatabase>({ ... });
298
+ * const insertQuery = qb.insertInto('users');
299
+ * ```
300
+ */
161
301
  insertInto(into) {
162
302
  return new InsertQueryBuilder({
163
303
  tableName: into,
@@ -166,6 +306,17 @@ export class RootQueryBuilder {
166
306
  type: 'create',
167
307
  }, this.#executor);
168
308
  }
309
+ /**
310
+ * Creates a new update query builder for the specified table.
311
+ * @param tableName - The name of the table to update.
312
+ * @returns A new `UpdateQueryBuilder` instance.
313
+ *
314
+ * @example
315
+ * ```typescript
316
+ * const qb = createQueryBuilder<MyDatabase>({ ... });
317
+ * const updateQuery = qb.update('users');
318
+ * ```
319
+ */
169
320
  update(tableName) {
170
321
  return new UpdateQueryBuilder({
171
322
  tableName: tableName,
@@ -174,6 +325,17 @@ export class RootQueryBuilder {
174
325
  type: 'update',
175
326
  }, this.#executor);
176
327
  }
328
+ /**
329
+ * Creates a new delete query builder for the specified table.
330
+ * @param tableName - The name of the table to delete from.
331
+ * @returns A new `DeleteQueryBuilder` instance.
332
+ *
333
+ * @example
334
+ * ```typescript
335
+ * const qb = createQueryBuilder<MyDatabase>({ ... });
336
+ * const deleteQuery = qb.deleteFrom('users');
337
+ * ```
338
+ */
177
339
  deleteFrom(tableName) {
178
340
  return new DeleteQueryBuilder({
179
341
  tableName: tableName,
@@ -182,9 +344,35 @@ export class RootQueryBuilder {
182
344
  type: 'delete',
183
345
  }, this.#executor);
184
346
  }
347
+ /**
348
+ * Creates a new batch query builder.
349
+ * @param builders - An array of query builders to execute in a batch.
350
+ * @returns A new `BatchQueryBuilder` instance.
351
+ *
352
+ * @example
353
+ * ```typescript
354
+ * const qb = createQueryBuilder<MyDatabase>({ ... });
355
+ * const batchQuery = qb.batch([
356
+ * qb.selectFrom('users').select(['id', 'name']),
357
+ * qb.insertInto('users').values({ name: 'New User' }),
358
+ * ]);
359
+ * const [users, newUser] = await batchQuery.execute();
360
+ * ```
361
+ */
185
362
  batch(builders) {
186
363
  return new BatchQueryBuilder(builders, this.#executor);
187
364
  }
365
+ /**
366
+ * Creates a new aggregation query builder for the specified table.
367
+ * @param tableName - The name of the table to aggregate from.
368
+ * @returns A new `AggregationQueryBuilder` instance.
369
+ *
370
+ * @example
371
+ * ```typescript
372
+ * const qb = createQueryBuilder<MyDatabase>({ ... });
373
+ * const aggregateQuery = qb.aggregateFrom('users');
374
+ * ```
375
+ */
188
376
  aggregateFrom(tableName) {
189
377
  const node = {
190
378
  tableName: tableName,
@@ -196,12 +384,37 @@ export class RootQueryBuilder {
196
384
  return new AggregationQueryBuilder(node, this.#executor);
197
385
  }
198
386
  }
387
+ export class RootQueryBuilder extends BaseRootQueryBuilder {
388
+ #executor;
389
+ constructor(executor) {
390
+ super(executor);
391
+ this.#executor = executor;
392
+ }
393
+ async transaction(callback) {
394
+ if (this.#executor.isInTransaction) {
395
+ throw new Error('Nested transactions are not supported.');
396
+ }
397
+ const { startTransaction: transactionId } = await this.#executor.rawRequest('mutation { startTransaction }', {});
398
+ const transactionalExecutor = this.#executor.withTransactionId(transactionId);
399
+ const transactionalQb = new BaseRootQueryBuilder(transactionalExecutor);
400
+ try {
401
+ const result = await callback(transactionalQb);
402
+ await transactionalExecutor.rawRequest('mutation { commitTransaction }', {});
403
+ return result;
404
+ }
405
+ catch (error) {
406
+ await transactionalExecutor.rawRequest('mutation { rollbackTransaction }', {});
407
+ throw error;
408
+ }
409
+ }
410
+ }
199
411
  const QBConfigSchema = z.object({
200
412
  baseUrl: z.string().url(),
201
413
  apiKey: z.string().nonempty(),
202
414
  });
203
415
  export function createQueryBuilder(config) {
204
416
  QBConfigSchema.parse(config);
205
- return new RootQueryBuilder(config);
417
+ const executor = new Executor(config.baseUrl, config.apiKey);
418
+ return new RootQueryBuilder(executor);
206
419
  }
207
420
  //# sourceMappingURL=query-builder.js.map