@hkdigital/lib-sveltekit 0.0.66 → 0.0.68

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.
@@ -1,4 +1,5 @@
1
1
  export const ACCEPT: "accept";
2
2
  export const CONTENT_TYPE: "content-type";
3
+ export const CONTENT_LENGTH: "content-length";
3
4
  export const AUTHORIZATION: "authorization";
4
5
  export const WWW_AUTHENTICATE: "www-authenticate";
@@ -1,5 +1,6 @@
1
1
  export const ACCEPT = 'accept';
2
2
  export const CONTENT_TYPE = 'content-type';
3
- export const AUTHORIZATION = 'authorization';
3
+ export const CONTENT_LENGTH = 'content-length';
4
4
 
5
+ export const AUTHORIZATION = 'authorization';
5
6
  export const WWW_AUTHENTICATE = 'www-authenticate';
@@ -1,3 +1,9 @@
1
+ /**
2
+ * @callback requestHandler
3
+ * @param {AbortController} controller
4
+ * @param {( reason?: Error ) => void} abort
5
+ * @param {( delayMs: number) => void} timeout
6
+ */
1
7
  /**
2
8
  * Make GET request
3
9
  *
@@ -13,8 +19,7 @@
13
19
  *
14
20
  * e.g. options.headers = { "content-type": "application/json" }
15
21
  *
16
- * @param {function} [_.requestHandler]
17
- * If defined, this function will receive the abort handler function
22
+ * @param {requestHandler} [_.requestHandler]
18
23
  *
19
24
  * @param {number} [_.timeoutMs]
20
25
  * If defined, this request will abort after the specified number of
@@ -37,8 +42,7 @@ export function httpGet({ url, urlSearchParams, headers, requestHandler, timeout
37
42
  *
38
43
  * e.g. options.headers = { "content-type": "application/json" }
39
44
  *
40
- * @param {function} [_.requestHandler]
41
- * If defined, this function will receive the abort handler function
45
+ * @param {requestHandler} [_.requestHandler]
42
46
  *
43
47
  * @param {number} [_.timeoutMs]
44
48
  * If defined, this request will abort after the specified number of
@@ -67,8 +71,7 @@ export function httpPost({ url, body, headers, requestHandler, timeoutMs }: stri
67
71
  *
68
72
  * e.g. options.headers = { "content-type": "application/json" }
69
73
  *
70
- * @param {( { controller: AbortController, abort: ( reason?: Error ) => void, timeout: number } )=> void} [_.requestHandler]
71
- * If defined, this function will receive the abort handler function
74
+ * @param {requestHandler} [_.requestHandler]
72
75
  *
73
76
  * @param {number} [_.timeoutMs]
74
77
  * If defined, this request will abort after the specified number of
@@ -82,3 +85,12 @@ export function httpPost({ url, body, headers, requestHandler, timeoutMs }: stri
82
85
  * @returns {Promise<*>} responsePromise
83
86
  */
84
87
  export function httpRequest({ method, url, urlSearchParams, body, headers, requestHandler, timeoutMs }: string | URL): Promise<any>;
88
+ /**
89
+ * Get the response size from the content-length response header
90
+ *
91
+ * @param {Response} response
92
+ *
93
+ * @returns {number} response size or 0 if unknown
94
+ */
95
+ export function getResponseSize(response: Response): number;
96
+ export type requestHandler = (controller: AbortController, abort: (reason?: Error) => void, timeout: (delayMs: number) => void) => any;
@@ -1,7 +1,7 @@
1
1
  import { METHOD_GET, METHOD_POST } from '../../constants/http/methods.js';
2
2
 
3
3
  import { APPLICATION_JSON } from '../../constants/mime/application.js';
4
- import { CONTENT_TYPE } from '../../constants/http/headers.js';
4
+ import { CONTENT_TYPE, CONTENT_LENGTH } from '../../constants/http/headers.js';
5
5
 
6
6
  import { AbortError, TimeoutError } from '../../constants/errors/api.js';
7
7
 
@@ -11,6 +11,13 @@ import { toURL } from './url.js';
11
11
  import { setRequestHeaders } from './headers.js';
12
12
  import { waitForAndCheckResponse } from './response.js';
13
13
 
