@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.
Files changed (77) hide show
  1. package/README.md +73 -0
  2. package/dist/VariablesPopulator.d.ts +18 -0
  3. package/dist/VariablesPopulator.d.ts.map +1 -0
  4. package/dist/VariablesPopulator.js +64 -0
  5. package/dist/VariablesPopulator.js.map +1 -0
  6. package/dist/errors/ErrorFactory.d.ts +11 -0
  7. package/dist/errors/ErrorFactory.d.ts.map +1 -0
  8. package/dist/errors/ErrorFactory.js +29 -0
  9. package/dist/errors/ErrorFactory.js.map +1 -0
  10. package/dist/errors/index.d.ts +2 -0
  11. package/dist/errors/index.d.ts.map +1 -0
  12. package/dist/errors/index.js +18 -0
  13. package/dist/errors/index.js.map +1 -0
  14. package/dist/errors/validation-errors.d.ts +26 -0
  15. package/dist/errors/validation-errors.d.ts.map +1 -0
  16. package/dist/errors/validation-errors.js +61 -0
  17. package/dist/errors/validation-errors.js.map +1 -0
  18. package/dist/index.d.ts +4 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +8 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/injection/StaticInjector.d.ts +5 -0
  23. package/dist/injection/StaticInjector.d.ts.map +1 -0
  24. package/dist/injection/StaticInjector.js +29 -0
  25. package/dist/injection/StaticInjector.js.map +1 -0
  26. package/dist/injection/index.d.ts +2 -0
  27. package/dist/injection/index.d.ts.map +1 -0
  28. package/dist/injection/index.js +6 -0
  29. package/dist/injection/index.js.map +1 -0
  30. package/dist/insertion/Inserter.d.ts +14 -0
  31. package/dist/insertion/Inserter.d.ts.map +1 -0
  32. package/dist/insertion/Inserter.js +72 -0
  33. package/dist/insertion/Inserter.js.map +1 -0
  34. package/dist/insertion/index.d.ts +2 -0
  35. package/dist/insertion/index.d.ts.map +1 -0
  36. package/dist/insertion/index.js +6 -0
  37. package/dist/insertion/index.js.map +1 -0
  38. package/dist/types/index.d.ts +3 -0
  39. package/dist/types/index.d.ts.map +1 -0
  40. package/dist/types/index.js +19 -0
  41. package/dist/types/index.js.map +1 -0
  42. package/dist/types/interfaces.d.ts +5 -0
  43. package/dist/types/interfaces.d.ts.map +1 -0
  44. package/dist/types/interfaces.js +3 -0
  45. package/dist/types/interfaces.js.map +1 -0
  46. package/dist/types/types.d.ts +42 -0
  47. package/dist/types/types.d.ts.map +1 -0
  48. package/dist/types/types.js +3 -0
  49. package/dist/types/types.js.map +1 -0
  50. package/dist/utils/format-variables.helper.d.ts +4 -0
  51. package/dist/utils/format-variables.helper.d.ts.map +1 -0
  52. package/dist/utils/format-variables.helper.js +54 -0
  53. package/dist/utils/format-variables.helper.js.map +1 -0
  54. package/dist/utils/index.d.ts +3 -0
  55. package/dist/utils/index.d.ts.map +1 -0
  56. package/dist/utils/index.js +19 -0
  57. package/dist/utils/index.js.map +1 -0
  58. package/dist/utils/validations.helper.d.ts +4 -0
  59. package/dist/utils/validations.helper.d.ts.map +1 -0
  60. package/dist/utils/validations.helper.js +70 -0
  61. package/dist/utils/validations.helper.js.map +1 -0
  62. package/package.json +70 -0
  63. package/src/VariablesPopulator.ts +120 -0
  64. package/src/errors/ErrorFactory.ts +53 -0
  65. package/src/errors/index.ts +1 -0
  66. package/src/errors/validation-errors.ts +57 -0
  67. package/src/index.ts +7 -0
  68. package/src/injection/StaticInjector.ts +57 -0
  69. package/src/injection/index.ts +1 -0
  70. package/src/insertion/Inserter.ts +127 -0
  71. package/src/insertion/index.ts +1 -0
  72. package/src/types/index.ts +2 -0
  73. package/src/types/interfaces.ts +6 -0
  74. package/src/types/types.ts +66 -0
  75. package/src/utils/format-variables.helper.ts +83 -0
  76. package/src/utils/index.ts +2 -0
  77. 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,2 @@
1
+ export * from './interfaces';
2
+ export * from './types';
@@ -0,0 +1,6 @@
1
+ // export interface IAsyncMapGetter<ValueType> {
2
+ export type SupportedTypes<T> = Promise<T> | T | undefined;
3
+
4
+ export interface IAsyncMapGetter<T> {
5
+ get(key: string): SupportedTypes<T>;
6
+ }
@@ -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,2 @@
1
+ export * from './format-variables.helper';
2
+ export * from './validations.helper';
@@ -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
+ };