@fabricorg/platform 1.9.0 → 1.10.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.
- package/CHANGELOG.md +56 -0
- package/README.md +48 -2
- package/dist/actions/index.cjs +45 -26
- package/dist/actions/index.cjs.map +1 -1
- package/dist/actions/index.d.cts +225 -226
- package/dist/actions/index.d.ts +225 -226
- package/dist/actions/index.js +41 -2
- package/dist/actions/index.js.map +1 -1
- package/dist/adapters/index.cjs +696 -66
- package/dist/adapters/index.cjs.map +1 -1
- package/dist/adapters/index.d.cts +367 -365
- package/dist/adapters/index.d.ts +367 -365
- package/dist/adapters/index.js +682 -2
- package/dist/adapters/index.js.map +1 -1
- package/dist/agent-hitl/index.cjs +21 -10
- package/dist/agent-hitl/index.cjs.map +1 -1
- package/dist/agent-hitl/index.d.cts +30 -30
- package/dist/agent-hitl/index.d.ts +30 -30
- package/dist/agent-hitl/index.js +21 -2
- package/dist/agent-hitl/index.js.map +1 -1
- package/dist/certification/index.cjs +109 -24
- package/dist/certification/index.cjs.map +1 -1
- package/dist/certification/index.d.cts +33 -39
- package/dist/certification/index.d.ts +33 -39
- package/dist/certification/index.js +107 -8
- package/dist/certification/index.js.map +1 -1
- package/dist/discovery/index.cjs +12 -10
- package/dist/discovery/index.cjs.map +1 -1
- package/dist/discovery/index.d.cts +2 -10
- package/dist/discovery/index.d.ts +2 -10
- package/dist/discovery/index.js +12 -2
- package/dist/discovery/index.js.map +1 -1
- package/dist/engine-B4csEOEc.js +223 -0
- package/dist/engine-B4csEOEc.js.map +1 -0
- package/dist/engine-BqScuhrT.cjs +246 -0
- package/dist/engine-BqScuhrT.cjs.map +1 -0
- package/dist/events/index.cjs +39 -10
- package/dist/events/index.cjs.map +1 -1
- package/dist/events/index.d.cts +43 -43
- package/dist/events/index.d.ts +43 -43
- package/dist/events/index.js +39 -2
- package/dist/events/index.js.map +1 -1
- package/dist/evidence/index.cjs +12 -50
- package/dist/evidence/index.d.cts +2 -229
- package/dist/evidence/index.d.ts +2 -229
- package/dist/evidence/index.js +1 -5
- package/dist/evidence-BuCICb0c.js +516 -0
- package/dist/evidence-BuCICb0c.js.map +1 -0
- package/dist/evidence-Cq48eDvA.cjs +575 -0
- package/dist/evidence-Cq48eDvA.cjs.map +1 -0
- package/dist/governance/index.cjs +24 -18
- package/dist/governance/index.cjs.map +1 -1
- package/dist/governance/index.d.cts +80 -83
- package/dist/governance/index.d.ts +80 -83
- package/dist/governance/index.js +22 -2
- package/dist/governance/index.js.map +1 -1
- package/dist/ids/index.cjs +52 -22
- package/dist/ids/index.cjs.map +1 -1
- package/dist/ids/index.d.cts +17 -17
- package/dist/ids/index.d.ts +17 -17
- package/dist/ids/index.js +49 -2
- package/dist/ids/index.js.map +1 -1
- package/dist/index-9jasmw76.d.cts +124 -0
- package/dist/index-BXpeFdk2.d.cts +190 -0
- package/dist/index-BXpeFdk2.d.ts +190 -0
- package/dist/index-BnbsKZsT.d.cts +231 -0
- package/dist/index-CIl1rYRv.d.cts +11 -0
- package/dist/index-CIl1rYRv.d.ts +11 -0
- package/dist/index-CVHA1ypT.d.cts +262 -0
- package/dist/index-DZ4mnNb7.d.cts +78 -0
- package/dist/index-DZ4mnNb7.d.ts +78 -0
- package/dist/index-IqcDvl69.d.ts +124 -0
- package/dist/index-fmUiRBXu.d.cts +57 -0
- package/dist/index-fmUiRBXu.d.ts +57 -0
- package/dist/index-sPUPs8pr.d.ts +262 -0
- package/dist/index-z9-CYOIo.d.ts +231 -0
- package/dist/index.cjs +111 -385
- package/dist/index.d.cts +18 -17
- package/dist/index.d.ts +18 -17
- package/dist/index.js +19 -20
- package/dist/manifest/index.cjs +224 -35
- package/dist/manifest/index.cjs.map +1 -1
- package/dist/manifest/index.d.cts +130 -131
- package/dist/manifest/index.d.ts +130 -131
- package/dist/manifest/index.js +219 -7
- package/dist/manifest/index.js.map +1 -1
- package/dist/modules/index.cjs +281 -42
- package/dist/modules/index.cjs.map +1 -1
- package/dist/modules/index.d.cts +157 -159
- package/dist/modules/index.d.ts +157 -159
- package/dist/modules/index.js +274 -6
- package/dist/modules/index.js.map +1 -1
- package/dist/objects/index.cjs +355 -22
- package/dist/objects/index.cjs.map +1 -1
- package/dist/objects/index.d.cts +2 -77
- package/dist/objects/index.d.ts +2 -77
- package/dist/objects/index.js +352 -2
- package/dist/objects/index.js.map +1 -1
- package/dist/policies/index.cjs +14 -48
- package/dist/policies/index.d.cts +2 -247
- package/dist/policies/index.d.ts +2 -247
- package/dist/policies/index.js +1 -3
- package/dist/policies-DH_GCXQ-.js +627 -0
- package/dist/policies-DH_GCXQ-.js.map +1 -0
- package/dist/policies-Nxbp1CH8.cjs +698 -0
- package/dist/policies-Nxbp1CH8.cjs.map +1 -0
- package/dist/privacy/index.cjs +26 -43
- package/dist/privacy/index.cjs.map +1 -1
- package/dist/privacy/index.d.cts +2 -189
- package/dist/privacy/index.d.ts +2 -189
- package/dist/privacy/index.js +18 -3
- package/dist/privacy/index.js.map +1 -1
- package/dist/projections/index.cjs +241 -23
- package/dist/projections/index.cjs.map +1 -1
- package/dist/projections/index.d.cts +2 -125
- package/dist/projections/index.d.ts +2 -125
- package/dist/projections/index.js +238 -3
- package/dist/projections/index.js.map +1 -1
- package/dist/state-machines/index.cjs +76 -18
- package/dist/state-machines/index.cjs.map +1 -1
- package/dist/state-machines/index.d.cts +2 -55
- package/dist/state-machines/index.d.ts +2 -55
- package/dist/state-machines/index.js +74 -2
- package/dist/state-machines/index.js.map +1 -1
- package/dist/testing/index.cjs +27 -19
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +17 -19
- package/dist/testing/index.d.ts +17 -19
- package/dist/testing/index.js +25 -3
- package/dist/testing/index.js.map +1 -1
- package/package.json +6 -5
- package/dist/chunk-2AE6TMAX.cjs +0 -44
- package/dist/chunk-2AE6TMAX.cjs.map +0 -1
- package/dist/chunk-6HY35TKB.cjs +0 -491
- package/dist/chunk-6HY35TKB.cjs.map +0 -1
- package/dist/chunk-6UGEIDLC.cjs +0 -26
- package/dist/chunk-6UGEIDLC.cjs.map +0 -1
- package/dist/chunk-7GAWSUOG.js +0 -64
- package/dist/chunk-7GAWSUOG.js.map +0 -1
- package/dist/chunk-AFXFAEWA.js +0 -673
- package/dist/chunk-AFXFAEWA.js.map +0 -1
- package/dist/chunk-AFXKSIVI.cjs +0 -540
- package/dist/chunk-AFXKSIVI.cjs.map +0 -1
- package/dist/chunk-B5DOGDPG.js +0 -42
- package/dist/chunk-B5DOGDPG.js.map +0 -1
- package/dist/chunk-BJGZE3GE.js +0 -20
- package/dist/chunk-BJGZE3GE.js.map +0 -1
- package/dist/chunk-CRZXTZ36.cjs +0 -258
- package/dist/chunk-CRZXTZ36.cjs.map +0 -1
- package/dist/chunk-D4SWRBUH.cjs +0 -22
- package/dist/chunk-D4SWRBUH.cjs.map +0 -1
- package/dist/chunk-DBTAUI6C.cjs +0 -395
- package/dist/chunk-DBTAUI6C.cjs.map +0 -1
- package/dist/chunk-EMSAFNPX.js +0 -98
- package/dist/chunk-EMSAFNPX.js.map +0 -1
- package/dist/chunk-F3E5SXPN.cjs +0 -28
- package/dist/chunk-F3E5SXPN.cjs.map +0 -1
- package/dist/chunk-HEYMMVDP.js +0 -480
- package/dist/chunk-HEYMMVDP.js.map +0 -1
- package/dist/chunk-IFW43ELT.cjs +0 -331
- package/dist/chunk-IFW43ELT.cjs.map +0 -1
- package/dist/chunk-LFE74IJX.js +0 -20
- package/dist/chunk-LFE74IJX.js.map +0 -1
- package/dist/chunk-LZSE6QGQ.cjs +0 -60
- package/dist/chunk-LZSE6QGQ.cjs.map +0 -1
- package/dist/chunk-MCWSUGB3.cjs +0 -102
- package/dist/chunk-MCWSUGB3.cjs.map +0 -1
- package/dist/chunk-MLBALEUR.js +0 -290
- package/dist/chunk-MLBALEUR.js.map +0 -1
- package/dist/chunk-NNXQZPB3.cjs +0 -31
- package/dist/chunk-NNXQZPB3.cjs.map +0 -1
- package/dist/chunk-OFCCZ27Z.js +0 -26
- package/dist/chunk-OFCCZ27Z.js.map +0 -1
- package/dist/chunk-PDN5DOLQ.js +0 -242
- package/dist/chunk-PDN5DOLQ.js.map +0 -1
- package/dist/chunk-PIDZQAEL.js +0 -50
- package/dist/chunk-PIDZQAEL.js.map +0 -1
- package/dist/chunk-Q4Q4JPR3.js +0 -524
- package/dist/chunk-Q4Q4JPR3.js.map +0 -1
- package/dist/chunk-RALMUSOX.js +0 -55
- package/dist/chunk-RALMUSOX.js.map +0 -1
- package/dist/chunk-SNTV45LH.cjs +0 -295
- package/dist/chunk-SNTV45LH.cjs.map +0 -1
- package/dist/chunk-TBS2S5AX.cjs +0 -40
- package/dist/chunk-TBS2S5AX.cjs.map +0 -1
- package/dist/chunk-TYNIFC7J.js +0 -253
- package/dist/chunk-TYNIFC7J.js.map +0 -1
- package/dist/chunk-UGWGHTNC.cjs +0 -56
- package/dist/chunk-UGWGHTNC.cjs.map +0 -1
- package/dist/chunk-WI7CWNYI.cjs +0 -68
- package/dist/chunk-WI7CWNYI.cjs.map +0 -1
- package/dist/chunk-WNZP53GI.js +0 -386
- package/dist/chunk-WNZP53GI.js.map +0 -1
- package/dist/chunk-WQ3BYI7T.cjs +0 -249
- package/dist/chunk-WQ3BYI7T.cjs.map +0 -1
- package/dist/chunk-Y2PJLRIY.js +0 -36
- package/dist/chunk-Y2PJLRIY.js.map +0 -1
- package/dist/chunk-YGIPN3TU.cjs +0 -684
- package/dist/chunk-YGIPN3TU.cjs.map +0 -1
- package/dist/chunk-ZAEVQSB5.js +0 -326
- package/dist/chunk-ZAEVQSB5.js.map +0 -1
- package/dist/chunk-ZMQTV5OJ.js +0 -27
- package/dist/chunk-ZMQTV5OJ.js.map +0 -1
- package/dist/evidence/index.cjs.map +0 -1
- package/dist/evidence/index.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/policies/index.cjs.map +0 -1
- package/dist/policies/index.js.map +0 -1
package/dist/chunk-YGIPN3TU.cjs
DELETED
|
@@ -1,684 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// policies/retryable-execution.ts
|
|
4
|
-
var RetryableExecutionError = class extends Error {
|
|
5
|
-
name = "RetryableExecutionError";
|
|
6
|
-
code = "EXECUTION_RETRYABLE";
|
|
7
|
-
constructor(message, options) {
|
|
8
|
-
super(message, options);
|
|
9
|
-
}
|
|
10
|
-
};
|
|
11
|
-
function isRetryableExecutionError(error) {
|
|
12
|
-
if (error instanceof RetryableExecutionError) return true;
|
|
13
|
-
return typeof error === "object" && error !== null && error.name === "RetryableExecutionError" && error.code === "EXECUTION_RETRYABLE";
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// policies/index.ts
|
|
17
|
-
function assertPolicyId(policyId) {
|
|
18
|
-
if (!/^[a-z][a-z0-9_-]*(\.[a-z][a-z0-9_-]*)*\.v[0-9]+$/.test(policyId)) {
|
|
19
|
-
throw new Error(`Invalid policy ID: ${policyId}`);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
function validatePolicyGuidance(guidance) {
|
|
23
|
-
const errors = [];
|
|
24
|
-
if (!isPlainRecord(guidance)) {
|
|
25
|
-
return { valid: false, errors: ["guidance must be an object"] };
|
|
26
|
-
}
|
|
27
|
-
if (guidance.summary !== void 0 && typeof guidance.summary !== "string") {
|
|
28
|
-
errors.push("guidance.summary must be a string when present");
|
|
29
|
-
}
|
|
30
|
-
if (!Array.isArray(guidance.factsUsed)) {
|
|
31
|
-
errors.push("guidance.factsUsed must be an array");
|
|
32
|
-
} else {
|
|
33
|
-
guidance.factsUsed.forEach((fact, index) => {
|
|
34
|
-
if (!isPlainRecord(fact)) {
|
|
35
|
-
errors.push(`guidance.factsUsed[${index}] must be an object`);
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
if (typeof fact.name !== "string" || fact.name.length === 0) {
|
|
39
|
-
errors.push(`guidance.factsUsed[${index}].name must be a non-empty string`);
|
|
40
|
-
}
|
|
41
|
-
if (fact.label !== void 0 && typeof fact.label !== "string") {
|
|
42
|
-
errors.push(`guidance.factsUsed[${index}].label must be a string when present`);
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
if (!Array.isArray(guidance.correctiveActions)) {
|
|
47
|
-
errors.push("guidance.correctiveActions must be an array");
|
|
48
|
-
} else {
|
|
49
|
-
guidance.correctiveActions.forEach((action, index) => {
|
|
50
|
-
errors.push(...validatePolicyCorrectiveAction(action, index));
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
return { valid: errors.length === 0, errors };
|
|
54
|
-
}
|
|
55
|
-
function validatePolicyCorrectiveAction(action, index) {
|
|
56
|
-
const errors = [];
|
|
57
|
-
const prefix = `guidance.correctiveActions[${index}]`;
|
|
58
|
-
if (!isPlainRecord(action)) {
|
|
59
|
-
return [`${prefix} must be an object`];
|
|
60
|
-
}
|
|
61
|
-
if (action.kind !== "invoke_action" && action.kind !== "navigate" && action.kind !== "manual") {
|
|
62
|
-
errors.push(`${prefix}.kind must be "invoke_action" | "navigate" | "manual"`);
|
|
63
|
-
}
|
|
64
|
-
if (typeof action.label !== "string" || action.label.length === 0) {
|
|
65
|
-
errors.push(`${prefix}.label must be a non-empty string`);
|
|
66
|
-
}
|
|
67
|
-
if (action.description !== void 0 && typeof action.description !== "string") {
|
|
68
|
-
errors.push(`${prefix}.description must be a string when present`);
|
|
69
|
-
}
|
|
70
|
-
if (action.requiresConfirmation !== void 0 && typeof action.requiresConfirmation !== "boolean") {
|
|
71
|
-
errors.push(`${prefix}.requiresConfirmation must be a boolean when present`);
|
|
72
|
-
}
|
|
73
|
-
if (action.requiresRole !== void 0) {
|
|
74
|
-
if (!Array.isArray(action.requiresRole)) {
|
|
75
|
-
errors.push(`${prefix}.requiresRole must be an array when present`);
|
|
76
|
-
} else if (action.requiresRole.some((role) => typeof role !== "string" || role.length === 0)) {
|
|
77
|
-
errors.push(`${prefix}.requiresRole must contain only non-empty strings`);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
if (action.kind === "invoke_action") {
|
|
81
|
-
if (typeof action.actionId !== "string" || action.actionId.length === 0) {
|
|
82
|
-
errors.push(`${prefix}.actionId must be a non-empty string for invoke_action`);
|
|
83
|
-
}
|
|
84
|
-
if (action.parameters !== void 0 && !isPlainRecord(action.parameters)) {
|
|
85
|
-
errors.push(`${prefix}.parameters must be an object when present`);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
if (action.kind === "navigate") {
|
|
89
|
-
if (action.route !== void 0 && typeof action.route !== "string") {
|
|
90
|
-
errors.push(`${prefix}.route must be a string when present`);
|
|
91
|
-
}
|
|
92
|
-
if (action.target !== void 0 && !isPlainRecord(action.target)) {
|
|
93
|
-
errors.push(`${prefix}.target must be an object when present`);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return errors;
|
|
97
|
-
}
|
|
98
|
-
function isPlainRecord(value) {
|
|
99
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
100
|
-
}
|
|
101
|
-
var DATA_POLICY_MAX_DEPTH = 5;
|
|
102
|
-
var DATA_POLICY_MAX_CONDITIONS_PER_NODE = 20;
|
|
103
|
-
var DATA_POLICY_MAX_TOTAL_CONDITIONS = 100;
|
|
104
|
-
var DATA_POLICY_MAX_PATH_SEGMENTS = 12;
|
|
105
|
-
var DATA_POLICY_MAX_STRING_LENGTH = 500;
|
|
106
|
-
var DATA_POLICY_CONTEXT_PATHS = Object.freeze([
|
|
107
|
-
"tenantId",
|
|
108
|
-
"spaceId",
|
|
109
|
-
"actionInvocationId",
|
|
110
|
-
"actionId",
|
|
111
|
-
"mode"
|
|
112
|
-
]);
|
|
113
|
-
var DATA_POLICY_COMPARISON_OPERATORS = Object.freeze([
|
|
114
|
-
"exists",
|
|
115
|
-
"equals",
|
|
116
|
-
"notEquals",
|
|
117
|
-
"gt",
|
|
118
|
-
"gte",
|
|
119
|
-
"lt",
|
|
120
|
-
"lte"
|
|
121
|
-
]);
|
|
122
|
-
var POLICY_RESULTS = Object.freeze(["pass", "warn", "block"]);
|
|
123
|
-
function createPolicyRegistry(evaluators = []) {
|
|
124
|
-
const policies = /* @__PURE__ */ new Map();
|
|
125
|
-
const register = (evaluator) => {
|
|
126
|
-
assertPolicyId(evaluator.policyId);
|
|
127
|
-
const existing = policies.get(evaluator.policyId);
|
|
128
|
-
if (existing && existing !== evaluator) throw new Error(`Conflicting policy registration for "${evaluator.policyId}". A different evaluator is already registered.`);
|
|
129
|
-
policies.set(evaluator.policyId, evaluator);
|
|
130
|
-
};
|
|
131
|
-
for (const evaluator of evaluators) register(evaluator);
|
|
132
|
-
return {
|
|
133
|
-
register,
|
|
134
|
-
registerIfMissing(evaluator) {
|
|
135
|
-
const existing = policies.get(evaluator.policyId);
|
|
136
|
-
if (!existing) register(evaluator);
|
|
137
|
-
else if (existing !== evaluator) throw new Error(`Conflicting policy registration for "${evaluator.policyId}". A different evaluator is already registered.`);
|
|
138
|
-
},
|
|
139
|
-
resolve: (policyId) => policies.get(policyId),
|
|
140
|
-
ids: () => Array.from(policies.keys())
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
async function evaluateRegisteredPolicies(policyIds, ctx) {
|
|
144
|
-
return evaluatePolicyDefinitions(
|
|
145
|
-
policyIds.map((policyId) => ({
|
|
146
|
-
policyId,
|
|
147
|
-
policyVersion: parsePolicyVersion(policyId),
|
|
148
|
-
kind: "code",
|
|
149
|
-
codeEvaluatorPolicyId: policyId
|
|
150
|
-
})),
|
|
151
|
-
ctx
|
|
152
|
-
);
|
|
153
|
-
}
|
|
154
|
-
async function evaluatePolicyDefinitions(policies, ctx) {
|
|
155
|
-
const outcomes = [];
|
|
156
|
-
for (const policy of policies) {
|
|
157
|
-
assertPolicyId(policy.policyId);
|
|
158
|
-
outcomes.push(await evaluatePolicyDefinition(policy, ctx));
|
|
159
|
-
}
|
|
160
|
-
return outcomes;
|
|
161
|
-
}
|
|
162
|
-
async function evaluatePolicyDefinition(policy, ctx) {
|
|
163
|
-
const authority = policy.authority ? { ...policy.authority } : void 0;
|
|
164
|
-
const outcome = policy.kind === "data" ? await evaluateDataPolicy(policy, ctx) : policy.kind === "code" ? await evaluateCodePolicy(policy, ctx) : await evaluateHybridPolicy(policy, ctx);
|
|
165
|
-
if (!authority) return outcome;
|
|
166
|
-
return {
|
|
167
|
-
...outcome,
|
|
168
|
-
dispatchEvidence: {
|
|
169
|
-
...outcome.dispatchEvidence ?? {
|
|
170
|
-
policyKind: policy.kind,
|
|
171
|
-
policyId: policy.policyId,
|
|
172
|
-
policyVersion: policy.policyVersion,
|
|
173
|
-
dispatchPath: []
|
|
174
|
-
},
|
|
175
|
-
authority
|
|
176
|
-
}
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
async function evaluateCodePolicy(policy, ctx) {
|
|
180
|
-
const codeEvaluatorPolicyId = policy.codeEvaluatorPolicyId ?? policy.policyId;
|
|
181
|
-
const evaluator = ctx.resolveCodePolicy?.(codeEvaluatorPolicyId);
|
|
182
|
-
if (!evaluator) {
|
|
183
|
-
return {
|
|
184
|
-
policyId: policy.policyId,
|
|
185
|
-
policyVersion: policy.policyVersion,
|
|
186
|
-
policyKind: policy.kind,
|
|
187
|
-
result: "block",
|
|
188
|
-
reason: `No evaluator registered for policy ${codeEvaluatorPolicyId}`,
|
|
189
|
-
metadata: {
|
|
190
|
-
missingCodeEvaluatorPolicyId: codeEvaluatorPolicyId
|
|
191
|
-
},
|
|
192
|
-
dispatchEvidence: {
|
|
193
|
-
policyKind: policy.kind,
|
|
194
|
-
policyId: policy.policyId,
|
|
195
|
-
policyVersion: policy.policyVersion,
|
|
196
|
-
dispatchPath: ["code"],
|
|
197
|
-
code: {
|
|
198
|
-
requestedPolicyId: codeEvaluatorPolicyId,
|
|
199
|
-
policyId: codeEvaluatorPolicyId,
|
|
200
|
-
registered: false
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
if (ctx.mode === "preview" && evaluator.previewSafe !== true) {
|
|
206
|
-
const skipReason = `Policy ${evaluator.policyId} skipped in preview mode (evaluator is not declared previewSafe)`;
|
|
207
|
-
return {
|
|
208
|
-
policyId: policy.policyId,
|
|
209
|
-
policyVersion: policy.policyVersion,
|
|
210
|
-
policyKind: policy.kind,
|
|
211
|
-
result: "warn",
|
|
212
|
-
reason: skipReason,
|
|
213
|
-
metadata: {
|
|
214
|
-
codePolicyId: evaluator.policyId,
|
|
215
|
-
codePolicyVersion: evaluator.version,
|
|
216
|
-
previewSkipped: true
|
|
217
|
-
},
|
|
218
|
-
dispatchEvidence: {
|
|
219
|
-
policyKind: policy.kind,
|
|
220
|
-
policyId: policy.policyId,
|
|
221
|
-
policyVersion: policy.policyVersion,
|
|
222
|
-
dispatchPath: ["code"],
|
|
223
|
-
code: {
|
|
224
|
-
requestedPolicyId: codeEvaluatorPolicyId,
|
|
225
|
-
policyId: evaluator.policyId,
|
|
226
|
-
version: evaluator.version,
|
|
227
|
-
registered: true,
|
|
228
|
-
skipped: true,
|
|
229
|
-
skipReason
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
const outcome = await evaluator.evaluate(ctx);
|
|
235
|
-
return normalizeOutcome(policy, outcome, {
|
|
236
|
-
policyKind: policy.kind,
|
|
237
|
-
policyId: policy.policyId,
|
|
238
|
-
policyVersion: policy.policyVersion,
|
|
239
|
-
dispatchPath: ["code"],
|
|
240
|
-
code: {
|
|
241
|
-
requestedPolicyId: codeEvaluatorPolicyId,
|
|
242
|
-
policyId: evaluator.policyId,
|
|
243
|
-
version: evaluator.version,
|
|
244
|
-
registered: true
|
|
245
|
-
}
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
async function evaluateHybridPolicy(policy, ctx) {
|
|
249
|
-
const dataOutcome = evaluateDataPolicy(policy, ctx);
|
|
250
|
-
const fallback = policy.fallback;
|
|
251
|
-
const fallbackDecision = fallback ? resolveFallbackDecision(policy, dataOutcome, fallback) : { shouldFallback: false, trigger: "not_triggered" };
|
|
252
|
-
if (!fallback || !fallbackDecision.shouldFallback) {
|
|
253
|
-
if (fallback && dataOutcome.dispatchEvidence) {
|
|
254
|
-
return {
|
|
255
|
-
...dataOutcome,
|
|
256
|
-
dispatchEvidence: {
|
|
257
|
-
...dataOutcome.dispatchEvidence,
|
|
258
|
-
fallback: {
|
|
259
|
-
used: false,
|
|
260
|
-
trigger: "not_triggered",
|
|
261
|
-
reason: "Data policy result did not trigger fallback",
|
|
262
|
-
fromResult: dataOutcome.result,
|
|
263
|
-
definitionVersion: policy.policyVersion,
|
|
264
|
-
codeEvaluatorPolicyId: fallback.codeEvaluatorPolicyId
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
return dataOutcome;
|
|
270
|
-
}
|
|
271
|
-
const codePolicy = {
|
|
272
|
-
policyId: policy.policyId,
|
|
273
|
-
policyVersion: policy.policyVersion,
|
|
274
|
-
kind: "hybrid",
|
|
275
|
-
codeEvaluatorPolicyId: fallback.codeEvaluatorPolicyId
|
|
276
|
-
};
|
|
277
|
-
const codeOutcome = await evaluateCodePolicy(codePolicy, ctx);
|
|
278
|
-
return normalizeOutcome(policy, codeOutcome, {
|
|
279
|
-
...codeOutcome.dispatchEvidence ?? {
|
|
280
|
-
policyKind: "hybrid",
|
|
281
|
-
policyId: policy.policyId,
|
|
282
|
-
policyVersion: policy.policyVersion,
|
|
283
|
-
dispatchPath: ["code"]
|
|
284
|
-
},
|
|
285
|
-
policyKind: "hybrid",
|
|
286
|
-
policyId: policy.policyId,
|
|
287
|
-
policyVersion: policy.policyVersion,
|
|
288
|
-
dispatchPath: ["data", "fallback", "code"],
|
|
289
|
-
data: dataOutcome.dispatchEvidence?.data,
|
|
290
|
-
fallback: {
|
|
291
|
-
used: true,
|
|
292
|
-
trigger: fallbackDecision.trigger,
|
|
293
|
-
reason: fallback.reason ?? "Data policy result triggered code fallback",
|
|
294
|
-
fromResult: dataOutcome.result,
|
|
295
|
-
definitionVersion: policy.policyVersion,
|
|
296
|
-
codeEvaluatorPolicyId: fallback.codeEvaluatorPolicyId
|
|
297
|
-
}
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
function resolveFallbackDecision(policy, dataOutcome, fallback) {
|
|
301
|
-
const allowedTriggers = fallback.triggers ?? [
|
|
302
|
-
"data_result",
|
|
303
|
-
"missing_data_definition",
|
|
304
|
-
"invalid_data_definition"
|
|
305
|
-
];
|
|
306
|
-
const definitionStatus = dataOutcome.dispatchEvidence?.data?.definitionStatus;
|
|
307
|
-
if (definitionStatus === "missing") {
|
|
308
|
-
return {
|
|
309
|
-
shouldFallback: allowedTriggers.includes("missing_data_definition"),
|
|
310
|
-
trigger: "missing_data_definition"
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
if (definitionStatus === "invalid") {
|
|
314
|
-
return {
|
|
315
|
-
shouldFallback: allowedTriggers.includes("invalid_data_definition"),
|
|
316
|
-
trigger: "invalid_data_definition"
|
|
317
|
-
};
|
|
318
|
-
}
|
|
319
|
-
const fallbackResults = fallback.onResults ?? ["warn", "block"];
|
|
320
|
-
return {
|
|
321
|
-
shouldFallback: policy.kind === "hybrid" && allowedTriggers.includes("data_result") && fallbackResults.includes(dataOutcome.result),
|
|
322
|
-
trigger: "data_result"
|
|
323
|
-
};
|
|
324
|
-
}
|
|
325
|
-
function evaluateDataPolicy(policy, ctx) {
|
|
326
|
-
const definition = policy.dataDefinition;
|
|
327
|
-
if (!definition) {
|
|
328
|
-
return {
|
|
329
|
-
policyId: policy.policyId,
|
|
330
|
-
policyVersion: policy.policyVersion,
|
|
331
|
-
policyKind: policy.kind,
|
|
332
|
-
result: "block",
|
|
333
|
-
reason: "Data policy definition is missing",
|
|
334
|
-
dispatchEvidence: {
|
|
335
|
-
policyKind: policy.kind,
|
|
336
|
-
policyId: policy.policyId,
|
|
337
|
-
policyVersion: policy.policyVersion,
|
|
338
|
-
dispatchPath: ["data"],
|
|
339
|
-
data: {
|
|
340
|
-
definitionVersion: policy.policyVersion,
|
|
341
|
-
definitionStatus: "missing",
|
|
342
|
-
conditionResults: []
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
};
|
|
346
|
-
}
|
|
347
|
-
const validation = validateDataPolicyDefinition(definition);
|
|
348
|
-
if (!validation.valid) {
|
|
349
|
-
return {
|
|
350
|
-
policyId: policy.policyId,
|
|
351
|
-
policyVersion: policy.policyVersion,
|
|
352
|
-
policyKind: policy.kind,
|
|
353
|
-
result: "block",
|
|
354
|
-
reason: `Invalid data policy definition: ${validation.errors.join("; ")}`,
|
|
355
|
-
metadata: {
|
|
356
|
-
validationErrors: validation.errors
|
|
357
|
-
},
|
|
358
|
-
dispatchEvidence: {
|
|
359
|
-
policyKind: policy.kind,
|
|
360
|
-
policyId: policy.policyId,
|
|
361
|
-
policyVersion: policy.policyVersion,
|
|
362
|
-
dispatchPath: ["data"],
|
|
363
|
-
data: {
|
|
364
|
-
definitionVersion: policy.policyVersion,
|
|
365
|
-
definitionStatus: "invalid",
|
|
366
|
-
conditionResults: [],
|
|
367
|
-
validationErrors: validation.errors
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
};
|
|
371
|
-
}
|
|
372
|
-
const evaluations = definition.conditions.map((condition) => evaluateDataPolicyCondition(condition, ctx));
|
|
373
|
-
const conditionResults = evaluations.flatMap((evaluation) => evaluation.evidence);
|
|
374
|
-
const topLevelResults = evaluations.map((evaluation) => evaluation.result);
|
|
375
|
-
const aggregate = topLevelResults.find((result2) => result2.result === "block") ?? topLevelResults.find((result2) => result2.result === "warn");
|
|
376
|
-
const result = aggregate?.result ?? definition.defaultResult ?? "pass";
|
|
377
|
-
return {
|
|
378
|
-
policyId: policy.policyId,
|
|
379
|
-
policyVersion: policy.policyVersion,
|
|
380
|
-
policyKind: policy.kind,
|
|
381
|
-
result,
|
|
382
|
-
reason: aggregate?.reason ?? definition.reason,
|
|
383
|
-
metadata: {
|
|
384
|
-
conditionCount: definition.conditions.length,
|
|
385
|
-
failedConditionId: aggregate?.conditionId
|
|
386
|
-
},
|
|
387
|
-
dispatchEvidence: {
|
|
388
|
-
policyKind: policy.kind,
|
|
389
|
-
policyId: policy.policyId,
|
|
390
|
-
policyVersion: policy.policyVersion,
|
|
391
|
-
dispatchPath: ["data"],
|
|
392
|
-
data: {
|
|
393
|
-
definitionVersion: policy.policyVersion,
|
|
394
|
-
definitionStatus: "evaluated",
|
|
395
|
-
conditionResults
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
};
|
|
399
|
-
}
|
|
400
|
-
function validateDataPolicyDefinition(definition) {
|
|
401
|
-
const errors = [];
|
|
402
|
-
if (!Array.isArray(definition.conditions) || definition.conditions.length === 0) {
|
|
403
|
-
errors.push("conditions must contain at least one condition");
|
|
404
|
-
} else if (definition.conditions.length > DATA_POLICY_MAX_CONDITIONS_PER_NODE) {
|
|
405
|
-
errors.push(
|
|
406
|
-
`conditions must contain at most ${DATA_POLICY_MAX_CONDITIONS_PER_NODE} top-level conditions`
|
|
407
|
-
);
|
|
408
|
-
}
|
|
409
|
-
if (definition.defaultResult && !POLICY_RESULTS.includes(definition.defaultResult)) {
|
|
410
|
-
errors.push("defaultResult must be pass, warn, or block");
|
|
411
|
-
}
|
|
412
|
-
let totalConditions = 0;
|
|
413
|
-
for (const condition of definition.conditions ?? []) {
|
|
414
|
-
validateDataPolicyCondition(condition, errors, 1, () => {
|
|
415
|
-
totalConditions += 1;
|
|
416
|
-
});
|
|
417
|
-
}
|
|
418
|
-
if (totalConditions > DATA_POLICY_MAX_TOTAL_CONDITIONS) {
|
|
419
|
-
errors.push(`policy must contain at most ${DATA_POLICY_MAX_TOTAL_CONDITIONS} total conditions`);
|
|
420
|
-
}
|
|
421
|
-
return { valid: errors.length === 0, errors };
|
|
422
|
-
}
|
|
423
|
-
function validateDataPolicyCondition(condition, errors, depth, count) {
|
|
424
|
-
count();
|
|
425
|
-
if (!condition || typeof condition !== "object") {
|
|
426
|
-
errors.push("condition must be an object");
|
|
427
|
-
return;
|
|
428
|
-
}
|
|
429
|
-
if (depth > DATA_POLICY_MAX_DEPTH) {
|
|
430
|
-
errors.push(`condition depth must not exceed ${DATA_POLICY_MAX_DEPTH}`);
|
|
431
|
-
return;
|
|
432
|
-
}
|
|
433
|
-
if (!isNonEmptyBoundedString(condition.conditionId)) {
|
|
434
|
-
errors.push("conditionId must be a non-empty bounded string");
|
|
435
|
-
}
|
|
436
|
-
validateOptionalPolicyResult("onPass" in condition ? condition.onPass : void 0, "onPass", errors);
|
|
437
|
-
validateOptionalPolicyResult("onFail" in condition ? condition.onFail : void 0, "onFail", errors);
|
|
438
|
-
if (condition.reason !== void 0 && !isNonEmptyBoundedString(condition.reason)) {
|
|
439
|
-
errors.push(`condition ${condition.conditionId} reason must be a bounded string`);
|
|
440
|
-
}
|
|
441
|
-
if (condition.type === "always") {
|
|
442
|
-
if (!POLICY_RESULTS.includes(condition.result)) {
|
|
443
|
-
errors.push(`condition ${condition.conditionId} result must be pass, warn, or block`);
|
|
444
|
-
}
|
|
445
|
-
return;
|
|
446
|
-
}
|
|
447
|
-
if (condition.type === "parameter") {
|
|
448
|
-
validatePath(condition.path, `condition ${condition.conditionId} path`, errors);
|
|
449
|
-
validateComparison(condition.operator, condition.value, condition.conditionId, errors);
|
|
450
|
-
return;
|
|
451
|
-
}
|
|
452
|
-
if (condition.type === "comparison") {
|
|
453
|
-
validateSourceReference(condition.left, condition.conditionId, errors);
|
|
454
|
-
validateComparison(condition.operator, condition.value, condition.conditionId, errors);
|
|
455
|
-
return;
|
|
456
|
-
}
|
|
457
|
-
if (condition.type === "all" || condition.type === "any") {
|
|
458
|
-
if (!Array.isArray(condition.conditions) || condition.conditions.length === 0) {
|
|
459
|
-
errors.push(`condition ${condition.conditionId} must contain child conditions`);
|
|
460
|
-
return;
|
|
461
|
-
}
|
|
462
|
-
if (condition.conditions.length > DATA_POLICY_MAX_CONDITIONS_PER_NODE) {
|
|
463
|
-
errors.push(
|
|
464
|
-
`condition ${condition.conditionId} must contain at most ${DATA_POLICY_MAX_CONDITIONS_PER_NODE} child conditions`
|
|
465
|
-
);
|
|
466
|
-
}
|
|
467
|
-
for (const child of condition.conditions) {
|
|
468
|
-
validateDataPolicyCondition(child, errors, depth + 1, count);
|
|
469
|
-
}
|
|
470
|
-
return;
|
|
471
|
-
}
|
|
472
|
-
if (condition.type === "not") {
|
|
473
|
-
validateDataPolicyCondition(condition.condition, errors, depth + 1, count);
|
|
474
|
-
return;
|
|
475
|
-
}
|
|
476
|
-
errors.push(`condition ${condition.conditionId} has unsupported type`);
|
|
477
|
-
}
|
|
478
|
-
function validateOptionalPolicyResult(result, fieldName, errors) {
|
|
479
|
-
if (result !== void 0 && !POLICY_RESULTS.includes(result)) {
|
|
480
|
-
errors.push(`${fieldName} must be pass, warn, or block`);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
function validateSourceReference(reference, conditionId, errors) {
|
|
484
|
-
if (!reference || typeof reference !== "object") {
|
|
485
|
-
errors.push(`condition ${conditionId} left must be a source reference`);
|
|
486
|
-
return;
|
|
487
|
-
}
|
|
488
|
-
if (reference.source !== "parameters" && reference.source !== "context") {
|
|
489
|
-
errors.push(`condition ${conditionId} source must be parameters or context`);
|
|
490
|
-
}
|
|
491
|
-
validatePath(reference.path, `condition ${conditionId} left.path`, errors);
|
|
492
|
-
if (reference.source === "context" && !DATA_POLICY_CONTEXT_PATHS.includes(reference.path)) {
|
|
493
|
-
errors.push(`condition ${conditionId} uses an unsupported context path`);
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
function validateComparison(operator, value, conditionId, errors) {
|
|
497
|
-
if (!DATA_POLICY_COMPARISON_OPERATORS.includes(operator)) {
|
|
498
|
-
errors.push(`condition ${conditionId} has unsupported operator`);
|
|
499
|
-
return;
|
|
500
|
-
}
|
|
501
|
-
if (operator === "exists") {
|
|
502
|
-
return;
|
|
503
|
-
}
|
|
504
|
-
if (!isDataPolicyLiteral(value)) {
|
|
505
|
-
errors.push(`condition ${conditionId} comparison value must be a bounded literal`);
|
|
506
|
-
return;
|
|
507
|
-
}
|
|
508
|
-
if (["gt", "gte", "lt", "lte"].includes(operator) && typeof value !== "number") {
|
|
509
|
-
errors.push(`condition ${conditionId} numeric comparison requires a number value`);
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
function validatePath(path, fieldName, errors) {
|
|
513
|
-
if (!isNonEmptyBoundedString(path)) {
|
|
514
|
-
errors.push(`${fieldName} must be a non-empty bounded string`);
|
|
515
|
-
return;
|
|
516
|
-
}
|
|
517
|
-
const segments = path.split(".");
|
|
518
|
-
if (segments.length > DATA_POLICY_MAX_PATH_SEGMENTS) {
|
|
519
|
-
errors.push(`${fieldName} must contain at most ${DATA_POLICY_MAX_PATH_SEGMENTS} segments`);
|
|
520
|
-
return;
|
|
521
|
-
}
|
|
522
|
-
for (const segment of segments) {
|
|
523
|
-
if (!/^[A-Za-z][A-Za-z0-9_-]*$/.test(segment)) {
|
|
524
|
-
errors.push(`${fieldName} contains an invalid path segment`);
|
|
525
|
-
return;
|
|
526
|
-
}
|
|
527
|
-
if (["__proto__", "constructor", "prototype"].includes(segment)) {
|
|
528
|
-
errors.push(`${fieldName} contains a forbidden path segment`);
|
|
529
|
-
return;
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
function isDataPolicyLiteral(value) {
|
|
534
|
-
if (value === null || typeof value === "number" || typeof value === "boolean") {
|
|
535
|
-
return true;
|
|
536
|
-
}
|
|
537
|
-
return typeof value === "string" && value.length <= DATA_POLICY_MAX_STRING_LENGTH;
|
|
538
|
-
}
|
|
539
|
-
function isNonEmptyBoundedString(value) {
|
|
540
|
-
return typeof value === "string" && value.length > 0 && value.length <= DATA_POLICY_MAX_STRING_LENGTH;
|
|
541
|
-
}
|
|
542
|
-
function evaluateDataPolicyCondition(condition, ctx) {
|
|
543
|
-
if (condition.type === "always") {
|
|
544
|
-
const result2 = {
|
|
545
|
-
conditionId: condition.conditionId,
|
|
546
|
-
passed: condition.result === "pass",
|
|
547
|
-
result: condition.result,
|
|
548
|
-
reason: condition.reason
|
|
549
|
-
};
|
|
550
|
-
return { result: result2, evidence: [result2] };
|
|
551
|
-
}
|
|
552
|
-
if (condition.type === "all" || condition.type === "any") {
|
|
553
|
-
const childEvaluations = condition.conditions.map((child) => evaluateDataPolicyCondition(child, ctx));
|
|
554
|
-
const passed2 = condition.type === "all" ? childEvaluations.every((evaluation) => evaluation.result.passed) : childEvaluations.some((evaluation) => evaluation.result.passed);
|
|
555
|
-
const result2 = {
|
|
556
|
-
conditionId: condition.conditionId,
|
|
557
|
-
passed: passed2,
|
|
558
|
-
result: passed2 ? condition.onPass ?? "pass" : condition.onFail ?? "block",
|
|
559
|
-
reason: passed2 ? void 0 : condition.reason
|
|
560
|
-
};
|
|
561
|
-
return {
|
|
562
|
-
result: result2,
|
|
563
|
-
evidence: [result2, ...childEvaluations.flatMap((evaluation) => evaluation.evidence)]
|
|
564
|
-
};
|
|
565
|
-
}
|
|
566
|
-
if (condition.type === "not") {
|
|
567
|
-
const childEvaluation = evaluateDataPolicyCondition(condition.condition, ctx);
|
|
568
|
-
const passed2 = !childEvaluation.result.passed;
|
|
569
|
-
const result2 = {
|
|
570
|
-
conditionId: condition.conditionId,
|
|
571
|
-
passed: passed2,
|
|
572
|
-
result: passed2 ? condition.onPass ?? "pass" : condition.onFail ?? "block",
|
|
573
|
-
reason: passed2 ? void 0 : condition.reason
|
|
574
|
-
};
|
|
575
|
-
return { result: result2, evidence: [result2, ...childEvaluation.evidence] };
|
|
576
|
-
}
|
|
577
|
-
if (condition.type !== "parameter" && condition.type !== "comparison") {
|
|
578
|
-
const result2 = {
|
|
579
|
-
conditionId: condition.conditionId,
|
|
580
|
-
passed: false,
|
|
581
|
-
result: "block",
|
|
582
|
-
reason: "Unsupported data policy condition type"
|
|
583
|
-
};
|
|
584
|
-
return { result: result2, evidence: [result2] };
|
|
585
|
-
}
|
|
586
|
-
const value = condition.type === "parameter" ? readPath(ctx.parameters, condition.path) : readDataPolicySource(ctx, condition.left);
|
|
587
|
-
const operator = condition.operator;
|
|
588
|
-
const expected = condition.value;
|
|
589
|
-
const passed = evaluateOperator(value, operator, expected);
|
|
590
|
-
const result = {
|
|
591
|
-
conditionId: condition.conditionId,
|
|
592
|
-
passed,
|
|
593
|
-
result: passed ? condition.onPass ?? "pass" : condition.onFail ?? "block",
|
|
594
|
-
reason: passed ? void 0 : condition.reason
|
|
595
|
-
};
|
|
596
|
-
return { result, evidence: [result] };
|
|
597
|
-
}
|
|
598
|
-
function evaluateOperator(actual, operator, expected) {
|
|
599
|
-
switch (operator) {
|
|
600
|
-
case "exists":
|
|
601
|
-
return actual !== void 0 && actual !== null && actual !== "";
|
|
602
|
-
case "equals":
|
|
603
|
-
return actual === expected;
|
|
604
|
-
case "notEquals":
|
|
605
|
-
return actual !== expected;
|
|
606
|
-
case "gt":
|
|
607
|
-
return typeof actual === "number" && typeof expected === "number" && actual > expected;
|
|
608
|
-
case "gte":
|
|
609
|
-
return typeof actual === "number" && typeof expected === "number" && actual >= expected;
|
|
610
|
-
case "lt":
|
|
611
|
-
return typeof actual === "number" && typeof expected === "number" && actual < expected;
|
|
612
|
-
case "lte":
|
|
613
|
-
return typeof actual === "number" && typeof expected === "number" && actual <= expected;
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
function readDataPolicySource(ctx, reference) {
|
|
617
|
-
if (reference.source === "parameters") {
|
|
618
|
-
return readPath(ctx.parameters, reference.path);
|
|
619
|
-
}
|
|
620
|
-
return readPath(
|
|
621
|
-
{
|
|
622
|
-
tenantId: ctx.tenantId,
|
|
623
|
-
spaceId: ctx.spaceId,
|
|
624
|
-
actionInvocationId: ctx.actionInvocationId,
|
|
625
|
-
actionId: ctx.actionId,
|
|
626
|
-
mode: ctx.mode
|
|
627
|
-
},
|
|
628
|
-
reference.path
|
|
629
|
-
);
|
|
630
|
-
}
|
|
631
|
-
function readPath(source, path) {
|
|
632
|
-
if (!source || typeof source !== "object") {
|
|
633
|
-
return void 0;
|
|
634
|
-
}
|
|
635
|
-
return path.split(".").reduce((current, segment) => {
|
|
636
|
-
if (!current || typeof current !== "object") {
|
|
637
|
-
return void 0;
|
|
638
|
-
}
|
|
639
|
-
return current[segment];
|
|
640
|
-
}, source);
|
|
641
|
-
}
|
|
642
|
-
function normalizeOutcome(policy, outcome, dispatchEvidence) {
|
|
643
|
-
if (outcome.guidance !== void 0) {
|
|
644
|
-
const guidanceValidation = validatePolicyGuidance(outcome.guidance);
|
|
645
|
-
if (!guidanceValidation.valid) {
|
|
646
|
-
throw new Error(
|
|
647
|
-
`Invalid guidance for policy ${outcome.policyId}: ${guidanceValidation.errors.join("; ")}`
|
|
648
|
-
);
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
const engine = outcome.dispatchEvidence?.engine;
|
|
652
|
-
return {
|
|
653
|
-
...outcome,
|
|
654
|
-
policyId: policy.policyId,
|
|
655
|
-
policyVersion: policy.policyVersion,
|
|
656
|
-
policyKind: policy.kind,
|
|
657
|
-
metadata: {
|
|
658
|
-
...outcome.metadata ?? {},
|
|
659
|
-
codePolicyId: dispatchEvidence.code?.policyId ?? outcome.policyId,
|
|
660
|
-
codePolicyVersion: dispatchEvidence.code?.version ?? outcome.policyVersion
|
|
661
|
-
},
|
|
662
|
-
dispatchEvidence: engine ? { ...dispatchEvidence, engine } : dispatchEvidence
|
|
663
|
-
};
|
|
664
|
-
}
|
|
665
|
-
function parsePolicyVersion(policyId) {
|
|
666
|
-
const segments = policyId.split(".v");
|
|
667
|
-
return Number(segments[segments.length - 1] ?? 1);
|
|
668
|
-
}
|
|
669
|
-
function aggregatePolicyOutcomes(outcomes) {
|
|
670
|
-
return outcomes.find((outcome) => outcome.result === "block") ?? outcomes.find((outcome) => outcome.result === "warn");
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
exports.RetryableExecutionError = RetryableExecutionError;
|
|
674
|
-
exports.aggregatePolicyOutcomes = aggregatePolicyOutcomes;
|
|
675
|
-
exports.assertPolicyId = assertPolicyId;
|
|
676
|
-
exports.createPolicyRegistry = createPolicyRegistry;
|
|
677
|
-
exports.evaluatePolicyDefinition = evaluatePolicyDefinition;
|
|
678
|
-
exports.evaluatePolicyDefinitions = evaluatePolicyDefinitions;
|
|
679
|
-
exports.evaluateRegisteredPolicies = evaluateRegisteredPolicies;
|
|
680
|
-
exports.isRetryableExecutionError = isRetryableExecutionError;
|
|
681
|
-
exports.validateDataPolicyDefinition = validateDataPolicyDefinition;
|
|
682
|
-
exports.validatePolicyGuidance = validatePolicyGuidance;
|
|
683
|
-
//# sourceMappingURL=chunk-YGIPN3TU.cjs.map
|
|
684
|
-
//# sourceMappingURL=chunk-YGIPN3TU.cjs.map
|