@saltcorn/data 0.6.1-beta.0 → 0.6.1

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 (60) hide show
  1. package/base-plugin/actions.js +172 -1
  2. package/base-plugin/fieldviews.js +63 -0
  3. package/base-plugin/fileviews.js +41 -0
  4. package/base-plugin/index.js +35 -0
  5. package/base-plugin/types.js +345 -9
  6. package/base-plugin/viewtemplates/edit.js +107 -0
  7. package/base-plugin/viewtemplates/feed.js +46 -0
  8. package/base-plugin/viewtemplates/filter.js +43 -0
  9. package/base-plugin/viewtemplates/list.js +73 -1
  10. package/base-plugin/viewtemplates/listshowlist.js +54 -3
  11. package/base-plugin/viewtemplates/room.js +100 -0
  12. package/base-plugin/viewtemplates/show.js +86 -0
  13. package/base-plugin/viewtemplates/viewable_fields.js +124 -0
  14. package/contracts.js +58 -0
  15. package/db/connect.js +13 -5
  16. package/db/db.test.js +0 -154
  17. package/db/fixtures.js +13 -1
  18. package/db/index.js +42 -3
  19. package/db/reset_schema.js +11 -0
  20. package/db/state.js +105 -36
  21. package/index.js +13 -0
  22. package/migrate.js +4 -1
  23. package/models/backup.js +78 -0
  24. package/models/config.js +113 -22
  25. package/models/crash.js +44 -0
  26. package/models/discovery.js +13 -11
  27. package/models/email.js +17 -0
  28. package/models/eventlog.js +51 -0
  29. package/models/expression.js +49 -1
  30. package/models/field.js +88 -9
  31. package/models/fieldrepeat.js +33 -0
  32. package/models/file.js +23 -4
  33. package/models/form.js +34 -0
  34. package/models/index.js +42 -0
  35. package/models/layout.js +33 -0
  36. package/models/library.js +44 -0
  37. package/models/pack.js +88 -0
  38. package/models/page.js +13 -3
  39. package/models/plugin.js +9 -2
  40. package/models/random.js +36 -0
  41. package/models/role.js +36 -0
  42. package/models/scheduler.js +28 -0
  43. package/models/table.js +34 -15
  44. package/models/table_constraints.js +44 -0
  45. package/models/tenant.js +46 -9
  46. package/models/trigger.js +24 -11
  47. package/models/user.js +33 -8
  48. package/models/view.js +89 -8
  49. package/models/workflow.js +31 -0
  50. package/package.json +7 -5
  51. package/plugin-helper.js +102 -44
  52. package/plugin-testing.js +4 -0
  53. package/tests/exact_views.test.js +5 -5
  54. package/utils.js +4 -0
  55. package/db/internal.js +0 -229
  56. package/db/multi-tenant.js +0 -24
  57. package/db/pg.js +0 -374
  58. package/db/single-tenant.js +0 -8
  59. package/db/sqlite.js +0 -280
  60. package/db/tenants.js +0 -6
package/models/config.js CHANGED
@@ -1,29 +1,33 @@
1
1
  /**
2
2
  * Config Variables
3
- *
3
+ * @category saltcorn-data
4
+ * @module models/config
5
+ * @subcategory models
4
6
  */
5
-
6
7
  const db = require("../db");
7
8
  const { contract, is } = require("contractis");
8
9
  const latestVersion = require("latest-version");
9
10
  const { getConfigFile, configFilePath } = require("../db/connect");
10
11
  const fs = require("fs");
11
12
  const moment = require("moment-timezone");
