@pipedream/sharepoint 0.7.1 → 0.8.0

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.
Files changed (30) hide show
  1. package/actions/create-folder/create-folder.mjs +1 -1
  2. package/actions/create-item/create-item.mjs +1 -1
  3. package/actions/create-link/create-link.mjs +1 -1
  4. package/actions/create-list/create-list.mjs +1 -1
  5. package/actions/download-file/download-file.mjs +93 -7
  6. package/actions/download-files/download-files.mjs +88 -0
  7. package/actions/find-file-by-name/find-file-by-name.mjs +1 -1
  8. package/actions/find-files-with-metadata/find-files-with-metadata.mjs +1 -1
  9. package/actions/get-excel-table/get-excel-table.mjs +1 -1
  10. package/actions/get-file-by-id/get-file-by-id.mjs +1 -1
  11. package/actions/get-site/get-site.mjs +1 -1
  12. package/actions/list-files-in-folder/list-files-in-folder.mjs +1 -1
  13. package/actions/list-sites/list-sites.mjs +1 -1
  14. package/actions/retrieve-file-metadata/retrieve-file-metadata.mjs +55 -0
  15. package/actions/search-and-filter-files/search-and-filter-files.mjs +1 -1
  16. package/actions/search-files/search-files.mjs +1 -1
  17. package/actions/search-sites/search-sites.mjs +1 -1
  18. package/actions/update-item/update-item.mjs +1 -1
  19. package/actions/upload-file/upload-file.mjs +1 -1
  20. package/common/constants.mjs +70 -0
  21. package/common/file-picker-base.mjs +308 -0
  22. package/common/utils.mjs +78 -0
  23. package/package.json +5 -2
  24. package/sharepoint.app.mjs +400 -3
  25. package/sources/new-file-created/new-file-created.mjs +1 -1
  26. package/sources/new-folder-created/new-folder-created.mjs +1 -1
  27. package/sources/new-list-item/new-list-item.mjs +1 -1
  28. package/sources/updated-file-instant/updated-file-instant.mjs +361 -0
  29. package/sources/updated-list-item/updated-list-item.mjs +1 -1
  30. package/actions/select-files/select-files.mjs +0 -198
