microsoft-graph 3.7.1 → 3.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 (99) hide show
  1. package/dist/cjs/models/Address.d.ts +32 -1
  2. package/dist/cjs/models/Address.d.ts.map +1 -1
  3. package/dist/cjs/models/DriveItem.d.ts +6 -0
  4. package/dist/cjs/models/DriveItem.d.ts.map +1 -1
  5. package/dist/cjs/operations/driveItem/createDriveItem.d.ts +3 -0
  6. package/dist/cjs/operations/driveItem/createDriveItem.d.ts.map +1 -1
  7. package/dist/cjs/operations/driveItem/createDriveItem.js +3 -0
  8. package/dist/cjs/operations/driveItem/createDriveItemContent.d.ts +21 -0
  9. package/dist/cjs/operations/driveItem/createDriveItemContent.d.ts.map +1 -0
  10. package/dist/cjs/operations/driveItem/createDriveItemContent.js +122 -0
  11. package/dist/cjs/operations/driveItem/existsDriveItem.d.ts.map +1 -1
  12. package/dist/cjs/operations/driveItem/existsDriveItem.js +1 -2
  13. package/dist/cjs/operations/driveItem/getDriveItemContent.d.ts.map +1 -1
  14. package/dist/cjs/operations/driveItem/getDriveItemContent.js +2 -9
  15. package/dist/cjs/operations/driveItem/streamDriveItemContent.d.ts.map +1 -1
  16. package/dist/cjs/operations/driveItem/streamDriveItemContent.js +2 -9
  17. package/dist/cjs/services/azureApplicationCredentials.d.ts +2 -7
  18. package/dist/cjs/services/azureApplicationCredentials.d.ts.map +1 -1
  19. package/dist/cjs/services/azureApplicationCredentials.js +2 -7
  20. package/dist/cjs/services/context.d.ts +11 -8
  21. package/dist/cjs/services/context.d.ts.map +1 -1
  22. package/dist/cjs/services/context.js +19 -16
  23. package/dist/cjs/services/http.d.ts +12 -2
  24. package/dist/cjs/services/http.d.ts.map +1 -1
  25. package/dist/cjs/services/http.js +207 -3
  26. package/dist/cjs/services/httpStatus.d.ts +6 -0
  27. package/dist/cjs/services/httpStatus.d.ts.map +1 -1
  28. package/dist/cjs/services/httpStatus.js +9 -0
  29. package/dist/cjs/services/operationInvoker.d.ts +0 -1
  30. package/dist/cjs/services/operationInvoker.d.ts.map +1 -1
  31. package/dist/cjs/services/operationInvoker.js +8 -207
  32. package/dist/cjs/services/usedAddress.d.ts +25 -0
  33. package/dist/cjs/services/usedAddress.d.ts.map +1 -0
  34. package/dist/cjs/services/usedAddress.js +69 -0
  35. package/dist/cjs/tasks/iterateDriveItems.d.ts.map +1 -1
  36. package/dist/cjs/tasks/iterateDriveItems.js +1 -2
  37. package/dist/cjs/tasks/iterateDrives.d.ts.map +1 -1
  38. package/dist/cjs/tasks/iterateDrives.js +1 -2
  39. package/dist/cjs/tasks/iterateSiteSearch.d.ts.map +1 -1
  40. package/dist/cjs/tasks/iterateSiteSearch.js +1 -2
  41. package/dist/cjs/tasks/iterateSites.d.ts.map +1 -1
  42. package/dist/cjs/tasks/iterateSites.js +1 -2
  43. package/dist/esm/models/Address.d.ts +32 -1
  44. package/dist/esm/models/Address.d.ts.map +1 -1
  45. package/dist/esm/models/DriveItem.d.ts +6 -0
  46. package/dist/esm/models/DriveItem.d.ts.map +1 -1
  47. package/dist/esm/operations/driveItem/createDriveItem.d.ts +3 -0
  48. package/dist/esm/operations/driveItem/createDriveItem.d.ts.map +1 -1
  49. package/dist/esm/operations/driveItem/createDriveItem.js +3 -0
  50. package/dist/esm/operations/driveItem/createDriveItemContent.d.ts +21 -0
  51. package/dist/esm/operations/driveItem/createDriveItemContent.d.ts.map +1 -0
  52. package/dist/esm/operations/driveItem/createDriveItemContent.js +116 -0
  53. package/dist/esm/operations/driveItem/existsDriveItem.d.ts.map +1 -1
  54. package/dist/esm/operations/driveItem/existsDriveItem.js +2 -3
  55. package/dist/esm/operations/driveItem/getDriveItemContent.d.ts.map +1 -1
  56. package/dist/esm/operations/driveItem/getDriveItemContent.js +4 -11
  57. package/dist/esm/operations/driveItem/streamDriveItemContent.d.ts.map +1 -1
  58. package/dist/esm/operations/driveItem/streamDriveItemContent.js +4 -11
  59. package/dist/esm/services/azureApplicationCredentials.d.ts +2 -7
  60. package/dist/esm/services/azureApplicationCredentials.d.ts.map +1 -1
  61. package/dist/esm/services/azureApplicationCredentials.js +2 -7
  62. package/dist/esm/services/context.d.ts +11 -8
  63. package/dist/esm/services/context.d.ts.map +1 -1
  64. package/dist/esm/services/context.js +18 -15
  65. package/dist/esm/services/http.d.ts +12 -2
  66. package/dist/esm/services/http.d.ts.map +1 -1
  67. package/dist/esm/services/http.js +204 -2
  68. package/dist/esm/services/httpStatus.d.ts +6 -0
  69. package/dist/esm/services/httpStatus.d.ts.map +1 -1
  70. package/dist/esm/services/httpStatus.js +8 -0
  71. package/dist/esm/services/operationInvoker.d.ts +0 -1
  72. package/dist/esm/services/operationInvoker.d.ts.map +1 -1
  73. package/dist/esm/services/operationInvoker.js +10 -208
  74. package/dist/esm/services/usedAddress.d.ts +25 -0
  75. package/dist/esm/services/usedAddress.d.ts.map +1 -0
  76. package/dist/esm/services/usedAddress.js +63 -0
  77. package/dist/esm/tasks/iterateDriveItems.d.ts.map +1 -1
  78. package/dist/esm/tasks/iterateDriveItems.js +2 -3
  79. package/dist/esm/tasks/iterateDrives.d.ts.map +1 -1
  80. package/dist/esm/tasks/iterateDrives.js +2 -3
  81. package/dist/esm/tasks/iterateSiteSearch.d.ts.map +1 -1
  82. package/dist/esm/tasks/iterateSiteSearch.js +2 -3
  83. package/dist/esm/tasks/iterateSites.d.ts.map +1 -1
  84. package/dist/esm/tasks/iterateSites.js +2 -3
  85. package/docs/api/Address.md +99 -13
  86. package/docs/api/DriveItem-1.md +16 -0
  87. package/docs/api/README.md +3 -3
  88. package/docs/api/context.md +28 -26
  89. package/docs/api/createDriveItemContent.md +37 -0
  90. package/docs/api/drive.md +3 -3
  91. package/docs/api/http.md +65 -4
  92. package/docs/api/httpStatus.md +48 -26
  93. package/docs/api/operationInvoker.md +3 -22
  94. package/docs/api/services/usedAddress.md +47 -0
  95. package/docs/api/streamDriveItemContent.md +1 -1
  96. package/package.json +21 -1
  97. package/docs/api/azureApplicationCredentials.md +0 -31
  98. package/docs/api/createDriveItem.md +0 -38
  99. /package/docs/api/{AzureApplicationCredentials-1.md → AzureApplicationCredentials.md} +0 -0
