mirror of
https://github.com/nuxt/nuxt.git
synced 2025-03-21 16:55:57 +00:00
feat(kit,nuxt): augment nitro types with addTypeTemplate
(#31079)
This commit is contained in:
parent
d153ea9d23
commit
156ab7c93c
@ -48,8 +48,12 @@ export function addServerTemplate (template: NuxtServerTemplate) {
|
|||||||
/**
|
/**
|
||||||
* Renders given types during build to disk in the project `buildDir`
|
* Renders given types during build to disk in the project `buildDir`
|
||||||
* and register them as types.
|
* and register them as types.
|
||||||
|
*
|
||||||
|
* You can pass a second context object to specify in which context the type should be added.
|
||||||
|
*
|
||||||
|
* If no context object is passed, then it will only be added to the nuxt context.
|
||||||
*/
|
*/
|
||||||
export function addTypeTemplate<T> (_template: NuxtTypeTemplate<T>) {
|
export function addTypeTemplate<T> (_template: NuxtTypeTemplate<T>, context?: { nitro?: boolean, nuxt?: boolean }) {
|
||||||
const nuxt = useNuxt()
|
const nuxt = useNuxt()
|
||||||
|
|
||||||
const template = addTemplate(_template)
|
const template = addTemplate(_template)
|
||||||
@ -59,9 +63,16 @@ export function addTypeTemplate<T> (_template: NuxtTypeTemplate<T>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add template to types reference
|
// Add template to types reference
|
||||||
|
if (!context || context.nuxt) {
|
||||||
nuxt.hook('prepare:types', ({ references }) => {
|
nuxt.hook('prepare:types', ({ references }) => {
|
||||||
references.push({ path: template.dst })
|
references.push({ path: template.dst })
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
if (context?.nitro) {
|
||||||
|
nuxt.hook('nitro:prepare:types', ({ references }) => {
|
||||||
|
references.push({ path: template.dst })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return template
|
return template
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { existsSync } from 'node:fs'
|
import { existsSync } from 'node:fs'
|
||||||
import { genArrayFromRaw, genDynamicImport, genExport, genImport, genObjectFromRawEntries, genSafeVariableName, genString } from 'knitwork'
|
import { genArrayFromRaw, genDynamicImport, genExport, genImport, genObjectFromRawEntries, genSafeVariableName, genString } from 'knitwork'
|
||||||
import { join, relative, resolve } from 'pathe'
|
import { isAbsolute, join, relative, resolve } from 'pathe'
|
||||||
import type { JSValue } from 'untyped'
|
import type { JSValue } from 'untyped'
|
||||||
import { generateTypes, resolveSchema } from 'untyped'
|
import { generateTypes, resolveSchema } from 'untyped'
|
||||||
import escapeRE from 'escape-string-regexp'
|
import escapeRE from 'escape-string-regexp'
|
||||||
import { hash } from 'ohash'
|
import { hash } from 'ohash'
|
||||||
import { camelCase } from 'scule'
|
import { camelCase } from 'scule'
|
||||||
import { filename } from 'pathe/utils'
|
import { filename } from 'pathe/utils'
|
||||||
import type { NuxtOptions, NuxtTemplate, NuxtTypeTemplate } from 'nuxt/schema'
|
import type { NuxtOptions, NuxtTemplate, NuxtTypeTemplate, TSReference } from 'nuxt/schema'
|
||||||
import type { Nitro } from 'nitropack'
|
import type { Nitro } from 'nitropack'
|
||||||
|
|
||||||
import { annotatePlugins, checkForCircularDependencies } from './app'
|
import { annotatePlugins, checkForCircularDependencies } from './app'
|
||||||
@ -331,10 +331,38 @@ export const middlewareTemplate: NuxtTemplate = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderAttr (key: string, value?: string) {
|
||||||
|
return value ? `${key}="${value}"` : ''
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderAttrs (obj: Record<string, string>) {
|
||||||
|
const attrs: string[] = []
|
||||||
|
for (const key in obj) {
|
||||||
|
attrs.push(renderAttr(key, obj[key]))
|
||||||
|
}
|
||||||
|
return attrs.join(' ')
|
||||||
|
}
|
||||||
|
|
||||||
export const nitroSchemaTemplate: NuxtTemplate = {
|
export const nitroSchemaTemplate: NuxtTemplate = {
|
||||||
filename: 'types/nitro-nuxt.d.ts',
|
filename: 'types/nitro-nuxt.d.ts',
|
||||||
getContents () {
|
async getContents ({ nuxt }) {
|
||||||
|
const references = [] as TSReference[]
|
||||||
|
const declarations = [] as string[]
|
||||||
|
await nuxt.callHook('nitro:prepare:types', { references, declarations })
|
||||||
|
|
||||||
|
const sourceDir = join(nuxt.options.buildDir, 'types')
|
||||||
|
const lines = [
|
||||||
|
...references.map((ref) => {
|
||||||
|
if ('path' in ref && isAbsolute(ref.path)) {
|
||||||
|
ref.path = relative(sourceDir, ref.path)
|
||||||
|
}
|
||||||
|
return `/// <reference ${renderAttrs(ref)} />`
|
||||||
|
}),
|
||||||
|
...declarations,
|
||||||
|
]
|
||||||
|
|
||||||
return /* typescript */`
|
return /* typescript */`
|
||||||
|
${lines.join('\n')}
|
||||||
/// <reference path="./schema.d.ts" />
|
/// <reference path="./schema.d.ts" />
|
||||||
|
|
||||||
import type { RuntimeConfig } from 'nuxt/schema'
|
import type { RuntimeConfig } from 'nuxt/schema'
|
||||||
|
@ -158,7 +158,7 @@ export default defineNuxtModule({
|
|||||||
'}',
|
'}',
|
||||||
'export {}',
|
'export {}',
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
})
|
}, { nuxt: true, nitro: true })
|
||||||
addComponent({
|
addComponent({
|
||||||
name: 'NuxtPage',
|
name: 'NuxtPage',
|
||||||
priority: 10, // built-in that we do not expect the user to override
|
priority: 10, // built-in that we do not expect the user to override
|
||||||
@ -575,6 +575,16 @@ export default defineNuxtModule({
|
|||||||
' middleware?: MiddlewareKey | NavigationGuard | Array<MiddlewareKey | NavigationGuard>',
|
' middleware?: MiddlewareKey | NavigationGuard | Array<MiddlewareKey | NavigationGuard>',
|
||||||
' }',
|
' }',
|
||||||
'}',
|
'}',
|
||||||
|
].join('\n')
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
addTypeTemplate({
|
||||||
|
filename: 'types/nitro-middleware.d.ts',
|
||||||
|
getContents: ({ app }) => {
|
||||||
|
const namedMiddleware = app.middleware.filter(mw => !mw.global)
|
||||||
|
return [
|
||||||
|
`export type MiddlewareKey = ${namedMiddleware.map(mw => genString(mw.name)).join(' | ') || 'never'}`,
|
||||||
'declare module \'nitropack\' {',
|
'declare module \'nitropack\' {',
|
||||||
' interface NitroRouteConfig {',
|
' interface NitroRouteConfig {',
|
||||||
' appMiddleware?: MiddlewareKey | MiddlewareKey[] | Record<MiddlewareKey, boolean>',
|
' appMiddleware?: MiddlewareKey | MiddlewareKey[] | Record<MiddlewareKey, boolean>',
|
||||||
@ -582,7 +592,7 @@ export default defineNuxtModule({
|
|||||||
'}',
|
'}',
|
||||||
].join('\n')
|
].join('\n')
|
||||||
},
|
},
|
||||||
})
|
}, { nuxt: true, nitro: true })
|
||||||
|
|
||||||
addTypeTemplate({
|
addTypeTemplate({
|
||||||
filename: 'types/layouts.d.ts',
|
filename: 'types/layouts.d.ts',
|
||||||
|
@ -257,6 +257,12 @@ export interface NuxtHooks {
|
|||||||
'components:extend': (components: Component[]) => HookResult
|
'components:extend': (components: Component[]) => HookResult
|
||||||
|
|
||||||
// Nitropack
|
// Nitropack
|
||||||
|
/**
|
||||||
|
* Called before Nitro writes `.nuxt/tsconfig.server.json`, allowing addition of custom references and declarations.
|
||||||
|
* @param options Objects containing `references`, `declarations`
|
||||||
|
* @returns Promise
|
||||||
|
*/
|
||||||
|
'nitro:prepare:types': (options: { references: TSReference[], declarations: string[] }) => HookResult
|
||||||
/**
|
/**
|
||||||
* Called before initializing Nitro, allowing customization of Nitro's configuration.
|
* Called before initializing Nitro, allowing customization of Nitro's configuration.
|
||||||
* @param nitroConfig The nitro config to be extended
|
* @param nitroConfig The nitro config to be extended
|
||||||
|
2
test/fixtures/basic-types/nuxt.config.ts
vendored
2
test/fixtures/basic-types/nuxt.config.ts
vendored
@ -10,7 +10,7 @@ export default defineNuxtConfig({
|
|||||||
addTypeTemplate({
|
addTypeTemplate({
|
||||||
filename: 'test.d.ts',
|
filename: 'test.d.ts',
|
||||||
getContents: () => 'declare type Fromage = "cheese"',
|
getContents: () => 'declare type Fromage = "cheese"',
|
||||||
})
|
}, { nuxt: true, nitro: true })
|
||||||
function _test () {
|
function _test () {
|
||||||
installModule('~/modules/example', {
|
installModule('~/modules/example', {
|
||||||
typeTest (val) {
|
typeTest (val) {
|
||||||
|
4
test/fixtures/basic-types/server/type-context.ts
vendored
Normal file
4
test/fixtures/basic-types/server/type-context.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
// @ts-expect-error Fromage is 'cheese'
|
||||||
|
const _fake: Fromage = 'babybel'
|
||||||
|
|
||||||
|
const _fromage: Fromage = 'cheese'
|
Loading…
Reference in New Issue
Block a user