@saltcorn/server 0.8.6-beta.9 → 0.8.7-beta.0

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/auth/admin.js CHANGED
@@ -54,7 +54,7 @@ module.exports = router;
54
54
  * @returns {Promise<object>}
55
55
  */
56
56
  const getUserFields = async (req) => {
57
- const userTable = await Table.findOne({ name: "users" });
57
+ const userTable = Table.findOne({ name: "users" });
58
58
  const userFields = (await userTable.getFields()).filter(
59
59
  (f) => !f.calculated && f.name !== "id"
60
60
  );
@@ -795,7 +795,7 @@ router.get(
795
795
  const contents = [];
796
796
  for (const table of tables) {
797
797
  if (table.external) continue;
798
- const fields = await table.getFields();
798
+ const fields = table.getFields();
799
799
  const ownership_opts = await table.ownership_options();
800
800
  const form = new Form({
801
801
  action: "/table",
package/auth/routes.js CHANGED
@@ -467,7 +467,7 @@ const default_signup_form = async (req) => {
467
467
  const form = loginForm(req, true);
468
468
  const new_user_form = getState().getConfig("new_user_form", "");
469
469
  if (!new_user_form) {
470
- const userTable = await Table.findOne({ name: "users" });
470
+ const userTable = Table.findOne({ name: "users" });
471
471
  const userFields = await userTable.getFields();
472
472
 
473
473
  for (const f of userFields) {
@@ -631,8 +631,8 @@ const getNewUserForm = async (new_user_view_name, req, askEmail) => {
631
631
  const view = await View.findOne({ name: new_user_view_name });
632
632
  if (!view)
633
633
  throw new InvalidConfiguration("New user form view does not exist");
634
- const table = await Table.findOne({ name: "users" });
635
- const fields = await table.getFields();
634
+ const table = Table.findOne({ name: "users" });
635
+ const fields = table.getFields();
636
636
  const { columns, layout } = view.configuration;
637
637
 
638
638
  const tfields = (columns || [])
@@ -776,8 +776,8 @@ router.post(
776
776
 
777
777
  signup_login_with_user(u, req, res);
778
778
  } catch (e) {
779
- const table = await Table.findOne({ name: "users" });
780
- const fields = await table.getFields();
779
+ const table = Table.findOne({ name: "users" });
780
+ const fields = table.getFields();
781
781
  form.hasErrors = true;
782
782
  const unique_field_error = fields.find(
783
783
  (f) =>
@@ -833,8 +833,8 @@ router.post(
833
833
 
834
834
  signup_login_with_user(u, req, res);
835
835
  } catch (e) {
836
- const table = await Table.findOne({ name: "users" });
837
- const fields = await table.getFields();
836
+ const table = Table.findOne({ name: "users" });
837
+ const fields = table.getFields();
838
838
  form.hasErrors = true;
839
839
  const unique_field_error = fields.find(
840
840
  (f) =>
package/load_plugins.js CHANGED
@@ -209,13 +209,14 @@ const loadAndSaveNewPlugin = async (plugin, force, noSignalOrDB) => {
209
209
  }
210
210
  }
211
211
  if (version) plugin.version = version;
212
- if (!noSignalOrDB) await plugin.upsert();
213
- if (!noSignalOrDB && process.send)
214
- process.send({
212
+ if (!noSignalOrDB) {
213
+ await plugin.upsert();
214
+ getState().processSend({
215
215
  installPlugin: plugin,
216
216
  tenant: db.getTenantSchema(),
217
217
  force,
218
218
  });
219
+ }
219
220
  };
220
221
 
221
222
  module.exports = {
package/locales/en.json CHANGED
@@ -1167,5 +1167,11 @@
1167
1167
  "Migrations": "Migrations",
1168
1168
  "Tag Entries": "Tag Entries",
1169
1169
  "Not a valid field name": "Not a valid field name",
1170
- "Set a default value for missing data": "Set a default value for missing data"
1170
+ "Set a default value for missing data": "Set a default value for missing data",
1171
+ "Table triggers: ": "Table triggers: ",
1172
+ "App name": "App name",
1173
+ "App icon": "App icon",
1174
+ "Splash Page": "Splash Page",
1175
+ "App version": "App version",
1176
+ "Forgot password?": "Forgot password?"
1171
1177
  }
package/markup/admin.js CHANGED
@@ -328,7 +328,7 @@ const send_admin_page = (args) => {
328
328
  */
329
329
  const viewAttributes = async (key) => {
330
330
  const [v, table_name] = configTypes[key].type.split(" ");
331
- const table = await Table.findOne({ name: table_name });
331
+ const table = Table.findOne({ name: table_name });
332
332
  const views = await View.find({ table_id: table.id });
333
333
  return {
334
334
  options: views.map((v) => {
package/package.json CHANGED
@@ -1,22 +1,22 @@
1
1
  {
2
2
  "name": "@saltcorn/server",
3
- "version": "0.8.6-beta.9",
3
+ "version": "0.8.7-beta.0",
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.8.6-beta.9",
10
- "@saltcorn/builder": "0.8.6-beta.9",
11
- "@saltcorn/data": "0.8.6-beta.9",
12
- "@saltcorn/admin-models": "0.8.6-beta.9",
13
- "@saltcorn/filemanager": "0.8.6-beta.9",
14
- "@saltcorn/markup": "0.8.6-beta.9",
15
- "@saltcorn/sbadmin2": "0.8.6-beta.9",
9
+ "@saltcorn/base-plugin": "0.8.7-beta.0",
10
+ "@saltcorn/builder": "0.8.7-beta.0",
11
+ "@saltcorn/data": "0.8.7-beta.0",
12
+ "@saltcorn/admin-models": "0.8.7-beta.0",
13
+ "@saltcorn/filemanager": "0.8.7-beta.0",
14
+ "@saltcorn/markup": "0.8.7-beta.0",
15
+ "@saltcorn/sbadmin2": "0.8.7-beta.0",
16
16
  "@socket.io/cluster-adapter": "^0.2.1",
17
17
  "@socket.io/sticky": "^1.0.1",
18
18
  "adm-zip": "0.5.10",
19
- "aws-sdk": "^2.1037.0",
19
+ "aws-sdk": "^2.1386.0",
20
20
  "connect-flash": "^0.1.1",
21
21
  "connect-pg-simple": "^6.1.0",
22
22
  "content-disposition": "^0.5.3",
@@ -0,0 +1,70 @@
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: https://codemirror.net/5/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"), require("../../addon/mode/simple"), require("../../addon/mode/multiplex"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror", "../../addon/mode/simple", "../../addon/mode/multiplex"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ CodeMirror.defineSimpleMode("handlebars-tags", {
15
+ start: [
16
+ { regex: /\{\{\{/, push: "handlebars_raw", token: "tag" },
17
+ { regex: /\{\{!--/, push: "dash_comment", token: "comment" },
18
+ { regex: /\{\{!/, push: "comment", token: "comment" },
19
+ { regex: /\{\{/, push: "handlebars", token: "tag" }
20
+ ],
21
+ handlebars_raw: [
22
+ { regex: /\}\}\}/, pop: true, token: "tag" },
23
+ ],
24
+ handlebars: [
25
+ { regex: /\}\}/, pop: true, token: "tag" },
26
+
27
+ // Double and single quotes
28
+ { regex: /"(?:[^\\"]|\\.)*"?/, token: "string" },
29
+ { regex: /'(?:[^\\']|\\.)*'?/, token: "string" },
30
+
31
+ // Handlebars keywords
32
+ { regex: />|[#\/]([A-Za-z_]\w*)/, token: "keyword" },
33
+ { regex: /(?:else|this)\b/, token: "keyword" },
34
+
35
+ // Numeral
36
+ { regex: /\d+/i, token: "number" },
37
+
38
+ // Atoms like = and .
39
+ { regex: /=|~|@|true|false/, token: "atom" },
40
+
41
+ // Paths
42
+ { regex: /(?:\.\.\/)*(?:[A-Za-z_][\w\.]*)+/, token: "variable-2" }
43
+ ],
44
+ dash_comment: [
45
+ { regex: /--\}\}/, pop: true, token: "comment" },
46
+
47
+ // Commented code
48
+ { regex: /./, token: "comment"}
49
+ ],
50
+ comment: [
51
+ { regex: /\}\}/, pop: true, token: "comment" },
52
+ { regex: /./, token: "comment" }
53
+ ],
54
+ meta: {
55
+ blockCommentStart: "{{--",
56
+ blockCommentEnd: "--}}"
57
+ }
58
+ });
59
+
60
+ CodeMirror.defineMode("handlebars", function(config, parserConfig) {
61
+ var handlebars = CodeMirror.getMode(config, "handlebars-tags");
62
+ if (!parserConfig || !parserConfig.base) return handlebars;
63
+ return CodeMirror.multiplexingMode(
64
+ CodeMirror.getMode(config, parserConfig.base),
65
+ {open: "{{", close: /\}\}\}?/, mode: handlebars, parseDelimiters: true}
66
+ );
67
+ });
68
+
69
+ CodeMirror.defineMIME("text/x-handlebars-template", "handlebars");
70
+ });
@@ -0,0 +1,153 @@
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: https://codemirror.net/5/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ var defaultTags = {
15
+ script: [
16
+ ["lang", /(javascript|babel)/i, "javascript"],
17
+ ["type", /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i, "javascript"],
18
+ ["type", /./, "text/plain"],
19
+ [null, null, "javascript"]
20
+ ],
21
+ style: [
22
+ ["lang", /^css$/i, "css"],
23
+ ["type", /^(text\/)?(x-)?(stylesheet|css)$/i, "css"],
24
+ ["type", /./, "text/plain"],
25
+ [null, null, "css"]
26
+ ]
27
+ };
28
+
29
+ function maybeBackup(stream, pat, style) {
30
+ var cur = stream.current(), close = cur.search(pat);
31
+ if (close > -1) {
32
+ stream.backUp(cur.length - close);
33
+ } else if (cur.match(/<\/?$/)) {
34
+ stream.backUp(cur.length);
35
+ if (!stream.match(pat, false)) stream.match(cur);
36
+ }
37
+ return style;
38
+ }
39
+
40
+ var attrRegexpCache = {};
41
+ function getAttrRegexp(attr) {
42
+ var regexp = attrRegexpCache[attr];
43
+ if (regexp) return regexp;
44
+ return attrRegexpCache[attr] = new RegExp("\\s+" + attr + "\\s*=\\s*('|\")?([^'\"]+)('|\")?\\s*");
45
+ }
46
+
47
+ function getAttrValue(text, attr) {
48
+ var match = text.match(getAttrRegexp(attr))
49
+ return match ? /^\s*(.*?)\s*$/.exec(match[2])[1] : ""
50
+ }
51
+
52
+ function getTagRegexp(tagName, anchored) {
53
+ return new RegExp((anchored ? "^" : "") + "<\/\\s*" + tagName + "\\s*>", "i");
54
+ }
55
+
56
+ function addTags(from, to) {
57
+ for (var tag in from) {
58
+ var dest = to[tag] || (to[tag] = []);
59
+ var source = from[tag];
60
+ for (var i = source.length - 1; i >= 0; i--)
61
+ dest.unshift(source[i])
62
+ }
63
+ }
64
+
65
+ function findMatchingMode(tagInfo, tagText) {
66
+ for (var i = 0; i < tagInfo.length; i++) {
67
+ var spec = tagInfo[i];
68
+ if (!spec[0] || spec[1].test(getAttrValue(tagText, spec[0]))) return spec[2];
69
+ }
70
+ }
71
+
72
+ CodeMirror.defineMode("htmlmixed", function (config, parserConfig) {
73
+ var htmlMode = CodeMirror.getMode(config, {
74
+ name: "xml",
75
+ htmlMode: true,
76
+ multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
77
+ multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag,
78
+ allowMissingTagName: parserConfig.allowMissingTagName,
79
+ });
80
+
81
+ var tags = {};
82
+ var configTags = parserConfig && parserConfig.tags, configScript = parserConfig && parserConfig.scriptTypes;
83
+ addTags(defaultTags, tags);
84
+ if (configTags) addTags(configTags, tags);
85
+ if (configScript) for (var i = configScript.length - 1; i >= 0; i--)
86
+ tags.script.unshift(["type", configScript[i].matches, configScript[i].mode])
87
+
88
+ function html(stream, state) {
89
+ var style = htmlMode.token(stream, state.htmlState), tag = /\btag\b/.test(style), tagName
90
+ if (tag && !/[<>\s\/]/.test(stream.current()) &&
91
+ (tagName = state.htmlState.tagName && state.htmlState.tagName.toLowerCase()) &&
92
+ tags.hasOwnProperty(tagName)) {
93
+ state.inTag = tagName + " "
94
+ } else if (state.inTag && tag && />$/.test(stream.current())) {
95
+ var inTag = /^([\S]+) (.*)/.exec(state.inTag)
96
+ state.inTag = null
97
+ var modeSpec = stream.current() == ">" && findMatchingMode(tags[inTag[1]], inTag[2])
98
+ var mode = CodeMirror.getMode(config, modeSpec)
99
+ var endTagA = getTagRegexp(inTag[1], true), endTag = getTagRegexp(inTag[1], false);
100
+ state.token = function (stream, state) {
101
+ if (stream.match(endTagA, false)) {
102
+ state.token = html;
103
+ state.localState = state.localMode = null;
104
+ return null;
105
+ }
106
+ return maybeBackup(stream, endTag, state.localMode.token(stream, state.localState));
107
+ };
108
+ state.localMode = mode;
109
+ state.localState = CodeMirror.startState(mode, htmlMode.indent(state.htmlState, "", ""));
110
+ } else if (state.inTag) {
111
+ state.inTag += stream.current()
112
+ if (stream.eol()) state.inTag += " "
113
+ }
114
+ return style;
115
+ };
116
+
117
+ return {
118
+ startState: function () {
119
+ var state = CodeMirror.startState(htmlMode);
120
+ return {token: html, inTag: null, localMode: null, localState: null, htmlState: state};
121
+ },
122
+
123
+ copyState: function (state) {
124
+ var local;
125
+ if (state.localState) {
126
+ local = CodeMirror.copyState(state.localMode, state.localState);
127
+ }
128
+ return {token: state.token, inTag: state.inTag,
129
+ localMode: state.localMode, localState: local,
130
+ htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
131
+ },
132
+
133
+ token: function (stream, state) {
134
+ return state.token(stream, state);
135
+ },
136
+
137
+ indent: function (state, textAfter, line) {
138
+ if (!state.localMode || /^\s*<\//.test(textAfter))
139
+ return htmlMode.indent(state.htmlState, textAfter, line);
140
+ else if (state.localMode.indent)
141
+ return state.localMode.indent(state.localState, textAfter, line);
142
+ else
143
+ return CodeMirror.Pass;
144
+ },
145
+
146
+ innerMode: function (state) {
147
+ return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
148
+ }
149
+ };
150
+ }, "xml", "javascript", "css");
151
+
152
+ CodeMirror.defineMIME("text/html", "htmlmixed");
153
+ });
package/routes/actions.js CHANGED
@@ -171,6 +171,13 @@ const triggerForm = async (req, trigger) => {
171
171
  required: true,
172
172
  options: Trigger.when_options.map((t) => ({ value: t, label: t })),
173
173
  sublabel: req.__("Event type which runs the trigger"),
174
+ attributes: {
175
+ explainers: {
176
+ Often: "Every 5 minutes",
177
+ Never:
178
+ "Not scheduled but can be run as an action from a button click",
179
+ },
180
+ },
174
181
  },
175
182
  {
176
183
  name: "table_id",
@@ -457,7 +464,7 @@ router.get(
457
464
  } else {
458
465
  // get table related to trigger
459
466
  const table = trigger.table_id
460
- ? await Table.findOne({ id: trigger.table_id })
467
+ ? Table.findOne({ id: trigger.table_id })
461
468
  : null;
462
469
  // get configuration fields
463
470
  const cfgFields = await getActionConfigFields(action, table);
@@ -502,7 +509,7 @@ router.post(
502
509
  const trigger = await Trigger.findOne({ id });
503
510
  const action = getState().actions[trigger.action];
504
511
  const table = trigger.table_id
505
- ? await Table.findOne({ id: trigger.table_id })
512
+ ? Table.findOne({ id: trigger.table_id })
506
513
  : null;
507
514
  const cfgFields = await getActionConfigFields(action, table);
508
515
  const form = new Form({
@@ -588,7 +595,7 @@ router.get(
588
595
  };
589
596
  let table, row;
590
597
  if (trigger.table_id) {
591
- table = await Table.findOne({ id: trigger.table_id });
598
+ table = Table.findOne({ id: trigger.table_id });
592
599
  row = await table.getRow({});
593
600
  }
594
601
  try {
package/routes/admin.js CHANGED
@@ -954,12 +954,14 @@ router.post(
954
954
  isAdmin,
955
955
  error_catcher(async (req, res) => {
956
956
  if (db.getTenantSchema() === db.connectObj.default_schema) {
957
- if (process.send) process.send("RestartServer");
957
+ if (process.send) getState().processSend("RestartServer");
958
958
  else process.exit(0);
959
959
  } else {
960
960
  await restart_tenant(loadAllPlugins);
961
- process.send &&
962
- process.send({ restart_tenant: true, tenant: db.getTenantSchema() });
961
+ getState().processSend({
962
+ restart_tenant: true,
963
+ tenant: db.getTenantSchema(),
964
+ });
963
965
  req.flash("success", req.__("Restart complete"));
964
966
  res.redirect("/admin");
965
967
  }
@@ -984,13 +986,13 @@ router.post(
984
986
  "npm",
985
987
  ["install", "-g", "@saltcorn/cli@latest", "--unsafe"],
986
988
  {
987
- stdio: ["ignore", "pipe", process.stderr],
989
+ stdio: ["ignore", "pipe", "pipe"],
988
990
  }
989
991
  );
990
992
  child.stdout.on("data", (data) => {
991
993
  res.write(data);
992
994
  });
993
- child.stderr.on("data", (data) => {
995
+ child.stderr?.on("data", (data) => {
994
996
  res.write(data);
995
997
  });
996
998
  child.on("exit", function (code, signal) {
@@ -1000,7 +1002,7 @@ router.post(
1000
1002
  )
1001
1003
  );
1002
1004
  setTimeout(() => {
1003
- if (process.send) process.send("RestartServer");
1005
+ getState().processSend("RestartServer");
1004
1006
  process.exit(0);
1005
1007
  }, 100);
1006
1008
  });
@@ -1385,6 +1387,9 @@ router.get(
1385
1387
  error_catcher(async (req, res) => {
1386
1388
  const views = await View.find();
1387
1389
  const pages = await Page.find();
1390
+ const images = (await File.find({ mime_super: "image" })).filter((image) =>
1391
+ image.filename?.endsWith(".png")
1392
+ );
1388
1393
 
1389
1394
  send_admin_page({
1390
1395
  res,
@@ -1462,7 +1467,7 @@ router.get(
1462
1467
  // select entry-view
1463
1468
  select(
1464
1469
  {
1465
- class: "form-control",
1470
+ class: "form-select",
1466
1471
  name: "entryPoint",
1467
1472
  id: "viewInputID",
1468
1473
  },
@@ -1475,14 +1480,14 @@ router.get(
1475
1480
  // select entry-page
1476
1481
  select(
1477
1482
  {
1478
- class: "form-control d-none",
1483
+ class: "form-select d-none",
1479
1484
  id: "pageInputID",
1480
1485
  },
1481
1486
  pages
1482
1487
  .map((page) =>
1483
1488
  option({ value: page.name }, page.name)
1484
1489
  )
1485
- .join(",")
1490
+ .join("")
1486
1491
  )
1487
1492
  ),
1488
1493
  div(
@@ -1528,28 +1533,51 @@ router.get(
1528
1533
  })
1529
1534
  )
1530
1535
  ),
1536
+ // app name
1531
1537
  div(
1532
1538
  { class: "row pb-2" },
1533
1539
  div(
1534
1540
  { class: "col-sm-8" },
1535
1541
  label(
1536
1542
  {
1537
- for: "appNameInputId",
1543
+ for: "appFileInputId",
1538
1544
  class: "form-label fw-bold",
1539
1545
  },
1540
- req.__("App file")
1546
+ req.__("App name")
1541
1547
  ),
1542
1548
  input({
1543
1549
  type: "text",
1544
1550
  class: "form-control",
1545
- name: "appFile",
1546
- id: "appFileInputId",
1547
- placeholder: "app-debug",
1551
+ name: "appName",
1552
+ id: "appNameInputId",
1553
+ placeholder: "SaltcornMobileApp",
1548
1554
  })
1549
1555
  )
1550
1556
  ),
1557
+ // app version
1551
1558
  div(
1552
- { class: "row pb-3" },
1559
+ { class: "row pb-2" },
1560
+ div(
1561
+ { class: "col-sm-8" },
1562
+ label(
1563
+ {
1564
+ for: "appVersionInputId",
1565
+ class: "form-label fw-bold",
1566
+ },
1567
+ req.__("App version")
1568
+ ),
1569
+ input({
1570
+ type: "text",
1571
+ class: "form-control",
1572
+ name: "appVersion",
1573
+ id: "appVersionInputId",
1574
+ placeholder: "1.0.0",
1575
+ })
1576
+ )
1577
+ ),
1578
+ // server url
1579
+ div(
1580
+ { class: "row pb-2" },
1553
1581
  div(
1554
1582
  { class: "col-sm-8" },
1555
1583
  label(
@@ -1568,6 +1596,60 @@ router.get(
1568
1596
  })
1569
1597
  )
1570
1598
  ),
1599
+ // app icon
1600
+ div(
1601
+ { class: "row pb-2" },
1602
+ div(
1603
+ { class: "col-sm-8" },
1604
+ label(
1605
+ {
1606
+ for: "appIconInputId",
1607
+ class: "form-label fw-bold",
1608
+ },
1609
+ req.__("App icon")
1610
+ ),
1611
+ select(
1612
+ {
1613
+ class: "form-select",
1614
+ name: "appIcon",
1615
+ id: "appIconInputId",
1616
+ },
1617
+ [
1618
+ option({ value: "" }, ""),
1619
+ ...images.map((image) =>
1620
+ option({ value: image.location }, image.filename)
1621
+ ),
1622
+ ].join("")
1623
+ )
1624
+ )
1625
+ ),
1626
+ div(
1627
+ { class: "row pb-3" },
1628
+ div(
1629
+ { class: "col-sm-8" },
1630
+ label(
1631
+ {
1632
+ for: "splashPageInputId",
1633
+ class: "form-label fw-bold",
1634
+ },
1635
+ req.__("Splash Page")
1636
+ ),
1637
+ select(
1638
+ {
1639
+ class: "form-select",
1640
+ name: "splashPage",
1641
+ id: "splashPageInputId",
1642
+ },
1643
+ [
1644
+ option({ value: "" }, ""),
1645
+ ...pages.map((page) =>
1646
+ option({ value: page.name }, page.name)
1647
+ ),
1648
+ ].join("")
1649
+ )
1650
+ )
1651
+ ),
1652
+
1571
1653
  div(
1572
1654
  // TODO only for some tables?
1573
1655
  { class: "row pb-2" },
@@ -1686,8 +1768,11 @@ router.post(
1686
1768
  androidPlatform,
1687
1769
  iOSPlatform,
1688
1770
  useDocker,
1689
- appFile,
1771
+ appName,
1772
+ appVersion,
1773
+ appIcon,
1690
1774
  serverURL,
1775
+ splashPage,
1691
1776
  allowOfflineMode,
1692
1777
  } = req.body;
1693
1778
  if (!androidPlatform && !iOSPlatform) {
@@ -1734,8 +1819,11 @@ router.post(
1734
1819
  spawnParams.push("--buildForEmulator");
1735
1820
  }
1736
1821
  }
1737
- if (appFile) spawnParams.push("-a", appFile);
1822
+ if (appName) spawnParams.push("--appName", appName);
1823
+ if (appVersion) spawnParams.push("--appVersion", appVersion);
1824
+ if (appIcon) spawnParams.push("--appIcon", appIcon);
1738
1825
  if (serverURL) spawnParams.push("-s", serverURL);
1826
+ if (splashPage) spawnParams.push("--splashPage", splashPage);
1739
1827
  if (allowOfflineMode) spawnParams.push("--allowOfflineMode");
1740
1828
  if (
1741
1829
  db.is_it_multi_tenant() &&
@@ -1816,7 +1904,7 @@ router.post(
1816
1904
  await View.delete({});
1817
1905
  }
1818
1906
  //user fields
1819
- const users = await Table.findOne({ name: "users" });
1907
+ const users = Table.findOne({ name: "users" });
1820
1908
  const userfields = await users.getFields();
1821
1909
  for (const f of userfields) {
1822
1910
  if (f.is_fkey) {
@@ -1837,7 +1925,7 @@ router.post(
1837
1925
  table_id: table.id,
1838
1926
  });
1839
1927
  await table.update({ ownership_field_id: null });
1840
- const fields = await table.getFields();
1928
+ const fields = table.getFields();
1841
1929
  for (const f of fields) {
1842
1930
  if (f.is_fkey) {
1843
1931
  await f.delete();
@@ -1880,14 +1968,16 @@ router.post(
1880
1968
  await getState().refresh();
1881
1969
  }
1882
1970
  if (form.values.users) {
1883
- const users1 = await Table.findOne({ name: "users" });
1971
+ const users1 = Table.findOne({ name: "users" });
1884
1972
  const userfields1 = await users1.getFields();
1885
1973
 
1886
1974
  for (const f of userfields1) {
1887
1975
  if (f.name !== "email" && f.name !== "id") await f.delete();
1888
1976
  }
1889
1977
  await db.deleteWhere("users");
1890
- await db.deleteWhere("_sc_roles", { not: { id: { in: [1, 4, 8, 10] } } });
1978
+ await db.deleteWhere("_sc_roles", {
1979
+ not: { id: { in: [1, 40, 80, 100] } },
1980
+ });
1891
1981
  if (db.reset_sequence) await db.reset_sequence("users");
1892
1982
  req.logout(function (err) {
1893
1983
  if (req.session.destroy)