12
- /**
13
- * Config variables types
14
- * @type {{custom_ssl_private_key: {default: string, fieldview: string, label: string, type: string, hide_value: boolean}, allow_signup: {default: boolean, label: string, type: string, blurb: string}, smtp_host: {default: string, label: string, type: string, blurb: string}, min_role_upload: {default: string, label: string, type: string, blurb: string, required: boolean}, next_hourly_event: {default: null, label: string, type: string}, favicon_id: {default: number, attributes: {select_file_where: {min_role_read: number, mime_super: string}}, label: string, type: string, blurb: string}, login_form: {default: string, label: string, type: string, blurb: string}, installed_packs: {default: *[], label: string, type: string}, custom_ssl_certificate: {default: string, fieldview: string, label: string, type: string, hide_value: boolean}, page_custom_css: {default: string, input_type: string, attributes: {mode: string}, label: string, hide_value: boolean}, cookie_sessions: {default: boolean, restart_required: boolean, root_only: boolean, label: string, type: string, blurb: string}, elevate_verified: {label: string, type: string, blurb: string}, available_plugins: {label: string, type: string}, login_menu: {default: boolean, label: string, type: string, blurb: string}, role_to_create_tenant: {default: string, label: string, type: string, blurb: string}, available_packs: {label: string, type: string}, site_name: {default: string, label: string, type: string, blurb: string}, log_sql: {default: boolean, onChange(*=): void, label: string, type: string, blurb: string}, next_weekly_event: {default: null, label: string, type: string}, admin_home: {default: string, label: string, type: string}, smtp_port: {default: string, label: string, type: string}, allow_forgot: {default: boolean, label: string, type: string, blurb: string}, menu_items: {label: string, type: string}, email_mask: {default: string, label: string, type: string, blurb: string}, latest_npm_version: {default: {}, label: string, type: string}, next_daily_event: {default: null, label: string, type: string}, exttables_min_role_read: {default: {}, label: string, type: string}, layout_by_role: {default: {}, label: string, type: string}, timeout: {default: number, restart_required: boolean, root_only: boolean, label: string, type: string, sublabel: string}, smtp_username: {default: string, label: string, type: string}, smtp_password: {default: string, input_type: string, label: string, type: string}, create_tenant_warning: {default: boolean, label: string, type: string, blurb: string}, home_page_by_role: {label: string, type: string}, staff_home: {default: string, label: string, type: string}, development_mode: {default: boolean, label: string, type: string, blurb: string}, page_custom_html: {default: string, input_type: string, attributes: {mode: string}, label: string, hide_value: boolean}, multitenancy_enabled: {default: boolean, restart_required: boolean, onChange(*=): void, root_only: boolean, label: string, type: string}, signup_form: {default: string, label: string, type: string, blurb: string}, user_home: {default: string, label: string, type: string}, base_url: {default: string, onChange(*=): void, label: string, type: string, blurb: string}, site_logo_id: {default: number, attributes: {select_file_where: {min_role_read: number, mime_super: string}}, label: string, type: string, blurb: string}, available_plugins_fetched_at: {label: string, type: string}, user_settings_form: {default: string, label: string, type: string, blurb: string}, public_home: {default: string, label: string, type: string}, new_user_form: {default: string, label: string, type: string, blurb: string}, smtp_secure: {default: boolean, label: string, type: string, sublabel: string}, globalSearch: {label: string, type: string}, letsencrypt: {default: boolean, root_only: boolean, label: string, type: string, blurb: string}, verification_view: {default: string, label: string, type: string, blurb: string}, available_packs_fetched_at: {label: string, type: string}, email_from: {default: string, label: string, type: string, blurb: string}, custom_http_headers: {default: string, input_type: string, attributes: {mode: string}, label: string, blurb: string, hide_value: boolean}}}
15
- */
16
13
 
17
14
  const allTimezones = moment.tz.names();
18
15
  const defaultTimezone = moment.tz.guess();
19
16
 
