@api-client/core 0.20.1 → 0.20.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.
@@ -5,7 +5,7 @@ import type { ExposedEntity } from './ExposedEntity.js';
5
5
  import type { Action } from './actions/Action.js';
6
6
  import type { DomainEntity } from './DomainEntity.js';
7
7
  import type { DomainProperty } from './DomainProperty.js';
8
- import { AccessRule, AccessRuleExecutionPhase } from './rules/AccessRule.js';
8
+ import { AccessRule } from './rules/AccessRule.js';
9
9
  /**
10
10
  * Identifies a specific exposed entity and its action kind.
11
11
  */
@@ -31,11 +31,21 @@ export interface RuntimeApiModelSchema extends ApiModelSchema {
31
31
  routingMap: RoutingMap;
32
32
  }
33
33
  export interface RuntimeResolvedAction {
34
- entity: ExposedEntity;
34
+ exposure: ExposedEntity;
35
+ entity: DomainEntity;
35
36
  action: Action;
36
37
  params: Record<string, string>;
37
38
  }
38
39
  export type RuleEvaluator = (rule: AccessRule) => Promise<boolean | undefined> | boolean | undefined;
40
+ export interface PhaseRules {
41
+ permissionRules: AccessRule[];
42
+ mandatoryRules: AccessRule[];
43
+ }
44
+ export interface ActionRulesCache {
45
+ preFetch: PhaseRules;
46
+ fetch: PhaseRules;
47
+ postFetch: PhaseRules;
48
+ }
39
49
  /**
40
50
  * An optimized API Model subclass designed for fast runtime lookups.
41
51
  * It pre-compiles the RoutingMap into a radix tree for O(log N) or faster endpoint resolution.
@@ -71,23 +81,9 @@ export declare class RuntimeApiModel extends ApiModel {
71
81
  */
72
82
  lookupAction(method: string, path: string): RuntimeResolvedAction | undefined;
73
83
  /**
74
- * Evaluates access rules for a given action and phase.
75
- *
76
- * The evaluation process follows two phases per execution phase (PRE_FETCH, FETCH, POST_FETCH):
77
- * 1. Mandatory Phase: All rules marked as `mandatory: true` across all levels must return true.
78
- * If any fail, the request is immediately rejected.
79
- * 2. Permission Phase: Evaluation follows the hierarchy from most specific to most general:
80
- * Action -> Endpoint (ExposedEntity) -> API Model.
81
- * If an explicit allow (true) or deny (false) is hit, evaluation stops and returns the result.
82
- * If no rules match (all return undefined), the request is rejected by default.
83
- *
84
- * @param action The resolved action to evaluate.
85
- * @param evaluator A callback that evaluates a single rule. Should return true (allow),
86
- * false (deny), or undefined (no hit).
87
- * @param phase The execution phase to evaluate.
88
- * @returns A promise that resolves to true if access is granted, false if denied.
84
+ * Retrieves the precomputed and shadowed effective rules for a given action.
89
85
  */
90
- evaluateAccess(action: RuntimeResolvedAction, evaluator: RuleEvaluator, phase: AccessRuleExecutionPhase): Promise<boolean>;
86
+ getEffectiveRules(action: RuntimeResolvedAction): ActionRulesCache;
91
87
  toJSON(): RuntimeApiModelSchema;
92
88
  }
93
89
  //# sourceMappingURL=RuntimeApiModel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RuntimeApiModel.d.ts","sourceRoot":"","sources":["../../../src/modeling/RuntimeApiModel.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAA;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACzD,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAA;AAG5E;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,gBAAgB,EAAE,MAAM,CAAA;IACxB,UAAU,EAAE,UAAU,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,WAAW,CAAA;CACpB;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC,CAAA;AAE1D;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,cAAc;IAC3D,UAAU,EAAE,UAAU,CAAA;CACvB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,aAAa,CAAA;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC/B;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,GAAG,OAAO,GAAG,SAAS,CAAA;AAapG;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,QAAQ;;IAY3C;;OAEG;IACH,cAAc,EAAE;QACd,IAAI,CAAC,EAAE,YAAY,CAAA;KACpB,CAAK;IAEN;;OAEG;IACH,gBAAgB,EAAE;QAChB,QAAQ,CAAC,EAAE,cAAc,CAAA;QACzB,QAAQ,CAAC,EAAE,cAAc,CAAA;QACzB,IAAI,CAAC,EAAE,cAAc,CAAA;KACtB,CAAK;IAYN;;;OAGG;IACH,IAAW,iBAAiB,IAAI,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,CAElE;gBAEW,MAAM,EAAE,qBAAqB,EAAE,YAAY,EAAE,gBAAgB;IAoJzE;;;;;;OAMG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS;IAoC7E;;;;;;;;;;;;;;;;OAgBG;IACG,cAAc,CAClB,MAAM,EAAE,qBAAqB,EAC7B,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,OAAO,CAAC;IAwCV,MAAM,IAAI,qBAAqB;CAazC"}
