mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-02 07:01:30 -08:00
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:
parent
8a94f1e361
commit
39a6f41720
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue