ng-qubee 2.1.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.md +378 -54
  2. package/fesm2022/ng-qubee.mjs +1791 -419
  3. package/fesm2022/ng-qubee.mjs.map +1 -1
  4. package/package.json +4 -4
  5. package/types/ng-qubee.d.ts +1544 -0
  6. package/index.d.ts +0 -5
  7. package/lib/enums/sort.enum.d.ts +0 -4
  8. package/lib/errors/invalid-limit.error.d.ts +0 -3
  9. package/lib/errors/invalid-model-name.error.d.ts +0 -3
  10. package/lib/errors/invalid-page-number.error.d.ts +0 -3
  11. package/lib/errors/key-not-found.error.d.ts +0 -3
  12. package/lib/errors/unselectable-model.error.d.ts +0 -3
  13. package/lib/interfaces/config.interface.d.ts +0 -6
  14. package/lib/interfaces/fields.interface.d.ts +0 -3
  15. package/lib/interfaces/filters.interface.d.ts +0 -3
  16. package/lib/interfaces/nest-state.interface.d.ts +0 -4
  17. package/lib/interfaces/normalized.interface.d.ts +0 -3
  18. package/lib/interfaces/page.interface.d.ts +0 -2
  19. package/lib/interfaces/paginated-object.interface.d.ts +0 -3
  20. package/lib/interfaces/pagination-config.interface.d.ts +0 -14
  21. package/lib/interfaces/query-builder-config.interface.d.ts +0 -9
  22. package/lib/interfaces/query-builder-state.interface.d.ts +0 -13
  23. package/lib/interfaces/sort.interface.d.ts +0 -5
  24. package/lib/models/paginated-collection.d.ts +0 -30
  25. package/lib/models/query-builder-options.d.ts +0 -11
  26. package/lib/models/response-options.d.ts +0 -16
  27. package/lib/ng-qubee.module.d.ts +0 -9
  28. package/lib/provide-ngqubee.d.ts +0 -21
  29. package/lib/services/nest.service.d.ts +0 -182
  30. package/lib/services/ng-qubee.service.d.ts +0 -147
  31. package/lib/services/pagination.service.d.ts +0 -13
  32. package/public-api.d.ts +0 -20
