ApiLogicServer 15.0.26__py3-none-any.whl → 15.0.27__py3-none-any.whl

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.
Files changed (56) hide show
  1. api_logic_server_cli/api_logic_server.py +2 -2
  2. api_logic_server_cli/api_logic_server_info.yaml +3 -3
  3. api_logic_server_cli/prototypes/.DS_Store +0 -0
  4. api_logic_server_cli/prototypes/basic_demo/.DS_Store +0 -0
  5. api_logic_server_cli/prototypes/basic_demo/customizations/.DS_Store +0 -0
  6. api_logic_server_cli/prototypes/basic_demo/customizations/ui/.DS_Store +0 -0
  7. api_logic_server_cli/prototypes/basic_demo/customizations/ui/admin/.DS_Store +0 -0
  8. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/.DS_Store +0 -0
  9. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/README.md +17 -0
  10. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/README_create_react_app.md +70 -0
  11. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/package-lock.json +18469 -0
  12. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/package.json +47 -0
  13. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/public/favicon.ico +0 -0
  14. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/public/index.html +43 -0
  15. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/public/logo192.png +0 -0
  16. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/public/logo512.png +0 -0
  17. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/public/manifest.json +25 -0
  18. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/public/robots.txt +3 -0
  19. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/App.css +38 -0
  20. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/App.js +61 -0
  21. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/App.test.js +8 -0
  22. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/Config-reference.js +527 -0
  23. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/Config.js +527 -0
  24. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/Customer-reference.js +216 -0
  25. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/Customer.js +230 -0
  26. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/Item.js +170 -0
  27. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/Order.js +207 -0
  28. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/Product.js +140 -0
  29. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/SysEmail.js +157 -0
  30. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/SysMcp.js +110 -0
  31. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/app_loader.js +24 -0
  32. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/index.css +13 -0
  33. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/index.js +17 -0
  34. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/logo.svg +1 -0
  35. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/rav4-jsonapi-client/.eslintrc +5 -0
  36. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/rav4-jsonapi-client/.yarnrc.yml +4 -0
  37. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/rav4-jsonapi-client/default-settings.js +25 -0
  38. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/rav4-jsonapi-client/default-settings.ts +25 -0
  39. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/rav4-jsonapi-client/errors.js +116 -0
  40. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/rav4-jsonapi-client/errors.ts +116 -0
  41. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/rav4-jsonapi-client/index.test.tsx +7 -0
  42. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/rav4-jsonapi-client/index.tsx +11 -0
  43. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/rav4-jsonapi-client/ra-jsonapi-client.js +577 -0
  44. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/rav4-jsonapi-client/ra-jsonapi-client.ts +577 -0
  45. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/rav4-jsonapi-client/resourceLookup.js +124 -0
  46. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/rav4-jsonapi-client/resourceLookup.ts +124 -0
  47. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/rav4-jsonapi-client/styles.module.css +9 -0
  48. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/reportWebVitals.js +13 -0
  49. api_logic_server_cli/prototypes/basic_demo/customizations/ui/basic_demo_app/src/setupTests.js +5 -0
  50. api_logic_server_cli/prototypes/manager/system/genai/app_templates/app_learning/Admin-App-Resource-Learning-Prompt.md +2 -2
  51. {apilogicserver-15.0.26.dist-info → apilogicserver-15.0.27.dist-info}/METADATA +1 -1
  52. {apilogicserver-15.0.26.dist-info → apilogicserver-15.0.27.dist-info}/RECORD +56 -10
  53. {apilogicserver-15.0.26.dist-info → apilogicserver-15.0.27.dist-info}/WHEEL +0 -0
  54. {apilogicserver-15.0.26.dist-info → apilogicserver-15.0.27.dist-info}/entry_points.txt +0 -0
  55. {apilogicserver-15.0.26.dist-info → apilogicserver-15.0.27.dist-info}/licenses/LICENSE +0 -0
  56. {apilogicserver-15.0.26.dist-info → apilogicserver-15.0.27.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,527 @@
1
+ import { compareVersions } from 'compare-versions';
2
+ const yaml = require("js-yaml");
3
+
4
+
5
+
6
+
7
+ const getBrowserLocales = (
8
+ options= {}
9
+ ) => {
10
+ const defaultOptions = {
11
+ languageCodeOnly: false,
12
+ };
13
+ const opt = {
14
+ ...defaultOptions,
15
+ ...options,
16
+ };
17
+ const browserLocales =
18
+ navigator.languages === undefined
19
+ ? [navigator.language]
20
+ : navigator.languages;
21
+ if (!browserLocales) {
22
+ return undefined;
23
+ }
24
+ return browserLocales.map((locale) => {
25
+ const trimmedLocale = locale.trim();
26
+ return opt.languageCodeOnly ? trimmedLocale.split(/-|_/)[0] : trimmedLocale;
27
+ });
28
+ };
29
+
30
+ export const getLSConf = ()=> {
31
+ let result = getCurrentConf();
32
+ let ls_conf = null;
33
+ try {
34
+ ls_conf = getCurrentConf();
35
+ result = ls_conf ?? result;
36
+ } catch (e) {
37
+ console.warn(`Failed to parse config `);
38
+ throw e;
39
+ }
40
+
41
+ console.debug("LSConf", result);
42
+
43
+ return result;
44
+ };
45
+
46
+ export const doTelemetry = () => {
47
+ const currentDate = new Date().toISOString();
48
+ if(localStorage.getItem("telemetry")){
49
+ return;
50
+ }
51
+ fetch('https://apifabric.ai/static2/tm?p='+document.location.href)
52
+ .finally(() => {
53
+ localStorage.setItem("telemetry", currentDate);
54
+ })
55
+ }
56
+
57
+ const json2Conf = (conf) => {
58
+ let result = conf;
59
+ if (!result.resources) {
60
+ result.resources = {};
61
+ }
62
+ if (!result.settings) {
63
+ result.settings = {};
64
+ }
65
+ const resourceEntries = Object.entries(result.resources);
66
+ resourceEntries.sort((a, b) => (b.order || 0) - (a.order || 0))
67
+ const resources = Object.fromEntries(resourceEntries);
68
+
69
+ for (let [resource_name, resource] of Object.entries(resources || {})) {
70
+ resource.relationships = resource.relationships || [];
71
+ if (resource.tab_groups instanceof Array) {
72
+ for (let tg of resource.tab_groups) {
73
+ if (!tg.direction) {
74
+ continue;
75
+ }
76
+ tg.target = tg.resource;
77
+ resource.relationships.push(tg);
78
+ }
79
+ } else {
80
+ for (let [tab_group_name, tab_group] of Object.entries(
81
+ resource.tab_groups || {}
82
+ )) {
83
+ resource.relationships.push(
84
+ Object.assign({}, tab_group, {
85
+ name: tab_group_name,
86
+ target: (tab_group).resource,
87
+ })
88
+ );
89
+ }
90
+ }
91
+
92
+ if (
93
+ !(
94
+ resource.attributes instanceof Array ||
95
+ resource.relationships instanceof Array
96
+ )
97
+ ) {
98
+ continue;
99
+ }
100
+
101
+ if (!resource.type) {
102
+ resource.type = resource_name;
103
+ }
104
+
105
+ resource.search_cols = [];
106
+ resource.sort_attr_names = [];
107
+ result.resources[resource_name].name = resource_name;
108
+ let attributes = resource.attributes || [];
109
+
110
+ for (let attr of attributes) {
111
+ if (!(attr.constructor === Object)) {
112
+ console.warn(`Invalid attribute ${attr}`);
113
+ continue;
114
+ }
115
+ for (let rel of resource.relationships || []) {
116
+ for (let fk of rel.fks || []) {
117
+ if (attr.name === fk) {
118
+ attr.relationship = rel;
119
+ attr.relationship.target_resource =
120
+ result.resources[attr.relationship.target] ||
121
+ result.resources[attr.relationship.resource];
122
+ }
123
+ }
124
+ }
125
+ if (attr.search) {
126
+ resource.search_cols.push(attr);
127
+ }
128
+ if (attr.sort) {
129
+ if (attr.sort === "DESC") {
130
+ resource.sort_attr_names.push("-" + attr.name);
131
+ } else {
132
+ resource.sort_attr_names.push(attr.name);
133
+ }
134
+ resource.sort = resource.sort_attr_names.join(",");
135
+ }
136
+ if (!attr.label) {
137
+ attr.label =
138
+ attr.relationship?.resource ||
139
+ attr.name?.replace(/([A-Z])/g, " $1").replace(/(_)/g, " ");
140
+ }
141
+ attr.resource = resource;
142
+ }
143
+ if (resource.search_cols.length === 0) {
144
+ resource.search_cols = attributes.filter(
145
+ (col) =>
146
+ col.name !== false &&
147
+ (col.name === "id" ||
148
+ col.name === resource.user_key ||
149
+ col.name === "name")
150
+ );
151
+ }
152
+ resource.max_list_columns =
153
+ resource.max_list_columns || result.settings?.max_list_columns || 8;
154
+ }
155
+
156
+ if (result.settings) {
157
+ result.settings.locale =
158
+ result.settings.locale || getBrowserLocales()?.[0] || "fr-FR";
159
+ }
160
+ return result || resetConf(true);
161
+ };
162
+
163
+ export const useConf = () => {
164
+ let conf = getCurrentConf();
165
+ if(document.location.hash.includes("/SPA")){
166
+ // workaround to show/hide SPA resources in the webgenai SPA admin
167
+ Object.entries(conf.resources || {}).forEach(([key, value]) => {
168
+ if(value?.hidden){
169
+ value.hidden = false;
170
+ }
171
+ })
172
+ }
173
+ try{
174
+ let uiUrl = new URL(conf.api_root);
175
+ uiUrl.pathname = uiUrl.pathname.replace('/api', '/') + '/ui/';
176
+ conf.ui_root = uiUrl.toString();
177
+ }
178
+ catch(e){
179
+ console.log('api_root not set')
180
+ }
181
+
182
+ return conf;
183
+ };
184
+
185
+ export const getConf = () => {
186
+ return json2Conf(getLSConf());
187
+ };
188
+
189
+ export const resetConf = (reload) => {
190
+ // const configs = {};
191
+ // console.log("Resetting conf");
192
+ // localStorage.removeItem("raconf");
193
+ // configs[config.api_root] = ;
194
+ // setConfigs(configs);
195
+
196
+ // if (reload) {
197
+ // window.location.reload();
198
+ // }
199
+ // return config;
200
+ };
201
+
202
+
203
+ export const getKcUrl = ()=> {
204
+ const conf = getCurrentConf();
205
+ let authentication;
206
+ try {
207
+ authentication = conf.authentication;
208
+ } catch (e) {
209
+ console.warn("conf.authentication error");
210
+ }
211
+ if (!authentication?.kc_url) {
212
+ return undefined;
213
+ }
214
+ return authentication?.kc_url;
215
+ };
216
+
217
+ export const getCurrentConf = (raw = false)=> {
218
+ const conf = sessionStorage.getItem("raconf") || localStorage.getItem("raconf") || "{}";
219
+ let result = null;
220
+ try {
221
+ result = JSON.parse(conf);
222
+ } catch (e) {
223
+ console.warn("Failed to parse raconf", e);
224
+ }
225
+ if(raw) { return result; }
226
+ return json2Conf(result);
227
+ };
228
+
229
+ const DEFAULT_YAML_URL = `/ui/admin/admin.yaml?v=${new Date().getTime()}`;
230
+ export const setCurrentConf = (conf) => {
231
+ //console.debug("setCurrentConf", conf);
232
+ if(conf.server_msg){
233
+ console.log("Server Message", conf.server_msg);
234
+ if(conf.server_msg.endsWith("reload")){
235
+ // Check webgenie @app.route('/api/boot/')' for a reload message
236
+ window.location.reload();
237
+ }
238
+ }
239
+ if (!conf.api_root) {
240
+ console.warn("No api_root in conf", conf);
241
+ window.location.href = `/#/Error?message=No%20api_root%20in%20conf&ref=${window.location.href}`;
242
+ return false;
243
+ }
244
+
245
+ sessionStorage.setItem("raconf", JSON.stringify(conf));
246
+ localStorage.setItem("raconf", JSON.stringify(conf));
247
+
248
+ const stFndStr = "fetchedNonDefault";
249
+ if (conf.about?.default && !sessionStorage.getItem(stFndStr)) {
250
+ sessionStorage.setItem(stFndStr, "true");
251
+ console.debug("default config - checking for " + DEFAULT_YAML_URL);
252
+ loadYaml(DEFAULT_YAML_URL); // async!!
253
+ } else if(!conf.path) {
254
+ conf.path = window.location.pathname.split("#")[0];
255
+ const configs = getConfigs();
256
+ configs[conf.api_root] = conf;
257
+ setConfigs(configs);
258
+ }
259
+ return true;
260
+ };
261
+
262
+ export const getConfigs = () => {
263
+ let result;
264
+ try {
265
+ result = JSON.parse(localStorage.getItem("raconfigs") || "{}");
266
+ } catch (e) {
267
+ console.warn("Failed to parse raconfigs", e);
268
+ result = {};
269
+ }
270
+ console.debug("getConfigs", result);
271
+ return result;
272
+ };
273
+
274
+ export const setConfigs = (configs) => {
275
+ localStorage.setItem("raconfigs", JSON.stringify(configs));
276
+ };
277
+
278
+
279
+ export const needsReload = () => {
280
+ // check if a reload is needed, only once per session
281
+ let result = localStorage.getItem("autoReload") && !(sessionStorage.getItem("autoReloaded") === window.location.pathname)
282
+ sessionStorage.setItem("autoReloaded", window.location.pathname);
283
+ const minVersion = localStorage.getItem("minVersion");
284
+ const currentVersion = getCurrentConf().about?.version;
285
+
286
+ if(minVersion){
287
+ if(compareVersions(currentVersion, minVersion) < 0){
288
+ console.log("Version mismatch, reloading", currentVersion, minVersion);
289
+ result = true;
290
+ }
291
+ }
292
+ console.log("needsReload", result, currentVersion, minVersion);
293
+ return result;
294
+ }
295
+
296
+ const removeDupConfs = () => {
297
+ let configs = getConfigs();
298
+ let found = false;
299
+ let newConfigs = {};
300
+ for (let root in configs) {
301
+ let conf = configs[root];
302
+ let path = conf.path;
303
+ for(let root2 in newConfigs){
304
+ let conf2 = configs[root2];
305
+ if (conf2.path === path && root2 !== root) {
306
+ console.warn("Multiple configs found for path", conf.path);
307
+ localStorage.removeItem("raconfigs"); // todo
308
+ return
309
+ }
310
+ }
311
+ if(!found){
312
+ newConfigs[conf.api_root] = conf;
313
+ }
314
+ found = false;
315
+ }
316
+ setConfigs(newConfigs);
317
+ // if(found){
318
+ // document.location.reload();
319
+ // }
320
+ }
321
+
322
+ export const loadHomeConf = async () => {
323
+
324
+ const projectId = getProjectId();
325
+ console.debug("loadHomeConf:",projectId, window.location.pathname);
326
+ doTelemetry();
327
+
328
+ // const storedConfigs = localStorage.getItem("raconfigs");
329
+ // let configs = storedConfigs ? JSON.parse(storedConfigs) : {};
330
+ // let found = false;
331
+
332
+ // for (let root in configs) {
333
+ // let conf = configs[root];
334
+
335
+ // if (conf.path === window.location.pathname.split("#")[0]) {
336
+ // console.log("loadHomeConf conf:", conf);
337
+ // if (found) {
338
+ // removeDupConfs();
339
+ // break;
340
+ // }
341
+ // found = true;
342
+ // setCurrentConf(conf);
343
+ // }
344
+ // }
345
+ let confPath = window.location.origin + `/${projectId}/ui/admin/admin.yaml?v=${new Date().getTime()}`;
346
+
347
+ if (window.location.origin === "http://localhost:3000") {
348
+ console.log("DEVMODE!!!");
349
+ confPath = `http://localhost:5656/${projectId}/ui/admin/admin.yaml`;
350
+ }
351
+
352
+ console.log("loadHomeConf, loading", projectId, confPath);
353
+ await loadYaml(confPath);
354
+ const newConf = getCurrentConf();
355
+ return newConf;
356
+ };
357
+
358
+ export const loadHomeConfTbd = async () => {
359
+ const currentConf = getCurrentConf();
360
+ const storedConfigs = localStorage.getItem("raconfigs");
361
+ const projectId = getProjectId();
362
+ let configs = storedConfigs ? JSON.parse(storedConfigs) : {};
363
+ let found = false;
364
+ console.debug("loadHomeConf path:", window.location.pathname);
365
+ doTelemetry();
366
+
367
+ for (let root in configs) {
368
+ let conf = configs[root];
369
+
370
+ if (conf.path === window.location.pathname.split("#")[0]) {
371
+ console.log("loadHomeConf conf:", conf);
372
+ if (found) {
373
+ console.warn("Multiple configs found for path", conf.path);
374
+ }
375
+ found = true;
376
+ setCurrentConf(conf);
377
+ }
378
+ }
379
+ const newConf = getCurrentConf();
380
+ if (currentConf.path != newConf.path) {
381
+ console.log("loadHomeConf: conf path changed", currentConf.path, newConf.path);
382
+ sessionStorage.setItem("autoReloaded", window.location.pathname);
383
+ window.location.reload();
384
+ } else if (!found || needsReload()) {
385
+ let confPath = window.location.origin + `/${projectId}/ui/admin/admin.yaml?v=${new Date().getTime()}`;
386
+
387
+ if (window.location.origin === "http://localhost:3000") {
388
+ console.log("DEVMODE!!!");
389
+ confPath = `http://localhost:8282/${projectId}/ui/admin/admin.yaml`;
390
+ }
391
+
392
+ console.log("loadHomeConf, loading", projectId, confPath);
393
+ await loadYaml(confPath);
394
+
395
+ } else {
396
+ console.log("loadHomeConf: conf found for", window.location.pathname);
397
+ }
398
+ return newConf;
399
+ };
400
+
401
+ export const loadYaml = async (confPath) => {
402
+ const storedConfigs = localStorage.getItem("raconfigs");
403
+ let configs = storedConfigs ? JSON.parse(storedConfigs) : {};
404
+
405
+ await fetch(confPath)
406
+ .then((response) => {
407
+ if(response.status == 502){
408
+ console.warn("502 error, retry");
409
+ console.log(response);
410
+ throw new Error("502 error");
411
+ // setTimeout(() => {
412
+ // loadYaml(confPath);
413
+ // }, 5000);
414
+ // return;
415
+ }
416
+ return response.text()
417
+ })
418
+ .then((text) => {
419
+
420
+ const prevConf = getCurrentConf(true);
421
+ let conf;
422
+ try {
423
+ conf = yaml.load(text);
424
+ let loadUrl = confPath
425
+
426
+ if(document.location.hash.includes("Configuration")){
427
+ // special case: configuration page contains a load parameter
428
+ const hashParams = new URLSearchParams(document.location.hash.split("?")[1]);
429
+ loadUrl = hashParams.get("load") ?? confPath
430
+ }
431
+
432
+ if (!conf.conf_source) {
433
+ const encodedLoadUrl = btoa(loadUrl);
434
+ conf.conf_source = encodedLoadUrl;
435
+ }
436
+ } catch (e) {
437
+ console.warn("Failed to parse yaml", e, conf);
438
+ return;
439
+ }
440
+ if (!setCurrentConf(conf)) {
441
+ return;
442
+ }
443
+
444
+ if(compareConf(prevConf, conf)){
445
+ return
446
+ }
447
+ console.log("loadYaml ymal changed...", conf);
448
+ configs[conf.api_root] = conf;
449
+ setConfigs(configs);
450
+ window.location.reload();
451
+ })
452
+ .catch((error) => {
453
+ console.warn("Failed to load yaml", error);
454
+ });
455
+ };
456
+
457
+ export const compareConf = (conf1, conf2) => {
458
+ // return true if the two configs are the same, else false
459
+ let result
460
+ try{
461
+ result = conf1.api_root === conf2.api_root && Object.keys(conf1).length === Object.keys(conf2).length && JSON.stringify(conf1.authentication) === JSON.stringify(conf2.authentication);
462
+ result = result && JSON.stringify(conf1.about) === JSON.stringify(conf2.about);
463
+ result = JSON.stringify({...(conf1.resources || {}), ...(conf1.authentication || {})}) === JSON.stringify({...(conf2.resources || {}), ...(conf2.authentication || {})});
464
+ }
465
+ catch(e){
466
+ console.warn("compareConf error", e);
467
+ result = false;
468
+ }
469
+ console.debug("compareConf", result);
470
+ return result;
471
+ }
472
+
473
+
474
+ export const getAppId = (appId) => {
475
+ // set the app id for the current session
476
+
477
+ appId = appId || window.location.pathname.split("/")[1];
478
+ if (!appId || appId === "index.html" || appId === "admin-app" || !appId.startsWith("0")) {
479
+ appId = "";
480
+ localStorage.removeItem("appId");
481
+ sessionStorage.removeItem("appId");
482
+ return appId;
483
+ }
484
+
485
+ appId = appId || sessionStorage.getItem("appId") || localStorage.getItem("appId") || "";
486
+ const hash = window.location.hash;
487
+
488
+ if (hash.includes('?') && hash.includes('appId')) {
489
+ // get the app id from the URL hash
490
+ const queryString = hash.split('?')[1];
491
+ const params = new URLSearchParams(queryString);
492
+ appId = params.get("appId") || appId;
493
+ }
494
+ else if (document.location.pathname.startsWith("/01")){
495
+ // get the app id from the URL path
496
+ appId = document.location.pathname.split("/")[1];
497
+ }
498
+ if(appId){
499
+ if(appId !== localStorage.getItem("appId")){
500
+ console.log("Changing LS appId", appId);
501
+ localStorage.setItem("appId", appId);
502
+ }
503
+ if(appId !== sessionStorage.getItem("appId")){
504
+ console.log("Changing SS appId", appId);
505
+ sessionStorage.setItem("appId", appId);
506
+ }
507
+ }
508
+ else{
509
+ localStorage.removeItem("appId");
510
+ sessionStorage.removeItem("appId");
511
+ }
512
+
513
+ return appId;
514
+ }
515
+
516
+
517
+ export const getProjectId = () => {
518
+ /*
519
+ Check if the path is a project id, used for apifabric..
520
+ */
521
+ return getAppId();
522
+
523
+ };
524
+
525
+ export const isSpa = () => {
526
+ return sessionStorage.getItem("raSpa") == "true" || window.location.href.includes("raSpa")
527
+ }