@xenon-device-management/xenon 1.7.2 → 1.7.3

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 (38) hide show
  1. package/lib/package.json +2 -1
  2. package/lib/src/app/index.js +6 -0
  3. package/lib/src/app/routers/auth.js +30 -0
  4. package/lib/src/app/routers/capabilities.js +25 -0
  5. package/lib/src/app/routers/control.js +14 -0
  6. package/lib/src/app/routers/projects.js +55 -0
  7. package/lib/src/generated/client/edge.js +22 -4
  8. package/lib/src/generated/client/index-browser.js +19 -1
  9. package/lib/src/generated/client/index.d.ts +2376 -158
  10. package/lib/src/generated/client/index.js +22 -4
  11. package/lib/src/generated/client/package.json +1 -1
  12. package/lib/src/generated/client/schema.prisma +21 -0
  13. package/lib/src/generated/client/wasm.js +19 -1
  14. package/lib/src/middleware/authMiddleware.js +64 -3
  15. package/lib/src/prisma.js +1 -1
  16. package/lib/src/services/EventLogService.js +81 -0
  17. package/lib/src/services/ServerManager.js +36 -0
  18. package/lib/src/services/SocketServer.js +2 -0
  19. package/lib/src/services/artifacts/ArtifactStore.js +60 -0
  20. package/lib/src/services/recording/RecordingOrchestrator.js +4 -5
  21. package/lib/src/services/token/JwtKeyService.js +137 -0
  22. package/lib/src/services/token/StreamTicketService.js +61 -0
  23. package/lib/test/unit/ArtifactStore.spec.js +59 -0
  24. package/lib/test/unit/CapabilitiesRouter.spec.js +18 -0
  25. package/lib/test/unit/EventLogService.spec.js +67 -0
  26. package/lib/test/unit/JwtKeyService.spec.js +86 -0
  27. package/lib/test/unit/ProjectsRouter.spec.js +45 -0
  28. package/lib/test/unit/StreamTicketService.spec.js +95 -0
  29. package/lib/test/unit/TokenEndpoint.spec.js +68 -0
  30. package/lib/test/unit/authMiddleware.bearer.spec.js +102 -0
  31. package/lib/test/unit/authMiddleware.streamTicket.spec.js +217 -0
  32. package/lib/test/unit/recording-instrumentation.spec.js +8 -0
  33. package/lib/test/unit/recording-orchestrator.spec.js +14 -0
  34. package/lib/tsconfig.tsbuildinfo +1 -1
  35. package/package.json +2 -1
  36. package/prisma/migrations/20260717063103_event_log/migration.sql +15 -0
  37. package/prisma/migrations/20260717070124_project_entity/migration.sql +10 -0
  38. package/prisma/schema.prisma +21 -0
