Add frontend autoformatting and set CI to require formatted code for all languages (#6052)

# Description of Changes
Changes the strategy for autoformatting to reject PRs if they are not
formatted correctly instead of allowing them to merge and then spawning
a new PR to fix the formatting. The old strategy just caused more work
for us because we'd have to manually approve the followup PR and get it
merged, which required 2 reviewers so in practice it rarely got done and
just meant everyone's PRs ended up containing reformatting for unrelated
files, which makes code review unnecessarily difficult. If the PR's code
is not formatted correctly after this PR, a comment will be added
automatically to tell the author how to run the formatter script to fix
their code so it can go in.

This also enables autoformatting for the frontend code, using Prettier.
I've enabled it for pretty much everything in the frontend folder, other
than 3rd party files and files it doesn't make sense for. I also
excluded Markdown because it sounds likely to be more annoying to have
to autoformat the Markdown in the frontend folder but nowhere else. Open
to changing this though if people disagree.

> [!note]
> 
> Advice to reviewers: The first commit contains all of the actual logic
I've introduced (CI changes, Prettier config, etc.)
> The second commit is just the reformatting of the entire frontend
folder.
> The first commit needs proper review, the second one just give it a
spot-check that it's doing what you'd expect.
This commit is contained in:
James Brunton
2026-04-10 17:41:19 +01:00
committed by GitHub
parent 33b2b5827a
commit a3e45bc182
1359 changed files with 57784 additions and 57460 deletions
+40 -40
View File
@@ -1,9 +1,9 @@
import { DOWNLOAD_BASE_URL } from '@app/constants/downloads';
import { DOWNLOAD_BASE_URL } from "@app/constants/downloads";
export interface UpdateSummary {
latest_version: string | null;
latest_stable_version?: string | null;
max_priority: 'urgent' | 'normal' | 'minor' | 'low';
max_priority: "urgent" | "normal" | "minor" | "low";
recommended_action?: string;
any_breaking: boolean;
migration_guides?: Array<{
@@ -15,7 +15,7 @@ export interface UpdateSummary {
export interface VersionUpdate {
version: string;
priority: 'urgent' | 'normal' | 'minor' | 'low';
priority: "urgent" | "normal" | "minor" | "low";
announcement: {
title: string;
message: string;
@@ -40,15 +40,15 @@ export interface MachineInfo {
}
export class UpdateService {
private readonly baseUrl = 'https://supabase.stirling.com/functions/v1/updates';
private readonly baseUrl = "https://supabase.stirling.com/functions/v1/updates";
/**
* Compare two version strings
* @returns 1 if v1 > v2, -1 if v1 < v2, 0 if equal
*/
compareVersions(version1: string, version2: string): number {
const v1 = version1.split('.');
const v2 = version2.split('.');
const v1 = version1.split(".");
const v2 = version2.split(".");
for (let i = 0; i < v1.length || i < v2.length; i++) {
const n1 = parseInt(v1[i]) || 0;
@@ -69,26 +69,26 @@ export class UpdateService {
*/
getDownloadUrl(machineInfo: MachineInfo): string | null {
// Only show download for non-Docker installations
if (machineInfo.machineType === 'Docker' || machineInfo.machineType === 'Kubernetes') {
if (machineInfo.machineType === "Docker" || machineInfo.machineType === "Kubernetes") {
return null;
}
// Determine file based on machine type and security
if (machineInfo.machineType === 'Server-jar') {
return DOWNLOAD_BASE_URL + (machineInfo.activeSecurity ? 'Stirling-PDF-with-login.jar' : 'Stirling-PDF.jar');
if (machineInfo.machineType === "Server-jar") {
return DOWNLOAD_BASE_URL + (machineInfo.activeSecurity ? "Stirling-PDF-with-login.jar" : "Stirling-PDF.jar");
}
// Client installations
if (machineInfo.machineType.startsWith('Client-')) {
const os = machineInfo.machineType.replace('Client-', ''); // win, mac, unix
const type = machineInfo.activeSecurity ? '-server-security' : '-server';
if (machineInfo.machineType.startsWith("Client-")) {
const os = machineInfo.machineType.replace("Client-", ""); // win, mac, unix
const type = machineInfo.activeSecurity ? "-server-security" : "-server";
if (os === 'unix') {
return DOWNLOAD_BASE_URL + os + type + '.jar';
} else if (os === 'win') {
return DOWNLOAD_BASE_URL + os + '-installer.exe';
} else if (os === 'mac') {
return DOWNLOAD_BASE_URL + os + '-installer.dmg';
if (os === "unix") {
return DOWNLOAD_BASE_URL + os + type + ".jar";
} else if (os === "win") {
return DOWNLOAD_BASE_URL + os + "-installer.exe";
} else if (os === "mac") {
return DOWNLOAD_BASE_URL + os + "-installer.dmg";
}
}
@@ -100,29 +100,29 @@ export class UpdateService {
*/
async getUpdateSummary(currentVersion: string, machineInfo: MachineInfo): Promise<UpdateSummary | null> {
// Map Java License enum to API types
let type = 'normal';
if (machineInfo.licenseType === 'SERVER') {
type = 'server';
} else if (machineInfo.licenseType === 'ENTERPRISE') {
type = 'enterprise';
let type = "normal";
if (machineInfo.licenseType === "SERVER") {
type = "server";
} else if (machineInfo.licenseType === "ENTERPRISE") {
type = "enterprise";
}
const url = `${this.baseUrl}?from=${currentVersion}&type=${type}&login=${machineInfo.activeSecurity}&summary=true`;
console.log('Fetching update summary from:', url);
console.log("Fetching update summary from:", url);
try {
const response = await fetch(url);
console.log('Response status:', response.status);
console.log("Response status:", response.status);
if (response.status === 200) {
const data = await response.json();
return data as UpdateSummary;
} else {
console.error('Failed to fetch update summary from Supabase:', response.status);
console.error("Failed to fetch update summary from Supabase:", response.status);
return null;
}
} catch (error) {
console.error('Failed to fetch update summary from Supabase:', error);
console.error("Failed to fetch update summary from Supabase:", error);
return null;
}
}
@@ -132,29 +132,29 @@ export class UpdateService {
*/
async getFullUpdateInfo(currentVersion: string, machineInfo: MachineInfo): Promise<FullUpdateInfo | null> {
// Map Java License enum to API types
let type = 'normal';
if (machineInfo.licenseType === 'SERVER') {
type = 'server';
} else if (machineInfo.licenseType === 'ENTERPRISE') {
type = 'enterprise';
let type = "normal";
if (machineInfo.licenseType === "SERVER") {
type = "server";
} else if (machineInfo.licenseType === "ENTERPRISE") {
type = "enterprise";
}
const url = `${this.baseUrl}?from=${currentVersion}&type=${type}&login=${machineInfo.activeSecurity}&summary=false`;
console.log('Fetching full update info from:', url);
console.log("Fetching full update info from:", url);
try {
const response = await fetch(url);
console.log('Full update response status:', response.status);
console.log("Full update response status:", response.status);
if (response.status === 200) {
const data = await response.json();
return data as FullUpdateInfo;
} else {
console.error('Failed to fetch full update info from Supabase:', response.status);
console.error("Failed to fetch full update info from Supabase:", response.status);
return null;
}
} catch (error) {
console.error('Failed to fetch full update info from Supabase:', error);
console.error("Failed to fetch full update info from Supabase:", error);
return null;
}
}
@@ -163,7 +163,7 @@ export class UpdateService {
* Get current version from GitHub build.gradle as fallback
*/
async getCurrentVersionFromGitHub(): Promise<string> {
const url = 'https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/master/build.gradle';
const url = "https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/master/build.gradle";
try {
const response = await fetch(url);
@@ -175,10 +175,10 @@ export class UpdateService {
return match[1];
}
}
throw new Error('Version number not found');
throw new Error("Version number not found");
} catch (error) {
console.error('Failed to fetch latest version from build.gradle:', error);
return '';
console.error("Failed to fetch latest version from build.gradle:", error);
return "";
}
}
}