node-opcua-convert-nodeset-to-javascript 2.75.0 → 2.76.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.
@@ -1,9 +1,17 @@
1
+ /* eslint-disable max-depth */
1
2
  import * as chalk from "chalk";
2
3
  import * as wrap from "wordwrap";
3
4
  import { LocalizedText, NodeClass, QualifiedName } from "node-opcua-data-model";
4
5
  import { NodeId } from "node-opcua-nodeid";
5
6
  import { IBasicSession } from "node-opcua-pseudo-session";
6
- import { EnumDefinition, ReferenceDescription, StructureDefinition, _enumerationDataChangeTrigger } from "node-opcua-types";
7
+ import {
8
+ EnumDefinition,
9
+ ReferenceDescription,
10
+ StructureDefinition,
11
+ StructureField,
12
+ Union,
13
+ _enumerationDataChangeTrigger
14
+ } from "node-opcua-types";
7
15
  import { LineFile, lowerFirstLetter } from "node-opcua-utils";
8
16
  import { DataType } from "node-opcua-variant";
9
17
  import assert from "node-opcua-assert";
@@ -44,6 +52,20 @@ const f2 = (str: string) => str.padEnd(50, "-");
44
52
  const f1 = (str: string) => str.padEnd(50, " ");
45
53
  const baseExtension = "_Base";
46
54
 
