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