node-red-contrib-aedes 0.15.1 → 1.2.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/.github/workflows/nodejs.yml +1 -1
- package/CHANGELOG.md +14 -0
- package/README.md +11 -3
- package/aedes.html +44 -19
- package/aedes.js +412 -210
- package/locales/de/aedes.html +110 -0
- package/locales/de/aedes.json +54 -0
- package/locales/en-US/aedes.html +103 -12
- package/locales/en-US/aedes.json +15 -2
- package/package.json +6 -4
- package/test/aedes_last_will_spec.js +25 -48
- package/test/aedes_persist_spec.js +777 -0
- package/test/aedes_qos_spec.js +76 -77
- package/test/aedes_retain_spec.js +62 -189
- package/test/aedes_spec.js +257 -67
- package/test/aedes_ws_spec.js +107 -38
- package/test/test-utils.js +17 -0
- package/docs/DEV-SETUP.md +0 -86
- package/docs/MIGRATION-PLAN-0.51-TO-1.0.md +0 -349
- package/docs/MIGRATION-PLAN-NODE-RED-4.md +0 -107
|
@@ -1,349 +0,0 @@
|
|
|
1
|
-
# Migration Plan: Aedes 0.51.x to 1.0.0
|
|
2
|
-
|
|
3
|
-
## Context
|
|
4
|
-
|
|
5
|
-
Aedes v1.0.0 is ESM-only with async broker creation and replaces `websocket-stream` with native `ws`. This plan migrates node-red-contrib-aedes from Aedes ^0.51.3 to ^1.0.0.
|
|
6
|
-
|
|
7
|
-
## Decision: Stay CJS
|
|
8
|
-
|
|
9
|
-
The project stays CommonJS (`module.exports = function(RED) {...}`). Node-RED has no native ESM support for custom nodes yet. Only `aedes` (ESM-only) needs dynamic `await import()`. All other dependencies (`aedes-persistence-mongodb` v9.4.1 = CJS, `ws` v8 = dual CJS/ESM, Node.js built-ins = both) work fine with `require()`.
|
|
10
|
-
|
|
11
|
-
## Breaking Changes
|
|
12
|
-
|
|
13
|
-
| Area | v0.51.3 (Current) | v1.0.0 (Target) |
|
|
14
|
-
|------|-------------------|------------------|
|
|
15
|
-
| Module system | CJS `require('aedes')` | ESM only -- use `await import('aedes')` |
|
|
16
|
-
| Broker creation | `aedes.createBroker(opts)` sync | `await Aedes.createBroker(opts)` async, named export |
|
|
17
|
-
| WebSocket lib | `websocket-stream` package | Native `ws` with `WebSocketServer` + `createWebSocketStream` |
|
|
18
|
-
| Default export | Callable function | Throws error -- must use named `{ Aedes }` |
|
|
19
|
-
| Subscribe event | Array (but code treats as single object -- latent bug) | Array -- must iterate |
|
|
20
|
-
| Unsubscribe event | Array of strings (but code treats as object -- latent bug) | Array of strings -- must iterate |
|
|
21
|
-
|
|
22
|
-
## Files to Modify
|
|
23
|
-
|
|
24
|
-
- `package.json` -- dependency updates
|
|
25
|
-
- `aedes.js` -- core broker logic (main work)
|
|
26
|
-
- `test/aedes_spec.js` -- basic TCP tests
|
|
27
|
-
- `test/aedes_ws_spec.js` -- WebSocket tests
|
|
28
|
-
- `test/aedes_secure_spec.js` -- TLS tests
|
|
29
|
-
- `test/aedes_qos_spec.js` -- QoS tests
|
|
30
|
-
- `test/aedes_retain_spec.js` -- retain tests
|
|
31
|
-
- `test/aedes_last_will_spec.js` -- last will tests
|
|
32
|
-
|
|
33
|
-
No changes: `aedes.html`, `locales/`, `examples/`, `icons/`
|
|
34
|
-
|
|
35
|
-
## Unchanged APIs (no migration needed)
|
|
36
|
-
|
|
37
|
-
- `broker.handle(conn, req)` -- same signature in v1
|
|
38
|
-
- `broker.authenticate(client, username, password, callback)` -- same in v1
|
|
39
|
-
- `broker.close(callback)` -- still callback-based in v1
|
|
40
|
-
- All broker events -- same names and signatures
|
|
41
|
-
- `broker.connectedClients` -- still a property
|
|
42
|
-
- `aedes-persistence-mongodb` v9.4.1 -- compatible (peer dep min ^9.3.1)
|
|
43
|
-
- `handleServerUpgrade` function -- uses standard `ws` API already
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## TASK 0: Create migration branch
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
git checkout -b migrate-aedes-v1
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
All migration work happens on this branch. Merge to master after tests pass.
|
|
54
|
-
|
|
55
|
-
---
|
|
56
|
-
|
|
57
|
-
## TASK 1: Update package.json dependencies
|
|
58
|
-
|
|
59
|
-
**File:** `package.json`
|
|
60
|
-
|
|
61
|
-
### 1.1 Update aedes version
|
|
62
|
-
- Change `"aedes": "^0.51.3"` to `"aedes": "^1.0.0"`
|
|
63
|
-
|
|
64
|
-
### 1.2 Replace websocket-stream with ws
|
|
65
|
-
- Remove `"websocket-stream": "^5.5.2"`
|
|
66
|
-
- Add `"ws": "^8.18.0"`
|
|
67
|
-
|
|
68
|
-
### 1.3 Keep aedes-persistence-mongodb
|
|
69
|
-
- No change needed: `"aedes-persistence-mongodb": "^9.4.1"` is compatible
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## TASK 2: Update imports in aedes.js
|
|
74
|
-
|
|
75
|
-
**File:** `aedes.js` lines 17-28
|
|
76
|
-
|
|
77
|
-
### 2.1 Remove aedes require
|
|
78
|
-
- Delete line 22: `const aedes = require('aedes');`
|
|
79
|
-
- Aedes will be dynamically imported inside async init (ESM-only, cannot require)
|
|
80
|
-
|
|
81
|
-
### 2.2 Replace websocket-stream require
|
|
82
|
-
- Delete line 28: `const ws = require('websocket-stream');`
|
|
83
|
-
- Add: `const { WebSocketServer, createWebSocketStream } = require('ws');`
|
|
84
|
-
- Note: `ws` v8 supports CJS require
|
|
85
|
-
|
|
86
|
-
---
|
|
87
|
-
|
|
88
|
-
## TASK 3: Async broker initialization pattern
|
|
89
|
-
|
|
90
|
-
**File:** `aedes.js` -- constructor `AedesBrokerNode` (line 54)
|
|
91
|
-
|
|
92
|
-
The constructor must stay synchronous (Node-RED requirement). Use "init promise" pattern.
|
|
93
|
-
|
|
94
|
-
### 3.1 Add state tracking to constructor
|
|
95
|
-
After synchronous config parsing (lines 54-133), add:
|
|
96
|
-
```javascript
|
|
97
|
-
node._closing = false;
|
|
98
|
-
node._broker = null;
|
|
99
|
-
node._server = null;
|
|
100
|
-
node._wss = null;
|
|
101
|
-
node._httpServer = null;
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
### 3.2 Extract async init function
|
|
105
|
-
Create `async function initializeBroker(node, config, aedesSettings, serverOptions)` containing all logic currently at lines 135-408:
|
|
106
|
-
```javascript
|
|
107
|
-
async function initializeBroker (node, config, aedesSettings, serverOptions) {
|
|
108
|
-
const { Aedes } = await import('aedes');
|
|
109
|
-
const broker = await Aedes.createBroker(aedesSettings);
|
|
110
|
-
if (node._closing) { broker.close(); return; }
|
|
111
|
-
node._broker = broker;
|
|
112
|
-
// ... TCP/TLS server setup (TASK 3.3)
|
|
113
|
-
// ... WebSocket port setup (TASK 4)
|
|
114
|
-
// ... WebSocket path setup (TASK 5)
|
|
115
|
-
// ... server.listen (existing logic)
|
|
116
|
-
// ... authentication setup (existing logic, unchanged)
|
|
117
|
-
// ... event handlers (TASK 6)
|
|
118
|
-
}
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
### 3.3 Call init from constructor
|
|
122
|
-
Replace lines 135-408 with:
|
|
123
|
-
```javascript
|
|
124
|
-
node._initPromise = initializeBroker(node, config, aedesSettings, serverOptions);
|
|
125
|
-
node._initPromise.catch(function (err) {
|
|
126
|
-
node.error('Failed to initialize Aedes broker: ' + err.toString());
|
|
127
|
-
node.status({ fill: 'red', shape: 'ring', text: 'initialization failed' });
|
|
128
|
-
});
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
### 3.4 TCP/TLS server creation inside initializeBroker
|
|
132
|
-
Move lines 136-141 into initializeBroker. No API changes needed:
|
|
133
|
-
```javascript
|
|
134
|
-
let server;
|
|
135
|
-
if (node.usetls) {
|
|
136
|
-
server = tls.createServer(serverOptions, broker.handle);
|
|
137
|
-
} else {
|
|
138
|
-
server = net.createServer(broker.handle);
|
|
139
|
-
}
|
|
140
|
-
node._server = server;
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
---
|
|
144
|
-
|
|
145
|
-
## TASK 4: Rewrite WebSocket port mode
|
|
146
|
-
|
|
147
|
-
**File:** `aedes.js` lines 146-188
|
|
148
|
-
|
|
149
|
-
### 4.1 Replace ws.createServer with WebSocketServer
|
|
150
|
-
**Old (lines 173-178):**
|
|
151
|
-
```javascript
|
|
152
|
-
wss = ws.createServer({ server: httpServer }, broker.handle);
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
**New:**
|
|
156
|
-
```javascript
|
|
157
|
-
const wss = new WebSocketServer({ server: httpServer });
|
|
158
|
-
wss.on('connection', function (websocket, req) {
|
|
159
|
-
const stream = createWebSocketStream(websocket);
|
|
160
|
-
broker.handle(stream, req);
|
|
161
|
-
});
|
|
162
|
-
node._wss = wss;
|
|
163
|
-
node._httpServer = httpServer;
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
### 4.2 Promisify port availability test
|
|
167
|
-
Wrap the testServer logic (lines 148-187) in a Promise for clean async flow inside initializeBroker. Keep same EADDRINUSE error handling.
|
|
168
|
-
|
|
169
|
-
---
|
|
170
|
-
|
|
171
|
-
## TASK 5: Rewrite WebSocket path mode
|
|
172
|
-
|
|
173
|
-
**File:** `aedes.js` lines 190-227
|
|
174
|
-
|
|
175
|
-
### 5.1 Replace ws.createServer noServer with WebSocketServer
|
|
176
|
-
**Old (lines 219-224):**
|
|
177
|
-
```javascript
|
|
178
|
-
node.server = ws.createServer({ noServer: true }, broker.handle);
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
**New:**
|
|
182
|
-
```javascript
|
|
183
|
-
node.server = new WebSocketServer({ noServer: true });
|
|
184
|
-
node.server.on('connection', function (websocket, req) {
|
|
185
|
-
const stream = createWebSocketStream(websocket);
|
|
186
|
-
broker.handle(stream, req);
|
|
187
|
-
});
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### 5.2 handleServerUpgrade -- NO CHANGES
|
|
191
|
-
Function at lines 40-52 already uses standard `ws` API pattern (`handleUpgrade` + `emit('connection')`). Works as-is with `WebSocketServer`.
|
|
192
|
-
|
|
193
|
-
---
|
|
194
|
-
|
|
195
|
-
## TASK 6: Fix subscribe/unsubscribe event handlers
|
|
196
|
-
|
|
197
|
-
**File:** `aedes.js` lines 368-390
|
|
198
|
-
|
|
199
|
-
### 6.1 Fix subscribe handler (lines 368-378)
|
|
200
|
-
The first argument is an **array** of `{topic, qos}` objects. Iterate it:
|
|
201
|
-
```javascript
|
|
202
|
-
broker.on('subscribe', function (subscriptions, client) {
|
|
203
|
-
for (const subscription of subscriptions) {
|
|
204
|
-
node.send([{
|
|
205
|
-
topic: 'subscribe',
|
|
206
|
-
payload: { topic: subscription.topic, qos: subscription.qos, client }
|
|
207
|
-
}, null]);
|
|
208
|
-
}
|
|
209
|
-
});
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
### 6.2 Fix unsubscribe handler (lines 380-390)
|
|
213
|
-
The first argument is an **array of topic strings** (not objects). Iterate it:
|
|
214
|
-
```javascript
|
|
215
|
-
broker.on('unsubscribe', function (unsubscriptions, client) {
|
|
216
|
-
for (const topic of unsubscriptions) {
|
|
217
|
-
node.send([{
|
|
218
|
-
topic: 'unsubscribe',
|
|
219
|
-
payload: { topic: topic, client }
|
|
220
|
-
}, null]);
|
|
221
|
-
}
|
|
222
|
-
});
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
---
|
|
226
|
-
|
|
227
|
-
## TASK 7: Restructure close handler
|
|
228
|
-
|
|
229
|
-
**File:** `aedes.js` lines 410-452
|
|
230
|
-
|
|
231
|
-
### 7.1 Replace close handler with async-safe version
|
|
232
|
-
Carries over the `removed` parameter from the Node-RED 4 migration (task 2.2):
|
|
233
|
-
```javascript
|
|
234
|
-
this.on('close', async function (removed, done) {
|
|
235
|
-
node._closing = true;
|
|
236
|
-
if (removed) {
|
|
237
|
-
node.debug('Node removed or disabled');
|
|
238
|
-
} else {
|
|
239
|
-
node.debug('Node restarting');
|
|
240
|
-
}
|
|
241
|
-
try {
|
|
242
|
-
await node._initPromise;
|
|
243
|
-
closeBroker(node, config, done);
|
|
244
|
-
} catch (e) {
|
|
245
|
-
done();
|
|
246
|
-
}
|
|
247
|
-
});
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
### 7.2 Create closeBroker function
|
|
251
|
-
Extract cleanup into a standalone function. Access resources via `node._broker`, `node._server`, `node._wss`, `node._httpServer` with null checks:
|
|
252
|
-
```javascript
|
|
253
|
-
function closeBroker (node, config, done) {
|
|
254
|
-
process.nextTick(function () {
|
|
255
|
-
function wsClose () {
|
|
256
|
-
if (node._wss) {
|
|
257
|
-
node._wss.close(function () {
|
|
258
|
-
if (node._httpServer) {
|
|
259
|
-
node._httpServer.close(function () { done(); });
|
|
260
|
-
} else { done(); }
|
|
261
|
-
});
|
|
262
|
-
} else { done(); }
|
|
263
|
-
}
|
|
264
|
-
function serverClose () {
|
|
265
|
-
if (node._server) {
|
|
266
|
-
node._server.close(function () {
|
|
267
|
-
if (node.mqtt_ws_path !== '' && node.fullPath) {
|
|
268
|
-
delete listenerNodes[node.fullPath];
|
|
269
|
-
if (node.server) {
|
|
270
|
-
node.server.close(function () { wsClose(); });
|
|
271
|
-
} else { wsClose(); }
|
|
272
|
-
} else { wsClose(); }
|
|
273
|
-
});
|
|
274
|
-
} else { wsClose(); }
|
|
275
|
-
}
|
|
276
|
-
if (node._broker) {
|
|
277
|
-
node._broker.close(function () { serverClose(); });
|
|
278
|
-
} else { serverClose(); }
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
---
|
|
284
|
-
|
|
285
|
-
## TASK 8: Update test files for async init
|
|
286
|
-
|
|
287
|
-
**Files:** all 6 files in `test/`
|
|
288
|
-
|
|
289
|
-
### 8.1 Add _initPromise wait pattern
|
|
290
|
-
In every test that connects an MQTT client, use the async `helper.load()` (available since `node-red-node-test-helper` v0.3.5) and `await` the init promise:
|
|
291
|
-
```javascript
|
|
292
|
-
await helper.load(aedesNode, flow);
|
|
293
|
-
const n1 = helper.getNode('n1');
|
|
294
|
-
await n1._initPromise;
|
|
295
|
-
// ... existing test logic ...
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
This replaces the nested callback + `.then()` pattern with flat async/await. Each `it()` callback must be declared `async`.
|
|
299
|
-
|
|
300
|
-
### 8.2 Tests that do NOT need changes
|
|
301
|
-
Tests that only check `n1.name` or node existence ("should be loaded") work without waiting -- the name is set synchronously in the constructor.
|
|
302
|
-
|
|
303
|
-
### 8.3 Test files to update
|
|
304
|
-
- `test/aedes_spec.js` -- all tests except "should be loaded"
|
|
305
|
-
- `test/aedes_ws_spec.js` -- all tests except "should be loaded"
|
|
306
|
-
- `test/aedes_secure_spec.js` -- all tests except "should be loaded"
|
|
307
|
-
- `test/aedes_qos_spec.js` -- all tests
|
|
308
|
-
- `test/aedes_retain_spec.js` -- all tests
|
|
309
|
-
- `test/aedes_last_will_spec.js` -- all tests except "should be loaded"
|
|
310
|
-
|
|
311
|
-
---
|
|
312
|
-
|
|
313
|
-
## TASK 9: Install and verify
|
|
314
|
-
|
|
315
|
-
### 9.1 Install new dependencies
|
|
316
|
-
```bash
|
|
317
|
-
npm install
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
### 9.2 Run full test suite
|
|
321
|
-
```bash
|
|
322
|
-
npm test
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
### 9.3 Verify all scenarios
|
|
326
|
-
- TCP plain connection
|
|
327
|
-
- TCP with TLS (port 8883)
|
|
328
|
-
- WebSocket via standalone port
|
|
329
|
-
- WebSocket via Node-RED path
|
|
330
|
-
- Secure WebSocket (WSS) on port
|
|
331
|
-
- Secure WebSocket (WSS) on path
|
|
332
|
-
- QoS 1 and QoS 2 persistence
|
|
333
|
-
- Retained messages
|
|
334
|
-
- Last will and testament
|
|
335
|
-
- Authentication (valid + invalid credentials)
|
|
336
|
-
- Multiple brokers on different ports
|
|
337
|
-
- Port conflict detection
|
|
338
|
-
|
|
339
|
-
---
|
|
340
|
-
|
|
341
|
-
## Legacy branch relevance (v11, v0.15.x)
|
|
342
|
-
|
|
343
|
-
Both legacy branches use Aedes 0.49.0. We checked whether Tasks 6 and 7.1 also apply there:
|
|
344
|
-
|
|
345
|
-
- **Task 6 (subscribe/unsubscribe handlers) — YES, relevant for both branches.**
|
|
346
|
-
Both `v11` and `v0.15.x` have the same latent bug: the handlers treat the first argument as a single object, but the Aedes API (even in 0.49.0) passes an array. This fix should be backported.
|
|
347
|
-
|
|
348
|
-
- **Task 7.1 (close handler `removed` parameter) — NO, not relevant.**
|
|
349
|
-
Both legacy branches use `this.on('close', function (done) {...})` with one parameter. Node-RED handles this via arity checking — if the function declares 1 param, Node-RED passes only `done`, so the handler works correctly on all Node-RED versions. The `removed` param is a nice-to-have, and the async-safe parts (`_initPromise`, `_closing`) only apply to aedes v1's async init.
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
# Migration Plan: Node-RED 4 Best Practices
|
|
2
|
-
|
|
3
|
-
## Context
|
|
4
|
-
|
|
5
|
-
The project was started with Node-RED v2 but `package.json` already requires `>=3.0.0`. Node-RED v3 went EOL June 2025. Only v4 is actively maintained. This plan aligns the project with Node-RED v4 best practices while keeping the changes minimal and low-risk.
|
|
6
|
-
|
|
7
|
-
## Recommended Order: Run this BEFORE the Aedes v1 migration
|
|
8
|
-
|
|
9
|
-
Rationale:
|
|
10
|
-
- These changes are small, low-risk, and independently testable
|
|
11
|
-
- They establish a clean, verified baseline before the larger Aedes rewrite
|
|
12
|
-
- The close handler update to `(removed, done)` carries over naturally into the Aedes migration's restructured close handler
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
## TASK 1: Update `node-red` version field in package.json
|
|
17
|
-
|
|
18
|
-
**File:** `package.json` line 21
|
|
19
|
-
|
|
20
|
-
### 1.1 Keep minimum Node-RED version at >=3.0.0
|
|
21
|
-
- No change needed -- `"version": ">=3.0.0"` already includes v4
|
|
22
|
-
- Keeps broader compatibility for users still on v3
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## TASK 2: Update close handler to use `removed` parameter
|
|
27
|
-
|
|
28
|
-
**File:** `aedes.js` line 410
|
|
29
|
-
|
|
30
|
-
### 2.1 Add `removed` parameter
|
|
31
|
-
Available since Node-RED v0.17. Compatible with v2, v3, and v4.
|
|
32
|
-
|
|
33
|
-
**Current:**
|
|
34
|
-
```javascript
|
|
35
|
-
this.on('close', function (done) {
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
**New:**
|
|
39
|
-
```javascript
|
|
40
|
-
this.on('close', function (removed, done) {
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### 2.2 Optional: use `removed` for cleaner logging
|
|
44
|
-
```javascript
|
|
45
|
-
this.on('close', function (removed, done) {
|
|
46
|
-
if (removed) {
|
|
47
|
-
node.debug('Node removed or disabled');
|
|
48
|
-
} else {
|
|
49
|
-
node.debug('Node restarting');
|
|
50
|
-
}
|
|
51
|
-
// ... existing cleanup ...
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
Note: The close handler has a **15-second timeout** enforced by Node-RED. The current nested callback chain should stay well within that, but keep it in mind.
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
## TASK 3: Add missing dev dependencies to package.json
|
|
59
|
-
|
|
60
|
-
**File:** `package.json`
|
|
61
|
-
|
|
62
|
-
### 3.1 Add semistandard and snazzy to devDependencies
|
|
63
|
-
The test script uses `semistandard` and `snazzy` but they're **not listed in devDependencies**. They only work if globally installed, which breaks `npm test` for other contributors.
|
|
64
|
-
|
|
65
|
-
Add to `devDependencies`:
|
|
66
|
-
```json
|
|
67
|
-
"semistandard": "^17.0.0",
|
|
68
|
-
"snazzy": "^9.0.0"
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
### 3.2 Alternative: Replace with ESLint (optional, larger scope)
|
|
72
|
-
`semistandard` was [last updated Aug 2024](https://github.com/standard/semistandard) and is not actively maintained. ESLint is the modern standard. However, this is a larger change -- consider deferring to a separate effort.
|
|
73
|
-
|
|
74
|
-
---
|
|
75
|
-
|
|
76
|
-
## TASK 4: Verify test helper version
|
|
77
|
-
|
|
78
|
-
**File:** `package.json` line 12
|
|
79
|
-
|
|
80
|
-
### 4.1 Already up to date
|
|
81
|
-
`node-red-node-test-helper` v0.3.6 (Jan 2025) is the latest. Your `^0.3.6` is correct. No change needed.
|
|
82
|
-
|
|
83
|
-
Notable: v0.3.5 added async `start`/`stop`/`load` support, which will be useful during the Aedes migration when tests need to `await _initPromise`.
|
|
84
|
-
|
|
85
|
-
---
|
|
86
|
-
|
|
87
|
-
## TASK 5: Run tests and verify
|
|
88
|
-
|
|
89
|
-
### 5.1 Install and test
|
|
90
|
-
```bash
|
|
91
|
-
npm install
|
|
92
|
-
npm test
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
### 5.2 Verify all existing tests still pass
|
|
96
|
-
No functional changes were made -- only the close handler signature and package metadata.
|
|
97
|
-
|
|
98
|
-
---
|
|
99
|
-
|
|
100
|
-
## Summary of changes
|
|
101
|
-
|
|
102
|
-
| Task | Risk | Effort | Backward compat |
|
|
103
|
-
|------|------|--------|-----------------|
|
|
104
|
-
| node-red version field | None | Trivial | v2+ (if >=3.0.0) or v4+ |
|
|
105
|
-
| close(removed, done) | None | Trivial | v2+ (since v0.17) |
|
|
106
|
-
| Add semistandard/snazzy to devDeps | None | Trivial | All versions |
|
|
107
|
-
| Test helper version | None | None | Already current |
|