@dudousxd/nestjs-filter 1.24.0 → 1.28.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 +155 -0
- package/README.md +2 -1
- package/dist/adapter/adapter.d.ts +74 -0
- package/dist/adapter/adapter.d.ts.map +1 -1
- package/dist/decorator/filterable.decorator.d.ts.map +1 -1
- package/dist/decorator/filterable.decorator.js +1 -0
- package/dist/decorator/filterable.decorator.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/interceptor/apply-filter.interceptor.d.ts.map +1 -1
- package/dist/interceptor/apply-filter.interceptor.js +6 -1
- package/dist/interceptor/apply-filter.interceptor.js.map +1 -1
- package/dist/runner.d.ts +381 -4
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +768 -54
- package/dist/runner.js.map +1 -1
- package/dist/types.d.ts +147 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/skills/filter-safety/SKILL.md +20 -4
- package/skills/structured-querying/SKILL.md +14 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,160 @@
|
|
|
1
1
|
# @dudousxd/nestjs-filter
|
|
2
2
|
|
|
3
|
+
## 1.28.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#100](https://github.com/DavideCarvalho/nestjs-filter/pull/100) [`ca9bdd9`](https://github.com/DavideCarvalho/nestjs-filter/commit/ca9bdd98b14cabecc36edc06f767e6654a6d8357) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - `where[]` columns are now checked against the entity, not just against the alphabet.
|
|
8
|
+
|
|
9
|
+
A `where[]` clause passed exactly two gates before it reached the ORM: the field-path grammar (`isValidFieldPath` — letters, digits, `_`, `.`, `[]`) and the operator allowlist. Neither asks whether the field is a column. So `{ field: "ghostColumn", operator: "equals", value: 1 }` is well-formed, sails through both, and fails inside the ORM. The consumer gets a 500 for what is a malformed request, and a background job filtering on a column that table does not have dies mid-run instead of at the boundary.
|
|
10
|
+
|
|
11
|
+
The library already knew the answer. `adapter.getEntityFields(entity)` is what `resolveAutoFields` uses to restrict the STRUCTURED filter keys to real columns, and `applyDynamic` already ran `pruneUnknownColumnFilters` over `where[]` for exactly this reason. Only the static (`@Filterable`) path was never wired to it — so the same unknown column was handled politely through one door and crashed through the other, on the same entity, in the same request.
|
|
12
|
+
|
|
13
|
+
Now both doors behave the same. Every `where[]` clause is resolved against the entity's real columns and relations (via `resolveFieldPath` when the adapter has it, else the path's root segment), recursing into AND/OR groups.
|
|
14
|
+
|
|
15
|
+
**The knob is `throwOnInvalid`, not `onUnknownKey`.** `FilterModuleOptions.throwOnInvalid` was already documented as covering "unknown `where` columns" — the static path simply never honoured it — and `applyDynamic` already routed this same check through it. Choosing the other knob would have recreated, one layer down, the static-vs-dynamic asymmetry this release closes. It is also overridable per-`@Filterable`, which matters here: whether a stray `where` column is a client bug or a tolerated legacy payload is an endpoint's judgement, not an application's. `onUnknownKey` keeps its own scope, which is the structured `filter` object — those keys are dispatch targets (`@FilterFor` / auto-field / relation / computed / aggregate), not column references, and they raise `UnknownFilterKeyException` rather than naming a column.
|
|
16
|
+
|
|
17
|
+
The default (`throwOnInvalid: false`) drops the clause and logs a warning naming the field. Dropping is what stops the crash without turning requests that work today into 400s, and it matches what `pruneBlacklistedColumnFilters` already does for the same tree; the warning is there because a dropped constraint is otherwise invisible, and an invisible dropped constraint is how you end up trusting a wider result set than you asked for. Set `throwOnInvalid: true` to get a `BadRequestException` naming the column instead.
|
|
18
|
+
|
|
19
|
+
Three things deliberately do NOT change:
|
|
20
|
+
|
|
21
|
+
- **A clause whose own field is unknown but which carries a surviving AND/OR group keeps the group.** Only the leaf goes. Dropping the whole clause would take its children's constraints with it and WIDEN the query — returning rows the client filtered out is a worse failure than the 500 this replaces.
|
|
22
|
+
- **Paths that were never plain columns still work.** Computed aliases and to-many aggregate paths (`posts.$max.publishedAt`) are peeled off by `splitSpecialColumnFilters` before this check and routed to `applyComputedField`/`applyAggregateField`, which have their own validation. Dotted relation paths (`base.name`) and JSON sub-paths (`metadata.tier`) resolve normally — and on an adapter without `resolveFieldPath`, a dotted path rooted at a scalar column is accepted rather than dropped, because such an adapter cannot tell a JSON column from any other and "we can't check this" must not become "this is wrong".
|
|
23
|
+
- **A malformed path is passed through, not swallowed.** Anything outside the SQL-safe grammar (`visits.$notafn`) still reaches `validateColumnFilters` and is still rejected loudly. This check answers "does this column exist", never "is this path legal" — quietly dropping SQL-unsafe input would trade a hard error for silence.
|
|
24
|
+
|
|
25
|
+
When the adapter implements no `getEntityFields` (or it returns nothing), the check falls back to accepting everything and warns — the same graceful degradation the auto-fields path uses, so an adapter that cannot introspect keeps its previous behaviour instead of having every `where` clause dropped.
|
|
26
|
+
|
|
27
|
+
Minor rather than patch: no API is added, but the queries the library emits for existing callers change. A `where[]` clause on a non-column that used to reach the database now does not, and under `throwOnInvalid: true` a request that used to 500 now 400s. Both are the point of the release, and both are worth a deliberate upgrade rather than arriving in a patch.
|
|
28
|
+
|
|
29
|
+
## 1.27.0
|
|
30
|
+
|
|
31
|
+
### Minor Changes
|
|
32
|
+
|
|
33
|
+
- [#99](https://github.com/DavideCarvalho/nestjs-filter/pull/99) [`28db30a`](https://github.com/DavideCarvalho/nestjs-filter/commit/28db30a4adf21c68d8e8912bcda026292d070b2e) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Let a trusted server-side call opt out of `maxPageSize`.
|
|
34
|
+
|
|
35
|
+
`maxPageSize` is configured once, on the module, and then has to answer two questions that want different answers. For a `size` that arrived on an HTTP request the cap is the whole point — it is what stops a client asking for a million rows. For a `size` the server itself wrote, it is not protection but a silent wrong answer: an export asks for 10 000 rows, is handed 100, reads `100 < 10 000` as "the table is exhausted", and writes a truncated CSV with nothing logged and nothing thrown. The runner cannot tell the two apart by looking at the number, so the only consumer that could opt out — trusted code — was the one that could not.
|
|
36
|
+
|
|
37
|
+
`findAndCount(entity, input, { trustedPageSize: true })` is the escape hatch, with the same option on `findPage` (lifting the cap off `first`/`last`) and on `applyDynamic`'s per-call `internal` bag for callers that build the query themselves. Nothing changes when it is not passed: the global cap still applies everywhere, which is the behaviour every existing call keeps.
|
|
38
|
+
|
|
39
|
+
It is a boolean, not a numeric per-call `maxPageSize`, because a number does not solve the problem it looks like it solves. The caller would have to invent a second ceiling that must be at least as large as the size it is already passing, and guessing it low reproduces the exact silent truncation the option exists to remove — one call site, two numbers that must agree, no error when they don't. The fact the call site actually holds is not a better ceiling; it is _this size did not come from a client_, which is one bit. `trustedPageSize: true` also reads as what it is at a glance, where `maxPageSize: 10_000` sitting in an options object reads like ordinary config and could as easily be tightening the cap as lifting it.
|
|
40
|
+
|
|
41
|
+
Deliberately absent from `apply()`: that is the filter-class path `@ApplyFilter` drives, where the input is the HTTP request by definition, and a trust flag travelling next to route-bound client input is the confusion this is trying to prevent. The minimum page size of 1 still applies to trusted calls — that one is a correctness floor (`LIMIT 0` is not a page), not a safety cap.
|
|
42
|
+
|
|
43
|
+
### Patch Changes
|
|
44
|
+
|
|
45
|
+
- [#98](https://github.com/DavideCarvalho/nestjs-filter/pull/98) [`272fc75`](https://github.com/DavideCarvalho/nestjs-filter/commit/272fc75e8de5cbadf34495256672963f19df9051) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Accept a `string[]` sort, which used to be dropped without a word.
|
|
46
|
+
|
|
47
|
+
`parseSorts` read two shapes: the comma-joined string `"-createdAt,name"`, and an array of `SortItem` objects. An array of plain strings — `["-createdAt", "name"]` — matched neither. It reached the array branch, failed the `typeof item === 'object'` test every element was measured against, and was filtered away.
|
|
48
|
+
|
|
49
|
+
Nothing said so. No throw, no warning, not even a 400 with `throwOnInvalid` on: the request was well-formed, the parse produced an empty list, and an empty list is exactly what "the client sent no sort" looks like. So the query fell through to `defaultSort` or to no ORDER BY at all, and the only symptom was a grid that had quietly stopped sorting.
|
|
50
|
+
|
|
51
|
+
That shape is not exotic. `["-year", "nsn"]` is the array spelling of the JSON:API convention this parser already implements, and it is what a legacy `orderBy: string[]` hands over verbatim.
|
|
52
|
+
|
|
53
|
+
Each element is now read by its own type: a string goes through the same token rules as the comma form (leading `-` means desc, trimmed, blanks dropped), an object is validated as a `SortItem` as before. Mixed arrays work for the same reason — `["-a", { field: 'b', direction: 'asc' }]` parses.
|
|
54
|
+
|
|
55
|
+
Purely additive. A `string[]` produced nothing before, so no existing behaviour depended on the old result; the string and `SortItem[]` shapes are untouched, and an element that is neither is still discarded.
|
|
56
|
+
|
|
57
|
+
## 1.25.0
|
|
58
|
+
|
|
59
|
+
### Minor Changes
|
|
60
|
+
|
|
61
|
+
- [#91](https://github.com/DavideCarvalho/nestjs-filter/pull/91) [`7c64f10`](https://github.com/DavideCarvalho/nestjs-filter/commit/7c64f105a127a3a24a5c22230437630e0ca51592) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Add `fieldExtent`, an adapter capability that answers the `MIN`/`MAX` of one or more fields over whatever the active filter selected.
|
|
62
|
+
|
|
63
|
+
A range control cannot place its endpoints without this. The shape callers reach for instead is two `ORDER BY <field> LIMIT 1` reads per field — ascending, then descending — which is two round trips, two filesorts over the filtered set when the column is unindexed, and, on a builder carrying a projected computed alias, two extra `COUNT`s nobody reads.
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
const extent = await adapter.fieldExtent?.(
|
|
67
|
+
qb,
|
|
68
|
+
["price", "createdAt"],
|
|
69
|
+
Product
|
|
70
|
+
);
|
|
71
|
+
// → { price: { min: 499, max: 128000 }, createdAt: { min: Date, max: Date } }
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**One query, however many fields.** `MIN`/`MAX` skip nulls per aggregate, so each field's pair is independent and they all share a single select list. That independence is exactly what the sort-and-limit approach cannot have: each field would need its own `IS NOT NULL` and its own ordering, so N fields is 2N queries there and one here.
|
|
75
|
+
|
|
76
|
+
Numbers and dates both work, and neither is coerced on the way out — a range control over dates needs real dates, and stringifying here would push parsing onto every caller. Plain columns, JSON sub-paths and computed members all resolve through the same paths the rest of the adapter uses.
|
|
77
|
+
|
|
78
|
+
Two states a caller has to tell apart, and which are deliberately not collapsed: a field present with `null` ends means no row in scope carries a value; a field **absent** from the result means this adapter could not turn it into an expression, so it measured nothing rather than guessing.
|
|
79
|
+
|
|
80
|
+
`fieldExtent` is optional on the `FilterAdapter` contract, so an adapter without aggregation support is unaffected and nothing about upgrading changes an existing query.
|
|
81
|
+
|
|
82
|
+
Deliberately only the extent, not a general `stats`. `MIN`/`MAX` are indifferent to the row multiplication a to-many join causes; an average or a sum would not be. Naming this `fieldStats` would have invited exactly that addition, and it would ship wrong numbers on any filter that joins a to-many without a single test going red.
|
|
83
|
+
|
|
84
|
+
- [#91](https://github.com/DavideCarvalho/nestjs-filter/pull/91) [`7c64f10`](https://github.com/DavideCarvalho/nestjs-filter/commit/7c64f105a127a3a24a5c22230437630e0ca51592) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Add `extent` as a structured input key, answered by `FilterRunner.fieldExtent(entity, input, opts)` — the `MIN`/`MAX` of the requested fields over whatever the active `where`/`search` selected.
|
|
85
|
+
|
|
86
|
+
The adapter capability already existed; nothing server-side read the key, so a route had to take `@Body('extent')` and call the adapter itself. That bypasses the filter class's field governance. A filter can narrow which columns it exposes — `static distinct`, the entity-metadata check that rejects a bare relation or an unknown identifier, `@Filterable.aliases` — and a name read off the body and handed straight to `fieldExtent` skips all of it, so a caller could measure a column the class deliberately does not expose. It was never an injection vector (the adapter resolves names through ORM metadata and quotes defensively), but it is a surface leak, and the runner is the only layer holding the allowlist that closes it.
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
// route
|
|
90
|
+
const [{ rows, total }, extent] = await Promise.all([
|
|
91
|
+
runner.findAndCount(Product, input),
|
|
92
|
+
runner.fieldExtent(Product, input, { filterClass: ProductFilter }),
|
|
93
|
+
]);
|
|
94
|
+
// → { price: { min: 499, max: 128000 }, createdAt: { min: Date, max: Date } }
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Fields go through the same validation `distinct` does, with the same allowlist: the filter class's `static distinct` when `opts.filterClass` declares one, else the entity's columns via adapter metadata. `distinct` and `extent` ask the same question about a column — what values may this control offer — so a class that already narrowed which columns a control may read narrows this too. Otherwise `extent` is the way around that narrowing.
|
|
98
|
+
|
|
99
|
+
**A disallowed or unknown field is dropped and the rest still answer**, matching `distinct` rather than `groupByCount`. The difference is which one the field is: in `groupByCount` the field IS the query, so an unknown one has to reject; here the surviving fields are a usable answer, and a range control that loses one endpoint is better than a request that 400s. Under `throwOnInvalid` the drop becomes a `BadRequestException` naming `extent`, again as `distinct`. A dropped field is simply absent from the result — which the `fieldExtent` contract already defines as "not measured", so the caller needs no new state to handle.
|
|
100
|
+
|
|
101
|
+
Computed members route as `{ alias, source }` rather than a bare name, exactly as `groupByCount`'s grouping field does: the adapter measures the dev-provided expression instead of resolving a column no table has. This is the other half of why it belongs in the runner — nothing outside it can tell a computed alias from a typo, since both are strings no column matches, and one must reach the adapter while the other must not.
|
|
102
|
+
|
|
103
|
+
Not terminal, unlike `groupByCount`: the extent describes the same rows the page comes from, so sort and pagination are untouched (`fieldExtent` applies WHERE/search only) and a route can answer with rows and extent from the same input. Variadic all the way down — the capability measures N fields in one query, so the runner hands the adapter one list rather than looping, which is the property `extent` exists for.
|
|
104
|
+
|
|
105
|
+
Requires an adapter implementing the optional `fieldExtent`; without it the call throws rather than returning `{}`, because an empty answer is indistinguishable from a legitimately empty set and draws a range control collapsed to a `(0, 0)` span with no error anywhere.
|
|
106
|
+
|
|
107
|
+
- [#91](https://github.com/DavideCarvalho/nestjs-filter/pull/91) [`7c64f10`](https://github.com/DavideCarvalho/nestjs-filter/commit/7c64f105a127a3a24a5c22230437630e0ca51592) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Add `distinctOrder`, an opt-in that orders a `distinct` request carrying no `sort` of its own ascending by the columns it projected.
|
|
108
|
+
|
|
109
|
+
`SELECT DISTINCT` has no inherent order. That is cosmetic for a full list and a correctness bug for a paged one — the shape a filter dropdown uses: `LIMIT`/`OFFSET` over an unordered query is not a partition, so one page can repeat a value another page already returned and skip a third entirely.
|
|
110
|
+
|
|
111
|
+
Off by default, so upgrading changes no query. Turn it on per filter class or for the whole app:
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
@Filterable({ entity: User, distinctOrder: true })
|
|
115
|
+
export class UserFilter extends MikroOrmFilter<User> {}
|
|
116
|
+
|
|
117
|
+
// or once, covering every filter including hand-written ones:
|
|
118
|
+
FilterModule.forRoot({ distinctOrder: true });
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The ordering is derived from what the projection actually kept, not from what the request named, so it is always a legal `SELECT DISTINCT` — a field that validation or an allowlist dropped stays out of the `ORDER BY` too. That matters more than it sounds: MySQL rejects an `ORDER BY` term outside a DISTINCT's select list outright (error 3065, a failed query rather than a warning). Computed aliases and to-many aggregates route through the same computed-aware sort path a client-sent sort takes, so they order by the projected expression rather than by a name no column has.
|
|
122
|
+
|
|
123
|
+
A client-sent `sort` and `defaultSort` both take precedence, and the derived ordering never throws: a projected column outside a narrowed `static sort` allowlist drops out of the `ORDER BY` instead of turning an otherwise valid request into a 400.
|
|
124
|
+
|
|
125
|
+
- [#91](https://github.com/DavideCarvalho/nestjs-filter/pull/91) [`7c64f10`](https://github.com/DavideCarvalho/nestjs-filter/commit/7c64f105a127a3a24a5c22230437630e0ca51592) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Add `histogram` as a structured input key, answered by `FilterRunner.fieldHistogram(entity, input, opts)` — one numeric field's extent AND its bucketed distribution over the same filtered set, from one request.
|
|
126
|
+
|
|
127
|
+
Both halves already shipped and neither is usable alone. `fieldExtent` places a range control's endpoints; `groupByCount`'s bucketed variant draws the bars behind them — but that variant takes a bucket **width**, and a width that is not derived from the data is either arbitrary (a hardcoded `1000` that yields two bars under one filter and four hundred under the next) or requires the extent the caller is asking for in the same breath. That circle cannot be broken from outside: you must measure, then divide. So the runner measures, then divides.
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
await runner.fieldHistogram(Product, {
|
|
131
|
+
filter,
|
|
132
|
+
histogram: { field: "price", buckets: 10 },
|
|
133
|
+
});
|
|
134
|
+
// → { min: 499, max: 128000, bucketWidth: 10000,
|
|
135
|
+
// buckets: [{ bucketStart: 0, bucketEnd: 10000, count: 12 }, …] }
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Two round trips, and it cannot be one.** The width is a function of the first query's _output_, so the second query's text does not exist until the first returns. Folding them into one statement means a correlated `(SELECT MAX(col)) - (SELECT MIN(col))` inside the bucket expression — the same scan again, per row-group, to save a round trip — or window functions the adapter contract does not have. Two plain aggregates over an indexable column is cheaper and keeps this a composition.
|
|
139
|
+
|
|
140
|
+
**Nothing was added to `FilterAdapter`.** Every optional method on that contract is a cost each adapter author pays forever, and this one would buy nothing: it is arithmetic between two existing calls, identical for every ORM. An adapter with both capabilities gets this for free; one missing a half is told _which_ half, since "histogram is unsupported" would send its author looking for a method by that name.
|
|
141
|
+
|
|
142
|
+
**The width is snapped to a 1/2/5 × 10ⁿ step**, nearest rather than upward. Raw `span / count` is arithmetically right and wrong for a control, twice over: buckets are anchored at multiples of the width (`FLOOR(col / w) * w`), so 499–128000 over 10 gives 12750.1 and an axis labelled 12750.1, 25500.2, 38250.3; and a raw width changes on every row inserted, so the bars re-partition and visibly jump as the filtered set shifts. Snapping to the nearest step keeps the count within about √2 of the request in either direction — `buckets` is a target, `bucketWidth` is authoritative. Rounding _up_ instead would turn a span of 101 over 10 into a width of 20 and six bars, a worse answer to "ten, please" than eleven.
|
|
143
|
+
|
|
144
|
+
**The degenerate sets are the point, not the edge case** — a facet is drawn over whatever the filter left behind, so one row and no rows are ordinary states, and each fails quietly on its own terms:
|
|
145
|
+
|
|
146
|
+
- **No rows, or a column null throughout them** → `{ min: null, max: null, bucketWidth: null, buckets: [] }` and _no second query_. A width from null is `NaN`, and `FLOOR(col / NaN)` groups the whole table into one null bucket: a query that succeeds and means nothing. Null ends are deliberately not collapsed into "zero bars", so an empty facet is distinguishable from a flat one.
|
|
147
|
+
- **`min === max`** (one row, or many sharing a value) → width 0, which is a null group on MySQL and a division-by-zero _error_ on Postgres. The bucketed variant is not asked for at all; the plain group-by answers, and the single bucket is reported as the point `[min, min]` rather than given a fabricated span that would draw a bar over values no row has.
|
|
148
|
+
- **A field the adapter measured nothing for** → throws. An _absent_ key means "could not be compiled" per the `fieldExtent` contract, not the `{ min: null }` the same contract defines as "no row carries a value"; reporting the first as the second renders an unmeasurable column as a legitimately empty facet.
|
|
149
|
+
|
|
150
|
+
**Dates are refused, not bucketed.** `fieldExtent` supports DATE columns on purpose, so `extent` and `histogram` accept the same field names right up to this point — and the failure without a check is not an error but a wrong answer: MySQL coerces a date to `20240131` and buckets _that_, returning plausible bars over an axis where two thirds of every year does not exist. Root-column metadata refuses one before either query runs; a computed source, relation path or JSON sub-path — which metadata cannot type — is caught on the way back, by identity rather than by coercion, since `Number(new Date())` is a perfectly finite epoch. For the same reason the numeric check is not `typeof value === 'number'` in the other direction either: DECIMAL hydrates to a _string_ on mysql2 and pg, and a strict check would refuse the most ordinary histogram there is.
|
|
151
|
+
|
|
152
|
+
Buckets come back contiguous and ascending with empty ones filled in. `GROUP BY` has no defined output order and emits nothing at all for an empty bucket, so the raw groups render as evenly spaced bars that lie about where the data sits. Rows are matched to buckets by index, not by comparing the returned edge — for a width of 0.1 the database's `FLOOR(x / 0.1) * 0.1` and JavaScript's `i * 0.1` differ in the last bits, and an equality match would silently zero exactly the buckets that have rows. The null group is dropped rather than passed through, since `Number(null)` is 0 and every null row would otherwise pile into a phantom bar at the origin.
|
|
153
|
+
|
|
154
|
+
Field governance is `extent`'s, through the same path: alias remapping, the filter class's static `distinct` allowlist (else entity metadata), and computed members routed to _both_ passes as `{ alias, source }` — nothing outside the runner can tell a computed alias from a typo, since both are strings no column matches. The one divergence is what an invalid field means: rejected here, as in `groupByCount`, because the field IS the query and an empty histogram would read as "no matching rows", the answer to an entirely different question.
|
|
155
|
+
|
|
156
|
+
Single-field, unlike `extent` — the width derivation is per field and the second query groups by one expression, so N fields is genuinely N of these and batching would only hide it. Not terminal, like `extent` and unlike `groupByCount`: it describes the same rows the page comes from, so sort and pagination are untouched and a route may answer with both. And it takes no `opts.qb`: two passes need two builders (the first is consumed by an aggregate `SELECT`), and quietly creating the second from scratch would drop whatever pre-scoping a caller put on theirs, so the distribution would describe a wider set than the extent — a chart with bars outside its own axis, with nothing to make it obvious.
|
|
157
|
+
|
|
3
158
|
## 1.24.0
|
|
4
159
|
|
|
5
160
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -102,7 +102,8 @@ class UsersController {
|
|
|
102
102
|
|--------|------|---------|-------------|
|
|
103
103
|
| `inputNormalizer` | `'camelCase' \| 'snakeCase' \| fn` | `'camelCase'` | Normalize input keys. |
|
|
104
104
|
| `dropId` | `boolean` | _set explicitly_ | Strip trailing `Id`/`_id`. Effective default is currently inconsistent in the code — when run through `FilterRunner`/`@ApplyFilter` the suffix is stripped unless you pass `dropId: false`. |
|
|
105
|
-
| `onUnknownKey` | `'ignore' \| 'warn' \| 'throw'` | `'ignore'` | Policy for unrecognized keys. |
|
|
105
|
+
| `onUnknownKey` | `'ignore' \| 'warn' \| 'throw'` | `'ignore'` | Policy for unrecognized **structured `filter` keys** (no `@FilterFor`, auto-field, relation, computed field or aggregate path). Unknown columns inside a `where[]` clause are governed by `throwOnInvalid` instead. |
|
|
106
|
+
| `throwOnInvalid` | `boolean` | `false` | When `true`, invalid sorts, distinct fields, and unknown `where[]` columns raise a `BadRequestException` instead of being dropped with a warning. Overridable per `@Filterable`. |
|
|
106
107
|
| `validation` | `'auto' \| 'off'` | `'auto'` | Validate with class-validator if installed. |
|
|
107
108
|
|
|
108
109
|
See the [root README](../../README.md) for full documentation.
|
|
@@ -43,6 +43,31 @@ export type GroupByCountField = string | {
|
|
|
43
43
|
alias: string;
|
|
44
44
|
source: ComputedSource;
|
|
45
45
|
};
|
|
46
|
+
/**
|
|
47
|
+
* One field to measure with {@link FilterAdapter.fieldExtent}. Same two shapes as
|
|
48
|
+
* {@link GroupByCountField}: a validated column/path, or the `{ alias, source }`
|
|
49
|
+
* pair of a computed member — whose source is dev-provided, never client input.
|
|
50
|
+
*/
|
|
51
|
+
export type FieldExtentField = string | {
|
|
52
|
+
alias: string;
|
|
53
|
+
source: ComputedSource;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* The extent of one field over the filtered set.
|
|
57
|
+
*
|
|
58
|
+
* `null` means no row in scope carries a value — deliberately distinct from a
|
|
59
|
+
* field whose values legitimately start at zero, which a caller sizing a range
|
|
60
|
+
* control has to tell apart.
|
|
61
|
+
*
|
|
62
|
+
* Values keep their column's type rather than being coerced: a `DATE` column
|
|
63
|
+
* yields whatever the driver hydrates dates to, a numeric one a number. That is
|
|
64
|
+
* the point of measuring server-side — a range control over dates needs real
|
|
65
|
+
* dates, and stringifying here would push parsing onto every caller.
|
|
66
|
+
*/
|
|
67
|
+
export interface FieldExtent {
|
|
68
|
+
min: unknown;
|
|
69
|
+
max: unknown;
|
|
70
|
+
}
|
|
46
71
|
/**
|
|
47
72
|
* Behavior flags for full-text vector search ({@link FilterAdapter.applyVectorSearch}).
|
|
48
73
|
*/
|
|
@@ -295,6 +320,55 @@ export interface FilterAdapter {
|
|
|
295
320
|
value: unknown;
|
|
296
321
|
count: number;
|
|
297
322
|
}>>;
|
|
323
|
+
/**
|
|
324
|
+
* The extent — `MIN` and `MAX` — of one or more fields over the rows the
|
|
325
|
+
* active WHERE / search already select. One query for every field asked for:
|
|
326
|
+
* with no `GROUP BY`, all the aggregate pairs fit in a single SELECT list.
|
|
327
|
+
*
|
|
328
|
+
* This exists because a range control cannot size itself without it. The
|
|
329
|
+
* alternative callers reach for is two `ORDER BY … LIMIT 1` reads per field,
|
|
330
|
+
* which is two round trips, two filesorts over the filtered set when the
|
|
331
|
+
* column is unindexed, and — on a builder carrying a projected computed alias
|
|
332
|
+
* — two extra `COUNT`s nobody reads. `MIN`/`MAX` is one pass and can use an
|
|
333
|
+
* index.
|
|
334
|
+
*
|
|
335
|
+
* Both value types matter and both are preserved: a numeric column sizes a
|
|
336
|
+
* slider, a `DATE` column sizes a calendar's selectable span. Nothing is
|
|
337
|
+
* coerced to string on the way out; see {@link FieldExtent}.
|
|
338
|
+
*
|
|
339
|
+
* Implementations must:
|
|
340
|
+
*
|
|
341
|
+
* - clear any `ORDER BY`, `LIMIT` and `OFFSET` the runner applied before
|
|
342
|
+
* aggregating. An `ORDER BY` on a column this SELECT no longer projects is
|
|
343
|
+
* MySQL error 3065 — a failed query, not a warning;
|
|
344
|
+
* - resolve each field through the SAME path the rest of the adapter uses
|
|
345
|
+
* (plain column, computed source, and whatever else it can project), since
|
|
346
|
+
* a caller may bound any field the filter accepts.
|
|
347
|
+
*
|
|
348
|
+
* Nulls need no handling: `MIN`/`MAX` skip them per aggregate, so a column
|
|
349
|
+
* that is null for half the rows still reports the extent of the other half.
|
|
350
|
+
* That is also what lets ONE query answer for many fields — the `ORDER BY …
|
|
351
|
+
* LIMIT 1` approach cannot, since each field would need its own `IS NOT NULL`
|
|
352
|
+
* and its own ordering, which is a query each.
|
|
353
|
+
*
|
|
354
|
+
* A to-many join multiplying rows is harmless here in a way it is not for
|
|
355
|
+
* `COUNT`/`SUM`: `MIN`/`MAX` are indifferent to duplicates. Anything added to
|
|
356
|
+
* this later that is not (an average, a sum) would NOT be.
|
|
357
|
+
*
|
|
358
|
+
* Active WHERE / search clauses are applied upstream by the caller; sort,
|
|
359
|
+
* pagination, distinct and select are not part of the question.
|
|
360
|
+
*
|
|
361
|
+
* Optional — adapters without aggregation support don't implement it, and the
|
|
362
|
+
* caller is expected to check before calling.
|
|
363
|
+
*
|
|
364
|
+
* @param qb - The query builder instance (WHERE/search already applied).
|
|
365
|
+
* @param fields - Already-validated fields, or `{ alias, source }` for computed ones.
|
|
366
|
+
* @param entity - The root entity class.
|
|
367
|
+
* @returns One entry per requested field, keyed by the field name (or the
|
|
368
|
+
* computed alias). A field the adapter cannot resolve is omitted rather
|
|
369
|
+
* than guessed at.
|
|
370
|
+
*/
|
|
371
|
+
fieldExtent?(qb: unknown, fields: FieldExtentField[], entity: Type<unknown>): Promise<Record<string, FieldExtent>>;
|
|
298
372
|
/**
|
|
299
373
|
* Restricts the query's projection to the given field(s) — JSON:API "sparse
|
|
300
374
|
* fieldsets". Unlike {@link applyDistinct}, this adds **no** `DISTINCT`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/adapter.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filterable.decorator.d.ts","sourceRoot":"","sources":["../../src/decorator/filterable.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAG1B,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErE,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"filterable.decorator.d.ts","sourceRoot":"","sources":["../../src/decorator/filterable.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAG1B,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErE,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,cAAc,CAwBrE;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAEhF"}
|
|
@@ -16,6 +16,7 @@ export function Filterable(options) {
|
|
|
16
16
|
autoFields: options.autoFields ?? true,
|
|
17
17
|
...(options.throwOnInvalid !== undefined && { throwOnInvalid: options.throwOnInvalid }),
|
|
18
18
|
...(options.defaultSort !== undefined && { defaultSort: options.defaultSort }),
|
|
19
|
+
...(options.distinctOrder !== undefined && { distinctOrder: options.distinctOrder }),
|
|
19
20
|
...(options.computed !== undefined && { computed: options.computed }),
|
|
20
21
|
...(options.aliases !== undefined && { aliases: options.aliases }),
|
|
21
22
|
// Metadata only — consumed statically (ts-morph AST) by
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filterable.decorator.js","sourceRoot":"","sources":["../../src/decorator/filterable.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAGnD,MAAM,UAAU,UAAU,CAAC,OAA0B;IACnD,OAAO,CAAC,MAAM,EAAE,EAAE;QAChB,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YAChC,MAAM,IAAI,4BAA4B,CAAC,MAAM,CAAC,IAAI,IAAI,iBAAiB,CAAC,CAAC;QAC3E,CAAC;QACD,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,kBAAkB,MAAM,CAAC,IAAI,6CAA6C,CAAC,CAAC;QAC9F,CAAC;QACD,MAAM,IAAI,GAAmB;YAC3B,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;YAClE,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;YAClE,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,IAAI;YACtC,GAAG,CAAC,OAAO,CAAC,cAAc,KAAK,SAAS,IAAI,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC;YACvF,GAAG,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC;YAC9E,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrE,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;YAClE,wDAAwD;YACxD,iEAAiE;YACjE,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;SACnE,CAAC;QACF,OAAO,CAAC,cAAc,CAAC,mBAAmB,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5D,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAc;IAClD,OAAO,OAAO,CAAC,WAAW,CAAC,mBAAmB,EAAE,MAAM,CAA+B,CAAC;AACxF,CAAC"}
|
|
1
|
+
{"version":3,"file":"filterable.decorator.js","sourceRoot":"","sources":["../../src/decorator/filterable.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAGnD,MAAM,UAAU,UAAU,CAAC,OAA0B;IACnD,OAAO,CAAC,MAAM,EAAE,EAAE;QAChB,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YAChC,MAAM,IAAI,4BAA4B,CAAC,MAAM,CAAC,IAAI,IAAI,iBAAiB,CAAC,CAAC;QAC3E,CAAC;QACD,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,kBAAkB,MAAM,CAAC,IAAI,6CAA6C,CAAC,CAAC;QAC9F,CAAC;QACD,MAAM,IAAI,GAAmB;YAC3B,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;YAClE,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;YAClE,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,IAAI;YACtC,GAAG,CAAC,OAAO,CAAC,cAAc,KAAK,SAAS,IAAI,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC;YACvF,GAAG,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC;YAC9E,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;YACpF,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrE,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;YAClE,wDAAwD;YACxD,iEAAiE;YACjE,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;SACnE,CAAC;QACF,OAAO,CAAC,cAAc,CAAC,mBAAmB,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5D,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAc;IAClD,OAAO,OAAO,CAAC,WAAW,CAAC,mBAAmB,EAAE,MAAM,CAA+B,CAAC;AACxF,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const VERSION = "0.0.0";
|
|
2
2
|
export { BaseFilter } from './base-filter.js';
|
|
3
|
-
export type { FilterAdapter, EntityFieldInfo, EntityRelationInfo, GroupByCountField, VectorSearchOptions, } from './adapter/adapter.js';
|
|
3
|
+
export type { FilterAdapter, EntityFieldInfo, EntityRelationInfo, FieldExtent, FieldExtentField, GroupByCountField, VectorSearchOptions, } from './adapter/adapter.js';
|
|
4
4
|
export { Filterable, getFilterableMetadata } from './decorator/filterable.decorator.js';
|
|
5
5
|
export { normalizeAllowed, allowedFieldNames } from './decorator/allowed.js';
|
|
6
6
|
export type { NormalizedAllowed } from './decorator/allowed.js';
|
|
@@ -22,7 +22,7 @@ export type { ComputedRegistryEntry } from './runner.js';
|
|
|
22
22
|
export { FilterModule } from './module.js';
|
|
23
23
|
export { FilterException, FilterNotRegisteredException, FilterMissingEntityException, FilterStateUnavailableException, UnknownFilterKeyException, FilterValidationException, FilterMissingAdapterException, FilterMethodException, } from './errors/exceptions.js';
|
|
24
24
|
export { FILTER_MODULE_OPTIONS, FILTER_ADAPTER, FILTERABLE_METADATA, FILTER_FOR_METADATA, FILTER_FOR_OPTS_METADATA, COMPUTED_METADATA, COMPUTED_OPTS_METADATA, FILTER_RELATIONS_METADATA, APPLY_FILTER_METADATA, APPLY_FILTER_REQ_KEY, TENANT_SCOPED_METADATA, CONTEXT_ACCESSOR, } from './tokens.js';
|
|
25
|
-
export type { AllowedFieldEntry, ApplyFilterOptions, CursorPage, CursorPagination, EntityDescription, FieldMeta, FilterableOptions, FilterContext, FilterInput, FilterInputStrict, FilterInputLoose, FilterMetadata, FilterModuleOptions, FilterModuleOptionsFactory, FilterModuleAsyncOptions, GroupByCountSpec, GroupByCountItem, GroupByCountBucket, GroupByCountResult, InputFormat, InputNormalizer, InputSource, OffsetPagination, OnUnknownKey, RelationMeta, SortItem, StructuredInput, ValidationMode, } from './types.js';
|
|
25
|
+
export type { AllowedFieldEntry, ApplyFilterOptions, CursorPage, CursorPagination, EntityDescription, FieldHistogram, FieldHistogramSpec, FieldMeta, FilterableOptions, FilterContext, FilterInput, FilterInputStrict, FilterInputLoose, FilterMetadata, FilterModuleOptions, FilterModuleOptionsFactory, FilterModuleAsyncOptions, GroupByCountSpec, GroupByCountItem, GroupByCountBucket, GroupByCountResult, InputFormat, InputNormalizer, InputSource, OffsetPagination, OnUnknownKey, RelationMeta, SortItem, StructuredInput, ValidationMode, } from './types.js';
|
|
26
26
|
export { resolveInputFromRequest } from './input/source-resolver.js';
|
|
27
27
|
export { normalizeInput } from './input/normalizer.js';
|
|
28
28
|
export { parseSpatieInput } from './input/spatie-parser.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAU9C,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AACxF,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EACL,SAAS,EACT,eAAe,EACf,mBAAmB,GACpB,MAAM,qCAAqC,CAAC;AAK7C,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AASjG,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC5F,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAEjG,OAAO,EACL,YAAY,EACZ,oBAAoB,GACrB,MAAM,wCAAwC,CAAC;AAEhD,OAAO,EAAE,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAElE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EACL,eAAe,EACf,4BAA4B,EAC5B,4BAA4B,EAC5B,+BAA+B,EAC/B,yBAAyB,EACzB,yBAAyB,EACzB,6BAA6B,EAC7B,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,EACxB,iBAAiB,EACjB,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAiCrB,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,mBAAmB,GACpB,MAAM,wBAAwB,CAAC;AAQhC,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,EACjB,wBAAwB,EACxB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,mBAAmB,GACpB,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply-filter.interceptor.d.ts","sourceRoot":"","sources":["../../src/interceptor/apply-filter.interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,gBAAgB,EAErB,KAAK,eAAe,EAErB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAiBvC,qBACa,sBAAuB,YAAW,eAAe;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,SAAS;IAKjD,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,aAAa,CAA8B;IAEnD,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,UAAU;IAwBlB,SAAS,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC;YAsB1D,MAAM;
|
|
1
|
+
{"version":3,"file":"apply-filter.interceptor.d.ts","sourceRoot":"","sources":["../../src/interceptor/apply-filter.interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,gBAAgB,EAErB,KAAK,eAAe,EAErB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAiBvC,qBACa,sBAAuB,YAAW,eAAe;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,SAAS;IAKjD,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,aAAa,CAA8B;IAEnD,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,UAAU;IAwBlB,SAAS,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC;YAsB1D,MAAM;CAoCrB"}
|
|
@@ -90,7 +90,12 @@ let ApplyFilterInterceptor = class ApplyFilterInterceptor {
|
|
|
90
90
|
const qb = adapter.createQueryBuilder(filterableMeta.entity);
|
|
91
91
|
const source = entry.options.source ?? 'auto';
|
|
92
92
|
const rawInput = resolveInputFromRequest(req, source);
|
|
93
|
-
|
|
93
|
+
// `distinctOrder` travels from the DECORATOR, not from the resolved
|
|
94
|
+
// filter class: a route that swaps its class per request (`resolve`)
|
|
95
|
+
// must keep the answer its own declaration gave. Passing it through
|
|
96
|
+
// undefined is the "route said nothing" case, which falls back to the
|
|
97
|
+
// filter class.
|
|
98
|
+
await runner.apply(FilterClass, rawInput, qb, { req }, { distinctOrder: entry.options.distinctOrder });
|
|
94
99
|
slot[entry.paramIndex] = qb;
|
|
95
100
|
}
|
|
96
101
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply-filter.interceptor.js","sourceRoot":"","sources":["../../src/interceptor/apply-filter.interceptor.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"apply-filter.interceptor.js","sourceRoot":"","sources":["../../src/interceptor/apply-filter.interceptor.ts"],"names":[],"mappings":"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"}
|