193 lines
7.7 KiB
JavaScript
193 lines
7.7 KiB
JavaScript
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
}
|
|
Object.defineProperty(o, k2, desc);
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || (function () {
|
|
var ownKeys = function(o) {
|
|
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
var ar = [];
|
|
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
return ar;
|
|
};
|
|
return ownKeys(o);
|
|
};
|
|
return function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
})();
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.updaterOutput = void 0;
|
|
exports.logDebug = logDebug;
|
|
exports.runUpdater = runUpdater;
|
|
exports.manualUpdateCheck = manualUpdateCheck;
|
|
const vscode = __importStar(require("vscode"));
|
|
const fs = __importStar(require("fs"));
|
|
const os = __importStar(require("os"));
|
|
const path = __importStar(require("path"));
|
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
// ================= LOGGING SETUP =================
|
|
exports.updaterOutput = vscode.window.createOutputChannel("Updater");
|
|
function logDebug(...args) {
|
|
const message = args
|
|
.map(a => (typeof a === "object" ? JSON.stringify(a, null, 2) : a))
|
|
.join(" ");
|
|
exports.updaterOutput.appendLine(message);
|
|
console.log(message); // optional, still shows in DevTools
|
|
exports.updaterOutput.show(true);
|
|
}
|
|
// ================= CONFIG =================
|
|
const CONFIG = {
|
|
apiBase: "https://git.cstmgames.dev/api/v1",
|
|
repo: "CSTMGames/FiveM_Snippets",
|
|
extensionId: "kj4lxc.cstmgames-fivem-snippets",
|
|
checkIntervalMs: 1000 * 60 * 60 * 6, // 6 hours
|
|
allowPrerelease: false,
|
|
authToken: "", // optional: "your_gitea_token"
|
|
};
|
|
// ================= UPDATER =================
|
|
async function runUpdater(context) {
|
|
// Run once on startup (silent)
|
|
await checkForUpdates(context, true);
|
|
// Schedule periodic checks
|
|
setInterval(() => {
|
|
checkForUpdates(context, true);
|
|
}, CONFIG.checkIntervalMs);
|
|
}
|
|
async function manualUpdateCheck(context) {
|
|
await checkForUpdates(context, false);
|
|
}
|
|
async function checkForUpdates(context, silent) {
|
|
try {
|
|
// Read user settings dynamically
|
|
const autoInstall = vscode.workspace
|
|
.getConfiguration("cstmgames.fivem_snippets")
|
|
.get("autoUpdate", false);
|
|
const now = Date.now();
|
|
const lastCheck = context.globalState.get("lastUpdateCheck") || 0;
|
|
// Prevent too frequent checks
|
|
if (now - lastCheck < CONFIG.checkIntervalMs && silent)
|
|
return;
|
|
context.globalState.update("lastUpdateCheck", now);
|
|
// Build Gitea releases URL
|
|
const url = `${CONFIG.apiBase}/repos/${CONFIG.repo}/releases`;
|
|
// Build headers safely
|
|
const headers = {};
|
|
if (CONFIG.authToken && CONFIG.authToken.length > 0) {
|
|
headers["Authorization"] = `token ${CONFIG.authToken}`;
|
|
}
|
|
logDebug(`[Updater] Checking Gitea releases URL: ${url}`);
|
|
logDebug(`[Updater] Headers:`, headers);
|
|
const res = await (0, node_fetch_1.default)(url, { headers });
|
|
logDebug(`[Updater] HTTP status: ${res.status}`);
|
|
if (!res.ok)
|
|
throw new Error(`HTTP ${res.status}`);
|
|
const dataRaw = await res.json();
|
|
let data = [];
|
|
if (Array.isArray(dataRaw)) {
|
|
data = dataRaw;
|
|
}
|
|
else {
|
|
logDebug("[Updater] Unexpected API response:", dataRaw);
|
|
}
|
|
logDebug(`[Updater] Releases data:`, data);
|
|
if (!Array.isArray(data) || data.length === 0) {
|
|
console.warn("[Updater] No releases found.");
|
|
return;
|
|
}
|
|
// Take the latest release (first in array)
|
|
const latestRelease = data[0];
|
|
const latestVersion = latestRelease.tag_name.replace(/^v/, "");
|
|
const ext = vscode.extensions.getExtension(CONFIG.extensionId);
|
|
if (!ext) {
|
|
console.warn(`[Updater] Extension ${CONFIG.extensionId} not found`);
|
|
return;
|
|
}
|
|
const currentVersion = ext.packageJSON.version;
|
|
logDebug(`[Updater] Current version: ${currentVersion}, Latest version: ${latestVersion}`);
|
|
if (latestVersion === currentVersion) {
|
|
if (!silent)
|
|
vscode.window.showInformationMessage("Extension is up to date.");
|
|
return;
|
|
}
|
|
const asset = latestRelease.assets?.find((a) => a.name.endsWith(".vsix"));
|
|
if (!asset) {
|
|
console.warn("[Updater] No VSIX asset found in latest release");
|
|
return;
|
|
}
|
|
logDebug(`[Updater] Latest VSIX URL: ${asset.browser_download_url}`);
|
|
if (autoInstall) {
|
|
await installVsix(asset.browser_download_url);
|
|
return;
|
|
}
|
|
const choice = await vscode.window.showInformationMessage(`Update available: ${currentVersion} → ${latestVersion}`, "Install", "Later");
|
|
if (choice === "Install") {
|
|
await installVsix(asset.browser_download_url);
|
|
}
|
|
}
|
|
catch (err) {
|
|
console.error("[Updater] Error checking updates:", err);
|
|
if (!silent) {
|
|
vscode.window.showErrorMessage(`Failed to check for updates: ${err}`);
|
|
}
|
|
}
|
|
}
|
|
// ================= INSTALL FUNCTION =================
|
|
async function installVsix(url) {
|
|
const tmpFile = path.join(os.tmpdir(), "update.vsix");
|
|
try {
|
|
logDebug("[Updater] Downloading VSIX from:", url);
|
|
// Fetch the VSIX
|
|
const res = await (0, node_fetch_1.default)(url);
|
|
if (!res.ok)
|
|
throw new Error(`HTTP ${res.status}`);
|
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
// Save to temp file
|
|
fs.writeFileSync(tmpFile, buffer);
|
|
logDebug("[Updater] VSIX saved to temp file:", tmpFile);
|
|
// Install extension from local file
|
|
await vscode.commands.executeCommand("workbench.extensions.installExtension", vscode.Uri.file(tmpFile));
|
|
logDebug("[Updater] Installed VSIX from temp file");
|
|
// Ask user to reload
|
|
const reload = await vscode.window.showInformationMessage("Extension updated successfully.", "Reload Now");
|
|
if (reload === "Reload Now") {
|
|
await vscode.commands.executeCommand("workbench.action.reloadWindow");
|
|
}
|
|
}
|
|
catch (err) {
|
|
logDebug("[Updater] Install failed:", err);
|
|
vscode.window.showErrorMessage("Failed to install update.");
|
|
}
|
|
finally {
|
|
// Clean up temp file
|
|
try {
|
|
if (fs.existsSync(tmpFile)) {
|
|
fs.unlinkSync(tmpFile);
|
|
logDebug("[Updater] Deleted temp VSIX file:", tmpFile);
|
|
}
|
|
}
|
|
catch (cleanupErr) {
|
|
logDebug("[Updater] Failed to delete temp VSIX file:", cleanupErr);
|
|
}
|
|
}
|
|
}
|
|
//# sourceMappingURL=updater.js.map
|