@openfn/language-msgraph 0.1.1 → 0.3.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.
package/ast.json CHANGED
@@ -125,6 +125,207 @@
125
125
  ]
126
126
  },
127
127
  "valid": true
128
+ },
129
+ {
130
+ "name": "getDrive",
131
+ "params": [
132
+ "specifier",
133
+ "name",
134
+ "callback"
135
+ ],
136
+ "docs": {
137
+ "description": "Get a Drive or SharePoint document library. The drive metadata will be written\nto state.drives, where it can be used by other adaptor functions.\nPass { id } to get a drive by id or { id, owner } to get default drive for\nsome parent resource, like a group",
138
+ "tags": [
139
+ {
140
+ "title": "public",
141
+ "description": null,
142
+ "type": null
143
+ },
144
+ {
145
+ "title": "example",
146
+ "description": "getDrive({ id: \"YXzpkoLwR06bxC8tNdg71m\" })",
147
+ "caption": "Get a drive by ID"
148
+ },
149
+ {
150
+ "title": "example",
151
+ "description": "getDrive({ id: \"openfn.sharepoint.com\", owner: \"sites\" })",
152
+ "caption": "Get the default drive for a site"
153
+ },
154
+ {
155
+ "title": "param",
156
+ "description": "{Object} - A definition of the drive to retrieve\n - id {string} - The ID of the resource or owner.\n - owner {string} - The type of drive owner (e.g. sites, groups).",
157
+ "type": null,
158
+ "name": "specifier"
159
+ },
160
+ {
161
+ "title": "param",
162
+ "description": "The local name of the drive used to write to state.drives, ie, state.drives[name]",
163
+ "type": {
164
+ "type": "NameExpression",
165
+ "name": "string"
166
+ },
167
+ "name": "name"
168
+ },
169
+ {
170
+ "title": "param",
171
+ "description": "(Optional) Callback function",
172
+ "type": {
173
+ "type": "OptionalType",
174
+ "expression": {
175
+ "type": "NameExpression",
176
+ "name": "function"
177
+ }
178
+ },
179
+ "name": "callback",
180
+ "default": "s=>s"
181
+ },
182
+ {
183
+ "title": "return",
184
+ "description": null,
185
+ "type": {
186
+ "type": "NameExpression",
187
+ "name": "Operation"
188
+ }
189
+ }
190
+ ]
191
+ },
192
+ "valid": true
193
+ },
194
+ {
195
+ "name": "getFolder",
196
+ "params": [
197
+ "pathOrId",
198
+ "options",
199
+ "callback"
200
+ ],
201
+ "docs": {
202
+ "description": "Get the contents or metadata of a folder.",
203
+ "tags": [
204
+ {
205
+ "title": "public",
206
+ "description": null,
207
+ "type": null
208
+ },
209
+ {
210
+ "title": "example",
211
+ "description": "getFolder('01LUM6XOCKDTZKQC7AVZF2VMHE2I3O6OY3')",
212
+ "caption": "Get a folder by ID"
213
+ },
214
+ {
215
+ "title": "example",
216
+ "description": "getFolder(\"01LUM6XOCKDTZKQC7AVZF2VMHE2I3O6OY3\",{ driveName: \"mydrive\"})",
217
+ "caption": "Get a folder for a named drive by id"
218
+ },
219
+ {
220
+ "title": "param",
221
+ "description": "A path to a folder or folder id",
222
+ "type": {
223
+ "type": "NameExpression",
224
+ "name": "string"
225
+ },
226
+ "name": "pathOrId"
227
+ },
228
+ {
229
+ "title": "param",
230
+ "description": "(Optional) Query parameters",
231
+ "type": {
232
+ "type": "NameExpression",
233
+ "name": "object"
234
+ },
235
+ "name": "options"
236
+ },
237
+ {
238
+ "title": "param",
239
+ "description": "(Optional) Callback function",
240
+ "type": {
241
+ "type": "OptionalType",
242
+ "expression": {
243
+ "type": "NameExpression",
244
+ "name": "function"
245
+ }
246
+ },
247
+ "name": "callback",
248
+ "default": "s=>s"
249
+ },
250
+ {
251
+ "title": "return",
252
+ "description": null,
253
+ "type": {
254
+ "type": "NameExpression",
255
+ "name": "Operation"
256
+ }
257
+ }
258
+ ]
259
+ },
260
+ "valid": true
261
+ },
262
+ {
263
+ "name": "getFile",
264
+ "params": [
265
+ "pathOrId",
266
+ "options",
267
+ "callback"
268
+ ],
269
+ "docs": {
270
+ "description": "Get file metadata or file content.",
271
+ "tags": [
272
+ {
273
+ "title": "public",
274
+ "description": null,
275
+ "type": null
276
+ },
277
+ {
278
+ "title": "example",
279
+ "description": "getFile('01LUM6XOGRONYNTZ26DBBJPTN5IFTQPBIW')",
280
+ "caption": "Get a file by ID"
281
+ },
282
+ {
283
+ "title": "example",
284
+ "description": "getFile(\"01LUM6XOGRONYNTZ26DBBJPTN5IFTQPBIW\",{ driveName: \"mydrive\"})",
285
+ "caption": "Get a file for a named drive by id"
286
+ },
287
+ {
288
+ "title": "param",
289
+ "description": "A path to a file or file id",
290
+ "type": {
291
+ "type": "NameExpression",
292
+ "name": "string"
293
+ },
294
+ "name": "pathOrId"
295
+ },
296
+ {
297
+ "title": "param",
298
+ "description": "(Optional) Query parameters",
299
+ "type": {
300
+ "type": "NameExpression",
301
+ "name": "object"
302
+ },
303
+ "name": "options"
304
+ },
305
+ {
306
+ "title": "param",
307
+ "description": "(Optional) Callback function",
308
+ "type": {
309
+ "type": "OptionalType",
310
+ "expression": {
311
+ "type": "NameExpression",
312
+ "name": "function"
313
+ }
314
+ },
315
+ "name": "callback",
316
+ "default": "s=>s"
317
+ },
318
+ {
319
+ "title": "return",
320
+ "description": null,
321
+ "type": {
322
+ "type": "NameExpression",
323
+ "name": "Operation"
324
+ }
325
+ }
326
+ ]
327
+ },
328
+ "valid": true
128
329
  }
