node-opcua-client-browser 2.177.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +42 -0
- package/dist/client_ws_transport.d.ts +92 -0
- package/dist/client_ws_transport.js +167 -0
- package/dist/client_ws_transport.js.map +1 -0
- package/dist/create_browser_client.d.ts +74 -0
- package/dist/create_browser_client.js +74 -0
- package/dist/create_browser_client.js.map +1 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.js +88 -0
- package/dist/index.js.map +1 -0
- package/dist/uacp.d.ts +14 -0
- package/dist/uacp.js +23 -0
- package/dist/uacp.js.map +1 -0
- package/dist/ws_socket_adapter.d.ts +67 -0
- package/dist/ws_socket_adapter.js +196 -0
- package/dist/ws_socket_adapter.js.map +1 -0
- package/package.json +70 -0
- package/source/client_ws_transport.ts +227 -0
- package/source/create_browser_client.ts +105 -0
- package/source/index.ts +49 -0
- package/source/uacp.ts +22 -0
- package/source/ws_socket_adapter.ts +219 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022-2024 Sterfive SAS - 833264583 RCS ORLEANS - France (https://www.sterfive.com)
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2014-2022 Etienne Rossignon
|
|
6
|
+
|
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
8
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
9
|
+
the Software without restriction, including without limitation the rights to
|
|
10
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
11
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
12
|
+
subject to the following conditions:
|
|
13
|
+
|
|
14
|
+
The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
19
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
20
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
21
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
22
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# node-opcua-client-browser
|
|
2
|
+
|
|
3
|
+
OPC UA client SDK for modern browsers, using the **WebSocket transport mapping**
|
|
4
|
+
defined in OPC UA Part 6, §7.5.
|
|
5
|
+
|
|
6
|
+
> **Status — scaffold only.**
|
|
7
|
+
> This initial drop establishes the package layout, build toolchain, and
|
|
8
|
+
> Playwright E2E harness. The WebSocket transport, the `createBrowserClient`
|
|
9
|
+
> helper, and the prebuilt browser bundle arrive in follow-up PRs. Consult
|
|
10
|
+
> `openspec/changes/add-browser-client-wsopcua/` for the canonical scope and
|
|
11
|
+
> roadmap.
|
|
12
|
+
|
|
13
|
+
## Planned scope (upcoming PRs)
|
|
14
|
+
|
|
15
|
+
- Endpoint URL schemes: `opc.ws://`, `opc.wss://`, `ws://`, `wss://`
|
|
16
|
+
- Security policies: `None`, `Basic256Sha256` (SignAndEncrypt)
|
|
17
|
+
- User identity tokens: Anonymous, UserName/Password (password encrypted under
|
|
18
|
+
`Basic256Sha256` when applicable)
|
|
19
|
+
- Services: Read / Write / CreateSubscription / CreateMonitoredItems / Publish
|
|
20
|
+
|
|
21
|
+
## What is in this scaffold PR
|
|
22
|
+
|
|
23
|
+
- Package skeleton (`package.json`, `tsconfig*.json`).
|
|
24
|
+
- An empty `source/index.ts` that just exports a `VERSION` string; subsequent
|
|
25
|
+
PRs add the actual transport implementation.
|
|
26
|
+
- A Playwright test harness that builds a minimal test page with esbuild,
|
|
27
|
+
serves it over a local HTTP server, and loads it headless in Chromium.
|
|
28
|
+
- One smoke spec (`test/e2e/smoke.spec.ts`) that asserts the test page loads
|
|
29
|
+
and the `node-opcua-client-browser` module evaluates. Later PRs replace
|
|
30
|
+
this with full OPC UA Read / Write / Subscribe flows over `opc.ws` and
|
|
31
|
+
`opc.wss` against a demo server.
|
|
32
|
+
|
|
33
|
+
## Running the smoke test
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pnpm exec playwright install chromium # first time only
|
|
37
|
+
pnpm test:e2e # runs the smoke spec headless
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## License
|
|
41
|
+
|
|
42
|
+
MIT — see [LICENSE](./LICENSE).
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module node-opcua-client-browser
|
|
3
|
+
*
|
|
4
|
+
* `ClientWS_transport` — OPC UA WebSocket client transport (Part 6 §7.5).
|
|
5
|
+
*
|
|
6
|
+
* Subclasses `ClientTCP_transport` and reuses its HEL/ACK + chunk-reassembly
|
|
7
|
+
* machinery unchanged. The only swap is the socket-creation step: instead of
|
|
8
|
+
* opening a TCP connection, we open a `WebSocket` and hand a
|
|
9
|
+
* {@link WsSocketAdapter} to `TCP_transport._install_socket`.
|
|
10
|
+
*
|
|
11
|
+
* OPC UA WebSocket framing:
|
|
12
|
+
* - One UACP chunk per outgoing binary WebSocket frame (handled naturally —
|
|
13
|
+
* each `write(chunk)` call invokes `ws.send(chunk)` once).
|
|
14
|
+
* - Incoming bytes are fed into `TCP_transport`'s packet-assembler, which
|
|
15
|
+
* re-combines split chunks.
|
|
16
|
+
* - Subprotocol `opcua+uacp` is requested on the handshake. If the server
|
|
17
|
+
* echoes it back we record that; if not (common with a `websockify`
|
|
18
|
+
* bridge) we continue without failing — browsers still accept the
|
|
19
|
+
* connection provided the server's bytes are valid UACP.
|
|
20
|
+
*/
|
|
21
|
+
import type { ErrorCallback } from "node-opcua-status-code";
|
|
22
|
+
import { ClientTransportBase, type IClientTransportFactory, type TransportSettingsOptions } from "node-opcua-transport";
|
|
23
|
+
import { type WebSocketLike } from "./ws_socket_adapter";
|
|
24
|
+
/** WebSocket subprotocol name defined by OPC UA Part 6 §7.5 */
|
|
25
|
+
export declare const OPCUA_UACP_SUBPROTOCOL = "opcua+uacp";
|
|
26
|
+
/**
|
|
27
|
+
* A tiny WebSocket-constructor type. In the browser this is `globalThis.WebSocket`;
|
|
28
|
+
* in Node-side unit tests this is the `ws` package's `default` export. Either works.
|
|
29
|
+
*/
|
|
30
|
+
export type WebSocketConstructor = new (url: string, protocols?: string | string[]) => WebSocketLike;
|
|
31
|
+
/** Options specific to the browser WebSocket transport. */
|
|
32
|
+
export interface ClientWSTransportOptions extends TransportSettingsOptions {
|
|
33
|
+
/**
|
|
34
|
+
* The WebSocket constructor to use. Defaults to `globalThis.WebSocket`.
|
|
35
|
+
* Override this from Node-side unit tests to inject the `ws` package.
|
|
36
|
+
*/
|
|
37
|
+
webSocketCtor?: WebSocketConstructor;
|
|
38
|
+
/**
|
|
39
|
+
* When `true`, `connect()` fails if the peer does not echo back the
|
|
40
|
+
* `opcua+uacp` subprotocol on the WebSocket opening handshake. Defaults to
|
|
41
|
+
* `false` because `websockify` bridges do not negotiate subprotocols; the
|
|
42
|
+
* OPC UA bytes that follow will fail the HEL/ACK step anyway if the peer
|
|
43
|
+
* isn't actually speaking UACP.
|
|
44
|
+
*/
|
|
45
|
+
strictSubprotocol?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Parsed endpoint URL, normalised for the browser `WebSocket` constructor.
|
|
49
|
+
*/
|
|
50
|
+
export interface ParsedWsEndpoint {
|
|
51
|
+
/** The URL to pass to `new WebSocket(url, …)` — always starts with `ws://` or `wss://`. */
|
|
52
|
+
wsUrl: string;
|
|
53
|
+
/** `true` if the original URL used `opc.wss://` or `wss://`. */
|
|
54
|
+
secure: boolean;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Parse and normalise an OPC UA WebSocket endpoint URL. Accepts all four
|
|
58
|
+
* forms: `opc.ws://`, `opc.wss://`, `ws://`, `wss://`. Anything else throws.
|
|
59
|
+
*
|
|
60
|
+
* @throws {Error} if the scheme is not one of the four accepted forms.
|
|
61
|
+
*/
|
|
62
|
+
export declare function parseWsEndpointUrl(endpointUrl: string): ParsedWsEndpoint;
|
|
63
|
+
/**
|
|
64
|
+
* WebSocket-backed client transport. A sibling of `ClientTCP_transport`: both extend
|
|
65
|
+
* {@link ClientTransportBase} and reuse its UACP HEL/ACK machinery; the only
|
|
66
|
+
* difference is the socket flavour (`WebSocket` here, `net.Socket` in TCP).
|
|
67
|
+
*/
|
|
68
|
+
export declare class ClientWS_transport extends ClientTransportBase {
|
|
69
|
+
private readonly _webSocketCtor;
|
|
70
|
+
private readonly _strictSubprotocol;
|
|
71
|
+
constructor(options?: ClientWSTransportOptions);
|
|
72
|
+
/**
|
|
73
|
+
* Opens a WebSocket to `endpointUrl`, adapts it to `ISocketLike`, and
|
|
74
|
+
* drives the inherited HEL/ACK transaction from `ClientTransportBase`.
|
|
75
|
+
*/
|
|
76
|
+
connect(endpointUrl: string, callback: ErrorCallback): void;
|
|
77
|
+
dispose(): void;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* A factory that produces {@link ClientWS_transport} instances. Pass to
|
|
81
|
+
* `ClientSecureChannelLayerOptions.transportFactory` to route all channel
|
|
82
|
+
* traffic through a WebSocket.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* const ws = browserWsTransportFactory.create({});
|
|
86
|
+
* // or, on Node:
|
|
87
|
+
* import WebSocket from "ws";
|
|
88
|
+
* const factory: IClientTransportFactory = {
|
|
89
|
+
* create(s) { return new ClientWS_transport({ ...s, webSocketCtor: WebSocket as any }); }
|
|
90
|
+
* };
|
|
91
|
+
*/
|
|
92
|
+
export declare const browserWsTransportFactory: IClientTransportFactory;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @module node-opcua-client-browser
|
|
4
|
+
*
|
|
5
|
+
* `ClientWS_transport` — OPC UA WebSocket client transport (Part 6 §7.5).
|
|
6
|
+
*
|
|
7
|
+
* Subclasses `ClientTCP_transport` and reuses its HEL/ACK + chunk-reassembly
|
|
8
|
+
* machinery unchanged. The only swap is the socket-creation step: instead of
|
|
9
|
+
* opening a TCP connection, we open a `WebSocket` and hand a
|
|
10
|
+
* {@link WsSocketAdapter} to `TCP_transport._install_socket`.
|
|
11
|
+
*
|
|
12
|
+
* OPC UA WebSocket framing:
|
|
13
|
+
* - One UACP chunk per outgoing binary WebSocket frame (handled naturally —
|
|
14
|
+
* each `write(chunk)` call invokes `ws.send(chunk)` once).
|
|
15
|
+
* - Incoming bytes are fed into `TCP_transport`'s packet-assembler, which
|
|
16
|
+
* re-combines split chunks.
|
|
17
|
+
* - Subprotocol `opcua+uacp` is requested on the handshake. If the server
|
|
18
|
+
* echoes it back we record that; if not (common with a `websockify`
|
|
19
|
+
* bridge) we continue without failing — browsers still accept the
|
|
20
|
+
* connection provided the server's bytes are valid UACP.
|
|
21
|
+
*/
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.browserWsTransportFactory = exports.ClientWS_transport = exports.OPCUA_UACP_SUBPROTOCOL = void 0;
|
|
24
|
+
exports.parseWsEndpointUrl = parseWsEndpointUrl;
|
|
25
|
+
/* global WebSocket */
|
|
26
|
+
const node_opcua_assert_1 = require("node-opcua-assert");
|
|
27
|
+
const node_opcua_debug_1 = require("node-opcua-debug");
|
|
28
|
+
const node_opcua_transport_1 = require("node-opcua-transport");
|
|
29
|
+
const ws_socket_adapter_1 = require("./ws_socket_adapter");
|
|
30
|
+
const debugLog = (0, node_opcua_debug_1.make_debugLog)("ClientWS_transport");
|
|
31
|
+
const warningLog = (0, node_opcua_debug_1.make_warningLog)("ClientWS_transport");
|
|
32
|
+
const doDebug = (0, node_opcua_debug_1.checkDebugFlag)("ClientWS_transport");
|
|
33
|
+
/** WebSocket subprotocol name defined by OPC UA Part 6 §7.5 */
|
|
34
|
+
exports.OPCUA_UACP_SUBPROTOCOL = "opcua+uacp";
|
|
35
|
+
/**
|
|
36
|
+
* Parse and normalise an OPC UA WebSocket endpoint URL. Accepts all four
|
|
37
|
+
* forms: `opc.ws://`, `opc.wss://`, `ws://`, `wss://`. Anything else throws.
|
|
38
|
+
*
|
|
39
|
+
* @throws {Error} if the scheme is not one of the four accepted forms.
|
|
40
|
+
*/
|
|
41
|
+
function parseWsEndpointUrl(endpointUrl) {
|
|
42
|
+
const m = /^(opc\.ws|opc\.wss|ws|wss):\/\/(.+)$/i.exec(endpointUrl);
|
|
43
|
+
if (!m) {
|
|
44
|
+
throw new Error(`[node-opcua-client-browser] unsupported endpoint URL scheme for WebSocket transport: ${endpointUrl} ` +
|
|
45
|
+
`(expected one of opc.ws://, opc.wss://, ws://, wss://)`);
|
|
46
|
+
}
|
|
47
|
+
const scheme = m[1].toLowerCase();
|
|
48
|
+
const secure = scheme === "opc.wss" || scheme === "wss";
|
|
49
|
+
const wsUrl = `${secure ? "wss" : "ws"}://${m[2]}`;
|
|
50
|
+
return { wsUrl, secure };
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* WebSocket-backed client transport. A sibling of `ClientTCP_transport`: both extend
|
|
54
|
+
* {@link ClientTransportBase} and reuse its UACP HEL/ACK machinery; the only
|
|
55
|
+
* difference is the socket flavour (`WebSocket` here, `net.Socket` in TCP).
|
|
56
|
+
*/
|
|
57
|
+
class ClientWS_transport extends node_opcua_transport_1.ClientTransportBase {
|
|
58
|
+
_webSocketCtor;
|
|
59
|
+
_strictSubprotocol;
|
|
60
|
+
constructor(options) {
|
|
61
|
+
super(options);
|
|
62
|
+
const resolvedCtor = options?.webSocketCtor ??
|
|
63
|
+
(typeof globalThis !== "undefined" ? globalThis.WebSocket : undefined);
|
|
64
|
+
if (!resolvedCtor) {
|
|
65
|
+
throw new Error("[ClientWS_transport] no WebSocket constructor available: pass `webSocketCtor` explicitly or run in a browser / Node 22+");
|
|
66
|
+
}
|
|
67
|
+
this._webSocketCtor = resolvedCtor;
|
|
68
|
+
this._strictSubprotocol = !!options?.strictSubprotocol;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Opens a WebSocket to `endpointUrl`, adapts it to `ISocketLike`, and
|
|
72
|
+
* drives the inherited HEL/ACK transaction from `ClientTransportBase`.
|
|
73
|
+
*/
|
|
74
|
+
connect(endpointUrl, callback) {
|
|
75
|
+
this.endpointUrl = endpointUrl;
|
|
76
|
+
/* c8 ignore next */
|
|
77
|
+
doDebug && debugLog(`ClientWS_transport#connect(endpointUrl = ${endpointUrl})`);
|
|
78
|
+
let parsed;
|
|
79
|
+
try {
|
|
80
|
+
parsed = parseWsEndpointUrl(endpointUrl);
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
callback(err);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
let ws;
|
|
87
|
+
try {
|
|
88
|
+
ws = new this._webSocketCtor(parsed.wsUrl, exports.OPCUA_UACP_SUBPROTOCOL);
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
/* c8 ignore next */
|
|
92
|
+
doDebug && debugLog("WebSocket construction failed", err.message);
|
|
93
|
+
callback(err);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const socket = new ws_socket_adapter_1.WsSocketAdapter(ws, parsed.wsUrl);
|
|
97
|
+
const onEarlyError = (err) => {
|
|
98
|
+
callback(err);
|
|
99
|
+
};
|
|
100
|
+
socket.once("error", onEarlyError);
|
|
101
|
+
socket.once("connect", () => {
|
|
102
|
+
socket.removeListener("error", onEarlyError);
|
|
103
|
+
// Subprotocol negotiation check. Browser WS exposes `protocol` on the
|
|
104
|
+
// instance; `ws` package exposes it too. When the peer doesn't
|
|
105
|
+
// negotiate (e.g. a websockify bridge), `protocol` is an empty
|
|
106
|
+
// string. Only fail in strict mode.
|
|
107
|
+
const negotiated = ws.protocol;
|
|
108
|
+
if (negotiated && negotiated !== exports.OPCUA_UACP_SUBPROTOCOL) {
|
|
109
|
+
const msg = `unexpected WebSocket subprotocol negotiated: "${negotiated}" (expected "${exports.OPCUA_UACP_SUBPROTOCOL}")`;
|
|
110
|
+
if (this._strictSubprotocol) {
|
|
111
|
+
callback(new Error(`[ClientWS_transport] ${msg}`));
|
|
112
|
+
socket.destroy();
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
warningLog(msg);
|
|
116
|
+
}
|
|
117
|
+
else if (!negotiated) {
|
|
118
|
+
/* c8 ignore next */
|
|
119
|
+
doDebug &&
|
|
120
|
+
debugLog(`peer did not echo the "${exports.OPCUA_UACP_SUBPROTOCOL}" subprotocol; continuing ` +
|
|
121
|
+
`(set strictSubprotocol=true to reject this)`);
|
|
122
|
+
}
|
|
123
|
+
// Install the WebSocket-backed socket adapter into the inherited TCP_transport machinery.
|
|
124
|
+
(0, node_opcua_assert_1.assert)(!this._socket, "transport should not have a socket yet");
|
|
125
|
+
this._install_socket(socket);
|
|
126
|
+
this._perform_HEL_ACK_transaction((err) => {
|
|
127
|
+
if (!err) {
|
|
128
|
+
/* c8 ignore next */
|
|
129
|
+
if (!this._socket) {
|
|
130
|
+
return callback(new Error("Abandoned"));
|
|
131
|
+
}
|
|
132
|
+
this._install_post_connect_error_handler(endpointUrl);
|
|
133
|
+
this.emit("connect");
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
debugLog("_perform_HEL_ACK_transaction has failed with err=", err.message);
|
|
137
|
+
}
|
|
138
|
+
callback(err);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
dispose() {
|
|
143
|
+
/* c8 ignore next */
|
|
144
|
+
doDebug && debugLog(" ClientWS_transport disposed");
|
|
145
|
+
super.dispose();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
exports.ClientWS_transport = ClientWS_transport;
|
|
149
|
+
/**
|
|
150
|
+
* A factory that produces {@link ClientWS_transport} instances. Pass to
|
|
151
|
+
* `ClientSecureChannelLayerOptions.transportFactory` to route all channel
|
|
152
|
+
* traffic through a WebSocket.
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* const ws = browserWsTransportFactory.create({});
|
|
156
|
+
* // or, on Node:
|
|
157
|
+
* import WebSocket from "ws";
|
|
158
|
+
* const factory: IClientTransportFactory = {
|
|
159
|
+
* create(s) { return new ClientWS_transport({ ...s, webSocketCtor: WebSocket as any }); }
|
|
160
|
+
* };
|
|
161
|
+
*/
|
|
162
|
+
exports.browserWsTransportFactory = {
|
|
163
|
+
create(settings) {
|
|
164
|
+
return new ClientWS_transport(settings);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
//# sourceMappingURL=client_ws_transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client_ws_transport.js","sourceRoot":"","sources":["../source/client_ws_transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module node-opcua-client-browser
|
|
3
|
+
*
|
|
4
|
+
* Thin helper that constructs an `OPCUAClient` (from `node-opcua-client`)
|
|
5
|
+
* pre-wired with the browser WebSocket transport factory and, when no
|
|
6
|
+
* credentials are supplied, an in-memory certificate/key pair provider so
|
|
7
|
+
* no disk paths are touched.
|
|
8
|
+
*
|
|
9
|
+
* All other `OPCUAClient` configuration passes through unchanged — callers
|
|
10
|
+
* configure session timeouts, reconnection strategies, security policies,
|
|
11
|
+
* etc. exactly as they would for the Node client.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { createBrowserClient, AttributeIds, MessageSecurityMode, SecurityPolicy } from "node-opcua-client-browser";
|
|
16
|
+
*
|
|
17
|
+
* const client = createBrowserClient({
|
|
18
|
+
* endpointMustExist: false,
|
|
19
|
+
* securityMode: MessageSecurityMode.None,
|
|
20
|
+
* securityPolicy: SecurityPolicy.None,
|
|
21
|
+
* });
|
|
22
|
+
* await client.connect("opc.ws://localhost:4840");
|
|
23
|
+
* const session = await client.createSession();
|
|
24
|
+
* const dv = await session.read({ nodeId: "ns=1;s=Counter", attributeId: AttributeIds.Value });
|
|
25
|
+
* await session.close();
|
|
26
|
+
* await client.disconnect();
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
import { OPCUAClient, type OPCUAClientOptions } from "node-opcua-client";
|
|
30
|
+
import type { Certificate, PrivateKey } from "node-opcua-crypto/web";
|
|
31
|
+
/**
|
|
32
|
+
* Options accepted by {@link createBrowserClient}. Superset of
|
|
33
|
+
* {@link OPCUAClientOptions}; the browser-specific defaults described above
|
|
34
|
+
* apply unless the caller overrides them.
|
|
35
|
+
*/
|
|
36
|
+
export interface CreateBrowserClientOptions extends OPCUAClientOptions {
|
|
37
|
+
/**
|
|
38
|
+
* Pre-built client certificate chain (DER). When combined with
|
|
39
|
+
* `clientPrivateKey`, it is loaded into an
|
|
40
|
+
* `InMemoryCertificateKeyPairProvider` so the owning `OPCUAClient`
|
|
41
|
+
* needs no disk cert files.
|
|
42
|
+
*
|
|
43
|
+
* If you already pass `certificateKeyPairProvider`, this option is
|
|
44
|
+
* ignored.
|
|
45
|
+
*/
|
|
46
|
+
clientCertificate?: Certificate | Certificate[];
|
|
47
|
+
/**
|
|
48
|
+
* Pre-built client private key. Paired with `clientCertificate` to
|
|
49
|
+
* populate the in-memory provider.
|
|
50
|
+
*
|
|
51
|
+
* If you already pass `certificateKeyPairProvider`, this option is
|
|
52
|
+
* ignored.
|
|
53
|
+
*/
|
|
54
|
+
clientPrivateKey?: PrivateKey;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Construct an `OPCUAClient` with browser-appropriate defaults.
|
|
58
|
+
*
|
|
59
|
+
* - `transportFactory` defaults to `browserWsTransportFactory` so the
|
|
60
|
+
* underlying secure channel opens a WebSocket. Callers can override by
|
|
61
|
+
* passing a different `transportFactory`.
|
|
62
|
+
* - `certificateKeyPairProvider` defaults to an
|
|
63
|
+
* `InMemoryCertificateKeyPairProvider`, populated with
|
|
64
|
+
* `clientCertificate` / `clientPrivateKey` when those are supplied.
|
|
65
|
+
* When they are NOT supplied, the provider is constructed empty —
|
|
66
|
+
* callers are expected to await `ensureCertificateExists(...)` on the
|
|
67
|
+
* returned client's credentials before connecting with a non-None
|
|
68
|
+
* security policy.
|
|
69
|
+
* - `clientCertificateManager` defaults to an `InMemoryCertificateStore`
|
|
70
|
+
* (auto-accept unknown peer certs). Callers can override by passing
|
|
71
|
+
* their own `clientCertificateManager` (e.g. one backed by IndexedDB
|
|
72
|
+
* or OPFS).
|
|
73
|
+
*/
|
|
74
|
+
export declare function createBrowserClient(options?: CreateBrowserClientOptions): OPCUAClient;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @module node-opcua-client-browser
|
|
4
|
+
*
|
|
5
|
+
* Thin helper that constructs an `OPCUAClient` (from `node-opcua-client`)
|
|
6
|
+
* pre-wired with the browser WebSocket transport factory and, when no
|
|
7
|
+
* credentials are supplied, an in-memory certificate/key pair provider so
|
|
8
|
+
* no disk paths are touched.
|
|
9
|
+
*
|
|
10
|
+
* All other `OPCUAClient` configuration passes through unchanged — callers
|
|
11
|
+
* configure session timeouts, reconnection strategies, security policies,
|
|
12
|
+
* etc. exactly as they would for the Node client.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { createBrowserClient, AttributeIds, MessageSecurityMode, SecurityPolicy } from "node-opcua-client-browser";
|
|
17
|
+
*
|
|
18
|
+
* const client = createBrowserClient({
|
|
19
|
+
* endpointMustExist: false,
|
|
20
|
+
* securityMode: MessageSecurityMode.None,
|
|
21
|
+
* securityPolicy: SecurityPolicy.None,
|
|
22
|
+
* });
|
|
23
|
+
* await client.connect("opc.ws://localhost:4840");
|
|
24
|
+
* const session = await client.createSession();
|
|
25
|
+
* const dv = await session.read({ nodeId: "ns=1;s=Counter", attributeId: AttributeIds.Value });
|
|
26
|
+
* await session.close();
|
|
27
|
+
* await client.disconnect();
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
exports.createBrowserClient = createBrowserClient;
|
|
32
|
+
const node_opcua_common_1 = require("node-opcua-common");
|
|
33
|
+
const node_opcua_client_1 = require("node-opcua-client");
|
|
34
|
+
const client_ws_transport_1 = require("./client_ws_transport");
|
|
35
|
+
/**
|
|
36
|
+
* Construct an `OPCUAClient` with browser-appropriate defaults.
|
|
37
|
+
*
|
|
38
|
+
* - `transportFactory` defaults to `browserWsTransportFactory` so the
|
|
39
|
+
* underlying secure channel opens a WebSocket. Callers can override by
|
|
40
|
+
* passing a different `transportFactory`.
|
|
41
|
+
* - `certificateKeyPairProvider` defaults to an
|
|
42
|
+
* `InMemoryCertificateKeyPairProvider`, populated with
|
|
43
|
+
* `clientCertificate` / `clientPrivateKey` when those are supplied.
|
|
44
|
+
* When they are NOT supplied, the provider is constructed empty —
|
|
45
|
+
* callers are expected to await `ensureCertificateExists(...)` on the
|
|
46
|
+
* returned client's credentials before connecting with a non-None
|
|
47
|
+
* security policy.
|
|
48
|
+
* - `clientCertificateManager` defaults to an `InMemoryCertificateStore`
|
|
49
|
+
* (auto-accept unknown peer certs). Callers can override by passing
|
|
50
|
+
* their own `clientCertificateManager` (e.g. one backed by IndexedDB
|
|
51
|
+
* or OPFS).
|
|
52
|
+
*/
|
|
53
|
+
function createBrowserClient(options = {}) {
|
|
54
|
+
const { clientCertificate, clientPrivateKey, ...clientOptions } = options;
|
|
55
|
+
// Default to the browser WS transport factory unless the caller supplies one.
|
|
56
|
+
if (!clientOptions.transportFactory) {
|
|
57
|
+
clientOptions.transportFactory = client_ws_transport_1.browserWsTransportFactory;
|
|
58
|
+
}
|
|
59
|
+
// Default to an in-memory cert/key provider unless the caller supplies one.
|
|
60
|
+
// If the caller provided a client cert + private key, pre-populate the
|
|
61
|
+
// provider so the owning client can reach them without further async setup.
|
|
62
|
+
if (!clientOptions.certificateKeyPairProvider) {
|
|
63
|
+
const chain = clientCertificate
|
|
64
|
+
? (Array.isArray(clientCertificate) ? clientCertificate : [clientCertificate])
|
|
65
|
+
: undefined;
|
|
66
|
+
clientOptions.certificateKeyPairProvider = new node_opcua_common_1.InMemoryCertificateKeyPairProvider(chain, clientPrivateKey);
|
|
67
|
+
}
|
|
68
|
+
// Default to an in-memory trust store unless the caller supplies one.
|
|
69
|
+
if (!clientOptions.clientCertificateManager) {
|
|
70
|
+
clientOptions.clientCertificateManager = new node_opcua_common_1.InMemoryCertificateStore({ autoAcceptUnknown: true });
|
|
71
|
+
}
|
|
72
|
+
return node_opcua_client_1.OPCUAClient.create(clientOptions);
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=create_browser_client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create_browser_client.js","sourceRoot":"","sources":["../source/create_browser_client.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;;AAqDH,kDAwBC;AA3ED,yDAAiG;AACjG,yDAAyE;AAGzE,+DAAkE;AA6BlE;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAgB,mBAAmB,CAAC,UAAsC,EAAgC;IACtG,MAAM,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,GAAG,aAAa,EAAE,GAAG,OAAO,CAAC;IAE1E,8EAA8E;IAC9E,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE,CAAC;QAClC,aAAa,CAAC,gBAAgB,GAAG,+CAAyB,CAAC;IAC/D,CAAC;IAED,4EAA4E;IAC5E,uEAAuE;IACvE,4EAA4E;IAC5E,IAAI,CAAC,aAAa,CAAC,0BAA0B,EAAE,CAAC;QAC5C,MAAM,KAAK,GAAG,iBAAiB;YAC3B,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC;YAC9E,CAAC,CAAC,SAAS,CAAC;QAChB,aAAa,CAAC,0BAA0B,GAAG,IAAI,sDAAkC,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC;IAC/G,CAAC;IAED,sEAAsE;IACtE,IAAI,CAAC,aAAa,CAAC,wBAAwB,EAAE,CAAC;QAC1C,aAAa,CAAC,wBAAwB,GAAG,IAAI,4CAAwB,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;IACvG,CAAC;IAED,OAAO,+BAAW,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;AAC7C,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* The MIT License (MIT)
|
|
3
|
+
* Copyright (c) 2022-2025 Sterfive SAS - 833264583 RCS ORLEANS - France (https://www.sterfive.com)
|
|
4
|
+
*
|
|
5
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
* this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
* the Software without restriction, including without limitation the rights to
|
|
8
|
+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
9
|
+
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
+
* subject to the following conditions:
|
|
11
|
+
*
|
|
12
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
* copies or substantial portions of the Software.
|
|
14
|
+
*
|
|
15
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
|
+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
|
+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* @module node-opcua-client-browser
|
|
24
|
+
*
|
|
25
|
+
* Browser entry point for `node-opcua-client`. Exposes the OPC UA WebSocket
|
|
26
|
+
* transport (`ClientWS_transport`, `browserWsTransportFactory`,
|
|
27
|
+
* `parseWsEndpointUrl`).
|
|
28
|
+
*
|
|
29
|
+
* Target environments: modern evergreen browsers (Chromium, Firefox, WebKit).
|
|
30
|
+
* The transport uses the OPC UA WebSocket mapping per Part 6 §7.5
|
|
31
|
+
* (`opcua+uacp` subprotocol, one UACP chunk per binary frame).
|
|
32
|
+
*
|
|
33
|
+
* NOTE: `createBrowserClient` is temporarily NOT re-exported from this
|
|
34
|
+
* barrel. Its `OPCUAClient` import drags in `node-opcua-client`, which
|
|
35
|
+
* still transitively pulls Node-only modules (`node:crypto`, `node:fs`,
|
|
36
|
+
* `node:dns`, `@ster5/global-mutex`, `multicast-dns`, …) at bundle
|
|
37
|
+
* time. The full plan to make those packages browser-safe lives at
|
|
38
|
+
* `C:\Users\etien\.claude\plans\run-pnpm-filter-node-opcua-client-browse-vivid-sparkle.md`.
|
|
39
|
+
* The Node-side helper itself is still built and unit-tested — its 8
|
|
40
|
+
* mocha cases in `test/unit/test_create_browser_client.ts` import it
|
|
41
|
+
* directly from `../../dist`. Re-export will be restored in Step 5 of
|
|
42
|
+
* the plan once Steps 1–4 land.
|
|
43
|
+
*/
|
|
44
|
+
export * from "./client_ws_transport";
|
|
45
|
+
export * as uacp from "./uacp";
|
|
46
|
+
export { type WebSocketLike, WsSocketAdapter } from "./ws_socket_adapter";
|
|
47
|
+
export declare const VERSION = "2.172.0";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* The MIT License (MIT)
|
|
4
|
+
* Copyright (c) 2022-2025 Sterfive SAS - 833264583 RCS ORLEANS - France (https://www.sterfive.com)
|
|
5
|
+
*
|
|
6
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
7
|
+
* this software and associated documentation files (the "Software"), to deal in
|
|
8
|
+
* the Software without restriction, including without limitation the rights to
|
|
9
|
+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
10
|
+
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
11
|
+
* subject to the following conditions:
|
|
12
|
+
*
|
|
13
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
* copies or substantial portions of the Software.
|
|
15
|
+
*
|
|
16
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
18
|
+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
19
|
+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
20
|
+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
21
|
+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* @module node-opcua-client-browser
|
|
25
|
+
*
|
|
26
|
+
* Browser entry point for `node-opcua-client`. Exposes the OPC UA WebSocket
|
|
27
|
+
* transport (`ClientWS_transport`, `browserWsTransportFactory`,
|
|
28
|
+
* `parseWsEndpointUrl`).
|
|
29
|
+
*
|
|
30
|
+
* Target environments: modern evergreen browsers (Chromium, Firefox, WebKit).
|
|
31
|
+
* The transport uses the OPC UA WebSocket mapping per Part 6 §7.5
|
|
32
|
+
* (`opcua+uacp` subprotocol, one UACP chunk per binary frame).
|
|
33
|
+
*
|
|
34
|
+
* NOTE: `createBrowserClient` is temporarily NOT re-exported from this
|
|
35
|
+
* barrel. Its `OPCUAClient` import drags in `node-opcua-client`, which
|
|
36
|
+
* still transitively pulls Node-only modules (`node:crypto`, `node:fs`,
|
|
37
|
+
* `node:dns`, `@ster5/global-mutex`, `multicast-dns`, …) at bundle
|
|
38
|
+
* time. The full plan to make those packages browser-safe lives at
|
|
39
|
+
* `C:\Users\etien\.claude\plans\run-pnpm-filter-node-opcua-client-browse-vivid-sparkle.md`.
|
|
40
|
+
* The Node-side helper itself is still built and unit-tested — its 8
|
|
41
|
+
* mocha cases in `test/unit/test_create_browser_client.ts` import it
|
|
42
|
+
* directly from `../../dist`. Re-export will be restored in Step 5 of
|
|
43
|
+
* the plan once Steps 1–4 land.
|
|
44
|
+
*/
|
|
45
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
46
|
+
if (k2 === undefined) k2 = k;
|
|
47
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
48
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
49
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
50
|
+
}
|
|
51
|
+
Object.defineProperty(o, k2, desc);
|
|
52
|
+
}) : (function(o, m, k, k2) {
|
|
53
|
+
if (k2 === undefined) k2 = k;
|
|
54
|
+
o[k2] = m[k];
|
|
55
|
+
}));
|
|
56
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
57
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
58
|
+
}) : function(o, v) {
|
|
59
|
+
o["default"] = v;
|
|
60
|
+
});
|
|
61
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
62
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
63
|
+
};
|
|
64
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
65
|
+
var ownKeys = function(o) {
|
|
66
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
67
|
+
var ar = [];
|
|
68
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
69
|
+
return ar;
|
|
70
|
+
};
|
|
71
|
+
return ownKeys(o);
|
|
72
|
+
};
|
|
73
|
+
return function (mod) {
|
|
74
|
+
if (mod && mod.__esModule) return mod;
|
|
75
|
+
var result = {};
|
|
76
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
77
|
+
__setModuleDefault(result, mod);
|
|
78
|
+
return result;
|
|
79
|
+
};
|
|
80
|
+
})();
|
|
81
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
82
|
+
exports.VERSION = exports.WsSocketAdapter = exports.uacp = void 0;
|
|
83
|
+
__exportStar(require("./client_ws_transport"), exports);
|
|
84
|
+
exports.uacp = __importStar(require("./uacp"));
|
|
85
|
+
var ws_socket_adapter_1 = require("./ws_socket_adapter");
|
|
86
|
+
Object.defineProperty(exports, "WsSocketAdapter", { enumerable: true, get: function () { return ws_socket_adapter_1.WsSocketAdapter; } });
|
|
87
|
+
exports.VERSION = "2.172.0";
|
|
88
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../source/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;;;;;;;;;;;;;;;;;;;;;GAqBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,wDAAsC;AACtC,+CAA+B;AAC/B,yDAA0E;AAA7C,oHAAA,eAAe,OAAA;AAE/B,QAAA,OAAO,GAAG,SAAS,CAAC"}
|
package/dist/uacp.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module node-opcua-client-browser
|
|
3
|
+
* @internal
|
|
4
|
+
*
|
|
5
|
+
* UACP primitives usable in the browser.
|
|
6
|
+
*
|
|
7
|
+
* These are thin re-exports of the byte-level encoders/decoders from
|
|
8
|
+
* `node-opcua-transport`. Those modules are pure-JS (only `node:events` is
|
|
9
|
+
* pulled in, which Vite polyfills automatically) and are therefore safe to
|
|
10
|
+
* bundle for the browser. Consolidating them here gives us a single point of
|
|
11
|
+
* audit if a future release of `node-opcua-transport` introduces a Node-only
|
|
12
|
+
* import.
|
|
13
|
+
*/
|
|
14
|
+
export { AcknowledgeMessage, HelloMessage, TCPErrorMessage, packTcpMessage, readRawMessageHeader, type TransportSettingsOptions } from "node-opcua-transport";
|