@@ -4,7 +4,7 @@ export default {
4
4
  key: "sharepoint-create-folder",
5
5
  name: "Create Folder",
6
6
  description: "Create a new folder in SharePoint. [See the documentation](https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_post_children?view=odsp-graph-online)",
7
- version: "0.0.4",
7
+ version: "0.0.5",
8
8
  type: "action",
9
9
  annotations: {
10
10
  destructiveHint: false,
@@ -4,7 +4,7 @@ export default {
4
4
  key: "sharepoint-create-item",
5
5
  name: "Create Item",
6
6
  description: "Create a new item in Microsoft Sharepoint. [See the documentation](https://learn.microsoft.com/en-us/graph/api/listitem-create?view=graph-rest-1.0&tabs=http)",
7
- version: "0.0.10",
7
+ version: "0.0.11",
8
8
  annotations: {
9
9
  destructiveHint: false,
10
10
  openWorldHint: true,
@@ -5,7 +5,7 @@ export default {
5
5
  key: "sharepoint-create-link",
6
6
  name: "Create Link",
7
7
  description: "Create a sharing link for a DriveItem. [See the documentation](https://docs.microsoft.com/en-us/graph/api/driveitem-createlink?view=graph-rest-1.0&tabs=http)",
8
- version: "0.0.5",
8
+ version: "0.0.7",
9
9
  type: "action",
10
10
  annotations: {
11
11
  destructiveHint: false,
@@ -4,7 +4,7 @@ export default {
4
4
  key: "sharepoint-create-list",
5
5
  name: "Create List",
6
6
  description: "Create a new list in Microsoft Sharepoint. [See the documentation](https://learn.microsoft.com/en-us/graph/api/list-create?view=graph-rest-1.0&tabs=http)",
7
- version: "0.0.10",
7
+ version: "0.0.11",
8
8
  annotations: {
9
9
  destructiveHint: false,
10
10
  openWorldHint: true,
@@ -1,11 +1,14 @@
1
1
  import sharepoint from "../../sharepoint.app.mjs";
2
2
  import fs from "fs";
3
+ import path from "path";
4
+ import { ConfigurationError } from "@pipedream/platform";
5
+ import constants from "../../common/constants.mjs";
3
6
 
4
7
  export default {
5
8
  key: "sharepoint-download-file",
6
9
  name: "Download File",
7
10
  description: "Download a Microsoft Sharepoint file to the /tmp directory. [See the documentation](https://learn.microsoft.com/en-us/graph/api/driveitem-get-content?view=graph-rest-1.0&tabs=http)",
8
- version: "0.0.10",
11
+ version: "0.0.12",
9
12
  annotations: {
10
13
  destructiveHint: false,
11
14
  openWorldHint: true,
@@ -44,31 +47,114 @@ export default {
44
47
  label: "Filename",
45
48
  description: "The filename to save the downloaded file as in the `/tmp` directory",
46
49
  },
50
+ convertToFormat: {
51
+ type: "string",
52
+ label: "Convert To Format",
53
+ description: "The format to convert the file to. See the [Format Options](https://learn.microsoft.com/en-us/graph/api/driveitem-get-content-format?view=graph-rest-1.0&tabs=http#format-options) for supported source formats",
54
+ options: [
55
+ "pdf",
56
+ "html",
57
+ ],
58
+ optional: true,
59
+ },
47
60
  syncDir: {
48
61
  type: "dir",
49
62
  accessMode: "write",
50
63
  sync: true,
51
64
  },
52
65
  },
66
+ methods: {
67
+ async getOriginalFileData($) {
68
+ const { name: originalFilename } = await this.sharepoint.getDriveItem({
69
+ $,
70
+ driveId: this.driveId,
71
+ siteId: this.siteId,
72
+ fileId: this.fileId,
73
+ });
74
+ const originalExtension = path.extname(originalFilename).slice(1)
75
+ .toLowerCase() || undefined;
76
+ return {
77
+ originalFilename,
78
+ originalExtension,
79
+ };
80
+ },
81
+ formatNewFilename(originalExtension) {
82
+ const parsed = path.parse(this.filename);
83
+ if (this.convertToFormat) {
84
+ const base = parsed.ext
85
+ ? parsed.name
86
+ : this.filename;
87
+ return `${base}.${this.convertToFormat.toLowerCase()}`;
88
+ }
89
+ if (parsed.ext) {
90
+ return this.filename;
91
+ }
92
+ return originalExtension
93
+ ? `${this.filename}.${originalExtension}`
94
+ : this.filename;
95
+ },
96
+ validateConversionFormat(originalExtension) {
97
+ const supportedFormats = this.convertToFormat === "pdf"
98
+ ? constants.PDF_CONVERTIBLE_FORMATS
99
+ : this.convertToFormat === "html"
100
+ ? constants.HTML_CONVERTIBLE_FORMATS
101
+ : [];
102
+ if (!supportedFormats.includes(originalExtension)) {
103
+ throw new ConfigurationError(`The file extension "${originalExtension}" is not supported for conversion to "${this.convertToFormat}". Supported formats are: ${supportedFormats.join(", ")}`);
104
+ }
105
+ },
106
+ },
53
107
  async run({ $ }) {
54
- const response = await this.sharepoint.getFile({
108
+ const {
109
+ originalFilename, originalExtension,
110
+ } = await this.getOriginalFileData($);
111
+
112
+ // ensure filename has an extension
113
+ const filename = this.formatNewFilename(originalExtension);
114
+
115
+ if (this.convertToFormat) {
116
+ this.validateConversionFormat(originalExtension);
117
+ }
118
+
119
+ let response;
120
+ let args = {
55
121
  $,
56
122
  driveId: this.driveId,
57
123
  fileId: this.fileId,
58
- responseType: "arraybuffer",
59
- });
124
+ params: {
125
+ format: this.convertToFormat,
126
+ },
127
+ };
128
+ try {
129
+ response = await this.sharepoint.getFile({
130
+ ...args,
131
+ responseType: "arraybuffer",
132
+ });
133
+ } catch {
134
+ // throw error without buffer encoding
135
+ await this.sharepoint.getFile(args);
136
+ }
60
137
 
61
138
  const rawcontent = response.toString("base64");
62
139
  const buffer = Buffer.from(rawcontent, "base64");
63
140
  // Since the filepath is not returned as one of the standard keys (filePath
64
141
  // or path), save the file to STASH_DIR, if defined, so it is synced at the
65
142
  // end of execution.
66
- const downloadedFilepath = `${process.env.STASH_DIR || "/tmp"}/${this.filename}`;
143
+ const downloadedFilepath = `${process.env.STASH_DIR || "/tmp"}/${filename}`;
67
144
  fs.writeFileSync(downloadedFilepath, buffer);
68
145
 
69
- return {
70
- filename: this.filename,
146
+ const data = {
147
+ filename,
148
+ fileSize: `${buffer.length} bytes`,
149
+ extension: this.convertToFormat || originalExtension,
71
150
  downloadedFilepath,
72
151
  };
152
+
153
+ if (this.convertToFormat) {
154
+ data.originalFilename = originalFilename;
155
+ data.originalExtension = originalExtension;
156
+ }
157
+
158
+ return data;
73
159
  },
74
160
  };
@@ -0,0 +1,88 @@
1
+ import sharepoint from "../../sharepoint.app.mjs";
2
+ import utils from "../../common/utils.mjs";
3
+ import { filePickerMethods } from "../../common/file-picker-base.mjs";
4
+
5
+ export default {
6
+ key: "sharepoint-download-files",
7
+ name: "Download Files",
8
+ description: "Browse and select files from SharePoint and get their metadata along with pre-authenticated download URLs (valid ~1 hour). [See the documentation](https://learn.microsoft.com/en-us/graph/api/driveitem-get)",
9
+ version: "0.0.1",
10
+ type: "action",
11
+ annotations: {
12
+ destructiveHint: false,
13
+ openWorldHint: true,
14
+ readOnlyHint: true,
15
+ },
16
+ props: {
17
+ sharepoint,
18
+ siteId: {
19
+ propDefinition: [
20
+ sharepoint,
21
+ "siteId",
22
+ ],
23
+ withLabel: true,
24
+ },
25
+ driveId: {
26
+ propDefinition: [
27
+ sharepoint,
28
+ "driveId",
29
+ (c) => ({
30
+ siteId: c.siteId,
31
+ }),
32
+ ],
33
+ withLabel: true,
34
+ },
35
+ folderId: {
36
+ propDefinition: [
37
+ sharepoint,
38
+ "folderId",
39
+ (c) => ({
40
+ siteId: c.siteId,
41
+ driveId: c.driveId,
42
+ }),
43
+ ],
44
+ description: "The folder to browse. Leave empty to browse the root of the drive.",
45
+ optional: true,
46
+ withLabel: true,
47
+ },
48
+ fileIds: {
49
+ propDefinition: [
50
+ sharepoint,
51
+ "fileIds",
52
+ (c) => ({
53
+ siteId: c.siteId,
54
+ driveId: c.driveId,
55
+ folderId: c.folderId,
56
+ }),
57
+ ],
58
+ label: "Files",
59
+ description: "Select one or more files to download. **Note:** Only files can be downloaded; folders are not supported.",
60
+ },
61
+ },
62
+ methods: filePickerMethods,
63
+ async run({ $ }) {
64
+ // Parse the fileIds (which are JSON strings from the file picker)
65
+ const selections = utils.parseFileOrFolderList(this.fileIds);
66
+
67
+ if (selections.length === 0) {
68
+ throw new Error("Please select at least one file");
69
+ }
70
+
71
+ const siteId = this.sharepoint.resolveWrappedValue(this.siteId);
72
+ const driveId = this.sharepoint.resolveWrappedValue(this.driveId);
73
+
74
+ // Fetch metadata for all selected files with download URLs
75
+ const {
76
+ fileResults,
77
+ errors,
78
+ } = await this.fetchFileMetadata($, selections, siteId, driveId, {
79
+ includeDownloadUrl: true,
80
+ });
81
+
82
+ // Process and return results (no folders to handle)
83
+ return this.processResults($, fileResults, errors, [], {
84
+ successVerb: "Retrieved",
85
+ successNoun: "download URL(s)",
86
+ });
87
+ },
88
+ };
@@ -6,7 +6,7 @@ export default {
6
6
  key: "sharepoint-find-file-by-name",
7
7
  name: "Find File by Name",
8
8
  description: "Search for a file or folder by name. [See the documentation](https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_search)",
9
- version: "0.1.2",
9
+ version: "0.1.4",
10
10
  type: "action",
11
11
  annotations: {
12
12
  destructiveHint: false,
@@ -5,7 +5,7 @@ export default {
5
5
  name: "Find Files in List with Metadata",
6
6
  description:
7
7
  "Search and filter items in a SharePoint list based on metadata and custom columns. [See docs here](https://learn.microsoft.com/en-us/graph/api/listitem-list)",
8
- version: "0.0.1",
8
+ version: "0.0.2",
9
9
  type: "action",
10
10
  annotations: {
11
11
  destructiveHint: false,
@@ -4,7 +4,7 @@ export default {
4
4
  key: "sharepoint-get-excel-table",
5
5
  name: "Get Excel Table",
6
6
  description: "Retrieve a table from an Excel spreadsheet stored in Sharepoint [See the documentation](https://learn.microsoft.com/en-us/graph/api/table-range?view=graph-rest-1.0&tabs=http)",
7
- version: "0.0.5",
7
+ version: "0.0.6",
8
8
  type: "action",
9
9
  annotations: {
10
10
  destructiveHint: false,
@@ -4,7 +4,7 @@ export default {
4
4
  key: "sharepoint-get-file-by-id",
5
5
  name: "Get File by ID",
6
6
  description: "Retrieves a file by ID. [See the documentation](https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_get)",
7
- version: "0.0.4",
7
+ version: "0.0.5",
8
8
  type: "action",
9
9
  annotations: {
10
10
  destructiveHint: false,
@@ -4,7 +4,7 @@ export default {
4
4
  key: "sharepoint-get-site",
5
5
  name: "Get Site",
6
6
  description: "Get a site in Microsoft Sharepoint. [See the documentation](https://learn.microsoft.com/en-us/graph/api/site-get?view=graph-rest-1.0&tabs=http)",
7
- version: "0.0.2",
7
+ version: "0.0.3",
8
8
  type: "action",
9
9
  annotations: {
10
10
  destructiveHint: false,
@@ -4,7 +4,7 @@ export default {
4
4
  key: "sharepoint-list-files-in-folder",
5
5
  name: "List Files in Folder",
6
6
  description: "Retrieves a list of the files and/or folders directly within a folder. [See the documentation](https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_list_children)",
7
- version: "0.0.4",
7
+ version: "0.0.5",
8
8
  type: "action",
9
9
  annotations: {
10
10
  destructiveHint: false,
@@ -4,7 +4,7 @@ export default {
4
4
  key: "sharepoint-list-sites",
5
5
  name: "List Sites",
6
6
  description: "List all sites in Microsoft Sharepoint. [See the documentation](https://learn.microsoft.com/en-us/graph/api/site-list?view=graph-rest-1.0&tabs=http)",
7
- version: "0.0.2",
7
+ version: "0.0.3",
8
8
  type: "action",
9
9
  annotations: {
10
10
  destructiveHint: false,
@@ -0,0 +1,55 @@
1
+ import utils from "../../common/utils.mjs";
2
+ import {
3
+ filePickerProps,
4
+ filePickerMethods,
5
+ } from "../../common/file-picker-base.mjs";
6
+
7
+ export default {
8
+ key: "sharepoint-retrieve-file-metadata",
9
+ name: "Retrieve File Metadata",
10
+ description: "Browse and select files from SharePoint to retrieve their metadata (name, size, dates, etc.) without download URLs. [See the documentation](https://learn.microsoft.com/en-us/graph/api/driveitem-get)",
11
+ version: "0.0.1",
12
+ type: "action",
13
+ annotations: {
14
+ destructiveHint: false,
15
+ openWorldHint: true,
16
+ readOnlyHint: true,
17
+ },
18
+ props: filePickerProps,
19
+ methods: filePickerMethods,
20
+ async run({ $ }) {
21
+ const selections = utils.parseFileOrFolderList(this.fileOrFolderIds);
22
+
23
+ if (selections.length === 0) {
24
+ throw new Error("Please select at least one file or folder");
25
+ }
26
+
27
+ const siteId = this.sharepoint.resolveWrappedValue(this.siteId);
28
+ const driveId = this.sharepoint.resolveWrappedValue(this.driveId);
29
+
30
+ // Separate files and folders
31
+ const {
32
+ files,
33
+ folders,
34
+ } = this.categorizeSelections(selections);
35
+
36
+ // If only folders selected, return folder info
37
+ if (files.length === 0 && folders.length > 0) {
38
+ return this.handleFolderOnlySelection($, folders);
39
+ }
40
+
41
+ // Fetch metadata for all selected files WITHOUT download URLs
42
+ const {
43
+ fileResults,
44
+ errors,
45
+ } = await this.fetchFileMetadata($, files, siteId, driveId, {
46
+ includeDownloadUrl: false,
47
+ });
48
+
49
+ // Process and return results
50
+ return this.processResults($, fileResults, errors, folders, {
51
+ successVerb: "Retrieved",
52
+ successNoun: "metadata",
53
+ });
54
+ },
55
+ };
@@ -6,7 +6,7 @@ export default {
6
6
  name: "Search and Filter Files",
7
7
  description:
8
8
  "Search and filter SharePoint files based on metadata and custom columns. This action allows you to query files using SharePoint's custom properties, managed metadata, and other column values. [See the documentation](https://learn.microsoft.com/en-us/graph/api/listitem-list)",
9
- version: "0.0.1",
9
+ version: "0.0.2",
10
10
  type: "action",
11
11
  annotations: {
12
12
  destructiveHint: false,
@@ -4,7 +4,7 @@ export default {
4
4
  key: "sharepoint-search-files",
5
5
  name: "Search Files",
6
6
  description: "Search for files in Microsoft Sharepoint. [See the documentation](https://learn.microsoft.com/en-us/graph/api/search-query?view=graph-rest-1.0&tabs=http)",
7
- version: "0.0.2",
7
+ version: "0.0.3",
8
8
  type: "action",
9
9
  annotations: {
10
10
  destructiveHint: false,
@@ -4,7 +4,7 @@ export default {
4
4
  key: "sharepoint-search-sites",
5
5
  name: "Search Sites",
6
6
  description: "Search for sites in Microsoft Sharepoint. [See the documentation](https://learn.microsoft.com/en-us/graph/api/site-search?view=graph-rest-1.0&tabs=http)",
7
- version: "0.0.2",
7
+ version: "0.0.3",
8
8
  type: "action",
9
9
  annotations: {
10
10
  destructiveHint: false,
@@ -5,7 +5,7 @@ export default {
5
5
  key: "sharepoint-update-item",
6
6
  name: "Update Item",
7
7
  description: "Updates an existing item in Microsoft Sharepoint. [See the documentation](https://learn.microsoft.com/en-us/graph/api/listitem-update?view=graph-rest-1.0&tabs=http)",
8
- version: "0.0.10",
8
+ version: "0.0.11",
9
9
  annotations: {
10
10
  destructiveHint: true,
11
11
  openWorldHint: true,
@@ -5,7 +5,7 @@ export default {
5
5
  key: "sharepoint-upload-file",
6
6
  name: "Upload File",
7
7
  description: "Upload a file to OneDrive. [See the documentation](https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_put_content?view=odsp-graph-online)",
8
- version: "0.0.4",
8
+ version: "0.0.5",
9
9
  type: "action",
10
10
  annotations: {
11
11
  destructiveHint: false,
@@ -1,3 +1,21 @@
1
+ /**
2
+ * Microsoft Graph subscription constants for SharePoint webhooks.
3
+ * https://learn.microsoft.com/en-us/graph/api/subscription-post-subscriptions
4
+ */
5
+
6
+ /**
7
+ * Maximum subscription lifetime for driveItem resources is 42,300 minutes (~29.4 days).
8
+ * We use 29 days in milliseconds to stay safely within the limit.
9
+ */
10
+ const WEBHOOK_SUBSCRIPTION_EXPIRATION_TIME_MILLISECONDS = 29 * 24 * 60 * 60 * 1000;
11
+
12
+ /**
13
+ * Renewal interval at 95% of max lifetime to ensure renewal before expiration.
14
+ * 29 days * 0.95 = 27.55 days = 2,380,320 seconds
15
+ */
16
+ const WEBHOOK_SUBSCRIPTION_RENEWAL_SECONDS =
17
+ (WEBHOOK_SUBSCRIPTION_EXPIRATION_TIME_MILLISECONDS * 0.95) / 1000;
18
+
1
19
  const SHARING_LINK_TYPE_OPTIONS = [
2
20
  {
3
21
  label: "Create a read-only link to the DriveItem",
@@ -24,6 +42,51 @@ const SHARING_LINK_SCOPE_OPTIONS = [
24
42
  },
25
43
  ];
26
44
 
45
+ const PDF_CONVERTIBLE_FORMATS = [
46
+ "doc",
47
+ "docx",
48
+ "dot",
49
+ "dotx",
50
+ "dotm",
51
+ "dsn",
52
+ "dwg",
53
+ "eml",
54
+ "epub",
55
+ "fluidframework",
56
+ "form",
57
+ "htm",
58
+ "html",
59
+ "loop",
60
+ "loot",
61
+ "markdown",
62
+ "md",
63
+ "msg",
64
+ "note",
65
+ "odp",
66
+ "ods",
67
+ "odt",
68
+ "page",
69
+ "pps",
70
+ "ppsx",
71
+ "ppt",
72
+ "pptx",
73
+ "pulse",
74
+ "rtf",
75
+ "task",
76
+ "tif",
77
+ "tiff",
78
+ "wbtx",
79
+ "whiteboard",
80
+ "xls",
81
+ "xlsm",
82
+ "xlsx",
83
+ ];
84
+
85
+ const HTML_CONVERTIBLE_FORMATS = [
86
+ "loop",
87
+ "fluid",
88
+ "wbtx",
89
+ ];
27
90
  const RETURN_CONTENT_TYPE_OPTIONS = [
28
91
  {
29
92
  label: "Only Files",
@@ -39,8 +102,15 @@ const RETURN_CONTENT_TYPE_OPTIONS = [
39
102
  },
40
103
  ];
41
104
 
105
+ export {
106
+ WEBHOOK_SUBSCRIPTION_EXPIRATION_TIME_MILLISECONDS,
107
+ WEBHOOK_SUBSCRIPTION_RENEWAL_SECONDS,
108
+ };
109
+
42
110
  export default {
43
111
  SHARING_LINK_TYPE_OPTIONS,
44
112
  SHARING_LINK_SCOPE_OPTIONS,
113
+ PDF_CONVERTIBLE_FORMATS,
114
+ HTML_CONVERTIBLE_FORMATS,
45
115
  RETURN_CONTENT_TYPE_OPTIONS,
46
116
  };