@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,412 @@
1
+ "use strict";
2
+ module.exports = (projectRoot) => ({
3
+ root: true, // fix possible "Plugin %s was conflicted between %s.json and %s.json" errors
4
+ env: {
5
+ jest: true,
6
+ browser: true,
7
+ es6: true,
8
+ node: true,
9
+ },
10
+ extends: [
11
+ "eslint:recommended",
12
+ "plugin:react/recommended",
13
+ "plugin:@typescript-eslint/eslint-recommended",
14
+ "plugin:import/recommended",
15
+ ],
16
+ globals: {
17
+ Atomics: "readonly",
18
+ SharedArrayBuffer: "readonly",
19
+ },
20
+ parser: "@typescript-eslint/parser",
21
+ parserOptions: {
22
+ ecmaFeatures: {
23
+ jsx: true,
24
+ },
25
+ ecmaVersion: 2018,
26
+ sourceType: "module",
27
+ tsconfigRootDir: projectRoot,
28
+ project: "tsconfig.json",
29
+ warnOnUnsupportedTypeScriptVersion: false,
30
+ },
31
+ plugins: [
32
+ "@typescript-eslint",
33
+ "import",
34
+ "lodash",
35
+ "node",
36
+ "react-hooks",
37
+ "react",
38
+ "typescript-enum",
39
+ "typescript-sort-keys",
40
+ "unused-imports",
41
+ ],
42
+ settings: {
43
+ react: {
44
+ version: "detect",
45
+ },
46
+ "import/parsers": {
47
+ "@typescript-eslint/parser": [".ts", ".tsx"],
48
+ },
49
+ "import/resolver": {
50
+ typescript: {
51
+ project: projectRoot,
52
+ },
53
+ },
54
+ },
55
+ ignorePatterns: [
56
+ "node_modules",
57
+ "webpack.config.ts",
58
+ "**/bin/**",
59
+ "*.d.ts",
60
+ "**/jest.config.js",
61
+ ],
62
+ rules: {
63
+ // TODO: slowly enable no-extraneous-dependencies rule below. For now, it's
64
+ // enforced only for some packages.
65
+ //
66
+ // In an ideal world, the root package.json should have 0 dependencies, and
67
+ // all packages/* should define their own dependencies by themselves,
68
+ // independently and locally. The rule below is exactly for that: it ensures
69
+ // that all package's dependencies are explicitly mentioned in its
70
+ // package.json, and no dependencies are borrowed implicitly from the root
71
+ // node_modules.
72
+ //
73
+ // In real life though, enforcing packages independency is dangerous: we may
74
+ // e.g. start accidentally bundle 2 React or 2 Redux versions if we forget
75
+ // to sync their versions in different monorepo packages' package.json
76
+ // files. (There must be some other lint rule for this hopefully.)
77
+ //
78
+ // In all cases, we should treat node_modules folders content as something
79
+ // secondary and transient. (It's true even now with the new "yarn
80
+ // Plug-n-Play" technology which we don't use yet.) The source of truth is
81
+ // always package.json (enforced by lint) and yarn.lock (defines the exact
82
+ // contents of all node_modules folders, bit by bit). In this schema, it
83
+ // doesn't matter at all, does yarn use hoisting or not.
84
+ //
85
+ // "import/no-extraneous-dependencies": "error";
86
+
87
+ "node/prefer-global/process": "error",
88
+ "node/prefer-global/console": "error",
89
+ "node/prefer-global/buffer": "error",
90
+ "node/prefer-global/url-search-params": "error",
91
+ "node/prefer-global/url": "error",
92
+
93
+ "require-atomic-updates": "off",
94
+ "no-prototype-builtins": "off",
95
+ "react/prop-types": "off",
96
+ "react/no-unescaped-entities": "off",
97
+ "react-hooks/rules-of-hooks": "error",
98
+ "react-hooks/exhaustive-deps": "warn",
99
+ "@typescript-eslint/no-misused-promises": "error",
100
+ "@typescript-eslint/promise-function-async": "error",
101
+ "arrow-body-style": ["error", "as-needed"],
102
+ "@typescript-eslint/await-thenable": "error",
103
+ "@typescript-eslint/no-floating-promises": ["error", { ignoreVoid: false }],
104
+ "@typescript-eslint/unbound-method": ["error", { ignoreStatic: true }],
105
+ "@typescript-eslint/return-await": ["error"],
106
+ "@typescript-eslint/array-type": ["error", { default: "array-simple" }],
107
+ "@typescript-eslint/ban-ts-comment": ["error"],
108
+ "@typescript-eslint/no-useless-constructor": ["error"],
109
+ "@typescript-eslint/prefer-optional-chain": ["error"],
110
+ "@typescript-eslint/consistent-type-imports": ["error"],
111
+ eqeqeq: ["error"],
112
+ "object-shorthand": ["error", "always"],
113
+ "@typescript-eslint/unbound-method": ["error"],
114
+ "typescript-enum/no-const-enum": ["error"], // not supported in SWC
115
+
116
+ "@typescript-eslint/naming-convention": [
117
+ "error",
118
+ {
119
+ selector: "variable",
120
+ format: ["camelCase", "PascalCase", "UPPER_CASE"],
121
+ leadingUnderscore: "allow",
122
+ trailingUnderscore: "allow",
123
+ filter: {
124
+ regex: "^__webpack",
125
+ match: false,
126
+ },
127
+ },
128
+ ],
129
+
130
+ // Disable in favour of @typescript-eslint/no-unused-vars.
131
+ "no-unused-vars": "off",
132
+ "@typescript-eslint/no-unused-vars": [
133
+ "error",
134
+ {
135
+ args: "all",
136
+ argsIgnorePattern: "^_",
137
+ varsIgnorePattern: "^_",
138
+ ignoreRestSiblings: true,
139
+ },
140
+ ],
141
+ "@typescript-eslint/member-ordering": [
142
+ "error",
143
+ {
144
+ //
145
+ // ATTENTION: the rules here are not simple, mainly because of this:
146
+ // https://github.com/typescript-eslint/typescript-eslint/issues/6133
147
+ //
148
+ // Besides that, we also wand contradictory things, like:
149
+ //
150
+ // 1. Having constructor close to fields definition (because people
151
+ // often define fields in the constructor arguments), although it
152
+ // logically should've been below static methods.
153
+ // 2. Having all abstract things in the class grouped, irregardless on
154
+ // their public/protected/private modifiers.
155
+ //
156
+ default: [
157
+ "signature",
158
+ "call-signature",
159
+
160
+ // Typically, class constants (that's why they're on top).
161
+ "public-static-field",
162
+ "public-static-get",
163
+ "public-static-set",
164
+ "protected-static-field",
165
+ "protected-static-get",
166
+ "protected-static-set",
167
+
168
+ // All concrete fields. What's interesting is that the order we
169
+ // emotionally want here for properties is private-protected-public,
170
+ // which is the opposite to the order of methods (which is
171
+ // public-protected-private). This is likely because the methods are
172
+ // bulky, and properties are lean.
173
+ "private-static-field",
174
+ "private-instance-field",
175
+ "public-instance-field",
176
+ "public-abstract-field",
177
+ "public-abstract-get",
178
+ "public-abstract-set",
179
+
180
+ // Protected fields and methods are grouped, because eslint currently
181
+ // doesn't distinguish fields assigned with a lambda FROM methods, and
182
+ // we often times expose abstract protected overridable lambdas:
183
+ // https://github.com/typescript-eslint/typescript-eslint/issues/6133
184
+ "protected-abstract-field",
185
+ "protected-abstract-get",
186
+ "protected-abstract-set",
187
+ "protected-abstract-method",
188
+ "public-abstract-method", // the only exception; it's to group all abstract things too
189
+ "protected-instance-field",
190
+ "protected-constructor",
191
+ "protected-static-method",
192
+ "protected-instance-get",
193
+ "protected-instance-set",
194
+ "protected-instance-method",
195
+
196
+ // Public constructor, instance methods, static methods.
197
+ "public-constructor", // often defines more public/protected/private properties, so should be close to fields
198
+ "public-static-method",
199
+ "public-instance-get",
200
+ "public-instance-set",
201
+ "public-instance-method",
202
+
203
+ // Private constructor, instance methods, static methods.
204
+ "private-constructor",
205
+ "private-static-method",
206
+ "private-instance-get",
207
+ "private-instance-set",
208
+ "private-instance-method",
209
+ "private-static-get",
210
+ "private-static-set",
211
+ ],
212
+ },
213
+ ],
214
+
215
+ "no-constant-condition": ["error", { checkLoops: false }],
216
+ "no-buffer-constructor": ["error"],
217
+ "no-console": ["error"],
218
+ curly: ["error", "all"],
219
+ "no-case-declarations": "off",
220
+
221
+ "padding-line-between-statements": "off",
222
+ "@typescript-eslint/padding-line-between-statements": [
223
+ "warn",
224
+ // Force empty lines.
225
+ {
226
+ blankLine: "always",
227
+ prev: ["block", "block-like", "function", "class", "interface", "type"],
228
+ next: "*",
229
+ },
230
+ {
231
+ blankLine: "always",
232
+ prev: "import",
233
+ next: [
234
+ "const",
235
+ "if",
236
+ "let",
237
+ "var",
238
+ "export",
239
+ "function",
240
+ "class",
241
+ "interface",
242
+ "type",
243
+ ],
244
+ },
245
+ {
246
+ blankLine: "always",
247
+ prev: "*",
248
+ next: ["function", "class", "interface", "type"],
249
+ },
250
+ // Allow one-liner functions without extra spacing (hacky):
251
+ { blankLine: "any", prev: "singleline-const", next: "*" },
252
+ { blankLine: "any", prev: "singleline-var", next: "*" },
253
+ { blankLine: "any", prev: "singleline-let", next: "*" },
254
+ ],
255
+
256
+ "no-restricted-properties": [
257
+ "error",
258
+ {
259
+ object: "window",
260
+ property: "location",
261
+ message:
262
+ "We use React Router and History to control the location of our web or desktop app. Prefer `useLocation` in React components and `historyFromContext` in Redux Saga.",
263
+ },
264
+ ...(projectRoot.endsWith("client")
265
+ ? [
266
+ {
267
+ object: "window",
268
+ property: "document",
269
+ message: "Please use `useDocument` from `useDocument.tsx`.",
270
+ },
271
+ ...[
272
+ "addEventListener",
273
+ "removeEventListener",
274
+ "getElementById",
275
+ "documentElement",
276
+ "activeElement",
277
+ "querySelectorAll",
278
+ ].map((property) => ({
279
+ object: "document",
280
+ property,
281
+ message: "Please use `useDocument` from `useDocument.tsx`.",
282
+ })),
283
+ ]
284
+ : []),
285
+ ],
286
+
287
+ "no-restricted-globals": [
288
+ "warn",
289
+ {
290
+ name: "location",
291
+ message:
292
+ "We use React Router and History to control the location of our web or desktop app. Prefer `useLocation` in React components and `historyFromContext` in Redux Saga.",
293
+ },
294
+ ],
295
+
296
+ "prefer-const": [
297
+ "error",
298
+ {
299
+ destructuring: "all",
300
+ },
301
+ ],
302
+
303
+ "no-var": "error",
304
+ "no-void": "error",
305
+
306
+ "react/forbid-dom-props": [
307
+ "error",
308
+ {
309
+ forbid: [
310
+ {
311
+ propName: "style",
312
+ message: "Please use CSS Modules instead",
313
+ },
314
+ ],
315
+ },
316
+ ],
317
+ "react/forbid-component-props": [
318
+ "error",
319
+ {
320
+ forbid: [
321
+ {
322
+ propName: "style",
323
+ message: "Please use CSS Modules instead",
324
+ },
325
+ ],
326
+ },
327
+ ],
328
+ "no-sequences": ["error"],
329
+ // Too noisy about `react` and other node_modules
330
+ "import/default": 0,
331
+ // This complains about React.forwardRef, ReactDOM.render, etc.
332
+ "import/no-named-as-default-member": 0,
333
+ // This complains about "apollo" exporting ApolloClient as a default and as a
334
+ // named import at the same time.
335
+ "import/no-named-as-default": 0,
336
+ // Does not seem to work well with node_modules
337
+ "import/named": 0,
338
+ "import/newline-after-import": "error",
339
+ "import/order": [
340
+ "error",
341
+ {
342
+ groups: ["builtin", "external", "index", "parent", "sibling"],
343
+ pathGroups: [
344
+ {
345
+ pattern: "./**.module.css",
346
+ group: "sibling",
347
+ position: "after",
348
+ },
349
+ {
350
+ pattern: "./**.module.scss",
351
+ group: "sibling",
352
+ position: "after",
353
+ },
354
+ ],
355
+ alphabetize: {
356
+ order: "asc",
357
+ caseInsensitive: true,
358
+ },
359
+ },
360
+ ],
361
+ "unused-imports/no-unused-imports": "error",
362
+ "no-restricted-imports": [
363
+ "error",
364
+ {
365
+ patterns: [
366
+ {
367
+ group: ["react-router"],
368
+ message:
369
+ "Please use react-router-dom instead, since react-router's useLocation() doesn't work properly with StaticRouter on server side.",
370
+ },
371
+ ],
372
+ },
373
+ ],
374
+ // Fixes a common mistake: `a ?? b < c` which feels like `(a ?? b) < c`, but
375
+ // actually is `a ?? (b < c)`
376
+ "no-mixed-operators": [
377
+ "error",
378
+ {
379
+ allowSamePrecedence: false,
380
+ groups: [
381
+ ["??", "+"],
382
+ ["??", "-"],
383
+ ["??", "*"],
384
+ ["??", "/"],
385
+ ["??", "%"],
386
+ ["??", "**"],
387
+ ["??", "&"],
388
+ ["??", "|"],
389
+ ["??", "^"],
390
+ ["??", "~"],
391
+ ["??", "<<"],
392
+ ["??", ">>"],
393
+ ["??", ">>>"],
394
+ ["??", "=="],
395
+ ["??", "!="],
396
+ ["??", "==="],
397
+ ["??", "!=="],
398
+ ["??", ">"],
399
+ ["??", ">="],
400
+ ["??", "<"],
401
+ ["??", "<="],
402
+ ["??", "&&"],
403
+ ["??", "||"],
404
+ ["??", "in"],
405
+ ["??", "instanceof"],
406
+ ],
407
+ },
408
+ ],
409
+
410
+ quotes: ["error", "double", { avoidEscape: true }],
411
+ },
412
+ });
package/.eslintrc.js ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ const config = require("./.eslintrc.base.js")(__dirname);
3
+ config.rules["import/no-extraneous-dependencies"] = "error";
4
+ config.rules["lodash/import-scope"] = ["error", "method"];
5
+ module.exports = config;
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Mango Technologies, Inc. DBA ClickUp
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,121 @@
1
+ # RestClient: a syntax sugar tool around Node fetch() API, tailored to work with typescript-is or superstruct validators
2
+
3
+ See also [Full API documentation](https://github.com/clickup/rest-client/blob/master/docs/modules.md).
4
+
5
+ ## Examples
6
+
7
+ In the example below we use
8
+ [superstruct](https://www.npmjs.com/package/superstruct) library to build a
9
+ strongly typed response validator. Validator is just a function passed to
10
+ `json()` method: it must throw if the argument passed doesn't match what it
11
+ expects the value to be.
12
+
13
+ ```ts
14
+ import { array, number, object, string } from "superstruct";
15
+ import RestClient from "rest-client";
16
+
17
+ // Initialized once. See RestOptions for lots of other options.
18
+ const client = new RestClient()
19
+ .withOptions({
20
+ timeoutMs: 1000,
21
+ logger: (_event) => {
22
+ /* myLogger.log(event); */
23
+ },
24
+ })
25
+ .withBase("https://reqres.in");
26
+
27
+ async function main() {
28
+ // Send individual request using superstruct as a validation backend.
29
+ const res = await client
30
+ .get("/api/users", { page: 2 })
31
+ .setDebug()
32
+ .json(
33
+ object({
34
+ total: number(),
35
+ data: array(
36
+ object({
37
+ id: number(),
38
+ email: string(),
39
+ })
40
+ ),
41
+ })
42
+ );
43
+ console.log("Masked and validated response: ", res);
44
+ // Notice that `res` is strongly typed! You won't make a typo.
45
+ console.log("Here is a TS strongly-typed field:", res.data[0].email);
46
+ }
47
+
48
+ main().catch((e) => console.error(e));
49
+ ```
50
+
51
+ The above script prints the following:
52
+
53
+ ```
54
+ +++ GET https://reqres.in/api/users?page=2
55
+ +++ Accept: application/json
56
+ === HTTP 200 (took 105 ms)
57
+ === { data:
58
+ === [ { id: 7,
59
+ === email: 'michael.lawson@reqres.in',
60
+ === first_name: 'Michael',
61
+ === last_name: 'Lawson',
62
+ === avatar: 'https://reqres.in/img/faces/7-image.jpg' },
63
+ === { id: 8,
64
+ === email: 'lindsay.ferguson@reqres.in',
65
+ === first_name: 'Lindsay',
66
+ === last_name: 'Ferguson',
67
+ === avatar: 'https://reqres.in/img/faces/8-image.jpg' },
68
+ === { id: 9,
69
+ === email: 'tobias.funke@reqres.in',
70
+ === first_name: 'Tobias',
71
+ === last_name: 'Funke',
72
+ === avatar: 'https://reqres.in/img/faces/9-image.jpg' },
73
+ === { id: 10,
74
+ === email: 'byron.fields@reqres.in',
75
+ === first_name: 'Byron',
76
+ === last_name: 'Fields',
77
+ === avatar: 'https://reqres.in/img/faces/10-image.jpg' },
78
+ === { id: 11,
79
+ === email: 'george.edwards@reqres.in',
80
+ === first_name: 'George',
81
+ === last_name: 'Edwards',
82
+ === avatar: 'https://reqres.in/img/faces/11-image.jpg' },
83
+ === { id: 12,
84
+ === email: 'rachel.howell@reqres.in',
85
+ === first_name: 'Rachel',
86
+ === last_name: 'Howell',
87
+ === avatar: 'https://reqres.in/img/faces/12-image.jpg' } ],
88
+ === page: 2,
89
+ === per_page: 6,
90
+ === support:
91
+ === { url: 'https://reqres.in/#support-heading',
92
+ === text: 'To keep ReqRes free, contributions!' },
93
+ === total: 12,
94
+ === total_pages: 2 }
95
+
96
+ Masked and validated response: {
97
+ total: 12,
98
+ data: [
99
+ { id: 7, email: 'michael.lawson@reqres.in' },
100
+ { id: 8, email: 'lindsay.ferguson@reqres.in' },
101
+ { id: 9, email: 'tobias.funke@reqres.in' },
102
+ { id: 10, email: 'byron.fields@reqres.in' },
103
+ { id: 11, email: 'george.edwards@reqres.in' },
104
+ { id: 12, email: 'rachel.howell@reqres.in' }
105
+ ]
106
+ }
107
+ Here is a TS strongly-typed field: michael.lawson@reqres.in
108
+ ```
109
+
110
+ If the API response doesn't match the expected shape (e.g. we expect "other_field" to be presented too), superstruct will throw a descriptive message:
111
+
112
+ ```
113
+ StructError: At path: data.0.other_field -- Expected a number, but received: undefined
114
+ ```
115
+
116
+ ## Validation Backends
117
+
118
+ You can use one of the following libraries to type-enforce the response:
119
+ - [typescript-is](https://www.npmjs.com/package/typescript-is)
120
+ - [superstruct](https://www.npmjs.com/package/superstruct)
121
+ - any other solution which can validate TS object shape against a JSON