@docbrasil/api-systemmanager 1.1.82 → 1.1.84

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/doc/api.md CHANGED
@@ -5403,6 +5403,8 @@ Api dispatch manager
5403
5403
  * [.errorOffline()](#Dispatch+errorOffline)
5404
5404
  * [.getContext(url, [session])](#Dispatch+getContext) ⇒ <code>Promise.&lt;object&gt;</code>
5405
5405
  * [.getClient()](#Dispatch+getClient) ⇒ <code>AxiosInstance</code>
5406
+ * [.setAkamaiBaseUrl(url, [options])](#Dispatch+setAkamaiBaseUrl)
5407
+ * [.getAkamaiClient()](#Dispatch+getAkamaiClient) ⇒ <code>AxiosInstance</code>
5406
5408
 
5407
5409
  <a name="Dispatch+errorOffline"></a>
5408
5410
 
@@ -5432,6 +5434,33 @@ Get the Axios client.
5432
5434
  **Kind**: instance method of [<code>Dispatch</code>](#Dispatch)
5433
5435
  **Returns**: <code>AxiosInstance</code> - The Axios client.
5434
5436
  **Access**: public
5437
+ <a name="Dispatch+setAkamaiBaseUrl"></a>
5438
+
5439
+ ### dispatch.setAkamaiBaseUrl(url, [options])
5440
+ Create a dedicated Axios client for Akamai routes.
5441
+ In DEV there is no NGiNX to translate the Authorization JWT into the
5442
+ x-api-key / x-user-id / x-organization-id headers that Akamai expects.
5443
+ When an apiKey is supplied the client adds a request interceptor that
5444
+ decodes the JWT and sets those headers automatically.
5445
+
5446
+ **Kind**: instance method of [<code>Dispatch</code>](#Dispatch)
5447
+ **Access**: public
5448
+
5449
+ | Param | Type | Description |
5450
+ | --- | --- | --- |
5451
+ | url | <code>string</code> | The Akamai base URL (e.g., http://localhost:9008 in DEV). |
5452
+ | [options] | <code>object</code> | Optional configuration |
5453
+ | [options.apiKey] | <code>string</code> | API key for Akamai authentication. When provided, the client will transform the Authorization JWT into x-api-key, x-user-id and x-organization-id headers on every request. |
5454
+
5455
+ <a name="Dispatch+getAkamaiClient"></a>
5456
+
5457
+ ### dispatch.getAkamaiClient() ⇒ <code>AxiosInstance</code>
5458
+ Get the Akamai Axios client. Falls back to the default client
5459
+ for backward compatibility (e.g., PROD where NGiNX proxies all routes).
5460
+
5461
+ **Kind**: instance method of [<code>Dispatch</code>](#Dispatch)
5462
+ **Returns**: <code>AxiosInstance</code> - The Akamai client or default client.
5463
+ **Access**: public
5435
5464
  <a name="External"></a>
5436
5465
 
5437
5466
  ## External
@@ -495,7 +495,7 @@ Use this to create a session with full metadata before triggering execution.
495
495
  <p class="tag-source">
496
496
  <a href="ai_sessions.js.html" class="button">View Source</a>
497
497
  <span>
498
- <a href="ai_sessions.js.html">ai/sessions.js</a>, <a href="ai_sessions.js.html#line182">line 182</a>
498
+ <a href="ai_sessions.js.html">ai/sessions.js</a>, <a href="ai_sessions.js.html#line183">line 183</a>
499
499
  </span>
500
500
  </p>
501
501
 
@@ -844,7 +844,7 @@ const retData = await api.ai.sessions.create(params, authorization);</code></pre
844
844
  <p class="tag-source">
845
845
  <a href="ai_sessions.js.html" class="button">View Source</a>
846
846
  <span>
847
- <a href="ai_sessions.js.html">ai/sessions.js</a>, <a href="ai_sessions.js.html#line224">line 224</a>
847
+ <a href="ai_sessions.js.html">ai/sessions.js</a>, <a href="ai_sessions.js.html#line226">line 226</a>
848
848
  </span>
849
849
  </p>
850
850
 
@@ -1133,7 +1133,7 @@ Returns session, execution, activities, pages, triples and summary.
1133
1133
  <p class="tag-source">
1134
1134
  <a href="ai_sessions.js.html" class="button">View Source</a>
1135
1135
  <span>
1136
- <a href="ai_sessions.js.html">ai/sessions.js</a>, <a href="ai_sessions.js.html#line74">line 74</a>
1136
+ <a href="ai_sessions.js.html">ai/sessions.js</a>, <a href="ai_sessions.js.html#line73">line 73</a>
1137
1137
  </span>
1138
1138
  </p>
1139
1139
 
@@ -314,6 +314,129 @@
314
314
 
315
315
 
316
316
 
317
+
318
+ </div>
319
+
320
+ <div class="member">
321
+
322
+
323
+
324
+ <h4 class="name" id="getAkamaiClient">
325
+ <a class="href-link" href="#getAkamaiClient">#</a>
326
+
327
+ <span class="code-name">
328
+
329
+ getAkamaiClient<span class="signature">()</span><span class="type-signature"> &rarr; {AxiosInstance}</span>
330
+
331
+ </span>
332
+ </h4>
333
+
334
+
335
+
336
+
337
+ <div class="description">
338
+ Get the Akamai Axios client. Falls back to the default client
339
+ for backward compatibility (e.g., PROD where NGiNX proxies all routes).
340
+ </div>
341
+
342
+
343
+
344
+
345
+
346
+
347
+
348
+
349
+
350
+
351
+
352
+
353
+
354
+
355
+ <dl class="details">
356
+
357
+
358
+
359
+
360
+
361
+
362
+
363
+
364
+
365
+
366
+
367
+
368
+
369
+
370
+
371
+
372
+
373
+
374
+
375
+
376
+
377
+
378
+
379
+
380
+
381
+
382
+
383
+
384
+
385
+
386
+
387
+ <p class="tag-source">
388
+ <a href="dispatch.js.html" class="button">View Source</a>
389
+ <span>
390
+ <a href="dispatch.js.html">dispatch.js</a>, <a href="dispatch.js.html#line277">line 277</a>
391
+ </span>
392
+ </p>
393
+
394
+ </dl>
395
+
396
+
397
+
398
+
399
+
400
+
401
+
402
+
403
+
404
+
405
+
406
+
407
+
408
+
409
+
410
+
411
+
412
+
413
+ <div class='columns method-parameter'>
414
+ <div class="column is-2"><label>Returns:</label></div>
415
+ <div class="column is-10">
416
+
417
+
418
+
419
+ <div class="columns">
420
+
421
+ <div class='param-desc column is-7'>The Akamai client or default client.</div>
422
+
423
+
424
+ <div class='column is-5 has-text-left'>
425
+ <label>Type: </label>
426
+
427
+ <code class="param-type">AxiosInstance</code>
428
+
429
+
430
+ </div>
431
+
432
+ </div>
433
+
434
+
435
+ </div>
436
+ </div>
437
+
438
+
439
+
317
440
 
318
441
  </div>
319
442
 
@@ -673,6 +796,241 @@
673
796
 
674
797
 
675
798
 
799
+
800
+ </div>
801
+
802
+ <div class="member">
803
+
804
+
805
+
806
+ <h4 class="name" id="setAkamaiBaseUrl">
807
+ <a class="href-link" href="#setAkamaiBaseUrl">#</a>
808
+
809
+ <span class="code-name">
810
+
811
+ setAkamaiBaseUrl<span class="signature">(url, options<span class="signature-attributes">opt</span>)</span><span class="type-signature"></span>
812
+
813
+ </span>
814
+ </h4>
815
+
816
+
817
+
818
+
819
+ <div class="description">
820
+ Create a dedicated Axios client for Akamai routes.
821
+ In DEV there is no NGiNX to translate the Authorization JWT into the
822
+ x-api-key / x-user-id / x-organization-id headers that Akamai expects.
823
+ When an apiKey is supplied the client adds a request interceptor that
824
+ decodes the JWT and sets those headers automatically.
825
+ </div>
826
+
827
+
828
+
829
+
830
+
831
+
832
+
833
+
834
+
835
+
836
+ <h5>Parameters:</h5>
837
+
838
+ <div class="table-container">
839
+ <table class="params table">
840
+ <thead>
841
+ <tr>
842
+
843
+ <th>Name</th>
844
+
845
+
846
+ <th>Type</th>
847
+
848
+
849
+ <th>Attributes</th>
850
+
851
+
852
+
853
+
854
+ <th class="last">Description</th>
855
+ </tr>
856
+ </thead>
857
+
858
+ <tbody>
859
+
860
+
861
+
862
+ <tr class="deep-level-0">
863
+
864
+ <td class="name"><code>url</code></td>
865
+
866
+
867
+ <td class="type">
868
+
869
+
870
+ <code class="param-type">string</code>
871
+
872
+
873
+
874
+ </td>
875
+
876
+
877
+ <td class="attributes">
878
+
879
+
880
+
881
+
882
+
883
+ </td>
884
+
885
+
886
+
887
+
888
+ <td class="description last">The Akamai base URL (e.g., http://localhost:9008 in DEV).</td>
889
+ </tr>
890
+
891
+
892
+
893
+
894
+
895
+ <tr class="deep-level-0">
896
+
897
+ <td class="name"><code>options</code></td>
898
+
899
+
900
+ <td class="type">
901
+
902
+
903
+ <code class="param-type">object</code>
904
+
905
+
906
+
907
+ </td>
908
+
909
+
910
+ <td class="attributes">
911
+
912
+ &lt;optional><br>
913
+
914
+
915
+
916
+
917
+
918
+ </td>
919
+
920
+
921
+
922
+
923
+ <td class="description last">Optional configuration</td>
924
+ </tr>
925
+
926
+
927
+
928
+
929
+ <tr class="deep-level-1">
930
+
931
+ <td class="name"><code>apiKey</code></td>
932
+
933
+
934
+ <td class="type">
935
+
936
+
937
+ <code class="param-type">string</code>
938
+
939
+
940
+
941
+ </td>
942
+
943
+
944
+ <td class="attributes">
945
+
946
+ &lt;optional><br>
947
+
948
+
949
+
950
+
951
+
952
+ </td>
953
+
954
+
955
+
956
+
957
+ <td class="description last">API key for Akamai authentication.
958
+ When provided, the client will transform the Authorization JWT into
959
+ x-api-key, x-user-id and x-organization-id headers on every request.</td>
960
+ </tr>
961
+
962
+
963
+
964
+
965
+
966
+ </tbody>
967
+ </table>
968
+ </div>
969
+
970
+
971
+
972
+
973
+
974
+ <dl class="details">
975
+
976
+
977
+
978
+
979
+
980
+
981
+
982
+
983
+
984
+
985
+
986
+
987
+
988
+
989
+
990
+
991
+
992
+
993
+
994
+
995
+
996
+
997
+
998
+
999
+
1000
+
1001
+
1002
+
1003
+
1004
+
1005
+
1006
+ <p class="tag-source">
1007
+ <a href="dispatch.js.html" class="button">View Source</a>
1008
+ <span>
1009
+ <a href="dispatch.js.html">dispatch.js</a>, <a href="dispatch.js.html#line236">line 236</a>
1010
+ </span>
1011
+ </p>
1012
+
1013
+ </dl>
1014
+
1015
+
1016
+
1017
+
1018
+
1019
+
1020
+
1021
+
1022
+
1023
+
1024
+
1025
+
1026
+
1027
+
1028
+
1029
+
1030
+
1031
+
1032
+
1033
+
676
1034
 
677
1035
  </div>
678
1036
 
package/docs/MyndAI.html CHANGED
@@ -632,7 +632,7 @@
632
632
  <p class="tag-source">
633
633
  <a href="ai_index.js.html" class="button">View Source</a>
634
634
  <span>
635
- <a href="ai_index.js.html">ai/index.js</a>, <a href="ai_index.js.html#line88">line 88</a>
635
+ <a href="ai_index.js.html">ai/index.js</a>, <a href="ai_index.js.html#line87">line 87</a>
636
636
  </span>
637
637
  </p>
638
638
 
@@ -102,7 +102,6 @@ class MyndAI {
102
102
 
103
103
  const self = this;
104
104
  self.parent = options.parent;
105
- self._client = self.parent.dispatch.getClient();
106
105
 
107
106
  self.sessions = new AISession(options);
108
107
  }
@@ -179,7 +178,8 @@ class MyndAI {
179
178
  Joi.assert(params, Joi.object().required().error(new Error('params is required')));
180
179
  Joi.assert(params.prompt, Joi.string().required().error(new Error('Provide a prompt')));
181
180
 
182
- const apiCall = self._client
181
+ const client = self.parent.dispatch.getAkamaiClient();
182
+ const apiCall = client
183
183
  .post('/agents/explain', params, self._setHeader(authorization));
184
184
 
185
185
  return self._returnData(await apiCall);
@@ -101,7 +101,6 @@ class AISession {
101
101
 
102
102
  const self = this;
103
103
  self.parent = options.parent;
104
- self._client = self.parent.dispatch.getClient();
105
104
  }
106
105
 
107
106
  /**
@@ -165,7 +164,8 @@ class AISession {
165
164
  Joi.assert(params, Joi.object().required().error(new Error('params is required')));
166
165
  Joi.assert(params.documentId, Joi.string().required().error(new Error('documentId is required')));
167
166
 
168
- const apiCall = self._client
167
+ const client = self.parent.dispatch.getAkamaiClient();
168
+ const apiCall = client
169
169
  .get(`/agents/session/document/${params.documentId}`, self._setHeader(authorization));
170
170
 
171
171
  return self._returnData(await apiCall);
@@ -227,7 +227,8 @@ class AISession {
227
227
 
228
228
  const { documentId, ...payload } = params;
229
229
 
230
- const apiCall = self._client
230
+ const client = self.parent.dispatch.getAkamaiClient();
231
+ const apiCall = client
231
232
  .patch(`/agents/session/document/${documentId}`, payload, self._setHeader(authorization));
232
233
 
233
234
  return self._returnData(await apiCall);
@@ -273,7 +274,8 @@ class AISession {
273
274
  Joi.assert(params, Joi.object().required().error(new Error('params is required')));
274
275
  Joi.assert(params.agentType, Joi.string().required().error(new Error('agentType is required')));
275
276
 
276
- const apiCall = self._client
277
+ const client = self.parent.dispatch.getAkamaiClient();
278
+ const apiCall = client
277
279
  .post('/agents/create', params, self._setHeader(authorization));
278
280
 
279
281
  return self._returnData(await apiCall);
@@ -317,7 +319,8 @@ class AISession {
317
319
 
318
320
  const { sessionId, ...payload } = params;
319
321
 
320
- const apiCall = self._client
322
+ const client = self.parent.dispatch.getAkamaiClient();
323
+ const apiCall = client
321
324
  .post(`/agents/${sessionId}/execute`, payload, self._setHeader(authorization));
322
325
 
323
326
  return self._returnData(await apiCall);
@@ -285,6 +285,85 @@ class Dispatch {
285
285
  getClient() {
286
286
  return this._client;
287
287
  }
288
+
289
+ /**
290
+ * @description Decode the payload of a JWT token (base64url → JSON).
291
+ * Does NOT verify the signature — used only to extract claims for header building.
292
+ * @param {string} token JWT token string
293
+ * @return {object|null} Decoded payload or null on failure
294
+ * @private
295
+ */
296
+ _decodeJwtPayload(token) {
297
+ try {
298
+ const parts = token.split('.');
299
+ if (parts.length !== 3) return null;
300
+ const base64 = parts[1].replace(/-/g, '+').replace(/_/g, '/');
301
+ const json = decodeURIComponent(
302
+ atob(base64).split('').map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)).join('')
303
+ );
304
+ return JSON.parse(json);
305
+ } catch (e) {
306
+ return null;
307
+ }
308
+ }
309
+
310
+ /**
311
+ * @description Create a dedicated Axios client for Akamai routes.
312
+ * In DEV there is no NGiNX to translate the Authorization JWT into the
313
+ * x-api-key / x-user-id / x-organization-id headers that Akamai expects.
314
+ * When an apiKey is supplied the client adds a request interceptor that
315
+ * decodes the JWT and sets those headers automatically.
316
+ * @param {string} url The Akamai base URL (e.g., http://localhost:9008 in DEV).
317
+ * @param {object} [options] Optional configuration
318
+ * @param {string} [options.apiKey] API key for Akamai authentication.
319
+ * When provided, the client will transform the Authorization JWT into
320
+ * x-api-key, x-user-id and x-organization-id headers on every request.
321
+ * @public
322
+ */
323
+ setAkamaiBaseUrl(url, options = {}) {
324
+ Joi.assert(url, Joi.string().required());
325
+
326
+ const self = this;
327
+
328
+ self._akamaiClient = Axios.create({
329
+ baseURL: url,
330
+ withCredentials: true
331
+ });
332
+
333
+ // When an API key is provided, add interceptor to build Akamai headers from the JWT
334
+ if (options.apiKey) {
335
+ const apiKey = options.apiKey;
336
+
337
+ self._akamaiClient.interceptors.request.use((config) => {
338
+ const auth = config.headers &amp;&amp; (config.headers.Authorization || config.headers.authorization);
339
+ if (auth) {
340
+ const payload = self._decodeJwtPayload(auth);
341
+ if (payload) {
342
+ config.headers['x-api-key'] = apiKey;
343
+ config.headers['x-user-id'] = payload._id || payload.userId;
344
+ config.headers['x-organization-id'] = payload.orgId || payload.organizationId;
345
+ if (payload.language) {
346
+ config.headers['x-country'] = payload.language;
347
+ }
348
+ // Remove the Authorization header — Akamai doesn't use it
349
+ delete config.headers.Authorization;
350
+ delete config.headers.authorization;
351
+ }
352
+ }
353
+ return config;
354
+ });
355
+ }
356
+ }
357
+
358
+ /**
359
+ * @description Get the Akamai Axios client. Falls back to the default client
360
+ * for backward compatibility (e.g., PROD where NGiNX proxies all routes).
361
+ * @return {AxiosInstance} The Akamai client or default client.
362
+ * @public
363
+ */
364
+ getAkamaiClient() {
365
+ return this._akamaiClient || this._client;
366
+ }
288
367
  }
289
368
 
290
369
  export default Dispatch;
package/index.js CHANGED
@@ -68,6 +68,7 @@ class API {
68
68
  }
69
69
  },
70
70
  uri: 'http://localhost:8080',
71
+ akamaiUri: null,
71
72
  attemptsRetry: 3,
72
73
  httpStatusToRetry: [401],
73
74
  debug: {success: true, error: true}
@@ -83,6 +84,23 @@ class API {
83
84
  self.admin = new Admin({parent: self});
84
85
  self.external = new External({parent: self});
85
86
  self.ai = new MyndAI({parent: self});
87
+
88
+ // If akamaiUri was provided in options, configure the Akamai client
89
+ if (self.options.akamaiUri) {
90
+ self.dispatch.setAkamaiBaseUrl(self.options.akamaiUri, { apiKey: self.options.akamaiApiKey });
91
+ }
92
+ }
93
+
94
+ /**
95
+ * @description Set the Akamai base URL for agent/AI routes.
96
+ * @param {string} url The Akamai base URL.
97
+ * @param {object} [options] Optional configuration
98
+ * @param {string} [options.apiKey] API key for Akamai authentication (required in DEV,
99
+ * where there is no NGiNX to translate Authorization JWT into x-* headers).
100
+ * @public
101
+ */
102
+ setAkamaiBaseUrl(url, options = {}) {
103
+ this.dispatch.setAkamaiBaseUrl(url, options);
86
104
  }
87
105
  }
88
106
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@docbrasil/api-systemmanager",
3
3
  "description": "Module API System Manager",
4
- "version": "1.1.82",
4
+ "version": "1.1.84",
5
5
  "scripts": {
6
6
  "htmldoc": "rm -rf docs && jsdoc api/** -d docs -t ./node_modules/better-docs",
7
7
  "doc": "rm -rf doc && mkdir doc && jsdoc2md api/**/* api/* > doc/api.md",