mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 08:33:53 +00:00
fix(nuxt,schema): prefer unknown rather than any for signatures (#21700)
This commit is contained in:
parent
f380be910e
commit
dd5dff37d5
@ -32,7 +32,7 @@ interface PageMeta {
|
||||
keepalive?: boolean | KeepAliveProps
|
||||
layout?: false | LayoutKey | Ref<LayoutKey> | ComputedRef<LayoutKey>
|
||||
middleware?: MiddlewareKey | NavigationGuard | Array<MiddlewareKey | NavigationGuard>
|
||||
[key: string]: any
|
||||
[key: string]: unknown
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { useNuxtApp } from '../nuxt'
|
||||
import type { NuxtPayload } from '#app'
|
||||
|
||||
/**
|
||||
* Allows full control of the hydration cycle to set and receive data from the server.
|
||||
@ -7,7 +8,7 @@ import { useNuxtApp } from '../nuxt'
|
||||
* @param get a function that returns the value to set the initial data
|
||||
* @param set a function that will receive the data on the client-side
|
||||
*/
|
||||
export const useHydration = <T> (key: string, get: () => T, set: (value: T) => void) => {
|
||||
export const useHydration = <K extends keyof NuxtPayload, T = NuxtPayload[K]> (key: K, get: () => T, set: (value: T) => void) => {
|
||||
const nuxt = useNuxtApp()
|
||||
|
||||
if (process.server) {
|
||||
@ -18,7 +19,7 @@ export const useHydration = <T> (key: string, get: () => T, set: (value: T) => v
|
||||
|
||||
if (process.client) {
|
||||
nuxt.hooks.hook('app:created', () => {
|
||||
set(nuxt.payload[key])
|
||||
set(nuxt.payload[key] as T)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,8 @@ import { useRuntimeConfig } from '#app'
|
||||
|
||||
export function useRequestURL () {
|
||||
if (process.server) {
|
||||
const { baseURL } = useRuntimeConfig().app
|
||||
const url = getRequestURL(useRequestEvent())
|
||||
url.pathname = joinURL(baseURL, url.pathname)
|
||||
url.pathname = joinURL(useRuntimeConfig().app.baseURL, url.pathname)
|
||||
return url
|
||||
}
|
||||
return new URL(window.location.href)
|
||||
|
@ -58,7 +58,9 @@ export interface NuxtSSRContext extends SSRContext {
|
||||
/** whether we are rendering an SSR error */
|
||||
error?: boolean
|
||||
nuxt: _NuxtApp
|
||||
payload: _NuxtApp['payload']
|
||||
payload: NuxtPayload
|
||||
/** This is used solely to render runtime config with SPA renderer. */
|
||||
config?: Pick<RuntimeConfig, 'public' | 'app'>
|
||||
teleports?: Record<string, string>
|
||||
renderMeta?: () => Promise<NuxtMeta> | NuxtMeta
|
||||
islandContext?: NuxtIslandContext
|
||||
@ -68,6 +70,25 @@ export interface NuxtSSRContext extends SSRContext {
|
||||
_payloadReducers: Record<string, (data: any) => any>
|
||||
}
|
||||
|
||||
export interface NuxtPayload {
|
||||
path?: string
|
||||
serverRendered?: boolean
|
||||
prerenderedAt?: number
|
||||
data: Record<string, any>
|
||||
state: Record<string, any>
|
||||
config?: Pick<RuntimeConfig, 'public' | 'app'>
|
||||
error?: Error | {
|
||||
url: string
|
||||
statusCode: number
|
||||
statusMessage: string
|
||||
message: string
|
||||
description: string
|
||||
data?: any
|
||||
} | null
|
||||
_errors: Record<string, NuxtError | undefined>
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
interface _NuxtApp {
|
||||
vueApp: App<Element>
|
||||
globalName: string
|
||||
@ -120,23 +141,7 @@ interface _NuxtApp {
|
||||
deferHydration: () => () => void | Promise<void>
|
||||
|
||||
ssrContext?: NuxtSSRContext
|
||||
payload: {
|
||||
path?: string
|
||||
serverRendered?: boolean
|
||||
prerenderedAt?: number
|
||||
data: Record<string, any>
|
||||
state: Record<string, any>
|
||||
error?: Error | {
|
||||
url: string
|
||||
statusCode: number
|
||||
statusMessage: string
|
||||
message: string
|
||||
description: string
|
||||
data?: any
|
||||
} | null
|
||||
_errors: Record<string, NuxtError | undefined>
|
||||
[key: string]: any
|
||||
}
|
||||
payload: NuxtPayload
|
||||
static: {
|
||||
data: Record<string, any>
|
||||
}
|
||||
@ -297,7 +302,7 @@ export function createNuxtApp (options: CreateOptions) {
|
||||
}
|
||||
|
||||
// Expose runtime config
|
||||
const runtimeConfig = process.server ? options.ssrContext!.runtimeConfig : reactive(nuxtApp.payload.config)
|
||||
const runtimeConfig = process.server ? options.ssrContext!.runtimeConfig : reactive(nuxtApp.payload.config!)
|
||||
nuxtApp.provide('config', runtimeConfig)
|
||||
|
||||
return nuxtApp
|
||||
|
@ -101,6 +101,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
|
||||
runtimeConfig: {
|
||||
...nuxt.options.runtimeConfig,
|
||||
nitro: {
|
||||
// @ts-expect-error TODO: https://github.com/unjs/nitro/pull/1336
|
||||
envPrefix: 'NUXT_',
|
||||
...nuxt.options.runtimeConfig.nitro
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import { defineRenderHandler, getRouteRules, useRuntimeConfig } from '#internal/
|
||||
import { useNitroApp } from '#internal/nitro/app'
|
||||
|
||||
// eslint-disable-next-line import/no-restricted-paths
|
||||
import type { NuxtApp, NuxtSSRContext } from '#app/nuxt'
|
||||
import type { NuxtPayload, NuxtSSRContext } from '#app/nuxt'
|
||||
// @ts-expect-error virtual file
|
||||
import { appRootId, appRootTag } from '#internal/nuxt.config.mjs'
|
||||
// @ts-expect-error virtual file
|
||||
@ -179,7 +179,7 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
|
||||
|
||||
// Whether we're rendering an error page
|
||||
const ssrError = event.node.req.url?.startsWith('/__nuxt_error')
|
||||
? getQuery(event) as unknown as Exclude<NuxtApp['payload']['error'], Error>
|
||||
? getQuery(event) as unknown as Exclude<NuxtPayload['error'], Error>
|
||||
: null
|
||||
|
||||
if (ssrError && ssrError.statusCode) {
|
||||
@ -230,7 +230,7 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
|
||||
(process.env.prerender ? PRERENDER_NO_SSR_ROUTES.has(url) : false),
|
||||
error: !!ssrError,
|
||||
nuxt: undefined!, /* NuxtApp */
|
||||
payload: (ssrError ? { error: ssrError } : {}) as NuxtSSRContext['payload'],
|
||||
payload: (ssrError ? { error: ssrError } : {}) as NuxtPayload,
|
||||
_payloadReducers: {},
|
||||
islandContext
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import { useRoute } from 'vue-router'
|
||||
import type { NuxtError } from '#app'
|
||||
|
||||
export interface PageMeta {
|
||||
[key: string]: any
|
||||
[key: string]: unknown
|
||||
/**
|
||||
* Validate whether a given route can validly be rendered with this page.
|
||||
*
|
||||
|
5
packages/nuxt/types.d.ts
vendored
5
packages/nuxt/types.d.ts
vendored
@ -10,7 +10,10 @@ declare global {
|
||||
}
|
||||
|
||||
declare module 'nitropack' {
|
||||
interface NitroRuntimeConfigApp extends RuntimeConfig['app'] {}
|
||||
interface NitroRuntimeConfigApp {
|
||||
buildAssetsDir: string
|
||||
cdnURL: string
|
||||
}
|
||||
interface NitroRuntimeConfig extends RuntimeConfig {}
|
||||
interface NitroRouteConfig {
|
||||
ssr?: boolean
|
||||
|
@ -6,6 +6,7 @@ import type { Options as VueJsxPluginOptions } from '@vitejs/plugin-vue-jsx'
|
||||
import type { AppHeadMetaObject } from './head'
|
||||
import type { Nuxt } from './nuxt'
|
||||
import type { SchemaDefinition } from 'untyped'
|
||||
import type { NitroRuntimeConfig, NitroRuntimeConfigApp } from 'nitropack'
|
||||
export type { SchemaDefinition } from 'untyped'
|
||||
|
||||
type DeepPartial<T> = T extends Function ? T : T extends Record<string, any> ? { [P in keyof T]?: DeepPartial<T[P]> } : T
|
||||
@ -52,12 +53,14 @@ const message = Symbol('message')
|
||||
export type RuntimeValue<T, B extends string> = T & { [message]?: B }
|
||||
type Overrideable<T extends Record<string, any>, Path extends string = ''> = {
|
||||
[K in keyof T]?: K extends string
|
||||
? T[K] extends Record<string, any>
|
||||
? RuntimeValue<Overrideable<T[K], `${Path}_${UpperSnakeCase<K>}`>, `You can override this value at runtime with NUXT${Path}_${UpperSnakeCase<K>}`>
|
||||
: RuntimeValue<T[K], `You can override this value at runtime with NUXT${Path}_${UpperSnakeCase<K>}`>
|
||||
: K extends number
|
||||
? T[K]
|
||||
: never
|
||||
? unknown extends T[K]
|
||||
? unknown
|
||||
: T[K] extends Record<string, unknown>
|
||||
? RuntimeValue<Overrideable<T[K], `${Path}_${UpperSnakeCase<K>}`>, `You can override this value at runtime with NUXT${Path}_${UpperSnakeCase<K>}`>
|
||||
: RuntimeValue<T[K], `You can override this value at runtime with NUXT${Path}_${UpperSnakeCase<K>}`>
|
||||
: K extends number
|
||||
? T[K]
|
||||
: never
|
||||
}
|
||||
|
||||
/** User configuration in `nuxt.config` file */
|
||||
@ -128,11 +131,14 @@ export interface ViteConfig extends ViteUserConfig {
|
||||
|
||||
// -- Runtime Config --
|
||||
|
||||
type RuntimeConfigNamespace = Record<string, any>
|
||||
type RuntimeConfigNamespace = Record<string, unknown>
|
||||
|
||||
export interface PublicRuntimeConfig extends RuntimeConfigNamespace { }
|
||||
|
||||
export interface RuntimeConfig extends RuntimeConfigNamespace {
|
||||
app: NitroRuntimeConfigApp
|
||||
/** Only available on the server. */
|
||||
nitro?: NitroRuntimeConfig['nitro']
|
||||
public: PublicRuntimeConfig
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ export interface ModuleMeta {
|
||||
*/
|
||||
compatibility?: NuxtCompatibility
|
||||
|
||||
[key: string]: any
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
/** The options received. */
|
||||
|
8
test/fixtures/basic-types/types.ts
vendored
8
test/fixtures/basic-types/types.ts
vendored
@ -218,14 +218,14 @@ describe('runtimeConfig', () => {
|
||||
expectTypeOf(runtimeConfig.public.needsFallback).toEqualTypeOf<string>()
|
||||
expectTypeOf(runtimeConfig.privateConfig).toEqualTypeOf<string>()
|
||||
expectTypeOf(runtimeConfig.public.ids).toEqualTypeOf<number[]>()
|
||||
expectTypeOf(runtimeConfig.unknown).toEqualTypeOf<any>()
|
||||
expectTypeOf(runtimeConfig.unknown).toEqualTypeOf<unknown>()
|
||||
|
||||
const injectedConfig = useNuxtApp().$config
|
||||
expectTypeOf(injectedConfig.public.testConfig).toEqualTypeOf<number>()
|
||||
expectTypeOf(injectedConfig.public.needsFallback).toEqualTypeOf<string>()
|
||||
expectTypeOf(injectedConfig.privateConfig).toEqualTypeOf<string>()
|
||||
expectTypeOf(injectedConfig.public.ids).toEqualTypeOf<number[]>()
|
||||
expectTypeOf(injectedConfig.unknown).toEqualTypeOf<any>()
|
||||
expectTypeOf(injectedConfig.unknown).toEqualTypeOf<unknown>()
|
||||
})
|
||||
it('provides hints on overriding these values', () => {
|
||||
const val = defineNuxtConfig({
|
||||
@ -241,8 +241,8 @@ describe('runtimeConfig', () => {
|
||||
expectTypeOf(val.runtimeConfig!.privateConfig).toEqualTypeOf<undefined | RuntimeValue<string, 'You can override this value at runtime with NUXT_PRIVATE_CONFIG'>>()
|
||||
expectTypeOf(val.runtimeConfig!.baseURL).toEqualTypeOf<undefined | RuntimeValue<string, 'You can override this value at runtime with NUXT_BASE_URL'>>()
|
||||
expectTypeOf(val.runtimeConfig!.baseAPIToken).toEqualTypeOf<undefined | RuntimeValue<string, 'You can override this value at runtime with NUXT_BASE_API_TOKEN'>>()
|
||||
expectTypeOf(val.runtimeConfig!.public!.ids).toEqualTypeOf<undefined | RuntimeValue<Array<number | undefined>, 'You can override this value at runtime with NUXT_PUBLIC_IDS'>>()
|
||||
expectTypeOf(val.runtimeConfig!.unknown).toEqualTypeOf<any>()
|
||||
expectTypeOf(val.runtimeConfig!.public!.ids).toEqualTypeOf<undefined | RuntimeValue<Array<number>, 'You can override this value at runtime with NUXT_PUBLIC_IDS'>>()
|
||||
expectTypeOf(val.runtimeConfig!.unknown).toEqualTypeOf<unknown>()
|
||||
})
|
||||
})
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user