14
+ /**
15
+ * @callback requestHandler
16
+ * @param {AbortController} controller
17
+ * @param {( reason?: Error ) => void} abort
18
+ * @param {( delayMs: number) => void} timeout
19
+ */
20
+
14
21
  /**
15
22
  * Make GET request
16
23
  *
@@ -26,8 +33,7 @@ import { waitForAndCheckResponse } from './response.js';
26
33
  *
27
34
  * e.g. options.headers = { "content-type": "application/json" }
28
35
  *
29
- * @param {function} [_.requestHandler]
30
- * If defined, this function will receive the abort handler function
36
+ * @param {requestHandler} [_.requestHandler]
31
37
  *
32
38
  * @param {number} [_.timeoutMs]
33
39
  * If defined, this request will abort after the specified number of
@@ -62,8 +68,7 @@ export async function httpGet({ url, urlSearchParams, headers, requestHandler, t
62
68
  *
63
69
  * e.g. options.headers = { "content-type": "application/json" }
64
70
  *
65
- * @param {function} [_.requestHandler]
66
- * If defined, this function will receive the abort handler function
71
+ * @param {requestHandler} [_.requestHandler]
67
72
  *
68
73
  * @param {number} [_.timeoutMs]
69
74
  * If defined, this request will abort after the specified number of
@@ -106,8 +111,7 @@ export async function httpPost({ url, body = null, headers, requestHandler, time
106
111
  *
107
112
  * e.g. options.headers = { "content-type": "application/json" }
108
113
  *
109
- * @param {( { controller: AbortController, abort: ( reason?: Error ) => void, timeout: number } )=> void} [_.requestHandler]
110
- * If defined, this function will receive the abort handler function
114
+ * @param {requestHandler} [_.requestHandler]
111
115
  *
112
116
  * @param {number} [_.timeoutMs]
113
117
  * If defined, this request will abort after the specified number of
@@ -261,5 +265,23 @@ export async function httpRequest({
261
265
  }
262
266
  }
263
267
 
268
+ // response promise
264
269
  return promise;
265
270
  }
271
+
272
+ /**
273
+ * Get the response size from the content-length response header
274
+ *
275
+ * @param {Response} response
276
+ *
277
+ * @returns {number} response size or 0 if unknown
278
+ */
279
+ export function getResponseSize(response) {
280
+ const sizeStr = response.headers.get(CONTENT_LENGTH);
281
+
282
+ if (!sizeStr) {
283
+ return 0;
284
+ }
285
+
286
+ return parseInt(sizeStr, 10);
287
+ }
@@ -3,7 +3,7 @@ import * as expect from '../expect/index.js';
3
3
 
4
4
  import { WWW_AUTHENTICATE } from '../../constants/http/headers.js';
5
5
 
6
- import { toURL } from './url.js';
6
+ import { href } from './url.js';
7
7
 
8
8
  import { getErrorFromResponse } from './errors.js';
9
9
 
