@adonis-agora/filter 0.3.1 → 0.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/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # @adonis-agora/filter
2
2
 
3
+ ## 0.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#6](https://github.com/DavideCarvalho/adonis-filter/pull/6) [`e39da2c`](https://github.com/DavideCarvalho/adonis-filter/commit/e39da2c6f7e47553990f3295414b23d508894c9a) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Os macros `query.applyFilterFromRequest(spec, ctx?)` e `query.filterPaginate(spec, ctx?)` passam a aceitar `ctx` opcional: quando omitido, leem o `HttpContext` ativo do AsyncLocalStorage do Adonis (`HttpContext.getOrFail()`). Nos controllers (99% dos casos) você chama `query.applyFilterFromRequest(spec)` sem passar o ctx. Fora de uma request (job/command), passe o ctx explicitamente. O default vive só no macro (camada Adonis); a função livre `applyFilterFromRequest` continua framework-agnostic, exigindo o ctx.
8
+
9
+ ## 0.4.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#4](https://github.com/DavideCarvalho/adonis-filter/pull/4) [`76b2ca8`](https://github.com/DavideCarvalho/adonis-filter/commit/76b2ca82d27811b09dbd98629be6964e9aee6167) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Add chainable Lucid query-builder macros via an optional `FilterProvider`
14
+
15
+ Register `@adonis-agora/filter/filter_provider` to get the method-call form of
16
+ `applyFilterFromRequest` on any Lucid query builder:
17
+
18
+ ```ts
19
+ // filter + sort + search, then keep chaining:
20
+ const rows = await User.query()
21
+ .where("tenantId", tenant.id)
22
+ .applyFilterFromRequest(userFilter, ctx)
23
+ .orderBy("createdAt", "desc");
24
+
25
+ // filter + paginate in one terminal call (returns Lucid's paginator):
26
+ const page = await User.query().filterPaginate(userFilter, ctx);
27
+ ```
28
+
29
+ `applyFilterFromRequest` applies the spec's server scope + allow-listed
30
+ filter/sort/search and returns the query for chaining (pagination resolved but
31
+ not applied); `filterPaginate` additionally calls `paginate(page, size)`. The
32
+ free functions are unchanged and work without the provider — the macros only add
33
+ the chainable sugar, so `@adonisjs/lucid` is an optional peer. `registerFilterMacros`
34
+ is also exported for manual registration.
35
+
3
36
  ## 0.3.1
4
37
 
5
38
  ### Patch Changes
