underpost 2.8.31 → 2.8.42

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 (53) hide show
  1. package/.github/workflows/ghpkg.yml +10 -7
  2. package/.github/workflows/pwa-microservices-template.page.yml +10 -3
  3. package/.vscode/extensions.json +9 -0
  4. package/.vscode/settings.json +10 -4
  5. package/AUTHORS.md +16 -5
  6. package/CHANGELOG.md +8 -0
  7. package/Dockerfile +19 -26
  8. package/README.md +1 -1
  9. package/bin/build.js +283 -0
  10. package/bin/db.js +2 -24
  11. package/bin/deploy.js +59 -49
  12. package/bin/file.js +3 -2
  13. package/bin/index.js +34 -41
  14. package/bin/util.js +9 -89
  15. package/bin/vs.js +22 -0
  16. package/conf.js +27 -143
  17. package/docker-compose.yml +1 -1
  18. package/manifests/core/kustomization.yaml +11 -0
  19. package/manifests/kind-config.yaml +12 -0
  20. package/manifests/letsencrypt-prod.yaml +15 -0
  21. package/package.json +4 -33
  22. package/src/api/user/user.model.js +7 -2
  23. package/src/client/components/core/CalendarCore.js +3 -0
  24. package/src/client/components/core/CommonJs.js +25 -0
  25. package/src/client/components/core/Modal.js +5 -5
  26. package/src/client/components/core/Panel.js +3 -1
  27. package/src/client/components/core/Translate.js +16 -4
  28. package/src/client/components/core/Validator.js +9 -1
  29. package/src/client/services/default/default.management.js +4 -2
  30. package/src/index.js +8 -1
  31. package/src/runtime/lampp/Lampp.js +1 -13
  32. package/src/runtime/xampp/Xampp.js +0 -13
  33. package/src/server/auth.js +3 -3
  34. package/src/server/client-build.js +3 -13
  35. package/src/server/conf.js +294 -27
  36. package/src/server/dns.js +2 -3
  37. package/src/server/logger.js +10 -5
  38. package/src/server/network.js +0 -36
  39. package/src/server/process.js +1 -1
  40. package/src/server/project.js +39 -0
  41. package/src/server/proxy.js +4 -26
  42. package/src/server/runtime.js +6 -7
  43. package/manifests/test/underpost-engine-pod.yaml +0 -108
  44. package/src/server/prompt-optimizer.js +0 -28
  45. /package/manifests/{underpost-engine-backup-access.yaml → core/underpost-engine-backup-access.yaml} +0 -0
  46. /package/manifests/{underpost-engine-backup-pv-pvc.yaml → core/underpost-engine-backup-pv-pvc.yaml} +0 -0
  47. /package/manifests/{underpost-engine-headless-service.yaml → core/underpost-engine-headless-service.yaml} +0 -0
  48. /package/manifests/{underpost-engine-mongodb-backup-cronjob.yaml → core/underpost-engine-mongodb-backup-cronjob.yaml} +0 -0
  49. /package/manifests/{test → core}/underpost-engine-mongodb-configmap.yaml +0 -0
  50. /package/manifests/{underpost-engine-pv-pvc.yaml → core/underpost-engine-pv-pvc.yaml} +0 -0
  51. /package/manifests/{underpost-engine-statefulset.yaml → core/underpost-engine-statefulset.yaml} +0 -0
  52. /package/manifests/{test → deployment}/mongo-express.yaml +0 -0
  53. /package/manifests/{test → deployment}/phpmyadmin.yaml +0 -0
package/conf.js CHANGED
@@ -2,7 +2,7 @@ import dotenv from 'dotenv';
2
2
 
3
3
  dotenv.config();
4
4
 
