@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.
Files changed (102) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +6 -0
  3. package/dist/cli.d.mts +1 -0
  4. package/dist/cli.mjs +82 -0
  5. package/dist/cli.mjs.map +1 -0
  6. package/dist/client/src/Opcua.d.mts +5 -0
  7. package/dist/client/src/OpcuaClient.d.mts +3 -0
  8. package/dist/client/src/OpcuaError.d.mts +139 -0
  9. package/dist/client/src/OpcuaError.d.mts.map +1 -0
  10. package/dist/client/src/OpcuaMethod.d.mts +78 -0
  11. package/dist/client/src/OpcuaMethod.d.mts.map +1 -0
  12. package/dist/client/src/OpcuaSession.d.mts +215 -0
  13. package/dist/client/src/OpcuaSession.d.mts.map +1 -0
  14. package/dist/client/src/OpcuaSubscription.d.mts +144 -0
  15. package/dist/client/src/OpcuaSubscription.d.mts.map +1 -0
  16. package/dist/client/src/OpcuaVariable.d.mts +140 -0
  17. package/dist/client/src/OpcuaVariable.d.mts.map +1 -0
  18. package/dist/client/src/index.d.mts +7 -0
  19. package/dist/client/src/internal/common/node-id.d.mts +1 -0
  20. package/dist/client/src/internal/events/model.d.mts +51 -0
  21. package/dist/client/src/internal/events/model.d.mts.map +1 -0
  22. package/dist/client/src/internal/monitoring/runtime.d.mts +7 -0
  23. package/dist/client/src/internal/structures/model.d.mts +18 -0
  24. package/dist/client/src/internal/structures/model.d.mts.map +1 -0
  25. package/dist/client/src/internal/structures/runtime.d.mts +5 -0
  26. package/dist/client/src/internal/values/codec.d.mts +21 -0
  27. package/dist/client/src/internal/values/codec.d.mts.map +1 -0
  28. package/dist/client/src/internal/values/normalize.d.mts +2 -0
  29. package/dist/client/src/node-opcua.d.mts +2 -0
  30. package/dist/compile/builtin-types.d.mts +10 -0
  31. package/dist/compile/builtin-types.d.mts.map +1 -0
  32. package/dist/compile/builtin-types.mjs +38 -0
  33. package/dist/compile/builtin-types.mjs.map +1 -0
  34. package/dist/compile/enums.d.mts +16 -0
  35. package/dist/compile/enums.d.mts.map +1 -0
  36. package/dist/compile/enums.mjs +81 -0
  37. package/dist/compile/enums.mjs.map +1 -0
  38. package/dist/compile/model.d.mts +10 -0
  39. package/dist/compile/model.d.mts.map +1 -0
  40. package/dist/compile/model.mjs +92 -0
  41. package/dist/compile/model.mjs.map +1 -0
  42. package/dist/compile/names.d.mts +17 -0
  43. package/dist/compile/names.d.mts.map +1 -0
  44. package/dist/compile/names.mjs +95 -0
  45. package/dist/compile/names.mjs.map +1 -0
  46. package/dist/compile/policy.d.mts +7 -0
  47. package/dist/compile/policy.d.mts.map +1 -0
  48. package/dist/compile/policy.mjs +6 -0
  49. package/dist/compile/policy.mjs.map +1 -0
  50. package/dist/compile/structures.d.mts +16 -0
  51. package/dist/compile/structures.d.mts.map +1 -0
  52. package/dist/compile/structures.mjs +220 -0
  53. package/dist/compile/structures.mjs.map +1 -0
  54. package/dist/compile/type-graph.d.mts +20 -0
  55. package/dist/compile/type-graph.d.mts.map +1 -0
  56. package/dist/compile/type-graph.mjs +78 -0
  57. package/dist/compile/type-graph.mjs.map +1 -0
  58. package/dist/compile/variables.d.mts +16 -0
  59. package/dist/compile/variables.d.mts.map +1 -0
  60. package/dist/compile/variables.mjs +110 -0
  61. package/dist/compile/variables.mjs.map +1 -0
  62. package/dist/compile.d.mts +9 -0
  63. package/dist/compile.d.mts.map +1 -0
  64. package/dist/compile.mjs +29 -0
  65. package/dist/compile.mjs.map +1 -0
  66. package/dist/config.d.mts +12 -0
  67. package/dist/config.d.mts.map +1 -0
  68. package/dist/config.mjs +158 -0
  69. package/dist/config.mjs.map +1 -0
  70. package/dist/diagnostics.d.mts +16 -0
  71. package/dist/diagnostics.d.mts.map +1 -0
  72. package/dist/diagnostics.mjs +45 -0
  73. package/dist/diagnostics.mjs.map +1 -0
  74. package/dist/discover.d.mts +23 -0
  75. package/dist/discover.d.mts.map +1 -0
  76. package/dist/discover.mjs +356 -0
  77. package/dist/discover.mjs.map +1 -0
  78. package/dist/emit.d.mts +8 -0
  79. package/dist/emit.d.mts.map +1 -0
  80. package/dist/emit.mjs +233 -0
  81. package/dist/emit.mjs.map +1 -0
  82. package/dist/errors.d.mts +27 -0
  83. package/dist/errors.d.mts.map +1 -0
  84. package/dist/errors.mjs +18 -0
  85. package/dist/errors.mjs.map +1 -0
  86. package/dist/generate.d.mts +19 -0
  87. package/dist/generate.d.mts.map +1 -0
  88. package/dist/generate.mjs +172 -0
  89. package/dist/generate.mjs.map +1 -0
  90. package/dist/index.d.mts +5 -0
  91. package/dist/index.mjs +5 -0
  92. package/dist/internal/types.d.mts +192 -0
  93. package/dist/internal/types.d.mts.map +1 -0
  94. package/dist/internal/types.mjs +1 -0
  95. package/dist/issue-codes.d.mts +119 -0
  96. package/dist/issue-codes.d.mts.map +1 -0
  97. package/dist/issue-codes.mjs +44 -0
  98. package/dist/issue-codes.mjs.map +1 -0
  99. package/dist/types.d.mts +57 -0
  100. package/dist/types.d.mts.map +1 -0
  101. package/dist/types.mjs +1 -0
  102. package/package.json +58 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.mjs","names":["issues: CodegenIssue[]","references: DiscoveredReference[]","roots: DiscoveredRoot[]","queue: TraversalItem[]","resolvedSegments: string[]","results: OpcuaDataTypeDefinitionResult[]","entries: Array<readonly [NodeKey, DiscoveredNode]>"],"sources":["../src/discover.ts"],"sourcesContent":["import { Context, Effect } from \"effect\";\nimport { OpcuaSession } from \"@effect-opcua/client\";\nimport type * as Client from \"@effect-opcua/client\";\n\nimport { errorIssue, issue, sortIssues } from \"./diagnostics.js\";\nimport { codegenError } from \"./errors.js\";\nimport type { CodegenIssue, PathPatternSegment } from \"./types.js\";\nimport type {\n DiscoveredNode,\n DiscoveredReference,\n DiscoveredRoot,\n DiscoveryModel,\n NodeKey,\n NormalizedCodegenConfig,\n NormalizedExcludeRule,\n NormalizedRootConfig,\n} from \"./internal/types.js\";\n\ntype TraversalItem = {\n readonly nodeId: string;\n readonly parentNodeId?: string;\n readonly rootIndex: number;\n readonly rootSegmentCount: number;\n readonly path: readonly string[];\n};\n\ntype OpcuaError = Client.OpcuaError.OpcuaError;\ntype OpcuaBrowseReference = OpcuaSession.OpcuaBrowseReference;\ntype OpcuaDataTypeDefinitionResult = OpcuaSession.OpcuaDataTypeDefinitionResult;\ntype OpcuaNodeMetadata = OpcuaSession.OpcuaNodeMetadata;\ntype OpcuaSessionService = OpcuaSession.Service;\n\ntype NodeDraft = Omit<DiscoveredNode, \"path\" | \"allPaths\"> & {\n path: readonly string[];\n allPaths: readonly (readonly string[])[];\n rootSegmentCount: number;\n};\n\ntype MetadataTargetReference = {\n readonly nodeId: { readonly text: string };\n readonly browseName?: { readonly name?: string };\n};\n\nconst objectsFolderNodeId = \"i=85\";\nconst allowedReferenceTypes = new Set([\"i=35\", \"i=46\", \"i=47\", \"i=49\"]);\ntype OpcuaSessionRequirement = Context.Service.Identifier<\n typeof OpcuaSession.OpcuaSession\n>;\nconst metadataPropertyNames = new Set([\n \"InputArguments\",\n \"OutputArguments\",\n \"EnumStrings\",\n \"EnumValues\",\n \"DataTypeVersion\",\n \"DictionaryFragment\",\n \"NodeVersion\",\n]);\n\nexport const discover = (\n config: NormalizedCodegenConfig,\n): Effect.Effect<\n DiscoveryModel,\n import(\"./errors.js\").CodegenError | OpcuaError,\n OpcuaSessionRequirement\n> =>\n Effect.gen(function* () {\n const session = yield* OpcuaSession.OpcuaSession;\n const issues: CodegenIssue[] = [];\n const references: DiscoveredReference[] = [];\n const nodes = new Map<NodeKey, NodeDraft>();\n const roots: DiscoveredRoot[] = [];\n\n for (let rootIndex = 0; rootIndex < config.roots.length; rootIndex++) {\n const rootConfig = config.roots[rootIndex]!;\n const root = yield* resolveRoot(session, rootConfig, rootIndex);\n roots.push({ ...root, exportPrefix: rootConfig.exportPrefix });\n const rootMetadata = yield* session.readNodeMetadata(root.nodeId);\n addOrUpdateNode(nodes, {\n metadata: rootMetadata,\n path: root.path,\n parentNodeId: undefined,\n rootIndex,\n rootSegmentCount: root.path.length,\n });\n }\n\n const queue: TraversalItem[] = roots.map((root) => ({\n nodeId: root.nodeId,\n rootIndex: root.rootIndex,\n rootSegmentCount: root.path.length,\n path: root.path,\n }));\n const visitedPaths = new Set<string>();\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n const visitKey = `${current.nodeId}\\u0000${current.path.join(\"\\u0000\")}`;\n if (visitedPaths.has(visitKey)) continue;\n visitedPaths.add(visitKey);\n\n const result = yield* session.browseChildren(current.nodeId);\n if (result._tag === \"NonGoodStatus\") {\n const browseIssue = issue(\"browse.failure\", {\n message: `Could not browse ${current.nodeId}`,\n nodeId: current.nodeId,\n path: current.path,\n cause: result.status,\n severity:\n config.discovery.onBrowseFailure === \"fail\" ? \"error\" : undefined,\n });\n if (browseIssue.severity === \"error\") {\n return yield* Effect.fail(\n codegenError({ _tag: \"Discovery\" }, [browseIssue]),\n );\n }\n issues.push(browseIssue);\n continue;\n }\n\n const children = selectedChildReferences(result.references);\n const duplicate = duplicateBrowseName(children);\n if (duplicate) {\n return yield* Effect.fail(\n codegenError({ _tag: \"Discovery\" }, [\n errorIssue(\"browse.ambiguousPath\", {\n message: \"Multiple children have the same BrowseName segment\",\n path: [...current.path, duplicate.name],\n cause: { candidates: duplicate.candidates },\n }),\n ]),\n );\n }\n const metadataByNodeId = yield* readChildMetadata(\n session,\n children,\n config.exclude,\n current.path,\n );\n\n for (const child of children) {\n const browseName = child.browseName?.name;\n const targetNodeId = child.nodeId.text;\n if (!browseName || !targetNodeId) continue;\n const referenceType = normalizeNamespaceZeroNodeId(\n child.referenceTypeId ?? \"\",\n );\n if (referenceType === \"i=46\" && metadataPropertyNames.has(browseName)) {\n continue;\n }\n const childPath = [...current.path, browseName];\n references.push({\n sourceNodeId: current.nodeId,\n targetNodeId,\n referenceType,\n isForward: child.isForward ?? true,\n browseName,\n });\n\n const exclude = matchingExclude(config.exclude, childPath);\n if (exclude?.mode === \"prune\") {\n issues.push(\n issue(\"branch.pruned\", {\n message: `Pruned ${displayPath(childPath)}`,\n path: childPath,\n nodeId: targetNodeId,\n }),\n );\n continue;\n }\n\n if (exclude?.mode !== \"omit\") {\n const metadata = metadataByNodeId.get(targetNodeId);\n if (!metadata) continue;\n addOrUpdateNode(nodes, {\n metadata,\n path: childPath,\n parentNodeId: current.nodeId,\n rootIndex: current.rootIndex,\n rootSegmentCount: current.rootSegmentCount,\n });\n } else {\n issues.push(\n issue(\"node.omitted\", {\n message: `Omitted ${displayPath(childPath)}`,\n path: childPath,\n nodeId: targetNodeId,\n }),\n );\n }\n\n if (shouldBrowseChildren(child.nodeClass)) {\n queue.push({\n nodeId: targetNodeId,\n parentNodeId: current.nodeId,\n rootIndex: current.rootIndex,\n rootSegmentCount: current.rootSegmentCount,\n path: childPath,\n });\n }\n }\n }\n\n for (const node of nodes.values()) {\n if (node.allPaths.length > 1) {\n issues.push(\n issue(\"node.multiPath\", {\n message: `Node ${node.nodeId} was reached through multiple paths`,\n path: node.path,\n nodeId: node.nodeId,\n }),\n );\n }\n }\n\n const finalizedNodes = finalizeNodes(nodes);\n const dataTypeDefinitions = yield* discoverDataTypeDefinitions(\n session,\n finalizedNodes,\n );\n\n return {\n roots,\n nodes: finalizedNodes,\n references: sortReferences(references),\n dataTypeDefinitions,\n issues: sortIssues(issues),\n };\n });\n\nconst resolveRoot = (\n session: OpcuaSessionService,\n root: NormalizedRootConfig,\n rootIndex: number,\n) =>\n root.nodeId !== undefined\n ? resolveNodeIdRoot(\n session,\n root as Extract<NormalizedRootConfig, { readonly nodeId: string }>,\n rootIndex,\n )\n : resolvePathRoot(\n session,\n root as Extract<\n NormalizedRootConfig,\n { readonly path: readonly string[] }\n >,\n rootIndex,\n );\n\nconst resolveNodeIdRoot = (\n session: OpcuaSessionService,\n root: Extract<NormalizedRootConfig, { readonly nodeId: string }>,\n rootIndex: number,\n) =>\n Effect.gen(function* () {\n const metadata = yield* session.readNodeMetadata(root.nodeId);\n const browseName = metadata.browseName ?? root.nodeId;\n return {\n rootIndex,\n nodeId: root.nodeId,\n path: [browseName],\n exportPrefix: root.exportPrefix,\n } satisfies DiscoveredRoot;\n });\n\nconst resolvePathRoot = (\n session: OpcuaSessionService,\n root: Extract<NormalizedRootConfig, { readonly path: readonly string[] }>,\n rootIndex: number,\n) =>\n Effect.gen(function* () {\n let currentNodeId = objectsFolderNodeId;\n const resolvedSegments: string[] = [];\n for (const segment of root.path) {\n const result = yield* session.browseChildren(currentNodeId);\n if (result._tag === \"NonGoodStatus\") {\n return yield* Effect.fail(\n codegenError({ _tag: \"Discovery\" }, [\n errorIssue(\"root.resolutionFailed\", {\n message: `Could not browse ${currentNodeId} while resolving ${displayPath(root.path)}`,\n path: root.path,\n nodeId: currentNodeId,\n cause: result.status,\n }),\n ]),\n );\n }\n const matches = selectedChildReferences(result.references).filter(\n (reference) => reference.browseName?.name === segment,\n );\n if (matches.length === 0) {\n return yield* Effect.fail(\n codegenError({ _tag: \"Discovery\" }, [\n errorIssue(\"root.resolutionFailed\", {\n message: `Missing root path segment ${segment}`,\n path: [...resolvedSegments, segment],\n }),\n ]),\n );\n }\n if (matches.length > 1) {\n return yield* Effect.fail(\n codegenError({ _tag: \"Discovery\" }, [\n errorIssue(\"browse.ambiguousPath\", {\n message: \"Multiple children match the root path segment\",\n path: [...resolvedSegments, segment],\n cause: { candidates: matches.map((match) => match.nodeId.text) },\n }),\n ]),\n );\n }\n currentNodeId = matches[0]!.nodeId.text;\n resolvedSegments.push(segment);\n }\n return {\n rootIndex,\n nodeId: currentNodeId,\n path: resolvedSegments,\n exportPrefix: root.exportPrefix,\n } satisfies DiscoveredRoot;\n });\n\nconst selectedChildReferences = (references: readonly OpcuaBrowseReference[]) =>\n references\n .filter((reference) => reference.isForward !== false)\n .filter((reference) =>\n allowedReferenceTypes.has(\n normalizeNamespaceZeroNodeId(reference.referenceTypeId ?? \"\"),\n ),\n )\n .sort(referenceSort);\n\nconst duplicateBrowseName = (references: readonly OpcuaBrowseReference[]) => {\n const groups = new Map<string, string[]>();\n for (const reference of references) {\n const name = reference.browseName?.name;\n if (!name) continue;\n const group = groups.get(name) ?? [];\n group.push(reference.nodeId.text);\n groups.set(name, group);\n }\n for (const [name, candidates] of groups) {\n if (candidates.length > 1) return { name, candidates };\n }\n return undefined;\n};\n\nconst referenceSort = (\n left: OpcuaBrowseReference,\n right: OpcuaBrowseReference,\n) =>\n (left.browseName?.name ?? \"\").localeCompare(right.browseName?.name ?? \"\") ||\n (left.nodeClass ?? \"\").localeCompare(right.nodeClass ?? \"\") ||\n left.nodeId.text.localeCompare(right.nodeId.text);\n\nconst matchingExclude = (\n rules: readonly NormalizedExcludeRule[],\n path: readonly string[],\n) =>\n rules.find((rule) =>\n rule._tag === \"Path\"\n ? samePath(rule.path, path)\n : matchPathPattern(rule.pathPattern, path),\n );\n\nconst readChildMetadata = (\n session: OpcuaSessionService,\n children: readonly OpcuaBrowseReference[],\n exclude: readonly NormalizedExcludeRule[],\n parentPath: readonly string[],\n) =>\n Effect.gen(function* () {\n const metadataTargets = metadataTargetNodeIds(\n children,\n exclude,\n parentPath,\n );\n if (metadataTargets.length === 0) {\n return new Map<string, OpcuaNodeMetadata>();\n }\n\n const results = yield* session.readManyNodeMetadata(metadataTargets);\n const failed = results.find((result) => result._tag === \"Failure\");\n if (failed?._tag === \"Failure\") {\n return yield* Effect.fail(\n codegenError({ _tag: \"Discovery\" }, [\n errorIssue(\"metadata.readFailed\", {\n message: `Could not read metadata for ${failed.nodeId}`,\n nodeId: failed.nodeId,\n cause: failed.reason,\n }),\n ]),\n );\n }\n\n return new Map(\n results.flatMap((result) =>\n result._tag === \"Success\"\n ? ([[result.nodeId, result.metadata]] as const)\n : [],\n ),\n );\n });\n\nexport const metadataTargetNodeIds = (\n children: readonly MetadataTargetReference[],\n exclude: readonly NormalizedExcludeRule[],\n parentPath: readonly string[],\n) =>\n children.flatMap((child) => {\n const browseName = child.browseName?.name;\n const targetNodeId = child.nodeId.text;\n if (!browseName || !targetNodeId) return [];\n const childPath = [...parentPath, browseName];\n return matchingExclude(exclude, childPath) ? [] : [targetNodeId];\n });\n\nconst matchPathPattern = (\n pattern: readonly PathPatternSegment[],\n path: readonly string[],\n): boolean => {\n const match = (patternIndex: number, pathIndex: number): boolean => {\n if (patternIndex === pattern.length) return pathIndex === path.length;\n const segment = pattern[patternIndex]!;\n if (segment === \"**\") {\n return (\n match(patternIndex + 1, pathIndex) ||\n (pathIndex < path.length && match(patternIndex, pathIndex + 1))\n );\n }\n if (pathIndex >= path.length) return false;\n return (\n segmentMatches(segment, path[pathIndex]!) &&\n match(patternIndex + 1, pathIndex + 1)\n );\n };\n return match(0, 0);\n};\n\nconst segmentMatches = (\n pattern: Exclude<PathPatternSegment, \"**\">,\n segment: string,\n) => (pattern instanceof RegExp ? pattern.test(segment) : pattern === segment);\n\nconst samePath = (left: readonly string[], right: readonly string[]) =>\n left.length === right.length &&\n left.every((segment, index) => segment === right[index]);\n\nconst addOrUpdateNode = (\n nodes: Map<NodeKey, NodeDraft>,\n input: {\n readonly metadata: OpcuaNodeMetadata;\n readonly path: readonly string[];\n readonly parentNodeId?: string;\n readonly rootIndex: number;\n readonly rootSegmentCount: number;\n },\n) => {\n const key = input.metadata.nodeId;\n const existing = nodes.get(key);\n if (existing) {\n const allPaths = uniquePaths([...existing.allPaths, input.path]);\n if (\n comparePathRank(\n {\n rootIndex: input.rootIndex,\n rootSegmentCount: input.rootSegmentCount,\n path: input.path,\n nodeId: key,\n },\n {\n rootIndex: existing.rootIndex ?? Number.MAX_SAFE_INTEGER,\n rootSegmentCount: existing.rootSegmentCount,\n path: existing.path,\n nodeId: existing.nodeId,\n },\n ) < 0\n ) {\n nodes.set(key, {\n ...existing,\n path: input.path,\n allPaths,\n parentNodeId: input.parentNodeId,\n rootIndex: input.rootIndex,\n rootSegmentCount: input.rootSegmentCount,\n });\n } else {\n nodes.set(key, { ...existing, allPaths });\n }\n return;\n }\n const nodeClass = normalizeNodeClass(input.metadata.nodeClass);\n if (!nodeClass) return;\n nodes.set(key, {\n key,\n nodeId: key,\n parsedNodeId: parseNodeId(key, input.metadata.namespaceIndex),\n namespaceIndex:\n input.metadata.namespaceIndex ?? parseNodeId(key).namespaceIndex,\n namespaceUri: input.metadata.namespaceUri,\n browseName: input.metadata.browseName ?? input.path.at(-1) ?? key,\n browseNameNamespaceIndex: input.metadata.browseNameNamespaceIndex,\n path: input.path,\n allPaths: [input.path],\n nodeClass,\n displayName: input.metadata.displayName,\n description: input.metadata.description,\n dataTypeNodeId: input.metadata.dataType,\n valueRank: input.metadata.valueRank,\n arrayDimensions: input.metadata.arrayDimensions,\n accessLevel: input.metadata.accessLevel,\n userAccessLevel: input.metadata.userAccessLevel,\n parentNodeId: input.parentNodeId,\n rootIndex: input.rootIndex,\n rootSegmentCount: input.rootSegmentCount,\n });\n};\n\nconst normalizeNodeClass = (\n nodeClass: string | undefined,\n): DiscoveredNode[\"nodeClass\"] | undefined => {\n switch (nodeClass) {\n case \"Object\":\n case \"Variable\":\n case \"Method\":\n case \"DataType\":\n case \"ObjectType\":\n case \"VariableType\":\n case \"ReferenceType\":\n return nodeClass;\n default:\n return undefined;\n }\n};\n\nconst shouldBrowseChildren = (nodeClass: string | undefined) =>\n nodeClass === \"Object\";\n\nconst discoverDataTypeDefinitions = (\n session: OpcuaSessionService,\n nodes: ReadonlyMap<NodeKey, DiscoveredNode>,\n) =>\n Effect.gen(function* () {\n const seen = new Set<string>();\n const queue = [...nodes.values()]\n .filter((node) => node.nodeClass === \"Variable\")\n .flatMap((node) => (node.dataTypeNodeId ? [node.dataTypeNodeId] : []))\n .filter((nodeId) => !isBuiltInDataType(nodeId));\n const results: OpcuaDataTypeDefinitionResult[] = [];\n\n while (queue.length > 0) {\n const batch = [...new Set(queue.splice(0))]\n .filter((nodeId) => !seen.has(nodeId))\n .sort();\n if (batch.length === 0) continue;\n batch.forEach((nodeId) => seen.add(nodeId));\n const batchResults = yield* session.readManyDataTypeDefinitions(batch);\n results.push(...batchResults);\n for (const result of batchResults) {\n if (\n result._tag !== \"Success\" ||\n result.definition._tag !== \"Structure\"\n ) {\n continue;\n }\n for (const field of result.definition.fields) {\n if (\n field.dataTypeNodeId &&\n !isBuiltInDataType(field.dataTypeNodeId) &&\n !seen.has(field.dataTypeNodeId)\n ) {\n queue.push(field.dataTypeNodeId);\n }\n }\n }\n }\n\n return results;\n });\n\nconst isBuiltInDataType = (nodeId: string) => {\n const normalized = normalizeNamespaceZeroNodeId(nodeId);\n return /^i=\\d+$/.test(normalized);\n};\n\nconst parseNodeId = (nodeId: string, namespaceIndex?: number) => {\n const match = /^ns=(\\d+);(.+)$/.exec(nodeId);\n return {\n namespaceIndex: namespaceIndex ?? (match ? Number(match[1]) : 0),\n identifier: match?.[2] ?? nodeId,\n };\n};\n\nconst comparePathRank = (\n left: {\n readonly rootIndex: number;\n readonly rootSegmentCount: number;\n readonly path: readonly string[];\n readonly nodeId: string;\n },\n right: {\n readonly rootIndex: number;\n readonly rootSegmentCount: number;\n readonly path: readonly string[];\n readonly nodeId: string;\n },\n) =>\n left.rootIndex - right.rootIndex ||\n relativeLength(left) - relativeLength(right) ||\n displayPath(left.path).localeCompare(displayPath(right.path)) ||\n left.nodeId.localeCompare(right.nodeId);\n\nconst relativeLength = (item: {\n readonly rootSegmentCount: number;\n readonly path: readonly string[];\n}) => item.path.length - item.rootSegmentCount;\n\nconst finalizeNodes = (nodes: ReadonlyMap<NodeKey, NodeDraft>) => {\n const entries: Array<readonly [NodeKey, DiscoveredNode]> = [];\n for (const [key, node] of nodes) {\n entries.push([\n key,\n {\n key: node.key,\n nodeId: node.nodeId,\n parsedNodeId: node.parsedNodeId,\n namespaceIndex: node.namespaceIndex,\n namespaceUri: node.namespaceUri,\n browseName: node.browseName,\n browseNameNamespaceIndex: node.browseNameNamespaceIndex,\n path: node.path,\n allPaths: uniquePaths(node.allPaths),\n nodeClass: node.nodeClass,\n displayName: node.displayName,\n description: node.description,\n dataTypeNodeId: node.dataTypeNodeId,\n valueRank: node.valueRank,\n arrayDimensions: node.arrayDimensions,\n accessLevel: node.accessLevel,\n userAccessLevel: node.userAccessLevel,\n parentNodeId: node.parentNodeId,\n rootIndex: node.rootIndex,\n },\n ]);\n }\n return new Map(\n entries.sort((left, right) =>\n displayPath(left[1].path).localeCompare(displayPath(right[1].path)),\n ),\n ) as ReadonlyMap<NodeKey, DiscoveredNode>;\n};\n\nconst uniquePaths = (paths: readonly (readonly string[])[]) =>\n [\n ...new Map(paths.map((path) => [path.join(\"\\u0000\"), [...path]])).values(),\n ].sort((left, right) => displayPath(left).localeCompare(displayPath(right)));\n\nconst sortReferences = (references: readonly DiscoveredReference[]) =>\n [...references].sort(\n (left, right) =>\n left.sourceNodeId.localeCompare(right.sourceNodeId) ||\n left.browseName.localeCompare(right.browseName) ||\n left.targetNodeId.localeCompare(right.targetNodeId),\n );\n\nconst displayPath = (path: readonly string[]) => path.join(\" / \");\n\nconst normalizeNamespaceZeroNodeId = (nodeId: string) =>\n nodeId.startsWith(\"ns=0;\") ? nodeId.slice(\"ns=0;\".length) : nodeId;\n"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { CodegenModel, GeneratedFile } from "./internal/types.mjs";
