ng-qubee 3.3.0 → 3.5.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 +41 -883
- package/fesm2022/ng-qubee.mjs +880 -102
- package/fesm2022/ng-qubee.mjs.map +1 -1
- package/package.json +18 -9
- package/types/ng-qubee.d.ts +218 -19
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"name": "Andrea Tantimonaco",
|
|
5
5
|
"url": "https://andreatantimonaco.me"
|
|
6
6
|
},
|
|
7
|
-
"version": "3.
|
|
7
|
+
"version": "3.5.0",
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
@@ -13,20 +13,29 @@
|
|
|
13
13
|
"bugs": {
|
|
14
14
|
"url": "https://github.com/AndreaAlhena/ng-qubee/issues"
|
|
15
15
|
},
|
|
16
|
-
"homepage": "https://
|
|
16
|
+
"homepage": "https://ng-qubee.andreatantimonaco.me",
|
|
17
17
|
"keywords": [
|
|
18
18
|
"angular",
|
|
19
|
-
"query-builder",
|
|
20
19
|
"api",
|
|
21
|
-
"
|
|
22
|
-
"
|
|
20
|
+
"builder",
|
|
21
|
+
"django",
|
|
22
|
+
"drf",
|
|
23
23
|
"filter",
|
|
24
|
+
"headless-cms",
|
|
25
|
+
"json-api",
|
|
26
|
+
"laravel",
|
|
27
|
+
"nestjs",
|
|
28
|
+
"nestjs-paginate",
|
|
29
|
+
"pagination",
|
|
30
|
+
"postgrest",
|
|
24
31
|
"query",
|
|
25
|
-
"builder",
|
|
26
|
-
"
|
|
32
|
+
"query-builder",
|
|
33
|
+
"rxjs",
|
|
27
34
|
"signals",
|
|
28
|
-
"
|
|
29
|
-
"
|
|
35
|
+
"spatie",
|
|
36
|
+
"strapi",
|
|
37
|
+
"supabase",
|
|
38
|
+
"typescript"
|
|
30
39
|
],
|
|
31
40
|
"allowedNonPeerDependencies": [
|
|
32
41
|
"qs"
|
package/types/ng-qubee.d.ts
CHANGED
|
@@ -46,11 +46,13 @@ declare class PaginatedCollection<T extends IPaginatedObject> {
|
|
|
46
46
|
* request building (URI generation) and response parsing.
|
|
47
47
|
*/
|
|
48
48
|
declare enum DriverEnum {
|
|
49
|
+
DRF = "drf",
|
|
49
50
|
JSON_API = "json-api",
|
|
50
51
|
LARAVEL = "laravel",
|
|
51
52
|
NESTJS = "nestjs",
|
|
52
53
|
POSTGREST = "postgrest",
|
|
53
|
-
SPATIE = "spatie"
|
|
54
|
+
SPATIE = "spatie",
|
|
55
|
+
STRAPI = "strapi"
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
/**
|
|
@@ -1641,6 +1643,36 @@ declare class LaravelRequestStrategy extends AbstractRequestStrategy {
|
|
|
1641
1643
|
protected parts(state: IQueryBuilderState, options: QueryBuilderOptions): string[];
|
|
1642
1644
|
}
|
|
1643
1645
|
|
|
1646
|
+
/**
|
|
1647
|
+
* Base class for response strategies whose pagination metadata is a flat
|
|
1648
|
+
* key-value envelope on the response body
|
|
1649
|
+
*
|
|
1650
|
+
* Laravel's stock pagination and Spatie's `QueryBuilder` both emit the
|
|
1651
|
+
* same flat shape — `{ data, current_page, total, per_page, from, to,
|
|
1652
|
+
* next_page_url, prev_page_url, first_page_url, last_page, last_page_url
|
|
1653
|
+
* }` — and both response strategies were duplicating the byte-identical
|
|
1654
|
+
* `new PaginatedCollection(response[options.X], ...)` body before this
|
|
1655
|
+
* base existed. Concrete classes now extend and provide only the
|
|
1656
|
+
* docstring describing their driver's specific shape (see
|
|
1657
|
+
* `LaravelResponseStrategy`, `SpatieResponseStrategy`).
|
|
1658
|
+
*
|
|
1659
|
+
* Drivers whose pagination metadata is a nested envelope (JSON:API,
|
|
1660
|
+
* NestJS, Strapi) extend `AbstractDotPathResponseStrategy` instead.
|
|
1661
|
+
* Drivers whose metadata comes from HTTP headers (PostgREST) or is
|
|
1662
|
+
* derived from response URLs (DRF) implement `IResponseStrategy`
|
|
1663
|
+
* directly.
|
|
1664
|
+
*/
|
|
1665
|
+
declare abstract class AbstractFlatResponseStrategy implements IResponseStrategy {
|
|
1666
|
+
/**
|
|
1667
|
+
* Parse a flat-envelope pagination response into a PaginatedCollection
|
|
1668
|
+
*
|
|
1669
|
+
* @param response - The raw API response object
|
|
1670
|
+
* @param options - The response key name configuration
|
|
1671
|
+
* @returns A typed PaginatedCollection instance
|
|
1672
|
+
*/
|
|
1673
|
+
paginate<T extends IPaginatedObject>(response: Record<string, any>, options: ResponseOptions): PaginatedCollection<T>;
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1644
1676
|
/**
|
|
1645
1677
|
* Response strategy for the Laravel (pagination-only) driver
|
|
1646
1678
|
*
|
|
@@ -1653,19 +1685,20 @@ declare class LaravelRequestStrategy extends AbstractRequestStrategy {
|
|
|
1653
1685
|
* "per_page": 15,
|
|
1654
1686
|
* "from": 1,
|
|
1655
1687
|
* "to": 15,
|
|
1656
|
-
* ...
|
|
1688
|
+
* "next_page_url": "...",
|
|
1689
|
+
* "prev_page_url": "...",
|
|
1690
|
+
* "first_page_url": "...",
|
|
1691
|
+
* "last_page": 7,
|
|
1692
|
+
* "last_page_url": "..."
|
|
1657
1693
|
* }
|
|
1658
1694
|
* ```
|
|
1695
|
+
*
|
|
1696
|
+
* The traversal algorithm (flat `response[options.X]` lookups) is
|
|
1697
|
+
* inherited from `AbstractFlatResponseStrategy`; this class exists so
|
|
1698
|
+
* `DriverEnum.LARAVEL` resolves to a distinct identity at the DI layer
|
|
1699
|
+
* even though the parsing logic is shared with Spatie.
|
|
1659
1700
|
*/
|
|
1660
|
-
declare class LaravelResponseStrategy
|
|
1661
|
-
/**
|
|
1662
|
-
* Parse a flat Laravel pagination response into a PaginatedCollection
|
|
1663
|
-
*
|
|
1664
|
-
* @param response - The raw API response object
|
|
1665
|
-
* @param options - The response key name configuration
|
|
1666
|
-
* @returns A typed PaginatedCollection instance
|
|
1667
|
-
*/
|
|
1668
|
-
paginate<T extends IPaginatedObject>(response: Record<string, any>, options: ResponseOptions): PaginatedCollection<T>;
|
|
1701
|
+
declare class LaravelResponseStrategy extends AbstractFlatResponseStrategy {
|
|
1669
1702
|
}
|
|
1670
1703
|
|
|
1671
1704
|
/**
|
|
@@ -2084,7 +2117,8 @@ declare class SpatieRequestStrategy extends AbstractRequestStrategy {
|
|
|
2084
2117
|
/**
|
|
2085
2118
|
* Response strategy for the Spatie Query Builder driver
|
|
2086
2119
|
*
|
|
2087
|
-
* Parses flat Laravel pagination responses
|
|
2120
|
+
* Parses flat Laravel-style pagination responses (Spatie's Query Builder
|
|
2121
|
+
* is built on Laravel's pagination):
|
|
2088
2122
|
* ```json
|
|
2089
2123
|
* {
|
|
2090
2124
|
* "data": [...],
|
|
@@ -2097,18 +2131,183 @@ declare class SpatieRequestStrategy extends AbstractRequestStrategy {
|
|
|
2097
2131
|
* }
|
|
2098
2132
|
* ```
|
|
2099
2133
|
*
|
|
2134
|
+
* The traversal algorithm (flat `response[options.X]` lookups) is
|
|
2135
|
+
* inherited from `AbstractFlatResponseStrategy`; this class exists so
|
|
2136
|
+
* `DriverEnum.SPATIE` resolves to a distinct identity at the DI layer
|
|
2137
|
+
* even though the parsing logic is shared with the plain Laravel driver.
|
|
2138
|
+
*
|
|
2100
2139
|
* @see https://spatie.be/docs/laravel-query-builder
|
|
2101
2140
|
*/
|
|
2102
|
-
declare class SpatieResponseStrategy
|
|
2141
|
+
declare class SpatieResponseStrategy extends AbstractFlatResponseStrategy {
|
|
2142
|
+
}
|
|
2143
|
+
|
|
2144
|
+
/**
|
|
2145
|
+
* Request strategy for the Strapi driver
|
|
2146
|
+
*
|
|
2147
|
+
* Generates URIs in [Strapi's filter API format](https://docs.strapi.io/dev-docs/api/rest/filters-locale-publication):
|
|
2148
|
+
* - Filters: `filters[field][$eq]=value` (multi-value collapses to `$in`)
|
|
2149
|
+
* - Operator filters: `filters[field][$op]=value` (translated from
|
|
2150
|
+
* `FilterOperatorEnum` — `BTW`→`$between`, `SW`→`$startsWith`,
|
|
2151
|
+
* `ILIKE`→`$containsi`, `NOT`→`$ne`/`$notIn`,
|
|
2152
|
+
* `NULL`→`$null`/`$notNull`)
|
|
2153
|
+
* - Sorts: `sort[0]=field:asc&sort[1]=field:desc`
|
|
2154
|
+
* - Field selection (flat): `fields[0]=col1&fields[1]=col2`
|
|
2155
|
+
* - Population: `populate[0]=relation`
|
|
2156
|
+
* - Pagination (page-based): `pagination[page]=N&pagination[pageSize]=N`
|
|
2157
|
+
*
|
|
2158
|
+
* Strapi-native full-text search (`FTS`, `PHFTS`, `PLFTS`, `WFTS`) is
|
|
2159
|
+
* PostgREST-only and throws `UnsupportedFilterOperatorError` here.
|
|
2160
|
+
*
|
|
2161
|
+
* @see https://docs.strapi.io/dev-docs/api/rest/filters-locale-publication
|
|
2162
|
+
*/
|
|
2163
|
+
declare class StrapiRequestStrategy extends AbstractRequestStrategy {
|
|
2103
2164
|
/**
|
|
2104
|
-
*
|
|
2165
|
+
* Filters, operator filters, sorts, populate (`includes`), flat field
|
|
2166
|
+
* selection (`select`) — no per-model fields, no global search (use
|
|
2167
|
+
* `$contains` / `$containsi` operator filters instead)
|
|
2168
|
+
*/
|
|
2169
|
+
readonly capabilities: IStrategyCapabilities;
|
|
2170
|
+
/**
|
|
2171
|
+
* Strapi-native names of the four hardcoded query keys
|
|
2105
2172
|
*
|
|
2106
|
-
*
|
|
2107
|
-
*
|
|
2108
|
-
*
|
|
2173
|
+
* Strapi's wire format is fixed (the server reads `pagination[page]`,
|
|
2174
|
+
* `populate`, `sort`, `fields`); these keys are intentionally not
|
|
2175
|
+
* configurable through `QueryBuilderOptions` and live as private
|
|
2176
|
+
* statics so they are visible in one place.
|
|
2109
2177
|
*/
|
|
2110
|
-
|
|
2178
|
+
private static readonly _fieldsKey;
|
|
2179
|
+
private static readonly _paginationKey;
|
|
2180
|
+
private static readonly _populateKey;
|
|
2181
|
+
private static readonly _sortKey;
|
|
2182
|
+
/**
|
|
2183
|
+
* Emit Strapi-format query-string segments in canonical order:
|
|
2184
|
+
* populate → fields → filters (merged) → sort → pagination
|
|
2185
|
+
*
|
|
2186
|
+
* Simple filters and operator filters share a single `filters` wrapper
|
|
2187
|
+
* so qs emits one ordered, deeply-nested bracket structure rather than
|
|
2188
|
+
* two duplicate top-level `filters[...]` blocks.
|
|
2189
|
+
*
|
|
2190
|
+
* @param state - The current query builder state
|
|
2191
|
+
* @param _options - The query parameter key name configuration (unused;
|
|
2192
|
+
* Strapi's wire keys are fixed by the server)
|
|
2193
|
+
* @returns Ordered query-string fragments
|
|
2194
|
+
*/
|
|
2195
|
+
protected parts(state: IQueryBuilderState, _options: QueryBuilderOptions): string[];
|
|
2196
|
+
/**
|
|
2197
|
+
* Append `fields[0]=col1&fields[1]=col2` from the flat select array
|
|
2198
|
+
*
|
|
2199
|
+
* Strapi's `fields` parameter is the column-pruner for the main
|
|
2200
|
+
* resource; per-relation field selection is expressed through the
|
|
2201
|
+
* `populate` deep syntax (out of scope for this driver).
|
|
2202
|
+
*
|
|
2203
|
+
* @param state - The current query builder state
|
|
2204
|
+
* @param out - The accumulator the caller joins into the URI
|
|
2205
|
+
*/
|
|
2206
|
+
private _appendFields;
|
|
2207
|
+
/**
|
|
2208
|
+
* Append the unified `filters[...]` wrapper combining simple filters
|
|
2209
|
+
* and operator filters
|
|
2210
|
+
*
|
|
2211
|
+
* Both kinds emit into the same nested object under `filters` so qs
|
|
2212
|
+
* produces a single deeply-bracketed block per request. Simple
|
|
2213
|
+
* single-value filters fold to `$eq`; simple multi-value filters fold
|
|
2214
|
+
* to `$in`. Operator filters then merge into the same per-field map,
|
|
2215
|
+
* potentially co-existing with a simple filter on the same field.
|
|
2216
|
+
*
|
|
2217
|
+
* @param state - The current query builder state
|
|
2218
|
+
* @param out - The accumulator the caller joins into the URI
|
|
2219
|
+
*/
|
|
2220
|
+
private _appendFilters;
|
|
2221
|
+
/**
|
|
2222
|
+
* Append the `pagination[page]` / `pagination[pageSize]` wrapper
|
|
2223
|
+
*
|
|
2224
|
+
* Page-based mode is the Strapi default; offset-based
|
|
2225
|
+
* (`pagination[start]` / `pagination[limit]`) is out of scope for this
|
|
2226
|
+
* driver until cursor/offset pagination lands library-wide.
|
|
2227
|
+
*
|
|
2228
|
+
* @param state - The current query builder state
|
|
2229
|
+
* @param out - The accumulator the caller joins into the URI
|
|
2230
|
+
*/
|
|
2231
|
+
private _appendPagination;
|
|
2232
|
+
/**
|
|
2233
|
+
* Append the `populate` parameter from the includes array
|
|
2234
|
+
*
|
|
2235
|
+
* Emits `populate[0]=relation1&populate[1]=relation2`; deep-populate
|
|
2236
|
+
* syntax (`populate[author][fields][0]=name`) is not exposed through
|
|
2237
|
+
* the current state shape.
|
|
2238
|
+
*
|
|
2239
|
+
* @param state - The current query builder state
|
|
2240
|
+
* @param out - The accumulator the caller joins into the URI
|
|
2241
|
+
*/
|
|
2242
|
+
private _appendPopulate;
|
|
2243
|
+
/**
|
|
2244
|
+
* Append the `sort[N]=field:dir` array
|
|
2245
|
+
*
|
|
2246
|
+
* @param state - The current query builder state
|
|
2247
|
+
* @param out - The accumulator the caller joins into the URI
|
|
2248
|
+
*/
|
|
2249
|
+
private _appendSort;
|
|
2250
|
+
/**
|
|
2251
|
+
* Translate a `FilterOperatorEnum` operator filter into Strapi's
|
|
2252
|
+
* `$operator → value` payload shape
|
|
2253
|
+
*
|
|
2254
|
+
* The mapping is library-canonical → Strapi-native:
|
|
2255
|
+
* - `EQ`/`GT`/`GTE`/`LT`/`LTE`/`CONTAINS` → identity (same key name)
|
|
2256
|
+
* - `ILIKE` → `$containsi` (case-insensitive contains)
|
|
2257
|
+
* - `IN` → `$in` (array)
|
|
2258
|
+
* - `SW` → `$startsWith`
|
|
2259
|
+
* - `BTW` → `$between` with `[min, max]` (arity-checked)
|
|
2260
|
+
* - `NOT` → `$ne` (single value) / `$notIn` (multi-value)
|
|
2261
|
+
* - `NULL` → `$null=true` (when value is `true`) / `$notNull=true`
|
|
2262
|
+
* (when value is `false`); arity- and type-checked
|
|
2263
|
+
*
|
|
2264
|
+
* PostgREST's full-text-search operators (`FTS`, `PHFTS`, `PLFTS`,
|
|
2265
|
+
* `WFTS`) have no Strapi equivalent and throw
|
|
2266
|
+
* `UnsupportedFilterOperatorError`.
|
|
2267
|
+
*
|
|
2268
|
+
* @param filter - The operator filter to translate
|
|
2269
|
+
* @returns A `{ $operator: value }` payload ready to merge under
|
|
2270
|
+
* `filters[field]`
|
|
2271
|
+
* @throws {InvalidFilterOperatorValueError} If `BTW` does not receive
|
|
2272
|
+
* exactly two values, or `NULL` does not receive exactly one boolean
|
|
2273
|
+
* @throws {UnsupportedFilterOperatorError} If the operator is a
|
|
2274
|
+
* PostgREST-only FTS variant
|
|
2275
|
+
*/
|
|
2276
|
+
private _formatOperatorPayload;
|
|
2277
|
+
}
|
|
2278
|
+
|
|
2279
|
+
/**
|
|
2280
|
+
* Response strategy for the Strapi driver
|
|
2281
|
+
*
|
|
2282
|
+
* Parses Strapi v4/v5 pagination responses:
|
|
2283
|
+
* ```json
|
|
2284
|
+
* {
|
|
2285
|
+
* "data": [{ "id": 1, "documentId": "abc", "title": "Hello" }],
|
|
2286
|
+
* "meta": {
|
|
2287
|
+
* "pagination": {
|
|
2288
|
+
* "page": 1,
|
|
2289
|
+
* "pageSize": 10,
|
|
2290
|
+
* "pageCount": 5,
|
|
2291
|
+
* "total": 48
|
|
2292
|
+
* }
|
|
2293
|
+
* }
|
|
2294
|
+
* }
|
|
2295
|
+
* ```
|
|
2296
|
+
*
|
|
2297
|
+
* Default key paths are configured in `StrapiResponseOptions`. Strapi
|
|
2298
|
+
* does not include navigation links in the envelope, so `firstPageUrl`,
|
|
2299
|
+
* `prevPageUrl`, `nextPageUrl`, and `lastPageUrl` resolve to `undefined`
|
|
2300
|
+
* unless the consumer overrides their paths via `IPaginationConfig`. The
|
|
2301
|
+
* traversal algorithm (dot-notation resolution + computed `from`/`to`)
|
|
2302
|
+
* is inherited from `AbstractDotPathResponseStrategy`; this class exists
|
|
2303
|
+
* so `DriverEnum.STRAPI` resolves to a distinct identity at the DI
|
|
2304
|
+
* layer even though the parsing logic is shared with JSON:API and
|
|
2305
|
+
* NestJS.
|
|
2306
|
+
*
|
|
2307
|
+
* @see https://docs.strapi.io/dev-docs/api/rest/sort-pagination
|
|
2308
|
+
*/
|
|
2309
|
+
declare class StrapiResponseStrategy extends AbstractDotPathResponseStrategy {
|
|
2111
2310
|
}
|
|
2112
2311
|
|
|
2113
|
-
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, UnselectableModelError, UnsupportedFieldSelectionError, UnsupportedFilterError, UnsupportedFilterOperatorError, UnsupportedIncludesError, UnsupportedSearchError, UnsupportedSelectError, UnsupportedSortError, buildNgQubeeProviders, provideNgQubee, provideNgQubeeInstance, readHeader };
|
|
2312
|
+
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 };
|
|
2114
2313
|
export type { HeaderBag, IConfig, IFields, IFilters, INestState, IOperatorFilter, IPage, IPaginatedObject, IPaginationConfig, IQueryBuilderConfig, IQueryBuilderState, IRequestStrategy, IResponseStrategy, ISort };
|