Add Activepieces integration for workflow automation
- Add Activepieces fork with SmoothSchedule custom piece - Create integrations app with Activepieces service layer - Add embed token endpoint for iframe integration - Create Automations page with embedded workflow builder - Add sidebar visibility fix for embed mode - Add list inactive customers endpoint to Public API - Include SmoothSchedule triggers: event created/updated/cancelled - Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
218
activepieces-fork/tools/scripts/pieces/bump-translated-pieces.ts
Normal file
218
activepieces-fork/tools/scripts/pieces/bump-translated-pieces.ts
Normal file
@@ -0,0 +1,218 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { execSync } from 'child_process';
|
||||
|
||||
interface PackageJson {
|
||||
name: string;
|
||||
version: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
interface UpdateResult {
|
||||
success: boolean;
|
||||
oldVersion?: string;
|
||||
newVersion?: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
// Function to bump patch version
|
||||
function bumpPatchVersion(version: string): string {
|
||||
const parts = version.split('.');
|
||||
if (parts.length >= 3) {
|
||||
const patch = parseInt(parts[2]) + 1;
|
||||
return `${parts[0]}.${parts[1]}.${patch}`;
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
// Function to update package.json
|
||||
function updatePackageJson(packageJsonPath: string): UpdateResult {
|
||||
try {
|
||||
const content = fs.readFileSync(packageJsonPath, 'utf8');
|
||||
const packageJson: PackageJson = JSON.parse(content);
|
||||
|
||||
if (packageJson.version) {
|
||||
const oldVersion = packageJson.version;
|
||||
const newVersion = bumpPatchVersion(oldVersion);
|
||||
|
||||
console.log(`Bumping ${path.basename(path.dirname(packageJsonPath))}: ${oldVersion} -> ${newVersion}`);
|
||||
|
||||
packageJson.version = newVersion;
|
||||
|
||||
// Write back to file with proper formatting
|
||||
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
|
||||
|
||||
return { success: true, oldVersion, newVersion };
|
||||
}
|
||||
|
||||
return { success: false, error: 'No version field found in package.json' };
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
||||
console.error(`Error updating ${packageJsonPath}:`, errorMessage);
|
||||
return { success: false, error: errorMessage };
|
||||
}
|
||||
}
|
||||
|
||||
// Function to check if a piece has changes compared to main
|
||||
function hasChangesComparedToMain(piecePath: string): boolean {
|
||||
try {
|
||||
// Check if there are any changes in the piece directory compared to main
|
||||
execSync(`git diff --quiet origin/main -- ${piecePath}`, { encoding: 'utf8' });
|
||||
return false; // No changes
|
||||
} catch (error) {
|
||||
if (error instanceof Error && 'status' in error && error.status === 1) {
|
||||
return true; // Has changes
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Function to check if a piece has i18n directory
|
||||
function hasI18nDirectory(piecePath: string): boolean {
|
||||
const i18nPath = path.join(piecePath, 'src', 'i18n');
|
||||
return fs.existsSync(i18nPath) && fs.statSync(i18nPath).isDirectory();
|
||||
}
|
||||
|
||||
// Function to check if a piece has translation-related changes
|
||||
function hasTranslationChanges(piecePath: string): boolean {
|
||||
try {
|
||||
// Check if there are changes in the i18n directory
|
||||
const i18nChanges = execSync(`git diff --name-only origin/main -- ${piecePath}/src/i18n`, { encoding: 'utf8' }).trim();
|
||||
return i18nChanges.length > 0;
|
||||
} catch (error) {
|
||||
if (error instanceof Error && 'status' in error && error.status === 1) {
|
||||
return true; // Has changes
|
||||
}
|
||||
return false; // No changes or error
|
||||
}
|
||||
}
|
||||
|
||||
// Function to check if a piece version has already been bumped compared to main
|
||||
function hasVersionBeenBumped(piecePath: string): boolean {
|
||||
try {
|
||||
const packageJsonPath = path.join(piecePath, 'package.json');
|
||||
if (!fs.existsSync(packageJsonPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get current version
|
||||
const content = fs.readFileSync(packageJsonPath, 'utf8');
|
||||
const packageJson: PackageJson = JSON.parse(content);
|
||||
const currentVersion = packageJson.version;
|
||||
|
||||
if (!currentVersion) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get version from main branch
|
||||
const mainVersion = execSync(`git show origin/main:${packageJsonPath}`, { encoding: 'utf8' });
|
||||
const mainPackageJson: PackageJson = JSON.parse(mainVersion);
|
||||
const mainBranchVersion = mainPackageJson.version;
|
||||
|
||||
// Compare versions - if current version is higher than main, it's already been bumped
|
||||
return compareVersions(currentVersion, mainBranchVersion) > 0;
|
||||
} catch (error) {
|
||||
// If we can't get the main version (e.g., file doesn't exist on main), assume not bumped
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to compare semantic versions
|
||||
function compareVersions(version1: string, version2: string): number {
|
||||
const v1Parts = version1.split('.').map(Number);
|
||||
const v2Parts = version2.split('.').map(Number);
|
||||
|
||||
for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
|
||||
const v1Part = v1Parts[i] || 0;
|
||||
const v2Part = v2Parts[i] || 0;
|
||||
|
||||
if (v1Part > v2Part) return 1;
|
||||
if (v1Part < v2Part) return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Function to get all piece directories
|
||||
function getPieceDirectories(piecesDir: string): string[] {
|
||||
return fs.readdirSync(piecesDir)
|
||||
.filter(item => {
|
||||
const fullPath = path.join(piecesDir, item);
|
||||
return fs.statSync(fullPath).isDirectory();
|
||||
});
|
||||
}
|
||||
|
||||
// Main function
|
||||
function main(): void {
|
||||
console.log('Finding pieces with translation changes compared to main...');
|
||||
|
||||
const piecesWithChanges: string[] = [];
|
||||
const piecesDir = 'packages/pieces/community';
|
||||
|
||||
// Get all piece directories
|
||||
const pieceDirs = getPieceDirectories(piecesDir);
|
||||
|
||||
console.log(`Checking ${pieceDirs.length} pieces for changes...`);
|
||||
|
||||
for (const piece of pieceDirs) {
|
||||
const piecePath = path.join(piecesDir, piece);
|
||||
// Check if piece has changes compared to main
|
||||
if (hasChangesComparedToMain(piecePath)) {
|
||||
// Check if it has i18n directory (indicating translations were added)
|
||||
if (hasI18nDirectory(piecePath)) {
|
||||
// Check if the changes are translation-related
|
||||
if (hasTranslationChanges(piecePath)) {
|
||||
// Check if version has already been bumped
|
||||
if (hasVersionBeenBumped(piecePath)) {
|
||||
console.log(` - ${piece} - has translation changes but version already bumped`);
|
||||
} else {
|
||||
piecesWithChanges.push(piece);
|
||||
console.log(` ✓ ${piece} - has translation changes and needs version bump`);
|
||||
}
|
||||
} else {
|
||||
console.log(` - ${piece} - has changes but not translation-related`);
|
||||
}
|
||||
} else {
|
||||
console.log(` - ${piece} - has changes but no i18n directory`);
|
||||
}
|
||||
} else {
|
||||
console.log(` - ${piece} - no changes`);
|
||||
}
|
||||
}
|
||||
|
||||
if (piecesWithChanges.length === 0) {
|
||||
console.log('\nNo pieces with translation changes found.');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`\nFound ${piecesWithChanges.length} pieces with translation changes:`);
|
||||
piecesWithChanges.forEach(piece => console.log(` - ${piece}`));
|
||||
|
||||
console.log('\nBumping patch versions...');
|
||||
|
||||
let successCount = 0;
|
||||
let errorCount = 0;
|
||||
|
||||
for (const piece of piecesWithChanges) {
|
||||
const packageJsonPath = path.join(piecesDir, piece, 'package.json');
|
||||
|
||||
if (fs.existsSync(packageJsonPath)) {
|
||||
const result = updatePackageJson(packageJsonPath);
|
||||
if (result.success) {
|
||||
successCount++;
|
||||
} else {
|
||||
errorCount++;
|
||||
}
|
||||
} else {
|
||||
console.error(`Package.json not found for ${piece}`);
|
||||
errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\nSummary:`);
|
||||
console.log(` Successfully updated: ${successCount} pieces`);
|
||||
console.log(` Errors: ${errorCount} pieces`);
|
||||
}
|
||||
|
||||
// Run the script
|
||||
main();
|
||||
50
activepieces-fork/tools/scripts/pieces/publish-piece.ts
Normal file
50
activepieces-fork/tools/scripts/pieces/publish-piece.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import assert from 'node:assert'
|
||||
import { argv } from 'node:process'
|
||||
import { exec } from '../utils/exec'
|
||||
import { readPackageJson, readProjectJson } from '../utils/files'
|
||||
import { findAllPiecesDirectoryInSource } from '../utils/piece-script-utils'
|
||||
import { isNil } from '@activepieces/shared'
|
||||
import chalk from 'chalk'
|
||||
import path from 'node:path'
|
||||
|
||||
export const publishPiece = async (name: string): Promise<void> => {
|
||||
assert(name, '[publishPiece] parameter "name" is required')
|
||||
|
||||
const distPaths = await findAllPiecesDirectoryInSource()
|
||||
const directory = distPaths.find(p => path.basename(p) === name)
|
||||
if (isNil(directory)) {
|
||||
console.error(chalk.red(`[publishPiece] can't find the directory with name ${name}`))
|
||||
return
|
||||
}
|
||||
const { version } = await readPackageJson(directory)
|
||||
const { name: nxProjectName } = await readProjectJson(directory)
|
||||
|
||||
await exec(`npx nx build ${nxProjectName}`)
|
||||
|
||||
|
||||
const nxPublishProjectCommand = `
|
||||
node tools/scripts/publish.mjs \
|
||||
${nxProjectName} \
|
||||
${version} \
|
||||
latest
|
||||
`
|
||||
|
||||
|
||||
await exec(nxPublishProjectCommand)
|
||||
|
||||
console.info(chalk.green.bold(`[publishPiece] success, name=${name}, version=${version}`))
|
||||
|
||||
}
|
||||
|
||||
const main = async (): Promise<void> => {
|
||||
const pieceName = argv[2]
|
||||
await publishPiece(pieceName)
|
||||
}
|
||||
|
||||
/*
|
||||
* module is entrypoint, not imported i.e. invoked directly
|
||||
* see https://nodejs.org/api/modules.html#modules_accessing_the_main_module
|
||||
*/
|
||||
if (require.main === module) {
|
||||
main()
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { publishNxProject } from '../utils/publish-nx-project'
|
||||
import { findAllPiecesDirectoryInSource } from '../utils/piece-script-utils'
|
||||
import { chunk } from '../../../packages/shared/src/lib/common/utils/utils'
|
||||
|
||||
const publishPiece = async (nxProjectPath: string): Promise<void> => {
|
||||
console.info(`[publishPiece] nxProjectPath=${nxProjectPath}`)
|
||||
await publishNxProject(nxProjectPath)
|
||||
}
|
||||
|
||||
const main = async () => {
|
||||
const piecesSource = await findAllPiecesDirectoryInSource()
|
||||
const piecesSourceChunks = chunk(piecesSource, 30)
|
||||
|
||||
for (const chunk of piecesSourceChunks) {
|
||||
await Promise.all(chunk.map(publishPiece))
|
||||
await new Promise(resolve => setTimeout(resolve, 5000))
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
||||
492
activepieces-fork/tools/scripts/pieces/update-authors.ts
Normal file
492
activepieces-fork/tools/scripts/pieces/update-authors.ts
Normal file
@@ -0,0 +1,492 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { execSync } from 'child_process';
|
||||
import semVer from 'semver';
|
||||
|
||||
const contributors = [
|
||||
{
|
||||
"name": "Kishan Parmar",
|
||||
"login": "kishanprmr"
|
||||
},
|
||||
{
|
||||
"name": "Mohammad AbuAboud",
|
||||
"login": "abuaboud"
|
||||
},
|
||||
{
|
||||
"name": "Damien HEBERT",
|
||||
"login": "doskyft"
|
||||
},
|
||||
{
|
||||
"name": "AbdulTheActivePiecer",
|
||||
"login": "AbdulTheActivePiecer"
|
||||
},
|
||||
{
|
||||
"name": "Moayyad Shaddad",
|
||||
"login": "MoShizzle"
|
||||
},
|
||||
{
|
||||
"name": "TaskMagicKyle",
|
||||
"login": "TaskMagicKyle"
|
||||
},
|
||||
{
|
||||
"name": "kylebuilds",
|
||||
"login": "TaskMagicKyle"
|
||||
},
|
||||
{
|
||||
"name": "Salem-Alaa",
|
||||
"login": "Salem-Alaa"
|
||||
},
|
||||
{
|
||||
"name": "Khaled Mashaly",
|
||||
"login": "khaledmashaly"
|
||||
},
|
||||
{
|
||||
"name": "abuaboud",
|
||||
"login": "abuaboud"
|
||||
},
|
||||
{
|
||||
"name": "Mohammed Abu Aboud",
|
||||
"login": "abuaboud"
|
||||
},
|
||||
{
|
||||
"name": "Mukewa O. Wekalao",
|
||||
"login": "kanarelo"
|
||||
},
|
||||
{
|
||||
"name": "Willian",
|
||||
"login": "Willianwg"
|
||||
},
|
||||
{
|
||||
"name": "Aler Denisov",
|
||||
"login": "alerdenisov"
|
||||
},
|
||||
{
|
||||
"name": "Abdallah-Alwarawreh",
|
||||
"login": "Abdallah-Alwarawreh"
|
||||
},
|
||||
{
|
||||
"name": "Shay Punter",
|
||||
"login": "ShayPunter"
|
||||
},
|
||||
{
|
||||
"name": "i-nithin",
|
||||
"login": "i-nithin"
|
||||
},
|
||||
{
|
||||
"name": "Joe Workman",
|
||||
"login": "joeworkman"
|
||||
},
|
||||
{
|
||||
"name": "ShayPunter",
|
||||
"login": "ShayPunter"
|
||||
},
|
||||
{
|
||||
"name": "Vraj Gohil",
|
||||
"login": "VrajGohil"
|
||||
},
|
||||
{
|
||||
"name": "Matthew Zeiler",
|
||||
"login": "zeiler"
|
||||
},
|
||||
{
|
||||
"name": "Alexandros Katechis",
|
||||
"login": "akatechis"
|
||||
},
|
||||
{
|
||||
"name": "JanHolger",
|
||||
"login": "JanHolger"
|
||||
},
|
||||
{
|
||||
"name": "Andrei Chirko",
|
||||
"login": "andchir"
|
||||
},
|
||||
{
|
||||
"name": "Landon Moir",
|
||||
"login": "landonmoir"
|
||||
},
|
||||
{
|
||||
"name": "bibhuty-did-this",
|
||||
"login": "bibhuty-did-this"
|
||||
},
|
||||
{
|
||||
"name": "Cyril Selasi",
|
||||
"login": "cyrilselasi"
|
||||
},
|
||||
{
|
||||
"name": "Gunther Schulz",
|
||||
"login": "Gunther-Schulz"
|
||||
},
|
||||
{
|
||||
"name": "Osama Zakarneh",
|
||||
"login": "Ozak93"
|
||||
},
|
||||
{
|
||||
"name": "Owlcept",
|
||||
"login": "Owlcept"
|
||||
},
|
||||
{
|
||||
"name": "Drew Lewis",
|
||||
"login": "Owlcept"
|
||||
},
|
||||
{
|
||||
"name": "AbdullahBitar",
|
||||
"login": "AbdullahBitar"
|
||||
},
|
||||
{
|
||||
"name": "Mohammad Abuaboud",
|
||||
"login": "abuaboud"
|
||||
},
|
||||
{
|
||||
"name": "BBND",
|
||||
"login": "BBND"
|
||||
},
|
||||
{
|
||||
"name": "Nilesh",
|
||||
"login": "Nilesh"
|
||||
},
|
||||
{
|
||||
"name": "Karim Khaleel",
|
||||
"login": "karimkhaleel"
|
||||
},
|
||||
{
|
||||
"name": "[NULL] Dev",
|
||||
"login": "Abdallah-Alwarawreh"
|
||||
},
|
||||
{
|
||||
"name": "Pablo Fernandez",
|
||||
"login": "pfernandez98"
|
||||
},
|
||||
{
|
||||
"name": "BastienMe",
|
||||
"login": "BastienMe"
|
||||
},
|
||||
{
|
||||
"name": "Olivier Sambourg",
|
||||
"login": "AdamSelene"
|
||||
},
|
||||
{
|
||||
"name": "MoShizzle",
|
||||
"login": "MoShizzle"
|
||||
},
|
||||
{
|
||||
"name": "Aasim Sani",
|
||||
"login": "aasimsani"
|
||||
},
|
||||
{
|
||||
"name": "Abdul-rahman Yasir Khalil",
|
||||
"login": "AbdulTheActivePiecer"
|
||||
},
|
||||
{
|
||||
"name": "awais",
|
||||
"login": "awais"
|
||||
},
|
||||
{
|
||||
"name": "Lisander Lopez",
|
||||
"login": "lisander-lopez"
|
||||
},
|
||||
{
|
||||
"name": "OsamaHaikal",
|
||||
"login": "OsamaHaikal"
|
||||
},
|
||||
{
|
||||
"name": "Maher",
|
||||
"login": "abaza738"
|
||||
},
|
||||
{
|
||||
"name": "Maher Abaza",
|
||||
"login": "abaza738"
|
||||
},
|
||||
{
|
||||
"name": "Mukewa Wekalao",
|
||||
"login": "kanarelo"
|
||||
},
|
||||
{
|
||||
"name": "Mark van Bellen",
|
||||
"login": "buttonsbond"
|
||||
},
|
||||
{
|
||||
"name": "Denis Gurskij",
|
||||
"login": "DGurskij"
|
||||
},
|
||||
{
|
||||
"name": "Thibaut Patel",
|
||||
"login": "tpatel"
|
||||
},
|
||||
{
|
||||
"name": "Bastien Meffre",
|
||||
"login": "BastienMe"
|
||||
},
|
||||
{
|
||||
"name": "Abdullah Ranginwala",
|
||||
"login": "abdullahranginwala"
|
||||
},
|
||||
{
|
||||
"name": "pfernandez98",
|
||||
"login": "pfernandez98"
|
||||
},
|
||||
{
|
||||
"name": "Vitali Borovi",
|
||||
"login": "Vitalini"
|
||||
},
|
||||
{
|
||||
"name": "Vitali Borovik",
|
||||
"login": "Vitalini"
|
||||
},
|
||||
{
|
||||
"name": "Vitalik Borovik",
|
||||
"login": "Vitalini"
|
||||
},
|
||||
{
|
||||
"name": "Armand Giauffret 4",
|
||||
"login": "ArmanGiau3"
|
||||
},
|
||||
{
|
||||
"name": "Armand Giauffret 3",
|
||||
"login": "ArmanGiau3"
|
||||
},
|
||||
{
|
||||
"name": "Salem Alwarawreh",
|
||||
"login": "Salem-Alaa"
|
||||
},
|
||||
{
|
||||
"name": "MyWay",
|
||||
"login": "MyWay"
|
||||
},
|
||||
{
|
||||
"name": "leenmashni",
|
||||
"login": "leenmashni"
|
||||
},
|
||||
{
|
||||
"name": "Fábio Ferreira",
|
||||
"login": "facferreira"
|
||||
},
|
||||
{
|
||||
"name": "Diego Nijboer",
|
||||
"login": "lldiegon"
|
||||
},
|
||||
{
|
||||
"name": "Enrike Nur",
|
||||
"login": "w95"
|
||||
},
|
||||
{
|
||||
"name": "Haithem BOUJRIDA",
|
||||
"login": "hkboujrida"
|
||||
},
|
||||
{
|
||||
"name": "Willian Guedes",
|
||||
"login": "Willianwg"
|
||||
},
|
||||
{
|
||||
"name": "Daniel Ostapenko",
|
||||
"login": "denieler"
|
||||
},
|
||||
{
|
||||
"name": "Yann Petitjean",
|
||||
"login": "yann120"
|
||||
},
|
||||
{
|
||||
"name": "Lawrence Li",
|
||||
"login": "la3rence"
|
||||
},
|
||||
{
|
||||
"name": "Mario Meyer",
|
||||
"login": "mariomeyer"
|
||||
},
|
||||
{
|
||||
"name": "aboudzein",
|
||||
"login": "aboudzein",
|
||||
},
|
||||
{
|
||||
"name": "aboudzeineddin",
|
||||
"login": "aboudzein",
|
||||
},
|
||||
{
|
||||
"name": "Alexander Storozhevsky",
|
||||
"login": "astorozhevsky"
|
||||
},
|
||||
{
|
||||
"name": "dentych",
|
||||
"login": "dentych"
|
||||
},
|
||||
{
|
||||
"name": "Matt Lung",
|
||||
"login": "Vitalini"
|
||||
},
|
||||
{
|
||||
"name": "joselupianez",
|
||||
"login": "joselupianez"
|
||||
},
|
||||
{
|
||||
"name": "Hoang Duc Tan",
|
||||
"login": "tanoggy"
|
||||
},
|
||||
{
|
||||
"name": "Herman Kudria",
|
||||
"login": "HKudria"
|
||||
},
|
||||
{
|
||||
"name": "Ahmad Ghosheh",
|
||||
"login": "BLaidzX"
|
||||
},
|
||||
{
|
||||
"name": "Ben",
|
||||
"login": "bendersej"
|
||||
},
|
||||
{
|
||||
"name": "Rita Gorokhod",
|
||||
"login": "rita-gorokhod"
|
||||
},
|
||||
{
|
||||
name: "Dennis Rongo",
|
||||
login: "dennisrongo"
|
||||
},
|
||||
{
|
||||
"name": "x7airworker",
|
||||
"login": "x7airworker"
|
||||
},
|
||||
{
|
||||
"name": "Camilo Usuga",
|
||||
"login": "camilou"
|
||||
},
|
||||
{
|
||||
"name": "Fardeen Panjwani",
|
||||
"login": "fardeenpanjwani-codeglo"
|
||||
},
|
||||
{
|
||||
"name": "Tân Một Nắng",
|
||||
"login": "tanoggy"
|
||||
},
|
||||
{
|
||||
"name": "ashrafsamhouri",
|
||||
"login": "ashrafsamhouri"
|
||||
},
|
||||
{
|
||||
"name": "Ahmad-AbuOsbeh",
|
||||
"login": "Ahmad-AbuOsbeh"
|
||||
},
|
||||
{
|
||||
"name": "Fastkop",
|
||||
"login": "abuaboud"
|
||||
},
|
||||
{
|
||||
"name": "Abdul",
|
||||
"login": "AbdulTheActivePiecer"
|
||||
},
|
||||
{
|
||||
"name": "ahmad jaber",
|
||||
"login": "creed983",
|
||||
},
|
||||
{
|
||||
"name": "creed983",
|
||||
"login": "creed983",
|
||||
},
|
||||
{
|
||||
"name": "Activepieces Dev",
|
||||
"login": "ashrafsamhouri"
|
||||
},
|
||||
{
|
||||
"name": "hiasat",
|
||||
"login": "abuaboud"
|
||||
},
|
||||
{
|
||||
"name": "Mohammad",
|
||||
"login": "abuaboud"
|
||||
},
|
||||
{
|
||||
"name": "ActivePieces",
|
||||
"login": "abuaboud"
|
||||
},
|
||||
{
|
||||
"name": "haseebrehmanpc",
|
||||
"login": "haseebrehmanpc"
|
||||
},
|
||||
{
|
||||
"name": "Haseeb Rehman",
|
||||
"login": "haseebrehmanpc"
|
||||
}
|
||||
]
|
||||
|
||||
function cleanAuthors(authors: string[]) {
|
||||
const cleanedAuthors: string[] = []
|
||||
authors.forEach(author => {
|
||||
const contributor = contributors.find(contributor => contributor.name === author);
|
||||
if (contributor) {
|
||||
cleanedAuthors.push(contributor.login);
|
||||
} else {
|
||||
throw new Error(`Author ${author} not found`);
|
||||
}
|
||||
});
|
||||
|
||||
return cleanedAuthors;
|
||||
}
|
||||
|
||||
function loadAuthors(directoryPath: string) {
|
||||
const gitLogCommand = `git log --format="%aN" -- ${directoryPath}`;
|
||||
const result = execSync(gitLogCommand, { cwd: '/workspace/', encoding: 'utf-8' });
|
||||
if (result.length === 0) {
|
||||
return [];
|
||||
}
|
||||
const authors = result.trim().split('\n');
|
||||
authors.forEach(author => {
|
||||
if (!contributors.find(contributor => contributor.name === author)) {
|
||||
throw new Error(`Author ${author} not found in ${directoryPath}`);
|
||||
}
|
||||
})
|
||||
return authors;
|
||||
}
|
||||
|
||||
function loadSrcIndexFiles(directoryPath: string) {
|
||||
const files = fs.readdirSync(directoryPath);
|
||||
files.forEach(file => {
|
||||
const filePath = path.join(directoryPath, file);
|
||||
const stats = fs.statSync(filePath);
|
||||
if (file === 'tmp' || file === 'framework' || file === 'common') return;
|
||||
if (stats.isDirectory()) {
|
||||
const indexPath = path.join(filePath, 'src', 'index.ts');
|
||||
if (fs.existsSync(indexPath)) {
|
||||
const authorsOne = cleanAuthors(loadAuthors(filePath));
|
||||
const authorsTwo = cleanAuthors(loadAuthors(filePath.replace('/community', '')));
|
||||
const authorsThree = cleanAuthors(loadAuthors(filePath.replace('/community', '/src/lib/apps')));
|
||||
const authorsFour = cleanAuthors(loadAuthors(filePath.replace('/community', '/src/apps')));
|
||||
const uniqueAuthors = customSort([...new Set([...authorsOne, ...authorsTwo, ...authorsThree, ...authorsFour])]);
|
||||
console.log(uniqueAuthors);
|
||||
|
||||
const fileContent = fs.readFileSync(indexPath, { encoding: 'utf-8' });
|
||||
|
||||
const pattern = /authors: \[(.*?)\]/;
|
||||
|
||||
if (!pattern.test(fileContent)) {
|
||||
throw new Error("Pattern 'authors: [...] not found in the file content. " + indexPath);
|
||||
}
|
||||
|
||||
const modifiedContent = fileContent.replace(/authors: \[(.*?)\]/, `authors: ${JSON.stringify(uniqueAuthors)}`);
|
||||
fs.writeFileSync(indexPath, modifiedContent, { encoding: 'utf-8' });
|
||||
|
||||
const packageJson = path.join(filePath, 'package.json');
|
||||
const packageJsonContent = JSON.parse(fs.readFileSync(packageJson, { encoding: 'utf-8' }));
|
||||
packageJsonContent.version = semVer.inc(packageJsonContent.version, 'patch');
|
||||
fs.writeFileSync(packageJson, JSON.stringify(packageJsonContent, null, 2), { encoding: 'utf-8' });
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Sort the official team members last.
|
||||
const authorsOrder = ['Abdallah-Alwarawreh', 'Salem-Alaa', 'kishanprmr', 'MoShizzle', 'AbdulTheActivePiecer', 'khaledmashaly', 'abuaboud'].map(author => author.toLocaleLowerCase());
|
||||
|
||||
function customSort(authors: string[]): string[] {
|
||||
return authors.sort((a, b) => {
|
||||
const indexA = authorsOrder.indexOf(a.toLocaleLowerCase());
|
||||
const indexB = authorsOrder.indexOf(b.toLocaleLowerCase());
|
||||
|
||||
// If either author is not found in the specified order, move it to the end
|
||||
if (indexA === -1) return -1;
|
||||
if (indexB === -1) return 1;
|
||||
|
||||
// Sort based on the index in the specified order
|
||||
return indexA - indexB;
|
||||
});
|
||||
}
|
||||
const directoryToTraverse = '/workspace/packages/pieces/community'
|
||||
loadSrcIndexFiles(directoryToTraverse);
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import assert from 'node:assert';
|
||||
import { PieceMetadata } from '../../../packages/pieces/community/framework/src';
|
||||
import { StatusCodes } from 'http-status-codes';
|
||||
import { HttpHeader } from '../../../packages/pieces/community/common/src';
|
||||
import { AP_CLOUD_API_BASE, findNewPieces, pieceMetadataExists } from '../utils/piece-script-utils';
|
||||
import { chunk } from '../../../packages/shared/src/lib/common/utils/utils';
|
||||
assert(process.env['AP_CLOUD_API_KEY'], 'API Key is not defined');
|
||||
|
||||
const { AP_CLOUD_API_KEY } = process.env;
|
||||
|
||||
const insertPieceMetadata = async (
|
||||
pieceMetadata: PieceMetadata
|
||||
): Promise<void> => {
|
||||
const body = JSON.stringify(pieceMetadata);
|
||||
|
||||
const headers = {
|
||||
['api-key']: AP_CLOUD_API_KEY,
|
||||
[HttpHeader.CONTENT_TYPE]: 'application/json'
|
||||
};
|
||||
|
||||
const cloudResponse = await fetch(`${AP_CLOUD_API_BASE}/admin/pieces`, {
|
||||
method: 'POST',
|
||||
headers,
|
||||
body
|
||||
});
|
||||
|
||||
if (cloudResponse.status !== StatusCodes.OK && cloudResponse.status !== StatusCodes.CONFLICT) {
|
||||
throw new Error(await cloudResponse.text());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
const insertMetadataIfNotExist = async (pieceMetadata: PieceMetadata) => {
|
||||
console.info(
|
||||
`insertMetadataIfNotExist, name: ${pieceMetadata.name}, version: ${pieceMetadata.version}`
|
||||
);
|
||||
|
||||
const metadataAlreadyExist = await pieceMetadataExists(
|
||||
pieceMetadata.name,
|
||||
pieceMetadata.version
|
||||
);
|
||||
|
||||
if (metadataAlreadyExist) {
|
||||
console.info(`insertMetadataIfNotExist, piece metadata already inserted`);
|
||||
return;
|
||||
}
|
||||
|
||||
await insertPieceMetadata(pieceMetadata);
|
||||
};
|
||||
|
||||
const insertMetadata = async (piecesMetadata: PieceMetadata[]) => {
|
||||
const batches = chunk(piecesMetadata, 30)
|
||||
for (const batch of batches) {
|
||||
await Promise.all(batch.map(insertMetadataIfNotExist))
|
||||
await new Promise(resolve => setTimeout(resolve, 5000))
|
||||
}
|
||||
};
|
||||
|
||||
const main = async () => {
|
||||
console.log('update pieces metadata: started')
|
||||
|
||||
const piecesMetadata = await findNewPieces()
|
||||
await insertMetadata(piecesMetadata)
|
||||
|
||||
console.log('update pieces metadata: completed')
|
||||
process.exit()
|
||||
}
|
||||
|
||||
main()
|
||||
Reference in New Issue
Block a user