Erster Commit
This commit is contained in:
+201
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
+216
@@ -0,0 +1,216 @@
|
||||
<!--
|
||||
SPDX-FileCopyrightText: 2024 LiveKit, Inc.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
-->
|
||||
|
||||
# LiveKit Server API for JS
|
||||
|
||||
Use this SDK to manage <a href="https://livekit.io/">LiveKit</a> rooms and create access tokens from your JavaScript/Node.js backend.
|
||||
|
||||
> [!NOTE]
|
||||
> This is v2 of the server-sdk-js which runs in NodeJS, Deno and Bun!
|
||||
> (It theoretically now also runs in every major browser, but that's not recommended due to the security risks involved with exposing your API secrets)
|
||||
> Read the [migration section](#migrate-from-v1x-to-v2x) below for a detailed overview on what has changed.
|
||||
|
||||
## Installation
|
||||
|
||||
### Pnpm
|
||||
|
||||
```
|
||||
pnpm add livekit-server-sdk
|
||||
```
|
||||
|
||||
### Yarn
|
||||
|
||||
```
|
||||
yarn add livekit-server-sdk
|
||||
```
|
||||
|
||||
### NPM
|
||||
|
||||
```
|
||||
npm install livekit-server-sdk --save
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Environment Variables
|
||||
|
||||
You may store credentials in environment variables. If api-key or api-secret is not passed in when creating a `RoomServiceClient` or `AccessToken`, the values in the following env vars will be used:
|
||||
|
||||
- `LIVEKIT_API_KEY`
|
||||
- `LIVEKIT_API_SECRET`
|
||||
|
||||
### Creating Access Tokens
|
||||
|
||||
Creating a token for participant to join a room.
|
||||
|
||||
```typescript
|
||||
import { AccessToken } from 'livekit-server-sdk';
|
||||
|
||||
// if this room doesn't exist, it'll be automatically created when the first
|
||||
// client joins
|
||||
const roomName = 'name-of-room';
|
||||
// identifier to be used for participant.
|
||||
// it's available as LocalParticipant.identity with livekit-client SDK
|
||||
const participantName = 'user-name';
|
||||
|
||||
const at = new AccessToken('api-key', 'secret-key', {
|
||||
identity: participantName,
|
||||
});
|
||||
at.addGrant({ roomJoin: true, room: roomName });
|
||||
|
||||
const token = await at.toJwt();
|
||||
console.log('access token', token);
|
||||
```
|
||||
|
||||
By default, the token expires after 6 hours. you may override this by passing in `ttl` in the access token options. `ttl` is expressed in seconds (as number) or a string describing a time span [vercel/ms](https://github.com/vercel/ms). eg: '2 days', '10h'.
|
||||
|
||||
### Permissions in Access Tokens
|
||||
|
||||
It's possible to customize the permissions of each participant:
|
||||
|
||||
```typescript
|
||||
const at = new AccessToken('api-key', 'secret-key', {
|
||||
identity: participantName,
|
||||
});
|
||||
|
||||
at.addGrant({
|
||||
roomJoin: true,
|
||||
room: roomName,
|
||||
canPublish: false,
|
||||
canSubscribe: true,
|
||||
});
|
||||
```
|
||||
|
||||
This will allow the participant to subscribe to tracks, but not publish their own to the room.
|
||||
|
||||
### Managing Rooms
|
||||
|
||||
`RoomServiceClient` gives you APIs to list, create, and delete rooms. It also requires a pair of api key/secret key to operate.
|
||||
|
||||
```typescript
|
||||
import { Room, RoomServiceClient } from 'livekit-server-sdk';
|
||||
|
||||
const livekitHost = 'https://my.livekit.host';
|
||||
const svc = new RoomServiceClient(livekitHost, 'api-key', 'secret-key');
|
||||
|
||||
// list rooms
|
||||
svc.listRooms().then((rooms: Room[]) => {
|
||||
console.log('existing rooms', rooms);
|
||||
});
|
||||
|
||||
// create a new room
|
||||
const opts = {
|
||||
name: 'myroom',
|
||||
// timeout in seconds
|
||||
emptyTimeout: 10 * 60,
|
||||
maxParticipants: 20,
|
||||
};
|
||||
svc.createRoom(opts).then((room: Room) => {
|
||||
console.log('room created', room);
|
||||
});
|
||||
|
||||
// delete a room
|
||||
svc.deleteRoom('myroom').then(() => {
|
||||
console.log('room deleted');
|
||||
});
|
||||
```
|
||||
|
||||
## Webhooks
|
||||
|
||||
The JS SDK also provides helper functions to decode and verify webhook callbacks. While verification is optional, it ensures the authenticity of the message. See [webhooks guide](https://docs.livekit.io/home/server/webhooks/) for details.
|
||||
|
||||
LiveKit POSTs to webhook endpoints with `Content-Type: application/webhook+json`. Please ensure your server is able to receive POST body with that MIME.
|
||||
|
||||
Check out [example projects](examples) for full examples of webhooks integration.
|
||||
|
||||
```typescript
|
||||
import { WebhookReceiver } from 'livekit-server-sdk';
|
||||
|
||||
const receiver = new WebhookReceiver('apikey', 'apisecret');
|
||||
|
||||
// In order to use the validator, WebhookReceiver must have access to the raw POSTed string (instead of a parsed JSON object)
|
||||
// if you are using express middleware, ensure that `express.raw` is used for the webhook endpoint
|
||||
// app.use(express.raw({type: 'application/webhook+json'}));
|
||||
|
||||
app.post('/webhook-endpoint', async (req, res) => {
|
||||
// event is a WebhookEvent object
|
||||
const event = await receiver.receive(req.body, req.get('Authorization'));
|
||||
});
|
||||
```
|
||||
|
||||
## Migrate from v1.x to v2.x
|
||||
|
||||
### Token generation
|
||||
|
||||
Because the `jsonwebtoken` lib got replaced with `jose`, there are a couple of APIs that are now async, that weren't before:
|
||||
|
||||
```typescript
|
||||
const at = new AccessToken('api-key', 'secret-key', {
|
||||
identity: participantName,
|
||||
});
|
||||
at.addGrant({ roomJoin: true, room: roomName });
|
||||
|
||||
// v1
|
||||
// const token = at.toJWT();
|
||||
|
||||
// v2
|
||||
const token = await at.toJwt();
|
||||
|
||||
// v1
|
||||
// const grants = v.verify(token);
|
||||
|
||||
// v2
|
||||
const grants = await v.verify(token);
|
||||
|
||||
app.post('/webhook-endpoint', async (req, res) => {
|
||||
// v1
|
||||
// const event = receiver.receive(req.body, req.get('Authorization'));
|
||||
|
||||
// v2
|
||||
const event = await receiver.receive(req.body, req.get('Authorization'));
|
||||
});
|
||||
```
|
||||
|
||||
### Egress API
|
||||
|
||||
Egress request types have been updated from interfaces to classes in the latest version. Additionally, `oneof` fields now require an explicit `case` field to specify the value type.
|
||||
|
||||
For example, to create a RoomComposite Egress:
|
||||
|
||||
```typescript
|
||||
// v1
|
||||
// const fileOutput = {
|
||||
// fileType: EncodedFileType.MP4,
|
||||
// filepath: 'livekit-demo/room-composite-test.mp4',
|
||||
// s3: {
|
||||
// accessKey: 'aws-access-key',
|
||||
// secret: 'aws-access-secret',
|
||||
// region: 'aws-region',
|
||||
// bucket: 'my-bucket',
|
||||
// },
|
||||
// };
|
||||
|
||||
// const info = await egressClient.startRoomCompositeEgress('my-room', {
|
||||
// file: fileOutput,
|
||||
// });
|
||||
|
||||
// v2 - current
|
||||
const fileOutput = new EncodedFileOutput({
|
||||
filepath: 'dz/davids-room-test.mp4',
|
||||
output: {
|
||||
case: 's3',
|
||||
value: new S3Upload({
|
||||
accessKey: 'aws-access-key',
|
||||
secret: 'aws-access-secret',
|
||||
bucket: 'my-bucket',
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
const info = await egressClient.startRoomCompositeEgress('my-room', {
|
||||
file: fileOutput,
|
||||
});
|
||||
```
|
||||
+187
@@ -0,0 +1,187 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var AccessToken_exports = {};
|
||||
__export(AccessToken_exports, {
|
||||
AccessToken: () => AccessToken,
|
||||
TokenVerifier: () => TokenVerifier
|
||||
});
|
||||
module.exports = __toCommonJS(AccessToken_exports);
|
||||
var jose = __toESM(require("jose"), 1);
|
||||
var import_grants = require("./grants.cjs");
|
||||
const defaultTTL = `6h`;
|
||||
const defaultClockToleranceSeconds = 10;
|
||||
class AccessToken {
|
||||
/**
|
||||
* Creates a new AccessToken
|
||||
* @param apiKey - API Key, can be set in env LIVEKIT_API_KEY
|
||||
* @param apiSecret - Secret, can be set in env LIVEKIT_API_SECRET
|
||||
*/
|
||||
constructor(apiKey, apiSecret, options) {
|
||||
if (!apiKey) {
|
||||
apiKey = process.env.LIVEKIT_API_KEY;
|
||||
}
|
||||
if (!apiSecret) {
|
||||
apiSecret = process.env.LIVEKIT_API_SECRET;
|
||||
}
|
||||
if (!apiKey || !apiSecret) {
|
||||
throw Error("api-key and api-secret must be set");
|
||||
} else if (typeof document !== "undefined") {
|
||||
console.error(
|
||||
"You should not include your API secret in your web client bundle.\n\nYour web client should request a token from your backend server which should then use the API secret to generate a token. See https://docs.livekit.io/client/connect/"
|
||||
);
|
||||
}
|
||||
this.apiKey = apiKey;
|
||||
this.apiSecret = apiSecret;
|
||||
this.grants = {};
|
||||
this.identity = options == null ? void 0 : options.identity;
|
||||
this.ttl = (options == null ? void 0 : options.ttl) || defaultTTL;
|
||||
if (typeof this.ttl === "number") {
|
||||
this.ttl = `${this.ttl}s`;
|
||||
}
|
||||
if (options == null ? void 0 : options.metadata) {
|
||||
this.metadata = options.metadata;
|
||||
}
|
||||
if (options == null ? void 0 : options.attributes) {
|
||||
this.attributes = options.attributes;
|
||||
}
|
||||
if (options == null ? void 0 : options.name) {
|
||||
this.name = options.name;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Adds a video grant to this token.
|
||||
* @param grant -
|
||||
*/
|
||||
addGrant(grant) {
|
||||
this.grants.video = { ...this.grants.video ?? {}, ...grant };
|
||||
}
|
||||
/**
|
||||
* Adds an inference grant to this token.
|
||||
* @param grant -
|
||||
*/
|
||||
addInferenceGrant(grant) {
|
||||
this.grants.inference = { ...this.grants.inference ?? {}, ...grant };
|
||||
}
|
||||
/**
|
||||
* Adds a SIP grant to this token.
|
||||
* @param grant -
|
||||
*/
|
||||
addSIPGrant(grant) {
|
||||
this.grants.sip = { ...this.grants.sip ?? {}, ...grant };
|
||||
}
|
||||
/**
|
||||
* Adds an observability grant to this token.
|
||||
* @param grant -
|
||||
*/
|
||||
addObservabilityGrant(grant) {
|
||||
this.grants.observability = { ...this.grants.observability ?? {}, ...grant };
|
||||
}
|
||||
get name() {
|
||||
return this.grants.name;
|
||||
}
|
||||
set name(name) {
|
||||
this.grants.name = name;
|
||||
}
|
||||
get metadata() {
|
||||
return this.grants.metadata;
|
||||
}
|
||||
/**
|
||||
* Set metadata to be passed to the Participant, used only when joining the room
|
||||
*/
|
||||
set metadata(md) {
|
||||
this.grants.metadata = md;
|
||||
}
|
||||
get attributes() {
|
||||
return this.grants.attributes;
|
||||
}
|
||||
set attributes(attrs) {
|
||||
this.grants.attributes = attrs;
|
||||
}
|
||||
get kind() {
|
||||
return this.grants.kind;
|
||||
}
|
||||
set kind(kind) {
|
||||
this.grants.kind = kind;
|
||||
}
|
||||
get sha256() {
|
||||
return this.grants.sha256;
|
||||
}
|
||||
set sha256(sha) {
|
||||
this.grants.sha256 = sha;
|
||||
}
|
||||
get roomPreset() {
|
||||
return this.grants.roomPreset;
|
||||
}
|
||||
set roomPreset(preset) {
|
||||
this.grants.roomPreset = preset;
|
||||
}
|
||||
get roomConfig() {
|
||||
return this.grants.roomConfig;
|
||||
}
|
||||
set roomConfig(config) {
|
||||
this.grants.roomConfig = config;
|
||||
}
|
||||
/**
|
||||
* @returns JWT encoded token
|
||||
*/
|
||||
async toJwt() {
|
||||
var _a;
|
||||
const secret = new TextEncoder().encode(this.apiSecret);
|
||||
const jwt = new jose.SignJWT((0, import_grants.claimsToJwtPayload)(this.grants)).setProtectedHeader({ alg: "HS256" }).setIssuer(this.apiKey).setExpirationTime(this.ttl).setNotBefore(/* @__PURE__ */ new Date());
|
||||
if (this.identity) {
|
||||
jwt.setSubject(this.identity);
|
||||
} else if ((_a = this.grants.video) == null ? void 0 : _a.roomJoin) {
|
||||
throw Error("identity is required for join but not set");
|
||||
}
|
||||
return jwt.sign(secret);
|
||||
}
|
||||
}
|
||||
class TokenVerifier {
|
||||
constructor(apiKey, apiSecret) {
|
||||
this.apiKey = apiKey;
|
||||
this.apiSecret = apiSecret;
|
||||
}
|
||||
async verify(token, clockTolerance = defaultClockToleranceSeconds) {
|
||||
const secret = new TextEncoder().encode(this.apiSecret);
|
||||
const { payload } = await jose.jwtVerify(token, secret, {
|
||||
issuer: this.apiKey,
|
||||
clockTolerance
|
||||
});
|
||||
if (!payload) {
|
||||
throw Error("invalid token");
|
||||
}
|
||||
return payload;
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
AccessToken,
|
||||
TokenVerifier
|
||||
});
|
||||
//# sourceMappingURL=AccessToken.cjs.map
|
||||
+1
File diff suppressed because one or more lines are too long
+90
@@ -0,0 +1,90 @@
|
||||
import { RoomConfiguration } from '@livekit/protocol';
|
||||
import { VideoGrant, InferenceGrant, SIPGrant, ObservabilityGrant, ClaimGrants } from './grants.cjs';
|
||||
import 'jose';
|
||||
|
||||
interface AccessTokenOptions {
|
||||
/**
|
||||
* amount of time before expiration
|
||||
* expressed in seconds or a string describing a time span zeit/ms.
|
||||
* eg: '2 days', '10h', or seconds as numeric value
|
||||
*/
|
||||
ttl?: number | string;
|
||||
/**
|
||||
* display name for the participant, available as `Participant.name`
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* identity of the user, required for room join tokens
|
||||
*/
|
||||
identity?: string;
|
||||
/**
|
||||
* custom participant metadata
|
||||
*/
|
||||
metadata?: string;
|
||||
/**
|
||||
* custom participant attributes
|
||||
*/
|
||||
attributes?: Record<string, string>;
|
||||
}
|
||||
declare class AccessToken {
|
||||
private apiKey;
|
||||
private apiSecret;
|
||||
private grants;
|
||||
identity?: string;
|
||||
ttl: number | string;
|
||||
/**
|
||||
* Creates a new AccessToken
|
||||
* @param apiKey - API Key, can be set in env LIVEKIT_API_KEY
|
||||
* @param apiSecret - Secret, can be set in env LIVEKIT_API_SECRET
|
||||
*/
|
||||
constructor(apiKey?: string, apiSecret?: string, options?: AccessTokenOptions);
|
||||
/**
|
||||
* Adds a video grant to this token.
|
||||
* @param grant -
|
||||
*/
|
||||
addGrant(grant: VideoGrant): void;
|
||||
/**
|
||||
* Adds an inference grant to this token.
|
||||
* @param grant -
|
||||
*/
|
||||
addInferenceGrant(grant: InferenceGrant): void;
|
||||
/**
|
||||
* Adds a SIP grant to this token.
|
||||
* @param grant -
|
||||
*/
|
||||
addSIPGrant(grant: SIPGrant): void;
|
||||
/**
|
||||
* Adds an observability grant to this token.
|
||||
* @param grant -
|
||||
*/
|
||||
addObservabilityGrant(grant: ObservabilityGrant): void;
|
||||
get name(): string | undefined;
|
||||
set name(name: string);
|
||||
get metadata(): string | undefined;
|
||||
/**
|
||||
* Set metadata to be passed to the Participant, used only when joining the room
|
||||
*/
|
||||
set metadata(md: string);
|
||||
get attributes(): Record<string, string> | undefined;
|
||||
set attributes(attrs: Record<string, string>);
|
||||
get kind(): string | undefined;
|
||||
set kind(kind: string);
|
||||
get sha256(): string | undefined;
|
||||
set sha256(sha: string | undefined);
|
||||
get roomPreset(): string | undefined;
|
||||
set roomPreset(preset: string | undefined);
|
||||
get roomConfig(): RoomConfiguration | undefined;
|
||||
set roomConfig(config: RoomConfiguration | undefined);
|
||||
/**
|
||||
* @returns JWT encoded token
|
||||
*/
|
||||
toJwt(): Promise<string>;
|
||||
}
|
||||
declare class TokenVerifier {
|
||||
private apiKey;
|
||||
private apiSecret;
|
||||
constructor(apiKey: string, apiSecret: string);
|
||||
verify(token: string, clockTolerance?: string | number): Promise<ClaimGrants>;
|
||||
}
|
||||
|
||||
export { AccessToken, type AccessTokenOptions, TokenVerifier };
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
import { RoomConfiguration } from '@livekit/protocol';
|
||||
import { VideoGrant, InferenceGrant, SIPGrant, ObservabilityGrant, ClaimGrants } from './grants.js';
|
||||
import 'jose';
|
||||
|
||||
interface AccessTokenOptions {
|
||||
/**
|
||||
* amount of time before expiration
|
||||
* expressed in seconds or a string describing a time span zeit/ms.
|
||||
* eg: '2 days', '10h', or seconds as numeric value
|
||||
*/
|
||||
ttl?: number | string;
|
||||
/**
|
||||
* display name for the participant, available as `Participant.name`
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* identity of the user, required for room join tokens
|
||||
*/
|
||||
identity?: string;
|
||||
/**
|
||||
* custom participant metadata
|
||||
*/
|
||||
metadata?: string;
|
||||
/**
|
||||
* custom participant attributes
|
||||
*/
|
||||
attributes?: Record<string, string>;
|
||||
}
|
||||
declare class AccessToken {
|
||||
private apiKey;
|
||||
private apiSecret;
|
||||
private grants;
|
||||
identity?: string;
|
||||
ttl: number | string;
|
||||
/**
|
||||
* Creates a new AccessToken
|
||||
* @param apiKey - API Key, can be set in env LIVEKIT_API_KEY
|
||||
* @param apiSecret - Secret, can be set in env LIVEKIT_API_SECRET
|
||||
*/
|
||||
constructor(apiKey?: string, apiSecret?: string, options?: AccessTokenOptions);
|
||||
/**
|
||||
* Adds a video grant to this token.
|
||||
* @param grant -
|
||||
*/
|
||||
addGrant(grant: VideoGrant): void;
|
||||
/**
|
||||
* Adds an inference grant to this token.
|
||||
* @param grant -
|
||||
*/
|
||||
addInferenceGrant(grant: InferenceGrant): void;
|
||||
/**
|
||||
* Adds a SIP grant to this token.
|
||||
* @param grant -
|
||||
*/
|
||||
addSIPGrant(grant: SIPGrant): void;
|
||||
/**
|
||||
* Adds an observability grant to this token.
|
||||
* @param grant -
|
||||
*/
|
||||
addObservabilityGrant(grant: ObservabilityGrant): void;
|
||||
get name(): string | undefined;
|
||||
set name(name: string);
|
||||
get metadata(): string | undefined;
|
||||
/**
|
||||
* Set metadata to be passed to the Participant, used only when joining the room
|
||||
*/
|
||||
set metadata(md: string);
|
||||
get attributes(): Record<string, string> | undefined;
|
||||
set attributes(attrs: Record<string, string>);
|
||||
get kind(): string | undefined;
|
||||
set kind(kind: string);
|
||||
get sha256(): string | undefined;
|
||||
set sha256(sha: string | undefined);
|
||||
get roomPreset(): string | undefined;
|
||||
set roomPreset(preset: string | undefined);
|
||||
get roomConfig(): RoomConfiguration | undefined;
|
||||
set roomConfig(config: RoomConfiguration | undefined);
|
||||
/**
|
||||
* @returns JWT encoded token
|
||||
*/
|
||||
toJwt(): Promise<string>;
|
||||
}
|
||||
declare class TokenVerifier {
|
||||
private apiKey;
|
||||
private apiSecret;
|
||||
constructor(apiKey: string, apiSecret: string);
|
||||
verify(token: string, clockTolerance?: string | number): Promise<ClaimGrants>;
|
||||
}
|
||||
|
||||
export { AccessToken, type AccessTokenOptions, TokenVerifier };
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"AccessToken.d.ts","sourceRoot":"","sources":["../src/AccessToken.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,QAAQ,EACR,UAAU,EACX,MAAM,aAAa,CAAC;AAQrB,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEtB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,SAAS,CAAS;IAE1B,OAAO,CAAC,MAAM,CAAc;IAE5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IAErB;;;;OAIG;gBACS,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB;IAsC7E;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,UAAU;IAI1B;;;OAGG;IACH,iBAAiB,CAAC,KAAK,EAAE,cAAc;IAIvC;;;OAGG;IACH,WAAW,CAAC,KAAK,EAAE,QAAQ;IAI3B;;;OAGG;IACH,qBAAqB,CAAC,KAAK,EAAE,kBAAkB;IAI/C,IAAI,IAAI,IAAI,MAAM,GAAG,SAAS,CAE7B;IAED,IAAI,IAAI,CAAC,IAAI,EAAE,MAAM,EAEpB;IAED,IAAI,QAAQ,IAAI,MAAM,GAAG,SAAS,CAEjC;IAED;;OAEG;IACH,IAAI,QAAQ,CAAC,EAAE,EAAE,MAAM,EAEtB;IAED,IAAI,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAEnD;IAED,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAE3C;IAED,IAAI,IAAI,IAAI,MAAM,GAAG,SAAS,CAE7B;IAED,IAAI,IAAI,CAAC,IAAI,EAAE,MAAM,EAEpB;IAED,IAAI,MAAM,IAAI,MAAM,GAAG,SAAS,CAE/B;IAED,IAAI,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAEjC;IAED,IAAI,UAAU,IAAI,MAAM,GAAG,SAAS,CAEnC;IAED,IAAI,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAExC;IAED,IAAI,UAAU,IAAI,iBAAiB,GAAG,SAAS,CAE9C;IAED,IAAI,UAAU,CAAC,MAAM,EAAE,iBAAiB,GAAG,SAAS,EAEnD;IAED;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;CAiB/B;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,SAAS,CAAS;gBAEd,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAKvC,MAAM,CACV,KAAK,EAAE,MAAM,EACb,cAAc,GAAE,MAAM,GAAG,MAAqC,GAC7D,OAAO,CAAC,WAAW,CAAC;CAYxB"}
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
import * as jose from "jose";
|
||||
import { claimsToJwtPayload } from "./grants.js";
|
||||
const defaultTTL = `6h`;
|
||||
const defaultClockToleranceSeconds = 10;
|
||||
class AccessToken {
|
||||
/**
|
||||
* Creates a new AccessToken
|
||||
* @param apiKey - API Key, can be set in env LIVEKIT_API_KEY
|
||||
* @param apiSecret - Secret, can be set in env LIVEKIT_API_SECRET
|
||||
*/
|
||||
constructor(apiKey, apiSecret, options) {
|
||||
if (!apiKey) {
|
||||
apiKey = process.env.LIVEKIT_API_KEY;
|
||||
}
|
||||
if (!apiSecret) {
|
||||
apiSecret = process.env.LIVEKIT_API_SECRET;
|
||||
}
|
||||
if (!apiKey || !apiSecret) {
|
||||
throw Error("api-key and api-secret must be set");
|
||||
} else if (typeof document !== "undefined") {
|
||||
console.error(
|
||||
"You should not include your API secret in your web client bundle.\n\nYour web client should request a token from your backend server which should then use the API secret to generate a token. See https://docs.livekit.io/client/connect/"
|
||||
);
|
||||
}
|
||||
this.apiKey = apiKey;
|
||||
this.apiSecret = apiSecret;
|
||||
this.grants = {};
|
||||
this.identity = options == null ? void 0 : options.identity;
|
||||
this.ttl = (options == null ? void 0 : options.ttl) || defaultTTL;
|
||||
if (typeof this.ttl === "number") {
|
||||
this.ttl = `${this.ttl}s`;
|
||||
}
|
||||
if (options == null ? void 0 : options.metadata) {
|
||||
this.metadata = options.metadata;
|
||||
}
|
||||
if (options == null ? void 0 : options.attributes) {
|
||||
this.attributes = options.attributes;
|
||||
}
|
||||
if (options == null ? void 0 : options.name) {
|
||||
this.name = options.name;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Adds a video grant to this token.
|
||||
* @param grant -
|
||||
*/
|
||||
addGrant(grant) {
|
||||
this.grants.video = { ...this.grants.video ?? {}, ...grant };
|
||||
}
|
||||
/**
|
||||
* Adds an inference grant to this token.
|
||||
* @param grant -
|
||||
*/
|
||||
addInferenceGrant(grant) {
|
||||
this.grants.inference = { ...this.grants.inference ?? {}, ...grant };
|
||||
}
|
||||
/**
|
||||
* Adds a SIP grant to this token.
|
||||
* @param grant -
|
||||
*/
|
||||
addSIPGrant(grant) {
|
||||
this.grants.sip = { ...this.grants.sip ?? {}, ...grant };
|
||||
}
|
||||
/**
|
||||
* Adds an observability grant to this token.
|
||||
* @param grant -
|
||||
*/
|
||||
addObservabilityGrant(grant) {
|
||||
this.grants.observability = { ...this.grants.observability ?? {}, ...grant };
|
||||
}
|
||||
get name() {
|
||||
return this.grants.name;
|
||||
}
|
||||
set name(name) {
|
||||
this.grants.name = name;
|
||||
}
|
||||
get metadata() {
|
||||
return this.grants.metadata;
|
||||
}
|
||||
/**
|
||||
* Set metadata to be passed to the Participant, used only when joining the room
|
||||
*/
|
||||
set metadata(md) {
|
||||
this.grants.metadata = md;
|
||||
}
|
||||
get attributes() {
|
||||
return this.grants.attributes;
|
||||
}
|
||||
set attributes(attrs) {
|
||||
this.grants.attributes = attrs;
|
||||
}
|
||||
get kind() {
|
||||
return this.grants.kind;
|
||||
}
|
||||
set kind(kind) {
|
||||
this.grants.kind = kind;
|
||||
}
|
||||
get sha256() {
|
||||
return this.grants.sha256;
|
||||
}
|
||||
set sha256(sha) {
|
||||
this.grants.sha256 = sha;
|
||||
}
|
||||
get roomPreset() {
|
||||
return this.grants.roomPreset;
|
||||
}
|
||||
set roomPreset(preset) {
|
||||
this.grants.roomPreset = preset;
|
||||
}
|
||||
get roomConfig() {
|
||||
return this.grants.roomConfig;
|
||||
}
|
||||
set roomConfig(config) {
|
||||
this.grants.roomConfig = config;
|
||||
}
|
||||
/**
|
||||
* @returns JWT encoded token
|
||||
*/
|
||||
async toJwt() {
|
||||
var _a;
|
||||
const secret = new TextEncoder().encode(this.apiSecret);
|
||||
const jwt = new jose.SignJWT(claimsToJwtPayload(this.grants)).setProtectedHeader({ alg: "HS256" }).setIssuer(this.apiKey).setExpirationTime(this.ttl).setNotBefore(/* @__PURE__ */ new Date());
|
||||
if (this.identity) {
|
||||
jwt.setSubject(this.identity);
|
||||
} else if ((_a = this.grants.video) == null ? void 0 : _a.roomJoin) {
|
||||
throw Error("identity is required for join but not set");
|
||||
}
|
||||
return jwt.sign(secret);
|
||||
}
|
||||
}
|
||||
class TokenVerifier {
|
||||
constructor(apiKey, apiSecret) {
|
||||
this.apiKey = apiKey;
|
||||
this.apiSecret = apiSecret;
|
||||
}
|
||||
async verify(token, clockTolerance = defaultClockToleranceSeconds) {
|
||||
const secret = new TextEncoder().encode(this.apiSecret);
|
||||
const { payload } = await jose.jwtVerify(token, secret, {
|
||||
issuer: this.apiKey,
|
||||
clockTolerance
|
||||
});
|
||||
if (!payload) {
|
||||
throw Error("invalid token");
|
||||
}
|
||||
return payload;
|
||||
}
|
||||
}
|
||||
export {
|
||||
AccessToken,
|
||||
TokenVerifier
|
||||
};
|
||||
//# sourceMappingURL=AccessToken.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+129
@@ -0,0 +1,129 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var AgentDispatchClient_exports = {};
|
||||
__export(AgentDispatchClient_exports, {
|
||||
AgentDispatchClient: () => AgentDispatchClient
|
||||
});
|
||||
module.exports = __toCommonJS(AgentDispatchClient_exports);
|
||||
var import_protocol = require("@livekit/protocol");
|
||||
var import_ServiceBase = require("./ServiceBase.cjs");
|
||||
var import_TwirpRPC = require("./TwirpRPC.cjs");
|
||||
const svc = "AgentDispatchService";
|
||||
class AgentDispatchClient extends import_ServiceBase.ServiceBase {
|
||||
/**
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host, apiKey, secret, options) {
|
||||
super({ apiKey, secret, token: options == null ? void 0 : options.token });
|
||||
this.rpc = new import_TwirpRPC.TwirpRpc(host, import_TwirpRPC.livekitPackage, {
|
||||
requestTimeout: options == null ? void 0 : options.requestTimeout,
|
||||
failover: options == null ? void 0 : options.failover
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Create an explicit dispatch for an agent to join a room. To use explicit
|
||||
* dispatch, your agent must be registered with an `agentName`.
|
||||
* @param roomName - name of the room to dispatch to
|
||||
* @param agentName - name of the agent to dispatch
|
||||
* @param options - optional metadata to send along with the dispatch
|
||||
* @returns the dispatch that was created
|
||||
*/
|
||||
async createDispatch(roomName, agentName, options) {
|
||||
const req = new import_protocol.CreateAgentDispatchRequest({
|
||||
room: roomName,
|
||||
agentName,
|
||||
metadata: options == null ? void 0 : options.metadata,
|
||||
restartPolicy: options == null ? void 0 : options.restartPolicy,
|
||||
deployment: options == null ? void 0 : options.deployment
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"CreateDispatch",
|
||||
req,
|
||||
await this.authHeader({ roomAdmin: true, room: roomName })
|
||||
);
|
||||
return import_protocol.AgentDispatch.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Delete an explicit dispatch for an agent in a room.
|
||||
* @param dispatchId - id of the dispatch to delete
|
||||
* @param roomName - name of the room the dispatch is for
|
||||
*/
|
||||
async deleteDispatch(dispatchId, roomName) {
|
||||
const req = new import_protocol.DeleteAgentDispatchRequest({
|
||||
dispatchId,
|
||||
room: roomName
|
||||
}).toJson();
|
||||
await this.rpc.request(
|
||||
svc,
|
||||
"DeleteDispatch",
|
||||
req,
|
||||
await this.authHeader({ roomAdmin: true, room: roomName })
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Get an Agent dispatch by ID
|
||||
* @param dispatchId - id of the dispatch to get
|
||||
* @param roomName - name of the room the dispatch is for
|
||||
* @returns the dispatch that was found, or undefined if not found
|
||||
*/
|
||||
async getDispatch(dispatchId, roomName) {
|
||||
const req = new import_protocol.ListAgentDispatchRequest({
|
||||
dispatchId,
|
||||
room: roomName
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ListDispatch",
|
||||
req,
|
||||
await this.authHeader({ roomAdmin: true, room: roomName })
|
||||
);
|
||||
const res = import_protocol.ListAgentDispatchResponse.fromJson(data, { ignoreUnknownFields: true });
|
||||
if (res.agentDispatches.length === 0) {
|
||||
return void 0;
|
||||
}
|
||||
return res.agentDispatches[0];
|
||||
}
|
||||
/**
|
||||
* List all agent dispatches for a room
|
||||
* @param roomName - name of the room to list dispatches for
|
||||
* @returns the list of dispatches
|
||||
*/
|
||||
async listDispatch(roomName) {
|
||||
const req = new import_protocol.ListAgentDispatchRequest({
|
||||
room: roomName
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ListDispatch",
|
||||
req,
|
||||
await this.authHeader({ roomAdmin: true, room: roomName })
|
||||
);
|
||||
const res = import_protocol.ListAgentDispatchResponse.fromJson(data, { ignoreUnknownFields: true });
|
||||
return res.agentDispatches;
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
AgentDispatchClient
|
||||
});
|
||||
//# sourceMappingURL=AgentDispatchClient.cjs.map
|
||||
+1
File diff suppressed because one or more lines are too long
+59
@@ -0,0 +1,59 @@
|
||||
import { JobRestartPolicy, AgentDispatch } from '@livekit/protocol';
|
||||
import { ClientOptions } from './ClientOptions.cjs';
|
||||
import { ServiceBase } from './ServiceBase.cjs';
|
||||
import './grants.cjs';
|
||||
import 'jose';
|
||||
|
||||
interface CreateDispatchOptions {
|
||||
/** any custom data to send along with the job.
|
||||
* note: this is different from room and participant metadata
|
||||
*/
|
||||
metadata?: string;
|
||||
/** controls whether the job should be restarted when it fails (cloud only) */
|
||||
restartPolicy?: JobRestartPolicy;
|
||||
/** optional deployment to dispatch to. Leave empty to target the production deployment. */
|
||||
deployment?: string;
|
||||
}
|
||||
/**
|
||||
* Client to access Agent APIs
|
||||
*/
|
||||
declare class AgentDispatchClient extends ServiceBase {
|
||||
private readonly rpc;
|
||||
/**
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host: string, apiKey?: string, secret?: string, options?: ClientOptions);
|
||||
/**
|
||||
* Create an explicit dispatch for an agent to join a room. To use explicit
|
||||
* dispatch, your agent must be registered with an `agentName`.
|
||||
* @param roomName - name of the room to dispatch to
|
||||
* @param agentName - name of the agent to dispatch
|
||||
* @param options - optional metadata to send along with the dispatch
|
||||
* @returns the dispatch that was created
|
||||
*/
|
||||
createDispatch(roomName: string, agentName: string, options?: CreateDispatchOptions): Promise<AgentDispatch>;
|
||||
/**
|
||||
* Delete an explicit dispatch for an agent in a room.
|
||||
* @param dispatchId - id of the dispatch to delete
|
||||
* @param roomName - name of the room the dispatch is for
|
||||
*/
|
||||
deleteDispatch(dispatchId: string, roomName: string): Promise<void>;
|
||||
/**
|
||||
* Get an Agent dispatch by ID
|
||||
* @param dispatchId - id of the dispatch to get
|
||||
* @param roomName - name of the room the dispatch is for
|
||||
* @returns the dispatch that was found, or undefined if not found
|
||||
*/
|
||||
getDispatch(dispatchId: string, roomName: string): Promise<AgentDispatch | undefined>;
|
||||
/**
|
||||
* List all agent dispatches for a room
|
||||
* @param roomName - name of the room to list dispatches for
|
||||
* @returns the list of dispatches
|
||||
*/
|
||||
listDispatch(roomName: string): Promise<AgentDispatch[]>;
|
||||
}
|
||||
|
||||
export { AgentDispatchClient };
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
import { JobRestartPolicy, AgentDispatch } from '@livekit/protocol';
|
||||
import { ClientOptions } from './ClientOptions.js';
|
||||
import { ServiceBase } from './ServiceBase.js';
|
||||
import './grants.js';
|
||||
import 'jose';
|
||||
|
||||
interface CreateDispatchOptions {
|
||||
/** any custom data to send along with the job.
|
||||
* note: this is different from room and participant metadata
|
||||
*/
|
||||
metadata?: string;
|
||||
/** controls whether the job should be restarted when it fails (cloud only) */
|
||||
restartPolicy?: JobRestartPolicy;
|
||||
/** optional deployment to dispatch to. Leave empty to target the production deployment. */
|
||||
deployment?: string;
|
||||
}
|
||||
/**
|
||||
* Client to access Agent APIs
|
||||
*/
|
||||
declare class AgentDispatchClient extends ServiceBase {
|
||||
private readonly rpc;
|
||||
/**
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host: string, apiKey?: string, secret?: string, options?: ClientOptions);
|
||||
/**
|
||||
* Create an explicit dispatch for an agent to join a room. To use explicit
|
||||
* dispatch, your agent must be registered with an `agentName`.
|
||||
* @param roomName - name of the room to dispatch to
|
||||
* @param agentName - name of the agent to dispatch
|
||||
* @param options - optional metadata to send along with the dispatch
|
||||
* @returns the dispatch that was created
|
||||
*/
|
||||
createDispatch(roomName: string, agentName: string, options?: CreateDispatchOptions): Promise<AgentDispatch>;
|
||||
/**
|
||||
* Delete an explicit dispatch for an agent in a room.
|
||||
* @param dispatchId - id of the dispatch to delete
|
||||
* @param roomName - name of the room the dispatch is for
|
||||
*/
|
||||
deleteDispatch(dispatchId: string, roomName: string): Promise<void>;
|
||||
/**
|
||||
* Get an Agent dispatch by ID
|
||||
* @param dispatchId - id of the dispatch to get
|
||||
* @param roomName - name of the room the dispatch is for
|
||||
* @returns the dispatch that was found, or undefined if not found
|
||||
*/
|
||||
getDispatch(dispatchId: string, roomName: string): Promise<AgentDispatch | undefined>;
|
||||
/**
|
||||
* List all agent dispatches for a room
|
||||
* @param roomName - name of the room to list dispatches for
|
||||
* @returns the list of dispatches
|
||||
*/
|
||||
listDispatch(roomName: string): Promise<AgentDispatch[]>;
|
||||
}
|
||||
|
||||
export { AgentDispatchClient };
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"AgentDispatchClient.d.ts","sourceRoot":"","sources":["../src/AgentDispatchClient.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,aAAa,EAGb,KAAK,gBAAgB,EAGtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,UAAU,qBAAqB;IAC7B;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,gBAAgB,CAAC;IACjC,2FAA2F;IAC3F,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAID;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,WAAW;IAClD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAE1B;;;;;OAKG;gBACS,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa;IAQnF;;;;;;;OAOG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,aAAa,CAAC;IAiBzB;;;;OAIG;IACG,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAazE;;;;;OAKG;IACG,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IAkB3F;;;;OAIG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;CAa/D"}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
import {
|
||||
AgentDispatch,
|
||||
CreateAgentDispatchRequest,
|
||||
DeleteAgentDispatchRequest,
|
||||
ListAgentDispatchRequest,
|
||||
ListAgentDispatchResponse
|
||||
} from "@livekit/protocol";
|
||||
import { ServiceBase } from "./ServiceBase.js";
|
||||
import { TwirpRpc, livekitPackage } from "./TwirpRPC.js";
|
||||
const svc = "AgentDispatchService";
|
||||
class AgentDispatchClient extends ServiceBase {
|
||||
/**
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host, apiKey, secret, options) {
|
||||
super({ apiKey, secret, token: options == null ? void 0 : options.token });
|
||||
this.rpc = new TwirpRpc(host, livekitPackage, {
|
||||
requestTimeout: options == null ? void 0 : options.requestTimeout,
|
||||
failover: options == null ? void 0 : options.failover
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Create an explicit dispatch for an agent to join a room. To use explicit
|
||||
* dispatch, your agent must be registered with an `agentName`.
|
||||
* @param roomName - name of the room to dispatch to
|
||||
* @param agentName - name of the agent to dispatch
|
||||
* @param options - optional metadata to send along with the dispatch
|
||||
* @returns the dispatch that was created
|
||||
*/
|
||||
async createDispatch(roomName, agentName, options) {
|
||||
const req = new CreateAgentDispatchRequest({
|
||||
room: roomName,
|
||||
agentName,
|
||||
metadata: options == null ? void 0 : options.metadata,
|
||||
restartPolicy: options == null ? void 0 : options.restartPolicy,
|
||||
deployment: options == null ? void 0 : options.deployment
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"CreateDispatch",
|
||||
req,
|
||||
await this.authHeader({ roomAdmin: true, room: roomName })
|
||||
);
|
||||
return AgentDispatch.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Delete an explicit dispatch for an agent in a room.
|
||||
* @param dispatchId - id of the dispatch to delete
|
||||
* @param roomName - name of the room the dispatch is for
|
||||
*/
|
||||
async deleteDispatch(dispatchId, roomName) {
|
||||
const req = new DeleteAgentDispatchRequest({
|
||||
dispatchId,
|
||||
room: roomName
|
||||
}).toJson();
|
||||
await this.rpc.request(
|
||||
svc,
|
||||
"DeleteDispatch",
|
||||
req,
|
||||
await this.authHeader({ roomAdmin: true, room: roomName })
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Get an Agent dispatch by ID
|
||||
* @param dispatchId - id of the dispatch to get
|
||||
* @param roomName - name of the room the dispatch is for
|
||||
* @returns the dispatch that was found, or undefined if not found
|
||||
*/
|
||||
async getDispatch(dispatchId, roomName) {
|
||||
const req = new ListAgentDispatchRequest({
|
||||
dispatchId,
|
||||
room: roomName
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ListDispatch",
|
||||
req,
|
||||
await this.authHeader({ roomAdmin: true, room: roomName })
|
||||
);
|
||||
const res = ListAgentDispatchResponse.fromJson(data, { ignoreUnknownFields: true });
|
||||
if (res.agentDispatches.length === 0) {
|
||||
return void 0;
|
||||
}
|
||||
return res.agentDispatches[0];
|
||||
}
|
||||
/**
|
||||
* List all agent dispatches for a room
|
||||
* @param roomName - name of the room to list dispatches for
|
||||
* @returns the list of dispatches
|
||||
*/
|
||||
async listDispatch(roomName) {
|
||||
const req = new ListAgentDispatchRequest({
|
||||
room: roomName
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ListDispatch",
|
||||
req,
|
||||
await this.authHeader({ roomAdmin: true, room: roomName })
|
||||
);
|
||||
const res = ListAgentDispatchResponse.fromJson(data, { ignoreUnknownFields: true });
|
||||
return res.agentDispatches;
|
||||
}
|
||||
}
|
||||
export {
|
||||
AgentDispatchClient
|
||||
};
|
||||
//# sourceMappingURL=AgentDispatchClient.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+17
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var ClientOptions_exports = {};
|
||||
module.exports = __toCommonJS(ClientOptions_exports);
|
||||
//# sourceMappingURL=ClientOptions.cjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../src/ClientOptions.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Options common to all clients\n */\nexport type ClientOptions = {\n /**\n * Optional timeout, in seconds, for all server requests\n */\n requestTimeout?: number;\n /**\n * Whether to fail over to alternative regions on retryable errors (LiveKit\n * Cloud hosts only). Defaults to true; set to false to disable.\n */\n failover?: boolean;\n /**\n * A pre-signed access token, sent verbatim as the Authorization header on\n * every request instead of signing one per call from an API key and secret.\n * The token must already carry the grants for the calls it's used with; since\n * it needs no secret, the client can run client-side.\n */\n token?: string;\n};\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Options common to all clients
|
||||
*/
|
||||
type ClientOptions = {
|
||||
/**
|
||||
* Optional timeout, in seconds, for all server requests
|
||||
*/
|
||||
requestTimeout?: number;
|
||||
/**
|
||||
* Whether to fail over to alternative regions on retryable errors (LiveKit
|
||||
* Cloud hosts only). Defaults to true; set to false to disable.
|
||||
*/
|
||||
failover?: boolean;
|
||||
/**
|
||||
* A pre-signed access token, sent verbatim as the Authorization header on
|
||||
* every request instead of signing one per call from an API key and secret.
|
||||
* The token must already carry the grants for the calls it's used with; since
|
||||
* it needs no secret, the client can run client-side.
|
||||
*/
|
||||
token?: string;
|
||||
};
|
||||
|
||||
export type { ClientOptions };
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Options common to all clients
|
||||
*/
|
||||
type ClientOptions = {
|
||||
/**
|
||||
* Optional timeout, in seconds, for all server requests
|
||||
*/
|
||||
requestTimeout?: number;
|
||||
/**
|
||||
* Whether to fail over to alternative regions on retryable errors (LiveKit
|
||||
* Cloud hosts only). Defaults to true; set to false to disable.
|
||||
*/
|
||||
failover?: boolean;
|
||||
/**
|
||||
* A pre-signed access token, sent verbatim as the Authorization header on
|
||||
* every request instead of signing one per call from an API key and secret.
|
||||
* The token must already carry the grants for the calls it's used with; since
|
||||
* it needs no secret, the client can run client-side.
|
||||
*/
|
||||
token?: string;
|
||||
};
|
||||
|
||||
export type { ClientOptions };
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ClientOptions.d.ts","sourceRoot":"","sources":["../src/ClientOptions.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC"}
|
||||
+1
@@ -0,0 +1 @@
|
||||
//# sourceMappingURL=ClientOptions.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var ConnectorClient_exports = {};
|
||||
__export(ConnectorClient_exports, {
|
||||
ConnectorClient: () => ConnectorClient
|
||||
});
|
||||
module.exports = __toCommonJS(ConnectorClient_exports);
|
||||
var import_protobuf = require("@bufbuild/protobuf");
|
||||
var import_protocol = require("@livekit/protocol");
|
||||
var import_ServiceBase = require("./ServiceBase.cjs");
|
||||
var import_TwirpRPC = require("./TwirpRPC.cjs");
|
||||
var import_dialTimeout = require("./dialTimeout.cjs");
|
||||
const svc = "Connector";
|
||||
class ConnectorClient extends import_ServiceBase.ServiceBase {
|
||||
/**
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host, apiKey, secret, options) {
|
||||
super({ apiKey, secret, token: options == null ? void 0 : options.token });
|
||||
this.rpc = new import_TwirpRPC.TwirpRpc(host, import_TwirpRPC.livekitPackage, {
|
||||
requestTimeout: options == null ? void 0 : options.requestTimeout,
|
||||
failover: options == null ? void 0 : options.failover
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Initiate an outbound WhatsApp call
|
||||
*
|
||||
* @param options - WhatsApp call options
|
||||
* @returns Promise containing the WhatsApp call ID and room name
|
||||
*/
|
||||
async dialWhatsAppCall(options) {
|
||||
const whatsappBizOpaqueCallbackData = options.whatsappBizOpaqueCallbackData || "";
|
||||
const roomName = options.roomName || "";
|
||||
const participantIdentity = options.participantIdentity || "";
|
||||
const participantName = options.participantName || "";
|
||||
const participantMetadata = options.participantMetadata || "";
|
||||
const destinationCountry = options.destinationCountry || "";
|
||||
const req = new import_protocol.DialWhatsAppCallRequest({
|
||||
whatsappPhoneNumberId: options.whatsappPhoneNumberId,
|
||||
whatsappToPhoneNumber: options.whatsappToPhoneNumber,
|
||||
whatsappApiKey: options.whatsappApiKey,
|
||||
whatsappCloudApiVersion: options.whatsappCloudApiVersion,
|
||||
whatsappBizOpaqueCallbackData,
|
||||
roomName,
|
||||
agents: options.agents,
|
||||
participantIdentity,
|
||||
participantName,
|
||||
participantMetadata,
|
||||
participantAttributes: options.participantAttributes,
|
||||
destinationCountry,
|
||||
ringingTimeout: options.ringingTimeout ? new import_protobuf.Duration({ seconds: BigInt(options.ringingTimeout) }) : void 0
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"DialWhatsAppCall",
|
||||
req,
|
||||
await this.authHeader({ roomCreate: true })
|
||||
);
|
||||
return import_protocol.DialWhatsAppCallResponse.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Accept an inbound WhatsApp call
|
||||
*
|
||||
* @param options - WhatsApp call accept options
|
||||
* @returns Promise containing the room name
|
||||
*/
|
||||
async acceptWhatsAppCall(options) {
|
||||
const whatsappBizOpaqueCallbackData = options.whatsappBizOpaqueCallbackData || "";
|
||||
const roomName = options.roomName || "";
|
||||
const participantIdentity = options.participantIdentity || "";
|
||||
const participantName = options.participantName || "";
|
||||
const participantMetadata = options.participantMetadata || "";
|
||||
const destinationCountry = options.destinationCountry || "";
|
||||
const req = new import_protocol.AcceptWhatsAppCallRequest({
|
||||
whatsappPhoneNumberId: options.whatsappPhoneNumberId,
|
||||
whatsappApiKey: options.whatsappApiKey,
|
||||
whatsappCloudApiVersion: options.whatsappCloudApiVersion,
|
||||
whatsappCallId: options.whatsappCallId,
|
||||
whatsappBizOpaqueCallbackData,
|
||||
sdp: options.sdp,
|
||||
roomName,
|
||||
agents: options.agents,
|
||||
participantIdentity,
|
||||
participantName,
|
||||
participantMetadata,
|
||||
participantAttributes: options.participantAttributes,
|
||||
destinationCountry,
|
||||
waitUntilAnswered: options.waitUntilAnswered
|
||||
}).toJson();
|
||||
const timeout = options.waitUntilAnswered ? options.timeout ?? import_dialTimeout.DEFAULT_RINGING_TIMEOUT_SECONDS : options.timeout;
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"AcceptWhatsAppCall",
|
||||
req,
|
||||
await this.authHeader({ roomCreate: true }),
|
||||
timeout
|
||||
);
|
||||
return import_protocol.AcceptWhatsAppCallResponse.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Connect an established WhatsApp call (used for business-initiated calls)
|
||||
*
|
||||
* @param whatsappCallId - Call ID sent by Meta
|
||||
* @param sdp - Session description from Meta
|
||||
*/
|
||||
async connectWhatsAppCall(whatsappCallId, sdp) {
|
||||
const req = new import_protocol.ConnectWhatsAppCallRequest({
|
||||
whatsappCallId,
|
||||
sdp
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ConnectWhatsAppCall",
|
||||
req,
|
||||
await this.authHeader({ roomCreate: true })
|
||||
);
|
||||
return import_protocol.ConnectWhatsAppCallResponse.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Disconnect an active WhatsApp call
|
||||
*
|
||||
* @param whatsappCallId - Call ID sent by Meta
|
||||
* @param whatsappApiKey - The API key of the business that is disconnecting the call.
|
||||
* Required when `disconnectReason` is BUSINESS_INITIATED, optional for USER_INITIATED.
|
||||
* @param disconnectReason - Optional reason for disconnecting the call. Defaults to BUSINESS_INITIATED.
|
||||
*/
|
||||
async disconnectWhatsAppCall(whatsappCallId, whatsappApiKey, disconnectReason) {
|
||||
const req = new import_protocol.DisconnectWhatsAppCallRequest({
|
||||
whatsappCallId,
|
||||
whatsappApiKey,
|
||||
disconnectReason
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"DisconnectWhatsAppCall",
|
||||
req,
|
||||
await this.authHeader({ roomCreate: true })
|
||||
);
|
||||
return import_protocol.DisconnectWhatsAppCallResponse.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Connect a Twilio call to a LiveKit room
|
||||
*
|
||||
* @param options - Twilio call connection options
|
||||
* @returns Promise containing the WebSocket connect URL for Twilio media stream
|
||||
*/
|
||||
async connectTwilioCall(options) {
|
||||
const participantIdentity = options.participantIdentity || "";
|
||||
const participantName = options.participantName || "";
|
||||
const participantMetadata = options.participantMetadata || "";
|
||||
const destinationCountry = options.destinationCountry || "";
|
||||
const req = new import_protocol.ConnectTwilioCallRequest({
|
||||
twilioCallDirection: options.twilioCallDirection,
|
||||
roomName: options.roomName,
|
||||
agents: options.agents,
|
||||
participantIdentity,
|
||||
participantName,
|
||||
participantMetadata,
|
||||
participantAttributes: options.participantAttributes,
|
||||
destinationCountry
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ConnectTwilioCall",
|
||||
req,
|
||||
await this.authHeader({ roomCreate: true })
|
||||
);
|
||||
return import_protocol.ConnectTwilioCallResponse.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
ConnectorClient
|
||||
});
|
||||
//# sourceMappingURL=ConnectorClient.cjs.map
|
||||
+1
File diff suppressed because one or more lines are too long
+145
@@ -0,0 +1,145 @@
|
||||
import { SessionDescription, RoomAgentDispatch, ConnectTwilioCallRequest_TwilioCallDirection, DialWhatsAppCallResponse, AcceptWhatsAppCallResponse, ConnectWhatsAppCallResponse, DisconnectWhatsAppCallRequest_DisconnectReason, DisconnectWhatsAppCallResponse, ConnectTwilioCallResponse } from '@livekit/protocol';
|
||||
import { ClientOptions } from './ClientOptions.cjs';
|
||||
import { ServiceBase } from './ServiceBase.cjs';
|
||||
import './grants.cjs';
|
||||
import 'jose';
|
||||
|
||||
interface DialWhatsAppCallOptions {
|
||||
/** Required - The identifier of the WhatsApp phone number that is initiating the call */
|
||||
whatsappPhoneNumberId: string;
|
||||
/** Required - The number of the user that is supposed to receive the call */
|
||||
whatsappToPhoneNumber: string;
|
||||
/** Required - The API key of the business that is initiating the call */
|
||||
whatsappApiKey: string;
|
||||
/** Required - WhatsApp Cloud API version, eg: 23.0, 24.0, etc. */
|
||||
whatsappCloudApiVersion: string;
|
||||
/** Optional - An arbitrary string you can pass in that is useful for tracking and logging purposes */
|
||||
whatsappBizOpaqueCallbackData?: string;
|
||||
/** Optional - What LiveKit room should this participant be connected to */
|
||||
roomName?: string;
|
||||
/** Optional - Agents to dispatch the call to */
|
||||
agents?: RoomAgentDispatch[];
|
||||
/** Optional - Identity of the participant in LiveKit room */
|
||||
participantIdentity?: string;
|
||||
/** Optional - Name of the participant in LiveKit room */
|
||||
participantName?: string;
|
||||
/** Optional - User-defined metadata. Will be attached to a created Participant in the room. */
|
||||
participantMetadata?: string;
|
||||
/** Optional - User-defined attributes. Will be attached to a created Participant in the room. */
|
||||
participantAttributes?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
/** Optional - Country where the call terminates as ISO 3166-1 alpha-2 */
|
||||
destinationCountry?: string;
|
||||
/** Optional - Max time in seconds for the callee to answer the call */
|
||||
ringingTimeout?: number;
|
||||
}
|
||||
interface AcceptWhatsAppCallOptions {
|
||||
/** Required - The identifier of the WhatsApp phone number that is connecting the call */
|
||||
whatsappPhoneNumberId: string;
|
||||
/** Required - The API key of the business that is connecting the call */
|
||||
whatsappApiKey: string;
|
||||
/** Required - WhatsApp Cloud API version, eg: 23.0, 24.0, etc. */
|
||||
whatsappCloudApiVersion: string;
|
||||
/** Required - Call ID sent by Meta */
|
||||
whatsappCallId: string;
|
||||
/** Optional - An arbitrary string you can pass in that is useful for tracking and logging purposes */
|
||||
whatsappBizOpaqueCallbackData?: string;
|
||||
/** Required - The call accept webhook comes with SDP from Meta */
|
||||
sdp: SessionDescription;
|
||||
/** Optional - What LiveKit room should this participant be connected to */
|
||||
roomName?: string;
|
||||
/** Optional - Agents to dispatch the call to */
|
||||
agents?: RoomAgentDispatch[];
|
||||
/** Optional - Identity of the participant in LiveKit room */
|
||||
participantIdentity?: string;
|
||||
/** Optional - Name of the participant in LiveKit room */
|
||||
participantName?: string;
|
||||
/** Optional - User-defined metadata. Will be attached to a created Participant in the room. */
|
||||
participantMetadata?: string;
|
||||
/** Optional - User-defined attributes. Will be attached to a created Participant in the room. */
|
||||
participantAttributes?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
/** Optional - Country where the call terminates as ISO 3166-1 alpha-2 */
|
||||
destinationCountry?: string;
|
||||
/** Optional - Wait until the inbound party joins before returning. */
|
||||
waitUntilAnswered?: boolean;
|
||||
/**
|
||||
* Optional - Request timeout in seconds. When `waitUntilAnswered` is set it
|
||||
* defaults to the standard ring window; otherwise the client default applies.
|
||||
*/
|
||||
timeout?: number;
|
||||
}
|
||||
interface ConnectTwilioCallOptions {
|
||||
/** The direction of the call */
|
||||
twilioCallDirection: ConnectTwilioCallRequest_TwilioCallDirection;
|
||||
/** What LiveKit room should this call be connected to */
|
||||
roomName: string;
|
||||
/** Optional agents to dispatch the call to */
|
||||
agents?: RoomAgentDispatch[];
|
||||
/** Optional identity of the participant in LiveKit room */
|
||||
participantIdentity?: string;
|
||||
/** Optional name of the participant in LiveKit room */
|
||||
participantName?: string;
|
||||
/** Optional user-defined metadata. Will be attached to a created Participant in the room. */
|
||||
participantMetadata?: string;
|
||||
/** Optional user-defined attributes. Will be attached to a created Participant in the room. */
|
||||
participantAttributes?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
/** Country where the call terminates as ISO 3166-1 alpha-2 */
|
||||
destinationCountry?: string;
|
||||
}
|
||||
/**
|
||||
* Client to access Connector APIs for WhatsApp and Twilio integrations
|
||||
*/
|
||||
declare class ConnectorClient extends ServiceBase {
|
||||
private readonly rpc;
|
||||
/**
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host: string, apiKey?: string, secret?: string, options?: ClientOptions);
|
||||
/**
|
||||
* Initiate an outbound WhatsApp call
|
||||
*
|
||||
* @param options - WhatsApp call options
|
||||
* @returns Promise containing the WhatsApp call ID and room name
|
||||
*/
|
||||
dialWhatsAppCall(options: DialWhatsAppCallOptions): Promise<DialWhatsAppCallResponse>;
|
||||
/**
|
||||
* Accept an inbound WhatsApp call
|
||||
*
|
||||
* @param options - WhatsApp call accept options
|
||||
* @returns Promise containing the room name
|
||||
*/
|
||||
acceptWhatsAppCall(options: AcceptWhatsAppCallOptions): Promise<AcceptWhatsAppCallResponse>;
|
||||
/**
|
||||
* Connect an established WhatsApp call (used for business-initiated calls)
|
||||
*
|
||||
* @param whatsappCallId - Call ID sent by Meta
|
||||
* @param sdp - Session description from Meta
|
||||
*/
|
||||
connectWhatsAppCall(whatsappCallId: string, sdp: SessionDescription): Promise<ConnectWhatsAppCallResponse>;
|
||||
/**
|
||||
* Disconnect an active WhatsApp call
|
||||
*
|
||||
* @param whatsappCallId - Call ID sent by Meta
|
||||
* @param whatsappApiKey - The API key of the business that is disconnecting the call.
|
||||
* Required when `disconnectReason` is BUSINESS_INITIATED, optional for USER_INITIATED.
|
||||
* @param disconnectReason - Optional reason for disconnecting the call. Defaults to BUSINESS_INITIATED.
|
||||
*/
|
||||
disconnectWhatsAppCall(whatsappCallId: string, whatsappApiKey: string, disconnectReason?: DisconnectWhatsAppCallRequest_DisconnectReason): Promise<DisconnectWhatsAppCallResponse>;
|
||||
/**
|
||||
* Connect a Twilio call to a LiveKit room
|
||||
*
|
||||
* @param options - Twilio call connection options
|
||||
* @returns Promise containing the WebSocket connect URL for Twilio media stream
|
||||
*/
|
||||
connectTwilioCall(options: ConnectTwilioCallOptions): Promise<ConnectTwilioCallResponse>;
|
||||
}
|
||||
|
||||
export { type AcceptWhatsAppCallOptions, type ConnectTwilioCallOptions, ConnectorClient, type DialWhatsAppCallOptions };
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
import { SessionDescription, RoomAgentDispatch, ConnectTwilioCallRequest_TwilioCallDirection, DialWhatsAppCallResponse, AcceptWhatsAppCallResponse, ConnectWhatsAppCallResponse, DisconnectWhatsAppCallRequest_DisconnectReason, DisconnectWhatsAppCallResponse, ConnectTwilioCallResponse } from '@livekit/protocol';
|
||||
import { ClientOptions } from './ClientOptions.js';
|
||||
import { ServiceBase } from './ServiceBase.js';
|
||||
import './grants.js';
|
||||
import 'jose';
|
||||
|
||||
interface DialWhatsAppCallOptions {
|
||||
/** Required - The identifier of the WhatsApp phone number that is initiating the call */
|
||||
whatsappPhoneNumberId: string;
|
||||
/** Required - The number of the user that is supposed to receive the call */
|
||||
whatsappToPhoneNumber: string;
|
||||
/** Required - The API key of the business that is initiating the call */
|
||||
whatsappApiKey: string;
|
||||
/** Required - WhatsApp Cloud API version, eg: 23.0, 24.0, etc. */
|
||||
whatsappCloudApiVersion: string;
|
||||
/** Optional - An arbitrary string you can pass in that is useful for tracking and logging purposes */
|
||||
whatsappBizOpaqueCallbackData?: string;
|
||||
/** Optional - What LiveKit room should this participant be connected to */
|
||||
roomName?: string;
|
||||
/** Optional - Agents to dispatch the call to */
|
||||
agents?: RoomAgentDispatch[];
|
||||
/** Optional - Identity of the participant in LiveKit room */
|
||||
participantIdentity?: string;
|
||||
/** Optional - Name of the participant in LiveKit room */
|
||||
participantName?: string;
|
||||
/** Optional - User-defined metadata. Will be attached to a created Participant in the room. */
|
||||
participantMetadata?: string;
|
||||
/** Optional - User-defined attributes. Will be attached to a created Participant in the room. */
|
||||
participantAttributes?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
/** Optional - Country where the call terminates as ISO 3166-1 alpha-2 */
|
||||
destinationCountry?: string;
|
||||
/** Optional - Max time in seconds for the callee to answer the call */
|
||||
ringingTimeout?: number;
|
||||
}
|
||||
interface AcceptWhatsAppCallOptions {
|
||||
/** Required - The identifier of the WhatsApp phone number that is connecting the call */
|
||||
whatsappPhoneNumberId: string;
|
||||
/** Required - The API key of the business that is connecting the call */
|
||||
whatsappApiKey: string;
|
||||
/** Required - WhatsApp Cloud API version, eg: 23.0, 24.0, etc. */
|
||||
whatsappCloudApiVersion: string;
|
||||
/** Required - Call ID sent by Meta */
|
||||
whatsappCallId: string;
|
||||
/** Optional - An arbitrary string you can pass in that is useful for tracking and logging purposes */
|
||||
whatsappBizOpaqueCallbackData?: string;
|
||||
/** Required - The call accept webhook comes with SDP from Meta */
|
||||
sdp: SessionDescription;
|
||||
/** Optional - What LiveKit room should this participant be connected to */
|
||||
roomName?: string;
|
||||
/** Optional - Agents to dispatch the call to */
|
||||
agents?: RoomAgentDispatch[];
|
||||
/** Optional - Identity of the participant in LiveKit room */
|
||||
participantIdentity?: string;
|
||||
/** Optional - Name of the participant in LiveKit room */
|
||||
participantName?: string;
|
||||
/** Optional - User-defined metadata. Will be attached to a created Participant in the room. */
|
||||
participantMetadata?: string;
|
||||
/** Optional - User-defined attributes. Will be attached to a created Participant in the room. */
|
||||
participantAttributes?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
/** Optional - Country where the call terminates as ISO 3166-1 alpha-2 */
|
||||
destinationCountry?: string;
|
||||
/** Optional - Wait until the inbound party joins before returning. */
|
||||
waitUntilAnswered?: boolean;
|
||||
/**
|
||||
* Optional - Request timeout in seconds. When `waitUntilAnswered` is set it
|
||||
* defaults to the standard ring window; otherwise the client default applies.
|
||||
*/
|
||||
timeout?: number;
|
||||
}
|
||||
interface ConnectTwilioCallOptions {
|
||||
/** The direction of the call */
|
||||
twilioCallDirection: ConnectTwilioCallRequest_TwilioCallDirection;
|
||||
/** What LiveKit room should this call be connected to */
|
||||
roomName: string;
|
||||
/** Optional agents to dispatch the call to */
|
||||
agents?: RoomAgentDispatch[];
|
||||
/** Optional identity of the participant in LiveKit room */
|
||||
participantIdentity?: string;
|
||||
/** Optional name of the participant in LiveKit room */
|
||||
participantName?: string;
|
||||
/** Optional user-defined metadata. Will be attached to a created Participant in the room. */
|
||||
participantMetadata?: string;
|
||||
/** Optional user-defined attributes. Will be attached to a created Participant in the room. */
|
||||
participantAttributes?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
/** Country where the call terminates as ISO 3166-1 alpha-2 */
|
||||
destinationCountry?: string;
|
||||
}
|
||||
/**
|
||||
* Client to access Connector APIs for WhatsApp and Twilio integrations
|
||||
*/
|
||||
declare class ConnectorClient extends ServiceBase {
|
||||
private readonly rpc;
|
||||
/**
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host: string, apiKey?: string, secret?: string, options?: ClientOptions);
|
||||
/**
|
||||
* Initiate an outbound WhatsApp call
|
||||
*
|
||||
* @param options - WhatsApp call options
|
||||
* @returns Promise containing the WhatsApp call ID and room name
|
||||
*/
|
||||
dialWhatsAppCall(options: DialWhatsAppCallOptions): Promise<DialWhatsAppCallResponse>;
|
||||
/**
|
||||
* Accept an inbound WhatsApp call
|
||||
*
|
||||
* @param options - WhatsApp call accept options
|
||||
* @returns Promise containing the room name
|
||||
*/
|
||||
acceptWhatsAppCall(options: AcceptWhatsAppCallOptions): Promise<AcceptWhatsAppCallResponse>;
|
||||
/**
|
||||
* Connect an established WhatsApp call (used for business-initiated calls)
|
||||
*
|
||||
* @param whatsappCallId - Call ID sent by Meta
|
||||
* @param sdp - Session description from Meta
|
||||
*/
|
||||
connectWhatsAppCall(whatsappCallId: string, sdp: SessionDescription): Promise<ConnectWhatsAppCallResponse>;
|
||||
/**
|
||||
* Disconnect an active WhatsApp call
|
||||
*
|
||||
* @param whatsappCallId - Call ID sent by Meta
|
||||
* @param whatsappApiKey - The API key of the business that is disconnecting the call.
|
||||
* Required when `disconnectReason` is BUSINESS_INITIATED, optional for USER_INITIATED.
|
||||
* @param disconnectReason - Optional reason for disconnecting the call. Defaults to BUSINESS_INITIATED.
|
||||
*/
|
||||
disconnectWhatsAppCall(whatsappCallId: string, whatsappApiKey: string, disconnectReason?: DisconnectWhatsAppCallRequest_DisconnectReason): Promise<DisconnectWhatsAppCallResponse>;
|
||||
/**
|
||||
* Connect a Twilio call to a LiveKit room
|
||||
*
|
||||
* @param options - Twilio call connection options
|
||||
* @returns Promise containing the WebSocket connect URL for Twilio media stream
|
||||
*/
|
||||
connectTwilioCall(options: ConnectTwilioCallOptions): Promise<ConnectTwilioCallResponse>;
|
||||
}
|
||||
|
||||
export { type AcceptWhatsAppCallOptions, type ConnectTwilioCallOptions, ConnectorClient, type DialWhatsAppCallOptions };
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ConnectorClient.d.ts","sourceRoot":"","sources":["../src/ConnectorClient.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,4CAA4C,EAC5C,8CAA8C,EAC9C,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAEL,0BAA0B,EAE1B,yBAAyB,EAEzB,2BAA2B,EAE3B,wBAAwB,EAExB,8BAA8B,EAC/B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAO/C,MAAM,WAAW,uBAAuB;IACtC,yFAAyF;IACzF,qBAAqB,EAAE,MAAM,CAAC;IAC9B,6EAA6E;IAC7E,qBAAqB,EAAE,MAAM,CAAC;IAC9B,yEAAyE;IACzE,cAAc,EAAE,MAAM,CAAC;IACvB,kEAAkE;IAClE,uBAAuB,EAAE,MAAM,CAAC;IAChC,sGAAsG;IACtG,6BAA6B,CAAC,EAAE,MAAM,CAAC;IACvC,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC7B,6DAA6D;IAC7D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,yDAAyD;IACzD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,+FAA+F;IAC/F,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,iGAAiG;IACjG,qBAAqB,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAClD,yEAAyE;IACzE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,yBAAyB;IACxC,yFAAyF;IACzF,qBAAqB,EAAE,MAAM,CAAC;IAC9B,yEAAyE;IACzE,cAAc,EAAE,MAAM,CAAC;IACvB,kEAAkE;IAClE,uBAAuB,EAAE,MAAM,CAAC;IAChC,sCAAsC;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,sGAAsG;IACtG,6BAA6B,CAAC,EAAE,MAAM,CAAC;IACvC,kEAAkE;IAClE,GAAG,EAAE,kBAAkB,CAAC;IACxB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC7B,6DAA6D;IAC7D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,yDAAyD;IACzD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,+FAA+F;IAC/F,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,iGAAiG;IACjG,qBAAqB,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAClD,yEAAyE;IACzE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,sEAAsE;IACtE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAGD,MAAM,WAAW,wBAAwB;IACvC,gCAAgC;IAChC,mBAAmB,EAAE,4CAA4C,CAAC;IAClE,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC7B,2DAA2D;IAC3D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,uDAAuD;IACvD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,6FAA6F;IAC7F,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,+FAA+F;IAC/F,qBAAqB,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAClD,8DAA8D;IAC9D,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,WAAW;IAC9C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAE1B;;;;;OAKG;gBACS,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa;IAQnF;;;;;OAKG;IACG,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAmC3F;;;;;OAKG;IACG,kBAAkB,CACtB,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,0BAA0B,CAAC;IA0CtC;;;;;OAKG;IACG,mBAAmB,CACvB,cAAc,EAAE,MAAM,EACtB,GAAG,EAAE,kBAAkB,GACtB,OAAO,CAAC,2BAA2B,CAAC;IAevC;;;;;;;OAOG;IACG,sBAAsB,CAC1B,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,EACtB,gBAAgB,CAAC,EAAE,8CAA8C,GAChE,OAAO,CAAC,8BAA8B,CAAC;IAgB1C;;;;;OAKG;IACG,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,yBAAyB,CAAC;CAyB/F"}
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
import { Duration } from "@bufbuild/protobuf";
|
||||
import {
|
||||
AcceptWhatsAppCallRequest,
|
||||
AcceptWhatsAppCallResponse,
|
||||
ConnectTwilioCallRequest,
|
||||
ConnectTwilioCallResponse,
|
||||
ConnectWhatsAppCallRequest,
|
||||
ConnectWhatsAppCallResponse,
|
||||
DialWhatsAppCallRequest,
|
||||
DialWhatsAppCallResponse,
|
||||
DisconnectWhatsAppCallRequest,
|
||||
DisconnectWhatsAppCallResponse
|
||||
} from "@livekit/protocol";
|
||||
import { ServiceBase } from "./ServiceBase.js";
|
||||
import { TwirpRpc, livekitPackage } from "./TwirpRPC.js";
|
||||
import { DEFAULT_RINGING_TIMEOUT_SECONDS } from "./dialTimeout.js";
|
||||
const svc = "Connector";
|
||||
class ConnectorClient extends ServiceBase {
|
||||
/**
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host, apiKey, secret, options) {
|
||||
super({ apiKey, secret, token: options == null ? void 0 : options.token });
|
||||
this.rpc = new TwirpRpc(host, livekitPackage, {
|
||||
requestTimeout: options == null ? void 0 : options.requestTimeout,
|
||||
failover: options == null ? void 0 : options.failover
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Initiate an outbound WhatsApp call
|
||||
*
|
||||
* @param options - WhatsApp call options
|
||||
* @returns Promise containing the WhatsApp call ID and room name
|
||||
*/
|
||||
async dialWhatsAppCall(options) {
|
||||
const whatsappBizOpaqueCallbackData = options.whatsappBizOpaqueCallbackData || "";
|
||||
const roomName = options.roomName || "";
|
||||
const participantIdentity = options.participantIdentity || "";
|
||||
const participantName = options.participantName || "";
|
||||
const participantMetadata = options.participantMetadata || "";
|
||||
const destinationCountry = options.destinationCountry || "";
|
||||
const req = new DialWhatsAppCallRequest({
|
||||
whatsappPhoneNumberId: options.whatsappPhoneNumberId,
|
||||
whatsappToPhoneNumber: options.whatsappToPhoneNumber,
|
||||
whatsappApiKey: options.whatsappApiKey,
|
||||
whatsappCloudApiVersion: options.whatsappCloudApiVersion,
|
||||
whatsappBizOpaqueCallbackData,
|
||||
roomName,
|
||||
agents: options.agents,
|
||||
participantIdentity,
|
||||
participantName,
|
||||
participantMetadata,
|
||||
participantAttributes: options.participantAttributes,
|
||||
destinationCountry,
|
||||
ringingTimeout: options.ringingTimeout ? new Duration({ seconds: BigInt(options.ringingTimeout) }) : void 0
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"DialWhatsAppCall",
|
||||
req,
|
||||
await this.authHeader({ roomCreate: true })
|
||||
);
|
||||
return DialWhatsAppCallResponse.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Accept an inbound WhatsApp call
|
||||
*
|
||||
* @param options - WhatsApp call accept options
|
||||
* @returns Promise containing the room name
|
||||
*/
|
||||
async acceptWhatsAppCall(options) {
|
||||
const whatsappBizOpaqueCallbackData = options.whatsappBizOpaqueCallbackData || "";
|
||||
const roomName = options.roomName || "";
|
||||
const participantIdentity = options.participantIdentity || "";
|
||||
const participantName = options.participantName || "";
|
||||
const participantMetadata = options.participantMetadata || "";
|
||||
const destinationCountry = options.destinationCountry || "";
|
||||
const req = new AcceptWhatsAppCallRequest({
|
||||
whatsappPhoneNumberId: options.whatsappPhoneNumberId,
|
||||
whatsappApiKey: options.whatsappApiKey,
|
||||
whatsappCloudApiVersion: options.whatsappCloudApiVersion,
|
||||
whatsappCallId: options.whatsappCallId,
|
||||
whatsappBizOpaqueCallbackData,
|
||||
sdp: options.sdp,
|
||||
roomName,
|
||||
agents: options.agents,
|
||||
participantIdentity,
|
||||
participantName,
|
||||
participantMetadata,
|
||||
participantAttributes: options.participantAttributes,
|
||||
destinationCountry,
|
||||
waitUntilAnswered: options.waitUntilAnswered
|
||||
}).toJson();
|
||||
const timeout = options.waitUntilAnswered ? options.timeout ?? DEFAULT_RINGING_TIMEOUT_SECONDS : options.timeout;
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"AcceptWhatsAppCall",
|
||||
req,
|
||||
await this.authHeader({ roomCreate: true }),
|
||||
timeout
|
||||
);
|
||||
return AcceptWhatsAppCallResponse.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Connect an established WhatsApp call (used for business-initiated calls)
|
||||
*
|
||||
* @param whatsappCallId - Call ID sent by Meta
|
||||
* @param sdp - Session description from Meta
|
||||
*/
|
||||
async connectWhatsAppCall(whatsappCallId, sdp) {
|
||||
const req = new ConnectWhatsAppCallRequest({
|
||||
whatsappCallId,
|
||||
sdp
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ConnectWhatsAppCall",
|
||||
req,
|
||||
await this.authHeader({ roomCreate: true })
|
||||
);
|
||||
return ConnectWhatsAppCallResponse.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Disconnect an active WhatsApp call
|
||||
*
|
||||
* @param whatsappCallId - Call ID sent by Meta
|
||||
* @param whatsappApiKey - The API key of the business that is disconnecting the call.
|
||||
* Required when `disconnectReason` is BUSINESS_INITIATED, optional for USER_INITIATED.
|
||||
* @param disconnectReason - Optional reason for disconnecting the call. Defaults to BUSINESS_INITIATED.
|
||||
*/
|
||||
async disconnectWhatsAppCall(whatsappCallId, whatsappApiKey, disconnectReason) {
|
||||
const req = new DisconnectWhatsAppCallRequest({
|
||||
whatsappCallId,
|
||||
whatsappApiKey,
|
||||
disconnectReason
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"DisconnectWhatsAppCall",
|
||||
req,
|
||||
await this.authHeader({ roomCreate: true })
|
||||
);
|
||||
return DisconnectWhatsAppCallResponse.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Connect a Twilio call to a LiveKit room
|
||||
*
|
||||
* @param options - Twilio call connection options
|
||||
* @returns Promise containing the WebSocket connect URL for Twilio media stream
|
||||
*/
|
||||
async connectTwilioCall(options) {
|
||||
const participantIdentity = options.participantIdentity || "";
|
||||
const participantName = options.participantName || "";
|
||||
const participantMetadata = options.participantMetadata || "";
|
||||
const destinationCountry = options.destinationCountry || "";
|
||||
const req = new ConnectTwilioCallRequest({
|
||||
twilioCallDirection: options.twilioCallDirection,
|
||||
roomName: options.roomName,
|
||||
agents: options.agents,
|
||||
participantIdentity,
|
||||
participantName,
|
||||
participantMetadata,
|
||||
participantAttributes: options.participantAttributes,
|
||||
destinationCountry
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ConnectTwilioCall",
|
||||
req,
|
||||
await this.authHeader({ roomCreate: true })
|
||||
);
|
||||
return ConnectTwilioCallResponse.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
}
|
||||
export {
|
||||
ConnectorClient
|
||||
};
|
||||
//# sourceMappingURL=ConnectorClient.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+390
@@ -0,0 +1,390 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var EgressClient_exports = {};
|
||||
__export(EgressClient_exports, {
|
||||
EgressClient: () => EgressClient
|
||||
});
|
||||
module.exports = __toCommonJS(EgressClient_exports);
|
||||
var import_protocol = require("@livekit/protocol");
|
||||
var import_ServiceBase = require("./ServiceBase.cjs");
|
||||
var import_TwirpRPC = require("./TwirpRPC.cjs");
|
||||
const svc = "Egress";
|
||||
class EgressClient extends import_ServiceBase.ServiceBase {
|
||||
/**
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host, apiKey, secret, options) {
|
||||
super({ apiKey, secret, token: options == null ? void 0 : options.token });
|
||||
this.rpc = new import_TwirpRPC.TwirpRpc(host, import_TwirpRPC.livekitPackage, {
|
||||
requestTimeout: options == null ? void 0 : options.requestTimeout,
|
||||
failover: options == null ? void 0 : options.failover
|
||||
});
|
||||
}
|
||||
async startRoomCompositeEgress(roomName, output, optsOrLayout, options, audioOnly, videoOnly, customBaseUrl, audioMixing) {
|
||||
let layout;
|
||||
let webhooks;
|
||||
if (optsOrLayout !== void 0) {
|
||||
if (typeof optsOrLayout === "string") {
|
||||
layout = optsOrLayout;
|
||||
} else {
|
||||
const opts = optsOrLayout;
|
||||
layout = opts.layout;
|
||||
options = opts.encodingOptions;
|
||||
audioOnly = opts.audioOnly;
|
||||
videoOnly = opts.videoOnly;
|
||||
customBaseUrl = opts.customBaseUrl;
|
||||
audioMixing = opts.audioMixing;
|
||||
webhooks = opts.webhooks;
|
||||
}
|
||||
}
|
||||
layout ??= "";
|
||||
audioOnly ??= false;
|
||||
videoOnly ??= false;
|
||||
customBaseUrl ??= "";
|
||||
audioMixing ??= import_protocol.AudioMixing.DEFAULT_MIXING;
|
||||
const {
|
||||
output: legacyOutput,
|
||||
options: egressOptions,
|
||||
fileOutputs,
|
||||
streamOutputs,
|
||||
segmentOutputs,
|
||||
imageOutputs
|
||||
} = this.getOutputParams(output, options);
|
||||
const req = new import_protocol.RoomCompositeEgressRequest({
|
||||
roomName,
|
||||
layout,
|
||||
audioOnly,
|
||||
audioMixing,
|
||||
videoOnly,
|
||||
customBaseUrl,
|
||||
output: legacyOutput,
|
||||
options: egressOptions,
|
||||
fileOutputs,
|
||||
streamOutputs,
|
||||
segmentOutputs,
|
||||
imageOutputs,
|
||||
webhooks
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"StartRoomCompositeEgress",
|
||||
req,
|
||||
await this.authHeader({ roomRecord: true })
|
||||
);
|
||||
return import_protocol.EgressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* @param url - url
|
||||
* @param output - file or stream output
|
||||
* @param opts - WebOptions
|
||||
*/
|
||||
async startWebEgress(url, output, opts) {
|
||||
const audioOnly = (opts == null ? void 0 : opts.audioOnly) || false;
|
||||
const videoOnly = (opts == null ? void 0 : opts.videoOnly) || false;
|
||||
const awaitStartSignal = (opts == null ? void 0 : opts.awaitStartSignal) || false;
|
||||
const webhooks = (opts == null ? void 0 : opts.webhooks) || [];
|
||||
const {
|
||||
output: legacyOutput,
|
||||
options,
|
||||
fileOutputs,
|
||||
streamOutputs,
|
||||
segmentOutputs,
|
||||
imageOutputs
|
||||
} = this.getOutputParams(output, opts == null ? void 0 : opts.encodingOptions);
|
||||
const req = new import_protocol.WebEgressRequest({
|
||||
url,
|
||||
audioOnly,
|
||||
videoOnly,
|
||||
awaitStartSignal,
|
||||
output: legacyOutput,
|
||||
options,
|
||||
fileOutputs,
|
||||
streamOutputs,
|
||||
segmentOutputs,
|
||||
imageOutputs,
|
||||
webhooks
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"StartWebEgress",
|
||||
req,
|
||||
await this.authHeader({ roomRecord: true })
|
||||
);
|
||||
return import_protocol.EgressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Export a participant's audio and video tracks,
|
||||
*
|
||||
* @param roomName - room name
|
||||
* @param output - one or more outputs
|
||||
* @param opts - ParticipantEgressOptions
|
||||
*/
|
||||
async startParticipantEgress(roomName, identity, output, opts) {
|
||||
const webhooks = (opts == null ? void 0 : opts.webhooks) || [];
|
||||
const { options, fileOutputs, streamOutputs, segmentOutputs, imageOutputs } = this.getOutputParams(output, opts == null ? void 0 : opts.encodingOptions);
|
||||
const req = new import_protocol.ParticipantEgressRequest({
|
||||
roomName,
|
||||
identity,
|
||||
screenShare: (opts == null ? void 0 : opts.screenShare) ?? false,
|
||||
options,
|
||||
fileOutputs,
|
||||
streamOutputs,
|
||||
segmentOutputs,
|
||||
imageOutputs,
|
||||
webhooks
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"StartParticipantEgress",
|
||||
req,
|
||||
await this.authHeader({ roomRecord: true })
|
||||
);
|
||||
return import_protocol.EgressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
async startTrackCompositeEgress(roomName, output, optsOrAudioTrackId, videoTrackId, options) {
|
||||
let audioTrackId;
|
||||
let webhooks;
|
||||
if (optsOrAudioTrackId !== void 0) {
|
||||
if (typeof optsOrAudioTrackId === "string") {
|
||||
audioTrackId = optsOrAudioTrackId;
|
||||
} else {
|
||||
const opts = optsOrAudioTrackId;
|
||||
audioTrackId = opts.audioTrackId;
|
||||
videoTrackId = opts.videoTrackId;
|
||||
options = opts.encodingOptions;
|
||||
webhooks = opts.webhooks;
|
||||
}
|
||||
}
|
||||
audioTrackId ??= "";
|
||||
videoTrackId ??= "";
|
||||
const {
|
||||
output: legacyOutput,
|
||||
options: egressOptions,
|
||||
fileOutputs,
|
||||
streamOutputs,
|
||||
segmentOutputs,
|
||||
imageOutputs
|
||||
} = this.getOutputParams(output, options);
|
||||
const req = new import_protocol.TrackCompositeEgressRequest({
|
||||
roomName,
|
||||
audioTrackId,
|
||||
videoTrackId,
|
||||
output: legacyOutput,
|
||||
options: egressOptions,
|
||||
fileOutputs,
|
||||
streamOutputs,
|
||||
segmentOutputs,
|
||||
imageOutputs,
|
||||
webhooks
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"StartTrackCompositeEgress",
|
||||
req,
|
||||
await this.authHeader({ roomRecord: true })
|
||||
);
|
||||
return import_protocol.EgressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
isEncodedOutputs(output) {
|
||||
return output.file !== void 0 || output.stream !== void 0 || output.segments !== void 0 || output.images !== void 0;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
isEncodedFileOutput(output) {
|
||||
return output.filepath !== void 0 || output.fileType !== void 0;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
isSegmentedFileOutput(output) {
|
||||
return output.filenamePrefix !== void 0 || output.playlistName !== void 0 || output.filenameSuffix !== void 0;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
isStreamOutput(output) {
|
||||
return output.protocol !== void 0 || output.urls !== void 0;
|
||||
}
|
||||
getOutputParams(output, opts) {
|
||||
let file;
|
||||
let fileOutputs;
|
||||
let stream;
|
||||
let streamOutputs;
|
||||
let segments;
|
||||
let segmentOutputs;
|
||||
let imageOutputs;
|
||||
if (this.isEncodedOutputs(output)) {
|
||||
if (output.file !== void 0) {
|
||||
fileOutputs = [output.file];
|
||||
}
|
||||
if (output.stream !== void 0) {
|
||||
streamOutputs = [output.stream];
|
||||
}
|
||||
if (output.segments !== void 0) {
|
||||
segmentOutputs = [output.segments];
|
||||
}
|
||||
if (output.images !== void 0) {
|
||||
imageOutputs = [output.images];
|
||||
}
|
||||
} else if (this.isEncodedFileOutput(output)) {
|
||||
file = output;
|
||||
fileOutputs = [file];
|
||||
} else if (this.isSegmentedFileOutput(output)) {
|
||||
segments = output;
|
||||
segmentOutputs = [segments];
|
||||
} else if (this.isStreamOutput(output)) {
|
||||
stream = output;
|
||||
streamOutputs = [stream];
|
||||
}
|
||||
let legacyOutput;
|
||||
if (file) {
|
||||
legacyOutput = {
|
||||
case: "file",
|
||||
value: file
|
||||
};
|
||||
} else if (stream) {
|
||||
legacyOutput = {
|
||||
case: "stream",
|
||||
value: stream
|
||||
};
|
||||
} else if (segments) {
|
||||
legacyOutput = {
|
||||
case: "segments",
|
||||
value: segments
|
||||
};
|
||||
}
|
||||
let egressOptions;
|
||||
if (opts) {
|
||||
if (typeof opts === "number") {
|
||||
egressOptions = {
|
||||
case: "preset",
|
||||
value: opts
|
||||
};
|
||||
} else {
|
||||
egressOptions = {
|
||||
case: "advanced",
|
||||
value: opts
|
||||
};
|
||||
}
|
||||
}
|
||||
return {
|
||||
output: legacyOutput,
|
||||
options: egressOptions,
|
||||
fileOutputs,
|
||||
streamOutputs,
|
||||
segmentOutputs,
|
||||
imageOutputs
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @param roomName - room name
|
||||
* @param output - file or websocket output
|
||||
* @param trackId - track Id
|
||||
*/
|
||||
async startTrackEgress(roomName, output, trackId, webhooks) {
|
||||
let legacyOutput;
|
||||
if (typeof output === "string") {
|
||||
legacyOutput = {
|
||||
case: "websocketUrl",
|
||||
value: output
|
||||
};
|
||||
} else {
|
||||
legacyOutput = {
|
||||
case: "file",
|
||||
value: output
|
||||
};
|
||||
}
|
||||
const req = new import_protocol.TrackEgressRequest({
|
||||
roomName,
|
||||
trackId,
|
||||
output: legacyOutput,
|
||||
webhooks
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"StartTrackEgress",
|
||||
req,
|
||||
await this.authHeader({ roomRecord: true })
|
||||
);
|
||||
return import_protocol.EgressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* @param egressId -
|
||||
* @param layout -
|
||||
*/
|
||||
async updateLayout(egressId, layout) {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateLayout",
|
||||
new import_protocol.UpdateLayoutRequest({ egressId, layout }).toJson(),
|
||||
await this.authHeader({ roomRecord: true })
|
||||
);
|
||||
return import_protocol.EgressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* @param egressId -
|
||||
* @param addOutputUrls -
|
||||
* @param removeOutputUrls -
|
||||
*/
|
||||
async updateStream(egressId, addOutputUrls, removeOutputUrls) {
|
||||
addOutputUrls ??= [];
|
||||
removeOutputUrls ??= [];
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateStream",
|
||||
new import_protocol.UpdateStreamRequest({ egressId, addOutputUrls, removeOutputUrls }).toJson(),
|
||||
await this.authHeader({ roomRecord: true })
|
||||
);
|
||||
return import_protocol.EgressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* @param roomName - list egress for one room only
|
||||
*/
|
||||
async listEgress(options) {
|
||||
let req = {};
|
||||
if (typeof options === "string") {
|
||||
req.roomName = options;
|
||||
} else if (options !== void 0) {
|
||||
req = options;
|
||||
}
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ListEgress",
|
||||
new import_protocol.ListEgressRequest(req).toJson(),
|
||||
await this.authHeader({ roomRecord: true })
|
||||
);
|
||||
return import_protocol.ListEgressResponse.fromJson(data, { ignoreUnknownFields: true }).items ?? [];
|
||||
}
|
||||
/**
|
||||
* @param egressId -
|
||||
*/
|
||||
async stopEgress(egressId) {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"StopEgress",
|
||||
new import_protocol.StopEgressRequest({ egressId }).toJson(),
|
||||
await this.authHeader({ roomRecord: true })
|
||||
);
|
||||
return import_protocol.EgressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
EgressClient
|
||||
});
|
||||
//# sourceMappingURL=EgressClient.cjs.map
|
||||
+1
File diff suppressed because one or more lines are too long
+180
@@ -0,0 +1,180 @@
|
||||
import { WebhookConfig, EncodedFileOutput, StreamOutput, SegmentedFileOutput, ImageOutput, EncodingOptionsPreset, EncodingOptions, AudioMixing, EgressInfo, DirectFileOutput } from '@livekit/protocol';
|
||||
import { ClientOptions } from './ClientOptions.cjs';
|
||||
import { ServiceBase } from './ServiceBase.cjs';
|
||||
import './grants.cjs';
|
||||
import 'jose';
|
||||
|
||||
interface BaseOptions {
|
||||
/**
|
||||
* webhooks to call for this request, optional.
|
||||
*/
|
||||
webhooks?: WebhookConfig[];
|
||||
}
|
||||
interface RoomCompositeOptions extends BaseOptions {
|
||||
/**
|
||||
* egress layout. optional
|
||||
*/
|
||||
layout?: string;
|
||||
/**
|
||||
* encoding options or preset. optional
|
||||
*/
|
||||
encodingOptions?: EncodingOptionsPreset | EncodingOptions;
|
||||
/**
|
||||
* record audio only. optional
|
||||
*/
|
||||
audioOnly?: boolean;
|
||||
/**
|
||||
* record video only. optional
|
||||
*/
|
||||
videoOnly?: boolean;
|
||||
/**
|
||||
* custom template url. optional
|
||||
*/
|
||||
customBaseUrl?: string;
|
||||
/**
|
||||
* audio mixing options. optional
|
||||
*/
|
||||
audioMixing?: AudioMixing;
|
||||
}
|
||||
interface WebOptions extends BaseOptions {
|
||||
/**
|
||||
* encoding options or preset. optional
|
||||
*/
|
||||
encodingOptions?: EncodingOptionsPreset | EncodingOptions;
|
||||
/**
|
||||
* record audio only. optional
|
||||
*/
|
||||
audioOnly?: boolean;
|
||||
/**
|
||||
* record video only. optional
|
||||
*/
|
||||
videoOnly?: boolean;
|
||||
/**
|
||||
* await START_RECORDING chrome log
|
||||
*/
|
||||
awaitStartSignal?: boolean;
|
||||
}
|
||||
interface ParticipantEgressOptions extends BaseOptions {
|
||||
/**
|
||||
* true to capture source screenshare and screenshare_audio
|
||||
* false to capture camera and microphone
|
||||
*/
|
||||
screenShare?: boolean;
|
||||
/**
|
||||
* encoding options or preset. optional
|
||||
*/
|
||||
encodingOptions?: EncodingOptionsPreset | EncodingOptions;
|
||||
}
|
||||
interface TrackCompositeOptions extends BaseOptions {
|
||||
/**
|
||||
* audio track ID
|
||||
*/
|
||||
audioTrackId?: string;
|
||||
/**
|
||||
* video track ID
|
||||
*/
|
||||
videoTrackId?: string;
|
||||
/**
|
||||
* encoding options or preset. optional
|
||||
*/
|
||||
encodingOptions?: EncodingOptionsPreset | EncodingOptions;
|
||||
}
|
||||
/**
|
||||
* Used to supply multiple outputs with an egress request
|
||||
*/
|
||||
interface EncodedOutputs {
|
||||
file?: EncodedFileOutput | undefined;
|
||||
stream?: StreamOutput | undefined;
|
||||
segments?: SegmentedFileOutput | undefined;
|
||||
images?: ImageOutput | undefined;
|
||||
}
|
||||
interface ListEgressOptions {
|
||||
roomName?: string;
|
||||
egressId?: string;
|
||||
active?: boolean;
|
||||
}
|
||||
/**
|
||||
* Client to access Egress APIs
|
||||
*/
|
||||
declare class EgressClient extends ServiceBase {
|
||||
private readonly rpc;
|
||||
/**
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host: string, apiKey?: string, secret?: string, options?: ClientOptions);
|
||||
/**
|
||||
* @param roomName - room name
|
||||
* @param output - file or stream output
|
||||
* @param opts - RoomCompositeOptions
|
||||
*/
|
||||
startRoomCompositeEgress(roomName: string, output: EncodedOutputs | EncodedFileOutput | StreamOutput | SegmentedFileOutput, opts?: RoomCompositeOptions): Promise<EgressInfo>;
|
||||
/**
|
||||
* @deprecated use RoomCompositeOptions instead
|
||||
*/
|
||||
startRoomCompositeEgress(roomName: string, output: EncodedOutputs | EncodedFileOutput | StreamOutput | SegmentedFileOutput, layout?: string, options?: EncodingOptionsPreset | EncodingOptions, audioOnly?: boolean, videoOnly?: boolean, customBaseUrl?: string, audioMixing?: AudioMixing): Promise<EgressInfo>;
|
||||
/**
|
||||
* @param url - url
|
||||
* @param output - file or stream output
|
||||
* @param opts - WebOptions
|
||||
*/
|
||||
startWebEgress(url: string, output: EncodedOutputs | EncodedFileOutput | StreamOutput | SegmentedFileOutput, opts?: WebOptions): Promise<EgressInfo>;
|
||||
/**
|
||||
* Export a participant's audio and video tracks,
|
||||
*
|
||||
* @param roomName - room name
|
||||
* @param output - one or more outputs
|
||||
* @param opts - ParticipantEgressOptions
|
||||
*/
|
||||
startParticipantEgress(roomName: string, identity: string, output: EncodedOutputs, opts?: ParticipantEgressOptions): Promise<EgressInfo>;
|
||||
/**
|
||||
* @param roomName - room name
|
||||
* @param output - file or stream output
|
||||
* @param opts - TrackCompositeOptions
|
||||
*/
|
||||
startTrackCompositeEgress(roomName: string, output: EncodedOutputs | EncodedFileOutput | StreamOutput | SegmentedFileOutput, opts?: TrackCompositeOptions): Promise<EgressInfo>;
|
||||
/**
|
||||
* @deprecated use TrackCompositeOptions instead
|
||||
*/
|
||||
startTrackCompositeEgress(roomName: string, output: EncodedOutputs | EncodedFileOutput | StreamOutput | SegmentedFileOutput, audioTrackId?: string, videoTrackId?: string, options?: EncodingOptionsPreset | EncodingOptions): Promise<EgressInfo>;
|
||||
private isEncodedOutputs;
|
||||
private isEncodedFileOutput;
|
||||
private isSegmentedFileOutput;
|
||||
private isStreamOutput;
|
||||
private getOutputParams;
|
||||
/**
|
||||
* @param roomName - room name
|
||||
* @param output - file or websocket output
|
||||
* @param trackId - track Id
|
||||
*/
|
||||
startTrackEgress(roomName: string, output: DirectFileOutput | string, trackId: string, webhooks?: WebhookConfig[]): Promise<EgressInfo>;
|
||||
/**
|
||||
* @param egressId -
|
||||
* @param layout -
|
||||
*/
|
||||
updateLayout(egressId: string, layout: string): Promise<EgressInfo>;
|
||||
/**
|
||||
* @param egressId -
|
||||
* @param addOutputUrls -
|
||||
* @param removeOutputUrls -
|
||||
*/
|
||||
updateStream(egressId: string, addOutputUrls?: string[], removeOutputUrls?: string[]): Promise<EgressInfo>;
|
||||
/**
|
||||
* @param options - options to filter listed Egresses, by default returns all
|
||||
* Egress instances
|
||||
*/
|
||||
listEgress(options?: ListEgressOptions): Promise<Array<EgressInfo>>;
|
||||
/**
|
||||
* @deprecated use `listEgress(options?: ListEgressOptions)` instead
|
||||
* @param roomName - list egress for one room only
|
||||
*/
|
||||
listEgress(roomName?: string): Promise<Array<EgressInfo>>;
|
||||
/**
|
||||
* @param egressId -
|
||||
*/
|
||||
stopEgress(egressId: string): Promise<EgressInfo>;
|
||||
}
|
||||
|
||||
export { type BaseOptions, EgressClient, type EncodedOutputs, type ListEgressOptions, type ParticipantEgressOptions, type RoomCompositeOptions, type TrackCompositeOptions, type WebOptions };
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
import { WebhookConfig, EncodedFileOutput, StreamOutput, SegmentedFileOutput, ImageOutput, EncodingOptionsPreset, EncodingOptions, AudioMixing, EgressInfo, DirectFileOutput } from '@livekit/protocol';
|
||||
import { ClientOptions } from './ClientOptions.js';
|
||||
import { ServiceBase } from './ServiceBase.js';
|
||||
import './grants.js';
|
||||
import 'jose';
|
||||
|
||||
interface BaseOptions {
|
||||
/**
|
||||
* webhooks to call for this request, optional.
|
||||
*/
|
||||
webhooks?: WebhookConfig[];
|
||||
}
|
||||
interface RoomCompositeOptions extends BaseOptions {
|
||||
/**
|
||||
* egress layout. optional
|
||||
*/
|
||||
layout?: string;
|
||||
/**
|
||||
* encoding options or preset. optional
|
||||
*/
|
||||
encodingOptions?: EncodingOptionsPreset | EncodingOptions;
|
||||
/**
|
||||
* record audio only. optional
|
||||
*/
|
||||
audioOnly?: boolean;
|
||||
/**
|
||||
* record video only. optional
|
||||
*/
|
||||
videoOnly?: boolean;
|
||||
/**
|
||||
* custom template url. optional
|
||||
*/
|
||||
customBaseUrl?: string;
|
||||
/**
|
||||
* audio mixing options. optional
|
||||
*/
|
||||
audioMixing?: AudioMixing;
|
||||
}
|
||||
interface WebOptions extends BaseOptions {
|
||||
/**
|
||||
* encoding options or preset. optional
|
||||
*/
|
||||
encodingOptions?: EncodingOptionsPreset | EncodingOptions;
|
||||
/**
|
||||
* record audio only. optional
|
||||
*/
|
||||
audioOnly?: boolean;
|
||||
/**
|
||||
* record video only. optional
|
||||
*/
|
||||
videoOnly?: boolean;
|
||||
/**
|
||||
* await START_RECORDING chrome log
|
||||
*/
|
||||
awaitStartSignal?: boolean;
|
||||
}
|
||||
interface ParticipantEgressOptions extends BaseOptions {
|
||||
/**
|
||||
* true to capture source screenshare and screenshare_audio
|
||||
* false to capture camera and microphone
|
||||
*/
|
||||
screenShare?: boolean;
|
||||
/**
|
||||
* encoding options or preset. optional
|
||||
*/
|
||||
encodingOptions?: EncodingOptionsPreset | EncodingOptions;
|
||||
}
|
||||
interface TrackCompositeOptions extends BaseOptions {
|
||||
/**
|
||||
* audio track ID
|
||||
*/
|
||||
audioTrackId?: string;
|
||||
/**
|
||||
* video track ID
|
||||
*/
|
||||
videoTrackId?: string;
|
||||
/**
|
||||
* encoding options or preset. optional
|
||||
*/
|
||||
encodingOptions?: EncodingOptionsPreset | EncodingOptions;
|
||||
}
|
||||
/**
|
||||
* Used to supply multiple outputs with an egress request
|
||||
*/
|
||||
interface EncodedOutputs {
|
||||
file?: EncodedFileOutput | undefined;
|
||||
stream?: StreamOutput | undefined;
|
||||
segments?: SegmentedFileOutput | undefined;
|
||||
images?: ImageOutput | undefined;
|
||||
}
|
||||
interface ListEgressOptions {
|
||||
roomName?: string;
|
||||
egressId?: string;
|
||||
active?: boolean;
|
||||
}
|
||||
/**
|
||||
* Client to access Egress APIs
|
||||
*/
|
||||
declare class EgressClient extends ServiceBase {
|
||||
private readonly rpc;
|
||||
/**
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host: string, apiKey?: string, secret?: string, options?: ClientOptions);
|
||||
/**
|
||||
* @param roomName - room name
|
||||
* @param output - file or stream output
|
||||
* @param opts - RoomCompositeOptions
|
||||
*/
|
||||
startRoomCompositeEgress(roomName: string, output: EncodedOutputs | EncodedFileOutput | StreamOutput | SegmentedFileOutput, opts?: RoomCompositeOptions): Promise<EgressInfo>;
|
||||
/**
|
||||
* @deprecated use RoomCompositeOptions instead
|
||||
*/
|
||||
startRoomCompositeEgress(roomName: string, output: EncodedOutputs | EncodedFileOutput | StreamOutput | SegmentedFileOutput, layout?: string, options?: EncodingOptionsPreset | EncodingOptions, audioOnly?: boolean, videoOnly?: boolean, customBaseUrl?: string, audioMixing?: AudioMixing): Promise<EgressInfo>;
|
||||
/**
|
||||
* @param url - url
|
||||
* @param output - file or stream output
|
||||
* @param opts - WebOptions
|
||||
*/
|
||||
startWebEgress(url: string, output: EncodedOutputs | EncodedFileOutput | StreamOutput | SegmentedFileOutput, opts?: WebOptions): Promise<EgressInfo>;
|
||||
/**
|
||||
* Export a participant's audio and video tracks,
|
||||
*
|
||||
* @param roomName - room name
|
||||
* @param output - one or more outputs
|
||||
* @param opts - ParticipantEgressOptions
|
||||
*/
|
||||
startParticipantEgress(roomName: string, identity: string, output: EncodedOutputs, opts?: ParticipantEgressOptions): Promise<EgressInfo>;
|
||||
/**
|
||||
* @param roomName - room name
|
||||
* @param output - file or stream output
|
||||
* @param opts - TrackCompositeOptions
|
||||
*/
|
||||
startTrackCompositeEgress(roomName: string, output: EncodedOutputs | EncodedFileOutput | StreamOutput | SegmentedFileOutput, opts?: TrackCompositeOptions): Promise<EgressInfo>;
|
||||
/**
|
||||
* @deprecated use TrackCompositeOptions instead
|
||||
*/
|
||||
startTrackCompositeEgress(roomName: string, output: EncodedOutputs | EncodedFileOutput | StreamOutput | SegmentedFileOutput, audioTrackId?: string, videoTrackId?: string, options?: EncodingOptionsPreset | EncodingOptions): Promise<EgressInfo>;
|
||||
private isEncodedOutputs;
|
||||
private isEncodedFileOutput;
|
||||
private isSegmentedFileOutput;
|
||||
private isStreamOutput;
|
||||
private getOutputParams;
|
||||
/**
|
||||
* @param roomName - room name
|
||||
* @param output - file or websocket output
|
||||
* @param trackId - track Id
|
||||
*/
|
||||
startTrackEgress(roomName: string, output: DirectFileOutput | string, trackId: string, webhooks?: WebhookConfig[]): Promise<EgressInfo>;
|
||||
/**
|
||||
* @param egressId -
|
||||
* @param layout -
|
||||
*/
|
||||
updateLayout(egressId: string, layout: string): Promise<EgressInfo>;
|
||||
/**
|
||||
* @param egressId -
|
||||
* @param addOutputUrls -
|
||||
* @param removeOutputUrls -
|
||||
*/
|
||||
updateStream(egressId: string, addOutputUrls?: string[], removeOutputUrls?: string[]): Promise<EgressInfo>;
|
||||
/**
|
||||
* @param options - options to filter listed Egresses, by default returns all
|
||||
* Egress instances
|
||||
*/
|
||||
listEgress(options?: ListEgressOptions): Promise<Array<EgressInfo>>;
|
||||
/**
|
||||
* @deprecated use `listEgress(options?: ListEgressOptions)` instead
|
||||
* @param roomName - list egress for one room only
|
||||
*/
|
||||
listEgress(roomName?: string): Promise<Array<EgressInfo>>;
|
||||
/**
|
||||
* @param egressId -
|
||||
*/
|
||||
stopEgress(egressId: string): Promise<EgressInfo>;
|
||||
}
|
||||
|
||||
export { type BaseOptions, EgressClient, type EncodedOutputs, type ListEgressOptions, type ParticipantEgressOptions, type RoomCompositeOptions, type TrackCompositeOptions, type WebOptions };
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"EgressClient.d.ts","sourceRoot":"","sources":["../src/EgressClient.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,qBAAqB,EACrB,WAAW,EACX,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,WAAW,EACX,UAAU,EAWX,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAM/C,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAqB,SAAQ,WAAW;IACvD;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,eAAe,CAAC,EAAE,qBAAqB,GAAG,eAAe,CAAC;IAC1D;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C;;OAEG;IACH,eAAe,CAAC,EAAE,qBAAqB,GAAG,eAAe,CAAC;IAC1D;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAyB,SAAQ,WAAW;IAC3D;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;OAEG;IACH,eAAe,CAAC,EAAE,qBAAqB,GAAG,eAAe,CAAC;CAC3D;AAED,MAAM,WAAW,qBAAsB,SAAQ,WAAW;IACxD;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,eAAe,CAAC,EAAE,qBAAqB,GAAG,eAAe,CAAC;CAC3D;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACrC,MAAM,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;IAC3C,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,WAAW;IAC3C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAE1B;;;;;OAKG;gBACS,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa;IAQnF;;;;OAIG;IACG,wBAAwB,CAC5B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,GAAG,iBAAiB,GAAG,YAAY,GAAG,mBAAmB,EAC/E,IAAI,CAAC,EAAE,oBAAoB,GAC1B,OAAO,CAAC,UAAU,CAAC;IACtB;;OAEG;IACG,wBAAwB,CAC5B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,GAAG,iBAAiB,GAAG,YAAY,GAAG,mBAAmB,EAC/E,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,qBAAqB,GAAG,eAAe,EACjD,SAAS,CAAC,EAAE,OAAO,EACnB,SAAS,CAAC,EAAE,OAAO,EACnB,aAAa,CAAC,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,UAAU,CAAC;IAoEtB;;;;OAIG;IACG,cAAc,CAClB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,cAAc,GAAG,iBAAiB,GAAG,YAAY,GAAG,mBAAmB,EAC/E,IAAI,CAAC,EAAE,UAAU,GAChB,OAAO,CAAC,UAAU,CAAC;IAqCtB;;;;;;OAMG;IACG,sBAAsB,CAC1B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,EACtB,IAAI,CAAC,EAAE,wBAAwB,GAC9B,OAAO,CAAC,UAAU,CAAC;IAyBtB;;;;OAIG;IACG,yBAAyB,CAC7B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,GAAG,iBAAiB,GAAG,YAAY,GAAG,mBAAmB,EAC/E,IAAI,CAAC,EAAE,qBAAqB,GAC3B,OAAO,CAAC,UAAU,CAAC;IACtB;;OAEG;IACG,yBAAyB,CAC7B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,GAAG,iBAAiB,GAAG,YAAY,GAAG,mBAAmB,EAC/E,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,qBAAqB,GAAG,eAAe,GAChD,OAAO,CAAC,UAAU,CAAC;IAwDtB,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,qBAAqB;IAS7B,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,eAAe;IAqGvB;;;;OAIG;IACG,gBAAgB,CACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,gBAAgB,GAAG,MAAM,EACjC,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,aAAa,EAAE,GACzB,OAAO,CAAC,UAAU,CAAC;IAwCtB;;;OAGG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAUzE;;;;OAIG;IACG,YAAY,CAChB,QAAQ,EAAE,MAAM,EAChB,aAAa,CAAC,EAAE,MAAM,EAAE,EACxB,gBAAgB,CAAC,EAAE,MAAM,EAAE,GAC1B,OAAO,CAAC,UAAU,CAAC;IAatB;;;OAGG;IACG,UAAU,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACzE;;;OAGG;IACG,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAqB/D;;OAEG;IACG,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;CASxD"}
|
||||
+379
@@ -0,0 +1,379 @@
|
||||
import {
|
||||
AudioMixing,
|
||||
EgressInfo,
|
||||
ListEgressRequest,
|
||||
ListEgressResponse,
|
||||
ParticipantEgressRequest,
|
||||
RoomCompositeEgressRequest,
|
||||
StopEgressRequest,
|
||||
TrackCompositeEgressRequest,
|
||||
TrackEgressRequest,
|
||||
UpdateLayoutRequest,
|
||||
UpdateStreamRequest,
|
||||
WebEgressRequest
|
||||
} from "@livekit/protocol";
|
||||
import { ServiceBase } from "./ServiceBase.js";
|
||||
import { TwirpRpc, livekitPackage } from "./TwirpRPC.js";
|
||||
const svc = "Egress";
|
||||
class EgressClient extends ServiceBase {
|
||||
/**
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host, apiKey, secret, options) {
|
||||
super({ apiKey, secret, token: options == null ? void 0 : options.token });
|
||||
this.rpc = new TwirpRpc(host, livekitPackage, {
|
||||
requestTimeout: options == null ? void 0 : options.requestTimeout,
|
||||
failover: options == null ? void 0 : options.failover
|
||||
});
|
||||
}
|
||||
async startRoomCompositeEgress(roomName, output, optsOrLayout, options, audioOnly, videoOnly, customBaseUrl, audioMixing) {
|
||||
let layout;
|
||||
let webhooks;
|
||||
if (optsOrLayout !== void 0) {
|
||||
if (typeof optsOrLayout === "string") {
|
||||
layout = optsOrLayout;
|
||||
} else {
|
||||
const opts = optsOrLayout;
|
||||
layout = opts.layout;
|
||||
options = opts.encodingOptions;
|
||||
audioOnly = opts.audioOnly;
|
||||
videoOnly = opts.videoOnly;
|
||||
customBaseUrl = opts.customBaseUrl;
|
||||
audioMixing = opts.audioMixing;
|
||||
webhooks = opts.webhooks;
|
||||
}
|
||||
}
|
||||
layout ??= "";
|
||||
audioOnly ??= false;
|
||||
videoOnly ??= false;
|
||||
customBaseUrl ??= "";
|
||||
audioMixing ??= AudioMixing.DEFAULT_MIXING;
|
||||
const {
|
||||
output: legacyOutput,
|
||||
options: egressOptions,
|
||||
fileOutputs,
|
||||
streamOutputs,
|
||||
segmentOutputs,
|
||||
imageOutputs
|
||||
} = this.getOutputParams(output, options);
|
||||
const req = new RoomCompositeEgressRequest({
|
||||
roomName,
|
||||
layout,
|
||||
audioOnly,
|
||||
audioMixing,
|
||||
videoOnly,
|
||||
customBaseUrl,
|
||||
output: legacyOutput,
|
||||
options: egressOptions,
|
||||
fileOutputs,
|
||||
streamOutputs,
|
||||
segmentOutputs,
|
||||
imageOutputs,
|
||||
webhooks
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"StartRoomCompositeEgress",
|
||||
req,
|
||||
await this.authHeader({ roomRecord: true })
|
||||
);
|
||||
return EgressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* @param url - url
|
||||
* @param output - file or stream output
|
||||
* @param opts - WebOptions
|
||||
*/
|
||||
async startWebEgress(url, output, opts) {
|
||||
const audioOnly = (opts == null ? void 0 : opts.audioOnly) || false;
|
||||
const videoOnly = (opts == null ? void 0 : opts.videoOnly) || false;
|
||||
const awaitStartSignal = (opts == null ? void 0 : opts.awaitStartSignal) || false;
|
||||
const webhooks = (opts == null ? void 0 : opts.webhooks) || [];
|
||||
const {
|
||||
output: legacyOutput,
|
||||
options,
|
||||
fileOutputs,
|
||||
streamOutputs,
|
||||
segmentOutputs,
|
||||
imageOutputs
|
||||
} = this.getOutputParams(output, opts == null ? void 0 : opts.encodingOptions);
|
||||
const req = new WebEgressRequest({
|
||||
url,
|
||||
audioOnly,
|
||||
videoOnly,
|
||||
awaitStartSignal,
|
||||
output: legacyOutput,
|
||||
options,
|
||||
fileOutputs,
|
||||
streamOutputs,
|
||||
segmentOutputs,
|
||||
imageOutputs,
|
||||
webhooks
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"StartWebEgress",
|
||||
req,
|
||||
await this.authHeader({ roomRecord: true })
|
||||
);
|
||||
return EgressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Export a participant's audio and video tracks,
|
||||
*
|
||||
* @param roomName - room name
|
||||
* @param output - one or more outputs
|
||||
* @param opts - ParticipantEgressOptions
|
||||
*/
|
||||
async startParticipantEgress(roomName, identity, output, opts) {
|
||||
const webhooks = (opts == null ? void 0 : opts.webhooks) || [];
|
||||
const { options, fileOutputs, streamOutputs, segmentOutputs, imageOutputs } = this.getOutputParams(output, opts == null ? void 0 : opts.encodingOptions);
|
||||
const req = new ParticipantEgressRequest({
|
||||
roomName,
|
||||
identity,
|
||||
screenShare: (opts == null ? void 0 : opts.screenShare) ?? false,
|
||||
options,
|
||||
fileOutputs,
|
||||
streamOutputs,
|
||||
segmentOutputs,
|
||||
imageOutputs,
|
||||
webhooks
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"StartParticipantEgress",
|
||||
req,
|
||||
await this.authHeader({ roomRecord: true })
|
||||
);
|
||||
return EgressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
async startTrackCompositeEgress(roomName, output, optsOrAudioTrackId, videoTrackId, options) {
|
||||
let audioTrackId;
|
||||
let webhooks;
|
||||
if (optsOrAudioTrackId !== void 0) {
|
||||
if (typeof optsOrAudioTrackId === "string") {
|
||||
audioTrackId = optsOrAudioTrackId;
|
||||
} else {
|
||||
const opts = optsOrAudioTrackId;
|
||||
audioTrackId = opts.audioTrackId;
|
||||
videoTrackId = opts.videoTrackId;
|
||||
options = opts.encodingOptions;
|
||||
webhooks = opts.webhooks;
|
||||
}
|
||||
}
|
||||
audioTrackId ??= "";
|
||||
videoTrackId ??= "";
|
||||
const {
|
||||
output: legacyOutput,
|
||||
options: egressOptions,
|
||||
fileOutputs,
|
||||
streamOutputs,
|
||||
segmentOutputs,
|
||||
imageOutputs
|
||||
} = this.getOutputParams(output, options);
|
||||
const req = new TrackCompositeEgressRequest({
|
||||
roomName,
|
||||
audioTrackId,
|
||||
videoTrackId,
|
||||
output: legacyOutput,
|
||||
options: egressOptions,
|
||||
fileOutputs,
|
||||
streamOutputs,
|
||||
segmentOutputs,
|
||||
imageOutputs,
|
||||
webhooks
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"StartTrackCompositeEgress",
|
||||
req,
|
||||
await this.authHeader({ roomRecord: true })
|
||||
);
|
||||
return EgressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
isEncodedOutputs(output) {
|
||||
return output.file !== void 0 || output.stream !== void 0 || output.segments !== void 0 || output.images !== void 0;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
isEncodedFileOutput(output) {
|
||||
return output.filepath !== void 0 || output.fileType !== void 0;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
isSegmentedFileOutput(output) {
|
||||
return output.filenamePrefix !== void 0 || output.playlistName !== void 0 || output.filenameSuffix !== void 0;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
isStreamOutput(output) {
|
||||
return output.protocol !== void 0 || output.urls !== void 0;
|
||||
}
|
||||
getOutputParams(output, opts) {
|
||||
let file;
|
||||
let fileOutputs;
|
||||
let stream;
|
||||
let streamOutputs;
|
||||
let segments;
|
||||
let segmentOutputs;
|
||||
let imageOutputs;
|
||||
if (this.isEncodedOutputs(output)) {
|
||||
if (output.file !== void 0) {
|
||||
fileOutputs = [output.file];
|
||||
}
|
||||
if (output.stream !== void 0) {
|
||||
streamOutputs = [output.stream];
|
||||
}
|
||||
if (output.segments !== void 0) {
|
||||
segmentOutputs = [output.segments];
|
||||
}
|
||||
if (output.images !== void 0) {
|
||||
imageOutputs = [output.images];
|
||||
}
|
||||
} else if (this.isEncodedFileOutput(output)) {
|
||||
file = output;
|
||||
fileOutputs = [file];
|
||||
} else if (this.isSegmentedFileOutput(output)) {
|
||||
segments = output;
|
||||
segmentOutputs = [segments];
|
||||
} else if (this.isStreamOutput(output)) {
|
||||
stream = output;
|
||||
streamOutputs = [stream];
|
||||
}
|
||||
let legacyOutput;
|
||||
if (file) {
|
||||
legacyOutput = {
|
||||
case: "file",
|
||||
value: file
|
||||
};
|
||||
} else if (stream) {
|
||||
legacyOutput = {
|
||||
case: "stream",
|
||||
value: stream
|
||||
};
|
||||
} else if (segments) {
|
||||
legacyOutput = {
|
||||
case: "segments",
|
||||
value: segments
|
||||
};
|
||||
}
|
||||
let egressOptions;
|
||||
if (opts) {
|
||||
if (typeof opts === "number") {
|
||||
egressOptions = {
|
||||
case: "preset",
|
||||
value: opts
|
||||
};
|
||||
} else {
|
||||
egressOptions = {
|
||||
case: "advanced",
|
||||
value: opts
|
||||
};
|
||||
}
|
||||
}
|
||||
return {
|
||||
output: legacyOutput,
|
||||
options: egressOptions,
|
||||
fileOutputs,
|
||||
streamOutputs,
|
||||
segmentOutputs,
|
||||
imageOutputs
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @param roomName - room name
|
||||
* @param output - file or websocket output
|
||||
* @param trackId - track Id
|
||||
*/
|
||||
async startTrackEgress(roomName, output, trackId, webhooks) {
|
||||
let legacyOutput;
|
||||
if (typeof output === "string") {
|
||||
legacyOutput = {
|
||||
case: "websocketUrl",
|
||||
value: output
|
||||
};
|
||||
} else {
|
||||
legacyOutput = {
|
||||
case: "file",
|
||||
value: output
|
||||
};
|
||||
}
|
||||
const req = new TrackEgressRequest({
|
||||
roomName,
|
||||
trackId,
|
||||
output: legacyOutput,
|
||||
webhooks
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"StartTrackEgress",
|
||||
req,
|
||||
await this.authHeader({ roomRecord: true })
|
||||
);
|
||||
return EgressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* @param egressId -
|
||||
* @param layout -
|
||||
*/
|
||||
async updateLayout(egressId, layout) {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateLayout",
|
||||
new UpdateLayoutRequest({ egressId, layout }).toJson(),
|
||||
await this.authHeader({ roomRecord: true })
|
||||
);
|
||||
return EgressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* @param egressId -
|
||||
* @param addOutputUrls -
|
||||
* @param removeOutputUrls -
|
||||
*/
|
||||
async updateStream(egressId, addOutputUrls, removeOutputUrls) {
|
||||
addOutputUrls ??= [];
|
||||
removeOutputUrls ??= [];
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateStream",
|
||||
new UpdateStreamRequest({ egressId, addOutputUrls, removeOutputUrls }).toJson(),
|
||||
await this.authHeader({ roomRecord: true })
|
||||
);
|
||||
return EgressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* @param roomName - list egress for one room only
|
||||
*/
|
||||
async listEgress(options) {
|
||||
let req = {};
|
||||
if (typeof options === "string") {
|
||||
req.roomName = options;
|
||||
} else if (options !== void 0) {
|
||||
req = options;
|
||||
}
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ListEgress",
|
||||
new ListEgressRequest(req).toJson(),
|
||||
await this.authHeader({ roomRecord: true })
|
||||
);
|
||||
return ListEgressResponse.fromJson(data, { ignoreUnknownFields: true }).items ?? [];
|
||||
}
|
||||
/**
|
||||
* @param egressId -
|
||||
*/
|
||||
async stopEgress(egressId) {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"StopEgress",
|
||||
new StopEgressRequest({ egressId }).toJson(),
|
||||
await this.authHeader({ roomRecord: true })
|
||||
);
|
||||
return EgressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
}
|
||||
export {
|
||||
EgressClient
|
||||
};
|
||||
//# sourceMappingURL=EgressClient.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+158
@@ -0,0 +1,158 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var IngressClient_exports = {};
|
||||
__export(IngressClient_exports, {
|
||||
IngressClient: () => IngressClient
|
||||
});
|
||||
module.exports = __toCommonJS(IngressClient_exports);
|
||||
var import_protocol = require("@livekit/protocol");
|
||||
var import_ServiceBase = require("./ServiceBase.cjs");
|
||||
var import_TwirpRPC = require("./TwirpRPC.cjs");
|
||||
const svc = "Ingress";
|
||||
class IngressClient extends import_ServiceBase.ServiceBase {
|
||||
/**
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host, apiKey, secret, options) {
|
||||
super({ apiKey, secret, token: options == null ? void 0 : options.token });
|
||||
this.rpc = new import_TwirpRPC.TwirpRpc(host, import_TwirpRPC.livekitPackage, {
|
||||
requestTimeout: options == null ? void 0 : options.requestTimeout,
|
||||
failover: options == null ? void 0 : options.failover
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @param inputType - protocol for the ingress
|
||||
* @param opts - CreateIngressOptions
|
||||
*/
|
||||
async createIngress(inputType, opts) {
|
||||
let name = "";
|
||||
let participantName = "";
|
||||
let participantIdentity = "";
|
||||
let bypassTranscoding = false;
|
||||
let url = "";
|
||||
if (opts == null) {
|
||||
throw new Error("options dictionary is required");
|
||||
}
|
||||
const roomName = opts.roomName;
|
||||
const enableTranscoding = opts.enableTranscoding;
|
||||
const audio = opts.audio;
|
||||
const video = opts.video;
|
||||
const participantMetadata = opts.participantMetadata;
|
||||
name = opts.name || "";
|
||||
participantName = opts.participantName || "";
|
||||
participantIdentity = opts.participantIdentity || "";
|
||||
bypassTranscoding = opts.bypassTranscoding || false;
|
||||
url = opts.url || "";
|
||||
if (typeof roomName == "undefined") {
|
||||
throw new Error("required roomName option not provided");
|
||||
}
|
||||
if (participantIdentity == "") {
|
||||
throw new Error("required participantIdentity option not provided");
|
||||
}
|
||||
const req = new import_protocol.CreateIngressRequest({
|
||||
inputType,
|
||||
name,
|
||||
roomName,
|
||||
participantIdentity,
|
||||
participantMetadata,
|
||||
participantName,
|
||||
bypassTranscoding,
|
||||
enableTranscoding,
|
||||
url,
|
||||
audio,
|
||||
video
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"CreateIngress",
|
||||
req,
|
||||
await this.authHeader({ ingressAdmin: true })
|
||||
);
|
||||
return import_protocol.IngressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* @param ingressId - ID of the ingress to update
|
||||
* @param opts - UpdateIngressOptions
|
||||
*/
|
||||
async updateIngress(ingressId, opts) {
|
||||
const name = opts.name || "";
|
||||
const roomName = opts.roomName || "";
|
||||
const participantName = opts.participantName || "";
|
||||
const participantIdentity = opts.participantIdentity || "";
|
||||
const { participantMetadata } = opts;
|
||||
const { audio, video, bypassTranscoding, enableTranscoding } = opts;
|
||||
const req = new import_protocol.UpdateIngressRequest({
|
||||
ingressId,
|
||||
name,
|
||||
roomName,
|
||||
participantIdentity,
|
||||
participantName,
|
||||
participantMetadata,
|
||||
bypassTranscoding,
|
||||
enableTranscoding,
|
||||
audio,
|
||||
video
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateIngress",
|
||||
req,
|
||||
await this.authHeader({ ingressAdmin: true })
|
||||
);
|
||||
return import_protocol.IngressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* @param arg - list room name or options
|
||||
*/
|
||||
async listIngress(arg) {
|
||||
let req = {};
|
||||
if (typeof arg === "string") {
|
||||
req.roomName = arg;
|
||||
} else if (arg) {
|
||||
req = arg;
|
||||
}
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ListIngress",
|
||||
new import_protocol.ListIngressRequest(req).toJson(),
|
||||
await this.authHeader({ ingressAdmin: true })
|
||||
);
|
||||
return import_protocol.ListIngressResponse.fromJson(data, { ignoreUnknownFields: true }).items ?? [];
|
||||
}
|
||||
/**
|
||||
* @param ingressId - ingress to delete
|
||||
*/
|
||||
async deleteIngress(ingressId) {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"DeleteIngress",
|
||||
new import_protocol.DeleteIngressRequest({ ingressId }).toJson(),
|
||||
await this.authHeader({ ingressAdmin: true })
|
||||
);
|
||||
return import_protocol.IngressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
IngressClient
|
||||
});
|
||||
//# sourceMappingURL=IngressClient.cjs.map
|
||||
+1
File diff suppressed because one or more lines are too long
+138
@@ -0,0 +1,138 @@
|
||||
import { IngressAudioOptions, IngressVideoOptions, IngressInput, IngressInfo } from '@livekit/protocol';
|
||||
import { ClientOptions } from './ClientOptions.cjs';
|
||||
import { ServiceBase } from './ServiceBase.cjs';
|
||||
import './grants.cjs';
|
||||
import 'jose';
|
||||
|
||||
interface CreateIngressOptions {
|
||||
/**
|
||||
* ingress name. optional
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* name of the room to send media to. required
|
||||
*/
|
||||
roomName?: string;
|
||||
/**
|
||||
* unique identity of the participant. required
|
||||
*/
|
||||
participantIdentity: string;
|
||||
/**
|
||||
* participant display name
|
||||
*/
|
||||
participantName?: string;
|
||||
/**
|
||||
* metadata to attach to the participant
|
||||
*/
|
||||
participantMetadata?: string;
|
||||
/**
|
||||
* @deprecated use `enableTranscoding` instead.
|
||||
* whether to skip transcoding and forward the input media directly. Only supported by WHIP
|
||||
*/
|
||||
bypassTranscoding?: boolean;
|
||||
/**
|
||||
* whether to enable transcoding or forward the input media directly.
|
||||
* Transcoding is required for all input types except WHIP. For WHIP, the default is to not transcode.
|
||||
*/
|
||||
enableTranscoding?: boolean | undefined;
|
||||
/**
|
||||
* url of the media to pull for ingresses of type URL
|
||||
*/
|
||||
url?: string;
|
||||
/**
|
||||
* custom audio encoding parameters. optional
|
||||
*/
|
||||
audio?: IngressAudioOptions;
|
||||
/**
|
||||
* custom video encoding parameters. optional
|
||||
*/
|
||||
video?: IngressVideoOptions;
|
||||
}
|
||||
interface UpdateIngressOptions {
|
||||
/**
|
||||
* ingress name. optional
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* name of the room to send media to.
|
||||
*/
|
||||
roomName?: string;
|
||||
/**
|
||||
* unique identity of the participant.
|
||||
*/
|
||||
participantIdentity?: string;
|
||||
/**
|
||||
* participant display name
|
||||
*/
|
||||
participantName?: string;
|
||||
/**
|
||||
* metadata to attach to the participant
|
||||
*/
|
||||
participantMetadata?: string;
|
||||
/**
|
||||
* @deprecated use `enableTranscoding` instead
|
||||
* whether to skip transcoding and forward the input media directly. Only supported by WHIP
|
||||
*/
|
||||
bypassTranscoding?: boolean | undefined;
|
||||
/**
|
||||
* whether to enable transcoding or forward the input media directly.
|
||||
* Transcoding is required for all input types except WHIP. For WHIP, the default is to not transcode.
|
||||
*/
|
||||
enableTranscoding?: boolean | undefined;
|
||||
/**
|
||||
* custom audio encoding parameters. optional
|
||||
*/
|
||||
audio?: IngressAudioOptions;
|
||||
/**
|
||||
* custom video encoding parameters. optional
|
||||
*/
|
||||
video?: IngressVideoOptions;
|
||||
}
|
||||
interface ListIngressOptions {
|
||||
/**
|
||||
* list ingress for one room only
|
||||
*/
|
||||
roomName?: string;
|
||||
/**
|
||||
* list ingress by ID
|
||||
*/
|
||||
ingressId?: string;
|
||||
}
|
||||
/**
|
||||
* Client to access Ingress APIs
|
||||
*/
|
||||
declare class IngressClient extends ServiceBase {
|
||||
private readonly rpc;
|
||||
/**
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host: string, apiKey?: string, secret?: string, options?: ClientOptions);
|
||||
/**
|
||||
* @param inputType - protocol for the ingress
|
||||
* @param opts - CreateIngressOptions
|
||||
*/
|
||||
createIngress(inputType: IngressInput, opts: CreateIngressOptions): Promise<IngressInfo>;
|
||||
/**
|
||||
* @param ingressId - ID of the ingress to update
|
||||
* @param opts - UpdateIngressOptions
|
||||
*/
|
||||
updateIngress(ingressId: string, opts: UpdateIngressOptions): Promise<IngressInfo>;
|
||||
/**
|
||||
* @deprecated use `listIngress(opts)` or `listIngress(arg)` instead
|
||||
* @param roomName - list ingress for one room only
|
||||
*/
|
||||
listIngress(roomName?: string): Promise<Array<IngressInfo>>;
|
||||
/**
|
||||
* @param opts - list options
|
||||
*/
|
||||
listIngress(opts?: ListIngressOptions): Promise<Array<IngressInfo>>;
|
||||
/**
|
||||
* @param ingressId - ingress to delete
|
||||
*/
|
||||
deleteIngress(ingressId: string): Promise<IngressInfo>;
|
||||
}
|
||||
|
||||
export { type CreateIngressOptions, IngressClient, type ListIngressOptions, type UpdateIngressOptions };
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
import { IngressAudioOptions, IngressVideoOptions, IngressInput, IngressInfo } from '@livekit/protocol';
|
||||
import { ClientOptions } from './ClientOptions.js';
|
||||
import { ServiceBase } from './ServiceBase.js';
|
||||
import './grants.js';
|
||||
import 'jose';
|
||||
|
||||
interface CreateIngressOptions {
|
||||
/**
|
||||
* ingress name. optional
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* name of the room to send media to. required
|
||||
*/
|
||||
roomName?: string;
|
||||
/**
|
||||
* unique identity of the participant. required
|
||||
*/
|
||||
participantIdentity: string;
|
||||
/**
|
||||
* participant display name
|
||||
*/
|
||||
participantName?: string;
|
||||
/**
|
||||
* metadata to attach to the participant
|
||||
*/
|
||||
participantMetadata?: string;
|
||||
/**
|
||||
* @deprecated use `enableTranscoding` instead.
|
||||
* whether to skip transcoding and forward the input media directly. Only supported by WHIP
|
||||
*/
|
||||
bypassTranscoding?: boolean;
|
||||
/**
|
||||
* whether to enable transcoding or forward the input media directly.
|
||||
* Transcoding is required for all input types except WHIP. For WHIP, the default is to not transcode.
|
||||
*/
|
||||
enableTranscoding?: boolean | undefined;
|
||||
/**
|
||||
* url of the media to pull for ingresses of type URL
|
||||
*/
|
||||
url?: string;
|
||||
/**
|
||||
* custom audio encoding parameters. optional
|
||||
*/
|
||||
audio?: IngressAudioOptions;
|
||||
/**
|
||||
* custom video encoding parameters. optional
|
||||
*/
|
||||
video?: IngressVideoOptions;
|
||||
}
|
||||
interface UpdateIngressOptions {
|
||||
/**
|
||||
* ingress name. optional
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* name of the room to send media to.
|
||||
*/
|
||||
roomName?: string;
|
||||
/**
|
||||
* unique identity of the participant.
|
||||
*/
|
||||
participantIdentity?: string;
|
||||
/**
|
||||
* participant display name
|
||||
*/
|
||||
participantName?: string;
|
||||
/**
|
||||
* metadata to attach to the participant
|
||||
*/
|
||||
participantMetadata?: string;
|
||||
/**
|
||||
* @deprecated use `enableTranscoding` instead
|
||||
* whether to skip transcoding and forward the input media directly. Only supported by WHIP
|
||||
*/
|
||||
bypassTranscoding?: boolean | undefined;
|
||||
/**
|
||||
* whether to enable transcoding or forward the input media directly.
|
||||
* Transcoding is required for all input types except WHIP. For WHIP, the default is to not transcode.
|
||||
*/
|
||||
enableTranscoding?: boolean | undefined;
|
||||
/**
|
||||
* custom audio encoding parameters. optional
|
||||
*/
|
||||
audio?: IngressAudioOptions;
|
||||
/**
|
||||
* custom video encoding parameters. optional
|
||||
*/
|
||||
video?: IngressVideoOptions;
|
||||
}
|
||||
interface ListIngressOptions {
|
||||
/**
|
||||
* list ingress for one room only
|
||||
*/
|
||||
roomName?: string;
|
||||
/**
|
||||
* list ingress by ID
|
||||
*/
|
||||
ingressId?: string;
|
||||
}
|
||||
/**
|
||||
* Client to access Ingress APIs
|
||||
*/
|
||||
declare class IngressClient extends ServiceBase {
|
||||
private readonly rpc;
|
||||
/**
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host: string, apiKey?: string, secret?: string, options?: ClientOptions);
|
||||
/**
|
||||
* @param inputType - protocol for the ingress
|
||||
* @param opts - CreateIngressOptions
|
||||
*/
|
||||
createIngress(inputType: IngressInput, opts: CreateIngressOptions): Promise<IngressInfo>;
|
||||
/**
|
||||
* @param ingressId - ID of the ingress to update
|
||||
* @param opts - UpdateIngressOptions
|
||||
*/
|
||||
updateIngress(ingressId: string, opts: UpdateIngressOptions): Promise<IngressInfo>;
|
||||
/**
|
||||
* @deprecated use `listIngress(opts)` or `listIngress(arg)` instead
|
||||
* @param roomName - list ingress for one room only
|
||||
*/
|
||||
listIngress(roomName?: string): Promise<Array<IngressInfo>>;
|
||||
/**
|
||||
* @param opts - list options
|
||||
*/
|
||||
listIngress(opts?: ListIngressOptions): Promise<Array<IngressInfo>>;
|
||||
/**
|
||||
* @param ingressId - ingress to delete
|
||||
*/
|
||||
deleteIngress(ingressId: string): Promise<IngressInfo>;
|
||||
}
|
||||
|
||||
export { type CreateIngressOptions, IngressClient, type ListIngressOptions, type UpdateIngressOptions };
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"IngressClient.d.ts","sourceRoot":"","sources":["../src/IngressClient.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAChG,OAAO,EAGL,WAAW,EAIZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAM/C,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,mBAAmB,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACxC;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,KAAK,CAAC,EAAE,mBAAmB,CAAC;IAC5B;;OAEG;IACH,KAAK,CAAC,EAAE,mBAAmB,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACxC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACxC;;OAEG;IACH,KAAK,CAAC,EAAE,mBAAmB,CAAC;IAC5B;;OAEG;IACH,KAAK,CAAC,EAAE,mBAAmB,CAAC;CAC7B;AAED,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,WAAW;IAC5C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAE1B;;;;;OAKG;gBACS,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa;IAQnF;;;OAGG;IACG,aAAa,CAAC,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC;IAsD9F;;;OAGG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC;IA8BxF;;;OAGG;IACG,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACjE;;OAEG;IACG,WAAW,CAAC,IAAI,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAoBzE;;OAEG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;CAS7D"}
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
import {
|
||||
CreateIngressRequest,
|
||||
DeleteIngressRequest,
|
||||
IngressInfo,
|
||||
ListIngressRequest,
|
||||
ListIngressResponse,
|
||||
UpdateIngressRequest
|
||||
} from "@livekit/protocol";
|
||||
import { ServiceBase } from "./ServiceBase.js";
|
||||
import { TwirpRpc, livekitPackage } from "./TwirpRPC.js";
|
||||
const svc = "Ingress";
|
||||
class IngressClient extends ServiceBase {
|
||||
/**
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host, apiKey, secret, options) {
|
||||
super({ apiKey, secret, token: options == null ? void 0 : options.token });
|
||||
this.rpc = new TwirpRpc(host, livekitPackage, {
|
||||
requestTimeout: options == null ? void 0 : options.requestTimeout,
|
||||
failover: options == null ? void 0 : options.failover
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @param inputType - protocol for the ingress
|
||||
* @param opts - CreateIngressOptions
|
||||
*/
|
||||
async createIngress(inputType, opts) {
|
||||
let name = "";
|
||||
let participantName = "";
|
||||
let participantIdentity = "";
|
||||
let bypassTranscoding = false;
|
||||
let url = "";
|
||||
if (opts == null) {
|
||||
throw new Error("options dictionary is required");
|
||||
}
|
||||
const roomName = opts.roomName;
|
||||
const enableTranscoding = opts.enableTranscoding;
|
||||
const audio = opts.audio;
|
||||
const video = opts.video;
|
||||
const participantMetadata = opts.participantMetadata;
|
||||
name = opts.name || "";
|
||||
participantName = opts.participantName || "";
|
||||
participantIdentity = opts.participantIdentity || "";
|
||||
bypassTranscoding = opts.bypassTranscoding || false;
|
||||
url = opts.url || "";
|
||||
if (typeof roomName == "undefined") {
|
||||
throw new Error("required roomName option not provided");
|
||||
}
|
||||
if (participantIdentity == "") {
|
||||
throw new Error("required participantIdentity option not provided");
|
||||
}
|
||||
const req = new CreateIngressRequest({
|
||||
inputType,
|
||||
name,
|
||||
roomName,
|
||||
participantIdentity,
|
||||
participantMetadata,
|
||||
participantName,
|
||||
bypassTranscoding,
|
||||
enableTranscoding,
|
||||
url,
|
||||
audio,
|
||||
video
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"CreateIngress",
|
||||
req,
|
||||
await this.authHeader({ ingressAdmin: true })
|
||||
);
|
||||
return IngressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* @param ingressId - ID of the ingress to update
|
||||
* @param opts - UpdateIngressOptions
|
||||
*/
|
||||
async updateIngress(ingressId, opts) {
|
||||
const name = opts.name || "";
|
||||
const roomName = opts.roomName || "";
|
||||
const participantName = opts.participantName || "";
|
||||
const participantIdentity = opts.participantIdentity || "";
|
||||
const { participantMetadata } = opts;
|
||||
const { audio, video, bypassTranscoding, enableTranscoding } = opts;
|
||||
const req = new UpdateIngressRequest({
|
||||
ingressId,
|
||||
name,
|
||||
roomName,
|
||||
participantIdentity,
|
||||
participantName,
|
||||
participantMetadata,
|
||||
bypassTranscoding,
|
||||
enableTranscoding,
|
||||
audio,
|
||||
video
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateIngress",
|
||||
req,
|
||||
await this.authHeader({ ingressAdmin: true })
|
||||
);
|
||||
return IngressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* @param arg - list room name or options
|
||||
*/
|
||||
async listIngress(arg) {
|
||||
let req = {};
|
||||
if (typeof arg === "string") {
|
||||
req.roomName = arg;
|
||||
} else if (arg) {
|
||||
req = arg;
|
||||
}
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ListIngress",
|
||||
new ListIngressRequest(req).toJson(),
|
||||
await this.authHeader({ ingressAdmin: true })
|
||||
);
|
||||
return ListIngressResponse.fromJson(data, { ignoreUnknownFields: true }).items ?? [];
|
||||
}
|
||||
/**
|
||||
* @param ingressId - ingress to delete
|
||||
*/
|
||||
async deleteIngress(ingressId) {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"DeleteIngress",
|
||||
new DeleteIngressRequest({ ingressId }).toJson(),
|
||||
await this.authHeader({ ingressAdmin: true })
|
||||
);
|
||||
return IngressInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
}
|
||||
export {
|
||||
IngressClient
|
||||
};
|
||||
//# sourceMappingURL=IngressClient.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+80
@@ -0,0 +1,80 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var LiveKitAPI_exports = {};
|
||||
__export(LiveKitAPI_exports, {
|
||||
LiveKitAPI: () => LiveKitAPI
|
||||
});
|
||||
module.exports = __toCommonJS(LiveKitAPI_exports);
|
||||
var import_AgentDispatchClient = require("./AgentDispatchClient.cjs");
|
||||
var import_ConnectorClient = require("./ConnectorClient.cjs");
|
||||
var import_EgressClient = require("./EgressClient.cjs");
|
||||
var import_IngressClient = require("./IngressClient.cjs");
|
||||
var import_RoomServiceClient = require("./RoomServiceClient.cjs");
|
||||
var import_SipClient = require("./SipClient.cjs");
|
||||
class LiveKitAPI {
|
||||
/**
|
||||
* @param options - server host, credentials, and client options; each value
|
||||
* falls back to its environment variable when omitted.
|
||||
*/
|
||||
constructor(options = {}) {
|
||||
const host = options.host || process.env.LIVEKIT_URL;
|
||||
if (!host) {
|
||||
throw new Error("host is required (pass it or set LIVEKIT_URL)");
|
||||
}
|
||||
const { apiKey, secret } = options;
|
||||
const token = options.token || (apiKey || secret ? void 0 : process.env.LIVEKIT_TOKEN);
|
||||
if (!token && !(apiKey ?? process.env.LIVEKIT_API_KEY)) {
|
||||
throw new Error("either a token or an API key and secret are required");
|
||||
}
|
||||
const clientOptions = {
|
||||
requestTimeout: options.requestTimeout,
|
||||
failover: options.failover,
|
||||
token
|
||||
};
|
||||
this._room = new import_RoomServiceClient.RoomServiceClient(host, apiKey, secret, clientOptions);
|
||||
this._egress = new import_EgressClient.EgressClient(host, apiKey, secret, clientOptions);
|
||||
this._ingress = new import_IngressClient.IngressClient(host, apiKey, secret, clientOptions);
|
||||
this._sip = new import_SipClient.SipClient(host, apiKey, secret, clientOptions);
|
||||
this._agentDispatch = new import_AgentDispatchClient.AgentDispatchClient(host, apiKey, secret, clientOptions);
|
||||
this._connector = new import_ConnectorClient.ConnectorClient(host, apiKey, secret, clientOptions);
|
||||
}
|
||||
get room() {
|
||||
return this._room;
|
||||
}
|
||||
get egress() {
|
||||
return this._egress;
|
||||
}
|
||||
get ingress() {
|
||||
return this._ingress;
|
||||
}
|
||||
get sip() {
|
||||
return this._sip;
|
||||
}
|
||||
get agentDispatch() {
|
||||
return this._agentDispatch;
|
||||
}
|
||||
get connector() {
|
||||
return this._connector;
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
LiveKitAPI
|
||||
});
|
||||
//# sourceMappingURL=LiveKitAPI.cjs.map
|
||||
+1
File diff suppressed because one or more lines are too long
+77
@@ -0,0 +1,77 @@
|
||||
import { AgentDispatchClient } from './AgentDispatchClient.cjs';
|
||||
import { ConnectorClient } from './ConnectorClient.cjs';
|
||||
import { EgressClient } from './EgressClient.cjs';
|
||||
import { IngressClient } from './IngressClient.cjs';
|
||||
import { RoomServiceClient } from './RoomServiceClient.cjs';
|
||||
import { SipClient } from './SipClient.cjs';
|
||||
import '@livekit/protocol';
|
||||
import './ClientOptions.cjs';
|
||||
import './ServiceBase.cjs';
|
||||
import './grants.cjs';
|
||||
import 'jose';
|
||||
|
||||
/** Server host and non-auth options, shared by both authentication modes. */
|
||||
interface LiveKitAPICommonOptions {
|
||||
/** Server host, including protocol. Falls back to the `LIVEKIT_URL` env var. */
|
||||
host?: string;
|
||||
/** Optional timeout, in seconds, for all server requests. */
|
||||
requestTimeout?: number;
|
||||
/**
|
||||
* Whether to fail over to alternative regions on retryable errors (LiveKit
|
||||
* Cloud hosts only). Defaults to true; set to false to disable.
|
||||
*/
|
||||
failover?: boolean;
|
||||
}
|
||||
/** API key and secret authentication (recommended for backend use). */
|
||||
interface ApiKeyAuth {
|
||||
/** API key. Falls back to the `LIVEKIT_API_KEY` env var. */
|
||||
apiKey?: string;
|
||||
/** API secret. Falls back to the `LIVEKIT_API_SECRET` env var. */
|
||||
secret?: string;
|
||||
token?: never;
|
||||
}
|
||||
/** Pre-signed token authentication (client-side use; no secret required). */
|
||||
interface TokenAuth {
|
||||
/** Pre-signed token, sent verbatim. Falls back to the `LIVEKIT_TOKEN` env var. */
|
||||
token: string;
|
||||
apiKey?: never;
|
||||
secret?: never;
|
||||
}
|
||||
/**
|
||||
* Options for {@link LiveKitAPI}. Provide either an `apiKey` and `secret` or a
|
||||
* pre-signed `token` — the two modes are mutually exclusive. Any omitted value
|
||||
* falls back to its environment variable (`LIVEKIT_URL`, `LIVEKIT_API_KEY`,
|
||||
* `LIVEKIT_API_SECRET`, `LIVEKIT_TOKEN`).
|
||||
*/
|
||||
type LiveKitAPIOptions = LiveKitAPICommonOptions & (ApiKeyAuth | TokenAuth);
|
||||
/**
|
||||
* A single entry point to every LiveKit server API, exposing each service
|
||||
* through a property, e.g. `api.room.createRoom(...)`.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const api = new LiveKitAPI({ apiKey, secret }); // or new LiveKitAPI() to read from env
|
||||
* await api.room.createRoom({ name: 'my-room' });
|
||||
* ```
|
||||
*/
|
||||
declare class LiveKitAPI {
|
||||
private readonly _room;
|
||||
private readonly _egress;
|
||||
private readonly _ingress;
|
||||
private readonly _sip;
|
||||
private readonly _agentDispatch;
|
||||
private readonly _connector;
|
||||
/**
|
||||
* @param options - server host, credentials, and client options; each value
|
||||
* falls back to its environment variable when omitted.
|
||||
*/
|
||||
constructor(options?: LiveKitAPIOptions);
|
||||
get room(): RoomServiceClient;
|
||||
get egress(): EgressClient;
|
||||
get ingress(): IngressClient;
|
||||
get sip(): SipClient;
|
||||
get agentDispatch(): AgentDispatchClient;
|
||||
get connector(): ConnectorClient;
|
||||
}
|
||||
|
||||
export { LiveKitAPI, type LiveKitAPIOptions };
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
import { AgentDispatchClient } from './AgentDispatchClient.js';
|
||||
import { ConnectorClient } from './ConnectorClient.js';
|
||||
import { EgressClient } from './EgressClient.js';
|
||||
import { IngressClient } from './IngressClient.js';
|
||||
import { RoomServiceClient } from './RoomServiceClient.js';
|
||||
import { SipClient } from './SipClient.js';
|
||||
import '@livekit/protocol';
|
||||
import './ClientOptions.js';
|
||||
import './ServiceBase.js';
|
||||
import './grants.js';
|
||||
import 'jose';
|
||||
|
||||
/** Server host and non-auth options, shared by both authentication modes. */
|
||||
interface LiveKitAPICommonOptions {
|
||||
/** Server host, including protocol. Falls back to the `LIVEKIT_URL` env var. */
|
||||
host?: string;
|
||||
/** Optional timeout, in seconds, for all server requests. */
|
||||
requestTimeout?: number;
|
||||
/**
|
||||
* Whether to fail over to alternative regions on retryable errors (LiveKit
|
||||
* Cloud hosts only). Defaults to true; set to false to disable.
|
||||
*/
|
||||
failover?: boolean;
|
||||
}
|
||||
/** API key and secret authentication (recommended for backend use). */
|
||||
interface ApiKeyAuth {
|
||||
/** API key. Falls back to the `LIVEKIT_API_KEY` env var. */
|
||||
apiKey?: string;
|
||||
/** API secret. Falls back to the `LIVEKIT_API_SECRET` env var. */
|
||||
secret?: string;
|
||||
token?: never;
|
||||
}
|
||||
/** Pre-signed token authentication (client-side use; no secret required). */
|
||||
interface TokenAuth {
|
||||
/** Pre-signed token, sent verbatim. Falls back to the `LIVEKIT_TOKEN` env var. */
|
||||
token: string;
|
||||
apiKey?: never;
|
||||
secret?: never;
|
||||
}
|
||||
/**
|
||||
* Options for {@link LiveKitAPI}. Provide either an `apiKey` and `secret` or a
|
||||
* pre-signed `token` — the two modes are mutually exclusive. Any omitted value
|
||||
* falls back to its environment variable (`LIVEKIT_URL`, `LIVEKIT_API_KEY`,
|
||||
* `LIVEKIT_API_SECRET`, `LIVEKIT_TOKEN`).
|
||||
*/
|
||||
type LiveKitAPIOptions = LiveKitAPICommonOptions & (ApiKeyAuth | TokenAuth);
|
||||
/**
|
||||
* A single entry point to every LiveKit server API, exposing each service
|
||||
* through a property, e.g. `api.room.createRoom(...)`.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const api = new LiveKitAPI({ apiKey, secret }); // or new LiveKitAPI() to read from env
|
||||
* await api.room.createRoom({ name: 'my-room' });
|
||||
* ```
|
||||
*/
|
||||
declare class LiveKitAPI {
|
||||
private readonly _room;
|
||||
private readonly _egress;
|
||||
private readonly _ingress;
|
||||
private readonly _sip;
|
||||
private readonly _agentDispatch;
|
||||
private readonly _connector;
|
||||
/**
|
||||
* @param options - server host, credentials, and client options; each value
|
||||
* falls back to its environment variable when omitted.
|
||||
*/
|
||||
constructor(options?: LiveKitAPIOptions);
|
||||
get room(): RoomServiceClient;
|
||||
get egress(): EgressClient;
|
||||
get ingress(): IngressClient;
|
||||
get sip(): SipClient;
|
||||
get agentDispatch(): AgentDispatchClient;
|
||||
get connector(): ConnectorClient;
|
||||
}
|
||||
|
||||
export { LiveKitAPI, type LiveKitAPIOptions };
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"LiveKitAPI.d.ts","sourceRoot":"","sources":["../src/LiveKitAPI.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,6EAA6E;AAC7E,UAAU,uBAAuB;IAC/B,gFAAgF;IAChF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,uEAAuE;AACvE,UAAU,UAAU;IAClB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,6EAA6E;AAC7E,UAAU,SAAS;IACjB,kFAAkF;IAClF,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,MAAM,CAAC,EAAE,KAAK,CAAC;CAChB;AAED;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,uBAAuB,GAAG,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;AAEnF;;;;;;;;;GASG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAE1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IAEvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IAEzC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAY;IAEjC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAsB;IAErD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAE7C;;;OAGG;gBACS,OAAO,GAAE,iBAAsB;IA0B3C,IAAI,IAAI,IAAI,iBAAiB,CAE5B;IAED,IAAI,MAAM,IAAI,YAAY,CAEzB;IAED,IAAI,OAAO,IAAI,aAAa,CAE3B;IAED,IAAI,GAAG,IAAI,SAAS,CAEnB;IAED,IAAI,aAAa,IAAI,mBAAmB,CAEvC;IAED,IAAI,SAAS,IAAI,eAAe,CAE/B;CACF"}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
import { AgentDispatchClient } from "./AgentDispatchClient.js";
|
||||
import { ConnectorClient } from "./ConnectorClient.js";
|
||||
import { EgressClient } from "./EgressClient.js";
|
||||
import { IngressClient } from "./IngressClient.js";
|
||||
import { RoomServiceClient } from "./RoomServiceClient.js";
|
||||
import { SipClient } from "./SipClient.js";
|
||||
class LiveKitAPI {
|
||||
/**
|
||||
* @param options - server host, credentials, and client options; each value
|
||||
* falls back to its environment variable when omitted.
|
||||
*/
|
||||
constructor(options = {}) {
|
||||
const host = options.host || process.env.LIVEKIT_URL;
|
||||
if (!host) {
|
||||
throw new Error("host is required (pass it or set LIVEKIT_URL)");
|
||||
}
|
||||
const { apiKey, secret } = options;
|
||||
const token = options.token || (apiKey || secret ? void 0 : process.env.LIVEKIT_TOKEN);
|
||||
if (!token && !(apiKey ?? process.env.LIVEKIT_API_KEY)) {
|
||||
throw new Error("either a token or an API key and secret are required");
|
||||
}
|
||||
const clientOptions = {
|
||||
requestTimeout: options.requestTimeout,
|
||||
failover: options.failover,
|
||||
token
|
||||
};
|
||||
this._room = new RoomServiceClient(host, apiKey, secret, clientOptions);
|
||||
this._egress = new EgressClient(host, apiKey, secret, clientOptions);
|
||||
this._ingress = new IngressClient(host, apiKey, secret, clientOptions);
|
||||
this._sip = new SipClient(host, apiKey, secret, clientOptions);
|
||||
this._agentDispatch = new AgentDispatchClient(host, apiKey, secret, clientOptions);
|
||||
this._connector = new ConnectorClient(host, apiKey, secret, clientOptions);
|
||||
}
|
||||
get room() {
|
||||
return this._room;
|
||||
}
|
||||
get egress() {
|
||||
return this._egress;
|
||||
}
|
||||
get ingress() {
|
||||
return this._ingress;
|
||||
}
|
||||
get sip() {
|
||||
return this._sip;
|
||||
}
|
||||
get agentDispatch() {
|
||||
return this._agentDispatch;
|
||||
}
|
||||
get connector() {
|
||||
return this._connector;
|
||||
}
|
||||
}
|
||||
export {
|
||||
LiveKitAPI
|
||||
};
|
||||
//# sourceMappingURL=LiveKitAPI.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+277
@@ -0,0 +1,277 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var RoomServiceClient_exports = {};
|
||||
__export(RoomServiceClient_exports, {
|
||||
RoomServiceClient: () => RoomServiceClient
|
||||
});
|
||||
module.exports = __toCommonJS(RoomServiceClient_exports);
|
||||
var import_protocol = require("@livekit/protocol");
|
||||
var import_ServiceBase = require("./ServiceBase.cjs");
|
||||
var import_TwirpRPC = require("./TwirpRPC.cjs");
|
||||
var import_uuid = require("./crypto/uuid.cjs");
|
||||
const svc = "RoomService";
|
||||
class RoomServiceClient extends import_ServiceBase.ServiceBase {
|
||||
/**
|
||||
*
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host, apiKey, secret, options) {
|
||||
super({ apiKey, secret, token: options == null ? void 0 : options.token });
|
||||
this.rpc = new import_TwirpRPC.TwirpRpc(host, import_TwirpRPC.livekitPackage, {
|
||||
requestTimeout: options == null ? void 0 : options.requestTimeout,
|
||||
failover: options == null ? void 0 : options.failover
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Creates a new room. Explicit room creation is not required, since rooms will
|
||||
* be automatically created when the first participant joins. This method can be
|
||||
* used to customize room settings.
|
||||
* @param options -
|
||||
*/
|
||||
async createRoom(options) {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"CreateRoom",
|
||||
new import_protocol.CreateRoomRequest(options).toJson(),
|
||||
await this.authHeader({ roomCreate: true })
|
||||
);
|
||||
return import_protocol.Room.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* List active rooms
|
||||
* @param names - when undefined or empty, list all rooms.
|
||||
* otherwise returns rooms with matching names
|
||||
* @returns
|
||||
*/
|
||||
async listRooms(names) {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ListRooms",
|
||||
new import_protocol.ListRoomsRequest({ names: names ?? [] }).toJson(),
|
||||
await this.authHeader({ roomList: true })
|
||||
);
|
||||
const res = import_protocol.ListRoomsResponse.fromJson(data, { ignoreUnknownFields: true });
|
||||
return res.rooms ?? [];
|
||||
}
|
||||
async deleteRoom(room) {
|
||||
await this.rpc.request(
|
||||
svc,
|
||||
"DeleteRoom",
|
||||
new import_protocol.DeleteRoomRequest({ room }).toJson(),
|
||||
await this.authHeader({ roomCreate: true })
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Update metadata of a room
|
||||
* @param room - name of the room
|
||||
* @param metadata - the new metadata for the room
|
||||
*/
|
||||
async updateRoomMetadata(room, metadata) {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateRoomMetadata",
|
||||
new import_protocol.UpdateRoomMetadataRequest({ room, metadata }).toJson(),
|
||||
await this.authHeader({ roomAdmin: true, room })
|
||||
);
|
||||
return import_protocol.Room.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* List participants in a room
|
||||
* @param room - name of the room
|
||||
*/
|
||||
async listParticipants(room) {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ListParticipants",
|
||||
new import_protocol.ListParticipantsRequest({ room }).toJson(),
|
||||
await this.authHeader({ roomAdmin: true, room })
|
||||
);
|
||||
const res = import_protocol.ListParticipantsResponse.fromJson(data, { ignoreUnknownFields: true });
|
||||
return res.participants ?? [];
|
||||
}
|
||||
/**
|
||||
* Get information on a specific participant, including the tracks that participant
|
||||
* has published
|
||||
* @param room - name of the room
|
||||
* @param identity - identity of the participant to return
|
||||
*/
|
||||
async getParticipant(room, identity) {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"GetParticipant",
|
||||
new import_protocol.RoomParticipantIdentity({ room, identity }).toJson(),
|
||||
await this.authHeader({ roomAdmin: true, room })
|
||||
);
|
||||
return import_protocol.ParticipantInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Removes a participant in the room. This will disconnect the participant
|
||||
* and will emit a Disconnected event for that participant.
|
||||
* Even after being removed, the participant can still re-join the room.
|
||||
* @param room -
|
||||
* @param identity -
|
||||
* @param options - removal options
|
||||
*/
|
||||
async removeParticipant(room, identity, options) {
|
||||
await this.rpc.request(
|
||||
svc,
|
||||
"RemoveParticipant",
|
||||
new import_protocol.RoomParticipantIdentity({
|
||||
room,
|
||||
identity,
|
||||
revokeTokenTs: options == null ? void 0 : options.revokeTokenTs
|
||||
}).toJson(),
|
||||
await this.authHeader({ roomAdmin: true, room })
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Forwards a participant's track to another room. This will create a
|
||||
* participant to join the destination room that has same information
|
||||
* with the source participant except the kind to be `Forwarded`. All
|
||||
* changes to the source participant will be reflected to the forwarded
|
||||
* participant. When the source participant disconnects or the
|
||||
* `RemoveParticipant` method is called in the destination room, the
|
||||
* forwarding will be stopped.
|
||||
* @param room -
|
||||
* @param identity -
|
||||
* @param destinationRoom - the room to forward the participant to
|
||||
*/
|
||||
async forwardParticipant(room, identity, destinationRoom) {
|
||||
await this.rpc.request(
|
||||
svc,
|
||||
"ForwardParticipant",
|
||||
new import_protocol.ForwardParticipantRequest({ room, identity, destinationRoom }).toJson(),
|
||||
await this.authHeader({ roomAdmin: true, room, destinationRoom })
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Move a connected participant to a different room. Requires `roomAdmin` and `destinationRoom`.
|
||||
* The participant will be removed from the current room and added to the destination room.
|
||||
* From the other observers' perspective, the participant would've disconnected from the previous room and joined the new one.
|
||||
* @param room -
|
||||
* @param identity -
|
||||
* @param destinationRoom - the room to move the participant to
|
||||
*/
|
||||
async moveParticipant(room, identity, destinationRoom) {
|
||||
await this.rpc.request(
|
||||
svc,
|
||||
"MoveParticipant",
|
||||
new import_protocol.MoveParticipantRequest({ room, identity, destinationRoom }).toJson(),
|
||||
await this.authHeader({ roomAdmin: true, room, destinationRoom })
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Mutes a track that the participant has published.
|
||||
* @param room -
|
||||
* @param identity -
|
||||
* @param trackSid - sid of the track to be muted
|
||||
* @param muted - true to mute, false to unmute
|
||||
*/
|
||||
async mutePublishedTrack(room, identity, trackSid, muted) {
|
||||
const req = new import_protocol.MuteRoomTrackRequest({
|
||||
room,
|
||||
identity,
|
||||
trackSid,
|
||||
muted
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"MutePublishedTrack",
|
||||
req,
|
||||
await this.authHeader({ roomAdmin: true, room })
|
||||
);
|
||||
const res = import_protocol.MuteRoomTrackResponse.fromJson(data, { ignoreUnknownFields: true });
|
||||
return res.track;
|
||||
}
|
||||
async updateParticipant(room, identity, metadataOrOptions, maybePermission, maybeName) {
|
||||
const hasOptions = typeof metadataOrOptions === "object";
|
||||
const metadata = hasOptions ? metadataOrOptions == null ? void 0 : metadataOrOptions.metadata : metadataOrOptions;
|
||||
const permission = hasOptions ? metadataOrOptions.permission : maybePermission;
|
||||
const name = hasOptions ? metadataOrOptions.name : maybeName;
|
||||
const attributes = hasOptions ? metadataOrOptions.attributes : {};
|
||||
const req = new import_protocol.UpdateParticipantRequest({
|
||||
room,
|
||||
identity,
|
||||
attributes,
|
||||
metadata,
|
||||
name
|
||||
});
|
||||
if (permission) {
|
||||
req.permission = new import_protocol.ParticipantPermission(permission);
|
||||
}
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateParticipant",
|
||||
req.toJson(),
|
||||
await this.authHeader({ roomAdmin: true, room })
|
||||
);
|
||||
return import_protocol.ParticipantInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Updates a participant's subscription to tracks
|
||||
* @param room -
|
||||
* @param identity -
|
||||
* @param trackSids -
|
||||
* @param subscribe - true to subscribe, false to unsubscribe
|
||||
*/
|
||||
async updateSubscriptions(room, identity, trackSids, subscribe) {
|
||||
const req = new import_protocol.UpdateSubscriptionsRequest({
|
||||
room,
|
||||
identity,
|
||||
trackSids,
|
||||
subscribe,
|
||||
participantTracks: []
|
||||
}).toJson();
|
||||
await this.rpc.request(
|
||||
svc,
|
||||
"UpdateSubscriptions",
|
||||
req,
|
||||
await this.authHeader({ roomAdmin: true, room })
|
||||
);
|
||||
}
|
||||
async sendData(room, data, kind, options = {}) {
|
||||
const destinationSids = Array.isArray(options) ? options : options.destinationSids;
|
||||
const topic = Array.isArray(options) ? void 0 : options.topic;
|
||||
const req = new import_protocol.SendDataRequest({
|
||||
room,
|
||||
data,
|
||||
kind,
|
||||
destinationSids: destinationSids ?? [],
|
||||
topic
|
||||
});
|
||||
if (!Array.isArray(options) && options.destinationIdentities) {
|
||||
req.destinationIdentities = options.destinationIdentities;
|
||||
}
|
||||
req.nonce = await (0, import_uuid.getRandomBytes)(16);
|
||||
await this.rpc.request(
|
||||
svc,
|
||||
"SendData",
|
||||
req.toJson(),
|
||||
await this.authHeader({ roomAdmin: true, room })
|
||||
);
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
RoomServiceClient
|
||||
});
|
||||
//# sourceMappingURL=RoomServiceClient.cjs.map
|
||||
+1
File diff suppressed because one or more lines are too long
+208
@@ -0,0 +1,208 @@
|
||||
import { RoomEgress, RoomAgentDispatch, Room, ParticipantInfo, TrackInfo, ParticipantPermission, DataPacket_Kind } from '@livekit/protocol';
|
||||
import { ClientOptions } from './ClientOptions.cjs';
|
||||
import { ServiceBase } from './ServiceBase.cjs';
|
||||
import './grants.cjs';
|
||||
import 'jose';
|
||||
|
||||
/**
|
||||
* Options for when creating a room
|
||||
*/
|
||||
interface CreateOptions {
|
||||
/**
|
||||
* name of the room. required
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* number of seconds to keep the room open before any participant joins
|
||||
*/
|
||||
emptyTimeout?: number;
|
||||
/**
|
||||
* number of seconds to keep the room open after the last participant leaves
|
||||
* this option is helpful to give a grace period for participants to re-join
|
||||
*/
|
||||
departureTimeout?: number;
|
||||
/**
|
||||
* limit to the number of participants in a room at a time
|
||||
*/
|
||||
maxParticipants?: number;
|
||||
/**
|
||||
* initial room metadata
|
||||
*/
|
||||
metadata?: string;
|
||||
/**
|
||||
* add egress options
|
||||
*/
|
||||
egress?: RoomEgress;
|
||||
/**
|
||||
* minimum playout delay in milliseconds
|
||||
*/
|
||||
minPlayoutDelay?: number;
|
||||
/**
|
||||
* maximum playout delay in milliseconds
|
||||
*/
|
||||
maxPlayoutDelay?: number;
|
||||
/**
|
||||
* improves A/V sync when min_playout_delay set to a value larger than 200ms.
|
||||
* It will disables transceiver re-use -- this option is not recommended
|
||||
* for rooms with frequent subscription changes
|
||||
*/
|
||||
syncStreams?: boolean;
|
||||
/**
|
||||
* agents that should be dispatched to this room
|
||||
*/
|
||||
agents?: RoomAgentDispatch[];
|
||||
/**
|
||||
* override the node room is allocated to, for debugging
|
||||
* does not work with Cloud
|
||||
*/
|
||||
nodeId?: string;
|
||||
}
|
||||
type SendDataOptions = {
|
||||
/** If set, only deliver to listed participant identities */
|
||||
destinationIdentities?: string[];
|
||||
destinationSids?: string[];
|
||||
topic?: string;
|
||||
};
|
||||
type UpdateParticipantOptions = {
|
||||
/** only attributes you'd want to update should be set, set value to empty string to remove it */
|
||||
attributes?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
metadata?: string;
|
||||
/** permissions are updated atomically - all desired permissions would need to be set */
|
||||
permission?: Partial<ParticipantPermission>;
|
||||
name?: string;
|
||||
};
|
||||
type RemoveParticipantOptions = {
|
||||
/**
|
||||
* Unix timestamp used to invalidate tokens whose nbf is before this value.
|
||||
*/
|
||||
revokeTokenTs?: bigint;
|
||||
};
|
||||
/**
|
||||
* Client to access Room APIs
|
||||
*/
|
||||
declare class RoomServiceClient extends ServiceBase {
|
||||
private readonly rpc;
|
||||
/**
|
||||
*
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host: string, apiKey?: string, secret?: string, options?: ClientOptions);
|
||||
/**
|
||||
* Creates a new room. Explicit room creation is not required, since rooms will
|
||||
* be automatically created when the first participant joins. This method can be
|
||||
* used to customize room settings.
|
||||
* @param options -
|
||||
*/
|
||||
createRoom(options: CreateOptions): Promise<Room>;
|
||||
/**
|
||||
* List active rooms
|
||||
* @param names - when undefined or empty, list all rooms.
|
||||
* otherwise returns rooms with matching names
|
||||
* @returns
|
||||
*/
|
||||
listRooms(names?: string[]): Promise<Room[]>;
|
||||
deleteRoom(room: string): Promise<void>;
|
||||
/**
|
||||
* Update metadata of a room
|
||||
* @param room - name of the room
|
||||
* @param metadata - the new metadata for the room
|
||||
*/
|
||||
updateRoomMetadata(room: string, metadata: string): Promise<Room>;
|
||||
/**
|
||||
* List participants in a room
|
||||
* @param room - name of the room
|
||||
*/
|
||||
listParticipants(room: string): Promise<ParticipantInfo[]>;
|
||||
/**
|
||||
* Get information on a specific participant, including the tracks that participant
|
||||
* has published
|
||||
* @param room - name of the room
|
||||
* @param identity - identity of the participant to return
|
||||
*/
|
||||
getParticipant(room: string, identity: string): Promise<ParticipantInfo>;
|
||||
/**
|
||||
* Removes a participant in the room. This will disconnect the participant
|
||||
* and will emit a Disconnected event for that participant.
|
||||
* Even after being removed, the participant can still re-join the room.
|
||||
* @param room -
|
||||
* @param identity -
|
||||
* @param options - removal options
|
||||
*/
|
||||
removeParticipant(room: string, identity: string, options?: RemoveParticipantOptions): Promise<void>;
|
||||
/**
|
||||
* Forwards a participant's track to another room. This will create a
|
||||
* participant to join the destination room that has same information
|
||||
* with the source participant except the kind to be `Forwarded`. All
|
||||
* changes to the source participant will be reflected to the forwarded
|
||||
* participant. When the source participant disconnects or the
|
||||
* `RemoveParticipant` method is called in the destination room, the
|
||||
* forwarding will be stopped.
|
||||
* @param room -
|
||||
* @param identity -
|
||||
* @param destinationRoom - the room to forward the participant to
|
||||
*/
|
||||
forwardParticipant(room: string, identity: string, destinationRoom: string): Promise<void>;
|
||||
/**
|
||||
* Move a connected participant to a different room. Requires `roomAdmin` and `destinationRoom`.
|
||||
* The participant will be removed from the current room and added to the destination room.
|
||||
* From the other observers' perspective, the participant would've disconnected from the previous room and joined the new one.
|
||||
* @param room -
|
||||
* @param identity -
|
||||
* @param destinationRoom - the room to move the participant to
|
||||
*/
|
||||
moveParticipant(room: string, identity: string, destinationRoom: string): Promise<void>;
|
||||
/**
|
||||
* Mutes a track that the participant has published.
|
||||
* @param room -
|
||||
* @param identity -
|
||||
* @param trackSid - sid of the track to be muted
|
||||
* @param muted - true to mute, false to unmute
|
||||
*/
|
||||
mutePublishedTrack(room: string, identity: string, trackSid: string, muted: boolean): Promise<TrackInfo>;
|
||||
/**
|
||||
* Updates a participant's state or permissions
|
||||
* @param room - target room
|
||||
* @param identity - participant identity
|
||||
* @param options - participant fields to update
|
||||
*/
|
||||
updateParticipant(room: string, identity: string, options: UpdateParticipantOptions): Promise<ParticipantInfo>;
|
||||
/**
|
||||
* Updates a participant's state or permissions
|
||||
* @param room - target room
|
||||
* @param identity - participant identity
|
||||
* @param options - participant fields to update
|
||||
*/
|
||||
updateParticipant(room: string, identity: string, metadata?: string, permission?: Partial<ParticipantPermission>, name?: string): Promise<ParticipantInfo>;
|
||||
/**
|
||||
* Updates a participant's subscription to tracks
|
||||
* @param room -
|
||||
* @param identity -
|
||||
* @param trackSids -
|
||||
* @param subscribe - true to subscribe, false to unsubscribe
|
||||
*/
|
||||
updateSubscriptions(room: string, identity: string, trackSids: string[], subscribe: boolean): Promise<void>;
|
||||
/**
|
||||
* Sends data message to participants in the room
|
||||
* @param room -
|
||||
* @param data - opaque payload to send
|
||||
* @param kind - delivery reliability
|
||||
* @param options - optionally specify a topic and destinationSids (when destinationSids is empty, message is sent to everyone)
|
||||
*/
|
||||
sendData(room: string, data: Uint8Array, kind: DataPacket_Kind, options: SendDataOptions): Promise<void>;
|
||||
/**
|
||||
* Sends data message to participants in the room
|
||||
* @deprecated use sendData(room, data, kind, options) instead
|
||||
* @param room -
|
||||
* @param data - opaque payload to send
|
||||
* @param kind - delivery reliability
|
||||
* @param destinationSids - optional. when empty, message is sent to everyone
|
||||
*/
|
||||
sendData(room: string, data: Uint8Array, kind: DataPacket_Kind, destinationSids?: string[]): Promise<void>;
|
||||
}
|
||||
|
||||
export { type CreateOptions, type RemoveParticipantOptions, RoomServiceClient, type SendDataOptions, type UpdateParticipantOptions };
|
||||
+208
@@ -0,0 +1,208 @@
|
||||
import { RoomEgress, RoomAgentDispatch, Room, ParticipantInfo, TrackInfo, ParticipantPermission, DataPacket_Kind } from '@livekit/protocol';
|
||||
import { ClientOptions } from './ClientOptions.js';
|
||||
import { ServiceBase } from './ServiceBase.js';
|
||||
import './grants.js';
|
||||
import 'jose';
|
||||
|
||||
/**
|
||||
* Options for when creating a room
|
||||
*/
|
||||
interface CreateOptions {
|
||||
/**
|
||||
* name of the room. required
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* number of seconds to keep the room open before any participant joins
|
||||
*/
|
||||
emptyTimeout?: number;
|
||||
/**
|
||||
* number of seconds to keep the room open after the last participant leaves
|
||||
* this option is helpful to give a grace period for participants to re-join
|
||||
*/
|
||||
departureTimeout?: number;
|
||||
/**
|
||||
* limit to the number of participants in a room at a time
|
||||
*/
|
||||
maxParticipants?: number;
|
||||
/**
|
||||
* initial room metadata
|
||||
*/
|
||||
metadata?: string;
|
||||
/**
|
||||
* add egress options
|
||||
*/
|
||||
egress?: RoomEgress;
|
||||
/**
|
||||
* minimum playout delay in milliseconds
|
||||
*/
|
||||
minPlayoutDelay?: number;
|
||||
/**
|
||||
* maximum playout delay in milliseconds
|
||||
*/
|
||||
maxPlayoutDelay?: number;
|
||||
/**
|
||||
* improves A/V sync when min_playout_delay set to a value larger than 200ms.
|
||||
* It will disables transceiver re-use -- this option is not recommended
|
||||
* for rooms with frequent subscription changes
|
||||
*/
|
||||
syncStreams?: boolean;
|
||||
/**
|
||||
* agents that should be dispatched to this room
|
||||
*/
|
||||
agents?: RoomAgentDispatch[];
|
||||
/**
|
||||
* override the node room is allocated to, for debugging
|
||||
* does not work with Cloud
|
||||
*/
|
||||
nodeId?: string;
|
||||
}
|
||||
type SendDataOptions = {
|
||||
/** If set, only deliver to listed participant identities */
|
||||
destinationIdentities?: string[];
|
||||
destinationSids?: string[];
|
||||
topic?: string;
|
||||
};
|
||||
type UpdateParticipantOptions = {
|
||||
/** only attributes you'd want to update should be set, set value to empty string to remove it */
|
||||
attributes?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
metadata?: string;
|
||||
/** permissions are updated atomically - all desired permissions would need to be set */
|
||||
permission?: Partial<ParticipantPermission>;
|
||||
name?: string;
|
||||
};
|
||||
type RemoveParticipantOptions = {
|
||||
/**
|
||||
* Unix timestamp used to invalidate tokens whose nbf is before this value.
|
||||
*/
|
||||
revokeTokenTs?: bigint;
|
||||
};
|
||||
/**
|
||||
* Client to access Room APIs
|
||||
*/
|
||||
declare class RoomServiceClient extends ServiceBase {
|
||||
private readonly rpc;
|
||||
/**
|
||||
*
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host: string, apiKey?: string, secret?: string, options?: ClientOptions);
|
||||
/**
|
||||
* Creates a new room. Explicit room creation is not required, since rooms will
|
||||
* be automatically created when the first participant joins. This method can be
|
||||
* used to customize room settings.
|
||||
* @param options -
|
||||
*/
|
||||
createRoom(options: CreateOptions): Promise<Room>;
|
||||
/**
|
||||
* List active rooms
|
||||
* @param names - when undefined or empty, list all rooms.
|
||||
* otherwise returns rooms with matching names
|
||||
* @returns
|
||||
*/
|
||||
listRooms(names?: string[]): Promise<Room[]>;
|
||||
deleteRoom(room: string): Promise<void>;
|
||||
/**
|
||||
* Update metadata of a room
|
||||
* @param room - name of the room
|
||||
* @param metadata - the new metadata for the room
|
||||
*/
|
||||
updateRoomMetadata(room: string, metadata: string): Promise<Room>;
|
||||
/**
|
||||
* List participants in a room
|
||||
* @param room - name of the room
|
||||
*/
|
||||
listParticipants(room: string): Promise<ParticipantInfo[]>;
|
||||
/**
|
||||
* Get information on a specific participant, including the tracks that participant
|
||||
* has published
|
||||
* @param room - name of the room
|
||||
* @param identity - identity of the participant to return
|
||||
*/
|
||||
getParticipant(room: string, identity: string): Promise<ParticipantInfo>;
|
||||
/**
|
||||
* Removes a participant in the room. This will disconnect the participant
|
||||
* and will emit a Disconnected event for that participant.
|
||||
* Even after being removed, the participant can still re-join the room.
|
||||
* @param room -
|
||||
* @param identity -
|
||||
* @param options - removal options
|
||||
*/
|
||||
removeParticipant(room: string, identity: string, options?: RemoveParticipantOptions): Promise<void>;
|
||||
/**
|
||||
* Forwards a participant's track to another room. This will create a
|
||||
* participant to join the destination room that has same information
|
||||
* with the source participant except the kind to be `Forwarded`. All
|
||||
* changes to the source participant will be reflected to the forwarded
|
||||
* participant. When the source participant disconnects or the
|
||||
* `RemoveParticipant` method is called in the destination room, the
|
||||
* forwarding will be stopped.
|
||||
* @param room -
|
||||
* @param identity -
|
||||
* @param destinationRoom - the room to forward the participant to
|
||||
*/
|
||||
forwardParticipant(room: string, identity: string, destinationRoom: string): Promise<void>;
|
||||
/**
|
||||
* Move a connected participant to a different room. Requires `roomAdmin` and `destinationRoom`.
|
||||
* The participant will be removed from the current room and added to the destination room.
|
||||
* From the other observers' perspective, the participant would've disconnected from the previous room and joined the new one.
|
||||
* @param room -
|
||||
* @param identity -
|
||||
* @param destinationRoom - the room to move the participant to
|
||||
*/
|
||||
moveParticipant(room: string, identity: string, destinationRoom: string): Promise<void>;
|
||||
/**
|
||||
* Mutes a track that the participant has published.
|
||||
* @param room -
|
||||
* @param identity -
|
||||
* @param trackSid - sid of the track to be muted
|
||||
* @param muted - true to mute, false to unmute
|
||||
*/
|
||||
mutePublishedTrack(room: string, identity: string, trackSid: string, muted: boolean): Promise<TrackInfo>;
|
||||
/**
|
||||
* Updates a participant's state or permissions
|
||||
* @param room - target room
|
||||
* @param identity - participant identity
|
||||
* @param options - participant fields to update
|
||||
*/
|
||||
updateParticipant(room: string, identity: string, options: UpdateParticipantOptions): Promise<ParticipantInfo>;
|
||||
/**
|
||||
* Updates a participant's state or permissions
|
||||
* @param room - target room
|
||||
* @param identity - participant identity
|
||||
* @param options - participant fields to update
|
||||
*/
|
||||
updateParticipant(room: string, identity: string, metadata?: string, permission?: Partial<ParticipantPermission>, name?: string): Promise<ParticipantInfo>;
|
||||
/**
|
||||
* Updates a participant's subscription to tracks
|
||||
* @param room -
|
||||
* @param identity -
|
||||
* @param trackSids -
|
||||
* @param subscribe - true to subscribe, false to unsubscribe
|
||||
*/
|
||||
updateSubscriptions(room: string, identity: string, trackSids: string[], subscribe: boolean): Promise<void>;
|
||||
/**
|
||||
* Sends data message to participants in the room
|
||||
* @param room -
|
||||
* @param data - opaque payload to send
|
||||
* @param kind - delivery reliability
|
||||
* @param options - optionally specify a topic and destinationSids (when destinationSids is empty, message is sent to everyone)
|
||||
*/
|
||||
sendData(room: string, data: Uint8Array, kind: DataPacket_Kind, options: SendDataOptions): Promise<void>;
|
||||
/**
|
||||
* Sends data message to participants in the room
|
||||
* @deprecated use sendData(room, data, kind, options) instead
|
||||
* @param room -
|
||||
* @param data - opaque payload to send
|
||||
* @param kind - delivery reliability
|
||||
* @param destinationSids - optional. when empty, message is sent to everyone
|
||||
*/
|
||||
sendData(room: string, data: Uint8Array, kind: DataPacket_Kind, destinationSids?: string[]): Promise<void>;
|
||||
}
|
||||
|
||||
export { type CreateOptions, type RemoveParticipantOptions, RoomServiceClient, type SendDataOptions, type UpdateParticipantOptions };
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"RoomServiceClient.d.ts","sourceRoot":"","sources":["../src/RoomServiceClient.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnG,OAAO,EAWL,eAAe,EACf,qBAAqB,EACrB,IAAI,EAML,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAK/C;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IAEpB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;OAEG;IACH,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAE7B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,4DAA4D;IAC5D,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,iGAAiG;IACjG,UAAU,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wFAAwF;IACxF,UAAU,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAIF;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,WAAW;IAChD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAE1B;;;;;;OAMG;gBACS,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa;IAQnF;;;;;OAKG;IACG,UAAU,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAUvD;;;;;OAKG;IACG,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAW5C,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS7C;;;;OAIG;IACG,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAUvD;;;OAGG;IACG,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAWhE;;;;;OAKG;IACG,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAW9E;;;;;;;OAOG;IACG,iBAAiB,CACrB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,IAAI,CAAC;IAahB;;;;;;;;;;;OAWG;IACG,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAShG;;;;;;;OAOG;IACG,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS7F;;;;;;OAMG;IACG,kBAAkB,CACtB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,SAAS,CAAC;IAiBrB;;;;;OAKG;IACG,iBAAiB,CACrB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,eAAe,CAAC;IAC3B;;;;;OAKG;IACG,iBAAiB,CACrB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,EAC3C,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,eAAe,CAAC;IAmC3B;;;;;;OAMG;IACG,mBAAmB,CACvB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EAAE,EACnB,SAAS,EAAE,OAAO,GACjB,OAAO,CAAC,IAAI,CAAC;IAgBhB;;;;;;OAMG;IACG,QAAQ,CACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,IAAI,CAAC;IAChB;;;;;;;OAOG;IACG,QAAQ,CACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,eAAe,EACrB,eAAe,CAAC,EAAE,MAAM,EAAE,GACzB,OAAO,CAAC,IAAI,CAAC;CA2BjB"}
|
||||
+272
@@ -0,0 +1,272 @@
|
||||
import {
|
||||
CreateRoomRequest,
|
||||
DeleteRoomRequest,
|
||||
ForwardParticipantRequest,
|
||||
ListParticipantsRequest,
|
||||
ListParticipantsResponse,
|
||||
ListRoomsRequest,
|
||||
ListRoomsResponse,
|
||||
MoveParticipantRequest,
|
||||
MuteRoomTrackRequest,
|
||||
MuteRoomTrackResponse,
|
||||
ParticipantInfo,
|
||||
ParticipantPermission,
|
||||
Room,
|
||||
RoomParticipantIdentity,
|
||||
SendDataRequest,
|
||||
UpdateParticipantRequest,
|
||||
UpdateRoomMetadataRequest,
|
||||
UpdateSubscriptionsRequest
|
||||
} from "@livekit/protocol";
|
||||
import { ServiceBase } from "./ServiceBase.js";
|
||||
import { TwirpRpc, livekitPackage } from "./TwirpRPC.js";
|
||||
import { getRandomBytes } from "./crypto/uuid.js";
|
||||
const svc = "RoomService";
|
||||
class RoomServiceClient extends ServiceBase {
|
||||
/**
|
||||
*
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host, apiKey, secret, options) {
|
||||
super({ apiKey, secret, token: options == null ? void 0 : options.token });
|
||||
this.rpc = new TwirpRpc(host, livekitPackage, {
|
||||
requestTimeout: options == null ? void 0 : options.requestTimeout,
|
||||
failover: options == null ? void 0 : options.failover
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Creates a new room. Explicit room creation is not required, since rooms will
|
||||
* be automatically created when the first participant joins. This method can be
|
||||
* used to customize room settings.
|
||||
* @param options -
|
||||
*/
|
||||
async createRoom(options) {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"CreateRoom",
|
||||
new CreateRoomRequest(options).toJson(),
|
||||
await this.authHeader({ roomCreate: true })
|
||||
);
|
||||
return Room.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* List active rooms
|
||||
* @param names - when undefined or empty, list all rooms.
|
||||
* otherwise returns rooms with matching names
|
||||
* @returns
|
||||
*/
|
||||
async listRooms(names) {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ListRooms",
|
||||
new ListRoomsRequest({ names: names ?? [] }).toJson(),
|
||||
await this.authHeader({ roomList: true })
|
||||
);
|
||||
const res = ListRoomsResponse.fromJson(data, { ignoreUnknownFields: true });
|
||||
return res.rooms ?? [];
|
||||
}
|
||||
async deleteRoom(room) {
|
||||
await this.rpc.request(
|
||||
svc,
|
||||
"DeleteRoom",
|
||||
new DeleteRoomRequest({ room }).toJson(),
|
||||
await this.authHeader({ roomCreate: true })
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Update metadata of a room
|
||||
* @param room - name of the room
|
||||
* @param metadata - the new metadata for the room
|
||||
*/
|
||||
async updateRoomMetadata(room, metadata) {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateRoomMetadata",
|
||||
new UpdateRoomMetadataRequest({ room, metadata }).toJson(),
|
||||
await this.authHeader({ roomAdmin: true, room })
|
||||
);
|
||||
return Room.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* List participants in a room
|
||||
* @param room - name of the room
|
||||
*/
|
||||
async listParticipants(room) {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ListParticipants",
|
||||
new ListParticipantsRequest({ room }).toJson(),
|
||||
await this.authHeader({ roomAdmin: true, room })
|
||||
);
|
||||
const res = ListParticipantsResponse.fromJson(data, { ignoreUnknownFields: true });
|
||||
return res.participants ?? [];
|
||||
}
|
||||
/**
|
||||
* Get information on a specific participant, including the tracks that participant
|
||||
* has published
|
||||
* @param room - name of the room
|
||||
* @param identity - identity of the participant to return
|
||||
*/
|
||||
async getParticipant(room, identity) {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"GetParticipant",
|
||||
new RoomParticipantIdentity({ room, identity }).toJson(),
|
||||
await this.authHeader({ roomAdmin: true, room })
|
||||
);
|
||||
return ParticipantInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Removes a participant in the room. This will disconnect the participant
|
||||
* and will emit a Disconnected event for that participant.
|
||||
* Even after being removed, the participant can still re-join the room.
|
||||
* @param room -
|
||||
* @param identity -
|
||||
* @param options - removal options
|
||||
*/
|
||||
async removeParticipant(room, identity, options) {
|
||||
await this.rpc.request(
|
||||
svc,
|
||||
"RemoveParticipant",
|
||||
new RoomParticipantIdentity({
|
||||
room,
|
||||
identity,
|
||||
revokeTokenTs: options == null ? void 0 : options.revokeTokenTs
|
||||
}).toJson(),
|
||||
await this.authHeader({ roomAdmin: true, room })
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Forwards a participant's track to another room. This will create a
|
||||
* participant to join the destination room that has same information
|
||||
* with the source participant except the kind to be `Forwarded`. All
|
||||
* changes to the source participant will be reflected to the forwarded
|
||||
* participant. When the source participant disconnects or the
|
||||
* `RemoveParticipant` method is called in the destination room, the
|
||||
* forwarding will be stopped.
|
||||
* @param room -
|
||||
* @param identity -
|
||||
* @param destinationRoom - the room to forward the participant to
|
||||
*/
|
||||
async forwardParticipant(room, identity, destinationRoom) {
|
||||
await this.rpc.request(
|
||||
svc,
|
||||
"ForwardParticipant",
|
||||
new ForwardParticipantRequest({ room, identity, destinationRoom }).toJson(),
|
||||
await this.authHeader({ roomAdmin: true, room, destinationRoom })
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Move a connected participant to a different room. Requires `roomAdmin` and `destinationRoom`.
|
||||
* The participant will be removed from the current room and added to the destination room.
|
||||
* From the other observers' perspective, the participant would've disconnected from the previous room and joined the new one.
|
||||
* @param room -
|
||||
* @param identity -
|
||||
* @param destinationRoom - the room to move the participant to
|
||||
*/
|
||||
async moveParticipant(room, identity, destinationRoom) {
|
||||
await this.rpc.request(
|
||||
svc,
|
||||
"MoveParticipant",
|
||||
new MoveParticipantRequest({ room, identity, destinationRoom }).toJson(),
|
||||
await this.authHeader({ roomAdmin: true, room, destinationRoom })
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Mutes a track that the participant has published.
|
||||
* @param room -
|
||||
* @param identity -
|
||||
* @param trackSid - sid of the track to be muted
|
||||
* @param muted - true to mute, false to unmute
|
||||
*/
|
||||
async mutePublishedTrack(room, identity, trackSid, muted) {
|
||||
const req = new MuteRoomTrackRequest({
|
||||
room,
|
||||
identity,
|
||||
trackSid,
|
||||
muted
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"MutePublishedTrack",
|
||||
req,
|
||||
await this.authHeader({ roomAdmin: true, room })
|
||||
);
|
||||
const res = MuteRoomTrackResponse.fromJson(data, { ignoreUnknownFields: true });
|
||||
return res.track;
|
||||
}
|
||||
async updateParticipant(room, identity, metadataOrOptions, maybePermission, maybeName) {
|
||||
const hasOptions = typeof metadataOrOptions === "object";
|
||||
const metadata = hasOptions ? metadataOrOptions == null ? void 0 : metadataOrOptions.metadata : metadataOrOptions;
|
||||
const permission = hasOptions ? metadataOrOptions.permission : maybePermission;
|
||||
const name = hasOptions ? metadataOrOptions.name : maybeName;
|
||||
const attributes = hasOptions ? metadataOrOptions.attributes : {};
|
||||
const req = new UpdateParticipantRequest({
|
||||
room,
|
||||
identity,
|
||||
attributes,
|
||||
metadata,
|
||||
name
|
||||
});
|
||||
if (permission) {
|
||||
req.permission = new ParticipantPermission(permission);
|
||||
}
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateParticipant",
|
||||
req.toJson(),
|
||||
await this.authHeader({ roomAdmin: true, room })
|
||||
);
|
||||
return ParticipantInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Updates a participant's subscription to tracks
|
||||
* @param room -
|
||||
* @param identity -
|
||||
* @param trackSids -
|
||||
* @param subscribe - true to subscribe, false to unsubscribe
|
||||
*/
|
||||
async updateSubscriptions(room, identity, trackSids, subscribe) {
|
||||
const req = new UpdateSubscriptionsRequest({
|
||||
room,
|
||||
identity,
|
||||
trackSids,
|
||||
subscribe,
|
||||
participantTracks: []
|
||||
}).toJson();
|
||||
await this.rpc.request(
|
||||
svc,
|
||||
"UpdateSubscriptions",
|
||||
req,
|
||||
await this.authHeader({ roomAdmin: true, room })
|
||||
);
|
||||
}
|
||||
async sendData(room, data, kind, options = {}) {
|
||||
const destinationSids = Array.isArray(options) ? options : options.destinationSids;
|
||||
const topic = Array.isArray(options) ? void 0 : options.topic;
|
||||
const req = new SendDataRequest({
|
||||
room,
|
||||
data,
|
||||
kind,
|
||||
destinationSids: destinationSids ?? [],
|
||||
topic
|
||||
});
|
||||
if (!Array.isArray(options) && options.destinationIdentities) {
|
||||
req.destinationIdentities = options.destinationIdentities;
|
||||
}
|
||||
req.nonce = await getRandomBytes(16);
|
||||
await this.rpc.request(
|
||||
svc,
|
||||
"SendData",
|
||||
req.toJson(),
|
||||
await this.authHeader({ roomAdmin: true, room })
|
||||
);
|
||||
}
|
||||
}
|
||||
export {
|
||||
RoomServiceClient
|
||||
};
|
||||
//# sourceMappingURL=RoomServiceClient.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+53
@@ -0,0 +1,53 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var ServiceBase_exports = {};
|
||||
__export(ServiceBase_exports, {
|
||||
ServiceBase: () => ServiceBase
|
||||
});
|
||||
module.exports = __toCommonJS(ServiceBase_exports);
|
||||
var import_AccessToken = require("./AccessToken.cjs");
|
||||
class ServiceBase {
|
||||
constructor(apiKeyOrOptions, secret, ttl) {
|
||||
const options = typeof apiKeyOrOptions === "object" ? apiKeyOrOptions : { apiKey: apiKeyOrOptions, secret, ttl };
|
||||
this.apiKey = options.apiKey;
|
||||
this.secret = options.secret;
|
||||
this.ttl = options.ttl || "10m";
|
||||
this.token = options.token;
|
||||
}
|
||||
async authHeader(grant, sip) {
|
||||
if (this.token) {
|
||||
return { Authorization: `Bearer ${this.token}` };
|
||||
}
|
||||
const at = new import_AccessToken.AccessToken(this.apiKey, this.secret, { ttl: this.ttl });
|
||||
if (grant) {
|
||||
at.addGrant(grant);
|
||||
}
|
||||
if (sip) {
|
||||
at.addSIPGrant(sip);
|
||||
}
|
||||
return {
|
||||
Authorization: `Bearer ${await at.toJwt()}`
|
||||
};
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
ServiceBase
|
||||
});
|
||||
//# sourceMappingURL=ServiceBase.cjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../src/ServiceBase.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { AccessToken } from './AccessToken.js';\nimport type { SIPGrant, VideoGrant } from './grants.js';\n\n/**\n * Authentication options for a service client.\n */\nexport interface ServiceBaseOptions {\n /** API Key. */\n apiKey?: string;\n /** API Secret. */\n secret?: string;\n /** Token TTL. Defaults to `10m`. */\n ttl?: string;\n /** Pre-signed token; sent verbatim, skipping per-call signing. */\n token?: string;\n}\n\n/**\n * Utilities to handle authentication\n */\nexport class ServiceBase {\n private readonly apiKey?: string;\n\n private readonly secret?: string;\n\n private readonly token?: string;\n\n private readonly ttl: string;\n\n /**\n * @param options - authentication options\n */\n constructor(options?: ServiceBaseOptions);\n /**\n * @deprecated pass a {@link ServiceBaseOptions} object instead.\n * @param apiKey - API Key.\n * @param secret - API Secret.\n * @param ttl - token TTL\n */\n constructor(apiKey?: string, secret?: string, ttl?: string);\n constructor(apiKeyOrOptions?: string | ServiceBaseOptions, secret?: string, ttl?: string) {\n const options: ServiceBaseOptions =\n typeof apiKeyOrOptions === 'object'\n ? apiKeyOrOptions\n : { apiKey: apiKeyOrOptions, secret, ttl };\n this.apiKey = options.apiKey;\n this.secret = options.secret;\n this.ttl = options.ttl || '10m';\n this.token = options.token;\n }\n\n async authHeader(grant: VideoGrant, sip?: SIPGrant): Promise<Record<string, string>> {\n // A pre-signed token is sent verbatim; the caller is responsible for its grants.\n if (this.token) {\n return { Authorization: `Bearer ${this.token}` };\n }\n const at = new AccessToken(this.apiKey, this.secret, { ttl: this.ttl });\n if (grant) {\n at.addGrant(grant);\n }\n if (sip) {\n at.addSIPGrant(sip);\n }\n return {\n Authorization: `Bearer ${await at.toJwt()}`,\n };\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,yBAA4B;AAoBrB,MAAM,YAAY;AAAA,EAoBvB,YAAY,iBAA+C,QAAiB,KAAc;AACxF,UAAM,UACJ,OAAO,oBAAoB,WACvB,kBACA,EAAE,QAAQ,iBAAiB,QAAQ,IAAI;AAC7C,SAAK,SAAS,QAAQ;AACtB,SAAK,SAAS,QAAQ;AACtB,SAAK,MAAM,QAAQ,OAAO;AAC1B,SAAK,QAAQ,QAAQ;AAAA,EACvB;AAAA,EAEA,MAAM,WAAW,OAAmB,KAAiD;AAEnF,QAAI,KAAK,OAAO;AACd,aAAO,EAAE,eAAe,UAAU,KAAK,KAAK,GAAG;AAAA,IACjD;AACA,UAAM,KAAK,IAAI,+BAAY,KAAK,QAAQ,KAAK,QAAQ,EAAE,KAAK,KAAK,IAAI,CAAC;AACtE,QAAI,OAAO;AACT,SAAG,SAAS,KAAK;AAAA,IACnB;AACA,QAAI,KAAK;AACP,SAAG,YAAY,GAAG;AAAA,IACpB;AACA,WAAO;AAAA,MACL,eAAe,UAAU,MAAM,GAAG,MAAM,CAAC;AAAA,IAC3C;AAAA,EACF;AACF;","names":[]}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
import { VideoGrant, SIPGrant } from './grants.cjs';
|
||||
import '@livekit/protocol';
|
||||
import 'jose';
|
||||
|
||||
/**
|
||||
* Authentication options for a service client.
|
||||
*/
|
||||
interface ServiceBaseOptions {
|
||||
/** API Key. */
|
||||
apiKey?: string;
|
||||
/** API Secret. */
|
||||
secret?: string;
|
||||
/** Token TTL. Defaults to `10m`. */
|
||||
ttl?: string;
|
||||
/** Pre-signed token; sent verbatim, skipping per-call signing. */
|
||||
token?: string;
|
||||
}
|
||||
/**
|
||||
* Utilities to handle authentication
|
||||
*/
|
||||
declare class ServiceBase {
|
||||
private readonly apiKey?;
|
||||
private readonly secret?;
|
||||
private readonly token?;
|
||||
private readonly ttl;
|
||||
/**
|
||||
* @param options - authentication options
|
||||
*/
|
||||
constructor(options?: ServiceBaseOptions);
|
||||
/**
|
||||
* @deprecated pass a {@link ServiceBaseOptions} object instead.
|
||||
* @param apiKey - API Key.
|
||||
* @param secret - API Secret.
|
||||
* @param ttl - token TTL
|
||||
*/
|
||||
constructor(apiKey?: string, secret?: string, ttl?: string);
|
||||
authHeader(grant: VideoGrant, sip?: SIPGrant): Promise<Record<string, string>>;
|
||||
}
|
||||
|
||||
export { ServiceBase, type ServiceBaseOptions };
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
import { VideoGrant, SIPGrant } from './grants.js';
|
||||
import '@livekit/protocol';
|
||||
import 'jose';
|
||||
|
||||
/**
|
||||
* Authentication options for a service client.
|
||||
*/
|
||||
interface ServiceBaseOptions {
|
||||
/** API Key. */
|
||||
apiKey?: string;
|
||||
/** API Secret. */
|
||||
secret?: string;
|
||||
/** Token TTL. Defaults to `10m`. */
|
||||
ttl?: string;
|
||||
/** Pre-signed token; sent verbatim, skipping per-call signing. */
|
||||
token?: string;
|
||||
}
|
||||
/**
|
||||
* Utilities to handle authentication
|
||||
*/
|
||||
declare class ServiceBase {
|
||||
private readonly apiKey?;
|
||||
private readonly secret?;
|
||||
private readonly token?;
|
||||
private readonly ttl;
|
||||
/**
|
||||
* @param options - authentication options
|
||||
*/
|
||||
constructor(options?: ServiceBaseOptions);
|
||||
/**
|
||||
* @deprecated pass a {@link ServiceBaseOptions} object instead.
|
||||
* @param apiKey - API Key.
|
||||
* @param secret - API Secret.
|
||||
* @param ttl - token TTL
|
||||
*/
|
||||
constructor(apiKey?: string, secret?: string, ttl?: string);
|
||||
authHeader(grant: VideoGrant, sip?: SIPGrant): Promise<Record<string, string>>;
|
||||
}
|
||||
|
||||
export { ServiceBase, type ServiceBaseOptions };
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ServiceBase.d.ts","sourceRoot":"","sources":["../src/ServiceBase.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,eAAe;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kBAAkB;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IAEjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IAEjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAS;IAEhC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAE7B;;OAEG;gBACS,OAAO,CAAC,EAAE,kBAAkB;IACxC;;;;;OAKG;gBACS,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM;IAYpD,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAgBrF"}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
import { AccessToken } from "./AccessToken.js";
|
||||
class ServiceBase {
|
||||
constructor(apiKeyOrOptions, secret, ttl) {
|
||||
const options = typeof apiKeyOrOptions === "object" ? apiKeyOrOptions : { apiKey: apiKeyOrOptions, secret, ttl };
|
||||
this.apiKey = options.apiKey;
|
||||
this.secret = options.secret;
|
||||
this.ttl = options.ttl || "10m";
|
||||
this.token = options.token;
|
||||
}
|
||||
async authHeader(grant, sip) {
|
||||
if (this.token) {
|
||||
return { Authorization: `Bearer ${this.token}` };
|
||||
}
|
||||
const at = new AccessToken(this.apiKey, this.secret, { ttl: this.ttl });
|
||||
if (grant) {
|
||||
at.addGrant(grant);
|
||||
}
|
||||
if (sip) {
|
||||
at.addSIPGrant(sip);
|
||||
}
|
||||
return {
|
||||
Authorization: `Bearer ${await at.toJwt()}`
|
||||
};
|
||||
}
|
||||
}
|
||||
export {
|
||||
ServiceBase
|
||||
};
|
||||
//# sourceMappingURL=ServiceBase.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../src/ServiceBase.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { AccessToken } from './AccessToken.js';\nimport type { SIPGrant, VideoGrant } from './grants.js';\n\n/**\n * Authentication options for a service client.\n */\nexport interface ServiceBaseOptions {\n /** API Key. */\n apiKey?: string;\n /** API Secret. */\n secret?: string;\n /** Token TTL. Defaults to `10m`. */\n ttl?: string;\n /** Pre-signed token; sent verbatim, skipping per-call signing. */\n token?: string;\n}\n\n/**\n * Utilities to handle authentication\n */\nexport class ServiceBase {\n private readonly apiKey?: string;\n\n private readonly secret?: string;\n\n private readonly token?: string;\n\n private readonly ttl: string;\n\n /**\n * @param options - authentication options\n */\n constructor(options?: ServiceBaseOptions);\n /**\n * @deprecated pass a {@link ServiceBaseOptions} object instead.\n * @param apiKey - API Key.\n * @param secret - API Secret.\n * @param ttl - token TTL\n */\n constructor(apiKey?: string, secret?: string, ttl?: string);\n constructor(apiKeyOrOptions?: string | ServiceBaseOptions, secret?: string, ttl?: string) {\n const options: ServiceBaseOptions =\n typeof apiKeyOrOptions === 'object'\n ? apiKeyOrOptions\n : { apiKey: apiKeyOrOptions, secret, ttl };\n this.apiKey = options.apiKey;\n this.secret = options.secret;\n this.ttl = options.ttl || '10m';\n this.token = options.token;\n }\n\n async authHeader(grant: VideoGrant, sip?: SIPGrant): Promise<Record<string, string>> {\n // A pre-signed token is sent verbatim; the caller is responsible for its grants.\n if (this.token) {\n return { Authorization: `Bearer ${this.token}` };\n }\n const at = new AccessToken(this.apiKey, this.secret, { ttl: this.ttl });\n if (grant) {\n at.addGrant(grant);\n }\n if (sip) {\n at.addSIPGrant(sip);\n }\n return {\n Authorization: `Bearer ${await at.toJwt()}`,\n };\n }\n}\n"],"mappings":"AAGA,SAAS,mBAAmB;AAoBrB,MAAM,YAAY;AAAA,EAoBvB,YAAY,iBAA+C,QAAiB,KAAc;AACxF,UAAM,UACJ,OAAO,oBAAoB,WACvB,kBACA,EAAE,QAAQ,iBAAiB,QAAQ,IAAI;AAC7C,SAAK,SAAS,QAAQ;AACtB,SAAK,SAAS,QAAQ;AACtB,SAAK,MAAM,QAAQ,OAAO;AAC1B,SAAK,QAAQ,QAAQ;AAAA,EACvB;AAAA,EAEA,MAAM,WAAW,OAAmB,KAAiD;AAEnF,QAAI,KAAK,OAAO;AACd,aAAO,EAAE,eAAe,UAAU,KAAK,KAAK,GAAG;AAAA,IACjD;AACA,UAAM,KAAK,IAAI,YAAY,KAAK,QAAQ,KAAK,QAAQ,EAAE,KAAK,KAAK,IAAI,CAAC;AACtE,QAAI,OAAO;AACT,SAAG,SAAS,KAAK;AAAA,IACnB;AACA,QAAI,KAAK;AACP,SAAG,YAAY,GAAG;AAAA,IACpB;AACA,WAAO;AAAA,MACL,eAAe,UAAU,MAAM,GAAG,MAAM,CAAC;AAAA,IAC3C;AAAA,EACF;AACF;","names":[]}
|
||||
+560
@@ -0,0 +1,560 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var SipClient_exports = {};
|
||||
__export(SipClient_exports, {
|
||||
SipClient: () => SipClient
|
||||
});
|
||||
module.exports = __toCommonJS(SipClient_exports);
|
||||
var import_protobuf = require("@bufbuild/protobuf");
|
||||
var import_protocol = require("@livekit/protocol");
|
||||
var import_ServiceBase = require("./ServiceBase.cjs");
|
||||
var import_TwirpRPC = require("./TwirpRPC.cjs");
|
||||
var import_dialTimeout = require("./dialTimeout.cjs");
|
||||
function asSipCallError(e) {
|
||||
if (e instanceof import_TwirpRPC.ServerError && e.metadata && "sip_status_code" in e.metadata) {
|
||||
return import_TwirpRPC.SipCallError.fromServerError(e);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
const svc = "SIP";
|
||||
class SipClient extends import_ServiceBase.ServiceBase {
|
||||
/**
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host, apiKey, secret, options) {
|
||||
super({ apiKey, secret, token: options == null ? void 0 : options.token });
|
||||
this.rpc = new import_TwirpRPC.TwirpRpc(host, import_TwirpRPC.livekitPackage, {
|
||||
requestTimeout: options == null ? void 0 : options.requestTimeout,
|
||||
failover: options == null ? void 0 : options.failover
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @param number - phone number of the trunk
|
||||
* @param opts - CreateSipTrunkOptions
|
||||
* @deprecated use `createSipInboundTrunk` or `createSipOutboundTrunk`
|
||||
*/
|
||||
async createSipTrunk(number, opts) {
|
||||
let inboundAddresses;
|
||||
let inboundNumbers;
|
||||
let inboundUsername = "";
|
||||
let inboundPassword = "";
|
||||
let outboundAddress = "";
|
||||
let outboundUsername = "";
|
||||
let outboundPassword = "";
|
||||
let name = "";
|
||||
let metadata = "";
|
||||
if (opts !== void 0) {
|
||||
inboundAddresses = opts.inbound_addresses;
|
||||
inboundNumbers = opts.inbound_numbers;
|
||||
inboundUsername = opts.inbound_username || "";
|
||||
inboundPassword = opts.inbound_password || "";
|
||||
outboundAddress = opts.outbound_address || "";
|
||||
outboundUsername = opts.outbound_username || "";
|
||||
outboundPassword = opts.outbound_password || "";
|
||||
name = opts.name || "";
|
||||
metadata = opts.metadata || "";
|
||||
}
|
||||
const req = new import_protocol.CreateSIPTrunkRequest({
|
||||
name,
|
||||
metadata,
|
||||
inboundAddresses,
|
||||
inboundNumbers,
|
||||
inboundUsername,
|
||||
inboundPassword,
|
||||
outboundNumber: number,
|
||||
outboundAddress,
|
||||
outboundUsername,
|
||||
outboundPassword
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"CreateSIPTrunk",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return import_protocol.SIPTrunkInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Create a new SIP inbound trunk.
|
||||
*
|
||||
* @param name - human-readable name of the trunk
|
||||
* @param numbers - phone numbers of the trunk
|
||||
* @param opts - CreateSipTrunkOptions
|
||||
* @returns Created SIP inbound trunk
|
||||
*/
|
||||
async createSipInboundTrunk(name, numbers, opts) {
|
||||
if (opts === void 0) {
|
||||
opts = {};
|
||||
}
|
||||
const req = new import_protocol.CreateSIPInboundTrunkRequest({
|
||||
trunk: new import_protocol.SIPInboundTrunkInfo({
|
||||
name,
|
||||
numbers,
|
||||
metadata: opts == null ? void 0 : opts.metadata,
|
||||
allowedAddresses: opts.allowedAddresses ?? opts.allowed_addresses,
|
||||
allowedNumbers: opts.allowedNumbers ?? opts.allowed_numbers,
|
||||
authUsername: opts.authUsername ?? opts.auth_username,
|
||||
authPassword: opts.authPassword ?? opts.auth_password,
|
||||
headers: opts.headers,
|
||||
headersToAttributes: opts.headersToAttributes,
|
||||
includeHeaders: opts.includeHeaders,
|
||||
krispEnabled: opts.krispEnabled,
|
||||
mediaEncryption: opts.mediaEncryption,
|
||||
media: opts.media,
|
||||
ringingTimeout: opts.ringingTimeout ? new import_protobuf.Duration({ seconds: BigInt(opts.ringingTimeout) }) : void 0
|
||||
})
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"CreateSIPInboundTrunk",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return import_protocol.SIPInboundTrunkInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Create a new SIP outbound trunk.
|
||||
*
|
||||
* @param name - human-readable name of the trunk
|
||||
* @param address - hostname and port of the SIP server to dial
|
||||
* @param numbers - phone numbers of the trunk
|
||||
* @param opts - CreateSipTrunkOptions
|
||||
* @returns Created SIP outbound trunk
|
||||
*/
|
||||
async createSipOutboundTrunk(name, address, numbers, opts) {
|
||||
if (opts === void 0) {
|
||||
opts = {
|
||||
transport: import_protocol.SIPTransport.SIP_TRANSPORT_AUTO
|
||||
};
|
||||
}
|
||||
const req = new import_protocol.CreateSIPOutboundTrunkRequest({
|
||||
trunk: new import_protocol.SIPOutboundTrunkInfo({
|
||||
name,
|
||||
address,
|
||||
numbers,
|
||||
metadata: opts.metadata,
|
||||
transport: opts.transport,
|
||||
authUsername: opts.authUsername ?? opts.auth_username,
|
||||
authPassword: opts.authPassword ?? opts.auth_password,
|
||||
headers: opts.headers,
|
||||
headersToAttributes: opts.headersToAttributes,
|
||||
includeHeaders: opts.includeHeaders,
|
||||
destinationCountry: opts.destinationCountry,
|
||||
mediaEncryption: opts.mediaEncryption,
|
||||
media: opts.media
|
||||
})
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"CreateSIPOutboundTrunk",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return import_protocol.SIPOutboundTrunkInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* @deprecated use `listSipInboundTrunk` or `listSipOutboundTrunk`
|
||||
*/
|
||||
async listSipTrunk() {
|
||||
const req = {};
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ListSIPTrunk",
|
||||
new import_protocol.ListSIPTrunkRequest(req).toJson(),
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return import_protocol.ListSIPTrunkResponse.fromJson(data, { ignoreUnknownFields: true }).items ?? [];
|
||||
}
|
||||
/**
|
||||
* List SIP inbound trunks with optional filtering.
|
||||
*
|
||||
* @param list - Request with optional filtering parameters
|
||||
* @returns Response containing list of SIP inbound trunks
|
||||
*/
|
||||
async listSipInboundTrunk(list = {}) {
|
||||
const req = new import_protocol.ListSIPInboundTrunkRequest(list).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ListSIPInboundTrunk",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return import_protocol.ListSIPInboundTrunkResponse.fromJson(data, { ignoreUnknownFields: true }).items ?? [];
|
||||
}
|
||||
/**
|
||||
* List SIP outbound trunks with optional filtering.
|
||||
*
|
||||
* @param list - Request with optional filtering parameters
|
||||
* @returns Response containing list of SIP outbound trunks
|
||||
*/
|
||||
async listSipOutboundTrunk(list = {}) {
|
||||
const req = new import_protocol.ListSIPOutboundTrunkRequest(list).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ListSIPOutboundTrunk",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return import_protocol.ListSIPOutboundTrunkResponse.fromJson(data, { ignoreUnknownFields: true }).items ?? [];
|
||||
}
|
||||
/**
|
||||
* Delete a SIP trunk.
|
||||
*
|
||||
* @param sipTrunkId - ID of the SIP trunk to delete
|
||||
* @returns Deleted trunk information
|
||||
*/
|
||||
async deleteSipTrunk(sipTrunkId) {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"DeleteSIPTrunk",
|
||||
new import_protocol.DeleteSIPTrunkRequest({ sipTrunkId }).toJson(),
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return import_protocol.SIPTrunkInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Create a new SIP dispatch rule.
|
||||
*
|
||||
* @param rule - SIP dispatch rule to create
|
||||
* @param opts - CreateSipDispatchRuleOptions
|
||||
* @returns Created SIP dispatch rule
|
||||
*/
|
||||
async createSipDispatchRule(rule, opts) {
|
||||
if (opts === void 0) {
|
||||
opts = {};
|
||||
}
|
||||
let ruleProto = void 0;
|
||||
if (rule.type == "direct") {
|
||||
ruleProto = new import_protocol.SIPDispatchRule({
|
||||
rule: {
|
||||
case: "dispatchRuleDirect",
|
||||
value: new import_protocol.SIPDispatchRuleDirect({
|
||||
roomName: rule.roomName,
|
||||
pin: rule.pin || ""
|
||||
})
|
||||
}
|
||||
});
|
||||
} else if (rule.type == "individual") {
|
||||
ruleProto = new import_protocol.SIPDispatchRule({
|
||||
rule: {
|
||||
case: "dispatchRuleIndividual",
|
||||
value: new import_protocol.SIPDispatchRuleIndividual({
|
||||
roomPrefix: rule.roomPrefix,
|
||||
pin: rule.pin || ""
|
||||
})
|
||||
}
|
||||
});
|
||||
} else if (rule.type == "callee") {
|
||||
ruleProto = new import_protocol.SIPDispatchRule({
|
||||
rule: {
|
||||
case: "dispatchRuleCallee",
|
||||
value: new import_protocol.SIPDispatchRuleCallee({
|
||||
roomPrefix: rule.roomPrefix,
|
||||
pin: rule.pin || "",
|
||||
randomize: rule.randomize || false
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
const req = new import_protocol.CreateSIPDispatchRuleRequest({
|
||||
rule: ruleProto,
|
||||
trunkIds: opts.trunkIds,
|
||||
hidePhoneNumber: opts.hidePhoneNumber,
|
||||
name: opts.name,
|
||||
metadata: opts.metadata,
|
||||
attributes: opts.attributes,
|
||||
roomPreset: opts.roomPreset,
|
||||
roomConfig: opts.roomConfig
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"CreateSIPDispatchRule",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return import_protocol.SIPDispatchRuleInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Updates an existing SIP dispatch rule by replacing it entirely.
|
||||
*
|
||||
* @param sipDispatchRuleId - ID of the SIP dispatch rule to update
|
||||
* @param rule - new SIP dispatch rule
|
||||
* @returns Updated SIP dispatch rule
|
||||
*/
|
||||
async updateSipDispatchRule(sipDispatchRuleId, rule) {
|
||||
const req = new import_protocol.UpdateSIPDispatchRuleRequest({
|
||||
sipDispatchRuleId,
|
||||
action: {
|
||||
case: "replace",
|
||||
value: rule
|
||||
}
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateSIPDispatchRule",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return import_protocol.SIPDispatchRuleInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Updates specific fields of an existing SIP dispatch rule.
|
||||
* Only provided fields will be updated.
|
||||
*
|
||||
* @param sipDispatchRuleId - ID of the SIP dispatch rule to update
|
||||
* @param fields - Fields of the dispatch rule to update
|
||||
* @returns Updated SIP dispatch rule
|
||||
*/
|
||||
async updateSipDispatchRuleFields(sipDispatchRuleId, fields = {}) {
|
||||
const req = new import_protocol.UpdateSIPDispatchRuleRequest({
|
||||
sipDispatchRuleId,
|
||||
action: {
|
||||
case: "update",
|
||||
value: fields
|
||||
}
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateSIPDispatchRule",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return import_protocol.SIPDispatchRuleInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Updates an existing SIP inbound trunk by replacing it entirely.
|
||||
*
|
||||
* @param sipTrunkId - ID of the SIP inbound trunk to update
|
||||
* @param trunk - SIP inbound trunk to update with
|
||||
* @returns Updated SIP inbound trunk
|
||||
*/
|
||||
async updateSipInboundTrunk(sipTrunkId, trunk) {
|
||||
const req = new import_protocol.UpdateSIPInboundTrunkRequest({
|
||||
sipTrunkId,
|
||||
action: {
|
||||
case: "replace",
|
||||
value: trunk
|
||||
}
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateSIPInboundTrunk",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return import_protocol.SIPInboundTrunkInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Updates specific fields of an existing SIP inbound trunk.
|
||||
* Only provided fields will be updated.
|
||||
*
|
||||
* @param sipTrunkId - ID of the SIP inbound trunk to update
|
||||
* @param fields - Fields of the inbound trunk to update
|
||||
* @returns Updated SIP inbound trunk
|
||||
*/
|
||||
async updateSipInboundTrunkFields(sipTrunkId, fields) {
|
||||
const req = new import_protocol.UpdateSIPInboundTrunkRequest({
|
||||
sipTrunkId,
|
||||
action: {
|
||||
case: "update",
|
||||
value: fields
|
||||
}
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateSIPInboundTrunk",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return import_protocol.SIPInboundTrunkInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Updates an existing SIP outbound trunk by replacing it entirely.
|
||||
*
|
||||
* @param sipTrunkId - ID of the SIP outbound trunk to update
|
||||
* @param trunk - SIP outbound trunk to update with
|
||||
* @returns Updated SIP outbound trunk
|
||||
*/
|
||||
async updateSipOutboundTrunk(sipTrunkId, trunk) {
|
||||
const req = new import_protocol.UpdateSIPOutboundTrunkRequest({
|
||||
sipTrunkId,
|
||||
action: {
|
||||
case: "replace",
|
||||
value: trunk
|
||||
}
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateSIPOutboundTrunk",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return import_protocol.SIPOutboundTrunkInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Updates specific fields of an existing SIP outbound trunk.
|
||||
* Only provided fields will be updated.
|
||||
*
|
||||
* @param sipTrunkId - ID of the SIP outbound trunk to update
|
||||
* @param fields - Fields of the outbound trunk to update
|
||||
* @returns Updated SIP outbound trunk
|
||||
*/
|
||||
async updateSipOutboundTrunkFields(sipTrunkId, fields) {
|
||||
const req = new import_protocol.UpdateSIPOutboundTrunkRequest({
|
||||
sipTrunkId,
|
||||
action: {
|
||||
case: "update",
|
||||
value: fields
|
||||
}
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateSIPOutboundTrunk",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return import_protocol.SIPOutboundTrunkInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* List SIP dispatch rules with optional filtering.
|
||||
*
|
||||
* @param list - Request with optional filtering parameters
|
||||
* @returns Response containing list of SIP dispatch rules
|
||||
*/
|
||||
async listSipDispatchRule(list = {}) {
|
||||
const req = new import_protocol.ListSIPDispatchRuleRequest(list).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ListSIPDispatchRule",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return import_protocol.ListSIPDispatchRuleResponse.fromJson(data, { ignoreUnknownFields: true }).items ?? [];
|
||||
}
|
||||
/**
|
||||
* Delete a SIP dispatch rule.
|
||||
*
|
||||
* @param sipDispatchRuleId - ID of the SIP dispatch rule to delete
|
||||
* @returns Deleted rule information
|
||||
*/
|
||||
async deleteSipDispatchRule(sipDispatchRuleId) {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"DeleteSIPDispatchRule",
|
||||
new import_protocol.DeleteSIPDispatchRuleRequest({ sipDispatchRuleId }).toJson(),
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return import_protocol.SIPDispatchRuleInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Create a new SIP participant.
|
||||
*
|
||||
* @param sipTrunkId - sip trunk to use for the call
|
||||
* @param number - number to dial
|
||||
* @param roomName - room to attach the call to
|
||||
* @param opts - CreateSipParticipantOptions
|
||||
* @param outboundTrunkConfig - Optional outbound trunk configuration for sip participant.
|
||||
* @returns Created SIP participant
|
||||
*/
|
||||
async createSipParticipant(sipTrunkId, number, roomName, opts, outboundTrunkConfig) {
|
||||
if (opts === void 0) {
|
||||
opts = {};
|
||||
}
|
||||
if (opts.waitUntilAnswered) {
|
||||
opts.ringingTimeout ??= import_dialTimeout.DEFAULT_RINGING_TIMEOUT_SECONDS;
|
||||
opts.timeout = (0, import_dialTimeout.dialRequestTimeout)(opts.timeout, opts.ringingTimeout);
|
||||
}
|
||||
const req = new import_protocol.CreateSIPParticipantRequest({
|
||||
sipTrunkId,
|
||||
trunk: outboundTrunkConfig,
|
||||
sipCallTo: number,
|
||||
sipNumber: opts.fromNumber,
|
||||
roomName,
|
||||
participantIdentity: opts.participantIdentity || "sip-participant",
|
||||
participantName: opts.participantName,
|
||||
displayName: opts.displayName,
|
||||
participantMetadata: opts.participantMetadata,
|
||||
participantAttributes: opts.participantAttributes,
|
||||
dtmf: opts.dtmf,
|
||||
playDialtone: opts.playDialtone ?? opts.playRingtone,
|
||||
headers: opts.headers,
|
||||
hidePhoneNumber: opts.hidePhoneNumber,
|
||||
includeHeaders: opts.includeHeaders,
|
||||
ringingTimeout: opts.ringingTimeout ? new import_protobuf.Duration({ seconds: BigInt(opts.ringingTimeout) }) : void 0,
|
||||
maxCallDuration: opts.maxCallDuration ? new import_protobuf.Duration({ seconds: BigInt(opts.maxCallDuration) }) : void 0,
|
||||
krispEnabled: opts.krispEnabled,
|
||||
waitUntilAnswered: opts.waitUntilAnswered,
|
||||
media: opts.media
|
||||
}).toJson();
|
||||
try {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"CreateSIPParticipant",
|
||||
req,
|
||||
await this.authHeader({}, { call: true }),
|
||||
opts.timeout
|
||||
);
|
||||
return import_protocol.SIPParticipantInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
} catch (e) {
|
||||
throw asSipCallError(e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Transfer a SIP participant to a different room.
|
||||
*
|
||||
* @param roomName - room the SIP participant to transfer is connectd to
|
||||
* @param participantIdentity - identity of the SIP participant to transfer
|
||||
* @param transferTo - SIP URL to transfer the participant to
|
||||
* @param opts - TransferSipParticipantOptions
|
||||
*/
|
||||
async transferSipParticipant(roomName, participantIdentity, transferTo, opts) {
|
||||
if (opts === void 0) {
|
||||
opts = {};
|
||||
}
|
||||
opts.ringingTimeout ??= import_dialTimeout.DEFAULT_RINGING_TIMEOUT_SECONDS;
|
||||
opts.timeout = (0, import_dialTimeout.dialRequestTimeout)(opts.timeout, opts.ringingTimeout);
|
||||
const req = new import_protocol.TransferSIPParticipantRequest({
|
||||
participantIdentity,
|
||||
roomName,
|
||||
transferTo,
|
||||
playDialtone: opts.playDialtone,
|
||||
headers: opts.headers,
|
||||
ringingTimeout: opts.ringingTimeout ? new import_protobuf.Duration({ seconds: BigInt(opts.ringingTimeout) }) : void 0
|
||||
}).toJson();
|
||||
try {
|
||||
await this.rpc.request(
|
||||
svc,
|
||||
"TransferSIPParticipant",
|
||||
req,
|
||||
await this.authHeader({ roomAdmin: true, room: roomName }, { call: true }),
|
||||
opts.timeout
|
||||
);
|
||||
} catch (e) {
|
||||
throw asSipCallError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
SipClient
|
||||
});
|
||||
//# sourceMappingURL=SipClient.cjs.map
|
||||
+1
File diff suppressed because one or more lines are too long
+356
@@ -0,0 +1,356 @@
|
||||
import { SIPTrunkInfo, SIPHeaderOptions, SIPMediaEncryption, SIPMediaConfig, SIPInboundTrunkInfo, SIPTransport, SIPOutboundTrunkInfo, Pagination, RoomConfiguration, SIPDispatchRuleInfo, ListUpdate, SIPDispatchRule, SIPOutboundConfig, SIPParticipantInfo } from '@livekit/protocol';
|
||||
import { ClientOptions } from './ClientOptions.cjs';
|
||||
import { ServiceBase } from './ServiceBase.cjs';
|
||||
import './grants.cjs';
|
||||
import 'jose';
|
||||
|
||||
/**
|
||||
* @deprecated use CreateSipInboundTrunkOptions or CreateSipOutboundTrunkOptions
|
||||
*/
|
||||
interface CreateSipTrunkOptions {
|
||||
name?: string;
|
||||
metadata?: string;
|
||||
inbound_addresses?: string[];
|
||||
inbound_numbers?: string[];
|
||||
inbound_username?: string;
|
||||
inbound_password?: string;
|
||||
outbound_address?: string;
|
||||
outbound_username?: string;
|
||||
outbound_password?: string;
|
||||
}
|
||||
interface CreateSipInboundTrunkOptions {
|
||||
metadata?: string;
|
||||
/** @deprecated - use `allowedAddresses` instead */
|
||||
allowed_addresses?: string[];
|
||||
allowedAddresses?: string[];
|
||||
/** @deprecated - use `allowedNumbers` instead */
|
||||
allowed_numbers?: string[];
|
||||
allowedNumbers?: string[];
|
||||
/** @deprecated - use `authUsername` instead */
|
||||
auth_username?: string;
|
||||
authUsername?: string;
|
||||
/** @deprecated - use `authPassword` instead */
|
||||
auth_password?: string;
|
||||
authPassword?: string;
|
||||
headers?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
headersToAttributes?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
includeHeaders?: SIPHeaderOptions;
|
||||
krispEnabled?: boolean;
|
||||
/** @deprecated - use `media.encryption` instead */
|
||||
mediaEncryption?: SIPMediaEncryption;
|
||||
media?: SIPMediaConfig;
|
||||
/** Maximum time for a call to ring in seconds. */
|
||||
ringingTimeout?: number;
|
||||
}
|
||||
interface CreateSipOutboundTrunkOptions {
|
||||
metadata?: string;
|
||||
transport: SIPTransport;
|
||||
destinationCountry?: string;
|
||||
/** @deprecated - use `authUsername` instead */
|
||||
auth_username?: string;
|
||||
authUsername?: string;
|
||||
/** @deprecated - use `authPassword` instead */
|
||||
auth_password?: string;
|
||||
authPassword?: string;
|
||||
headers?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
headersToAttributes?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
includeHeaders?: SIPHeaderOptions;
|
||||
/** @deprecated - use `media.encryption` instead */
|
||||
mediaEncryption?: SIPMediaEncryption;
|
||||
media?: SIPMediaConfig;
|
||||
}
|
||||
interface SipDispatchRuleDirect {
|
||||
type: 'direct';
|
||||
roomName: string;
|
||||
pin?: string;
|
||||
}
|
||||
interface SipDispatchRuleIndividual {
|
||||
type: 'individual';
|
||||
roomPrefix: string;
|
||||
pin?: string;
|
||||
}
|
||||
interface SipDispatchRuleCallee {
|
||||
type: 'callee';
|
||||
roomPrefix: string;
|
||||
pin?: string;
|
||||
/** Optionally append a random suffix to the room name. */
|
||||
randomize?: boolean;
|
||||
}
|
||||
interface CreateSipDispatchRuleOptions {
|
||||
name?: string;
|
||||
metadata?: string;
|
||||
trunkIds?: string[];
|
||||
hidePhoneNumber?: boolean;
|
||||
attributes?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
roomPreset?: string;
|
||||
roomConfig?: RoomConfiguration;
|
||||
}
|
||||
interface CreateSipParticipantOptions {
|
||||
/** Optional SIP From number to use. If empty, trunk number is used. */
|
||||
fromNumber?: string;
|
||||
/** Optional identity of the SIP participant */
|
||||
participantIdentity?: string;
|
||||
/** Optional name of the participant */
|
||||
participantName?: string;
|
||||
/** Optional display name for the SIP participant */
|
||||
displayName?: string;
|
||||
/** Optional metadata to attach to the participant */
|
||||
participantMetadata?: string;
|
||||
/** Optional attributes to attach to the participant */
|
||||
participantAttributes?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
/** Optionally send following DTMF digits (extension codes) when making a call.
|
||||
* Character 'w' can be used to add a 0.5 sec delay. */
|
||||
dtmf?: string;
|
||||
/** @deprecated use `playDialtone` instead */
|
||||
playRingtone?: boolean;
|
||||
/** If `true`, the SIP Participant plays a dial tone to the room until the phone is picked up. */
|
||||
playDialtone?: boolean;
|
||||
/** These headers are sent as-is and may help identify this call as coming from LiveKit for the other SIP endpoint. */
|
||||
headers?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
/** Map SIP response headers from INVITE to sip.h.* participant attributes automatically. */
|
||||
includeHeaders?: SIPHeaderOptions;
|
||||
hidePhoneNumber?: boolean;
|
||||
/** Maximum time for the call to ring in seconds. */
|
||||
ringingTimeout?: number;
|
||||
/** Maximum call duration in seconds. */
|
||||
maxCallDuration?: number;
|
||||
/** If `true`, Krisp noise cancellation will be enabled for the caller. */
|
||||
krispEnabled?: boolean;
|
||||
/** If `true`, this will wait until the call is answered before returning. */
|
||||
waitUntilAnswered?: boolean;
|
||||
/** Optional request timeout in seconds. Defaults to 30s when waitUntilAnswered is true (dialing takes time), otherwise the client default. */
|
||||
timeout?: number;
|
||||
media?: SIPMediaConfig;
|
||||
}
|
||||
interface ListSipDispatchRuleOptions {
|
||||
/** Pagination options. */
|
||||
page?: Pagination;
|
||||
/** Rule IDs to list. If this option is set, the response will contains rules in the same order. If any of the rules is missing, a nil item in that position will be sent in the response. */
|
||||
dispatchRuleIds?: string[];
|
||||
/** Only list rules that contain one of the Trunk IDs, including wildcard rules. */
|
||||
trunkIds?: string[];
|
||||
}
|
||||
interface ListSipTrunkOptions {
|
||||
/** Pagination options. */
|
||||
page?: Pagination;
|
||||
/** Trunk IDs to list. If this option is set, the response will contains trunks in the same order. If any of the trunks is missing, a nil item in that position will be sent in the response. */
|
||||
trunkIds?: string[];
|
||||
/** Only list trunks that contain one of the numbers, including wildcard trunks. */
|
||||
numbers?: string[];
|
||||
}
|
||||
interface SipDispatchRuleUpdateOptions {
|
||||
trunkIds?: ListUpdate;
|
||||
rule?: SIPDispatchRule;
|
||||
name?: string;
|
||||
metadata?: string;
|
||||
attributes?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
}
|
||||
interface SipInboundTrunkUpdateOptions {
|
||||
numbers?: ListUpdate;
|
||||
allowedAddresses?: ListUpdate;
|
||||
allowedNumbers?: ListUpdate;
|
||||
authUsername?: string;
|
||||
authPassword?: string;
|
||||
name?: string;
|
||||
metadata?: string;
|
||||
/** @deprecated - use `media.encryption` instead */
|
||||
mediaEncryption?: SIPMediaEncryption;
|
||||
media?: SIPMediaConfig;
|
||||
}
|
||||
interface SipOutboundTrunkUpdateOptions {
|
||||
numbers?: ListUpdate;
|
||||
allowedAddresses?: ListUpdate;
|
||||
allowedNumbers?: ListUpdate;
|
||||
authUsername?: string;
|
||||
authPassword?: string;
|
||||
destinationCountry?: string;
|
||||
name?: string;
|
||||
metadata?: string;
|
||||
/** @deprecated - use `media.encryption` instead */
|
||||
mediaEncryption?: SIPMediaEncryption;
|
||||
media?: SIPMediaConfig;
|
||||
}
|
||||
interface TransferSipParticipantOptions {
|
||||
playDialtone?: boolean;
|
||||
headers?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
/** Maximum time for the transfer destination to answer the call, in seconds. */
|
||||
ringingTimeout?: number;
|
||||
/** Optional request timeout in seconds. Defaults to 30s (dialing takes time). */
|
||||
timeout?: number;
|
||||
}
|
||||
/**
|
||||
* Client to access Egress APIs
|
||||
*/
|
||||
declare class SipClient extends ServiceBase {
|
||||
private readonly rpc;
|
||||
/**
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host: string, apiKey?: string, secret?: string, options?: ClientOptions);
|
||||
/**
|
||||
* @param number - phone number of the trunk
|
||||
* @param opts - CreateSipTrunkOptions
|
||||
* @deprecated use `createSipInboundTrunk` or `createSipOutboundTrunk`
|
||||
*/
|
||||
createSipTrunk(number: string, opts?: CreateSipTrunkOptions): Promise<SIPTrunkInfo>;
|
||||
/**
|
||||
* Create a new SIP inbound trunk.
|
||||
*
|
||||
* @param name - human-readable name of the trunk
|
||||
* @param numbers - phone numbers of the trunk
|
||||
* @param opts - CreateSipTrunkOptions
|
||||
* @returns Created SIP inbound trunk
|
||||
*/
|
||||
createSipInboundTrunk(name: string, numbers: string[], opts?: CreateSipInboundTrunkOptions): Promise<SIPInboundTrunkInfo>;
|
||||
/**
|
||||
* Create a new SIP outbound trunk.
|
||||
*
|
||||
* @param name - human-readable name of the trunk
|
||||
* @param address - hostname and port of the SIP server to dial
|
||||
* @param numbers - phone numbers of the trunk
|
||||
* @param opts - CreateSipTrunkOptions
|
||||
* @returns Created SIP outbound trunk
|
||||
*/
|
||||
createSipOutboundTrunk(name: string, address: string, numbers: string[], opts?: CreateSipOutboundTrunkOptions): Promise<SIPOutboundTrunkInfo>;
|
||||
/**
|
||||
* @deprecated use `listSipInboundTrunk` or `listSipOutboundTrunk`
|
||||
*/
|
||||
listSipTrunk(): Promise<Array<SIPTrunkInfo>>;
|
||||
/**
|
||||
* List SIP inbound trunks with optional filtering.
|
||||
*
|
||||
* @param list - Request with optional filtering parameters
|
||||
* @returns Response containing list of SIP inbound trunks
|
||||
*/
|
||||
listSipInboundTrunk(list?: ListSipTrunkOptions): Promise<Array<SIPInboundTrunkInfo>>;
|
||||
/**
|
||||
* List SIP outbound trunks with optional filtering.
|
||||
*
|
||||
* @param list - Request with optional filtering parameters
|
||||
* @returns Response containing list of SIP outbound trunks
|
||||
*/
|
||||
listSipOutboundTrunk(list?: ListSipTrunkOptions): Promise<Array<SIPOutboundTrunkInfo>>;
|
||||
/**
|
||||
* Delete a SIP trunk.
|
||||
*
|
||||
* @param sipTrunkId - ID of the SIP trunk to delete
|
||||
* @returns Deleted trunk information
|
||||
*/
|
||||
deleteSipTrunk(sipTrunkId: string): Promise<SIPTrunkInfo>;
|
||||
/**
|
||||
* Create a new SIP dispatch rule.
|
||||
*
|
||||
* @param rule - SIP dispatch rule to create
|
||||
* @param opts - CreateSipDispatchRuleOptions
|
||||
* @returns Created SIP dispatch rule
|
||||
*/
|
||||
createSipDispatchRule(rule: SipDispatchRuleDirect | SipDispatchRuleIndividual | SipDispatchRuleCallee, opts?: CreateSipDispatchRuleOptions): Promise<SIPDispatchRuleInfo>;
|
||||
/**
|
||||
* Updates an existing SIP dispatch rule by replacing it entirely.
|
||||
*
|
||||
* @param sipDispatchRuleId - ID of the SIP dispatch rule to update
|
||||
* @param rule - new SIP dispatch rule
|
||||
* @returns Updated SIP dispatch rule
|
||||
*/
|
||||
updateSipDispatchRule(sipDispatchRuleId: string, rule: SIPDispatchRuleInfo): Promise<SIPDispatchRuleInfo>;
|
||||
/**
|
||||
* Updates specific fields of an existing SIP dispatch rule.
|
||||
* Only provided fields will be updated.
|
||||
*
|
||||
* @param sipDispatchRuleId - ID of the SIP dispatch rule to update
|
||||
* @param fields - Fields of the dispatch rule to update
|
||||
* @returns Updated SIP dispatch rule
|
||||
*/
|
||||
updateSipDispatchRuleFields(sipDispatchRuleId: string, fields?: SipDispatchRuleUpdateOptions): Promise<SIPDispatchRuleInfo>;
|
||||
/**
|
||||
* Updates an existing SIP inbound trunk by replacing it entirely.
|
||||
*
|
||||
* @param sipTrunkId - ID of the SIP inbound trunk to update
|
||||
* @param trunk - SIP inbound trunk to update with
|
||||
* @returns Updated SIP inbound trunk
|
||||
*/
|
||||
updateSipInboundTrunk(sipTrunkId: string, trunk: SIPInboundTrunkInfo): Promise<SIPInboundTrunkInfo>;
|
||||
/**
|
||||
* Updates specific fields of an existing SIP inbound trunk.
|
||||
* Only provided fields will be updated.
|
||||
*
|
||||
* @param sipTrunkId - ID of the SIP inbound trunk to update
|
||||
* @param fields - Fields of the inbound trunk to update
|
||||
* @returns Updated SIP inbound trunk
|
||||
*/
|
||||
updateSipInboundTrunkFields(sipTrunkId: string, fields: SipInboundTrunkUpdateOptions): Promise<SIPInboundTrunkInfo>;
|
||||
/**
|
||||
* Updates an existing SIP outbound trunk by replacing it entirely.
|
||||
*
|
||||
* @param sipTrunkId - ID of the SIP outbound trunk to update
|
||||
* @param trunk - SIP outbound trunk to update with
|
||||
* @returns Updated SIP outbound trunk
|
||||
*/
|
||||
updateSipOutboundTrunk(sipTrunkId: string, trunk: SIPOutboundTrunkInfo): Promise<SIPOutboundTrunkInfo>;
|
||||
/**
|
||||
* Updates specific fields of an existing SIP outbound trunk.
|
||||
* Only provided fields will be updated.
|
||||
*
|
||||
* @param sipTrunkId - ID of the SIP outbound trunk to update
|
||||
* @param fields - Fields of the outbound trunk to update
|
||||
* @returns Updated SIP outbound trunk
|
||||
*/
|
||||
updateSipOutboundTrunkFields(sipTrunkId: string, fields: SipOutboundTrunkUpdateOptions): Promise<SIPOutboundTrunkInfo>;
|
||||
/**
|
||||
* List SIP dispatch rules with optional filtering.
|
||||
*
|
||||
* @param list - Request with optional filtering parameters
|
||||
* @returns Response containing list of SIP dispatch rules
|
||||
*/
|
||||
listSipDispatchRule(list?: ListSipDispatchRuleOptions): Promise<Array<SIPDispatchRuleInfo>>;
|
||||
/**
|
||||
* Delete a SIP dispatch rule.
|
||||
*
|
||||
* @param sipDispatchRuleId - ID of the SIP dispatch rule to delete
|
||||
* @returns Deleted rule information
|
||||
*/
|
||||
deleteSipDispatchRule(sipDispatchRuleId: string): Promise<SIPDispatchRuleInfo>;
|
||||
/**
|
||||
* Create a new SIP participant.
|
||||
*
|
||||
* @param sipTrunkId - sip trunk to use for the call
|
||||
* @param number - number to dial
|
||||
* @param roomName - room to attach the call to
|
||||
* @param opts - CreateSipParticipantOptions
|
||||
* @param outboundTrunkConfig - Optional outbound trunk configuration for sip participant.
|
||||
* @returns Created SIP participant
|
||||
*/
|
||||
createSipParticipant(sipTrunkId: string, number: string, roomName: string, opts?: CreateSipParticipantOptions, outboundTrunkConfig?: SIPOutboundConfig): Promise<SIPParticipantInfo>;
|
||||
/**
|
||||
* Transfer a SIP participant to a different room.
|
||||
*
|
||||
* @param roomName - room the SIP participant to transfer is connectd to
|
||||
* @param participantIdentity - identity of the SIP participant to transfer
|
||||
* @param transferTo - SIP URL to transfer the participant to
|
||||
* @param opts - TransferSipParticipantOptions
|
||||
*/
|
||||
transferSipParticipant(roomName: string, participantIdentity: string, transferTo: string, opts?: TransferSipParticipantOptions): Promise<void>;
|
||||
}
|
||||
|
||||
export { type CreateSipDispatchRuleOptions, type CreateSipInboundTrunkOptions, type CreateSipOutboundTrunkOptions, type CreateSipParticipantOptions, type CreateSipTrunkOptions, type ListSipDispatchRuleOptions, type ListSipTrunkOptions, SipClient, type SipDispatchRuleCallee, type SipDispatchRuleDirect, type SipDispatchRuleIndividual, type SipDispatchRuleUpdateOptions, type SipInboundTrunkUpdateOptions, type SipOutboundTrunkUpdateOptions, type TransferSipParticipantOptions };
|
||||
+356
@@ -0,0 +1,356 @@
|
||||
import { SIPTrunkInfo, SIPHeaderOptions, SIPMediaEncryption, SIPMediaConfig, SIPInboundTrunkInfo, SIPTransport, SIPOutboundTrunkInfo, Pagination, RoomConfiguration, SIPDispatchRuleInfo, ListUpdate, SIPDispatchRule, SIPOutboundConfig, SIPParticipantInfo } from '@livekit/protocol';
|
||||
import { ClientOptions } from './ClientOptions.js';
|
||||
import { ServiceBase } from './ServiceBase.js';
|
||||
import './grants.js';
|
||||
import 'jose';
|
||||
|
||||
/**
|
||||
* @deprecated use CreateSipInboundTrunkOptions or CreateSipOutboundTrunkOptions
|
||||
*/
|
||||
interface CreateSipTrunkOptions {
|
||||
name?: string;
|
||||
metadata?: string;
|
||||
inbound_addresses?: string[];
|
||||
inbound_numbers?: string[];
|
||||
inbound_username?: string;
|
||||
inbound_password?: string;
|
||||
outbound_address?: string;
|
||||
outbound_username?: string;
|
||||
outbound_password?: string;
|
||||
}
|
||||
interface CreateSipInboundTrunkOptions {
|
||||
metadata?: string;
|
||||
/** @deprecated - use `allowedAddresses` instead */
|
||||
allowed_addresses?: string[];
|
||||
allowedAddresses?: string[];
|
||||
/** @deprecated - use `allowedNumbers` instead */
|
||||
allowed_numbers?: string[];
|
||||
allowedNumbers?: string[];
|
||||
/** @deprecated - use `authUsername` instead */
|
||||
auth_username?: string;
|
||||
authUsername?: string;
|
||||
/** @deprecated - use `authPassword` instead */
|
||||
auth_password?: string;
|
||||
authPassword?: string;
|
||||
headers?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
headersToAttributes?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
includeHeaders?: SIPHeaderOptions;
|
||||
krispEnabled?: boolean;
|
||||
/** @deprecated - use `media.encryption` instead */
|
||||
mediaEncryption?: SIPMediaEncryption;
|
||||
media?: SIPMediaConfig;
|
||||
/** Maximum time for a call to ring in seconds. */
|
||||
ringingTimeout?: number;
|
||||
}
|
||||
interface CreateSipOutboundTrunkOptions {
|
||||
metadata?: string;
|
||||
transport: SIPTransport;
|
||||
destinationCountry?: string;
|
||||
/** @deprecated - use `authUsername` instead */
|
||||
auth_username?: string;
|
||||
authUsername?: string;
|
||||
/** @deprecated - use `authPassword` instead */
|
||||
auth_password?: string;
|
||||
authPassword?: string;
|
||||
headers?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
headersToAttributes?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
includeHeaders?: SIPHeaderOptions;
|
||||
/** @deprecated - use `media.encryption` instead */
|
||||
mediaEncryption?: SIPMediaEncryption;
|
||||
media?: SIPMediaConfig;
|
||||
}
|
||||
interface SipDispatchRuleDirect {
|
||||
type: 'direct';
|
||||
roomName: string;
|
||||
pin?: string;
|
||||
}
|
||||
interface SipDispatchRuleIndividual {
|
||||
type: 'individual';
|
||||
roomPrefix: string;
|
||||
pin?: string;
|
||||
}
|
||||
interface SipDispatchRuleCallee {
|
||||
type: 'callee';
|
||||
roomPrefix: string;
|
||||
pin?: string;
|
||||
/** Optionally append a random suffix to the room name. */
|
||||
randomize?: boolean;
|
||||
}
|
||||
interface CreateSipDispatchRuleOptions {
|
||||
name?: string;
|
||||
metadata?: string;
|
||||
trunkIds?: string[];
|
||||
hidePhoneNumber?: boolean;
|
||||
attributes?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
roomPreset?: string;
|
||||
roomConfig?: RoomConfiguration;
|
||||
}
|
||||
interface CreateSipParticipantOptions {
|
||||
/** Optional SIP From number to use. If empty, trunk number is used. */
|
||||
fromNumber?: string;
|
||||
/** Optional identity of the SIP participant */
|
||||
participantIdentity?: string;
|
||||
/** Optional name of the participant */
|
||||
participantName?: string;
|
||||
/** Optional display name for the SIP participant */
|
||||
displayName?: string;
|
||||
/** Optional metadata to attach to the participant */
|
||||
participantMetadata?: string;
|
||||
/** Optional attributes to attach to the participant */
|
||||
participantAttributes?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
/** Optionally send following DTMF digits (extension codes) when making a call.
|
||||
* Character 'w' can be used to add a 0.5 sec delay. */
|
||||
dtmf?: string;
|
||||
/** @deprecated use `playDialtone` instead */
|
||||
playRingtone?: boolean;
|
||||
/** If `true`, the SIP Participant plays a dial tone to the room until the phone is picked up. */
|
||||
playDialtone?: boolean;
|
||||
/** These headers are sent as-is and may help identify this call as coming from LiveKit for the other SIP endpoint. */
|
||||
headers?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
/** Map SIP response headers from INVITE to sip.h.* participant attributes automatically. */
|
||||
includeHeaders?: SIPHeaderOptions;
|
||||
hidePhoneNumber?: boolean;
|
||||
/** Maximum time for the call to ring in seconds. */
|
||||
ringingTimeout?: number;
|
||||
/** Maximum call duration in seconds. */
|
||||
maxCallDuration?: number;
|
||||
/** If `true`, Krisp noise cancellation will be enabled for the caller. */
|
||||
krispEnabled?: boolean;
|
||||
/** If `true`, this will wait until the call is answered before returning. */
|
||||
waitUntilAnswered?: boolean;
|
||||
/** Optional request timeout in seconds. Defaults to 30s when waitUntilAnswered is true (dialing takes time), otherwise the client default. */
|
||||
timeout?: number;
|
||||
media?: SIPMediaConfig;
|
||||
}
|
||||
interface ListSipDispatchRuleOptions {
|
||||
/** Pagination options. */
|
||||
page?: Pagination;
|
||||
/** Rule IDs to list. If this option is set, the response will contains rules in the same order. If any of the rules is missing, a nil item in that position will be sent in the response. */
|
||||
dispatchRuleIds?: string[];
|
||||
/** Only list rules that contain one of the Trunk IDs, including wildcard rules. */
|
||||
trunkIds?: string[];
|
||||
}
|
||||
interface ListSipTrunkOptions {
|
||||
/** Pagination options. */
|
||||
page?: Pagination;
|
||||
/** Trunk IDs to list. If this option is set, the response will contains trunks in the same order. If any of the trunks is missing, a nil item in that position will be sent in the response. */
|
||||
trunkIds?: string[];
|
||||
/** Only list trunks that contain one of the numbers, including wildcard trunks. */
|
||||
numbers?: string[];
|
||||
}
|
||||
interface SipDispatchRuleUpdateOptions {
|
||||
trunkIds?: ListUpdate;
|
||||
rule?: SIPDispatchRule;
|
||||
name?: string;
|
||||
metadata?: string;
|
||||
attributes?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
}
|
||||
interface SipInboundTrunkUpdateOptions {
|
||||
numbers?: ListUpdate;
|
||||
allowedAddresses?: ListUpdate;
|
||||
allowedNumbers?: ListUpdate;
|
||||
authUsername?: string;
|
||||
authPassword?: string;
|
||||
name?: string;
|
||||
metadata?: string;
|
||||
/** @deprecated - use `media.encryption` instead */
|
||||
mediaEncryption?: SIPMediaEncryption;
|
||||
media?: SIPMediaConfig;
|
||||
}
|
||||
interface SipOutboundTrunkUpdateOptions {
|
||||
numbers?: ListUpdate;
|
||||
allowedAddresses?: ListUpdate;
|
||||
allowedNumbers?: ListUpdate;
|
||||
authUsername?: string;
|
||||
authPassword?: string;
|
||||
destinationCountry?: string;
|
||||
name?: string;
|
||||
metadata?: string;
|
||||
/** @deprecated - use `media.encryption` instead */
|
||||
mediaEncryption?: SIPMediaEncryption;
|
||||
media?: SIPMediaConfig;
|
||||
}
|
||||
interface TransferSipParticipantOptions {
|
||||
playDialtone?: boolean;
|
||||
headers?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
/** Maximum time for the transfer destination to answer the call, in seconds. */
|
||||
ringingTimeout?: number;
|
||||
/** Optional request timeout in seconds. Defaults to 30s (dialing takes time). */
|
||||
timeout?: number;
|
||||
}
|
||||
/**
|
||||
* Client to access Egress APIs
|
||||
*/
|
||||
declare class SipClient extends ServiceBase {
|
||||
private readonly rpc;
|
||||
/**
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host: string, apiKey?: string, secret?: string, options?: ClientOptions);
|
||||
/**
|
||||
* @param number - phone number of the trunk
|
||||
* @param opts - CreateSipTrunkOptions
|
||||
* @deprecated use `createSipInboundTrunk` or `createSipOutboundTrunk`
|
||||
*/
|
||||
createSipTrunk(number: string, opts?: CreateSipTrunkOptions): Promise<SIPTrunkInfo>;
|
||||
/**
|
||||
* Create a new SIP inbound trunk.
|
||||
*
|
||||
* @param name - human-readable name of the trunk
|
||||
* @param numbers - phone numbers of the trunk
|
||||
* @param opts - CreateSipTrunkOptions
|
||||
* @returns Created SIP inbound trunk
|
||||
*/
|
||||
createSipInboundTrunk(name: string, numbers: string[], opts?: CreateSipInboundTrunkOptions): Promise<SIPInboundTrunkInfo>;
|
||||
/**
|
||||
* Create a new SIP outbound trunk.
|
||||
*
|
||||
* @param name - human-readable name of the trunk
|
||||
* @param address - hostname and port of the SIP server to dial
|
||||
* @param numbers - phone numbers of the trunk
|
||||
* @param opts - CreateSipTrunkOptions
|
||||
* @returns Created SIP outbound trunk
|
||||
*/
|
||||
createSipOutboundTrunk(name: string, address: string, numbers: string[], opts?: CreateSipOutboundTrunkOptions): Promise<SIPOutboundTrunkInfo>;
|
||||
/**
|
||||
* @deprecated use `listSipInboundTrunk` or `listSipOutboundTrunk`
|
||||
*/
|
||||
listSipTrunk(): Promise<Array<SIPTrunkInfo>>;
|
||||
/**
|
||||
* List SIP inbound trunks with optional filtering.
|
||||
*
|
||||
* @param list - Request with optional filtering parameters
|
||||
* @returns Response containing list of SIP inbound trunks
|
||||
*/
|
||||
listSipInboundTrunk(list?: ListSipTrunkOptions): Promise<Array<SIPInboundTrunkInfo>>;
|
||||
/**
|
||||
* List SIP outbound trunks with optional filtering.
|
||||
*
|
||||
* @param list - Request with optional filtering parameters
|
||||
* @returns Response containing list of SIP outbound trunks
|
||||
*/
|
||||
listSipOutboundTrunk(list?: ListSipTrunkOptions): Promise<Array<SIPOutboundTrunkInfo>>;
|
||||
/**
|
||||
* Delete a SIP trunk.
|
||||
*
|
||||
* @param sipTrunkId - ID of the SIP trunk to delete
|
||||
* @returns Deleted trunk information
|
||||
*/
|
||||
deleteSipTrunk(sipTrunkId: string): Promise<SIPTrunkInfo>;
|
||||
/**
|
||||
* Create a new SIP dispatch rule.
|
||||
*
|
||||
* @param rule - SIP dispatch rule to create
|
||||
* @param opts - CreateSipDispatchRuleOptions
|
||||
* @returns Created SIP dispatch rule
|
||||
*/
|
||||
createSipDispatchRule(rule: SipDispatchRuleDirect | SipDispatchRuleIndividual | SipDispatchRuleCallee, opts?: CreateSipDispatchRuleOptions): Promise<SIPDispatchRuleInfo>;
|
||||
/**
|
||||
* Updates an existing SIP dispatch rule by replacing it entirely.
|
||||
*
|
||||
* @param sipDispatchRuleId - ID of the SIP dispatch rule to update
|
||||
* @param rule - new SIP dispatch rule
|
||||
* @returns Updated SIP dispatch rule
|
||||
*/
|
||||
updateSipDispatchRule(sipDispatchRuleId: string, rule: SIPDispatchRuleInfo): Promise<SIPDispatchRuleInfo>;
|
||||
/**
|
||||
* Updates specific fields of an existing SIP dispatch rule.
|
||||
* Only provided fields will be updated.
|
||||
*
|
||||
* @param sipDispatchRuleId - ID of the SIP dispatch rule to update
|
||||
* @param fields - Fields of the dispatch rule to update
|
||||
* @returns Updated SIP dispatch rule
|
||||
*/
|
||||
updateSipDispatchRuleFields(sipDispatchRuleId: string, fields?: SipDispatchRuleUpdateOptions): Promise<SIPDispatchRuleInfo>;
|
||||
/**
|
||||
* Updates an existing SIP inbound trunk by replacing it entirely.
|
||||
*
|
||||
* @param sipTrunkId - ID of the SIP inbound trunk to update
|
||||
* @param trunk - SIP inbound trunk to update with
|
||||
* @returns Updated SIP inbound trunk
|
||||
*/
|
||||
updateSipInboundTrunk(sipTrunkId: string, trunk: SIPInboundTrunkInfo): Promise<SIPInboundTrunkInfo>;
|
||||
/**
|
||||
* Updates specific fields of an existing SIP inbound trunk.
|
||||
* Only provided fields will be updated.
|
||||
*
|
||||
* @param sipTrunkId - ID of the SIP inbound trunk to update
|
||||
* @param fields - Fields of the inbound trunk to update
|
||||
* @returns Updated SIP inbound trunk
|
||||
*/
|
||||
updateSipInboundTrunkFields(sipTrunkId: string, fields: SipInboundTrunkUpdateOptions): Promise<SIPInboundTrunkInfo>;
|
||||
/**
|
||||
* Updates an existing SIP outbound trunk by replacing it entirely.
|
||||
*
|
||||
* @param sipTrunkId - ID of the SIP outbound trunk to update
|
||||
* @param trunk - SIP outbound trunk to update with
|
||||
* @returns Updated SIP outbound trunk
|
||||
*/
|
||||
updateSipOutboundTrunk(sipTrunkId: string, trunk: SIPOutboundTrunkInfo): Promise<SIPOutboundTrunkInfo>;
|
||||
/**
|
||||
* Updates specific fields of an existing SIP outbound trunk.
|
||||
* Only provided fields will be updated.
|
||||
*
|
||||
* @param sipTrunkId - ID of the SIP outbound trunk to update
|
||||
* @param fields - Fields of the outbound trunk to update
|
||||
* @returns Updated SIP outbound trunk
|
||||
*/
|
||||
updateSipOutboundTrunkFields(sipTrunkId: string, fields: SipOutboundTrunkUpdateOptions): Promise<SIPOutboundTrunkInfo>;
|
||||
/**
|
||||
* List SIP dispatch rules with optional filtering.
|
||||
*
|
||||
* @param list - Request with optional filtering parameters
|
||||
* @returns Response containing list of SIP dispatch rules
|
||||
*/
|
||||
listSipDispatchRule(list?: ListSipDispatchRuleOptions): Promise<Array<SIPDispatchRuleInfo>>;
|
||||
/**
|
||||
* Delete a SIP dispatch rule.
|
||||
*
|
||||
* @param sipDispatchRuleId - ID of the SIP dispatch rule to delete
|
||||
* @returns Deleted rule information
|
||||
*/
|
||||
deleteSipDispatchRule(sipDispatchRuleId: string): Promise<SIPDispatchRuleInfo>;
|
||||
/**
|
||||
* Create a new SIP participant.
|
||||
*
|
||||
* @param sipTrunkId - sip trunk to use for the call
|
||||
* @param number - number to dial
|
||||
* @param roomName - room to attach the call to
|
||||
* @param opts - CreateSipParticipantOptions
|
||||
* @param outboundTrunkConfig - Optional outbound trunk configuration for sip participant.
|
||||
* @returns Created SIP participant
|
||||
*/
|
||||
createSipParticipant(sipTrunkId: string, number: string, roomName: string, opts?: CreateSipParticipantOptions, outboundTrunkConfig?: SIPOutboundConfig): Promise<SIPParticipantInfo>;
|
||||
/**
|
||||
* Transfer a SIP participant to a different room.
|
||||
*
|
||||
* @param roomName - room the SIP participant to transfer is connectd to
|
||||
* @param participantIdentity - identity of the SIP participant to transfer
|
||||
* @param transferTo - SIP URL to transfer the participant to
|
||||
* @param opts - TransferSipParticipantOptions
|
||||
*/
|
||||
transferSipParticipant(roomName: string, participantIdentity: string, transferTo: string, opts?: TransferSipParticipantOptions): Promise<void>;
|
||||
}
|
||||
|
||||
export { type CreateSipDispatchRuleOptions, type CreateSipInboundTrunkOptions, type CreateSipOutboundTrunkOptions, type CreateSipParticipantOptions, type CreateSipTrunkOptions, type ListSipDispatchRuleOptions, type ListSipTrunkOptions, SipClient, type SipDispatchRuleCallee, type SipDispatchRuleDirect, type SipDispatchRuleIndividual, type SipDispatchRuleUpdateOptions, type SipInboundTrunkUpdateOptions, type SipOutboundTrunkUpdateOptions, type TransferSipParticipantOptions };
|
||||
+1
File diff suppressed because one or more lines are too long
+566
@@ -0,0 +1,566 @@
|
||||
import { Duration } from "@bufbuild/protobuf";
|
||||
import {
|
||||
CreateSIPDispatchRuleRequest,
|
||||
CreateSIPInboundTrunkRequest,
|
||||
CreateSIPOutboundTrunkRequest,
|
||||
CreateSIPParticipantRequest,
|
||||
CreateSIPTrunkRequest,
|
||||
DeleteSIPDispatchRuleRequest,
|
||||
DeleteSIPTrunkRequest,
|
||||
ListSIPDispatchRuleRequest,
|
||||
ListSIPDispatchRuleResponse,
|
||||
ListSIPInboundTrunkRequest,
|
||||
ListSIPInboundTrunkResponse,
|
||||
ListSIPOutboundTrunkRequest,
|
||||
ListSIPOutboundTrunkResponse,
|
||||
ListSIPTrunkRequest,
|
||||
ListSIPTrunkResponse,
|
||||
SIPDispatchRule,
|
||||
SIPDispatchRuleCallee,
|
||||
SIPDispatchRuleDirect,
|
||||
SIPDispatchRuleIndividual,
|
||||
SIPDispatchRuleInfo,
|
||||
SIPInboundTrunkInfo,
|
||||
SIPOutboundTrunkInfo,
|
||||
SIPParticipantInfo,
|
||||
SIPTransport,
|
||||
SIPTrunkInfo,
|
||||
TransferSIPParticipantRequest,
|
||||
UpdateSIPDispatchRuleRequest,
|
||||
UpdateSIPInboundTrunkRequest,
|
||||
UpdateSIPOutboundTrunkRequest
|
||||
} from "@livekit/protocol";
|
||||
import { ServiceBase } from "./ServiceBase.js";
|
||||
import { ServerError, SipCallError, TwirpRpc, livekitPackage } from "./TwirpRPC.js";
|
||||
import { DEFAULT_RINGING_TIMEOUT_SECONDS, dialRequestTimeout } from "./dialTimeout.js";
|
||||
function asSipCallError(e) {
|
||||
if (e instanceof ServerError && e.metadata && "sip_status_code" in e.metadata) {
|
||||
return SipCallError.fromServerError(e);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
const svc = "SIP";
|
||||
class SipClient extends ServiceBase {
|
||||
/**
|
||||
* @param host - hostname including protocol. i.e. 'https://<project>.livekit.cloud'
|
||||
* @param apiKey - API Key, can be set in env var LIVEKIT_API_KEY
|
||||
* @param secret - API Secret, can be set in env var LIVEKIT_API_SECRET
|
||||
* @param options - client options
|
||||
*/
|
||||
constructor(host, apiKey, secret, options) {
|
||||
super({ apiKey, secret, token: options == null ? void 0 : options.token });
|
||||
this.rpc = new TwirpRpc(host, livekitPackage, {
|
||||
requestTimeout: options == null ? void 0 : options.requestTimeout,
|
||||
failover: options == null ? void 0 : options.failover
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @param number - phone number of the trunk
|
||||
* @param opts - CreateSipTrunkOptions
|
||||
* @deprecated use `createSipInboundTrunk` or `createSipOutboundTrunk`
|
||||
*/
|
||||
async createSipTrunk(number, opts) {
|
||||
let inboundAddresses;
|
||||
let inboundNumbers;
|
||||
let inboundUsername = "";
|
||||
let inboundPassword = "";
|
||||
let outboundAddress = "";
|
||||
let outboundUsername = "";
|
||||
let outboundPassword = "";
|
||||
let name = "";
|
||||
let metadata = "";
|
||||
if (opts !== void 0) {
|
||||
inboundAddresses = opts.inbound_addresses;
|
||||
inboundNumbers = opts.inbound_numbers;
|
||||
inboundUsername = opts.inbound_username || "";
|
||||
inboundPassword = opts.inbound_password || "";
|
||||
outboundAddress = opts.outbound_address || "";
|
||||
outboundUsername = opts.outbound_username || "";
|
||||
outboundPassword = opts.outbound_password || "";
|
||||
name = opts.name || "";
|
||||
metadata = opts.metadata || "";
|
||||
}
|
||||
const req = new CreateSIPTrunkRequest({
|
||||
name,
|
||||
metadata,
|
||||
inboundAddresses,
|
||||
inboundNumbers,
|
||||
inboundUsername,
|
||||
inboundPassword,
|
||||
outboundNumber: number,
|
||||
outboundAddress,
|
||||
outboundUsername,
|
||||
outboundPassword
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"CreateSIPTrunk",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return SIPTrunkInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Create a new SIP inbound trunk.
|
||||
*
|
||||
* @param name - human-readable name of the trunk
|
||||
* @param numbers - phone numbers of the trunk
|
||||
* @param opts - CreateSipTrunkOptions
|
||||
* @returns Created SIP inbound trunk
|
||||
*/
|
||||
async createSipInboundTrunk(name, numbers, opts) {
|
||||
if (opts === void 0) {
|
||||
opts = {};
|
||||
}
|
||||
const req = new CreateSIPInboundTrunkRequest({
|
||||
trunk: new SIPInboundTrunkInfo({
|
||||
name,
|
||||
numbers,
|
||||
metadata: opts == null ? void 0 : opts.metadata,
|
||||
allowedAddresses: opts.allowedAddresses ?? opts.allowed_addresses,
|
||||
allowedNumbers: opts.allowedNumbers ?? opts.allowed_numbers,
|
||||
authUsername: opts.authUsername ?? opts.auth_username,
|
||||
authPassword: opts.authPassword ?? opts.auth_password,
|
||||
headers: opts.headers,
|
||||
headersToAttributes: opts.headersToAttributes,
|
||||
includeHeaders: opts.includeHeaders,
|
||||
krispEnabled: opts.krispEnabled,
|
||||
mediaEncryption: opts.mediaEncryption,
|
||||
media: opts.media,
|
||||
ringingTimeout: opts.ringingTimeout ? new Duration({ seconds: BigInt(opts.ringingTimeout) }) : void 0
|
||||
})
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"CreateSIPInboundTrunk",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return SIPInboundTrunkInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Create a new SIP outbound trunk.
|
||||
*
|
||||
* @param name - human-readable name of the trunk
|
||||
* @param address - hostname and port of the SIP server to dial
|
||||
* @param numbers - phone numbers of the trunk
|
||||
* @param opts - CreateSipTrunkOptions
|
||||
* @returns Created SIP outbound trunk
|
||||
*/
|
||||
async createSipOutboundTrunk(name, address, numbers, opts) {
|
||||
if (opts === void 0) {
|
||||
opts = {
|
||||
transport: SIPTransport.SIP_TRANSPORT_AUTO
|
||||
};
|
||||
}
|
||||
const req = new CreateSIPOutboundTrunkRequest({
|
||||
trunk: new SIPOutboundTrunkInfo({
|
||||
name,
|
||||
address,
|
||||
numbers,
|
||||
metadata: opts.metadata,
|
||||
transport: opts.transport,
|
||||
authUsername: opts.authUsername ?? opts.auth_username,
|
||||
authPassword: opts.authPassword ?? opts.auth_password,
|
||||
headers: opts.headers,
|
||||
headersToAttributes: opts.headersToAttributes,
|
||||
includeHeaders: opts.includeHeaders,
|
||||
destinationCountry: opts.destinationCountry,
|
||||
mediaEncryption: opts.mediaEncryption,
|
||||
media: opts.media
|
||||
})
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"CreateSIPOutboundTrunk",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return SIPOutboundTrunkInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* @deprecated use `listSipInboundTrunk` or `listSipOutboundTrunk`
|
||||
*/
|
||||
async listSipTrunk() {
|
||||
const req = {};
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ListSIPTrunk",
|
||||
new ListSIPTrunkRequest(req).toJson(),
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return ListSIPTrunkResponse.fromJson(data, { ignoreUnknownFields: true }).items ?? [];
|
||||
}
|
||||
/**
|
||||
* List SIP inbound trunks with optional filtering.
|
||||
*
|
||||
* @param list - Request with optional filtering parameters
|
||||
* @returns Response containing list of SIP inbound trunks
|
||||
*/
|
||||
async listSipInboundTrunk(list = {}) {
|
||||
const req = new ListSIPInboundTrunkRequest(list).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ListSIPInboundTrunk",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return ListSIPInboundTrunkResponse.fromJson(data, { ignoreUnknownFields: true }).items ?? [];
|
||||
}
|
||||
/**
|
||||
* List SIP outbound trunks with optional filtering.
|
||||
*
|
||||
* @param list - Request with optional filtering parameters
|
||||
* @returns Response containing list of SIP outbound trunks
|
||||
*/
|
||||
async listSipOutboundTrunk(list = {}) {
|
||||
const req = new ListSIPOutboundTrunkRequest(list).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ListSIPOutboundTrunk",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return ListSIPOutboundTrunkResponse.fromJson(data, { ignoreUnknownFields: true }).items ?? [];
|
||||
}
|
||||
/**
|
||||
* Delete a SIP trunk.
|
||||
*
|
||||
* @param sipTrunkId - ID of the SIP trunk to delete
|
||||
* @returns Deleted trunk information
|
||||
*/
|
||||
async deleteSipTrunk(sipTrunkId) {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"DeleteSIPTrunk",
|
||||
new DeleteSIPTrunkRequest({ sipTrunkId }).toJson(),
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return SIPTrunkInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Create a new SIP dispatch rule.
|
||||
*
|
||||
* @param rule - SIP dispatch rule to create
|
||||
* @param opts - CreateSipDispatchRuleOptions
|
||||
* @returns Created SIP dispatch rule
|
||||
*/
|
||||
async createSipDispatchRule(rule, opts) {
|
||||
if (opts === void 0) {
|
||||
opts = {};
|
||||
}
|
||||
let ruleProto = void 0;
|
||||
if (rule.type == "direct") {
|
||||
ruleProto = new SIPDispatchRule({
|
||||
rule: {
|
||||
case: "dispatchRuleDirect",
|
||||
value: new SIPDispatchRuleDirect({
|
||||
roomName: rule.roomName,
|
||||
pin: rule.pin || ""
|
||||
})
|
||||
}
|
||||
});
|
||||
} else if (rule.type == "individual") {
|
||||
ruleProto = new SIPDispatchRule({
|
||||
rule: {
|
||||
case: "dispatchRuleIndividual",
|
||||
value: new SIPDispatchRuleIndividual({
|
||||
roomPrefix: rule.roomPrefix,
|
||||
pin: rule.pin || ""
|
||||
})
|
||||
}
|
||||
});
|
||||
} else if (rule.type == "callee") {
|
||||
ruleProto = new SIPDispatchRule({
|
||||
rule: {
|
||||
case: "dispatchRuleCallee",
|
||||
value: new SIPDispatchRuleCallee({
|
||||
roomPrefix: rule.roomPrefix,
|
||||
pin: rule.pin || "",
|
||||
randomize: rule.randomize || false
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
const req = new CreateSIPDispatchRuleRequest({
|
||||
rule: ruleProto,
|
||||
trunkIds: opts.trunkIds,
|
||||
hidePhoneNumber: opts.hidePhoneNumber,
|
||||
name: opts.name,
|
||||
metadata: opts.metadata,
|
||||
attributes: opts.attributes,
|
||||
roomPreset: opts.roomPreset,
|
||||
roomConfig: opts.roomConfig
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"CreateSIPDispatchRule",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return SIPDispatchRuleInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Updates an existing SIP dispatch rule by replacing it entirely.
|
||||
*
|
||||
* @param sipDispatchRuleId - ID of the SIP dispatch rule to update
|
||||
* @param rule - new SIP dispatch rule
|
||||
* @returns Updated SIP dispatch rule
|
||||
*/
|
||||
async updateSipDispatchRule(sipDispatchRuleId, rule) {
|
||||
const req = new UpdateSIPDispatchRuleRequest({
|
||||
sipDispatchRuleId,
|
||||
action: {
|
||||
case: "replace",
|
||||
value: rule
|
||||
}
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateSIPDispatchRule",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return SIPDispatchRuleInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Updates specific fields of an existing SIP dispatch rule.
|
||||
* Only provided fields will be updated.
|
||||
*
|
||||
* @param sipDispatchRuleId - ID of the SIP dispatch rule to update
|
||||
* @param fields - Fields of the dispatch rule to update
|
||||
* @returns Updated SIP dispatch rule
|
||||
*/
|
||||
async updateSipDispatchRuleFields(sipDispatchRuleId, fields = {}) {
|
||||
const req = new UpdateSIPDispatchRuleRequest({
|
||||
sipDispatchRuleId,
|
||||
action: {
|
||||
case: "update",
|
||||
value: fields
|
||||
}
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateSIPDispatchRule",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return SIPDispatchRuleInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Updates an existing SIP inbound trunk by replacing it entirely.
|
||||
*
|
||||
* @param sipTrunkId - ID of the SIP inbound trunk to update
|
||||
* @param trunk - SIP inbound trunk to update with
|
||||
* @returns Updated SIP inbound trunk
|
||||
*/
|
||||
async updateSipInboundTrunk(sipTrunkId, trunk) {
|
||||
const req = new UpdateSIPInboundTrunkRequest({
|
||||
sipTrunkId,
|
||||
action: {
|
||||
case: "replace",
|
||||
value: trunk
|
||||
}
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateSIPInboundTrunk",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return SIPInboundTrunkInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Updates specific fields of an existing SIP inbound trunk.
|
||||
* Only provided fields will be updated.
|
||||
*
|
||||
* @param sipTrunkId - ID of the SIP inbound trunk to update
|
||||
* @param fields - Fields of the inbound trunk to update
|
||||
* @returns Updated SIP inbound trunk
|
||||
*/
|
||||
async updateSipInboundTrunkFields(sipTrunkId, fields) {
|
||||
const req = new UpdateSIPInboundTrunkRequest({
|
||||
sipTrunkId,
|
||||
action: {
|
||||
case: "update",
|
||||
value: fields
|
||||
}
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateSIPInboundTrunk",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return SIPInboundTrunkInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Updates an existing SIP outbound trunk by replacing it entirely.
|
||||
*
|
||||
* @param sipTrunkId - ID of the SIP outbound trunk to update
|
||||
* @param trunk - SIP outbound trunk to update with
|
||||
* @returns Updated SIP outbound trunk
|
||||
*/
|
||||
async updateSipOutboundTrunk(sipTrunkId, trunk) {
|
||||
const req = new UpdateSIPOutboundTrunkRequest({
|
||||
sipTrunkId,
|
||||
action: {
|
||||
case: "replace",
|
||||
value: trunk
|
||||
}
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateSIPOutboundTrunk",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return SIPOutboundTrunkInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Updates specific fields of an existing SIP outbound trunk.
|
||||
* Only provided fields will be updated.
|
||||
*
|
||||
* @param sipTrunkId - ID of the SIP outbound trunk to update
|
||||
* @param fields - Fields of the outbound trunk to update
|
||||
* @returns Updated SIP outbound trunk
|
||||
*/
|
||||
async updateSipOutboundTrunkFields(sipTrunkId, fields) {
|
||||
const req = new UpdateSIPOutboundTrunkRequest({
|
||||
sipTrunkId,
|
||||
action: {
|
||||
case: "update",
|
||||
value: fields
|
||||
}
|
||||
}).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"UpdateSIPOutboundTrunk",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return SIPOutboundTrunkInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* List SIP dispatch rules with optional filtering.
|
||||
*
|
||||
* @param list - Request with optional filtering parameters
|
||||
* @returns Response containing list of SIP dispatch rules
|
||||
*/
|
||||
async listSipDispatchRule(list = {}) {
|
||||
const req = new ListSIPDispatchRuleRequest(list).toJson();
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"ListSIPDispatchRule",
|
||||
req,
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return ListSIPDispatchRuleResponse.fromJson(data, { ignoreUnknownFields: true }).items ?? [];
|
||||
}
|
||||
/**
|
||||
* Delete a SIP dispatch rule.
|
||||
*
|
||||
* @param sipDispatchRuleId - ID of the SIP dispatch rule to delete
|
||||
* @returns Deleted rule information
|
||||
*/
|
||||
async deleteSipDispatchRule(sipDispatchRuleId) {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"DeleteSIPDispatchRule",
|
||||
new DeleteSIPDispatchRuleRequest({ sipDispatchRuleId }).toJson(),
|
||||
await this.authHeader({}, { admin: true })
|
||||
);
|
||||
return SIPDispatchRuleInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
}
|
||||
/**
|
||||
* Create a new SIP participant.
|
||||
*
|
||||
* @param sipTrunkId - sip trunk to use for the call
|
||||
* @param number - number to dial
|
||||
* @param roomName - room to attach the call to
|
||||
* @param opts - CreateSipParticipantOptions
|
||||
* @param outboundTrunkConfig - Optional outbound trunk configuration for sip participant.
|
||||
* @returns Created SIP participant
|
||||
*/
|
||||
async createSipParticipant(sipTrunkId, number, roomName, opts, outboundTrunkConfig) {
|
||||
if (opts === void 0) {
|
||||
opts = {};
|
||||
}
|
||||
if (opts.waitUntilAnswered) {
|
||||
opts.ringingTimeout ??= DEFAULT_RINGING_TIMEOUT_SECONDS;
|
||||
opts.timeout = dialRequestTimeout(opts.timeout, opts.ringingTimeout);
|
||||
}
|
||||
const req = new CreateSIPParticipantRequest({
|
||||
sipTrunkId,
|
||||
trunk: outboundTrunkConfig,
|
||||
sipCallTo: number,
|
||||
sipNumber: opts.fromNumber,
|
||||
roomName,
|
||||
participantIdentity: opts.participantIdentity || "sip-participant",
|
||||
participantName: opts.participantName,
|
||||
displayName: opts.displayName,
|
||||
participantMetadata: opts.participantMetadata,
|
||||
participantAttributes: opts.participantAttributes,
|
||||
dtmf: opts.dtmf,
|
||||
playDialtone: opts.playDialtone ?? opts.playRingtone,
|
||||
headers: opts.headers,
|
||||
hidePhoneNumber: opts.hidePhoneNumber,
|
||||
includeHeaders: opts.includeHeaders,
|
||||
ringingTimeout: opts.ringingTimeout ? new Duration({ seconds: BigInt(opts.ringingTimeout) }) : void 0,
|
||||
maxCallDuration: opts.maxCallDuration ? new Duration({ seconds: BigInt(opts.maxCallDuration) }) : void 0,
|
||||
krispEnabled: opts.krispEnabled,
|
||||
waitUntilAnswered: opts.waitUntilAnswered,
|
||||
media: opts.media
|
||||
}).toJson();
|
||||
try {
|
||||
const data = await this.rpc.request(
|
||||
svc,
|
||||
"CreateSIPParticipant",
|
||||
req,
|
||||
await this.authHeader({}, { call: true }),
|
||||
opts.timeout
|
||||
);
|
||||
return SIPParticipantInfo.fromJson(data, { ignoreUnknownFields: true });
|
||||
} catch (e) {
|
||||
throw asSipCallError(e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Transfer a SIP participant to a different room.
|
||||
*
|
||||
* @param roomName - room the SIP participant to transfer is connectd to
|
||||
* @param participantIdentity - identity of the SIP participant to transfer
|
||||
* @param transferTo - SIP URL to transfer the participant to
|
||||
* @param opts - TransferSipParticipantOptions
|
||||
*/
|
||||
async transferSipParticipant(roomName, participantIdentity, transferTo, opts) {
|
||||
if (opts === void 0) {
|
||||
opts = {};
|
||||
}
|
||||
opts.ringingTimeout ??= DEFAULT_RINGING_TIMEOUT_SECONDS;
|
||||
opts.timeout = dialRequestTimeout(opts.timeout, opts.ringingTimeout);
|
||||
const req = new TransferSIPParticipantRequest({
|
||||
participantIdentity,
|
||||
roomName,
|
||||
transferTo,
|
||||
playDialtone: opts.playDialtone,
|
||||
headers: opts.headers,
|
||||
ringingTimeout: opts.ringingTimeout ? new Duration({ seconds: BigInt(opts.ringingTimeout) }) : void 0
|
||||
}).toJson();
|
||||
try {
|
||||
await this.rpc.request(
|
||||
svc,
|
||||
"TransferSIPParticipant",
|
||||
req,
|
||||
await this.authHeader({ roomAdmin: true, room: roomName }, { call: true }),
|
||||
opts.timeout
|
||||
);
|
||||
} catch (e) {
|
||||
throw asSipCallError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
export {
|
||||
SipClient
|
||||
};
|
||||
//# sourceMappingURL=SipClient.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+196
@@ -0,0 +1,196 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var TwirpRPC_exports = {};
|
||||
__export(TwirpRPC_exports, {
|
||||
ServerError: () => ServerError,
|
||||
SipCallError: () => SipCallError,
|
||||
TwirpError: () => TwirpError,
|
||||
TwirpRpc: () => TwirpRpc,
|
||||
livekitPackage: () => livekitPackage
|
||||
});
|
||||
module.exports = __toCommonJS(TwirpRPC_exports);
|
||||
var import_failover = require("./failover.cjs");
|
||||
var import_version = require("./version.cjs");
|
||||
const USER_AGENT = `livekit-server-sdk-node/${import_version.SDK_VERSION}`;
|
||||
const defaultPrefix = "/twirp";
|
||||
const defaultTimeoutSeconds = 10;
|
||||
const livekitPackage = "livekit";
|
||||
class ServerError extends Error {
|
||||
constructor(name, message, status, code, metadata) {
|
||||
super(message);
|
||||
this.name = name;
|
||||
this.status = status;
|
||||
this.code = code;
|
||||
this.metadata = metadata;
|
||||
}
|
||||
}
|
||||
const TwirpError = ServerError;
|
||||
class SipCallError extends ServerError {
|
||||
constructor(name, message, status, code, metadata) {
|
||||
super(name, SipCallError.describe(message, code, metadata), status, code, metadata);
|
||||
this.name = "SipCallError";
|
||||
}
|
||||
/** The SIP response code of the failed call, e.g. 486 (Busy Here). */
|
||||
get sipStatusCode() {
|
||||
var _a;
|
||||
const raw = (_a = this.metadata) == null ? void 0 : _a.sip_status_code;
|
||||
return raw !== void 0 ? Number(raw) : void 0;
|
||||
}
|
||||
/** The SIP reason phrase of the failed call, e.g. "Busy Here". */
|
||||
get sipStatus() {
|
||||
var _a;
|
||||
return (_a = this.metadata) == null ? void 0 : _a.sip_status;
|
||||
}
|
||||
/** Builds a SipCallError from a ServerError, preserving its code and metadata. */
|
||||
static fromServerError(err) {
|
||||
return new SipCallError(err.name, err.message, err.status, err.code, err.metadata);
|
||||
}
|
||||
// describe renders a clear message: the SIP status, the error code, and any
|
||||
// other metadata the server attached. Falls back to the raw message when the
|
||||
// error carries no SIP status.
|
||||
static describe(fallback, code, metadata) {
|
||||
const sipCode = metadata == null ? void 0 : metadata.sip_status_code;
|
||||
if (!sipCode) {
|
||||
return fallback;
|
||||
}
|
||||
const reason = metadata == null ? void 0 : metadata.sip_status;
|
||||
let msg = `SIP call failed: ${sipCode}${reason ? ` ${reason}` : ""}`;
|
||||
if (code) {
|
||||
msg += ` (${code})`;
|
||||
}
|
||||
const extra = Object.entries(metadata ?? {}).filter(([k]) => k !== "sip_status_code" && k !== "sip_status" && k !== "error_details").map(([k, v]) => `${k}=${v}`);
|
||||
if (extra.length) {
|
||||
msg += ` [${extra.join(", ")}]`;
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
class TwirpRpc {
|
||||
constructor(host, pkg, options) {
|
||||
if (host.startsWith("ws")) {
|
||||
host = host.replace("ws", "http");
|
||||
}
|
||||
this.host = host;
|
||||
this.pkg = pkg;
|
||||
this.requestTimeout = (options == null ? void 0 : options.requestTimeout) ?? defaultTimeoutSeconds;
|
||||
this.prefix = (options == null ? void 0 : options.prefix) || defaultPrefix;
|
||||
this.failover = (options == null ? void 0 : options.failover) ?? true;
|
||||
this.failoverForce = (options == null ? void 0 : options.failoverForce) ?? false;
|
||||
this.failoverBackoffMs = (options == null ? void 0 : options.failoverBackoffMs) ?? import_failover.FAILOVER_BACKOFF_BASE_MS;
|
||||
}
|
||||
/**
|
||||
* Issues a Twirp request, failing over to alternative regions on retryable
|
||||
* errors. On any transport error or HTTP 5xx it discovers regions via
|
||||
* /settings/regions and replays the request — body and headers intact —
|
||||
* against the next untried region, with exponential backoff. A 4xx is
|
||||
* returned immediately.
|
||||
*/
|
||||
async request(service, method, data, headers, timeout = this.requestTimeout) {
|
||||
const path = `${this.prefix}/${this.pkg}.${service}/${method}`;
|
||||
const body = JSON.stringify(data);
|
||||
const requestHeaders = {
|
||||
"Content-Type": "application/json;charset=UTF-8",
|
||||
"User-Agent": USER_AGENT,
|
||||
...headers
|
||||
};
|
||||
const origin = new URL(this.host);
|
||||
const maxAttempts = (0, import_failover.failoverAttempts)(
|
||||
this.failover,
|
||||
origin.hostname,
|
||||
this.failoverForce,
|
||||
timeout
|
||||
);
|
||||
const attempted = /* @__PURE__ */ new Set([(0, import_failover.hostKey)(origin)]);
|
||||
let regions;
|
||||
let current = this.host;
|
||||
for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
|
||||
const isLast = attempt + 1 >= maxAttempts;
|
||||
const init = { method: "POST", headers: requestHeaders, body };
|
||||
if (timeout) {
|
||||
init.signal = AbortSignal.timeout(timeout * 1e3);
|
||||
}
|
||||
let response;
|
||||
let transportError;
|
||||
try {
|
||||
response = await fetch(new URL(path, current), init);
|
||||
} catch (e) {
|
||||
transportError = e;
|
||||
}
|
||||
if (response == null ? void 0 : response.ok) {
|
||||
return await response.json();
|
||||
}
|
||||
const retryable = transportError !== void 0 || !!response && response.status >= 500;
|
||||
let next;
|
||||
if (retryable && !isLast) {
|
||||
if (!regions) {
|
||||
regions = await (0, import_failover.regionOrigins)(origin, headers);
|
||||
}
|
||||
next = (0, import_failover.pickNext)(regions, attempted);
|
||||
}
|
||||
if (!retryable || next === void 0) {
|
||||
if (response) {
|
||||
throw await toTwirpError(response);
|
||||
}
|
||||
throw transportError;
|
||||
}
|
||||
const reason = response ? `status ${response.status}` : transportError;
|
||||
console.warn(
|
||||
`livekit API request to ${new URL(current).host} failed (${reason}), retrying with fallback url ${next}`
|
||||
);
|
||||
await (0, import_failover.sleep)(this.failoverBackoffMs * 2 ** attempt);
|
||||
attempted.add((0, import_failover.hostKey)(new URL(next)));
|
||||
current = next;
|
||||
}
|
||||
throw new Error("failover loop exited without returning");
|
||||
}
|
||||
}
|
||||
async function toTwirpError(response) {
|
||||
const isJson = response.headers.get("content-type") === "application/json";
|
||||
let errorMessage = "Unknown internal error";
|
||||
let errorCode = void 0;
|
||||
let metadata = void 0;
|
||||
try {
|
||||
if (isJson) {
|
||||
const parsedError = await response.json();
|
||||
if ("msg" in parsedError) {
|
||||
errorMessage = parsedError.msg;
|
||||
}
|
||||
if ("code" in parsedError) {
|
||||
errorCode = parsedError.code;
|
||||
}
|
||||
if ("meta" in parsedError) {
|
||||
metadata = parsedError.meta;
|
||||
}
|
||||
} else {
|
||||
errorMessage = await response.text();
|
||||
}
|
||||
} catch (e) {
|
||||
console.debug(`Error when trying to parse error message, using defaults`, e);
|
||||
}
|
||||
return new TwirpError(response.statusText, errorMessage, response.status, errorCode, metadata);
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
ServerError,
|
||||
SipCallError,
|
||||
TwirpError,
|
||||
TwirpRpc,
|
||||
livekitPackage
|
||||
});
|
||||
//# sourceMappingURL=TwirpRPC.cjs.map
|
||||
+1
File diff suppressed because one or more lines are too long
+70
@@ -0,0 +1,70 @@
|
||||
import { JsonValue } from '@bufbuild/protobuf';
|
||||
|
||||
type Options = {
|
||||
/** Prefix for the RPC requests */
|
||||
prefix?: string;
|
||||
/** Timeout for fetch requests, in seconds. Must be within the valid range for abort signal timeouts. */
|
||||
requestTimeout?: number;
|
||||
/** Whether region failover is enabled (LiveKit Cloud hosts only). Defaults to true. */
|
||||
failover?: boolean;
|
||||
/** @internal test-only: force failover regardless of host. */
|
||||
failoverForce?: boolean;
|
||||
/** @internal test-only: base retry backoff in ms. */
|
||||
failoverBackoffMs?: number;
|
||||
};
|
||||
declare const livekitPackage = "livekit";
|
||||
interface Rpc {
|
||||
request(service: string, method: string, data: JsonValue, headers: any, // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
timeout?: number): Promise<string>;
|
||||
}
|
||||
declare class ServerError extends Error {
|
||||
status: number;
|
||||
code?: string;
|
||||
metadata?: Record<string, string>;
|
||||
constructor(name: string, message: string, status: number, code?: string, metadata?: Record<string, string>);
|
||||
}
|
||||
/** @deprecated use {@link ServerError} */
|
||||
declare const TwirpError: typeof ServerError;
|
||||
/** @deprecated use {@link ServerError} */
|
||||
type TwirpError = ServerError;
|
||||
/**
|
||||
* A {@link ServerError} from a SIP dialing call (`createSipParticipant` /
|
||||
* `transferSipParticipant`) that failed with a SIP response status. The SIP code
|
||||
* and reason are exposed as getters; any other error metadata remains available
|
||||
* via {@link ServerError.metadata}.
|
||||
*/
|
||||
declare class SipCallError extends ServerError {
|
||||
constructor(name: string, message: string, status: number, code?: string, metadata?: Record<string, string>);
|
||||
/** The SIP response code of the failed call, e.g. 486 (Busy Here). */
|
||||
get sipStatusCode(): number | undefined;
|
||||
/** The SIP reason phrase of the failed call, e.g. "Busy Here". */
|
||||
get sipStatus(): string | undefined;
|
||||
/** Builds a SipCallError from a ServerError, preserving its code and metadata. */
|
||||
static fromServerError(err: ServerError): SipCallError;
|
||||
private static describe;
|
||||
}
|
||||
/**
|
||||
* JSON based Twirp V7 RPC
|
||||
*/
|
||||
declare class TwirpRpc {
|
||||
host: string;
|
||||
pkg: string;
|
||||
prefix: string;
|
||||
requestTimeout: number;
|
||||
failover: boolean;
|
||||
private failoverForce;
|
||||
private failoverBackoffMs;
|
||||
constructor(host: string, pkg: string, options?: Options);
|
||||
/**
|
||||
* Issues a Twirp request, failing over to alternative regions on retryable
|
||||
* errors. On any transport error or HTTP 5xx it discovers regions via
|
||||
* /settings/regions and replays the request — body and headers intact —
|
||||
* against the next untried region, with exponential backoff. A 4xx is
|
||||
* returned immediately.
|
||||
*/
|
||||
request(service: string, method: string, data: any, // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
headers: any, // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
timeout?: number): Promise<any>;
|
||||
}
|
||||
|
||||
export { type Rpc, ServerError, SipCallError, TwirpError, TwirpRpc, livekitPackage };
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
import { JsonValue } from '@bufbuild/protobuf';
|
||||
|
||||
type Options = {
|
||||
/** Prefix for the RPC requests */
|
||||
prefix?: string;
|
||||
/** Timeout for fetch requests, in seconds. Must be within the valid range for abort signal timeouts. */
|
||||
requestTimeout?: number;
|
||||
/** Whether region failover is enabled (LiveKit Cloud hosts only). Defaults to true. */
|
||||
failover?: boolean;
|
||||
/** @internal test-only: force failover regardless of host. */
|
||||
failoverForce?: boolean;
|
||||
/** @internal test-only: base retry backoff in ms. */
|
||||
failoverBackoffMs?: number;
|
||||
};
|
||||
declare const livekitPackage = "livekit";
|
||||
interface Rpc {
|
||||
request(service: string, method: string, data: JsonValue, headers: any, // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
timeout?: number): Promise<string>;
|
||||
}
|
||||
declare class ServerError extends Error {
|
||||
status: number;
|
||||
code?: string;
|
||||
metadata?: Record<string, string>;
|
||||
constructor(name: string, message: string, status: number, code?: string, metadata?: Record<string, string>);
|
||||
}
|
||||
/** @deprecated use {@link ServerError} */
|
||||
declare const TwirpError: typeof ServerError;
|
||||
/** @deprecated use {@link ServerError} */
|
||||
type TwirpError = ServerError;
|
||||
/**
|
||||
* A {@link ServerError} from a SIP dialing call (`createSipParticipant` /
|
||||
* `transferSipParticipant`) that failed with a SIP response status. The SIP code
|
||||
* and reason are exposed as getters; any other error metadata remains available
|
||||
* via {@link ServerError.metadata}.
|
||||
*/
|
||||
declare class SipCallError extends ServerError {
|
||||
constructor(name: string, message: string, status: number, code?: string, metadata?: Record<string, string>);
|
||||
/** The SIP response code of the failed call, e.g. 486 (Busy Here). */
|
||||
get sipStatusCode(): number | undefined;
|
||||
/** The SIP reason phrase of the failed call, e.g. "Busy Here". */
|
||||
get sipStatus(): string | undefined;
|
||||
/** Builds a SipCallError from a ServerError, preserving its code and metadata. */
|
||||
static fromServerError(err: ServerError): SipCallError;
|
||||
private static describe;
|
||||
}
|
||||
/**
|
||||
* JSON based Twirp V7 RPC
|
||||
*/
|
||||
declare class TwirpRpc {
|
||||
host: string;
|
||||
pkg: string;
|
||||
prefix: string;
|
||||
requestTimeout: number;
|
||||
failover: boolean;
|
||||
private failoverForce;
|
||||
private failoverBackoffMs;
|
||||
constructor(host: string, pkg: string, options?: Options);
|
||||
/**
|
||||
* Issues a Twirp request, failing over to alternative regions on retryable
|
||||
* errors. On any transport error or HTTP 5xx it discovers regions via
|
||||
* /settings/regions and replays the request — body and headers intact —
|
||||
* against the next untried region, with exponential backoff. A 4xx is
|
||||
* returned immediately.
|
||||
*/
|
||||
request(service: string, method: string, data: any, // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
headers: any, // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
timeout?: number): Promise<any>;
|
||||
}
|
||||
|
||||
export { type Rpc, ServerError, SipCallError, TwirpError, TwirpRpc, livekitPackage };
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"TwirpRPC.d.ts","sourceRoot":"","sources":["../src/TwirpRPC.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAiBpD,KAAK,OAAO,GAAG;IACb,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wGAAwG;IACxG,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uFAAuF;IACvF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qDAAqD;IACrD,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAKF,eAAO,MAAM,cAAc,YAAY,CAAC;AACxC,MAAM,WAAW,GAAG;IAClB,OAAO,CACL,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,GAAG,EAAE,yDAAyD;IACvE,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAAC;CACpB;AAED,qBAAa,WAAY,SAAQ,KAAK;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAGhC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;CAQpC;AAED,0CAA0C;AAC1C,eAAO,MAAM,UAAU,oBAAc,CAAC;AACtC,0CAA0C;AAC1C,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC;AAErC;;;;;GAKG;AACH,qBAAa,YAAa,SAAQ,WAAW;gBAEzC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAMnC,sEAAsE;IACtE,IAAI,aAAa,IAAI,MAAM,GAAG,SAAS,CAGtC;IAED,kEAAkE;IAClE,IAAI,SAAS,IAAI,MAAM,GAAG,SAAS,CAElC;IAED,kFAAkF;IAClF,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,WAAW,GAAG,YAAY;IAOtD,OAAO,CAAC,MAAM,CAAC,QAAQ;CAkBxB;AAED;;GAEG;AACH,qBAAa,QAAQ;IACnB,IAAI,EAAE,MAAM,CAAC;IAEb,GAAG,EAAE,MAAM,CAAC;IAEZ,MAAM,EAAE,MAAM,CAAC;IAEf,cAAc,EAAE,MAAM,CAAC;IAEvB,QAAQ,EAAE,OAAO,CAAC;IAElB,OAAO,CAAC,aAAa,CAAU;IAE/B,OAAO,CAAC,iBAAiB,CAAS;gBAEtB,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO;IAaxD;;;;;;OAMG;IACG,OAAO,CACX,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,GAAG,EAAE,yDAAyD;IACpE,OAAO,EAAE,GAAG,EAAE,yDAAyD;IACvE,OAAO,SAAsB,GAE5B,OAAO,CAAC,GAAG,CAAC;CAyEhB"}
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
import {
|
||||
FAILOVER_BACKOFF_BASE_MS,
|
||||
failoverAttempts,
|
||||
hostKey,
|
||||
pickNext,
|
||||
regionOrigins,
|
||||
sleep
|
||||
} from "./failover.js";
|
||||
import { SDK_VERSION } from "./version.js";
|
||||
const USER_AGENT = `livekit-server-sdk-node/${SDK_VERSION}`;
|
||||
const defaultPrefix = "/twirp";
|
||||
const defaultTimeoutSeconds = 10;
|
||||
const livekitPackage = "livekit";
|
||||
class ServerError extends Error {
|
||||
constructor(name, message, status, code, metadata) {
|
||||
super(message);
|
||||
this.name = name;
|
||||
this.status = status;
|
||||
this.code = code;
|
||||
this.metadata = metadata;
|
||||
}
|
||||
}
|
||||
const TwirpError = ServerError;
|
||||
class SipCallError extends ServerError {
|
||||
constructor(name, message, status, code, metadata) {
|
||||
super(name, SipCallError.describe(message, code, metadata), status, code, metadata);
|
||||
this.name = "SipCallError";
|
||||
}
|
||||
/** The SIP response code of the failed call, e.g. 486 (Busy Here). */
|
||||
get sipStatusCode() {
|
||||
var _a;
|
||||
const raw = (_a = this.metadata) == null ? void 0 : _a.sip_status_code;
|
||||
return raw !== void 0 ? Number(raw) : void 0;
|
||||
}
|
||||
/** The SIP reason phrase of the failed call, e.g. "Busy Here". */
|
||||
get sipStatus() {
|
||||
var _a;
|
||||
return (_a = this.metadata) == null ? void 0 : _a.sip_status;
|
||||
}
|
||||
/** Builds a SipCallError from a ServerError, preserving its code and metadata. */
|
||||
static fromServerError(err) {
|
||||
return new SipCallError(err.name, err.message, err.status, err.code, err.metadata);
|
||||
}
|
||||
// describe renders a clear message: the SIP status, the error code, and any
|
||||
// other metadata the server attached. Falls back to the raw message when the
|
||||
// error carries no SIP status.
|
||||
static describe(fallback, code, metadata) {
|
||||
const sipCode = metadata == null ? void 0 : metadata.sip_status_code;
|
||||
if (!sipCode) {
|
||||
return fallback;
|
||||
}
|
||||
const reason = metadata == null ? void 0 : metadata.sip_status;
|
||||
let msg = `SIP call failed: ${sipCode}${reason ? ` ${reason}` : ""}`;
|
||||
if (code) {
|
||||
msg += ` (${code})`;
|
||||
}
|
||||
const extra = Object.entries(metadata ?? {}).filter(([k]) => k !== "sip_status_code" && k !== "sip_status" && k !== "error_details").map(([k, v]) => `${k}=${v}`);
|
||||
if (extra.length) {
|
||||
msg += ` [${extra.join(", ")}]`;
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
class TwirpRpc {
|
||||
constructor(host, pkg, options) {
|
||||
if (host.startsWith("ws")) {
|
||||
host = host.replace("ws", "http");
|
||||
}
|
||||
this.host = host;
|
||||
this.pkg = pkg;
|
||||
this.requestTimeout = (options == null ? void 0 : options.requestTimeout) ?? defaultTimeoutSeconds;
|
||||
this.prefix = (options == null ? void 0 : options.prefix) || defaultPrefix;
|
||||
this.failover = (options == null ? void 0 : options.failover) ?? true;
|
||||
this.failoverForce = (options == null ? void 0 : options.failoverForce) ?? false;
|
||||
this.failoverBackoffMs = (options == null ? void 0 : options.failoverBackoffMs) ?? FAILOVER_BACKOFF_BASE_MS;
|
||||
}
|
||||
/**
|
||||
* Issues a Twirp request, failing over to alternative regions on retryable
|
||||
* errors. On any transport error or HTTP 5xx it discovers regions via
|
||||
* /settings/regions and replays the request — body and headers intact —
|
||||
* against the next untried region, with exponential backoff. A 4xx is
|
||||
* returned immediately.
|
||||
*/
|
||||
async request(service, method, data, headers, timeout = this.requestTimeout) {
|
||||
const path = `${this.prefix}/${this.pkg}.${service}/${method}`;
|
||||
const body = JSON.stringify(data);
|
||||
const requestHeaders = {
|
||||
"Content-Type": "application/json;charset=UTF-8",
|
||||
"User-Agent": USER_AGENT,
|
||||
...headers
|
||||
};
|
||||
const origin = new URL(this.host);
|
||||
const maxAttempts = failoverAttempts(
|
||||
this.failover,
|
||||
origin.hostname,
|
||||
this.failoverForce,
|
||||
timeout
|
||||
);
|
||||
const attempted = /* @__PURE__ */ new Set([hostKey(origin)]);
|
||||
let regions;
|
||||
let current = this.host;
|
||||
for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
|
||||
const isLast = attempt + 1 >= maxAttempts;
|
||||
const init = { method: "POST", headers: requestHeaders, body };
|
||||
if (timeout) {
|
||||
init.signal = AbortSignal.timeout(timeout * 1e3);
|
||||
}
|
||||
let response;
|
||||
let transportError;
|
||||
try {
|
||||
response = await fetch(new URL(path, current), init);
|
||||
} catch (e) {
|
||||
transportError = e;
|
||||
}
|
||||
if (response == null ? void 0 : response.ok) {
|
||||
return await response.json();
|
||||
}
|
||||
const retryable = transportError !== void 0 || !!response && response.status >= 500;
|
||||
let next;
|
||||
if (retryable && !isLast) {
|
||||
if (!regions) {
|
||||
regions = await regionOrigins(origin, headers);
|
||||
}
|
||||
next = pickNext(regions, attempted);
|
||||
}
|
||||
if (!retryable || next === void 0) {
|
||||
if (response) {
|
||||
throw await toTwirpError(response);
|
||||
}
|
||||
throw transportError;
|
||||
}
|
||||
const reason = response ? `status ${response.status}` : transportError;
|
||||
console.warn(
|
||||
`livekit API request to ${new URL(current).host} failed (${reason}), retrying with fallback url ${next}`
|
||||
);
|
||||
await sleep(this.failoverBackoffMs * 2 ** attempt);
|
||||
attempted.add(hostKey(new URL(next)));
|
||||
current = next;
|
||||
}
|
||||
throw new Error("failover loop exited without returning");
|
||||
}
|
||||
}
|
||||
async function toTwirpError(response) {
|
||||
const isJson = response.headers.get("content-type") === "application/json";
|
||||
let errorMessage = "Unknown internal error";
|
||||
let errorCode = void 0;
|
||||
let metadata = void 0;
|
||||
try {
|
||||
if (isJson) {
|
||||
const parsedError = await response.json();
|
||||
if ("msg" in parsedError) {
|
||||
errorMessage = parsedError.msg;
|
||||
}
|
||||
if ("code" in parsedError) {
|
||||
errorCode = parsedError.code;
|
||||
}
|
||||
if ("meta" in parsedError) {
|
||||
metadata = parsedError.meta;
|
||||
}
|
||||
} else {
|
||||
errorMessage = await response.text();
|
||||
}
|
||||
} catch (e) {
|
||||
console.debug(`Error when trying to parse error message, using defaults`, e);
|
||||
}
|
||||
return new TwirpError(response.statusText, errorMessage, response.status, errorCode, metadata);
|
||||
}
|
||||
export {
|
||||
ServerError,
|
||||
SipCallError,
|
||||
TwirpError,
|
||||
TwirpRpc,
|
||||
livekitPackage
|
||||
};
|
||||
//# sourceMappingURL=TwirpRPC.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+79
@@ -0,0 +1,79 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var WebhookReceiver_exports = {};
|
||||
__export(WebhookReceiver_exports, {
|
||||
WebhookEvent: () => WebhookEvent,
|
||||
WebhookReceiver: () => WebhookReceiver,
|
||||
authorizeHeader: () => authorizeHeader
|
||||
});
|
||||
module.exports = __toCommonJS(WebhookReceiver_exports);
|
||||
var import_protocol = require("@livekit/protocol");
|
||||
var import_AccessToken = require("./AccessToken.cjs");
|
||||
var import_digest = require("./crypto/digest.cjs");
|
||||
const authorizeHeader = "Authorize";
|
||||
class WebhookEvent extends import_protocol.WebhookEvent {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.event = "";
|
||||
}
|
||||
static fromBinary(bytes, options) {
|
||||
return new WebhookEvent().fromBinary(bytes, options);
|
||||
}
|
||||
static fromJson(jsonValue, options) {
|
||||
return new WebhookEvent().fromJson(jsonValue, options);
|
||||
}
|
||||
static fromJsonString(jsonString, options) {
|
||||
return new WebhookEvent().fromJsonString(jsonString, options);
|
||||
}
|
||||
}
|
||||
class WebhookReceiver {
|
||||
constructor(apiKey, apiSecret) {
|
||||
this.verifier = new import_AccessToken.TokenVerifier(apiKey, apiSecret);
|
||||
}
|
||||
/**
|
||||
* @param body - string of the posted body
|
||||
* @param authHeader - `Authorization` header from the request
|
||||
* @param skipAuth - true to skip auth validation
|
||||
* @param clockTolerance - How much tolerance to allow for checks against the auth header to be skewed from the claims
|
||||
* @returns The processed webhook event
|
||||
*/
|
||||
async receive(body, authHeader, skipAuth = false, clockTolerance) {
|
||||
if (!skipAuth) {
|
||||
if (!authHeader) {
|
||||
throw new Error("authorization header is empty");
|
||||
}
|
||||
const claims = await this.verifier.verify(authHeader, clockTolerance);
|
||||
const hash = await (0, import_digest.digest)(body);
|
||||
const hashDecoded = btoa(
|
||||
Array.from(new Uint8Array(hash)).map((v) => String.fromCharCode(v)).join("")
|
||||
);
|
||||
if (claims.sha256 !== hashDecoded) {
|
||||
throw new Error("sha256 checksum of body does not match");
|
||||
}
|
||||
}
|
||||
return WebhookEvent.fromJson(JSON.parse(body), { ignoreUnknownFields: true });
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
WebhookEvent,
|
||||
WebhookReceiver,
|
||||
authorizeHeader
|
||||
});
|
||||
//# sourceMappingURL=WebhookReceiver.cjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../src/WebhookReceiver.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { BinaryReadOptions, JsonReadOptions, JsonValue } from '@bufbuild/protobuf';\nimport { WebhookEvent as ProtoWebhookEvent } from '@livekit/protocol';\nimport { TokenVerifier } from './AccessToken.js';\nimport { digest } from './crypto/digest.js';\n\nexport const authorizeHeader = 'Authorize';\n\nexport class WebhookEvent extends ProtoWebhookEvent {\n event: WebhookEventNames = '';\n\n static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): WebhookEvent {\n return new WebhookEvent().fromBinary(bytes, options);\n }\n\n static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): WebhookEvent {\n return new WebhookEvent().fromJson(jsonValue, options);\n }\n\n static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): WebhookEvent {\n return new WebhookEvent().fromJsonString(jsonString, options);\n }\n}\n\nexport type WebhookEventNames =\n | 'room_started'\n | 'room_finished'\n | 'participant_joined'\n | 'participant_left'\n | 'participant_connection_aborted'\n | 'track_published'\n | 'track_unpublished'\n | 'egress_started'\n | 'egress_updated'\n | 'egress_ended'\n | 'ingress_started'\n | 'ingress_ended'\n /**\n * @internal\n * @remarks only used as a default value, not a valid webhook event\n */\n | '';\n\nexport class WebhookReceiver {\n private verifier: TokenVerifier;\n\n constructor(apiKey: string, apiSecret: string) {\n this.verifier = new TokenVerifier(apiKey, apiSecret);\n }\n\n /**\n * @param body - string of the posted body\n * @param authHeader - `Authorization` header from the request\n * @param skipAuth - true to skip auth validation\n * @param clockTolerance - How much tolerance to allow for checks against the auth header to be skewed from the claims\n * @returns The processed webhook event\n */\n async receive(\n body: string,\n authHeader?: string,\n skipAuth: boolean = false,\n clockTolerance?: string | number,\n ): Promise<WebhookEvent> {\n // verify token\n if (!skipAuth) {\n if (!authHeader) {\n throw new Error('authorization header is empty');\n }\n const claims = await this.verifier.verify(authHeader, clockTolerance);\n // confirm sha\n const hash = await digest(body);\n const hashDecoded = btoa(\n Array.from(new Uint8Array(hash))\n .map((v) => String.fromCharCode(v))\n .join(''),\n );\n\n if (claims.sha256 !== hashDecoded) {\n throw new Error('sha256 checksum of body does not match');\n }\n }\n\n return WebhookEvent.fromJson(JSON.parse(body), { ignoreUnknownFields: true });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,sBAAkD;AAClD,yBAA8B;AAC9B,oBAAuB;AAEhB,MAAM,kBAAkB;AAExB,MAAM,qBAAqB,gBAAAA,aAAkB;AAAA,EAA7C;AAAA;AACL,iBAA2B;AAAA;AAAA,EAE3B,OAAO,WAAW,OAAmB,SAAoD;AACvF,WAAO,IAAI,aAAa,EAAE,WAAW,OAAO,OAAO;AAAA,EACrD;AAAA,EAEA,OAAO,SAAS,WAAsB,SAAkD;AACtF,WAAO,IAAI,aAAa,EAAE,SAAS,WAAW,OAAO;AAAA,EACvD;AAAA,EAEA,OAAO,eAAe,YAAoB,SAAkD;AAC1F,WAAO,IAAI,aAAa,EAAE,eAAe,YAAY,OAAO;AAAA,EAC9D;AACF;AAqBO,MAAM,gBAAgB;AAAA,EAG3B,YAAY,QAAgB,WAAmB;AAC7C,SAAK,WAAW,IAAI,iCAAc,QAAQ,SAAS;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,QACJ,MACA,YACA,WAAoB,OACpB,gBACuB;AAEvB,QAAI,CAAC,UAAU;AACb,UAAI,CAAC,YAAY;AACf,cAAM,IAAI,MAAM,+BAA+B;AAAA,MACjD;AACA,YAAM,SAAS,MAAM,KAAK,SAAS,OAAO,YAAY,cAAc;AAEpE,YAAM,OAAO,UAAM,sBAAO,IAAI;AAC9B,YAAM,cAAc;AAAA,QAClB,MAAM,KAAK,IAAI,WAAW,IAAI,CAAC,EAC5B,IAAI,CAAC,MAAM,OAAO,aAAa,CAAC,CAAC,EACjC,KAAK,EAAE;AAAA,MACZ;AAEA,UAAI,OAAO,WAAW,aAAa;AACjC,cAAM,IAAI,MAAM,wCAAwC;AAAA,MAC1D;AAAA,IACF;AAEA,WAAO,aAAa,SAAS,KAAK,MAAM,IAAI,GAAG,EAAE,qBAAqB,KAAK,CAAC;AAAA,EAC9E;AACF;","names":["ProtoWebhookEvent"]}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
import { BinaryReadOptions, JsonValue, JsonReadOptions } from '@bufbuild/protobuf';
|
||||
import { WebhookEvent as WebhookEvent$1 } from '@livekit/protocol';
|
||||
|
||||
declare const authorizeHeader = "Authorize";
|
||||
declare class WebhookEvent extends WebhookEvent$1 {
|
||||
event: WebhookEventNames;
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): WebhookEvent;
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): WebhookEvent;
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): WebhookEvent;
|
||||
}
|
||||
type WebhookEventNames = 'room_started' | 'room_finished' | 'participant_joined' | 'participant_left' | 'participant_connection_aborted' | 'track_published' | 'track_unpublished' | 'egress_started' | 'egress_updated' | 'egress_ended' | 'ingress_started' | 'ingress_ended'
|
||||
/**
|
||||
* @internal
|
||||
* @remarks only used as a default value, not a valid webhook event
|
||||
*/
|
||||
| '';
|
||||
declare class WebhookReceiver {
|
||||
private verifier;
|
||||
constructor(apiKey: string, apiSecret: string);
|
||||
/**
|
||||
* @param body - string of the posted body
|
||||
* @param authHeader - `Authorization` header from the request
|
||||
* @param skipAuth - true to skip auth validation
|
||||
* @param clockTolerance - How much tolerance to allow for checks against the auth header to be skewed from the claims
|
||||
* @returns The processed webhook event
|
||||
*/
|
||||
receive(body: string, authHeader?: string, skipAuth?: boolean, clockTolerance?: string | number): Promise<WebhookEvent>;
|
||||
}
|
||||
|
||||
export { WebhookEvent, type WebhookEventNames, WebhookReceiver, authorizeHeader };
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
import { BinaryReadOptions, JsonValue, JsonReadOptions } from '@bufbuild/protobuf';
|
||||
import { WebhookEvent as WebhookEvent$1 } from '@livekit/protocol';
|
||||
|
||||
declare const authorizeHeader = "Authorize";
|
||||
declare class WebhookEvent extends WebhookEvent$1 {
|
||||
event: WebhookEventNames;
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): WebhookEvent;
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): WebhookEvent;
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): WebhookEvent;
|
||||
}
|
||||
type WebhookEventNames = 'room_started' | 'room_finished' | 'participant_joined' | 'participant_left' | 'participant_connection_aborted' | 'track_published' | 'track_unpublished' | 'egress_started' | 'egress_updated' | 'egress_ended' | 'ingress_started' | 'ingress_ended'
|
||||
/**
|
||||
* @internal
|
||||
* @remarks only used as a default value, not a valid webhook event
|
||||
*/
|
||||
| '';
|
||||
declare class WebhookReceiver {
|
||||
private verifier;
|
||||
constructor(apiKey: string, apiSecret: string);
|
||||
/**
|
||||
* @param body - string of the posted body
|
||||
* @param authHeader - `Authorization` header from the request
|
||||
* @param skipAuth - true to skip auth validation
|
||||
* @param clockTolerance - How much tolerance to allow for checks against the auth header to be skewed from the claims
|
||||
* @returns The processed webhook event
|
||||
*/
|
||||
receive(body: string, authHeader?: string, skipAuth?: boolean, clockTolerance?: string | number): Promise<WebhookEvent>;
|
||||
}
|
||||
|
||||
export { WebhookEvent, type WebhookEventNames, WebhookReceiver, authorizeHeader };
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"WebhookReceiver.d.ts","sourceRoot":"","sources":["../src/WebhookReceiver.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACxF,OAAO,EAAE,YAAY,IAAI,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAItE,eAAO,MAAM,eAAe,cAAc,CAAC;AAE3C,qBAAa,YAAa,SAAQ,iBAAiB;IACjD,KAAK,EAAE,iBAAiB,CAAM;IAE9B,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,YAAY;IAIxF,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,YAAY;IAIvF,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,YAAY;CAG5F;AAED,MAAM,MAAM,iBAAiB,GACzB,cAAc,GACd,eAAe,GACf,oBAAoB,GACpB,kBAAkB,GAClB,gCAAgC,GAChC,iBAAiB,GACjB,mBAAmB,GACnB,gBAAgB,GAChB,gBAAgB,GAChB,cAAc,GACd,iBAAiB,GACjB,eAAe;AACjB;;;GAGG;GACD,EAAE,CAAC;AAEP,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAgB;gBAEpB,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAI7C;;;;;;OAMG;IACG,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,EACnB,QAAQ,GAAE,OAAe,EACzB,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,GAC/B,OAAO,CAAC,YAAY,CAAC;CAsBzB"}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
import { WebhookEvent as ProtoWebhookEvent } from "@livekit/protocol";
|
||||
import { TokenVerifier } from "./AccessToken.js";
|
||||
import { digest } from "./crypto/digest.js";
|
||||
const authorizeHeader = "Authorize";
|
||||
class WebhookEvent extends ProtoWebhookEvent {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.event = "";
|
||||
}
|
||||
static fromBinary(bytes, options) {
|
||||
return new WebhookEvent().fromBinary(bytes, options);
|
||||
}
|
||||
static fromJson(jsonValue, options) {
|
||||
return new WebhookEvent().fromJson(jsonValue, options);
|
||||
}
|
||||
static fromJsonString(jsonString, options) {
|
||||
return new WebhookEvent().fromJsonString(jsonString, options);
|
||||
}
|
||||
}
|
||||
class WebhookReceiver {
|
||||
constructor(apiKey, apiSecret) {
|
||||
this.verifier = new TokenVerifier(apiKey, apiSecret);
|
||||
}
|
||||
/**
|
||||
* @param body - string of the posted body
|
||||
* @param authHeader - `Authorization` header from the request
|
||||
* @param skipAuth - true to skip auth validation
|
||||
* @param clockTolerance - How much tolerance to allow for checks against the auth header to be skewed from the claims
|
||||
* @returns The processed webhook event
|
||||
*/
|
||||
async receive(body, authHeader, skipAuth = false, clockTolerance) {
|
||||
if (!skipAuth) {
|
||||
if (!authHeader) {
|
||||
throw new Error("authorization header is empty");
|
||||
}
|
||||
const claims = await this.verifier.verify(authHeader, clockTolerance);
|
||||
const hash = await digest(body);
|
||||
const hashDecoded = btoa(
|
||||
Array.from(new Uint8Array(hash)).map((v) => String.fromCharCode(v)).join("")
|
||||
);
|
||||
if (claims.sha256 !== hashDecoded) {
|
||||
throw new Error("sha256 checksum of body does not match");
|
||||
}
|
||||
}
|
||||
return WebhookEvent.fromJson(JSON.parse(body), { ignoreUnknownFields: true });
|
||||
}
|
||||
}
|
||||
export {
|
||||
WebhookEvent,
|
||||
WebhookReceiver,
|
||||
authorizeHeader
|
||||
};
|
||||
//# sourceMappingURL=WebhookReceiver.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../src/WebhookReceiver.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { BinaryReadOptions, JsonReadOptions, JsonValue } from '@bufbuild/protobuf';\nimport { WebhookEvent as ProtoWebhookEvent } from '@livekit/protocol';\nimport { TokenVerifier } from './AccessToken.js';\nimport { digest } from './crypto/digest.js';\n\nexport const authorizeHeader = 'Authorize';\n\nexport class WebhookEvent extends ProtoWebhookEvent {\n event: WebhookEventNames = '';\n\n static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): WebhookEvent {\n return new WebhookEvent().fromBinary(bytes, options);\n }\n\n static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): WebhookEvent {\n return new WebhookEvent().fromJson(jsonValue, options);\n }\n\n static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): WebhookEvent {\n return new WebhookEvent().fromJsonString(jsonString, options);\n }\n}\n\nexport type WebhookEventNames =\n | 'room_started'\n | 'room_finished'\n | 'participant_joined'\n | 'participant_left'\n | 'participant_connection_aborted'\n | 'track_published'\n | 'track_unpublished'\n | 'egress_started'\n | 'egress_updated'\n | 'egress_ended'\n | 'ingress_started'\n | 'ingress_ended'\n /**\n * @internal\n * @remarks only used as a default value, not a valid webhook event\n */\n | '';\n\nexport class WebhookReceiver {\n private verifier: TokenVerifier;\n\n constructor(apiKey: string, apiSecret: string) {\n this.verifier = new TokenVerifier(apiKey, apiSecret);\n }\n\n /**\n * @param body - string of the posted body\n * @param authHeader - `Authorization` header from the request\n * @param skipAuth - true to skip auth validation\n * @param clockTolerance - How much tolerance to allow for checks against the auth header to be skewed from the claims\n * @returns The processed webhook event\n */\n async receive(\n body: string,\n authHeader?: string,\n skipAuth: boolean = false,\n clockTolerance?: string | number,\n ): Promise<WebhookEvent> {\n // verify token\n if (!skipAuth) {\n if (!authHeader) {\n throw new Error('authorization header is empty');\n }\n const claims = await this.verifier.verify(authHeader, clockTolerance);\n // confirm sha\n const hash = await digest(body);\n const hashDecoded = btoa(\n Array.from(new Uint8Array(hash))\n .map((v) => String.fromCharCode(v))\n .join(''),\n );\n\n if (claims.sha256 !== hashDecoded) {\n throw new Error('sha256 checksum of body does not match');\n }\n }\n\n return WebhookEvent.fromJson(JSON.parse(body), { ignoreUnknownFields: true });\n }\n}\n"],"mappings":"AAIA,SAAS,gBAAgB,yBAAyB;AAClD,SAAS,qBAAqB;AAC9B,SAAS,cAAc;AAEhB,MAAM,kBAAkB;AAExB,MAAM,qBAAqB,kBAAkB;AAAA,EAA7C;AAAA;AACL,iBAA2B;AAAA;AAAA,EAE3B,OAAO,WAAW,OAAmB,SAAoD;AACvF,WAAO,IAAI,aAAa,EAAE,WAAW,OAAO,OAAO;AAAA,EACrD;AAAA,EAEA,OAAO,SAAS,WAAsB,SAAkD;AACtF,WAAO,IAAI,aAAa,EAAE,SAAS,WAAW,OAAO;AAAA,EACvD;AAAA,EAEA,OAAO,eAAe,YAAoB,SAAkD;AAC1F,WAAO,IAAI,aAAa,EAAE,eAAe,YAAY,OAAO;AAAA,EAC9D;AACF;AAqBO,MAAM,gBAAgB;AAAA,EAG3B,YAAY,QAAgB,WAAmB;AAC7C,SAAK,WAAW,IAAI,cAAc,QAAQ,SAAS;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,QACJ,MACA,YACA,WAAoB,OACpB,gBACuB;AAEvB,QAAI,CAAC,UAAU;AACb,UAAI,CAAC,YAAY;AACf,cAAM,IAAI,MAAM,+BAA+B;AAAA,MACjD;AACA,YAAM,SAAS,MAAM,KAAK,SAAS,OAAO,YAAY,cAAc;AAEpE,YAAM,OAAO,MAAM,OAAO,IAAI;AAC9B,YAAM,cAAc;AAAA,QAClB,MAAM,KAAK,IAAI,WAAW,IAAI,CAAC,EAC5B,IAAI,CAAC,MAAM,OAAO,aAAa,CAAC,CAAC,EACjC,KAAK,EAAE;AAAA,MACZ;AAEA,UAAI,OAAO,WAAW,aAAa;AACjC,cAAM,IAAI,MAAM,wCAAwC;AAAA,MAC1D;AAAA,IACF;AAEA,WAAO,aAAa,SAAS,KAAK,MAAM,IAAI,GAAG,EAAE,qBAAqB,KAAK,CAAC;AAAA,EAC9E;AACF;","names":[]}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var digest_exports = {};
|
||||
__export(digest_exports, {
|
||||
digest: () => digest
|
||||
});
|
||||
module.exports = __toCommonJS(digest_exports);
|
||||
async function digest(data) {
|
||||
var _a;
|
||||
if ((_a = globalThis.crypto) == null ? void 0 : _a.subtle) {
|
||||
const encoder = new TextEncoder();
|
||||
return crypto.subtle.digest("SHA-256", encoder.encode(data));
|
||||
} else {
|
||||
const nodeCrypto = await import("node:crypto");
|
||||
return nodeCrypto.createHash("sha256").update(data).digest();
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
digest
|
||||
});
|
||||
//# sourceMappingURL=digest.cjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../src/crypto/digest.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\n// Use the Web Crypto API if available, otherwise fallback to Node.js crypto\nexport async function digest(data: string): Promise<ArrayBuffer> {\n if (globalThis.crypto?.subtle) {\n const encoder = new TextEncoder();\n return crypto.subtle.digest('SHA-256', encoder.encode(data));\n } else {\n const nodeCrypto = await import('node:crypto');\n return nodeCrypto.createHash('sha256').update(data).digest();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,eAAsB,OAAO,MAAoC;AALjE;AAME,OAAI,gBAAW,WAAX,mBAAmB,QAAQ;AAC7B,UAAM,UAAU,IAAI,YAAY;AAChC,WAAO,OAAO,OAAO,OAAO,WAAW,QAAQ,OAAO,IAAI,CAAC;AAAA,EAC7D,OAAO;AACL,UAAM,aAAa,MAAM,OAAO,aAAa;AAC7C,WAAO,WAAW,WAAW,QAAQ,EAAE,OAAO,IAAI,EAAE,OAAO;AAAA,EAC7D;AACF;","names":[]}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
declare function digest(data: string): Promise<ArrayBuffer>;
|
||||
|
||||
export { digest };
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
declare function digest(data: string): Promise<ArrayBuffer>;
|
||||
|
||||
export { digest };
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"digest.d.ts","sourceRoot":"","sources":["../../src/crypto/digest.ts"],"names":[],"mappings":"AAKA,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAQ/D"}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
async function digest(data) {
|
||||
var _a;
|
||||
if ((_a = globalThis.crypto) == null ? void 0 : _a.subtle) {
|
||||
const encoder = new TextEncoder();
|
||||
return crypto.subtle.digest("SHA-256", encoder.encode(data));
|
||||
} else {
|
||||
const nodeCrypto = await import("node:crypto");
|
||||
return nodeCrypto.createHash("sha256").update(data).digest();
|
||||
}
|
||||
}
|
||||
export {
|
||||
digest
|
||||
};
|
||||
//# sourceMappingURL=digest.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../src/crypto/digest.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\n// Use the Web Crypto API if available, otherwise fallback to Node.js crypto\nexport async function digest(data: string): Promise<ArrayBuffer> {\n if (globalThis.crypto?.subtle) {\n const encoder = new TextEncoder();\n return crypto.subtle.digest('SHA-256', encoder.encode(data));\n } else {\n const nodeCrypto = await import('node:crypto');\n return nodeCrypto.createHash('sha256').update(data).digest();\n }\n}\n"],"mappings":"AAKA,eAAsB,OAAO,MAAoC;AALjE;AAME,OAAI,gBAAW,WAAX,mBAAmB,QAAQ;AAC7B,UAAM,UAAU,IAAI,YAAY;AAChC,WAAO,OAAO,OAAO,OAAO,WAAW,QAAQ,OAAO,IAAI,CAAC;AAAA,EAC7D,OAAO;AACL,UAAM,aAAa,MAAM,OAAO,aAAa;AAC7C,WAAO,WAAW,WAAW,QAAQ,EAAE,OAAO,IAAI,EAAE,OAAO;AAAA,EAC7D;AACF;","names":[]}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var uuid_exports = {};
|
||||
__export(uuid_exports, {
|
||||
getRandomBytes: () => getRandomBytes
|
||||
});
|
||||
module.exports = __toCommonJS(uuid_exports);
|
||||
async function getRandomBytes(size = 16) {
|
||||
if (globalThis.crypto) {
|
||||
return crypto.getRandomValues(new Uint8Array(size));
|
||||
} else {
|
||||
const nodeCrypto = await import("node:crypto");
|
||||
return nodeCrypto.getRandomValues(new Uint8Array(size));
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
getRandomBytes
|
||||
});
|
||||
//# sourceMappingURL=uuid.cjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../src/crypto/uuid.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\n// Use the Web Crypto API if available, otherwise fallback to Node.js crypto\nexport async function getRandomBytes(size: number = 16): Promise<Uint8Array> {\n if (globalThis.crypto) {\n return crypto.getRandomValues(new Uint8Array(size));\n } else {\n const nodeCrypto = await import('node:crypto');\n return nodeCrypto.getRandomValues(new Uint8Array(size));\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,eAAsB,eAAe,OAAe,IAAyB;AAC3E,MAAI,WAAW,QAAQ;AACrB,WAAO,OAAO,gBAAgB,IAAI,WAAW,IAAI,CAAC;AAAA,EACpD,OAAO;AACL,UAAM,aAAa,MAAM,OAAO,aAAa;AAC7C,WAAO,WAAW,gBAAgB,IAAI,WAAW,IAAI,CAAC;AAAA,EACxD;AACF;","names":[]}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
declare function getRandomBytes(size?: number): Promise<Uint8Array>;
|
||||
|
||||
export { getRandomBytes };
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
declare function getRandomBytes(size?: number): Promise<Uint8Array>;
|
||||
|
||||
export { getRandomBytes };
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"uuid.d.ts","sourceRoot":"","sources":["../../src/crypto/uuid.ts"],"names":[],"mappings":"AAKA,wBAAsB,cAAc,CAAC,IAAI,GAAE,MAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAO3E"}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
async function getRandomBytes(size = 16) {
|
||||
if (globalThis.crypto) {
|
||||
return crypto.getRandomValues(new Uint8Array(size));
|
||||
} else {
|
||||
const nodeCrypto = await import("node:crypto");
|
||||
return nodeCrypto.getRandomValues(new Uint8Array(size));
|
||||
}
|
||||
}
|
||||
export {
|
||||
getRandomBytes
|
||||
};
|
||||
//# sourceMappingURL=uuid.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../src/crypto/uuid.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\n// Use the Web Crypto API if available, otherwise fallback to Node.js crypto\nexport async function getRandomBytes(size: number = 16): Promise<Uint8Array> {\n if (globalThis.crypto) {\n return crypto.getRandomValues(new Uint8Array(size));\n } else {\n const nodeCrypto = await import('node:crypto');\n return nodeCrypto.getRandomValues(new Uint8Array(size));\n }\n}\n"],"mappings":"AAKA,eAAsB,eAAe,OAAe,IAAyB;AAC3E,MAAI,WAAW,QAAQ;AACrB,WAAO,OAAO,gBAAgB,IAAI,WAAW,IAAI,CAAC;AAAA,EACpD,OAAO;AACL,UAAM,aAAa,MAAM,OAAO,aAAa;AAC7C,WAAO,WAAW,gBAAgB,IAAI,WAAW,IAAI,CAAC;AAAA,EACxD;AACF;","names":[]}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user