cyberia 2.99.8 → 3.0.2

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 (81) hide show
  1. package/.env.production +1 -0
  2. package/.github/workflows/engine-cyberia.cd.yml +1 -0
  3. package/.github/workflows/gitlab.ci.yml +20 -0
  4. package/.github/workflows/publish.ci.yml +18 -38
  5. package/.github/workflows/publish.cyberia.ci.yml +18 -38
  6. package/.vscode/extensions.json +8 -50
  7. package/.vscode/settings.json +0 -77
  8. package/CHANGELOG.md +171 -1
  9. package/{cli.md → CLI-HELP.md} +49 -44
  10. package/README.md +139 -0
  11. package/bin/build.js +7 -15
  12. package/bin/cyberia.js +385 -71
  13. package/bin/deploy.js +14 -151
  14. package/bin/file.js +13 -8
  15. package/bin/index.js +385 -71
  16. package/bin/zed.js +63 -2
  17. package/conf.js +32 -3
  18. package/deployment.yaml +2 -2
  19. package/jsdoc.json +1 -2
  20. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
  21. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
  22. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  23. package/manifests/deployment/dd-test-development/deployment.yaml +2 -2
  24. package/manifests/deployment/fastapi/initial_data.sh +4 -52
  25. package/manifests/ipfs/configmap.yaml +64 -0
  26. package/manifests/ipfs/headless-service.yaml +35 -0
  27. package/manifests/ipfs/kustomization.yaml +8 -0
  28. package/manifests/ipfs/statefulset.yaml +149 -0
  29. package/manifests/ipfs/storage-class.yaml +9 -0
  30. package/package.json +15 -11
  31. package/scripts/k3s-node-setup.sh +89 -0
  32. package/scripts/lxd-vm-setup.sh +23 -0
  33. package/scripts/rocky-setup.sh +1 -13
  34. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +2 -0
  35. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +7 -0
  36. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +93 -2
  37. package/src/api/file/file.controller.js +3 -13
  38. package/src/api/file/file.ref.json +0 -21
  39. package/src/api/ipfs/ipfs.controller.js +104 -0
  40. package/src/api/ipfs/ipfs.model.js +71 -0
  41. package/src/api/ipfs/ipfs.router.js +31 -0
  42. package/src/api/ipfs/ipfs.service.js +193 -0
  43. package/src/api/object-layer/README.md +139 -0
  44. package/src/api/object-layer/object-layer.controller.js +3 -0
  45. package/src/api/object-layer/object-layer.model.js +15 -1
  46. package/src/api/object-layer/object-layer.router.js +6 -10
  47. package/src/api/object-layer/object-layer.service.js +311 -182
  48. package/src/api/user/user.router.js +0 -47
  49. package/src/cli/baremetal.js +7 -9
  50. package/src/cli/cluster.js +95 -152
  51. package/src/cli/deploy.js +8 -5
  52. package/src/cli/index.js +31 -31
  53. package/src/cli/ipfs.js +184 -0
  54. package/src/cli/lxd.js +192 -237
  55. package/src/cli/repository.js +4 -1
  56. package/src/cli/run.js +17 -2
  57. package/src/client/components/core/Docs.js +92 -6
  58. package/src/client/components/core/LoadingAnimation.js +2 -3
  59. package/src/client/components/core/Modal.js +1 -1
  60. package/src/client/components/core/VanillaJs.js +36 -25
  61. package/src/client/components/cyberia/ObjectLayerEngineModal.js +4 -5
  62. package/src/client/components/cyberia/ObjectLayerEngineViewer.js +280 -29
  63. package/src/client/services/ipfs/ipfs.service.js +144 -0
  64. package/src/client/services/object-layer/object-layer.management.js +161 -8
  65. package/src/client/services/user/user.management.js +0 -5
  66. package/src/client/services/user/user.service.js +1 -1
  67. package/src/index.js +12 -1
  68. package/src/runtime/express/Express.js +4 -3
  69. package/src/server/auth.js +18 -18
  70. package/src/server/client-build-docs.js +178 -41
  71. package/src/server/conf.js +1 -1
  72. package/src/server/ipfs-client.js +433 -0
  73. package/src/server/logger.js +22 -10
  74. package/src/server/object-layer.js +649 -18
  75. package/src/server/semantic-layer-generator.js +1083 -0
  76. package/src/server/shape-generator.js +952 -0
  77. package/test/shape-generator.test.js +457 -0
  78. package/.vscode/zed.keymap.json +0 -39
  79. package/.vscode/zed.settings.json +0 -20
  80. package/bin/ssl.js +0 -63
  81. package/manifests/lxd/underpost-setup.sh +0 -163
