@fsai-flow/core 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/dist/README.md +11 -0
- package/dist/package.json +44 -0
- package/dist/src/index.d.ts +15 -0
- package/dist/src/index.js +29 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/lib/ActiveWebhooks.d.ts +59 -0
- package/dist/src/lib/ActiveWebhooks.js +184 -0
- package/dist/src/lib/ActiveWebhooks.js.map +1 -0
- package/dist/src/lib/ActiveWorkflows.d.ts +58 -0
- package/dist/src/lib/ActiveWorkflows.js +244 -0
- package/dist/src/lib/ActiveWorkflows.js.map +1 -0
- package/dist/src/lib/BinaryDataManager/FileSystem.d.ts +26 -0
- package/dist/src/lib/BinaryDataManager/FileSystem.js +179 -0
- package/dist/src/lib/BinaryDataManager/FileSystem.js.map +1 -0
- package/dist/src/lib/BinaryDataManager/index.d.ts +21 -0
- package/dist/src/lib/BinaryDataManager/index.js +146 -0
- package/dist/src/lib/BinaryDataManager/index.js.map +1 -0
- package/dist/src/lib/ChangeCase.d.ts +9 -0
- package/dist/src/lib/ChangeCase.js +43 -0
- package/dist/src/lib/ChangeCase.js.map +1 -0
- package/dist/src/lib/Constants.d.ts +14 -0
- package/dist/src/lib/Constants.js +19 -0
- package/dist/src/lib/Constants.js.map +1 -0
- package/dist/src/lib/Credentials.d.ts +27 -0
- package/dist/src/lib/Credentials.js +89 -0
- package/dist/src/lib/Credentials.js.map +1 -0
- package/dist/src/lib/FileSystem.d.ts +26 -0
- package/dist/src/lib/FileSystem.js +179 -0
- package/dist/src/lib/FileSystem.js.map +1 -0
- package/dist/src/lib/InputConnectionDataLegacy.d.ts +2 -0
- package/dist/src/lib/InputConnectionDataLegacy.js +79 -0
- package/dist/src/lib/InputConnectionDataLegacy.js.map +1 -0
- package/dist/src/lib/Interfaces.d.ts +148 -0
- package/dist/src/lib/Interfaces.js +3 -0
- package/dist/src/lib/Interfaces.js.map +1 -0
- package/dist/src/lib/LoadNodeParameterOptions.d.ts +39 -0
- package/dist/src/lib/LoadNodeParameterOptions.js +150 -0
- package/dist/src/lib/LoadNodeParameterOptions.js.map +1 -0
- package/dist/src/lib/NodeExecuteFunctions.d.ts +226 -0
- package/dist/src/lib/NodeExecuteFunctions.js +2483 -0
- package/dist/src/lib/NodeExecuteFunctions.js.map +1 -0
- package/dist/src/lib/NodesLoader/constants.d.ts +5 -0
- package/dist/src/lib/NodesLoader/constants.js +106 -0
- package/dist/src/lib/NodesLoader/constants.js.map +1 -0
- package/dist/src/lib/NodesLoader/custom-directory-loader.d.ts +9 -0
- package/dist/src/lib/NodesLoader/custom-directory-loader.js +36 -0
- package/dist/src/lib/NodesLoader/custom-directory-loader.js.map +1 -0
- package/dist/src/lib/NodesLoader/directory-loader.d.ts +66 -0
- package/dist/src/lib/NodesLoader/directory-loader.js +325 -0
- package/dist/src/lib/NodesLoader/directory-loader.js.map +1 -0
- package/dist/src/lib/NodesLoader/index.d.ts +5 -0
- package/dist/src/lib/NodesLoader/index.js +12 -0
- package/dist/src/lib/NodesLoader/index.js.map +1 -0
- package/dist/src/lib/NodesLoader/lazy-package-directory-loader.d.ts +7 -0
- package/dist/src/lib/NodesLoader/lazy-package-directory-loader.js +52 -0
- package/dist/src/lib/NodesLoader/lazy-package-directory-loader.js.map +1 -0
- package/dist/src/lib/NodesLoader/load-class-in-isolation.d.ts +1 -0
- package/dist/src/lib/NodesLoader/load-class-in-isolation.js +22 -0
- package/dist/src/lib/NodesLoader/load-class-in-isolation.js.map +1 -0
- package/dist/src/lib/NodesLoader/package-directory-loader.d.ts +17 -0
- package/dist/src/lib/NodesLoader/package-directory-loader.js +100 -0
- package/dist/src/lib/NodesLoader/package-directory-loader.js.map +1 -0
- package/dist/src/lib/NodesLoader/types.d.ts +14 -0
- package/dist/src/lib/NodesLoader/types.js +3 -0
- package/dist/src/lib/NodesLoader/types.js.map +1 -0
- package/dist/src/lib/UserSettings.d.ts +80 -0
- package/dist/src/lib/UserSettings.js +261 -0
- package/dist/src/lib/UserSettings.js.map +1 -0
- package/dist/src/lib/WorkflowExecute.d.ts +53 -0
- package/dist/src/lib/WorkflowExecute.js +835 -0
- package/dist/src/lib/WorkflowExecute.js.map +1 -0
- package/dist/src/lib/index.d.ts +21 -0
- package/dist/src/lib/index.js +146 -0
- package/dist/src/lib/index.js.map +1 -0
- package/dist/src/utils/crypto.d.ts +1 -0
- package/dist/src/utils/crypto.js +8 -0
- package/dist/src/utils/crypto.js.map +1 -0
- package/eslint.config.js +19 -0
- package/jest.config.ts +10 -0
- package/package.json +44 -0
- package/project.json +19 -0
- package/src/index.ts +27 -0
- package/src/lib/ActiveWebhooks.ts +245 -0
- package/src/lib/ActiveWorkflows.ts +304 -0
- package/src/lib/BinaryDataManager/FileSystem.ts +214 -0
- package/src/lib/BinaryDataManager/index.ts +187 -0
- package/src/lib/ChangeCase.ts +45 -0
- package/src/lib/Constants.ts +16 -0
- package/src/lib/Credentials.ts +108 -0
- package/src/lib/FileSystem.ts +214 -0
- package/src/lib/InputConnectionDataLegacy.ts +123 -0
- package/src/lib/Interfaces.ts +338 -0
- package/src/lib/LoadNodeParameterOptions.ts +235 -0
- package/src/lib/NodeExecuteFunctions.ts +3704 -0
- package/src/lib/NodesLoader/constants.ts +112 -0
- package/src/lib/NodesLoader/custom-directory-loader.ts +31 -0
- package/src/lib/NodesLoader/directory-loader.ts +458 -0
- package/src/lib/NodesLoader/index.ts +5 -0
- package/src/lib/NodesLoader/lazy-package-directory-loader.ts +55 -0
- package/src/lib/NodesLoader/load-class-in-isolation.ts +19 -0
- package/src/lib/NodesLoader/package-directory-loader.ts +107 -0
- package/src/lib/NodesLoader/types.ts +14 -0
- package/src/lib/UserSettings.ts +292 -0
- package/src/lib/WorkflowExecute.ts +1108 -0
- package/src/lib/index.ts +187 -0
- package/src/utils/crypto.ts +5 -0
- package/tests/Credentials.test.ts +88 -0
- package/tests/Helpers.ts +808 -0
- package/tests/WorkflowExecute.test.ts +1242 -0
- package/tsconfig.json +42 -0
- package/tsconfig.lib.json +10 -0
- package/tsconfig.spec.json +14 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { Icon, jsonParse } from '@fsai-flow/workflow';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
|
|
5
|
+
import { DirectoryLoader } from './directory-loader';
|
|
6
|
+
import type { n8n } from './types';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Loader for source files of nodes and credentials located in a package dir,
|
|
10
|
+
* e.g. /nodes-base or community packages.
|
|
11
|
+
*/
|
|
12
|
+
export class PackageDirectoryLoader extends DirectoryLoader {
|
|
13
|
+
packageJson: n8n.PackageJson;
|
|
14
|
+
|
|
15
|
+
packageName: string;
|
|
16
|
+
|
|
17
|
+
constructor(directory: string, excludeNodes: string[] = [], includeNodes: string[] = []) {
|
|
18
|
+
super(directory, excludeNodes, includeNodes);
|
|
19
|
+
|
|
20
|
+
this.packageJson = this.readJSONSync('package.json');
|
|
21
|
+
this.packageName = this.packageJson.name;
|
|
22
|
+
this.excludeNodes = this.extractNodeTypes(excludeNodes);
|
|
23
|
+
this.includeNodes = this.extractNodeTypes(includeNodes);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private extractNodeTypes(fullNodeTypes: string[]) {
|
|
27
|
+
return fullNodeTypes
|
|
28
|
+
.map((fullNodeType) => fullNodeType.split('.'))
|
|
29
|
+
.filter(([packageName]) => packageName === this.packageName)
|
|
30
|
+
.map(([_, nodeType]) => nodeType);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
override async loadAll() {
|
|
34
|
+
const { n8n } = this.packageJson;
|
|
35
|
+
if (!n8n) return;
|
|
36
|
+
|
|
37
|
+
const { nodes, credentials } = n8n;
|
|
38
|
+
|
|
39
|
+
if (Array.isArray(nodes)) {
|
|
40
|
+
for (const nodePath of nodes) {
|
|
41
|
+
this.loadNodeFromFile(nodePath);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (Array.isArray(credentials)) {
|
|
46
|
+
for (const credentialPath of credentials) {
|
|
47
|
+
this.loadCredentialFromFile(credentialPath);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
this.inferSupportedNodes();
|
|
52
|
+
|
|
53
|
+
console.debug(`Loaded all credentials and nodes from ${this.packageName}`, {
|
|
54
|
+
credentials: credentials?.length ?? 0,
|
|
55
|
+
nodes: nodes?.length ?? 0,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private inferSupportedNodes() {
|
|
60
|
+
const knownCredentials = this.known.credentials;
|
|
61
|
+
for (const { type: credentialType } of Object.values(this.credentialTypes)) {
|
|
62
|
+
const supportedNodes = knownCredentials[credentialType.name].supportedNodes ?? [];
|
|
63
|
+
if (supportedNodes.length > 0 && credentialType.httpRequestNode) {
|
|
64
|
+
credentialType.httpRequestNode.hidden = true;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
credentialType.supportedNodes = supportedNodes;
|
|
68
|
+
|
|
69
|
+
if (!credentialType.iconUrl && !credentialType.icon) {
|
|
70
|
+
for (const supportedNode of supportedNodes) {
|
|
71
|
+
const nodeDescription = this.nodeTypes[supportedNode]?.type.description;
|
|
72
|
+
|
|
73
|
+
if (!nodeDescription) continue;
|
|
74
|
+
if (nodeDescription.icon) {
|
|
75
|
+
credentialType.icon = nodeDescription.icon as Icon;
|
|
76
|
+
credentialType.iconColor = nodeDescription.iconColor;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
if (nodeDescription.iconUrl) {
|
|
80
|
+
credentialType.iconUrl = nodeDescription.iconUrl;
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private parseJSON<T>(fileString: string, filePath: string): T {
|
|
89
|
+
try {
|
|
90
|
+
return jsonParse<T>(fileString);
|
|
91
|
+
} catch (error) {
|
|
92
|
+
throw new Error(`Failed to parse JSON, ${filePath}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
protected readJSONSync<T>(file: string): T {
|
|
97
|
+
const filePath = this.resolvePath(file);
|
|
98
|
+
const fileString = readFileSync(filePath, 'utf8');
|
|
99
|
+
return this.parseJSON<T>(fileString, filePath);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
protected async readJSON<T>(file: string): Promise<T> {
|
|
103
|
+
const filePath = this.resolvePath(file);
|
|
104
|
+
const fileString = await readFile(filePath, 'utf8');
|
|
105
|
+
return this.parseJSON<T>(fileString, filePath);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/* eslint-disable no-param-reassign */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
import * as path from 'path';
|
|
7
|
+
import { createHash, randomBytes } from 'crypto';
|
|
8
|
+
// eslint-disable-next-line import/no-cycle
|
|
9
|
+
import {
|
|
10
|
+
ENCRYPTION_KEY_ENV_OVERWRITE,
|
|
11
|
+
EXTENSIONS_SUBDIRECTORY,
|
|
12
|
+
IUserSettings,
|
|
13
|
+
USER_FOLDER_ENV_OVERWRITE,
|
|
14
|
+
USER_SETTINGS_FILE_NAME,
|
|
15
|
+
USER_SETTINGS_SUBFOLDER,
|
|
16
|
+
} from '../../src';
|
|
17
|
+
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
19
|
+
const { promisify } = require('util');
|
|
20
|
+
|
|
21
|
+
const fsAccess = promisify(fs.access);
|
|
22
|
+
const fsReadFile = promisify(fs.readFile);
|
|
23
|
+
const fsMkdir = promisify(fs.mkdir);
|
|
24
|
+
const fsWriteFile = promisify(fs.writeFile);
|
|
25
|
+
|
|
26
|
+
let settingsCache: IUserSettings | undefined;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Creates the user settings if they do not exist yet
|
|
30
|
+
*
|
|
31
|
+
* @export
|
|
32
|
+
*/
|
|
33
|
+
export async function prepareUserSettings(): Promise<IUserSettings> {
|
|
34
|
+
const settingsPath = getUserSettingsPath();
|
|
35
|
+
|
|
36
|
+
let userSettings = await getUserSettings(settingsPath);
|
|
37
|
+
if (userSettings !== undefined) {
|
|
38
|
+
// Settings already exist, check if they contain the encryptionKey
|
|
39
|
+
if (userSettings.encryptionKey !== undefined) {
|
|
40
|
+
// Key already exists
|
|
41
|
+
if (userSettings.instanceId === undefined) {
|
|
42
|
+
userSettings.instanceId = await generateInstanceId(userSettings.encryptionKey);
|
|
43
|
+
settingsCache = userSettings;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return userSettings;
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
userSettings = {};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (process.env[ENCRYPTION_KEY_ENV_OVERWRITE] !== undefined) {
|
|
53
|
+
// Use the encryption key which got set via environment
|
|
54
|
+
userSettings.encryptionKey = process.env[ENCRYPTION_KEY_ENV_OVERWRITE];
|
|
55
|
+
} else {
|
|
56
|
+
// Generate a new encryption key
|
|
57
|
+
userSettings.encryptionKey = randomBytes(24).toString('base64');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
userSettings.instanceId = await generateInstanceId(userSettings.encryptionKey);
|
|
61
|
+
|
|
62
|
+
// eslint-disable-next-line no-console
|
|
63
|
+
console.log(`UserSettings were generated and saved to: ${settingsPath}`);
|
|
64
|
+
|
|
65
|
+
return writeUserSettings(userSettings, settingsPath);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Returns the encryption key which is used to encrypt
|
|
70
|
+
* the credentials.
|
|
71
|
+
*
|
|
72
|
+
* @export
|
|
73
|
+
* @returns
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
export async function getEncryptionKey(): Promise<string | undefined> {
|
|
77
|
+
if (process.env[ENCRYPTION_KEY_ENV_OVERWRITE] !== undefined) {
|
|
78
|
+
return process.env[ENCRYPTION_KEY_ENV_OVERWRITE];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const userSettings = await getUserSettings();
|
|
82
|
+
|
|
83
|
+
if (userSettings === undefined) {
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (userSettings.encryptionKey === undefined) {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return userSettings.encryptionKey;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Returns the instance ID
|
|
96
|
+
*
|
|
97
|
+
* @export
|
|
98
|
+
* @returns
|
|
99
|
+
*/
|
|
100
|
+
export async function getInstanceId(): Promise<string> {
|
|
101
|
+
const userSettings = await getUserSettings();
|
|
102
|
+
|
|
103
|
+
if (userSettings === undefined) {
|
|
104
|
+
return '';
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (userSettings.instanceId === undefined) {
|
|
108
|
+
return '';
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return userSettings.instanceId;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async function generateInstanceId(key?: string) {
|
|
115
|
+
const hash = key
|
|
116
|
+
? createHash('sha256')
|
|
117
|
+
.update(key.slice(Math.round(key.length / 2)))
|
|
118
|
+
.digest('hex')
|
|
119
|
+
: undefined;
|
|
120
|
+
|
|
121
|
+
return hash;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Adds/Overwrite the given settings in the currently
|
|
126
|
+
* saved user settings
|
|
127
|
+
*
|
|
128
|
+
* @export
|
|
129
|
+
* @param {IUserSettings} addSettings The settings to add/overwrite
|
|
130
|
+
* @param {string} [settingsPath] Optional settings file path
|
|
131
|
+
* @returns {Promise<IUserSettings>}
|
|
132
|
+
*/
|
|
133
|
+
export async function addToUserSettings(
|
|
134
|
+
addSettings: IUserSettings,
|
|
135
|
+
settingsPath?: string,
|
|
136
|
+
): Promise<IUserSettings> {
|
|
137
|
+
if (settingsPath === undefined) {
|
|
138
|
+
settingsPath = getUserSettingsPath();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
let userSettings = await getUserSettings(settingsPath);
|
|
142
|
+
|
|
143
|
+
if (userSettings === undefined) {
|
|
144
|
+
userSettings = {};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Add the settings
|
|
148
|
+
Object.assign(userSettings, addSettings);
|
|
149
|
+
|
|
150
|
+
return writeUserSettings(userSettings, settingsPath);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Writes a user settings file
|
|
155
|
+
*
|
|
156
|
+
* @export
|
|
157
|
+
* @param {IUserSettings} userSettings The settings to write
|
|
158
|
+
* @param {string} [settingsPath] Optional settings file path
|
|
159
|
+
* @returns {Promise<IUserSettings>}
|
|
160
|
+
*/
|
|
161
|
+
export async function writeUserSettings(
|
|
162
|
+
userSettings: IUserSettings,
|
|
163
|
+
settingsPath?: string,
|
|
164
|
+
): Promise<IUserSettings> {
|
|
165
|
+
if (settingsPath === undefined) {
|
|
166
|
+
settingsPath = getUserSettingsPath();
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (userSettings === undefined) {
|
|
170
|
+
userSettings = {};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Check if parent folder exists if not create it.
|
|
174
|
+
try {
|
|
175
|
+
await fsAccess(path.dirname(settingsPath));
|
|
176
|
+
} catch (error) {
|
|
177
|
+
// Parent folder does not exist so create
|
|
178
|
+
await fsMkdir(path.dirname(settingsPath));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const settingsToWrite = { ...userSettings };
|
|
182
|
+
if (settingsToWrite.instanceId !== undefined) {
|
|
183
|
+
delete settingsToWrite.instanceId;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
await fsWriteFile(settingsPath, JSON.stringify(settingsToWrite, null, '\t'));
|
|
187
|
+
settingsCache = JSON.parse(JSON.stringify(userSettings));
|
|
188
|
+
|
|
189
|
+
return userSettings;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Returns the content of the user settings
|
|
194
|
+
*
|
|
195
|
+
* @export
|
|
196
|
+
* @returns {UserSettings}
|
|
197
|
+
*/
|
|
198
|
+
export async function getUserSettings(
|
|
199
|
+
settingsPath?: string,
|
|
200
|
+
ignoreCache?: boolean,
|
|
201
|
+
): Promise<IUserSettings | undefined> {
|
|
202
|
+
if (settingsCache !== undefined && ignoreCache !== true) {
|
|
203
|
+
return settingsCache;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (settingsPath === undefined) {
|
|
207
|
+
settingsPath = getUserSettingsPath();
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
try {
|
|
211
|
+
await fsAccess(settingsPath);
|
|
212
|
+
} catch (error) {
|
|
213
|
+
// The file does not exist
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const settingsFile = await fsReadFile(settingsPath, 'utf8');
|
|
218
|
+
|
|
219
|
+
try {
|
|
220
|
+
settingsCache = JSON.parse(settingsFile);
|
|
221
|
+
} catch (error) {
|
|
222
|
+
throw new Error(
|
|
223
|
+
`Error parsing n8n-config file "${settingsPath}". It does not seem to be valid JSON.`,
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return settingsCache as IUserSettings;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Returns the path to the user settings
|
|
232
|
+
*
|
|
233
|
+
* @export
|
|
234
|
+
* @returns {string}
|
|
235
|
+
*/
|
|
236
|
+
export function getUserSettingsPath(): string {
|
|
237
|
+
const n8nFolder = getUserN8nFolderPath();
|
|
238
|
+
|
|
239
|
+
return path.join(n8nFolder, USER_SETTINGS_FILE_NAME);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Retruns the path to the n8n folder in which all n8n
|
|
244
|
+
* related data gets saved
|
|
245
|
+
*
|
|
246
|
+
* @export
|
|
247
|
+
* @returns {string}
|
|
248
|
+
*/
|
|
249
|
+
export function getUserN8nFolderPath(): string {
|
|
250
|
+
let userFolder;
|
|
251
|
+
if (process.env[USER_FOLDER_ENV_OVERWRITE] !== undefined) {
|
|
252
|
+
userFolder = process.env[USER_FOLDER_ENV_OVERWRITE] as string;
|
|
253
|
+
} else {
|
|
254
|
+
userFolder = getUserHome();
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return path.join(userFolder, USER_SETTINGS_SUBFOLDER);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Returns the path to the n8n user folder with the custom
|
|
262
|
+
* extensions like nodes and credentials
|
|
263
|
+
*
|
|
264
|
+
* @export
|
|
265
|
+
* @returns {string}
|
|
266
|
+
*/
|
|
267
|
+
export function getUserN8nFolderCustomExtensionPath(): string {
|
|
268
|
+
return path.join(getUserN8nFolderPath(), EXTENSIONS_SUBDIRECTORY);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Returns the home folder path of the user if
|
|
273
|
+
* none can be found it falls back to the current
|
|
274
|
+
* working directory
|
|
275
|
+
*
|
|
276
|
+
* @export
|
|
277
|
+
* @returns {string}
|
|
278
|
+
*/
|
|
279
|
+
export function getUserHome(): string {
|
|
280
|
+
let variableName = 'HOME';
|
|
281
|
+
if (process.platform === 'win32') {
|
|
282
|
+
variableName = 'USERPROFILE';
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (process.env[variableName] === undefined) {
|
|
286
|
+
// If for some reason the variable does not exist
|
|
287
|
+
// fall back to current folder
|
|
288
|
+
return process.cwd();
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return process.env[variableName] as string;
|
|
292
|
+
}
|