@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.
- package/base-plugin/actions.js +172 -1
- package/base-plugin/fieldviews.js +63 -0
- package/base-plugin/fileviews.js +41 -0
- package/base-plugin/index.js +35 -0
- package/base-plugin/types.js +345 -9
- package/base-plugin/viewtemplates/edit.js +107 -0
- package/base-plugin/viewtemplates/feed.js +46 -0
- package/base-plugin/viewtemplates/filter.js +43 -0
- package/base-plugin/viewtemplates/list.js +73 -1
- package/base-plugin/viewtemplates/listshowlist.js +54 -3
- package/base-plugin/viewtemplates/room.js +100 -0
- package/base-plugin/viewtemplates/show.js +86 -0
- package/base-plugin/viewtemplates/viewable_fields.js +124 -0
- package/contracts.js +58 -0
- package/db/connect.js +13 -5
- package/db/db.test.js +0 -154
- package/db/fixtures.js +13 -1
- package/db/index.js +42 -3
- package/db/reset_schema.js +11 -0
- package/db/state.js +105 -36
- package/index.js +13 -0
- package/migrate.js +4 -1
- package/models/backup.js +78 -0
- package/models/config.js +113 -22
- package/models/crash.js +44 -0
- package/models/discovery.js +13 -11
- package/models/email.js +17 -0
- package/models/eventlog.js +51 -0
- package/models/expression.js +49 -1
- package/models/field.js +88 -9
- package/models/fieldrepeat.js +33 -0
- package/models/file.js +23 -4
- package/models/form.js +34 -0
- package/models/index.js +42 -0
- package/models/layout.js +33 -0
- package/models/library.js +44 -0
- package/models/pack.js +88 -0
- package/models/page.js +13 -3
- package/models/plugin.js +9 -2
- package/models/random.js +36 -0
- package/models/role.js +36 -0
- package/models/scheduler.js +28 -0
- package/models/table.js +34 -15
- package/models/table_constraints.js +44 -0
- package/models/tenant.js +46 -9
- package/models/trigger.js +24 -11
- package/models/user.js +33 -8
- package/models/view.js +89 -8
- package/models/workflow.js +31 -0
- package/package.json +7 -5
- package/plugin-helper.js +102 -44
- package/plugin-testing.js +4 -0
- package/tests/exact_views.test.js +5 -5
- package/utils.js +4 -0
- package/db/internal.js +0 -229
- package/db/multi-tenant.js +0 -24
- package/db/pg.js +0 -374
- package/db/single-tenant.js +0 -8
- package/db/sqlite.js +0 -280
- 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
|
-
* @
|
|
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
|
-
*
|
|
396
|
-
* @
|
|
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
|
-
* @
|
|
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
|
-
* @
|
|
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
|
-
* @
|
|
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
|
-
* @
|
|
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
|
|
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 {
|
|
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
|
-
* @
|
|
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
|
-
* @
|
|
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 = {
|
package/models/discovery.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* DB Tables discovery to Saltcorn tables.
|
|
3
|
-
* @
|
|
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
|
|
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
|
|
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
|
|
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<
|
|
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) => {
|