@saltcorn/server 0.9.5-beta.2 → 0.9.5-beta.4
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/load_plugins.js +14 -129
- package/package.json +15 -13
- package/routes/plugins.js +2 -0
- package/serve.js +1 -1
package/load_plugins.js
CHANGED
|
@@ -6,59 +6,10 @@
|
|
|
6
6
|
* @module load_plugins
|
|
7
7
|
*/
|
|
8
8
|
const db = require("@saltcorn/data/db");
|
|
9
|
-
const { PluginManager } = require("live-plugin-manager");
|
|
10
9
|
const { getState, getRootState } = require("@saltcorn/data/db/state");
|
|
11
10
|
const Plugin = require("@saltcorn/data/models/plugin");
|
|
12
|
-
const fs = require("fs");
|
|
13
|
-
const proc = require("child_process");
|
|
14
|
-
const tmp = require("tmp-promise");
|
|
15
11
|
|
|
16
|
-
const
|
|
17
|
-
"@saltcorn/markup": require("@saltcorn/markup"),
|
|
18
|
-
"@saltcorn/markup/tags": require("@saltcorn/markup/tags"),
|
|
19
|
-
"@saltcorn/markup/layout": require("@saltcorn/markup/layout"),
|
|
20
|
-
"@saltcorn/markup/helpers": require("@saltcorn/markup/helpers"),
|
|
21
|
-
"@saltcorn/markup/layout_utils": require("@saltcorn/markup/layout_utils"),
|
|
22
|
-
"@saltcorn/data": require("@saltcorn/data"),
|
|
23
|
-
"@saltcorn/data/db": require("@saltcorn/data/db"),
|
|
24
|
-
"@saltcorn/data/utils": require("@saltcorn/data/utils"),
|
|
25
|
-
"@saltcorn/data/db/state": require("@saltcorn/data/db/state"),
|
|
26
|
-
"@saltcorn/data/plugin-helper": require("@saltcorn/data/plugin-helper"),
|
|
27
|
-
"@saltcorn/data/plugin-testing": require("@saltcorn/data/plugin-testing"),
|
|
28
|
-
"@saltcorn/data/models/field": require("@saltcorn/data/models/field"),
|
|
29
|
-
"@saltcorn/data/models/fieldrepeat": require("@saltcorn/data/models/fieldrepeat"),
|
|
30
|
-
"@saltcorn/data/models/table": require("@saltcorn/data/models/table"),
|
|
31
|
-
"@saltcorn/data/models/form": require("@saltcorn/data/models/form"),
|
|
32
|
-
"@saltcorn/data/models/discovery": require("@saltcorn/data/models/discovery"),
|
|
33
|
-
"@saltcorn/data/models/config": require("@saltcorn/data/models/config"),
|
|
34
|
-
"@saltcorn/data/models/library": require("@saltcorn/data/models/library"),
|
|
35
|
-
"@saltcorn/data/models/model": require("@saltcorn/data/models/model"),
|
|
36
|
-
"@saltcorn/data/models/model_instance": require("@saltcorn/data/models/model_instance"),
|
|
37
|
-
"@saltcorn/data/models/notification": require("@saltcorn/data/models/notification"),
|
|
38
|
-
"@saltcorn/data/models/role": require("@saltcorn/data/models/role"),
|
|
39
|
-
"@saltcorn/data/models/tag": require("@saltcorn/data/models/tag"),
|
|
40
|
-
"@saltcorn/data/models/tag_entry": require("@saltcorn/data/models/tag_entry"),
|
|
41
|
-
"@saltcorn/data/models/view": require("@saltcorn/data/models/view"),
|
|
42
|
-
"@saltcorn/data/models/page": require("@saltcorn/data/models/page"),
|
|
43
|
-
"@saltcorn/data/models/file": require("@saltcorn/data/models/file"),
|
|
44
|
-
"@saltcorn/data/models/user": require("@saltcorn/data/models/user"),
|
|
45
|
-
"@saltcorn/data/models/layout": require("@saltcorn/data/models/layout"),
|
|
46
|
-
"@saltcorn/data/models/expression": require("@saltcorn/data/models/expression"),
|
|
47
|
-
"@saltcorn/data/models/workflow": require("@saltcorn/data/models/workflow"),
|
|
48
|
-
imapflow: require("imapflow"),
|
|
49
|
-
"node-fetch": require("node-fetch"),
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Create plugin manager with default list of core plugins
|
|
54
|
-
* @type {PluginManager}
|
|
55
|
-
*/
|
|
56
|
-
const defaultManager = new PluginManager({
|
|
57
|
-
staticDependencies: {
|
|
58
|
-
contractis: require("contractis"),
|
|
59
|
-
...staticDependencies,
|
|
60
|
-
},
|
|
61
|
-
});
|
|
12
|
+
const PluginInstaller = require("@saltcorn/plugins-loader/plugin_installer");
|
|
62
13
|
|
|
63
14
|
/**
|
|
64
15
|
* Load one plugin
|
|
@@ -68,7 +19,8 @@ const defaultManager = new PluginManager({
|
|
|
68
19
|
*/
|
|
69
20
|
const loadPlugin = async (plugin, force) => {
|
|
70
21
|
// load plugin
|
|
71
|
-
const
|
|
22
|
+
const loader = new PluginInstaller(plugin);
|
|
23
|
+
const res = await loader.install(force);
|
|
72
24
|
const configuration =
|
|
73
25
|
typeof plugin.configuration === "string"
|
|
74
26
|
? JSON.parse(plugin.configuration)
|
|
@@ -91,105 +43,42 @@ const loadPlugin = async (plugin, force) => {
|
|
|
91
43
|
return res;
|
|
92
44
|
};
|
|
93
45
|
|
|
94
|
-
/**
|
|
95
|
-
* Git pull or clone
|
|
96
|
-
* @param plugin
|
|
97
|
-
*/
|
|
98
|
-
const gitPullOrClone = async (plugin) => {
|
|
99
|
-
await fs.promises.mkdir("git_plugins", { recursive: true });
|
|
100
|
-
let keyfnm,
|
|
101
|
-
setKey = `-c core.sshCommand="ssh -oBatchMode=yes -o 'StrictHostKeyChecking no'" `;
|
|
102
|
-
if (plugin.deploy_private_key) {
|
|
103
|
-
keyfnm = await tmp.tmpName();
|
|
104
|
-
await fs.promises.writeFile(
|
|
105
|
-
keyfnm,
|
|
106
|
-
plugin.deploy_private_key.replace(/[\r]+/g, "") + "\n",
|
|
107
|
-
{
|
|
108
|
-
mode: 0o600,
|
|
109
|
-
encoding: "ascii",
|
|
110
|
-
}
|
|
111
|
-
);
|
|
112
|
-
setKey = `-c core.sshCommand="ssh -oBatchMode=yes -o 'StrictHostKeyChecking no' -i ${keyfnm}" `;
|
|
113
|
-
}
|
|
114
|
-
const dir = `git_plugins/${plugin.name}`;
|
|
115
|
-
if (fs.existsSync(dir)) {
|
|
116
|
-
proc.execSync(`git ${setKey} -C ${dir} pull`);
|
|
117
|
-
} else {
|
|
118
|
-
proc.execSync(`git ${setKey} clone ${plugin.location} ${dir}`);
|
|
119
|
-
}
|
|
120
|
-
if (plugin.deploy_private_key) await fs.promises.unlink(keyfnm);
|
|
121
|
-
return dir;
|
|
122
|
-
};
|
|
123
46
|
/**
|
|
124
47
|
* Install plugin
|
|
125
48
|
* @param plugin - plugin name
|
|
126
49
|
* @param force - force flag
|
|
127
|
-
* @param manager - plugin manager
|
|
128
50
|
* @returns {Promise<{plugin_module: *}|{plugin_module: any}>}
|
|
129
51
|
*/
|
|
130
|
-
const requirePlugin = async (plugin, force
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
if (
|
|
134
|
-
["@saltcorn/base-plugin", "@saltcorn/sbadmin2"].includes(plugin.location)
|
|
135
|
-
) {
|
|
136
|
-
return { plugin_module: require(plugin.location) };
|
|
137
|
-
} else if (plugin.source === "npm") {
|
|
138
|
-
if (force || !installed_plugins.includes(plugin.location)) {
|
|
139
|
-
const plinfo = await manager.install(plugin.location, plugin.version);
|
|
140
|
-
return { plugin_module: manager.require(plugin.location), ...plinfo };
|
|
141
|
-
} else {
|
|
142
|
-
const plinfo = manager.getInfo(plugin.location);
|
|
143
|
-
return { plugin_module: manager.require(plugin.location), ...plinfo };
|
|
144
|
-
}
|
|
145
|
-
} else if (plugin.source === "local") {
|
|
146
|
-
const plinfo = await manager.installFromPath(plugin.location, {
|
|
147
|
-
force: true,
|
|
148
|
-
});
|
|
149
|
-
return { plugin_module: manager.require(plugin.name), ...plinfo };
|
|
150
|
-
} else if (plugin.source === "git") {
|
|
151
|
-
const loc = await gitPullOrClone(plugin);
|
|
152
|
-
const plinfo = await manager.installFromPath(loc, {
|
|
153
|
-
force: true,
|
|
154
|
-
});
|
|
155
|
-
return { plugin_module: manager.require(plugin.name), ...plinfo };
|
|
156
|
-
} else if (plugin.source === "github") {
|
|
157
|
-
if (force || !installed_plugins.includes(plugin.location)) {
|
|
158
|
-
const plinfo = await manager.installFromGithub(plugin.location, {
|
|
159
|
-
force: true,
|
|
160
|
-
});
|
|
161
|
-
return { plugin_module: manager.require(plugin.name), ...plinfo };
|
|
162
|
-
} else {
|
|
163
|
-
const plinfo = manager.getInfo(plugin.location);
|
|
164
|
-
return { plugin_module: manager.require(plugin.location), ...plinfo };
|
|
165
|
-
}
|
|
166
|
-
} else throw new Error("Unknown plugin source: " + plugin.source);
|
|
52
|
+
const requirePlugin = async (plugin, force) => {
|
|
53
|
+
const loader = new PluginInstaller(plugin);
|
|
54
|
+
return await loader.install(force);
|
|
167
55
|
};
|
|
56
|
+
|
|
168
57
|
/**
|
|
169
58
|
* Load all plugins
|
|
170
59
|
* @returns {Promise<void>}
|
|
171
60
|
*/
|
|
172
|
-
const loadAllPlugins = async () => {
|
|
61
|
+
const loadAllPlugins = async (force) => {
|
|
173
62
|
await getState().refresh(true);
|
|
174
63
|
const plugins = await db.select("_sc_plugins");
|
|
175
64
|
for (const plugin of plugins) {
|
|
176
65
|
try {
|
|
177
|
-
await loadPlugin(plugin);
|
|
66
|
+
await loadPlugin(plugin, force);
|
|
178
67
|
} catch (e) {
|
|
179
68
|
console.error(e);
|
|
180
69
|
}
|
|
181
70
|
}
|
|
182
71
|
await getState().refresh(true);
|
|
183
72
|
};
|
|
73
|
+
|
|
184
74
|
/**
|
|
185
75
|
* Load Plugin and its dependencies and save into local installation
|
|
186
76
|
* @param plugin
|
|
187
77
|
* @param force
|
|
188
78
|
* @param noSignalOrDB
|
|
189
|
-
* @param manager - optional plugin manager
|
|
190
79
|
* @returns {Promise<void>}
|
|
191
80
|
*/
|
|
192
|
-
const loadAndSaveNewPlugin = async (plugin, force, noSignalOrDB
|
|
81
|
+
const loadAndSaveNewPlugin = async (plugin, force, noSignalOrDB) => {
|
|
193
82
|
const tenants_unsafe_plugins = getRootState().getConfig(
|
|
194
83
|
"tenants_unsafe_plugins",
|
|
195
84
|
false
|
|
@@ -215,11 +104,8 @@ const loadAndSaveNewPlugin = async (plugin, force, noSignalOrDB, manager) => {
|
|
|
215
104
|
return;
|
|
216
105
|
}
|
|
217
106
|
}
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
force,
|
|
221
|
-
manager
|
|
222
|
-
);
|
|
107
|
+
const loader = new PluginInstaller(plugin);
|
|
108
|
+
const { version, plugin_module, location } = await loader.install(force);
|
|
223
109
|
|
|
224
110
|
// install dependecies
|
|
225
111
|
for (const loc of plugin_module.dependencies || []) {
|
|
@@ -252,7 +138,7 @@ const loadAndSaveNewPlugin = async (plugin, force, noSignalOrDB, manager) => {
|
|
|
252
138
|
getState().processSend({
|
|
253
139
|
installPlugin: plugin,
|
|
254
140
|
tenant: db.getTenantSchema(),
|
|
255
|
-
force,
|
|
141
|
+
force: false, // okay ??
|
|
256
142
|
});
|
|
257
143
|
}
|
|
258
144
|
};
|
|
@@ -262,5 +148,4 @@ module.exports = {
|
|
|
262
148
|
loadAllPlugins,
|
|
263
149
|
loadPlugin,
|
|
264
150
|
requirePlugin,
|
|
265
|
-
staticDependencies,
|
|
266
151
|
};
|
package/package.json
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saltcorn/server",
|
|
3
|
-
"version": "0.9.5-beta.
|
|
3
|
+
"version": "0.9.5-beta.4",
|
|
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
9
|
"@aws-sdk/client-s3": "^3.451.0",
|
|
10
|
-
"@saltcorn/base-plugin": "0.9.5-beta.
|
|
11
|
-
"@saltcorn/builder": "0.9.5-beta.
|
|
12
|
-
"@saltcorn/data": "0.9.5-beta.
|
|
13
|
-
"@saltcorn/admin-models": "0.9.5-beta.
|
|
14
|
-
"@saltcorn/filemanager": "0.9.5-beta.
|
|
15
|
-
"@saltcorn/markup": "0.9.5-beta.
|
|
16
|
-
"@saltcorn/
|
|
10
|
+
"@saltcorn/base-plugin": "0.9.5-beta.4",
|
|
11
|
+
"@saltcorn/builder": "0.9.5-beta.4",
|
|
12
|
+
"@saltcorn/data": "0.9.5-beta.4",
|
|
13
|
+
"@saltcorn/admin-models": "0.9.5-beta.4",
|
|
14
|
+
"@saltcorn/filemanager": "0.9.5-beta.4",
|
|
15
|
+
"@saltcorn/markup": "0.9.5-beta.4",
|
|
16
|
+
"@saltcorn/plugins-loader": "0.9.5-beta.4",
|
|
17
|
+
"@saltcorn/sbadmin2": "0.9.5-beta.4",
|
|
17
18
|
"@socket.io/cluster-adapter": "^0.2.1",
|
|
18
19
|
"@socket.io/sticky": "^1.0.1",
|
|
19
20
|
"adm-zip": "0.5.10",
|
|
@@ -37,7 +38,6 @@
|
|
|
37
38
|
"i18n": "^0.15.1",
|
|
38
39
|
"imapflow": "1.0.123",
|
|
39
40
|
"jsonwebtoken": "^9.0.0",
|
|
40
|
-
"live-plugin-manager": "^0.17.1",
|
|
41
41
|
"markdown-it": "^13.0.2",
|
|
42
42
|
"moment": "^2.29.4",
|
|
43
43
|
"multer": "1.4.5-lts.1",
|
|
@@ -70,8 +70,8 @@
|
|
|
70
70
|
},
|
|
71
71
|
"repository": "github:saltcorn/saltcorn",
|
|
72
72
|
"devDependencies": {
|
|
73
|
-
"jest": "
|
|
74
|
-
"jest-environment-jsdom": "
|
|
73
|
+
"jest": "^28.1.3",
|
|
74
|
+
"jest-environment-jsdom": "28.1.3",
|
|
75
75
|
"supertest": "^6.3.3"
|
|
76
76
|
},
|
|
77
77
|
"scripts": {
|
|
@@ -84,11 +84,13 @@
|
|
|
84
84
|
"testEnvironment": "node",
|
|
85
85
|
"testPathIgnorePatterns": [
|
|
86
86
|
"/node_modules/",
|
|
87
|
-
"/plugin_packages/"
|
|
87
|
+
"/plugin_packages/",
|
|
88
|
+
"/plugins_folder/"
|
|
88
89
|
],
|
|
89
90
|
"coveragePathIgnorePatterns": [
|
|
90
91
|
"/node_modules/",
|
|
91
|
-
"/plugin_packages/"
|
|
92
|
+
"/plugin_packages/",
|
|
93
|
+
"/plugins_folder/"
|
|
92
94
|
],
|
|
93
95
|
"moduleNameMapper": {
|
|
94
96
|
"@saltcorn/sqlite/(.*)": "<rootDir>/../sqlite/dist/$1",
|
package/routes/plugins.js
CHANGED
|
@@ -57,6 +57,7 @@ const { flash_restart } = require("../markup/admin.js");
|
|
|
57
57
|
const { sleep, removeNonWordChars } = require("@saltcorn/data/utils");
|
|
58
58
|
const { loadAllPlugins } = require("../load_plugins");
|
|
59
59
|
const npmFetch = require("npm-registry-fetch");
|
|
60
|
+
const PluginInstaller = require("@saltcorn/plugins-loader/plugin_installer");
|
|
60
61
|
|
|
61
62
|
/**
|
|
62
63
|
* @type {object}
|
|
@@ -1178,6 +1179,7 @@ router.post(
|
|
|
1178
1179
|
getState().getConfig("development_mode", false)
|
|
1179
1180
|
) {
|
|
1180
1181
|
await plugin.delete();
|
|
1182
|
+
await new PluginInstaller(plugin).remove();
|
|
1181
1183
|
req.flash("success", req.__(`Module %s removed.`, plugin.name));
|
|
1182
1184
|
} else {
|
|
1183
1185
|
req.flash(
|
package/serve.js
CHANGED
|
@@ -105,7 +105,7 @@ const initMaster = async ({ disableMigrate }, useClusterAdaptor = true) => {
|
|
|
105
105
|
// migrate database
|
|
106
106
|
if (!disableMigrate) await migrate(db.connectObj.default_schema, true);
|
|
107
107
|
// load all plugins
|
|
108
|
-
await loadAllPlugins();
|
|
108
|
+
await loadAllPlugins(true);
|
|
109
109
|
// switch on sql logging - but it was initiated before???
|
|
110
110
|
if (getState().getConfig("log_sql", false)) db.set_sql_logging();
|
|
111
111
|
if (db.is_it_multi_tenant()) {
|