mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
feat(Execute Workflow Trigger Node): Add JSON-based input modes and dropdown (#11946)
This commit is contained in:
parent
698f7d0ae1
commit
001e3f931f
|
@ -1,3 +1,5 @@
|
||||||
|
import { json as generateSchemaFromExample, type SchemaObject } from 'generate-schema';
|
||||||
|
import type { JSONSchema7 } from 'json-schema';
|
||||||
import {
|
import {
|
||||||
type INodeExecutionData,
|
type INodeExecutionData,
|
||||||
NodeConnectionType,
|
NodeConnectionType,
|
||||||
|
@ -7,96 +9,16 @@ import {
|
||||||
type INodeTypeDescription,
|
type INodeTypeDescription,
|
||||||
validateFieldType,
|
validateFieldType,
|
||||||
type FieldType,
|
type FieldType,
|
||||||
|
jsonParse,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
const INPUT_SOURCE = 'inputSource';
|
||||||
const WORKFLOW_INPUTS = 'workflowInputs';
|
const WORKFLOW_INPUTS = 'workflowInputs';
|
||||||
const INPUT_OPTIONS = 'inputOptions';
|
const INPUT_OPTIONS = 'inputOptions';
|
||||||
const VALUES = 'values';
|
const VALUES = 'values';
|
||||||
|
const JSON_EXAMPLE = 'jsonExample';
|
||||||
type ValueOptions = { name: string; value: FieldType };
|
const JSON_SCHEMA = 'jsonSchema';
|
||||||
|
const TYPE_OPTIONS: Array<{ name: string; value: FieldType | 'any' }> = [
|
||||||
const DEFAULT_PLACEHOLDER = null;
|
|
||||||
|
|
||||||
export class ExecuteWorkflowTrigger implements INodeType {
|
|
||||||
description: INodeTypeDescription = {
|
|
||||||
displayName: 'Execute Workflow Trigger',
|
|
||||||
name: 'executeWorkflowTrigger',
|
|
||||||
icon: 'fa:sign-out-alt',
|
|
||||||
group: ['trigger'],
|
|
||||||
version: [1, 1.1],
|
|
||||||
description:
|
|
||||||
'Helpers for calling other n8n workflows. Used for designing modular, microservice-like workflows.',
|
|
||||||
eventTriggerDescription: '',
|
|
||||||
maxNodes: 1,
|
|
||||||
defaults: {
|
|
||||||
name: 'Execute Workflow Trigger',
|
|
||||||
color: '#ff6d5a',
|
|
||||||
},
|
|
||||||
|
|
||||||
inputs: [],
|
|
||||||
outputs: [NodeConnectionType.Main],
|
|
||||||
properties: [
|
|
||||||
{
|
|
||||||
displayName: `When an ‘Execute Workflow’ node calls this workflow, the execution starts here.<br><br>
|
|
||||||
Specified fields below will be output by this node with values provided by the calling workflow.<br><br>
|
|
||||||
If you don't provide fields, all data passed into the 'Execute Workflow' node will be passed through instead.`,
|
|
||||||
name: 'notice',
|
|
||||||
type: 'notice',
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Events',
|
|
||||||
name: 'events',
|
|
||||||
type: 'hidden',
|
|
||||||
noDataExpression: true,
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
name: 'Workflow Call',
|
|
||||||
value: 'worklfow_call',
|
|
||||||
description: 'When called by another workflow using Execute Workflow Trigger',
|
|
||||||
action: 'When Called by Another Workflow',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
default: 'worklfow_call',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Workflow Inputs',
|
|
||||||
name: WORKFLOW_INPUTS,
|
|
||||||
placeholder: 'Add Field',
|
|
||||||
type: 'fixedCollection',
|
|
||||||
description:
|
|
||||||
'Define expected input fields. If no inputs are provided, all data from the calling workflow will be passed through.',
|
|
||||||
typeOptions: {
|
|
||||||
multipleValues: true,
|
|
||||||
sortable: true,
|
|
||||||
},
|
|
||||||
displayOptions: {
|
|
||||||
show: { '@version': [{ _cnd: { gte: 1.1 } }] },
|
|
||||||
},
|
|
||||||
default: {},
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
name: VALUES,
|
|
||||||
displayName: 'Values',
|
|
||||||
values: [
|
|
||||||
{
|
|
||||||
displayName: 'Name',
|
|
||||||
name: 'name',
|
|
||||||
type: 'string',
|
|
||||||
default: '',
|
|
||||||
placeholder: 'e.g. fieldName',
|
|
||||||
description: 'Name of the field',
|
|
||||||
noDataExpression: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Type',
|
|
||||||
name: 'type',
|
|
||||||
type: 'options',
|
|
||||||
description: 'The field value type',
|
|
||||||
// eslint-disable-next-line n8n-nodes-base/node-param-options-type-unsorted-items
|
|
||||||
options: [
|
|
||||||
// This is not a FieldType type, but will
|
|
||||||
// hit the default case in the type check function
|
|
||||||
{
|
{
|
||||||
name: 'Allow Any Type',
|
name: 'Allow Any Type',
|
||||||
value: 'any',
|
value: 'any',
|
||||||
|
@ -122,7 +44,265 @@ If you don't provide fields, all data passed into the 'Execute Workflow' node wi
|
||||||
value: 'object',
|
value: 'object',
|
||||||
},
|
},
|
||||||
// Intentional omission of `dateTime`, `time`, `string-alphanumeric`, `form-fields`, `jwt` and `url`
|
// Intentional omission of `dateTime`, `time`, `string-alphanumeric`, `form-fields`, `jwt` and `url`
|
||||||
] as ValueOptions[],
|
];
|
||||||
|
const SUPPORTED_TYPES = TYPE_OPTIONS.map((x) => x.value);
|
||||||
|
|
||||||
|
const DEFAULT_PLACEHOLDER = null;
|
||||||
|
|
||||||
|
type ValueOptions = { name: string; type: FieldType | 'any' };
|
||||||
|
|
||||||
|
function parseJsonSchema(schema: JSONSchema7): ValueOptions[] | string {
|
||||||
|
if (!schema?.properties) {
|
||||||
|
return 'Invalid JSON schema. Missing key `properties` in schema';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof schema.properties !== 'object') {
|
||||||
|
return 'Invalid JSON schema. Key `properties` is not an object';
|
||||||
|
}
|
||||||
|
|
||||||
|
const result: ValueOptions[] = [];
|
||||||
|
for (const [name, v] of Object.entries(schema.properties)) {
|
||||||
|
if (typeof v !== 'object') {
|
||||||
|
return `Invalid JSON schema. Value for property '${name}' is not an object`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const type = v?.type;
|
||||||
|
|
||||||
|
if (type === 'null') {
|
||||||
|
result.push({ name, type: 'any' });
|
||||||
|
} else if (Array.isArray(type)) {
|
||||||
|
// Schema allows an array of types, but we don't
|
||||||
|
return `Invalid JSON schema. Array of types for property '${name}' is not supported by n8n. Either provide a single type or use type 'any' to allow any type`;
|
||||||
|
} else if (typeof type !== 'string') {
|
||||||
|
return `Invalid JSON schema. Unexpected non-string type ${type} for property '${name}'`;
|
||||||
|
} else if (!SUPPORTED_TYPES.includes(type as never)) {
|
||||||
|
return `Invalid JSON schema. Unsupported type ${type} for property '${name}'. Supported types are ${JSON.stringify(SUPPORTED_TYPES, null, 1)}`;
|
||||||
|
} else {
|
||||||
|
result.push({ name, type: type as FieldType });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseJsonExample(context: IExecuteFunctions): JSONSchema7 {
|
||||||
|
const jsonString = context.getNodeParameter(JSON_EXAMPLE, 0, '') as string;
|
||||||
|
const json = jsonParse<SchemaObject>(jsonString);
|
||||||
|
|
||||||
|
return generateSchemaFromExample(json) as JSONSchema7;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFieldEntries(context: IExecuteFunctions): ValueOptions[] {
|
||||||
|
const inputSource = context.getNodeParameter(INPUT_SOURCE, 0) as string;
|
||||||
|
let result: ValueOptions[] | string = 'Internal Error: Invalid input source';
|
||||||
|
try {
|
||||||
|
if (inputSource === WORKFLOW_INPUTS) {
|
||||||
|
result = context.getNodeParameter(`${WORKFLOW_INPUTS}.${VALUES}`, 0, []) as Array<{
|
||||||
|
name: string;
|
||||||
|
type: FieldType;
|
||||||
|
}>;
|
||||||
|
} else if (inputSource === JSON_SCHEMA) {
|
||||||
|
const schema = context.getNodeParameter(JSON_SCHEMA, 0, '{}') as string;
|
||||||
|
result = parseJsonSchema(jsonParse<JSONSchema7>(schema));
|
||||||
|
} else if (inputSource === JSON_EXAMPLE) {
|
||||||
|
const schema = parseJsonExample(context);
|
||||||
|
result = parseJsonSchema(schema);
|
||||||
|
}
|
||||||
|
} catch (e: unknown) {
|
||||||
|
result =
|
||||||
|
e && typeof e === 'object' && 'message' in e && typeof e.message === 'string'
|
||||||
|
? e.message
|
||||||
|
: `Unknown error occurred: ${JSON.stringify(e)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(result)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
throw new NodeOperationError(context.getNode(), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This intentionally doesn't catch any potential errors, e.g. an invalid json example
|
||||||
|
// This way they correctly end up exposed to the user.
|
||||||
|
// Otherwise we'd have to return true on error here as we short-circuit on false
|
||||||
|
function hasFields(context: IExecuteFunctions): boolean {
|
||||||
|
const entries = getFieldEntries(context);
|
||||||
|
return entries.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ExecuteWorkflowTrigger implements INodeType {
|
||||||
|
description: INodeTypeDescription = {
|
||||||
|
displayName: 'Execute Workflow Trigger',
|
||||||
|
name: 'executeWorkflowTrigger',
|
||||||
|
icon: 'fa:sign-out-alt',
|
||||||
|
group: ['trigger'],
|
||||||
|
version: [1, 1.1],
|
||||||
|
description:
|
||||||
|
'Helpers for calling other n8n workflows. Used for designing modular, microservice-like workflows.',
|
||||||
|
eventTriggerDescription: '',
|
||||||
|
maxNodes: 1,
|
||||||
|
defaults: {
|
||||||
|
name: 'Workflow Input Trigger',
|
||||||
|
color: '#ff6d5a',
|
||||||
|
},
|
||||||
|
inputs: [],
|
||||||
|
outputs: [NodeConnectionType.Main],
|
||||||
|
hints: [
|
||||||
|
{
|
||||||
|
message:
|
||||||
|
'We strongly recommend defining your input fields explicitly.<br>If no inputs are provided, all data from the calling workflow will be available, and issues will be more difficult to debug later on.',
|
||||||
|
// This condition checks if we have no input fields, which gets a bit awkward:
|
||||||
|
// For WORKFLOW_INPUTS: keys() only contains `VALUES` if at least one value is provided
|
||||||
|
// For JSON_EXAMPLE: We remove all whitespace and check if we're left with an empty object. Note that we already error if the example is not valid JSON
|
||||||
|
// For JSON_SCHEMA: We check if we have '"properties":{}' after removing all whitespace. Otherwise the schema is invalid anyway and we'll error out elsewhere
|
||||||
|
displayCondition:
|
||||||
|
`={{$parameter['${INPUT_SOURCE}'] === '${WORKFLOW_INPUTS}' && !$parameter['${WORKFLOW_INPUTS}'].keys().length ` +
|
||||||
|
`|| $parameter['${INPUT_SOURCE}'] === '${JSON_EXAMPLE}' && $parameter['${JSON_EXAMPLE}'].toString().replaceAll(' ', '').replaceAll('\\n', '') === '{}' ` +
|
||||||
|
`|| $parameter['${INPUT_SOURCE}'] === '${JSON_SCHEMA}' && $parameter['${JSON_SCHEMA}'].toString().replaceAll(' ', '').replaceAll('\\n', '').includes('"properties":{}') }}`,
|
||||||
|
whenToDisplay: 'always',
|
||||||
|
location: 'ndv',
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
message:
|
||||||
|
'n8n does not support items types on Array fields. These entries will have no effect.',
|
||||||
|
// This is only best effort, but few natural use cases should trigger false positives here
|
||||||
|
displayCondition: `={{$parameter["${INPUT_SOURCE}"] === '${JSON_SCHEMA}' && $parameter["${JSON_SCHEMA}"].toString().includes('"items":') && $parameter["${JSON_SCHEMA}"].toString().includes('"array"') }}`,
|
||||||
|
whenToDisplay: 'always',
|
||||||
|
location: 'ndv',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
properties: [
|
||||||
|
{
|
||||||
|
displayName: `When an ‘Execute Workflow’ node calls this workflow, the execution starts here.<br><br>
|
||||||
|
Specified fields below will be output by this node with values provided by the calling workflow.<br><br>
|
||||||
|
If you don't provide fields, all data passed into the 'Execute Workflow' node will be passed through instead.`,
|
||||||
|
name: 'notice',
|
||||||
|
type: 'notice',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Events',
|
||||||
|
name: 'events',
|
||||||
|
type: 'hidden',
|
||||||
|
noDataExpression: true,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Workflow Call',
|
||||||
|
value: 'worklfow_call',
|
||||||
|
description: 'When called by another workflow using Execute Workflow Trigger',
|
||||||
|
action: 'When Called by Another Workflow',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'worklfow_call',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Input Source',
|
||||||
|
name: INPUT_SOURCE,
|
||||||
|
type: 'options',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Using Fields Below',
|
||||||
|
value: WORKFLOW_INPUTS,
|
||||||
|
description: 'Provide via UI',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Using JSON Example',
|
||||||
|
value: JSON_EXAMPLE,
|
||||||
|
description: 'Infer JSON schema via JSON example output',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Using JSON Schema',
|
||||||
|
value: JSON_SCHEMA,
|
||||||
|
description: 'Provide JSON Schema',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: WORKFLOW_INPUTS,
|
||||||
|
noDataExpression: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName:
|
||||||
|
'Provide an example object to infer fields and their types.<br>To allow any type for a given field, set the value to null.',
|
||||||
|
name: `${JSON_EXAMPLE}_notice`,
|
||||||
|
type: 'notice',
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: { '@version': [{ _cnd: { gte: 1.1 } }], inputSource: [JSON_EXAMPLE] },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'JSON Example',
|
||||||
|
name: JSON_EXAMPLE,
|
||||||
|
type: 'json',
|
||||||
|
default: JSON.stringify(
|
||||||
|
{
|
||||||
|
aField: 'a string',
|
||||||
|
aNumber: 123,
|
||||||
|
thisFieldAcceptsAnyType: null,
|
||||||
|
anArray: [],
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
noDataExpression: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: { '@version': [{ _cnd: { gte: 1.1 } }], inputSource: [JSON_EXAMPLE] },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'JSON Schema',
|
||||||
|
name: JSON_SCHEMA,
|
||||||
|
type: 'json',
|
||||||
|
default: JSON.stringify(
|
||||||
|
{
|
||||||
|
properties: {
|
||||||
|
aField: { type: 'number' },
|
||||||
|
anotherField: { type: 'array' },
|
||||||
|
thisFieldAcceptsAnyType: { type: 'any' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
noDataExpression: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: { '@version': [{ _cnd: { gte: 1.1 } }], inputSource: [JSON_SCHEMA] },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Workflow Inputs',
|
||||||
|
name: WORKFLOW_INPUTS,
|
||||||
|
placeholder: 'Add Field',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
description:
|
||||||
|
'Define expected input fields. If no inputs are provided, all data from the calling workflow will be passed through.',
|
||||||
|
typeOptions: {
|
||||||
|
multipleValues: true,
|
||||||
|
sortable: true,
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: { '@version': [{ _cnd: { gte: 1.1 } }], inputSource: [WORKFLOW_INPUTS] },
|
||||||
|
},
|
||||||
|
default: {},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: VALUES,
|
||||||
|
displayName: 'Values',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Name',
|
||||||
|
name: 'name',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'e.g. fieldName',
|
||||||
|
description: 'Name of the field',
|
||||||
|
noDataExpression: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Type',
|
||||||
|
name: 'type',
|
||||||
|
type: 'options',
|
||||||
|
description: 'The field value type',
|
||||||
|
// eslint-disable-next-line n8n-nodes-base/node-param-options-type-unsorted-items
|
||||||
|
options: TYPE_OPTIONS,
|
||||||
default: 'string',
|
default: 'string',
|
||||||
noDataExpression: true,
|
noDataExpression: true,
|
||||||
},
|
},
|
||||||
|
@ -184,15 +364,7 @@ If you don't provide fields, all data passed into the 'Execute Workflow' node wi
|
||||||
if (this.getNode().typeVersion < 1.1) {
|
if (this.getNode().typeVersion < 1.1) {
|
||||||
return [inputData];
|
return [inputData];
|
||||||
} else {
|
} else {
|
||||||
// Need to mask type due to bad `getNodeParameter` typing
|
if (!hasFields(this)) {
|
||||||
const marker = Symbol() as unknown as object;
|
|
||||||
const hasFields =
|
|
||||||
inputData.length >= 0 &&
|
|
||||||
inputData.some(
|
|
||||||
(_x, i) => this.getNodeParameter(`${WORKFLOW_INPUTS}.${VALUES}`, i, marker) !== marker,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!hasFields) {
|
|
||||||
return [inputData];
|
return [inputData];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,27 +401,20 @@ If you don't provide fields, all data passed into the 'Execute Workflow' node wi
|
||||||
pairedItem: { item: itemIndex },
|
pairedItem: { item: itemIndex },
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const newParams = this.getNodeParameter(
|
const newParams = getFieldEntries(this);
|
||||||
`${WORKFLOW_INPUTS}.${VALUES}`,
|
|
||||||
itemIndex,
|
|
||||||
[],
|
|
||||||
) as Array<{
|
|
||||||
name: string;
|
|
||||||
type: FieldType;
|
|
||||||
}>;
|
|
||||||
for (const { name, type } of newParams) {
|
for (const { name, type } of newParams) {
|
||||||
if (!item.json.hasOwnProperty(name)) {
|
if (!item.json.hasOwnProperty(name)) {
|
||||||
newItem.json[name] = DEFAULT_PLACEHOLDER;
|
newItem.json[name] = DEFAULT_PLACEHOLDER;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We always parse strings rather than blindly accepting anything as a string
|
const result =
|
||||||
// Which is the behavior of this function
|
type === 'any'
|
||||||
// Also note we intentionally pass `any` in here for `type`, which hits a
|
? ({ valid: true, newValue: item.json[name] } as const)
|
||||||
// permissive default case in the function
|
: validateFieldType(name, item.json[name], type, {
|
||||||
const result = validateFieldType(name, item.json[name], type, {
|
|
||||||
strict: !attemptToConvertTypes,
|
strict: !attemptToConvertTypes,
|
||||||
parseStrings: true,
|
parseStrings: true, // Default behavior is to accept anything as a string, this is a good opportunity for a stricter boundary
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!result.valid) {
|
if (!result.valid) {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import type { IExecuteFunctions, INode, INodeExecutionData } from 'n8n-workflow'
|
||||||
import { ExecuteWorkflowTrigger } from '../ExecuteWorkflowTrigger.node';
|
import { ExecuteWorkflowTrigger } from '../ExecuteWorkflowTrigger.node';
|
||||||
|
|
||||||
describe('ExecuteWorkflowTrigger', () => {
|
describe('ExecuteWorkflowTrigger', () => {
|
||||||
it('should return its input data', async () => {
|
it('should return its input data on V1', async () => {
|
||||||
const mockInputData: INodeExecutionData[] = [
|
const mockInputData: INodeExecutionData[] = [
|
||||||
{ json: { item: 0, foo: 'bar' } },
|
{ json: { item: 0, foo: 'bar' } },
|
||||||
{ json: { item: 1, foo: 'quz' } },
|
{ json: { item: 1, foo: 'quz' } },
|
||||||
|
|
|
@ -864,6 +864,7 @@
|
||||||
"fast-glob": "catalog:",
|
"fast-glob": "catalog:",
|
||||||
"fflate": "0.7.4",
|
"fflate": "0.7.4",
|
||||||
"get-system-fonts": "2.0.2",
|
"get-system-fonts": "2.0.2",
|
||||||
|
"generate-schema": "2.6.0",
|
||||||
"gm": "1.25.0",
|
"gm": "1.25.0",
|
||||||
"html-to-text": "9.0.5",
|
"html-to-text": "9.0.5",
|
||||||
"iconv-lite": "0.6.3",
|
"iconv-lite": "0.6.3",
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
"credentials/**/*.ts",
|
"credentials/**/*.ts",
|
||||||
"nodes/**/*.ts",
|
"nodes/**/*.ts",
|
||||||
"nodes/**/*.json",
|
"nodes/**/*.json",
|
||||||
"credentials/translations/**/*.json"
|
"credentials/translations/**/*.json",
|
||||||
|
"types/**/*.ts"
|
||||||
],
|
],
|
||||||
"exclude": ["nodes/**/*.test.ts", "credentials/**/*.test.ts", "test/**"]
|
"exclude": ["nodes/**/*.test.ts", "credentials/**/*.test.ts", "test/**"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,13 @@
|
||||||
"noImplicitReturns": false,
|
"noImplicitReturns": false,
|
||||||
"useUnknownInCatchVariables": false
|
"useUnknownInCatchVariables": false
|
||||||
},
|
},
|
||||||
"include": ["credentials/**/*.ts", "nodes/**/*.ts", "test/**/*.ts", "utils/**/*.ts"],
|
"include": [
|
||||||
|
"credentials/**/*.ts",
|
||||||
|
"nodes/**/*.ts",
|
||||||
|
"test/**/*.ts",
|
||||||
|
"utils/**/*.ts",
|
||||||
|
"types/**/*.ts"
|
||||||
|
],
|
||||||
"references": [
|
"references": [
|
||||||
{ "path": "../@n8n/imap/tsconfig.build.json" },
|
{ "path": "../@n8n/imap/tsconfig.build.json" },
|
||||||
{ "path": "../workflow/tsconfig.build.json" },
|
{ "path": "../workflow/tsconfig.build.json" },
|
||||||
|
|
27
packages/nodes-base/types/generate-schema.d.ts
vendored
Normal file
27
packages/nodes-base/types/generate-schema.d.ts
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
declare module 'generate-schema' {
|
||||||
|
export interface SchemaObject {
|
||||||
|
$schema: string;
|
||||||
|
title?: string;
|
||||||
|
type: string;
|
||||||
|
properties?: {
|
||||||
|
[key: string]: SchemaObject | SchemaArray | SchemaProperty;
|
||||||
|
};
|
||||||
|
required?: string[];
|
||||||
|
items?: SchemaObject | SchemaArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SchemaArray {
|
||||||
|
type: string;
|
||||||
|
items?: SchemaObject | SchemaArray | SchemaProperty;
|
||||||
|
oneOf?: Array<SchemaObject | SchemaArray | SchemaProperty>;
|
||||||
|
required?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SchemaProperty {
|
||||||
|
type: string | string[];
|
||||||
|
format?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function json(title: string, schema: SchemaObject): SchemaObject;
|
||||||
|
export function json(schema: SchemaObject): SchemaObject;
|
||||||
|
}
|
|
@ -1111,7 +1111,7 @@ importers:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@langchain/core':
|
'@langchain/core':
|
||||||
specifier: 'catalog:'
|
specifier: 'catalog:'
|
||||||
version: 0.3.15(openai@4.69.0(zod@3.23.8))
|
version: 0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))
|
||||||
'@n8n/client-oauth2':
|
'@n8n/client-oauth2':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../@n8n/client-oauth2
|
version: link:../@n8n/client-oauth2
|
||||||
|
@ -1662,6 +1662,9 @@ importers:
|
||||||
fflate:
|
fflate:
|
||||||
specifier: 0.7.4
|
specifier: 0.7.4
|
||||||
version: 0.7.4
|
version: 0.7.4
|
||||||
|
generate-schema:
|
||||||
|
specifier: 2.6.0
|
||||||
|
version: 2.6.0
|
||||||
get-system-fonts:
|
get-system-fonts:
|
||||||
specifier: 2.0.2
|
specifier: 2.0.2
|
||||||
version: 2.0.2
|
version: 2.0.2
|
||||||
|
@ -1939,7 +1942,7 @@ importers:
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@langchain/core':
|
'@langchain/core':
|
||||||
specifier: 'catalog:'
|
specifier: 'catalog:'
|
||||||
version: 0.3.15(openai@4.69.0)
|
version: 0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))
|
||||||
'@types/deep-equal':
|
'@types/deep-equal':
|
||||||
specifier: ^1.0.1
|
specifier: ^1.0.1
|
||||||
version: 1.0.1
|
version: 1.0.1
|
||||||
|
@ -14657,38 +14660,6 @@ snapshots:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- openai
|
- openai
|
||||||
|
|
||||||
'@langchain/core@0.3.15(openai@4.69.0(zod@3.23.8))':
|
|
||||||
dependencies:
|
|
||||||
ansi-styles: 5.2.0
|
|
||||||
camelcase: 6.3.0
|
|
||||||
decamelize: 1.2.0
|
|
||||||
js-tiktoken: 1.0.12
|
|
||||||
langsmith: 0.2.3(openai@4.69.0(zod@3.23.8))
|
|
||||||
mustache: 4.2.0
|
|
||||||
p-queue: 6.6.2
|
|
||||||
p-retry: 4.6.2
|
|
||||||
uuid: 10.0.0
|
|
||||||
zod: 3.23.8
|
|
||||||
zod-to-json-schema: 3.23.3(zod@3.23.8)
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- openai
|
|
||||||
|
|
||||||
'@langchain/core@0.3.15(openai@4.69.0)':
|
|
||||||
dependencies:
|
|
||||||
ansi-styles: 5.2.0
|
|
||||||
camelcase: 6.3.0
|
|
||||||
decamelize: 1.2.0
|
|
||||||
js-tiktoken: 1.0.12
|
|
||||||
langsmith: 0.2.3(openai@4.69.0)
|
|
||||||
mustache: 4.2.0
|
|
||||||
p-queue: 6.6.2
|
|
||||||
p-retry: 4.6.2
|
|
||||||
uuid: 10.0.0
|
|
||||||
zod: 3.23.8
|
|
||||||
zod-to-json-schema: 3.23.3(zod@3.23.8)
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- openai
|
|
||||||
|
|
||||||
'@langchain/google-common@0.1.1(@langchain/core@0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8)))(zod@3.23.8)':
|
'@langchain/google-common@0.1.1(@langchain/core@0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8)))(zod@3.23.8)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@langchain/core': 0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))
|
'@langchain/core': 0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))
|
||||||
|
@ -20420,7 +20391,7 @@ snapshots:
|
||||||
isstream: 0.1.2
|
isstream: 0.1.2
|
||||||
jsonwebtoken: 9.0.2
|
jsonwebtoken: 9.0.2
|
||||||
mime-types: 2.1.35
|
mime-types: 2.1.35
|
||||||
retry-axios: 2.6.0(axios@1.7.4(debug@4.3.7))
|
retry-axios: 2.6.0(axios@1.7.4)
|
||||||
tough-cookie: 4.1.3
|
tough-cookie: 4.1.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
@ -21451,28 +21422,6 @@ snapshots:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
openai: 4.69.0(encoding@0.1.13)(zod@3.23.8)
|
openai: 4.69.0(encoding@0.1.13)(zod@3.23.8)
|
||||||
|
|
||||||
langsmith@0.2.3(openai@4.69.0(zod@3.23.8)):
|
|
||||||
dependencies:
|
|
||||||
'@types/uuid': 10.0.0
|
|
||||||
commander: 10.0.1
|
|
||||||
p-queue: 6.6.2
|
|
||||||
p-retry: 4.6.2
|
|
||||||
semver: 7.6.0
|
|
||||||
uuid: 10.0.0
|
|
||||||
optionalDependencies:
|
|
||||||
openai: 4.69.0(zod@3.23.8)
|
|
||||||
|
|
||||||
langsmith@0.2.3(openai@4.69.0):
|
|
||||||
dependencies:
|
|
||||||
'@types/uuid': 10.0.0
|
|
||||||
commander: 10.0.1
|
|
||||||
p-queue: 6.6.2
|
|
||||||
p-retry: 4.6.2
|
|
||||||
semver: 7.6.0
|
|
||||||
uuid: 10.0.0
|
|
||||||
optionalDependencies:
|
|
||||||
openai: 4.69.0(zod@3.23.8)
|
|
||||||
|
|
||||||
lazy-ass@1.6.0: {}
|
lazy-ass@1.6.0: {}
|
||||||
|
|
||||||
ldapts@4.2.6:
|
ldapts@4.2.6:
|
||||||
|
@ -22807,22 +22756,6 @@ snapshots:
|
||||||
- encoding
|
- encoding
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
openai@4.69.0(zod@3.23.8):
|
|
||||||
dependencies:
|
|
||||||
'@types/node': 18.16.16
|
|
||||||
'@types/node-fetch': 2.6.4
|
|
||||||
abort-controller: 3.0.0
|
|
||||||
agentkeepalive: 4.2.1
|
|
||||||
form-data-encoder: 1.7.2
|
|
||||||
formdata-node: 4.4.1
|
|
||||||
node-fetch: 2.7.0(encoding@0.1.13)
|
|
||||||
optionalDependencies:
|
|
||||||
zod: 3.23.8
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- encoding
|
|
||||||
- supports-color
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
openapi-sampler@1.5.1:
|
openapi-sampler@1.5.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/json-schema': 7.0.15
|
'@types/json-schema': 7.0.15
|
||||||
|
@ -23807,9 +23740,9 @@ snapshots:
|
||||||
|
|
||||||
ret@0.1.15: {}
|
ret@0.1.15: {}
|
||||||
|
|
||||||
retry-axios@2.6.0(axios@1.7.4(debug@4.3.7)):
|
retry-axios@2.6.0(axios@1.7.4):
|
||||||
dependencies:
|
dependencies:
|
||||||
axios: 1.7.4(debug@4.3.7)
|
axios: 1.7.4
|
||||||
|
|
||||||
retry-request@7.0.2(encoding@0.1.13):
|
retry-request@7.0.2(encoding@0.1.13):
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
Loading…
Reference in a new issue