import { getCurrentInstance, reactive } from "vue"; import { createHooks } from "hookable"; import { getContext } from "unctx"; const nuxtAppCtx = getContext("nuxt-app"); export const NuxtPluginIndicator = "__nuxt_plugin"; export function createNuxtApp(options) { let hydratingCount = 0; const nuxtApp = { provide: void 0, globalName: "nuxt", payload: reactive({ data: {}, state: {}, _errors: {}, ...process.client ? window.__NUXT__ : { serverRendered: true } }), static: { data: {} }, isHydrating: process.client, deferHydration() { if (!nuxtApp.isHydrating) { return () => { }; } hydratingCount++; let called = false; return () => { if (called) { return; } called = true; hydratingCount--; if (hydratingCount === 0) { nuxtApp.isHydrating = false; return nuxtApp.callHook("app:suspense:resolve"); } }; }, _asyncDataPromises: {}, _asyncData: {}, ...options }; nuxtApp.hooks = createHooks(); nuxtApp.hook = nuxtApp.hooks.hook; nuxtApp.callHook = nuxtApp.hooks.callHook; nuxtApp.provide = (name, value) => { const $name = "$" + name; defineGetter(nuxtApp, $name, value); defineGetter(nuxtApp.vueApp.config.globalProperties, $name, value); }; defineGetter(nuxtApp.vueApp, "$nuxt", nuxtApp); defineGetter(nuxtApp.vueApp.config.globalProperties, "$nuxt", nuxtApp); if (process.server) { if (nuxtApp.ssrContext) { nuxtApp.ssrContext.nuxt = nuxtApp; } nuxtApp.ssrContext = nuxtApp.ssrContext || {}; if (nuxtApp.ssrContext.payload) { Object.assign(nuxtApp.payload, nuxtApp.ssrContext.payload); } nuxtApp.ssrContext.payload = nuxtApp.payload; nuxtApp.payload.config = { public: options.ssrContext.runtimeConfig.public, app: options.ssrContext.runtimeConfig.app }; } const runtimeConfig = process.server ? options.ssrContext.runtimeConfig : reactive(nuxtApp.payload.config); const compatibilityConfig = new Proxy(runtimeConfig, { get(target, prop) { if (prop === "public") { return target.public; } return target[prop] ?? target.public[prop]; }, set(target, prop, value) { if (process.server || prop === "public" || prop === "app") { return false; } target[prop] = value; target.public[prop] = value; return true; } }); nuxtApp.provide("config", compatibilityConfig); return nuxtApp; } export async function applyPlugin(nuxtApp, plugin) { if (typeof plugin !== "function") { return; } const { provide } = await callWithNuxt(nuxtApp, plugin, [nuxtApp]) || {}; if (provide && typeof provide === "object") { for (const key in provide) { nuxtApp.provide(key, provide[key]); } } } export async function applyPlugins(nuxtApp, plugins) { for (const plugin of plugins) { await applyPlugin(nuxtApp, plugin); } } export function normalizePlugins(_plugins) { const unwrappedPlugins = []; const legacyInjectPlugins = []; const invalidPlugins = []; const plugins = _plugins.map((plugin) => { if (typeof plugin !== "function") { invalidPlugins.push(plugin); return null; } if (plugin.length > 1) { legacyInjectPlugins.push(plugin); return (nuxtApp) => plugin(nuxtApp, nuxtApp.provide); } if (!isNuxtPlugin(plugin)) { unwrappedPlugins.push(plugin); } return plugin; }).filter(Boolean); if (process.dev && legacyInjectPlugins.length) { console.warn("[warn] [nuxt] You are using a plugin with legacy Nuxt 2 format (context, inject) which is likely to be broken. In the future they will be ignored:", legacyInjectPlugins.map((p) => p.name || p).join(",")); } if (process.dev && invalidPlugins.length) { console.warn("[warn] [nuxt] Some plugins are not exposing a function and skipped:", invalidPlugins); } if (process.dev && unwrappedPlugins.length) { console.warn("[warn] [nuxt] You are using a plugin that has not been wrapped in `defineNuxtPlugin`. It is advised to wrap your plugins as in the future this may enable enhancements:", unwrappedPlugins.map((p) => p.name || p).join(",")); } return plugins; } export function defineNuxtPlugin(plugin) { plugin[NuxtPluginIndicator] = true; return plugin; } export function isNuxtPlugin(plugin) { return typeof plugin === "function" && NuxtPluginIndicator in plugin; } export function callWithNuxt(nuxt, setup, args) { const fn = () => args ? setup(...args) : setup(); if (process.server) { return nuxtAppCtx.callAsync(nuxt, fn); } else { nuxtAppCtx.set(nuxt); return fn(); } } export function useNuxtApp() { const nuxtAppInstance = nuxtAppCtx.tryUse(); if (!nuxtAppInstance) { const vm = getCurrentInstance(); if (!vm) { throw new Error("nuxt instance unavailable"); } return vm.appContext.app.$nuxt; } return nuxtAppInstance; } export function useRuntimeConfig() { return useNuxtApp().$config; } function defineGetter(obj, key, val) { Object.defineProperty(obj, key, { get: () => val }); } export function defineAppConfig(config) { return config; }