toride 0.3.0 → 0.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.
@@ -1,8 +1,56 @@
1
1
  // src/policy/schema.ts
2
2
  import * as v from "valibot";
3
- var AttributeTypeSchema = v.picklist(["string", "number", "boolean"]);
3
+ var AttributeTypeSchema = v.picklist(["string", "number", "boolean", "string[]", "number[]", "boolean[]"]);
4
+ var MAX_ATTRIBUTE_DEPTH = 3;
5
+ function getAttributeDepth(schema, currentDepth = 0) {
6
+ if (typeof schema !== "object" || schema === null) {
7
+ return currentDepth;
8
+ }
9
+ const obj = schema;
10
+ if (obj.kind === "primitive") {
11
+ return currentDepth;
12
+ }
13
+ if (obj.kind === "object" && typeof obj.fields === "object" && obj.fields !== null) {
14
+ const fields = obj.fields;
15
+ let maxDepth = currentDepth;
16
+ for (const field of Object.values(fields)) {
17
+ const fieldDepth = getAttributeDepth(field, currentDepth + 1);
18
+ if (fieldDepth > maxDepth) {
19
+ maxDepth = fieldDepth;
20
+ }
21
+ }
22
+ return maxDepth;
23
+ }
24
+ if (obj.kind === "array" && typeof obj.items === "object" && obj.items !== null) {
25
+ return getAttributeDepth(obj.items, currentDepth);
26
+ }
27
+ return currentDepth;
28
+ }
29
+ function checkAttributeDepth(input) {
30
+ return getAttributeDepth(input) <= MAX_ATTRIBUTE_DEPTH;
31
+ }
32
+ var PrimitiveAttributeSchemaNodeSchema = v.object({
33
+ kind: v.literal("primitive"),
34
+ type: AttributeTypeSchema
35
+ });
36
+ var ObjectAttributeSchemaNodeSchema = v.object({
37
+ kind: v.literal("object"),
38
+ fields: v.record(v.string(), v.lazy(() => AttributeSchemaNodeSchema))
39
+ });
40
+ var ArrayAttributeSchemaNodeSchema = v.object({
41
+ kind: v.literal("array"),
42
+ items: v.lazy(() => AttributeSchemaNodeSchema)
43
+ });
44
+ var AttributeSchemaNodeSchema = v.pipe(
45
+ v.union([
46
+ PrimitiveAttributeSchemaNodeSchema,
47
+ ObjectAttributeSchemaNodeSchema,
48
+ ArrayAttributeSchemaNodeSchema
49
+ ]),
50
+ v.check(checkAttributeDepth, "Attribute schema exceeds maximum depth of 3")
51
+ );
4
52
  var ActorDeclarationSchema = v.object({
5
- attributes: v.record(v.string(), AttributeTypeSchema)
53
+ attributes: v.record(v.string(), AttributeSchemaNodeSchema)
6
54
  });
