@xenon-device-management/xenon 1.1.15 → 1.1.17
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/lib/package.json
CHANGED
package/lib/src/app/index.js
CHANGED
|
@@ -132,17 +132,27 @@ apiRouter.get('/metrics', (req, res) => __awaiter(void 0, void 0, void 0, functi
|
|
|
132
132
|
res.set('Content-Type', 'text/plain');
|
|
133
133
|
res.send(metrics);
|
|
134
134
|
}));
|
|
135
|
-
const
|
|
136
|
-
path_1.default.resolve(__dirname, '..', '
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
135
|
+
const findPublicPath = () => {
|
|
136
|
+
const rootDir = path_1.default.resolve(__dirname, '..', '..');
|
|
137
|
+
const searchPaths = [
|
|
138
|
+
path_1.default.join(rootDir, 'public'), // Production (lib/public)
|
|
139
|
+
path_1.default.join(rootDir, 'src', 'public'), // Development (src/public)
|
|
140
|
+
path_1.default.resolve(__dirname, '../public'), // Alternative structure
|
|
141
|
+
path_1.default.resolve(__dirname, '../../public'),
|
|
142
|
+
path_1.default.resolve(__dirname, '../../../public'),
|
|
143
|
+
];
|
|
144
|
+
for (const p of searchPaths) {
|
|
145
|
+
if (fs_1.default.existsSync(path_1.default.join(p, 'index.html'))) {
|
|
146
|
+
logger_1.default.info(`[Xenon] Dashboard assets found at: ${p}`);
|
|
147
|
+
return p;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Last resort fallback
|
|
151
|
+
const fallback = path_1.default.resolve(__dirname, '../../public');
|
|
152
|
+
logger_1.default.warn(`[Xenon] Could not find dashboard index.html in standard paths. Falling back to: ${fallback}`);
|
|
153
|
+
return fallback;
|
|
154
|
+
};
|
|
155
|
+
const publicPath = findPublicPath();
|
|
146
156
|
logger_1.default.info(`[Xenon] Public assets path resolved to: ${publicPath}`);
|
|
147
157
|
staticFilesRouter.use(express_1.default.static(publicPath));
|
|
148
158
|
router.use('/api', apiRouter);
|
|
@@ -175,12 +185,29 @@ function createRouter(pluginArgs) {
|
|
|
175
185
|
// Fallback route for client-side routing - serve index.html for all non-API routes
|
|
176
186
|
// MUST be registered after Swagger to avoid interception
|
|
177
187
|
router.get(/^(?!\/api).*/, (req, res) => {
|
|
178
|
-
const indexPath = path_1.default.
|
|
188
|
+
const indexPath = path_1.default.resolve(publicPath, 'index.html');
|
|
189
|
+
const url = req.originalUrl || req.url;
|
|
190
|
+
logger_1.default.debug(`[Xenon] UI Fallback triggered for: ${url}. Targeting: ${indexPath}`);
|
|
179
191
|
if (fs_1.default.existsSync(indexPath)) {
|
|
180
|
-
res.sendFile(indexPath)
|
|
192
|
+
res.sendFile(indexPath, (err) => {
|
|
193
|
+
if (err) {
|
|
194
|
+
logger_1.default.error(`[Xenon] res.sendFile failed for ${indexPath}. Error: ${err.message}`);
|
|
195
|
+
if (!res.headersSent) {
|
|
196
|
+
res.status(404).send(`Xenon UI Asset Error: ${err.message}`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
});
|
|
181
200
|
}
|
|
182
201
|
else {
|
|
183
202
|
logger_1.default.error(`[Xenon] UI Fallback failed: index.html not found at ${indexPath}`);
|
|
203
|
+
// Diagnostic: List files in publicPath
|
|
204
|
+
try {
|
|
205
|
+
const files = fs_1.default.readdirSync(publicPath);
|
|
206
|
+
logger_1.default.error(`[Xenon] Contents of ${publicPath}: ${files.join(', ')}`);
|
|
207
|
+
}
|
|
208
|
+
catch (e) {
|
|
209
|
+
logger_1.default.error(`[Xenon] Could not even read directory ${publicPath}: ${e.message}`);
|
|
210
|
+
}
|
|
184
211
|
res.status(404).send('Xenon UI assets not found. Check installation.');
|
|
185
212
|
}
|
|
186
213
|
});
|
|
@@ -179,12 +179,18 @@ let AndroidDeviceManager = class AndroidDeviceManager {
|
|
|
179
179
|
: adbInstance.adbRemoteHost;
|
|
180
180
|
const existingDevice = existingDeviceDetails.find((dev) => dev.udid === device.udid && dev.host.includes(this.pluginArgs.bindHostOrIp));
|
|
181
181
|
if (existingDevice) {
|
|
182
|
-
|
|
183
|
-
|
|
182
|
+
if (device.state === 'device') {
|
|
183
|
+
logger_1.default.debug(`Android Device details for ${device.udid} already available and online`);
|
|
184
|
+
return Object.assign(Object.assign({}, existingDevice), { state: 'device', busy: existingDevice.busy || false });
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
logger_1.default.info(`Device ${device.udid} was cached but is now in "${device.state}" state. Ignoring.`);
|
|
188
|
+
return undefined;
|
|
189
|
+
}
|
|
184
190
|
}
|
|
185
191
|
else {
|
|
186
|
-
logger_1.default.info(`Android Device details for ${device.udid} not available. So querying now.`);
|
|
187
192
|
if (device.state === 'device') {
|
|
193
|
+
logger_1.default.info(`New Android Device ${device.udid} discovered in "device" state. Querying details...`);
|
|
188
194
|
try {
|
|
189
195
|
return yield this.deviceInfo(device, adbInstance, this.pluginArgs, this.hostPort);
|
|
190
196
|
}
|
|
@@ -194,7 +200,7 @@ let AndroidDeviceManager = class AndroidDeviceManager {
|
|
|
194
200
|
}
|
|
195
201
|
}
|
|
196
202
|
else {
|
|
197
|
-
logger_1.default.info(`Device ${device.udid} is
|
|
203
|
+
logger_1.default.info(`Device ${device.udid} is in "${device.state}" state. Ignoring.`);
|
|
198
204
|
return undefined;
|
|
199
205
|
}
|
|
200
206
|
}
|
package/package.json
CHANGED