typescript-scaffolder
Version:
 
99 lines (96 loc) • 4.68 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateFactoriesFromFile = generateFactoriesFromFile;
exports.generateFactoriesFromPath = generateFactoriesFromPath;
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
const logger_1 = require("../utils/logger");
const file_system_1 = require("../utils/file-system");
const interface_parser_1 = require("../utils/interface-parser");
const mock_value_resolver_1 = require("../utils/mocking/mock-value-resolver");
/**
* Generate a factory class file from a single interface file.
* @param filePath - absolute path to the input interface file
* @param relativePath - relative path (used to mirror directory structure)
* @param outputBaseDir - root output directory for generated factories
* @param useFakerDefaults - whether to use faker-based mocks
*/
async function generateFactoriesFromFile(filePath, relativePath, outputBaseDir, useFakerDefaults = false) {
const funcName = "generateFactoriesFromFile";
logger_1.Logger.debug(funcName, `Generating files for ${filePath}`);
try {
const interfaceName = path_1.default.basename(filePath, path_1.default.extname(filePath));
const outputDir = path_1.default.join(outputBaseDir, path_1.default.dirname(relativePath));
const outputFile = path_1.default.join(outputDir, `${interfaceName}Factory.ts`);
await fs_extra_1.default.ensureDir(outputDir);
const interfaces = (0, interface_parser_1.extractInterfacesFromFile)(filePath);
logger_1.Logger.debug(`Parsed ${interfaces.length} interfaces from ${filePath}`);
const importPath = path_1.default
.relative(outputDir, path_1.default.dirname(filePath))
.replace(/\\/g, "/")
.replace(/\.ts$/, "");
const importName = interfaces.map((iface) => iface.name).join(", ");
const importStatement = `import { ${importName} } from "${importPath}/${interfaceName}";\n\n`;
const localInterfaces = new Set(interfaces.map((i) => i.name));
const factoryBlocks = interfaces.map((iface) => {
const defaults = iface.properties
.map(({ name, type }) => ` ${name}: ${(0, mock_value_resolver_1.getMockValueForProperty)(name, type, localInterfaces, useFakerDefaults)},`)
.join("\n");
return `// Auto-generated factory for ${iface.name}
export class ${iface.name}Factory {
/**
* Builds a new ${iface.name} object with default values and optional overrides.
* This method only constructs the object — it does not persist or extend behavior.
*/
static build(overrides: Partial<${iface.name}> = {}): ${iface.name} {
return {
${defaults}
...overrides
};
}
/**
* Creates a new ${iface.name} instance by delegating to build().
* Can be extended in subclasses to introduce side effects or persistence.
*/
static create(overrides: Partial<${iface.name}> = {}): ${iface.name} {
return this.build(overrides);
}
/**
* Generates an array of mock ${iface.name} instances.
* @param count - number of items to generate
* @param overrides - optional overrides applied to each item
*/
static mockList(count = 3, overrides: Partial<${iface.name}> = {}): ${iface.name}[] {
return Array.from({ length: count }, () => this.create(overrides));
}
}
`;
}).join("\n\n");
const content = importStatement + factoryBlocks;
await fs_extra_1.default.writeFile(outputFile, content, "utf-8");
logger_1.Logger.debug(`Generated factory: ${outputFile}`);
}
catch (error) {
logger_1.Logger.error("Error generating factory from file:", error);
throw error;
}
}
/**
* Generate factory class files for all interfaces in a directory.
* Mirrors directory structure using walkDirectory.
*/
async function generateFactoriesFromPath(inputDir, outputDir, ext = ".ts", useFakerDefaults = false) {
const funcName = 'generateFactoriesFromPath';
logger_1.Logger.debug(funcName, `Walking directory for factories: ${inputDir}`);
(0, file_system_1.ensureDir)(outputDir);
const tasks = [];
(0, file_system_1.walkDirectory)(inputDir, (filePath, relativePath) => {
const task = generateFactoriesFromFile(filePath, relativePath, outputDir, useFakerDefaults);
tasks.push(task);
}, ext);
await Promise.all(tasks);
logger_1.Logger.debug(funcName, `Factory generation complete. Output root: ${outputDir}`);
}