fix(nuxt): mark non-augmented NuxtApp properties as unknown (#19643)

This commit is contained in:
Daniel Roe 2023-03-14 10:09:50 +00:00 committed by GitHub
parent e84ec61eeb
commit 0f6276dc6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 59 additions and 14 deletions

View File

@ -25,7 +25,8 @@
"jsdoc/require-param-type": "off",
"no-redeclare": "off",
"import/order": [
"error", {
"error",
{
"pathGroups": [
{
"pattern": "@nuxt/test-utils",
@ -73,6 +74,7 @@
},
"settings": {
"jsdoc": {
"ignoreInternal": true,
"tagNamePreference": {
"warning": "warning",
"note": "note"

View File

@ -56,7 +56,7 @@ export default defineComponent({
nuxtApp[pKey] = nuxtApp[pKey] || {}
if (!nuxtApp[pKey][hashId.value]) {
nuxtApp[pKey][hashId.value] = _fetchComponent().finally(() => {
delete nuxtApp[pKey][hashId.value]
delete nuxtApp[pKey]![hashId.value]
})
}
const res: NuxtIslandResponse = await nuxtApp[pKey][hashId.value]

View File

@ -7,7 +7,7 @@ interface LoadPayloadOptions {
hash?: string
}
export function loadPayload (url: string, opts: LoadPayloadOptions = {}) {
export function loadPayload (url: string, opts: LoadPayloadOptions = {}): Record<string, any> | Promise<Record<string, any>> | null {
if (process.server) { return null }
const payloadURL = _getPayloadURL(url, opts)
const nuxtApp = useNuxtApp()

View File

@ -53,10 +53,16 @@ interface AddRouteMiddleware {
export const addRouteMiddleware: AddRouteMiddleware = (name: string | RouteMiddleware, middleware?: RouteMiddleware, options: AddRouteMiddlewareOptions = {}) => {
const nuxtApp = useNuxtApp()
if (options.global || typeof name === 'function') {
nuxtApp._middleware.global.push(typeof name === 'function' ? name : middleware)
const global = options.global || typeof name !== 'string'
const mw = typeof name !== 'string' ? name : middleware
if (!mw) {
console.warn('[nuxt] No route middleware passed to `addRouteMiddleware`.', name)
return
}
if (global) {
nuxtApp._middleware.global.push(mw)
} else {
nuxtApp._middleware.named[name] = middleware
nuxtApp._middleware.named[name] = mw
}
}

View File

@ -1,15 +1,17 @@
/* eslint-disable no-use-before-define */
import { getCurrentInstance, reactive } from 'vue'
import type { App, onErrorCaptured, VNode, Ref } from 'vue'
import type { RouteLocationNormalizedLoaded, Router } from 'vue-router'
import type { Hookable } from 'hookable'
import { createHooks } from 'hookable'
import { getContext } from 'unctx'
import type { SSRContext } from 'vue-bundle-renderer/runtime'
import type { H3Event } from 'h3'
import type { RuntimeConfig, AppConfigInput } from 'nuxt/schema'
import type { RuntimeConfig, AppConfigInput, AppConfig } from 'nuxt/schema'
// eslint-disable-next-line import/no-restricted-paths
import type { NuxtIslandContext } from '../core/runtime/nitro/renderer'
import type { RouteMiddleware } from '../../app'
const nuxtAppCtx = /* #__PURE__ */ getContext<NuxtApp>('nuxt-app')
@ -67,15 +69,40 @@ interface _NuxtApp {
hook: _NuxtApp['hooks']['hook']
callHook: _NuxtApp['hooks']['callHook']
[key: string]: any
[key: string]: unknown
/** @internal */
_asyncDataPromises: Record<string, Promise<any> | undefined>
/** @internal */
_asyncData: Record<string, {
data: Ref<any>
pending: Ref<boolean>
error: Ref<any>
} | undefined>
/** @internal */
_middleware: {
global: RouteMiddleware[]
named: Record<string, RouteMiddleware>
}
/** @internal */
_observer?: { observe: (element: Element, callback: () => void) => () => void }
/** @internal */
_payloadCache?: Record<string, Promise<Record<string, any>> | Record<string, any>>
/** @internal */
_appConfig: AppConfig
/** @internal */
_route: RouteLocationNormalizedLoaded
/** @internal */
_islandPromises?: Record<string, Promise<any>>
// Nuxt injections
$config: RuntimeConfig
$router: Router
isHydrating?: boolean
deferHydration: () => () => void | Promise<void>

View File

@ -11,9 +11,9 @@ export default defineNuxtPlugin((nuxtApp) => {
}
// Load payload into cache
nuxtApp.hooks.hook('link:prefetch', (url) => {
nuxtApp.hooks.hook('link:prefetch', async (url) => {
if (!parseURL(url).protocol) {
return loadPayload(url)
await loadPayload(url)
}
})

View File

@ -30,6 +30,8 @@ interface Route {
redirectedFrom: Route | undefined
/** Merged `meta` properties from all of the matched route records. */
meta: Record<string, any>
/** compatibility type for vue-router */
matched: never[]
}
function getRouteFromPath (fullPath: string | Partial<Route>) {

View File

@ -67,7 +67,7 @@ const NuxtServerComponent = defineComponent({
nuxtApp[pKey] = nuxtApp[pKey] || {}
if (!nuxtApp[pKey][hashId.value]) {
nuxtApp[pKey][hashId.value] = _fetchComponent().finally(() => {
delete nuxtApp[pKey][hashId.value]
delete nuxtApp[pKey]![hashId.value]
})
}
const res: NuxtIslandResponse = await nuxtApp[pKey][hashId.value]

View File

@ -1,7 +1,6 @@
import { computed, isReadonly, reactive, shallowRef } from 'vue'
import type { Ref } from 'vue'
import type {
NavigationGuard,
RouteLocation
} from 'vue-router'
import {
@ -13,7 +12,7 @@ import {
import { createError } from 'h3'
import { withoutBase, isEqual } from 'ufo'
import type { PageMeta } from '#app'
import type { PageMeta, RouteMiddleware } from '#app'
import { callWithNuxt, defineNuxtPlugin, useRuntimeConfig } from '#app/nuxt'
import { showError, clearError, useError } from '#app/composables/error'
import { useRequestEvent } from '#app/composables/ssr'
@ -125,7 +124,7 @@ export default defineNuxtPlugin(async (nuxtApp) => {
}
nuxtApp._processingMiddleware = true
type MiddlewareDef = string | NavigationGuard
type MiddlewareDef = string | RouteMiddleware
const middlewareEntries = new Set<MiddlewareDef>([...globalMiddleware, ...nuxtApp._middleware.global])
for (const component of to.matched) {
const componentMiddleware = component.meta.middleware as MiddlewareDef | MiddlewareDef[]

View File

@ -127,6 +127,15 @@ describe('modules', () => {
})
})
describe('nuxtApp', () => {
it('types injections provided by plugins', () => {
expectTypeOf(useNuxtApp().$asyncPlugin).toEqualTypeOf<() => string>()
})
it('marks unknown injections as unknown', () => {
expectTypeOf(useNuxtApp().doesNotExist).toEqualTypeOf<unknown>()
})
})
describe('runtimeConfig', () => {
it('generated runtimeConfig types', () => {
const runtimeConfig = useRuntimeConfig()