CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-nuxt--schema

Nuxt types and default configuration providing comprehensive TypeScript types, schema definitions, and configuration system for the Nuxt framework.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

schema-validation.mddocs/

Schema Validation

The schema validation system in @nuxt/schema provides default configuration schema and validation system that ensures proper Nuxt configuration through the untyped library integration.

Core Schema Types

Schema Definition

type SchemaDefinition = import('untyped').SchemaDefinition

const NuxtConfigSchema: SchemaDefinition

The 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,
}

Configuration Resolvers

Common Configuration Resolvers

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;
    }
  }
}

App Configuration Resolvers

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 Configuration Resolvers

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 };
    }
  }
}

Schema Definition Utilities

defineResolvers Helper

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
}

Configuration Validation Patterns

Custom Schema Definition

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'
      }
    }
  }
});

Conditional Resolution

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;
      }
    }
  }
});

Schema Validation

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']
    }
  }
};

Runtime Schema Usage

Configuration Resolution in Modules

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
    };
  }
});

Schema Extension

// 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'
          }
        }
      }
    };
  }
});

Validation Helpers

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;
}

Dynamic Schema Generation

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

docs

compatibility.md

components.md

configuration-types.md

core-types.md

hooks.md

index.md

modules.md

runtime-config.md

schema-validation.md

tile.json