fix(editor): Schema preview displays for some empty nodes (#14488)

This commit is contained in:
Elias Meire
2025-04-11 15:47:29 +02:00
committed by GitHub
parent 43ebb1e357
commit 8c352293b5
4 changed files with 88 additions and 43 deletions

View File

@@ -0,0 +1,71 @@
import { getSchemaPreview } from './schemaPreview';
import * as apiUtils from '@/utils/apiUtils';
vi.mock('@/utils/apiUtils');
describe('API: schemaPreview', () => {
describe('getSchemaPreview', () => {
it('should return a valid JSON schema', async () => {
const schema = {
type: 'object',
properties: { count: { type: 'number' }, name: { type: 'string' } },
};
vi.spyOn(apiUtils, 'request').mockResolvedValue(schema);
const schemaResponse = await getSchemaPreview('http://test-n8n-base-url', {
nodeType: 'n8n-nodes-base.test',
version: 1.2,
});
expect(apiUtils.request).toHaveBeenCalledWith({
baseURL: 'http://test-n8n-base-url',
endpoint: 'schemas/n8n-nodes-base.test/1.2.0.json',
method: 'GET',
withCredentials: false,
});
expect(schemaResponse).toEqual(schema);
});
it('should reject an invalid JSON schema', async () => {
const schema = {};
vi.spyOn(apiUtils, 'request').mockResolvedValue(schema);
await expect(
getSchemaPreview('http://test-n8n-base-url', {
nodeType: 'n8n-nodes-base.test',
version: 1.2,
resource: 'contact',
operation: 'create',
}),
).rejects.toEqual(new Error('Invalid JSON schema'));
expect(apiUtils.request).toHaveBeenCalledWith({
baseURL: 'http://test-n8n-base-url',
endpoint: 'schemas/n8n-nodes-base.test/1.2.0/contact/create.json',
method: 'GET',
withCredentials: false,
});
});
it('should parse out nodeType', async () => {
const schema = {
type: 'object',
properties: { count: { type: 'number' }, name: { type: 'string' } },
};
vi.spyOn(apiUtils, 'request').mockResolvedValue(schema);
await getSchemaPreview('http://test.com', {
nodeType: '@n8n/n8n-nodes-base.asana',
version: 1,
resource: 'resource',
operation: 'operation',
});
expect(apiUtils.request).toHaveBeenCalledWith({
method: 'GET',
baseURL: 'http://test.com',
endpoint: 'schemas/n8n-nodes-base.asana/1.0.0/resource/operation.json',
withCredentials: false,
});
});
});
});

View File

@@ -1,6 +1,7 @@
import { request } from '@/utils/apiUtils';
import type { JSONSchema7 } from 'json-schema';
import type { NodeParameterValueType } from 'n8n-workflow';
import { isEmpty } from '@/utils/typesUtils';
export type GetSchemaPreviewOptions = {
nodeType: string;
@@ -13,6 +14,16 @@ const padVersion = (version: number) => {
return version.toString().split('.').concat(['0', '0']).slice(0, 3).join('.');
};
const isNonEmptyJsonSchema = (response: unknown): response is JSONSchema7 => {
return (
!!response &&
typeof response === 'object' &&
'type' in response &&
'properties' in response &&
!isEmpty(response.properties)
);
};
export const getSchemaPreview = async (
baseUrl: string,
options: GetSchemaPreviewOptions,
@@ -22,10 +33,14 @@ export const getSchemaPreview = async (
const path = ['schemas', nodeType.replace('@n8n/', ''), versionString, resource, operation]
.filter(Boolean)
.join('/');
return await request({
const response = await request({
method: 'GET',
baseURL: baseUrl,
endpoint: `${path}.json`,
withCredentials: false,
});
if (!isNonEmptyJsonSchema(response)) throw new Error('Invalid JSON schema');
return response;
};

View File

@@ -1,41 +0,0 @@
import { getSchemaPreview } from '../schemaPreview';
import * as apiUtils from '@/utils/apiUtils';
describe('schemaPreview', () => {
afterEach(() => {
vi.resetAllMocks();
});
vi.mock('@/utils/apiUtils', () => ({
request: vi.fn().mockResolvedValue({ test: 'test' }),
}));
it('should return schema preview', async () => {
const response = await getSchemaPreview('http://test.com', {
nodeType: 'n8n-nodes-base.asana',
version: 1,
resource: 'resource',
operation: 'operation',
});
expect(response).toEqual({ test: 'test' });
});
it('should parse out nodeType', async () => {
const spy = vi.spyOn(apiUtils, 'request');
await getSchemaPreview('http://test.com', {
nodeType: '@n8n/n8n-nodes-base.asana',
version: 1,
resource: 'resource',
operation: 'operation',
});
expect(spy).toHaveBeenCalledWith({
method: 'GET',
baseURL: 'http://test.com',
endpoint: 'schemas/n8n-nodes-base.asana/1.0.0/resource/operation.json',
withCredentials: false,
});
});
});