@ouroboros/body 1.2.2 → 1.3.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/README.md +19 -7
- package/lib/index.d.ts +2 -2
- package/lib/index.js +24 -11
- package/package.json +3 -3
- package/releases.md +3 -0
- package/src/index.ts +34 -20
- package/tslint-to-eslint-config.log +19 -0
package/README.md
CHANGED
|
@@ -70,7 +70,13 @@ function MyApp() {
|
|
|
70
70
|
'my_service',
|
|
71
71
|
'my_request',
|
|
72
72
|
{ _id: 'someid' }
|
|
73
|
-
).then(
|
|
73
|
+
).then(res => {
|
|
74
|
+
if(res.error) {
|
|
75
|
+
setError(res.error);
|
|
76
|
+
} else {
|
|
77
|
+
setData(res.data);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
74
80
|
}
|
|
75
81
|
|
|
76
82
|
return <>
|
|
@@ -136,7 +142,13 @@ the [example](#body) could have also been written as
|
|
|
136
142
|
'my_service',
|
|
137
143
|
'my_request',
|
|
138
144
|
{ _id: 'someid' }
|
|
139
|
-
).then(
|
|
145
|
+
).then(res => {
|
|
146
|
+
if(res.error) {
|
|
147
|
+
setError(res.error);
|
|
148
|
+
} else {
|
|
149
|
+
setData(res.data);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
140
152
|
```
|
|
141
153
|
|
|
142
154
|
[ [top](#ouroborosbody), [contents](#contents), [body](#body) ]
|
|
@@ -289,17 +301,17 @@ body.read(
|
|
|
289
301
|
'my_service',
|
|
290
302
|
'my/request',
|
|
291
303
|
{ _id: 'someid' }
|
|
292
|
-
).then(res => {
|
|
293
|
-
error
|
|
294
|
-
if(error.code === errors.DATA_FIELDS) {
|
|
304
|
+
).then(res => {
|
|
305
|
+
if(res.error) {
|
|
306
|
+
if(res.error.code === errors.DATA_FIELDS) {
|
|
295
307
|
// Bad data sent to request
|
|
296
|
-
} else if(error.code === errors.DB_NO_RECORD) {
|
|
308
|
+
} else if(res.error.code === errors.DB_NO_RECORD) {
|
|
297
309
|
// Bad ID, no such record
|
|
298
310
|
} else {
|
|
299
311
|
// Unknown error code
|
|
300
312
|
}
|
|
301
313
|
}
|
|
302
|
-
)
|
|
314
|
+
})
|
|
303
315
|
```
|
|
304
316
|
|
|
305
317
|
[ [top](#ouroborosbody), [contents](#contents) ]
|
package/lib/index.d.ts
CHANGED
|
@@ -36,7 +36,7 @@ export type onRequestingStruct = {
|
|
|
36
36
|
data: any;
|
|
37
37
|
url: string;
|
|
38
38
|
};
|
|
39
|
-
export type onWarning = (warning: any, info: onRequestedStruct) => void;
|
|
39
|
+
export type onWarning = (warning: any, info: onRequestedStruct) => void | false;
|
|
40
40
|
export type responseStruct = {
|
|
41
41
|
data?: any;
|
|
42
42
|
error?: responseErrorStruct;
|
|
@@ -47,7 +47,7 @@ export type responseErrorStruct = {
|
|
|
47
47
|
msg?: any;
|
|
48
48
|
};
|
|
49
49
|
export type responseResolve = (res: responseStruct) => void;
|
|
50
|
-
export type responseReject = (error: responseErrorStruct) =>
|
|
50
|
+
export type responseReject = (error: responseErrorStruct) => void;
|
|
51
51
|
/**
|
|
52
52
|
* Body
|
|
53
53
|
*
|
package/lib/index.js
CHANGED
|
@@ -135,25 +135,27 @@ class Body {
|
|
|
135
135
|
// If the Content-Type is missing or invalid
|
|
136
136
|
const ct = response.headers.get('Content-Type');
|
|
137
137
|
if (!ct || ct !== 'application/json; charset=utf-8') {
|
|
138
|
-
|
|
138
|
+
const err = `${METHODS[action]} ${url} returned invalid Content-Type: ${ct}`;
|
|
139
|
+
handleError(err);
|
|
140
|
+
return reject({ code: 0, msg: err });
|
|
139
141
|
}
|
|
140
142
|
// Return the JSON
|
|
141
143
|
return response.json();
|
|
142
144
|
}
|
|
143
145
|
// If it's 401
|
|
144
|
-
if (response.status === 401) {
|
|
146
|
+
else if (response.status === 401) {
|
|
145
147
|
// If we have a no session callback
|
|
146
148
|
if (_.noSession) {
|
|
147
149
|
_.noSession();
|
|
148
|
-
return reject({ code: 0, msg: '401 Not Authorized' });
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
throw new Error(`${METHODS[action]} ${url} return 401 NOT AUTHORIZED`);
|
|
152
150
|
}
|
|
151
|
+
// Reject the request
|
|
152
|
+
return reject({ code: 0, msg: `${METHODS[action]} ${url} return 401 NOT AUTHORIZED` });
|
|
153
153
|
}
|
|
154
154
|
// Else, invalid status
|
|
155
155
|
else {
|
|
156
|
-
|
|
156
|
+
const err = `${METHODS[action]} ${url} returned invalid status: ${response.status}`;
|
|
157
|
+
handleError(err);
|
|
158
|
+
return reject({ code: 0, msg: err });
|
|
157
159
|
}
|
|
158
160
|
}).then(result => {
|
|
159
161
|
// If there's no result, do nothing
|
|
@@ -162,24 +164,35 @@ class Body {
|
|
|
162
164
|
}
|
|
163
165
|
// Set res
|
|
164
166
|
res = result;
|
|
167
|
+
// Init the structure to pass to resolve
|
|
168
|
+
const oResult = {};
|
|
165
169
|
// If we got an error
|
|
166
170
|
if ('error' in result && result.error) {
|
|
167
171
|
// If we don't have an onErrorCode callback, or we do and
|
|
168
172
|
// calling it returns false
|
|
169
173
|
if (!_.errorCode ||
|
|
170
174
|
_.errorCode(result.error, { action, data, res, url }) === false) {
|
|
171
|
-
|
|
175
|
+
// If it wasn't handled, add it to the result
|
|
176
|
+
oResult.error = structuredClone(result.error);
|
|
172
177
|
}
|
|
173
178
|
}
|
|
174
179
|
// If we got a warning and we have an onWarning callback
|
|
175
180
|
if ('warning' in result && result.warning && _.warning) {
|
|
176
|
-
|
|
181
|
+
// If we don't have an onWarning callback, or we do and
|
|
182
|
+
// calling it returns false
|
|
183
|
+
if (!_.warning ||
|
|
184
|
+
_.warning(result.warning, { action, data, res, url }) === false) {
|
|
185
|
+
// If it wasn't handled, add it to the result
|
|
186
|
+
oResult.warning = structuredClone(result.warning);
|
|
187
|
+
}
|
|
177
188
|
}
|
|
178
189
|
// If we got data
|
|
179
190
|
if ('data' in result) {
|
|
180
|
-
//
|
|
181
|
-
|
|
191
|
+
// Add it
|
|
192
|
+
oResult.data = structuredClone(result.data);
|
|
182
193
|
}
|
|
194
|
+
// Resolve
|
|
195
|
+
return resolve(oResult);
|
|
183
196
|
}).catch(reason => {
|
|
184
197
|
handleError(`${METHODS[action]} ${url} failed because of "${reason}"`);
|
|
185
198
|
}).finally(() => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ouroboros/body",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Classes to communicate with Ouroboros Coding Inc. body services",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -26,6 +26,6 @@
|
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"tslint": "^6.1.3",
|
|
28
28
|
"tslint-config-prettier": "^1.18.0",
|
|
29
|
-
"typescript": "^5.9.
|
|
29
|
+
"typescript": "^5.9.3"
|
|
30
30
|
}
|
|
31
|
-
}
|
|
31
|
+
}
|
package/releases.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# @ouroboros/body releases
|
|
2
2
|
|
|
3
|
+
## 1.3.0
|
|
4
|
+
- Stopped splitting data and error into resolve and reject as this made it harder to identify and solve real communication problems. From now on all requests that are returned successfully, regardless of the result, are returned in full to resolve. This means all current `.then()` calls on requests must handle the full responseStruct result instead of just the `.data`. Similarly, any code currently running in the reject based on completed, but error filled, requests must be moved into the first argument of `.then()`.
|
|
5
|
+
|
|
3
6
|
## 1.2.2
|
|
4
7
|
- Fixed issue where `finally` not being called on Promises if 401 Not Authorized is returned.
|
|
5
8
|
|
package/src/index.ts
CHANGED
|
@@ -42,7 +42,7 @@ export type onRequestingStruct = {
|
|
|
42
42
|
data: any,
|
|
43
43
|
url: string
|
|
44
44
|
};
|
|
45
|
-
export type onWarning = (warning: any, info: onRequestedStruct) => void;
|
|
45
|
+
export type onWarning = (warning: any, info: onRequestedStruct) => void | false;
|
|
46
46
|
export type responseStruct = {
|
|
47
47
|
data?: any,
|
|
48
48
|
error?: responseErrorStruct,
|
|
@@ -53,7 +53,7 @@ export type responseErrorStruct = {
|
|
|
53
53
|
msg?: any
|
|
54
54
|
}
|
|
55
55
|
export type responseResolve = (res: responseStruct) => void;
|
|
56
|
-
export type responseReject = (error: responseErrorStruct) =>
|
|
56
|
+
export type responseReject = (error: responseErrorStruct) => void;
|
|
57
57
|
|
|
58
58
|
// Actions to methods
|
|
59
59
|
const METHODS = {
|
|
@@ -206,9 +206,9 @@ class Body {
|
|
|
206
206
|
// If the Content-Type is missing or invalid
|
|
207
207
|
const ct = response.headers.get('Content-Type');
|
|
208
208
|
if(!ct || ct !== 'application/json; charset=utf-8') {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
);
|
|
209
|
+
const err = `${METHODS[action]} ${url} returned invalid Content-Type: ${ct}`
|
|
210
|
+
handleError(err);
|
|
211
|
+
return reject({ code: 0, msg: err });
|
|
212
212
|
}
|
|
213
213
|
|
|
214
214
|
// Return the JSON
|
|
@@ -216,23 +216,21 @@ class Body {
|
|
|
216
216
|
}
|
|
217
217
|
|
|
218
218
|
// If it's 401
|
|
219
|
-
if(response.status === 401) {
|
|
219
|
+
else if(response.status === 401) {
|
|
220
220
|
|
|
221
221
|
// If we have a no session callback
|
|
222
222
|
if(_.noSession) {
|
|
223
223
|
_.noSession();
|
|
224
|
-
return reject({ code: 0, msg: '401 Not Authorized' });
|
|
225
|
-
} else {
|
|
226
|
-
throw new Error(
|
|
227
|
-
`${METHODS[action]} ${url} return 401 NOT AUTHORIZED`
|
|
228
|
-
);
|
|
229
224
|
}
|
|
225
|
+
|
|
226
|
+
// Reject the request
|
|
227
|
+
return reject({ code: 0, msg: `${METHODS[action]} ${url} return 401 NOT AUTHORIZED` });
|
|
230
228
|
}
|
|
231
229
|
// Else, invalid status
|
|
232
230
|
else {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
);
|
|
231
|
+
const err = `${METHODS[action]} ${url} returned invalid status: ${response.status}`;
|
|
232
|
+
handleError(err);
|
|
233
|
+
return reject({ code: 0, msg: err });
|
|
236
234
|
}
|
|
237
235
|
|
|
238
236
|
}).then(result => {
|
|
@@ -245,6 +243,9 @@ class Body {
|
|
|
245
243
|
// Set res
|
|
246
244
|
res = result;
|
|
247
245
|
|
|
246
|
+
// Init the structure to pass to resolve
|
|
247
|
+
const oResult: responseStruct = { };
|
|
248
|
+
|
|
248
249
|
// If we got an error
|
|
249
250
|
if('error' in result && result.error) {
|
|
250
251
|
|
|
@@ -256,24 +257,37 @@ class Body {
|
|
|
256
257
|
{ action, data, res, url }
|
|
257
258
|
) === false
|
|
258
259
|
) {
|
|
259
|
-
|
|
260
|
+
// If it wasn't handled, add it to the result
|
|
261
|
+
oResult.error = structuredClone(result.error);
|
|
260
262
|
}
|
|
261
263
|
}
|
|
262
264
|
|
|
263
265
|
// If we got a warning and we have an onWarning callback
|
|
264
266
|
if('warning' in result && result.warning && _.warning) {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
267
|
+
|
|
268
|
+
// If we don't have an onWarning callback, or we do and
|
|
269
|
+
// calling it returns false
|
|
270
|
+
if(!_.warning ||
|
|
271
|
+
_.warning(
|
|
272
|
+
result.warning,
|
|
273
|
+
{ action, data, res, url }
|
|
274
|
+
) === false
|
|
275
|
+
) {
|
|
276
|
+
// If it wasn't handled, add it to the result
|
|
277
|
+
oResult.warning = structuredClone(result.warning);
|
|
278
|
+
}
|
|
268
279
|
}
|
|
269
280
|
|
|
270
281
|
// If we got data
|
|
271
282
|
if('data' in result) {
|
|
272
283
|
|
|
273
|
-
//
|
|
274
|
-
|
|
284
|
+
// Add it
|
|
285
|
+
oResult.data = structuredClone(result.data);
|
|
275
286
|
}
|
|
276
287
|
|
|
288
|
+
// Resolve
|
|
289
|
+
return resolve(oResult);
|
|
290
|
+
|
|
277
291
|
}).catch(reason => {
|
|
278
292
|
handleError(
|
|
279
293
|
`${METHODS[action]} ${url} failed because of "${reason}"`
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
6 ESLint rules behave differently from their TSLint counterparts:
|
|
2
|
+
* no-invalid-this:
|
|
3
|
+
- Functions in methods will no longer be ignored.
|
|
4
|
+
* @typescript-eslint/no-unused-expressions:
|
|
5
|
+
- The TSLint optional config "allow-new" is the default ESLint behavior and will no longer be ignored.
|
|
6
|
+
* prefer-arrow/prefer-arrow-functions:
|
|
7
|
+
- ESLint (eslint-plugin-prefer-arrow plugin) does not support allowing named functions defined with the function keyword.
|
|
8
|
+
* eqeqeq:
|
|
9
|
+
- Option "smart" allows for comparing two literal values, evaluating the value of typeof and null comparisons.
|
|
10
|
+
* no-underscore-dangle:
|
|
11
|
+
- Leading and trailing underscores (_) on identifiers will now be ignored.
|
|
12
|
+
* padded-blocks:
|
|
13
|
+
- ESLint's padded-blocks rule also bans a blank line before a closing brace.
|
|
14
|
+
|
|
15
|
+
Error: multiple output react/jsx-curly-spacing ESLint rule options were generated, but tslint-to-eslint-config doesn't have "merger" logic to deal with this.
|
|
16
|
+
Please file an issue at https://github.com/typescript-eslint/tslint-to-eslint-config/issues/new?template=missing_merger.md. Thanks!
|
|
17
|
+
|
|
18
|
+
* import-destructuring-spacing
|
|
19
|
+
|