matterbridge-example-dynamic-platform 1.1.8 → 1.2.0-edge.10

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/dist/robot.js ADDED
@@ -0,0 +1,215 @@
1
+ import { Matterbridge, MatterbridgeServer, MatterbridgeEndpoint, roboticVacuumCleaner, dishwasher } from 'matterbridge';
2
+ import { LogLevel as MatterLogLevel, LogFormat as MatterLogFormat, EndpointServer, logEndpoint, DeviceTypeId, VendorId, } from 'matterbridge/matter';
3
+ import { ModeBase, OperationalState, PowerSource, RvcRunMode, RvcCleanMode, RvcOperationalState, ServiceArea } from 'matterbridge/matter/clusters';
4
+ import { ActionsServer, RvcCleanModeBehavior, RvcOperationalStateBehavior, RvcRunModeBehavior, ServiceAreaBehavior } from 'matterbridge/matter/behaviors';
5
+ import { AnsiLogger } from 'matterbridge/logger';
6
+ import { Appliances } from './appliances.js';
7
+ export class Robot extends MatterbridgeEndpoint {
8
+ constructor(name, serial) {
9
+ super(roboticVacuumCleaner, { uniqueStorageKey: `${name}-${serial}` }, true);
10
+ this.createDefaultIdentifyClusterServer()
11
+ .createDefaultBasicInformationClusterServer(name, serial, 0xfff1, 'Matterbridge', 0x8000, 'Matterbridge Robot Vacuum Cleaner')
12
+ .createDefaultRvcRunModeClusterServer()
13
+ .createDefaultRvcOperationalStateClusterServer()
14
+ .createDefaultRvcCleanModeClusterServer()
15
+ .createDefaultServiceAreaClusterServer()
16
+ .createDefaultPowerSourceRechargeableBatteryClusterServer(80, PowerSource.BatChargeLevel.Ok, 5900);
17
+ }
18
+ createDefaultRvcRunModeClusterServer(currentMode, supportedModes) {
19
+ this.behaviors.require(MatterbridgeRvcRunModeServer, {
20
+ supportedModes: supportedModes ?? [
21
+ { label: 'Idle', mode: 1, modeTags: [{ value: RvcRunMode.ModeTag.Idle }] },
22
+ { label: 'Cleaning', mode: 2, modeTags: [{ value: RvcRunMode.ModeTag.Cleaning }] },
23
+ { label: 'Mapping', mode: 3, modeTags: [{ value: RvcRunMode.ModeTag.Mapping }] },
24
+ { label: 'SpotCleaning', mode: 4, modeTags: [{ value: RvcRunMode.ModeTag.Cleaning }, { value: RvcRunMode.ModeTag.Max }] },
25
+ ],
26
+ currentMode: currentMode ?? 1,
27
+ });
28
+ return this;
29
+ }
30
+ createDefaultRvcCleanModeClusterServer(currentMode, supportedModes) {
31
+ this.behaviors.require(MatterbridgeRvcCleanModeServer, {
32
+ supportedModes: supportedModes ?? [
33
+ { label: 'Vacuum', mode: 1, modeTags: [{ value: RvcCleanMode.ModeTag.Vacuum }] },
34
+ { label: 'Mop', mode: 2, modeTags: [{ value: RvcCleanMode.ModeTag.Mop }] },
35
+ { label: 'Clean', mode: 3, modeTags: [{ value: RvcCleanMode.ModeTag.DeepClean }] },
36
+ ],
37
+ currentMode: currentMode ?? 1,
38
+ });
39
+ return this;
40
+ }
41
+ createDefaultServiceAreaClusterServer(supportedAreas, selectedAreas) {
42
+ this.behaviors.require(MatterbridgeServiceAreaServer, {
43
+ supportedAreas: supportedAreas ?? [
44
+ {
45
+ areaId: 1,
46
+ mapId: null,
47
+ areaInfo: { locationInfo: { locationName: 'Living', floorNumber: null, areaType: null }, landmarkInfo: null },
48
+ },
49
+ {
50
+ areaId: 2,
51
+ mapId: null,
52
+ areaInfo: { locationInfo: { locationName: 'Kitchen', floorNumber: null, areaType: null }, landmarkInfo: null },
53
+ },
54
+ {
55
+ areaId: 3,
56
+ mapId: null,
57
+ areaInfo: { locationInfo: { locationName: 'Bedroom', floorNumber: null, areaType: null }, landmarkInfo: null },
58
+ },
59
+ {
60
+ areaId: 4,
61
+ mapId: null,
62
+ areaInfo: { locationInfo: { locationName: 'Bathroom', floorNumber: null, areaType: null }, landmarkInfo: null },
63
+ },
64
+ ],
65
+ selectedAreas: selectedAreas ?? [],
66
+ currentArea: 1,
67
+ estimatedEndTime: null,
68
+ });
69
+ return this;
70
+ }
71
+ createDefaultRvcOperationalStateClusterServer(phaseList = null, currentPhase = null, operationalStateList, operationalState, operationalError) {
72
+ this.behaviors.require(MatterbridgeRvcOperationalStateServer, {
73
+ phaseList,
74
+ currentPhase,
75
+ operationalStateList: operationalStateList ?? [
76
+ { operationalStateId: RvcOperationalState.OperationalState.Stopped, operationalStateLabel: 'Stopped' },
77
+ { operationalStateId: RvcOperationalState.OperationalState.Running, operationalStateLabel: 'Running' },
78
+ { operationalStateId: RvcOperationalState.OperationalState.Paused, operationalStateLabel: 'Paused' },
79
+ { operationalStateId: RvcOperationalState.OperationalState.Error, operationalStateLabel: 'Error' },
80
+ { operationalStateId: RvcOperationalState.OperationalState.SeekingCharger, operationalStateLabel: 'SeekingCharger' },
81
+ { operationalStateId: RvcOperationalState.OperationalState.Charging, operationalStateLabel: 'Charging' },
82
+ { operationalStateId: RvcOperationalState.OperationalState.Docked, operationalStateLabel: 'Docked' },
83
+ ],
84
+ operationalState: operationalState ?? RvcOperationalState.OperationalState.Docked,
85
+ operationalError: operationalError ?? { errorStateId: RvcOperationalState.ErrorState.NoError, errorStateLabel: 'No Error', errorStateDetails: 'Fully operational' },
86
+ });
87
+ return this;
88
+ }
89
+ }
90
+ export class MatterbridgeServiceAreaServer extends ServiceAreaBehavior {
91
+ initialize() {
92
+ }
93
+ selectAreas({ newAreas }) {
94
+ const device = this.endpoint.stateOf(MatterbridgeServer).deviceCommand;
95
+ for (const area of newAreas) {
96
+ const supportedArea = this.state.supportedAreas.find((supportedArea) => supportedArea.areaId === area);
97
+ if (!supportedArea) {
98
+ device.log.error('MatterbridgeServiceAreaServer selectAreas called with unsupported area:', area);
99
+ return { status: ServiceArea.SelectAreasStatus.UnsupportedArea, statusText: 'Unsupported areas' };
100
+ }
101
+ }
102
+ this.state.selectedAreas = newAreas;
103
+ this.state.currentArea = newAreas[0];
104
+ device.log.info(`***MatterbridgeServiceAreaServer selectAreas called with: ${newAreas.map((area) => area.toString()).join(', ')}`);
105
+ return { status: ServiceArea.SelectAreasStatus.Success, statusText: 'Succesfully selected new areas' };
106
+ }
107
+ }
108
+ export class MatterbridgeRvcRunModeServer extends RvcRunModeBehavior {
109
+ initialize() {
110
+ this.state.currentMode = 1;
111
+ }
112
+ changeToMode({ newMode }) {
113
+ const device = this.endpoint.stateOf(MatterbridgeServer).deviceCommand;
114
+ const changedMode = this.state.supportedModes.find((mode) => mode.mode === newMode);
115
+ if (!changedMode) {
116
+ device.log.error('MatterbridgeRvcRunModeServer changeToMode called with unsupported newMode:', newMode);
117
+ return { status: ModeBase.ModeChangeStatus.InvalidInMode, statusText: 'Invalid mode' };
118
+ }
119
+ device.changeToMode({ newMode });
120
+ this.state.currentMode = newMode;
121
+ if (changedMode.modeTags.find((tag) => tag.value === RvcRunMode.ModeTag.Cleaning)) {
122
+ device.log.info('***MatterbridgeRvcRunModeServer changeToMode called with newMode Cleaning => Running');
123
+ this.agent.get(MatterbridgeRvcOperationalStateServer).state.operationalState = RvcOperationalState.OperationalState.Running;
124
+ return { status: ModeBase.ModeChangeStatus.Success, statusText: 'Running' };
125
+ }
126
+ else if (changedMode.modeTags.find((tag) => tag.value === RvcRunMode.ModeTag.Idle)) {
127
+ device.log.info('***MatterbridgeRvcRunModeServer changeToMode called with newMode Idle => Docked');
128
+ this.agent.get(MatterbridgeRvcOperationalStateServer).state.operationalState = RvcOperationalState.OperationalState.Docked;
129
+ return { status: ModeBase.ModeChangeStatus.Success, statusText: 'Docked' };
130
+ }
131
+ device.log.info(`***MatterbridgeRvcRunModeServer changeToMode called with newMode ${newMode} => ${changedMode.label}`);
132
+ this.agent.get(MatterbridgeRvcOperationalStateServer).state.operationalState = RvcOperationalState.OperationalState.Running;
133
+ return { status: ModeBase.ModeChangeStatus.Success, statusText: 'Success' };
134
+ }
135
+ }
136
+ export class MatterbridgeRvcCleanModeServer extends RvcCleanModeBehavior {
137
+ initialize() {
138
+ this.state.currentMode = 1;
139
+ }
140
+ changeToMode({ newMode }) {
141
+ const device = this.endpoint.stateOf(MatterbridgeServer).deviceCommand;
142
+ const supported = this.state.supportedModes.find((mode) => mode.mode === newMode);
143
+ if (!supported) {
144
+ device.log.error('***MatterbridgeRvcCleanModeServer changeToMode called with unsupported newMode:', newMode);
145
+ return { status: ModeBase.ModeChangeStatus.InvalidInMode, statusText: 'Invalid mode' };
146
+ }
147
+ device.changeToMode({ newMode });
148
+ this.state.currentMode = newMode;
149
+ device.log.info(`***MatterbridgeRvcCleanModeServer changeToMode called with newMode ${newMode} => ${supported.label}`);
150
+ return { status: ModeBase.ModeChangeStatus.Success, statusText: 'Success' };
151
+ }
152
+ }
153
+ export class MatterbridgeRvcOperationalStateServer extends RvcOperationalStateBehavior {
154
+ initialize() {
155
+ const device = this.endpoint.stateOf(MatterbridgeServer).deviceCommand;
156
+ device.log.info('***MatterbridgeRvcOperationalStateServer initialized: setting operational state to Docked');
157
+ this.state.operationalState = RvcOperationalState.OperationalState.Docked;
158
+ this.state.operationalError = { errorStateId: RvcOperationalState.ErrorState.NoError, errorStateLabel: 'No Error', errorStateDetails: 'Fully operational' };
159
+ }
160
+ pause() {
161
+ const device = this.endpoint.stateOf(MatterbridgeServer).deviceCommand;
162
+ device.log.info('MatterbridgeRvcOperationalStateServer: pause called setting operational state to Paused and currentMode to Idle');
163
+ this.agent.get(MatterbridgeRvcRunModeServer).state.currentMode = 1;
164
+ this.state.operationalState = RvcOperationalState.OperationalState.Paused;
165
+ this.state.operationalError = { errorStateId: RvcOperationalState.ErrorState.NoError, errorStateLabel: 'No Error', errorStateDetails: 'Fully operational' };
166
+ return {
167
+ commandResponseState: { errorStateId: OperationalState.ErrorState.NoError, errorStateLabel: 'No error', errorStateDetails: 'Fully operational' },
168
+ };
169
+ }
170
+ resume() {
171
+ const device = this.endpoint.stateOf(MatterbridgeServer).deviceCommand;
172
+ device.log.info('MatterbridgeRvcOperationalStateServer: resume called setting operational state to Running and currentMode to Cleaning');
173
+ this.agent.get(MatterbridgeRvcRunModeServer).state.currentMode = 2;
174
+ this.state.operationalState = RvcOperationalState.OperationalState.Running;
175
+ this.state.operationalError = { errorStateId: RvcOperationalState.ErrorState.NoError, errorStateLabel: 'No Error', errorStateDetails: 'Fully operational' };
176
+ return {
177
+ commandResponseState: { errorStateId: OperationalState.ErrorState.NoError, errorStateLabel: 'No error', errorStateDetails: 'Fully operational' },
178
+ };
179
+ }
180
+ goHome() {
181
+ const device = this.endpoint.stateOf(MatterbridgeServer).deviceCommand;
182
+ device.log.info('MatterbridgeRvcOperationalStateServer: goHome called setting operational state to Docked and currentMode to Idle');
183
+ this.agent.get(MatterbridgeRvcRunModeServer).state.currentMode = 1;
184
+ this.state.operationalState = RvcOperationalState.OperationalState.Docked;
185
+ this.state.operationalError = { errorStateId: RvcOperationalState.ErrorState.NoError, errorStateLabel: 'No Error', errorStateDetails: 'Fully operational' };
186
+ return {
187
+ commandResponseState: { errorStateId: OperationalState.ErrorState.NoError, errorStateLabel: 'No error', errorStateDetails: 'Fully operational' },
188
+ };
189
+ }
190
+ }
191
+ function createEndpointActionsClusterServer(endpoint, endpointLists) {
192
+ endpoint.behaviors.require(ActionsServer, {
193
+ actionList: [],
194
+ endpointLists,
195
+ });
196
+ return endpoint;
197
+ }
198
+ if (process.argv.includes('-testRobot')) {
199
+ const matterbridge = await Matterbridge.loadInstance(false);
200
+ matterbridge.log = new AnsiLogger({ logName: 'Matterbridge', logTimestampFormat: 4, logLevel: "debug" });
201
+ matterbridge.environment.vars.set('log.level', MatterLogLevel.DEBUG);
202
+ matterbridge.environment.vars.set('log.format', MatterLogFormat.ANSI);
203
+ matterbridge.environment.vars.set('path.root', 'matterstorage');
204
+ matterbridge.environment.vars.set('runtime.signals', true);
205
+ matterbridge.environment.vars.set('runtime.exitcode', true);
206
+ matterbridge.environment.vars.set('mdns.networkInterface', 'Wi-Fi');
207
+ await matterbridge.startMatterStorage();
208
+ const deviceType = dishwasher;
209
+ const context = await matterbridge.createServerNodeContext('Matterbridge', deviceType.name, DeviceTypeId(deviceType.code), VendorId(0xfff1), 'Matterbridge', 0x8000, 'Matterbridge device');
210
+ const server = (await matterbridge.createServerNode(context));
211
+ const device = new Appliances(deviceType, 'Dish Washer', '97754248654');
212
+ await server.add(device);
213
+ await matterbridge.startServerNode(server);
214
+ logEndpoint(EndpointServer.forEndpoint(server));
215
+ }
@@ -2,6 +2,8 @@
2
2
  "name": "matterbridge-example-dynamic-platform",
