mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-14 08:34:07 -08:00
e77fd5d286
Ensure all errors in `nodes-base` are `ApplicationError` or children of it and contain no variables in the message, to continue normalizing all the backend errors we report to Sentry. Also, skip reporting to Sentry errors from user input and from external APIs. In future we should refine `ApplicationError` to more specific errors. Follow-up to: [#7877](https://github.com/n8n-io/n8n/pull/7877) - [x] Test workflows: https://github.com/n8n-io/n8n/actions/runs/7084627970 - [x] e2e: https://github.com/n8n-io/n8n/actions/runs/7084936861 --------- Co-authored-by: Michael Kret <michael.k@radency.com>
137 lines
3.5 KiB
TypeScript
137 lines
3.5 KiB
TypeScript
import type { IDataObject, INodeExecutionData } from 'n8n-workflow';
|
|
import { deepCopy, assert, ApplicationError } from 'n8n-workflow';
|
|
|
|
import type {
|
|
AdjustedPutItem,
|
|
AttributeValueType,
|
|
EAttributeValueType,
|
|
IAttributeNameUi,
|
|
IAttributeValue,
|
|
IAttributeValueUi,
|
|
IAttributeValueValue,
|
|
PutItemUi,
|
|
} from './types';
|
|
|
|
const addColon = (attribute: string) =>
|
|
(attribute = attribute.charAt(0) === ':' ? attribute : `:${attribute}`);
|
|
|
|
const addPound = (key: string) => (key = key.charAt(0) === '#' ? key : `#${key}`);
|
|
|
|
export function adjustExpressionAttributeValues(eavUi: IAttributeValueUi[]) {
|
|
const eav: IAttributeValue = {};
|
|
|
|
eavUi.forEach(({ attribute, type, value }) => {
|
|
eav[addColon(attribute)] = { [type]: value } as IAttributeValueValue;
|
|
});
|
|
|
|
return eav;
|
|
}
|
|
|
|
export function adjustExpressionAttributeName(eanUi: IAttributeNameUi[]) {
|
|
const ean: { [key: string]: string } = {};
|
|
|
|
eanUi.forEach(({ key, value }) => {
|
|
ean[addPound(key)] = value;
|
|
});
|
|
|
|
return ean;
|
|
}
|
|
|
|
export function adjustPutItem(putItemUi: PutItemUi) {
|
|
const adjustedPutItem: AdjustedPutItem = {};
|
|
|
|
Object.entries(putItemUi).forEach(([attribute, value]) => {
|
|
let type: string;
|
|
|
|
if (typeof value === 'boolean') {
|
|
type = 'BOOL';
|
|
} else if (typeof value === 'object' && !Array.isArray(value) && value !== null) {
|
|
type = 'M';
|
|
} else if (isNaN(Number(value))) {
|
|
type = 'S';
|
|
} else {
|
|
type = 'N';
|
|
}
|
|
|
|
adjustedPutItem[attribute] = { [type]: value.toString() };
|
|
});
|
|
|
|
return adjustedPutItem;
|
|
}
|
|
|
|
export function simplify(item: IAttributeValue): IDataObject {
|
|
const output: IDataObject = {};
|
|
|
|
for (const [attribute, value] of Object.entries(item)) {
|
|
const [type, content] = Object.entries(value)[0] as [AttributeValueType, string];
|
|
//nedded as simplify is used in decodeItem
|
|
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
output[attribute] = decodeAttribute(type, content);
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
function decodeAttribute(type: AttributeValueType, attribute: string | IAttributeValue) {
|
|
switch (type) {
|
|
case 'BOOL':
|
|
return Boolean(attribute);
|
|
case 'N':
|
|
return Number(attribute);
|
|
case 'S':
|
|
return String(attribute);
|
|
case 'SS':
|
|
case 'NS':
|
|
return attribute;
|
|
case 'M':
|
|
assert(
|
|
typeof attribute === 'object' && !Array.isArray(attribute) && attribute !== null,
|
|
'Attribute must be an object',
|
|
);
|
|
return simplify(attribute);
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export function validateJSON(input: any): object {
|
|
try {
|
|
return JSON.parse(input as string);
|
|
} catch (error) {
|
|
throw new ApplicationError('Items must be a valid JSON', { level: 'warning' });
|
|
}
|
|
}
|
|
|
|
export function copyInputItem(item: INodeExecutionData, properties: string[]): IDataObject {
|
|
// Prepare the data to insert and copy it to be returned
|
|
const newItem: IDataObject = {};
|
|
for (const property of properties) {
|
|
if (item.json[property] === undefined) {
|
|
newItem[property] = null;
|
|
} else {
|
|
newItem[property] = deepCopy(item.json[property]);
|
|
}
|
|
}
|
|
return newItem;
|
|
}
|
|
|
|
export function mapToAttributeValues(item: IDataObject): void {
|
|
for (const key of Object.keys(item)) {
|
|
if (!key.startsWith(':')) {
|
|
item[`:${key}`] = item[key];
|
|
delete item[key];
|
|
}
|
|
}
|
|
}
|
|
|
|
export function decodeItem(item: IAttributeValue): IDataObject {
|
|
const _item: IDataObject = {};
|
|
for (const entry of Object.entries(item)) {
|
|
const [attribute, value]: [string, object] = entry;
|
|
const [type, content]: [string, object] = Object.entries(value)[0];
|
|
_item[attribute] = decodeAttribute(type as EAttributeValueType, content as unknown as string);
|
|
}
|
|
|
|
return _item;
|
|
}
|