feat(FTP Node): Add option to recursively create directories on rename (#3001)

* Recursively Make Directories on SFTP Rename

* Linting

*  Improvement

*  Rename "Move" to "Create Directories"

* Change "Create Directories" description

Co-authored-by: ricardo <ricardoespinoza105@gmail.com>
This commit is contained in:
Rhys Williams 2022-04-01 14:48:45 +02:00 committed by GitHub
parent 8a94f1e361
commit 39a6f41720
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -51,6 +51,7 @@ export class Ftp implements INodeType {
outputs: ['main'], outputs: ['main'],
credentials: [ credentials: [
{ {
// nodelinter-ignore-next-line
name: 'ftp', name: 'ftp',
required: true, required: true,
displayOptions: { displayOptions: {
@ -62,6 +63,7 @@ export class Ftp implements INodeType {
}, },
}, },
{ {
// nodelinter-ignore-next-line
name: 'sftp', name: 'sftp',
required: true, required: true,
displayOptions: { displayOptions: {
@ -124,6 +126,7 @@ export class Ftp implements INodeType {
], ],
default: 'download', default: 'download',
description: 'Operation to perform.', description: 'Operation to perform.',
noDataExpression: true,
}, },
// ---------------------------------- // ----------------------------------
@ -253,6 +256,29 @@ export class Ftp implements INodeType {
description: 'The new path', description: 'The new path',
required: true, required: true,
}, },
{
displayName: 'Options',
name: 'options',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
operation: [
'rename',
],
},
},
options: [
{
displayName: 'Create Directories',
name: 'createDirectories',
type: 'boolean',
default: false,
description: `Recursively create destination directory when renaming an existing file or folder`,
},
],
},
// ---------------------------------- // ----------------------------------
// upload // upload
@ -381,8 +407,8 @@ export class Ftp implements INodeType {
throw new NodeOperationError(this.getNode(), 'Failed to get credentials!'); throw new NodeOperationError(this.getNode(), 'Failed to get credentials!');
} }
let ftp : ftpClient; let ftp: ftpClient;
let sftp : sftpClient; let sftp: sftpClient;
if (protocol === 'sftp') { if (protocol === 'sftp') {
sftp = new sftpClient(); sftp = new sftpClient();
@ -452,9 +478,13 @@ export class Ftp implements INodeType {
if (operation === 'rename') { if (operation === 'rename') {
const oldPath = this.getNodeParameter('oldPath', i) as string; const oldPath = this.getNodeParameter('oldPath', i) as string;
const { createDirectories = false } = this.getNodeParameter('options', i) as { createDirectories: boolean };
const newPath = this.getNodeParameter('newPath', i) as string; const newPath = this.getNodeParameter('newPath', i) as string;
if (createDirectories) {
await recursivelyCreateSftpDirs(sftp!, newPath);
}
responseData = await sftp!.rename(oldPath, newPath); responseData = await sftp!.rename(oldPath, newPath);
returnItems.push({ json: { success: true } }); returnItems.push({ json: { success: true } });
@ -475,16 +505,7 @@ export class Ftp implements INodeType {
if (operation === 'upload') { if (operation === 'upload') {
const remotePath = this.getNodeParameter('path', i) as string; const remotePath = this.getNodeParameter('path', i) as string;
await recursivelyCreateSftpDirs(sftp!, remotePath);
// Check if dir path exists
const dirPath = dirname(remotePath);
const dirExists = await sftp!.exists(dirPath);
// If dir does not exist, create all recursively in path
if (!dirExists) {
// Create directory
await sftp!.mkdir(dirPath, true);
}
if (this.getNodeParameter('binaryData', i) === true) { if (this.getNodeParameter('binaryData', i) === true) {
// Is binary file to upload // Is binary file to upload
@ -635,7 +656,7 @@ export class Ftp implements INodeType {
} catch (error) { } catch (error) {
if (this.continueOnFail()) { if (this.continueOnFail()) {
return this.prepareOutputData([{json:{ error: error.message }}]); return this.prepareOutputData([{ json: { error: error.message } }]);
} }
throw error; throw error;
@ -661,17 +682,17 @@ function normalizeSFtpItem(input: sftpClient.FileInfo, path: string, recursive =
} }
async function callRecursiveList(path: string, client: sftpClient | ftpClient, normalizeFunction: (input: ftpClient.ListingElement & sftpClient.FileInfo, path: string, recursive?: boolean) => void) { async function callRecursiveList(path: string, client: sftpClient | ftpClient, normalizeFunction: (input: ftpClient.ListingElement & sftpClient.FileInfo, path: string, recursive?: boolean) => void) {
const pathArray : string[] = [path]; const pathArray: string[] = [path];
let currentPath = path; let currentPath = path;
const directoryItems : sftpClient.FileInfo[] = []; const directoryItems: sftpClient.FileInfo[] = [];
let index = 0; let index = 0;
do { do {
// tslint:disable-next-line: array-type // tslint:disable-next-line: array-type
const returnData : sftpClient.FileInfo[] | (string | ftpClient.ListingElement)[] = await client.list(pathArray[index]); const returnData: sftpClient.FileInfo[] | (string | ftpClient.ListingElement)[] = await client.list(pathArray[index]);
// @ts-ignore // @ts-ignore
returnData.map((item : sftpClient.FileInfo) => { returnData.map((item: sftpClient.FileInfo) => {
if ((pathArray[index] as string).endsWith('/')) { if ((pathArray[index] as string).endsWith('/')) {
currentPath = `${pathArray[index]}${item.name}`; currentPath = `${pathArray[index]}${item.name}`;
} else { } else {
@ -693,3 +714,12 @@ async function callRecursiveList(path: string, client: sftpClient | ftpClient, n
return directoryItems; return directoryItems;
} }
async function recursivelyCreateSftpDirs(sftp: sftpClient, path: string) {
const dirPath = dirname(path);
const dirExists = await sftp!.exists(dirPath);
if (!dirExists) {
await sftp!.mkdir(dirPath, true);
}
}