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
JavaScript
;
/**
* 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