@@ -3,6 +3,16 @@
3
3
  * @module http
4
4
  * @category Services
5
5
  */
6
- import { type AxiosRequestConfig } from "axios";
7
- export declare function executeHttpRequest(config: AxiosRequestConfig): Promise<import("axios").AxiosResponse<any, any>>;
6
+ import { type AxiosResponse, type RawAxiosRequestHeaders, type ResponseType } from "axios";
7
+ import type { HttpMethod } from "../models/Http.ts";
8
+ export type Request = {
9
+ url: string;
10
+ method: HttpMethod;
11
+ headers?: RawAxiosRequestHeaders;
12
+ data?: unknown;
13
+ responseType?: ResponseType;
14
+ };
15
+ export declare function execute<TResponse>(request: Request): Promise<TResponse>;
16
+ export declare function throwHttpException(responseCode: number, message: string): never;
17
+ export declare function executeRaw(request: Request): Promise<AxiosResponse<any, any>>;
8
18
  //# sourceMappingURL=http.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../src/services/http.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAc,EAAsB,KAAK,kBAAkB,EAA4B,MAAM,OAAO,CAAC;AAKrG,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,oDAMlE"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../src/services/http.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAc,EAA+C,KAAK,aAAa,EAA4B,KAAK,sBAAsB,EAAE,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AA0BzK,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAkCpD,MAAM,MAAM,OAAO,GAAG;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,YAAY,CAAC;CAC5B,CAAC;AAEF,wBAAsB,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAkD7E;AAED,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,CAwE/E;AAID,wBAAsB,UAAU,CAAC,OAAO,EAAE,OAAO,oCAMhD"}
@@ -5,12 +5,159 @@
5
5
  */
6
6
  import axios from "axios";
7
7
  import { HttpsProxyAgent } from "https-proxy-agent";