129
330
  ],
130
331
  "exports": [],
@@ -545,6 +746,80 @@
545
746
  ]
546
747
  },
547
748
  "valid": true
749
+ },
750
+ {
751
+ "name": "parseCsv",
752
+ "params": [
753
+ "csvData",
754
+ "parsingOptions",
755
+ "callback"
756
+ ],
757
+ "docs": {
758
+ "description": "Takes a CSV file string or stream and parsing options as input, and returns a promise that\nresolves to the parsed CSV data as an array of objects.\nOptions for `parsingOptions` include:\n- `delimiter` {string/Buffer/[string/Buffer]} - Defines the character(s) used to delineate the fields inside a record. Default: `','`\n- `quote` {string/Buffer/[string/Buffer]} - Defines the characters used to surround a field. Default: `'\"'`\n- `escape` {Buffer/string/null/boolean} - Set the escape character as one character/byte only. Default: `\"`\n- `columns` {boolean / array / function} - Generates record in the form of object literals. Default: `true`\n- `bom` {boolean} - Strips the {@link https://en.wikipedia.org/wiki/Byte_order_mark byte order mark (BOM)} from the input string or buffer. Default: `true`\n- `trim` {boolean} - Ignore whitespace characters immediately around the `delimiter`. Default: `true`\n- `ltrim` {boolean} - Ignore whitespace characters from the left side of a CSV field. Default: `true`\n- `rtrim` {boolean} - Ignore whitespace characters from the right side of a CSV field. Default: `true`\n- `chunkSize` {number} - The size of each chunk of CSV data. Default: `Infinity`\n- `skip_empty_lines` {boolean} - Ignore empty lines in the CSV file. Default: `true`",
759
+ "tags": [
760
+ {
761
+ "title": "public",
762
+ "description": null,
763
+ "type": null
764
+ },
765
+ {
766
+ "title": "function",
767
+ "description": null,
768
+ "name": null
769
+ },
770
+ {
771
+ "title": "param",
772
+ "description": "A CSV string or a readable stream",
773
+ "type": {
774
+ "type": "UnionType",
775
+ "elements": [
776
+ {
777
+ "type": "NameExpression",
778
+ "name": "String"
779
+ },
780
+ {
781
+ "type": "NameExpression",
782
+ "name": "Stream"
783
+ }
784
+ ]
785
+ },
786
+ "name": "csvData"
787
+ },
788
+ {
789
+ "title": "param",
790
+ "description": "Optional. Parsing options for converting CSV to JSON.",
791
+ "type": {
792
+ "type": "OptionalType",
793
+ "expression": {
794
+ "type": "NameExpression",
795
+ "name": "Object"
796
+ }
797
+ },
798
+ "name": "parsingOptions"
799
+ },
800
+ {
801
+ "title": "param",
802
+ "description": "(Optional) callback function. If used it will be called state and an array of rows.",
803
+ "type": {
804
+ "type": "OptionalType",
805
+ "expression": {
806
+ "type": "NameExpression",
807
+ "name": "function"
808
+ }
809
+ },
810
+ "name": "callback"
811
+ },
812
+ {
813
+ "title": "returns",
814
+ "description": "The function returns a Promise that resolves to the result of parsing a CSV `stringOrStream`.",
815
+ "type": {
816
+ "type": "NameExpression",
817
+ "name": "Operation"
818
+ }
819
+ }
820
+ ]
821
+ },
822
+ "valid": true
548
823
  }
