particle-api-js 11.1.7 → 12.0.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.
Files changed (85) hide show
  1. package/README.md +90 -10
  2. package/dist/particle.min.js +1 -1
  3. package/dist/particle.min.js.map +1 -1
  4. package/fs.d.ts +2 -0
  5. package/lib/fs.d.ts +2 -0
  6. package/lib/fs.js +3 -0
  7. package/lib/package.json +110 -0
  8. package/lib/src/Agent.d.ts +40 -0
  9. package/lib/src/Agent.d.ts.map +1 -0
  10. package/lib/src/Agent.js +233 -0
  11. package/lib/src/Agent.js.map +1 -0
  12. package/lib/src/Client.d.ts +80 -0
  13. package/lib/src/Client.d.ts.map +1 -0
  14. package/lib/src/Client.js +104 -0
  15. package/lib/src/Client.js.map +1 -0
  16. package/lib/src/Defaults.d.ts +6 -0
  17. package/lib/src/Defaults.d.ts.map +1 -0
  18. package/lib/src/Defaults.js +12 -0
  19. package/lib/src/Defaults.js.map +1 -0
  20. package/lib/src/EventStream.d.ts +31 -0
  21. package/lib/src/EventStream.d.ts.map +1 -0
  22. package/lib/src/EventStream.js +275 -0
  23. package/lib/src/EventStream.js.map +1 -0
  24. package/lib/src/Library.d.ts +33 -0
  25. package/lib/src/Library.d.ts.map +1 -0
  26. package/lib/src/Library.js +19 -0
  27. package/lib/src/Library.js.map +1 -0
  28. package/{src/Particle.js → lib/src/Particle.d.ts} +623 -1779
  29. package/lib/src/Particle.d.ts.map +1 -0
  30. package/lib/src/Particle.js +2578 -0
  31. package/lib/src/Particle.js.map +1 -0
  32. package/lib/src/types/common.d.ts +73 -0
  33. package/lib/src/types/common.d.ts.map +1 -0
  34. package/lib/src/types/common.js +3 -0
  35. package/lib/src/types/common.js.map +1 -0
  36. package/lib/src/types/index.d.ts +4 -0
  37. package/lib/src/types/index.d.ts.map +1 -0
  38. package/lib/src/types/index.js +20 -0
  39. package/lib/src/types/index.js.map +1 -0
  40. package/lib/src/types/requests.d.ts +568 -0
  41. package/lib/src/types/requests.d.ts.map +1 -0
  42. package/lib/src/types/requests.js +3 -0
  43. package/lib/src/types/requests.js.map +1 -0
  44. package/lib/src/types/responses.d.ts +449 -0
  45. package/lib/src/types/responses.d.ts.map +1 -0
  46. package/lib/src/types/responses.js +3 -0
  47. package/lib/src/types/responses.js.map +1 -0
  48. package/package.json +35 -14
  49. package/scripts/postprocess-docs.js +306 -0
  50. package/typedoc.json +20 -0
  51. package/.circleci/config.yml +0 -104
  52. package/.nvmrc +0 -1
  53. package/CHANGELOG.md +0 -404
  54. package/EventStream-e2e-browser.html +0 -39
  55. package/EventStream-e2e-node.js +0 -34
  56. package/RELEASE.md +0 -12
  57. package/bower.json +0 -30
  58. package/docs/api.md +0 -2594
  59. package/eslint.config.mjs +0 -7
  60. package/examples/login/login.html +0 -17
  61. package/karma.conf.js +0 -80
  62. package/src/Agent.js +0 -397
  63. package/src/Client.js +0 -171
  64. package/src/Defaults.js +0 -8
  65. package/src/EventStream.js +0 -269
  66. package/src/Library.js +0 -33
  67. package/test/Agent.integration.js +0 -23
  68. package/test/Agent.spec.js +0 -488
  69. package/test/Client.spec.js +0 -216
  70. package/test/Defaults.spec.js +0 -30
  71. package/test/EventStream.feature +0 -65
  72. package/test/EventStream.spec.js +0 -263
  73. package/test/FakeAgent.js +0 -27
  74. package/test/Library.spec.js +0 -40
  75. package/test/Particle.integration.js +0 -38
  76. package/test/Particle.spec.js +0 -3198
  77. package/test/fixtures/index.js +0 -15
  78. package/test/fixtures/libraries.json +0 -33
  79. package/test/fixtures/library.json +0 -31
  80. package/test/fixtures/libraryVersions.json +0 -211
  81. package/test/out.tmp +0 -0
  82. package/test/support/FixtureHttpServer.js +0 -28
  83. package/test/test-setup.js +0 -17
  84. package/tsconfig.json +0 -17
  85. package/webpack.config.js +0 -46
