UNPKG

@lit-protocol/vincent-scaffold-sdk

Version:

Shared build configuration and utilities for Vincent abilities and policies

131 lines (112 loc) • 4.25 kB
const fs = require("fs"); const path = require("path"); const chalk = require("chalk"); const { requireVincentConfig } = require("../utils/config-utils"); const { processTemplate, getTemplateFiles, validateTemplateType, } = require("../template-loader"); // Default policy name that abilities will reference const DEFAULT_POLICY_NAME = "send-counter-limit"; /** * Create project from template */ function createProjectFromTemplate(type, directory, variables) { // Validate template type if (!validateTemplateType(type)) { throw new Error(`Invalid or incomplete template type: ${type}`); } // Check if directory already exists if (fs.existsSync(directory)) { throw new Error(`Directory already exists: ${directory}`); } try { // Create the directory fs.mkdirSync(directory, { recursive: true }); // Get all template files for this type const templateFiles = getTemplateFiles(type); // Process each template file for (const filename of templateFiles) { const content = processTemplate(type, filename, variables); const outputPath = path.join(directory, filename); // Ensure the directory exists for the file const outputDir = path.dirname(outputPath); if (!fs.existsSync(outputDir)) { fs.mkdirSync(outputDir, { recursive: true }); } // Handle JSON files (need to parse and format) if (filename.endsWith(".json")) { const jsonContent = JSON.parse(content); fs.writeFileSync(outputPath, JSON.stringify(jsonContent, null, 2)); } else { fs.writeFileSync(outputPath, content); } } } catch (error) { throw new Error(`Failed to create project: ${error.message}`); } } /** * Create a new Vincent project */ function createProject(type, name, directory) { // Load Vincent configuration const vincentConfig = requireVincentConfig(); // If directory not provided, use configured directory structure if (!directory || directory === name) { const baseDir = type === "ability" ? vincentConfig.directories.abilities : vincentConfig.directories.policies; directory = path.resolve(baseDir, name); } console.log(chalk.cyan(`\nšŸ“ Creating ${type} "${name}"...\n`)); try { // Template variables with configuration const prefix = type === "ability" ? vincentConfig.package.abilityPrefix : vincentConfig.package.policyPrefix; const packageName = `${vincentConfig.package.namespace}/${prefix}${name}`; const variables = { name: name, type: type, namespace: vincentConfig.package.namespace, packageName: packageName, camelCaseName: name.replace(/-([a-z])/g, (g) => g[1].toUpperCase()), }; // For abilities, add the default policy package name and description if (type === "ability") { const policyPrefix = vincentConfig.package.policyPrefix; const policyPackageName = `${vincentConfig.package.namespace}/${policyPrefix}${DEFAULT_POLICY_NAME}`; variables.policyPackageName = policyPackageName; variables.abilityDescription = `A ${name.replace(/-/g, ' ')} ability that provides functionality for ${name.replace(/-/g, ' ')} operations`; } // Use the shared template creation function createProjectFromTemplate(type, directory, variables); // Get template files for logging const templateFiles = getTemplateFiles(type); for (const filename of templateFiles) { console.log(chalk.green(`āœ“ Created ${filename}`)); } console.log( chalk.green.bold(`\nāœ… Successfully created Vincent ${type}: ${name}`) ); console.log(chalk.cyan(`šŸ“ Location: ${directory}`)); console.log(chalk.yellow(`\nšŸ“‹ Next steps:`)); console.log(chalk.gray(` cd ${path.relative(process.cwd(), directory)}`)); console.log(chalk.gray(` npm install`)); console.log(chalk.gray(` # Start developing your ${type}!`)); } catch (error) { // Clean up on error if (fs.existsSync(directory)) { fs.rmSync(directory, { recursive: true, force: true }); } console.error(chalk.red(`\nāŒ Failed to create project: ${error.message}`)); process.exit(1); } } module.exports = { createProject, };