7
55
  var ConditionOperatorSchema = v.union([
8
56
  v.object({ eq: v.unknown() }),
@@ -54,7 +102,7 @@ var FieldAccessDefSchema = v.object({
54
102
  var ResourceBlockSchema = v.object({
55
103
  roles: v.array(v.string()),
56
104
  permissions: v.array(v.string()),
57
- attributes: v.optional(v.record(v.string(), AttributeTypeSchema)),
105
+ attributes: v.optional(v.record(v.string(), AttributeSchemaNodeSchema)),
58
106
  relations: v.optional(v.record(v.string(), v.string())),
59
107
  grants: v.optional(v.record(v.string(), v.array(v.string()))),
60
108
  derived_roles: v.optional(v.array(DerivedRoleEntrySchema)),
@@ -122,6 +170,20 @@ var DepthLimitError = class extends Error {
122
170
  this.limitType = limitType;
123
171
  }
124
172
  };
173
+ var ForbiddenError = class extends Error {
174
+ actor;
175
+ action;
176
+ resourceType;
177
+ constructor(actor, action, resourceType) {
178
+ super(
179
+ `Actor "${actor.type}:${actor.id}" is forbidden from performing "${action}" on resource type "${resourceType}"`
180
+ );
181
+ this.name = "ForbiddenError";
182
+ this.actor = actor;
183
+ this.action = action;
184
+ this.resourceType = resourceType;
185
+ }
186
+ };
125
187
 
126
188
  // src/policy/validator.ts
127
189
  function extractActorAttributes(condition) {
@@ -1434,7 +1496,7 @@ var OPERATOR_KEYS2 = /* @__PURE__ */ new Set([
1434
1496
  async function buildConstraints(actor, action, resourceType, cache, policy, options) {
1435
1497
  const resourceBlock = policy.resources[resourceType];
1436
1498
  if (!resourceBlock) {
1437
- return { forbidden: true };
1499
+ return { ok: false };
1438
1500
  }
1439
1501
  const env = options?.env ?? {};
1440
1502
  const rolesGrantingAction = findRolesGrantingAction(action, resourceBlock);
@@ -1443,7 +1505,7 @@ async function buildConstraints(actor, action, resourceType, cache, policy, opti
1443
1505
  (r) => r.effect === "permit" && r.permissions.includes(action)
1444
1506
  );
1445
1507
  if (permitRules2.length === 0) {
1446
- return { forbidden: true };
1508
+ return { ok: false };
1447
1509
  }
1448
1510
  }
1449
1511
  const roleConstraintCache = /* @__PURE__ */ new Map();
@@ -1504,7 +1566,7 @@ async function buildConstraints(actor, action, resourceType, cache, policy, opti
1504
1566
  }
1505
1567
  }
1506
1568
  if (pathConstraints.length === 0) {
1507
- return { forbidden: true };
1569
+ return { ok: false };
1508
1570
  }
1509
1571
  let combined;
1510
1572
  if (pathConstraints.length === 1) {
@@ -1526,12 +1588,12 @@ async function buildConstraints(actor, action, resourceType, cache, policy, opti
1526
1588
  }
1527
1589
  combined = simplify(combined);
1528
1590
  if (combined.type === "always") {
1529
- return { unrestricted: true };
1591
+ return { ok: true, constraint: null };
1530
1592
  }
1531
1593
  if (combined.type === "never") {
1532
- return { forbidden: true };
1594
+ return { ok: false };
1533
1595
  }
1534
- return { constraints: combined };
1596
+ return { ok: true, constraint: combined };
1535
1597
  }
1536
1598
  function findRolesGrantingAction(action, resourceBlock) {
1537
1599
  const grants = resourceBlock.grants ?? {};
@@ -1949,11 +2011,11 @@ function translateConstraints(constraint, adapter, _depth = 0) {
1949
2011
  // Terminal nodes - should not reach the translator
1950
2012
  case "always":
1951
2013
  throw new Error(
1952
- 'Constraint node "always" should be simplified out before translation. Use buildConstraints() which returns ConstraintResult with unrestricted/forbidden sentinels.'
2014
+ 'Constraint node "always" should be simplified out before translation. Check result.ok and result.constraint before calling translateConstraints().'
1953
2015
  );
1954
2016
  case "never":
1955
2017
  throw new Error(
1956
- 'Constraint node "never" should be simplified out before translation. Use buildConstraints() which returns ConstraintResult with unrestricted/forbidden sentinels.'
2018
+ 'Constraint node "never" should be simplified out before translation. Check result.ok and result.constraint before calling translateConstraints().'
1957
2019
  );
1958
2020
  default: {
1959
2021
  const _exhaustive = constraint;
@@ -2168,9 +2230,9 @@ var Toride = class {
2168
2230
  const a = actor;
2169
2231
  const sharedCache = new AttributeCache(this.resolvers);
2170
2232
  const results = [];
2171
- for (const check of checks) {
2172
- const r = check.resource;
2173
- const act = check.action;
2233
+ for (const check2 of checks) {
2234
+ const r = check2.resource;
2235
+ const act = check2.action;
2174
2236
  const result = await this.evaluateInternal(
2175
2237
  a,
2176
2238
  act,
@@ -2211,17 +2273,12 @@ var Toride = class {
2211
2273
  * T064: Translate constraint AST using an adapter.
2212
2274
  * Dispatches each constraint node to the adapter's methods.
2213
2275
  *
2214
- * Accepts ConstraintResult<R> from buildConstraints() and returns
2276
+ * Accepts Constraint (the AST) from buildConstraints() and returns
2215
2277
  * TQueryMap[R] — the adapter's mapped output type for resource R.
2216
- * The resource type R is inferred from the ConstraintResult phantom type.
2278
+ * Callers must check result.ok and result.constraint before calling this method.
2217
2279
  */
2218
- translateConstraints(constraints, adapter) {
2219
- if ("unrestricted" in constraints || "forbidden" in constraints) {
2220
- throw new Error(
2221
- "Cannot translate unrestricted or forbidden ConstraintResult. Check for 'constraints' property before calling translateConstraints()."
2222
- );
2223
- }
2224
- return translateConstraints(constraints.constraints, adapter);
2280
+ translateConstraints(constraint, adapter) {
2281
+ return translateConstraints(constraint, adapter);
2225
2282
  }
2226
2283
  /**
2227
2284
  * T072: Fire onDecision audit callback via microtask (non-blocking).
@@ -2260,10 +2317,10 @@ var Toride = class {
2260
2317
  const callback = this.options.onQuery;
2261
2318
  if (!callback) return;
2262
2319
  let resultType;
2263
- if ("unrestricted" in constraintResult && constraintResult.unrestricted) {
2264
- resultType = "unrestricted";
2265
- } else if ("forbidden" in constraintResult && constraintResult.forbidden) {
2320
+ if (!constraintResult.ok) {
2266
2321
  resultType = "forbidden";
2322
+ } else if (constraintResult.constraint === null) {
2323
+ resultType = "unrestricted";
2267
2324
  } else {
2268
2325
  resultType = "constrained";
2269
2326
  }
@@ -2360,10 +2417,12 @@ async function runTestCases(policy, tests) {
2360
2417
  }
2361
2418
 
2362
2419
  export {
2420
+ ConditionExpressionSchema,
2363
2421
  PolicySchema,
2364
2422
  ValidationError,
2365
2423
  CycleError,
2366
2424
  DepthLimitError,
2425
+ ForbiddenError,
2367
2426
  validatePolicy,
2368
2427
  validatePolicyResult,
2369
2428
  validatePolicyStrict,
package/dist/cli.js CHANGED
@@ -7,13 +7,96 @@ import {
7
7
  runTestCases,
8
8
  validatePolicyResult,
9
9
  validatePolicyStrict
10
- } from "./chunk-2AWXNP37.js";
10
+ } from "./chunk-GRFSE3QO.js";
11
11
 
12
12
  // src/cli.ts
13
13
  import { readFileSync, readdirSync, statSync } from "fs";
14
14
  import { resolve, dirname, join } from "path";
15
15
  import * as YAML from "yaml";
16
16
  import * as v from "valibot";
17
+ function normalizeAttributeValue(raw) {
18
+ if (raw === null || raw === void 0) return raw;
19
+ if (typeof raw === "string" && ["string", "number", "boolean"].includes(raw)) {
20
+ return { kind: "primitive", type: raw };
21
+ }
22
+ if (typeof raw === "object" && !Array.isArray(raw)) {
23
+ const obj = raw;
24
+ if ("kind" in obj && obj.kind !== void 0) {
25
+ if (obj.kind === "object" && typeof obj.fields === "object" && obj.fields !== null) {
26
+ const normalizedFields = {};
27
+ for (const [key, value] of Object.entries(obj.fields)) {
28
+ normalizedFields[key] = normalizeAttributeValue(value);
29
+ }
30
+ return { ...obj, fields: normalizedFields };
31
+ }
32
+ if (obj.kind === "array" && "items" in obj) {
33
+ return { ...obj, items: normalizeAttributeValue(obj.items) };
34
+ }
35
+ return obj;
36
+ }
37
+ }
38
+ if (typeof raw === "object" && !Array.isArray(raw)) {
39
+ const obj = raw;
40
+ const normalized = {};
41
+ for (const [key, value] of Object.entries(obj)) {
42
+ normalized[key] = normalizeAttributeValue(value);
43
+ }
44
+ return normalized;
45
+ }
46
+ if (Array.isArray(raw)) {
47
+ return raw.map((item) => normalizeAttributeValue(item));
48
+ }
49
+ return raw;
50
+ }
51
+ function normalizeAttributeRecord(attrs) {
52
+ const normalizedAttrs = {};
53
+ for (const [attrKey, attrValue] of Object.entries(attrs)) {
54
+ normalizedAttrs[attrKey] = normalizeAttributeValue(attrValue);
55
+ }
56
+ return normalizedAttrs;
57
+ }
58
+ function normalizeAttributes(raw) {
59
+ if (raw === null || raw === void 0 || typeof raw !== "object" || Array.isArray(raw)) {
60
+ return raw;
61
+ }
62
+ const obj = raw;
63
+ const normalized = { ...obj };
64
+ if ("actors" in normalized && typeof normalized.actors === "object" && normalized.actors !== null) {
65
+ const actors = normalized.actors;
66
+ const normalizedActors = {};
67
+ for (const [actorName, actorDef] of Object.entries(actors)) {
68
+ if (typeof actorDef === "object" && actorDef !== null) {
69
+ const actor = actorDef;
70
+ const normalizedActor = { ...actor };
71
+ if ("attributes" in normalizedActor && typeof normalizedActor.attributes === "object" && normalizedActor.attributes !== null) {
72
+ normalizedActor.attributes = normalizeAttributeRecord(normalizedActor.attributes);
73
+ }
74
+ normalizedActors[actorName] = normalizedActor;
75
+ } else {
76
+ normalizedActors[actorName] = actorDef;
77
+ }
78
+ }
79
+ normalized.actors = normalizedActors;
80
+ }
81
+ if ("resources" in normalized && typeof normalized.resources === "object" && normalized.resources !== null) {
82
+ const resources = normalized.resources;
83
+ const normalizedResources = {};
84
+ for (const [resName, resDef] of Object.entries(resources)) {
85
+ if (typeof resDef === "object" && resDef !== null) {
86
+ const resource = resDef;
87
+ const normalizedResource = { ...resource };
88
+ if ("attributes" in normalizedResource && typeof normalizedResource.attributes === "object" && normalizedResource.attributes !== null) {
89
+ normalizedResource.attributes = normalizeAttributeRecord(normalizedResource.attributes);
90
+ }
91
+ normalizedResources[resName] = normalizedResource;
92
+ } else {
93
+ normalizedResources[resName] = resDef;
94
+ }
95
+ }
96
+ normalized.resources = normalizedResources;
97
+ }
98
+ return normalized;
99
+ }
17
100
  function loadPolicyFile(filePath) {
18
101
  const absPath = resolve(filePath);
19
102
  let content;
@@ -42,7 +125,8 @@ function loadPolicyFile(filePath) {
42
125
  );
43
126
  }
44
127
  }
45
- const result = v.safeParse(PolicySchema, raw);
128
+ const normalizedRaw = normalizeAttributes(raw);
129
+ const result = v.safeParse(PolicySchema, normalizedRaw);
46
130
  if (!result.success) {
47
131
  const issue = result.issues[0];
48
132
  const path = issue?.path?.map((p) => String(p.key)).join(".") ?? "";
@@ -45,6 +45,58 @@ interface DefaultSchema extends TorideSchema {
45
45
  actorAttributeMap: Record<string, Record<string, unknown>>;
46
46
  relationMap: Record<string, Record<string, string>>;
47
47
  }
48
+ /**
49
+ * Virtual field mapping configuration.
50
+ * Describes how a virtual field maps to a related resource query.
51
+ */
52
+ interface VirtualFieldMapping {
53
+ /** The relation name to query */
54
+ readonly relation: string;
55
+ /** The field in the related resource to match against */
56
+ readonly matchField: string;
57
+ /** Optional filter to apply to the relation query */
58
+ readonly filter?: Record<string, unknown>;
59
+ }
60
+ /**
61
+ * Extracts keys from T whose values are arrays.
62
+ */
63
+ type ArrayKeys<T> = {
64
+ [K in keyof T]: T[K] extends unknown[] ? K : never;
65
+ }[keyof T];
66
+ type ModelScalars<T> = T extends {
67
+ scalars: infer S extends Record<string, unknown>;
68
+ } ? S : T extends Record<string, unknown> ? T : never;
69
+ type UnwrapRelation<T> = T extends readonly (infer U)[] ? U : NonNullable<T>;
70
+ type PayloadRelations<T> = T extends {
71
+ objects: infer O extends Record<string, unknown>;
72
+ } ? {
73
+ [K in keyof O & string]: ModelScalars<UnwrapRelation<O[K]>>;
74
+ } : Record<string, never>;
75
+ type VirtualFieldMappingFor<TRelations extends Record<string, Record<string, unknown>>> = {
76
+ [R in keyof TRelations & string]: {
77
+ readonly relation: R;
78
+ readonly matchField: keyof TRelations[R] & string;
79
+ readonly filter?: {
80
+ readonly [F in keyof TRelations[R]]?: TRelations[R][F];
81
+ };
82
+ };
83
+ }[keyof TRelations & string];
84
+ /**
85
+ * Conditional type that uses model-aware detection when TModelMap is provided,
86
+ * falls back to ArrayKeys otherwise.
87
+ */
88
+ type VirtualFieldKeysFor<S extends TorideSchema, R extends string, TModelMap> = [TModelMap] extends [never] ? S["resourceAttributeMap"][R] extends Record<string, unknown> ? Record<string, unknown> extends S["resourceAttributeMap"][R] ? string : ArrayKeys<S["resourceAttributeMap"][R]> : never : R extends keyof TModelMap ? Exclude<keyof S["resourceAttributeMap"][R] & string, keyof ModelScalars<TModelMap[R]> & string> : string;
89
+ /**
90
+ * Per-resource mapping of virtual field keys to VirtualFieldMapping.
91
+ * When TModelMap is provided, uses model-aware detection for virtual field keys.
92
+ */
93
+ type VirtualFieldsConfig<S extends TorideSchema, TModelMap = never> = {
94
+ [R in S["resources"]]?: {
95
+ [K in VirtualFieldKeysFor<S, R & string, TModelMap>]?: R extends keyof TModelMap ? TModelMap[R] extends {
96
+ objects: Record<string, unknown>;
97
+ } ? VirtualFieldMappingFor<PayloadRelations<TModelMap[R]>> : VirtualFieldMapping : VirtualFieldMapping;
98
+ };
99
+ };
48
100
  /**
49
101
  * Represents an entity performing actions.
50
102
  * Generic discriminated union over actor types in S.
@@ -145,10 +197,27 @@ interface TorideOptions<S extends TorideSchema = DefaultSchema> {
145
197
  readonly onQuery?: (event: QueryEvent) => void;
146
198
  }
147
199
  /** Attribute type for actor declarations. */
148
- type AttributeType = "string" | "number" | "boolean";
200
+ type AttributeType = "string" | "number" | "boolean" | "string[]" | "number[]" | "boolean[]";
201
+ /** Schema for a primitive attribute. */
202
+ interface PrimitiveAttributeSchema {
203
+ readonly kind: "primitive";
204
+ readonly type: AttributeType;
205
+ }
206
+ /** Schema for a nested object attribute. */
207
+ interface ObjectAttributeSchema {
208
+ readonly kind: "object";
209
+ readonly fields: Record<string, AttributeSchema>;
210
+ }
211
+ /** Schema for an array attribute. */
212
+ interface ArrayAttributeSchema {
213
+ readonly kind: "array";
214
+ readonly items: AttributeSchema;
215
+ }
216
+ /** Discriminated union of all attribute schema types. */
217
+ type AttributeSchema = PrimitiveAttributeSchema | ObjectAttributeSchema | ArrayAttributeSchema;
149
218
  /** Actor type declaration with attribute schema. */
150
219
  interface ActorDeclaration {
151
- readonly attributes: Record<string, AttributeType>;
220
+ readonly attributes: Record<string, AttributeSchema>;
152
221
  }
153
222
  /** Global role definition derived from actor attributes. */
154
223
  interface GlobalRole {
@@ -190,7 +259,7 @@ interface ResourceBlock {
190
259
  readonly roles: string[];
191
260
  readonly permissions: string[];
192
261
  /** Optional typed attribute declarations for this resource type. */
193
- readonly attributes?: Record<string, AttributeType>;
262
+ readonly attributes?: Record<string, AttributeSchema>;
194
263
  /** Relations map field names to target resource type names (simplified). */
195
264
  readonly relations?: Record<string, string>;
196
265
  readonly grants?: Record<string, string[]>;
@@ -324,6 +393,13 @@ declare class DepthLimitError extends Error {
324
393
  readonly limitType: "condition" | "derivation";
325
394
  constructor(message: string, limit: number, limitType: "condition" | "derivation");
326
395
  }
396
+ /** Thrown when an actor is forbidden from performing an action. */
397
+ declare class ForbiddenError extends Error {
398
+ readonly actor: ActorRef;
399
+ readonly action: string;
400
+ readonly resourceType: string;
401
+ constructor(actor: ActorRef, action: string, resourceType: string);
402
+ }
327
403
 
328
404
  /**
329
405
  * A serializable map of permissions keyed by "Type:id".
@@ -370,4 +446,4 @@ declare class TorideClient<S extends TorideSchema = DefaultSchema> {
370
446
  permittedActions<R extends S["resources"]>(resource: ClientResourceRef<S, R>): S["permissionMap"][R][];
371
447
  }
372
448
 
373
- export { type ActorRef as A, type BatchCheckItem as B, type CheckOptions as C, type DefaultSchema as D, type ExplainResult as E, type FieldAccessDef as F, type GlobalRole as G, type MatchedRule as M, type Policy as P, type QueryEvent as Q, type ResourceRef as R, type SimpleConditions as S, type TorideSchema as T, ValidationError as V, type TorideOptions as a, type PermissionSnapshot as b, type TestCase as c, type Resolvers as d, type ActorDeclaration as e, type AttributeType as f, type ClientResourceRef as g, type ConditionExpression as h, type ConditionOperator as i, type ConditionValue as j, CycleError as k, type DecisionEvent as l, DepthLimitError as m, type DerivedRoleEntry as n, type DerivedRoleTrace as o, type EvaluatorFn as p, type ResolvedRolesDetail as q, type ResourceBlock as r, type ResourceResolver as s, type Rule as t, TorideClient as u, CLIENT_VERSION as v };
449
+ export { type ActorRef as A, type BatchCheckItem as B, type CheckOptions as C, type DefaultSchema as D, type ExplainResult as E, type FieldAccessDef as F, type GlobalRole as G, type VirtualFieldMapping as H, type VirtualFieldMappingFor as I, type VirtualFieldsConfig as J, CLIENT_VERSION as K, type MatchedRule as M, type ObjectAttributeSchema as O, type Policy as P, type QueryEvent as Q, type ResourceRef as R, type SimpleConditions as S, type TorideSchema as T, ValidationError as V, type TorideOptions as a, type PermissionSnapshot as b, type TestCase as c, type Resolvers as d, type ActorDeclaration as e, type ArrayAttributeSchema as f, type AttributeSchema as g, type AttributeType as h, type ClientResourceRef as i, type ConditionExpression as j, type ConditionOperator as k, type ConditionValue as l, CycleError as m, type DecisionEvent as n, DepthLimitError as o, type DerivedRoleEntry as p, type DerivedRoleTrace as q, type EvaluatorFn as r, ForbiddenError as s, type PayloadRelations as t, type PrimitiveAttributeSchema as u, type ResolvedRolesDetail as v, type ResourceBlock as w, type ResourceResolver as x, type Rule as y, TorideClient as z };
package/dist/client.d.ts CHANGED
@@ -1 +1 @@
1
- export { v as CLIENT_VERSION, g as ClientResourceRef, b as PermissionSnapshot, u as TorideClient } from './client-aExMng5T.js';
1
+ export { K as CLIENT_VERSION, i as ClientResourceRef, b as PermissionSnapshot, z as TorideClient } from './client-CBp3admQ.js';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,64 @@
1
- import { P as Policy, T as TorideSchema, D as DefaultSchema, a as TorideOptions, A as ActorRef, R as ResourceRef, C as CheckOptions, E as ExplainResult, b as PermissionSnapshot, B as BatchCheckItem, c as TestCase, d as Resolvers } from './client-aExMng5T.js';
2
- export { e as ActorDeclaration, f as AttributeType, g as ClientResourceRef, h as ConditionExpression, i as ConditionOperator, j as ConditionValue, k as CycleError, l as DecisionEvent, m as DepthLimitError, n as DerivedRoleEntry, o as DerivedRoleTrace, p as EvaluatorFn, F as FieldAccessDef, G as GlobalRole, M as MatchedRule, Q as QueryEvent, q as ResolvedRolesDetail, r as ResourceBlock, s as ResourceResolver, t as Rule, S as SimpleConditions, u as TorideClient, V as ValidationError } from './client-aExMng5T.js';
1
+ import * as v from 'valibot';
2
+ import { P as Policy, T as TorideSchema, D as DefaultSchema, a as TorideOptions, A as ActorRef, R as ResourceRef, C as CheckOptions, E as ExplainResult, b as PermissionSnapshot, B as BatchCheckItem, c as TestCase, d as Resolvers } from './client-CBp3admQ.js';
3
+ export { e as ActorDeclaration, f as ArrayAttributeSchema, g as AttributeSchema, h as AttributeType, i as ClientResourceRef, j as ConditionExpression, k as ConditionOperator, l as ConditionValue, m as CycleError, n as DecisionEvent, o as DepthLimitError, p as DerivedRoleEntry, q as DerivedRoleTrace, r as EvaluatorFn, F as FieldAccessDef, s as ForbiddenError, G as GlobalRole, M as MatchedRule, O as ObjectAttributeSchema, t as PayloadRelations, u as PrimitiveAttributeSchema, Q as QueryEvent, v as ResolvedRolesDetail, w as ResourceBlock, x as ResourceResolver, y as Rule, S as SimpleConditions, z as TorideClient, V as ValidationError, H as VirtualFieldMapping, I as VirtualFieldMappingFor, J as VirtualFieldsConfig } from './client-CBp3admQ.js';
4
+
5
+ /**
6
+ * ConditionExpression: recursive type using lazy().
7
+ * Either simple conditions, { any: [...] }, or { all: [...] }.
8
+ */
9
+ declare const ConditionExpressionSchema: v.GenericSchema<unknown>;
10
+ declare const PolicySchema: v.ObjectSchema<{
11
+ readonly version: v.LiteralSchema<"1", undefined>;
12
+ readonly actors: v.RecordSchema<v.StringSchema<undefined>, v.ObjectSchema<{
13
+ readonly attributes: v.RecordSchema<v.StringSchema<undefined>, any, undefined>;
14
+ }, undefined>, undefined>;
15
+ readonly global_roles: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.ObjectSchema<{
16
+ readonly actor_type: v.StringSchema<undefined>;
17
+ readonly when: v.GenericSchema<unknown>;
18
+ }, undefined>, undefined>, undefined>;
19
+ readonly resources: v.RecordSchema<v.StringSchema<undefined>, v.ObjectSchema<{
20
+ readonly roles: v.ArraySchema<v.StringSchema<undefined>, undefined>;
21
+ readonly permissions: v.ArraySchema<v.StringSchema<undefined>, undefined>;
22
+ readonly attributes: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, any, undefined>, undefined>;
23
+ readonly relations: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, undefined>;
24
+ readonly grants: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>, undefined>;
25
+ readonly derived_roles: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
26
+ readonly role: v.StringSchema<undefined>;
27
+ readonly from_global_role: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
28
+ readonly from_role: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
29
+ readonly on_relation: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
30
+ readonly from_relation: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
31
+ readonly actor_type: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
32
+ readonly when: v.OptionalSchema<v.GenericSchema<unknown>, undefined>;
33
+ }, undefined>, undefined>, undefined>;
34
+ readonly rules: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
35
+ readonly effect: v.PicklistSchema<["permit", "forbid"], undefined>;
36
+ readonly roles: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
37
+ readonly permissions: v.ArraySchema<v.StringSchema<undefined>, undefined>;
38
+ readonly when: v.GenericSchema<unknown>;
39
+ }, undefined>, undefined>, undefined>;
40
+ readonly field_access: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.ObjectSchema<{
41
+ readonly read: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
42
+ readonly update: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
43
+ }, undefined>, undefined>, undefined>;
44
+ }, undefined>, undefined>;
45
+ readonly tests: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
46
+ readonly name: v.StringSchema<undefined>;
47
+ readonly actor: v.ObjectSchema<{
48
+ readonly type: v.StringSchema<undefined>;
49
+ readonly id: v.StringSchema<undefined>;
50
+ readonly attributes: v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>;
51
+ }, undefined>;
52
+ readonly resolvers: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, undefined>, undefined>;
53
+ readonly action: v.StringSchema<undefined>;
54
+ readonly resource: v.ObjectSchema<{
55
+ readonly type: v.StringSchema<undefined>;
56
+ readonly id: v.StringSchema<undefined>;
57
+ readonly attributes: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, undefined>;
58
+ }, undefined>;
59
+ readonly expected: v.PicklistSchema<["allow", "deny"], undefined>;
60
+ }, undefined>, undefined>, undefined>;
61
+ }, undefined>;
3
62
 
4
63
  /**
5
64
  * Parse and validate a YAML string into a typed Policy object.
@@ -151,13 +210,11 @@ type Constraint = FieldEqConstraint | FieldNeqConstraint | FieldGtConstraint | F
151
210
  type LeafConstraint = FieldEqConstraint | FieldNeqConstraint | FieldGtConstraint | FieldGteConstraint | FieldLtConstraint | FieldLteConstraint | FieldInConstraint | FieldNinConstraint | FieldExistsConstraint | FieldIncludesConstraint | FieldContainsConstraint;
152
211
  /** Result of partial evaluation, tagged with resource type R (phantom). */
153
212
  type ConstraintResult<R extends string = string> = {
154
- readonly unrestricted: true;
155
- readonly __resource?: R;
156
- } | {
157
- readonly forbidden: true;
213
+ readonly ok: true;
214
+ readonly constraint: Constraint | null;
158
215
  readonly __resource?: R;
159
216
  } | {
160
- readonly constraints: Constraint;
217
+ readonly ok: false;
161
218
  readonly __resource?: R;
162
219
  };
163
220
  /**
@@ -244,11 +301,11 @@ declare class Toride<S extends TorideSchema = DefaultSchema> {
244
301
  * T064: Translate constraint AST using an adapter.
245
302
  * Dispatches each constraint node to the adapter's methods.
246
303
  *
247
- * Accepts ConstraintResult<R> from buildConstraints() and returns
304
+ * Accepts Constraint (the AST) from buildConstraints() and returns
248
305
  * TQueryMap[R] — the adapter's mapped output type for resource R.
249
- * The resource type R is inferred from the ConstraintResult phantom type.
306
+ * Callers must check result.ok and result.constraint before calling this method.
250
307
  */
251
- translateConstraints<R extends string, TQueryMap extends Record<string, unknown>>(constraints: ConstraintResult<R>, adapter: ConstraintAdapter<TQueryMap>): TQueryMap[R];
308
+ translateConstraints<R extends string, TQueryMap extends Record<string, unknown>>(constraint: Constraint, adapter: ConstraintAdapter<TQueryMap>): TQueryMap[R];
252
309
  /**
253
310
  * T072: Fire onDecision audit callback via microtask (non-blocking).
254
311
  * Errors are silently swallowed to prevent audit failures from affecting authorization.
@@ -319,4 +376,4 @@ declare function runTestCases(policy: Policy, tests: TestCase[]): Promise<TestRe
319
376
 
320
377
  declare const VERSION = "0.0.1";
321
378
 
322
- export { ActorRef, BatchCheckItem, CheckOptions, type Constraint, type ConstraintAdapter, type ConstraintResult, DefaultSchema, ExplainResult, type LeafConstraint, PermissionSnapshot, Policy, Resolvers, ResourceRef, type StrictValidationResult, TestCase, type TestFileResult, type TestResult, Toride, TorideOptions, TorideSchema, VERSION, type ValidationDiagnostic, type ValidationResult, createMockResolver, createToride, loadJson, loadYaml, mergePolicies, parseInlineTests, parseTestFile, runTestCases, validatePolicy, validatePolicyResult, validatePolicyStrict };
379
+ export { ActorRef, BatchCheckItem, CheckOptions, ConditionExpressionSchema, type Constraint, type ConstraintAdapter, type ConstraintResult, DefaultSchema, ExplainResult, type LeafConstraint, PermissionSnapshot, Policy, PolicySchema, Resolvers, ResourceRef, type StrictValidationResult, TestCase, type TestFileResult, type TestResult, Toride, TorideOptions, TorideSchema, VERSION, type ValidationDiagnostic, type ValidationResult, createMockResolver, createToride, loadJson, loadYaml, mergePolicies, parseInlineTests, parseTestFile, runTestCases, validatePolicy, validatePolicyResult, validatePolicyStrict };