@@ -1,30 +0,0 @@
1
- 'use strict';
2
- const { expect } = require('./test-setup');
3
- const Defaults = require('../src/Defaults');
4
-
5
- describe('Default Particle constructor options', () => {
6
- it('includes baseUrl', () => {
7
- expect(Defaults).to.have.property('baseUrl');
8
- expect(Defaults.baseUrl).to.eql('https://api.particle.io');
9
- });
10
-
11
- it('includes clientSecret', () => {
12
- expect(Defaults).to.have.property('clientSecret');
13
- expect(Defaults.clientSecret).to.eql('particle-api');
14
- });
15
-
16
- it('includes clientId', () => {
17
- expect(Defaults).to.have.property('clientId');
18
- expect(Defaults.clientId).to.eql('particle-api');
19
- });
20
-
21
- it('includes tokenDuration', () => {
22
- expect(Defaults).to.have.property('tokenDuration');
23
- expect(Defaults.tokenDuration).to.eql(7776000);
24
- });
25
-
26
- it('includes defaultAuth', () => {
27
- expect(Defaults).to.have.property('auth');
28
- expect(Defaults.auth).to.eql(undefined);
29
- });
30
- });
@@ -1,65 +0,0 @@
1
- # End-to-end tests for the EventStream feature
2
- # These tests are hard to automate, especially in the browser since they involve error handling with the API
3
- # so the tests are documented in Gerkin format and are meant to be executed manually
4
- Feature: EventStream
5
-
6
- Scenario: Connect to event stream
7
- Given the API is running
8
- And the API access token is valid
9
- When I run the end-to-end test program
10
- Then the output should contain "event stream connected"
11
-
12
- Scenario: Receive event
13
- Given the event stream is connected
14
- When I publish a Particle event through the CLI with `particle publish test`
15
- Then the event "event" with data "{ name: 'test', ... }" should be output
16
-
17
- Scenario: Initial connection failure
18
- Given the API is not running
19
- When I run the end-to-end test program
20
- Then the output should contain "Error: connect ECONNREFUSED"
21
- And the end-to-end test program should exit
22
-
23
- Scenario: Invalid credentials
24
- Given the API is running
25
- And the API access token is not valid
26
- When I run the end-to-end test program
27
- Then the output should contain "The access token provided is invalid"
28
- And the end-to-end test program should exit
29
-
30
- Scenario: Initial connection timeout
31
- Given the API is paused (press Ctrl-Z in the API terminal)
32
- When I run the end-to-end test program
33
- Then the output should contain "Timeout"
34
- And the end-to-end test program should exit
35
-
36
- Scenario: Disconnect due to connection failure
37
- Given the event stream is connected
38
- When I stop the API (press Ctrl-C in the API terminal)
39
- Then the event "disconnect" should be output immediately
40
- And after 2 seconds, the event "reconnect" should be output
41
- And the event "reconnect-error" should be output immediately
42
- And the "reconnect" and "reconnect-error" should repeat indefinitely
43
-
44
- Scenario: Reconnect after connection failure
45
- Given the event stream is trying to reconnect after connection failure
46
- When I start the API
47
- Then the event "reconnect" followed by "reconnect-success" should be output
48
-
49
- Scenario: Disconnect due to idle timeout
50
- Given the event stream is connected
51
- When I pause the API (press Ctrl-Z in the API terminal)
52
- Then after up to 13 seconds, the event "disconnect" should be output
53
- And after 2 seconds, the event "reconnect" should be output
54
- And after 13 seconds, the event "reconnect-error" should be output
55
- And the "reconnect" and "reconnect-error" should repeat indefinitely
56
-
57
- Scenario: Reconnect after idle timeout
58
- Given the event stream is trying to reconnect after idle timeout
59
- When I unpause the API (type % in bash to resume the process)
60
- Then the event "reconnect-success" should be output
61
-
62
- Scenario: Receive event after reconnect
63
- Given the event stream reconnected after a connection failure
64
- When I publish a Particle event through the CLI with `particle publish test`
65
- Then the event "event" should be published once
@@ -1,263 +0,0 @@
1
- 'use strict';
2
- const { sinon, expect } = require('./test-setup');
3
- const http = require('http');
4
- const { EventEmitter } = require('events');
5
-
6
- const EventStream = require('../src/EventStream');
7
-
8
- describe('EventStream', () => {
9
- afterEach(() => {
10
- sinon.restore();
11
- });
12
-
13
- function makeRequest() {
14
- const fakeRequest = new EventEmitter();
15
- fakeRequest.end = sinon.spy();
16
- fakeRequest.setTimeout = sinon.spy();
17
- return fakeRequest;
18
- }
19
-
20
- function makeResponse(statusCode) {
21
- const fakeResponse = new EventEmitter();
22
- fakeResponse.statusCode = statusCode;
23
- return fakeResponse;
24
- }
25
-
26
- describe('constructor', () => {
27
- it('creates an EventStream objects', () => {
28
- const eventStream = new EventStream('uri', 'token');
29
-
30
- expect(eventStream).to.own.include({ uri: 'uri', token: 'token' });
31
- });
32
- });
33
-
34
- describe('connect', () => {
35
- it('successfully connects to http', () => {
36
- sinon.useFakeTimers({ shouldAdvanceTime: true });
37
- const fakeRequest = makeRequest();
38
- sinon.stub(http, 'request').callsFake(() => {
39
- setImmediate(() => {
40
- const fakeResponse = makeResponse(200);
41
- fakeRequest.emit('response', fakeResponse);
42
- });
43
-
44
- return fakeRequest;
45
- });
46
-
47
- const eventStream = new EventStream('http://hostname:8080/path', 'token');
48
-
49
- return eventStream.connect().then(() => {
50
- expect(http.request).to.have.been.calledWith({
51
- hostname: 'hostname',
52
- protocol: 'http:',
53
- path: '/path?nonce=0',
54
- headers: {
55
- 'Authorization': 'Bearer token'
56
- },
57
- method: 'get',
58
- port: 8080,
59
- mode: 'prefer-streaming'
60
- });
61
- });
62
- });
63
-
64
- it('returns http errors on connect', () => {
65
- sinon.useFakeTimers({ shouldAdvanceTime: true });
66
- const fakeRequest = makeRequest();
67
- sinon.stub(http, 'request').callsFake(() => {
68
- setImmediate(() => {
69
- const fakeResponse = makeResponse(500);
70
- fakeRequest.emit('response', fakeResponse);
71
- setImmediate(() => {
72
- fakeResponse.emit('data', '{"error":"unknown"}');
73
- fakeResponse.emit('end');
74
- });
75
- });
76
-
77
- return fakeRequest;
78
- });
79
-
80
- const eventStream = new EventStream('http://hostname:8080/path', 'token');
81
-
82
- return eventStream.connect().then(() => {
83
- throw new Error('expected to throw error');
84
- }, (reason) => {
85
- expect(reason).to.eql({
86
- statusCode: 500,
87
- errorDescription: 'HTTP error 500 from http://hostname:8080/path',
88
- body: {
89
- error: 'unknown'
90
- }
91
- });
92
- });
93
- });
94
- });
95
-
96
- describe('parse', () => {
97
- let eventStream;
98
- beforeEach(() => {
99
- eventStream = new EventStream();
100
- sinon.stub(eventStream, 'parseEventStreamLine');
101
- });
102
-
103
- it('accumulates date into the buffer before parsing line', () => {
104
- eventStream.parse('wo');
105
- eventStream.parse('rd');
106
-
107
- expect(eventStream.buf).to.eql('word');
108
- expect(eventStream.parseEventStreamLine).not.to.have.been.called;
109
- });
110
-
111
- it('parses a line ending with \\n', () => {
112
- const line = 'field: value\n';
113
-
114
- eventStream.parse(line);
115
-
116
- expect(eventStream.parseEventStreamLine).to.have.been.calledWith(0, line.indexOf(':'), line.indexOf('\n'));
117
- });
118
-
119
- it('parses 2 lines ending with \\n', () => {
120
- const line1 = 'field: value\n';
121
- const line2 = 'field2: value2\n';
122
-
123
- eventStream.parse(line1 + line2);
124
-
125
- expect(eventStream.parseEventStreamLine).to.have.been.calledWith(0, line1.indexOf(':'), line1.indexOf('\n'));
126
- expect(eventStream.parseEventStreamLine).to.have.been.calledWith(line1.length, line2.indexOf(':'), line2.indexOf('\n'));
127
- });
128
-
129
-
130
- it('parses a line ending with \\r\\n', () => {
131
- const line = 'field: value\r\n';
132
-
133
- eventStream.parse(line);
134
-
135
- expect(eventStream.parseEventStreamLine).to.have.been.calledWith(0, line.indexOf(':'), line.indexOf('\r'));
136
- });
137
-
138
- it('parses 2 lines ending with \\r\\n', () => {
139
- const line1 = 'field: value\r\n';
140
- const line2 = 'field2: value2\r\n';
141
-
142
- eventStream.parse(line1 + line2);
143
-
144
- expect(eventStream.parseEventStreamLine).to.have.been.calledWith(0, line1.indexOf(':'), line1.indexOf('\r'));
145
- expect(eventStream.parseEventStreamLine).to.have.been.calledWith(line1.length, line2.indexOf(':'), line2.indexOf('\r'));
146
- });
147
-
148
- it('clears buffer after parsing full lines', () => {
149
- eventStream.parse('field: value\n');
150
-
151
- expect(eventStream.buf).to.eql('');
152
- });
153
-
154
- it('keeps partial lines in buffer after parsing full lines', () => {
155
- eventStream.parse('field: value\nfield2');
156
-
157
- expect(eventStream.buf).to.eql('field2');
158
- });
159
- });
160
-
161
- describe('parseEventStreamLine', () => {
162
- let eventStream;
163
- beforeEach(() => {
164
- eventStream = new EventStream();
165
- });
166
-
167
- it('ignores comments', () => {
168
- // comments starts with : at column 0
169
- const line = ':ok\n';
170
- eventStream.buf = line;
171
-
172
- eventStream.parseEventStreamLine(0, line.indexOf(':'), line.indexOf('\n'));
173
-
174
- expect(eventStream.event).not.to.be.ok;
175
- expect(eventStream.data).to.be.eql('');
176
- });
177
-
178
- it('saves event name', () => {
179
- const line = 'event: testevent\n';
180
- eventStream.buf = line;
181
-
182
- eventStream.parseEventStreamLine(0, line.indexOf(':'), line.indexOf('\n'));
183
-
184
- expect(eventStream.event).to.be.true;
185
- expect(eventStream.eventName).to.eql('testevent');
186
- });
187
-
188
- it('saves event data', () => {
189
- const line = 'data: {"data":"test"}\n';
190
- eventStream.buf = line;
191
-
192
- eventStream.parseEventStreamLine(0, line.indexOf(':'), line.indexOf('\n'));
193
-
194
- expect(eventStream.data).to.eql('{"data":"test"}\n');
195
- });
196
-
197
- it('saves event name and data on separate lines', () => {
198
- const lines = ['event: testevent\n', 'data: {"data":"test"}\n'];
199
- for (const line of lines) {
200
- eventStream.buf = line;
201
-
202
- eventStream.parseEventStreamLine(0, line.indexOf(':'), line.indexOf('\n'));
203
- }
204
-
205
- expect(eventStream.event).to.be.true;
206
- expect(eventStream.eventName).to.eql('testevent');
207
- expect(eventStream.data).to.eql('{"data":"test"}\n');
208
- });
209
-
210
- it('emits event on blank line after saving event name and data', () => {
211
- const handler = sinon.spy();
212
- eventStream.event = true;
213
- eventStream.eventName = 'testevent';
214
- eventStream.data = '{"data":"test"}\n';
215
- eventStream.on('event', handler);
216
-
217
- eventStream.parseEventStreamLine(0, -1, 0);
218
-
219
- expect(handler).to.have.been.calledWith({
220
- name: 'testevent',
221
- data: 'test'
222
- });
223
- });
224
-
225
- it('emits error if the event handler crashes', () => {
226
- const errorHandler = sinon.spy();
227
- eventStream.event = true;
228
- eventStream.eventName = 'testevent';
229
- eventStream.data = '{"data":"test"}\n';
230
- eventStream.on('error', errorHandler);
231
- eventStream.on('event', () => {
232
- throw new Error('failed!');
233
- });
234
-
235
- eventStream.parseEventStreamLine(0, -1, 0);
236
-
237
- expect(errorHandler).to.have.been.called;
238
- });
239
-
240
- it('clears the event after emitting it', () => {
241
- eventStream.event = true;
242
- eventStream.eventName = 'testevent';
243
- eventStream.data = '{"data":"test"}\n';
244
-
245
- eventStream.parseEventStreamLine(0, -1, 0);
246
-
247
- expect(eventStream.event).to.be.false;
248
- expect(eventStream.eventName).to.be.undefined;
249
- expect(eventStream.data).to.eql('');
250
- });
251
-
252
- it('ignores multiple blank lines in succession', () => {
253
- const handler = sinon.spy();
254
- eventStream.on('event', handler);
255
-
256
- eventStream.parseEventStreamLine(0, -1, 0);
257
- eventStream.parseEventStreamLine(0, -1, 0);
258
- eventStream.parseEventStreamLine(0, -1, 0);
259
-
260
- expect(handler).not.to.have.been.called;
261
- });
262
- });
263
- });
package/test/FakeAgent.js DELETED
@@ -1,27 +0,0 @@
1
- 'use strict';
2
- class FakeAgent {
3
- get({ uri, auth, headers, query, context }){
4
- return this.request({ uri, method: 'get', auth, headers, query, context });
5
- }
6
-
7
- head({ uri, auth, headers, query, context }){
8
- return this.request({ uri, method: 'head', auth, headers, query, context });
9
- }
10
-
11
- post({ uri, headers, data, auth, context }){
12
- return this.request({ uri, method: 'post', auth, headers, data, context });
13
- }
14
-
15
- put({ uri, auth, headers, data, query, context }){
16
- return this.request({ uri, method: 'put', auth, headers, data, query, context });
17
- }
18
-
19
- delete({ uri, auth, headers, data, context }){
20
- return this.request({ uri, method: 'delete', auth, headers, data, context });
21
- }
22
-
23
- request(opts){
24
- return Promise.resolve(opts);
25
- }
26
- }
27
- module.exports = FakeAgent;
@@ -1,40 +0,0 @@
1
- 'use strict';
2
- const { expect } = require('./test-setup');
3
- const Library = require('../src/Library');
4
-
5
- const client = {};
6
-
7
-
8
- describe('Library', () => {
9
- describe('constructor', () => {
10
- it('sets attributes', () => {
11
- const library = new Library(client, {
12
- attributes: {
13
- name: 'testlib',
14
- version: '1.0.0'
15
- }
16
- });
17
- expect(library.name).to.equal('testlib');
18
- expect(library.version).to.equal('1.0.0');
19
- });
20
- });
21
-
22
- describe('download', () => {
23
- it('return the file contents', () => {
24
- client.downloadFile = (url) => {
25
- return Promise.resolve(`${url}-content`);
26
- };
27
-
28
- const library = new Library(client, {
29
- attributes: {
30
- name: 'testlib',
31
- version: '1.0.0'
32
- },
33
- links: {
34
- download: 'url'
35
- }
36
- });
37
- expect(library.download()).to.eventually.equal('url-content');
38
- });
39
- });
40
- });
@@ -1,38 +0,0 @@
1
- 'use strict';
2
- const { expect, sinon } = require('./test-setup');
3
- const Particle = require('../src/Particle');
4
-
5
- describe('Particle', () => {
6
- let api;
7
-
8
- beforeEach(() => {
9
- api = new Particle({ baseUrl: '' });
10
- });
11
-
12
- describe('downloadFile', () => {
13
- it('download the file', () => {
14
- const uri = 'https://binaries.particle.io/libraries/neopixel/neopixel-0.0.10.tar.gz';
15
- const fileSize = 25505;
16
- return api.downloadFile({ uri })
17
- .then(contents => {
18
- expect(contents.length || contents.byteLength).to.equal(fileSize);
19
- });
20
- });
21
- });
22
-
23
- describe('context', () => {
24
- it('adds headers for the context', () => {
25
- api.setContext('tool', { name:'cli', version:'1.2.3' });
26
- api.setContext('project', { name:'blinky', version:'0.0.1' });
27
- api.agent._promiseResponse = sinon.stub().resolves();
28
- return api.flashTinker('deviceID', 'auth').then(() => {
29
- expect(api.agent._promiseResponse).to.have.been.calledOnce;
30
- const req = api.agent._promiseResponse.firstCall.args[0];
31
- const options = req[1];
32
- expect(req).to.be.ok;
33
- expect(options.headers).to.have.property('X-Particle-Tool').eql('cli@1.2.3');
34
- expect(options.headers).to.have.property('X-Particle-Project').eql('blinky; version=0.0.1');
35
- });
36
- });
37
- });
38
- });