@authup/access 1.0.0-beta.49 → 1.0.0-beta.51

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.
Files changed (43) hide show
  1. package/dist/index.d.mts +138 -15
  2. package/dist/index.d.mts.map +1 -1
  3. package/dist/index.mjs +252 -47
  4. package/dist/index.mjs.map +1 -1
  5. package/dist/permission/evaluator/module.d.ts +2 -2
  6. package/dist/permission/evaluator/module.d.ts.map +1 -1
  7. package/dist/permission/evaluator/types.d.ts +1 -1
  8. package/dist/permission/evaluator/types.d.ts.map +1 -1
  9. package/dist/permission/helpers/aggregate.d.ts +10 -0
  10. package/dist/permission/helpers/aggregate.d.ts.map +1 -0
  11. package/dist/permission/helpers/equal.d.ts +6 -2
  12. package/dist/permission/helpers/equal.d.ts.map +1 -1
  13. package/dist/permission/helpers/grant.d.ts +9 -0
  14. package/dist/permission/helpers/grant.d.ts.map +1 -0
  15. package/dist/permission/helpers/index.d.ts +2 -1
  16. package/dist/permission/helpers/index.d.ts.map +1 -1
  17. package/dist/permission/index.d.ts +1 -0
  18. package/dist/permission/index.d.ts.map +1 -1
  19. package/dist/permission/provider/memory.d.ts +3 -3
  20. package/dist/permission/provider/memory.d.ts.map +1 -1
  21. package/dist/permission/provider/types.d.ts +2 -2
  22. package/dist/permission/provider/types.d.ts.map +1 -1
  23. package/dist/permission/realm-scope/constants.d.ts +20 -0
  24. package/dist/permission/realm-scope/constants.d.ts.map +1 -0
  25. package/dist/permission/realm-scope/helpers.d.ts +23 -0
  26. package/dist/permission/realm-scope/helpers.d.ts.map +1 -0
  27. package/dist/permission/realm-scope/index.d.ts +3 -0
  28. package/dist/permission/realm-scope/index.d.ts.map +1 -0
  29. package/dist/permission/types.d.ts +37 -0
  30. package/dist/permission/types.d.ts.map +1 -1
  31. package/dist/policy/built-in/constants.d.ts +0 -2
  32. package/dist/policy/built-in/constants.d.ts.map +1 -1
  33. package/dist/policy/built-in/realm-match/evaluator.d.ts.map +1 -1
  34. package/dist/policy/built-in/realm-match/types.d.ts +6 -3
  35. package/dist/policy/built-in/realm-match/types.d.ts.map +1 -1
  36. package/dist/policy/built-in/realm-match/validator.d.ts.map +1 -1
  37. package/dist/policy/index.d.ts +1 -0
  38. package/dist/policy/index.d.ts.map +1 -1
  39. package/dist/policy/input.d.ts +26 -0
  40. package/dist/policy/input.d.ts.map +1 -0
  41. package/package.json +7 -11
  42. package/dist/permission/helpers/merge.d.ts +0 -3
  43. package/dist/permission/helpers/merge.d.ts.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  import { AuthupError, ErrorCode, hasInstanceof, isAuthupError, markInstanceof } from "@authup/errors";
2
2
  import { DecisionStrategy, flattenObject, hasOwnProperty, isObject } from "@authup/kit";
3
+ import { isEqual } from "smob";
3
4
  import { Container, defineIssueGroup, defineIssueItem } from "validup";
4
5
  import { createValidator } from "@validup/zod";
5
6
  import { z } from "zod";
@@ -58,12 +59,102 @@ function isPermissionError(input) {
58
59
  return input.code === ErrorCode.PERMISSION_NOT_FOUND || input.code === ErrorCode.PERMISSION_DENIED || input.code === ErrorCode.PERMISSION_EVALUATION_FAILED;
59
60
  }
60
61
  //#endregion
