Files
calculate-version/app/config.js
T
JefferyandClaude Opus 4.8 b8804c5218 fix(calculate-version): 強化輸入驗證與錯誤訊息
- config 對 GITEA_REPOSITORY 加入 owner/repo 格式驗證,拒絕路徑穿越與特殊字元
- releases JSON 解析失敗時,錯誤訊息納入截斷的回傳內容片段以利除錯

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 14:01:30 +08:00

91 lines
3.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use strict';
/**
* 判斷環境變數值是否視為「未設定」。
*
* 下列任一情況皆視為未設定:undefined、null、空字串、字面字串 "null"。
*
* @param {*} value - 欲檢查的值(通常為環境變數字串)。
* @returns {boolean} 視為未設定時回傳 true,否則回傳 false。
*/
function isUnset(value) {
return value === undefined || value === null || value === '' || value === 'null';
}
/**
* 驗證必填環境變數;未設定時拋出錯誤。
*
* @param {string} name - 環境變數名稱,用於組出錯誤訊息。
* @param {*} value - 環境變數的值。
* @returns {*} 驗證通過後原樣回傳的 value。
* @throws {Error} 當 value 被視為未設定(undefined/null/空字串/"null")時拋出,訊息為 `${name} 未設定`。
*/
function requireEnv(name, value) {
if (isUnset(value)) {
throw new Error(`${name} 未設定`);
}
return value;
}
/**
* 將 beta 旗標正規化為布林值。
*
* 未設定時預設為 false;僅當值嚴格等於字面字串 "true" 時回傳 true。
*
* @param {*} value - beta 旗標環境變數的值。
* @returns {boolean} 啟用 beta 時回傳 true,否則回傳 false。
*/
function normalizeBetaFlag(value) {
if (isUnset(value)) {
return false;
}
return value === 'true';
}
// 驗證字串為合法的 http/https URL,否則拋出錯誤(避免指向非預期協定或格式錯誤的位址)
function assertHttpUrl(name, value) {
let parsed;
try {
parsed = new URL(value);
} catch {
throw new Error(`${name} 格式錯誤,必須為合法的 URL`);
}
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
throw new Error(`${name} 必須使用 http 或 https 協定`);
}
}
// 驗證 repository 為 owner/repo 格式(僅允許字母數字與 . _ -,且拒絕 . 與 .. 路徑穿越段)
function assertRepository(name, value) {
const parts = value.split('/');
const valid = parts.length === 2
&& parts.every((part) => /^[A-Za-z0-9._-]+$/.test(part) && part !== '.' && part !== '..');
if (!valid) {
throw new Error(`${name} 格式錯誤,必須為 owner/repo`);
}
}
/**
* 從環境變數載入並驗證執行所需的設定。
*
* GITEA_SERVER_URL 與 GITEA_REPOSITORY 為必填,未設定時會拋出錯誤;GITEA_SERVER_URL
* 另需為合法的 http/https URLGITEA_REPOSITORY 另需為 owner/repo 格式;
* GITEA_TOKEN 為非必填,未設定時為 null;IS_BETA 會被正規化為布林值。
*
* @param {Object} [env=process.env] - 環境變數來源物件,預設為 process.env。
* @returns {{ serverUrl: string, repository: string, token: (string|null), isBeta: boolean }} 已驗證的設定物件。
* @throws {Error} 當必填項未設定、GITEA_SERVER_URL 非合法 http/https URL,或 GITEA_REPOSITORY 非 owner/repo 格式時拋出。
*/
function loadConfig(env = process.env) {
const serverUrl = requireEnv('GITEA_SERVER_URL', env.GITEA_SERVER_URL);
assertHttpUrl('GITEA_SERVER_URL', serverUrl);
const repository = requireEnv('GITEA_REPOSITORY', env.GITEA_REPOSITORY);
assertRepository('GITEA_REPOSITORY', repository);
const token = isUnset(env.GITEA_TOKEN) ? null : env.GITEA_TOKEN;
const isBeta = normalizeBetaFlag(env.IS_BETA);
return { serverUrl, repository, token, isBeta };
}
module.exports = { isUnset, requireEnv, normalizeBetaFlag, loadConfig };