UNPKG

@lonu/stc

Version:

A tool for converting OpenApi/Swagger/Apifox into code.

99 lines (98 loc) 3.21 kB
import * as dntShim from "../_dnt.shims.js"; import { exists } from "../deps/jsr.io/@std/fs/1.0.24/mod.js"; import { pathToFileURL } from "node:url"; import { readFile } from "./utils.js"; /** * 支持的配置文件名,按查找优先级排序 */ export const CONFIG_FILE_NAMES = [ "stc.config.json", "stc.config.ts", "stc.config.js", ".stcrc.json", ".stcrc", ]; /** * 查找配置文件 * * @param explicitPath - 通过 `--config` 显式指定的路径 * @returns 配置文件路径,未找到时返回 undefined */ export const findConfigFile = async (explicitPath) => { if (explicitPath) { return (await exists(explicitPath)) ? explicitPath : undefined; } for (const name of CONFIG_FILE_NAMES) { if (await exists(name)) return name; } return undefined; }; /** * 读取并解析配置文件内容 * * @param path - 配置文件路径 * @returns 配置对象 */ export const parseConfigContent = (content, path) => { if (!content.trim()) return {}; try { const data = JSON.parse(content); if (typeof data !== "object" || data === null || Array.isArray(data)) { throw new Error("invalid config content"); } return data; } catch (error) { const message = error instanceof Error ? error.message : String(error); throw new Error(`${path}: ${message}`); } }; /** * 加载配置文件 * * @param explicitPath - 通过 `--config` 显式指定的路径 * @returns 配置对象,未找到配置文件时返回空对象 */ export const loadConfigFile = async (explicitPath) => { const path = await findConfigFile(explicitPath); if (!path) { // 未找到配置文件。显式指定但不存在的情况,由调用方判断处理 return { options: {}, path: undefined }; } // ts/js 配置文件通过动态导入加载,支持 `export default` if (path.endsWith(".ts") || path.endsWith(".js")) { // 配置文件可能在 watch 模式下被重复加载,使用查询参数绕过模块缓存。 const modulePath = await dntShim.Deno.realPath(path); const module = await import(`${pathToFileURL(modulePath).href}?stc_config_reload=${Date.now()}`); const config = module.default ?? module; if (typeof config !== "object" || config === null) { throw new Error(`${path}: invalid config content`); } return { options: config, path }; } const content = await readFile(path); return { options: parseConfigContent(content, path), path }; }; /** * 规范化配置:`filter`、`globalHeader` 支持字符串或字符串数组 * * @param options - 配置对象 */ export const normalizeConfig = (options) => { const result = { ...options }; ["filter", "globalHeader"].forEach((key) => { const value = result[key]; if (typeof value === "string") { result[key] = [value]; } }); if (typeof result.interval === "string") { const value = Number(result.interval); if (!Number.isNaN(value)) { result.interval = value; } } return result; };