edilkamin 1.7.2 → 1.7.3

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.
@@ -8,7 +8,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { strict as assert } from "assert";
11
- import axios from "axios";
12
11
  import pako from "pako";
13
12
  import sinon from "sinon";
14
13
  import { configure, createAuthService } from "../src/library";
@@ -24,15 +23,20 @@ const createGzippedBuffer = (data) => {
24
23
  data: Array.from(compressed),
25
24
  };
26
25
  };
26
+ /**
27
+ * Helper to create a mock Response object for fetch.
28
+ */
29
+ const mockResponse = (data, status = 200) => ({
30
+ ok: status >= 200 && status < 300,
31
+ status,
32
+ statusText: status >= 200 && status < 300 ? "OK" : "Error",
33
+ json: () => Promise.resolve(data),
34
+ });
27
35
  describe("library", () => {
28
- let axiosStub;
36
+ let fetchStub;
29
37
  const expectedToken = "mockJwtToken";
30
38
  beforeEach(() => {
31
- axiosStub = sinon.stub(axios, "create").returns({
32
- get: sinon.stub(),
33
- put: sinon.stub(),
34
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
- });
39
+ fetchStub = sinon.stub(globalThis, "fetch");
36
40
  });
37
41
  afterEach(() => {
38
42
  sinon.restore();
@@ -182,29 +186,25 @@ describe("library", () => {
182
186
  "getTargetTemperature",
183
187
  "setTargetTemperature",
184
188
  ];
185
- it("should create API methods with the correct baseURL", () => {
186
- const baseURL = "https://example.com/api";
189
+ it("should create API methods with the correct baseURL", () => __awaiter(void 0, void 0, void 0, function* () {
190
+ const baseURL = "https://example.com/api/";
191
+ fetchStub.resolves(mockResponse({ test: "data" }));
187
192
  const api = configure(baseURL);
188
- assert.deepEqual(axiosStub.args, [
189
- [
190
- {
191
- baseURL,
192
- },
193
- ],
194
- ]);
195
193
  assert.deepEqual(Object.keys(api), expectedApi);
196
- });
197
- it("should create API methods with the default baseURL", () => {
194
+ // Verify baseURL is used when making a request
195
+ yield api.deviceInfo(expectedToken, "mockMac");
196
+ assert.ok(fetchStub.calledOnce);
197
+ assert.ok(fetchStub.firstCall.args[0].startsWith(baseURL));
198
+ }));
199
+ it("should create API methods with the default baseURL", () => __awaiter(void 0, void 0, void 0, function* () {
200
+ fetchStub.resolves(mockResponse({ test: "data" }));
198
201
  const api = configure();
199
- assert.deepEqual(axiosStub.args, [
200
- [
201
- {
202
- baseURL: API_URL,
203
- },
204
- ],
205
- ]);
206
202
  assert.deepEqual(Object.keys(api), expectedApi);
207
- });
203
+ // Verify default baseURL is used when making a request
204
+ yield api.deviceInfo(expectedToken, "mockMac");
205
+ assert.ok(fetchStub.calledOnce);
206
+ assert.ok(fetchStub.firstCall.args[0].startsWith(API_URL));
207
+ }));
208
208
  });
209
209
  describe("API Methods", () => {
210
210
  const mockDeviceInfo = {
@@ -222,19 +222,16 @@ describe("library", () => {
222
222
  },
223
223
  },
224
224
  };
225
- it("should call axios for deviceInfo", () => __awaiter(void 0, void 0, void 0, function* () {
226
- const mockAxios = {
227
- get: sinon.stub().resolves({ data: mockDeviceInfo }),
228
- };
229
- axiosStub.returns(mockAxios);
230
- const api = configure("https://example.com/api");
225
+ it("should call fetch for deviceInfo", () => __awaiter(void 0, void 0, void 0, function* () {
226
+ fetchStub.resolves(mockResponse(mockDeviceInfo));
227
+ const api = configure("https://example.com/api/");
231
228
  const result = yield api.deviceInfo(expectedToken, "mockMacAddress");
232
- assert.deepEqual(mockAxios.get.args, [
233
- [
234
- "device/mockMacAddress/info",
235
- { headers: { Authorization: `Bearer ${expectedToken}` } },
236
- ],
237
- ]);
229
+ assert.ok(fetchStub.calledOnce);
230
+ assert.equal(fetchStub.firstCall.args[0], "https://example.com/api/device/mockMacAddress/info");
231
+ assert.deepEqual(fetchStub.firstCall.args[1], {
232
+ method: "GET",
233
+ headers: { Authorization: `Bearer ${expectedToken}` },
234
+ });
238
235
  assert.deepEqual(result, mockDeviceInfo);
239
236
  }));
240
237
  // Tests for setPowerOn and setPowerOff
@@ -250,28 +247,25 @@ describe("library", () => {
250
247
  expectedValue: 0,
251
248
  },
252
249
  ].forEach(({ method, call, expectedValue }) => {
253
- it(`should call axios for ${method}`, () => __awaiter(void 0, void 0, void 0, function* () {
254
- const mockAxios = {
255
- put: sinon.stub().resolves({ status: 200 }),
256
- };
257
- axiosStub.returns(mockAxios);
258
- const api = configure("https://example.com/api");
250
+ it(`should call fetch for ${method}`, () => __awaiter(void 0, void 0, void 0, function* () {
251
+ fetchStub.resolves(mockResponse({ success: true }));
252
+ const api = configure("https://example.com/api/");
259
253
  // Invoke the method using the mapped call function
260
- const result = yield call(api);
261
- assert.deepEqual(mockAxios.put.args, [
262
- [
263
- "mqtt/command",
264
- {
265
- mac_address: "mockMacAddress",
266
- name: "power",
267
- value: expectedValue,
268
- },
269
- {
270
- headers: { Authorization: "Bearer mockToken" },
271
- },
272
- ],
273
- ]);
274
- assert.equal(result.status, 200);
254
+ yield call(api);
255
+ assert.ok(fetchStub.calledOnce);
256
+ assert.equal(fetchStub.firstCall.args[0], "https://example.com/api/mqtt/command");
257
+ assert.deepEqual(fetchStub.firstCall.args[1], {
258
+ method: "PUT",
259
+ headers: {
260
+ "Content-Type": "application/json",
261
+ Authorization: "Bearer mockToken",
262
+ },
263
+ body: JSON.stringify({
264
+ mac_address: "mockMacAddress",
265
+ name: "power",
266
+ value: expectedValue,
267
+ }),
268
+ });
275
269
  }));
276
270
  });
277
271
  const getterTests = [
@@ -292,19 +286,16 @@ describe("library", () => {
292
286
  },
293
287
  ];
294
288
  getterTests.forEach(({ method, call, expectedResult }) => {
295
- it(`should call axios and return the correct value for ${method}`, () => __awaiter(void 0, void 0, void 0, function* () {
296
- const mockAxios = {
297
- get: sinon.stub().resolves({ data: mockDeviceInfo }),
298
- };
299
- axiosStub.returns(mockAxios);
300
- const api = configure("https://example.com/api");
289
+ it(`should call fetch and return the correct value for ${method}`, () => __awaiter(void 0, void 0, void 0, function* () {
290
+ fetchStub.resolves(mockResponse(mockDeviceInfo));
291
+ const api = configure("https://example.com/api/");
301
292
  const result = yield call(api, expectedToken, "mockMacAddress");
302
- assert.deepEqual(mockAxios.get.args, [
303
- [
304
- "device/mockMacAddress/info",
305
- { headers: { Authorization: `Bearer ${expectedToken}` } },
306
- ],
307
- ]);
293
+ assert.ok(fetchStub.calledOnce);
294
+ assert.equal(fetchStub.firstCall.args[0], "https://example.com/api/device/mockMacAddress/info");
295
+ assert.deepEqual(fetchStub.firstCall.args[1], {
296
+ method: "GET",
297
+ headers: { Authorization: `Bearer ${expectedToken}` },
298
+ });
308
299
  assert.equal(result, expectedResult);
309
300
  }));
310
301
  });
@@ -320,119 +311,100 @@ describe("library", () => {
320
311
  },
321
312
  ];
322
313
  setterTests.forEach(({ method, call, payload }) => {
323
- it(`should call axios and send the correct payload for ${method}`, () => __awaiter(void 0, void 0, void 0, function* () {
324
- const mockAxios = {
325
- put: sinon.stub().resolves({ status: 200 }),
326
- };
327
- axiosStub.returns(mockAxios);
328
- const api = configure("https://example.com/api");
329
- const result = yield call(api, expectedToken, "mockMacAddress", payload.value);
330
- assert.deepEqual(mockAxios.put.args, [
331
- [
332
- "mqtt/command",
333
- Object.assign({ mac_address: "mockMacAddress" }, payload),
334
- {
335
- headers: { Authorization: `Bearer ${expectedToken}` },
336
- },
337
- ],
338
- ]);
339
- assert.equal(result.status, 200);
314
+ it(`should call fetch and send the correct payload for ${method}`, () => __awaiter(void 0, void 0, void 0, function* () {
315
+ fetchStub.resolves(mockResponse({ success: true }));
316
+ const api = configure("https://example.com/api/");
317
+ yield call(api, expectedToken, "mockMacAddress", payload.value);
318
+ assert.ok(fetchStub.calledOnce);
319
+ assert.equal(fetchStub.firstCall.args[0], "https://example.com/api/mqtt/command");
320
+ assert.deepEqual(fetchStub.firstCall.args[1], {
321
+ method: "PUT",
322
+ headers: {
323
+ "Content-Type": "application/json",
324
+ Authorization: `Bearer ${expectedToken}`,
325
+ },
326
+ body: JSON.stringify(Object.assign({ mac_address: "mockMacAddress" }, payload)),
327
+ });
340
328
  }));
341
329
  });
342
330
  });
343
331
  describe("registerDevice", () => {
344
332
  it("should call POST /device with correct payload", () => __awaiter(void 0, void 0, void 0, function* () {
345
- const mockResponse = {
333
+ const mockResponseData = {
346
334
  macAddress: "AABBCCDDEEFF",
347
335
  deviceName: "Test Stove",
348
336
  deviceRoom: "Living Room",
349
337
  serialNumber: "EDK123",
350
338
  };
351
- const mockAxios = {
352
- post: sinon.stub().resolves({ data: mockResponse }),
353
- get: sinon.stub(),
354
- put: sinon.stub(),
355
- };
356
- axiosStub.returns(mockAxios);
357
- const api = configure("https://example.com/api");
339
+ fetchStub.resolves(mockResponse(mockResponseData));
340
+ const api = configure("https://example.com/api/");
358
341
  const result = yield api.registerDevice(expectedToken, "AA:BB:CC:DD:EE:FF", "EDK123", "Test Stove", "Living Room");
359
- assert.deepEqual(mockAxios.post.args, [
360
- [
361
- "device",
362
- {
363
- macAddress: "AABBCCDDEEFF",
364
- deviceName: "Test Stove",
365
- deviceRoom: "Living Room",
366
- serialNumber: "EDK123",
367
- },
368
- { headers: { Authorization: `Bearer ${expectedToken}` } },
369
- ],
370
- ]);
371
- assert.deepEqual(result, mockResponse);
342
+ assert.ok(fetchStub.calledOnce);
343
+ assert.equal(fetchStub.firstCall.args[0], "https://example.com/api/device");
344
+ assert.deepEqual(fetchStub.firstCall.args[1], {
345
+ method: "POST",
346
+ headers: {
347
+ "Content-Type": "application/json",
348
+ Authorization: `Bearer ${expectedToken}`,
349
+ },
350
+ body: JSON.stringify({
351
+ macAddress: "AABBCCDDEEFF",
352
+ deviceName: "Test Stove",
353
+ deviceRoom: "Living Room",
354
+ serialNumber: "EDK123",
355
+ }),
356
+ });
357
+ assert.deepEqual(result, mockResponseData);
372
358
  }));
373
359
  it("should normalize MAC address by removing colons", () => __awaiter(void 0, void 0, void 0, function* () {
374
- const mockAxios = {
375
- post: sinon.stub().resolves({ data: {} }),
376
- get: sinon.stub(),
377
- put: sinon.stub(),
378
- };
379
- axiosStub.returns(mockAxios);
380
- const api = configure("https://example.com/api");
360
+ fetchStub.resolves(mockResponse({}));
361
+ const api = configure("https://example.com/api/");
381
362
  yield api.registerDevice(expectedToken, "AA:BB:CC:DD:EE:FF", "EDK123");
382
- assert.equal(mockAxios.post.args[0][1].macAddress, "AABBCCDDEEFF");
363
+ const body = JSON.parse(fetchStub.firstCall.args[1].body);
364
+ assert.equal(body.macAddress, "AABBCCDDEEFF");
383
365
  }));
384
366
  it("should use empty strings as defaults for name and room", () => __awaiter(void 0, void 0, void 0, function* () {
385
- const mockAxios = {
386
- post: sinon.stub().resolves({ data: {} }),
387
- get: sinon.stub(),
388
- put: sinon.stub(),
389
- };
390
- axiosStub.returns(mockAxios);
391
- const api = configure("https://example.com/api");
367
+ fetchStub.resolves(mockResponse({}));
368
+ const api = configure("https://example.com/api/");
392
369
  yield api.registerDevice(expectedToken, "AABBCCDDEEFF", "EDK123");
393
- assert.equal(mockAxios.post.args[0][1].deviceName, "");
394
- assert.equal(mockAxios.post.args[0][1].deviceRoom, "");
370
+ const body = JSON.parse(fetchStub.firstCall.args[1].body);
371
+ assert.equal(body.deviceName, "");
372
+ assert.equal(body.deviceRoom, "");
395
373
  }));
396
374
  });
397
375
  describe("editDevice", () => {
398
376
  it("should call PUT /device/{mac} with correct payload", () => __awaiter(void 0, void 0, void 0, function* () {
399
- const mockResponse = {
377
+ const mockResponseData = {
400
378
  macAddress: "AABBCCDDEEFF",
401
379
  deviceName: "Updated Name",
402
380
  deviceRoom: "Basement",
403
381
  serialNumber: "EDK123",
404
382
  };
405
- const mockAxios = {
406
- put: sinon.stub().resolves({ data: mockResponse }),
407
- get: sinon.stub(),
408
- post: sinon.stub(),
409
- };
410
- axiosStub.returns(mockAxios);
411
- const api = configure("https://example.com/api");
383
+ fetchStub.resolves(mockResponse(mockResponseData));
384
+ const api = configure("https://example.com/api/");
412
385
  const result = yield api.editDevice(expectedToken, "AA:BB:CC:DD:EE:FF", "Updated Name", "Basement");
413
- assert.deepEqual(mockAxios.put.args, [
414
- [
415
- "device/AABBCCDDEEFF",
416
- {
417
- deviceName: "Updated Name",
418
- deviceRoom: "Basement",
419
- },
420
- { headers: { Authorization: `Bearer ${expectedToken}` } },
421
- ],
422
- ]);
423
- assert.deepEqual(result, mockResponse);
386
+ assert.ok(fetchStub.calledOnce);
387
+ assert.equal(fetchStub.firstCall.args[0], "https://example.com/api/device/AABBCCDDEEFF");
388
+ assert.deepEqual(fetchStub.firstCall.args[1], {
389
+ method: "PUT",
390
+ headers: {
391
+ "Content-Type": "application/json",
392
+ Authorization: `Bearer ${expectedToken}`,
393
+ },
394
+ body: JSON.stringify({
395
+ deviceName: "Updated Name",
396
+ deviceRoom: "Basement",
397
+ }),
398
+ });
399
+ assert.deepEqual(result, mockResponseData);
424
400
  }));
425
401
  it("should use empty strings as defaults for name and room", () => __awaiter(void 0, void 0, void 0, function* () {
426
- const mockAxios = {
427
- put: sinon.stub().resolves({ data: {} }),
428
- get: sinon.stub(),
429
- post: sinon.stub(),
430
- };
431
- axiosStub.returns(mockAxios);
432
- const api = configure("https://example.com/api");
402
+ fetchStub.resolves(mockResponse({}));
403
+ const api = configure("https://example.com/api/");
433
404
  yield api.editDevice(expectedToken, "AABBCCDDEEFF");
434
- assert.equal(mockAxios.put.args[0][1].deviceName, "");
435
- assert.equal(mockAxios.put.args[0][1].deviceRoom, "");
405
+ const body = JSON.parse(fetchStub.firstCall.args[1].body);
406
+ assert.equal(body.deviceName, "");
407
+ assert.equal(body.deviceRoom, "");
436
408
  }));
437
409
  });
438
410
  describe("deviceInfo with compressed responses", () => {
@@ -441,7 +413,7 @@ describe("library", () => {
441
413
  commands: { power: true },
442
414
  temperatures: { enviroment: 19, board: 25 },
443
415
  };
444
- const mockResponse = {
416
+ const mockResponseData = {
445
417
  status: createGzippedBuffer(statusData),
446
418
  nvm: {
447
419
  user_parameters: {
@@ -449,11 +421,8 @@ describe("library", () => {
449
421
  },
450
422
  },
451
423
  };
452
- const mockAxios = {
453
- get: sinon.stub().resolves({ data: mockResponse }),
454
- };
455
- axiosStub.returns(mockAxios);
456
- const api = configure("https://example.com/api");
424
+ fetchStub.resolves(mockResponse(mockResponseData));
425
+ const api = configure("https://example.com/api/");
457
426
  const result = yield api.deviceInfo(expectedToken, "mockMacAddress");
458
427
  assert.deepEqual(result.status, statusData);
459
428
  }));
@@ -467,18 +436,15 @@ describe("library", () => {
467
436
  is_sound_active: true,
468
437
  },
469
438
  };
470
- const mockResponse = {
439
+ const mockResponseData = {
471
440
  status: {
472
441
  commands: { power: true },
473
442
  temperatures: { enviroment: 19 },
474
443
  },
475
444
  nvm: createGzippedBuffer(nvmData),
476
445
  };
477
- const mockAxios = {
478
- get: sinon.stub().resolves({ data: mockResponse }),
479
- };
480
- axiosStub.returns(mockAxios);
481
- const api = configure("https://example.com/api");
446
+ fetchStub.resolves(mockResponse(mockResponseData));
447
+ const api = configure("https://example.com/api/");
482
448
  const result = yield api.deviceInfo(expectedToken, "mockMacAddress");
483
449
  assert.deepEqual(result.nvm, nvmData);
484
450
  }));
@@ -496,15 +462,12 @@ describe("library", () => {
496
462
  is_sound_active: false,
497
463
  },
498
464
  };
499
- const mockResponse = {
465
+ const mockResponseData = {
500
466
  status: createGzippedBuffer(statusData),
501
467
  nvm: createGzippedBuffer(nvmData),
502
468
  };
503
- const mockAxios = {
504
- get: sinon.stub().resolves({ data: mockResponse }),
505
- };
506
- axiosStub.returns(mockAxios);
507
- const api = configure("https://example.com/api");
469
+ fetchStub.resolves(mockResponse(mockResponseData));
470
+ const api = configure("https://example.com/api/");
508
471
  const result = yield api.deviceInfo(expectedToken, "mockMacAddress");
509
472
  assert.deepEqual(result.status, statusData);
510
473
  assert.deepEqual(result.nvm, nvmData);
@@ -514,15 +477,12 @@ describe("library", () => {
514
477
  commands: { power: true },
515
478
  temperatures: { enviroment: 19 },
516
479
  };
517
- const mockResponse = {
480
+ const mockResponseData = {
518
481
  status: createGzippedBuffer(statusData),
519
482
  nvm: { user_parameters: { enviroment_1_temperature: 22 } },
520
483
  };
521
- const mockAxios = {
522
- get: sinon.stub().resolves({ data: mockResponse }),
523
- };
524
- axiosStub.returns(mockAxios);
525
- const api = configure("https://example.com/api");
484
+ fetchStub.resolves(mockResponse(mockResponseData));
485
+ const api = configure("https://example.com/api/");
526
486
  const result = yield api.getPower(expectedToken, "mockMacAddress");
527
487
  assert.equal(result, true);
528
488
  }));
@@ -531,15 +491,12 @@ describe("library", () => {
531
491
  commands: { power: true },
532
492
  temperatures: { enviroment: 19, board: 25 },
533
493
  };
534
- const mockResponse = {
494
+ const mockResponseData = {
535
495
  status: createGzippedBuffer(statusData),
536
496
  nvm: { user_parameters: { enviroment_1_temperature: 22 } },
537
497
  };
538
- const mockAxios = {
539
- get: sinon.stub().resolves({ data: mockResponse }),
540
- };
541
- axiosStub.returns(mockAxios);
542
- const api = configure("https://example.com/api");
498
+ fetchStub.resolves(mockResponse(mockResponseData));
499
+ const api = configure("https://example.com/api/");
543
500
  const result = yield api.getEnvironmentTemperature(expectedToken, "mockMacAddress");
544
501
  assert.equal(result, 19);
545
502
  }));
@@ -549,17 +506,37 @@ describe("library", () => {
549
506
  enviroment_1_temperature: 22,
550
507
  },
551
508
  };
552
- const mockResponse = {
509
+ const mockResponseData = {
553
510
  status: { commands: { power: true }, temperatures: { enviroment: 19 } },
554
511
  nvm: createGzippedBuffer(nvmData),
555
512
  };
556
- const mockAxios = {
557
- get: sinon.stub().resolves({ data: mockResponse }),
558
- };
559
- axiosStub.returns(mockAxios);
560
- const api = configure("https://example.com/api");
513
+ fetchStub.resolves(mockResponse(mockResponseData));
514
+ const api = configure("https://example.com/api/");
561
515
  const result = yield api.getTargetTemperature(expectedToken, "mockMacAddress");
562
516
  assert.equal(result, 22);
563
517
  }));
564
518
  });
519
+ describe("Error Handling", () => {
520
+ const errorTests = [
521
+ { status: 400, statusText: "Bad Request" },
522
+ { status: 401, statusText: "Unauthorized" },
523
+ { status: 404, statusText: "Not Found" },
524
+ { status: 500, statusText: "Internal Server Error" },
525
+ ];
526
+ errorTests.forEach(({ status, statusText }) => {
527
+ it(`should throw error when fetch returns ${status}`, () => __awaiter(void 0, void 0, void 0, function* () {
528
+ const errorResponse = {
529
+ ok: false,
530
+ status,
531
+ statusText,
532
+ json: () => Promise.resolve({ error: statusText }),
533
+ };
534
+ fetchStub.resolves(errorResponse);
535
+ const api = configure("https://example.com/api/");
536
+ yield assert.rejects(() => __awaiter(void 0, void 0, void 0, function* () { return api.deviceInfo(expectedToken, "mockMac"); }), {
537
+ message: `HTTP ${status}: ${statusText}`,
538
+ });
539
+ }));
540
+ });
541
+ });
565
542
  });
package/package.json CHANGED
@@ -1,10 +1,22 @@
1
1
  {
2
2
  "name": "edilkamin",
3
- "version": "1.7.2",
3
+ "version": "1.7.3",
4
4
  "description": "",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
7
7
  "types": "dist/esm/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": {
11
+ "types": "./dist/esm/index.d.ts",
12
+ "default": "./dist/esm/index.js"
13
+ },
14
+ "require": {
15
+ "types": "./dist/cjs/index.d.ts",
16
+ "default": "./dist/cjs/index.js"
17
+ }
18
+ }
19
+ },
8
20
  "scripts": {
9
21
  "cli": "ts-node src/cli.ts",
10
22
  "cli:debug": "node --inspect --require ts-node/register/transpile-only src/cli.ts",
@@ -42,7 +54,6 @@
42
54
  },
43
55
  "dependencies": {
44
56
  "aws-amplify": "^6.10.0",
45
- "axios": "^1.13.2",
46
57
  "pako": "^2.1.0"
47
58
  },
48
59
  "devDependencies": {
@@ -54,6 +65,7 @@
54
65
  "@types/sinon": "^17.0.3",
55
66
  "@typescript-eslint/eslint-plugin": "^8.17.0",
56
67
  "@typescript-eslint/parser": "^8.17.0",
68
+ "esbuild": "^0.27.1",
57
69
  "eslint": "^9.16.0",
58
70
  "eslint-config-prettier": "^10.1.8",
59
71
  "eslint-plugin-prettier": "^5.2.1",
@@ -0,0 +1,21 @@
1
+ import { strict as assert } from "assert";
2
+ import * as esbuild from "esbuild";
3
+
4
+ describe("browser-bundle", () => {
5
+ it("should bundle for browser without Node.js built-ins", async () => {
6
+ // This test verifies that the library can be bundled for browser environments
7
+ // without requiring Node.js built-in modules (fs, os, path).
8
+ // If this test fails, it means Node.js-only code has leaked into the main exports.
9
+ const result = await esbuild.build({
10
+ entryPoints: ["dist/esm/index.js"],
11
+ platform: "browser",
12
+ bundle: true,
13
+ write: false,
14
+ // External dependencies that are expected (real deps + assert which is used for validation)
15
+ external: ["aws-amplify", "aws-amplify/*", "pako", "assert"],
16
+ logLevel: "silent",
17
+ });
18
+ // If we get here without error, the bundle succeeded
19
+ assert.ok(result.outputFiles.length > 0, "Bundle should produce output");
20
+ });
21
+ });
@@ -0,0 +1,47 @@
1
+ import { strict as assert } from "assert";
2
+ import sinon from "sinon";
3
+
4
+ import { configureAmplify } from "../src/library";
5
+
6
+ /**
7
+ * This test file specifically tests the configureAmplify function with custom storage.
8
+ * It tests line 61 in library.ts:
9
+ * cognitoUserPoolsTokenProvider.setKeyValueStorage(storage)
10
+ *
11
+ * IMPORTANT: This file is named to run BEFORE library.test.ts (alphabetically)
12
+ * to ensure amplifyConfigured is still false when these tests run.
13
+ */
14
+
15
+ describe("configureAmplify", () => {
16
+ it("should configure Amplify with custom storage", () => {
17
+ const mockStorage = {
18
+ setItem: sinon.stub().resolves(),
19
+ getItem: sinon.stub().resolves(null),
20
+ removeItem: sinon.stub().resolves(),
21
+ clear: sinon.stub().resolves(),
22
+ };
23
+
24
+ // Call configureAmplify with custom storage
25
+ // This is the first call in the test suite, so amplifyConfigured is false
26
+ // This should trigger line 61 in library.ts
27
+ configureAmplify(mockStorage);
28
+
29
+ // The test passes if no error is thrown
30
+ // Coverage confirms line 61 is executed
31
+ assert.ok(true, "configureAmplify with storage completed without error");
32
+ });
33
+
34
+ it("should only configure Amplify once (idempotent)", () => {
35
+ // Call configureAmplify multiple times without storage
36
+ configureAmplify();
37
+ configureAmplify();
38
+ configureAmplify();
39
+
40
+ // Should not throw or have any side effects
41
+ // The function returns early if already configured (line 58)
42
+ assert.ok(
43
+ true,
44
+ "Multiple calls to configureAmplify completed without error",
45
+ );
46
+ });
47
+ });
package/src/index.ts CHANGED
@@ -8,7 +8,6 @@ export {
8
8
  serialNumberFromHex,
9
9
  serialNumberToHex,
10
10
  } from "./serial-utils";
11
- export { clearSession } from "./token-storage";
12
11
  export {
13
12
  BufferEncodedType,
14
13
  CommandsType,