1
+ {"version":3,"file":"RuntimeApiModel.d.ts","sourceRoot":"","sources":["../../../src/modeling/RuntimeApiModel.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAA;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACzD,OAAO,EAAE,UAAU,EAA4B,MAAM,uBAAuB,CAAA;AAG5E;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,gBAAgB,EAAE,MAAM,CAAA;IACxB,UAAU,EAAE,UAAU,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,WAAW,CAAA;CACpB;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC,CAAA;AAE1D;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,cAAc;IAC3D,UAAU,EAAE,UAAU,CAAA;CACvB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,aAAa,CAAA;IACvB,MAAM,EAAE,YAAY,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC/B;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,GAAG,OAAO,GAAG,SAAS,CAAA;AAEpG,MAAM,WAAW,UAAU;IACzB,eAAe,EAAE,UAAU,EAAE,CAAA;IAC7B,cAAc,EAAE,UAAU,EAAE,CAAA;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,UAAU,CAAA;IACpB,KAAK,EAAE,UAAU,CAAA;IACjB,SAAS,EAAE,UAAU,CAAA;CACtB;AAED;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,QAAQ;;IAY3C;;OAEG;IACH,cAAc,EAAE;QACd,IAAI,CAAC,EAAE,YAAY,CAAA;KACpB,CAAK;IAEN;;OAEG;IACH,gBAAgB,EAAE;QAChB,QAAQ,CAAC,EAAE,cAAc,CAAA;QACzB,QAAQ,CAAC,EAAE,cAAc,CAAA;QACzB,IAAI,CAAC,EAAE,cAAc,CAAA;KACtB,CAAK;IAYN;;;OAGG;IACH,IAAW,iBAAiB,IAAI,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,CAElE;gBAEW,MAAM,EAAE,qBAAqB,EAAE,YAAY,EAAE,gBAAgB;IAoJzE;;;;;;OAMG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS;IA0C7E;;OAEG;IACH,iBAAiB,CAAC,MAAM,EAAE,qBAAqB,GAAG,gBAAgB;IASzD,MAAM,IAAI,qBAAqB;CAazC"}
@@ -191,73 +191,35 @@ export class RuntimeApiModel extends ApiModel {
191
191
  return undefined;
192
192
  }
193
193
  const params = exec(path, matchedRoute);
194
- const entity = this.exposes.get(def.lookup.exposedEntityKey);
195
- if (!entity) {
196
- return undefined;
194
+ const exposure = this.exposes.get(def.lookup.exposedEntityKey);
195
+ if (!exposure) {
196
+ throw new Exception('Missing exposure ' + def.lookup.exposedEntityKey, { code: 'API_MODEL_ERROR', status: 500 });
197
197
  }
198
- const action = entity.actions.find((a) => a.kind === def.lookup.actionKind);
198
+ const action = exposure.actions.find((a) => a.kind === def.lookup.actionKind);
199
199
  if (!action) {
200
- return undefined;
200
+ throw new Exception('Missing action ' + def.lookup.actionKind, { code: 'API_MODEL_ERROR', status: 500 });
201
+ }
202
+ const entity = this.domain?.findEntity(exposure.entity.key, exposure.entity.domain);
203
+ if (!entity) {
204
+ throw new Exception('Missing entity ' + exposure.entity.key, { code: 'API_MODEL_ERROR', status: 500 });
201
205
  }
202
206
  return {
207
+ exposure,
203
208
  entity,
204
209
  action,
205
210
  params,
206
211
  };
207
212
  }
208
213
  /**
209
- * Evaluates access rules for a given action and phase.
210
- *
211
- * The evaluation process follows two phases per execution phase (PRE_FETCH, FETCH, POST_FETCH):
212
- * 1. Mandatory Phase: All rules marked as `mandatory: true` across all levels must return true.
213
- * If any fail, the request is immediately rejected.
214
- * 2. Permission Phase: Evaluation follows the hierarchy from most specific to most general:
215
- * Action -> Endpoint (ExposedEntity) -> API Model.
216
- * If an explicit allow (true) or deny (false) is hit, evaluation stops and returns the result.
217
- * If no rules match (all return undefined), the request is rejected by default.
218
- *
219
- * @param action The resolved action to evaluate.
220
- * @param evaluator A callback that evaluates a single rule. Should return true (allow),
221
- * false (deny), or undefined (no hit).
222
- * @param phase The execution phase to evaluate.
223
- * @returns A promise that resolves to true if access is granted, false if denied.
214
+ * Retrieves the precomputed and shadowed effective rules for a given action.
224
215
  */
225
- async evaluateAccess(action, evaluator, phase) {
216
+ getEffectiveRules(action) {
226
217
  let cachedRules = this.#actionRulesCache.get(action.action);
227
218
  if (!cachedRules) {
228
- // Fallback if somehow action is not cached (e.g. dynamically added after initialization or in tests)
229
- cachedRules = this.#computeEffectiveRules(action.action, action.entity);
219
+ cachedRules = this.#computeEffectiveRules(action.action, action.exposure);
230
220
  this.#actionRulesCache.set(action.action, cachedRules);
231
221
  }
232
- let rulesForPhase;
233
- if (phase === AccessRuleExecutionPhase.POST_FETCH) {
234
- rulesForPhase = cachedRules.postFetch;
235
- }
236
- else if (phase === AccessRuleExecutionPhase.FETCH) {
237
- rulesForPhase = cachedRules.fetch;
238
- }
239
- else {
240
- rulesForPhase = cachedRules.preFetch;
241
- }
242
- // Step 1: Mandatory Phase
243
- for (const rule of rulesForPhase.mandatoryRules) {
244
- const result = await evaluator(rule);
245
- if (result !== true) {
246
- return false; // Immediately reject if any mandatory rule fails
247
- }
248
- }
249
- // Step 2-4: Permission Phase
250
- for (const rule of rulesForPhase.permissionRules) {
251
- const result = await evaluator(rule);
252
- if (result === true) {
253
- return true;
254
- }
255
- if (result === false) {
256
- return false;
257
- }
258
- }
259
- // Default: no hit
260
- return false;
222
+ return cachedRules;
261
223
  }
262
224
  toJSON() {
263
225
  const base = super.toJSON();
@@ -1 +1 @@
1
- {"version":3,"file":"RuntimeApiModel.js","sourceRoot":"","sources":["../../../src/modeling/RuntimeApiModel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAmB,MAAM,mBAAmB,CAAA;AACvE,OAAO,EAAE,QAAQ,EAAuB,MAAM,eAAe,CAAA;AAK7D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAG7C,OAAO,EAAc,wBAAwB,EAAE,MAAM,uBAAuB,CAAA;AAC5E,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AAiDtD;;;GAGG;AACH,MAAM,OAAO,eAAgB,SAAQ,QAAQ;IAC3C;;;OAGG;IACH,OAAO,GAAG,IAAI,GAAG,EAA0B,CAAA;IAE3C;;OAEG;IACH,YAAY,GAAG,IAAI,OAAO,EAAiC,CAAA;IAE3D;;OAEG;IACH,cAAc,GAEV,EAAE,CAAA;IAEN;;OAEG;IACH,gBAAgB,GAIZ,EAAE,CAAA;IAEN;;OAEG;IACH,iBAAiB,GAAG,IAAI,OAAO,EAA4B,CAAA;IAE3D;;OAEG;IACM,kBAAkB,GAAG,IAAI,GAAG,EAA0B,CAAA;IAE/D;;;OAGG;IACH,IAAW,iBAAiB;QAC1B,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;IACzC,CAAC;IAED,YAAY,MAA6B,EAAE,YAA8B;QACvE,KAAK,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;QAE3B,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;QAC3C,CAAC;QAED,IAAI,CAAC,2BAA2B,EAAE,CAAA;QAClC,IAAI,CAAC,sBAAsB,EAAE,CAAA;QAC7B,IAAI,CAAC,4BAA4B,EAAE,CAAA;IACrC,CAAC;IAED,4BAA4B;QAC1B,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAClC,OAAM;QACR,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;YAC3C,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;YACtE,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,MAAM,IAAI,SAAS,CAAC,oBAAoB,IAAI,CAAC,GAAG,sBAAsB,CAAC,CAAA;YACzE,CAAC;YACD,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAA;QACvD,CAAC;IACH,CAAC;IAED,sBAAsB;QACpB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YAC3C,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;YACjF,CAAC;QACH,CAAC;IACH,CAAC;IAED,sBAAsB,CAAC,MAAc,EAAE,MAAqB;QAC1D,MAAM,SAAS,GAAmB,EAAE,CAAA;QAEpC,IAAI,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtD,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;QACnC,CAAC;QAED,IAAI,aAAa,GAA8B,MAAM,CAAA;QACrD,OAAO,aAAa,EAAE,CAAC;YACrB,IAAI,aAAa,CAAC,UAAU,IAAI,aAAa,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpE,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAA;YAC1C,CAAC;YACD,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QAC/F,CAAC;QAED,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClD,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACjC,CAAC;QAED,MAAM,MAAM,GAAqB;YAC/B,QAAQ,EAAE;gBACR,eAAe,EAAE,EAAE;gBACnB,cAAc,EAAE,EAAE;aACnB;YACD,KAAK,EAAE;gBACL,eAAe,EAAE,EAAE;gBACnB,cAAc,EAAE,EAAE;aACnB;YACD,SAAS,EAAE;gBACT,eAAe,EAAE,EAAE;gBACnB,cAAc,EAAE,EAAE;aACnB;SACF,CAAA;QAED,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAA;QAEnC,KAAK,MAAM,UAAU,IAAI,SAAS,EAAE,CAAC;YACnC,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAA;YAC1C,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;gBAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAkC,CAAC,CAAA;gBAEtE,4FAA4F;gBAC5F,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,SAAQ;gBACV,CAAC;gBAED,2FAA2F;gBAC3F,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC7B,SAAQ;gBACV,CAAC;gBACD,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBAE/B,IAAI,MAAM,CAAA;gBACV,IAAI,KAAK,KAAK,wBAAwB,CAAC,UAAU,EAAE,CAAC;oBAClD,MAAM,GAAG,MAAM,CAAC,SAAS,CAAA;gBAC3B,CAAC;qBAAM,IAAI,KAAK,KAAK,wBAAwB,CAAC,KAAK,EAAE,CAAC;oBACpD,MAAM,GAAG,MAAM,CAAC,KAAK,CAAA;gBACvB,CAAC;qBAAM,CAAC;oBACN,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAA;gBAC1B,CAAC;gBAED,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACnB,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBAClC,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBACnC,CAAC;YACH,CAAC;YACD,KAAK,MAAM,IAAI,IAAI,gBAAgB,EAAE,CAAC;gBACpC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YACrB,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC;IAED,2BAA2B;QACzB,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAC/B,OAAM;QACR,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAC1E,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAM;QACR,CAAC;QAED,IAAI,CAAC,cAAc,CAAC,IAAI,GAAG,UAAU,CAAA;QAErC,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;YACzC,IAAI,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC5C,IAAI,CAAC,gBAAgB,CAAC,QAAQ,GAAG,IAAI,CAAA;YACvC,CAAC;YACD,IAAI,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC5C,IAAI,CAAC,gBAAgB,CAAC,QAAQ,GAAG,IAAI,CAAA;YACvC,CAAC;YACD,IAAI,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC5C,IAAI,CAAC,gBAAgB,CAAC,IAAI,GAAG,IAAI,CAAA;YACnC,CAAC;QACH,CAAC;IACH,CAAC;IAED,iBAAiB,CAAC,UAAsB;QACtC,KAAK,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/D,MAAM,YAAY,GAAG,EAAE,CAAA;YACvB,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;gBAC9B,6EAA6E;gBAC7E,iFAAiF;gBACjF,MAAM,WAAW,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;gBAC3D,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,CAAA;gBACjC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;gBAClC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YAC3B,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,YAAY,CAAC,CAAA;QACtD,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,YAAY,CAAC,MAAc,EAAE,IAAY;QACvC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAA;QAC3D,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,OAAO,SAAS,CAAA;QAClB,CAAC;QAED,wGAAwG;QACxG,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,EAAE,YAAY,CAAC,CAAA;QAC9C,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/C,OAAO,SAAS,CAAA;QAClB,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QAC/C,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,SAAS,CAAA;QAClB,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAA;QAEvC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAA;QAC5D,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,SAAS,CAAA;QAClB,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;QAC3E,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,SAAS,CAAA;QAClB,CAAC;QAED,OAAO;YACL,MAAM;YACN,MAAM;YACN,MAAM;SACP,CAAA;IACH,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,cAAc,CAClB,MAA6B,EAC7B,SAAwB,EACxB,KAA+B;QAE/B,IAAI,WAAW,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QAC3D,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,qGAAqG;YACrG,WAAW,GAAG,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;YACvE,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;QACxD,CAAC;QAED,IAAI,aAAa,CAAA;QACjB,IAAI,KAAK,KAAK,wBAAwB,CAAC,UAAU,EAAE,CAAC;YAClD,aAAa,GAAG,WAAW,CAAC,SAAS,CAAA;QACvC,CAAC;aAAM,IAAI,KAAK,KAAK,wBAAwB,CAAC,KAAK,EAAE,CAAC;YACpD,aAAa,GAAG,WAAW,CAAC,KAAK,CAAA;QACnC,CAAC;aAAM,CAAC;YACN,aAAa,GAAG,WAAW,CAAC,QAAQ,CAAA;QACtC,CAAC;QAED,0BAA0B;QAC1B,KAAK,MAAM,IAAI,IAAI,aAAa,CAAC,cAAc,EAAE,CAAC;YAChD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,CAAA;YACpC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBACpB,OAAO,KAAK,CAAA,CAAC,iDAAiD;YAChE,CAAC;QACH,CAAC;QAED,6BAA6B;QAC7B,KAAK,MAAM,IAAI,IAAI,aAAa,CAAC,eAAe,EAAE,CAAC;YACjD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,CAAA;YACpC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBACpB,OAAO,IAAI,CAAA;YACb,CAAC;YACD,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;gBACrB,OAAO,KAAK,CAAA;YACd,CAAC;QACH,CAAC;QAED,kBAAkB;QAClB,OAAO,KAAK,CAAA;IACd,CAAC;IAEQ,MAAM;QACb,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,EAA2B,CAAA;QAEpD,MAAM,UAAU,GAAe,EAAE,CAAA;QACjC,KAAK,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YAC5D,UAAU,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAoB,CAAC,CAAA;QAC7F,CAAC;QAED,OAAO;YACL,GAAG,IAAI;YACP,UAAU;SACX,CAAA;IACH,CAAC;CACF","sourcesContent":["import { match, parse, exec, type RouteToken } from '@poppinss/matchit'\nimport { ApiModel, type ApiModelSchema } from './ApiModel.js'\nimport type { DataDomainSchema } from './DataDomain.js'\nimport type { ActionKind } from './actions/index.js'\nimport type { ExposedEntity } from './ExposedEntity.js'\nimport type { Action } from './actions/Action.js'\nimport { SemanticType } from './Semantics.js'\nimport type { DomainEntity } from './DomainEntity.js'\nimport type { DomainProperty } from './DomainProperty.js'\nimport { AccessRule, AccessRuleExecutionPhase } from './rules/AccessRule.js'\nimport { Exception } from '../exceptions/exception.js'\n\n/**\n * Identifies a specific exposed entity and its action kind.\n */\nexport interface RouteLookup {\n exposedEntityKey: string\n actionKind: ActionKind\n}\n\n/**\n * A routing definition mapping a path to an action lookup.\n */\nexport interface RouteDefinition {\n path: string\n lookup: RouteLookup\n}\n\n/**\n * A map of HTTP methods to their route definitions.\n */\nexport type RoutingMap = Record<string, RouteDefinition[]>\n\n/**\n * Schema for an API Model optimized for runtime routing.\n */\nexport interface RuntimeApiModelSchema extends ApiModelSchema {\n routingMap: RoutingMap\n}\n\nexport interface RuntimeResolvedAction {\n entity: ExposedEntity\n action: Action\n params: Record<string, string>\n}\n\nexport type RuleEvaluator = (rule: AccessRule) => Promise<boolean | undefined> | boolean | undefined\n\ninterface PhaseRules {\n permissionRules: AccessRule[]\n mandatoryRules: AccessRule[]\n}\n\ninterface ActionRulesCache {\n preFetch: PhaseRules\n fetch: PhaseRules\n postFetch: PhaseRules\n}\n\n/**\n * An optimized API Model subclass designed for fast runtime lookups.\n * It pre-compiles the RoutingMap into a radix tree for O(log N) or faster endpoint resolution.\n */\nexport class RuntimeApiModel extends ApiModel {\n /**\n * The parsed radix tree for fast routing.\n * Method -> ParsedRoutes\n */\n #routes = new Map<string, RouteToken[][]>()\n\n /**\n * Quick map from matchit parsed route format to our RouteDefinition for returning results\n */\n #definitions = new WeakMap<RouteToken[], RouteDefinition>()\n\n /**\n * Cached references to commonly used entities for fast runtime lookup.\n */\n cachedEntities: {\n user?: DomainEntity\n } = {}\n\n /**\n * Cached references to commonly used properties for fast runtime lookup.\n */\n cachedProperties: {\n username?: DomainProperty\n password?: DomainProperty\n role?: DomainProperty\n } = {}\n\n /**\n * Cached access rules for each action to avoid runtime computation overhead.\n */\n #actionRulesCache = new WeakMap<Action, ActionRulesCache>()\n\n /**\n * Cached session properties for fast runtime lookup.\n */\n readonly #sessionProperties = new Map<string, DomainProperty>()\n\n /**\n * Returns a readonly map of session properties.\n * Note, it creates a copy of the cached map to prevent modification of the internal state.\n */\n public get sessionProperties(): ReadonlyMap<string, DomainProperty> {\n return new Map(this.#sessionProperties)\n }\n\n constructor(schema: RuntimeApiModelSchema, domainSchema: DataDomainSchema) {\n super(schema, domainSchema)\n\n if (schema.routingMap) {\n this.#initializeRouter(schema.routingMap)\n }\n\n this.#cacheEntitiesAndProperties()\n this.#precomputeAccessRules()\n this.#precomputeSessionProperties()\n }\n\n #precomputeSessionProperties(): void {\n if (!this.session || !this.domain) {\n return\n }\n for (const prop of this.session.properties) {\n const domainProperty = this.domain.findProperty(prop.key, prop.domain)\n if (!domainProperty) {\n throw new Exception(`Session property ${prop.key} not found in domain`)\n }\n this.#sessionProperties.set(prop.key, domainProperty)\n }\n }\n\n #precomputeAccessRules(): void {\n for (const entity of this.exposes.values()) {\n for (const action of entity.actions) {\n this.#actionRulesCache.set(action, this.#computeEffectiveRules(action, entity))\n }\n }\n }\n\n #computeEffectiveRules(action: Action, entity: ExposedEntity): ActionRulesCache {\n const hierarchy: AccessRule[][] = []\n\n if (action.accessRule && action.accessRule.length > 0) {\n hierarchy.push(action.accessRule)\n }\n\n let currentEntity: ExposedEntity | undefined = entity\n while (currentEntity) {\n if (currentEntity.accessRule && currentEntity.accessRule.length > 0) {\n hierarchy.push(currentEntity.accessRule)\n }\n currentEntity = currentEntity.parent ? this.exposes.get(currentEntity.parent.key) : undefined\n }\n\n if (this.accessRule && this.accessRule.length > 0) {\n hierarchy.push(this.accessRule)\n }\n\n const result: ActionRulesCache = {\n preFetch: {\n permissionRules: [],\n mandatoryRules: [],\n },\n fetch: {\n permissionRules: [],\n mandatoryRules: [],\n },\n postFetch: {\n permissionRules: [],\n mandatoryRules: [],\n },\n }\n\n const seenTypes = new Set<string>()\n\n for (const rulesLevel of hierarchy) {\n const typesInThisLevel = new Set<string>()\n for (const rule of rulesLevel) {\n const phase = rule.metadata[action.kind as keyof typeof rule.metadata]\n\n // If the rule does not specify an execution phase for this action kind, it is not evaluated\n if (!phase) {\n continue\n }\n\n // Shadowing: If a rule of the same type was defined closer to the action, ignore this one.\n if (seenTypes.has(rule.type)) {\n continue\n }\n typesInThisLevel.add(rule.type)\n\n let bucket\n if (phase === AccessRuleExecutionPhase.POST_FETCH) {\n bucket = result.postFetch\n } else if (phase === AccessRuleExecutionPhase.FETCH) {\n bucket = result.fetch\n } else {\n bucket = result.preFetch\n }\n\n if (rule.mandatory) {\n bucket.mandatoryRules.push(rule)\n } else {\n bucket.permissionRules.push(rule)\n }\n }\n for (const type of typesInThisLevel) {\n seenTypes.add(type)\n }\n }\n\n return result\n }\n\n #cacheEntitiesAndProperties(): void {\n if (!this.user || !this.domain) {\n return\n }\n\n const userEntity = this.domain.findEntity(this.user.key, this.user.domain)\n if (!userEntity) {\n return\n }\n\n this.cachedEntities.user = userEntity\n\n for (const prop of userEntity.properties) {\n if (prop.hasSemantic(SemanticType.Username)) {\n this.cachedProperties.username = prop\n }\n if (prop.hasSemantic(SemanticType.Password)) {\n this.cachedProperties.password = prop\n }\n if (prop.hasSemantic(SemanticType.UserRole)) {\n this.cachedProperties.role = prop\n }\n }\n }\n\n #initializeRouter(routingMap: RoutingMap): void {\n for (const [method, definitions] of Object.entries(routingMap)) {\n const parsedRoutes = []\n for (const def of definitions) {\n // matchit's parse() transforms a route string into an object representation.\n // It expects `:param` syntax, while our API models use OpenAPI `{param}` syntax.\n const matchitPath = def.path.replace(/\\{([^}]+)\\}/g, ':$1')\n const parsed = parse(matchitPath)\n this.#definitions.set(parsed, def)\n parsedRoutes.push(parsed)\n }\n this.#routes.set(method.toUpperCase(), parsedRoutes)\n }\n }\n\n /**\n * Looks up the corresponding exposed entity and action for a given request.\n *\n * @param method The HTTP method (e.g., 'GET', 'POST').\n * @param path The request path (e.g., '/users/123').\n * @returns An object with the entity, action, and extracted path parameters if a match is found.\n */\n lookupAction(method: string, path: string): RuntimeResolvedAction | undefined {\n const parsedRoutes = this.#routes.get(method.toUpperCase())\n if (!parsedRoutes) {\n return undefined\n }\n\n // `match` returns the matching parsed route (which is an array of segments), or empty array if no match\n const matchedRoute = match(path, parsedRoutes)\n if (!matchedRoute || matchedRoute.length === 0) {\n return undefined\n }\n\n const def = this.#definitions.get(matchedRoute)\n if (!def) {\n return undefined\n }\n\n const params = exec(path, matchedRoute)\n\n const entity = this.exposes.get(def.lookup.exposedEntityKey)\n if (!entity) {\n return undefined\n }\n\n const action = entity.actions.find((a) => a.kind === def.lookup.actionKind)\n if (!action) {\n return undefined\n }\n\n return {\n entity,\n action,\n params,\n }\n }\n\n /**\n * Evaluates access rules for a given action and phase.\n *\n * The evaluation process follows two phases per execution phase (PRE_FETCH, FETCH, POST_FETCH):\n * 1. Mandatory Phase: All rules marked as `mandatory: true` across all levels must return true.\n * If any fail, the request is immediately rejected.\n * 2. Permission Phase: Evaluation follows the hierarchy from most specific to most general:\n * Action -> Endpoint (ExposedEntity) -> API Model.\n * If an explicit allow (true) or deny (false) is hit, evaluation stops and returns the result.\n * If no rules match (all return undefined), the request is rejected by default.\n *\n * @param action The resolved action to evaluate.\n * @param evaluator A callback that evaluates a single rule. Should return true (allow),\n * false (deny), or undefined (no hit).\n * @param phase The execution phase to evaluate.\n * @returns A promise that resolves to true if access is granted, false if denied.\n */\n async evaluateAccess(\n action: RuntimeResolvedAction,\n evaluator: RuleEvaluator,\n phase: AccessRuleExecutionPhase\n ): Promise<boolean> {\n let cachedRules = this.#actionRulesCache.get(action.action)\n if (!cachedRules) {\n // Fallback if somehow action is not cached (e.g. dynamically added after initialization or in tests)\n cachedRules = this.#computeEffectiveRules(action.action, action.entity)\n this.#actionRulesCache.set(action.action, cachedRules)\n }\n\n let rulesForPhase\n if (phase === AccessRuleExecutionPhase.POST_FETCH) {\n rulesForPhase = cachedRules.postFetch\n } else if (phase === AccessRuleExecutionPhase.FETCH) {\n rulesForPhase = cachedRules.fetch\n } else {\n rulesForPhase = cachedRules.preFetch\n }\n\n // Step 1: Mandatory Phase\n for (const rule of rulesForPhase.mandatoryRules) {\n const result = await evaluator(rule)\n if (result !== true) {\n return false // Immediately reject if any mandatory rule fails\n }\n }\n\n // Step 2-4: Permission Phase\n for (const rule of rulesForPhase.permissionRules) {\n const result = await evaluator(rule)\n if (result === true) {\n return true\n }\n if (result === false) {\n return false\n }\n }\n\n // Default: no hit\n return false\n }\n\n override toJSON(): RuntimeApiModelSchema {\n const base = super.toJSON() as RuntimeApiModelSchema\n\n const routingMap: RoutingMap = {}\n for (const [method, parsedRoutes] of this.#routes.entries()) {\n routingMap[method] = parsedRoutes.map((pr) => this.#definitions.get(pr) as RouteDefinition)\n }\n\n return {\n ...base,\n routingMap,\n }\n }\n}\n"]}
1
+ {"version":3,"file":"RuntimeApiModel.js","sourceRoot":"","sources":["../../../src/modeling/RuntimeApiModel.ts"],"names":[],"mappings":"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","sourcesContent":["import { match, parse, exec, type RouteToken } from '@poppinss/matchit'\nimport { ApiModel, type ApiModelSchema } from './ApiModel.js'\nimport type { DataDomainSchema } from './DataDomain.js'\nimport type { ActionKind } from './actions/index.js'\nimport type { ExposedEntity } from './ExposedEntity.js'\nimport type { Action } from './actions/Action.js'\nimport { SemanticType } from './Semantics.js'\nimport type { DomainEntity } from './DomainEntity.js'\nimport type { DomainProperty } from './DomainProperty.js'\nimport { AccessRule, AccessRuleExecutionPhase } from './rules/AccessRule.js'\nimport { Exception } from '../exceptions/exception.js'\n\n/**\n * Identifies a specific exposed entity and its action kind.\n */\nexport interface RouteLookup {\n exposedEntityKey: string\n actionKind: ActionKind\n}\n\n/**\n * A routing definition mapping a path to an action lookup.\n */\nexport interface RouteDefinition {\n path: string\n lookup: RouteLookup\n}\n\n/**\n * A map of HTTP methods to their route definitions.\n */\nexport type RoutingMap = Record<string, RouteDefinition[]>\n\n/**\n * Schema for an API Model optimized for runtime routing.\n */\nexport interface RuntimeApiModelSchema extends ApiModelSchema {\n routingMap: RoutingMap\n}\n\nexport interface RuntimeResolvedAction {\n exposure: ExposedEntity\n entity: DomainEntity\n action: Action\n params: Record<string, string>\n}\n\nexport type RuleEvaluator = (rule: AccessRule) => Promise<boolean | undefined> | boolean | undefined\n\nexport interface PhaseRules {\n permissionRules: AccessRule[]\n mandatoryRules: AccessRule[]\n}\n\nexport interface ActionRulesCache {\n preFetch: PhaseRules\n fetch: PhaseRules\n postFetch: PhaseRules\n}\n\n/**\n * An optimized API Model subclass designed for fast runtime lookups.\n * It pre-compiles the RoutingMap into a radix tree for O(log N) or faster endpoint resolution.\n */\nexport class RuntimeApiModel extends ApiModel {\n /**\n * The parsed radix tree for fast routing.\n * Method -> ParsedRoutes\n */\n #routes = new Map<string, RouteToken[][]>()\n\n /**\n * Quick map from matchit parsed route format to our RouteDefinition for returning results\n */\n #definitions = new WeakMap<RouteToken[], RouteDefinition>()\n\n /**\n * Cached references to commonly used entities for fast runtime lookup.\n */\n cachedEntities: {\n user?: DomainEntity\n } = {}\n\n /**\n * Cached references to commonly used properties for fast runtime lookup.\n */\n cachedProperties: {\n username?: DomainProperty\n password?: DomainProperty\n role?: DomainProperty\n } = {}\n\n /**\n * Cached access rules for each action to avoid runtime computation overhead.\n */\n #actionRulesCache = new WeakMap<Action, ActionRulesCache>()\n\n /**\n * Cached session properties for fast runtime lookup.\n */\n readonly #sessionProperties = new Map<string, DomainProperty>()\n\n /**\n * Returns a readonly map of session properties.\n * Note, it creates a copy of the cached map to prevent modification of the internal state.\n */\n public get sessionProperties(): ReadonlyMap<string, DomainProperty> {\n return new Map(this.#sessionProperties)\n }\n\n constructor(schema: RuntimeApiModelSchema, domainSchema: DataDomainSchema) {\n super(schema, domainSchema)\n\n if (schema.routingMap) {\n this.#initializeRouter(schema.routingMap)\n }\n\n this.#cacheEntitiesAndProperties()\n this.#precomputeAccessRules()\n this.#precomputeSessionProperties()\n }\n\n #precomputeSessionProperties(): void {\n if (!this.session || !this.domain) {\n return\n }\n for (const prop of this.session.properties) {\n const domainProperty = this.domain.findProperty(prop.key, prop.domain)\n if (!domainProperty) {\n throw new Exception(`Session property ${prop.key} not found in domain`)\n }\n this.#sessionProperties.set(prop.key, domainProperty)\n }\n }\n\n #precomputeAccessRules(): void {\n for (const entity of this.exposes.values()) {\n for (const action of entity.actions) {\n this.#actionRulesCache.set(action, this.#computeEffectiveRules(action, entity))\n }\n }\n }\n\n #computeEffectiveRules(action: Action, entity: ExposedEntity): ActionRulesCache {\n const hierarchy: AccessRule[][] = []\n\n if (action.accessRule && action.accessRule.length > 0) {\n hierarchy.push(action.accessRule)\n }\n\n let currentEntity: ExposedEntity | undefined = entity\n while (currentEntity) {\n if (currentEntity.accessRule && currentEntity.accessRule.length > 0) {\n hierarchy.push(currentEntity.accessRule)\n }\n currentEntity = currentEntity.parent ? this.exposes.get(currentEntity.parent.key) : undefined\n }\n\n if (this.accessRule && this.accessRule.length > 0) {\n hierarchy.push(this.accessRule)\n }\n\n const result: ActionRulesCache = {\n preFetch: {\n permissionRules: [],\n mandatoryRules: [],\n },\n fetch: {\n permissionRules: [],\n mandatoryRules: [],\n },\n postFetch: {\n permissionRules: [],\n mandatoryRules: [],\n },\n }\n\n const seenTypes = new Set<string>()\n\n for (const rulesLevel of hierarchy) {\n const typesInThisLevel = new Set<string>()\n for (const rule of rulesLevel) {\n const phase = rule.metadata[action.kind as keyof typeof rule.metadata]\n\n // If the rule does not specify an execution phase for this action kind, it is not evaluated\n if (!phase) {\n continue\n }\n\n // Shadowing: If a rule of the same type was defined closer to the action, ignore this one.\n if (seenTypes.has(rule.type)) {\n continue\n }\n typesInThisLevel.add(rule.type)\n\n let bucket\n if (phase === AccessRuleExecutionPhase.POST_FETCH) {\n bucket = result.postFetch\n } else if (phase === AccessRuleExecutionPhase.FETCH) {\n bucket = result.fetch\n } else {\n bucket = result.preFetch\n }\n\n if (rule.mandatory) {\n bucket.mandatoryRules.push(rule)\n } else {\n bucket.permissionRules.push(rule)\n }\n }\n for (const type of typesInThisLevel) {\n seenTypes.add(type)\n }\n }\n\n return result\n }\n\n #cacheEntitiesAndProperties(): void {\n if (!this.user || !this.domain) {\n return\n }\n\n const userEntity = this.domain.findEntity(this.user.key, this.user.domain)\n if (!userEntity) {\n return\n }\n\n this.cachedEntities.user = userEntity\n\n for (const prop of userEntity.properties) {\n if (prop.hasSemantic(SemanticType.Username)) {\n this.cachedProperties.username = prop\n }\n if (prop.hasSemantic(SemanticType.Password)) {\n this.cachedProperties.password = prop\n }\n if (prop.hasSemantic(SemanticType.UserRole)) {\n this.cachedProperties.role = prop\n }\n }\n }\n\n #initializeRouter(routingMap: RoutingMap): void {\n for (const [method, definitions] of Object.entries(routingMap)) {\n const parsedRoutes = []\n for (const def of definitions) {\n // matchit's parse() transforms a route string into an object representation.\n // It expects `:param` syntax, while our API models use OpenAPI `{param}` syntax.\n const matchitPath = def.path.replace(/\\{([^}]+)\\}/g, ':$1')\n const parsed = parse(matchitPath)\n this.#definitions.set(parsed, def)\n parsedRoutes.push(parsed)\n }\n this.#routes.set(method.toUpperCase(), parsedRoutes)\n }\n }\n\n /**\n * Looks up the corresponding exposed entity and action for a given request.\n *\n * @param method The HTTP method (e.g., 'GET', 'POST').\n * @param path The request path (e.g., '/users/123').\n * @returns An object with the entity, action, and extracted path parameters if a match is found.\n */\n lookupAction(method: string, path: string): RuntimeResolvedAction | undefined {\n const parsedRoutes = this.#routes.get(method.toUpperCase())\n if (!parsedRoutes) {\n return undefined\n }\n\n // `match` returns the matching parsed route (which is an array of segments), or empty array if no match\n const matchedRoute = match(path, parsedRoutes)\n if (!matchedRoute || matchedRoute.length === 0) {\n return undefined\n }\n\n const def = this.#definitions.get(matchedRoute)\n if (!def) {\n return undefined\n }\n\n const params = exec(path, matchedRoute)\n\n const exposure = this.exposes.get(def.lookup.exposedEntityKey)\n if (!exposure) {\n throw new Exception('Missing exposure ' + def.lookup.exposedEntityKey, { code: 'API_MODEL_ERROR', status: 500 })\n }\n\n const action = exposure.actions.find((a) => a.kind === def.lookup.actionKind)\n if (!action) {\n throw new Exception('Missing action ' + def.lookup.actionKind, { code: 'API_MODEL_ERROR', status: 500 })\n }\n\n const entity = this.domain?.findEntity(exposure.entity.key, exposure.entity.domain)\n if (!entity) {\n throw new Exception('Missing entity ' + exposure.entity.key, { code: 'API_MODEL_ERROR', status: 500 })\n }\n\n return {\n exposure,\n entity,\n action,\n params,\n }\n }\n\n /**\n * Retrieves the precomputed and shadowed effective rules for a given action.\n */\n getEffectiveRules(action: RuntimeResolvedAction): ActionRulesCache {\n let cachedRules = this.#actionRulesCache.get(action.action)\n if (!cachedRules) {\n cachedRules = this.#computeEffectiveRules(action.action, action.exposure)\n this.#actionRulesCache.set(action.action, cachedRules)\n }\n return cachedRules\n }\n\n override toJSON(): RuntimeApiModelSchema {\n const base = super.toJSON() as RuntimeApiModelSchema\n\n const routingMap: RoutingMap = {}\n for (const [method, parsedRoutes] of this.#routes.entries()) {\n routingMap[method] = parsedRoutes.map((pr) => this.#definitions.get(pr) as RouteDefinition)\n }\n\n return {\n ...base,\n routingMap,\n }\n }\n}\n"]}
@@ -289,246 +289,6 @@ export declare enum SemanticCategory {
289
289
  */
290
290
  Computed = "Computed Values"
291
291
  }
292
- /**
293
- * Defines when a semantic should execute in relation to database operations.
294
- */
295
- export declare enum SemanticTiming {
296
- /**
297
- * Execute before the database operation (validation, preprocessing)
298
- */
299
- Before = "Before",
300
- /**
301
- * Execute after the database operation (cleanup, notifications, derived values)
302
- */
303
- After = "After",
304
- /**
305
- * Execute both before and after the operation
306
- */
307
- Both = "Both",
308
- /**
309
- * No automatic execution (manual/on-demand only)
310
- */
311
- None = "None"
312
- }
313
- /**
314
- * Defines which database operations can trigger a semantic.
315
- */
316
- export declare enum SemanticOperation {
317
- Create = "Create",
318
- Read = "Read",
319
- Update = "Update",
320
- Delete = "Delete",
321
- /**
322
- * Special operation for list operations
323
- */
324
- List = "List",
325
- /**
326
- * Special operation for search operations
327
- */
328
- Search = "Search"
329
- }
330
- /**
331
- * Defines the execution mode for a semantic.
332
- */
333
- export declare enum SemanticExecutionMode {
334
- /**
335
- * Execute synchronously as part of the main operation
336
- */
337
- Synchronous = "Synchronous",
338
- /**
339
- * Execute asynchronously after the main operation
340
- */
341
- Asynchronous = "Asynchronous",
342
- /**
343
- * Execute in background/queue (fire and forget)
344
- */
345
- Background = "Background"
346
- }
347
- /**
348
- * Defines validation strategies for semantics.
349
- */
350
- export declare enum SemanticValidationStrategy {
351
- /**
352
- * Fail the operation if semantic validation fails
353
- */
354
- Strict = "Strict",
355
- /**
356
- * Log warnings but continue operation
357
- */
358
- Warning = "Warning",
359
- /**
360
- * Skip validation entirely
361
- */
362
- Skip = "Skip"
363
- }
364
- /**
365
- * Defines caching strategies for computed semantics.
366
- */
367
- export declare enum SemanticCacheStrategy {
368
- /**
369
- * No caching - always compute
370
- */
371
- None = "None",
372
- /**
373
- * Cache until dependent fields change
374
- */
375
- Dependency = "Dependency",
376
- /**
377
- * Cache with TTL expiration
378
- */
379
- TimeToLive = "TimeToLive",
380
- /**
381
- * Cache until manually invalidated
382
- */
383
- Manual = "Manual"
384
- }
385
- /**
386
- * Configuration for when and how a semantic should execute at runtime.
387
- */
388
- export interface SemanticRuntimeConfig {
389
- /**
390
- * When the semantic should execute relative to the database operation.
391
- */
392
- timing: SemanticTiming;
393
- /**
394
- * Which database operations should trigger this semantic.
395
- */
396
- operations: SemanticOperation[];
397
- /**
398
- * Priority order for execution when multiple semantics apply.
399
- * Lower numbers execute first. Default is 100.
400
- */
401
- priority?: number;
402
- /**
403
- * Whether this semantic can be disabled at the entity/property level.
404
- */
405
- canDisable?: boolean;
406
- /**
407
- * How the semantic should execute (sync/async/background).
408
- * Default is Synchronous.
409
- * @default Synchronous
410
- */
411
- executionMode?: SemanticExecutionMode;
412
- /**
413
- * Validation strategy when semantic processing fails.
414
- * Default is Strict.
415
- * @default Strict
416
- */
417
- validationStrategy?: SemanticValidationStrategy;
418
- /**
419
- * Maximum execution time in milliseconds before timeout.
420
- * Default is 5000ms for sync, 30000ms for async.
421
- * @default 5000 for sync, 30000 for async
422
- */
423
- timeoutMs?: number;
424
- /**
425
- * Number of retry attempts on failure.
426
- * Default is 0 (no retries).
427
- * @default 0
428
- */
429
- retryAttempts?: number;
430
- /**
431
- * Dependencies on other semantics that must execute first.
432
- * Uses semantic IDs.
433
- */
434
- dependencies?: SemanticType[];
435
- /**
436
- * Fields that this semantic depends on for computation.
437
- * Used for cache invalidation and optimization.
438
- */
439
- dependentFields?: string[];
440
- /**
441
- * Caching strategy for computed/derived values.
442
- */
443
- cacheStrategy?: SemanticCacheStrategy;
444
- /**
445
- * Cache TTL in seconds (only used with TimeToLive strategy).
446
- */
447
- cacheTtlSeconds?: number;
448
- /**
449
- * Whether this semantic should run in transactions.
450
- * Default is true.
451
- */
452
- transactional?: boolean;
453
- /**
454
- * Rate limiting configuration for expensive operations.
455
- */
456
- rateLimit?: SemanticRateLimit;
457
- /**
458
- * Conditional execution based on data or context.
459
- */
460
- conditions?: SemanticCondition[];
461
- /**
462
- * Audit and logging configuration.
463
- */
464
- audit?: SemanticAudit;
465
- }
466
- export interface SemanticRateLimit {
467
- /**
468
- * Maximum executions per time window.
469
- */
470
- maxExecutions: number;
471
- /**
472
- * Time window in seconds.
473
- */
474
- windowSeconds: number;
475
- /**
476
- * Strategy when rate limit is exceeded.
477
- */
478
- strategy: 'queue' | 'drop' | 'error';
479
- }
480
- export interface SemanticCondition {
481
- /**
482
- * JEXL expression that must evaluate to true for execution.
483
- * Has access to entity data, user context, and semantic field references.
484
- *
485
- * Available context variables:
486
- * - `entity`: The entity data being processed
487
- * - `user`: Current user context (if authenticated)
488
- * - `operation`: The current operation (Create, Update, etc.)
489
- * - `semantics`: Object with semantic field accessors
490
- *
491
- * Semantic field references use dot notation:
492
- * - `semantics.CreatedTimestamp` - field with CreatedTimestamp semantic
493
- * - `semantics.Password` - field with Password semantic
494
- * - `semantics.User` - entity with User semantic (for associations)
495
- *
496
- * @example
497
- * // Only set timestamp if not already provided
498
- * "semantics.CreatedTimestamp == null"
499
- *
500
- * @example
501
- * // Only apply to authenticated users
502
- * "user != null && user.authenticated == true"
503
- *
504
- * @example
505
- * // Only hash password if it's a plain text (not already hashed)
506
- * "entity[semantics.Password] != null && !entity[semantics.Password].startsWith('$')"
507
- *
508
- * @example
509
- * // Only generate slug if title exists
510
- * "entity[semantics.Title] != null && entity[semantics.Title].length > 0"
511
- */
512
- expression: string;
513
- /**
514
- * Description of when this semantic should run.
515
- */
516
- description: string;
517
- }
518
- export interface SemanticAudit {
519
- /**
520
- * Whether to log semantic execution.
521
- */
522
- logExecution: boolean;
523
- /**
524
- * Whether to log input/output data.
525
- */
526
- logData: boolean;
527
- /**
528
- * Retention period for audit logs in days.
529
- */
530
- retentionDays: number;
531
- }
532
292
  /**
533
293
  * A base interface for all Data Semantics, containing common properties.
534
294
  * A semantic is an annotation applied to a Data Entity, Property, or Association
@@ -561,10 +321,6 @@ interface BaseDataSemantic {
561
321
  * This is used to determine if the semantic requires additional setup or configuration.
562
322
  */
563
323
  hasConfig: boolean;
564
- /**
565
- * Runtime execution configuration for this semantic.
566
- */
567
- runtime: SemanticRuntimeConfig;
568
324
  }
569
325
  /**
570
326
  * Represents a semantic that can be applied to an entire Data Entity.
@@ -610,14 +366,6 @@ export type DataSemantic = EntitySemantic | PropertySemantic | AssociationSemant
610
366
  * This acts as a central registry for the application.
611
367
  */
612
368
  export declare const DataSemantics: Record<SemanticType, DataSemantic>;
613
- /**
614
- * Get all semantics that should run for a specific operation and timing
615
- */
616
- export declare function getSemanticsForOperation(semantics: AppliedDataSemantic[], operation: SemanticOperation, timing: SemanticTiming): AppliedDataSemantic[];
617
- /**
618
- * Check if a specific semantic can be disabled at runtime
619
- */
620
- export declare function canSemanticBeDisabled(semanticType: SemanticType): boolean;
621
369
  export declare function getSemanticsByCategory(): Record<SemanticCategory, DataSemantic[]>;
622
370
  export declare function getSemanticsByCategory(scope: SemanticScope.Entity): Record<SemanticCategory, EntitySemantic[]>;
623
371
  export declare function getSemanticsByCategory(scope: SemanticScope.Property): Record<SemanticCategory, PropertySemantic[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"Semantics.d.ts","sourceRoot":"","sources":["../../../src/modeling/Semantics.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAEzD;;;GAGG;AACH,oBAAY,YAAY;IAKtB;;OAEG;IACH,IAAI,kBAAkB;IACtB;;OAEG;IACH,OAAO,qBAAqB;IAM5B;;;;OAIG;IACH,QAAQ,sBAAsB;IAC9B;;;;;OAKG;IACH,QAAQ,sBAAsB;IAC9B;;;OAGG;IACH,gBAAgB,8BAA8B;IAC9C;;;OAGG;IACH,gBAAgB,8BAA8B;IAC9C;;;;;OAKG;IACH,gBAAgB,8BAA8B;IAC9C;;;;OAIG;IACH,WAAW,yBAAyB;IACpC;;;;;;;OAOG;IACH,gBAAgB,8BAA8B;IAC9C;;;;OAIG;IACH,KAAK,mBAAmB;IACxB;;;;OAIG;IACH,IAAI,kBAAkB;IACtB;;;;;;OAMG;IACH,QAAQ,sBAAsB;IAC9B;;;;;;;;;OASG;IACH,MAAM,oBAAoB;IAE1B;;;;OAIG;IACH,OAAO,qBAAqB;IAE5B;;;OAGG;IACH,QAAQ,sBAAsB;IAE9B;;;OAGG;IACH,OAAO,qBAAqB;IAE5B;;;;;;OAMG;IACH,QAAQ,sBAAsB;IAE9B;;;;;;OAMG;IACH,IAAI,kBAAkB;IAEtB;;;;;;;;;;;;;;;OAeG;IACH,qBAAqB,mCAAmC;IAExD;;OAEG;IACH,KAAK,mBAAmB;IACxB;;OAEG;IACH,KAAK,mBAAmB;IACxB;;;;;;;OAOG;IACH,QAAQ,sBAAsB;IAC9B;;OAEG;IACH,GAAG,iBAAiB;IACpB;;;;OAIG;IACH,GAAG,iBAAiB;IACpB;;OAEG;IACH,WAAW,yBAAyB;IACpC;;OAEG;IACH,OAAO,qBAAqB;IAC5B;;OAEG;IACH,UAAU,wBAAwB;IAClC;;OAEG;IACH,OAAO,qBAAqB;IAC5B;;;OAGG;IACH,eAAe,6BAA6B;IAC5C;;OAEG;IACH,aAAa,2BAA2B;IACxC;;OAEG;IACH,yBAAyB,uCAAuC;IAChE;;OAEG;IACH,IAAI,kBAAkB;IACtB;;OAEG;IACH,UAAU,wBAAwB;IAClC;;OAEG;IACH,OAAO,qBAAqB;IAC5B;;OAEG;IACH,MAAM,oBAAoB;IAM1B;;;;;;;;OAQG;IACH,uBAAuB,qCAAqC;IAC5D;;;;OAIG;IACH,IAAI,kBAAkB;IACtB;;;;OAIG;IACH,UAAU,wBAAwB;CACnC;AAED;;GAEG;AACH,oBAAY,aAAa;IACvB;;;OAGG;IACH,MAAM,WAAW;IACjB;;;OAGG;IACH,QAAQ,aAAa;IACrB;;;OAGG;IACH,WAAW,gBAAgB;CAC5B;AAED;;GAEG;AACH,oBAAY,gBAAgB;IAC1B;;OAEG;IACH,QAAQ,8BAA8B;IACtC;;OAEG;IACH,SAAS,4BAA4B;IACrC;;OAEG;IACH,OAAO,oBAAoB;IAC3B;;OAEG;IACH,QAAQ,kBAAkB;IAC1B;;OAEG;IACH,YAAY,kCAAkC;IAC9C;;OAEG;IACH,QAAQ,yBAAyB;IACjC;;OAEG;IACH,OAAO,wBAAwB;IAC/B;;OAEG;IACH,QAAQ,oBAAoB;CAC7B;AAED;;GAEG;AACH,oBAAY,cAAc;IACxB;;OAEG;IACH,MAAM,WAAW;IACjB;;OAEG;IACH,KAAK,UAAU;IACf;;OAEG;IACH,IAAI,SAAS;IACb;;OAEG;IACH,IAAI,SAAS;CACd;AAED;;GAEG;AACH,oBAAY,iBAAiB;IAC3B,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,MAAM,WAAW;IACjB;;OAEG;IACH,IAAI,SAAS;IACb;;OAEG;IACH,MAAM,WAAW;CAClB;AAED;;GAEG;AACH,oBAAY,qBAAqB;IAC/B;;OAEG;IACH,WAAW,gBAAgB;IAC3B;;OAEG;IACH,YAAY,iBAAiB;IAC7B;;OAEG;IACH,UAAU,eAAe;CAC1B;AAED;;GAEG;AACH,oBAAY,0BAA0B;IACpC;;OAEG;IACH,MAAM,WAAW;IACjB;;OAEG;IACH,OAAO,YAAY;IACnB;;OAEG;IACH,IAAI,SAAS;CACd;AAED;;GAEG;AACH,oBAAY,qBAAqB;IAC/B;;OAEG;IACH,IAAI,SAAS;IACb;;OAEG;IACH,UAAU,eAAe;IACzB;;OAEG;IACH,UAAU,eAAe;IACzB;;OAEG;IACH,MAAM,WAAW;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,MAAM,EAAE,cAAc,CAAA;IACtB;;OAEG;IACH,UAAU,EAAE,iBAAiB,EAAE,CAAA;IAC/B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;OAIG;IACH,aAAa,CAAC,EAAE,qBAAqB,CAAA;IACrC;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,0BAA0B,CAAA;IAC/C;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;OAGG;IACH,YAAY,CAAC,EAAE,YAAY,EAAE,CAAA;IAC7B;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B;;OAEG;IACH,aAAa,CAAC,EAAE,qBAAqB,CAAA;IACrC;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;OAEG;IACH,SAAS,CAAC,EAAE,iBAAiB,CAAA;IAC7B;;OAEG;IACH,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAA;IAChC;;OAEG;IACH,KAAK,CAAC,EAAE,aAAa,CAAA;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,aAAa,EAAE,MAAM,CAAA;IACrB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAA;IACrB;;OAEG;IACH,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAA;CACrC;AAED,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,UAAU,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,YAAY,EAAE,OAAO,CAAA;IACrB;;OAEG;IACH,OAAO,EAAE,OAAO,CAAA;IAChB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAA;CACtB;AAED;;;;;GAKG;AACH,UAAU,gBAAgB;IACxB;;OAEG;IACH,EAAE,EAAE,YAAY,CAAA;IAChB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,KAAK,EAAE,aAAa,CAAA;IACpB;;OAEG;IACH,QAAQ,EAAE,gBAAgB,CAAA;IAC1B;;;OAGG;IACH,SAAS,EAAE,OAAO,CAAA;IAClB;;OAEG;IACH,OAAO,EAAE,qBAAqB,CAAA;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD,KAAK,EAAE,aAAa,CAAC,MAAM,CAAA;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,gBAAgB;IACxD,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAA;IAC7B;;;OAGG;IACH,mBAAmB,CAAC,EAAE,kBAAkB,EAAE,CAAA;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,gBAAgB;IAC3D,KAAK,EAAE,aAAa,CAAC,WAAW,CAAA;CACjC;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAAI,UAAU,YAAY,KAAG,QAAQ,IAAI,cAC7B,CAAA;AAEzC;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAAI,UAAU,YAAY,KAAG,QAAQ,IAAI,gBAC7B,CAAA;AAE3C;;GAEG;AACH,eAAO,MAAM,qBAAqB,GAAI,UAAU,YAAY,KAAG,QAAQ,IAAI,mBAC7B,CAAA;AAE9C;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,cAAc,GAAG,gBAAgB,GAAG,mBAAmB,CAAA;AAElF;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,YAAY,EAAE,YAAY,CAumB5D,CAAA;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,mBAAmB,EAAE,EAChC,SAAS,EAAE,iBAAiB,EAC5B,MAAM,EAAE,cAAc,GACrB,mBAAmB,EAAE,CAwBvB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAGzE;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAAC,gBAAgB,EAAE,YAAY,EAAE,CAAC,CAAA;AAClF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC,gBAAgB,EAAE,cAAc,EAAE,CAAC,CAAA;AAC/G,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,aAAa,CAAC,QAAQ,GAAG,MAAM,CAAC,gBAAgB,EAAE,gBAAgB,EAAE,CAAC,CAAA;AACnH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,aAAa,CAAC,WAAW,GAC/B,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,EAAE,CAAC,CAAA;AA+BlD;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,GAAI,UAAU,gBAAgB,KAAG,YAAY,EAEnF,CAAA;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,EAAE,EAAE,YAAY,CAAA;IAEhB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjC"}
1
+ {"version":3,"file":"Semantics.d.ts","sourceRoot":"","sources":["../../../src/modeling/Semantics.ts"],"names":[],"mappings":"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"}