UNPKG

nuxt-prepare

Version:
175 lines (170 loc) 5.38 kB
import { defineNuxtModule, useLogger, findPath, addTemplate } from '@nuxt/kit'; import { defu } from 'defu'; import * as importx from 'importx'; import { interopDefault } from 'mlly'; import { join } from 'pathe'; import { pascalCase } from 'scule'; const name = "nuxt-prepare"; const version = "2.3.2"; function toArray(value) { return Array.isArray(value) ? value : [value]; } function isObject(value) { return Object.prototype.toString.call(value) === "[object Object]"; } const module = defineNuxtModule({ meta: { name, version, configKey: "prepare", compatibility: { nuxt: ">=3.0.0" } }, defaults: { scripts: ["server.prepare"], parallel: false, continueOnError: false, runOnNuxtPrepare: true }, async setup(options, nuxt) { const moduleName = name; const logger = useLogger(moduleName); const extensions = [".js", ".mjs", ".ts"]; let successCount = 0; let errorCount = 0; let resolvedScripts = []; let state = {}; for (const script of toArray(options.scripts)) { let name2 = typeof script === "string" ? script : script.file; for (const ext of extensions) { if (name2.endsWith(ext)) { name2 = name2.slice(0, -ext.length); break; } } const path = await findPath(name2, { extensions }, "file"); if (name2 === "server.prepare" && !path) { continue; } if (!path) { logger.error( `Server prepare script \`${name2}{${extensions.join(",")}}\` not found. Please create the file or remove it from the \`prepare.scripts\` module option.` ); throw new Error("Server prepare script not found"); } resolvedScripts.push({ name: name2, path, runOnNuxtPrepare: typeof script === "string" ? true : script.runOnNuxtPrepare ?? true }); } const scriptNames = /* @__PURE__ */ new Set(); resolvedScripts = resolvedScripts.filter(({ name: name2 }) => { if (scriptNames.has(name2)) return false; scriptNames.add(name2); return true; }); const runScript = async ({ name: name2, path, runOnNuxtPrepare }) => { if (nuxt.options._prepare && !runOnNuxtPrepare) { logger.info(`Skipping prepare script \`${name2}\``); return; } logger.info(`Running prepare script \`${name2}\``); const result = await interopDefault( await importx.import(path, { parentURL: nuxt.options.rootDir, cache: false, loaderOptions: { // Nuxt's TypeScript config will only be generated along // with prepare scripts, so we disable config resolution tsx: { tsconfig: false } } }) ); const isOk = result.ok ?? true; if (!isOk) { logger.error(`Server prepare script \`${name2}\` returned an error`); errorCount++; if (!options.continueOnError) throw new TypeError("Server prepare script failed"); return; } successCount++; if (result.runtimeConfig) { nuxt.options.runtimeConfig = defu( nuxt.options.runtimeConfig, result.runtimeConfig ); } if (result.appConfig) nuxt.options.appConfig = defu(nuxt.options.appConfig, result.appConfig); if (result.state) { if (!isObject(result.state)) throw new TypeError("Server prepare script returned invalid state"); state = defu(state, result.state); } }; if (nuxt.options._prepare && !options.runOnNuxtPrepare) { logger.info("Skipping prepare scripts"); } else { if (options.parallel) { await Promise.all(resolvedScripts.map(runScript)); } else { for (const script of resolvedScripts) { await runScript(script); } } } nuxt.options.alias[`#${moduleName}`] = join(nuxt.options.buildDir, `module/${moduleName}`); nuxt.hooks.hook("nitro:config", (config) => { config.alias ||= {}; config.alias[`#${moduleName}`] = join(nuxt.options.buildDir, `module/${moduleName}`); }); addTemplate({ filename: `module/${moduleName}.mjs`, write: true, getContents() { const results = Object.entries(state); if (!results.length) { return ` // Generated by ${moduleName} export {} `.trimStart(); } return ` // Generated by ${moduleName} ${results.map(([key, value]) => ` export const ${key} = ${JSON.stringify(value, void 0, 2)} `.trim()).join("\n")} `.trimStart(); } }); addTemplate({ filename: `module/${moduleName}.d.ts`, write: true, getContents() { const results = Object.entries(state); if (!results.length) { return ` // Generated by ${moduleName} export {} `.trimStart(); } return ` // Generated by ${moduleName} ${results.map(([key, value]) => ` export declare const ${key}: ${JSON.stringify(value, void 0, 2)} export type ${pascalCase(key)} = typeof ${key} `.trim()).join("\n")} `.trimStart(); } }); if (errorCount > 0) logger.warn(`Server prepare scripts completed with ${errorCount} error${errorCount > 1 ? "s" : ""}`); else if (successCount > 0) logger.success("Server prepare scripts completed"); } }); export { module as default };