@aooth/arbac 0.2.1 → 0.2.3
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/dist/index.cjs +9 -18
- package/dist/index.d.cts +37 -57
- package/dist/index.d.mts +37 -57
- package/dist/index.mjs +9 -18
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
|
|
2
|
+
// src/define-role.ts
|
|
3
3
|
var RoleBuilderImpl = class {
|
|
4
4
|
_id;
|
|
5
5
|
_name;
|
|
@@ -65,8 +65,7 @@ var RoleBuilderImpl = class {
|
|
|
65
65
|
function defineRole() {
|
|
66
66
|
return new RoleBuilderImpl();
|
|
67
67
|
}
|
|
68
|
-
|
|
69
|
-
//#region src/define-privilege.ts
|
|
68
|
+
// src/define-privilege.ts
|
|
70
69
|
/**
|
|
71
70
|
* Define a reusable privilege factory.
|
|
72
71
|
*
|
|
@@ -91,8 +90,7 @@ function definePrivilege() {
|
|
|
91
90
|
return (...args) => () => factory(...args);
|
|
92
91
|
};
|
|
93
92
|
}
|
|
94
|
-
|
|
95
|
-
//#region src/scope/controls.ts
|
|
93
|
+
// src/scope/controls.ts
|
|
96
94
|
/**
|
|
97
95
|
* Controls whose values can be sensibly whitelisted via `readonly string[]`.
|
|
98
96
|
*
|
|
@@ -208,8 +206,7 @@ function intersectControlsPolicy(a, b) {
|
|
|
208
206
|
}
|
|
209
207
|
return result;
|
|
210
208
|
}
|
|
211
|
-
|
|
212
|
-
//#region src/scope/filter.ts
|
|
209
|
+
// src/scope/filter.ts
|
|
213
210
|
/**
|
|
214
211
|
* A filter that matches no rows (`{ $or: [] }`) — what a denied read, or a
|
|
215
212
|
* conjunction whose field intersection is empty, filters by. Shared; never
|
|
@@ -284,8 +281,7 @@ function canOptimizeToIn(scopes) {
|
|
|
284
281
|
}
|
|
285
282
|
return true;
|
|
286
283
|
}
|
|
287
|
-
|
|
288
|
-
//#region src/scope/projection.ts
|
|
284
|
+
// src/scope/projection.ts
|
|
289
285
|
/**
|
|
290
286
|
* Determine whether a projection is in inclusion mode (all 1s),
|
|
291
287
|
* exclusion mode (all 0s), or empty (`{}`, no restriction).
|
|
@@ -481,8 +477,7 @@ function intersectProjections(a, b, childrenOf) {
|
|
|
481
477
|
function restrictProjection(desired, accessControl, childrenOf) {
|
|
482
478
|
return intersectProjections(desired, accessControl, childrenOf) ?? { ...accessControl };
|
|
483
479
|
}
|
|
484
|
-
|
|
485
|
-
//#region src/scope/db-scope.ts
|
|
480
|
+
// src/scope/db-scope.ts
|
|
486
481
|
/**
|
|
487
482
|
* The built-in {@link TDbScope} keys — the facets the scope algebra itself
|
|
488
483
|
* combines. Any other key is a custom (declaration-merged) scope field, which
|
|
@@ -887,8 +882,7 @@ function conjoinWith(ea, eb, fields) {
|
|
|
887
882
|
function stableKey(value) {
|
|
888
883
|
return JSON.stringify(value, (_k, v) => typeof v === "bigint" ? `${v}n` : v);
|
|
889
884
|
}
|
|
890
|
-
|
|
891
|
-
//#region src/db-privileges.ts
|
|
885
|
+
// src/db-privileges.ts
|
|
892
886
|
/**
|
|
893
887
|
* Read-side handler actions of an `AsDbController` table: `query`, `pages`,
|
|
894
888
|
* `getOne`, `getOneComposite`, `geo`, `meta`, `metaForm`.
|
|
@@ -1044,8 +1038,7 @@ function defineTableAccess(resource, def) {
|
|
|
1044
1038
|
function isList(v) {
|
|
1045
1039
|
return Array.isArray(v);
|
|
1046
1040
|
}
|
|
1047
|
-
|
|
1048
|
-
//#region src/codegen/extract.ts
|
|
1041
|
+
// src/codegen/extract.ts
|
|
1049
1042
|
function hasWildcard(s) {
|
|
1050
1043
|
return s.includes("*");
|
|
1051
1044
|
}
|
|
@@ -1078,8 +1071,7 @@ function extractResourceActions(roles, options) {
|
|
|
1078
1071
|
allActions
|
|
1079
1072
|
};
|
|
1080
1073
|
}
|
|
1081
|
-
|
|
1082
|
-
//#region src/codegen/generate.ts
|
|
1074
|
+
// src/codegen/generate.ts
|
|
1083
1075
|
/**
|
|
1084
1076
|
* Escape a string for safe embedding inside a TypeScript double-quoted literal.
|
|
1085
1077
|
* Handles backslashes, double quotes, and control chars so resource/action
|
|
@@ -1115,7 +1107,6 @@ function generateResourceTypes(map, options) {
|
|
|
1115
1107
|
lines.push("");
|
|
1116
1108
|
return lines.join("\n");
|
|
1117
1109
|
}
|
|
1118
|
-
//#endregion
|
|
1119
1110
|
exports.DB_SCOPE_KEYS = DB_SCOPE_KEYS;
|
|
1120
1111
|
exports.DENY_FILTER = DENY_FILTER;
|
|
1121
1112
|
exports.INHERITED_CONJUNCTION = INHERITED_CONJUNCTION;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { TArbacRole, TArbacRule } from "@aooth/arbac-core";
|
|
2
2
|
export * from "@aooth/arbac-core";
|
|
3
|
-
//#region src/define-role.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* A privilege function produces an array of rules when called.
|
|
6
5
|
* Created by `definePrivilege()` or manually.
|
|
@@ -62,9 +61,7 @@ interface RoleBuilder<TUserAttrs, TScope> {
|
|
|
62
61
|
* .deny("articles", "publish")
|
|
63
62
|
* .build();
|
|
64
63
|
*/
|
|
65
|
-
declare function defineRole<TUserAttrs extends object = object, TScope extends object = object>(): RoleBuilder<TUserAttrs, TScope>;
|
|
66
|
-
//#endregion
|
|
67
|
-
//#region src/define-privilege.d.ts
|
|
64
|
+
export declare function defineRole<TUserAttrs extends object = object, TScope extends object = object>(): RoleBuilder<TUserAttrs, TScope>;
|
|
68
65
|
/**
|
|
69
66
|
* Define a reusable privilege factory.
|
|
70
67
|
*
|
|
@@ -84,9 +81,7 @@ declare function defineRole<TUserAttrs extends object = object, TScope extends o
|
|
|
84
81
|
* .use(canManageUsers((attrs) => ({ dept: attrs.dept })))
|
|
85
82
|
* .build();
|
|
86
83
|
*/
|
|
87
|
-
declare function definePrivilege<TUserAttrs extends object = object, TScope extends object = object>(): <TArgs extends unknown[]>(factory: (...args: TArgs) => TArbacRule<TUserAttrs, TScope>[]) => ((...args: TArgs) => TPrivilegeFunction<TUserAttrs, TScope>);
|
|
88
|
-
//#endregion
|
|
89
|
-
//#region src/scope/types.d.ts
|
|
84
|
+
export declare function definePrivilege<TUserAttrs extends object = object, TScope extends object = object>(): <TArgs extends unknown[]>(factory: (...args: TArgs) => TArbacRule<TUserAttrs, TScope>[]) => ((...args: TArgs) => TPrivilegeFunction<TUserAttrs, TScope>);
|
|
90
85
|
/**
|
|
91
86
|
* Mongo-style field projection: `{ field: 0 | 1 }`.
|
|
92
87
|
* - All 1s = inclusion mode (only listed fields allowed)
|
|
@@ -122,33 +117,31 @@ type TScopeFilter = Record<string, unknown>;
|
|
|
122
117
|
* supported in v1; supplying a whitelist throws at scope-evaluation time.
|
|
123
118
|
*/
|
|
124
119
|
type ControlGate = boolean | readonly string[];
|
|
125
|
-
//#endregion
|
|
126
|
-
//#region src/db-privileges.d.ts
|
|
127
120
|
/**
|
|
128
121
|
* Read-side handler actions of an `AsDbController` table: `query`, `pages`,
|
|
129
122
|
* `getOne`, `getOneComposite`, `geo`, `meta`, `metaForm`.
|
|
130
123
|
*/
|
|
131
|
-
declare const TABLE_READ_ACTIONS: readonly ["query", "pages", "getOne", "getOneComposite", "geo", "meta", "metaForm"];
|
|
124
|
+
export declare const TABLE_READ_ACTIONS: readonly ["query", "pages", "getOne", "getOneComposite", "geo", "meta", "metaForm"];
|
|
132
125
|
/** Write-side handler actions of an `AsDbController` table. */
|
|
133
|
-
declare const TABLE_WRITE_ACTIONS: readonly ["insert", "update", "replace", "remove", "removeComposite"];
|
|
126
|
+
export declare const TABLE_WRITE_ACTIONS: readonly ["insert", "update", "replace", "remove", "removeComposite"];
|
|
134
127
|
/** The `/meta` + `/meta/form/:name` handler actions (a subset of {@link TABLE_READ_ACTIONS}). */
|
|
135
|
-
declare const TABLE_META_ACTIONS: readonly ["meta", "metaForm"];
|
|
128
|
+
export declare const TABLE_META_ACTIONS: readonly ["meta", "metaForm"];
|
|
136
129
|
/** Table operation names accepted by {@link allowTableOps} / {@link defineTableAccess}. */
|
|
137
130
|
type TTableOp = "read" | "meta" | "insert" | "update" | "replace" | "remove";
|
|
138
131
|
/**
|
|
139
132
|
* Operation → handler actions. `meta` is the form-metadata subset of `read`,
|
|
140
133
|
* for write-only principals that still render forms from `/meta`.
|
|
141
134
|
*/
|
|
142
|
-
declare const TABLE_OP_ACTIONS: Readonly<Record<TTableOp, readonly string[]>>;
|
|
135
|
+
export declare const TABLE_OP_ACTIONS: Readonly<Record<TTableOp, readonly string[]>>;
|
|
143
136
|
/** A rule scope; `null` / `undefined` = this rule admits nothing (deny for it). */
|
|
144
137
|
type ScopeFn<TUserAttrs, TScope> = (attrs: TUserAttrs, userId: string) => TScope | null | undefined;
|
|
145
138
|
interface ScopeOpts<TUserAttrs, TScope> {
|
|
146
139
|
scope?: ScopeFn<TUserAttrs, TScope>;
|
|
147
140
|
}
|
|
148
141
|
/** Read-side actions on an `AsDbController` table — see {@link TABLE_READ_ACTIONS}. */
|
|
149
|
-
declare function allowTableRead<TUserAttrs extends object = object, TScope extends object = object>(resource: string, opts?: ScopeOpts<TUserAttrs, TScope>): TPrivilegeFunction<TUserAttrs, TScope>;
|
|
142
|
+
export declare function allowTableRead<TUserAttrs extends object = object, TScope extends object = object>(resource: string, opts?: ScopeOpts<TUserAttrs, TScope>): TPrivilegeFunction<TUserAttrs, TScope>;
|
|
150
143
|
/** All actions on an `AsDbController` table: read + `insert`, `update`, `replace`, `remove`, `removeComposite`. */
|
|
151
|
-
declare function allowTableWrite<TUserAttrs extends object = object, TScope extends object = object>(resource: string, opts?: ScopeOpts<TUserAttrs, TScope>): TPrivilegeFunction<TUserAttrs, TScope>;
|
|
144
|
+
export declare function allowTableWrite<TUserAttrs extends object = object, TScope extends object = object>(resource: string, opts?: ScopeOpts<TUserAttrs, TScope>): TPrivilegeFunction<TUserAttrs, TScope>;
|
|
152
145
|
/**
|
|
153
146
|
* Selected operations on an `AsDbController` table, sharing a scope — e.g. an
|
|
154
147
|
* insert-only form principal: `allowTableOps("leads", ["insert", "meta"])`.
|
|
@@ -160,9 +153,9 @@ declare function allowTableWrite<TUserAttrs extends object = object, TScope exte
|
|
|
160
153
|
*
|
|
161
154
|
* Throws on an unknown op name.
|
|
162
155
|
*/
|
|
163
|
-
declare function allowTableOps<TUserAttrs extends object = object, TScope extends object = object>(resource: string, ops: readonly TTableOp[], opts?: ScopeOpts<TUserAttrs, TScope>): TPrivilegeFunction<TUserAttrs, TScope>;
|
|
156
|
+
export declare function allowTableOps<TUserAttrs extends object = object, TScope extends object = object>(resource: string, ops: readonly TTableOp[], opts?: ScopeOpts<TUserAttrs, TScope>): TPrivilegeFunction<TUserAttrs, TScope>;
|
|
164
157
|
/** One or more declarative actions on the same table, sharing a scope. */
|
|
165
|
-
declare function allowTableAction<TUserAttrs extends object = object, TScope extends object = object>(resource: string, name: string | string[], opts?: ScopeOpts<TUserAttrs, TScope>): TPrivilegeFunction<TUserAttrs, TScope>;
|
|
158
|
+
export declare function allowTableAction<TUserAttrs extends object = object, TScope extends object = object>(resource: string, name: string | string[], opts?: ScopeOpts<TUserAttrs, TScope>): TPrivilegeFunction<TUserAttrs, TScope>;
|
|
166
159
|
/** The scope keys {@link defineTableAccess} conjoins instead of overriding. */
|
|
167
160
|
interface TTableAccessScope {
|
|
168
161
|
filter?: TScopeFilter;
|
|
@@ -214,9 +207,7 @@ interface TTableAccessDef<TUserAttrs, TScope> {
|
|
|
214
207
|
* });
|
|
215
208
|
* ```
|
|
216
209
|
*/
|
|
217
|
-
declare function defineTableAccess<TUserAttrs extends object = object, TScope extends TTableAccessScope = TTableAccessScope>(resource: string, def: TTableAccessDef<TUserAttrs, TScope>): TPrivilegeFunction<TUserAttrs, TScope>;
|
|
218
|
-
//#endregion
|
|
219
|
-
//#region src/scope/projection.d.ts
|
|
210
|
+
export declare function defineTableAccess<TUserAttrs extends object = object, TScope extends TTableAccessScope = TTableAccessScope>(resource: string, def: TTableAccessDef<TUserAttrs, TScope>): TPrivilegeFunction<TUserAttrs, TScope>;
|
|
220
211
|
type TProjectionMode = "include" | "exclude" | "empty";
|
|
221
212
|
/**
|
|
222
213
|
* Determine whether a projection is in inclusion mode (all 1s),
|
|
@@ -224,7 +215,7 @@ type TProjectionMode = "include" | "exclude" | "empty";
|
|
|
224
215
|
*
|
|
225
216
|
* @throws when a single projection mixes 0 and 1 values
|
|
226
217
|
*/
|
|
227
|
-
declare function getProjectionMode(proj: TProjection): TProjectionMode;
|
|
218
|
+
export declare function getProjectionMode(proj: TProjection): TProjectionMode;
|
|
228
219
|
/**
|
|
229
220
|
* Check whether a dot-path field is allowed by a projection.
|
|
230
221
|
*
|
|
@@ -233,7 +224,7 @@ declare function getProjectionMode(proj: TProjection): TProjectionMode;
|
|
|
233
224
|
* Exclusion mode: a field is allowed unless it or any of its parents is excluded.
|
|
234
225
|
* Empty projection: every field is allowed.
|
|
235
226
|
*/
|
|
236
|
-
declare function isFieldAllowed(field: string, projection: TProjection): boolean;
|
|
227
|
+
export declare function isFieldAllowed(field: string, projection: TProjection): boolean;
|
|
237
228
|
/**
|
|
238
229
|
* Combines projections from multiple RBAC role grants under additive semantics:
|
|
239
230
|
* more roles = broader access. Each projection represents a set of allowed fields:
|
|
@@ -255,7 +246,7 @@ declare function isFieldAllowed(field: string, projection: TProjection): boolean
|
|
|
255
246
|
*
|
|
256
247
|
* @throws when a single projection mixes 1 and 0 keys, or contains an invalid value
|
|
257
248
|
*/
|
|
258
|
-
declare function unionProjections(...projections: TProjection[]): TProjection;
|
|
249
|
+
export declare function unionProjections(...projections: TProjection[]): TProjection;
|
|
259
250
|
/**
|
|
260
251
|
* Direct child field paths of a nested-object path (`a` → `["a.b", "a.c"]`),
|
|
261
252
|
* from the model schema; `[]` for a leaf. Lets a projection intersection
|
|
@@ -269,7 +260,7 @@ type TProjectionChildren = (path: string) => readonly string[];
|
|
|
269
260
|
* columns, so a parent key alone would strip nothing. Without `childrenOf`,
|
|
270
261
|
* or for an inclusion / empty projection, the input is returned unchanged.
|
|
271
262
|
*/
|
|
272
|
-
declare function expandExcludeToLeaves(projection: TProjection, childrenOf: TProjectionChildren | undefined): TProjection;
|
|
263
|
+
export declare function expandExcludeToLeaves(projection: TProjection, childrenOf: TProjectionChildren | undefined): TProjection;
|
|
273
264
|
/**
|
|
274
265
|
* The exact field intersection of two projections, by PATH — never wider than
|
|
275
266
|
* either side. Returns `null` when no field survives (a disjoint pair, or
|
|
@@ -285,7 +276,7 @@ declare function expandExcludeToLeaves(projection: TProjection, childrenOf: TPro
|
|
|
285
276
|
*
|
|
286
277
|
* @param childrenOf - optional schema lookup for exact nested subtraction
|
|
287
278
|
*/
|
|
288
|
-
declare function intersectProjections(a: TProjection, b: TProjection, childrenOf?: TProjectionChildren): TProjection | null;
|
|
279
|
+
export declare function intersectProjections(a: TProjection, b: TProjection, childrenOf?: TProjectionChildren): TProjection | null;
|
|
289
280
|
/**
|
|
290
281
|
* Restrict a desired projection to only fields allowed by an access-control projection.
|
|
291
282
|
*
|
|
@@ -304,15 +295,13 @@ declare function intersectProjections(a: TProjection, b: TProjection, childrenOf
|
|
|
304
295
|
* @param accessControl - the projection allowed by RBAC
|
|
305
296
|
* @param childrenOf - optional schema lookup for exact nested subtraction
|
|
306
297
|
*/
|
|
307
|
-
declare function restrictProjection(desired: TProjection, accessControl: TProjection, childrenOf?: TProjectionChildren): TProjection;
|
|
308
|
-
//#endregion
|
|
309
|
-
//#region src/scope/filter.d.ts
|
|
298
|
+
export declare function restrictProjection(desired: TProjection, accessControl: TProjection, childrenOf?: TProjectionChildren): TProjection;
|
|
310
299
|
/**
|
|
311
300
|
* A filter that matches no rows (`{ $or: [] }`) — what a denied read, or a
|
|
312
301
|
* conjunction whose field intersection is empty, filters by. Shared; never
|
|
313
302
|
* mutate it.
|
|
314
303
|
*/
|
|
315
|
-
declare const DENY_FILTER: Readonly<TScopeFilter>;
|
|
304
|
+
export declare const DENY_FILTER: Readonly<TScopeFilter>;
|
|
316
305
|
/**
|
|
317
306
|
* Merge multiple scope filters into a single filter using `$or` semantics.
|
|
318
307
|
*
|
|
@@ -328,7 +317,7 @@ declare const DENY_FILTER: Readonly<TScopeFilter>;
|
|
|
328
317
|
*
|
|
329
318
|
* @returns the merged filter, or `undefined` for unrestricted access
|
|
330
319
|
*/
|
|
331
|
-
declare function mergeScopeFilters(scopes: TScopeFilter[]): TScopeFilter | undefined;
|
|
320
|
+
export declare function mergeScopeFilters(scopes: TScopeFilter[]): TScopeFilter | undefined;
|
|
332
321
|
/**
|
|
333
322
|
* Conjoin two filters under `$and` semantics — a row survives only if BOTH
|
|
334
323
|
* sides admit it. The restrict-only combiner, used wherever two independent
|
|
@@ -351,9 +340,7 @@ declare function mergeScopeFilters(scopes: TScopeFilter[]): TScopeFilter | undef
|
|
|
351
340
|
*
|
|
352
341
|
* @returns the conjoined filter, or `undefined` when BOTH sides are unrestricted.
|
|
353
342
|
*/
|
|
354
|
-
declare function conjoinScopeFilters(a: TScopeFilter | undefined, b: TScopeFilter | undefined): TScopeFilter | undefined;
|
|
355
|
-
//#endregion
|
|
356
|
-
//#region src/scope/controls.d.ts
|
|
343
|
+
export declare function conjoinScopeFilters(a: TScopeFilter | undefined, b: TScopeFilter | undefined): TScopeFilter | undefined;
|
|
357
344
|
/**
|
|
358
345
|
* Union per-role `controls` policies. Additive RBAC semantics: more roles =
|
|
359
346
|
* broader access, mirroring how `mergeScopeFilters` and `unionProjections`
|
|
@@ -386,7 +373,7 @@ declare function conjoinScopeFilters(a: TScopeFilter | undefined, b: TScopeFilte
|
|
|
386
373
|
*
|
|
387
374
|
* @throws when a non-whitelistable control is given a `readonly string[]` gate.
|
|
388
375
|
*/
|
|
389
|
-
declare function unionControlsPolicy(scopes: ReadonlyArray<{
|
|
376
|
+
export declare function unionControlsPolicy(scopes: ReadonlyArray<{
|
|
390
377
|
controls?: Record<string, ControlGate>;
|
|
391
378
|
}>): Record<string, ControlGate>;
|
|
392
379
|
/**
|
|
@@ -405,9 +392,7 @@ declare function unionControlsPolicy(scopes: ReadonlyArray<{
|
|
|
405
392
|
* @returns merged policy; keys absent from the result mean "allowed" (callers
|
|
406
393
|
* treat a missing key as `true`), matching {@link unionControlsPolicy}.
|
|
407
394
|
*/
|
|
408
|
-
declare function intersectControlsPolicy(a: Record<string, ControlGate>, b: Record<string, ControlGate>): Record<string, ControlGate>;
|
|
409
|
-
//#endregion
|
|
410
|
-
//#region src/scope/db-scope.d.ts
|
|
395
|
+
export declare function intersectControlsPolicy(a: Record<string, ControlGate>, b: Record<string, ControlGate>): Record<string, ControlGate>;
|
|
411
396
|
/**
|
|
412
397
|
* The DB scope shape the scope algebra reads — structurally what
|
|
413
398
|
* `ArbacDbScope` (`@aooth/arbac-moost`) carries. Every facet is optional.
|
|
@@ -433,7 +418,7 @@ interface TDbScope {
|
|
|
433
418
|
*
|
|
434
419
|
* @since 0.1.72
|
|
435
420
|
*/
|
|
436
|
-
declare const DB_SCOPE_KEYS: readonly string[];
|
|
421
|
+
export declare const DB_SCOPE_KEYS: readonly string[];
|
|
437
422
|
/**
|
|
438
423
|
* The conjunction rule of ONE custom scope field (a key an app adds to its
|
|
439
424
|
* scope type by declaration merging). {@link conjoinScopes} calls `conjoin`
|
|
@@ -471,7 +456,7 @@ interface TScopeFieldRule<S extends object = TDbScope> {
|
|
|
471
456
|
*
|
|
472
457
|
* @since 0.1.72
|
|
473
458
|
*/
|
|
474
|
-
declare class ScopeFieldConfigError extends Error {
|
|
459
|
+
export declare class ScopeFieldConfigError extends Error {
|
|
475
460
|
/** The custom scope field without a rule. */
|
|
476
461
|
readonly field: string;
|
|
477
462
|
readonly name = "ScopeFieldConfigError";
|
|
@@ -531,14 +516,14 @@ interface TEffectiveDbScope<S extends TDbScope = TDbScope> {
|
|
|
531
516
|
*
|
|
532
517
|
* @since 0.1.72
|
|
533
518
|
*/
|
|
534
|
-
declare function effectiveScope<S extends TDbScope>(scopes: readonly S[]): TEffectiveDbScope<S>;
|
|
519
|
+
export declare function effectiveScope<S extends TDbScope>(scopes: readonly S[]): TEffectiveDbScope<S>;
|
|
535
520
|
/**
|
|
536
521
|
* Intersection of enforcement: an entry is enforced only when EVERY input
|
|
537
522
|
* enables it (`true` enables all). No input → nothing enforced.
|
|
538
523
|
*
|
|
539
524
|
* @since 0.1.72
|
|
540
525
|
*/
|
|
541
|
-
declare function intersectEnabled<K>(inputs: Iterable<true | ReadonlySet<K>>): true | Set<K>;
|
|
526
|
+
export declare function intersectEnabled<K>(inputs: Iterable<true | ReadonlySet<K>>): true | Set<K>;
|
|
542
527
|
/**
|
|
543
528
|
* The unified empty-scope rule for an evaluation outcome: denied → `undefined`;
|
|
544
529
|
* allowed with `scopes` absent (a scope-agnostic evaluator) → `[{}]`
|
|
@@ -547,7 +532,7 @@ declare function intersectEnabled<K>(inputs: Iterable<true | ReadonlySet<K>>): t
|
|
|
547
532
|
*
|
|
548
533
|
* @since 0.1.72
|
|
549
534
|
*/
|
|
550
|
-
declare function normalizeScopes<S extends object>(outcome: {
|
|
535
|
+
export declare function normalizeScopes<S extends object>(outcome: {
|
|
551
536
|
allowed: boolean;
|
|
552
537
|
scopes?: ReadonlyArray<S | null | undefined>;
|
|
553
538
|
}): S[] | undefined;
|
|
@@ -558,7 +543,7 @@ declare function normalizeScopes<S extends object>(outcome: {
|
|
|
558
543
|
*
|
|
559
544
|
* @since 0.1.72
|
|
560
545
|
*/
|
|
561
|
-
declare function unionOutcomes<S extends object>(outcomes: ReadonlyArray<{
|
|
546
|
+
export declare function unionOutcomes<S extends object>(outcomes: ReadonlyArray<{
|
|
562
547
|
allowed: boolean;
|
|
563
548
|
scopes?: ReadonlyArray<S | null | undefined>;
|
|
564
549
|
}>): S[] | undefined;
|
|
@@ -576,7 +561,7 @@ interface TRowPolicy {
|
|
|
576
561
|
*
|
|
577
562
|
* @since 0.1.72
|
|
578
563
|
*/
|
|
579
|
-
declare function conjoinRowPolicies(a: TRowPolicy, b: TRowPolicy): TRowPolicy;
|
|
564
|
+
export declare function conjoinRowPolicies(a: TRowPolicy, b: TRowPolicy): TRowPolicy;
|
|
580
565
|
/** Options of {@link conjoinScopes}. */
|
|
581
566
|
interface TConjoinScopesOptions<S extends TDbScope> {
|
|
582
567
|
/** Schema lookup to subtract a nested exclusion exactly (without it: fail closed). */
|
|
@@ -616,7 +601,7 @@ interface TConjoinScopesOptions<S extends TDbScope> {
|
|
|
616
601
|
*
|
|
617
602
|
* @since 0.1.72
|
|
618
603
|
*/
|
|
619
|
-
declare function conjoinScopes<S extends TDbScope>(a: readonly S[], b: readonly S[], opts?: TConjoinScopesOptions<S>): S;
|
|
604
|
+
export declare function conjoinScopes<S extends TDbScope>(a: readonly S[], b: readonly S[], opts?: TConjoinScopesOptions<S>): S;
|
|
620
605
|
/** Options of {@link applyScopeFieldFilters}. @since 0.1.72 */
|
|
621
606
|
interface TApplyScopeFieldFiltersOptions {
|
|
622
607
|
/**
|
|
@@ -639,7 +624,7 @@ interface TApplyScopeFieldFiltersOptions {
|
|
|
639
624
|
*
|
|
640
625
|
* @since 0.1.72
|
|
641
626
|
*/
|
|
642
|
-
declare function applyScopeFieldFilters<S extends TDbScope>(scopes: readonly S[], fields: TScopeFieldRules<S> | undefined, opts?: TApplyScopeFieldFiltersOptions): readonly S[];
|
|
627
|
+
export declare function applyScopeFieldFilters<S extends TDbScope>(scopes: readonly S[], fields: TScopeFieldRules<S> | undefined, opts?: TApplyScopeFieldFiltersOptions): readonly S[];
|
|
643
628
|
/**
|
|
644
629
|
* Marks a `with.<rel>` sub-scope {@link conjoinScopes} built from ONE side's
|
|
645
630
|
* declaration. The other side is silent on the relation, so ITS policy for
|
|
@@ -650,18 +635,16 @@ declare function applyScopeFieldFilters<S extends TDbScope>(scopes: readonly S[]
|
|
|
650
635
|
*
|
|
651
636
|
* @since 0.1.72
|
|
652
637
|
*/
|
|
653
|
-
declare const INHERITED_CONJUNCTION: unique symbol;
|
|
638
|
+
export declare const INHERITED_CONJUNCTION: unique symbol;
|
|
654
639
|
/** A `with` sub-scope marked {@link INHERITED_CONJUNCTION}. @since 0.1.72 */
|
|
655
|
-
declare function needsInheritedConjunction(scope: object): boolean;
|
|
640
|
+
export declare function needsInheritedConjunction(scope: object): boolean;
|
|
656
641
|
/**
|
|
657
642
|
* A stable string key for a JSON-like value (bigint-safe) — for
|
|
658
643
|
* de-duplicating filters / tuples and comparing them structurally.
|
|
659
644
|
*
|
|
660
645
|
* @since 0.1.72
|
|
661
646
|
*/
|
|
662
|
-
declare function stableKey(value: unknown): string;
|
|
663
|
-
//#endregion
|
|
664
|
-
//#region src/codegen/extract.d.ts
|
|
647
|
+
export declare function stableKey(value: unknown): string;
|
|
665
648
|
interface TResourceActionMap {
|
|
666
649
|
/** Map of resource string → Set of action strings */
|
|
667
650
|
resources: Map<string, Set<string>>;
|
|
@@ -676,11 +659,9 @@ interface TResourceActionMap {
|
|
|
676
659
|
* @param roles - Array of built role definitions
|
|
677
660
|
* @param options.includeWildcards - If false (default), skip entries containing `*` or `**`
|
|
678
661
|
*/
|
|
679
|
-
declare function extractResourceActions(roles: TArbacRole<unknown, unknown>[], options?: {
|
|
662
|
+
export declare function extractResourceActions(roles: TArbacRole<unknown, unknown>[], options?: {
|
|
680
663
|
includeWildcards?: boolean;
|
|
681
664
|
}): TResourceActionMap;
|
|
682
|
-
//#endregion
|
|
683
|
-
//#region src/codegen/generate.d.ts
|
|
684
665
|
interface TCodegenOptions {
|
|
685
666
|
/** Name for the resource union type. Default: "Resource" */
|
|
686
667
|
resourceTypeName?: string;
|
|
@@ -694,6 +675,5 @@ interface TCodegenOptions {
|
|
|
694
675
|
/**
|
|
695
676
|
* Generate TypeScript source defining union types for resources and actions.
|
|
696
677
|
*/
|
|
697
|
-
declare function generateResourceTypes(map: TResourceActionMap, options?: TCodegenOptions): string;
|
|
698
|
-
|
|
699
|
-
export { type ControlGate, DB_SCOPE_KEYS, DENY_FILTER, INHERITED_CONJUNCTION, type RoleBuilder, ScopeFieldConfigError, TABLE_META_ACTIONS, TABLE_OP_ACTIONS, TABLE_READ_ACTIONS, TABLE_WRITE_ACTIONS, type TApplyScopeFieldFiltersOptions, type TCodegenOptions, type TConjoinScopesOptions, type TDbScope, type TEffectiveDbScope, type TPrivilegeFunction, type TProjection, type TProjectionChildren, type TProjectionMode, type TResourceActionMap, type TRowPolicy, type TScopeFieldRule, type TScopeFieldRules, type TScopeFilter, type TTableAccessDef, type TTableAccessScope, type TTableOp, type TTableWriteOp, allowTableAction, allowTableOps, allowTableRead, allowTableWrite, applyScopeFieldFilters, conjoinRowPolicies, conjoinScopeFilters, conjoinScopes, definePrivilege, defineRole, defineTableAccess, effectiveScope, expandExcludeToLeaves, extractResourceActions, generateResourceTypes, getProjectionMode, intersectControlsPolicy, intersectEnabled, intersectProjections, isFieldAllowed, mergeScopeFilters, needsInheritedConjunction, normalizeScopes, restrictProjection, stableKey, unionControlsPolicy, unionOutcomes, unionProjections };
|
|
678
|
+
export declare function generateResourceTypes(map: TResourceActionMap, options?: TCodegenOptions): string;
|
|
679
|
+
export type { ControlGate, RoleBuilder, TApplyScopeFieldFiltersOptions, TCodegenOptions, TConjoinScopesOptions, TDbScope, TEffectiveDbScope, TPrivilegeFunction, TProjection, TProjectionChildren, TProjectionMode, TResourceActionMap, TRowPolicy, TScopeFieldRule, TScopeFieldRules, TScopeFilter, TTableAccessDef, TTableAccessScope, TTableOp, TTableWriteOp };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { TArbacRole, TArbacRule } from "@aooth/arbac-core";
|
|
2
2
|
export * from "@aooth/arbac-core";
|
|
3
|
-
//#region src/define-role.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* A privilege function produces an array of rules when called.
|
|
6
5
|
* Created by `definePrivilege()` or manually.
|
|
@@ -62,9 +61,7 @@ interface RoleBuilder<TUserAttrs, TScope> {
|
|
|
62
61
|
* .deny("articles", "publish")
|
|
63
62
|
* .build();
|
|
64
63
|
*/
|
|
65
|
-
declare function defineRole<TUserAttrs extends object = object, TScope extends object = object>(): RoleBuilder<TUserAttrs, TScope>;
|
|
66
|
-
//#endregion
|
|
67
|
-
//#region src/define-privilege.d.ts
|
|
64
|
+
export declare function defineRole<TUserAttrs extends object = object, TScope extends object = object>(): RoleBuilder<TUserAttrs, TScope>;
|
|
68
65
|
/**
|
|
69
66
|
* Define a reusable privilege factory.
|
|
70
67
|
*
|
|
@@ -84,9 +81,7 @@ declare function defineRole<TUserAttrs extends object = object, TScope extends o
|
|
|
84
81
|
* .use(canManageUsers((attrs) => ({ dept: attrs.dept })))
|
|
85
82
|
* .build();
|
|
86
83
|
*/
|
|
87
|
-
declare function definePrivilege<TUserAttrs extends object = object, TScope extends object = object>(): <TArgs extends unknown[]>(factory: (...args: TArgs) => TArbacRule<TUserAttrs, TScope>[]) => ((...args: TArgs) => TPrivilegeFunction<TUserAttrs, TScope>);
|
|
88
|
-
//#endregion
|
|
89
|
-
//#region src/scope/types.d.ts
|
|
84
|
+
export declare function definePrivilege<TUserAttrs extends object = object, TScope extends object = object>(): <TArgs extends unknown[]>(factory: (...args: TArgs) => TArbacRule<TUserAttrs, TScope>[]) => ((...args: TArgs) => TPrivilegeFunction<TUserAttrs, TScope>);
|
|
90
85
|
/**
|
|
91
86
|
* Mongo-style field projection: `{ field: 0 | 1 }`.
|
|
92
87
|
* - All 1s = inclusion mode (only listed fields allowed)
|
|
@@ -122,33 +117,31 @@ type TScopeFilter = Record<string, unknown>;
|
|
|
122
117
|
* supported in v1; supplying a whitelist throws at scope-evaluation time.
|
|
123
118
|
*/
|
|
124
119
|
type ControlGate = boolean | readonly string[];
|
|
125
|
-
//#endregion
|
|
126
|
-
//#region src/db-privileges.d.ts
|
|
127
120
|
/**
|
|
128
121
|
* Read-side handler actions of an `AsDbController` table: `query`, `pages`,
|
|
129
122
|
* `getOne`, `getOneComposite`, `geo`, `meta`, `metaForm`.
|
|
130
123
|
*/
|
|
131
|
-
declare const TABLE_READ_ACTIONS: readonly ["query", "pages", "getOne", "getOneComposite", "geo", "meta", "metaForm"];
|
|
124
|
+
export declare const TABLE_READ_ACTIONS: readonly ["query", "pages", "getOne", "getOneComposite", "geo", "meta", "metaForm"];
|
|
132
125
|
/** Write-side handler actions of an `AsDbController` table. */
|
|
133
|
-
declare const TABLE_WRITE_ACTIONS: readonly ["insert", "update", "replace", "remove", "removeComposite"];
|
|
126
|
+
export declare const TABLE_WRITE_ACTIONS: readonly ["insert", "update", "replace", "remove", "removeComposite"];
|
|
134
127
|
/** The `/meta` + `/meta/form/:name` handler actions (a subset of {@link TABLE_READ_ACTIONS}). */
|
|
135
|
-
declare const TABLE_META_ACTIONS: readonly ["meta", "metaForm"];
|
|
128
|
+
export declare const TABLE_META_ACTIONS: readonly ["meta", "metaForm"];
|
|
136
129
|
/** Table operation names accepted by {@link allowTableOps} / {@link defineTableAccess}. */
|
|
137
130
|
type TTableOp = "read" | "meta" | "insert" | "update" | "replace" | "remove";
|
|
138
131
|
/**
|
|
139
132
|
* Operation → handler actions. `meta` is the form-metadata subset of `read`,
|
|
140
133
|
* for write-only principals that still render forms from `/meta`.
|
|
141
134
|
*/
|
|
142
|
-
declare const TABLE_OP_ACTIONS: Readonly<Record<TTableOp, readonly string[]>>;
|
|
135
|
+
export declare const TABLE_OP_ACTIONS: Readonly<Record<TTableOp, readonly string[]>>;
|
|
143
136
|
/** A rule scope; `null` / `undefined` = this rule admits nothing (deny for it). */
|
|
144
137
|
type ScopeFn<TUserAttrs, TScope> = (attrs: TUserAttrs, userId: string) => TScope | null | undefined;
|
|
145
138
|
interface ScopeOpts<TUserAttrs, TScope> {
|
|
146
139
|
scope?: ScopeFn<TUserAttrs, TScope>;
|
|
147
140
|
}
|
|
148
141
|
/** Read-side actions on an `AsDbController` table — see {@link TABLE_READ_ACTIONS}. */
|
|
149
|
-
declare function allowTableRead<TUserAttrs extends object = object, TScope extends object = object>(resource: string, opts?: ScopeOpts<TUserAttrs, TScope>): TPrivilegeFunction<TUserAttrs, TScope>;
|
|
142
|
+
export declare function allowTableRead<TUserAttrs extends object = object, TScope extends object = object>(resource: string, opts?: ScopeOpts<TUserAttrs, TScope>): TPrivilegeFunction<TUserAttrs, TScope>;
|
|
150
143
|
/** All actions on an `AsDbController` table: read + `insert`, `update`, `replace`, `remove`, `removeComposite`. */
|
|
151
|
-
declare function allowTableWrite<TUserAttrs extends object = object, TScope extends object = object>(resource: string, opts?: ScopeOpts<TUserAttrs, TScope>): TPrivilegeFunction<TUserAttrs, TScope>;
|
|
144
|
+
export declare function allowTableWrite<TUserAttrs extends object = object, TScope extends object = object>(resource: string, opts?: ScopeOpts<TUserAttrs, TScope>): TPrivilegeFunction<TUserAttrs, TScope>;
|
|
152
145
|
/**
|
|
153
146
|
* Selected operations on an `AsDbController` table, sharing a scope — e.g. an
|
|
154
147
|
* insert-only form principal: `allowTableOps("leads", ["insert", "meta"])`.
|
|
@@ -160,9 +153,9 @@ declare function allowTableWrite<TUserAttrs extends object = object, TScope exte
|
|
|
160
153
|
*
|
|
161
154
|
* Throws on an unknown op name.
|
|
162
155
|
*/
|
|
163
|
-
declare function allowTableOps<TUserAttrs extends object = object, TScope extends object = object>(resource: string, ops: readonly TTableOp[], opts?: ScopeOpts<TUserAttrs, TScope>): TPrivilegeFunction<TUserAttrs, TScope>;
|
|
156
|
+
export declare function allowTableOps<TUserAttrs extends object = object, TScope extends object = object>(resource: string, ops: readonly TTableOp[], opts?: ScopeOpts<TUserAttrs, TScope>): TPrivilegeFunction<TUserAttrs, TScope>;
|
|
164
157
|
/** One or more declarative actions on the same table, sharing a scope. */
|
|
165
|
-
declare function allowTableAction<TUserAttrs extends object = object, TScope extends object = object>(resource: string, name: string | string[], opts?: ScopeOpts<TUserAttrs, TScope>): TPrivilegeFunction<TUserAttrs, TScope>;
|
|
158
|
+
export declare function allowTableAction<TUserAttrs extends object = object, TScope extends object = object>(resource: string, name: string | string[], opts?: ScopeOpts<TUserAttrs, TScope>): TPrivilegeFunction<TUserAttrs, TScope>;
|
|
166
159
|
/** The scope keys {@link defineTableAccess} conjoins instead of overriding. */
|
|
167
160
|
interface TTableAccessScope {
|
|
168
161
|
filter?: TScopeFilter;
|
|
@@ -214,9 +207,7 @@ interface TTableAccessDef<TUserAttrs, TScope> {
|
|
|
214
207
|
* });
|
|
215
208
|
* ```
|
|
216
209
|
*/
|
|
217
|
-
declare function defineTableAccess<TUserAttrs extends object = object, TScope extends TTableAccessScope = TTableAccessScope>(resource: string, def: TTableAccessDef<TUserAttrs, TScope>): TPrivilegeFunction<TUserAttrs, TScope>;
|
|
218
|
-
//#endregion
|
|
219
|
-
//#region src/scope/projection.d.ts
|
|
210
|
+
export declare function defineTableAccess<TUserAttrs extends object = object, TScope extends TTableAccessScope = TTableAccessScope>(resource: string, def: TTableAccessDef<TUserAttrs, TScope>): TPrivilegeFunction<TUserAttrs, TScope>;
|
|
220
211
|
type TProjectionMode = "include" | "exclude" | "empty";
|
|
221
212
|
/**
|
|
222
213
|
* Determine whether a projection is in inclusion mode (all 1s),
|
|
@@ -224,7 +215,7 @@ type TProjectionMode = "include" | "exclude" | "empty";
|
|
|
224
215
|
*
|
|
225
216
|
* @throws when a single projection mixes 0 and 1 values
|
|
226
217
|
*/
|
|
227
|
-
declare function getProjectionMode(proj: TProjection): TProjectionMode;
|
|
218
|
+
export declare function getProjectionMode(proj: TProjection): TProjectionMode;
|
|
228
219
|
/**
|
|
229
220
|
* Check whether a dot-path field is allowed by a projection.
|
|
230
221
|
*
|
|
@@ -233,7 +224,7 @@ declare function getProjectionMode(proj: TProjection): TProjectionMode;
|
|
|
233
224
|
* Exclusion mode: a field is allowed unless it or any of its parents is excluded.
|
|
234
225
|
* Empty projection: every field is allowed.
|
|
235
226
|
*/
|
|
236
|
-
declare function isFieldAllowed(field: string, projection: TProjection): boolean;
|
|
227
|
+
export declare function isFieldAllowed(field: string, projection: TProjection): boolean;
|
|
237
228
|
/**
|
|
238
229
|
* Combines projections from multiple RBAC role grants under additive semantics:
|
|
239
230
|
* more roles = broader access. Each projection represents a set of allowed fields:
|
|
@@ -255,7 +246,7 @@ declare function isFieldAllowed(field: string, projection: TProjection): boolean
|
|
|
255
246
|
*
|
|
256
247
|
* @throws when a single projection mixes 1 and 0 keys, or contains an invalid value
|
|
257
248
|
*/
|
|
258
|
-
declare function unionProjections(...projections: TProjection[]): TProjection;
|
|
249
|
+
export declare function unionProjections(...projections: TProjection[]): TProjection;
|
|
259
250
|
/**
|
|
260
251
|
* Direct child field paths of a nested-object path (`a` → `["a.b", "a.c"]`),
|
|
261
252
|
* from the model schema; `[]` for a leaf. Lets a projection intersection
|
|
@@ -269,7 +260,7 @@ type TProjectionChildren = (path: string) => readonly string[];
|
|
|
269
260
|
* columns, so a parent key alone would strip nothing. Without `childrenOf`,
|
|
270
261
|
* or for an inclusion / empty projection, the input is returned unchanged.
|
|
271
262
|
*/
|
|
272
|
-
declare function expandExcludeToLeaves(projection: TProjection, childrenOf: TProjectionChildren | undefined): TProjection;
|
|
263
|
+
export declare function expandExcludeToLeaves(projection: TProjection, childrenOf: TProjectionChildren | undefined): TProjection;
|
|
273
264
|
/**
|
|
274
265
|
* The exact field intersection of two projections, by PATH — never wider than
|
|
275
266
|
* either side. Returns `null` when no field survives (a disjoint pair, or
|
|
@@ -285,7 +276,7 @@ declare function expandExcludeToLeaves(projection: TProjection, childrenOf: TPro
|
|
|
285
276
|
*
|
|
286
277
|
* @param childrenOf - optional schema lookup for exact nested subtraction
|
|
287
278
|
*/
|
|
288
|
-
declare function intersectProjections(a: TProjection, b: TProjection, childrenOf?: TProjectionChildren): TProjection | null;
|
|
279
|
+
export declare function intersectProjections(a: TProjection, b: TProjection, childrenOf?: TProjectionChildren): TProjection | null;
|
|
289
280
|
/**
|
|
290
281
|
* Restrict a desired projection to only fields allowed by an access-control projection.
|
|
291
282
|
*
|
|
@@ -304,15 +295,13 @@ declare function intersectProjections(a: TProjection, b: TProjection, childrenOf
|
|
|
304
295
|
* @param accessControl - the projection allowed by RBAC
|
|
305
296
|
* @param childrenOf - optional schema lookup for exact nested subtraction
|
|
306
297
|
*/
|
|
307
|
-
declare function restrictProjection(desired: TProjection, accessControl: TProjection, childrenOf?: TProjectionChildren): TProjection;
|
|
308
|
-
//#endregion
|
|
309
|
-
//#region src/scope/filter.d.ts
|
|
298
|
+
export declare function restrictProjection(desired: TProjection, accessControl: TProjection, childrenOf?: TProjectionChildren): TProjection;
|
|
310
299
|
/**
|
|
311
300
|
* A filter that matches no rows (`{ $or: [] }`) — what a denied read, or a
|
|
312
301
|
* conjunction whose field intersection is empty, filters by. Shared; never
|
|
313
302
|
* mutate it.
|
|
314
303
|
*/
|
|
315
|
-
declare const DENY_FILTER: Readonly<TScopeFilter>;
|
|
304
|
+
export declare const DENY_FILTER: Readonly<TScopeFilter>;
|
|
316
305
|
/**
|
|
317
306
|
* Merge multiple scope filters into a single filter using `$or` semantics.
|
|
318
307
|
*
|
|
@@ -328,7 +317,7 @@ declare const DENY_FILTER: Readonly<TScopeFilter>;
|
|
|
328
317
|
*
|
|
329
318
|
* @returns the merged filter, or `undefined` for unrestricted access
|
|
330
319
|
*/
|
|
331
|
-
declare function mergeScopeFilters(scopes: TScopeFilter[]): TScopeFilter | undefined;
|
|
320
|
+
export declare function mergeScopeFilters(scopes: TScopeFilter[]): TScopeFilter | undefined;
|
|
332
321
|
/**
|
|
333
322
|
* Conjoin two filters under `$and` semantics — a row survives only if BOTH
|
|
334
323
|
* sides admit it. The restrict-only combiner, used wherever two independent
|
|
@@ -351,9 +340,7 @@ declare function mergeScopeFilters(scopes: TScopeFilter[]): TScopeFilter | undef
|
|
|
351
340
|
*
|
|
352
341
|
* @returns the conjoined filter, or `undefined` when BOTH sides are unrestricted.
|
|
353
342
|
*/
|
|
354
|
-
declare function conjoinScopeFilters(a: TScopeFilter | undefined, b: TScopeFilter | undefined): TScopeFilter | undefined;
|
|
355
|
-
//#endregion
|
|
356
|
-
//#region src/scope/controls.d.ts
|
|
343
|
+
export declare function conjoinScopeFilters(a: TScopeFilter | undefined, b: TScopeFilter | undefined): TScopeFilter | undefined;
|
|
357
344
|
/**
|
|
358
345
|
* Union per-role `controls` policies. Additive RBAC semantics: more roles =
|
|
359
346
|
* broader access, mirroring how `mergeScopeFilters` and `unionProjections`
|
|
@@ -386,7 +373,7 @@ declare function conjoinScopeFilters(a: TScopeFilter | undefined, b: TScopeFilte
|
|
|
386
373
|
*
|
|
387
374
|
* @throws when a non-whitelistable control is given a `readonly string[]` gate.
|
|
388
375
|
*/
|
|
389
|
-
declare function unionControlsPolicy(scopes: ReadonlyArray<{
|
|
376
|
+
export declare function unionControlsPolicy(scopes: ReadonlyArray<{
|
|
390
377
|
controls?: Record<string, ControlGate>;
|
|
391
378
|
}>): Record<string, ControlGate>;
|
|
392
379
|
/**
|
|
@@ -405,9 +392,7 @@ declare function unionControlsPolicy(scopes: ReadonlyArray<{
|
|
|
405
392
|
* @returns merged policy; keys absent from the result mean "allowed" (callers
|
|
406
393
|
* treat a missing key as `true`), matching {@link unionControlsPolicy}.
|
|
407
394
|
*/
|
|
408
|
-
declare function intersectControlsPolicy(a: Record<string, ControlGate>, b: Record<string, ControlGate>): Record<string, ControlGate>;
|
|
409
|
-
//#endregion
|
|
410
|
-
//#region src/scope/db-scope.d.ts
|
|
395
|
+
export declare function intersectControlsPolicy(a: Record<string, ControlGate>, b: Record<string, ControlGate>): Record<string, ControlGate>;
|
|
411
396
|
/**
|
|
412
397
|
* The DB scope shape the scope algebra reads — structurally what
|
|
413
398
|
* `ArbacDbScope` (`@aooth/arbac-moost`) carries. Every facet is optional.
|
|
@@ -433,7 +418,7 @@ interface TDbScope {
|
|
|
433
418
|
*
|
|
434
419
|
* @since 0.1.72
|
|
435
420
|
*/
|
|
436
|
-
declare const DB_SCOPE_KEYS: readonly string[];
|
|
421
|
+
export declare const DB_SCOPE_KEYS: readonly string[];
|
|
437
422
|
/**
|
|
438
423
|
* The conjunction rule of ONE custom scope field (a key an app adds to its
|
|
439
424
|
* scope type by declaration merging). {@link conjoinScopes} calls `conjoin`
|
|
@@ -471,7 +456,7 @@ interface TScopeFieldRule<S extends object = TDbScope> {
|
|
|
471
456
|
*
|
|
472
457
|
* @since 0.1.72
|
|
473
458
|
*/
|
|
474
|
-
declare class ScopeFieldConfigError extends Error {
|
|
459
|
+
export declare class ScopeFieldConfigError extends Error {
|
|
475
460
|
/** The custom scope field without a rule. */
|
|
476
461
|
readonly field: string;
|
|
477
462
|
readonly name = "ScopeFieldConfigError";
|
|
@@ -531,14 +516,14 @@ interface TEffectiveDbScope<S extends TDbScope = TDbScope> {
|
|
|
531
516
|
*
|
|
532
517
|
* @since 0.1.72
|
|
533
518
|
*/
|
|
534
|
-
declare function effectiveScope<S extends TDbScope>(scopes: readonly S[]): TEffectiveDbScope<S>;
|
|
519
|
+
export declare function effectiveScope<S extends TDbScope>(scopes: readonly S[]): TEffectiveDbScope<S>;
|
|
535
520
|
/**
|
|
536
521
|
* Intersection of enforcement: an entry is enforced only when EVERY input
|
|
537
522
|
* enables it (`true` enables all). No input → nothing enforced.
|
|
538
523
|
*
|
|
539
524
|
* @since 0.1.72
|
|
540
525
|
*/
|
|
541
|
-
declare function intersectEnabled<K>(inputs: Iterable<true | ReadonlySet<K>>): true | Set<K>;
|
|
526
|
+
export declare function intersectEnabled<K>(inputs: Iterable<true | ReadonlySet<K>>): true | Set<K>;
|
|
542
527
|
/**
|
|
543
528
|
* The unified empty-scope rule for an evaluation outcome: denied → `undefined`;
|
|
544
529
|
* allowed with `scopes` absent (a scope-agnostic evaluator) → `[{}]`
|
|
@@ -547,7 +532,7 @@ declare function intersectEnabled<K>(inputs: Iterable<true | ReadonlySet<K>>): t
|
|
|
547
532
|
*
|
|
548
533
|
* @since 0.1.72
|
|
549
534
|
*/
|
|
550
|
-
declare function normalizeScopes<S extends object>(outcome: {
|
|
535
|
+
export declare function normalizeScopes<S extends object>(outcome: {
|
|
551
536
|
allowed: boolean;
|
|
552
537
|
scopes?: ReadonlyArray<S | null | undefined>;
|
|
553
538
|
}): S[] | undefined;
|
|
@@ -558,7 +543,7 @@ declare function normalizeScopes<S extends object>(outcome: {
|
|
|
558
543
|
*
|
|
559
544
|
* @since 0.1.72
|
|
560
545
|
*/
|
|
561
|
-
declare function unionOutcomes<S extends object>(outcomes: ReadonlyArray<{
|
|
546
|
+
export declare function unionOutcomes<S extends object>(outcomes: ReadonlyArray<{
|
|
562
547
|
allowed: boolean;
|
|
563
548
|
scopes?: ReadonlyArray<S | null | undefined>;
|
|
564
549
|
}>): S[] | undefined;
|
|
@@ -576,7 +561,7 @@ interface TRowPolicy {
|
|
|
576
561
|
*
|
|
577
562
|
* @since 0.1.72
|
|
578
563
|
*/
|
|
579
|
-
declare function conjoinRowPolicies(a: TRowPolicy, b: TRowPolicy): TRowPolicy;
|
|
564
|
+
export declare function conjoinRowPolicies(a: TRowPolicy, b: TRowPolicy): TRowPolicy;
|
|
580
565
|
/** Options of {@link conjoinScopes}. */
|
|
581
566
|
interface TConjoinScopesOptions<S extends TDbScope> {
|
|
582
567
|
/** Schema lookup to subtract a nested exclusion exactly (without it: fail closed). */
|
|
@@ -616,7 +601,7 @@ interface TConjoinScopesOptions<S extends TDbScope> {
|
|
|
616
601
|
*
|
|
617
602
|
* @since 0.1.72
|
|
618
603
|
*/
|
|
619
|
-
declare function conjoinScopes<S extends TDbScope>(a: readonly S[], b: readonly S[], opts?: TConjoinScopesOptions<S>): S;
|
|
604
|
+
export declare function conjoinScopes<S extends TDbScope>(a: readonly S[], b: readonly S[], opts?: TConjoinScopesOptions<S>): S;
|
|
620
605
|
/** Options of {@link applyScopeFieldFilters}. @since 0.1.72 */
|
|
621
606
|
interface TApplyScopeFieldFiltersOptions {
|
|
622
607
|
/**
|
|
@@ -639,7 +624,7 @@ interface TApplyScopeFieldFiltersOptions {
|
|
|
639
624
|
*
|
|
640
625
|
* @since 0.1.72
|
|
641
626
|
*/
|
|
642
|
-
declare function applyScopeFieldFilters<S extends TDbScope>(scopes: readonly S[], fields: TScopeFieldRules<S> | undefined, opts?: TApplyScopeFieldFiltersOptions): readonly S[];
|
|
627
|
+
export declare function applyScopeFieldFilters<S extends TDbScope>(scopes: readonly S[], fields: TScopeFieldRules<S> | undefined, opts?: TApplyScopeFieldFiltersOptions): readonly S[];
|
|
643
628
|
/**
|
|
644
629
|
* Marks a `with.<rel>` sub-scope {@link conjoinScopes} built from ONE side's
|
|
645
630
|
* declaration. The other side is silent on the relation, so ITS policy for
|
|
@@ -650,18 +635,16 @@ declare function applyScopeFieldFilters<S extends TDbScope>(scopes: readonly S[]
|
|
|
650
635
|
*
|
|
651
636
|
* @since 0.1.72
|
|
652
637
|
*/
|
|
653
|
-
declare const INHERITED_CONJUNCTION: unique symbol;
|
|
638
|
+
export declare const INHERITED_CONJUNCTION: unique symbol;
|
|
654
639
|
/** A `with` sub-scope marked {@link INHERITED_CONJUNCTION}. @since 0.1.72 */
|
|
655
|
-
declare function needsInheritedConjunction(scope: object): boolean;
|
|
640
|
+
export declare function needsInheritedConjunction(scope: object): boolean;
|
|
656
641
|
/**
|
|
657
642
|
* A stable string key for a JSON-like value (bigint-safe) — for
|
|
658
643
|
* de-duplicating filters / tuples and comparing them structurally.
|
|
659
644
|
*
|
|
660
645
|
* @since 0.1.72
|
|
661
646
|
*/
|
|
662
|
-
declare function stableKey(value: unknown): string;
|
|
663
|
-
//#endregion
|
|
664
|
-
//#region src/codegen/extract.d.ts
|
|
647
|
+
export declare function stableKey(value: unknown): string;
|
|
665
648
|
interface TResourceActionMap {
|
|
666
649
|
/** Map of resource string → Set of action strings */
|
|
667
650
|
resources: Map<string, Set<string>>;
|
|
@@ -676,11 +659,9 @@ interface TResourceActionMap {
|
|
|
676
659
|
* @param roles - Array of built role definitions
|
|
677
660
|
* @param options.includeWildcards - If false (default), skip entries containing `*` or `**`
|
|
678
661
|
*/
|
|
679
|
-
declare function extractResourceActions(roles: TArbacRole<unknown, unknown>[], options?: {
|
|
662
|
+
export declare function extractResourceActions(roles: TArbacRole<unknown, unknown>[], options?: {
|
|
680
663
|
includeWildcards?: boolean;
|
|
681
664
|
}): TResourceActionMap;
|
|
682
|
-
//#endregion
|
|
683
|
-
//#region src/codegen/generate.d.ts
|
|
684
665
|
interface TCodegenOptions {
|
|
685
666
|
/** Name for the resource union type. Default: "Resource" */
|
|
686
667
|
resourceTypeName?: string;
|
|
@@ -694,6 +675,5 @@ interface TCodegenOptions {
|
|
|
694
675
|
/**
|
|
695
676
|
* Generate TypeScript source defining union types for resources and actions.
|
|
696
677
|
*/
|
|
697
|
-
declare function generateResourceTypes(map: TResourceActionMap, options?: TCodegenOptions): string;
|
|
698
|
-
|
|
699
|
-
export { type ControlGate, DB_SCOPE_KEYS, DENY_FILTER, INHERITED_CONJUNCTION, type RoleBuilder, ScopeFieldConfigError, TABLE_META_ACTIONS, TABLE_OP_ACTIONS, TABLE_READ_ACTIONS, TABLE_WRITE_ACTIONS, type TApplyScopeFieldFiltersOptions, type TCodegenOptions, type TConjoinScopesOptions, type TDbScope, type TEffectiveDbScope, type TPrivilegeFunction, type TProjection, type TProjectionChildren, type TProjectionMode, type TResourceActionMap, type TRowPolicy, type TScopeFieldRule, type TScopeFieldRules, type TScopeFilter, type TTableAccessDef, type TTableAccessScope, type TTableOp, type TTableWriteOp, allowTableAction, allowTableOps, allowTableRead, allowTableWrite, applyScopeFieldFilters, conjoinRowPolicies, conjoinScopeFilters, conjoinScopes, definePrivilege, defineRole, defineTableAccess, effectiveScope, expandExcludeToLeaves, extractResourceActions, generateResourceTypes, getProjectionMode, intersectControlsPolicy, intersectEnabled, intersectProjections, isFieldAllowed, mergeScopeFilters, needsInheritedConjunction, normalizeScopes, restrictProjection, stableKey, unionControlsPolicy, unionOutcomes, unionProjections };
|
|
678
|
+
export declare function generateResourceTypes(map: TResourceActionMap, options?: TCodegenOptions): string;
|
|
679
|
+
export type { ControlGate, RoleBuilder, TApplyScopeFieldFiltersOptions, TCodegenOptions, TConjoinScopesOptions, TDbScope, TEffectiveDbScope, TPrivilegeFunction, TProjection, TProjectionChildren, TProjectionMode, TResourceActionMap, TRowPolicy, TScopeFieldRule, TScopeFieldRules, TScopeFilter, TTableAccessDef, TTableAccessScope, TTableOp, TTableWriteOp };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from "@aooth/arbac-core";
|
|
2
|
-
|
|
2
|
+
// src/define-role.ts
|
|
3
3
|
var RoleBuilderImpl = class {
|
|
4
4
|
_id;
|
|
5
5
|
_name;
|
|
@@ -65,8 +65,7 @@ var RoleBuilderImpl = class {
|
|
|
65
65
|
function defineRole() {
|
|
66
66
|
return new RoleBuilderImpl();
|
|
67
67
|
}
|
|
68
|
-
|
|
69
|
-
//#region src/define-privilege.ts
|
|
68
|
+
// src/define-privilege.ts
|
|
70
69
|
/**
|
|
71
70
|
* Define a reusable privilege factory.
|
|
72
71
|
*
|
|
@@ -91,8 +90,7 @@ function definePrivilege() {
|
|
|
91
90
|
return (...args) => () => factory(...args);
|
|
92
91
|
};
|
|
93
92
|
}
|
|
94
|
-
|
|
95
|
-
//#region src/scope/controls.ts
|
|
93
|
+
// src/scope/controls.ts
|
|
96
94
|
/**
|
|
97
95
|
* Controls whose values can be sensibly whitelisted via `readonly string[]`.
|
|
98
96
|
*
|
|
@@ -208,8 +206,7 @@ function intersectControlsPolicy(a, b) {
|
|
|
208
206
|
}
|
|
209
207
|
return result;
|
|
210
208
|
}
|
|
211
|
-
|
|
212
|
-
//#region src/scope/filter.ts
|
|
209
|
+
// src/scope/filter.ts
|
|
213
210
|
/**
|
|
214
211
|
* A filter that matches no rows (`{ $or: [] }`) — what a denied read, or a
|
|
215
212
|
* conjunction whose field intersection is empty, filters by. Shared; never
|
|
@@ -284,8 +281,7 @@ function canOptimizeToIn(scopes) {
|
|
|
284
281
|
}
|
|
285
282
|
return true;
|
|
286
283
|
}
|
|
287
|
-
|
|
288
|
-
//#region src/scope/projection.ts
|
|
284
|
+
// src/scope/projection.ts
|
|
289
285
|
/**
|
|
290
286
|
* Determine whether a projection is in inclusion mode (all 1s),
|
|
291
287
|
* exclusion mode (all 0s), or empty (`{}`, no restriction).
|
|
@@ -481,8 +477,7 @@ function intersectProjections(a, b, childrenOf) {
|
|
|
481
477
|
function restrictProjection(desired, accessControl, childrenOf) {
|
|
482
478
|
return intersectProjections(desired, accessControl, childrenOf) ?? { ...accessControl };
|
|
483
479
|
}
|
|
484
|
-
|
|
485
|
-
//#region src/scope/db-scope.ts
|
|
480
|
+
// src/scope/db-scope.ts
|
|
486
481
|
/**
|
|
487
482
|
* The built-in {@link TDbScope} keys — the facets the scope algebra itself
|
|
488
483
|
* combines. Any other key is a custom (declaration-merged) scope field, which
|
|
@@ -887,8 +882,7 @@ function conjoinWith(ea, eb, fields) {
|
|
|
887
882
|
function stableKey(value) {
|
|
888
883
|
return JSON.stringify(value, (_k, v) => typeof v === "bigint" ? `${v}n` : v);
|
|
889
884
|
}
|
|
890
|
-
|
|
891
|
-
//#region src/db-privileges.ts
|
|
885
|
+
// src/db-privileges.ts
|
|
892
886
|
/**
|
|
893
887
|
* Read-side handler actions of an `AsDbController` table: `query`, `pages`,
|
|
894
888
|
* `getOne`, `getOneComposite`, `geo`, `meta`, `metaForm`.
|
|
@@ -1044,8 +1038,7 @@ function defineTableAccess(resource, def) {
|
|
|
1044
1038
|
function isList(v) {
|
|
1045
1039
|
return Array.isArray(v);
|
|
1046
1040
|
}
|
|
1047
|
-
|
|
1048
|
-
//#region src/codegen/extract.ts
|
|
1041
|
+
// src/codegen/extract.ts
|
|
1049
1042
|
function hasWildcard(s) {
|
|
1050
1043
|
return s.includes("*");
|
|
1051
1044
|
}
|
|
@@ -1078,8 +1071,7 @@ function extractResourceActions(roles, options) {
|
|
|
1078
1071
|
allActions
|
|
1079
1072
|
};
|
|
1080
1073
|
}
|
|
1081
|
-
|
|
1082
|
-
//#region src/codegen/generate.ts
|
|
1074
|
+
// src/codegen/generate.ts
|
|
1083
1075
|
/**
|
|
1084
1076
|
* Escape a string for safe embedding inside a TypeScript double-quoted literal.
|
|
1085
1077
|
* Handles backslashes, double quotes, and control chars so resource/action
|
|
@@ -1115,5 +1107,4 @@ function generateResourceTypes(map, options) {
|
|
|
1115
1107
|
lines.push("");
|
|
1116
1108
|
return lines.join("\n");
|
|
1117
1109
|
}
|
|
1118
|
-
//#endregion
|
|
1119
1110
|
export { DB_SCOPE_KEYS, DENY_FILTER, INHERITED_CONJUNCTION, ScopeFieldConfigError, TABLE_META_ACTIONS, TABLE_OP_ACTIONS, TABLE_READ_ACTIONS, TABLE_WRITE_ACTIONS, allowTableAction, allowTableOps, allowTableRead, allowTableWrite, applyScopeFieldFilters, conjoinRowPolicies, conjoinScopeFilters, conjoinScopes, definePrivilege, defineRole, defineTableAccess, effectiveScope, expandExcludeToLeaves, extractResourceActions, generateResourceTypes, getProjectionMode, intersectControlsPolicy, intersectEnabled, intersectProjections, isFieldAllowed, mergeScopeFilters, needsInheritedConjunction, normalizeScopes, restrictProjection, stableKey, unionControlsPolicy, unionOutcomes, unionProjections };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aooth/arbac",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Batteries-included RBAC: builder API, privilege factories, scope merge utilities",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"access-control",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"access": "public"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@aooth/arbac-core": "0.2.
|
|
48
|
+
"@aooth/arbac-core": "0.2.3"
|
|
49
49
|
},
|
|
50
50
|
"scripts": {
|
|
51
51
|
"build": "vp pack",
|