@saltcorn/server 0.6.4-beta.1 → 0.6.4-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app.js +3 -1
- package/auth/routes.js +1 -1
- package/locales/en.json +5 -1
- package/package.json +10 -7
- package/public/saltcorn.js +13 -8
- package/restart_watcher.js +1 -1
- package/routes/admin.js +2 -2
- package/routes/fields.js +31 -2
- package/routes/homepage.js +1 -1
- package/routes/packs.js +1 -1
- package/routes/pageedit.js +1 -1
- package/routes/plugins.js +1 -1
- package/routes/scapi.js +1 -1
- package/routes/tenant.js +19 -9
- package/routes/viewedit.js +1 -1
- package/serve.js +38 -27
package/app.js
CHANGED
|
@@ -28,6 +28,7 @@ const {
|
|
|
28
28
|
getSessionStore,
|
|
29
29
|
setTenant,
|
|
30
30
|
} = require("./routes/utils.js");
|
|
31
|
+
const { getAllTenants } = require("@saltcorn/admin-models/models/tenant");
|
|
31
32
|
const path = require("path");
|
|
32
33
|
const fileUpload = require("express-fileupload");
|
|
33
34
|
const helmet = require("helmet");
|
|
@@ -84,7 +85,8 @@ const getApp = async (opts = {}) => {
|
|
|
84
85
|
app.use(i18n.init);
|
|
85
86
|
// init multitenant mode
|
|
86
87
|
if (db.is_it_multi_tenant()) {
|
|
87
|
-
await
|
|
88
|
+
const tenants = await getAllTenants();
|
|
89
|
+
await init_multi_tenant(loadAllPlugins, opts.disableMigrate, tenants);
|
|
88
90
|
}
|
|
89
91
|
//
|
|
90
92
|
// todo ability to configure session_secret Age
|
package/auth/routes.js
CHANGED
|
@@ -53,7 +53,7 @@ const Table = require("@saltcorn/data/models/table");
|
|
|
53
53
|
const { InvalidConfiguration } = require("@saltcorn/data/utils");
|
|
54
54
|
const Trigger = require("@saltcorn/data/models/trigger");
|
|
55
55
|
const { restore_backup } = require("../markup/admin.js");
|
|
56
|
-
const { restore } = require("@saltcorn/
|
|
56
|
+
const { restore } = require("@saltcorn/admin-models/models/backup");
|
|
57
57
|
const load_plugins = require("../load_plugins");
|
|
58
58
|
const fs = require("fs");
|
|
59
59
|
const base32 = require("thirty-two");
|
package/locales/en.json
CHANGED
|
@@ -861,5 +861,9 @@
|
|
|
861
861
|
"Auto save": "Auto save",
|
|
862
862
|
"Save any changes immediately": "Save any changes immediately",
|
|
863
863
|
"Transpose": "Transpose",
|
|
864
|
-
"Display one column per line": "Display one column per line"
|
|
864
|
+
"Display one column per line": "Display one column per line",
|
|
865
|
+
"Vertical column width": "Vertical column width",
|
|
866
|
+
"Vertical width units": "Vertical width units",
|
|
867
|
+
"Save before going back": "Save before going back",
|
|
868
|
+
"Reload after going back": "Reload after going back"
|
|
865
869
|
}
|
package/package.json
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saltcorn/server",
|
|
3
|
-
"version": "0.6.4-beta.
|
|
3
|
+
"version": "0.6.4-beta.2",
|
|
4
4
|
"description": "Server app for Saltcorn, open-source no-code platform",
|
|
5
5
|
"homepage": "https://saltcorn.com",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@saltcorn/base-plugin": "0.6.4-beta.
|
|
10
|
-
"@saltcorn/builder": "0.6.4-beta.
|
|
11
|
-
"@saltcorn/data": "0.6.4-beta.
|
|
9
|
+
"@saltcorn/base-plugin": "0.6.4-beta.2",
|
|
10
|
+
"@saltcorn/builder": "0.6.4-beta.2",
|
|
11
|
+
"@saltcorn/data": "0.6.4-beta.2",
|
|
12
|
+
"@saltcorn/admin-models": "0.6.4-beta.2",
|
|
12
13
|
"greenlock-express": "^4.0.3",
|
|
13
|
-
"@saltcorn/markup": "0.6.4-beta.
|
|
14
|
-
"@saltcorn/sbadmin2": "0.6.4-beta.
|
|
14
|
+
"@saltcorn/markup": "0.6.4-beta.2",
|
|
15
|
+
"@saltcorn/sbadmin2": "0.6.4-beta.2",
|
|
15
16
|
"@socket.io/cluster-adapter": "^0.1.0",
|
|
16
17
|
"@socket.io/sticky": "^1.0.1",
|
|
17
18
|
"connect-flash": "^0.1.1",
|
|
@@ -81,7 +82,9 @@
|
|
|
81
82
|
"@saltcorn/data/(.*)": "@saltcorn/data/dist/$1",
|
|
82
83
|
"@saltcorn/types/(.*)": "@saltcorn/types/dist/$1",
|
|
83
84
|
"@saltcorn/markup$": "@saltcorn/markup/dist",
|
|
84
|
-
"@saltcorn/markup/(.*)": "@saltcorn/markup/dist/$1"
|
|
85
|
+
"@saltcorn/markup/(.*)": "@saltcorn/markup/dist/$1",
|
|
86
|
+
"@saltcorn/server/(.*)": "@saltcorn/server/dist/$1",
|
|
87
|
+
"@saltcorn/admin-models/(.*)": "@saltcorn/admin-models/dist/$1"
|
|
85
88
|
}
|
|
86
89
|
},
|
|
87
90
|
"publishConfig": {
|
package/public/saltcorn.js
CHANGED
|
@@ -228,13 +228,15 @@ function initialize_page() {
|
|
|
228
228
|
});
|
|
229
229
|
if (codes.length > 0)
|
|
230
230
|
enable_codemirror(() => {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
231
|
+
setTimeout(() => {
|
|
232
|
+
codes.forEach((el) => {
|
|
233
|
+
//console.log($(el).attr("mode"), el);
|
|
234
|
+
CodeMirror.fromTextArea(el, {
|
|
235
|
+
lineNumbers: true,
|
|
236
|
+
mode: $(el).attr("mode"),
|
|
237
|
+
});
|
|
236
238
|
});
|
|
237
|
-
});
|
|
239
|
+
}, 100);
|
|
238
240
|
});
|
|
239
241
|
const locale =
|
|
240
242
|
navigator.userLanguage ||
|
|
@@ -482,7 +484,7 @@ function press_store_button(clicked) {
|
|
|
482
484
|
|
|
483
485
|
function ajax_modal(url, opts = {}) {
|
|
484
486
|
if ($("#scmodal").length === 0) {
|
|
485
|
-
$("body").append(`<div id="scmodal", class="modal"
|
|
487
|
+
$("body").append(`<div id="scmodal", class="modal">
|
|
486
488
|
<div class="modal-dialog">
|
|
487
489
|
<div class="modal-content">
|
|
488
490
|
<div class="modal-header">
|
|
@@ -515,7 +517,7 @@ function ajax_modal(url, opts = {}) {
|
|
|
515
517
|
});
|
|
516
518
|
}
|
|
517
519
|
|
|
518
|
-
function saveAndContinue(e) {
|
|
520
|
+
function saveAndContinue(e, k) {
|
|
519
521
|
var form = $(e).closest("form");
|
|
520
522
|
var url = form.attr("action");
|
|
521
523
|
var form_data = form.serialize();
|
|
@@ -536,6 +538,9 @@ function saveAndContinue(e) {
|
|
|
536
538
|
$("#page-inner-content").html(request.responseText);
|
|
537
539
|
initialize_page();
|
|
538
540
|
},
|
|
541
|
+
complete: function () {
|
|
542
|
+
if (k) k();
|
|
543
|
+
},
|
|
539
544
|
});
|
|
540
545
|
|
|
541
546
|
return false;
|
package/restart_watcher.js
CHANGED
|
@@ -8,7 +8,7 @@ const { spawnSync } = require("child_process");
|
|
|
8
8
|
const watch = require("node-watch");
|
|
9
9
|
const Plugin = require("@saltcorn/data/models/plugin");
|
|
10
10
|
const db = require("@saltcorn/data/db");
|
|
11
|
-
const { eachTenant } = require("@saltcorn/
|
|
11
|
+
const { eachTenant } = require("@saltcorn/admin-models/models/tenant");
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* packages that should trigger a server re-start
|
package/routes/admin.js
CHANGED
|
@@ -17,7 +17,7 @@ const File = require("@saltcorn/data/models/file");
|
|
|
17
17
|
const { spawn } = require("child_process");
|
|
18
18
|
const User = require("@saltcorn/data/models/user");
|
|
19
19
|
const path = require("path");
|
|
20
|
-
const { getAllTenants } = require("@saltcorn/
|
|
20
|
+
const { getAllTenants } = require("@saltcorn/admin-models/models/tenant");
|
|
21
21
|
const { post_btn, renderForm } = require("@saltcorn/markup");
|
|
22
22
|
const {
|
|
23
23
|
div,
|
|
@@ -46,7 +46,7 @@ const {
|
|
|
46
46
|
get_process_init_time,
|
|
47
47
|
} = require("@saltcorn/data/db/state");
|
|
48
48
|
const { loadAllPlugins } = require("../load_plugins");
|
|
49
|
-
const { create_backup, restore } = require("@saltcorn/
|
|
49
|
+
const { create_backup, restore } = require("@saltcorn/admin-models/models/backup");
|
|
50
50
|
const fs = require("fs");
|
|
51
51
|
const load_plugins = require("../load_plugins");
|
|
52
52
|
const {
|
package/routes/fields.js
CHANGED
|
@@ -27,6 +27,7 @@ const expressionBlurb = require("../markup/expression_blurb");
|
|
|
27
27
|
const { readState } = require("@saltcorn/data/plugin-helper");
|
|
28
28
|
const { wizardCardTitle } = require("../markup/forms.js");
|
|
29
29
|
const FieldRepeat = require("@saltcorn/data/models/fieldrepeat");
|
|
30
|
+
const { applyAsync } = require("@saltcorn/data/utils");
|
|
30
31
|
|
|
31
32
|
/**
|
|
32
33
|
* @type {object}
|
|
@@ -624,10 +625,38 @@ router.post(
|
|
|
624
625
|
const { tableName, fieldName, fieldview } = req.params;
|
|
625
626
|
const table = await Table.findOne({ name: tableName });
|
|
626
627
|
const fields = await table.getFields();
|
|
627
|
-
const field = fields.find((f) => f.name === fieldName);
|
|
628
|
-
const formula = field.expression;
|
|
629
628
|
const row = { ...req.body };
|
|
630
629
|
readState(row, fields);
|
|
630
|
+
|
|
631
|
+
if (fieldName.includes(".")) {
|
|
632
|
+
//join field
|
|
633
|
+
const kpath = fieldName.split(".");
|
|
634
|
+
|
|
635
|
+
if (kpath.length === 2 && row[kpath[0]]) {
|
|
636
|
+
const field = fields.find((f) => f.name === kpath[0]);
|
|
637
|
+
const reftable = await Table.findOne({ name: field.reftable_name });
|
|
638
|
+
const targetField = (await reftable.getFields()).find(
|
|
639
|
+
(f) => f.name === kpath[1]
|
|
640
|
+
);
|
|
641
|
+
const fv = targetField.type.fieldviews[fieldview];
|
|
642
|
+
const q = { [reftable.pk_name]: row[kpath[0]] };
|
|
643
|
+
const refRow = await reftable.getRow(q);
|
|
644
|
+
const configuration = req.query;
|
|
645
|
+
let configFields = [];
|
|
646
|
+
if (fv.configFields)
|
|
647
|
+
configFields = await applyAsync(fv.configFields, targetField);
|
|
648
|
+
readState(configuration, configFields);
|
|
649
|
+
res.send(fv.run(refRow[kpath[1]], req, configuration));
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
res.send("");
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
const field = fields.find((f) => f.name === fieldName);
|
|
657
|
+
|
|
658
|
+
const formula = field.expression;
|
|
659
|
+
|
|
631
660
|
let result;
|
|
632
661
|
try {
|
|
633
662
|
if (field.stored) {
|
package/routes/homepage.js
CHANGED
|
@@ -13,7 +13,7 @@ const Page = require("@saltcorn/data/models/page");
|
|
|
13
13
|
const { link, renderForm, mkTable, post_btn } = require("@saltcorn/markup");
|
|
14
14
|
const { ul, li, div, small, a, h5, p, i } = require("@saltcorn/markup/tags");
|
|
15
15
|
const Table = require("@saltcorn/data/models/table");
|
|
16
|
-
const { fetch_available_packs } = require("@saltcorn/
|
|
16
|
+
const { fetch_available_packs } = require("@saltcorn/admin-models/models/pack");
|
|
17
17
|
const { restore_backup } = require("../markup/admin");
|
|
18
18
|
const { get_latest_npm_version } = require("@saltcorn/data/models/config");
|
|
19
19
|
const packagejson = require("../package.json");
|
package/routes/packs.js
CHANGED
|
@@ -30,7 +30,7 @@ const {
|
|
|
30
30
|
fetch_pack_by_name,
|
|
31
31
|
can_install_pack,
|
|
32
32
|
uninstall_pack,
|
|
33
|
-
} = require("@saltcorn/
|
|
33
|
+
} = require("@saltcorn/admin-models/models/pack");
|
|
34
34
|
const { h5, pre, code, p, text, text_attr } = require("@saltcorn/markup/tags");
|
|
35
35
|
const Library = require("@saltcorn/data/models/library");
|
|
36
36
|
const Trigger = require("@saltcorn/data/models/trigger");
|
package/routes/pageedit.js
CHANGED
|
@@ -17,7 +17,7 @@ const Form = require("@saltcorn/data/models/form");
|
|
|
17
17
|
const File = require("@saltcorn/data/models/file");
|
|
18
18
|
const Trigger = require("@saltcorn/data/models/trigger");
|
|
19
19
|
const { getViews, traverseSync } = require("@saltcorn/data/models/layout");
|
|
20
|
-
const { add_to_menu } = require("@saltcorn/
|
|
20
|
+
const { add_to_menu } = require("@saltcorn/admin-models/models/pack");
|
|
21
21
|
const db = require("@saltcorn/data/db");
|
|
22
22
|
|
|
23
23
|
const { isAdmin, error_catcher } = require("./utils.js");
|
package/routes/plugins.js
CHANGED
|
@@ -18,7 +18,7 @@ const { getState } = require("@saltcorn/data/db/state");
|
|
|
18
18
|
const Form = require("@saltcorn/data/models/form");
|
|
19
19
|
const Field = require("@saltcorn/data/models/field");
|
|
20
20
|
const Plugin = require("@saltcorn/data/models/plugin");
|
|
21
|
-
const { fetch_available_packs } = require("@saltcorn/
|
|
21
|
+
const { fetch_available_packs } = require("@saltcorn/admin-models/models/pack");
|
|
22
22
|
const { getConfig, setConfig } = require("@saltcorn/data/models/config");
|
|
23
23
|
const db = require("@saltcorn/data/db");
|
|
24
24
|
const {
|
package/routes/scapi.js
CHANGED
|
@@ -16,7 +16,7 @@ const Page = require("@saltcorn/data/models/page");
|
|
|
16
16
|
const File = require("@saltcorn/data/models/file");
|
|
17
17
|
const Trigger = require("@saltcorn/data/models/trigger");
|
|
18
18
|
const Role = require("@saltcorn/data/models/role");
|
|
19
|
-
const Tenant = require("@saltcorn/
|
|
19
|
+
const Tenant = require("@saltcorn/admin-models/models/tenant");
|
|
20
20
|
const Plugin = require("@saltcorn/data/models/plugin");
|
|
21
21
|
const Config = require("@saltcorn/data/models/config");
|
|
22
22
|
const passport = require("passport");
|
package/routes/tenant.js
CHANGED
|
@@ -6,12 +6,15 @@
|
|
|
6
6
|
|
|
7
7
|
const Router = require("express-promise-router");
|
|
8
8
|
const Form = require("@saltcorn/data/models/form");
|
|
9
|
-
const { getState,
|
|
9
|
+
const { getState, add_tenant } = require("@saltcorn/data/db/state");
|
|
10
|
+
const { create_tenant } = require("@saltcorn/admin-models/models/tenant");
|
|
10
11
|
const {
|
|
11
12
|
getAllTenants,
|
|
12
13
|
domain_sanitize,
|
|
13
14
|
deleteTenant,
|
|
14
|
-
|
|
15
|
+
switchToTenant,
|
|
16
|
+
insertTenant,
|
|
17
|
+
} = require("@saltcorn/admin-models/models/tenant");
|
|
15
18
|
const {
|
|
16
19
|
renderForm,
|
|
17
20
|
link,
|
|
@@ -45,6 +48,10 @@ const {
|
|
|
45
48
|
save_config_from_form,
|
|
46
49
|
} = require("../markup/admin.js");
|
|
47
50
|
const { getConfig } = require("@saltcorn/data/models/config");
|
|
51
|
+
const {
|
|
52
|
+
create_backup,
|
|
53
|
+
restore,
|
|
54
|
+
} = require("@saltcorn/admin-models/models/backup");
|
|
48
55
|
|
|
49
56
|
/**
|
|
50
57
|
* @type {object}
|
|
@@ -249,13 +256,16 @@ router.post(
|
|
|
249
256
|
);
|
|
250
257
|
} else {
|
|
251
258
|
const newurl = getNewURL(req, subdomain);
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
+
const tenant_template = getState().getConfig("tenant_template");
|
|
260
|
+
await switchToTenant(await insertTenant(subdomain), newurl);
|
|
261
|
+
add_tenant(subdomain);
|
|
262
|
+
await create_tenant({
|
|
263
|
+
t: subdomain,
|
|
264
|
+
plugin_loader: loadAllPlugins,
|
|
265
|
+
noSignalOrDB: false,
|
|
266
|
+
loadAndSaveNewPlugin: loadAndSaveNewPlugin,
|
|
267
|
+
tenant_template,
|
|
268
|
+
});
|
|
259
269
|
let new_url_create = newurl;
|
|
260
270
|
const hasTemplate = getState().getConfig("tenant_template");
|
|
261
271
|
if (hasTemplate) {
|
package/routes/viewedit.js
CHANGED
|
@@ -39,7 +39,7 @@ const Workflow = require("@saltcorn/data/models/workflow");
|
|
|
39
39
|
const User = require("@saltcorn/data/models/user");
|
|
40
40
|
const Page = require("@saltcorn/data/models/page");
|
|
41
41
|
|
|
42
|
-
const { add_to_menu } = require("@saltcorn/
|
|
42
|
+
const { add_to_menu } = require("@saltcorn/admin-models/models/pack");
|
|
43
43
|
const { editRoleForm } = require("../markup/forms.js");
|
|
44
44
|
|
|
45
45
|
/**
|
package/serve.js
CHANGED
|
@@ -11,9 +11,10 @@ const db = require("@saltcorn/data/db");
|
|
|
11
11
|
const {
|
|
12
12
|
getState,
|
|
13
13
|
init_multi_tenant,
|
|
14
|
-
create_tenant,
|
|
15
14
|
restart_tenant,
|
|
15
|
+
add_tenant,
|
|
16
16
|
} = require("@saltcorn/data/db/state");
|
|
17
|
+
const { create_tenant } = require("@saltcorn/admin-models/models/tenant");
|
|
17
18
|
|
|
18
19
|
const path = require("path");
|
|
19
20
|
|
|
@@ -38,7 +39,10 @@ const {
|
|
|
38
39
|
getRelevantPackages,
|
|
39
40
|
getPluginDirectories,
|
|
40
41
|
} = require("./restart_watcher");
|
|
41
|
-
const {
|
|
42
|
+
const {
|
|
43
|
+
eachTenant,
|
|
44
|
+
getAllTenants,
|
|
45
|
+
} = require("@saltcorn/admin-models/models/tenant");
|
|
42
46
|
|
|
43
47
|
// helpful https://gist.github.com/jpoehls/2232358
|
|
44
48
|
/**
|
|
@@ -72,7 +76,8 @@ const initMaster = async ({ disableMigrate }, useClusterAdaptor = true) => {
|
|
|
72
76
|
// switch on sql logging - but it was initiated before???
|
|
73
77
|
if (getState().getConfig("log_sql", false)) db.set_sql_logging();
|
|
74
78
|
if (db.is_it_multi_tenant()) {
|
|
75
|
-
await
|
|
79
|
+
const tenants = await getAllTenants();
|
|
80
|
+
await init_multi_tenant(loadAllPlugins, disableMigrate, tenants);
|
|
76
81
|
}
|
|
77
82
|
if (useClusterAdaptor) setupPrimary();
|
|
78
83
|
};
|
|
@@ -95,7 +100,14 @@ const workerDispatchMsg = ({ tenant, ...msg }) => {
|
|
|
95
100
|
}
|
|
96
101
|
if (msg.refresh) getState()[`refresh_${msg.refresh}`](true);
|
|
97
102
|
if (msg.createTenant) {
|
|
98
|
-
|
|
103
|
+
const tenant_template = getState().getConfig("tenant_template");
|
|
104
|
+
add_tenant(msg.createTenant);
|
|
105
|
+
create_tenant({
|
|
106
|
+
t: msg.createTenant,
|
|
107
|
+
plugin_loader: loadAllPlugins,
|
|
108
|
+
noSignalOrDB: true,
|
|
109
|
+
tenant_template,
|
|
110
|
+
});
|
|
99
111
|
db.runWithTenant(msg.createTenant, async () => {
|
|
100
112
|
getState().refresh(true);
|
|
101
113
|
});
|
|
@@ -117,29 +129,28 @@ const workerDispatchMsg = ({ tenant, ...msg }) => {
|
|
|
117
129
|
* @param {number} opts.pid
|
|
118
130
|
* @returns {function}
|
|
119
131
|
*/
|
|
120
|
-
const onMessageFromWorker =
|
|
121
|
-
masterState,
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
};
|
|
132
|
+
const onMessageFromWorker =
|
|
133
|
+
(masterState, { port, watchReaper, disableScheduler, pid }) =>
|
|
134
|
+
(msg) => {
|
|
135
|
+
//console.log("worker msg", typeof msg, msg);
|
|
136
|
+
if (msg === "Start" && !masterState.started) {
|
|
137
|
+
masterState.started = true;
|
|
138
|
+
runScheduler({ port, watchReaper, disableScheduler, eachTenant });
|
|
139
|
+
require("./systemd")({ port });
|
|
140
|
+
return true;
|
|
141
|
+
} else if (msg === "RestartServer") {
|
|
142
|
+
process.exit(0);
|
|
143
|
+
return true;
|
|
144
|
+
} else if (msg.tenant || msg.createTenant) {
|
|
145
|
+
///ie from saltcorn
|
|
146
|
+
//broadcast
|
|
147
|
+
Object.entries(cluster.workers).forEach(([wpid, w]) => {
|
|
148
|
+
if (wpid !== pid) w.send(msg);
|
|
149
|
+
});
|
|
150
|
+
workerDispatchMsg(msg); //also master
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
};
|
|
143
154
|
|
|
144
155
|
module.exports =
|
|
145
156
|
/**
|