@tamilvananmurugan/xlibs
Version:
Comprehensive UI component library with Aceternity, MagicUI, and ShadCN components
188 lines (159 loc) • 6.35 kB
text/typescript
// Build Configuration Parser
// Handles CLI/build config overrides for libraries and stack
import * as yaml from 'js-yaml';
import { readFileSync } from 'fs';
export interface BuildConfig {
version: number;
type: string;
// Stack configuration - ONLY non-UI components allowed
stack?: {
frontend: 'react' | 'vue' | 'svelte';
state_management: 'redux' | 'mobx' | 'zustand' | 'context';
api_client: 'axios' | 'fetch' | 'graphql-request' | 'apollo';
build_tool: 'vite' | 'webpack' | 'next' | 'rollup';
};
// Backend integration
backend?: {
provider: 'wundergraph' | 'graphql' | 'rest' | 'firebase' | 'supabase';
endpoint?: string;
auth_required?: boolean;
};
// Routing configuration
routing?: {
strategy: 'file-based' | 'config-based';
nested_routes?: boolean;
dynamic_routes?: boolean;
};
}
export class BuildConfigParser {
/**
* Parse a YAML file containing build configuration
* @param filePath Path to the YAML file
* @returns Parsed build configuration
*/
static parseConfig(filePath: string): BuildConfig {
try {
const fileContent = readFileSync(filePath, 'utf8');
const parsed = yaml.load(fileContent) as BuildConfig;
// Validate required fields
if (!parsed.version) {
throw new Error('Missing required field: version');
}
if (!parsed.type) {
throw new Error('Missing required field: type');
}
return parsed;
} catch (error) {
throw new Error(`Failed to parse build config YAML file ${filePath}: ${(error as Error).message}`);
}
}
/**
* Get the effective component library for a specific component
* @param config Build configuration
* @param componentName Name of the component
* @returns The effective library for the component
*/
static getComponentLibrary(): string {
return "aceternity"; // Default to Aceternity UI for now
}
/**
* Get the effective stack configuration
* @param config Build configuration
* @returns The effective stack configuration
*/
static getStackConfig(config: BuildConfig): BuildConfig['stack'] {
// Return stack config if specified, otherwise default values
return config.stack || {
frontend: 'react',
state_management: 'redux',
api_client: 'axios',
build_tool: 'vite'
};
}
/**
* Get the effective backend configuration
* @param config Build configuration
* @returns The effective backend configuration
*/
static getBackendConfig(config: BuildConfig): BuildConfig['backend'] {
// Return backend config if specified
return config.backend;
}
/**
* Get the effective routing configuration
* @param config Build configuration
* @returns The effective routing configuration
*/
static getRoutingConfig(config: BuildConfig): BuildConfig['routing'] {
// Return routing config if specified, otherwise default values
return config.routing || {
strategy: 'file-based',
nested_routes: true,
dynamic_routes: true
};
}
/**
* Validate build configuration compatibility
* @param config Build configuration
* @returns Validation result with isValid flag and errors array
*/
static validateConfig(config: BuildConfig): {
isValid: boolean;
errors: string[]
} {
const errors: string[] = [];
// Validate stack configuration
if (config.stack) {
const validFrontends = ['react', 'vue', 'svelte'];
const validStateManagement = ['redux', 'mobx', 'zustand', 'context'];
const validApiClient = ['axios', 'fetch', 'graphql-request', 'apollo'];
const validBuildTools = ['vite', 'webpack', 'next', 'rollup'];
if (config.stack.frontend && !validFrontends.includes(config.stack.frontend)) {
errors.push(`Invalid frontend: ${config.stack.frontend}`);
}
if (config.stack.state_management && !validStateManagement.includes(config.stack.state_management)) {
errors.push(`Invalid state management: ${config.stack.state_management}`);
}
if (config.stack.api_client && !validApiClient.includes(config.stack.api_client)) {
errors.push(`Invalid API client: ${config.stack.api_client}`);
}
if (config.stack.build_tool && !validBuildTools.includes(config.stack.build_tool)) {
errors.push(`Invalid build tool: ${config.stack.build_tool}`);
}
}
// Validate backend configuration
if (config.backend) {
const validProviders = ['wundergraph', 'graphql', 'rest', 'firebase', 'supabase'];
if (config.backend.provider && !validProviders.includes(config.backend.provider)) {
errors.push(`Invalid backend provider: ${config.backend.provider}`);
}
if (config.backend.auth_required && typeof config.backend.auth_required !== 'boolean') {
errors.push('auth_required must be a boolean');
}
}
// Validate routing configuration
if (config.routing) {
const validStrategies = ['file-based', 'config-based'];
if (config.routing.strategy && !validStrategies.includes(config.routing.strategy)) {
errors.push(`Invalid routing strategy: ${config.routing.strategy}`);
}
if (config.routing.nested_routes && typeof config.routing.nested_routes !== 'boolean') {
errors.push('nested_routes must be a boolean');
}
if (config.routing.dynamic_routes && typeof config.routing.dynamic_routes !== 'boolean') {
errors.push('dynamic_routes must be a boolean');
}
}
return {
isValid: errors.length === 0,
errors
};
}
}
// Utility functions for common config tasks
export const parseBuildConfig = (filePath: string) => BuildConfigParser.parseConfig(filePath);
export const validateBuildConfig = (config: BuildConfig) => BuildConfigParser.validateConfig(config);
export const getComponentLibrary = () => BuildConfigParser.getComponentLibrary();
export const getStackConfig = (config: BuildConfig) => BuildConfigParser.getStackConfig(config);
export const getBackendConfig = (config: BuildConfig) => BuildConfigParser.getBackendConfig(config);
export const getRoutingConfig = (config: BuildConfig) => BuildConfigParser.getRoutingConfig(config);