@adobe/helix-onedrive-support 10.0.13 → 10.1.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/CHANGELOG.md +14 -0
- package/package.json +7 -7
- package/src/OneDrive.js +8 -1
- package/src/RateLimit.js +77 -0
- package/src/StatusCodeError.js +6 -3
- package/src/excel/NamedItemContainer.js +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [10.1.0](https://github.com/adobe/helix-onedrive-support/compare/v10.0.14...v10.1.0) (2023-06-05)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* add rate limit in log and StatusCodeError ([#394](https://github.com/adobe/helix-onedrive-support/issues/394)) ([d9289fd](https://github.com/adobe/helix-onedrive-support/commit/d9289fd12fd290ad6482f3604ab9a3b1b9f1200d))
|
|
7
|
+
|
|
8
|
+
## [10.0.14](https://github.com/adobe/helix-onedrive-support/compare/v10.0.13...v10.0.14) (2023-06-03)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **deps:** update dependency @adobe/helix-shared-tokencache to v1.2.5 ([#393](https://github.com/adobe/helix-onedrive-support/issues/393)) ([a40b956](https://github.com/adobe/helix-onedrive-support/commit/a40b956a4bb01f10ea85d84bb387a7644f54173d))
|
|
14
|
+
|
|
1
15
|
## [10.0.13](https://github.com/adobe/helix-onedrive-support/compare/v10.0.12...v10.0.13) (2023-05-28)
|
|
2
16
|
|
|
3
17
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/helix-onedrive-support",
|
|
3
|
-
"version": "10.0
|
|
3
|
+
"version": "10.1.0",
|
|
4
4
|
"description": "Helix OneDrive Support",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"homepage": "https://github.com/adobe/helix-onedrive-support#readme",
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@adobe/fetch": "4.0.13",
|
|
31
|
-
"@adobe/helix-shared-tokencache": "1.2.
|
|
31
|
+
"@adobe/helix-shared-tokencache": "1.2.5",
|
|
32
32
|
"@azure/msal-node": "1.17.2",
|
|
33
33
|
"jose": "4.14.4"
|
|
34
34
|
},
|
|
@@ -36,12 +36,12 @@
|
|
|
36
36
|
"@adobe/eslint-config-helix": "2.0.2",
|
|
37
37
|
"@semantic-release/changelog": "6.0.3",
|
|
38
38
|
"@semantic-release/git": "10.0.1",
|
|
39
|
-
"@aws-sdk/client-s3": "3.
|
|
39
|
+
"@aws-sdk/client-s3": "3.345.0",
|
|
40
40
|
"ajv": "8.12.0",
|
|
41
|
-
"c8": "7.
|
|
41
|
+
"c8": "7.14.0",
|
|
42
42
|
"codecov": "3.8.3",
|
|
43
|
-
"dotenv": "16.
|
|
44
|
-
"eslint": "8.
|
|
43
|
+
"dotenv": "16.1.3",
|
|
44
|
+
"eslint": "8.42.0",
|
|
45
45
|
"eslint-plugin-header": "3.1.1",
|
|
46
46
|
"eslint-plugin-import": "2.27.5",
|
|
47
47
|
"husky": "8.0.3",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"mocha-multi-reporters": "1.5.1",
|
|
55
55
|
"nock": "13.3.1",
|
|
56
56
|
"npm": "9.6.7",
|
|
57
|
-
"semantic-release": "21.0.
|
|
57
|
+
"semantic-release": "21.0.3"
|
|
58
58
|
},
|
|
59
59
|
"lint-staged": {
|
|
60
60
|
"*.js": "eslint"
|
package/src/OneDrive.js
CHANGED
|
@@ -16,6 +16,7 @@ import { Workbook } from './excel/Workbook.js';
|
|
|
16
16
|
import { StatusCodeError } from './StatusCodeError.js';
|
|
17
17
|
import { editDistance, sanitizeName, splitByExtension } from './utils.js';
|
|
18
18
|
import { SharePointSite } from './SharePointSite.js';
|
|
19
|
+
import { RateLimit } from './RateLimit.js';
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* the maximum subscription time in milliseconds
|
|
@@ -128,12 +129,18 @@ export class OneDrive {
|
|
|
128
129
|
try {
|
|
129
130
|
const { fetch } = this.fetchContext;
|
|
130
131
|
const resp = await fetch(url, opts);
|
|
132
|
+
const rateLimit = RateLimit.fromHeaders(resp.headers);
|
|
133
|
+
|
|
134
|
+
if (rateLimit) {
|
|
135
|
+
this.log.warn({ sharepointRateLimit: { tenant: this.auth.tenant, ...rateLimit.toJSON() } });
|
|
136
|
+
}
|
|
137
|
+
|
|
131
138
|
if (!resp.ok) {
|
|
132
139
|
const text = await resp.text();
|
|
133
140
|
let err;
|
|
134
141
|
try {
|
|
135
142
|
// try to parse json
|
|
136
|
-
err = StatusCodeError.fromErrorResponse(JSON.parse(text), resp.status);
|
|
143
|
+
err = StatusCodeError.fromErrorResponse(JSON.parse(text), resp.status, rateLimit);
|
|
137
144
|
} catch {
|
|
138
145
|
err = new StatusCodeError(text, resp.status);
|
|
139
146
|
}
|
package/src/RateLimit.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Rate limit class
|
|
15
|
+
*/
|
|
16
|
+
export class RateLimit {
|
|
17
|
+
static fromHeaders(headers) {
|
|
18
|
+
const names = [
|
|
19
|
+
['RateLimit-Limit', 'limit'],
|
|
20
|
+
['RateLimit-Remaining', 'remaining'],
|
|
21
|
+
['RateLimit-Reset', 'reset'],
|
|
22
|
+
['Retry-After', 'retryAfter'],
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const result = {};
|
|
26
|
+
let notEmpty = false;
|
|
27
|
+
|
|
28
|
+
names.forEach(([hdr, prop]) => {
|
|
29
|
+
const valueS = headers.get(hdr);
|
|
30
|
+
if (valueS) {
|
|
31
|
+
const value = Number.parseInt(valueS, 10);
|
|
32
|
+
if (!Number.isNaN(value)) {
|
|
33
|
+
result[prop] = value;
|
|
34
|
+
notEmpty = true;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
return notEmpty ? new RateLimit(result) : null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
constructor({
|
|
42
|
+
limit, remaining, reset, retryAfter,
|
|
43
|
+
}) {
|
|
44
|
+
this._limit = limit;
|
|
45
|
+
this._remaining = remaining;
|
|
46
|
+
this._reset = reset;
|
|
47
|
+
this._retryAfter = retryAfter;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
get limit() {
|
|
51
|
+
return this._limit;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
get remaining() {
|
|
55
|
+
return this._remaining;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get reset() {
|
|
59
|
+
return this._reset;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
get retryAfter() {
|
|
63
|
+
return this._retryAfter;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
toJSON() {
|
|
67
|
+
const o = {
|
|
68
|
+
limit: this.limit,
|
|
69
|
+
remaining: this.remaining,
|
|
70
|
+
reset: this.reset,
|
|
71
|
+
};
|
|
72
|
+
if (this.retryAfter) {
|
|
73
|
+
o.retryAfter = this.retryAfter;
|
|
74
|
+
}
|
|
75
|
+
return o;
|
|
76
|
+
}
|
|
77
|
+
}
|
package/src/StatusCodeError.js
CHANGED
|
@@ -39,15 +39,16 @@ export class StatusCodeError extends Error {
|
|
|
39
39
|
* Converts a Graph API error response to a status code error.
|
|
40
40
|
* @param {object} errorBody The parsed error response body
|
|
41
41
|
* @param {number} statusCode The status code of the error response
|
|
42
|
+
* @param {RateLimit} rateLimit rate limit or null
|
|
42
43
|
* @param {object} details The underlying error
|
|
43
44
|
* @returns {StatusCodeError} status code error
|
|
44
45
|
*/
|
|
45
|
-
static fromErrorResponse(errorBody, statusCode) {
|
|
46
|
+
static fromErrorResponse(errorBody, statusCode, rateLimit) {
|
|
46
47
|
if (errorBody.error && errorBody.error.message) {
|
|
47
48
|
// eslint-disable-next-line no-param-reassign
|
|
48
49
|
errorBody = errorBody.error;
|
|
49
50
|
}
|
|
50
|
-
return new StatusCodeError(errorBody.message, statusCode, errorBody);
|
|
51
|
+
return new StatusCodeError(errorBody.message, statusCode, errorBody, rateLimit);
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
/**
|
|
@@ -56,10 +57,12 @@ export class StatusCodeError extends Error {
|
|
|
56
57
|
* @param {string} msg Error message
|
|
57
58
|
* @param {number} statusCode Status code of the error response
|
|
58
59
|
* @param {object} details underlying error
|
|
60
|
+
* @param {RateLimit} rateLimit rate limit or null
|
|
59
61
|
*/
|
|
60
|
-
constructor(msg, statusCode, details) {
|
|
62
|
+
constructor(msg, statusCode, details, rateLimit) {
|
|
61
63
|
super(msg?.value ?? msg);
|
|
62
64
|
this.statusCode = statusCode;
|
|
63
65
|
this.details = details;
|
|
66
|
+
this.rateLimit = rateLimit;
|
|
64
67
|
}
|
|
65
68
|
}
|
|
@@ -50,7 +50,7 @@ export class NamedItemContainer {
|
|
|
50
50
|
});
|
|
51
51
|
} catch (e) {
|
|
52
52
|
if ((e.details && e.details.code === 'ItemAlreadyExists') && e.statusCode !== 409) {
|
|
53
|
-
throw new StatusCodeError(e.message, 409
|
|
53
|
+
throw new StatusCodeError(e.message, 409);
|
|
54
54
|
}
|
|
55
55
|
throw e;
|
|
56
56
|
}
|
|
@@ -64,7 +64,7 @@ export class NamedItemContainer {
|
|
|
64
64
|
});
|
|
65
65
|
} catch (e) {
|
|
66
66
|
if ((e.details && e.details.code === 'ItemNotFound') && e.statusCode !== 404) {
|
|
67
|
-
throw new StatusCodeError(e.message, 404
|
|
67
|
+
throw new StatusCodeError(e.message, 404);
|
|
68
68
|
}
|
|
69
69
|
throw e;
|
|
70
70
|
}
|