@patchworkdev/pdk
Version:
Patchwork Development Kit
151 lines (150 loc) • 7.25 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CLIProcessor = void 0;
const common_1 = require("@patchworkdev/common");
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const project_1 = require("../helpers/project");
class CLIProcessor {
contractSchema;
projectSchema;
constructor(contractSchema, projectSchema) {
this.contractSchema = contractSchema;
this.projectSchema = projectSchema;
}
generateSolidity(config, outputDir = process.cwd(), contract) {
//console.log('Generating Solidity files...');
const _config = this.setProjectConfigDefaults(config);
this.generateProjectContracts(_config, contract, outputDir);
}
generateProjectContracts(config, contract, outputDir) {
if (contract) {
const contractConfig = config.contracts[contract];
if (!contractConfig) {
console.error(`Contract '${contract}' not found in the project config.`);
throw new Error(`Contract '${contract}' not found in the project config.`);
}
this.generateContract(new common_1.ContractSchemaImpl(contractConfig), outputDir);
}
else {
const fullProjectConfig = this.loadFullProjectConfig(config);
Object.values(fullProjectConfig.contracts).forEach((value) => {
this.generateContract(value, outputDir);
});
}
}
/**
* Loads the full project configuration by resolving and loading all contract configurations
* referenced in the given project configuration.
*
* @param projectConfig - The initial project configuration containing contract references or full contracts
* @param configFile - The path to the original project config file - needed to find relative contract config paths.
* @returns The full project configuration with all contract configurations loaded.
*/
loadFullProjectConfig(project) {
const fullProjectConfig = { ...project };
Object.entries(project.contracts).forEach(([key, value]) => {
fullProjectConfig.contracts[key] = new common_1.ContractSchemaImpl(value);
});
return fullProjectConfig;
}
generateContract(schema, outputDir) {
try {
schema.validate();
const solidityGenFilename = (0, common_1.cleanAndCapitalizeFirstLetter)(schema.name) + 'Generated.sol';
const solidityUserFilename = (0, common_1.cleanAndCapitalizeFirstLetter)(schema.name) + '.sol';
const jsonFilename = (0, common_1.cleanAndCapitalizeFirstLetter)(schema.name) + '-schema.json';
const solidityCode = new common_1.MainContractGen().gen(schema);
const solidityUserCode = new common_1.UserContractGen().gen(schema);
const jsonSchema = new common_1.JSONSchemaGen().gen(schema);
let outputPath = path_1.default.join(outputDir, solidityGenFilename);
// TODO check the path to make sure it's not a file instead of a writeable directory
// console.log("trying to write to", outputPath);
fs_1.default.writeFileSync(outputPath, solidityCode);
//console.log(`Solidity gen file generated at ${outputPath}`);
outputPath = path_1.default.join(outputDir, solidityUserFilename);
if (fs_1.default.existsSync(outputPath)) {
//console.log(`Output file ${outputPath} already exists. Skipping overwrite.`);
}
else {
fs_1.default.writeFileSync(outputPath, solidityUserCode);
//console.log(`Solidity user file generated at ${outputPath}`);
}
outputPath = path_1.default.join(outputDir, jsonFilename);
fs_1.default.writeFileSync(outputPath, jsonSchema);
//console.log(`JSON Schema file generated at ${outputPath}`);
}
catch (err) {
console.error('Error:', err.message);
throw new Error('Error generating contract');
}
}
generateDeployScripts(config, contractsDir, outputDir = process.cwd()) {
const _config = this.setProjectConfigDefaults(config);
const projectConfig = this.loadFullProjectConfig(_config);
try {
// TODO hack b/c the deploy script generator is in common and doesn't know about the PDK project stuff
const deployScriptCode = new common_1.DeployScriptGen().gen((0, project_1.exportProjectConfig)(projectConfig), contractsDir);
const deployerFilename = (0, common_1.cleanAndCapitalizeFirstLetter)(projectConfig.name) + '-deploy.s.sol';
let outputPath = path_1.default.join(outputDir, deployerFilename);
fs_1.default.writeFileSync(outputPath, deployScriptCode);
//console.log(`Deploy script generated at ${outputPath}`);
}
catch (err) {
console.error('Error:', err.message);
throw new Error('Error generating deploy script');
}
}
async buildContracts(targetDir = process.cwd()) {
try {
const { oraPromise } = await import('ora');
const { execa } = await import('execa');
await oraPromise(execa('forge', ['build', '--extra-output-files', 'abi', '--force'], {
cwd: targetDir,
}), {
text: `Building contracts`,
failText: 'Failed to build contracts',
successText: `Contracts built successfully`,
});
}
catch (err) {
console.error('Error:', err.message);
throw new Error('Error building contracts');
}
}
isPDKRepo(rootDir) {
// walk up the directory tree to find package.json and see if the package is packworkdev/common
let currentDir = rootDir;
while (currentDir !== '/') {
// console.log("Checking", currentDir);
if (fs_1.default.existsSync(path_1.default.join(currentDir, 'package.json'))) {
const packageJson = JSON.parse(fs_1.default.readFileSync(path_1.default.join(currentDir, 'package.json'), 'utf8'));
if (packageJson.name === '@patchworkdev/pdkmonorepo') {
return currentDir;
}
}
currentDir = path_1.default.resolve(currentDir, '..');
}
return undefined;
}
// Set default values for project config
setProjectConfigDefaults(projectConfig) {
const projectConfigCopy = { ...projectConfig };
Object.entries(projectConfigCopy.scopes).forEach(([key, value]) => {
if (value.whitelist === undefined) {
value.whitelist = true;
}
if (value.userAssign === undefined) {
value.userAssign = false;
}
if (value.userPatch === undefined) {
value.userPatch = false;
}
});
return projectConfigCopy;
}
}
exports.CLIProcessor = CLIProcessor;