@machinemetrics/io-adapter-lib 2.32.3 → 2.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.33.0]
4
+ - Added support for numeric indexing in expressions
5
+ - Fixed map not allowing any transforms to be chained beyond it
6
+
3
7
  ## [2.32.3]
4
8
  - Added opcua-conditions options for code format and allow/deny nodes
5
9
 
@@ -196,7 +196,7 @@ class ExpressionService {
196
196
  }
197
197
 
198
198
  findCompoundIdentifiers(str) {
199
- const matches = str.match(/[A-Za-z_][A-Za-z0-9_-]*(?:(?:\.[A-Za-z][A-Za-z0-9_-]*)|(?:\['[^'"]+'\]))+/g);
199
+ const matches = str.match(/[A-Za-z_][A-Za-z0-9_-]*(?:(?:\.[A-Za-z][A-Za-z0-9_-]*)|(?:\[('[^'"]+'|\d+)\]))+/g);
200
200
  return matches ?? [];
201
201
  }
202
202
 
@@ -216,7 +216,13 @@ class ExpressionService {
216
216
  rest.push(match[1]);
217
217
  compound = compound.substr(match[0].length);
218
218
  } else {
219
- break;
219
+ match = compound.match(/^\[(\d+)\]/);
220
+ if (match) {
221
+ rest.push(+match[1]);
222
+ compound = compound.substr(match[0].length);
223
+ } else {
224
+ break;
225
+ }
220
226
  }
221
227
  }
222
228
  }
@@ -249,6 +255,12 @@ class ExpressionService {
249
255
  const first = tokens[0];
250
256
  if (first === 'this' || this.channelsLookup[first]) {
251
257
  accum[first] = _.reduceRight(_.tail(tokens), (sub, item) => {
258
+ if (_.isNumber(item)) {
259
+ return [
260
+ ..._.times(Math.max(0, item - 1), () => 0),
261
+ sub,
262
+ ];
263
+ }
252
264
  return { [item]: sub };
253
265
  }, 0);
254
266
  } else {
@@ -261,7 +273,11 @@ class ExpressionService {
261
273
  try {
262
274
  return this.compileInnerExpression(expression, { ...scope, ...addedScope });
263
275
  } catch (err) {
264
- throw new Error(`Problem evaluating expression: ${errMessage}`);
276
+ let message = err.message;
277
+ if (message.startsWith('Index out')) {
278
+ message = `${message}. Indexes in expressions start at 1`;
279
+ }
280
+ throw new Error(`Problem evaluating expression: ${message}`);
265
281
  }
266
282
  }
267
283
 
@@ -47,7 +47,7 @@ class MapFilter extends TransformState {
47
47
  constructor({ engine, /* path, rootPath, baseTransform, */ args: { transforms } }, builder) {
48
48
  super();
49
49
 
50
- this.chain = builder.createTransformChain(engine, transforms);
50
+ this.innerChain = builder.createTransformChain(engine, transforms);
51
51
 
52
52
  this.makeChain = () => {
53
53
  return new MapChain(builder.createTransformChain(engine, transforms));
@@ -78,7 +78,7 @@ class MapFilter extends TransformState {
78
78
  }
79
79
 
80
80
  supportsPendingChanges() {
81
- return this.chain.supportsPendingChanges();
81
+ return this.innerChain.supportsPendingChanges();
82
82
  }
83
83
 
84
84
  updateChainList(size) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@machinemetrics/io-adapter-lib",
3
- "version": "2.32.3",
3
+ "version": "2.33.0",
4
4
  "description": "Configuration and engine implementation for MachineMetrics AdapterScripts and adapters",
5
5
  "main": "index.js",
6
6
  "license": "UNLICENSED",
@@ -7,6 +7,7 @@ declare-keys:
7
7
  - counter
8
8
  - program
9
9
  - complex
10
+ - complex2
10
11
  variables:
11
12
  var1:
12
13
  - source: counter
@@ -17,3 +18,8 @@ variables:
17
18
  - source: complex
18
19
  - map:
19
20
  - expression: this.subkey
21
+ var3:
22
+ - source: complex2
23
+ - map:
24
+ - expression: this.subkey
25
+ - expression: this[1]
@@ -80,6 +80,42 @@ describe('ExpressionService tests', function () {
80
80
  expect(() => exprsvc.compileExpression('this + 1')).to.throw('Undefined symbol this');
81
81
  });
82
82
 
83
+ it('parses expressions with compound identifiers', function () {
84
+ const exprsvc = new ExpressionService();
85
+
86
+ const context1 = { this: 5 };
87
+ const expr1 = exprsvc.compileExpression('this', context1);
88
+ expect(expr1.evaluate(context1)).to.eq(5);
89
+
90
+ const context2 = { this: { subkey: 5 } };
91
+ const expr2 = exprsvc.compileExpression('this.subkey', context2);
92
+ expect(expr2.evaluate(context2)).to.eq(5);
93
+
94
+ const context3 = { this: { subkey: { secondary: 5 } } };
95
+ const expr3 = exprsvc.compileExpression('this.subkey.secondary', context3);
96
+ expect(expr3.evaluate(context3)).to.eq(5);
97
+
98
+ const context4 = { this: { subkey: { secondary: 5 } } };
99
+ const expr4 = exprsvc.compileExpression('this.subkey[\'secondary\']', context4);
100
+ expect(expr4.evaluate(context4)).to.eq(5);
101
+
102
+ const context5 = { this: { subkey: [0, 0, 5] } };
103
+ const expr5 = exprsvc.compileExpression('this.subkey[3]', context5);
104
+ expect(expr5.evaluate(context5)).to.eq(5);
105
+
106
+ const context6 = { this: [0, 0, 5] };
107
+ const expr6 = exprsvc.compileExpression('this[3]', context6);
108
+ expect(expr6.evaluate(context6)).to.eq(5);
109
+
110
+ const context7 = { this: { subkey: [0, 0, { bar: 5 }] } };
111
+ const expr7 = exprsvc.compileExpression('this.subkey[3].bar', context7);
112
+ expect(expr7.evaluate(context7)).to.eq(5);
113
+
114
+ const context8 = { this: { subkey: [0, 0, { bar: [0, { baz: 5 }] }] } };
115
+ const expr8 = exprsvc.compileExpression('this.subkey[3].bar[2].baz', context8);
116
+ expect(expr8.evaluate(context8)).to.eq(5);
117
+ });
118
+
83
119
  /* eslint-disable no-template-curly-in-string */
84
120
 
85
121
  it('parses string expressions', function () {
@@ -39,4 +39,19 @@ describe('map full engine config file tests', function () {
39
39
  [[10, 20], 0],
40
40
  ]);
41
41
  });
42
+
43
+ it('transform chained after map', function () {
44
+ const engine = new EngineV2(config);
45
+ const builder = new Builder(config);
46
+ builder.build(engine);
47
+
48
+ const source = testUtils.valueSource();
49
+ testUtils.attachEngineTransformValidator(engine, engine.variablePool.var3, source);
50
+
51
+ source.sendValue('complex2', [{ subkey: 10, xx: 15 }, { subkey: 20, xx: 30 }], 0);
52
+
53
+ engine.validateFilter([
54
+ [10, 0],
55
+ ]);
56
+ });
42
57
  });