@effect-opcua/codegen 0.1.0-alpha.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/LICENSE +201 -0
- package/README.md +6 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +82 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/client/src/Opcua.d.mts +5 -0
- package/dist/client/src/OpcuaClient.d.mts +3 -0
- package/dist/client/src/OpcuaError.d.mts +139 -0
- package/dist/client/src/OpcuaError.d.mts.map +1 -0
- package/dist/client/src/OpcuaMethod.d.mts +78 -0
- package/dist/client/src/OpcuaMethod.d.mts.map +1 -0
- package/dist/client/src/OpcuaSession.d.mts +215 -0
- package/dist/client/src/OpcuaSession.d.mts.map +1 -0
- package/dist/client/src/OpcuaSubscription.d.mts +144 -0
- package/dist/client/src/OpcuaSubscription.d.mts.map +1 -0
- package/dist/client/src/OpcuaVariable.d.mts +140 -0
- package/dist/client/src/OpcuaVariable.d.mts.map +1 -0
- package/dist/client/src/index.d.mts +7 -0
- package/dist/client/src/internal/common/node-id.d.mts +1 -0
- package/dist/client/src/internal/events/model.d.mts +51 -0
- package/dist/client/src/internal/events/model.d.mts.map +1 -0
- package/dist/client/src/internal/monitoring/runtime.d.mts +7 -0
- package/dist/client/src/internal/structures/model.d.mts +18 -0
- package/dist/client/src/internal/structures/model.d.mts.map +1 -0
- package/dist/client/src/internal/structures/runtime.d.mts +5 -0
- package/dist/client/src/internal/values/codec.d.mts +21 -0
- package/dist/client/src/internal/values/codec.d.mts.map +1 -0
- package/dist/client/src/internal/values/normalize.d.mts +2 -0
- package/dist/client/src/node-opcua.d.mts +2 -0
- package/dist/compile/builtin-types.d.mts +10 -0
- package/dist/compile/builtin-types.d.mts.map +1 -0
- package/dist/compile/builtin-types.mjs +38 -0
- package/dist/compile/builtin-types.mjs.map +1 -0
- package/dist/compile/enums.d.mts +16 -0
- package/dist/compile/enums.d.mts.map +1 -0
- package/dist/compile/enums.mjs +81 -0
- package/dist/compile/enums.mjs.map +1 -0
- package/dist/compile/model.d.mts +10 -0
- package/dist/compile/model.d.mts.map +1 -0
- package/dist/compile/model.mjs +92 -0
- package/dist/compile/model.mjs.map +1 -0
- package/dist/compile/names.d.mts +17 -0
- package/dist/compile/names.d.mts.map +1 -0
- package/dist/compile/names.mjs +95 -0
- package/dist/compile/names.mjs.map +1 -0
- package/dist/compile/policy.d.mts +7 -0
- package/dist/compile/policy.d.mts.map +1 -0
- package/dist/compile/policy.mjs +6 -0
- package/dist/compile/policy.mjs.map +1 -0
- package/dist/compile/structures.d.mts +16 -0
- package/dist/compile/structures.d.mts.map +1 -0
- package/dist/compile/structures.mjs +220 -0
- package/dist/compile/structures.mjs.map +1 -0
- package/dist/compile/type-graph.d.mts +20 -0
- package/dist/compile/type-graph.d.mts.map +1 -0
- package/dist/compile/type-graph.mjs +78 -0
- package/dist/compile/type-graph.mjs.map +1 -0
- package/dist/compile/variables.d.mts +16 -0
- package/dist/compile/variables.d.mts.map +1 -0
- package/dist/compile/variables.mjs +110 -0
- package/dist/compile/variables.mjs.map +1 -0
- package/dist/compile.d.mts +9 -0
- package/dist/compile.d.mts.map +1 -0
- package/dist/compile.mjs +29 -0
- package/dist/compile.mjs.map +1 -0
- package/dist/config.d.mts +12 -0
- package/dist/config.d.mts.map +1 -0
- package/dist/config.mjs +158 -0
- package/dist/config.mjs.map +1 -0
- package/dist/diagnostics.d.mts +16 -0
- package/dist/diagnostics.d.mts.map +1 -0
- package/dist/diagnostics.mjs +45 -0
- package/dist/diagnostics.mjs.map +1 -0
- package/dist/discover.d.mts +23 -0
- package/dist/discover.d.mts.map +1 -0
- package/dist/discover.mjs +356 -0
- package/dist/discover.mjs.map +1 -0
- package/dist/emit.d.mts +8 -0
- package/dist/emit.d.mts.map +1 -0
- package/dist/emit.mjs +233 -0
- package/dist/emit.mjs.map +1 -0
- package/dist/errors.d.mts +27 -0
- package/dist/errors.d.mts.map +1 -0
- package/dist/errors.mjs +18 -0
- package/dist/errors.mjs.map +1 -0
- package/dist/generate.d.mts +19 -0
- package/dist/generate.d.mts.map +1 -0
- package/dist/generate.mjs +172 -0
- package/dist/generate.mjs.map +1 -0
- package/dist/index.d.mts +5 -0
- package/dist/index.mjs +5 -0
- package/dist/internal/types.d.mts +192 -0
- package/dist/internal/types.d.mts.map +1 -0
- package/dist/internal/types.mjs +1 -0
- package/dist/issue-codes.d.mts +119 -0
- package/dist/issue-codes.d.mts.map +1 -0
- package/dist/issue-codes.mjs +44 -0
- package/dist/issue-codes.mjs.map +1 -0
- package/dist/types.d.mts +57 -0
- package/dist/types.d.mts.map +1 -0
- package/dist/types.mjs +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { issue } from "../diagnostics.mjs";
|
|
2
|
+
import { nodeOpcuaFieldName, sanitizeCamel, sanitizePascal } from "./names.mjs";
|
|
3
|
+
import { isDynamicScalarDataType, isUnsupportedArrayRank, scalarSchema } from "./builtin-types.mjs";
|
|
4
|
+
import { typeFallbackSeverity } from "./policy.mjs";
|
|
5
|
+
|
|
6
|
+
//#region src/compile/structures.ts
|
|
7
|
+
const compileStructures = (config, definitions, enums, invalidEnums) => {
|
|
8
|
+
const issues = [];
|
|
9
|
+
const unsupportedSeverity = typeFallbackSeverity(config);
|
|
10
|
+
const rawStructures = /* @__PURE__ */ new Map();
|
|
11
|
+
const invalidStructures = /* @__PURE__ */ new Set();
|
|
12
|
+
const structureNames = /* @__PURE__ */ new Map();
|
|
13
|
+
const nameGroups = /* @__PURE__ */ new Map();
|
|
14
|
+
for (const [nodeId, definition] of definitions) {
|
|
15
|
+
if (definition._tag !== "Structure") continue;
|
|
16
|
+
rawStructures.set(nodeId, definition);
|
|
17
|
+
const name = sanitizePascal(definition.name);
|
|
18
|
+
if (!name) {
|
|
19
|
+
invalidStructures.add(nodeId);
|
|
20
|
+
issues.push(issue("structure.emptyName", {
|
|
21
|
+
severity: "error",
|
|
22
|
+
message: `Structure ${nodeId} has no usable generated name`,
|
|
23
|
+
nodeId
|
|
24
|
+
}));
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
structureNames.set(nodeId, name);
|
|
28
|
+
nameGroups.set(name, [...nameGroups.get(name) ?? [], nodeId]);
|
|
29
|
+
}
|
|
30
|
+
for (const [name, nodeIds] of nameGroups) if (nodeIds.length > 1) {
|
|
31
|
+
for (const nodeId of nodeIds) invalidStructures.add(nodeId);
|
|
32
|
+
issues.push(issue("structure.nameCollision", {
|
|
33
|
+
severity: "error",
|
|
34
|
+
message: `Multiple structure DataTypes generate ${name}`,
|
|
35
|
+
generatedPath: [name],
|
|
36
|
+
cause: { candidates: nodeIds }
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
for (const [nodeId, definition] of rawStructures) {
|
|
40
|
+
const name = structureNames.get(nodeId) ?? nodeId;
|
|
41
|
+
if (definition.structureType === "Union") {
|
|
42
|
+
invalidStructures.add(nodeId);
|
|
43
|
+
issues.push(issue("datatype.unionUnsupported", {
|
|
44
|
+
severity: unsupportedSeverity,
|
|
45
|
+
message: `Union DataType ${name} is not generated`,
|
|
46
|
+
nodeId,
|
|
47
|
+
generatedPath: [name]
|
|
48
|
+
}));
|
|
49
|
+
}
|
|
50
|
+
if (definition.structureType === "Unknown") {
|
|
51
|
+
invalidStructures.add(nodeId);
|
|
52
|
+
issues.push(issue("datatype.definitionUnsupported", {
|
|
53
|
+
severity: unsupportedSeverity,
|
|
54
|
+
message: `Structure DataType ${name} has unsupported structure type`,
|
|
55
|
+
nodeId,
|
|
56
|
+
generatedPath: [name]
|
|
57
|
+
}));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const validFieldNames = /* @__PURE__ */ new Map();
|
|
61
|
+
for (const [nodeId, definition] of rawStructures) {
|
|
62
|
+
if (invalidStructures.has(nodeId)) continue;
|
|
63
|
+
const name = structureNames.get(nodeId);
|
|
64
|
+
const generatedNames = /* @__PURE__ */ new Map();
|
|
65
|
+
const fieldNames = [];
|
|
66
|
+
for (const [index, field] of definition.fields.entries()) {
|
|
67
|
+
let fieldName = sanitizeCamel(field.name);
|
|
68
|
+
if (!fieldName) {
|
|
69
|
+
fieldName = `_field${index + 1}`;
|
|
70
|
+
issues.push(issue("structure.fieldEmptyName", {
|
|
71
|
+
message: `Structure ${name} has a field without a usable generated name`,
|
|
72
|
+
nodeId,
|
|
73
|
+
generatedPath: [name, fieldName]
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
generatedNames.set(fieldName, [...generatedNames.get(fieldName) ?? [], field.name]);
|
|
77
|
+
fieldNames.push(fieldName);
|
|
78
|
+
}
|
|
79
|
+
const collision = [...generatedNames].find(([, candidates]) => candidates.length > 1);
|
|
80
|
+
if (collision) {
|
|
81
|
+
invalidStructures.add(nodeId);
|
|
82
|
+
issues.push(issue("structure.fieldNameCollision", {
|
|
83
|
+
severity: "error",
|
|
84
|
+
message: `Structure ${name} has colliding generated field ${collision[0]}`,
|
|
85
|
+
nodeId,
|
|
86
|
+
generatedPath: [name, collision[0]],
|
|
87
|
+
cause: { candidates: collision[1] }
|
|
88
|
+
}));
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
validFieldNames.set(nodeId, fieldNames);
|
|
92
|
+
}
|
|
93
|
+
const recursiveFields = recursiveStructureFields(rawStructures);
|
|
94
|
+
const structures = /* @__PURE__ */ new Map();
|
|
95
|
+
for (const [nodeId, definition] of rawStructures) {
|
|
96
|
+
if (invalidStructures.has(nodeId)) continue;
|
|
97
|
+
const name = structureNames.get(nodeId);
|
|
98
|
+
const fieldNames = validFieldNames.get(nodeId);
|
|
99
|
+
const fields = definition.fields.map((field, index) => {
|
|
100
|
+
const fieldName = fieldNames[index];
|
|
101
|
+
const recursive = recursiveFields.get(nodeId)?.has(field.dataTypeNodeId);
|
|
102
|
+
if (recursive) issues.push(issue("structure.recursiveField", {
|
|
103
|
+
severity: unsupportedSeverity,
|
|
104
|
+
message: `Structure ${name} has recursive field ${field.name}`,
|
|
105
|
+
nodeId,
|
|
106
|
+
generatedPath: [name, fieldName]
|
|
107
|
+
}));
|
|
108
|
+
return {
|
|
109
|
+
name: fieldName,
|
|
110
|
+
encodedName: nodeOpcuaFieldName(field.name),
|
|
111
|
+
originalName: field.name,
|
|
112
|
+
optional: field.isOptional === true,
|
|
113
|
+
schema: recursive ? { _tag: "Unknown" } : fieldSchema({
|
|
114
|
+
ownerNodeId: nodeId,
|
|
115
|
+
fieldNodeId: field.dataTypeNodeId,
|
|
116
|
+
valueRank: field.valueRank,
|
|
117
|
+
definitions,
|
|
118
|
+
rawStructures,
|
|
119
|
+
structureNames,
|
|
120
|
+
invalidStructures,
|
|
121
|
+
enums,
|
|
122
|
+
invalidEnums,
|
|
123
|
+
issues,
|
|
124
|
+
unsupportedSeverity
|
|
125
|
+
})
|
|
126
|
+
};
|
|
127
|
+
});
|
|
128
|
+
structures.set(nodeId, {
|
|
129
|
+
name,
|
|
130
|
+
dataTypeNodeId: nodeId,
|
|
131
|
+
browseName: definition.name,
|
|
132
|
+
fields
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
structures,
|
|
137
|
+
invalidStructures,
|
|
138
|
+
issues
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
const fieldSchema = (input) => {
|
|
142
|
+
if (isUnsupportedArrayRank(input.valueRank)) {
|
|
143
|
+
input.issues.push(issue("structure.unsupportedField", {
|
|
144
|
+
severity: input.unsupportedSeverity,
|
|
145
|
+
message: `Structure field has unsupported array rank ${input.valueRank}`,
|
|
146
|
+
nodeId: input.ownerNodeId
|
|
147
|
+
}));
|
|
148
|
+
return { _tag: "Unknown" };
|
|
149
|
+
}
|
|
150
|
+
const isArray = input.valueRank === 1;
|
|
151
|
+
const wrapArray = (schema) => isArray ? {
|
|
152
|
+
_tag: "Array",
|
|
153
|
+
item: schema
|
|
154
|
+
} : schema;
|
|
155
|
+
const scalar = scalarSchema(input.fieldNodeId);
|
|
156
|
+
if (scalar) return wrapArray({
|
|
157
|
+
_tag: "Scalar",
|
|
158
|
+
schema: scalar
|
|
159
|
+
});
|
|
160
|
+
const enumDefinition = input.enums.get(input.fieldNodeId);
|
|
161
|
+
if (enumDefinition) return wrapArray({
|
|
162
|
+
_tag: "Enum",
|
|
163
|
+
name: enumDefinition.name
|
|
164
|
+
});
|
|
165
|
+
if (input.invalidEnums.has(input.fieldNodeId)) return wrapArray({
|
|
166
|
+
_tag: "Scalar",
|
|
167
|
+
schema: "Number"
|
|
168
|
+
});
|
|
169
|
+
const structureName = input.structureNames.get(input.fieldNodeId);
|
|
170
|
+
if (structureName && !input.invalidStructures.has(input.fieldNodeId)) return wrapArray({
|
|
171
|
+
_tag: "Structure",
|
|
172
|
+
name: structureName
|
|
173
|
+
});
|
|
174
|
+
if (isDynamicScalarDataType(input.fieldNodeId)) {
|
|
175
|
+
input.issues.push(issue("structure.unsupportedField", {
|
|
176
|
+
severity: input.unsupportedSeverity,
|
|
177
|
+
message: `Structure field references dynamic scalar DataType ${input.fieldNodeId}`,
|
|
178
|
+
nodeId: input.ownerNodeId
|
|
179
|
+
}));
|
|
180
|
+
return wrapArray({ _tag: "Unknown" });
|
|
181
|
+
}
|
|
182
|
+
if (input.rawStructures.get(input.fieldNodeId)?.structureType === "Union" || input.invalidStructures.has(input.fieldNodeId)) {
|
|
183
|
+
input.issues.push(issue("structure.unsupportedField", {
|
|
184
|
+
severity: input.unsupportedSeverity,
|
|
185
|
+
message: `Structure field references unsupported DataType ${input.fieldNodeId}`,
|
|
186
|
+
nodeId: input.ownerNodeId
|
|
187
|
+
}));
|
|
188
|
+
return { _tag: "Unknown" };
|
|
189
|
+
}
|
|
190
|
+
if (!input.definitions.has(input.fieldNodeId)) input.issues.push(issue("structure.unsupportedField", {
|
|
191
|
+
severity: input.unsupportedSeverity,
|
|
192
|
+
message: `Structure field references DataType without definition ${input.fieldNodeId}`,
|
|
193
|
+
nodeId: input.ownerNodeId
|
|
194
|
+
}));
|
|
195
|
+
return { _tag: "Unknown" };
|
|
196
|
+
};
|
|
197
|
+
const recursiveStructureFields = (structures) => {
|
|
198
|
+
const result = /* @__PURE__ */ new Map();
|
|
199
|
+
const dependencies = /* @__PURE__ */ new Map();
|
|
200
|
+
for (const [nodeId, structure] of structures) dependencies.set(nodeId, structure.fields.map((field) => field.dataTypeNodeId).filter((fieldNodeId) => structures.has(fieldNodeId)));
|
|
201
|
+
for (const [nodeId, structure] of structures) for (const field of structure.fields) {
|
|
202
|
+
if (!structures.has(field.dataTypeNodeId)) continue;
|
|
203
|
+
if (reaches(field.dataTypeNodeId, nodeId, dependencies, /* @__PURE__ */ new Set())) {
|
|
204
|
+
const set = result.get(nodeId) ?? /* @__PURE__ */ new Set();
|
|
205
|
+
set.add(field.dataTypeNodeId);
|
|
206
|
+
result.set(nodeId, set);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return result;
|
|
210
|
+
};
|
|
211
|
+
const reaches = (current, target, dependencies, seen) => {
|
|
212
|
+
if (current === target) return true;
|
|
213
|
+
if (seen.has(current)) return false;
|
|
214
|
+
seen.add(current);
|
|
215
|
+
return (dependencies.get(current) ?? []).some((next) => reaches(next, target, dependencies, seen));
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
//#endregion
|
|
219
|
+
export { compileStructures };
|
|
220
|
+
//# sourceMappingURL=structures.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structures.mjs","names":["issues: CodegenIssue[]","fieldNames: string[]","fields: StructureFieldDefinition[]"],"sources":["../../src/compile/structures.ts"],"sourcesContent":["import type { OpcuaSession } from \"@effect-opcua/client\";\n\nimport { issue } from \"../diagnostics.js\";\nimport type { CodegenIssue } from \"../types.js\";\nimport type {\n EnumDefinition,\n NormalizedCodegenConfig,\n SchemaExpression,\n StructureDefinition,\n StructureFieldDefinition,\n} from \"../internal/types.js\";\nimport {\n isDynamicScalarDataType,\n isUnsupportedArrayRank,\n scalarSchema,\n} from \"./builtin-types.js\";\nimport { nodeOpcuaFieldName, sanitizeCamel, sanitizePascal } from \"./names.js\";\nimport { typeFallbackSeverity } from \"./policy.js\";\n\ntype OpcuaDataTypeDefinition = OpcuaSession.OpcuaDataTypeDefinition;\ntype OpcuaStructureDefinition = OpcuaSession.OpcuaStructureDefinition;\n\nexport type StructureGraph = {\n readonly structures: ReadonlyMap<string, StructureDefinition>;\n readonly invalidStructures: ReadonlySet<string>;\n readonly issues: readonly CodegenIssue[];\n};\n\nexport const compileStructures = (\n config: NormalizedCodegenConfig,\n definitions: ReadonlyMap<string, OpcuaDataTypeDefinition>,\n enums: ReadonlyMap<string, EnumDefinition>,\n invalidEnums: ReadonlySet<string>,\n): StructureGraph => {\n const issues: CodegenIssue[] = [];\n const unsupportedSeverity = typeFallbackSeverity(config);\n const rawStructures = new Map<string, OpcuaStructureDefinition>();\n const invalidStructures = new Set<string>();\n const structureNames = new Map<string, string>();\n const nameGroups = new Map<string, string[]>();\n\n for (const [nodeId, definition] of definitions) {\n if (definition._tag !== \"Structure\") continue;\n rawStructures.set(nodeId, definition);\n const name = sanitizePascal(definition.name);\n if (!name) {\n invalidStructures.add(nodeId);\n issues.push(\n issue(\"structure.emptyName\", {\n severity: \"error\",\n message: `Structure ${nodeId} has no usable generated name`,\n nodeId,\n }),\n );\n continue;\n }\n structureNames.set(nodeId, name);\n nameGroups.set(name, [...(nameGroups.get(name) ?? []), nodeId]);\n }\n\n for (const [name, nodeIds] of nameGroups) {\n if (nodeIds.length > 1) {\n for (const nodeId of nodeIds) invalidStructures.add(nodeId);\n issues.push(\n issue(\"structure.nameCollision\", {\n severity: \"error\",\n message: `Multiple structure DataTypes generate ${name}`,\n generatedPath: [name],\n cause: { candidates: nodeIds },\n }),\n );\n }\n }\n\n for (const [nodeId, definition] of rawStructures) {\n const name = structureNames.get(nodeId) ?? nodeId;\n if (definition.structureType === \"Union\") {\n invalidStructures.add(nodeId);\n issues.push(\n issue(\"datatype.unionUnsupported\", {\n severity: unsupportedSeverity,\n message: `Union DataType ${name} is not generated`,\n nodeId,\n generatedPath: [name],\n }),\n );\n }\n if (definition.structureType === \"Unknown\") {\n invalidStructures.add(nodeId);\n issues.push(\n issue(\"datatype.definitionUnsupported\", {\n severity: unsupportedSeverity,\n message: `Structure DataType ${name} has unsupported structure type`,\n nodeId,\n generatedPath: [name],\n }),\n );\n }\n }\n\n const validFieldNames = new Map<string, readonly string[]>();\n for (const [nodeId, definition] of rawStructures) {\n if (invalidStructures.has(nodeId)) continue;\n const name = structureNames.get(nodeId)!;\n const generatedNames = new Map<string, string[]>();\n const fieldNames: string[] = [];\n for (const [index, field] of definition.fields.entries()) {\n let fieldName = sanitizeCamel(field.name);\n if (!fieldName) {\n fieldName = `_field${index + 1}`;\n issues.push(\n issue(\"structure.fieldEmptyName\", {\n message: `Structure ${name} has a field without a usable generated name`,\n nodeId,\n generatedPath: [name, fieldName],\n }),\n );\n }\n generatedNames.set(fieldName, [\n ...(generatedNames.get(fieldName) ?? []),\n field.name,\n ]);\n fieldNames.push(fieldName);\n }\n const collision = [...generatedNames].find(\n ([, candidates]) => candidates.length > 1,\n );\n if (collision) {\n invalidStructures.add(nodeId);\n issues.push(\n issue(\"structure.fieldNameCollision\", {\n severity: \"error\",\n message: `Structure ${name} has colliding generated field ${collision[0]}`,\n nodeId,\n generatedPath: [name, collision[0]],\n cause: { candidates: collision[1] },\n }),\n );\n continue;\n }\n validFieldNames.set(nodeId, fieldNames);\n }\n\n const recursiveFields = recursiveStructureFields(rawStructures);\n const structures = new Map<string, StructureDefinition>();\n for (const [nodeId, definition] of rawStructures) {\n if (invalidStructures.has(nodeId)) continue;\n const name = structureNames.get(nodeId)!;\n const fieldNames = validFieldNames.get(nodeId)!;\n const fields: StructureFieldDefinition[] = definition.fields.map(\n (field, index) => {\n const fieldName = fieldNames[index]!;\n const recursive = recursiveFields\n .get(nodeId)\n ?.has(field.dataTypeNodeId);\n if (recursive) {\n issues.push(\n issue(\"structure.recursiveField\", {\n severity: unsupportedSeverity,\n message: `Structure ${name} has recursive field ${field.name}`,\n nodeId,\n generatedPath: [name, fieldName],\n }),\n );\n }\n return {\n name: fieldName,\n encodedName: nodeOpcuaFieldName(field.name),\n originalName: field.name,\n optional: field.isOptional === true,\n schema: recursive\n ? { _tag: \"Unknown\" }\n : fieldSchema({\n ownerNodeId: nodeId,\n fieldNodeId: field.dataTypeNodeId,\n valueRank: field.valueRank,\n definitions,\n rawStructures,\n structureNames,\n invalidStructures,\n enums,\n invalidEnums,\n issues,\n unsupportedSeverity,\n }),\n };\n },\n );\n structures.set(nodeId, {\n name,\n dataTypeNodeId: nodeId,\n browseName: definition.name,\n fields,\n });\n }\n\n return { structures, invalidStructures, issues };\n};\n\nconst fieldSchema = (input: {\n readonly ownerNodeId: string;\n readonly fieldNodeId: string;\n readonly valueRank?: number;\n readonly definitions: ReadonlyMap<string, OpcuaDataTypeDefinition>;\n readonly rawStructures: ReadonlyMap<string, OpcuaStructureDefinition>;\n readonly structureNames: ReadonlyMap<string, string>;\n readonly invalidStructures: ReadonlySet<string>;\n readonly enums: ReadonlyMap<string, EnumDefinition>;\n readonly invalidEnums: ReadonlySet<string>;\n readonly issues: CodegenIssue[];\n readonly unsupportedSeverity: \"error\" | \"warning\";\n}): SchemaExpression => {\n if (isUnsupportedArrayRank(input.valueRank)) {\n input.issues.push(\n issue(\"structure.unsupportedField\", {\n severity: input.unsupportedSeverity,\n message: `Structure field has unsupported array rank ${input.valueRank}`,\n nodeId: input.ownerNodeId,\n }),\n );\n return { _tag: \"Unknown\" };\n }\n\n const isArray = input.valueRank === 1;\n const wrapArray = (\n schema: Exclude<SchemaExpression, { readonly _tag: \"Array\" }>,\n ) => (isArray ? ({ _tag: \"Array\", item: schema } as const) : schema);\n const scalar = scalarSchema(input.fieldNodeId);\n if (scalar) return wrapArray({ _tag: \"Scalar\", schema: scalar });\n\n const enumDefinition = input.enums.get(input.fieldNodeId);\n if (enumDefinition) {\n return wrapArray({ _tag: \"Enum\", name: enumDefinition.name });\n }\n if (input.invalidEnums.has(input.fieldNodeId)) {\n return wrapArray({ _tag: \"Scalar\", schema: \"Number\" });\n }\n\n const structureName = input.structureNames.get(input.fieldNodeId);\n if (structureName && !input.invalidStructures.has(input.fieldNodeId)) {\n return wrapArray({ _tag: \"Structure\", name: structureName });\n }\n\n if (isDynamicScalarDataType(input.fieldNodeId)) {\n input.issues.push(\n issue(\"structure.unsupportedField\", {\n severity: input.unsupportedSeverity,\n message: `Structure field references dynamic scalar DataType ${input.fieldNodeId}`,\n nodeId: input.ownerNodeId,\n }),\n );\n return wrapArray({ _tag: \"Unknown\" });\n }\n\n if (\n input.rawStructures.get(input.fieldNodeId)?.structureType === \"Union\" ||\n input.invalidStructures.has(input.fieldNodeId)\n ) {\n input.issues.push(\n issue(\"structure.unsupportedField\", {\n severity: input.unsupportedSeverity,\n message: `Structure field references unsupported DataType ${input.fieldNodeId}`,\n nodeId: input.ownerNodeId,\n }),\n );\n return { _tag: \"Unknown\" };\n }\n\n if (!input.definitions.has(input.fieldNodeId)) {\n input.issues.push(\n issue(\"structure.unsupportedField\", {\n severity: input.unsupportedSeverity,\n message: `Structure field references DataType without definition ${input.fieldNodeId}`,\n nodeId: input.ownerNodeId,\n }),\n );\n }\n return { _tag: \"Unknown\" };\n};\n\nconst recursiveStructureFields = (\n structures: ReadonlyMap<string, OpcuaStructureDefinition>,\n) => {\n const result = new Map<string, Set<string>>();\n const dependencies = new Map<string, readonly string[]>();\n for (const [nodeId, structure] of structures) {\n dependencies.set(\n nodeId,\n structure.fields\n .map((field) => field.dataTypeNodeId)\n .filter((fieldNodeId) => structures.has(fieldNodeId)),\n );\n }\n for (const [nodeId, structure] of structures) {\n for (const field of structure.fields) {\n if (!structures.has(field.dataTypeNodeId)) continue;\n if (reaches(field.dataTypeNodeId, nodeId, dependencies, new Set())) {\n const set = result.get(nodeId) ?? new Set<string>();\n set.add(field.dataTypeNodeId);\n result.set(nodeId, set);\n }\n }\n }\n return result;\n};\n\nconst reaches = (\n current: string,\n target: string,\n dependencies: ReadonlyMap<string, readonly string[]>,\n seen: Set<string>,\n): boolean => {\n if (current === target) return true;\n if (seen.has(current)) return false;\n seen.add(current);\n return (dependencies.get(current) ?? []).some((next) =>\n reaches(next, target, dependencies, seen),\n );\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { CodegenIssue } from "../types.mjs";
|
|
2
|
+
import { OpcuaDataTypeDefinitionResult as OpcuaDataTypeDefinitionResult$1 } from "../client/src/OpcuaSession.mjs";
|
|
3
|
+
import "../client/src/index.mjs";
|
|
4
|
+
import { EnumDefinition, NormalizedCodegenConfig, StructureDefinition } from "../internal/types.mjs";
|
|
5
|
+
import { SurfaceNode } from "./names.mjs";
|
|
6
|
+
|
|
7
|
+
//#region src/compile/type-graph.d.ts
|
|
8
|
+
type OpcuaDataTypeDefinitionResult = OpcuaDataTypeDefinitionResult$1;
|
|
9
|
+
type TypeGraph = {
|
|
10
|
+
readonly enums: ReadonlyMap<string, EnumDefinition>;
|
|
11
|
+
readonly structures: ReadonlyMap<string, StructureDefinition>;
|
|
12
|
+
readonly invalidEnums: ReadonlySet<string>;
|
|
13
|
+
readonly invalidStructures: ReadonlySet<string>;
|
|
14
|
+
readonly issues: readonly CodegenIssue[];
|
|
15
|
+
};
|
|
16
|
+
declare const compileReachableTypes: (config: NormalizedCodegenConfig, variableNodes: readonly SurfaceNode[], dataTypeResults: ReadonlyMap<string, OpcuaDataTypeDefinitionResult>) => TypeGraph;
|
|
17
|
+
declare const dataTypeResultMap: (results: readonly OpcuaDataTypeDefinitionResult[]) => Map<string, OpcuaDataTypeDefinitionResult$1>;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { TypeGraph, compileReachableTypes, dataTypeResultMap };
|
|
20
|
+
//# sourceMappingURL=type-graph.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-graph.d.mts","names":[],"sources":["../../src/compile/type-graph.ts"],"sourcesContent":[],"mappings":";;;;;;;KAgBK,6BAAA,GAAgC;KAEzB,SAAA;kBACM,oBAAoB;EAHjC,SAAA,UAAA,EAIkB,WAJW,CAAA,MAAA,EAIS,mBAJN,CAAA;EAEzB,SAAA,YAAS,EAGI,WAHJ,CAAA,MAAA,CAAA;EACiB,SAAA,iBAAA,EAGR,WAHQ,CAAA,MAAA,CAAA;EAApB,SAAA,MAAA,EAAA,SAIU,YAJV,EAAA;CACyB;AAApB,cAMV,qBANU,EAAA,CAAA,MAAA,EAOb,uBAPa,EAAA,aAAA,EAAA,SAQG,WARH,EAAA,EAAA,eAAA,EASJ,WATI,CAAA,MAAA,EASgB,6BAThB,CAAA,EAAA,GAUpB,SAVoB;AACE,cAiCZ,iBAjCY,EAAA,CAAA,OAAA,EAAA,SAkCL,6BAlCK,EAAA,EAAA,GAkC0B,GAlC1B,CAAA,MAAA,EAkC0B,+BAlC1B,CAAA"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { issue } from "../diagnostics.mjs";
|
|
2
|
+
import { requiresDataTypeDefinition } from "./builtin-types.mjs";
|
|
3
|
+
import { compileEnums } from "./enums.mjs";
|
|
4
|
+
import { typeFallbackSeverity } from "./policy.mjs";
|
|
5
|
+
import { compileStructures } from "./structures.mjs";
|
|
6
|
+
|
|
7
|
+
//#region src/compile/type-graph.ts
|
|
8
|
+
const compileReachableTypes = (config, variableNodes, dataTypeResults) => {
|
|
9
|
+
const issues = [];
|
|
10
|
+
const rawDefinitions = reachableDefinitions(config, variableNodes, dataTypeResults, issues);
|
|
11
|
+
const enumGraph = compileEnums(rawDefinitions);
|
|
12
|
+
const structureGraph = compileStructures(config, rawDefinitions, enumGraph.enums, enumGraph.invalidEnums);
|
|
13
|
+
return {
|
|
14
|
+
enums: enumGraph.enums,
|
|
15
|
+
structures: structureGraph.structures,
|
|
16
|
+
invalidEnums: enumGraph.invalidEnums,
|
|
17
|
+
invalidStructures: structureGraph.invalidStructures,
|
|
18
|
+
issues: [
|
|
19
|
+
...issues,
|
|
20
|
+
...enumGraph.issues,
|
|
21
|
+
...structureGraph.issues
|
|
22
|
+
]
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
const dataTypeResultMap = (results) => new Map(results.map((result) => [result.dataTypeNodeId, result]));
|
|
26
|
+
const reachableDefinitions = (config, variableNodes, dataTypeResults, issues) => {
|
|
27
|
+
const unsupportedSeverity = typeFallbackSeverity(config);
|
|
28
|
+
const queue = variableNodes.flatMap((item) => item.node.dataTypeNodeId !== void 0 ? [item.node.dataTypeNodeId] : []).filter(requiresDataTypeDefinition);
|
|
29
|
+
const seen = /* @__PURE__ */ new Set();
|
|
30
|
+
const definitions = /* @__PURE__ */ new Map();
|
|
31
|
+
while (queue.length > 0) {
|
|
32
|
+
const dataTypeNodeId = queue.shift();
|
|
33
|
+
if (seen.has(dataTypeNodeId)) continue;
|
|
34
|
+
seen.add(dataTypeNodeId);
|
|
35
|
+
const result = dataTypeResults.get(dataTypeNodeId);
|
|
36
|
+
if (!result) {
|
|
37
|
+
issues.push(issue("datatype.definitionMissing", {
|
|
38
|
+
severity: unsupportedSeverity,
|
|
39
|
+
message: `Missing DataTypeDefinition for ${dataTypeNodeId}`,
|
|
40
|
+
nodeId: dataTypeNodeId
|
|
41
|
+
}));
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (result._tag === "Missing") {
|
|
45
|
+
issues.push(issue("datatype.definitionMissing", {
|
|
46
|
+
severity: unsupportedSeverity,
|
|
47
|
+
message: `Missing DataTypeDefinition for ${dataTypeNodeId}: ${result.reason}`,
|
|
48
|
+
nodeId: dataTypeNodeId
|
|
49
|
+
}));
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (result._tag === "Unsupported") {
|
|
53
|
+
issues.push(issue("datatype.definitionUnsupported", {
|
|
54
|
+
severity: unsupportedSeverity,
|
|
55
|
+
message: `Unsupported DataTypeDefinition for ${dataTypeNodeId}: ${result.reason}`,
|
|
56
|
+
nodeId: dataTypeNodeId
|
|
57
|
+
}));
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (result._tag === "Failure") {
|
|
61
|
+
issues.push(issue("datatype.definitionFailure", {
|
|
62
|
+
severity: unsupportedSeverity,
|
|
63
|
+
message: `Failed to read DataTypeDefinition for ${dataTypeNodeId}: ${result.reason}`,
|
|
64
|
+
nodeId: dataTypeNodeId
|
|
65
|
+
}));
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
definitions.set(dataTypeNodeId, result.definition);
|
|
69
|
+
if (result.definition._tag === "Structure") {
|
|
70
|
+
for (const field of result.definition.fields) if (requiresDataTypeDefinition(field.dataTypeNodeId)) queue.push(field.dataTypeNodeId);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return definitions;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
//#endregion
|
|
77
|
+
export { compileReachableTypes, dataTypeResultMap };
|
|
78
|
+
//# sourceMappingURL=type-graph.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-graph.mjs","names":["issues: CodegenIssue[]"],"sources":["../../src/compile/type-graph.ts"],"sourcesContent":["import type { OpcuaSession } from \"@effect-opcua/client\";\n\nimport { issue } from \"../diagnostics.js\";\nimport type { CodegenIssue } from \"../types.js\";\nimport type {\n EnumDefinition,\n NormalizedCodegenConfig,\n StructureDefinition,\n} from \"../internal/types.js\";\nimport { requiresDataTypeDefinition } from \"./builtin-types.js\";\nimport { compileEnums } from \"./enums.js\";\nimport type { SurfaceNode } from \"./names.js\";\nimport { typeFallbackSeverity } from \"./policy.js\";\nimport { compileStructures } from \"./structures.js\";\n\ntype OpcuaDataTypeDefinition = OpcuaSession.OpcuaDataTypeDefinition;\ntype OpcuaDataTypeDefinitionResult = OpcuaSession.OpcuaDataTypeDefinitionResult;\n\nexport type TypeGraph = {\n readonly enums: ReadonlyMap<string, EnumDefinition>;\n readonly structures: ReadonlyMap<string, StructureDefinition>;\n readonly invalidEnums: ReadonlySet<string>;\n readonly invalidStructures: ReadonlySet<string>;\n readonly issues: readonly CodegenIssue[];\n};\n\nexport const compileReachableTypes = (\n config: NormalizedCodegenConfig,\n variableNodes: readonly SurfaceNode[],\n dataTypeResults: ReadonlyMap<string, OpcuaDataTypeDefinitionResult>,\n): TypeGraph => {\n const issues: CodegenIssue[] = [];\n const rawDefinitions = reachableDefinitions(\n config,\n variableNodes,\n dataTypeResults,\n issues,\n );\n const enumGraph = compileEnums(rawDefinitions);\n const structureGraph = compileStructures(\n config,\n rawDefinitions,\n enumGraph.enums,\n enumGraph.invalidEnums,\n );\n return {\n enums: enumGraph.enums,\n structures: structureGraph.structures,\n invalidEnums: enumGraph.invalidEnums,\n invalidStructures: structureGraph.invalidStructures,\n issues: [...issues, ...enumGraph.issues, ...structureGraph.issues],\n };\n};\n\nexport const dataTypeResultMap = (\n results: readonly OpcuaDataTypeDefinitionResult[],\n) => new Map(results.map((result) => [result.dataTypeNodeId, result]));\n\nconst reachableDefinitions = (\n config: NormalizedCodegenConfig,\n variableNodes: readonly SurfaceNode[],\n dataTypeResults: ReadonlyMap<string, OpcuaDataTypeDefinitionResult>,\n issues: CodegenIssue[],\n): ReadonlyMap<string, OpcuaDataTypeDefinition> => {\n const unsupportedSeverity = typeFallbackSeverity(config);\n const queue = variableNodes\n .flatMap((item) =>\n item.node.dataTypeNodeId !== undefined ? [item.node.dataTypeNodeId] : [],\n )\n .filter(requiresDataTypeDefinition);\n const seen = new Set<string>();\n const definitions = new Map<string, OpcuaDataTypeDefinition>();\n\n while (queue.length > 0) {\n const dataTypeNodeId = queue.shift()!;\n if (seen.has(dataTypeNodeId)) continue;\n seen.add(dataTypeNodeId);\n const result = dataTypeResults.get(dataTypeNodeId);\n if (!result) {\n issues.push(\n issue(\"datatype.definitionMissing\", {\n severity: unsupportedSeverity,\n message: `Missing DataTypeDefinition for ${dataTypeNodeId}`,\n nodeId: dataTypeNodeId,\n }),\n );\n continue;\n }\n if (result._tag === \"Missing\") {\n issues.push(\n issue(\"datatype.definitionMissing\", {\n severity: unsupportedSeverity,\n message: `Missing DataTypeDefinition for ${dataTypeNodeId}: ${result.reason}`,\n nodeId: dataTypeNodeId,\n }),\n );\n continue;\n }\n if (result._tag === \"Unsupported\") {\n issues.push(\n issue(\"datatype.definitionUnsupported\", {\n severity: unsupportedSeverity,\n message: `Unsupported DataTypeDefinition for ${dataTypeNodeId}: ${result.reason}`,\n nodeId: dataTypeNodeId,\n }),\n );\n continue;\n }\n if (result._tag === \"Failure\") {\n issues.push(\n issue(\"datatype.definitionFailure\", {\n severity: unsupportedSeverity,\n message: `Failed to read DataTypeDefinition for ${dataTypeNodeId}: ${result.reason}`,\n nodeId: dataTypeNodeId,\n }),\n );\n continue;\n }\n definitions.set(dataTypeNodeId, result.definition);\n if (result.definition._tag === \"Structure\") {\n for (const field of result.definition.fields) {\n if (requiresDataTypeDefinition(field.dataTypeNodeId)) {\n queue.push(field.dataTypeNodeId);\n }\n }\n }\n }\n\n return definitions;\n};\n"],"mappings":";;;;;;;AA0BA,MAAa,yBACX,QACA,eACA,oBACc;CACd,MAAMA,SAAyB,EAAE;CACjC,MAAM,iBAAiB,qBACrB,QACA,eACA,iBACA,OACD;CACD,MAAM,YAAY,aAAa,eAAe;CAC9C,MAAM,iBAAiB,kBACrB,QACA,gBACA,UAAU,OACV,UAAU,aACX;AACD,QAAO;EACL,OAAO,UAAU;EACjB,YAAY,eAAe;EAC3B,cAAc,UAAU;EACxB,mBAAmB,eAAe;EAClC,QAAQ;GAAC,GAAG;GAAQ,GAAG,UAAU;GAAQ,GAAG,eAAe;GAAO;EACnE;;AAGH,MAAa,qBACX,YACG,IAAI,IAAI,QAAQ,KAAK,WAAW,CAAC,OAAO,gBAAgB,OAAO,CAAC,CAAC;AAEtE,MAAM,wBACJ,QACA,eACA,iBACA,WACiD;CACjD,MAAM,sBAAsB,qBAAqB,OAAO;CACxD,MAAM,QAAQ,cACX,SAAS,SACR,KAAK,KAAK,mBAAmB,SAAY,CAAC,KAAK,KAAK,eAAe,GAAG,EAAE,CACzE,CACA,OAAO,2BAA2B;CACrC,MAAM,uBAAO,IAAI,KAAa;CAC9B,MAAM,8BAAc,IAAI,KAAsC;AAE9D,QAAO,MAAM,SAAS,GAAG;EACvB,MAAM,iBAAiB,MAAM,OAAO;AACpC,MAAI,KAAK,IAAI,eAAe,CAAE;AAC9B,OAAK,IAAI,eAAe;EACxB,MAAM,SAAS,gBAAgB,IAAI,eAAe;AAClD,MAAI,CAAC,QAAQ;AACX,UAAO,KACL,MAAM,8BAA8B;IAClC,UAAU;IACV,SAAS,kCAAkC;IAC3C,QAAQ;IACT,CAAC,CACH;AACD;;AAEF,MAAI,OAAO,SAAS,WAAW;AAC7B,UAAO,KACL,MAAM,8BAA8B;IAClC,UAAU;IACV,SAAS,kCAAkC,eAAe,IAAI,OAAO;IACrE,QAAQ;IACT,CAAC,CACH;AACD;;AAEF,MAAI,OAAO,SAAS,eAAe;AACjC,UAAO,KACL,MAAM,kCAAkC;IACtC,UAAU;IACV,SAAS,sCAAsC,eAAe,IAAI,OAAO;IACzE,QAAQ;IACT,CAAC,CACH;AACD;;AAEF,MAAI,OAAO,SAAS,WAAW;AAC7B,UAAO,KACL,MAAM,8BAA8B;IAClC,UAAU;IACV,SAAS,yCAAyC,eAAe,IAAI,OAAO;IAC5E,QAAQ;IACT,CAAC,CACH;AACD;;AAEF,cAAY,IAAI,gBAAgB,OAAO,WAAW;AAClD,MAAI,OAAO,WAAW,SAAS,aAC7B;QAAK,MAAM,SAAS,OAAO,WAAW,OACpC,KAAI,2BAA2B,MAAM,eAAe,CAClD,OAAM,KAAK,MAAM,eAAe;;;AAMxC,QAAO"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { CodegenIssue } from "../types.mjs";
|
|
2
|
+
import { OpcuaDataTypeDefinitionResult as OpcuaDataTypeDefinitionResult$1 } from "../client/src/OpcuaSession.mjs";
|
|
3
|
+
import "../client/src/index.mjs";
|
|
4
|
+
import { NormalizedCodegenConfig, VariableDefinition } from "../internal/types.mjs";
|
|
5
|
+
import { SurfaceNode } from "./names.mjs";
|
|
6
|
+
import { TypeGraph } from "./type-graph.mjs";
|
|
7
|
+
|
|
8
|
+
//#region src/compile/variables.d.ts
|
|
9
|
+
type OpcuaDataTypeDefinitionResult = OpcuaDataTypeDefinitionResult$1;
|
|
10
|
+
declare const compileVariables: (config: NormalizedCodegenConfig, variableNodes: readonly SurfaceNode[], typeGraph: TypeGraph, dataTypeResults: ReadonlyMap<string, OpcuaDataTypeDefinitionResult>) => {
|
|
11
|
+
variables: VariableDefinition[];
|
|
12
|
+
issues: CodegenIssue[];
|
|
13
|
+
};
|
|
14
|
+
//#endregion
|
|
15
|
+
export { compileVariables };
|
|
16
|
+
//# sourceMappingURL=variables.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variables.d.mts","names":[],"sources":["../../src/compile/variables.ts"],"sourcesContent":[],"mappings":";;;;;;;;KAoBK,6BAAA,GAAgC;cAExB,2BACH,iDACgB,0BACb,4BACM,oBAAoB;;EANlC,MAAA,cAAA,EAAA;AAEL,CAAA"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { issue } from "../diagnostics.mjs";
|
|
2
|
+
import { displayPath } from "./names.mjs";
|
|
3
|
+
import { isDynamicScalarDataType, isUnsupportedArrayRank, scalarSchema } from "./builtin-types.mjs";
|
|
4
|
+
import { typeFallbackSeverity } from "./policy.mjs";
|
|
5
|
+
|
|
6
|
+
//#region src/compile/variables.ts
|
|
7
|
+
const compileVariables = (config, variableNodes, typeGraph, dataTypeResults) => {
|
|
8
|
+
const issues = [];
|
|
9
|
+
const variables = [];
|
|
10
|
+
for (const item of variableNodes) {
|
|
11
|
+
const access = variableAccess(item.node);
|
|
12
|
+
if (access._tag === "Skip") {
|
|
13
|
+
issues.push(issue(access.issueCode, {
|
|
14
|
+
message: `Skipped ${access.label} variable ${displayPath(item.path)}`,
|
|
15
|
+
path: item.path,
|
|
16
|
+
generatedPath: item.generatedPath,
|
|
17
|
+
nodeId: item.node.nodeId
|
|
18
|
+
}));
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const codec = variableCodec(config, item.node, typeGraph, dataTypeResults);
|
|
22
|
+
if (codec.issue) issues.push({
|
|
23
|
+
...codec.issue,
|
|
24
|
+
path: item.path,
|
|
25
|
+
generatedPath: item.generatedPath,
|
|
26
|
+
nodeId: item.node.nodeId
|
|
27
|
+
});
|
|
28
|
+
variables.push({
|
|
29
|
+
path: item.path,
|
|
30
|
+
generatedPath: item.generatedPath,
|
|
31
|
+
nodeId: item.node.nodeId,
|
|
32
|
+
codec: codec.codec,
|
|
33
|
+
access: access.value
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
variables,
|
|
38
|
+
issues
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
const variableCodec = (config, node, typeGraph, dataTypeResults) => {
|
|
42
|
+
const dataTypeNodeId = node.dataTypeNodeId;
|
|
43
|
+
const isArray = node.valueRank === 1;
|
|
44
|
+
const unsupportedSeverity = typeFallbackSeverity(config);
|
|
45
|
+
if (isUnsupportedArrayRank(node.valueRank)) return {
|
|
46
|
+
codec: { _tag: "Dynamic" },
|
|
47
|
+
issue: issue("codec.unsupportedArrayRank", {
|
|
48
|
+
severity: unsupportedSeverity,
|
|
49
|
+
message: `Variable has unsupported array rank ${node.valueRank}`
|
|
50
|
+
})
|
|
51
|
+
};
|
|
52
|
+
const structure = dataTypeNodeId ? typeGraph.structures.get(dataTypeNodeId) : void 0;
|
|
53
|
+
if (structure) return { codec: isArray ? {
|
|
54
|
+
_tag: "StructureArray",
|
|
55
|
+
name: structure.name
|
|
56
|
+
} : {
|
|
57
|
+
_tag: "Structure",
|
|
58
|
+
name: structure.name
|
|
59
|
+
} };
|
|
60
|
+
const enumDefinition = dataTypeNodeId ? typeGraph.enums.get(dataTypeNodeId) : void 0;
|
|
61
|
+
if (enumDefinition) return { codec: isArray ? {
|
|
62
|
+
_tag: "EnumArray",
|
|
63
|
+
name: enumDefinition.name
|
|
64
|
+
} : {
|
|
65
|
+
_tag: "Enum",
|
|
66
|
+
name: enumDefinition.name
|
|
67
|
+
} };
|
|
68
|
+
if (dataTypeNodeId && typeGraph.invalidEnums.has(dataTypeNodeId)) return { codec: isArray ? {
|
|
69
|
+
_tag: "SchemaArray",
|
|
70
|
+
element: "Number"
|
|
71
|
+
} : {
|
|
72
|
+
_tag: "Schema",
|
|
73
|
+
schema: "Number"
|
|
74
|
+
} };
|
|
75
|
+
const scalar = scalarSchema(dataTypeNodeId);
|
|
76
|
+
if (scalar) return { codec: isArray ? {
|
|
77
|
+
_tag: "SchemaArray",
|
|
78
|
+
element: scalar
|
|
79
|
+
} : {
|
|
80
|
+
_tag: "Schema",
|
|
81
|
+
schema: scalar
|
|
82
|
+
} };
|
|
83
|
+
if (isDynamicScalarDataType(dataTypeNodeId)) return { codec: { _tag: "Dynamic" } };
|
|
84
|
+
const result = dataTypeNodeId ? dataTypeResults.get(dataTypeNodeId) : void 0;
|
|
85
|
+
const directDefinition = result?._tag === "Success" ? result.definition : void 0;
|
|
86
|
+
const isUnion = directDefinition?._tag === "Structure" && directDefinition.structureType === "Union";
|
|
87
|
+
return {
|
|
88
|
+
codec: { _tag: "Dynamic" },
|
|
89
|
+
issue: issue(isUnion ? "datatype.unionUnsupported" : "codec.dynamicFallback", {
|
|
90
|
+
severity: unsupportedSeverity,
|
|
91
|
+
message: isUnion ? `Variable uses unsupported union DataType ${dataTypeNodeId}` : `Variable uses dynamic codec fallback for DataType ${dataTypeNodeId ?? "unknown"}`
|
|
92
|
+
})
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
const variableAccess = (node) => {
|
|
96
|
+
const effective = node.userAccessLevel ?? node.accessLevel;
|
|
97
|
+
if (effective && !effective.readable && !effective.writable) return {
|
|
98
|
+
_tag: "Skip",
|
|
99
|
+
label: "not-accessible",
|
|
100
|
+
issueCode: "variable.notAccessibleSkipped"
|
|
101
|
+
};
|
|
102
|
+
return {
|
|
103
|
+
_tag: "Emit",
|
|
104
|
+
value: effective?.writable === true ? effective.readable ? "readWrite" : "write" : "read"
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
//#endregion
|
|
109
|
+
export { compileVariables };
|
|
110
|
+
//# sourceMappingURL=variables.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variables.mjs","names":["issues: CodegenIssue[]","variables: VariableDefinition[]"],"sources":["../../src/compile/variables.ts"],"sourcesContent":["import type { OpcuaSession } from \"@effect-opcua/client\";\n\nimport { issue } from \"../diagnostics.js\";\nimport type { CodegenIssue } from \"../types.js\";\nimport type {\n DiscoveredNode,\n NormalizedCodegenConfig,\n VariableCodecExpression,\n VariableDefinition,\n} from \"../internal/types.js\";\nimport {\n isDynamicScalarDataType,\n isUnsupportedArrayRank,\n scalarSchema,\n} from \"./builtin-types.js\";\nimport { displayPath } from \"./names.js\";\nimport type { SurfaceNode } from \"./names.js\";\nimport { typeFallbackSeverity } from \"./policy.js\";\nimport type { TypeGraph } from \"./type-graph.js\";\n\ntype OpcuaDataTypeDefinitionResult = OpcuaSession.OpcuaDataTypeDefinitionResult;\n\nexport const compileVariables = (\n config: NormalizedCodegenConfig,\n variableNodes: readonly SurfaceNode[],\n typeGraph: TypeGraph,\n dataTypeResults: ReadonlyMap<string, OpcuaDataTypeDefinitionResult>,\n) => {\n const issues: CodegenIssue[] = [];\n const variables: VariableDefinition[] = [];\n for (const item of variableNodes) {\n const access = variableAccess(item.node);\n if (access._tag === \"Skip\") {\n issues.push(\n issue(access.issueCode, {\n message: `Skipped ${access.label} variable ${displayPath(item.path)}`,\n path: item.path,\n generatedPath: item.generatedPath,\n nodeId: item.node.nodeId,\n }),\n );\n continue;\n }\n\n const codec = variableCodec(config, item.node, typeGraph, dataTypeResults);\n if (codec.issue) {\n issues.push({\n ...codec.issue,\n path: item.path,\n generatedPath: item.generatedPath,\n nodeId: item.node.nodeId,\n });\n }\n variables.push({\n path: item.path,\n generatedPath: item.generatedPath,\n nodeId: item.node.nodeId,\n codec: codec.codec,\n access: access.value,\n });\n }\n return { variables, issues };\n};\n\nconst variableCodec = (\n config: NormalizedCodegenConfig,\n node: DiscoveredNode,\n typeGraph: TypeGraph,\n dataTypeResults: ReadonlyMap<string, OpcuaDataTypeDefinitionResult>,\n): {\n readonly codec: VariableCodecExpression;\n readonly issue?: CodegenIssue;\n} => {\n const dataTypeNodeId = node.dataTypeNodeId;\n const isArray = node.valueRank === 1;\n const unsupportedSeverity = typeFallbackSeverity(config);\n if (isUnsupportedArrayRank(node.valueRank)) {\n return {\n codec: { _tag: \"Dynamic\" },\n issue: issue(\"codec.unsupportedArrayRank\", {\n severity: unsupportedSeverity,\n message: `Variable has unsupported array rank ${node.valueRank}`,\n }),\n };\n }\n\n const structure = dataTypeNodeId\n ? typeGraph.structures.get(dataTypeNodeId)\n : undefined;\n if (structure) {\n return {\n codec: isArray\n ? { _tag: \"StructureArray\", name: structure.name }\n : { _tag: \"Structure\", name: structure.name },\n };\n }\n\n const enumDefinition = dataTypeNodeId\n ? typeGraph.enums.get(dataTypeNodeId)\n : undefined;\n if (enumDefinition) {\n return {\n codec: isArray\n ? { _tag: \"EnumArray\", name: enumDefinition.name }\n : { _tag: \"Enum\", name: enumDefinition.name },\n };\n }\n\n if (dataTypeNodeId && typeGraph.invalidEnums.has(dataTypeNodeId)) {\n return {\n codec: isArray\n ? { _tag: \"SchemaArray\", element: \"Number\" }\n : { _tag: \"Schema\", schema: \"Number\" },\n };\n }\n\n const scalar = scalarSchema(dataTypeNodeId);\n if (scalar) {\n return {\n codec: isArray\n ? { _tag: \"SchemaArray\", element: scalar }\n : { _tag: \"Schema\", schema: scalar },\n };\n }\n\n if (isDynamicScalarDataType(dataTypeNodeId)) {\n return { codec: { _tag: \"Dynamic\" } };\n }\n\n const result = dataTypeNodeId\n ? dataTypeResults.get(dataTypeNodeId)\n : undefined;\n const directDefinition =\n result?._tag === \"Success\" ? result.definition : undefined;\n const isUnion =\n directDefinition?._tag === \"Structure\" &&\n directDefinition.structureType === \"Union\";\n return {\n codec: { _tag: \"Dynamic\" },\n issue: issue(\n isUnion ? \"datatype.unionUnsupported\" : \"codec.dynamicFallback\",\n {\n severity: unsupportedSeverity,\n message: isUnion\n ? `Variable uses unsupported union DataType ${dataTypeNodeId}`\n : `Variable uses dynamic codec fallback for DataType ${dataTypeNodeId ?? \"unknown\"}`,\n },\n ),\n };\n};\n\nconst variableAccess = (\n node: DiscoveredNode,\n):\n | {\n readonly _tag: \"Emit\";\n readonly value: VariableDefinition[\"access\"];\n }\n | {\n readonly _tag: \"Skip\";\n readonly label: \"not-accessible\";\n readonly issueCode: \"variable.notAccessibleSkipped\";\n } => {\n const effective = node.userAccessLevel ?? node.accessLevel;\n if (effective && !effective.readable && !effective.writable) {\n return {\n _tag: \"Skip\",\n label: \"not-accessible\",\n issueCode: \"variable.notAccessibleSkipped\",\n };\n }\n return {\n _tag: \"Emit\",\n value:\n effective?.writable === true\n ? effective.readable\n ? \"readWrite\"\n : \"write\"\n : \"read\",\n };\n};\n"],"mappings":";;;;;;AAsBA,MAAa,oBACX,QACA,eACA,WACA,oBACG;CACH,MAAMA,SAAyB,EAAE;CACjC,MAAMC,YAAkC,EAAE;AAC1C,MAAK,MAAM,QAAQ,eAAe;EAChC,MAAM,SAAS,eAAe,KAAK,KAAK;AACxC,MAAI,OAAO,SAAS,QAAQ;AAC1B,UAAO,KACL,MAAM,OAAO,WAAW;IACtB,SAAS,WAAW,OAAO,MAAM,YAAY,YAAY,KAAK,KAAK;IACnE,MAAM,KAAK;IACX,eAAe,KAAK;IACpB,QAAQ,KAAK,KAAK;IACnB,CAAC,CACH;AACD;;EAGF,MAAM,QAAQ,cAAc,QAAQ,KAAK,MAAM,WAAW,gBAAgB;AAC1E,MAAI,MAAM,MACR,QAAO,KAAK;GACV,GAAG,MAAM;GACT,MAAM,KAAK;GACX,eAAe,KAAK;GACpB,QAAQ,KAAK,KAAK;GACnB,CAAC;AAEJ,YAAU,KAAK;GACb,MAAM,KAAK;GACX,eAAe,KAAK;GACpB,QAAQ,KAAK,KAAK;GAClB,OAAO,MAAM;GACb,QAAQ,OAAO;GAChB,CAAC;;AAEJ,QAAO;EAAE;EAAW;EAAQ;;AAG9B,MAAM,iBACJ,QACA,MACA,WACA,oBAIG;CACH,MAAM,iBAAiB,KAAK;CAC5B,MAAM,UAAU,KAAK,cAAc;CACnC,MAAM,sBAAsB,qBAAqB,OAAO;AACxD,KAAI,uBAAuB,KAAK,UAAU,CACxC,QAAO;EACL,OAAO,EAAE,MAAM,WAAW;EAC1B,OAAO,MAAM,8BAA8B;GACzC,UAAU;GACV,SAAS,uCAAuC,KAAK;GACtD,CAAC;EACH;CAGH,MAAM,YAAY,iBACd,UAAU,WAAW,IAAI,eAAe,GACxC;AACJ,KAAI,UACF,QAAO,EACL,OAAO,UACH;EAAE,MAAM;EAAkB,MAAM,UAAU;EAAM,GAChD;EAAE,MAAM;EAAa,MAAM,UAAU;EAAM,EAChD;CAGH,MAAM,iBAAiB,iBACnB,UAAU,MAAM,IAAI,eAAe,GACnC;AACJ,KAAI,eACF,QAAO,EACL,OAAO,UACH;EAAE,MAAM;EAAa,MAAM,eAAe;EAAM,GAChD;EAAE,MAAM;EAAQ,MAAM,eAAe;EAAM,EAChD;AAGH,KAAI,kBAAkB,UAAU,aAAa,IAAI,eAAe,CAC9D,QAAO,EACL,OAAO,UACH;EAAE,MAAM;EAAe,SAAS;EAAU,GAC1C;EAAE,MAAM;EAAU,QAAQ;EAAU,EACzC;CAGH,MAAM,SAAS,aAAa,eAAe;AAC3C,KAAI,OACF,QAAO,EACL,OAAO,UACH;EAAE,MAAM;EAAe,SAAS;EAAQ,GACxC;EAAE,MAAM;EAAU,QAAQ;EAAQ,EACvC;AAGH,KAAI,wBAAwB,eAAe,CACzC,QAAO,EAAE,OAAO,EAAE,MAAM,WAAW,EAAE;CAGvC,MAAM,SAAS,iBACX,gBAAgB,IAAI,eAAe,GACnC;CACJ,MAAM,mBACJ,QAAQ,SAAS,YAAY,OAAO,aAAa;CACnD,MAAM,UACJ,kBAAkB,SAAS,eAC3B,iBAAiB,kBAAkB;AACrC,QAAO;EACL,OAAO,EAAE,MAAM,WAAW;EAC1B,OAAO,MACL,UAAU,8BAA8B,yBACxC;GACE,UAAU;GACV,SAAS,UACL,4CAA4C,mBAC5C,qDAAqD,kBAAkB;GAC5E,CACF;EACF;;AAGH,MAAM,kBACJ,SAUO;CACP,MAAM,YAAY,KAAK,mBAAmB,KAAK;AAC/C,KAAI,aAAa,CAAC,UAAU,YAAY,CAAC,UAAU,SACjD,QAAO;EACL,MAAM;EACN,OAAO;EACP,WAAW;EACZ;AAEH,QAAO;EACL,MAAM;EACN,OACE,WAAW,aAAa,OACpB,UAAU,WACR,cACA,UACF;EACP"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { CodegenError } from "./errors.mjs";
|
|
2
|
+
import { CodegenModel, DiscoveryModel, NormalizedCodegenConfig } from "./internal/types.mjs";
|
|
3
|
+
import { Effect } from "effect";
|
|
4
|
+
|
|
5
|
+
//#region src/compile.d.ts
|
|
6
|
+
declare const compile: (config: NormalizedCodegenConfig, discovery: DiscoveryModel) => Effect.Effect<CodegenModel, CodegenError>;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { compile };
|
|
9
|
+
//# sourceMappingURL=compile.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.d.mts","names":[],"sources":["../src/compile.ts"],"sourcesContent":[],"mappings":";;;;;cAkBa,kBACH,oCACG,mBACV,MAAA,CAAO,OAAO,cAAY,YAAA"}
|
package/dist/compile.mjs
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { codegenError } from "./errors.mjs";
|
|
2
|
+
import { sortIssues } from "./diagnostics.mjs";
|
|
3
|
+
import { pathIssues, surfaceNodes } from "./compile/names.mjs";
|
|
4
|
+
import { assembleModel, modelIssues } from "./compile/model.mjs";
|
|
5
|
+
import { compileReachableTypes, dataTypeResultMap } from "./compile/type-graph.mjs";
|
|
6
|
+
import { compileVariables } from "./compile/variables.mjs";
|
|
7
|
+
import { Effect } from "effect";
|
|
8
|
+
|
|
9
|
+
//#region src/compile.ts
|
|
10
|
+
const compile = (config, discovery) => Effect.gen(function* () {
|
|
11
|
+
const issues = [...discovery.issues];
|
|
12
|
+
const nodes = surfaceNodes(discovery);
|
|
13
|
+
issues.push(...pathIssues(nodes));
|
|
14
|
+
yield* failOnFatalIssues(issues);
|
|
15
|
+
const variableNodes = nodes.filter((item) => item.node.nodeClass === "Variable");
|
|
16
|
+
const dataTypeResults = dataTypeResultMap(discovery.dataTypeDefinitions);
|
|
17
|
+
const typeGraph = compileReachableTypes(config, variableNodes, dataTypeResults);
|
|
18
|
+
issues.push(...typeGraph.issues);
|
|
19
|
+
const variableResult = compileVariables(config, variableNodes, typeGraph, dataTypeResults);
|
|
20
|
+
issues.push(...variableResult.issues);
|
|
21
|
+
issues.push(...modelIssues(variableResult.variables, typeGraph));
|
|
22
|
+
yield* failOnFatalIssues(issues);
|
|
23
|
+
return assembleModel(variableResult.variables, typeGraph, sortIssues(issues));
|
|
24
|
+
});
|
|
25
|
+
const failOnFatalIssues = (issues) => issues.some((item) => item.severity === "error") ? Effect.fail(codegenError({ _tag: "Compile" }, sortIssues(issues))) : Effect.void;
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
export { compile };
|
|
29
|
+
//# sourceMappingURL=compile.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.mjs","names":["issues: CodegenIssue[]"],"sources":["../src/compile.ts"],"sourcesContent":["import { Effect } from \"effect\";\n\nimport { sortIssues } from \"./diagnostics.js\";\nimport { codegenError } from \"./errors.js\";\nimport { assembleModel, modelIssues } from \"./compile/model.js\";\nimport { pathIssues, surfaceNodes } from \"./compile/names.js\";\nimport {\n compileReachableTypes,\n dataTypeResultMap,\n} from \"./compile/type-graph.js\";\nimport { compileVariables } from \"./compile/variables.js\";\nimport type { CodegenIssue } from \"./types.js\";\nimport type {\n CodegenModel,\n DiscoveryModel,\n NormalizedCodegenConfig,\n} from \"./internal/types.js\";\n\nexport const compile = (\n config: NormalizedCodegenConfig,\n discovery: DiscoveryModel,\n): Effect.Effect<CodegenModel, import(\"./errors.js\").CodegenError> =>\n Effect.gen(function* () {\n const issues: CodegenIssue[] = [...discovery.issues];\n const nodes = surfaceNodes(discovery);\n issues.push(...pathIssues(nodes));\n yield* failOnFatalIssues(issues);\n\n const variableNodes = nodes.filter(\n (item) => item.node.nodeClass === \"Variable\",\n );\n const dataTypeResults = dataTypeResultMap(discovery.dataTypeDefinitions);\n const typeGraph = compileReachableTypes(\n config,\n variableNodes,\n dataTypeResults,\n );\n issues.push(...typeGraph.issues);\n\n const variableResult = compileVariables(\n config,\n variableNodes,\n typeGraph,\n dataTypeResults,\n );\n issues.push(...variableResult.issues);\n issues.push(...modelIssues(variableResult.variables, typeGraph));\n yield* failOnFatalIssues(issues);\n\n return assembleModel(\n variableResult.variables,\n typeGraph,\n sortIssues(issues),\n );\n });\n\nconst failOnFatalIssues = (issues: readonly CodegenIssue[]) =>\n issues.some((item) => item.severity === \"error\")\n ? Effect.fail(codegenError({ _tag: \"Compile\" }, sortIssues(issues)))\n : Effect.void;\n"],"mappings":";;;;;;;;;AAkBA,MAAa,WACX,QACA,cAEA,OAAO,IAAI,aAAa;CACtB,MAAMA,SAAyB,CAAC,GAAG,UAAU,OAAO;CACpD,MAAM,QAAQ,aAAa,UAAU;AACrC,QAAO,KAAK,GAAG,WAAW,MAAM,CAAC;AACjC,QAAO,kBAAkB,OAAO;CAEhC,MAAM,gBAAgB,MAAM,QACzB,SAAS,KAAK,KAAK,cAAc,WACnC;CACD,MAAM,kBAAkB,kBAAkB,UAAU,oBAAoB;CACxE,MAAM,YAAY,sBAChB,QACA,eACA,gBACD;AACD,QAAO,KAAK,GAAG,UAAU,OAAO;CAEhC,MAAM,iBAAiB,iBACrB,QACA,eACA,WACA,gBACD;AACD,QAAO,KAAK,GAAG,eAAe,OAAO;AACrC,QAAO,KAAK,GAAG,YAAY,eAAe,WAAW,UAAU,CAAC;AAChE,QAAO,kBAAkB,OAAO;AAEhC,QAAO,cACL,eAAe,WACf,WACA,WAAW,OAAO,CACnB;EACD;AAEJ,MAAM,qBAAqB,WACzB,OAAO,MAAM,SAAS,KAAK,aAAa,QAAQ,GAC5C,OAAO,KAAK,aAAa,EAAE,MAAM,WAAW,EAAE,WAAW,OAAO,CAAC,CAAC,GAClE,OAAO"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { CodegenConfig } from "./types.mjs";
|
|
2
|
+
import { CodegenError } from "./errors.mjs";
|
|
3
|
+
import { NormalizedCodegenConfig } from "./internal/types.mjs";
|
|
4
|
+
import { Effect } from "effect";
|
|
5
|
+
|
|
6
|
+
//#region src/config.d.ts
|
|
7
|
+
declare const defineConfig: (config: CodegenConfig) => CodegenConfig;
|
|
8
|
+
declare const loadConfig: (path?: string) => Effect.Effect<NormalizedCodegenConfig, CodegenError>;
|
|
9
|
+
declare const normalizeConfig: (config: unknown) => Effect.Effect<NormalizedCodegenConfig, CodegenError>;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { defineConfig, loadConfig, normalizeConfig };
|
|
12
|
+
//# sourceMappingURL=config.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.mts","names":[],"sources":["../src/config.ts"],"sourcesContent":[],"mappings":";;;;;;cAiBa,uBAAwB,kBAAgB;cAExC,+BAEV,MAAA,CAAO,OAAO,yBAAuB,YAAA;cAkC3B,sCAEV,MAAA,CAAO,OAAO,yBAAuB,YAAA"}
|