61
- //#region src/permission/helpers/equal.ts
62
- function isPermissionPolicyBindingEqual(a, b) {
63
- if (a.permission.name !== b.permission.name) return false;
64
- if ((a.permission.realm_id ?? null) !== (b.permission.realm_id ?? null)) return false;
65
- if ((a.permission.client_id ?? null) !== (b.permission.client_id ?? null)) return false;
66
- return true;
62
+ //#region src/permission/realm-scope/constants.ts
63
+ /**
64
+ * Actor-relative realm reach of a permission grant.
65
+ *
66
+ * Total order (least -> most permissive): none < own < ownOrNull < any.
67
+ * A missing/unknown column coerces to `own` (fail-closed); `none` is only ever an
68
+ * explicit value (the grant reaches no realm at all).
69
+ */
70
+ let RealmScope = /* @__PURE__ */ function(RealmScope) {
71
+ /** No reach — the grant matches no resource realm. */
72
+ RealmScope["NONE"] = "none";
73
+ /** Own realm only — resource realm must equal the actor's realm. */
74
+ RealmScope["OWN"] = "own";
75
+ /** Own realm or null/global resources (realm_id === null). */
76
+ RealmScope["OWN_OR_NULL"] = "ownOrNull";
77
+ /** Any realm, including null/global. */
78
+ RealmScope["ANY"] = "any";
79
+ return RealmScope;
80
+ }({});
81
+ /** Numeric restrictiveness order — internal to the fold/compare helpers. */
82
+ const REALM_SCOPE_ORDER = {
83
+ ["none"]: 0,
84
+ ["own"]: 1,
85
+ ["ownOrNull"]: 2,
86
+ ["any"]: 3
87
+ };
88
+ //#endregion
89
+ //#region src/permission/realm-scope/helpers.ts
90
+ /**
91
+ * Coerce an arbitrary value to a RealmScope, defaulting to `own` for missing /
92
+ * null / unknown input (fail-closed). `none` is honoured only when explicit.
93
+ */
94
+ function normalizeRealmScope(value) {
95
+ return value === "any" || value === "ownOrNull" || value === "none" ? value : "own";
96
+ }
97
+ /**
98
+ * Numeric comparison of two realm scopes by restrictiveness.
99
+ * Negative when `a` is more restrictive than `b`, positive when less.
100
+ */
101
+ function compareRealmScope(a, b) {
102
+ return REALM_SCOPE_ORDER[normalizeRealmScope(a)] - REALM_SCOPE_ORDER[normalizeRealmScope(b)];
103
+ }
104
+ /** Fold scopes to the MOST permissive (ordered max). Empty folds to `own`. */
105
+ function maxRealmScope(values) {
106
+ let max = "none";
107
+ let seen = false;
108
+ for (const value of values) {
109
+ seen = true;
110
+ const scope = normalizeRealmScope(value);
111
+ if (REALM_SCOPE_ORDER[scope] > REALM_SCOPE_ORDER[max]) max = scope;
112
+ }
113
+ return seen ? max : "own";
114
+ }
115
+ /** Fold scopes to the MORE restrictive (ordered min) — used to CAP a grant. Empty folds to `own`. */
116
+ function minRealmScope(values) {
117
+ let min = "any";
118
+ let seen = false;
119
+ for (const value of values) {
120
+ seen = true;
121
+ const scope = normalizeRealmScope(value);
122
+ if (REALM_SCOPE_ORDER[scope] < REALM_SCOPE_ORDER[min]) min = scope;
123
+ }
124
+ return seen ? min : "own";
125
+ }
126
+ /**
127
+ * Whether `scope` reaches a single resource realm `resourceRealmId` for an actor whose
128
+ * realm is `identityRealmId`/`identityRealmName`.
129
+ *
130
+ * - `any` -> always.
131
+ * - `none` -> never.
132
+ * - realm-less actor (no realmId and no realmName) -> never `own`/`ownOrNull`.
133
+ * - resource realm `null` (global) -> only `ownOrNull`.
134
+ * - concrete resource realm -> must equal the actor's own realm (by id or name).
135
+ */
136
+ function matchesSingle(normalized, resourceRealmId, identityRealmId, identityRealmName) {
137
+ if (resourceRealmId === null) return normalized === "ownOrNull";
138
+ return resourceRealmId === identityRealmId || resourceRealmId === identityRealmName;
139
+ }
140
+ /**
141
+ * Whether `scope` reaches the resource. The resource realm may be presented as a single
142
+ * id, `null` (global), or an array of realm ids — the array form (a resource that spans
143
+ * multiple realms) requires the scope to reach EVERY listed realm (unanimous, fail-closed),
144
+ * so any app/entity can express its realm via one or many keys under the canonical contract.
145
+ */
146
+ function realmScopeMatches(scope, resourceRealmId, identityRealmId, identityRealmName) {
147
+ const normalized = normalizeRealmScope(scope);
148
+ if (normalized === "any") return true;
149
+ if (normalized === "none") return false;
150
+ const realmId = identityRealmId ?? null;
151
+ const realmName = identityRealmName ?? null;
152
+ if (realmId === null && realmName === null) return false;
153
+ if (Array.isArray(resourceRealmId)) {
154
+ if (resourceRealmId.length === 0) return false;
155
+ return resourceRealmId.every((id) => matchesSingle(normalized, id ?? null, realmId, realmName));
156
+ }
157
+ return matchesSingle(normalized, resourceRealmId ?? null, realmId, realmName);
67
158
  }
68
159
  //#endregion
69
160
  //#region src/permission/helpers/key.ts
@@ -74,8 +165,34 @@ function buildPermissionKey(input) {
74
165
  return `${formatKeySegment(input.realm_id)}/${formatKeySegment(input.client_id)}/${input.name}`;
75
166
  }
76
167
  //#endregion
77
- //#region src/permission/helpers/merge.ts
78
- function mergePermissionPolicyBindings(input) {
168
+ //#region src/permission/helpers/aggregate.ts
169
+ /**
170
+ * One disjunction term per raw binding: the grant's realm reach (fail-closed `own` default)
171
+ * paired with its policy — the raw single policy (its `id` preserved for junction propagation),
172
+ * a composite over multiple policies (Layer-1 permission policies, combined under the
173
+ * permission's decision_strategy), or `undefined` when the grant is unrestricted.
174
+ */
175
+ function buildGrant(binding) {
176
+ let policy;
177
+ if (binding.policies && binding.policies.length === 1) policy = binding.policies[0];
178
+ else if (binding.policies && binding.policies.length > 1) policy = {
179
+ type: "composite",
180
+ decision_strategy: binding.permission.decision_strategy || DecisionStrategy.UNANIMOUS,
181
+ children: binding.policies
182
+ };
183
+ return {
184
+ realm_scope: normalizeRealmScope(binding.realm_scope),
185
+ policy
186
+ };
187
+ }
188
+ /**
189
+ * Group raw permission-policy bindings by permission key into the actor's disjunction of
190
+ * `(realm_scope, policy)` grants per permission — with NO lossy collapse. Every consumer
191
+ * (the binding evaluator, isSuperset, junction propagation, the memory provider) evaluates the
192
+ * grant disjunction directly, so each grant's realm reach stays paired with the policy that
193
+ * gates it.
194
+ */
195
+ function aggregatePermissionPolicyBindings(input) {
79
196
  const grouped = input.reduce((previous, current) => {
80
197
  const key = buildPermissionKey(current.permission);
81
198
  if (!previous[key]) previous[key] = [];
@@ -83,41 +200,115 @@ function mergePermissionPolicyBindings(input) {
83
200
  return previous;
84
201
  }, {});
85
202
  const output = [];
86
- const keys = Object.keys(grouped);
87
- for (const key of keys) {
203
+ for (const key of Object.keys(grouped)) {
88
204
  const group = grouped[key];
89
- const first = group[0];
90
- if (group.length === 1) {
91
- output.push(first);
92
- continue;
93
- }
94
- const children = [];
95
- for (const element of group) {
96
- if (!element.policies || element.policies.length === 0) continue;
97
- const policy = {
98
- type: "composite",
99
- decision_strategy: element.permission.decision_strategy || DecisionStrategy.UNANIMOUS,
100
- children: element.policies
101
- };
102
- children.push(policy);
103
- }
104
- let mergedPolicies;
105
- if (children.length > 0 && children.length === group.length) mergedPolicies = [{
106
- type: "composite",
107
- decision_strategy: DecisionStrategy.AFFIRMATIVE,
108
- children
109
- }];
110
205
  output.push({
111
- permission: {
112
- ...first.permission,
113
- decision_strategy: DecisionStrategy.AFFIRMATIVE
114
- },
115
- policies: mergedPolicies
206
+ permission: group[0].permission,
207
+ grants: group.map(buildGrant)
116
208
  });
117
209
  }
118
210
  return output;
119
211
  }
120
212
  //#endregion
213
+ //#region src/permission/helpers/equal.ts
214
+ function isPermissionPolicyBindingEqual(a, b) {
215
+ if (a.permission.name !== b.permission.name) return false;
216
+ if ((a.permission.realm_id ?? null) !== (b.permission.realm_id ?? null)) return false;
217
+ if ((a.permission.client_id ?? null) !== (b.permission.client_id ?? null)) return false;
218
+ return true;
219
+ }
220
+ //#endregion
221
+ //#region src/permission/helpers/grant.ts
222
+ /**
223
+ * Policy fields that do NOT affect evaluation — persisted identity, audit and label columns plus
224
+ * the loaded `parent` / `realm` relation objects. They are stripped before the structural compare
225
+ * in isPolicyEquivalent so two DISTINCT rows with identical configuration still match. Verified
226
+ * against every built-in evaluator, which read only `type`, `invert`, `decision_strategy`,
227
+ * `children` and the type-specific config (query / names / types / start / end / interval /
228
+ * day_of_* / attribute_name* / scope). `parent` is additionally a circular back-reference and
229
+ * `realm` a nested object with its own id, so leaving either in would break the deep compare.
230
+ *
231
+ * SECURITY INVARIANT: every key here MUST stay non-evaluation-affecting. Adding an
232
+ * evaluation-relevant field would silently widen equivalence into an over-permit. New *config*
233
+ * fields need NOT be added — they are compared by default, which is the fail-closed direction.
234
+ */
235
+ const NON_SEMANTIC_POLICY_KEYS = /* @__PURE__ */ new Set([
236
+ "id",
237
+ "built_in",
238
+ "name",
239
+ "display_name",
240
+ "description",
241
+ "parent_id",
242
+ "parent",
243
+ "realm_id",
244
+ "realm",
245
+ "created_at",
246
+ "updated_at"
247
+ ]);
248
+ /**
249
+ * Project a policy node onto its evaluation-relevant configuration: drop the non-semantic keys
250
+ * and recurse through `children` (the only field that carries nested policy nodes). Config values
251
+ * (e.g. an `attributes` `query`) are left untouched, so a semantic `id` / `name` key *inside* a
252
+ * query is never mistaken for the policy's own identity column.
253
+ */
254
+ function normalizePolicyForEquality(policy) {
255
+ const result = {};
256
+ for (const key of Object.keys(policy)) {
257
+ if (NON_SEMANTIC_POLICY_KEYS.has(key)) continue;
258
+ const value = policy[key];
259
+ if (key === "children" && Array.isArray(value)) {
260
+ result[key] = value.map((child) => normalizePolicyForEquality(child));
261
+ continue;
262
+ }
263
+ result[key] = value;
264
+ }
265
+ return result;
266
+ }
267
+ /**
268
+ * Whether two restriction policies are provably the SAME policy for domination purposes — by
269
+ * persisted identity OR by identical configuration, never by evaluated effect. Fast path: equal
270
+ * primary-key `id` means the same persisted row (the `typeof … === 'string'` guards keep an
271
+ * id-less / missing-id policy out of it — never `undefined === undefined`). Otherwise fall back to
272
+ * a structural value-compare of the configuration (`normalizePolicyForEquality` strips the
273
+ * non-semantic identity / audit / relation columns, `isEqual` deep-compares the rest), so two
274
+ * distinct rows with identical config — the same predicate — still dominate. Comparing by
275
+ * *effect* is undecidable (a policy is a predicate over PolicyData), so we accept ONLY provable
276
+ * identity or provable structural equality; a genuinely different configuration is treated as
277
+ * distinct (fail-closed) — isSuperset must never assume one restriction covers a different one.
278
+ */
279
+ function isPolicyEquivalent(parent, child) {
280
+ const parentId = parent.id;
281
+ const childId = child.id;
282
+ if (typeof parentId === "string" && typeof childId === "string" && parentId === childId) return true;
283
+ return isEqual(normalizePolicyForEquality(parent), normalizePolicyForEquality(child));
284
+ }
285
+ /**
286
+ * Whether the actor's `parent` policy provably covers the target's `child` policy on a shared
287
+ * permission. Conservative / fail-closed:
288
+ * - an unrestricted parent (no policy) covers any child;
289
+ * - a restricted parent NEVER covers an unrestricted child — it cannot confer the wider,
290
+ * policy-free reach it does not itself hold;
291
+ * - two restricted grants cover one another only when their policies are provably equivalent.
292
+ * A DIFFERENT policy is NOT assumed to be a subset (#3159: the predecessor treated any two
293
+ * policy-bound grants as mutually dominating, a latent over-permit across disjoint policy
294
+ * scopes — e.g. an actor restricted to `department=X` conferring a `department=Y` grant).
295
+ */
296
+ function policyDominates(parent, child) {
297
+ if (!parent) return true;
298
+ if (!child) return false;
299
+ return isPolicyEquivalent(parent, child);
300
+ }
301
+ /**
302
+ * Whether the actor's `parent` grant covers the target's `child` grant: it reaches at least as
303
+ * far (ordered none < own < ownOrNull < any) AND its policy provably covers the child's
304
+ * (see `policyDominates`). Used per grant by `isSuperset` over the aggregated disjunction —
305
+ * every child grant must be dominated by SOME parent grant.
306
+ */
307
+ function grantDominates(parent, child) {
308
+ if (compareRealmScope(parent.realm_scope, child.realm_scope) < 0) return false;
309
+ return policyDominates(parent.policy, child.policy);
310
+ }
311
+ //#endregion
121
312
  //#region src/permission/provider/memory.ts
122
313
  var PermissionMemoryProvider = class {
123
314
  items = {};
@@ -135,7 +326,7 @@ var PermissionMemoryProvider = class {
135
326
  return null;
136
327
  }
137
328
  setMany(input) {
138
- this.items = mergePermissionPolicyBindings(input).reduce((prev, current) => {
329
+ this.items = aggregatePermissionPolicyBindings(input).reduce((prev, current) => {
139
330
  const key = buildPermissionKey(current.permission);
140
331
  prev[key] = current;
141
332
  return prev;
@@ -402,8 +593,6 @@ const SystemPolicyName = {
402
593
  IDENTITY: "system.identity",
403
594
  PERMISSION_BINDING: "system.permission-binding",
404
595
  REALM_MATCH: "system.realm-match",
405
- REALM_BOUND: "system.realm-bound",
406
- REALM_OR_GLOBAL: "system.realm-or-global",
407
596
  CLIENT_NAMES_SELF_MANAGE: "system.client-names-self-manage",
408
597
  ROBOT_NAMES_SELF_MANAGE: "system.robot-names-self-manage",
409
598
  USER_NAMES_SELF_MANAGE: "system.user-names-self-manage"
@@ -708,7 +897,7 @@ var RealmMatchPolicyValidator = class extends Container {
708
897
  this.mount("attribute_name", createValidator(z.string().min(3).or(z.array(z.string().min(3))).or(z.null()).or(z.undefined()).optional()));
709
898
  this.mount("attribute_name_strict", createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
710
899
  this.mount("attribute_null_match_all", createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
711
- this.mount("identity_master_match_all", createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
900
+ this.mount("scope", createValidator(z.enum(RealmScope).or(z.null()).or(z.undefined()).optional()));
712
901
  this.mount("invert", createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
713
902
  }
714
903
  };
@@ -734,6 +923,11 @@ var RealmMatchPolicyEvaluator = class {
734
923
  path: ctx.path
735
924
  })]
736
925
  };
926
+ if (policy.scope) {
927
+ if (!ctx.data || !ctx.data.has("realmMatch")) return { success: true };
928
+ const resourceRealm = ctx.data.get("realmMatch");
929
+ return { success: maybeInvertPolicyOutcome(realmScopeMatches(policy.scope, resourceRealm ?? null, identity.realmId, identity.realmName), policy.invert) };
930
+ }
737
931
  const attributes = await this.attributesEvaluator.accessData(ctx);
738
932
  if (!attributes) return {
739
933
  success: false,
@@ -743,7 +937,6 @@ var RealmMatchPolicyEvaluator = class {
743
937
  path: ctx.path
744
938
  })]
745
939
  };
746
- if ((policy.identity_master_match_all ?? true) && identity.realmName && identity.realmName === "master") return { success: true };
747
940
  let keys;
748
941
  if (policy.attribute_name) if (Array.isArray(policy.attribute_name)) keys = policy.attribute_name;
749
942
  else keys = [policy.attribute_name];
@@ -910,6 +1103,18 @@ const PolicyDefaultEvaluators = {
910
1103
  ["time"]: new TimePolicyEvaluator()
911
1104
  };
912
1105
  //#endregion
1106
+ //#region src/policy/input.ts
1107
+ /**
1108
+ * Build a {@link PolicyData} bag from a typed {@link PolicyInput} seed. Well-known keys
1109
+ * (identity / attributes / realmMatch) are type-checked; unknown keys are accepted as-is.
1110
+ *
1111
+ * Prefer this over `new PolicyData({ ... })` at construction sites so the key vocabulary and
1112
+ * per-key value types live in one place.
1113
+ */
1114
+ function definePolicyData(input = {}) {
1115
+ return new PolicyData(input);
1116
+ }
1117
+ //#endregion
913
1118
  //#region src/permission/evaluator/module.ts
914
1119
  var PermissionEvaluator = class {
915
1120
  provider;
@@ -942,7 +1147,7 @@ var PermissionEvaluator = class {
942
1147
  const decisionStrategy = options.decisionStrategy ?? DecisionStrategy.UNANIMOUS;
943
1148
  const issues = [];
944
1149
  let count = 0;
945
- const dataBase = ctx.input || new PolicyData();
1150
+ const dataBase = ctx.data || new PolicyData();
946
1151
  for (const name of ctx.name) {
947
1152
  const binding = await this.findOne(name, {
948
1153
  realmId: ctx.realmId,
@@ -961,8 +1166,8 @@ var PermissionEvaluator = class {
961
1166
  }
962
1167
  continue;
963
1168
  }
964
- const policies = binding.policies ?? [];
965
- if (policies.length === 0) {
1169
+ const grantPolicies = binding.grants.map((grant) => grant.policy).filter((grantPolicy) => !!grantPolicy);
1170
+ if (grantPolicies.length < binding.grants.length) {
966
1171
  if (decisionStrategy === DecisionStrategy.AFFIRMATIVE) return;
967
1172
  count++;
968
1173
  continue;
@@ -971,8 +1176,8 @@ var PermissionEvaluator = class {
971
1176
  data.set("permissionBinding", binding);
972
1177
  const compositePolicy = {
973
1178
  type: "composite",
974
- decision_strategy: binding.permission.decision_strategy ?? DecisionStrategy.UNANIMOUS,
975
- children: policies
1179
+ decision_strategy: DecisionStrategy.AFFIRMATIVE,
1180
+ children: grantPolicies
976
1181
  };
977
1182
  const evaluationResult = await this.policyEngine.evaluate(compositePolicy, definePolicyEvaluationContext({
978
1183
  include: options.policiesIncluded,
@@ -1038,6 +1243,6 @@ var PermissionEvaluator = class {
1038
1243
  }
1039
1244
  };
1040
1245
  //#endregion
1041
- export { AttributeNamesPolicyEvaluator, AttributeNamesPolicyValidator, AttributesPolicyEvaluator, AttributesPolicyValidator, BuiltInPolicyType, CompositePolicyEvaluator, CompositePolicyValidator, DatePolicyEvaluator, DatePolicyValidator, IdentityPolicyEvaluator, IdentityPolicyValidator, PERMISSION_ERROR_INSTANCE, POLICY_ERROR_INSTANCE, PermissionBindingPolicyEvaluator, PermissionBindingPolicyValidator, PermissionError, PermissionEvaluator, PermissionMemoryProvider, PolicyData, PolicyDefaultEvaluators, PolicyEngine, PolicyError, PolicyIssueCode, PolicyIssueSeverity, RealmMatchPolicyEvaluator, RealmMatchPolicyValidator, SystemPolicyName, TimePolicyEvaluator, TimePolicyInterval, TimePolicyValidator, buildPermissionKey, defineAttributesPolicy, definePolicyEvaluationContext, definePolicyIssueGroup, definePolicyIssueItem, definePolicyWithType, isCompositePolicy, isIntervalForDayOfMonth, isIntervalForDayOfWeek, isIntervalForDayOfYear, isPermissionError, isPermissionPolicyBindingEqual, isPolicyError, maybeInvertPolicyOutcome, mergePermissionPolicyBindings };
1246
+ export { AttributeNamesPolicyEvaluator, AttributeNamesPolicyValidator, AttributesPolicyEvaluator, AttributesPolicyValidator, BuiltInPolicyType, CompositePolicyEvaluator, CompositePolicyValidator, DatePolicyEvaluator, DatePolicyValidator, IdentityPolicyEvaluator, IdentityPolicyValidator, PERMISSION_ERROR_INSTANCE, POLICY_ERROR_INSTANCE, PermissionBindingPolicyEvaluator, PermissionBindingPolicyValidator, PermissionError, PermissionEvaluator, PermissionMemoryProvider, PolicyData, PolicyDefaultEvaluators, PolicyEngine, PolicyError, PolicyIssueCode, PolicyIssueSeverity, REALM_SCOPE_ORDER, RealmMatchPolicyEvaluator, RealmMatchPolicyValidator, RealmScope, SystemPolicyName, TimePolicyEvaluator, TimePolicyInterval, TimePolicyValidator, aggregatePermissionPolicyBindings, buildPermissionKey, compareRealmScope, defineAttributesPolicy, definePolicyData, definePolicyEvaluationContext, definePolicyIssueGroup, definePolicyIssueItem, definePolicyWithType, grantDominates, isCompositePolicy, isIntervalForDayOfMonth, isIntervalForDayOfWeek, isIntervalForDayOfYear, isPermissionError, isPermissionPolicyBindingEqual, isPolicyError, maxRealmScope, maybeInvertPolicyOutcome, minRealmScope, normalizeRealmScope, realmScopeMatches };
1042
1247
 
1043
1248
  //# sourceMappingURL=index.mjs.map