mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 01:56:46 +00:00
refactor(core): Include native Python option in Code node (#18331)
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
/* eslint-disable n8n-nodes-base/node-execute-block-wrong-error-thrown */
|
||||
import { NodesConfig, TaskRunnersConfig } from '@n8n/config';
|
||||
import { Container } from '@n8n/di';
|
||||
import set from 'lodash/set';
|
||||
import {
|
||||
type INodeProperties,
|
||||
NodeConnectionTypes,
|
||||
UserError,
|
||||
type CodeExecutionMode,
|
||||
@@ -12,15 +14,19 @@ import {
|
||||
type INodeTypeDescription,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
type CodeNodeLanguageOption = CodeNodeEditorLanguage | 'pythonNative';
|
||||
|
||||
import { javascriptCodeDescription } from './descriptions/JavascriptCodeDescription';
|
||||
import { pythonCodeDescription } from './descriptions/PythonCodeDescription';
|
||||
import { JavaScriptSandbox } from './JavaScriptSandbox';
|
||||
import { JsTaskRunnerSandbox } from './JsTaskRunnerSandbox';
|
||||
import { NativePythonWithoutRunnerError } from './native-python-without-runner.error';
|
||||
import { PythonSandbox } from './PythonSandbox';
|
||||
import { PythonTaskRunnerSandbox } from './PythonTaskRunnerSandbox';
|
||||
import { getSandboxContext } from './Sandbox';
|
||||
import { addPostExecutionWarning, standardizeOutput } from './utils';
|
||||
|
||||
const { CODE_ENABLE_STDOUT } = process.env;
|
||||
const { CODE_ENABLE_STDOUT, N8N_NATIVE_PYTHON_RUNNER } = process.env;
|
||||
|
||||
class PythonDisabledError extends UserError {
|
||||
constructor() {
|
||||
@@ -30,6 +36,40 @@ class PythonDisabledError extends UserError {
|
||||
}
|
||||
}
|
||||
|
||||
const getV2LanguageProperty = (): INodeProperties => {
|
||||
const options = [
|
||||
{
|
||||
name: 'JavaScript',
|
||||
value: 'javaScript',
|
||||
},
|
||||
{
|
||||
name: 'Python (Beta)',
|
||||
value: 'python',
|
||||
},
|
||||
];
|
||||
|
||||
if (N8N_NATIVE_PYTHON_RUNNER === 'true') {
|
||||
options.push({
|
||||
name: 'Python (Native) (Beta)',
|
||||
value: 'pythonNative',
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
displayName: 'Language',
|
||||
name: 'language',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
'@version': [2],
|
||||
},
|
||||
},
|
||||
options,
|
||||
default: 'javaScript',
|
||||
};
|
||||
};
|
||||
|
||||
export class Code implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'Code',
|
||||
@@ -65,28 +105,7 @@ export class Code implements INodeType {
|
||||
],
|
||||
default: 'runOnceForAllItems',
|
||||
},
|
||||
{
|
||||
displayName: 'Language',
|
||||
name: 'language',
|
||||
type: 'options',
|
||||
noDataExpression: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
'@version': [2],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'JavaScript',
|
||||
value: 'javaScript',
|
||||
},
|
||||
{
|
||||
name: 'Python (Beta)',
|
||||
value: 'python',
|
||||
},
|
||||
],
|
||||
default: 'javaScript',
|
||||
},
|
||||
getV2LanguageProperty(),
|
||||
{
|
||||
displayName: 'Language',
|
||||
name: 'language',
|
||||
@@ -106,22 +125,24 @@ export class Code implements INodeType {
|
||||
|
||||
async execute(this: IExecuteFunctions) {
|
||||
const node = this.getNode();
|
||||
const language: CodeNodeEditorLanguage =
|
||||
const language: CodeNodeLanguageOption =
|
||||
node.typeVersion === 2
|
||||
? (this.getNodeParameter('language', 0) as CodeNodeEditorLanguage)
|
||||
? (this.getNodeParameter('language', 0) as CodeNodeLanguageOption)
|
||||
: 'javaScript';
|
||||
|
||||
if (language === 'python' && !Container.get(NodesConfig).pythonEnabled) {
|
||||
// eslint-disable-next-line n8n-nodes-base/node-execute-block-wrong-error-thrown
|
||||
throw new PythonDisabledError();
|
||||
}
|
||||
|
||||
const runnersConfig = Container.get(TaskRunnersConfig);
|
||||
const isRunnerEnabled = runnersConfig.enabled;
|
||||
|
||||
const nodeMode = this.getNodeParameter('mode', 0) as CodeExecutionMode;
|
||||
const workflowMode = this.getMode();
|
||||
const codeParameterName = language === 'python' ? 'pythonCode' : 'jsCode';
|
||||
const codeParameterName =
|
||||
language === 'python' || language === 'pythonNative' ? 'pythonCode' : 'jsCode';
|
||||
|
||||
if (runnersConfig.enabled && language === 'javaScript') {
|
||||
if (language === 'javaScript' && isRunnerEnabled) {
|
||||
const code = this.getNodeParameter(codeParameterName, 0) as string;
|
||||
const sandbox = new JsTaskRunnerSandbox(code, nodeMode, workflowMode, this);
|
||||
const numInputItems = this.getInputData().length;
|
||||
@@ -131,6 +152,15 @@ export class Code implements INodeType {
|
||||
: [await sandbox.runCodeForEachItem(numInputItems)];
|
||||
}
|
||||
|
||||
if (language === 'pythonNative' && !isRunnerEnabled) throw new NativePythonWithoutRunnerError();
|
||||
|
||||
if (language === 'pythonNative') {
|
||||
const code = this.getNodeParameter(codeParameterName, 0) as string;
|
||||
const sandbox = new PythonTaskRunnerSandbox(code, nodeMode, workflowMode, this);
|
||||
|
||||
return [await sandbox.runUsingIncomingItems()];
|
||||
}
|
||||
|
||||
const getSandbox = (index = 0) => {
|
||||
const code = this.getNodeParameter(codeParameterName, index) as string;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user