ng-qubee 3.0.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.
package/README.md CHANGED
@@ -15,7 +15,7 @@ NgQubee is a Query Builder for Angular. Easily compose your API requests without
15
15
  - Pagination ready
16
16
  - Reactive, as the results are emitted with a RxJS Observable
17
17
  - Developed with a test-driven approach
18
- - **Multi-driver support**: Laravel (pagination-only), Spatie Query Builder, and NestJS (nestjs-paginate)
18
+ - **Multi-driver support**: JSON:API, Laravel (pagination-only), Spatie Query Builder, and NestJS (nestjs-paginate)
19
19
 
20
20
  ## We love it, we use it ❤️
21
21
  NgQubee uses some open source projects to work properly:
@@ -41,16 +41,46 @@ npm i ng-qubee
41
41
 
42
42
  ## Drivers
43
43
 
44
- NgQubee supports three drivers out of the box. A driver **must** be specified in the configuration:
44
+ NgQubee supports four drivers out of the box. A driver **must** be specified in the configuration:
45
45
 
46
46
  | Driver | Backend | Request Format | Response Format |
47
47
  |---|---|---|---|
48
+ | **JSON:API** | Any JSON:API-compliant backend | `filter[field]=value`, `sort=-field`, `page[number]=N&page[size]=N` | Nested: `{ data, meta: {...}, links: {...} }` |
48
49
  | **Laravel** | Plain Laravel pagination | `limit=N&page=N` (pagination only) | Flat: `{ data, current_page, total, ... }` |
49
50
  | **Spatie** | Spatie Query Builder | `filter[field]=value`, `sort=-field` | Flat: `{ data, current_page, total, ... }` |
50
51
  | **NestJS** | nestjs-paginate | `filter.field=$operator:value`, `sortBy=field:DESC` | Nested: `{ data, meta: {...}, links: {...} }` |
51
52
 
52
53
  ## Usage
53
54
 
