Nuxt types and default configuration providing comprehensive TypeScript types, schema definitions, and configuration system for the Nuxt framework.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
The schema validation system in @nuxt/schema provides default configuration schema and validation system that ensures proper Nuxt configuration through the untyped library integration.
type SchemaDefinition = import('untyped').SchemaDefinition
const NuxtConfigSchema: SchemaDefinitionThe default export from @nuxt/schema combines all configuration resolvers:
const NuxtConfigSchema = {
...adhoc,
...app,
...build,
...common,
...dev,
...experimental,
...generate,
...internal,
...nitro,
...postcss,
...router,
...typescript,
...esbuild,
...oxc,
...vite,
...webpack,
}The common configuration module defines core Nuxt options:
const commonResolvers = {
extends: undefined,
compatibilityDate: undefined,
theme: undefined,
rootDir: {
$resolve: (val: unknown) => typeof val === 'string' ? resolve(val) : process.cwd()
},
workspaceDir: {
$resolve: async (val: unknown, get: Function) => {
const rootDir = await get('rootDir');
return val && typeof val === 'string'
? resolve(rootDir, val)
: await findWorkspaceDir(rootDir, { gitConfig: 'closest', try: true })
.catch(() => rootDir);
}
},
srcDir: {
$resolve: async (val: unknown, get: Function) => {
if (val && typeof val === 'string') {
return resolve(await get('rootDir'), val);
}
const rootDir = await get('rootDir');
const srcDir = resolve(rootDir, 'app');
if (!existsSync(srcDir)) {
return rootDir;
}
return srcDir;
}
}
}Application-specific configuration with validation:
const appResolvers = {
vue: {
transformAssetUrls: {
video: ['src', 'poster'],
source: ['src'],
img: ['src'],
image: ['xlink:href', 'href'],
use: ['xlink:href', 'href']
},
compilerOptions: {},
runtimeCompiler: {
$resolve: (val: unknown) => typeof val === 'boolean' ? val : false
},
propsDestructure: true,
config: {}
},
app: {
baseURL: {
$resolve: (val: unknown) => {
if (typeof val === 'string') {
return withTrailingSlash(val);
}
return '/';
}
},
buildAssetsDir: {
$resolve: (val: unknown, get: Function) => {
return val || '/_nuxt/';
}
}
}
}Build system configuration with defaults:
const buildResolvers = {
builder: {
$resolve: (val: unknown) => {
if (val && typeof val === 'object' && 'bundle' in val) {
return val as NuxtBuilder;
}
const map = {
rspack: '@nuxt/rspack-builder',
vite: '@nuxt/vite-builder',
webpack: '@nuxt/webpack-builder'
};
if (typeof val === 'string' && val in map) {
return map[val as keyof typeof map];
}
return map.vite;
}
},
sourcemap: {
$resolve: async (val: unknown, get: Function) => {
if (typeof val === 'boolean') {
return { server: val, client: val };
}
if (val && typeof val === 'object') {
return {
server: val.server ?? true,
client: val.client ?? false
};
}
return { server: true, client: false };
}
}
}Utility function for creating type-safe configuration resolvers:
function defineResolvers<C extends Partial<Resolvable<ConfigSchema>>>(config: C): any {
return config as any;
}
type Resolvable<Namespace> = keyof Exclude<NonNullable<Namespace>, boolean | string | (() => any)> extends string
? {
[K in keyof Namespace]: Partial<Resolvable<Namespace[K]>> | Resolvers<Namespace[K]>
} | Namespace
: Namespace | Resolvers<Namespace>
interface Resolvers<ReturnValue> {
$resolve: (val: unknown, get: <K extends KeysOf<ConfigSchema>>(key: K) => Promise<ReturnFromKey<ConfigSchema, K>>) => Awaitable<ReturnValue>
$schema?: InputObject['$schema']
$default?: ReturnValue
}import { defineResolvers } from '@nuxt/schema/utils/definition';
const myModuleResolvers = defineResolvers({
myModule: {
enabled: {
$resolve: (val) => val !== false,
$default: true,
$schema: {
type: 'boolean',
description: 'Enable the module'
}
},
apiKey: {
$resolve: (val) => {
if (typeof val !== 'string' || val.length === 0) {
throw new Error('API key is required and must be a non-empty string');
}
return val;
},
$schema: {
type: 'string',
description: 'API key for the service'
}
},
timeout: {
$resolve: (val) => {
const timeout = typeof val === 'number' ? val : 5000;
if (timeout < 0) {
throw new Error('Timeout must be a positive number');
}
return timeout;
},
$default: 5000,
$schema: {
type: 'number',
minimum: 0,
description: 'Request timeout in milliseconds'
}
}
}
});const conditionalResolvers = defineResolvers({
database: {
$resolve: async (val, get) => {
const isDev = await get('dev');
if (typeof val === 'object' && val !== null) {
return val;
}
// Default configuration based on environment
return {
host: isDev ? 'localhost' : process.env.DB_HOST,
port: isDev ? 5432 : parseInt(process.env.DB_PORT || '5432'),
name: isDev ? 'dev_db' : process.env.DB_NAME,
ssl: !isDev
};
}
},
features: {
analytics: {
$resolve: async (val, get) => {
const isDev = await get('dev');
// Disable analytics in development by default
if (isDev && val === undefined) {
return false;
}
return val !== false;
}
}
}
});import type { SchemaDefinition } from '@nuxt/schema';
const moduleSchema: SchemaDefinition = {
type: 'object',
properties: {
myModule: {
type: 'object',
properties: {
enabled: {
type: 'boolean',
default: true,
description: 'Enable the module'
},
apiKey: {
type: 'string',
minLength: 1,
description: 'API key for the service'
},
timeout: {
type: 'number',
minimum: 0,
default: 5000,
description: 'Request timeout in milliseconds'
},
endpoints: {
type: 'object',
properties: {
api: { type: 'string', format: 'uri' },
auth: { type: 'string', format: 'uri' }
},
required: ['api']
}
},
required: ['apiKey']
}
}
};export default defineNuxtModule({
meta: {
name: 'my-module',
configKey: 'myModule'
},
schema: {
enabled: { type: 'boolean', default: true },
apiKey: { type: 'string' },
timeout: { type: 'number', default: 5000, minimum: 0 }
},
setup(options, nuxt) {
// Options are already resolved and validated by schema
if (!options.enabled) return;
// Use validated configuration
console.log(`Module enabled with timeout: ${options.timeout}ms`);
// Add runtime configuration
nuxt.options.runtimeConfig.myModule = {
apiKey: options.apiKey
};
}
});// Extend existing schema
export default defineNuxtModule({
setup(options, nuxt) {
// Extend the Nuxt config schema
nuxt.options.$schema = nuxt.options.$schema || {};
// Add module-specific schema
nuxt.options.$schema.properties = {
...nuxt.options.$schema.properties,
myModule: {
type: 'object',
properties: {
customOption: {
type: 'string',
default: 'default-value'
}
}
}
};
}
});import { validateConfig } from 'untyped';
export function validateNuxtConfig(config: any, schema: SchemaDefinition) {
const result = validateConfig(config, schema);
if (result.errors && result.errors.length > 0) {
const errorMessages = result.errors.map(error =>
`${error.path}: ${error.message}`
).join('\n');
throw new Error(`Configuration validation failed:\n${errorMessages}`);
}
return result.config;
}export function createModuleSchema(options: {
required?: string[],
optional?: string[],
types?: Record<string, any>
}) {
const properties: Record<string, any> = {};
// Add required properties
options.required?.forEach(prop => {
properties[prop] = {
type: options.types?.[prop] || 'string',
description: `Required ${prop} configuration`
};
});
// Add optional properties
options.optional?.forEach(prop => {
properties[prop] = {
type: options.types?.[prop] || 'string',
description: `Optional ${prop} configuration`
};
});
return {
type: 'object',
properties,
required: options.required || []
};
}The schema validation system ensures that all Nuxt configuration is properly validated and resolved, providing type safety and clear error messages when configuration issues are detected.
Install with Tessl CLI
npx tessl i tessl/npm-nuxt--schema