Skip to main content
Glama
file-pieces-utils.ts4.62 kB
import { readdir, readFile, stat } from 'node:fs/promises' import { join, resolve } from 'node:path' import { cwd } from 'node:process' import { sep } from 'path' import importFresh from '@activepieces/import-fresh-webpack' import { Piece, PieceMetadata, pieceTranslation } from '@activepieces/pieces-framework' import { extractPieceFromModule } from '@activepieces/shared' import clearModule from 'clear-module' import { FastifyBaseLogger } from 'fastify' const DIST_PIECES_PATH = resolve(cwd(), 'dist', 'packages', 'pieces') const SOURCE_PIECES_PATH = resolve(cwd(), 'packages', 'pieces') export const filePiecesUtils = (log: FastifyBaseLogger) => ({ getPackageNameFromFolderPath: async (folderPath: string): Promise<string> => { const packageJson = await readFile(join(folderPath, 'package.json'), 'utf-8').then(JSON.parse) return packageJson.name }, getProjectJsonFromFolderPath: async (folderPath: string): Promise<string> => { return join(folderPath, 'project.json') }, getPieceDependencies: async (folderPath: string): Promise<Record<string, string> | null> => { try { const packageJson = await readFile(join(folderPath, 'package.json'), 'utf-8').then(JSON.parse) if (!packageJson.dependencies) { return null } return packageJson.dependencies } catch (e) { return null } }, findDistPiecePathByPackageName: async (packageName: string): Promise<string | null> => { const paths = await findAllPiecesFolder(DIST_PIECES_PATH) for (const path of paths) { try { const packageJsonName = await filePiecesUtils(log).getPackageNameFromFolderPath(path) if (packageJsonName === packageName) { return path } } catch (e) { log.error({ name: 'findDistPiecePathByPackageName', message: JSON.stringify(e), }, 'Error finding dist piece path by package name') } } return null }, findSourcePiecePathByPieceName: async (pieceName: string): Promise<string | null> => { const piecesPath = await findAllPiecesFolder(SOURCE_PIECES_PATH) const piecePath = piecesPath.find((p) => p.endsWith(sep + pieceName)) return piecePath ?? null }, loadDistPiecesMetadata: async (piecesNames: string[]): Promise<PieceMetadata[]> => { try { const paths = (await findAllPiecesFolder(DIST_PIECES_PATH)).filter(path => piecesNames.some(name => path.includes(name))) const pieces = await Promise.all(paths.map((p) => loadPieceFromFolder(p))) return pieces.filter((p): p is PieceMetadata => p !== null) } catch (e) { const err = e as Error log.warn({ name: 'FilePieceMetadataService#loadPiecesFromFolder', message: err.message, stack: err.stack }) return [] } }, }) const findAllPiecesFolder = async (folderPath: string): Promise<string[]> => { const paths = [] const files = await readdir(folderPath) const ignoredFiles = ['node_modules', 'dist', 'framework', 'common', 'common-ai'] for (const file of files) { const filePath = join(folderPath, file) const fileStats = await stat(filePath) if ( fileStats.isDirectory() && !ignoredFiles.includes(file) ) { paths.push(...(await findAllPiecesFolder(filePath))) } else if (file === 'package.json') { paths.push(folderPath) } } return paths } const loadPieceFromFolder = async ( folderPath: string, ): Promise<PieceMetadata | null> => { const indexPath = join(folderPath, 'src', 'index') clearModule(indexPath) const packageJson = importFresh<Record<string, string>>( join(folderPath, 'package.json'), ) const module = importFresh<Record<string, unknown>>( indexPath, ) const { name: pieceName, version: pieceVersion } = packageJson const piece = extractPieceFromModule<Piece>({ module, pieceName, pieceVersion, }) const originalMetadata = piece.metadata() const i18n = await pieceTranslation.initializeI18n(folderPath) const metadata: PieceMetadata = { ...originalMetadata, name: pieceName, version: pieceVersion, authors: piece.authors, directoryPath: folderPath, i18n, } return metadata }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/activepieces/activepieces'

If you have feedback or need assistance with the MCP directory API, please join our Discord server