55
+ ### JSON:API Driver
56
+
57
+ The JSON:API driver generates URIs compatible with any [JSON:API](https://jsonapi.org/format/)-compliant backend (Rails, Django, .NET, Java, Elixir, etc.):
58
+
59
+ ```typescript
60
+ import { DriverEnum } from 'ng-qubee';
61
+
62
+ // Standalone approach
63
+ bootstrapApplication(AppComponent, {
64
+ providers: [provideNgQubee({ driver: DriverEnum.JSON_API })]
65
+ });
66
+
67
+ // Module approach
68
+ @NgModule({
69
+ imports: [
70
+ NgQubeeModule.forRoot({ driver: DriverEnum.JSON_API })
71
+ ]
72
+ })
73
+ export class AppModule {}
74
+ ```
75
+
76
+ The JSON:API driver supports:
77
+
78
+ - **Filters** are composed as `filter[field]=value`
79
+ - **Fields** are composed as `fields[type]=col1,col2`
80
+ - **Includes** are composed as `include=author,comments.author`
81
+ - **Sort** is composed as `sort=-created_at,name` (`-` prefix = DESC)
82
+ - **Pagination** uses bracket notation: `page[number]=1&page[size]=15`
83
+
54
84
  ### Laravel Driver (pagination-only)
55
85
 
56
86
  The Laravel driver provides basic pagination — limit and page parameters only. No filters, sorts, fields, or includes are supported.
@@ -166,7 +196,7 @@ this._ngQubeeService.setResource('users');
166
196
  This is necessary to build the prefix of the URI (/users)
167
197
 
168
198
 
169
- ### Fields (Spatie only)
199
+ ### Fields (JSON:API + Spatie)
170
200
  Fields can be selected as following:
171
201
 
172
202
  ```typescript
@@ -184,7 +214,7 @@ this._ngQubeeService.addSelect('id', 'name', 'email');
184
214
 
185
215
  Will output _/users?select=id,name,email_
186
216
 
187
- ### Filters (Spatie + NestJS)
217
+ ### Filters (JSON:API + Spatie + NestJS)
188
218
  Filters are applied as following:
189
219
 
190
220
  ```typescript
@@ -234,7 +264,7 @@ this._ngQubeeService.addFilterOperator('name', FilterOperatorEnum.ILIKE, 'john')
234
264
 
235
265
  **Available operators:** `$eq`, `$not`, `$null`, `$in`, `$gt`, `$gte`, `$lt`, `$lte`, `$btw`, `$ilike`, `$sw`, `$contains`
236
266
 
237
- ### Includes (Spatie only)
267
+ ### Includes (JSON:API + Spatie)
238
268
  Ask to include related models with:
239
269
 
240
270
  ```typescript
@@ -252,7 +282,7 @@ this._ngQubeeService.setSearch('john doe');
252
282
 
253
283
  Will output _/users?search=john doe_
254
284
 
255
- ### Sort (Spatie + NestJS)
285
+ ### Sort (JSON:API + Spatie + NestJS)
256
286
  Sort elements as following:
257
287
 
258
288
  ```typescript
@@ -285,6 +315,28 @@ Default values are automatically added to the query:
285
315
 
286
316
  Always expect your query to include _limit=15&page=1_
287
317
 
318
+ #### Fetch all (NestJS only)
319
+
320
+ When the active driver is NestJS, `setLimit(-1)` is accepted as a "fetch all items" sentinel, following the [nestjs-paginate](https://github.com/ppetzold/nestjs-paginate) convention (the server must opt in via `maxLimit: -1`):
321
+
322
+ ```typescript
323
+ // NestJS driver only
324
+ this._ngQubeeService.setLimit(-1);
325
+ ```
326
+
327
+ JSON:API, Laravel, and Spatie drivers reject `-1` and throw `InvalidLimitError`.
328
+
329
+ #### Limit validation
330
+
331
+ Limit validation is driver-scoped — each request strategy enforces its own accepted range and invalid values throw `InvalidLimitError` immediately when passed to `setLimit()`:
332
+
333
+ | Driver | Accepted limit values |
334
+ |---|---|
335
+ | NestJS | integer `-1` (fetch all) or `>= 1` |
336
+ | JSON:API / Laravel / Spatie | integer `>= 1` |
337
+
338
+ Non-integer values, zero, negative numbers (other than `-1` for NestJS), `NaN`, and `Infinity` are all rejected.
339
+
288
340
  ### Retrieving data
289
341
  URI is generated invoking the _generateUri_ method of the NgQubeeService. An observable is returned and the URI will be emitted:
290
342
 
@@ -297,11 +349,11 @@ this._ngQubeeService.generateUri().subscribe(uri => console.log(uri));
297
349
  All query features have corresponding delete methods:
298
350
 
299
351
  ```typescript
300
- // Spatie + NestJS
352
+ // JSON:API + Spatie + NestJS
301
353
  this._ngQubeeService.deleteFilters('status', 'role');
302
354
  this._ngQubeeService.deleteSorts('created_at');
303
355
 
304
- // Spatie only
356
+ // JSON:API + Spatie only
305
357
  this._ngQubeeService.deleteFields({ users: ['email'] });
306
358
  this._ngQubeeService.deleteFieldsByModel('users', 'email');
307
359
  this._ngQubeeService.deleteIncludes('profile');
@@ -323,15 +375,15 @@ this._ngQubeeService.reset();
323
375
 
324
376
  Calling a method that is not supported by the active driver throws a descriptive error immediately:
325
377
 
326
- | Method | Laravel | Spatie | NestJS |
327
- |---|---|---|---|
328
- | `addFilter()` / `deleteFilters()` | throws `UnsupportedFilterError` | supported | supported |
329
- | `addSort()` / `deleteSorts()` | throws `UnsupportedSortError` | supported | supported |
330
- | `addFields()` / `deleteFields()` / `deleteFieldsByModel()` | throws `UnsupportedFieldSelectionError` | supported | throws `UnsupportedFieldSelectionError` |
331
- | `addIncludes()` / `deleteIncludes()` | throws `UnsupportedIncludesError` | supported | throws `UnsupportedIncludesError` |
332
- | `addFilterOperator()` / `deleteOperatorFilters()` | throws `UnsupportedFilterOperatorError` | throws `UnsupportedFilterOperatorError` | supported |
333
- | `addSelect()` / `deleteSelect()` | throws `UnsupportedSelectError` | throws `UnsupportedSelectError` | supported |
334
- | `setSearch()` / `deleteSearch()` | throws `UnsupportedSearchError` | throws `UnsupportedSearchError` | supported |
378
+ | Method | JSON:API | Laravel | Spatie | NestJS |
379
+ |---|---|---|---|---|
380
+ | `addFilter()` / `deleteFilters()` | supported | throws `UnsupportedFilterError` | supported | supported |
381
+ | `addSort()` / `deleteSorts()` | supported | throws `UnsupportedSortError` | supported | supported |
382
+ | `addFields()` / `deleteFields()` / `deleteFieldsByModel()` | supported | throws `UnsupportedFieldSelectionError` | supported | throws `UnsupportedFieldSelectionError` |
383
+ | `addIncludes()` / `deleteIncludes()` | supported | throws `UnsupportedIncludesError` | supported | throws `UnsupportedIncludesError` |
384
+ | `addFilterOperator()` / `deleteOperatorFilters()` | throws `UnsupportedFilterOperatorError` | throws `UnsupportedFilterOperatorError` | throws `UnsupportedFilterOperatorError` | supported |
385
+ | `addSelect()` / `deleteSelect()` | throws `UnsupportedSelectError` | throws `UnsupportedSelectError` | throws `UnsupportedSelectError` | supported |
386
+ | `setSearch()` / `deleteSearch()` | throws `UnsupportedSearchError` | throws `UnsupportedSearchError` | throws `UnsupportedSearchError` | supported |
335
387
 
336
388
  ## Pagination
337
389
  If you are working with an API that supports pagination, we have got you covered 😉 NgQubee provides:
@@ -368,6 +420,30 @@ When using the Laravel or Spatie driver, the paginated collection will check for
368
420
  - first_page_url - URL to the first page
369
421
  - last_page_url - URL to the last page
370
422
 
423
+ ### JSON:API Response Format
424
+
425
+ When using the JSON:API driver, the PaginationService automatically parses nested responses:
426
+
427
+ ```json
428
+ {
429
+ "data": [...],
430
+ "meta": {
431
+ "current-page": 1,
432
+ "per-page": 10,
433
+ "total": 100,
434
+ "page-count": 10
435
+ },
436
+ "links": {
437
+ "first": "http://api.com/articles?page[number]=1&page[size]=10",
438
+ "prev": null,
439
+ "next": "http://api.com/articles?page[number]=2&page[size]=10",
440
+ "last": "http://api.com/articles?page[number]=10&page[size]=10"
441
+ }
442
+ }
443
+ ```
444
+
445
+ The `from` and `to` values are computed automatically from `current-page` and `per-page` when not present in the response. JSON:API meta key names vary by implementation; defaults can be fully customised via response configuration.
446
+
371
447
  ### NestJS Response Format
372
448
 
373
449
  When using the NestJS driver, the PaginationService automatically parses nested responses:
@@ -426,6 +502,7 @@ NgQubee is fully typed and exports all public interfaces, enums, and types for T
426
502
  import { DriverEnum, FilterOperatorEnum, SortEnum } from 'ng-qubee';
427
503
 
428
504
  // Driver options
505
+ DriverEnum.JSON_API // 'json-api'
429
506
  DriverEnum.LARAVEL // 'laravel' (pagination only)
430
507
  DriverEnum.SPATIE // 'spatie'
431
508
  DriverEnum.NESTJS // 'nestjs'