From 68e153c71a943c376a30ea7fafcddf1550676233 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Fri, 9 Aug 2024 12:31:04 +0100 Subject: [PATCH] fix(nuxt): handle plugin type extensions more correctly (#28480) --- packages/nuxt/src/core/templates.ts | 41 ++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/packages/nuxt/src/core/templates.ts b/packages/nuxt/src/core/templates.ts index c10d58ac88..1acd3cbbdf 100644 --- a/packages/nuxt/src/core/templates.ts +++ b/packages/nuxt/src/core/templates.ts @@ -1,6 +1,6 @@ import { existsSync } from 'node:fs' import { genArrayFromRaw, genDynamicImport, genExport, genImport, genObjectFromRawEntries, genSafeVariableName, genString } from 'knitwork' -import { isAbsolute, join, relative, resolve } from 'pathe' +import { join, relative, resolve } from 'pathe' import type { JSValue } from 'untyped' import { generateTypes, resolveSchema } from 'untyped' import escapeRE from 'escape-string-regexp' @@ -98,19 +98,36 @@ export const serverPluginTemplate: NuxtTemplate = { export const pluginsDeclaration: NuxtTemplate = { filename: 'types/plugins.d.ts', - getContents: async (ctx) => { - const EXTENSION_RE = new RegExp(`(?<=\\w)(${ctx.nuxt.options.extensions.map(e => escapeRE(e)).join('|')})$`, 'g') + getContents: async ({ nuxt, app }) => { + const EXTENSION_RE = new RegExp(`(?<=\\w)(${nuxt.options.extensions.map(e => escapeRE(e)).join('|')})$`, 'g') + + const typesDir = join(nuxt.options.buildDir, 'types') const tsImports: string[] = [] - for (const p of ctx.app.plugins) { - const sources = [p.src, p.src.replace(EXTENSION_RE, '.d.ts')] - if (!isAbsolute(p.src)) { - tsImports.push(p.src.replace(EXTENSION_RE, '')) - } else if (ctx.app.templates.some(t => t.write && t.dst && sources.includes(t.dst)) || sources.some(s => existsSync(s))) { - tsImports.push(relative(join(ctx.nuxt.options.buildDir, 'types'), p.src).replace(EXTENSION_RE, '')) - } + const pluginNames: string[] = [] + + function exists (path: string) { + return app.templates.some(t => t.write && path === t.dst) || existsSync(path) } - const pluginsName = (await annotatePlugins(ctx.nuxt, ctx.app.plugins)).filter(p => p.name).map(p => `'${p.name}'`) + for (const plugin of await annotatePlugins(nuxt, app.plugins)) { + if (plugin.name) { + pluginNames.push(`'${plugin.name}'`) + } + + const pluginPath = resolve(typesDir, plugin.src) + const relativePath = relative(typesDir, pluginPath) + + const correspondingDeclaration = pluginPath.replace(/\.(?[cm])?jsx?$/, '.d.$ts') + if (correspondingDeclaration !== pluginPath && exists(correspondingDeclaration)) { + tsImports.push(relativePath) + continue + } + + if (exists(pluginPath)) { + tsImports.push(relativePath.replace(EXTENSION_RE, '')) + continue + } + } return `// Generated by Nuxt' import type { Plugin } from '#app' @@ -126,7 +143,7 @@ declare module '#app' { interface NuxtApp extends NuxtAppInjections { } interface NuxtAppLiterals { - pluginName: ${pluginsName.join(' | ')} + pluginName: ${pluginNames.join(' | ')} } }