8
+ import BadRequestError from "../errors/BadRequestError.js";
9
+ import BandwidthLimitExceededError from "../errors/BandwidthLimitExceededError.js";
10
+ import ConflictError from "../errors/ConflictError.js";
11
+ import ForbiddenError from "../errors/ForbiddenError.js";
12
+ import GatewayTimeoutError from "../errors/GatewayTimeoutError.js";
13
+ import GoneError from "../errors/GoneError.js";
14
+ import InsufficientStorageError from "../errors/InsufficientStorageError.js";
15
+ import InternalServerError from "../errors/InternalServerError.js";
16
+ import LengthRequiredError from "../errors/LengthRequiredError.js";
17
+ import LockedError from "../errors/LockedError.js";
18
+ import MethodNotAllowedError from "../errors/MethodNotAllowedError.js";
19
+ import NeverError from "../errors/NeverError.js";
20
+ import NotAcceptableError from "../errors/NotAcceptableError.js";
21
+ import NotFoundError from "../errors/NotFoundError.js";
22
+ import NotImplementedError from "../errors/NotImplementedError.js";
23
+ import PaymentRequiredError from "../errors/PaymentRequiredError.js";
24
+ import PreconditionFailedError from "../errors/PreconditionFailedError.js";
25
+ import RequestedRangeNotSatisfiableError from "../errors/RequestedRangeNotSatisfiableError.js";
26
+ import RequestEntityTooLargeError from "../errors/RequestEntityTooLargeError.js";
27
+ import ServiceUnavailableError from "../errors/ServiceUnavailableError.js";
28
+ import TooManyRequestsError from "../errors/TooManyRequestsError.js";
29
+ import UnauthorizedError from "../errors/UnauthorizedError.js";
30
+ import UnprocessableEntityError from "../errors/UnprocessableEntityError.js";
31
+ import UnsupportedMediaTypeError from "../errors/UnsupportedMediaTypeError.js";
32
+ import { isHttpBadRequest, isHttpBandwidthLimitExceeded, isHttpConflict, isHttpForbidden, isHttpGatewayTimeout, isHttpGone, isHttpInsufficientStorage, isHttpInternalServerError, isHttpLengthRequired, isHttpLocked, isHttpMethodNotAllowed, isHttpNotAcceptable, isHttpNotFound, isHttpNotImplemented, isHttpPaymentRequired, isHttpPreconditionFailed, isHttpRequestedRangeNotSatisfiable, isHttpRequestEntityTooLarge, isHttpServiceUnavailable, isHttpSuccess, isHttpTooManyRequests, isHttpUnauthorized, isHttpUnprocessableEntity, isHttpUnsupportedMediaType, isRetryable, } from "./httpStatus.js";
33
+ import { sleep } from "./sleep.js";
34
+ const maxRetries = 3;
35
+ const defaultRetryDelayMilliseconds = 1000;
36
+ const consecutiveRetryDelayMultiplier = 2;
37
+ export async function execute(request) {
38
+ let retryAfterMilliseconds = defaultRetryDelayMilliseconds;
39
+ let response = null;
40
+ let attempts = 0;
41
+ let errorLog = "";
42
+ while (true) {
43
+ try {
44
+ response = await executeRaw(request);
45
+ }
46
+ catch (error) {
47
+ const message = error instanceof Error ? error.message : error?.toString() || "Unknown error";
48
+ response = {
49
+ status: -1,
50
+ statusText: message,
51
+ headers: {},
52
+ data: null,
53
+ config: request,
54
+ request: null,
55
+ };
56
+ errorLog += message;
57
+ }
58
+ errorLog += requestToString(request);
59
+ errorLog += responseToString(response);
60
+ attempts++;
61
+ if (isHttpSuccess(response.status) || !isRetryable(response.status) || attempts === maxRetries) {
62
+ break;
63
+ }
64
+ const requestedRetryAfterSeconds = Number.parseInt(response.headers["retry-after"] ?? "0", 10);
65
+ if (requestedRetryAfterSeconds) {
66
+ retryAfterMilliseconds = requestedRetryAfterSeconds * 1000;
67
+ }
68
+ else {
69
+ retryAfterMilliseconds += Math.random() * 1000; // Add some randomness to the retry delay to avoid thundering herd problem
70
+ }
71
+ errorLog += waitToString(retryAfterMilliseconds);
72
+ await sleep(retryAfterMilliseconds);
73
+ retryAfterMilliseconds *= consecutiveRetryDelayMultiplier;
74
+ }
75
+ if (!response) {
76
+ throw new NeverError("Response is empty.");
77
+ }
78
+ if (!isHttpSuccess(response.status)) {
79
+ handleResponseError(response, errorLog, attempts);
80
+ }
81
+ return response.data;
82
+ }
83
+ export function throwHttpException(responseCode, message) {
84
+ if (isHttpBadRequest(responseCode)) {
85
+ throw new BadRequestError(message);
86
+ }
87
+ if (isHttpUnauthorized(responseCode)) {
88
+ throw new UnauthorizedError(message);
89
+ }
90
+ if (isHttpPaymentRequired(responseCode)) {
91
+ throw new PaymentRequiredError(message);
92
+ }
93
+ if (isHttpForbidden(responseCode)) {
94
+ throw new ForbiddenError(message);
95
+ }
96
+ if (isHttpNotFound(responseCode)) {
97
+ throw new NotFoundError(message);
98
+ }
99
+ if (isHttpMethodNotAllowed(responseCode)) {
100
+ throw new MethodNotAllowedError(message);
101
+ }
102
+ if (isHttpNotAcceptable(responseCode)) {
103
+ throw new NotAcceptableError(message);
104
+ }
105
+ if (isHttpConflict(responseCode)) {
106
+ throw new ConflictError(message);
107
+ }
108
+ if (isHttpGone(responseCode)) {
109
+ throw new GoneError(message);
110
+ }
111
+ if (isHttpLengthRequired(responseCode)) {
112
+ throw new LengthRequiredError(message);
113
+ }
114
+ if (isHttpPreconditionFailed(responseCode)) {
115
+ throw new PreconditionFailedError(message);
116
+ }
117
+ if (isHttpRequestEntityTooLarge(responseCode)) {
118
+ throw new RequestEntityTooLargeError(message);
119
+ }
120
+ if (isHttpUnsupportedMediaType(responseCode)) {
121
+ throw new UnsupportedMediaTypeError(message);
122
+ }
123
+ if (isHttpRequestedRangeNotSatisfiable(responseCode)) {
124
+ throw new RequestedRangeNotSatisfiableError(message);
125
+ }
126
+ if (isHttpUnprocessableEntity(responseCode)) {
127
+ throw new UnprocessableEntityError(message);
128
+ }
129
+ if (isHttpLocked(responseCode)) {
130
+ throw new LockedError(message);
131
+ }
132
+ if (isHttpTooManyRequests(responseCode)) {
133
+ throw new TooManyRequestsError(message);
134
+ }
135
+ if (isHttpInternalServerError(responseCode)) {
136
+ throw new InternalServerError(message);
137
+ }
138
+ if (isHttpNotImplemented(responseCode)) {
139
+ throw new NotImplementedError(message);
140
+ }
141
+ if (isHttpServiceUnavailable(responseCode)) {
142
+ throw new ServiceUnavailableError(message);
143
+ }
144
+ if (isHttpGatewayTimeout(responseCode)) {
145
+ throw new GatewayTimeoutError(message);
146
+ }
147
+ if (isHttpInsufficientStorage(responseCode)) {
148
+ throw new InsufficientStorageError(message);
149
+ }
150
+ if (isHttpBandwidthLimitExceeded(responseCode)) {
151
+ throw new BandwidthLimitExceededError(message);
152
+ }
153
+ throw new Error(message);
154
+ }
8
155
  let instance = null;
