Files
calculate-version/app/config.js
T

113 lines
4.9 KiB
JavaScript
Raw Permalink 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,否則拋出錯誤(避免指向非預期協定或格式錯誤的位址)。
*
* 先以 `new URL(value)` 解析,無法解析時視為格式錯誤;解析成功後再檢查協定,
* 僅允許 `http:` 與 `https:`,其餘協定(如 ftp)一律拒絕。
*
* @param {string} name - 設定項名稱,用於組出錯誤訊息(例如 `GITEA_SERVER_URL`)。
* @param {string} value - 待驗證的 URL 字串。
* @returns {void} 驗證通過時不回傳值;不通過時改以拋出例外表示。
* @throws {Error} 當 value 無法解析為合法 URL 時拋出 `${name} 格式錯誤,必須為合法的 URL`。
* @throws {Error} 當 value 協定非 http/https 時拋出 `${name} 必須使用 http 或 https 協定`。
* @remarks 由 loadConfig 於驗證 GITEA_SERVER_URL 時呼叫,確保後續組出的 release API 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 協定`);
}
}
/**
* 驗證字串為合法的 `owner/repo` 形式,否則拋出錯誤。
*
* 此值會直接拼接於 release API URL`.../repos/{repository}/releases`),故須限制為單一斜線
* 分隔的合法 repo 字元,並排除含 `..` 等可能造成路徑穿越或非預期端點存取的輸入。
*
* @param {string} name - 設定項名稱,用於組出錯誤訊息(例如 `GITEA_REPOSITORY`)。
* @param {string} value - 待驗證的 `owner/repo` 字串。
* @returns {void} 驗證通過時不回傳值;不通過時改以拋出例外表示。
* @throws {Error} 當 value 非 `owner/repo` 形式、含非法字元或含 `..` 路徑穿越片段時拋出。
* @remarks 由 loadConfig 於驗證 GITEA_REPOSITORY 時呼叫;允許 repo 名稱含 `.`(如 `org/my.repo`),
* 但拒絕任何 `..` 片段與多餘斜線,避免拼接出非預期的 API 路徑。
*/
function assertRepository(name, value) {
if (!/^[A-Za-z0-9._-]+\/[A-Za-z0-9._-]+$/.test(value) || value.includes('..')) {
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 或 GITEA_REPOSITORY 未設定、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 };