@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 CHANGED
@@ -70,7 +70,13 @@ function MyApp() {
70
70
  'my_service',
71
71
  'my_request',
72
72
  { _id: 'someid' }
73
- ).then(setData, setError);
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(setData, setError);
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) => boolean;
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
- handleError(`${METHODS[action]} ${url} returned invalid Content-Type: ${ct}`);
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
- handleError(`${METHODS[action]} ${url} returned invalid status: ${response.status}`);
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
- return reject(result.error);
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
- _.warning(result.warning, { action, data, res, url });
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
- // Resolve it
181
- return resolve(result.data);
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.2.2",
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.2"
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) => boolean;
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
- handleError(
210
- `${METHODS[action]} ${url} returned invalid Content-Type: ${ct}`
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
- handleError(
234
- `${METHODS[action]} ${url} returned invalid status: ${response.status}`
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
- return reject(result.error);
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
- _.warning(
266
- result.warning, { action, data, res, url }
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
- // Resolve it
274
- return resolve(result.data);
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
+