9
- export async function executeHttpRequest(config) {
156
+ export async function executeRaw(request) {
10
157
  if (!instance) {
11
158
  instance = createAxiosInstance();
12
159
  }
13
- return await instance(config);
160
+ return await instance(request);
14
161
  }
15
162
  function createAxiosInstance() {
16
163
  const config = {
@@ -24,3 +171,58 @@ function createAxiosInstance() {
24
171
  }
25
172
  return axios.create(config);
26
173
  }
174
+ function requestToString(request) {
175
+ const url = request.url || "";
176
+ let message = ` 📤 ${request.method} ${url}\n`;
177
+ if (request.data) {
178
+ message += errorObjectToString(request.data);
179
+ }
180
+ return message;
181
+ }
182
+ function responseToString(response) {
183
+ const message = ` 📥 ${response.status} ${response.statusText}\n`;
184
+ // TODO: Is there any case where we care about the response body?
185
+ // if (response.data) {
186
+ // message += errorObjectToString(response.data);
187
+ // }
188
+ return message;
189
+ }
190
+ function waitToString(milliseconds) {
191
+ return ` ⏳ Wait ${milliseconds}ms for retry.\n`;
192
+ }
193
+ function errorObjectToString(obj) {
194
+ const maxLength = 1024;
195
+ const ellipses = "...";
196
+ let str = JSON.stringify(obj, null, 2)
197
+ .split("\n")
198
+ .map((line) => ` ${line}`)
199
+ .join("\n");
200
+ if (str.length > maxLength) {
201
+ str = `${str.substring(0, maxLength - ellipses.length)}${ellipses}`;
202
+ }
203
+ return `${str}\n`;
204
+ }
205
+ function handleResponseError(response, errorLog, attempts, operationIndex = null) {
206
+ const error = response.data;
207
+ let message = error?.error?.message;
208
+ if (message && !message.endsWith(".")) {
209
+ message += ".";
210
+ }
211
+ if (error?.error?.innerError?.message) {
212
+ message += ` ${error.error.innerError.message}`;
213
+ }
214
+ if (message && !message.endsWith(".")) {
215
+ message += ".";
216
+ }
217
+ if (!message) {
218
+ message = response.statusText;
219
+ }
220
+ if (attempts > 1) {
221
+ message += ` Operation attempted ${attempts} time(s).`;
222
+ }
223
+ if (operationIndex !== null) {
224
+ message += ` (op #${operationIndex})`;
225
+ }
226
+ message += `\n${errorLog}`;
227
+ throwHttpException(response.status, message);
228
+ }
@@ -15,6 +15,12 @@ export declare function isHttpSuccess(status: number): boolean;
15
15
  * @returns True if the status code is 200, otherwise false.
16
16
  */
17
17
  export declare function isHttpOk(status: number): boolean;
18
+ /**
19
+ * Checks if the HTTP status code is created
20
+ * @param status - The HTTP status code.
21
+ * @returns True if the status code is 201, otherwise false.
22
+ */
23
+ export declare function isHttpCreated(status: number): boolean;
18
24
  /**
19
25
  * Checks if the HTTP status code indicates not found.
20
26
  * @param status - The HTTP status code.
@@ -1 +1 @@
1
- {"version":3,"file":"httpStatus.d.ts","sourceRoot":"","sources":["../../../src/services/httpStatus.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAElD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAElE;AAED;;;;GAIG;AACH,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE1E;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEjE;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEjE;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEpE;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEjE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAenD"}
1
+ {"version":3,"file":"httpStatus.d.ts","sourceRoot":"","sources":["../../../src/services/httpStatus.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAElD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAElE;AAED;;;;GAIG;AACH,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE1E;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEjE;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEjE;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEpE;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEjE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAenD"}
@@ -19,6 +19,14 @@ export function isHttpSuccess(status) {
19
19
  export function isHttpOk(status) {
20
20
  return status === 200;
21
21
  }
22
+ /**
23
+ * Checks if the HTTP status code is created
24
+ * @param status - The HTTP status code.
25
+ * @returns True if the status code is 201, otherwise false.
26
+ */
27
+ export function isHttpCreated(status) {
28
+ return status === 201;
29
+ }
22
30
  /**
23
31
  * Checks if the HTTP status code indicates not found.
24
32
  * @param status - The HTTP status code.
@@ -39,5 +39,4 @@ export declare function parallel<T extends GraphOperation<unknown>[]>(...operati
39
39
  * @returns The responses for each operation, in the same order.
40
40
  */
41
41
  export declare function sequential<T extends GraphOperation<unknown>[]>(...operations: T): Promise<OperationResponse<T>>;
42
- export declare function throwException(responseCode: number, message: string): never;
43
42
  //# sourceMappingURL=operationInvoker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"operationInvoker.d.ts","sourceRoot":"","sources":["../../../src/services/operationInvoker.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,cAAc,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAiC/G;;;GAGG;AACH,eAAO,MAAM,QAAQ,qCAAqC,CAAC;AAE3D;;;GAGG;AACH,eAAO,MAAM,aAAa,4CAAuB,CAAC;AAElD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,wBAAwB,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAQvF;AAED;;;;;;;;GAQG;AACH,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;;;;;;;;GAQG;AACH,wBAAsB,UAAU,CAAC,CAAC,SAAS,cAAc,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,UAAU,EAAE,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAOrH;AAoND,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,CAwE3E"}
1
+ {"version":3,"file":"operationInvoker.d.ts","sourceRoot":"","sources":["../../../src/services/operationInvoker.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAM/G;;;GAGG;AACH,eAAO,MAAM,QAAQ,qCAAqC,CAAC;AAE3D;;;GAGG;AACH,eAAO,MAAM,aAAa,4CAAuB,CAAC;AAElD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,wBAAwB,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAQvF;AAED;;;;;;;;GAQG;AACH,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;;;;;;;;GAQG;AACH,wBAAsB,UAAU,CAAC,CAAC,SAAS,cAAc,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,UAAU,EAAE,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAOrH"}
@@ -1,34 +1,15 @@
1
- import BadRequestError from "../errors/BadRequestError.js";
2
- import BandwidthLimitExceededError from "../errors/BandwidthLimitExceededError.js";
3
- import ConflictError from "../errors/ConflictError.js";
4
- import ForbiddenError from "../errors/ForbiddenError.js";
5
- import GatewayTimeoutError from "../errors/GatewayTimeoutError.js";
6
- import GoneError from "../errors/GoneError.js";
1
+ /**
2
+ * Invoke operations, potentially as parallel or sequential batches.
3
+ * @module operationInvoker
4
+ * @category Services
5
+ **/
7
6
  import InconsistentContextError from "../errors/InconsistentContextError.js";
8
- import InsufficientStorageError from "../errors/InsufficientStorageError.js";
9
- import InternalServerError from "../errors/InternalServerError.js";
10
7
  import InvalidArgumentError from "../errors/InvalidArgumentError.js";
11
- import LengthRequiredError from "../errors/LengthRequiredError.js";
12
- import LockedError from "../errors/LockedError.js";
13
- import MethodNotAllowedError from "../errors/MethodNotAllowedError.js";
14
8
  import NeverError from "../errors/NeverError.js";
15
- import NotAcceptableError from "../errors/NotAcceptableError.js";
16
- import NotFoundError from "../errors/NotFoundError.js";
17
- import NotImplementedError from "../errors/NotImplementedError.js";
18
- import PaymentRequiredError from "../errors/PaymentRequiredError.js";
19
- import PreconditionFailedError from "../errors/PreconditionFailedError.js";
20
9
  import ProtocolError from "../errors/ProtocolError.js";
21
- import RequestedRangeNotSatisfiableError from "../errors/RequestedRangeNotSatisfiableError.js";
22
- import RequestEntityTooLargeError from "../errors/RequestEntityTooLargeError.js";
23
- import ServiceUnavailableError from "../errors/ServiceUnavailableError.js";
24
- import TooManyRequestsError from "../errors/TooManyRequestsError.js";
25
- import UnauthorizedError from "../errors/UnauthorizedError.js";
26
- import UnprocessableEntityError from "../errors/UnprocessableEntityError.js";
27
- import UnsupportedMediaTypeError from "../errors/UnsupportedMediaTypeError.js";
28
- import { executeHttpRequest } from "./http.js";
29
- import { isHttpBadRequest, isHttpBandwidthLimitExceeded, isHttpConflict, isHttpForbidden, isHttpGatewayTimeout, isHttpGone, isHttpInsufficientStorage, isHttpInternalServerError, isHttpLengthRequired, isHttpLocked, isHttpMethodNotAllowed, isHttpNotAcceptable, isHttpNotFound, isHttpNotImplemented, isHttpPaymentRequired, isHttpPreconditionFailed, isHttpRequestedRangeNotSatisfiable, isHttpRequestEntityTooLarge, isHttpServiceUnavailable, isHttpSuccess, isHttpTooManyRequests, isHttpUnauthorized, isHttpUnprocessableEntity, isHttpUnsupportedMediaType, isRetryable, } from "./httpStatus.js";
10
+ import { execute, throwHttpException } from "./http.js";
11
+ import { isHttpSuccess } from "./httpStatus.js";
30
12
  import { operationIdToIndex, operationIndexToId } from "./operationId.js";
31
- import { sleep } from "./sleep.js";
32
13
  /**
33
14
  * Endpoint for submitting individual requests.
34
15
  * @internal
@@ -86,12 +67,9 @@ export async function sequential(...operations) {
86
67
  return (await executeBatch(...definitions));
87
68
  }
88
69
  const maxBatchOperations = 20; // https://learn.microsoft.com/en-us/graph/json-batching?tabs=http#batch-size-limitations
89
- const maxRetries = 3;
90
- const defaultRetryDelayMilliseconds = 1000;
91
- const consecutiveRetryDelayMultiplier = 2;
92
70
  async function executeSingle(definition) {
93
71
  const accessToken = await definition.context.generateAccessToken();
94
- const response = await innerFetch({
72
+ const response = await execute({
95
73
  url: `${endpoint}${definition.path}`,
96
74
  method: definition.method,
97
75
  headers: {
@@ -116,7 +94,7 @@ async function executeBatch(...ops) {
116
94
  throw new InconsistentContextError("All operations in a batch must share the same context.");
117
95
  }
118
96
  const accessToken = await context.generateAccessToken();
119
- const body = await innerFetch({
97
+ const body = await execute({
120
98
  url: batchEndpoint,
121
99
  method: "POST",
122
100
  headers: {
@@ -146,188 +124,12 @@ async function executeBatch(...ops) {
146
124
  throw new ProtocolError("Reference to operation that was not submitted in the batch");
147
125
  }
148
126
  if (!isHttpSuccess(r.status)) {
149
- throwException(r.status, `Batch operation failed for op #${index}: ${JSON.stringify(r.body, null, 2)}`);
127
+ throwHttpException(r.status, `Batch operation failed for op #${index}: ${JSON.stringify(r.body, null, 2)}`);
150
128
  }
151
129
  responses[index] = op.responseTransform(body);
152
130
  }
153
131
  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.
154
132
  }
155
- async function innerFetch(request) {
156
- let retryAfterMilliseconds = defaultRetryDelayMilliseconds;
157
- let response = null;
158
- let attempts = 0;
159
- let errorLog = "";
160
- while (true) {
161
- try {
162
- response = await executeHttpRequest(request);
163
- }
164
- catch (error) {
165
- const message = error instanceof Error ? error.message : error?.toString() || "Unknown error";
166
- response = {
167
- status: -1,
168
- statusText: message,
169
- headers: {},
170
- data: null,
171
- config: request,
172
- request: null,
173
- };
174
- errorLog += message;
175
- }
176
- errorLog += requestToString(request);
177
- errorLog += responseToString(response);
178
- attempts++;
179
- if (isHttpSuccess(response.status) || !isRetryable(response.status) || attempts === maxRetries) {
180
- break;
181
- }
182
- const requestedRetryAfterSeconds = Number.parseInt(response.headers["retry-after"] ?? "0", 10);
183
- if (requestedRetryAfterSeconds) {
184
- retryAfterMilliseconds = requestedRetryAfterSeconds * 1000;
185
- }
186
- else {
187
- retryAfterMilliseconds += Math.random() * 1000; // Add some randomness to the retry delay to avoid thundering herd problem
188
- }
189
- errorLog += waitToString(retryAfterMilliseconds);
190
- await sleep(retryAfterMilliseconds);
191
- retryAfterMilliseconds *= consecutiveRetryDelayMultiplier;
192
- }
193
- if (!response) {
194
- throw new NeverError("Response is empty.");
195
- }
196
- if (!isHttpSuccess(response.status)) {
197
- handleResponseError(response, errorLog, attempts);
198
- }
199
- return response.data;
200
- }
201
- function requestToString(request) {
202
- let url = request.url || "";
203
- if (url.startsWith(endpoint)) {
204
- url = url.substring(endpoint.length);
205
- }
206
- let message = ` 📤 ${request.method} ${url}\n`;
207
- if (request.data) {
208
- message += errorObjectToString(request.data);
209
- }
210
- return message;
211
- }
212
- function responseToString(response) {
213
- const message = ` 📥 ${response.status} ${response.statusText}\n`;
214
- // TODO: Is there any case where we care about the response body?
215
- // if (response.data) {
216
- // message += errorObjectToString(response.data);
217
- // }
218
- return message;
219
- }
220
- function waitToString(milliseconds) {
221
- return ` ⏳ Wait ${milliseconds}ms for retry.\n`;
222
- }
223
- function errorObjectToString(obj) {
224
- const maxLength = 1024;
225
- const ellipses = "...";
226
- let str = JSON.stringify(obj, null, 2)
227
- .split("\n")
228
- .map((line) => ` ${line}`)
229
- .join("\n");
230
- if (str.length > maxLength) {
231
- str = `${str.substring(0, maxLength - ellipses.length)}${ellipses}`;
232
- }
233
- return `${str}\n`;
234
- }
235
- function handleResponseError(response, errorLog, attempts, operationIndex = null) {
236
- const error = response.data;
237
- let message = error?.error?.message;
238
- if (message && !message.endsWith(".")) {
239
- message += ".";
240
- }
241
- if (error?.error?.innerError?.message) {
242
- message += ` ${error.error.innerError.message}`;
243
- }
244
- if (message && !message.endsWith(".")) {
245
- message += ".";
246
- }
247
- if (!message) {
248
- message = response.statusText;
249
- }
250
- if (attempts > 1) {
251
- message += ` Operation attempted ${attempts} time(s).`;
252
- }
253
- if (operationIndex !== null) {
254
- message += ` (op #${operationIndex})`;
255
- }
256
- message += `\n${errorLog}`;
257
- throwException(response.status, message);
258
- }
259
- export function throwException(responseCode, message) {
260
- if (isHttpBadRequest(responseCode)) {
261
- throw new BadRequestError(message);
262
- }
263
- if (isHttpUnauthorized(responseCode)) {
264
- throw new UnauthorizedError(message);
265
- }
266
- if (isHttpPaymentRequired(responseCode)) {
267
- throw new PaymentRequiredError(message);
268
- }
269
- if (isHttpForbidden(responseCode)) {
270
- throw new ForbiddenError(message);
271
- }
272
- if (isHttpNotFound(responseCode)) {
273
- throw new NotFoundError(message);
274
- }
275
- if (isHttpMethodNotAllowed(responseCode)) {
276
- throw new MethodNotAllowedError(message);
277
- }
278
- if (isHttpNotAcceptable(responseCode)) {
279
- throw new NotAcceptableError(message);
280
- }
281
- if (isHttpConflict(responseCode)) {
282
- throw new ConflictError(message);
283
- }
284
- if (isHttpGone(responseCode)) {
285
- throw new GoneError(message);
286
- }
287
- if (isHttpLengthRequired(responseCode)) {
288
- throw new LengthRequiredError(message);
289
- }
290
- if (isHttpPreconditionFailed(responseCode)) {
291
- throw new PreconditionFailedError(message);
292
- }
293
- if (isHttpRequestEntityTooLarge(responseCode)) {
294
- throw new RequestEntityTooLargeError(message);
295
- }
296
- if (isHttpUnsupportedMediaType(responseCode)) {
297
- throw new UnsupportedMediaTypeError(message);
298
- }
299
- if (isHttpRequestedRangeNotSatisfiable(responseCode)) {
300
- throw new RequestedRangeNotSatisfiableError(message);
301
- }
302
- if (isHttpUnprocessableEntity(responseCode)) {
303
- throw new UnprocessableEntityError(message);
304
- }
305
- if (isHttpLocked(responseCode)) {
306
- throw new LockedError(message);
307
- }
308
- if (isHttpTooManyRequests(responseCode)) {
309
- throw new TooManyRequestsError(message);
310
- }
311
- if (isHttpInternalServerError(responseCode)) {
312
- throw new InternalServerError(message);
313
- }
314
- if (isHttpNotImplemented(responseCode)) {
315
- throw new NotImplementedError(message);
316
- }
317
- if (isHttpServiceUnavailable(responseCode)) {
318
- throw new ServiceUnavailableError(message);
319
- }
320
- if (isHttpGatewayTimeout(responseCode)) {
321
- throw new GatewayTimeoutError(message);
322
- }
323
- if (isHttpInsufficientStorage(responseCode)) {
324
- throw new InsufficientStorageError(message);
325
- }
326
- if (isHttpBandwidthLimitExceeded(responseCode)) {
327
- throw new BandwidthLimitExceededError(message);
328
- }
329
- throw new NeverError(message);
330
- }
331
133
  function normalizeBatchBody(contentType, body) {
332
134
  if (contentType?.startsWith("application/json") && typeof body === "string") {
333
135
  return JSON.parse(atob(body));
@@ -0,0 +1,25 @@
1
+ import type { Address, CellRangeAddress, UsedAddress } from "../models/Address.ts";
2
+ /**
3
+ * Resolves a used range address (which may use partial or open-ended A1 notation, e.g., ":D5", "C:", etc.) against a concrete used range.
4
+ *
5
+ * This function fills in any missing start/end columns or rows in the `usedRangeAddress` using the corresponding values from the provided `usedRange`.
6
+ *
7
+ * @param address - The used range address (may be open-ended, e.g., ":D5", "C:", etc.).
8
+ * @param usedRange - The concrete used range address to resolve against (e.g., "B2:E10").
9
+ * @returns The resolved address as a concrete A1 range (e.g., "C2:E10"), or null if there is no overlap.
10
+ * @throws {InvalidArgumentError} If the used range address is invalid or cannot be resolved.
11
+ *
12
+ * @example
13
+ * // If usedRange is "B2:E10":
14
+ * // resolveUsedRangeAddress("C:", usedRange) // "C2:E10"
15
+ * // resolveUsedRangeAddress(":D", usedRange) // "B2:D10"
16
+ * // resolveUsedRangeAddress("3:", usedRange) // "B3:E10"
17
+ * // resolveUsedRangeAddress(":5", usedRange) // "B2:E5"
18
+ * // resolveUsedRangeAddress("C3:", usedRange) // "C3:E10"
19
+ * // resolveUsedRangeAddress(":D5", usedRange) // "B2:D5"
20
+ * // resolveUsedRangeAddress(":", usedRange) // "B2:E10"
21
+ * // resolveUsedRangeAddress("Z100:Z200", usedRange) // null (no overlap)
22
+ * // resolveUsedRangeAddress("A1:A1", usedRange) // null (no overlap)
23
+ */
24
+ export declare function resolveUsedAddress(address: Address | UsedAddress, usedRange: CellRangeAddress): Address | null;
25
+ //# sourceMappingURL=usedAddress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usedAddress.d.ts","sourceRoot":"","sources":["../../../src/services/usedAddress.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAMnF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,WAAW,EAAE,SAAS,EAAE,gBAAgB,GAAG,OAAO,GAAG,IAAI,CAuC9G"}
@@ -0,0 +1,63 @@
1
+ import InvalidArgumentError from "../errors/InvalidArgumentError.js";
2
+ import { composeAddress, decomposeAddress } from "./addressManipulation.js";
3
+ import { columnAddressToOffset, rowAddressToOffset } from "./addressOffset.js";
4
+ const pattern = /^(?<startColumn>[A-Z]*)(?<startRow>[0-9]*):(?<endColumn>[A-Z]*)(?<endRow>[0-9]*)$/;
5
+ /**
6
+ * Resolves a used range address (which may use partial or open-ended A1 notation, e.g., ":D5", "C:", etc.) against a concrete used range.
7
+ *
8
+ * This function fills in any missing start/end columns or rows in the `usedRangeAddress` using the corresponding values from the provided `usedRange`.
9
+ *
10
+ * @param address - The used range address (may be open-ended, e.g., ":D5", "C:", etc.).
11
+ * @param usedRange - The concrete used range address to resolve against (e.g., "B2:E10").
12
+ * @returns The resolved address as a concrete A1 range (e.g., "C2:E10"), or null if there is no overlap.
13
+ * @throws {InvalidArgumentError} If the used range address is invalid or cannot be resolved.
14
+ *
15
+ * @example
16
+ * // If usedRange is "B2:E10":
17
+ * // resolveUsedRangeAddress("C:", usedRange) // "C2:E10"
18
+ * // resolveUsedRangeAddress(":D", usedRange) // "B2:D10"
19
+ * // resolveUsedRangeAddress("3:", usedRange) // "B3:E10"
20
+ * // resolveUsedRangeAddress(":5", usedRange) // "B2:E5"
21
+ * // resolveUsedRangeAddress("C3:", usedRange) // "C3:E10"
22
+ * // resolveUsedRangeAddress(":D5", usedRange) // "B2:D5"
23
+ * // resolveUsedRangeAddress(":", usedRange) // "B2:E10"
24
+ * // resolveUsedRangeAddress("Z100:Z200", usedRange) // null (no overlap)
25
+ * // resolveUsedRangeAddress("A1:A1", usedRange) // null (no overlap)
26
+ */
27
+ export function resolveUsedAddress(address, usedRange) {
28
+ const match = pattern.exec(address.toUpperCase());
29
+ if (!match || !match.groups) {
30
+ throw new InvalidArgumentError(`Invalid used range address '${address}', Must match pattern '${pattern}'.`);
31
+ }
32
+ let { startColumn, startRow, endColumn, endRow } = match.groups;
33
+ const { startColumn: usedStartColumn, endColumn: usedEndColumn, startRow: usedStartRow, endRow: usedEndRow } = decomposeAddress(usedRange);
34
+ if (!startColumn)
35
+ startColumn = usedStartColumn;
36
+ if (!endColumn)
37
+ endColumn = usedEndColumn;
38
+ if (!startRow)
39
+ startRow = usedStartRow;
40
+ if (!endRow)
41
+ endRow = usedEndRow;
42
+ const resolved = composeAddress({
43
+ startColumn: startColumn,
44
+ endColumn: endColumn,
45
+ startRow: startRow,
46
+ endRow: endRow,
47
+ });
48
+ const decomposed = decomposeAddress(resolved);
49
+ const resStartCol = columnAddressToOffset(decomposed.startColumn);
50
+ const resEndCol = columnAddressToOffset(decomposed.endColumn);
51
+ const usedStartCol = columnAddressToOffset(usedStartColumn);
52
+ const usedEndCol = columnAddressToOffset(usedEndColumn);
53
+ const resStartRow = rowAddressToOffset(decomposed.startRow);
54
+ const resEndRow = rowAddressToOffset(decomposed.endRow);
55
+ const usedStartRowNum = rowAddressToOffset(usedStartRow);
56
+ const usedEndRowNum = rowAddressToOffset(usedEndRow);
57
+ const colOverlap = resStartCol <= usedEndCol && resEndCol >= usedStartCol;
58
+ const rowOverlap = resStartRow <= usedEndRowNum && resEndRow >= usedStartRowNum;
59
+ if (!colOverlap || !rowOverlap) {
60
+ return null;
61
+ }
62
+ return resolved;
63
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"iterateDriveItems.d.ts","sourceRoot":"","sources":["../../../src/tasks/iterateDriveItems.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAe,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAKxE;;;;;;GAMG;AACH,wBAA+B,iBAAiB,CAAC,SAAS,EAAE,QAAQ,GAAG,YAAY,EAAE,WAAW,SAAO,GAAG,cAAc,CAAC,SAAS,GAAG,YAAY,CAAC,CA0BjJ"}
1
+ {"version":3,"file":"iterateDriveItems.d.ts","sourceRoot":"","sources":["../../../src/tasks/iterateDriveItems.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAe,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAKxE;;;;;;GAMG;AACH,wBAA+B,iBAAiB,CAAC,SAAS,EAAE,QAAQ,GAAG,YAAY,EAAE,WAAW,SAAO,GAAG,cAAc,CAAC,SAAS,GAAG,YAAY,CAAC,CAyBjJ"}