diff --git a/packages/nodes-base/nodes/Google/Drive/GenericFunctions.ts b/packages/nodes-base/nodes/Google/Drive/GenericFunctions.ts index 36919cba27..5e455898ef 100644 --- a/packages/nodes-base/nodes/Google/Drive/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Google/Drive/GenericFunctions.ts @@ -82,6 +82,7 @@ export async function googleApiRequestAllItems(this: IExecuteFunctions | ILoadOp let responseData; query.maxResults = 100; + query.pageSize = 100; do { responseData = await googleApiRequest.call(this, method, endpoint, body, query); diff --git a/packages/nodes-base/nodes/Google/Drive/GoogleDrive.node.ts b/packages/nodes-base/nodes/Google/Drive/GoogleDrive.node.ts index 7351935e8b..73f068f436 100644 --- a/packages/nodes-base/nodes/Google/Drive/GoogleDrive.node.ts +++ b/packages/nodes-base/nodes/Google/Drive/GoogleDrive.node.ts @@ -10,22 +10,25 @@ import { INodeTypeDescription, } from 'n8n-workflow'; +import uuid = require('uuid'); + import { googleApiRequest, + googleApiRequestAllItems, } from './GenericFunctions'; export class GoogleDrive implements INodeType { description: INodeTypeDescription = { displayName: 'Google Drive', name: 'googleDrive', - icon: 'file:googleDrive.png', + icon: 'file:googleDrive.svg', group: ['input'], version: 1, subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', description: 'Access data on Google Drive', defaults: { name: 'Google Drive', - color: '#3f87f2', + color: '#4285F4', }, inputs: ['main'], outputs: ['main'], @@ -75,6 +78,10 @@ export class GoogleDrive implements INodeType { name: 'resource', type: 'options', options: [ + { + name: 'Drive', + value: 'drive', + }, { name: 'File', value: 'file', @@ -747,7 +754,6 @@ export class GoogleDrive implements INodeType { description: 'The IDs of the parent folders which contain the file.', }, - // ---------------------------------- // folder // ---------------------------------- @@ -780,6 +786,13 @@ export class GoogleDrive implements INodeType { type: 'collection', placeholder: 'Add Option', default: {}, + displayOptions: { + hide: { + resource: [ + 'drive', + ], + }, + }, options: [ { displayName: 'Email Message', @@ -1034,8 +1047,7 @@ export class GoogleDrive implements INodeType { }, }, default: false, - description: `Issue the request as a domain administrator; if set to true, then the requester will be granted access if the file ID parameter
- refers to a shared drive and the requester is an administrator of the domain to which the shared drive belongs.`, + description: `Perform the operation as domain administrator, i.e. if you are an administrator of the domain to which the shared drive belongs, you will be granted access automatically`, }, { @@ -1156,7 +1168,7 @@ export class GoogleDrive implements INodeType { description: 'The corpora to operate on.', }, { - displayName: 'Drive Id', + displayName: 'Drive ID', name: 'driveId', type: 'string', default: '', @@ -1178,6 +1190,531 @@ export class GoogleDrive implements INodeType { }, ], }, + // ---------------------------------- + // drive + // ---------------------------------- + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'drive', + ], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + description: 'Create a drive', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a drive', + }, + { + name: 'Get', + value: 'get', + description: 'Get a drive', + }, + { + name: 'List', + value: 'list', + description: 'List all drives', + }, + { + name: 'Update', + value: 'update', + description: 'Update a drive', + }, + ], + default: 'create', + description: 'The operation to perform.', + }, + // ---------------------------------- + // drive:create + // ---------------------------------- + { + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + required: false, + displayOptions: { + show: { + operation: [ + 'create', + ], + resource: [ + 'drive', + ], + }, + }, + description: 'The name of this shared drive.', + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + operation: [ + 'create', + ], + resource: [ + 'drive', + ], + }, + }, + options: [ + { + displayName: 'Capabilities', + name: 'capabilities', + type: 'collection', + placeholder: 'Add Field', + default: {}, + options: [ + { + displayName: 'Can Add Children', + name: 'canAddChildren', + type: 'boolean', + default: false, + description: `Whether the current user can add children to folders in this shared drive.`, + }, + { + displayName: 'Can Change Copy Requires Writer Permission Restriction', + name: 'canChangeCopyRequiresWriterPermissionRestriction', + type: 'boolean', + default: false, + description: `Whether the current user can change the copyRequiresWriterPermission restriction of this shared drive.`, + }, + { + displayName: 'Can Change Domain Users Only Restriction', + name: 'canChangeDomainUsersOnlyRestriction', + type: 'boolean', + default: false, + description: `Whether the current user can change the domainUsersOnly restriction of this shared drive.`, + }, + { + displayName: 'Can Change Drive Background', + name: 'canChangeDriveBackground', + type: 'boolean', + default: false, + description: `Whether the current user can change the background of this shared drive.`, + }, + { + displayName: 'Can Change Drive Members Only Restriction', + name: 'canChangeDriveMembersOnlyRestriction', + type: 'boolean', + default: false, + description: `Whether the current user can change the driveMembersOnly restriction of this shared drive.`, + }, + { + displayName: 'Can Comment', + name: 'canComment', + type: 'boolean', + default: false, + description: `Whether the current user can comment on files in this shared drive.`, + }, + { + displayName: 'Can Copy', + name: 'canCopy', + type: 'boolean', + default: false, + description: `Whether the current user can copy files in this shared drive.`, + }, + { + displayName: 'Can Delete Children', + name: 'canDeleteChildren', + type: 'boolean', + default: false, + description: `Whether the current user can delete children from folders in this shared drive.`, + }, + { + displayName: 'Can Delete Drive', + name: 'canDeleteDrive', + type: 'boolean', + default: false, + description: `Whether the current user can delete this shared drive. Attempting to delete the shared drive may still fail if there are untrashed items inside the shared drive.`, + }, + { + displayName: 'Can Download', + name: 'canDownload', + type: 'boolean', + default: false, + description: `Whether the current user can download files in this shared drive.`, + }, + { + displayName: 'Can Edit', + name: 'canEdit', + type: 'boolean', + default: false, + description: `Whether the current user can edit files in this shared drive`, + }, + { + displayName: 'Can List Children', + name: 'canListChildren', + type: 'boolean', + default: false, + description: `Whether the current user can list the children of folders in this shared drive.`, + }, + { + displayName: 'Can Manage Members', + name: 'canManageMembers', + type: 'boolean', + default: false, + description: `Whether the current user can add members to this shared drive or remove them or change their role.`, + }, + { + displayName: 'Can Read Revisions', + name: 'canReadRevisions', + type: 'boolean', + default: false, + description: `Whether the current user can read the revisions resource of files in this shared drive.`, + }, + { + displayName: 'Can Rename', + name: 'canRename', + type: 'boolean', + default: false, + description: `Whether the current user can rename files or folders in this shared drive.`, + }, + { + displayName: 'Can Rename Drive', + name: 'canRenameDrive', + type: 'boolean', + default: false, + description: `Whether the current user can rename this shared drive.`, + }, + { + displayName: 'Can Share', + name: 'canShare', + type: 'boolean', + default: false, + description: `Whether the current user can rename this shared drive.`, + }, + { + displayName: 'Can Trash Children', + name: 'canTrashChildren', + type: 'boolean', + default: false, + description: `Whether the current user can trash children from folders in this shared drive.`, + }, + ], + }, + { + displayName: 'Color RGB', + name: 'colorRgb', + type: 'color', + default: '', + description: 'The color of this shared drive as an RGB hex string', + }, + { + displayName: 'Created Time', + name: 'createdTime', + type: 'dateTime', + default: '', + description: 'The time at which the shared drive was created (RFC 3339 date-time).', + }, + { + displayName: 'Hidden', + name: 'hidden', + type: 'boolean', + default: false, + description: 'Whether the shared drive is hidden from default view.', + }, + { + displayName: 'Restrictions', + name: 'restrictions', + type: 'collection', + placeholder: 'Add Field', + default: {}, + options: [ + { + displayName: 'Admin Managed Restrictions', + name: 'adminManagedRestrictions', + type: 'boolean', + default: false, + description: `Whether the options to copy, print, or download files inside this shared drive,
+ should be disabled for readers and commenters. When this restriction is set to true, it will
+ override the similarly named field to true for any file inside this shared drive.`, + }, + { + displayName: 'Copy Requires Writer Permission', + name: 'copyRequiresWriterPermission', + type: 'boolean', + default: false, + description: `Whether the options to copy, print, or download files inside this shared drive,
+ should be disabled for readers and commenters. When this restriction is set to true, it will
+ override the similarly named field to true for any file inside this shared drive.`, + }, + { + displayName: 'Domain Users Only', + name: 'domainUsersOnly', + type: 'boolean', + default: false, + description: `Whether access to this shared drive and items inside this shared drive
+ is restricted to users of the domain to which this shared drive belongs. This restriction
+ may be overridden by other sharing policies controlled outside of this shared drive.`, + }, + { + displayName: 'Drive Members Only', + name: 'driveMembersOnly', + type: 'boolean', + default: false, + description: `Whether access to items inside this shared drive is restricted to its members.`, + }, + ], + }, + ], + }, + // ---------------------------------- + // drive:delete + // ---------------------------------- + { + displayName: 'Drive ID', + name: 'driveId', + type: 'string', + default: '', + required: false, + displayOptions: { + show: { + operation: [ + 'delete', + ], + resource: [ + 'drive', + ], + }, + }, + description: 'The ID of the shared drive.', + }, + // ---------------------------------- + // drive:get + // ---------------------------------- + { + displayName: 'Drive ID', + name: 'driveId', + type: 'string', + default: '', + required: false, + displayOptions: { + show: { + operation: [ + 'get', + ], + resource: [ + 'drive', + ], + }, + }, + description: 'The ID of the shared drive.', + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + operation: [ + 'get', + ], + resource: [ + 'drive', + ], + }, + }, + options: [ + { + displayName: 'Use Domain Admin Access', + name: 'useDomainAdminAccess', + type: 'boolean', + default: false, + description: 'Issue the request as a domain administrator; if set to true, then the requester will be granted access if they are an administrator of the domain to which the shared drive belongs. (Default: false)', + }, + ], + }, + // ---------------------------------- + // drive:list + // ---------------------------------- + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + operation: [ + 'list', + ], + resource: [ + 'drive', + ], + }, + }, + default: false, + description: 'If all results should be returned or only up to a given limit.', + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + displayOptions: { + show: { + operation: [ + 'list', + ], + resource: [ + 'drive', + ], + returnAll: [ + false, + ], + }, + }, + typeOptions: { + minValue: 1, + maxValue: 200, + }, + default: 100, + description: 'How many results to return.', + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + operation: [ + 'list', + ], + resource: [ + 'drive', + ], + }, + }, + options: [ + { + displayName: 'Query', + name: 'q', + type: 'string', + default: '', + description: 'Query string for searching shared drives. See the "Search for shared drives" guide for supported syntax.', + }, + { + displayName: 'Use Domain Admin Access', + name: 'useDomainAdminAccess', + type: 'boolean', + default: false, + description: 'Issue the request as a domain administrator; if set to true, then the requester will be granted access if they are an administrator of the domain to which the shared drive belongs. (Default: false)', + }, + ], + }, + // ---------------------------------- + // drive:update + // ---------------------------------- + { + displayName: 'Drive ID', + name: 'driveId', + type: 'string', + default: '', + required: false, + displayOptions: { + show: { + operation: [ + 'update', + ], + resource: [ + 'drive', + ], + }, + }, + description: 'The ID of the shared drive.', + }, + { + displayName: 'Update Fields', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + operation: [ + 'update', + ], + resource: [ + 'drive', + ], + }, + }, + options: [ + { + displayName: 'Color RGB', + name: 'colorRgb', + type: 'color', + default: '', + description: 'The color of this shared drive as an RGB hex string', + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + description: 'The name of this shared drive.', + }, + { + displayName: 'Restrictions', + name: 'restrictions', + type: 'collection', + placeholder: 'Add Field', + default: {}, + options: [ + { + displayName: 'Admin Managed Restrictions', + name: 'adminManagedRestrictions', + type: 'boolean', + default: false, + description: `Whether the options to copy, print, or download files inside this shared drive,
+ should be disabled for readers and commenters. When this restriction is set to true, it will
+ override the similarly named field to true for any file inside this shared drive.`, + }, + { + displayName: 'Copy Requires Writer Permission', + name: 'copyRequiresWriterPermission', + type: 'boolean', + default: false, + description: `Whether the options to copy, print, or download files inside this shared drive,
+ should be disabled for readers and commenters. When this restriction is set to true, it will
+ override the similarly named field to true for any file inside this shared drive.`, + }, + { + displayName: 'Domain Users Only', + name: 'domainUsersOnly', + type: 'boolean', + default: false, + description: `Whether access to this shared drive and items inside this shared drive
+ is restricted to users of the domain to which this shared drive belongs. This restriction
+ may be overridden by other sharing policies controlled outside of this shared drive.`, + }, + { + displayName: 'Drive Members Only', + name: 'driveMembersOnly', + type: 'boolean', + default: false, + description: `Whether access to items inside this shared drive is restricted to its members.`, + }, + ], + }, + ], + }, ], }; @@ -1190,7 +1727,7 @@ export class GoogleDrive implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < items.length; i++) { - const options = this.getNodeParameter('options', i) as IDataObject; + const options = this.getNodeParameter('options', i, {}) as IDataObject; let queryFields = 'id, name'; if (options && options.fields) { @@ -1202,7 +1739,89 @@ export class GoogleDrive implements INodeType { } } - if (resource === 'file') { + if (resource === 'drive') { + if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + const name = this.getNodeParameter('name', i) as string; + + const body: IDataObject = { + name, + }; + + Object.assign(body, options); + + const response = await googleApiRequest.call(this, 'POST', `/drive/v3/drives`, body, { requestId: uuid() }); + + returnData.push(response as IDataObject); + } + if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + + const driveId = this.getNodeParameter('driveId', i) as string; + + await googleApiRequest.call(this, 'DELETE', `/drive/v3/drives/${driveId}`); + + returnData.push({ success: true }); + } + if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + const driveId = this.getNodeParameter('driveId', i) as string; + + const qs: IDataObject = {}; + + Object.assign(qs, options); + + const response = await googleApiRequest.call(this, 'GET', `/drive/v3/drives/${driveId}`, {}, qs); + + returnData.push(response as IDataObject); + } + if (operation === 'list') { + // ---------------------------------- + // list + // ---------------------------------- + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + const qs: IDataObject = {}; + + let response: IDataObject[] = []; + + Object.assign(qs, options); + + if (returnAll === true) { + response = await googleApiRequestAllItems.call(this, 'drives', 'GET', `/drive/v3/drives`, {}, qs); + } else { + qs.pageSize = this.getNodeParameter('limit', i) as number; + const data = await googleApiRequest.call(this, 'GET', `/drive/v3/drives`, {}, qs); + response = data.drives as IDataObject[]; + } + returnData.push.apply(returnData, response); + } + if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- + + const driveId = this.getNodeParameter('driveId', i) as string; + + const body: IDataObject = {}; + + Object.assign(body, options); + + const response = await googleApiRequest.call(this, 'PATCH', `/drive/v3/drives/${driveId}`, body); + + returnData.push(response as IDataObject); + } + + } else if (resource === 'file') { if (operation === 'copy') { // ---------------------------------- // copy @@ -1357,6 +1976,7 @@ export class GoogleDrive implements INodeType { // ---------------------------------- // upload // ---------------------------------- + const options = this.getNodeParameter('options', i) as IDataObject; let mimeType = 'text/plain'; let body; @@ -1416,6 +2036,8 @@ export class GoogleDrive implements INodeType { qs = { addParents: parents.join(','), + // When set to true shared drives can be used. + supportsAllDrives: true, }; response = await googleApiRequest.call(this, 'PATCH', `/drive/v3/files/${JSON.parse(response).id}`, body, qs); @@ -1445,8 +2067,7 @@ export class GoogleDrive implements INodeType { returnData.push(response as IDataObject); } - } - if (['file', 'folder'].includes(resource)) { + } else if (['file', 'folder'].includes(resource)) { if (operation === 'delete') { // ---------------------------------- // delete diff --git a/packages/nodes-base/nodes/Google/Drive/googleDrive.png b/packages/nodes-base/nodes/Google/Drive/googleDrive.png deleted file mode 100644 index c9a361ff8f..0000000000 Binary files a/packages/nodes-base/nodes/Google/Drive/googleDrive.png and /dev/null differ diff --git a/packages/nodes-base/nodes/Google/Drive/googleDrive.svg b/packages/nodes-base/nodes/Google/Drive/googleDrive.svg new file mode 100644 index 0000000000..8d09ca1271 --- /dev/null +++ b/packages/nodes-base/nodes/Google/Drive/googleDrive.svg @@ -0,0 +1 @@ + \ No newline at end of file