Spaces:
Running
Running
File size: 3,255 Bytes
c0a9bce |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
export interface UpdateCheckResult {
available: boolean;
version: string;
releaseNotes?: string;
error?: {
type: 'rate_limit' | 'network' | 'auth' | 'unknown';
message: string;
};
}
interface PackageJson {
version: string;
name: string;
[key: string]: unknown;
}
function compareVersions(v1: string, v2: string): number {
// Remove 'v' prefix if present
const version1 = v1.replace(/^v/, '');
const version2 = v2.replace(/^v/, '');
const parts1 = version1.split('.').map(Number);
const parts2 = version2.split('.').map(Number);
for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
const part1 = parts1[i] || 0;
const part2 = parts2[i] || 0;
if (part1 !== part2) {
return part1 - part2;
}
}
return 0;
}
export const checkForUpdates = async (): Promise<UpdateCheckResult> => {
try {
// Get the current version from local package.json
const packageResponse = await fetch('/package.json');
if (!packageResponse.ok) {
throw new Error('Failed to fetch local package.json');
}
const packageData = (await packageResponse.json()) as PackageJson;
if (!packageData.version || typeof packageData.version !== 'string') {
throw new Error('Invalid package.json format: missing or invalid version');
}
const currentVersion = packageData.version;
/*
* Get the latest version from GitHub's main branch package.json
* Using raw.githubusercontent.com which doesn't require authentication
*/
const latestPackageResponse = await fetch(
'https://raw.githubusercontent.com/stackblitz-labs/bolt.diy/main/package.json',
);
if (!latestPackageResponse.ok) {
throw new Error(`Failed to fetch latest package.json: ${latestPackageResponse.status}`);
}
const latestPackageData = (await latestPackageResponse.json()) as PackageJson;
if (!latestPackageData.version || typeof latestPackageData.version !== 'string') {
throw new Error('Invalid remote package.json format: missing or invalid version');
}
const latestVersion = latestPackageData.version;
// Compare versions semantically
const hasUpdate = compareVersions(latestVersion, currentVersion) > 0;
return {
available: hasUpdate,
version: latestVersion,
releaseNotes: hasUpdate ? 'Update available. Check GitHub for release notes.' : undefined,
};
} catch (error) {
console.error('Error checking for updates:', error);
// Determine error type
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
const isNetworkError =
errorMessage.toLowerCase().includes('network') || errorMessage.toLowerCase().includes('fetch');
return {
available: false,
version: 'unknown',
error: {
type: isNetworkError ? 'network' : 'unknown',
message: `Failed to check for updates: ${errorMessage}`,
},
};
}
};
export const acknowledgeUpdate = async (version: string): Promise<void> => {
// Store the acknowledged version in localStorage
try {
localStorage.setItem('last_acknowledged_update', version);
} catch (error) {
console.error('Failed to store acknowledged version:', error);
}
};
|