@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/db/connect.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Controls Saltcorn configuration
|
|
3
|
-
* @
|
|
3
|
+
* @category saltcorn-data
|
|
4
|
+
* @module db/connect
|
|
5
|
+
* @subcategory db
|
|
4
6
|
*/
|
|
7
|
+
|
|
5
8
|
const path = require("path");
|
|
6
9
|
const fs = require("fs");
|
|
7
10
|
const envPaths = require("env-paths");
|
|
@@ -13,13 +16,18 @@ const pathsWithApp = envPaths("saltcorn", { suffix: "" });
|
|
|
13
16
|
* @type {string}
|
|
14
17
|
*/
|
|
15
18
|
const defaultDataPath = pathsWithApp.data;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {string|object} x
|
|
22
|
+
* @returns {object}
|
|
23
|
+
*/
|
|
16
24
|
const stringToJSON = (x) => (typeof x === "string" ? JSON.parse(x) : x);
|
|
17
25
|
/**
|
|
18
26
|
* Get Git revision of Saltcorn source.
|
|
19
27
|
* Required to work:
|
|
20
28
|
* - Git client installed,
|
|
21
29
|
* - Local git with repo Saltcorn sources.
|
|
22
|
-
* @returns {
|
|
30
|
+
* @returns {string} - Return current Git commit
|
|
23
31
|
*/
|
|
24
32
|
const getGitRevision = () => {
|
|
25
33
|
let revision = null;
|
|
@@ -41,8 +49,8 @@ const getGitRevision = () => {
|
|
|
41
49
|
* - File store path
|
|
42
50
|
* - Saltcorn confuration inheritance and fixed configuration
|
|
43
51
|
* For all parameters and priority see the code of function.
|
|
44
|
-
* @param connSpec
|
|
45
|
-
* @returns {
|
|
52
|
+
* @param {object} [connSpec = {}]
|
|
53
|
+
* @returns {object|boolean}
|
|
46
54
|
*/
|
|
47
55
|
const getConnectObject = (connSpec = {}) => {
|
|
48
56
|
const git_commit = getGitRevision();
|
|
@@ -123,7 +131,7 @@ const getConfigFile = () => {
|
|
|
123
131
|
};
|
|
124
132
|
/**
|
|
125
133
|
* Check that Saltcorn configured to use SQLite as database
|
|
126
|
-
* @param connObj - connectin object
|
|
134
|
+
* @param {object} connObj - connectin object
|
|
127
135
|
* @returns {boolean} - Returns true if Saltcorn configured to use SQLite as database
|
|
128
136
|
*/
|
|
129
137
|
const is_sqlite = (connObj) => {
|
package/db/db.test.js
CHANGED
|
@@ -1,162 +1,8 @@
|
|
|
1
|
-
const { sqlsanitize, mkWhere, sqlsanitizeAllowDots } = require("./internal");
|
|
2
1
|
const db = require("./index.js");
|
|
3
2
|
const Table = require("../models/table");
|
|
4
3
|
|
|
5
4
|
afterAll(db.close);
|
|
6
5
|
|
|
7
|
-
describe("sqlsanitize", () => {
|
|
8
|
-
it("should not alter valid name", () => {
|
|
9
|
-
expect(sqlsanitize("ffoo_oo")).toBe("ffoo_oo");
|
|
10
|
-
});
|
|
11
|
-
it("should remove spaces", () => {
|
|
12
|
-
expect(sqlsanitize(" ")).toBe("");
|
|
13
|
-
});
|
|
14
|
-
it("should remove chars from invalid name", () => {
|
|
15
|
-
expect(sqlsanitize("ffoo--oo--uu")).toBe("ffoooouu");
|
|
16
|
-
});
|
|
17
|
-
it("should not allow dots", () => {
|
|
18
|
-
expect(sqlsanitize("ffoo.oo")).toBe("ffoooo");
|
|
19
|
-
});
|
|
20
|
-
it("should allow dots when specified", () => {
|
|
21
|
-
expect(sqlsanitizeAllowDots("ffoo.oo")).toBe("ffoo.oo");
|
|
22
|
-
});
|
|
23
|
-
it("should allow quotes when dots specified", () => {
|
|
24
|
-
expect(sqlsanitizeAllowDots('ffoo."oo"')).toBe('ffoo."oo"');
|
|
25
|
-
});
|
|
26
|
-
it("should allow numbers", () => {
|
|
27
|
-
expect(sqlsanitize("ff1oo_oo")).toBe("ff1oo_oo");
|
|
28
|
-
});
|
|
29
|
-
it("should not allow numbers in initial position", () => {
|
|
30
|
-
expect(sqlsanitize("1ffoo_o1o")).toBe("_1ffoo_o1o");
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
describe("mkWhere", () => {
|
|
35
|
-
it("should empty on no arg", () => {
|
|
36
|
-
expect(mkWhere()).toStrictEqual({ values: [], where: "" });
|
|
37
|
-
});
|
|
38
|
-
it("should empty on null obj arg", () => {
|
|
39
|
-
expect(mkWhere({})).toStrictEqual({ values: [], where: "" });
|
|
40
|
-
});
|
|
41
|
-
it("should query json", () => {
|
|
42
|
-
expect(mkWhere({ foo: { json: ["bar", 5] } })).toStrictEqual({
|
|
43
|
-
values: [5],
|
|
44
|
-
where: `where "foo"->>'bar'=$1`,
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it("should set id", () => {
|
|
49
|
-
expect(mkWhere({ id: 5 })).toStrictEqual({
|
|
50
|
-
values: [5],
|
|
51
|
-
where: 'where "id"=$1',
|
|
52
|
-
});
|
|
53
|
-
expect(mkWhere({ id: 5, hello: "world" })).toStrictEqual({
|
|
54
|
-
values: [5, "world"],
|
|
55
|
-
where: 'where "id"=$1 and "hello"=$2',
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
it("should query null", () => {
|
|
59
|
-
expect(mkWhere({ id: null })).toStrictEqual({
|
|
60
|
-
values: [],
|
|
61
|
-
where: 'where "id" is null',
|
|
62
|
-
});
|
|
63
|
-
expect(mkWhere({ id: null, foo: 1 })).toStrictEqual({
|
|
64
|
-
values: [1],
|
|
65
|
-
where: 'where "id" is null and "foo"=$1',
|
|
66
|
-
});
|
|
67
|
-
expect(mkWhere({ foo: 1, id: null })).toStrictEqual({
|
|
68
|
-
values: [1],
|
|
69
|
-
where: 'where "foo"=$1 and "id" is null',
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
it("should query lt/gt", () => {
|
|
73
|
-
expect(mkWhere({ id: { lt: 5 } })).toStrictEqual({
|
|
74
|
-
values: [5],
|
|
75
|
-
where: 'where "id"<$1',
|
|
76
|
-
});
|
|
77
|
-
expect(mkWhere({ id: { gt: 8 } })).toStrictEqual({
|
|
78
|
-
values: [8],
|
|
79
|
-
where: 'where "id">$1',
|
|
80
|
-
});
|
|
81
|
-
expect(mkWhere({ id: { lt: 5, equal: true } })).toStrictEqual({
|
|
82
|
-
values: [5],
|
|
83
|
-
where: 'where "id"<=$1',
|
|
84
|
-
});
|
|
85
|
-
expect(mkWhere({ id: { gt: 8, equal: true } })).toStrictEqual({
|
|
86
|
-
values: [8],
|
|
87
|
-
where: 'where "id">=$1',
|
|
88
|
-
});
|
|
89
|
-
expect(mkWhere({ id: [{ gt: 0 }, { lt: 10 }] })).toStrictEqual({
|
|
90
|
-
values: [0, 10],
|
|
91
|
-
where: 'where "id">$1 and "id"<$2',
|
|
92
|
-
});
|
|
93
|
-
expect(mkWhere({ id: { or: [{ gt: 10 }, { lt: 5 }] } })).toStrictEqual({
|
|
94
|
-
values: [10, 5],
|
|
95
|
-
where: 'where ("id">$1 or "id"<$2)',
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
it("should query subselect", () => {
|
|
99
|
-
expect(
|
|
100
|
-
mkWhere({
|
|
101
|
-
id: [{ inSelect: { table: "foo", field: "bar", where: { baz: 7 } } }],
|
|
102
|
-
})
|
|
103
|
-
).toStrictEqual({
|
|
104
|
-
values: [7],
|
|
105
|
-
where: 'where "id" in (select bar from foo where "baz"=$1)',
|
|
106
|
-
});
|
|
107
|
-
expect(
|
|
108
|
-
mkWhere({
|
|
109
|
-
age: 45,
|
|
110
|
-
id: [{ inSelect: { table: "foo", field: "bar", where: { baz: 7 } } }],
|
|
111
|
-
name: "Alice",
|
|
112
|
-
})
|
|
113
|
-
).toStrictEqual({
|
|
114
|
-
values: [45, 7, "Alice"],
|
|
115
|
-
where: `where "age"=$1 and "id" in (select bar from foo where "baz"=$2) and "name"=$3`,
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
it("should query or", () => {
|
|
119
|
-
expect(mkWhere({ or: [{ id: 5 }, { x: 7 }] })).toStrictEqual({
|
|
120
|
-
values: [5, 7],
|
|
121
|
-
where: 'where ("id"=$1 or "x"=$2)',
|
|
122
|
-
});
|
|
123
|
-
expect(mkWhere({ or: [{ id: 5 }, { x: { gt: 7 } }] })).toStrictEqual({
|
|
124
|
-
values: [5, 7],
|
|
125
|
-
where: 'where ("id"=$1 or "x">$2)',
|
|
126
|
-
});
|
|
127
|
-
expect(mkWhere({ or: [{ id: 5 }, { x: 7, y: 8 }] })).toStrictEqual({
|
|
128
|
-
values: [5, 7, 8],
|
|
129
|
-
where: 'where ("id"=$1 or "x"=$2 and "y"=$3)',
|
|
130
|
-
});
|
|
131
|
-
expect(mkWhere({ not: { id: 5 } })).toStrictEqual({
|
|
132
|
-
values: [5],
|
|
133
|
-
where: 'where not ("id"=$1)',
|
|
134
|
-
});
|
|
135
|
-
expect(mkWhere({ not: { id: 5, y: 1 } })).toStrictEqual({
|
|
136
|
-
values: [5, 1],
|
|
137
|
-
where: 'where not ("id"=$1 and "y"=$2)',
|
|
138
|
-
});
|
|
139
|
-
expect(mkWhere({ not: { y: { in: [1, 2, 3] } } })).toStrictEqual({
|
|
140
|
-
values: [[1, 2, 3]],
|
|
141
|
-
where: 'where not ("y" = ANY ($1))',
|
|
142
|
-
});
|
|
143
|
-
expect(mkWhere({ y: { in: [1, 2, 3] } })).toStrictEqual({
|
|
144
|
-
values: [[1, 2, 3]],
|
|
145
|
-
where: 'where "y" = ANY ($1)',
|
|
146
|
-
});
|
|
147
|
-
/*
|
|
148
|
-
TODO
|
|
149
|
-
expect(mkWhere([{ id: 5 }, { x: 7 }])).toStrictEqual({
|
|
150
|
-
values: [5, 7],
|
|
151
|
-
where: 'where "id"=$1 and "x"=$2',
|
|
152
|
-
});
|
|
153
|
-
expect(mkWhere([{ or: [{ id: 5 }, { x: 7 }] }, { z: 9 }])).toStrictEqual({
|
|
154
|
-
values: [5, 7, 9],
|
|
155
|
-
where: 'where ("id"=$1 or "x"=$2) and "z"=$3',
|
|
156
|
-
});*/
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
|
|
160
6
|
describe("where", () => {
|
|
161
7
|
it("should support in", async () => {
|
|
162
8
|
await Table.create("myothertable");
|
package/db/fixtures.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* init fixtures
|
|
3
|
+
* @category saltcorn-data
|
|
4
|
+
* @module db/fixtures
|
|
5
|
+
* @subcategory db
|
|
6
|
+
*/
|
|
1
7
|
const db = require(".");
|
|
2
8
|
const { getState } = require("./state");
|
|
3
9
|
const Table = require("../models/table");
|
|
@@ -8,7 +14,13 @@ const User = require("../models/user");
|
|
|
8
14
|
const Page = require("../models/page");
|
|
9
15
|
const fs = require("fs").promises;
|
|
10
16
|
|
|
11
|
-
module.exports =
|
|
17
|
+
module.exports =
|
|
18
|
+
/**
|
|
19
|
+
* @function
|
|
20
|
+
* @name "module.exports function"
|
|
21
|
+
* @returns {Promise<void>}
|
|
22
|
+
*/
|
|
23
|
+
async () => {
|
|
12
24
|
getState().registerPlugin("base", require("../base-plugin"));
|
|
13
25
|
const table = await Table.create("books", {
|
|
14
26
|
min_role_read: 10,
|
package/db/index.js
CHANGED
|
@@ -1,21 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* init fixtures
|
|
3
|
+
* @category saltcorn-data
|
|
4
|
+
* @module db/index
|
|
5
|
+
* @subcategory db
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* All files in the db module.
|
|
10
|
+
* @namespace db_overview
|
|
11
|
+
* @property {module:db/connect} connect
|
|
12
|
+
* @property {module:db/fixtures} fixtures
|
|
13
|
+
* @property {module:db/reset_schema} reset_schema
|
|
14
|
+
* @property {module:db/state} state
|
|
15
|
+
* @property {module:db/connect} connect
|
|
16
|
+
*
|
|
17
|
+
* @category saltcorn-data
|
|
18
|
+
* @subcategory db
|
|
19
|
+
*/
|
|
1
20
|
const { getConnectObject, is_sqlite } = require("./connect");
|
|
2
|
-
const { sqlsanitize, mkWhere } = require("
|
|
21
|
+
const { sqlsanitize, mkWhere } = require("@saltcorn/db-common/internal");
|
|
3
22
|
var connectObj = getConnectObject();
|
|
4
23
|
|
|
5
|
-
|
|
24
|
+
/** @type {db/sqlite|db/pg|null} */
|
|
25
|
+
let dbmodule = null;
|
|
26
|
+
try {
|
|
27
|
+
dbmodule = is_sqlite(connectObj) ?
|
|
28
|
+
require("@saltcorn/sqlite/sqlite")(getConnectObject) :
|
|
29
|
+
require("@saltcorn/postgres/postgres")(getConnectObject);
|
|
30
|
+
} catch(e) {
|
|
31
|
+
console.log("No database package found.")
|
|
32
|
+
throw e;
|
|
33
|
+
}
|
|
6
34
|
|
|
7
|
-
|
|
35
|
+
/** @type {db/tenant} */
|
|
36
|
+
const tenant = require("@saltcorn/db-common/tenants")(getConnectObject());
|
|
8
37
|
|
|
38
|
+
/** @type {boolean} */
|
|
9
39
|
const isSQLite = is_sqlite(connectObj);
|
|
10
40
|
|
|
41
|
+
/**
|
|
42
|
+
* @returns {string}
|
|
43
|
+
*/
|
|
11
44
|
const getTenantSchemaPrefix = () =>
|
|
12
45
|
isSQLite ? "" : `"${tenant.getTenantSchema()}".`;
|
|
46
|
+
|
|
13
47
|
module.exports = {
|
|
14
48
|
...tenant,
|
|
15
49
|
sqlsanitize,
|
|
16
50
|
connectObj,
|
|
17
51
|
isSQLite,
|
|
18
52
|
...dbmodule,
|
|
53
|
+
/**
|
|
54
|
+
* @param {object} q
|
|
55
|
+
* @returns {function}
|
|
56
|
+
*/
|
|
19
57
|
mkWhere: (q) => mkWhere(q, isSQLite),
|
|
20
58
|
getTenantSchemaPrefix,
|
|
21
59
|
};
|
|
60
|
+
|
package/db/reset_schema.js
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @category saltcorn-data
|
|
3
|
+
* @module db/reset_schema
|
|
4
|
+
* @subcategory db
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
//https://stackoverflow.com/a/21247009
|
|
8
|
+
/**
|
|
9
|
+
* @param {boolean} dontDrop
|
|
10
|
+
* @param {string} schema0
|
|
11
|
+
* @returns {Promise<void>}
|
|
12
|
+
*/
|
|
2
13
|
const reset = async (dontDrop = false, schema0) => {
|
|
3
14
|
const db = require(".");
|
|
4
15
|
const { migrate } = require("../migrate");
|
package/db/state.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* State of Saltcorn
|
|
3
3
|
* Keeps cache for main objects
|
|
4
|
+
* @category saltcorn-data
|
|
5
|
+
* @module db/state
|
|
6
|
+
* @subcategory db
|
|
4
7
|
*/
|
|
5
|
-
|
|
6
8
|
const { contract, is } = require("contractis");
|
|
7
9
|
const {
|
|
8
10
|
is_plugin_wrap,
|
|
@@ -19,7 +21,11 @@ const { migrate } = require("../migrate");
|
|
|
19
21
|
const File = require("../models/file");
|
|
20
22
|
const Trigger = require("../models/trigger");
|
|
21
23
|
const View = require("../models/view");
|
|
22
|
-
const {
|
|
24
|
+
const {
|
|
25
|
+
getAllTenants,
|
|
26
|
+
createTenant,
|
|
27
|
+
copy_tenant_template,
|
|
28
|
+
} = require("../models/tenant");
|
|
23
29
|
const {
|
|
24
30
|
getAllConfigOrDefaults,
|
|
25
31
|
setConfig,
|
|
@@ -32,14 +38,23 @@ const { I18n } = require("i18n");
|
|
|
32
38
|
const path = require("path");
|
|
33
39
|
const fs = require("fs");
|
|
34
40
|
|
|
41
|
+
/**
|
|
42
|
+
* @param {object} v
|
|
43
|
+
* @returns {void}
|
|
44
|
+
*/
|
|
35
45
|
const process_send = (v) => {
|
|
36
46
|
if (process.send) process.send(v);
|
|
37
47
|
};
|
|
38
48
|
|
|
39
49
|
/**
|
|
40
|
-
* State
|
|
50
|
+
* State Class
|
|
51
|
+
* @category saltcorn-data
|
|
41
52
|
*/
|
|
42
53
|
class State {
|
|
54
|
+
/**
|
|
55
|
+
* State constructor
|
|
56
|
+
* @param {string} tenant description
|
|
57
|
+
*/
|
|
43
58
|
constructor(tenant) {
|
|
44
59
|
this.tenant = tenant;
|
|
45
60
|
this.views = [];
|
|
@@ -78,8 +93,8 @@ class State {
|
|
|
78
93
|
/**
|
|
79
94
|
* Get Layout by user
|
|
80
95
|
* Based on role of user
|
|
81
|
-
* @param user
|
|
82
|
-
* @returns {
|
|
96
|
+
* @param {object} user
|
|
97
|
+
* @returns {object}
|
|
83
98
|
*/
|
|
84
99
|
getLayout(user) {
|
|
85
100
|
const role_id = user ? +user.role_id : 10;
|
|
@@ -94,6 +109,7 @@ class State {
|
|
|
94
109
|
|
|
95
110
|
/**
|
|
96
111
|
* Refresh State cache for all Saltcorn main objects
|
|
112
|
+
* @param {boolean} noSignal
|
|
97
113
|
* @returns {Promise<void>}
|
|
98
114
|
*/
|
|
99
115
|
async refresh(noSignal) {
|
|
@@ -104,8 +120,10 @@ class State {
|
|
|
104
120
|
await this.refresh_pages(noSignal);
|
|
105
121
|
await this.refresh_config(noSignal);
|
|
106
122
|
}
|
|
123
|
+
|
|
107
124
|
/**
|
|
108
125
|
* Refresh config
|
|
126
|
+
* @param {boolean} noSignal
|
|
109
127
|
* @returns {Promise<void>}
|
|
110
128
|
*/
|
|
111
129
|
async refresh_config(noSignal) {
|
|
@@ -117,6 +135,10 @@ class State {
|
|
|
117
135
|
if (!noSignal)
|
|
118
136
|
process_send({ refresh: "config", tenant: db.getTenantSchema() });
|
|
119
137
|
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* @returns {Promise<void>}
|
|
141
|
+
*/
|
|
120
142
|
async refresh_i18n() {
|
|
121
143
|
const localeDir = path.join(__dirname, "..", "app-locales", this.tenant);
|
|
122
144
|
try {
|
|
@@ -144,6 +166,7 @@ class State {
|
|
|
144
166
|
|
|
145
167
|
/**
|
|
146
168
|
* Refresh views
|
|
169
|
+
* @param {boolean} noSignal
|
|
147
170
|
* @returns {Promise<void>}
|
|
148
171
|
*/
|
|
149
172
|
async refresh_views(noSignal) {
|
|
@@ -166,6 +189,7 @@ class State {
|
|
|
166
189
|
|
|
167
190
|
/**
|
|
168
191
|
* Refresh triggers
|
|
192
|
+
* @param {boolean} noSignal
|
|
169
193
|
* @returns {Promise<void>}
|
|
170
194
|
*/
|
|
171
195
|
async refresh_triggers(noSignal) {
|
|
@@ -176,6 +200,7 @@ class State {
|
|
|
176
200
|
|
|
177
201
|
/**
|
|
178
202
|
* Refresh pages
|
|
203
|
+
* @param {boolean} noSignal
|
|
179
204
|
* @returns {Promise<void>}
|
|
180
205
|
*/
|
|
181
206
|
async refresh_pages(noSignal) {
|
|
@@ -187,6 +212,7 @@ class State {
|
|
|
187
212
|
|
|
188
213
|
/**
|
|
189
214
|
* Refresh files
|
|
215
|
+
* @param {boolean} noSignal
|
|
190
216
|
* @returns {Promise<void>}
|
|
191
217
|
*/
|
|
192
218
|
// todo what will be if there are a lot of files? Yes, there are cache only ids of files.
|
|
@@ -202,6 +228,7 @@ class State {
|
|
|
202
228
|
|
|
203
229
|
/**
|
|
204
230
|
* Refresh tables & fields
|
|
231
|
+
* @param {boolean} noSignal
|
|
205
232
|
* @returns {Promise<void>}
|
|
206
233
|
*/
|
|
207
234
|
async refresh_tables(noSignal) {
|
|
@@ -244,9 +271,9 @@ class State {
|
|
|
244
271
|
|
|
245
272
|
/**
|
|
246
273
|
* Get config parameter by key
|
|
247
|
-
* @param key - key of config paramter
|
|
248
|
-
* @param def - default value
|
|
249
|
-
* @returns {
|
|
274
|
+
* @param {string} key - key of config paramter
|
|
275
|
+
* @param {string} [def] - default value
|
|
276
|
+
* @returns {string}
|
|
250
277
|
*/
|
|
251
278
|
getConfig(key, def) {
|
|
252
279
|
const fixed = db.connectObj.fixed_configuration[key];
|
|
@@ -264,9 +291,9 @@ class State {
|
|
|
264
291
|
|
|
265
292
|
/**
|
|
266
293
|
* Get copy of config parameter
|
|
267
|
-
* @param key - key of parameter
|
|
268
|
-
* @param def - default value
|
|
269
|
-
* @returns {
|
|
294
|
+
* @param {sring} key - key of parameter
|
|
295
|
+
* @param {string} [def] - default value
|
|
296
|
+
* @returns {string}
|
|
270
297
|
*/
|
|
271
298
|
getConfigCopy(key, def) {
|
|
272
299
|
return structuredClone(this.getConfig(key, def));
|
|
@@ -275,8 +302,8 @@ class State {
|
|
|
275
302
|
/**
|
|
276
303
|
*
|
|
277
304
|
* Set value of config parameter
|
|
278
|
-
* @param key - key of parameter
|
|
279
|
-
* @param value - value of parameter
|
|
305
|
+
* @param {string} key - key of parameter
|
|
306
|
+
* @param {string} value - value of parameter
|
|
280
307
|
* @returns {Promise<void>}
|
|
281
308
|
*/
|
|
282
309
|
async setConfig(key, value) {
|
|
@@ -294,7 +321,7 @@ class State {
|
|
|
294
321
|
|
|
295
322
|
/**
|
|
296
323
|
* Delete config parameter by key
|
|
297
|
-
* @param key - key of parameter
|
|
324
|
+
* @param {string} key - key of parameter
|
|
298
325
|
* @returns {Promise<void>}
|
|
299
326
|
*/
|
|
300
327
|
async deleteConfig(...keys) {
|
|
@@ -306,11 +333,13 @@ class State {
|
|
|
306
333
|
}
|
|
307
334
|
|
|
308
335
|
/**
|
|
309
|
-
*
|
|
310
|
-
* @param name
|
|
311
|
-
* @param plugin
|
|
312
|
-
* @param cfg
|
|
313
|
-
* @param location
|
|
336
|
+
* Register plugin
|
|
337
|
+
* @param {string} name
|
|
338
|
+
* @param {object} plugin
|
|
339
|
+
* @param {*} cfg
|
|
340
|
+
* @param {*} location
|
|
341
|
+
* @param {string} modname
|
|
342
|
+
* @returns {void}
|
|
314
343
|
*/
|
|
315
344
|
registerPlugin(name, plugin, cfg, location, modname) {
|
|
316
345
|
this.plugins[name] = plugin;
|
|
@@ -381,7 +410,7 @@ class State {
|
|
|
381
410
|
|
|
382
411
|
/**
|
|
383
412
|
* Get type names
|
|
384
|
-
* @
|
|
413
|
+
* @type {string[]}
|
|
385
414
|
*/
|
|
386
415
|
get type_names() {
|
|
387
416
|
return Object.keys(this.types);
|
|
@@ -389,7 +418,7 @@ class State {
|
|
|
389
418
|
|
|
390
419
|
/**
|
|
391
420
|
* Add type
|
|
392
|
-
* @param t
|
|
421
|
+
* @param {object} t
|
|
393
422
|
*/
|
|
394
423
|
addType(t) {
|
|
395
424
|
this.types[t.name] = {
|
|
@@ -403,7 +432,8 @@ class State {
|
|
|
403
432
|
|
|
404
433
|
/**
|
|
405
434
|
* Remove plugin
|
|
406
|
-
* @param name
|
|
435
|
+
* @param {string} name
|
|
436
|
+
* @param {boolean} noSignal
|
|
407
437
|
* @returns {Promise<void>}
|
|
408
438
|
*/
|
|
409
439
|
async remove_plugin(name, noSignal) {
|
|
@@ -415,6 +445,7 @@ class State {
|
|
|
415
445
|
|
|
416
446
|
/**
|
|
417
447
|
* Reload plugins
|
|
448
|
+
* @param {boolean} noSignal
|
|
418
449
|
* @returns {Promise<void>}
|
|
419
450
|
*/
|
|
420
451
|
async refresh_plugins(noSignal) {
|
|
@@ -441,6 +472,9 @@ class State {
|
|
|
441
472
|
process_send({ refresh: "plugins", tenant: db.getTenantSchema() });
|
|
442
473
|
}
|
|
443
474
|
|
|
475
|
+
/**
|
|
476
|
+
* @returns {string[]}
|
|
477
|
+
*/
|
|
444
478
|
getStringsForI18n() {
|
|
445
479
|
const strings = [];
|
|
446
480
|
this.views.forEach((v) => strings.push(...v.getStringsForI18n()));
|
|
@@ -452,10 +486,18 @@ class State {
|
|
|
452
486
|
);
|
|
453
487
|
}
|
|
454
488
|
|
|
489
|
+
/**
|
|
490
|
+
*
|
|
491
|
+
* @param {function} f
|
|
492
|
+
*/
|
|
455
493
|
setRoomEmitter(f) {
|
|
456
494
|
this.roomEmitter = f;
|
|
457
495
|
}
|
|
458
496
|
|
|
497
|
+
/**
|
|
498
|
+
*
|
|
499
|
+
* @param {*} args
|
|
500
|
+
*/
|
|
459
501
|
emitRoom(...args) {
|
|
460
502
|
if (this.roomEmitter) this.roomEmitter(...args);
|
|
461
503
|
}
|
|
@@ -483,6 +525,11 @@ State.contract = {
|
|
|
483
525
|
const singleton = new State("public");
|
|
484
526
|
|
|
485
527
|
// return current State object
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* @function
|
|
531
|
+
* @returns {State}
|
|
532
|
+
*/
|
|
486
533
|
const getState = contract(
|
|
487
534
|
is.fun([], is.or(is.class("State"), is.eq(undefined))),
|
|
488
535
|
() => {
|
|
@@ -497,14 +544,17 @@ const getState = contract(
|
|
|
497
544
|
var tenants = { public: singleton };
|
|
498
545
|
// list of tenants with other domains
|
|
499
546
|
const otherdomaintenants = {};
|
|
547
|
+
|
|
500
548
|
/**
|
|
501
549
|
* Get other domain tenant
|
|
502
|
-
* @param hostname
|
|
550
|
+
* @param {string} hostname
|
|
551
|
+
* @returns {object}
|
|
503
552
|
*/
|
|
504
553
|
const get_other_domain_tenant = (hostname) => otherdomaintenants[hostname];
|
|
505
554
|
/**
|
|
506
555
|
* Get tenant
|
|
507
|
-
* @param ten
|
|
556
|
+
* @param {string} ten
|
|
557
|
+
* @returns {object}
|
|
508
558
|
*/
|
|
509
559
|
const getTenant = (ten) => {
|
|
510
560
|
//console.log({ ten, tenants });
|
|
@@ -512,8 +562,8 @@ const getTenant = (ten) => {
|
|
|
512
562
|
};
|
|
513
563
|
/**
|
|
514
564
|
* Remove protocol (http:// or https://) from domain url
|
|
515
|
-
* @param url
|
|
516
|
-
* @returns {
|
|
565
|
+
* @param {string} url
|
|
566
|
+
* @returns {string}
|
|
517
567
|
*/
|
|
518
568
|
const get_domain = (url) => {
|
|
519
569
|
const noproto = url.replace("https://", "").replace("http://", "");
|
|
@@ -522,8 +572,8 @@ const get_domain = (url) => {
|
|
|
522
572
|
/**
|
|
523
573
|
* Set tenant base url???
|
|
524
574
|
* From my point of view it just add tenant to list of otherdomaintenant
|
|
525
|
-
* @param tenant_subdomain
|
|
526
|
-
* @param value - new
|
|
575
|
+
* @param {object} tenant_subdomain
|
|
576
|
+
* @param {string} [value] - new
|
|
527
577
|
*/
|
|
528
578
|
const set_tenant_base_url = (tenant_subdomain, value) => {
|
|
529
579
|
const root_domain = get_domain(singleton.configs.base_url.value);
|
|
@@ -535,8 +585,8 @@ const set_tenant_base_url = (tenant_subdomain, value) => {
|
|
|
535
585
|
};
|
|
536
586
|
/**
|
|
537
587
|
* Switch to multi_tenant
|
|
538
|
-
* @param plugin_loader
|
|
539
|
-
* @param disableMigrate - if true then dont migrate db
|
|
588
|
+
* @param {object} plugin_loader
|
|
589
|
+
* @param {boolean} disableMigrate - if true then dont migrate db
|
|
540
590
|
* @returns {Promise<void>}
|
|
541
591
|
*/
|
|
542
592
|
const init_multi_tenant = async (plugin_loader, disableMigrate) => {
|
|
@@ -558,20 +608,39 @@ const init_multi_tenant = async (plugin_loader, disableMigrate) => {
|
|
|
558
608
|
};
|
|
559
609
|
/**
|
|
560
610
|
* Create tenant
|
|
561
|
-
* @param t
|
|
562
|
-
* @param plugin_loader
|
|
563
|
-
* @param newurl
|
|
611
|
+
* @param {string} t
|
|
612
|
+
* @param {object} plugin_loader
|
|
613
|
+
* @param {string} newurl
|
|
614
|
+
* @param {boolean} noSignalOrDB
|
|
564
615
|
* @returns {Promise<void>}
|
|
565
616
|
*/
|
|
566
|
-
const create_tenant = async (
|
|
617
|
+
const create_tenant = async (
|
|
618
|
+
t,
|
|
619
|
+
plugin_loader,
|
|
620
|
+
newurl,
|
|
621
|
+
noSignalOrDB,
|
|
622
|
+
loadAndSaveNewPlugin
|
|
623
|
+
) => {
|
|
567
624
|
if (!noSignalOrDB) await createTenant(t, newurl);
|
|
568
625
|
tenants[t] = new State(t);
|
|
569
626
|
await db.runWithTenant(t, plugin_loader);
|
|
570
|
-
if (!noSignalOrDB)
|
|
627
|
+
if (!noSignalOrDB) {
|
|
628
|
+
const tenant_template = singleton.getConfig("tenant_template");
|
|
629
|
+
if (tenant_template) {
|
|
630
|
+
//create backup
|
|
631
|
+
await copy_tenant_template({
|
|
632
|
+
tenant_template,
|
|
633
|
+
target: t,
|
|
634
|
+
state: tenants[t],
|
|
635
|
+
loadAndSaveNewPlugin,
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
process_send({ createTenant: t });
|
|
639
|
+
}
|
|
571
640
|
};
|
|
572
641
|
/**
|
|
573
642
|
* Restart tenant
|
|
574
|
-
* @param plugin_loader
|
|
643
|
+
* @param {object} plugin_loader
|
|
575
644
|
* @returns {Promise<void>}
|
|
576
645
|
*/
|
|
577
646
|
const restart_tenant = async (plugin_loader) => {
|
package/index.js
CHANGED
|
@@ -1 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @category saltcorn-data
|
|
3
|
+
* @module saltcorn-data/index
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* All modules in the saltcorn-data package.
|
|
8
|
+
* @namespace saltcorn-data_overview
|
|
9
|
+
* @property {module:models/index~models_overview} models
|
|
10
|
+
* @property {module:db/index~db_overview} db
|
|
11
|
+
* @property {module:base-plugin/index~base-plugin_overview} base-plugin
|
|
12
|
+
* @category saltcorn-data
|
|
13
|
+
*/
|
|
1
14
|
module.exports = {};
|