@guardian-network/policy-variables 0.3.2
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/README.md +73 -0
- package/dist/VariablesPopulator.d.ts +18 -0
- package/dist/VariablesPopulator.d.ts.map +1 -0
- package/dist/VariablesPopulator.js +64 -0
- package/dist/VariablesPopulator.js.map +1 -0
- package/dist/errors/ErrorFactory.d.ts +11 -0
- package/dist/errors/ErrorFactory.d.ts.map +1 -0
- package/dist/errors/ErrorFactory.js +29 -0
- package/dist/errors/ErrorFactory.js.map +1 -0
- package/dist/errors/index.d.ts +2 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +18 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/errors/validation-errors.d.ts +26 -0
- package/dist/errors/validation-errors.d.ts.map +1 -0
- package/dist/errors/validation-errors.js +61 -0
- package/dist/errors/validation-errors.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/injection/StaticInjector.d.ts +5 -0
- package/dist/injection/StaticInjector.d.ts.map +1 -0
- package/dist/injection/StaticInjector.js +29 -0
- package/dist/injection/StaticInjector.js.map +1 -0
- package/dist/injection/index.d.ts +2 -0
- package/dist/injection/index.d.ts.map +1 -0
- package/dist/injection/index.js +6 -0
- package/dist/injection/index.js.map +1 -0
- package/dist/insertion/Inserter.d.ts +14 -0
- package/dist/insertion/Inserter.d.ts.map +1 -0
- package/dist/insertion/Inserter.js +72 -0
- package/dist/insertion/Inserter.js.map +1 -0
- package/dist/insertion/index.d.ts +2 -0
- package/dist/insertion/index.d.ts.map +1 -0
- package/dist/insertion/index.js +6 -0
- package/dist/insertion/index.js.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +19 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/interfaces.d.ts +5 -0
- package/dist/types/interfaces.d.ts.map +1 -0
- package/dist/types/interfaces.js +3 -0
- package/dist/types/interfaces.js.map +1 -0
- package/dist/types/types.d.ts +42 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/types.js +3 -0
- package/dist/types/types.js.map +1 -0
- package/dist/utils/format-variables.helper.d.ts +4 -0
- package/dist/utils/format-variables.helper.d.ts.map +1 -0
- package/dist/utils/format-variables.helper.js +54 -0
- package/dist/utils/format-variables.helper.js.map +1 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +19 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/validations.helper.d.ts +4 -0
- package/dist/utils/validations.helper.d.ts.map +1 -0
- package/dist/utils/validations.helper.js +70 -0
- package/dist/utils/validations.helper.js.map +1 -0
- package/package.json +70 -0
- package/src/VariablesPopulator.ts +120 -0
- package/src/errors/ErrorFactory.ts +53 -0
- package/src/errors/index.ts +1 -0
- package/src/errors/validation-errors.ts +57 -0
- package/src/index.ts +7 -0
- package/src/injection/StaticInjector.ts +57 -0
- package/src/injection/index.ts +1 -0
- package/src/insertion/Inserter.ts +127 -0
- package/src/insertion/index.ts +1 -0
- package/src/types/index.ts +2 -0
- package/src/types/interfaces.ts +6 -0
- package/src/types/types.ts +66 -0
- package/src/utils/format-variables.helper.ts +83 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/validations.helper.ts +116 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { ErrorFactory } from '../errors';
|
|
2
|
+
import {
|
|
3
|
+
AllowedVariablesType,
|
|
4
|
+
IAsyncMapGetter,
|
|
5
|
+
NodeId,
|
|
6
|
+
NodeVariablesConfig,
|
|
7
|
+
SuppliedVariables,
|
|
8
|
+
VarIndex,
|
|
9
|
+
VarName,
|
|
10
|
+
VarValue,
|
|
11
|
+
} from '../types';
|
|
12
|
+
|
|
13
|
+
// note: insert variable value
|
|
14
|
+
export class Inserter implements IAsyncMapGetter<AllowedVariablesType> {
|
|
15
|
+
// static fromDump = (
|
|
16
|
+
// varsConfig: NodeVariablesConfig[],
|
|
17
|
+
// dump: SuppliedVariables[],
|
|
18
|
+
// ): Inserter => {
|
|
19
|
+
// const inserter = new Inserter(varsConfig);
|
|
20
|
+
// inserter.import(dump);
|
|
21
|
+
// return inserter;
|
|
22
|
+
// };
|
|
23
|
+
|
|
24
|
+
// the node-with-no-variables list
|
|
25
|
+
private spareNodesConfig: NodeVariablesConfig[] = [];
|
|
26
|
+
|
|
27
|
+
// variable-unique-name => its-node-id
|
|
28
|
+
private varNameToNodeId: Map<VarName, NodeId> = new Map();
|
|
29
|
+
|
|
30
|
+
// variable-unique-name => its-index-in-node-vars-list (as defined in "this.nodeToVars")
|
|
31
|
+
private varNameToVarIndex: Map<VarName, VarIndex> = new Map();
|
|
32
|
+
|
|
33
|
+
// node-id => its-known-variables; known = filled
|
|
34
|
+
private nodeToVars: Map<NodeId, Array<VarValue>> = new Map();
|
|
35
|
+
|
|
36
|
+
constructor(
|
|
37
|
+
varsConfig /* expectedVarsConfig */ : NodeVariablesConfig[], // nodes-variables-config list
|
|
38
|
+
) {
|
|
39
|
+
this.initialize(varsConfig);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private initialize = (varsConfig: NodeVariablesConfig[]) => {
|
|
43
|
+
for (const nodeVars of varsConfig) {
|
|
44
|
+
this.nodeToVars.set(nodeVars.nodeId, []);
|
|
45
|
+
|
|
46
|
+
// if (varsByNode.variables) { // note: legacy code has and ERROR at this point
|
|
47
|
+
|
|
48
|
+
if (nodeVars.variables.length === 0) {
|
|
49
|
+
this.spareNodesConfig.push(nodeVars);
|
|
50
|
+
} else {
|
|
51
|
+
for (const { index, uniqueName } of nodeVars.variables) {
|
|
52
|
+
this.varNameToNodeId.set(uniqueName, nodeVars.nodeId);
|
|
53
|
+
this.varNameToVarIndex.set(uniqueName, index);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
insert = (varName: string, varValue: AllowedVariablesType) => {
|
|
60
|
+
const targetNodeId = this.varNameToNodeId.get(varName);
|
|
61
|
+
// won't reach if calling from Populator - getVarDescription will catch earlier
|
|
62
|
+
if (!targetNodeId) throw ErrorFactory.variableNodeNotFound(varName);
|
|
63
|
+
|
|
64
|
+
const nodeVariables = this.nodeToVars.get(targetNodeId);
|
|
65
|
+
// must have been caught in "initialized" previously
|
|
66
|
+
if (!nodeVariables)
|
|
67
|
+
throw ErrorFactory.nodeVariablesAreUndefined(targetNodeId);
|
|
68
|
+
|
|
69
|
+
nodeVariables.push({
|
|
70
|
+
// todo: safer approach
|
|
71
|
+
index: this.varNameToVarIndex.get(varName)!,
|
|
72
|
+
value: varValue,
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
get = (varName: string): AllowedVariablesType | undefined => {
|
|
77
|
+
const nodeId = this.varNameToNodeId.get(varName)!;
|
|
78
|
+
|
|
79
|
+
const result = this.nodeToVars
|
|
80
|
+
// todo: safer approach
|
|
81
|
+
.get(nodeId)!
|
|
82
|
+
.find((el) => el.index == this.varNameToVarIndex.get(varName))?.value;
|
|
83
|
+
|
|
84
|
+
return result;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
import = (dump: Array<SuppliedVariables>) => {
|
|
88
|
+
for (const { nodeId, values } of dump) {
|
|
89
|
+
this.nodeToVars.set(
|
|
90
|
+
nodeId,
|
|
91
|
+
values.map((value, index) => ({ index, value })),
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
get filledVars(): SuppliedVariables[] {
|
|
97
|
+
const suppliedVars: SuppliedVariables[] = [];
|
|
98
|
+
|
|
99
|
+
for (let [targetNodeId, nodeVars] of this.nodeToVars) {
|
|
100
|
+
let filledVariable: SuppliedVariables = {} as SuppliedVariables;
|
|
101
|
+
|
|
102
|
+
const variableValuesTmp = new Array<AllowedVariablesType>(
|
|
103
|
+
nodeVars.length,
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
for (let { index, value } of nodeVars) {
|
|
107
|
+
// important: preserve index??; otherwise use nodeVars.map
|
|
108
|
+
variableValuesTmp[index] = value;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
filledVariable.values = variableValuesTmp;
|
|
112
|
+
filledVariable.nodeId = targetNodeId;
|
|
113
|
+
suppliedVars.push(filledVariable);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const emptyVars: SuppliedVariables[] = this.spareNodesConfig.map(
|
|
117
|
+
({ nodeId }) => ({
|
|
118
|
+
nodeId,
|
|
119
|
+
values: [],
|
|
120
|
+
}),
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
// note: also push nodes without variables so they are processed anyways
|
|
124
|
+
const result = [...suppliedVars, ...emptyVars];
|
|
125
|
+
return result;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Inserter } from './Inserter';
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OnchainVariablesDescription,
|
|
3
|
+
PrimitiveEncodeParamTypes,
|
|
4
|
+
} from '@guardian-network/shared';
|
|
5
|
+
|
|
6
|
+
/* type OnchainVariablesDescription = {
|
|
7
|
+
nodeId: string;
|
|
8
|
+
nodeIndex: bigint;
|
|
9
|
+
artifactAddress: string;
|
|
10
|
+
variables: ArgumentStructOutput[];
|
|
11
|
+
injections: StringAndIndexStructOutput[];
|
|
12
|
+
}; */
|
|
13
|
+
|
|
14
|
+
export type AllowedVariablesType = PrimitiveEncodeParamTypes; // string | number | boolean;
|
|
15
|
+
|
|
16
|
+
// note: this reflects in some way a bit reshaped entry of 'NodeVariablesDescription' type
|
|
17
|
+
export type VarDescription = {
|
|
18
|
+
name: string; // according to "Artifact.getExecDescriptor" definition, or dsl definition
|
|
19
|
+
type: string; // according to "Artifact.getExecDescriptor" definition, or dsl definition
|
|
20
|
+
uniqueName: string; // this contain unique variable name in comparison to other variables in the same node or in the other nodes
|
|
21
|
+
index: number; // position is node vars list
|
|
22
|
+
injection?: string; // unique injection-id if variable injects
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type VarValue = {
|
|
26
|
+
index: number;
|
|
27
|
+
value: AllowedVariablesType;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export type SuppliedVariables = {
|
|
31
|
+
nodeId: NodeId;
|
|
32
|
+
values: AllowedVariablesType[];
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export type Variable = {
|
|
36
|
+
typename: string;
|
|
37
|
+
name: string;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
type Injection = {
|
|
41
|
+
value: string;
|
|
42
|
+
index: number;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export type TypedRawOnchainVariablesDescription = {
|
|
46
|
+
nodeId: NodeId;
|
|
47
|
+
nodeIndex: number; // parent node
|
|
48
|
+
artifactAddress: string;
|
|
49
|
+
descriptions: Array<Variable>;
|
|
50
|
+
injections: Array<Injection>;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export type NodeVariablesDescription =
|
|
54
|
+
| OnchainVariablesDescription
|
|
55
|
+
| TypedRawOnchainVariablesDescription;
|
|
56
|
+
|
|
57
|
+
// note: this reflects in some way a bit reshaped value of 'NodeVariablesDescription' type
|
|
58
|
+
// see also, 'VarDescription' definition
|
|
59
|
+
export type NodeVariablesConfig = {
|
|
60
|
+
nodeId: NodeId;
|
|
61
|
+
variables: VarDescription[];
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export type VarName = string;
|
|
65
|
+
export type VarIndex = number;
|
|
66
|
+
export type NodeId = string;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { ErrorFactory } from '../errors';
|
|
2
|
+
import {
|
|
3
|
+
NodeVariablesConfig,
|
|
4
|
+
NodeVariablesDescription,
|
|
5
|
+
TypedRawOnchainVariablesDescription,
|
|
6
|
+
Variable,
|
|
7
|
+
} from '../types';
|
|
8
|
+
|
|
9
|
+
export const translateVarsDescriptionToConfig = (
|
|
10
|
+
nodesVarsList: NodeVariablesDescription[],
|
|
11
|
+
): NodeVariablesConfig[] => {
|
|
12
|
+
const nodesVarsConfig: NodeVariablesConfig[] = [];
|
|
13
|
+
|
|
14
|
+
for (let nodeVars of nodesVarsList.map(
|
|
15
|
+
rawOnchainVariablesDescriptionToOffchainView,
|
|
16
|
+
)) {
|
|
17
|
+
nodesVarsConfig.push({
|
|
18
|
+
nodeId: nodeVars.nodeId,
|
|
19
|
+
variables: [],
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// note: add all variable data excluding injections
|
|
23
|
+
for (const [index, variable] of nodeVars.descriptions.entries()) {
|
|
24
|
+
const variableConfig = {
|
|
25
|
+
name: variable.name,
|
|
26
|
+
type: variable.typename,
|
|
27
|
+
uniqueName: buildUniqueVariablesName(variable, nodeVars),
|
|
28
|
+
index,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
nodesVarsConfig[nodesVarsConfig.length - 1].variables.push(
|
|
32
|
+
variableConfig,
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// note: add injections
|
|
37
|
+
for (const injection of nodeVars.injections) {
|
|
38
|
+
const injectableVar = nodesVarsConfig[
|
|
39
|
+
nodesVarsConfig.length - 1
|
|
40
|
+
].variables.find((el) => el.index == Number(injection.index));
|
|
41
|
+
|
|
42
|
+
if (!!injectableVar) {
|
|
43
|
+
injectableVar.injection = injection.value;
|
|
44
|
+
} else
|
|
45
|
+
throw ErrorFactory.injectionFormatting(
|
|
46
|
+
injection.value,
|
|
47
|
+
injection.index,
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return [...nodesVarsConfig];
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const rawOnchainVariablesDescriptionToOffchainView = (
|
|
56
|
+
nodeVars: NodeVariablesDescription,
|
|
57
|
+
): TypedRawOnchainVariablesDescription => {
|
|
58
|
+
const { nodeId, descriptions, injections, artifactAddress, nodeIndex } =
|
|
59
|
+
nodeVars;
|
|
60
|
+
|
|
61
|
+
const result = {
|
|
62
|
+
nodeId,
|
|
63
|
+
nodeIndex: Number(nodeIndex),
|
|
64
|
+
artifactAddress,
|
|
65
|
+
descriptions: descriptions.map(({ typename, name }) => ({
|
|
66
|
+
typename,
|
|
67
|
+
name,
|
|
68
|
+
})),
|
|
69
|
+
injections: injections.map(({ value, index }) => ({
|
|
70
|
+
value,
|
|
71
|
+
index: Number(index),
|
|
72
|
+
})),
|
|
73
|
+
};
|
|
74
|
+
return result;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// note: this is a DEFINABLE method in what it outputs; double-check before applying adjustment
|
|
78
|
+
const buildUniqueVariablesName = (
|
|
79
|
+
variable: Variable,
|
|
80
|
+
varDescription: NodeVariablesDescription,
|
|
81
|
+
) => {
|
|
82
|
+
return `${variable.name}_${variable.typename}_${varDescription.artifactAddress}_${varDescription.nodeIndex}`;
|
|
83
|
+
};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
+
import {
|
|
3
|
+
SupportedSolidityType,
|
|
4
|
+
verifyAddress,
|
|
5
|
+
verifyBytes,
|
|
6
|
+
} from '@guardian-network/shared';
|
|
7
|
+
import { ErrorFactory } from '../errors';
|
|
8
|
+
import {
|
|
9
|
+
AllowedVariablesType,
|
|
10
|
+
NodeVariablesConfig,
|
|
11
|
+
SuppliedVariables,
|
|
12
|
+
VarDescription,
|
|
13
|
+
} from '../types';
|
|
14
|
+
|
|
15
|
+
export const validateVarValueTypeWithErr = (
|
|
16
|
+
varValue: AllowedVariablesType,
|
|
17
|
+
expectedTypeAsString: string,
|
|
18
|
+
) => {
|
|
19
|
+
const isValid = validateVarValueType(varValue, expectedTypeAsString);
|
|
20
|
+
|
|
21
|
+
if (!isValid) {
|
|
22
|
+
throw ErrorFactory.variableTypeNotMet(
|
|
23
|
+
varValue.toString(),
|
|
24
|
+
expectedTypeAsString,
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// note: this validates that value complies with required solidity type
|
|
30
|
+
const validateVarValueType = (
|
|
31
|
+
varValue: AllowedVariablesType,
|
|
32
|
+
expectedTypeString: string,
|
|
33
|
+
// todo: expectedTypeString: SupportedSolidityType
|
|
34
|
+
): boolean => {
|
|
35
|
+
let verified = false;
|
|
36
|
+
// todo: apply safer approach instead assertion, since this gives no safe at this point
|
|
37
|
+
const vatiableSolidityType = expectedTypeString as SupportedSolidityType;
|
|
38
|
+
|
|
39
|
+
switch (vatiableSolidityType) {
|
|
40
|
+
// todo: case SupportedSolidityTypesEnum.String
|
|
41
|
+
case 'string':
|
|
42
|
+
verified ||= typeof varValue == 'string';
|
|
43
|
+
break;
|
|
44
|
+
case 'uint256':
|
|
45
|
+
verified ||= typeof varValue == 'number';
|
|
46
|
+
break;
|
|
47
|
+
case 'bool':
|
|
48
|
+
verified ||= typeof varValue == 'boolean';
|
|
49
|
+
break;
|
|
50
|
+
case 'address':
|
|
51
|
+
try {
|
|
52
|
+
verifyAddress(varValue as any as string);
|
|
53
|
+
verified = true;
|
|
54
|
+
} catch (_: unknown) {
|
|
55
|
+
verified = false;
|
|
56
|
+
}
|
|
57
|
+
break;
|
|
58
|
+
case 'bytes':
|
|
59
|
+
try {
|
|
60
|
+
verifyBytes(varValue as any as string);
|
|
61
|
+
verified = true;
|
|
62
|
+
} catch (_: unknown) {
|
|
63
|
+
verified = false;
|
|
64
|
+
}
|
|
65
|
+
break;
|
|
66
|
+
// note: handles when unknown (Solidty) type provided
|
|
67
|
+
default:
|
|
68
|
+
// should not reach there, since previous validations step in faster
|
|
69
|
+
throw ErrorFactory.providedVariableWithNotKnownType(
|
|
70
|
+
varValue.toString(),
|
|
71
|
+
vatiableSolidityType,
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return verified;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const defaultExtraCondition = (_: VarDescription) => false;
|
|
79
|
+
|
|
80
|
+
export const validateAllVariablesSupplied = (
|
|
81
|
+
varsConfig: NodeVariablesConfig[],
|
|
82
|
+
knownVariables: SuppliedVariables[],
|
|
83
|
+
// note: usually has to be "isInjection" func; when not, then instead default blank method consumed
|
|
84
|
+
isVariableInjectable: (
|
|
85
|
+
varDescription: VarDescription,
|
|
86
|
+
) => boolean = defaultExtraCondition,
|
|
87
|
+
) => {
|
|
88
|
+
for (let i = 0; i < varsConfig.length; i++) {
|
|
89
|
+
const suppliedVars = knownVariables[i];
|
|
90
|
+
const expectedVarsConfig = varsConfig[i];
|
|
91
|
+
|
|
92
|
+
for (let j = 0; j < expectedVarsConfig.variables.length; j++) {
|
|
93
|
+
const variable = expectedVarsConfig.variables[j];
|
|
94
|
+
|
|
95
|
+
// "defaultExtraCondition" gives "false" value, which treats each variable as NOT-AN-INJECTION
|
|
96
|
+
const isInjection = isVariableInjectable(variable);
|
|
97
|
+
const isVariableSupplied = suppliedVars.values[j] !== undefined;
|
|
98
|
+
|
|
99
|
+
// note: throw when not supplied and not injection
|
|
100
|
+
if (!isVariableSupplied && !isInjection) {
|
|
101
|
+
throw ErrorFactory.variableNotFilled(
|
|
102
|
+
variable.uniqueName,
|
|
103
|
+
variable.injection,
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// note: this is intentional double validation of value type against the expected type
|
|
108
|
+
// the initial validation is done in VariablesPopulator.insert, or VariablesPopulator.inject
|
|
109
|
+
if (isVariableSupplied) {
|
|
110
|
+
const value = suppliedVars.values[j];
|
|
111
|
+
const expectedType = variable.type;
|
|
112
|
+
validateVarValueTypeWithErr(value, expectedType);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
};
|