@gandalan/weblibs 1.1.52 → 1.1.54

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/api/authUtils.js CHANGED
@@ -2,9 +2,36 @@
2
2
  import { jwtDecode } from "jwt-decode";
3
3
  import validator from "validator";
4
4
 
5
+ /**
6
+ * @typedef {Object} Settings
7
+ * @property {string} appToken - The application token.
8
+ * @property {string} mandantGuid - The mandant GUID.
9
+ * @property {string} apiBaseurl - The base URL for the API.
10
+ * @property {string} authUrl - The authentication URL.
11
+ */
12
+
13
+ /**
14
+ * the current JWT token (encoded)
15
+ *
16
+ * @type {string}
17
+ */
5
18
  export let currentToken = undefined;
19
+
20
+ /**
21
+ * the current refresh token (UUID v4)
22
+ *
23
+ * @type {string}
24
+ */
6
25
  export let currentRefreshToken = undefined;
7
26
 
27
+ /**
28
+ * initializes the API client with the given appToken
29
+ *
30
+ * @export
31
+ * @async
32
+ * @param {string} appToken, UUID v4 format
33
+ * @returns {Settings} settings object
34
+ */
8
35
  export async function initIDAS(appToken)
9
36
  {
10
37
  if (!validator.isUUID(appToken))
@@ -59,6 +86,13 @@ export async function initIDAS(appToken)
59
86
  return settings;
60
87
  }
61
88
 
89
+ /**
90
+ * sets up authentication
91
+ *
92
+ * @export
93
+ * @async
94
+ * @param {Settings} settings
95
+ */
62
96
  export async function setup(settings)
63
97
  {
64
98
  console.log("Setup IDAS");
@@ -97,6 +131,12 @@ export async function setup(settings)
97
131
  console.log("Setup finished", settings);
98
132
  }
99
133
 
134
+ /**
135
+ * starts a timer to refresh the JWT token before it expires
136
+ *
137
+ * @private
138
+ * @type {*}
139
+ */
100
140
  let timerRef = undefined;
101
141
  function startRefreshTimer(settings)
102
142
  {
@@ -119,6 +159,13 @@ function startRefreshTimer(settings)
119
159
  }, 5000);
120
160
  }
121
161
 
162
+ /**
163
+ * checks if the current JWT token is invalid
164
+ *
165
+ * @export
166
+ * @param {Settings} settings
167
+ * @returns {boolean}
168
+ */
122
169
  export function isInvalid(settings)
123
170
  {
124
171
  if (!currentToken)
@@ -136,6 +183,13 @@ export function isInvalid(settings)
136
183
  return true;
137
184
  }
138
185
 
186
+ /**
187
+ * tries to renew the JWT token
188
+ *
189
+ * @export
190
+ * @async
191
+ * @param {Settings} settings
192
+ */
139
193
  export async function tryRenew(settings)
140
194
  {
141
195
  console.log("Try to refresh");
@@ -173,6 +227,12 @@ export async function tryRenew(settings)
173
227
  }
174
228
  }
175
229
 
230
+ /**
231
+ * redirects to the login page
232
+ *
233
+ * @export
234
+ * @param {Settings} settings
235
+ */
176
236
  export function redirectToLogin(settings, authPath)