549
824
  ]
550
825
  }
package/dist/index.cjs CHANGED
@@ -30,8 +30,12 @@ __export(src_exports, {
30
30
  fields: () => import_language_common3.fields,
31
31
  fn: () => import_language_common3.fn,
32
32
  get: () => get,
33
+ getDrive: () => getDrive,
34
+ getFile: () => getFile,
35
+ getFolder: () => getFolder,
33
36
  lastReferenceValue: () => import_language_common3.lastReferenceValue,
34
37
  merge: () => import_language_common3.merge,
38
+ parseCsv: () => import_language_common3.parseCsv,
35
39
  request: () => request,
36
40
  sourceValue: () => import_language_common3.sourceValue
37
41
  });
@@ -50,20 +54,35 @@ __export(Adaptor_exports, {
50
54
  fields: () => import_language_common3.fields,
51
55
  fn: () => import_language_common3.fn,
52
56
  get: () => get,
57
+ getDrive: () => getDrive,
58
+ getFile: () => getFile,
59
+ getFolder: () => getFolder,
53
60
  lastReferenceValue: () => import_language_common3.lastReferenceValue,
54
61
  merge: () => import_language_common3.merge,
62
+ parseCsv: () => import_language_common3.parseCsv,
55
63
  request: () => request,
56
64
  sourceValue: () => import_language_common3.sourceValue
57
65
  });
58
66
  var import_language_common2 = require("@openfn/language-common");
67
+ var import_util = require("@openfn/language-common/util");
59
68
 
60
69
  // src/Utils.js
70
+ var import_undici = require("undici");
61
71
  var import_language_common = require("@openfn/language-common");
