UNPKG

@maizzle/framework

Version:

Maizzle is a framework that helps you quickly build HTML emails with Tailwind CSS.

135 lines (116 loc) 4.09 kB
import { resolve } from 'pathe' import get from 'lodash/get.js' import { defu as merge } from 'defu' import { lstat } from 'node:fs/promises' import isEmpty from 'lodash-es/isEmpty.js' /** * Compute the Maizzle config object. * * If a config file path is provided, that file will be read * instead of trying to merge the base and environment configs. * * If an environment is provided, the config object will be * computed based on a base config and the resolved * environment config. * * @param {string} env - The environment name to use. * @param {string} path - The path to the config file to use. * @returns {Promise<object>} The computed config object. */ export async function readFileConfig(config) { try { /** * If `config` is string, try to read and return * the config object from it. */ if (typeof config === 'string' && config) { const { default: resolvedConfig } = await import(`file://${resolve(config)}?d=${Date.now()}`) .catch(() => { throw new Error('Could not read config file') }) return merge(resolvedConfig, { env: config }) } /** * Otherwise, default to the Environment config approach, * where we check for config files that follow a * specific naming convention. * * First, we check for a base config file, in this order: */ const baseConfigFileNames = [ './maizzle.config.js', './maizzle.config.local.js', './config.js', './config.local.js', './maizzle.config.cjs', './maizzle.config.local.cjs', './config.cjs', './config.local.cjs', ] const env = get(config, 'env', 'local') let baseConfig = merge({ env }, config) let envConfig = merge({ env }, config) const cwd = env === 'maizzle-ci' ? './test/stubs/config' : process.cwd() // We load the first base config found for (const module of baseConfigFileNames) { // Check if the file exists, go to next one if not const configFileExists = await lstat(resolve(cwd, module)).catch(() => false) if (!configFileExists) { continue } // Load the config file try { const { default: baseConfigFile } = await import(`file://${resolve(cwd, module)}?d=${Date.now()}`) // Use the first base config found if (!isEmpty(baseConfigFile)) { baseConfig = merge(baseConfigFile, baseConfig) break } } catch (error) { break } } // Then, we load and compute the first Environment config found if (env !== 'local') { let loaded = false const modulesToTry = [ `./maizzle.config.${env}.js`, `./config.${env}.js`, `./maizzle.config.${env}.cjs`, `./config.${env}.cjs`, ] for (const module of modulesToTry) { // Check if the file exists, go to next one if not const configFileExists = await lstat(resolve(cwd, module)).catch(() => false) if (!configFileExists) { continue } // Load the config file try { const { default: envConfigFile } = await import(`file://${resolve(cwd, module)}?d=${Date.now()}`) // If it's not an empty object, merge it with the base config if (!isEmpty(envConfigFile)) { envConfig = merge(envConfigFile, envConfig) loaded = true break } } catch (error) { break } } if (!loaded) { throw new Error(`Failed to load the \`${env}\` environment config, do you have one of these files in your project root?\n\n${modulesToTry.join('\n')}`) } } /** * Override the `content` key in `baseConfig` with the one in `envConfig`. * * This is done so that each build uses its own `content` paths, in * order to avoid compiling unnecessary files. */ if (Array.isArray(envConfig.content)) { baseConfig.content = [] } return merge(envConfig, baseConfig) } catch (error) { throw new Error('Could not compute config') } }