@gravity-rail/sdk 0.5.1 → 0.7.0
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/dist/agui.cjs +78 -0
- package/dist/agui.cjs.map +1 -0
- package/dist/agui.d.cts +13 -0
- package/dist/agui.d.ts +13 -0
- package/dist/agui.js +48 -0
- package/dist/agui.js.map +1 -0
- package/dist/audio.cjs +223 -0
- package/dist/audio.cjs.map +1 -0
- package/dist/audio.d.cts +25 -0
- package/dist/audio.d.ts +25 -0
- package/dist/audio.js +147 -0
- package/dist/audio.js.map +1 -0
- package/dist/chunk-BSOOMHW6.js +62 -0
- package/dist/chunk-BSOOMHW6.js.map +1 -0
- package/dist/{chunk-XRKRVY46.js → chunk-PEWFZXNK.js} +194 -31
- package/dist/chunk-PEWFZXNK.js.map +1 -0
- package/dist/{index-BhUZfOAG.d.cts → client-CLxHFOeB.d.cts} +310 -1632
- package/dist/{index-fPswHAIF.d.ts → client-Dft3Kmkn.d.ts} +310 -1632
- package/dist/helpers.cjs +123 -0
- package/dist/helpers.cjs.map +1 -0
- package/dist/helpers.d.cts +28 -0
- package/dist/helpers.d.ts +28 -0
- package/dist/helpers.js +92 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index-CeVDRf6l.d.cts +1607 -0
- package/dist/index-D1G8EKz2.d.ts +1607 -0
- package/dist/index.cjs +186 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/{inquiries-DiTDrTG2.d.cts → inquiries-BIlL6Obb.d.cts} +28 -3
- package/dist/{inquiries-DiTDrTG2.d.ts → inquiries-BIlL6Obb.d.ts} +28 -3
- package/dist/internal.cjs +195 -30
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +4 -3
- package/dist/internal.d.ts +4 -3
- package/dist/internal.js +5 -1
- package/dist/oauth-client.cjs +78 -0
- package/dist/oauth-client.cjs.map +1 -0
- package/dist/oauth-client.d.cts +15 -0
- package/dist/oauth-client.d.ts +15 -0
- package/dist/oauth-client.js +48 -0
- package/dist/oauth-client.js.map +1 -0
- package/dist/realtime.cjs +637 -0
- package/dist/realtime.cjs.map +1 -0
- package/dist/realtime.d.cts +94 -0
- package/dist/realtime.d.ts +94 -0
- package/dist/realtime.js +580 -0
- package/dist/realtime.js.map +1 -0
- package/dist/schemas.cjs +7 -3
- package/dist/schemas.cjs.map +1 -1
- package/dist/schemas.d.cts +28 -6
- package/dist/schemas.d.ts +28 -6
- package/dist/schemas.js +6 -3
- package/dist/schemas.js.map +1 -1
- package/dist/types-DkYyrvoC.d.cts +19 -0
- package/dist/types-DkYyrvoC.d.ts +19 -0
- package/package.json +26 -1
- package/dist/chunk-XRKRVY46.js.map +0 -1
package/dist/helpers.cjs
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/helpers/index.ts
|
|
21
|
+
var helpers_exports = {};
|
|
22
|
+
__export(helpers_exports, {
|
|
23
|
+
findMemberByPhone: () => findMemberByPhone,
|
|
24
|
+
listOutboundPhoneNumbers: () => listOutboundPhoneNumbers,
|
|
25
|
+
normalizePhoneLast10: () => normalizePhoneLast10,
|
|
26
|
+
resolveOutboundPhoneNumberId: () => resolveOutboundPhoneNumberId,
|
|
27
|
+
resolveOutboundWorkflowId: () => resolveOutboundWorkflowId
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(helpers_exports);
|
|
30
|
+
|
|
31
|
+
// src/helpers/outbound.ts
|
|
32
|
+
function normalizePhoneLast10(phone) {
|
|
33
|
+
const digits = phone.replace(/\D/g, "");
|
|
34
|
+
return digits.length >= 10 ? digits.slice(-10) : digits;
|
|
35
|
+
}
|
|
36
|
+
function phonesMatchLast10(a, b) {
|
|
37
|
+
const da = normalizePhoneLast10(a);
|
|
38
|
+
const db = normalizePhoneLast10(b);
|
|
39
|
+
if (!da || !db) return false;
|
|
40
|
+
if (da.length >= 10 && db.length >= 10) {
|
|
41
|
+
return da === db;
|
|
42
|
+
}
|
|
43
|
+
return da === db;
|
|
44
|
+
}
|
|
45
|
+
async function listOutboundPhoneNumbers(client, workspaceUuid) {
|
|
46
|
+
const [phones, defaults] = await Promise.all([
|
|
47
|
+
client.getPhoneNumbers(workspaceUuid, { isArchived: false }),
|
|
48
|
+
client.getWorkspaceDefaults(workspaceUuid)
|
|
49
|
+
]);
|
|
50
|
+
const voicePhones = phones.filter((phone) => phone.enableVoice && !phone.isArchived).map((phone) => ({
|
|
51
|
+
id: phone.id,
|
|
52
|
+
number: phone.number,
|
|
53
|
+
name: phone.name
|
|
54
|
+
}));
|
|
55
|
+
let defaultPhoneNumberId = defaults.defaultPhoneNumberId ?? null;
|
|
56
|
+
if (defaultPhoneNumberId !== null && !voicePhones.some((phone) => phone.id === defaultPhoneNumberId)) {
|
|
57
|
+
defaultPhoneNumberId = voicePhones[0]?.id ?? null;
|
|
58
|
+
}
|
|
59
|
+
if (defaultPhoneNumberId === null) {
|
|
60
|
+
defaultPhoneNumberId = voicePhones[0]?.id ?? null;
|
|
61
|
+
}
|
|
62
|
+
return { phones: voicePhones, defaultPhoneNumberId };
|
|
63
|
+
}
|
|
64
|
+
async function resolveOutboundPhoneNumberId(client, workspaceUuid, configDefaults) {
|
|
65
|
+
const { phones, defaultPhoneNumberId } = await listOutboundPhoneNumbers(client, workspaceUuid);
|
|
66
|
+
if (phones.length === 0) {
|
|
67
|
+
throw new Error(
|
|
68
|
+
"No voice-enabled phone numbers in this workspace. Add a line in Gravity Rail first."
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
const requestedId = configDefaults.requestedPhoneNumberId;
|
|
72
|
+
const candidate = requestedId ?? defaultPhoneNumberId ?? configDefaults.phoneNumberId ?? phones[0]?.id;
|
|
73
|
+
if (candidate === void 0 || !phones.some((phone) => phone.id === candidate)) {
|
|
74
|
+
throw new Error("Selected outbound phone number is not available.");
|
|
75
|
+
}
|
|
76
|
+
return candidate;
|
|
77
|
+
}
|
|
78
|
+
async function resolveOutboundWorkflowId(client, workspaceUuid, defaultWorkflowId, override) {
|
|
79
|
+
const workflows = await client.getWorkflows(workspaceUuid, false);
|
|
80
|
+
const options = workflows.filter((workflow) => !workflow.archived).map((workflow) => ({
|
|
81
|
+
id: workflow.id,
|
|
82
|
+
name: workflow.name
|
|
83
|
+
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
84
|
+
if (options.length === 0) {
|
|
85
|
+
throw new Error("No workflows in this workspace. Create a workflow in Gravity Rail first.");
|
|
86
|
+
}
|
|
87
|
+
let resolvedDefault = defaultWorkflowId;
|
|
88
|
+
if (!options.some((workflow) => workflow.id === resolvedDefault)) {
|
|
89
|
+
resolvedDefault = options[0]?.id ?? defaultWorkflowId;
|
|
90
|
+
}
|
|
91
|
+
const candidate = override ?? resolvedDefault;
|
|
92
|
+
if (!options.some((workflow) => workflow.id === candidate)) {
|
|
93
|
+
throw new Error("Selected workflow is not available.");
|
|
94
|
+
}
|
|
95
|
+
return candidate;
|
|
96
|
+
}
|
|
97
|
+
async function findMemberByPhone(client, workspaceUuid, phone) {
|
|
98
|
+
const searchDigits = phone.replace(/\D/g, "");
|
|
99
|
+
for (let page = 1; page <= 5; page += 1) {
|
|
100
|
+
const response = await client.getWorkspaceMembers(
|
|
101
|
+
workspaceUuid,
|
|
102
|
+
page,
|
|
103
|
+
50,
|
|
104
|
+
void 0,
|
|
105
|
+
searchDigits
|
|
106
|
+
);
|
|
107
|
+
const match = response.items.find(
|
|
108
|
+
(member) => member.phone && phonesMatchLast10(member.phone, phone)
|
|
109
|
+
);
|
|
110
|
+
if (match) return match;
|
|
111
|
+
if (page >= response.totalPages) break;
|
|
112
|
+
}
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
116
|
+
0 && (module.exports = {
|
|
117
|
+
findMemberByPhone,
|
|
118
|
+
listOutboundPhoneNumbers,
|
|
119
|
+
normalizePhoneLast10,
|
|
120
|
+
resolveOutboundPhoneNumberId,
|
|
121
|
+
resolveOutboundWorkflowId
|
|
122
|
+
});
|
|
123
|
+
//# sourceMappingURL=helpers.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/helpers/index.ts","../src/helpers/outbound.ts"],"sourcesContent":["export {\n findMemberByPhone,\n listOutboundPhoneNumbers,\n normalizePhoneLast10,\n resolveOutboundPhoneNumberId,\n resolveOutboundWorkflowId,\n type OutboundPhoneNumberConfigDefaults,\n type OutboundPhoneNumberOption,\n type WorkspacePhoneNumbersPayload,\n} from './outbound';\n","import type { GravityRailClient } from '../client/client';\nimport type { Member } from '../types/member-types';\n\nexport interface OutboundPhoneNumberOption {\n id: number;\n number: string;\n name: string | null;\n}\n\nexport interface WorkspacePhoneNumbersPayload {\n phones: OutboundPhoneNumberOption[];\n defaultPhoneNumberId: number | null;\n}\n\n/** App/env fallbacks when resolving outbound phone numbers. */\nexport interface OutboundPhoneNumberConfigDefaults {\n /** e.g. GRAVITY_RAIL_PHONE_NUMBER_ID */\n phoneNumberId?: number;\n /** Explicit selection overriding workspace default */\n requestedPhoneNumberId?: number;\n}\n\n/** Strip to digits and return the last 10 (US-friendly match). */\nexport function normalizePhoneLast10(phone: string): string {\n const digits = phone.replace(/\\D/g, '');\n return digits.length >= 10 ? digits.slice(-10) : digits;\n}\n\nfunction phonesMatchLast10(a: string, b: string): boolean {\n const da = normalizePhoneLast10(a);\n const db = normalizePhoneLast10(b);\n if (!da || !db) return false;\n if (da.length >= 10 && db.length >= 10) {\n return da === db;\n }\n return da === db;\n}\n\nexport async function listOutboundPhoneNumbers(\n client: GravityRailClient,\n workspaceUuid: string\n): Promise<WorkspacePhoneNumbersPayload> {\n const [phones, defaults] = await Promise.all([\n client.getPhoneNumbers(workspaceUuid, { isArchived: false }),\n client.getWorkspaceDefaults(workspaceUuid),\n ]);\n\n const voicePhones = phones\n .filter((phone) => phone.enableVoice && !phone.isArchived)\n .map((phone) => ({\n id: phone.id,\n number: phone.number,\n name: phone.name,\n }));\n\n let defaultPhoneNumberId = defaults.defaultPhoneNumberId ?? null;\n if (\n defaultPhoneNumberId !== null &&\n !voicePhones.some((phone) => phone.id === defaultPhoneNumberId)\n ) {\n defaultPhoneNumberId = voicePhones[0]?.id ?? null;\n }\n if (defaultPhoneNumberId === null) {\n defaultPhoneNumberId = voicePhones[0]?.id ?? null;\n }\n\n return { phones: voicePhones, defaultPhoneNumberId };\n}\n\nexport async function resolveOutboundPhoneNumberId(\n client: GravityRailClient,\n workspaceUuid: string,\n configDefaults: OutboundPhoneNumberConfigDefaults\n): Promise<number> {\n const { phones, defaultPhoneNumberId } = await listOutboundPhoneNumbers(client, workspaceUuid);\n\n if (phones.length === 0) {\n throw new Error(\n 'No voice-enabled phone numbers in this workspace. Add a line in Gravity Rail first.'\n );\n }\n\n const requestedId = configDefaults.requestedPhoneNumberId;\n const candidate =\n requestedId ?? defaultPhoneNumberId ?? configDefaults.phoneNumberId ?? phones[0]?.id;\n\n if (candidate === undefined || !phones.some((phone) => phone.id === candidate)) {\n throw new Error('Selected outbound phone number is not available.');\n }\n\n return candidate;\n}\n\nexport async function resolveOutboundWorkflowId(\n client: GravityRailClient,\n workspaceUuid: string,\n defaultWorkflowId: number,\n override?: number\n): Promise<number> {\n const workflows = await client.getWorkflows(workspaceUuid, false);\n const options = workflows\n .filter((workflow) => !workflow.archived)\n .map((workflow) => ({\n id: workflow.id,\n name: workflow.name,\n }))\n .sort((a, b) => a.name.localeCompare(b.name));\n\n if (options.length === 0) {\n throw new Error('No workflows in this workspace. Create a workflow in Gravity Rail first.');\n }\n\n let resolvedDefault = defaultWorkflowId;\n if (!options.some((workflow) => workflow.id === resolvedDefault)) {\n resolvedDefault = options[0]?.id ?? defaultWorkflowId;\n }\n\n const candidate = override ?? resolvedDefault;\n\n if (!options.some((workflow) => workflow.id === candidate)) {\n throw new Error('Selected workflow is not available.');\n }\n\n return candidate;\n}\n\nexport async function findMemberByPhone(\n client: GravityRailClient,\n workspaceUuid: string,\n phone: string\n): Promise<Member | null> {\n const searchDigits = phone.replace(/\\D/g, '');\n\n for (let page = 1; page <= 5; page += 1) {\n const response = await client.getWorkspaceMembers(\n workspaceUuid,\n page,\n 50,\n undefined,\n searchDigits\n );\n const match = response.items.find(\n (member) => member.phone && phonesMatchLast10(member.phone, phone)\n );\n if (match) return match;\n\n if (page >= response.totalPages) break;\n }\n\n return null;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { G as GravityRailClient } from './client-CLxHFOeB.cjs';
|
|
2
|
+
import { W as WorkspaceMemberResponse } from './inquiries-BIlL6Obb.cjs';
|
|
3
|
+
import 'zod';
|
|
4
|
+
|
|
5
|
+
interface OutboundPhoneNumberOption {
|
|
6
|
+
id: number;
|
|
7
|
+
number: string;
|
|
8
|
+
name: string | null;
|
|
9
|
+
}
|
|
10
|
+
interface WorkspacePhoneNumbersPayload {
|
|
11
|
+
phones: OutboundPhoneNumberOption[];
|
|
12
|
+
defaultPhoneNumberId: number | null;
|
|
13
|
+
}
|
|
14
|
+
/** App/env fallbacks when resolving outbound phone numbers. */
|
|
15
|
+
interface OutboundPhoneNumberConfigDefaults {
|
|
16
|
+
/** e.g. GRAVITY_RAIL_PHONE_NUMBER_ID */
|
|
17
|
+
phoneNumberId?: number;
|
|
18
|
+
/** Explicit selection overriding workspace default */
|
|
19
|
+
requestedPhoneNumberId?: number;
|
|
20
|
+
}
|
|
21
|
+
/** Strip to digits and return the last 10 (US-friendly match). */
|
|
22
|
+
declare function normalizePhoneLast10(phone: string): string;
|
|
23
|
+
declare function listOutboundPhoneNumbers(client: GravityRailClient, workspaceUuid: string): Promise<WorkspacePhoneNumbersPayload>;
|
|
24
|
+
declare function resolveOutboundPhoneNumberId(client: GravityRailClient, workspaceUuid: string, configDefaults: OutboundPhoneNumberConfigDefaults): Promise<number>;
|
|
25
|
+
declare function resolveOutboundWorkflowId(client: GravityRailClient, workspaceUuid: string, defaultWorkflowId: number, override?: number): Promise<number>;
|
|
26
|
+
declare function findMemberByPhone(client: GravityRailClient, workspaceUuid: string, phone: string): Promise<WorkspaceMemberResponse | null>;
|
|
27
|
+
|
|
28
|
+
export { type OutboundPhoneNumberConfigDefaults, type OutboundPhoneNumberOption, type WorkspacePhoneNumbersPayload, findMemberByPhone, listOutboundPhoneNumbers, normalizePhoneLast10, resolveOutboundPhoneNumberId, resolveOutboundWorkflowId };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { G as GravityRailClient } from './client-Dft3Kmkn.js';
|
|
2
|
+
import { W as WorkspaceMemberResponse } from './inquiries-BIlL6Obb.js';
|
|
3
|
+
import 'zod';
|
|
4
|
+
|
|
5
|
+
interface OutboundPhoneNumberOption {
|
|
6
|
+
id: number;
|
|
7
|
+
number: string;
|
|
8
|
+
name: string | null;
|
|
9
|
+
}
|
|
10
|
+
interface WorkspacePhoneNumbersPayload {
|
|
11
|
+
phones: OutboundPhoneNumberOption[];
|
|
12
|
+
defaultPhoneNumberId: number | null;
|
|
13
|
+
}
|
|
14
|
+
/** App/env fallbacks when resolving outbound phone numbers. */
|
|
15
|
+
interface OutboundPhoneNumberConfigDefaults {
|
|
16
|
+
/** e.g. GRAVITY_RAIL_PHONE_NUMBER_ID */
|
|
17
|
+
phoneNumberId?: number;
|
|
18
|
+
/** Explicit selection overriding workspace default */
|
|
19
|
+
requestedPhoneNumberId?: number;
|
|
20
|
+
}
|
|
21
|
+
/** Strip to digits and return the last 10 (US-friendly match). */
|
|
22
|
+
declare function normalizePhoneLast10(phone: string): string;
|
|
23
|
+
declare function listOutboundPhoneNumbers(client: GravityRailClient, workspaceUuid: string): Promise<WorkspacePhoneNumbersPayload>;
|
|
24
|
+
declare function resolveOutboundPhoneNumberId(client: GravityRailClient, workspaceUuid: string, configDefaults: OutboundPhoneNumberConfigDefaults): Promise<number>;
|
|
25
|
+
declare function resolveOutboundWorkflowId(client: GravityRailClient, workspaceUuid: string, defaultWorkflowId: number, override?: number): Promise<number>;
|
|
26
|
+
declare function findMemberByPhone(client: GravityRailClient, workspaceUuid: string, phone: string): Promise<WorkspaceMemberResponse | null>;
|
|
27
|
+
|
|
28
|
+
export { type OutboundPhoneNumberConfigDefaults, type OutboundPhoneNumberOption, type WorkspacePhoneNumbersPayload, findMemberByPhone, listOutboundPhoneNumbers, normalizePhoneLast10, resolveOutboundPhoneNumberId, resolveOutboundWorkflowId };
|
package/dist/helpers.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// src/helpers/outbound.ts
|
|
2
|
+
function normalizePhoneLast10(phone) {
|
|
3
|
+
const digits = phone.replace(/\D/g, "");
|
|
4
|
+
return digits.length >= 10 ? digits.slice(-10) : digits;
|
|
5
|
+
}
|
|
6
|
+
function phonesMatchLast10(a, b) {
|
|
7
|
+
const da = normalizePhoneLast10(a);
|
|
8
|
+
const db = normalizePhoneLast10(b);
|
|
9
|
+
if (!da || !db) return false;
|
|
10
|
+
if (da.length >= 10 && db.length >= 10) {
|
|
11
|
+
return da === db;
|
|
12
|
+
}
|
|
13
|
+
return da === db;
|
|
14
|
+
}
|
|
15
|
+
async function listOutboundPhoneNumbers(client, workspaceUuid) {
|
|
16
|
+
const [phones, defaults] = await Promise.all([
|
|
17
|
+
client.getPhoneNumbers(workspaceUuid, { isArchived: false }),
|
|
18
|
+
client.getWorkspaceDefaults(workspaceUuid)
|
|
19
|
+
]);
|
|
20
|
+
const voicePhones = phones.filter((phone) => phone.enableVoice && !phone.isArchived).map((phone) => ({
|
|
21
|
+
id: phone.id,
|
|
22
|
+
number: phone.number,
|
|
23
|
+
name: phone.name
|
|
24
|
+
}));
|
|
25
|
+
let defaultPhoneNumberId = defaults.defaultPhoneNumberId ?? null;
|
|
26
|
+
if (defaultPhoneNumberId !== null && !voicePhones.some((phone) => phone.id === defaultPhoneNumberId)) {
|
|
27
|
+
defaultPhoneNumberId = voicePhones[0]?.id ?? null;
|
|
28
|
+
}
|
|
29
|
+
if (defaultPhoneNumberId === null) {
|
|
30
|
+
defaultPhoneNumberId = voicePhones[0]?.id ?? null;
|
|
31
|
+
}
|
|
32
|
+
return { phones: voicePhones, defaultPhoneNumberId };
|
|
33
|
+
}
|
|
34
|
+
async function resolveOutboundPhoneNumberId(client, workspaceUuid, configDefaults) {
|
|
35
|
+
const { phones, defaultPhoneNumberId } = await listOutboundPhoneNumbers(client, workspaceUuid);
|
|
36
|
+
if (phones.length === 0) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
"No voice-enabled phone numbers in this workspace. Add a line in Gravity Rail first."
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
const requestedId = configDefaults.requestedPhoneNumberId;
|
|
42
|
+
const candidate = requestedId ?? defaultPhoneNumberId ?? configDefaults.phoneNumberId ?? phones[0]?.id;
|
|
43
|
+
if (candidate === void 0 || !phones.some((phone) => phone.id === candidate)) {
|
|
44
|
+
throw new Error("Selected outbound phone number is not available.");
|
|
45
|
+
}
|
|
46
|
+
return candidate;
|
|
47
|
+
}
|
|
48
|
+
async function resolveOutboundWorkflowId(client, workspaceUuid, defaultWorkflowId, override) {
|
|
49
|
+
const workflows = await client.getWorkflows(workspaceUuid, false);
|
|
50
|
+
const options = workflows.filter((workflow) => !workflow.archived).map((workflow) => ({
|
|
51
|
+
id: workflow.id,
|
|
52
|
+
name: workflow.name
|
|
53
|
+
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
54
|
+
if (options.length === 0) {
|
|
55
|
+
throw new Error("No workflows in this workspace. Create a workflow in Gravity Rail first.");
|
|
56
|
+
}
|
|
57
|
+
let resolvedDefault = defaultWorkflowId;
|
|
58
|
+
if (!options.some((workflow) => workflow.id === resolvedDefault)) {
|
|
59
|
+
resolvedDefault = options[0]?.id ?? defaultWorkflowId;
|
|
60
|
+
}
|
|
61
|
+
const candidate = override ?? resolvedDefault;
|
|
62
|
+
if (!options.some((workflow) => workflow.id === candidate)) {
|
|
63
|
+
throw new Error("Selected workflow is not available.");
|
|
64
|
+
}
|
|
65
|
+
return candidate;
|
|
66
|
+
}
|
|
67
|
+
async function findMemberByPhone(client, workspaceUuid, phone) {
|
|
68
|
+
const searchDigits = phone.replace(/\D/g, "");
|
|
69
|
+
for (let page = 1; page <= 5; page += 1) {
|
|
70
|
+
const response = await client.getWorkspaceMembers(
|
|
71
|
+
workspaceUuid,
|
|
72
|
+
page,
|
|
73
|
+
50,
|
|
74
|
+
void 0,
|
|
75
|
+
searchDigits
|
|
76
|
+
);
|
|
77
|
+
const match = response.items.find(
|
|
78
|
+
(member) => member.phone && phonesMatchLast10(member.phone, phone)
|
|
79
|
+
);
|
|
80
|
+
if (match) return match;
|
|
81
|
+
if (page >= response.totalPages) break;
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
export {
|
|
86
|
+
findMemberByPhone,
|
|
87
|
+
listOutboundPhoneNumbers,
|
|
88
|
+
normalizePhoneLast10,
|
|
89
|
+
resolveOutboundPhoneNumberId,
|
|
90
|
+
resolveOutboundWorkflowId
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/helpers/outbound.ts"],"sourcesContent":["import type { GravityRailClient } from '../client/client';\nimport type { Member } from '../types/member-types';\n\nexport interface OutboundPhoneNumberOption {\n id: number;\n number: string;\n name: string | null;\n}\n\nexport interface WorkspacePhoneNumbersPayload {\n phones: OutboundPhoneNumberOption[];\n defaultPhoneNumberId: number | null;\n}\n\n/** App/env fallbacks when resolving outbound phone numbers. */\nexport interface OutboundPhoneNumberConfigDefaults {\n /** e.g. GRAVITY_RAIL_PHONE_NUMBER_ID */\n phoneNumberId?: number;\n /** Explicit selection overriding workspace default */\n requestedPhoneNumberId?: number;\n}\n\n/** Strip to digits and return the last 10 (US-friendly match). */\nexport function normalizePhoneLast10(phone: string): string {\n const digits = phone.replace(/\\D/g, '');\n return digits.length >= 10 ? digits.slice(-10) : digits;\n}\n\nfunction phonesMatchLast10(a: string, b: string): boolean {\n const da = normalizePhoneLast10(a);\n const db = normalizePhoneLast10(b);\n if (!da || !db) return false;\n if (da.length >= 10 && db.length >= 10) {\n return da === db;\n }\n return da === db;\n}\n\nexport async function listOutboundPhoneNumbers(\n client: GravityRailClient,\n workspaceUuid: string\n): Promise<WorkspacePhoneNumbersPayload> {\n const [phones, defaults] = await Promise.all([\n client.getPhoneNumbers(workspaceUuid, { isArchived: false }),\n client.getWorkspaceDefaults(workspaceUuid),\n ]);\n\n const voicePhones = phones\n .filter((phone) => phone.enableVoice && !phone.isArchived)\n .map((phone) => ({\n id: phone.id,\n number: phone.number,\n name: phone.name,\n }));\n\n let defaultPhoneNumberId = defaults.defaultPhoneNumberId ?? null;\n if (\n defaultPhoneNumberId !== null &&\n !voicePhones.some((phone) => phone.id === defaultPhoneNumberId)\n ) {\n defaultPhoneNumberId = voicePhones[0]?.id ?? null;\n }\n if (defaultPhoneNumberId === null) {\n defaultPhoneNumberId = voicePhones[0]?.id ?? null;\n }\n\n return { phones: voicePhones, defaultPhoneNumberId };\n}\n\nexport async function resolveOutboundPhoneNumberId(\n client: GravityRailClient,\n workspaceUuid: string,\n configDefaults: OutboundPhoneNumberConfigDefaults\n): Promise<number> {\n const { phones, defaultPhoneNumberId } = await listOutboundPhoneNumbers(client, workspaceUuid);\n\n if (phones.length === 0) {\n throw new Error(\n 'No voice-enabled phone numbers in this workspace. Add a line in Gravity Rail first.'\n );\n }\n\n const requestedId = configDefaults.requestedPhoneNumberId;\n const candidate =\n requestedId ?? defaultPhoneNumberId ?? configDefaults.phoneNumberId ?? phones[0]?.id;\n\n if (candidate === undefined || !phones.some((phone) => phone.id === candidate)) {\n throw new Error('Selected outbound phone number is not available.');\n }\n\n return candidate;\n}\n\nexport async function resolveOutboundWorkflowId(\n client: GravityRailClient,\n workspaceUuid: string,\n defaultWorkflowId: number,\n override?: number\n): Promise<number> {\n const workflows = await client.getWorkflows(workspaceUuid, false);\n const options = workflows\n .filter((workflow) => !workflow.archived)\n .map((workflow) => ({\n id: workflow.id,\n name: workflow.name,\n }))\n .sort((a, b) => a.name.localeCompare(b.name));\n\n if (options.length === 0) {\n throw new Error('No workflows in this workspace. Create a workflow in Gravity Rail first.');\n }\n\n let resolvedDefault = defaultWorkflowId;\n if (!options.some((workflow) => workflow.id === resolvedDefault)) {\n resolvedDefault = options[0]?.id ?? defaultWorkflowId;\n }\n\n const candidate = override ?? resolvedDefault;\n\n if (!options.some((workflow) => workflow.id === candidate)) {\n throw new Error('Selected workflow is not available.');\n }\n\n return candidate;\n}\n\nexport async function findMemberByPhone(\n client: GravityRailClient,\n workspaceUuid: string,\n phone: string\n): Promise<Member | null> {\n const searchDigits = phone.replace(/\\D/g, '');\n\n for (let page = 1; page <= 5; page += 1) {\n const response = await client.getWorkspaceMembers(\n workspaceUuid,\n page,\n 50,\n undefined,\n searchDigits\n );\n const match = response.items.find(\n (member) => member.phone && phonesMatchLast10(member.phone, phone)\n );\n if (match) return match;\n\n if (page >= response.totalPages) break;\n }\n\n return null;\n}\n"],"mappings":"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","names":[]}
|