5
- const DefaultConf = {
5
+ const DefaultConf = /**/ {
6
6
  client: {
7
7
  default: {
8
8
  metadata: {
@@ -79,58 +79,16 @@ const DefaultConf = {
79
79
  ],
80
80
  },
81
81
  views: [
82
- {
83
- path: '/',
84
- title: 'Home',
85
- client: 'Default',
86
- ssr: 'Default',
87
- },
88
- {
89
- path: '/home',
90
- title: 'Home',
91
- client: 'Default',
92
- ssr: 'Default',
93
- },
94
- {
95
- path: '/settings',
96
- client: 'Default',
97
- ssr: 'Default',
98
- },
99
- {
100
- path: '/log-in',
101
- client: 'Default',
102
- ssr: 'Default',
103
- },
104
- {
105
- path: '/sign-up',
106
- client: 'Default',
107
- ssr: 'Default',
108
- },
109
- {
110
- path: '/log-out',
111
- client: 'Default',
112
- ssr: 'Default',
113
- },
114
- {
115
- path: '/account',
116
- client: 'Default',
117
- ssr: 'Default',
118
- },
119
- {
120
- path: '/docs',
121
- client: 'Default',
122
- ssr: 'Default',
123
- },
124
- {
125
- path: '/recover',
126
- client: 'Default',
127
- ssr: 'Default',
128
- },
129
- {
130
- path: '/default-management',
131
- client: 'Default',
132
- ssr: 'Default',
133
- },
82
+ { path: '/', title: 'Home', client: 'Default', ssr: 'Default' },
83
+ { path: '/home', title: 'Home', client: 'Default', ssr: 'Default' },
84
+ { path: '/settings', client: 'Default', ssr: 'Default' },
85
+ { path: '/log-in', client: 'Default', ssr: 'Default' },
86
+ { path: '/sign-up', client: 'Default', ssr: 'Default' },
87
+ { path: '/log-out', client: 'Default', ssr: 'Default' },
88
+ { path: '/account', client: 'Default', ssr: 'Default' },
89
+ { path: '/docs', client: 'Default', ssr: 'Default' },
90
+ { path: '/recover', client: 'Default', ssr: 'Default' },
91
+ { path: '/default-management', client: 'Default', ssr: 'Default' },
134
92
  { client: 'Default', ssr: 'Default', path: '/404', title: '404 Not Found' },
135
93
  { client: 'Default', ssr: 'Default', path: '/500', title: '500 Server Error' },
136
94
  ],
@@ -141,24 +99,15 @@ const DefaultConf = {
141
99
  import_name: '@neodrag/vanilla',
142
100
  import_name_build: '/dist/@neodrag-vanilla/index.js',
143
101
  },
144
- {
145
- folder: './node_modules/@fortawesome/fontawesome-free',
146
- public_folder: '/dist/fontawesome',
147
- },
102
+ { folder: './node_modules/@fortawesome/fontawesome-free', public_folder: '/dist/fontawesome' },
148
103
  {
149
104
  folder: './node_modules/sortablejs/modular',
150
105
  public_folder: '/dist/sortablejs',
151
106
  import_name: 'sortablejs',
152
107
  import_name_build: '/dist/sortablejs/sortable.complete.esm.js',
153
108
  },
154
- {
155
- folder: './node_modules/validator',
156
- public_folder: '/dist/validator',
157
- },
158
- {
159
- folder: './node_modules/@loadingio/css-spinner/entries',
160
- public_folder: '/dist/loadingio',
161
- },
109
+ { folder: './node_modules/validator', public_folder: '/dist/validator' },
110
+ { folder: './node_modules/@loadingio/css-spinner/entries', public_folder: '/dist/loadingio' },
162
111
  {
163
112
  import_name: 'ag-grid-community',
164
113
  import_name_build: '/dist/ag-grid-community/ag-grid-community.auto.complete.esm.min.js',
@@ -173,10 +122,7 @@ const DefaultConf = {
173
122
  import_name: 'socket.io/client-dist/socket.io.esm.min.js',
174
123
  import_name_build: '/dist/socket.io/socket.io.esm.min.js',
175
124
  },
176
- {
177
- folder: './node_modules/peerjs/dist',
178
- public_folder: '/dist/peerjs',
179
- },
125
+ { folder: './node_modules/peerjs/dist', public_folder: '/dist/peerjs' },
180
126
  ],
181
127
  services: ['default', 'core', 'user', 'test', 'file'],
182
128
  },
@@ -185,35 +131,12 @@ const DefaultConf = {
185
131
  Default: {
186
132
  head: ['Seo', 'Pwa', 'Css', 'DefaultScripts', 'Production'],
187
133
  body: ['CacheControl', 'DefaultSplashScreen', '404', '500'],
188
- mailer: {
189
- userVerifyEmail: 'DefaultVerifyEmail',
190
- userRecoverEmail: 'DefaultRecoverEmail',
191
- },
134
+ mailer: { userVerifyEmail: 'DefaultVerifyEmail', userRecoverEmail: 'DefaultRecoverEmail' },
192
135
  offline: [
193
- {
194
- path: '/offline',
195
- title: 'No Network Connection',
196
- client: 'NoNetworkConnection',
197
- head: [],
198
- body: [],
199
- },
200
- {
201
- path: '/maintenance',
202
- title: 'Server Maintenance',
203
- client: 'Maintenance',
204
- head: [],
205
- body: [],
206
- },
207
- ],
208
- pages: [
209
- {
210
- path: '/test',
211
- title: 'Test',
212
- client: 'Test',
213
- head: [],
214
- body: [],
215
- },
136
+ { path: '/offline', title: 'No Network Connection', client: 'NoNetworkConnection', head: [], body: [] },
137
+ { path: '/maintenance', title: 'Server Maintenance', client: 'Maintenance', head: [], body: [] },
216
138
  ],
139
+ pages: [{ path: '/test', title: 'Test', client: 'Test', head: [], body: [] }],
217
140
  },
218
141
  },
219
142
  server: {
@@ -231,29 +154,14 @@ const DefaultConf = {
231
154
  ws: 'core',
232
155
  peer: true,
233
156
  proxy: [80, 443],
234
- db: {
235
- provider: 'mongoose',
236
- // mongodb://<username>:<password>@<pod-0-name>.<headless-service-name>.<namespace>.svc.cluster.local:27017
237
- // ,<pod-1-name>.<headless-service-name>.<namespace>.svc.cluster.local:27017/<database-name>?replicaSet=rs0;
238
- // <k8s-pod-name>.<k8s-internal-service-name>.<k8s-namespace>.<cluster-name>
239
- // host: 'mongodb://mongodb-0.mongodb-service.default.svc.cluster.local:27017?replicaSet=rs0',
240
- host: 'mongodb://127.0.0.1:27017',
241
- // host: `mongodb://${process.env.MONGO_INITDB_ROOT_USERNAME}:${process.env.MONGO_INITDB_ROOT_PASSWORD}@mongodb-0.mongodb-service:27017`, // ?replicaSet=rs0
242
- name: 'default',
243
- },
157
+ db: { provider: 'mongoose', host: 'mongodb://127.0.0.1:27017', name: 'default' },
244
158
  mailer: {
245
- sender: {
246
- email: 'noreply@default.net',
247
- name: 'Default',
248
- },
159
+ sender: { email: 'noreply@default.net', name: 'Default' },
249
160
  transport: {
250
161
  host: 'smtp.default.com',
251
162
  port: 465,
252
163
  secure: true,
253
- auth: {
254
- user: 'noreply@default.net',
255
- pass: '',
256
- },
164
+ auth: { user: 'noreply@default.net', pass: '' },
257
165
  },
258
166
  },
259
167
  },
@@ -271,35 +179,11 @@ const DefaultConf = {
271
179
  },
272
180
  },
273
181
  cron: {
274
- ipDaemon: {
275
- ip: null,
276
- },
277
- records: {
278
- A: [
279
- {
280
- host: 'example.com',
281
- dns: 'dondominio',
282
- api_key: '???',
283
- user: '???',
284
- },
285
- ],
286
- },
287
- backups: [
288
- {
289
- deployGroupId: 'default-group',
290
- },
291
- ],
292
- jobs: {
293
- dns: {
294
- expression: '* * * * *',
295
- enabled: true,
296
- },
297
- backups: {
298
- expression: '0 1 * * *',
299
- enabled: true,
300
- },
301
- },
182
+ ipDaemon: { ip: null },
183
+ records: { A: [{ host: 'example.com', dns: 'dondominio', api_key: '???', user: '???' }] },
184
+ backups: [{ deployGroupId: 'default-group' }],
185
+ jobs: { dns: { expression: '* * * * *', enabled: true }, backups: { expression: '0 1 * * *', enabled: true } },
302
186
  },
303
- };
187
+ }; /**/
304
188
 
305
189
  export { DefaultConf };
@@ -58,7 +58,7 @@ services:
58
58
  cpus: '0.25'
59
59
  memory: 20M
60
60
  labels: # labels in Compose file instead of Dockerfile
61
- engine.version: '2.8.31'
61
+ engine.version: '2.8.42'
62
62
  networks:
63
63
  - load-balancer
64
64
 
@@ -0,0 +1,11 @@
1
+ ---
2
+ # kubectl apply -k core/.
3
+ apiVersion: kustomize.config.k8s.io/v1beta1
4
+ kind: Kustomization
5
+ resources:
6
+ - underpost-engine-pv-pvc.yaml
7
+ - underpost-engine-headless-service.yaml
8
+ - underpost-engine-statefulset.yaml
9
+ - underpost-engine-backup-pv-pvc.yaml
10
+ - underpost-engine-mongodb-backup-cronjob.yaml
11
+ - underpost-engine-backup-access.yaml
@@ -0,0 +1,12 @@
1
+ kind: Cluster
2
+ apiVersion: kind.x-k8s.io/v1alpha4
3
+ nodes:
4
+ - role: control-plane
5
+ - role: worker
6
+ extraPortMappings:
7
+ - containerPort: 80
8
+ hostPort: 80
9
+ listenAddress: '0.0.0.0'
10
+ - containerPort: 443
11
+ hostPort: 443
12
+ listenAddress: '0.0.0.0'
@@ -0,0 +1,15 @@
1
+ apiVersion: cert-manager.io/v1
2
+ kind: ClusterIssuer
3
+ metadata:
4
+ name: letsencrypt-prod
5
+ namespace: cert-manager
6
+ spec:
7
+ acme:
8
+ email: development@underpost.net
9
+ privateKeySecretRef:
10
+ name: letsencrypt-prod
11
+ server: https://acme-v02.api.letsencrypt.org/directory
12
+ solvers:
13
+ - http01:
14
+ ingress:
15
+ class: contour
package/package.json CHANGED
@@ -2,35 +2,20 @@
2
2
  "type": "module",
3
3
  "main": "src/index.js",
4
4
  "name": "underpost",
5
- "version": "2.8.31",
5
+ "version": "2.8.42",
6
6
  "description": "pwa api rest template",
7
7
  "scripts": {
8
8
  "start": "env-cmd -f .env.production node --max-old-space-size=8192 src/server",
9
- "pm2": "env-cmd -f .env.production pm2 start src/server.js --node-args=\"--max-old-space-size=8192\" --name engine && pm2 logs",
10
- "ssl": "env-cmd -f .env.production node bin/ssl",
11
- "pm2-delete": "pm2 delete engine",
12
- "build": "node bin/deploy build-full-client && node bin/deploy fix-deps",
13
- "build-production": "env-cmd -f .env.production node bin/deploy build-full-client",
9
+ "build": "node bin/deploy build-full-client",
14
10
  "dev": "env-cmd -f .env.development node src/client.dev default",
15
11
  "dev-api": "env-cmd -f .env.development nodemon --watch src --ignore src/client src/api",
16
12
  "docs": "jsdoc -c jsdoc.json",
17
- "backup": "node bin/db default.net/ export",
18
- "install-template": "npm install && npm run build",
19
13
  "install-global": "npm install -g pm2 && npm install -g jsdoc && npm install -g prettier && npm install -g env-cmd && npm install -g yarn && npm install -g auto-changelog",
20
14
  "install-test": "npm install -g mocha && npm install -g c8 && npm install -g nyc && npm install -g coveralls",
21
- "install-vs-extensions": "node bin/vs import",
22
- "preinstall": "npm config set audit false && npm config set loglevel error",
23
- "restore-preinstall": "npm config set audit true && npm config set loglevel notice",
24
- "install": "npm run install-global && npm run install-test && npm run restore-preinstall --no-audit --no-warnings",
15
+ "install": "npm run install-global && npm run install-test",
25
16
  "docker:start": "docker-compose up",
26
17
  "prettier": "prettier --write .",
27
- "coveralls": "nyc npm run test --reporter=text-lcov | coveralls -v",
28
- "test": "env-cmd -f .env.test c8 mocha",
29
- "update": "npm update -g && npm update && npm audit fix --force && npm audit fix --force",
30
- "underpost-publish": "npm publish --provenance --access public",
31
- "underpost-unpublish": "npm unpublish underpost@2.5.x",
32
- "login": "npm adduser",
33
- "bin": "npm link --force"
18
+ "test": "env-cmd -f .env.test c8 mocha"
34
19
  },
35
20
  "bin": {
36
21
  "underpost": "bin/index.js"
@@ -54,13 +39,8 @@
54
39
  "dependencies": {
55
40
  "@fortawesome/fontawesome-free": "^6.4.2",
56
41
  "@fullcalendar/rrule": "^6.1.15",
57
- "@google/generative-ai": "^0.21.0",
58
42
  "@loadingio/css-spinner": "^2.0.2",
59
43
  "@neodrag/vanilla": "^2.0.3",
60
- "@nomiclabs/hardhat-ethers": "^2.2.3",
61
- "@nomiclabs/hardhat-etherscan": "^3.1.8",
62
- "@nomiclabs/hardhat-waffle": "^2.0.6",
63
- "@openzeppelin/contracts": "^5.0.2",
64
44
  "adm-zip": "^0.5.10",
65
45
  "ag-grid-community": "31.0.0",
66
46
  "axios": "^1.5.1",
@@ -74,12 +54,9 @@
74
54
  "compression": "^1.7.4",
75
55
  "cors": "^2.8.5",
76
56
  "d3": "^7.9.0",
77
- "deepmerge": "^4.3.1",
78
- "detect-port": "^1.5.1",
79
57
  "dotenv": "^16.3.1",
80
58
  "easymde": "^2.18.0",
81
59
  "env-cmd": "^10.1.0",
82
- "eventemitter3": "^5.0.1",
83
60
  "express": "^4.18.2",
84
61
  "express-fileupload": "^1.4.3",
85
62
  "favicons": "^7.2.0",
@@ -90,14 +67,11 @@
90
67
  "http-proxy-middleware": "^2.0.6",
91
68
  "ignore-walk": "^6.0.4",
92
69
  "iovalkey": "^0.2.1",
93
- "is-admin": "^4.0.0",
94
- "is-ip": "^5.0.1",
95
70
  "jimp": "^0.22.12",
96
71
  "joystick-controller": "^1.0.15",
97
72
  "json-colorizer": "^2.2.2",
98
73
  "jsonwebtoken": "^9.0.2",
99
74
  "keyword-extractor": "^0.0.28",
100
- "kill-port-process": "^3.2.0",
101
75
  "log-update": "^6.0.0",
102
76
  "mariadb": "^3.2.2",
103
77
  "marked": "^12.0.2",
@@ -115,7 +89,6 @@
115
89
  "rrule": "^2.8.1",
116
90
  "sharp": "^0.32.5",
117
91
  "shelljs": "^0.8.5",
118
- "simple-git": "^3.26.0",
119
92
  "simple-icons": "^13.9.0",
120
93
  "sitemap": "^7.1.1",
121
94
  "socket.io": "^4.8.0",
@@ -126,13 +99,11 @@
126
99
  "uglify-js": "^3.17.4",
127
100
  "validator": "^13.11.0",
128
101
  "vanilla-jsoneditor": "^2.3.2",
129
- "web3": "^4.13.0",
130
102
  "winston": "^3.11.0"
131
103
  },
132
104
  "devDependencies": {
133
105
  "clean-jsdoc-theme": "^4.3.0",
134
106
  "easy-json-schema": "^0.0.2-beta",
135
- "hardhat": "^2.22.13",
136
107
  "mocha": "^10.4.0",
137
108
  "plantuml": "^0.0.2",
138
109
  "swagger-autogen": "^2.23.7"
@@ -1,10 +1,9 @@
1
1
  import { Schema, model } from 'mongoose';
2
2
  import validator from 'validator';
3
+ import { userRoleEnum } from '../../client/components/core/CommonJs.js';
3
4
 
4
5
  // https://mongoosejs.com/docs/2.7.x/docs/schematypes.html
5
6
 
6
- const userRoleEnum = ['admin', 'moderator', 'user', 'guest'];
7
-
8
7
  const UserSchema = new Schema(
9
8
  {
10
9
  email: {
@@ -42,6 +41,12 @@ const UserSchema = new Schema(
42
41
  ],
43
42
  default: [],
44
43
  },
44
+ associatedCompanies: [
45
+ {
46
+ company: { type: Schema.Types.ObjectId, ref: 'Company', required: true },
47
+ context: [{ type: String, enum: ['client', 'supplier', 'employee', 'owner'] }],
48
+ },
49
+ ],
45
50
  },
46
51
  {
47
52
  timestamps: true,
@@ -96,6 +96,7 @@ const CalendarCore = {
96
96
  const renderCalendar = (events) => {
97
97
  const calendarEl = s(`.calendar-${idPanel}`);
98
98
  this.Data[options.idModal].calendar = new FullCalendar.Calendar(calendarEl, {
99
+ allDaySlot: false,
99
100
  plugins: [
100
101
  FullCalendar.DayGrid.default,
101
102
  FullCalendar.TimeGrid.default,
@@ -127,6 +128,7 @@ const CalendarCore = {
127
128
  if (!args.event.extendedProps._id) return args.event.remove();
128
129
  const dateData = eventDateFactory(args.event);
129
130
  if (
131
+ new Date(dateData.start).getTime() <= new Date().getTime() ||
130
132
  CalendarCore.Data[options.idModal].hiddenDates.find(
131
133
  (d) => d.eventSchedulerId === dateData.event._id && d.date === dateData.start,
132
134
  )
@@ -275,6 +277,7 @@ const CalendarCore = {
275
277
  data: this.Data[options.idModal].data,
276
278
  formContainerClass: '',
277
279
  scrollClassContainer: `main-body-calendar-${options.idModal}`,
280
+ role: options.role,
278
281
  originData: () => this.Data[options.idModal].originData,
279
282
  filesData: () => this.Data[options.idModal].filesData,
280
283
  onClick: async function ({ payload }) {
@@ -662,6 +662,22 @@ function componentFromStr(numStr, percent) {
662
662
  return percent ? Math.floor((255 * Math.min(100, num)) / 100) : Math.min(255, num);
663
663
  }
664
664
 
665
+ const isChileanIdentityDocument = function (rutCompleto) {
666
+ const dv = function (T) {
667
+ let M = 0,
668
+ S = 1;
669
+ for (; T; T = Math.floor(T / 10)) S = (S + (T % 10) * (9 - (M++ % 6))) % 11;
670
+ return S ? S - 1 : 'k';
671
+ };
672
+ rutCompleto = rutCompleto.replace('‐', '-');
673
+ if (!/^[0-9]+[-|‐]{1}[0-9kK]{1}$/.test(rutCompleto)) return false;
674
+ var tmp = rutCompleto.split('-');
675
+ var digv = tmp[1];
676
+ var rut = tmp[0];
677
+ if (digv == 'K') digv = 'k';
678
+ return dv(rut) == digv;
679
+ };
680
+
665
681
  function rgbToHex(rgb) {
666
682
  const rgbRegex = /^rgb\(\s*(-?\d+)(%?)\s*,\s*(-?\d+)(%?)\s*,\s*(-?\d+)(%?)\s*\)$/;
667
683
  let result,
@@ -795,6 +811,11 @@ const generateRandomPasswordSelection = (length) => {
795
811
  // 0b = Binary
796
812
  // 0o = Octal
797
813
 
814
+ const userRoleEnum = ['admin', 'moderator', 'user', 'guest'];
815
+
816
+ const commonAdminGuard = (role) => userRoleEnum.indexOf(role) === userRoleEnum.indexOf('admin');
817
+ const commonModeratorGuard = (role) => userRoleEnum.indexOf(role) <= userRoleEnum.indexOf('moderator');
818
+
798
819
  export {
799
820
  s4,
800
821
  range,
@@ -848,4 +869,8 @@ export {
848
869
  hexToNumber,
849
870
  numberToHex,
850
871
  generateRandomPasswordSelection,
872
+ userRoleEnum,
873
+ commonAdminGuard,
874
+ commonModeratorGuard,
875
+ isChileanIdentityDocument,
851
876
  };
@@ -542,12 +542,12 @@ const Modal = {
542
542
  if (routerId) {
543
543
  if (
544
544
  s(`.main-btn-${routerId}`) &&
545
- (routerId.toLocaleLowerCase().match(s(`.${id}`).value.toLocaleLowerCase()) ||
545
+ (routerId.toLowerCase().match(s(`.${id}`).value.toLowerCase()) ||
546
546
  (Translate.Data[routerId] &&
547
547
  Object.keys(Translate.Data[routerId]).filter((keyLang) =>
548
548
  Translate.Data[routerId][keyLang]
549
- .toLocaleLowerCase()
550
- .match(s(`.${id}`).value.toLocaleLowerCase()),
549
+ .toLowerCase()
550
+ .match(s(`.${id}`).value.toLowerCase()),
551
551
  ).length > 0))
552
552
  ) {
553
553
  const fontAwesomeIcon = getAllChildNodes(s(`.main-btn-${routerId}`)).find((e) => {
@@ -1696,7 +1696,7 @@ const Modal = {
1696
1696
  const htmlRender = html`
1697
1697
  <br />
1698
1698
  <div class="in section-mp" style="font-size: 40px; text-align: center">
1699
- <i class="fas fa-question-circle"></i>
1699
+ ${options.icon ? options.icon : html` <i class="fas fa-question-circle"></i>`}
1700
1700
  </div>
1701
1701
  ${await options.html()}
1702
1702
  <div class="in section-mp">
@@ -1707,7 +1707,7 @@ const Modal = {
1707
1707
  style: `margin: auto`,
1708
1708
  })}
1709
1709
  </div>
1710
- <div class="in section-mp">
1710
+ <div class="in section-mp ${options.disableBtnCancel ? 'hide' : ''}">
1711
1711
  ${await BtnIcon.Render({
1712
1712
  class: `in section-mp form-button btn-cancel-${id}`,
1713
1713
  label: Translate.Render('cancel'),
@@ -654,7 +654,9 @@ const Panel = {
654
654
  >
655
655
  <div class="in ${idPanel}-form-header">
656
656
  ${await BtnIcon.Render({
657
- class: `section-mp btn-custom btn-${idPanel}-add`,
657
+ class: `section-mp btn-custom btn-${idPanel}-add ${
658
+ options?.role?.add ? (!options.role.add() ? 'hide' : '') : ''
659
+ }`,
658
660
  label: html`<i class="fas fa-plus"></i> ${Translate.Render('add')}`,
659
661
  type: 'button',
660
662
  })}
@@ -11,19 +11,20 @@ const Translate = {
11
11
  Data: {},
12
12
  Token: {},
13
13
  Event: {},
14
+ Options: {},
14
15
  Parse: function (lang) {
15
16
  s('html').lang = lang;
16
17
  Object.keys(this.Token).map((translateHash) => {
17
18
  if (translateHash in this.Token && lang in this.Token[translateHash]) {
18
- if (!('placeholder' in this.Token[translateHash]) && s(`.${translateHash}`))
19
+ if (!('placeholder' in this.Options[translateHash]) && s(`.${translateHash}`))
19
20
  htmls(
20
21
  `.${translateHash}`,
21
- this.Token[translateHash].options?.disableTextFormat
22
+ this.Options[translateHash]?.disableTextFormat
22
23
  ? this.Token[translateHash][lang]
23
24
  : textFormatted(this.Token[translateHash][lang]),
24
25
  );
25
26
  else if ('placeholder' in this.Token[translateHash] && s(this.Token[translateHash].placeholder))
26
- s(this.Token[translateHash].placeholder).placeholder = this.Token[translateHash].options?.disableTextFormat
27
+ s(this.Token[translateHash].placeholder).placeholder = this.Options[translateHash]?.disableTextFormat
27
28
  ? this.Token[translateHash][lang]
28
29
  : textFormatted(this.Token[translateHash][lang]);
29
30
  }
@@ -36,10 +37,10 @@ const Translate = {
36
37
  logger.warn('translate key lang does not exist: ', keyLang);
37
38
  return options.disableTextFormat ? keyLang : textFormatted(keyLang);
38
39
  }
39
- this.Data[keyLang].options = options;
40
40
  if (placeholder) this.Data[keyLang].placeholder = placeholder;
41
41
  keyLang = this.Data[keyLang];
42
42
  const translateHash = getId(this.Token, 'trans');
43
+ this.Options[translateHash] = options;
43
44
  this.Token[translateHash] = newInstance(keyLang);
44
45
  if ('placeholder' in keyLang) {
45
46
  if (s('html').lang in keyLang)
@@ -496,6 +497,17 @@ const TranslateCore = {
496
497
  en: 'Your appointment has been scheduled',
497
498
  es: 'Tu cita ha sido programada',
498
499
  };
500
+ Translate.Data['info'] = { es: 'Información', en: 'Info' };
501
+ Translate.Data['complete-name'] = { es: 'Nombre completo', en: 'Complete name' };
502
+ Translate.Data['identityDocument'] = { es: 'Rut', en: 'Identity document' };
503
+ Translate.Data['day'] = { es: 'Día', en: 'Day' };
504
+ Translate.Data['month'] = { es: 'Mes', en: 'Month' };
505
+ Translate.Data['year'] = { es: 'Año', en: 'Year' };
506
+ Translate.Data['phone'] = { es: 'Teléfono', en: 'Phone' };
507
+ Translate.Data['invalid-identity-document'] = {
508
+ en: 'Invalid identity document',
509
+ es: 'Documento de identidad inválido',
510
+ };
499
511
  },
500
512
  };
501
513
 
@@ -1,4 +1,4 @@
1
- import { validatePassword } from './CommonJs.js';
1
+ import { isChileanIdentityDocument, validatePassword } from './CommonJs.js';
2
2
  import { renderStatus } from './Css.js';
3
3
  import { loggerFactory } from './Logger.js';
4
4
  import { textFormatted, Translate } from './Translate.js';
@@ -58,6 +58,14 @@ const Validator = {
58
58
  if (!validator.isLength(s(`.${validatorData.id}`).value, rule.options))
59
59
  errorMessage += this.renderErrorMessage(rule);
60
60
  break;
61
+
62
+ case 'isChileanIdentityDocument': {
63
+ if (!isChileanIdentityDocument(s(`.${validatorData.id}`).value)) {
64
+ errorMessage += this.renderErrorMessage(undefined, Translate.Render('invalid-identity-document'));
65
+ }
66
+
67
+ break;
68
+ }
61
69
  default:
62
70
  if (
63
71
  validator[rule.type] &&
@@ -1,6 +1,6 @@
1
1
  import { AgGrid } from '../../components/core/AgGrid.js';
2
2
  import { BtnIcon } from '../../components/core/BtnIcon.js';
3
- import { getId, timer } from '../../components/core/CommonJs.js';
3
+ import { getId, getValueFromJoinString, timer } from '../../components/core/CommonJs.js';
4
4
  import { darkTheme } from '../../components/core/Css.js';
5
5
  import { EventsUI } from '../../components/core/EventsUI.js';
6
6
  import { loggerFactory } from '../../components/core/Logger.js';
@@ -88,7 +88,9 @@ const DefaultManagement = {
88
88
  ${Translate.Render('confirm-delete-item')}
89
89
  ${Object.keys(params.data).length > 0
90
90
  ? html`<br />
91
- "${params.data[Object.keys(params.data)[0]]}"`
91
+ "${options.defaultColKeyFocus
92
+ ? getValueFromJoinString(params.data, options.defaultColKeyFocus)
93
+ : params.data[Object.keys(params.data)[0]]}"`
92
94
  : ''}
93
95
  </div>
94
96
  `;
package/src/index.js CHANGED
@@ -4,7 +4,9 @@
4
4
  * @namespace Underpost
5
5
  */
6
6
 
7
+ import { runTest } from './server/conf.js';
7
8
  import { loggerFactory, setUpInfo } from './server/logger.js';
9
+ import Project from './server/project.js';
8
10
 
9
11
  const logger = loggerFactory(import.meta);
10
12
 
@@ -20,7 +22,8 @@ class Underpost {
20
22
  * @type {String}
21
23
  * @memberof Underpost
22
24
  */
23
- static version = 'v2.8.31';
25
+ static version = 'v2.8.42';
26
+ static project = Project;
24
27
 
25
28
  constructor() {}
26
29
 
@@ -40,6 +43,10 @@ class Underpost {
40
43
  static async setUpInfo() {
41
44
  return await setUpInfo(logger);
42
45
  }
46
+
47
+ static runTest() {
48
+ return runTest(Underpost.version);
49
+ }
43
50
  }
44
51
 
45
52
  const up = Underpost;