package/README.md CHANGED
@@ -17,6 +17,33 @@ const { page, size } = applyFilter(query, input, {
17
17
  return query.paginate(page, size)
18
18
  ```
19
19
 
20
+ ### Chainable macros (optional)
21
+
22
+ Register the `FilterProvider` to get the method-call form of
23
+ `applyFilterFromRequest` on any Lucid query builder — the same operation, but
24
+ chainable:
25
+
26
+ ```ts
27
+ // adonisrc.ts → providers
28
+ () => import('@adonis-agora/filter/filter_provider')
29
+ ```
30
+
31
+ ```ts
32
+ // filter + sort + search, then keep chaining:
33
+ const rows = await User.query()
34
+ .where('tenantId', tenant.id)
35
+ .applyFilterFromRequest(userFilter, ctx)
36
+ .orderBy('createdAt', 'desc')
37
+
38
+ // filter + paginate in one terminal call (returns Lucid's paginator):
39
+ const page = await User.query().filterPaginate(userFilter, ctx)
40
+ ```
41
+
42
+ `applyFilterFromRequest` returns the query (pagination resolved but not applied);
43
+ `filterPaginate` applies `paginate(page, size)` with the resolved values. The free
44
+ functions work without the provider — the macros only add the chainable sugar, so
45
+ `@adonisjs/lucid` stays an optional peer.
46
+
20
47
  Operators: equals/notEquals, contains/iContains/startsWith/endsWith, gt/gte/lt/lte,
21
48
  between/notBetween, in/notIn/isAnyOf, isNull/isNotNull/isEmpty/isNotEmpty, plus
22
49
  AND/OR composition. The `allowed`/`sortable`/`searchable` lists are the security
@@ -0,0 +1,28 @@
1
+ import type { ApplicationService } from '@adonisjs/core/types';
2
+ /**
3
+ * Wires `@adonis-agora/filter`'s chainable Lucid macros into the application.
4
+ *
5
+ * On boot it registers the `applyFilterFromRequest` and `filterPaginate` macros
6
+ * onto Lucid's `ModelQueryBuilder`, so any model query gains the method-call form
7
+ * of the free `applyFilterFromRequest` helper:
8
+ *
9
+ * ```ts
10
+ * const rows = await User.query()
11
+ * .where('tenantId', tenant.id)
12
+ * .applyFilterFromRequest(userFilter, ctx)
13
+ * .orderBy('createdAt', 'desc')
14
+ *
15
+ * const page = await User.query().filterPaginate(userFilter, ctx)
16
+ * ```
17
+ *
18
+ * Register it in `adonisrc.ts` (`providers`). The free functions
19
+ * (`applyFilterFromRequest`, `applyCursorFromRequest`) work without it — this
20
+ * provider only adds the chainable sugar, so `@adonisjs/lucid` is loaded lazily
21
+ * here (not a hard dependency of the package).
22
+ */
23
+ export default class FilterProvider {
24
+ protected app: ApplicationService;
25
+ constructor(app: ApplicationService);
26
+ boot(): Promise<void>;
27
+ }
28
+ //# sourceMappingURL=filter_provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter_provider.d.ts","sourceRoot":"","sources":["../../providers/filter_provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG/D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,OAAO,OAAO,cAAc;IACrB,SAAS,CAAC,GAAG,EAAE,kBAAkB;gBAAvB,GAAG,EAAE,kBAAkB;IAEvC,IAAI;CAIX"}
@@ -0,0 +1,33 @@
1
+ import { registerFilterMacros } from '../src/lucid_macros.js';
2
+ /**
3
+ * Wires `@adonis-agora/filter`'s chainable Lucid macros into the application.
4
+ *
5
+ * On boot it registers the `applyFilterFromRequest` and `filterPaginate` macros
6
+ * onto Lucid's `ModelQueryBuilder`, so any model query gains the method-call form
7
+ * of the free `applyFilterFromRequest` helper:
8
+ *
9
+ * ```ts
10
+ * const rows = await User.query()
11
+ * .where('tenantId', tenant.id)
12
+ * .applyFilterFromRequest(userFilter, ctx)
13
+ * .orderBy('createdAt', 'desc')
14
+ *
15
+ * const page = await User.query().filterPaginate(userFilter, ctx)
16
+ * ```
17
+ *
18
+ * Register it in `adonisrc.ts` (`providers`). The free functions
19
+ * (`applyFilterFromRequest`, `applyCursorFromRequest`) work without it — this
20
+ * provider only adds the chainable sugar, so `@adonisjs/lucid` is loaded lazily
21
+ * here (not a hard dependency of the package).
22
+ */
23
+ export default class FilterProvider {
24
+ app;
25
+ constructor(app) {
26
+ this.app = app;
27
+ }
28
+ async boot() {
29
+ const { ModelQueryBuilder } = await import('@adonisjs/lucid/orm');
30
+ registerFilterMacros(ModelQueryBuilder);
31
+ }
32
+ }
33
+ //# sourceMappingURL=filter_provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter_provider.js","sourceRoot":"","sources":["../../providers/filter_provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,OAAO,OAAO,cAAc;IACX;IAAtB,YAAsB,GAAuB;QAAvB,QAAG,GAAH,GAAG,CAAoB;IAAG,CAAC;IAEjD,KAAK,CAAC,IAAI;QACR,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;QAClE,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;IAC1C,CAAC;CACF"}
@@ -12,6 +12,8 @@ export type { FilterClientEntry, FilterClientManifest, FilterFieldKind, FilterFi
12
12
  export type { DefineFilterOptions, FilterSpec, RelationColumns, RelationSpec, TenantResolver, TenantScopeSpec, } from './filter_spec.js';
13
13
  export { applyCursorFromRequest, applyFilterFromRequest } from './apply_from_request.js';
14
14
  export type { ApplyCursorFromRequestOptions, ApplyFromRequestOptions, FilterRequestContext, } from './apply_from_request.js';
15
+ export { registerFilterMacros } from './lucid_macros.js';
16
+ export type { MacroableQueryBuilder } from './lucid_macros.js';
15
17
  export { parseFilterRequest, parseSort, toColumnFilters } from './parse_request.js';
16
18
  export { parseSpatieRequest } from './spatie_parser.js';
17
19
  export type { SpatieInput } from './spatie_parser.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,YAAY,EACV,YAAY,EACZ,cAAc,EACd,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EACL,wBAAwB,EACxB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,QAAQ,EACR,sBAAsB,GACvB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,YAAY,EACZ,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,mBAAmB,EACnB,qBAAqB,EACrB,2BAA2B,GAC5B,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,YAAY,EACZ,cAAc,EACd,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACzF,YAAY,EACV,6BAA6B,EAC7B,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,WAAW,EACX,WAAW,EACX,SAAS,EACT,qBAAqB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,GAC7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,eAAe,EACf,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC1F,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC7F,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,YAAY,EACV,YAAY,EACZ,cAAc,EACd,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EACL,wBAAwB,EACxB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,QAAQ,EACR,sBAAsB,GACvB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,YAAY,EACZ,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,mBAAmB,EACnB,qBAAqB,EACrB,2BAA2B,GAC5B,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,YAAY,EACZ,cAAc,EACd,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACzF,YAAY,EACV,6BAA6B,EAC7B,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,YAAY,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,WAAW,EACX,WAAW,EACX,SAAS,EACT,qBAAqB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,GAC7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,eAAe,EACf,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC1F,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC7F,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/src/index.js CHANGED
@@ -7,6 +7,7 @@ export { escapeLike } from './escape-like.js';
7
7
  export { defineFilter, FilterDefinitionError, specToFilterConfig, } from './filter_spec.js';
8
8
  export { filterableFieldPaths, generateFilterClient, generateFilterClients, sortableFieldPaths, } from './generate_client.js';
9
9
  export { applyCursorFromRequest, applyFilterFromRequest } from './apply_from_request.js';
10
+ export { registerFilterMacros } from './lucid_macros.js';
10
11
  export { parseFilterRequest, parseSort, toColumnFilters } from './parse_request.js';
11
12
  export { parseSpatieRequest } from './spatie_parser.js';
12
13
  export { applyCursor, applyFilter } from './runner.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAQ/B,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EACL,wBAAwB,EACxB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAW9C,OAAO,EACL,YAAY,EACZ,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAiB9B,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAMzF,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEvD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,WAAW,EACX,WAAW,EACX,SAAS,EACT,qBAAqB,GAKtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,eAAe,EACf,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,aAAa,GACd,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE7F,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAQ/B,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EACL,wBAAwB,EACxB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAW9C,OAAO,EACL,YAAY,EACZ,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAiB9B,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAMzF,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEvD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,WAAW,EACX,WAAW,EACX,SAAS,EACT,qBAAqB,GAKtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,eAAe,EACf,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,aAAa,GACd,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE7F,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,56 @@
1
+ import { type ApplyFromRequestOptions, type FilterRequestContext } from './apply_from_request.js';
2
+ import type { FilterSpec } from './filter_spec.js';
3
+ /**
4
+ * The static slice of a Lucid query-builder class we register onto: Adonis'
5
+ * `Macroable.macro(name, fn)` adds `fn` to the builder prototype so every query
6
+ * instance gains the method. Declared structurally so this module never
7
+ * hard-imports `@adonisjs/lucid` at runtime (the provider passes the real
8
+ * `ModelQueryBuilder` in) — matching how the rest of the package stays
9
+ * framework-free.
10
+ */
11
+ export interface MacroableQueryBuilder {
12
+ macro(name: string, fn: (this: unknown, ...args: never[]) => unknown): void;
13
+ }
14
+ /**
15
+ * Register the chainable filter macros onto a Lucid query-builder class (the
16
+ * method-call form of {@link applyFilterFromRequest}). Call this from a provider's
17
+ * `boot()` with `ModelQueryBuilder` (from `@adonisjs/lucid/orm`); the
18
+ * `@adonis-agora/filter` provider does exactly that.
19
+ *
20
+ * Two macros are added:
21
+ *
22
+ * - `query.applyFilterFromRequest(spec, ctx, options?)` — applies the spec's
23
+ * server scope + allow-listed filter/sort/search and returns the query so it
24
+ * chains (`User.query().applyFilterFromRequest(spec, ctx).orderBy(...)`). The
25
+ * resolved pagination is dropped; use `filterPaginate` (or the free function)
26
+ * when you need it.
27
+ * - `query.filterPaginate(spec, ctx, options?)` — applies the same and then
28
+ * `paginate(page, size)` with the resolved pagination, returning Lucid's
29
+ * paginator (`await User.query().filterPaginate(spec, ctx)`).
30
+ *
31
+ * Idempotent enough to call once at boot; calling twice re-defines the macros to
32
+ * the same implementations.
33
+ */
34
+ export declare function registerFilterMacros(ModelQueryBuilder: MacroableQueryBuilder): void;
35
+ declare module '@adonisjs/lucid/types/model' {
36
+ interface ModelQueryBuilderContract<Model extends LucidModel, Result = InstanceType<Model>> {
37
+ /**
38
+ * Apply a {@link FilterSpec} from the request context (server scope +
39
+ * allow-listed filter/sort/search) and return the query for chaining — the
40
+ * method form of the free `applyFilterFromRequest`. Pagination is resolved
41
+ * but not returned here; use {@link filterPaginate} when you need it.
42
+ *
43
+ * `ctx` is optional: when omitted, the active `HttpContext` is read from
44
+ * AsyncLocalStorage (`HttpContext.getOrFail()`). Pass it explicitly outside a
45
+ * request scope (e.g. a job/command), where there is no ambient context.
46
+ */
47
+ applyFilterFromRequest(spec: FilterSpec, ctx?: FilterRequestContext, options?: ApplyFromRequestOptions): this;
48
+ /**
49
+ * Apply a {@link FilterSpec} from the request context and paginate with the
50
+ * resolved `{ page, size }`, returning Lucid's paginator — filter + paginate
51
+ * in one terminal call. `ctx` is optional (see {@link applyFilterFromRequest}).
52
+ */
53
+ filterPaginate(spec: FilterSpec, ctx?: FilterRequestContext, options?: ApplyFromRequestOptions): ReturnType<this['paginate']>;
54
+ }
55
+ }
56
+ //# sourceMappingURL=lucid_macros.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lucid_macros.d.ts","sourceRoot":"","sources":["../../src/lucid_macros.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EAE1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAanD;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,GAAG,IAAI,CAAC;CAC7E;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,CAAC,iBAAiB,EAAE,qBAAqB,GAAG,IAAI,CAoBnF;AAED,OAAO,QAAQ,6BAA6B,CAAC;IAC3C,UAAU,yBAAyB,CAAC,KAAK,SAAS,UAAU,EAAE,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC;QACxF;;;;;;;;;WASG;QACH,sBAAsB,CACpB,IAAI,EAAE,UAAU,EAChB,GAAG,CAAC,EAAE,oBAAoB,EAC1B,OAAO,CAAC,EAAE,uBAAuB,GAChC,IAAI,CAAC;QACR;;;;WAIG;QACH,cAAc,CACZ,IAAI,EAAE,UAAU,EAChB,GAAG,CAAC,EAAE,oBAAoB,EAC1B,OAAO,CAAC,EAAE,uBAAuB,GAChC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;KACjC;CACF"}
@@ -0,0 +1,42 @@
1
+ import { HttpContext } from '@adonisjs/core/http';
2
+ import { applyFilterFromRequest, } from './apply_from_request.js';
3
+ /**
4
+ * O ctx da request para o macro: explícito, ou o `HttpContext` ativo lido do AsyncLocalStorage do
5
+ * Adonis quando omitido. `getOrFail()` lança quando não há request em escopo (ex.: chamada dentro de
6
+ * um job/command) — nesse caso passe o ctx explicitamente. Fica no macro (camada Adonis); o
7
+ * `applyFilterFromRequest` livre continua framework-agnostic, exigindo o ctx.
8
+ */
9
+ function resolveCtx(ctx) {
10
+ return ctx ?? HttpContext.getOrFail();
11
+ }
12
+ /**
13
+ * Register the chainable filter macros onto a Lucid query-builder class (the
14
+ * method-call form of {@link applyFilterFromRequest}). Call this from a provider's
15
+ * `boot()` with `ModelQueryBuilder` (from `@adonisjs/lucid/orm`); the
16
+ * `@adonis-agora/filter` provider does exactly that.
17
+ *
18
+ * Two macros are added:
19
+ *
20
+ * - `query.applyFilterFromRequest(spec, ctx, options?)` — applies the spec's
21
+ * server scope + allow-listed filter/sort/search and returns the query so it
22
+ * chains (`User.query().applyFilterFromRequest(spec, ctx).orderBy(...)`). The
23
+ * resolved pagination is dropped; use `filterPaginate` (or the free function)
24
+ * when you need it.
25
+ * - `query.filterPaginate(spec, ctx, options?)` — applies the same and then
26
+ * `paginate(page, size)` with the resolved pagination, returning Lucid's
27
+ * paginator (`await User.query().filterPaginate(spec, ctx)`).
28
+ *
29
+ * Idempotent enough to call once at boot; calling twice re-defines the macros to
30
+ * the same implementations.
31
+ */
32
+ export function registerFilterMacros(ModelQueryBuilder) {
33
+ ModelQueryBuilder.macro('applyFilterFromRequest', function (spec, ctx, options) {
34
+ applyFilterFromRequest(this, spec, resolveCtx(ctx), options);
35
+ return this;
36
+ });
37
+ ModelQueryBuilder.macro('filterPaginate', function (spec, ctx, options) {
38
+ const { page, size } = applyFilterFromRequest(this, spec, resolveCtx(ctx), options);
39
+ return this.paginate(page, size);
40
+ });
41
+ }
42
+ //# sourceMappingURL=lucid_macros.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lucid_macros.js","sourceRoot":"","sources":["../../src/lucid_macros.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,OAAO,EAGL,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AAIjC;;;;;GAKG;AACH,SAAS,UAAU,CAAC,GAAqC;IACvD,OAAO,GAAG,IAAI,WAAW,CAAC,SAAS,EAAE,CAAC;AACxC,CAAC;AAcD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,oBAAoB,CAAC,iBAAwC;IAC3E,iBAAiB,CAAC,KAAK,CAAC,wBAAwB,EAAE,UAEhD,IAAgB,EAChB,GAA0B,EAC1B,OAAiC;QAEjC,sBAAsB,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;QAC7D,OAAO,IAAI,CAAC;IACd,CAAiD,CAAC,CAAC;IAEnD,iBAAiB,CAAC,KAAK,CAAC,gBAAgB,EAAE,UAExC,IAAgB,EAChB,GAA0B,EAC1B,OAAiC;QAEjC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,sBAAsB,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;QACpF,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACnC,CAAiD,CAAC,CAAC;AACrD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adonis-agora/filter",
3
- "version": "0.3.1",
3
+ "version": "0.5.0",
4
4
  "description": "Server-side query filtering/sorting/pagination for AdonisJS — Spatie-style input, a Lucid adapter, and field allow-listing. Part of the Agora ecosystem.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -27,6 +27,11 @@
27
27
  "types": "./dist/commands/main.d.ts",
28
28
  "import": "./dist/commands/main.js",
29
29
  "default": "./dist/commands/main.js"
30
+ },
31
+ "./filter_provider": {
32
+ "types": "./dist/providers/filter_provider.d.ts",
33
+ "import": "./dist/providers/filter_provider.js",
34
+ "default": "./dist/providers/filter_provider.js"
30
35
  }
31
36
  },
32
37
  "files": [
@@ -36,11 +41,15 @@
36
41
  ],
37
42
  "sideEffects": false,
38
43
  "peerDependencies": {
39
- "@adonisjs/core": "^7.3.0"
44
+ "@adonisjs/core": "^7.3.0",
45
+ "@adonisjs/lucid": "^22.0.0"
40
46
  },
41
47
  "peerDependenciesMeta": {
42
48
  "@adonisjs/core": {
43
49
  "optional": true
50
+ },
51
+ "@adonisjs/lucid": {
52
+ "optional": true
44
53
  }
45
54
  },
46
55
  "devDependencies": {