fix(core): Prevent re-parsing of dynamically loaded options (#9503)

This commit is contained in:
Iván Ovejero 2024-05-24 11:00:15 +02:00 committed by GitHub
parent 24e8ac00c6
commit a58be175cc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 40 additions and 7 deletions

View file

@ -1,5 +1,4 @@
import type { INodePropertyOptions } from 'n8n-workflow'; import type { INodePropertyOptions } from 'n8n-workflow';
import { jsonParse } from 'n8n-workflow';
import { Post, RestController } from '@/decorators'; import { Post, RestController } from '@/decorators';
import { getBase } from '@/WorkflowExecuteAdditionalData'; import { getBase } from '@/WorkflowExecuteAdditionalData';
@ -37,7 +36,7 @@ export class DynamicNodeParametersController {
if (loadOptions) { if (loadOptions) {
return await this.service.getOptionsViaLoadOptions( return await this.service.getOptionsViaLoadOptions(
jsonParse(loadOptions), loadOptions,
additionalData, additionalData,
nodeTypeAndVersion, nodeTypeAndVersion,
currentNodeParameters, currentNodeParameters,

View file

@ -3,6 +3,7 @@ import type {
BannerName, BannerName,
ICredentialDataDecryptedObject, ICredentialDataDecryptedObject,
IDataObject, IDataObject,
ILoadOptions,
INodeCredentialTestRequest, INodeCredentialTestRequest,
INodeCredentials, INodeCredentials,
INodeParameters, INodeParameters,
@ -406,19 +407,19 @@ export declare namespace DynamicNodeParametersRequest {
{} {}
>; >;
/** GET /dynamic-node-parameters/options */ /** POST /dynamic-node-parameters/options */
type Options = BaseRequest<{ type Options = BaseRequest<{
loadOptions?: string; loadOptions?: ILoadOptions;
}>; }>;
/** GET /dynamic-node-parameters/resource-locator-results */ /** POST /dynamic-node-parameters/resource-locator-results */
type ResourceLocatorResults = BaseRequest<{ type ResourceLocatorResults = BaseRequest<{
methodName: string; methodName: string;
filter?: string; filter?: string;
paginationToken?: string; paginationToken?: string;
}>; }>;
/** GET dynamic-node-parameters/resource-mapper-fields */ /** POST dynamic-node-parameters/resource-mapper-fields */
type ResourceMapperFields = BaseRequest<{ type ResourceMapperFields = BaseRequest<{
methodName: string; methodName: string;
}>; }>;

View file

@ -39,7 +39,7 @@ describe('DynamicNodeParametersController', () => {
.post('/dynamic-node-parameters/options') .post('/dynamic-node-parameters/options')
.send({ .send({
...commonRequestParams, ...commonRequestParams,
loadOptions: 'loadOptions', loadOptions: {},
}) })
.expect(200); .expect(200);
}); });

View file

@ -0,0 +1,33 @@
import { DynamicNodeParametersController } from '@/controllers/dynamicNodeParameters.controller';
import type { DynamicNodeParametersRequest } from '@/requests';
import type { DynamicNodeParametersService } from '@/services/dynamicNodeParameters.service';
import { mock } from 'jest-mock-extended';
import * as AdditionalData from '@/WorkflowExecuteAdditionalData';
import type { ILoadOptions, IWorkflowExecuteAdditionalData } from 'n8n-workflow';
describe('DynamicNodeParametersController', () => {
const service = mock<DynamicNodeParametersService>();
const controller = new DynamicNodeParametersController(service);
beforeEach(() => {
jest.clearAllMocks();
});
describe('getOptions', () => {
it('should take `loadOptions` as object', async () => {
jest
.spyOn(AdditionalData, 'getBase')
.mockResolvedValue(mock<IWorkflowExecuteAdditionalData>());
const req = mock<DynamicNodeParametersRequest.Options>();
const loadOptions: ILoadOptions = {};
req.body.loadOptions = loadOptions;
await controller.getOptions(req);
const zerothArg = service.getOptionsViaLoadOptions.mock.calls[0][0];
expect(zerothArg).toEqual(loadOptions);
});
});
});