62
- function setUrl(urlParams) {
63
- const { apiVersion, resolvePath } = urlParams;
64
- if (isValidHttpUrl(resolvePath))
65
- return resolvePath;
66
- const pathSuffix = apiVersion ? `${apiVersion}/${resolvePath}` : `v1.0/${resolvePath}`;
72
+ function assertDrive(state, driveName) {
73
+ if (!state.drives[driveName]) {
74
+ const errorString = [
75
+ `Drive is not defined.`,
76
+ `At the top of your job you should define all the drives you want to use.`,
77
+ `eg: getDrive({ id: "openfn.sharepoint.com", owner: "sites"})`
78
+ ].join("\n \u221F ");
79
+ throw new Error(errorString);
80
+ }
81
+ }
82
+ function getUrl(resource, apiVersion) {
83
+ if (isValidHttpUrl(resource))
84
+ return resource;
85
+ const pathSuffix = apiVersion ? `${apiVersion}/${resource}` : `v1.0/${resource}`;
67
86
  return `https://graph.microsoft.com/${pathSuffix}`;
68
87
  }
69
88
  function isValidHttpUrl(string) {
@@ -75,7 +94,7 @@ function isValidHttpUrl(string) {
75
94
  }
76
95
  return url.protocol === "http:" || url.protocol === "https:";
77
96
  }
78
- function setAuth(token) {
97
+ function getAuth(token) {
79
98
  return token ? { headers: { Authorization: `Bearer ${token}` } } : null;
80
99
  }
81
100
  function handleResponse(response, state, callback) {
@@ -114,7 +133,7 @@ var request = async (urlString, params = {}, method = "GET") => {
114
133
  } else {
115
134
  options.body = JSON.stringify(params);
116
135
  }
117
- const response = await fetch(url, options);
136
+ const response = await (0, import_undici.fetch)(url, options);
118
137
  const contentType = response.headers.get("Content-Type");
119
138
  const data = (contentType == null ? void 0 : contentType.includes("application/json")) ? await response.json() : await response.text();
120
139
  handleResponseError(response, data, method);
@@ -126,25 +145,33 @@ var import_language_common3 = require("@openfn/language-common");
126
145
  function execute(...operations) {
127
146
  const initialState = {
128
147
  references: [],
129
- data: null
148
+ data: null,
149
+ drives: {}
150
+ };
151
+ const cleanup = (finalState) => {
152
+ const { drives, ...rest } = finalState;
153
+ return rest;
130
154
  };
131
155
  return (state) => {
132
156
  return (0, import_language_common2.execute)(...operations)({
133
157
  ...initialState,
134
158
  ...state
135
- });
159
+ }).then(cleanup).catch(cleanup);
136
160
  };
137
161
  }
138
162
  function create(resource, data, callback) {
139
163
  return (state) => {
140
- const resolveResource = (0, import_language_common2.expandReferences)(resource)(state);
141
- const resolveData = (0, import_language_common2.expandReferences)(data)(state);
164
+ const [resolvedResource, resolvedData] = (0, import_util.expandReferences)(
165
+ state,
166
+ resource,
167
+ data
168
+ );
142
169
  const { accessToken, apiVersion } = state.configuration;
143
- const url = setUrl({ apiVersion, resolveResource });
144
- const auth = setAuth(accessToken);
170
+ const url = getUrl({ apiVersion, resolvedResource });
171
+ const auth = getAuth(accessToken);
145
172
  const options = {
146
173
  auth,
147
- ...resolveData
174
+ ...resolvedData
148
175
  };
149
176
  return request(url, options, "POST").then(
150
177
  (response) => handleResponse(response, state, callback)
@@ -153,12 +180,103 @@ function create(resource, data, callback) {
153
180
  }
154
181
  function get(path, query, callback = false) {
155
182
  return (state) => {
156
- const resolvePath = (0, import_language_common2.expandReferences)(path)(state);
157
- const resolveQuery = (0, import_language_common2.expandReferences)(query)(state);
158
183
  const { accessToken, apiVersion } = state.configuration;
159
- const url = setUrl({ apiVersion, resolvePath });
160
- const auth = setAuth(accessToken);
161
- return request(url, { ...resolveQuery, ...auth }).then(
184
+ const [resolvedPath, resolvedQuery] = (0, import_util.expandReferences)(state, path, query);
185
+ const url = getUrl(resolvedPath, apiVersion);
186
+ const auth = getAuth(accessToken);
187
+ return request(url, { ...resolvedQuery, ...auth }).then(
188
+ (response) => handleResponse(response, state, callback)
189
+ );
190
+ };
191
+ }
192
+ function getDrive(specifier, name = "default", callback = (s) => s) {
193
+ return (state) => {
194
+ const { accessToken, apiVersion } = state.configuration;
195
+ const [resolvedSpecifier, resolvedName] = (0, import_util.expandReferences)(
196
+ state,
197
+ specifier,
198
+ name
199
+ );
200
+ const { id, owner = "drive" } = resolvedSpecifier;
201
+ let resource;
202
+ if (owner === "drive") {
203
+ resource = `drives/${id}`;
204
+ } else {
205
+ resource = `${owner}/${id}/drive`;
206
+ }
207
+ const url = getUrl(resource, apiVersion);
208
+ const auth = getAuth(accessToken);
209
+ return request(url, { ...auth }).then((response) => {
210
+ state.drives[resolvedName] = response;
211
+ return callback(state);
212
+ });
213
+ };
214
+ }
215
+ function getFolder(pathOrId, options, callback = (s) => s) {
216
+ return async (state) => {
217
+ const defaultOptions = {
218
+ driveName: "default",
219
+ metadata: false
220
+ };
221
+ const { accessToken, apiVersion } = state.configuration;
222
+ const [resolvedPathOrId, resolvedOptions] = (0, import_util.expandReferences)(
223
+ state,
224
+ pathOrId,
225
+ options
226
+ );
227
+ const { driveName, metadata } = { ...defaultOptions, ...resolvedOptions };
228
+ assertDrive(state, driveName);
229
+ const { id: driveId } = state.drives[driveName];
230
+ let resource;
231
+ if (resolvedPathOrId.startsWith("/")) {
232
+ resource = `drives/${driveId}/root:/${encodeURIComponent(
233
+ resolvedPathOrId
234
+ )}`;
235
+ } else {
236
+ resource = `drives/${driveId}/items/${resolvedPathOrId}`;
237
+ }
238
+ if (!metadata) {
239
+ resource += resolvedPathOrId.startsWith("/") ? ":/children" : "/children";
240
+ }
241
+ const url = getUrl(resource, apiVersion);
242
+ const auth = getAuth(accessToken);
243
+ return request(url, { ...auth }).then(
244
+ (response) => handleResponse(response, state, callback)
245
+ );
246
+ };
247
+ }
248
+ function getFile(pathOrId, options, callback = (s) => s) {
249
+ return async (state) => {
250
+ const defaultOptions = {
251
+ driveName: "default",
252
+ metadata: false
253
+ };
254
+ const { accessToken, apiVersion } = state.configuration;
255
+ const [resolvedPathOrId, resolvedOptions] = (0, import_util.expandReferences)(
256
+ state,
257
+ pathOrId,
258
+ options
259
+ );
260
+ const { driveName, metadata } = {
261
+ ...defaultOptions,
262
+ ...resolvedOptions
263
+ };
264
+ assertDrive(state, driveName);
265
+ const { id: driveId } = state.drives[driveName];
266
+ let resource;
267
+ if (resolvedPathOrId.startsWith("/")) {
268
+ resource = `drives/${driveId}/root:/${encodeURIComponent(
269
+ resolvedPathOrId
270
+ )}`;
271
+ } else {
272
+ resource = `drives/${driveId}/items/${resolvedPathOrId}`;
273
+ }
274
+ if (!metadata) {
275
+ resource += resolvedPathOrId.startsWith("/") ? ":/content" : "/content";
276
+ }
277
+ const url = getUrl(resource, apiVersion);
278
+ const auth = getAuth(accessToken);
279
+ return request(url, { ...auth }).then(
162
280
  (response) => handleResponse(response, state, callback)
163
281
  );
164
282
  };
@@ -178,8 +296,12 @@ var src_default = Adaptor_exports;
178
296
  fields,
179
297
  fn,
180
298
  get,
299
+ getDrive,
300
+ getFile,
301
+ getFolder,
181
302
  lastReferenceValue,
182
303
  merge,
304
+ parseCsv,
183
305
  request,
184
306
  sourceValue
185
307
  });
package/dist/index.js CHANGED
@@ -17,23 +17,35 @@ __export(Adaptor_exports, {
17
17
  fields: () => fields,
18
18
  fn: () => fn,
19
19
  get: () => get,
20
+ getDrive: () => getDrive,
21
+ getFile: () => getFile,
22
+ getFolder: () => getFolder,
20
23
  lastReferenceValue: () => lastReferenceValue,
21
24
  merge: () => merge,
25
+ parseCsv: () => parseCsv,
22
26
  request: () => request,
23
27
  sourceValue: () => sourceValue
24
28
  });
25
- import {
26
- execute as commonExecute,
27
- expandReferences
28
- } from "@openfn/language-common";
29
+ import { execute as commonExecute } from "@openfn/language-common";
30
+ import { expandReferences } from "@openfn/language-common/util";
29
31
 
30
32
  // src/Utils.js
33
+ import { fetch } from "undici";
31
34
  import { composeNextState } from "@openfn/language-common";
32
- function setUrl(urlParams) {
33
- const { apiVersion, resolvePath } = urlParams;
34
- if (isValidHttpUrl(resolvePath))
35
- return resolvePath;
36
- const pathSuffix = apiVersion ? `${apiVersion}/${resolvePath}` : `v1.0/${resolvePath}`;
35
+ function assertDrive(state, driveName) {
36
+ if (!state.drives[driveName]) {
37
+ const errorString = [
38
+ `Drive is not defined.`,
39
+ `At the top of your job you should define all the drives you want to use.`,
40
+ `eg: getDrive({ id: "openfn.sharepoint.com", owner: "sites"})`
41
+ ].join("\n \u221F ");
42
+ throw new Error(errorString);
43
+ }
44
+ }
45
+ function getUrl(resource, apiVersion) {
46
+ if (isValidHttpUrl(resource))
47
+ return resource;
48
+ const pathSuffix = apiVersion ? `${apiVersion}/${resource}` : `v1.0/${resource}`;
37
49
  return `https://graph.microsoft.com/${pathSuffix}`;
38
50
  }
39
51
  function isValidHttpUrl(string) {
@@ -45,7 +57,7 @@ function isValidHttpUrl(string) {
45
57
  }
46
58
  return url.protocol === "http:" || url.protocol === "https:";
47
59
  }
48
- function setAuth(token) {
60
+ function getAuth(token) {
49
61
  return token ? { headers: { Authorization: `Bearer ${token}` } } : null;
50
62
  }
51
63
  function handleResponse(response, state, callback) {
@@ -102,30 +114,39 @@ import {
102
114
  fn,
103
115
  lastReferenceValue,
104
116
  merge,
105
- sourceValue
117
+ sourceValue,
118
+ parseCsv
106
119
  } from "@openfn/language-common";
107
120
  function execute(...operations) {
108
121
  const initialState = {
109
122
  references: [],
110
- data: null
123
+ data: null,
124
+ drives: {}
125
+ };
126
+ const cleanup = (finalState) => {
127
+ const { drives, ...rest } = finalState;
128
+ return rest;
111
129
  };
112
130
  return (state) => {
113
131
  return commonExecute(...operations)({
114
132
  ...initialState,
115
133
  ...state
116
- });
134
+ }).then(cleanup).catch(cleanup);
117
135
  };
118
136
  }
119
137
  function create(resource, data, callback) {
120
138
  return (state) => {
121
- const resolveResource = expandReferences(resource)(state);
122
- const resolveData = expandReferences(data)(state);
139
+ const [resolvedResource, resolvedData] = expandReferences(
140
+ state,
141
+ resource,
142
+ data
143
+ );
123
144
  const { accessToken, apiVersion } = state.configuration;
124
- const url = setUrl({ apiVersion, resolveResource });
125
- const auth = setAuth(accessToken);
145
+ const url = getUrl({ apiVersion, resolvedResource });
146
+ const auth = getAuth(accessToken);
126
147
  const options = {
127
148
  auth,
128
- ...resolveData
149
+ ...resolvedData
129
150
  };
130
151
  return request(url, options, "POST").then(
131
152
  (response) => handleResponse(response, state, callback)
@@ -134,12 +155,103 @@ function create(resource, data, callback) {
134
155
  }
135
156
  function get(path, query, callback = false) {
136
157
  return (state) => {
137
- const resolvePath = expandReferences(path)(state);
138
- const resolveQuery = expandReferences(query)(state);
139
158
  const { accessToken, apiVersion } = state.configuration;
140
- const url = setUrl({ apiVersion, resolvePath });
141
- const auth = setAuth(accessToken);
142
- return request(url, { ...resolveQuery, ...auth }).then(
159
+ const [resolvedPath, resolvedQuery] = expandReferences(state, path, query);
160
+ const url = getUrl(resolvedPath, apiVersion);
161
+ const auth = getAuth(accessToken);
162
+ return request(url, { ...resolvedQuery, ...auth }).then(
163
+ (response) => handleResponse(response, state, callback)
164
+ );
165
+ };
166
+ }
167
+ function getDrive(specifier, name = "default", callback = (s) => s) {
168
+ return (state) => {
169
+ const { accessToken, apiVersion } = state.configuration;
170
+ const [resolvedSpecifier, resolvedName] = expandReferences(
171
+ state,
172
+ specifier,
173
+ name
174
+ );
175
+ const { id, owner = "drive" } = resolvedSpecifier;
176
+ let resource;
177
+ if (owner === "drive") {
178
+ resource = `drives/${id}`;
179
+ } else {
180
+ resource = `${owner}/${id}/drive`;
181
+ }
182
+ const url = getUrl(resource, apiVersion);
183
+ const auth = getAuth(accessToken);
184
+ return request(url, { ...auth }).then((response) => {
185
+ state.drives[resolvedName] = response;
186
+ return callback(state);
187
+ });
188
+ };
189
+ }
190
+ function getFolder(pathOrId, options, callback = (s) => s) {
191
+ return async (state) => {
192
+ const defaultOptions = {
193
+ driveName: "default",
194
+ metadata: false
195
+ };
196
+ const { accessToken, apiVersion } = state.configuration;
197
+ const [resolvedPathOrId, resolvedOptions] = expandReferences(
198
+ state,
199
+ pathOrId,
200
+ options
201
+ );
202
+ const { driveName, metadata } = { ...defaultOptions, ...resolvedOptions };
203
+ assertDrive(state, driveName);
204
+ const { id: driveId } = state.drives[driveName];
205
+ let resource;
206
+ if (resolvedPathOrId.startsWith("/")) {
207
+ resource = `drives/${driveId}/root:/${encodeURIComponent(
208
+ resolvedPathOrId
209
+ )}`;
210
+ } else {
211
+ resource = `drives/${driveId}/items/${resolvedPathOrId}`;
212
+ }
213
+ if (!metadata) {
214
+ resource += resolvedPathOrId.startsWith("/") ? ":/children" : "/children";
215
+ }
216
+ const url = getUrl(resource, apiVersion);
217
+ const auth = getAuth(accessToken);
218
+ return request(url, { ...auth }).then(
219
+ (response) => handleResponse(response, state, callback)
220
+ );
221
+ };
222
+ }
223
+ function getFile(pathOrId, options, callback = (s) => s) {
224
+ return async (state) => {
225
+ const defaultOptions = {
226
+ driveName: "default",
227
+ metadata: false
228
+ };
229
+ const { accessToken, apiVersion } = state.configuration;
230
+ const [resolvedPathOrId, resolvedOptions] = expandReferences(
231
+ state,
232
+ pathOrId,
233
+ options
234
+ );
235
+ const { driveName, metadata } = {
236
+ ...defaultOptions,
237
+ ...resolvedOptions
238
+ };
239
+ assertDrive(state, driveName);
240
+ const { id: driveId } = state.drives[driveName];
241
+ let resource;
242
+ if (resolvedPathOrId.startsWith("/")) {
243
+ resource = `drives/${driveId}/root:/${encodeURIComponent(
244
+ resolvedPathOrId
245
+ )}`;
246
+ } else {
247
+ resource = `drives/${driveId}/items/${resolvedPathOrId}`;
248
+ }
249
+ if (!metadata) {
250
+ resource += resolvedPathOrId.startsWith("/") ? ":/content" : "/content";
251
+ }
252
+ const url = getUrl(resource, apiVersion);
253
+ const auth = getAuth(accessToken);
254
+ return request(url, { ...auth }).then(
143
255
  (response) => handleResponse(response, state, callback)
144
256
  );
145
257
  };
@@ -159,8 +271,12 @@ export {
159
271
  fields,
160
272
  fn,
161
273
  get,
274
+ getDrive,
275
+ getFile,
276
+ getFolder,
162
277
  lastReferenceValue,
163
278
  merge,
279
+ parseCsv,
164
280
  request,
165
281
  sourceValue
166
282
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfn/language-msgraph",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "description": "Microsoft Graph Language Pack for OpenFn",
5
5
  "type": "module",
6
6
  "exports": {
@@ -19,7 +19,8 @@
19
19
  "configuration-schema.json"
20
20
  ],
21
21
  "dependencies": {
22
- "@openfn/language-common": "^1.10.0"
22
+ "@openfn/language-common": "^1.10.1",
23
+ "undici": "^5.22.1"
23
24
  },
24
25
  "devDependencies": {
25
26
  "@openfn/buildtools": "^1.0.2",
@@ -29,8 +30,7 @@
29
30
  "deep-eql": "4.1.1",
30
31
  "esno": "^0.16.3",
31
32
  "mocha": "9.2.2",
32
- "rimraf": "3.0.2",
33
- "undici": "^5.22.1"
33
+ "rimraf": "3.0.2"
34
34
  },
35
35
  "repository": {
36
36
  "type": "git",
@@ -35,5 +35,49 @@ export function create(resource: string, data: object, callback: Function): Oper
35
35
  * @returns {Operation}
36
36
  */
37
37
  export function get(path: string, query: object, callback?: Function): Operation;
38
+ /**
39
+ * Get a Drive or SharePoint document library. The drive metadata will be written
40
+ * to state.drives, where it can be used by other adaptor functions.
41
+ * Pass { id } to get a drive by id or { id, owner } to get default drive for
42
+ * some parent resource, like a group
43
+ * @public
44
+ * @example <caption>Get a drive by ID</caption>
45
+ * getDrive({ id: "YXzpkoLwR06bxC8tNdg71m" })
46
+ * @example <caption>Get the default drive for a site</caption>
47
+ * getDrive({ id: "openfn.sharepoint.com", owner: "sites" })
48
+ * @param specifier {Object} - A definition of the drive to retrieve
49
+ * - id {string} - The ID of the resource or owner.
50
+ * - owner {string} - The type of drive owner (e.g. sites, groups).
51
+ * @param {string} name - The local name of the drive used to write to state.drives, ie, state.drives[name]
52
+ * @param {function} [callback = s => s] (Optional) Callback function
53
+ * @return {Operation}
54
+ */
55
+ export function getDrive(specifier: any, name?: string, callback?: Function): Operation;
56
+ /**
57
+ * Get the contents or metadata of a folder.
58
+ * @public
59
+ * @example <caption>Get a folder by ID</caption>
60
+ * getFolder('01LUM6XOCKDTZKQC7AVZF2VMHE2I3O6OY3')
61
+ * @example <caption>Get a folder for a named drive by id</caption>
62
+ * getFolder("01LUM6XOCKDTZKQC7AVZF2VMHE2I3O6OY3",{ driveName: "mydrive"})
63
+ * @param {string} pathOrId - A path to a folder or folder id
64
+ * @param {object} options - (Optional) Query parameters
65
+ * @param {function} [callback = s => s] (Optional) Callback function
66
+ * @return {Operation}
67
+ */
68
+ export function getFolder(pathOrId: string, options: object, callback?: Function): Operation;
69
+ /**
70
+ * Get file metadata or file content.
71
+ * @public
72
+ * @example <caption>Get a file by ID</caption>
73
+ * getFile('01LUM6XOGRONYNTZ26DBBJPTN5IFTQPBIW')
74
+ * @example <caption>Get a file for a named drive by id</caption>
75
+ * getFile("01LUM6XOGRONYNTZ26DBBJPTN5IFTQPBIW",{ driveName: "mydrive"})
76
+ * @param {string} pathOrId - A path to a file or file id
77
+ * @param {object} options - (Optional) Query parameters
78
+ * @param {function} [callback = s => s] (Optional) Callback function
79
+ * @return {Operation}
80
+ */
81
+ export function getFile(pathOrId: string, options: object, callback?: Function): Operation;
38
82
  export { request } from "./Utils";
39
- export { dataPath, dataValue, dateFns, each, field, fields, fn, lastReferenceValue, merge, sourceValue } from "@openfn/language-common";
83
+ export { dataPath, dataValue, dateFns, each, field, fields, fn, lastReferenceValue, merge, sourceValue, parseCsv } from "@openfn/language-common";
package/types/Utils.d.ts CHANGED
@@ -1,9 +1,10 @@
1
- export function setUrl(urlParams: any): any;
2
- export function setAuth(token: any): {
1
+ export function assertDrive(state: any, driveName: any): void;
2
+ export function getUrl(resource: any, apiVersion: any): any;
3
+ export function getAuth(token: any): {
3
4
  headers: {
4
5
  Authorization: string;
5
6
  };
6
7
  };
7
8
  export function handleResponse(response: any, state: any, callback: any): any;
8
9
  export function handleResponseError(response: any, data: any, method: any): void;
9
- export function request(urlString: any, params?: object, method?: string): Promise<any>;
10
+ export function request(urlString: any, params?: object, method?: string): Promise<unknown>;