@signalhousellc/sdk 1.0.53 → 1.0.54

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signalhousellc/sdk",
3
- "version": "1.0.53",
3
+ "version": "1.0.54",
4
4
  "description": "Signal House SDK for use with the Signal House platform",
5
5
  "type": "module",
6
6
  "main": "src/SignalHouseSDK.js",
@@ -198,6 +198,29 @@ export class Brands {
198
198
  return this.client(`/brand/externalvetting/${safeBrandId}`, { method: "POST", ...options });
199
199
  }
200
200
 
201
+ /**
202
+ * Import an existing external vetting record for a brand
203
+ *
204
+ * Unlike createExternalVetting (which orders a new, billable vetting), this attaches a vetting the
205
+ * brand already completed directly with the provider, using the provider-issued vettingId and
206
+ * vettingToken. It is synchronous and not billable.
207
+ * @async
208
+ * @roles api, admin, developer, billing, user
209
+ * @param {Object} params - The parameters for importing external vetting
210
+ * @param {string} params.brandId - The ID of the brand to import external vetting for
211
+ * @param {string} params.vettingProviderId - The external vetting provider (AEGIS, WMC, CV)
212
+ * @param {string} params.vettingId - The provider-issued vetting / transaction ID to import
213
+ * @param {string} [params.vettingToken] - The provider-issued vetting token (required by some providers, e.g. AEGIS)
214
+ * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
215
+ * @throws {Error} Throws an error if brandId, vettingProviderId, or vettingId is missing
216
+ * @returns {Promise<Object>} The response from the server
217
+ */
218
+ async importExternalVetting({ brandId, vettingProviderId, vettingId, vettingToken, options = {} }) {
219
+ this.client._require({ brandId, vettingProviderId, vettingId });
220
+ const safeBrandId = encodeURIComponent(brandId);
221
+ return this.client(`/brand/externalvetting/import/${safeBrandId}`, { method: "POST", body: { vettingProviderId, vettingId, vettingToken }, ...options });
222
+ }
223
+
201
224
  /**
202
225
  * Update a brand's information
203
226
  * @async
@@ -134,15 +134,16 @@ export class Numbers {
134
134
  /**
135
135
  * Read the outcome of a Toll-Free number purchase by the `orderId` returned from
136
136
  * {@link Numbers#purchaseTollFreeNumbers}. Reports per-number status as ready / provisioning / failed
137
- * counts (plus failure reasons) so a client can poll until the order reaches a terminal state. The
138
- * provisioned numbers themselves appear in the regular numbers list as they materialize.
137
+ * counts (plus failure reasons) so a client can poll until the order reaches a terminal state, and
138
+ * returns the provisioned phone numbers for the order so a client can act on exactly those numbers.
139
+ * `numbers` is empty until each number is provisioned (it fills in as the order completes).
139
140
  * @async
140
141
  * @roles api, admin, developer, billing, user
141
142
  * @param {Object} params - The parameters for reading the order status
142
143
  * @param {string} params.orderId - The order id returned by `purchaseTollFreeNumbers`
143
144
  * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
144
145
  * @throws {Error} Throws an error if the orderId parameter is missing
145
- * @returns {Promise<Object>} A promise that resolves to `{ orderId, counts: { ready, provisioning, failed }, failures: [{ reason }] }`.
146
+ * @returns {Promise<Object>} A promise that resolves to `{ orderId, counts: { ready, provisioning, failed }, failures: [{ reason }], numbers: string[] }`.
146
147
  */
147
148
  async getTollFreeOrderStatus({ orderId, options = {} }) {
148
149
  this.client._require({ orderId });
@@ -141,6 +141,104 @@ export class Call {
141
141
  }
142
142
  }
143
143
 
144
+ /**
145
+ * Mute or unmute the local microphone. Twilio-shape: pass `true` to mute,
146
+ * `false` to unmute. Stops/resumes sending audio RTP at the media layer —
147
+ * no SIP signaling, so it works regardless of server support.
148
+ * @param {boolean} [shouldMute=true]
149
+ */
150
+ mute(shouldMute = true) {
151
+ if (this.status !== "in_progress") {
152
+ console.warn(`[Call.mute] no-op: call is not in_progress (status=${this.status})`);
153
+ return;
154
+ }
155
+ try {
156
+ if (shouldMute) this._session.mute({ audio: true });
157
+ else this._session.unmute({ audio: true });
158
+ } catch (err) {
159
+ console.warn(`[Call.mute] threw: ${err?.message || err}`);
160
+ }
161
+ }
162
+
163
+ /** Unmute the local microphone. Convenience for `mute(false)`. */
164
+ unmute() {
165
+ this.mute(false);
166
+ }
167
+
168
+ /**
169
+ * @returns {boolean} whether the local microphone is currently muted.
170
+ */
171
+ isMuted() {
172
+ try {
173
+ return Boolean(this._session.isMuted?.()?.audio);
174
+ } catch {
175
+ return false;
176
+ }
177
+ }
178
+
179
+ /**
180
+ * Put the call on hold, or resume it. Sends a re-INVITE with the audio
181
+ * direction set to sendonly (hold) / sendrecv (resume); the media server
182
+ * (rtpengine) handles it. Pass `false` to resume.
183
+ * @param {boolean} [shouldHold=true]
184
+ * @returns {boolean} whether the (un)hold was initiated.
185
+ */
186
+ hold(shouldHold = true) {
187
+ if (this.status !== "in_progress") {
188
+ console.warn(`[Call.hold] no-op: call is not in_progress (status=${this.status})`);
189
+ return false;
190
+ }
191
+ try {
192
+ return shouldHold ? this._session.hold() : this._session.unhold();
193
+ } catch (err) {
194
+ console.warn(`[Call.hold] threw: ${err?.message || err}`);
195
+ return false;
196
+ }
197
+ }
198
+
199
+ /** Resume a held call. Convenience for `hold(false)`. */
200
+ unhold() {
201
+ return this.hold(false);
202
+ }
203
+
204
+ /**
205
+ * @returns {boolean} whether this leg is locally on hold.
206
+ */
207
+ isOnHold() {
208
+ try {
209
+ return Boolean(this._session.isOnHold?.()?.local);
210
+ } catch {
211
+ return false;
212
+ }
213
+ }
214
+
215
+ /**
216
+ * Blind-transfer (cold transfer) the call to another destination via SIP
217
+ * REFER. The far end is re-routed to `target` and this leg ends once the
218
+ * transfer is accepted. `target` may be a phone number (E.164 or bare
219
+ * digits) or a full SIP URI — bare numbers are normalized against the
220
+ * registered SIP domain by the underlying stack.
221
+ *
222
+ * NOTE: completing the transfer requires the SIP server to honor the REFER
223
+ * (route the new leg / bridge the parties). The client only initiates it.
224
+ * @param {string} target - Destination number or SIP URI.
225
+ */
226
+ transfer(target) {
227
+ if (this.status !== "in_progress") {
228
+ console.warn(`[Call.transfer] no-op: call is not in_progress (status=${this.status})`);
229
+ return;
230
+ }
231
+ if (!target) {
232
+ console.warn("[Call.transfer] no-op: a transfer target is required");
233
+ return;
234
+ }
235
+ try {
236
+ this._session.refer(target);
237
+ } catch (err) {
238
+ console.warn(`[Call.transfer] refer threw: ${err?.message || err}`);
239
+ }
240
+ }
241
+
144
242
  /**
145
243
  * Attach an event listener. Events:
146
244
  * "accepted" — 200 OK received (outbound) or sent (inbound after accept)