underpost 2.8.878 → 2.8.882

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 (61) hide show
  1. package/.env.development +35 -3
  2. package/.env.production +40 -3
  3. package/.env.test +35 -3
  4. package/.github/workflows/release.cd.yml +3 -3
  5. package/README.md +20 -2
  6. package/bin/deploy.js +40 -0
  7. package/cli.md +3 -1
  8. package/conf.js +29 -3
  9. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  10. package/manifests/deployment/dd-test-development/deployment.yaml +6 -6
  11. package/package.json +1 -2
  12. package/src/api/document/document.controller.js +66 -0
  13. package/src/api/document/document.model.js +51 -0
  14. package/src/api/document/document.router.js +24 -0
  15. package/src/api/document/document.service.js +133 -0
  16. package/src/cli/deploy.js +1 -1
  17. package/src/cli/index.js +2 -0
  18. package/src/cli/repository.js +2 -0
  19. package/src/cli/run.js +27 -1
  20. package/src/client/Default.index.js +46 -1
  21. package/src/client/components/core/Account.js +8 -1
  22. package/src/client/components/core/AgGrid.js +18 -9
  23. package/src/client/components/core/Auth.js +258 -89
  24. package/src/client/components/core/BtnIcon.js +13 -3
  25. package/src/client/components/core/Content.js +2 -1
  26. package/src/client/components/core/CssCore.js +40 -27
  27. package/src/client/components/core/Docs.js +189 -88
  28. package/src/client/components/core/Input.js +34 -19
  29. package/src/client/components/core/LoadingAnimation.js +5 -10
  30. package/src/client/components/core/Modal.js +280 -123
  31. package/src/client/components/core/ObjectLayerEngine.js +470 -104
  32. package/src/client/components/core/ObjectLayerEngineModal.js +1 -0
  33. package/src/client/components/core/Panel.js +9 -2
  34. package/src/client/components/core/PanelForm.js +234 -76
  35. package/src/client/components/core/Router.js +15 -15
  36. package/src/client/components/core/ToolTip.js +83 -19
  37. package/src/client/components/core/Translate.js +1 -1
  38. package/src/client/components/core/VanillaJs.js +7 -3
  39. package/src/client/components/core/windowGetDimensions.js +202 -0
  40. package/src/client/components/default/MenuDefault.js +105 -41
  41. package/src/client/components/default/RoutesDefault.js +2 -0
  42. package/src/client/services/default/default.management.js +1 -0
  43. package/src/client/services/document/document.service.js +97 -0
  44. package/src/client/services/file/file.service.js +2 -0
  45. package/src/client/ssr/Render.js +1 -1
  46. package/src/client/ssr/head/DefaultScripts.js +2 -0
  47. package/src/client/ssr/head/Seo.js +1 -0
  48. package/src/index.js +1 -1
  49. package/src/mailer/EmailRender.js +1 -1
  50. package/src/server/auth.js +68 -17
  51. package/src/server/client-build.js +2 -3
  52. package/src/server/client-formatted.js +40 -12
  53. package/src/server/conf.js +5 -1
  54. package/src/server/crypto.js +195 -76
  55. package/src/server/object-layer.js +196 -0
  56. package/src/server/peer.js +47 -5
  57. package/src/server/process.js +85 -1
  58. package/src/server/runtime.js +23 -23
  59. package/src/server/ssr.js +52 -10
  60. package/src/server/valkey.js +89 -1
  61. package/test/crypto.test.js +117 -0
@@ -1,12 +1,9 @@
1
1
  import { Badge } from './Badge.js';
2
2
  import { BtnIcon } from './BtnIcon.js';
3
3
  import { Css, renderCssAttr, simpleIconsRender, ThemeEvents, Themes } from './Css.js';
4
- import { DropDown } from './DropDown.js';
5
- import { buildBadgeToolTipMenuOption, Modal, renderMenuLabel, renderViewTitle } from './Modal.js';
4
+ import { buildBadgeToolTipMenuOption, Modal, renderViewTitle } from './Modal.js';
6
5
  import { listenQueryPathInstance, setQueryPath, closeModalRouteChangeEvent, getProxyPath } from './Router.js';
7
- import { Translate } from './Translate.js';
8
6
  import { htmls, s } from './VanillaJs.js';
9
- import Sortable from 'sortablejs';
10
7
 
11
8
  // https://mintlify.com/docs/quickstart
12
9
 