@@ -0,0 +1,217 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ require("reflect-metadata");
16
+ const chai_1 = require("chai");
17
+ const sinon_1 = __importDefault(require("sinon"));
18
+ const express_1 = __importDefault(require("express"));
19
+ const supertest_1 = __importDefault(require("supertest"));
20
+ const typedi_1 = require("typedi");
21
+ const fs_1 = __importDefault(require("fs"));
22
+ const os_1 = __importDefault(require("os"));
23
+ const path_1 = __importDefault(require("path"));
24
+ const JwtKeyService_1 = require("../../src/services/token/JwtKeyService");
25
+ const StreamTicketService_1 = require("../../src/services/token/StreamTicketService");
26
+ const authMiddleware_1 = require("../../src/middleware/authMiddleware");
27
+ const control_1 = __importDefault(require("../../src/app/routers/control"));
28
+ const device_store_1 = require("../../src/data-service/device-store");
29
+ const UserService_1 = require("../../src/services/UserService");
30
+ const ApiKeyService_1 = require("../../src/services/ApiKeyService");
31
+ const UserSessionService_1 = require("../../src/services/UserSessionService");
32
+ function fakeRes() {
33
+ const res = { statusCode: 200 };
34
+ res.status = (c) => {
35
+ res.statusCode = c;
36
+ return res;
37
+ };
38
+ res.json = (b) => {
39
+ res.body = b;
40
+ return res;
41
+ };
42
+ res.cookie = () => res;
43
+ return res;
44
+ }
45
+ describe('authMiddleware — stream-ticket branch', () => {
46
+ let dir;
47
+ let keySvc;
48
+ let ticketSvc;
49
+ beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
50
+ dir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'xenon-authmw-ticket-'));
51
+ keySvc = new JwtKeyService_1.JwtKeyService();
52
+ yield keySvc.init(dir);
53
+ typedi_1.Container.set(JwtKeyService_1.JwtKeyService, keySvc);
54
+ ticketSvc = new StreamTicketService_1.StreamTicketService();
55
+ typedi_1.Container.set(StreamTicketService_1.StreamTicketService, ticketSvc);
56
+ typedi_1.Container.set(UserService_1.UserService, { findById: sinon_1.default.stub().resolves(null) });
57
+ typedi_1.Container.set(ApiKeyService_1.ApiKeyService, {
58
+ verifyPair: sinon_1.default.stub().resolves(null),
59
+ verify: sinon_1.default.stub().resolves(null),
60
+ });
61
+ typedi_1.Container.set(UserSessionService_1.UserSessionService, { resolve: sinon_1.default.stub().resolves(null) });
62
+ }));
63
+ afterEach(() => {
64
+ sinon_1.default.restore();
65
+ typedi_1.Container.reset();
66
+ fs_1.default.rmSync(dir, { recursive: true, force: true });
67
+ });
68
+ // req.path here mirrors what authMiddleware actually sees at runtime:
69
+ // it's mounted directly on apiRouter (src/app/index.ts line 223) BEFORE
70
+ // ControlRouter.register(apiRouter) mounts '/control' onto that same
71
+ // apiRouter (control.ts: parentRouter.use('/control', router)), so the
72
+ // apiRouter-relative path for GET /xenon/api/control/UDID-1/stream is
73
+ // '/control/UDID-1/stream' — not the full external URL.
74
+ it('accepts a valid ticket for the matching udid on GET /control/:udid/stream', () => __awaiter(void 0, void 0, void 0, function* () {
75
+ const ticket = yield ticketSvc.mint('UDID-1', 'actor-1');
76
+ const req = {
77
+ method: 'GET',
78
+ path: '/control/UDID-1/stream',
79
+ query: { ticket },
80
+ headers: {},
81
+ };
82
+ const res = fakeRes();
83
+ const next = sinon_1.default.spy();
84
+ yield (0, authMiddleware_1.authMiddleware)(req, res, next);
85
+ (0, chai_1.expect)(next.calledOnce).to.equal(true);
86
+ (0, chai_1.expect)(req.auth.kind).to.equal('stream-ticket');
87
+ (0, chai_1.expect)(req.auth.userId).to.equal('actor-1');
88
+ }));
89
+ it('rejects a ticket minted for a different udid with 401 invalid ticket', () => __awaiter(void 0, void 0, void 0, function* () {
90
+ const ticket = yield ticketSvc.mint('UDID-1', 'actor-1');
91
+ const req = {
92
+ method: 'GET',
93
+ path: '/control/UDID-2/stream',
94
+ query: { ticket },
95
+ headers: {},
96
+ };
97
+ const res = fakeRes();
98
+ yield (0, authMiddleware_1.authMiddleware)(req, res, sinon_1.default.spy());
99
+ (0, chai_1.expect)(res.statusCode).to.equal(401);
100
+ (0, chai_1.expect)(res.body).to.deep.equal({ error: 'invalid ticket' });
101
+ }));
102
+ it('rejects reuse of an already-redeemed ticket', () => __awaiter(void 0, void 0, void 0, function* () {
103
+ const ticket = yield ticketSvc.mint('UDID-1', 'actor-1');
104
+ yield ticketSvc.redeem(ticket, 'UDID-1');
105
+ const req = {
106
+ method: 'GET',
107
+ path: '/control/UDID-1/stream',
108
+ query: { ticket },
109
+ headers: {},
110
+ };
111
+ const res = fakeRes();
112
+ yield (0, authMiddleware_1.authMiddleware)(req, res, sinon_1.default.spy());
113
+ (0, chai_1.expect)(res.statusCode).to.equal(401);
114
+ (0, chai_1.expect)(res.body).to.deep.equal({ error: 'invalid ticket' });
115
+ }));
116
+ it('does NOT match a sibling stream route (stream/status) even with a valid ticket', () => __awaiter(void 0, void 0, void 0, function* () {
117
+ const ticket = yield ticketSvc.mint('UDID-1', 'actor-1');
118
+ const req = {
119
+ method: 'GET',
120
+ path: '/control/UDID-1/stream/status',
121
+ query: { ticket },
122
+ headers: {},
123
+ };
124
+ const res = fakeRes();
125
+ yield (0, authMiddleware_1.authMiddleware)(req, res, sinon_1.default.spy());
126
+ // Falls through to the final unauthenticated 401, not the ticket branch.
127
+ (0, chai_1.expect)(res.statusCode).to.equal(401);
128
+ (0, chai_1.expect)(res.body).to.deep.equal({ error: 'unauthenticated' });
129
+ }));
130
+ it('does NOT match a POST to the stream route (ticket-mint or otherwise)', () => __awaiter(void 0, void 0, void 0, function* () {
131
+ const ticket = yield ticketSvc.mint('UDID-1', 'actor-1');
132
+ const req = {
133
+ method: 'POST',
134
+ path: '/control/UDID-1/stream',
135
+ query: { ticket },
136
+ headers: {},
137
+ };
138
+ const res = fakeRes();
139
+ yield (0, authMiddleware_1.authMiddleware)(req, res, sinon_1.default.spy());
140
+ (0, chai_1.expect)(res.statusCode).to.equal(401);
141
+ (0, chai_1.expect)(res.body).to.deep.equal({ error: 'unauthenticated' });
142
+ }));
143
+ it('ignores a non-string ticket query value (e.g. array from ?ticket=a&ticket=b)', () => __awaiter(void 0, void 0, void 0, function* () {
144
+ const req = {
145
+ method: 'GET',
146
+ path: '/control/UDID-1/stream',
147
+ query: { ticket: ['a', 'b'] },
148
+ headers: {},
149
+ };
150
+ const res = fakeRes();
151
+ yield (0, authMiddleware_1.authMiddleware)(req, res, sinon_1.default.spy());
152
+ (0, chai_1.expect)(res.statusCode).to.equal(401);
153
+ (0, chai_1.expect)(res.body).to.deep.equal({ error: 'unauthenticated' });
154
+ }));
155
+ });
156
+ // Mount-order guard: the hand-built-req tests above hardcode
157
+ // req.path='/control/UDID-1/stream', so they'd keep passing even if a future
158
+ // change to how authMiddleware / ControlRouter are mounted stopped delivering
159
+ // that apiRouter-relative path to the middleware — silently reopening "does
160
+ // the ticket branch even fire?". This block wires the REAL chain the same way
161
+ // src/app/index.ts does (apiRouter.use(authMiddleware); ControlRouter mounts
162
+ // '/control' onto apiRouter) and drives an actual HTTP request through it, so
163
+ // a regression in the mount path is caught end-to-end. The device store is
164
+ // stubbed to report "no such device", so a request that clears auth lands on
165
+ // the route handler's 404 — distinct from authMiddleware's 401. Asserting
166
+ // "not 401 unauthenticated" therefore proves the ticket branch fired.
167
+ describe('authMiddleware — stream-ticket branch (real mount-order, supertest)', () => {
168
+ let dir;
169
+ let app;
170
+ let ticketSvc;
171
+ beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
172
+ dir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'xenon-authmw-mount-'));
173
+ const keySvc = new JwtKeyService_1.JwtKeyService();
174
+ yield keySvc.init(dir);
175
+ typedi_1.Container.set(JwtKeyService_1.JwtKeyService, keySvc);
176
+ ticketSvc = new StreamTicketService_1.StreamTicketService();
177
+ typedi_1.Container.set(StreamTicketService_1.StreamTicketService, ticketSvc);
178
+ typedi_1.Container.set(UserService_1.UserService, { findById: sinon_1.default.stub().resolves(null) });
179
+ typedi_1.Container.set(ApiKeyService_1.ApiKeyService, {
180
+ verifyPair: sinon_1.default.stub().resolves(null),
181
+ verify: sinon_1.default.stub().resolves(null),
182
+ });
183
+ typedi_1.Container.set(UserSessionService_1.UserSessionService, { resolve: sinon_1.default.stub().resolves(null) });
184
+ // Clean 404 path: the GET /:udid/stream handler's first act is
185
+ // getDeviceInfo(udid) -> DeviceStoreFactory.getStore().findDevice(...).
186
+ // Return no device so the handler responds 404 'Device not found' the
187
+ // moment it runs — which only happens if auth (the ticket branch) passed.
188
+ sinon_1.default
189
+ .stub(device_store_1.DeviceStoreFactory, 'getStore')
190
+ .returns({ findDevice: sinon_1.default.stub().resolves(undefined) });
191
+ // Mount exactly like src/app/index.ts: authMiddleware directly on the
192
+ // apiRouter, THEN ControlRouter.register(apiRouter) mounts '/control'.
193
+ const apiRouter = express_1.default.Router();
194
+ apiRouter.use(authMiddleware_1.authMiddleware);
195
+ control_1.default.register(apiRouter);
196
+ app = (0, express_1.default)();
197
+ app.use('/xenon/api', apiRouter);
198
+ }));
199
+ afterEach(() => {
200
+ sinon_1.default.restore();
201
+ typedi_1.Container.reset();
202
+ fs_1.default.rmSync(dir, { recursive: true, force: true });
203
+ });
204
+ it('a valid ticket on GET /xenon/api/control/:udid/stream reaches the route (past 401)', () => __awaiter(void 0, void 0, void 0, function* () {
205
+ const ticket = yield ticketSvc.mint('UDID-1', 'actor-1');
206
+ const res = yield (0, supertest_1.default)(app).get('/xenon/api/control/UDID-1/stream').query({ ticket });
207
+ // The ticket branch fired: request cleared auth and hit the handler's
208
+ // device lookup (404), rather than being rejected at the middleware (401).
209
+ (0, chai_1.expect)(res.status).to.not.equal(401);
210
+ (0, chai_1.expect)(res.status).to.equal(404); // 'Device not found' from the stubbed store
211
+ }));
212
+ it('the SAME request without a ticket is rejected 401 (proves the guard is non-vacuous)', () => __awaiter(void 0, void 0, void 0, function* () {
213
+ const res = yield (0, supertest_1.default)(app).get('/xenon/api/control/UDID-1/stream');
214
+ (0, chai_1.expect)(res.status).to.equal(401);
215
+ (0, chai_1.expect)(res.body).to.deep.equal({ error: 'unauthenticated' });
216
+ }));
217
+ });
@@ -15,8 +15,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
15
15
  require("reflect-metadata");