177
237
  {
178
238
  const authEndpoint = (new URL(window.location.href).origin) + authPath;
package/api/fluentApi.js CHANGED
@@ -1,9 +1,42 @@
1
1
  import { jwtDecode } from "jwt-decode";
2
-
2
+ import { restClient } from "./fluentRestClient";
3
+ import { authBuilder } from "./fluentAuthBuilder";
4
+
5
+ /**
6
+ * @typedef {Object} EnvironmentConfig
7
+ * @property {string} name - The environment name.
8
+ * @property {string} version - The version number.
9
+ * @property {string} cms - The CMS URL.
10
+ * @property {string} idas - The IDAS API URL.
11
+ * @property {string} store - The store API URL.
12
+ * @property {string} docs - The documentation URL.
13
+ * @property {string} notify - The notification service URL.
14
+ * @property {string} feedback - The feedback service URL.
15
+ * @property {string} helpcenter - The help center URL.
16
+ * @property {string} reports - The reports service URL.
17
+ * @property {string} webhookService - The webhook service URL.
18
+ */
19
+
20
+ /**
21
+ * buffer for environment data
22
+ * @private
23
+ * @type {Object.<string, EnvironmentConfig>}
24
+ */
3
25
  const envs = {};
4
26
 
27
+ /**
28
+ * configure the time before token expiry to renew
29
+ * @type {number}
30
+ */
5
31
  const JWT_SAFE_RENEWAL = 30; // seconds before token expiry to renew
6
32
 
33
+ /**
34
+ * fetches the environment data from the hub
35
+ * @export
36
+ * @async
37
+ * @param {string} [env="", env="dev", env="staging", env="produktiv"]
38
+ * @returns {Promise<EnvironmentConfig>}
39
+ */
7
40
  export async function fetchEnv(env = "") {
8
41
  if (!(env in envs)) {
9
42
  const hubUrl = `https://connect.idas-cloudservices.net/api/Endpoints?env=${env}`;
@@ -15,17 +48,37 @@ export async function fetchEnv(env = "") {
15
48
  return envs[env];
16
49
  }
17
50
 
51
+ /**
52
+ * @typedef {Object} JwtTokenExt
53
+ * @property {string} id
54
+ * @property {string} refreshToken
55
+ */
56
+
57
+ /**
58
+ * decode the JWT token and return the refresh token
59
+ * @export
60
+ * @param {string} token
61
+ * @returns {string}
62
+ */
18
63
  export function getRefreshToken(token) {
19
- const decoded = jwtDecode(token);
64
+ const decoded = /** @type {JwtTokenExt} */(jwtDecode(token));
20
65
  return decoded.refreshToken;
21
66
  }
22
67
 
68
+ /**
69
+ * check if the token is still valid
70
+ * - checks the expiry date and the JWT_SAFE_RENEWAL buffer
71
+ *
72
+ * @export
73
+ * @param {string} token
74
+ * @returns {boolean}
75
+ */
23
76
  export function isTokenValid(token)
24
77
  {
25
78
  try
26
79
  {
27
80
  const decoded = jwtDecode(token);
28
- if (!decoded)
81
+ if (!decoded || !decoded.exp)
29
82
  throw new Error("Invalid token");
30
83
  return (decoded.exp - JWT_SAFE_RENEWAL > Date.now() / 1000);
31
84
  }
@@ -34,133 +87,37 @@ export function isTokenValid(token)
34
87
  }
35
88
  }
36
89
 
37
- export function authBuilder() {
38
- return {
39
- authUrl: "",
40
- appToken: "",
41
- token: "",
42
- refreshToken: "",
43
-
44
- useAppToken(appToken = "") {
45
- this.appToken = appToken; return this;
46
- },
47
-
48
- useBaseUrl(authUrl = "") {
49
- this.authUrl = authUrl; return this;
50
- },
51
-
52
- useToken(jwtToken = "") {
53
- this.token = jwtToken; return this;
54
- },
55
-
56
- useRefreshToken(storedRefreshToken = "") {
57
- this.refreshToken = storedRefreshToken; return this;
58
- },
59
-
60
- async authenticate(username = "", password = "")
61
- {
62
- console.log("authenticating:", this.token ? `token set, exp: ${jwtDecode(this.token).exp - (Date.now() / 1000)}` : "no token,", this.refreshToken);
63
-
64
- if (this.token && isTokenValid(this.token))
65
- return this.token;
66
-
67
- if (this.token && !this.refreshToken)
68
- this.refreshToken = getRefreshToken(this.token);
69
-
70
- if (this.refreshToken) {
71
- try {
72
- const temptoken = await this.tryRefreshToken(this.refreshToken);
73
- if (temptoken) {
74
- this.token = temptoken;
75
- this.refreshToken = getRefreshToken(temptoken);
76
- }
77
- } catch {
78
- // if refresh failed, we'll return the current token
79
- // - should still be valid for a while
80
- }
81
- return this.token;
82
- }
83
-
84
- if (username && password) {
85
- const payload = { "Email": username, "Password": password, "AppToken": this.appToken };
86
- const res = await fetch(`${this.authUrl}/LoginJwt`,
87
- { method: "POST", body: JSON.stringify(payload), headers: { "Content-Type": "application/json" } });
88
- const temptoken = await res.json();
89
- if (temptoken) {
90
- this.token = temptoken;
91
- return this.token;
92
- }
93
- }
94
-
95
- throw new Error("not authenticated");
96
- },
97
-
98
- async tryRefreshToken(refreshToken = "") {
99
- const payload = { "Token": refreshToken };
100
- const res = await fetch(`${this.authUrl}/LoginJwt/Refresh`,
101
- {
102
- method: "PUT",
103
- body: JSON.stringify(payload),
104
- headers: { "Content-Type": "application/json" },
105
- });
106
- return res.ok ? await res.json() : null;
107
- },
108
- }
109
- }
110
-
111
- export function restClient()
112
- {
113
- return {
114
- baseUrl: "",
115
- token: "",
116
-
117
- useBaseUrl(url = "") {
118
- this.baseUrl = url; return this;
119
- },
120
-
121
- useToken(jwtToken = "") {
122
- this.token = jwtToken; return this;
123
- },
124
-
125
- async get(url = "", auth = true) {
126
- const finalUrl = `${this.baseUrl}/${url}`;
127
- const headers = this.token ? { "Authorization": `Bearer ${this.token}` } : {};
128
- const res = await fetch(finalUrl, { method: "GET", headers });
129
- if (res.ok)
130
- return await res.json();
131
- throw new Error(`GET ${finalUrl} failed: ${res.status} ${res.statusText}`);
132
- },
133
-
134
- async put(url = "", payload = {}) {
135
- const finalUrl = `${this.baseUrl}/${url}`;
136
- const headers = this.token ? { "Authorization": `Bearer ${this.token}`, "Content-Type": "application/json" } : {};
137
- const res = await fetch(finalUrl, { method: "PUT", body: JSON.stringify(payload), headers });
138
- if (res.ok)
139
- return await res.json();
140
- throw new Error(`PUT ${finalUrl} failed: ${res.status} ${res.statusText}`);
141
- },
142
-
143
- async post(url = "", payload = {}) {
144
- const finalUrl = `${this.baseUrl}/${url}`;
145
- const headers = this.token ? { "Authorization": `Bearer ${this.token}`, "Content-Type": "application/json" } : {};
146
- const res = await fetch(finalUrl, { method: "POST", body: JSON.stringify(payload), headers });
147
- if (res.ok)
148
- return await res.json();
149
- throw new Error(`POST ${finalUrl} failed: ${res.status} ${res.statusText}`);
150
- },
151
-
152
- async delete(url = "") {
153
- const finalUrl = `${this.baseUrl}/${url}`;
154
- const headers = this.token ? { "Authorization": `Bearer ${this.token}` } : {};
155
- const res = await fetch(finalUrl, { method: "DELETE", headers });
156
- if (res.ok)
157
- return await res.json();
158
- throw new Error(`DELETE ${finalUrl} failed: ${res.status} ${res.statusText}`);
159
- }
160
- }
161
- }
162
-
163
- export function api() {
90
+ /**
91
+ * @typedef {Object} FluentApi
92
+ * @property {string} baseUrl - The base URL for API requests.
93
+ * @property {string} authUrl - The authentication URL.
94
+ * @property {string} env - The environment setting.
95
+ * @property {string} appToken - The application token.
96
+ * @property {string} storageEntry - The storage entry.
97
+ * @property {string} token - The JWT token for authorization.
98
+ * @property {string} refreshToken - The refresh token.
99
+ * @property {function(string) : FluentApi} useEnvironment - Sets the environment and returns the FluentApi object.
100
+ * @property {function(string) : FluentApi} useAppToken - Sets the application token and returns the FluentApi object.
101
+ * @property {function(string) : FluentApi} useBaseUrl - Sets the base URL for API requests and returns the FluentApi object.
102
+ * @property {function(string) : FluentApi} useAuthUrl - Sets the authentication URL and returns the FluentApi object.
103
+ * @property {function(string) : FluentApi} useToken - Sets the JWT token for authorization and returns the FluentApi object.
104
+ * @property {function(string) : FluentApi} useRefreshToken - Sets the refresh token and returns the FluentApi object.
105
+ * @property {function() : FluentApi} useGlobalAuth - Uses global authentication tokens and returns the FluentApi object.
106
+ * @property {function(string) : object|Array<any>} get - Async function to perform GET requests.
107
+ * @property {function(string, object) : object|Array<any>} put - Async function to perform PUT requests with a payload.
108
+ * @property {function(string, object) : object|Array<any>} post - Async function to perform POST requests with a payload.
109
+ * @property {function(string) : object|Array<any>} delete - Async function to perform DELETE requests.
110
+ * @property {Function} ensureAuthenticated - Ensures the user is authenticated before making a request.
111
+ * @property {Function} ensureBaseUrlIsSet - Ensures the base URL is set before making a request.
112
+ * @property {Function} redirectToLogin - Redirects to the login page.
113
+ */
114
+
115
+ /**
116
+ * Builds a client to communicate with the IDAS api in a fluent syntax
117
+ *
118
+ * @return {FluentApi}
119
+ */
120
+ export function createApi() {
164
121
  return {
165
122
  baseUrl: "",
166
123
  authUrl: "",
@@ -170,59 +127,143 @@ export function api() {
170
127
  token: "",
171
128
  refreshToken: "",
172
129
 
130
+ /**
131
+ * set the environment to use
132
+ *
133
+ * @param {string} env
134
+ * @return {FluentApi}
135
+ */
173
136
  useEnvironment(env = "") {
174
137
  this.env = env; return this;
175
138
  },
176
139
 
140
+ /**
141
+ * set the app token to use
142
+ *
143
+ * @param {string} [newApptoken=""]
144
+ * @return {FluentApi}
145
+ */
177
146
  useAppToken(newApptoken = "") {
178
147
  this.appToken = newApptoken; return this;
179
148
  },
180
149
 
150
+ /**
151
+ * set the base URL for API requests
152
+ *
153
+ * @param {string} [url=""]
154
+ * @return {FluentApi}
155
+ */
181
156
  useBaseUrl(url = "") {
182
157
  this.baseUrl = url; return this;
183
158
  },
184
159
 
160
+ /**
161
+ * set the authentication URL
162
+ *
163
+ * @param {string} [url=""]
164
+ * @return {FluentApi}
165
+ */
185
166
  useAuthUrl(url = "") {
186
167
  this.authUrl = url; return this;
187
168
  },
188
169
 
170
+ /**
171
+ * set the JWT token for authorization
172
+ *
173
+ * @param {string} [jwtToken=""]
174
+ * @return {FluentApi}
175
+ */
189
176
  useToken(jwtToken = "") {
190
177
  this.token = jwtToken; return this;
191
178
  },
192
179
 
180
+ /**
181
+ * set the refresh token
182
+ *
183
+ * @param {string} [storedRefreshToken=""]
184
+ * @return {FluentApi}
185
+ */
193
186
  useRefreshToken(storedRefreshToken = "") {
194
187
  this.refreshToken = storedRefreshToken; return this;
195
188
  },
196
-
189
+
190
+ /**
191
+ * tell the client to use the global authentication tokens
192
+ *
193
+ * @return {FluentApi}
194
+ */
197
195
  useGlobalAuth() {
196
+ // eslint-disable-next-line no-undef
197
+ this.token = globalThis.idasTokens.token;
198
198
  // eslint-disable-next-line no-undef
199
- this.token = globalThis.idasTokens.token; this.refreshToken = globalThis.idasTokens.refreshToken; return this;
199
+ this.refreshToken = globalThis.idasTokens.refreshToken;
200
+ return this;
200
201
  },
201
-
202
+
203
+ /**
204
+ * GET request, ensure authenticated if needed
205
+ *
206
+ * @async
207
+ * @param {string} [url=""]
208
+ * @param {boolean} [auth=true]
209
+ * @returns {Promise<Object>}
210
+ */
202
211
  async get(url = "", auth = true) {
203
212
  if (auth)
204
213
  await this.ensureAuthenticated();
205
214
  return restClient().useBaseUrl(this.baseUrl).useToken(this.token).get(url);
206
215
  },
207
216
 
217
+ /**
218
+ * PUT request, ensure authenticated if needed
219
+ *
220
+ * @async
221
+ * @param {string} [url=""]
222
+ * @param {Object} [payload={}]
223
+ * @param {boolean} [auth=true]
224
+ * @returns {Promise<Object>}
225
+ */
208
226
  async put(url = "", payload = {}, auth = true) {
209
227
  if (auth)
210
228
  await this.ensureAuthenticated();
211
229
  return restClient().useBaseUrl(this.baseUrl).useToken(this.token).put(url, payload);
212
230
  },
213
231
 
232
+ /**
233
+ * POST request, ensure authenticated if needed
234
+ *
235
+ * @async
236
+ * @param {string} [url=""]
237
+ * @param {Object} [payload={}]
238
+ * @param {boolean} [auth=true]
239
+ * @returns {Promise<Object>}
240
+ */
214
241
  async post(url = "", payload = {}, auth = true) {
215
242
  if (auth)
216
243
  await this.ensureAuthenticated();
217
244
  return restClient().useBaseUrl(this.baseUrl).useToken(this.token).post(url, payload);
218
245
  },
219
-
246
+
247
+ /**
248
+ * DELETE request, ensure authenticated if needed
249
+ *
250
+ * @async
251
+ * @param {string} [url=""]
252
+ * @param {boolean} [auth=true]
253
+ * @returns {Promise<Object>}
254
+ */
220
255
  async delete(url = "", auth = true) {
221
256
  if (auth)
222
257
  await this.ensureAuthenticated();
223
258
  return restClient().useBaseUrl(this.baseUrl).useToken(this.token).delete(url);
224
259
  },
225
260
 
261
+ /**
262
+ * Ensure the user is authenticated before making a request
263
+ *
264
+ * @async
265
+ * @private
266
+ */
226
267
  async ensureAuthenticated() {
227
268
  if (this.token && isTokenValid(this.token))
228
269
  return;
@@ -252,7 +293,14 @@ export function api() {
252
293
  this.redirectToLogin();
253
294
  }
254
295
  },
255
-
296
+
297
+ /**
298
+ * Ensure the base URL is set before making a request. If not set,
299
+ * retrieve the environment data and set the base URL.
300
+ *
301
+ * @async
302
+ * @private
303
+ */
256
304
  async ensureBaseUrlIsSet() {
257
305
  if (this.env && (!this.baseUrl || !this.authUrl)) {
258
306
  const envInfo = await fetchEnv(this.env);
@@ -270,6 +318,12 @@ export function api() {
270
318
  }
271
319
  },
272
320
 
321
+ /**
322
+ * Redirect to the login page
323
+ *
324
+ * @param {string} [authPath=""]
325
+ * @private
326
+ */
273
327
  redirectToLogin(authPath = "") {
274
328
  if (!window) {
275
329
  return;
@@ -284,14 +338,34 @@ export function api() {
284
338
  url.search = `?a=${this.appToken}&r=${encodeURIComponent(authUrlCallback)}`;
285
339
  let loginUrl = url.toString();
286
340
 
287
- window.location = loginUrl;
341
+ window.location.href = loginUrl;
288
342
  },
289
343
  };
290
344
  }
291
345
 
346
+ /**
347
+ * Default setup for IDAS
348
+ *
349
+ * @export
350
+ * @param {string} [appToken=""]
351
+ * @return {FluentApi}
352
+ */
292
353
  export function idasApi(appToken = "") {
293
- return api()
354
+ return createApi()
294
355
  .useGlobalAuth()
295
356
  .useAppToken(appToken)
296
357
  .useEnvironment("dev");
297
358
  }
359
+
360
+ /**
361
+ * Default setup for local API
362
+ *
363
+ * @export
364
+ * @return {FluentApi}
365
+ */
366
+ export function localApi() {
367
+ return createApi()
368
+ .useGlobalAuth()
369
+ .useBaseUrl("/api")
370
+ .useEnvironment("dev");
371
+ }
@@ -0,0 +1,133 @@
1
+ import { jwtDecode } from "jwt-decode";
2
+ import { isTokenValid, getRefreshToken } from "./fluentApi";
3
+
4
+ /**
5
+ * @typedef {Object} FluentAuth
6
+ * @property {string} authUrl - The authentication URL.
7
+ * @property {string} appToken - The application token.
8
+ * @property {string} token - The JWT token.
9
+ * @property {string} refreshToken - The refresh token.
10
+ * @property {function(string) : FluentApi} useAppToken - Sets the application token and returns the FluentApi object.
11
+ * @property {function(string) : FluentApi} useBaseUrl - Sets the base URL for authentication and returns the FluentApi object.
12
+ * @property {function(string) : FluentApi} useToken - Sets the JWT token and returns the FluentApi object.
13
+ * @property {function(string) : FluentApi} useRefreshToken - Sets the refresh token and returns the FluentApi object.
14
+ * @property {Function} authenticate - Authenticates the user with username and password, or refreshes the token.
15
+ * @property {Function} tryRefreshToken - Attempts to refresh the authentication token using the refresh token.
16
+ */
17
+
18
+ /**
19
+ * Builds an authentication object
20
+ *
21
+ * @export
22
+ * @returns {FluentAuth}
23
+ */
24
+ export function authBuilder() {
25
+ return {
26
+ authUrl: "",
27
+ appToken: "",
28
+ token: "",
29
+ refreshToken: "",
30
+
31
+ /**
32
+ * app token to use for authentication
33
+ *
34
+ * @param {string} [appToken=""]
35
+ * @returns {FluentAuth}
36
+ */
37
+ useAppToken(appToken = "") {
38
+ this.appToken = appToken; return this;
39
+ },
40
+
41
+ /**
42
+ * base URL for authentication
43
+ *
44
+ * @param {string} [authUrl=""]
45
+ * @returns {FluentAuth}
46
+ */
47
+ useBaseUrl(authUrl = "") {
48
+ this.authUrl = authUrl; return this;
49
+ },
50
+
51
+ /**
52
+ * token to use for authentication
53
+ *
54
+ * @param {string} [jwtToken=""]
55
+ * @returns {FluentAuth}
56
+ */
57
+ useToken(jwtToken = "") {
58
+ this.token = jwtToken; return this;
59
+ },
60
+
61
+ /**
62
+ * sets the refresh token to use
63
+ * @param {string} a refresh token (UUID v4 format)
64
+ * @returns {FluentAuth}
65
+ */
66
+ useRefreshToken(storedRefreshToken = "") {
67
+ this.refreshToken = storedRefreshToken; return this;
68
+ },
69
+
70
+ /**
71
+ * Authenticates the user with username and password, or refreshes the token.
72
+ *
73
+ * @param {string} username
74
+ * @param {string} password
75
+ * @returns
76
+ */
77
+ async authenticate(username = "", password = "") {
78
+ console.log("authenticating:", this.token ? `token set, exp: ${jwtDecode(this.token).exp - (Date.now() / 1000)}` : "no token,", this.refreshToken);
79
+
80
+ if (this.token && isTokenValid(this.token))
81
+ return this.token;
82
+
83
+ if (this.token && !this.refreshToken)
84
+ this.refreshToken = getRefreshToken(this.token);
85
+
86
+ if (this.refreshToken) {
87
+ try {
88
+ const temptoken = await this.tryRefreshToken(this.refreshToken);
89
+ if (temptoken) {
90
+ this.token = temptoken;
91
+ this.refreshToken = getRefreshToken(temptoken);
92
+ }
93
+ } catch {
94
+ // if refresh failed, we'll return the current token
95
+ // - should still be valid for a while
96
+ }
97
+ return this.token;
98
+ }
99
+
100
+ if (username && password) {
101
+ const payload = { "Email": username, "Password": password, "AppToken": this.appToken };
102
+ const res = await fetch(`${this.authUrl}/LoginJwt`,
103
+ { method: "POST", body: JSON.stringify(payload), headers: { "Content-Type": "application/json" } });
104
+ const temptoken = await res.json();
105
+ if (temptoken) {
106
+ this.token = temptoken;
107
+ return this.token;
108
+ }
109
+ }
110
+
111
+ throw new Error("not authenticated");
112
+ },
113
+
114
+ /**
115
+ * try to refresh the token using the refresh token
116
+ *
117
+ * @async
118
+ * @private
119
+ * @param {string} [refreshToken=""]
120
+ * @returns {unknown}
121
+ */
122
+ async tryRefreshToken(refreshToken = "") {
123
+ const payload = { "Token": refreshToken };
124
+ const res = await fetch(`${this.authUrl}/LoginJwt/Refresh`,
125
+ {
126
+ method: "PUT",
127
+ body: JSON.stringify(payload),
128
+ headers: { "Content-Type": "application/json" },
129
+ });
130
+ return res.ok ? await res.json() : null;
131
+ },
132
+ };
133
+ }
@@ -0,0 +1,109 @@
1
+ /**
2
+ * @typedef {Object} FluentRESTClient
3
+ * @property {string} baseUrl - The base URL for API requests.
4
+ * @property {string} token - The JWT token for authorization.
5
+ * @property {function(string) : FluentRESTClient} useBaseUrl - Function to set the base URL and return the FluentApi object.
6
+ * @property {function(string) : FluentRESTClient} useToken - Function to set the JWT token and return the FluentApi object.
7
+ * @property {function(string) : object|Array<any>} get - Async function to perform GET requests.
8
+ * @property {function(string, object) : object|Array<any>} put - Async function to perform PUT requests with a payload.
9
+ * @property {function(string, object) : object|Array<any>} post - Async function to perform POST requests with a payload.
10
+ * @property {function(string) : object|Array<any>} delete - Async function to perform DELETE requests.
11
+ */
12
+
13
+ /**
14
+ * Creates a REST client object with fluent API for making HTTP requests.
15
+ * @returns {FluentRESTClient} The REST client object.
16
+ */
17
+ export function restClient() {
18
+ return {
19
+ baseUrl: "",
20
+ token: "",
21
+
22
+ /**
23
+ * set the base URL for all requests
24
+ *
25
+ * @param {string} url to use as base URL
26
+ * @returns {FluentRESTClient}
27
+ */
28
+ useBaseUrl(url = "") {
29
+ this.baseUrl = url; return this;
30
+ },
31
+
32
+ /**
33
+ * set the JWT token for authorization
34
+ *
35
+ * @param {string} [jwtToken=""]
36
+ * @returns {FluentRESTClient}
37
+ */
38
+ useToken(jwtToken = "") {
39
+ this.token = jwtToken; return this;
40
+ },
41
+
42
+ /**
43
+ * GET request to the specified URL
44
+ *
45
+ * @async
46
+ * @param {string} [url=""]
47
+ * @param {boolean} [auth=true]
48
+ * @returns {Promise<any>}
49
+ */
50
+ async get(url = "", auth = true) {
51
+ const finalUrl = `${this.baseUrl}/${url}`;
52
+ const headers = this.token ? { "Authorization": `Bearer ${this.token}` } : {};
53
+ const res = await fetch(finalUrl, { method: "GET", headers });
54
+ if (res.ok)
55
+ return await res.json();
56
+ throw new Error(`GET ${finalUrl} failed: ${res.status} ${res.statusText}`);
57
+ },
58
+
59
+ /**
60
+ * PUT request to the specified URL
61
+ *
62
+ * @async
63
+ * @param {string} [url=""]
64
+ * @param {Object} [payload={}]
65
+ * @returns {Promise<any>}
66
+ */
67
+ async put(url = "", payload = {}) {
68
+ const finalUrl = `${this.baseUrl}/${url}`;
69
+ const headers = this.token ? { "Authorization": `Bearer ${this.token}`, "Content-Type": "application/json" } : {};
70
+ const res = await fetch(finalUrl, { method: "PUT", body: JSON.stringify(payload), headers });
71
+ if (res.ok)
72
+ return await res.json();
73
+ throw new Error(`PUT ${finalUrl} failed: ${res.status} ${res.statusText}`);
74
+ },
75
+
76
+ /**
77
+ * POST request to the specified URL
78
+ *
79
+ * @async
80
+ * @param {string} [url=""]
81
+ * @param {Object} [payload={}]
82
+ * @returns {Promise<any>}
83
+ */
84
+ async post(url = "", payload = {}) {
85
+ const finalUrl = `${this.baseUrl}/${url}`;
86
+ const headers = this.token ? { "Authorization": `Bearer ${this.token}`, "Content-Type": "application/json" } : {};
87
+ const res = await fetch(finalUrl, { method: "POST", body: JSON.stringify(payload), headers });
88
+ if (res.ok)
89
+ return await res.json();
90
+ throw new Error(`POST ${finalUrl} failed: ${res.status} ${res.statusText}`);
91
+ },
92
+
93
+ /**
94
+ * DELETE request to the specified URL
95
+ *
96
+ * @async
97
+ * @param {string} [url=""]
98
+ * @returns {Promise<any>}
99
+ */
100
+ async delete(url = "") {
101
+ const finalUrl = `${this.baseUrl}/${url}`;
102
+ const headers = this.token ? { "Authorization": `Bearer ${this.token}` } : {};
103
+ const res = await fetch(finalUrl, { method: "DELETE", headers });
104
+ if (res.ok)
105
+ return await res.json();
106
+ throw new Error(`DELETE ${finalUrl} failed: ${res.status} ${res.statusText}`);
107
+ }
108
+ };
109
+ }
package/index.js CHANGED
@@ -15,4 +15,7 @@ export {
15
15
  export { IDASFactory } from "./api/IDAS";
16
16
  export { RESTClient } from "./api/RESTClient";
17
17
  export { initIDAS } from "./api/authUtils";
18
- export { api, authBuilder, fetchEnv, getRefreshToken, idasApi } from "./api/fluentApi";
18
+
19
+ export { createApi as api, idasApi, fetchEnv, getRefreshToken } from "./api/fluentApi";
20
+ export { authBuilder } from "./api/fluentAuthBuilder";
21
+ export { restClient } from "./api/fluentRestClient";
package/jsconfig.json CHANGED
@@ -10,6 +10,7 @@
10
10
  "forceConsistentCasingInFileNames": true,
11
11
  "resolveJsonModule": true,
12
12
  "skipLibCheck": true,
13
+ "lib": [ "ES6" ],
13
14
  /**
14
15
  * To have warnings / errors of the Svelte compiler at the
15
16
  * correct position, enable source maps by default.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gandalan/weblibs",
3
- "version": "1.1.52",
3
+ "version": "1.1.54",
4
4
  "description": "WebLibs for Gandalan JS/TS/Svelte projects",
5
5
  "keywords": [
6
6
  "gandalan"