@clickup/rest-client 2.10.292

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 (137) hide show
  1. package/.eslintrc.base.js +412 -0
  2. package/.eslintrc.js +5 -0
  3. package/LICENSE +22 -0
  4. package/README.md +121 -0
  5. package/dist/RestClient.d.ts +154 -0
  6. package/dist/RestClient.d.ts.map +1 -0
  7. package/dist/RestClient.js +361 -0
  8. package/dist/RestClient.js.map +1 -0
  9. package/dist/RestOptions.d.ts +143 -0
  10. package/dist/RestOptions.d.ts.map +1 -0
  11. package/dist/RestOptions.js +63 -0
  12. package/dist/RestOptions.js.map +1 -0
  13. package/dist/RestRequest.d.ts +81 -0
  14. package/dist/RestRequest.d.ts.map +1 -0
  15. package/dist/RestRequest.js +367 -0
  16. package/dist/RestRequest.js.map +1 -0
  17. package/dist/RestResponse.d.ts +37 -0
  18. package/dist/RestResponse.d.ts.map +1 -0
  19. package/dist/RestResponse.js +56 -0
  20. package/dist/RestResponse.js.map +1 -0
  21. package/dist/RestStream.d.ts +29 -0
  22. package/dist/RestStream.d.ts.map +1 -0
  23. package/dist/RestStream.js +85 -0
  24. package/dist/RestStream.js.map +1 -0
  25. package/dist/errors/RestContentSizeOverLimitError.d.ts +4 -0
  26. package/dist/errors/RestContentSizeOverLimitError.d.ts.map +1 -0
  27. package/dist/errors/RestContentSizeOverLimitError.js +10 -0
  28. package/dist/errors/RestContentSizeOverLimitError.js.map +1 -0
  29. package/dist/errors/RestError.d.ts +4 -0
  30. package/dist/errors/RestError.d.ts.map +1 -0
  31. package/dist/errors/RestError.js +10 -0
  32. package/dist/errors/RestError.js.map +1 -0
  33. package/dist/errors/RestRateLimitError.d.ts +7 -0
  34. package/dist/errors/RestRateLimitError.d.ts.map +1 -0
  35. package/dist/errors/RestRateLimitError.js +14 -0
  36. package/dist/errors/RestRateLimitError.js.map +1 -0
  37. package/dist/errors/RestResponseError.d.ts +13 -0
  38. package/dist/errors/RestResponseError.d.ts.map +1 -0
  39. package/dist/errors/RestResponseError.js +32 -0
  40. package/dist/errors/RestResponseError.js.map +1 -0
  41. package/dist/errors/RestRetriableError.d.ts +7 -0
  42. package/dist/errors/RestRetriableError.d.ts.map +1 -0
  43. package/dist/errors/RestRetriableError.js +14 -0
  44. package/dist/errors/RestRetriableError.js.map +1 -0
  45. package/dist/errors/RestTimeoutError.d.ts +4 -0
  46. package/dist/errors/RestTimeoutError.d.ts.map +1 -0
  47. package/dist/errors/RestTimeoutError.js +10 -0
  48. package/dist/errors/RestTimeoutError.js.map +1 -0
  49. package/dist/errors/RestTokenInvalidError.d.ts +7 -0
  50. package/dist/errors/RestTokenInvalidError.d.ts.map +1 -0
  51. package/dist/errors/RestTokenInvalidError.js +14 -0
  52. package/dist/errors/RestTokenInvalidError.js.map +1 -0
  53. package/dist/helpers/depaginate.d.ts +10 -0
  54. package/dist/helpers/depaginate.d.ts.map +1 -0
  55. package/dist/helpers/depaginate.js +32 -0
  56. package/dist/helpers/depaginate.js.map +1 -0
  57. package/dist/index.d.ts +20 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +42 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/internal/RestFetchReader.d.ts +72 -0
  62. package/dist/internal/RestFetchReader.d.ts.map +1 -0
  63. package/dist/internal/RestFetchReader.js +192 -0
  64. package/dist/internal/RestFetchReader.js.map +1 -0
  65. package/dist/internal/RestRangeUploader.d.ts +24 -0
  66. package/dist/internal/RestRangeUploader.d.ts.map +1 -0
  67. package/dist/internal/RestRangeUploader.js +54 -0
  68. package/dist/internal/RestRangeUploader.js.map +1 -0
  69. package/dist/internal/calcRetryDelay.d.ts +8 -0
  70. package/dist/internal/calcRetryDelay.d.ts.map +1 -0
  71. package/dist/internal/calcRetryDelay.js +44 -0
  72. package/dist/internal/calcRetryDelay.js.map +1 -0
  73. package/dist/internal/inspectPossibleJSON.d.ts +6 -0
  74. package/dist/internal/inspectPossibleJSON.d.ts.map +1 -0
  75. package/dist/internal/inspectPossibleJSON.js +53 -0
  76. package/dist/internal/inspectPossibleJSON.js.map +1 -0
  77. package/dist/internal/prependNewlineIfMultiline.d.ts +2 -0
  78. package/dist/internal/prependNewlineIfMultiline.d.ts.map +1 -0
  79. package/dist/internal/prependNewlineIfMultiline.js +7 -0
  80. package/dist/internal/prependNewlineIfMultiline.js.map +1 -0
  81. package/dist/internal/substituteParams.d.ts +7 -0
  82. package/dist/internal/substituteParams.d.ts.map +1 -0
  83. package/dist/internal/substituteParams.js +24 -0
  84. package/dist/internal/substituteParams.js.map +1 -0
  85. package/dist/internal/throwIfErrorResponse.d.ts +11 -0
  86. package/dist/internal/throwIfErrorResponse.d.ts.map +1 -0
  87. package/dist/internal/throwIfErrorResponse.js +60 -0
  88. package/dist/internal/throwIfErrorResponse.js.map +1 -0
  89. package/dist/internal/toFloatMs.d.ts +2 -0
  90. package/dist/internal/toFloatMs.d.ts.map +1 -0
  91. package/dist/internal/toFloatMs.js +7 -0
  92. package/dist/internal/toFloatMs.js.map +1 -0
  93. package/dist/middlewares/paceRequests.d.ts +9 -0
  94. package/dist/middlewares/paceRequests.d.ts.map +1 -0
  95. package/dist/middlewares/paceRequests.js +36 -0
  96. package/dist/middlewares/paceRequests.js.map +1 -0
  97. package/dist/pacers/Pacer.d.ts +21 -0
  98. package/dist/pacers/Pacer.d.ts.map +1 -0
  99. package/dist/pacers/Pacer.js +3 -0
  100. package/dist/pacers/Pacer.js.map +1 -0
  101. package/dist/pacers/PacerComposite.d.ts +14 -0
  102. package/dist/pacers/PacerComposite.d.ts.map +1 -0
  103. package/dist/pacers/PacerComposite.js +32 -0
  104. package/dist/pacers/PacerComposite.js.map +1 -0
  105. package/dist/pacers/PacerQPS.d.ts +53 -0
  106. package/dist/pacers/PacerQPS.d.ts.map +1 -0
  107. package/dist/pacers/PacerQPS.js +105 -0
  108. package/dist/pacers/PacerQPS.js.map +1 -0
  109. package/dist/tsconfig.tsbuildinfo +1 -0
  110. package/docs/.nojekyll +1 -0
  111. package/docs/README.md +123 -0
  112. package/docs/classes/PacerComposite.md +62 -0
  113. package/docs/classes/PacerQPS.md +75 -0
  114. package/docs/classes/RestClient.md +424 -0
  115. package/docs/classes/RestContentSizeOverLimitError.md +128 -0
  116. package/docs/classes/RestError.md +31 -0
  117. package/docs/classes/RestRateLimitError.md +139 -0
  118. package/docs/classes/RestRequest.md +257 -0
  119. package/docs/classes/RestResponse.md +110 -0
  120. package/docs/classes/RestResponseError.md +110 -0
  121. package/docs/classes/RestRetriableError.md +139 -0
  122. package/docs/classes/RestStream.md +92 -0
  123. package/docs/classes/RestTimeoutError.md +128 -0
  124. package/docs/classes/RestTokenInvalidError.md +138 -0
  125. package/docs/interfaces/Middleware.md +27 -0
  126. package/docs/interfaces/Pacer.md +40 -0
  127. package/docs/interfaces/PacerDelay.md +25 -0
  128. package/docs/interfaces/PacerQPSBackend.md +44 -0
  129. package/docs/interfaces/PacerQPSOptions.md +40 -0
  130. package/docs/interfaces/RestLogEvent.md +95 -0
  131. package/docs/interfaces/RestOptions.md +351 -0
  132. package/docs/interfaces/TokenGetter.md +34 -0
  133. package/docs/modules.md +87 -0
  134. package/jest.config.js +8 -0
  135. package/package.json +42 -0
  136. package/tsconfig.json +39 -0
  137. package/typedoc.json +17 -0
