@pipedream/dropbox 0.3.18 → 0.3.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,15 +1,11 @@
1
1
  # Overview
2
2
 
3
- With the Dropbox API, you can build a variety of applications that range from
4
- simple file sharing to complex content management systems. Some examples of
5
- what you can build using the Dropbox API include:
6
-
7
- - A file sharing application that allows users to share and sync files across
8
- devices
9
- - A content management system that allows users to manage and share files and
10
- folders
11
- - A note taking application that allows users to sync notes across devices
12
- - A task management application that allows users to manage and share tasks and
13
- files
14
- - A document management application that allows users to manage and share
15
- documents and files
3
+ The Dropbox API on Pipedream enables you to automate file and folder operations, streamlining workflows that involve storing, syncing, and sharing content. With this API, you can programmatically manage files, set up event-driven triggers based on changes within Dropbox, and leverage Pipedream's capabilities to connect with hundreds of other apps for extended automation scenarios. It's ideal for building custom file management solutions, archiving systems, or collaborative content workflows without writing extensive code.
4
+
5
+ # Example Use Cases
6
+
7
+ - **Automated Backup to Dropbox**: Whenever a new file is uploaded to an FTP server, trigger a Pipedream workflow that automatically uploads this file to a specified Dropbox folder. This can serve as an off-site backup system for important documents or media files, ensuring they are safe and accessible from anywhere.
8
+
9
+ - **Content Approval Workflow**: Create a system where new files added to a specific Dropbox folder trigger a Pipedream workflow, sending an approval request via Slack to a designated approver. Once the approver responds with approval, the workflow moves the file to a 'Published' folder within Dropbox, or if rejected, sends a notification back to the submitter with feedback.
10
+
11
+ - **Dropbox to Google Sheets Logging**: Every time a new file is added to a Dropbox folder, a Pipedream workflow extracts relevant metadata (like filename, size, and upload date) and appends it to a Google Sheets spreadsheet. This creates an ongoing log for tracking uploads, which is particularly useful for teams needing to maintain records of content updates and revisions.
@@ -2,23 +2,26 @@ import dropbox from "../../dropbox.app.mjs";
2
2
 
