deleted unnecesary

This commit is contained in:
2026-05-31 18:45:57 +02:00
parent ce59c5db89
commit 8e6b79ca68
8 changed files with 41 additions and 135 deletions
+13 -9
View File
@@ -1,24 +1,28 @@
# Runtime / app # SCOREKO Configuration File Template
# Copy this file to '.env' in the application root and edit as needed.
# Application Information (Required)
SCOREKO_APP_TITLE=Scoreko SCOREKO_APP_TITLE=Scoreko
SCOREKO_APP_USER_MODEL_ID=com.scoreko.desktop SCOREKO_APP_USER_MODEL_ID=com.scoreko.desktop
SCOREKO_APP_USER_DATA_DIRECTORY=scoreko SCOREKO_APP_USER_DATA_DIRECTORY=scoreko
# SCOREKO_APP_ICON_PATH=static/icons/icon.ico SCOREKO_APP_ICON_PATH=static/icons/icon.ico
# NodeCG # NodeCG Managed Runtime Configuration (Required)
NODECG_BUNDLE_NAME=scoreko-dev NODECG_BUNDLE_NAME=scoreko-dev
NODECG_PORT=9090 NODECG_PORT=9090
SCOREKO_DASHBOARD_ROUTE=dashboard/scoreko-dev/main.html?standalone=true SCOREKO_DASHBOARD_ROUTE=dashboard/scoreko-dev/main.html?standalone=true
SCOREKO_LOADING_ROUTE=dashboard/loading/main.html?standalone=true SCOREKO_LOADING_ROUTE=dashboard/loading/main.html?standalone=true
# Timing # Timing & Lifecycles (Required)
ELECTRON_LOAD_DELAY_MS=10000 ELECTRON_LOAD_DELAY_MS=10000
NODECG_STARTUP_TIMEOUT_MS=120000 NODECG_STARTUP_TIMEOUT_MS=120000
NODECG_KILL_TIMEOUT_MS=2500 NODECG_KILL_TIMEOUT_MS=2500
# Updates # Automated Updates Configuration (Required)
SCOREKO_UPDATES_ENABLED=true SCOREKO_UPDATES_ENABLED=true
# SCOREKO_UPDATE_API_URL=http://gitea.local/api/v1/repos/OWNER/REPO/releases/latest
# SCOREKO_UPDATE_RELEASE_PAGE_URL=http://gitea.local/OWNER/REPO/releases
SCOREKO_UPDATE_ASSET_PATTERN=Scoreko-setup-.*\.exe$
SCOREKO_UPDATE_CHECK_DELAY_MS=5000 SCOREKO_UPDATE_CHECK_DELAY_MS=5000
# SCOREKO_UPDATE_CONFIG_PATH=static/updates.json
# Optional Update Release Source (Only required if SCOREKO_UPDATES_ENABLED is true)
SCOREKO_UPDATE_API_URL=http://gitea.local/api/v1/repos/OWNER/REPO/releases/latest
SCOREKO_UPDATE_RELEASE_PAGE_URL=http://gitea.local/OWNER/REPO/releases
SCOREKO_UPDATE_ASSET_PATTERN=Scoreko-setup-.*\.exe$
-4
View File
@@ -27,10 +27,6 @@ export function getSourceNodecgRuntimePath(rootPath: string): string {
return path.resolve(rootPath, "lib", "nodecg"); return path.resolve(rootPath, "lib", "nodecg");
} }
export function getDefaultUpdateConfigPath(rootPath: string): string {
return path.join(rootPath, "static", "updates.json");
}
export function getUpdateDownloadDirectory(tempDirectory: string): string { export function getUpdateDownloadDirectory(tempDirectory: string): string {
return path.join(tempDirectory, "scoreko-updates"); return path.join(tempDirectory, "scoreko-updates");
} }
-2
View File
@@ -16,7 +16,6 @@ export type AppRuntimeConfig = {
updateApiUrl?: string; updateApiUrl?: string;
updateReleasePageUrl?: string; updateReleasePageUrl?: string;
updateAssetPattern?: string; updateAssetPattern?: string;
updateConfigPathOverride?: string;
updateCheckDelayMs: number; updateCheckDelayMs: number;
}; };
@@ -55,7 +54,6 @@ export function getRuntimeConfig(): AppRuntimeConfig {
updateApiUrl: parseOptionalHttpUrl("SCOREKO_UPDATE_API_URL"), updateApiUrl: parseOptionalHttpUrl("SCOREKO_UPDATE_API_URL"),
updateReleasePageUrl: parseOptionalHttpUrl("SCOREKO_UPDATE_RELEASE_PAGE_URL"), updateReleasePageUrl: parseOptionalHttpUrl("SCOREKO_UPDATE_RELEASE_PAGE_URL"),
updateAssetPattern: getOptionalEnv("SCOREKO_UPDATE_ASSET_PATTERN"), updateAssetPattern: getOptionalEnv("SCOREKO_UPDATE_ASSET_PATTERN"),
updateConfigPathOverride: getOptionalEnv("SCOREKO_UPDATE_CONFIG_PATH"),
updateCheckDelayMs: parseRequiredEnvIntInRange("SCOREKO_UPDATE_CHECK_DELAY_MS", 0, 600000), updateCheckDelayMs: parseRequiredEnvIntInRange("SCOREKO_UPDATE_CHECK_DELAY_MS", 0, 600000),
}; };
} }
+7 -49
View File
@@ -1,9 +1,6 @@
import fs from "node:fs";
import { getDefaultUpdateConfigPath } from "../app/paths";
import { AppRuntimeConfig } from "../config/runtime-config"; import { AppRuntimeConfig } from "../config/runtime-config";
import { isRecord, readNonEmptyString } from "../utils/unknown-values"; import { readNonEmptyString } from "../utils/unknown-values";
import { UpdateFileConfig, validateHttpUrl } from "./update-schema"; import { validateHttpUrl } from "./update-schema";
const DEFAULT_UPDATE_ASSET_PATTERN = "Scoreko-setup-.*\\.exe$"; const DEFAULT_UPDATE_ASSET_PATTERN = "Scoreko-setup-.*\\.exe$";
@@ -20,11 +17,7 @@ type UpdateConfigOptions = {
type UpdateRuntimeConfig = Pick< type UpdateRuntimeConfig = Pick<
AppRuntimeConfig, AppRuntimeConfig,
| "updateApiUrl" "updateApiUrl" | "updateAssetPattern" | "updateReleasePageUrl" | "updatesEnabled"
| "updateAssetPattern"
| "updateConfigPathOverride"
| "updateReleasePageUrl"
| "updatesEnabled"
>; >;
export function loadUpdateSettings( export function loadUpdateSettings(
@@ -33,49 +26,14 @@ export function loadUpdateSettings(
log: (...args: unknown[]) => void, log: (...args: unknown[]) => void,
options: UpdateConfigOptions = { allowInsecureHttp: true }, options: UpdateConfigOptions = { allowInsecureHttp: true },
): UpdateSettings { ): UpdateSettings {
const fileConfig = readUpdateFileConfig(appConfig, rootPath, log); const apiUrl = readOptionalHttpUrl(appConfig.updateApiUrl, options);
const apiUrl = readOptionalHttpUrl(appConfig.updateApiUrl ?? fileConfig.apiUrl, options); const releasePageUrl = readOptionalHttpUrl(appConfig.updateReleasePageUrl, options);
const releasePageUrl = readOptionalHttpUrl(appConfig.updateReleasePageUrl ?? fileConfig.releasePageUrl, options);
return { return {
enabled: appConfig.updatesEnabled && (Boolean(fileConfig.enabled) || Boolean(appConfig.updateApiUrl)) && Boolean(apiUrl), enabled: appConfig.updatesEnabled && Boolean(apiUrl),
...(apiUrl ? { apiUrl } : {}), ...(apiUrl ? { apiUrl } : {}),
...(releasePageUrl ? { releasePageUrl } : {}), ...(releasePageUrl ? { releasePageUrl } : {}),
assetPattern: assetPattern: appConfig.updateAssetPattern || DEFAULT_UPDATE_ASSET_PATTERN,
appConfig.updateAssetPattern || readNonEmptyString(fileConfig.assetPattern) || DEFAULT_UPDATE_ASSET_PATTERN,
};
}
export function readUpdateFileConfig(
appConfig: Pick<AppRuntimeConfig, "updateConfigPathOverride">,
rootPath: string,
log: (...args: unknown[]) => void,
): UpdateFileConfig {
const configPath = appConfig.updateConfigPathOverride ?? getDefaultUpdateConfigPath(rootPath);
if (!fs.existsSync(configPath)) {
return {};
}
try {
const parsedConfig: unknown = JSON.parse(fs.readFileSync(configPath, "utf8"));
return normalizeUpdateFileConfig(parsedConfig);
} catch (error) {
log(`Could not read update config at ${configPath}.`, error);
return {};
}
}
function normalizeUpdateFileConfig(value: unknown): UpdateFileConfig {
if (!isRecord(value)) {
return {};
}
return {
enabled: value.enabled,
apiUrl: value.apiUrl,
releasePageUrl: value.releasePageUrl,
assetPattern: value.assetPattern,
}; };
} }
-7
View File
@@ -26,13 +26,6 @@ export type ReleaseUpdate = {
installer: InstallerAsset; installer: InstallerAsset;
}; };
export type UpdateFileConfig = {
enabled?: unknown;
apiUrl?: unknown;
releasePageUrl?: unknown;
assetPattern?: unknown;
};
type UrlPolicy = { type UrlPolicy = {
allowInsecureHttp: boolean; allowInsecureHttp: boolean;
}; };
-2
View File
@@ -5,7 +5,6 @@ import test from "node:test";
import { import {
getApplicationPaths, getApplicationPaths,
getDashboardUrl, getDashboardUrl,
getDefaultUpdateConfigPath,
getManagedNodecgRuntimePath, getManagedNodecgRuntimePath,
getNodecgBaseUrl, getNodecgBaseUrl,
getRootPath, getRootPath,
@@ -23,7 +22,6 @@ test("app path helpers build deterministic development paths and URLs", () => {
assert.equal(getSourceNodecgRuntimePath(rootPath), path.resolve(rootPath, "lib", "nodecg")); assert.equal(getSourceNodecgRuntimePath(rootPath), path.resolve(rootPath, "lib", "nodecg"));
assert.equal(getUserDataPath("/app-data", "scoreko"), path.join("/app-data", "scoreko")); assert.equal(getUserDataPath("/app-data", "scoreko"), path.join("/app-data", "scoreko"));
assert.equal(getManagedNodecgRuntimePath("/app-data/scoreko"), path.join("/app-data/scoreko", "nodecg")); assert.equal(getManagedNodecgRuntimePath("/app-data/scoreko"), path.join("/app-data/scoreko", "nodecg"));
assert.equal(getDefaultUpdateConfigPath(rootPath), path.join(rootPath, "static", "updates.json"));
assert.equal(getUpdateDownloadDirectory("/tmp"), path.join("/tmp", "scoreko-updates")); assert.equal(getUpdateDownloadDirectory("/tmp"), path.join("/tmp", "scoreko-updates"));
assert.equal(getNodecgBaseUrl("9090"), "http://127.0.0.1:9090"); assert.equal(getNodecgBaseUrl("9090"), "http://127.0.0.1:9090");
assert.equal( assert.equal(
+21 -56
View File
@@ -1,11 +1,8 @@
import assert from "node:assert/strict"; import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import test from "node:test"; import test from "node:test";
import { AppRuntimeConfig } from "../main/config/runtime-config"; import { AppRuntimeConfig } from "../main/config/runtime-config";
import { loadUpdateSettings, readUpdateFileConfig } from "../main/updates/update-config"; import { loadUpdateSettings } from "../main/updates/update-config";
const baseConfig: AppRuntimeConfig = { const baseConfig: AppRuntimeConfig = {
title: "Scoreko", title: "Scoreko",
@@ -23,37 +20,36 @@ const baseConfig: AppRuntimeConfig = {
}; };
test("loadUpdateSettings keeps updates disabled when the runtime config disables them", () => { test("loadUpdateSettings keeps updates disabled when the runtime config disables them", () => {
const rootPath = makeTempRoot({ const settings = loadUpdateSettings(
enabled: true, {
apiUrl: "https://gitea.local/releases/latest", ...baseConfig,
}); updatesEnabled: false,
updateApiUrl: "https://gitea.local/releases/latest",
const settings = loadUpdateSettings({ ...baseConfig, updatesEnabled: false }, rootPath, () => undefined); },
"",
() => undefined,
);
assert.equal(settings.enabled, false); assert.equal(settings.enabled, false);
assert.equal(settings.apiUrl, "https://gitea.local/releases/latest"); assert.equal(settings.apiUrl, "https://gitea.local/releases/latest");
}); });
test("loadUpdateSettings fails closed on insecure production update URLs", () => { test("loadUpdateSettings fails closed on insecure production update URLs", () => {
const rootPath = makeTempRoot({ const settings = loadUpdateSettings(
enabled: true, {
apiUrl: "http://gitea.local/releases/latest", ...baseConfig,
}); updateApiUrl: "http://gitea.local/releases/latest",
},
const settings = loadUpdateSettings(baseConfig, rootPath, () => undefined, { allowInsecureHttp: false }); "",
() => undefined,
{ allowInsecureHttp: false },
);
assert.equal(settings.enabled, false); assert.equal(settings.enabled, false);
assert.equal(settings.apiUrl, undefined); assert.equal(settings.apiUrl, undefined);
}); });
test("loadUpdateSettings lets runtime config override file settings", () => { test("loadUpdateSettings lets runtime config specify settings", () => {
const rootPath = makeTempRoot({
enabled: true,
apiUrl: "https://file.local/releases/latest",
releasePageUrl: "https://file.local/releases",
assetPattern: "File-.*\\.exe$",
});
const settings = loadUpdateSettings( const settings = loadUpdateSettings(
{ {
...baseConfig, ...baseConfig,
@@ -61,7 +57,7 @@ test("loadUpdateSettings lets runtime config override file settings", () => {
updateReleasePageUrl: "https://env.local/releases", updateReleasePageUrl: "https://env.local/releases",
updateAssetPattern: "Env-.*\\.exe$", updateAssetPattern: "Env-.*\\.exe$",
}, },
rootPath, "",
() => undefined, () => undefined,
); );
@@ -72,34 +68,3 @@ test("loadUpdateSettings lets runtime config override file settings", () => {
assetPattern: "Env-.*\\.exe$", assetPattern: "Env-.*\\.exe$",
}); });
}); });
test("readUpdateFileConfig normalizes malformed config into an empty file config", () => {
const rootPath = makeTempRoot(["not", "an", "object"]);
assert.deepEqual(readUpdateFileConfig(baseConfig, rootPath, () => undefined), {});
});
test("readUpdateFileConfig logs invalid JSON and returns an empty file config", () => {
const rootPath = fs.mkdtempSync(path.join(os.tmpdir(), "scoreko-update-config-"));
const staticPath = path.join(rootPath, "static");
fs.mkdirSync(staticPath, { recursive: true });
fs.writeFileSync(path.join(staticPath, "updates.json"), "{ invalid", "utf8");
const messages: unknown[][] = [];
const settings = readUpdateFileConfig(baseConfig, rootPath, (...args: unknown[]) => {
messages.push(args);
});
assert.deepEqual(settings, {});
assert.equal(messages.length, 1);
});
function makeTempRoot(config: unknown): string {
const rootPath = fs.mkdtempSync(path.join(os.tmpdir(), "scoreko-update-config-"));
const staticPath = path.join(rootPath, "static");
fs.mkdirSync(staticPath, { recursive: true });
fs.writeFileSync(path.join(staticPath, "updates.json"), JSON.stringify(config), "utf8");
return rootPath;
}
-6
View File
@@ -1,6 +0,0 @@
{
"enabled": false,
"apiUrl": "http://gitea.local/api/v1/repos/OWNER/REPO/releases/latest",
"releasePageUrl": "http://gitea.local/OWNER/REPO/releases",
"assetPattern": "Scoreko-setup-.*\\.exe$"
}