@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.
- package/.eslintrc.base.js +412 -0
- package/.eslintrc.js +5 -0
- package/LICENSE +22 -0
- package/README.md +121 -0
- package/dist/RestClient.d.ts +154 -0
- package/dist/RestClient.d.ts.map +1 -0
- package/dist/RestClient.js +361 -0
- package/dist/RestClient.js.map +1 -0
- package/dist/RestOptions.d.ts +143 -0
- package/dist/RestOptions.d.ts.map +1 -0
- package/dist/RestOptions.js +63 -0
- package/dist/RestOptions.js.map +1 -0
- package/dist/RestRequest.d.ts +81 -0
- package/dist/RestRequest.d.ts.map +1 -0
- package/dist/RestRequest.js +367 -0
- package/dist/RestRequest.js.map +1 -0
- package/dist/RestResponse.d.ts +37 -0
- package/dist/RestResponse.d.ts.map +1 -0
- package/dist/RestResponse.js +56 -0
- package/dist/RestResponse.js.map +1 -0
- package/dist/RestStream.d.ts +29 -0
- package/dist/RestStream.d.ts.map +1 -0
- package/dist/RestStream.js +85 -0
- package/dist/RestStream.js.map +1 -0
- package/dist/errors/RestContentSizeOverLimitError.d.ts +4 -0
- package/dist/errors/RestContentSizeOverLimitError.d.ts.map +1 -0
- package/dist/errors/RestContentSizeOverLimitError.js +10 -0
- package/dist/errors/RestContentSizeOverLimitError.js.map +1 -0
- package/dist/errors/RestError.d.ts +4 -0
- package/dist/errors/RestError.d.ts.map +1 -0
- package/dist/errors/RestError.js +10 -0
- package/dist/errors/RestError.js.map +1 -0
- package/dist/errors/RestRateLimitError.d.ts +7 -0
- package/dist/errors/RestRateLimitError.d.ts.map +1 -0
- package/dist/errors/RestRateLimitError.js +14 -0
- package/dist/errors/RestRateLimitError.js.map +1 -0
- package/dist/errors/RestResponseError.d.ts +13 -0
- package/dist/errors/RestResponseError.d.ts.map +1 -0
- package/dist/errors/RestResponseError.js +32 -0
- package/dist/errors/RestResponseError.js.map +1 -0
- package/dist/errors/RestRetriableError.d.ts +7 -0
- package/dist/errors/RestRetriableError.d.ts.map +1 -0
- package/dist/errors/RestRetriableError.js +14 -0
- package/dist/errors/RestRetriableError.js.map +1 -0
- package/dist/errors/RestTimeoutError.d.ts +4 -0
- package/dist/errors/RestTimeoutError.d.ts.map +1 -0
- package/dist/errors/RestTimeoutError.js +10 -0
- package/dist/errors/RestTimeoutError.js.map +1 -0
- package/dist/errors/RestTokenInvalidError.d.ts +7 -0
- package/dist/errors/RestTokenInvalidError.d.ts.map +1 -0
- package/dist/errors/RestTokenInvalidError.js +14 -0
- package/dist/errors/RestTokenInvalidError.js.map +1 -0
- package/dist/helpers/depaginate.d.ts +10 -0
- package/dist/helpers/depaginate.d.ts.map +1 -0
- package/dist/helpers/depaginate.js +32 -0
- package/dist/helpers/depaginate.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/RestFetchReader.d.ts +72 -0
- package/dist/internal/RestFetchReader.d.ts.map +1 -0
- package/dist/internal/RestFetchReader.js +192 -0
- package/dist/internal/RestFetchReader.js.map +1 -0
- package/dist/internal/RestRangeUploader.d.ts +24 -0
- package/dist/internal/RestRangeUploader.d.ts.map +1 -0
- package/dist/internal/RestRangeUploader.js +54 -0
- package/dist/internal/RestRangeUploader.js.map +1 -0
- package/dist/internal/calcRetryDelay.d.ts +8 -0
- package/dist/internal/calcRetryDelay.d.ts.map +1 -0
- package/dist/internal/calcRetryDelay.js +44 -0
- package/dist/internal/calcRetryDelay.js.map +1 -0
- package/dist/internal/inspectPossibleJSON.d.ts +6 -0
- package/dist/internal/inspectPossibleJSON.d.ts.map +1 -0
- package/dist/internal/inspectPossibleJSON.js +53 -0
- package/dist/internal/inspectPossibleJSON.js.map +1 -0
- package/dist/internal/prependNewlineIfMultiline.d.ts +2 -0
- package/dist/internal/prependNewlineIfMultiline.d.ts.map +1 -0
- package/dist/internal/prependNewlineIfMultiline.js +7 -0
- package/dist/internal/prependNewlineIfMultiline.js.map +1 -0
- package/dist/internal/substituteParams.d.ts +7 -0
- package/dist/internal/substituteParams.d.ts.map +1 -0
- package/dist/internal/substituteParams.js +24 -0
- package/dist/internal/substituteParams.js.map +1 -0
- package/dist/internal/throwIfErrorResponse.d.ts +11 -0
- package/dist/internal/throwIfErrorResponse.d.ts.map +1 -0
- package/dist/internal/throwIfErrorResponse.js +60 -0
- package/dist/internal/throwIfErrorResponse.js.map +1 -0
- package/dist/internal/toFloatMs.d.ts +2 -0
- package/dist/internal/toFloatMs.d.ts.map +1 -0
- package/dist/internal/toFloatMs.js +7 -0
- package/dist/internal/toFloatMs.js.map +1 -0
- package/dist/middlewares/paceRequests.d.ts +9 -0
- package/dist/middlewares/paceRequests.d.ts.map +1 -0
- package/dist/middlewares/paceRequests.js +36 -0
- package/dist/middlewares/paceRequests.js.map +1 -0
- package/dist/pacers/Pacer.d.ts +21 -0
- package/dist/pacers/Pacer.d.ts.map +1 -0
- package/dist/pacers/Pacer.js +3 -0
- package/dist/pacers/Pacer.js.map +1 -0
- package/dist/pacers/PacerComposite.d.ts +14 -0
- package/dist/pacers/PacerComposite.d.ts.map +1 -0
- package/dist/pacers/PacerComposite.js +32 -0
- package/dist/pacers/PacerComposite.js.map +1 -0
- package/dist/pacers/PacerQPS.d.ts +53 -0
- package/dist/pacers/PacerQPS.d.ts.map +1 -0
- package/dist/pacers/PacerQPS.js +105 -0
- package/dist/pacers/PacerQPS.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/docs/.nojekyll +1 -0
- package/docs/README.md +123 -0
- package/docs/classes/PacerComposite.md +62 -0
- package/docs/classes/PacerQPS.md +75 -0
- package/docs/classes/RestClient.md +424 -0
- package/docs/classes/RestContentSizeOverLimitError.md +128 -0
- package/docs/classes/RestError.md +31 -0
- package/docs/classes/RestRateLimitError.md +139 -0
- package/docs/classes/RestRequest.md +257 -0
- package/docs/classes/RestResponse.md +110 -0
- package/docs/classes/RestResponseError.md +110 -0
- package/docs/classes/RestRetriableError.md +139 -0
- package/docs/classes/RestStream.md +92 -0
- package/docs/classes/RestTimeoutError.md +128 -0
- package/docs/classes/RestTokenInvalidError.md +138 -0
- package/docs/interfaces/Middleware.md +27 -0
- package/docs/interfaces/Pacer.md +40 -0
- package/docs/interfaces/PacerDelay.md +25 -0
- package/docs/interfaces/PacerQPSBackend.md +44 -0
- package/docs/interfaces/PacerQPSOptions.md +40 -0
- package/docs/interfaces/RestLogEvent.md +95 -0
- package/docs/interfaces/RestOptions.md +351 -0
- package/docs/interfaces/TokenGetter.md +34 -0
- package/docs/modules.md +87 -0
- package/jest.config.js +8 -0
- package/package.json +42 -0
- package/tsconfig.json +39 -0
- 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
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
|