221 lines
7.2 KiB
JavaScript
221 lines
7.2 KiB
JavaScript
import { useNuxt, createResolver, addTemplate, defineNuxtModule, useLogger, addImportsDir, addComponent, addServerImportsDir, addPlugin, hasNuxtModule, addServerHandler, addPrerenderRoutes, addServerPlugin } from '@nuxt/kit';
|
|
import { initSiteConfig, updateSiteConfig, getSiteConfigStack } from 'nuxt-site-config-kit';
|
|
import { readPackageJSON } from 'pkg-types';
|
|
import { validateSiteConfigStack } from 'site-config-stack';
|
|
import { existsSync } from 'node:fs';
|
|
import { relative } from 'pathe';
|
|
|
|
const DEVTOOLS_UI_ROUTE = "/__nuxt-site-config";
|
|
const DEVTOOLS_UI_LOCAL_PORT = 3030;
|
|
function setupDevToolsUI(resolve, nuxt = useNuxt()) {
|
|
const clientPath = resolve("./client");
|
|
const isProductionBuild = existsSync(clientPath);
|
|
if (isProductionBuild) {
|
|
nuxt.hook("vite:serverCreated", async (server) => {
|
|
const sirv = await import('sirv').then((r) => r.default || r);
|
|
server.middlewares.use(
|
|
DEVTOOLS_UI_ROUTE,
|
|
sirv(clientPath, { dev: true, single: true })
|
|
);
|
|
});
|
|
} else {
|
|
nuxt.hook("vite:extendConfig", (config) => {
|
|
config.server = config.server || {};
|
|
config.server.proxy = config.server.proxy || {};
|
|
config.server.proxy[DEVTOOLS_UI_ROUTE] = {
|
|
target: `http://localhost:${DEVTOOLS_UI_LOCAL_PORT}${DEVTOOLS_UI_ROUTE}`,
|
|
changeOrigin: true,
|
|
followRedirects: true,
|
|
rewrite: (path) => path.replace(DEVTOOLS_UI_ROUTE, "")
|
|
};
|
|
});
|
|
}
|
|
nuxt.hook("devtools:customTabs", (tabs) => {
|
|
tabs.push({
|
|
// unique identifier
|
|
name: "nuxt-site-config",
|
|
// title to display in the tab
|
|
title: "Site Config",
|
|
// any icon from Iconify, or a URL to an image
|
|
icon: "carbon:settings-check",
|
|
// iframe view
|
|
view: {
|
|
type: "iframe",
|
|
src: DEVTOOLS_UI_ROUTE
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function extendTypes(module, template) {
|
|
const nuxt = useNuxt();
|
|
const { resolve } = createResolver(import.meta.url);
|
|
addTemplate({
|
|
filename: `module/${module}.d.ts`,
|
|
getContents: async () => {
|
|
const typesPath = relative(resolve(nuxt.options.rootDir, nuxt.options.buildDir, "module"), resolve("runtime/types"));
|
|
const s = await template({ typesPath });
|
|
return `// Generated by ${module}
|
|
${s}
|
|
export {}
|
|
`;
|
|
}
|
|
});
|
|
nuxt.hooks.hook("prepare:types", ({ references }) => {
|
|
references.push({ path: resolve(nuxt.options.buildDir, `module/${module}.d.ts`) });
|
|
});
|
|
nuxt.hooks.hook("nitro:config", (config) => {
|
|
config.typescript = config.typescript || {};
|
|
config.typescript.tsConfig = config.typescript.tsConfig || {};
|
|
config.typescript.tsConfig.include = config.typescript.tsConfig.include || [];
|
|
config.typescript.tsConfig.include.push(`./module/${module}.d.ts`);
|
|
});
|
|
}
|
|
|
|
const module = defineNuxtModule({
|
|
meta: {
|
|
name: "nuxt-site-config",
|
|
compatibility: {
|
|
nuxt: ">=3.9.0",
|
|
bridge: false
|
|
},
|
|
configKey: "site"
|
|
},
|
|
defaults(nuxt) {
|
|
return {
|
|
enabled: true,
|
|
debug: nuxt.options.debug || false
|
|
};
|
|
},
|
|
async setup(config, nuxt) {
|
|
const { resolve } = createResolver(import.meta.url);
|
|
const { name, version } = await readPackageJSON(resolve("../package.json"));
|
|
const logger = useLogger(name);
|
|
logger.level = config.debug ? 4 : 3;
|
|
if (config.enabled === false) {
|
|
logger.debug("The module is disabled, skipping setup.");
|
|
return;
|
|
}
|
|
await initSiteConfig();
|
|
const siteConfigInput = { ...config };
|
|
delete siteConfigInput.debug;
|
|
delete siteConfigInput.enabled;
|
|
updateSiteConfig({
|
|
// we should allow environment variables to override the site config
|
|
_priority: -3,
|
|
_context: "nuxt-site-config:config",
|
|
...siteConfigInput
|
|
});
|
|
nuxt.hook("modules:done", async () => {
|
|
await nuxt.callHook("site-config:resolve");
|
|
const errors = validateSiteConfigStack(getSiteConfigStack());
|
|
if (errors.length > 0) {
|
|
logger.warn("[Nuxt Site Config] Invalid config provided, please correct:");
|
|
for (const error of errors)
|
|
logger.log(` - ${error}`);
|
|
logger.log("");
|
|
}
|
|
nuxt.options.runtimeConfig["nuxt-site-config"] = {
|
|
stack: getSiteConfigStack().stack,
|
|
version,
|
|
debug: config.debug
|
|
};
|
|
});
|
|
extendTypes("nuxt-site-config", async ({ typesPath }) => {
|
|
return `
|
|
declare module 'nitropack' {
|
|
interface NitroRouteRules {
|
|
site?: import('${typesPath}').SiteConfigInput
|
|
}
|
|
interface NitroRouteConfig {
|
|
site?: import('${typesPath}').SiteConfig
|
|
}
|
|
interface NitroRuntimeHooks {
|
|
'site-config:init': (ctx: import('${typesPath}').HookSiteConfigInitContext) => void | Promise<void>
|
|
}
|
|
}
|
|
|
|
declare module 'h3' {
|
|
interface H3EventContext {
|
|
siteConfig: import('${typesPath}').SiteConfigStack
|
|
siteConfigNitroOrigin: string
|
|
}
|
|
}
|
|
|
|
declare module '@nuxt/schema' {
|
|
interface AppConfigInput {
|
|
/** Theme configuration */
|
|
site?: import('${typesPath}').SiteConfigInput
|
|
}
|
|
interface Nuxt {
|
|
_siteConfig?: import('${typesPath}').SiteConfigStack
|
|
}
|
|
}
|
|
declare module 'nuxt/app' {
|
|
interface NuxtApp {
|
|
$nuxtSiteConfig: import('${typesPath}').SiteConfigResolved
|
|
}
|
|
}
|
|
declare module '#app' {
|
|
interface NuxtApp {
|
|
$nuxtSiteConfig: import('${typesPath}').SiteConfigResolved
|
|
}
|
|
}
|
|
declare global {
|
|
interface Window {
|
|
__NUXT_SITE_CONFIG__: import('${typesPath}').SiteConfigResolved
|
|
}
|
|
}
|
|
`;
|
|
});
|
|
addImportsDir(resolve("./runtime/nuxt/composables"));
|
|
await addComponent({
|
|
filePath: resolve("./runtime/nuxt/component/SiteLink.vue"),
|
|
name: `${config.componentOptions?.prefix || ""}SiteLink`,
|
|
global: config.componentOptions?.global
|
|
});
|
|
if (process.env.playground) {
|
|
nuxt.options.alias["site-config-stack/urls"] = resolve("../../site-config/src/urls");
|
|
nuxt.options.alias["site-config-stack"] = resolve("../../site-config/src/index");
|
|
}
|
|
addServerImportsDir(resolve("./runtime/nitro/composables"));
|
|
nuxt.options.nitro.alias = nuxt.options.nitro.alias || {};
|
|
nuxt.options.nitro.alias["#site-config"] = resolve("./runtime");
|
|
nuxt.options.nitro.alias["#internal/nuxt-site-config"] = resolve("./runtime/nitro/composable-barrel-deprecated");
|
|
nuxt.options.build.transpile.push("site-config-stack");
|
|
addPlugin({
|
|
src: resolve("./runtime/nuxt/plugins/0.siteConfig")
|
|
});
|
|
if (hasNuxtModule("@nuxtjs/i18n")) {
|
|
addPlugin({
|
|
mode: "server",
|
|
src: resolve("./runtime/nuxt/plugins/i18n.server")
|
|
});
|
|
updateSiteConfig({
|
|
_context: "@nuxtjs/i18n",
|
|
// @ts-expect-error untyped
|
|
url: nuxt.options.i18n?.baseUrl,
|
|
// @ts-expect-error untyped
|
|
defaultLocale: nuxt.options.i18n?.defaultLocale
|
|
});
|
|
}
|
|
addServerHandler({
|
|
middleware: true,
|
|
handler: resolve("./runtime/nitro/middleware/init")
|
|
});
|
|
if (config.debug || nuxt.options.dev) {
|
|
addServerHandler({
|
|
route: "/__site-config__/debug.json",
|
|
handler: resolve("./runtime/nitro/routes/__site-config__/debug")
|
|
});
|
|
if (nuxt.options._generate)
|
|
addPrerenderRoutes("/__site-config__/debug.json");
|
|
}
|
|
if (nuxt.options.dev)
|
|
setupDevToolsUI(resolve);
|
|
addServerPlugin(resolve("./runtime/nitro/plugins/injectState"));
|
|
}
|
|
});
|
|
|
|
export { module as default };
|