@@ -0,0 +1,154 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import type RestOptions from "./RestOptions";
4
+ import RestRequest from "./RestRequest";
5
+ import type RestResponse from "./RestResponse";
6
+ /**
7
+ * A callback which returns access token, possibly after refreshing it, and also
8
+ * possibly before a retry on "invalid token" condition. I.e. it can be called
9
+ * once or twice (the 2nd time after the previous request error, and that error
10
+ * will be passed as a parameter).
11
+ */
12
+ export interface TokenGetter<TData = string> {
13
+ (prevError: Error | null): Promise<TData>;
14
+ }
15
+ /**
16
+ * RestClient is an immutable object which allows to:
17
+ * 1. Send remote requests in different formats, in a caller-friendly manner.
18
+ * 2. Create a new RestClient objects deriving the current set of options and
19
+ * adding new ones.
20
+ */
21
+ export default class RestClient {
22
+ private readonly _options;
23
+ constructor(options?: Partial<RestOptions>);
24
+ /**
25
+ * Returns a new RestClient with some options updated with the passed ones.
26
+ */
27
+ withOptions(options: Partial<RestOptions>): RestClient;
28
+ /**
29
+ * Returns a new RestClient with added middleware.
30
+ */
31
+ withMiddleware(middleware: RestOptions["middlewares"][0], method?: "unshift" | "push"): RestClient;
32
+ /**
33
+ * Returns a new RestClient with the base URL which will be prepended to all
34
+ * relative paths in get(), writeForm() etc. Allows to defer resolution of
35
+ * this base URL to the very late per-request moment. The complicated piece
36
+ * here is that, if we want base URL to be resolved asynchronously, we often
37
+ * times want to reuse the same RestClient object (to e.g. fetch some part of
38
+ * the base URL using already authenticated client). And a re-enterable call
39
+ * appears here which we must protect against in the code below.
40
+ */
41
+ withBase(base: string | (() => Promise<string>)): RestClient;
42
+ /**
43
+ * Returns a new RestClient with a custom header.
44
+ */
45
+ withHeader(name: string, value: string | (() => Promise<string>)): RestClient;
46
+ /**
47
+ * Returns a new RestClient with a bearer token authentication workflow.
48
+ * - RestClient supports interception of options.isTokenInvalid() signal and
49
+ * conversion it into RestTokenInvalidError exception.
50
+ * - If a token() is a lambda with 1 argument, it may be called the 2nd time
51
+ * when we get an isTokenInvalid() signal. In this case, the request is
52
+ * retried.
53
+ * - If token() is a lambda with 0 arguments, that means it doesn't want to
54
+ * watch for the isTokenInvalid() signal, so there is no sense in retrying
55
+ * the request either.
56
+ *
57
+ * From the first sight, it looks like options.isTokenInvalid() signal is
58
+ * coupled to setBearer() auth method only. But it's not true:
59
+ * isTokenInvalid() makes sense for ALL authentication methods actually (even
60
+ * for basic auth), and setBearer() is just one of "clients" which implements
61
+ * refreshing/retries on top of isTokenInvalid().
62
+ *
63
+ * Passing the token as lambda allows the caller to implement some complex
64
+ * logic, e.g.:
65
+ * - oauth2 tokens refreshing
66
+ * - marking the token as "revoked" in the database in case the refresh fails
67
+ * - marking the token as "revoked" after a failed request if refresh-token is
68
+ * not supported
69
+ */
70
+ withBearer(token: TokenGetter, bearerPrefix?: string): RestClient;
71
+ /**
72
+ * Returns a new RestClient with oauth1 authentication workflow.
73
+ * - In case we get an options.isTokenInvalid() signal, the token() lambda is
74
+ * called the 2nd time with the error object, then the request is retries.
75
+ * This gives the lambda a chance to recover or update something in the
76
+ * database.
77
+ *
78
+ * We use a separate and small oauth-1.0a node library here, because the more
79
+ * popular one (https://www.npmjs.com/package/oauth) doesn't support signing
80
+ * of arbitrary requests, it can only send its own requests.
81
+ */
82
+ withOAuth1(consumer: {
83
+ consumerKey: string;
84
+ consumerSecret: string;
85
+ }, token: TokenGetter<{
86
+ token: string;
87
+ tokenSecret: string;
88
+ }>): RestClient;
89
+ /**
90
+ * Returns a new RestClient with basic authorization workflow.
91
+ */
92
+ withBasic(token: TokenGetter<{
93
+ name: string;
94
+ password: string;
95
+ }>): RestClient;
96
+ /**
97
+ * Sends a plain GET request without body.
98
+ *
99
+ * NOTE, all args will be passed through `encodeURIComponent`.
100
+ */
101
+ get(path: string, args?: Partial<Record<string, string | number | string[]>>, accept?: string): RestRequest<any>;
102
+ /**
103
+ * Writes some raw string, buffer or a stream.
104
+ */
105
+ writeRaw(path: string, body: string | Buffer | NodeJS.ReadableStream, contentType: string, method?: "POST" | "PUT" | "PATCH", accept?: string): RestRequest<any>;
106
+ /**
107
+ * A shortcut method to write JSON body.
108
+ */
109
+ writeJson(path: string, body: any, method?: "POST" | "PUT" | "PATCH" | "DELETE", accept?: string): RestRequest<any>;
110
+ /**
111
+ * A shortcut method to write "application/x-www-form-urlencoded" data.
112
+ */
113
+ writeForm(path: string, body: Partial<Record<string, string>> | string, method?: "POST" | "PUT" | "PATCH", accept?: string): RestRequest<any>;
114
+ /**
115
+ * A shortcut method to write DELETE request.
116
+ */
117
+ writeDelete(path: string, args?: Partial<Record<string, string>>, accept?: string): RestRequest<any>;
118
+ /**
119
+ * Returns a RestRequest prepared for sending GraphQL operation.
120
+ * - Expects the response to contain no errors; throws otherwise.
121
+ * - In case of success, returns just the content of `data` field (this is
122
+ * different with writeGraphQLNullable() which returns `data` as a separate
123
+ * fields along with `error` and `errors`).
124
+ */
125
+ writeGraphQLX(query: string, variables?: any): RestRequest<any>;
126
+ /**
127
+ * Same as writeGraphQLX(), but doesn't throw if GraphQL response contains
128
+ * non-empty `error` or `errors` fields and instead returns the full response.
129
+ * I.e. allows the caller to process these errors.
130
+ */
131
+ writeGraphQLNullable(query: string, variables?: any): RestRequest<{
132
+ data?: any;
133
+ error?: any;
134
+ errors?: any[] | undefined;
135
+ } | null | undefined>;
136
+ /**
137
+ * Performs a series of Content-Range requests with content from a sequence of
138
+ * Buffers.
139
+ */
140
+ rangeUpload(path: string, mimeType: string, stream: AsyncIterable<Buffer>, method: "POST" | "PUT" | undefined, chunkSize: number): Promise<string | null>;
141
+ private _writeGraphQLImpl;
142
+ /**
143
+ * Sends a plain request (with no body, like GET or DELETE).
144
+ */
145
+ private _noBodyRequest;
146
+ }
147
+ /**
148
+ * @ignore
149
+ * Calls token(null), then runs body() passing the result there. If we get a
150
+ * RestTokenInvalidError exception, call token() with this error as a parameter
151
+ * and then passes the response to body() again (kinda retry with a new token).
152
+ */
153
+ export declare function tokenRetryStrategy<TData>(token: TokenGetter<TData>, body: (tokenData: TData) => Promise<RestResponse>): Promise<RestResponse>;
154
+ //# sourceMappingURL=RestClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RestClient.d.ts","sourceRoot":"","sources":["../src/RestClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,361 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.tokenRetryStrategy = void 0;
7
+ const crypto_1 = __importDefault(require("crypto"));
8
+ const isUndefined_1 = __importDefault(require("lodash/isUndefined"));
9
+ const omitBy_1 = __importDefault(require("lodash/omitBy"));
10
+ const node_fetch_1 = require("node-fetch");
11
+ const oauth_1_0a_1 = __importDefault(require("oauth-1.0a"));
12
+ const RestTokenInvalidError_1 = __importDefault(require("./errors/RestTokenInvalidError"));
13
+ const RestRangeUploader_1 = __importDefault(require("./internal/RestRangeUploader"));
14
+ const substituteParams_1 = __importDefault(require("./internal/substituteParams"));
15
+ const RestOptions_1 = require("./RestOptions");
16
+ const RestRequest_1 = __importDefault(require("./RestRequest"));
17
+ /**
18
+ * RestClient is an immutable object which allows to:
19
+ * 1. Send remote requests in different formats, in a caller-friendly manner.
20
+ * 2. Create a new RestClient objects deriving the current set of options and
21
+ * adding new ones.
22
+ */
23
+ class RestClient {
24
+ constructor(options = {}) {
25
+ this._options = {
26
+ ...RestOptions_1.DEFAULT_OPTIONS,
27
+ ...(0, omitBy_1.default)(options, isUndefined_1.default),
28
+ ...(options.keepAlive ? { keepAlive: { ...options.keepAlive } } : {}),
29
+ ...(options.middlewares ? { middlewares: [...options.middlewares] } : {}),
30
+ };
31
+ }
32
+ /**
33
+ * Returns a new RestClient with some options updated with the passed ones.
34
+ */
35
+ withOptions(options) {
36
+ return new RestClient({
37
+ ...this._options,
38
+ ...(0, omitBy_1.default)(options, isUndefined_1.default),
39
+ });
40
+ }
41
+ /**
42
+ * Returns a new RestClient with added middleware.
43
+ */
44
+ withMiddleware(middleware, method = "push") {
45
+ const clone = new RestClient(this._options);
46
+ clone._options.middlewares[method](middleware);
47
+ return clone;
48
+ }
49
+ /**
50
+ * Returns a new RestClient with the base URL which will be prepended to all
51
+ * relative paths in get(), writeForm() etc. Allows to defer resolution of
52
+ * this base URL to the very late per-request moment. The complicated piece
53
+ * here is that, if we want base URL to be resolved asynchronously, we often
54
+ * times want to reuse the same RestClient object (to e.g. fetch some part of
55
+ * the base URL using already authenticated client). And a re-enterable call
56
+ * appears here which we must protect against in the code below.
57
+ */
58
+ withBase(base) {
59
+ return this.withMiddleware(async function withBaseMiddleware(req, next) {
60
+ // If URL is already absolute, we don't even need to call base() lambda
61
+ // to resolve it. Return early.
62
+ if (req.url.match(/^\w+:\/\//)) {
63
+ return next(req);
64
+ }
65
+ // Re-enterable call detected, e.g. base() lambda issued a request
66
+ // through the same RestClient. We must just skip setting the base.
67
+ if (base === "") {
68
+ return next(req);
69
+ }
70
+ if (typeof base !== "string") {
71
+ const baseGetter = base;
72
+ base = ""; // disable re-enterable calls
73
+ try {
74
+ base = await baseGetter();
75
+ }
76
+ catch (e) {
77
+ base = baseGetter;
78
+ throw e;
79
+ }
80
+ }
81
+ req.url = new URL(req.url, base).toString();
82
+ return next(req);
83
+ });
84
+ }
85
+ /**
86
+ * Returns a new RestClient with a custom header.
87
+ */
88
+ withHeader(name, value) {
89
+ return this.withMiddleware(async function withHeaderMiddleware(req, next) {
90
+ req.headers.set(name, typeof value === "string" ? value : await value());
91
+ return next(req);
92
+ });
93
+ }
94
+ /**
95
+ * Returns a new RestClient with a bearer token authentication workflow.
96
+ * - RestClient supports interception of options.isTokenInvalid() signal and
97
+ * conversion it into RestTokenInvalidError exception.
98
+ * - If a token() is a lambda with 1 argument, it may be called the 2nd time
99
+ * when we get an isTokenInvalid() signal. In this case, the request is
100
+ * retried.
101
+ * - If token() is a lambda with 0 arguments, that means it doesn't want to
102
+ * watch for the isTokenInvalid() signal, so there is no sense in retrying
103
+ * the request either.
104
+ *
105
+ * From the first sight, it looks like options.isTokenInvalid() signal is
106
+ * coupled to setBearer() auth method only. But it's not true:
107
+ * isTokenInvalid() makes sense for ALL authentication methods actually (even
108
+ * for basic auth), and setBearer() is just one of "clients" which implements
109
+ * refreshing/retries on top of isTokenInvalid().
110
+ *
111
+ * Passing the token as lambda allows the caller to implement some complex
112
+ * logic, e.g.:
113
+ * - oauth2 tokens refreshing
114
+ * - marking the token as "revoked" in the database in case the refresh fails
115
+ * - marking the token as "revoked" after a failed request if refresh-token is
116
+ * not supported
117
+ */
118
+ withBearer(token, bearerPrefix = "Bearer ") {
119
+ return this.withMiddleware(async function withBearerMiddleware(req, next) {
120
+ return tokenRetryStrategy(token, async (tokenData) => {
121
+ req.headers.set("Authorization", bearerPrefix + tokenData);
122
+ return next(req);
123
+ });
124
+ });
125
+ }
126
+ /**
127
+ * Returns a new RestClient with oauth1 authentication workflow.
128
+ * - In case we get an options.isTokenInvalid() signal, the token() lambda is
129
+ * called the 2nd time with the error object, then the request is retries.
130
+ * This gives the lambda a chance to recover or update something in the
131
+ * database.
132
+ *
133
+ * We use a separate and small oauth-1.0a node library here, because the more
134
+ * popular one (https://www.npmjs.com/package/oauth) doesn't support signing
135
+ * of arbitrary requests, it can only send its own requests.
136
+ */
137
+ withOAuth1(consumer, token) {
138
+ const oauth = new oauth_1_0a_1.default({
139
+ consumer: { key: consumer.consumerKey, secret: consumer.consumerSecret },
140
+ signature_method: "HMAC-SHA1",
141
+ hash_function: (baseString, key) => crypto_1.default.createHmac("sha1", key).update(baseString).digest("base64"),
142
+ });
143
+ return this.withMiddleware(async function withOAuth1Middleware(req, next) {
144
+ return tokenRetryStrategy(token, async (tokenData) => {
145
+ const requestData = {
146
+ url: req.url,
147
+ method: req.method,
148
+ data: req.body,
149
+ };
150
+ const addHeaders = oauth.toHeader(oauth.authorize(requestData, {
151
+ key: tokenData.token,
152
+ secret: tokenData.tokenSecret,
153
+ }));
154
+ for (const [name, value] of Object.entries(addHeaders)) {
155
+ req.headers.set(name, value);
156
+ }
157
+ return next(req);
158
+ });
159
+ });
160
+ }
161
+ /**
162
+ * Returns a new RestClient with basic authorization workflow.
163
+ */
164
+ withBasic(token) {
165
+ return this.withMiddleware(async function withBasicMiddleware(req, next) {
166
+ return tokenRetryStrategy(token, async ({ name, password }) => {
167
+ const unencodedHeader = name + ":" + password;
168
+ req.headers.set("Authorization", "Basic " + Buffer.from(unencodedHeader).toString("base64"));
169
+ return next(req);
170
+ });
171
+ });
172
+ }
173
+ /**
174
+ * Sends a plain GET request without body.
175
+ *
176
+ * NOTE, all args will be passed through `encodeURIComponent`.
177
+ */
178
+ get(path, args = {}, accept = "application/json") {
179
+ return this._noBodyRequest(path, args, "GET", accept);
180
+ }
181
+ /**
182
+ * Writes some raw string, buffer or a stream.
183
+ */
184
+ writeRaw(path, body, contentType, method = "POST", accept) {
185
+ const origShape = simpleShape(path);
186
+ return new RestRequest_1.default(this._options, method, path, new node_fetch_1.Headers({
187
+ Accept: accept || contentType,
188
+ "Content-Type": contentType,
189
+ }), body, origShape);
190
+ }
191
+ /**
192
+ * A shortcut method to write JSON body.
193
+ */
194
+ writeJson(path, body, method = "POST", accept = "application/json") {
195
+ const origShape = simpleShape(path, body);
196
+ [path, body] = (0, substituteParams_1.default)(path, body);
197
+ return new RestRequest_1.default(this._options, method, path, new node_fetch_1.Headers({
198
+ Accept: accept || "application/json",
199
+ "Content-Type": "application/json",
200
+ }), JSON.stringify(body), origShape);
201
+ }
202
+ /**
203
+ * A shortcut method to write "application/x-www-form-urlencoded" data.
204
+ */
205
+ writeForm(path, body, method = "POST", accept = "application/json") {
206
+ const origShape = simpleShape(path, body);
207
+ [path, body] = (0, substituteParams_1.default)(path, body);
208
+ return new RestRequest_1.default(this._options, method, path, new node_fetch_1.Headers({
209
+ Accept: accept,
210
+ "Content-Type": "application/x-www-form-urlencoded",
211
+ }), typeof body === "string"
212
+ ? body
213
+ : new URLSearchParams((0, omitBy_1.default)(body, isUndefined_1.default)).toString(), origShape);
214
+ }
215
+ /**
216
+ * A shortcut method to write DELETE request.
217
+ */
218
+ writeDelete(path, args = {}, accept = "application/json") {
219
+ return this._noBodyRequest(path, args, "DELETE", accept);
220
+ }
221
+ /**
222
+ * Returns a RestRequest prepared for sending GraphQL operation.
223
+ * - Expects the response to contain no errors; throws otherwise.
224
+ * - In case of success, returns just the content of `data` field (this is
225
+ * different with writeGraphQLNullable() which returns `data` as a separate
226
+ * fields along with `error` and `errors`).
227
+ */
228
+ writeGraphQLX(query, variables = {}) {
229
+ const oldIsSuccessResponse = this._options.isSuccessResponse;
230
+ return this.withOptions({
231
+ isSuccessResponse: (res) => {
232
+ const oldIsSuccess = oldIsSuccessResponse === null || oldIsSuccessResponse === void 0 ? void 0 : oldIsSuccessResponse(res);
233
+ const json = res.json;
234
+ return oldIsSuccess === "THROW" ||
235
+ !(json === null || json === void 0 ? void 0 : json.data) ||
236
+ json.error ||
237
+ (json.errors instanceof Array && json.errors.length > 0)
238
+ ? "THROW"
239
+ : "BEST_EFFORT";
240
+ },
241
+ })
242
+ .withMiddleware(async function writeGraphQLXMiddleware(req, next) {
243
+ const res = await next(req);
244
+ const json = res.json;
245
+ // Substitute the response json object with just its data field.
246
+ Object.defineProperty(res, "json", { value: json.data });
247
+ return res;
248
+ })
249
+ ._writeGraphQLImpl(query, variables);
250
+ }
251
+ /**
252
+ * Same as writeGraphQLX(), but doesn't throw if GraphQL response contains
253
+ * non-empty `error` or `errors` fields and instead returns the full response.
254
+ * I.e. allows the caller to process these errors.
255
+ */
256
+ writeGraphQLNullable(query, variables = {}) {
257
+ return this._writeGraphQLImpl(query, variables);
258
+ }
259
+ /**
260
+ * Performs a series of Content-Range requests with content from a sequence of
261
+ * Buffers.
262
+ */
263
+ async rangeUpload(path, mimeType, stream, method = "POST", chunkSize) {
264
+ return new RestRangeUploader_1.default(this, chunkSize, method, path, mimeType).upload(stream);
265
+ }
266
+ _writeGraphQLImpl(query, variables = {}) {
267
+ const origShape = query;
268
+ // To beautify the query, we remove leading spaces (extracted from the last line).
269
+ query = query.trimEnd();
270
+ if (query.match(/\n([ \t]+)[^\n]+$/)) {
271
+ const prefix = RegExp.$1;
272
+ query = query.replace(new RegExp("^" + prefix, "gm"), "").trimEnd();
273
+ }
274
+ return new RestRequest_1.default(this._options, "POST", "", new node_fetch_1.Headers({ "Content-Type": "application/json" }), JSON.stringify({ variables, query }), // variables first - for truncation in logs,
275
+ origShape);
276
+ }
277
+ /**
278
+ * Sends a plain request (with no body, like GET or DELETE).
279
+ */
280
+ _noBodyRequest(path, args = {}, method, accept = "application/json") {
281
+ const origShape = simpleShape(path, args);
282
+ [path, args] = (0, substituteParams_1.default)(path, args);
283
+ const searchParams = new URLSearchParams();
284
+ for (const [k, v] of Object.entries(args)) {
285
+ if (Array.isArray(v)) {
286
+ for (const element of v) {
287
+ searchParams.append(k, element.toString());
288
+ }
289
+ }
290
+ else if (v !== undefined) {
291
+ searchParams.append(k, v.toString());
292
+ }
293
+ }
294
+ const suffix = searchParams.toString();
295
+ if (suffix !== "") {
296
+ path += (path.includes("?") ? "&" : "?") + suffix;
297
+ }
298
+ return new RestRequest_1.default(this._options, method, path, new node_fetch_1.Headers({ Accept: accept }), "", origShape);
299
+ }
300
+ }
301
+ exports.default = RestClient;
302
+ /**
303
+ * @ignore
304
+ * Calls token(null), then runs body() passing the result there. If we get a
305
+ * RestTokenInvalidError exception, call token() with this error as a parameter
306
+ * and then passes the response to body() again (kinda retry with a new token).
307
+ */
308
+ async function tokenRetryStrategy(token, body) {
309
+ let tokenData = await token(null);
310
+ try {
311
+ return await body(tokenData);
312
+ }
313
+ catch (e) {
314
+ const supportsRetry = token.length > 0; // args count
315
+ if (e instanceof RestTokenInvalidError_1.default && supportsRetry) {
316
+ tokenData = await token(e);
317
+ try {
318
+ return await body(tokenData);
319
+ }
320
+ catch (e) {
321
+ if (e instanceof RestTokenInvalidError_1.default) {
322
+ e.message = `(still failed, even with updated token) ${e.message}`;
323
+ }
324
+ throw e;
325
+ }
326
+ }
327
+ throw e;
328
+ }
329
+ }
330
+ exports.tokenRetryStrategy = tokenRetryStrategy;
331
+ /**
332
+ * Returns a simple "shape" of a request useful for e.g. grouping by in logger
333
+ * to figure out, which requests are more frequent.
334
+ * - reflects args names and not values
335
+ * - wipes the domain
336
+ * - removes query string parameter values
337
+ */
338
+ function simpleShape(path, args) {
339
+ path = path.replace(/^\w+:\/\/[^/]+/, "").replace(/=[^&]+/g, "=");
340
+ const argsInPath = [];
341
+ const regex = /:([a-z0-9_]+)/gi;
342
+ while (true) {
343
+ const match = regex.exec(path);
344
+ if (!match) {
345
+ break;
346
+ }
347
+ else {
348
+ argsInPath.push(match[1]);
349
+ }
350
+ }
351
+ const keys = args && typeof args === "object"
352
+ ? Object.keys(args)
353
+ // Filter out args that are already mentioned in the path, e.g.
354
+ // /pages/:pageID/blocks.
355
+ .filter((arg) => !argsInPath.includes(arg))
356
+ .sort()
357
+ .join(",")
358
+ : "";
359
+ return path + (keys !== "" ? `:${keys}` : "");
360
+ }
361
+ //# sourceMappingURL=RestClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RestClient.js","sourceRoot":"","sources":["../src/RestClient.ts"],"names":[],"mappings":"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"}