2
+
3
+ //#region src/emit.d.ts
4
+ declare const generatedHeader = "// Generated by @effect-opcua/codegen. Do not edit manually.";
5
+ declare const emit: (model: CodegenModel) => readonly GeneratedFile[];
6
+ //#endregion
7
+ export { emit, generatedHeader };
8
+ //# sourceMappingURL=emit.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit.d.mts","names":[],"sources":["../src/emit.ts"],"sourcesContent":[],"mappings":";;;cAYa,eAAA;cAGA,cAAe,0BAAwB"}
package/dist/emit.mjs ADDED
@@ -0,0 +1,233 @@
1
+ //#region src/emit.ts
2
+ const generatedHeader = "// Generated by @effect-opcua/codegen. Do not edit manually.";
3
+ const emit = (model) => [
4
+ {
5
+ path: "nodeIds.ts",
6
+ contents: emitNodeIds(model.nodeIds, model.dataTypeNodeIds)
7
+ },
8
+ {
9
+ path: "enums.ts",
10
+ contents: emitEnums(model.enums)
11
+ },
12
+ {
13
+ path: "structures.ts",
14
+ contents: emitStructures(model.structures)
15
+ },
16
+ {
17
+ path: "variables.ts",
18
+ contents: emitVariables(model.variables)
19
+ },
20
+ {
21
+ path: "index.ts",
22
+ contents: emitIndex()
23
+ }
24
+ ];
25
+ const emitNodeIds = (nodeIds, dataTypeNodeIds) => {
26
+ const root = { children: /* @__PURE__ */ new Map() };
27
+ for (const nodeId of [...nodeIds].sort(pathSort)) {
28
+ let current = root;
29
+ for (const segment of nodeId.generatedPath) {
30
+ const child = current.children.get(segment) ?? { children: /* @__PURE__ */ new Map() };
31
+ current.children.set(segment, child);
32
+ current = child;
33
+ }
34
+ current.value = nodeId.nodeId;
35
+ }
36
+ if (dataTypeNodeIds.length > 0) {
37
+ const dataTypes = { children: /* @__PURE__ */ new Map() };
38
+ for (const dataType of [...dataTypeNodeIds].sort((left, right) => left.name.localeCompare(right.name))) dataTypes.children.set(dataType.name, {
39
+ value: dataType.nodeId,
40
+ children: /* @__PURE__ */ new Map()
41
+ });
42
+ root.children.set("DataTypes", dataTypes);
43
+ }
44
+ const topLevel = [...root.children.entries()].sort(keySort);
45
+ if (topLevel.length === 0) return emitEmptyModule();
46
+ return [
47
+ generatedHeader,
48
+ "",
49
+ ...topLevel.map(([key, value]) => `export const ${key} = ${emitTree(value, 0)} as const;`),
50
+ ""
51
+ ].join("\n");
52
+ };
53
+ const emitTree = (node, depth) => {
54
+ if (node.value !== void 0 && node.children.size === 0) return JSON.stringify(node.value);
55
+ const lines = ["{"];
56
+ for (const [key, child] of [...node.children.entries()].sort(keySort)) {
57
+ const value = emitTree(child, depth + 1);
58
+ const property = `${indent(depth + 1)}${key}: ${value},`;
59
+ lines.push(property.length > 80 && isLeafValue(child) ? `${indent(depth + 1)}${key}:\n${indent(depth + 2)}${value},` : property);
60
+ }
61
+ lines.push(`${indent(depth)}}`);
62
+ return lines.join("\n");
63
+ };
64
+ const emitEnums = (enums) => {
65
+ if (enums.length === 0) return emitEmptyModule();
66
+ const lines = [
67
+ generatedHeader,
68
+ "",
69
+ "import { Schema } from \"effect\";",
70
+ ""
71
+ ];
72
+ for (const item of [...enums].sort((left, right) => left.name.localeCompare(right.name))) {
73
+ lines.push(`export const ${item.name} = {`);
74
+ for (const member of item.members) lines.push(`${indent(1)}${member.name}: ${member.value},`);
75
+ lines.push("} as const;");
76
+ lines.push("");
77
+ lines.push(...emitTypeAlias(item.name, `(typeof ${item.name})[keyof typeof ${item.name}]`));
78
+ lines.push("");
79
+ lines.push(`export const ${item.name}Schema = Schema.Literals([`);
80
+ for (const member of item.members) lines.push(`${indent(1)}${item.name}.${member.name},`);
81
+ lines.push("]);");
82
+ lines.push("");
83
+ }
84
+ return lines.join("\n");
85
+ };
86
+ const emitStructures = (structures) => {
87
+ if (structures.length === 0) return emitEmptyModule();
88
+ const lines = [
89
+ generatedHeader,
90
+ "",
91
+ "import { Opcua } from \"@effect-opcua/client\";",
92
+ "import { Schema } from \"effect\";",
93
+ ""
94
+ ];
95
+ if (structures.some((structure) => structure.fields.some((field) => schemaUsesEnum(field.schema)))) lines.push("import * as Enums from \"./enums.js\";");
96
+ lines.push("import * as NodeIds from \"./nodeIds.js\";");
97
+ lines.push("");
98
+ for (const item of structures) {
99
+ lines.push(`export const ${item.name}Schema = Schema.Struct({`);
100
+ for (const field of item.fields) {
101
+ const schema = emitFieldSchema(field.schema);
102
+ lines.push(`${indent(1)}${field.name}: ${field.optional ? `Schema.optional(${schema})` : schema},`);
103
+ }
104
+ const encodedKeys = item.fields.filter((field) => field.name !== field.encodedName);
105
+ if (encodedKeys.length === 0) lines.push("});");
106
+ else {
107
+ lines.push("}).pipe(");
108
+ lines.push(`${indent(1)}Schema.encodeKeys({`);
109
+ for (const field of encodedKeys) lines.push(`${indent(2)}${field.name}: ${JSON.stringify(field.encodedName)},`);
110
+ lines.push(`${indent(1)}}),`);
111
+ lines.push(");");
112
+ }
113
+ lines.push("");
114
+ lines.push(...emitTypeAlias(item.name, `typeof ${item.name}Schema.Type`));
115
+ lines.push("");
116
+ lines.push(`export const ${item.name} = Opcua.structure({`);
117
+ lines.push(`${indent(1)}name: ${JSON.stringify(item.browseName)},`);
118
+ lines.push(`${indent(1)}dataTypeId: NodeIds.DataTypes.${item.name},`);
119
+ lines.push(`${indent(1)}schema: ${item.name}Schema,`);
120
+ lines.push("});");
121
+ lines.push("");
122
+ }
123
+ return lines.join("\n");
124
+ };
125
+ const emitVariables = (variables) => {
126
+ const lines = [
127
+ generatedHeader,
128
+ "",
129
+ "import { Opcua } from \"@effect-opcua/client\";"
130
+ ];
131
+ if (variables.some((variable) => codecUsesSchema(variable.codec))) lines.push("import { Schema } from \"effect\";");
132
+ const localImports = [];
133
+ if (variables.some((variable) => codecUsesEnum(variable.codec))) localImports.push("import * as Enums from \"./enums.js\";");
134
+ localImports.push("import * as NodeIds from \"./nodeIds.js\";");
135
+ if (variables.some((variable) => codecUsesStructure(variable.codec))) localImports.push("import * as Structures from \"./structures.js\";");
136
+ lines.push("", ...localImports, "");
137
+ if (variables.length === 0) {
138
+ lines.push("export {};", "");
139
+ return lines.join("\n");
140
+ }
141
+ const root = variableTree(variables);
142
+ for (const [key, child] of [...root.children.entries()].sort(keySort)) {
143
+ const assertion = child.variable && child.children.size === 0 ? "" : " as const";
144
+ lines.push(`export const ${key} = ${emitVariableTree(child, 0)}${assertion};`);
145
+ lines.push("");
146
+ }
147
+ return lines.join("\n");
148
+ };
149
+ const variableTree = (variables) => {
150
+ const root = { children: /* @__PURE__ */ new Map() };
151
+ for (const variable of [...variables].sort(pathSort)) {
152
+ let current = root;
153
+ for (const segment of variable.generatedPath) {
154
+ const child = current.children.get(segment) ?? { children: /* @__PURE__ */ new Map() };
155
+ current.children.set(segment, child);
156
+ current = child;
157
+ }
158
+ current.variable = variable;
159
+ }
160
+ return root;
161
+ };
162
+ const emitVariableTree = (node, depth) => {
163
+ if (node.variable && node.children.size === 0) return emitVariable(node.variable, depth);
164
+ const lines = ["{"];
165
+ for (const [key, child] of [...node.children.entries()].sort(keySort)) lines.push(`${indent(depth + 1)}${key}: ${emitVariableTree(child, depth + 1)},`);
166
+ lines.push(`${indent(depth)}}`);
167
+ return lines.join("\n");
168
+ };
169
+ const emitVariable = (variable, depth) => {
170
+ const lines = ["Opcua.variable({"];
171
+ lines.push(`${indent(depth + 1)}nodeId: NodeIds.${variable.generatedPath.join(".")},`);
172
+ lines.push(`${indent(depth + 1)}codec: ${emitCodec(variable.codec)},`);
173
+ if (variable.access !== "read") lines.push(`${indent(depth + 1)}access: ${JSON.stringify(variable.access)},`);
174
+ lines.push(`${indent(depth)}})`);
175
+ return lines.join("\n");
176
+ };
177
+ const emitCodec = (codec) => {
178
+ switch (codec._tag) {
179
+ case "Schema": return `Opcua.schema(Schema.${codec.schema})`;
180
+ case "SchemaArray": return `Opcua.schema(Schema.Array(Schema.${codec.element}))`;
181
+ case "Enum": return `Opcua.schema(Enums.${codec.name}Schema)`;
182
+ case "EnumArray": return `Opcua.schema(Schema.Array(Enums.${codec.name}Schema))`;
183
+ case "Structure": return `Structures.${codec.name}`;
184
+ case "StructureArray": return `Opcua.structureArray(Structures.${codec.name})`;
185
+ case "Dynamic": return "Opcua.dynamic()";
186
+ }
187
+ };
188
+ const emitFieldSchema = (schema) => {
189
+ switch (schema._tag) {
190
+ case "Scalar": return `Schema.${schema.schema}`;
191
+ case "Array": return `Schema.Array(${emitFieldSchema(schema.item)})`;
192
+ case "Enum": return `Enums.${schema.name}Schema`;
193
+ case "Structure": return `${schema.name}Schema`;
194
+ case "Unknown": return "Schema.Unknown";
195
+ }
196
+ };
197
+ const emitTypeAlias = (name, expression) => {
198
+ const line = `export type ${name} = ${expression};`;
199
+ return line.length > 80 ? [`export type ${name} =`, `${indent(1)}${expression};`] : [line];
200
+ };
201
+ const schemaUsesEnum = (schema) => {
202
+ switch (schema._tag) {
203
+ case "Enum": return true;
204
+ case "Array": return schemaUsesEnum(schema.item);
205
+ default: return false;
206
+ }
207
+ };
208
+ const codecUsesSchema = (codec) => codec._tag === "Schema" || codec._tag === "SchemaArray" || codec._tag === "EnumArray";
209
+ const codecUsesEnum = (codec) => codec._tag === "Enum" || codec._tag === "EnumArray";
210
+ const codecUsesStructure = (codec) => codec._tag === "Structure" || codec._tag === "StructureArray";
211
+ const emitEmptyModule = () => [
212
+ generatedHeader,
213
+ "",
214
+ "export {};",
215
+ ""
216
+ ].join("\n");
217
+ const emitIndex = () => [
218
+ generatedHeader,
219
+ "",
220
+ "export * as NodeIds from \"./nodeIds.js\";",
221
+ "export * as Enums from \"./enums.js\";",
222
+ "export * as Structures from \"./structures.js\";",
223
+ "export * as Variables from \"./variables.js\";",
224
+ ""
225
+ ].join("\n");
226
+ const pathSort = (left, right) => left.generatedPath.join(".").localeCompare(right.generatedPath.join(".")) || (left.path ?? []).join(".").localeCompare((right.path ?? []).join("."));
227
+ const keySort = (left, right) => left[0].localeCompare(right[0]);
228
+ const isLeafValue = (node) => node.value !== void 0 && node.children.size === 0;
229
+ const indent = (depth) => " ".repeat(depth);
230
+
231
+ //#endregion
232
+ export { emit, generatedHeader };
233
+ //# sourceMappingURL=emit.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit.mjs","names":["root: TreeNode","dataTypes: TreeNode","localImports: string[]"],"sources":["../src/emit.ts"],"sourcesContent":["import type {\n CodegenModel,\n DataTypeNodeIdDefinition,\n EnumDefinition,\n GeneratedFile,\n NodeIdDefinition,\n SchemaExpression,\n StructureDefinition,\n VariableCodecExpression,\n VariableDefinition,\n} from \"./internal/types.js\";\n\nexport const generatedHeader =\n \"// Generated by @effect-opcua/codegen. Do not edit manually.\";\n\nexport const emit = (model: CodegenModel): readonly GeneratedFile[] => [\n {\n path: \"nodeIds.ts\",\n contents: emitNodeIds(model.nodeIds, model.dataTypeNodeIds),\n },\n { path: \"enums.ts\", contents: emitEnums(model.enums) },\n { path: \"structures.ts\", contents: emitStructures(model.structures) },\n { path: \"variables.ts\", contents: emitVariables(model.variables) },\n { path: \"index.ts\", contents: emitIndex() },\n];\n\ntype TreeNode = {\n value?: string;\n variable?: VariableDefinition;\n children: Map<string, TreeNode>;\n};\n\nconst emitNodeIds = (\n nodeIds: readonly NodeIdDefinition[],\n dataTypeNodeIds: readonly DataTypeNodeIdDefinition[],\n) => {\n const root: TreeNode = { children: new Map() };\n for (const nodeId of [...nodeIds].sort(pathSort)) {\n let current = root;\n for (const segment of nodeId.generatedPath) {\n const child = current.children.get(segment) ?? { children: new Map() };\n current.children.set(segment, child);\n current = child;\n }\n current.value = nodeId.nodeId;\n }\n if (dataTypeNodeIds.length > 0) {\n const dataTypes: TreeNode = { children: new Map() };\n for (const dataType of [...dataTypeNodeIds].sort((left, right) =>\n left.name.localeCompare(right.name),\n )) {\n dataTypes.children.set(dataType.name, {\n value: dataType.nodeId,\n children: new Map(),\n });\n }\n root.children.set(\"DataTypes\", dataTypes);\n }\n const topLevel = [...root.children.entries()].sort(keySort);\n if (topLevel.length === 0) return emitEmptyModule();\n return [\n generatedHeader,\n \"\",\n ...topLevel.map(\n ([key, value]) => `export const ${key} = ${emitTree(value, 0)} as const;`,\n ),\n \"\",\n ].join(\"\\n\");\n};\n\nconst emitTree = (node: TreeNode, depth: number): string => {\n if (node.value !== undefined && node.children.size === 0) {\n return JSON.stringify(node.value);\n }\n const lines = [\"{\"];\n for (const [key, child] of [...node.children.entries()].sort(keySort)) {\n const value = emitTree(child, depth + 1);\n const property = `${indent(depth + 1)}${key}: ${value},`;\n lines.push(\n property.length > 80 && isLeafValue(child)\n ? `${indent(depth + 1)}${key}:\\n${indent(depth + 2)}${value},`\n : property,\n );\n }\n lines.push(`${indent(depth)}}`);\n return lines.join(\"\\n\");\n};\n\nconst emitEnums = (enums: readonly EnumDefinition[]) => {\n if (enums.length === 0) return emitEmptyModule();\n const lines = [generatedHeader, \"\", 'import { Schema } from \"effect\";', \"\"];\n for (const item of [...enums].sort((left, right) =>\n left.name.localeCompare(right.name),\n )) {\n lines.push(`export const ${item.name} = {`);\n for (const member of item.members) {\n lines.push(`${indent(1)}${member.name}: ${member.value},`);\n }\n lines.push(\"} as const;\");\n lines.push(\"\");\n lines.push(\n ...emitTypeAlias(\n item.name,\n `(typeof ${item.name})[keyof typeof ${item.name}]`,\n ),\n );\n lines.push(\"\");\n lines.push(`export const ${item.name}Schema = Schema.Literals([`);\n for (const member of item.members) {\n lines.push(`${indent(1)}${item.name}.${member.name},`);\n }\n lines.push(\"]);\");\n lines.push(\"\");\n }\n return lines.join(\"\\n\");\n};\n\nconst emitStructures = (structures: readonly StructureDefinition[]) => {\n if (structures.length === 0) return emitEmptyModule();\n const lines = [\n generatedHeader,\n \"\",\n 'import { Opcua } from \"@effect-opcua/client\";',\n 'import { Schema } from \"effect\";',\n \"\",\n ];\n if (\n structures.some((structure) =>\n structure.fields.some((field) => schemaUsesEnum(field.schema)),\n )\n ) {\n lines.push('import * as Enums from \"./enums.js\";');\n }\n lines.push('import * as NodeIds from \"./nodeIds.js\";');\n lines.push(\"\");\n for (const item of structures) {\n lines.push(`export const ${item.name}Schema = Schema.Struct({`);\n for (const field of item.fields) {\n const schema = emitFieldSchema(field.schema);\n lines.push(\n `${indent(1)}${field.name}: ${\n field.optional ? `Schema.optional(${schema})` : schema\n },`,\n );\n }\n const encodedKeys = item.fields.filter(\n (field) => field.name !== field.encodedName,\n );\n if (encodedKeys.length === 0) {\n lines.push(\"});\");\n } else {\n lines.push(\"}).pipe(\");\n lines.push(`${indent(1)}Schema.encodeKeys({`);\n for (const field of encodedKeys) {\n lines.push(\n `${indent(2)}${field.name}: ${JSON.stringify(field.encodedName)},`,\n );\n }\n lines.push(`${indent(1)}}),`);\n lines.push(\");\");\n }\n lines.push(\"\");\n lines.push(...emitTypeAlias(item.name, `typeof ${item.name}Schema.Type`));\n lines.push(\"\");\n lines.push(`export const ${item.name} = Opcua.structure({`);\n lines.push(`${indent(1)}name: ${JSON.stringify(item.browseName)},`);\n lines.push(`${indent(1)}dataTypeId: NodeIds.DataTypes.${item.name},`);\n lines.push(`${indent(1)}schema: ${item.name}Schema,`);\n lines.push(\"});\");\n lines.push(\"\");\n }\n return lines.join(\"\\n\");\n};\n\nconst emitVariables = (variables: readonly VariableDefinition[]) => {\n const lines = [\n generatedHeader,\n \"\",\n 'import { Opcua } from \"@effect-opcua/client\";',\n ];\n if (variables.some((variable) => codecUsesSchema(variable.codec))) {\n lines.push('import { Schema } from \"effect\";');\n }\n const localImports: string[] = [];\n if (variables.some((variable) => codecUsesEnum(variable.codec))) {\n localImports.push('import * as Enums from \"./enums.js\";');\n }\n localImports.push('import * as NodeIds from \"./nodeIds.js\";');\n if (variables.some((variable) => codecUsesStructure(variable.codec))) {\n localImports.push('import * as Structures from \"./structures.js\";');\n }\n lines.push(\"\", ...localImports, \"\");\n if (variables.length === 0) {\n lines.push(\"export {};\", \"\");\n return lines.join(\"\\n\");\n }\n const root = variableTree(variables);\n for (const [key, child] of [...root.children.entries()].sort(keySort)) {\n const assertion =\n child.variable && child.children.size === 0 ? \"\" : \" as const\";\n lines.push(\n `export const ${key} = ${emitVariableTree(child, 0)}${assertion};`,\n );\n lines.push(\"\");\n }\n return lines.join(\"\\n\");\n};\n\nconst variableTree = (variables: readonly VariableDefinition[]) => {\n const root: TreeNode = { children: new Map() };\n for (const variable of [...variables].sort(pathSort)) {\n let current = root;\n for (const segment of variable.generatedPath) {\n const child = current.children.get(segment) ?? { children: new Map() };\n current.children.set(segment, child);\n current = child;\n }\n current.variable = variable;\n }\n return root;\n};\n\nconst emitVariableTree = (node: TreeNode, depth: number): string => {\n if (node.variable && node.children.size === 0) {\n return emitVariable(node.variable, depth);\n }\n const lines = [\"{\"];\n for (const [key, child] of [...node.children.entries()].sort(keySort)) {\n lines.push(\n `${indent(depth + 1)}${key}: ${emitVariableTree(child, depth + 1)},`,\n );\n }\n lines.push(`${indent(depth)}}`);\n return lines.join(\"\\n\");\n};\n\nconst emitVariable = (variable: VariableDefinition, depth: number) => {\n const lines = [\"Opcua.variable({\"];\n lines.push(\n `${indent(depth + 1)}nodeId: NodeIds.${variable.generatedPath.join(\".\")},`,\n );\n lines.push(`${indent(depth + 1)}codec: ${emitCodec(variable.codec)},`);\n if (variable.access !== \"read\") {\n lines.push(\n `${indent(depth + 1)}access: ${JSON.stringify(variable.access)},`,\n );\n }\n lines.push(`${indent(depth)}})`);\n return lines.join(\"\\n\");\n};\n\nconst emitCodec = (codec: VariableCodecExpression) => {\n switch (codec._tag) {\n case \"Schema\":\n return `Opcua.schema(Schema.${codec.schema})`;\n case \"SchemaArray\":\n return `Opcua.schema(Schema.Array(Schema.${codec.element}))`;\n case \"Enum\":\n return `Opcua.schema(Enums.${codec.name}Schema)`;\n case \"EnumArray\":\n return `Opcua.schema(Schema.Array(Enums.${codec.name}Schema))`;\n case \"Structure\":\n return `Structures.${codec.name}`;\n case \"StructureArray\":\n return `Opcua.structureArray(Structures.${codec.name})`;\n case \"Dynamic\":\n return \"Opcua.dynamic()\";\n }\n};\n\nconst emitFieldSchema = (schema: SchemaExpression): string => {\n switch (schema._tag) {\n case \"Scalar\":\n return `Schema.${schema.schema}`;\n case \"Array\":\n return `Schema.Array(${emitFieldSchema(schema.item)})`;\n case \"Enum\":\n return `Enums.${schema.name}Schema`;\n case \"Structure\":\n return `${schema.name}Schema`;\n case \"Unknown\":\n return \"Schema.Unknown\";\n }\n};\n\nconst emitTypeAlias = (name: string, expression: string): readonly string[] => {\n const line = `export type ${name} = ${expression};`;\n return line.length > 80\n ? [`export type ${name} =`, `${indent(1)}${expression};`]\n : [line];\n};\n\nconst schemaUsesEnum = (schema: SchemaExpression): boolean => {\n switch (schema._tag) {\n case \"Enum\":\n return true;\n case \"Array\":\n return schemaUsesEnum(schema.item);\n default:\n return false;\n }\n};\n\nconst codecUsesSchema = (codec: VariableCodecExpression): boolean =>\n codec._tag === \"Schema\" ||\n codec._tag === \"SchemaArray\" ||\n codec._tag === \"EnumArray\";\n\nconst codecUsesEnum = (codec: VariableCodecExpression): boolean =>\n codec._tag === \"Enum\" || codec._tag === \"EnumArray\";\n\nconst codecUsesStructure = (codec: VariableCodecExpression): boolean =>\n codec._tag === \"Structure\" || codec._tag === \"StructureArray\";\n\nconst emitEmptyModule = () =>\n [generatedHeader, \"\", \"export {};\", \"\"].join(\"\\n\");\n\nconst emitIndex = () =>\n [\n generatedHeader,\n \"\",\n 'export * as NodeIds from \"./nodeIds.js\";',\n 'export * as Enums from \"./enums.js\";',\n 'export * as Structures from \"./structures.js\";',\n 'export * as Variables from \"./variables.js\";',\n \"\",\n ].join(\"\\n\");\n\nconst pathSort = <\n T extends {\n readonly generatedPath: readonly string[];\n readonly path?: readonly string[];\n },\n>(\n left: T,\n right: T,\n) =>\n left.generatedPath.join(\".\").localeCompare(right.generatedPath.join(\".\")) ||\n (left.path ?? []).join(\".\").localeCompare((right.path ?? []).join(\".\"));\n\nconst keySort = (\n left: readonly [string, TreeNode],\n right: readonly [string, TreeNode],\n) => left[0].localeCompare(right[0]);\n\nconst isLeafValue = (node: TreeNode) =>\n node.value !== undefined && node.children.size === 0;\n\nconst indent = (depth: number) => \" \".repeat(depth);\n"],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { CodegenIssue } from "./types.mjs";
2
+ import * as effect_Types0 from "effect/Types";
3
+ import * as effect_Cause0 from "effect/Cause";
4
+
5
+ //#region src/errors.d.ts
6
+ declare const CodegenError_base: new <A extends Record<string, any> = {}>(args: effect_Types0.VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => effect_Cause0.YieldableError & {
7
+ readonly _tag: "CodegenError";
8
+ } & Readonly<A>;
9
+ declare class CodegenError extends CodegenError_base<{
10
+ readonly reason: CodegenErrorReason;
11
+ readonly issues: readonly CodegenIssue[];
12
+ }> {}
13
+ type CodegenErrorReason = {
14
+ readonly _tag: "Config";
15
+ readonly path?: string;
16
+ } | {
17
+ readonly _tag: "Discovery";
18
+ } | {
19
+ readonly _tag: "Compile";
20
+ } | {
21
+ readonly _tag: "Output";
22
+ };
23
+ declare const codegenError: (reason: CodegenErrorReason, issues?: readonly CodegenIssue[]) => CodegenError;
24
+ declare const invalidConfig: (message: string, cause?: unknown) => CodegenError;
25
+ //#endregion
26
+ export { CodegenError, CodegenErrorReason, codegenError, invalidConfig };
27
+ //# sourceMappingURL=errors.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.mts","names":[],"sources":["../src/errors.ts"],"sourcesContent":[],"mappings":";;;;;cAE+C;;;cAElC,YAAA,SAAqB;EAFa,SAAA,MAAA,EAG5B,kBAH4B;4BAInB;;KAGhB,kBAAA;;;;;;;;EALC,SAAA,IAAA,EAAa,QAAA;CACP;AACS,cASf,YATe,EAAA,CAAA,MAAA,EAUlB,kBAVkB,EAAA,MAAA,CAAA,EAAA,SAWT,YAXS,EAAA,EAAA,GAWU,YAXV;AAFM,cAgBrB,aAhBqB,EAAA,CAAA,OAAA,EAAA,MAAA,EAAA,KAAA,CAAA,EAAA,OAAA,EAAA,GAgB4B,YAhB5B"}
@@ -0,0 +1,18 @@
1
+ import { Data } from "effect";
2
+
3
+ //#region src/errors.ts
4
+ var CodegenError = class extends Data.TaggedError("CodegenError") {};
5
+ const codegenError = (reason, issues = []) => new CodegenError({
6
+ reason,
7
+ issues
8
+ });
9
+ const invalidConfig = (message, cause) => codegenError({ _tag: "Config" }, [{
10
+ severity: "error",
11
+ code: "config.invalid",
12
+ message,
13
+ cause
14
+ }]);
15
+
16
+ //#endregion
17
+ export { CodegenError, codegenError, invalidConfig };
18
+ //# sourceMappingURL=errors.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.mjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["import { Data } from \"effect\";\n\nimport type { CodegenIssue } from \"./types.js\";\n\nexport class CodegenError extends Data.TaggedError(\"CodegenError\")<{\n readonly reason: CodegenErrorReason;\n readonly issues: readonly CodegenIssue[];\n}> {}\n\nexport type CodegenErrorReason =\n | { readonly _tag: \"Config\"; readonly path?: string }\n | { readonly _tag: \"Discovery\" }\n | { readonly _tag: \"Compile\" }\n | { readonly _tag: \"Output\" };\n\nexport const codegenError = (\n reason: CodegenErrorReason,\n issues: readonly CodegenIssue[] = [],\n) => new CodegenError({ reason, issues });\n\nexport const invalidConfig = (message: string, cause?: unknown) =>\n codegenError({ _tag: \"Config\" }, [\n {\n severity: \"error\",\n code: \"config.invalid\",\n message,\n cause,\n },\n ]);\n"],"mappings":";;;AAIA,IAAa,eAAb,cAAkC,KAAK,YAAY,eAAe,CAG/D;AAQH,MAAa,gBACX,QACA,SAAkC,EAAE,KACjC,IAAI,aAAa;CAAE;CAAQ;CAAQ,CAAC;AAEzC,MAAa,iBAAiB,SAAiB,UAC7C,aAAa,EAAE,MAAM,UAAU,EAAE,CAC/B;CACE,UAAU;CACV,MAAM;CACN;CACA;CACD,CACF,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { CheckResult, CodegenConfig, GenerateResult } from "./types.mjs";
2
+ import { CodegenError } from "./errors.mjs";
3
+ import { OpcuaError as OpcuaError$1 } from "./client/src/OpcuaError.mjs";
4
+ import "./client/src/index.mjs";
5
+ import { CodegenPlan, DiscoveryModel, NormalizedCodegenConfig } from "./internal/types.mjs";
6
+ import { Effect, Scope } from "effect";
7
+
8
+ //#region src/generate.d.ts
9
+ type OpcuaError = OpcuaError$1;
10
+ declare const generate: (config: CodegenConfig) => Effect.Effect<GenerateResult, CodegenError | OpcuaError, Scope.Scope>;
11
+ declare const check: (config: CodegenConfig) => Effect.Effect<CheckResult, CodegenError | OpcuaError, Scope.Scope>;
12
+ declare const generateFromNormalizedConfig: (config: NormalizedCodegenConfig) => Effect.Effect<GenerateResult, CodegenError | OpcuaError, Scope.Scope>;
13
+ declare const checkFromNormalizedConfig: (config: NormalizedCodegenConfig) => Effect.Effect<CheckResult, CodegenError | OpcuaError, Scope.Scope>;
14
+ declare const planFromDiscovery: (config: NormalizedCodegenConfig, discovery: DiscoveryModel) => Effect.Effect<CodegenPlan, CodegenError>;
15
+ declare const discoverFromServer: (config: NormalizedCodegenConfig) => Effect.Effect<DiscoveryModel, CodegenError | OpcuaError, Scope.Scope>;
16
+ declare const planFromServer: (config: NormalizedCodegenConfig) => Effect.Effect<CodegenPlan, CodegenError | OpcuaError, Scope.Scope>;
17
+ //#endregion
18
+ export { check, checkFromNormalizedConfig, discoverFromServer, generate, generateFromNormalizedConfig, planFromDiscovery, planFromServer };
19
+ //# sourceMappingURL=generate.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.d.mts","names":[],"sources":["../src/generate.ts"],"sourcesContent":[],"mappings":";;;;;;;;KAyBK,UAAA,GAAa;cAEL,mBACH,kBACP,MAAA,CAAO,OACR,gBAAc,YAAA,GACuB,YACrC,KAAA,CAAM;cAOK,gBACH,kBACP,MAAA,CAAO,OACR,aAAW,YAAA,GAC0B,YACrC,KAAA,CAAM;cAOK,uCACH,4BACP,MAAA,CAAO,OACR,gBAAc,YAAA,GACuB,YACrC,KAAA,CAAM;AA/BH,cA8CQ,yBA9CiC,EAAA,CAAA,MAAA,EA+CpC,uBA/CoC,EAAA,GAgD3C,MAAA,CAAO,MAhDoC,CAiD5C,WAjD4C,EAiDjC,YAAA,GAC0B,UAlDO,EAmD5C,KAAA,CAAM,KAnDsC,CAAA;AAEjC,cAsIA,iBA5HT,EAAA,CAAA,MAAA,EA6HM,uBA7HN,EAAA,SAAA,EA8HS,cA9HT,EAAA,GA+HD,MAAA,CAAO,MA/HN,CA+Ha,WA/Hb,EA+HwB,YAAA,CA/HxB;AATM,cAsJG,kBAtJH,EAAA,CAAA,MAAA,EAuJA,uBAvJA,EAAA,GAwJP,MAAA,CAAO,MAxJA,CAyJR,cAzJQ,EAyJM,YAAA,GACuB,UA1J7B,EA2JR,KAAA,CAAM,KA3JE,CAAA;AAER,cA0KW,cA1KX,EAAA,CAAA,MAAA,EA2KQ,uBA3KR,EAAA,GA4KC,MAAA,CAAO,MA5KR,CA6KA,WA7KA,EA6KW,YAAA,GAC0B,UA9KrC,EA+KA,KAAA,CAAM,KA/KN,CAAA"}
@@ -0,0 +1,172 @@
1
+ import { codegenError } from "./errors.mjs";
2
+ import { enforceIssuePolicy, issue, sortIssues } from "./diagnostics.mjs";
3
+ import { compile } from "./compile.mjs";
4
+ import { normalizeConfig } from "./config.mjs";
5
+ import { discover } from "./discover.mjs";
6
+ import { emit, generatedHeader } from "./emit.mjs";
7
+ import { Effect, Layer } from "effect";
8
+ import { dirname, join, resolve } from "node:path";
9
+ import { OpcuaClient, OpcuaSession } from "@effect-opcua/client";
10
+ import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
11
+
12
+ //#region src/generate.ts
13
+ const generate = (config) => Effect.gen(function* () {
14
+ return yield* generateFromNormalizedConfig(yield* normalizeConfig(config));
15
+ });
16
+ const check = (config) => Effect.gen(function* () {
17
+ return yield* checkFromNormalizedConfig(yield* normalizeConfig(config));
18
+ });
19
+ const generateFromNormalizedConfig = (config) => Effect.gen(function* () {
20
+ const plan = yield* planFromServer(config);
21
+ const writeResult = yield* writeGeneratedFiles(config.outputDir, plan.files);
22
+ return {
23
+ issues: sortIssues([...plan.issues, ...writeResult.issues]),
24
+ writtenFiles: writeResult.writtenFiles
25
+ };
26
+ });
27
+ const checkFromNormalizedConfig = (config) => Effect.gen(function* () {
28
+ const plan = yield* planFromServer(config);
29
+ const checked = yield* checkGeneratedFiles(config.outputDir, plan.files);
30
+ return {
31
+ issues: sortIssues([...plan.issues, ...checked.issues]),
32
+ staleFiles: checked.staleFiles,
33
+ missingFiles: checked.missingFiles,
34
+ ok: checked.staleFiles.length === 0 && checked.missingFiles.length === 0
35
+ };
36
+ });
37
+ const writeGeneratedFiles = (outputDir, files) => Effect.gen(function* () {
38
+ const absoluteOutputDir = resolve(outputDir);
39
+ yield* mkdirEffect(absoluteOutputDir);
40
+ const writtenFiles = [];
41
+ const issues = [];
42
+ for (const file of files) {
43
+ const path = join(absoluteOutputDir, file.path);
44
+ yield* assertGeneratedOwnership(path);
45
+ yield* mkdirEffect(dirname(path));
46
+ yield* Effect.tryPromise({
47
+ try: () => writeFile(path, file.contents, "utf8"),
48
+ catch: (cause) => codegenError({ _tag: "Output" }, [{
49
+ severity: "error",
50
+ code: "file.writeFailed",
51
+ message: `Failed to write ${path}`,
52
+ file: path,
53
+ cause
54
+ }])
55
+ });
56
+ writtenFiles.push(path);
57
+ issues.push(issue("file.written", {
58
+ message: `Wrote ${path}`,
59
+ file: path
60
+ }));
61
+ }
62
+ return {
63
+ writtenFiles,
64
+ issues
65
+ };
66
+ });
67
+ const checkGeneratedFiles = (outputDir, files) => Effect.gen(function* () {
68
+ const absoluteOutputDir = resolve(outputDir);
69
+ const staleFiles = [];
70
+ const missingFiles = [];
71
+ const issues = [];
72
+ const expectedPaths = new Set(files.map((file) => file.path));
73
+ for (const file of files) {
74
+ const path = join(absoluteOutputDir, file.path);
75
+ const existing = yield* readExistingFile(path);
76
+ if (existing === void 0) missingFiles.push(path);
77
+ else if (existing !== file.contents) staleFiles.push(path);
78
+ issues.push(issue("file.checked", {
79
+ message: `Checked ${path}`,
80
+ file: path
81
+ }));
82
+ }
83
+ for (const file of yield* obsoleteGeneratedFiles(absoluteOutputDir, expectedPaths)) staleFiles.push(file);
84
+ return {
85
+ staleFiles,
86
+ missingFiles,
87
+ issues
88
+ };
89
+ });
90
+ const planFromDiscovery = (config, discovery) => Effect.gen(function* () {
91
+ const model = yield* compile(config, discovery);
92
+ const issues = yield* enforceIssuePolicy(config.diagnostics.warningsAsErrors, model.issues);
93
+ return {
94
+ model,
95
+ files: emit(model),
96
+ issues
97
+ };
98
+ });
99
+ const discoverFromServer = (config) => discover(config).pipe(Effect.provide(OpcuaSession.layer({ userIdentity: config.userIdentity }).pipe(Layer.provideMerge(OpcuaClient.layer({
100
+ endpointUrl: config.endpointUrl,
101
+ clientOptions: config.clientOptions
102
+ })))));
103
+ const planFromServer = (config) => Effect.gen(function* () {
104
+ return yield* planFromDiscovery(config, yield* discoverFromServer(config));
105
+ });
106
+ const mkdirEffect = (path) => Effect.tryPromise({
107
+ try: () => mkdir(path, { recursive: true }),
108
+ catch: (cause) => codegenError({ _tag: "Output" }, [{
109
+ severity: "error",
110
+ code: "file.mkdirFailed",
111
+ message: `Failed to create directory ${path}`,
112
+ file: path,
113
+ cause
114
+ }])
115
+ });
116
+ const assertGeneratedOwnership = (path) => Effect.gen(function* () {
117
+ const existing = yield* readExistingFile(path);
118
+ if (existing !== void 0 && !existing.startsWith(generatedHeader)) return yield* Effect.fail(codegenError({ _tag: "Output" }, [{
119
+ severity: "error",
120
+ code: "file.ownershipViolation",
121
+ message: `Refusing to overwrite non-generated file ${path}`,
122
+ file: path
123
+ }]));
124
+ });
125
+ const obsoleteGeneratedFiles = (outputDir, expectedPaths) => Effect.gen(function* () {
126
+ const entries = yield* Effect.tryPromise({
127
+ try: async () => {
128
+ try {
129
+ return await readdir(outputDir, { withFileTypes: true });
130
+ } catch (cause) {
131
+ if (isNodeError(cause) && cause.code === "ENOENT") return [];
132
+ throw cause;
133
+ }
134
+ },
135
+ catch: (cause) => codegenError({ _tag: "Output" }, [{
136
+ severity: "error",
137
+ code: "file.readFailed",
138
+ message: `Failed to read directory ${outputDir}`,
139
+ file: outputDir,
140
+ cause
141
+ }])
142
+ });
143
+ const stale = [];
144
+ for (const entry of entries) {
145
+ if (!entry.isFile() || expectedPaths.has(entry.name)) continue;
146
+ const path = join(outputDir, entry.name);
147
+ if ((yield* readExistingFile(path))?.startsWith(generatedHeader)) stale.push(path);
148
+ }
149
+ return stale;
150
+ });
151
+ const readExistingFile = (path) => Effect.tryPromise({
152
+ try: async () => {
153
+ try {
154
+ return await readFile(path, "utf8");
155
+ } catch (cause) {
156
+ if (isNodeError(cause) && cause.code === "ENOENT") return void 0;
157
+ throw cause;
158
+ }
159
+ },
160
+ catch: (cause) => codegenError({ _tag: "Output" }, [{
161
+ severity: "error",
162
+ code: "file.readFailed",
163
+ message: `Failed to read ${path}`,
164
+ file: path,
165
+ cause
166
+ }])
167
+ });
168
+ const isNodeError = (cause) => typeof cause === "object" && cause !== null && "code" in cause;
169
+
170
+ //#endregion
171
+ export { check, checkFromNormalizedConfig, discoverFromServer, generate, generateFromNormalizedConfig, planFromDiscovery, planFromServer };
172
+ //# sourceMappingURL=generate.mjs.map