16
16
  const chai_1 = require("chai");
17
17
  const sinon_1 = __importDefault(require("sinon"));
18
+ const os_1 = __importDefault(require("os"));
19
+ const typedi_1 = require("typedi");
18
20
  const api_1 = require("@opentelemetry/api");
19
21
  const attributes_1 = require("../../src/services/telemetry/attributes");
22
+ const ArtifactStore_1 = require("../../src/services/artifacts/ArtifactStore");
20
23
  // Stub metrics + trace BEFORE the module loads so the module-level
21
24
  // ensureOtelInstruments() picks up our mocks. Inline import after stubbing.
22
25
  function makeMockMeter() {
@@ -63,12 +66,17 @@ describe('RecordingOrchestrator instrumentation', () => {
63
66
  // Pre-stub once to get clean instrument creation in the SUT.
64
67
  getMeterStub = sinon_1.default.stub(api_1.metrics, 'getMeter');
65
68
  getTracerStub = sinon_1.default.stub(api_1.trace, 'getTracer');
69
+ // RecordingOrchestrator resolves ARTIFACT_STORE from the container at
70
+ // runtime (registered at boot in ServerManager); register it here so the
71
+ // path-construction helpers work under test.
72
+ typedi_1.Container.set(ArtifactStore_1.ARTIFACT_STORE, new ArtifactStore_1.FsArtifactStore(os_1.default.tmpdir()));
66
73
  // Now import — module-level let bindings will populate against the stub.
67
74
  RecordingOrchestratorMod = require('../../src/services/recording/RecordingOrchestrator');
68
75
  });
69
76
  after(() => {
70
77
  getMeterStub.restore();
71
78
  getTracerStub.restore();
79
+ typedi_1.Container.remove(ArtifactStore_1.ARTIFACT_STORE);
72
80
  });
73
81
  beforeEach(() => {
74
82
  mockMeterCtx = makeMockMeter();
@@ -48,10 +48,24 @@ Object.defineProperty(exports, "__esModule", { value: true });
48
48
  require("reflect-metadata");
49
49
  const chai_1 = require("chai");
50
50
  const sinon_1 = __importDefault(require("sinon"));
51
+ const os_1 = __importDefault(require("os"));
52
+ const typedi_1 = require("typedi");
51
53
  const RecordingOrchestrator_1 = require("../../src/services/recording/RecordingOrchestrator");
52
54
  const concurrency_gate_1 = require("../../src/services/recording/concurrency-gate");
55
+ const ArtifactStore_1 = require("../../src/services/artifacts/ArtifactStore");
53
56
  // Stub the device store factory (used to look up host).
54
57
  const deviceStoreModule = __importStar(require("../../src/data-service/device-store"));
58
+ // compositeOutputPath / per-device filePath construction resolve through
59
+ // ArtifactStore now (Task 7) — register a store the same way ServerManager
60
+ // does at boot, so RecordingOrchestrator's Container.get(ARTIFACT_STORE)
61
+ // doesn't throw in this unit test context.
62
+ before(() => {
63
+ typedi_1.Container.set(ArtifactStore_1.ARTIFACT_STORE, new ArtifactStore_1.FsArtifactStore(os_1.default.tmpdir()));
64
+ });
65
+ // Don't leave the global container polluted for later spec files in the run.
66
+ after(() => {
67
+ typedi_1.Container.remove(ArtifactStore_1.ARTIFACT_STORE);
68
+ });
55
69
  function makeOrch(overrides = {}) {
56
70
  var _a, _b, _c, _d, _e, _f, _g;
57
71
  const busyPrecheck = (_a = overrides.busyPrecheck) !== null && _a !== void 0 ? _a : { findBusy: sinon_1.default.stub().resolves([]) };
@@ -1 +1 @@
1
- {"root":["../src/InternalHttpClient.ts","../src/PluginContext.ts","../src/XenonCapabilityManager.ts","../src/chromeUtils.ts","../src/config.ts","../src/device-utils.ts","../src/index.ts","../src/logger.ts","../src/plugin.ts","../src/prisma.ts","../src/app/index.ts","../src/app/swagger-docs.ts","../src/app/swagger.ts","../src/app/routers/apikeys.ts","../src/app/routers/apps.ts","../src/app/routers/auth.ts","../src/app/routers/bug-report.ts","../src/app/routers/build-export.ts","../src/app/routers/config.ts","../src/app/routers/control.ts","../src/app/routers/dashboard.ts","../src/app/routers/grid.ts","../src/app/routers/interceptor.ts","../src/app/routers/ports.ts","../src/app/routers/processes.ts","../src/app/routers/profile.ts","../src/app/routers/recordings.ts","../src/app/routers/reservation.ts","../src/app/routers/sdk-leases.ts","../src/app/routers/sdk-version.ts","../src/app/routers/teams.ts","../src/app/routers/users.ts","../src/app/routers/webhook.ts","../src/commands/handle.ts","../src/commands/index.ts","../src/dashboard/asset-manager.ts","../src/dashboard/commands.ts","../src/dashboard/event-manager.ts","../src/dashboard/services/app-service.ts","../src/dashboard/services/failure-analysis-service.ts","../src/dashboard/services/session-service.ts","../src/data-service/CircuitBreaker.ts","../src/data-service/config-service.ts","../src/data-service/db.ts","../src/data-service/device-service.ts","../src/data-service/device-store.interface.ts","../src/data-service/device-store.ts","../src/data-service/pending-sessions-service.ts","../src/data-service/pluginArgs.ts","../src/data-service/prisma-service.ts","../src/data-service/prisma-store.ts","../src/data-service/queue-service.ts","../src/data-service/web-config-service.ts","../src/device-managers/AndroidDeviceManager.ts","../src/device-managers/ChromeDriverManager.ts","../src/device-managers/HealthMonitorService.ts","../src/device-managers/IOSDeviceManager.ts","../src/device-managers/NodeDevices.ts","../src/device-managers/iOSTracker.ts","../src/device-managers/index.ts","../src/device-managers/android/AndroidStreamService.ts","../src/device-managers/android/DeviceLockManager.ts","../src/device-managers/cloud/CapabilityManager.ts","../src/device-managers/cloud/Devices.ts","../src/device-managers/ios/IOSDiscoveryService.ts","../src/device-managers/ios/IOSStreamService.ts","../src/device-managers/ios/WDAClient.ts","../src/enums/Capabilities.ts","../src/enums/Cloud.ts","../src/enums/Platform.ts","../src/enums/SessionType.ts","../src/enums/SocketEvents.ts","../src/generated/client/default.d.ts","../src/generated/client/default.js","../src/generated/client/edge.d.ts","../src/generated/client/edge.js","../src/generated/client/index-browser.js","../src/generated/client/index.d.ts","../src/generated/client/index.js","../src/generated/client/wasm.d.ts","../src/generated/client/wasm.js","../src/generated/client/runtime/edge-esm.js","../src/generated/client/runtime/edge.js","../src/generated/client/runtime/index-browser.d.ts","../src/generated/client/runtime/index-browser.js","../src/generated/client/runtime/library.d.ts","../src/generated/client/runtime/library.js","../src/generated/client/runtime/react-native.js","../src/generated/client/runtime/wasm.js","../src/helpers/UniversalMjpegProxy.ts","../src/helpers/index.ts","../src/interceptors/CommandInterceptor.ts","../src/interfaces/ICloudManager.ts","../src/interfaces/IDevice.ts","../src/interfaces/IDeviceFilterOptions.ts","../src/interfaces/IDeviceManager.ts","../src/interfaces/IOptions.ts","../src/interfaces/IPluginArgs.ts","../src/interfaces/ISessionCapability.ts","../src/logging/sessionContext.ts","../src/middleware/authMiddleware.ts","../src/middleware/csrfMiddleware.ts","../src/middleware/leaseTokenMiddleware.ts","../src/middleware/loginRateLimiter.ts","../src/middleware/rateLimitMiddleware.ts","../src/middleware/roleGuard.ts","../src/middleware/scopeGuard.ts","../src/profiling/AndroidAppProfiler.ts","../src/proxy/wd-command-proxy.ts","../src/scripts/generate-database-migration.ts","../src/scripts/initialize-database.ts","../src/scripts/install-go-ios.ts","../src/scripts/prepare-prisma.ts","../src/scripts/run-migrations.ts","../src/services/AICommandService.ts","../src/services/AIService.ts","../src/services/ApiKeyService.ts","../src/services/CircuitBreaker.ts","../src/services/CleanupService.ts","../src/services/DeviceReconciler.ts","../src/services/EmailService.ts","../src/services/EventBus.ts","../src/services/InspectorService.ts","../src/services/InterceptorService.ts","../src/services/MetricsService.ts","../src/services/NetworkConditioningService.ts","../src/services/NotificationService.ts","../src/services/OrphanSweeper.ts","../src/services/PasswordResetService.ts","../src/services/PortAllocator.ts","../src/services/ProcessMetricsService.ts","../src/services/ProcessRegistry.ts","../src/services/RequestLogService.ts","../src/services/ResourceIsolationService.ts","../src/services/SecurityService.ts","../src/services/SelectorStateService.ts","../src/services/SelectorVerificationJob.ts","../src/services/ServerManager.ts","../src/services/SessionHeartbeatService.ts","../src/services/SessionLifecycleService.ts","../src/services/ShutdownCoordinator.ts","../src/services/SocketClient.ts","../src/services/SocketServer.ts","../src/services/TeamService.ts","../src/services/TracingService.ts","../src/services/UserService.ts","../src/services/UserSessionService.ts","../src/services/VideoPipelineService.ts","../src/services/autowait/AutowaitService.ts","../src/services/autowait/waitFor.ts","../src/services/bug-report/BugReportService.ts","../src/services/bug-report/archive.ts","../src/services/bug-report/har-collector.ts","../src/services/bug-report/manifest.ts","../src/services/bug-report/readme.ts","../src/services/bug-report/types.ts","../src/services/bug-report/video-slice.ts","../src/services/bug-report/window.ts","../src/services/healing/FuzzyXmlHealingProvider.ts","../src/services/healing/HealEtalonService.ts","../src/services/healing/HealedLocatorGenerator.ts","../src/services/healing/HealingMetrics.ts","../src/services/healing/HealingOrchestrator.ts","../src/services/healing/LlmHealingProvider.ts","../src/services/healing/OcrHealingProvider.ts","../src/services/healing/ResilioTreeHealingProvider.ts","../src/services/healing/VisualAiHealingProvider.ts","../src/services/healing/types.ts","../src/services/identity/bootstrap.ts","../src/services/identity/sessionCleanupCron.ts","../src/services/identity/userAuthorization.ts","../src/services/interceptor/AndroidProxyAdapter.ts","../src/services/interceptor/CertManager.ts","../src/services/interceptor/HarBuilder.ts","../src/services/interceptor/HostFilter.ts","../src/services/interceptor/MitmProxyHost.ts","../src/services/interceptor/MockEngine.ts","../src/services/interceptor/RequestBuffer.ts","../src/services/interceptor/SessionArchive.ts","../src/services/interceptor/types.ts","../src/services/lease/LeaseOrphanSweeper.ts","../src/services/lease/LeaseService.ts","../src/services/lease/buildCapabilityBag.ts","../src/services/lease/leaseToken.ts","../src/services/omni-vision/OmniVisionService.ts","../src/services/omni-vision/VisionAssertionService.ts","../src/services/ports/PortAllocatorClient.ts","../src/services/ports/PortAllocatorService.ts","../src/services/recording/RecordingOrchestrator.ts","../src/services/recording/annotation-render.ts","../src/services/recording/busy-precheck.ts","../src/services/recording/concurrency-gate.ts","../src/services/recording/manualLock.ts","../src/services/recording/proof-bundle.ts","../src/services/recording/recording-store.ts","../src/services/telemetry/attributes.ts","../src/sessions/CloudSession.ts","../src/sessions/LocalSession.ts","../src/sessions/RemoteSession.ts","../src/sessions/SessionManager.ts","../src/sessions/XenonSession.ts","../src/types/CLIArgs.ts","../src/types/CloudArgs.ts","../src/types/CloudSchema.ts","../src/types/DeviceType.ts","../src/types/DeviceUpdate.ts","../src/types/IOSDevice.ts","../src/types/Platform.ts","../src/types/SessionStatus.ts","../src/types/express.d.ts","../src/types/healing.d.ts","../src/types/identity.ts","../src/validators/CapabilityValidator.ts","../test/e2e/e2ehelper.ts","../test/e2e/plugin-harness.ts","../test/e2e/plugin.spec.ts","../test/e2e/startup-verification.spec.ts","../test/e2e/telemetry_verification.spec.ts","../test/e2e/video-recording-test.spec.js","../test/e2e/android/conf.spec.js","../test/e2e/android/conf2.spec.js","../test/e2e/android/conf3.spec.js","../test/e2e/hubnode/forward-request.spec.ts","../test/e2e/hubnode/hubnode.spec.ts","../test/e2e/ios/conf1.spec.js","../test/e2e/ios/conf2.spec.js","../test/helpers/seedUser.ts","../test/helpers/test-container.ts","../test/integration/androidDevices.spec.ts","../test/integration/auth-flow.spec.ts","../test/integration/auth-rate-limit.spec.ts","../test/integration/bug-report-route.spec.ts","../test/integration/cliArgs.js","../test/integration/cross-workflow.spec.ts","../test/integration/forgot-password-rate-limit.spec.ts","../test/integration/forgot-password.spec.ts","../test/integration/legacy-deprecation-headers.spec.ts","../test/integration/migration.spec.ts","../test/integration/node-pair-auth-rest.spec.ts","../test/integration/ports-router.spec.ts","../test/integration/profile-tokens.spec.ts","../test/integration/recordings-router.spec.ts","../test/integration/reset-revokes-sessions.spec.ts","../test/integration/role-matrix.spec.ts","../test/integration/sdk-leases-router.spec.ts","../test/integration/sdk-version.spec.ts","../test/integration/selector-state-flow.spec.ts","../test/integration/team-membership-migration.spec.ts","../test/integration/team-visibility-dashboard.spec.ts","../test/integration/team-visibility-grid.spec.ts","../test/integration/team-visibility-recordings.spec.ts","../test/integration/users-flow.spec.ts","../test/integration/users-lockout.spec.ts","../test/integration/ios/01iOSSimulator.spec.ts","../test/integration/ios/02iOSDevices.spec.ts","../test/unit/AndroidDeviceManager.spec.ts","../test/unit/ApiKeyService.test.ts","../test/unit/AutowaitService.spec.ts","../test/unit/ChromeDriverManager.spec.js","../test/unit/CleanupService.spec.ts","../test/unit/CommandInterceptor.autowait.spec.ts","../test/unit/DeviceModel.spec.ts","../test/unit/EmailService.test.ts","../test/unit/FuzzyXmlHealingProvider.test.ts","../test/unit/GetAdbOriginal.js","../test/unit/HealingCascade.test.ts","../test/unit/IOSDeviceManager.spec.js","../test/unit/OrphanSweeper.test.ts","../test/unit/PasswordResetService.test.ts","../test/unit/PortAllocator.test.ts","../test/unit/ProcessRegistry.test.ts","../test/unit/RemoteIOs.spec.js","../test/unit/ResilioTreeHealingProvider.test.ts","../test/unit/SessionHeartbeatWrite.test.ts","../test/unit/TeamService.test.ts","../test/unit/UserService.test.ts","../test/unit/UserSessionService.test.ts","../test/unit/XenonCapabilityManager.spec.ts","../test/unit/aggregate-hotspots-tuple-key.spec.ts","../test/unit/auth-me-auth-disabled.test.ts","../test/unit/authMiddleware.test.ts","../test/unit/bootstrap-identity.test.ts","../test/unit/build-export.spec.ts","../test/unit/busy-precheck.spec.ts","../test/unit/commands.spec.js","../test/unit/concurrency-gate.spec.ts","../test/unit/config.spec.js","../test/unit/device-service.spec.ts","../test/unit/device-utils.spec.ts","../test/unit/event-manager-regression-hook.spec.ts","../test/unit/extract-access-key-token-pair.test.ts","../test/unit/findAndLockDevice-leasemerge.spec.ts","../test/unit/healing-instrumentation.spec.ts","../test/unit/healing-state-endpoints.spec.ts","../test/unit/helpers.spec.ts","../test/unit/loginRateLimiter.test.ts","../test/unit/omni-vision.spec.ts","../test/unit/plugin.spec.ts","../test/unit/prisma.spec.ts","../test/unit/profile-router.test.ts","../test/unit/proof-bundle.spec.ts","../test/unit/rateLimitMiddleware.test.ts","../test/unit/recording-instrumentation.spec.ts","../test/unit/recording-orchestrator.spec.ts","../test/unit/recording-store.spec.ts","../test/unit/roleGuard.test.ts","../test/unit/run-migrations-fail-fast.test.ts","../test/unit/run-migrations.test.ts","../test/unit/selector-state-service.spec.ts","../test/unit/selector-verification-job.spec.ts","../test/unit/team-filter.test.ts","../test/unit/tracing-service-init.spec.ts","../test/unit/userAuthorization.test.ts","../test/unit/users-router.test.ts","../test/unit/video-pipeline-outputpath.spec.ts","../test/unit/bug-report/archive.spec.ts","../test/unit/bug-report/har-collector.spec.ts","../test/unit/bug-report/manifest.spec.ts","../test/unit/bug-report/readme.spec.ts","../test/unit/bug-report/route.spec.ts","../test/unit/bug-report/service.spec.ts","../test/unit/bug-report/video-slice.spec.ts","../test/unit/bug-report/window.spec.ts","../test/unit/fixtures/device.config.js","../test/unit/fixtures/devices.js","../test/unit/interceptor/AndroidProxyAdapter.spec.ts","../test/unit/interceptor/CertManager.spec.ts","../test/unit/interceptor/HarBuilder.spec.ts","../test/unit/interceptor/HostFilter.spec.ts","../test/unit/interceptor/MitmProxyHost.spec.ts","../test/unit/interceptor/MockEngine.spec.ts","../test/unit/interceptor/RequestBuffer.spec.ts","../test/unit/interceptor/SessionArchive.spec.ts","../test/unit/lease/LeaseOrphanSweeper.spec.ts","../test/unit/lease/LeaseService.spec.ts","../test/unit/lease/buildCapabilityBag.spec.ts","../test/unit/lease/leaseToken.spec.ts","../test/unit/ports/PortAllocatorService.spec.ts"],"version":"5.9.3"}
1
+ {"root":["../src/InternalHttpClient.ts","../src/PluginContext.ts","../src/XenonCapabilityManager.ts","../src/chromeUtils.ts","../src/config.ts","../src/device-utils.ts","../src/index.ts","../src/logger.ts","../src/plugin.ts","../src/prisma.ts","../src/app/index.ts","../src/app/swagger-docs.ts","../src/app/swagger.ts","../src/app/routers/apikeys.ts","../src/app/routers/apps.ts","../src/app/routers/auth.ts","../src/app/routers/bug-report.ts","../src/app/routers/build-export.ts","../src/app/routers/capabilities.ts","../src/app/routers/config.ts","../src/app/routers/control.ts","../src/app/routers/dashboard.ts","../src/app/routers/grid.ts","../src/app/routers/interceptor.ts","../src/app/routers/ports.ts","../src/app/routers/processes.ts","../src/app/routers/profile.ts","../src/app/routers/projects.ts","../src/app/routers/recordings.ts","../src/app/routers/reservation.ts","../src/app/routers/sdk-leases.ts","../src/app/routers/sdk-version.ts","../src/app/routers/teams.ts","../src/app/routers/users.ts","../src/app/routers/webhook.ts","../src/commands/handle.ts","../src/commands/index.ts","../src/dashboard/asset-manager.ts","../src/dashboard/commands.ts","../src/dashboard/event-manager.ts","../src/dashboard/services/app-service.ts","../src/dashboard/services/failure-analysis-service.ts","../src/dashboard/services/session-service.ts","../src/data-service/CircuitBreaker.ts","../src/data-service/config-service.ts","../src/data-service/db.ts","../src/data-service/device-service.ts","../src/data-service/device-store.interface.ts","../src/data-service/device-store.ts","../src/data-service/pending-sessions-service.ts","../src/data-service/pluginArgs.ts","../src/data-service/prisma-service.ts","../src/data-service/prisma-store.ts","../src/data-service/queue-service.ts","../src/data-service/web-config-service.ts","../src/device-managers/AndroidDeviceManager.ts","../src/device-managers/ChromeDriverManager.ts","../src/device-managers/HealthMonitorService.ts","../src/device-managers/IOSDeviceManager.ts","../src/device-managers/NodeDevices.ts","../src/device-managers/iOSTracker.ts","../src/device-managers/index.ts","../src/device-managers/android/AndroidStreamService.ts","../src/device-managers/android/DeviceLockManager.ts","../src/device-managers/cloud/CapabilityManager.ts","../src/device-managers/cloud/Devices.ts","../src/device-managers/ios/IOSDiscoveryService.ts","../src/device-managers/ios/IOSStreamService.ts","../src/device-managers/ios/WDAClient.ts","../src/enums/Capabilities.ts","../src/enums/Cloud.ts","../src/enums/Platform.ts","../src/enums/SessionType.ts","../src/enums/SocketEvents.ts","../src/generated/client/default.d.ts","../src/generated/client/default.js","../src/generated/client/edge.d.ts","../src/generated/client/edge.js","../src/generated/client/index-browser.js","../src/generated/client/index.d.ts","../src/generated/client/index.js","../src/generated/client/wasm.d.ts","../src/generated/client/wasm.js","../src/generated/client/runtime/edge-esm.js","../src/generated/client/runtime/edge.js","../src/generated/client/runtime/index-browser.d.ts","../src/generated/client/runtime/index-browser.js","../src/generated/client/runtime/library.d.ts","../src/generated/client/runtime/library.js","../src/generated/client/runtime/react-native.js","../src/generated/client/runtime/wasm.js","../src/helpers/UniversalMjpegProxy.ts","../src/helpers/index.ts","../src/interceptors/CommandInterceptor.ts","../src/interfaces/ICloudManager.ts","../src/interfaces/IDevice.ts","../src/interfaces/IDeviceFilterOptions.ts","../src/interfaces/IDeviceManager.ts","../src/interfaces/IOptions.ts","../src/interfaces/IPluginArgs.ts","../src/interfaces/ISessionCapability.ts","../src/logging/sessionContext.ts","../src/middleware/authMiddleware.ts","../src/middleware/csrfMiddleware.ts","../src/middleware/leaseTokenMiddleware.ts","../src/middleware/loginRateLimiter.ts","../src/middleware/rateLimitMiddleware.ts","../src/middleware/roleGuard.ts","../src/middleware/scopeGuard.ts","../src/profiling/AndroidAppProfiler.ts","../src/proxy/wd-command-proxy.ts","../src/scripts/generate-database-migration.ts","../src/scripts/initialize-database.ts","../src/scripts/install-go-ios.ts","../src/scripts/prepare-prisma.ts","../src/scripts/run-migrations.ts","../src/services/AICommandService.ts","../src/services/AIService.ts","../src/services/ApiKeyService.ts","../src/services/CircuitBreaker.ts","../src/services/CleanupService.ts","../src/services/DeviceReconciler.ts","../src/services/EmailService.ts","../src/services/EventBus.ts","../src/services/EventLogService.ts","../src/services/InspectorService.ts","../src/services/InterceptorService.ts","../src/services/MetricsService.ts","../src/services/NetworkConditioningService.ts","../src/services/NotificationService.ts","../src/services/OrphanSweeper.ts","../src/services/PasswordResetService.ts","../src/services/PortAllocator.ts","../src/services/ProcessMetricsService.ts","../src/services/ProcessRegistry.ts","../src/services/RequestLogService.ts","../src/services/ResourceIsolationService.ts","../src/services/SecurityService.ts","../src/services/SelectorStateService.ts","../src/services/SelectorVerificationJob.ts","../src/services/ServerManager.ts","../src/services/SessionHeartbeatService.ts","../src/services/SessionLifecycleService.ts","../src/services/ShutdownCoordinator.ts","../src/services/SocketClient.ts","../src/services/SocketServer.ts","../src/services/TeamService.ts","../src/services/TracingService.ts","../src/services/UserService.ts","../src/services/UserSessionService.ts","../src/services/VideoPipelineService.ts","../src/services/artifacts/ArtifactStore.ts","../src/services/autowait/AutowaitService.ts","../src/services/autowait/waitFor.ts","../src/services/bug-report/BugReportService.ts","../src/services/bug-report/archive.ts","../src/services/bug-report/har-collector.ts","../src/services/bug-report/manifest.ts","../src/services/bug-report/readme.ts","../src/services/bug-report/types.ts","../src/services/bug-report/video-slice.ts","../src/services/bug-report/window.ts","../src/services/healing/FuzzyXmlHealingProvider.ts","../src/services/healing/HealEtalonService.ts","../src/services/healing/HealedLocatorGenerator.ts","../src/services/healing/HealingMetrics.ts","../src/services/healing/HealingOrchestrator.ts","../src/services/healing/LlmHealingProvider.ts","../src/services/healing/OcrHealingProvider.ts","../src/services/healing/ResilioTreeHealingProvider.ts","../src/services/healing/VisualAiHealingProvider.ts","../src/services/healing/types.ts","../src/services/identity/bootstrap.ts","../src/services/identity/sessionCleanupCron.ts","../src/services/identity/userAuthorization.ts","../src/services/interceptor/AndroidProxyAdapter.ts","../src/services/interceptor/CertManager.ts","../src/services/interceptor/HarBuilder.ts","../src/services/interceptor/HostFilter.ts","../src/services/interceptor/MitmProxyHost.ts","../src/services/interceptor/MockEngine.ts","../src/services/interceptor/RequestBuffer.ts","../src/services/interceptor/SessionArchive.ts","../src/services/interceptor/types.ts","../src/services/lease/LeaseOrphanSweeper.ts","../src/services/lease/LeaseService.ts","../src/services/lease/buildCapabilityBag.ts","../src/services/lease/leaseToken.ts","../src/services/omni-vision/OmniVisionService.ts","../src/services/omni-vision/VisionAssertionService.ts","../src/services/ports/PortAllocatorClient.ts","../src/services/ports/PortAllocatorService.ts","../src/services/recording/RecordingOrchestrator.ts","../src/services/recording/annotation-render.ts","../src/services/recording/busy-precheck.ts","../src/services/recording/concurrency-gate.ts","../src/services/recording/manualLock.ts","../src/services/recording/proof-bundle.ts","../src/services/recording/recording-store.ts","../src/services/telemetry/attributes.ts","../src/services/token/JwtKeyService.ts","../src/services/token/StreamTicketService.ts","../src/sessions/CloudSession.ts","../src/sessions/LocalSession.ts","../src/sessions/RemoteSession.ts","../src/sessions/SessionManager.ts","../src/sessions/XenonSession.ts","../src/types/CLIArgs.ts","../src/types/CloudArgs.ts","../src/types/CloudSchema.ts","../src/types/DeviceType.ts","../src/types/DeviceUpdate.ts","../src/types/IOSDevice.ts","../src/types/Platform.ts","../src/types/SessionStatus.ts","../src/types/express.d.ts","../src/types/healing.d.ts","../src/types/identity.ts","../src/validators/CapabilityValidator.ts","../test/e2e/e2ehelper.ts","../test/e2e/plugin-harness.ts","../test/e2e/plugin.spec.ts","../test/e2e/startup-verification.spec.ts","../test/e2e/telemetry_verification.spec.ts","../test/e2e/video-recording-test.spec.js","../test/e2e/android/conf.spec.js","../test/e2e/android/conf2.spec.js","../test/e2e/android/conf3.spec.js","../test/e2e/hubnode/forward-request.spec.ts","../test/e2e/hubnode/hubnode.spec.ts","../test/e2e/ios/conf1.spec.js","../test/e2e/ios/conf2.spec.js","../test/helpers/seedUser.ts","../test/helpers/test-container.ts","../test/integration/androidDevices.spec.ts","../test/integration/auth-flow.spec.ts","../test/integration/auth-rate-limit.spec.ts","../test/integration/bug-report-route.spec.ts","../test/integration/cliArgs.js","../test/integration/cross-workflow.spec.ts","../test/integration/forgot-password-rate-limit.spec.ts","../test/integration/forgot-password.spec.ts","../test/integration/legacy-deprecation-headers.spec.ts","../test/integration/migration.spec.ts","../test/integration/node-pair-auth-rest.spec.ts","../test/integration/ports-router.spec.ts","../test/integration/profile-tokens.spec.ts","../test/integration/recordings-router.spec.ts","../test/integration/reset-revokes-sessions.spec.ts","../test/integration/role-matrix.spec.ts","../test/integration/sdk-leases-router.spec.ts","../test/integration/sdk-version.spec.ts","../test/integration/selector-state-flow.spec.ts","../test/integration/team-membership-migration.spec.ts","../test/integration/team-visibility-dashboard.spec.ts","../test/integration/team-visibility-grid.spec.ts","../test/integration/team-visibility-recordings.spec.ts","../test/integration/users-flow.spec.ts","../test/integration/users-lockout.spec.ts","../test/integration/ios/01iOSSimulator.spec.ts","../test/integration/ios/02iOSDevices.spec.ts","../test/unit/AndroidDeviceManager.spec.ts","../test/unit/ApiKeyService.test.ts","../test/unit/ArtifactStore.spec.ts","../test/unit/AutowaitService.spec.ts","../test/unit/CapabilitiesRouter.spec.ts","../test/unit/ChromeDriverManager.spec.js","../test/unit/CleanupService.spec.ts","../test/unit/CommandInterceptor.autowait.spec.ts","../test/unit/DeviceModel.spec.ts","../test/unit/EmailService.test.ts","../test/unit/EventLogService.spec.ts","../test/unit/FuzzyXmlHealingProvider.test.ts","../test/unit/GetAdbOriginal.js","../test/unit/HealingCascade.test.ts","../test/unit/IOSDeviceManager.spec.js","../test/unit/JwtKeyService.spec.ts","../test/unit/OrphanSweeper.test.ts","../test/unit/PasswordResetService.test.ts","../test/unit/PortAllocator.test.ts","../test/unit/ProcessRegistry.test.ts","../test/unit/ProjectsRouter.spec.ts","../test/unit/RemoteIOs.spec.js","../test/unit/ResilioTreeHealingProvider.test.ts","../test/unit/SessionHeartbeatWrite.test.ts","../test/unit/StreamTicketService.spec.ts","../test/unit/TeamService.test.ts","../test/unit/TokenEndpoint.spec.ts","../test/unit/UserService.test.ts","../test/unit/UserSessionService.test.ts","../test/unit/XenonCapabilityManager.spec.ts","../test/unit/aggregate-hotspots-tuple-key.spec.ts","../test/unit/auth-me-auth-disabled.test.ts","../test/unit/authMiddleware.bearer.spec.ts","../test/unit/authMiddleware.streamTicket.spec.ts","../test/unit/authMiddleware.test.ts","../test/unit/bootstrap-identity.test.ts","../test/unit/build-export.spec.ts","../test/unit/busy-precheck.spec.ts","../test/unit/commands.spec.js","../test/unit/concurrency-gate.spec.ts","../test/unit/config.spec.js","../test/unit/device-service.spec.ts","../test/unit/device-utils.spec.ts","../test/unit/event-manager-regression-hook.spec.ts","../test/unit/extract-access-key-token-pair.test.ts","../test/unit/findAndLockDevice-leasemerge.spec.ts","../test/unit/healing-instrumentation.spec.ts","../test/unit/healing-state-endpoints.spec.ts","../test/unit/helpers.spec.ts","../test/unit/loginRateLimiter.test.ts","../test/unit/omni-vision.spec.ts","../test/unit/plugin.spec.ts","../test/unit/prisma.spec.ts","../test/unit/profile-router.test.ts","../test/unit/proof-bundle.spec.ts","../test/unit/rateLimitMiddleware.test.ts","../test/unit/recording-instrumentation.spec.ts","../test/unit/recording-orchestrator.spec.ts","../test/unit/recording-store.spec.ts","../test/unit/roleGuard.test.ts","../test/unit/run-migrations-fail-fast.test.ts","../test/unit/run-migrations.test.ts","../test/unit/selector-state-service.spec.ts","../test/unit/selector-verification-job.spec.ts","../test/unit/team-filter.test.ts","../test/unit/tracing-service-init.spec.ts","../test/unit/userAuthorization.test.ts","../test/unit/users-router.test.ts","../test/unit/video-pipeline-outputpath.spec.ts","../test/unit/bug-report/archive.spec.ts","../test/unit/bug-report/har-collector.spec.ts","../test/unit/bug-report/manifest.spec.ts","../test/unit/bug-report/readme.spec.ts","../test/unit/bug-report/route.spec.ts","../test/unit/bug-report/service.spec.ts","../test/unit/bug-report/video-slice.spec.ts","../test/unit/bug-report/window.spec.ts","../test/unit/fixtures/device.config.js","../test/unit/fixtures/devices.js","../test/unit/interceptor/AndroidProxyAdapter.spec.ts","../test/unit/interceptor/CertManager.spec.ts","../test/unit/interceptor/HarBuilder.spec.ts","../test/unit/interceptor/HostFilter.spec.ts","../test/unit/interceptor/MitmProxyHost.spec.ts","../test/unit/interceptor/MockEngine.spec.ts","../test/unit/interceptor/RequestBuffer.spec.ts","../test/unit/interceptor/SessionArchive.spec.ts","../test/unit/lease/LeaseOrphanSweeper.spec.ts","../test/unit/lease/LeaseService.spec.ts","../test/unit/lease/buildCapabilityBag.spec.ts","../test/unit/lease/leaseToken.spec.ts","../test/unit/ports/PortAllocatorService.spec.ts"],"version":"5.9.3"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xenon-device-management/xenon",
3
- "version": "1.7.2",
3
+ "version": "1.7.3",
4
4
  "description": "Xenon - Intelligent Mobile Infrastructure. A self-healing device orchestration platform for Appium.",
5
5
  "main": "./lib/src/index.js",
6
6
  "exports": {
@@ -92,6 +92,7 @@
92
92
  "http-proxy-middleware": "^3.0.0-beta.1",
93
93
  "https-proxy-agent": "7.0.2",
94
94
  "ip": "^1.1.8",
95
+ "jose": "^5.10.0",
95
96
  "jsonschema": "1.4.1",
96
97
  "lodash": "^4.17.21",
97
98
  "lokijs": "^1.5.12",
@@ -0,0 +1,15 @@
1
+ -- CreateTable
2
+ CREATE TABLE "EventLog" (
3
+ "id" TEXT NOT NULL PRIMARY KEY,
4
+ "type" TEXT NOT NULL,
5
+ "payload" TEXT NOT NULL,
6
+ "correlationId" TEXT,
7
+ "teamId" TEXT,
8
+ "occurredAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
9
+ );
10
+
11
+ -- CreateIndex
12
+ CREATE INDEX "EventLog_type_occurredAt_idx" ON "EventLog"("type", "occurredAt");
13
+
14
+ -- CreateIndex
15
+ CREATE INDEX "EventLog_occurredAt_idx" ON "EventLog"("occurredAt");
@@ -0,0 +1,10 @@
1
+ -- CreateTable
2
+ CREATE TABLE "Project" (
3
+ "id" TEXT NOT NULL PRIMARY KEY,
4
+ "name" TEXT NOT NULL,
5
+ "teamId" TEXT,
6
+ "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
7
+ );
8
+
9
+ -- CreateIndex
10
+ CREATE INDEX "Project_teamId_idx" ON "Project"("teamId");
@@ -437,3 +437,24 @@ model TeamMember {
437
437
  @@id([teamId, userId])
438
438
  @@index([userId])
439
439
  }
440
+
441
+ model EventLog {
442
+ id String @id @default(cuid())
443
+ type String
444
+ payload String // JSON string — portable, no SQLite-isms
445
+ correlationId String?
446
+ teamId String?
447
+ occurredAt DateTime @default(now())
448
+
449
+ @@index([type, occurredAt])
450
+ @@index([occurredAt])
451
+ }
452
+
453
+ model Project {
454
+ id String @id @default(cuid())
455
+ name String
456
+ teamId String?
457
+ createdAt DateTime @default(now())
458
+
459
+ @@index([teamId])
460
+ }