@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 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 staticDependencies = {
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 res = await requirePlugin(plugin, force);
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, manager = defaultManager) => {
131
- const installed_plugins = (await manager.list()).map((p) => p.name);
132
- // todo as idea is to make list of mandatory plugins configurable
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, manager) => {
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 { version, plugin_module, location } = await requirePlugin(
219
- plugin,
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.2",
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.2",
11
- "@saltcorn/builder": "0.9.5-beta.2",
12
- "@saltcorn/data": "0.9.5-beta.2",
13
- "@saltcorn/admin-models": "0.9.5-beta.2",
14
- "@saltcorn/filemanager": "0.9.5-beta.2",
15
- "@saltcorn/markup": "0.9.5-beta.2",
16
- "@saltcorn/sbadmin2": "0.9.5-beta.2",
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": "26.6.3",
74
- "jest-environment-jsdom": "^26.6.2",
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()) {