17
+ /**
18
+ * Config variables types
19
+ * @namespace
20
+ * @category saltcorn-data
21
+ */
20
22
  const configTypes = {
23
+ /** @type {object} */
21
24
  site_name: {
22
25
  type: "String",
23
26
  label: "Site name",
24
27
  default: "Saltcorn",
25
28
  blurb: "A short string which is the name of your site",
26
29
  },
30
+ /** @type {object} */
27
31
  timezone: {
28
32
  type: "String",
29
33
  label: "Home Timezone",
@@ -32,6 +36,7 @@ const configTypes = {
32
36
  options: allTimezones,
33
37
  },
34
38
  },
39
+ /** @type {object} */
35
40
  site_logo_id: {
36
41
  type: "File",
37
42
  label: "Site logo",
@@ -41,6 +46,7 @@ const configTypes = {
41
46
  },
42
47
  blurb: "Select a publicly accessible image file for the menu logo",
43
48
  },
49
+ /** @type {object} */
44
50
  favicon_id: {
45
51
  type: "File",
46
52
  label: "Favicon",
@@ -50,6 +56,7 @@ const configTypes = {
50
56
  },
51
57
  blurb: "Select a publicly accessible image file for the browser tab icon",
52
58
  },
59
+ /** @type {object} */
53
60
  base_url: {
54
61
  type: "String",
55
62
  label: "Base URL",
@@ -65,35 +72,50 @@ const configTypes = {
65
72
  blurb:
66
73
  "The URL at which your site is available. For instance, https://example.com/",
67
74
  },
75
+ /** @type {object} */
68
76
  menu_items: { type: "hidden", label: "Menu items" },
77
+ /** @type {object} */
69
78
  globalSearch: { type: "hidden", label: "Global search" },
79
+ /** @type {object} */
70
80
  available_packs: { type: "hidden", label: "Available packs" },
81
+ /** @type {object} */
71
82
  available_packs_fetched_at: {
72
83
  type: "Date",
73
84
  label: "Available packs fetched",
74
85
  },
86
+ /** @type {object} */
75
87
  available_plugins: { type: "hidden", label: "Available plugins" },
88
+ /** @type {object} */
76
89
  available_plugins_fetched_at: {
77
90
  type: "Date",
78
91
  label: "Available plugins fetched",
79
92
  },
93
+ /** @type {object} */
80
94
  home_page_by_role: { type: "hidden", label: "Home Page by Role" },
95
+ /** @type {object} */
81
96
  exttables_min_role_read: {
82
97
  type: "hidden",
83
98
  label: "Home Page by Role",
84
99
  default: {},
85
100
  },
101
+ /** @type {object} */
86
102
  public_home: { type: "String", label: "Public home page", default: "" },
103
+ /** @type {object} */
87
104
  user_home: { type: "String", label: "User home page", default: "" },
105
+ /** @type {object} */
88
106
  staff_home: { type: "String", label: "Staff home page", default: "" },
107
+ /** @type {object} */
89
108
  admin_home: { type: "String", label: "Admin home page", default: "" },
109
+ /** @type {object} */
90
110
  layout_by_role: { type: "hidden", label: "Layout by role", default: {} },
111
+ /** @type {object} */
91
112
  allow_signup: {
92
113
  type: "Bool",
93
114
  label: "Allow signups",
94
115
  default: true,
95
116
  blurb: "Allow users to sign up for a new user account",
96
117
  },
118
+ /** @type {object} */
97
119
  allow_forgot: {
98
120
  type: "Bool",
99
121
  label: "Allow password reset",
@@ -101,12 +123,14 @@ const configTypes = {
101
123
  blurb:
102
124
  "Allow users to request a password reset email. Email must be configured.",
103
125
  },
126
+ /** @type {object} */
104
127
  login_menu: {
105
128
  type: "Bool",
106
129
  label: "Login in menu",
107
130
  default: true,
108
131
  blurb: "Show the login link in the menu",
109
132
  },
133
+ /** @type {object} */
110
134
  cookie_sessions: {
111
135
  type: "Bool",
112
136
  label: "Cookie sessions",
@@ -115,30 +139,35 @@ const configTypes = {
115
139
  restart_required: true,
116
140
  blurb: "Store sessions entirely in client cookies for higher performance",
117
141
  },
142
+ /** @type {object} */
118
143
  new_user_form: {
119
144
  type: "View users",
120
145
  label: "New user form",
121
146
  default: "",
122
147
  blurb: "A view to show to new users",
123
148
  },
149
+ /** @type {object} */
124
150
  user_settings_form: {
125
151
  type: "View users",
126
152
  label: "User settings form",
127
153
  default: "",
128
154
  blurb: "A view for users to change their custom user fields",
129
155
  },
156
+ /** @type {object} */
130
157
  login_form: {
131
158
  type: "View users",
132
159
  label: "Login view",
133
160
  blurb: "A view with the login form",
134
161
  default: "",
135
162
  },
163
+ /** @type {object} */
136
164
  signup_form: {
137
165
  type: "View users",
138
166
  label: "Signup view",
139
167
  blurb: "A view with the signup form",
140
168
  default: "",
141
169
  },
170
+ /** @type {object} */
142
171
  verification_view: {
143
172
  type: "View users",
144
173
  label: "Verification view",
@@ -146,12 +175,14 @@ const configTypes = {
146
175
  "A view with the view to be emailed to users for email address verification",
147
176
  default: "",
148
177
  },
178
+ /** @type {object} */
149
179
  elevate_verified: {
150
180
  type: "Role",
151
181
  label: "Elevate verified to role",
152
182
  blurb:
153
183
  "Elevate users to a higher role when their email addresses have been verified",
154
184
  },
185
+ /** @type {object} */
155
186
  min_role_upload: {
156
187
  type: "Role",
157
188
  label: "Role to upload files",
@@ -160,13 +191,16 @@ const configTypes = {
160
191
  blurb:
161
192
  "User should have this role or higher to upload files with API (uploads through forms are not affected)",
162
193
  },
194
+ /** @type {object} */
163
195
  email_mask: {
164
196
  type: "String",
165
197
  label: "Email mask",
166
198
  default: "",
167
199
  blurb: "Emails used for signup must end with this string",
168
200
  },
201
+ /** @type {object} */
169
202
  installed_packs: { type: "String[]", label: "Installed packs", default: [] },
203
+ /** @type {object} */
170
204
  log_sql: {
171
205
  type: "Bool",
172
206
  label: "Log SQL to stdout",
@@ -176,6 +210,7 @@ const configTypes = {
176
210
  },
177
211
  blurb: "Print all SQL statements to the standard output",
178
212
  },
213
+ /** @type {object} */
179
214
  multitenancy_enabled: {
180
215
  type: "Bool",
181
216
  root_only: true,
@@ -186,12 +221,14 @@ const configTypes = {
186
221
  set_multitenancy_cfg(val);
187
222
  },
188
223
  },
224
+ /** @type {object} */
189
225
  role_to_create_tenant: {
190
226
  type: "Role",
191
227
  label: "Role to create tenants",
192
228
  blurb: "Minimum user role required to create a new tenant",
193
229
  default: "10",
194
230
  },
231
+ /** @type {object} */
195
232
  create_tenant_warning: {
196
233
  type: "Bool",
197
234
  label: "Create tenant warning",
@@ -199,6 +236,13 @@ const configTypes = {
199
236
  blurb:
200
237
  "Show a warning to users creating a tenant disclaiming warrenty of availability or security",
201
238
  },
239
+ /** @type {object} */
240
+ tenant_template: {
241
+ type: "Tenant",
242
+ label: "New tenant template",
243
+ blurb: "Copy site structure for new tenants from this tenant",
244
+ },
245
+ /** @type {object} */
202
246
  development_mode: {
203
247
  type: "Bool",
204
248
  label: "Development mode",
@@ -206,6 +250,7 @@ const configTypes = {
206
250
  blurb:
207
251
  "Disable JS/CSS asset caching, show full error to user on crash, enable editing field type",
208
252
  },
253
+ /** @type {object} */
209
254
  smtp_host: {
210
255
  type: "String",
211
256
  label: "SMTP host",
@@ -213,12 +258,14 @@ const configTypes = {
213
258
  blurb:
214
259
  "The host address of your SMTP server. For instance, smtp.postmarkapp.com",
215
260
  },
261
+ /** @type {object} */
216
262
  smtp_username: {
217
263
  type: "String",
218
264
  label: "SMTP username",
219
265
  default: "",
220
266
  blurb: "The user name to access SMTP server for sending emails.",
221
267
  },
268
+ /** @type {object} */
222
269
  smtp_password: {
223
270
  type: "String",
224
271
  label: "SMTP password",
@@ -229,12 +276,14 @@ const configTypes = {
229
276
  "If your SMTP provider allows to create app password for using from application " +
230
277
  "We recommends to use app password instead of user password.",
231
278
  },
279
+ /** @type {object} */
232
280
  smtp_port: {
233
281
  type: "Integer",
234
282
  label: "SMTP port",
235
283
  default: "25",
236
284
  blurb: "The port of your SMTP server",
237
285
  },
286
+ /** @type {object} */
238
287
  smtp_secure: {
239
288
  type: "Bool",
240
289
  label: "Force TLS",
@@ -242,6 +291,7 @@ const configTypes = {
242
291
  sublabel:
243
292
  "Always use TLS when connecting to server? If unchecked, TLS is used if server supports the STARTTLS extension. In most cases check this box if you are connecting to port 465. For port 587 or 25 keep it unchecked",
244
293
  },
294
+ /** @type {object} */
245
295
  email_from: {
246
296
  type: "String",
247
297
  label: "Email from address",
@@ -249,6 +299,7 @@ const configTypes = {
249
299
  blurb:
250
300
  "The email address from which emails are sent. For instance, hello@saltcorn.com",
251
301
  },
302
+ /** @type {object} */
252
303
  custom_ssl_certificate: {
253
304
  type: "String",
254
305
  fieldview: "textarea",
@@ -256,6 +307,7 @@ const configTypes = {
256
307
  default: "",
257
308
  hide_value: true,
258
309
  },
310
+ /** @type {object} */
259
311
  custom_ssl_private_key: {
260
312
  type: "String",
261
313
  fieldview: "textarea",
@@ -263,6 +315,7 @@ const configTypes = {
263
315
  hide_value: true,
264
316
  default: "",
265
317
  },
318
+ /** @type {object} */
266
319
  letsencrypt: {
267
320
  label: "LetsEncrypt enabled",
268
321
  default: false,
@@ -270,6 +323,7 @@ const configTypes = {
270
323
  root_only: true,
271
324
  blurb: "Enable SSL certificate from Let's Encrypt for HTTPS traffic",
272
325
  },
326
+ /** @type {object} */
273
327
  timeout: {
274
328
  type: "Integer",
275
329
  label: "HTTP timeout (s)",
@@ -278,21 +332,25 @@ const configTypes = {
278
332
  restart_required: true,
279
333
  sublabel: "Increase if you expect large uploads",
280
334
  },
335
+ /** @type {object} */
281
336
  latest_npm_version: {
282
337
  type: "hidden",
283
338
  label: "Latest npm version cache",
284
339
  default: {},
285
340
  },
341
+ /** @type {object} */
286
342
  event_log_settings: {
287
343
  type: "hidden",
288
344
  label: "Event log settings",
289
345
  default: {},
290
346
  },
347
+ /** @type {object} */
291
348
  custom_events: {
292
349
  type: "hidden",
293
350
  label: "Custom events",
294
351
  default: [],
295
352
  },
353
+ /** @type {object} */
296
354
  page_custom_css: {
297
355
  input_type: "code",
298
356
  label: "Custom CSS",
@@ -300,6 +358,7 @@ const configTypes = {
300
358
  hide_value: true,
301
359
  attributes: { mode: "text/css" },
302
360
  },
361
+ /** @type {object} */
303
362
  page_custom_html: {
304
363
  input_type: "code",
305
364
  label: "Custom HTML",
@@ -307,6 +366,7 @@ const configTypes = {
307
366
  hide_value: true,
308
367
  attributes: { mode: "text/html" },
309
368
  },
369
+ /** @type {object} */
310
370
  custom_http_headers: {
311
371
  input_type: "code",
312
372
  label: "Custom HTTP headers",
@@ -315,26 +375,31 @@ const configTypes = {
315
375
  hide_value: true,
316
376
  attributes: { mode: "message/http" },
317
377
  },
378
+ /** @type {object} */
318
379
  next_hourly_event: {
319
380
  type: "Date",
320
381
  label: "Next hourly event",
321
382
  default: null,
322
383
  },
384
+ /** @type {object} */
323
385
  next_daily_event: {
324
386
  type: "Date",
325
387
  label: "Next daily event",
326
388
  default: null,
327
389
  },
390
+ /** @type {object} */
328
391
  next_weekly_event: {
329
392
  type: "Date",
330
393
  label: "Next weekly event",
331
394
  default: null,
332
395
  },
396
+ /** @type {object} */
333
397
  localizer_languages: {
334
398
  type: "hidden",
335
399
  label: "Localizer languages",
336
400
  default: {},
337
401
  },
402
+ /** @type {object} */
338
403
  localizer_strings: {
339
404
  type: "hidden",
340
405
  label: "Localizer strings",
@@ -370,7 +435,10 @@ const available_languages = {
370
435
  };
371
436
  /**
372
437
  * Get Config variable value by key (contract)
373
- * @type {*|(function(...[*]=): *)}
438
+ * @function
439
+ * @param {string} key
440
+ * @param {object|undefined} def
441
+ * @returns {Promise<object>}
374
442
  */
375
443
  const getConfig = contract(
376
444
  is.fun([is.str, is.maybe(is.any)], is.promise(is.any)),
@@ -382,18 +450,21 @@ const getConfig = contract(
382
450
  else return configTypes[key] ? configTypes[key].default : undefined;
383
451
  }
384
452
  );
453
+
385
454
  /**
386
455
  * Returns true if key is defined in fixed_configration for tenant
387
- * @param key
388
- * @returns {boolean|*}
456
+ * @param {string} key
457
+ * @returns {boolean}
389
458
  */
390
459
  const isFixedConfig = (key) =>
391
460
  typeof db.connectObj.fixed_configuration[key] !== "undefined" ||
392
461
  (db.connectObj.inherit_configuration.includes(key) &&
393
462
  db.getTenantSchema() !== db.connectObj.default_schema);
463
+
394
464
  /**
395
- * Get all config variables list
396
- * @type {*|(function(...[*]=): *)}
465
+ * Get all config variables list
466
+ * @function
467
+ * @returns {Promise<object>}
397
468
  */
398
469
  const getAllConfig = contract(
399
470
  is.fun([], is.promise(is.objVals(is.any))),
@@ -419,10 +490,12 @@ const getAllConfig = contract(
419
490
  return cfg;
420
491
  }
421
492
  );
493
+
422
494
  /**
423
495
  * Get all config variables list
424
496
  * If variable is not defined that default value is used
425
- * @type {*|(function(...[*]=): *)}
497
+ * @function
498
+ * @returns {Promise<object>}
426
499
  */
427
500
  const getAllConfigOrDefaults = contract(
428
501
  is.fun([], is.promise(is.objVals(is.any))),
@@ -441,7 +514,10 @@ const getAllConfigOrDefaults = contract(
441
514
 
442
515
  /**
443
516
  * Set config variable value by key
444
- * @type {*|(function(...[*]=): *)}
517
+ * @function
518
+ * @param {string} key
519
+ * @param {object} value
520
+ * @returns {Promise<void>}
445
521
  */
446
522
  // TODO move db specific to pg/sqlite
447
523
  const setConfig = contract(
@@ -465,7 +541,9 @@ const setConfig = contract(
465
541
  );
466
542
  /**
467
543
  * Delete config variable
468
- * @type {*|(function(...[*]=): *)}
544
+ * @function
545
+ * @param {string} key
546
+ * @returns {Promise<void>}
469
547
  */
470
548
  const deleteConfig = contract(
471
549
  is.fun(is.str, is.promise(is.undefined)),
@@ -473,9 +551,12 @@ const deleteConfig = contract(
473
551
  await db.deleteWhere("_sc_config", { key });
474
552
  }
475
553
  );
554
+
476
555
  /**
477
556
  * Remove from menu
478
- * @type {*|(function(...[*]=): *)}
557
+ * @function
558
+ * @param {object} item
559
+ * @returns {Promise<void>}
479
560
  */
480
561
  const remove_from_menu = contract(
481
562
  is.fun(
@@ -501,10 +582,11 @@ const remove_from_menu = contract(
501
582
  await getState().setConfig("menu_items", new_menu);
502
583
  }
503
584
  );
585
+
504
586
  /**
505
587
  * Get latest npm version
506
- * @param pkg
507
- * @returns {Promise<*|string|*>}
588
+ * @param {string} pkg
589
+ * @returns {Promise<string>}
508
590
  */
509
591
  const get_latest_npm_version = async (pkg) => {
510
592
  const { getState } = require("../db/state");
@@ -527,15 +609,17 @@ const get_latest_npm_version = async (pkg) => {
527
609
  else return "";
528
610
  }
529
611
  };
612
+
530
613
  /**
531
614
  * Ensure that string is finished with /
532
- * @param s
533
- * @returns {*|string}
615
+ * @param {string} s
616
+ * @returns {string}
534
617
  */
535
618
  const ensure_final_slash = (s) => (s.endsWith("/") ? s : s + "/");
619
+
536
620
  /**
537
621
  * Get base url
538
- * @param req
622
+ * @param {object} req
539
623
  * @returns {string}
540
624
  */
541
625
  const get_base_url = (req) => {
@@ -552,9 +636,12 @@ const get_base_url = (req) => {
552
636
  }
553
637
  return `${req.protocol}://${req.hostname}${ports}/`;
554
638
  };
639
+
555
640
  /**
556
641
  * Check email mask
557
- * @type {*|(function(...[*]=): *)}
642
+ * @function
643
+ * @param {string} email
644
+ * @returns {boolean}
558
645
  */
559
646
  const check_email_mask = contract(is.fun(is.str, is.bool), (email) => {
560
647
  const { getState } = require("../db/state");
@@ -564,15 +651,19 @@ const check_email_mask = contract(is.fun(is.str, is.bool), (email) => {
564
651
  return email.endsWith(cfg);
565
652
  } else return true;
566
653
  });
654
+
567
655
  /**
568
656
  * Set multitenancy cfg flag
569
- * @type {*|(function(...[*]=): *)}
657
+ * @function
658
+ * @param {boolean} val
659
+ * @returns {void}
570
660
  */
571
661
  const set_multitenancy_cfg = contract(is.fun(is.bool, is.undefined), (val) => {
572
662
  const cfg = getConfigFile();
573
663
  cfg.multi_tenant = val;
574
664
  fs.writeFileSync(configFilePath, JSON.stringify(cfg, null, 2));
575
665
  });
666
+
576
667
  module.exports = {
577
668
  getConfig,
578
669
  getAllConfig,
package/models/crash.js CHANGED
@@ -1,8 +1,22 @@
1
+ /**
2
+ * Crash Database Access Layer
3
+ * @category saltcorn-data
4
+ * @module models/crash
5
+ * @subcategory models
6
+ */
1
7
  const db = require("../db");
2
8
  const moment = require("moment");
3
9
  const { contract, is } = require("contractis");
4
10
 
11
+ /**
12
+ * Crash Class
13
+ * @category saltcorn-data
14
+ */
5
15
  class Crash {
16
+ /**
17
+ * Crash constructor
18
+ * @param {object} o
19
+ */
6
20
  constructor(o) {
7
21
  this.id = o.id;
8
22
  this.stack = o.stack;
@@ -18,25 +32,55 @@ class Crash {
18
32
  typeof o.headers === "string" ? JSON.parse(o.headers) : o.headers;
19
33
  contract.class(this);
20
34
  }
35
+
36
+ /**
37
+ * @param {object} where
38
+ * @param {object} selopts
39
+ * @returns {Promise<Crash[]>}
40
+ */
21
41
  static async find(where, selopts) {
22
42
  const us = await db.select("_sc_errors", where, selopts);
23
43
  return us.map((u) => new Crash(u));
24
44
  }
45
+
46
+ /**
47
+ * @param {object} where
48
+ * @returns {Promise<Crash>}
49
+ */
25
50
  static async findOne(where) {
26
51
  const u = await db.selectOne("_sc_errors", where);
27
52
  return new Crash(u);
28
53
  }
54
+
55
+ /**
56
+ * @type {string}
57
+ */
29
58
  get reltime() {
30
59
  return moment(this.occur_at).fromNow();
31
60
  }
61
+
62
+ /**
63
+ * @param {object} where
64
+ * @returns {Promise<number>}
65
+ */
32
66
  static async count(where) {
33
67
  return await db.count("_sc_errors", where || {});
34
68
  }
69
+
70
+ /**
71
+ * @type {string}
72
+ */
35
73
  get msg_short() {
36
74
  return this.message.length > 90
37
75
  ? this.message.substring(0, 90)
38
76
  : this.message;
39
77
  }
78
+
79
+ /**
80
+ * @param {object} err
81
+ * @param {object} [req = {}]
82
+ * @returns {Promise<void>}
83
+ */
40
84
  static async create(err, req = {}) {
41
85
  const schema = db.getTenantSchema();
42
86
  const payload = {
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * DB Tables discovery to Saltcorn tables.
3
- * @type {{changeConnection?: ((function(*): Promise<void>)|(function(*=): Promise<void>)), select?: ((function(*=, *=, *=): Promise<*>)|(function(*=, *=, *=): Promise<*>)), runWithTenant: ((function(*=, *=): (*))|(function(*, *): *)), set_sql_logging?: (function(*=): void), insert?: ((function(*=, *=, *=): Promise<undefined|*>)|(function(*=, *=, *=): Promise<undefined|*>)), update?: ((function(*=, *=, *=): Promise<void>)|(function(*=, *=, *=, *=): Promise<void>)), sql_log?: (function(*=, *=): void), deleteWhere?: ((function(*=, *=): Promise<void>)|(function(*=, *=): Promise<*>)), isSQLite: *, selectMaybeOne?: ((function(*=, *=): Promise<null|*>)|(function(*=, *=): Promise<null|*>)), close?: (function(): Promise<void>), drop_unique_constraint?: (function(*=, *): Promise<void>), enable_multi_tenant: (function()), getVersion?: ((function(): Promise<*>)|(function(*=): Promise<*>)), add_unique_constraint?: (function(*=, *): Promise<void>), getTenantSchema: ((function(): *)|(function(): *)), is_it_multi_tenant: ((function(): boolean)|(function(): boolean)), sqliteDatabase?: *, drop_reset_schema?: ((function(): Promise<void>)|(function(*): Promise<void>)), query?: ((function(*=, *=): Promise<unknown>)|(function(*=, *=): *)), count?: ((function(*=, *=): Promise<number>)|(function(*=, *=): Promise<number>)), pool?: *, connectObj: {sc_version: *, connectionString: string | undefined, git_commit: *, version_tag: *}|{sc_version: *, git_commit: *, version_tag: *}|boolean, sqlsanitize: *|(function(...[*]=): *), getClient?: (function(): Promise<*>), reset_sequence?: (function(*=): Promise<void>), copyFrom?: (function(*=, *=, *, *): Promise<void>), mkWhere: function(*=): {values: *, where: string|string}, selectOne?: ((function(*=, *=): Promise<*|undefined>)|(function(*=, *=): Promise<*|undefined>)), getTenantSchemaPrefix: function(): string|string}|{sqlsanitize?: *|(function(...[*]=): *), connectObj?: {sc_version: *, connectionString: string | undefined, git_commit: *, version_tag: *}|{sc_version: *, git_commit: *, version_tag: *}|boolean, isSQLite?: *, mkWhere?: function(*=): {values: *, where: string|string}, getTenantSchemaPrefix?: function(): string|string}}
3
+ * @category saltcorn-data
4
+ * @module models/discovery
5
+ * @subcategory models
4
6
  */
5
7
  const db = require("../db");
6
8
  const { getState } = require("../db/state");
@@ -12,8 +14,8 @@ const Table = require("./table");
12
14
  * List of discoverable tables.
13
15
  * Returns all tables that can be imported to Saltcorn from current tenant database schema.
14
16
  * The tables with name started with "_sc_" and tables imported to Saltcorn are ignored.
15
- * @param schema0 - current tenant db schema
16
- * @returns {Promise<*>} all tables that can be imported to Saltcorn from current tenant database schema
17
+ * @param {string} schema0 - current tenant db schema
18
+ * @returns {Promise<object[]>} all tables that can be imported to Saltcorn from current tenant database schema
17
19
  */
18
20
  const discoverable_tables = async (schema0) => {
19
21
  const schema = schema0 || db.getTenantSchema();
@@ -33,8 +35,8 @@ const discoverable_tables = async (schema0) => {
33
35
  };
34
36
  /**
35
37
  * List all views in current tenant db schema
36
- * @param schema0 - current tenant db schema
37
- * @returns {Promise<*>} Return list of views
38
+ * @param {string} schema0 - current tenant db schema
39
+ * @returns {Promise<object[]>} Return list of views
38
40
  */
39
41
  const get_existing_views = async (schema0) => {
40
42
  const schema = schema0 || db.getTenantSchema();
@@ -48,8 +50,8 @@ const get_existing_views = async (schema0) => {
48
50
  };
49
51
  /**
50
52
  * Mapping SQL Type to Saltcorn type
51
- * @param sql_name - SQL type name
52
- * @returns {string|*} return Saltcorn type
53
+ * @param {string} sql_name - SQL type name
54
+ * @returns {string|void} return Saltcorn type
53
55
  */
54
56
  const findType = (sql_name) => {
55
57
  const fixed = {
@@ -78,9 +80,9 @@ const findType = (sql_name) => {
78
80
  };
79
81
  /**
80
82
  * Discover tables definitions
81
- * @param tableNames - list of table names
82
- * @param schema0 - db schema
83
- * @returns {Promise<{tables: *[]}>}
83
+ * @param {string[]} tableNames - list of table names
84
+ * @param {string} schema0 - db schema
85
+ * @returns {Promise<object>}
84
86
  */
85
87
  const discover_tables = async (tableNames, schema0) => {
86
88
  const schema = schema0 || db.getTenantSchema();
@@ -167,7 +169,7 @@ const discover_tables = async (tableNames, schema0) => {
167
169
  };
168
170
  /**
169
171
  * Add discovered tables to Saltcorn
170
- * @param pack - table definition
172
+ * @param {object} pack - table definition
171
173
  * @returns {Promise<void>}
172
174
  */
173
175
  const implement_discovery = async (pack) => {