@fonoster/sdk 0.27.0 → 0.31.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.
Files changed (91) hide show
  1. package/README.md +12 -9
  2. package/dist/node/Agents.js +5 -20
  3. package/dist/node/Applications.d.ts +21 -85
  4. package/dist/node/Applications.js +64 -74
  5. package/dist/node/Billing.d.ts +50 -0
  6. package/dist/node/Billing.js +84 -0
  7. package/dist/node/CallRecords.d.ts +92 -0
  8. package/dist/node/CallRecords.js +127 -0
  9. package/dist/node/Calls.d.ts +3 -1
  10. package/dist/node/Calls.js +3 -1
  11. package/dist/node/Domains.js +4 -2
  12. package/dist/node/Numbers.js +2 -7
  13. package/dist/node/Providers.d.ts +49 -0
  14. package/dist/node/Providers.js +109 -0
  15. package/dist/node/Regions.d.ts +91 -0
  16. package/dist/node/Regions.js +127 -0
  17. package/dist/node/Usage.d.ts +44 -0
  18. package/dist/node/Usage.js +41 -0
  19. package/dist/node/Users.d.ts +4 -2
  20. package/dist/node/Users.js +4 -2
  21. package/dist/node/Webhooks.d.ts +56 -0
  22. package/dist/node/Webhooks.js +139 -0
  23. package/dist/node/Workspaces.d.ts +22 -3
  24. package/dist/node/Workspaces.js +29 -2
  25. package/dist/node/client/AbstractClient.d.ts +94 -3
  26. package/dist/node/client/AbstractClient.js +101 -1
  27. package/dist/node/client/Client.d.ts +9 -0
  28. package/dist/node/client/Client.js +34 -1
  29. package/dist/node/client/jsonToObject.js +17 -0
  30. package/dist/node/client/objectToJson.js +35 -0
  31. package/dist/node/client/types/ApplicationsClient.d.ts +2 -1
  32. package/dist/node/client/types/BillingClient.d.ts +28 -0
  33. package/dist/node/client/types/BillingClient.js +2 -0
  34. package/dist/node/client/types/CapabilitiesClient.d.ts +24 -0
  35. package/dist/node/client/types/CapabilitiesClient.js +2 -0
  36. package/dist/node/client/types/FonosterClient.d.ts +12 -0
  37. package/dist/node/client/types/IdentityClient.d.ts +3 -1
  38. package/dist/node/client/types/ProvidersClient.d.ts +28 -0
  39. package/dist/node/client/types/ProvidersClient.js +2 -0
  40. package/dist/node/client/types/UsageClient.d.ts +24 -0
  41. package/dist/node/client/types/UsageClient.js +2 -0
  42. package/dist/node/client/types/WebhooksClient.d.ts +31 -0
  43. package/dist/node/client/types/WebhooksClient.js +2 -0
  44. package/dist/node/client/types/index.d.ts +5 -0
  45. package/dist/node/client/types/index.js +5 -0
  46. package/dist/node/generated/node/applications_grpc_pb.js +34 -0
  47. package/dist/node/generated/node/applications_pb.js +2991 -178
  48. package/dist/node/generated/node/billing_grpc_pb.js +169 -0
  49. package/dist/node/generated/node/billing_pb.js +1720 -0
  50. package/dist/node/generated/node/calls_pb.js +62 -2
  51. package/dist/node/generated/node/capabilities_grpc_pb.js +66 -0
  52. package/dist/node/generated/node/capabilities_pb.js +2288 -0
  53. package/dist/node/generated/node/identity_grpc_pb.js +34 -0
  54. package/dist/node/generated/node/identity_pb.js +609 -5
  55. package/dist/node/generated/node/providers_grpc_pb.js +200 -0
  56. package/dist/node/generated/node/providers_pb.js +3094 -0
  57. package/dist/node/generated/node/usage_grpc_pb.js +64 -0
  58. package/dist/node/generated/node/usage_pb.js +866 -0
  59. package/dist/node/generated/node/webhooks_grpc_pb.js +302 -0
  60. package/dist/node/generated/node/webhooks_pb.js +3314 -0
  61. package/dist/node/generated/web/ApplicationsServiceClientPb.ts +43 -0
  62. package/dist/node/generated/web/BillingServiceClientPb.ts +258 -0
  63. package/dist/node/generated/web/CapabilitiesServiceClientPb.ts +87 -0
  64. package/dist/node/generated/web/IdentityServiceClientPb.ts +43 -0
  65. package/dist/node/generated/web/ProvidersServiceClientPb.ts +258 -0
  66. package/dist/node/generated/web/UsageServiceClientPb.ts +86 -0
  67. package/dist/node/generated/web/WebhooksServiceClientPb.ts +387 -0
  68. package/dist/node/generated/web/applications_pb.d.ts +343 -1
  69. package/dist/node/generated/web/applications_pb.js +2991 -178
  70. package/dist/node/generated/web/billing_pb.d.ts +210 -0
  71. package/dist/node/generated/web/billing_pb.js +1720 -0
  72. package/dist/node/generated/web/calls_pb.d.ts +8 -0
  73. package/dist/node/generated/web/calls_pb.js +62 -2
  74. package/dist/node/generated/web/capabilities_pb.d.ts +273 -0
  75. package/dist/node/generated/web/capabilities_pb.js +2288 -0
  76. package/dist/node/generated/web/identity_pb.d.ts +76 -0
  77. package/dist/node/generated/web/identity_pb.js +609 -5
  78. package/dist/node/generated/web/providers_pb.d.ts +372 -0
  79. package/dist/node/generated/web/providers_pb.js +3094 -0
  80. package/dist/node/generated/web/usage_pb.d.ts +106 -0
  81. package/dist/node/generated/web/usage_pb.js +866 -0
  82. package/dist/node/generated/web/webhooks_pb.d.ts +398 -0
  83. package/dist/node/generated/web/webhooks_pb.js +3314 -0
  84. package/dist/node/node.d.ts +7 -0
  85. package/dist/node/node.js +6 -0
  86. package/dist/node/tsconfig.tsbuildinfo +1 -1
  87. package/dist/node/utils.d.ts +7 -12
  88. package/dist/node/utils.js +18 -39
  89. package/dist/web/fonoster.min.js +1 -1
  90. package/dist/web/index.esm.js +1 -1
  91. package/package.json +8 -13
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Billing = void 0;
4
+ const makeRpcRequest_1 = require("./client/makeRpcRequest");
5
+ const billing_pb_1 = require("./generated/node/billing_pb");
6
+ /**
7
+ * @classdesc Fonoster Cloud's billing for the owner signed in: the balance in credits
8
+ * (1 credit = $0.01) by source, the plan, top-ups, auto-recharge and the Stripe Customer Portal.
9
+ * Only workspace owners may call it, and only on Fonoster Cloud (the capabilities say
10
+ * `billing.enabled`). The account is always the caller's: it covers every workspace they own.
11
+ *
12
+ * @example
13
+ * const billing = new SDK.Billing(client);
14
+ * const { balance, sources } = await billing.getBilling();
15
+ * await billing.createTopUp({ credits: 1000 });
16
+ */
17
+ class Billing {
18
+ client;
19
+ constructor(client) {
20
+ this.client = client;
21
+ }
22
+ /** The balance by source, the plan and auto-recharge. */
23
+ async getBilling() {
24
+ const client = this.client.getBillingClient();
25
+ return this.summary((0, makeRpcRequest_1.makeRpcRequest)({
26
+ method: client.getBilling.bind(client),
27
+ requestPBObjectConstructor: billing_pb_1.GetBillingRequest,
28
+ metadata: this.client.getMetadata(),
29
+ request: {},
30
+ repeatableObjectMapping: [["sourcesList", billing_pb_1.CreditSource]]
31
+ }));
32
+ }
33
+ /** Turns auto-recharge on or off, with its threshold and amount in credits. */
34
+ async updateAutoRecharge(request) {
35
+ const client = this.client.getBillingClient();
36
+ return this.summary((0, makeRpcRequest_1.makeRpcRequest)({
37
+ method: client.updateAutoRecharge.bind(client),
38
+ requestPBObjectConstructor: billing_pb_1.UpdateAutoRechargeRequest,
39
+ metadata: this.client.getMetadata(),
40
+ request,
41
+ repeatableObjectMapping: [["sourcesList", billing_pb_1.CreditSource]]
42
+ }));
43
+ }
44
+ /**
45
+ * Buys top-up credits, charged to the payment method added in the Customer Portal, with tax on
46
+ * top. The credits appear once the payment succeeds.
47
+ */
48
+ async createTopUp(request) {
49
+ const client = this.client.getBillingClient();
50
+ return this.summary((0, makeRpcRequest_1.makeRpcRequest)({
51
+ method: client.createTopUp.bind(client),
52
+ requestPBObjectConstructor: billing_pb_1.CreateTopUpRequest,
53
+ metadata: this.client.getMetadata(),
54
+ request,
55
+ repeatableObjectMapping: [["sourcesList", billing_pb_1.CreditSource]]
56
+ }));
57
+ }
58
+ /** Moves the owner from the Trial to Pay-as-you-go. Needs a payment method first. */
59
+ async subscribe() {
60
+ const client = this.client.getBillingClient();
61
+ return this.summary((0, makeRpcRequest_1.makeRpcRequest)({
62
+ method: client.subscribe.bind(client),
63
+ requestPBObjectConstructor: billing_pb_1.SubscribeRequest,
64
+ metadata: this.client.getMetadata(),
65
+ request: {},
66
+ repeatableObjectMapping: [["sourcesList", billing_pb_1.CreditSource]]
67
+ }));
68
+ }
69
+ /** A Stripe Customer Portal link for payment methods and invoices. */
70
+ async createPortalSession(request) {
71
+ const client = this.client.getBillingClient();
72
+ return (0, makeRpcRequest_1.makeRpcRequest)({
73
+ method: client.createPortalSession.bind(client),
74
+ requestPBObjectConstructor: billing_pb_1.CreatePortalSessionRequest,
75
+ metadata: this.client.getMetadata(),
76
+ request
77
+ });
78
+ }
79
+ async summary(raw) {
80
+ const { sources, ...rest } = await raw;
81
+ return { ...rest, sources: sources ?? [] };
82
+ }
83
+ }
84
+ exports.Billing = Billing;
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
3
+ * http://github.com/fonoster/fonoster
4
+ *
5
+ * This file is part of Fonoster
6
+ *
7
+ * Licensed under the MIT License (the "License");
8
+ * you may not use this file except in compliance with
9
+ * the License. You may obtain a copy of the License at
10
+ *
11
+ * https://opensource.org/licenses/MIT
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ */
19
+ import { CallRecordAuditEntry, CallRecordDetail, ListCallRecordsRequest, ListCallRecordsResponse, RetentionPolicy } from "@fonoster/types";
20
+ import { FonosterClient } from "./client/types";
21
+ type FetchLike = (url: string, init?: {
22
+ method?: string;
23
+ headers?: Record<string, string>;
24
+ body?: string;
25
+ }) => Promise<{
26
+ ok: boolean;
27
+ status: number;
28
+ headers: {
29
+ get(name: string): string | null;
30
+ };
31
+ json(): Promise<unknown>;
32
+ arrayBuffer(): Promise<ArrayBuffer>;
33
+ }>;
34
+ /** An error answer from the records API (status and its `error` code). */
35
+ declare class CallRecordsError extends Error {
36
+ readonly status: number;
37
+ readonly code: string;
38
+ constructor(status: number, code: string, message?: string);
39
+ }
40
+ /**
41
+ * @classdesc Call records (vCon) through the HTTP records API (`/api/records`): search, one
42
+ * record (redacted unless you ask for the original and have the owner or admin role), the
43
+ * recording, the audit log, erasure and retention.
44
+ *
45
+ * @example
46
+ * const records = new SDK.CallRecords(client);
47
+ * const { items } = await records.listRecords({ after: "2026-10-01T00:00:00Z" });
48
+ * const record = await records.getRecord(items[0].callRef);
49
+ */
50
+ declare class CallRecords {
51
+ private readonly client;
52
+ private readonly baseUrl?;
53
+ private readonly fetchFn;
54
+ /**
55
+ * @param {FonosterClient} client - A logged-in client
56
+ * @param {object} options - `baseUrl` of the HTTP API (default: the client's), `fetch`
57
+ */
58
+ constructor(client: FonosterClient, options?: {
59
+ baseUrl?: string;
60
+ fetch?: FetchLike;
61
+ });
62
+ private url;
63
+ /** Sends a request, refreshing the access token once on 401. */
64
+ private send;
65
+ private json;
66
+ /** Searches the workspace's records, newest first. */
67
+ listRecords(request?: ListCallRecordsRequest): Promise<ListCallRecordsResponse>;
68
+ /** One record; the latest version unless `version` is given. */
69
+ getRecord(callRef: string, options?: {
70
+ version?: number;
71
+ original?: boolean;
72
+ }): Promise<CallRecordDetail>;
73
+ /** The recording (WAV) with its content hash. */
74
+ getRecording(callRef: string, options?: {
75
+ version?: number;
76
+ original?: boolean;
77
+ }): Promise<{
78
+ data: ArrayBuffer;
79
+ contentType: string;
80
+ contentHash: string;
81
+ }>;
82
+ /** Deletions and erasures of a record (owner or admin). */
83
+ getAudit(callRef: string): Promise<CallRecordAuditEntry[]>;
84
+ /** Erases the call: every object is deleted and a signed tombstone remains (owner or admin). */
85
+ eraseRecord(callRef: string, reason?: string): Promise<unknown>;
86
+ /** Deletes one part (recording, transcript, messages) of a record (owner or admin). */
87
+ deletePart(callRef: string, part: string, reason?: string): Promise<unknown>;
88
+ getRetention(): Promise<RetentionPolicy[]>;
89
+ /** Sets how many days a part is kept; `null` removes the policy (owner or admin). */
90
+ setRetention(part: string, days: number | null): Promise<RetentionPolicy>;
91
+ }
92
+ export { CallRecords, CallRecordsError };
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CallRecordsError = exports.CallRecords = void 0;
4
+ /** An error answer from the records API (status and its `error` code). */
5
+ class CallRecordsError extends Error {
6
+ status;
7
+ code;
8
+ constructor(status, code, message) {
9
+ super(message ?? `records API: ${status} ${code}`);
10
+ this.status = status;
11
+ this.code = code;
12
+ }
13
+ }
14
+ exports.CallRecordsError = CallRecordsError;
15
+ /**
16
+ * @classdesc Call records (vCon) through the HTTP records API (`/api/records`): search, one
17
+ * record (redacted unless you ask for the original and have the owner or admin role), the
18
+ * recording, the audit log, erasure and retention.
19
+ *
20
+ * @example
21
+ * const records = new SDK.CallRecords(client);
22
+ * const { items } = await records.listRecords({ after: "2026-10-01T00:00:00Z" });
23
+ * const record = await records.getRecord(items[0].callRef);
24
+ */
25
+ class CallRecords {
26
+ client;
27
+ baseUrl;
28
+ fetchFn;
29
+ /**
30
+ * @param {FonosterClient} client - A logged-in client
31
+ * @param {object} options - `baseUrl` of the HTTP API (default: the client's), `fetch`
32
+ */
33
+ constructor(client, options = {}) {
34
+ this.client = client;
35
+ this.baseUrl = options.baseUrl?.replace(/\/+$/, "");
36
+ // Called as a method below, so never store the global unbound: in browsers a detached
37
+ // `fetch` throws "Illegal invocation".
38
+ this.fetchFn =
39
+ options.fetch ??
40
+ ((input, init) => globalThis.fetch(input, init));
41
+ }
42
+ url(path, query = {}) {
43
+ const base = this.baseUrl ?? this.client.getHttpUrl?.() ?? "https://api.fonoster.ai";
44
+ const qs = Object.entries(query)
45
+ .filter(([, v]) => v !== undefined && v !== null && v !== "")
46
+ .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)
47
+ .join("&");
48
+ return `${base}/api/records${path}${qs ? `?${qs}` : ""}`;
49
+ }
50
+ /** Sends a request, refreshing the access token once on 401. */
51
+ async send(path, init = {}) {
52
+ const attempt = () => this.fetchFn(this.url(path, init.query), {
53
+ method: init.method ?? "GET",
54
+ headers: {
55
+ authorization: `Bearer ${this.client.getAccessToken()}`,
56
+ "x-accesskey-id": this.client.getAccessKeyId(),
57
+ ...(init.body ? { "content-type": "application/json" } : {})
58
+ },
59
+ body: init.body ? JSON.stringify(init.body) : undefined
60
+ });
61
+ let res = await attempt();
62
+ if (res.status === 401) {
63
+ await this.client.refreshToken();
64
+ res = await attempt();
65
+ }
66
+ if (!res.ok) {
67
+ const body = (await res.json().catch(() => ({})));
68
+ throw new CallRecordsError(res.status, body.error ?? "error", body.message);
69
+ }
70
+ return res;
71
+ }
72
+ async json(path, init) {
73
+ return (await (await this.send(path, init)).json());
74
+ }
75
+ /** Searches the workspace's records, newest first. */
76
+ async listRecords(request = {}) {
77
+ return this.json("", { query: request });
78
+ }
79
+ /** One record; the latest version unless `version` is given. */
80
+ async getRecord(callRef, options = {}) {
81
+ return this.json(`/${encodeURIComponent(callRef)}`, {
82
+ query: {
83
+ version: options.version,
84
+ original: options.original ? "true" : undefined
85
+ }
86
+ });
87
+ }
88
+ /** The recording (WAV) with its content hash. */
89
+ async getRecording(callRef, options = {}) {
90
+ const res = await this.send(`/${encodeURIComponent(callRef)}/recording`, {
91
+ query: {
92
+ version: options.version,
93
+ original: options.original ? "true" : undefined
94
+ }
95
+ });
96
+ return {
97
+ data: await res.arrayBuffer(),
98
+ contentType: res.headers.get("content-type") ?? "audio/x-wav",
99
+ contentHash: res.headers.get("x-content-hash") ?? ""
100
+ };
101
+ }
102
+ /** Deletions and erasures of a record (owner or admin). */
103
+ async getAudit(callRef) {
104
+ const { items } = await this.json(`/${encodeURIComponent(callRef)}/audit`);
105
+ return items;
106
+ }
107
+ /** Erases the call: every object is deleted and a signed tombstone remains (owner or admin). */
108
+ async eraseRecord(callRef, reason) {
109
+ return this.json(`/${encodeURIComponent(callRef)}`, {
110
+ method: "DELETE",
111
+ body: reason ? { reason } : undefined
112
+ });
113
+ }
114
+ /** Deletes one part (recording, transcript, messages) of a record (owner or admin). */
115
+ async deletePart(callRef, part, reason) {
116
+ return this.json(`/${encodeURIComponent(callRef)}/parts/${encodeURIComponent(part)}`, { method: "DELETE", body: reason ? { reason } : undefined });
117
+ }
118
+ async getRetention() {
119
+ const { items } = await this.json("/retention");
120
+ return items;
121
+ }
122
+ /** Sets how many days a part is kept; `null` removes the policy (owner or admin). */
123
+ async setRetention(part, days) {
124
+ return this.json("/retention", { method: "PUT", body: { part, days } });
125
+ }
126
+ }
127
+ exports.CallRecords = CallRecords;
@@ -126,13 +126,15 @@ declare class Calls {
126
126
  * @param {ListCallsRequest} request - The request object that contains the necessary information to retrieve a list of Calls
127
127
  * @param {number} request.pageSize - The number of Calls to retrieve
128
128
  * @param {string} request.pageToken - The token to retrieve the next page of Calls
129
+ * @param {string} request.appRef - Optional. Lists only the Calls the App with this reference handled
129
130
  * @return {Promise<ListCallsResponse>} - The response object that contains the list of Calls
130
131
  * @example
131
132
  * const calls = new SDK.Calls(client); // Existing client object
132
133
  *
133
134
  * const request = {
134
135
  * pageSize: 10,
135
- * pageToken: "00000000-0000-0000-0000-000000000000"
136
+ * pageToken: "00000000-0000-0000-0000-000000000000",
137
+ * appRef: "00000000-0000-0000-0000-000000000000" // Optional: only this App's Calls
136
138
  * };
137
139
  *
138
140
  * calls
@@ -175,13 +175,15 @@ class Calls {
175
175
  * @param {ListCallsRequest} request - The request object that contains the necessary information to retrieve a list of Calls
176
176
  * @param {number} request.pageSize - The number of Calls to retrieve
177
177
  * @param {string} request.pageToken - The token to retrieve the next page of Calls
178
+ * @param {string} request.appRef - Optional. Lists only the Calls the App with this reference handled
178
179
  * @return {Promise<ListCallsResponse>} - The response object that contains the list of Calls
179
180
  * @example
180
181
  * const calls = new SDK.Calls(client); // Existing client object
181
182
  *
182
183
  * const request = {
183
184
  * pageSize: 10,
184
- * pageToken: "00000000-0000-0000-0000-000000000000"
185
+ * pageToken: "00000000-0000-0000-0000-000000000000",
186
+ * appRef: "00000000-0000-0000-0000-000000000000" // Optional: only this App's Calls
185
187
  * };
186
188
  *
187
189
  * calls
@@ -86,7 +86,8 @@ class Domains {
86
86
  method: client.createDomain.bind(client),
87
87
  requestPBObjectConstructor: domains_pb_1.CreateDomainRequest,
88
88
  metadata: this.client.getMetadata(),
89
- request
89
+ request,
90
+ objectMapping: [["egressPolicies", domains_pb_1.EgressPolicy]]
90
91
  });
91
92
  }