3
3
  "type": "DynamicPlatform",
4
4
  "version": "1.1.7",
5
+ "whiteList": [],
6
+ "blackList": [],
5
7
  "useInterval": true,
6
8
  "debug": true,
7
9
  "unregisterOnShutdown": false
@@ -7,18 +7,43 @@
7
7
  "name": {
8
8
  "description": "Plugin name",
9
9
  "type": "string",
10
- "readOnly": true
10
+ "readOnly": true,
11
+ "ui:widget": "hidden"
11
12
  },
12
13
  "type": {
13
14
  "description": "Plugin type",
14
15
  "type": "string",
15
- "readOnly": true
16
+ "readOnly": true,
17
+ "ui:widget": "hidden"
18
+ },
19
+ "whiteList": {
20
+ "description": "Only the devices in the list will be exposed. If the list is empty, all the devices will be exposed.",
21
+ "type": "array",
22
+ "items": {
23
+ "type": "string"
24
+ },
25
+ "uniqueItems": true,
26
+ "selectFrom": "name"
27
+ },
28
+ "blackList": {
29
+ "description": "The devices in the list will not be exposed. If the list is empty, no devices will be excluded.",
30
+ "type": "array",
31
+ "items": {
32
+ "type": "string"
33
+ },
34
+ "uniqueItems": true,
35
+ "selectFrom": "name"
16
36
  },