@@ -129,19 +126,16 @@ const Docs = {
129
126
  s(`.btn-docs-src`).onclick = async () => {
130
127
  setQueryPath({ path: 'docs', queryPath: 'src' });
131
128
  cleanActive();
132
- s(`.btn-docs-src`).classList.add('main-btn-menu-active');
133
129
  await this.RenderModal('src', options.modalOptions);
134
130
  };
135
131
  s(`.btn-docs-api`).onclick = async () => {
136
132
  setQueryPath({ path: 'docs', queryPath: 'api' });
137
133
  cleanActive();
138
- s(`.btn-docs-api`).classList.add('main-btn-menu-active');
139
134
  await this.RenderModal('api', options.modalOptions);
140
135
  };
141
136
  s(`.btn-docs-coverage`).onclick = async () => {
142
137
  setQueryPath({ path: 'docs', queryPath: 'coverage' });
143
138
  cleanActive();
144
- s(`.btn-docs-coverage`).classList.add('main-btn-menu-active');
145
139
  await this.RenderModal('coverage', options.modalOptions);
146
140
  };
147
141
 
@@ -162,7 +156,13 @@ const Docs = {
162
156
  id: options.idModal,
163
157
  routeId: 'docs',
164
158
  event: (path) => {
159
+ Modal.subMenuBtnClass['docs'].open = !Modal.subMenuBtnClass['docs'].open;
165
160
  if (s(`.btn-docs-${path}`)) s(`.btn-docs-${path}`).click();
161
+ if (Modal.mobileModal()) {
162
+ setTimeout(() => {
163
+ s(`.btn-close-modal-menu`).click();
164
+ });
165
+ }
166
166
  },
167
167
  });
168
168
  });
@@ -186,98 +186,199 @@ const Docs = {
186
186
  tabHref = docData.url();
187
187
  docMenuRender += html`
188
188
  ${await BtnIcon.Render({
189
- class: `in wfa main-btn-menu btn-docs-${docData.type}`,
190
- label: html`<span class="menu-btn-icon">${docData.icon}</span
191
- ><span class="menu-label-text"> ${docData.text} </span>`,
189
+ class: `in wfa main-btn-menu submenu-btn btn-docs btn-docs-${docData.type}`,
190
+ label: html`<span class="inl menu-btn-icon">${docData.icon}</span
191
+ ><span class="menu-label-text menu-label-text-docs"> ${docData.text} </span>`,
192
192
  tabHref,
193
- handleContainerClass: 'handle-btn-container',
194
193
  tooltipHtml: await Badge.Render(buildBadgeToolTipMenuOption(docData.text, 'right')),
195
- attrs: `data-id="${docData.type}"`,
196
- handleContainerClass: 'handle-btn-container',
194
+ useMenuBtn: true,
197
195
  })}
198
196
  `;
199
197
  }
198
+ // s(`.menu-btn-container-children`).classList.remove('hide');
199
+ // htmls(`.nav-path-display-${'modal-menu'}`, location.pathname);
200
200
 
201
- htmls('.menu-btn-container-children', html` <div class="fl menu-btn-container-docs">${docMenuRender}</div>`);
202
- if (s(`.menu-btn-container-main`)) s(`.menu-btn-container-main`).classList.add('hide');
203
- htmls(`.nav-path-display-${'modal-menu'}`, location.pathname);
201
+ htmls('.menu-btn-container-children-docs', docMenuRender);
204
202
 
