UNPKG

@owdproject/core

Version:

Nuxt Desktop module for browser desktop experiences (windows, shell, apps)

255 lines (250 loc) 8.86 kB
import { installModule, defineNuxtModule, createResolver, resolvePath, addComponentsDir, addPlugin, addImportsDir } from '@nuxt/kit'; import { defu } from 'defu'; import { existsSync } from 'node:fs'; import { join } from 'node:path'; function assertValidDesktopUserConfig(config, configFile = "desktop.config.ts") { if (!config || typeof config !== "object" || Array.isArray(config)) { throw new Error( `[@owdproject/core] ${configFile} must default-export a non-array object from defineDesktopConfig({ ... }).` ); } const c = config; if (c.theme != null && typeof c.theme !== "string") { throw new Error( `[@owdproject/core] ${configFile}: \`theme\` must be a string (npm package name of the theme module).` ); } if (c.apps !== void 0) { if (!Array.isArray(c.apps) || !c.apps.every((item) => typeof item === "string")) { throw new Error( `[@owdproject/core] ${configFile}: \`apps\` must be an array of strings (Nuxt module package names).` ); } } if (c.modules !== void 0) { if (!Array.isArray(c.modules) || !c.modules.every((item) => typeof item === "string")) { throw new Error( `[@owdproject/core] ${configFile}: \`modules\` must be an array of strings (Nuxt module package names).` ); } } } const DESKTOP_CONFIG_FILENAME = "desktop.config.ts"; const LEGACY_DESKTOP_CONFIG_FILENAME = "owd.config.ts"; const LEGACY_CONFIG_DEPRECATION = "[@owdproject/core] owd.config.ts is deprecated and kept only for backward compatibility; rename to desktop.config.ts (required from @owdproject/core 3.2)."; function resolveDesktopConfigPath(rootDir) { const desktopPath = join(rootDir, DESKTOP_CONFIG_FILENAME); const legacyPath = join(rootDir, LEGACY_DESKTOP_CONFIG_FILENAME); const hasDesktop = existsSync(desktopPath); const hasLegacy = existsSync(legacyPath); if (hasDesktop && hasLegacy) { console.warn( "[@owdproject/core] Both desktop.config.ts and owd.config.ts exist; using desktop.config.ts. Remove owd.config.ts." ); return { path: desktopPath, file: DESKTOP_CONFIG_FILENAME, legacy: false }; } if (hasDesktop) { return { path: desktopPath, file: DESKTOP_CONFIG_FILENAME, legacy: false }; } if (hasLegacy) { return { path: legacyPath, file: LEGACY_DESKTOP_CONFIG_FILENAME, legacy: true }; } return null; } function warnLegacyDesktopConfig(resolved) { if (resolved?.legacy) { console.warn(LEGACY_CONFIG_DEPRECATION); } } const NUXT_OPTION_KEYS = /* @__PURE__ */ new Set([ "ssr", "devtools", "vite", "nitro", "runtimeConfig", "app", "appConfig", "css", "plugins", "hooks", "extends", "compatibilityDate", "experimental", "future", "i18n", "tailwindcss", "primevue" ]); function warnDesktopConfigKeys(config, configFile = "desktop.config.ts") { for (const key of Object.keys(config)) { if (NUXT_OPTION_KEYS.has(key)) { console.warn( `[@owdproject/core] ${configFile}: key "${key}" looks like a Nuxt option and is ignored for _nuxt.options. Move it to nuxt.config.ts; shell values belong under defineDesktopConfig({ systemBar, workspaces, ... }).` ); } } } function readConfigKey(mod) { const key = mod?.meta?.configKey ?? mod?.default?.meta?.configKey; return typeof key === "string" && key.length > 0 ? key : void 0; } async function loadModuleDescriptor(modulePath) { try { const imported = await import(modulePath); return imported.default ?? imported; } catch (e) { console.warn(`[@owdproject/core] Failed to load module descriptor for "${modulePath}":`, e.message || e); return void 0; } } async function installDesktopPackage(nuxt, modulePath, desktop) { const descriptor = await loadModuleDescriptor(modulePath); const configKey = readConfigKey(descriptor); if (configKey && desktop) { const slice = desktop[configKey]; const inline = slice && typeof slice === "object" && !Array.isArray(slice) ? slice : {}; await installModule(modulePath, inline); return; } await installModule(modulePath); } const version = "3.4.0"; const pkg = { version: version}; const module$1 = defineNuxtModule({ meta: { name: "desktop", configKey: "desktop" }, defaults: { theme: "@owdproject/theme-nova", apps: [], modules: [] }, moduleDependencies: { "@pinia/nuxt": {}, "@nuxt/fonts": {}, "@nuxt/icon": { defaults: { clientBundle: { scan: true, sizeLimitKb: 256 } } }, "@vueuse/nuxt": {}, "@nuxtjs/i18n": {} }, async setup(_options, _nuxt) { const { resolve } = createResolver(import.meta.url); let resolvedNanoid = null; try { resolvedNanoid = await resolvePath("nanoid", { url: import.meta.url }); } catch (e) { } _nuxt.options.experimental = { ..._nuxt.options.experimental, viteEnvironmentApi: _nuxt.options.experimental?.viteEnvironmentApi ?? true }; _nuxt.options.runtimeConfig.public.desktop = {}; let clientConfig; const resolvedConfig = resolveDesktopConfigPath(_nuxt.options.rootDir); if (!resolvedConfig) { const hint = "Create desktop.config.ts next to your Nuxt root (e.g. desktop/desktop.config.ts), export default defineDesktopConfig({ theme, apps, modules })."; throw new Error(`[@owdproject/core] Cannot find desktop.config.ts in ${_nuxt.options.rootDir}. ${hint}`); } warnLegacyDesktopConfig(resolvedConfig); _nuxt.options.watch ??= []; _nuxt.options.watch.push(resolvedConfig.path); try { clientConfig = (await import(resolvedConfig.path)).default; } catch (e) { const hint = "Export default defineDesktopConfig({ theme, apps, modules }) from desktop.config.ts."; throw new Error( `[@owdproject/core] Cannot load ${resolvedConfig.file}. ${hint}`, { cause: e } ); } assertValidDesktopUserConfig(clientConfig, resolvedConfig.file); if (!clientConfig.theme) { clientConfig.theme = "@owdproject/theme-nova"; } const configRecord = clientConfig; warnDesktopConfigKeys(configRecord, resolvedConfig.file); const desktop = defu(configRecord, { coreVersion: pkg.version }); _nuxt.options.runtimeConfig.public.desktop = desktop; { if (desktop.theme) { try { await installDesktopPackage(_nuxt, desktop.theme, desktop); } catch (e) { const msg = e instanceof Error ? e.message : String(e); console.warn(`[@owdproject/core] Warning: Could not load theme "${desktop.theme}". Details: ${msg}`); } } if (Array.isArray(desktop.modules)) { for (const modulePath of desktop.modules) { try { await installDesktopPackage(_nuxt, modulePath, desktop); } catch (e) { const msg = e instanceof Error ? e.message : String(e); console.warn(`[@owdproject/core] Warning: Could not load module "${modulePath}". Details: ${msg}`); } } } if (Array.isArray(desktop.apps)) { for (const appPath of desktop.apps) { try { await installDesktopPackage(_nuxt, appPath, desktop); } catch (e) { const msg = e instanceof Error ? e.message : String(e); console.warn(`[@owdproject/core] Warning: Could not load app "${appPath}". Details: ${msg}`); } } } } _nuxt.options.appConfig.desktop = _nuxt.options.runtimeConfig.public.desktop; { _nuxt.hook("vite:extendConfig", (viteConfig) => { viteConfig.css = viteConfig.css || {}; viteConfig.css.preprocessorOptions = viteConfig.css.preprocessorOptions || {}; viteConfig.css.preprocessorOptions.scss = { api: "modern-compiler" }; viteConfig.optimizeDeps = viteConfig.optimizeDeps || {}; viteConfig.optimizeDeps.include = viteConfig.optimizeDeps.include || []; if (resolvedNanoid && !viteConfig.optimizeDeps.include.includes(resolvedNanoid)) { viteConfig.optimizeDeps.include.push(resolvedNanoid); } }); } { _nuxt.options.css.push("sanitize.css"); } { addComponentsDir({ path: resolve("./runtime/components"), prefix: "Desktop", pathPrefix: false, global: true }); } { addPlugin(resolve("./runtime/plugins/resize.client.ts")); addPlugin( resolve("./runtime/plugins/01.desktop-shell-init.client.ts") ); addPlugin( resolve("./runtime/plugins/02.desktop-register-desktop-apps.client.ts") ); addImportsDir(resolve("./runtime/composables")); addImportsDir(resolve("./runtime/stores")); addImportsDir(resolve("./runtime/utils")); } } }); export { module$1 as default };