17
37
  "useInterval": {
18
38
  "description": "Use interval to refresh the devices",
19
39
  "type": "boolean",
20
40
  "default": true
21
41
  },
42
+ "enableConcentrationMeasurements": {
43
+ "description": "Enable the ConcentrationMeasurements in the Air Quality device and SmokeCoSensor devices (Apple Home 18.4 will discard these devices when enabled)",
44
+ "type": "boolean",
45
+ "default": true
46
+ },
22
47
  "debug": {
23
48
  "description": "Enable the debug for the plugin (development only)",
24
49
  "type": "boolean",
@@ -0,0 +1,50 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 296.2 296.2">
2
+ <defs>
3
+ <linearGradient id="lg1" x1="16.6" y1="16.6" x2="279.6" y2="279.6" gradientUnits="userSpaceOnUse">
4
+ <stop offset="0" stop-color="#00b48d" />
5
+ <stop offset=".1" stop-color="#3faa77" />
6
+ <stop offset=".3" stop-color="#234148" />
7
+ <stop offset=".7" stop-color="#203b44" />
8
+ <stop offset=".9" stop-color="#ad2e6e" />
9
+ <stop offset="1" stop-color="#c81b74" />
10
+ </linearGradient>
11
+ <linearGradient id="lg2" x1="31.1" y1="31.1" x2="265.1" y2="265.1" gradientUnits="userSpaceOnUse">
12
+ <stop offset="0" stop-color="#00b48d" />
13
+ <stop offset=".2" stop-color="#285251" />
14
+ <stop offset=".4" stop-color="#234148" />
15
+ <stop offset=".8" stop-color="#203b44" />
16
+ <stop offset=".9" stop-color="#a8316c" />
17
+ <stop offset="1" stop-color="#c81b74" />
18
+ </linearGradient>
19
+ <linearGradient id="lg3" x1="116.2" y1="143.9" x2="139.8" y2="143.9"
20
+ gradientUnits="userSpaceOnUse">
21
+ <stop offset="0" stop-color="#8bc751" />
22
+ <stop offset="1" stop-color="#0db14b" />
23
+ </linearGradient>
24
+ <linearGradient id="lg4" x1="136.1" y1="100.8" x2="159.6" y2="100.8"
25
+ xlink:href="#lg3" />
26
+ <linearGradient id="lg5" x1="155.3" y1="143.9" x2="178.9" y2="143.9"
27
+ xlink:href="#lg3" />
28
+ <linearGradient id="lg6" x1="46.8" y1="25.7" x2="89.6" y2="74.8" gradientUnits="userSpaceOnUse">
29
+ <stop offset="0" stop-color="#b1d34a" />
30
+ <stop offset="1" stop-color="#50b848" />
31
+ </linearGradient>
32
+ </defs>
33
+ <rect width="296.2" height="296.2" rx="56.7" ry="56.7" style="fill:url(#lg1)" />
34
+ <rect x="16.3" y="16.3" width="263.6" height="263.6" rx="50.5" ry="50.5" style="fill:url(#lg2)" />
35
+ <circle cx="128" cy="143.9" r="11.8" style="fill:url(#lg3)" />
36
+ <circle cx="147.8" cy="100.8" r="11.8" style="fill:url(#lg4)" />
37
+ <path
38
+ d="m244.6 114.5.4-.5L160 33a17 17 0 0 0-24.7-.5l-86.4 83.3a15 15 0 0 0 9.2 26.9h19.3v-4.7l-13.7-12.7v-.1l83.7-80.8 84.2 81-13.9 12.8v4.5h19.5a15 15 0 0 0 7.4-28.1Z"
39
+ style="fill:url(#lg3)" />
40
+ <circle cx="167.1" cy="143.9" r="11.8" style="fill:url(#lg5)" />
41
+ <path fill="#fff" d="M219 89.3V35.5a10.5 10.5 0 1 0-21 0v33.7l21 20Z" />
42
+ <path
43
+ d="M91.4 73.3H83a37 37 0 0 0-14.5-28.4L65 50.2c.1 0 12.6 9 11.7 25.4-5.3-.4-11.2-1.9-16.3-5.3-11.8-7.8-16-23.7-11.9-46 8.7 1.5 34 7 43 22.8 4.1 7.3 4.1 16.1 0 26.2Z"
44
+ style="fill:url(#lg6)" />
45
+ <path
46
+ d="M65.9 80a49.6 49.6 0 0 0 17.8 2.2l16.6-16c1.6-8.3.5-15.7-3.3-22.4C84.6 22 47.8 17.5 46.2 17.4l-3-.4-.6 3c-3.8 18.4-5.9 50.6 23.2 60ZM48.4 24.4c8.7 1.5 34 7 43 22.8 4.1 7.3 4.1 16.1 0 26.2H83a37 37 0 0 0-14.5-28.4l-3.7 5.3c.1 0 12.6 9 11.7 25.4-5.3-.4-11.2-1.9-16.3-5.3-11.9-7.8-16-23.7-11.9-46Z"
47
+ fill="#1e5857" />
48
+ <path fill="#fff"
49
+ d="M250.5 90.5a17.4 17.4 0 1 1 0-34.8 17.4 17.4 0 0 1 0 34.8Zm0-22.7a5.4 5.4 0 0 0 0 10.7 5.3 5.3 0 0 0 0-10.7ZM258.8 148.2a15.9 15.9 0 0 0-9.6 28.5c-.8 4.2-5.4 4.6-5.4 4.6h-26v-43l13.6-13-1.8-2-82.2-79-81.2 78.3-2.5 2.6 13.7 13v42.9H53a21.5 21.5 0 1 0 11.7 15h12.6v18.8c0 7.8 6.4 14.1 14.1 14.1h29.3v14.8H64a10.6 10.6 0 0 0-17.7 8 10.6 10.6 0 0 0 17.6 8h157.6a16.3 16.3 0 1 0 0-16h-84.8V229h66.8c7.8 0 14.2-6.3 14.2-14.1v-19.2h27.6c14.3 0 17.8-12.8 18.5-16.6a15.9 15.9 0 0 0-5-30.9ZM43.7 210.8a10.3 10.3 0 1 1 0-20.6 10.3 10.3 0 0 1 0 20.6Zm192 36a5 5 0 1 1 0 10 5 5 0 0 1 0-10Zm-77-34.8h-22v-34h22v34Zm8.4-79.8c2.7 0 5.2 1 7.2 2.5v-10.4L188 137s2.6 1.3 4.6 1.3h6.7v68c0 3.2-2.6 5.7-5.7 5.7h-19v-34h1.4a7.5 7.5 0 0 0 0-15H120a7.5 7.5 0 0 0 0 15h.7v34h-19.3a5.7 5.7 0 0 1-5.7-5.6v-68.1h6.7c2 0 4.6-1.3 4.6-1.3l13.7-12.7v10.4a11.7 11.7 0 0 1 16 1.6v-13a14.9 14.9 0 0 0-25-10.8s-.1.2-.1.2l-.5.5-6.9 7H92.5l55-53.2 55.1 53.2h-11.8l-7-7c0-.2-.2-.3-.4-.5l-.2-.2a14.8 14.8 0 0 0-25 10.9v12.9c2.2-2.5 5.3-4.1 8.9-4.1Zm91.7 36.7a4.9 4.9 0 1 1 0-9.7 4.9 4.9 0 0 1 0 9.7Z" />
50
+ </svg>
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "matterbridge-example-dynamic-platform",
3
- "version": "1.1.8",
3
+ "version": "1.2.0-edge.10",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "matterbridge-example-dynamic-platform",
9
- "version": "1.1.8",
9
+ "version": "1.2.0-edge.10",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "node-ansi-logger": "3.0.1",
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "matterbridge-example-dynamic-platform",
3
- "version": "1.1.8",
3
+ "version": "1.2.0-edge.10",
4
4
  "description": "Matterbridge dynamic plugin",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "MIT",
7
+ "homepage": "https://www.npmjs.com/package/matterbridge-example-dynamic-platform",
7
8
  "type": "module",
8
9
  "main": "dist/index.js",
9
10
  "repository": {
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ // enable isolatedModules just for ts-jest
5
+ "isolatedModules": true
6
+ },
7
+ "include": ["**/*.spec.ts", "**/*.test.ts", "**/__test__/*"]
8
+ }