@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.
Files changed (68) hide show
  1. package/dist/app/server/index.d.ts +2 -0
  2. package/dist/app/server/index.d.ts.map +1 -1
  3. package/dist/app/server/index.js +48 -26
  4. package/dist/app/session/dashboard.d.ts +7 -7
  5. package/dist/app/session/dashboard.d.ts.map +1 -1
  6. package/dist/app/session/dashboard.js +12 -12
  7. package/dist/app/session/events.d.ts +3 -1
  8. package/dist/app/session/events.d.ts.map +1 -1
  9. package/dist/app/session/events.js +12 -2
  10. package/dist/app/session/index.d.ts +1 -1
  11. package/dist/app/session/index.d.ts.map +1 -1
  12. package/dist/app/session/index.js +12 -7
  13. package/dist/app/session/modules/audio.js +1 -1
  14. package/dist/app/session/modules/camera.d.ts +17 -0
  15. package/dist/app/session/modules/camera.d.ts.map +1 -1
  16. package/dist/app/session/modules/camera.js +27 -0
  17. package/dist/app/session/modules/location.d.ts.map +1 -1
  18. package/dist/app/session/modules/location.js +3 -0
  19. package/dist/constants/log-messages/color.d.ts +5 -0
  20. package/dist/constants/log-messages/color.d.ts.map +1 -0
  21. package/dist/constants/log-messages/color.js +14 -0
  22. package/dist/constants/log-messages/logos.d.ts +4 -0
  23. package/dist/constants/log-messages/logos.d.ts.map +1 -0
  24. package/dist/constants/log-messages/logos.js +48 -0
  25. package/dist/constants/{messages.d.ts → log-messages/updates.d.ts} +2 -3
  26. package/dist/constants/log-messages/updates.d.ts.map +1 -0
  27. package/dist/constants/log-messages/updates.js +55 -0
  28. package/dist/constants/log-messages/warning.d.ts +8 -0
  29. package/dist/constants/log-messages/warning.d.ts.map +1 -0
  30. package/dist/constants/log-messages/warning.js +89 -0
  31. package/dist/index.d.ts +2 -3
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +18 -15
  34. package/dist/logging/logger.d.ts +2 -1
  35. package/dist/logging/logger.d.ts.map +1 -1
  36. package/dist/types/enums.d.ts +0 -20
  37. package/dist/types/enums.d.ts.map +1 -1
  38. package/dist/types/enums.js +2 -25
  39. package/dist/types/index.d.ts +1 -2
  40. package/dist/types/index.d.ts.map +1 -1
  41. package/dist/types/index.js +0 -2
  42. package/dist/types/layouts.d.ts +3 -3
  43. package/dist/types/layouts.d.ts.map +1 -1
  44. package/dist/types/message-types.d.ts +6 -4
  45. package/dist/types/message-types.d.ts.map +1 -1
  46. package/dist/types/message-types.js +13 -13
  47. package/dist/types/messages/base.d.ts.map +1 -1
  48. package/dist/types/messages/cloud-to-app.d.ts +9 -0
  49. package/dist/types/messages/cloud-to-app.d.ts.map +1 -1
  50. package/dist/types/messages/cloud-to-glasses.d.ts +15 -8
  51. package/dist/types/messages/cloud-to-glasses.d.ts.map +1 -1
  52. package/dist/types/messages/glasses-to-cloud.d.ts +99 -9
  53. package/dist/types/messages/glasses-to-cloud.d.ts.map +1 -1
  54. package/dist/types/messages/glasses-to-cloud.js +45 -1
  55. package/dist/types/models.d.ts.map +1 -1
  56. package/dist/types/streams.js +1 -1
  57. package/dist/types/webhooks.d.ts +4 -51
  58. package/dist/types/webhooks.d.ts.map +1 -1
  59. package/dist/types/webhooks.js +0 -27
  60. package/dist/utils/permissions-utils.d.ts +8 -0
  61. package/dist/utils/permissions-utils.d.ts.map +1 -0
  62. package/dist/utils/permissions-utils.js +263 -0
  63. package/package.json +4 -1
  64. package/dist/constants/messages.d.ts.map +0 -1
  65. package/dist/constants/messages.js +0 -57
  66. package/dist/types/user-session.d.ts +0 -73
  67. package/dist/types/user-session.d.ts.map +0 -1
  68. package/dist/types/user-session.js +0 -17
@@ -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: 'user_disabled' | 'system_stop' | 'error';
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 | ServerRegistrationWebhookRequest | SessionRecoveryWebhookRequest | ServerHeartbeatWebhookRequest;
45
+ export type WebhookRequest = SessionWebhookRequest | StopWebhookRequest;
81
46
  /**
82
47
  * Response to a webhook request
83
48
  */
84
49
  export interface WebhookResponse {
85
- status: 'success' | 'error';
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;IAE7B,uCAAuC;IACvC,mBAAmB,wBAAwB;IAE3C,gCAAgC;IAChC,gBAAgB,qBAAqB;IAErC,+BAA+B;IAC/B,gBAAgB,qBAAqB;CACtC;AAEC;;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;CAEhC;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;;;;GAIG;AACH,MAAM,WAAW,gCAAiC,SAAQ,kBAAkB;IAC1E,IAAI,EAAE,kBAAkB,CAAC,mBAAmB,CAAC;IAC7C,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,6BAA8B,SAAQ,kBAAkB;IACvE,IAAI,EAAE,kBAAkB,CAAC,gBAAgB,CAAC;IAC1C,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED;;;;GAIG;AACH,MAAM,WAAW,6BAA8B,SAAQ,kBAAkB;IACvE,IAAI,EAAE,kBAAkB,CAAC,gBAAgB,CAAC;IAC1C,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,qBAAqB,GACrB,kBAAkB,GAClB,gCAAgC,GAChC,6BAA6B,GAC7B,6BAA6B,CAAC;AAElC;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,IAAI,qBAAqB,CAEjG;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,IAAI,kBAAkB,CAE3F;AAED;;GAEG;AACH,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,cAAc,GACtB,OAAO,IAAI,gCAAgC,CAE7C;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,cAAc,GACtB,OAAO,IAAI,6BAA6B,CAE1C;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,cAAc,GACtB,OAAO,IAAI,6BAA6B,CAE1C"}
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"}
@@ -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.24",
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
- // }