205
- this.Tokens[idModal] = new Sortable(s(`.menu-btn-container-docs`), {
206
- animation: 150,
207
- group: `docs-sortable`,
208
- forceFallback: true,
209
- fallbackOnBody: true,
210
- handle: '.handle-btn-container',
211
- store: {
212
- /**
213
- * Get the order of elements. Called once during initialization.
214
- * @param {Sortable} sortable
215
- * @returns {Array}
216
- */
217
- get: function (sortable) {
218
- const order = localStorage.getItem(sortable.options.group.name);
219
- return order ? order.split('|') : [];
203
+ {
204
+ const docsData = [
205
+ {
206
+ id: 'getting-started',
207
+ icon: 'rocket',
208
+ title: 'Getting Started',
209
+ description: 'Learn the basics and get started with our platform',
220
210
  },
221
-
222
- /**
223
- * Save the order of elements. Called onEnd (when the item is dropped).
224
- * @param {Sortable} sortable
225
- */
226
- set: function (sortable) {
227
- const order = sortable.toArray();
228
- localStorage.setItem(sortable.options.group.name, order.join('|'));
211
+ {
212
+ id: 'api-docs',
213
+ icon: 'code',
214
+ title: 'API Reference',
215
+ description: 'Detailed documentation of our API endpoints',
229
216
  },
230
- },
231
- // chosenClass: 'css-class',
232
- // ghostClass: 'css-class',
233
- // Element dragging ended
234
- onEnd: function (/**Event*/ evt) {
235
- // console.log('Sortable onEnd', evt);
236
- // console.log('evt.oldIndex', evt.oldIndex);
237
- // console.log('evt.newIndex', evt.newIndex);
238
- const slotId = Array.from(evt.item.classList).pop();
239
- // console.log('slotId', slotId);
240
- if (evt.oldIndex === evt.newIndex) s(`.${slotId}`).click();
217
+ {
218
+ id: 'guides',
219
+ icon: 'book',
220
+ title: 'Guides',
221
+ description: 'Step-by-step tutorials and how-to guides',
222
+ },
223
+ {
224
+ id: 'demo',
225
+ icon: 'laptop-code',
226
+ title: 'Demo',
227
+ description: 'Practical examples and code snippets',
228
+ },
229
+ {
230
+ id: 'faq',
231
+ icon: 'question-circle',
232
+ title: 'FAQ',
233
+ description: 'Frequently asked questions',
234
+ },
235
+ {
236
+ id: 'community',
237
+ icon: 'users',
238
+ title: 'Community',
239
+ description: 'Join our developer community',
240
+ },
241
+ ];
241
242
 
242
- // var itemEl = evt.item; // dragged HTMLElement
243
- // evt.to; // target list
244
- // evt.from; // previous list
245
- // evt.oldIndex; // element's old index within old parent
246
- // evt.newIndex; // element's new index within new parent
247
- // evt.oldDraggableIndex; // element's old index within old parent, only counting draggable elements
248
- // evt.newDraggableIndex; // element's new index within new parent, only counting draggable elements
249
- // evt.clone; // the clone element
250
- // evt.pullMode; // when item is in another sortable: `"clone"` if cloning, `true` if moving
251
- },
252
- });
243
+ return html`
244
+ <style>
245
+ .docs-landing {
246
+ padding: 2rem;
247
+ max-width: 1200px;
248
+ margin: 0 auto;
249
+ height: 100%;
250
+ box-sizing: border-box;
251
+ }
252
+ .docs-header {
253
+ text-align: center;
254
+ margin-bottom: 3rem;
255
+ opacity: 0;
256
+ animation: fadeInUp 0.6s ease-out forwards;
257
+ }
258
+ .docs-header h1 {
259
+ font-size: 2.5rem;
260
+ margin: 0 0 1rem;
261
+ line-height: 1.2;
262
+ }
263
+ .docs-header p {
264
+ font-size: 1.2rem;
265
+ max-width: 700px;
266
+ margin: 0 auto 2rem;
267
+ line-height: 1.6;
268
+ }
269
+ .docs-grid {
270
+ display: grid;
271
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
272
+ gap: 1.5rem;
273
+ margin: 0;
274
+ padding: 0;
275
+ list-style: none;
276
+ }
277
+ .docs-card-container {
278
+ cursor: pointer;
279
+ opacity: 0;
280
+ margin-bottom: 3rem;
281
+ animation: fadeInUp 0.6s ease-out forwards;
282
+ }
283
+ .docs-card {
284
+ border-radius: 8px;
285
+ padding: 1.5rem;
286
+ display: flex;
287
+ flex-direction: column;
288
+ height: 100%;
289
+ position: relative;
290
+ transition: all 0.3s ease-in-out;
291
+ }
292
+
293
+ .card-icon {
294
+ font-size: 1.75rem;
295
+ width: 56px;
296
+ height: 56px;
297
+ border-radius: 12px;
298
+ display: flex;
299
+ align-items: center;
300
+ justify-content: center;
301
+ margin: 0 0 1.25rem;
302
+ transition: transform 0.2s ease;
303
+ }
304
+
305
+ .card-content {
306
+ flex: 1;
307
+ }
308
+ .card-content h3 {
309
+ margin: 0 0 0.5rem;
310
+ font-size: 1.25rem;
311
+ font-weight: 600;
312
+ }
313
+ .card-content p {
314
+ margin: 0;
315
+ font-size: 0.95rem;
316
+ transition: color 0.3s ease;
317
+ }
318
+ </style>
319
+
320
+ <style>
321
+ ${docsData
322
+ .map(
323
+ (_, index) => css`
324
+ .docs-card-container:nth-child(${index + 1}) {
325
+ animation-delay: ${0.1 * (index + 1)}s;
326
+ }
327
+ `,
328
+ )
329
+ .join('')}
330
+ </style>
253
331
 
254
- return '';
255
- return html` <div class="in section-mp">${docMenuRender}</div>`;
256
- return html` <div class="in section-mp">
257
- ${await DropDown.Render({
258
- id: 'dropdown-docs',
259
- disableClose: true,
260
- disableSelectLabel: true,
261
- disableSelectOptionsLabel: true,
262
- disableSearchBox: true,
263
- open: true,
264
- lastSelectClass: 'hover-active',
265
- label: renderMenuLabel({
266
- icon: html`<i class="fas fa-book"></i>`,
267
- text: html`${Translate.Render('docs')}`,
268
- }),
269
- containerClass: '',
270
- data: this.Data.map((docTypeData) => {
271
- return {
272
- display: docTypeData.label,
273
- value: docTypeData.type,
274
- onClick: async () => {
275
- console.warn(this.viewUrl[docTypeData.type]());
276
- },
277
- };
278
- }),
279
- })}
280
- </div>`;
332
+ <div class="docs-landing">
333
+ <div class="docs-header">
334
+ <h1>Documentation</h1>
335
+ <p>
336
+ Find everything you need to build amazing applications with our platform. Get started with our guides, API
337
+ reference, and examples.
338
+ </p>
339
+ <!--
340
+ <div class="search-bar">
341
+ <i class="fas fa-search"></i>
342
+ <input type="text" placeholder="Search documentation..." id="docs-search">
343
+ </div>
344
+ -->
345
+ </div>
346
+
347
+ <ul class="docs-grid">
348
+ ${docsData
349
+ .map((item) => {
350
+ setTimeout(() => {
351
+ if (s(`.docs-card-container-${item.id}`)) {
352
+ s(`.docs-card-container-${item.id}`).onclick = () => {
353
+ if (item.id.match('demo')) {
354
+ location.href = 'https://underpostnet.github.io/pwa-microservices-template-ghpkg/';
355
+ } else if (item.id.match('api')) {
356
+ if (s(`.btn-docs-api`)) s(`.btn-docs-api`).click();
357
+ } else {
358
+ if (s(`.btn-docs-src`)) s(`.btn-docs-src`).click();
359
+ }
360
+ };
361
+ }
362
+ });
363
+ return html`
364
+ <div class="in docs-card-container docs-card-container-${item.id}">
365
+ <li class="docs-card">
366
+ <div class="card-icon">
367
+ <i class="fas fa-${item.icon}"></i>
368
+ </div>
369
+ <div class="card-content">
370
+ <h3>${item.title}</h3>
371
+ <p>${item.description}</p>
372
+ </div>
373
+ </li>
374
+ </div>
375
+ `;
376
+ })
377
+ .join('')}
378
+ </ul>
379
+ </div>
380
+ `;
381
+ }
281
382
  },
282
383
  };
