Files
calculate-version/app/releases.js
T

97 lines
3.2 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';
// 每頁取得的 release 筆數
const RELEASES_PER_PAGE = 10;
/**
* 以分頁方式取得指定 Gitea repo 的所有 release,並回傳合併後的陣列。
*
* 使用全域 fetch 逐頁請求,每頁 limit 為 10;當某頁回傳空資料、null
* 或筆數少於每頁上限時即停止取得。
*
* @param {string} baseUrl - release API 的基底 URL(不含 query string)。
* @param {object} [options={}] - 選用設定。
* @param {string} [options.token] - 授權 token;有值時以 `Authorization: token <token>`
* 進行授權請求,否則以匿名方式請求。
* @param {{ info: (message: string) => void }} [options.logger] - 選用的記錄器,
* 需提供 info() 方法以輸出進度訊息。
* @returns {Promise<Array>} 解析為所有 release 物件合併後的陣列;首頁即無資料時回傳空陣列。
* @throws {Error} 當網路請求失敗、response 非 2xx、回應本文讀取失敗、回傳資料無法解析,
* 或回傳非陣列資料時拋出。
* @remarks 依賴 Node.js 18+ 的全域 fetchbaseUrl 不含 query string,函式自行附加
* `?limit=<RELEASES_PER_PAGE>&page=<n>` 逐頁請求,直到某頁空字串/`null`/不足一頁為止。
*/
async function fetchReleases(baseUrl, options = {}) {
const { token, logger } = options;
const headers = {};
if (token) {
logger?.info('使用授權 token 取得 release');
headers.Authorization = `token ${token}`;
} else {
logger?.info('使用匿名請求取得 release');
}
let page = 1;
const combined = [];
while (true) {
const url = `${baseUrl}?limit=${RELEASES_PER_PAGE}&page=${page}`;
let response;
try {
response = await fetch(url, { headers });
} catch (error) {
throw new Error(`release API 請求失敗 (page=${page}): ${error.message}`);
}
if (!response.ok) {
throw new Error(`release API 請求失敗 (page=${page})`);
}
let text;
try {
text = await response.text();
} catch (error) {
throw new Error(`release API 回應讀取失敗 (page=${page}): ${error.message}`);
}
// 空字串或 null 代表已無更多資料
if (!text || text === 'null') {
break;
}
let pageJson;
try {
pageJson = JSON.parse(text);
} catch {
// 附上截斷的回傳內容(至多 200 字元)以利定位回傳格式異常的確切原因
const snippet = text.length > 200 ? `${text.slice(0, 200)}…` : text;
throw new Error(`release API 回傳資料無法解析 (page=${page})${snippet}`);
}
if (pageJson === null) {
break;
}
if (!Array.isArray(pageJson)) {
throw new Error(`release API 回傳非陣列資料 (page=${page})`);
}
const count = pageJson.length;
logger?.info(`第 ${page} 頁取得 ${count} 筆 release`);
combined.push(...pageJson);
// 不足一頁代表已取完
if (count < RELEASES_PER_PAGE) {
break;
}
page += 1;
}
return combined;
}
module.exports = { RELEASES_PER_PAGE, fetchReleases };