mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-11 07:04:06 -08:00
375 lines
8.9 KiB
TypeScript
375 lines
8.9 KiB
TypeScript
|
import type {
|
||
|
IExecuteFunctions,
|
||
|
INodeExecutionData,
|
||
|
INodeType,
|
||
|
INodeTypeDescription,
|
||
|
} from 'n8n-workflow';
|
||
|
import { NodeApiError, NodeOperationError } from 'n8n-workflow';
|
||
|
import {
|
||
|
generateCreditCard,
|
||
|
generateIPv4,
|
||
|
generateIPv6,
|
||
|
generateLocation,
|
||
|
generateMAC,
|
||
|
generateNanoid,
|
||
|
generateRandomAddress,
|
||
|
generateRandomEmail,
|
||
|
generateRandomUser,
|
||
|
generateURL,
|
||
|
generateUUID,
|
||
|
generateVersion,
|
||
|
} from './randomData';
|
||
|
import { setSeed, array as mfArray } from 'minifaker';
|
||
|
import { generateGarbageMemory, runGarbageCollector } from './functions';
|
||
|
|
||
|
export class DebugHelper implements INodeType {
|
||
|
description: INodeTypeDescription = {
|
||
|
displayName: 'DebugHelper',
|
||
|
name: 'debugHelper',
|
||
|
icon: 'file:DebugHelper.svg',
|
||
|
group: ['output'],
|
||
|
subtitle: '={{$parameter["category"]}}',
|
||
|
description: 'Causes problems intentionally and generates useful data for debugging',
|
||
|
version: 1,
|
||
|
defaults: {
|
||
|
name: 'DebugHelper',
|
||
|
},
|
||
|
inputs: ['main'],
|
||
|
outputs: ['main'],
|
||
|
credentials: [],
|
||
|
properties: [
|
||
|
{
|
||
|
displayName: 'Category',
|
||
|
name: 'category',
|
||
|
type: 'options',
|
||
|
noDataExpression: true,
|
||
|
options: [
|
||
|
{
|
||
|
name: 'Do Nothing',
|
||
|
value: 'doNothing',
|
||
|
description: 'Does nothing',
|
||
|
},
|
||
|
{
|
||
|
name: 'Throw Error',
|
||
|
value: 'throwError',
|
||
|
description: 'Throws an error with the specified type and message',
|
||
|
},
|
||
|
{
|
||
|
name: 'Out Of Memory',
|
||
|
value: 'oom',
|
||
|
description: 'Generates a large amount of memory to cause an out of memory error',
|
||
|
},
|
||
|
{
|
||
|
name: 'Generate Random Data',
|
||
|
value: 'randomData',
|
||
|
description: 'Generates random data sets',
|
||
|
},
|
||
|
],
|
||
|
default: 'throwError',
|
||
|
},
|
||
|
{
|
||
|
displayName: 'Error Type',
|
||
|
name: 'throwErrorType',
|
||
|
type: 'options',
|
||
|
noDataExpression: true,
|
||
|
options: [
|
||
|
{
|
||
|
name: 'NodeApiError',
|
||
|
value: 'NodeApiError',
|
||
|
},
|
||
|
{
|
||
|
name: 'NodeOperationError',
|
||
|
value: 'NodeOperationError',
|
||
|
},
|
||
|
{
|
||
|
name: 'Error',
|
||
|
value: 'Error',
|
||
|
},
|
||
|
],
|
||
|
default: 'NodeApiError',
|
||
|
displayOptions: {
|
||
|
show: {
|
||
|
category: ['throwError'],
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
displayName: 'Error Message',
|
||
|
name: 'throwErrorMessage',
|
||
|
type: 'string',
|
||
|
default: 'Node has thrown an error',
|
||
|
description: 'The message to send as part of the error',
|
||
|
displayOptions: {
|
||
|
show: {
|
||
|
category: ['throwError'],
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
displayName: 'Memory Size to Generate',
|
||
|
name: 'memorySizeValue',
|
||
|
type: 'number',
|
||
|
default: 10,
|
||
|
description: 'The approximate amount of memory to generate. Be generous...',
|
||
|
displayOptions: {
|
||
|
show: {
|
||
|
category: ['oom'],
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
displayName: 'Data Type',
|
||
|
name: 'randomDataType',
|
||
|
type: 'options',
|
||
|
noDataExpression: true,
|
||
|
options: [
|
||
|
{
|
||
|
name: 'Address',
|
||
|
value: 'address',
|
||
|
},
|
||
|
{
|
||
|
name: 'Coordinates',
|
||
|
value: 'latLong',
|
||
|
},
|
||
|
{
|
||
|
name: 'Credit Card',
|
||
|
value: 'creditCard',
|
||
|
},
|
||
|
{
|
||
|
name: 'Email',
|
||
|
value: 'email',
|
||
|
},
|
||
|
{
|
||
|
name: 'IPv4',
|
||
|
value: 'ipv4',
|
||
|
},
|
||
|
{
|
||
|
name: 'IPv6',
|
||
|
value: 'ipv6',
|
||
|
},
|
||
|
{
|
||
|
name: 'MAC',
|
||
|
value: 'macAddress',
|
||
|
},
|
||
|
{
|
||
|
name: 'NanoIds',
|
||
|
value: 'nanoid',
|
||
|
},
|
||
|
{
|
||
|
name: 'URL',
|
||
|
value: 'url',
|
||
|
},
|
||
|
{
|
||
|
name: 'User Data',
|
||
|
value: 'user',
|
||
|
},
|
||
|
{
|
||
|
name: 'UUID',
|
||
|
value: 'uuid',
|
||
|
},
|
||
|
{
|
||
|
name: 'Version',
|
||
|
value: 'semver',
|
||
|
},
|
||
|
],
|
||
|
default: 'user',
|
||
|
displayOptions: {
|
||
|
show: {
|
||
|
category: ['randomData'],
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
displayName: 'NanoId Alphabet',
|
||
|
name: 'nanoidAlphabet',
|
||
|
type: 'string',
|
||
|
default: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||
|
description: 'The alphabet to use for generating the nanoIds',
|
||
|
displayOptions: {
|
||
|
show: {
|
||
|
category: ['randomData'],
|
||
|
randomDataType: ['nanoid'],
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
displayName: 'NanoId Length',
|
||
|
name: 'nanoidLength',
|
||
|
type: 'string',
|
||
|
default: '16',
|
||
|
description: 'The length of each nanoIds',
|
||
|
displayOptions: {
|
||
|
show: {
|
||
|
category: ['randomData'],
|
||
|
randomDataType: ['nanoid'],
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
displayName: 'Seed',
|
||
|
name: 'randomDataSeed',
|
||
|
type: 'string',
|
||
|
default: '',
|
||
|
placeholder: 'Leave empty for random seed',
|
||
|
description:
|
||
|
'If set, seed to use for generating the data (same seed will generate the same data)',
|
||
|
displayOptions: {
|
||
|
show: {
|
||
|
category: ['randomData'],
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
displayName: 'Number of Items to Generate',
|
||
|
name: 'randomDataCount',
|
||
|
type: 'number',
|
||
|
default: 10,
|
||
|
description: 'The number of random data items to generate into an array',
|
||
|
displayOptions: {
|
||
|
show: {
|
||
|
category: ['randomData'],
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
displayName: 'Output as Single Array',
|
||
|
name: 'randomDataSingleArray',
|
||
|
type: 'boolean',
|
||
|
default: false,
|
||
|
description: 'Whether to output a single array instead of multiple items',
|
||
|
displayOptions: {
|
||
|
show: {
|
||
|
category: ['randomData'],
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
],
|
||
|
};
|
||
|
|
||
|
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
||
|
const items = this.getInputData();
|
||
|
const returnData: INodeExecutionData[] = [];
|
||
|
const category = this.getNodeParameter('category', 0) as string;
|
||
|
|
||
|
for (let i = 0; i < items.length; i++) {
|
||
|
try {
|
||
|
switch (category) {
|
||
|
case 'doNothing':
|
||
|
// as it says on the tin...
|
||
|
break;
|
||
|
case 'throwError':
|
||
|
const throwErrorType = this.getNodeParameter('throwErrorType', 0) as string;
|
||
|
const throwErrorMessage = this.getNodeParameter('throwErrorMessage', 0) as string;
|
||
|
switch (throwErrorType) {
|
||
|
case 'NodeApiError':
|
||
|
throw new NodeApiError(
|
||
|
this.getNode(),
|
||
|
{ message: throwErrorMessage },
|
||
|
{ message: throwErrorMessage },
|
||
|
);
|
||
|
case 'NodeOperationError':
|
||
|
throw new NodeOperationError(this.getNode(), throwErrorMessage, {
|
||
|
message: throwErrorMessage,
|
||
|
});
|
||
|
case 'Error':
|
||
|
// eslint-disable-next-line n8n-nodes-base/node-execute-block-wrong-error-thrown
|
||
|
throw new Error(throwErrorMessage);
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
case 'oom':
|
||
|
const memorySizeValue = this.getNodeParameter('memorySizeValue', 0) as number;
|
||
|
runGarbageCollector();
|
||
|
const memUsed = generateGarbageMemory(memorySizeValue);
|
||
|
items[i].json = memUsed;
|
||
|
returnData.push(items[i]);
|
||
|
break;
|
||
|
case 'randomData':
|
||
|
const randomDataType = this.getNodeParameter('randomDataType', 0) as string;
|
||
|
const randomDataCount = this.getNodeParameter('randomDataCount', 0) as number;
|
||
|
const randomDataSeed = this.getNodeParameter('randomDataSeed', 0) as string;
|
||
|
const randomDataSingleArray = this.getNodeParameter(
|
||
|
'randomDataSingleArray',
|
||
|
0,
|
||
|
) as boolean;
|
||
|
const newItem: INodeExecutionData = {
|
||
|
json: {},
|
||
|
pairedItem: { item: i },
|
||
|
};
|
||
|
if (randomDataSeed !== '') {
|
||
|
setSeed(randomDataSeed);
|
||
|
}
|
||
|
|
||
|
let randomFn: () => any = generateRandomUser;
|
||
|
switch (randomDataType) {
|
||
|
case 'user':
|
||
|
randomFn = generateRandomUser;
|
||
|
break;
|
||
|
case 'email':
|
||
|
randomFn = generateRandomEmail;
|
||
|
break;
|
||
|
case 'address':
|
||
|
randomFn = generateRandomAddress;
|
||
|
break;
|
||
|
case 'creditCard':
|
||
|
randomFn = generateCreditCard;
|
||
|
break;
|
||
|
case 'uuid':
|
||
|
randomFn = generateUUID;
|
||
|
break;
|
||
|
case 'macAddress':
|
||
|
randomFn = generateMAC;
|
||
|
break;
|
||
|
case 'ipv4':
|
||
|
randomFn = generateIPv4;
|
||
|
break;
|
||
|
case 'ipv6':
|
||
|
randomFn = generateIPv6;
|
||
|
break;
|
||
|
case 'latLong':
|
||
|
randomFn = generateLocation;
|
||
|
break;
|
||
|
case 'semver':
|
||
|
randomFn = generateVersion;
|
||
|
break;
|
||
|
case 'url':
|
||
|
randomFn = generateURL;
|
||
|
break;
|
||
|
case 'nanoid':
|
||
|
const nanoidAlphabet = this.getNodeParameter('nanoidAlphabet', 0) as string;
|
||
|
const nanoidLength = this.getNodeParameter('nanoidLength', 0) as string;
|
||
|
randomFn = () => generateNanoid(nanoidAlphabet, nanoidLength);
|
||
|
break;
|
||
|
}
|
||
|
const generatedItems = mfArray(randomDataCount, randomFn);
|
||
|
if (randomDataSingleArray) {
|
||
|
newItem.json = { generatedItems };
|
||
|
returnData.push(newItem);
|
||
|
} else {
|
||
|
for (const generatedItem of generatedItems) {
|
||
|
returnData.push({
|
||
|
json: generatedItem,
|
||
|
pairedItem: { item: i },
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
} catch (error) {
|
||
|
if (this.continueOnFail()) {
|
||
|
const executionErrorData = this.helpers.constructExecutionMetaData(
|
||
|
this.helpers.returnJsonArray({ error: error.message }),
|
||
|
{ itemData: { item: i } },
|
||
|
);
|
||
|
returnData.push(...executionErrorData);
|
||
|
continue;
|
||
|
}
|
||
|
throw error;
|
||
|
}
|
||
|
}
|
||
|
return this.prepareOutputData(returnData);
|
||
|
}
|
||
|
}
|