src/transform/Mapping.js
- import { basename } from 'path';
- import assert from 'assert';
- import { VariantArrayType, DataType } from 'node-opcua/lib/datamodel/variant';
- import Transformer from '../lib/transform/Transformer';
-
- /**
- * Atvise specific types that need special extensions.
- * @type {Map<string, Object>}
- */
- const standardTypes = {
- 'VariableTypes.ATVISE.HtmlHelp': {
- extension: '.help.html',
- dataType: DataType.ByteString,
- },
- 'VariableTypes.ATVISE.TranslationTable': {
- extension: '.locs.xml',
- dataType: DataType.XmlElement,
- },
- };
-
- /**
- * Extensions to use for {@link node-opcua~DataType}s.
- * @type {Map<string, string>}
- */
- const extensionForDataType = {
- [DataType.Boolean.key]: '.bool',
- [DataType.SByte.key]: '.sbyte',
- [DataType.Byte.key]: '.byte',
- [DataType.Int16.key]: '.int16',
- [DataType.UInt16.key]: '.uint16',
- [DataType.Int32.key]: '.int32',
- [DataType.UInt32.key]: '.uint32',
- [DataType.Int64.key]: '.int64',
- [DataType.UInt64.key]: '.uint64',
- [DataType.Float.key]: '.float',
- [DataType.Double.key]: '.double',
- [DataType.String.key]: '.string',
- [DataType.DateTime.key]: '.datetime',
- [DataType.Guid.key]: '.guid',
- // [DataType.ByteString.key]: '.bytestring',
- [DataType.XmlElement.key]: '.xml',
- [DataType.NodeId.key]: '.nodeid',
- [DataType.ExpandedNodeId.key]: '.enodeid',
- [DataType.StatusCode.key]: '.status',
- [DataType.QualifiedName.key]: '.name',
- [DataType.LocalizedText.key]: '.text',
- [DataType.ExtensionObject.key]: '.obj',
- [DataType.DataValue.key]: '.value',
- [DataType.Variant.key]: '.variant',
- [DataType.DiagnosticInfo.key]: '.info',
- };
-
- /**
- * Extensions to use for {@link node-opcua~VariantArrayType}s.
- * @type {Map<string, string>}
- */
- const extensionForArrayType = {
- [VariantArrayType.Array.key]: '.array',
- [VariantArrayType.Matrix.key]: '.matrix',
- };
-
- /**
- * A Transformer that maps {@link ReadStream.ReadResult}s to {@link AtviseFile}s.
- */
- export default class MappingTransformer extends Transformer {
- /**
- * Creates a new mapping transformer.
- * @param {Object} [options] The arguments passed to the {@link Transformer} constructor.
- */
- constructor(options = {}) {
- super(options);
-
- /**
- * Contents of the reference files read but not used yet.
- * @type {Object}
- */
- this._readReferenceFiles = {};
- }
-
- /**
- * Writes an {@link AtviseFile} for each {@link ReadStream.ReadResult} read. If a read file has a
- * non-standard type (definition) an additional `rc` file is pushed holding this type.
- * @param {Node} node The read result to create the file for.
- * @param {string} encoding The encoding used.
- * @param {function(err: ?Error, data: ?AtviseFile)} callback Called with the error that occurred
- * while transforming the read result or the resulting file.
- */
- transformFromDB(node, encoding, callback) {
- if (!node.fullyMapped && !node.parentResolvesMetadata) {
- // Skip mapping for e.g. split files
- const typeDefinition = node.typeDefinition;
- let isStandardTypeNode = false;
-
- // Add extensions for standard types
- for (const [def, { extension }] of Object.entries(standardTypes)) {
- if (node.isVariable && typeDefinition === def) {
- node.renameTo(`${node.name}${extension}`);
- isStandardTypeNode = true;
-
- // FIXME: Set dataType and mark as resolved
- // FIXME: Set typeDefinition and mark as resolved
- } else if (node.fileName.endsWith(extension)) {
- callback(new Error(`Name conflict: ${node.nodeId} should not end with '${extension}'`));
- return;
- }
- }
-
- // Add extensions for data types
- for (const [type, ext] of Object.entries(extensionForDataType)) {
- if (node.isVariable && node.value && node.value.dataType.key === type) {
- if (!isStandardTypeNode) {
- node.renameTo(`${node.name}${ext}`);
- break;
- }
-
- // FIXME: Set dataType and mark as resolved
- }
- }
-
- // Add extensions for array types
- for (const [type, ext] of Object.entries(extensionForArrayType)) {
- if (node.isVariable && node.value.arrayType.key === type) {
- if (!isStandardTypeNode) {
- node.renameTo(`${node.name}${ext}`);
- }
-
- // FIXME: Set arrayType and mark as resolved
- } else if (node.fileName.endsWith(ext)) {
- callback(new Error(`Name conflict: ${node.nodeId} should not end with '${ext}'`));
- return;
- }
- }
- }
-
- // Compact mapping: Root source folders are AGENT, SYSTEM, ObjectTypes and VariableTypes
- // FIXME: Make optional
- const ignore = new Set([
- 58, // Objects -> Types -> BaseObjectType
- 62, // Objects -> Types -> BaseVariableType
- 85, // Objects
- 86, // Objects -> Types
- ]);
-
- for (let c = node; c && c.parent && !c._compactMappingApplied; c = c.parent) {
- if (ignore.has(c.parent.id.value)) {
- c.parent = c.parent.parent;
- c = node;
- }
- }
-
- Object.assign(node, {
- _compactMappingApplied: true,
- });
-
- callback(null, node);
- }
-
- /**
- * Writes an {@link AtviseFile} for each {@link Node} read.
- * @param {Node} node The raw file.
- * @param {string} encoding The encoding used.
- * @param {function(err: ?Error, data: ?AtviseFile)} callback Called with the error that occurred
- * while transforming the read result or the resulting file.
- */
- transformFromFilesystem(node, encoding, callback) {
- let isStandardTypeNode = false;
-
- // Resolve standard type from extension
- for (const [, { extension }] of Object.entries(standardTypes)) {
- if (node.name.endsWith(extension)) {
- isStandardTypeNode = true;
-
- // FIXME: Set dataType and mark as resolved
- // FIXME: Set typeDefinition and mark as resolved
-
- node.renameTo(basename(node.name, extension));
- }
- }
-
- // Resolve arrayType from extension
- for (const [type, extension] of Object.entries(extensionForArrayType)) {
- if (node.name.endsWith(extension) && !isStandardTypeNode) {
- assert.equal(node.arrayType.key, type);
-
- // FIXME: Set arrayType and mark as resolved
-
- node.renameTo(basename(node.name, extension));
- break;
- }
- }
-
- // Resolve dataType from extension
- for (const [type, extension] of Object.entries(extensionForDataType)) {
- if (node.name.endsWith(extension) && !isStandardTypeNode && node.dataType.key === type) {
- // FIXME: Set dataType and mark as resolved
-
- node.renameTo(basename(node.name, extension));
- break;
- }
- }
-
- return callback(null, node);
- }
-
- /**
- * `true` as the mapping transformer should infer references from config files.
- */
- get transformsReferenceConfigFiles() {
- return true;
- }
- }