microsoft-graph 2.8.0 → 2.9.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"graphApi.d.ts","sourceRoot":"","sources":["../../src/graphApi.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAgB,cAAc,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACzG,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAQ/C,eAAO,MAAM,mBAAmB,EAA6C,KAAK,CAAC;AACnF,eAAO,MAAM,QAAQ,qCAAqC,CAAC;AAC3D,eAAO,MAAM,aAAa,4CAAuB,CAAC;AAElD,8KAA8K;AAC9K,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,wBAAwB,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAQvF;AAED,6LAA6L;AAC7L,wBAAsB,QAAQ,CAAC,CAAC,SAAS,cAAc,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,UAAU,EAAE,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAInH;AAED,2DAA2D;AAC3D,wBAAsB,UAAU,CAAC,CAAC,SAAS,cAAc,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,UAAU,EAAE,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAOrH;AAoBD,KAAK,iBAAiB,CAAC,CAAC,IAAI;KAC1B,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CAChE,CAAC"}
1
+ {"version":3,"file":"graphApi.d.ts","sourceRoot":"","sources":["../../src/graphApi.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAgB,cAAc,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACzG,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAQ/C,eAAO,MAAM,mBAAmB,EAA6C,KAAK,CAAC;AACnF,eAAO,MAAM,QAAQ,qCAAqC,CAAC;AAC3D,eAAO,MAAM,aAAa,4CAAuB,CAAC;AAElD,8KAA8K;AAC9K,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,wBAAwB,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAQvF;AAED,6LAA6L;AAC7L,wBAAsB,QAAQ,CAAC,CAAC,SAAS,cAAc,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,UAAU,EAAE,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAInH;AAED,2DAA2D;AAC3D,wBAAsB,UAAU,CAAC,CAAC,SAAS,cAAc,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,UAAU,EAAE,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAOrH;AAoBD,KAAK,iBAAiB,CAAC,CAAC,IAAI;KAC1B,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CAChE,CAAC"}
@@ -7,7 +7,7 @@ exports.batchEndpoint = exports.endpoint = exports.authenticationScope = void 0;
7
7
  exports.operation = operation;
8
8
  exports.parallel = parallel;
9
9
  exports.sequential = sequential;
10
- const node_fetch_1 = __importDefault(require("node-fetch"));
10
+ const axios_1 = __importDefault(require("axios"));
11
11
  const InconsistentContextError_ts_1 = __importDefault(require("./errors/InconsistentContextError.js"));
12
12
  const InvalidArgumentError_ts_1 = __importDefault(require("./errors/InvalidArgumentError.js"));
13
13
  const NeverError_ts_1 = __importDefault(require("./errors/NeverError.js"));
@@ -51,7 +51,7 @@ const consecutiveRetryDelayMultiplier = 2;
51
51
  async function executeSingle(definition) {
52
52
  const context = (0, context_ts_1.getContext)(definition.contextId);
53
53
  const accessToken = await (0, accessToken_ts_1.getCurrentAccessToken)(context.tenantId, context.clientId, context.clientSecret, exports.authenticationScope);
54
- const agent = (0, httpAgent_ts_1.tryGetHttpAgent)(context.httpProxy);
54
+ const httpAgent = (0, httpAgent_ts_1.tryGetHttpAgent)(context.httpProxy);
55
55
  const response = await innerFetch({
56
56
  url: `${exports.endpoint}${definition.path}`,
57
57
  method: definition.method,
@@ -59,8 +59,8 @@ async function executeSingle(definition) {
59
59
  authorization: createAuthorizationHeader(accessToken),
60
60
  ...headersToObject(definition.headers),
61
61
  },
62
- body: definition.body === null ? null : JSON.stringify(definition.body),
63
- agent,
62
+ data: definition.body === null ? null : definition.body,
63
+ httpAgent,
64
64
  });
65
65
  return definition.responseTransform(response);
66
66
  }
@@ -79,7 +79,7 @@ async function executeBatch(...ops) {
79
79
  }
80
80
  const context = (0, context_ts_1.getContext)(contextId);
81
81
  const accessToken = await (0, accessToken_ts_1.getCurrentAccessToken)(context.tenantId, context.clientId, context.clientSecret, exports.authenticationScope);
82
- const agent = (0, httpAgent_ts_1.tryGetHttpAgent)(context.httpProxy);
82
+ const httpAgent = (0, httpAgent_ts_1.tryGetHttpAgent)(context.httpProxy);
83
83
  const body = await innerFetch({
84
84
  url: exports.batchEndpoint,
85
85
  method: "POST",
@@ -88,7 +88,7 @@ async function executeBatch(...ops) {
88
88
  accept: "application/json",
89
89
  "content-type": "application/json",
90
90
  },
91
- body: JSON.stringify({
91
+ data: {
92
92
  requests: ops.map((op, index) => ({
93
93
  id: (0, operationId_ts_1.operationIndexToId)(index),
94
94
  method: op.method,
@@ -97,8 +97,8 @@ async function executeBatch(...ops) {
97
97
  body: op.body === null ? undefined : op.body,
98
98
  dependsOn: op.dependsOn?.map((id) => id.toString()),
99
99
  })),
100
- }),
101
- agent,
100
+ },
101
+ httpAgent,
102
102
  });
103
103
  const responses = [];
104
104
  for (const r of body.responses) {
@@ -123,27 +123,48 @@ async function executeBatch(...ops) {
123
123
  return responses; // TODO: Is there a neater way to massage the types correctly? This is functionally correct, but I do want to avoid using `unknown` here if possible.
124
124
  }
125
125
  /** Execute request, supporting GraphAPI retry logic */
126
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: This function does need to be simplified, though it is a TODO for another day
126
127
  async function innerFetch(args) {
127
128
  const { url, ...options } = args;
129
+ if (!url) {
130
+ throw new Error("URL is required for request");
131
+ }
128
132
  let retryAfterMilliseconds = defaultRetryDelayMilliseconds;
129
133
  let response = null;
130
134
  let attempts = 0; // Track the number of attempts
135
+ const instance = axios_1.default.create({
136
+ httpsAgent: options.httpAgent,
137
+ });
131
138
  while (attempts < maxRetries) {
132
- // Retry at most 3 times
133
- response = await (0, node_fetch_1.default)(url, options);
134
- if (!((0, httpStatus_ts_1.isHttpTooManyRequests)(response.status) || (0, httpStatus_ts_1.isServiceUnavailable)(response.status))) {
135
- break;
139
+ try {
140
+ response = await instance({
141
+ url,
142
+ ...options,
143
+ });
144
+ break; // If successful, exit the loop
136
145
  }
137
- const requestedRetryAfterSeconds = Number.parseInt(response.headers.get("Retry-After") ?? "0", 10);
138
- if (requestedRetryAfterSeconds) {
139
- retryAfterMilliseconds = requestedRetryAfterSeconds * 1000;
146
+ catch (error) {
147
+ if (axios_1.default.isAxiosError(error) && error.response) {
148
+ response = error.response;
149
+ if (!((0, httpStatus_ts_1.isHttpTooManyRequests)(response.status) || (0, httpStatus_ts_1.isServiceUnavailable)(response.status) || (0, httpStatus_ts_1.isGatewayTimeout)(response.status))) {
150
+ throw error; // Don't retry for other error codes
151
+ }
152
+ const requestedRetryAfterSeconds = Number.parseInt(response.headers["retry-after"] ?? "0", 10);
153
+ if (requestedRetryAfterSeconds) {
154
+ retryAfterMilliseconds = requestedRetryAfterSeconds * 1000;
155
+ }
156
+ await (0, sleep_ts_1.sleep)(retryAfterMilliseconds);
157
+ retryAfterMilliseconds *= consecutiveRetryDelayMultiplier;
158
+ attempts++; // Increment the attempt counter
159
+ if (attempts >= maxRetries) {
160
+ RequestFailedError_ts_1.default.throw(`GraphAPI fetch exceed retry limit of ${maxRetries} attempts.`, args);
161
+ }
162
+ }
163
+ else {
164
+ // For non-Axios errors or errors without response, just throw
165
+ throw error;
166
+ }
140
167
  }
141
- await (0, sleep_ts_1.sleep)(retryAfterMilliseconds);
142
- retryAfterMilliseconds *= consecutiveRetryDelayMultiplier;
143
- attempts++; // Increment the attempt counter
144
- }
145
- if (attempts >= maxRetries) {
146
- RequestFailedError_ts_1.default.throw(`GraphAPI fetch exceed retry limit of ${maxRetries} attempts.`, args);
147
168
  }
148
169
  if (!response) {
149
170
  throw new NeverError_ts_1.default("Response is null. Should be impossible");
@@ -151,17 +172,15 @@ async function innerFetch(args) {
151
172
  if ((0, httpStatus_ts_1.isHttpTooManyRequests)(response.status)) {
152
173
  RequestFailedError_ts_1.default.throw("GraphAPI fetch failed after 3 retries due to too many requests.", args);
153
174
  }
154
- const replyContentType = response.headers.get("content-type")?.toLowerCase();
155
- const body = replyContentType?.startsWith("application/json") ? await response.json() : null;
156
175
  if (!(0, httpStatus_ts_1.isHttpOk)(response.status)) {
157
- const bodyError = body;
176
+ const bodyError = response.data;
158
177
  let errorMessage = `${response.status} '${response.statusText}'`;
159
178
  if (bodyError?.error) {
160
179
  errorMessage += `: [${bodyError.error.code}] '${bodyError.error.message}'`;
161
180
  }
162
- RequestFailedError_ts_1.default.throw(`GraphAPI fetch failed: ${errorMessage}`, args, body);
181
+ RequestFailedError_ts_1.default.throw(`GraphAPI fetch failed: ${errorMessage}`, args, response.data);
163
182
  }
164
- return body;
183
+ return response.data;
165
184
  }
166
185
  function normalizeBatchBody(contentType, body) {
167
186
  if (contentType?.startsWith("application/json") && typeof body === "string") {
@@ -1 +1 @@
1
- {"version":3,"file":"getDriveItemContent.d.ts","sourceRoot":"","sources":["../../../../src/operations/driveItem/getDriveItemContent.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAMjE;;;;;;;GAOG;AACH,wBAA8B,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAmB7F"}
1
+ {"version":3,"file":"getDriveItemContent.d.ts","sourceRoot":"","sources":["../../../../src/operations/driveItem/getDriveItemContent.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAOjE;;;;;;;GAOG;AACH,wBAA8B,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAgC7F"}
@@ -4,11 +4,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.default = getDriveItemContent;
7
- const node_fetch_1 = __importDefault(require("node-fetch"));
7
+ const axios_1 = __importDefault(require("axios"));
8
8
  const graphApi_ts_1 = require("../../graphApi.js");
9
9
  const accessToken_ts_1 = require("../../services/accessToken.js");
10
10
  const context_ts_1 = require("../../services/context.js");
11
11
  const httpAgent_ts_1 = require("../../services/httpAgent.js");
12
+ const httpStatus_ts_1 = require("../../services/httpStatus.js");
12
13
  const templatedPaths_ts_1 = require("../../services/templatedPaths.js");
13
14
  /**
14
15
  * Download the content of a drive item.
@@ -23,15 +24,25 @@ async function getDriveItemContent(itemRef) {
23
24
  const url = `${graphApi_ts_1.endpoint}${(0, templatedPaths_ts_1.generatePath)("/sites/{site-id}/drives/{drive-id}/items/{item-id}/content", itemRef)}`;
24
25
  const context = (0, context_ts_1.getContext)(itemRef.contextId);
25
26
  const accessToken = await (0, accessToken_ts_1.getCurrentAccessToken)(context.tenantId, context.clientId, context.clientSecret, graphApi_ts_1.authenticationScope);
26
- const agent = (0, httpAgent_ts_1.tryGetHttpAgent)(context.httpProxy);
27
- const response = await (0, node_fetch_1.default)(url, {
27
+ const httpAgent = (0, httpAgent_ts_1.tryGetHttpAgent)(context.httpProxy);
28
+ const response = await (0, axios_1.default)({
29
+ url,
30
+ method: "GET",
28
31
  headers: {
29
32
  authorization: `Bearer ${accessToken}`,
30
33
  },
31
- agent,
34
+ responseType: "arraybuffer",
35
+ httpsAgent: httpAgent,
32
36
  });
33
- if (!response.ok) {
37
+ if (!(0, httpStatus_ts_1.isHttpOk)(response.status)) {
34
38
  throw new Error(`Failed to download file: ${response.status} ${response.statusText}`);
35
39
  }
36
- return await response.arrayBuffer();
40
+ if (!Buffer.isBuffer(response.data)) {
41
+ throw new Error(`Unexpected response type: ${typeof response.data}`);
42
+ }
43
+ const buffer = response.data.buffer.slice(response.data.byteOffset, response.data.byteOffset + response.data.byteLength);
44
+ if (!(buffer instanceof ArrayBuffer)) {
45
+ throw new Error("Failed to convert Buffer to ArrayBuffer");
46
+ }
47
+ return buffer;
37
48
  }
@@ -1,7 +1,7 @@
1
1
  import type { GraphOperation } from "../../models/GraphOperation.ts";
2
2
  import type { WorkbookRangeRef } from "../../models/WorkbookRangeRef.ts";
3
3
  /**
4
- * Autofit the columns in a range.
4
+ * Auto-fit the columns in a range.
5
5
  *
6
6
  * @param rangeRef - A reference to the range, optionally including session information.
7
7
  * @returns Nothing.
@@ -4,7 +4,7 @@ exports.default = autoFitWorkbookRangeColumns;
4
4
  const graphApi_ts_1 = require("../../graphApi.js");
5
5
  const templatedPaths_ts_1 = require("../../services/templatedPaths.js");
6
6
  /**
7
- * Autofit the columns in a range.
7
+ * Auto-fit the columns in a range.
8
8
  *
9
9
  * @param rangeRef - A reference to the range, optionally including session information.
10
10
  * @returns Nothing.
@@ -16,4 +16,10 @@ export declare function isHttpTooManyRequests(status: number): boolean;
16
16
  * @returns True if the status code is 503, otherwise false.
17
17
  */
18
18
  export declare function isServiceUnavailable(status: number): boolean;
19
+ /**
20
+ * Checks if the HTTP status code indicates a gateway has timed out.
21
+ * @param status - The HTTP status code.
22
+ * @returns True if the status code is 504, otherwise false.
23
+ */
24
+ export declare function isGatewayTimeout(status: number): boolean;
19
25
  //# sourceMappingURL=httpStatus.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"httpStatus.d.ts","sourceRoot":"","sources":["../../../src/services/httpStatus.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE5D"}
1
+ {"version":3,"file":"httpStatus.d.ts","sourceRoot":"","sources":["../../../src/services/httpStatus.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAExD"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isHttpOk = isHttpOk;
4
4
  exports.isHttpTooManyRequests = isHttpTooManyRequests;
5
5
  exports.isServiceUnavailable = isServiceUnavailable;
6
+ exports.isGatewayTimeout = isGatewayTimeout;
6
7
  /**
7
8
  * Checks if the HTTP status code indicates a successful response.
8
9
  * @param status - The HTTP status code.
@@ -27,3 +28,11 @@ function isHttpTooManyRequests(status) {
27
28
  function isServiceUnavailable(status) {
28
29
  return status === 503;
29
30
  }
31
+ /**
32
+ * Checks if the HTTP status code indicates a gateway has timed out.
33
+ * @param status - The HTTP status code.
34
+ * @returns True if the status code is 504, otherwise false.
35
+ */
36
+ function isGatewayTimeout(status) {
37
+ return status === 504;
38
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"graphApi.d.ts","sourceRoot":"","sources":["../../src/graphApi.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAgB,cAAc,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACzG,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAQ/C,eAAO,MAAM,mBAAmB,EAA6C,KAAK,CAAC;AACnF,eAAO,MAAM,QAAQ,qCAAqC,CAAC;AAC3D,eAAO,MAAM,aAAa,4CAAuB,CAAC;AAElD,8KAA8K;AAC9K,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,wBAAwB,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAQvF;AAED,6LAA6L;AAC7L,wBAAsB,QAAQ,CAAC,CAAC,SAAS,cAAc,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,UAAU,EAAE,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAInH;AAED,2DAA2D;AAC3D,wBAAsB,UAAU,CAAC,CAAC,SAAS,cAAc,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,UAAU,EAAE,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAOrH;AAoBD,KAAK,iBAAiB,CAAC,CAAC,IAAI;KAC1B,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CAChE,CAAC"}
1
+ {"version":3,"file":"graphApi.d.ts","sourceRoot":"","sources":["../../src/graphApi.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAgB,cAAc,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACzG,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAQ/C,eAAO,MAAM,mBAAmB,EAA6C,KAAK,CAAC;AACnF,eAAO,MAAM,QAAQ,qCAAqC,CAAC;AAC3D,eAAO,MAAM,aAAa,4CAAuB,CAAC;AAElD,8KAA8K;AAC9K,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,wBAAwB,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAQvF;AAED,6LAA6L;AAC7L,wBAAsB,QAAQ,CAAC,CAAC,SAAS,cAAc,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,UAAU,EAAE,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAInH;AAED,2DAA2D;AAC3D,wBAAsB,UAAU,CAAC,CAAC,SAAS,cAAc,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,UAAU,EAAE,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAOrH;AAoBD,KAAK,iBAAiB,CAAC,CAAC,IAAI;KAC1B,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CAChE,CAAC"}
@@ -1,4 +1,4 @@
1
- import fetch from "node-fetch";
1
+ import axios from "axios";
2
2
  import InconsistentContextError from "./errors/InconsistentContextError.js";
3
3
  import InvalidArgumentError from "./errors/InvalidArgumentError.js";
4
4
  import NeverError from "./errors/NeverError.js";
@@ -7,7 +7,7 @@ import RequestFailedError from "./errors/RequestFailedError.js";
7
7
  import { getCurrentAccessToken } from "./services/accessToken.js";
8
8
  import { getContext } from "./services/context.js";
9
9
  import { tryGetHttpAgent } from "./services/httpAgent.js";
10
- import { isHttpOk, isHttpTooManyRequests, isServiceUnavailable } from "./services/httpStatus.js";
10
+ import { isGatewayTimeout, isHttpOk, isHttpTooManyRequests, isServiceUnavailable } from "./services/httpStatus.js";
11
11
  import { operationIdToIndex, operationIndexToId } from "./services/operationId.js";
12
12
  import { sleep } from "./services/sleep.js";
13
13
  export const authenticationScope = "https://graph.microsoft.com/.default";
@@ -42,7 +42,7 @@ const consecutiveRetryDelayMultiplier = 2;
42
42
  async function executeSingle(definition) {
43
43
  const context = getContext(definition.contextId);
44
44
  const accessToken = await getCurrentAccessToken(context.tenantId, context.clientId, context.clientSecret, authenticationScope);
45
- const agent = tryGetHttpAgent(context.httpProxy);
45
+ const httpAgent = tryGetHttpAgent(context.httpProxy);
46
46
  const response = await innerFetch({
47
47
  url: `${endpoint}${definition.path}`,
48
48
  method: definition.method,
@@ -50,8 +50,8 @@ async function executeSingle(definition) {
50
50
  authorization: createAuthorizationHeader(accessToken),
51
51
  ...headersToObject(definition.headers),
52
52
  },
53
- body: definition.body === null ? null : JSON.stringify(definition.body),
54
- agent,
53
+ data: definition.body === null ? null : definition.body,
54
+ httpAgent,
55
55
  });
56
56
  return definition.responseTransform(response);
57
57
  }
@@ -70,7 +70,7 @@ async function executeBatch(...ops) {
70
70
  }
71
71
  const context = getContext(contextId);
72
72
  const accessToken = await getCurrentAccessToken(context.tenantId, context.clientId, context.clientSecret, authenticationScope);
73
- const agent = tryGetHttpAgent(context.httpProxy);
73
+ const httpAgent = tryGetHttpAgent(context.httpProxy);
74
74
  const body = await innerFetch({
75
75
  url: batchEndpoint,
76
76
  method: "POST",
@@ -79,7 +79,7 @@ async function executeBatch(...ops) {
79
79
  accept: "application/json",
80
80
  "content-type": "application/json",
81
81
  },
82
- body: JSON.stringify({
82
+ data: {
83
83
  requests: ops.map((op, index) => ({
84
84
  id: operationIndexToId(index),
85
85
  method: op.method,
@@ -88,8 +88,8 @@ async function executeBatch(...ops) {
88
88
  body: op.body === null ? undefined : op.body,
89
89
  dependsOn: op.dependsOn?.map((id) => id.toString()),
90
90
  })),
91
- }),
92
- agent,
91
+ },
92
+ httpAgent,
93
93
  });
94
94
  const responses = [];
95
95
  for (const r of body.responses) {
@@ -114,27 +114,48 @@ async function executeBatch(...ops) {
114
114
  return responses; // TODO: Is there a neater way to massage the types correctly? This is functionally correct, but I do want to avoid using `unknown` here if possible.
115
115
  }
116
116
  /** Execute request, supporting GraphAPI retry logic */
117
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: This function does need to be simplified, though it is a TODO for another day
117
118
  async function innerFetch(args) {
118
119
  const { url, ...options } = args;
120
+ if (!url) {
121
+ throw new Error("URL is required for request");
122
+ }
119
123
  let retryAfterMilliseconds = defaultRetryDelayMilliseconds;
120
124
  let response = null;
121
125
  let attempts = 0; // Track the number of attempts
126
+ const instance = axios.create({
127
+ httpsAgent: options.httpAgent,
128
+ });
122
129
  while (attempts < maxRetries) {
123
- // Retry at most 3 times
124
- response = await fetch(url, options);
125
- if (!(isHttpTooManyRequests(response.status) || isServiceUnavailable(response.status))) {
126
- break;
130
+ try {
131
+ response = await instance({
132
+ url,
133
+ ...options,
134
+ });
135
+ break; // If successful, exit the loop
127
136
  }
128
- const requestedRetryAfterSeconds = Number.parseInt(response.headers.get("Retry-After") ?? "0", 10);
129
- if (requestedRetryAfterSeconds) {
130
- retryAfterMilliseconds = requestedRetryAfterSeconds * 1000;
137
+ catch (error) {
138
+ if (axios.isAxiosError(error) && error.response) {
139
+ response = error.response;
140
+ if (!(isHttpTooManyRequests(response.status) || isServiceUnavailable(response.status) || isGatewayTimeout(response.status))) {
141
+ throw error; // Don't retry for other error codes
142
+ }
143
+ const requestedRetryAfterSeconds = Number.parseInt(response.headers["retry-after"] ?? "0", 10);
144
+ if (requestedRetryAfterSeconds) {
145
+ retryAfterMilliseconds = requestedRetryAfterSeconds * 1000;
146
+ }
147
+ await sleep(retryAfterMilliseconds);
148
+ retryAfterMilliseconds *= consecutiveRetryDelayMultiplier;
149
+ attempts++; // Increment the attempt counter
150
+ if (attempts >= maxRetries) {
151
+ RequestFailedError.throw(`GraphAPI fetch exceed retry limit of ${maxRetries} attempts.`, args);
152
+ }
153
+ }
154
+ else {
155
+ // For non-Axios errors or errors without response, just throw
156
+ throw error;
157
+ }
131
158
  }
132
- await sleep(retryAfterMilliseconds);
133
- retryAfterMilliseconds *= consecutiveRetryDelayMultiplier;
134
- attempts++; // Increment the attempt counter
135
- }
136
- if (attempts >= maxRetries) {
137
- RequestFailedError.throw(`GraphAPI fetch exceed retry limit of ${maxRetries} attempts.`, args);
138
159
  }
139
160
  if (!response) {
140
161
  throw new NeverError("Response is null. Should be impossible");
@@ -142,17 +163,15 @@ async function innerFetch(args) {
142
163
  if (isHttpTooManyRequests(response.status)) {
143
164
  RequestFailedError.throw("GraphAPI fetch failed after 3 retries due to too many requests.", args);
144
165
  }
145
- const replyContentType = response.headers.get("content-type")?.toLowerCase();
146
- const body = replyContentType?.startsWith("application/json") ? await response.json() : null;
147
166
  if (!isHttpOk(response.status)) {
148
- const bodyError = body;
167
+ const bodyError = response.data;
149
168
  let errorMessage = `${response.status} '${response.statusText}'`;
150
169
  if (bodyError?.error) {
151
170
  errorMessage += `: [${bodyError.error.code}] '${bodyError.error.message}'`;
152
171
  }
153
- RequestFailedError.throw(`GraphAPI fetch failed: ${errorMessage}`, args, body);
172
+ RequestFailedError.throw(`GraphAPI fetch failed: ${errorMessage}`, args, response.data);
154
173
  }
155
- return body;
174
+ return response.data;
156
175
  }
157
176
  function normalizeBatchBody(contentType, body) {
158
177
  if (contentType?.startsWith("application/json") && typeof body === "string") {
@@ -1 +1 @@
1
- {"version":3,"file":"getDriveItemContent.d.ts","sourceRoot":"","sources":["../../../../src/operations/driveItem/getDriveItemContent.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAMjE;;;;;;;GAOG;AACH,wBAA8B,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAmB7F"}
1
+ {"version":3,"file":"getDriveItemContent.d.ts","sourceRoot":"","sources":["../../../../src/operations/driveItem/getDriveItemContent.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAOjE;;;;;;;GAOG;AACH,wBAA8B,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAgC7F"}
@@ -1,8 +1,9 @@
1
- import fetch from "node-fetch";
1
+ import axios from "axios";
2
2
  import { authenticationScope, endpoint } from "../../graphApi.js";
3
3
  import { getCurrentAccessToken } from "../../services/accessToken.js";
4
4
  import { getContext } from "../../services/context.js";
5
5
  import { tryGetHttpAgent } from "../../services/httpAgent.js";
6
+ import { isHttpOk } from "../../services/httpStatus.js";
6
7
  import { generatePath } from "../../services/templatedPaths.js";
7
8
  /**
8
9
  * Download the content of a drive item.
@@ -17,15 +18,25 @@ export default async function getDriveItemContent(itemRef) {
17
18
  const url = `${endpoint}${generatePath("/sites/{site-id}/drives/{drive-id}/items/{item-id}/content", itemRef)}`;
18
19
  const context = getContext(itemRef.contextId);
19
20
  const accessToken = await getCurrentAccessToken(context.tenantId, context.clientId, context.clientSecret, authenticationScope);
20
- const agent = tryGetHttpAgent(context.httpProxy);
21
- const response = await fetch(url, {
21
+ const httpAgent = tryGetHttpAgent(context.httpProxy);
22
+ const response = await axios({
23
+ url,
24
+ method: "GET",
22
25
  headers: {
23
26
  authorization: `Bearer ${accessToken}`,
24
27
  },
25
- agent,
28
+ responseType: "arraybuffer",
29
+ httpsAgent: httpAgent,
26
30
  });
27
- if (!response.ok) {
31
+ if (!isHttpOk(response.status)) {
28
32
  throw new Error(`Failed to download file: ${response.status} ${response.statusText}`);
29
33
  }
30
- return await response.arrayBuffer();
34
+ if (!Buffer.isBuffer(response.data)) {
35
+ throw new Error(`Unexpected response type: ${typeof response.data}`);
36
+ }
37
+ const buffer = response.data.buffer.slice(response.data.byteOffset, response.data.byteOffset + response.data.byteLength);
38
+ if (!(buffer instanceof ArrayBuffer)) {
39
+ throw new Error("Failed to convert Buffer to ArrayBuffer");
40
+ }
41
+ return buffer;
31
42
  }
@@ -1,7 +1,7 @@
1
1
  import type { GraphOperation } from "../../models/GraphOperation.ts";
2
2
  import type { WorkbookRangeRef } from "../../models/WorkbookRangeRef.ts";
3
3
  /**
4
- * Autofit the columns in a range.
4
+ * Auto-fit the columns in a range.
5
5
  *
6
6
  * @param rangeRef - A reference to the range, optionally including session information.
7
7
  * @returns Nothing.
@@ -1,7 +1,7 @@
1
1
  import { operation } from "../../graphApi.js";
2
2
  import { generatePath } from "../../services/templatedPaths.js";
3
3
  /**
4
- * Autofit the columns in a range.
4
+ * Auto-fit the columns in a range.
5
5
  *
6
6
  * @param rangeRef - A reference to the range, optionally including session information.
7
7
  * @returns Nothing.
@@ -16,4 +16,10 @@ export declare function isHttpTooManyRequests(status: number): boolean;
16
16
  * @returns True if the status code is 503, otherwise false.
17
17
  */
18
18
  export declare function isServiceUnavailable(status: number): boolean;
19
+ /**
20
+ * Checks if the HTTP status code indicates a gateway has timed out.
21
+ * @param status - The HTTP status code.
22
+ * @returns True if the status code is 504, otherwise false.
23
+ */
24
+ export declare function isGatewayTimeout(status: number): boolean;
19
25
  //# sourceMappingURL=httpStatus.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"httpStatus.d.ts","sourceRoot":"","sources":["../../../src/services/httpStatus.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE5D"}
1
+ {"version":3,"file":"httpStatus.d.ts","sourceRoot":"","sources":["../../../src/services/httpStatus.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAExD"}
@@ -22,3 +22,11 @@ export function isHttpTooManyRequests(status) {
22
22
  export function isServiceUnavailable(status) {
23
23
  return status === 503;
24
24
  }
25
+ /**
26
+ * Checks if the HTTP status code indicates a gateway has timed out.
27
+ * @param status - The HTTP status code.
28
+ * @returns True if the status code is 504, otherwise false.
29
+ */
30
+ export function isGatewayTimeout(status) {
31
+ return status === 504;
32
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "microsoft-graph",
3
- "version": "2.8.0",
3
+ "version": "2.9.1",
4
4
  "description": "Microsoft GraphAPI SDK for NodeJS",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "module": "./dist/esm/index.js",
@@ -38,8 +38,8 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@azure/identity": "^4.8.0",
41
- "https-proxy-agent": "^7.0.6",
42
- "node-fetch": "^3.3.2"
41
+ "axios": "^1.7.9",
42
+ "https-proxy-agent": "^7.0.6"
43
43
  },
44
44
  "exports": {
45
45
  ".": {