@dlovans/tenet-core 0.2.1 → 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.
- package/dist/core/engine.d.ts +4 -1
- package/dist/core/engine.js +117 -47
- package/dist/core/lint.d.ts +20 -0
- package/dist/core/lint.js +622 -0
- package/dist/core/operators.js +9 -3
- package/dist/core/temporal.js +2 -2
- package/dist/core/types.d.ts +111 -5
- package/dist/core/types.js +2 -2
- package/dist/core/validate.d.ts +4 -4
- package/dist/core/validate.js +35 -36
- package/dist/index.d.ts +12 -85
- package/dist/index.js +11 -1
- package/dist/lint.test.d.ts +5 -0
- package/dist/lint.test.js +570 -0
- package/package.json +1 -1
package/dist/core/types.d.ts
CHANGED
|
@@ -1,8 +1,112 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* All type definitions for the Tenet VM.
|
|
3
|
+
* This is the single source of truth — other modules re-export from here.
|
|
4
4
|
*/
|
|
5
|
-
export
|
|
5
|
+
export interface TenetResult {
|
|
6
|
+
result?: TenetSchema;
|
|
7
|
+
error?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Machine-parseable codes for verification issues.
|
|
11
|
+
* UI layers map these to customer-friendly messages; the VM never decides presentation.
|
|
12
|
+
*/
|
|
13
|
+
export type VerifyIssueCode = 'unknown_field' | 'computed_mismatch' | 'attestation_unsigned' | 'attestation_no_evidence' | 'attestation_no_timestamp' | 'status_mismatch' | 'convergence_failed' | 'internal_error';
|
|
14
|
+
/**
|
|
15
|
+
* A single structured problem found during verification.
|
|
16
|
+
*/
|
|
17
|
+
export interface VerifyIssue {
|
|
18
|
+
code: VerifyIssueCode;
|
|
19
|
+
field_id?: string;
|
|
20
|
+
message: string;
|
|
21
|
+
expected?: unknown;
|
|
22
|
+
claimed?: unknown;
|
|
23
|
+
}
|
|
24
|
+
export interface TenetVerifyResult {
|
|
25
|
+
valid: boolean;
|
|
26
|
+
status?: string;
|
|
27
|
+
issues?: VerifyIssue[];
|
|
28
|
+
schema?: TenetSchema;
|
|
29
|
+
error?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface Evidence {
|
|
32
|
+
provider_audit_id?: string;
|
|
33
|
+
timestamp?: string;
|
|
34
|
+
signer_id?: string;
|
|
35
|
+
logic_version?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface Attestation {
|
|
38
|
+
statement: string;
|
|
39
|
+
law_ref?: string;
|
|
40
|
+
required_role?: string;
|
|
41
|
+
provider?: string;
|
|
42
|
+
required?: boolean;
|
|
43
|
+
signed?: boolean;
|
|
44
|
+
evidence?: Evidence;
|
|
45
|
+
on_sign?: Action;
|
|
46
|
+
}
|
|
47
|
+
export interface TenetSchema {
|
|
48
|
+
protocol?: string;
|
|
49
|
+
schema_id?: string;
|
|
50
|
+
version?: string;
|
|
51
|
+
valid_from?: string;
|
|
52
|
+
definitions: Record<string, Definition>;
|
|
53
|
+
logic_tree?: Rule[];
|
|
54
|
+
temporal_map?: TemporalBranch[];
|
|
55
|
+
state_model?: StateModel;
|
|
56
|
+
errors?: ValidationError[];
|
|
57
|
+
status?: 'READY' | 'INCOMPLETE' | 'INVALID';
|
|
58
|
+
attestations?: Record<string, Attestation>;
|
|
59
|
+
}
|
|
60
|
+
export interface Definition {
|
|
61
|
+
type: 'string' | 'number' | 'boolean' | 'select' | 'date' | 'attestation' | 'currency';
|
|
62
|
+
value?: unknown;
|
|
63
|
+
options?: string[];
|
|
64
|
+
label?: string;
|
|
65
|
+
required?: boolean;
|
|
66
|
+
readonly?: boolean;
|
|
67
|
+
visible?: boolean;
|
|
68
|
+
min?: number;
|
|
69
|
+
max?: number;
|
|
70
|
+
step?: number;
|
|
71
|
+
min_length?: number;
|
|
72
|
+
max_length?: number;
|
|
73
|
+
pattern?: string;
|
|
74
|
+
ui_class?: string;
|
|
75
|
+
ui_message?: string;
|
|
76
|
+
}
|
|
77
|
+
export interface Rule {
|
|
78
|
+
id: string;
|
|
79
|
+
law_ref?: string;
|
|
80
|
+
logic_version?: string;
|
|
81
|
+
when: Record<string, unknown>;
|
|
82
|
+
then: Action;
|
|
83
|
+
disabled?: boolean;
|
|
84
|
+
}
|
|
85
|
+
export interface Action {
|
|
86
|
+
set?: Record<string, unknown>;
|
|
87
|
+
ui_modify?: Record<string, unknown>;
|
|
88
|
+
error_msg?: string;
|
|
89
|
+
}
|
|
90
|
+
export interface TemporalBranch {
|
|
91
|
+
valid_range: [string | null, string | null];
|
|
92
|
+
logic_version: string;
|
|
93
|
+
status: 'ACTIVE' | 'ARCHIVED';
|
|
94
|
+
}
|
|
95
|
+
export interface StateModel {
|
|
96
|
+
inputs: string[];
|
|
97
|
+
derived: Record<string, DerivedDef>;
|
|
98
|
+
}
|
|
99
|
+
export interface DerivedDef {
|
|
100
|
+
eval: Record<string, unknown>;
|
|
101
|
+
}
|
|
102
|
+
export type ErrorKind = 'type_mismatch' | 'missing_required' | 'constraint_violation' | 'attestation_incomplete' | 'runtime_warning' | 'cycle_detected';
|
|
103
|
+
export interface ValidationError {
|
|
104
|
+
field_id?: string;
|
|
105
|
+
rule_id?: string;
|
|
106
|
+
kind: ErrorKind;
|
|
107
|
+
message: string;
|
|
108
|
+
law_ref?: string;
|
|
109
|
+
}
|
|
6
110
|
/**
|
|
7
111
|
* Evaluation context for collection operators (some/all/none).
|
|
8
112
|
* When iterating over an array, provides access to the current element.
|
|
@@ -17,7 +121,7 @@ export interface EvalContext {
|
|
|
17
121
|
*/
|
|
18
122
|
export interface EvalState {
|
|
19
123
|
/** The schema being evaluated (mutable copy) */
|
|
20
|
-
schema:
|
|
124
|
+
schema: TenetSchema;
|
|
21
125
|
/** Effective date for temporal routing */
|
|
22
126
|
effectiveDate: Date;
|
|
23
127
|
/** Tracks which fields were set by which rule (cycle detection) */
|
|
@@ -25,7 +129,9 @@ export interface EvalState {
|
|
|
25
129
|
/** Current element context for some/all/none operators */
|
|
26
130
|
currentElement?: unknown;
|
|
27
131
|
/** Accumulated validation errors */
|
|
28
|
-
errors:
|
|
132
|
+
errors: ValidationError[];
|
|
133
|
+
/** Cycle detection for derived fields */
|
|
134
|
+
derivedInProgress: Set<string>;
|
|
29
135
|
}
|
|
30
136
|
/**
|
|
31
137
|
* Document status values
|
package/dist/core/types.js
CHANGED
package/dist/core/validate.d.ts
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* Definition validation and status determination.
|
|
3
3
|
* Validates types, constraints, and required fields.
|
|
4
4
|
*/
|
|
5
|
-
import type { EvalState, DocStatus } from './types.js';
|
|
5
|
+
import type { EvalState, ErrorKind, DocStatus, Action } from './types.js';
|
|
6
6
|
/**
|
|
7
7
|
* Add an error to the state's error list.
|
|
8
8
|
*/
|
|
9
|
-
export declare function addError(state: EvalState, fieldId: string, ruleId: string, message: string, lawRef?: string): void;
|
|
9
|
+
export declare function addError(state: EvalState, fieldId: string, ruleId: string, kind: ErrorKind, message: string, lawRef?: string): void;
|
|
10
10
|
/**
|
|
11
11
|
* Validate all definitions for type correctness and required fields.
|
|
12
12
|
*/
|
|
@@ -14,8 +14,8 @@ export declare function validateDefinitions(state: EvalState): void;
|
|
|
14
14
|
/**
|
|
15
15
|
* Check attestations for required signatures.
|
|
16
16
|
*/
|
|
17
|
-
export declare function checkAttestations(state: EvalState, applyAction: (action:
|
|
17
|
+
export declare function checkAttestations(state: EvalState, applyAction: (action: Action, ruleId: string, lawRef: string) => void): void;
|
|
18
18
|
/**
|
|
19
|
-
* Determine document status based on
|
|
19
|
+
* Determine document status based on ErrorKind.
|
|
20
20
|
*/
|
|
21
21
|
export declare function determineStatus(state: EvalState): DocStatus;
|
package/dist/core/validate.js
CHANGED
|
@@ -6,10 +6,11 @@ import { toFloat, parseDate } from './operators.js';
|
|
|
6
6
|
/**
|
|
7
7
|
* Add an error to the state's error list.
|
|
8
8
|
*/
|
|
9
|
-
export function addError(state, fieldId, ruleId, message, lawRef) {
|
|
9
|
+
export function addError(state, fieldId, ruleId, kind, message, lawRef) {
|
|
10
10
|
state.errors.push({
|
|
11
11
|
field_id: fieldId || undefined,
|
|
12
12
|
rule_id: ruleId || undefined,
|
|
13
|
+
kind,
|
|
13
14
|
message,
|
|
14
15
|
law_ref: lawRef || undefined,
|
|
15
16
|
});
|
|
@@ -28,10 +29,10 @@ function isValidOption(value, options) {
|
|
|
28
29
|
*/
|
|
29
30
|
function validateNumericConstraints(state, id, value, def) {
|
|
30
31
|
if (def.min !== undefined && value < def.min) {
|
|
31
|
-
addError(state, id, '', `Field '${id}' value ${value.toFixed(2)} is below minimum ${def.min.toFixed(2)}`);
|
|
32
|
+
addError(state, id, '', 'constraint_violation', `Field '${id}' value ${value.toFixed(2)} is below minimum ${def.min.toFixed(2)}`);
|
|
32
33
|
}
|
|
33
34
|
if (def.max !== undefined && value > def.max) {
|
|
34
|
-
addError(state, id, '', `Field '${id}' value ${value.toFixed(2)} exceeds maximum ${def.max.toFixed(2)}`);
|
|
35
|
+
addError(state, id, '', 'constraint_violation', `Field '${id}' value ${value.toFixed(2)} exceeds maximum ${def.max.toFixed(2)}`);
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
/**
|
|
@@ -39,16 +40,16 @@ function validateNumericConstraints(state, id, value, def) {
|
|
|
39
40
|
*/
|
|
40
41
|
function validateStringConstraints(state, id, value, def) {
|
|
41
42
|
if (def.min_length !== undefined && value.length < def.min_length) {
|
|
42
|
-
addError(state, id, '', `Field '${id}' is too short (minimum ${def.min_length} characters)`);
|
|
43
|
+
addError(state, id, '', 'constraint_violation', `Field '${id}' is too short (minimum ${def.min_length} characters)`);
|
|
43
44
|
}
|
|
44
45
|
if (def.max_length !== undefined && value.length > def.max_length) {
|
|
45
|
-
addError(state, id, '', `Field '${id}' is too long (maximum ${def.max_length} characters)`);
|
|
46
|
+
addError(state, id, '', 'constraint_violation', `Field '${id}' is too long (maximum ${def.max_length} characters)`);
|
|
46
47
|
}
|
|
47
48
|
if (def.pattern) {
|
|
48
49
|
try {
|
|
49
50
|
const regex = new RegExp(def.pattern);
|
|
50
51
|
if (!regex.test(value)) {
|
|
51
|
-
addError(state, id, '', `Field '${id}' does not match required pattern`);
|
|
52
|
+
addError(state, id, '', 'constraint_violation', `Field '${id}' does not match required pattern`);
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
55
|
catch {
|
|
@@ -58,13 +59,19 @@ function validateStringConstraints(state, id, value, def) {
|
|
|
58
59
|
}
|
|
59
60
|
/**
|
|
60
61
|
* Validate a single definition's type and constraints.
|
|
62
|
+
* Array values are allowed — the declared type describes the element type,
|
|
63
|
+
* used by collection operators (some/all/none). Scalar validation is skipped for arrays.
|
|
61
64
|
*/
|
|
62
65
|
function validateType(state, id, def) {
|
|
63
66
|
const value = def.value;
|
|
67
|
+
// Skip scalar validation for array values (used with some/all/none operators)
|
|
68
|
+
if (Array.isArray(value)) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
64
71
|
switch (def.type) {
|
|
65
72
|
case 'string': {
|
|
66
73
|
if (typeof value !== 'string') {
|
|
67
|
-
addError(state, id, '', `Field '${id}' must be a string`);
|
|
74
|
+
addError(state, id, '', 'type_mismatch', `Field '${id}' must be a string`);
|
|
68
75
|
return;
|
|
69
76
|
}
|
|
70
77
|
validateStringConstraints(state, id, value, def);
|
|
@@ -74,7 +81,7 @@ function validateType(state, id, def) {
|
|
|
74
81
|
case 'currency': {
|
|
75
82
|
const [numVal, ok] = toFloat(value);
|
|
76
83
|
if (!ok) {
|
|
77
|
-
addError(state, id, '', `Field '${id}' must be a number`);
|
|
84
|
+
addError(state, id, '', 'type_mismatch', `Field '${id}' must be a number`);
|
|
78
85
|
return;
|
|
79
86
|
}
|
|
80
87
|
validateNumericConstraints(state, id, numVal, def);
|
|
@@ -82,30 +89,30 @@ function validateType(state, id, def) {
|
|
|
82
89
|
}
|
|
83
90
|
case 'boolean': {
|
|
84
91
|
if (typeof value !== 'boolean') {
|
|
85
|
-
addError(state, id, '', `Field '${id}' must be a boolean`);
|
|
92
|
+
addError(state, id, '', 'type_mismatch', `Field '${id}' must be a boolean`);
|
|
86
93
|
}
|
|
87
94
|
break;
|
|
88
95
|
}
|
|
89
96
|
case 'select': {
|
|
90
97
|
if (typeof value !== 'string') {
|
|
91
|
-
addError(state, id, '', `Field '${id}' must be a string`);
|
|
98
|
+
addError(state, id, '', 'type_mismatch', `Field '${id}' must be a string`);
|
|
92
99
|
return;
|
|
93
100
|
}
|
|
94
101
|
if (!isValidOption(value, def.options)) {
|
|
95
|
-
addError(state, id, '', `Field '${id}' value '${value}' is not a valid option`);
|
|
102
|
+
addError(state, id, '', 'constraint_violation', `Field '${id}' value '${value}' is not a valid option`);
|
|
96
103
|
}
|
|
97
104
|
break;
|
|
98
105
|
}
|
|
99
106
|
case 'attestation': {
|
|
100
107
|
if (typeof value !== 'boolean') {
|
|
101
|
-
addError(state, id, '', `Attestation '${id}' must be a boolean`);
|
|
108
|
+
addError(state, id, '', 'type_mismatch', `Attestation '${id}' must be a boolean`);
|
|
102
109
|
}
|
|
103
110
|
break;
|
|
104
111
|
}
|
|
105
112
|
case 'date': {
|
|
106
113
|
const [, ok] = parseDate(value);
|
|
107
114
|
if (!ok) {
|
|
108
|
-
addError(state, id, '', `Field '${id}' must be a valid date`);
|
|
115
|
+
addError(state, id, '', 'type_mismatch', `Field '${id}' must be a valid date`);
|
|
109
116
|
}
|
|
110
117
|
break;
|
|
111
118
|
}
|
|
@@ -122,11 +129,11 @@ export function validateDefinitions(state) {
|
|
|
122
129
|
// Check required fields
|
|
123
130
|
if (def.required) {
|
|
124
131
|
if (def.value === undefined || def.value === null) {
|
|
125
|
-
addError(state, id, '', `Required field '${id}' is missing`);
|
|
132
|
+
addError(state, id, '', 'missing_required', `Required field '${id}' is missing`);
|
|
126
133
|
}
|
|
127
134
|
else if ((def.type === 'string' || def.type === 'select') && def.value === '') {
|
|
128
135
|
// Empty string is also considered "missing" for required string/select fields
|
|
129
|
-
addError(state, id, '', `Required field '${id}' is missing`);
|
|
136
|
+
addError(state, id, '', 'missing_required', `Required field '${id}' is missing`);
|
|
130
137
|
}
|
|
131
138
|
}
|
|
132
139
|
// Validate type if value is present
|
|
@@ -145,7 +152,7 @@ export function checkAttestations(state, applyAction) {
|
|
|
145
152
|
continue;
|
|
146
153
|
}
|
|
147
154
|
if (def.required && def.value !== true) {
|
|
148
|
-
addError(state, id, '', `Required attestation '${id}' not confirmed`);
|
|
155
|
+
addError(state, id, '', 'attestation_incomplete', `Required attestation '${id}' not confirmed`);
|
|
149
156
|
}
|
|
150
157
|
}
|
|
151
158
|
// Check rich attestations
|
|
@@ -163,38 +170,30 @@ export function checkAttestations(state, applyAction) {
|
|
|
163
170
|
// Validate required attestations
|
|
164
171
|
if (att.required) {
|
|
165
172
|
if (!att.signed) {
|
|
166
|
-
addError(state, id, '', `Required attestation '${id}' not signed`, att.law_ref);
|
|
173
|
+
addError(state, id, '', 'attestation_incomplete', `Required attestation '${id}' not signed`, att.law_ref);
|
|
167
174
|
}
|
|
168
175
|
else if (!att.evidence || !att.evidence.provider_audit_id) {
|
|
169
|
-
addError(state, id, '', `Attestation '${id}' signed but missing evidence`, att.law_ref);
|
|
176
|
+
addError(state, id, '', 'attestation_incomplete', `Attestation '${id}' signed but missing evidence`, att.law_ref);
|
|
170
177
|
}
|
|
171
178
|
}
|
|
172
179
|
}
|
|
173
180
|
}
|
|
174
181
|
/**
|
|
175
|
-
* Determine document status based on
|
|
182
|
+
* Determine document status based on ErrorKind.
|
|
176
183
|
*/
|
|
177
184
|
export function determineStatus(state) {
|
|
178
|
-
let hasTypeErrors = false;
|
|
179
|
-
let hasMissingRequired = false;
|
|
180
|
-
let hasMissingAttestations = false;
|
|
181
185
|
for (const err of state.errors) {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
hasTypeErrors = true;
|
|
185
|
-
}
|
|
186
|
-
else if (msg.includes('missing') || msg.includes('Required field')) {
|
|
187
|
-
hasMissingRequired = true;
|
|
188
|
-
}
|
|
189
|
-
else if (msg.includes('attestation')) {
|
|
190
|
-
hasMissingAttestations = true;
|
|
191
|
-
}
|
|
186
|
+
if (err.kind === 'type_mismatch')
|
|
187
|
+
return 'INVALID';
|
|
192
188
|
}
|
|
193
|
-
|
|
194
|
-
|
|
189
|
+
for (const err of state.errors) {
|
|
190
|
+
if (err.kind === 'missing_required' || err.kind === 'attestation_incomplete') {
|
|
191
|
+
return 'INCOMPLETE';
|
|
192
|
+
}
|
|
195
193
|
}
|
|
196
|
-
|
|
197
|
-
|
|
194
|
+
for (const err of state.errors) {
|
|
195
|
+
if (err.kind === 'constraint_violation')
|
|
196
|
+
return 'INVALID';
|
|
198
197
|
}
|
|
199
198
|
return 'READY';
|
|
200
199
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,91 +4,10 @@
|
|
|
4
4
|
* This module provides a pure TypeScript implementation of the Tenet VM.
|
|
5
5
|
* Works in both browser and Node.js environments with no WASM dependencies.
|
|
6
6
|
*/
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
export interface TenetVerifyResult {
|
|
12
|
-
valid: boolean;
|
|
13
|
-
error?: string;
|
|
14
|
-
}
|
|
15
|
-
export interface Evidence {
|
|
16
|
-
provider_audit_id?: string;
|
|
17
|
-
timestamp?: string;
|
|
18
|
-
signer_id?: string;
|
|
19
|
-
logic_version?: string;
|
|
20
|
-
}
|
|
21
|
-
export interface Attestation {
|
|
22
|
-
statement: string;
|
|
23
|
-
law_ref?: string;
|
|
24
|
-
required_role?: string;
|
|
25
|
-
provider?: string;
|
|
26
|
-
required?: boolean;
|
|
27
|
-
signed?: boolean;
|
|
28
|
-
evidence?: Evidence;
|
|
29
|
-
on_sign?: Action;
|
|
30
|
-
}
|
|
31
|
-
export interface TenetSchema {
|
|
32
|
-
protocol?: string;
|
|
33
|
-
schema_id?: string;
|
|
34
|
-
version?: string;
|
|
35
|
-
valid_from?: string;
|
|
36
|
-
definitions: Record<string, Definition>;
|
|
37
|
-
logic_tree?: Rule[];
|
|
38
|
-
temporal_map?: TemporalBranch[];
|
|
39
|
-
state_model?: StateModel;
|
|
40
|
-
errors?: ValidationError[];
|
|
41
|
-
status?: 'READY' | 'INCOMPLETE' | 'INVALID';
|
|
42
|
-
attestations?: Record<string, Attestation>;
|
|
43
|
-
}
|
|
44
|
-
export interface Definition {
|
|
45
|
-
type: 'string' | 'number' | 'boolean' | 'select' | 'date' | 'attestation' | 'currency';
|
|
46
|
-
value?: unknown;
|
|
47
|
-
options?: string[];
|
|
48
|
-
label?: string;
|
|
49
|
-
required?: boolean;
|
|
50
|
-
readonly?: boolean;
|
|
51
|
-
visible?: boolean;
|
|
52
|
-
min?: number;
|
|
53
|
-
max?: number;
|
|
54
|
-
step?: number;
|
|
55
|
-
min_length?: number;
|
|
56
|
-
max_length?: number;
|
|
57
|
-
pattern?: string;
|
|
58
|
-
ui_class?: string;
|
|
59
|
-
ui_message?: string;
|
|
60
|
-
}
|
|
61
|
-
export interface Rule {
|
|
62
|
-
id: string;
|
|
63
|
-
law_ref?: string;
|
|
64
|
-
logic_version?: string;
|
|
65
|
-
when: Record<string, unknown>;
|
|
66
|
-
then: Action;
|
|
67
|
-
disabled?: boolean;
|
|
68
|
-
}
|
|
69
|
-
export interface Action {
|
|
70
|
-
set?: Record<string, unknown>;
|
|
71
|
-
ui_modify?: Record<string, unknown>;
|
|
72
|
-
error_msg?: string;
|
|
73
|
-
}
|
|
74
|
-
export interface TemporalBranch {
|
|
75
|
-
valid_range: [string | null, string | null];
|
|
76
|
-
logic_version: string;
|
|
77
|
-
status: 'ACTIVE' | 'ARCHIVED';
|
|
78
|
-
}
|
|
79
|
-
export interface StateModel {
|
|
80
|
-
inputs: string[];
|
|
81
|
-
derived: Record<string, DerivedDef>;
|
|
82
|
-
}
|
|
83
|
-
export interface DerivedDef {
|
|
84
|
-
eval: Record<string, unknown>;
|
|
85
|
-
}
|
|
86
|
-
export interface ValidationError {
|
|
87
|
-
field_id?: string;
|
|
88
|
-
rule_id?: string;
|
|
89
|
-
message: string;
|
|
90
|
-
law_ref?: string;
|
|
91
|
-
}
|
|
7
|
+
export type { TenetSchema, TenetResult, TenetVerifyResult, VerifyIssue, VerifyIssueCode, Definition, Rule, Action, TemporalBranch, StateModel, DerivedDef, ValidationError, Evidence, Attestation, ErrorKind, } from './core/types.js';
|
|
8
|
+
export type { LintResult, LintIssue, LintSeverity } from './core/lint.js';
|
|
9
|
+
import type { TenetSchema, TenetResult, TenetVerifyResult } from './core/types.js';
|
|
10
|
+
import type { LintResult } from './core/lint.js';
|
|
92
11
|
/**
|
|
93
12
|
* Initialize the Tenet VM.
|
|
94
13
|
* This is a no-op in the pure TypeScript implementation (kept for backwards compatibility).
|
|
@@ -113,6 +32,14 @@ export declare function run(schema: TenetSchema | string, date?: Date | string):
|
|
|
113
32
|
* @returns Whether the transformation is valid
|
|
114
33
|
*/
|
|
115
34
|
export declare function verify(newSchema: TenetSchema | string, oldSchema: TenetSchema | string): TenetVerifyResult;
|
|
35
|
+
/**
|
|
36
|
+
* Lint a schema for structural errors and type mismatches.
|
|
37
|
+
* Returns issues without executing the schema — pure static analysis.
|
|
38
|
+
*
|
|
39
|
+
* @param schema - The schema object or JSON string
|
|
40
|
+
* @returns Lint result with validity flag and issue list
|
|
41
|
+
*/
|
|
42
|
+
export declare function lint(schema: TenetSchema | string): LintResult;
|
|
116
43
|
/**
|
|
117
44
|
* Check if the VM is ready.
|
|
118
45
|
* Always returns true in the pure TypeScript implementation.
|
package/dist/index.js
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* This module provides a pure TypeScript implementation of the Tenet VM.
|
|
5
5
|
* Works in both browser and Node.js environments with no WASM dependencies.
|
|
6
6
|
*/
|
|
7
|
-
// Import core engine functions
|
|
8
7
|
import { run as coreRun, verify as coreVerify } from './core/engine.js';
|
|
8
|
+
import { lint as coreLint } from './core/lint.js';
|
|
9
9
|
/**
|
|
10
10
|
* Initialize the Tenet VM.
|
|
11
11
|
* This is a no-op in the pure TypeScript implementation (kept for backwards compatibility).
|
|
@@ -37,6 +37,16 @@ export function run(schema, date = new Date()) {
|
|
|
37
37
|
export function verify(newSchema, oldSchema) {
|
|
38
38
|
return coreVerify(newSchema, oldSchema);
|
|
39
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Lint a schema for structural errors and type mismatches.
|
|
42
|
+
* Returns issues without executing the schema — pure static analysis.
|
|
43
|
+
*
|
|
44
|
+
* @param schema - The schema object or JSON string
|
|
45
|
+
* @returns Lint result with validity flag and issue list
|
|
46
|
+
*/
|
|
47
|
+
export function lint(schema) {
|
|
48
|
+
return coreLint(schema);
|
|
49
|
+
}
|
|
40
50
|
/**
|
|
41
51
|
* Check if the VM is ready.
|
|
42
52
|
* Always returns true in the pure TypeScript implementation.
|