nuxt-prepare
Version:
Build actions for Nuxt
206 lines (198 loc) • 6.44 kB
JavaScript
;
const kit = require('@nuxt/kit');
const defu = require('defu');
const importx = require('importx');
const mlly = require('mlly');
const pathe = require('pathe');
const scule = require('scule');
function _interopNamespaceCompat(e) {
if (e && typeof e === 'object' && 'default' in e) return e;
const n = Object.create(null);
if (e) {
for (const k in e) {
n[k] = e[k];
}
}
n.default = e;
return n;
}
const importx__namespace = /*#__PURE__*/_interopNamespaceCompat(importx);
const name = "nuxt-prepare";
const version = "3.1.0";
function toArray(value) {
return Array.isArray(value) ? value : [value];
}
function isObject(value) {
return Object.prototype.toString.call(value) === "[object Object]";
}
function stripExtension(name, extensions) {
for (const ext of extensions) {
if (name.endsWith(ext))
return name.slice(0, -ext.length);
}
return name;
}
const SCRIPT_EXTENSIONS = [".js", ".mjs", ".ts"];
const module$1 = kit.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 = kit.useLogger(moduleName);
let successCount = 0;
let errorCount = 0;
let state = {};
const layerScripts = [];
for (const [index, layer] of nuxt.options._layers.entries()) {
const isAppLayer = index === 0;
const layerPrepareScripts = layer.config.prepare ? layer.config.prepare.scripts : void 0;
const scripts = layerPrepareScripts !== void 0 ? toArray(layerPrepareScripts) : isAppLayer ? ["server.prepare"] : [];
for (const entry of scripts) {
const scriptName = stripExtension(
typeof entry === "string" ? entry : entry.file,
SCRIPT_EXTENSIONS
);
layerScripts.push({
root: layer.config.rootDir,
name: scriptName,
runOnNuxtPrepare: typeof entry === "string" ? true : entry.runOnNuxtPrepare ?? true
});
}
}
const resolvedEntries = await Promise.all(layerScripts.map(async (script) => {
const path = await kit.findPath(script.name, { extensions: SCRIPT_EXTENSIONS, cwd: script.root }, "file");
if (!path) {
if (script.name === "server.prepare") {
return;
}
logger.error(
`Server prepare script \`${script.name}{${SCRIPT_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");
}
return {
name: script.name,
path,
runOnNuxtPrepare: script.runOnNuxtPrepare
};
}));
const scriptsByPath = /* @__PURE__ */ new Map();
for (const entry of resolvedEntries) {
if (entry && !scriptsByPath.has(entry.path))
scriptsByPath.set(entry.path, entry);
}
const resolvedScripts = [...scriptsByPath.values()];
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 mlly.interopDefault(
await importx__namespace.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.defu(
nuxt.options.runtimeConfig,
result.runtimeConfig
);
}
if (result.appConfig)
nuxt.options.appConfig = defu.defu(nuxt.options.appConfig, result.appConfig);
if (result.state) {
if (!isObject(result.state))
throw new TypeError("Server prepare script returned invalid state");
state = defu.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}`] = pathe.join(nuxt.options.buildDir, `module/${moduleName}`);
nuxt.hooks.hook("nitro:config", (config) => {
config.alias ||= {};
config.alias[`#${moduleName}`] = pathe.join(nuxt.options.buildDir, `module/${moduleName}`);
});
kit.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();
}
});
kit.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 ${scule.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");
}
});
module.exports = module$1;