@jsenv/core 41.4.23 → 41.4.24
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/dist/build/build.js +32 -11
- package/dist/js/dependency_status.js +34 -1
- package/dist/start_dev_server/start_dev_server.js +52 -16
- package/package.json +1 -1
- package/src/dev/start_dev_server.js +19 -5
- package/src/kitchen/package_dependencies.js +33 -11
- package/src/plugins/dependency_status/client/dependency_status.js +34 -1
package/dist/build/build.js
CHANGED
|
@@ -149,6 +149,13 @@ const jsenvCoreDirectoryUrl = new URL("../", import.meta.url);
|
|
|
149
149
|
* Only exact declared versions ("1.2.3") are compared: a range ("^1.2.3"), a
|
|
150
150
|
* file/workspace protocol or a tag cannot be checked without resolving what npm
|
|
151
151
|
* would pick, which is way beyond what is needed here.
|
|
152
|
+
*
|
|
153
|
+
* A status carries a severity so that every consumer (server log, browser
|
|
154
|
+
* overlay, reload on install) reads the same decision: a missing package or an
|
|
155
|
+
* outdated runtime dependency is a "warning", the page is not running what the
|
|
156
|
+
* project asks for. An outdated devDependency is only "info": the installed
|
|
157
|
+
* version runs, what may differ is tooling, and that is worth a line in the
|
|
158
|
+
* console, not a dialog nor a reload once installed.
|
|
152
159
|
*/
|
|
153
160
|
|
|
154
161
|
|
|
@@ -180,13 +187,14 @@ const readDependencyStatus = (
|
|
|
180
187
|
if (!packageJSON) {
|
|
181
188
|
return null;
|
|
182
189
|
}
|
|
183
|
-
const
|
|
184
|
-
if (!
|
|
190
|
+
const declaration = readDeclaration(packageJSON, packageName);
|
|
191
|
+
if (!declaration) {
|
|
185
192
|
return null;
|
|
186
193
|
}
|
|
187
194
|
return createStatus(packageDirectory, {
|
|
188
195
|
packageName,
|
|
189
|
-
declaredVersion,
|
|
196
|
+
declaredVersion: declaration.version,
|
|
197
|
+
declaredIn: declaration.field,
|
|
190
198
|
declaringDirectoryUrl,
|
|
191
199
|
declaredBy: packageJSON.name,
|
|
192
200
|
});
|
|
@@ -194,17 +202,25 @@ const readDependencyStatus = (
|
|
|
194
202
|
|
|
195
203
|
const createStatus = (
|
|
196
204
|
packageDirectory,
|
|
197
|
-
{
|
|
205
|
+
{
|
|
206
|
+
packageName,
|
|
207
|
+
declaredVersion,
|
|
208
|
+
declaredIn,
|
|
209
|
+
declaringDirectoryUrl,
|
|
210
|
+
declaredBy,
|
|
211
|
+
},
|
|
198
212
|
) => {
|
|
199
213
|
const status = {
|
|
200
214
|
packageName,
|
|
201
215
|
declaredVersion,
|
|
216
|
+
declaredIn,
|
|
202
217
|
declaredBy,
|
|
203
218
|
installedVersion: null,
|
|
204
219
|
// the file telling this dependency apart; it is what an install rewrites and
|
|
205
220
|
// what the dev server looks at to know the dependency became the declared one
|
|
206
221
|
watchedPath: null,
|
|
207
222
|
state: "missing",
|
|
223
|
+
severity: "warning",
|
|
208
224
|
};
|
|
209
225
|
const installedDirectoryUrl = findInstalledDirectoryUrl(
|
|
210
226
|
declaringDirectoryUrl,
|
|
@@ -226,11 +242,16 @@ const createStatus = (
|
|
|
226
242
|
status.installedVersion = installedPackageJSON
|
|
227
243
|
? installedPackageJSON.version
|
|
228
244
|
: null;
|
|
229
|
-
|
|
230
|
-
isExactVersion(declaredVersion)
|
|
231
|
-
status.installedVersion
|
|
232
|
-
|
|
233
|
-
|
|
245
|
+
if (
|
|
246
|
+
!isExactVersion(declaredVersion) ||
|
|
247
|
+
status.installedVersion === declaredVersion
|
|
248
|
+
) {
|
|
249
|
+
status.state = "installed";
|
|
250
|
+
status.severity = null;
|
|
251
|
+
return status;
|
|
252
|
+
}
|
|
253
|
+
status.state = "outdated";
|
|
254
|
+
status.severity = declaredIn === "devDependencies" ? "info" : "warning";
|
|
234
255
|
return status;
|
|
235
256
|
};
|
|
236
257
|
|
|
@@ -258,11 +279,11 @@ const findInstalledDirectoryUrl = (declaringDirectoryUrl, packageName) => {
|
|
|
258
279
|
return null;
|
|
259
280
|
};
|
|
260
281
|
|
|
261
|
-
const
|
|
282
|
+
const readDeclaration = (packageJSON, packageName) => {
|
|
262
283
|
for (const field of DEPENDENCY_FIELDS) {
|
|
263
284
|
const dependencies = packageJSON[field];
|
|
264
285
|
if (dependencies && dependencies[packageName]) {
|
|
265
|
-
return dependencies[packageName];
|
|
286
|
+
return { field, version: dependencies[packageName] };
|
|
266
287
|
}
|
|
267
288
|
}
|
|
268
289
|
return null;
|
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
* A missing dependency is not handled here: it makes the import fail, so the
|
|
5
5
|
* error overlay already says it, with more precision (which import, where).
|
|
6
6
|
*
|
|
7
|
+
* The overlay is for the problems the server marks as "warning" (see severity
|
|
8
|
+
* in package_dependencies.js). An outdated devDependency is "info": it goes to
|
|
9
|
+
* the console as a line, said once, followed by an other line when it gets
|
|
10
|
+
* installed; no overlay, and the server does not reload the page for it.
|
|
11
|
+
*
|
|
7
12
|
* The overlay does not only describe the problem, it shows the dev server
|
|
8
13
|
* watching for the fix: the paths being looked at are named and kept alive on
|
|
9
14
|
* screen, so waiting for "npm install" feels like waiting for something that is
|
|
@@ -16,6 +21,9 @@ let watchInfoFromServer = {};
|
|
|
16
21
|
// what leaves this map has been installed while the overlay was open, which is
|
|
17
22
|
// worth showing as such
|
|
18
23
|
const outdatedPathMap = new Map();
|
|
24
|
+
// the console is append-only: a problem is said when it appears or changes,
|
|
25
|
+
// and its resolution when it leaves the list
|
|
26
|
+
const consoleLineMap = new Map();
|
|
19
27
|
|
|
20
28
|
const initDependencyStatus = ({ problems, watchInfo }) => {
|
|
21
29
|
watchInfoFromServer = watchInfo || {};
|
|
@@ -32,7 +40,10 @@ const initDependencyStatus = ({ problems, watchInfo }) => {
|
|
|
32
40
|
};
|
|
33
41
|
|
|
34
42
|
const render = (problems) => {
|
|
35
|
-
|
|
43
|
+
logInfoProblems(problems.filter(({ severity }) => severity === "info"));
|
|
44
|
+
const outdatedList = problems.filter(
|
|
45
|
+
({ state, severity }) => state === "outdated" && severity === "warning",
|
|
46
|
+
);
|
|
36
47
|
removeOverlay();
|
|
37
48
|
removeOverlay = () => {};
|
|
38
49
|
const installedList = [];
|
|
@@ -67,6 +78,28 @@ const render = (problems) => {
|
|
|
67
78
|
});
|
|
68
79
|
};
|
|
69
80
|
|
|
81
|
+
const logInfoProblems = (infoList) => {
|
|
82
|
+
for (const problem of infoList) {
|
|
83
|
+
const { packageName, declaredIn, declaredVersion, installedVersion } =
|
|
84
|
+
problem;
|
|
85
|
+
const line = `[jsenv] "${packageName}" is installed in ${
|
|
86
|
+
installedVersion || "an unknown version"
|
|
87
|
+
} but package.json declares ${declaredVersion} in ${declaredIn}, run npm install`;
|
|
88
|
+
if (consoleLineMap.get(packageName) === line) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
consoleLineMap.set(packageName, line);
|
|
92
|
+
console.info(line);
|
|
93
|
+
}
|
|
94
|
+
for (const packageName of consoleLineMap.keys()) {
|
|
95
|
+
if (infoList.some((problem) => problem.packageName === packageName)) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
consoleLineMap.delete(packageName);
|
|
99
|
+
console.info(`[jsenv] "${packageName}" is now installed`);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
70
103
|
const describe = ({ packageName, declaredVersion, installedVersion }) => {
|
|
71
104
|
return `${packageName}
|
|
72
105
|
package.json declares ${declaredVersion}
|
|
@@ -62,6 +62,13 @@ const createEventEmitter = () => {
|
|
|
62
62
|
* Only exact declared versions ("1.2.3") are compared: a range ("^1.2.3"), a
|
|
63
63
|
* file/workspace protocol or a tag cannot be checked without resolving what npm
|
|
64
64
|
* would pick, which is way beyond what is needed here.
|
|
65
|
+
*
|
|
66
|
+
* A status carries a severity so that every consumer (server log, browser
|
|
67
|
+
* overlay, reload on install) reads the same decision: a missing package or an
|
|
68
|
+
* outdated runtime dependency is a "warning", the page is not running what the
|
|
69
|
+
* project asks for. An outdated devDependency is only "info": the installed
|
|
70
|
+
* version runs, what may differ is tooling, and that is worth a line in the
|
|
71
|
+
* console, not a dialog nor a reload once installed.
|
|
65
72
|
*/
|
|
66
73
|
|
|
67
74
|
|
|
@@ -93,13 +100,14 @@ const readDependencyStatus = (
|
|
|
93
100
|
if (!packageJSON) {
|
|
94
101
|
return null;
|
|
95
102
|
}
|
|
96
|
-
const
|
|
97
|
-
if (!
|
|
103
|
+
const declaration = readDeclaration(packageJSON, packageName);
|
|
104
|
+
if (!declaration) {
|
|
98
105
|
return null;
|
|
99
106
|
}
|
|
100
107
|
return createStatus(packageDirectory, {
|
|
101
108
|
packageName,
|
|
102
|
-
declaredVersion,
|
|
109
|
+
declaredVersion: declaration.version,
|
|
110
|
+
declaredIn: declaration.field,
|
|
103
111
|
declaringDirectoryUrl,
|
|
104
112
|
declaredBy: packageJSON.name,
|
|
105
113
|
});
|
|
@@ -126,6 +134,7 @@ const readDependencyStatuses = (packageDirectory) => {
|
|
|
126
134
|
createStatus(packageDirectory, {
|
|
127
135
|
packageName,
|
|
128
136
|
declaredVersion: dependencies[packageName],
|
|
137
|
+
declaredIn: field,
|
|
129
138
|
declaringDirectoryUrl: packageDirectory.url,
|
|
130
139
|
declaredBy: packageJSON.name,
|
|
131
140
|
}),
|
|
@@ -137,17 +146,25 @@ const readDependencyStatuses = (packageDirectory) => {
|
|
|
137
146
|
|
|
138
147
|
const createStatus = (
|
|
139
148
|
packageDirectory,
|
|
140
|
-
{
|
|
149
|
+
{
|
|
150
|
+
packageName,
|
|
151
|
+
declaredVersion,
|
|
152
|
+
declaredIn,
|
|
153
|
+
declaringDirectoryUrl,
|
|
154
|
+
declaredBy,
|
|
155
|
+
},
|
|
141
156
|
) => {
|
|
142
157
|
const status = {
|
|
143
158
|
packageName,
|
|
144
159
|
declaredVersion,
|
|
160
|
+
declaredIn,
|
|
145
161
|
declaredBy,
|
|
146
162
|
installedVersion: null,
|
|
147
163
|
// the file telling this dependency apart; it is what an install rewrites and
|
|
148
164
|
// what the dev server looks at to know the dependency became the declared one
|
|
149
165
|
watchedPath: null,
|
|
150
166
|
state: "missing",
|
|
167
|
+
severity: "warning",
|
|
151
168
|
};
|
|
152
169
|
const installedDirectoryUrl = findInstalledDirectoryUrl(
|
|
153
170
|
declaringDirectoryUrl,
|
|
@@ -169,11 +186,16 @@ const createStatus = (
|
|
|
169
186
|
status.installedVersion = installedPackageJSON
|
|
170
187
|
? installedPackageJSON.version
|
|
171
188
|
: null;
|
|
172
|
-
|
|
173
|
-
isExactVersion(declaredVersion)
|
|
174
|
-
status.installedVersion
|
|
175
|
-
|
|
176
|
-
|
|
189
|
+
if (
|
|
190
|
+
!isExactVersion(declaredVersion) ||
|
|
191
|
+
status.installedVersion === declaredVersion
|
|
192
|
+
) {
|
|
193
|
+
status.state = "installed";
|
|
194
|
+
status.severity = null;
|
|
195
|
+
return status;
|
|
196
|
+
}
|
|
197
|
+
status.state = "outdated";
|
|
198
|
+
status.severity = declaredIn === "devDependencies" ? "info" : "warning";
|
|
177
199
|
return status;
|
|
178
200
|
};
|
|
179
201
|
|
|
@@ -201,11 +223,11 @@ const findInstalledDirectoryUrl = (declaringDirectoryUrl, packageName) => {
|
|
|
201
223
|
return null;
|
|
202
224
|
};
|
|
203
225
|
|
|
204
|
-
const
|
|
226
|
+
const readDeclaration = (packageJSON, packageName) => {
|
|
205
227
|
for (const field of DEPENDENCY_FIELDS) {
|
|
206
228
|
const dependencies = packageJSON[field];
|
|
207
229
|
if (dependencies && dependencies[packageName]) {
|
|
208
|
-
return dependencies[packageName];
|
|
230
|
+
return { field, version: dependencies[packageName] };
|
|
209
231
|
}
|
|
210
232
|
}
|
|
211
233
|
return null;
|
|
@@ -12152,15 +12174,29 @@ const startDevServer = async ({
|
|
|
12152
12174
|
onChange: (problems) => {
|
|
12153
12175
|
dependencyProblemEventEmitter.emit(problems);
|
|
12154
12176
|
},
|
|
12155
|
-
onProblem: ({
|
|
12156
|
-
|
|
12177
|
+
onProblem: ({
|
|
12178
|
+
packageName,
|
|
12179
|
+
declaredVersion,
|
|
12180
|
+
installedVersion,
|
|
12181
|
+
declaredIn,
|
|
12182
|
+
state,
|
|
12183
|
+
severity,
|
|
12184
|
+
}) => {
|
|
12185
|
+
const message =
|
|
12157
12186
|
state === "missing"
|
|
12158
12187
|
? `"${packageName}@${declaredVersion}" is declared in package.json but not installed, run npm install`
|
|
12159
|
-
: `"${packageName}" is installed in ${installedVersion} but package.json declares ${declaredVersion}, run npm install
|
|
12160
|
-
)
|
|
12188
|
+
: `"${packageName}" is installed in ${installedVersion} but package.json declares ${declaredVersion} in ${declaredIn}, run npm install`;
|
|
12189
|
+
if (severity === "warning") {
|
|
12190
|
+
logger.warn(message);
|
|
12191
|
+
} else {
|
|
12192
|
+
logger.info(message);
|
|
12193
|
+
}
|
|
12161
12194
|
},
|
|
12162
|
-
onInstalled: ({ packageName, declaredVersion }) => {
|
|
12195
|
+
onInstalled: ({ packageName, declaredVersion, severity }) => {
|
|
12163
12196
|
logger.info(`"${packageName}@${declaredVersion}" is now installed`);
|
|
12197
|
+
if (severity !== "warning") {
|
|
12198
|
+
return;
|
|
12199
|
+
}
|
|
12164
12200
|
reloadRequestEventEmitter.emit({
|
|
12165
12201
|
cause: `${packageName}@${declaredVersion} installed`,
|
|
12166
12202
|
reason: `a dependency became available in node_modules`,
|
package/package.json
CHANGED
|
@@ -220,15 +220,29 @@ export const startDevServer = async ({
|
|
|
220
220
|
onChange: (problems) => {
|
|
221
221
|
dependencyProblemEventEmitter.emit(problems);
|
|
222
222
|
},
|
|
223
|
-
onProblem: ({
|
|
224
|
-
|
|
223
|
+
onProblem: ({
|
|
224
|
+
packageName,
|
|
225
|
+
declaredVersion,
|
|
226
|
+
installedVersion,
|
|
227
|
+
declaredIn,
|
|
228
|
+
state,
|
|
229
|
+
severity,
|
|
230
|
+
}) => {
|
|
231
|
+
const message =
|
|
225
232
|
state === "missing"
|
|
226
233
|
? `"${packageName}@${declaredVersion}" is declared in package.json but not installed, run npm install`
|
|
227
|
-
: `"${packageName}" is installed in ${installedVersion} but package.json declares ${declaredVersion}, run npm install
|
|
228
|
-
)
|
|
234
|
+
: `"${packageName}" is installed in ${installedVersion} but package.json declares ${declaredVersion} in ${declaredIn}, run npm install`;
|
|
235
|
+
if (severity === "warning") {
|
|
236
|
+
logger.warn(message);
|
|
237
|
+
} else {
|
|
238
|
+
logger.info(message);
|
|
239
|
+
}
|
|
229
240
|
},
|
|
230
|
-
onInstalled: ({ packageName, declaredVersion }) => {
|
|
241
|
+
onInstalled: ({ packageName, declaredVersion, severity }) => {
|
|
231
242
|
logger.info(`"${packageName}@${declaredVersion}" is now installed`);
|
|
243
|
+
if (severity !== "warning") {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
232
246
|
reloadRequestEventEmitter.emit({
|
|
233
247
|
cause: `${packageName}@${declaredVersion} installed`,
|
|
234
248
|
reason: `a dependency became available in node_modules`,
|
|
@@ -10,6 +10,13 @@
|
|
|
10
10
|
* Only exact declared versions ("1.2.3") are compared: a range ("^1.2.3"), a
|
|
11
11
|
* file/workspace protocol or a tag cannot be checked without resolving what npm
|
|
12
12
|
* would pick, which is way beyond what is needed here.
|
|
13
|
+
*
|
|
14
|
+
* A status carries a severity so that every consumer (server log, browser
|
|
15
|
+
* overlay, reload on install) reads the same decision: a missing package or an
|
|
16
|
+
* outdated runtime dependency is a "warning", the page is not running what the
|
|
17
|
+
* project asks for. An outdated devDependency is only "info": the installed
|
|
18
|
+
* version runs, what may differ is tooling, and that is worth a line in the
|
|
19
|
+
* console, not a dialog nor a reload once installed.
|
|
13
20
|
*/
|
|
14
21
|
|
|
15
22
|
import { urlToRelativeUrl } from "@jsenv/urls";
|
|
@@ -43,13 +50,14 @@ export const readDependencyStatus = (
|
|
|
43
50
|
if (!packageJSON) {
|
|
44
51
|
return null;
|
|
45
52
|
}
|
|
46
|
-
const
|
|
47
|
-
if (!
|
|
53
|
+
const declaration = readDeclaration(packageJSON, packageName);
|
|
54
|
+
if (!declaration) {
|
|
48
55
|
return null;
|
|
49
56
|
}
|
|
50
57
|
return createStatus(packageDirectory, {
|
|
51
58
|
packageName,
|
|
52
|
-
declaredVersion,
|
|
59
|
+
declaredVersion: declaration.version,
|
|
60
|
+
declaredIn: declaration.field,
|
|
53
61
|
declaringDirectoryUrl,
|
|
54
62
|
declaredBy: packageJSON.name,
|
|
55
63
|
});
|
|
@@ -76,6 +84,7 @@ export const readDependencyStatuses = (packageDirectory) => {
|
|
|
76
84
|
createStatus(packageDirectory, {
|
|
77
85
|
packageName,
|
|
78
86
|
declaredVersion: dependencies[packageName],
|
|
87
|
+
declaredIn: field,
|
|
79
88
|
declaringDirectoryUrl: packageDirectory.url,
|
|
80
89
|
declaredBy: packageJSON.name,
|
|
81
90
|
}),
|
|
@@ -87,17 +96,25 @@ export const readDependencyStatuses = (packageDirectory) => {
|
|
|
87
96
|
|
|
88
97
|
const createStatus = (
|
|
89
98
|
packageDirectory,
|
|
90
|
-
{
|
|
99
|
+
{
|
|
100
|
+
packageName,
|
|
101
|
+
declaredVersion,
|
|
102
|
+
declaredIn,
|
|
103
|
+
declaringDirectoryUrl,
|
|
104
|
+
declaredBy,
|
|
105
|
+
},
|
|
91
106
|
) => {
|
|
92
107
|
const status = {
|
|
93
108
|
packageName,
|
|
94
109
|
declaredVersion,
|
|
110
|
+
declaredIn,
|
|
95
111
|
declaredBy,
|
|
96
112
|
installedVersion: null,
|
|
97
113
|
// the file telling this dependency apart; it is what an install rewrites and
|
|
98
114
|
// what the dev server looks at to know the dependency became the declared one
|
|
99
115
|
watchedPath: null,
|
|
100
116
|
state: "missing",
|
|
117
|
+
severity: "warning",
|
|
101
118
|
};
|
|
102
119
|
const installedDirectoryUrl = findInstalledDirectoryUrl(
|
|
103
120
|
declaringDirectoryUrl,
|
|
@@ -119,11 +136,16 @@ const createStatus = (
|
|
|
119
136
|
status.installedVersion = installedPackageJSON
|
|
120
137
|
? installedPackageJSON.version
|
|
121
138
|
: null;
|
|
122
|
-
|
|
123
|
-
isExactVersion(declaredVersion)
|
|
124
|
-
status.installedVersion
|
|
125
|
-
|
|
126
|
-
|
|
139
|
+
if (
|
|
140
|
+
!isExactVersion(declaredVersion) ||
|
|
141
|
+
status.installedVersion === declaredVersion
|
|
142
|
+
) {
|
|
143
|
+
status.state = "installed";
|
|
144
|
+
status.severity = null;
|
|
145
|
+
return status;
|
|
146
|
+
}
|
|
147
|
+
status.state = "outdated";
|
|
148
|
+
status.severity = declaredIn === "devDependencies" ? "info" : "warning";
|
|
127
149
|
return status;
|
|
128
150
|
};
|
|
129
151
|
|
|
@@ -151,11 +173,11 @@ const findInstalledDirectoryUrl = (declaringDirectoryUrl, packageName) => {
|
|
|
151
173
|
return null;
|
|
152
174
|
};
|
|
153
175
|
|
|
154
|
-
const
|
|
176
|
+
const readDeclaration = (packageJSON, packageName) => {
|
|
155
177
|
for (const field of DEPENDENCY_FIELDS) {
|
|
156
178
|
const dependencies = packageJSON[field];
|
|
157
179
|
if (dependencies && dependencies[packageName]) {
|
|
158
|
-
return dependencies[packageName];
|
|
180
|
+
return { field, version: dependencies[packageName] };
|
|
159
181
|
}
|
|
160
182
|
}
|
|
161
183
|
return null;
|
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
* A missing dependency is not handled here: it makes the import fail, so the
|
|
5
5
|
* error overlay already says it, with more precision (which import, where).
|
|
6
6
|
*
|
|
7
|
+
* The overlay is for the problems the server marks as "warning" (see severity
|
|
8
|
+
* in package_dependencies.js). An outdated devDependency is "info": it goes to
|
|
9
|
+
* the console as a line, said once, followed by an other line when it gets
|
|
10
|
+
* installed; no overlay, and the server does not reload the page for it.
|
|
11
|
+
*
|
|
7
12
|
* The overlay does not only describe the problem, it shows the dev server
|
|
8
13
|
* watching for the fix: the paths being looked at are named and kept alive on
|
|
9
14
|
* screen, so waiting for "npm install" feels like waiting for something that is
|
|
@@ -16,6 +21,9 @@ let watchInfoFromServer = {};
|
|
|
16
21
|
// what leaves this map has been installed while the overlay was open, which is
|
|
17
22
|
// worth showing as such
|
|
18
23
|
const outdatedPathMap = new Map();
|
|
24
|
+
// the console is append-only: a problem is said when it appears or changes,
|
|
25
|
+
// and its resolution when it leaves the list
|
|
26
|
+
const consoleLineMap = new Map();
|
|
19
27
|
|
|
20
28
|
export const initDependencyStatus = ({ problems, watchInfo }) => {
|
|
21
29
|
watchInfoFromServer = watchInfo || {};
|
|
@@ -32,7 +40,10 @@ export const initDependencyStatus = ({ problems, watchInfo }) => {
|
|
|
32
40
|
};
|
|
33
41
|
|
|
34
42
|
const render = (problems) => {
|
|
35
|
-
|
|
43
|
+
logInfoProblems(problems.filter(({ severity }) => severity === "info"));
|
|
44
|
+
const outdatedList = problems.filter(
|
|
45
|
+
({ state, severity }) => state === "outdated" && severity === "warning",
|
|
46
|
+
);
|
|
36
47
|
removeOverlay();
|
|
37
48
|
removeOverlay = () => {};
|
|
38
49
|
const installedList = [];
|
|
@@ -67,6 +78,28 @@ const render = (problems) => {
|
|
|
67
78
|
});
|
|
68
79
|
};
|
|
69
80
|
|
|
81
|
+
const logInfoProblems = (infoList) => {
|
|
82
|
+
for (const problem of infoList) {
|
|
83
|
+
const { packageName, declaredIn, declaredVersion, installedVersion } =
|
|
84
|
+
problem;
|
|
85
|
+
const line = `[jsenv] "${packageName}" is installed in ${
|
|
86
|
+
installedVersion || "an unknown version"
|
|
87
|
+
} but package.json declares ${declaredVersion} in ${declaredIn}, run npm install`;
|
|
88
|
+
if (consoleLineMap.get(packageName) === line) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
consoleLineMap.set(packageName, line);
|
|
92
|
+
console.info(line);
|
|
93
|
+
}
|
|
94
|
+
for (const packageName of consoleLineMap.keys()) {
|
|
95
|
+
if (infoList.some((problem) => problem.packageName === packageName)) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
consoleLineMap.delete(packageName);
|
|
99
|
+
console.info(`[jsenv] "${packageName}" is now installed`);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
70
103
|
const describe = ({ packageName, declaredVersion, installedVersion }) => {
|
|
71
104
|
return `${packageName}
|
|
72
105
|
package.json declares ${declaredVersion}
|