UNPKG

winterspec

Version:

Write Winter-CG compatible routes with filesystem routing and tons of features

98 lines (97 loc) 3.66 kB
import path from "node:path"; import fs from "node:fs/promises"; import { bundleRequire } from "bundle-require"; import Debug from "debug"; const cloneObjectAndDeleteUndefinedKeys = (obj) => { const clone = { ...obj }; Object.keys(clone).forEach((key) => { if (clone[key] === undefined) { delete clone[key]; } }); return clone; }; const resolvePossibleRelativePath = (possibleRelativePath, configDirectory) => { if (path.isAbsolute(possibleRelativePath)) { return possibleRelativePath; } return path.resolve(configDirectory, possibleRelativePath); }; /** * Resolves relative paths and sets defaults for any missing values. */ export const resolveConfig = (config) => { const { rootDirectory, tsconfigPath, routesDirectory, ...rest } = cloneObjectAndDeleteUndefinedKeys(config); const resolvedRootDirectory = path.resolve(config.rootDirectory); return { rootDirectory: resolvedRootDirectory, tsconfigPath: resolvePossibleRelativePath(tsconfigPath ?? "tsconfig.json", resolvedRootDirectory), routesDirectory: resolvePossibleRelativePath(routesDirectory ?? "api", resolvedRootDirectory), platform: "wintercg-minimal", ...rest, }; }; const validateConfig = async (config) => { const debug = Debug("winterspec:validateConfig"); debug("Validating config..."); try { await fs.stat(config.routesDirectory); debug("Routes directory found: %s", config.routesDirectory); } catch (error) { throw new Error(`Could not find routes directory ${config.routesDirectory}`); } try { await fs.stat(config.tsconfigPath); debug("Tsconfig.json found: %s", config.tsconfigPath); } catch (error) { throw new Error(`Could not find tsconfig.json at ${config.tsconfigPath}`); } return config; }; export const loadConfig = async (rootDirectory, overrides) => { const debug = Debug("winterspec:loadConfig"); let loadedConfig = {}; let configInRootExists = false; const potentialConfigPath = path.join(rootDirectory, "winterspec.config.ts"); debug("Checking for config in root directory: %s", potentialConfigPath); try { await fs.stat(potentialConfigPath); configInRootExists = true; debug("Config found in root directory: %s", potentialConfigPath); } catch { debug("No config found in root directory: %s", potentialConfigPath); } if (configInRootExists) { debug("Loading config from root directory: %s", potentialConfigPath); let config; if (typeof Bun !== "undefined") { debug("Bun is available, using dynamic import"); config = await import(potentialConfigPath).catch((e) => { debug("failed to dynamically import config", e); return null; }); } else { debug("Calling bundleRequire..."); const { mod } = await bundleRequire({ filepath: potentialConfigPath, }); config = mod.default; } if (!config) { debug("No config found in root directory: %s", potentialConfigPath); throw new Error(`Could not find a default export in ${potentialConfigPath}`); } debug("Config loaded from root directory: %s", potentialConfigPath); loadedConfig = config.default ?? config; } debug("Validating config..."); return await validateConfig(resolveConfig({ rootDirectory, ...loadedConfig, ...cloneObjectAndDeleteUndefinedKeys(overrides ?? {}), })); };