sinricpro 2.3.1 → 2.6.1

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.
@@ -1,32 +1,32 @@
1
- # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2
- # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
3
-
4
- name: Node.js Package
5
-
6
- on:
7
- release:
8
- types: [created]
9
-
10
- jobs:
11
- build:
12
- runs-on: ubuntu-latest
13
- steps:
14
- - uses: actions/checkout@v2
15
- - uses: actions/setup-node@v2
16
- with:
17
- node-version: 16
18
- - run: npm ci
19
-
20
- publish-npm:
21
- needs: build
22
- runs-on: ubuntu-latest
23
- steps:
24
- - uses: actions/checkout@v2
25
- - uses: actions/setup-node@v2
26
- with:
27
- node-version: 16
28
- registry-url: https://registry.npmjs.org/
29
- - run: npm ci
30
- - run: npm publish
31
- env:
32
- NODE_AUTH_TOKEN: ${{secrets.npm_token}}
1
+ # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2
+ # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
3
+
4
+ name: Node.js Package
5
+
6
+ on:
7
+ release:
8
+ types: [created]
9
+
10
+ jobs:
11
+ build:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+ - uses: actions/setup-node@v2
16
+ with:
17
+ node-version: 16
18
+ - run: npm ci
19
+
20
+ publish-npm:
21
+ needs: build
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - uses: actions/checkout@v2
25
+ - uses: actions/setup-node@v2
26
+ with:
27
+ node-version: 16
28
+ registry-url: https://registry.npmjs.org/
29
+ - run: npm ci
30
+ - run: npm publish
31
+ env:
32
+ NODE_AUTH_TOKEN: ${{secrets.npm_token}}
package/CHANGELOG.md ADDED
@@ -0,0 +1,6 @@
1
+ ## [2.6.1]
2
+
3
+ ### Features
4
+
5
+ * **Custom device types support**
6
+ * **SR_DEBUG to support debug logs**
package/README.md CHANGED
@@ -1,15 +1,15 @@
1
- # SinricPro (NodeJs-SDK)
2
-
3
- [![](https://img.shields.io/npm/v/sinricpro)](https://www.npmjs.com/package/sinricpro)
4
- [![](https://img.shields.io/npm/dependency-version/sinricpro/dev/eslint)](https://www.npmjs.com/package/sinricpro)
5
- [![](https://img.shields.io/bundlephobia/min/sinricpro)](https://www.npmjs.com/package/sinricpro)
6
- [![](https://img.shields.io/github/languages/code-size/sinricpro/nodejs-sdk)](https://www.npmjs.com/package/sinricpro)
7
-
8
- ### Installation
9
-
10
- ```
11
- npm install sinricpro
12
- ```
13
-
14
- ### Examples
15
- Check the examples [here](https://github.com/sinricpro/nodejs-sdk/tree/master/examples)
1
+ # SinricPro (NodeJs-SDK)
2
+
3
+ [![](https://img.shields.io/npm/v/sinricpro)](https://www.npmjs.com/package/sinricpro)
4
+ [![](https://img.shields.io/npm/dependency-version/sinricpro/dev/eslint)](https://www.npmjs.com/package/sinricpro)
5
+ [![](https://img.shields.io/bundlephobia/min/sinricpro)](https://www.npmjs.com/package/sinricpro)
6
+ [![](https://img.shields.io/github/languages/code-size/sinricpro/nodejs-sdk)](https://www.npmjs.com/package/sinricpro)
7
+
8
+ ### Installation
9
+
10
+ ```
11
+ npm install sinricpro
12
+ ```
13
+
14
+ ### Examples
15
+ Check the examples [here](https://github.com/sinricpro/nodejs-sdk/tree/master/examples)
package/lib/cbhandler.js CHANGED
@@ -15,16 +15,18 @@ const { RangeValue, RangeValueAdjust } = require('./contorllers/range_value_cont
15
15
  const { Volume, VolumeAdjust, Mute } = require('./contorllers/tv_controller');
16
16
  const { ChangeChannel, SkipChannel, Media } = require('./contorllers/tv_controller');
17
17
  const { Input } = require('./contorllers/tv_controller');
18
- const { Bands, Mode, BandReset } = require('./contorllers/speaker_controller');
18
+ const { Bands, BandReset } = require('./contorllers/speaker_controller');
19
19
  const { AdjustBands } = require('./contorllers/speaker_controller');
20
+ const { ToggleState } = require('./contorllers/toggle_state_controller');
21
+ const { Mode } = require('./contorllers/mode_controller');
20
22
 
21
- const jsonResponse = (client, defaultPayload, dValue) => {
23
+ const jsonResponse = (client, defaultPayload, payloadValue, instanceId) => {
22
24
  const header = {
23
25
  payloadVersion: 2,
24
26
  signatureVersion: 1,
25
27
  };
26
28
 
27
- const payload = {
29
+ let payload = {
28
30
  action: defaultPayload.action,
29
31
  clientId: defaultPayload.clientId,
30
32
  createdAt: Math.floor(new Date() / 1000),
@@ -33,9 +35,11 @@ const jsonResponse = (client, defaultPayload, dValue) => {
33
35
  replyToken: defaultPayload.replyToken,
34
36
  success: true,
35
37
  type: 'response',
36
- value: dValue,
38
+ value: payloadValue,
37
39
  };
38
40
 
41
+ if(instanceId) payload.instanceId = instanceId;
42
+
39
43
  const signature = {
40
44
  HMAC: getSignature(client, JSON.stringify(payload)),
41
45
  };
@@ -49,144 +53,150 @@ const handlePayload = (client, payload, signature, callbacks) => verifySignature
49
53
  return powerState(payload, callbacks)
50
54
  .then((value) => jsonResponse(client, payload, value))
51
55
  .catch((err) => {
52
- console.log(err.message);
56
+ if (process.env.SR_DEBUG) console.log(err.message);
53
57
  });
54
58
  } else if (action === 'setPowerLevel') {
55
59
  return powerLevel(payload, callbacks)
56
60
  .then((value) => jsonResponse(client, payload, value))
57
61
  .catch((err) => {
58
- console.log(err.message);
62
+ if (process.env.SR_DEBUG) console.log(err.message);
59
63
  });
60
64
  } else if (action === 'adjustPowerLevel') {
61
65
  return powerLevelAdjust(payload, callbacks)
62
66
  .then((value) => jsonResponse(client, payload, value))
63
67
  .catch((err) => {
64
- console.log(err.message);
68
+ if (process.env.SR_DEBUG) console.log(err.message);
65
69
  });
66
70
  } else if (action === 'setBrightness') {
67
71
  return Brightness(payload, callbacks)
68
72
  .then((value) => jsonResponse(client, payload, value))
69
73
  .catch((err) => {
70
- console.log(err.message);
74
+ if (process.env.SR_DEBUG) console.log(err.message);
71
75
  });
72
76
  } else if (action === 'adjustBrightness') {
73
77
  return BrightnessAdjust(payload, callbacks)
74
78
  .then((value) => jsonResponse(client, payload, value))
75
79
  .catch((err) => {
76
- console.log(err.message);
80
+ if (process.env.SR_DEBUG) console.log(err.message);
77
81
  });
78
82
  } else if (action === 'setColor') {
79
83
  return Color(payload, callbacks)
80
84
  .then((value) => jsonResponse(client, payload, value))
81
85
  .catch((err) => {
82
- console.log(err.message);
86
+ if (process.env.SR_DEBUG) console.log(err.message);
83
87
  });
84
88
  } else if (action === 'setColorTemperature') {
85
89
  return ColorTemperature(payload, callbacks)
86
90
  .then((value) => jsonResponse(client, payload, value))
87
91
  .catch((err) => {
88
- console.log(err.message);
92
+ if (process.env.SR_DEBUG) console.log(err.message);
89
93
  });
90
94
  } else if (action === 'setThermostatMode') {
91
95
  return ThermoStatMode(payload, callbacks)
92
96
  .then((value) => jsonResponse(client, payload, value))
93
97
  .catch((err) => {
94
- console.log(err.message);
98
+ if (process.env.SR_DEBUG) console.log(err.message);
95
99
  });
96
100
  } else if (action === 'targetTemperature') {
97
101
  return ThermoStatTemperature(payload, callbacks)
98
102
  .then((value) => jsonResponse(client, payload, value))
99
103
  .catch((err) => {
100
- console.log(err.message);
104
+ if (process.env.SR_DEBUG) console.log(err.message);
101
105
  });
102
106
  } else if (action === 'setRangeValue') {
103
107
  return RangeValue(payload, callbacks)
104
- .then((value) => jsonResponse(client, payload, value))
108
+ .then(([value, instanceId]) => jsonResponse(client, payload, value, instanceId))
105
109
  .catch((err) => {
106
- console.log(err.message);
110
+ if (process.env.SR_DEBUG) console.log(err.message);
107
111
  });
108
112
  } else if (action === 'adjustRangeValue') {
109
113
  return RangeValueAdjust(payload, callbacks)
110
- .then((value) => jsonResponse(client, payload, value))
114
+ .then(([value, instanceId]) => jsonResponse(client, payload, value, instanceId))
111
115
  .catch((err) => {
112
- console.log(err.message);
116
+ if (process.env.SR_DEBUG) console.log(err.message);
113
117
  });
114
118
  } else if (action === 'setVolume') {
115
119
  return Volume(payload, callbacks)
116
120
  .then((value) => jsonResponse(client, payload, value))
117
121
  .catch((err) => {
118
- console.log(err.message);
122
+ if (process.env.SR_DEBUG) console.log(err.message);
119
123
  });
120
124
  } else if (action === 'adjustVolume') {
121
125
  return VolumeAdjust(payload, callbacks)
122
126
  .then((value) => jsonResponse(client, payload, value))
123
127
  .catch((err) => {
124
- console.log(err.message);
128
+ if (process.env.SR_DEBUG) console.log(err.message);
125
129
  });
126
130
  } else if (action === 'selectInput') {
127
131
  return Input(payload, callbacks)
128
132
  .then((value) => jsonResponse(client, payload, value))
129
133
  .catch((err) => {
130
- console.log(err.message);
134
+ if (process.env.SR_DEBUG) console.log(err.message);
131
135
  });
132
136
  } else if (action === 'mediaControl') {
133
137
  return Media(payload, callbacks)
134
138
  .then((value) => jsonResponse(client, payload, value))
135
139
  .catch((err) => {
136
- console.log(err.message);
140
+ if (process.env.SR_DEBUG) console.log(err.message);
137
141
  });
138
142
  } else if (action === 'changeChannel') {
139
143
  return ChangeChannel(payload, callbacks)
140
144
  .then((value) => jsonResponse(client, payload, value))
141
145
  .catch((err) => {
142
- console.log(err.message);
146
+ if (process.env.SR_DEBUG) console.log(err.message);
143
147
  });
144
148
  } else if (action === 'skipChannels') {
145
149
  return SkipChannel(payload, callbacks)
146
150
  .then((value) => jsonResponse(client, payload, value))
147
151
  .catch((err) => {
148
- console.log(err.message);
152
+ if (process.env.SR_DEBUG) console.log(err.message);
149
153
  });
150
154
  } else if (action === 'setBands') {
151
155
  return Bands(payload, callbacks)
152
156
  .then((value) => jsonResponse(client, payload, value))
153
157
  .catch((err) => {
154
- console.log(err.message);
158
+ if (process.env.SR_DEBUG) console.log(err.message);
155
159
  });
156
160
  } else if (action === 'adjustBands') {
157
161
  return AdjustBands(payload, callbacks)
158
162
  .then((value) => jsonResponse(client, payload, value))
159
163
  .catch((err) => {
160
- console.log(err.message);
164
+ if (process.env.SR_DEBUG) console.log(err.message);
161
165
  });
162
166
  } else if (action === 'resetBands') {
163
167
  return BandReset(payload, callbacks)
164
168
  .then((value) => jsonResponse(client, payload, value))
165
169
  .catch((err) => {
166
- console.log(err.message);
170
+ if (process.env.SR_DEBUG) console.log(err.message);
167
171
  });
168
172
  } else if (action === 'setMode') {
169
173
  return Mode(payload, callbacks)
170
- .then((value) => jsonResponse(client, payload, value))
174
+ .then(([value, instanceId]) => jsonResponse(client, payload, value, instanceId))
171
175
  .catch((err) => {
172
- console.log(err.message);
176
+ if (process.env.SR_DEBUG) console.log(err.message);
173
177
  });
174
178
  } else if (action === 'setLockState') {
175
179
  return Lock(payload, callbacks)
176
180
  .then((value) => jsonResponse(client, payload, value))
177
181
  .catch((err) => {
178
- console.log(err.message);
182
+ if (process.env.SR_DEBUG) console.log(err.message);
179
183
  });
180
184
  } else if (action === 'setMute') {
181
185
  return Mute(payload, callbacks)
182
186
  .then((value) => jsonResponse(client, payload, value))
183
187
  .catch((err) => {
184
- console.log(err.message);
188
+ if (process.env.SR_DEBUG) console.log(err.message);
189
+ });
190
+ } else if (action === 'setToggleState') {
191
+ return ToggleState(payload, callbacks)
192
+ .then(([value, instanceId]) => jsonResponse(client, payload, value, instanceId))
193
+ .catch((err) => {
194
+ if (process.env.SR_DEBUG) console.log(err.message);
185
195
  });
186
196
  }
187
197
  return {};
188
198
  })
189
199
  .catch((err) => {
190
- console.log(err.message);
200
+ console.error(err.message);
191
201
  });
192
202
  module.exports = handlePayload;
@@ -0,0 +1,21 @@
1
+ /*
2
+ * Copyright (c) 2019 Sinric. All rights reserved.
3
+ * Licensed under Creative Commons Attribution-Share Alike (CC BY-SA)
4
+ *
5
+ * This file is part of the Sinric Pro (https://github.com/sinricpro/)
6
+ */
7
+
8
+ const sinricData = require('../storage');
9
+
10
+ const Mode = (payload, callbacks) => {
11
+ const resp = callbacks.setMode(payload.deviceId, payload.value.mode, payload.instanceId);
12
+
13
+ return new Promise((resolve, reject) => {
14
+ if (resp) resolve([payload.value, payload.instanceId]);
15
+ else reject(new Error('Mode undefined'));
16
+ });
17
+ };
18
+
19
+ module.exports = {
20
+ Mode
21
+ };
@@ -1,4 +1,3 @@
1
-
2
1
  /*
3
2
  * Copyright (c) 2019 Sinric. All rights reserved.
4
3
  * Licensed under Creative Commons Attribution-Share Alike (CC BY-SA)
@@ -10,20 +9,25 @@ const sinricProData = require('../storage');
10
9
 
11
10
  const RangeValue = (payload, callbacks) => {
12
11
  sinricProData.rangeValue = payload.value.rangeValue;
13
- const resp = callbacks.setRangeValue(payload.deviceId, sinricProData.rangeValue);
12
+
13
+ const resp = callbacks.setRangeValue(payload.deviceId, sinricProData.rangeValue, payload.instanceId);
14
+
14
15
  return new Promise((resolve, reject) => {
15
- if (payload.value.rangeValue && resp) resolve(payload.value);
16
+ if (payload.value.rangeValue !== undefined && resp) resolve([payload.value, payload.instanceId]);
16
17
  else reject(new Error('RangeValue is undefined'));
17
18
  });
18
19
  };
19
20
 
20
21
  const RangeValueAdjust = (payload, callbacks) => {
21
- sinricProData.rangeValue += payload.value.rangeValueDelta;
22
+ sinricProData.rangeValue += payload.value.rangeValueDelta;
23
+
22
24
  if (sinricProData.rangeValue < 0) sinricProData.rangeValue = 0;
23
25
  else if (sinricProData.rangeValue > 100) sinricProData.rangeValue = 100;
24
- const resp = callbacks.adjustRangeValue(payload.deviceId, sinricProData.rangeValue);
26
+
27
+ const resp = callbacks.adjustRangeValue(payload.deviceId, sinricProData.rangeValue, payload.instanceId);
28
+
25
29
  return new Promise((resolve, reject) => {
26
- if (payload.value.rangeValueDelta && resp) resolve({ rangeValue: sinricProData.rangeValue });
30
+ if (payload.value.rangeValueDelta && resp) resolve([{ rangeValue: sinricProData.rangeValue }, payload.instanceId]);
27
31
  else reject(new Error('RangeValue undefined'));
28
32
  });
29
33
  };
@@ -18,14 +18,6 @@ const Bands = (payload, callbacks) => {
18
18
  });
19
19
  };
20
20
 
21
- const Mode = (payload, callbacks) => {
22
- const resp = callbacks.setMode(payload.deviceId, payload.value.mode);
23
- return new Promise((resolve, reject) => {
24
- if (resp) resolve(payload.value);
25
- else reject(new Error('Mode undefined'));
26
- });
27
- };
28
-
29
21
  const BandReset = (payload, callbacks) => {
30
22
  const resp = callbacks.resetBands(payload.deviceId, payload.value);
31
23
  return new Promise((resolve, reject) => {
@@ -45,6 +37,7 @@ const AdjustBands = (payload, callbacks) => {
45
37
  else reject(new Error('Rest Bands Failed'));
46
38
  });
47
39
  };
40
+
48
41
  module.exports = {
49
- Bands, Mode, BandReset, AdjustBands,
42
+ Bands, BandReset, AdjustBands,
50
43
  };
@@ -0,0 +1,19 @@
1
+ /*
2
+ * Copyright (c) 2019 Sinric. All rights reserved.
3
+ * Licensed under Creative Commons Attribution-Share Alike (CC BY-SA)
4
+ *
5
+ * This file is part of the Sinric Pro (https://github.com/sinricpro/)
6
+ */
7
+
8
+ const ToggleState = (payload, callbacks) => {
9
+ const resp = callbacks.setToggleState(payload.deviceId, payload.value.state, payload.instanceId);
10
+
11
+ return new Promise((resolve, reject) => {
12
+ if (resp) resolve([payload.value, payload.instanceId]);
13
+ else reject(new Error('Toggle State Error'));
14
+ });
15
+ };
16
+
17
+ module.exports = {
18
+ ToggleState
19
+ };
@@ -86,7 +86,9 @@ const raiseEvent = async (client, eventName, deviceId, value) => {
86
86
  if (actionArr.includes(eventName)) {
87
87
  try {
88
88
  await burstyLimiter.consume('queue');
89
- client.send(JSON.stringify(getJson(client, eventName, deviceId, value)));
89
+ const request = JSON.stringify(getJson(client, eventName, deviceId, value));
90
+ if (process.env.SR_DEBUG) console.log('>> %j', request);
91
+ client.send(request);
90
92
  } catch (rlRejected) {
91
93
  console.log('Too many events!');
92
94
  }
package/lib/sinrcpro.js CHANGED
@@ -42,12 +42,14 @@ const startSinricPro = (client, callbacks) => {
42
42
  });
43
43
 
44
44
  client.on("message", (data) => {
45
+ if (process.env.SR_DEBUG) console.log('<< %s', data.toString());
46
+
45
47
  const parsedData = JSON.parse(data);
46
48
 
47
49
  if (parsedData.timestamp) {
48
50
  if (Math.floor(new Date() / 1000) - parsedData.timestamp > 60000) {
49
- console.log("Timestamp is not in sync");
50
- } else console.log("TimeStamp is in sync");
51
+ if (process.env.SR_DEBUG) console.log("Timestamp is not in sync");
52
+ } else if (process.env.SR_DEBUG) console.log("TimeStamp is in sync");
51
53
  } else {
52
54
  const response = callbackHandler(
53
55
  client,
@@ -57,7 +59,9 @@ const startSinricPro = (client, callbacks) => {
57
59
  );
58
60
  response
59
61
  .then((res) => {
60
- client.send(JSON.stringify(res));
62
+ const reqResponse = JSON.stringify(res);
63
+ if (process.env.SR_DEBUG) console.log('>> %s', reqResponse);
64
+ client.send(reqResponse);
61
65
  })
62
66
  .catch((err) => {
63
67
  console.log(err.message);
@@ -74,15 +78,15 @@ const startSinricPro = (client, callbacks) => {
74
78
 
75
79
  const startSinricProObservable = (client, callbacks) => new rx.Observable((observer) => {
76
80
  client.on('open', () => {
77
- console.log('Connected');
81
+ console.log('Connected to Sinric Pro');
78
82
  });
79
83
 
80
84
  client.on("message", (data) => {
81
85
  const parsedData = JSON.parse(data);
82
86
  if (parsedData.timestamp) {
83
87
  if (Math.floor(new Date() / 1000) - parsedData.timestamp > 60000) {
84
- console.log("Timestamp is not in sync");
85
- } else console.log("TimeStamp is in sync");
88
+ if (process.env.SR_DEBUG) console.log("Timestamp is not in sync");
89
+ } else if (process.env.SR_DEBUG) console.log("TimeStamp is in sync");
86
90
  } else {
87
91
  const response = callbackHandler(
88
92
  client,
@@ -93,7 +97,9 @@ const startSinricProObservable = (client, callbacks) => new rx.Observable((obser
93
97
  response
94
98
  .then((res) => {
95
99
  observer.next(res);
96
- client.send(JSON.stringify(res));
100
+ const reqResponse = JSON.stringify(res);
101
+ if (process.env.SR_DEBUG) console.log('>> %s', reqResponse);
102
+ client.send(reqResponse);
97
103
  })
98
104
  .catch((err) => {
99
105
  observer.error(err.message);
@@ -0,0 +1,6 @@
1
+ Switch to Login module (by typing "how-to-npm" on command line)
2
+ Type "npm adduser" to login
3
+ Type "npm whoami" to confirm if logged in
4
+ Switch back to the package at which you are getting error(my case it was Publish Again)
5
+ Type "npm publish"
6
+ Done
package/package.json CHANGED
@@ -1,38 +1,37 @@
1
- {
2
- "name": "sinricpro",
3
- "version": "2.3.1",
4
- "description": "Sinric Pro Nodejs SDK",
5
- "main": "index.js",
6
- "repository": {
7
- "type": "git",
8
- "url": "git+https://github.com/sinricpro/nodejs-sdk.git"
9
- },
10
- "author": "Dhanush",
11
- "license": "ISC",
12
- "bugs": {
13
- "url": "https://github.com/sinricpro/nodejs-sdk/issues"
14
- },
15
- "homepage": "https://github.com/sinricpro/nodejs-sdk#readme",
16
- "dependencies": {
17
- "dgram": "^1.0.1",
18
- "leaky-bucket": "^4.1.4",
19
- "process": "^0.11.10",
20
- "rate-limiter-flexible": "^2.3.6",
21
- "rxjs": "^6.6.3",
22
- "uuid": "^3.3.3",
23
- "ws": "^8.5.0"
24
- },
25
- "keywords": [
26
- "sinricpro",
27
- "sinric"
28
- ],
29
- "devDependencies": {
30
- "eslint": "^6.8.0",
31
- "eslint-config-airbnb-base": "^14.0.0",
32
- "eslint-config-standard": "^14.1.0",
33
- "eslint-plugin-import": "^2.18.2",
34
- "eslint-plugin-node": "^10.0.0",
35
- "eslint-plugin-promise": "^4.2.1",
36
- "eslint-plugin-standard": "^4.0.1"
37
- }
38
- }
1
+ {
2
+ "name": "sinricpro",
3
+ "version": "2.6.1",
4
+ "description": "Sinric Pro Nodejs SDK",
5
+ "main": "index.js",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/sinricpro/nodejs-sdk.git"
9
+ },
10
+ "author": "SinricPro",
11
+ "license": "ISC",
12
+ "bugs": {
13
+ "url": "https://github.com/sinricpro/nodejs-sdk/issues"
14
+ },
15
+ "homepage": "https://github.com/sinricpro/nodejs-sdk#readme",
16
+ "dependencies": {
17
+ "dgram": "^1.0.1",
18
+ "process": "^0.11.10",
19
+ "rate-limiter-flexible": "^2.3.6",
20
+ "rxjs": "^6.6.3",
21
+ "uuid": "^3.3.3",
22
+ "ws": "^8.5.0"
23
+ },
24
+ "keywords": [
25
+ "sinricpro",
26
+ "sinric"
27
+ ],
28
+ "devDependencies": {
29
+ "eslint": "^8.9.0",
30
+ "eslint-config-airbnb-base": "^14.0.0",
31
+ "eslint-config-standard": "^14.1.0",
32
+ "eslint-plugin-import": "^2.18.2",
33
+ "eslint-plugin-node": "^10.0.0",
34
+ "eslint-plugin-promise": "^4.2.1",
35
+ "eslint-plugin-standard": "^4.0.1"
36
+ }
37
+ }