@saltcorn/server 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/app.js +7 -0
- package/auth/admin.js +120 -5
- package/auth/index.js +7 -0
- package/auth/resetpw.js +22 -0
- package/auth/roleadmin.js +52 -0
- package/auth/routes.js +211 -2
- package/auth/testhelp.js +69 -0
- package/errors.js +14 -1
- package/fixture_persons.js +14 -0
- package/index.js +6 -0
- package/load_plugins.js +4 -3
- package/locales/en.json +7 -1
- package/markup/admin.js +97 -1
- package/markup/blockly.js +15 -0
- package/markup/expression_blurb.js +45 -0
- package/markup/forms.js +24 -0
- package/markup/index.js +7 -0
- package/markup/plugin-store.js +36 -0
- package/package.json +6 -6
- package/public/saltcorn-builder.css +1 -0
- package/public/saltcorn.js +5 -1
- package/routes/actions.js +53 -1
- package/routes/admin.js +97 -1
- package/routes/api.js +45 -10
- package/routes/config.js +18 -0
- package/routes/crashlog.js +31 -0
- package/routes/delete.js +19 -0
- package/routes/edit.js +19 -0
- package/routes/eventlog.js +65 -1
- package/routes/events.js +19 -0
- package/routes/fields.js +88 -0
- package/routes/files.js +62 -0
- package/routes/homepage.js +175 -80
- package/routes/index.js +7 -1
- package/routes/infoarch.js +56 -0
- package/routes/library.js +32 -0
- package/routes/list.js +28 -1
- package/routes/menu.js +45 -0
- package/routes/packs.js +53 -0
- package/routes/page.js +26 -0
- package/routes/pageedit.js +129 -3
- package/routes/plugins.js +156 -5
- package/routes/scapi.js +79 -23
- package/routes/search.js +51 -0
- package/routes/settings.js +27 -0
- package/routes/tables.js +148 -19
- package/routes/tenant.js +123 -31
- package/routes/utils.js +60 -1
- package/routes/view.js +37 -0
- package/routes/viewedit.js +114 -1
- package/serve.js +138 -88
- package/systemd.js +18 -1
- package/wrapper.js +4 -0
package/locales/en.json
CHANGED
|
@@ -808,5 +808,11 @@
|
|
|
808
808
|
"Set to 0 for expration at the end of browser session": "Set to 0 for expration at the end of browser session",
|
|
809
809
|
"Cookie duration (hours) when remember ticked": "Cookie duration (hours) when remember ticked",
|
|
810
810
|
"Forget table": "Forget table",
|
|
811
|
-
"Table %s forgotten. You can now discover it.": "Table %s forgotten. You can now discover it."
|
|
811
|
+
"Table %s forgotten. You can now discover it.": "Table %s forgotten. You can now discover it.",
|
|
812
|
+
"No triggers": "No triggers",
|
|
813
|
+
"List width": "List width",
|
|
814
|
+
"Number of columns (1-12) allocated to the list view": "Number of columns (1-12) allocated to the list view",
|
|
815
|
+
"New tenant template": "New tenant template",
|
|
816
|
+
"Copy site structure for new tenants from this tenant": "Copy site structure for new tenants from this tenant",
|
|
817
|
+
"Use this link: <a href=\"%s\">%s</a> to revisit your application at any time.": "Use this link: <a href=\"%s\">%s</a> to revisit your application at any time."
|
|
812
818
|
}
|
package/markup/admin.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @category server
|
|
3
|
+
* @module markup/admin
|
|
4
|
+
* @subcategory markup
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
const {
|
|
2
8
|
div,
|
|
3
9
|
hr,
|
|
@@ -26,6 +32,12 @@ const Table = require("@saltcorn/data/models/table");
|
|
|
26
32
|
const View = require("@saltcorn/data/models/view");
|
|
27
33
|
const User = require("@saltcorn/data/models/user");
|
|
28
34
|
|
|
35
|
+
/**
|
|
36
|
+
* @param {*} csrf
|
|
37
|
+
* @param {*} inner
|
|
38
|
+
* @param {string} action
|
|
39
|
+
* @returns {*}
|
|
40
|
+
*/
|
|
29
41
|
const restore_backup = (csrf, inner, action = `/admin/restore`) =>
|
|
30
42
|
form(
|
|
31
43
|
{
|
|
@@ -45,6 +57,16 @@ const restore_backup = (csrf, inner, action = `/admin/restore`) =>
|
|
|
45
57
|
})
|
|
46
58
|
);
|
|
47
59
|
|
|
60
|
+
/**
|
|
61
|
+
* @param {object} opts
|
|
62
|
+
* @param {*} opts.role
|
|
63
|
+
* @param {*} opts.title
|
|
64
|
+
* @param {*} opts.contents
|
|
65
|
+
* @param {*} opts.what
|
|
66
|
+
* @param {*} opts.url
|
|
67
|
+
* @param {*} opts.req
|
|
68
|
+
* @returns {object}
|
|
69
|
+
*/
|
|
48
70
|
const add_edit_bar = ({ role, title, contents, what, url, req }) => {
|
|
49
71
|
if (role > 1 && req && req.xhr) return { above: [contents] }; //make sure not put in card
|
|
50
72
|
if (role > 1) return contents;
|
|
@@ -61,6 +83,19 @@ const add_edit_bar = ({ role, title, contents, what, url, req }) => {
|
|
|
61
83
|
} else return { above: [bar, contents] };
|
|
62
84
|
};
|
|
63
85
|
|
|
86
|
+
/**
|
|
87
|
+
* @param {object} opts
|
|
88
|
+
* @param {*} opts.req,
|
|
89
|
+
* @param {*} opts.res,
|
|
90
|
+
* @param {*} opts.main_section,
|
|
91
|
+
* @param {*} opts.main_section_href,
|
|
92
|
+
* @param {*} opts.sub_sections,
|
|
93
|
+
* @param {*} opts.active_sub,
|
|
94
|
+
* @param {*} opts.contents,
|
|
95
|
+
* @param {*} opts.headers,
|
|
96
|
+
* @param {*} opts.no_nav_pills,
|
|
97
|
+
* @param {*} opts.sub2_page,
|
|
98
|
+
*/
|
|
64
99
|
const send_settings_page = ({
|
|
65
100
|
req,
|
|
66
101
|
res,
|
|
@@ -132,6 +167,10 @@ const send_settings_page = ({
|
|
|
132
167
|
});
|
|
133
168
|
};
|
|
134
169
|
|
|
170
|
+
/**
|
|
171
|
+
* @param {object} args
|
|
172
|
+
* @returns {void}
|
|
173
|
+
*/
|
|
135
174
|
const send_infoarch_page = (args) => {
|
|
136
175
|
const tenant_list =
|
|
137
176
|
db.is_it_multi_tenant() &&
|
|
@@ -155,6 +194,10 @@ const send_infoarch_page = (args) => {
|
|
|
155
194
|
});
|
|
156
195
|
};
|
|
157
196
|
|
|
197
|
+
/**
|
|
198
|
+
* @param {object} args
|
|
199
|
+
* @returns {void}
|
|
200
|
+
*/
|
|
158
201
|
const send_users_page = (args) => {
|
|
159
202
|
const isRoot = db.getTenantSchema() === db.connectObj.default_schema;
|
|
160
203
|
return send_settings_page({
|
|
@@ -170,6 +213,10 @@ const send_users_page = (args) => {
|
|
|
170
213
|
});
|
|
171
214
|
};
|
|
172
215
|
|
|
216
|
+
/**
|
|
217
|
+
* @param {object} args
|
|
218
|
+
* @returns {void}
|
|
219
|
+
*/
|
|
173
220
|
const send_events_page = (args) => {
|
|
174
221
|
const isRoot = db.getTenantSchema() === db.connectObj.default_schema;
|
|
175
222
|
return send_settings_page({
|
|
@@ -185,6 +232,11 @@ const send_events_page = (args) => {
|
|
|
185
232
|
...args,
|
|
186
233
|
});
|
|
187
234
|
};
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* @param {object} args
|
|
238
|
+
* @returns {void}
|
|
239
|
+
*/
|
|
188
240
|
const send_admin_page = (args) => {
|
|
189
241
|
const isRoot = db.getTenantSchema() === db.connectObj.default_schema;
|
|
190
242
|
return send_settings_page({
|
|
@@ -199,6 +251,11 @@ const send_admin_page = (args) => {
|
|
|
199
251
|
...args,
|
|
200
252
|
});
|
|
201
253
|
};
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* @param {object} key
|
|
257
|
+
* @returns {Promise<object>}
|
|
258
|
+
*/
|
|
202
259
|
const viewAttributes = async (key) => {
|
|
203
260
|
const [v, table_name] = configTypes[key].type.split(" ");
|
|
204
261
|
const table = await Table.findOne({ name: table_name });
|
|
@@ -211,6 +268,11 @@ const viewAttributes = async (key) => {
|
|
|
211
268
|
};
|
|
212
269
|
};
|
|
213
270
|
|
|
271
|
+
/**
|
|
272
|
+
* @param {*} cfgForm
|
|
273
|
+
* @param {*} req
|
|
274
|
+
* @returns {void}
|
|
275
|
+
*/
|
|
214
276
|
const flash_restart_if_required = (cfgForm, req) => {
|
|
215
277
|
let restart = false;
|
|
216
278
|
cfgForm.fields.forEach((f) => {
|
|
@@ -222,6 +284,10 @@ const flash_restart_if_required = (cfgForm, req) => {
|
|
|
222
284
|
if (restart) flash_restart(req);
|
|
223
285
|
};
|
|
224
286
|
|
|
287
|
+
/**
|
|
288
|
+
* @param {object} req
|
|
289
|
+
* @returns {void}
|
|
290
|
+
*/
|
|
225
291
|
const flash_restart = (req) => {
|
|
226
292
|
req.flash(
|
|
227
293
|
"warning",
|
|
@@ -231,6 +297,13 @@ const flash_restart = (req) => {
|
|
|
231
297
|
);
|
|
232
298
|
};
|
|
233
299
|
|
|
300
|
+
/**
|
|
301
|
+
* @param {object} opts
|
|
302
|
+
* @param {string[]} opts.field_names
|
|
303
|
+
* @param {object} opts.req
|
|
304
|
+
* @param {*} opts.formArgs
|
|
305
|
+
* @returns {Promise<Form>}
|
|
306
|
+
*/
|
|
234
307
|
const config_fields_form = async ({ field_names, req, ...formArgs }) => {
|
|
235
308
|
const values = {};
|
|
236
309
|
const state = getState();
|
|
@@ -243,6 +316,7 @@ const config_fields_form = async ({ field_names, req, ...formArgs }) => {
|
|
|
243
316
|
continue;
|
|
244
317
|
const isView = (configTypes[name].type || "").startsWith("View ");
|
|
245
318
|
const isRole = configTypes[name].type === "Role";
|
|
319
|
+
const isTenant = configTypes[name].type === "Tenant";
|
|
246
320
|
const label = configTypes[name].label || name;
|
|
247
321
|
const sublabel = configTypes[name].sublabel || configTypes[name].blurb;
|
|
248
322
|
const roleAttribs = {
|
|
@@ -251,6 +325,10 @@ const config_fields_form = async ({ field_names, req, ...formArgs }) => {
|
|
|
251
325
|
name: `${r.id}`,
|
|
252
326
|
})),
|
|
253
327
|
};
|
|
328
|
+
const getTenants = async () => {
|
|
329
|
+
const tens = await db.select("_sc_tenants");
|
|
330
|
+
return { options: tens.map((t) => t.subdomain) };
|
|
331
|
+
};
|
|
254
332
|
fields.push({
|
|
255
333
|
name,
|
|
256
334
|
...configTypes[name],
|
|
@@ -258,7 +336,7 @@ const config_fields_form = async ({ field_names, req, ...formArgs }) => {
|
|
|
258
336
|
sublabel: sublabel ? req.__(sublabel) : undefined,
|
|
259
337
|
disabled: isFixedConfig(name),
|
|
260
338
|
type:
|
|
261
|
-
isView || isRole
|
|
339
|
+
isView || isRole || isTenant
|
|
262
340
|
? "String"
|
|
263
341
|
: configTypes[name].input_type
|
|
264
342
|
? undefined
|
|
@@ -268,6 +346,8 @@ const config_fields_form = async ({ field_names, req, ...formArgs }) => {
|
|
|
268
346
|
? await viewAttributes(name)
|
|
269
347
|
: isRole
|
|
270
348
|
? roleAttribs
|
|
349
|
+
: isTenant
|
|
350
|
+
? await getTenants()
|
|
271
351
|
: configTypes[name].attributes,
|
|
272
352
|
});
|
|
273
353
|
}
|
|
@@ -282,6 +362,10 @@ const config_fields_form = async ({ field_names, req, ...formArgs }) => {
|
|
|
282
362
|
return form;
|
|
283
363
|
};
|
|
284
364
|
|
|
365
|
+
/**
|
|
366
|
+
* @param {*} form
|
|
367
|
+
* @returns {Promise<void>}
|
|
368
|
+
*/
|
|
285
369
|
const save_config_from_form = async (form) => {
|
|
286
370
|
const state = getState();
|
|
287
371
|
|
|
@@ -292,6 +376,9 @@ const save_config_from_form = async (form) => {
|
|
|
292
376
|
}
|
|
293
377
|
};
|
|
294
378
|
|
|
379
|
+
/**
|
|
380
|
+
* @returns {string}
|
|
381
|
+
*/
|
|
295
382
|
const getBaseDomain = () => {
|
|
296
383
|
const base_url = getState().getConfig("base_url");
|
|
297
384
|
if (!base_url) return null;
|
|
@@ -303,8 +390,17 @@ const getBaseDomain = () => {
|
|
|
303
390
|
return domain;
|
|
304
391
|
};
|
|
305
392
|
|
|
393
|
+
/**
|
|
394
|
+
* @param {object} req
|
|
395
|
+
* @param {string} domain
|
|
396
|
+
* @returns {boolean}
|
|
397
|
+
*/
|
|
306
398
|
const hostname_matches_baseurl = (req, domain) => domain === req.hostname;
|
|
307
399
|
|
|
400
|
+
/**
|
|
401
|
+
* @param {string} domain
|
|
402
|
+
* @returns {string[]}
|
|
403
|
+
*/
|
|
308
404
|
const is_hsts_tld = (domain) => {
|
|
309
405
|
if (!domain) return false;
|
|
310
406
|
const ds = domain.split(".");
|
package/markup/blockly.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @category server
|
|
3
|
+
* @module markup/blockly
|
|
4
|
+
* @subcategory markup
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
const {
|
|
2
8
|
div,
|
|
3
9
|
code,
|
|
@@ -9,6 +15,11 @@ const {
|
|
|
9
15
|
} = require("@saltcorn/markup/tags");
|
|
10
16
|
const db = require("@saltcorn/data/db");
|
|
11
17
|
|
|
18
|
+
/**
|
|
19
|
+
* @param {object} opts
|
|
20
|
+
* @param {string} opts.locale
|
|
21
|
+
* @returns {string}
|
|
22
|
+
*/
|
|
12
23
|
const blocklyImportScripts = ({ locale }) =>
|
|
13
24
|
script({
|
|
14
25
|
src: "/plugins/pubdeps/base/blockly/6.20210701.0/blockly_compressed.js",
|
|
@@ -26,6 +37,10 @@ const blocklyImportScripts = ({ locale }) =>
|
|
|
26
37
|
src: `/static_assets/${db.connectObj.version_tag}/blockly.js`,
|
|
27
38
|
});
|
|
28
39
|
|
|
40
|
+
/**
|
|
41
|
+
* @param {boolean} hasActions
|
|
42
|
+
* @returns {string}
|
|
43
|
+
*/
|
|
29
44
|
const blocklyToolbox = (hasActions) => `
|
|
30
45
|
<xml xmlns="https://developers.google.com/blockly/xml" id="toolbox" style="display: none">
|
|
31
46
|
<category name="Control Flow" categorystyle="loop_category">
|
|
@@ -1,7 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @category server
|
|
3
|
+
* @module markup/expression_blurb
|
|
4
|
+
* @subcategory markup
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
const { p, code, li, ul, pre } = require("@saltcorn/markup/tags");
|
|
2
8
|
const { contract, is } = require("contractis");
|
|
3
9
|
const { getState } = require("@saltcorn/data/db/state");
|
|
4
10
|
|
|
11
|
+
/**
|
|
12
|
+
* @param {*} type
|
|
13
|
+
* @returns {*}
|
|
14
|
+
*/
|
|
5
15
|
const toJsType = (type) =>
|
|
6
16
|
({
|
|
7
17
|
Integer: "number",
|
|
@@ -12,6 +22,11 @@ const toJsType = (type) =>
|
|
|
12
22
|
Color: "string",
|
|
13
23
|
}[type] || type);
|
|
14
24
|
|
|
25
|
+
/**
|
|
26
|
+
* @param {*} type
|
|
27
|
+
* @param {object[]} fields
|
|
28
|
+
* @returns {string[]}
|
|
29
|
+
*/
|
|
15
30
|
const intExamples = (type, fields) => {
|
|
16
31
|
const boolFields = fields.filter((f) => f.type && f.type.name === "Bool");
|
|
17
32
|
const intFields = fields.filter((f) => f.type && f.type.name === "Integer");
|
|
@@ -27,6 +42,11 @@ const intExamples = (type, fields) => {
|
|
|
27
42
|
return exs;
|
|
28
43
|
};
|
|
29
44
|
|
|
45
|
+
/**
|
|
46
|
+
* @param {*} type
|
|
47
|
+
* @param {object[]} fields
|
|
48
|
+
* @returns {string[]}
|
|
49
|
+
*/
|
|
30
50
|
const colorExamples = (type, fields) => {
|
|
31
51
|
const boolFields = fields.filter((f) => f.type && f.type.name === "Bool");
|
|
32
52
|
const exs = [`"#06ab6d1"`];
|
|
@@ -36,6 +56,12 @@ const colorExamples = (type, fields) => {
|
|
|
36
56
|
}
|
|
37
57
|
return exs;
|
|
38
58
|
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @param {*} type
|
|
62
|
+
* @param {object[]} fields
|
|
63
|
+
* @returns {string[]}
|
|
64
|
+
*/
|
|
39
65
|
const stringExamples = (type, fields) => {
|
|
40
66
|
const boolFields = fields.filter((f) => f.type && f.type.name === "Bool");
|
|
41
67
|
const strFields = fields.filter((f) => f.type && f.type.name === "String");
|
|
@@ -50,6 +76,12 @@ const stringExamples = (type, fields) => {
|
|
|
50
76
|
}
|
|
51
77
|
return exs;
|
|
52
78
|
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @param {*} type
|
|
82
|
+
* @param {object[]} fields
|
|
83
|
+
* @returns {string[]}
|
|
84
|
+
*/
|
|
53
85
|
const floatExamples = (type, fields) => {
|
|
54
86
|
const boolFields = fields.filter((f) => f.type && f.type.name === "Bool");
|
|
55
87
|
const numFields = fields.filter(
|
|
@@ -73,6 +105,12 @@ const floatExamples = (type, fields) => {
|
|
|
73
105
|
}
|
|
74
106
|
return exs;
|
|
75
107
|
};
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @param {*} type
|
|
111
|
+
* @param {object[]} fields
|
|
112
|
+
* @returns {string[]}
|
|
113
|
+
*/
|
|
76
114
|
const boolExamples = (type, fields) => {
|
|
77
115
|
const boolFields = fields.filter((f) => f.type && f.type.name === "Bool");
|
|
78
116
|
const numFields = fields.filter(
|
|
@@ -100,6 +138,13 @@ const boolExamples = (type, fields) => {
|
|
|
100
138
|
return exs;
|
|
101
139
|
};
|
|
102
140
|
|
|
141
|
+
/**
|
|
142
|
+
* @param {string} type
|
|
143
|
+
* @param {*} stored
|
|
144
|
+
* @param {object[]} allFields
|
|
145
|
+
* @param {object} req
|
|
146
|
+
* @returns {p[]}
|
|
147
|
+
*/
|
|
103
148
|
const expressionBlurb = (type, stored, allFields, req) => {
|
|
104
149
|
const fields = allFields.filter((f) => !f.is_fkey && !f.calculated);
|
|
105
150
|
const funs = getState().functions;
|
package/markup/forms.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @category server
|
|
3
|
+
* @module markup/forms
|
|
4
|
+
* @subcategory markup
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
const {
|
|
2
8
|
form,
|
|
3
9
|
select,
|
|
@@ -11,6 +17,14 @@ const {
|
|
|
11
17
|
} = require("@saltcorn/markup/tags");
|
|
12
18
|
const { csrfField } = require("../routes/utils");
|
|
13
19
|
|
|
20
|
+
/**
|
|
21
|
+
* @param {object} opts
|
|
22
|
+
* @param {string} opts.url
|
|
23
|
+
* @param {Role} opts.current_role
|
|
24
|
+
* @param {Role[]} opts.roles
|
|
25
|
+
* @param {object} opts.req
|
|
26
|
+
* @returns {Form}
|
|
27
|
+
*/
|
|
14
28
|
const editRoleForm = ({ url, current_role, roles, req }) =>
|
|
15
29
|
form(
|
|
16
30
|
{
|
|
@@ -32,6 +46,10 @@ const editRoleForm = ({ url, current_role, roles, req }) =>
|
|
|
32
46
|
)
|
|
33
47
|
);
|
|
34
48
|
|
|
49
|
+
/**
|
|
50
|
+
* @param {object} req
|
|
51
|
+
* @returns {Form}
|
|
52
|
+
*/
|
|
35
53
|
const fileUploadForm = (req) =>
|
|
36
54
|
form(
|
|
37
55
|
{
|
|
@@ -50,6 +68,12 @@ const fileUploadForm = (req) =>
|
|
|
50
68
|
})
|
|
51
69
|
);
|
|
52
70
|
|
|
71
|
+
/**
|
|
72
|
+
* @param {string} wizardTitle
|
|
73
|
+
* @param {*} wf
|
|
74
|
+
* @param {object} wfres
|
|
75
|
+
* @returns {string}
|
|
76
|
+
*/
|
|
53
77
|
const wizardCardTitle = (wizardTitle, wf, wfres) =>
|
|
54
78
|
`${wizardTitle}: ${wfres.stepName}`;
|
|
55
79
|
|
package/markup/index.js
ADDED
package/markup/plugin-store.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @category server
|
|
3
|
+
* @module markup/plugin-store
|
|
4
|
+
* @subcategory markup
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
const {
|
|
2
8
|
h5,
|
|
3
9
|
h4,
|
|
@@ -17,9 +23,20 @@ const {
|
|
|
17
23
|
strong,
|
|
18
24
|
} = require("@saltcorn/markup/tags");
|
|
19
25
|
const { link } = require("@saltcorn/markup");
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @param {object} args
|
|
29
|
+
* @returns {string}
|
|
30
|
+
*/
|
|
20
31
|
const show_function_arguments = (args) =>
|
|
21
32
|
(args || []).map(({ name, type }) => `${name}: ${type}`).join(", ");
|
|
22
33
|
|
|
34
|
+
/**
|
|
35
|
+
* @param {object} plugin
|
|
36
|
+
* @param {string} key
|
|
37
|
+
* @param {object} def
|
|
38
|
+
* @returns {*}
|
|
39
|
+
*/
|
|
23
40
|
const withCfg = (plugin, key, def) =>
|
|
24
41
|
plugin.plugin_module.configuration_workflow
|
|
25
42
|
? plugin.plugin_module[key]
|
|
@@ -27,6 +44,11 @@ const withCfg = (plugin, key, def) =>
|
|
|
27
44
|
: def
|
|
28
45
|
: plugin.plugin_module[key] || def;
|
|
29
46
|
|
|
47
|
+
/**
|
|
48
|
+
* @param {object} plugin
|
|
49
|
+
* @param {object} req
|
|
50
|
+
* @returns {*}
|
|
51
|
+
*/
|
|
30
52
|
const plugin_types_info_card = (plugin, req) => ({
|
|
31
53
|
type: "card",
|
|
32
54
|
title: req.__("Types"),
|
|
@@ -35,6 +57,11 @@ const plugin_types_info_card = (plugin, req) => ({
|
|
|
35
57
|
),
|
|
36
58
|
});
|
|
37
59
|
|
|
60
|
+
/**
|
|
61
|
+
* @param {object} plugin
|
|
62
|
+
* @param {object} req
|
|
63
|
+
* @returns {*}
|
|
64
|
+
*/
|
|
38
65
|
const plugin_functions_info_card = (plugin, req) => ({
|
|
39
66
|
type: "card",
|
|
40
67
|
title: req.__("Functions"),
|
|
@@ -53,6 +80,11 @@ const plugin_functions_info_card = (plugin, req) => ({
|
|
|
53
80
|
.join("<hr>"),
|
|
54
81
|
});
|
|
55
82
|
|
|
83
|
+
/**
|
|
84
|
+
* @param {object} plugin
|
|
85
|
+
* @param {object} req
|
|
86
|
+
* @returns {*}
|
|
87
|
+
*/
|
|
56
88
|
const plugin_viewtemplates_info_card = (plugin, req) => ({
|
|
57
89
|
type: "card",
|
|
58
90
|
title: req.__("View templates"),
|
|
@@ -61,6 +93,10 @@ const plugin_viewtemplates_info_card = (plugin, req) => ({
|
|
|
61
93
|
.join("<hr>"),
|
|
62
94
|
});
|
|
63
95
|
|
|
96
|
+
/**
|
|
97
|
+
* @param {object} repo
|
|
98
|
+
* @returns {*}
|
|
99
|
+
*/
|
|
64
100
|
const showRepository = (repo) =>
|
|
65
101
|
!repo
|
|
66
102
|
? repo
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saltcorn/server",
|
|
3
|
-
"version": "0.6.1
|
|
3
|
+
"version": "0.6.1",
|
|
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.1
|
|
10
|
-
"@saltcorn/builder": "0.6.1
|
|
11
|
-
"@saltcorn/data": "0.6.1
|
|
9
|
+
"@saltcorn/base-plugin": "0.6.1",
|
|
10
|
+
"@saltcorn/builder": "0.6.1",
|
|
11
|
+
"@saltcorn/data": "0.6.1",
|
|
12
12
|
"greenlock-express": "^4.0.3",
|
|
13
|
-
"@saltcorn/markup": "0.6.1
|
|
14
|
-
"@saltcorn/sbadmin2": "0.6.1
|
|
13
|
+
"@saltcorn/markup": "0.6.1",
|
|
14
|
+
"@saltcorn/sbadmin2": "0.6.1",
|
|
15
15
|
"@socket.io/cluster-adapter": "^0.1.0",
|
|
16
16
|
"@socket.io/sticky": "^1.0.1",
|
|
17
17
|
"connect-flash": "^0.1.1",
|
package/public/saltcorn.js
CHANGED
|
@@ -341,7 +341,11 @@ function pjax_to(href) {
|
|
|
341
341
|
setTimeout(() => {
|
|
342
342
|
loadPage = true;
|
|
343
343
|
}, 0);
|
|
344
|
-
|
|
344
|
+
if (res.includes("<!--SCPT:")) {
|
|
345
|
+
const start = res.indexOf("<!--SCPT:");
|
|
346
|
+
const end = res.indexOf("-->", start);
|
|
347
|
+
document.title = res.substring(start + 9, end);
|
|
348
|
+
}
|
|
345
349
|
$("#page-inner-content").html(res);
|
|
346
350
|
initialize_page();
|
|
347
351
|
},
|
package/routes/actions.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Actions (Triggers) Handler
|
|
3
|
-
*
|
|
3
|
+
* @category server
|
|
4
|
+
* @module routes/actions
|
|
5
|
+
* @subcategory routes
|
|
4
6
|
*/
|
|
5
7
|
const Router = require("express-promise-router");
|
|
6
8
|
const {
|
|
@@ -12,6 +14,13 @@ const {
|
|
|
12
14
|
const { getState } = require("@saltcorn/data/db/state");
|
|
13
15
|
const Trigger = require("@saltcorn/data/models/trigger");
|
|
14
16
|
|
|
17
|
+
/**
|
|
18
|
+
* @type {object}
|
|
19
|
+
* @const
|
|
20
|
+
* @namespace actionsRouter
|
|
21
|
+
* @category server
|
|
22
|
+
* @subcategory routes
|
|
23
|
+
*/
|
|
15
24
|
const router = new Router();
|
|
16
25
|
module.exports = router;
|
|
17
26
|
const {
|
|
@@ -55,6 +64,9 @@ const {
|
|
|
55
64
|
blocklyToolbox,
|
|
56
65
|
} = require("../markup/blockly.js");
|
|
57
66
|
|
|
67
|
+
/**
|
|
68
|
+
* @returns {Promise<object>}
|
|
69
|
+
*/
|
|
58
70
|
const getActions = async () => {
|
|
59
71
|
return Object.entries(getState().actions).map(([k, v]) => {
|
|
60
72
|
const hasConfig = !!v.configFields;
|
|
@@ -66,8 +78,12 @@ const getActions = async () => {
|
|
|
66
78
|
};
|
|
67
79
|
});
|
|
68
80
|
};
|
|
81
|
+
|
|
69
82
|
/**
|
|
70
83
|
* Show list of Actions (Triggers) (HTTP GET)
|
|
84
|
+
* @name get
|
|
85
|
+
* @function
|
|
86
|
+
* @memberof module:routes/actions~actionsRouter
|
|
71
87
|
*/
|
|
72
88
|
router.get(
|
|
73
89
|
"/",
|
|
@@ -263,8 +279,12 @@ const triggerForm = async (req, trigger) => {
|
|
|
263
279
|
// }
|
|
264
280
|
return form;
|
|
265
281
|
};
|
|
282
|
+
|
|
266
283
|
/**
|
|
267
284
|
* Show form to create new Trigger (get)
|
|
285
|
+
* @name get/new
|
|
286
|
+
* @function
|
|
287
|
+
* @memberof module:routes/actions~actionsRouter
|
|
268
288
|
*/
|
|
269
289
|
router.get(
|
|
270
290
|
"/new",
|
|
@@ -285,8 +305,12 @@ router.get(
|
|
|
285
305
|
});
|
|
286
306
|
})
|
|
287
307
|
);
|
|
308
|
+
|
|
288
309
|
/**
|
|
289
310
|
* Show form to Edit existing Trigger (get)
|
|
311
|
+
* @name get/edit/:id
|
|
312
|
+
* @function
|
|
313
|
+
* @memberof module:routes/actions~actionsRouter
|
|
290
314
|
*/
|
|
291
315
|
router.get(
|
|
292
316
|
"/edit/:id",
|
|
@@ -311,8 +335,12 @@ router.get(
|
|
|
311
335
|
});
|
|
312
336
|
})
|
|
313
337
|
);
|
|
338
|
+
|
|
314
339
|
/**
|
|
315
340
|
* POST for new or existing trigger (Save trigger)
|
|
341
|
+
* @name post/new
|
|
342
|
+
* @function
|
|
343
|
+
* @memberof module:routes/actions~actionsRouter
|
|
316
344
|
*/
|
|
317
345
|
router.post(
|
|
318
346
|
"/new",
|
|
@@ -347,8 +375,12 @@ router.post(
|
|
|
347
375
|
}
|
|
348
376
|
})
|
|
349
377
|
);
|
|
378
|
+
|
|
350
379
|
/**
|
|
351
380
|
* POST for existing trigger (Save trigger)
|
|
381
|
+
* @name /edit/:id
|
|
382
|
+
* @function
|
|
383
|
+
* @memberof module:routes/actions~actionsRouter
|
|
352
384
|
*/
|
|
353
385
|
router.post(
|
|
354
386
|
"/edit/:id",
|
|
@@ -381,6 +413,7 @@ router.post(
|
|
|
381
413
|
}
|
|
382
414
|
})
|
|
383
415
|
);
|
|
416
|
+
|
|
384
417
|
/**
|
|
385
418
|
* Edit Trigger configuration (GET)
|
|
386
419
|
*
|
|
@@ -388,6 +421,9 @@ router.post(
|
|
|
388
421
|
*
|
|
389
422
|
* - get configuration fields
|
|
390
423
|
* - create form
|
|
424
|
+
* @name get/configure/:id
|
|
425
|
+
* @function
|
|
426
|
+
* @memberof module:routes/actions~actionsRouter
|
|
391
427
|
*/
|
|
392
428
|
router.get(
|
|
393
429
|
"/configure/:id",
|
|
@@ -498,8 +534,12 @@ router.get(
|
|
|
498
534
|
}
|
|
499
535
|
})
|
|
500
536
|
);
|
|
537
|
+
|
|
501
538
|
/**
|
|
502
539
|
* Configure Trigger (POST)
|
|
540
|
+
* @name post/configure/:id
|
|
541
|
+
* @function
|
|
542
|
+
* @memberof module:routes/actions~actionsRouter
|
|
503
543
|
*/
|
|
504
544
|
router.post(
|
|
505
545
|
"/configure/:id",
|
|
@@ -537,6 +577,12 @@ router.post(
|
|
|
537
577
|
}
|
|
538
578
|
})
|
|
539
579
|
);
|
|
580
|
+
|
|
581
|
+
/**
|
|
582
|
+
* @name post/delete/:id
|
|
583
|
+
* @function
|
|
584
|
+
* @memberof module:routes/actions~actionsRouter
|
|
585
|
+
*/
|
|
540
586
|
router.post(
|
|
541
587
|
"/delete/:id",
|
|
542
588
|
setTenant,
|
|
@@ -548,6 +594,12 @@ router.post(
|
|
|
548
594
|
res.redirect(`/actions/`);
|
|
549
595
|
})
|
|
550
596
|
);
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* @name get/testrun/:id
|
|
600
|
+
* @function
|
|
601
|
+
* @memberof module:routes/actions~actionsRouter
|
|
602
|
+
*/
|
|
551
603
|
router.get(
|
|
552
604
|
"/testrun/:id",
|
|
553
605
|
setTenant,
|