@@ -19,8 +19,6 @@ import { getErrorFromResponse } from './errors.js';
19
19
  export async function expectResponseOk(response, url) {
20
20
  expect.object(response);
21
21
 
22
- url = toURL(url);
23
-
24
22
  // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/200
25
23
  // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/201
26
24
 
@@ -28,7 +26,7 @@ export async function expectResponseOk(response, url) {
28
26
  if (!response.ok) {
29
27
  throw new ResponseError(
30
28
  `Server returned - ${response.status} ${response.statusText} ` +
31
- `[response.ok=false] [url=${decodeURI(url.href)}]`
29
+ `[response.ok=false] [url=${href(url)}]`
32
30
  );
33
31
  }
34
32
 
@@ -49,7 +47,7 @@ export async function expectResponseOk(response, url) {
49
47
  errorMessage += ` (${authValue})`;
50
48
  }
51
49
 
52
- errorMessage += ` [url=${decodeURI(url.href)}]`;
50
+ errorMessage += ` [url=${href(url)}]`;
53
51
 
54
52
  throw new Error(errorMessage);
55
53
  }
@@ -59,7 +57,7 @@ export async function expectResponseOk(response, url) {
59
57
  const error = await getErrorFromResponse(response);
60
58
 
61
59
  throw new ResponseError(
62
- `Server returned - ${response.status} ${response.statusText} ` + `[url=${decodeURI(url.href)}]`,
60
+ `Server returned - ${response.status} ${response.statusText} ` + `[url=${href(url)}]`,
63
61
  { cause: error }
64
62
  );
65
63
  }
@@ -80,8 +78,6 @@ export async function expectResponseOk(response, url) {
80
78
  export async function waitForAndCheckResponse(responsePromise, url) {
81
79
  expect.promise(responsePromise);
82
80
 
83
- url = toURL(url);
84
-
85
81
  let response;
86
82
 
87
83
  try {
@@ -93,7 +89,7 @@ export async function waitForAndCheckResponse(responsePromise, url) {
93
89
  }
94
90
  } catch (e) {
95
91
  if (e instanceof TypeError || response?.ok === false) {
96
- throw new ResponseError(`A network error occurred for request [${decodeURI(url.href)}]`, {
92
+ throw new ResponseError(`A network error occurred for request [${href(url)}]`, {
97
93
  cause: e
98
94
  });
99
95
  } else {
@@ -1,8 +1,25 @@
1
1
  /**
2
- * Ensure to return an URL instance
2
+ * Returns an URL instance
3
+ * - Prefixes the URL with the current orign if the url is relative
3
4
  *
4
5
  * @param {string|URL} url
5
6
  *
6
7
  * @returns {URL} url instance
7
8
  */
8
9
  export function toURL(url: string | URL): URL;
10
+ /**
11
+ * Checks if the url starts with a protocol specification such
12
+ * as https://
13
+ *
14
+ * @param {string} url
15
+ *
16
+ * @return {boolean} true if the value looks like an array
17
+ */
18
+ export function hasProtocol(url: string): boolean;
19
+ /**
20
+ * Convert an url to an absolute url and apply decodeURI to
21
+ * convert URI encoded characters to normal characters
22
+ *
23
+ * @param {string} url
24
+ */
25
+ export function href(url: string): string;
@@ -1,7 +1,8 @@
1
1
  import { TypeOrValueError } from '../../constants/errors/index.js';
2
2
 
3
3
  /**
4
- * Ensure to return an URL instance
4
+ * Returns an URL instance
5
+ * - Prefixes the URL with the current orign if the url is relative
5
6
  *
6
7
  * @param {string|URL} url
7
8
  *
@@ -9,7 +10,12 @@ import { TypeOrValueError } from '../../constants/errors/index.js';
9
10
  */
10
11
  export function toURL(url) {
11
12
  if (typeof url === 'string') {
12
- return new URL(url);
13
+ if (hasProtocol(url)) {
14
+ return new URL(url);
15
+ } else {
16
+ // Use location.origin aas baseUrl
17
+ return new URL(url, location.origin);
18
+ }
13
19
  } else if (!(url instanceof URL)) {
14
20
  throw new TypeOrValueError('Missing or invalid parameter [url]');
15
21
  }
@@ -17,3 +23,30 @@ export function toURL(url) {
17
23
  // already an URL instance
18
24
  return url;
19
25
  }
26
+
27
+ /**
28
+ * Checks if the url starts with a protocol specification such
29
+ * as https://
30
+ *
31
+ * @param {string} url
32
+ *
33
+ * @return {boolean} true if the value looks like an array
34
+ */
35
+ export function hasProtocol(url) {
36
+ if (/^([a-zA-Z]{2,})s?:\/\//.test(url)) {
37
+ return true;
38
+ }
39
+
40
+ return false;
41
+ }
42
+
43
+ /**
44
+ * Convert an url to an absolute url and apply decodeURI to
45
+ * convert URI encoded characters to normal characters
46
+ *
47
+ * @param {string} url
48
+ */
49
+ export function href(url) {
50
+ const urlObj = toURL(url);
51
+ return decodeURI(urlObj.href);
52
+ }
@@ -1,3 +1,4 @@
1
+ /** Exports */
1
2
  /**
2
3
  * Check if a value looks like an array
3
4
  *
@@ -1,4 +1,4 @@
1
- /* ---------------------------------------------------------------- Internals */
1
+ /** Internals */
2
2
 
3
3
  //
4
4
  // @see https://developer.mozilla.org/
@@ -7,9 +7,7 @@
7
7
  const AsyncFunction = Object.getPrototypeOf(async () => {}).constructor;
8
8
  const objectToString = Object.prototype.toString;
9
9
 
10
- /* ------------------------------------------------------------------ Exports */
11
-
12
- // ---------------------------------------------------------------------- Method
10
+ /** Exports */
13
11
 
14
12
  /**
15
13
  * Check if a value looks like an array
@@ -30,8 +28,6 @@ export function isArrayLike(item) {
30
28
  return false;
31
29
  }
32
30
 
33
- // ---------------------------------------------------------------------- Method
34
-
35
31
  /**
36
32
  * Check if a value is an Arguments object
37
33
  *
@@ -43,8 +39,6 @@ export function isArguments(value) {
43
39
  return objectToString.call(value) === '[object Arguments]';
44
40
  }
45
41
 
46
- // ---------------------------------------------------------------------- Method
47
-
48
42
  /**
49
43
  * Check if a value is an array that only contains primitives
50
44
  * - A primitive is a not-object value
@@ -68,8 +62,6 @@ export function isArrayOfPrimitives(arr) {
68
62
  return true;
69
63
  }
70
64
 
71
- // ---------------------------------------------------------------------- Method
72
-
73
65
  /**
74
66
  * Check if the supplied value is async iterable
75
67
  * - Aync iterable objects must implement the "@@asyncIterator" method
@@ -86,8 +78,6 @@ export function isAsyncIterator(value) {
86
78
  return true;
87
79
  }
88
80
 
89
- // ---------------------------------------------------------------------- Method
90
-
91
81
  /**
92
82
  * Check if the supplied value is an async function
93
83
  * - Returns true for functions declared as "async function" or
@@ -108,8 +98,6 @@ export function isAsyncFunction(value) {
108
98
  return false;
109
99
  }
110
100
 
111
- // ---------------------------------------------------------------------- Method
112
-
113
101
  /**
114
102
  * Check if the supplied value is iterable
115
103
  * - Iterable objects must implement the "@@iterator" method
@@ -127,8 +115,6 @@ export function isIterable(value) {
127
115
  return true;
128
116
  }
129
117
 
130
- // ---------------------------------------------------------------------- Method
131
-
132
118
  /**
133
119
  * Check if the supplied value is an object bu not a promise
134
120
  * - Promises return false
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hkdigital/lib-sveltekit",
3
- "version": "0.0.66",
3
+ "version": "0.0.68",
4
4
  "author": "Jens Kleinhout, HKdigital (https://hkdigital.nl)",
5
5
  "license": "ISC",
6
6
  "repository": {