mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-12 15:44:06 -08:00
fix: correct all the spelling typos (#3960)
* Improve code health Fix TS typos in local variables Fix CSS typos in local styles Fix typos in comments Fix typos in strings * Fix order of n8n setup sections in CONTRIBUTING.md
This commit is contained in:
parent
a3791c22b3
commit
49c85a1df8
2
.vscode/DEBUGGER.md
vendored
2
.vscode/DEBUGGER.md
vendored
|
@ -18,7 +18,7 @@ Breakpoints are noted with a red dot in front of the line, meaning that whenever
|
||||||
|
|
||||||
## What if I change the code?
|
## What if I change the code?
|
||||||
|
|
||||||
You might need to restart the debugger if you make changes to your code, since the running process will be executing an oudated version of the code.
|
You might need to restart the debugger if you make changes to your code, since the running process will be executing an outdated version of the code.
|
||||||
|
|
||||||
In order to make this process easier you can simply run `npm run watch` in another terminal window, so you don't have to fully build the project. Please note that restarting n8n is still required, but this is much faster.
|
In order to make this process easier you can simply run `npm run watch` in another terminal window, so you don't have to fully build the project. Please note that restarting n8n is still required, but this is much faster.
|
||||||
|
|
||||||
|
|
|
@ -97,18 +97,18 @@ checked out and set up:
|
||||||
git clone https://github.com/<your_github_username>/n8n.git
|
git clone https://github.com/<your_github_username>/n8n.git
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Add the original n8n repository as `upstream` to your forked repository
|
3. Go into repository folder
|
||||||
|
|
||||||
```
|
|
||||||
git remote add upstream https://github.com/n8n-io/n8n.git
|
|
||||||
```
|
|
||||||
|
|
||||||
4. Go into repository folder
|
|
||||||
|
|
||||||
```
|
```
|
||||||
cd n8n
|
cd n8n
|
||||||
```
|
```
|
||||||
|
|
||||||
|
4. Add the original n8n repository as `upstream` to your forked repository
|
||||||
|
|
||||||
|
```
|
||||||
|
git remote add upstream https://github.com/n8n-io/n8n.git
|
||||||
|
```
|
||||||
|
|
||||||
5. Install all dependencies of all modules and link them together:
|
5. Install all dependencies of all modules and link them together:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# n8n on Subfolder with SSL
|
# n8n on Subfolder with SSL
|
||||||
|
|
||||||
Starts n8n and deployes it on a subfolder
|
Starts n8n and deploys it on a subfolder
|
||||||
|
|
||||||
## Start
|
## Start
|
||||||
|
|
||||||
|
|
2
packages/cli/commands/Interfaces.d.ts
vendored
2
packages/cli/commands/Interfaces.d.ts
vendored
|
@ -15,7 +15,7 @@ interface IResult {
|
||||||
interface IExecutionResult {
|
interface IExecutionResult {
|
||||||
workflowId: string | number;
|
workflowId: string | number;
|
||||||
workflowName: string;
|
workflowName: string;
|
||||||
executionTime: number; // Given in seconds with decimals for milisseconds
|
executionTime: number; // Given in seconds with decimals for milliseconds
|
||||||
finished: boolean;
|
finished: boolean;
|
||||||
executionStatus: ExecutionStatus;
|
executionStatus: ExecutionStatus;
|
||||||
error?: string;
|
error?: string;
|
||||||
|
|
|
@ -98,7 +98,7 @@ export class ExecuteBatch extends Command {
|
||||||
}),
|
}),
|
||||||
shallow: flags.boolean({
|
shallow: flags.boolean({
|
||||||
description:
|
description:
|
||||||
'Compares only if attributes output from node are the same, with no regards to neste JSON objects.',
|
'Compares only if attributes output from node are the same, with no regards to nested JSON objects.',
|
||||||
}),
|
}),
|
||||||
skipList: flags.string({
|
skipList: flags.string({
|
||||||
description: 'File containing a comma separated list of workflow IDs to skip.',
|
description: 'File containing a comma separated list of workflow IDs to skip.',
|
||||||
|
@ -152,7 +152,7 @@ export class ExecuteBatch extends Command {
|
||||||
executingWorkflows = activeExecutionsInstance.getActiveExecutions();
|
executingWorkflows = activeExecutionsInstance.getActiveExecutions();
|
||||||
}
|
}
|
||||||
// We may receive true but when called from `process.on`
|
// We may receive true but when called from `process.on`
|
||||||
// we get the signal (SIGNIT, etc.)
|
// we get the signal (SIGINT, etc.)
|
||||||
if (skipExit !== true) {
|
if (skipExit !== true) {
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
@ -864,7 +864,7 @@ export class ExecuteBatch extends Command {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Save snapshots only after comparing - this is to make sure we're updating
|
// Save snapshots only after comparing - this is to make sure we're updating
|
||||||
// After comparing to existing verion.
|
// After comparing to existing version.
|
||||||
if (ExecuteBatch.snapshot !== undefined) {
|
if (ExecuteBatch.snapshot !== undefined) {
|
||||||
const fileName = `${
|
const fileName = `${
|
||||||
ExecuteBatch.snapshot.endsWith(sep)
|
ExecuteBatch.snapshot.endsWith(sep)
|
||||||
|
|
|
@ -86,7 +86,7 @@ export class ExportCredentialsCommand extends Command {
|
||||||
|
|
||||||
if (fs.existsSync(flags.output)) {
|
if (fs.existsSync(flags.output)) {
|
||||||
if (!fs.lstatSync(flags.output).isDirectory()) {
|
if (!fs.lstatSync(flags.output).isDirectory()) {
|
||||||
console.info(`The paramenter --output must be a directory`);
|
console.info(`The parameter --output must be a directory`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -105,7 +105,7 @@ export class ExportCredentialsCommand extends Command {
|
||||||
} else if (flags.output) {
|
} else if (flags.output) {
|
||||||
if (fs.existsSync(flags.output)) {
|
if (fs.existsSync(flags.output)) {
|
||||||
if (fs.lstatSync(flags.output).isDirectory()) {
|
if (fs.lstatSync(flags.output).isDirectory()) {
|
||||||
console.info(`The paramenter --output must be a writeble file`);
|
console.info(`The parameter --output must be a writeable file`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ export class ExportWorkflowsCommand extends Command {
|
||||||
|
|
||||||
if (fs.existsSync(flags.output)) {
|
if (fs.existsSync(flags.output)) {
|
||||||
if (!fs.lstatSync(flags.output).isDirectory()) {
|
if (!fs.lstatSync(flags.output).isDirectory()) {
|
||||||
console.info(`The paramenter --output must be a directory`);
|
console.info(`The parameter --output must be a directory`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -97,7 +97,7 @@ export class ExportWorkflowsCommand extends Command {
|
||||||
} else if (flags.output) {
|
} else if (flags.output) {
|
||||||
if (fs.existsSync(flags.output)) {
|
if (fs.existsSync(flags.output)) {
|
||||||
if (fs.lstatSync(flags.output).isDirectory()) {
|
if (fs.lstatSync(flags.output).isDirectory()) {
|
||||||
console.info(`The paramenter --output must be a writeble file`);
|
console.info(`The parameter --output must be a writeable file`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -256,7 +256,7 @@ export class Start extends Command {
|
||||||
missingPackages.delete(missingPackage);
|
missingPackages.delete(missingPackage);
|
||||||
}
|
}
|
||||||
LoggerProxy.info(
|
LoggerProxy.info(
|
||||||
'Packages reinstalled successfully. Resuming regular intiailization.',
|
'Packages reinstalled successfully. Resuming regular initialization.',
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
LoggerProxy.error('n8n was unable to install the missing packages.');
|
LoggerProxy.error('n8n was unable to install the missing packages.');
|
||||||
|
|
|
@ -106,7 +106,7 @@ export class Webhook extends Command {
|
||||||
* as it is unable to determine if it is still running or crashed
|
* as it is unable to determine if it is still running or crashed
|
||||||
* - You cannot stop currently executing jobs from webhook processes
|
* - You cannot stop currently executing jobs from webhook processes
|
||||||
* when running without queues as the main process cannot talk to
|
* when running without queues as the main process cannot talk to
|
||||||
* the wehbook processes to communicate workflow execution interruption.
|
* the webhook processes to communicate workflow execution interruption.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
this.error('Webhook processes can only run with execution mode as queue.');
|
this.error('Webhook processes can only run with execution mode as queue.');
|
||||||
|
|
|
@ -391,7 +391,7 @@ export class Worker extends Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Just to be complete, generally will the worker stop automatically
|
// Just to be complete, generally will the worker stop automatically
|
||||||
// if it loses the conection to redis
|
// if it loses the connection to redis
|
||||||
try {
|
try {
|
||||||
// Redis ping
|
// Redis ping
|
||||||
await Worker.jobQueue.client.ping();
|
await Worker.jobQueue.client.ping();
|
||||||
|
|
|
@ -151,7 +151,7 @@ export const schema = {
|
||||||
// Allows to set default values for credentials which
|
// Allows to set default values for credentials which
|
||||||
// get automatically prefilled and the user does not get
|
// get automatically prefilled and the user does not get
|
||||||
// displayed and can not change.
|
// displayed and can not change.
|
||||||
// Format: { CREDENTIAL_NAME: { PARAMTER: VALUE }}
|
// Format: { CREDENTIAL_NAME: { PARAMETER: VALUE }}
|
||||||
doc: 'Overwrites for credentials',
|
doc: 'Overwrites for credentials',
|
||||||
format: '*',
|
format: '*',
|
||||||
default: '{}',
|
default: '{}',
|
||||||
|
@ -248,7 +248,7 @@ export const schema = {
|
||||||
env: 'EXECUTIONS_DATA_SAVE_ON_SUCCESS',
|
env: 'EXECUTIONS_DATA_SAVE_ON_SUCCESS',
|
||||||
},
|
},
|
||||||
saveExecutionProgress: {
|
saveExecutionProgress: {
|
||||||
doc: 'Wether or not to save progress for each node executed',
|
doc: 'Whether or not to save progress for each node executed',
|
||||||
format: 'Boolean',
|
format: 'Boolean',
|
||||||
default: false,
|
default: false,
|
||||||
env: 'EXECUTIONS_DATA_SAVE_ON_PROGRESS',
|
env: 'EXECUTIONS_DATA_SAVE_ON_PROGRESS',
|
||||||
|
@ -363,7 +363,7 @@ export const schema = {
|
||||||
generic: {
|
generic: {
|
||||||
// The timezone to use. Is important for nodes like "Cron" which start the
|
// The timezone to use. Is important for nodes like "Cron" which start the
|
||||||
// workflow automatically at a specified time. This setting can also be
|
// workflow automatically at a specified time. This setting can also be
|
||||||
// overwritten on a per worfklow basis in the workflow settings in the
|
// overwritten on a per workflow basis in the workflow settings in the
|
||||||
// editor.
|
// editor.
|
||||||
timezone: {
|
timezone: {
|
||||||
doc: 'The timezone to use',
|
doc: 'The timezone to use',
|
||||||
|
@ -607,7 +607,7 @@ export const schema = {
|
||||||
format: Boolean,
|
format: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
env: 'N8N_WORKFLOW_TAGS_DISABLED',
|
env: 'N8N_WORKFLOW_TAGS_DISABLED',
|
||||||
doc: 'Disable worfklow tags.',
|
doc: 'Disable workflow tags.',
|
||||||
},
|
},
|
||||||
|
|
||||||
userManagement: {
|
userManagement: {
|
||||||
|
@ -945,7 +945,7 @@ export const schema = {
|
||||||
|
|
||||||
onboardingCallPrompt: {
|
onboardingCallPrompt: {
|
||||||
enabled: {
|
enabled: {
|
||||||
doc: 'Whether onboarding call propmpt feature is available',
|
doc: 'Whether onboarding call prompt feature is available',
|
||||||
format: Boolean,
|
format: Boolean,
|
||||||
default: true,
|
default: true,
|
||||||
env: 'N8N_ONBOARDING_CALL_PROMPTS_ENABLED',
|
env: 'N8N_ONBOARDING_CALL_PROMPTS_ENABLED',
|
||||||
|
|
|
@ -75,7 +75,7 @@ export class ActiveWorkflowRunner {
|
||||||
|
|
||||||
// NOTE
|
// NOTE
|
||||||
// Here I guess we can have a flag on the workflow table like hasTrigger
|
// Here I guess we can have a flag on the workflow table like hasTrigger
|
||||||
// so intead of pulling all the active wehhooks just pull the actives that have a trigger
|
// so instead of pulling all the active webhooks just pull the actives that have a trigger
|
||||||
const workflowsData: IWorkflowDb[] = (await Db.collections.Workflow.find({
|
const workflowsData: IWorkflowDb[] = (await Db.collections.Workflow.find({
|
||||||
where: { active: true },
|
where: { active: true },
|
||||||
relations: ['shared', 'shared.user', 'shared.user.globalRole'],
|
relations: ['shared', 'shared.user', 'shared.user.globalRole'],
|
||||||
|
@ -183,7 +183,7 @@ export class ActiveWorkflowRunner {
|
||||||
req: express.Request,
|
req: express.Request,
|
||||||
res: express.Response,
|
res: express.Response,
|
||||||
): Promise<IResponseCallbackData> {
|
): Promise<IResponseCallbackData> {
|
||||||
Logger.debug(`Received webhoook "${httpMethod}" for path "${path}"`);
|
Logger.debug(`Received webhook "${httpMethod}" for path "${path}"`);
|
||||||
if (this.activeWorkflows === null) {
|
if (this.activeWorkflows === null) {
|
||||||
throw new ResponseHelper.ResponseError(
|
throw new ResponseHelper.ResponseError(
|
||||||
'The "activeWorkflows" instance did not get initialized yet.',
|
'The "activeWorkflows" instance did not get initialized yet.',
|
||||||
|
@ -480,7 +480,7 @@ export class ActiveWorkflowRunner {
|
||||||
config.getEnv('endpoints.skipWebhoooksDeregistrationOnShutdown') &&
|
config.getEnv('endpoints.skipWebhoooksDeregistrationOnShutdown') &&
|
||||||
error.name === 'QueryFailedError'
|
error.name === 'QueryFailedError'
|
||||||
) {
|
) {
|
||||||
// When skipWebhoooksDeregistrationOnShutdown is enabled,
|
// When skipWebhooksDeregistrationOnShutdown is enabled,
|
||||||
// n8n does not remove the registered webhooks on exit.
|
// n8n does not remove the registered webhooks on exit.
|
||||||
// This means that further initializations will always fail
|
// This means that further initializations will always fail
|
||||||
// when inserting to database. This is why we ignore this error
|
// when inserting to database. This is why we ignore this error
|
||||||
|
@ -504,7 +504,7 @@ export class ActiveWorkflowRunner {
|
||||||
if (error.name === 'QueryFailedError') {
|
if (error.name === 'QueryFailedError') {
|
||||||
error.message = `The URL path that the "${webhook.node}" node uses is already taken. Please change it to something else.`;
|
error.message = `The URL path that the "${webhook.node}" node uses is already taken. Please change it to something else.`;
|
||||||
} else if (error.detail) {
|
} else if (error.detail) {
|
||||||
// it's a error runnig the webhook methods (checkExists, create)
|
// it's a error running the webhook methods (checkExists, create)
|
||||||
error.message = error.detail;
|
error.message = error.detail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -307,7 +307,7 @@ export class CredentialsHelper extends ICredentialsHelper {
|
||||||
NodeHelpers.mergeNodeProperties(combineProperties, mergeCredentialProperties);
|
NodeHelpers.mergeNodeProperties(combineProperties, mergeCredentialProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The properties defined on the parent credentials take presidence
|
// The properties defined on the parent credentials take precedence
|
||||||
NodeHelpers.mergeNodeProperties(combineProperties, credentialTypeData.properties);
|
NodeHelpers.mergeNodeProperties(combineProperties, credentialTypeData.properties);
|
||||||
|
|
||||||
return combineProperties;
|
return combineProperties;
|
||||||
|
@ -526,11 +526,11 @@ export class CredentialsHelper extends ICredentialsHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Test is defined as string which links to a functoin
|
// Test is defined as string which links to a function
|
||||||
return (node as unknown as INodeType).methods?.credentialTest![credential.testedBy];
|
return (node as unknown as INodeType).methods?.credentialTest![credential.testedBy];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test is defined as JSON with a defintion for the request to make
|
// Test is defined as JSON with a definition for the request to make
|
||||||
return {
|
return {
|
||||||
nodeType,
|
nodeType,
|
||||||
testRequest: credential.testedBy,
|
testRequest: credential.testedBy,
|
||||||
|
@ -574,7 +574,7 @@ export class CredentialsHelper extends ICredentialsHelper {
|
||||||
|
|
||||||
// Credentials get tested via request instructions
|
// Credentials get tested via request instructions
|
||||||
|
|
||||||
// TODO: Temp worfklows get created at multiple locations (for example also LoadNodeParameterOptions),
|
// TODO: Temp workflows get created at multiple locations (for example also LoadNodeParameterOptions),
|
||||||
// check if some of them are identical enough that it can be combined
|
// check if some of them are identical enough that it can be combined
|
||||||
|
|
||||||
let nodeType: INodeType;
|
let nodeType: INodeType;
|
||||||
|
|
|
@ -121,7 +121,7 @@ export async function getConfigValue(
|
||||||
return config.getEnv(configKey);
|
return config.getEnv(configKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if special file enviroment variable exists
|
// Check if special file environment variable exists
|
||||||
const fileEnvironmentVariable = process.env[`${currentSchema.env}_FILE`];
|
const fileEnvironmentVariable = process.env[`${currentSchema.env}_FILE`];
|
||||||
if (fileEnvironmentVariable === undefined) {
|
if (fileEnvironmentVariable === undefined) {
|
||||||
// Does not exist, so return value from config
|
// Does not exist, so return value from config
|
||||||
|
|
|
@ -216,7 +216,7 @@ export interface IExecutionResponse extends IExecutionBase {
|
||||||
workflowData: IWorkflowBase;
|
workflowData: IWorkflowBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flatted data to save memory when saving in database or transfering
|
// Flatted data to save memory when saving in database or transferring
|
||||||
// via REST API
|
// via REST API
|
||||||
export interface IExecutionFlatted extends IExecutionBase {
|
export interface IExecutionFlatted extends IExecutionBase {
|
||||||
data: string;
|
data: string;
|
||||||
|
|
|
@ -343,7 +343,7 @@ export class InternalHooksClass implements IInternalHooksClass {
|
||||||
public_api: boolean;
|
public_api: boolean;
|
||||||
}): Promise<void> {
|
}): Promise<void> {
|
||||||
return this.telemetry.track(
|
return this.telemetry.track(
|
||||||
'Instance sent transacptional email to user',
|
'Instance sent transactional email to user',
|
||||||
userTransactionalEmailData,
|
userTransactionalEmailData,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,7 +201,7 @@ class LoadNodesAndCredentialsClass {
|
||||||
// Add serializer method "toJSON" to the class so that authenticate method (if defined)
|
// Add serializer method "toJSON" to the class so that authenticate method (if defined)
|
||||||
// gets mapped to the authenticate attribute before it is sent to the client.
|
// gets mapped to the authenticate attribute before it is sent to the client.
|
||||||
// The authenticate property is used by the client to decide whether or not to
|
// The authenticate property is used by the client to decide whether or not to
|
||||||
// include the credential type in the predifined credentials (HTTP node)
|
// include the credential type in the predefined credentials (HTTP node)
|
||||||
// eslint-disable-next-line func-names
|
// eslint-disable-next-line func-names
|
||||||
tempModule[credentialName].prototype.toJSON = function () {
|
tempModule[credentialName].prototype.toJSON = function () {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||||
|
@ -426,7 +426,7 @@ class LoadNodesAndCredentialsClass {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the node should be skiped
|
// Check if the node should be skipped
|
||||||
if (this.excludeNodes !== undefined && this.excludeNodes.includes(fullNodeName)) {
|
if (this.excludeNodes !== undefined && this.excludeNodes.includes(fullNodeName)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ function createApiRouter(
|
||||||
): Router {
|
): Router {
|
||||||
const n8nPath = config.getEnv('path');
|
const n8nPath = config.getEnv('path');
|
||||||
const swaggerDocument = YAML.load(openApiSpecPath) as swaggerUi.JsonObject;
|
const swaggerDocument = YAML.load(openApiSpecPath) as swaggerUi.JsonObject;
|
||||||
// add the server depeding on the config so the user can interact with the API
|
// add the server depending on the config so the user can interact with the API
|
||||||
// from the Swagger UI
|
// from the Swagger UI
|
||||||
swaggerDocument.server = [
|
swaggerDocument.server = [
|
||||||
{
|
{
|
||||||
|
|
|
@ -137,9 +137,9 @@ export function sanitizeCredentials(
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* toJsonSchema
|
* toJsonSchema
|
||||||
* Take an array of crendentials parameter and map it
|
* Take an array of credentials parameter and map it
|
||||||
* to a JSON Schema (see https://json-schema.org/). With
|
* to a JSON Schema (see https://json-schema.org/). With
|
||||||
* the JSON Schema defintion we can validate the credential's shape
|
* the JSON Schema definition we can validate the credential's shape
|
||||||
* @param properties - Credentials properties
|
* @param properties - Credentials properties
|
||||||
* @returns The credentials schema definition.
|
* @returns The credentials schema definition.
|
||||||
*/
|
*/
|
||||||
|
@ -155,7 +155,7 @@ export function toJsonSchema(properties: INodeProperties[]): IDataObject {
|
||||||
const optionsValues: { [key: string]: string[] } = {};
|
const optionsValues: { [key: string]: string[] } = {};
|
||||||
const resolveProperties: string[] = [];
|
const resolveProperties: string[] = [];
|
||||||
|
|
||||||
// get all posible values of properties type "options"
|
// get all possible values of properties type "options"
|
||||||
// so we can later resolve the displayOptions dependencies
|
// so we can later resolve the displayOptions dependencies
|
||||||
properties
|
properties
|
||||||
.filter((property) => property.type === 'options')
|
.filter((property) => property.type === 'options')
|
||||||
|
@ -177,7 +177,7 @@ export function toJsonSchema(properties: INodeProperties[]): IDataObject {
|
||||||
requiredFields.push(property.name);
|
requiredFields.push(property.name);
|
||||||
if (property.type === 'options') {
|
if (property.type === 'options') {
|
||||||
// if the property is type options,
|
// if the property is type options,
|
||||||
// include all possible values in the anum property.
|
// include all possible values in the enum property.
|
||||||
Object.assign(jsonSchema.properties, {
|
Object.assign(jsonSchema.properties, {
|
||||||
[property.name]: {
|
[property.name]: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
|
|
@ -251,7 +251,7 @@ export = {
|
||||||
return res.json(sharedWorkflow.workflow);
|
return res.json(sharedWorkflow.workflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
// nothing to do as the wokflow is already active
|
// nothing to do as the workflow is already active
|
||||||
return res.json(sharedWorkflow.workflow);
|
return res.json(sharedWorkflow.workflow);
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -280,7 +280,7 @@ export = {
|
||||||
return res.json(sharedWorkflow.workflow);
|
return res.json(sharedWorkflow.workflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
// nothing to do as the wokflow is already inactive
|
// nothing to do as the workflow is already inactive
|
||||||
return res.json(sharedWorkflow.workflow);
|
return res.json(sharedWorkflow.workflow);
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -68,7 +68,7 @@ export class Push {
|
||||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
|
||||||
send(type: IPushDataType, data: any, sessionId?: string) {
|
send(type: IPushDataType, data: any, sessionId?: string) {
|
||||||
if (sessionId !== undefined && this.connections[sessionId] === undefined) {
|
if (sessionId !== undefined && this.connections[sessionId] === undefined) {
|
||||||
Logger.error(`The session "${sessionId}" is not registred.`, { sessionId });
|
Logger.error(`The session "${sessionId}" is not registered.`, { sessionId });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1748,7 +1748,7 @@ class App {
|
||||||
this.app.all(
|
this.app.all(
|
||||||
`/${this.endpointWebhookTest}/*`,
|
`/${this.endpointWebhookTest}/*`,
|
||||||
async (req: express.Request, res: express.Response) => {
|
async (req: express.Request, res: express.Response) => {
|
||||||
// Cut away the "/webhook-test/" to get the registred part of the url
|
// Cut away the "/webhook-test/" to get the registered part of the url
|
||||||
const requestUrl = (req as ICustomRequest).parsedUrl!.pathname!.slice(
|
const requestUrl = (req as ICustomRequest).parsedUrl!.pathname!.slice(
|
||||||
this.endpointWebhookTest.length + 2,
|
this.endpointWebhookTest.length + 2,
|
||||||
);
|
);
|
||||||
|
@ -1936,7 +1936,7 @@ export async function start(): Promise<void> {
|
||||||
|
|
||||||
await app.externalHooks.run('n8n.ready', [app, config]);
|
await app.externalHooks.run('n8n.ready', [app, config]);
|
||||||
const cpus = os.cpus();
|
const cpus = os.cpus();
|
||||||
const binarDataConfig = config.getEnv('binaryDataManager');
|
const binaryDataConfig = config.getEnv('binaryDataManager');
|
||||||
const diagnosticInfo: IDiagnosticInfo = {
|
const diagnosticInfo: IDiagnosticInfo = {
|
||||||
basicAuthActive: config.getEnv('security.basicAuth.active'),
|
basicAuthActive: config.getEnv('security.basicAuth.active'),
|
||||||
databaseType: (await GenericHelpers.getConfigValue('database.type')) as DatabaseType,
|
databaseType: (await GenericHelpers.getConfigValue('database.type')) as DatabaseType,
|
||||||
|
@ -1973,7 +1973,7 @@ export async function start(): Promise<void> {
|
||||||
executions_data_prune_timeout: config.getEnv('executions.pruneDataTimeout'),
|
executions_data_prune_timeout: config.getEnv('executions.pruneDataTimeout'),
|
||||||
},
|
},
|
||||||
deploymentType: config.getEnv('deployment.type'),
|
deploymentType: config.getEnv('deployment.type'),
|
||||||
binaryDataMode: binarDataConfig.mode,
|
binaryDataMode: binaryDataConfig.mode,
|
||||||
n8n_multi_user_allowed: isUserManagementEnabled(),
|
n8n_multi_user_allowed: isUserManagementEnabled(),
|
||||||
smtp_set_up: config.getEnv('userManagement.emails.mode') === 'smtp',
|
smtp_set_up: config.getEnv('userManagement.emails.mode') === 'smtp',
|
||||||
};
|
};
|
||||||
|
|
|
@ -290,7 +290,7 @@ export class TestWebhooks {
|
||||||
this.testWebhookData[webhookKey].sessionId,
|
this.testWebhookData[webhookKey].sessionId,
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Could not inform editor, probably is not connected anymore. So sipmly go on.
|
// Could not inform editor, probably is not connected anymore. So simply go on.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,7 @@ export async function checkPermissionsForExecution(
|
||||||
credentialNames.forEach((credentialName) => {
|
credentialNames.forEach((credentialName) => {
|
||||||
const credentialDetail = node.credentials![credentialName];
|
const credentialDetail = node.credentials![credentialName];
|
||||||
// If it does not contain an id, it means it is a very old
|
// If it does not contain an id, it means it is a very old
|
||||||
// workflow. Nowaways it should not happen anymore.
|
// workflow. Nowadays it should not happen anymore.
|
||||||
// Migrations should handle the case where a credential does
|
// Migrations should handle the case where a credential does
|
||||||
// not have an id.
|
// not have an id.
|
||||||
if (credentialDetail.id === null) {
|
if (credentialDetail.id === null) {
|
||||||
|
@ -189,7 +189,7 @@ export async function checkPermissionsForExecution(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// If this check happens on top, we may get
|
// If this check happens on top, we may get
|
||||||
// unitialized db errors.
|
// uninitialized db errors.
|
||||||
// Db is certainly initialized if workflow uses credentials.
|
// Db is certainly initialized if workflow uses credentials.
|
||||||
const user = await getUserById(userId);
|
const user = await getUserById(userId);
|
||||||
if (user.globalRole.name === 'owner') {
|
if (user.globalRole.name === 'owner') {
|
||||||
|
|
|
@ -43,14 +43,14 @@ export class WaitTrackerClass {
|
||||||
|
|
||||||
// Poll every 60 seconds a list of upcoming executions
|
// Poll every 60 seconds a list of upcoming executions
|
||||||
this.mainTimer = setInterval(() => {
|
this.mainTimer = setInterval(() => {
|
||||||
this.getwaitingExecutions();
|
this.getWaitingExecutions();
|
||||||
}, 60000);
|
}, 60000);
|
||||||
|
|
||||||
this.getwaitingExecutions();
|
this.getWaitingExecutions();
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||||
async getwaitingExecutions() {
|
async getWaitingExecutions() {
|
||||||
Logger.debug('Wait tracker querying database for waiting executions');
|
Logger.debug('Wait tracker querying database for waiting executions');
|
||||||
// Find all the executions which should be triggered in the next 70 seconds
|
// Find all the executions which should be triggered in the next 70 seconds
|
||||||
const findQuery: FindManyOptions<IExecutionFlattedDb> = {
|
const findQuery: FindManyOptions<IExecutionFlattedDb> = {
|
||||||
|
@ -100,7 +100,7 @@ export class WaitTrackerClass {
|
||||||
|
|
||||||
async stopExecution(executionId: string): Promise<IExecutionsStopData> {
|
async stopExecution(executionId: string): Promise<IExecutionsStopData> {
|
||||||
if (this.waitingExecutions[executionId] !== undefined) {
|
if (this.waitingExecutions[executionId] !== undefined) {
|
||||||
// The waiting execution was already sheduled to execute.
|
// The waiting execution was already scheduled to execute.
|
||||||
// So stop timer and remove.
|
// So stop timer and remove.
|
||||||
clearTimeout(this.waitingExecutions[executionId].timer);
|
clearTimeout(this.waitingExecutions[executionId].timer);
|
||||||
delete this.waitingExecutions[executionId];
|
delete this.waitingExecutions[executionId];
|
||||||
|
|
|
@ -35,7 +35,7 @@ export class WaitingWebhooks {
|
||||||
req: express.Request,
|
req: express.Request,
|
||||||
res: express.Response,
|
res: express.Response,
|
||||||
): Promise<IResponseCallbackData> {
|
): Promise<IResponseCallbackData> {
|
||||||
Logger.debug(`Received waiting-webhoook "${httpMethod}" for path "${fullPath}"`);
|
Logger.debug(`Received waiting-webhook "${httpMethod}" for path "${fullPath}"`);
|
||||||
|
|
||||||
// Reset request parameters
|
// Reset request parameters
|
||||||
req.params = {};
|
req.params = {};
|
||||||
|
|
|
@ -75,7 +75,7 @@ export function getWorkflowWebhooks(
|
||||||
workflow: Workflow,
|
workflow: Workflow,
|
||||||
additionalData: IWorkflowExecuteAdditionalData,
|
additionalData: IWorkflowExecuteAdditionalData,
|
||||||
destinationNode?: string,
|
destinationNode?: string,
|
||||||
ignoreRestartWehbooks = false,
|
ignoreRestartWebhooks = false,
|
||||||
): IWebhookData[] {
|
): IWebhookData[] {
|
||||||
// Check all the nodes in the workflow if they have webhooks
|
// Check all the nodes in the workflow if they have webhooks
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ export function getWorkflowWebhooks(
|
||||||
}
|
}
|
||||||
returnData.push.apply(
|
returnData.push.apply(
|
||||||
returnData,
|
returnData,
|
||||||
NodeHelpers.getNodeWebhooks(workflow, node, additionalData, ignoreRestartWehbooks),
|
NodeHelpers.getNodeWebhooks(workflow, node, additionalData, ignoreRestartWebhooks),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,7 +346,7 @@ export async function executeWebhook(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now that we know that the workflow should run we can return the default response
|
// Now that we know that the workflow should run we can return the default response
|
||||||
// directly if responseMode it set to "onReceived" and a respone should be sent
|
// directly if responseMode it set to "onReceived" and a response should be sent
|
||||||
if (responseMode === 'onReceived' && !didSendResponse) {
|
if (responseMode === 'onReceived' && !didSendResponse) {
|
||||||
// Return response directly and do not wait for the workflow to finish
|
// Return response directly and do not wait for the workflow to finish
|
||||||
if (responseData === 'noData') {
|
if (responseData === 'noData') {
|
||||||
|
@ -478,7 +478,7 @@ export async function executeWebhook(
|
||||||
if (!didSendResponse) {
|
if (!didSendResponse) {
|
||||||
responseCallback(null, {
|
responseCallback(null, {
|
||||||
data: {
|
data: {
|
||||||
message: 'Workflow executed sucessfully but no data was returned',
|
message: 'Workflow executed successfully but no data was returned',
|
||||||
},
|
},
|
||||||
responseCode,
|
responseCode,
|
||||||
});
|
});
|
||||||
|
@ -510,7 +510,7 @@ export async function executeWebhook(
|
||||||
// Return an error if no Webhook-Response node did send any data
|
// Return an error if no Webhook-Response node did send any data
|
||||||
responseCallback(null, {
|
responseCallback(null, {
|
||||||
data: {
|
data: {
|
||||||
message: 'Workflow executed sucessfully',
|
message: 'Workflow executed successfully',
|
||||||
},
|
},
|
||||||
responseCode,
|
responseCode,
|
||||||
});
|
});
|
||||||
|
@ -523,7 +523,7 @@ export async function executeWebhook(
|
||||||
if (!didSendResponse) {
|
if (!didSendResponse) {
|
||||||
responseCallback(null, {
|
responseCallback(null, {
|
||||||
data: {
|
data: {
|
||||||
message: 'Workflow executed sucessfully but the last node did not return any data',
|
message: 'Workflow executed successfully but the last node did not return any data',
|
||||||
},
|
},
|
||||||
responseCode,
|
responseCode,
|
||||||
});
|
});
|
||||||
|
|
|
@ -47,7 +47,7 @@ export function registerProductionWebhooks() {
|
||||||
this.app.all(
|
this.app.all(
|
||||||
`/${this.endpointWebhook}/*`,
|
`/${this.endpointWebhook}/*`,
|
||||||
async (req: express.Request, res: express.Response) => {
|
async (req: express.Request, res: express.Response) => {
|
||||||
// Cut away the "/webhook/" to get the registred part of the url
|
// Cut away the "/webhook/" to get the registered part of the url
|
||||||
const requestUrl = (req as ICustomRequest).parsedUrl!.pathname!.slice(
|
const requestUrl = (req as ICustomRequest).parsedUrl!.pathname!.slice(
|
||||||
this.endpointWebhook.length + 2,
|
this.endpointWebhook.length + 2,
|
||||||
);
|
);
|
||||||
|
@ -112,14 +112,14 @@ export function registerProductionWebhooks() {
|
||||||
this.app.all(
|
this.app.all(
|
||||||
`/${this.endpointWebhookWaiting}/*`,
|
`/${this.endpointWebhookWaiting}/*`,
|
||||||
async (req: express.Request, res: express.Response) => {
|
async (req: express.Request, res: express.Response) => {
|
||||||
// Cut away the "/webhook-waiting/" to get the registred part of the url
|
// Cut away the "/webhook-waiting/" to get the registered part of the url
|
||||||
const requestUrl = (req as ICustomRequest).parsedUrl!.pathname!.slice(
|
const requestUrl = (req as ICustomRequest).parsedUrl!.pathname!.slice(
|
||||||
this.endpointWebhookWaiting.length + 2,
|
this.endpointWebhookWaiting.length + 2,
|
||||||
);
|
);
|
||||||
|
|
||||||
const method = req.method.toUpperCase() as WebhookHttpMethod;
|
const method = req.method.toUpperCase() as WebhookHttpMethod;
|
||||||
|
|
||||||
// TOOD: Add support for OPTIONS in the future
|
// TODO: Add support for OPTIONS in the future
|
||||||
// if (method === 'OPTIONS') {
|
// if (method === 'OPTIONS') {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
|
@ -930,7 +930,7 @@ export async function executeWorkflow(
|
||||||
await checkPermissionsForExecution(workflow, additionalData.userId);
|
await checkPermissionsForExecution(workflow, additionalData.userId);
|
||||||
|
|
||||||
// Create new additionalData to have different workflow loaded and to call
|
// Create new additionalData to have different workflow loaded and to call
|
||||||
// different webooks
|
// different webhooks
|
||||||
const additionalDataIntegrated = await getBase(additionalData.userId);
|
const additionalDataIntegrated = await getBase(additionalData.userId);
|
||||||
additionalDataIntegrated.hooks = getWorkflowHooksIntegrated(
|
additionalDataIntegrated.hooks = getWorkflowHooksIntegrated(
|
||||||
runData.executionMode,
|
runData.executionMode,
|
||||||
|
@ -1059,7 +1059,7 @@ export function sendMessageToUI(source: string, messages: any[]) {
|
||||||
this.sessionId,
|
this.sessionId,
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.warn(`There was a problem sending messsage to UI: ${error.message}`);
|
Logger.warn(`There was a problem sending message to UI: ${error.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -251,7 +251,7 @@ export async function executeErrorWorkflow(
|
||||||
export function getAllNodeTypeData(): ITransferNodeTypes {
|
export function getAllNodeTypeData(): ITransferNodeTypes {
|
||||||
const nodeTypes = NodeTypes();
|
const nodeTypes = NodeTypes();
|
||||||
|
|
||||||
// Get the data of all thenode types that they
|
// Get the data of all the node types that they
|
||||||
// can be loaded again in the process
|
// can be loaded again in the process
|
||||||
const returnData: ITransferNodeTypes = {};
|
const returnData: ITransferNodeTypes = {};
|
||||||
for (const nodeTypeName of Object.keys(nodeTypes.nodeTypes)) {
|
for (const nodeTypeName of Object.keys(nodeTypes.nodeTypes)) {
|
||||||
|
|
|
@ -82,7 +82,7 @@ export class WorkflowRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The process did send a hook message so execute the appropiate hook
|
* The process did send a hook message so execute the appropriate hook
|
||||||
*
|
*
|
||||||
* @param {WorkflowHooks} workflowHooks
|
* @param {WorkflowHooks} workflowHooks
|
||||||
* @param {IProcessMessageDataHook} hookData
|
* @param {IProcessMessageDataHook} hookData
|
||||||
|
@ -469,7 +469,7 @@ export class WorkflowRunner {
|
||||||
* when Redis crashes and recovers shortly *
|
* when Redis crashes and recovers shortly *
|
||||||
* but during this time, some execution(s) *
|
* but during this time, some execution(s) *
|
||||||
* finished. The end result is that the main *
|
* finished. The end result is that the main *
|
||||||
* process will wait indefinitively and never *
|
* process will wait indefinitely and never *
|
||||||
* get a response. This adds an active polling to*
|
* get a response. This adds an active polling to*
|
||||||
* the queue that allows us to identify that the *
|
* the queue that allows us to identify that the *
|
||||||
* execution finished and get information from *
|
* execution finished and get information from *
|
||||||
|
|
|
@ -178,23 +178,23 @@ export class WorkflowRunnerProcess {
|
||||||
// Credentials should now be loaded from database.
|
// Credentials should now be loaded from database.
|
||||||
// We check if any node uses credentials. If it does, then
|
// We check if any node uses credentials. If it does, then
|
||||||
// init database.
|
// init database.
|
||||||
let shouldInitializaDb = false;
|
let shouldInitializeDb = false;
|
||||||
// eslint-disable-next-line array-callback-return
|
// eslint-disable-next-line array-callback-return
|
||||||
inputData.workflowData.nodes.map((node) => {
|
inputData.workflowData.nodes.map((node) => {
|
||||||
if (Object.keys(node.credentials === undefined ? {} : node.credentials).length > 0) {
|
if (Object.keys(node.credentials === undefined ? {} : node.credentials).length > 0) {
|
||||||
shouldInitializaDb = true;
|
shouldInitializeDb = true;
|
||||||
}
|
}
|
||||||
if (node.type === 'n8n-nodes-base.executeWorkflow') {
|
if (node.type === 'n8n-nodes-base.executeWorkflow') {
|
||||||
// With UM, child workflows from arbitrary JSON
|
// With UM, child workflows from arbitrary JSON
|
||||||
// Should be persisted by the child process,
|
// Should be persisted by the child process,
|
||||||
// so DB needs to be initialized
|
// so DB needs to be initialized
|
||||||
shouldInitializaDb = true;
|
shouldInitializeDb = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// This code has been split into 4 ifs just to make it easier to understand
|
// This code has been split into 4 ifs just to make it easier to understand
|
||||||
// Can be made smaller but in the end it will make it impossible to read.
|
// Can be made smaller but in the end it will make it impossible to read.
|
||||||
if (shouldInitializaDb) {
|
if (shouldInitializeDb) {
|
||||||
// initialize db as we need to load credentials
|
// initialize db as we need to load credentials
|
||||||
await Db.init();
|
await Db.init();
|
||||||
} else if (
|
} else if (
|
||||||
|
@ -490,7 +490,7 @@ async function sendToParentProcess(type: string, data: any): Promise<void> {
|
||||||
const workflowRunner = new WorkflowRunnerProcess();
|
const workflowRunner = new WorkflowRunnerProcess();
|
||||||
|
|
||||||
// Listen to messages from parent process which send the data of
|
// Listen to messages from parent process which send the data of
|
||||||
// the worflow to process
|
// the workflow to process
|
||||||
process.on('message', async (message: IProcessMessage) => {
|
process.on('message', async (message: IProcessMessage) => {
|
||||||
try {
|
try {
|
||||||
if (message.type === 'startWorkflow') {
|
if (message.type === 'startWorkflow') {
|
||||||
|
|
|
@ -415,7 +415,7 @@ executionsController.post(
|
||||||
const sharedWorkflowIds = await getSharedWorkflowIds(req.user);
|
const sharedWorkflowIds = await getSharedWorkflowIds(req.user);
|
||||||
const binaryDataManager = BinaryDataManager.getInstance();
|
const binaryDataManager = BinaryDataManager.getInstance();
|
||||||
|
|
||||||
// delete executions by date, if user may access the underyling workflows
|
// delete executions by date, if user may access the underlying workflows
|
||||||
|
|
||||||
if (deleteBefore) {
|
if (deleteBefore) {
|
||||||
const filters: IDataObject = {
|
const filters: IDataObject = {
|
||||||
|
@ -446,7 +446,7 @@ executionsController.post(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete executions by IDs, if user may access the underyling workflows
|
// delete executions by IDs, if user may access the underlying workflows
|
||||||
|
|
||||||
if (ids) {
|
if (ids) {
|
||||||
const executions = await Db.collections.Execution.find({
|
const executions = await Db.collections.Execution.find({
|
||||||
|
|
|
@ -232,7 +232,7 @@ test('GET /executions should fail due to invalid API Key', async () => {
|
||||||
expect(response.statusCode).toBe(401);
|
expect(response.statusCode).toBe(401);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('GET /executions should retrieve all successfull executions', async () => {
|
test('GET /executions should retrieve all successful executions', async () => {
|
||||||
const owner = await testDb.createUser({ globalRole: globalOwnerRole, apiKey: randomApiKey() });
|
const owner = await testDb.createUser({ globalRole: globalOwnerRole, apiKey: randomApiKey() });
|
||||||
|
|
||||||
const authOwnerAgent = utils.createAgent(app, {
|
const authOwnerAgent = utils.createAgent(app, {
|
||||||
|
|
|
@ -793,7 +793,7 @@ test('POST /workflows/:id/deactivate should fail due to non-existing workflow',
|
||||||
expect(response.statusCode).toBe(404);
|
expect(response.statusCode).toBe(404);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('POST /workflows/:id/deactivate should deactive workflow', async () => {
|
test('POST /workflows/:id/deactivate should deactivate workflow', async () => {
|
||||||
const member = await testDb.createUser({ globalRole: globalMemberRole, apiKey: randomApiKey() });
|
const member = await testDb.createUser({ globalRole: globalMemberRole, apiKey: randomApiKey() });
|
||||||
|
|
||||||
const authAgent = utils.createAgent(app, {
|
const authAgent = utils.createAgent(app, {
|
||||||
|
@ -837,7 +837,7 @@ test('POST /workflows/:id/deactivate should deactive workflow', async () => {
|
||||||
expect(await workflowRunner.isActive(workflow.id.toString())).toBe(false);
|
expect(await workflowRunner.isActive(workflow.id.toString())).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('POST /workflows/:id/deactivate should deactive non-owned workflow when owner', async () => {
|
test('POST /workflows/:id/deactivate should deactivate non-owned workflow when owner', async () => {
|
||||||
const owner = await testDb.createUser({ globalRole: globalOwnerRole, apiKey: randomApiKey() });
|
const owner = await testDb.createUser({ globalRole: globalOwnerRole, apiKey: randomApiKey() });
|
||||||
const member = await testDb.createUser({ globalRole: globalMemberRole });
|
const member = await testDb.createUser({ globalRole: globalMemberRole });
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ export class ActiveWebhooks {
|
||||||
webhookData.webhookId,
|
webhookData.webhookId,
|
||||||
);
|
);
|
||||||
|
|
||||||
// check that there is not a webhook already registed with that path/method
|
// check that there is not a webhook already registered with that path/method
|
||||||
if (this.webhookUrls[webhookKey] && !webhookData.webhookId) {
|
if (this.webhookUrls[webhookKey] && !webhookData.webhookId) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`The URL path that the "${webhookData.node}" node uses is already taken. Please change it to something else.`,
|
`The URL path that the "${webhookData.node}" node uses is already taken. Please change it to something else.`,
|
||||||
|
|
|
@ -7,7 +7,7 @@ export const EXTENSIONS_SUBDIRECTORY = 'custom';
|
||||||
export const USER_FOLDER_ENV_OVERWRITE = 'N8N_USER_FOLDER';
|
export const USER_FOLDER_ENV_OVERWRITE = 'N8N_USER_FOLDER';
|
||||||
export const USER_SETTINGS_FILE_NAME = 'config';
|
export const USER_SETTINGS_FILE_NAME = 'config';
|
||||||
export const USER_SETTINGS_SUBFOLDER = '.n8n';
|
export const USER_SETTINGS_SUBFOLDER = '.n8n';
|
||||||
export const PLACEHOLDER_EMPTY_EXECUTION_ID = '__UNKOWN__';
|
export const PLACEHOLDER_EMPTY_EXECUTION_ID = '__UNKNOWN__';
|
||||||
export const PLACEHOLDER_EMPTY_WORKFLOW_ID = '__EMPTY__';
|
export const PLACEHOLDER_EMPTY_WORKFLOW_ID = '__EMPTY__';
|
||||||
export const TUNNEL_SUBDOMAIN_ENV = 'N8N_TUNNEL_SUBDOMAIN';
|
export const TUNNEL_SUBDOMAIN_ENV = 'N8N_TUNNEL_SUBDOMAIN';
|
||||||
export const WAIT_TIME_UNLIMITED = '3000-01-01T00:00:00.000Z';
|
export const WAIT_TIME_UNLIMITED = '3000-01-01T00:00:00.000Z';
|
||||||
|
|
|
@ -137,7 +137,7 @@ export class LoadNodeParameterOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the available options via a load request informatoin
|
* Returns the available options via a load request information
|
||||||
*
|
*
|
||||||
* @param {ILoadOptions} loadOptions The load options which also contain the request information
|
* @param {ILoadOptions} loadOptions The load options which also contain the request information
|
||||||
* @param {IWorkflowExecuteAdditionalData} additionalData
|
* @param {IWorkflowExecuteAdditionalData} additionalData
|
||||||
|
|
|
@ -1053,7 +1053,7 @@ export async function requestOAuth2(
|
||||||
client_secret: credentials.clientSecret,
|
client_secret: credentials.clientSecret,
|
||||||
};
|
};
|
||||||
tokenRefreshOptions.body = body;
|
tokenRefreshOptions.body = body;
|
||||||
// Override authorization property so the credentails are not included in it
|
// Override authorization property so the credentials are not included in it
|
||||||
tokenRefreshOptions.headers = {
|
tokenRefreshOptions.headers = {
|
||||||
Authorization: '',
|
Authorization: '',
|
||||||
};
|
};
|
||||||
|
@ -1122,7 +1122,7 @@ export async function requestOAuth2(
|
||||||
* @export
|
* @export
|
||||||
* @param {IAllExecuteFunctions} this
|
* @param {IAllExecuteFunctions} this
|
||||||
* @param {string} credentialsType
|
* @param {string} credentialsType
|
||||||
* @param {(OptionsWithUrl | requestPromise.RequestPromiseOptions)} requestOptionså
|
* @param {(OptionsWithUrl | requestPromise.RequestPromiseOptions)} requestOptions
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export async function requestOAuth1(
|
export async function requestOAuth1(
|
||||||
|
@ -1253,7 +1253,7 @@ export async function httpRequestWithAuthentication(
|
||||||
return await httpRequest(requestOptions);
|
return await httpRequest(requestOptions);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// if there is a pre authorization method defined and
|
// if there is a pre authorization method defined and
|
||||||
// the method failed due to unathorized request
|
// the method failed due to unauthorized request
|
||||||
if (
|
if (
|
||||||
error.response?.status === 401 &&
|
error.response?.status === 401 &&
|
||||||
additionalData.credentialsHelper.preAuthentication !== undefined
|
additionalData.credentialsHelper.preAuthentication !== undefined
|
||||||
|
@ -1702,7 +1702,7 @@ export function getNodeParameter(
|
||||||
): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object {
|
): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object {
|
||||||
const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
|
const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
|
||||||
if (nodeType === undefined) {
|
if (nodeType === undefined) {
|
||||||
throw new Error(`Node type "${node.type}" is not known so can not return paramter value!`);
|
throw new Error(`Node type "${node.type}" is not known so can not return parameter value!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const value = get(node.parameters, parameterName, fallbackValue);
|
const value = get(node.parameters, parameterName, fallbackValue);
|
||||||
|
@ -2352,7 +2352,7 @@ export function getExecuteFunctions(
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||||
Logger.warn(`There was a problem sending messsage to UI: ${error.message}`);
|
Logger.warn(`There was a problem sending message to UI: ${error.message}`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async sendResponse(response: IExecuteResponsePromiseData): Promise<void> {
|
async sendResponse(response: IExecuteResponsePromiseData): Promise<void> {
|
||||||
|
|
|
@ -239,7 +239,7 @@ export function getUserSettingsPath(): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retruns the path to the n8n folder in which all n8n
|
* Returns the path to the n8n folder in which all n8n
|
||||||
* related data gets saved
|
* related data gets saved
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
|
|
@ -993,13 +993,13 @@ export class WorkflowExecute {
|
||||||
executionData.data.main[0]?.length === nodeSuccessData[0].length
|
executionData.data.main[0]?.length === nodeSuccessData[0].length
|
||||||
) {
|
) {
|
||||||
// The node has one input and one output. The number of items on both is
|
// The node has one input and one output. The number of items on both is
|
||||||
// identical so we can make the resonable asumption that each of the input
|
// identical so we can make the reasonable assumption that each of the input
|
||||||
// items is the origin of the corresponding output items
|
// items is the origin of the corresponding output items
|
||||||
item.pairedItem = {
|
item.pairedItem = {
|
||||||
item: index,
|
item: index,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// In all other cases is autofixing not possible
|
// In all other cases autofixing is not possible
|
||||||
break checkOutputData;
|
break checkOutputData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -356,7 +356,7 @@ class NodeTypesClass implements INodeTypes {
|
||||||
// The different dataTypes to check the values in
|
// The different dataTypes to check the values in
|
||||||
const dataTypes = ['boolean', 'number', 'string'];
|
const dataTypes = ['boolean', 'number', 'string'];
|
||||||
|
|
||||||
// Itterate over all items to check which ones should be output as via output "true" and
|
// Iterate over all items to check which ones should be output as via output "true" and
|
||||||
// which ones via output "false"
|
// which ones via output "false"
|
||||||
let dataType: string;
|
let dataType: string;
|
||||||
let compareOperationResult: boolean;
|
let compareOperationResult: boolean;
|
||||||
|
@ -441,7 +441,7 @@ class NodeTypesClass implements INodeTypes {
|
||||||
name: 'Pass-through',
|
name: 'Pass-through',
|
||||||
value: 'passThrough',
|
value: 'passThrough',
|
||||||
description:
|
description:
|
||||||
'Passes through data of one input. The output will conain only items of the defined input.',
|
'Passes through data of one input. The output will contain only items of the defined input.',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Wait',
|
name: 'Wait',
|
||||||
|
|
|
@ -313,14 +313,14 @@ export default mixins(
|
||||||
},
|
},
|
||||||
executionFinished (): boolean {
|
executionFinished (): boolean {
|
||||||
if (!this.isExecutionPage) {
|
if (!this.isExecutionPage) {
|
||||||
// We are not on an exeuction page so return false
|
// We are not on an execution page so return false
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fullExecution = this.$store.getters.getWorkflowExecution;
|
const fullExecution = this.$store.getters.getWorkflowExecution;
|
||||||
|
|
||||||
if (fullExecution === null) {
|
if (fullExecution === null) {
|
||||||
// No exeuction loaded so return also false
|
// No execution loaded so return also false
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,9 +437,9 @@ export default mixins(
|
||||||
reader.onload = (event: ProgressEvent) => {
|
reader.onload = (event: ProgressEvent) => {
|
||||||
const data = (event.target as FileReader).result;
|
const data = (event.target as FileReader).result;
|
||||||
|
|
||||||
let worflowData: IWorkflowDataUpdate;
|
let workflowData: IWorkflowDataUpdate;
|
||||||
try {
|
try {
|
||||||
worflowData = JSON.parse(data as string);
|
workflowData = JSON.parse(data as string);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.$showMessage({
|
this.$showMessage({
|
||||||
title: this.$locale.baseText('mainSidebar.showMessage.handleFileImport.title'),
|
title: this.$locale.baseText('mainSidebar.showMessage.handleFileImport.title'),
|
||||||
|
@ -449,7 +449,7 @@ export default mixins(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$root.$emit('importWorkflowData', { data: worflowData });
|
this.$root.$emit('importWorkflowData', { data: workflowData });
|
||||||
};
|
};
|
||||||
|
|
||||||
const input = this.$refs.importFile as HTMLInputElement;
|
const input = this.$refs.importFile as HTMLInputElement;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-if="webhooksNode.length" class="webhoooks">
|
<div v-if="webhooksNode.length" class="webhooks">
|
||||||
<div class="clickable headline" :class="{expanded: !isMinimized}" @click="isMinimized=!isMinimized" :title="isMinimized ? $locale.baseText('nodeWebhooks.clickToDisplayWebhookUrls') : $locale.baseText('nodeWebhooks.clickToHideWebhookUrls')">
|
<div class="clickable headline" :class="{expanded: !isMinimized}" @click="isMinimized=!isMinimized" :title="isMinimized ? $locale.baseText('nodeWebhooks.clickToDisplayWebhookUrls') : $locale.baseText('nodeWebhooks.clickToHideWebhookUrls')">
|
||||||
<font-awesome-icon icon="angle-down" class="minimize-button minimize-icon" />
|
<font-awesome-icon icon="angle-down" class="minimize-button minimize-icon" />
|
||||||
{{ $locale.baseText('nodeWebhooks.webhookUrls') }}
|
{{ $locale.baseText('nodeWebhooks.webhookUrls') }}
|
||||||
|
@ -110,7 +110,7 @@ export default mixins(
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|
||||||
.webhoooks {
|
.webhooks {
|
||||||
padding-bottom: var(--spacing-xs);
|
padding-bottom: var(--spacing-xs);
|
||||||
margin: var(--spacing-xs) 0;
|
margin: var(--spacing-xs) 0;
|
||||||
border-bottom: 1px solid var(--color-text-lighter);
|
border-bottom: 1px solid var(--color-text-lighter);
|
||||||
|
|
|
@ -991,11 +991,11 @@ export default mixins(
|
||||||
// Reload function on change element from
|
// Reload function on change element from
|
||||||
// displayOptions.typeOptions.reloadOnChange parameters
|
// displayOptions.typeOptions.reloadOnChange parameters
|
||||||
if (this.parameter.typeOptions && this.parameter.typeOptions.reloadOnChange) {
|
if (this.parameter.typeOptions && this.parameter.typeOptions.reloadOnChange) {
|
||||||
// Get all paramter in reloadOnChange property
|
// Get all parameter in reloadOnChange property
|
||||||
// This reload when parameters in reloadOnChange is updated
|
// This reload when parameters in reloadOnChange is updated
|
||||||
const paramtersOnChange : string[] = this.parameter.typeOptions.reloadOnChange;
|
const parametersOnChange : string[] = this.parameter.typeOptions.reloadOnChange;
|
||||||
for (let i = 0; i < paramtersOnChange.length; i++) {
|
for (let i = 0; i < parametersOnChange.length; i++) {
|
||||||
const parameter = paramtersOnChange[i] as string;
|
const parameter = parametersOnChange[i] as string;
|
||||||
if (parameter in this.node.parameters) {
|
if (parameter in this.node.parameters) {
|
||||||
this.$watch(() => {
|
this.$watch(() => {
|
||||||
if (this.node && this.node.parameters && this.node.parameters[parameter]) {
|
if (this.node && this.node.parameters && this.node.parameters[parameter]) {
|
||||||
|
|
|
@ -116,7 +116,7 @@ export const copyPaste = Vue.extend({
|
||||||
this.standardClipboardEvent(event, e as ClipboardEvent);
|
this.standardClipboardEvent(event, e as ClipboardEvent);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (!document.activeElement || (document.activeElement && ['textarea', 'text', 'email', 'password'].indexOf(document.activeElement.type) === -1)) {
|
if (!document.activeElement || (document.activeElement && ['textarea', 'text', 'email', 'password'].indexOf(document.activeElement.type) === -1)) {
|
||||||
// That it still allows to paste into text, email, password & textarea-fiels we
|
// That it still allows to paste into text, email, password & textarea-fields we
|
||||||
// check if we can identify the active element and if so only
|
// check if we can identify the active element and if so only
|
||||||
// run it if something else is selected.
|
// run it if something else is selected.
|
||||||
this.focusHiddenArea(hiddenInput);
|
this.focusHiddenArea(hiddenInput);
|
||||||
|
|
|
@ -135,7 +135,7 @@ export const mouseSelect = mixins(
|
||||||
this.deselectAllNodes();
|
this.deselectAllNodes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If it is not active return direcly.
|
// If it is not active return directly.
|
||||||
// Else normal node dragging will not work.
|
// Else normal node dragging will not work.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ export const moveNodeWorkflow = mixins(
|
||||||
},
|
},
|
||||||
mouseUpMoveWorkflow (e: MouseEvent) {
|
mouseUpMoveWorkflow (e: MouseEvent) {
|
||||||
if (this.$store.getters.isNodeViewMoveInProgress === false) {
|
if (this.$store.getters.isNodeViewMoveInProgress === false) {
|
||||||
// If it is not active return direcly.
|
// If it is not active return directly.
|
||||||
// Else normal node dragging will not work.
|
// Else normal node dragging will not work.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -251,14 +251,14 @@ export const nodeBase = mixins(
|
||||||
// even though "start" and "drag" gets called for all. So lets do for now
|
// even though "start" and "drag" gets called for all. So lets do for now
|
||||||
// some dirty DOM query to get the new positions till I have more time to
|
// some dirty DOM query to get the new positions till I have more time to
|
||||||
// create a proper solution
|
// create a proper solution
|
||||||
let newNodePositon: XYPosition;
|
let newNodePosition: XYPosition;
|
||||||
moveNodes.forEach((node: INodeUi) => {
|
moveNodes.forEach((node: INodeUi) => {
|
||||||
const element = document.getElementById(node.id);
|
const element = document.getElementById(node.id);
|
||||||
if (element === null) {
|
if (element === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
newNodePositon = [
|
newNodePosition = [
|
||||||
parseInt(element.style.left!.slice(0, -2), 10),
|
parseInt(element.style.left!.slice(0, -2), 10),
|
||||||
parseInt(element.style.top!.slice(0, -2), 10),
|
parseInt(element.style.top!.slice(0, -2), 10),
|
||||||
];
|
];
|
||||||
|
@ -267,7 +267,7 @@ export const nodeBase = mixins(
|
||||||
name: node.name,
|
name: node.name,
|
||||||
properties: {
|
properties: {
|
||||||
// @ts-ignore, draggable does not have definitions
|
// @ts-ignore, draggable does not have definitions
|
||||||
position: newNodePositon,
|
position: newNodePosition,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ export const workflowHelpers = mixins(
|
||||||
[inputName]: workflowRunData[currentNode][runIndex].source!,
|
[inputName]: workflowRunData[currentNode][runIndex].source!,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// The curent node did not get executed in UI yet so build data manually
|
// The current node did not get executed in UI yet so build data manually
|
||||||
executeData.source = {
|
executeData.source = {
|
||||||
[inputName]: [
|
[inputName]: [
|
||||||
{
|
{
|
||||||
|
@ -183,7 +183,7 @@ export const workflowHelpers = mixins(
|
||||||
return returnNodes;
|
return returnNodes;
|
||||||
},
|
},
|
||||||
|
|
||||||
// Returns data about nodeTypes which ahve a "maxNodes" limit set.
|
// Returns data about nodeTypes which have a "maxNodes" limit set.
|
||||||
// For each such type does it return how high the limit is, how many
|
// For each such type does it return how high the limit is, how many
|
||||||
// already exist and the name of this nodes.
|
// already exist and the name of this nodes.
|
||||||
getNodeTypesMaxCount (): INodeTypesMaxCount {
|
getNodeTypesMaxCount (): INodeTypesMaxCount {
|
||||||
|
@ -239,7 +239,7 @@ export const workflowHelpers = mixins(
|
||||||
checkNodes = workflow.getParentNodes(lastNodeName);
|
checkNodes = workflow.getParentNodes(lastNodeName);
|
||||||
checkNodes.push(lastNodeName);
|
checkNodes.push(lastNodeName);
|
||||||
} else {
|
} else {
|
||||||
// As webhook nodes always take presidence check first
|
// As webhook nodes always take precedence check first
|
||||||
// if there are any
|
// if there are any
|
||||||
let checkWebhook: string[] = [];
|
let checkWebhook: string[] = [];
|
||||||
for (const nodeName of Object.keys(workflow.nodes)) {
|
for (const nodeName of Object.keys(workflow.nodes)) {
|
||||||
|
@ -430,10 +430,10 @@ export const workflowHelpers = mixins(
|
||||||
|
|
||||||
// Add the node credentials if there are some set and if they should be displayed
|
// Add the node credentials if there are some set and if they should be displayed
|
||||||
if (node.credentials !== undefined && nodeType.credentials !== undefined) {
|
if (node.credentials !== undefined && nodeType.credentials !== undefined) {
|
||||||
const saveCredenetials: INodeCredentials = {};
|
const saveCredentials: INodeCredentials = {};
|
||||||
for (const nodeCredentialTypeName of Object.keys(node.credentials)) {
|
for (const nodeCredentialTypeName of Object.keys(node.credentials)) {
|
||||||
if (this.hasProxyAuth(node) || Object.keys(node.parameters).includes('genericAuthType')) {
|
if (this.hasProxyAuth(node) || Object.keys(node.parameters).includes('genericAuthType')) {
|
||||||
saveCredenetials[nodeCredentialTypeName] = node.credentials[nodeCredentialTypeName];
|
saveCredentials[nodeCredentialTypeName] = node.credentials[nodeCredentialTypeName];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,12 +452,12 @@ export const workflowHelpers = mixins(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveCredenetials[nodeCredentialTypeName] = node.credentials[nodeCredentialTypeName];
|
saveCredentials[nodeCredentialTypeName] = node.credentials[nodeCredentialTypeName];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set credential property only if it has content
|
// Set credential property only if it has content
|
||||||
if (Object.keys(saveCredenetials).length !== 0) {
|
if (Object.keys(saveCredentials).length !== 0) {
|
||||||
nodeData.credentials = saveCredenetials;
|
nodeData.credentials = saveCredentials;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -284,8 +284,8 @@ const module: Module<IUiState, IRootState> = {
|
||||||
setDraggableCanDrop(state: IUiState, canDrop: boolean) {
|
setDraggableCanDrop(state: IUiState, canDrop: boolean) {
|
||||||
Vue.set(state.draggable, 'canDrop', canDrop);
|
Vue.set(state.draggable, 'canDrop', canDrop);
|
||||||
},
|
},
|
||||||
setMappingTelemetry(state: IUiState, telemetery: {[key: string]: string | number | boolean}) {
|
setMappingTelemetry(state: IUiState, telemetry: {[key: string]: string | number | boolean}) {
|
||||||
state.ndv.mappingTelemetry = {...state.ndv.mappingTelemetry, ...telemetery};
|
state.ndv.mappingTelemetry = {...state.ndv.mappingTelemetry, ...telemetry};
|
||||||
},
|
},
|
||||||
resetMappingTelemetry(state: IUiState) {
|
resetMappingTelemetry(state: IUiState) {
|
||||||
state.ndv.mappingTelemetry = {};
|
state.ndv.mappingTelemetry = {};
|
||||||
|
|
|
@ -181,7 +181,7 @@ function getPersonalizationV2(answers: IPersonalizationSurveyAnswersV2 | IPerson
|
||||||
nodeTypes = nodeTypes.concat(SWITCH_NODE_TYPE);
|
nodeTypes = nodeTypes.concat(SWITCH_NODE_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// slot 4 usecase #1
|
// slot 4 use case #1
|
||||||
if (companySize === COMPANY_SIZE_500_999 || companySize === COMPANY_SIZE_1000_OR_MORE) {
|
if (companySize === COMPANY_SIZE_500_999 || companySize === COMPANY_SIZE_1000_OR_MORE) {
|
||||||
switch (automationGoal) {
|
switch (automationGoal) {
|
||||||
case CUSTOMER_INTEGRATIONS_GOAL:
|
case CUSTOMER_INTEGRATIONS_GOAL:
|
||||||
|
|
|
@ -2602,7 +2602,7 @@ export default mixins(
|
||||||
const workflow = this.getCurrentWorkflow(true);
|
const workflow = this.getCurrentWorkflow(true);
|
||||||
workflow.renameNode(currentName, newName);
|
workflow.renameNode(currentName, newName);
|
||||||
|
|
||||||
// Update also last selected node and exeuction data
|
// Update also last selected node and execution data
|
||||||
this.$store.commit('renameNodeSelectedAndExecution', { old: currentName, new: newName });
|
this.$store.commit('renameNodeSelectedAndExecution', { old: currentName, new: newName });
|
||||||
|
|
||||||
// Reset all nodes and connections to load the new ones
|
// Reset all nodes and connections to load the new ones
|
||||||
|
|
|
@ -136,7 +136,7 @@ export class New extends Command {
|
||||||
// File does not exist. That is exactly what we want so go on.
|
// File does not exist. That is exactly what we want so go on.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that the variables in the template file get formated
|
// Make sure that the variables in the template file get formatted
|
||||||
// in the correct way
|
// in the correct way
|
||||||
const replaceValues = {
|
const replaceValues = {
|
||||||
ClassNameReplace: changeCase.pascalCase(nodeName),
|
ClassNameReplace: changeCase.pascalCase(nodeName),
|
||||||
|
@ -147,7 +147,7 @@ export class New extends Command {
|
||||||
|
|
||||||
await createTemplate(sourceFilePath, destinationFilePath, replaceValues);
|
await createTemplate(sourceFilePath, destinationFilePath, replaceValues);
|
||||||
|
|
||||||
this.log('\nExecution was successfull:');
|
this.log('\nExecution was successful:');
|
||||||
this.log('====================================');
|
this.log('====================================');
|
||||||
|
|
||||||
this.log(`Node got created: ${destinationFilePath}`);
|
this.log(`Node got created: ${destinationFilePath}`);
|
||||||
|
|
|
@ -33,7 +33,7 @@ export async function createCustomTsconfig() {
|
||||||
// Get path to simple tsconfig file which should be used for build
|
// Get path to simple tsconfig file which should be used for build
|
||||||
const tsconfigPath = join(__dirname, '../../src/tsconfig-build.json');
|
const tsconfigPath = join(__dirname, '../../src/tsconfig-build.json');
|
||||||
|
|
||||||
// Read the tsconfi file
|
// Read the tsconfig file
|
||||||
const tsConfigString = await fsReadFile(tsconfigPath, { encoding: 'utf8' });
|
const tsConfigString = await fsReadFile(tsconfigPath, { encoding: 'utf8' });
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
const tsConfig = JSON.parse(tsConfigString);
|
const tsConfig = JSON.parse(tsConfigString);
|
||||||
|
|
|
@ -34,7 +34,7 @@ export class ClassNameReplace implements INodeType {
|
||||||
let item: INodeExecutionData;
|
let item: INodeExecutionData;
|
||||||
let myString: string;
|
let myString: string;
|
||||||
|
|
||||||
// Itterates over all input items and add the key "myString" with the
|
// Iterates over all input items and add the key "myString" with the
|
||||||
// value the parameter "myString" resolves to.
|
// value the parameter "myString" resolves to.
|
||||||
// (This could be a different value for each item in case it contains an expression)
|
// (This could be a different value for each item in case it contains an expression)
|
||||||
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
||||||
|
|
|
@ -40,7 +40,7 @@ export class GithubOAuth2Api implements ICredentialType {
|
||||||
name: 'scope',
|
name: 'scope',
|
||||||
type: 'hidden',
|
type: 'hidden',
|
||||||
default:
|
default:
|
||||||
'repo,admin:repo_hook,admin:org,admin:org_hook,gist,notifications,user,write:packages,read:packages,delete:packages,worfklow',
|
'repo,admin:repo_hook,admin:org,admin:org_hook,gist,notifications,user,write:packages,read:packages,delete:packages,workflow',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Auth URI Query Parameters',
|
displayName: 'Auth URI Query Parameters',
|
||||||
|
|
|
@ -491,7 +491,7 @@ export class GithubTrigger implements INodeType {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is a regular webhoook call
|
// Is a regular webhook call
|
||||||
|
|
||||||
// TODO: Add headers & requestPath
|
// TODO: Add headers & requestPath
|
||||||
const returnData: IDataObject[] = [];
|
const returnData: IDataObject[] = [];
|
||||||
|
|
|
@ -799,7 +799,7 @@ export class HttpRequest implements INodeType {
|
||||||
},
|
},
|
||||||
queryParametersJson: {
|
queryParametersJson: {
|
||||||
name: 'qs',
|
name: 'qs',
|
||||||
displayName: 'Query Paramters',
|
displayName: 'Query Parameters',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let returnItems: INodeExecutionData[] = [];
|
let returnItems: INodeExecutionData[] = [];
|
||||||
|
@ -885,7 +885,7 @@ export class HttpRequest implements INodeType {
|
||||||
const contentTypesAllowed = ['raw', 'multipart-form-data'];
|
const contentTypesAllowed = ['raw', 'multipart-form-data'];
|
||||||
|
|
||||||
if (!contentTypesAllowed.includes(options.bodyContentType as string)) {
|
if (!contentTypesAllowed.includes(options.bodyContentType as string)) {
|
||||||
// As n8n-workflow.NodeHelpers.getParamterResolveOrder can not be changed
|
// As n8n-workflow.NodeHelpers.getParameterResolveOrder can not be changed
|
||||||
// easily to handle parameters in dot.notation simply error for now.
|
// easily to handle parameters in dot.notation simply error for now.
|
||||||
throw new NodeOperationError(
|
throw new NodeOperationError(
|
||||||
this.getNode(),
|
this.getNode(),
|
||||||
|
@ -972,7 +972,7 @@ export class HttpRequest implements INodeType {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tempValue === '') {
|
if (tempValue === '') {
|
||||||
// Paramter is empty so skip it
|
// Parameter is empty so skip it
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -998,7 +998,7 @@ export class HttpRequest implements INodeType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Paramters are defined in UI
|
// Parameters are defined in UI
|
||||||
let optionName: string;
|
let optionName: string;
|
||||||
for (const parameterName of Object.keys(uiParameters)) {
|
for (const parameterName of Object.keys(uiParameters)) {
|
||||||
setUiParameter = this.getNodeParameter(parameterName, itemIndex, {}) as IDataObject;
|
setUiParameter = this.getNodeParameter(parameterName, itemIndex, {}) as IDataObject;
|
||||||
|
|
|
@ -55,7 +55,7 @@ export class Expression {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves the paramter value. If it is an expression it will execute it and
|
* Resolves the parameter value. If it is an expression it will execute it and
|
||||||
* return the result. For everything simply the supplied value will be returned.
|
* return the result. For everything simply the supplied value will be returned.
|
||||||
*
|
*
|
||||||
* @param {NodeParameterValue} parameterValue
|
* @param {NodeParameterValue} parameterValue
|
||||||
|
|
|
@ -112,7 +112,7 @@ export abstract class ICredentials {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defines which nodes are allowed to access the credentials and
|
// Defines which nodes are allowed to access the credentials and
|
||||||
// when that access got grented from which user
|
// when that access got granted from which user
|
||||||
export interface ICredentialNodeAccess {
|
export interface ICredentialNodeAccess {
|
||||||
nodeType: string;
|
nodeType: string;
|
||||||
user?: string;
|
user?: string;
|
||||||
|
@ -447,7 +447,7 @@ export interface IGetExecuteWebhookFunctions {
|
||||||
|
|
||||||
export interface ISourceDataConnections {
|
export interface ISourceDataConnections {
|
||||||
// Key for each input type and because there can be multiple inputs of the same type it is an array
|
// Key for each input type and because there can be multiple inputs of the same type it is an array
|
||||||
// null is also allowed because if we still need data for a later while executing the workflow set teompoary to null
|
// null is also allowed because if we still need data for a later while executing the workflow set temporary to null
|
||||||
// the nodes get as input TaskDataConnections which is identical to this one except that no null is allowed.
|
// the nodes get as input TaskDataConnections which is identical to this one except that no null is allowed.
|
||||||
[key: string]: Array<ISourceData[] | null>;
|
[key: string]: Array<ISourceData[] | null>;
|
||||||
}
|
}
|
||||||
|
@ -1020,7 +1020,7 @@ export interface INodeType {
|
||||||
[key: string]: (this: ILoadOptionsFunctions) => Promise<INodePropertyOptions[]>;
|
[key: string]: (this: ILoadOptionsFunctions) => Promise<INodePropertyOptions[]>;
|
||||||
};
|
};
|
||||||
credentialTest?: {
|
credentialTest?: {
|
||||||
// Contains a group of functins that test credentials.
|
// Contains a group of functions that test credentials.
|
||||||
[functionName: string]: ICredentialTestFunction;
|
[functionName: string]: ICredentialTestFunction;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -1371,10 +1371,10 @@ export interface ISourceData {
|
||||||
previousNodeRun?: number; // If undefined "0" gets used
|
previousNodeRun?: number; // If undefined "0" gets used
|
||||||
}
|
}
|
||||||
|
|
||||||
// The data for all the different kind of connectons (like main) and all the indexes
|
// The data for all the different kind of connections (like main) and all the indexes
|
||||||
export interface ITaskDataConnections {
|
export interface ITaskDataConnections {
|
||||||
// Key for each input type and because there can be multiple inputs of the same type it is an array
|
// Key for each input type and because there can be multiple inputs of the same type it is an array
|
||||||
// null is also allowed because if we still need data for a later while executing the workflow set teompoary to null
|
// null is also allowed because if we still need data for a later while executing the workflow set temporary to null
|
||||||
// the nodes get as input TaskDataConnections which is identical to this one except that no null is allowed.
|
// the nodes get as input TaskDataConnections which is identical to this one except that no null is allowed.
|
||||||
[key: string]: Array<INodeExecutionData[] | null>;
|
[key: string]: Array<INodeExecutionData[] | null>;
|
||||||
}
|
}
|
||||||
|
@ -1390,7 +1390,7 @@ export interface IWaitingForExecution {
|
||||||
|
|
||||||
export interface ITaskDataConnectionsSource {
|
export interface ITaskDataConnectionsSource {
|
||||||
// Key for each input type and because there can be multiple inputs of the same type it is an array
|
// Key for each input type and because there can be multiple inputs of the same type it is an array
|
||||||
// null is also allowed because if we still need data for a later while executing the workflow set teompoary to null
|
// null is also allowed because if we still need data for a later while executing the workflow set temporary to null
|
||||||
// the nodes get as input TaskDataConnections which is identical to this one except that no null is allowed.
|
// the nodes get as input TaskDataConnections which is identical to this one except that no null is allowed.
|
||||||
[key: string]: Array<ISourceData | null>;
|
[key: string]: Array<ISourceData | null>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -470,7 +470,7 @@ export function getParamterResolveOrder(
|
||||||
): number[] {
|
): number[] {
|
||||||
const executionOrder: number[] = [];
|
const executionOrder: number[] = [];
|
||||||
const indexToResolve = Array.from({ length: nodePropertiesArray.length }, (v, k) => k);
|
const indexToResolve = Array.from({ length: nodePropertiesArray.length }, (v, k) => k);
|
||||||
const resolvedParamters: string[] = [];
|
const resolvedParameters: string[] = [];
|
||||||
|
|
||||||
let index: number;
|
let index: number;
|
||||||
let property: INodeProperties;
|
let property: INodeProperties;
|
||||||
|
@ -489,18 +489,18 @@ export function getParamterResolveOrder(
|
||||||
if (parameterDependencies[property.name].length === 0) {
|
if (parameterDependencies[property.name].length === 0) {
|
||||||
// Does not have any dependencies so simply add
|
// Does not have any dependencies so simply add
|
||||||
executionOrder.push(index);
|
executionOrder.push(index);
|
||||||
resolvedParamters.push(property.name);
|
resolvedParameters.push(property.name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parameter has dependencies
|
// Parameter has dependencies
|
||||||
for (const dependency of parameterDependencies[property.name]) {
|
for (const dependency of parameterDependencies[property.name]) {
|
||||||
if (!resolvedParamters.includes(dependency)) {
|
if (!resolvedParameters.includes(dependency)) {
|
||||||
if (dependency.charAt(0) === '/') {
|
if (dependency.charAt(0) === '/') {
|
||||||
// Assume that root level depenencies are resolved
|
// Assume that root level dependencies are resolved
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Dependencies for that paramter are still missing so
|
// Dependencies for that parameter are still missing so
|
||||||
// try to add again later
|
// try to add again later
|
||||||
indexToResolve.push(index);
|
indexToResolve.push(index);
|
||||||
continue;
|
continue;
|
||||||
|
@ -509,7 +509,7 @@ export function getParamterResolveOrder(
|
||||||
|
|
||||||
// All dependencies got found so add
|
// All dependencies got found so add
|
||||||
executionOrder.push(index);
|
executionOrder.push(index);
|
||||||
resolvedParamters.push(property.name);
|
resolvedParameters.push(property.name);
|
||||||
|
|
||||||
if (indexToResolve.length < lastIndexLength) {
|
if (indexToResolve.length < lastIndexLength) {
|
||||||
lastIndexReduction = iterations;
|
lastIndexReduction = iterations;
|
||||||
|
@ -517,7 +517,7 @@ export function getParamterResolveOrder(
|
||||||
|
|
||||||
if (iterations > lastIndexReduction + nodePropertiesArray.length) {
|
if (iterations > lastIndexReduction + nodePropertiesArray.length) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'Could not resolve parameter depenencies. Max iterations reached! Hint: If `displayOptions` are specified in any child parameter of a parent `collection` or `fixedCollection`, remove the `displayOptions` from the child parameter.',
|
'Could not resolve parameter dependencies. Max iterations reached! Hint: If `displayOptions` are specified in any child parameter of a parent `collection` or `fixedCollection`, remove the `displayOptions` from the child parameter.',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
lastIndexLength = indexToResolve.length;
|
lastIndexLength = indexToResolve.length;
|
||||||
|
@ -889,7 +889,7 @@ export function getNodeWebhooks(
|
||||||
workflow: Workflow,
|
workflow: Workflow,
|
||||||
node: INode,
|
node: INode,
|
||||||
additionalData: IWorkflowExecuteAdditionalData,
|
additionalData: IWorkflowExecuteAdditionalData,
|
||||||
ignoreRestartWehbooks = false,
|
ignoreRestartWebhooks = false,
|
||||||
): IWebhookData[] {
|
): IWebhookData[] {
|
||||||
if (node.disabled === true) {
|
if (node.disabled === true) {
|
||||||
// Node is disabled so webhooks will also not be enabled
|
// Node is disabled so webhooks will also not be enabled
|
||||||
|
@ -908,7 +908,7 @@ export function getNodeWebhooks(
|
||||||
|
|
||||||
const returnData: IWebhookData[] = [];
|
const returnData: IWebhookData[] = [];
|
||||||
for (const webhookDescription of nodeType.description.webhooks) {
|
for (const webhookDescription of nodeType.description.webhooks) {
|
||||||
if (ignoreRestartWehbooks && webhookDescription.restartWebhook === true) {
|
if (ignoreRestartWebhooks && webhookDescription.restartWebhook === true) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1145,7 +1145,7 @@ export function addToIssuesIfMissing(
|
||||||
(nodeProperties.type === 'dateTime' && value === undefined) ||
|
(nodeProperties.type === 'dateTime' && value === undefined) ||
|
||||||
(nodeProperties.type === 'options' && (value === '' || value === undefined))
|
(nodeProperties.type === 'options' && (value === '' || value === undefined))
|
||||||
) {
|
) {
|
||||||
// Parameter is requried but empty
|
// Parameter is required but empty
|
||||||
if (foundIssues.parameters === undefined) {
|
if (foundIssues.parameters === undefined) {
|
||||||
foundIssues.parameters = {};
|
foundIssues.parameters = {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ export function create(
|
||||||
// eslint-disable-next-line no-param-reassign, @typescript-eslint/prefer-nullish-coalescing
|
// eslint-disable-next-line no-param-reassign, @typescript-eslint/prefer-nullish-coalescing
|
||||||
depth = depth || 0;
|
depth = depth || 0;
|
||||||
|
|
||||||
// Make all the children of target also observeable
|
// Make all the children of target also observable
|
||||||
// eslint-disable-next-line no-restricted-syntax
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
for (const key in target) {
|
for (const key in target) {
|
||||||
if (typeof target[key] === 'object' && target[key] !== null) {
|
if (typeof target[key] === 'object' && target[key] !== null) {
|
||||||
|
|
|
@ -82,7 +82,7 @@ export class Workflow {
|
||||||
settings: IWorkflowSettings;
|
settings: IWorkflowSettings;
|
||||||
|
|
||||||
// To save workflow specific static data like for example
|
// To save workflow specific static data like for example
|
||||||
// ids of registred webhooks of nodes
|
// ids of registered webhooks of nodes
|
||||||
staticData: IDataObject;
|
staticData: IDataObject;
|
||||||
|
|
||||||
pinData?: IPinData;
|
pinData?: IPinData;
|
||||||
|
@ -134,7 +134,7 @@ export class Workflow {
|
||||||
}
|
}
|
||||||
this.connectionsBySourceNode = parameters.connections;
|
this.connectionsBySourceNode = parameters.connections;
|
||||||
|
|
||||||
// Save also the connections by the destionation nodes
|
// Save also the connections by the destination nodes
|
||||||
this.connectionsByDestinationNode = this.__getConnectionsByDestination(parameters.connections);
|
this.connectionsByDestinationNode = this.__getConnectionsByDestination(parameters.connections);
|
||||||
|
|
||||||
this.active = parameters.active || false;
|
this.active = parameters.active || false;
|
||||||
|
@ -544,7 +544,7 @@ export class Workflow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the updated connections to create updated connections by destionation nodes
|
// Use the updated connections to create updated connections by destination nodes
|
||||||
this.connectionsByDestinationNode = this.__getConnectionsByDestination(
|
this.connectionsByDestinationNode = this.__getConnectionsByDestination(
|
||||||
this.connectionsBySourceNode,
|
this.connectionsBySourceNode,
|
||||||
);
|
);
|
||||||
|
@ -951,7 +951,7 @@ export class Workflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the start node to start the worfklow from
|
* Returns the start node to start the workflow from
|
||||||
*
|
*
|
||||||
* @param {string} [destinationNode]
|
* @param {string} [destinationNode]
|
||||||
* @returns {(INode | undefined)}
|
* @returns {(INode | undefined)}
|
||||||
|
|
|
@ -445,7 +445,7 @@ export class WorkflowDataProxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a proxt to query data from the workflow
|
* Returns a proxy to query data from the workflow
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @returns
|
* @returns
|
||||||
|
@ -693,12 +693,12 @@ export class WorkflowDataProxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sourceData === null) {
|
if (sourceData === null) {
|
||||||
// 'Could not resolve, proably no pairedItem exists.'
|
// 'Could not resolve, probably no pairedItem exists.'
|
||||||
throw createExpressionError(
|
throw createExpressionError(
|
||||||
'Can’t get data for expression',
|
'Can’t get data for expression',
|
||||||
{
|
{
|
||||||
messageTemplate: `Can’t get data for expression under ‘%%PARAMETER%%’`,
|
messageTemplate: `Can’t get data for expression under ‘%%PARAMETER%%’`,
|
||||||
description: `Could not resolve, proably no pairedItem exists`,
|
description: `Could not resolve, probably no pairedItem exists`,
|
||||||
},
|
},
|
||||||
nodeBeforeLast,
|
nodeBeforeLast,
|
||||||
);
|
);
|
||||||
|
|
|
@ -163,7 +163,7 @@ export function getNodeParameter(
|
||||||
): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object {
|
): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object {
|
||||||
const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
|
const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
|
||||||
if (nodeType === undefined) {
|
if (nodeType === undefined) {
|
||||||
throw new Error(`Node type "${node.type}" is not known so can not return paramter value!`);
|
throw new Error(`Node type "${node.type}" is not known so can not return parameter value!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const value = get(node.parameters, parameterName, fallbackValue);
|
const value = get(node.parameters, parameterName, fallbackValue);
|
||||||
|
@ -329,7 +329,7 @@ export function getExecuteFunctions(
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||||
console.error(`There was a problem sending messsage to UI: ${error.message}`);
|
console.error(`There was a problem sending message to UI: ${error.message}`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async sendResponse(response: IExecuteResponsePromiseData): Promise<void> {
|
async sendResponse(response: IExecuteResponsePromiseData): Promise<void> {
|
||||||
|
|
|
@ -2249,7 +2249,7 @@ describe('Workflow', () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description:
|
description:
|
||||||
'One property which is dependeny on two identically named properties of which only one gets displayed with different options. No value set at all.',
|
'One property which is dependency on two identically named properties of which only one gets displayed with different options. No value set at all.',
|
||||||
input: {
|
input: {
|
||||||
nodePropertiesArray: [
|
nodePropertiesArray: [
|
||||||
{
|
{
|
||||||
|
@ -2360,7 +2360,7 @@ describe('Workflow', () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description:
|
description:
|
||||||
'One property which is dependeny on two identically named properties of which only one gets displayed with different options. No value set at all. Order reversed',
|
'One property which is dependency on two identically named properties of which only one gets displayed with different options. No value set at all. Order reversed',
|
||||||
input: {
|
input: {
|
||||||
nodePropertiesArray: [
|
nodePropertiesArray: [
|
||||||
{
|
{
|
||||||
|
@ -2471,7 +2471,7 @@ describe('Workflow', () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description:
|
description:
|
||||||
'One property which is dependeny on two identically named properties of which only one gets displayed with different options. No value set at all.',
|
'One property which is dependency on two identically named properties of which only one gets displayed with different options. No value set at all.',
|
||||||
input: {
|
input: {
|
||||||
nodePropertiesArray: [
|
nodePropertiesArray: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -167,7 +167,7 @@ describe('RoutingNode', () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: 'mutliple parameters, complex example with everything',
|
description: 'multiple parameters, complex example with everything',
|
||||||
input: {
|
input: {
|
||||||
nodeParameters: {
|
nodeParameters: {
|
||||||
multipleFields: {
|
multipleFields: {
|
||||||
|
@ -967,7 +967,7 @@ describe('RoutingNode', () => {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: 'mutliple parameters, complex example with everything',
|
description: 'multiple parameters, complex example with everything',
|
||||||
input: {
|
input: {
|
||||||
node: {
|
node: {
|
||||||
parameters: {
|
parameters: {
|
||||||
|
@ -1573,7 +1573,7 @@ describe('RoutingNode', () => {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: 'single parameter, mutliple postReceive: rootProperty, setKeyValue, sort',
|
description: 'single parameter, multiple postReceive: rootProperty, setKeyValue, sort',
|
||||||
input: {
|
input: {
|
||||||
nodeType: {
|
nodeType: {
|
||||||
requestDefaults: {
|
requestDefaults: {
|
||||||
|
|
|
@ -972,7 +972,7 @@ describe('Workflow', () => {
|
||||||
},
|
},
|
||||||
// TODO: Make that this test does not fail!
|
// TODO: Make that this test does not fail!
|
||||||
// {
|
// {
|
||||||
// description: 'return resolved value when short "data" syntax got used in expression on paramter of not active node which got referenced by active one',
|
// description: 'return resolved value when short "data" syntax got used in expression on parameter of not active node which got referenced by active one',
|
||||||
// input: {
|
// input: {
|
||||||
// Node1: {
|
// Node1: {
|
||||||
// parameters: {
|
// parameters: {
|
||||||
|
|
Loading…
Reference in a new issue