first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
import type {
|
||||
IExecuteFunctions,
|
||||
IBinaryData,
|
||||
INodeExecutionData,
|
||||
GenericValue,
|
||||
} from 'n8n-workflow';
|
||||
import { ApplicationError, NodeOperationError } from 'n8n-workflow';
|
||||
|
||||
import { JsTaskRunnerSandbox } from '../../../Code/JsTaskRunnerSandbox';
|
||||
|
||||
export const prepareFieldsArray = (fields: string | string[], fieldName = 'Fields') => {
|
||||
if (typeof fields === 'string') {
|
||||
return fields
|
||||
.split(',')
|
||||
.map((entry) => entry.trim())
|
||||
.filter((entry) => entry !== '');
|
||||
}
|
||||
if (Array.isArray(fields)) {
|
||||
return fields;
|
||||
}
|
||||
throw new ApplicationError(
|
||||
`The \'${fieldName}\' parameter must be a string of fields separated by commas or an array of strings.`,
|
||||
{ level: 'warning' },
|
||||
);
|
||||
};
|
||||
|
||||
const returnRegExp = /\breturn\b/g;
|
||||
|
||||
export async function sortByCode(
|
||||
this: IExecuteFunctions,
|
||||
items: INodeExecutionData[],
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const userCode = this.getNodeParameter('code', 0) as string;
|
||||
if (!returnRegExp.test(userCode)) {
|
||||
throw new NodeOperationError(
|
||||
this.getNode(),
|
||||
"Sort code doesn't return. Please add a 'return' statement to your code",
|
||||
);
|
||||
}
|
||||
|
||||
const mode = this.getMode();
|
||||
const chunkSize = undefined;
|
||||
const sortCode = `return items.sort((a, b) => { ${userCode} })`;
|
||||
const sandbox = new JsTaskRunnerSandbox(mode, this, chunkSize, { items });
|
||||
const executionResult = await sandbox.runCode<INodeExecutionData[]>(sortCode);
|
||||
|
||||
return executionResult;
|
||||
}
|
||||
|
||||
type PartialBinaryData = Omit<IBinaryData, 'data'>;
|
||||
const isBinaryUniqueSetup = () => {
|
||||
const binaries: PartialBinaryData[] = [];
|
||||
return (binary: IBinaryData) => {
|
||||
for (const existingBinary of binaries) {
|
||||
if (
|
||||
existingBinary.mimeType === binary.mimeType &&
|
||||
existingBinary.fileType === binary.fileType &&
|
||||
existingBinary.fileSize === binary.fileSize &&
|
||||
existingBinary.fileExtension === binary.fileExtension
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
binaries.push({
|
||||
mimeType: binary.mimeType,
|
||||
fileType: binary.fileType,
|
||||
fileSize: binary.fileSize,
|
||||
fileExtension: binary.fileExtension,
|
||||
});
|
||||
|
||||
return true;
|
||||
};
|
||||
};
|
||||
|
||||
export function addBinariesToItem(
|
||||
newItem: INodeExecutionData,
|
||||
items: INodeExecutionData[],
|
||||
uniqueOnly?: boolean,
|
||||
) {
|
||||
const isBinaryUnique = uniqueOnly ? isBinaryUniqueSetup() : undefined;
|
||||
|
||||
for (const item of items) {
|
||||
if (item.binary === undefined) continue;
|
||||
|
||||
for (const key of Object.keys(item.binary)) {
|
||||
if (!newItem.binary) newItem.binary = {};
|
||||
let binaryKey = key;
|
||||
const binary = item.binary[key];
|
||||
|
||||
if (isBinaryUnique && !isBinaryUnique(binary)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the binary key already exists add a suffix to it
|
||||
let i = 1;
|
||||
while (newItem.binary[binaryKey] !== undefined) {
|
||||
binaryKey = `${key}_${i}`;
|
||||
i++;
|
||||
}
|
||||
|
||||
newItem.binary[binaryKey] = binary;
|
||||
}
|
||||
}
|
||||
|
||||
return newItem;
|
||||
}
|
||||
|
||||
export function typeToNumber(value: GenericValue): number {
|
||||
if (typeof value === 'object') {
|
||||
if (Array.isArray(value)) return 9;
|
||||
if (value === null) return 10;
|
||||
if (value instanceof Date) return 11;
|
||||
}
|
||||
const types = {
|
||||
_string: 1,
|
||||
_number: 2,
|
||||
_bigint: 3,
|
||||
_boolean: 4,
|
||||
_symbol: 5,
|
||||
_undefined: 6,
|
||||
_object: 7,
|
||||
_function: 8,
|
||||
};
|
||||
return types[`_${typeof value}`];
|
||||
}
|
||||
Reference in New Issue
Block a user