283
384
 
@@ -7,7 +7,7 @@ import { loggerFactory } from './Logger.js';
7
7
  import { RichText } from './RichText.js';
8
8
  import { ToggleSwitch } from './ToggleSwitch.js';
9
9
  import { Translate } from './Translate.js';
10
- import { htmls, s } from './VanillaJs.js';
10
+ import { htmls, htmlStrSanitize, s } from './VanillaJs.js';
11
11
  const logger = loggerFactory(import.meta);
12
12
 
13
13
  const fileFormDataFactory = (e, extensions) => {
@@ -61,22 +61,27 @@ const Input = {
61
61
  };
62
62
  });
63
63
 
64
- const inputElement = html` <input
65
- type="${options?.type ? options.type : 'text'}"
66
- class="${options.inputClass ? options.inputClass : 'in wfa'} ${id}"
67
- ${options?.min !== undefined ? `min="${options.min}"` : ''}
68
- ${options?.max !== undefined ? `max="${options.max}"` : ''}
69
- placeholder${options?.placeholder ? `="${options.placeholder}"` : ''}
70
- ${options?.value !== undefined ? `value="${options.value}"` : ''}
71
- ${options?.autocomplete ? `autocomplete="${options.autocomplete}"` : ''}
72
- ${options?.disabled ? `disabled` : ''}
73
- ${options?.name !== undefined ? `name="${options.name}"` : ''}
74
- ${options?.pattern !== undefined ? `pattern="${options.pattern}"` : ''}
75
- ${options?.pattern === undefined && options.type === 'tel' ? `pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"` : ''}
76
- ${options?.required ? ` required ` : ''}
77
- ${options?.accept ? `accept="${options.accept}"` : ''}
78
- ${options?.multiple ? `multiple="multiple"` : ''}
79
- />
64
+ const labelValue = htmlStrSanitize(options.label) ? htmlStrSanitize(options.label) : id;
65
+
66
+ const inputElement = html` <label for="${id}-name">
67
+ <span class="hide">${labelValue}</span>
68
+ <input
69
+ type="${options?.type ? options.type : 'text'}"
70
+ class="${options.inputClass ? options.inputClass : 'in wfa'} ${id}"
71
+ ${options?.min !== undefined ? `min="${options.min}"` : ''}
72
+ ${options?.max !== undefined ? `max="${options.max}"` : ''}
73
+ placeholder${options?.placeholder ? `="${options.placeholder}"` : ''}
74
+ ${options?.value !== undefined ? `value="${options.value}"` : ''}
75
+ ${options?.autocomplete ? `autocomplete="${options.autocomplete}"` : ''}
76
+ ${options?.disabled ? `disabled` : ''}
77
+ ${options?.name !== undefined ? `name="${options.name}"` : `name='${id}-name'`}
78
+ ${options?.pattern !== undefined ? `pattern="${options.pattern}"` : ''}
79
+ ${options?.pattern === undefined && options.type === 'tel' ? `pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"` : ''}
80
+ ${options?.required ? ` required ` : ''}
81
+ ${options?.accept ? `accept="${options.accept}"` : ''}
82
+ ${options?.multiple ? `multiple="multiple"` : ''}
83
+ id="${id}-name"
84
+ /></label>
80
85
  <div class="${id}-input-extension input-info input-extension ${options?.extension ? '' : 'hide'}">
