@mentra/cloud-client 3.2.1-dev.311 → 3.3.0-dev.316

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mentra/cloud-client",
3
- "version": "3.2.1-dev.311",
3
+ "version": "3.3.0-dev.316",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "exports": {
@@ -12,7 +12,7 @@
12
12
  "test": "bun test"
13
13
  },
14
14
  "dependencies": {
15
- "@mentra/cloud-protocol": "3.2.1-dev.311",
15
+ "@mentra/cloud-protocol": "3.3.0-dev.316",
16
16
  "tweetnacl": "^1.0.3"
17
17
  },
18
18
  "devDependencies": {
package/src/client.ts CHANGED
@@ -33,6 +33,7 @@ import {RuntimeEmitter} from "./modules/runtime/emitter"
33
33
  import {Subscriptions} from "./modules/runtime/subscriptions"
34
34
  import {Camera} from "./modules/runtime/camera"
35
35
  import {Maps} from "./modules/runtime/maps"
36
+ import {Meetings} from "./modules/runtime/meetings"
36
37
  import {Tts} from "./modules/runtime/tts"
37
38
  import {UdpAudio} from "./modules/runtime/audio-udp"
38
39
  import {Core} from "./modules/core/core"
@@ -247,6 +248,7 @@ export class CloudClient {
247
248
  camera,
248
249
  tts,
249
250
  maps,
251
+ meetings: new Meetings(runtimeHttp),
250
252
  audio,
251
253
  timers,
252
254
  logger,
package/src/index.ts CHANGED
@@ -16,6 +16,7 @@
16
16
 
17
17
  // The top-level object. Implemented in ./client by the client agent; re-exported
18
18
  // here so the public import is `@mentra/cloud-client`, not a deep path.
19
+ export type { AcsMeetingCredential } from "./modules/runtime/meetings";
19
20
  export { CloudClient } from "./client";
20
21
  export { DEFAULT_REFRESH_TOKEN_KEY } from "./modules/auth/token-store";
21
22
 
@@ -0,0 +1,34 @@
1
+ import type {HttpClient} from "../../http"
2
+
3
+ /** Host-only credentials. Never forward this object to a miniapp. */
4
+ export interface AcsMeetingCredential {
5
+ token: string
6
+ expiresOn: string
7
+ identityMode: "guest" | "teams-user"
8
+ acsUserId?: string
9
+ guestReason?: "teams-license-unavailable"
10
+ }
11
+
12
+ export class Meetings {
13
+ constructor(private readonly http: HttpClient) {}
14
+
15
+ async getAcsCredential(teamsUserAadToken?: string): Promise<AcsMeetingCredential> {
16
+ const value = await this.http.post<AcsMeetingCredential>(
17
+ "/api/meetings/acs/token",
18
+ teamsUserAadToken ? {teamsUserAadToken} : {},
19
+ )
20
+ if (
21
+ !value ||
22
+ typeof value.token !== "string" ||
23
+ !value.token ||
24
+ !Number.isFinite(Date.parse(value.expiresOn)) ||
25
+ Date.parse(value.expiresOn) <= Date.now() ||
26
+ (value.identityMode !== "guest" && value.identityMode !== "teams-user") ||
27
+ (value.identityMode === "guest" && (typeof value.acsUserId !== "string" || !value.acsUserId)) ||
28
+ (teamsUserAadToken && value.identityMode === "guest" && value.guestReason !== "teams-license-unavailable") ||
29
+ (!teamsUserAadToken && value.identityMode !== "guest")
30
+ )
31
+ throw new Error("Runtime returned an invalid meeting credential")
32
+ return value
33
+ }
34
+ }
@@ -30,6 +30,7 @@ import { HandshakeRejectedError } from "./connection";
30
30
  import type { RuntimeEmitter, RuntimeEvents } from "./emitter";
31
31
  import type { Subscriptions } from "./subscriptions";
32
32
  import type { Camera, StreamOptions, ManagedStream, StreamStatusResult } from "./camera";
33
+ import type { Meetings } from "./meetings";
33
34
  import type { Maps, DirectionsRequest, DirectionsResult, LatLng, ReverseGeocodeResult } from "./maps";
34
35
  import type { Tts, RuntimeTtsSpeakOptions, RuntimeTtsSpeechSource } from "./tts";
35
36
  import type { UdpAudio } from "./audio-udp";
@@ -68,6 +69,7 @@ export type { RuntimeStatus, RuntimeSnapshot } from "./status";
68
69
  * unsubscribe function.
69
70
  */
70
71
  export interface RuntimeModule {
72
+ readonly meetings: Meetings;
71
73
  connect(): Promise<void>;
72
74
  close(): void;
73
75
 
@@ -111,6 +113,7 @@ export interface RuntimeModule {
111
113
  }
112
114
 
113
115
  export interface RuntimeDeps {
116
+ meetings?: Meetings;
114
117
  connection: Connection;
115
118
  emitter: RuntimeEmitter;
116
119
  subscriptions: Subscriptions;
@@ -136,6 +139,11 @@ export interface RuntimeDeps {
136
139
  const AUTH_EXPIRED_CODE = "AUTH_EXPIRED";
137
140
 
138
141
  export class Runtime implements RuntimeModule {
142
+ private readonly meetingService?: Meetings;
143
+ get meetings(): Meetings {
144
+ if (!this.meetingService) throw new Error("Meeting credentials are unavailable");
145
+ return this.meetingService;
146
+ }
139
147
  private readonly connection: Connection;
140
148
  private readonly emitter: RuntimeEmitter;
141
149
  private readonly subscriptions: Subscriptions;
@@ -175,6 +183,7 @@ export class Runtime implements RuntimeModule {
175
183
  private opened = false;
176
184
 
177
185
  constructor(deps: RuntimeDeps) {
186
+ this.meetingService = deps.meetings;
178
187
  this.connection = deps.connection;
179
188
  this.emitter = deps.emitter;
180
189
  this.subscriptions = deps.subscriptions;