@rhino-dev/rhino-nestjs 4.3.1 → 4.4.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rhino-dev/rhino-nestjs",
3
- "version": "4.3.1",
3
+ "version": "4.4.0",
4
4
  "description": "Rhino for NestJS — auto-generated REST APIs from model definitions.",
5
5
  "author": "Bruno Cipolla <bruno@codalio.com>",
6
6
  "license": "MIT",
@@ -138,3 +138,46 @@ npm test
138
138
  - Returning `{}` from `apply()` adds no filter — safe default for "no restriction needed".
139
139
  - Scopes are AND-merged with the org filter and user-supplied filters. Do not add an `AND: [...]` wrapper yourself.
140
140
  - Do not use `req.user` or `request()` inside a scope class — the user context is passed as a parameter.
141
+
142
+ ## Named Scopes (`?scope=<key>`) — client-selectable, opt-in
143
+
144
+ The `scopes` array above is a *global* scope: it applies to every query, always.
145
+ A **named scope** is different — it is client-selectable via `?scope=<key>` and
146
+ applies only to `index`/`trashed` (not `show`/`update`/`destroy`). Implement
147
+ `RhinoNamedScope` (from the package root) — its `apply(ctx)` takes **only** the
148
+ context and returns a Prisma where-*fragment*; Rhino AND-wraps it into the query,
149
+ so a named scope can never drop the org/filter/search/soft-delete constraints
150
+ (do NOT add your own `AND: [...]` wrapper here).
151
+
152
+ ```typescript
153
+ import type { RhinoNamedScope, ScopeContext } from '@rhino-dev/rhino-nestjs';
154
+
155
+ export class AvailableForDriversScope implements RhinoNamedScope {
156
+ apply(ctx: ScopeContext): Record<string, any> {
157
+ if (!ctx.user) return { id: { in: [] } }; // fail closed with no user
158
+ return { status: 'active', ownerId: ctx.user.id };
159
+ }
160
+ }
161
+
162
+ export class ActiveScope implements RhinoNamedScope {
163
+ apply(): Record<string, any> {
164
+ return { status: 'active' };
165
+ }
166
+ }
167
+ ```
168
+
169
+ Register the callable keys on the model. Only declared keys are callable; an
170
+ unknown or prototype key (`?scope=constructor`) is rejected with **403**. A
171
+ non-string `?scope` (repeated/array param) is also **403**. `defaultScope` is
172
+ applied when no `?scope` is sent and is validated at boot to be a declared key.
173
+
174
+ ```typescript
175
+ routes: {
176
+ model: 'route',
177
+ namedScopes: {
178
+ active: ActiveScope,
179
+ availableForDrivers: AvailableForDriversScope,
180
+ },
181
+ defaultScope: 'active', // must be a key of namedScopes
182
+ }
183
+ ```