@ouroboros/body 1.1.2 → 1.2.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/LICENSE +4 -4
- package/README.md +319 -10
- package/{build → lib}/Service.d.ts +32 -1
- package/{build → lib}/Service.js +37 -0
- package/{build → lib}/constants.d.ts +1 -0
- package/{build → lib}/constants.js +1 -0
- package/{build → lib}/index.d.ts +17 -28
- package/{build → lib}/index.js +115 -129
- package/{build → lib}/regex.js +2 -2
- package/ouroboros-body-1.2.0.tgz +0 -0
- package/package.json +5 -8
- package/releases.md +12 -0
- package/src/Service.ts +43 -1
- package/src/constants.ts +5 -4
- package/src/index.ts +153 -157
- package/src/regex.ts +2 -2
- package/build/types/xhr2.d.ts +0 -3
- package/src/types/xhr2.d.ts +0 -3
- /package/{build → lib}/errors.d.ts +0 -0
- /package/{build → lib}/errors.js +0 -0
- /package/{build → lib}/regex.d.ts +0 -0
package/{build → lib}/index.js
RENAMED
|
@@ -7,8 +7,6 @@
|
|
|
7
7
|
* @copyright Ouroboros Coding Inc.
|
|
8
8
|
* @created 2023-03-03
|
|
9
9
|
*/
|
|
10
|
-
// NPM modules
|
|
11
|
-
import XMLHttpRequest from 'xhr2';
|
|
12
10
|
// Import const files
|
|
13
11
|
import * as constants from './constants';
|
|
14
12
|
import * as errors from './errors';
|
|
@@ -17,7 +15,7 @@ import * as regex from './regex';
|
|
|
17
15
|
export { constants, errors, regex };
|
|
18
16
|
export { default as Service } from './Service';
|
|
19
17
|
// Actions to methods
|
|
20
|
-
const
|
|
18
|
+
const METHODS = {
|
|
21
19
|
create: 'POST',
|
|
22
20
|
delete: 'DELETE',
|
|
23
21
|
read: 'GET',
|
|
@@ -33,13 +31,13 @@ const ACTIONS_TO_METHODS = {
|
|
|
33
31
|
*/
|
|
34
32
|
class Body {
|
|
35
33
|
// The domain used to make requests to
|
|
36
|
-
_domain = '';
|
|
34
|
+
_domain = 'localhost';
|
|
37
35
|
// The function to call for http and related errors that need to be reported
|
|
38
36
|
error = null;
|
|
39
37
|
// The function to call if we get body errors
|
|
40
38
|
errorCode = null;
|
|
41
39
|
// The function to call when we get a status 401, or error code
|
|
42
|
-
//
|
|
40
|
+
// REST_AUTHORIZATION
|
|
43
41
|
noSession = null;
|
|
44
42
|
// The function to call after any request is sent
|
|
45
43
|
requested = null;
|
|
@@ -47,21 +45,27 @@ class Body {
|
|
|
47
45
|
requesting = null;
|
|
48
46
|
// The token associated with the current session
|
|
49
47
|
token = null;
|
|
50
|
-
// Flag for being verbose
|
|
51
|
-
verbose = false;
|
|
52
48
|
// The function to call if we get body warnings
|
|
53
49
|
warning = null;
|
|
54
50
|
/**
|
|
55
51
|
* Domain
|
|
56
52
|
*
|
|
57
|
-
*
|
|
53
|
+
* Sets/Gets the domain
|
|
58
54
|
*
|
|
59
55
|
* @name domain
|
|
60
56
|
* @access public
|
|
61
|
-
* @param domain The
|
|
57
|
+
* @param @param domain The domain to set
|
|
58
|
+
* @returns the domain set
|
|
62
59
|
*/
|
|
63
60
|
domain(domain) {
|
|
64
|
-
|
|
61
|
+
// If we are getting the token
|
|
62
|
+
if (domain === undefined) {
|
|
63
|
+
return this._domain;
|
|
64
|
+
}
|
|
65
|
+
// Else, we are setting the token
|
|
66
|
+
else {
|
|
67
|
+
this._domain = domain;
|
|
68
|
+
}
|
|
65
69
|
}
|
|
66
70
|
/**
|
|
67
71
|
* Request
|
|
@@ -70,6 +74,7 @@ class Body {
|
|
|
70
74
|
*
|
|
71
75
|
* @name request
|
|
72
76
|
* @access public
|
|
77
|
+
* @param action The action to take in the call
|
|
73
78
|
* @param service The service to call
|
|
74
79
|
* @param noun The noun to call on the service
|
|
75
80
|
* @param data The data associated with the request
|
|
@@ -77,124 +82,107 @@ class Body {
|
|
|
77
82
|
request(action, service, noun, data) {
|
|
78
83
|
// Generate the URL for the request
|
|
79
84
|
let url = `https://${this._domain}/${service}/${noun}`;
|
|
80
|
-
// Init the response
|
|
85
|
+
// Init the response and json variables
|
|
81
86
|
let res;
|
|
87
|
+
let json;
|
|
88
|
+
// If we got data
|
|
89
|
+
if (data !== null) {
|
|
90
|
+
// If we're in GET mode, append the data as a param "d" after
|
|
91
|
+
// turning it into JSON
|
|
92
|
+
if (action === 'read') {
|
|
93
|
+
url += '?d=' + encodeURIComponent(JSON.stringify(data));
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
json = JSON.stringify(data);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
82
99
|
// Set this
|
|
83
|
-
const
|
|
100
|
+
const _ = this;
|
|
101
|
+
// Handles an error based on whether an error handler is set
|
|
102
|
+
function handleError(message) {
|
|
103
|
+
if (_.error) {
|
|
104
|
+
_.error(message, { action, data, url });
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
throw new Error(message);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
84
110
|
// Create a new Promise and return it
|
|
85
111
|
return new Promise((resolve, reject) => {
|
|
86
|
-
//
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
$this.error(message, { action, data, res, url, xhr });
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
throw new Error(message);
|
|
112
|
+
// Init the fetch init
|
|
113
|
+
const fetchInit = {
|
|
114
|
+
method: METHODS[action],
|
|
115
|
+
headers: {
|
|
116
|
+
'Content-Type': 'application/json; charset=utf-8'
|
|
95
117
|
}
|
|
118
|
+
};
|
|
119
|
+
// If we have a session token, add it as the Authorization header
|
|
120
|
+
if (_.token) {
|
|
121
|
+
fetchInit.headers.Authorization = _.token;
|
|
96
122
|
}
|
|
97
|
-
//
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
123
|
+
// If we have JSON
|
|
124
|
+
if (json) {
|
|
125
|
+
fetchInit.body = json;
|
|
126
|
+
}
|
|
127
|
+
// If we have a requesting callback, call it
|
|
128
|
+
if (this.requesting) {
|
|
129
|
+
this.requesting({ action, data, url });
|
|
130
|
+
}
|
|
131
|
+
// Make the call
|
|
132
|
+
fetch(url, fetchInit).then(response => {
|
|
133
|
+
// If 2xx
|
|
134
|
+
if (response.ok) {
|
|
135
|
+
// If the Content-Type is missing or invalid
|
|
136
|
+
const ct = response.headers.get('Content-Type');
|
|
137
|
+
if (!ct || ct !== 'application/json; charset=utf-8') {
|
|
138
|
+
handleError(`${METHODS[action]} ${url} returned invalid Content-Type: ${ct}`);
|
|
139
|
+
}
|
|
140
|
+
// Return the JSON
|
|
141
|
+
return response.json();
|
|
115
142
|
}
|
|
116
|
-
// If
|
|
117
|
-
if (
|
|
118
|
-
// If
|
|
119
|
-
if (
|
|
120
|
-
|
|
121
|
-
if (this.noSession) {
|
|
122
|
-
return this.noSession();
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
throw new Error(`${ACTIONS_TO_METHODS[action]} ${url} return 401 NOT AUTHORIZED`);
|
|
126
|
-
}
|
|
143
|
+
// If it's 401
|
|
144
|
+
if (response.status === 401) {
|
|
145
|
+
// If we have a no session callback
|
|
146
|
+
if (_.noSession) {
|
|
147
|
+
return _.noSession();
|
|
127
148
|
}
|
|
128
|
-
// Else, invalid status
|
|
129
149
|
else {
|
|
130
|
-
|
|
150
|
+
throw new Error(`${METHODS[action]} ${url} return 401 NOT AUTHORIZED`);
|
|
131
151
|
}
|
|
132
152
|
}
|
|
133
|
-
//
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
handleError(`${ACTIONS_TO_METHODS[action]} ${url} returned invalid Content-Type: ${contentType}`);
|
|
137
|
-
}
|
|
138
|
-
// Convert the text from JSON
|
|
139
|
-
res = JSON.parse(xhr.responseText);
|
|
140
|
-
// If the JSON failed to parse
|
|
141
|
-
if (!res) {
|
|
142
|
-
handleError(`${ACTIONS_TO_METHODS[action]} ${url} returned invalid JSON: ${xhr.responseText}`);
|
|
153
|
+
// Else, invalid status
|
|
154
|
+
else {
|
|
155
|
+
handleError(`${METHODS[action]} ${url} returned invalid status: ${response.status}`);
|
|
143
156
|
}
|
|
157
|
+
}).then(result => {
|
|
158
|
+
// Set res
|
|
159
|
+
res = result;
|
|
144
160
|
// If we got an error
|
|
145
|
-
if ('error' in
|
|
146
|
-
//
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
return reject(res.error);
|
|
161
|
+
if ('error' in result && result.error) {
|
|
162
|
+
// If we don't have an onErrorCode callback, or we do and
|
|
163
|
+
// calling it returns false
|
|
164
|
+
if (!_.errorCode ||
|
|
165
|
+
_.errorCode(result.error, { action, data, res, url }) === false) {
|
|
166
|
+
return reject(result.error);
|
|
152
167
|
}
|
|
153
168
|
}
|
|
169
|
+
// If we got a warning and we have an onWarning callback
|
|
170
|
+
if ('warning' in result && result.warning && _.warning) {
|
|
171
|
+
_.warning(result.warning, { action, data, res, url });
|
|
172
|
+
}
|
|
154
173
|
// If we got data
|
|
155
|
-
if ('data' in
|
|
174
|
+
if ('data' in result) {
|
|
156
175
|
// Resolve it
|
|
157
|
-
return resolve(
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
// Handle the request being finished
|
|
161
|
-
xhr.addEventListener('loadend', event => {
|
|
162
|
-
if (this.verbose) {
|
|
163
|
-
console.log(`xhr.loadend:\n\t${ACTIONS_TO_METHODS[action]} ${url}\n\t`, event);
|
|
176
|
+
return resolve(result.data);
|
|
164
177
|
}
|
|
178
|
+
}).catch(reason => {
|
|
179
|
+
handleError(`${METHODS[action]} ${url} failed because of "${reason}"`);
|
|
180
|
+
}).finally(() => {
|
|
165
181
|
// If we have a requested callback
|
|
166
182
|
if (this.requested) {
|
|
167
|
-
this.requested({ action, data, res, url
|
|
183
|
+
this.requested({ action, data, res, url });
|
|
168
184
|
}
|
|
169
185
|
});
|
|
170
|
-
// Init the request body
|
|
171
|
-
let xml = '';
|
|
172
|
-
// If we got data
|
|
173
|
-
if (data !== null) {
|
|
174
|
-
// If we're in GET mode
|
|
175
|
-
if (action === 'read') {
|
|
176
|
-
// Append the data as a param
|
|
177
|
-
url += '?d=' + encodeURIComponent(JSON.stringify(data));
|
|
178
|
-
}
|
|
179
|
-
// Else, DELETE, POST, PUT, just encode the data
|
|
180
|
-
else {
|
|
181
|
-
xml = JSON.stringify(data);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
// Open the request
|
|
185
|
-
xhr.open(ACTIONS_TO_METHODS[action], url);
|
|
186
|
-
// If we have a session token, add it as the Authorization header
|
|
187
|
-
if (this.token) {
|
|
188
|
-
xhr.setRequestHeader('Authorization', this.token);
|
|
189
|
-
}
|
|
190
|
-
// Set the Content-Type header
|
|
191
|
-
xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
|
|
192
|
-
// If we have a requesting callback, call it
|
|
193
|
-
if (this.requesting) {
|
|
194
|
-
this.requesting({ action, data, url, xhr });
|
|
195
|
-
}
|
|
196
|
-
// Send the request
|
|
197
|
-
xhr.send(xml);
|
|
198
186
|
});
|
|
199
187
|
}
|
|
200
188
|
/**
|
|
@@ -243,6 +231,9 @@ class Body {
|
|
|
243
231
|
case 'errorCode':
|
|
244
232
|
this.errorCode = callbacks.errorCode;
|
|
245
233
|
continue;
|
|
234
|
+
case 'noSession':
|
|
235
|
+
this.noSession = callbacks.noSession;
|
|
236
|
+
continue;
|
|
246
237
|
case 'requested':
|
|
247
238
|
this.requested = callbacks.requested;
|
|
248
239
|
continue;
|
|
@@ -277,7 +268,7 @@ class Body {
|
|
|
277
268
|
*
|
|
278
269
|
* Sets callback for whenever a request gets an error back
|
|
279
270
|
*
|
|
280
|
-
* @name
|
|
271
|
+
* @name onErrorCode
|
|
281
272
|
* @access public
|
|
282
273
|
* @param callback The function to call if there's an error
|
|
283
274
|
*/
|
|
@@ -340,6 +331,23 @@ class Body {
|
|
|
340
331
|
// Set the callback
|
|
341
332
|
this.requesting = callback;
|
|
342
333
|
}
|
|
334
|
+
/**
|
|
335
|
+
* On Warning
|
|
336
|
+
*
|
|
337
|
+
* Sets callback for whenever a request gets a warning back
|
|
338
|
+
*
|
|
339
|
+
* @name onWarning
|
|
340
|
+
* @access public
|
|
341
|
+
* @param callback The function to call if there's a warning
|
|
342
|
+
*/
|
|
343
|
+
onWarning(callback) {
|
|
344
|
+
// Make sure the callback is function
|
|
345
|
+
if (typeof callback !== 'function') {
|
|
346
|
+
throw new Error('onWarning() called with an invalid callback');
|
|
347
|
+
}
|
|
348
|
+
// Set the callback
|
|
349
|
+
this.warning = callback;
|
|
350
|
+
}
|
|
343
351
|
/**
|
|
344
352
|
* Read
|
|
345
353
|
*
|
|
@@ -388,28 +396,6 @@ class Body {
|
|
|
388
396
|
update(service, noun, data = null) {
|
|
389
397
|
return this.request('update', service, noun, data);
|
|
390
398
|
}
|
|
391
|
-
/**
|
|
392
|
-
* Verbose Off
|
|
393
|
-
*
|
|
394
|
-
* Called to turn verbose mode off
|
|
395
|
-
*
|
|
396
|
-
* @name verbose_off
|
|
397
|
-
* @access
|
|
398
|
-
*/
|
|
399
|
-
verbose_off() {
|
|
400
|
-
this.verbose = false;
|
|
401
|
-
}
|
|
402
|
-
/**
|
|
403
|
-
* Verbose On
|
|
404
|
-
*
|
|
405
|
-
* Called to turn verbose mode on
|
|
406
|
-
*
|
|
407
|
-
* @name verbose_on
|
|
408
|
-
* @access
|
|
409
|
-
*/
|
|
410
|
-
verbose_on() {
|
|
411
|
-
this.verbose = true;
|
|
412
|
-
}
|
|
413
399
|
}
|
|
414
400
|
// Create an instance of Body
|
|
415
401
|
const body = new Body();
|
package/{build → lib}/regex.js
RENAMED
|
@@ -8,6 +8,6 @@
|
|
|
8
8
|
* @created 2023-03-05
|
|
9
9
|
*/
|
|
10
10
|
// E-Mail address
|
|
11
|
-
export const EMAIL_ADDRESS =
|
|
11
|
+
export const EMAIL_ADDRESS = /^[^@\s]+@[^@\s]+\.[a-zA-Z0-9]{2,}$/;
|
|
12
12
|
// North American Phone Number
|
|
13
|
-
export const PHONE_NUMBER_NA =
|
|
13
|
+
export const PHONE_NUMBER_NA = /^\+?1?[ -]?\(?(\d{3})\)?[ -]?(\d{3})[ -]?(\d{4})$/;
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ouroboros/body",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Classes to communicate with Ouroboros Coding Inc. body services",
|
|
5
|
-
"main": "
|
|
6
|
-
"types": "
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"types": "lib/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "tslint -p tsconfig.json && tsc",
|
|
9
|
-
"clean": "rm
|
|
9
|
+
"clean": "rm lib/*",
|
|
10
10
|
"for_local": "npm install; tslint -p tsconfig.json && tsc; rm -Rf node_modules",
|
|
11
11
|
"test": "echo \"Error: no test specified.\" && exit 1"
|
|
12
12
|
},
|
|
@@ -26,9 +26,6 @@
|
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"tslint": "^6.1.3",
|
|
28
28
|
"tslint-config-prettier": "^1.18.0",
|
|
29
|
-
"typescript": "^4.
|
|
30
|
-
},
|
|
31
|
-
"dependencies": {
|
|
32
|
-
"xhr2": "^0.2.1"
|
|
29
|
+
"typescript": "^4.9.5"
|
|
33
30
|
}
|
|
34
31
|
}
|
package/releases.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# @ouroboros/body releases
|
|
2
|
+
|
|
3
|
+
## 1.2.0
|
|
4
|
+
- Moved generated .js and .d.ts files into lib/ instead of build/, this changes the "main" from "build/index.js" to "lib/index.js".
|
|
5
|
+
- Removed `xhr2` from the project and replaced `XMLHttpRequest` with `fetch`.
|
|
6
|
+
- Removed `xhr` from `onRequestedStruct` and `onRequestingStruct`.
|
|
7
|
+
- Removed `Body.verbose_on()` and `Body.verbose_off()` functions as well as all `console.log` calls.
|
|
8
|
+
- Added missing `Body.onWarning` function.
|
|
9
|
+
- Added "noSession" as a valid key to the `on` function's argument.
|
|
10
|
+
- Added check in `Body.request` to trigger `this.warning` if a warning is returned.
|
|
11
|
+
- Added `domain`, `on`, and `onWarning` functions to `Service` class, each passes their arguments to, and returns from, the `body` function of the same name.
|
|
12
|
+
- Changed `body.domain` to getter/setter instead of just setter.
|
package/src/Service.ts
CHANGED
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
import body from './';
|
|
13
13
|
|
|
14
14
|
// Types
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
onCallbacks, onError, onErrorCode, onRequested, onRequesting, onWarning
|
|
17
|
+
} from './';
|
|
16
18
|
|
|
17
19
|
/**
|
|
18
20
|
* Service
|
|
@@ -70,6 +72,33 @@ export default class Service {
|
|
|
70
72
|
return body.request('delete', this.service, noun, data);
|
|
71
73
|
}
|
|
72
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Domain
|
|
77
|
+
*
|
|
78
|
+
* Set/Gets the current domain
|
|
79
|
+
*
|
|
80
|
+
* @name domain
|
|
81
|
+
* @access public
|
|
82
|
+
* @param domain The domain to make all calls to
|
|
83
|
+
* @returns void
|
|
84
|
+
*/
|
|
85
|
+
domain(domain?: string): void | string {
|
|
86
|
+
return body.domain(domain);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* On
|
|
91
|
+
*
|
|
92
|
+
* Called to set multiple events at once
|
|
93
|
+
*
|
|
94
|
+
* @name on
|
|
95
|
+
* @access public
|
|
96
|
+
* @param callbacks A name to callback object to set multiple events
|
|
97
|
+
*/
|
|
98
|
+
on(callbacks: onCallbacks): void {
|
|
99
|
+
return body.on(callbacks);
|
|
100
|
+
}
|
|
101
|
+
|
|
73
102
|
/**
|
|
74
103
|
* On Error
|
|
75
104
|
*
|
|
@@ -120,6 +149,19 @@ export default class Service {
|
|
|
120
149
|
return body.onRequesting(callback);
|
|
121
150
|
}
|
|
122
151
|
|
|
152
|
+
/**
|
|
153
|
+
* On Warning
|
|
154
|
+
*
|
|
155
|
+
* Sets callback for whenever a request gets a warning back
|
|
156
|
+
*
|
|
157
|
+
* @name onWarning
|
|
158
|
+
* @access public
|
|
159
|
+
* @param callback The function to call if there's a warning
|
|
160
|
+
*/
|
|
161
|
+
onWarning(callback: onWarning): void {
|
|
162
|
+
return body.onWarning(callback);
|
|
163
|
+
}
|
|
164
|
+
|
|
123
165
|
/**
|
|
124
166
|
* Read
|
|
125
167
|
*
|
package/src/constants.ts
CHANGED
|
@@ -9,9 +9,10 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
// Empty UUID
|
|
12
|
-
export const
|
|
12
|
+
export const EMPTY_TUUID = '00000000000040008000000000000000';
|
|
13
|
+
export const EMPTY_UUID = '00000000-0000-4000-8000-000000000000';
|
|
13
14
|
|
|
14
15
|
// Seconds
|
|
15
|
-
export const SECONDS_HOUR = 3600
|
|
16
|
-
export const SECONDS_DAY = 86400
|
|
17
|
-
export const SECONDS_WEEK = 604800
|
|
16
|
+
export const SECONDS_HOUR = 3600;
|
|
17
|
+
export const SECONDS_DAY = 86400;
|
|
18
|
+
export const SECONDS_WEEK = 604800;
|