From c2e9747bc2d6aa7b623d72ed91fba75548b22080 Mon Sep 17 00:00:00 2001 From: ali ebrahimi Date: Mon, 14 Oct 2024 03:57:56 +0330 Subject: [PATCH 01/11] add required configs for funding pot execution to the env variables --- config/example.env | 6 +++++- src/config.ts | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/config/example.env b/config/example.env index 180044cbc..f116768b6 100644 --- a/config/example.env +++ b/config/example.env @@ -288,4 +288,8 @@ PRIVADO_VERIFIER_NETWORK_ID= PRIVADO_VERIFIER_CONTRACT_ADDRESS= PRIVADO_REQUEST_ID= -INVERTER_GRAPHQL_ENDPOINT= \ No newline at end of file +INVERTER_GRAPHQL_ENDPOINT= + +# Funding pot service variables +DELEGATE_PK_FOR_FUNDING_POT= +ANKR_API_KEY_FOR_FUNDING_POT= \ No newline at end of file diff --git a/src/config.ts b/src/config.ts index 2e7e6a98c..cc6c96cdb 100644 --- a/src/config.ts +++ b/src/config.ts @@ -51,6 +51,10 @@ const envVars = [ // 'XDAI_NODE_HTTP_URL', 'TRACE_FILE_UPLOADER_PASSWORD', 'DONATION_VERIFICAITON_EXPIRATION_HOURS', + + // funding pot variables + 'DELEGATE_PK_FOR_FUNDING_POT', + 'ANKR_API_KEY_FOR_FUNDING_POT', ]; interface requiredEnv { From 6511b969841a89ce06b932682a442ea0678df11a Mon Sep 17 00:00:00 2001 From: ali ebrahimi Date: Mon, 14 Oct 2024 04:03:19 +0330 Subject: [PATCH 02/11] refactor previous script to read the configs from common file and replace logger with console --- src/scripts/configs.ts | 19 ++++++++++++++++ src/scripts/runScript.ts | 49 +++++++++++----------------------------- 2 files changed, 32 insertions(+), 36 deletions(-) create mode 100644 src/scripts/configs.ts diff --git a/src/scripts/configs.ts b/src/scripts/configs.ts new file mode 100644 index 000000000..61a731f71 --- /dev/null +++ b/src/scripts/configs.ts @@ -0,0 +1,19 @@ +import path from 'path'; + +// Path to the local reports directory inside the repo +export const reportsDir = path.join(__dirname, 'reportFiles/output'); +// The URL of the GitHub repository containing the reports +export const repoUrl = 'https://github.com/ae2079/funding-pot.git'; +// Local directory for cloning or pulling the latest reports +export const repoLocalDir = path.join(__dirname, '/funding-pot-repo'); +// Subdirectory inside the repo where reports are located +export function getReportsSubDir() { + let reportsSubDir = 'data/'; + if (process.env.NODE_ENV !== 'production') { + reportsSubDir += 'test'; + } else { + reportsSubDir += 'production'; + } + reportsSubDir += '/output'; + return reportsSubDir; +} diff --git a/src/scripts/runScript.ts b/src/scripts/runScript.ts index 1c10fd3d4..d60683cd9 100644 --- a/src/scripts/runScript.ts +++ b/src/scripts/runScript.ts @@ -1,44 +1,20 @@ +/* eslint-disable no-console */ import path from 'path'; import fs from 'fs-extra'; -import simpleGit from 'simple-git'; import { syncDonationsWithBlockchainData } from './syncDataWithInverter'; -import { logger } from '../utils/logger'; - -// Path to the local reports directory inside the repo -const reportsDir = path.join(__dirname, 'reportFiles/output'); -// The URL of the GitHub repository containing the reports -const repoUrl = 'https://github.com/ae2079/funding-pot.git'; -// Local directory for cloning or pulling the latest reports -const repoLocalDir = path.join(__dirname, '/fonding-pot-repo'); -// Subdirectory inside the repo where reports are located -let reportsSubDir = 'data/'; -if (process.env.NODE_ENV !== 'production') { - reportsSubDir += 'test'; -} else { - reportsSubDir += 'production'; -} -reportsSubDir += '/output'; +import { repoLocalDir, reportsDir, getReportsSubDir } from './configs'; // Function to ensure directory exists or create it function ensureDirectoryExists(dirPath) { if (!fs.existsSync(dirPath)) { - logger.info(`Creating directory: ${dirPath}`); + console.info(`Creating directory: ${dirPath}`); fs.mkdirSync(dirPath, { recursive: true }); } } -// Function to pull or clone the latest reports from the GitHub repository -async function pullLatestReports() { - const git = simpleGit(); - - if (!fs.existsSync(repoLocalDir)) { - logger.info('Cloning reports repository...'); - await git.clone(repoUrl, repoLocalDir); - } else { - logger.info('Pulling latest reports from repository...'); - await git.cwd(repoLocalDir).pull(); - } - +// copy reports from output of funding pot service +async function copyReports() { + const reportsSubDir = getReportsSubDir(); // Copy the report files from the subdirectory to the output folder const reportFilesDir = path.join(repoLocalDir, reportsSubDir); ensureDirectoryExists(reportsDir); @@ -46,9 +22,9 @@ async function pullLatestReports() { if (fs.existsSync(reportFilesDir)) { fs.emptyDirSync(reportsDir); // Clear the destination folder first fs.copySync(reportFilesDir, reportsDir, { recursive: true }); // Copy recursively - logger.info('Report files copied successfully.'); + console.info('Report files copied successfully.'); } else { - logger.error( + console.error( `Subdirectory ${reportsSubDir} does not exist in the repository.`, ); } @@ -58,15 +34,16 @@ async function pullLatestReports() { async function main() { try { // Step 1: Pull the latest reports from GitHub - await pullLatestReports(); - logger.info('Reports pulled successfully.'); + console.info('Start copy report files...'); + await copyReports(); + console.info('Reports were copy successfully.'); // Step 2: Sync donations with the blockchain data await syncDonationsWithBlockchainData(); - logger.info('Data synced successfully.'); + console.info('Data synced successfully.'); process.exit(); } catch (error) { - logger.error('Error syncing data:', error); + console.error('Error syncing data:', error); process.abort(); } } From c8c9022e72d469e8390407680ec2adecd85c4dac Mon Sep 17 00:00:00 2001 From: ali ebrahimi Date: Mon, 14 Oct 2024 04:05:57 +0330 Subject: [PATCH 03/11] add a script to create all the needed things to run the funding pot service and execute it --- src/scripts/runFundingPotService.ts | 178 ++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 src/scripts/runFundingPotService.ts diff --git a/src/scripts/runFundingPotService.ts b/src/scripts/runFundingPotService.ts new file mode 100644 index 000000000..ff10ebb3b --- /dev/null +++ b/src/scripts/runFundingPotService.ts @@ -0,0 +1,178 @@ +/* eslint-disable no-console */ +import { exec } from 'child_process'; +import path from 'path'; +import fs from 'fs-extra'; +import simpleGit from 'simple-git'; +import { repoLocalDir, repoUrl } from './configs'; +import config from '../config'; +import { Project } from '../entities/project'; +import { AppDataSource } from '../orm'; + +// Attention: the configs of batches should be saved in the funding pot repo +// this script pulls the latest version of funding pot service, +// fill project details and execute it + +async function pullLatestVersionOfFundingPot() { + const git = simpleGit(); + + if (!fs.existsSync(repoLocalDir)) { + console.info('Cloning funding pot repository...'); + await git.clone(repoUrl, repoLocalDir); + } else { + console.info('Pulling latest version of funding pot service...'); + await git.cwd(repoLocalDir).pull(); + } +} + +// Helper function to convert a string to SCREAMING_SNAKE_CASE +function toScreamingSnakeCase(str: string): string { + return str + .replace(/\s+/g, '_') // Replace spaces with underscores + .replace(/[a-z]/g, letter => letter.toUpperCase()) // Convert lowercase letters to uppercase + .replace(/[^A-Z0-9_]/g, ''); // Remove non-alphanumeric characters except underscores +} + +async function fillProjectsData() { + console.info('Initialize the data source (database connection)...'); + await AppDataSource.initialize(false); + console.info('Data source initialized.'); + const datasource = AppDataSource.getDataSource(); + const projectRepository = datasource.getRepository(Project); + + const allProjects = await projectRepository.find(); + + // Prepare the projects data in the required format + const projectsData = {}; + allProjects.forEach(project => { + // Check if project has the required fields (orchestratorAddress, projectAddress, NFT) + if (project.abc) { + const screamingSnakeCaseTitle = toScreamingSnakeCase(project.title); + projectsData[screamingSnakeCaseTitle] = { + SAFE: project.abc.projectAddress || '', + ORCHESTRATOR: project.abc.orchestratorAddress || '', + NFT: project.abc.nftContractAddress || '', + }; + } else { + console.warn( + `Project ${project.id} does not have abc object. Skipping...`, + ); + } + }); + + // Define the path to the projects.json file inside funding pot repo + const filePath = path.join( + repoLocalDir, + 'data', + 'production', + 'input', + 'projects.json', + ); + + // Ensure the directory exists + await fs.ensureDir(path.dirname(filePath)); + + // Write the projects data to the projects.json file + await fs.writeJson(filePath, projectsData, { spaces: 2 }); + + console.info(`Projects data successfully written to ${filePath}`); +} + +async function createEnvFile() { + const envExamplePath = path.join(repoLocalDir, '.env.example'); // Path to .env.example in funding pot service + const envFilePath = path.join(repoLocalDir, '.env'); // Path to the new .env file in funding pot service + + if (!fs.existsSync(envExamplePath)) { + console.error(`.env.example file not found in ${envExamplePath}`); + throw new Error('.env.example file not found'); + } + + try { + const envExampleContent = await fs.readFile(envExamplePath, 'utf-8'); + + // Replace placeholders with actual values from the service's environment + const updatedEnvContent = envExampleContent + .replace( + /DELEGATE=/g, + `DELEGATE=${config.get('DELEGATE_PK_FOR_FUNDING_POT') || ''}`, + ) + .replace( + 'ANKR_API_KEY=""', + `ANKR_API_KEY="${config.get('ANKR_API_KEY_FOR_FUNDING_POT') || ''}"`, + ); + + await fs.writeFile(envFilePath, updatedEnvContent, 'utf-8'); + } catch (error) { + console.error('Error creating .env file:', error.message); + throw error; + } +} + +// Helper function to execute a shell command +function execShellCommand(command: string, workingDir: string): Promise { + return new Promise((resolve, reject) => { + console.info(`Executing command: "${command}" in ${workingDir}...`); + + exec(command, { cwd: workingDir }, (error, stdout, stderr) => { + if (error) { + console.error(`Error executing command: ${error.message}`); + return reject(error); + } + + if (stderr) { + console.error(`stderr: ${stderr}`); + return reject(new Error(stderr)); + } + + console.log(`stdout: ${stdout}`); + resolve(); + }); + }); +} + +const serviceDir = path.join(repoLocalDir); + +async function installDependencies() { + console.info(`Installing npm dependencies in ${serviceDir}...`); + await execShellCommand('npm install', serviceDir); +} + +async function runFundingPotService() { + const command = 'npm run all ' + Number(process.argv[2]); + console.info(`Running "${command}" in ${serviceDir}...`); + await execShellCommand(command, serviceDir); +} + +async function main() { + try { + // Step 1 + console.info('Start pulling latest version of funding pot service...'); + await pullLatestVersionOfFundingPot(); + console.info('Funding pot service updates successfully.'); + + // Step 2 + console.info('Installing dependencies of funding pot service...'); + await installDependencies(); + console.info('Dependencies installed.'); + + // Step 3 + console.info('Filling projects data in to the funding pot service...'); + await fillProjectsData(); + console.info('Projects data filled successfully.'); + + // Step 4 + console.info('Creating .env file for funding pot service...'); + await createEnvFile(); + console.info('Env file created successfully.'); + + // Step 5 + console.info('Running funding pot service...'); + await runFundingPotService(); + console.info('Done!'); + process.exit(); + } catch (error) { + console.error('Error in running funding pot service.', error.message); + process.exit(); + } +} + +main(); From a3a662b6fbea527f8856919e87c16e327b322c7d Mon Sep 17 00:00:00 2001 From: ali ebrahimi Date: Mon, 14 Oct 2024 04:07:30 +0330 Subject: [PATCH 04/11] add execute:inverter:production command to the package.json file --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index c9366528a..5df2f2459 100644 --- a/package.json +++ b/package.json @@ -203,7 +203,8 @@ "start:docker:locally": "npm run db:migrate:run:local && npm run dev", "postinstall": "patch-package", "sync:inverter:test": "NODE_ENV=test node ./build/src/scripts/runScript.js", - "sync:inverter:production": "NODE_ENV=production node ./build/src/scripts/runScript.js" + "sync:inverter:production": "NODE_ENV=production node ./build/src/scripts/runScript.js", + "execute:inverter:production": "NODE_ENV=production node ./build/src/scripts/runFundingPotService.js" }, "husky": { "hooks": { From 4960c869b223ba3f55fb8af2aa421fa4b01d94f1 Mon Sep 17 00:00:00 2001 From: ali ebrahimi Date: Mon, 14 Oct 2024 04:22:54 +0330 Subject: [PATCH 05/11] remove funding pot env variables from mandatory variables --- src/config.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/config.ts b/src/config.ts index cc6c96cdb..2e7e6a98c 100644 --- a/src/config.ts +++ b/src/config.ts @@ -51,10 +51,6 @@ const envVars = [ // 'XDAI_NODE_HTTP_URL', 'TRACE_FILE_UPLOADER_PASSWORD', 'DONATION_VERIFICAITON_EXPIRATION_HOURS', - - // funding pot variables - 'DELEGATE_PK_FOR_FUNDING_POT', - 'ANKR_API_KEY_FOR_FUNDING_POT', ]; interface requiredEnv { From e1f70bf7232ed0be1ec31d2636ef420940b86ff6 Mon Sep 17 00:00:00 2001 From: ali ebrahimi Date: Tue, 15 Oct 2024 04:07:43 +0330 Subject: [PATCH 06/11] change funding pot repo url to inverter repo --- src/scripts/configs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scripts/configs.ts b/src/scripts/configs.ts index 61a731f71..86f55685d 100644 --- a/src/scripts/configs.ts +++ b/src/scripts/configs.ts @@ -3,7 +3,7 @@ import path from 'path'; // Path to the local reports directory inside the repo export const reportsDir = path.join(__dirname, 'reportFiles/output'); // The URL of the GitHub repository containing the reports -export const repoUrl = 'https://github.com/ae2079/funding-pot.git'; +export const repoUrl = 'https://github.com/InverterNetwork/funding-pot.git'; // Local directory for cloning or pulling the latest reports export const repoLocalDir = path.join(__dirname, '/funding-pot-repo'); // Subdirectory inside the repo where reports are located From 2b52750e7d78e82d4f2dafab5025f41f898b4c66 Mon Sep 17 00:00:00 2001 From: ali ebrahimi Date: Tue, 15 Oct 2024 04:08:46 +0330 Subject: [PATCH 07/11] move helper functions to helper file --- src/scripts/helpers.ts | 17 +++++++++++++++++ src/scripts/runScript.ts | 9 +-------- 2 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 src/scripts/helpers.ts diff --git a/src/scripts/helpers.ts b/src/scripts/helpers.ts new file mode 100644 index 000000000..abb69a4a8 --- /dev/null +++ b/src/scripts/helpers.ts @@ -0,0 +1,17 @@ +/* eslint-disable no-console */ +import fs from 'fs-extra'; + +// Function to ensure directory exists or create it +export function ensureDirectoryExists(dirPath: string) { + if (!fs.existsSync(dirPath)) { + console.info(`Creating directory: ${dirPath}`); + fs.mkdirSync(dirPath, { recursive: true }); + } +} +// Function to convert a string to SCREAMING_SNAKE_CASE +export function toScreamingSnakeCase(str: string): string { + return str + .replace(/\s+/g, '_') // Replace spaces with underscores + .replace(/[a-z]/g, letter => letter.toUpperCase()) // Convert lowercase letters to uppercase + .replace(/[^A-Z0-9_]/g, ''); // Remove non-alphanumeric characters except underscores +} diff --git a/src/scripts/runScript.ts b/src/scripts/runScript.ts index d60683cd9..ee84df6c1 100644 --- a/src/scripts/runScript.ts +++ b/src/scripts/runScript.ts @@ -3,14 +3,7 @@ import path from 'path'; import fs from 'fs-extra'; import { syncDonationsWithBlockchainData } from './syncDataWithInverter'; import { repoLocalDir, reportsDir, getReportsSubDir } from './configs'; - -// Function to ensure directory exists or create it -function ensureDirectoryExists(dirPath) { - if (!fs.existsSync(dirPath)) { - console.info(`Creating directory: ${dirPath}`); - fs.mkdirSync(dirPath, { recursive: true }); - } -} +import { ensureDirectoryExists } from './helpers'; // copy reports from output of funding pot service async function copyReports() { From a3898b5688b6a071a852f3e7005f245f374b4793 Mon Sep 17 00:00:00 2001 From: ali ebrahimi Date: Tue, 15 Oct 2024 04:09:26 +0330 Subject: [PATCH 08/11] generate batch configs automatic based on rounds data --- src/scripts/runFundingPotService.ts | 112 +++++++++++++++++++++++++--- 1 file changed, 101 insertions(+), 11 deletions(-) diff --git a/src/scripts/runFundingPotService.ts b/src/scripts/runFundingPotService.ts index ff10ebb3b..2397d5cf6 100644 --- a/src/scripts/runFundingPotService.ts +++ b/src/scripts/runFundingPotService.ts @@ -7,6 +7,9 @@ import { repoLocalDir, repoUrl } from './configs'; import config from '../config'; import { Project } from '../entities/project'; import { AppDataSource } from '../orm'; +import { toScreamingSnakeCase, ensureDirectoryExists } from './helpers'; +import { EarlyAccessRound } from '../entities/earlyAccessRound'; +import { QfRound } from '../entities/qfRound'; // Attention: the configs of batches should be saved in the funding pot repo // this script pulls the latest version of funding pot service, @@ -24,12 +27,93 @@ async function pullLatestVersionOfFundingPot() { } } -// Helper function to convert a string to SCREAMING_SNAKE_CASE -function toScreamingSnakeCase(str: string): string { - return str - .replace(/\s+/g, '_') // Replace spaces with underscores - .replace(/[a-z]/g, letter => letter.toUpperCase()) // Convert lowercase letters to uppercase - .replace(/[^A-Z0-9_]/g, ''); // Remove non-alphanumeric characters except underscores +async function generateBatchFile(batchNumber: number) { + console.info(`Generating batch config for batch number: ${batchNumber}`); + + // Initialize the data source (database connection) + const datasource = AppDataSource.getDataSource(); + const earlyAccessRoundRepository = datasource.getRepository(EarlyAccessRound); + const qfRoundRepository = datasource.getRepository(QfRound); + + // Step 1: Check if an Early Access Round exists for the given batchNumber + let roundData: any; + let isEarlyAccess = true; // Set this to true if it's an Early Access Round by default + + roundData = await earlyAccessRoundRepository.findOne({ + where: { roundNumber: batchNumber }, + }); + + if (!roundData) { + // No Early Access Round found, fallback to QF Round + isEarlyAccess = false; + + // Step 2: Get the last Early Access Round to adjust the round number + const lastEarlyAccessRound = await earlyAccessRoundRepository + .createQueryBuilder('eaRound') + .orderBy('eaRound.roundNumber', 'DESC') + .getOne(); + + const lastEarlyAccessRoundNumber = lastEarlyAccessRound + ? lastEarlyAccessRound.roundNumber + : 0; + + // Step 3: Find the QF Round, add it to the number of the last Early Access Round + const qfRound = await qfRoundRepository.findOne({ + where: { roundNumber: batchNumber - lastEarlyAccessRoundNumber }, + }); + + // Step 4: If no QF round is found, throw an error + if (!qfRound) { + throw new Error( + `No Early Access or QF round found for batch number ${batchNumber}`, + ); + } + roundData = qfRound; + roundData.startDate = qfRound.beginDate; + } + + // Step 5: Format the data based on the round type + const batchConfig = { + TIMEFRAME: { + FROM_TIMESTAMP: Math.floor( + new Date(roundData.startDate).getTime() / 1000, + ), // Convert to timestamp + TO_TIMESTAMP: Math.floor(new Date(roundData.endDate).getTime() / 1000), + }, + VESTING_DETAILS: { + START: Math.floor(new Date(roundData?.startDate).getTime() / 1000), // todo: should add it to rounds DB or set a default value + CLIFF: 100, // Default to 100 secs + END: Math.floor(new Date(roundData.endDate).getTime() / 1000), // todo: should add it to rounds DB or set a default value + }, + LIMITS: { + INDIVIDUAL: (roundData.roundUSDCapPerUserPerProject || '5000').toString(), // Default to 5000 for individual cap + INDIVIDUAL_2: isEarlyAccess ? undefined : '250', // Only required for QACC rounds + TOTAL: (roundData.roundUSDCapPerProject || '100000').toString(), // Default to 100000 for total limit + TOTAL_2: isEarlyAccess + ? '0' + : (roundData.roundUSDCloseCapPerProject || '1050000').toString(), // Only required for QACC rounds + }, + IS_EARLY_ACCESS: isEarlyAccess, // Set based on the round type + PRICE: (roundData.tokenPrice || '0.1').toString(), // Default price to "0.1" if not provided + }; + + // Step 6: Define the path to the {batchNumber}.json file inside the funding pot repo + const batchFilePath = path.join( + repoLocalDir, + 'data', + 'production', + 'input', + 'batches', + `${batchNumber}.json`, + ); + + // Ensure the directory exists + ensureDirectoryExists(path.dirname(batchFilePath)); + + // Write the batch data to the {batchNumber}.json file + await fs.writeJson(batchFilePath, batchConfig, { spaces: 2 }); + + console.info(`Batch config successfully written to ${batchFilePath}`); } async function fillProjectsData() { @@ -69,7 +153,7 @@ async function fillProjectsData() { ); // Ensure the directory exists - await fs.ensureDir(path.dirname(filePath)); + ensureDirectoryExists(path.dirname(filePath)); // Write the projects data to the projects.json file await fs.writeJson(filePath, projectsData, { spaces: 2 }); @@ -133,17 +217,18 @@ const serviceDir = path.join(repoLocalDir); async function installDependencies() { console.info(`Installing npm dependencies in ${serviceDir}...`); - await execShellCommand('npm install', serviceDir); + await execShellCommand('npm install --loglevel=error', serviceDir); } -async function runFundingPotService() { - const command = 'npm run all ' + Number(process.argv[2]); +async function runFundingPotService(batchNumber: number) { + const command = 'npm run all ' + batchNumber; console.info(`Running "${command}" in ${serviceDir}...`); await execShellCommand(command, serviceDir); } async function main() { try { + const batchNumber = Number(process.argv[2]); // Step 1 console.info('Start pulling latest version of funding pot service...'); await pullLatestVersionOfFundingPot(); @@ -159,6 +244,11 @@ async function main() { await fillProjectsData(); console.info('Projects data filled successfully.'); + // Step 5 + console.info('Create batch config in the funding pot service...'); + await generateBatchFile(batchNumber); + console.info('Batch config created successfully.'); + // Step 4 console.info('Creating .env file for funding pot service...'); await createEnvFile(); @@ -166,7 +256,7 @@ async function main() { // Step 5 console.info('Running funding pot service...'); - await runFundingPotService(); + await runFundingPotService(batchNumber); console.info('Done!'); process.exit(); } catch (error) { From d5a52e001bf22f0f5f500e22f50c36039906b676 Mon Sep 17 00:00:00 2001 From: ali ebrahimi Date: Wed, 16 Oct 2024 02:03:32 +0330 Subject: [PATCH 09/11] use upper case and snake case from lodash --- src/scripts/helpers.ts | 7 ------- src/scripts/runFundingPotService.ts | 5 +++-- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/scripts/helpers.ts b/src/scripts/helpers.ts index abb69a4a8..fe5653089 100644 --- a/src/scripts/helpers.ts +++ b/src/scripts/helpers.ts @@ -8,10 +8,3 @@ export function ensureDirectoryExists(dirPath: string) { fs.mkdirSync(dirPath, { recursive: true }); } } -// Function to convert a string to SCREAMING_SNAKE_CASE -export function toScreamingSnakeCase(str: string): string { - return str - .replace(/\s+/g, '_') // Replace spaces with underscores - .replace(/[a-z]/g, letter => letter.toUpperCase()) // Convert lowercase letters to uppercase - .replace(/[^A-Z0-9_]/g, ''); // Remove non-alphanumeric characters except underscores -} diff --git a/src/scripts/runFundingPotService.ts b/src/scripts/runFundingPotService.ts index 2397d5cf6..7aefd2c49 100644 --- a/src/scripts/runFundingPotService.ts +++ b/src/scripts/runFundingPotService.ts @@ -1,13 +1,14 @@ /* eslint-disable no-console */ import { exec } from 'child_process'; import path from 'path'; +import _ from 'lodash'; import fs from 'fs-extra'; import simpleGit from 'simple-git'; import { repoLocalDir, repoUrl } from './configs'; import config from '../config'; import { Project } from '../entities/project'; import { AppDataSource } from '../orm'; -import { toScreamingSnakeCase, ensureDirectoryExists } from './helpers'; +import { ensureDirectoryExists } from './helpers'; import { EarlyAccessRound } from '../entities/earlyAccessRound'; import { QfRound } from '../entities/qfRound'; @@ -130,7 +131,7 @@ async function fillProjectsData() { allProjects.forEach(project => { // Check if project has the required fields (orchestratorAddress, projectAddress, NFT) if (project.abc) { - const screamingSnakeCaseTitle = toScreamingSnakeCase(project.title); + const screamingSnakeCaseTitle = _.upperCase(_.snakeCase(project.title)); projectsData[screamingSnakeCaseTitle] = { SAFE: project.abc.projectAddress || '', ORCHESTRATOR: project.abc.orchestratorAddress || '', From 1bcc6ddacd2a02181c21abbbb641cacd8ca02ed1 Mon Sep 17 00:00:00 2001 From: ali ebrahimi Date: Wed, 16 Oct 2024 02:07:38 +0330 Subject: [PATCH 10/11] fix bug --- src/scripts/runFundingPotService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scripts/runFundingPotService.ts b/src/scripts/runFundingPotService.ts index 7aefd2c49..b5d909c57 100644 --- a/src/scripts/runFundingPotService.ts +++ b/src/scripts/runFundingPotService.ts @@ -131,7 +131,7 @@ async function fillProjectsData() { allProjects.forEach(project => { // Check if project has the required fields (orchestratorAddress, projectAddress, NFT) if (project.abc) { - const screamingSnakeCaseTitle = _.upperCase(_.snakeCase(project.title)); + const screamingSnakeCaseTitle = _.snakeCase(_.upperCase(project.title)); projectsData[screamingSnakeCaseTitle] = { SAFE: project.abc.projectAddress || '', ORCHESTRATOR: project.abc.orchestratorAddress || '', From 9ee14aa87b82c29ef8414b40272b70346bab54fe Mon Sep 17 00:00:00 2001 From: ali ebrahimi Date: Wed, 16 Oct 2024 02:13:02 +0330 Subject: [PATCH 11/11] revert the changes related to use lodash --- src/scripts/helpers.ts | 7 +++++++ src/scripts/runFundingPotService.ts | 5 ++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/scripts/helpers.ts b/src/scripts/helpers.ts index fe5653089..abb69a4a8 100644 --- a/src/scripts/helpers.ts +++ b/src/scripts/helpers.ts @@ -8,3 +8,10 @@ export function ensureDirectoryExists(dirPath: string) { fs.mkdirSync(dirPath, { recursive: true }); } } +// Function to convert a string to SCREAMING_SNAKE_CASE +export function toScreamingSnakeCase(str: string): string { + return str + .replace(/\s+/g, '_') // Replace spaces with underscores + .replace(/[a-z]/g, letter => letter.toUpperCase()) // Convert lowercase letters to uppercase + .replace(/[^A-Z0-9_]/g, ''); // Remove non-alphanumeric characters except underscores +} diff --git a/src/scripts/runFundingPotService.ts b/src/scripts/runFundingPotService.ts index b5d909c57..2397d5cf6 100644 --- a/src/scripts/runFundingPotService.ts +++ b/src/scripts/runFundingPotService.ts @@ -1,14 +1,13 @@ /* eslint-disable no-console */ import { exec } from 'child_process'; import path from 'path'; -import _ from 'lodash'; import fs from 'fs-extra'; import simpleGit from 'simple-git'; import { repoLocalDir, repoUrl } from './configs'; import config from '../config'; import { Project } from '../entities/project'; import { AppDataSource } from '../orm'; -import { ensureDirectoryExists } from './helpers'; +import { toScreamingSnakeCase, ensureDirectoryExists } from './helpers'; import { EarlyAccessRound } from '../entities/earlyAccessRound'; import { QfRound } from '../entities/qfRound'; @@ -131,7 +130,7 @@ async function fillProjectsData() { allProjects.forEach(project => { // Check if project has the required fields (orchestratorAddress, projectAddress, NFT) if (project.abc) { - const screamingSnakeCaseTitle = _.snakeCase(_.upperCase(project.title)); + const screamingSnakeCaseTitle = toScreamingSnakeCase(project.title); projectsData[screamingSnakeCaseTitle] = { SAFE: project.abc.projectAddress || '', ORCHESTRATOR: project.abc.orchestratorAddress || '',