@@ -0,0 +1,1544 @@
1
+ import * as i0 from '@angular/core';
2
+ import { ModuleWithProviders, EnvironmentProviders, Signal } from '@angular/core';
3
+ import { Observable } from 'rxjs';
4
+
5
+ interface INormalized {
6
+ [k: number | string]: number[] | string[];
7
+ }
8
+
9
+ interface IPaginatedObject {
10
+ [k: string]: any;
11
+ }
12
+
13
+ declare class PaginatedCollection<T extends IPaginatedObject> {
14
+ data: T[];
15
+ readonly page: number;
16
+ readonly from?: number | undefined;
17
+ readonly to?: number | undefined;
18
+ readonly total?: number | undefined;
19
+ readonly perPage?: number | undefined;
20
+ readonly prevPageUrl?: string | undefined;
21
+ readonly nextPageUrl?: string | undefined;
22
+ readonly lastPage?: number | undefined;
23
+ readonly firstPageUrl?: string | undefined;
24
+ readonly lastPageUrl?: string | undefined;
25
+ constructor(data: T[], page: number, from?: number | undefined, to?: number | undefined, total?: number | undefined, perPage?: number | undefined, prevPageUrl?: string | undefined, nextPageUrl?: string | undefined, lastPage?: number | undefined, firstPageUrl?: string | undefined, lastPageUrl?: string | undefined);
26
+ /**
27
+ * Normalize the collection to a paginated list of ids for state-managed applications.
28
+ *
29
+ * This method returns a single key object, where the key is the page number and the associated value is
30
+ * an array of ids. Each id is fetched by the collection items, looking up for the "id" key. If an id is supplied
31
+ * to this method, it will be used instead of the default "id" key.
32
+ *
33
+ * Please note that in case the key doesn't exist in the collection's item, a KeyNotFoundError is thrown
34
+ *
35
+ * @param k A key to use instead of the default "id": this will be searched inside each element of the collection
36
+ * @returns []
37
+ * @throws KeyNotFoundItem
38
+ */
39
+ normalize(id?: string): INormalized;
40
+ }
41
+
42
+ /**
43
+ * Enum representing the available pagination driver types
44
+ *
45
+ * Each driver encapsulates the full format knowledge for both
46
+ * request building (URI generation) and response parsing.
47
+ */
48
+ declare enum DriverEnum {
49
+ JSON_API = "json-api",
50
+ LARAVEL = "laravel",
51
+ NESTJS = "nestjs",
52
+ SPATIE = "spatie"
53
+ }
54
+
55
+ /**
56
+ * Configuration interface for customizing response field key names
57
+ *
58
+ * Each property maps a logical pagination concept to the actual key name
59
+ * used in the API response. The defaults depend on the selected driver.
60
+ *
61
+ * For the NestJS driver, dot-notation paths are used to access nested values
62
+ * (e.g., 'meta.currentPage', 'links.next').
63
+ */
64
+ interface IPaginationConfig {
65
+ /** Key for the current page number (Laravel: 'current_page', NestJS: 'meta.currentPage') */
66
+ currentPage?: string;
67
+ /** Key for the data array (default: 'data') */
68
+ data?: string;
69
+ /** Key for the first page URL (Laravel: 'first_page_url', NestJS: 'links.first') */
70
+ firstPageUrl?: string;
71
+ /** Key for the "from" item index (Laravel: 'from', NestJS: computed) */
72
+ from?: string;
73
+ /** Key for the last page number (Laravel: 'last_page', NestJS: 'meta.totalPages') */
74
+ lastPage?: string;
75
+ /** Key for the last page URL (Laravel: 'last_page_url', NestJS: 'links.last') */
76
+ lastPageUrl?: string;
77
+ /** Key for the next page URL (Laravel: 'next_page_url', NestJS: 'links.next') */
78
+ nextPageUrl?: string;
79
+ /** Key for the base path (Laravel only, default: 'path') */
80
+ path?: string;
81
+ /** Key for items per page (Laravel: 'per_page', NestJS: 'meta.itemsPerPage') */
82
+ perPage?: string;
83
+ /** Key for the previous page URL (Laravel: 'prev_page_url', NestJS: 'links.previous') */
84
+ prevPageUrl?: string;
85
+ /** Key for the "to" item index (Laravel: 'to', NestJS: computed) */
86
+ to?: string;
87
+ /** Key for the total item count (Laravel: 'total', NestJS: 'meta.totalItems') */
88
+ total?: string;
89
+ }
90
+
91
+ /**
92
+ * Configuration interface for customizing request query parameter key names
93
+ *
94
+ * Each property maps a logical query concept to the actual query parameter name
95
+ * used in the generated URI. The defaults depend on the selected driver.
96
+ */
97
+ interface IQueryBuilderConfig {
98
+ /** Key for the appends parameter (Laravel only, default: 'append') */
99
+ appends?: string;
100
+ /** Key for the fields parameter (Laravel: 'fields', NestJS: 'select') */
101
+ fields?: string;
102
+ /** Key for the filters parameter (default: 'filter') */
103
+ filters?: string;
104
+ /** Key for the includes parameter (Laravel only, default: 'include') */
105
+ includes?: string;
106
+ /** Key for the limit parameter (default: 'limit') */
107
+ limit?: string;
108
+ /** Key for the page parameter (default: 'page') */
109
+ page?: string;
110
+ /** Key for the search parameter (NestJS only, default: 'search') */
111
+ search?: string;
112
+ /** Key for the select parameter (NestJS only, default: 'select') */
113
+ select?: string;
114
+ /** Key for the sort parameter (Laravel: 'sort', NestJS: 'sortBy') */
115
+ sort?: string;
116
+ /** Key for the sortBy parameter (NestJS only, default: 'sortBy') */
117
+ sortBy?: string;
118
+ }
119
+
120
+ /**
121
+ * Main configuration interface for ng-qubee
122
+ *
123
+ * Allows configuring the pagination driver and customizing
124
+ * both request query parameter keys and response field keys.
125
+ *
126
+ * @example
127
+ * ```typescript
128
+ * const config: IConfig = {
129
+ * driver: DriverEnum.NESTJS,
130
+ * request: { filters: 'filter', sort: 'sortBy' },
131
+ * response: { data: 'data' }
132
+ * };
133
+ * ```
134
+ */
135
+ interface IConfig {
136
+ /** The pagination driver to use */
137
+ driver: DriverEnum;
138
+ /** Custom key names for request query parameters */
139
+ request?: IQueryBuilderConfig;
140
+ /** Custom key names for response field mapping */
141
+ response?: IPaginationConfig;
142
+ }
143
+
144
+ declare class NgQubeeModule {
145
+ /**
146
+ * Configure NgQubee for the root module
147
+ *
148
+ * @param config - Configuration object with driver, and optional request and response settings
149
+ * @returns Module with providers configured for the specified driver
150
+ */
151
+ static forRoot(config: IConfig): ModuleWithProviders<NgQubeeModule>;
152
+ static ɵfac: i0.ɵɵFactoryDeclaration<NgQubeeModule, never>;
153
+ static ɵmod: i0.ɵɵNgModuleDeclaration<NgQubeeModule, never, never, never>;
154
+ static ɵinj: i0.ɵɵInjectorDeclaration<NgQubeeModule>;
155
+ }
156
+
157
+ /**
158
+ * Sets up providers necessary to enable `NgQubee` functionality for the application.
159
+ *
160
+ * @usageNotes
161
+ *
162
+ * Basic example with the Laravel driver:
163
+ * ```
164
+ * bootstrapApplication(AppComponent, {
165
+ * providers: [provideNgQubee({ driver: DriverEnum.LARAVEL })]
166
+ * });
167
+ * ```
168
+ *
169
+ * Spatie driver example:
170
+ * ```
171
+ * import { DriverEnum } from 'ng-qubee';
172
+ *
173
+ * bootstrapApplication(AppComponent, {
174
+ * providers: [provideNgQubee({ driver: DriverEnum.SPATIE })]
175
+ * });
176
+ * ```
177
+ *
178
+ * JSON:API driver example:
179
+ * ```
180
+ * import { DriverEnum } from 'ng-qubee';
181
+ *
182
+ * bootstrapApplication(AppComponent, {
183
+ * providers: [provideNgQubee({ driver: DriverEnum.JSON_API })]
184
+ * });
185
+ * ```
186
+ *
187
+ * NestJS driver example:
188
+ * ```
189
+ * import { DriverEnum } from 'ng-qubee';
190
+ *
191
+ * bootstrapApplication(AppComponent, {
192
+ * providers: [provideNgQubee({ driver: DriverEnum.NESTJS })]
193
+ * });
194
+ * ```
195
+ *
196
+ * @publicApi
197
+ * @param config - Configuration object compliant to the IConfig interface
198
+ * @returns A set of providers to setup NgQubee
199
+ */
200
+ declare function provideNgQubee(config: IConfig): EnvironmentProviders;
201
+
202
+ /**
203
+ * Enum representing the available filter operators for the NestJS driver
204
+ *
205
+ * These operators map to the nestjs-paginate filter syntax:
206
+ * `filter.field=$operator:value`
207
+ *
208
+ * @see https://github.com/ppetzold/nestjs-paginate
209
+ */
210
+ declare enum FilterOperatorEnum {
211
+ BTW = "$btw",
212
+ CONTAINS = "$contains",
213
+ EQ = "$eq",
214
+ GT = "$gt",
215
+ GTE = "$gte",
216
+ ILIKE = "$ilike",
217
+ IN = "$in",
218
+ LT = "$lt",
219
+ LTE = "$lte",
220
+ NOT = "$not",
221
+ NULL = "$null",
222
+ SW = "$sw"
223
+ }
224
+
225
+ declare enum SortEnum {
226
+ ASC = "asc",
227
+ DESC = "desc"
228
+ }
229
+
230
+ interface IFields {
231
+ [model: string]: string[];
232
+ }
233
+
234
+ interface IFilters {
235
+ [k: string]: (string | number | boolean)[];
236
+ }
237
+
238
+ /**
239
+ * Represents a filter with an explicit operator for the NestJS driver
240
+ *
241
+ * Operator filters produce query parameters in the format:
242
+ * `filter.field=$operator:value`
243
+ *
244
+ * @example
245
+ * ```typescript
246
+ * const filter: IOperatorFilter = {
247
+ * field: 'age',
248
+ * operator: FilterOperatorEnum.GTE,
249
+ * values: [18]
250
+ * };
251
+ * // Produces: filter.age=$gte:18
252
+ * ```
253
+ */
254
+ interface IOperatorFilter {
255
+ /** The field name to filter on */
256
+ field: string;
257
+ /** The filter operator to apply */
258
+ operator: FilterOperatorEnum;
259
+ /** The value(s) for the filter */
260
+ values: (string | number | boolean)[];
261
+ }
262
+
263
+ interface ISort {
264
+ field: string;
265
+ order: SortEnum;
266
+ }
267
+
268
+ /**
269
+ * Represents the complete query builder state
270
+ *
271
+ * This is a superset that covers the needs of all drivers.
272
+ * Each driver reads only the fields it needs from this state.
273
+ */
274
+ interface IQueryBuilderState {
275
+ /** The base URL to prepend to generated URIs */
276
+ baseUrl: string;
277
+ /** Per-model field selection (Spatie only) */
278
+ fields: IFields;
279
+ /** Simple key-value filters (Spatie and NestJS) */
280
+ filters: IFilters;
281
+ /** Related models to include (Spatie only) */
282
+ includes: string[];
283
+ /** Number of items per page (all drivers) */
284
+ limit: number;
285
+ /** Filters with explicit operators (NestJS only) */
286
+ operatorFilters: IOperatorFilter[];
287
+ /** Current page number (all drivers) */
288
+ page: number;
289
+ /** The API resource name for URI generation (all drivers) */
290
+ resource: string;
291
+ /** Full-text search term (NestJS only) */
292
+ search: string;
293
+ /** Flat field selection (NestJS only) */
294
+ select: string[];
295
+ /** Sort configurations (Spatie and NestJS) */
296
+ sorts: ISort[];
297
+ }
298
+
299
+ /**
300
+ * Resolved query parameter key names with defaults applied
301
+ *
302
+ * Maps logical query concepts to the actual query parameter names
303
+ * used in the generated URI. Unset values fall back to defaults.
304
+ */
305
+ declare class QueryBuilderOptions {
306
+ readonly appends: string;
307
+ readonly fields: string;
308
+ readonly filters: string;
309
+ readonly includes: string;
310
+ readonly limit: string;
311
+ readonly page: string;
312
+ readonly search: string;
313
+ readonly select: string;
314
+ readonly sort: string;
315
+ readonly sortBy: string;
316
+ constructor(options: IQueryBuilderConfig);
317
+ }
318
+
319
+ /**
320
+ * Strategy interface for building request URIs
321
+ *
322
+ * Each driver implements this interface to produce URIs
323
+ * in the format expected by the corresponding backend.
324
+ */
325
+ interface IRequestStrategy {
326
+ /**
327
+ * Build a URI string from the given query builder state
328
+ *
329
+ * @param state - The current query builder state
330
+ * @param options - The query parameter key name configuration
331
+ * @returns The composed URI string
332
+ */
333
+ buildUri(state: IQueryBuilderState, options: QueryBuilderOptions): string;
334
+ /**
335
+ * Assert that the given limit value is valid for this driver
336
+ *
337
+ * Validation is driver-scoped because the accepted range differs by
338
+ * backend: nestjs-paginate treats `-1` as a "fetch all" sentinel, while
339
+ * other backends (Laravel, Spatie, JSON:API) require a positive integer.
340
+ *
341
+ * @param limit - The limit value to validate
342
+ * @throws {import('../errors/invalid-limit.error').InvalidLimitError} If the value is not accepted by the driver
343
+ */
344
+ validateLimit(limit: number): void;
345
+ }
346
+
347
+ declare class NestService {
348
+ /**
349
+ * Private writable signal that holds the Query Builder state
350
+ *
351
+ * @type {IQueryBuilderState}
352
+ */
353
+ private _nest;
354
+ /**
355
+ * A computed signal that makes readonly the writable signal _nest
356
+ *
357
+ * @type {Signal<IQueryBuilderState>}
358
+ */
359
+ nest: Signal<IQueryBuilderState>;
360
+ constructor();
361
+ /**
362
+ * Set the base URL for the API
363
+ *
364
+ * @param {string} baseUrl - The base URL to prepend to generated URIs
365
+ * @example
366
+ * service.baseUrl = 'https://api.example.com';
367
+ */
368
+ set baseUrl(baseUrl: string);
369
+ /**
370
+ * Set the limit for paginated results
371
+ *
372
+ * This setter performs a raw state write. Validation of the value is the
373
+ * responsibility of the active request strategy and is enforced upstream
374
+ * by `NgQubeeService.setLimit()`, because the accepted range depends on
375
+ * the driver (e.g. nestjs-paginate accepts `-1` for "fetch all").
376
+ *
377
+ * @param {number} limit - The number of items per page
378
+ * @example
379
+ * service.limit = 25;
380
+ */
381
+ set limit(limit: number);
382
+ /**
383
+ * Set the page number for pagination
384
+ * Must be a positive integer greater than 0
385
+ *
386
+ * @param {number} page - The page number to fetch
387
+ * @throws {InvalidPageNumberError} If page is not a positive integer
388
+ * @example
389
+ * service.page = 2;
390
+ */
391
+ set page(page: number);
392
+ /**
393
+ * Set the resource name for the query
394
+ * Must be a non-empty string
395
+ *
396
+ * @param {string} resource - The API resource name (e.g., 'users', 'posts')
397
+ * @throws {InvalidResourceNameError} If resource is not a non-empty string
398
+ * @example
399
+ * service.resource = 'users';
400
+ */
401
+ set resource(resource: string);
402
+ private _clone;
403
+ /**
404
+ * Validates that the page number is a positive integer
405
+ *
406
+ * @param {number} page - The page number to validate
407
+ * @throws {InvalidPageNumberError} If page is not a positive integer
408
+ * @private
409
+ */
410
+ private _validatePageNumber;
411
+ /**
412
+ * Validates that the resource name is a non-empty string
413
+ *
414
+ * @param {string} resource - The resource name to validate
415
+ * @throws {InvalidResourceNameError} If resource is not a non-empty string
416
+ * @private
417
+ */
418
+ private _validateResourceName;
419
+ /**
420
+ * Add selectable fields for the given model to the request
421
+ * Automatically prevents duplicate fields for each model
422
+ *
423
+ * @param {IFields} fields - Object mapping model names to arrays of field names
424
+ * @return {void}
425
+ * @example
426
+ * service.addFields({ users: ['id', 'email', 'username'] });
427
+ * service.addFields({ posts: ['title', 'content'] });
428
+ */
429
+ addFields(fields: IFields): void;
430
+ /**
431
+ * Add filters to the request
432
+ * Automatically prevents duplicate filter values for each filter key
433
+ *
434
+ * @param {IFilters} filters - Object mapping filter keys to arrays of values
435
+ * @return {void}
436
+ * @example
437
+ * service.addFilters({ id: [1, 2, 3] });
438
+ * service.addFilters({ status: ['active', 'pending'] });
439
+ */
440
+ addFilters(filters: IFilters): void;
441
+ /**
442
+ * Add resources to include with the request
443
+ * Automatically prevents duplicate includes
444
+ *
445
+ * @param {string[]} includes - Array of resource names to include in the response
446
+ * @return {void}
447
+ * @example
448
+ * service.addIncludes(['profile', 'posts']);
449
+ * service.addIncludes(['comments']);
450
+ */
451
+ addIncludes(includes: string[]): void;
452
+ /**
453
+ * Add filters with explicit operators (NestJS only)
454
+ * Automatically prevents duplicate operator filters for the same field + operator combination
455
+ *
456
+ * @param {IOperatorFilter[]} filters - Array of operator filter configurations
457
+ * @return {void}
458
+ * @example
459
+ * import { FilterOperatorEnum } from 'ng-qubee';
460
+ * service.addOperatorFilters([{ field: 'age', operator: FilterOperatorEnum.GTE, values: [18] }]);
461
+ */
462
+ addOperatorFilters(filters: IOperatorFilter[]): void;
463
+ /**
464
+ * Add flat field selection columns (NestJS only)
465
+ * Automatically prevents duplicate select fields
466
+ *
467
+ * @param {string[]} fields - Array of column names to select
468
+ * @return {void}
469
+ * @example
470
+ * service.addSelect(['id', 'name', 'email']);
471
+ */
472
+ addSelect(fields: string[]): void;
473
+ /**
474
+ * Add a field that should be used for sorting data
475
+ *
476
+ * @param {ISort} sort - Sort configuration with field name and order (ASC/DESC)
477
+ * @return {void}
478
+ * @example
479
+ * import { SortEnum } from 'ng-qubee';
480
+ * service.addSort({ field: 'created_at', order: SortEnum.DESC });
481
+ * service.addSort({ field: 'name', order: SortEnum.ASC });
482
+ */
483
+ addSort(sort: ISort): void;
484
+ /**
485
+ * Remove fields for the given model
486
+ * Uses deep cloning to prevent mutations to the original state
487
+ *
488
+ * @param {IFields} fields - Object mapping model names to arrays of field names to remove
489
+ * @return {void}
490
+ * @example
491
+ * service.deleteFields({ users: ['email'] });
492
+ * service.deleteFields({ posts: ['content', 'body'] });
493
+ */
494
+ deleteFields(fields: IFields): void;
495
+ /**
496
+ * Remove filters from the request
497
+ * Uses deep cloning to prevent mutations to the original state
498
+ *
499
+ * @param {...string[]} filters - Filter keys to remove
500
+ * @return {void}
501
+ * @example
502
+ * service.deleteFilters('id');
503
+ * service.deleteFilters('status', 'type');
504
+ */
505
+ deleteFilters(...filters: string[]): void;
506
+ /**
507
+ * Remove includes from the request
508
+ *
509
+ * @param {...string[]} includes - Include names to remove
510
+ * @return {void}
511
+ * @example
512
+ * service.deleteIncludes('profile');
513
+ * service.deleteIncludes('posts', 'comments');
514
+ */
515
+ deleteIncludes(...includes: string[]): void;
516
+ /**
517
+ * Remove operator filters by field name (NestJS only)
518
+ *
519
+ * @param {...string[]} fields - Field names of operator filters to remove
520
+ * @return {void}
521
+ * @example
522
+ * service.deleteOperatorFilters('age');
523
+ * service.deleteOperatorFilters('price', 'quantity');
524
+ */
525
+ deleteOperatorFilters(...fields: string[]): void;
526
+ /**
527
+ * Remove the search term from the state (NestJS only)
528
+ *
529
+ * @return {void}
530
+ * @example
531
+ * service.deleteSearch();
532
+ */
533
+ deleteSearch(): void;
534
+ /**
535
+ * Remove flat field selections from the state (NestJS only)
536
+ *
537
+ * @param {...string[]} fields - Field names to remove from selection
538
+ * @return {void}
539
+ * @example
540
+ * service.deleteSelect('email');
541
+ * service.deleteSelect('name', 'email');
542
+ */
543
+ deleteSelect(...fields: string[]): void;
544
+ /**
545
+ * Remove sorts from the request by field name
546
+ *
547
+ * @param {...string[]} sorts - Field names of sorts to remove
548
+ * @return {void}
549
+ * @example
550
+ * service.deleteSorts('created_at');
551
+ * service.deleteSorts('name', 'created_at');
552
+ */
553
+ deleteSorts(...sorts: string[]): void;
554
+ /**
555
+ * Set the full-text search term (NestJS only)
556
+ *
557
+ * @param {string} search - The search term
558
+ * @return {void}
559
+ * @example
560
+ * service.setSearch('john doe');
561
+ */
562
+ setSearch(search: string): void;
563
+ /**
564
+ * Reset the query builder state to initial values
565
+ * Clears all fields, filters, includes, sorts, and resets pagination
566
+ *
567
+ * @return {void}
568
+ * @example
569
+ * service.reset();
570
+ */
571
+ reset(): void;
572
+ static ɵfac: i0.ɵɵFactoryDeclaration<NestService, never>;
573
+ static ɵprov: i0.ɵɵInjectableDeclaration<NestService>;
574
+ }
575
+
576
+ declare class NgQubeeService {
577
+ private _nestService;
578
+ /**
579
+ * The active pagination driver
580
+ */
581
+ private _driver;
582
+ /**
583
+ * Resolved query parameter key name options
584
+ */
585
+ private _options;
586
+ /**
587
+ * The request strategy that builds URIs for the active driver
588
+ */
589
+ private _requestStrategy;
590
+ /**
591
+ * Internal BehaviorSubject that holds the latest generated URI
592
+ */
593
+ private _uri$;
594
+ /**
595
+ * Observable that emits non-empty generated URIs
596
+ */
597
+ uri$: Observable<string>;
598
+ constructor(_nestService: NestService, requestStrategy: IRequestStrategy, driver: DriverEnum, options?: IQueryBuilderConfig);
599
+ /**
600
+ * Assert that the active driver is one of the allowed drivers
601
+ *
602
+ * @param allowed - The allowed drivers
603
+ * @param error - The error to throw if the driver is not allowed
604
+ * @throws The provided error if the active driver is not in the allowed list
605
+ */
606
+ private _assertDriver;
607
+ /**
608
+ * Add fields to the select statement for the given model (JSON:API and Spatie only)
609
+ *
610
+ * @param model - Model that holds the fields
611
+ * @param fields - Fields to select
612
+ * @returns {this}
613
+ * @throws {UnsupportedFieldSelectionError} If the active driver does not support per-model field selection
614
+ */
615
+ addFields(model: string, fields: string[]): this;
616
+ /**
617
+ * Add a filter with the given value(s) (JSON:API, NestJS, and Spatie)
618
+ *
619
+ * Produces: `filter[field]=value` (JSON:API / Spatie) or `filter.field=value` (NestJS)
620
+ *
621
+ * @param {string} field - Name of the field to filter
622
+ * @param {(string | number | boolean)[]} values - The needle(s)
623
+ * @returns {this}
624
+ * @throws {UnsupportedFilterError} If the active driver does not support filters
625
+ */
626
+ addFilter(field: string, ...values: (string | number | boolean)[]): this;
627
+ /**
628
+ * Add a filter with an explicit operator (NestJS only)
629
+ *
630
+ * Produces: `filter.field=$operator:value`
631
+ *
632
+ * @param {string} field - Name of the field to filter
633
+ * @param {FilterOperatorEnum} operator - The filter operator to apply
634
+ * @param {(string | number | boolean)[]} values - The value(s) for the filter
635
+ * @returns {this}
636
+ * @throws {UnsupportedFilterOperatorError} If the active driver does not support filter operators
637
+ */
638
+ addFilterOperator(field: string, operator: FilterOperatorEnum, ...values: (string | number | boolean)[]): this;
639
+ /**
640
+ * Add related entities to include in the request (JSON:API and Spatie only)
641
+ *
642
+ * @param {string[]} models - Models to include
643
+ * @returns {this}
644
+ * @throws {UnsupportedIncludesError} If the active driver does not support includes
645
+ */
646
+ addIncludes(...models: string[]): this;
647
+ /**
648
+ * Add flat field selection (NestJS only)
649
+ *
650
+ * Produces: `select=col1,col2`
651
+ *
652
+ * @param {string[]} fields - Fields to select
653
+ * @returns {this}
654
+ * @throws {UnsupportedSelectError} If the active driver does not support flat field selection
655
+ */
656
+ addSelect(...fields: string[]): this;
657
+ /**
658
+ * Add a field with a sort criteria (JSON:API, NestJS, and Spatie)
659
+ *
660
+ * @param field - Field to use for sorting
661
+ * @param {SortEnum} order - A value from the SortEnum enumeration
662
+ * @returns {this}
663
+ * @throws {UnsupportedSortError} If the active driver does not support sorts
664
+ */
665
+ addSort(field: string, order: SortEnum): this;
666
+ /**
667
+ * Delete selected fields for the given models in the current query builder state (JSON:API and Spatie only)
668
+ *
669
+ * ```
670
+ * ngQubeeService.deleteFields({
671
+ * users: ['email', 'password'],
672
+ * address: ['zipcode']
673
+ * });
674
+ * ```
675
+ *
676
+ * @param {IFields} fields - Object mapping model names to field arrays to remove
677
+ * @returns {this}
678
+ * @throws {UnsupportedFieldSelectionError} If the active driver does not support per-model field selection
679
+ */
680
+ deleteFields(fields: IFields): this;
681
+ /**
682
+ * Delete selected fields for the given model in the current query builder state (JSON:API and Spatie only)
683
+ *
684
+ * ```
685
+ * ngQubeeService.deleteFieldsByModel('users', 'email', 'password');
686
+ * ```
687
+ *
688
+ * @param model - Model that holds the fields
689
+ * @param {string[]} fields - Fields to delete from the state
690
+ * @returns {this}
691
+ * @throws {UnsupportedFieldSelectionError} If the active driver does not support per-model field selection
692
+ */
693
+ deleteFieldsByModel(model: string, ...fields: string[]): this;
694
+ /**
695
+ * Remove given filters from the query builder state (JSON:API, NestJS, and Spatie)
696
+ *
697
+ * @param {string[]} filters - Filters to remove
698
+ * @returns {this}
699
+ * @throws {UnsupportedFilterError} If the active driver does not support filters
700
+ */
701
+ deleteFilters(...filters: string[]): this;
702
+ /**
703
+ * Remove selected related models from the query builder state (JSON:API and Spatie only)
704
+ *
705
+ * @param {string[]} includes - Models to remove
706
+ * @returns {this}
707
+ * @throws {UnsupportedIncludesError} If the active driver does not support includes
708
+ */
709
+ deleteIncludes(...includes: string[]): this;
710
+ /**
711
+ * Remove operator filters by field name (NestJS only)
712
+ *
713
+ * @param {string[]} fields - Field names of operator filters to remove
714
+ * @returns {this}
715
+ * @throws {UnsupportedFilterOperatorError} If the active driver does not support filter operators
716
+ */
717
+ deleteOperatorFilters(...fields: string[]): this;
718
+ /**
719
+ * Remove search term from the query builder state (NestJS only)
720
+ *
721
+ * @returns {this}
722
+ * @throws {UnsupportedSearchError} If the active driver does not support search
723
+ */
724
+ deleteSearch(): this;
725
+ /**
726
+ * Remove flat field selections from the query builder state (NestJS only)
727
+ *
728
+ * @param {string[]} fields - Fields to remove from selection
729
+ * @returns {this}
730
+ * @throws {UnsupportedSelectError} If the active driver does not support flat field selection
731
+ */
732
+ deleteSelect(...fields: string[]): this;
733
+ /**
734
+ * Remove sort rules from the query builder state (JSON:API, NestJS, and Spatie)
735
+ *
736
+ * @param sorts - Fields used for sorting to remove
737
+ * @returns {this}
738
+ * @throws {UnsupportedSortError} If the active driver does not support sorts
739
+ */
740
+ deleteSorts(...sorts: string[]): this;
741
+ /**
742
+ * Generate a URI accordingly to the given data and active driver
743
+ *
744
+ * @returns {Observable<string>} An observable that emits the generated URI
745
+ */
746
+ generateUri(): Observable<string>;
747
+ /**
748
+ * Clear the current state and reset the Query Builder to a fresh, clean condition
749
+ *
750
+ * @returns {this}
751
+ */
752
+ reset(): this;
753
+ /**
754
+ * Set the base URL to use for composing the address
755
+ *
756
+ * @param {string} baseUrl - The base URL
757
+ * @returns {this}
758
+ */
759
+ setBaseUrl(baseUrl: string): this;
760
+ /**
761
+ * Set the items per page number
762
+ *
763
+ * Validation is delegated to the active request strategy because the
764
+ * accepted range is driver-specific: nestjs-paginate additionally accepts
765
+ * `-1` as a "fetch all" sentinel, while Laravel, Spatie, and JSON:API
766
+ * require a positive integer.
767
+ *
768
+ * @param limit - Number of items per page (or `-1` to fetch all, NestJS only)
769
+ * @returns {this}
770
+ * @throws {import('../errors/invalid-limit.error').InvalidLimitError} If the value is not accepted by the active driver
771
+ */
772
+ setLimit(limit: number): this;
773
+ /**
774
+ * Set the page that the backend will use to paginate the result set
775
+ *
776
+ * @param page - Page number
777
+ * @returns {this}
778
+ */
779
+ setPage(page: number): this;
780
+ /**
781
+ * Set the API resource to run the query against
782
+ *
783
+ * @param {string} resource - Resource name (e.g. 'users' produces /users)
784
+ * @returns {this}
785
+ */
786
+ setResource(resource: string): this;
787
+ /**
788
+ * Set the search term for full-text search (NestJS only)
789
+ *
790
+ * Produces: `search=term`
791
+ *
792
+ * @param {string} search - The search term
793
+ * @returns {this}
794
+ * @throws {UnsupportedSearchError} If the active driver does not support search
795
+ */
796
+ setSearch(search: string): this;
797
+ }
798
+
799
+ /**
800
+ * Resolved response field key names with defaults applied
801
+ *
802
+ * Maps logical pagination concepts to the actual key names
803
+ * used in the API response. Unset values fall back to Laravel defaults.
804
+ *
805
+ * For NestJS responses, use dot-notation paths:
806
+ * ```typescript
807
+ * new ResponseOptions({
808
+ * currentPage: 'meta.currentPage',
809
+ * total: 'meta.totalItems'
810
+ * });
811
+ * ```
812
+ */
813
+ declare class ResponseOptions {
814
+ readonly currentPage: string;
815
+ readonly data: string;
816
+ readonly firstPageUrl: string;
817
+ readonly from: string;
818
+ readonly lastPage: string;
819
+ readonly lastPageUrl: string;
820
+ readonly nextPageUrl: string;
821
+ readonly path: string;
822
+ readonly perPage: string;
823
+ readonly prevPageUrl: string;
824
+ readonly to: string;
825
+ readonly total: string;
826
+ constructor(options: IPaginationConfig);
827
+ }
828
+
829
+ /**
830
+ * Strategy interface for parsing paginated API responses
831
+ *
832
+ * Each driver implements this interface to parse responses
833
+ * from the corresponding backend format into a PaginatedCollection.
834
+ */
835
+ interface IResponseStrategy {
836
+ /**
837
+ * Parse a raw API response into a typed PaginatedCollection
838
+ *
839
+ * @param response - The raw API response object
840
+ * @param options - The response key name configuration
841
+ * @returns A typed PaginatedCollection instance
842
+ */
843
+ paginate<T extends IPaginatedObject>(response: Record<string, unknown>, options: ResponseOptions): PaginatedCollection<T>;
844
+ }
845
+
846
+ declare class PaginationService {
847
+ /**
848
+ * Resolved response key name options
849
+ */
850
+ private _options;
851
+ /**
852
+ * The response strategy that parses responses for the active driver
853
+ */
854
+ private _responseStrategy;
855
+ constructor(responseStrategy: IResponseStrategy, options?: IPaginationConfig);
856
+ /**
857
+ * Transform a raw API response into a typed PaginatedCollection
858
+ *
859
+ * Delegates to the active driver's response strategy for parsing.
860
+ *
861
+ * @param response - The raw API response object
862
+ * @returns A typed PaginatedCollection instance
863
+ */
864
+ paginate<T extends IPaginatedObject>(response: {
865
+ [key: string]: any;
866
+ }): PaginatedCollection<T>;
867
+ }
868
+
869
+ /**
870
+ * Thrown when a limit value does not satisfy the active driver's constraints
871
+ *
872
+ * Validation is driver-scoped: most drivers require an integer `>= 1`, while
873
+ * the NestJS driver additionally accepts `-1` as a "fetch all items" sentinel
874
+ * (as documented by nestjs-paginate). The message is tailored accordingly so
875
+ * the caller understands which values are permitted.
876
+ */
877
+ declare class InvalidLimitError extends Error {
878
+ /**
879
+ * @param limit - The rejected limit value
880
+ * @param allowFetchAll - Whether the active driver accepts `-1` (fetch all)
881
+ */
882
+ constructor(limit: number, allowFetchAll?: boolean);
883
+ }
884
+
885
+ declare class InvalidPageNumberError extends Error {
886
+ constructor(page: number);
887
+ }
888
+
889
+ /**
890
+ * Error thrown when an invalid resource name is provided
891
+ *
892
+ * Resource name must be a non-empty string.
893
+ */
894
+ declare class InvalidResourceNameError extends Error {
895
+ constructor(resource: string | null | undefined);
896
+ }
897
+
898
+ declare class KeyNotFoundError extends Error {
899
+ constructor(key: string);
900
+ }
901
+
902
+ declare class UnselectableModelError extends Error {
903
+ constructor(model: string);
904
+ }
905
+
906
+ /**
907
+ * Error thrown when per-model field selection is attempted with a driver that does not support it
908
+ *
909
+ * Per-model field selection is only supported by the Spatie driver.
910
+ * Use `addSelect()` for NestJS flat field selection.
911
+ */
912
+ declare class UnsupportedFieldSelectionError extends Error {
913
+ constructor();
914
+ }
915
+
916
+ /**
917
+ * Error thrown when filters are attempted with a driver that does not support them
918
+ *
919
+ * Filters are only supported by the Spatie and NestJS drivers.
920
+ */
921
+ declare class UnsupportedFilterError extends Error {
922
+ constructor();
923
+ }
924
+
925
+ /**
926
+ * Error thrown when filter operators are attempted with a driver that does not support them
927
+ *
928
+ * Filter operators are only supported by the NestJS driver.
929
+ * Use `addFilter()` for Spatie implicit equality filters.
930
+ */
931
+ declare class UnsupportedFilterOperatorError extends Error {
932
+ constructor();
933
+ }
934
+
935
+ /**
936
+ * Error thrown when includes are attempted with a driver that does not support them
937
+ *
938
+ * Includes are only supported by the Spatie driver.
939
+ */
940
+ declare class UnsupportedIncludesError extends Error {
941
+ constructor();
942
+ }
943
+
944
+ /**
945
+ * Error thrown when search is attempted with a driver that does not support it
946
+ *
947
+ * Search is only supported by the NestJS driver.
948
+ */
949
+ declare class UnsupportedSearchError extends Error {
950
+ constructor();
951
+ }
952
+
953
+ /**
954
+ * Error thrown when flat field selection is attempted with a driver that does not support it
955
+ *
956
+ * Flat field selection is only supported by the NestJS driver.
957
+ * Use `addFields()` for Spatie per-model field selection.
958
+ */
959
+ declare class UnsupportedSelectError extends Error {
960
+ constructor();
961
+ }
962
+
963
+ /**
964
+ * Error thrown when sorts are attempted with a driver that does not support them
965
+ *
966
+ * Sorts are only supported by the Spatie and NestJS drivers.
967
+ */
968
+ declare class UnsupportedSortError extends Error {
969
+ constructor();
970
+ }
971
+
972
+ interface INestState {
973
+ nest: IQueryBuilderState;
974
+ }
975
+
976
+ interface IPage {
977
+ }
978
+
979
+ /**
980
+ * Request strategy for the JSON:API driver
981
+ *
982
+ * Generates URIs in the JSON:API format:
983
+ * - Fields: `fields[articles]=title,body&fields[people]=name`
984
+ * - Filters: `filter[status]=active`
985
+ * - Includes: `include=author,comments.author`
986
+ * - Pagination: `page[number]=1&page[size]=15`
987
+ * - Sort: `sort=-created_at,name` (- prefix = DESC)
988
+ *
989
+ * @see https://jsonapi.org/format/
990
+ */
991
+ declare class JsonApiRequestStrategy implements IRequestStrategy {
992
+ /**
993
+ * Accumulator for composing the URI string
994
+ */
995
+ private _uri;
996
+ /**
997
+ * Build a URI string from the given state using the JSON:API format
998
+ *
999
+ * @param state - The current query builder state
1000
+ * @param options - The query parameter key name configuration
1001
+ * @returns The composed URI string
1002
+ * @throws Error if resource is not set
1003
+ */
1004
+ buildUri(state: IQueryBuilderState, options: QueryBuilderOptions): string;
1005
+ /**
1006
+ * Validate that the given limit is accepted by the JSON:API driver
1007
+ *
1008
+ * The JSON:API specification leaves pagination semantics to the server and
1009
+ * does not define a "fetch all" sentinel, so only positive integers are
1010
+ * accepted.
1011
+ *
1012
+ * @param limit - The limit value to validate
1013
+ * @throws {InvalidLimitError} If the value is not a positive integer
1014
+ */
1015
+ validateLimit(limit: number): void;
1016
+ /**
1017
+ * Parse and append field selection parameters
1018
+ *
1019
+ * Validates that each field model exists either as the main resource
1020
+ * or in the includes list. Fields are grouped by type in bracket notation.
1021
+ *
1022
+ * @param state - The current query builder state
1023
+ * @param options - The query parameter key name configuration
1024
+ * @returns The generated field selection parameter string
1025
+ * @throws Error if resource is required but not set
1026
+ * @throws UnselectableModelError if a field model is not in resource or includes
1027
+ */
1028
+ private _parseFields;
1029
+ /**
1030
+ * Parse and append filter parameters
1031
+ *
1032
+ * Generates filter parameters in bracket notation: `filter[key]=value1,value2`
1033
+ *
1034
+ * @param state - The current query builder state
1035
+ * @param options - The query parameter key name configuration
1036
+ * @returns The generated filter parameter string
1037
+ */
1038
+ private _parseFilters;
1039
+ /**
1040
+ * Parse and append include parameters
1041
+ *
1042
+ * Generates: `include=author,comments.author`
1043
+ *
1044
+ * @param state - The current query builder state
1045
+ * @param options - The query parameter key name configuration
1046
+ * @returns The generated include parameter string
1047
+ */
1048
+ private _parseIncludes;
1049
+ /**
1050
+ * Parse and append pagination parameters in JSON:API bracket notation
1051
+ *
1052
+ * Generates: `page[number]=1&page[size]=15`
1053
+ *
1054
+ * @param state - The current query builder state
1055
+ * @param options - The query parameter key name configuration
1056
+ * @returns The generated pagination parameter string
1057
+ */
1058
+ private _parsePagination;
1059
+ /**
1060
+ * Parse and append sort parameters
1061
+ *
1062
+ * Generates: `sort=-field1,field2` where `-` prefix indicates DESC order
1063
+ *
1064
+ * @param state - The current query builder state
1065
+ * @param options - The query parameter key name configuration
1066
+ * @returns The generated sort parameter string
1067
+ */
1068
+ private _parseSort;
1069
+ /**
1070
+ * Determine the appropriate URI prefix based on the current accumulator state
1071
+ *
1072
+ * Returns the full base path with `?` for the first parameter,
1073
+ * or `&` for subsequent parameters.
1074
+ *
1075
+ * @param state - The current query builder state
1076
+ * @returns The prefix string to prepend to the next parameter
1077
+ */
1078
+ private _prepend;
1079
+ }
1080
+
1081
+ /**
1082
+ * Response strategy for the JSON:API driver
1083
+ *
1084
+ * Parses JSON:API pagination responses:
1085
+ * ```json
1086
+ * {
1087
+ * "data": [...],
1088
+ * "meta": {
1089
+ * "current-page": 1,
1090
+ * "per-page": 10,
1091
+ * "total": 100,
1092
+ * "page-count": 10,
1093
+ * "from": 1,
1094
+ * "to": 10
1095
+ * },
1096
+ * "links": {
1097
+ * "first": "url",
1098
+ * "prev": "url",
1099
+ * "next": "url",
1100
+ * "last": "url"
1101
+ * }
1102
+ * }
1103
+ * ```
1104
+ *
1105
+ * @see https://jsonapi.org/format/
1106
+ */
1107
+ declare class JsonApiResponseStrategy implements IResponseStrategy {
1108
+ /**
1109
+ * Parse a JSON:API pagination response into a PaginatedCollection
1110
+ *
1111
+ * Supports dot-notation key paths for accessing nested values.
1112
+ * Computes `from` and `to` from `currentPage` and `perPage` when
1113
+ * they are not directly available in the response.
1114
+ *
1115
+ * @param response - The raw API response object
1116
+ * @param options - The response key name configuration
1117
+ * @returns A typed PaginatedCollection instance
1118
+ */
1119
+ paginate<T extends IPaginatedObject>(response: Record<string, any>, options: ResponseOptions): PaginatedCollection<T>;
1120
+ /**
1121
+ * Resolve a value from a response object using a dot-notation path
1122
+ *
1123
+ * Supports both flat keys ('data') and nested paths ('meta.current-page').
1124
+ *
1125
+ * @param response - The raw response object
1126
+ * @param path - The dot-notation path to resolve
1127
+ * @returns The resolved value, or undefined if not found
1128
+ */
1129
+ private _resolve;
1130
+ /**
1131
+ * Resolve the "from" index value
1132
+ *
1133
+ * If the path resolves to a value in the response, use it.
1134
+ * Otherwise, compute it from currentPage and perPage:
1135
+ * `(currentPage - 1) * perPage + 1`
1136
+ *
1137
+ * @param response - The raw response object
1138
+ * @param options - The response key name configuration
1139
+ * @param currentPage - The current page number
1140
+ * @param perPage - The number of items per page
1141
+ * @returns The computed "from" index
1142
+ */
1143
+ private _resolveFrom;
1144
+ /**
1145
+ * Resolve the "to" index value
1146
+ *
1147
+ * If the path resolves to a value in the response, use it.
1148
+ * Otherwise, compute it from currentPage, perPage, and total:
1149
+ * `Math.min(currentPage * perPage, total)`
1150
+ *
1151
+ * @param response - The raw response object
1152
+ * @param options - The response key name configuration
1153
+ * @param currentPage - The current page number
1154
+ * @param perPage - The number of items per page
1155
+ * @param total - The total number of items
1156
+ * @returns The computed "to" index
1157
+ */
1158
+ private _resolveTo;
1159
+ }
1160
+
1161
+ /**
1162
+ * Request strategy for the Laravel (pagination-only) driver
1163
+ *
1164
+ * Generates simple pagination URIs:
1165
+ * - `/{resource}?limit=N&page=N`
1166
+ *
1167
+ * Filters, sorts, fields, includes, search, and select in state are ignored.
1168
+ */
1169
+ declare class LaravelRequestStrategy implements IRequestStrategy {
1170
+ /**
1171
+ * Build a pagination-only URI from the given state
1172
+ *
1173
+ * @param state - The current query builder state
1174
+ * @param options - The query parameter key name configuration
1175
+ * @returns The composed URI string
1176
+ * @throws Error if resource is not set
1177
+ */
1178
+ buildUri(state: IQueryBuilderState, options: QueryBuilderOptions): string;
1179
+ /**
1180
+ * Validate that the given limit is accepted by the Laravel driver
1181
+ *
1182
+ * Laravel pagination does not recognize `-1` as a "fetch all" sentinel,
1183
+ * so only positive integers are accepted.
1184
+ *
1185
+ * @param limit - The limit value to validate
1186
+ * @throws {InvalidLimitError} If the value is not a positive integer
1187
+ */
1188
+ validateLimit(limit: number): void;
1189
+ }
1190
+
1191
+ /**
1192
+ * Response strategy for the Laravel (pagination-only) driver
1193
+ *
1194
+ * Parses flat Laravel pagination responses:
1195
+ * ```json
1196
+ * {
1197
+ * "data": [...],
1198
+ * "current_page": 1,
1199
+ * "total": 100,
1200
+ * "per_page": 15,
1201
+ * "from": 1,
1202
+ * "to": 15,
1203
+ * ...
1204
+ * }
1205
+ * ```
1206
+ */
1207
+ declare class LaravelResponseStrategy implements IResponseStrategy {
1208
+ /**
1209
+ * Parse a flat Laravel pagination response into a PaginatedCollection
1210
+ *
1211
+ * @param response - The raw API response object
1212
+ * @param options - The response key name configuration
1213
+ * @returns A typed PaginatedCollection instance
1214
+ */
1215
+ paginate<T extends IPaginatedObject>(response: Record<string, any>, options: ResponseOptions): PaginatedCollection<T>;
1216
+ }
1217
+
1218
+ /**
1219
+ * Request strategy for the NestJS (nestjs-paginate) driver
1220
+ *
1221
+ * Generates URIs in the NestJS paginate format:
1222
+ * - Simple filters: `filter.field=value`
1223
+ * - Operator filters: `filter.field=$operator:value`
1224
+ * - Sorts: `sortBy=field1:DESC,field2:ASC`
1225
+ * - Select: `select=col1,col2`
1226
+ * - Search: `search=term`
1227
+ * - Pagination: `limit=N&page=N`
1228
+ *
1229
+ * @see https://github.com/ppetzold/nestjs-paginate
1230
+ */
1231
+ declare class NestjsRequestStrategy implements IRequestStrategy {
1232
+ /**
1233
+ * Accumulator for composing the URI string
1234
+ */
1235
+ private _uri;
1236
+ /**
1237
+ * Build a URI string from the given state using the NestJS paginate format
1238
+ *
1239
+ * @param state - The current query builder state
1240
+ * @param options - The query parameter key name configuration
1241
+ * @returns The composed URI string
1242
+ * @throws Error if model is not set
1243
+ */
1244
+ buildUri(state: IQueryBuilderState, options: QueryBuilderOptions): string;
1245
+ /**
1246
+ * Validate that the given limit is accepted by nestjs-paginate
1247
+ *
1248
+ * Accepts any integer `>= 1` as a page size, plus `-1` which nestjs-paginate
1249
+ * interprets as "fetch all items" (server must opt-in via `maxLimit: -1`).
1250
+ *
1251
+ * @param limit - The limit value to validate
1252
+ * @throws {InvalidLimitError} If the value is not an integer, or is 0, or is a negative number other than -1
1253
+ */
1254
+ validateLimit(limit: number): void;
1255
+ /**
1256
+ * Parse and append simple filter parameters
1257
+ *
1258
+ * Generates: `filter.field=value1,value2` for each filter
1259
+ *
1260
+ * @param state - The current query builder state
1261
+ * @param options - The query parameter key name configuration
1262
+ */
1263
+ private _parseFilters;
1264
+ /**
1265
+ * Parse and append the limit parameter
1266
+ *
1267
+ * @param state - The current query builder state
1268
+ * @param options - The query parameter key name configuration
1269
+ */
1270
+ private _parseLimit;
1271
+ /**
1272
+ * Parse and append operator filter parameters
1273
+ *
1274
+ * Groups operator filters by field and generates:
1275
+ * - Single value: `filter.field=$operator:value`
1276
+ * - Multiple values ($in, $btw): `filter.field=$operator:val1,val2`
1277
+ *
1278
+ * @param state - The current query builder state
1279
+ * @param options - The query parameter key name configuration
1280
+ */
1281
+ private _parseOperatorFilters;
1282
+ /**
1283
+ * Parse and append the page parameter
1284
+ *
1285
+ * @param state - The current query builder state
1286
+ * @param options - The query parameter key name configuration
1287
+ */
1288
+ private _parsePage;
1289
+ /**
1290
+ * Parse and append the search parameter
1291
+ *
1292
+ * Generates: `search=term`
1293
+ *
1294
+ * @param state - The current query builder state
1295
+ * @param options - The query parameter key name configuration
1296
+ */
1297
+ private _parseSearch;
1298
+ /**
1299
+ * Parse and append the select parameter
1300
+ *
1301
+ * Generates: `select=col1,col2`
1302
+ *
1303
+ * @param state - The current query builder state
1304
+ * @param options - The query parameter key name configuration
1305
+ */
1306
+ private _parseSelect;
1307
+ /**
1308
+ * Parse and append sort parameters
1309
+ *
1310
+ * Generates: `sortBy=field1:DESC,field2:ASC`
1311
+ *
1312
+ * @param state - The current query builder state
1313
+ * @param options - The query parameter key name configuration
1314
+ */
1315
+ private _parseSort;
1316
+ /**
1317
+ * Determine the appropriate URI prefix based on the current accumulator state
1318
+ *
1319
+ * Returns the full base path with `?` for the first parameter,
1320
+ * or `&` for subsequent parameters.
1321
+ *
1322
+ * @param state - The current query builder state
1323
+ * @returns The prefix string to prepend to the next parameter
1324
+ */
1325
+ private _prepend;
1326
+ }
1327
+
1328
+ /**
1329
+ * Response strategy for the NestJS (nestjs-paginate) driver
1330
+ *
1331
+ * Parses nested NestJS pagination responses:
1332
+ * ```json
1333
+ * {
1334
+ * "data": [...],
1335
+ * "meta": {
1336
+ * "currentPage": 1,
1337
+ * "totalItems": 100,
1338
+ * "itemsPerPage": 10,
1339
+ * "totalPages": 10
1340
+ * },
1341
+ * "links": {
1342
+ * "first": "url",
1343
+ * "previous": "url",
1344
+ * "next": "url",
1345
+ * "last": "url",
1346
+ * "current": "url"
1347
+ * }
1348
+ * }
1349
+ * ```
1350
+ *
1351
+ * @see https://github.com/ppetzold/nestjs-paginate
1352
+ */
1353
+ declare class NestjsResponseStrategy implements IResponseStrategy {
1354
+ /**
1355
+ * Parse a nested NestJS pagination response into a PaginatedCollection
1356
+ *
1357
+ * Supports dot-notation key paths for accessing nested values.
1358
+ * Computes `from` and `to` from `currentPage` and `itemsPerPage` when
1359
+ * they are not directly available in the response.
1360
+ *
1361
+ * @param response - The raw API response object
1362
+ * @param options - The response key name configuration
1363
+ * @returns A typed PaginatedCollection instance
1364
+ */
1365
+ paginate<T extends IPaginatedObject>(response: Record<string, any>, options: ResponseOptions): PaginatedCollection<T>;
1366
+ /**
1367
+ * Resolve a value from a response object using a dot-notation path
1368
+ *
1369
+ * Supports both flat keys ('data') and nested paths ('meta.currentPage').
1370
+ *
1371
+ * @param response - The raw response object
1372
+ * @param path - The dot-notation path to resolve
1373
+ * @returns The resolved value, or undefined if not found
1374
+ */
1375
+ private _resolve;
1376
+ /**
1377
+ * Resolve the "from" index value
1378
+ *
1379
+ * If the path resolves to a value in the response, use it.
1380
+ * Otherwise, compute it from currentPage and perPage:
1381
+ * `(currentPage - 1) * perPage + 1`
1382
+ *
1383
+ * @param response - The raw response object
1384
+ * @param options - The response key name configuration
1385
+ * @param currentPage - The current page number
1386
+ * @param perPage - The number of items per page
1387
+ * @returns The computed "from" index
1388
+ */
1389
+ private _resolveFrom;
1390
+ /**
1391
+ * Resolve the "to" index value
1392
+ *
1393
+ * If the path resolves to a value in the response, use it.
1394
+ * Otherwise, compute it from currentPage, perPage, and total:
1395
+ * `Math.min(currentPage * perPage, total)`
1396
+ *
1397
+ * @param response - The raw response object
1398
+ * @param options - The response key name configuration
1399
+ * @param currentPage - The current page number
1400
+ * @param perPage - The number of items per page
1401
+ * @param total - The total number of items
1402
+ * @returns The computed "to" index
1403
+ */
1404
+ private _resolveTo;
1405
+ }
1406
+
1407
+ /**
1408
+ * Request strategy for the Spatie Query Builder driver
1409
+ *
1410
+ * Generates URIs in the Spatie format:
1411
+ * - Fields: `fields[model]=col1,col2`
1412
+ * - Filters: `filter[field]=value`
1413
+ * - Includes: `include=model1,model2`
1414
+ * - Sorts: `sort=-field1,field2` (- prefix = DESC)
1415
+ * - Pagination: `limit=N&page=N`
1416
+ *
1417
+ * @see https://spatie.be/docs/laravel-query-builder
1418
+ */
1419
+ declare class SpatieRequestStrategy implements IRequestStrategy {
1420
+ /**
1421
+ * Accumulator for composing the URI string
1422
+ */
1423
+ private _uri;
1424
+ /**
1425
+ * Build a URI string from the given state using the Spatie format
1426
+ *
1427
+ * @param state - The current query builder state
1428
+ * @param options - The query parameter key name configuration
1429
+ * @returns The composed URI string
1430
+ * @throws Error if resource is not set
1431
+ */
1432
+ buildUri(state: IQueryBuilderState, options: QueryBuilderOptions): string;
1433
+ /**
1434
+ * Validate that the given limit is accepted by the Spatie driver
1435
+ *
1436
+ * Spatie query-builder does not recognize `-1` as a "fetch all" sentinel,
1437
+ * so only positive integers are accepted.
1438
+ *
1439
+ * @param limit - The limit value to validate
1440
+ * @throws {InvalidLimitError} If the value is not a positive integer
1441
+ */
1442
+ validateLimit(limit: number): void;
1443
+ /**
1444
+ * Parse and append field selection parameters
1445
+ *
1446
+ * Validates that each field model exists either as the main resource
1447
+ * or in the includes list. Fields are grouped by model in bracket notation.
1448
+ *
1449
+ * @param state - The current query builder state
1450
+ * @param options - The query parameter key name configuration
1451
+ * @returns The generated field selection parameter string
1452
+ * @throws Error if resource is required but not set
1453
+ * @throws UnselectableModelError if a field model is not in resource or includes
1454
+ */
1455
+ private _parseFields;
1456
+ /**
1457
+ * Parse and append filter parameters
1458
+ *
1459
+ * Generates filter parameters in bracket notation: `filter[key]=value1,value2`
1460
+ *
1461
+ * @param state - The current query builder state
1462
+ * @param options - The query parameter key name configuration
1463
+ * @returns The generated filter parameter string
1464
+ */
1465
+ private _parseFilters;
1466
+ /**
1467
+ * Parse and append include parameters
1468
+ *
1469
+ * Generates: `include=model1,model2`
1470
+ *
1471
+ * @param state - The current query builder state
1472
+ * @param options - The query parameter key name configuration
1473
+ * @returns The generated include parameter string
1474
+ */
1475
+ private _parseIncludes;
1476
+ /**
1477
+ * Parse and append the limit parameter
1478
+ *
1479
+ * @param state - The current query builder state
1480
+ * @param options - The query parameter key name configuration
1481
+ * @returns The generated limit parameter string
1482
+ */
1483
+ private _parseLimit;
1484
+ /**
1485
+ * Parse and append the page parameter
1486
+ *
1487
+ * @param state - The current query builder state
1488
+ * @param options - The query parameter key name configuration
1489
+ * @returns The generated page parameter string
1490
+ */
1491
+ private _parsePage;
1492
+ /**
1493
+ * Parse and append sort parameters
1494
+ *
1495
+ * Generates: `sort=-field1,field2` where `-` prefix indicates DESC order
1496
+ *
1497
+ * @param state - The current query builder state
1498
+ * @param options - The query parameter key name configuration
1499
+ * @returns The generated sort parameter string
1500
+ */
1501
+ private _parseSort;
1502
+ /**
1503
+ * Determine the appropriate URI prefix based on the current accumulator state
1504
+ *
1505
+ * Returns the full base path with `?` for the first parameter,
1506
+ * or `&` for subsequent parameters.
1507
+ *
1508
+ * @param state - The current query builder state
1509
+ * @returns The prefix string to prepend to the next parameter
1510
+ */
1511
+ private _prepend;
1512
+ }
1513
+
1514
+ /**
1515
+ * Response strategy for the Spatie Query Builder driver
1516
+ *
1517
+ * Parses flat Laravel pagination responses:
1518
+ * ```json
1519
+ * {
1520
+ * "data": [...],
1521
+ * "current_page": 1,
1522
+ * "total": 100,
1523
+ * "per_page": 15,
1524
+ * "from": 1,
1525
+ * "to": 15,
1526
+ * ...
1527
+ * }
1528
+ * ```
1529
+ *
1530
+ * @see https://spatie.be/docs/laravel-query-builder
1531
+ */
1532
+ declare class SpatieResponseStrategy implements IResponseStrategy {
1533
+ /**
1534
+ * Parse a flat Laravel pagination response into a PaginatedCollection
1535
+ *
1536
+ * @param response - The raw API response object
1537
+ * @param options - The response key name configuration
1538
+ * @returns A typed PaginatedCollection instance
1539
+ */
1540
+ paginate<T extends IPaginatedObject>(response: Record<string, any>, options: ResponseOptions): PaginatedCollection<T>;
1541
+ }
1542
+
1543
+ export { DriverEnum, FilterOperatorEnum, InvalidLimitError, InvalidPageNumberError, InvalidResourceNameError, JsonApiRequestStrategy, JsonApiResponseStrategy, KeyNotFoundError, LaravelRequestStrategy, LaravelResponseStrategy, NestjsRequestStrategy, NestjsResponseStrategy, NgQubeeModule, NgQubeeService, PaginatedCollection, PaginationService, SortEnum, SpatieRequestStrategy, SpatieResponseStrategy, UnselectableModelError, UnsupportedFieldSelectionError, UnsupportedFilterError, UnsupportedFilterOperatorError, UnsupportedIncludesError, UnsupportedSearchError, UnsupportedSelectError, UnsupportedSortError, provideNgQubee };
1544
+ export type { IConfig, IFields, IFilters, INestState, IOperatorFilter, IPage, IPaginatedObject, IPaginationConfig, IQueryBuilderConfig, IQueryBuilderState, IRequestStrategy, IResponseStrategy, ISort };