mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 10:02:05 +00:00
⚡ Add file:search operation to Dropbox Node (#1494)
* ⚡ Add search resource to Dropbox Node * 📚 Add breaking change instructions * ⚡ Add missing credentials * ⚡ Add "simple" parameter to the operation search:query * ⚡ Update breaking change message * ⚡ Improvement Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
This commit is contained in:
@@ -11,21 +11,24 @@ import {
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
dropboxApiRequest
|
||||
dropboxApiRequest,
|
||||
dropboxpiRequestAllItems,
|
||||
getRootDirectory,
|
||||
simplify,
|
||||
} from './GenericFunctions';
|
||||
|
||||
export class Dropbox implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'Dropbox',
|
||||
name: 'dropbox',
|
||||
icon: 'file:dropbox.png',
|
||||
icon: 'file:dropbox.svg',
|
||||
group: ['input'],
|
||||
version: 1,
|
||||
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
||||
description: 'Access data on Dropbox',
|
||||
defaults: {
|
||||
name: 'Dropbox',
|
||||
color: '#0062ff',
|
||||
color: '#007ee5',
|
||||
},
|
||||
inputs: ['main'],
|
||||
outputs: ['main'],
|
||||
@@ -84,6 +87,10 @@ export class Dropbox implements INodeType {
|
||||
name: 'Folder',
|
||||
value: 'folder',
|
||||
},
|
||||
{
|
||||
name: 'Search',
|
||||
value: 'search',
|
||||
},
|
||||
],
|
||||
default: 'file',
|
||||
description: 'The resource to operate on.',
|
||||
@@ -176,6 +183,27 @@ export class Dropbox implements INodeType {
|
||||
description: 'The operation to perform.',
|
||||
},
|
||||
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'search',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Query',
|
||||
value: 'query',
|
||||
},
|
||||
],
|
||||
default: 'query',
|
||||
description: 'The operation to perform.',
|
||||
},
|
||||
|
||||
// ----------------------------------
|
||||
// file
|
||||
// ----------------------------------
|
||||
@@ -419,7 +447,189 @@ export class Dropbox implements INodeType {
|
||||
description: 'Name of the binary property which contains<br />the data for the file to be uploaded.',
|
||||
},
|
||||
|
||||
|
||||
// ----------------------------------
|
||||
// search:query
|
||||
// ----------------------------------
|
||||
{
|
||||
displayName: 'Query',
|
||||
name: 'query',
|
||||
type: 'string',
|
||||
default: '',
|
||||
required: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'query',
|
||||
],
|
||||
resource: [
|
||||
'search',
|
||||
],
|
||||
},
|
||||
},
|
||||
description: ' The string to search for. May match across multiple fields based on the request arguments.',
|
||||
},
|
||||
{
|
||||
displayName: 'File Status',
|
||||
name: 'fileStatus',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'Active',
|
||||
value: 'active',
|
||||
},
|
||||
{
|
||||
name: 'Deleted',
|
||||
value: 'deleted',
|
||||
},
|
||||
],
|
||||
default: 'active',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'query',
|
||||
],
|
||||
resource: [
|
||||
'search',
|
||||
],
|
||||
},
|
||||
},
|
||||
description: ' The string to search for. May match across multiple fields based on the request arguments.',
|
||||
},
|
||||
{
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
type: 'boolean',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'query',
|
||||
],
|
||||
resource: [
|
||||
'search',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: false,
|
||||
description: 'If all results should be returned or only up to a given limit.',
|
||||
},
|
||||
{
|
||||
displayName: 'Limit',
|
||||
name: 'limit',
|
||||
type: 'number',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'search',
|
||||
],
|
||||
operation: [
|
||||
'query',
|
||||
],
|
||||
returnAll: [
|
||||
false,
|
||||
],
|
||||
},
|
||||
},
|
||||
default: 100,
|
||||
description: 'How many results to return.',
|
||||
},
|
||||
{
|
||||
displayName: 'Simple',
|
||||
name: 'simple',
|
||||
type: 'boolean',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'query',
|
||||
],
|
||||
resource: [
|
||||
'search',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: true,
|
||||
description: 'When set to true a simplify version of the response will be used else the raw data.',
|
||||
},
|
||||
{
|
||||
displayName: 'Filters',
|
||||
name: 'filters',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Filter',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'search',
|
||||
],
|
||||
operation: [
|
||||
'query',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'File Categories',
|
||||
name: 'file_categories',
|
||||
type: 'multiOptions',
|
||||
options: [
|
||||
{
|
||||
name: 'Audio (mp3, wav, mid, etc.)',
|
||||
value: 'audio',
|
||||
},
|
||||
{
|
||||
name: 'Document (doc, docx, txt, etc.)',
|
||||
value: 'document',
|
||||
},
|
||||
{
|
||||
name: 'Folder',
|
||||
value: 'folder',
|
||||
},
|
||||
{
|
||||
name: 'Image (jpg, png, gif, etc.)',
|
||||
value: 'image',
|
||||
},
|
||||
{
|
||||
name: 'Other',
|
||||
value: 'other',
|
||||
},
|
||||
{
|
||||
name: 'Dropbox Paper',
|
||||
value: 'paper',
|
||||
},
|
||||
{
|
||||
name: 'PDF',
|
||||
value: 'pdf',
|
||||
},
|
||||
{
|
||||
name: 'Presentation (ppt, pptx, key, etc.)',
|
||||
value: 'presentation',
|
||||
},
|
||||
{
|
||||
name: 'Spreadsheet (xlsx, xls, csv, etc.)',
|
||||
value: 'spreadsheet',
|
||||
},
|
||||
{
|
||||
name: 'Video (avi, wmv, mp4, etc.)',
|
||||
value: 'video',
|
||||
},
|
||||
],
|
||||
default: [],
|
||||
},
|
||||
{
|
||||
displayName: 'File Extensions',
|
||||
name: 'file_extensions',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Multiple can be set separated by comma. Example: jpg,pdf',
|
||||
},
|
||||
{
|
||||
displayName: 'Folder',
|
||||
name: 'path',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'If this field is not specified, this module searches the entire Dropbox',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ----------------------------------
|
||||
// folder
|
||||
@@ -469,7 +679,97 @@ export class Dropbox implements INodeType {
|
||||
placeholder: '/invoices/2019/',
|
||||
description: 'The path of which to list the content.',
|
||||
},
|
||||
|
||||
{
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
type: 'boolean',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'list',
|
||||
],
|
||||
resource: [
|
||||
'folder',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: false,
|
||||
description: 'If all results should be returned or only up to a given limit.',
|
||||
},
|
||||
{
|
||||
displayName: 'Limit',
|
||||
name: 'limit',
|
||||
type: 'number',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'folder',
|
||||
],
|
||||
operation: [
|
||||
'list',
|
||||
],
|
||||
returnAll: [
|
||||
false,
|
||||
],
|
||||
},
|
||||
},
|
||||
default: 100,
|
||||
description: 'How many results to return.',
|
||||
},
|
||||
{
|
||||
displayName: 'Filters',
|
||||
name: 'filters',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Filter',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'folder',
|
||||
],
|
||||
operation: [
|
||||
'list',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Include Deleted',
|
||||
name: 'include_deleted',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'If true, the results will include entries for files and folders that used to exist but were deleted. The default for this field is False.',
|
||||
},
|
||||
{
|
||||
displayName: 'Include Shared Members ',
|
||||
name: 'include_has_explicit_shared_members',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'If true, the results will include a flag for each file indicating whether or not that file has any explicit members. The default for this field is False.',
|
||||
},
|
||||
{
|
||||
displayName: 'Include Mounted Folders ',
|
||||
name: 'include_mounted_folders',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
description: 'If true, the results will include entries under mounted folders which includes app folder, shared folder and team folder. The default for this field is True.',
|
||||
},
|
||||
{
|
||||
displayName: 'Include Non Downloadable Files ',
|
||||
name: 'include_non_downloadable_files',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
description: 'If true, include files that are not downloadable, i.e. Google Docs. The default for this field is True.',
|
||||
},
|
||||
{
|
||||
displayName: 'Recursive',
|
||||
name: 'recursive',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'If true, the list folder operation will be applied recursively to all subfolders and the response will contain contents of all subfolders. The default for this field is False.',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -484,11 +784,24 @@ export class Dropbox implements INodeType {
|
||||
|
||||
let endpoint = '';
|
||||
let requestMethod = '';
|
||||
let returnAll = false;
|
||||
let property = '';
|
||||
let body: IDataObject | Buffer;
|
||||
let options;
|
||||
const query: IDataObject = {};
|
||||
|
||||
const headers: IDataObject = {};
|
||||
let headers: IDataObject = {};
|
||||
let simple = false;
|
||||
|
||||
// get the root directory to set it as the default search folder
|
||||
const { root_info: { root_namespace_id } } = await getRootDirectory.call(this);
|
||||
|
||||
headers = {
|
||||
'dropbox-api-path-root': JSON.stringify({
|
||||
'.tag': 'root',
|
||||
'root': root_namespace_id,
|
||||
}),
|
||||
};
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
body = {};
|
||||
@@ -545,7 +858,6 @@ export class Dropbox implements INodeType {
|
||||
body = Buffer.from(this.getNodeParameter('fileContent', i) as string, 'utf8');
|
||||
}
|
||||
}
|
||||
|
||||
} else if (resource === 'folder') {
|
||||
if (operation === 'create') {
|
||||
// ----------------------------------
|
||||
@@ -564,20 +876,65 @@ export class Dropbox implements INodeType {
|
||||
// list
|
||||
// ----------------------------------
|
||||
|
||||
returnAll = this.getNodeParameter('returnAll', 0) as boolean;
|
||||
|
||||
const filters = this.getNodeParameter('filters', i) as IDataObject;
|
||||
|
||||
property = 'entries';
|
||||
|
||||
requestMethod = 'POST';
|
||||
body = {
|
||||
path: this.getNodeParameter('path', i) as string,
|
||||
limit: 2000,
|
||||
limit: 1000,
|
||||
};
|
||||
|
||||
// TODO: If more files than the max-amount exist it has to be possible to
|
||||
// also request them.
|
||||
if (returnAll === false) {
|
||||
const limit = this.getNodeParameter('limit', 0) as number;
|
||||
body.limit = limit;
|
||||
}
|
||||
|
||||
Object.assign(body, filters);
|
||||
|
||||
endpoint = 'https://api.dropboxapi.com/2/files/list_folder';
|
||||
|
||||
}
|
||||
} else if (resource === 'search') {
|
||||
if (operation === 'query') {
|
||||
// ----------------------------------
|
||||
// query
|
||||
// ----------------------------------
|
||||
|
||||
returnAll = this.getNodeParameter('returnAll', 0) as boolean;
|
||||
|
||||
simple = this.getNodeParameter('simple', 0) as boolean;
|
||||
|
||||
const filters = this.getNodeParameter('filters', i) as IDataObject;
|
||||
|
||||
property = 'matches';
|
||||
|
||||
requestMethod = 'POST';
|
||||
body = {
|
||||
query: this.getNodeParameter('query', i) as string,
|
||||
options: {
|
||||
filename_only: true,
|
||||
},
|
||||
};
|
||||
|
||||
if (filters.file_extensions) {
|
||||
filters.file_extensions = (filters.file_extensions as string).split(',');
|
||||
}
|
||||
|
||||
Object.assign(body.options, filters);
|
||||
|
||||
if (returnAll === false) {
|
||||
const limit = this.getNodeParameter('limit', i) as number;
|
||||
Object.assign(body.options, { max_results: limit });
|
||||
}
|
||||
|
||||
endpoint = 'https://api.dropboxapi.com/2/files/search_v2';
|
||||
}
|
||||
}
|
||||
if (['file', 'folder'].includes(resource)) {
|
||||
if (['file', 'folder', 'search'].includes(resource)) {
|
||||
if (operation === 'copy') {
|
||||
// ----------------------------------
|
||||
// copy
|
||||
@@ -625,7 +982,13 @@ export class Dropbox implements INodeType {
|
||||
options = { encoding: null };
|
||||
}
|
||||
|
||||
let responseData = await dropboxApiRequest.call(this, requestMethod, endpoint, body, query, headers, options);
|
||||
let responseData;
|
||||
|
||||
if (returnAll === true) {
|
||||
responseData = await dropboxpiRequestAllItems.call(this, property, requestMethod, endpoint, body, query, headers);
|
||||
} else {
|
||||
responseData = await dropboxApiRequest.call(this, requestMethod, endpoint, body, query, headers, options);
|
||||
}
|
||||
|
||||
if (resource === 'file' && operation === 'upload') {
|
||||
responseData = JSON.parse(responseData);
|
||||
@@ -665,7 +1028,11 @@ export class Dropbox implements INodeType {
|
||||
'content_hash': 'contentHash',
|
||||
};
|
||||
|
||||
for (const item of responseData.entries) {
|
||||
if (returnAll === false) {
|
||||
responseData = responseData.entries;
|
||||
}
|
||||
|
||||
for (const item of responseData) {
|
||||
const newItem: IDataObject = {};
|
||||
|
||||
// Get the props and save them under a proper name
|
||||
@@ -677,8 +1044,14 @@ export class Dropbox implements INodeType {
|
||||
|
||||
returnData.push(newItem as IDataObject);
|
||||
}
|
||||
} else if (resource === 'search' && operation === 'query') {
|
||||
if (returnAll === true) {
|
||||
returnData.push.apply(returnData, (simple === true) ? simplify(responseData) : responseData);
|
||||
} else {
|
||||
returnData.push.apply(returnData, (simple === true) ? simplify(responseData[property]) : responseData[property]);
|
||||
}
|
||||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
returnData.push(responseData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user