Release v0.2.0
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
'use strict';
|
||||
|
||||
const https = require('https');
|
||||
|
||||
const LATEST_RELEASE_URL = 'https://api.github.com/repos/FunplayAI/funplay-cocos-mcp/releases/latest';
|
||||
|
||||
function normalizeVersion(value) {
|
||||
return String(value || '')
|
||||
.trim()
|
||||
.replace(/^v/i, '')
|
||||
.split(/[+-]/)[0];
|
||||
}
|
||||
|
||||
function parseVersion(value) {
|
||||
return normalizeVersion(value)
|
||||
.split('.')
|
||||
.map((part) => Number.parseInt(part, 10))
|
||||
.map((part) => (Number.isFinite(part) ? part : 0));
|
||||
}
|
||||
|
||||
function compareVersions(left, right) {
|
||||
const leftParts = parseVersion(left);
|
||||
const rightParts = parseVersion(right);
|
||||
const length = Math.max(leftParts.length, rightParts.length, 3);
|
||||
for (let index = 0; index < length; index += 1) {
|
||||
const leftPart = leftParts[index] || 0;
|
||||
const rightPart = rightParts[index] || 0;
|
||||
if (leftPart > rightPart) return 1;
|
||||
if (leftPart < rightPart) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function fetchJson(url, timeoutMs = 5000) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = https.get(
|
||||
url,
|
||||
{
|
||||
headers: {
|
||||
Accept: 'application/vnd.github+json',
|
||||
'User-Agent': 'funplay-cocos-mcp-update-checker',
|
||||
},
|
||||
timeout: timeoutMs,
|
||||
},
|
||||
(response) => {
|
||||
const chunks = [];
|
||||
response.on('data', (chunk) => chunks.push(chunk));
|
||||
response.on('end', () => {
|
||||
const body = Buffer.concat(chunks).toString('utf8');
|
||||
if (response.statusCode < 200 || response.statusCode >= 300) {
|
||||
reject(new Error(`GitHub returned HTTP ${response.statusCode}: ${body.slice(0, 160)}`));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
resolve(JSON.parse(body));
|
||||
} catch (error) {
|
||||
reject(new Error(`Failed to parse GitHub response: ${error.message}`));
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
request.on('timeout', () => {
|
||||
request.destroy(new Error(`Update check timed out after ${timeoutMs}ms.`));
|
||||
});
|
||||
request.on('error', reject);
|
||||
});
|
||||
}
|
||||
|
||||
async function checkForUpdate(options = {}) {
|
||||
const currentVersion = normalizeVersion(options.currentVersion || '0.0.0');
|
||||
const checkedAt = new Date().toISOString();
|
||||
|
||||
try {
|
||||
const release = await fetchJson(options.url || LATEST_RELEASE_URL, options.timeoutMs || 5000);
|
||||
const latestVersion = normalizeVersion(release.tag_name || release.name || '');
|
||||
const comparison = latestVersion ? compareVersions(latestVersion, currentVersion) : 0;
|
||||
return {
|
||||
ok: true,
|
||||
checkedAt,
|
||||
currentVersion,
|
||||
latestVersion,
|
||||
updateAvailable: comparison > 0,
|
||||
releaseUrl: release.html_url || '',
|
||||
publishedAt: release.published_at || '',
|
||||
source: options.url || LATEST_RELEASE_URL,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
ok: false,
|
||||
checkedAt,
|
||||
currentVersion,
|
||||
latestVersion: '',
|
||||
updateAvailable: false,
|
||||
releaseUrl: '',
|
||||
publishedAt: '',
|
||||
source: options.url || LATEST_RELEASE_URL,
|
||||
error: error.message,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
LATEST_RELEASE_URL,
|
||||
checkForUpdate,
|
||||
compareVersions,
|
||||
normalizeVersion,
|
||||
};
|
||||
Reference in New Issue
Block a user