@xenon-device-management/xenon 1.1.0
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/README.md +446 -0
- package/lib/package.json +207 -0
- package/lib/public/assets/Layouts-7IT8aFLI.js +11 -0
- package/lib/public/assets/Layouts-DPMls9vh.css +1 -0
- package/lib/public/assets/ai-settings-BbnfgdEx.js +11 -0
- package/lib/public/assets/apps-CRMrI4_p.js +16 -0
- package/lib/public/assets/apps-CcM77dgg.css +1 -0
- package/lib/public/assets/badge-B1nKs8zj.css +1 -0
- package/lib/public/assets/badge-CSvl5xIU.js +11 -0
- package/lib/public/assets/button-CJlKn4PZ.css +1 -0
- package/lib/public/assets/button-CvLaGFYj.js +26 -0
- package/lib/public/assets/calendar-6w-D6Oaw.js +6 -0
- package/lib/public/assets/clock-DcdeWBPr.js +6 -0
- package/lib/public/assets/cpu-DiSoXT9n.js +6 -0
- package/lib/public/assets/device-explorer-CajM63OJ.js +193 -0
- package/lib/public/assets/device-explorer-CxdUAoTL.css +1 -0
- package/lib/public/assets/index-ByQwMN5T.js +174 -0
- package/lib/public/assets/index-C1DBaoSh.js +1 -0
- package/lib/public/assets/index-qzCez_kk.css +1 -0
- package/lib/public/assets/lock-B23ibZmo.js +6 -0
- package/lib/public/assets/maintenance-settings-CirzA6yG.js +6 -0
- package/lib/public/assets/mouse-pointer-2-Cz76SHFb.js +6 -0
- package/lib/public/assets/plus-BBwlIevt.js +6 -0
- package/lib/public/assets/session-dashboard-C2k7FFv_.css +1 -0
- package/lib/public/assets/session-dashboard-HPDtwPOZ.js +62 -0
- package/lib/public/assets/settings-DrZsZwdc.js +1 -0
- package/lib/public/assets/trash-2-DQpvzJec.js +6 -0
- package/lib/public/assets/useSocket-Dxsqae2a.js +16 -0
- package/lib/public/assets/webhook-settings-CDPgsgkb.css +1 -0
- package/lib/public/assets/webhook-settings-Cp-B4Nrw.js +1 -0
- package/lib/public/assets/zap-DovP6iow.js +6 -0
- package/lib/public/favicon.ico +0 -0
- package/lib/public/favicon.png +0 -0
- package/lib/public/favicon.svg +9 -0
- package/lib/public/index.html +46 -0
- package/lib/public/logo.svg +17 -0
- package/lib/public/logo192.png +0 -0
- package/lib/public/logo512.png +0 -0
- package/lib/public/manifest.json +25 -0
- package/lib/public/robots.txt +3 -0
- package/lib/schema.json +348 -0
- package/lib/src/InternalHttpClient.js +212 -0
- package/lib/src/PluginContext.js +29 -0
- package/lib/src/XenonCapabilityManager.js +199 -0
- package/lib/src/app/index.js +167 -0
- package/lib/src/app/routers/apps.js +79 -0
- package/lib/src/app/routers/config.js +131 -0
- package/lib/src/app/routers/control.js +835 -0
- package/lib/src/app/routers/dashboard.js +301 -0
- package/lib/src/app/routers/grid.js +352 -0
- package/lib/src/app/routers/reservation.js +190 -0
- package/lib/src/app/routers/webhook.js +83 -0
- package/lib/src/app/swagger-docs.js +203 -0
- package/lib/src/app/swagger.js +366 -0
- package/lib/src/chromeUtils.js +148 -0
- package/lib/src/commands/handle.js +19 -0
- package/lib/src/commands/index.js +8 -0
- package/lib/src/config.js +73 -0
- package/lib/src/dashboard/asset-manager.js +84 -0
- package/lib/src/dashboard/commands.js +284 -0
- package/lib/src/dashboard/event-manager.js +699 -0
- package/lib/src/dashboard/services/app-service.js +134 -0
- package/lib/src/dashboard/services/failure-analysis-service.js +173 -0
- package/lib/src/dashboard/services/session-service.js +113 -0
- package/lib/src/data-service/CircuitBreaker.js +83 -0
- package/lib/src/data-service/config-service.js +155 -0
- package/lib/src/data-service/db.js +122 -0
- package/lib/src/data-service/device-service.js +320 -0
- package/lib/src/data-service/device-store.interface.js +2 -0
- package/lib/src/data-service/device-store.js +345 -0
- package/lib/src/data-service/pending-sessions-service.js +25 -0
- package/lib/src/data-service/pluginArgs.js +25 -0
- package/lib/src/data-service/prisma-service.js +31 -0
- package/lib/src/data-service/prisma-store.js +385 -0
- package/lib/src/data-service/queue-service.js +150 -0
- package/lib/src/data-service/web-config-service.js +130 -0
- package/lib/src/device-managers/AndroidDeviceManager.js +1155 -0
- package/lib/src/device-managers/ChromeDriverManager.js +68 -0
- package/lib/src/device-managers/HealthMonitorService.js +325 -0
- package/lib/src/device-managers/IOSDeviceManager.js +351 -0
- package/lib/src/device-managers/NodeDevices.js +82 -0
- package/lib/src/device-managers/android/AndroidStreamService.js +370 -0
- package/lib/src/device-managers/android/DeviceLockManager.js +45 -0
- package/lib/src/device-managers/cloud/CapabilityManager.js +26 -0
- package/lib/src/device-managers/cloud/Devices.js +86 -0
- package/lib/src/device-managers/iOSTracker.js +44 -0
- package/lib/src/device-managers/index.js +89 -0
- package/lib/src/device-managers/ios/IOSDiscoveryService.js +268 -0
- package/lib/src/device-managers/ios/IOSStreamService.js +893 -0
- package/lib/src/device-managers/ios/WDAClient.js +866 -0
- package/lib/src/device-utils.js +663 -0
- package/lib/src/enums/Capabilities.js +8 -0
- package/lib/src/enums/Cloud.js +11 -0
- package/lib/src/enums/Platform.js +9 -0
- package/lib/src/enums/SessionType.js +9 -0
- package/lib/src/enums/SocketEvents.js +15 -0
- package/lib/src/helpers/UniversalMjpegProxy.js +273 -0
- package/lib/src/helpers/index.js +229 -0
- package/lib/src/index.js +95 -0
- package/lib/src/interceptors/CommandInterceptor.js +524 -0
- package/lib/src/interfaces/ICloudManager.js +2 -0
- package/lib/src/interfaces/IDevice.js +2 -0
- package/lib/src/interfaces/IDeviceFilterOptions.js +2 -0
- package/lib/src/interfaces/IDeviceManager.js +2 -0
- package/lib/src/interfaces/IOptions.js +2 -0
- package/lib/src/interfaces/IPluginArgs.js +55 -0
- package/lib/src/interfaces/ISessionCapability.js +2 -0
- package/lib/src/logger.js +225 -0
- package/lib/src/plugin.js +244 -0
- package/lib/src/prisma.js +12 -0
- package/lib/src/profiling/AndroidAppProfiler.js +213 -0
- package/lib/src/proxy/wd-command-proxy.js +221 -0
- package/lib/src/scripts/generate-database-migration.js +59 -0
- package/lib/src/scripts/initialize-database.js +55 -0
- package/lib/src/scripts/install-go-ios.js +66 -0
- package/lib/src/scripts/prepare-prisma.js +89 -0
- package/lib/src/services/AICommandService.js +143 -0
- package/lib/src/services/AIService.js +466 -0
- package/lib/src/services/CleanupService.js +141 -0
- package/lib/src/services/EventBus.js +74 -0
- package/lib/src/services/InspectorService.js +395 -0
- package/lib/src/services/MetricsService.js +134 -0
- package/lib/src/services/NetworkConditioningService.js +173 -0
- package/lib/src/services/NotificationService.js +163 -0
- package/lib/src/services/RequestLogService.js +252 -0
- package/lib/src/services/ResourceIsolationService.js +122 -0
- package/lib/src/services/SecurityService.js +120 -0
- package/lib/src/services/ServerManager.js +284 -0
- package/lib/src/services/SessionHeartbeatService.js +158 -0
- package/lib/src/services/SessionLifecycleService.js +572 -0
- package/lib/src/services/SocketClient.js +71 -0
- package/lib/src/services/SocketServer.js +87 -0
- package/lib/src/services/TracingService.js +132 -0
- package/lib/src/services/VideoPipelineService.js +220 -0
- package/lib/src/services/healing/FuzzyXmlHealingProvider.js +333 -0
- package/lib/src/services/healing/HealEtalonService.js +98 -0
- package/lib/src/services/healing/HealedLocatorGenerator.js +132 -0
- package/lib/src/services/healing/HealingOrchestrator.js +165 -0
- package/lib/src/services/healing/LlmHealingProvider.js +77 -0
- package/lib/src/services/healing/OcrHealingProvider.js +119 -0
- package/lib/src/services/healing/ResilioTreeHealingProvider.js +100 -0
- package/lib/src/services/healing/VisualAiHealingProvider.js +90 -0
- package/lib/src/services/healing/types.js +12 -0
- package/lib/src/services/omni-vision/OmniVisionService.js +718 -0
- package/lib/src/services/omni-vision/VisionAssertionService.js +68 -0
- package/lib/src/sessions/CloudSession.js +42 -0
- package/lib/src/sessions/LocalSession.js +313 -0
- package/lib/src/sessions/RemoteSession.js +287 -0
- package/lib/src/sessions/SessionManager.js +238 -0
- package/lib/src/sessions/XenonSession.js +44 -0
- package/lib/src/types/CLIArgs.js +2 -0
- package/lib/src/types/CloudArgs.js +2 -0
- package/lib/src/types/CloudSchema.js +131 -0
- package/lib/src/types/DeviceType.js +2 -0
- package/lib/src/types/DeviceUpdate.js +2 -0
- package/lib/src/types/IOSDevice.js +2 -0
- package/lib/src/types/Platform.js +2 -0
- package/lib/src/types/SessionStatus.js +11 -0
- package/lib/src/validators/CapabilityValidator.js +93 -0
- package/lib/test/e2e/android/conf.spec.js +43 -0
- package/lib/test/e2e/android/conf2.spec.js +44 -0
- package/lib/test/e2e/android/conf3.spec.js +44 -0
- package/lib/test/e2e/e2ehelper.js +113 -0
- package/lib/test/e2e/hubnode/forward-request.spec.js +224 -0
- package/lib/test/e2e/hubnode/hubnode.spec.js +214 -0
- package/lib/test/e2e/ios/conf1.spec.js +39 -0
- package/lib/test/e2e/ios/conf2.spec.js +39 -0
- package/lib/test/e2e/plugin-harness.js +236 -0
- package/lib/test/e2e/plugin.spec.js +97 -0
- package/lib/test/e2e/telemetry_verification.spec.js +83 -0
- package/lib/test/e2e/video-recording-test.spec.js +63 -0
- package/lib/test/helpers/test-container.js +112 -0
- package/lib/test/integration/androidDevices.spec.js +137 -0
- package/lib/test/integration/cliArgs.js +73 -0
- package/lib/test/integration/ios/01iOSSimulator.spec.js +291 -0
- package/lib/test/integration/ios/02iOSDevices.spec.js +75 -0
- package/lib/test/integration/testHelpers.js +74 -0
- package/lib/test/unit/AndroidDeviceManager.spec.js +178 -0
- package/lib/test/unit/ChromeDriverManager.spec.js +26 -0
- package/lib/test/unit/CleanupService.spec.js +21 -0
- package/lib/test/unit/DeviceModel.spec.js +157 -0
- package/lib/test/unit/FuzzyXmlHealingProvider.test.js +294 -0
- package/lib/test/unit/GetAdbOriginal.js +42 -0
- package/lib/test/unit/HealingCascade.test.js +128 -0
- package/lib/test/unit/IOSDeviceManager.spec.js +261 -0
- package/lib/test/unit/RemoteIOs.spec.js +78 -0
- package/lib/test/unit/ResilioTreeHealingProvider.test.js +96 -0
- package/lib/test/unit/commands.spec.js +27 -0
- package/lib/test/unit/config.spec.js +27 -0
- package/lib/test/unit/device-service.spec.js +307 -0
- package/lib/test/unit/device-utils.spec.js +313 -0
- package/lib/test/unit/fixtures/device.config.js +4 -0
- package/lib/test/unit/fixtures/devices.js +89 -0
- package/lib/test/unit/helpers.spec.js +62 -0
- package/lib/test/unit/omni-vision.spec.js +100 -0
- package/lib/test/unit/plugin.spec.js +133 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/package.json +207 -0
- package/prisma/data.db +0 -0
- package/prisma/dev.db +0 -0
- package/prisma/dev.db-journal +0 -0
- package/prisma/migrations/20231011074725_initial_tables/migration.sql +47 -0
- package/prisma/migrations/20231226115334_update_session_log/migration.sql +2 -0
- package/prisma/migrations/20251204113710_add_video_recording_enabled/migration.sql +29 -0
- package/prisma/migrations/20251204132449_add_log_table/migration.sql +11 -0
- package/prisma/migrations/20251205050111_add_profiling_support/migration.sql +47 -0
- package/prisma/migrations/20251205050947_add_is_error_field/migration.sql +24 -0
- package/prisma/migrations/20260126201337_add_app_model/migration.sql +18 -0
- package/prisma/migrations/20260130115722_add_performance_trace_and_xenon_sync/migration.sql +2 -0
- package/prisma/migrations/20260130135114_add_device_models/migration.sql +57 -0
- package/prisma/migrations/20260130140655_make_systemport_optional/migration.sql +45 -0
- package/prisma/migrations/20260130140932_make_device_fields_optional/migration.sql +45 -0
- package/prisma/migrations/20260130141040_final_schema_fix/migration.sql +45 -0
- package/prisma/migrations/20260130143234_add_device_health_fields/migration.sql +4 -0
- package/prisma/migrations/20260130144921_add_failure_category/migration.sql +2 -0
- package/prisma/migrations/20260131151456_add_webhook_config/migration.sql +10 -0
- package/prisma/migrations/20260201094507_add_device_tags/migration.sql +11 -0
- package/prisma/migrations/20260201103410_add_managed_process/migration.sql +15 -0
- package/prisma/migrations/20260201140637_add_web_config/migration.sql +22 -0
- package/prisma/migrations/20260201162232_add_session_progress/migration.sql +2 -0
- package/prisma/migrations/20260201174231_add_total_healed_count/migration.sql +2 -0
- package/prisma/migrations/migration_lock.toml +3 -0
- package/prisma/schema.prisma +210 -0
- package/schema.json +348 -0
- package/scripts/build-xenon.sh +32 -0
- package/scripts/dev/debug-gemini.ts +44 -0
- package/scripts/generate-types-from-schema.js +86 -0
- package/scripts/install-compatible-driver.js +39 -0
|
@@ -0,0 +1,345 @@
|
|
|
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
|
+
exports.DeviceStoreFactory = void 0;
|
|
16
|
+
const logger_1 = __importDefault(require("../logger"));
|
|
17
|
+
const semver_1 = __importDefault(require("semver"));
|
|
18
|
+
const db_1 = require("./db");
|
|
19
|
+
const prisma_store_1 = require("./prisma-store");
|
|
20
|
+
const config_1 = require("../config");
|
|
21
|
+
/**
|
|
22
|
+
* LokiJS Implementation of Device Store (Legacy/Internal)
|
|
23
|
+
*/
|
|
24
|
+
class LokiDeviceStore {
|
|
25
|
+
constructor() {
|
|
26
|
+
this.log = logger_1.default.scope('LokiStore');
|
|
27
|
+
}
|
|
28
|
+
getAllDevices() {
|
|
29
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
30
|
+
return (yield db_1.XenonDatabase.DeviceModel).chain().find().data();
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
getDevices(filterOptions) {
|
|
34
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
35
|
+
const basicFilter = process.env.NODE_ENV === 'test'
|
|
36
|
+
? {}
|
|
37
|
+
: { host: { $ne: undefined }, userBlocked: { $ne: undefined } };
|
|
38
|
+
const allInColl = (yield db_1.XenonDatabase.DeviceModel).find(basicFilter);
|
|
39
|
+
const filtered = allInColl.filter((device) => {
|
|
40
|
+
var _a;
|
|
41
|
+
// Platform Filter
|
|
42
|
+
if (filterOptions.platform) {
|
|
43
|
+
const match = (device.platform || '').toLowerCase() === filterOptions.platform.toLowerCase();
|
|
44
|
+
// if (!match) console.error(`[LokiStore] Platform Mismatch: ${device.udid} (${device.platform} vs ${filterOptions.platform})`);
|
|
45
|
+
if (!match)
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
// Platform Version Filter
|
|
49
|
+
if (filterOptions.platformVersion) {
|
|
50
|
+
const coercedFilterVersion = semver_1.default.coerce(filterOptions.platformVersion);
|
|
51
|
+
const coercedDeviceVersion = semver_1.default.coerce(device.sdk || '');
|
|
52
|
+
if (!coercedFilterVersion ||
|
|
53
|
+
!coercedDeviceVersion ||
|
|
54
|
+
!semver_1.default.eq(coercedDeviceVersion, coercedFilterVersion))
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
// Name Filter
|
|
58
|
+
if ((_a = filterOptions.name) === null || _a === void 0 ? void 0 : _a.trim()) {
|
|
59
|
+
const nameRegex = new RegExp(filterOptions.name.trim(), 'i');
|
|
60
|
+
if (!nameRegex.test(device.name || ''))
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
// UDID Filter
|
|
64
|
+
if (filterOptions.udid) {
|
|
65
|
+
if (Array.isArray(filterOptions.udid)) {
|
|
66
|
+
if (filterOptions.udid.length > 0 && !filterOptions.udid.includes(device.udid))
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
else if (device.udid !== filterOptions.udid) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Device Type Filter
|
|
74
|
+
if (filterOptions.deviceType) {
|
|
75
|
+
if (device.deviceType !== filterOptions.deviceType)
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
// Host Filter
|
|
79
|
+
if (filterOptions.filterByHost) {
|
|
80
|
+
const hostFilter = filterOptions.filterByHost.toLowerCase();
|
|
81
|
+
if (!(device.host || '').toLowerCase().includes(hostFilter))
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
// Session ID Filter
|
|
85
|
+
if (filterOptions.session_id) {
|
|
86
|
+
if (device.session_id !== filterOptions.session_id)
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
// Busy / Offline / UserBlocked Filters
|
|
90
|
+
if (filterOptions.busy !== undefined && device.busy !== filterOptions.busy)
|
|
91
|
+
return false;
|
|
92
|
+
if (filterOptions.offline !== undefined && device.offline !== filterOptions.offline)
|
|
93
|
+
return false;
|
|
94
|
+
if (filterOptions.userBlocked !== undefined &&
|
|
95
|
+
device.userBlocked !== filterOptions.userBlocked)
|
|
96
|
+
return false;
|
|
97
|
+
// minSDK Filter
|
|
98
|
+
if (filterOptions.minSDK) {
|
|
99
|
+
const coercedMinSDK = semver_1.default.coerce(filterOptions.minSDK);
|
|
100
|
+
const coercedSDK = semver_1.default.coerce(device.sdk || '');
|
|
101
|
+
if (!coercedMinSDK || !coercedSDK || !semver_1.default.gte(coercedSDK, coercedMinSDK))
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
// maxSDK Filter
|
|
105
|
+
if (filterOptions.maxSDK) {
|
|
106
|
+
const coercedMaxSDK = semver_1.default.coerce(filterOptions.maxSDK);
|
|
107
|
+
const coercedSDK = semver_1.default.coerce(device.sdk || '');
|
|
108
|
+
if (!coercedMaxSDK || !coercedSDK || !semver_1.default.lte(coercedSDK, coercedMaxSDK))
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
return true;
|
|
112
|
+
});
|
|
113
|
+
return filtered.sort((a, b) => {
|
|
114
|
+
try {
|
|
115
|
+
const vA = semver_1.default.coerce(a.sdk || '0.0.0');
|
|
116
|
+
const vB = semver_1.default.coerce(b.sdk || '0.0.0');
|
|
117
|
+
if (vA && vB) {
|
|
118
|
+
if (semver_1.default.gt(vA, vB))
|
|
119
|
+
return -1;
|
|
120
|
+
if (semver_1.default.lt(vA, vB))
|
|
121
|
+
return 1;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
// Ignore sort errors
|
|
126
|
+
}
|
|
127
|
+
return 0;
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
updateDevice(udid, host, updateData) {
|
|
132
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
133
|
+
(yield db_1.XenonDatabase.DeviceModel)
|
|
134
|
+
.chain()
|
|
135
|
+
.find({ udid, host })
|
|
136
|
+
.update((device) => {
|
|
137
|
+
Object.assign(device, updateData);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
updateDevices(filter, updateFn) {
|
|
142
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
143
|
+
(yield db_1.XenonDatabase.DeviceModel).chain().find(filter).update(updateFn);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
addDevices(devices) {
|
|
147
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
148
|
+
const deviceModel = yield db_1.XenonDatabase.DeviceModel;
|
|
149
|
+
const added = [];
|
|
150
|
+
for (const device of devices) {
|
|
151
|
+
const existing = deviceModel.findOne({ udid: device.udid, host: device.host });
|
|
152
|
+
if (!existing) {
|
|
153
|
+
const cleanDevice = Object.assign({}, device);
|
|
154
|
+
if (cleanDevice.host === undefined)
|
|
155
|
+
cleanDevice.host = 'Local';
|
|
156
|
+
if (cleanDevice.userBlocked === undefined)
|
|
157
|
+
cleanDevice.userBlocked = false;
|
|
158
|
+
if (cleanDevice.busy === undefined)
|
|
159
|
+
cleanDevice.busy = false;
|
|
160
|
+
if (cleanDevice.offline === undefined)
|
|
161
|
+
cleanDevice.offline = false;
|
|
162
|
+
// @ts-ignore - LokiJS adds $loki metadata that we need to strip before insert
|
|
163
|
+
delete cleanDevice['$loki'];
|
|
164
|
+
// @ts-ignore
|
|
165
|
+
delete cleanDevice['meta'];
|
|
166
|
+
deviceModel.insert(cleanDevice);
|
|
167
|
+
added.push(cleanDevice);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return added;
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
removeDevices(filter) {
|
|
174
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
175
|
+
(yield db_1.XenonDatabase.DeviceModel).chain().find(filter).remove();
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
clearStorage() {
|
|
179
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
180
|
+
(yield db_1.XenonDatabase.DeviceModel).removeDataOnly();
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
findDevice(filter) {
|
|
184
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
185
|
+
return (yield db_1.XenonDatabase.DeviceModel).findOne(filter);
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
findDevices(filter) {
|
|
189
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
190
|
+
return (yield db_1.XenonDatabase.DeviceModel).find(filter);
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
findAndLockDevice(filterOptions) {
|
|
194
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
195
|
+
const devices = yield this.getDevices(filterOptions);
|
|
196
|
+
const available = devices.find((d) => !d.busy && !d.userBlocked);
|
|
197
|
+
if (available) {
|
|
198
|
+
yield this.updateDevice(available.udid, available.host, { busy: true });
|
|
199
|
+
return available;
|
|
200
|
+
}
|
|
201
|
+
return null;
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
resetMetrics() {
|
|
205
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
206
|
+
(yield db_1.XenonDatabase.DeviceModel)
|
|
207
|
+
.chain()
|
|
208
|
+
.find()
|
|
209
|
+
.update((device) => {
|
|
210
|
+
device.totalHealedCount = 0;
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
class LokiPendingSessionStore {
|
|
216
|
+
addPendingSession(capability) {
|
|
217
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
218
|
+
(yield db_1.XenonDatabase.PendingSessionsModel).insert(capability);
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
removePendingSession(sessionCapabilityId) {
|
|
222
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
223
|
+
(yield db_1.XenonDatabase.PendingSessionsModel)
|
|
224
|
+
.chain()
|
|
225
|
+
.find({ capability_id: sessionCapabilityId })
|
|
226
|
+
.remove();
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
getAllPendingSessions() {
|
|
230
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
231
|
+
return (yield db_1.XenonDatabase.PendingSessionsModel).chain().find().data();
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
remove(session) {
|
|
235
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
236
|
+
(yield db_1.XenonDatabase.PendingSessionsModel).remove(session);
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
class LokiCLIArgsStore {
|
|
241
|
+
addCLIArgs(args) {
|
|
242
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
243
|
+
(yield db_1.XenonDatabase.CLIArgs).insert(args);
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
getCLIArgs() {
|
|
247
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
248
|
+
return (yield db_1.XenonDatabase.CLIArgs).chain().find().data();
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
class LokiHealEtalonStore {
|
|
253
|
+
constructor() {
|
|
254
|
+
this.collectionName = 'locator-etalons';
|
|
255
|
+
}
|
|
256
|
+
getCollection() {
|
|
257
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
258
|
+
const db = yield db_1.XenonDatabase.db;
|
|
259
|
+
let coll = db.getCollection(this.collectionName);
|
|
260
|
+
if (!coll) {
|
|
261
|
+
coll = db.addCollection(this.collectionName, { unique: ['selector'] });
|
|
262
|
+
}
|
|
263
|
+
return coll;
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
saveSignature(etalon) {
|
|
267
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
268
|
+
const coll = yield this.getCollection();
|
|
269
|
+
const existing = coll.findOne({ selector: etalon.selector });
|
|
270
|
+
if (existing) {
|
|
271
|
+
Object.assign(existing, etalon);
|
|
272
|
+
coll.update(existing);
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
coll.insert(etalon);
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
getSignature(selector) {
|
|
280
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
281
|
+
const coll = yield this.getCollection();
|
|
282
|
+
return coll.findOne({ selector });
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Factory for Device Store.
|
|
288
|
+
* Determines storage type based on config.
|
|
289
|
+
*/
|
|
290
|
+
class DeviceStoreFactory {
|
|
291
|
+
static getStorageType() {
|
|
292
|
+
if (process.env.NODE_ENV === 'test')
|
|
293
|
+
return 'loki';
|
|
294
|
+
const type = process.env.XENON_STORAGE_TYPE || config_1.config.databaseProvider;
|
|
295
|
+
if (type === 'sqlite' || type === 'postgresql' || type === 'prisma')
|
|
296
|
+
return 'prisma';
|
|
297
|
+
return 'loki';
|
|
298
|
+
}
|
|
299
|
+
static getStore() {
|
|
300
|
+
if (!this._deviceStore) {
|
|
301
|
+
if (this.getStorageType() === 'prisma') {
|
|
302
|
+
this._deviceStore = new prisma_store_1.PrismaDeviceStore();
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
this._deviceStore = new LokiDeviceStore();
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
return this._deviceStore;
|
|
309
|
+
}
|
|
310
|
+
static getPendingSessionStore() {
|
|
311
|
+
if (!this._pendingSessionStore) {
|
|
312
|
+
if (this.getStorageType() === 'prisma') {
|
|
313
|
+
this._pendingSessionStore = new prisma_store_1.PrismaPendingSessionStore();
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
this._pendingSessionStore = new LokiPendingSessionStore();
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return this._pendingSessionStore;
|
|
320
|
+
}
|
|
321
|
+
static getCLIArgsStore() {
|
|
322
|
+
if (!this._cliArgsStore) {
|
|
323
|
+
if (this.getStorageType() === 'prisma') {
|
|
324
|
+
this._cliArgsStore = new prisma_store_1.PrismaCLIArgsStore();
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
this._cliArgsStore = new LokiCLIArgsStore();
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return this._cliArgsStore;
|
|
331
|
+
}
|
|
332
|
+
static getHealEtalonStore() {
|
|
333
|
+
if (!this._healEtalonStore) {
|
|
334
|
+
if (this.getStorageType() === 'prisma') {
|
|
335
|
+
const { PrismaHealEtalonStore } = require('./prisma-store');
|
|
336
|
+
this._healEtalonStore = new PrismaHealEtalonStore();
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
this._healEtalonStore = new LokiHealEtalonStore();
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return this._healEtalonStore;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
exports.DeviceStoreFactory = DeviceStoreFactory;
|
|
@@ -0,0 +1,25 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.addNewPendingSession = addNewPendingSession;
|
|
13
|
+
exports.removePendingSession = removePendingSession;
|
|
14
|
+
const device_store_1 = require("./device-store");
|
|
15
|
+
const store = device_store_1.DeviceStoreFactory.getPendingSessionStore();
|
|
16
|
+
function addNewPendingSession(capability) {
|
|
17
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
18
|
+
yield store.addPendingSession(capability);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function removePendingSession(sessionCapabilityId) {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
yield store.removePendingSession(sessionCapabilityId);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.addCLIArgs = addCLIArgs;
|
|
13
|
+
exports.getCLIArgs = getCLIArgs;
|
|
14
|
+
const device_store_1 = require("./device-store");
|
|
15
|
+
const store = device_store_1.DeviceStoreFactory.getCLIArgsStore();
|
|
16
|
+
function addCLIArgs(args) {
|
|
17
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
18
|
+
yield store.addCLIArgs(args);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function getCLIArgs() {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
return yield store.getCLIArgs();
|
|
24
|
+
});
|
|
25
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.PrismaService = void 0;
|
|
13
|
+
const client_1 = require("@prisma/client");
|
|
14
|
+
const config_1 = require("../config");
|
|
15
|
+
const typedi_1 = require("typedi");
|
|
16
|
+
let PrismaService = class PrismaService extends client_1.PrismaClient {
|
|
17
|
+
constructor() {
|
|
18
|
+
super({
|
|
19
|
+
datasources: {
|
|
20
|
+
db: {
|
|
21
|
+
url: config_1.config.databaseUrl,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
exports.PrismaService = PrismaService;
|
|
28
|
+
exports.PrismaService = PrismaService = __decorate([
|
|
29
|
+
(0, typedi_1.Service)(),
|
|
30
|
+
__metadata("design:paramtypes", [])
|
|
31
|
+
], PrismaService);
|