signal-sdk 0.1.1 → 0.1.2

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/README.md CHANGED
@@ -14,7 +14,7 @@
14
14
 
15
15
  [![npm version](https://badge.fury.io/js/signal-sdk.svg)](https://badge.fury.io/js/signal-sdk)
16
16
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
17
- [![signal-cli](https://img.shields.io/badge/signal--cli-v0.13.22-blue.svg)](https://github.com/AsamK/signal-cli)
17
+ [![signal-cli](https://img.shields.io/badge/signal--cli-v0.13.23-blue.svg)](https://github.com/AsamK/signal-cli)
18
18
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.8+-blue.svg)](https://www.typescriptlang.org/)
19
19
  [![Node.js](https://img.shields.io/badge/Node.js-18+-green.svg)](https://nodejs.org/)
20
20
  [![Tests](https://img.shields.io/badge/tests-310%20passing-brightgreen.svg)](./src/__tests__)
@@ -364,7 +364,7 @@ await bot.start();
364
364
  - **TypeScript**: 5.8+ with strict mode
365
365
  - **Test Coverage**: 225 passing tests across 9 suites
366
366
  - **Code Coverage**: 57.52% overall, critical modules at 96-100%
367
- - **signal-cli**: Compatible with v0.13.22
367
+ - **signal-cli**: Compatible with v0.13.23
368
368
 
369
369
  ## Testing
370
370
 
@@ -570,7 +570,7 @@ This project is licensed under the MIT License - see the [LICENSE](./LICENSE) fi
570
570
 
571
571
  ## API Methods
572
572
 
573
- Compatible with signal-cli v0.13.22 - **100% Feature Coverage**
573
+ Compatible with signal-cli v0.13.23 - **100% Feature Coverage**
574
574
 
575
575
  | Category | Method | Description | Status |
576
576
  | --------------- | -------------------------- | ---------------------------------- | ------ |
@@ -595,6 +595,8 @@ Compatible with signal-cli v0.13.22 - **100% Feature Coverage**
595
595
  | | `getUserStatus` | Check registration status | ✅ |
596
596
  | **Account** | `updateAccount` | Update account settings | ✅ |
597
597
  | | `listAccountsDetailed` | List accounts with detailed info | ✅ |
598
+ | **Devices** | `listDevices` | List linked devices | ✅ |
599
+ | | `updateDevice` | Update device name (v0.13.23+) | ✅ |
598
600
  | **Attachments** | `getAttachment` | Retrieve attachment by ID | ✅ |
599
601
  | | `getAvatar` | Retrieve avatar by ID | ✅ |
600
602
  | | `getSticker` | Retrieve sticker by ID | ✅ |
@@ -1,4 +1,4 @@
1
- import { Message, Contact, GroupUpdateOptions, SendMessageOptions, ContactUpdateOptions, AccountConfiguration, Device, ReceiptType, StickerPack, IdentityKey, LinkingOptions, LinkingResult, MessageRequestResponseType, SendResponse, GroupInfo, RemoveContactOptions, UserStatusResult, PaymentNotificationData, StickerPackManifest, StickerPackUploadResult, RateLimitChallengeResult, ReceiveOptions, UploadProgress, PollCreateOptions, PollVoteOptions, PollTerminateOptions, GetAttachmentOptions, GetAvatarOptions, GetStickerOptions, UpdateAccountOptions, AccountUpdateResult, SendContactsOptions, ListGroupsOptions } from './interfaces';
1
+ import { Message, Contact, GroupUpdateOptions, SendMessageOptions, ContactUpdateOptions, AccountConfiguration, Device, ReceiptType, StickerPack, IdentityKey, LinkingOptions, LinkingResult, MessageRequestResponseType, SendResponse, GroupInfo, RemoveContactOptions, UserStatusResult, PaymentNotificationData, StickerPackManifest, StickerPackUploadResult, RateLimitChallengeResult, ReceiveOptions, UploadProgress, PollCreateOptions, PollVoteOptions, PollTerminateOptions, GetAttachmentOptions, GetAvatarOptions, GetStickerOptions, UpdateAccountOptions, AccountUpdateResult, SendContactsOptions, ListGroupsOptions, UpdateDeviceOptions } from './interfaces';
2
2
  import { EventEmitter } from 'events';
3
3
  import { SignalCliConfig } from './config';
4
4
  export declare class SignalCli extends EventEmitter {
@@ -158,6 +158,26 @@ export declare class SignalCli extends EventEmitter {
158
158
  resetGroupLink(groupId: string): Promise<void>;
159
159
  listContacts(): Promise<Contact[]>;
160
160
  listDevices(): Promise<Device[]>;
161
+ /**
162
+ * Update a linked device name (signal-cli v0.13.23+).
163
+ * Allows changing the display name of a linked device.
164
+ *
165
+ * @param options - Device update options
166
+ * @returns Promise that resolves when device is updated
167
+ *
168
+ * @example
169
+ * ```typescript
170
+ * // List devices to get device IDs
171
+ * const devices = await signal.listDevices();
172
+ *
173
+ * // Update device name
174
+ * await signal.updateDevice({
175
+ * deviceId: 2,
176
+ * deviceName: 'My New Device Name'
177
+ * });
178
+ * ```
179
+ */
180
+ updateDevice(options: UpdateDeviceOptions): Promise<void>;
161
181
  listAccounts(): Promise<string[]>;
162
182
  /**
163
183
  * @deprecated Use `connect` and listen for `message` events instead.
package/dist/SignalCli.js CHANGED
@@ -876,6 +876,35 @@ class SignalCli extends events_1.EventEmitter {
876
876
  async listDevices() {
877
877
  return this.sendJsonRpcRequest('listDevices', { account: this.account });
878
878
  }
879
+ /**
880
+ * Update a linked device name (signal-cli v0.13.23+).
881
+ * Allows changing the display name of a linked device.
882
+ *
883
+ * @param options - Device update options
884
+ * @returns Promise that resolves when device is updated
885
+ *
886
+ * @example
887
+ * ```typescript
888
+ * // List devices to get device IDs
889
+ * const devices = await signal.listDevices();
890
+ *
891
+ * // Update device name
892
+ * await signal.updateDevice({
893
+ * deviceId: 2,
894
+ * deviceName: 'My New Device Name'
895
+ * });
896
+ * ```
897
+ */
898
+ async updateDevice(options) {
899
+ this.logger.debug('Updating device', options);
900
+ (0, validators_1.validateDeviceId)(options.deviceId);
901
+ (0, validators_1.validateMessage)(options.deviceName, 200);
902
+ await this.sendJsonRpcRequest('updateDevice', {
903
+ deviceId: options.deviceId,
904
+ deviceName: options.deviceName,
905
+ account: this.account
906
+ });
907
+ }
879
908
  async listAccounts() {
880
909
  const result = await this.sendJsonRpcRequest('listAccounts');
881
910
  return result.accounts.map((acc) => acc.number);
@@ -401,6 +401,90 @@ describe('SignalCli Methods Tests', () => {
401
401
  }));
402
402
  });
403
403
  });
404
+ describe('Update Account Methods', () => {
405
+ it('should update account with device name', async () => {
406
+ sendJsonRpcRequestSpy.mockResolvedValue({ username: 'user.123' });
407
+ const result = await signalCli.updateAccount({ deviceName: 'New Device' });
408
+ expect(result.success).toBe(true);
409
+ expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('updateAccount', expect.objectContaining({
410
+ deviceName: 'New Device'
411
+ }));
412
+ });
413
+ it('should update account with username', async () => {
414
+ sendJsonRpcRequestSpy.mockResolvedValue({ username: 'newuser.456', usernameLink: 'link' });
415
+ const result = await signalCli.updateAccount({ username: 'newuser.456' });
416
+ expect(result.success).toBe(true);
417
+ expect(result.username).toBe('newuser.456');
418
+ });
419
+ it('should delete username', async () => {
420
+ sendJsonRpcRequestSpy.mockResolvedValue({});
421
+ await signalCli.updateAccount({ deleteUsername: true });
422
+ expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('updateAccount', expect.objectContaining({
423
+ deleteUsername: true
424
+ }));
425
+ });
426
+ it('should update privacy settings', async () => {
427
+ sendJsonRpcRequestSpy.mockResolvedValue({});
428
+ await signalCli.updateAccount({
429
+ unrestrictedUnidentifiedSender: true,
430
+ discoverableByNumber: false,
431
+ numberSharing: false
432
+ });
433
+ expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('updateAccount', expect.objectContaining({
434
+ unrestrictedUnidentifiedSender: true,
435
+ discoverableByNumber: false,
436
+ numberSharing: false
437
+ }));
438
+ });
439
+ it('should handle update account error', async () => {
440
+ sendJsonRpcRequestSpy.mockRejectedValue(new Error('Update failed'));
441
+ const result = await signalCli.updateAccount({ deviceName: 'Device' });
442
+ expect(result.success).toBe(false);
443
+ });
444
+ });
445
+ describe('Device Management Methods (v0.13.23+)', () => {
446
+ it('should list devices', async () => {
447
+ const mockDevices = [
448
+ { id: 1, name: 'Primary', lastSeen: Date.now() },
449
+ { id: 2, name: 'Tablet', lastSeen: Date.now() }
450
+ ];
451
+ sendJsonRpcRequestSpy.mockResolvedValue(mockDevices);
452
+ const result = await signalCli.listDevices();
453
+ expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('listDevices', {
454
+ account: '+1234567890'
455
+ });
456
+ expect(result).toEqual(mockDevices);
457
+ });
458
+ it('should update device name', async () => {
459
+ sendJsonRpcRequestSpy.mockResolvedValue(undefined);
460
+ await signalCli.updateDevice({
461
+ deviceId: 3,
462
+ deviceName: 'My Laptop'
463
+ });
464
+ expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('updateDevice', {
465
+ account: '+1234567890',
466
+ deviceId: 3,
467
+ deviceName: 'My Laptop'
468
+ });
469
+ });
470
+ it('should validate device ID', async () => {
471
+ await expect(signalCli.updateDevice({
472
+ deviceId: 0,
473
+ deviceName: 'Invalid'
474
+ })).rejects.toThrow();
475
+ await expect(signalCli.updateDevice({
476
+ deviceId: -5,
477
+ deviceName: 'Invalid'
478
+ })).rejects.toThrow();
479
+ });
480
+ it('should validate device name is not too long', async () => {
481
+ const longName = 'x'.repeat(300);
482
+ await expect(signalCli.updateDevice({
483
+ deviceId: 2,
484
+ deviceName: longName
485
+ })).rejects.toThrow();
486
+ });
487
+ });
404
488
  describe('Update Account Methods', () => {
405
489
  it('should update account with device name', async () => {
406
490
  sendJsonRpcRequestSpy.mockResolvedValue({ username: 'user.123' });
@@ -407,6 +407,51 @@ describe('SignalCli', () => {
407
407
  expect(result).toEqual(mockResponse.accounts);
408
408
  });
409
409
  });
410
+ // Test device management (v0.13.23+)
411
+ describe('Device Management', () => {
412
+ beforeEach(() => {
413
+ jest.spyOn(signalCli, 'sendJsonRpcRequest').mockResolvedValue({});
414
+ });
415
+ it('should list devices', async () => {
416
+ const mockDevices = [
417
+ { id: 1, name: 'Device 1' },
418
+ { id: 2, name: 'Device 2' }
419
+ ];
420
+ const sendJsonRpcRequestSpy = jest.spyOn(signalCli, 'sendJsonRpcRequest')
421
+ .mockResolvedValue(mockDevices);
422
+ const result = await signalCli.listDevices();
423
+ expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('listDevices', {
424
+ account: '+1234567890'
425
+ });
426
+ expect(result).toEqual(mockDevices);
427
+ });
428
+ it('should update device name', async () => {
429
+ const sendJsonRpcRequestSpy = jest.spyOn(signalCli, 'sendJsonRpcRequest')
430
+ .mockResolvedValue(undefined);
431
+ await signalCli.updateDevice({
432
+ deviceId: 2,
433
+ deviceName: 'My Updated Device'
434
+ });
435
+ expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('updateDevice', {
436
+ account: '+1234567890',
437
+ deviceId: 2,
438
+ deviceName: 'My Updated Device'
439
+ });
440
+ });
441
+ it('should validate device ID when updating', async () => {
442
+ await expect(signalCli.updateDevice({
443
+ deviceId: -1,
444
+ deviceName: 'Invalid'
445
+ })).rejects.toThrow();
446
+ });
447
+ it('should validate device name length', async () => {
448
+ const longName = 'a'.repeat(201);
449
+ await expect(signalCli.updateDevice({
450
+ deviceId: 2,
451
+ deviceName: longName
452
+ })).rejects.toThrow();
453
+ });
454
+ });
410
455
  // Test v0.1.0 features: Synchronization
411
456
  describe('Synchronization', () => {
412
457
  beforeEach(() => {
@@ -1095,6 +1095,15 @@ export interface AccountUpdateResult {
1095
1095
  /** Error message if failed */
1096
1096
  error?: string;
1097
1097
  }
1098
+ /**
1099
+ * Options for updating a linked device
1100
+ */
1101
+ export interface UpdateDeviceOptions {
1102
+ /** Device ID to update */
1103
+ deviceId: number;
1104
+ /** New device name */
1105
+ deviceName: string;
1106
+ }
1098
1107
  /**
1099
1108
  * Options for receiving messages
1100
1109
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "signal-sdk",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "A comprehensive TypeScript SDK for Signal Messenger with native JSON-RPC support, providing high-performance messaging, bot framework, and full signal-cli integration.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -3,7 +3,7 @@ const fs = require('fs');
3
3
  const path = require('path');
4
4
  const tar = require('tar');
5
5
 
6
- const VERSION = '0.13.22';
6
+ const VERSION = '0.13.23';
7
7
  const BASE_URL = `https://github.com/AsamK/signal-cli/releases/download/v${VERSION}`;
8
8
 
9
9
  const platform = process.platform;