3
3
  export default {
4
4
  name: "Create a Text File",
5
- description: "Creates a brand new text file from plain text content you specify. [See docs here](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesUpload__anchor)",
5
+ description: "Creates a brand new text file from plain text content you specify. [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesUpload__anchor)",
6
6
  key: "dropbox-create-a-text-file",
7
- version: "0.0.8",
7
+ version: "0.0.10",
8
8
  type: "action",
9
9
  props: {
10
10
  dropbox,
11
11
  name: {
12
12
  type: "string",
13
- label: "File name",
14
- description: "Your new file name.",
13
+ label: "File Name",
14
+ description: "Your new file name. Example: `textfile.txt`",
15
15
  },
16
16
  path: {
17
17
  propDefinition: [
18
18
  dropbox,
19
- "pathFolder",
19
+ "path",
20
+ () => ({
21
+ filter: ({ metadata: { metadata: { [".tag"]: type } } }) => type === "folder",
22
+ }),
20
23
  ],
21
- description: "The file path in the user's Dropbox to create the file. If not filled, it will be created in the root folder.",
24
+ description: "Type the folder name to search for it in the user's Dropbox. If not filled, it will be created in the root folder.",
22
25
  },
23
26
  content: {
24
27
  type: "string",
@@ -33,9 +36,13 @@ export default {
33
36
  path,
34
37
  } = this;
35
38
 
39
+ const filename = name.includes(".txt")
40
+ ? name
41
+ : `${name}.txt`;
42
+
36
43
  const res = await this.dropbox.uploadFile({
37
44
  contents: Buffer.from(content),
38
- path: this.dropbox.getNormalizedPath(path, true) + name,
45
+ path: this.dropbox.getNormalizedPath(path, true) + filename,
39
46
  autorename: true,
40
47
  });
41
48
 
@@ -2,24 +2,27 @@ import dropbox from "../../dropbox.app.mjs";
2
2
 
3
3
  export default {
4
4
  name: "Create folder",
5
- description: "Create a folder. [See docs here](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesCreateFolderV2__anchor)",
5
+ description: "Create a Folder. [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesCreateFolderV2__anchor)",
6
6
  key: "dropbox-create-folder",
7
- version: "0.0.8",
7
+ version: "0.0.10",
8
8
  type: "action",
9
9
  props: {
10
10
  dropbox,
11
11
  name: {
12
12
  type: "string",
13
- label: "Folder name",
13
+ label: "Folder Name",
14
14
  description: "Your new folder name.",
15
15
  },
16
16
  path: {
17
17
  propDefinition: [
18
18
  dropbox,
19
- "pathFolder",
19
+ "path",
20
+ () => ({
21
+ filter: ({ metadata: { metadata: { [".tag"]: type } } }) => type === "folder",
22
+ }),
20
23
  ],
21
24
  optional: true,
22
- description: "The file path in the user's Dropbox to create the folder. If not filled, it will be created in the root folder.",
25
+ description: "Type the folder name to search for it in the user's Dropbox. If not filled, it will be created in the root folder.",
23
26
  },
24
27
  autorename: {
25
28
  type: "boolean",
@@ -2,24 +2,27 @@ import dropbox from "../../dropbox.app.mjs";
2
2
 
3
3
  export default {
4
4
  name: "Create or Append to a Text File",
5
- description: "Adds a new line to an existing text file, or creates a file if it doesn't exist. [See docs here](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesUpload__anchor)",
5
+ description: "Adds a new line to an existing text file, or creates a file if it doesn't exist. [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesUpload__anchor)",
6
6
  key: "dropbox-create-or-append-to-a-text-file",
7
- version: "0.0.8",
7
+ version: "0.0.10",
8
8
  type: "action",
9
9
  props: {
10
10
  dropbox,
11
11
  name: {
12
12
  type: "string",
13
- label: "File name",
13
+ label: "File Name",
14
14
  description: "Your new file name",
15
15
  },
16
16
  path: {
17
17
  propDefinition: [
18
18
  dropbox,
19
- "pathFolder",
19
+ "path",
20
+ () => ({
21
+ filter: ({ metadata: { metadata: { [".tag"]: type } } }) => type === "folder",
22
+ }),
20
23
  ],
21
24
  optional: true,
22
- description: "The file path in the user's Dropbox to create the file. If not filled, it will be created in the root folder.",
25
+ description: "Type the folder name to search for it in the user's Dropbox. If not filled, it will be created in the root folder.",
23
26
  },
24
27
  content: {
25
28
  type: "string",
@@ -0,0 +1,10 @@
1
+ import dropbox from "../../dropbox.app.mjs";
2
+
3
+ export default {
4
+ props: {
5
+ dropbox: {
6
+ ...dropbox,
7
+ reloadProps: true,
8
+ },
9
+ },
10
+ };
@@ -1,60 +1,80 @@
1
- import dropbox from "../../dropbox.app.mjs";
1
+ import common from "./common.mjs";
2
2
  import consts from "../../common/consts.mjs";
3
3
 
4
4
  export default {
5
5
  name: "Create/Update a Share Link",
6
- description: "Creates or updates a public share link to the file or folder (It allows to share the file or folder with anyone). [See docs here](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#sharingCreateSharedLinkWithSettings__anchor)",
6
+ description: "Creates or updates a public share link to the file or folder (It allows you to share the file or folder with anyone). [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#sharingCreateSharedLinkWithSettings__anchor)",
7
7
  key: "dropbox-create-update-share-link",
8
- version: "0.0.8",
8
+ version: "0.0.10",
9
9
  type: "action",
10
10
  props: {
11
- dropbox,
11
+ ...common.props,
12
+ alert: {
13
+ type: "alert",
14
+ alertType: "warning",
15
+ content: `Dropbox Free and Basic users are able to create a publicly-available share link which allows downloads.
16
+ \nIn order to utilize advanced link sharing functionality, you must be on a Dropbox Essentials plan or higher. See the Dropbox pricing [page](https://www.dropbox.com/plans?trigger=nr#:~:text=Collaborative%20sharing) for more details.`,
17
+ },
12
18
  path: {
13
19
  propDefinition: [
14
- dropbox,
15
- "pathFileFolder",
20
+ common.props.dropbox,
21
+ "path",
16
22
  () => ({
17
- omitRootFolder: true,
23
+ initialOptions: [],
24
+ filter: ({ metadata: { metadata: { [".tag"]: type } } }) => [
25
+ "file",
26
+ "folder",
27
+ ].includes(type),
18
28
  }),
19
29
  ],
20
- description: "The path to be shared by the shared link.",
21
- },
22
- requirePassword: {
23
- type: "boolean",
24
- label: "Require password",
25
- description: "Boolean flag to enable or disable password protection.",
26
- default: false,
27
- },
28
- linkPassword: {
29
- type: "string",
30
- label: "Link password",
31
- description: "If `require_password` is `true`, this is needed to specify the password to access the link.",
32
- optional: true,
33
- },
34
- allowDownload: {
35
- type: "boolean",
36
- label: "Allow downloads",
37
- description: "Boolean flag to allow or not allow capabilities for shared links.",
30
+ description: "Type the file or folder name to search for it in the user's Dropbox.",
38
31
  },
39
- expires: {
40
- type: "string",
41
- label: "Expires",
42
- description: "Expiration time of the shared link. By default the link never expires. Make sure to use a valid [timestamp](https://dropbox.github.io/dropbox-sdk-js/global.html#Timestamp) value.",
43
- optional: true,
44
- },
45
- audience: {
46
- type: "string",
47
- label: "Audience",
48
- description: "The new audience who can benefit from the access level specified by the link's access level specified in the `link_access_level` field of `LinkPermissions`. This is used in conjunction with team policies and shared folder policies to determine the final effective audience type in the `effective_audience` field of `LinkPermissions.",
49
- optional: true,
50
- options: consts.CREATE_SHARED_LINK_AUDIENCE_OPTIONS,
51
- },
52
- access: {
53
- type: "string",
54
- label: "Access",
55
- description: "Requested access level you want the audience to gain from this link. Note, modifying access level for an existing link is not supported.",
56
- optional: true,
57
- options: consts.CREATE_SHARED_LINK_ACCESS_OPTIONS,
32
+ },
33
+ async additionalProps() {
34
+ const props = {};
35
+
36
+ const accountType = await this.getCurrentAccount();
37
+ if (accountType !== "basic") {
38
+ props.requirePassword = {
39
+ type: "boolean",
40
+ label: "Require Password",
41
+ description: "Boolean flag to enable or disable password protection.",
42
+ default: false,
43
+ reloadProps: true,
44
+ };
45
+ props.linkPassword = {
46
+ type: "string",
47
+ label: "Link Password",
48
+ description: "If `require_password` is `true`, this is needed to specify the password to access the link.",
49
+ hidden: !this.requirePassword,
50
+ };
51
+ props.allowDownload = {
52
+ type: "boolean",
53
+ label: "Allow Downloads",
54
+ description: "Boolean flag to allow or not allow capabilities for shared links.",
55
+ };
56
+ props.expires = {
57
+ type: "string",
58
+ label: "Expires",
59
+ description: "Expiration time of the shared link. By default the link never expires. Make sure to use a valid [timestamp](https://dropbox.github.io/dropbox-sdk-js/global.html#Timestamp) value. Example: `2024-07-18T20:00:00Z`",
60
+ optional: true,
61
+ };
62
+ props.access = {
63
+ type: "string",
64
+ label: "Access",
65
+ description: "Requested access level you want the audience to gain from this link. Note, modifying access level for an existing link is not supported.",
66
+ optional: true,
67
+ options: consts.CREATE_SHARED_LINK_ACCESS_OPTIONS,
68
+ };
69
+ }
70
+
71
+ return props;
72
+ },
73
+ methods: {
74
+ async getCurrentAccount() {
75
+ const dpx = await this.dropbox.sdk();
76
+ const { result: { account_type: accountType } } = await dpx.usersGetCurrentAccount();
77
+ return accountType[".tag"];
58
78
  },
59
79
  },
60
80
  async run({ $ }) {
@@ -63,29 +83,31 @@ export default {
63
83
  requirePassword,
64
84
  linkPassword,
65
85
  expires,
66
- audience,
67
86
  access,
68
- requestedVisibility,
69
- allowDownload,
70
- removeExpiration,
71
87
  } = this;
72
88
 
89
+ const accountType = await this.getCurrentAccount();
90
+ const allowDownload = accountType === "basic"
91
+ ? true
92
+ : this.allowDownload;
93
+
73
94
  if (requirePassword && !linkPassword) {
74
95
  throw new Error("Since the password is required, please add a linkPassword");
75
96
  }
76
97
 
98
+ if (expires && Date.parse(expires) < Date.now()) {
99
+ throw new Error("Expire date must be later than the current datetime");
100
+ }
101
+
77
102
  const res = await this.dropbox.createSharedLink({
78
103
  path: this.dropbox.getPath(path),
79
104
  settings: {
80
105
  require_password: requirePassword,
81
106
  link_password: linkPassword,
82
107
  expires,
83
- audience,
84
108
  access,
85
- requested_visibility: requestedVisibility,
86
109
  allow_download: allowDownload,
87
110
  },
88
- remove_expiration: removeExpiration,
89
111
  });
90
112
  $.export("$summary", `Shared link for "${path?.label || path}" successfully created`);
91
113
  return res;
@@ -2,21 +2,25 @@ import dropbox from "../../dropbox.app.mjs";
2
2
 
3
3
  export default {
4
4
  name: "Delete a File/Folder",
5
- description: "Permanently removes a file/folder from the server. [See docs here](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesDeleteV2__anchor)",
5
+ description: "Permanently removes a file/folder from the server. [See documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesDeleteV2__anchor)",
6
6
  key: "dropbox-delete-file-folder",
7
- version: "0.0.8",
7
+ version: "0.0.10",
8
8
  type: "action",
9
9
  props: {
10
10
  dropbox,
11
11
  path: {
12
12
  propDefinition: [
13
13
  dropbox,
14
- "pathFileFolder",
14
+ "path",
15
15
  () => ({
16
- omitRootFolder: true,
16
+ initialOptions: [],
17
+ filter: ({ metadata: { metadata: { [".tag"]: type } } }) => [
18
+ "file",
19
+ "folder",
20
+ ].includes(type),
17
21
  }),
18
22
  ],
19
- description: "Path in the user's Dropbox to delete.",
23
+ description: "Type the file or folder name to search for it in the user's Dropbox.",
20
24
  },
21
25
  },
22
26
  async run({ $ }) {
@@ -6,20 +6,22 @@ export default {
6
6
  name: "Download File to TMP",
7
7
  description: "Download a specific file to the temporary directory. [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesDownload__anchor).",
8
8
  key: "dropbox-download-file-to-tmp",
9
- version: "0.0.4",
9
+ version: "0.0.6",
10
10
  type: "action",
11
11
  props: {
12
12
  dropbox,
13
13
  path: {
14
14
  propDefinition: [
15
15
  dropbox,
16
- "pathFile",
16
+ "path",
17
+ () => ({
18
+ initialOptions: [],
19
+ }),
17
20
  ],
18
- description: "The file path in the user's Dropbox to download.",
19
21
  },
20
22
  name: {
21
23
  type: "string",
22
- label: "File name",
24
+ label: "File Name",
23
25
  description: "The new name of the file to be saved, including it's extension. e.g: `myFile.csv`",
24
26
  optional: true,
25
27
  },
@@ -33,16 +35,18 @@ export default {
33
35
  path, cleanup,
34
36
  } = await file();
35
37
 
38
+ const extension = result.name.split(".").pop();
39
+
36
40
  const tmpPath = this.name
37
41
  ? `/tmp/${this.name}`
38
- : path;
42
+ : `${path}.${extension}`;
39
43
 
40
44
  await fs.promises.appendFile(tmpPath, Buffer.from(result.fileBinary));
41
45
  await cleanup();
42
46
 
43
47
  delete result.fileBinary;
44
48
 
45
- $.export("$summary", `File successfully saved in "/tmp/${this.name}"`);
49
+ $.export("$summary", `File successfully saved in "${tmpPath}"`);
46
50
 
47
51
  return {
48
52
  tmpPath,
@@ -2,18 +2,22 @@ import dropbox from "../../dropbox.app.mjs";
2
2
 
3
3
  export default {
4
4
  name: "List All Files/Subfolders in a Folder",
5
- description: "Retrieves a list of files or subfolders in a specified folder [See the docs here](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesListFolder__anchor)",
5
+ description: "Retrieves a list of files or subfolders in a specified folder [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesListFolder__anchor)",
6
6
  key: "dropbox-list-file-folders-in-a-folder",
7
- version: "0.0.8",
7
+ version: "0.0.10",
8
8
  type: "action",
9
9
  props: {
10
10
  dropbox,
11
11
  path: {
12
12
  propDefinition: [
13
13
  dropbox,
14
- "pathFolder",
14
+ "path",
15
+ () => ({
16
+ initialOptions: [],
17
+ filter: ({ metadata: { metadata: { [".tag"]: type } } }) => type === "folder",
18
+ }),
15
19
  ],
16
- description: "Scopes the search to a path in the user's Dropbox.",
20
+ description: "Type the folder name to search for it in the user's Dropbox.",
17
21
  },
18
22
  recursive: {
19
23
  type: "boolean",
@@ -23,7 +27,7 @@ export default {
23
27
  },
24
28
  includeDeleted: {
25
29
  type: "boolean",
26
- label: "Include deleted",
30
+ label: "Include Deleted",
27
31
  description: "If `true`, the results will include files and folders that used to exist but were deleted.",
28
32
  default: false,
29
33
  },
@@ -3,23 +3,25 @@ import dropbox from "../../dropbox.app.mjs";
3
3
 
4
4
  export default {
5
5
  name: "List File Revisions",
6
- description: "Retrieves a list of file revisions needed to recover previous content. [See docs here](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesListRevisions__anchor)",
6
+ description: "Retrieves a list of file revisions needed to recover previous content. [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesListRevisions__anchor)",
7
7
  key: "dropbox-list-file-revisions",
8
- version: "0.0.8",
8
+ version: "0.0.10",
9
9
  type: "action",
10
10
  props: {
11
11
  dropbox,
12
12
  path: {
13
13
  propDefinition: [
14
14
  dropbox,
15
- "pathFile",
15
+ "path",
16
+ () => ({
17
+ initialOptions: [],
18
+ }),
16
19
  ],
17
- description: "The file path for the file whose revisions you'd like to list.",
18
20
  },
19
21
  mode: {
20
22
  type: "string",
21
23
  label: "Mode",
22
- description: "Determines the behavior of the API in listing the revisions for a given file path or id.",
24
+ description: "Determines the behavior of the API in listing the revisions for a given file path or id. In `path` (default) mode, all revisions at the same file path as the latest file entry are returned. If revisions with the same file id are desired, then mode must be set to `id`.",
23
25
  optional: true,
24
26
  options: consts.LIST_FILE_REVISIONS_OPTIONS,
25
27
  },
@@ -2,30 +2,37 @@ import dropbox from "../../dropbox.app.mjs";
2
2
 
3
3
  export default {
4
4
  name: "Move a File/Folder",
5
- description: "Moves a file or folder to a different location in the user's Dropbox [See the docs here](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesMoveV2__anchor)",
5
+ description: "Moves a file or folder to a different location in the user's Dropbox [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesMoveV2__anchor)",
6
6
  key: "dropbox-move-file-folder",
7
- version: "0.0.9",
7
+ version: "0.0.11",
8
8
  type: "action",
9
9
  props: {
10
10
  dropbox,
11
11
  pathFrom: {
12
12
  propDefinition: [
13
13
  dropbox,
14
- "pathFileFolder",
14
+ "path",
15
15
  () => ({
16
- omitRootFolder: true,
16
+ initialOptions: [],
17
+ filter: ({ metadata: { metadata: { [".tag"]: type } } }) => [
18
+ "file",
19
+ "folder",
20
+ ].includes(type),
17
21
  }),
18
22
  ],
19
- label: "Path from",
20
- description: "The file/folder that you want to move.",
23
+ label: "Path From",
24
+ description: "Type the file or folder name to search for it in the user's Dropbox.",
21
25
  },
22
26
  pathTo: {
23
27
  propDefinition: [
24
28
  dropbox,
25
- "pathFolder",
29
+ "path",
30
+ () => ({
31
+ filter: ({ metadata: { metadata: { [".tag"]: type } } }) => type === "folder",
32
+ }),
26
33
  ],
27
- label: "Path to",
28
- description: "The new path of your file/folder",
34
+ label: "Path To",
35
+ description: "Type the folder name to search for it in the user's Dropbox.",
29
36
  },
30
37
  autorename: {
31
38
  type: "boolean",
@@ -35,7 +42,7 @@ export default {
35
42
  },
36
43
  allowOwnershipTransfer: {
37
44
  type: "boolean",
38
- label: "Allow ownership transfer",
45
+ label: "Allow Ownership Transfer",
39
46
  description: "Allow moves by owner even if it would result in an ownership transfer for the content being moved. This does not apply to copies.",
40
47
  optional: true,
41
48
  },
@@ -2,22 +2,26 @@ import dropbox from "../../dropbox.app.mjs";
2
2
 
3
3
  export default {
4
4
  name: "Rename a File/Folder",
5
- description: "Renames a file or folder in the user's Dropbox [See the docs here](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesMoveV2__anchor)",
5
+ description: "Renames a file or folder in the user's Dropbox [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesMoveV2__anchor)",
6
6
  key: "dropbox-rename-file-folder",
7
- version: "0.0.8",
7
+ version: "0.0.10",
8
8
  type: "action",
9
9
  props: {
10
10
  dropbox,
11
11
  pathFrom: {
12
12
  propDefinition: [
13
13
  dropbox,
14
- "pathFileFolder",
14
+ "path",
15
15
  () => ({
16
- omitRootFolder: true,
16
+ initialOptions: [],
17
+ filter: ({ metadata: { metadata: { [".tag"]: type } } }) => [
18
+ "file",
19
+ "folder",
20
+ ].includes(type),
17
21
  }),
18
22
  ],
19
23
  label: "Path From",
20
- description: "The file that you want to rename.",
24
+ description: "Type the file or folder name to search for it in the user's Dropbox.",
21
25
  },
22
26
  newName: {
23
27
  type: "string",
@@ -2,21 +2,21 @@ import dropbox from "../../dropbox.app.mjs";
2
2
 
3
3
  export default {
4
4
  name: "Restore a File",
5
- description: "Restores a previous file version. [See docs here](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesRestore__anchor)",
5
+ description: "Restores a previous file version. [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesRestore__anchor)",
6
6
  key: "dropbox-restore-a-file",
7
- version: "0.0.8",
7
+ version: "0.0.10",
8
8
  type: "action",
9
9
  props: {
10
10
  dropbox,
11
11
  path: {
12
12
  propDefinition: [
13
13
  dropbox,
14
- "pathFile",
14
+ "path",
15
15
  () => ({
16
- omitRootFolder: true,
16
+ initialOptions: [],
17
17
  }),
18
18
  ],
19
- description: "The path to save the restored file.",
19
+ description: "Type the file name to search for it in the user's Dropbox.",
20
20
  },
21
21
  rev: {
22
22
  propDefinition: [
@@ -4,9 +4,9 @@ import consts from "../../common/consts.mjs";
4
4
 
5
5
  export default {
6
6
  name: "Search files and folders",
7
- description: "Searches for files and folders by name. [See the docs here](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesSearchV2__anchor)",
7
+ description: "Searches for files and folders by name. [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesSearchV2__anchor)",
8
8
  key: "dropbox-search-files-folders",
9
- version: "0.0.8",
9
+ version: "0.0.10",
10
10
  type: "action",
11
11
  props: {
12
12
  dropbox,
@@ -19,47 +19,49 @@ export default {
19
19
  path: {
20
20
  propDefinition: [
21
21
  dropbox,
22
- "pathFolder",
22
+ "path",
23
+ () => ({
24
+ filter: ({ metadata: { metadata: { [".tag"]: type } } }) => type === "folder",
25
+ }),
23
26
  ],
24
- optional: true,
25
- description: "Scopes the search to a path in the user's Dropbox. Searches the entire Dropbox if not specified.",
27
+ description: "Type the folder name to search for it in the user's Dropbox.",
26
28
  },
27
29
  orderBy: {
28
30
  type: "string",
29
- label: "Order by",
31
+ label: "Order By",
30
32
  description: "By default, results are sorted by relevance.",
31
33
  optional: true,
32
34
  options: consts.SEARCH_FILE_FOLDER_ORDER_BY_OPTIONS,
33
35
  },
34
36
  fileStatus: {
35
37
  type: "string",
36
- label: "File status",
38
+ label: "File Status",
37
39
  description: "Restricts search to the given file status.",
38
40
  optional: true,
39
41
  options: consts.SEARCH_FILE_FOLDER_STATUS_OPTIONS,
40
42
  },
41
43
  filenameOnly: {
42
44
  type: "boolean",
43
- label: "Filename only",
45
+ label: "Filename Only",
44
46
  description: "Restricts search to only match on filenames.",
45
47
  optional: true,
46
48
  },
47
49
  fileCategories: {
48
50
  type: "string[]",
49
- label: "File categories",
51
+ label: "File Categories",
50
52
  description: "Restricts search to only the file categories specified. Only supported for active file search.",
51
53
  optional: true,
52
54
  options: consts.FILES_CATEGORIES_OPTIONS,
53
55
  },
54
56
  fileExtensions: {
55
57
  type: "string[]",
56
- label: "File extensions",
58
+ label: "File Extensions",
57
59
  description: "Restricts search to only the extensions specified. Only supported for active file search.",
58
60
  optional: true,
59
61
  },
60
62
  includeHighlights: {
61
63
  type: "boolean",
62
- label: "Include highlights",
64
+ label: "Include Highlights",
63
65
  description: "Whether to include highlight span from file title.",
64
66
  optional: true,
65
67
  },
@@ -2,26 +2,30 @@ import dropbox from "../../dropbox.app.mjs";
2
2
  import consts from "../../common/consts.mjs";
3
3
  import fs from "fs";
4
4
  import got from "got";
5
+ import { ConfigurationError } from "@pipedream/platform";
5
6
 
6
7
  export default {
7
8
  name: "Upload a File",
8
- description: "Uploads a file to a selected folder. [See docs here](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesUpload__anchor)",
9
+ description: "Uploads a file to a selected folder. [See the documentation](https://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesUpload__anchor)",
9
10
  key: "dropbox-upload-file",
10
- version: "0.0.11",
11
+ version: "0.0.13",
11
12
  type: "action",
12
13
  props: {
13
14
  dropbox,
14
15
  path: {
15
16
  propDefinition: [
16
17
  dropbox,
17
- "pathFolder",
18
+ "path",
19
+ () => ({
20
+ filter: ({ metadata: { metadata: { [".tag"]: type } } }) => type === "folder",
21
+ }),
18
22
  ],
19
- description: "The file path in the user's Dropbox to create the file. If not filled, it will be created in the root folder.",
23
+ description: "Type the folder name to search for it in the user's Dropbox. If not filled, it will be created in the root folder.",
20
24
  },
21
25
  name: {
22
26
  type: "string",
23
- label: "File name",
24
- description: "The name of your new file.",
27
+ label: "File Name",
28
+ description: "The name of your new file (make sure to include the file extension).",
25
29
  },
26
30
  fileUrl: {
27
31
  type: "string",
@@ -74,6 +78,10 @@ export default {
74
78
  clientModified,
75
79
  } = this;
76
80
 
81
+ if (!fileUrl && !filePath) {
82
+ throw new ConfigurationError("Must specify either File URL or File Path.");
83
+ }
84
+
77
85
  const contents = fileUrl
78
86
  ? await got.stream(fileUrl)
79
87
  : fs.createReadStream(filePath);
package/common/config.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  SEARCH_FILE_FOLDERS: {
3
- DEFAULT_MAX_RESULTS: 100,
3
+ DEFAULT_MAX_RESULTS: 1000,
4
4
  },
5
5
  LIST_FILES_IN_FOLDER: {
6
6
  DEFAULT_MAX_RESULTS: 100,
package/common/consts.mjs CHANGED
@@ -23,7 +23,6 @@ export default {
23
23
  LIST_FILE_REVISIONS_OPTIONS: [
24
24
  "path",
25
25
  "id",
26
- "other",
27
26
  ],
28
27
  CREATE_SHARED_LINK_AUDIENCE_OPTIONS: [
29
28
  "public",
@@ -34,10 +33,22 @@ export default {
34
33
  "other",
35
34
  ],
36
35
  CREATE_SHARED_LINK_ACCESS_OPTIONS: [
37
- "viewer",
38
- "editor",
39
- "max",
40
- "other",
36
+ {
37
+ value: "viewer",
38
+ label: "Users who use the link can view and comment on the content",
39
+ },
40
+ {
41
+ value: "editor",
42
+ label: "Users who use the link can edit, view and comment on the content. Note, not all file types support edit links yet.",
43
+ },
44
+ {
45
+ value: "max",
46
+ label: "Request for the maximum access level you can set the link to",
47
+ },
48
+ {
49
+ value: "default",
50
+ label: "Request for the default access level the user has set",
51
+ },
41
52
  ],
42
53
  CREATE_SHARED_LINK_REQUESTED_VISIBILITY_OPTIONS: [
43
54
  "public",
package/dropbox.app.mjs CHANGED
@@ -12,78 +12,90 @@ export default {
12
12
  type: "app",
13
13
  app: "dropbox",
14
14
  propDefinitions: {
15
- pathFolder: {
15
+ path: {
16
16
  type: "string",
17
17
  label: "Path",
18
- description: "The folder path. (Please use a valid path to filter the values and type at least 2 characters after the latest '/' to perform the search.)",
18
+ description: "Type the file name to search for it in the user's Dropbox.",
19
19
  useQuery: true,
20
20
  withLabel: true,
21
21
  async options({
22
- prevContext,
23
- query,
24
- returnSimpleString,
25
- omitRootFolder,
26
- }) {
27
- if (prevContext?.reachedLastPage) {
28
- return [];
29
- }
30
- return this.getPathOptions(
31
- query,
22
+ query, prevContext: { cursor },
23
+ params,
24
+ initialOptions = [
32
25
  {
33
- omitFiles: true,
34
- returnSimpleString,
35
- omitRootFolder,
26
+ label: "Root Folder",
27
+ value: "",
36
28
  },
37
- );
38
- },
39
- },
40
- pathFile: {
41
- type: "string",
42
- label: "Path",
43
- description: "The file path. (Please use a valid path to filter the values)",
44
- useQuery: true,
45
- withLabel: true,
46
- async options({
47
- prevContext,
48
- query,
49
- returnSimpleString,
50
- omitRootFolder,
29
+ ],
30
+ filter = ({ metadata: { metadata: { [".tag"]: type } } }) => type === "file",
31
+ mapper = ({ metadata: { metadata } }) => ({
32
+ label: metadata.path_display,
33
+ value: metadata.path_lower,
34
+ }),
51
35
  }) {
52
- if (prevContext?.reachedLastPage) {
53
- return [];
54
- }
55
- return this.getPathOptions(
56
- query,
57
- {
58
- omitFolders: true,
59
- returnSimpleString,
60
- omitRootFolder,
61
- },
62
- );
63
- },
64
- },
65
- pathFileFolder: {
66
- type: "string",
67
- label: "Path",
68
- description: "The file or folder path. (Please use a valid path to filter the values)",
69
- useQuery: true,
70
- withLabel: true,
71
- async options({
72
- prevContext,
73
- query,
74
- returnSimpleString,
75
- omitRootFolder,
76
- }) {
77
- if (prevContext?.reachedLastPage) {
36
+ try {
37
+ const dpx = await this.sdk();
38
+
39
+ if (cursor === null) {
40
+ return [];
41
+ }
42
+
43
+ if (cursor) {
44
+ const {
45
+ result: {
46
+ matches,
47
+ cursor: nextCursor,
48
+ has_more: hasMore,
49
+ },
50
+ } = await dpx.filesSearchContinueV2({
51
+ cursor,
52
+ });
53
+
54
+ return {
55
+ options: matches
56
+ .filter(filter)
57
+ .map(mapper),
58
+ context: {
59
+ cursor: hasMore
60
+ ? nextCursor
61
+ : null,
62
+ },
63
+ };
64
+ }
65
+
66
+ const {
67
+ result: {
68
+ matches,
69
+ cursor: nextCursor,
70
+ has_more: hasMore,
71
+ },
72
+ } = await dpx.filesSearchV2({
73
+ ...params,
74
+ query: query || "text",
75
+ options: {
76
+ path: params?.path || "",
77
+ max_results: config.SEARCH_FILE_FOLDERS.DEFAULT_MAX_RESULTS,
78
+ ...params?.options,
79
+ },
80
+ });
81
+
82
+ return {
83
+ options: initialOptions.concat(
84
+ matches
85
+ .filter(filter)
86
+ .map(mapper),
87
+ ),
88
+ context: {
89
+ cursor: hasMore
90
+ ? nextCursor
91
+ : null,
92
+ },
93
+ };
94
+
95
+ } catch (error) {
96
+ console.log("Error searching for files/folders", error);
78
97
  return [];
79
98
  }
80
- return this.getPathOptions(
81
- query,
82
- {
83
- returnSimpleString,
84
- omitRootFolder,
85
- },
86
- );
87
99
  },
88
100
  },
89
101
  fileRevision: {
@@ -178,7 +190,7 @@ export default {
178
190
  const revisions = await dpx.filesListRevisions({
179
191
  path,
180
192
  mode: {
181
- ".tag": "id",
193
+ ".tag": "path",
182
194
  },
183
195
  });
184
196
  return revisions.result?.entries?.map((revision) => ({
@@ -189,106 +201,6 @@ export default {
189
201
  this.normalizeError(err);
190
202
  }
191
203
  },
192
- async getPathOptions(path, opts = {}) {
193
- try {
194
- const {
195
- omitFolders,
196
- omitFiles,
197
- omitRootFolder,
198
- } = opts;
199
-
200
- let data = [];
201
- path = path === "/" || path === null
202
- ? ""
203
- : path;
204
-
205
- if (path.length > 0 && !path.startsWith("/")) {
206
- path = "/" + path;
207
- }
208
-
209
- if (path === "") {
210
- const entries = await this.listFilesFolders({
211
- path,
212
- recursive: true,
213
- include_mounted_folders: true,
214
- });
215
-
216
- data = entries.map((item) => ({
217
- path: item.path_display,
218
- type: item[".tag"],
219
- }));
220
-
221
- } else {
222
- let subpath = "";
223
- let query = path;
224
- if ((path.match(/\//g) || []).length > 1) {
225
- const splitPath = path.split("/");
226
- query = splitPath.pop();
227
- subpath = splitPath.join("/");
228
- }
229
- const res = await this.searchFilesFolders({
230
- query,
231
- options: {
232
- path: subpath,
233
- },
234
- });
235
-
236
- data = res.map(({ metadata }) => ({
237
- path: metadata.metadata.path_display,
238
- type: metadata.metadata[".tag"],
239
- }));
240
-
241
- const folders = data.filter((item) => item.type !== "file");
242
- for (const folder of folders) {
243
- const entries = await this.listFilesFolders({
244
- path: folder.path,
245
- recursive: true,
246
- include_mounted_folders: true,
247
- });
248
- const folderData = entries?.map((item) => ({
249
- path: item.path_display,
250
- type: item[".tag"],
251
- }));
252
- data.push(...folderData);
253
- }
254
- }
255
-
256
- if (omitFiles) {
257
- data = data.filter((item) => item.type !== "file");
258
- }
259
-
260
- if (omitFolders) {
261
- data = data.filter((item) => item.type !== "folder");
262
- }
263
-
264
- data = data.map((item) => ({
265
- label: item.path,
266
- value: item.path,
267
- }));
268
-
269
- if (path === "" && !omitFolders && !omitRootFolder) {
270
- data = [
271
- {
272
- label: "Root Folder",
273
- value: "",
274
- },
275
- ...data,
276
- ];
277
- }
278
-
279
- data.sort((a, b) => {
280
- return a > b ?
281
- 1 :
282
- -1;
283
- });
284
-
285
- return data;
286
-
287
- } catch (err) {
288
- console.log(err);
289
- return [];
290
- }
291
- },
292
204
  async initState(context) {
293
205
  const {
294
206
  path,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipedream/dropbox",
3
- "version": "0.3.18",
3
+ "version": "0.3.20",
4
4
  "description": "Pipedream Dropbox Components",
5
5
  "main": "dropbox.app.mjs",
6
6
  "keywords": [
@@ -1,4 +1,5 @@
1
1
  import common from "../common/common.mjs";
2
+ import sampleEmit from "./test-event.mjs";
2
3
 
3
4
  export default {
4
5
  ...common,
@@ -6,7 +7,7 @@ export default {
6
7
  type: "source",
7
8
  key: "dropbox-all-updates",
8
9
  name: "New or Modified File or Folder",
9
- version: "0.0.15",
10
+ version: "0.0.17",
10
11
  description: "Emit new event when a file or folder is added or modified. Make sure the number of files/folders in the watched folder does not exceed 4000.",
11
12
  props: {
12
13
  ...common.props,
@@ -25,14 +26,20 @@ export default {
25
26
  },
26
27
  hooks: {
27
28
  async activate() {
28
- await this.getHistoricalEvents([
29
- "file",
30
- "folder",
31
- ]);
29
+ await this.getHistoricalEvents(this.getFileTypes());
32
30
  const state = await this.dropbox.initState(this);
33
31
  this._setDropboxState(state);
34
32
  },
35
33
  },
34
+ methods: {
35
+ ...common.methods,
36
+ getFileTypes() {
37
+ return [
38
+ "file",
39
+ "folder",
40
+ ];
41
+ },
42
+ },
36
43
  async run() {
37
44
  const state = this._getDropboxState();
38
45
  const {
@@ -43,10 +50,14 @@ export default {
43
50
  let file = {
44
51
  ...update,
45
52
  };
46
- if (this.includeMediaInfo) {
53
+ const fileTypes = this.getFileTypes();
54
+ if (!fileTypes.includes(file[".tag"])) {
55
+ continue;
56
+ }
57
+ if (this.includeMediaInfo && file[".tag"] === "file") {
47
58
  file = await this.getMediaInfo(update);
48
59
  }
49
- if (this.includeLink) {
60
+ if (this.includeLink && file[".tag"] === "file") {
50
61
  file.link = await this.getTemporaryLink(update);
51
62
  }
52
63
  // new unique identification from merging the file id and the last file revision
@@ -56,4 +67,5 @@ export default {
56
67
  this.$emit(file, this.getMeta(id, file.path_display || file.id));
57
68
  }
58
69
  },
70
+ sampleEmit,
59
71
  };
@@ -0,0 +1,14 @@
1
+ export default {
2
+ ".tag": "file",
3
+ "name": "Document.docx",
4
+ "path_lower": "/document.docx",
5
+ "path_display": "/Document.docx",
6
+ "id": "id:yVswVBnnL7cAAAAAAAAAdg",
7
+ "client_modified": "2023-04-27T17:50:32Z",
8
+ "server_modified": "2023-07-17T19:28:05Z",
9
+ "rev": "01600b3cc31f26000000002574cf900",
10
+ "size": 10468,
11
+ "is_downloadable": true,
12
+ "content_hash": "065e09a66c9bb9264a6657083c9e7a06f8e2e9bc6a5420900c737250ed108147",
13
+ "link": "https://uc2aea9ca1ec13663730d4f924d1.dl.dropboxusercontent.com/cd/0/get/CWzN/file"
14
+ }
@@ -7,8 +7,12 @@ export default {
7
7
  path: {
8
8
  propDefinition: [
9
9
  dropbox,
10
- "pathFolder",
10
+ "path",
11
+ () => ({
12
+ filter: ({ metadata: { metadata: { [".tag"]: type } } }) => type === "folder",
13
+ }),
11
14
  ],
15
+ description: "Type the folder name to search for it in the user's Dropbox.",
12
16
  },
13
17
  recursive: {
14
18
  propDefinition: [
@@ -40,7 +44,7 @@ export default {
40
44
  if (!fileTypes.includes(file[".tag"])) {
41
45
  continue;
42
46
  }
43
- if (this.includeLink) {
47
+ if (this.includeLink && file[".tag"] === "file") {
44
48
  file.link = await this.getTemporaryLink(file);
45
49
  }
46
50
  this.$emit(file, this.getMeta(file.id, file.path_display || file.id));
@@ -7,7 +7,7 @@ export default {
7
7
  type: "source",
8
8
  key: "dropbox-new-file",
9
9
  name: "New File",
10
- version: "0.0.16",
10
+ version: "0.0.18",
11
11
  description: "Emit new event when a new file is added to your account or a specific folder. Make sure the number of files/folders in the watched folder does not exceed 4000.",
12
12
  props: {
13
13
  ...common.props,
@@ -1,4 +1,5 @@
1
1
  import common from "../common/common.mjs";
2
+ import sampleEmit from "./test-event.mjs";
2
3
 
3
4
  export default {
4
5
  ...common,
@@ -6,7 +7,7 @@ export default {
6
7
  type: "source",
7
8
  key: "dropbox-new-folder",
8
9
  name: "New Folder",
9
- version: "0.0.15",
10
+ version: "0.0.17",
10
11
  description: "Emit new event when a new folder is created. Make sure the number of files/folders in the watched folder does not exceed 4000.",
11
12
  hooks: {
12
13
  async activate() {
@@ -30,4 +31,5 @@ export default {
30
31
  this.$emit(update, this.getMeta(update.id, update.path_display || update.id));
31
32
  }
32
33
  },
34
+ sampleEmit,
33
35
  };
@@ -0,0 +1,14 @@
1
+ export default {
2
+ ".tag": "folder",
3
+ "name": "Clients",
4
+ "path_lower": "/clients",
5
+ "path_display": "/Clients",
6
+ "id": "id:yVswVBnnL7cAAAAAAAAAbQ",
7
+ "shared_folder_id": "4005125857",
8
+ "sharing_info": {
9
+ "read_only": false,
10
+ "shared_folder_id": "4005125857",
11
+ "traverse_only": false,
12
+ "no_access": false
13
+ }
14
+ }