homebridge-multiple-switch 1.2.0 → 1.3.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/ci.yml +9 -20
- package/.github/workflows/release.yml +7 -7
- package/CHANGELOG.md +32 -0
- package/README.md +30 -30
- package/index.js +116 -65
- package/package.json +6 -2
- package/.github/workflows/release.yml.save +0 -28
- package/.github/workflows/release.yml.save.1 +0 -28
- package/.github/workflows/release.yml.save.2 +0 -28
package/.github/workflows/ci.yml
CHANGED
|
@@ -11,31 +11,20 @@ jobs:
|
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
12
|
|
|
13
13
|
steps:
|
|
14
|
-
- name:
|
|
15
|
-
uses: actions/checkout@
|
|
14
|
+
- name: Checkout
|
|
15
|
+
uses: actions/checkout@v4
|
|
16
16
|
|
|
17
|
-
- name:
|
|
18
|
-
uses: actions/setup-node@
|
|
17
|
+
- name: Setup Node.js
|
|
18
|
+
uses: actions/setup-node@v4
|
|
19
19
|
with:
|
|
20
20
|
node-version: '18'
|
|
21
21
|
cache: 'npm'
|
|
22
22
|
|
|
23
|
-
- name:
|
|
23
|
+
- name: Install dependencies
|
|
24
24
|
run: npm install
|
|
25
25
|
|
|
26
|
-
- name:
|
|
27
|
-
run:
|
|
28
|
-
if [ -f .eslintrc.js ] || [ -f .eslintrc.json ]; then
|
|
29
|
-
npm run lint
|
|
30
|
-
else
|
|
31
|
-
echo "Lint skripti tapılmadı, keçilir..."
|
|
32
|
-
fi
|
|
33
|
-
|
|
34
|
-
- name: 🧪 Testləri icra et (əgər varsa)
|
|
35
|
-
run: |
|
|
36
|
-
if [ -f package.json ] && grep -q '\"test\"' package.json; then
|
|
37
|
-
npm test
|
|
38
|
-
else
|
|
39
|
-
echo "Test skripti yoxdur, keçilir..."
|
|
40
|
-
fi
|
|
26
|
+
- name: Lint
|
|
27
|
+
run: npm run lint
|
|
41
28
|
|
|
29
|
+
- name: Test
|
|
30
|
+
run: npm test
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
name:
|
|
1
|
+
name: Publish to npm
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
@@ -10,19 +10,19 @@ jobs:
|
|
|
10
10
|
runs-on: ubuntu-latest
|
|
11
11
|
|
|
12
12
|
steps:
|
|
13
|
-
- name:
|
|
14
|
-
uses: actions/checkout@
|
|
13
|
+
- name: Checkout
|
|
14
|
+
uses: actions/checkout@v4
|
|
15
15
|
|
|
16
|
-
- name:
|
|
17
|
-
uses: actions/setup-node@
|
|
16
|
+
- name: Setup Node.js
|
|
17
|
+
uses: actions/setup-node@v4
|
|
18
18
|
with:
|
|
19
19
|
node-version: '18'
|
|
20
20
|
registry-url: 'https://registry.npmjs.org/'
|
|
21
21
|
|
|
22
|
-
- name:
|
|
22
|
+
- name: Install dependencies
|
|
23
23
|
run: npm install
|
|
24
24
|
|
|
25
|
-
- name:
|
|
25
|
+
- name: Publish to npm
|
|
26
26
|
run: npm publish
|
|
27
27
|
env:
|
|
28
28
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [1.3.0] - 2026-03-21
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
- Replaced global mutable variables with instance properties
|
|
7
|
+
- Refactored accessory setup to reuse cached accessories instead of creating duplicates on restart
|
|
8
|
+
- Extracted switch behavior logic into dedicated methods (`turnOffOthers`, `setAll`, `scheduleAutoOff`)
|
|
9
|
+
- Used `Map` for service and accessory tracking instead of plain objects
|
|
10
|
+
- Service type lookup uses a constant map instead of a switch statement
|
|
11
|
+
- Auto-off now checks current state before turning off (prevents stale timeouts)
|
|
12
|
+
- Updated minimum Node.js version from 14 to 18
|
|
13
|
+
- Updated GitHub Actions from v3 to v4
|
|
14
|
+
- Cleaned up CI workflow
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- `delayOff` not working in `master` mode due to if/else logic bug
|
|
18
|
+
- Cached accessories not being restored on Homebridge restart (caused duplicate accessories)
|
|
19
|
+
- Services stored in `accessory.context` which is not serializable
|
|
20
|
+
- README field names (`autoTurnOff`, `mode`) now match actual config schema (`delayOff`, `switchBehavior`)
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
- Automatic removal of stale cached accessories when config changes
|
|
24
|
+
- Service reconciliation: adds new services and removes old ones on config update
|
|
25
|
+
- Validation for empty or missing switches array
|
|
26
|
+
|
|
27
|
+
## [1.2.0] - 2025-01-01
|
|
28
|
+
|
|
29
|
+
- Initial published version with independent, master, and single switch modes
|
|
30
|
+
- Support for switch, outlet, lightbulb, and fan accessory types
|
|
31
|
+
- Per-switch config: type, defaultState, delayOff
|
|
32
|
+
- Homebridge UI config schema
|
package/README.md
CHANGED
|
@@ -5,26 +5,26 @@
|
|
|
5
5
|
[](https://github.com/azadaydinli/homebridge-multiple-switch/issues)
|
|
6
6
|
[](https://github.com/azadaydinli/homebridge-multiple-switch/blob/master/LICENSE)
|
|
7
7
|
|
|
8
|
-
A lightweight Homebridge plugin that lets you create multiple customizable dummy switches under a single accessory — configurable as `Switch`, `Outlet`, `Lightbulb`, or `Fan`.
|
|
8
|
+
A lightweight Homebridge plugin that lets you create multiple customizable dummy switches under a single accessory — configurable as `Switch`, `Outlet`, `Lightbulb`, or `Fan`.
|
|
9
9
|
Supports `Independent`, `Master`, and `Single` switch modes.
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Features
|
|
14
14
|
|
|
15
15
|
- Grouped multiple switches in one HomeKit tile
|
|
16
16
|
- Accessory type: `switch`, `outlet`, `lightbulb`, or `fan`
|
|
17
17
|
- **Independent Mode** – All switches operate separately
|
|
18
|
-
- **Master Mode** – One
|
|
18
|
+
- **Master Mode** – One switch controls all others
|
|
19
19
|
- **Single Mode** – Only one switch can be active at a time
|
|
20
|
-
- Per-switch config support (type, auto-off, default state)
|
|
21
|
-
- Switch states
|
|
22
|
-
-
|
|
20
|
+
- Per-switch config support (type, auto-off delay, default state)
|
|
21
|
+
- Switch states preserved across Homebridge restarts via cached accessories
|
|
22
|
+
- Automatic cleanup of stale accessories on config change
|
|
23
23
|
- Compatible with HomeKit and Siri
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
27
|
-
##
|
|
27
|
+
## Installation
|
|
28
28
|
|
|
29
29
|
Install via Homebridge UI:
|
|
30
30
|
|
|
@@ -40,20 +40,21 @@ npm install -g homebridge-multiple-switch
|
|
|
40
40
|
|
|
41
41
|
---
|
|
42
42
|
|
|
43
|
-
##
|
|
43
|
+
## Configuration
|
|
44
44
|
|
|
45
|
-
Configure from Homebridge UI or manually edit `config.json
|
|
45
|
+
Configure from Homebridge UI or manually edit `config.json`:
|
|
46
46
|
|
|
47
47
|
```json
|
|
48
48
|
{
|
|
49
49
|
"platform": "MultipleSwitchPlatform",
|
|
50
50
|
"name": "Multiple Switches",
|
|
51
|
+
"switchBehavior": "single",
|
|
51
52
|
"switches": [
|
|
52
53
|
{
|
|
53
54
|
"name": "Heater",
|
|
54
55
|
"type": "outlet",
|
|
55
56
|
"defaultState": true,
|
|
56
|
-
"
|
|
57
|
+
"delayOff": 10000
|
|
57
58
|
},
|
|
58
59
|
{
|
|
59
60
|
"name": "Fan",
|
|
@@ -62,35 +63,34 @@ Configure from Homebridge UI or manually edit `config.json` like below:
|
|
|
62
63
|
{
|
|
63
64
|
"name": "Light",
|
|
64
65
|
"type": "lightbulb",
|
|
65
|
-
"
|
|
66
|
+
"delayOff": 5000
|
|
66
67
|
}
|
|
67
|
-
]
|
|
68
|
-
"mode": "single"
|
|
68
|
+
]
|
|
69
69
|
}
|
|
70
70
|
```
|
|
71
71
|
|
|
72
72
|
---
|
|
73
73
|
|
|
74
|
-
###
|
|
74
|
+
### Platform Options
|
|
75
75
|
|
|
76
|
-
| Field
|
|
77
|
-
|
|
78
|
-
| `name`
|
|
79
|
-
| `
|
|
80
|
-
| `
|
|
81
|
-
| `type` | string | ❌ | Switch type: `switch`, `outlet`, `lightbulb`, `fan` (overridden per switch) |
|
|
82
|
-
| `autoTurnOff` | number | ❌ | Global auto-off (ms) – can be overridden per switch |
|
|
83
|
-
| `defaultState` | boolean | ❌ | Default power state on restart – can be overridden per switch |
|
|
76
|
+
| Field | Type | Required | Description |
|
|
77
|
+
|------------------|--------|----------|--------------------------------------|
|
|
78
|
+
| `name` | string | Yes | Name of the platform instance |
|
|
79
|
+
| `switchBehavior` | string | No | `independent`, `master`, or `single` |
|
|
80
|
+
| `switches` | array | Yes | List of switches to create |
|
|
84
81
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
82
|
+
### Per-Switch Options
|
|
83
|
+
|
|
84
|
+
| Field | Type | Required | Description |
|
|
85
|
+
|----------------|---------|----------|--------------------------------------------------|
|
|
86
|
+
| `name` | string | Yes | Name of the switch |
|
|
87
|
+
| `type` | string | No | `switch`, `outlet`, `lightbulb`, or `fan` |
|
|
88
|
+
| `defaultState` | boolean | No | Initial power state (default: `false`) |
|
|
89
|
+
| `delayOff` | number | No | Auto turn off after N milliseconds (default: `0`) |
|
|
90
90
|
|
|
91
91
|
---
|
|
92
92
|
|
|
93
|
-
##
|
|
93
|
+
## Example Use Cases
|
|
94
94
|
|
|
95
95
|
- Simulate smart plugs for automation testing
|
|
96
96
|
- Trigger HomeKit scenes manually
|
|
@@ -99,7 +99,7 @@ Each object inside `switches[]` can include:
|
|
|
99
99
|
|
|
100
100
|
---
|
|
101
101
|
|
|
102
|
-
##
|
|
102
|
+
## Links
|
|
103
103
|
|
|
104
104
|
- [NPM Package](https://www.npmjs.com/package/homebridge-multiple-switch)
|
|
105
105
|
- [Homebridge](https://homebridge.io/)
|
|
@@ -107,6 +107,6 @@ Each object inside `switches[]` can include:
|
|
|
107
107
|
|
|
108
108
|
---
|
|
109
109
|
|
|
110
|
-
##
|
|
110
|
+
## License
|
|
111
111
|
|
|
112
112
|
MIT © [Azad Aydınlı](https://github.com/azadaydinli)
|
package/index.js
CHANGED
|
@@ -1,109 +1,160 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const PLUGIN_NAME = 'homebridge-multiple-switch';
|
|
4
|
+
const PLATFORM_NAME = 'MultipleSwitchPlatform';
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
const SERVICE_TYPES = {
|
|
7
|
+
switch: 'Switch',
|
|
8
|
+
lightbulb: 'Lightbulb',
|
|
9
|
+
fan: 'Fan',
|
|
10
|
+
outlet: 'Outlet',
|
|
11
|
+
};
|
|
9
12
|
|
|
10
|
-
|
|
13
|
+
module.exports = (api) => {
|
|
14
|
+
api.registerPlatform(PLATFORM_NAME, MultipleSwitchPlatform);
|
|
11
15
|
};
|
|
12
16
|
|
|
13
17
|
class MultipleSwitchPlatform {
|
|
14
18
|
constructor(log, config, api) {
|
|
15
19
|
this.log = log;
|
|
16
|
-
this.config = config;
|
|
20
|
+
this.config = config || {};
|
|
17
21
|
this.api = api;
|
|
18
|
-
this.
|
|
22
|
+
this.Service = api.hap.Service;
|
|
23
|
+
this.Characteristic = api.hap.Characteristic;
|
|
24
|
+
this.cachedAccessories = new Map();
|
|
25
|
+
this.switchServices = new Map();
|
|
19
26
|
|
|
20
27
|
this.api.on('didFinishLaunching', () => {
|
|
21
|
-
this.log('
|
|
28
|
+
this.log.info('MultipleSwitchPlatform started.');
|
|
22
29
|
this.setupAccessories();
|
|
23
30
|
});
|
|
24
31
|
}
|
|
25
32
|
|
|
33
|
+
configureAccessory(accessory) {
|
|
34
|
+
this.cachedAccessories.set(accessory.UUID, accessory);
|
|
35
|
+
}
|
|
36
|
+
|
|
26
37
|
setupAccessories() {
|
|
27
|
-
const switches = this.config.switches
|
|
28
|
-
|
|
38
|
+
const switches = this.config.switches;
|
|
39
|
+
if (!Array.isArray(switches) || switches.length === 0) {
|
|
40
|
+
this.log.warn('No switches configured. Removing stale accessories.');
|
|
41
|
+
this.removeStaleCachedAccessories();
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
29
45
|
const name = this.config.name || 'Multiple Switch Panel';
|
|
46
|
+
const behavior = this.config.switchBehavior || 'independent';
|
|
47
|
+
const uuid = this.api.hap.uuid.generate(name);
|
|
48
|
+
|
|
49
|
+
let accessory = this.cachedAccessories.get(uuid);
|
|
50
|
+
const isNew = !accessory;
|
|
30
51
|
|
|
31
|
-
|
|
32
|
-
|
|
52
|
+
if (isNew) {
|
|
53
|
+
accessory = new this.api.platformAccessory(name, uuid);
|
|
54
|
+
}
|
|
33
55
|
|
|
34
|
-
accessory.context.switchStates = {};
|
|
35
|
-
accessory.context.switchServices = {};
|
|
36
56
|
accessory.context.switchBehavior = behavior;
|
|
57
|
+
accessory.context.switchStates = accessory.context.switchStates || {};
|
|
58
|
+
|
|
59
|
+
this.reconcileServices(accessory, switches);
|
|
60
|
+
|
|
61
|
+
if (isNew) {
|
|
62
|
+
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
this.cachedAccessories.delete(uuid);
|
|
66
|
+
this.removeStaleCachedAccessories();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
reconcileServices(accessory, switches) {
|
|
70
|
+
const activeSubtypes = new Set();
|
|
37
71
|
|
|
38
72
|
switches.forEach((sw, index) => {
|
|
39
|
-
const
|
|
40
|
-
|
|
73
|
+
const subtype = `switch_${index}`;
|
|
74
|
+
activeSubtypes.add(subtype);
|
|
41
75
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
76
|
+
const ServiceClass = this.getServiceClass(sw.type);
|
|
77
|
+
let service = accessory.getServiceById(ServiceClass, subtype);
|
|
78
|
+
|
|
79
|
+
if (!service) {
|
|
80
|
+
service = accessory.addService(ServiceClass, sw.name, subtype);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
service.setCharacteristic(this.Characteristic.Name, sw.name);
|
|
84
|
+
this.configureSwitchHandlers(accessory, service, sw, subtype);
|
|
85
|
+
|
|
86
|
+
this.switchServices.set(subtype, service);
|
|
87
|
+
|
|
88
|
+
if (accessory.context.switchStates[subtype] === undefined) {
|
|
89
|
+
accessory.context.switchStates[subtype] = sw.defaultState || false;
|
|
90
|
+
}
|
|
45
91
|
});
|
|
46
92
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
);
|
|
52
|
-
this.accessories.push(accessory);
|
|
93
|
+
const servicesToRemove = accessory.services.filter((s) => {
|
|
94
|
+
return s.subtype && !activeSubtypes.has(s.subtype);
|
|
95
|
+
});
|
|
96
|
+
servicesToRemove.forEach((s) => accessory.removeService(s));
|
|
53
97
|
}
|
|
54
98
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
service.getCharacteristic(Characteristic.On)
|
|
60
|
-
.onGet(() => {
|
|
61
|
-
return accessory.context.switchStates[id];
|
|
62
|
-
})
|
|
99
|
+
configureSwitchHandlers(accessory, service, sw, subtype) {
|
|
100
|
+
service.getCharacteristic(this.Characteristic.On)
|
|
101
|
+
.onGet(() => accessory.context.switchStates[subtype] ?? false)
|
|
63
102
|
.onSet((value) => {
|
|
103
|
+
accessory.context.switchStates[subtype] = value;
|
|
104
|
+
this.log.info(`[${sw.name}] ${value ? 'ON' : 'OFF'}`);
|
|
105
|
+
|
|
64
106
|
const behavior = accessory.context.switchBehavior;
|
|
65
|
-
accessory.context.switchStates[id] = value;
|
|
66
|
-
this.log(`[${sw.name}] → ${value ? 'ON' : 'OFF'}`);
|
|
67
107
|
|
|
68
108
|
if (behavior === 'single' && value) {
|
|
69
|
-
|
|
70
|
-
if (key !== id) {
|
|
71
|
-
accessory.context.switchStates[key] = false;
|
|
72
|
-
accessory.context.switchServices[key].updateCharacteristic(Characteristic.On, false);
|
|
73
|
-
}
|
|
74
|
-
});
|
|
109
|
+
this.turnOffOthers(accessory, subtype);
|
|
75
110
|
}
|
|
76
111
|
|
|
77
112
|
if (behavior === 'master') {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (value && sw.delayOff > 0) {
|
|
84
|
-
setTimeout(() => {
|
|
85
|
-
accessory.context.switchStates[id] = false;
|
|
86
|
-
service.updateCharacteristic(Characteristic.On, false);
|
|
87
|
-
this.log(`[${sw.name}] auto-off after ${sw.delayOff}ms`);
|
|
88
|
-
}, sw.delayOff);
|
|
89
|
-
}
|
|
113
|
+
this.setAll(accessory, value);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (value && sw.delayOff > 0) {
|
|
117
|
+
this.scheduleAutoOff(accessory, service, sw, subtype);
|
|
90
118
|
}
|
|
91
119
|
});
|
|
120
|
+
}
|
|
92
121
|
|
|
93
|
-
|
|
122
|
+
turnOffOthers(accessory, excludeSubtype) {
|
|
123
|
+
for (const [key, svc] of this.switchServices) {
|
|
124
|
+
if (key !== excludeSubtype) {
|
|
125
|
+
accessory.context.switchStates[key] = false;
|
|
126
|
+
svc.updateCharacteristic(this.Characteristic.On, false);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
94
129
|
}
|
|
95
130
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
case 'fan': return Service.Fan;
|
|
101
|
-
case 'outlet':
|
|
102
|
-
default: return Service.Outlet;
|
|
131
|
+
setAll(accessory, value) {
|
|
132
|
+
for (const [key, svc] of this.switchServices) {
|
|
133
|
+
accessory.context.switchStates[key] = value;
|
|
134
|
+
svc.updateCharacteristic(this.Characteristic.On, value);
|
|
103
135
|
}
|
|
104
136
|
}
|
|
105
137
|
|
|
106
|
-
|
|
107
|
-
|
|
138
|
+
scheduleAutoOff(accessory, service, sw, subtype) {
|
|
139
|
+
setTimeout(() => {
|
|
140
|
+
if (accessory.context.switchStates[subtype]) {
|
|
141
|
+
accessory.context.switchStates[subtype] = false;
|
|
142
|
+
service.updateCharacteristic(this.Characteristic.On, false);
|
|
143
|
+
this.log.info(`[${sw.name}] auto-off after ${sw.delayOff}ms`);
|
|
144
|
+
}
|
|
145
|
+
}, sw.delayOff);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
getServiceClass(type) {
|
|
149
|
+
const key = (type || 'outlet').toLowerCase();
|
|
150
|
+
const name = SERVICE_TYPES[key] || SERVICE_TYPES.outlet;
|
|
151
|
+
return this.Service[name];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
removeStaleCachedAccessories() {
|
|
155
|
+
if (this.cachedAccessories.size === 0) return;
|
|
156
|
+
const stale = [...this.cachedAccessories.values()];
|
|
157
|
+
this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, stale);
|
|
158
|
+
this.cachedAccessories.clear();
|
|
108
159
|
}
|
|
109
160
|
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-multiple-switch",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Multiple switch platform for Homebridge",
|
|
5
5
|
"homepage": "https://github.com/azadaydinli/homebridge-multiple-switch",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"author": "Azad Aydınlı",
|
|
8
8
|
"license": "ISC",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"lint": "echo \"No linter configured\"",
|
|
11
|
+
"test": "echo \"No tests configured\""
|
|
12
|
+
},
|
|
9
13
|
"bugs": {
|
|
10
14
|
"url": "https://github.com/azadaydinli/homebridge-multiple-switch/issues"
|
|
11
15
|
},
|
|
@@ -26,7 +30,7 @@
|
|
|
26
30
|
"url": "https://github.com/azadaydinli/homebridge-multiple-switch.git"
|
|
27
31
|
},
|
|
28
32
|
"engines": {
|
|
29
|
-
"node": ">=
|
|
33
|
+
"node": ">=18.0.0",
|
|
30
34
|
"homebridge": ">=1.3.0"
|
|
31
35
|
}
|
|
32
36
|
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
name: 📦 Publish to npm
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
tags:
|
|
6
|
-
- 'v*.*.*'
|
|
7
|
-
|
|
8
|
-
jobs:
|
|
9
|
-
publish:
|
|
10
|
-
runs-on: ubuntu-latest
|
|
11
|
-
|
|
12
|
-
steps:
|
|
13
|
-
- name: 📥 Repo-nu klonla
|
|
14
|
-
uses: actions/checkout@v3
|
|
15
|
-
|
|
16
|
-
- name: ⚙️ Node.js qur
|
|
17
|
-
uses: actions/setup-node@v3
|
|
18
|
-
with:
|
|
19
|
-
node-version: '18'
|
|
20
|
-
registry-url: 'https://registry.npmjs.org/'
|
|
21
|
-
|
|
22
|
-
- name: 📦 Asılılıqları qur
|
|
23
|
-
run: npm install
|
|
24
|
-
|
|
25
|
-
- name: 🚀 NPM-ə yüklə
|
|
26
|
-
run: npm publish
|
|
27
|
-
env:
|
|
28
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
name: 📦 Publish to npm
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
tags:
|
|
6
|
-
- 'v*.*.*'
|
|
7
|
-
|
|
8
|
-
jobs:
|
|
9
|
-
publish:
|
|
10
|
-
runs-on: ubuntu-latest
|
|
11
|
-
|
|
12
|
-
steps:
|
|
13
|
-
- name: 📥 Repo-nu klonla
|
|
14
|
-
uses: actions/checkout@v3
|
|
15
|
-
|
|
16
|
-
- name: ⚙️ Node.js qur
|
|
17
|
-
uses: actions/setup-node@v3
|
|
18
|
-
with:
|
|
19
|
-
node-version: '18'
|
|
20
|
-
registry-url: 'https://registry.npmjs.org/'
|
|
21
|
-
|
|
22
|
-
- name: 📦 Asılılıqları qur
|
|
23
|
-
run: npm install
|
|
24
|
-
|
|
25
|
-
- name: 🚀 NPM-ə yüklə
|
|
26
|
-
run: npm publish
|
|
27
|
-
env:
|
|
28
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
name: 📦 Publish to npm
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
tags:
|
|
6
|
-
- 'v*.*.*'
|
|
7
|
-
|
|
8
|
-
jobs:
|
|
9
|
-
publish:
|
|
10
|
-
runs-on: ubuntu-latest
|
|
11
|
-
|
|
12
|
-
steps:
|
|
13
|
-
- name: 📥 Repo-nu klonla
|
|
14
|
-
uses: actions/checkout@v3
|
|
15
|
-
|
|
16
|
-
- name: ⚙️ Node.js qur
|
|
17
|
-
uses: actions/setup-node@v3
|
|
18
|
-
with:
|
|
19
|
-
node-version: '18'
|
|
20
|
-
registry-url: 'https://registry.npmjs.org/'
|
|
21
|
-
|
|
22
|
-
- name: 📦 Asılılıqları qur
|
|
23
|
-
run: npm install
|
|
24
|
-
|
|
25
|
-
- name: 🚀 NPM-ə yüklə
|
|
26
|
-
run: npm publish
|
|
27
|
-
env:
|
|
28
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|