Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

node-opcua-client-dynamic-extension-object

Package Overview
Dependencies
Maintainers
1
Versions
201
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-opcua-client-dynamic-extension-object - npm Package Compare versions

Comparing version 2.6.4 to 2.6.5

247

dist/client_dynamic_extension_object.js

@@ -39,2 +39,3 @@ "use strict";

if (!a.targets || a.targets.length === 0) {
// the server is probably version < 1.04.
debugLog("Cannot find Deprecated property for dataTypeDictionary " + dataTypeDictionary.toString());

@@ -91,2 +92,6 @@ return false;

}
/* istanbul ignore next */
if (nodesToBrowse3.length === 0) {
return [];
}
const results3 = yield session.browse(nodesToBrowse3);

@@ -121,17 +126,19 @@ const binaryEncodings = [];

}
const results4 = yield session.browse(nodesToBrowseDataType);
const dataTypeNodeIds = [];
i = 0;
for (const result4 of results4) {
result4.references = result4.references || [];
/* istanbul ignore next */
if (result4.references.length !== 1) {
console.log("What's going on ?", result4.toString());
if (nodesToBrowseDataType.length > 0) {
const results4 = yield session.browse(nodesToBrowseDataType);
i = 0;
for (const result4 of results4) {
result4.references = result4.references || [];
/* istanbul ignore next */
if (result4.references.length !== 1) {
console.log("What's going on ?", result4.toString());
}
for (const ref of result4.references) {
const dataTypeNodeId = ref.nodeId;
dataTypeNodeIds.push(dataTypeNodeId);
const dataTypeDescription = dataTypeDescriptions[i++];
dataTypeDescription.encodings.dataTypeNodeId = dataTypeNodeId;
}
}
for (const ref of result4.references) {
const dataTypeNodeId = ref.nodeId;
dataTypeNodeIds.push(dataTypeNodeId);
const dataTypeDescription = dataTypeDescriptions[i++];
dataTypeDescription.encodings.dataTypeNodeId = dataTypeNodeId;
}
}

@@ -154,3 +161,3 @@ return dataTypeNodeIds;

if (references.length === 0) {
//xx throw new Error("Cannot find encodings on type " + dataTypeNodeId.toString() + " statusCode " + result.statusCode.toString());
// xx throw new Error("Cannot find encodings on type " + dataTypeNodeId.toString() + " statusCode " + result.statusCode.toString());
}

@@ -217,3 +224,3 @@ const encodings = {

const dataTypeNodeIds = yield _enrichWithDescriptionOf(session, dataTypeDescriptions);
// now read DataTypeDefition attributes of all the dataTypeNodeIds, this will only contains concrete structure
// now read DataTypeDefinition attributes of all the dataTypeNodeIds, this will only contains concrete structure
const nodesToRead = dataTypeNodeIds.map((nodeId) => ({

@@ -243,3 +250,3 @@ attributeId: node_opcua_data_model_1.AttributeIds.DataTypeDefinition, nodeId,

}
// to do put in logicial order
// to do put in logical order
const dataTypeDefinitionsSorted = sortStructure(dataTypeDefinitions);

@@ -252,3 +259,3 @@ if (doDebug) {

if (doDebug) {
console.log(chalk.yellow("--------------------------------------- "), className, dataTypeNodeId.toString());
debugLog(chalk.yellow("--------------------------------------- "), className, dataTypeNodeId.toString());
}

@@ -292,15 +299,17 @@ if (dataTypeFactory.hasStructuredType(className)) {

}
function _extractDataTypeDictionary(session, dataTypeDictionaryNodeId, dataTypeManager) {
;
function _extractDataTypeDictionary(session, d, dataTypeManager) {
return __awaiter(this, void 0, void 0, function* () {
const isDictionaryDeprecated = yield _readDeprecatedFlag(session, dataTypeDictionaryNodeId);
const rawSchemaDataValue = yield session.read({ nodeId: dataTypeDictionaryNodeId, attributeId: node_opcua_data_model_1.AttributeIds.Value });
const dataTypeDictionaryNodeId = d.reference.nodeId;
const isDictionaryDeprecated = d.isDictionaryDeprecated; // await _readDeprecatedFlag(session, dataTypeDictionaryNodeId);
const rawSchema = d.rawSchema; // DataValue = await session.read({ nodeId: dataTypeDictionaryNodeId, attributeId: AttributeIds.Value });
const name = yield session.read({ nodeId: dataTypeDictionaryNodeId, attributeId: node_opcua_data_model_1.AttributeIds.BrowseName });
const namespace = yield _readNamespaceUriProperty(session, dataTypeDictionaryNodeId);
if (isDictionaryDeprecated || !rawSchemaDataValue.value.value) {
if (isDictionaryDeprecated || rawSchema.length === 0) {
debugLog("DataTypeDictionary is deprecated or BSD schema stored in dataValue is null !", chalk.cyan(name.value.value.toString()), "namespace =", namespace);
debugLog("lets use the new way (1.04) and let's crawl all dataTypes exposed by this name space");
// dataType definition in store directily in UADataType under the $definition property
debugLog("let's use the new way (1.04) and let's crawl all dataTypes exposed by this name space");
// dataType definition in store directly in UADataType under the $definition property
const dataTypeFactory2 = dataTypeManager.getDataTypeFactory(dataTypeDictionaryNodeId.namespace);
if (!dataTypeFactory2) {
throw new Error("cannot find dataTypeFactort for namespace " + dataTypeDictionaryNodeId.namespace);
throw new Error("cannot find dataTypeFactory for namespace " + dataTypeDictionaryNodeId.namespace);
}

@@ -314,3 +323,2 @@ yield _extractDataTypeDictionaryFromDefinition(session, dataTypeDictionaryNodeId, dataTypeFactory2);

// one need to read the schema file store in the dataTypeDictionary node and parse it !
const rawSchema = rawSchemaDataValue.value.value.toString();
/* istanbul ignore next */

@@ -405,8 +413,16 @@ if (doDebug) {

const namespaceArray = dataValueNamespaceArray.value.value;
if (dataValueNamespaceArray.statusCode === node_opcua_status_code_1.StatusCodes.Good &&
(namespaceArray && namespaceArray.length > 0)) {
// istanbul ignore next
if (!namespaceArray) {
// throw new Error("Cannot get Server_NamespaceArray as a array of string");
return;
}
// istanbul ignore next
if (doDebug) {
debugLog("namespaceArray ", namespaceArray.map((a, index) => " " + index.toString().padEnd(3) + ":" + a).join(" "));
}
if (dataValueNamespaceArray.statusCode === node_opcua_status_code_1.StatusCodes.Good && (namespaceArray && namespaceArray.length > 0)) {
dataTypeManager.setNamespaceArray(namespaceArray);
for (let namespaceIndex = 1; namespaceIndex < namespaceArray.length; namespaceIndex++) {
if (!dataTypeManager.hasDataTypeFactory(namespaceIndex)) {
const dataTypeFactory1 = new node_opcua_factory_1.DataTypeFactory([node_opcua_factory_1.getStandartDataTypeFactory()]);
const dataTypeFactory1 = new node_opcua_factory_1.DataTypeFactory([node_opcua_factory_1.getStandardDataTypeFactory()]);
dataTypeManager.registerDataTypeFactory(namespaceIndex, dataTypeFactory1);

@@ -424,3 +440,2 @@ }

const opcBinaryNodeId = node_opcua_nodeid_1.resolveNodeId("OPCBinarySchema_TypeSystem");
debugLog(opcBinaryNodeId.toString());
// let find all DataType dictionary node corresponding to a given namespace

@@ -446,24 +461,141 @@ // (have DataTypeDictionaryType)

node_opcua_nodeid_1.sameNodeId(e.typeDefinition, dataTypeDictionaryType));
debugLog(`found ${references.length} dictionnary`);
debugLog(`found ${references.length} dictionary`);
function putInCorrectOrder() {
return __awaiter(this, void 0, void 0, function* () {
const infos = [];
const innerMap = {};
for (const reference of references) {
const dataTypeDictionaryNodeId = reference.nodeId;
const isDictionaryDeprecated = yield _readDeprecatedFlag(session, dataTypeDictionaryNodeId);
const rawSchemaDataValue = yield session.read({ nodeId: dataTypeDictionaryNodeId, attributeId: node_opcua_data_model_1.AttributeIds.Value });
const rawSchema = rawSchemaDataValue.value.value ? rawSchemaDataValue.value.value.toString() : "";
const info = {
dataTypeDictionaryNodeId,
dependencies: {},
isDictionaryDeprecated,
rawSchema,
reference,
targetNamespace: "",
};
infos.push(info);
if (!isDictionaryDeprecated && rawSchema.length > 0) {
const matches = rawSchema.match(/<opc:TypeDictionary(.*)>/);
if (matches) {
// extract xml:NS="namespace" from attribute list
// for instance:
// <opc:TypeDictionary
// xmlns:opc="http://opcfoundation.org/BinarySchema/"
// xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
// xmlns:ua="http://opcfoundation.org/UA/"
// xmlns:tns="urn:SomeName:Ua:Types:GlobalTypes"
// DefaultByteOrder="LittleEndian"
// TargetNamespace="urn:SomeName:Ua:Types:GlobalTypes">
const typeDictionaryElementAttributes = matches[1];
const c2 = typeDictionaryElementAttributes.match(/TargetNamespace="([^\"]+)"/);
if (c2) {
info.targetNamespace = c2[1];
}
const nsKeyNamespace = {};
for (const attribute of typeDictionaryElementAttributes.split(" ")) {
const c = attribute.match(/xmlns:(.*)=\"([^\"]+)\"/);
if (c) {
const xmlns = c[1];
const namespace = c[2];
nsKeyNamespace[xmlns] = namespace;
debugLog("xxxx ns= ", xmlns, "=>", namespace);
}
}
info.dependencies = nsKeyNamespace;
debugLog("xxx targetNamespace = ", info.targetNamespace);
innerMap[info.targetNamespace] = info;
}
}
else {
// may be 1.04 => the rawScheme is no more needed in new version
info.targetNamespace = namespaceArray[dataTypeDictionaryNodeId.namespace];
debugLog("xxx targetNamespace = ", info.targetNamespace);
innerMap[info.targetNamespace] = info;
}
node_opcua_assert_1.assert(info.targetNamespace.length !== 0);
}
// ----------------------------------
const orderedList = [];
const visited = {};
function explore(d) {
if (visited[d.targetNamespace]) {
return;
}
visited[d.targetNamespace] = 1;
for (const [xmlns, namespace] of Object.entries(d.dependencies)) {
if (!innerMap[namespace] || namespace === d.targetNamespace) {
continue;
}
explore(innerMap[namespace]);
}
orderedList.push(d);
}
for (const d of infos) {
explore(d);
}
debugLog(" Ordered List = ", orderedList.map(a => a.targetNamespace).join(" "));
return orderedList;
});
}
const dataTypeDictionaryInfo = yield putInCorrectOrder();
// setup dependencies
const map = {};
for (const d of dataTypeDictionaryInfo) {
map[d.targetNamespace] = d;
debugLog(" fixing based dataTypeFactory dependencies for ", d.targetNamespace, "index = ", d.dataTypeDictionaryNodeId.namespace);
const baseDataFactories = [node_opcua_factory_1.getStandardDataTypeFactory()];
for (const namespace of Object.values(d.dependencies)) {
if (namespace === d.targetNamespace) {
continue;
}
const baseDataFactory = map[namespace];
if (!baseDataFactory) {
// xx console.log("xxxxx baseDataFactory = ", namespace);
continue;
}
const namespaceIndex = baseDataFactory.dataTypeDictionaryNodeId.namespace;
if (dataTypeManager.hasDataTypeFactory(namespaceIndex)) {
const dep = dataTypeManager.getDataTypeFactory(namespaceIndex);
baseDataFactories.push(dep);
debugLog(" considering , ", baseDataFactory.targetNamespace, "index = ", baseDataFactory.dataTypeDictionaryNodeId.namespace);
}
}
const dataTypeFactory = dataTypeManager.getDataTypeFactory(d.dataTypeDictionaryNodeId.namespace);
dataTypeFactory.repairBaseDataFactories(baseDataFactories);
}
// --------------------
// now investigate DataTypeDescriptionType
yield (() => __awaiter(this, void 0, void 0, function* () {
function processReference2(ref) {
return __awaiter(this, void 0, void 0, function* () {
const dataTypeDicitionaryNodeId = ref.nodeId;
// xx const dataTypeFactory = dataTypeManager.getDataTypeFactoryForNamespace(dataTypeDicitionaryNodeId.namespace);
yield _extractDataTypeDictionary(session, dataTypeDicitionaryNodeId, dataTypeManager);
/* istanbul ignore next */
if (doDebug) {
debugLog(chalk.bgWhite(" => "), ref.browseName.toString(), ref.nodeId.toString());
}
const dataTypeFactory = dataTypeManager.getDataTypeFactoryForNamespace(dataTypeDicitionaryNodeId.namespace);
yield _exploreDataTypeDefinition(session, dataTypeDicitionaryNodeId, dataTypeFactory, dataTypeManager.namespaceArray);
function processReferenceOnDataTypeDictionaryType(d) {
return __awaiter(this, void 0, void 0, function* () {
debugLog(chalk.cyan("processReferenceOnDataTypeDictionaryType on "), d.targetNamespace);
const ref = d.reference;
const dataTypeDictionaryNodeId = d.reference.nodeId;
yield _extractDataTypeDictionary(session, d, dataTypeManager);
/* istanbul ignore next */
if (doDebug) {
debugLog(chalk.bgWhite(" => "), ref.browseName.toString(), ref.nodeId.toString());
}
const dataTypeFactory = dataTypeManager.getDataTypeFactoryForNamespace(dataTypeDictionaryNodeId.namespace);
yield _exploreDataTypeDefinition(session, dataTypeDictionaryNodeId, dataTypeFactory, dataTypeManager.namespaceArray);
});
}
// https://medium.com/swlh/dealing-with-multiple-promises-in-javascript-41d6c21f20ff
for (const d of dataTypeDictionaryInfo) {
try {
yield processReferenceOnDataTypeDictionaryType(d).catch(e => {
console.log(e);
debugLog("processReferenceOnDataTypeDictionaryType has failed ");
debugLog("Error", e.message);
debugLog(e);
return e;
});
}
const promises2 = [];
for (const ref of references) {
promises2.push(processReference2(ref));
catch (err) {
debugLog(chalk.red("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx "), err);
}
yield Promise.all(promises2);
}))();
}
debugLog("out ... populateDataTypeManager");

@@ -597,3 +729,4 @@ });

}
const name = yield (yield session.read({ nodeId: dataTypeNodeId, attributeId: node_opcua_data_model_1.AttributeIds.BrowseName })).value.value.name;
const nameDataValue = yield session.read({ nodeId: dataTypeNodeId, attributeId: node_opcua_data_model_1.AttributeIds.BrowseName });
const name = nameDataValue.value.value.name;
const schema = dataTypeFactory.getStructuredTypeSchema(name);

@@ -638,3 +771,3 @@ return schema;

if (subTypeNodeId.namespace === 0 && subTypeNodeId.value <= 29) {
// well knwow node ID !
// well known node ID !
switch (subTypeNodeId.value) {

@@ -685,3 +818,3 @@ case 22: /* Structure */

if (dataValue.statusCode !== node_opcua_status_code_1.StatusCodes.Good) {
const message = "cannot extract BrowseName of nodeId = " + nodeId.toString();
const message = "cannot extract BrowseName of nodeId = " + nodeId.toString() + " statusCode = " + dataValue.statusCode.toString();
debugLog(message);

@@ -695,10 +828,3 @@ throw new Error(message);

return __awaiter(this, void 0, void 0, function* () {
if ((dataTypeNodeId.namespace === 0 && dataTypeNodeId.value === 22)) {
// this is the default Structure !
// throw new Error("invalid nodeId " + dataTypeNodeId.toString());
/* istanbul ignore next */
if (doDebug) {
console.log("resolveFieldType: Invalid NodeId ", dataTypeNodeId.toString());
console.log(pe.render(new Error()));
}
if (dataTypeNodeId.namespace === 0 && dataTypeNodeId.value === 22) {
return null;

@@ -813,6 +939,6 @@ }

case node_opcua_types_1.StructureType.Union:
//xx console.log("Union Found : ", name);
// xx console.log("Union Found : ", name);
fields.push({
fieldType: "UInt32",
name: "SwitchField",
fieldType: "UInt32"
});

@@ -855,2 +981,3 @@ break;

field.category = category;
field.schema = schema;
fields.push(field);

@@ -857,0 +984,0 @@ }

@@ -36,3 +36,3 @@ "use strict";

if (namespaceIndex === 0) {
return node_opcua_factory_1.getStandartDataTypeFactory();
return node_opcua_factory_1.getStandardDataTypeFactory();
}

@@ -63,3 +63,3 @@ return this.dataTypeFactoryMapByNamespace[namespaceIndex];

}
write("ExtraDataTypeMananager");
write("ExtraDataTypeManager");
for (let n = 0; n < this.namespaceArray.length; n++) {

@@ -66,0 +66,0 @@ write("-----------", this.namespaceArray[n]);

@@ -1,4 +0,7 @@

import { DataValue } from "node-opcua-data-value";
import { IBasicSession } from "node-opcua-pseudo-session";
import { Variant } from "node-opcua-variant";
export declare function getExtraDataTypeManager(session: IBasicSession): Promise<any>;
export declare function promoteOpaqueStructure(session: IBasicSession, dataValues: DataValue[]): Promise<void>;
export interface PseudoDataValue {
value: Variant;
}
export declare function promoteOpaqueStructure(session: IBasicSession, dataValues: PseudoDataValue[]): Promise<void>;

@@ -30,2 +30,3 @@ "use strict";

exports.getExtraDataTypeManager = getExtraDataTypeManager;
;
function promoteOpaqueStructure(session, dataValues) {

@@ -49,3 +50,4 @@ return __awaiter(this, void 0, void 0, function* () {

}));
yield Promise.all(promises);
// https://medium.com/swlh/dealing-with-multiple-promises-in-javascript-41d6c21f20ff
yield Promise.all(promises.map(p => p.catch(e => e)));
});

@@ -52,0 +54,0 @@ }

{
"name": "node-opcua-client-dynamic-extension-object",
"version": "2.6.4",
"version": "2.6.5",
"description": "pure nodejs OPCUA SDK - module client-dynamic-extension-object",

@@ -16,15 +16,15 @@ "main": "./dist/index.js",

"node-opcua-binary-stream": "^2.6.1",
"node-opcua-data-model": "^2.6.1",
"node-opcua-data-value": "^2.6.4",
"node-opcua-data-model": "^2.6.5",
"node-opcua-data-value": "^2.6.5",
"node-opcua-debug": "^2.6.1",
"node-opcua-extension-object": "^2.6.1",
"node-opcua-factory": "^2.6.1",
"node-opcua-extension-object": "^2.6.5",
"node-opcua-factory": "^2.6.5",
"node-opcua-nodeid": "^2.6.1",
"node-opcua-pseudo-session": "^2.6.4",
"node-opcua-schemas": "^2.6.4",
"node-opcua-service-browse": "^2.6.4",
"node-opcua-service-translate-browse-path": "^2.6.4",
"node-opcua-pseudo-session": "^2.6.5",
"node-opcua-schemas": "^2.6.5",
"node-opcua-service-browse": "^2.6.5",
"node-opcua-service-translate-browse-path": "^2.6.5",
"node-opcua-status-code": "^2.6.1",
"node-opcua-types": "^2.6.4",
"node-opcua-variant": "^2.6.1"
"node-opcua-types": "^2.6.5",
"node-opcua-variant": "^2.6.5"
},

@@ -46,3 +46,3 @@ "author": "Etienne Rossignon",

"homepage": "http://node-opcua.github.io/",
"gitHead": "0d168bdc8351bbaf7ff9e60e21d459e8c4bdfeca"
"gitHead": "e5e38142a719ebe22afb9617dce34b985d407d9b"
}

@@ -10,3 +10,2 @@ // tslint:disable: no-console

import { assert } from "node-opcua-assert";

@@ -35,3 +34,3 @@ import {

TypeSchemaBase,
getStandartDataTypeFactory,
getStandardDataTypeFactory,
EnumerationDefinitionSchema,

@@ -88,2 +87,3 @@ } from "node-opcua-factory";

if (!a.targets || a.targets.length === 0) {
// the server is probably version < 1.04.
debugLog("Cannot find Deprecated property for dataTypeDictionary " + dataTypeDictionary.toString());

@@ -111,5 +111,5 @@ return false;

dataTypeDictionaryNodeId: NodeId
): Promise<IDataTypeDescriptuon[]> {
): Promise<IDataTypeDescription[]> {
const nodeToBrowse2 = {
const nodeToBrowse2: BrowseDescriptionLike = {
browseDirection: BrowseDirection.Forward,

@@ -130,3 +130,3 @@ includeSubtypes: false,

session: IBasicSession,
dataTypeDescriptions: IDataTypeDescriptuon[]
dataTypeDescriptions: IDataTypeDescription[]
): Promise<NodeId[]> {

@@ -146,2 +146,6 @@ const nodesToBrowse3: BrowseDescriptionOptions[] = [];

}
/* istanbul ignore next */
if (nodesToBrowse3.length === 0) {
return [];
}
const results3 = await session.browse(nodesToBrowse3);

@@ -181,20 +185,22 @@

}
const results4 = await session.browse(nodesToBrowseDataType);
const dataTypeNodeIds: NodeId[] = [];
i = 0;
for (const result4 of results4) {
result4.references = result4.references || [];
if (nodesToBrowseDataType.length > 0) {
const results4 = await session.browse(nodesToBrowseDataType);
i = 0;
for (const result4 of results4) {
result4.references = result4.references || [];
/* istanbul ignore next */
if (result4.references.length !== 1) {
console.log("What's going on ?", result4.toString());
}
/* istanbul ignore next */
if (result4.references.length !== 1) {
console.log("What's going on ?", result4.toString());
}
for (const ref of result4.references) {
const dataTypeNodeId = ref.nodeId;
for (const ref of result4.references) {
const dataTypeNodeId = ref.nodeId;
dataTypeNodeIds.push(dataTypeNodeId);
dataTypeNodeIds.push(dataTypeNodeId);
const dataTypeDescription = dataTypeDescriptions[i++];
dataTypeDescription.encodings!.dataTypeNodeId = dataTypeNodeId;
const dataTypeDescription = dataTypeDescriptions[i++];
dataTypeDescription.encodings!.dataTypeNodeId = dataTypeNodeId;
}
}

@@ -205,3 +211,3 @@ }

interface IDataTypeDescriptuon {
interface IDataTypeDescription {
browseName: QualifiedName;

@@ -213,3 +219,3 @@ nodeId: NodeId;

async function _findEncodings(session: IBasicSession, dataTypeNodeId: NodeId): Promise<DataTypeAndEncodingId> {
const nodeToBrowse = {
const nodeToBrowse: BrowseDescriptionLike = {
browseDirection: BrowseDirection.Forward,

@@ -225,3 +231,3 @@ includeSubtypes: true,

if (references.length === 0) {
//xx throw new Error("Cannot find encodings on type " + dataTypeNodeId.toString() + " statusCode " + result.statusCode.toString());
// xx throw new Error("Cannot find encodings on type " + dataTypeNodeId.toString() + " statusCode " + result.statusCode.toString());
}

@@ -307,3 +313,3 @@ const encodings: DataTypeAndEncodingId = {

// now read DataTypeDefition attributes of all the dataTypeNodeIds, this will only contains concrete structure
// now read DataTypeDefinition attributes of all the dataTypeNodeIds, this will only contains concrete structure
const nodesToRead: ReadValueIdLike[] = dataTypeNodeIds.map((nodeId: NodeId) => ({

@@ -339,3 +345,3 @@ attributeId: AttributeIds.DataTypeDefinition, nodeId,

}
// to do put in logicial order
// to do put in logical order
const dataTypeDefinitionsSorted = sortStructure(dataTypeDefinitions);

@@ -349,3 +355,3 @@ if (doDebug) {

if (doDebug) {
console.log(chalk.yellow("--------------------------------------- "), className, dataTypeNodeId.toString());
debugLog(chalk.yellow("--------------------------------------- "), className, dataTypeNodeId.toString());
}

@@ -399,23 +405,34 @@ if (dataTypeFactory.hasStructuredType(className)) {

interface TypeDictionaryInfo {
reference: ReferenceDescription,
dataTypeDictionaryNodeId: NodeId,
isDictionaryDeprecated: boolean,
rawSchema: string,
dependencies: { [key: string]: string },
targetNamespace: string,
};
async function _extractDataTypeDictionary(
session: IBasicSession,
dataTypeDictionaryNodeId: NodeId,
d: TypeDictionaryInfo,
dataTypeManager: ExtraDataTypeManager
): Promise<void> {
const isDictionaryDeprecated = await _readDeprecatedFlag(session, dataTypeDictionaryNodeId);
const rawSchemaDataValue = await session.read({ nodeId: dataTypeDictionaryNodeId, attributeId: AttributeIds.Value });
const dataTypeDictionaryNodeId = d.reference.nodeId;
const isDictionaryDeprecated = d.isDictionaryDeprecated; // await _readDeprecatedFlag(session, dataTypeDictionaryNodeId);
const rawSchema = d.rawSchema; // DataValue = await session.read({ nodeId: dataTypeDictionaryNodeId, attributeId: AttributeIds.Value });
const name = await session.read({ nodeId: dataTypeDictionaryNodeId, attributeId: AttributeIds.BrowseName });
const namespace = await _readNamespaceUriProperty(session, dataTypeDictionaryNodeId);
if (isDictionaryDeprecated || !rawSchemaDataValue.value.value) {
if (isDictionaryDeprecated || rawSchema.length === 0) {
debugLog("DataTypeDictionary is deprecated or BSD schema stored in dataValue is null !", chalk.cyan(name.value.value.toString()), "namespace =", namespace);
debugLog("lets use the new way (1.04) and let's crawl all dataTypes exposed by this name space");
debugLog("let's use the new way (1.04) and let's crawl all dataTypes exposed by this name space");
// dataType definition in store directily in UADataType under the $definition property
// dataType definition in store directly in UADataType under the $definition property
const dataTypeFactory2 = dataTypeManager.getDataTypeFactory(dataTypeDictionaryNodeId.namespace);
if (!dataTypeFactory2) {
throw new Error("cannot find dataTypeFactort for namespace " + dataTypeDictionaryNodeId.namespace);
throw new Error("cannot find dataTypeFactory for namespace " + dataTypeDictionaryNodeId.namespace);
}

@@ -429,4 +446,2 @@ await _extractDataTypeDictionaryFromDefinition(session, dataTypeDictionaryNodeId, dataTypeFactory2);

// one need to read the schema file store in the dataTypeDictionary node and parse it !
const rawSchema = rawSchemaDataValue.value.value.toString();
/* istanbul ignore next */

@@ -451,3 +466,3 @@ if (doDebug) {

const nodeToBrowse = {
const nodeToBrowse: BrowseDescriptionLike = {
browseDirection: BrowseDirection.Forward,

@@ -537,15 +552,25 @@ includeSubtypes: false,

const namespaceArray = dataValueNamespaceArray.value.value;
const namespaceArray: string[] = dataValueNamespaceArray.value.value;
if (dataValueNamespaceArray.statusCode === StatusCodes.Good &&
(namespaceArray && namespaceArray.length > 0)) {
dataTypeManager.setNamespaceArray(namespaceArray as string[]);
// istanbul ignore next
if (!namespaceArray) {
// throw new Error("Cannot get Server_NamespaceArray as a array of string");
return;
}
// istanbul ignore next
if (doDebug) {
debugLog("namespaceArray ", namespaceArray.map((a, index) => " " + index.toString().padEnd(3) + ":" + a).join(" "));
}
if (dataValueNamespaceArray.statusCode === StatusCodes.Good && (namespaceArray && namespaceArray.length > 0)) {
dataTypeManager.setNamespaceArray(namespaceArray);
for (let namespaceIndex = 1; namespaceIndex < namespaceArray.length; namespaceIndex++) {
if (!dataTypeManager.hasDataTypeFactory(namespaceIndex)) {
const dataTypeFactory1 = new DataTypeFactory([getStandartDataTypeFactory()]);
const dataTypeFactory1 = new DataTypeFactory([getStandardDataTypeFactory()]);
dataTypeManager.registerDataTypeFactory(namespaceIndex, dataTypeFactory1);
}
}
}

@@ -564,4 +589,2 @@

debugLog(opcBinaryNodeId.toString());
// let find all DataType dictionary node corresponding to a given namespace

@@ -591,28 +614,155 @@ // (have DataTypeDictionaryType)

debugLog(`found ${references.length} dictionnary`);
debugLog(`found ${references.length} dictionary`);
// now investigate DataTypeDescriptionType
await (async () => {
async function processReference2(ref: ReferenceDescription): Promise<void> {
async function putInCorrectOrder(): Promise<TypeDictionaryInfo[]> {
const dataTypeDicitionaryNodeId = ref.nodeId;
// xx const dataTypeFactory = dataTypeManager.getDataTypeFactoryForNamespace(dataTypeDicitionaryNodeId.namespace);
const infos: TypeDictionaryInfo[] = [];
const innerMap: { [key: string]: TypeDictionaryInfo } = {};
await _extractDataTypeDictionary(session, dataTypeDicitionaryNodeId, dataTypeManager);
/* istanbul ignore next */
if (doDebug) {
debugLog(chalk.bgWhite(" => "), ref.browseName.toString(), ref.nodeId.toString());
for (const reference of references) {
const dataTypeDictionaryNodeId = reference.nodeId;
const isDictionaryDeprecated = await _readDeprecatedFlag(session, dataTypeDictionaryNodeId);
const rawSchemaDataValue = await session.read({ nodeId: dataTypeDictionaryNodeId, attributeId: AttributeIds.Value });
const rawSchema = rawSchemaDataValue.value.value ? rawSchemaDataValue.value.value.toString() : "";
const info: TypeDictionaryInfo = {
dataTypeDictionaryNodeId,
dependencies: {},
isDictionaryDeprecated,
rawSchema,
reference,
targetNamespace: "",
};
infos.push(info);
if (!isDictionaryDeprecated && rawSchema.length > 0) {
const matches = rawSchema.match(/<opc:TypeDictionary(.*)>/);
if (matches) {
// extract xml:NS="namespace" from attribute list
// for instance:
// <opc:TypeDictionary
// xmlns:opc="http://opcfoundation.org/BinarySchema/"
// xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
// xmlns:ua="http://opcfoundation.org/UA/"
// xmlns:tns="urn:SomeName:Ua:Types:GlobalTypes"
// DefaultByteOrder="LittleEndian"
// TargetNamespace="urn:SomeName:Ua:Types:GlobalTypes">
const typeDictionaryElementAttributes = matches[1];
const c2 = typeDictionaryElementAttributes.match(/TargetNamespace="([^\"]+)"/);
if (c2) {
info.targetNamespace = c2[1];
}
const nsKeyNamespace: { [key: string]: string } = {};
for (const attribute of typeDictionaryElementAttributes.split(" ")) {
const c = attribute.match(/xmlns:(.*)=\"([^\"]+)\"/);
if (c) {
const xmlns = c[1];
const namespace = c[2];
nsKeyNamespace[xmlns] = namespace;
debugLog("xxxx ns= ", xmlns, "=>", namespace);
}
}
info.dependencies = nsKeyNamespace;
debugLog("xxx targetNamespace = ", info.targetNamespace);
innerMap[info.targetNamespace] = info;
}
} else {
// may be 1.04 => the rawScheme is no more needed in new version
info.targetNamespace = namespaceArray[dataTypeDictionaryNodeId.namespace];
debugLog("xxx targetNamespace = ", info.targetNamespace);
innerMap[info.targetNamespace] = info;
}
const dataTypeFactory = dataTypeManager.getDataTypeFactoryForNamespace(dataTypeDicitionaryNodeId.namespace);
await _exploreDataTypeDefinition(session, dataTypeDicitionaryNodeId, dataTypeFactory, dataTypeManager.namespaceArray);
assert(info.targetNamespace.length !== 0);
}
// ----------------------------------
const orderedList: TypeDictionaryInfo[] = [];
const visited: any = {};
function explore(d: TypeDictionaryInfo): void {
if (visited[d.targetNamespace]) {
return;
}
visited[d.targetNamespace] = 1;
for (const [xmlns, namespace] of Object.entries(d.dependencies)) {
if (!innerMap[namespace] || namespace === d.targetNamespace) {
continue;
}
explore(innerMap[namespace]);
}
orderedList.push(d);
}
for (const d of infos) {
explore(d);
}
debugLog(" Ordered List = ", orderedList.map(a => a.targetNamespace).join(" "));
return orderedList;
}
const dataTypeDictionaryInfo = await putInCorrectOrder();
// setup dependencies
const map: { [key: string]: TypeDictionaryInfo } = {};
for (const d of dataTypeDictionaryInfo) {
map[d.targetNamespace] = d;
debugLog(" fixing based dataTypeFactory dependencies for ", d.targetNamespace, "index = ", d.dataTypeDictionaryNodeId.namespace);
const baseDataFactories: DataTypeFactory[] = [getStandardDataTypeFactory()];
for (const namespace of Object.values(d.dependencies)) {
if (namespace === d.targetNamespace) {
continue;
}
const baseDataFactory = map[namespace];
if (!baseDataFactory) {
// xx console.log("xxxxx baseDataFactory = ", namespace);
continue;
}
const namespaceIndex = baseDataFactory.dataTypeDictionaryNodeId.namespace;
if (dataTypeManager.hasDataTypeFactory(namespaceIndex)) {
const dep = dataTypeManager.getDataTypeFactory(namespaceIndex);
baseDataFactories.push(dep);
debugLog(" considering , ", baseDataFactory.targetNamespace, "index = ", baseDataFactory.dataTypeDictionaryNodeId.namespace);
}
}
const promises2: Promise<void>[] = [];
for (const ref of references) {
promises2.push(processReference2(ref));
const dataTypeFactory = dataTypeManager.getDataTypeFactory(d.dataTypeDictionaryNodeId.namespace);
dataTypeFactory.repairBaseDataFactories(baseDataFactories);
}
// --------------------
// now investigate DataTypeDescriptionType
async function processReferenceOnDataTypeDictionaryType(d: TypeDictionaryInfo): Promise<void> {
debugLog(chalk.cyan("processReferenceOnDataTypeDictionaryType on "), d.targetNamespace);
const ref = d.reference;
const dataTypeDictionaryNodeId = d.reference.nodeId;
await _extractDataTypeDictionary(session, d, dataTypeManager);
/* istanbul ignore next */
if (doDebug) {
debugLog(chalk.bgWhite(" => "), ref.browseName.toString(), ref.nodeId.toString());
}
await Promise.all(promises2);
const dataTypeFactory = dataTypeManager.getDataTypeFactoryForNamespace(dataTypeDictionaryNodeId.namespace);
await _exploreDataTypeDefinition(session, dataTypeDictionaryNodeId, dataTypeFactory, dataTypeManager.namespaceArray);
}
})();
// https://medium.com/swlh/dealing-with-multiple-promises-in-javascript-41d6c21f20ff
for (const d of dataTypeDictionaryInfo) {
try {
await processReferenceOnDataTypeDictionaryType(d).catch(e => {
console.log(e);
debugLog("processReferenceOnDataTypeDictionaryType has failed ")
debugLog("Error", e.message);
debugLog(e);
return e;
});
} catch (err) {
debugLog(chalk.red("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx "), err);
}
}
debugLog("out ... populateDataTypeManager");

@@ -626,3 +776,3 @@ }

const nodeToBrowse1 = {
const nodeToBrowse1: BrowseDescriptionLike = {
browseDirection: BrowseDirection.Forward,

@@ -682,3 +832,3 @@ includeSubtypes: false,

async function getDefinition(session: IBasicSession, defaultBinaryEncodingNodeId: NodeId): Promise<NodeId> {
const nodeToBrowse2 = {
const nodeToBrowse2: BrowseDescriptionLike = {
browseDirection: BrowseDirection.Forward,

@@ -714,3 +864,3 @@ includeSubtypes: false,

// find parent node to access the xsd File
const nodeToBrowse3 = {
const nodeToBrowse3: BrowseDescriptionLike = {
browseDirection: BrowseDirection.Inverse,

@@ -767,4 +917,6 @@ includeSubtypes: false,

}
const name = await (await session.read({ nodeId: dataTypeNodeId, attributeId: AttributeIds.BrowseName })).value.value.name;
const nameDataValue: DataValue =
await session.read({ nodeId: dataTypeNodeId, attributeId: AttributeIds.BrowseName });
const name = nameDataValue.value.value.name!;
const schema = dataTypeFactory.getStructuredTypeSchema(name);

@@ -779,3 +931,3 @@ return schema;

const nodeToBrowse3 = {
const nodeToBrowse3: BrowseDescriptionLike = {
browseDirection: BrowseDirection.Inverse,

@@ -817,3 +969,3 @@ includeSubtypes: false,

if (subTypeNodeId.namespace === 0 && subTypeNodeId.value <= 29) {
// well knwow node ID !
// well known node ID !
switch (subTypeNodeId.value) {

@@ -874,3 +1026,3 @@ case 22: /* Structure */

if (dataValue.statusCode !== StatusCodes.Good) {
const message = "cannot extract BrowseName of nodeId = " + nodeId.toString();
const message = "cannot extract BrowseName of nodeId = " + nodeId.toString() + " statusCode = " + dataValue.statusCode.toString();
debugLog(message);

@@ -889,10 +1041,3 @@ throw new Error(message);

if ((dataTypeNodeId.namespace === 0 && dataTypeNodeId.value === 22)) {
// this is the default Structure !
// throw new Error("invalid nodeId " + dataTypeNodeId.toString());
/* istanbul ignore next */
if (doDebug) {
console.log("resolveFieldType: Invalid NodeId ", dataTypeNodeId.toString());
console.log(pe.render(new Error()));
}
if (dataTypeNodeId.namespace === 0 && dataTypeNodeId.value === 22) {
return null;

@@ -1032,6 +1177,6 @@ }

case StructureType.Union:
//xx console.log("Union Found : ", name);
// xx console.log("Union Found : ", name);
fields.push({
fieldType: "UInt32",
name: "SwitchField",
fieldType: "UInt32"
});

@@ -1080,2 +1225,3 @@ break;

field.category = category;
field.schema = schema;
fields.push(field);

@@ -1082,0 +1228,0 @@ }

@@ -10,3 +10,3 @@ /**

DataTypeFactory,
getStandartDataTypeFactory,
getStandardDataTypeFactory,
StructuredTypeSchema,

@@ -57,3 +57,3 @@ } from "node-opcua-factory";

if (namespaceIndex === 0) {
return getStandartDataTypeFactory();
return getStandardDataTypeFactory();
}

@@ -90,3 +90,3 @@ return this.dataTypeFactoryMapByNamespace[namespaceIndex];

}
write("ExtraDataTypeMananager");
write("ExtraDataTypeManager");
for (let n = 0; n < this.namespaceArray.length; n++) {

@@ -93,0 +93,0 @@ write("-----------", this.namespaceArray[n]);

import { DataValue } from "node-opcua-data-value";
import { OpaqueStructure } from "node-opcua-extension-object";
import { IBasicSession } from "node-opcua-pseudo-session";
import { DataType, VariantArrayType } from "node-opcua-variant";
import { DataType, VariantArrayType, Variant } from "node-opcua-variant";

@@ -22,9 +22,10 @@ import { populateDataTypeManager } from "./client_dynamic_extension_object";

export interface PseudoDataValue { value: Variant };
export async function promoteOpaqueStructure(
session: IBasicSession,
dataValues: DataValue[]
dataValues: PseudoDataValue[]
) {
// count number of Opaque Structures
const dataValuesToFix = dataValues.filter((dataValue: DataValue) =>
const dataValuesToFix = dataValues.filter((dataValue: PseudoDataValue) =>
dataValue.value && dataValue.value.dataType === DataType.ExtensionObject &&

@@ -49,6 +50,7 @@ (

const promises = dataValuesToFix.map(
async (dataValue: DataValue) => {
async (dataValue: PseudoDataValue) => {
return await resolveDynamicExtensionObject(dataValue.value, extraDataTypeManager)
});
await Promise.all(promises);
// https://medium.com/swlh/dealing-with-multiple-promises-in-javascript-41d6c21f20ff
await Promise.all(promises.map(p => p.catch(e => e)));
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc