@venizia/ignis-filter 0.2.0-8 → 0.2.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/LICENSE.md +0 -1
- package/README.md +76 -55
- package/dist/esm/common/index.d.ts +2 -2
- package/dist/esm/common/index.js +2 -2
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/package.json +4 -0
- package/dist/esm/schemas/builder.d.ts +1 -1
- package/dist/esm/schemas/common/index.d.ts +1 -1
- package/dist/esm/schemas/common/index.js +1 -1
- package/dist/esm/schemas/index.d.ts +2 -2
- package/dist/esm/schemas/index.js +3 -3
- package/package.json +4 -4
package/LICENSE.md
CHANGED
|
@@ -72,7 +72,6 @@ Ignis uses the following open-source libraries. We are grateful to the authors a
|
|
|
72
72
|
|
|
73
73
|
| Library | License | Description |
|
|
74
74
|
|---------|---------|-------------|
|
|
75
|
-
| [Lodash](https://github.com/lodash/lodash) | MIT | Utility library |
|
|
76
75
|
| [reflect-metadata](https://github.com/rbuckton/reflect-metadata) | Apache-2.0 | Metadata reflection API |
|
|
77
76
|
|
|
78
77
|
### Documentation Dependencies
|
package/README.md
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
# @venizia/ignis-filter
|
|
2
2
|
|
|
3
|
-
The
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
It is **isomorphic by construction**. The package resolves to no node builtin and no server-only
|
|
7
|
-
peer, so the same filter language describes a query against a Postgres repository on the server and
|
|
8
|
-
against a WASM database in a browser worker. A guard test bundles the barrel for `target: 'browser'`
|
|
9
|
-
and fails if anything outside `@venizia/ignis-inversion`, `lodash` and `reflect-metadata` enters the
|
|
10
|
-
graph.
|
|
3
|
+
The query filter language of IGNIS: the `TFilter` shape, its operators, and the zod schemas that
|
|
4
|
+
validate it. Install it directly when you want the language without the server framework, for
|
|
5
|
+
example in a browser.
|
|
11
6
|
|
|
12
7
|
## Install
|
|
13
8
|
|
|
@@ -15,72 +10,98 @@ graph.
|
|
|
15
10
|
bun add @venizia/ignis-filter
|
|
16
11
|
```
|
|
17
12
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
want the vocabulary **without** the server framework, which is the browser case.
|
|
13
|
+
An application on `@venizia/ignis` does not need it: `TFilter`, `QueryOperators`, `Sorts` and the
|
|
14
|
+
schemas are re-exported from `@venizia/ignis`.
|
|
21
15
|
|
|
22
|
-
##
|
|
16
|
+
## Use it
|
|
23
17
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
| `TFields` | Field selection - array of names, or an object keyed by name |
|
|
29
|
-
| `TInclusion` | One relation to include, with an optional nested `scope` |
|
|
30
|
-
| `TLimit`, `TOffset`, `TSkip`, `TOrderBy` | The scalar members of the shape |
|
|
31
|
-
| `QueryOperators` | Comparison, pattern, null, array and logical operators, plus `isValid` |
|
|
32
|
-
| `TQueryOperator` | The operator union, derived from the const class |
|
|
33
|
-
| `Sorts` | `ASC` / `DESC`, plus `isValid` |
|
|
34
|
-
|
|
35
|
-
```ts
|
|
18
|
+
A filter is a plain object. Type it against your entity, and an unknown field in `where` is a
|
|
19
|
+
compile error.
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
36
22
|
import { QueryOperators, Sorts, type TFilter } from '@venizia/ignis-filter';
|
|
37
23
|
|
|
38
|
-
|
|
39
|
-
|
|
24
|
+
type TUser = { id: number; status: string; createdAt: string };
|
|
25
|
+
|
|
26
|
+
const filter: TFilter<TUser> = {
|
|
27
|
+
where: {
|
|
28
|
+
status: 'active',
|
|
29
|
+
createdAt: { [QueryOperators.GTE]: '2026-01-01' },
|
|
30
|
+
or: [{ id: { [QueryOperators.IN]: [1, 2, 3] } }, { status: 'pending' }],
|
|
31
|
+
},
|
|
40
32
|
order: [`createdAt ${Sorts.DESC}`],
|
|
41
33
|
limit: 20,
|
|
42
34
|
};
|
|
43
35
|
```
|
|
44
36
|
|
|
45
|
-
|
|
37
|
+
A bare value means `eq`, and `null` means `is`. The same object works against every IGNIS
|
|
38
|
+
repository. Each connector translates it for its engine and throws on an operator the engine does
|
|
39
|
+
not support.
|
|
46
40
|
|
|
47
|
-
|
|
41
|
+
## Validate a filter from the wire
|
|
42
|
+
|
|
43
|
+
Import the schemas from the `/schemas` entry point. `FilterSchema` and `WhereSchema` accept an
|
|
44
|
+
object or a JSON string.
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
48
47
|
import { FilterSchema, WhereSchema } from '@venizia/ignis-filter/schemas';
|
|
49
48
|
|
|
50
|
-
const
|
|
51
|
-
const where = WhereSchema.
|
|
49
|
+
const filter = FilterSchema.parse('{"where":{"status":"active"},"limit":20}');
|
|
50
|
+
const where = WhereSchema.safeParse('not-json'); // success: false - a validation issue, not a throw
|
|
52
51
|
```
|
|
53
52
|
|
|
54
|
-
A
|
|
55
|
-
|
|
56
|
-
`InclusionSchema`, `LimitSchema`, `OffsetSchema`, `SkipSchema`, `OrderBySchema`.
|
|
53
|
+
A negative or fractional `limit`, `offset` or `skip` fails validation. `include[].scope` takes a
|
|
54
|
+
nested filter.
|
|
57
55
|
|
|
58
|
-
|
|
59
|
-
> OpenAPI metadata - they validate identically but document nothing, so a route built on them
|
|
60
|
-
> produces an API reference with no descriptions.
|
|
56
|
+
## What it carries
|
|
61
57
|
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
| Export | What it is |
|
|
59
|
+
| :--- | :--- |
|
|
60
|
+
| `TFilter<T>` | `{ where, fields, include, order, limit, offset, skip }` |
|
|
61
|
+
| `TWhere<T>` | Conditions keyed by the fields of `T`, with nested `and` / `or` |
|
|
62
|
+
| `TWhereOperators<V>`, `TWhereValue<V>` | The operator object and what one field accepts |
|
|
63
|
+
| `TFields<T>` | An array of field names, or `{ field: true \| false }` |
|
|
64
|
+
| `TInclusion` | `{ relation, scope? }`: a relation to load, with its own filter |
|
|
65
|
+
| `TIsoTimestamp` | A branded string for ISO timestamp columns; `where` also accepts a `Date` for it |
|
|
66
|
+
| `QueryOperators` | The operator names, plus `isValid()` |
|
|
67
|
+
| `Sorts` | `ASC` / `DESC`, plus `isValid()` |
|
|
64
68
|
|
|
65
|
-
|
|
66
|
-
|
|
69
|
+
| Operators | Names |
|
|
70
|
+
| :--- | :--- |
|
|
71
|
+
| Comparison | `eq`, `ne`, `neq`, `gt`, `gte`, `lt`, `lte` |
|
|
72
|
+
| Pattern | `like`, `nlike`, `ilike`, `nilike`, `regexp`, `iregexp` |
|
|
73
|
+
| Null | `is`, `isn` |
|
|
74
|
+
| List and range | `in`, `inq`, `nin`, `between`, `notBetween` |
|
|
75
|
+
| Array columns | `contains`, `containedBy`, `overlaps` |
|
|
76
|
+
| Other | `exists`, `notExists`, `not`, `and`, `or` |
|
|
67
77
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
78
|
+
## Entry points
|
|
79
|
+
|
|
80
|
+
| Entry point | What it gives | Extra peers |
|
|
81
|
+
| :--- | :--- | :--- |
|
|
82
|
+
| `@venizia/ignis-filter` | Types, `QueryOperators`, `Sorts`. Does not load zod | none |
|
|
83
|
+
| `@venizia/ignis-filter/schemas` | `FilterSchema`, `WhereSchema`, `FieldsSchema`, `InclusionSchema`, `LimitSchema`, `OffsetSchema`, `SkipSchema`, `OrderBySchema`, `buildQuerySchemas` | none (`zod` is a dependency) |
|
|
84
|
+
|
|
85
|
+
Both ship CommonJS and ES module builds, with no node builtin, so they load in a browser.
|
|
86
|
+
|
|
87
|
+
The schemas here carry no OpenAPI descriptions. On a server, import them from `@venizia/ignis`
|
|
88
|
+
instead: the same schemas, built through `buildQuerySchemas({ decorate })` with an OpenAPI
|
|
89
|
+
decorator, so your API reference documents them.
|
|
90
|
+
|
|
91
|
+
The schema's inferred type is looser than `TFilter<T>`. It describes what arrives over the wire,
|
|
92
|
+
so it accepts any field name in `where`.
|
|
93
|
+
|
|
94
|
+
## Where it sits
|
|
72
95
|
|
|
73
|
-
|
|
96
|
+
Depends on inversion. Used by kernel and connectors: dev-configs -> inversion -> {**filter**,
|
|
97
|
+
helpers} -> {boot, kernel} -> connectors -> {core-worker, core-server} -> atlas.
|
|
74
98
|
|
|
75
|
-
|
|
76
|
-
Postgres translator is Drizzle-coupled and lives with its connector. Operator support differs per
|
|
77
|
-
engine, and an unsupported operator throws at translation time rather than being dropped from this
|
|
78
|
-
list.
|
|
79
|
-
- **Types inferred from the schemas.** `TFilter<T>` is generic over the entity, so `TFilter<User>`
|
|
80
|
-
rejects `{ where: { notAField: 1 } }`; `z.infer<typeof FilterSchema>` accepts it, because the
|
|
81
|
-
recursive where-clause is `z.ZodType<any>`. The schema describes what arrives over the wire, the
|
|
82
|
-
type describes what application code builds, and they only overlap in the middle.
|
|
99
|
+
## Links
|
|
83
100
|
|
|
84
|
-
|
|
101
|
+
- [Filter system](https://ignis.venizia.ai/references/base/filter-system/)
|
|
102
|
+
- [Filter quick reference](https://ignis.venizia.ai/references/base/filter-system/quick-reference)
|
|
103
|
+
- [Changelog: the filter package](https://ignis.venizia.ai/changelogs/2026-07-25-ignis-filter-package)
|
|
104
|
+
- [Changelog](https://ignis.venizia.ai/changelogs/)
|
|
105
|
+
- [Source](https://github.com/VENIZIA-AI/ignis/blob/main/packages/filter)
|
|
85
106
|
|
|
86
|
-
MIT
|
|
107
|
+
MIT licensed - see [LICENSE.md](./LICENSE.md).
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from './operators';
|
|
2
|
-
export * from './types';
|
|
1
|
+
export * from './operators.js';
|
|
2
|
+
export * from './types.js';
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/esm/common/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from './operators';
|
|
2
|
-
export * from './types';
|
|
1
|
+
export * from './operators.js';
|
|
2
|
+
export * from './types.js';
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './common';
|
|
1
|
+
export * from './common/index.js';
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/esm/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './common';
|
|
1
|
+
export * from './common/index.js';
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './types';
|
|
1
|
+
export * from './types.js';
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './types';
|
|
1
|
+
export * from './types.js';
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export * from './builder';
|
|
2
|
-
export * from './common';
|
|
1
|
+
export * from './builder.js';
|
|
2
|
+
export * from './common/index.js';
|
|
3
3
|
/** Ready-to-use schemas with no documentation metadata attached - the browser case, and the reason most consumers never touch `buildQuerySchemas` directly. */
|
|
4
4
|
export declare const FieldsSchema: import("zod").ZodOptional<import("zod").ZodUnion<[import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodBoolean>, import("zod").ZodArray<import("zod").ZodString>]>>, FilterSchema: import("zod").ZodOptional<import("zod").ZodUnion<readonly [any, import("zod").ZodPipe<import("zod").ZodPipe<import("zod").ZodString, import("zod").ZodTransform<any, string>>, any>]>>, InclusionSchema: any, LimitSchema: import("zod").ZodOptional<import("zod").ZodNumber>, OffsetSchema: import("zod").ZodOptional<import("zod").ZodNumber>, OrderBySchema: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>, SkipSchema: import("zod").ZodOptional<import("zod").ZodNumber>, WhereSchema: import("zod").ZodUnion<readonly [import("zod").ZodType<any, unknown, import("zod/v4/core").$ZodTypeInternals<any, unknown>>, import("zod").ZodPipe<import("zod").ZodPipe<import("zod").ZodString, import("zod").ZodTransform<any, string>>, import("zod").ZodType<any, unknown, import("zod/v4/core").$ZodTypeInternals<any, unknown>>>]>;
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { buildQuerySchemas } from './builder';
|
|
2
|
-
export * from './builder';
|
|
3
|
-
export * from './common';
|
|
1
|
+
import { buildQuerySchemas } from './builder.js';
|
|
2
|
+
export * from './builder.js';
|
|
3
|
+
export * from './common/index.js';
|
|
4
4
|
/** Ready-to-use schemas with no documentation metadata attached - the browser case, and the reason most consumers never touch `buildQuerySchemas` directly. */
|
|
5
5
|
export const { FieldsSchema, FilterSchema, InclusionSchema, LimitSchema, OffsetSchema, OrderBySchema, SkipSchema, WhereSchema, } = buildQuerySchemas();
|
|
6
6
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@venizia/ignis-filter",
|
|
3
|
-
"version": "0.2.0
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Engine-neutral query filter vocabulary for TypeScript: the `{ where, order, limit, offset, skip, fields, include }` shape, comparison/pattern/null/array/logical operators, and sort direction constants. Isomorphic by construction - no node builtins and no server-only peer, so the same filter language serves a server repository and a browser data layer.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"browser",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
"license": "MIT",
|
|
36
36
|
"engines": {
|
|
37
|
-
"bun": ">=1.
|
|
37
|
+
"bun": ">=1.4"
|
|
38
38
|
},
|
|
39
39
|
"main": "./dist/cjs/index.js",
|
|
40
40
|
"exports": {
|
|
@@ -79,12 +79,12 @@
|
|
|
79
79
|
"prepublishOnly": "bun run rebuild"
|
|
80
80
|
},
|
|
81
81
|
"dependencies": {
|
|
82
|
-
"@venizia/ignis-inversion": "^0.2.0
|
|
82
|
+
"@venizia/ignis-inversion": "^0.2.0",
|
|
83
83
|
"zod": "^4.5.4"
|
|
84
84
|
},
|
|
85
85
|
"devDependencies": {
|
|
86
86
|
"@types/bun": "^1.4.1",
|
|
87
|
-
"@venizia/dev-configs": "^0.2.0
|
|
87
|
+
"@venizia/dev-configs": "^0.2.0",
|
|
88
88
|
"eslint": "^10.10.0",
|
|
89
89
|
"prettier": "^3.9.6",
|
|
90
90
|
"tsc-alias": "^1.9.4",
|