@hf-chimera/query-builder 0.2.0 → 0.2.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Hewston Fox
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,407 +1,407 @@
1
- # ChimeraQueryBuilder
2
-
3
- A type-safe query builder for constructing filters and ordering rules for Chimera Store collections. `ChimeraQueryBuilder` provides a fluent API for building complex queries with support for filtering, ordering, and nested grouping.
4
-
5
- ## Features
6
-
7
- - **Type-Safe**: Full TypeScript support with automatic type inference
8
- - **Fluent API**: Chainable methods for building queries
9
- - **Complex Filtering**: Support for operators, negations, and grouped conditions
10
- - **Ordering**: Flexible sorting with null handling options
11
- - **Nested Groups**: Create complex logical groupings with AND/OR/NOT
12
-
13
- ## Installation
14
-
15
- ```bash
16
- # Install both the core store and query builder
17
- npm install @hf-chimera/store @hf-chimera/query-builder
18
-
19
- # Or with yarn
20
- yarn add @hf-chimera/store @hf-chimera/query-builder
21
-
22
- # Or with pnpm
23
- pnpm add @hf-chimera/store @hf-chimera/query-builder
24
- ```
25
-
26
- ## Setting Up Your Store
27
-
28
- Before using `ChimeraQueryBuilder`, you need to create entity stores. Here's a complete example:
29
-
30
- ```typescript
31
- import { createChimeraEntityStore } from "@hf-chimera/store";
32
-
33
- // Define your entity types
34
- type Customer = {
35
- id: number;
36
- name: string;
37
- email: string;
38
- phone: string;
39
- createdAt: Date;
40
- };
41
-
42
- type Order = {
43
- id: number;
44
- customerId: number;
45
- productName: string;
46
- quantity: number;
47
- totalAmount: number;
48
- status: "pending" | "completed" | "cancelled";
49
- createdAt: Date;
50
- };
51
-
52
- // Create entity stores
53
- export const customerStore = createChimeraEntityStore<"customer", Customer>({
54
- name: "customer",
55
- idGetter: "id",
56
- async collectionFetcher(params, requestParams) {
57
- const response = await fetch(`/api/customers`, {
58
- method: "POST",
59
- headers: { "Content-Type": "application/json" },
60
- body: JSON.stringify({ filter: params.filter, order: params.order }),
61
- signal: requestParams.signal,
62
- });
63
- return { data: await response.json() };
64
- },
65
- async itemCreator(item, requestParams) {
66
- const response = await fetch(`/api/customers`, {
67
- method: "POST",
68
- headers: { "Content-Type": "application/json" },
69
- body: JSON.stringify(item),
70
- signal: requestParams.signal,
71
- });
72
- return { data: await response.json() };
73
- },
74
- async itemUpdater(item, requestParams) {
75
- const response = await fetch(`/api/customers/${item.id}`, {
76
- method: "PUT",
77
- headers: { "Content-Type": "application/json" },
78
- body: JSON.stringify(item),
79
- signal: requestParams.signal,
80
- });
81
- return { data: await response.json() };
82
- },
83
- async itemDeleter(id, requestParams) {
84
- await fetch(`/api/customers/${id}`, {
85
- method: "DELETE",
86
- signal: requestParams.signal,
87
- });
88
- return { result: { id, success: true } };
89
- },
90
- async itemFetcher(params, requestParams) {
91
- const response = await fetch(`/api/customers/${params.id}`, {
92
- signal: requestParams.signal,
93
- });
94
- return { data: await response.json() };
95
- },
96
- });
97
-
98
- export const orderStore = createChimeraEntityStore<"order", Order>({
99
- name: "order",
100
- idGetter: "id",
101
- // ... similar CRUD operations
102
- });
103
- ```
104
-
105
- ## Basic Usage
106
-
107
- ```typescript
108
- import { ChimeraQueryBuilder } from "@hf-chimera/query-builder";
109
- import { customerStore } from "./store";
110
-
111
- // Create a query builder instance
112
- const query = new ChimeraQueryBuilder<typeof customerStore, Customer, any>();
113
-
114
- // Build a simple query
115
- query
116
- .where("name", "eq", "John")
117
- .where("age", "gte", 18)
118
- .orderBy("createdAt", true); // true = descending
119
-
120
- // Build the query descriptor
121
- const descriptor = query.build();
122
- // Returns: { filter: {...}, order: [...] }
123
-
124
- // Use with entity store
125
- const customers = customerStore.getCollection(descriptor);
126
- ```
127
-
128
- ## API Reference
129
-
130
- ### `orderBy(key, desc?, nulls?)`
131
-
132
- Adds an ordering rule to the query.
133
-
134
- **Parameters:**
135
-
136
- - `key`: `ChimeraPropertyGetter<Entity> | (keyof Entity & string)` - The property to order by (can be a property name string or a property getter function)
137
- - `desc`: `boolean` (default: `false`) - Whether to sort in descending order
138
- - `nulls`: `ChimeraOrderNulls` (default: `ChimeraOrderNulls.Last`) - How to handle null values (`Last` or `First`)
139
-
140
- **Returns:** `this` - Returns the builder instance for chaining
141
-
142
- **Example:**
143
-
144
- ```typescript
145
- query
146
- .orderBy("name") // Ascending
147
- .orderBy("age", true) // Descending
148
- .orderBy("createdAt", false, ChimeraOrderNulls.First); // Nulls first
149
- ```
150
-
151
- ### `where(value, op, test)`
152
-
153
- Adds a filter condition to the query. Multiple `where` calls are combined with AND logic by default.
154
-
155
- **Parameters:**
156
-
157
- - `value`: `ChimeraPropertyGetter<Entity> | (KeysOfType<Entity, T> & string)` - The property to filter on (property name or getter function)
158
- - `op`: `Op extends keyof OperatorsMap & string` - The operator to use (e.g., `'eq'`, `'gte'`, `'in'`, etc.)
159
- - `test`: `Parameters<OperatorsMap[Op]>[1]` - The value to compare against (type depends on the operator)
160
-
161
- **Returns:** `this` - Returns the builder instance for chaining
162
-
163
- **Example:**
164
-
165
- ```typescript
166
- query
167
- .where("status", "eq", "active")
168
- .where("age", "gte", 18)
169
- .where("tags", "in", ["javascript", "typescript"]);
170
- ```
171
-
172
- ### `whereNot(value, op, test)`
173
-
174
- Adds a negated filter condition (NOT condition) to the query.
175
-
176
- **Parameters:**
177
-
178
- - `value`: Same as `where()`
179
- - `op`: Same as `where()`
180
- - `test`: Same as `where()`
181
-
182
- **Returns:** `this` - Returns the builder instance for chaining
183
-
184
- **Example:**
185
-
186
- ```typescript
187
- query.where("status", "eq", "active").whereNot("deleted", "eq", true); // NOT deleted = true
188
- ```
189
-
190
- ### `group(conjunction, builder)`
191
-
192
- Creates a grouped condition with a specified logical conjunction. Useful for creating complex logical expressions with AND, OR, or NOT groups.
193
-
194
- **Parameters:**
195
-
196
- - `conjunction`: `ChimeraConjunctionType` - The logical operator: `'and'`, `'or'`, or `'not'`
197
- - `builder`: `QueryBuilderCreator<Store, Entity, OperatorsMap>` - A callback function that receives a new builder instance for building the nested query
198
-
199
- **Returns:** `this` - Returns the builder instance for chaining
200
-
201
- **Example:**
202
-
203
- ```typescript
204
- // Create an OR group: (status = 'active' OR status = 'pending')
205
- query.group("or", (q) => {
206
- q.where("status", "eq", "active").where("status", "eq", "pending");
207
- });
208
-
209
- // Create a NOT group: NOT (age < 18 OR deleted = true)
210
- query.group("not", (q) => {
211
- q.group("or", (nested) => {
212
- nested.where("age", "lt", 18).where("deleted", "eq", true);
213
- });
214
- });
215
- ```
216
-
217
- ### `build()`
218
-
219
- Builds and returns the final query descriptor object.
220
-
221
- **Returns:**
222
-
223
- ```typescript
224
- {
225
- filter: ChimeraFilterDescriptor<OperatorsMap, Entity> | null;
226
- order: (ChimeraOrderDescriptor < Entity > []) | null;
227
- }
228
- ```
229
-
230
- - `filter`: The filter descriptor, or `null` if no filters were added
231
- - `order`: An array of order descriptors, or `null` if no ordering was specified
232
-
233
- **Example:**
234
-
235
- ```typescript
236
- const { filter, order } = query.build();
237
-
238
- // Use with store
239
- const collection = store.from("customer").getCollection({ filter, order });
240
- ```
241
-
242
- ## Examples
243
-
244
- _Note: The following examples use generic type parameters like `Store`, `User`, and `OperatorsMap`. See [Setting Up Your Store](#setting-up-your-store) section above for a complete store setup example._
245
-
246
- ### Simple Filtering
247
-
248
- ```typescript
249
- const query = new ChimeraQueryBuilder<Store, User, OperatorsMap>();
250
-
251
- query
252
- .where("email", "eq", "user@example.com")
253
- .where("active", "eq", true)
254
- .orderBy("createdAt", true);
255
-
256
- const { filter, order } = query.build();
257
- ```
258
-
259
- ### Complex Logical Groups
260
-
261
- ```typescript
262
- const query = new ChimeraQueryBuilder<Store, Post, OperatorsMap>();
263
-
264
- query
265
- // Main AND condition
266
- .where("published", "eq", true)
267
- .where("createdAt", "gte", new Date("2024-01-01"))
268
-
269
- // OR group: (authorId = '123' OR authorId = '456')
270
- .group("or", (q) => {
271
- q.where("authorId", "eq", "123").where("authorId", "eq", "456");
272
- })
273
-
274
- // NOT group: NOT (tags contains 'draft')
275
- .group("not", (q) => {
276
- q.where("tags", "contains", "draft");
277
- })
278
-
279
- .orderBy("createdAt", true)
280
- .orderBy("title"); // Secondary sort
281
-
282
- const { filter, order } = query.build();
283
- ```
284
-
285
- ### Multiple Order Rules
286
-
287
- ```typescript
288
- const query = new ChimeraQueryBuilder<Store, Product, OperatorsMap>();
289
-
290
- query
291
- .where("inStock", "eq", true)
292
- .orderBy("category") // Primary sort: category ascending
293
- .orderBy("price", false) // Secondary sort: price ascending
294
- .orderBy("rating", true) // Tertiary sort: rating descending
295
- .orderBy("name"); // Final sort: name ascending
296
-
297
- const { filter, order } = query.build();
298
- ```
299
-
300
- ### Combining whereNot and Groups
301
-
302
- ```typescript
303
- const query = new ChimeraQueryBuilder<Store, Article, OperatorsMap>();
304
-
305
- query
306
- .where("published", "eq", true)
307
- .whereNot("archived", "eq", true)
308
-
309
- // Either in featured category OR has high views
310
- .group("or", (q) => {
311
- q.where("category", "eq", "featured").where("views", "gte", 1000);
312
- })
313
-
314
- // But NOT in any of these tags
315
- .group("not", (q) => {
316
- q.where("tags", "in", ["spam", "deprecated"]);
317
- })
318
-
319
- .orderBy("publishedAt", true);
320
-
321
- const { filter, order } = query.build();
322
- ```
323
-
324
- ### Empty Query
325
-
326
- ```typescript
327
- const query = new ChimeraQueryBuilder<Store, Entity, OperatorsMap>();
328
-
329
- // Build without any filters or ordering
330
- const { filter, order } = query.build();
331
- // filter: null
332
- // order: null
333
- ```
334
-
335
- ### Chaining Pattern
336
-
337
- All methods return `this`, allowing you to chain operations:
338
-
339
- ```typescript
340
- const query = new ChimeraQueryBuilder<Store, User, OperatorsMap>()
341
- .where("active", "eq", true)
342
- .where("role", "in", ["admin", "moderator"])
343
- .group("or", (q) => {
344
- q.where("age", "gte", 18).where("verified", "eq", true);
345
- })
346
- .orderBy("lastActive", true)
347
- .orderBy("name");
348
-
349
- const descriptor = query.build();
350
- ```
351
-
352
- ## Type Safety
353
-
354
- The `ChimeraQueryBuilder` is fully type-safe. It ensures:
355
-
356
- - Property names must exist on the entity type
357
- - Operator names must exist in the `OperatorsMap`
358
- - Test values match the expected types for each operator
359
- - Property getters are correctly typed
360
-
361
- ```typescript
362
- type User = {
363
- id: string;
364
- name: string;
365
- age: number;
366
- email: string;
367
- };
368
-
369
- type OperatorsMap = {
370
- eq: (value: any) => boolean;
371
- gte: (value: number) => boolean;
372
- in: (value: any[]) => boolean;
373
- };
374
-
375
- const query = new ChimeraQueryBuilder<Store, User, OperatorsMap>();
376
-
377
- // ✅ Valid
378
- query.where("name", "eq", "John");
379
- query.where("age", "gte", 18);
380
- query.where("id", "in", ["1", "2", "3"]);
381
-
382
- // ❌ TypeScript errors
383
- query.where("invalidProperty", "eq", "value"); // Property doesn't exist
384
- query.where("age", "invalidOp", 18); // Operator doesn't exist
385
- query.where("age", "eq", "not a number"); // Wrong type for operator
386
- ```
387
-
388
- ## Integration
389
-
390
- ### With Repository
391
-
392
- ```typescript
393
- const query = new ChimeraQueryBuilder<typeof store, User, OperatorsMap>()
394
- .where("active", "eq", true)
395
- .orderBy("createdAt", true);
396
-
397
- // Use with entity store
398
- const users = userStore.getCollection(query.build());
399
- ```
400
-
401
- ## Notes
402
-
403
- - Multiple `where()` calls are combined with **AND** logic by default
404
- - Use `group('or', ...)` to create OR conditions
405
- - Use `group('not', ...)` or `whereNot()` for negations
406
- - Order rules are applied in the sequence they're added (first = primary sort)
407
- - An empty query builder will return `{ filter: null, order: null }`
1
+ # ChimeraQueryBuilder
2
+
3
+ A type-safe query builder for constructing filters and ordering rules for Chimera Store collections. `ChimeraQueryBuilder` provides a fluent API for building complex queries with support for filtering, ordering, and nested grouping.
4
+
5
+ ## Features
6
+
7
+ - **Type-Safe**: Full TypeScript support with automatic type inference
8
+ - **Fluent API**: Chainable methods for building queries
9
+ - **Complex Filtering**: Support for operators, negations, and grouped conditions
10
+ - **Ordering**: Flexible sorting with null handling options
11
+ - **Nested Groups**: Create complex logical groupings with AND/OR/NOT
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ # Install both the core store and query builder
17
+ npm install @hf-chimera/store @hf-chimera/query-builder
18
+
19
+ # Or with yarn
20
+ yarn add @hf-chimera/store @hf-chimera/query-builder
21
+
22
+ # Or with pnpm
23
+ pnpm add @hf-chimera/store @hf-chimera/query-builder
24
+ ```
25
+
26
+ ## Setting Up Your Store
27
+
28
+ Before using `ChimeraQueryBuilder`, you need to create entity stores. Here's a complete example:
29
+
30
+ ```typescript
31
+ import { createChimeraEntityStore } from "@hf-chimera/store";
32
+
33
+ // Define your entity types
34
+ type Customer = {
35
+ id: number;
36
+ name: string;
37
+ email: string;
38
+ phone: string;
39
+ createdAt: Date;
40
+ };
41
+
42
+ type Order = {
43
+ id: number;
44
+ customerId: number;
45
+ productName: string;
46
+ quantity: number;
47
+ totalAmount: number;
48
+ status: "pending" | "completed" | "cancelled";
49
+ createdAt: Date;
50
+ };
51
+
52
+ // Create entity stores
53
+ export const customerStore = createChimeraEntityStore<"customer", Customer>({
54
+ name: "customer",
55
+ idGetter: "id",
56
+ async collectionFetcher(params, requestParams) {
57
+ const response = await fetch(`/api/customers`, {
58
+ method: "POST",
59
+ headers: { "Content-Type": "application/json" },
60
+ body: JSON.stringify({ filter: params.filter, order: params.order }),
61
+ signal: requestParams.signal,
62
+ });
63
+ return { data: await response.json() };
64
+ },
65
+ async itemCreator(item, requestParams) {
66
+ const response = await fetch(`/api/customers`, {
67
+ method: "POST",
68
+ headers: { "Content-Type": "application/json" },
69
+ body: JSON.stringify(item),
70
+ signal: requestParams.signal,
71
+ });
72
+ return { data: await response.json() };
73
+ },
74
+ async itemUpdater(item, requestParams) {
75
+ const response = await fetch(`/api/customers/${item.id}`, {
76
+ method: "PUT",
77
+ headers: { "Content-Type": "application/json" },
78
+ body: JSON.stringify(item),
79
+ signal: requestParams.signal,
80
+ });
81
+ return { data: await response.json() };
82
+ },
83
+ async itemDeleter(id, requestParams) {
84
+ await fetch(`/api/customers/${id}`, {
85
+ method: "DELETE",
86
+ signal: requestParams.signal,
87
+ });
88
+ return { result: { id, success: true } };
89
+ },
90
+ async itemFetcher(params, requestParams) {
91
+ const response = await fetch(`/api/customers/${params.id}`, {
92
+ signal: requestParams.signal,
93
+ });
94
+ return { data: await response.json() };
95
+ },
96
+ });
97
+
98
+ export const orderStore = createChimeraEntityStore<"order", Order>({
99
+ name: "order",
100
+ idGetter: "id",
101
+ // ... similar CRUD operations
102
+ });
103
+ ```
104
+
105
+ ## Basic Usage
106
+
107
+ ```typescript
108
+ import { ChimeraQueryBuilder } from "@hf-chimera/query-builder";
109
+ import { customerStore } from "./store";
110
+
111
+ // Create a query builder instance
112
+ const query = new ChimeraQueryBuilder<typeof customerStore, Customer, any>();
113
+
114
+ // Build a simple query
115
+ query
116
+ .where("name", "eq", "John")
117
+ .where("age", "gte", 18)
118
+ .orderBy("createdAt", true); // true = descending
119
+
120
+ // Build the query descriptor
121
+ const descriptor = query.build();
122
+ // Returns: { filter: {...}, order: [...] }
123
+
124
+ // Use with entity store
125
+ const customers = customerStore.getCollection(descriptor);
126
+ ```
127
+
128
+ ## API Reference
129
+
130
+ ### `orderBy(key, desc?, nulls?)`
131
+
132
+ Adds an ordering rule to the query.
133
+
134
+ **Parameters:**
135
+
136
+ - `key`: `ChimeraPropertyGetter<Entity> | (keyof Entity & string)` - The property to order by (can be a property name string or a property getter function)
137
+ - `desc`: `boolean` (default: `false`) - Whether to sort in descending order
138
+ - `nulls`: `ChimeraOrderNulls` (default: `ChimeraOrderNulls.Last`) - How to handle null values (`Last` or `First`)
139
+
140
+ **Returns:** `this` - Returns the builder instance for chaining
141
+
142
+ **Example:**
143
+
144
+ ```typescript
145
+ query
146
+ .orderBy("name") // Ascending
147
+ .orderBy("age", true) // Descending
148
+ .orderBy("createdAt", false, ChimeraOrderNulls.First); // Nulls first
149
+ ```
150
+
151
+ ### `where(value, op, test)`
152
+
153
+ Adds a filter condition to the query. Multiple `where` calls are combined with AND logic by default.
154
+
155
+ **Parameters:**
156
+
157
+ - `value`: `ChimeraPropertyGetter<Entity> | (KeysOfType<Entity, T> & string)` - The property to filter on (property name or getter function)
158
+ - `op`: `Op extends keyof OperatorsMap & string` - The operator to use (e.g., `'eq'`, `'gte'`, `'in'`, etc.)
159
+ - `test`: `Parameters<OperatorsMap[Op]>[1]` - The value to compare against (type depends on the operator)
160
+
161
+ **Returns:** `this` - Returns the builder instance for chaining
162
+
163
+ **Example:**
164
+
165
+ ```typescript
166
+ query
167
+ .where("status", "eq", "active")
168
+ .where("age", "gte", 18)
169
+ .where("tags", "in", ["javascript", "typescript"]);
170
+ ```
171
+
172
+ ### `whereNot(value, op, test)`
173
+
174
+ Adds a negated filter condition (NOT condition) to the query.
175
+
176
+ **Parameters:**
177
+
178
+ - `value`: Same as `where()`
179
+ - `op`: Same as `where()`
180
+ - `test`: Same as `where()`
181
+
182
+ **Returns:** `this` - Returns the builder instance for chaining
183
+
184
+ **Example:**
185
+
186
+ ```typescript
187
+ query.where("status", "eq", "active").whereNot("deleted", "eq", true); // NOT deleted = true
188
+ ```
189
+
190
+ ### `group(conjunction, builder)`
191
+
192
+ Creates a grouped condition with a specified logical conjunction. Useful for creating complex logical expressions with AND, OR, or NOT groups.
193
+
194
+ **Parameters:**
195
+
196
+ - `conjunction`: `ChimeraConjunctionType` - The logical operator: `'and'`, `'or'`, or `'not'`
197
+ - `builder`: `QueryBuilderCreator<Store, Entity, OperatorsMap>` - A callback function that receives a new builder instance for building the nested query
198
+
199
+ **Returns:** `this` - Returns the builder instance for chaining
200
+
201
+ **Example:**
202
+
203
+ ```typescript
204
+ // Create an OR group: (status = 'active' OR status = 'pending')
205
+ query.group("or", (q) => {
206
+ q.where("status", "eq", "active").where("status", "eq", "pending");
207
+ });
208
+
209
+ // Create a NOT group: NOT (age < 18 OR deleted = true)
210
+ query.group("not", (q) => {
211
+ q.group("or", (nested) => {
212
+ nested.where("age", "lt", 18).where("deleted", "eq", true);
213
+ });
214
+ });
215
+ ```
216
+
217
+ ### `build()`
218
+
219
+ Builds and returns the final query descriptor object.
220
+
221
+ **Returns:**
222
+
223
+ ```typescript
224
+ {
225
+ filter: ChimeraFilterDescriptor<OperatorsMap, Entity> | null;
226
+ order: (ChimeraOrderDescriptor < Entity > []) | null;
227
+ }
228
+ ```
229
+
230
+ - `filter`: The filter descriptor, or `null` if no filters were added
231
+ - `order`: An array of order descriptors, or `null` if no ordering was specified
232
+
233
+ **Example:**
234
+
235
+ ```typescript
236
+ const { filter, order } = query.build();
237
+
238
+ // Use with store
239
+ const collection = store.from("customer").getCollection({ filter, order });
240
+ ```
241
+
242
+ ## Examples
243
+
244
+ _Note: The following examples use generic type parameters like `Store`, `User`, and `OperatorsMap`. See [Setting Up Your Store](#setting-up-your-store) section above for a complete store setup example._
245
+
246
+ ### Simple Filtering
247
+
248
+ ```typescript
249
+ const query = new ChimeraQueryBuilder<Store, User, OperatorsMap>();
250
+
251
+ query
252
+ .where("email", "eq", "user@example.com")
253
+ .where("active", "eq", true)
254
+ .orderBy("createdAt", true);
255
+
256
+ const { filter, order } = query.build();
257
+ ```
258
+
259
+ ### Complex Logical Groups
260
+
261
+ ```typescript
262
+ const query = new ChimeraQueryBuilder<Store, Post, OperatorsMap>();
263
+
264
+ query
265
+ // Main AND condition
266
+ .where("published", "eq", true)
267
+ .where("createdAt", "gte", new Date("2024-01-01"))
268
+
269
+ // OR group: (authorId = '123' OR authorId = '456')
270
+ .group("or", (q) => {
271
+ q.where("authorId", "eq", "123").where("authorId", "eq", "456");
272
+ })
273
+
274
+ // NOT group: NOT (tags contains 'draft')
275
+ .group("not", (q) => {
276
+ q.where("tags", "contains", "draft");
277
+ })
278
+
279
+ .orderBy("createdAt", true)
280
+ .orderBy("title"); // Secondary sort
281
+
282
+ const { filter, order } = query.build();
283
+ ```
284
+
285
+ ### Multiple Order Rules
286
+
287
+ ```typescript
288
+ const query = new ChimeraQueryBuilder<Store, Product, OperatorsMap>();
289
+
290
+ query
291
+ .where("inStock", "eq", true)
292
+ .orderBy("category") // Primary sort: category ascending
293
+ .orderBy("price", false) // Secondary sort: price ascending
294
+ .orderBy("rating", true) // Tertiary sort: rating descending
295
+ .orderBy("name"); // Final sort: name ascending
296
+
297
+ const { filter, order } = query.build();
298
+ ```
299
+
300
+ ### Combining whereNot and Groups
301
+
302
+ ```typescript
303
+ const query = new ChimeraQueryBuilder<Store, Article, OperatorsMap>();
304
+
305
+ query
306
+ .where("published", "eq", true)
307
+ .whereNot("archived", "eq", true)
308
+
309
+ // Either in featured category OR has high views
310
+ .group("or", (q) => {
311
+ q.where("category", "eq", "featured").where("views", "gte", 1000);
312
+ })
313
+
314
+ // But NOT in any of these tags
315
+ .group("not", (q) => {
316
+ q.where("tags", "in", ["spam", "deprecated"]);
317
+ })
318
+
319
+ .orderBy("publishedAt", true);
320
+
321
+ const { filter, order } = query.build();
322
+ ```
323
+
324
+ ### Empty Query
325
+
326
+ ```typescript
327
+ const query = new ChimeraQueryBuilder<Store, Entity, OperatorsMap>();
328
+
329
+ // Build without any filters or ordering
330
+ const { filter, order } = query.build();
331
+ // filter: null
332
+ // order: null
333
+ ```
334
+
335
+ ### Chaining Pattern
336
+
337
+ All methods return `this`, allowing you to chain operations:
338
+
339
+ ```typescript
340
+ const query = new ChimeraQueryBuilder<Store, User, OperatorsMap>()
341
+ .where("active", "eq", true)
342
+ .where("role", "in", ["admin", "moderator"])
343
+ .group("or", (q) => {
344
+ q.where("age", "gte", 18).where("verified", "eq", true);
345
+ })
346
+ .orderBy("lastActive", true)
347
+ .orderBy("name");
348
+
349
+ const descriptor = query.build();
350
+ ```
351
+
352
+ ## Type Safety
353
+
354
+ The `ChimeraQueryBuilder` is fully type-safe. It ensures:
355
+
356
+ - Property names must exist on the entity type
357
+ - Operator names must exist in the `OperatorsMap`
358
+ - Test values match the expected types for each operator
359
+ - Property getters are correctly typed
360
+
361
+ ```typescript
362
+ type User = {
363
+ id: string;
364
+ name: string;
365
+ age: number;
366
+ email: string;
367
+ };
368
+
369
+ type OperatorsMap = {
370
+ eq: (value: any) => boolean;
371
+ gte: (value: number) => boolean;
372
+ in: (value: any[]) => boolean;
373
+ };
374
+
375
+ const query = new ChimeraQueryBuilder<Store, User, OperatorsMap>();
376
+
377
+ // ✅ Valid
378
+ query.where("name", "eq", "John");
379
+ query.where("age", "gte", 18);
380
+ query.where("id", "in", ["1", "2", "3"]);
381
+
382
+ // ❌ TypeScript errors
383
+ query.where("invalidProperty", "eq", "value"); // Property doesn't exist
384
+ query.where("age", "invalidOp", 18); // Operator doesn't exist
385
+ query.where("age", "eq", "not a number"); // Wrong type for operator
386
+ ```
387
+
388
+ ## Integration
389
+
390
+ ### With Repository
391
+
392
+ ```typescript
393
+ const query = new ChimeraQueryBuilder<typeof store, User, OperatorsMap>()
394
+ .where("active", "eq", true)
395
+ .orderBy("createdAt", true);
396
+
397
+ // Use with entity store
398
+ const users = userStore.getCollection(query.build());
399
+ ```
400
+
401
+ ## Notes
402
+
403
+ - Multiple `where()` calls are combined with **AND** logic by default
404
+ - Use `group('or', ...)` to create OR conditions
405
+ - Use `group('not', ...)` or `whereNot()` for negations
406
+ - Order rules are applied in the sequence they're added (first = primary sort)
407
+ - An empty query builder will return `{ filter: null, order: null }`
package/dist/index.cjs CHANGED
@@ -44,6 +44,13 @@ var DefaultChimeraQueryBuilder = class {
44
44
  }
45
45
  };
46
46
 
47
+ //#endregion
48
+ //#region factory.ts
49
+ function createDefaultQueryBuilder() {
50
+ return new DefaultChimeraQueryBuilder();
51
+ }
52
+
47
53
  //#endregion
48
54
  exports.DefaultChimeraQueryBuilder = DefaultChimeraQueryBuilder;
55
+ exports.createDefaultQueryBuilder = createDefaultQueryBuilder;
49
56
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["ChimeraOrderNulls"],"sources":["../DefaultChimeraQueryBuilder.ts"],"sourcesContent":["import {\n\ttype AnyChimeraEntityStore,\n\ttype ChimeraConjunctionDescriptor,\n\ttype ChimeraConjunctionOperationDescriptor,\n\ttype ChimeraConjunctionType,\n\ttype ChimeraEntityStoreEntity,\n\ttype ChimeraEntityStoreOperatorsMap,\n\ttype ChimeraFilterDescriptor,\n\ttype ChimeraOrderDescriptor,\n\tChimeraOrderNulls,\n\ttype ChimeraPropertyGetter,\n\ttype Constructable,\n\tchimeraCreateConjunction,\n\tchimeraCreateNot,\n\tchimeraCreateOperator,\n\tchimeraCreateOrderBy,\n\ttype KeysOfType,\n} from \"@hf-chimera/store\";\nimport type { ChimeraQueryBuilder, QueryBuilderCreator } from \"./types\";\n\nexport class DefaultChimeraQueryBuilder<\n\tTStore extends AnyChimeraEntityStore,\n\tTEntity extends ChimeraEntityStoreEntity<TStore> = ChimeraEntityStoreEntity<TStore>,\n\tTOperatorsMap extends ChimeraEntityStoreOperatorsMap<TStore> = ChimeraEntityStoreOperatorsMap<TStore>,\n> implements ChimeraQueryBuilder<TStore>\n{\n\tprivate orderRules: ChimeraOrderDescriptor<TEntity>[] = [];\n\n\tisChimeraQueryBuilder: true = true;\n\n\tcreate(): this {\n\t\treturn new (this.constructor as Constructable)();\n\t}\n\n\torderBy(\n\t\tkey: ChimeraPropertyGetter<TEntity> | (keyof TEntity & string),\n\t\tdesc = false,\n\t\tnulls: ChimeraOrderNulls = ChimeraOrderNulls.Last,\n\t): this {\n\t\tthis.orderRules.push(chimeraCreateOrderBy<TEntity>(key, desc, nulls));\n\t\treturn this;\n\t}\n\n\tprivate filters: ChimeraConjunctionOperationDescriptor<TOperatorsMap, TEntity>[] = [];\n\tprivate rootConjunction: Exclude<ChimeraConjunctionType, \"not\"> = \"and\";\n\n\tprivate conjunction(type: Exclude<ChimeraConjunctionType, \"not\">) {\n\t\tthis.rootConjunction = type;\n\t}\n\n\tprivate buildFilter(): ChimeraConjunctionDescriptor<TOperatorsMap, TEntity> | null {\n\t\treturn this.filters.length\n\t\t\t? chimeraCreateConjunction<TEntity, TOperatorsMap>(this.rootConjunction, this.filters)\n\t\t\t: null;\n\t}\n\n\twhere<Op extends keyof TOperatorsMap & string>(\n\t\tvalue:\n\t\t\t| ChimeraPropertyGetter<TEntity, Parameters<TOperatorsMap[Op]>[0]>\n\t\t\t| (KeysOfType<TEntity, Parameters<TOperatorsMap[Op]>[0]> & string),\n\t\top: Op,\n\t\ttest: Parameters<TOperatorsMap[Op]>[1],\n\t): this {\n\t\tthis.filters.push(chimeraCreateOperator<TEntity, TOperatorsMap, Op>(op, value, test));\n\t\treturn this;\n\t}\n\n\tgroup(conjunction: ChimeraConjunctionType, builder: QueryBuilderCreator<TStore, this>): this {\n\t\tconst isNot = conjunction === \"not\";\n\t\tconst nestedBuilder = this.create();\n\n\t\t!isNot && nestedBuilder.conjunction(conjunction);\n\n\t\tbuilder(nestedBuilder);\n\n\t\tconst nestedQuery = nestedBuilder.buildFilter();\n\t\tnestedQuery && this.filters.push(isNot ? chimeraCreateNot<TEntity, TOperatorsMap>(nestedQuery) : nestedQuery);\n\n\t\treturn this;\n\t}\n\n\twhereNot<Op extends keyof TOperatorsMap & string>(\n\t\tvalue:\n\t\t\t| ChimeraPropertyGetter<TEntity, Parameters<TOperatorsMap[Op]>[0]>\n\t\t\t| (KeysOfType<TEntity, Parameters<TOperatorsMap[Op]>[0]> & string),\n\t\top: Op,\n\t\ttest: Parameters<TOperatorsMap[Op]>[1],\n\t): this {\n\t\tthis.filters.push(\n\t\t\tchimeraCreateNot<TEntity, TOperatorsMap>(chimeraCreateOperator<TEntity, TOperatorsMap, Op>(op, value, test)),\n\t\t);\n\t\treturn this;\n\t}\n\n\tbuild(): {\n\t\tfilter: ChimeraFilterDescriptor<TOperatorsMap, TEntity> | null;\n\t\torder: ChimeraOrderDescriptor<TEntity>[] | null;\n\t} {\n\t\treturn {\n\t\t\tfilter: this.buildFilter(),\n\t\t\torder: this.orderRules.length ? this.orderRules : null,\n\t\t};\n\t}\n}\n"],"mappings":";;;AAoBA,IAAa,6BAAb,MAKA;CACC,AAAQ,aAAgD,EAAE;CAE1D,wBAA8B;CAE9B,SAAe;AACd,SAAO,IAAK,KAAK,aAA+B;;CAGjD,QACC,KACA,OAAO,OACP,QAA2BA,oCAAkB,MACtC;AACP,OAAK,WAAW,iDAAmC,KAAK,MAAM,MAAM,CAAC;AACrE,SAAO;;CAGR,AAAQ,UAA2E,EAAE;CACrF,AAAQ,kBAA0D;CAElE,AAAQ,YAAY,MAA8C;AACjE,OAAK,kBAAkB;;CAGxB,AAAQ,cAA2E;AAClF,SAAO,KAAK,QAAQ,yDACgC,KAAK,iBAAiB,KAAK,QAAQ,GACpF;;CAGJ,MACC,OAGA,IACA,MACO;AACP,OAAK,QAAQ,kDAAuD,IAAI,OAAO,KAAK,CAAC;AACrF,SAAO;;CAGR,MAAM,aAAqC,SAAkD;EAC5F,MAAM,QAAQ,gBAAgB;EAC9B,MAAM,gBAAgB,KAAK,QAAQ;AAEnC,GAAC,SAAS,cAAc,YAAY,YAAY;AAEhD,UAAQ,cAAc;EAEtB,MAAM,cAAc,cAAc,aAAa;AAC/C,iBAAe,KAAK,QAAQ,KAAK,gDAAiD,YAAY,GAAG,YAAY;AAE7G,SAAO;;CAGR,SACC,OAGA,IACA,MACO;AACP,OAAK,QAAQ,0FAC+E,IAAI,OAAO,KAAK,CAAC,CAC5G;AACD,SAAO;;CAGR,QAGE;AACD,SAAO;GACN,QAAQ,KAAK,aAAa;GAC1B,OAAO,KAAK,WAAW,SAAS,KAAK,aAAa;GAClD"}
1
+ {"version":3,"file":"index.cjs","names":["ChimeraOrderNulls"],"sources":["../DefaultChimeraQueryBuilder.ts","../factory.ts"],"sourcesContent":["import {\n\ttype AnyChimeraEntityStore,\n\ttype ChimeraConjunctionDescriptor,\n\ttype ChimeraConjunctionOperationDescriptor,\n\ttype ChimeraConjunctionType,\n\ttype ChimeraEntityStoreEntity,\n\ttype ChimeraEntityStoreOperatorsMap,\n\ttype ChimeraFilterDescriptor,\n\ttype ChimeraOrderDescriptor,\n\tChimeraOrderNulls,\n\ttype ChimeraPropertyGetter,\n\ttype Constructable,\n\tchimeraCreateConjunction,\n\tchimeraCreateNot,\n\tchimeraCreateOperator,\n\tchimeraCreateOrderBy,\n\ttype KeysOfType,\n} from \"@hf-chimera/store\";\nimport type { ChimeraQueryBuilder, QueryBuilderCreator } from \"./types\";\n\nexport class DefaultChimeraQueryBuilder<\n\tTStore extends AnyChimeraEntityStore,\n\tTEntity extends ChimeraEntityStoreEntity<TStore> = ChimeraEntityStoreEntity<TStore>,\n\tTOperatorsMap extends ChimeraEntityStoreOperatorsMap<TStore> = ChimeraEntityStoreOperatorsMap<TStore>,\n> implements ChimeraQueryBuilder<TStore>\n{\n\tprivate orderRules: ChimeraOrderDescriptor<TEntity>[] = [];\n\n\tisChimeraQueryBuilder: true = true;\n\n\tcreate(): this {\n\t\treturn new (this.constructor as Constructable)();\n\t}\n\n\torderBy(\n\t\tkey: ChimeraPropertyGetter<TEntity> | (keyof TEntity & string),\n\t\tdesc = false,\n\t\tnulls: ChimeraOrderNulls = ChimeraOrderNulls.Last,\n\t): this {\n\t\tthis.orderRules.push(chimeraCreateOrderBy<TEntity>(key, desc, nulls));\n\t\treturn this;\n\t}\n\n\tprivate filters: ChimeraConjunctionOperationDescriptor<TOperatorsMap, TEntity>[] = [];\n\tprivate rootConjunction: Exclude<ChimeraConjunctionType, \"not\"> = \"and\";\n\n\tprivate conjunction(type: Exclude<ChimeraConjunctionType, \"not\">) {\n\t\tthis.rootConjunction = type;\n\t}\n\n\tprivate buildFilter(): ChimeraConjunctionDescriptor<TOperatorsMap, TEntity> | null {\n\t\treturn this.filters.length\n\t\t\t? chimeraCreateConjunction<TEntity, TOperatorsMap>(this.rootConjunction, this.filters)\n\t\t\t: null;\n\t}\n\n\twhere<Op extends keyof TOperatorsMap & string>(\n\t\tvalue:\n\t\t\t| ChimeraPropertyGetter<TEntity, Parameters<TOperatorsMap[Op]>[0]>\n\t\t\t| (KeysOfType<TEntity, Parameters<TOperatorsMap[Op]>[0]> & string),\n\t\top: Op,\n\t\ttest: Parameters<TOperatorsMap[Op]>[1],\n\t): this {\n\t\tthis.filters.push(chimeraCreateOperator<TEntity, TOperatorsMap, Op>(op, value, test));\n\t\treturn this;\n\t}\n\n\tgroup(conjunction: ChimeraConjunctionType, builder: QueryBuilderCreator<TStore, this>): this {\n\t\tconst isNot = conjunction === \"not\";\n\t\tconst nestedBuilder = this.create();\n\n\t\t!isNot && nestedBuilder.conjunction(conjunction);\n\n\t\tbuilder(nestedBuilder);\n\n\t\tconst nestedQuery = nestedBuilder.buildFilter();\n\t\tnestedQuery && this.filters.push(isNot ? chimeraCreateNot<TEntity, TOperatorsMap>(nestedQuery) : nestedQuery);\n\n\t\treturn this;\n\t}\n\n\twhereNot<Op extends keyof TOperatorsMap & string>(\n\t\tvalue:\n\t\t\t| ChimeraPropertyGetter<TEntity, Parameters<TOperatorsMap[Op]>[0]>\n\t\t\t| (KeysOfType<TEntity, Parameters<TOperatorsMap[Op]>[0]> & string),\n\t\top: Op,\n\t\ttest: Parameters<TOperatorsMap[Op]>[1],\n\t): this {\n\t\tthis.filters.push(\n\t\t\tchimeraCreateNot<TEntity, TOperatorsMap>(chimeraCreateOperator<TEntity, TOperatorsMap, Op>(op, value, test)),\n\t\t);\n\t\treturn this;\n\t}\n\n\tbuild(): {\n\t\tfilter: ChimeraFilterDescriptor<TOperatorsMap, TEntity> | null;\n\t\torder: ChimeraOrderDescriptor<TEntity>[] | null;\n\t} {\n\t\treturn {\n\t\t\tfilter: this.buildFilter(),\n\t\t\torder: this.orderRules.length ? this.orderRules : null,\n\t\t};\n\t}\n}\n","import type { AnyChimeraEntityStore } from \"@hf-chimera/store\";\nimport { DefaultChimeraQueryBuilder } from \"./DefaultChimeraQueryBuilder\";\n\nexport function createDefaultQueryBuilder<TStore extends AnyChimeraEntityStore>(): DefaultChimeraQueryBuilder<TStore> {\n\treturn new DefaultChimeraQueryBuilder<TStore>();\n}\n"],"mappings":";;;AAoBA,IAAa,6BAAb,MAKA;CACC,AAAQ,aAAgD,EAAE;CAE1D,wBAA8B;CAE9B,SAAe;AACd,SAAO,IAAK,KAAK,aAA+B;;CAGjD,QACC,KACA,OAAO,OACP,QAA2BA,oCAAkB,MACtC;AACP,OAAK,WAAW,iDAAmC,KAAK,MAAM,MAAM,CAAC;AACrE,SAAO;;CAGR,AAAQ,UAA2E,EAAE;CACrF,AAAQ,kBAA0D;CAElE,AAAQ,YAAY,MAA8C;AACjE,OAAK,kBAAkB;;CAGxB,AAAQ,cAA2E;AAClF,SAAO,KAAK,QAAQ,yDACgC,KAAK,iBAAiB,KAAK,QAAQ,GACpF;;CAGJ,MACC,OAGA,IACA,MACO;AACP,OAAK,QAAQ,kDAAuD,IAAI,OAAO,KAAK,CAAC;AACrF,SAAO;;CAGR,MAAM,aAAqC,SAAkD;EAC5F,MAAM,QAAQ,gBAAgB;EAC9B,MAAM,gBAAgB,KAAK,QAAQ;AAEnC,GAAC,SAAS,cAAc,YAAY,YAAY;AAEhD,UAAQ,cAAc;EAEtB,MAAM,cAAc,cAAc,aAAa;AAC/C,iBAAe,KAAK,QAAQ,KAAK,gDAAiD,YAAY,GAAG,YAAY;AAE7G,SAAO;;CAGR,SACC,OAGA,IACA,MACO;AACP,OAAK,QAAQ,0FAC+E,IAAI,OAAO,KAAK,CAAC,CAC5G;AACD,SAAO;;CAGR,QAGE;AACD,SAAO;GACN,QAAQ,KAAK,aAAa;GAC1B,OAAO,KAAK,WAAW,SAAS,KAAK,aAAa;GAClD;;;;;;AClGH,SAAgB,4BAAsG;AACrH,QAAO,IAAI,4BAAoC"}
package/dist/index.d.cts CHANGED
@@ -30,5 +30,8 @@ declare class DefaultChimeraQueryBuilder<TStore extends AnyChimeraEntityStore, T
30
30
  };
31
31
  }
32
32
  //#endregion
33
- export { type ChimeraQueryBuilder, DefaultChimeraQueryBuilder, type QueryBuilderCreator };
33
+ //#region factory.d.ts
34
+ declare function createDefaultQueryBuilder<TStore extends AnyChimeraEntityStore>(): DefaultChimeraQueryBuilder<TStore>;
35
+ //#endregion
36
+ export { type ChimeraQueryBuilder, DefaultChimeraQueryBuilder, type QueryBuilderCreator, createDefaultQueryBuilder };
34
37
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../types.ts","../DefaultChimeraQueryBuilder.ts"],"sourcesContent":[],"mappings":";;;UASiB,mCAAmC;;EAAnC,MAAA,EAAA,EAAA,IAAA;EAAmC,KAAA,EAAA,EAAA;IAMa,MAAA,EAAvD,uBAAuD,CAA/B,8BAA+B,CAAA,MAAA,CAAA,EAAS,wBAAT,CAAkC,MAAlC,CAAA,CAAA,GAAA,IAAA;IAA/B,KAAA,EACzB,sBADyB,CACF,wBADE,CACuB,MADvB,CAAA,CAAA,EAAA,GAAA,IAAA;EAAiE,CAAA;;AAAzF,KAKE,mBALF,CAAA,eAMM,qBANN,EAAA,sBAOa,mBAPb,CAOiC,MAPjC,CAAA,GAO2C,mBAP3C,CAO+D,MAP/D,CAAA,CAAA,GAAA,CAAA,CAAA,EAQF,aARE,EAAA,GAQgB,OARhB,CAQwB,mBARxB,CAQ4C,MAR5C,CAAA,CAAA;;;cCKG,0CACG,uCACC,yBAAyB,UAAU,yBAAyB,+BACtD,+BAA+B,UAAU,+BAA+B,oBAClF,oBAAoB;EDfhB,QAAA,UAAA;EAAmC,qBAAA,EAAA,IAAA;EAMa,MAAA,CAAA,CAAA,EAAA,IAAA;EAA/B,OAAA,CAAA,GAAA,ECoB3B,qBDpB2B,CCoBL,ODpBK,CAAA,GAAA,CAAA,MCoBa,ODpBb,GAAA,MAAA,CAAA,EAAA,IAAA,CAAA,EAAA,OAAA,EAAA,KAAA,CAAA,ECsBzB,iBDtByB,CAAA,EAAA,IAAA;EAAiE,QAAA,OAAA;EAAzB,QAAA,eAAA;EAAhE,QAAA,WAAA;EAC+C,QAAA,WAAA;EAAzB,KAAA,CAAA,WAAA,MCwCR,aDxCQ,GAAA,MAAA,CAAA,CAAA,KAAA,EC0C3B,qBD1C2B,CC0CL,OD1CK,EC0CI,UD1CJ,CC0Ce,aD1Cf,CC0C6B,ED1C7B,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CC2C1B,UD3C0B,CC2Cf,OD3Ce,EC2CN,UD3CM,CC2CK,aD3CL,CC2CmB,ED3CnB,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,MAAA,CAAA,EAAA,EAAA,EC4C1B,ED5C0B,EAAA,IAAA,EC6CxB,UD7CwB,CC6Cb,aD7Ca,CC6CC,ED7CD,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,IAAA;EAAvB,KAAA,CAAA,WAAA,ECmDW,sBDnDX,EAAA,OAAA,ECmD4C,mBDnD5C,CCmDgE,MDnDhE,EAAA,IAAA,CAAA,CAAA,EAAA,IAAA;EAAsB,QAAA,CAAA,WAAA,MCiEJ,aDjEI,GAAA,MAAA,CAAA,CAAA,KAAA,ECmE1B,qBDnE0B,CCmEJ,ODnEI,ECmEK,UDnEL,CCmEgB,aDnEhB,CCmE8B,EDnE9B,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CCoEzB,UDpEyB,CCoEd,ODpEc,ECoEL,UDpEK,CCoEM,aDpEN,CCoEoB,EDpEpB,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,MAAA,CAAA,EAAA,EAAA,ECqEzB,EDrEyB,EAAA,IAAA,ECsEvB,UDtEuB,CCsEZ,aDtEY,CCsEE,EDtEF,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,IAAA;EAInB,KAAA,CAAA,CAAA,EAAA;IACI,MAAA,EC0EN,uBD1EM,CC0EkB,aD1ElB,EC0EiC,OD1EjC,CAAA,GAAA,IAAA;IAC2B,KAAA,EC0ElC,sBD1EkC,CC0EX,OD1EW,CAAA,EAAA,GAAA,IAAA;EAApB,CAAA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../types.ts","../DefaultChimeraQueryBuilder.ts","../factory.ts"],"sourcesContent":[],"mappings":";;;UASiB,mCAAmC;;EAAnC,MAAA,EAAA,EAAA,IAAA;EAAmC,KAAA,EAAA,EAAA;IAMa,MAAA,EAAvD,uBAAuD,CAA/B,8BAA+B,CAAA,MAAA,CAAA,EAAS,wBAAT,CAAkC,MAAlC,CAAA,CAAA,GAAA,IAAA;IAA/B,KAAA,EACzB,sBADyB,CACF,wBADE,CACuB,MADvB,CAAA,CAAA,EAAA,GAAA,IAAA;EAAiE,CAAA;;AAAzF,KAKE,mBALF,CAAA,eAMM,qBANN,EAAA,sBAOa,mBAPb,CAOiC,MAPjC,CAAA,GAO2C,mBAP3C,CAO+D,MAP/D,CAAA,CAAA,GAAA,CAAA,CAAA,EAQF,aARE,EAAA,GAQgB,OARhB,CAQwB,mBARxB,CAQ4C,MAR5C,CAAA,CAAA;;;cCKG,0CACG,uCACC,yBAAyB,UAAU,yBAAyB,+BACtD,+BAA+B,UAAU,+BAA+B,oBAClF,oBAAoB;EDfhB,QAAA,UAAA;EAAmC,qBAAA,EAAA,IAAA;EAMa,MAAA,CAAA,CAAA,EAAA,IAAA;EAA/B,OAAA,CAAA,GAAA,ECoB3B,qBDpB2B,CCoBL,ODpBK,CAAA,GAAA,CAAA,MCoBa,ODpBb,GAAA,MAAA,CAAA,EAAA,IAAA,CAAA,EAAA,OAAA,EAAA,KAAA,CAAA,ECsBzB,iBDtByB,CAAA,EAAA,IAAA;EAAiE,QAAA,OAAA;EAAzB,QAAA,eAAA;EAAhE,QAAA,WAAA;EAC+C,QAAA,WAAA;EAAzB,KAAA,CAAA,WAAA,MCwCR,aDxCQ,GAAA,MAAA,CAAA,CAAA,KAAA,EC0C3B,qBD1C2B,CC0CL,OD1CK,EC0CI,UD1CJ,CC0Ce,aD1Cf,CC0C6B,ED1C7B,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CC2C1B,UD3C0B,CC2Cf,OD3Ce,EC2CN,UD3CM,CC2CK,aD3CL,CC2CmB,ED3CnB,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,MAAA,CAAA,EAAA,EAAA,EC4C1B,ED5C0B,EAAA,IAAA,EC6CxB,UD7CwB,CC6Cb,aD7Ca,CC6CC,ED7CD,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,IAAA;EAAvB,KAAA,CAAA,WAAA,ECmDW,sBDnDX,EAAA,OAAA,ECmD4C,mBDnD5C,CCmDgE,MDnDhE,EAAA,IAAA,CAAA,CAAA,EAAA,IAAA;EAAsB,QAAA,CAAA,WAAA,MCiEJ,aDjEI,GAAA,MAAA,CAAA,CAAA,KAAA,ECmE1B,qBDnE0B,CCmEJ,ODnEI,ECmEK,UDnEL,CCmEgB,aDnEhB,CCmE8B,EDnE9B,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CCoEzB,UDpEyB,CCoEd,ODpEc,ECoEL,UDpEK,CCoEM,aDpEN,CCoEoB,EDpEpB,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,MAAA,CAAA,EAAA,EAAA,ECqEzB,EDrEyB,EAAA,IAAA,ECsEvB,UDtEuB,CCsEZ,aDtEY,CCsEE,EDtEF,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,IAAA;EAInB,KAAA,CAAA,CAAA,EAAA;IACI,MAAA,EC0EN,uBD1EM,CC0EkB,aD1ElB,EC0EiC,OD1EjC,CAAA,GAAA,IAAA;IAC2B,KAAA,EC0ElC,sBD1EkC,CC0EX,OD1EW,CAAA,EAAA,GAAA,IAAA;EAApB,CAAA;;;;iBEnBP,yCAAyC,0BAA0B,2BAA2B"}
package/dist/index.d.mts CHANGED
@@ -30,5 +30,8 @@ declare class DefaultChimeraQueryBuilder<TStore extends AnyChimeraEntityStore, T
30
30
  };
31
31
  }
32
32
  //#endregion
33
- export { type ChimeraQueryBuilder, DefaultChimeraQueryBuilder, type QueryBuilderCreator };
33
+ //#region factory.d.ts
34
+ declare function createDefaultQueryBuilder<TStore extends AnyChimeraEntityStore>(): DefaultChimeraQueryBuilder<TStore>;
35
+ //#endregion
36
+ export { type ChimeraQueryBuilder, DefaultChimeraQueryBuilder, type QueryBuilderCreator, createDefaultQueryBuilder };
34
37
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../types.ts","../DefaultChimeraQueryBuilder.ts"],"sourcesContent":[],"mappings":";;;UASiB,mCAAmC;;EAAnC,MAAA,EAAA,EAAA,IAAA;EAAmC,KAAA,EAAA,EAAA;IAMa,MAAA,EAAvD,uBAAuD,CAA/B,8BAA+B,CAAA,MAAA,CAAA,EAAS,wBAAT,CAAkC,MAAlC,CAAA,CAAA,GAAA,IAAA;IAA/B,KAAA,EACzB,sBADyB,CACF,wBADE,CACuB,MADvB,CAAA,CAAA,EAAA,GAAA,IAAA;EAAiE,CAAA;;AAAzF,KAKE,mBALF,CAAA,eAMM,qBANN,EAAA,sBAOa,mBAPb,CAOiC,MAPjC,CAAA,GAO2C,mBAP3C,CAO+D,MAP/D,CAAA,CAAA,GAAA,CAAA,CAAA,EAQF,aARE,EAAA,GAQgB,OARhB,CAQwB,mBARxB,CAQ4C,MAR5C,CAAA,CAAA;;;cCKG,0CACG,uCACC,yBAAyB,UAAU,yBAAyB,+BACtD,+BAA+B,UAAU,+BAA+B,oBAClF,oBAAoB;EDfhB,QAAA,UAAA;EAAmC,qBAAA,EAAA,IAAA;EAMa,MAAA,CAAA,CAAA,EAAA,IAAA;EAA/B,OAAA,CAAA,GAAA,ECoB3B,qBDpB2B,CCoBL,ODpBK,CAAA,GAAA,CAAA,MCoBa,ODpBb,GAAA,MAAA,CAAA,EAAA,IAAA,CAAA,EAAA,OAAA,EAAA,KAAA,CAAA,ECsBzB,iBDtByB,CAAA,EAAA,IAAA;EAAiE,QAAA,OAAA;EAAzB,QAAA,eAAA;EAAhE,QAAA,WAAA;EAC+C,QAAA,WAAA;EAAzB,KAAA,CAAA,WAAA,MCwCR,aDxCQ,GAAA,MAAA,CAAA,CAAA,KAAA,EC0C3B,qBD1C2B,CC0CL,OD1CK,EC0CI,UD1CJ,CC0Ce,aD1Cf,CC0C6B,ED1C7B,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CC2C1B,UD3C0B,CC2Cf,OD3Ce,EC2CN,UD3CM,CC2CK,aD3CL,CC2CmB,ED3CnB,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,MAAA,CAAA,EAAA,EAAA,EC4C1B,ED5C0B,EAAA,IAAA,EC6CxB,UD7CwB,CC6Cb,aD7Ca,CC6CC,ED7CD,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,IAAA;EAAvB,KAAA,CAAA,WAAA,ECmDW,sBDnDX,EAAA,OAAA,ECmD4C,mBDnD5C,CCmDgE,MDnDhE,EAAA,IAAA,CAAA,CAAA,EAAA,IAAA;EAAsB,QAAA,CAAA,WAAA,MCiEJ,aDjEI,GAAA,MAAA,CAAA,CAAA,KAAA,ECmE1B,qBDnE0B,CCmEJ,ODnEI,ECmEK,UDnEL,CCmEgB,aDnEhB,CCmE8B,EDnE9B,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CCoEzB,UDpEyB,CCoEd,ODpEc,ECoEL,UDpEK,CCoEM,aDpEN,CCoEoB,EDpEpB,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,MAAA,CAAA,EAAA,EAAA,ECqEzB,EDrEyB,EAAA,IAAA,ECsEvB,UDtEuB,CCsEZ,aDtEY,CCsEE,EDtEF,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,IAAA;EAInB,KAAA,CAAA,CAAA,EAAA;IACI,MAAA,EC0EN,uBD1EM,CC0EkB,aD1ElB,EC0EiC,OD1EjC,CAAA,GAAA,IAAA;IAC2B,KAAA,EC0ElC,sBD1EkC,CC0EX,OD1EW,CAAA,EAAA,GAAA,IAAA;EAApB,CAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../types.ts","../DefaultChimeraQueryBuilder.ts","../factory.ts"],"sourcesContent":[],"mappings":";;;UASiB,mCAAmC;;EAAnC,MAAA,EAAA,EAAA,IAAA;EAAmC,KAAA,EAAA,EAAA;IAMa,MAAA,EAAvD,uBAAuD,CAA/B,8BAA+B,CAAA,MAAA,CAAA,EAAS,wBAAT,CAAkC,MAAlC,CAAA,CAAA,GAAA,IAAA;IAA/B,KAAA,EACzB,sBADyB,CACF,wBADE,CACuB,MADvB,CAAA,CAAA,EAAA,GAAA,IAAA;EAAiE,CAAA;;AAAzF,KAKE,mBALF,CAAA,eAMM,qBANN,EAAA,sBAOa,mBAPb,CAOiC,MAPjC,CAAA,GAO2C,mBAP3C,CAO+D,MAP/D,CAAA,CAAA,GAAA,CAAA,CAAA,EAQF,aARE,EAAA,GAQgB,OARhB,CAQwB,mBARxB,CAQ4C,MAR5C,CAAA,CAAA;;;cCKG,0CACG,uCACC,yBAAyB,UAAU,yBAAyB,+BACtD,+BAA+B,UAAU,+BAA+B,oBAClF,oBAAoB;EDfhB,QAAA,UAAA;EAAmC,qBAAA,EAAA,IAAA;EAMa,MAAA,CAAA,CAAA,EAAA,IAAA;EAA/B,OAAA,CAAA,GAAA,ECoB3B,qBDpB2B,CCoBL,ODpBK,CAAA,GAAA,CAAA,MCoBa,ODpBb,GAAA,MAAA,CAAA,EAAA,IAAA,CAAA,EAAA,OAAA,EAAA,KAAA,CAAA,ECsBzB,iBDtByB,CAAA,EAAA,IAAA;EAAiE,QAAA,OAAA;EAAzB,QAAA,eAAA;EAAhE,QAAA,WAAA;EAC+C,QAAA,WAAA;EAAzB,KAAA,CAAA,WAAA,MCwCR,aDxCQ,GAAA,MAAA,CAAA,CAAA,KAAA,EC0C3B,qBD1C2B,CC0CL,OD1CK,EC0CI,UD1CJ,CC0Ce,aD1Cf,CC0C6B,ED1C7B,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CC2C1B,UD3C0B,CC2Cf,OD3Ce,EC2CN,UD3CM,CC2CK,aD3CL,CC2CmB,ED3CnB,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,MAAA,CAAA,EAAA,EAAA,EC4C1B,ED5C0B,EAAA,IAAA,EC6CxB,UD7CwB,CC6Cb,aD7Ca,CC6CC,ED7CD,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,IAAA;EAAvB,KAAA,CAAA,WAAA,ECmDW,sBDnDX,EAAA,OAAA,ECmD4C,mBDnD5C,CCmDgE,MDnDhE,EAAA,IAAA,CAAA,CAAA,EAAA,IAAA;EAAsB,QAAA,CAAA,WAAA,MCiEJ,aDjEI,GAAA,MAAA,CAAA,CAAA,KAAA,ECmE1B,qBDnE0B,CCmEJ,ODnEI,ECmEK,UDnEL,CCmEgB,aDnEhB,CCmE8B,EDnE9B,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CCoEzB,UDpEyB,CCoEd,ODpEc,ECoEL,UDpEK,CCoEM,aDpEN,CCoEoB,EDpEpB,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,MAAA,CAAA,EAAA,EAAA,ECqEzB,EDrEyB,EAAA,IAAA,ECsEvB,UDtEuB,CCsEZ,aDtEY,CCsEE,EDtEF,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,IAAA;EAInB,KAAA,CAAA,CAAA,EAAA;IACI,MAAA,EC0EN,uBD1EM,CC0EkB,aD1ElB,EC0EiC,OD1EjC,CAAA,GAAA,IAAA;IAC2B,KAAA,EC0ElC,sBD1EkC,CC0EX,OD1EW,CAAA,EAAA,GAAA,IAAA;EAApB,CAAA;;;;iBEnBP,yCAAyC,0BAA0B,2BAA2B"}
package/dist/index.mjs CHANGED
@@ -45,5 +45,11 @@ var DefaultChimeraQueryBuilder = class {
45
45
  };
46
46
 
47
47
  //#endregion
48
- export { DefaultChimeraQueryBuilder };
48
+ //#region factory.ts
49
+ function createDefaultQueryBuilder() {
50
+ return new DefaultChimeraQueryBuilder();
51
+ }
52
+
53
+ //#endregion
54
+ export { DefaultChimeraQueryBuilder, createDefaultQueryBuilder };
49
55
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../DefaultChimeraQueryBuilder.ts"],"sourcesContent":["import {\n\ttype AnyChimeraEntityStore,\n\ttype ChimeraConjunctionDescriptor,\n\ttype ChimeraConjunctionOperationDescriptor,\n\ttype ChimeraConjunctionType,\n\ttype ChimeraEntityStoreEntity,\n\ttype ChimeraEntityStoreOperatorsMap,\n\ttype ChimeraFilterDescriptor,\n\ttype ChimeraOrderDescriptor,\n\tChimeraOrderNulls,\n\ttype ChimeraPropertyGetter,\n\ttype Constructable,\n\tchimeraCreateConjunction,\n\tchimeraCreateNot,\n\tchimeraCreateOperator,\n\tchimeraCreateOrderBy,\n\ttype KeysOfType,\n} from \"@hf-chimera/store\";\nimport type { ChimeraQueryBuilder, QueryBuilderCreator } from \"./types\";\n\nexport class DefaultChimeraQueryBuilder<\n\tTStore extends AnyChimeraEntityStore,\n\tTEntity extends ChimeraEntityStoreEntity<TStore> = ChimeraEntityStoreEntity<TStore>,\n\tTOperatorsMap extends ChimeraEntityStoreOperatorsMap<TStore> = ChimeraEntityStoreOperatorsMap<TStore>,\n> implements ChimeraQueryBuilder<TStore>\n{\n\tprivate orderRules: ChimeraOrderDescriptor<TEntity>[] = [];\n\n\tisChimeraQueryBuilder: true = true;\n\n\tcreate(): this {\n\t\treturn new (this.constructor as Constructable)();\n\t}\n\n\torderBy(\n\t\tkey: ChimeraPropertyGetter<TEntity> | (keyof TEntity & string),\n\t\tdesc = false,\n\t\tnulls: ChimeraOrderNulls = ChimeraOrderNulls.Last,\n\t): this {\n\t\tthis.orderRules.push(chimeraCreateOrderBy<TEntity>(key, desc, nulls));\n\t\treturn this;\n\t}\n\n\tprivate filters: ChimeraConjunctionOperationDescriptor<TOperatorsMap, TEntity>[] = [];\n\tprivate rootConjunction: Exclude<ChimeraConjunctionType, \"not\"> = \"and\";\n\n\tprivate conjunction(type: Exclude<ChimeraConjunctionType, \"not\">) {\n\t\tthis.rootConjunction = type;\n\t}\n\n\tprivate buildFilter(): ChimeraConjunctionDescriptor<TOperatorsMap, TEntity> | null {\n\t\treturn this.filters.length\n\t\t\t? chimeraCreateConjunction<TEntity, TOperatorsMap>(this.rootConjunction, this.filters)\n\t\t\t: null;\n\t}\n\n\twhere<Op extends keyof TOperatorsMap & string>(\n\t\tvalue:\n\t\t\t| ChimeraPropertyGetter<TEntity, Parameters<TOperatorsMap[Op]>[0]>\n\t\t\t| (KeysOfType<TEntity, Parameters<TOperatorsMap[Op]>[0]> & string),\n\t\top: Op,\n\t\ttest: Parameters<TOperatorsMap[Op]>[1],\n\t): this {\n\t\tthis.filters.push(chimeraCreateOperator<TEntity, TOperatorsMap, Op>(op, value, test));\n\t\treturn this;\n\t}\n\n\tgroup(conjunction: ChimeraConjunctionType, builder: QueryBuilderCreator<TStore, this>): this {\n\t\tconst isNot = conjunction === \"not\";\n\t\tconst nestedBuilder = this.create();\n\n\t\t!isNot && nestedBuilder.conjunction(conjunction);\n\n\t\tbuilder(nestedBuilder);\n\n\t\tconst nestedQuery = nestedBuilder.buildFilter();\n\t\tnestedQuery && this.filters.push(isNot ? chimeraCreateNot<TEntity, TOperatorsMap>(nestedQuery) : nestedQuery);\n\n\t\treturn this;\n\t}\n\n\twhereNot<Op extends keyof TOperatorsMap & string>(\n\t\tvalue:\n\t\t\t| ChimeraPropertyGetter<TEntity, Parameters<TOperatorsMap[Op]>[0]>\n\t\t\t| (KeysOfType<TEntity, Parameters<TOperatorsMap[Op]>[0]> & string),\n\t\top: Op,\n\t\ttest: Parameters<TOperatorsMap[Op]>[1],\n\t): this {\n\t\tthis.filters.push(\n\t\t\tchimeraCreateNot<TEntity, TOperatorsMap>(chimeraCreateOperator<TEntity, TOperatorsMap, Op>(op, value, test)),\n\t\t);\n\t\treturn this;\n\t}\n\n\tbuild(): {\n\t\tfilter: ChimeraFilterDescriptor<TOperatorsMap, TEntity> | null;\n\t\torder: ChimeraOrderDescriptor<TEntity>[] | null;\n\t} {\n\t\treturn {\n\t\t\tfilter: this.buildFilter(),\n\t\t\torder: this.orderRules.length ? this.orderRules : null,\n\t\t};\n\t}\n}\n"],"mappings":";;;AAoBA,IAAa,6BAAb,MAKA;CACC,AAAQ,aAAgD,EAAE;CAE1D,wBAA8B;CAE9B,SAAe;AACd,SAAO,IAAK,KAAK,aAA+B;;CAGjD,QACC,KACA,OAAO,OACP,QAA2B,kBAAkB,MACtC;AACP,OAAK,WAAW,KAAK,qBAA8B,KAAK,MAAM,MAAM,CAAC;AACrE,SAAO;;CAGR,AAAQ,UAA2E,EAAE;CACrF,AAAQ,kBAA0D;CAElE,AAAQ,YAAY,MAA8C;AACjE,OAAK,kBAAkB;;CAGxB,AAAQ,cAA2E;AAClF,SAAO,KAAK,QAAQ,SACjB,yBAAiD,KAAK,iBAAiB,KAAK,QAAQ,GACpF;;CAGJ,MACC,OAGA,IACA,MACO;AACP,OAAK,QAAQ,KAAK,sBAAkD,IAAI,OAAO,KAAK,CAAC;AACrF,SAAO;;CAGR,MAAM,aAAqC,SAAkD;EAC5F,MAAM,QAAQ,gBAAgB;EAC9B,MAAM,gBAAgB,KAAK,QAAQ;AAEnC,GAAC,SAAS,cAAc,YAAY,YAAY;AAEhD,UAAQ,cAAc;EAEtB,MAAM,cAAc,cAAc,aAAa;AAC/C,iBAAe,KAAK,QAAQ,KAAK,QAAQ,iBAAyC,YAAY,GAAG,YAAY;AAE7G,SAAO;;CAGR,SACC,OAGA,IACA,MACO;AACP,OAAK,QAAQ,KACZ,iBAAyC,sBAAkD,IAAI,OAAO,KAAK,CAAC,CAC5G;AACD,SAAO;;CAGR,QAGE;AACD,SAAO;GACN,QAAQ,KAAK,aAAa;GAC1B,OAAO,KAAK,WAAW,SAAS,KAAK,aAAa;GAClD"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../DefaultChimeraQueryBuilder.ts","../factory.ts"],"sourcesContent":["import {\n\ttype AnyChimeraEntityStore,\n\ttype ChimeraConjunctionDescriptor,\n\ttype ChimeraConjunctionOperationDescriptor,\n\ttype ChimeraConjunctionType,\n\ttype ChimeraEntityStoreEntity,\n\ttype ChimeraEntityStoreOperatorsMap,\n\ttype ChimeraFilterDescriptor,\n\ttype ChimeraOrderDescriptor,\n\tChimeraOrderNulls,\n\ttype ChimeraPropertyGetter,\n\ttype Constructable,\n\tchimeraCreateConjunction,\n\tchimeraCreateNot,\n\tchimeraCreateOperator,\n\tchimeraCreateOrderBy,\n\ttype KeysOfType,\n} from \"@hf-chimera/store\";\nimport type { ChimeraQueryBuilder, QueryBuilderCreator } from \"./types\";\n\nexport class DefaultChimeraQueryBuilder<\n\tTStore extends AnyChimeraEntityStore,\n\tTEntity extends ChimeraEntityStoreEntity<TStore> = ChimeraEntityStoreEntity<TStore>,\n\tTOperatorsMap extends ChimeraEntityStoreOperatorsMap<TStore> = ChimeraEntityStoreOperatorsMap<TStore>,\n> implements ChimeraQueryBuilder<TStore>\n{\n\tprivate orderRules: ChimeraOrderDescriptor<TEntity>[] = [];\n\n\tisChimeraQueryBuilder: true = true;\n\n\tcreate(): this {\n\t\treturn new (this.constructor as Constructable)();\n\t}\n\n\torderBy(\n\t\tkey: ChimeraPropertyGetter<TEntity> | (keyof TEntity & string),\n\t\tdesc = false,\n\t\tnulls: ChimeraOrderNulls = ChimeraOrderNulls.Last,\n\t): this {\n\t\tthis.orderRules.push(chimeraCreateOrderBy<TEntity>(key, desc, nulls));\n\t\treturn this;\n\t}\n\n\tprivate filters: ChimeraConjunctionOperationDescriptor<TOperatorsMap, TEntity>[] = [];\n\tprivate rootConjunction: Exclude<ChimeraConjunctionType, \"not\"> = \"and\";\n\n\tprivate conjunction(type: Exclude<ChimeraConjunctionType, \"not\">) {\n\t\tthis.rootConjunction = type;\n\t}\n\n\tprivate buildFilter(): ChimeraConjunctionDescriptor<TOperatorsMap, TEntity> | null {\n\t\treturn this.filters.length\n\t\t\t? chimeraCreateConjunction<TEntity, TOperatorsMap>(this.rootConjunction, this.filters)\n\t\t\t: null;\n\t}\n\n\twhere<Op extends keyof TOperatorsMap & string>(\n\t\tvalue:\n\t\t\t| ChimeraPropertyGetter<TEntity, Parameters<TOperatorsMap[Op]>[0]>\n\t\t\t| (KeysOfType<TEntity, Parameters<TOperatorsMap[Op]>[0]> & string),\n\t\top: Op,\n\t\ttest: Parameters<TOperatorsMap[Op]>[1],\n\t): this {\n\t\tthis.filters.push(chimeraCreateOperator<TEntity, TOperatorsMap, Op>(op, value, test));\n\t\treturn this;\n\t}\n\n\tgroup(conjunction: ChimeraConjunctionType, builder: QueryBuilderCreator<TStore, this>): this {\n\t\tconst isNot = conjunction === \"not\";\n\t\tconst nestedBuilder = this.create();\n\n\t\t!isNot && nestedBuilder.conjunction(conjunction);\n\n\t\tbuilder(nestedBuilder);\n\n\t\tconst nestedQuery = nestedBuilder.buildFilter();\n\t\tnestedQuery && this.filters.push(isNot ? chimeraCreateNot<TEntity, TOperatorsMap>(nestedQuery) : nestedQuery);\n\n\t\treturn this;\n\t}\n\n\twhereNot<Op extends keyof TOperatorsMap & string>(\n\t\tvalue:\n\t\t\t| ChimeraPropertyGetter<TEntity, Parameters<TOperatorsMap[Op]>[0]>\n\t\t\t| (KeysOfType<TEntity, Parameters<TOperatorsMap[Op]>[0]> & string),\n\t\top: Op,\n\t\ttest: Parameters<TOperatorsMap[Op]>[1],\n\t): this {\n\t\tthis.filters.push(\n\t\t\tchimeraCreateNot<TEntity, TOperatorsMap>(chimeraCreateOperator<TEntity, TOperatorsMap, Op>(op, value, test)),\n\t\t);\n\t\treturn this;\n\t}\n\n\tbuild(): {\n\t\tfilter: ChimeraFilterDescriptor<TOperatorsMap, TEntity> | null;\n\t\torder: ChimeraOrderDescriptor<TEntity>[] | null;\n\t} {\n\t\treturn {\n\t\t\tfilter: this.buildFilter(),\n\t\t\torder: this.orderRules.length ? this.orderRules : null,\n\t\t};\n\t}\n}\n","import type { AnyChimeraEntityStore } from \"@hf-chimera/store\";\nimport { DefaultChimeraQueryBuilder } from \"./DefaultChimeraQueryBuilder\";\n\nexport function createDefaultQueryBuilder<TStore extends AnyChimeraEntityStore>(): DefaultChimeraQueryBuilder<TStore> {\n\treturn new DefaultChimeraQueryBuilder<TStore>();\n}\n"],"mappings":";;;AAoBA,IAAa,6BAAb,MAKA;CACC,AAAQ,aAAgD,EAAE;CAE1D,wBAA8B;CAE9B,SAAe;AACd,SAAO,IAAK,KAAK,aAA+B;;CAGjD,QACC,KACA,OAAO,OACP,QAA2B,kBAAkB,MACtC;AACP,OAAK,WAAW,KAAK,qBAA8B,KAAK,MAAM,MAAM,CAAC;AACrE,SAAO;;CAGR,AAAQ,UAA2E,EAAE;CACrF,AAAQ,kBAA0D;CAElE,AAAQ,YAAY,MAA8C;AACjE,OAAK,kBAAkB;;CAGxB,AAAQ,cAA2E;AAClF,SAAO,KAAK,QAAQ,SACjB,yBAAiD,KAAK,iBAAiB,KAAK,QAAQ,GACpF;;CAGJ,MACC,OAGA,IACA,MACO;AACP,OAAK,QAAQ,KAAK,sBAAkD,IAAI,OAAO,KAAK,CAAC;AACrF,SAAO;;CAGR,MAAM,aAAqC,SAAkD;EAC5F,MAAM,QAAQ,gBAAgB;EAC9B,MAAM,gBAAgB,KAAK,QAAQ;AAEnC,GAAC,SAAS,cAAc,YAAY,YAAY;AAEhD,UAAQ,cAAc;EAEtB,MAAM,cAAc,cAAc,aAAa;AAC/C,iBAAe,KAAK,QAAQ,KAAK,QAAQ,iBAAyC,YAAY,GAAG,YAAY;AAE7G,SAAO;;CAGR,SACC,OAGA,IACA,MACO;AACP,OAAK,QAAQ,KACZ,iBAAyC,sBAAkD,IAAI,OAAO,KAAK,CAAC,CAC5G;AACD,SAAO;;CAGR,QAGE;AACD,SAAO;GACN,QAAQ,KAAK,aAAa;GAC1B,OAAO,KAAK,WAAW,SAAS,KAAK,aAAa;GAClD;;;;;;AClGH,SAAgB,4BAAsG;AACrH,QAAO,IAAI,4BAAoC"}
package/package.json CHANGED
@@ -1,45 +1,45 @@
1
1
  {
2
- "name": "@hf-chimera/query-builder",
3
- "version": "0.2.0",
4
- "description": "Cross-end reactivity API - Query builder",
5
- "license": "MIT",
6
- "author": "hewston",
7
- "keywords": [
8
- "query-builder",
9
- "reactivity",
10
- "reactive",
11
- "typescript",
12
- "fullstack"
13
- ],
14
- "type": "module",
15
- "types": "./dist/index.d.ts",
16
- "main": "./dist/index.cjs",
17
- "module": "./dist/index.js",
18
- "exports": {
19
- ".": {
20
- "types": "./dist/index.d.ts",
21
- "require": "./dist/index.cjs",
22
- "import": "./dist/index.js"
23
- }
24
- },
25
- "files": [
26
- "dist"
27
- ],
28
- "bugs": {
29
- "url": "https://github.com/hf-chimera/store/issues"
30
- },
31
- "repository": {
32
- "url": "https://github.com/hf-chimera/store"
33
- },
34
- "peerDependencies": {
35
- "@hf-chimera/store": "workspace:^"
36
- },
37
- "scripts": {
38
- "build": "tsdown",
39
- "changeset:patch": "node ../../scripts/changeset-patch.mjs @hf-chimera/query-builder"
40
- },
41
- "publishConfig": {
42
- "access": "public",
43
- "provenance": true
44
- }
45
- }
2
+ "name": "@hf-chimera/query-builder",
3
+ "version": "0.2.2",
4
+ "description": "Cross-end reactivity API - Query builder",
5
+ "license": "MIT",
6
+ "author": "hewston",
7
+ "keywords": [
8
+ "query-builder",
9
+ "reactivity",
10
+ "reactive",
11
+ "typescript",
12
+ "fullstack"
13
+ ],
14
+ "type": "module",
15
+ "types": "./dist/index.d.ts",
16
+ "main": "./dist/index.cjs",
17
+ "module": "./dist/index.js",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "require": "./dist/index.cjs",
22
+ "import": "./dist/index.js"
23
+ }
24
+ },
25
+ "files": [
26
+ "dist"
27
+ ],
28
+ "bugs": {
29
+ "url": "https://github.com/hf-chimera/store/issues"
30
+ },
31
+ "repository": {
32
+ "url": "https://github.com/hf-chimera/store"
33
+ },
34
+ "peerDependencies": {
35
+ "@hf-chimera/store": "~0.2.0"
36
+ },
37
+ "publishConfig": {
38
+ "access": "public",
39
+ "provenance": true
40
+ },
41
+ "scripts": {
42
+ "build": "tsdown",
43
+ "changeset:patch": "node ../../scripts/changeset-patch.mjs @hf-chimera/query-builder"
44
+ }
45
+ }