UNPKG

node-apis

Version:

🚀 Advanced TypeScript API generator with clean architecture, comprehensive testing, and automatic formatting. Generate production-ready Node.js APIs with complete integration test suites.

352 lines 13.1 kB
"use strict"; /** * Configuration management service */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.getEffectiveApiStyle = exports.getEffectiveFramework = exports.validateConfig = exports.initializeConfig = exports.setDatabaseConfig = exports.getDatabaseConfig = exports.setTrpcStyle = exports.setApiStyle = exports.setFramework = exports.getApiStyle = exports.getFramework = exports.saveConfig = exports.loadConfig = exports.configExists = exports.getConfigPath = void 0; const path = __importStar(require("path")); const fs = __importStar(require("fs-extra")); const DEFAULT_CONFIG_FILENAME = 'node-apis.config.json'; const CONFIG_VERSION = '1.0.0'; /** * Gets the config file path */ const getConfigPath = ({ configPath, baseDir = process.cwd(), } = {}) => { if (configPath) { return configPath; } return path.join(baseDir, DEFAULT_CONFIG_FILENAME); }; exports.getConfigPath = getConfigPath; /** * Checks if config file exists */ const configExists = async ({ configPath, } = {}) => { const filePath = (0, exports.getConfigPath)(configPath ? { configPath } : {}); return await fs.pathExists(filePath); }; exports.configExists = configExists; /** * Loads configuration from file */ const loadConfig = async ({ configPath, } = {}) => { try { const filePath = (0, exports.getConfigPath)(configPath ? { configPath } : {}); const exists = await (0, exports.configExists)(configPath ? { configPath } : {}); if (!exists) { return null; } const configContent = await fs.readFile(filePath, 'utf8'); const config = JSON.parse(configContent); // Validate the loaded config const validation = (0, exports.validateConfig)({ config }); if (!validation.isValid) { console.warn('⚠️ Config file has validation errors:', validation.errors.join(', ')); // Return the config anyway, but with warnings } return config; } catch (error) { console.warn(`⚠️ Failed to load config: ${error.message}`); return null; } }; exports.loadConfig = loadConfig; /** * Saves configuration to file */ const saveConfig = async ({ config, configPath, options = {}, }) => { try { const filePath = (0, exports.getConfigPath)(configPath ? { configPath } : {}); let finalConfig = config; // Merge with existing config if requested if (options.merge) { const existingConfig = await (0, exports.loadConfig)(configPath ? { configPath } : {}); if (existingConfig) { finalConfig = { ...existingConfig, ...config }; } } // Add version if not present if (!finalConfig.version) { finalConfig.version = CONFIG_VERSION; } // Validate if requested if (options.validate !== false) { const validation = (0, exports.validateConfig)({ config: finalConfig }); if (!validation.isValid) { throw new Error(`Config validation failed: ${validation.errors.join(', ')}`); } } const configContent = JSON.stringify(finalConfig, null, 2); await fs.writeFile(filePath, configContent, 'utf8'); } catch (error) { throw new Error(`Failed to save config: ${error.message}`); } }; exports.saveConfig = saveConfig; /** * Gets the configured framework */ const getFramework = async ({ configPath, } = {}) => { const config = await (0, exports.loadConfig)(configPath ? { configPath } : {}); return config?.framework || null; }; exports.getFramework = getFramework; /** * Gets the configured API style */ const getApiStyle = async ({ configPath, } = {}) => { const config = await (0, exports.loadConfig)(configPath ? { configPath } : {}); return config?.apiStyle || null; }; exports.getApiStyle = getApiStyle; /** * Sets the framework in config */ const setFramework = async ({ framework, configPath, }) => { // Check if config exists, if not create a default one first const exists = await (0, exports.configExists)(configPath ? { configPath } : {}); if (!exists) { // Create default config with the specified framework await (0, exports.initializeConfig)({ framework, ...(configPath && { configPath }), }); } else { // Update existing config await (0, exports.saveConfig)({ config: { framework }, ...(configPath && { configPath }), options: { merge: true, validate: true }, }); } }; exports.setFramework = setFramework; /** * Sets the API style in config */ const setApiStyle = async ({ apiStyle, configPath, }) => { // Check if config exists, if not create a default one first const exists = await (0, exports.configExists)(configPath ? { configPath } : {}); if (!exists) { // Create default config with the specified API style await (0, exports.initializeConfig)({ ...(configPath && { configPath }), }); // Then update with API style await (0, exports.saveConfig)({ config: { apiStyle }, ...(configPath && { configPath }), options: { merge: true, validate: true }, }); } else { // Update existing config await (0, exports.saveConfig)({ config: { apiStyle }, ...(configPath && { configPath }), options: { merge: true, validate: true }, }); } }; exports.setApiStyle = setApiStyle; /** * Sets the default tRPC style preference in config (deprecated - use setApiStyle) */ const setTrpcStyle = async ({ trpcStyle, configPath, }) => { // Deprecated: Convert to new API style format const apiStyle = trpcStyle ? 'trpc' : 'rest'; await (0, exports.setApiStyle)({ apiStyle, ...(configPath && { configPath }) }); }; exports.setTrpcStyle = setTrpcStyle; /** * Gets database configuration */ const getDatabaseConfig = async ({ configPath, } = {}) => { const config = await (0, exports.loadConfig)(configPath ? { configPath } : {}); return config?.database || null; }; exports.getDatabaseConfig = getDatabaseConfig; /** * Sets database configuration */ const setDatabaseConfig = async ({ databaseConfig, configPath, }) => { await (0, exports.saveConfig)({ config: { database: databaseConfig }, ...(configPath && { configPath }), options: { merge: true, validate: true }, }); }; exports.setDatabaseConfig = setDatabaseConfig; /** * Initializes a new config file */ const initializeConfig = async ({ framework, force = false, configPath, } = {}) => { const exists = await (0, exports.configExists)(configPath ? { configPath } : {}); if (exists && !force) { throw new Error('Config file already exists. Use --force to overwrite.'); } const defaultConfig = { version: CONFIG_VERSION, framework: framework || 'express', database: {}, preferences: { autoFormat: true, generateTests: true, skipConfirmation: false, }, }; await (0, exports.saveConfig)({ config: defaultConfig, ...(configPath && { configPath }), options: { validate: true }, }); return defaultConfig; }; exports.initializeConfig = initializeConfig; /** * Validates configuration object */ const validateConfig = ({ config }) => { const errors = []; const warnings = []; if (!config || typeof config !== 'object') { errors.push('Config must be an object'); return { isValid: false, errors, warnings }; } // Validate framework if (config.framework && !['express', 'hono', 't3'].includes(config.framework)) { errors.push(`Invalid framework: ${config.framework}. Must be 'express', 'hono', or 't3'`); } // Validate API style if (config.apiStyle && !['rest', 'trpc'].includes(config.apiStyle)) { errors.push(`Invalid API style: ${config.apiStyle}. Must be 'rest' or 'trpc'`); } // Validate database config if (config.database && typeof config.database === 'object') { if (config.database.orm && !['prisma', 'typeorm', 'drizzle'].includes(config.database.orm)) { errors.push(`Invalid ORM: ${config.database.orm}. Must be 'prisma', 'typeorm', or 'drizzle'`); } if (config.database.type && !['postgresql', 'mysql', 'sqlite'].includes(config.database.type)) { errors.push(`Invalid database type: ${config.database.type}. Must be 'postgresql', 'mysql', or 'sqlite'`); } } // Validate preferences if (config.preferences && typeof config.preferences === 'object') { const prefs = config.preferences; if (prefs.autoFormat !== undefined && typeof prefs.autoFormat !== 'boolean') { errors.push('preferences.autoFormat must be a boolean'); } if (prefs.generateTests !== undefined && typeof prefs.generateTests !== 'boolean') { errors.push('preferences.generateTests must be a boolean'); } if (prefs.skipConfirmation !== undefined && typeof prefs.skipConfirmation !== 'boolean') { errors.push('preferences.skipConfirmation must be a boolean'); } } // Validate paths config if (config.paths && typeof config.paths === 'object') { const paths = config.paths; if (paths.srcDir !== undefined && typeof paths.srcDir !== 'string') { errors.push('paths.srcDir must be a string'); } if (paths.fallbackPaths !== undefined) { if (!Array.isArray(paths.fallbackPaths)) { errors.push('paths.fallbackPaths must be an array'); } else { for (let i = 0; i < paths.fallbackPaths.length; i++) { if (typeof paths.fallbackPaths[i] !== 'string') { errors.push(`paths.fallbackPaths[${i}] must be a string`); } } } } } // Version warnings if (!config.version) { warnings.push('Config version not specified, assuming latest'); } else if (config.version !== CONFIG_VERSION) { warnings.push(`Config version ${config.version} differs from current ${CONFIG_VERSION}`); } return { isValid: errors.length === 0, errors, warnings, }; }; exports.validateConfig = validateConfig; /** * Gets the effective framework (from config, CLI option, or default) */ const getEffectiveFramework = async ({ cliFramework, configPath, } = {}) => { // CLI option takes precedence if (cliFramework && ['express', 'hono', 't3'].includes(cliFramework)) { return cliFramework; } // Then check config file const configFramework = await (0, exports.getFramework)(configPath ? { configPath } : {}); if (configFramework) { return configFramework; } // Default to express return 'express'; }; exports.getEffectiveFramework = getEffectiveFramework; /** * Gets the effective API style (from config, CLI option, or default) */ const getEffectiveApiStyle = async ({ cliApiStyle, configPath, } = {}) => { // CLI option takes precedence if (cliApiStyle && ['rest', 'trpc'].includes(cliApiStyle)) { return cliApiStyle; } // Then check config file const configApiStyle = await (0, exports.getApiStyle)(configPath ? { configPath } : {}); if (configApiStyle) { return configApiStyle; } // Default to rest return 'rest'; }; exports.getEffectiveApiStyle = getEffectiveApiStyle; //# sourceMappingURL=config.service.js.map