@fonoster/sdk 0.26.0 → 0.30.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/README.md +6 -5
- package/dist/node/Applications.d.ts +21 -85
- package/dist/node/Applications.js +55 -73
- package/dist/node/CallRecords.d.ts +92 -0
- package/dist/node/CallRecords.js +124 -0
- package/dist/node/Domains.js +4 -2
- package/dist/node/Providers.d.ts +49 -0
- package/dist/node/Providers.js +107 -0
- package/dist/node/Regions.d.ts +91 -0
- package/dist/node/Regions.js +124 -0
- package/dist/node/Users.d.ts +4 -2
- package/dist/node/Users.js +4 -2
- package/dist/node/Webhooks.d.ts +56 -0
- package/dist/node/Webhooks.js +139 -0
- package/dist/node/Workspaces.d.ts +22 -3
- package/dist/node/Workspaces.js +29 -2
- package/dist/node/client/AbstractClient.d.ts +83 -3
- package/dist/node/client/AbstractClient.js +97 -1
- package/dist/node/client/Client.d.ts +7 -0
- package/dist/node/client/Client.js +21 -0
- package/dist/node/client/jsonToObject.js +17 -0
- package/dist/node/client/objectToJson.js +35 -0
- package/dist/node/client/types/ApplicationsClient.d.ts +2 -1
- package/dist/node/client/types/CapabilitiesClient.d.ts +24 -0
- package/dist/node/client/types/CapabilitiesClient.js +2 -0
- package/dist/node/client/types/FonosterClient.d.ts +8 -0
- package/dist/node/client/types/IdentityClient.d.ts +3 -1
- package/dist/node/client/types/ProvidersClient.d.ts +28 -0
- package/dist/node/client/types/ProvidersClient.js +2 -0
- package/dist/node/client/types/WebhooksClient.d.ts +31 -0
- package/dist/node/client/types/WebhooksClient.js +2 -0
- package/dist/node/client/types/index.d.ts +3 -0
- package/dist/node/client/types/index.js +3 -0
- package/dist/node/generated/node/applications_grpc_pb.js +34 -0
- package/dist/node/generated/node/applications_pb.js +2657 -206
- package/dist/node/generated/node/capabilities_grpc_pb.js +66 -0
- package/dist/node/generated/node/capabilities_pb.js +2085 -0
- package/dist/node/generated/node/identity_grpc_pb.js +34 -0
- package/dist/node/generated/node/identity_pb.js +609 -5
- package/dist/node/generated/node/providers_grpc_pb.js +200 -0
- package/dist/node/generated/node/providers_pb.js +3034 -0
- package/dist/node/generated/node/webhooks_grpc_pb.js +302 -0
- package/dist/node/generated/node/webhooks_pb.js +3314 -0
- package/dist/node/generated/web/ApplicationsServiceClientPb.ts +43 -0
- package/dist/node/generated/web/CapabilitiesServiceClientPb.ts +87 -0
- package/dist/node/generated/web/IdentityServiceClientPb.ts +43 -0
- package/dist/node/generated/web/ProvidersServiceClientPb.ts +258 -0
- package/dist/node/generated/web/WebhooksServiceClientPb.ts +387 -0
- package/dist/node/generated/web/applications_pb.d.ts +301 -1
- package/dist/node/generated/web/applications_pb.js +2657 -206
- package/dist/node/generated/web/capabilities_pb.d.ts +249 -0
- package/dist/node/generated/web/capabilities_pb.js +2085 -0
- package/dist/node/generated/web/identity_pb.d.ts +76 -0
- package/dist/node/generated/web/identity_pb.js +609 -5
- package/dist/node/generated/web/providers_pb.d.ts +364 -0
- package/dist/node/generated/web/providers_pb.js +3034 -0
- package/dist/node/generated/web/webhooks_pb.d.ts +398 -0
- package/dist/node/generated/web/webhooks_pb.js +3314 -0
- package/dist/node/node.d.ts +5 -0
- package/dist/node/node.js +4 -0
- package/dist/node/tsconfig.tsbuildinfo +1 -1
- package/dist/node/utils.d.ts +1 -13
- package/dist/node/utils.js +1 -38
- package/dist/web/fonoster.min.js +1 -1
- package/dist/web/index.esm.js +1 -1
- package/package.json +5 -5
package/dist/node/Domains.js
CHANGED
|
@@ -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
|
/**
|
|
@@ -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,107 @@
|
|
|
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
|
+
if (value === "")
|
|
12
|
+
continue;
|
|
13
|
+
out[name] = value;
|
|
14
|
+
}
|
|
15
|
+
for (const list of ["capabilities", "languages", "features", "models"])
|
|
16
|
+
out[list] ??= [];
|
|
17
|
+
return out;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* @classdesc The provider catalog (read-only) and the workspace's own vendor keys. Catalog ids
|
|
21
|
+
* (`<provider>/<model-or-voice>`) are what apps use for speech defaults. A key is stored in a
|
|
22
|
+
* write-only Secret and never read back.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* const providers = new SDK.Providers(client);
|
|
26
|
+
* const { items } = await providers.listCatalog({ kind: "voice" });
|
|
27
|
+
* await providers.setProviderKey({ providerId: "deepgram", key: "dg-..." });
|
|
28
|
+
*/
|
|
29
|
+
class Providers {
|
|
30
|
+
client;
|
|
31
|
+
constructor(client) {
|
|
32
|
+
this.client = client;
|
|
33
|
+
}
|
|
34
|
+
/** Providers, models and voices this workspace can use (not retired). */
|
|
35
|
+
async listCatalog(request = {}) {
|
|
36
|
+
const client = this.client.getProvidersClient();
|
|
37
|
+
const raw = await (0, makeRpcRequest_1.makeRpcRequest)({
|
|
38
|
+
method: client.listCatalog.bind(client),
|
|
39
|
+
requestPBObjectConstructor: providers_pb_1.ListCatalogRequest,
|
|
40
|
+
metadata: this.client.getMetadata(),
|
|
41
|
+
request,
|
|
42
|
+
repeatableObjectMapping: [["itemsList", providers_pb_1.CatalogItem]]
|
|
43
|
+
});
|
|
44
|
+
return { items: (raw.items ?? []).map(toItem) };
|
|
45
|
+
}
|
|
46
|
+
/** Stores or replaces the workspace's key for a provider. */
|
|
47
|
+
async setProviderKey(request) {
|
|
48
|
+
const client = this.client.getProvidersClient();
|
|
49
|
+
return await (0, makeRpcRequest_1.makeRpcRequest)({
|
|
50
|
+
method: client.setProviderKey.bind(client),
|
|
51
|
+
requestPBObjectConstructor: providers_pb_1.SetProviderKeyRequest,
|
|
52
|
+
metadata: this.client.getMetadata(),
|
|
53
|
+
request
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
async listProviderKeys() {
|
|
57
|
+
const client = this.client.getProvidersClient();
|
|
58
|
+
const raw = await (0, makeRpcRequest_1.makeRpcRequest)({
|
|
59
|
+
method: client.listProviderKeys.bind(client),
|
|
60
|
+
requestPBObjectConstructor: providers_pb_1.ListProviderKeysRequest,
|
|
61
|
+
metadata: this.client.getMetadata(),
|
|
62
|
+
request: {},
|
|
63
|
+
repeatableObjectMapping: [["itemsList", providers_pb_1.ProviderKey]]
|
|
64
|
+
});
|
|
65
|
+
return { items: raw.items ?? [] };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Deprecated or retired catalog items this workspace uses, with the saved configs that name
|
|
69
|
+
* them and the apps whose sessions used them lately (the dashboard's warnings).
|
|
70
|
+
*/
|
|
71
|
+
async listWarnings() {
|
|
72
|
+
const client = this.client.getProvidersClient();
|
|
73
|
+
const raw = await (0, makeRpcRequest_1.makeRpcRequest)({
|
|
74
|
+
method: client.listWarnings.bind(client),
|
|
75
|
+
requestPBObjectConstructor: providers_pb_1.ListWarningsRequest,
|
|
76
|
+
metadata: this.client.getMetadata(),
|
|
77
|
+
request: {},
|
|
78
|
+
repeatableObjectMapping: [["itemsList", providers_pb_1.Warning]]
|
|
79
|
+
});
|
|
80
|
+
return {
|
|
81
|
+
items: (raw.items ?? []).map((w) => {
|
|
82
|
+
const out = {};
|
|
83
|
+
for (const [key, value] of Object.entries(w)) {
|
|
84
|
+
const name = key.endsWith("List") ? key.slice(0, -4) : key;
|
|
85
|
+
if (value === "")
|
|
86
|
+
continue;
|
|
87
|
+
out[name] = value;
|
|
88
|
+
}
|
|
89
|
+
out.usedBy ??= [];
|
|
90
|
+
out.runtimeApps ??= [];
|
|
91
|
+
out.runtimeSessions ??= 0;
|
|
92
|
+
return out;
|
|
93
|
+
})
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/** Removes the workspace's key for a provider (the platform key applies again). */
|
|
97
|
+
async deleteProviderKey(providerId) {
|
|
98
|
+
const client = this.client.getProvidersClient();
|
|
99
|
+
return await (0, makeRpcRequest_1.makeRpcRequest)({
|
|
100
|
+
method: client.deleteProviderKey.bind(client),
|
|
101
|
+
requestPBObjectConstructor: providers_pb_1.DeleteProviderKeyRequest,
|
|
102
|
+
metadata: this.client.getMetadata(),
|
|
103
|
+
request: { providerId }
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
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 };
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RegionsError = exports.Regions = void 0;
|
|
4
|
+
/** An error answer from the regions API (status and its `error` code). */
|
|
5
|
+
class RegionsError extends Error {
|
|
6
|
+
status;
|
|
7
|
+
code;
|
|
8
|
+
constructor(status, code, message) {
|
|
9
|
+
super(message ?? `regions API: ${status} ${code}`);
|
|
10
|
+
this.status = status;
|
|
11
|
+
this.code = code;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.RegionsError = RegionsError;
|
|
15
|
+
/**
|
|
16
|
+
* @classdesc Regions (add-private-regions, PR-12..PR-21) through the HTTP API (`/api/regions`).
|
|
17
|
+
* Regions belong to the signed-in user: create a private region (id, display name, SIP domain),
|
|
18
|
+
* get its one-time enrollment token, watch its status, re-issue the token, disconnect or delete
|
|
19
|
+
* it. A workspace picks a region when it is created (`workspaces.createWorkspace({name, region})`).
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* const regions = new SDK.Regions(client);
|
|
23
|
+
* const { items } = await regions.listRegions();
|
|
24
|
+
* const { ref, token } = await regions.createRegion({
|
|
25
|
+
* id: "acme-hq", displayName: "Acme HQ", sipDomain: "sip.acme.com"
|
|
26
|
+
* });
|
|
27
|
+
* const region = await regions.getRegion("acme-hq");
|
|
28
|
+
*/
|
|
29
|
+
class Regions {
|
|
30
|
+
client;
|
|
31
|
+
baseUrl;
|
|
32
|
+
fetchFn;
|
|
33
|
+
constructor(client, options = {}) {
|
|
34
|
+
this.client = client;
|
|
35
|
+
this.baseUrl = options.baseUrl?.replace(/\/+$/, "");
|
|
36
|
+
this.fetchFn =
|
|
37
|
+
options.fetch ?? globalThis.fetch;
|
|
38
|
+
}
|
|
39
|
+
headers(auth, body) {
|
|
40
|
+
const h = {};
|
|
41
|
+
if (body !== undefined)
|
|
42
|
+
h["content-type"] = "application/json";
|
|
43
|
+
if (!auth)
|
|
44
|
+
return h;
|
|
45
|
+
const token = this.client.getAccessToken?.();
|
|
46
|
+
if (token)
|
|
47
|
+
h.authorization = `Bearer ${token}`;
|
|
48
|
+
const accessKeyId = this.client.getAccessKeyId?.();
|
|
49
|
+
if (accessKeyId)
|
|
50
|
+
h["x-accesskey-id"] = accessKeyId;
|
|
51
|
+
return h;
|
|
52
|
+
}
|
|
53
|
+
async json(path, method = "GET", body, auth = true) {
|
|
54
|
+
const base = this.baseUrl ?? this.client.getHttpUrl?.() ?? "https://api.fonoster.com";
|
|
55
|
+
const attempt = () => this.fetchFn(`${base}/api/regions${path}`, {
|
|
56
|
+
method,
|
|
57
|
+
headers: this.headers(auth, body),
|
|
58
|
+
...(body !== undefined ? { body: JSON.stringify(body) } : {})
|
|
59
|
+
});
|
|
60
|
+
let res = await attempt();
|
|
61
|
+
if (res.status === 401 && auth) {
|
|
62
|
+
await this.client.refreshToken();
|
|
63
|
+
res = await attempt();
|
|
64
|
+
}
|
|
65
|
+
const out = (await res.json().catch(() => ({})));
|
|
66
|
+
if (!res.ok)
|
|
67
|
+
throw new RegionsError(res.status, String(out.error ?? "error"), out.message);
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
static path(region) {
|
|
71
|
+
return `/${encodeURIComponent(region)}`;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The regions a new workspace can pick: the offered public regions and, when signed in, your
|
|
75
|
+
* private regions (with status).
|
|
76
|
+
*/
|
|
77
|
+
async listRegions() {
|
|
78
|
+
let signedIn = false;
|
|
79
|
+
try {
|
|
80
|
+
signedIn = !!this.client.getAccessToken?.();
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
signedIn = false;
|
|
84
|
+
}
|
|
85
|
+
return this.json("", "GET", undefined, signedIn);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Creates a private region (PR-15, PR-16, PR-18). The token (`token`, also `enrollmentToken`)
|
|
89
|
+
* is returned once; run `fonoster-region enroll <token>` on the region machine.
|
|
90
|
+
*/
|
|
91
|
+
async createRegion(request) {
|
|
92
|
+
return this.json("", "POST", request);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* One region by id or ref; without an argument, the current workspace's region (its status,
|
|
96
|
+
* secrets and connection details).
|
|
97
|
+
*/
|
|
98
|
+
async getRegion(region) {
|
|
99
|
+
return this.json(region ? Regions.path(region) : "/current");
|
|
100
|
+
}
|
|
101
|
+
/** Changes a private region's display name (the id never changes). */
|
|
102
|
+
async updateRegion(region, request) {
|
|
103
|
+
return this.json(Regions.path(region), "PATCH", request);
|
|
104
|
+
}
|
|
105
|
+
/** A new one-time enrollment token; enrolling with it revokes the current cell. */
|
|
106
|
+
async reissueRegionToken(region) {
|
|
107
|
+
return this.json(`${Regions.path(await this.refOf(region))}/token`, "POST");
|
|
108
|
+
}
|
|
109
|
+
/** Revokes the region's cell now; the region goes back to `waiting`. */
|
|
110
|
+
async disconnectRegion(region) {
|
|
111
|
+
await this.json(`${Regions.path(await this.refOf(region))}/disconnect`, "POST");
|
|
112
|
+
}
|
|
113
|
+
/** Deletes a private region; refused (`region_in_use`) while any workspace uses it. */
|
|
114
|
+
async deleteRegion(region) {
|
|
115
|
+
return this.json(Regions.path(region), "DELETE");
|
|
116
|
+
}
|
|
117
|
+
/** The given region, or the current workspace's region. */
|
|
118
|
+
async refOf(region) {
|
|
119
|
+
if (region)
|
|
120
|
+
return region;
|
|
121
|
+
return (await this.getRegion()).ref;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
exports.Regions = Regions;
|
package/dist/node/Users.d.ts
CHANGED
|
@@ -117,7 +117,8 @@ declare class Users {
|
|
|
117
117
|
* @param {UpdateUserRequest} request - The request object that contains the necessary information to update a User
|
|
118
118
|
* @param {string} request.ref - The reference of the User to update
|
|
119
119
|
* @param {string} [request.name] - The name of the User
|
|
120
|
-
* @param {string} [request.password] -
|
|
120
|
+
* @param {string} [request.password] - A new password for the User; requires currentPassword and signs the User out everywhere
|
|
121
|
+
* @param {string} [request.currentPassword] - The User's current password, required to set a new one
|
|
121
122
|
* @param {string} [request.avatar] - The avatar of the User
|
|
122
123
|
* @param {string} [request.phone] - The phone number of the User (optional)
|
|
123
124
|
* @return {Promise<BaseApiObject>} - The response object that contains the reference to the updated User
|
|
@@ -127,7 +128,8 @@ declare class Users {
|
|
|
127
128
|
* const request = {
|
|
128
129
|
* ref: "00000000-0000-0000-0000-000000000000",
|
|
129
130
|
* name: "John Doe",
|
|
130
|
-
* password: "password",
|
|
131
|
+
* password: "a-new-password",
|
|
132
|
+
* currentPassword: "the-current-password",
|
|
131
133
|
* avatar: "https://example.com/avatar.jpg",
|
|
132
134
|
* phone: "+1234567890"
|
|
133
135
|
* };
|
package/dist/node/Users.js
CHANGED
|
@@ -128,7 +128,8 @@ class Users {
|
|
|
128
128
|
* @param {UpdateUserRequest} request - The request object that contains the necessary information to update a User
|
|
129
129
|
* @param {string} request.ref - The reference of the User to update
|
|
130
130
|
* @param {string} [request.name] - The name of the User
|
|
131
|
-
* @param {string} [request.password] -
|
|
131
|
+
* @param {string} [request.password] - A new password for the User; requires currentPassword and signs the User out everywhere
|
|
132
|
+
* @param {string} [request.currentPassword] - The User's current password, required to set a new one
|
|
132
133
|
* @param {string} [request.avatar] - The avatar of the User
|
|
133
134
|
* @param {string} [request.phone] - The phone number of the User (optional)
|
|
134
135
|
* @return {Promise<BaseApiObject>} - The response object that contains the reference to the updated User
|
|
@@ -138,7 +139,8 @@ class Users {
|
|
|
138
139
|
* const request = {
|
|
139
140
|
* ref: "00000000-0000-0000-0000-000000000000",
|
|
140
141
|
* name: "John Doe",
|
|
141
|
-
* password: "password",
|
|
142
|
+
* password: "a-new-password",
|
|
143
|
+
* currentPassword: "the-current-password",
|
|
142
144
|
* avatar: "https://example.com/avatar.jpg",
|
|
143
145
|
* phone: "+1234567890"
|
|
144
146
|
* };
|
|
@@ -0,0 +1,56 @@
|
|
|
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 { BaseApiObject, CreateWebhookRequest, CreateWebhookResponse, ListWebhookDeliveriesRequest, ListWebhookDeliveriesResponse, ListWebhooksRequest, ListWebhooksResponse, RotateWebhookSecretResponse, UpdateWebhookRequest, Webhook, WebhookDelivery } from "@fonoster/types";
|
|
20
|
+
import { FonosterClient } from "./client/types";
|
|
21
|
+
/**
|
|
22
|
+
* @classdesc Fonoster Webhooks, a capability of Fonoster's Workspaces. Webhooks receive call
|
|
23
|
+
* events (call.started, call.ended, call.failed, call_record.sealed, provider.deprecated),
|
|
24
|
+
* signed with the endpoint's secret.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* const SDK = require("@fonoster/sdk");
|
|
28
|
+
*
|
|
29
|
+
* async function main() {
|
|
30
|
+
* const client = new SDK.Client({ accessKeyId: "WO00000000000000000000000000000000" });
|
|
31
|
+
* await client.loginWithApiKey("APXXXXXXXXXXXXXXXX", "YYYYYYYYYYYYYYYYY");
|
|
32
|
+
* const webhooks = new SDK.Webhooks(client);
|
|
33
|
+
* const { ref, secret } = await webhooks.createWebhook({
|
|
34
|
+
* url: "https://example.com/fonoster",
|
|
35
|
+
* events: ["call.ended"]
|
|
36
|
+
* });
|
|
37
|
+
* }
|
|
38
|
+
*/
|
|
39
|
+
declare class Webhooks {
|
|
40
|
+
private readonly client;
|
|
41
|
+
constructor(client: FonosterClient);
|
|
42
|
+
/** Creates an endpoint. The secret is returned only here and on rotation. */
|
|
43
|
+
createWebhook(request: CreateWebhookRequest): Promise<CreateWebhookResponse>;
|
|
44
|
+
getWebhook(ref: string): Promise<Webhook>;
|
|
45
|
+
listWebhooks(request?: ListWebhooksRequest): Promise<ListWebhooksResponse>;
|
|
46
|
+
/** Changes the URL and/or events; fields left out are kept. */
|
|
47
|
+
updateWebhook(request: UpdateWebhookRequest): Promise<BaseApiObject>;
|
|
48
|
+
deleteWebhook(ref: string): Promise<BaseApiObject>;
|
|
49
|
+
/** A new secret; the previous one keeps verifying for 24 hours. */
|
|
50
|
+
rotateWebhookSecret(ref: string): Promise<RotateWebhookSecretResponse>;
|
|
51
|
+
/** The delivery log, newest first (optionally one endpoint's). */
|
|
52
|
+
listWebhookDeliveries(request?: ListWebhookDeliveriesRequest): Promise<ListWebhookDeliveriesResponse>;
|
|
53
|
+
/** Sends a delivery again now, with the same event id and a fresh signature. */
|
|
54
|
+
resendWebhookDelivery(ref: string): Promise<WebhookDelivery>;
|
|
55
|
+
}
|
|
56
|
+
export { Webhooks };
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Webhooks = void 0;
|
|
4
|
+
const makeRpcRequest_1 = require("./client/makeRpcRequest");
|
|
5
|
+
const webhooks_pb_1 = require("./generated/node/webhooks_pb");
|
|
6
|
+
const date = (seconds) => typeof seconds === "number" && seconds > 0
|
|
7
|
+
? new Date(seconds * 1000)
|
|
8
|
+
: undefined;
|
|
9
|
+
function toWebhook(raw) {
|
|
10
|
+
const { eventsList, previousSecretUntil, ...rest } = raw;
|
|
11
|
+
return {
|
|
12
|
+
...rest,
|
|
13
|
+
events: (raw.events ?? eventsList ?? []),
|
|
14
|
+
previousSecretUntil: date(previousSecretUntil)
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function toDelivery(raw) {
|
|
18
|
+
return {
|
|
19
|
+
...raw,
|
|
20
|
+
lastAttemptAt: date(raw.lastAttemptAt),
|
|
21
|
+
nextAttemptAt: date(raw.nextAttemptAt)
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* @classdesc Fonoster Webhooks, a capability of Fonoster's Workspaces. Webhooks receive call
|
|
26
|
+
* events (call.started, call.ended, call.failed, call_record.sealed, provider.deprecated),
|
|
27
|
+
* signed with the endpoint's secret.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* const SDK = require("@fonoster/sdk");
|
|
31
|
+
*
|
|
32
|
+
* async function main() {
|
|
33
|
+
* const client = new SDK.Client({ accessKeyId: "WO00000000000000000000000000000000" });
|
|
34
|
+
* await client.loginWithApiKey("APXXXXXXXXXXXXXXXX", "YYYYYYYYYYYYYYYYY");
|
|
35
|
+
* const webhooks = new SDK.Webhooks(client);
|
|
36
|
+
* const { ref, secret } = await webhooks.createWebhook({
|
|
37
|
+
* url: "https://example.com/fonoster",
|
|
38
|
+
* events: ["call.ended"]
|
|
39
|
+
* });
|
|
40
|
+
* }
|
|
41
|
+
*/
|
|
42
|
+
class Webhooks {
|
|
43
|
+
client;
|
|
44
|
+
constructor(client) {
|
|
45
|
+
this.client = client;
|
|
46
|
+
}
|
|
47
|
+
/** Creates an endpoint. The secret is returned only here and on rotation. */
|
|
48
|
+
async createWebhook(request) {
|
|
49
|
+
const client = this.client.getWebhooksClient();
|
|
50
|
+
return await (0, makeRpcRequest_1.makeRpcRequest)({
|
|
51
|
+
method: client.createWebhook.bind(client),
|
|
52
|
+
requestPBObjectConstructor: webhooks_pb_1.CreateWebhookRequest,
|
|
53
|
+
metadata: this.client.getMetadata(),
|
|
54
|
+
request
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
async getWebhook(ref) {
|
|
58
|
+
const client = this.client.getWebhooksClient();
|
|
59
|
+
const raw = await (0, makeRpcRequest_1.makeRpcRequest)({
|
|
60
|
+
method: client.getWebhook.bind(client),
|
|
61
|
+
requestPBObjectConstructor: webhooks_pb_1.GetWebhookRequest,
|
|
62
|
+
metadata: this.client.getMetadata(),
|
|
63
|
+
request: { ref }
|
|
64
|
+
});
|
|
65
|
+
return toWebhook(raw);
|
|
66
|
+
}
|
|
67
|
+
async listWebhooks(request = {}) {
|
|
68
|
+
const client = this.client.getWebhooksClient();
|
|
69
|
+
const raw = await (0, makeRpcRequest_1.makeRpcRequest)({
|
|
70
|
+
method: client.listWebhooks.bind(client),
|
|
71
|
+
requestPBObjectConstructor: webhooks_pb_1.ListWebhooksRequest,
|
|
72
|
+
metadata: this.client.getMetadata(),
|
|
73
|
+
request,
|
|
74
|
+
repeatableObjectMapping: [["itemsList", webhooks_pb_1.Webhook]]
|
|
75
|
+
});
|
|
76
|
+
return {
|
|
77
|
+
items: (raw.items ?? []).map(toWebhook),
|
|
78
|
+
nextPageToken: raw.nextPageToken
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/** Changes the URL and/or events; fields left out are kept. */
|
|
82
|
+
async updateWebhook(request) {
|
|
83
|
+
const client = this.client.getWebhooksClient();
|
|
84
|
+
return await (0, makeRpcRequest_1.makeRpcRequest)({
|
|
85
|
+
method: client.updateWebhook.bind(client),
|
|
86
|
+
requestPBObjectConstructor: webhooks_pb_1.UpdateWebhookRequest,
|
|
87
|
+
metadata: this.client.getMetadata(),
|
|
88
|
+
request
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
async deleteWebhook(ref) {
|
|
92
|
+
const client = this.client.getWebhooksClient();
|
|
93
|
+
return await (0, makeRpcRequest_1.makeRpcRequest)({
|
|
94
|
+
method: client.deleteWebhook.bind(client),
|
|
95
|
+
requestPBObjectConstructor: webhooks_pb_1.DeleteWebhookRequest,
|
|
96
|
+
metadata: this.client.getMetadata(),
|
|
97
|
+
request: { ref }
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
/** A new secret; the previous one keeps verifying for 24 hours. */
|
|
101
|
+
async rotateWebhookSecret(ref) {
|
|
102
|
+
const client = this.client.getWebhooksClient();
|
|
103
|
+
const raw = await (0, makeRpcRequest_1.makeRpcRequest)({
|
|
104
|
+
method: client.rotateWebhookSecret.bind(client),
|
|
105
|
+
requestPBObjectConstructor: webhooks_pb_1.RotateWebhookSecretRequest,
|
|
106
|
+
metadata: this.client.getMetadata(),
|
|
107
|
+
request: { ref }
|
|
108
|
+
});
|
|
109
|
+
return {
|
|
110
|
+
ref: raw.ref,
|
|
111
|
+
secret: raw.secret,
|
|
112
|
+
previousSecretUntil: date(raw.previousSecretUntil)
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/** The delivery log, newest first (optionally one endpoint's). */
|
|
116
|
+
async listWebhookDeliveries(request = {}) {
|
|
117
|
+
const client = this.client.getWebhooksClient();
|
|
118
|
+
const raw = await (0, makeRpcRequest_1.makeRpcRequest)({
|
|
119
|
+
method: client.listWebhookDeliveries.bind(client),
|
|
120
|
+
requestPBObjectConstructor: webhooks_pb_1.ListWebhookDeliveriesRequest,
|
|
121
|
+
metadata: this.client.getMetadata(),
|
|
122
|
+
request,
|
|
123
|
+
repeatableObjectMapping: [["itemsList", webhooks_pb_1.WebhookDelivery]]
|
|
124
|
+
});
|
|
125
|
+
return { items: (raw.items ?? []).map(toDelivery) };
|
|
126
|
+
}
|
|
127
|
+
/** Sends a delivery again now, with the same event id and a fresh signature. */
|
|
128
|
+
async resendWebhookDelivery(ref) {
|
|
129
|
+
const client = this.client.getWebhooksClient();
|
|
130
|
+
const raw = await (0, makeRpcRequest_1.makeRpcRequest)({
|
|
131
|
+
method: client.resendWebhookDelivery.bind(client),
|
|
132
|
+
requestPBObjectConstructor: webhooks_pb_1.ResendWebhookDeliveryRequest,
|
|
133
|
+
metadata: this.client.getMetadata(),
|
|
134
|
+
request: { ref }
|
|
135
|
+
});
|
|
136
|
+
return toDelivery(raw);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
exports.Webhooks = Webhooks;
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* See the License for the specific language governing permissions and
|
|
17
17
|
* limitations under the License.
|
|
18
18
|
*/
|
|
19
|
-
import { BaseApiObject, CreateWorkspaceRequest, InviteUserToWorkspaceRequest, ListWorkspaceMembersRequest, ListWorkspaceMembersResponse, ListWorkspacesResponse, RemoveUserFromWorkspaceResponse, ResendWorkspaceMembershipInvitationResponse, UpdateWorkspaceRequest, Workspace } from "@fonoster/types";
|
|
19
|
+
import { BaseApiObject, CreateWorkspaceRequest, CreateWorkspaceResponse, InviteUserToWorkspaceRequest, ListWorkspaceMembersRequest, ListWorkspaceMembersResponse, ListWorkspacesResponse, Region, RegionEnrollmentToken, RemoveUserFromWorkspaceResponse, ResendWorkspaceMembershipInvitationResponse, UpdateWorkspaceRequest, Workspace } from "@fonoster/types";
|
|
20
20
|
import { FonosterClient } from "./client/types";
|
|
21
21
|
/**
|
|
22
22
|
* @classdesc Fonoster Workspaces, part of the Fonoster Identity subsystem,
|
|
@@ -66,7 +66,8 @@ declare class Workspaces {
|
|
|
66
66
|
*
|
|
67
67
|
* @param {CreateWorkspaceRequest} request - The request object that contains the necessary information to create a new Workspace
|
|
68
68
|
* @param {string} request.name - The name of the Workspace
|
|
69
|
-
* @
|
|
69
|
+
* @param {string} request.region - An offered public region id (default `default`) or one of your private regions (id or ref, see `Regions.createRegion`); fixed for life
|
|
70
|
+
* @return {Promise<CreateWorkspaceResponse>} - The reference and the stored region
|
|
70
71
|
* @example
|
|
71
72
|
* const workspaces = new SDK.Workspaces(client); // Existing client object
|
|
72
73
|
*
|
|
@@ -79,7 +80,25 @@ declare class Workspaces {
|
|
|
79
80
|
* .then(console.log) // successful response
|
|
80
81
|
* .catch(console.error); // an error occurred
|
|
81
82
|
*/
|
|
82
|
-
createWorkspace(request: CreateWorkspaceRequest): Promise<
|
|
83
|
+
createWorkspace(request: CreateWorkspaceRequest): Promise<CreateWorkspaceResponse>;
|
|
84
|
+
/**
|
|
85
|
+
* The current workspace's region (add-private-regions): for a private region, the cell's status,
|
|
86
|
+
* version, components, active calls and which secrets it needs and has.
|
|
87
|
+
*
|
|
88
|
+
* @return {Promise<Region>} - The region view
|
|
89
|
+
*/
|
|
90
|
+
getRegion(): Promise<Region>;
|
|
91
|
+
/**
|
|
92
|
+
* Issues a new one-time enrollment token for the current workspace's region (its owner only).
|
|
93
|
+
* Enrolling a cell with it revokes the previous cell's credentials.
|
|
94
|
+
*
|
|
95
|
+
* @return {Promise<RegionEnrollmentToken>} - The token (shown once) and its expiry
|
|
96
|
+
*/
|
|
97
|
+
reissueRegionToken(): Promise<RegionEnrollmentToken>;
|
|
98
|
+
/**
|
|
99
|
+
* Revokes the current workspace's region cell now; it goes back to `waiting` (region owner).
|
|
100
|
+
*/
|
|
101
|
+
disconnectRegion(): Promise<void>;
|
|
83
102
|
/**
|
|
84
103
|
* Retrieves an existing Workspace in the system.
|
|
85
104
|
*
|