Skip to content

Commit 21739ef

Browse files
Feat: Refactor session management to support desktop and mobile filtering with improved OS and browser version handling
1 parent bca862d commit 21739ef

File tree

7 files changed

+336
-234
lines changed

7 files changed

+336
-234
lines changed

src/tools/applive-utils/start-session.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ function openBrowser(launchUrl: string): void {
221221
: process.platform === "win32"
222222
? ["cmd", "/c", "start", launchUrl]
223223
: ["xdg-open", launchUrl];
224-
224+
225225
// nosemgrep:javascript.lang.security.detect-child-process.detect-child-process
226226
const child = childProcess.spawn(command[0], command.slice(1), {
227227
stdio: "ignore",
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
import { getLiveData } from "./device-cache";
2+
import { resolveVersion } from "./version-resolver";
3+
import { customFuzzySearch } from "../../lib/fuzzy";
4+
import { DesktopArgs, DesktopEntry } from "./types";
5+
6+
export async function filterDesktop(args: DesktopArgs): Promise<DesktopEntry> {
7+
const data = await getLiveData();
8+
const allEntries = getAllDesktopEntries(data);
9+
10+
// Filter OS
11+
const osList = filterByOS(allEntries, args.os);
12+
13+
// Filter browser
14+
const browserList = filterByBrowser(osList, args.browser, args.os);
15+
16+
// Resolve OS version
17+
const uniqueOSVersions = getUniqueOSVersions(browserList);
18+
const chosenOS = resolveOSVersion(args.os, args.osVersion, uniqueOSVersions);
19+
20+
// Filter entries based on chosen OS version
21+
const entriesForOS = filterByOSVersion(browserList, chosenOS);
22+
23+
// Resolve browser version
24+
const browserVersions = entriesForOS.map((e) => e.browser_version);
25+
const chosenBrowserVersion = resolveVersion(
26+
args.browserVersion,
27+
browserVersions,
28+
);
29+
30+
// Find final entry
31+
const finalEntry = entriesForOS.find(
32+
(e) => e.browser_version === chosenBrowserVersion,
33+
);
34+
if (!finalEntry) {
35+
throw new Error(`No entry for browser version "${args.browserVersion}".`);
36+
}
37+
38+
// Add notes if versions were adjusted
39+
addNotes(finalEntry, args, chosenOS, chosenBrowserVersion);
40+
41+
return finalEntry;
42+
}
43+
44+
function getAllDesktopEntries(data: any): DesktopEntry[] {
45+
return data.desktop.flatMap((plat: any) =>
46+
plat.browsers.map((b: any) => ({
47+
os: plat.os,
48+
os_version: plat.os_version,
49+
browser: b.browser,
50+
browser_version: b.browser_version,
51+
})),
52+
);
53+
}
54+
55+
function filterByOS(entries: DesktopEntry[], os: string): DesktopEntry[] {
56+
const filtered = entries.filter((e) => e.os === os);
57+
if (!filtered.length) throw new Error(`No OS entries for "${os}".`);
58+
return filtered;
59+
}
60+
61+
function filterByBrowser(
62+
entries: DesktopEntry[],
63+
browser: string,
64+
os: string,
65+
): DesktopEntry[] {
66+
const filtered = entries.filter((e) => e.browser === browser);
67+
if (!filtered.length) throw new Error(`No browser "${browser}" on ${os}.`);
68+
return filtered;
69+
}
70+
71+
function getUniqueOSVersions(entries: DesktopEntry[]): string[] {
72+
return Array.from(new Set(entries.map((e) => e.os_version)));
73+
}
74+
75+
function resolveOSVersion(
76+
os: string,
77+
requestedVersion: string,
78+
availableVersions: string[],
79+
): string {
80+
if (os === "OS X") {
81+
return resolveMacOSVersion(requestedVersion, availableVersions);
82+
} else {
83+
// For Windows, use semantic versioning
84+
return resolveVersion(requestedVersion, availableVersions);
85+
}
86+
}
87+
88+
function resolveMacOSVersion(requested: string, available: string[]): string {
89+
if (requested === "latest") {
90+
return available[available.length - 1];
91+
} else if (requested === "oldest") {
92+
return available[0];
93+
} else {
94+
// Try fuzzy matching
95+
const fuzzy = customFuzzySearch(
96+
available.map((v) => ({ os_version: v })),
97+
["os_version"],
98+
requested,
99+
1,
100+
);
101+
const matched = fuzzy.length ? fuzzy[0].os_version : requested;
102+
103+
// Fallback if not valid
104+
return available.includes(matched) ? matched : available[0];
105+
}
106+
}
107+
108+
function filterByOSVersion(
109+
entries: DesktopEntry[],
110+
osVersion: string,
111+
): DesktopEntry[] {
112+
return entries.filter((e) => e.os_version === osVersion);
113+
}
114+
115+
function addNotes(
116+
entry: DesktopEntry,
117+
args: DesktopArgs,
118+
resolvedOS: string,
119+
resolvedBrowser: string,
120+
): void {
121+
if (
122+
args.osVersion !== resolvedOS &&
123+
args.osVersion !== "latest" &&
124+
args.osVersion !== "oldest"
125+
) {
126+
entry.notes = `Note: OS version ${args.osVersion} was not found. Using "${resolvedOS}" instead.`;
127+
}
128+
129+
if (
130+
args.browserVersion !== resolvedBrowser &&
131+
args.browserVersion !== "latest" &&
132+
args.browserVersion !== "oldest"
133+
) {
134+
if (!entry.notes) {
135+
entry.notes = `Note: `;
136+
} else {
137+
entry.notes += ` `;
138+
}
139+
entry.notes += `Browser version ${args.browserVersion} was not found. Using "${resolvedBrowser}" instead.`;
140+
}
141+
}

src/tools/live-utils/mobile-filter.ts

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import { getLiveData } from "./device-cache";
2+
import { resolveVersion } from "./version-resolver";
3+
import { customFuzzySearch } from "../../lib/fuzzy";
4+
import { MobileArgs, MobileEntry } from "./types";
5+
6+
// Extract all mobile entries from the data
7+
function getAllMobileEntries(data: any): MobileEntry[] {
8+
return data.mobile.flatMap((grp: any) =>
9+
grp.devices.map((d: any) => ({
10+
os: grp.os,
11+
os_version: d.os_version,
12+
display_name: d.display_name,
13+
notes: "",
14+
})),
15+
);
16+
}
17+
18+
// Filter entries by OS
19+
function filterByOS(entries: MobileEntry[], os: string): MobileEntry[] {
20+
const candidates = entries.filter((d) => d.os === os);
21+
if (!candidates.length) throw new Error(`No mobile OS entries for "${os}".`);
22+
return candidates;
23+
}
24+
25+
// Find matching device with exact match validation
26+
function findMatchingDevice(
27+
entries: MobileEntry[],
28+
deviceName: string,
29+
os: string,
30+
): MobileEntry[] {
31+
const matches = customFuzzySearch(entries, ["display_name"], deviceName, 5);
32+
if (!matches.length)
33+
throw new Error(`No devices matching "${deviceName}" on ${os}.`);
34+
35+
const exact = matches.find(
36+
(m) => m.display_name.toLowerCase() === deviceName.toLowerCase(),
37+
);
38+
if (!exact) {
39+
const names = matches.map((m) => m.display_name).join(", ");
40+
throw new Error(
41+
`Alternative Device/Device's found : ${names}. Please Select one.`,
42+
);
43+
}
44+
45+
const result = entries.filter((d) => d.display_name === exact.display_name);
46+
if (!result.length)
47+
throw new Error(`No device "${exact.display_name}" on ${os}.`);
48+
49+
return result;
50+
}
51+
52+
// Find the appropriate OS version
53+
function findOSVersion(
54+
entries: MobileEntry[],
55+
requestedVersion: string,
56+
): { entries: MobileEntry[]; chosenVersion: string } {
57+
const versions = entries.map((d) => d.os_version);
58+
const chosenVersion = resolveVersion(requestedVersion, versions);
59+
60+
const result = entries.filter((d) => d.os_version === chosenVersion);
61+
if (!result.length)
62+
throw new Error(`No entry for OS version "${requestedVersion}".`);
63+
64+
return { entries: result, chosenVersion };
65+
}
66+
67+
// Create version note if needed
68+
function createVersionNote(
69+
requestedVersion: string,
70+
actualVersion: string,
71+
): string {
72+
if (
73+
actualVersion !== requestedVersion &&
74+
requestedVersion !== "latest" &&
75+
requestedVersion !== "oldest"
76+
) {
77+
return `Note: Os version ${requestedVersion} was not found. Using ${actualVersion} instead.`;
78+
}
79+
return "";
80+
}
81+
82+
export async function filterMobile(args: MobileArgs): Promise<MobileEntry> {
83+
const data = await getLiveData();
84+
const allEntries = getAllMobileEntries(data);
85+
86+
const osCandidates = filterByOS(allEntries, args.os);
87+
const deviceCandidates = findMatchingDevice(
88+
osCandidates,
89+
args.device,
90+
args.os,
91+
);
92+
93+
const { entries: versionCandidates, chosenVersion } = findOSVersion(
94+
deviceCandidates,
95+
args.osVersion,
96+
);
97+
98+
const final = versionCandidates[0];
99+
final.notes = createVersionNote(args.osVersion, chosenVersion);
100+
101+
return final;
102+
}

0 commit comments

Comments
 (0)