Files
core/src/ast/nodes/EvidenceNode.js
T
John Dvorak 717ae1031e initial commit: @arbiter/core authorization engine with js-rigor hardening
Zanzibar-style authorization graph engine (direct/chain/TTU/defeasible/
binary modes, condensed snapshots, value relations) with 39 rigor test
campaigns. Includes fixes for snapshot binary writer/reader format
mismatch (snapshot-of-snapshot corruption), possibility write-boundary
validation, empty-graph snapshot serialization, relation lookup cache
direction collision, config-redefinition cache invalidation, binary
threshold semantics, defeasible compiled routing, and comparator
reason whitelisting.
2026-07-31 13:44:06 -07:00

118 lines
2.9 KiB
JavaScript

import { BaseNode } from './BaseNode.js';
/**
* AST node for evidence definitions
* Represents: evidence canRead(user: User, doc: Document) { ... } PROVIDES string
*/
export class EvidenceNode extends BaseNode {
constructor(name, location = null) {
super('Evidence', location);
this.name = name;
this.parameters = [];
this.returnType = null;
this.body = null; // EvidenceBodyNode
this.provides = null; // Return type specification
}
/**
* Add a parameter to the evidence
* @param {ParameterNode} parameter - Parameter to add
*/
addParameter(parameter) {
this.parameters.push(parameter);
this.addChild(parameter);
}
/**
* Set the body of the evidence
* @param {EvidenceBodyNode} body - Evidence body
*/
setBody(body) {
this.body = body;
this.addChild(body);
}
/**
* Set the return type for this evidence
* @param {string} returnType - Return type
*/
setReturnType(returnType) {
this.returnType = returnType;
this.provides = returnType;
}
/**
* Get the parameter names as an array
* @returns {string[]} Array of parameter names
*/
getParameterNames() {
return this.parameters.map(param => param.name);
}
/**
* Get the parameter types as an array
* @returns {string[]} Array of parameter types
*/
getParameterTypes() {
return this.parameters.map(param => param.type);
}
/**
* Find a parameter by name
* @param {string} name - Parameter name to find
* @returns {ParameterNode|null} Found parameter or null
*/
getParameter(name) {
return this.parameters.find(param => param.name === name) || null;
}
/**
* Get the signature string for this evidence
* @returns {string} Evidence signature
*/
getSignature() {
const paramStr = this.parameters.map(param => `${param.name}: ${param.type}`).join(', ');
return `${this.name}(${paramStr})`;
}
/**
* Check if this evidence has a return type
* @returns {boolean} True if has return type
*/
hasReturnType() {
return this.returnType !== null;
}
/**
* Validate the evidence
* @returns {string[]} Array of error messages
*/
validate() {
const errors = [];
// Validate evidence name
if (!this.name || typeof this.name !== 'string') {
errors.push(`Invalid evidence name: ${this.name}`);
}
// Validate parameters
this.parameters.forEach((param, index) => {
const paramErrors = param.validate ? param.validate() : [];
errors.push(...paramErrors.map(err => `Parameter ${index + 1}: ${err}`));
});
// Validate body
if (this.body) {
const bodyErrors = this.body.validate ? this.body.validate() : [];
errors.push(...bodyErrors);
}
return errors;
}
toString() {
const providesStr = this.returnType ? ` PROVIDES ${this.returnType}` : '';
return `Evidence(${this.getSignature()}${providesStr})`;
}
}