1
import { IComponentNodes, IComponentCredentials } from './Interface'
3
import { Dirent } from 'fs'
4
import { getNodeModulesPackagePath } from './utils'
5
import { promises } from 'fs'
6
import { ICommonObject } from 'flowise-components'
7
import logger from './utils/logger'
9
export class NodesPool {
10
componentNodes: IComponentNodes = {}
11
componentCredentials: IComponentCredentials = {}
12
private credentialIconPath: ICommonObject = {}
15
* Initialize to get all nodes & credentials
18
await this.initializeNodes()
19
await this.initializeCredentials()
25
private async initializeNodes() {
26
const packagePath = getNodeModulesPackagePath('flowise-components')
27
const nodesPath = path.join(packagePath, 'dist', 'nodes')
28
const nodeFiles = await this.getFiles(nodesPath)
30
nodeFiles.map(async (file) => {
31
if (file.endsWith('.js')) {
33
const nodeModule = await require(file)
35
if (nodeModule.nodeClass) {
36
const newNodeInstance = new nodeModule.nodeClass()
37
newNodeInstance.filePath = file
39
// Replace file icon with absolute path
41
newNodeInstance.icon &&
42
(newNodeInstance.icon.endsWith('.svg') ||
43
newNodeInstance.icon.endsWith('.png') ||
44
newNodeInstance.icon.endsWith('.jpg'))
46
const filePath = file.replace(/\\/g, '/').split('/')
48
const nodeIconAbsolutePath = `${filePath.join('/')}/${newNodeInstance.icon}`
49
newNodeInstance.icon = nodeIconAbsolutePath
51
// Store icon path for componentCredentials
52
if (newNodeInstance.credential) {
53
for (const credName of newNodeInstance.credential.credentialNames) {
54
this.credentialIconPath[credName] = nodeIconAbsolutePath
59
const skipCategories = ['Analytic', 'SpeechToText']
60
if (!skipCategories.includes(newNodeInstance.category)) {
61
this.componentNodes[newNodeInstance.name] = newNodeInstance
65
logger.error(`❌ [server]: Error during initDatabase with file ${file}:`, err)
73
* Initialize credentials
75
private async initializeCredentials() {
76
const packagePath = getNodeModulesPackagePath('flowise-components')
77
const nodesPath = path.join(packagePath, 'dist', 'credentials')
78
const nodeFiles = await this.getFiles(nodesPath)
80
nodeFiles.map(async (file) => {
81
if (file.endsWith('.credential.js')) {
82
const credentialModule = await require(file)
83
if (credentialModule.credClass) {
84
const newCredInstance = new credentialModule.credClass()
85
newCredInstance.icon = this.credentialIconPath[newCredInstance.name] ?? ''
86
this.componentCredentials[newCredInstance.name] = newCredInstance
94
* Recursive function to get node files
98
private async getFiles(dir: string): Promise<string[]> {
99
const dirents = await promises.readdir(dir, { withFileTypes: true })
100
const files = await Promise.all(
101
dirents.map((dirent: Dirent) => {
102
const res = path.resolve(dir, dirent.name)
103
return dirent.isDirectory() ? this.getFiles(res) : res
106
return Array.prototype.concat(...files)