@highflame/policy 1.1.3 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/actions.gen.d.ts +21 -0
  2. package/dist/actions.gen.d.ts.map +1 -1
  3. package/dist/actions.gen.js +21 -0
  4. package/dist/actions.gen.js.map +1 -1
  5. package/dist/builder.d.ts +47 -10
  6. package/dist/builder.d.ts.map +1 -1
  7. package/dist/builder.js.map +1 -1
  8. package/dist/engine.d.ts +37 -0
  9. package/dist/engine.d.ts.map +1 -1
  10. package/dist/engine.js +99 -0
  11. package/dist/engine.js.map +1 -1
  12. package/dist/engine.test.d.ts +8 -0
  13. package/dist/engine.test.d.ts.map +1 -0
  14. package/dist/engine.test.js +190 -0
  15. package/dist/engine.test.js.map +1 -0
  16. package/dist/entities.gen.d.ts +4 -0
  17. package/dist/entities.gen.d.ts.map +1 -1
  18. package/dist/entities.gen.js +4 -0
  19. package/dist/entities.gen.js.map +1 -1
  20. package/dist/errors.d.ts +102 -0
  21. package/dist/errors.d.ts.map +1 -0
  22. package/dist/errors.js +127 -0
  23. package/dist/errors.js.map +1 -0
  24. package/dist/index.d.ts +2 -0
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +2 -0
  27. package/dist/index.js.map +1 -1
  28. package/dist/parser.d.ts +34 -0
  29. package/dist/parser.d.ts.map +1 -0
  30. package/dist/parser.js +393 -0
  31. package/dist/parser.js.map +1 -0
  32. package/dist/parser.test.d.ts +8 -0
  33. package/dist/parser.test.d.ts.map +1 -0
  34. package/dist/parser.test.js +143 -0
  35. package/dist/parser.test.js.map +1 -0
  36. package/dist/schema.gen.d.ts +1 -1
  37. package/dist/schema.gen.d.ts.map +1 -1
  38. package/dist/schema.gen.js +331 -17
  39. package/dist/schema.gen.js.map +1 -1
  40. package/dist/types.d.ts +1 -0
  41. package/dist/types.d.ts.map +1 -1
  42. package/dist/types.js +2 -0
  43. package/dist/types.js.map +1 -1
  44. package/package.json +8 -2
  45. package/src/actions.gen.ts +21 -0
  46. package/src/builder.ts +52 -10
  47. package/src/engine.test.ts +371 -0
  48. package/src/engine.ts +145 -0
  49. package/src/entities.gen.ts +4 -0
  50. package/src/errors.ts +195 -0
  51. package/src/index.ts +2 -0
  52. package/src/parser.test.ts +169 -0
  53. package/src/parser.ts +517 -0
  54. package/src/schema.gen.ts +331 -17
  55. package/src/types.ts +3 -0
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Engine unit tests
3
+ *
4
+ * Tests the PolicyEngine evaluate() function.
5
+ * These tests are consistent across Go, TypeScript, and Python SDKs.
6
+ */
7
+ import { describe, it, expect, beforeEach } from 'vitest';
8
+ import { PolicyEngine, EntityType, ActionType, InputValidationError, DEFAULT_LIMITS, } from './index.js';
9
+ describe('PolicyEngine', () => {
10
+ let engine;
11
+ const permitAllPolicy = `
12
+ permit(principal, action, resource);
13
+ `;
14
+ const denyAllPolicy = `
15
+ forbid(principal, action, resource);
16
+ `;
17
+ // Simple context-based policy without action constraint for testing context evaluation
18
+ const contextBasedPolicy = `
19
+ @id("allow-production")
20
+ permit(
21
+ principal,
22
+ action,
23
+ resource
24
+ )
25
+ when { context.environment == "production" };
26
+
27
+ @id("deny-all")
28
+ forbid(principal, action, resource);
29
+ `;
30
+ beforeEach(() => {
31
+ engine = new PolicyEngine();
32
+ });
33
+ describe('basic evaluation', () => {
34
+ it('should allow when permit policy matches', () => {
35
+ engine.loadPolicies(permitAllPolicy);
36
+ const decision = engine.evaluateSimple(EntityType.Scanner, 'test-scanner', ActionType.ScanArtifact, EntityType.Artifact, '/model.safetensors');
37
+ expect(decision.effect).toBe('Allow');
38
+ });
39
+ it('should deny when forbid policy matches', () => {
40
+ engine.loadPolicies(denyAllPolicy);
41
+ const decision = engine.evaluateSimple(EntityType.Scanner, 'test-scanner', ActionType.ScanArtifact, EntityType.Artifact, '/model.safetensors');
42
+ expect(decision.effect).toBe('Deny');
43
+ });
44
+ it('should deny when no policies match (default deny)', () => {
45
+ engine.loadPolicies(''); // No policies
46
+ const decision = engine.evaluateSimple(EntityType.Scanner, 'test-scanner', ActionType.ScanArtifact, EntityType.Artifact, '/model.safetensors');
47
+ expect(decision.effect).toBe('Deny');
48
+ });
49
+ });
50
+ describe('context-based evaluation', () => {
51
+ beforeEach(() => {
52
+ engine.loadPolicies(contextBasedPolicy);
53
+ });
54
+ it('should allow when context matches permit condition', () => {
55
+ // Use simple permit policy to test context evaluation in isolation
56
+ const simplePermitPolicy = `
57
+ permit(principal, action, resource)
58
+ when { context.environment == "production" };
59
+ `;
60
+ const testEngine = new PolicyEngine();
61
+ testEngine.loadPolicies(simplePermitPolicy);
62
+ const decision = testEngine.evaluateSimple(EntityType.Scanner, 'palisade', ActionType.ScanArtifact, EntityType.Artifact, '/model.safetensors', { environment: 'production' });
63
+ expect(decision.effect).toBe('Allow');
64
+ });
65
+ it('should deny when context does not match permit condition', () => {
66
+ const decision = engine.evaluateSimple(EntityType.Scanner, 'palisade', ActionType.ScanArtifact, EntityType.Artifact, '/model.safetensors', { environment: 'development' });
67
+ expect(decision.effect).toBe('Deny');
68
+ });
69
+ it('should deny when context is missing required field', () => {
70
+ const decision = engine.evaluateSimple(EntityType.Scanner, 'palisade', ActionType.ScanArtifact, EntityType.Artifact, '/model.safetensors', {} // Missing environment
71
+ );
72
+ expect(decision.effect).toBe('Deny');
73
+ });
74
+ });
75
+ describe('input validation', () => {
76
+ beforeEach(() => {
77
+ engine.loadPolicies(permitAllPolicy);
78
+ });
79
+ it('should accept valid context', () => {
80
+ const decision = engine.evaluateSimple(EntityType.Scanner, 'test', ActionType.ScanArtifact, EntityType.Artifact, '/model.safetensors', {
81
+ environment: 'production',
82
+ severity: 'HIGH',
83
+ count: 42,
84
+ enabled: true,
85
+ });
86
+ expect(decision.effect).toBe('Allow');
87
+ });
88
+ it('should reject context with too many keys', () => {
89
+ const engine = new PolicyEngine({ limits: { maxContextKeys: 5 } });
90
+ engine.loadPolicies(permitAllPolicy);
91
+ const bigContext = {};
92
+ for (let i = 0; i < 10; i++) {
93
+ bigContext[`key${i}`] = 'value';
94
+ }
95
+ expect(() => {
96
+ engine.evaluateSimple(EntityType.Scanner, 'test', ActionType.ScanArtifact, EntityType.Artifact, '/model.safetensors', bigContext);
97
+ }).toThrow(InputValidationError);
98
+ });
99
+ it('should reject context with too long strings', () => {
100
+ const engine = new PolicyEngine({ limits: { maxStringLength: 100 } });
101
+ engine.loadPolicies(permitAllPolicy);
102
+ const longString = 'x'.repeat(200);
103
+ expect(() => {
104
+ engine.evaluateSimple(EntityType.Scanner, 'test', ActionType.ScanArtifact, EntityType.Artifact, '/model.safetensors', { value: longString });
105
+ }).toThrow(InputValidationError);
106
+ });
107
+ it('should reject deeply nested context', () => {
108
+ const engine = new PolicyEngine({ limits: { maxNestingDepth: 3 } });
109
+ engine.loadPolicies(permitAllPolicy);
110
+ const deepContext = {
111
+ level1: {
112
+ level2: {
113
+ level3: {
114
+ level4: {
115
+ level5: 'too deep',
116
+ },
117
+ },
118
+ },
119
+ },
120
+ };
121
+ expect(() => {
122
+ engine.evaluateSimple(EntityType.Scanner, 'test', ActionType.ScanArtifact, EntityType.Artifact, '/model.safetensors', deepContext);
123
+ }).toThrow(InputValidationError);
124
+ });
125
+ it('should allow skipping validation', () => {
126
+ const engine = new PolicyEngine({
127
+ skipValidation: true,
128
+ limits: { maxContextKeys: 1 },
129
+ });
130
+ engine.loadPolicies(permitAllPolicy);
131
+ // This would normally fail validation
132
+ const decision = engine.evaluateSimple(EntityType.Scanner, 'test', ActionType.ScanArtifact, EntityType.Artifact, '/model.safetensors', { key1: 'value1', key2: 'value2', key3: 'value3' });
133
+ expect(decision.effect).toBe('Allow');
134
+ });
135
+ });
136
+ describe('complex context types', () => {
137
+ beforeEach(() => {
138
+ engine.loadPolicies(permitAllPolicy);
139
+ });
140
+ it('should handle array context values', () => {
141
+ const decision = engine.evaluateSimple(EntityType.Scanner, 'test', ActionType.ScanArtifact, EntityType.Artifact, '/model.safetensors', { threats: ['malware', 'backdoor', 'injection'] });
142
+ expect(decision.effect).toBe('Allow');
143
+ });
144
+ it('should handle nested object context', () => {
145
+ const decision = engine.evaluateSimple(EntityType.Scanner, 'test', ActionType.ScanArtifact, EntityType.Artifact, '/model.safetensors', {
146
+ metadata: {
147
+ format: 'safetensors',
148
+ size: 1024,
149
+ },
150
+ });
151
+ expect(decision.effect).toBe('Allow');
152
+ });
153
+ it('should handle empty context', () => {
154
+ // Cedar doesn't have null values - this tests that empty context works
155
+ const decision = engine.evaluateSimple(EntityType.Scanner, 'test', ActionType.ScanArtifact, EntityType.Artifact, '/model.safetensors', {});
156
+ expect(decision.effect).toBe('Allow');
157
+ });
158
+ it('should handle boolean context values', () => {
159
+ const decision = engine.evaluateSimple(EntityType.Scanner, 'test', ActionType.ScanArtifact, EntityType.Artifact, '/model.safetensors', { is_signed: true, is_malicious: false });
160
+ expect(decision.effect).toBe('Allow');
161
+ });
162
+ it('should handle integer context values', () => {
163
+ // Cedar uses Long type for numbers (integers only, no floats)
164
+ const decision = engine.evaluateSimple(EntityType.Scanner, 'test', ActionType.ScanArtifact, EntityType.Artifact, '/model.safetensors', { severity_score: 7, count: 100 });
165
+ expect(decision.effect).toBe('Allow');
166
+ });
167
+ });
168
+ describe('error handling', () => {
169
+ it('should handle invalid policy syntax gracefully', () => {
170
+ const invalidPolicy = `permit(principal, action, resource`; // Missing closing paren
171
+ expect(() => {
172
+ engine.loadPolicies(invalidPolicy);
173
+ engine.evaluateSimple(EntityType.Scanner, 'test', ActionType.ScanArtifact, EntityType.Artifact, '/model.safetensors');
174
+ }).not.toThrow();
175
+ // Should return deny with reason
176
+ engine.loadPolicies(invalidPolicy);
177
+ const decision = engine.evaluateSimple(EntityType.Scanner, 'test', ActionType.ScanArtifact, EntityType.Artifact, '/model.safetensors');
178
+ expect(decision.effect).toBe('Deny');
179
+ });
180
+ });
181
+ describe('DEFAULT_LIMITS', () => {
182
+ it('should have consistent default values', () => {
183
+ expect(DEFAULT_LIMITS.maxContextKeys).toBe(100);
184
+ expect(DEFAULT_LIMITS.maxStringLength).toBe(1_000_000);
185
+ expect(DEFAULT_LIMITS.maxNestingDepth).toBe(10);
186
+ expect(DEFAULT_LIMITS.maxContextSizeBytes).toBe(10_000_000);
187
+ });
188
+ });
189
+ });
190
+ //# sourceMappingURL=engine.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.test.js","sourceRoot":"","sources":["../src/engine.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EACL,YAAY,EAEZ,UAAU,EACV,UAAU,EAEV,oBAAoB,EACpB,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,IAAI,MAAoB,CAAC;IAEzB,MAAM,eAAe,GAAG;;GAEvB,CAAC;IAEF,MAAM,aAAa,GAAG;;GAErB,CAAC;IAEF,uFAAuF;IACvF,MAAM,kBAAkB,GAAG;;;;;;;;;;;GAW1B,CAAC;IAEF,UAAU,CAAC,GAAG,EAAE;QACd,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;YAErC,MAAM,QAAQ,GAAG,MAAM,CAAC,cAAc,CACpC,UAAU,CAAC,OAAO,EAClB,cAAc,EACd,UAAU,CAAC,YAAY,EACvB,UAAU,CAAC,QAAQ,EACnB,oBAAoB,CACrB,CAAC;YAEF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;YAEnC,MAAM,QAAQ,GAAG,MAAM,CAAC,cAAc,CACpC,UAAU,CAAC,OAAO,EAClB,cAAc,EACd,UAAU,CAAC,YAAY,EACvB,UAAU,CAAC,QAAQ,EACnB,oBAAoB,CACrB,CAAC;YAEF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;YAC3D,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc;YAEvC,MAAM,QAAQ,GAAG,MAAM,CAAC,cAAc,CACpC,UAAU,CAAC,OAAO,EAClB,cAAc,EACd,UAAU,CAAC,YAAY,EACvB,UAAU,CAAC,QAAQ,EACnB,oBAAoB,CACrB,CAAC;YAEF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;QACxC,UAAU,CAAC,GAAG,EAAE;YACd,MAAM,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;YAC5D,mEAAmE;YACnE,MAAM,kBAAkB,GAAG;;;OAG1B,CAAC;YACF,MAAM,UAAU,GAAG,IAAI,YAAY,EAAE,CAAC;YACtC,UAAU,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC;YAE5C,MAAM,QAAQ,GAAG,UAAU,CAAC,cAAc,CACxC,UAAU,CAAC,OAAO,EAClB,UAAU,EACV,UAAU,CAAC,YAAY,EACvB,UAAU,CAAC,QAAQ,EACnB,oBAAoB,EACpB,EAAE,WAAW,EAAE,YAAY,EAAE,CAC9B,CAAC;YAEF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;YAClE,MAAM,QAAQ,GAAG,MAAM,CAAC,cAAc,CACpC,UAAU,CAAC,OAAO,EAClB,UAAU,EACV,UAAU,CAAC,YAAY,EACvB,UAAU,CAAC,QAAQ,EACnB,oBAAoB,EACpB,EAAE,WAAW,EAAE,aAAa,EAAE,CAC/B,CAAC;YAEF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;YAC5D,MAAM,QAAQ,GAAG,MAAM,CAAC,cAAc,CACpC,UAAU,CAAC,OAAO,EAClB,UAAU,EACV,UAAU,CAAC,YAAY,EACvB,UAAU,CAAC,QAAQ,EACnB,oBAAoB,EACpB,EAAE,CAAC,sBAAsB;aAC1B,CAAC;YAEF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,UAAU,CAAC,GAAG,EAAE;YACd,MAAM,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;YACrC,MAAM,QAAQ,GAAG,MAAM,CAAC,cAAc,CACpC,UAAU,CAAC,OAAO,EAClB,MAAM,EACN,UAAU,CAAC,YAAY,EACvB,UAAU,CAAC,QAAQ,EACnB,oBAAoB,EACpB;gBACE,WAAW,EAAE,YAAY;gBACzB,QAAQ,EAAE,MAAM;gBAChB,KAAK,EAAE,EAAE;gBACT,OAAO,EAAE,IAAI;aACd,CACF,CAAC;YAEF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,cAAc,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YACnE,MAAM,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;YAErC,MAAM,UAAU,GAA4B,EAAE,CAAC;YAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC5B,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC;YAClC,CAAC;YAED,MAAM,CAAC,GAAG,EAAE;gBACV,MAAM,CAAC,cAAc,CACnB,UAAU,CAAC,OAAO,EAClB,MAAM,EACN,UAAU,CAAC,YAAY,EACvB,UAAU,CAAC,QAAQ,EACnB,oBAAoB,EACpB,UAAU,CACX,CAAC;YACJ,CAAC,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;YACrD,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,eAAe,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;YACtE,MAAM,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;YAErC,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAEnC,MAAM,CAAC,GAAG,EAAE;gBACV,MAAM,CAAC,cAAc,CACnB,UAAU,CAAC,OAAO,EAClB,MAAM,EACN,UAAU,CAAC,YAAY,EACvB,UAAU,CAAC,QAAQ,EACnB,oBAAoB,EACpB,EAAE,KAAK,EAAE,UAAU,EAAE,CACtB,CAAC;YACJ,CAAC,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YACpE,MAAM,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;YAErC,MAAM,WAAW,GAAG;gBAClB,MAAM,EAAE;oBACN,MAAM,EAAE;wBACN,MAAM,EAAE;4BACN,MAAM,EAAE;gCACN,MAAM,EAAE,UAAU;6BACnB;yBACF;qBACF;iBACF;aACF,CAAC;YAEF,MAAM,CAAC,GAAG,EAAE;gBACV,MAAM,CAAC,cAAc,CACnB,UAAU,CAAC,OAAO,EAClB,MAAM,EACN,UAAU,CAAC,YAAY,EACvB,UAAU,CAAC,QAAQ,EACnB,oBAAoB,EACpB,WAAW,CACZ,CAAC;YACJ,CAAC,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC;gBAC9B,cAAc,EAAE,IAAI;gBACpB,MAAM,EAAE,EAAE,cAAc,EAAE,CAAC,EAAE;aAC9B,CAAC,CAAC;YACH,MAAM,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;YAErC,sCAAsC;YACtC,MAAM,QAAQ,GAAG,MAAM,CAAC,cAAc,CACpC,UAAU,CAAC,OAAO,EAClB,MAAM,EACN,UAAU,CAAC,YAAY,EACvB,UAAU,CAAC,QAAQ,EACnB,oBAAoB,EACpB,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,CACnD,CAAC;YAEF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACrC,UAAU,CAAC,GAAG,EAAE;YACd,MAAM,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,QAAQ,GAAG,MAAM,CAAC,cAAc,CACpC,UAAU,CAAC,OAAO,EAClB,MAAM,EACN,UAAU,CAAC,YAAY,EACvB,UAAU,CAAC,QAAQ,EACnB,oBAAoB,EACpB,EAAE,OAAO,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,WAAW,CAAC,EAAE,CAClD,CAAC;YAEF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,QAAQ,GAAG,MAAM,CAAC,cAAc,CACpC,UAAU,CAAC,OAAO,EAClB,MAAM,EACN,UAAU,CAAC,YAAY,EACvB,UAAU,CAAC,QAAQ,EACnB,oBAAoB,EACpB;gBACE,QAAQ,EAAE;oBACR,MAAM,EAAE,aAAa;oBACrB,IAAI,EAAE,IAAI;iBACX;aACF,CACF,CAAC;YAEF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;YACrC,uEAAuE;YACvE,MAAM,QAAQ,GAAG,MAAM,CAAC,cAAc,CACpC,UAAU,CAAC,OAAO,EAClB,MAAM,EACN,UAAU,CAAC,YAAY,EACvB,UAAU,CAAC,QAAQ,EACnB,oBAAoB,EACpB,EAAE,CACH,CAAC;YAEF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;YAC9C,MAAM,QAAQ,GAAG,MAAM,CAAC,cAAc,CACpC,UAAU,CAAC,OAAO,EAClB,MAAM,EACN,UAAU,CAAC,YAAY,EACvB,UAAU,CAAC,QAAQ,EACnB,oBAAoB,EACpB,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,CACzC,CAAC;YAEF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;YAC9C,8DAA8D;YAC9D,MAAM,QAAQ,GAAG,MAAM,CAAC,cAAc,CACpC,UAAU,CAAC,OAAO,EAClB,MAAM,EACN,UAAU,CAAC,YAAY,EACvB,UAAU,CAAC,QAAQ,EACnB,oBAAoB,EACpB,EAAE,cAAc,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAClC,CAAC;YAEF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,aAAa,GAAG,oCAAoC,CAAC,CAAC,wBAAwB;YAEpF,MAAM,CAAC,GAAG,EAAE;gBACV,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;gBACnC,MAAM,CAAC,cAAc,CACnB,UAAU,CAAC,OAAO,EAClB,MAAM,EACN,UAAU,CAAC,YAAY,EACvB,UAAU,CAAC,QAAQ,EACnB,oBAAoB,CACrB,CAAC;YACJ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YAEjB,iCAAiC;YACjC,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;YACnC,MAAM,QAAQ,GAAG,MAAM,CAAC,cAAc,CACpC,UAAU,CAAC,OAAO,EAClB,MAAM,EACN,UAAU,CAAC,YAAY,EACvB,UAAU,CAAC,QAAQ,EACnB,oBAAoB,CACrB,CAAC;YAEF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,MAAM,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChD,MAAM,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACvD,MAAM,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAChD,MAAM,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -4,8 +4,12 @@
4
4
  export declare const EntityType: {
5
5
  readonly Agent: "Agent";
6
6
  readonly Artifact: "Artifact";
7
+ readonly ExternalAPI: "ExternalAPI";
7
8
  readonly FilePath: "FilePath";
9
+ readonly GitBranch: "GitBranch";
8
10
  readonly HttpEndpoint: "HttpEndpoint";
11
+ readonly Memory: "Memory";
12
+ readonly Model: "Model";
9
13
  readonly Package: "Package";
10
14
  readonly Repository: "Repository";
11
15
  readonly Resource: "Resource";
@@ -1 +1 @@
1
- {"version":3,"file":"entities.gen.d.ts","sourceRoot":"","sources":["../src/entities.gen.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;CAcb,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,SAAS;IACtB,IAAI,EAAE,UAAU,GAAG,MAAM,CAAC;IAC1B,EAAE,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IACnB,GAAG,EAAE,SAAS,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,SAAS,CAE7E;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAMxG"}
1
+ {"version":3,"file":"entities.gen.d.ts","sourceRoot":"","sources":["../src/entities.gen.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;CAkBb,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,SAAS;IACtB,IAAI,EAAE,UAAU,GAAG,MAAM,CAAC;IAC1B,EAAE,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IACnB,GAAG,EAAE,SAAS,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,SAAS,CAE7E;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAMxG"}
@@ -6,8 +6,12 @@
6
6
  export const EntityType = {
7
7
  Agent: 'Agent',
8
8
  Artifact: 'Artifact',
9
+ ExternalAPI: 'ExternalAPI',
9
10
  FilePath: 'FilePath',
11
+ GitBranch: 'GitBranch',
10
12
  HttpEndpoint: 'HttpEndpoint',
13
+ Memory: 'Memory',
14
+ Model: 'Model',
11
15
  Package: 'Package',
12
16
  Repository: 'Repository',
13
17
  Resource: 'Resource',
@@ -1 +1 @@
1
- {"version":3,"file":"entities.gen.js","sourceRoot":"","sources":["../src/entities.gen.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,uCAAuC;AAEvC;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACtB,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;IACpB,QAAQ,EAAE,UAAU;IACpB,YAAY,EAAE,cAAc;IAC5B,OAAO,EAAE,SAAS;IAClB,UAAU,EAAE,YAAY;IACxB,QAAQ,EAAE,UAAU;IACpB,YAAY,EAAE,cAAc;IAC5B,OAAO,EAAE,SAAS;IAClB,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;CACN,CAAC;AAqBX;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,IAAyB,EAAE,EAAU;IAC9D,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,IAAyB,EAAE,EAAU,EAAE,KAA+B;IAC5F,OAAO;QACH,GAAG,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACjB,KAAK,EAAE,KAAK,IAAI,EAAE;QAClB,OAAO,EAAE,EAAE;KACd,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"entities.gen.js","sourceRoot":"","sources":["../src/entities.gen.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,uCAAuC;AAEvC;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACtB,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;IACpB,WAAW,EAAE,aAAa;IAC1B,QAAQ,EAAE,UAAU;IACpB,SAAS,EAAE,WAAW;IACtB,YAAY,EAAE,cAAc;IAC5B,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,UAAU,EAAE,YAAY;IACxB,QAAQ,EAAE,UAAU;IACpB,YAAY,EAAE,cAAc;IAC5B,OAAO,EAAE,SAAS;IAClB,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;CACN,CAAC;AAqBX;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,IAAyB,EAAE,EAAU;IAC9D,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,IAAyB,EAAE,EAAU,EAAE,KAA+B;IAC5F,OAAO;QACH,GAAG,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACjB,KAAK,EAAE,KAAK,IAAI,EAAE;QAClB,OAAO,EAAE,EAAE;KACd,CAAC;AACN,CAAC"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Parser error types and codes for highflame-policy.
3
+ *
4
+ * This module provides standardized error codes that are consistent
5
+ * across all language implementations (Rust, Go, TypeScript, Python).
6
+ */
7
+ /**
8
+ * Error codes for parser errors.
9
+ *
10
+ * These codes are stable and consistent across all language implementations.
11
+ * Format: HFP-<CATEGORY>-<NUMBER>
12
+ * - HFP = HighFlame Policy
13
+ * - CATEGORY = SCOPE | ACTION | COND | PARSE
14
+ * - NUMBER = 3-digit incremental
15
+ */
16
+ export declare const ErrorCodes: {
17
+ /** Scope constraint is missing an entity (for == operator) */
18
+ readonly SCOPE_MISSING_ENTITY: "HFP-SCOPE-001";
19
+ /** Scope constraint is missing an entity type (for is operator) */
20
+ readonly SCOPE_MISSING_ENTITY_TYPE: "HFP-SCOPE-002";
21
+ /** Scope constraint is missing entity list (for in operator) */
22
+ readonly SCOPE_MISSING_ENTITY_LIST: "HFP-SCOPE-003";
23
+ /** Slot constraints are not supported in PolicyRule */
24
+ readonly SCOPE_SLOT_NOT_SUPPORTED: "HFP-SCOPE-004";
25
+ /** Unsupported scope operator */
26
+ readonly SCOPE_UNSUPPORTED_OP: "HFP-SCOPE-005";
27
+ /** Action constraint is missing an entity (for == operator) */
28
+ readonly ACTION_MISSING_ENTITY: "HFP-ACTION-001";
29
+ /** Action constraint is missing entities (for in operator) */
30
+ readonly ACTION_MISSING_ENTITIES: "HFP-ACTION-002";
31
+ /** Unsupported action operator */
32
+ readonly ACTION_UNSUPPORTED_OP: "HFP-ACTION-003";
33
+ /** Action scope is null/nil */
34
+ readonly ACTION_SCOPE_NIL: "HFP-ACTION-004";
35
+ /** Unless clauses are not supported in PolicyRule */
36
+ readonly COND_UNLESS_NOT_SUPPORTED: "HFP-COND-001";
37
+ /** Complex condition cannot be parsed */
38
+ readonly COND_COMPLEX_EXPRESSION: "HFP-COND-002";
39
+ /** Invalid Cedar syntax */
40
+ readonly PARSE_INVALID_SYNTAX: "HFP-PARSE-001";
41
+ /** Failed to convert policy to JSON */
42
+ readonly PARSE_JSON_CONVERSION: "HFP-PARSE-002";
43
+ /** Failed to parse Cedar JSON structure */
44
+ readonly PARSE_JSON_STRUCTURE: "HFP-PARSE-003";
45
+ /** Unknown policy effect (not permit or forbid) */
46
+ readonly PARSE_UNKNOWN_EFFECT: "HFP-PARSE-004";
47
+ /** Duplicate policy ID found */
48
+ readonly PARSE_DUPLICATE_ID: "HFP-PARSE-005";
49
+ };
50
+ export type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
51
+ /**
52
+ * Context information for parser errors.
53
+ */
54
+ export interface ErrorContext {
55
+ /** The operator that caused the error (e.g., "==", "in", "is") */
56
+ operator?: string;
57
+ /** The field that caused the error (e.g., "principal", "action", "resource") */
58
+ field?: string;
59
+ /** The policy ID if available */
60
+ policyId?: string;
61
+ }
62
+ /**
63
+ * A structured parser error with code, message, and optional context.
64
+ */
65
+ export declare class ParserError extends Error {
66
+ /** Machine-readable error code (e.g., "HFP-SCOPE-001") */
67
+ readonly code: ErrorCode;
68
+ /** Optional context for debugging */
69
+ readonly context?: ErrorContext;
70
+ constructor(code: ErrorCode, message: string, context?: ErrorContext);
71
+ /**
72
+ * Returns a string representation including the error code.
73
+ */
74
+ toString(): string;
75
+ /**
76
+ * Serializes the error to a plain object for JSON serialization.
77
+ */
78
+ toJSON(): {
79
+ code: string;
80
+ message: string;
81
+ context?: ErrorContext;
82
+ };
83
+ /** Scope constraint is missing an entity */
84
+ static scopeMissingEntity(operator: string, field: string): ParserError;
85
+ /** Scope constraint is missing an entity type */
86
+ static scopeMissingEntityType(field: string): ParserError;
87
+ /** Scope constraint is missing entity list */
88
+ static scopeMissingEntityList(field: string): ParserError;
89
+ /** Slot constraints are not supported */
90
+ static scopeSlotNotSupported(operator: string, field: string): ParserError;
91
+ /** Unsupported scope operator */
92
+ static scopeUnsupportedOp(operator: string, field: string): ParserError;
93
+ /** Action constraint is missing an entity */
94
+ static actionMissingEntity(operator: string): ParserError;
95
+ /** Action constraint is missing entities */
96
+ static actionMissingEntities(): ParserError;
97
+ /** Unsupported action operator */
98
+ static actionUnsupportedOp(operator: string): ParserError;
99
+ /** Action scope is nil */
100
+ static actionScopeNil(): ParserError;
101
+ }
102
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU;IAErB,8DAA8D;;IAE9D,mEAAmE;;IAEnE,gEAAgE;;IAEhE,uDAAuD;;IAEvD,iCAAiC;;IAIjC,+DAA+D;;IAE/D,8DAA8D;;IAE9D,kCAAkC;;IAElC,+BAA+B;;IAI/B,qDAAqD;;IAErD,yCAAyC;;IAIzC,2BAA2B;;IAE3B,uCAAuC;;IAEvC,2CAA2C;;IAE3C,mDAAmD;;IAEnD,gCAAgC;;CAExB,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,WAAY,SAAQ,KAAK;IACpC,0DAA0D;IAC1D,SAAgB,IAAI,EAAE,SAAS,CAAC;IAChC,qCAAqC;IACrC,SAAgB,OAAO,CAAC,EAAE,YAAY,CAAC;gBAE3B,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;IAapE;;OAEG;IACM,QAAQ,IAAI,MAAM;IAI3B;;OAEG;IACH,MAAM,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,YAAY,CAAA;KAAE;IAUnE,4CAA4C;IAC5C,MAAM,CAAC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW;IAQvE,iDAAiD;IACjD,MAAM,CAAC,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW;IAQzD,8CAA8C;IAC9C,MAAM,CAAC,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW;IAQzD,yCAAyC;IACzC,MAAM,CAAC,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW;IAQ1E,iCAAiC;IACjC,MAAM,CAAC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW;IAQvE,6CAA6C;IAC7C,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW;IAQzD,4CAA4C;IAC5C,MAAM,CAAC,qBAAqB,IAAI,WAAW;IAQ3C,kCAAkC;IAClC,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW;IAQzD,0BAA0B;IAC1B,MAAM,CAAC,cAAc,IAAI,WAAW;CAOrC"}
package/dist/errors.js ADDED
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Parser error types and codes for highflame-policy.
3
+ *
4
+ * This module provides standardized error codes that are consistent
5
+ * across all language implementations (Rust, Go, TypeScript, Python).
6
+ */
7
+ /**
8
+ * Error codes for parser errors.
9
+ *
10
+ * These codes are stable and consistent across all language implementations.
11
+ * Format: HFP-<CATEGORY>-<NUMBER>
12
+ * - HFP = HighFlame Policy
13
+ * - CATEGORY = SCOPE | ACTION | COND | PARSE
14
+ * - NUMBER = 3-digit incremental
15
+ */
16
+ export const ErrorCodes = {
17
+ // Scope constraint errors (HFP-SCOPE-xxx)
18
+ /** Scope constraint is missing an entity (for == operator) */
19
+ SCOPE_MISSING_ENTITY: "HFP-SCOPE-001",
20
+ /** Scope constraint is missing an entity type (for is operator) */
21
+ SCOPE_MISSING_ENTITY_TYPE: "HFP-SCOPE-002",
22
+ /** Scope constraint is missing entity list (for in operator) */
23
+ SCOPE_MISSING_ENTITY_LIST: "HFP-SCOPE-003",
24
+ /** Slot constraints are not supported in PolicyRule */
25
+ SCOPE_SLOT_NOT_SUPPORTED: "HFP-SCOPE-004",
26
+ /** Unsupported scope operator */
27
+ SCOPE_UNSUPPORTED_OP: "HFP-SCOPE-005",
28
+ // Action constraint errors (HFP-ACTION-xxx)
29
+ /** Action constraint is missing an entity (for == operator) */
30
+ ACTION_MISSING_ENTITY: "HFP-ACTION-001",
31
+ /** Action constraint is missing entities (for in operator) */
32
+ ACTION_MISSING_ENTITIES: "HFP-ACTION-002",
33
+ /** Unsupported action operator */
34
+ ACTION_UNSUPPORTED_OP: "HFP-ACTION-003",
35
+ /** Action scope is null/nil */
36
+ ACTION_SCOPE_NIL: "HFP-ACTION-004",
37
+ // Condition errors (HFP-COND-xxx)
38
+ /** Unless clauses are not supported in PolicyRule */
39
+ COND_UNLESS_NOT_SUPPORTED: "HFP-COND-001",
40
+ /** Complex condition cannot be parsed */
41
+ COND_COMPLEX_EXPRESSION: "HFP-COND-002",
42
+ // Parse errors (HFP-PARSE-xxx)
43
+ /** Invalid Cedar syntax */
44
+ PARSE_INVALID_SYNTAX: "HFP-PARSE-001",
45
+ /** Failed to convert policy to JSON */
46
+ PARSE_JSON_CONVERSION: "HFP-PARSE-002",
47
+ /** Failed to parse Cedar JSON structure */
48
+ PARSE_JSON_STRUCTURE: "HFP-PARSE-003",
49
+ /** Unknown policy effect (not permit or forbid) */
50
+ PARSE_UNKNOWN_EFFECT: "HFP-PARSE-004",
51
+ /** Duplicate policy ID found */
52
+ PARSE_DUPLICATE_ID: "HFP-PARSE-005",
53
+ };
54
+ /**
55
+ * A structured parser error with code, message, and optional context.
56
+ */
57
+ export class ParserError extends Error {
58
+ /** Machine-readable error code (e.g., "HFP-SCOPE-001") */
59
+ code;
60
+ /** Optional context for debugging */
61
+ context;
62
+ constructor(code, message, context) {
63
+ super(message);
64
+ this.name = "ParserError";
65
+ this.code = code;
66
+ this.context = context;
67
+ // Maintains proper stack trace for where our error was thrown (only available on V8)
68
+ const ErrorWithCapture = Error;
69
+ if (ErrorWithCapture.captureStackTrace) {
70
+ ErrorWithCapture.captureStackTrace(this, ParserError);
71
+ }
72
+ }
73
+ /**
74
+ * Returns a string representation including the error code.
75
+ */
76
+ toString() {
77
+ return `[${this.code}] ${this.message}`;
78
+ }
79
+ /**
80
+ * Serializes the error to a plain object for JSON serialization.
81
+ */
82
+ toJSON() {
83
+ return {
84
+ code: this.code,
85
+ message: this.message,
86
+ ...(this.context && { context: this.context }),
87
+ };
88
+ }
89
+ // Convenience static factory methods for common errors
90
+ /** Scope constraint is missing an entity */
91
+ static scopeMissingEntity(operator, field) {
92
+ return new ParserError(ErrorCodes.SCOPE_MISSING_ENTITY, `'${operator}' constraint is missing an entity`, { operator, field });
93
+ }
94
+ /** Scope constraint is missing an entity type */
95
+ static scopeMissingEntityType(field) {
96
+ return new ParserError(ErrorCodes.SCOPE_MISSING_ENTITY_TYPE, "'is' constraint is missing an entity_type", { operator: "is", field });
97
+ }
98
+ /** Scope constraint is missing entity list */
99
+ static scopeMissingEntityList(field) {
100
+ return new ParserError(ErrorCodes.SCOPE_MISSING_ENTITY_LIST, "'in' constraint is missing an entity", { operator: "in", field });
101
+ }
102
+ /** Slot constraints are not supported */
103
+ static scopeSlotNotSupported(operator, field) {
104
+ return new ParserError(ErrorCodes.SCOPE_SLOT_NOT_SUPPORTED, `'${operator}' constraint with slot cannot be represented`, { operator, field });
105
+ }
106
+ /** Unsupported scope operator */
107
+ static scopeUnsupportedOp(operator, field) {
108
+ return new ParserError(ErrorCodes.SCOPE_UNSUPPORTED_OP, `Unsupported scope operator: ${operator}`, { operator, field });
109
+ }
110
+ /** Action constraint is missing an entity */
111
+ static actionMissingEntity(operator) {
112
+ return new ParserError(ErrorCodes.ACTION_MISSING_ENTITY, `Action '${operator}' constraint is missing an entity`, { operator, field: "action" });
113
+ }
114
+ /** Action constraint is missing entities */
115
+ static actionMissingEntities() {
116
+ return new ParserError(ErrorCodes.ACTION_MISSING_ENTITIES, "Action 'in' constraint is missing entities", { operator: "in", field: "action" });
117
+ }
118
+ /** Unsupported action operator */
119
+ static actionUnsupportedOp(operator) {
120
+ return new ParserError(ErrorCodes.ACTION_UNSUPPORTED_OP, `Unsupported action operator: ${operator}`, { operator, field: "action" });
121
+ }
122
+ /** Action scope is nil */
123
+ static actionScopeNil() {
124
+ return new ParserError(ErrorCodes.ACTION_SCOPE_NIL, "Action scope is nil", { field: "action" });
125
+ }
126
+ }
127
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -4,4 +4,6 @@ export * from './context.gen.js';
4
4
  export * from './schema.gen.js';
5
5
  export * from './engine.js';
6
6
  export * from './builder.js';
7
+ export * from './parser.js';
8
+ export * from './errors.js';
7
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAGhC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAGhC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -10,4 +10,6 @@ export * from './schema.gen.js';
10
10
  // Non-generated modules (require Node.js)
11
11
  export * from './engine.js';
12
12
  export * from './builder.js';
13
+ export * from './parser.js';
14
+ export * from './errors.js';
13
15
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,uCAAuC;AACvC,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AAEpE,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAEhC,0CAA0C;AAC1C,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,uCAAuC;AACvC,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AAEpE,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAEhC,0CAA0C;AAC1C,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Cedar Policy Parser
3
+ *
4
+ * Converts Cedar policy text to structured PolicyRule format using the
5
+ * official Cedar engine (cedar-wasm) for parsing.
6
+ *
7
+ * Architecture:
8
+ * 1. Cedar text → Cedar JSON (via cedar-wasm policyToJson)
9
+ * 2. Cedar JSON → PolicyRule (simple JSON mapping)
10
+ */
11
+ import type { PolicyRule } from "./builder.js";
12
+ /**
13
+ * Result of parsing Cedar policies
14
+ */
15
+ export interface ParseResult {
16
+ /** Policies successfully converted to PolicyRule format */
17
+ rules: PolicyRule[];
18
+ /** Policies that couldn't be fully represented as PolicyRule (raw Cedar text) */
19
+ unstructured: string[];
20
+ /** Any parsing errors encountered */
21
+ errors: string[];
22
+ }
23
+ /**
24
+ * Parse Cedar policy text and convert to PolicyRule format.
25
+ *
26
+ * Uses the official cedar-wasm engine for parsing, ensuring correctness.
27
+ * Policies with features that can't be represented as PolicyRule (e.g.,
28
+ * unless clauses, complex expressions) are returned in the unstructured array.
29
+ *
30
+ * @param cedarText - Cedar policy text to parse
31
+ * @returns ParseResult with structured rules, unstructured policies, and errors
32
+ */
33
+ export declare function parseCedarToRules(cedarText: string): ParseResult;
34
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAkE,MAAM,cAAc,CAAC;AAG/G;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,iFAAiF;IACjF,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,qCAAqC;IACrC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAmDD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,CA4EhE"}