92
93
  /**
@@ -155,7 +156,8 @@ class Domains {
155
156
  method: client.updateDomain.bind(client),
156
157
  requestPBObjectConstructor: domains_pb_1.UpdateDomainRequest,
157
158
  metadata: this.client.getMetadata(),
158
- request
159
+ request,
160
+ objectMapping: [["egressPolicies", domains_pb_1.EgressPolicy]]
159
161
  });
160
162
  }
161
163
  /**
@@ -110,13 +110,8 @@ class Numbers {
110
110
  metadata: this.client.getMetadata(),
111
111
  request: { ref }
112
112
  });
113
- const trunk = response?.trunk?.toObject();
114
- return response
115
- ? {
116
- ...response,
117
- trunk
118
- }
119
- : null;
113
+ // The trunk comes back as a plain object (objectToJson).
114
+ return response ?? null;
120
115
  }
121
116
  /**
122
117
  * Updates an existing Number in the Workspace.
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
3
+ * http://github.com/fonoster/fonoster
4
+ *
5
+ * This file is part of Fonoster
6
+ *
7
+ * Licensed under the MIT License (the "License");
8
+ * you may not use this file except in compliance with
9
+ * the License. You may obtain a copy of the License at
10
+ *
11
+ * https://opensource.org/licenses/MIT
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ */
19
+ import { ListCatalogRequest, ListCatalogResponse, ListProviderKeysResponse, ListWarningsResponse, ProviderKey, SetProviderKeyRequest } from "@fonoster/types";
20
+ import { FonosterClient } from "./client/types";
21
+ /**
22
+ * @classdesc The provider catalog (read-only) and the workspace's own vendor keys. Catalog ids
23
+ * (`<provider>/<model-or-voice>`) are what apps use for speech defaults. A key is stored in a
24
+ * write-only Secret and never read back.
25
+ *
26
+ * @example
27
+ * const providers = new SDK.Providers(client);
28
+ * const { items } = await providers.listCatalog({ kind: "voice" });
29
+ * await providers.setProviderKey({ providerId: "deepgram", key: "dg-..." });
30
+ */
31
+ declare class Providers {
32
+ private readonly client;
33
+ constructor(client: FonosterClient);
34
+ /** Providers, models and voices this workspace can use (not retired). */
35
+ listCatalog(request?: ListCatalogRequest): Promise<ListCatalogResponse>;
36
+ /** Stores or replaces the workspace's key for a provider. */
37
+ setProviderKey(request: SetProviderKeyRequest): Promise<ProviderKey>;
38
+ listProviderKeys(): Promise<ListProviderKeysResponse>;
39
+ /**
40
+ * Deprecated or retired catalog items this workspace uses, with the saved configs that name
41
+ * them and the apps whose sessions used them lately (the dashboard's warnings).
42
+ */
43
+ listWarnings(): Promise<ListWarningsResponse>;
44
+ /** Removes the workspace's key for a provider (the platform key applies again). */
45
+ deleteProviderKey(providerId: string): Promise<{
46
+ providerId: string;
47
+ }>;
48
+ }
49
+ export { Providers };
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Providers = void 0;
4
+ const makeRpcRequest_1 = require("./client/makeRpcRequest");
5
+ const providers_pb_1 = require("./generated/node/providers_pb");
6
+ /** Repeated fields come back as `xList` when empty; normalize them and drop empty strings. */
7
+ function toItem(raw) {
8
+ const out = {};
9
+ for (const [key, value] of Object.entries(raw)) {
10
+ const name = key.endsWith("List") ? key.slice(0, -4) : key;
11
+ // Proto3 defaults: "" is unset, and keyless is false for anything but a keyless provider.
12
+ if (value === "" || (name === "keyless" && !value))
13
+ continue;
14
+ out[name] = value;
15
+ }
16
+ for (const list of ["capabilities", "languages", "features", "models"])
17
+ out[list] ??= [];
18
+ return out;
19
+ }
20
+ /**
21
+ * @classdesc The provider catalog (read-only) and the workspace's own vendor keys. Catalog ids
22
+ * (`<provider>/<model-or-voice>`) are what apps use for speech defaults. A key is stored in a
23
+ * write-only Secret and never read back.
24
+ *
25
+ * @example
26
+ * const providers = new SDK.Providers(client);
27
+ * const { items } = await providers.listCatalog({ kind: "voice" });
28
+ * await providers.setProviderKey({ providerId: "deepgram", key: "dg-..." });
29
+ */
30
+ class Providers {
31
+ client;
32
+ constructor(client) {
33
+ this.client = client;
34
+ }
35
+ /** Providers, models and voices this workspace can use (not retired). */
36
+ async listCatalog(request = {}) {
37
+ const client = this.client.getProvidersClient();
38
+ const raw = await (0, makeRpcRequest_1.makeRpcRequest)({
39
+ method: client.listCatalog.bind(client),
40
+ requestPBObjectConstructor: providers_pb_1.ListCatalogRequest,
41
+ metadata: this.client.getMetadata(),
42
+ request,
43
+ repeatableObjectMapping: [["itemsList", providers_pb_1.CatalogItem]]
44
+ });
45
+ return { items: (raw.items ?? []).map(toItem) };
46
+ }
47
+ /** Stores or replaces the workspace's key for a provider. */
48
+ async setProviderKey(request) {
49
+ const client = this.client.getProvidersClient();
50
+ return await (0, makeRpcRequest_1.makeRpcRequest)({
51
+ method: client.setProviderKey.bind(client),
52
+ requestPBObjectConstructor: providers_pb_1.SetProviderKeyRequest,
53
+ metadata: this.client.getMetadata(),
54
+ request
55
+ });
56
+ }
57
+ async listProviderKeys() {
58
+ const client = this.client.getProvidersClient();
59
+ const raw = await (0, makeRpcRequest_1.makeRpcRequest)({
60
+ method: client.listProviderKeys.bind(client),
61
+ requestPBObjectConstructor: providers_pb_1.ListProviderKeysRequest,
62
+ metadata: this.client.getMetadata(),
63
+ request: {},
64
+ repeatableObjectMapping: [["itemsList", providers_pb_1.ProviderKey]]
65
+ });
66
+ return { items: raw.items ?? [] };
67
+ }
68
+ /**
69
+ * Deprecated or retired catalog items this workspace uses, with the saved configs that name
70
+ * them and the apps whose sessions used them lately (the dashboard's warnings).
71
+ */
72
+ async listWarnings() {
73
+ const client = this.client.getProvidersClient();
74
+ const raw = await (0, makeRpcRequest_1.makeRpcRequest)({
75
+ method: client.listWarnings.bind(client),
76
+ requestPBObjectConstructor: providers_pb_1.ListWarningsRequest,
77
+ metadata: this.client.getMetadata(),
78
+ request: {},
79
+ repeatableObjectMapping: [["itemsList", providers_pb_1.Warning]]
80
+ });
81
+ return {
82
+ items: (raw.items ?? []).map((w) => {
83
+ const out = {};
84
+ for (const [key, value] of Object.entries(w)) {
85
+ const name = key.endsWith("List") ? key.slice(0, -4) : key;
86
+ // Proto3 defaults: "" is unset, and keyless is false for anything but a keyless provider.
87
+ if (value === "" || (name === "keyless" && !value))
88
+ continue;
89
+ out[name] = value;
90
+ }
91
+ out.usedBy ??= [];
92
+ out.runtimeApps ??= [];
93
+ out.runtimeSessions ??= 0;
94
+ return out;
95
+ })
96
+ };
97
+ }
98
+ /** Removes the workspace's key for a provider (the platform key applies again). */
99
+ async deleteProviderKey(providerId) {
100
+ const client = this.client.getProvidersClient();
101
+ return await (0, makeRpcRequest_1.makeRpcRequest)({
102
+ method: client.deleteProviderKey.bind(client),
103
+ requestPBObjectConstructor: providers_pb_1.DeleteProviderKeyRequest,
104
+ metadata: this.client.getMetadata(),
105
+ request: { providerId }
106
+ });
107
+ }
108
+ }
109
+ exports.Providers = Providers;
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
3
+ * http://github.com/fonoster/fonoster
4
+ *
5
+ * This file is part of Fonoster
6
+ *
7
+ * Licensed under the MIT License (the "License");
8
+ * you may not use this file except in compliance with
9
+ * the License. You may obtain a copy of the License at
10
+ *
11
+ * https://opensource.org/licenses/MIT
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ */
19
+ import { CreateRegionRequest, CreateRegionResponse, ListRegionsResponse, Region, RegionEnrollmentToken } from "@fonoster/types";
20
+ import { FonosterClient } from "./client/types";
21
+ type FetchLike = (url: string, init?: {
22
+ method?: string;
23
+ headers?: Record<string, string>;
24
+ body?: string;
25
+ }) => Promise<{
26
+ ok: boolean;
27
+ status: number;
28
+ json(): Promise<unknown>;
29
+ }>;
30
+ /** An error answer from the regions API (status and its `error` code). */
31
+ declare class RegionsError extends Error {
32
+ readonly status: number;
33
+ readonly code: string;
34
+ constructor(status: number, code: string, message?: string);
35
+ }
36
+ /**
37
+ * @classdesc Regions (add-private-regions, PR-12..PR-21) through the HTTP API (`/api/regions`).
38
+ * Regions belong to the signed-in user: create a private region (id, display name, SIP domain),
39
+ * get its one-time enrollment token, watch its status, re-issue the token, disconnect or delete
40
+ * it. A workspace picks a region when it is created (`workspaces.createWorkspace({name, region})`).
41
+ *
42
+ * @example
43
+ * const regions = new SDK.Regions(client);
44
+ * const { items } = await regions.listRegions();
45
+ * const { ref, token } = await regions.createRegion({
46
+ * id: "acme-hq", displayName: "Acme HQ", sipDomain: "sip.acme.com"
47
+ * });
48
+ * const region = await regions.getRegion("acme-hq");
49
+ */
50
+ declare class Regions {
51
+ private readonly client;
52
+ private readonly baseUrl?;
53
+ private readonly fetchFn;
54
+ constructor(client: FonosterClient, options?: {
55
+ baseUrl?: string;
56
+ fetch?: FetchLike;
57
+ });
58
+ private headers;
59
+ private json;
60
+ private static path;
61
+ /**
62
+ * The regions a new workspace can pick: the offered public regions and, when signed in, your
63
+ * private regions (with status).
64
+ */
65
+ listRegions(): Promise<ListRegionsResponse>;
66
+ /**
67
+ * Creates a private region (PR-15, PR-16, PR-18). The token (`token`, also `enrollmentToken`)
68
+ * is returned once; run `fonoster-region enroll <token>` on the region machine.
69
+ */
70
+ createRegion(request: CreateRegionRequest): Promise<CreateRegionResponse>;
71
+ /**
72
+ * One region by id or ref; without an argument, the current workspace's region (its status,
73
+ * secrets and connection details).
74
+ */
75
+ getRegion(region?: string): Promise<Region>;
76
+ /** Changes a private region's display name (the id never changes). */
77
+ updateRegion(region: string, request: {
78
+ displayName: string;
79
+ }): Promise<Region>;
80
+ /** A new one-time enrollment token; enrolling with it revokes the current cell. */
81
+ reissueRegionToken(region?: string): Promise<RegionEnrollmentToken>;
82
+ /** Revokes the region's cell now; the region goes back to `waiting`. */
83
+ disconnectRegion(region?: string): Promise<void>;
84
+ /** Deletes a private region; refused (`region_in_use`) while any workspace uses it. */
85
+ deleteRegion(region: string): Promise<{
86
+ ref: string;
87
+ }>;
88
+ /** The given region, or the current workspace's region. */
89
+ private refOf;
90
+ }
91
+ export { Regions, RegionsError };