Use universal Mac installer + centralized installer URLs

This commit is contained in:
Anthony Stirling
2026-05-26 19:44:10 +01:00
parent c2cc7ede10
commit 930dc5c018
3 changed files with 103 additions and 16 deletions
@@ -1,8 +1,18 @@
// Centralized download URLs for Stirling PDF desktop installers
export const DOWNLOAD_URLS = {
WINDOWS: "https://files.stirlingpdf.com/win-installer.exe",
MAC: "https://files.stirlingpdf.com/mac-installer.dmg",
LINUX_DOCS: "https://docs.stirlingpdf.com/Installation/Unix%20Installation/",
// Centralized download URLs for Stirling PDF desktop installers.
// File names match the GitHub release artifacts so files.stirlingpdf.com can
// alias them 1:1.
export const DOWNLOAD_BASE_URL = "https://files.stirlingpdf.com/";
export const DESKTOP_INSTALLER_FILES = {
// Universal Mac binary - works on both Intel and Apple silicon, so no arch
// detection is needed on the client.
MAC: "Stirling-PDF-macos-universal.dmg",
WINDOWS: "Stirling-PDF-windows-x86_64.msi",
LINUX_DEB: "Stirling-PDF-linux-x86_64.deb",
} as const;
export const DOWNLOAD_BASE_URL = "https://files.stirlingpdf.com/";
export const DOWNLOAD_URLS = {
WINDOWS: DOWNLOAD_BASE_URL + DESKTOP_INSTALLER_FILES.WINDOWS,
MAC: DOWNLOAD_BASE_URL + DESKTOP_INSTALLER_FILES.MAC,
LINUX_DOCS: "https://docs.stirlingpdf.com/Installation/Unix%20Installation/",
} as const;
@@ -0,0 +1,76 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { updateService } from "@app/services/updateService";
import { DOWNLOAD_URLS } from "@app/constants/downloads";
type MachineInfo = Parameters<typeof updateService.getDownloadUrl>[0];
const stubMachineInfo: MachineInfo = {
machineType: "Server-jar",
activeSecurity: false,
licenseType: "FREE",
};
const setUserAgent = (value: string) => {
Object.defineProperty(window.navigator, "userAgent", {
value,
configurable: true,
});
};
describe("updateService.getDownloadUrl (desktop)", () => {
const original = window.navigator.userAgent;
beforeEach(() => {
vi.restoreAllMocks();
});
afterEach(() => {
setUserAgent(original);
});
it("returns the universal Mac installer for Apple-silicon Macs", () => {
setUserAgent(
"Mozilla/5.0 (Macintosh; ARM Mac OS X 14_0) AppleWebKit/605.1.15",
);
expect(updateService.getDownloadUrl(stubMachineInfo, true)).toBe(
DOWNLOAD_URLS.MAC,
);
});
it("returns the universal Mac installer for Intel Macs", () => {
setUserAgent(
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15",
);
expect(updateService.getDownloadUrl(stubMachineInfo, true)).toBe(
DOWNLOAD_URLS.MAC,
);
});
it("returns the universal Mac URL even when the UA misreports Apple-silicon as Intel", () => {
setUserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)");
const url = updateService.getDownloadUrl(stubMachineInfo, true);
expect(url).toBe(DOWNLOAD_URLS.MAC);
expect(url).toContain("Stirling-PDF-macos-universal.dmg");
});
it("returns the Windows installer for Windows UAs", () => {
setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
expect(updateService.getDownloadUrl(stubMachineInfo, true)).toBe(
DOWNLOAD_URLS.WINDOWS,
);
});
it("returns a .deb URL for Linux UAs", () => {
setUserAgent("Mozilla/5.0 (X11; Linux x86_64)");
expect(updateService.getDownloadUrl(stubMachineInfo, true)).toContain(
"Stirling-PDF-linux-x86_64.deb",
);
});
it("falls back to the GitHub releases page for unknown platforms", () => {
setUserAgent("Mozilla/5.0 (Unknown OS)");
expect(updateService.getDownloadUrl(stubMachineInfo, true)).toBe(
"https://github.com/Stirling-Tools/Stirling-PDF/releases/latest",
);
});
});
@@ -1,4 +1,8 @@
import { DOWNLOAD_BASE_URL } from "@app/constants/downloads";
import {
DESKTOP_INSTALLER_FILES,
DOWNLOAD_BASE_URL,
DOWNLOAD_URLS,
} from "@app/constants/downloads";
export interface UpdateSummary {
latest_version: string | null;
@@ -76,17 +80,14 @@ export class UpdateService {
if (isDesktop) {
const userAgent = navigator.userAgent.toLowerCase();
if (userAgent.includes("win")) {
return DOWNLOAD_BASE_URL + "win-installer.exe";
return DOWNLOAD_URLS.WINDOWS;
} else if (userAgent.includes("mac")) {
const isARM =
userAgent.includes("arm") || userAgent.includes("aarch64");
if (isARM) {
return DOWNLOAD_BASE_URL + "mac-installer.dmg";
} else {
return DOWNLOAD_BASE_URL + "mac-x86_64-installer.dmg";
}
// Universal Mac binary covers both Intel and Apple silicon, so we
// don't need to detect arch (which is unreliable on the web anyway -
// Apple-silicon Macs often report Intel in the UA).
return DOWNLOAD_URLS.MAC;
} else if (userAgent.includes("linux")) {
return DOWNLOAD_BASE_URL + "linux-x86_64.deb";
return DOWNLOAD_BASE_URL + DESKTOP_INSTALLER_FILES.LINUX_DEB;
}
return "https://github.com/Stirling-Tools/Stirling-PDF/releases/latest";
}