node-opcua-service-filter 2.184.0 → 2.184.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.
@@ -1 +1 @@
1
- {"version":3,"file":"check_event_clause.d.ts","sourceRoot":"","sources":["../source/check_event_clause.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAI5E,OAAO,EAAE,KAAK,UAAU,EAAe,MAAM,wBAAwB,CAAC;AACtE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAK/D;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,sBAAsB,GAAG,UAAU,CAkCxG;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,sBAAsB,EAAE,GAAG,UAAU,EAAE,CAErH"}
1
+ {"version":3,"file":"check_event_clause.d.ts","sourceRoot":"","sources":["../source/check_event_clause.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAI5E,OAAO,EAAE,KAAK,UAAU,EAAe,MAAM,wBAAwB,CAAC;AACtE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAK/D;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,sBAAsB,GAAG,UAAU,CAkDxG;AA2BD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,sBAAsB,EAAE,GAAG,UAAU,EAAE,CAErH"}
@@ -42,8 +42,46 @@ export function checkSelectClause(parentNode, selectClause) {
42
42
  // navigate to the innerNode specified by the browsePath [ QualifiedName]
43
43
  const browsePath = constructBrowsePathFromQualifiedName(eventTypeNode, selectClause.browsePath);
44
44
  const browsePathResult = addressSpace.browsePath(browsePath);
45
+ if (browsePathResult.statusCode.isGood()) {
46
+ return browsePathResult.statusCode;
47
+ }
48
+ // OPC 10000-4 7.4.4.5: typeDefinitionId restricts the operand to instances of that type *or its
49
+ // subtypes*, so a browsePath that does not resolve on typeDefinitionId itself is still valid as soon
50
+ // as one subtype declares it. BaseEventType therefore acts as a wildcard: an Alarms and Conditions
51
+ // client asks for [BranchId] or [Retain] with typeDefinitionId = BaseEventType, and those fields are
52
+ // declared on ConditionType. Delivery already resolves per event instance (see extractEventField), so
53
+ // only the validation had to be relaxed - and only for the clauses that did not resolve directly, so
54
+ // the walk below never runs for a well-targeted filter.
55
+ if (findFieldInSubtypes(eventTypeNode, selectClause)) {
56
+ return StatusCodes.Good;
57
+ }
58
+ // the field is declared by no subtype of typeDefinitionId either: report the original diagnostic.
45
59
  return browsePathResult.statusCode;
46
60
  }
61
+ /**
62
+ * depth-first search of the subtypes of eventTypeNode for one that declares the browsePath of selectClause.
63
+ *
64
+ * This is bounded by the *event type* hierarchy, not by the address space: event types are a few dozen
65
+ * ObjectTypes even in a large server, and the search only runs when the direct resolution failed, on a
66
+ * CreateMonitoredItems / filter validation path. It is not a per-notification cost.
67
+ */
68
+ function findFieldInSubtypes(eventTypeNode, selectClause) {
69
+ const addressSpace = eventTypeNode.addressSpace;
70
+ const subtypes = eventTypeNode.findReferencesAsObject("HasSubtype", true);
71
+ for (const subtype of subtypes) {
72
+ if (subtype.nodeClass !== NodeClass.ObjectType) {
73
+ continue;
74
+ }
75
+ const browsePath = constructBrowsePathFromQualifiedName(subtype, selectClause.browsePath);
76
+ if (addressSpace.browsePath(browsePath).statusCode.isGood()) {
77
+ return true;
78
+ }
79
+ if (findFieldInSubtypes(subtype, selectClause)) {
80
+ return true;
81
+ }
82
+ }
83
+ return false;
84
+ }
47
85
  /**
48
86
 
49
87
  * @param eventTypeNode
@@ -1 +1 @@
1
- {"version":3,"file":"check_event_clause.js","sourceRoot":"","sources":["../source/check_event_clause.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,oCAAoC,EAAE,MAAM,0CAA0C,CAAC;AAChG,OAAO,EAAmB,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGtE,MAAM,QAAQ,GAAG,aAAa,CAAC,oBAAoB,CAAC,CAAC;AACrD,MAAM,OAAO,GAAG,cAAc,CAAC,oBAAoB,CAAC,CAAC;AAErD;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAAoB,EAAE,YAAoC;IACxF,EAAE;IACF,MAAM,YAAY,GAAG,UAAU,CAAC,YAAY,CAAC;IAE7C,oBAAoB;IACpB,IAAI,YAAY,CAAC,gBAAgB,CAAC,OAAO,EAAE,EAAE,CAAC;QAC1C,OAAO,WAAW,CAAC,IAAI,CAAC;IAC5B,CAAC;IACD,MAAM,aAAa,GAAG,YAAY,CAAC,aAAa,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;IAEhF,2DAA2D;IAC3D,IAAI,CAAC,aAAa,EAAE,CAAC;QACjB,OAAO,WAAW,CAAC,gBAAgB,CAAC;IACxC,CAAC;IACD,yDAAyD;IACzD,IAAI,aAAa,CAAC,SAAS,KAAK,SAAS,CAAC,UAAU,EAAE,CAAC;QACnD,oBAAoB;QACpB,OAAO,IAAI,QAAQ,CAAC,oBAAoB,EAAE,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAC;QACpE,OAAO,WAAW,CAAC,eAAe,CAAC;IACvC,CAAC;IAED,+FAA+F;IAC/F,gGAAgG;IAChG,8FAA8F;IAC9F,kGAAkG;IAClG,gDAAgD;IAChD,IAAI,CAAC,YAAY,CAAC,UAAU,IAAI,YAAY,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnE,OAAO,WAAW,CAAC,IAAI,CAAC;IAC5B,CAAC;IAED,yEAAyE;IACzE,MAAM,UAAU,GAAG,oCAAoC,CAAC,aAAa,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;IAChG,MAAM,gBAAgB,GAAG,YAAY,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAC7D,OAAO,gBAAgB,CAAC,UAAU,CAAC;AACvC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,aAA2B,EAAE,aAAuC;IACnG,OAAO,aAAa,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;AAC1E,CAAC"}
1
+ {"version":3,"file":"check_event_clause.js","sourceRoot":"","sources":["../source/check_event_clause.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "node-opcua-service-filter",
3
3
  "type": "module",
4
- "version": "2.184.0",
4
+ "version": "2.184.1",
5
5
  "description": "pure nodejs OPCUA SDK - module service-filter",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -15,23 +15,23 @@
15
15
  "node": ">=22.13.0"
16
16
  },
17
17
  "dependencies": {
18
- "node-opcua-address-space-base": "2.184.0",
18
+ "node-opcua-address-space-base": "2.184.1",
19
19
  "node-opcua-assert": "2.184.0",
20
- "node-opcua-basic-types": "2.184.0",
20
+ "node-opcua-basic-types": "2.184.1",
21
21
  "node-opcua-constants": "2.184.0",
22
- "node-opcua-data-model": "2.184.0",
23
- "node-opcua-data-value": "2.184.0",
22
+ "node-opcua-data-model": "2.184.1",
23
+ "node-opcua-data-value": "2.184.1",
24
24
  "node-opcua-debug": "2.184.0",
25
- "node-opcua-extension-object": "2.184.0",
26
- "node-opcua-nodeid": "2.184.0",
27
- "node-opcua-service-translate-browse-path": "2.184.0",
28
- "node-opcua-status-code": "2.184.0",
29
- "node-opcua-types": "2.184.0",
30
- "node-opcua-variant": "2.184.0"
25
+ "node-opcua-extension-object": "2.184.1",
26
+ "node-opcua-nodeid": "2.184.1",
27
+ "node-opcua-service-translate-browse-path": "2.184.1",
28
+ "node-opcua-status-code": "2.184.1",
29
+ "node-opcua-types": "2.184.1",
30
+ "node-opcua-variant": "2.184.1"
31
31
  },
32
32
  "devDependencies": {
33
- "node-opcua-numeric-range": "2.184.0",
34
- "node-opcua-packet-analyzer": "2.184.0"
33
+ "node-opcua-numeric-range": "2.184.1",
34
+ "node-opcua-packet-analyzer": "2.184.1"
35
35
  },
36
36
  "author": "Etienne Rossignon",
37
37
  "license": "MIT",
@@ -48,7 +48,7 @@
48
48
  "internet of things"
49
49
  ],
50
50
  "homepage": "http://node-opcua.github.io/",
51
- "gitHead": "441a5c63e3a4202eb8de8597acac77a3a49248b7",
51
+ "gitHead": "29af4e8ac45f585e7b0d8cff9c799b4f0f2f0985",
52
52
  "files": [
53
53
  "dist",
54
54
  "source"
@@ -51,9 +51,50 @@ export function checkSelectClause(parentNode: BaseNode, selectClause: SimpleAttr
51
51
  // navigate to the innerNode specified by the browsePath [ QualifiedName]
52
52
  const browsePath = constructBrowsePathFromQualifiedName(eventTypeNode, selectClause.browsePath);
53
53
  const browsePathResult = addressSpace.browsePath(browsePath);
54
+ if (browsePathResult.statusCode.isGood()) {
55
+ return browsePathResult.statusCode;
56
+ }
57
+
58
+ // OPC 10000-4 7.4.4.5: typeDefinitionId restricts the operand to instances of that type *or its
59
+ // subtypes*, so a browsePath that does not resolve on typeDefinitionId itself is still valid as soon
60
+ // as one subtype declares it. BaseEventType therefore acts as a wildcard: an Alarms and Conditions
61
+ // client asks for [BranchId] or [Retain] with typeDefinitionId = BaseEventType, and those fields are
62
+ // declared on ConditionType. Delivery already resolves per event instance (see extractEventField), so
63
+ // only the validation had to be relaxed - and only for the clauses that did not resolve directly, so
64
+ // the walk below never runs for a well-targeted filter.
65
+ if (findFieldInSubtypes(eventTypeNode as UAObjectType, selectClause)) {
66
+ return StatusCodes.Good;
67
+ }
68
+
69
+ // the field is declared by no subtype of typeDefinitionId either: report the original diagnostic.
54
70
  return browsePathResult.statusCode;
55
71
  }
56
72
 
73
+ /**
74
+ * depth-first search of the subtypes of eventTypeNode for one that declares the browsePath of selectClause.
75
+ *
76
+ * This is bounded by the *event type* hierarchy, not by the address space: event types are a few dozen
77
+ * ObjectTypes even in a large server, and the search only runs when the direct resolution failed, on a
78
+ * CreateMonitoredItems / filter validation path. It is not a per-notification cost.
79
+ */
80
+ function findFieldInSubtypes(eventTypeNode: UAObjectType, selectClause: SimpleAttributeOperand): boolean {
81
+ const addressSpace = eventTypeNode.addressSpace;
82
+ const subtypes = eventTypeNode.findReferencesAsObject("HasSubtype", true);
83
+ for (const subtype of subtypes) {
84
+ if (subtype.nodeClass !== NodeClass.ObjectType) {
85
+ continue;
86
+ }
87
+ const browsePath = constructBrowsePathFromQualifiedName(subtype, selectClause.browsePath);
88
+ if (addressSpace.browsePath(browsePath).statusCode.isGood()) {
89
+ return true;
90
+ }
91
+ if (findFieldInSubtypes(subtype as UAObjectType, selectClause)) {
92
+ return true;
93
+ }
94
+ }
95
+ return false;
96
+ }
97
+
57
98
  /**
58
99
 
59
100
  * @param eventTypeNode