feat: Implement quick connect module and configuration provider (#25231)

This commit is contained in:
Dimitri Lavrenük
2026-02-04 13:56:47 +01:00
committed by GitHub
parent f4de4300a2
commit 1e1e459784
6 changed files with 103 additions and 0 deletions
@@ -34,6 +34,7 @@ describe('eligibleModules', () => {
'sso-saml',
'log-streaming',
'ldap',
'quick-connect',
]);
});
@@ -54,6 +55,7 @@ describe('eligibleModules', () => {
'sso-saml',
'log-streaming',
'ldap',
'quick-connect',
]);
});
@@ -44,6 +44,7 @@ export class ModuleRegistry {
'sso-saml',
'log-streaming',
'ldap',
'quick-connect',
];
private readonly activeModules: string[] = [];
@@ -17,6 +17,7 @@ export const MODULE_NAMES = [
'sso-saml',
'log-streaming',
'ldap',
'quick-connect',
] as const;
export type ModuleName = (typeof MODULE_NAMES)[number];
@@ -0,0 +1,51 @@
import { Container } from '@n8n/di';
import { QuickConnectConfig } from '../quick-connect.config';
describe('QuickConnectConfig', () => {
beforeEach(() => {
Container.reset();
});
afterEach(() => {
delete process.env.N8N_QUICK_CONNECT_OPTIONS;
});
it('returns an empty options array per default', () => {
const { options } = Container.get(QuickConnectConfig);
expect(options).toEqual([]);
});
it('returns configured options given valid format', () => {
const testConfig = [
{
packageName: '@n8n/superagent',
credentialType: 'agentApi',
text: 'Superagent for everyone',
quickConnectType: 'oauth',
},
];
process.env.N8N_QUICK_CONNECT_OPTIONS = JSON.stringify(testConfig);
const { options } = Container.get(QuickConnectConfig);
expect(options).toEqual(testConfig);
});
it.each([
'no-json',
JSON.stringify([
{
credentialType: 'agentApi',
text: 'Superagent for everyone',
quickConnectType: 'oauth',
},
]),
])('uses default if configuration is invalid: %s', (config) => {
process.env.N8N_QUICK_CONNECT_OPTIONS = config;
const { options } = Container.get(QuickConnectConfig);
expect(options).toEqual([]);
});
});
@@ -0,0 +1,31 @@
import { Config, Env } from '@n8n/config';
import { z } from 'zod';
const quickConnectOptionsSchema = z.string().pipe(
z.preprocess(
(input: string) => {
try {
return JSON.parse(input);
} catch {
return [];
}
},
z.array(
z.object({
packageName: z.string(),
credentialType: z.string(),
text: z.string(),
quickConnectType: z.string(),
}),
),
),
);
type QuickConnectOptions = z.infer<typeof quickConnectOptionsSchema>;
@Config
export class QuickConnectConfig {
/** Promoted quick connect options */
@Env('N8N_QUICK_CONNECT_OPTIONS', quickConnectOptionsSchema)
options: QuickConnectOptions = [];
}
@@ -0,0 +1,17 @@
import type { ModuleInterface } from '@n8n/decorators';
import { BackendModule } from '@n8n/decorators';
import { Container } from '@n8n/di';
@BackendModule({ name: 'quick-connect' })
export class QuickConnectModule implements ModuleInterface {
/**
* Settings exposed to the frontend under `/rest/module-settings`.
*
* The response shape will be `{ options: [{ packageName: string, credentialType: string, text: string, quickConnectType: string }]}`.
*/
async settings() {
const { QuickConnectConfig } = await import('./quick-connect.config');
const { options } = Container.get(QuickConnectConfig);
return { options };
}
}