@@ -1,9 +1,9 @@
1
1
  import { Badge } from './Badge.js';
2
2
  import { BtnIcon } from './BtnIcon.js';
3
- import { Css, renderCssAttr, simpleIconsRender, ThemeEvents, Themes } from './Css.js';
3
+ import { Css, darkTheme, renderCssAttr, simpleIconsRender, ThemeEvents, Themes } from './Css.js';
4
4
  import { buildBadgeToolTipMenuOption, Modal, renderViewTitle } from './Modal.js';
5
5
  import { listenQueryPathInstance, setQueryPath, closeModalRouteChangeEvent, getProxyPath } from './Router.js';
6
- import { htmls, s } from './VanillaJs.js';
6
+ import { htmls, s, sIframe } from './VanillaJs.js';
7
7
 
8
8
  // https://mintlify.com/docs/quickstart
9
9
 
@@ -39,6 +39,7 @@ const Docs = {
39
39
  RouterInstance: Modal.Data['modal-docs'].options.RouterInstance,
40
40
  });
41
41
  const iframeEl = s(`.iframe-${ModalId}`);
42
+ let swaggerThemeEventKey = null;
42
43
  if (iframeEl) {
43
44
  iframeEl.addEventListener('load', () => {
44
45
  try {
@@ -51,7 +52,95 @@ const Docs = {
51
52
  // cross-origin or security restriction — safe to ignore
52
53
  }
53
54
  window.scrollTo(0, 0);
55
+ // Bind Shift+K inside the iframe to focus the parent SearchBox (mirrors app-wide shortcut)
56
+ try {
57
+ const iframeDoc = iframeEl.contentDocument || iframeEl.contentWindow?.document;
58
+ if (iframeDoc) {
59
+ iframeDoc.addEventListener('keydown', (e) => {
60
+ if (e.shiftKey && e.key.toLowerCase() === 'k') {
61
+ e.preventDefault();
62
+ e.stopPropagation();
63
+ if (s(`.top-bar-search-box`)) {
64
+ if (s(`.main-body-btn-ui-close`) && s(`.main-body-btn-ui-close`).classList.contains('hide')) {
65
+ s(`.main-body-btn-ui-open`).click();
66
+ }
67
+ s(`.top-bar-search-box`).blur();
68
+ s(`.top-bar-search-box`).focus();
69
+ s(`.top-bar-search-box`).select();
70
+ }
71
+ }
72
+ });
73
+ }
74
+ } catch (e) {
75
+ // cross-origin or security restriction — safe to ignore
76
+ }
54
77
  });
78
+
79
+ if (type === 'src') {
80
+ swaggerThemeEventKey = `jsdocs-iframe-${ModalId}`;
81
+
82
+ const applyJsDocsTheme = (isDark) => {
83
+ try {
84
+ const iframeWin = iframeEl.contentWindow;
85
+ if (!iframeWin) return;
86
+ const theme = isDark ? 'dark' : 'light';
87
+ if (typeof iframeWin.updateTheme === 'function') {
88
+ // clean-jsdoc-theme exposes updateTheme() globally
89
+ iframeWin.updateTheme(theme);
90
+ } else {
91
+ // Fallback: replicate localUpdateTheme manually
92
+ const iframeDoc = iframeEl.contentDocument || iframeWin.document;
93
+ if (!iframeDoc || !iframeDoc.body) return;
94
+ iframeDoc.body.setAttribute('data-theme', theme);
95
+ iframeDoc.body.classList.remove('dark', 'light');
96
+ iframeDoc.body.classList.add(theme);
97
+ const iconID = isDark ? '#light-theme-icon' : '#dark-theme-icon';
98
+ const svgUses = sIframe(iframeEl, '.theme-svg-use') ? iframeDoc.querySelectorAll('.theme-svg-use') : [];
99
+ svgUses.forEach((svg) => svg.setAttribute('xlink:href', iconID));
100
+ iframeWin.localStorage?.setItem('theme', theme);
101
+ }
102
+ } catch (e) {
103
+ // cross-origin or security restriction — safe to ignore
104
+ }
105
+ };
106
+
107
+ // Apply current theme as soon as the iframe content is ready
108
+ iframeEl.addEventListener('load', () => applyJsDocsTheme(darkTheme));
109
+
110
+ // Keep in sync whenever the parent page theme changes
111
+ ThemeEvents[swaggerThemeEventKey] = () => {
112
+ if (s(`.iframe-${ModalId}`)) applyJsDocsTheme(darkTheme);
113
+ };
114
+ }
115
+
116
+ if (type === 'api') {
117
+ swaggerThemeEventKey = `swagger-iframe-${ModalId}`;
118
+
119
+ const applySwaggerTheme = (isDark) => {
120
+ try {
121
+ const iframeDoc = iframeEl.contentDocument || iframeEl.contentWindow?.document;
122
+ if (!iframeDoc || !iframeDoc.body) return;
123
+ if (isDark) {
124
+ iframeDoc.body.classList.add('swagger-dark');
125
+ } else {
126
+ iframeDoc.body.classList.remove('swagger-dark');
127
+ }
128
+ iframeEl.contentWindow?.localStorage?.setItem('swagger-theme', isDark ? 'dark' : 'light');
129
+ const toggleBtn = sIframe(iframeEl, '#swagger-theme-toggle');
130
+ if (toggleBtn) toggleBtn.textContent = isDark ? '\u2600\uFE0F Light Mode' : '\uD83C\uDF19 Dark Mode';
131
+ } catch (e) {
132
+ // cross-origin or security restriction — safe to ignore
133
+ }
134
+ };
135
+
136
+ // Apply current theme as soon as the iframe content is ready
137
+ iframeEl.addEventListener('load', () => applySwaggerTheme(darkTheme));
138
+
139
+ // Keep in sync whenever the parent page theme changes
140
+ ThemeEvents[swaggerThemeEventKey] = () => {
141
+ if (s(`.iframe-${ModalId}`)) applySwaggerTheme(darkTheme);
142
+ };
143
+ }
55
144
  }
56
145
  Modal.Data[ModalId].onObserverListener[ModalId] = () => {
57
146
  if (s(`.iframe-${ModalId}`)) {
@@ -67,6 +156,7 @@ const Docs = {
67
156
  };
68
157
  Modal.Data[ModalId].onObserverListener[ModalId]();
69
158
  Modal.Data[ModalId].onCloseListener[ModalId] = () => {
159
+ if (swaggerThemeEventKey) delete ThemeEvents[swaggerThemeEventKey];
70
160
  closeModalRouteChangeEvent({ closedId: ModalId });
71
161
  };
72
162
  },
@@ -342,10 +432,6 @@ const Docs = {
342
432
  <div class="docs-landing">
343
433
  <div class="docs-header">
344
434
  <h1>Documentation</h1>
345
- <p>
346
- Find everything you need to build amazing applications with our platform. Get started with our guides, API
347
- reference, and examples.
348
- </p>
349
435
  <!--
350
436
  <div class="search-bar">
351
437
  <i class="fas fa-search"></i>
@@ -27,8 +27,8 @@ const LoadingAnimation = {
27
27
  ? subThemeManager.darkColor
28
28
  : `#66e400`
29
29
  : subThemeManager.lightColor
30
- ? subThemeManager.lightColor
31
- : `#157e00`};"
30
+ ? subThemeManager.lightColor
31
+ : `#157e00`};"
32
32
  ></div>
33
33
  `,
34
34
  );
@@ -131,7 +131,6 @@ const LoadingAnimation = {
131
131
  if (!backgroundContainer) backgroundContainer = '.ssr-background';
132
132
  if (s(backgroundContainer)) {
133
133
  s(backgroundContainer).style.display = 'none';
134
- if (s(`.main-body-btn-container`)) s(`.main-body-btn-container`).classList.remove('hide');
135
134
  if (callBack) callBack();
136
135
  }
137
136
  },
@@ -322,7 +322,7 @@ const Modal = {
322
322
  'body',
323
323
  html`
324
324
  <div
325
- class="abs main-body-btn-container hide"
325
+ class="abs main-body-btn-container"
326
326
  style="top: ${options.heightTopBar + 50}px; z-index: 9; ${true ||
327
327
  (options.mode && options.mode.match('right'))
328
328
  ? 'right'
@@ -7,31 +7,6 @@
7
7
  import { s4 } from './CommonJs.js';
8
8
  import { windowGetH, windowGetW } from './windowGetDimensions.js';
9
9
 
10
- /*
11
-
12
- Name: es6-string-html
13
- Id: Tobermory.es6-string-html
14
- Description: Syntax highlighting in es6 multiline strings
15
- Version: 2.12.1
16
- Publisher: Tobermory
17
- VS Marketplace Link: https://marketplace.visualstudio.com/items?itemName=Tobermory.es6-string-html
18
-
19
- Name: es6-string-css
20
- Id: bashmish.es6-string-css
21
- Description: Highlight CSS language in ES6 template literals
22
- Version: 0.1.0
23
- Publisher: Mikhail Bashkirov
24
- VS Marketplace Link: https://marketplace.visualstudio.com/items?itemName=bashmish.es6-string-css
25
-
26
- Name: lit-html
27
- Id: bierner.lit-html
28
- Description: Syntax highlighting and IntelliSense for html inside of JavaScript and TypeScript tagged template strings
29
- Version: 1.11.1
30
- Publisher: Matt Bierner
31
- VS Marketplace Link: https://marketplace.visualstudio.com/items?itemName=bierner.lit-html
32
-
33
- */
34
-
35
10
  /**
36
11
  * Query selector.
37
12
  *
@@ -443,12 +418,48 @@ function hexToRgbA(hex) {
443
418
 
444
419
  const htmlStrSanitize = (str) => (str ? str.replace(/<\/?[^>]+(>|$)/g, '').trim() : '');
445
420
 
421
+ /**
422
+ * Query selector inside an iframe. Allows obtaining a single element that is
423
+ * inside an iframe in order to execute events on it.
424
+ * Note: the iframe must be same-origin for this to work.
425
+ *
426
+ * @param {string|Element} iframeEl The CSS selector string or the iframe Element itself.
427
+ * @param {string} el The query selector for the element inside the iframe.
428
+ * @returns {Element|null} The matched element inside the iframe, or null if not found.
429
+ * @memberof VanillaJS
430
+ */
431
+ const sIframe = (iframeEl, el) => {
432
+ const iframe = typeof iframeEl === 'string' ? s(iframeEl) : iframeEl;
433
+ if (!iframe) return null;
434
+ const iframeDoc = iframe.contentDocument || iframe.contentWindow?.document;
435
+ return iframeDoc ? iframeDoc.querySelector(el) : null;
436
+ };
437
+
438
+ /**
439
+ * Query selector all inside an iframe. Allows obtaining all elements matching a
440
+ * selector that are inside an iframe in order to execute events on them.
441
+ * Note: the iframe must be same-origin for this to work.
442
+ *
443
+ * @param {string|Element} iframeEl The CSS selector string or the iframe Element itself.
444
+ * @param {string} el The query selector for the elements inside the iframe.
445
+ * @returns {NodeList|null} A NodeList of matched elements inside the iframe, or null if not found.
446
+ * @memberof VanillaJS
447
+ */
448
+ const saIframe = (iframeEl, el) => {
449
+ const iframe = typeof iframeEl === 'string' ? s(iframeEl) : iframeEl;
450
+ if (!iframe) return null;
451
+ const iframeDoc = iframe.contentDocument || iframe.contentWindow?.document;
452
+ return iframeDoc ? iframeDoc.querySelectorAll(el) : null;
453
+ };
454
+
446
455
  export {
447
456
  s,
448
457
  htmls,
449
458
  append,
450
459
  prepend,
451
460
  sa,
461
+ sIframe,
462
+ saIframe,
452
463
  copyData,
453
464
  pasteData,
454
465
  preHTML,
@@ -195,7 +195,7 @@ const ObjectLayerEngineModal = {
195
195
  const itemTypes = ['skin', 'weapon', 'armor', 'artifact', 'floor'];
196
196
  const statTypes = ['effect', 'resistance', 'agility', 'range', 'intelligence', 'utility'];
197
197
 
198
- // Check if we have a 'cid' query parameter to load existing object layer
198
+ // Check if we have an 'id' query parameter to load existing object layer
199
199
  const queryParams = getQueryParams();
200
200
  let loadedData = null;
201
201
 
@@ -302,9 +302,9 @@ const ObjectLayerEngineModal = {
302
302
  });
303
303
  };
304
304
 
305
- if (queryParams.cid) {
306
- ObjectLayerEngineModal.existingObjectLayerId = queryParams.cid;
307
- loadedData = await ObjectLayerEngineModal.loadFromDatabase(queryParams.cid);
305
+ if (queryParams.id) {
306
+ ObjectLayerEngineModal.existingObjectLayerId = queryParams.id;
307
+ loadedData = await ObjectLayerEngineModal.loadFromDatabase(queryParams.id);
308
308
 
309
309
  if (loadedData) {
310
310
  const { metadata, objectLayerRenderFramesId } = loadedData;
@@ -1257,7 +1257,6 @@ const ObjectLayerEngineModal = {
1257
1257
  setPath(`${getProxyPath()}object-layer-engine-management`);
1258
1258
  const queryParams = getQueryParams();
1259
1259
  queryParams.id = id ? id : '';
1260
- queryParams.cid = '';
1261
1260
  queryParams.page = 1;
1262
1261
  setQueryParams(queryParams, { replace: true });
1263
1262