81
86
  ${options?.extension ? await options.extension() : ''}
82
87
  </div>`;
@@ -244,7 +249,12 @@ const Input = {
244
249
  };
245
250
 
246
251
  const InputFile = {
247
- Render: async function ({ id, multiple }, on = { change: () => {}, clear: () => {} }) {
252
+ Render: async function (
253
+ options = { id: '', multiple: false, extensionsAccept: [] },
254
+ on = { change: () => {}, clear: () => {} },
255
+ ) {
256
+ let { id, multiple, extensionsAccept } = options;
257
+ if (!extensionsAccept) extensionsAccept = [];
248
258
  // drag drop multi file
249
259
  const gridId = `ag-grid-input-file-${id}`;
250
260
  setTimeout(() => {
@@ -322,7 +332,12 @@ const InputFile = {
322
332
  return html` <div class="fl">
323
333
  <div class="in fll input-file-col">
324
334
  <div class="in section-mp input-file-sub-col">
325
- <input class="wfa ${id}" type="file" ${multiple ? `multiple="multiple"` : ''} />
335
+ <input
336
+ class="wfa ${id}"
337
+ type="file"
338
+ ${multiple ? `multiple="multiple"` : ''}
339
+ ${extensionsAccept.length > 0 ? `accept="${extensionsAccept.join(', ')}"` : ''}
340
+ />
326
341
  <div class="in">
327
342
  ${await BtnIcon.Render({
328
343
  class: `wfa btn-clear-input-file-${id}`,
@@ -129,16 +129,11 @@ const LoadingAnimation = {
129
129
  removeSplashScreen: function (backgroundContainer, callBack) {
130
130
  if (s(`.clean-cache-container`)) s(`.clean-cache-container`).style.display = 'none';
131
131
  if (!backgroundContainer) backgroundContainer = '.ssr-background';
132
- if (s(backgroundContainer))
133
- setTimeout(() => {
134
- s(backgroundContainer).style.opacity = 0;
135
- setTimeout(async () => {
136
- s(backgroundContainer).style.display = 'none';
137
- if (s(`.modal-menu`)) s(`.modal-menu`).classList.remove('hide');
138
- if (s(`.main-body-btn-container`)) s(`.main-body-btn-container`).classList.remove('hide');
139
- if (callBack) callBack();
140
- }, 300);
141
- });
132
+ if (s(backgroundContainer)) {
133
+ s(backgroundContainer).style.display = 'none';
134
+ if (s(`.main-body-btn-container`)) s(`.main-body-btn-container`).classList.remove('hide');
135
+ if (callBack) callBack();
136
+ }
142
137
  },
143
138
 
144
139
  RenderCurrentSrcLoad: function (event) {