@saltcorn/plugins-loader 1.0.0-beta.9 → 1.0.0-rc.2
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/download_utils.js +11 -5
- package/package.json +20 -4
- package/plugin_installer.js +30 -6
- package/stable_versioning.js +104 -0
- package/tests/stable_versioning.test.js +263 -0
package/download_utils.js
CHANGED
|
@@ -2,7 +2,7 @@ const fs = require("fs");
|
|
|
2
2
|
const { rm } = require("fs").promises;
|
|
3
3
|
const { mkdir, pathExists } = require("fs-extra");
|
|
4
4
|
const { tmpName } = require("tmp-promise");
|
|
5
|
-
const {
|
|
5
|
+
const { execFileSync } = require("child_process");
|
|
6
6
|
const { extract } = require("tar");
|
|
7
7
|
const { join } = require("path");
|
|
8
8
|
const { createWriteStream, unlink } = require("fs");
|
|
@@ -93,7 +93,10 @@ const loadTarball = (rootFolder, url, name) => {
|
|
|
93
93
|
*/
|
|
94
94
|
const gitPullOrClone = async (plugin, pluginDir) => {
|
|
95
95
|
let keyfnm,
|
|
96
|
-
setKey =
|
|
96
|
+
setKey = [
|
|
97
|
+
"-c",
|
|
98
|
+
`core.sshCommand="ssh -oBatchMode=yes -o 'StrictHostKeyChecking no'"`,
|
|
99
|
+
];
|
|
97
100
|
if (plugin.deploy_private_key) {
|
|
98
101
|
keyfnm = await tmpName();
|
|
99
102
|
await fs.promises.writeFile(
|
|
@@ -104,12 +107,15 @@ const gitPullOrClone = async (plugin, pluginDir) => {
|
|
|
104
107
|
encoding: "ascii",
|
|
105
108
|
}
|
|
106
109
|
);
|
|
107
|
-
setKey =
|
|
110
|
+
setKey = [
|
|
111
|
+
"-c",
|
|
112
|
+
`core.sshCommand="ssh -oBatchMode=yes -o 'StrictHostKeyChecking no' -i ${keyfnm}"`,
|
|
113
|
+
];
|
|
108
114
|
}
|
|
109
115
|
if (fs.existsSync(pluginDir)) {
|
|
110
|
-
|
|
116
|
+
execFileSync("git", [...setKey, "-C", pluginDir, "pull"]);
|
|
111
117
|
} else {
|
|
112
|
-
|
|
118
|
+
execFileSync("git", [...setKey, "clone", plugin.location, pluginDir]);
|
|
113
119
|
}
|
|
114
120
|
if (plugin.deploy_private_key && keyfnm) await fs.promises.unlink(keyfnm);
|
|
115
121
|
};
|
package/package.json
CHANGED
|
@@ -1,20 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saltcorn/plugins-loader",
|
|
3
|
-
"version": "1.0.0-
|
|
3
|
+
"version": "1.0.0-rc.2",
|
|
4
4
|
"description": "Saltcorn plugin loader",
|
|
5
5
|
"homepage": "https://saltcorn.com",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"test": "
|
|
7
|
+
"test": "jest --runInBand",
|
|
8
8
|
"tsc": "echo 'No TypeScript build'",
|
|
9
9
|
"clean": "echo 'No TypeScript build'"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"env-paths": "^2.2.0",
|
|
13
|
-
"npm-registry-fetch": "
|
|
14
|
-
"@saltcorn/data": "1.0.0-
|
|
13
|
+
"npm-registry-fetch": "17.1.0",
|
|
14
|
+
"@saltcorn/data": "1.0.0-rc.2"
|
|
15
15
|
},
|
|
16
16
|
"author": "Christian Hugo",
|
|
17
17
|
"license": "MIT",
|
|
18
|
+
"jest": {
|
|
19
|
+
"testEnvironment": "node",
|
|
20
|
+
"testPathIgnorePatterns": [
|
|
21
|
+
"/node_modules/",
|
|
22
|
+
"/plugin_packages/",
|
|
23
|
+
"/plugins_folder/"
|
|
24
|
+
],
|
|
25
|
+
"coveragePathIgnorePatterns": [
|
|
26
|
+
"/node_modules/",
|
|
27
|
+
"/plugin_packages/",
|
|
28
|
+
"/plugins_folder/"
|
|
29
|
+
],
|
|
30
|
+
"moduleNameMapper": {
|
|
31
|
+
"@saltcorn/data/(.*)": "<rootDir>/../saltcorn-data/dist/$1"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
18
34
|
"main": "index.js",
|
|
19
35
|
"repository": "github:saltcorn/saltcorn",
|
|
20
36
|
"publishConfig": {
|
package/plugin_installer.js
CHANGED
|
@@ -11,6 +11,7 @@ const {
|
|
|
11
11
|
const { getState } = require("@saltcorn/data/db/state");
|
|
12
12
|
const { rm, rename, cp, readFile } = require("fs").promises;
|
|
13
13
|
const envPaths = require("env-paths");
|
|
14
|
+
const semver = require("semver");
|
|
14
15
|
|
|
15
16
|
const staticDeps = ["@saltcorn/markup", "@saltcorn/data", "jest"];
|
|
16
17
|
const fixedPlugins = ["@saltcorn/base-plugin", "@saltcorn/sbadmin2"];
|
|
@@ -26,10 +27,10 @@ const readPackageJson = async (filePath) => {
|
|
|
26
27
|
};
|
|
27
28
|
|
|
28
29
|
const npmInstallNeeded = (oldPckJSON, newPckJSON) => {
|
|
29
|
-
const oldDeps = oldPckJSON.dependencies ||
|
|
30
|
-
const oldDevDeps = oldPckJSON.devDependencies ||
|
|
31
|
-
const newDeps = newPckJSON.dependencies ||
|
|
32
|
-
const newDevDeps = newPckJSON.devDependencies ||
|
|
30
|
+
const oldDeps = oldPckJSON.dependencies || Object.create(null);
|
|
31
|
+
const oldDevDeps = oldPckJSON.devDependencies || Object.create(null);
|
|
32
|
+
const newDeps = newPckJSON.dependencies || Object.create(null);
|
|
33
|
+
const newDevDeps = newPckJSON.devDependencies || Object.create(null);
|
|
33
34
|
return (
|
|
34
35
|
JSON.stringify(oldDeps) !== JSON.stringify(newDeps) ||
|
|
35
36
|
JSON.stringify(oldDevDeps) !== JSON.stringify(newDevDeps)
|
|
@@ -37,7 +38,7 @@ const npmInstallNeeded = (oldPckJSON, newPckJSON) => {
|
|
|
37
38
|
};
|
|
38
39
|
|
|
39
40
|
class PluginInstaller {
|
|
40
|
-
constructor(plugin, opts =
|
|
41
|
+
constructor(plugin, opts = Object.create(null)) {
|
|
41
42
|
this.plugin = plugin;
|
|
42
43
|
this.rootFolder =
|
|
43
44
|
opts.rootFolder || envPaths("saltcorn", { suffix: "plugins" }).data;
|
|
@@ -56,13 +57,33 @@ class PluginInstaller {
|
|
|
56
57
|
this.pckJsonPath = join(this.pluginDir, "package.json");
|
|
57
58
|
this.tempDir = join(this.tempRootFolder, "temp_install", ...tokens);
|
|
58
59
|
this.tempPckJsonPath = join(this.tempDir, "package.json");
|
|
60
|
+
this.scVersion = opts.scVersion;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* check if the host supports the plugin and return a warning if not
|
|
65
|
+
* @param pckJSON
|
|
66
|
+
* @returns
|
|
67
|
+
*/
|
|
68
|
+
checkEngineWarning(pckJSON) {
|
|
69
|
+
const scEngine = pckJSON.engines?.saltcorn;
|
|
70
|
+
if (
|
|
71
|
+
this.scVersion &&
|
|
72
|
+
scEngine &&
|
|
73
|
+
!semver.satisfies(this.scVersion, scEngine)
|
|
74
|
+
) {
|
|
75
|
+
const warnMsg = `Plugin ${this.plugin.name} requires Saltcorn version ${scEngine} but running ${this.scVersion}`;
|
|
76
|
+
getState().log(4, warnMsg);
|
|
77
|
+
return warnMsg;
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
59
80
|
}
|
|
60
81
|
|
|
61
82
|
async install(force) {
|
|
62
83
|
await this.ensurePluginsRootFolders();
|
|
63
84
|
if (fixedPlugins.includes(this.plugin.location))
|
|
64
85
|
return { plugin_module: require(this.plugin.location) };
|
|
65
|
-
|
|
86
|
+
const msgs = [];
|
|
66
87
|
let pckJSON = await readPackageJson(this.pckJsonPath);
|
|
67
88
|
const installer = async () => {
|
|
68
89
|
if (await this.prepPluginsFolder(force, pckJSON)) {
|
|
@@ -80,6 +101,8 @@ class PluginInstaller {
|
|
|
80
101
|
await removeTarball(this.rootFolder, this.plugin);
|
|
81
102
|
}
|
|
82
103
|
pckJSON = await readPackageJson(this.pckJsonPath);
|
|
104
|
+
const msg = this.checkEngineWarning(pckJSON);
|
|
105
|
+
if (msg && !msgs.includes(msg)) msgs.push(msg);
|
|
83
106
|
};
|
|
84
107
|
await installer();
|
|
85
108
|
let module = null;
|
|
@@ -108,6 +131,7 @@ class PluginInstaller {
|
|
|
108
131
|
location: this.pluginDir,
|
|
109
132
|
name: this.plugin.name,
|
|
110
133
|
loadedWithReload,
|
|
134
|
+
msgs,
|
|
111
135
|
};
|
|
112
136
|
}
|
|
113
137
|
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
const semver = require("semver");
|
|
2
|
+
const { getState } = require("@saltcorn/data/db/state");
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
internal helper
|
|
6
|
+
*/
|
|
7
|
+
const doCheck = (pluginVersion, versionInfos, scVersion) => {
|
|
8
|
+
if (!versionInfos[pluginVersion])
|
|
9
|
+
throw new Error(`Version ${pluginVersion} not found in available versions`);
|
|
10
|
+
const scEngine = versionInfos[pluginVersion].engines?.saltcorn;
|
|
11
|
+
if (!scEngine) return true;
|
|
12
|
+
if (semver.validRange(scEngine) === null) {
|
|
13
|
+
getState().log(4, `invalid engine property: ${scEngine}`);
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
if (semver.valid(scVersion) === null) {
|
|
17
|
+
getState().log(4, `invalid saltcorn version: ${scVersion}`);
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
return semver.satisfies(scVersion, scEngine);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* check if 'pluginVersion' is supported or find the latest supported version
|
|
25
|
+
* @param pluginVersion - wanted version
|
|
26
|
+
* @param versionInfos - version infos from the npm registry (resembles the package.json version).
|
|
27
|
+
* Here you'll find the engines.saltcorn property.
|
|
28
|
+
* @param scVersion - optional saltcorn version (if not set it will be taken from the state)
|
|
29
|
+
* @returns
|
|
30
|
+
*/
|
|
31
|
+
const supportedVersion = (
|
|
32
|
+
pluginVersion = "latest",
|
|
33
|
+
versionInfos,
|
|
34
|
+
scVersion
|
|
35
|
+
) => {
|
|
36
|
+
const resolved =
|
|
37
|
+
pluginVersion === "latest" ? resolveLatest(versionInfos) : pluginVersion;
|
|
38
|
+
const safeScVersion = scVersion || getState().scVersion;
|
|
39
|
+
if (doCheck(resolved, versionInfos, safeScVersion)) return resolved;
|
|
40
|
+
else {
|
|
41
|
+
const keys = Object.keys(versionInfos);
|
|
42
|
+
keys.sort((a, b) => semver.rcompare(b, a));
|
|
43
|
+
// iterate in reverse order to get the latest version
|
|
44
|
+
for (let i = keys.length - 1; i >= 0; i--) {
|
|
45
|
+
const version = keys[i];
|
|
46
|
+
if (doCheck(version, versionInfos, safeScVersion)) return version;
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* check if 'pluginVersion' is supported
|
|
54
|
+
* @param pluginVersion - wanted version
|
|
55
|
+
* @param scEngine - version infos from the npm registry (resembles the package.json version)
|
|
56
|
+
* Here you'll find the engines.saltcorn property.
|
|
57
|
+
* If versionInfos is a string, it will be treated as the engines.saltcorn property.
|
|
58
|
+
* @param scVersion - optional saltcorn version (if not set it will be taken from the state)
|
|
59
|
+
*/
|
|
60
|
+
const isVersionSupported = (pluginVersion, scEngine, scVersion) => {
|
|
61
|
+
const safeInfos =
|
|
62
|
+
typeof scEngine === "string"
|
|
63
|
+
? { [pluginVersion]: { engines: scEngine } }
|
|
64
|
+
: scEngine;
|
|
65
|
+
const safeScVersion = scVersion || getState().scVersion;
|
|
66
|
+
return doCheck(pluginVersion, safeInfos, safeScVersion);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* check if 'scVersion' fullfilles 'scEngine'
|
|
71
|
+
* @param scEngine fixed version or range of saltcorn versions (e.g. ">=1.0.0")
|
|
72
|
+
* @param scVersion optional saltcorn version (if not set it will be taken from the state)
|
|
73
|
+
* @returns true if the saltcorn version fullfilles scEngine
|
|
74
|
+
*/
|
|
75
|
+
const isEngineSatisfied = (scEngine, scVersion) => {
|
|
76
|
+
if (!scEngine) return true;
|
|
77
|
+
if (semver.validRange(scEngine) === null) {
|
|
78
|
+
getState().log(4, `invalid engine property: ${scEngine}`);
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
const safeScVersion = scVersion || getState().scVersion;
|
|
82
|
+
if (semver.valid(safeScVersion) === null) {
|
|
83
|
+
getState().log(4, `invalid saltcorn version: ${scVersion}`);
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
return semver.satisfies(safeScVersion, scEngine);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* change latest to the actual version
|
|
91
|
+
* @param versionInfos - version infos from the npm registry
|
|
92
|
+
*/
|
|
93
|
+
const resolveLatest = (versionInfos) => {
|
|
94
|
+
const keys = Object.keys(versionInfos);
|
|
95
|
+
keys.sort((a, b) => semver.rcompare(a, b));
|
|
96
|
+
return keys[0];
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
module.exports = {
|
|
100
|
+
isVersionSupported,
|
|
101
|
+
isEngineSatisfied,
|
|
102
|
+
supportedVersion,
|
|
103
|
+
resolveLatest,
|
|
104
|
+
};
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
const npmFetch = require("npm-registry-fetch");
|
|
2
|
+
const semver = require("semver");
|
|
3
|
+
|
|
4
|
+
const {
|
|
5
|
+
supportedVersion,
|
|
6
|
+
isVersionSupported,
|
|
7
|
+
} = require("../stable_versioning");
|
|
8
|
+
|
|
9
|
+
jest.setTimeout(30000);
|
|
10
|
+
|
|
11
|
+
const getSortedKeys = (pkgInfo) => {
|
|
12
|
+
const keys = [...Object.keys(pkgInfo.versions)];
|
|
13
|
+
keys.sort((a, b) => semver.rcompare(a, b));
|
|
14
|
+
return keys;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
describe("Stable versioning", () => {
|
|
18
|
+
it("stays compatible to version 1.0.0", async () => {
|
|
19
|
+
const wantedVersion = "latest";
|
|
20
|
+
const scVersion = "1.0.0";
|
|
21
|
+
const plugin = {
|
|
22
|
+
location: "@saltcorn/html",
|
|
23
|
+
version: wantedVersion,
|
|
24
|
+
};
|
|
25
|
+
const pkgInfo = await npmFetch.json(
|
|
26
|
+
`https://registry.npmjs.org/${plugin.location}`
|
|
27
|
+
);
|
|
28
|
+
const sortedKeys = getSortedKeys(pkgInfo);
|
|
29
|
+
pkgInfo.versions[sortedKeys[0]].engines = { saltcorn: ">=1.0.1" };
|
|
30
|
+
pkgInfo.versions[sortedKeys[1]].engines = { saltcorn: ">=1.0.1-beta.1" };
|
|
31
|
+
pkgInfo.versions[sortedKeys[2]].engines = { saltcorn: "<=1.0.0" };
|
|
32
|
+
pkgInfo.versions[sortedKeys[3]].engines = { saltcorn: ">=1.0.0-beta.1" };
|
|
33
|
+
const result = supportedVersion(
|
|
34
|
+
plugin.version,
|
|
35
|
+
pkgInfo.versions,
|
|
36
|
+
scVersion
|
|
37
|
+
);
|
|
38
|
+
expect(result).toBe(sortedKeys[2]);
|
|
39
|
+
expect(isVersionSupported(sortedKeys[0], pkgInfo.versions, scVersion)).toBe(
|
|
40
|
+
false
|
|
41
|
+
);
|
|
42
|
+
expect(isVersionSupported(sortedKeys[1], pkgInfo.versions, scVersion)).toBe(
|
|
43
|
+
false
|
|
44
|
+
);
|
|
45
|
+
expect(isVersionSupported(sortedKeys[2], pkgInfo.versions, scVersion)).toBe(
|
|
46
|
+
true
|
|
47
|
+
);
|
|
48
|
+
expect(isVersionSupported(sortedKeys[3], pkgInfo.versions, scVersion)).toBe(
|
|
49
|
+
true
|
|
50
|
+
);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("picks one fixed version instead of a range", async () => {
|
|
54
|
+
const wantedVersion = "latest";
|
|
55
|
+
const scVersion = "1.0.0";
|
|
56
|
+
const plugin = {
|
|
57
|
+
location: "@saltcorn/html",
|
|
58
|
+
version: wantedVersion,
|
|
59
|
+
};
|
|
60
|
+
const pkgInfo = await npmFetch.json(
|
|
61
|
+
`https://registry.npmjs.org/${plugin.location}`
|
|
62
|
+
);
|
|
63
|
+
const sortedKeys = getSortedKeys(pkgInfo);
|
|
64
|
+
pkgInfo.versions[sortedKeys[0]].engines = { saltcorn: ">=1.0.1" };
|
|
65
|
+
pkgInfo.versions[sortedKeys[1]].engines = { saltcorn: ">=1.0.1-beta.1" };
|
|
66
|
+
pkgInfo.versions[sortedKeys[2]].engines = { saltcorn: "1.0.0" };
|
|
67
|
+
pkgInfo.versions[sortedKeys[3]].engines = { saltcorn: ">=1.0.0-beta.1" };
|
|
68
|
+
const result = supportedVersion(
|
|
69
|
+
plugin.version,
|
|
70
|
+
pkgInfo.versions,
|
|
71
|
+
scVersion
|
|
72
|
+
);
|
|
73
|
+
expect(result).toBe(sortedKeys[2]);
|
|
74
|
+
expect(isVersionSupported(sortedKeys[0], pkgInfo.versions, scVersion)).toBe(
|
|
75
|
+
false
|
|
76
|
+
);
|
|
77
|
+
expect(isVersionSupported(sortedKeys[1], pkgInfo.versions, scVersion)).toBe(
|
|
78
|
+
false
|
|
79
|
+
);
|
|
80
|
+
expect(isVersionSupported(sortedKeys[2], pkgInfo.versions, scVersion)).toBe(
|
|
81
|
+
true
|
|
82
|
+
);
|
|
83
|
+
expect(isVersionSupported(sortedKeys[3], pkgInfo.versions, scVersion)).toBe(
|
|
84
|
+
true
|
|
85
|
+
);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("warns and takes invalid engine properties", async () => {
|
|
89
|
+
const wantedVersion = "latest";
|
|
90
|
+
const scVersion = "1.0.0";
|
|
91
|
+
const plugin = {
|
|
92
|
+
location: "@saltcorn/html",
|
|
93
|
+
version: wantedVersion,
|
|
94
|
+
};
|
|
95
|
+
const pkgInfo = await npmFetch.json(
|
|
96
|
+
`https://registry.npmjs.org/${plugin.location}`
|
|
97
|
+
);
|
|
98
|
+
const sortedKeys = getSortedKeys(pkgInfo);
|
|
99
|
+
pkgInfo.versions[sortedKeys[0]].engines = { saltcorn: ">=1.0.1" };
|
|
100
|
+
// invalid: >=1.0.1.beta.1 should be >=1.0.1-beta.1
|
|
101
|
+
pkgInfo.versions[sortedKeys[1]].engines = { saltcorn: ">=1.0.1.beta.1" };
|
|
102
|
+
pkgInfo.versions[sortedKeys[2]].engines = { saltcorn: "<=1.0.0" };
|
|
103
|
+
pkgInfo.versions[sortedKeys[3]].engines = { saltcorn: ">=1.0.0-beta.1" };
|
|
104
|
+
const result = supportedVersion(
|
|
105
|
+
plugin.version,
|
|
106
|
+
pkgInfo.versions,
|
|
107
|
+
scVersion
|
|
108
|
+
);
|
|
109
|
+
expect(result).toBe(sortedKeys[1]);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("downgrades latest with greater equal", async () => {
|
|
113
|
+
const wantedVersion = "latest";
|
|
114
|
+
const scVersion = "1.0.0-beta.6";
|
|
115
|
+
const plugin = {
|
|
116
|
+
location: "@saltcorn/html",
|
|
117
|
+
version: wantedVersion,
|
|
118
|
+
};
|
|
119
|
+
const pkgInfo = await npmFetch.json(
|
|
120
|
+
`https://registry.npmjs.org/${plugin.location}`
|
|
121
|
+
);
|
|
122
|
+
const sortedKeys = getSortedKeys(pkgInfo);
|
|
123
|
+
pkgInfo.versions[sortedKeys[0]].engines = { saltcorn: ">=1.0.0-beta.7" };
|
|
124
|
+
pkgInfo.versions[sortedKeys[1]].engines = { saltcorn: ">=1.0.0-beta.6" };
|
|
125
|
+
const result = supportedVersion(
|
|
126
|
+
plugin.version,
|
|
127
|
+
pkgInfo.versions,
|
|
128
|
+
scVersion
|
|
129
|
+
);
|
|
130
|
+
expect(result).toBe(sortedKeys[1]);
|
|
131
|
+
expect(isVersionSupported(result, pkgInfo.versions, scVersion)).toBe(true);
|
|
132
|
+
expect(isVersionSupported(sortedKeys[0], pkgInfo.versions, scVersion)).toBe(
|
|
133
|
+
false
|
|
134
|
+
);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it("takes latest with smaller equal", async () => {
|
|
138
|
+
const wantedVersion = "latest";
|
|
139
|
+
const scVersion = "1.0.0-beta.6";
|
|
140
|
+
const plugin = {
|
|
141
|
+
location: "@saltcorn/html",
|
|
142
|
+
version: wantedVersion,
|
|
143
|
+
};
|
|
144
|
+
const pkgInfo = await npmFetch.json(
|
|
145
|
+
`https://registry.npmjs.org/${plugin.location}`
|
|
146
|
+
);
|
|
147
|
+
const sortedKeys = getSortedKeys(pkgInfo);
|
|
148
|
+
pkgInfo.versions[sortedKeys[0]].engines = { saltcorn: "<=1.0.0-beta.7" };
|
|
149
|
+
pkgInfo.versions[sortedKeys[1]].engines = { saltcorn: "<=1.0.0-beta.6" };
|
|
150
|
+
const result = supportedVersion(
|
|
151
|
+
plugin.version,
|
|
152
|
+
pkgInfo.versions,
|
|
153
|
+
scVersion
|
|
154
|
+
);
|
|
155
|
+
expect(result).toBe(sortedKeys[0]);
|
|
156
|
+
expect(isVersionSupported(result, pkgInfo.versions, scVersion)).toBe(true);
|
|
157
|
+
expect(isVersionSupported(sortedKeys[0], pkgInfo.versions, scVersion)).toBe(
|
|
158
|
+
true
|
|
159
|
+
);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it("resolves latest to the current version", async () => {
|
|
163
|
+
const wantedVersion = "latest";
|
|
164
|
+
const scVersion = "1.0.0-beta.6";
|
|
165
|
+
const plugin = {
|
|
166
|
+
location: "@saltcorn/html",
|
|
167
|
+
version: wantedVersion,
|
|
168
|
+
};
|
|
169
|
+
const pkgInfo = await npmFetch.json(
|
|
170
|
+
`https://registry.npmjs.org/${plugin.location}`
|
|
171
|
+
);
|
|
172
|
+
const sortedKeys = getSortedKeys(pkgInfo);
|
|
173
|
+
pkgInfo.versions[sortedKeys[0]].engines = { saltcorn: ">=1.0.0-beta.6" };
|
|
174
|
+
pkgInfo.versions[sortedKeys[1]].engines = { saltcorn: ">=1.0.0-beta.6" };
|
|
175
|
+
const result = supportedVersion(
|
|
176
|
+
plugin.version,
|
|
177
|
+
pkgInfo.versions,
|
|
178
|
+
scVersion
|
|
179
|
+
);
|
|
180
|
+
expect(result).toBe(sortedKeys[0]);
|
|
181
|
+
expect(isVersionSupported(result, pkgInfo.versions, scVersion)).toBe(true);
|
|
182
|
+
expect(isVersionSupported(sortedKeys[1], pkgInfo.versions, scVersion)).toBe(
|
|
183
|
+
true
|
|
184
|
+
);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it("it takes the latest version, all engine properties are missing", async () => {
|
|
188
|
+
const wantedVersion = "latest";
|
|
189
|
+
const scVersion = "1.0.0-beta.6";
|
|
190
|
+
const plugin = {
|
|
191
|
+
location: "@saltcorn/html",
|
|
192
|
+
version: wantedVersion,
|
|
193
|
+
};
|
|
194
|
+
const pkgInfo = await npmFetch.json(
|
|
195
|
+
`https://registry.npmjs.org/${plugin.location}`
|
|
196
|
+
);
|
|
197
|
+
const sortedKeys = getSortedKeys(pkgInfo);
|
|
198
|
+
for (const key of sortedKeys) pkgInfo.versions[key].engines = undefined;
|
|
199
|
+
const result = supportedVersion(
|
|
200
|
+
plugin.version,
|
|
201
|
+
pkgInfo.versions,
|
|
202
|
+
scVersion
|
|
203
|
+
);
|
|
204
|
+
expect(result).toBe(sortedKeys[0]);
|
|
205
|
+
expect(isVersionSupported(result, pkgInfo.versions, scVersion)).toBe(true);
|
|
206
|
+
expect(isVersionSupported(sortedKeys[1], pkgInfo.versions, scVersion)).toBe(
|
|
207
|
+
true
|
|
208
|
+
);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it("takes a version without the engines property", async () => {
|
|
212
|
+
const wantedVersion = "latest";
|
|
213
|
+
const scVersion = "1.0.0-beta.6";
|
|
214
|
+
const plugin = {
|
|
215
|
+
location: "@saltcorn/html",
|
|
216
|
+
version: wantedVersion,
|
|
217
|
+
};
|
|
218
|
+
const pkgInfo = await npmFetch.json(
|
|
219
|
+
`https://registry.npmjs.org/${plugin.location}`
|
|
220
|
+
);
|
|
221
|
+
const sortedKeys = getSortedKeys(pkgInfo);
|
|
222
|
+
pkgInfo.versions[sortedKeys[0]].engines = { saltcorn: ">=1.0.0-beta.7" };
|
|
223
|
+
pkgInfo.versions[sortedKeys[1]].engines = { saltcorn: ">=1.0.0-beta.7" };
|
|
224
|
+
pkgInfo.versions[sortedKeys[2]].engines = undefined;
|
|
225
|
+
const result = supportedVersion(
|
|
226
|
+
plugin.version,
|
|
227
|
+
pkgInfo.versions,
|
|
228
|
+
scVersion
|
|
229
|
+
);
|
|
230
|
+
expect(result).toBe(sortedKeys[2]);
|
|
231
|
+
expect(isVersionSupported(result, pkgInfo.versions, scVersion)).toBe(true);
|
|
232
|
+
expect(isVersionSupported(sortedKeys[0], pkgInfo.versions, scVersion)).toBe(
|
|
233
|
+
false
|
|
234
|
+
);
|
|
235
|
+
expect(isVersionSupported(sortedKeys[1], pkgInfo.versions, scVersion)).toBe(
|
|
236
|
+
false
|
|
237
|
+
);
|
|
238
|
+
expect(isVersionSupported(sortedKeys[2], pkgInfo.versions, scVersion)).toBe(
|
|
239
|
+
true
|
|
240
|
+
);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it("finds no supported version", async () => {
|
|
244
|
+
const wantedVersion = "latest";
|
|
245
|
+
const scVersion = "1.0.0-beta.6";
|
|
246
|
+
const plugin = {
|
|
247
|
+
location: "@saltcorn/html",
|
|
248
|
+
version: wantedVersion,
|
|
249
|
+
};
|
|
250
|
+
const pkgInfo = await npmFetch.json(
|
|
251
|
+
`https://registry.npmjs.org/${plugin.location}`
|
|
252
|
+
);
|
|
253
|
+
const sortedKeys = getSortedKeys(pkgInfo);
|
|
254
|
+
for (const key of sortedKeys)
|
|
255
|
+
pkgInfo.versions[key].engines = { saltcorn: ">=1.0.0-beta.7" };
|
|
256
|
+
const result = supportedVersion(
|
|
257
|
+
plugin.version,
|
|
258
|
+
pkgInfo.versions,
|
|
259
|
+
scVersion
|
|
260
|
+
);
|
|
261
|
+
expect(result).toBeNull();
|
|
262
|
+
});
|
|
263
|
+
});
|