Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(nuxt): enable config schema by default #19172

Merged
merged 15 commits into from
Mar 4, 2023
35 changes: 16 additions & 19 deletions packages/nuxt/src/core/schema.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { existsSync } from 'node:fs'
import { writeFile, mkdir, rm } from 'node:fs/promises'
import { writeFile, mkdir } from 'node:fs/promises'
import { dirname, resolve } from 'pathe'
import chokidar from 'chokidar'
import { defu } from 'defu'
import { debounce } from 'perfect-debounce'
import { defineNuxtModule, createResolver } from '@nuxt/kit'
import {
resolveSchema as resolveUntypedSchema,
generateMarkdown,
generateTypes
} from 'untyped'
import type { Schema, SchemaDefinition } from 'untyped'
Expand Down Expand Up @@ -39,9 +38,14 @@ export default defineNuxtModule({
})

// Register module types
nuxt.hook('prepare:types', (ctx) => {
nuxt.hook('prepare:types', async (ctx) => {
ctx.references.push({ path: 'nuxt-config-schema' })
ctx.references.push({ path: 'schema/nuxt.schema.d.ts' })
if (nuxt.options._prepare) {
await nuxt.hooks.callHook('schema:beforeWrite', schema)
await writeSchema(schema)
await nuxt.hooks.callHook('schema:written')
Comment on lines +45 to +47
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it make sense to move the hooks into writeSchema itself?

}
})

// Resolve schema after all modules initialized
Expand Down Expand Up @@ -122,26 +126,13 @@ export default defineNuxtModule({
}

async function writeSchema (schema: Schema) {
// Avoid writing empty schema
const isEmptySchema = !schema.properties || Object.keys(schema.properties).length === 0
if (isEmptySchema) {
await rm(resolve(nuxt.options.buildDir, 'schema'), { recursive: true }).catch(() => { })
return
}

// Write it to build dir
await mkdir(resolve(nuxt.options.buildDir, 'schema'), { recursive: true })
await writeFile(
resolve(nuxt.options.buildDir, 'schema/nuxt.schema.json'),
JSON.stringify(schema, null, 2),
'utf8'
)
const markdown = '# Nuxt Custom Config Schema' + generateMarkdown(schema)
await writeFile(
resolve(nuxt.options.buildDir, 'schema/nuxt.schema.md'),
markdown,
'utf8'
)
const _types = generateTypes(schema, {
addExport: true,
interfaceName: 'NuxtCustomSchema',
Expand All @@ -152,12 +143,18 @@ export default defineNuxtModule({
`
export type CustomAppConfig = Exclude<NuxtCustomSchema['appConfig'], undefined>

declare module '@nuxt/schema' {
interface NuxtConfig extends NuxtCustomSchema {}
interface NuxtOptions extends NuxtCustomSchema {}
interface _AppConfig extends CustomAppConfig {}
}

declare module 'nuxt/schema' {
interface NuxtConfig extends NuxtCustomSchema {}
interface NuxtOptions extends NuxtCustomSchema {}
interface AppConfigInput extends CustomAppConfig {}
interface AppConfig extends CustomAppConfig {}
}`
interface _AppConfig extends CustomAppConfig {}
}
`
const typesPath = resolve(
nuxt.options.buildDir,
'schema/nuxt.schema.d.ts'
Expand Down
2 changes: 1 addition & 1 deletion packages/schema/src/config/experimental.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export default defineUntypedSchema({
componentIslands: false,

/**
* Enable experimental config schema support
* Config schema support
*
* @see https://github.com/nuxt/nuxt/issues/15592
*/
Expand Down
7 changes: 5 additions & 2 deletions packages/schema/src/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,10 @@ export interface RuntimeConfig extends RuntimeConfigNamespace {
}

// -- App Config --
export interface AppConfigInput extends Record<string, any> {

export interface _AppConfig extends Record<string, any> { }
pi0 marked this conversation as resolved.
Show resolved Hide resolved

export interface AppConfigInput extends _AppConfig {
/** @deprecated reserved */
private?: never
/** @deprecated reserved */
Expand All @@ -153,4 +156,4 @@ export interface NuxtAppConfig {
keepalive: boolean | KeepAliveProps
}

export interface AppConfig { }
export interface AppConfig extends _AppConfig { }
3 changes: 1 addition & 2 deletions test/fixtures/basic/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,7 @@ export default defineNuxtConfig({
componentIslands: true,
reactivityTransform: true,
treeshakeClientOnly: true,
payloadExtraction: true,
configSchema: true
payloadExtraction: true
},
appConfig: {
fromNuxtConfig: true,
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/basic/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ describe('app config', () => {
nested: {
val: number
},
userConfig: number
userConfig?: number
danielroe marked this conversation as resolved.
Show resolved Hide resolved
}
expectTypeOf<AppConfig>().toMatchTypeOf<ExpectedMergedAppConfig>()
})
Expand Down