@mentra/sdk 2.1.24 → 2.1.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/server/index.d.ts +2 -0
- package/dist/app/server/index.d.ts.map +1 -1
- package/dist/app/server/index.js +48 -26
- package/dist/app/session/dashboard.d.ts +7 -7
- package/dist/app/session/dashboard.d.ts.map +1 -1
- package/dist/app/session/dashboard.js +12 -12
- package/dist/app/session/events.d.ts +3 -1
- package/dist/app/session/events.d.ts.map +1 -1
- package/dist/app/session/events.js +12 -2
- package/dist/app/session/index.d.ts +1 -1
- package/dist/app/session/index.d.ts.map +1 -1
- package/dist/app/session/index.js +12 -7
- package/dist/app/session/modules/audio.js +1 -1
- package/dist/app/session/modules/camera.d.ts +17 -0
- package/dist/app/session/modules/camera.d.ts.map +1 -1
- package/dist/app/session/modules/camera.js +27 -0
- package/dist/app/session/modules/location.d.ts.map +1 -1
- package/dist/app/session/modules/location.js +3 -0
- package/dist/constants/log-messages/color.d.ts +5 -0
- package/dist/constants/log-messages/color.d.ts.map +1 -0
- package/dist/constants/log-messages/color.js +14 -0
- package/dist/constants/log-messages/logos.d.ts +4 -0
- package/dist/constants/log-messages/logos.d.ts.map +1 -0
- package/dist/constants/log-messages/logos.js +48 -0
- package/dist/constants/{messages.d.ts → log-messages/updates.d.ts} +2 -3
- package/dist/constants/log-messages/updates.d.ts.map +1 -0
- package/dist/constants/log-messages/updates.js +55 -0
- package/dist/constants/log-messages/warning.d.ts +8 -0
- package/dist/constants/log-messages/warning.d.ts.map +1 -0
- package/dist/constants/log-messages/warning.js +89 -0
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -15
- package/dist/logging/logger.d.ts +2 -1
- package/dist/logging/logger.d.ts.map +1 -1
- package/dist/types/enums.d.ts +0 -20
- package/dist/types/enums.d.ts.map +1 -1
- package/dist/types/enums.js +2 -25
- package/dist/types/index.d.ts +1 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +0 -2
- package/dist/types/layouts.d.ts +3 -3
- package/dist/types/layouts.d.ts.map +1 -1
- package/dist/types/message-types.d.ts +6 -4
- package/dist/types/message-types.d.ts.map +1 -1
- package/dist/types/message-types.js +13 -13
- package/dist/types/messages/base.d.ts.map +1 -1
- package/dist/types/messages/cloud-to-app.d.ts +9 -0
- package/dist/types/messages/cloud-to-app.d.ts.map +1 -1
- package/dist/types/messages/cloud-to-glasses.d.ts +15 -8
- package/dist/types/messages/cloud-to-glasses.d.ts.map +1 -1
- package/dist/types/messages/glasses-to-cloud.d.ts +99 -9
- package/dist/types/messages/glasses-to-cloud.d.ts.map +1 -1
- package/dist/types/messages/glasses-to-cloud.js +45 -1
- package/dist/types/models.d.ts.map +1 -1
- package/dist/types/streams.js +1 -1
- package/dist/types/webhooks.d.ts +4 -51
- package/dist/types/webhooks.d.ts.map +1 -1
- package/dist/types/webhooks.js +0 -27
- package/dist/utils/permissions-utils.d.ts +8 -0
- package/dist/utils/permissions-utils.d.ts.map +1 -0
- package/dist/utils/permissions-utils.js +263 -0
- package/package.json +4 -1
- package/dist/constants/messages.d.ts.map +0 -1
- package/dist/constants/messages.js +0 -57
- package/dist/types/user-session.d.ts +0 -73
- package/dist/types/user-session.d.ts.map +0 -1
- package/dist/types/user-session.js +0 -17
package/dist/types/webhooks.d.ts
CHANGED
|
@@ -5,13 +5,7 @@ export declare enum WebhookRequestType {
|
|
|
5
5
|
/** Request to start a App session */
|
|
6
6
|
SESSION_REQUEST = "session_request",
|
|
7
7
|
/** Request to stop a App session */
|
|
8
|
-
STOP_REQUEST = "stop_request"
|
|
9
|
-
/** Server registration confirmation */
|
|
10
|
-
SERVER_REGISTRATION = "server_registration",
|
|
11
|
-
/** Server heartbeat response */
|
|
12
|
-
SERVER_HEARTBEAT = "server_heartbeat",
|
|
13
|
-
/** Session recovery request */
|
|
14
|
-
SESSION_RECOVERY = "session_recovery"
|
|
8
|
+
STOP_REQUEST = "stop_request"
|
|
15
9
|
}
|
|
16
10
|
/**
|
|
17
11
|
* Base interface for all webhook requests
|
|
@@ -43,46 +37,17 @@ export interface SessionWebhookRequest extends BaseWebhookRequest {
|
|
|
43
37
|
*/
|
|
44
38
|
export interface StopWebhookRequest extends BaseWebhookRequest {
|
|
45
39
|
type: WebhookRequestType.STOP_REQUEST;
|
|
46
|
-
reason:
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Server registration webhook
|
|
50
|
-
*
|
|
51
|
-
* Sent to a App when its server registration is confirmed
|
|
52
|
-
*/
|
|
53
|
-
export interface ServerRegistrationWebhookRequest extends BaseWebhookRequest {
|
|
54
|
-
type: WebhookRequestType.SERVER_REGISTRATION;
|
|
55
|
-
registrationId: string;
|
|
56
|
-
packageName: string;
|
|
57
|
-
serverUrls: string[];
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Session recovery webhook
|
|
61
|
-
*
|
|
62
|
-
* Sent to a App when the system is trying to recover a session after server restart
|
|
63
|
-
*/
|
|
64
|
-
export interface SessionRecoveryWebhookRequest extends BaseWebhookRequest {
|
|
65
|
-
type: WebhookRequestType.SESSION_RECOVERY;
|
|
66
|
-
mentraOSWebsocketUrl: string;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Server heartbeat webhook
|
|
70
|
-
*
|
|
71
|
-
* Sent to a App to check its health status
|
|
72
|
-
*/
|
|
73
|
-
export interface ServerHeartbeatWebhookRequest extends BaseWebhookRequest {
|
|
74
|
-
type: WebhookRequestType.SERVER_HEARTBEAT;
|
|
75
|
-
registrationId: string;
|
|
40
|
+
reason: "user_disabled" | "system_stop" | "error";
|
|
76
41
|
}
|
|
77
42
|
/**
|
|
78
43
|
* Union type for all webhook requests
|
|
79
44
|
*/
|
|
80
|
-
export type WebhookRequest = SessionWebhookRequest | StopWebhookRequest
|
|
45
|
+
export type WebhookRequest = SessionWebhookRequest | StopWebhookRequest;
|
|
81
46
|
/**
|
|
82
47
|
* Response to a webhook request
|
|
83
48
|
*/
|
|
84
49
|
export interface WebhookResponse {
|
|
85
|
-
status:
|
|
50
|
+
status: "success" | "error";
|
|
86
51
|
message?: string;
|
|
87
52
|
}
|
|
88
53
|
/**
|
|
@@ -93,16 +58,4 @@ export declare function isSessionWebhookRequest(request: WebhookRequest): reques
|
|
|
93
58
|
* Type guard to check if a webhook request is a stop request
|
|
94
59
|
*/
|
|
95
60
|
export declare function isStopWebhookRequest(request: WebhookRequest): request is StopWebhookRequest;
|
|
96
|
-
/**
|
|
97
|
-
* Type guard to check if a webhook request is a server registration request
|
|
98
|
-
*/
|
|
99
|
-
export declare function isServerRegistrationWebhookRequest(request: WebhookRequest): request is ServerRegistrationWebhookRequest;
|
|
100
|
-
/**
|
|
101
|
-
* Type guard to check if a webhook request is a session recovery request
|
|
102
|
-
*/
|
|
103
|
-
export declare function isSessionRecoveryWebhookRequest(request: WebhookRequest): request is SessionRecoveryWebhookRequest;
|
|
104
|
-
/**
|
|
105
|
-
* Type guard to check if a webhook request is a server heartbeat request
|
|
106
|
-
*/
|
|
107
|
-
export declare function isServerHeartbeatWebhookRequest(request: WebhookRequest): request is ServerHeartbeatWebhookRequest;
|
|
108
61
|
//# sourceMappingURL=webhooks.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../src/types/webhooks.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,oBAAY,kBAAkB;IAC5B,qCAAqC;IACrC,eAAe,oBAAoB;IAEnC,oCAAoC;IACpC,YAAY,iBAAiB;
|
|
1
|
+
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../src/types/webhooks.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,oBAAY,kBAAkB;IAC5B,qCAAqC;IACrC,eAAe,oBAAoB;IAEnC,oCAAoC;IACpC,YAAY,iBAAiB;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,8BAA8B;IAC9B,IAAI,EAAE,kBAAkB,CAAC;IAEzB,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAElB,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;IAEf,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAsB,SAAQ,kBAAkB;IAC/D,IAAI,EAAE,kBAAkB,CAAC,eAAe,CAAC;IACzC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAmB,SAAQ,kBAAkB;IAC5D,IAAI,EAAE,kBAAkB,CAAC,YAAY,CAAC;IACtC,MAAM,EAAE,eAAe,GAAG,aAAa,GAAG,OAAO,CAAC;CACnD;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,qBAAqB,GAAG,kBAAkB,CAAC;AAExE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,cAAc,GACtB,OAAO,IAAI,qBAAqB,CAElC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,cAAc,GACtB,OAAO,IAAI,kBAAkB,CAE/B"}
|
package/dist/types/webhooks.js
CHANGED
|
@@ -4,9 +4,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
4
4
|
exports.WebhookRequestType = void 0;
|
|
5
5
|
exports.isSessionWebhookRequest = isSessionWebhookRequest;
|
|
6
6
|
exports.isStopWebhookRequest = isStopWebhookRequest;
|
|
7
|
-
exports.isServerRegistrationWebhookRequest = isServerRegistrationWebhookRequest;
|
|
8
|
-
exports.isSessionRecoveryWebhookRequest = isSessionRecoveryWebhookRequest;
|
|
9
|
-
exports.isServerHeartbeatWebhookRequest = isServerHeartbeatWebhookRequest;
|
|
10
7
|
/**
|
|
11
8
|
* Types of webhook requests that can be sent to Apps
|
|
12
9
|
*/
|
|
@@ -16,12 +13,6 @@ var WebhookRequestType;
|
|
|
16
13
|
WebhookRequestType["SESSION_REQUEST"] = "session_request";
|
|
17
14
|
/** Request to stop a App session */
|
|
18
15
|
WebhookRequestType["STOP_REQUEST"] = "stop_request";
|
|
19
|
-
/** Server registration confirmation */
|
|
20
|
-
WebhookRequestType["SERVER_REGISTRATION"] = "server_registration";
|
|
21
|
-
/** Server heartbeat response */
|
|
22
|
-
WebhookRequestType["SERVER_HEARTBEAT"] = "server_heartbeat";
|
|
23
|
-
/** Session recovery request */
|
|
24
|
-
WebhookRequestType["SESSION_RECOVERY"] = "session_recovery";
|
|
25
16
|
})(WebhookRequestType || (exports.WebhookRequestType = WebhookRequestType = {}));
|
|
26
17
|
/**
|
|
27
18
|
* Type guard to check if a webhook request is a session request
|
|
@@ -35,21 +26,3 @@ function isSessionWebhookRequest(request) {
|
|
|
35
26
|
function isStopWebhookRequest(request) {
|
|
36
27
|
return request.type === WebhookRequestType.STOP_REQUEST;
|
|
37
28
|
}
|
|
38
|
-
/**
|
|
39
|
-
* Type guard to check if a webhook request is a server registration request
|
|
40
|
-
*/
|
|
41
|
-
function isServerRegistrationWebhookRequest(request) {
|
|
42
|
-
return request.type === WebhookRequestType.SERVER_REGISTRATION;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Type guard to check if a webhook request is a session recovery request
|
|
46
|
-
*/
|
|
47
|
-
function isSessionRecoveryWebhookRequest(request) {
|
|
48
|
-
return request.type === WebhookRequestType.SESSION_RECOVERY;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Type guard to check if a webhook request is a server heartbeat request
|
|
52
|
-
*/
|
|
53
|
-
function isServerHeartbeatWebhookRequest(request) {
|
|
54
|
-
return request.type === WebhookRequestType.SERVER_HEARTBEAT;
|
|
55
|
-
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const microPhoneWarnLog: (cloudServerUrl: string, packageName: string, funcName?: string) => void;
|
|
2
|
+
export declare const locationWarnLog: (cloudServerUrl: string, packageName: string, funcName?: string) => void;
|
|
3
|
+
export declare const backgroundLocationWarnLog: (cloudServerUrl: string, packageName: string, funcName?: string) => void;
|
|
4
|
+
export declare const calendarWarnLog: (cloudServerUrl: string, packageName: string, funcName?: string) => void;
|
|
5
|
+
export declare const readNotificationWarnLog: (cloudServerUrl: string, packageName: string, funcName?: string) => void;
|
|
6
|
+
export declare const postNotificationWarnLog: (cloudServerUrl: string, packageName: string, funcName?: string) => void;
|
|
7
|
+
export declare const cameraWarnLog: (cloudServerUrl: string, packageName: string, funcName?: string) => void;
|
|
8
|
+
//# sourceMappingURL=permissions-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions-utils.d.ts","sourceRoot":"","sources":["../../src/utils/permissions-utils.ts"],"names":[],"mappings":"AAiCA,eAAO,MAAM,iBAAiB,GAC5B,gBAAgB,MAAM,EACtB,aAAa,MAAM,EACnB,WAAW,MAAM,SA2ClB,CAAC;AAGF,eAAO,MAAM,eAAe,GAC1B,gBAAgB,MAAM,EACtB,aAAa,MAAM,EACnB,WAAW,MAAM,SAyClB,CAAC;AAGF,eAAO,MAAM,yBAAyB,GACpC,gBAAgB,MAAM,EACtB,aAAa,MAAM,EACnB,WAAW,MAAM,SAyClB,CAAC;AAGF,eAAO,MAAM,eAAe,GAC1B,gBAAgB,MAAM,EACtB,aAAa,MAAM,EACnB,WAAW,MAAM,SAyClB,CAAC;AAGF,eAAO,MAAM,uBAAuB,GAClC,gBAAgB,MAAM,EACtB,aAAa,MAAM,EACnB,WAAW,MAAM,SAyClB,CAAC;AAGF,eAAO,MAAM,uBAAuB,GAClC,gBAAgB,MAAM,EACtB,aAAa,MAAM,EACnB,WAAW,MAAM,SAyClB,CAAC;AAGF,eAAO,MAAM,aAAa,GACxB,gBAAgB,MAAM,EACtB,aAAa,MAAM,EACnB,WAAW,MAAM,SAyClB,CAAC"}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cameraWarnLog = exports.postNotificationWarnLog = exports.readNotificationWarnLog = exports.calendarWarnLog = exports.backgroundLocationWarnLog = exports.locationWarnLog = exports.microPhoneWarnLog = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* permissions-utils.ts
|
|
6
|
+
*
|
|
7
|
+
* This file provides runtime permission validation utilities for the MentraOS SDK.
|
|
8
|
+
*
|
|
9
|
+
* Each function queries the public permissions API endpoint to check if an app
|
|
10
|
+
* has declared the required permission for a specific feature. If the permission
|
|
11
|
+
* is missing, a styled warning message is displayed in the terminal.
|
|
12
|
+
*
|
|
13
|
+
* Key features:
|
|
14
|
+
* - Fetches app permissions from /api/public/permissions/:packageName
|
|
15
|
+
* - Gracefully handles offline/unreachable endpoints (silent failure)
|
|
16
|
+
* - Displays professional bordered warnings when permissions are missing
|
|
17
|
+
* - Non-blocking - allows app execution to continue even if checks fail
|
|
18
|
+
*
|
|
19
|
+
* These functions are called automatically by SDK methods that require specific
|
|
20
|
+
* permissions (e.g., microphone access, location tracking, camera, etc.) to help
|
|
21
|
+
* developers identify missing permission declarations during development.
|
|
22
|
+
*/
|
|
23
|
+
const warning_1 = require("../constants/log-messages/warning");
|
|
24
|
+
// Check if app has microphone permission, warn if missing
|
|
25
|
+
const microPhoneWarnLog = (cloudServerUrl, packageName, funcName) => {
|
|
26
|
+
if (!cloudServerUrl)
|
|
27
|
+
return;
|
|
28
|
+
const permissionsUrl = `${cloudServerUrl}/api/public/permissions/${encodeURIComponent(packageName)}`;
|
|
29
|
+
// console.log(`Fetching permissions from: ${permissionsUrl}`);
|
|
30
|
+
fetch(permissionsUrl)
|
|
31
|
+
.then(async (res) => {
|
|
32
|
+
const contentType = res.headers.get("content-type");
|
|
33
|
+
if (!res.ok) {
|
|
34
|
+
console.warn(`Permission API returned ${res.status}: ${res.statusText}`);
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
if (contentType && contentType.includes("application/json")) {
|
|
38
|
+
return (await res.json());
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
const text = await res.text();
|
|
42
|
+
console.warn(`Permission API returned non-JSON response: ${text}`);
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
.then((data) => {
|
|
47
|
+
if (data) {
|
|
48
|
+
const hasMic = data.permissions.some((p) => p.type === "MICROPHONE");
|
|
49
|
+
if (!hasMic) {
|
|
50
|
+
console.log((0, warning_1.noMicrophoneWarn)(funcName, packageName));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
.catch((err) => {
|
|
55
|
+
// Silently fail if endpoint is unreachable - don't block execution
|
|
56
|
+
console.debug("Permission check skipped - endpoint unreachable:", err.message);
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
exports.microPhoneWarnLog = microPhoneWarnLog;
|
|
60
|
+
// Check if app has location permission, warn if missing
|
|
61
|
+
const locationWarnLog = (cloudServerUrl, packageName, funcName) => {
|
|
62
|
+
if (!cloudServerUrl)
|
|
63
|
+
return;
|
|
64
|
+
const permissionsUrl = `${cloudServerUrl}/api/public/permissions/${encodeURIComponent(packageName)}`;
|
|
65
|
+
fetch(permissionsUrl)
|
|
66
|
+
.then(async (res) => {
|
|
67
|
+
const contentType = res.headers.get("content-type");
|
|
68
|
+
if (!res.ok) {
|
|
69
|
+
console.warn(`Permission API returned ${res.status}: ${res.statusText}`);
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
if (contentType && contentType.includes("application/json")) {
|
|
73
|
+
return (await res.json());
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
const text = await res.text();
|
|
77
|
+
console.warn(`Permission API returned non-JSON response: ${text}`);
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
.then((data) => {
|
|
82
|
+
if (data) {
|
|
83
|
+
const hasLocation = data.permissions.some((p) => p.type === "LOCATION");
|
|
84
|
+
if (!hasLocation) {
|
|
85
|
+
console.log((0, warning_1.locationWarn)(funcName, packageName));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
})
|
|
89
|
+
.catch((err) => {
|
|
90
|
+
console.debug("Permission check skipped - endpoint unreachable:", err.message);
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
exports.locationWarnLog = locationWarnLog;
|
|
94
|
+
// Check if app has background location permission, warn if missing
|
|
95
|
+
const backgroundLocationWarnLog = (cloudServerUrl, packageName, funcName) => {
|
|
96
|
+
if (!cloudServerUrl)
|
|
97
|
+
return;
|
|
98
|
+
const permissionsUrl = `${cloudServerUrl}/api/public/permissions/${encodeURIComponent(packageName)}`;
|
|
99
|
+
fetch(permissionsUrl)
|
|
100
|
+
.then(async (res) => {
|
|
101
|
+
const contentType = res.headers.get("content-type");
|
|
102
|
+
if (!res.ok) {
|
|
103
|
+
console.warn(`Permission API returned ${res.status}: ${res.statusText}`);
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
if (contentType && contentType.includes("application/json")) {
|
|
107
|
+
return (await res.json());
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
const text = await res.text();
|
|
111
|
+
console.warn(`Permission API returned non-JSON response: ${text}`);
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
.then((data) => {
|
|
116
|
+
if (data) {
|
|
117
|
+
const hasBackgroundLocation = data.permissions.some((p) => p.type === "BACKGROUND_LOCATION");
|
|
118
|
+
if (!hasBackgroundLocation) {
|
|
119
|
+
console.log((0, warning_1.baackgroundLocationWarn)(funcName, packageName));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
.catch((err) => {
|
|
124
|
+
console.debug("Permission check skipped - endpoint unreachable:", err.message);
|
|
125
|
+
});
|
|
126
|
+
};
|
|
127
|
+
exports.backgroundLocationWarnLog = backgroundLocationWarnLog;
|
|
128
|
+
// Check if app has calendar permission, warn if missing
|
|
129
|
+
const calendarWarnLog = (cloudServerUrl, packageName, funcName) => {
|
|
130
|
+
if (!cloudServerUrl)
|
|
131
|
+
return;
|
|
132
|
+
const permissionsUrl = `${cloudServerUrl}/api/public/permissions/${encodeURIComponent(packageName)}`;
|
|
133
|
+
fetch(permissionsUrl)
|
|
134
|
+
.then(async (res) => {
|
|
135
|
+
const contentType = res.headers.get("content-type");
|
|
136
|
+
if (!res.ok) {
|
|
137
|
+
console.warn(`Permission API returned ${res.status}: ${res.statusText}`);
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
if (contentType && contentType.includes("application/json")) {
|
|
141
|
+
return (await res.json());
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
const text = await res.text();
|
|
145
|
+
console.warn(`Permission API returned non-JSON response: ${text}`);
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
})
|
|
149
|
+
.then((data) => {
|
|
150
|
+
if (data) {
|
|
151
|
+
const hasCalendar = data.permissions.some((p) => p.type === "CALENDAR");
|
|
152
|
+
if (!hasCalendar) {
|
|
153
|
+
console.log((0, warning_1.calendarWarn)(funcName, packageName));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
})
|
|
157
|
+
.catch((err) => {
|
|
158
|
+
console.debug("Permission check skipped - endpoint unreachable:", err.message);
|
|
159
|
+
});
|
|
160
|
+
};
|
|
161
|
+
exports.calendarWarnLog = calendarWarnLog;
|
|
162
|
+
// Check if app has read notifications permission, warn if missing
|
|
163
|
+
const readNotificationWarnLog = (cloudServerUrl, packageName, funcName) => {
|
|
164
|
+
if (!cloudServerUrl)
|
|
165
|
+
return;
|
|
166
|
+
const permissionsUrl = `${cloudServerUrl}/api/public/permissions/${encodeURIComponent(packageName)}`;
|
|
167
|
+
fetch(permissionsUrl)
|
|
168
|
+
.then(async (res) => {
|
|
169
|
+
const contentType = res.headers.get("content-type");
|
|
170
|
+
if (!res.ok) {
|
|
171
|
+
console.warn(`Permission API returned ${res.status}: ${res.statusText}`);
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
if (contentType && contentType.includes("application/json")) {
|
|
175
|
+
return (await res.json());
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
const text = await res.text();
|
|
179
|
+
console.warn(`Permission API returned non-JSON response: ${text}`);
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
})
|
|
183
|
+
.then((data) => {
|
|
184
|
+
if (data) {
|
|
185
|
+
const hasReadNotifications = data.permissions.some((p) => p.type === "READ_NOTIFICATIONS");
|
|
186
|
+
if (!hasReadNotifications) {
|
|
187
|
+
console.log((0, warning_1.readNotficationWarn)(funcName, packageName));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
})
|
|
191
|
+
.catch((err) => {
|
|
192
|
+
console.debug("Permission check skipped - endpoint unreachable:", err.message);
|
|
193
|
+
});
|
|
194
|
+
};
|
|
195
|
+
exports.readNotificationWarnLog = readNotificationWarnLog;
|
|
196
|
+
// Check if app has post notifications permission, warn if missing
|
|
197
|
+
const postNotificationWarnLog = (cloudServerUrl, packageName, funcName) => {
|
|
198
|
+
if (!cloudServerUrl)
|
|
199
|
+
return;
|
|
200
|
+
const permissionsUrl = `${cloudServerUrl}/api/public/permissions/${encodeURIComponent(packageName)}`;
|
|
201
|
+
fetch(permissionsUrl)
|
|
202
|
+
.then(async (res) => {
|
|
203
|
+
const contentType = res.headers.get("content-type");
|
|
204
|
+
if (!res.ok) {
|
|
205
|
+
console.warn(`Permission API returned ${res.status}: ${res.statusText}`);
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
if (contentType && contentType.includes("application/json")) {
|
|
209
|
+
return (await res.json());
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
const text = await res.text();
|
|
213
|
+
console.warn(`Permission API returned non-JSON response: ${text}`);
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
})
|
|
217
|
+
.then((data) => {
|
|
218
|
+
if (data) {
|
|
219
|
+
const hasPostNotifications = data.permissions.some((p) => p.type === "POST_NOTIFICATIONS");
|
|
220
|
+
if (!hasPostNotifications) {
|
|
221
|
+
console.log((0, warning_1.postNotficationWarn)(funcName, packageName));
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
})
|
|
225
|
+
.catch((err) => {
|
|
226
|
+
console.debug("Permission check skipped - endpoint unreachable:", err.message);
|
|
227
|
+
});
|
|
228
|
+
};
|
|
229
|
+
exports.postNotificationWarnLog = postNotificationWarnLog;
|
|
230
|
+
// Check if app has camera permission, warn if missing
|
|
231
|
+
const cameraWarnLog = (cloudServerUrl, packageName, funcName) => {
|
|
232
|
+
if (!cloudServerUrl)
|
|
233
|
+
return;
|
|
234
|
+
const permissionsUrl = `${cloudServerUrl}/api/public/permissions/${encodeURIComponent(packageName)}`;
|
|
235
|
+
fetch(permissionsUrl)
|
|
236
|
+
.then(async (res) => {
|
|
237
|
+
const contentType = res.headers.get("content-type");
|
|
238
|
+
if (!res.ok) {
|
|
239
|
+
console.warn(`Permission API returned ${res.status}: ${res.statusText}`);
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
if (contentType && contentType.includes("application/json")) {
|
|
243
|
+
return (await res.json());
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
const text = await res.text();
|
|
247
|
+
console.warn(`Permission API returned non-JSON response: ${text}`);
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
})
|
|
251
|
+
.then((data) => {
|
|
252
|
+
if (data) {
|
|
253
|
+
const hasCamera = data.permissions.some((p) => p.type === "CAMERA");
|
|
254
|
+
if (!hasCamera) {
|
|
255
|
+
console.log((0, warning_1.cameraWarn)(funcName, packageName));
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
})
|
|
259
|
+
.catch((err) => {
|
|
260
|
+
console.debug("Permission check skipped - endpoint unreachable:", err.message);
|
|
261
|
+
});
|
|
262
|
+
};
|
|
263
|
+
exports.cameraWarnLog = cameraWarnLog;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mentra/sdk",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.27",
|
|
4
4
|
"description": "Build apps for MentraOS smartglasses. This SDK provides everything you need to create real-time smartglasses applications.",
|
|
5
5
|
"source": "src/index.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@logtail/pino": "^0.5.4",
|
|
31
31
|
"axios": "^1.8.1",
|
|
32
|
+
"boxen": "^8.0.1",
|
|
33
|
+
"chalk": "^5.6.2",
|
|
32
34
|
"cookie-parser": "^1.4.7",
|
|
33
35
|
"dotenv": "^16.4.0",
|
|
34
36
|
"express": "^4.18.2",
|
|
@@ -38,6 +40,7 @@
|
|
|
38
40
|
"multer": "^2.0.1",
|
|
39
41
|
"pino": "^9.6.0",
|
|
40
42
|
"pino-pretty": "^13.0.0",
|
|
43
|
+
"strip-ansi": "^7.1.2",
|
|
41
44
|
"ws": "^8.18.2"
|
|
42
45
|
},
|
|
43
46
|
"devDependencies": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/constants/messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,aAAa,GAAI,aAAa,MAAM,KAAG,MAcnD,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,aAAa,MAAM,KAAG,MAoBlD,CAAC"}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* messages.ts
|
|
4
|
-
*
|
|
5
|
-
* This file defines constant messages that should be displayed
|
|
6
|
-
* in the terminal to notify developers about new SDK releases.
|
|
7
|
-
*
|
|
8
|
-
* Each function generates a stylized ASCII message (banner-style)
|
|
9
|
-
* that highlights the latest SDK version and provides the npm install command.
|
|
10
|
-
* https://patorjk.com/software/taag/
|
|
11
|
-
*
|
|
12
|
-
* These messages are intended to be logged to the console or shown in
|
|
13
|
-
* terminal output so developers are aware of updates in a clear
|
|
14
|
-
* and visually distinct way.
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*/
|
|
18
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.newSDKUpdate = exports.newSDKUpdate2 = void 0;
|
|
20
|
-
const newSDKUpdate2 = (versionNumb) => {
|
|
21
|
-
return `
|
|
22
|
-
___
|
|
23
|
-
/__/:\\ ┬╔╗╔╔═╗╦ ╦ ╦ ╦╔═╗╔╦╗╔═╗╔╦╗╔═╗┬
|
|
24
|
-
| |:: \\ │║║║║╣ ║║║ ║ ║╠═╝ ║║╠═╣ ║ ║╣ │
|
|
25
|
-
| |:|: \\ o╝╚╝╚═╝╚╩╝ ╚═╝╩ ═╩╝╩ ╩ ╩ ╚═╝o
|
|
26
|
-
__|__|:|\\:\\ -------------------------------
|
|
27
|
-
/__/::::| \\:\\ SDK VERSION V${versionNumb} is out!
|
|
28
|
-
\\ \\:\\~~\\_\\ -------------------------------
|
|
29
|
-
\\ \\:\\ npm install @mentra/sdk@latest
|
|
30
|
-
\\ \\:\\
|
|
31
|
-
\\ \\:\\
|
|
32
|
-
\\__\\/
|
|
33
|
-
`;
|
|
34
|
-
};
|
|
35
|
-
exports.newSDKUpdate2 = newSDKUpdate2;
|
|
36
|
-
const newSDKUpdate = (versionNumb) => {
|
|
37
|
-
return `
|
|
38
|
-
|
|
39
|
-
/$$ /$$ /$$$$$$$$ /$$ /$$ /$$$$$$$$ /$$$$$$$ /$$$$$$
|
|
40
|
-
| $$$ /$$$| $$_____/| $$$ | $$|__ $$__/| $$__ $$ /$$__ $$
|
|
41
|
-
| $$$$ /$$$$| $$ | $$$$| $$ | $$ | $$ \ $$| $$ \ $$
|
|
42
|
-
| $$ $$/$$ $$| $$$$$ | $$ $$ $$ | $$ | $$$$$$$/| $$$$$$$$
|
|
43
|
-
| $$ $$$| $$| $$__/ | $$ $$$$ | $$ | $$__ $$| $$__ $$
|
|
44
|
-
| $$\ $ | $$| $$ | $$\ $$$ | $$ | $$ \ $$| $$ | $$
|
|
45
|
-
| $$ \/ | $$| $$$$$$$$| $$ \ $$ | $$ | $$ | $$| $$ | $$
|
|
46
|
-
|__/ |__/|________/|__/ \__/ |__/ |__/ |__/|__/ |__/
|
|
47
|
-
|
|
48
|
-
┬╔╗╔╔═╗╦ ╦ ╦ ╦╔═╗╔╦╗╔═╗╔╦╗╔═╗┬
|
|
49
|
-
│║║║║╣ ║║║ ║ ║╠═╝ ║║╠═╣ ║ ║╣ │
|
|
50
|
-
o╝╚╝╚═╝╚╩╝ ╚═╝╩ ═╩╝╩ ╩ ╩ ╚═╝o
|
|
51
|
-
-------------------------------
|
|
52
|
-
SDK VERSION V${versionNumb} is out!
|
|
53
|
-
-------------------------------
|
|
54
|
-
bun install @mentra/sdk@latest
|
|
55
|
-
`;
|
|
56
|
-
};
|
|
57
|
-
exports.newSDKUpdate = newSDKUpdate;
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { WebSocket } from "ws";
|
|
2
|
-
import { AppI, TranscriptI } from "./models";
|
|
3
|
-
import { DisplayRequest } from "./layouts";
|
|
4
|
-
import { Transform } from "stream";
|
|
5
|
-
import { ConversationTranscriber, PushAudioInputStream } from "microsoft-cognitiveservices-speech-sdk";
|
|
6
|
-
import { ExtendedStreamType } from "./streams";
|
|
7
|
-
import pino from "pino";
|
|
8
|
-
/**
|
|
9
|
-
* Session for an application
|
|
10
|
-
*/
|
|
11
|
-
/**
|
|
12
|
-
* Audio processor configuration
|
|
13
|
-
*/
|
|
14
|
-
export interface AudioProcessorConfig {
|
|
15
|
-
threshold: number;
|
|
16
|
-
ratio: number;
|
|
17
|
-
attack: number;
|
|
18
|
-
release: number;
|
|
19
|
-
gainDb: number;
|
|
20
|
-
sampleRate: number;
|
|
21
|
-
channels: number;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Audio processor interface
|
|
25
|
-
*/
|
|
26
|
-
export interface AudioProcessorI extends Transform {
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* The display manager interface
|
|
30
|
-
*/
|
|
31
|
-
export interface DisplayManagerI {
|
|
32
|
-
handleDisplayEvent(displayRequest: DisplayRequest, userSession: UserSession): boolean;
|
|
33
|
-
handleAppStart(packageName: string, userSession: UserSession): void;
|
|
34
|
-
handleAppStop(packageName: string, userSession: UserSession): void;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Currently active display
|
|
38
|
-
*/
|
|
39
|
-
export interface ActiveDisplay {
|
|
40
|
-
displayRequest: DisplayRequest;
|
|
41
|
-
startedAt: Date;
|
|
42
|
-
expiresAt?: Date;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* User session with glasses client
|
|
46
|
-
*/
|
|
47
|
-
export interface UserSession {
|
|
48
|
-
sessionId: string;
|
|
49
|
-
userId: string;
|
|
50
|
-
startTime: Date;
|
|
51
|
-
disconnectedAt: Date | null;
|
|
52
|
-
logger: pino.Logger;
|
|
53
|
-
installedApps: AppI[];
|
|
54
|
-
activeAppSessions: string[];
|
|
55
|
-
loadingApps: Set<string>;
|
|
56
|
-
appSubscriptions: Map<string, ExtendedStreamType[]> | object;
|
|
57
|
-
appConnections: Map<string, WebSocket>;
|
|
58
|
-
websocket: WebSocket;
|
|
59
|
-
transcript: TranscriptI;
|
|
60
|
-
pushStream?: PushAudioInputStream;
|
|
61
|
-
recognizer?: ConversationTranscriber;
|
|
62
|
-
isTranscribing: boolean;
|
|
63
|
-
lastAudioTimestamp?: number;
|
|
64
|
-
isGracefullyClosing?: boolean;
|
|
65
|
-
bufferedAudio: ArrayBufferLike[];
|
|
66
|
-
audioProcessor?: AudioProcessorI;
|
|
67
|
-
isAudioProcessing?: boolean;
|
|
68
|
-
whatToStream: ExtendedStreamType[];
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* App session within a user session
|
|
72
|
-
*/
|
|
73
|
-
//# sourceMappingURL=user-session.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"user-session.d.ts","sourceRoot":"","sources":["../../src/types/user-session.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,EAAE,IAAI,EAAe,WAAW,EAAE,MAAM,UAAU,CAAC;AAE1D,OAAO,EAAE,cAAc,EAAU,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACrB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAc,MAAM,WAAW,CAAC;AAE3D,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;GAEG;AAkBH;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,SAAS;CAAG;AAErD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kBAAkB,CAChB,cAAc,EAAE,cAAc,EAC9B,WAAW,EAAE,WAAW,GACvB,OAAO,CAAC;IACX,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IACpE,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;CACpE;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,cAAc,CAAC;IAC/B,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,CAAC,EAAE,IAAI,CAAC;CAClB;AAED;;GAEG;AAEH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,cAAc,EAAE,IAAI,GAAG,IAAI,CAAC;IAG5B,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;IAGpB,aAAa,EAAE,IAAI,EAAE,CAAC;IACtB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,GAAG,MAAM,CAAC;IAC7D,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAEvC,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,WAAW,CAAC;IAGxB,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAClC,UAAU,CAAC,EAAE,uBAAuB,CAAC;IACrC,cAAc,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAG9B,aAAa,EAAE,eAAe,EAAE,CAAC;IAGjC,cAAc,CAAC,EAAE,eAAe,CAAC;IACjC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAG5B,YAAY,EAAE,kBAAkB,EAAE,CAAC;CACpC;AAED;;GAEG"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// src/sessions.ts - Session-related interfaces
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
/**
|
|
5
|
-
* App session within a user session
|
|
6
|
-
*/
|
|
7
|
-
// This is not actually used anywhere so i commented it out.
|
|
8
|
-
// export interface AppSession {
|
|
9
|
-
// packageName: string;
|
|
10
|
-
// userId: string;
|
|
11
|
-
// subscriptions: StreamType[];
|
|
12
|
-
// settings: AppSettings;
|
|
13
|
-
// websocket?: WebSocket;
|
|
14
|
-
// state: AppState;
|
|
15
|
-
// startTime: Date;
|
|
16
|
-
// lastActiveTime: Date;
|
|
17
|
-
// }
|