ng-qubee 3.2.0 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -768
- package/fesm2022/ng-qubee.mjs +2376 -1732
- package/fesm2022/ng-qubee.mjs.map +1 -1
- package/package.json +17 -8
- package/types/ng-qubee.d.ts +784 -261
package/types/ng-qubee.d.ts
CHANGED
|
@@ -49,7 +49,26 @@ declare enum DriverEnum {
|
|
|
49
49
|
JSON_API = "json-api",
|
|
50
50
|
LARAVEL = "laravel",
|
|
51
51
|
NESTJS = "nestjs",
|
|
52
|
-
|
|
52
|
+
POSTGREST = "postgrest",
|
|
53
|
+
SPATIE = "spatie",
|
|
54
|
+
STRAPI = "strapi"
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Enum representing the wire-level pagination mechanism
|
|
59
|
+
*
|
|
60
|
+
* `QUERY` (default) — the request strategy emits `limit` and `offset` (or
|
|
61
|
+
* equivalent) query parameters on the URL.
|
|
62
|
+
*
|
|
63
|
+
* `RANGE` — the request strategy omits URL-based pagination and the
|
|
64
|
+
* consumer instead applies HTTP request headers returned by
|
|
65
|
+
* `NgQubeeService.paginationHeaders()`. Currently honoured only by the
|
|
66
|
+
* PostgREST driver, which maps it to `Range-Unit: items` + `Range: 0-9`.
|
|
67
|
+
* Other drivers ignore the setting.
|
|
68
|
+
*/
|
|
69
|
+
declare enum PaginationModeEnum {
|
|
70
|
+
QUERY = "query",
|
|
71
|
+
RANGE = "range"
|
|
53
72
|
}
|
|
54
73
|
|
|
55
74
|
/**
|
|
@@ -135,6 +154,12 @@ interface IQueryBuilderConfig {
|
|
|
135
154
|
interface IConfig {
|
|
136
155
|
/** The pagination driver to use */
|
|
137
156
|
driver: DriverEnum;
|
|
157
|
+
/**
|
|
158
|
+
* Wire-level pagination mechanism. Defaults to `PaginationModeEnum.QUERY`
|
|
159
|
+
* when omitted. Currently honoured only by the PostgREST driver; other
|
|
160
|
+
* drivers ignore it.
|
|
161
|
+
*/
|
|
162
|
+
pagination?: PaginationModeEnum;
|
|
138
163
|
/** Custom key names for request query parameters */
|
|
139
164
|
request?: IQueryBuilderConfig;
|
|
140
165
|
/** Custom key names for response field mapping */
|
|
@@ -158,6 +183,11 @@ declare class NgQubeeModule {
|
|
|
158
183
|
* Build the core provider list shared by `provideNgQubee()` and
|
|
159
184
|
* `NgQubeeModule.forRoot()`
|
|
160
185
|
*
|
|
186
|
+
* Looks up the driver definition from the registry and calls its three
|
|
187
|
+
* factories — request strategy, response strategy, response options.
|
|
188
|
+
* Adding a driver means adding one entry to `DRIVERS`; this function
|
|
189
|
+
* does not change.
|
|
190
|
+
*
|
|
161
191
|
* Exposes the driver, strategies, and options via injection tokens so that
|
|
162
192
|
* consumers can request a component-scoped instance of the services through
|
|
163
193
|
* `provideNgQubeeInstance()`.
|
|
@@ -240,17 +270,27 @@ declare function provideNgQubee(config: IConfig): EnvironmentProviders;
|
|
|
240
270
|
declare function provideNgQubeeInstance(): Provider[];
|
|
241
271
|
|
|
242
272
|
/**
|
|
243
|
-
* Enum representing the available filter operators for
|
|
273
|
+
* Enum representing the available filter operators for explicit operator
|
|
274
|
+
* filters
|
|
244
275
|
*
|
|
245
|
-
*
|
|
246
|
-
* `filter.field=$operator:value`
|
|
276
|
+
* NestJS encodes these with the `$` prefix at the wire level
|
|
277
|
+
* (`filter.field=$operator:value`); PostgREST translates them to its own
|
|
278
|
+
* prefix notation (`col=eq.val`, `col=is.null`, etc.). The enum values are
|
|
279
|
+
* intentionally the NestJS form; each driver's request strategy is
|
|
280
|
+
* responsible for mapping them into its own shape.
|
|
281
|
+
*
|
|
282
|
+
* `FTS`, `PLFTS`, `PHFTS`, `WFTS` are PostgREST-native full-text search
|
|
283
|
+
* variants; they throw `UnsupportedFilterOperatorError` on every other
|
|
284
|
+
* driver that does not recognise them.
|
|
247
285
|
*
|
|
248
286
|
* @see https://github.com/ppetzold/nestjs-paginate
|
|
287
|
+
* @see https://postgrest.org/en/stable/api.html#operators
|
|
249
288
|
*/
|
|
250
289
|
declare enum FilterOperatorEnum {
|
|
251
290
|
BTW = "$btw",
|
|
252
291
|
CONTAINS = "$contains",
|
|
253
292
|
EQ = "$eq",
|
|
293
|
+
FTS = "$fts",
|
|
254
294
|
GT = "$gt",
|
|
255
295
|
GTE = "$gte",
|
|
256
296
|
ILIKE = "$ilike",
|
|
@@ -259,7 +299,10 @@ declare enum FilterOperatorEnum {
|
|
|
259
299
|
LTE = "$lte",
|
|
260
300
|
NOT = "$not",
|
|
261
301
|
NULL = "$null",
|
|
262
|
-
|
|
302
|
+
PHFTS = "$phfts",
|
|
303
|
+
PLFTS = "$plfts",
|
|
304
|
+
SW = "$sw",
|
|
305
|
+
WFTS = "$wfts"
|
|
263
306
|
}
|
|
264
307
|
|
|
265
308
|
declare enum SortEnum {
|
|
@@ -340,6 +383,33 @@ interface IQueryBuilderState {
|
|
|
340
383
|
sorts: ISort[];
|
|
341
384
|
}
|
|
342
385
|
|
|
386
|
+
/**
|
|
387
|
+
* Capability flags declared by an `IRequestStrategy`
|
|
388
|
+
*
|
|
389
|
+
* Single source of truth for what a driver supports. Replaces the inline
|
|
390
|
+
* `DriverEnum` allowlists previously scattered across `NgQubeeService`'s
|
|
391
|
+
* `_assertDriver(...)` call sites.
|
|
392
|
+
*
|
|
393
|
+
* Adding a new driver means defining one of these objects on the new
|
|
394
|
+
* strategy class — `NgQubeeService` does not need to be touched.
|
|
395
|
+
*/
|
|
396
|
+
interface IStrategyCapabilities {
|
|
397
|
+
/** Per-model field selection (e.g. JSON:API `fields[type]=col1,col2`) */
|
|
398
|
+
readonly fields: boolean;
|
|
399
|
+
/** Simple key-value filters (e.g. `filter.status=active`) */
|
|
400
|
+
readonly filters: boolean;
|
|
401
|
+
/** Related-resource includes (e.g. JSON:API/Spatie `include=author`) */
|
|
402
|
+
readonly includes: boolean;
|
|
403
|
+
/** Filters with explicit operators (e.g. NestJS `$gte`, PostgREST `gte.`) */
|
|
404
|
+
readonly operatorFilters: boolean;
|
|
405
|
+
/** Global full-text search via a single term (NestJS `search=…`) */
|
|
406
|
+
readonly search: boolean;
|
|
407
|
+
/** Flat column-list selection (NestJS / PostgREST `select=col1,col2`) */
|
|
408
|
+
readonly select: boolean;
|
|
409
|
+
/** Sort ordering on one or more fields */
|
|
410
|
+
readonly sort: boolean;
|
|
411
|
+
}
|
|
412
|
+
|
|
343
413
|
/**
|
|
344
414
|
* Resolved query parameter key names with defaults applied
|
|
345
415
|
*
|
|
@@ -367,6 +437,14 @@ declare class QueryBuilderOptions {
|
|
|
367
437
|
* in the format expected by the corresponding backend.
|
|
368
438
|
*/
|
|
369
439
|
interface IRequestStrategy {
|
|
440
|
+
/**
|
|
441
|
+
* Capability flags declared by this driver
|
|
442
|
+
*
|
|
443
|
+
* Read by `NgQubeeService` to gate feature methods (e.g. `addFilter`)
|
|
444
|
+
* without hardcoding `DriverEnum` checks. Each strategy returns a
|
|
445
|
+
* static, immutable capability map.
|
|
446
|
+
*/
|
|
447
|
+
readonly capabilities: IStrategyCapabilities;
|
|
370
448
|
/**
|
|
371
449
|
* Build a URI string from the given query builder state
|
|
372
450
|
*
|
|
@@ -375,6 +453,23 @@ interface IRequestStrategy {
|
|
|
375
453
|
* @returns The composed URI string
|
|
376
454
|
*/
|
|
377
455
|
buildUri(state: IQueryBuilderState, options: QueryBuilderOptions): string;
|
|
456
|
+
/**
|
|
457
|
+
* Compute HTTP request headers carrying pagination metadata
|
|
458
|
+
*
|
|
459
|
+
* Honoured only by drivers that support header-based pagination (the
|
|
460
|
+
* PostgREST driver configured with `PaginationModeEnum.RANGE`). All
|
|
461
|
+
* other drivers should return `null` — which is also the default when
|
|
462
|
+
* a driver does not override this method.
|
|
463
|
+
*
|
|
464
|
+
* When the method returns a non-null object, `NgQubeeService.buildUri`
|
|
465
|
+
* is expected to have already omitted URL-level pagination params for
|
|
466
|
+
* that request; the consumer then merges these headers into the HTTP
|
|
467
|
+
* call so the server knows the requested range.
|
|
468
|
+
*
|
|
469
|
+
* @param state - The current query builder state
|
|
470
|
+
* @returns A map of header name → value, or `null` when not applicable
|
|
471
|
+
*/
|
|
472
|
+
buildPaginationHeaders?(state: IQueryBuilderState): Record<string, string> | null;
|
|
378
473
|
/**
|
|
379
474
|
* Assert that the given limit value is valid for this driver
|
|
380
475
|
*
|
|
@@ -654,13 +749,17 @@ declare class NgQubeeService {
|
|
|
654
749
|
uri$: Observable<string>;
|
|
655
750
|
constructor(_nestService: NestService, requestStrategy: IRequestStrategy, driver: DriverEnum, options?: QueryBuilderOptions);
|
|
656
751
|
/**
|
|
657
|
-
* Assert that the active
|
|
752
|
+
* Assert that the active strategy declares support for a capability
|
|
658
753
|
*
|
|
659
|
-
*
|
|
660
|
-
*
|
|
661
|
-
*
|
|
754
|
+
* Reads from `IRequestStrategy.capabilities` rather than the driver
|
|
755
|
+
* enum so adding a new driver only requires declaring its capability
|
|
756
|
+
* map — this method does not change.
|
|
757
|
+
*
|
|
758
|
+
* @param flag - The capability key to check
|
|
759
|
+
* @param error - The error to throw if the capability is unsupported
|
|
760
|
+
* @throws The provided error if the active strategy lacks the capability
|
|
662
761
|
*/
|
|
663
|
-
private
|
|
762
|
+
private _assertCapability;
|
|
664
763
|
/**
|
|
665
764
|
* Add fields to the select statement for the given model (JSON:API and Spatie only)
|
|
666
765
|
*
|
|
@@ -671,7 +770,7 @@ declare class NgQubeeService {
|
|
|
671
770
|
*/
|
|
672
771
|
addFields(model: string, fields: string[]): this;
|
|
673
772
|
/**
|
|
674
|
-
* Add a filter with the given value(s) (JSON:API, NestJS, and Spatie)
|
|
773
|
+
* Add a filter with the given value(s) (JSON:API, NestJS, PostgREST, and Spatie)
|
|
675
774
|
*
|
|
676
775
|
* Produces: `filter[field]=value` (JSON:API / Spatie) or `filter.field=value` (NestJS)
|
|
677
776
|
*
|
|
@@ -682,7 +781,7 @@ declare class NgQubeeService {
|
|
|
682
781
|
*/
|
|
683
782
|
addFilter(field: string, ...values: (string | number | boolean)[]): this;
|
|
684
783
|
/**
|
|
685
|
-
* Add a filter with an explicit operator (NestJS
|
|
784
|
+
* Add a filter with an explicit operator (NestJS and PostgREST)
|
|
686
785
|
*
|
|
687
786
|
* Produces: `filter.field=$operator:value`
|
|
688
787
|
*
|
|
@@ -702,7 +801,7 @@ declare class NgQubeeService {
|
|
|
702
801
|
*/
|
|
703
802
|
addIncludes(...models: string[]): this;
|
|
704
803
|
/**
|
|
705
|
-
* Add flat field selection (NestJS
|
|
804
|
+
* Add flat field selection (NestJS and PostgREST)
|
|
706
805
|
*
|
|
707
806
|
* Produces: `select=col1,col2`
|
|
708
807
|
*
|
|
@@ -712,7 +811,7 @@ declare class NgQubeeService {
|
|
|
712
811
|
*/
|
|
713
812
|
addSelect(...fields: string[]): this;
|
|
714
813
|
/**
|
|
715
|
-
* Add a field with a sort criteria (JSON:API, NestJS, and Spatie)
|
|
814
|
+
* Add a field with a sort criteria (JSON:API, NestJS, PostgREST, and Spatie)
|
|
716
815
|
*
|
|
717
816
|
* @param field - Field to use for sorting
|
|
718
817
|
* @param {SortEnum} order - A value from the SortEnum enumeration
|
|
@@ -756,7 +855,7 @@ declare class NgQubeeService {
|
|
|
756
855
|
*/
|
|
757
856
|
deleteFieldsByModel(model: string, ...fields: string[]): this;
|
|
758
857
|
/**
|
|
759
|
-
* Remove given filters from the query builder state (JSON:API, NestJS, and Spatie)
|
|
858
|
+
* Remove given filters from the query builder state (JSON:API, NestJS, PostgREST, and Spatie)
|
|
760
859
|
*
|
|
761
860
|
* @param {string[]} filters - Filters to remove
|
|
762
861
|
* @returns {this}
|
|
@@ -772,7 +871,7 @@ declare class NgQubeeService {
|
|
|
772
871
|
*/
|
|
773
872
|
deleteIncludes(...includes: string[]): this;
|
|
774
873
|
/**
|
|
775
|
-
* Remove operator filters by field name (NestJS
|
|
874
|
+
* Remove operator filters by field name (NestJS and PostgREST)
|
|
776
875
|
*
|
|
777
876
|
* @param {string[]} fields - Field names of operator filters to remove
|
|
778
877
|
* @returns {this}
|
|
@@ -787,7 +886,7 @@ declare class NgQubeeService {
|
|
|
787
886
|
*/
|
|
788
887
|
deleteSearch(): this;
|
|
789
888
|
/**
|
|
790
|
-
* Remove flat field selections from the query builder state (NestJS
|
|
889
|
+
* Remove flat field selections from the query builder state (NestJS and PostgREST)
|
|
791
890
|
*
|
|
792
891
|
* @param {string[]} fields - Fields to remove from selection
|
|
793
892
|
* @returns {this}
|
|
@@ -795,7 +894,7 @@ declare class NgQubeeService {
|
|
|
795
894
|
*/
|
|
796
895
|
deleteSelect(...fields: string[]): this;
|
|
797
896
|
/**
|
|
798
|
-
* Remove sort rules from the query builder state (JSON:API, NestJS, and Spatie)
|
|
897
|
+
* Remove sort rules from the query builder state (JSON:API, NestJS, PostgREST, and Spatie)
|
|
799
898
|
*
|
|
800
899
|
* @param sorts - Fields used for sorting to remove
|
|
801
900
|
* @returns {this}
|
|
@@ -870,6 +969,19 @@ declare class NgQubeeService {
|
|
|
870
969
|
* @returns {this}
|
|
871
970
|
*/
|
|
872
971
|
nextPage(): this;
|
|
972
|
+
/**
|
|
973
|
+
* HTTP request headers the active driver wants the consumer to apply
|
|
974
|
+
*
|
|
975
|
+
* Returns `null` for drivers that pass all pagination metadata on the
|
|
976
|
+
* URL (Laravel, Spatie, JSON:API, NestJS, and PostgREST in its default
|
|
977
|
+
* QUERY mode). Returns a map of header name → value when the active
|
|
978
|
+
* driver uses HTTP headers instead — today, only the PostgREST driver
|
|
979
|
+
* configured with `PaginationModeEnum.RANGE`, which yields
|
|
980
|
+
* `{ 'Range-Unit': 'items', 'Range': 'from-to' }`.
|
|
981
|
+
*
|
|
982
|
+
* @returns Map of headers to apply to the HTTP request, or `null` when not needed
|
|
983
|
+
*/
|
|
984
|
+
paginationHeaders(): Record<string, string> | null;
|
|
873
985
|
/**
|
|
874
986
|
* Navigate to the previous page
|
|
875
987
|
*
|
|
@@ -939,6 +1051,27 @@ declare class NgQubeeService {
|
|
|
939
1051
|
static ɵprov: i0.ɵɵInjectableDeclaration<NgQubeeService>;
|
|
940
1052
|
}
|
|
941
1053
|
|
|
1054
|
+
/**
|
|
1055
|
+
* A minimal bag of HTTP response headers that a response strategy can read
|
|
1056
|
+
* by name.
|
|
1057
|
+
*
|
|
1058
|
+
* Accepts anything that exposes a `.get(name): string | null` method
|
|
1059
|
+
* (Angular's `HttpHeaders`, the DOM `Headers` class) or a plain object
|
|
1060
|
+
* keyed by header name. Consumers should not need to convert between them.
|
|
1061
|
+
*/
|
|
1062
|
+
type HeaderBag = {
|
|
1063
|
+
get(name: string): string | null;
|
|
1064
|
+
} | Record<string, string | null | undefined>;
|
|
1065
|
+
/**
|
|
1066
|
+
* Read a header value by name from a `HeaderBag`, regardless of whether the
|
|
1067
|
+
* bag exposes a `.get()` accessor or plain property access.
|
|
1068
|
+
*
|
|
1069
|
+
* @param bag - The header bag to read from
|
|
1070
|
+
* @param name - The header name (case-sensitivity follows the underlying bag)
|
|
1071
|
+
* @returns The header value, or `null` if absent or the bag itself is falsy
|
|
1072
|
+
*/
|
|
1073
|
+
declare function readHeader(bag: HeaderBag | null | undefined, name: string): string | null;
|
|
1074
|
+
|
|
942
1075
|
/**
|
|
943
1076
|
* Resolved response field key names with defaults applied
|
|
944
1077
|
*
|
|
@@ -979,11 +1112,16 @@ interface IResponseStrategy {
|
|
|
979
1112
|
/**
|
|
980
1113
|
* Parse a raw API response into a typed PaginatedCollection
|
|
981
1114
|
*
|
|
982
|
-
* @param response - The raw API response object
|
|
1115
|
+
* @param response - The raw API response object (body). For drivers that
|
|
1116
|
+
* emit a bare array body (e.g. PostgREST), pass the array here.
|
|
983
1117
|
* @param options - The response key name configuration
|
|
1118
|
+
* @param headers - Optional HTTP response headers. Drivers that carry
|
|
1119
|
+
* pagination metadata in headers (PostgREST's `Content-Range`) read from
|
|
1120
|
+
* this bag; body-only drivers ignore it. Accepts anything with a `.get()`
|
|
1121
|
+
* accessor (`HttpHeaders`, `Headers`) or a plain `Record<string, string>`.
|
|
984
1122
|
* @returns A typed PaginatedCollection instance
|
|
985
1123
|
*/
|
|
986
|
-
paginate<T extends IPaginatedObject>(response: Record<string, unknown>, options: ResponseOptions): PaginatedCollection<T>;
|
|
1124
|
+
paginate<T extends IPaginatedObject>(response: Record<string, unknown>, options: ResponseOptions, headers?: HeaderBag): PaginatedCollection<T>;
|
|
987
1125
|
}
|
|
988
1126
|
|
|
989
1127
|
declare class PaginationService {
|
|
@@ -1015,16 +1153,44 @@ declare class PaginationService {
|
|
|
1015
1153
|
* Server-emitted `0` (empty collection edge case) and absent fields are
|
|
1016
1154
|
* treated as "no useful info" and leave `isLastPageKnown: false`.
|
|
1017
1155
|
*
|
|
1018
|
-
* @param response - The raw API response
|
|
1156
|
+
* @param response - The raw API response body. For drivers that emit a
|
|
1157
|
+
* bare array (PostgREST), pass the array.
|
|
1158
|
+
* @param headers - Optional HTTP response headers. Required by the
|
|
1159
|
+
* PostgREST driver (reads `Content-Range` for pagination metadata);
|
|
1160
|
+
* body-only drivers ignore it. Accepts Angular's `HttpHeaders`, the
|
|
1161
|
+
* native `Headers` class, or a plain `Record<string, string>`.
|
|
1019
1162
|
* @returns A typed PaginatedCollection instance
|
|
1020
1163
|
*/
|
|
1021
1164
|
paginate<T extends IPaginatedObject>(response: {
|
|
1022
1165
|
[key: string]: any;
|
|
1023
|
-
}): PaginatedCollection<T>;
|
|
1166
|
+
}, headers?: HeaderBag): PaginatedCollection<T>;
|
|
1024
1167
|
static ɵfac: i0.ɵɵFactoryDeclaration<PaginationService, never>;
|
|
1025
1168
|
static ɵprov: i0.ɵɵInjectableDeclaration<PaginationService>;
|
|
1026
1169
|
}
|
|
1027
1170
|
|
|
1171
|
+
/**
|
|
1172
|
+
* Thrown when a filter operator receives a value array of the wrong shape
|
|
1173
|
+
*
|
|
1174
|
+
* Some operators have arity or type constraints that the library enforces
|
|
1175
|
+
* at call time so misuse fails loudly instead of silently emitting invalid
|
|
1176
|
+
* server requests:
|
|
1177
|
+
*
|
|
1178
|
+
* - `BTW` requires exactly two values (min, max).
|
|
1179
|
+
* - `NULL` requires exactly one boolean value (`true` for `IS NULL`,
|
|
1180
|
+
* `false` for `IS NOT NULL`).
|
|
1181
|
+
*
|
|
1182
|
+
* Operators with looser shape rules leave validation to the server; this
|
|
1183
|
+
* error is reserved for cases where the library itself can detect the
|
|
1184
|
+
* problem unambiguously from the call site.
|
|
1185
|
+
*/
|
|
1186
|
+
declare class InvalidFilterOperatorValueError extends Error {
|
|
1187
|
+
/**
|
|
1188
|
+
* @param operator - The operator that rejected the values
|
|
1189
|
+
* @param reason - Short human-readable explanation of the constraint
|
|
1190
|
+
*/
|
|
1191
|
+
constructor(operator: FilterOperatorEnum, reason: string);
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1028
1194
|
/**
|
|
1029
1195
|
* Thrown when a limit value does not satisfy the active driver's constraints
|
|
1030
1196
|
*
|
|
@@ -1193,185 +1359,264 @@ declare const NG_QUBEE_RESPONSE_STRATEGY: InjectionToken<IResponseStrategy>;
|
|
|
1193
1359
|
declare const NG_QUBEE_RESPONSE_OPTIONS: InjectionToken<ResponseOptions>;
|
|
1194
1360
|
|
|
1195
1361
|
/**
|
|
1196
|
-
*
|
|
1362
|
+
* Base class for request strategies
|
|
1197
1363
|
*
|
|
1198
|
-
*
|
|
1199
|
-
* -
|
|
1200
|
-
* -
|
|
1201
|
-
* -
|
|
1202
|
-
*
|
|
1203
|
-
* -
|
|
1364
|
+
* Concentrates the glue every concrete strategy used to copy: the
|
|
1365
|
+
* resource-required guard, the `?`/`&` URL composition, and the default
|
|
1366
|
+
* positive-integer `validateLimit`. Concrete strategies override only
|
|
1367
|
+
* the parts that differ — the per-driver wire format goes into a single
|
|
1368
|
+
* `protected parts(state, options): string[]` method that returns the
|
|
1369
|
+
* ordered query-string segments the base then joins.
|
|
1204
1370
|
*
|
|
1205
|
-
*
|
|
1371
|
+
* Drivers that need a non-default `validateLimit` (e.g. NestJS, which
|
|
1372
|
+
* accepts `-1` as a fetch-all sentinel) override that method directly.
|
|
1206
1373
|
*/
|
|
1207
|
-
declare class
|
|
1374
|
+
declare abstract class AbstractRequestStrategy implements IRequestStrategy {
|
|
1208
1375
|
/**
|
|
1209
|
-
*
|
|
1376
|
+
* Capability declaration for this driver
|
|
1377
|
+
*
|
|
1378
|
+
* Concrete strategies must provide a static, immutable capability map
|
|
1379
|
+
* so `NgQubeeService._assertCapability(...)` can read it.
|
|
1210
1380
|
*/
|
|
1211
|
-
|
|
1381
|
+
abstract readonly capabilities: IStrategyCapabilities;
|
|
1212
1382
|
/**
|
|
1213
|
-
*
|
|
1383
|
+
* Compose the full request URI from the given state
|
|
1384
|
+
*
|
|
1385
|
+
* Template method: validates the resource, computes the base path,
|
|
1386
|
+
* delegates the per-driver query-string segments to `parts(...)`, and
|
|
1387
|
+
* joins them with the conventional `?`/`&` separators.
|
|
1214
1388
|
*
|
|
1215
1389
|
* @param state - The current query builder state
|
|
1216
1390
|
* @param options - The query parameter key name configuration
|
|
1217
1391
|
* @returns The composed URI string
|
|
1218
|
-
* @throws Error if resource is not set
|
|
1392
|
+
* @throws Error if the resource is not set
|
|
1219
1393
|
*/
|
|
1220
1394
|
buildUri(state: IQueryBuilderState, options: QueryBuilderOptions): string;
|
|
1221
1395
|
/**
|
|
1222
|
-
* Validate that
|
|
1396
|
+
* Validate that a limit value is acceptable for this driver
|
|
1223
1397
|
*
|
|
1224
|
-
*
|
|
1225
|
-
*
|
|
1226
|
-
* accepted.
|
|
1398
|
+
* Default policy: positive integer. Drivers that recognise a sentinel
|
|
1399
|
+
* (NestJS treats `-1` as "fetch all") override this method.
|
|
1227
1400
|
*
|
|
1228
1401
|
* @param limit - The limit value to validate
|
|
1229
1402
|
* @throws {InvalidLimitError} If the value is not a positive integer
|
|
1230
1403
|
*/
|
|
1231
1404
|
validateLimit(limit: number): void;
|
|
1232
1405
|
/**
|
|
1233
|
-
*
|
|
1406
|
+
* Per-driver query-string segments, in emission order
|
|
1234
1407
|
*
|
|
1235
|
-
*
|
|
1236
|
-
*
|
|
1408
|
+
* Each entry is one `key=value` (or `key=v1&key=v2` for compound
|
|
1409
|
+
* params like PostgREST's `BTW`). Empty arrays are valid and produce
|
|
1410
|
+
* a URI containing only the resource path.
|
|
1237
1411
|
*
|
|
1238
1412
|
* @param state - The current query builder state
|
|
1239
1413
|
* @param options - The query parameter key name configuration
|
|
1240
|
-
* @returns
|
|
1241
|
-
* @throws Error if resource is required but not set
|
|
1242
|
-
* @throws UnselectableModelError if a field model is not in resource or includes
|
|
1414
|
+
* @returns Ordered list of query-string fragments
|
|
1243
1415
|
*/
|
|
1244
|
-
|
|
1416
|
+
protected abstract parts(state: IQueryBuilderState, options: QueryBuilderOptions): string[];
|
|
1245
1417
|
/**
|
|
1246
|
-
*
|
|
1418
|
+
* Throw if the resource is not set on the state
|
|
1247
1419
|
*
|
|
1248
|
-
*
|
|
1420
|
+
* Centralises the message that was previously copy-pasted across four
|
|
1421
|
+
* of the five concrete strategies.
|
|
1249
1422
|
*
|
|
1250
1423
|
* @param state - The current query builder state
|
|
1251
|
-
* @
|
|
1252
|
-
|
|
1424
|
+
* @throws Error if `state.resource` is empty
|
|
1425
|
+
*/
|
|
1426
|
+
protected assertResource(state: IQueryBuilderState): void;
|
|
1427
|
+
/**
|
|
1428
|
+
* Compute the base path (no query string)
|
|
1429
|
+
*
|
|
1430
|
+
* @param state - The current query builder state
|
|
1431
|
+
* @returns The base URI without the query separator (e.g. `/users` or `https://api.example.com/users`)
|
|
1253
1432
|
*/
|
|
1254
|
-
|
|
1433
|
+
protected baseUri(state: IQueryBuilderState): string;
|
|
1255
1434
|
/**
|
|
1256
|
-
*
|
|
1435
|
+
* Glue the base URI and the per-driver query-string segments
|
|
1257
1436
|
*
|
|
1258
|
-
*
|
|
1437
|
+
* Returns the bare base when no segments were emitted (e.g. PostgREST
|
|
1438
|
+
* in RANGE mode with no filters), otherwise joins with `?` + `&`.
|
|
1439
|
+
*
|
|
1440
|
+
* @param base - The base URI from `_baseUri`
|
|
1441
|
+
* @param segments - The query-string fragments from `parts(...)`
|
|
1442
|
+
* @returns The full URI
|
|
1443
|
+
*/
|
|
1444
|
+
protected join(base: string, segments: string[]): string;
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
/**
|
|
1448
|
+
* Request strategy for the JSON:API driver
|
|
1449
|
+
*
|
|
1450
|
+
* Generates URIs in the JSON:API format:
|
|
1451
|
+
* - Fields: `fields[articles]=title,body&fields[people]=name`
|
|
1452
|
+
* - Filters: `filter[status]=active`
|
|
1453
|
+
* - Includes: `include=author,comments.author`
|
|
1454
|
+
* - Pagination: `page[number]=1&page[size]=15`
|
|
1455
|
+
* - Sort: `sort=-created_at,name` (- prefix = DESC)
|
|
1456
|
+
*
|
|
1457
|
+
* @see https://jsonapi.org/format/
|
|
1458
|
+
*/
|
|
1459
|
+
declare class JsonApiRequestStrategy extends AbstractRequestStrategy {
|
|
1460
|
+
/**
|
|
1461
|
+
* Filters, sorts, includes, per-model fields — same shape as Spatie
|
|
1462
|
+
* but with bracket-style pagination
|
|
1463
|
+
*/
|
|
1464
|
+
readonly capabilities: IStrategyCapabilities;
|
|
1465
|
+
/**
|
|
1466
|
+
* Emit JSON:API-format query-string segments in canonical order:
|
|
1467
|
+
* include → fields → filters → pagination → sort
|
|
1259
1468
|
*
|
|
1260
1469
|
* @param state - The current query builder state
|
|
1261
1470
|
* @param options - The query parameter key name configuration
|
|
1262
|
-
* @returns
|
|
1471
|
+
* @returns Ordered query-string fragments
|
|
1263
1472
|
*/
|
|
1264
|
-
|
|
1473
|
+
protected parts(state: IQueryBuilderState, options: QueryBuilderOptions): string[];
|
|
1265
1474
|
/**
|
|
1266
|
-
*
|
|
1267
|
-
*
|
|
1268
|
-
* Generates: `page[number]=1&page[size]=15`
|
|
1475
|
+
* Append per-type field selection in bracket notation
|
|
1269
1476
|
*
|
|
1270
1477
|
* @param state - The current query builder state
|
|
1271
1478
|
* @param options - The query parameter key name configuration
|
|
1272
|
-
* @
|
|
1479
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1480
|
+
* @throws Error if the resource is missing from the fields object
|
|
1481
|
+
* @throws UnselectableModelError if a field type is not the resource or in includes
|
|
1273
1482
|
*/
|
|
1274
|
-
private
|
|
1483
|
+
private _appendFields;
|
|
1275
1484
|
/**
|
|
1276
|
-
*
|
|
1485
|
+
* Append filter parameters in bracket notation: `filter[key]=value`
|
|
1277
1486
|
*
|
|
1278
|
-
*
|
|
1487
|
+
* @param state - The current query builder state
|
|
1488
|
+
* @param options - The query parameter key name configuration
|
|
1489
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1490
|
+
*/
|
|
1491
|
+
private _appendFilters;
|
|
1492
|
+
/**
|
|
1493
|
+
* Append include parameter as `include=author,comments.author`
|
|
1279
1494
|
*
|
|
1280
1495
|
* @param state - The current query builder state
|
|
1281
1496
|
* @param options - The query parameter key name configuration
|
|
1282
|
-
* @
|
|
1497
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1283
1498
|
*/
|
|
1284
|
-
private
|
|
1499
|
+
private _appendIncludes;
|
|
1285
1500
|
/**
|
|
1286
|
-
*
|
|
1501
|
+
* Append JSON:API bracket pagination as `page[number]=1&page[size]=15`
|
|
1287
1502
|
*
|
|
1288
|
-
*
|
|
1289
|
-
*
|
|
1503
|
+
* `qs.stringify` already returns the two segments joined with `&`, so we
|
|
1504
|
+
* push the whole string as one accumulator entry — `_join` will glue
|
|
1505
|
+
* it onto the rest with the same separator.
|
|
1290
1506
|
*
|
|
1291
1507
|
* @param state - The current query builder state
|
|
1292
|
-
* @
|
|
1508
|
+
* @param options - The query parameter key name configuration
|
|
1509
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1293
1510
|
*/
|
|
1294
|
-
private
|
|
1511
|
+
private _appendPagination;
|
|
1512
|
+
/**
|
|
1513
|
+
* Append sort parameter as `sort=-field1,field2` (`-` prefix = DESC)
|
|
1514
|
+
*
|
|
1515
|
+
* @param state - The current query builder state
|
|
1516
|
+
* @param options - The query parameter key name configuration
|
|
1517
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1518
|
+
*/
|
|
1519
|
+
private _appendSort;
|
|
1295
1520
|
}
|
|
1296
1521
|
|
|
1297
1522
|
/**
|
|
1298
|
-
*
|
|
1523
|
+
* Base class for response strategies whose pagination metadata lives at
|
|
1524
|
+
* dot-notation paths inside the response body
|
|
1299
1525
|
*
|
|
1300
|
-
*
|
|
1301
|
-
*
|
|
1302
|
-
*
|
|
1303
|
-
*
|
|
1304
|
-
*
|
|
1305
|
-
*
|
|
1306
|
-
*
|
|
1307
|
-
* "total": 100,
|
|
1308
|
-
* "page-count": 10,
|
|
1309
|
-
* "from": 1,
|
|
1310
|
-
* "to": 10
|
|
1311
|
-
* },
|
|
1312
|
-
* "links": {
|
|
1313
|
-
* "first": "url",
|
|
1314
|
-
* "prev": "url",
|
|
1315
|
-
* "next": "url",
|
|
1316
|
-
* "last": "url"
|
|
1317
|
-
* }
|
|
1318
|
-
* }
|
|
1319
|
-
* ```
|
|
1526
|
+
* JSON:API and NestJS share an identical body-traversal algorithm: the
|
|
1527
|
+
* total / current-page / etc. live at nested keys like `meta.total`, and
|
|
1528
|
+
* `from`/`to` are either present directly or must be derived from
|
|
1529
|
+
* `currentPage` × `perPage`. Both strategies were duplicating this
|
|
1530
|
+
* verbatim before this base existed; concrete classes now extend and
|
|
1531
|
+
* provide only the docstring describing their driver's specific path
|
|
1532
|
+
* conventions (see `JsonApiResponseStrategy`, `NestjsResponseStrategy`).
|
|
1320
1533
|
*
|
|
1321
|
-
*
|
|
1534
|
+
* Drivers whose pagination metadata travels via HTTP headers (PostgREST)
|
|
1535
|
+
* or whose body has a flat shape with no dot paths (Laravel, Spatie) do
|
|
1536
|
+
* not extend this class — they implement `IResponseStrategy` directly.
|
|
1322
1537
|
*/
|
|
1323
|
-
declare class
|
|
1538
|
+
declare abstract class AbstractDotPathResponseStrategy implements IResponseStrategy {
|
|
1324
1539
|
/**
|
|
1325
|
-
* Parse a
|
|
1326
|
-
*
|
|
1327
|
-
* Supports dot-notation key paths for accessing nested values.
|
|
1328
|
-
* Computes `from` and `to` from `currentPage` and `perPage` when
|
|
1329
|
-
* they are not directly available in the response.
|
|
1540
|
+
* Parse a nested-envelope pagination response into a PaginatedCollection
|
|
1330
1541
|
*
|
|
1331
1542
|
* @param response - The raw API response object
|
|
1332
|
-
* @param options - The response key name configuration
|
|
1543
|
+
* @param options - The response key name configuration (dot-notation paths supported)
|
|
1333
1544
|
* @returns A typed PaginatedCollection instance
|
|
1334
1545
|
*/
|
|
1335
1546
|
paginate<T extends IPaginatedObject>(response: Record<string, any>, options: ResponseOptions): PaginatedCollection<T>;
|
|
1336
1547
|
/**
|
|
1337
1548
|
* Resolve a value from a response object using a dot-notation path
|
|
1338
1549
|
*
|
|
1339
|
-
* Supports both flat keys ('data') and nested paths ('meta.
|
|
1550
|
+
* Supports both flat keys (`'data'`) and nested paths (`'meta.totalItems'`).
|
|
1340
1551
|
*
|
|
1341
1552
|
* @param response - The raw response object
|
|
1342
1553
|
* @param path - The dot-notation path to resolve
|
|
1343
|
-
* @returns The resolved value, or undefined if
|
|
1554
|
+
* @returns The resolved value, or undefined if any segment is missing
|
|
1344
1555
|
*/
|
|
1345
|
-
|
|
1556
|
+
protected resolve(response: Record<string, any>, path: string): unknown;
|
|
1346
1557
|
/**
|
|
1347
1558
|
* Resolve the "from" index value
|
|
1348
1559
|
*
|
|
1349
|
-
* If
|
|
1350
|
-
* Otherwise
|
|
1351
|
-
* `(currentPage - 1) * perPage + 1`
|
|
1560
|
+
* If `options.from` resolves to a value in the response, use it.
|
|
1561
|
+
* Otherwise compute `(currentPage - 1) * perPage + 1` when both are known.
|
|
1352
1562
|
*
|
|
1353
1563
|
* @param response - The raw response object
|
|
1354
1564
|
* @param options - The response key name configuration
|
|
1355
1565
|
* @param currentPage - The current page number
|
|
1356
1566
|
* @param perPage - The number of items per page
|
|
1357
|
-
* @returns The
|
|
1567
|
+
* @returns The "from" index, or `undefined` when neither path nor inputs suffice
|
|
1358
1568
|
*/
|
|
1359
|
-
|
|
1569
|
+
protected resolveFrom(response: Record<string, any>, options: ResponseOptions, currentPage: number, perPage?: number): number | undefined;
|
|
1360
1570
|
/**
|
|
1361
1571
|
* Resolve the "to" index value
|
|
1362
1572
|
*
|
|
1363
|
-
* If
|
|
1364
|
-
* Otherwise
|
|
1365
|
-
*
|
|
1573
|
+
* If `options.to` resolves to a value in the response, use it.
|
|
1574
|
+
* Otherwise compute `Math.min(currentPage * perPage, total)` when all
|
|
1575
|
+
* three are known.
|
|
1366
1576
|
*
|
|
1367
1577
|
* @param response - The raw response object
|
|
1368
1578
|
* @param options - The response key name configuration
|
|
1369
1579
|
* @param currentPage - The current page number
|
|
1370
1580
|
* @param perPage - The number of items per page
|
|
1371
1581
|
* @param total - The total number of items
|
|
1372
|
-
* @returns The
|
|
1582
|
+
* @returns The "to" index, or `undefined` when neither path nor inputs suffice
|
|
1373
1583
|
*/
|
|
1374
|
-
|
|
1584
|
+
protected resolveTo(response: Record<string, any>, options: ResponseOptions, currentPage: number, perPage?: number, total?: number): number | undefined;
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1587
|
+
/**
|
|
1588
|
+
* Response strategy for the JSON:API driver
|
|
1589
|
+
*
|
|
1590
|
+
* Parses JSON:API pagination responses:
|
|
1591
|
+
* ```json
|
|
1592
|
+
* {
|
|
1593
|
+
* "data": [...],
|
|
1594
|
+
* "meta": {
|
|
1595
|
+
* "current-page": 1,
|
|
1596
|
+
* "per-page": 10,
|
|
1597
|
+
* "total": 100,
|
|
1598
|
+
* "page-count": 10,
|
|
1599
|
+
* "from": 1,
|
|
1600
|
+
* "to": 10
|
|
1601
|
+
* },
|
|
1602
|
+
* "links": {
|
|
1603
|
+
* "first": "url",
|
|
1604
|
+
* "prev": "url",
|
|
1605
|
+
* "next": "url",
|
|
1606
|
+
* "last": "url"
|
|
1607
|
+
* }
|
|
1608
|
+
* }
|
|
1609
|
+
* ```
|
|
1610
|
+
*
|
|
1611
|
+
* Default key paths are configured in `JsonApiResponseOptions`. The
|
|
1612
|
+
* traversal algorithm (dot-notation resolution + computed `from`/`to`) is
|
|
1613
|
+
* inherited from `AbstractDotPathResponseStrategy`; this class exists so
|
|
1614
|
+
* `DriverEnum.JSON_API` resolves to a distinct identity at the DI layer
|
|
1615
|
+
* even though the parsing logic is shared with NestJS.
|
|
1616
|
+
*
|
|
1617
|
+
* @see https://jsonapi.org/format/
|
|
1618
|
+
*/
|
|
1619
|
+
declare class JsonApiResponseStrategy extends AbstractDotPathResponseStrategy {
|
|
1375
1620
|
}
|
|
1376
1621
|
|
|
1377
1622
|
/**
|
|
@@ -1382,26 +1627,19 @@ declare class JsonApiResponseStrategy implements IResponseStrategy {
|
|
|
1382
1627
|
*
|
|
1383
1628
|
* Filters, sorts, fields, includes, search, and select in state are ignored.
|
|
1384
1629
|
*/
|
|
1385
|
-
declare class LaravelRequestStrategy
|
|
1630
|
+
declare class LaravelRequestStrategy extends AbstractRequestStrategy {
|
|
1386
1631
|
/**
|
|
1387
|
-
*
|
|
1388
|
-
*
|
|
1389
|
-
* @param state - The current query builder state
|
|
1390
|
-
* @param options - The query parameter key name configuration
|
|
1391
|
-
* @returns The composed URI string
|
|
1392
|
-
* @throws Error if resource is not set
|
|
1632
|
+
* Pagination-only driver — no filtering, sorting, or column selection
|
|
1393
1633
|
*/
|
|
1394
|
-
|
|
1634
|
+
readonly capabilities: IStrategyCapabilities;
|
|
1395
1635
|
/**
|
|
1396
|
-
*
|
|
1397
|
-
*
|
|
1398
|
-
* Laravel pagination does not recognize `-1` as a "fetch all" sentinel,
|
|
1399
|
-
* so only positive integers are accepted.
|
|
1636
|
+
* Emit only the pagination params; filters/sorts/etc. are ignored
|
|
1400
1637
|
*
|
|
1401
|
-
* @param
|
|
1402
|
-
* @
|
|
1638
|
+
* @param state - The current query builder state
|
|
1639
|
+
* @param options - The query parameter key name configuration
|
|
1640
|
+
* @returns The two pagination query-string fragments
|
|
1403
1641
|
*/
|
|
1404
|
-
|
|
1642
|
+
protected parts(state: IQueryBuilderState, options: QueryBuilderOptions): string[];
|
|
1405
1643
|
}
|
|
1406
1644
|
|
|
1407
1645
|
/**
|
|
@@ -1444,20 +1682,12 @@ declare class LaravelResponseStrategy implements IResponseStrategy {
|
|
|
1444
1682
|
*
|
|
1445
1683
|
* @see https://github.com/ppetzold/nestjs-paginate
|
|
1446
1684
|
*/
|
|
1447
|
-
declare class NestjsRequestStrategy
|
|
1448
|
-
/**
|
|
1449
|
-
* Accumulator for composing the URI string
|
|
1450
|
-
*/
|
|
1451
|
-
private _uri;
|
|
1685
|
+
declare class NestjsRequestStrategy extends AbstractRequestStrategy {
|
|
1452
1686
|
/**
|
|
1453
|
-
*
|
|
1454
|
-
*
|
|
1455
|
-
* @param state - The current query builder state
|
|
1456
|
-
* @param options - The query parameter key name configuration
|
|
1457
|
-
* @returns The composed URI string
|
|
1458
|
-
* @throws Error if model is not set
|
|
1687
|
+
* Filters, operator filters, sorts, flat select, global search — no
|
|
1688
|
+
* per-model fields, no includes
|
|
1459
1689
|
*/
|
|
1460
|
-
|
|
1690
|
+
readonly capabilities: IStrategyCapabilities;
|
|
1461
1691
|
/**
|
|
1462
1692
|
* Validate that the given limit is accepted by nestjs-paginate
|
|
1463
1693
|
*
|
|
@@ -1469,76 +1699,72 @@ declare class NestjsRequestStrategy implements IRequestStrategy {
|
|
|
1469
1699
|
*/
|
|
1470
1700
|
validateLimit(limit: number): void;
|
|
1471
1701
|
/**
|
|
1472
|
-
*
|
|
1473
|
-
*
|
|
1474
|
-
* Generates: `filter.field=value1,value2` for each filter
|
|
1702
|
+
* Emit NestJS-format query-string segments in canonical order:
|
|
1703
|
+
* filters → operator filters → sortBy → select → search → limit → page
|
|
1475
1704
|
*
|
|
1476
1705
|
* @param state - The current query builder state
|
|
1477
1706
|
* @param options - The query parameter key name configuration
|
|
1707
|
+
* @returns Ordered query-string fragments
|
|
1478
1708
|
*/
|
|
1479
|
-
|
|
1709
|
+
protected parts(state: IQueryBuilderState, options: QueryBuilderOptions): string[];
|
|
1480
1710
|
/**
|
|
1481
|
-
*
|
|
1711
|
+
* Append simple filter parameters as `filter.field=value1,value2`
|
|
1482
1712
|
*
|
|
1483
1713
|
* @param state - The current query builder state
|
|
1484
1714
|
* @param options - The query parameter key name configuration
|
|
1715
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1485
1716
|
*/
|
|
1486
|
-
private
|
|
1717
|
+
private _appendFilters;
|
|
1487
1718
|
/**
|
|
1488
|
-
*
|
|
1489
|
-
*
|
|
1490
|
-
* Groups operator filters by field and generates:
|
|
1491
|
-
* - Single value: `filter.field=$operator:value`
|
|
1492
|
-
* - Multiple values ($in, $btw): `filter.field=$operator:val1,val2`
|
|
1719
|
+
* Append the limit parameter
|
|
1493
1720
|
*
|
|
1494
1721
|
* @param state - The current query builder state
|
|
1495
1722
|
* @param options - The query parameter key name configuration
|
|
1723
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1496
1724
|
*/
|
|
1497
|
-
private
|
|
1725
|
+
private _appendLimit;
|
|
1498
1726
|
/**
|
|
1499
|
-
*
|
|
1727
|
+
* Append operator-filter parameters as `filter.field=$op:value`
|
|
1728
|
+
*
|
|
1729
|
+
* Groups by field; multi-value operators ($in, $btw) join values with commas.
|
|
1500
1730
|
*
|
|
1501
1731
|
* @param state - The current query builder state
|
|
1502
1732
|
* @param options - The query parameter key name configuration
|
|
1733
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1503
1734
|
*/
|
|
1504
|
-
private
|
|
1735
|
+
private _appendOperatorFilters;
|
|
1505
1736
|
/**
|
|
1506
|
-
*
|
|
1507
|
-
*
|
|
1508
|
-
* Generates: `search=term`
|
|
1737
|
+
* Append the page parameter
|
|
1509
1738
|
*
|
|
1510
1739
|
* @param state - The current query builder state
|
|
1511
1740
|
* @param options - The query parameter key name configuration
|
|
1741
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1512
1742
|
*/
|
|
1513
|
-
private
|
|
1743
|
+
private _appendPage;
|
|
1514
1744
|
/**
|
|
1515
|
-
*
|
|
1516
|
-
*
|
|
1517
|
-
* Generates: `select=col1,col2`
|
|
1745
|
+
* Append the search parameter as `search=term`
|
|
1518
1746
|
*
|
|
1519
1747
|
* @param state - The current query builder state
|
|
1520
1748
|
* @param options - The query parameter key name configuration
|
|
1749
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1521
1750
|
*/
|
|
1522
|
-
private
|
|
1751
|
+
private _appendSearch;
|
|
1523
1752
|
/**
|
|
1524
|
-
*
|
|
1525
|
-
*
|
|
1526
|
-
* Generates: `sortBy=field1:DESC,field2:ASC`
|
|
1753
|
+
* Append the select parameter as `select=col1,col2`
|
|
1527
1754
|
*
|
|
1528
1755
|
* @param state - The current query builder state
|
|
1529
1756
|
* @param options - The query parameter key name configuration
|
|
1757
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1530
1758
|
*/
|
|
1531
|
-
private
|
|
1759
|
+
private _appendSelect;
|
|
1532
1760
|
/**
|
|
1533
|
-
*
|
|
1534
|
-
*
|
|
1535
|
-
* Returns the full base path with `?` for the first parameter,
|
|
1536
|
-
* or `&` for subsequent parameters.
|
|
1761
|
+
* Append sort parameter as `sortBy=field1:DESC,field2:ASC`
|
|
1537
1762
|
*
|
|
1538
1763
|
* @param state - The current query builder state
|
|
1539
|
-
* @
|
|
1764
|
+
* @param options - The query parameter key name configuration
|
|
1765
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1540
1766
|
*/
|
|
1541
|
-
private
|
|
1767
|
+
private _appendSort;
|
|
1542
1768
|
}
|
|
1543
1769
|
|
|
1544
1770
|
/**
|
|
@@ -1564,60 +1790,214 @@ declare class NestjsRequestStrategy implements IRequestStrategy {
|
|
|
1564
1790
|
* }
|
|
1565
1791
|
* ```
|
|
1566
1792
|
*
|
|
1793
|
+
* Default key paths are configured in `NestjsResponseOptions`. The
|
|
1794
|
+
* traversal algorithm (dot-notation resolution + computed `from`/`to`) is
|
|
1795
|
+
* inherited from `AbstractDotPathResponseStrategy`; this class exists so
|
|
1796
|
+
* `DriverEnum.NESTJS` resolves to a distinct identity at the DI layer
|
|
1797
|
+
* even though the parsing logic is shared with JSON:API.
|
|
1798
|
+
*
|
|
1567
1799
|
* @see https://github.com/ppetzold/nestjs-paginate
|
|
1568
1800
|
*/
|
|
1569
|
-
declare class NestjsResponseStrategy
|
|
1801
|
+
declare class NestjsResponseStrategy extends AbstractDotPathResponseStrategy {
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
/**
|
|
1805
|
+
* Request strategy for the PostgREST driver
|
|
1806
|
+
*
|
|
1807
|
+
* PostgREST auto-generates REST APIs from PostgreSQL schemas and is the
|
|
1808
|
+
* backbone of Supabase's data API. This strategy produces URIs in
|
|
1809
|
+
* PostgREST's native query-string format:
|
|
1810
|
+
*
|
|
1811
|
+
* - Filters: `col=eq.val` (single value) / `col=in.(v1,v2,v3)` (multi-value)
|
|
1812
|
+
* - Order: `order=col1.asc,col2.desc`
|
|
1813
|
+
* - Select: `select=col1,col2`
|
|
1814
|
+
* - Pagination: `limit=N&offset=M` (offset derived from state.page)
|
|
1815
|
+
*
|
|
1816
|
+
* The `order` and `offset` query-parameter names are PostgREST conventions
|
|
1817
|
+
* and are intentionally not configurable via `QueryBuilderOptions` (see
|
|
1818
|
+
* issue #50 MVP scope). `limit`, `select`, and `filters` (per-column name)
|
|
1819
|
+
* honour the existing option keys.
|
|
1820
|
+
*
|
|
1821
|
+
* @see https://postgrest.org/en/stable/api.html
|
|
1822
|
+
* @see https://supabase.com/docs/reference/javascript/select
|
|
1823
|
+
*/
|
|
1824
|
+
declare class PostgrestRequestStrategy extends AbstractRequestStrategy {
|
|
1570
1825
|
/**
|
|
1571
|
-
*
|
|
1826
|
+
* Filters, operator filters (incl. FTS), sorts, flat select — no
|
|
1827
|
+
* per-model fields, no JSON:API/Spatie-style includes, no global
|
|
1828
|
+
* search (per-column FTS via the operator family covers it)
|
|
1829
|
+
*/
|
|
1830
|
+
readonly capabilities: IStrategyCapabilities;
|
|
1831
|
+
private static readonly _offsetKey;
|
|
1832
|
+
private static readonly _orderKey;
|
|
1833
|
+
/**
|
|
1834
|
+
* Active pagination mode
|
|
1572
1835
|
*
|
|
1573
|
-
*
|
|
1574
|
-
*
|
|
1575
|
-
*
|
|
1836
|
+
* QUERY (default) → URL emits limit/offset.
|
|
1837
|
+
* RANGE → URL omits them; `buildPaginationHeaders()` returns the
|
|
1838
|
+
* `Range-Unit` / `Range` HTTP headers instead.
|
|
1839
|
+
*/
|
|
1840
|
+
private readonly _paginationMode;
|
|
1841
|
+
/**
|
|
1842
|
+
* @param paginationMode - Wire-level pagination mechanism. Defaults to
|
|
1843
|
+
* `PaginationModeEnum.QUERY`; `provideNgQubee` wires this from
|
|
1844
|
+
* `IConfig.pagination`.
|
|
1845
|
+
*/
|
|
1846
|
+
constructor(paginationMode?: PaginationModeEnum);
|
|
1847
|
+
/**
|
|
1848
|
+
* Compute `Range-Unit` / `Range` HTTP headers for RANGE pagination mode
|
|
1576
1849
|
*
|
|
1577
|
-
*
|
|
1578
|
-
*
|
|
1579
|
-
*
|
|
1850
|
+
* In QUERY mode this returns `null` so `NgQubeeService.paginationHeaders()`
|
|
1851
|
+
* conveys "no headers needed" to the consumer. In RANGE mode the method
|
|
1852
|
+
* converts the 1-indexed `state.page` + `state.limit` into PostgREST's
|
|
1853
|
+
* 0-indexed inclusive range (`from = (page - 1) * limit`,
|
|
1854
|
+
* `to = from + limit - 1`) and returns both header values.
|
|
1855
|
+
*
|
|
1856
|
+
* @param state - The current query builder state
|
|
1857
|
+
* @returns `{ 'Range-Unit': 'items', 'Range': 'from-to' }` or `null`
|
|
1580
1858
|
*/
|
|
1581
|
-
|
|
1859
|
+
buildPaginationHeaders(state: IQueryBuilderState): Record<string, string> | null;
|
|
1582
1860
|
/**
|
|
1583
|
-
*
|
|
1861
|
+
* Emit PostgREST-format query-string segments in canonical order:
|
|
1862
|
+
* filters → operator filters → order → select → (limit + offset in
|
|
1863
|
+
* QUERY mode only — RANGE mode passes pagination via headers instead)
|
|
1584
1864
|
*
|
|
1585
|
-
*
|
|
1865
|
+
* @param state - The current query builder state
|
|
1866
|
+
* @param options - The query parameter key name configuration
|
|
1867
|
+
* @returns Ordered query-string fragments
|
|
1868
|
+
*/
|
|
1869
|
+
protected parts(state: IQueryBuilderState, options: QueryBuilderOptions): string[];
|
|
1870
|
+
/**
|
|
1871
|
+
* Append filter parameters in PostgREST format
|
|
1586
1872
|
*
|
|
1587
|
-
*
|
|
1588
|
-
*
|
|
1589
|
-
*
|
|
1873
|
+
* Every filter is operator-prefixed (PostgREST has no implicit equality):
|
|
1874
|
+
* a single value yields `col=eq.val`; multiple values collapse into
|
|
1875
|
+
* PostgREST's native IN-list syntax `col=in.(v1,v2,v3)`.
|
|
1876
|
+
*
|
|
1877
|
+
* @param state - The current query builder state
|
|
1878
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1590
1879
|
*/
|
|
1591
|
-
private
|
|
1880
|
+
private _appendFilters;
|
|
1592
1881
|
/**
|
|
1593
|
-
*
|
|
1882
|
+
* Append the limit parameter
|
|
1594
1883
|
*
|
|
1595
|
-
*
|
|
1596
|
-
*
|
|
1597
|
-
*
|
|
1884
|
+
* @param state - The current query builder state
|
|
1885
|
+
* @param options - The query parameter key name configuration
|
|
1886
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1887
|
+
*/
|
|
1888
|
+
private _appendLimit;
|
|
1889
|
+
/**
|
|
1890
|
+
* Append the offset parameter, derived from state.page
|
|
1598
1891
|
*
|
|
1599
|
-
*
|
|
1600
|
-
*
|
|
1601
|
-
*
|
|
1602
|
-
*
|
|
1603
|
-
*
|
|
1892
|
+
* PostgREST uses offset-based pagination, not page-based. The offset is
|
|
1893
|
+
* computed as `(page - 1) * limit`. Omitted when offset would be 0
|
|
1894
|
+
* (i.e. page 1) since PostgREST defaults to offset=0 anyway and dropping
|
|
1895
|
+
* it keeps the URI shorter.
|
|
1896
|
+
*
|
|
1897
|
+
* @param state - The current query builder state
|
|
1898
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1604
1899
|
*/
|
|
1605
|
-
private
|
|
1900
|
+
private _appendOffset;
|
|
1606
1901
|
/**
|
|
1607
|
-
*
|
|
1902
|
+
* Append explicit operator filters
|
|
1608
1903
|
*
|
|
1609
|
-
*
|
|
1610
|
-
*
|
|
1611
|
-
* `
|
|
1904
|
+
* Maps each `FilterOperatorEnum` value to PostgREST's prefix-operator
|
|
1905
|
+
* syntax. `BTW` expands to two query params (`gte` + `lte`); `NULL`
|
|
1906
|
+
* emits `is.null` / `is.not.null` based on the boolean value; `NOT`
|
|
1907
|
+
* picks its inner operator by arity (`not.eq.val` for single values,
|
|
1908
|
+
* `not.in.(v1,v2)` for multi-value).
|
|
1612
1909
|
*
|
|
1613
|
-
* @param
|
|
1614
|
-
* @param
|
|
1615
|
-
* @
|
|
1616
|
-
* @param perPage - The number of items per page
|
|
1617
|
-
* @param total - The total number of items
|
|
1618
|
-
* @returns The computed "to" index
|
|
1910
|
+
* @param state - The current query builder state
|
|
1911
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1912
|
+
* @throws {InvalidFilterOperatorValueError} If `BTW` does not receive exactly 2 values, or `NULL` does not receive exactly 1 boolean
|
|
1619
1913
|
*/
|
|
1620
|
-
private
|
|
1914
|
+
private _appendOperatorFilters;
|
|
1915
|
+
/**
|
|
1916
|
+
* Append a `BTW` operator filter as two PostgREST segments
|
|
1917
|
+
*
|
|
1918
|
+
* Produces: `col=gte.min` and `col=lte.max`. Values must be exactly
|
|
1919
|
+
* `[min, max]`.
|
|
1920
|
+
*
|
|
1921
|
+
* @param filter - The operator filter carrying the BTW bounds
|
|
1922
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1923
|
+
* @throws {InvalidFilterOperatorValueError} If values.length !== 2
|
|
1924
|
+
*/
|
|
1925
|
+
private _appendBetweenFilter;
|
|
1926
|
+
/**
|
|
1927
|
+
* Build the right-hand-side of a PostgREST filter param for the given operator
|
|
1928
|
+
*
|
|
1929
|
+
* Kept as a separate helper so each operator's shape is visible in one
|
|
1930
|
+
* place and the dispatch is exhaustively typed against
|
|
1931
|
+
* `FilterOperatorEnum`.
|
|
1932
|
+
*
|
|
1933
|
+
* @param filter - The operator filter (field, operator, values)
|
|
1934
|
+
* @returns The PostgREST-formatted value portion (right of the `=` sign)
|
|
1935
|
+
* @throws {InvalidFilterOperatorValueError} If NULL receives a non-boolean or wrong arity
|
|
1936
|
+
*/
|
|
1937
|
+
private _formatOperatorRhs;
|
|
1938
|
+
/**
|
|
1939
|
+
* Append the order parameter as `order=col1.asc,col2.desc`
|
|
1940
|
+
*
|
|
1941
|
+
* @param state - The current query builder state
|
|
1942
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1943
|
+
*/
|
|
1944
|
+
private _appendOrder;
|
|
1945
|
+
/**
|
|
1946
|
+
* Append the select parameter as `select=col1,col2`
|
|
1947
|
+
*
|
|
1948
|
+
* PostgREST uses a `select` query param for column pruning, matching
|
|
1949
|
+
* NestJS semantics.
|
|
1950
|
+
*
|
|
1951
|
+
* @param state - The current query builder state
|
|
1952
|
+
* @param options - The query parameter key name configuration
|
|
1953
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1954
|
+
*/
|
|
1955
|
+
private _appendSelect;
|
|
1956
|
+
}
|
|
1957
|
+
|
|
1958
|
+
/**
|
|
1959
|
+
* Response strategy for the PostgREST driver
|
|
1960
|
+
*
|
|
1961
|
+
* PostgREST (and Supabase, which wraps it) returns a bare array body for
|
|
1962
|
+
* collection endpoints. Pagination metadata is carried in the
|
|
1963
|
+
* `Content-Range` HTTP response header, e.g. `0-9/50` meaning "items 0–9
|
|
1964
|
+
* out of 50 total". Consumers opt into totals by sending the
|
|
1965
|
+
* `Prefer: count=exact` request header.
|
|
1966
|
+
*
|
|
1967
|
+
* This strategy expects the consumer to pass the array body as `response`
|
|
1968
|
+
* (or a plain object with `response[options.data]` pointing at the array)
|
|
1969
|
+
* and the response headers via the optional `headers` bag. See
|
|
1970
|
+
* `PaginationService.paginate()` for the call-site shape.
|
|
1971
|
+
*
|
|
1972
|
+
* @see https://postgrest.org/en/stable/references/api/pagination_count.html
|
|
1973
|
+
*/
|
|
1974
|
+
declare class PostgrestResponseStrategy implements IResponseStrategy {
|
|
1975
|
+
private static readonly _contentRangeHeader;
|
|
1976
|
+
private static readonly _contentRangeRegex;
|
|
1977
|
+
/**
|
|
1978
|
+
* Parse a PostgREST response into a typed PaginatedCollection
|
|
1979
|
+
*
|
|
1980
|
+
* @param response - The raw response. Either the array body directly, or
|
|
1981
|
+
* an object with the array at `response[options.data]`.
|
|
1982
|
+
* @param options - The response key configuration (only `options.data` is
|
|
1983
|
+
* consulted; all pagination metadata comes from the Content-Range header).
|
|
1984
|
+
* @param headers - Optional HTTP response headers. The `Content-Range`
|
|
1985
|
+
* header drives page/total derivation; omission is tolerated and yields
|
|
1986
|
+
* a collection with `undefined` bounds (auto-sync will leave
|
|
1987
|
+
* `isLastPageKnown` at `false`).
|
|
1988
|
+
* @returns A typed PaginatedCollection instance
|
|
1989
|
+
*/
|
|
1990
|
+
paginate<T extends IPaginatedObject>(response: Record<string, unknown>, options: ResponseOptions, headers?: HeaderBag): PaginatedCollection<T>;
|
|
1991
|
+
/**
|
|
1992
|
+
* Extract `{from, to, total}` from a PostgREST `Content-Range` value
|
|
1993
|
+
*
|
|
1994
|
+
* Expected format: `<from>-<to>/<total|*>`. Any shape mismatch returns
|
|
1995
|
+
* an empty object; `*` as the total yields `total: undefined`.
|
|
1996
|
+
*
|
|
1997
|
+
* @param value - Raw header value (possibly null/undefined)
|
|
1998
|
+
* @returns Parsed integers; missing fields indicate an unparseable header
|
|
1999
|
+
*/
|
|
2000
|
+
private _parseContentRange;
|
|
1621
2001
|
}
|
|
1622
2002
|
|
|
1623
2003
|
/**
|
|
@@ -1632,99 +2012,74 @@ declare class NestjsResponseStrategy implements IResponseStrategy {
|
|
|
1632
2012
|
*
|
|
1633
2013
|
* @see https://spatie.be/docs/laravel-query-builder
|
|
1634
2014
|
*/
|
|
1635
|
-
declare class SpatieRequestStrategy
|
|
2015
|
+
declare class SpatieRequestStrategy extends AbstractRequestStrategy {
|
|
1636
2016
|
/**
|
|
1637
|
-
*
|
|
2017
|
+
* Filters, sorts, includes, per-model fields — no operators, no flat
|
|
2018
|
+
* select, no global search
|
|
1638
2019
|
*/
|
|
1639
|
-
|
|
2020
|
+
readonly capabilities: IStrategyCapabilities;
|
|
1640
2021
|
/**
|
|
1641
|
-
*
|
|
2022
|
+
* Emit Spatie-format query-string segments in canonical order:
|
|
2023
|
+
* include → fields → filters → limit → page → sort
|
|
1642
2024
|
*
|
|
1643
2025
|
* @param state - The current query builder state
|
|
1644
2026
|
* @param options - The query parameter key name configuration
|
|
1645
|
-
* @returns
|
|
1646
|
-
* @throws Error if resource is not set
|
|
1647
|
-
*/
|
|
1648
|
-
buildUri(state: IQueryBuilderState, options: QueryBuilderOptions): string;
|
|
1649
|
-
/**
|
|
1650
|
-
* Validate that the given limit is accepted by the Spatie driver
|
|
1651
|
-
*
|
|
1652
|
-
* Spatie query-builder does not recognize `-1` as a "fetch all" sentinel,
|
|
1653
|
-
* so only positive integers are accepted.
|
|
1654
|
-
*
|
|
1655
|
-
* @param limit - The limit value to validate
|
|
1656
|
-
* @throws {InvalidLimitError} If the value is not a positive integer
|
|
2027
|
+
* @returns Ordered query-string fragments
|
|
1657
2028
|
*/
|
|
1658
|
-
|
|
2029
|
+
protected parts(state: IQueryBuilderState, options: QueryBuilderOptions): string[];
|
|
1659
2030
|
/**
|
|
1660
|
-
*
|
|
2031
|
+
* Append per-model field selection in bracket notation
|
|
1661
2032
|
*
|
|
1662
2033
|
* Validates that each field model exists either as the main resource
|
|
1663
|
-
* or in the includes list.
|
|
2034
|
+
* or in the includes list.
|
|
1664
2035
|
*
|
|
1665
2036
|
* @param state - The current query builder state
|
|
1666
2037
|
* @param options - The query parameter key name configuration
|
|
1667
|
-
* @
|
|
1668
|
-
* @throws Error if resource is required but not set
|
|
2038
|
+
* @param out - The accumulator the caller joins into the URI
|
|
2039
|
+
* @throws Error if the resource is required but not set
|
|
1669
2040
|
* @throws UnselectableModelError if a field model is not in resource or includes
|
|
1670
2041
|
*/
|
|
1671
|
-
private
|
|
2042
|
+
private _appendFields;
|
|
1672
2043
|
/**
|
|
1673
|
-
*
|
|
1674
|
-
*
|
|
1675
|
-
* Generates filter parameters in bracket notation: `filter[key]=value1,value2`
|
|
2044
|
+
* Append filter parameters in bracket notation: `filter[key]=value`
|
|
1676
2045
|
*
|
|
1677
2046
|
* @param state - The current query builder state
|
|
1678
2047
|
* @param options - The query parameter key name configuration
|
|
1679
|
-
* @
|
|
2048
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1680
2049
|
*/
|
|
1681
|
-
private
|
|
2050
|
+
private _appendFilters;
|
|
1682
2051
|
/**
|
|
1683
|
-
*
|
|
1684
|
-
*
|
|
1685
|
-
* Generates: `include=model1,model2`
|
|
2052
|
+
* Append include parameter as `include=model1,model2`
|
|
1686
2053
|
*
|
|
1687
2054
|
* @param state - The current query builder state
|
|
1688
2055
|
* @param options - The query parameter key name configuration
|
|
1689
|
-
* @
|
|
2056
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1690
2057
|
*/
|
|
1691
|
-
private
|
|
2058
|
+
private _appendIncludes;
|
|
1692
2059
|
/**
|
|
1693
|
-
*
|
|
2060
|
+
* Append the limit parameter
|
|
1694
2061
|
*
|
|
1695
2062
|
* @param state - The current query builder state
|
|
1696
2063
|
* @param options - The query parameter key name configuration
|
|
1697
|
-
* @
|
|
2064
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1698
2065
|
*/
|
|
1699
|
-
private
|
|
2066
|
+
private _appendLimit;
|
|
1700
2067
|
/**
|
|
1701
|
-
*
|
|
2068
|
+
* Append the page parameter
|
|
1702
2069
|
*
|
|
1703
2070
|
* @param state - The current query builder state
|
|
1704
2071
|
* @param options - The query parameter key name configuration
|
|
1705
|
-
* @
|
|
2072
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1706
2073
|
*/
|
|
1707
|
-
private
|
|
2074
|
+
private _appendPage;
|
|
1708
2075
|
/**
|
|
1709
|
-
*
|
|
1710
|
-
*
|
|
1711
|
-
* Generates: `sort=-field1,field2` where `-` prefix indicates DESC order
|
|
2076
|
+
* Append sort parameter as `sort=-field1,field2` (`-` prefix = DESC)
|
|
1712
2077
|
*
|
|
1713
2078
|
* @param state - The current query builder state
|
|
1714
2079
|
* @param options - The query parameter key name configuration
|
|
1715
|
-
* @
|
|
1716
|
-
*/
|
|
1717
|
-
private _parseSort;
|
|
1718
|
-
/**
|
|
1719
|
-
* Determine the appropriate URI prefix based on the current accumulator state
|
|
1720
|
-
*
|
|
1721
|
-
* Returns the full base path with `?` for the first parameter,
|
|
1722
|
-
* or `&` for subsequent parameters.
|
|
1723
|
-
*
|
|
1724
|
-
* @param state - The current query builder state
|
|
1725
|
-
* @returns The prefix string to prepend to the next parameter
|
|
2080
|
+
* @param out - The accumulator the caller joins into the URI
|
|
1726
2081
|
*/
|
|
1727
|
-
private
|
|
2082
|
+
private _appendSort;
|
|
1728
2083
|
}
|
|
1729
2084
|
|
|
1730
2085
|
/**
|
|
@@ -1756,5 +2111,173 @@ declare class SpatieResponseStrategy implements IResponseStrategy {
|
|
|
1756
2111
|
paginate<T extends IPaginatedObject>(response: Record<string, any>, options: ResponseOptions): PaginatedCollection<T>;
|
|
1757
2112
|
}
|
|
1758
2113
|
|
|
1759
|
-
|
|
1760
|
-
|
|
2114
|
+
/**
|
|
2115
|
+
* Request strategy for the Strapi driver
|
|
2116
|
+
*
|
|
2117
|
+
* Generates URIs in [Strapi's filter API format](https://docs.strapi.io/dev-docs/api/rest/filters-locale-publication):
|
|
2118
|
+
* - Filters: `filters[field][$eq]=value` (multi-value collapses to `$in`)
|
|
2119
|
+
* - Operator filters: `filters[field][$op]=value` (translated from
|
|
2120
|
+
* `FilterOperatorEnum` — `BTW`→`$between`, `SW`→`$startsWith`,
|
|
2121
|
+
* `ILIKE`→`$containsi`, `NOT`→`$ne`/`$notIn`,
|
|
2122
|
+
* `NULL`→`$null`/`$notNull`)
|
|
2123
|
+
* - Sorts: `sort[0]=field:asc&sort[1]=field:desc`
|
|
2124
|
+
* - Field selection (flat): `fields[0]=col1&fields[1]=col2`
|
|
2125
|
+
* - Population: `populate[0]=relation`
|
|
2126
|
+
* - Pagination (page-based): `pagination[page]=N&pagination[pageSize]=N`
|
|
2127
|
+
*
|
|
2128
|
+
* Strapi-native full-text search (`FTS`, `PHFTS`, `PLFTS`, `WFTS`) is
|
|
2129
|
+
* PostgREST-only and throws `UnsupportedFilterOperatorError` here.
|
|
2130
|
+
*
|
|
2131
|
+
* @see https://docs.strapi.io/dev-docs/api/rest/filters-locale-publication
|
|
2132
|
+
*/
|
|
2133
|
+
declare class StrapiRequestStrategy extends AbstractRequestStrategy {
|
|
2134
|
+
/**
|
|
2135
|
+
* Filters, operator filters, sorts, populate (`includes`), flat field
|
|
2136
|
+
* selection (`select`) — no per-model fields, no global search (use
|
|
2137
|
+
* `$contains` / `$containsi` operator filters instead)
|
|
2138
|
+
*/
|
|
2139
|
+
readonly capabilities: IStrategyCapabilities;
|
|
2140
|
+
/**
|
|
2141
|
+
* Strapi-native names of the four hardcoded query keys
|
|
2142
|
+
*
|
|
2143
|
+
* Strapi's wire format is fixed (the server reads `pagination[page]`,
|
|
2144
|
+
* `populate`, `sort`, `fields`); these keys are intentionally not
|
|
2145
|
+
* configurable through `QueryBuilderOptions` and live as private
|
|
2146
|
+
* statics so they are visible in one place.
|
|
2147
|
+
*/
|
|
2148
|
+
private static readonly _fieldsKey;
|
|
2149
|
+
private static readonly _paginationKey;
|
|
2150
|
+
private static readonly _populateKey;
|
|
2151
|
+
private static readonly _sortKey;
|
|
2152
|
+
/**
|
|
2153
|
+
* Emit Strapi-format query-string segments in canonical order:
|
|
2154
|
+
* populate → fields → filters (merged) → sort → pagination
|
|
2155
|
+
*
|
|
2156
|
+
* Simple filters and operator filters share a single `filters` wrapper
|
|
2157
|
+
* so qs emits one ordered, deeply-nested bracket structure rather than
|
|
2158
|
+
* two duplicate top-level `filters[...]` blocks.
|
|
2159
|
+
*
|
|
2160
|
+
* @param state - The current query builder state
|
|
2161
|
+
* @param _options - The query parameter key name configuration (unused;
|
|
2162
|
+
* Strapi's wire keys are fixed by the server)
|
|
2163
|
+
* @returns Ordered query-string fragments
|
|
2164
|
+
*/
|
|
2165
|
+
protected parts(state: IQueryBuilderState, _options: QueryBuilderOptions): string[];
|
|
2166
|
+
/**
|
|
2167
|
+
* Append `fields[0]=col1&fields[1]=col2` from the flat select array
|
|
2168
|
+
*
|
|
2169
|
+
* Strapi's `fields` parameter is the column-pruner for the main
|
|
2170
|
+
* resource; per-relation field selection is expressed through the
|
|
2171
|
+
* `populate` deep syntax (out of scope for this driver).
|
|
2172
|
+
*
|
|
2173
|
+
* @param state - The current query builder state
|
|
2174
|
+
* @param out - The accumulator the caller joins into the URI
|
|
2175
|
+
*/
|
|
2176
|
+
private _appendFields;
|
|
2177
|
+
/**
|
|
2178
|
+
* Append the unified `filters[...]` wrapper combining simple filters
|
|
2179
|
+
* and operator filters
|
|
2180
|
+
*
|
|
2181
|
+
* Both kinds emit into the same nested object under `filters` so qs
|
|
2182
|
+
* produces a single deeply-bracketed block per request. Simple
|
|
2183
|
+
* single-value filters fold to `$eq`; simple multi-value filters fold
|
|
2184
|
+
* to `$in`. Operator filters then merge into the same per-field map,
|
|
2185
|
+
* potentially co-existing with a simple filter on the same field.
|
|
2186
|
+
*
|
|
2187
|
+
* @param state - The current query builder state
|
|
2188
|
+
* @param out - The accumulator the caller joins into the URI
|
|
2189
|
+
*/
|
|
2190
|
+
private _appendFilters;
|
|
2191
|
+
/**
|
|
2192
|
+
* Append the `pagination[page]` / `pagination[pageSize]` wrapper
|
|
2193
|
+
*
|
|
2194
|
+
* Page-based mode is the Strapi default; offset-based
|
|
2195
|
+
* (`pagination[start]` / `pagination[limit]`) is out of scope for this
|
|
2196
|
+
* driver until cursor/offset pagination lands library-wide.
|
|
2197
|
+
*
|
|
2198
|
+
* @param state - The current query builder state
|
|
2199
|
+
* @param out - The accumulator the caller joins into the URI
|
|
2200
|
+
*/
|
|
2201
|
+
private _appendPagination;
|
|
2202
|
+
/**
|
|
2203
|
+
* Append the `populate` parameter from the includes array
|
|
2204
|
+
*
|
|
2205
|
+
* Emits `populate[0]=relation1&populate[1]=relation2`; deep-populate
|
|
2206
|
+
* syntax (`populate[author][fields][0]=name`) is not exposed through
|
|
2207
|
+
* the current state shape.
|
|
2208
|
+
*
|
|
2209
|
+
* @param state - The current query builder state
|
|
2210
|
+
* @param out - The accumulator the caller joins into the URI
|
|
2211
|
+
*/
|
|
2212
|
+
private _appendPopulate;
|
|
2213
|
+
/**
|
|
2214
|
+
* Append the `sort[N]=field:dir` array
|
|
2215
|
+
*
|
|
2216
|
+
* @param state - The current query builder state
|
|
2217
|
+
* @param out - The accumulator the caller joins into the URI
|
|
2218
|
+
*/
|
|
2219
|
+
private _appendSort;
|
|
2220
|
+
/**
|
|
2221
|
+
* Translate a `FilterOperatorEnum` operator filter into Strapi's
|
|
2222
|
+
* `$operator → value` payload shape
|
|
2223
|
+
*
|
|
2224
|
+
* The mapping is library-canonical → Strapi-native:
|
|
2225
|
+
* - `EQ`/`GT`/`GTE`/`LT`/`LTE`/`CONTAINS` → identity (same key name)
|
|
2226
|
+
* - `ILIKE` → `$containsi` (case-insensitive contains)
|
|
2227
|
+
* - `IN` → `$in` (array)
|
|
2228
|
+
* - `SW` → `$startsWith`
|
|
2229
|
+
* - `BTW` → `$between` with `[min, max]` (arity-checked)
|
|
2230
|
+
* - `NOT` → `$ne` (single value) / `$notIn` (multi-value)
|
|
2231
|
+
* - `NULL` → `$null=true` (when value is `true`) / `$notNull=true`
|
|
2232
|
+
* (when value is `false`); arity- and type-checked
|
|
2233
|
+
*
|
|
2234
|
+
* PostgREST's full-text-search operators (`FTS`, `PHFTS`, `PLFTS`,
|
|
2235
|
+
* `WFTS`) have no Strapi equivalent and throw
|
|
2236
|
+
* `UnsupportedFilterOperatorError`.
|
|
2237
|
+
*
|
|
2238
|
+
* @param filter - The operator filter to translate
|
|
2239
|
+
* @returns A `{ $operator: value }` payload ready to merge under
|
|
2240
|
+
* `filters[field]`
|
|
2241
|
+
* @throws {InvalidFilterOperatorValueError} If `BTW` does not receive
|
|
2242
|
+
* exactly two values, or `NULL` does not receive exactly one boolean
|
|
2243
|
+
* @throws {UnsupportedFilterOperatorError} If the operator is a
|
|
2244
|
+
* PostgREST-only FTS variant
|
|
2245
|
+
*/
|
|
2246
|
+
private _formatOperatorPayload;
|
|
2247
|
+
}
|
|
2248
|
+
|
|
2249
|
+
/**
|
|
2250
|
+
* Response strategy for the Strapi driver
|
|
2251
|
+
*
|
|
2252
|
+
* Parses Strapi v4/v5 pagination responses:
|
|
2253
|
+
* ```json
|
|
2254
|
+
* {
|
|
2255
|
+
* "data": [{ "id": 1, "documentId": "abc", "title": "Hello" }],
|
|
2256
|
+
* "meta": {
|
|
2257
|
+
* "pagination": {
|
|
2258
|
+
* "page": 1,
|
|
2259
|
+
* "pageSize": 10,
|
|
2260
|
+
* "pageCount": 5,
|
|
2261
|
+
* "total": 48
|
|
2262
|
+
* }
|
|
2263
|
+
* }
|
|
2264
|
+
* }
|
|
2265
|
+
* ```
|
|
2266
|
+
*
|
|
2267
|
+
* Default key paths are configured in `StrapiResponseOptions`. Strapi
|
|
2268
|
+
* does not include navigation links in the envelope, so `firstPageUrl`,
|
|
2269
|
+
* `prevPageUrl`, `nextPageUrl`, and `lastPageUrl` resolve to `undefined`
|
|
2270
|
+
* unless the consumer overrides their paths via `IPaginationConfig`. The
|
|
2271
|
+
* traversal algorithm (dot-notation resolution + computed `from`/`to`)
|
|
2272
|
+
* is inherited from `AbstractDotPathResponseStrategy`; this class exists
|
|
2273
|
+
* so `DriverEnum.STRAPI` resolves to a distinct identity at the DI
|
|
2274
|
+
* layer even though the parsing logic is shared with JSON:API and
|
|
2275
|
+
* NestJS.
|
|
2276
|
+
*
|
|
2277
|
+
* @see https://docs.strapi.io/dev-docs/api/rest/sort-pagination
|
|
2278
|
+
*/
|
|
2279
|
+
declare class StrapiResponseStrategy extends AbstractDotPathResponseStrategy {
|
|
2280
|
+
}
|
|
2281
|
+
|
|
2282
|
+
export { DriverEnum, FilterOperatorEnum, InvalidFilterOperatorValueError, InvalidLimitError, InvalidPageNumberError, InvalidResourceNameError, JsonApiRequestStrategy, JsonApiResponseStrategy, KeyNotFoundError, LaravelRequestStrategy, LaravelResponseStrategy, NG_QUBEE_DRIVER, NG_QUBEE_REQUEST_OPTIONS, NG_QUBEE_REQUEST_STRATEGY, NG_QUBEE_RESPONSE_OPTIONS, NG_QUBEE_RESPONSE_STRATEGY, NestjsRequestStrategy, NestjsResponseStrategy, NgQubeeModule, NgQubeeService, PaginatedCollection, PaginationModeEnum, PaginationNotSyncedError, PaginationService, PostgrestRequestStrategy, PostgrestResponseStrategy, SortEnum, SpatieRequestStrategy, SpatieResponseStrategy, StrapiRequestStrategy, StrapiResponseStrategy, UnselectableModelError, UnsupportedFieldSelectionError, UnsupportedFilterError, UnsupportedFilterOperatorError, UnsupportedIncludesError, UnsupportedSearchError, UnsupportedSelectError, UnsupportedSortError, buildNgQubeeProviders, provideNgQubee, provideNgQubeeInstance, readHeader };
|
|
2283
|
+
export type { HeaderBag, IConfig, IFields, IFilters, INestState, IOperatorFilter, IPage, IPaginatedObject, IPaginationConfig, IQueryBuilderConfig, IQueryBuilderState, IRequestStrategy, IResponseStrategy, ISort };
|