55
+ const m0 = !doDebug ? "" : `/* 0 */`;
56
+ const m1 = !doDebug ? "" : `/* 1 */`;
57
+ const m2 = !doDebug ? "" : `/* 2 */`;
58
+ const m3 = !doDebug ? "" : `/* 3 */`;
59
+ const m4 = !doDebug ? "" : `/* 4 */`;
60
+ const m5 = !doDebug ? "" : `/* 5 */`;
61
+ const m6 = !doDebug ? "" : `/* 6 */`;
62
+ const m7 = !doDebug ? "" : `/* 7 */`;
63
+ const m8 = !doDebug ? "" : `/* 8 */`;
64
+ const m9 = !doDebug ? "" : `/* 9 */`;
65
+ const mA = !doDebug ? "" : `/* a */`;
66
+ const mB = !doDebug ? "" : `/* b */`;
67
+ const mC = !doDebug ? "" : `/* c */`;
68
+
47
69
  export async function convertDataTypeToTypescript(session: IBasicSession, dataTypeId: NodeId): Promise<void> {
48
70
  const definition = await getDefinition(session, dataTypeId);
49
71
  const browseName = await getBrowseName(session, dataTypeId);
@@ -561,13 +583,14 @@ async function extractVariableExtra(session: IBasicSession, nodeId: NodeId, cach
561
583
  importCollector({ name: "DataType", namespace: -1, module: "BasicType" });
562
584
 
563
585
  const t = isUnspecifiedDataType(classMember.classDef?.dataType);
586
+
564
587
  const suffix =
565
588
  jtype === "undefined" || isUnspecifiedDataType(dataType)
566
589
  ? `<any, any>`
567
- : `<${jtype}${t ? `, /*c*/DataType.${DataType[dataType]}` : ""}>`;
590
+ : `<${jtype}${t ? `, ${m0}DataType.${DataType[dataType]}` : ""}>`;
568
591
 
569
- // const suffix2 = `<T${t ? `, /*a*/DT extends DataType` : ""}>`;
570
- const suffix3 = `<T${t ? `, /*b*/DT` : ""}>`;
592
+ // const suffix2 = `<T${t ? `, /DT extends DataType` : ""}>`;
593
+ const suffix3 = `<T${t ? `, ${m1}DT` : ""}>`;
571
594
 
572
595
  const typeDef = await getTypeDefOrBaseType(session, nodeId);
573
596
  const typeDefCD = await extractClassDefinition(session, typeDef.nodeId!, cache);
@@ -588,7 +611,7 @@ async function extractVariableExtra(session: IBasicSession, nodeId: NodeId, cach
588
611
  if (!isUnspecifiedDataType(typeDefCD.dataType)) {
589
612
  suffixInstantiate = `<${jtype}>`;
590
613
  } else {
591
- suffixInstantiate = `<${jtype}, /*z*/DataType.${DataType[dataType]}>`;
614
+ suffixInstantiate = `<${jtype}, DataType.${DataType[dataType]}>`;
592
615
  }
593
616
  }
594
617
 
@@ -603,7 +626,6 @@ interface ClassDefinitionB {
603
626
  };
604
627
  interfaceName: Import;
605
628
  baseClassDef?: ClassDefinition | null;
606
-
607
629
  }
608
630
  // eslint-disable-next-line max-statements
609
631
  export async function extractClassMemberDef(
@@ -612,10 +634,9 @@ export async function extractClassMemberDef(
612
634
  parentDef: ClassDefinitionB,
613
635
  cache: Cache
614
636
  ): Promise<ClassMember> {
615
-
616
637
  const nodeClass = await getNodeClass(session, nodeId);
617
638
  const browseName = await getBrowseName(session, nodeId);
618
-
639
+
619
640
  const name = toJavascritPropertyName(browseName.name!, { ignoreConflictingName: true });
620
641
 
621
642
  if (nodeClass !== NodeClass.Method && nodeClass !== NodeClass.Object && nodeClass !== NodeClass.Variable) {
@@ -628,7 +649,6 @@ export async function extractClassMemberDef(
628
649
  const modellingRule = await getModellingRule(session, nodeId);
629
650
  const isOptional = sameInBaseClassIsMandatory(parentDef, browseName) ? false : modellingRule === "Optional";
630
651
 
631
-
632
652
  const typeDefinition = await getTypeDefOrBaseType(session, nodeId);
633
653
 
634
654
  if (nodeClass !== NodeClass.Method && (!typeDefinition.browseName || !typeDefinition.browseName.name)) {
@@ -756,6 +776,14 @@ async function preDumpChildren(padding: string, classDef: ClassDefinition, f: Li
756
776
  }
757
777
  }
758
778
 
779
+ const isPlaceHolder = (def: ClassMemberBasic) => {
780
+ const { modellingRule } = def;
781
+ return modellingRule === "MandatoryPlaceholder" || modellingRule === "OptionalPlaceholder";
782
+ };
783
+
784
+ function countExposedChildren(children: ClassMemberBasic[]) {
785
+ return children.reduce((p, def) => p + (isPlaceHolder(def) ? 0 : 1), 0);
786
+ }
759
787
  function dumpChildren(padding: string, children: ClassMemberBasic[], f: LineFile, cache: Cache): void {
760
788
  f = f || new LineFile();
761
789
 
@@ -763,7 +791,10 @@ function dumpChildren(padding: string, children: ClassMemberBasic[], f: LineFile
763
791
  const { suffixInstantiate, name, childType, modellingRule, isOptional, description } = def;
764
792
  def.typeToReference.forEach((t) => cache.ensureImported(t));
765
793
 
766
- if (modellingRule === "MandatoryPlaceholder" || modellingRule === "OptionalPlaceholder") continue;
794
+ if (isPlaceHolder(def)) {
795
+ f.write(" // PlaceHolder for ", name);
796
+ continue;
797
+ }
767
798
  cache.ensureImported(childType);
768
799
  const adjustedName = toJavascritPropertyName(name, { ignoreConflictingName: true });
769
800
  if (description.text) {
@@ -858,7 +889,7 @@ function toComment(prefix: string, description: string) {
858
889
  .join("\n");
859
890
  }
860
891
  export type Type = "enum" | "basic" | "structure" | "ua";
861
- // eslint-disable-next-line max-statements
892
+ // eslint-disable-next-line max-statements, complexity
862
893
  export async function _exportDataTypeToTypescript(
863
894
  session: IBasicSession,
864
895
  nodeId: NodeId,
@@ -913,31 +944,60 @@ export async function _exportDataTypeToTypescript(
913
944
  }
914
945
  f.write(`}`);
915
946
  } else if (definition instanceof StructureDefinition) {
916
- type = "structure";
917
- if (interfaceName === "DTStructure") {
918
- f.write(`export interface ${interfaceName} {`);
947
+ if (baseInterfaceName === "DTUnion") {
948
+ type = "structure";
949
+ for (let i = 0; i < definition.fields!.length; i++) {
950
+ f.write(`export interface ${interfaceName}_${i} extends ${baseInterfaceName} {`);
951
+ for (let j = 0; j < definition.fields!.length; j++) {
952
+ const field = definition.fields![j];
953
+ const fieldName = toJavascritPropertyName(field.name!, { ignoreConflictingName: false });
954
+ if (j === i) {
955
+ await outputStructureField(f, field);
956
+ } else {
957
+ f.write(` ${quotifyIfNecessary(fieldName)}?: never`);
958
+ }
959
+ }
960
+ f.write(`}`);
961
+ }
962
+ f.write(`export type ${interfaceName} = `);
963
+ for (let i = 0; i < definition.fields!.length; i++) {
964
+ f.write(` | ${interfaceName}_${i}`);
965
+ }
966
+ f.write(` ;`);
919
967
  } else {
920
- f.write(`export interface ${interfaceName} extends ${baseInterfaceName} {`);
921
- }
922
- for (const field of definition.fields!) {
923
- const fieldName = toJavascritPropertyName(field.name!, { ignoreConflictingName: false });
924
- // special case ! fieldName=
925
- if (field.description.text) {
926
- f.write(`/** ${field.description.text}*/`);
968
+ type = "structure";
969
+ if (!definition.fields!.length && interfaceName !== "DTStructure") {
970
+ f.write(`export type ${interfaceName} = ${baseInterfaceName};`);
971
+ } else {
972
+ if (interfaceName === "DTStructure") {
973
+ f.write(`export interface ${interfaceName} {`);
974
+ } else {
975
+ f.write(`export interface ${interfaceName} extends ${baseInterfaceName} {`);
976
+ }
977
+ for (const field of definition.fields!) {
978
+ await outputStructureField(f, field);
979
+ }
980
+ f.write(`}`);
927
981
  }
928
- const ar = field.valueRank >= 1 ? "[]" : "";
929
- const { dataType, jtype } = await getCorrepondingJavascriptType(session, field.dataType, cache, importCollector);
930
- f.write(` ${quotifyIfNecessary(fieldName)}: ${jtype}${ar}; // ${DataType[dataType]} ${field.dataType.toString()}`);
931
982
  }
932
- f.write(`}`);
933
983
  } else {
934
984
  type = "basic";
935
985
  f.write(`// NO DEFINITION`);
936
- f.write(`export interface ${interfaceName} extends ${baseInterfaceName} {`);
937
- f.write(`}`);
986
+ f.write(`export type ${interfaceName} = ${baseInterfaceName};`);
938
987
  // throw new Error("Invalid " + definition?.constructor.name);
939
988
  }
940
989
  return { type, content: f.toString(), typeName: interfaceName };
990
+
991
+ async function outputStructureField(f: LineFile, field: StructureField) {
992
+ const fieldName = toJavascritPropertyName(field.name!, { ignoreConflictingName: false });
993
+ // special case ! fieldName=
994
+ if (field.description.text) {
995
+ f.write(`/** ${field.description.text}*/`);
996
+ }
997
+ const ar = field.valueRank >= 1 ? "[]" : "";
998
+ const { dataType, jtype } = await getCorrepondingJavascriptType(session, field.dataType, cache, importCollector);
999
+ f.write(` ${quotifyIfNecessary(fieldName)}: ${jtype}${ar}; // ${DataType[dataType]} ${field.dataType.toString()}`);
1000
+ }
941
1001
  }
942
1002
 
943
1003
  function calculateChevrons(classDef: ClassDefinition, classDefDerived?: { dataType: DataType }) {
@@ -950,13 +1010,13 @@ function calculateChevrons(classDef: ClassDefinition, classDefDerived?: { dataTy
950
1010
  }
951
1011
 
952
1012
  if (!isUnspecifiedDataType(dataType)) {
953
- chevronsDef = `<T extends ${dataTypeName}/*j*/>`;
954
- chevronsUse = "<T/*k*/>";
1013
+ chevronsDef = `<T extends ${dataTypeName}${m3}>`;
1014
+ chevronsUse = `<T${m4}>`;
955
1015
  if (classDefDerived) {
956
1016
  if (isUnspecifiedDataType(classDefDerived.dataType)) {
957
- chevronsExtend = `<T, /*i*/DataType.${DataType[dataType]}>`;
1017
+ chevronsExtend = `<T, ${m5}DataType.${DataType[dataType]}>`;
958
1018
  } else {
959
- chevronsExtend = `<T/*h*/>`;
1019
+ chevronsExtend = `<T${m6}>`;
960
1020
  }
961
1021
  }
962
1022
  } else {
@@ -964,11 +1024,11 @@ function calculateChevrons(classDef: ClassDefinition, classDefDerived?: { dataTy
964
1024
  chevronsDef = `<T, DT extends DataType>`;
965
1025
  if (classDefDerived) {
966
1026
  if (isUnspecifiedDataType(classDefDerived.dataType)) {
967
- chevronsUse = "<T, /*m*/DT>";
968
- chevronsExtend = `<T/*g*/, DT>`;
1027
+ chevronsUse = `<T, ${m7}DT>`;
1028
+ chevronsExtend = `<T${m8}, DT>`;
969
1029
  } else {
970
- chevronsUse = `<T, /*n*/DataType.${DataType[classDefDerived.dataType]}>`;
971
- chevronsExtend = `<T, /*e*/DataType.${DataType[classDefDerived.dataType]}>`;
1030
+ chevronsUse = `<T, ${m9}DataType.${DataType[classDefDerived.dataType]}>`;
1031
+ chevronsExtend = `<T, ${mA}DataType.${DataType[classDefDerived.dataType]}>`;
972
1032
  }
973
1033
  }
974
1034
  }
@@ -1082,46 +1142,60 @@ export async function _convertTypeToTypescript(
1082
1142
 
1083
1143
  const ch = calculateChevrons(classDef);
1084
1144
 
1085
- if (nodeClass === NodeClass.VariableType) {
1086
- if (classDef.dataTypeImport) {
1087
- console.log(chalk.red(" ----------------> ", classDef.browseName));
1088
- classDef.dataTypeImport.forEach((a) => {
1089
- console.log(chalk.red(" ------------------------> ", a.module, a.name, a.namespace));
1090
- });
1091
- classDef.dataTypeImport.forEach(cache.ensureImported.bind(cache));
1092
- }
1093
-
1094
- cache.referenceBasicType("DataType");
1095
- const chevrons = calculateChevrons(classDef);
1096
- const chevronsBase = calculateChevrons(classDef.baseClassDef!, classDef);
1097
- // Shall we cache.ensureImported({ ...baseInterfaceName!, module: dataTypeName, name: dataTypeName });
1098
- const classBaseName = `${interfaceName.name}${baseExtension}${chevrons.chevronsDef}`;
1099
-
1100
- if (baseInterfaceName?.name === "UAVariableT") {
1101
- f.write(`export interface ${classBaseName} {`);
1102
- } else {
1103
- const baseName = `${baseInterfaceName?.name}${baseExtension}${chevronsBase.chevronsExtend}`;
1104
- f.write(`export interface ${classBaseName} extends ${baseName} {`);
1105
- }
1106
- } else {
1107
- const classBaseName = `${interfaceName.name}${baseExtension}`;
1108
- if (baseInterfaceName?.name === "UAObject") {
1109
- f.write(`export interface ${classBaseName} {`);
1145
+ {
1146
+ if (nodeClass === NodeClass.VariableType) {
1147
+ if (classDef.dataTypeImport) {
1148
+ if (doDebug) {
1149
+ console.log(chalk.red(" ----------------> ", classDef.browseName));
1150
+ classDef.dataTypeImport.forEach((a) => {
1151
+ console.log(chalk.red(" ------------------------> ", a.module, a.name, a.namespace));
1152
+ });
1153
+ }
1154
+ classDef.dataTypeImport.forEach(cache.ensureImported.bind(cache));
1155
+ }
1156
+ cache.referenceBasicType("DataType");
1157
+ const chevrons = calculateChevrons(classDef);
1158
+ const chevronsBase = calculateChevrons(classDef.baseClassDef!, classDef);
1159
+ // Shall we cache.ensureImported({ ...baseInterfaceName!, module: dataTypeName, name: dataTypeName });
1160
+ const classBaseName = `${interfaceName.name}${baseExtension}${chevrons.chevronsDef}`;
1161
+ if (countExposedChildren(members) === 0 && baseInterfaceName?.name !== "UAVariableT") {
1162
+ //
1163
+ const baseName = `${baseInterfaceName?.name}${baseExtension}${chevronsBase.chevronsExtend}`;
1164
+ f.write(`export type ${classBaseName} = ${baseName};`);
1165
+ } else {
1166
+ if (baseInterfaceName?.name === "UAVariableT") {
1167
+ f.write(`export interface ${classBaseName} {`);
1168
+ } else {
1169
+ const baseName = `${baseInterfaceName?.name}${baseExtension}${chevronsBase.chevronsExtend}`;
1170
+ f.write(`export interface ${classBaseName} extends ${baseName} {`);
1171
+ }
1172
+ await dumpChildren(" ", members, f, cache);
1173
+ f.write(`}`);
1174
+ }
1110
1175
  } else {
1111
- const baseName = `${baseInterfaceName?.name}${baseExtension}`;
1112
- f.write(`export interface ${classBaseName} extends ${baseName} {`);
1176
+ const classBaseName = `${interfaceName.name}${baseExtension}`;
1177
+ if (countExposedChildren(members) === 0 && baseInterfaceName?.name !== "UAObject") {
1178
+ const baseName = `${baseInterfaceName?.name}${baseExtension}`;
1179
+ f.write(`export type ${classBaseName} = ${baseName};`);
1180
+ } else {
1181
+ if (baseInterfaceName?.name === "UAObject") {
1182
+ f.write(`export interface ${classBaseName} {`);
1183
+ } else {
1184
+ const baseName = `${baseInterfaceName?.name}${baseExtension}`;
1185
+ f.write(`export interface ${classBaseName} extends ${baseName} {`);
1186
+ }
1187
+ await dumpChildren(" ", members, f, cache);
1188
+ f.write(`}`);
1189
+ }
1113
1190
  }
1114
1191
  }
1115
- await dumpChildren( " ", members, f, cache);
1116
- f.write(`}`);
1117
-
1118
1192
  const baseStuff = getBaseClassWithOmit(classDef);
1119
1193
 
1120
1194
  if (nodeClass === NodeClass.VariableType) {
1121
1195
  cache.referenceBasicType("DataType");
1122
1196
  // if dataType is a extension object we can simpligy by forcing DT
1123
1197
  const className = `${interfaceName.name}${ch.chevronsDef}`;
1124
- const c = isUnspecifiedDataType(dataType) ? "<T, DT /*A*/>" : "<T /*B*/>";
1198
+ const c = isUnspecifiedDataType(dataType) ? `<T, DT${mB}>` : `<T${mC}>`;
1125
1199
  const classBaseName = `${interfaceName.name}${baseExtension}${c}`;
1126
1200
  f.write(`export interface ${className} extends ${baseStuff}, ${classBaseName} {`);
1127
1201
  } else {
@@ -1130,6 +1204,7 @@ export async function _convertTypeToTypescript(
1130
1204
  f.write(`export interface ${className} extends ${baseStuff}, ${classBaseName} {`);
1131
1205
  }
1132
1206
  f.write(`}`);
1207
+
1133
1208
  return { type: "ua", content: f.toString(), typeName: interfaceName.name };
1134
1209
  }
1135
1210