fix(deps): update dependency node-opcua to v2.184.2 - #795
Open
renovate[bot] wants to merge 1 commit into
Open
renovate[bot] wants to merge 1 commit into
renovate[bot] wants to merge 1 commit into
Conversation
renovate
Bot
force-pushed
the
renovate/node-opcua-2.x
branch
from
September 5, 2026 22:28
6e38cf0 to
48f653c
Compare
renovate
Bot
force-pushed
the
renovate/node-opcua-2.x
branch
from
September 8, 2026 14:39
48f653c to
1f348ad
Compare
renovate
Bot
force-pushed
the
renovate/node-opcua-2.x
branch
from
September 9, 2026 17:52
1f348ad to
b4a010a
Compare
renovate
Bot
force-pushed
the
renovate/node-opcua-2.x
branch
from
September 10, 2026 23:38
b4a010a to
ecc61db
Compare
renovate
Bot
force-pushed
the
renovate/node-opcua-2.x
branch
from
September 11, 2026 15:05
ecc61db to
41c4f65
Compare
renovate
Bot
force-pushed
the
renovate/node-opcua-2.x
branch
from
September 14, 2026 16:04
41c4f65 to
e77592a
Compare
renovate
Bot
force-pushed
the
renovate/node-opcua-2.x
branch
from
September 14, 2026 19:35
e77592a to
b84c709
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
2.180.0→2.184.2Release Notes
node-opcua/node-opcua (node-opcua)
v2.184.2Compare Source
v2.184.1Compare Source
v2.184.0: : Modules, All The Way DownCompare Source
node-opcua 2.184.0: Modules, All The Way Down
Compare:
v2.183.0...v2.184.0· 93 commits · 48 pull requests · includes the2.183.1patchTL;DR
Every one of the 122 packages is now a real ES module, the umbrella included. node-opcua was written when CommonJS was the only option, and the whole workspace has just moved across in seven batches, from the eight leaf packages up through the encoding core, the address space, the client and server chain, and finally
node-opcuaitself. Your application keeps running:require("node-opcua")works exactly as it did, because Node has read ES modules fromrequire()since 22.12 and the project has required 22.13 since last month. Two consumer fixtures, one CommonJS and one ESM, prove it on every single run. A CommonJS TypeScript project does need one line changed before it compiles again, and the banner above says which line.The toolchain moved with it. The workspace compiles with TypeScript 7, which took a cold build from 192 seconds to 38, a real saving on every push since CI builds seven times before a test runs. Declaration maps ship now, so "go to definition" on a node-opcua symbol lands in the actual source instead of stopping at a
.d.ts. Loading the SDK resolves a third fewer files after the generated nodeset packages stopped requiring 532 modules that contain nothing at run time. And five new gates check what npm actually publishes, which immediately found one companion nodeset package that had been shipping with no compiled code at all, and a sample command that had pointed at a deleted file for nearly three years.Alongside it, the alarm story continues and the test suite got honest. Namespaces can now be deleted and repopulated, which takes a model recompile from 442 ms to single digits, the work behind an editor that stays warm. Alarms and Conditions clients finally get their condition filters answered, so the compliance tool's alarm collector runs at last, after reporting "no alarms received" for months. The suite itself now runs on Node's own type stripping rather than a transpiler, which stopped coverage being measured against compiled output nobody edits: the reported figure went from 79% to 91.7% without a single new test, because 32 500 covered lines had been counted against the wrong files.
Highlights
require("node-opcua")is unaffected, proven by a CommonJS fixture on every run.require("node-opcua")goes from 1 606 files to 1 074.deleteNamespace, so a model can be emptied and repopulated in milliseconds instead of rebuilding the address space.If your build stops compiling
node-opcuadeclares"type": "module"from this release. 2.183.1 declared notypeat all, so the umbrella went from format-neutral to ESM-only in one step. That is the change most likely to reach you, and it deserves more than a line.What still works, unchanged.
require("node-opcua")from a CommonJS file returns the module and every named export, because Node has read ES modules fromrequire()without a flag since 22.12 and this project has declared a floor of 22.13 since 2.183.0. There is noexportsmap on the umbrella, somainandtypesresolve exactly as before. Verified directly: a CommonJS file requiring the published package resolvesOPCUAClient, andresolveNodeId("ns=0;i=85")returns a realNodeId. The precondition for that is no module-scopeawaitanywhere in the graph, which thecheck:tlagate has enforced since 2.181.0.What stops. A CommonJS TypeScript project compiling against it reports one error per import site:
The compiler is describing an older Node than you are running. Your project says CommonJS, the dependency says ESM, and under
module: node16TypeScript still treats that pair as forbidden. It is a compile-time verdict, not a runtime one.Exactly one consumer shape breaks. Both versions were installed from npm and driven through the same four projects, compiling and then running the emitted output:
require("node-opcua")module: commonjs+moduleResolution: nodemodule: node16module: nodenextThe fix is
nodenext, and your project stays CommonJS:{ "compilerOptions": { "module": "nodenext", "moduleResolution": "nodenext" } }nodenextis the setting that knows a modern Node canrequire()an ES module;node16is the one that does not. You do not add"type": "module", you do not rewrite imports, and you do not switch toawait import(). The compiler keeps emitting CommonJS: withnodenext,tscemitsconst node_opcua_1 = require("node-opcua")and the result runs.This was confirmed on a real consumer, not only on a probe. A 145-file package with 19 node-opcua dependencies went from 258 errors to 0 with those two settings and nothing else changed, and its full pipeline then ran end to end.
Three error codes, one cause. The same upgrade produces
TS1479on value imports,TS1541on type-only imports andTS1542. In that 145-file package the split was 180, 76 and 2. All three are cured by the one line above.TS1541is a trap worth naming: it suggests a per-importresolution-modeattribute, which appears to work, so you can spend an afternoon hand-editing a third of the errors before discovering thatTS1479next door cannot be fixed that way at all.Converting to ESM also works, and costs much more. The moment you set
"type": "module"your own code inherits ESM specifier strictness: every relative import needs an explicit.js, measured at 513 rewrites across 107 files in that same package. Extensionless subpaths into node-opcua packages, such asnode-opcua-address-space/nodeJS, also stop resolving. Undernodenext-as-CommonJS both keep working, because these packages publish noexportsmap and CommonJS still guesses extensions. The cost of converting is not one setting, it is every import you own.One caveat if you are on TypeScript 5.
moduleResolution: "node"ignores bothtypeandexports, so a project on that setting compiles today with no change at all. That is not a long-term answer, since TypeScript 7 removed it outright (TS5108), but it explains why some packages in one workspace break and others do not.If the errors do not go away, delete the build cache. This is the most likely reason you will think the fix failed. With
incremental: true, whichcomposite: trueimplies, TypeScript caches diagnostics per file and a change in an extendedtsconfig.jsondoes not invalidate them, so old files replay old errors. Runtsc -b --force, or delete every.tsbuildinfo. Note that whenoutDiris set the cache lives inside the output directory, not beside yourtsconfig.json, so deleting the file you expect to find achieves nothing. Reproduced:node16gives oneTS1479; switching tonodenextand deleting./tsconfig.tsbuildinfostill gives one; deletingout/tsconfig.tsbuildinfogives zero, with no source change.Bundlers: most are fine, and the exception is not about ES module support. What matters is whether your bundler emits the
require()and lets Node resolve it, or pre-validates the externalisation against a rule that predates Node 22.12. esbuild is verified working, externalising the whole family from a CommonJS output with a 658-test suite passing. Next.js 16.2.6 with Turbopack is confirmed broken: it refuses to externalise an ES module, bundles it instead, and the build then dies because those packages were externalised precisely for using__dirnameand reading nodeset files from disk. Its message says "The package seems invalid", which describes its own check rather than the package, and no node-opcua change can fix it.For scale, in the 22-package workspace where all of this was measured, twenty-one packages upgraded untouched: a CLI, a language server, an editor extension and several back-end services. One Next.js application broke.
The full guide, with the FAQ and the measurements, is at documentation/migrating_to_esm.md.
Every package is an ES module, the umbrella included.
"type": "module"on all 122, where 2.183.1 declared none. Nothing changes at run time, and a CommonJS TypeScript project needs one line changed to compile. See If your build stops compiling. #1690 through #1704A project compiling against node-opcua needs TypeScript 5.0 or above. The generated nodeset indexes now use
export type *, which is TypeScript 5.0 syntax and appears in published.d.tsfiles thatnode-opcua-address-spacere-exports. TypeScript 4.x cannot parse them. TypeScript 5.0 is from March 2023 and the Node floor is already 22.13. #1688Hand-run scripts are renamed to
.cjs. Roughly 40 CommonJS scripts acrossbin/and playground directories keep their CommonJS form under an explicit extension. Three published commands moved with their manifest entries, so nothing a consumer types changes. The end-to-end tests that spawn a server by file name were updated, a reference no compiler or gate can see. #1701 #1703 #1704node-opcua-samplesgenerates its certificate folder as CommonJS.node-opcua-pkiwrites a CommonJScertificates/config.jsand then requires it; once the package became a module that file was read as ESM andpkifailed while still exiting 0. Acertificates/package.jsoncarrying{"type":"commonjs"}scopes the generated folder back. #1704Fourteen type re-exports became
export type.export { SomeInterface } from "..."is elided by a whole-program compiler and kept by a single-file transpiler, where it becomes a link error under ESM. Five were in thenode-opcuaandnode-opcua-cliententry points, so they would have failed to link for any ESM consumer.isolatedModulesis now on across the workspace, so the class cannot return. #1710A test file with
#in its name is renamed. ESM resolves a specifier as a URL, so#​804.jswas read as a fragment and discarded. It was the only such file in the repository, and the gate now reports#and?in a relative specifier. #1711Every Variable created by one nodeset load carries the same
sourceTimestamp. One clock reading is taken per load and reused, keyed on the address space being loaded and reference counted, so a server writing elsewhere or outside a load still gets a real clock. #1728A state machine type declares the transition event it raises. node-opcua's finite state machines raise a
TransitionEventTypeon every state change, but noGeneratesEventreference said so, which OPC 10000-16 requires and the compliance tool checks on every state machine instance. One reference is added toFiniteStateMachineType, covering every subtype. One catalog digest moves with it. #1705A semantics change raises
SemanticChangeEventTypeon the Server object, alongside the SemanticsChanged bit, as OPC 10000-5 6.4.31 requires. The bit itself no longer becomes part of the change-detection baseline, which used to produce a second, bit-less notification for a value that never changed. #1706Coverage numbers move for measurement reasons, not code reasons. The suite runs on Node's own type stripping, so coverage lands on the TypeScript sources instead of compiled output. The reported figure goes from 79.06% to 91.70% with the same tests: 32 500 lines were always covered and were being counted against files nobody edits. #1714
🚀 The ESM migration (FEAT-2)
Seven batches, ordered by dependency layer rather than by size, because a CommonJS package sitting on top of flipped ones is the dangerous position: under a transpiling test loader it duplicates every module beneath it, and anything holding module-level state splits in two silently.
service-*family and friends)leak-detector, the last hand-written CommonJS packageaddress-spaceand its neighbours, 7 packagesThree findings worth carrying away:
node-opcua-factory: the built-in type registry is filled by import side effects, and the last CommonJS package in that chain made the test loader create a second module object with its own state, soNumericRangeregistered into the copy nobody read. The generator now exits non-zero when it cannot resolve a schema, instead of logging and returning.clientandserveralone broke ESM consumers only: Node discovers a CommonJS module's named exports with a static lexer that can see through other CommonJS files, and once the re-export targets became ES modules the names simply vanished.require("node-opcua")never broke, because it reads an object at run time rather than resolving names before evaluation.tsc -bdoes not re-emit on atypechange alone, so an ordinary build leaves CommonJS output and looks like it worked. Every batch verified the emitted files rather than trusting the build.🏗️ Modernisation
TypeScript 7 (#1693). A cold
tsc -b packagesgoes from 192 s to 38 s, andbuild:allfrom CI's 152 to 224 s down to 51 s. The output was compared rather than assumed: of 2 584 emitted JavaScript files 2 differ, by redundant parentheses around an identifier, and 6 declaration files differ by union member order and character escaping. The checkers undertools/read the classic compiler API, which TypeScript 7 does not expose, so they depend on atypescript-5alias that also names, at the import site, which compiler is meant.A third fewer files at load (#1688). The generated nodeset packages are mostly type declarations: 536 of 576 compiled modules in
node-opcua-nodeset-uahave no run-time content, andexport *loaded them anyway.node-opcua-address-spacenode-opcuaDeclaration maps (#1702). 2 628 maps, every one verified to resolve to a file that exists.
distgrows about 2%, build time is unchanged.Five new gates. Each answers a different question about what is published, and each was verified against the defect it exists to catch rather than merely observed green:
check-build-graph(#1698)check-package-shape(#1700)check-cjs-globals(#1711)require,moduleorexports?check-erasable(#1718)check-c8-ignore([77c3feb])What they found immediately:
node-opcua-nodeset-i-4-aaswas published with no compiled code at all, missing from the aggregate build list, andcheck-packhad been blind to it becausemain: "dist/index.js"does not start with./and was read as a bare specifier. 37 of 115 packages write their entry points that way.node-opcua-leak-detectorhad been shipping without its types. Theconvert-nodeset-to-javascriptCLI had no shebang, so it was not executable on Linux. And thesimple_clientcommand has pointed at a file deleted in November 2023. #1695 #1707The test suite runs on Node's own type stripping (#1714, #1710, #1715). Two resolver redirects replace the transpiler, with
TSX=1as a fallback. No import is rewritten and no experimental flag is used. Coverage lands on the sources, andc8finally reads its own configuration: the previous file was annycYAML file that c8 ignored silently, so none of its settings had ever applied and--allwas reporting 3 103 never-loaded source files at 0%.🚀 Features
deleteNamespace(indexOrUri)empties a namespace and frees its index for reuse, so a tool that recompiles a model does not have to rebuild the whole address space. Deleting node by node used to leave survivors: a DataType or a ReferenceType could not be deleted at all, so on the AutoID nodeset 15 nodes threw and 15 survived. The delete batches its model-change transaction instead of opening one per node, which is where most of the gain is. Measured on that nodeset: a full rebuild is 442 ms, the old node-by-node loop 89 ms, anddeleteNamespace4 to 8 ms, or 3.8 ms with the newsuspendModelChangeEventsoption.modelChangeTransactionis published too, so a caller can batch its own work the same way. #1726registerNodePromoteraccepts a NodeId, so an application can register a promoter for a type it defines itself or for a companion-specification type, whose namespace index is a property of the load rather than a constant. The numeric form still works. Shipped in 2.183.1. #1684onSetpointDataValueChange, the deviation-alarm counterpart ofonInputDataValueChange, completing the alarm extension points published in 2.183.0. Shipped in 2.183.1. #1682trustSiblingImages(opt-in, off by default) skips the read-and-hash that proves a precompiled nodeset image matches its XML, checking the recorded source length against the file size instead. The bargain is explicit: an edit that changes the length is still caught, one that keeps it byte-for-byte is not. #1728⚡ Performance
Beyond the build and load figures above, two passes over the address space, both measured with pinned process priority because a laptop migrating a benchmark between performance and efficiency cores reports regressions that are not there:
findReferencescalls during a standard-plus-DI load drop from 10 136 to 6 132, andfindReferencesAsObjectfrom 4 898 to 894. Image node decoding loses two allocations per node. #1728_getDefinitionasked separately whether a type was an Enumeration, a Structure and a Union, each walking the supertype chain; andisSubtypeOf's memo is invalidated by everyHasSubtypereference added anywhere, so during a load it is thrown away before it is read.allReferencescalls drop from 2 966 to 236, and the median warm load by about 10%. #1729That PR also carries a correction and a negative result, both worth more than the speedup. The work was opened on a profile claiming one function was 59% of a load; a warm profile, taken around the loads rather than the process, puts it at 3.9%, and the PR says so in its first paragraph. And four routes through image parsing were measured to close the question of whether string slicing was costing anything: the current route is already the fastest available, and the ceiling is 9% for a format change.
🐛 Fixes
Alarms and Conditions, and the compliance tool
browsePathin aSimpleAttributeOperanddenotes the instance itself, per Part 4 §7.4.4.5, not "nothing to resolve". Every Alarms and Conditions client asks for the ConditionId with exactly that operand, so the select clause came backBadNothingToDo, the compliance tool's alarm collector gave up, and every A&C unit was skipped. #1716InList(ConditionId, ...)andEqualsmatch the event's own ConditionId. Measured before the fix: a wide monitored item received 3 condition events, a filtered one on the same subscription received 0. Delivery and evaluation now share one resolver so they cannot drift apart again. #1717GeneratesEventtoTransitionEventType. #1705Address space
instantiate()now forwardsparentNodeIdtoo. Shipped in 2.183.1. #1683enumValuesentry keeps its description. The array form ofaddMultiStateValueDiscretebuilt eachEnumValueTypefrom the display name and value only, silently dropping a description the type declares. #1723BadNoMatch; the analog array items accept a write toEngineeringUnits. #1706Tests and infrastructure
🗑️ Housekeeping
169 dead CommonJS files are deleted: 162 schema literals from 2015 in thirteen
service-*packages, threenycconfigs, three unreferenced fixtures and one explorer script. None was published, and one search across the whole repository found every reference inside the deleted set itself. #1686A new gate refuses an import that reaches into another package's
impl/directory. The current count is zero, which is the cheap moment to add one: a gate introduced after the count grows is a negotiation. #1725📦 Dependencies
TypeScript moves from 5.9.3 to 7.0.2, with a
typescript-5alias kept for the tools that read the classic compiler API and fornode-opcua-generator, which compiles generated code at run time.c8is pinned at 12.0.0 as a devDependency instead of being fetched unpinned on every invocation, andpublintand@arethetypeswrong/clijoin the packaging gates.typedocleaves the root devDependencies, since both callers invoke it throughpnpx, which resolves its own compiler.Pull requests
Full Changelog: node-opcua/node-opcua@v2.183.0...v2.184.0
v2.183.1Compare Source
v2.183.0: : The Eleventh ListenerCompare Source
node-opcua 2.183.0: The Eleventh Listener
Compare:
v2.182.0...v2.183.0· 72 commits · 33 pull requests · includes the2.182.1and2.182.2patchesTL;DR
Alarms are yours to shape now. Giving an alarm its own behaviour used to mean reaching inside the package, extending a class that never actually built anything, and copying methods onto objects by hand. Enough people invented that same workaround independently to prove the library owed them a real answer. Here it is: three documented hooks, and
promoteToAlarm, which takes an ordinary node, one that came from a NodeSet file or a plain instantiate, and turns it into a live alarm in place, keeping its identity and every reference pointing at it. Alongside it,namespaceOfhands you the full namespace from any node, so the casts that used to litter application code are gone.Your information models now survive the round trip. Load a NodeSet file, export it, and the parent relationships come back exactly as the working group declared them, not as whichever reference the loader happened to meet first. That is 3 996 of 3 996 parents matching on the standard nodeset, and it is what lets a model pass through node-opcua and out again without quietly rearranging itself. Engineering units get the same treatment: every description and display name now matches the OPC Foundation's own table word for word, so your server and everyone else's finally agree on how to spell "pascal". Underneath, the first package ships as a genuine ES module and every published package finally declares the Node version it is actually tested on.
And two bugs that could take a server out are gone. Subscribe to events on the Server object an eleventh time and the process died: Node.js went to print a routine "too many listeners" warning, printing it meant describing the node, and the colour-handling code on that path threw where nobody was catching. A single leftover lock file from an old version could hang every untrusted client's connection attempt forever, silently. Both came out of three weeks of OPC Foundation compliance runs that closed fifteen findings in all, each traced to a sentence of the specification before a line was changed. One thing to check before upgrading: anonymous clients reconnecting over unencrypted connections no longer keep their subscriptions, because the specification forbids it. They rebuild instead, which node-opcua's own client does unprompted, and one server option puts the old behaviour back.
A conformance and extensibility release. Three weeks of OPC Foundation Compliance Test Tool (CTT) runs closed fifteen more findings, among them two that had been taking the server process down or hanging every untrusted client. Alarm customisation finally has published extension points, so an application no longer deep-imports an implementation class to give an alarm behaviour, and an existing node can be promoted to an alarm in place. The NodeSet loader honours
ParentNodeId, so a model round-trips with the parent chain its working group declared. Underneath, every published package now declares the Node floor CI actually tests, the first package ships as ESM, and 1 245 deep-import specifiers were spelled out so the remaining ESM work is mechanical.Highlights
onInputDataValueChange,setStateBasedOnInputValue,signalNewCondition, pluspromoteToAlarmto give an existing node condition behaviour.util.inspectover a node and threw from a Proxy invariant, uncaught.ParentNodeId, so add-ins and organized folders reload under the parent the document declares.node >= 22.13.0, the floor CI has tested since May.standardUnitsand the 1 797 generated units.node-opcua-transportpublishes as ESM, the first package to flip, withrequire("node-opcua")unaffected.Anonymous subscription transfer is refused by default (behaviour change).
OPCUAServerOptions.allowAnonymousSubscriptionTransferOnUnsecuredChannelnow defaults tofalse, where it defaulted totrue. As Part 4 §5.13.7 requires, a subscription created by an anonymous session transfers to another session only over aSignorSignAndEncryptchannel and only when the client certificate's ApplicationUri matches the original session's; otherwise the transfer is refused withBadUserAccessDenied. An anonymous client reconnecting over aNoneendpoint now rebuilds its subscription instead of keeping itssubscriptionId, which node-opcua's own client does transparently. Set the option totrueto restore the previous behaviour. The cross-user ownership check was always enforced and is unchanged. #1666Every published package declares
node >= 22.13.0. The root has required it since Node 18 and 20 left CI in May, but the root is never published: three packages declared>=18and 110 declared nothing. A consumer on Node 18 now gets anEBADENGINEwarning per node-opcua package at install time instead of silence. The floor was measured, not assumed: 22.12 is whererequire()reads an ES module unflagged, so the eventual ESM-only release raises the floor for nobody. #1654node-opcua-transportis an ES module."type": "module", withmainandtypeskept at the top level.require("node-opcua")works, CJS dependents pass, and both consumer fixtures pass. Three things this does not cover: a bundler with a CJS-only transform, a TypeScript consumer onmoduleResolution: node, and replacing an export on the namespace object, which ESM silently ignores. A local tree built before this needsnpx tsc -b packages/node-opcua-transport --forceonce, becausetsc -bdoes not re-emit on atypechange. #1658An omitted
DataTypeattribute readsBaseDataType(i=24), not the null NodeId. The UANodeSet schema defaults it that way; 56 elements of the standard nodeset omit it and every one answeredi=0. Generated nodeset typings follow: a field typedBaseDataTypenow usesVariantOptionsrather than the unconstructibleVariant, and 43 nodeset packages were regenerated. #1673 [253c280]The NodeSet loader honours
ParentNodeId. A node's parent used to be the first aggregating reference met. An add-in reached from two parents reloaded under the type rather than its folder, and a folder a type only organizes reloaded under nothing, so a round trip could not reproduce a working group's NodeId table. The declared parent now wins when it is one of the node's hierarchical parents,Organizesincluded. Without a declaration nothing changes. Exports write the declared parents back: standard 3 996 of 3 996 match, LADS 567, Robotics 473. #1664Precompiled nodeset images use record schema 5 (3 in 2.182.0). Any image cached under
imageStore: trueis rebuilt on first use; the 35 catalog images shipped withnode-opcua-nodesetsare already regenerated. [e0fced0] #1673A deadband makes
StatusValueTimestampbehave asStatusValue. Part 4 §7.22.2 says so explicitly, andtimestampHasChangedwas a tautology that reported every sample, so the deadband and the value and status comparisons behind it were never consulted. With no deadband in force the SourceTimestamp remains a trigger of its own. #1672A mistyped Call argument answers
BadInvalidArgumentat the operation level, withBadTypeMismatchorBadOutOfRangeininputArgumentResults. It used to promote the per-argument code to the operation level. The count cases are unchanged. #1662FindAliasrefuses aReferenceTypeFilterthat is notAliasForor a subtype, withBadInvalidArgumentand the offending argument marked. It used to answerGoodwith an empty match list. #1671Event filter limits are raised to 1 000.
maxSelectClauseParametersandmaxWhereClauseParametersdefaulted to 100, below what a conformant client sends to any server exposing the standard alarm types. AnInListwhere-clause operator now accepts one operand and evaluates to false, as Part 4 §7.7.4 defines it. Shipped in 2.182.2. #1653Unit descriptions and display names changed. 55
standardUnitsentries and every table-backed entry of the 1 797 generated units now carry the OPC Foundation's UNECE text verbatim:"pascal"rather than"pascal [unit of pressure]","gram"rather than"gramme 1E-3 kg". Keys,unitIdvalues and themakeEUInformationsignature are unchanged, so no consumer code breaks, but a server displaying these strings will show different text. Seven display-name defects from the spreadsheet parse are fixed in passing. #1677An issuer without a revocation list refuses with
BadSecurityChecksFailedon the wire, per Errata 1.04.12. The certificate manager's own verdict, the rejected folder, audit and diagnostics keep the precise code; only the wire answer narrows. #1655OPCUAServer.shutdown()is idempotent. Repeated or concurrent calls share one outcome, and shutting down a server that never started resolves instead of throwing, so a caller's own cleanup no longer replaces the real cause of a failed start. Shipped in 2.182.1. #1649Two published CLIs changed their flag spelling.
yargs15 (2020) was replaced bycommand-line-args, which is ESM-native. The local discovery server's--no-tolerantand--no-forcebecome--tolerant falseand--force false, and a missing required option prints the usage guide rather than yargs's own help. #1660🚀 Features
Alarms: published extension points, and promotion (#1675, #1678, #1679)
Customising an alarm meant deep-importing
ua_alarm_condition_impl.js, extending a class that was never used for construction, and hand-copying prototype methods onto the instantiated node. Three extension points are now published onUAAlarmConditionHelperandUALimitAlarmHelper:onInputDataValueChange(newValue)_onInputDataValueChangesetStateBasedOnInputValue(value)_setStateBasedOnInputValue, which threwsignalNewCondition(stateName, isActive, value)_signalNewConditionThe underscore names stay as deprecated delegates and an existing override still wins, so nothing breaks. Internal classes that overrode the underscore names moved to the public ones, without which an application's assignment would have been silently shadowed.
promoteToAlarm(node, options)gives condition behaviour to a node that arrived any other way, from a nodeset or a plaininstantiate(), which used to be inert. It retypes in place like the six existing promoters, so the node keeps its identity and every reference to it. It refuses rather than half-promotes: anything not deriving fromAlarmConditionType, the limit-alarm family, andCertificateExpirationAlarmType, which owns a timer onlypromoteToCertificateExpirationAlarminstalls.packages/playground/device_health_extra.tsis rewritten as the worked example, with no deep imports, no classes and no type assertions left, and is now type-checked by thecheck:testtypesgate.Address space
namespaceOf(node)returns the node's namespace as the fullNamespace, so reachinginstantiateAlarmConditionfrom a node no longer needs a cast.BaseNode.namespaceis declared innode-opcua-address-space-base, which cannot name whatnode-opcua-address-spaceadds; the assertion now happens once, where the invariant is checkable. #1680installReadProcessedDetails(addressSpace, handler)names the hooknode-opcua-aggregateswas reaching by casting toAddressSpacePrivateand assigning an underscore field. #1669checkVariantCompatibilityis declared onUAVariable, andadjustDataValueStatusCodetakes the public interface rather than the implementation class. Both were reachable only by casting. #1669parentNodeIdonAddBaseNodeOptions, so theadd*API can declare a parent the way a NodeSet2 document does. [383820d]JSON encoding
node-opcua-json/104andnode-opcua-json/105, version-locked subpath entry points. Each realm re-exports every function and JSON type under its version-free name withJsonEncoderModebound to that edition, so passing a 1.04 mode into the 1.05 realm is a type error. The root stays scheme-dispatched. Shipped in 2.182.1. #1652ExpandedNodeIdencoder threw unconditionally; it now follows Part 6 1.04 §5.4.2.11 and the ServerIndex round-trips. Shipped in 2.182.1. [cccdf12]Units
standardUnits.one(UNECE C62) is a table-backed count unit, the alternative tocategorizedUnits.piece(H87), which the Foundation's table does not carry. #1677node-opcua-unitsexportsunitsNotInFoundationTable, a set of the 254 unit ids whose UNECE code the Foundation table does not carry, so a server author can tell the two apart at run time instead of discovering it from a CTT report.Tooling
node-opcua-versionsunderstands workspace globs as pnpm, npm, yarn and lerna write them, including./prefixes, partial names,**and!exclusions. A manifest without the family says so instead of reporting success over an empty set, and a workspace root read without-wis told what it did not read. Shipped in 2.182.1. [Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.