'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 ` * 進行授權請求,否則以匿名方式請求。 * @param {{ info: (message: string) => void }} [options.logger] - 選用的記錄器, * 需提供 info() 方法以輸出進度訊息。 * @returns {Promise} 解析為所有 release 物件合併後的陣列。 * @throws {Error} 當網路請求失敗、response 非 2xx、回傳資料無法解析, * 或回傳非陣列資料時拋出。 */ 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 { throw new Error(`release API 回傳資料無法解析 (page=${page})`); } 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 };