mirror of
https://github.com/n8n-io/n8n.git
synced 2024-09-19 22:37:31 -07:00
Add schemas for ftp and sftp
This commit is contained in:
parent
6f15aa6a88
commit
2d40b299df
|
@ -1,4 +1,14 @@
|
|||
import type { ICredentialType, INodeProperties } from 'n8n-workflow';
|
||||
import type { ICredentialType } from 'n8n-workflow';
|
||||
import { CredentialSchema, type InferCredentialSchema } from '../utils/CredentialSchema';
|
||||
|
||||
const ftpCredentialSchema = CredentialSchema.create({
|
||||
host: CredentialSchema.string({ label: 'Host', placeholder: 'localhost' }),
|
||||
port: CredentialSchema.number({ label: 'Port', default: 21 }),
|
||||
username: CredentialSchema.string({ label: 'Username', optional: true }),
|
||||
password: CredentialSchema.password({ optional: true }),
|
||||
});
|
||||
|
||||
export type FtpCredentialSchema = InferCredentialSchema<typeof ftpCredentialSchema>;
|
||||
|
||||
export class Ftp implements ICredentialType {
|
||||
name = 'ftp';
|
||||
|
@ -7,36 +17,5 @@ export class Ftp implements ICredentialType {
|
|||
|
||||
documentationUrl = 'ftp';
|
||||
|
||||
properties: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Host',
|
||||
name: 'host',
|
||||
required: true,
|
||||
type: 'string',
|
||||
default: '',
|
||||
placeholder: 'localhost',
|
||||
},
|
||||
{
|
||||
displayName: 'Port',
|
||||
name: 'port',
|
||||
required: true,
|
||||
type: 'number',
|
||||
default: 21,
|
||||
},
|
||||
{
|
||||
displayName: 'Username',
|
||||
name: 'username',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Password',
|
||||
name: 'password',
|
||||
type: 'string',
|
||||
typeOptions: {
|
||||
password: true,
|
||||
},
|
||||
default: '',
|
||||
},
|
||||
];
|
||||
properties = ftpCredentialSchema.toNodeProperties();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,23 @@
|
|||
import type { ICredentialType, INodeProperties } from 'n8n-workflow';
|
||||
import type { ICredentialType } from 'n8n-workflow';
|
||||
import { CredentialSchema, type InferCredentialSchema } from '../utils/CredentialSchema';
|
||||
|
||||
const sftpCredentialSchema = CredentialSchema.create({
|
||||
host: CredentialSchema.string({ label: 'Host', placeholder: 'localhost' }),
|
||||
port: CredentialSchema.number({ label: 'Port', default: 22 }),
|
||||
username: CredentialSchema.string({ label: 'Username' }),
|
||||
password: CredentialSchema.password(),
|
||||
privateKey: CredentialSchema.password({
|
||||
label: 'Private Key',
|
||||
description:
|
||||
'String that contains a private key for either key-based or hostbased user authentication (OpenSSH format)',
|
||||
}),
|
||||
passphrase: CredentialSchema.password({
|
||||
label: 'Passphrase',
|
||||
description: 'For an encrypted private key, this is the passphrase used to decrypt it',
|
||||
}),
|
||||
});
|
||||
|
||||
export type SftpCredentialSchema = InferCredentialSchema<typeof sftpCredentialSchema>;
|
||||
|
||||
export class Sftp implements ICredentialType {
|
||||
name = 'sftp';
|
||||
|
@ -7,55 +26,5 @@ export class Sftp implements ICredentialType {
|
|||
|
||||
documentationUrl = 'ftp';
|
||||
|
||||
properties: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Host',
|
||||
name: 'host',
|
||||
required: true,
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Port',
|
||||
name: 'port',
|
||||
required: true,
|
||||
type: 'number',
|
||||
default: 22,
|
||||
},
|
||||
{
|
||||
displayName: 'Username',
|
||||
name: 'username',
|
||||
required: true,
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Password',
|
||||
name: 'password',
|
||||
type: 'string',
|
||||
typeOptions: {
|
||||
password: true,
|
||||
},
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Private Key',
|
||||
name: 'privateKey',
|
||||
type: 'string',
|
||||
typeOptions: { password: true },
|
||||
default: '',
|
||||
description:
|
||||
'String that contains a private key for either key-based or hostbased user authentication (OpenSSH format)',
|
||||
},
|
||||
{
|
||||
displayName: 'Passphrase',
|
||||
name: 'passphrase',
|
||||
typeOptions: {
|
||||
password: true,
|
||||
},
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'For an encrypted private key, this is the passphrase used to decrypt it',
|
||||
},
|
||||
];
|
||||
properties = sftpCredentialSchema.toNodeProperties();
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import ftpClient from 'promise-ftp';
|
|||
import sftpClient from 'ssh2-sftp-client';
|
||||
import { BINARY_ENCODING, NodeApiError } from 'n8n-workflow';
|
||||
import type {
|
||||
ICredentialDataDecryptedObject,
|
||||
ICredentialsDecrypted,
|
||||
ICredentialTestFunctions,
|
||||
IDataObject,
|
||||
|
@ -18,6 +17,8 @@ import type {
|
|||
INodeTypeDescription,
|
||||
JsonObject,
|
||||
} from 'n8n-workflow';
|
||||
import type { FtpCredentialSchema } from '@credentials/Ftp.credentials';
|
||||
import type { SftpCredentialSchema } from '@credentials/Sftp.credentials';
|
||||
import { formatPrivateKey, generatePairedItemData } from '@utils/utilities';
|
||||
|
||||
interface ReturnFtpItem {
|
||||
|
@ -439,14 +440,14 @@ export class Ftp implements INodeType {
|
|||
this: ICredentialTestFunctions,
|
||||
credential: ICredentialsDecrypted,
|
||||
): Promise<INodeCredentialTestResult> {
|
||||
const credentials = credential.data as ICredentialDataDecryptedObject;
|
||||
const credentials = credential.data as FtpCredentialSchema;
|
||||
const ftp = new ftpClient();
|
||||
try {
|
||||
await ftp.connect({
|
||||
host: credentials.host as string,
|
||||
port: credentials.port as number,
|
||||
user: credentials.username as string,
|
||||
password: credentials.password as string,
|
||||
host: credentials.host,
|
||||
port: credentials.port,
|
||||
user: credentials.username,
|
||||
password: credentials.password,
|
||||
});
|
||||
} catch (error) {
|
||||
await ftp.end();
|
||||
|
@ -465,24 +466,24 @@ export class Ftp implements INodeType {
|
|||
this: ICredentialTestFunctions,
|
||||
credential: ICredentialsDecrypted,
|
||||
): Promise<INodeCredentialTestResult> {
|
||||
const credentials = credential.data as ICredentialDataDecryptedObject;
|
||||
const credentials = credential.data as SftpCredentialSchema;
|
||||
const sftp = new sftpClient();
|
||||
try {
|
||||
if (credentials.privateKey) {
|
||||
await sftp.connect({
|
||||
host: credentials.host as string,
|
||||
port: credentials.port as number,
|
||||
username: credentials.username as string,
|
||||
password: (credentials.password as string) || undefined,
|
||||
privateKey: formatPrivateKey(credentials.privateKey as string),
|
||||
passphrase: credentials.passphrase as string | undefined,
|
||||
host: credentials.host,
|
||||
port: credentials.port,
|
||||
username: credentials.username,
|
||||
password: credentials.password || undefined,
|
||||
privateKey: formatPrivateKey(credentials.privateKey),
|
||||
passphrase: credentials.passphrase,
|
||||
});
|
||||
} else {
|
||||
await sftp.connect({
|
||||
host: credentials.host as string,
|
||||
port: credentials.port as number,
|
||||
username: credentials.username as string,
|
||||
password: credentials.password as string,
|
||||
host: credentials.host,
|
||||
port: credentials.port,
|
||||
username: credentials.username,
|
||||
password: credentials.password,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
|
@ -516,30 +517,30 @@ export class Ftp implements INodeType {
|
|||
try {
|
||||
if (protocol === 'sftp') {
|
||||
sftp = new sftpClient();
|
||||
if (credentials.privateKey) {
|
||||
if ('privateKey' in credentials && credentials.privateKey) {
|
||||
await sftp.connect({
|
||||
host: credentials.host as string,
|
||||
port: credentials.port as number,
|
||||
username: credentials.username as string,
|
||||
password: (credentials.password as string) || undefined,
|
||||
privateKey: formatPrivateKey(credentials.privateKey as string),
|
||||
passphrase: credentials.passphrase as string | undefined,
|
||||
host: credentials.host,
|
||||
port: credentials.port,
|
||||
username: credentials.username,
|
||||
password: credentials.password || undefined,
|
||||
privateKey: formatPrivateKey(credentials.privateKey),
|
||||
passphrase: credentials.passphrase,
|
||||
});
|
||||
} else {
|
||||
await sftp.connect({
|
||||
host: credentials.host as string,
|
||||
port: credentials.port as number,
|
||||
username: credentials.username as string,
|
||||
password: credentials.password as string,
|
||||
host: credentials.host,
|
||||
port: credentials.port,
|
||||
username: credentials.username,
|
||||
password: credentials.password,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
ftp = new ftpClient();
|
||||
await ftp.connect({
|
||||
host: credentials.host as string,
|
||||
port: credentials.port as number,
|
||||
user: credentials.username as string,
|
||||
password: credentials.password as string,
|
||||
host: credentials.host,
|
||||
port: credentials.port,
|
||||
user: credentials.username,
|
||||
password: credentials.password,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
|
|
|
@ -9,7 +9,7 @@ import type {
|
|||
JsonObject,
|
||||
} from 'n8n-workflow';
|
||||
import { NodeApiError } from 'n8n-workflow';
|
||||
import type { StrapiApiCredential } from '../../credentials/StrapiApi.credentials';
|
||||
import type { StrapiApiCredential } from '@credentials/StrapiApi.credentials';
|
||||
|
||||
export const removeTrailingSlash = (url: string) => {
|
||||
if (url.endsWith('/')) {
|
||||
|
|
|
@ -11,7 +11,6 @@ import type {
|
|||
} from 'n8n-workflow';
|
||||
import { NodeOperationError } from 'n8n-workflow';
|
||||
|
||||
import type { StrapiApiCredential } from '../../credentials/StrapiApi.credentials';
|
||||
import {
|
||||
getToken,
|
||||
removeTrailingSlash,
|
||||
|
@ -21,6 +20,7 @@ import {
|
|||
} from './GenericFunctions';
|
||||
|
||||
import { entryFields, entryOperations } from './EntryDescription';
|
||||
import type { StrapiApiCredential } from '@credentials/StrapiApi.credentials';
|
||||
|
||||
export class Strapi implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
"lib": ["dom", "es2020", "es2022.error"],
|
||||
"paths": {
|
||||
"@test/*": ["./test/*"],
|
||||
"@utils/*": ["./utils/*"]
|
||||
"@utils/*": ["./utils/*"],
|
||||
"@nodes/*": ["./nodes/*"],
|
||||
"@credentials/*": ["./credentials/*"]
|
||||
},
|
||||
"tsBuildInfoFile": "dist/typecheck.tsbuildinfo",
|
||||
// TODO: remove all options below this line
|
||||
|
|
4
packages/nodes-base/types.d.ts
vendored
4
packages/nodes-base/types.d.ts
vendored
|
@ -1,9 +1,13 @@
|
|||
import type { FtpCredentialSchema } from './credentials/Ftp.credentials';
|
||||
import type { SftpCredentialSchema } from './credentials/Sftp.credentials';
|
||||
import type { StrapiApiCredential } from './credentials/StrapiApi.credentials';
|
||||
import type { StrapiTokenApiCredential } from './credentials/StrapiTokenApi.credentials';
|
||||
|
||||
type CredentialSchemaMap = {
|
||||
strapiApi: StrapiApiCredential;
|
||||
strapiTokenApi: StrapiTokenApiCredential;
|
||||
ftp: FtpCredentialSchema;
|
||||
sftp: SftpCredentialSchema;
|
||||
};
|
||||
|
||||
declare module 'n8n-workflow' {
|
||||
|
|
|
@ -103,6 +103,26 @@ class CredentialSchemaString<
|
|||
}
|
||||
}
|
||||
|
||||
class CredentialSchemaNumber<
|
||||
S extends ZodType,
|
||||
M extends NumberMetadata,
|
||||
> extends CredentialSchemaProperty<M, S> {
|
||||
constructor(
|
||||
public metadata: M,
|
||||
schema: S,
|
||||
) {
|
||||
super(metadata, schema);
|
||||
}
|
||||
|
||||
toNodeProperties(name: string): INodeProperties {
|
||||
return removeUndefinedProperties({
|
||||
...super.toNodeProperties(name),
|
||||
type: 'number',
|
||||
default: this.metadata.default,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class CredentialSchemaOptions<
|
||||
V extends string,
|
||||
S extends ZodType,
|
||||
|
@ -157,6 +177,11 @@ type StringMetadata = BaseMetadata &
|
|||
default: string;
|
||||
}>;
|
||||
|
||||
type NumberMetadata = BaseMetadata &
|
||||
Partial<{
|
||||
default: number;
|
||||
}>;
|
||||
|
||||
type Option<V extends string> = {
|
||||
label: string;
|
||||
value: V;
|
||||
|
@ -210,6 +235,10 @@ export const CredentialSchema = {
|
|||
string<M extends StringMetadata>(options: M) {
|
||||
return new CredentialSchemaString(options, z.string());
|
||||
},
|
||||
// eslint-disable-next-line id-denylist
|
||||
number<M extends NumberMetadata>(options: M) {
|
||||
return new CredentialSchemaNumber(options, z.number());
|
||||
},
|
||||
url(options: Optional<StringMetadata, 'label'> = {}) {
|
||||
return new CredentialSchemaString({ label: 'URL', ...options }, z.string().url());
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue