@venizia/ignis-docs 0.2.0 → 0.2.1-1
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 +14 -14
- package/content/best-practices/api-usage-examples.md +39 -19
- package/content/best-practices/architectural-patterns.md +24 -13
- package/content/best-practices/architecture-decisions.md +29 -16
- package/content/best-practices/code-style-standards/advanced-patterns.md +43 -31
- package/content/best-practices/code-style-standards/constants-configuration.md +19 -4
- package/content/best-practices/code-style-standards/control-flow.md +33 -1
- package/content/best-practices/code-style-standards/documentation.md +28 -8
- package/content/best-practices/code-style-standards/function-patterns.md +15 -4
- package/content/best-practices/code-style-standards/index.md +7 -2
- package/content/best-practices/code-style-standards/naming-conventions.md +27 -3
- package/content/best-practices/code-style-standards/route-definitions.md +9 -5
- package/content/best-practices/code-style-standards/tooling.md +14 -1
- package/content/best-practices/code-style-standards/type-safety.md +39 -6
- package/content/best-practices/common-pitfalls.md +59 -35
- package/content/best-practices/contribution-workflow.md +8 -4
- package/content/best-practices/data-modeling.md +78 -62
- package/content/best-practices/deployment-strategies.md +56 -19
- package/content/best-practices/error-handling.md +247 -153
- package/content/best-practices/index.md +6 -0
- package/content/best-practices/performance-optimization.md +26 -13
- package/content/best-practices/security-guidelines.md +35 -9
- package/content/best-practices/testing-strategies.md +7 -2
- package/content/best-practices/troubleshooting-tips.md +27 -17
- package/content/extensions/components/api-reference.md +109 -323
- package/content/extensions/components/authentication/api.md +489 -602
- package/content/extensions/components/authentication/errors.md +135 -498
- package/content/extensions/components/authentication/index.md +89 -801
- package/content/extensions/components/authentication/usage.md +231 -955
- package/content/extensions/components/authorization/api.md +991 -644
- package/content/extensions/components/authorization/errors.md +204 -208
- package/content/extensions/components/authorization/getting-started.md +227 -0
- package/content/extensions/components/authorization/index.md +88 -795
- package/content/extensions/components/authorization/usage.md +219 -528
- package/content/extensions/components/health-check.md +77 -243
- package/content/extensions/components/index.md +24 -90
- package/content/extensions/components/mail/api.md +553 -285
- package/content/extensions/components/mail/errors.md +76 -62
- package/content/extensions/components/mail/index.md +111 -463
- package/content/extensions/components/mail/usage.md +139 -173
- package/content/extensions/components/request-tracker.md +70 -173
- package/content/extensions/components/socket-io/api.md +462 -785
- package/content/extensions/components/socket-io/errors.md +49 -51
- package/content/extensions/components/socket-io/index.md +69 -372
- package/content/extensions/components/socket-io/usage.md +212 -105
- package/content/extensions/components/static-asset/api.md +461 -141
- package/content/extensions/components/static-asset/errors.md +121 -53
- package/content/extensions/components/static-asset/index.md +84 -606
- package/content/extensions/components/static-asset/usage.md +184 -299
- package/content/extensions/components/template/index.md +3 -3
- package/content/extensions/components/websocket/api.md +311 -404
- package/content/extensions/components/websocket/errors.md +47 -56
- package/content/extensions/components/websocket/index.md +75 -407
- package/content/extensions/components/websocket/usage.md +120 -338
- package/content/extensions/helpers/cron/index.md +52 -160
- package/content/extensions/helpers/crypto/index.md +67 -480
- package/content/extensions/helpers/crypto/reference.md +528 -0
- package/content/extensions/helpers/env/index.md +64 -178
- package/content/extensions/helpers/error/index.md +286 -196
- package/content/extensions/helpers/index.md +61 -47
- package/content/extensions/helpers/inversion/index.md +76 -550
- package/content/extensions/helpers/inversion/reference.md +530 -0
- package/content/extensions/helpers/kafka/admin.md +23 -3
- package/content/extensions/helpers/kafka/compile-binary.md +83 -52
- package/content/extensions/helpers/kafka/consumer.md +65 -28
- package/content/extensions/helpers/kafka/examples.md +46 -253
- package/content/extensions/helpers/kafka/index.md +55 -617
- package/content/extensions/helpers/kafka/producer.md +156 -22
- package/content/extensions/helpers/kafka/schema-registry.md +59 -79
- package/content/extensions/helpers/logger/hf-logger.md +220 -0
- package/content/extensions/helpers/logger/index.md +78 -552
- package/content/extensions/helpers/logger/pino.md +105 -0
- package/content/extensions/helpers/logger/reference.md +937 -0
- package/content/extensions/helpers/network/api.md +276 -195
- package/content/extensions/helpers/network/index.md +87 -524
- package/content/extensions/helpers/queue/index.md +80 -897
- package/content/extensions/helpers/queue/reference.md +494 -0
- package/content/extensions/helpers/redis/index.md +86 -640
- package/content/extensions/helpers/redis/reference.md +784 -0
- package/content/extensions/helpers/secrets/index.md +136 -0
- package/content/extensions/helpers/socket-io/api.md +325 -204
- package/content/extensions/helpers/socket-io/index.md +79 -429
- package/content/extensions/helpers/storage/api.md +584 -464
- package/content/extensions/helpers/storage/index.md +80 -573
- package/content/extensions/helpers/types/index.md +75 -495
- package/content/extensions/helpers/types/reference.md +689 -0
- package/content/extensions/helpers/uid/index.md +176 -189
- package/content/extensions/helpers/websocket/api.md +366 -214
- package/content/extensions/helpers/websocket/index.md +68 -503
- package/content/extensions/helpers/worker-thread/index.md +62 -396
- package/content/extensions/helpers/worker-thread/reference.md +428 -0
- package/content/extensions/index.md +38 -39
- package/content/extensions/src-details/mcp-server.md +96 -548
- package/content/guides/core-concepts/persistent/datasources.md +2 -2
- package/content/guides/core-concepts/persistent/index.md +5 -1
- package/content/guides/core-concepts/persistent/models.md +1 -1
- package/content/guides/core-concepts/persistent/pglite.md +218 -0
- package/content/guides/core-concepts/persistent/postgres-drivers.md +21 -15
- package/content/guides/core-concepts/persistent/search-meilisearch.md +22 -12
- package/content/guides/core-concepts/persistent/search-typesense.md +28 -16
- package/content/guides/core-concepts/persistent/sqlite.md +296 -0
- package/content/guides/core-concepts/persistent/transactions.md +12 -11
- package/content/guides/core-concepts/secrets-vault.md +177 -0
- package/content/guides/core-concepts/services.md +1 -1
- package/content/guides/get-started/5-minute-quickstart.md +59 -206
- package/content/guides/get-started/philosophy.md +135 -670
- package/content/guides/get-started/setup.md +53 -74
- package/content/guides/migrations/redis-helpers-migration.md +5 -4
- package/content/guides/migrations/scoped-rbac-migration.md +5 -5
- package/content/guides/migrations/unified-connectors-migration.md +8 -7
- package/content/guides/tutorials/ecommerce-api.md +3 -8
- package/content/guides/tutorials/realtime-chat.md +1 -1
- package/content/references/base/application.md +64 -22
- package/content/references/base/components.md +3 -3
- package/content/references/base/connectors.md +79 -136
- package/content/references/base/controllers.md +12 -12
- package/content/references/base/datasources-reference.md +600 -0
- package/content/references/base/datasources.md +84 -444
- package/content/references/base/dependency-injection.md +25 -46
- package/content/references/base/filter-system/application-usage.md +95 -123
- package/content/references/base/filter-system/array-operators.md +33 -43
- package/content/references/base/filter-system/comparison-operators.md +55 -63
- package/content/references/base/filter-system/default-filter.md +144 -350
- package/content/references/base/filter-system/fields-order-pagination.md +116 -148
- package/content/references/base/filter-system/index.md +114 -253
- package/content/references/base/filter-system/json-filtering.md +52 -181
- package/content/references/base/filter-system/list-operators.md +28 -44
- package/content/references/base/filter-system/logical-operators.md +69 -114
- package/content/references/base/filter-system/null-operators.md +41 -98
- package/content/references/base/filter-system/pattern-matching.md +48 -51
- package/content/references/base/filter-system/quick-reference.md +93 -196
- package/content/references/base/filter-system/range-operators.md +22 -38
- package/content/references/base/filter-system/tips.md +70 -133
- package/content/references/base/filter-system/use-cases.md +173 -232
- package/content/references/base/grpc-controllers.md +53 -17
- package/content/references/base/index.md +5 -3
- package/content/references/base/middlewares.md +43 -28
- package/content/references/base/models-reference.md +886 -0
- package/content/references/base/models.md +81 -1452
- package/content/references/base/providers.md +8 -8
- package/content/references/base/repositories/advanced.md +281 -419
- package/content/references/base/repositories/index.md +84 -644
- package/content/references/base/repositories/mixins.md +25 -21
- package/content/references/base/repositories/relations.md +194 -375
- package/content/references/base/repositories/soft-deletable.md +67 -55
- package/content/references/base/secrets.md +267 -0
- package/content/references/base/services.md +8 -6
- package/content/references/configuration/environment-variables.md +73 -21
- package/content/references/configuration/index.md +51 -31
- package/content/references/index.md +1 -1
- package/content/references/quick-reference.md +3 -16
- package/content/references/utilities/crypto.md +35 -76
- package/content/references/utilities/date.md +33 -73
- package/content/references/utilities/duration.md +85 -0
- package/content/references/utilities/index.md +6 -2
- package/content/references/utilities/jsx-reference.md +298 -0
- package/content/references/utilities/jsx.md +82 -525
- package/content/references/utilities/module.md +81 -61
- package/content/references/utilities/parse.md +34 -64
- package/content/references/utilities/performance.md +33 -58
- package/content/references/utilities/promise.md +28 -62
- package/content/references/utilities/request.md +58 -218
- package/content/references/utilities/retry.md +139 -0
- package/content/references/utilities/schema.md +43 -137
- package/content/references/utilities/statuses-reference.md +361 -0
- package/content/references/utilities/statuses.md +63 -667
- package/dist/mcp-server/index.js +0 -0
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.js +3 -3
- package/dist/mcp-server/tools/github/search-code.tool.js +1 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js +1 -1
- package/dist/mcp-server/tools/github/view-source-file.tool.js +1 -1
- package/package.json +24 -23
|
@@ -1,288 +1,149 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: Filter System
|
|
3
|
-
description:
|
|
2
|
+
title: Filter System
|
|
3
|
+
description: Shape a query - which rows, which fields, what order, how much
|
|
4
4
|
difficulty: intermediate
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Filter System
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Every repository read, update, and delete verb takes the same `filter` object. It picks rows (`where`), columns (`fields`), order (`order`), and how many (`limit`/`skip`).
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
> If you're new to IGNIS, start with:
|
|
13
|
-
> - [5-Minute Quickstart](/guides/get-started/5-minute-quickstart) - Get up and running
|
|
14
|
-
> - [Building a CRUD API](/guides/tutorials/building-a-crud-api) - Learn the basics
|
|
15
|
-
> - [Repositories](/references/base/repositories/) - Repository overview
|
|
11
|
+
The vocabulary ships as its own package, **`@venizia/ignis-filter`**. Applications on `@venizia/ignis` already get every name here re-exported from the core barrel, so nothing changes for them. Install it directly only when you want the filter language **without** the server framework - a browser or a Web Worker - since it resolves no node builtin and no server-only dependency:
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
- [Repositories](../repositories/) - Basic repository operations (find, create, update, delete)
|
|
22
|
-
- [Models](../models.md) - Entity definitions and schemas
|
|
23
|
-
- SQL basics - Understanding of WHERE clauses and operators
|
|
24
|
-
- TypeScript type system - Type safety and inference
|
|
13
|
+
```typescript
|
|
14
|
+
import { QueryOperators, Sorts, type TFilter } from '@venizia/ignis-filter';
|
|
15
|
+
import { FilterSchema, WhereSchema } from '@venizia/ignis-filter/schemas';
|
|
16
|
+
```
|
|
25
17
|
|
|
26
|
-
|
|
18
|
+
On a server take the schemas from `@venizia/ignis` instead: the ones on that subpath carry no OpenAPI metadata, so a route built on them documents nothing.
|
|
27
19
|
|
|
28
|
-
|
|
29
|
-
|-------|-------------|
|
|
30
|
-
| [**Quick Reference**](./quick-reference.md) | **Single-page cheat sheet of all operators** |
|
|
31
|
-
| [Comparison Operators](./comparison-operators.md) | Equality, range, null checks |
|
|
32
|
-
| [Pattern Matching](./pattern-matching.md) | LIKE, ILIKE, regex |
|
|
33
|
-
| [Logical Operators](./logical-operators.md) | AND, OR combinations |
|
|
34
|
-
| [List Operators](./list-operators.md) | IN, NOT IN |
|
|
35
|
-
| [Range Operators](./range-operators.md) | BETWEEN, NOT BETWEEN |
|
|
36
|
-
| [Null Operators](./null-operators.md) | IS NULL, IS NOT NULL |
|
|
37
|
-
| [Array Operators](./array-operators.md) | PostgreSQL array operations |
|
|
38
|
-
| [JSON Filtering](./json-filtering.md) | JSON/JSONB path queries |
|
|
39
|
-
| [Fields, Order, Pagination](./fields-order-pagination.md) | SELECT, ORDER BY, LIMIT |
|
|
40
|
-
| [**Default Filter**](./default-filter.md) | Automatic filter application |
|
|
41
|
-
| [Application Usage](./application-usage.md) | Filter flow in applications |
|
|
42
|
-
| [Tips & Best Practices](./tips.md) | Performance and patterns |
|
|
43
|
-
| [Use Cases](./use-cases.md) | Real-world examples |
|
|
20
|
+
## In one example
|
|
44
21
|
|
|
22
|
+
`where` picks rows, `fields` picks columns, `order` sorts, `limit` bounds the result:
|
|
45
23
|
|
|
46
|
-
|
|
24
|
+
```typescript
|
|
25
|
+
import { postRepository } from '@/repositories';
|
|
26
|
+
|
|
27
|
+
const posts = await postRepository.find({
|
|
28
|
+
filter: {
|
|
29
|
+
where: {
|
|
30
|
+
status: 'published',
|
|
31
|
+
or: [{ featured: true }, { rating: { gte: 4.5 } }],
|
|
32
|
+
},
|
|
33
|
+
fields: ['id', 'title', 'rating', 'publishedAt'],
|
|
34
|
+
order: ['rating DESC', 'publishedAt DESC'],
|
|
35
|
+
limit: 20,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
```
|
|
47
39
|
|
|
48
|
-
|
|
40
|
+
`postRepository` is a `@repository({ model: Post, dataSource })`-bound repository. `Post`'s schema comes from `@/schemas` - see [Models](/references/base/models) and [Repositories](../repositories/).
|
|
49
41
|
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
offset?: number; // Alias for skip
|
|
58
|
-
include?: TInclusion[]; // Related data (Drizzle relational queries)
|
|
59
|
-
};
|
|
42
|
+
```sql
|
|
43
|
+
-- Equivalent SQL
|
|
44
|
+
SELECT "id", "title", "rating", "published_at"
|
|
45
|
+
FROM "post"
|
|
46
|
+
WHERE "status" = 'published' AND ("featured" = true OR "rating" >= 4.5)
|
|
47
|
+
ORDER BY "rating" DESC, "published_at" DESC
|
|
48
|
+
LIMIT 20
|
|
60
49
|
```
|
|
61
50
|
|
|
51
|
+
## How it works
|
|
62
52
|
|
|
63
|
-
|
|
53
|
+
- **`TFilter` maps straight to SQL.** Every property corresponds to one clause of the generated query - see the table below.
|
|
54
|
+
- **`where` takes a bare value or an operator object.** A bare value is implicit equality (`null` becomes `IS NULL`, an array becomes `IN`). An operator object keys into one of the operator families.
|
|
55
|
+
- **Multiple `where` keys are an implicit AND.** A dot-notation key (`'metadata.path'`) targets a JSON/JSONB column instead of a top-level column, and accepts the same operators. IGNIS casts the operand automatically when it's a number.
|
|
56
|
+
- **A model's `settings.defaultFilter` merges into every query for that model** - see [Default filter](#default-filter) below.
|
|
64
57
|
|
|
65
|
-
| Filter
|
|
66
|
-
|
|
58
|
+
| Filter property | SQL equivalent | Purpose |
|
|
59
|
+
|---|---|---|
|
|
67
60
|
| `where` | `WHERE` | Filter rows by conditions |
|
|
68
61
|
| `fields` | `SELECT col1, col2` | Select specific columns |
|
|
69
62
|
| `order` | `ORDER BY` | Sort results |
|
|
70
|
-
| `limit` | `LIMIT` | Restrict number of results |
|
|
71
|
-
| `skip` / `offset` | `OFFSET` | Skip rows for pagination |
|
|
72
|
-
| `include` | Separate relational query |
|
|
63
|
+
| `limit` | `LIMIT` | Restrict the number of results |
|
|
64
|
+
| `skip` / `offset` | `OFFSET` | Skip rows for pagination (aliases - `skip` wins if both are given) |
|
|
65
|
+
| `include` | Separate relational query | Eager-load related rows ([Relations & Includes](../repositories/relations)) |
|
|
73
66
|
|
|
67
|
+
### The `where` operator families
|
|
74
68
|
|
|
75
|
-
|
|
69
|
+
| Family | Operators | Example |
|
|
70
|
+
|---|---|---|
|
|
71
|
+
| Comparison | `eq`, `ne`/`neq`, `gt`, `gte`, `lt`, `lte` | `{ age: { gte: 18, lte: 65 } }` |
|
|
72
|
+
| Null / presence | `is`, `isn`, `exists`, `notExists` | `{ deletedAt: null }` or `{ verifiedAt: { exists: true } }` |
|
|
73
|
+
| List | `in`/`inq`, `nin` | `{ status: { inq: ['active', 'pending'] } }` |
|
|
74
|
+
| Range | `between`, `notBetween` | `{ score: { between: [40, 60] } }` |
|
|
75
|
+
| Pattern | `like`, `nlike`, `ilike`, `nilike`, `regexp`, `iregexp` | `{ email: { ilike: '%@company.com' } }` |
|
|
76
|
+
| Logical | `and`, `or`, `not` | `{ or: [{ role: 'admin' }, { role: 'moderator' }] }` |
|
|
77
|
+
| Array (PostgreSQL) | `contains`, `containedBy`, `overlaps` | `{ tags: { contains: ['typescript'] } }` |
|
|
78
|
+
| JSON path | comparison, null, list, range, and pattern operators, on a `'column.path'` key | `{ 'metadata.score': { gt: 80 } }` |
|
|
76
79
|
|
|
77
|
-
|
|
78
|
-
// Filter object
|
|
79
|
-
const filter = {
|
|
80
|
-
where: { status: 'active', role: 'admin' },
|
|
81
|
-
fields: ['id', 'name', 'email'],
|
|
82
|
-
order: ['createdAt DESC'],
|
|
83
|
-
limit: 10,
|
|
84
|
-
skip: 0
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
// Equivalent SQL
|
|
88
|
-
// SELECT "id", "name", "email"
|
|
89
|
-
// FROM "users"
|
|
90
|
-
// WHERE "status" = 'active' AND "role" = 'admin'
|
|
91
|
-
// ORDER BY "created_at" DESC
|
|
92
|
-
// LIMIT 10 OFFSET 0
|
|
93
|
-
```
|
|
80
|
+
Full operator-by-operator tables, one line each, live on the [Quick Reference](./quick-reference) page.
|
|
94
81
|
|
|
82
|
+
### Fields, order, and pagination
|
|
95
83
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
| Equals | `{ field: value }` or `{ field: { eq: value } }` |
|
|
101
|
-
| Not equals | `{ field: { ne: value } }` or `{ field: { neq: value } }` |
|
|
102
|
-
| Greater than | `{ field: { gt: value } }` |
|
|
103
|
-
| Greater or equal | `{ field: { gte: value } }` |
|
|
104
|
-
| Less than | `{ field: { lt: value } }` |
|
|
105
|
-
| Less or equal | `{ field: { lte: value } }` |
|
|
106
|
-
| Is null | `{ field: null }` or `{ field: { is: null } }` |
|
|
107
|
-
| Is not null | `{ field: { isn: null } }` or `{ field: { ne: null } }` |
|
|
108
|
-
| Field present (`IS NOT NULL`) | `{ field: { exists: true } }` (or `{ field: { notExists: false } }`) |
|
|
109
|
-
| Field missing/null (`IS NULL`) | `{ field: { exists: false } }` or `{ field: { notExists: true } }` |
|
|
110
|
-
| Negate a condition | `{ field: { not: value } }` (negates `eq`) or `{ field: { not: { gt: 10 } } }` |
|
|
111
|
-
| In list | `{ field: { in: [a, b, c] } }` or `{ field: { inq: [a, b, c] } }` |
|
|
112
|
-
| Not in list | `{ field: { nin: [a, b, c] } }` |
|
|
113
|
-
| Range | `{ field: { between: [min, max] } }` |
|
|
114
|
-
| Outside range | `{ field: { notBetween: [min, max] } }` |
|
|
115
|
-
| Contains pattern | `{ field: { like: '%pattern%' } }` |
|
|
116
|
-
| Not contains pattern | `{ field: { nlike: '%pattern%' } }` |
|
|
117
|
-
| Case-insensitive | `{ field: { ilike: '%pattern%' } }` |
|
|
118
|
-
| Not case-insensitive | `{ field: { nilike: '%pattern%' } }` |
|
|
119
|
-
| Regex match | `{ field: { regexp: '^pattern$' } }` |
|
|
120
|
-
| Case-insensitive regex | `{ field: { iregexp: '^pattern$' } }` |
|
|
121
|
-
| Array contains all | `{ arrayField: { contains: [a, b] } }` |
|
|
122
|
-
| Array is subset | `{ arrayField: { containedBy: [a, b, c] } }` |
|
|
123
|
-
| Array overlaps | `{ arrayField: { overlaps: [a, b] } }` |
|
|
124
|
-
| JSON nested | `{ 'jsonField.nested.path': value }` |
|
|
125
|
-
| JSON with operator | `{ 'jsonField.path': { gt: 10 } }` |
|
|
126
|
-
| AND conditions | `{ a: 1, b: 2 }` or `{ and: [{a: 1}, {b: 2}] }` |
|
|
127
|
-
| OR conditions | `{ or: [{ a: 1 }, { b: 2 }] }` |
|
|
128
|
-
| Include relation | `{ include: [{ relation: 'name' }] }` |
|
|
129
|
-
| Nested include | `{ include: [{ relation: 'a', scope: { include: [{ relation: 'b' }] } }] }` |
|
|
130
|
-
| Select fields | `{ fields: ['id', 'name'] }` or `{ fields: { id: true, name: true } }` |
|
|
131
|
-
| Order by | `{ order: ['field DESC'] }` |
|
|
132
|
-
| Order by JSON | `{ order: ['jsonField.path DESC'] }` |
|
|
133
|
-
| Paginate | `{ limit: 10, skip: 20 }` or `{ limit: 10, offset: 20 }` |
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
## Common Filter Patterns
|
|
137
|
-
|
|
138
|
-
### Multi-Condition Search
|
|
84
|
+
- **`fields`** selects columns - an array, or a `{ field: true }` object (inclusion-only; `false` is ignored).
|
|
85
|
+
- **`order`** takes `'field ASC'` / `'field DESC'` strings, including JSON paths.
|
|
86
|
+
- **`limit`**, when omitted, resolves through `query.limit ?? model settings.defaultLimit ?? 10`.
|
|
87
|
+
- **`skip` / `offset`** both map to SQL `OFFSET`.
|
|
139
88
|
|
|
140
|
-
|
|
141
|
-
{
|
|
142
|
-
where: {
|
|
143
|
-
and: [
|
|
144
|
-
{ age: { gte: 18, lte: 65 } }, // Between 18 and 65
|
|
145
|
-
{ status: { in: ['active', 'pending'] } },
|
|
146
|
-
{ or: [
|
|
147
|
-
{ email: { ilike: '%@company.com' } },
|
|
148
|
-
{ role: 'admin' }
|
|
149
|
-
]}
|
|
150
|
-
]
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
```
|
|
89
|
+
### Default filter
|
|
154
90
|
|
|
155
|
-
|
|
91
|
+
- **Applies automatically.** A model's `settings.defaultFilter` merges into every read, update, and delete for that model.
|
|
92
|
+
- **AND-composes on collision.** When the default and the caller's filter constrain the same field, IGNIS AND-composes the two conditions instead of one replacing the other.
|
|
93
|
+
- **One override escape.** Setting that same field to a plain scalar (not an operator object) replaces the default outright - the one intentional opt-out, and it needs no `shouldSkipDefaultFilter`. The full collision table lives on the [Default Filter](./default-filter) page.
|
|
156
94
|
|
|
157
95
|
```typescript
|
|
158
|
-
{
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
96
|
+
import { model, BaseEntity } from '@venizia/ignis';
|
|
97
|
+
import { postTable } from '@/schemas';
|
|
98
|
+
|
|
99
|
+
@model({
|
|
100
|
+
type: 'entity',
|
|
101
|
+
settings: { defaultFilter: { where: { isDeleted: false } } },
|
|
102
|
+
})
|
|
103
|
+
export class Post extends BaseEntity<typeof Post.schema> {
|
|
104
|
+
static override schema = postTable;
|
|
166
105
|
}
|
|
167
|
-
```
|
|
168
106
|
|
|
169
|
-
|
|
107
|
+
await postRepository.find({ filter: { where: { status: 'published' } } });
|
|
108
|
+
// WHERE "isDeleted" = false AND "status" = 'published' - different keys, both apply
|
|
170
109
|
|
|
171
|
-
|
|
172
|
-
{
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
lt: new Date('2024-02-01')
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
110
|
+
await postRepository.find({
|
|
111
|
+
filter: { where: { status: 'published' } },
|
|
112
|
+
options: { shouldSkipDefaultFilter: true },
|
|
113
|
+
});
|
|
114
|
+
// WHERE "status" = 'published' - default filter skipped entirely
|
|
180
115
|
```
|
|
181
116
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
Use explicit nesting (via `and`/`or` arrays) for clarity:
|
|
217
|
-
|
|
218
|
-
```typescript
|
|
219
|
-
// Clear precedence
|
|
220
|
-
{
|
|
221
|
-
where: {
|
|
222
|
-
and: [
|
|
223
|
-
{ status: 'active' },
|
|
224
|
-
{ or: [
|
|
225
|
-
{ role: 'admin' },
|
|
226
|
-
{ role: 'moderator' }
|
|
227
|
-
]}
|
|
228
|
-
]
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
## Performance Tips
|
|
235
|
-
|
|
236
|
-
1. **Index frequently filtered columns:**
|
|
237
|
-
```sql
|
|
238
|
-
CREATE INDEX idx_users_status ON users(status);
|
|
239
|
-
CREATE INDEX idx_posts_created_at ON posts(created_at DESC);
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
2. **Use `eq` instead of `like` when possible:**
|
|
243
|
-
```typescript
|
|
244
|
-
// Fast: Uses index
|
|
245
|
-
{ status: { eq: 'active' } }
|
|
246
|
-
|
|
247
|
-
// Slower: Full table scan
|
|
248
|
-
{ status: { like: 'active' } }
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
3. **Limit array contains operations:**
|
|
252
|
-
```typescript
|
|
253
|
-
// Better performance with smaller arrays
|
|
254
|
-
{ tags: { contains: ['typescript'] } } // Good
|
|
255
|
-
{ tags: { contains: ['tag1', 'tag2', /* ... 100 tags */] } } // Slow
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
4. **Use pagination for large result sets:**
|
|
259
|
-
```typescript
|
|
260
|
-
{
|
|
261
|
-
where: { isActive: true },
|
|
262
|
-
limit: 100,
|
|
263
|
-
skip: 0,
|
|
264
|
-
order: ['id ASC']
|
|
265
|
-
}
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
## See Also
|
|
270
|
-
|
|
271
|
-
- **Detailed Guides:**
|
|
272
|
-
- [Comparison Operators](./comparison-operators.md)
|
|
273
|
-
- [Logical Operators](./logical-operators.md)
|
|
274
|
-
- [Pattern Matching](./pattern-matching.md)
|
|
275
|
-
- [JSON Filtering](./json-filtering.md)
|
|
276
|
-
- [Array Operators](./array-operators.md)
|
|
277
|
-
|
|
278
|
-
- **Related References:**
|
|
279
|
-
- [Repositories](../repositories/) - Using filters in repository queries
|
|
280
|
-
- [Models](../models.md) - Defining model schemas
|
|
281
|
-
|
|
282
|
-
- **Usage Guides:**
|
|
283
|
-
- [Application Usage](./application-usage.md) - Filters in the full stack
|
|
284
|
-
- [Use Case Gallery](./use-cases.md) - Real-world examples
|
|
285
|
-
- [Pro Tips & Edge Cases](./tips.md) - Advanced patterns
|
|
286
|
-
|
|
287
|
-
- **Quick Reference:**
|
|
288
|
-
- [Main Quick Reference](/references/quick-reference.md) - All IGNIS APIs
|
|
117
|
+
## Operators
|
|
118
|
+
|
|
119
|
+
Each operator family and every long-form topic has its own page:
|
|
120
|
+
|
|
121
|
+
| Page | Covers |
|
|
122
|
+
|---|---|
|
|
123
|
+
| [Quick Reference](./quick-reference) | Every operator, one line each - the fast lookup |
|
|
124
|
+
| [Comparison Operators](./comparison-operators) | `eq`, `ne`/`neq`, `gt`, `gte`, `lt`, `lte` |
|
|
125
|
+
| [Null Operators](./null-operators) | `is`, `isn`, direct `null`, `exists`/`notExists` |
|
|
126
|
+
| [List Operators](./list-operators) | `in`/`inq`, `nin` |
|
|
127
|
+
| [Range Operators](./range-operators) | `between`, `notBetween` |
|
|
128
|
+
| [Pattern Matching](./pattern-matching) | `like`, `nlike`, `ilike`, `nilike`, `regexp`, `iregexp` |
|
|
129
|
+
| [Logical Operators](./logical-operators) | Implicit/explicit `and`, `or`, `not`, empty-group semantics |
|
|
130
|
+
| [Array Operators](./array-operators) | `contains`, `containedBy`, `overlaps` (PostgreSQL array columns) |
|
|
131
|
+
| [JSON Filtering](./json-filtering) | Dot-path queries into JSON/JSONB columns |
|
|
132
|
+
| [Fields, Order & Pagination](./fields-order-pagination) | `fields`, `order`, `limit`/`skip`/`offset`, `defaultLimit` |
|
|
133
|
+
| [Default Filter](./default-filter) | `settings.defaultFilter`, the collision/narrowing law, `shouldSkipDefaultFilter` |
|
|
134
|
+
| [Application Usage](./application-usage) | How a filter flows controller -> service -> repository |
|
|
135
|
+
| [Use Case Gallery](./use-cases) | Real-world filters with the SQL they produce |
|
|
136
|
+
| [Tips & Edge Cases](./tips) | Performance notes and common gotchas |
|
|
137
|
+
|
|
138
|
+
## See also
|
|
139
|
+
|
|
140
|
+
- [Repositories](../repositories/) - the `find`/`count`/`updateAll`/`deleteAll` verbs that take a `filter`
|
|
141
|
+
- [Models](/references/base/models) - `settings.defaultFilter` and `settings.hiddenProperties`
|
|
142
|
+
- [Building a CRUD API](/guides/tutorials/building-a-crud-api) - filters in a real endpoint
|
|
143
|
+
- [Quick Reference Card](/references/quick-reference.md) - all IGNIS APIs on one page
|
|
144
|
+
|
|
145
|
+
**Files:**
|
|
146
|
+
|
|
147
|
+
- [`packages/core-server/src/connectors/relational/repositories/dialect/filter.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core-server/src/connectors/relational/repositories/dialect/filter.ts) - `FilterBuilder`, translates `TFilter` to Drizzle/SQL
|
|
148
|
+
- [`packages/filter/src/common/types.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/filter/src/common/types.ts) - `TFilter`/`TInclusion` types
|
|
149
|
+
- [`packages/filter/src/common/operators.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/filter/src/common/operators.ts) - `QueryOperators`/`Sorts` constants
|