Skip to content

Commit 286d75e

Browse files
authored
feat(ui): Dependencies view (vuejs#1740)
* fix(ui): chrome bug: grid element overflow https://bugs.chromium.org/p/chromium/issues/detail?id=833837 * feat(ui): dependencies view * feat(ui): filter deps
1 parent 6bc5d72 commit 286d75e

27 files changed

+1067
-165
lines changed
Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
const fs = require('fs')
2+
const path = require('path')
3+
const LRU = require('lru-cache')
4+
const semver = require('semver')
5+
// Connectors
6+
const cwd = require('./cwd')
7+
const folders = require('./folders')
8+
const progress = require('./progress')
9+
const logs = require('./logs')
10+
// Context
11+
const getContext = require('../context')
12+
// Utils
13+
const { isPlugin } = require('@vue/cli-shared-utils')
14+
const { resolveModule } = require('@vue/cli/lib/util/module')
15+
const getPackageVersion = require('@vue/cli/lib/util/getPackageVersion')
16+
const {
17+
progress: installProgress,
18+
installPackage,
19+
uninstallPackage,
20+
updatePackage
21+
} = require('@vue/cli/lib/util/installDeps')
22+
const { getCommand } = require('../util/command')
23+
const { resolveModuleRoot } = require('../util/resolve-path')
24+
const { notify } = require('../util/notification')
25+
26+
const PROGRESS_ID = 'dependency-installation'
27+
const CLI_SERVICE = '@vue/cli-service'
28+
29+
// Caches
30+
const metadataCache = new LRU({
31+
max: 200,
32+
maxAge: 1000 * 60 * 30 // 30 min.
33+
})
34+
35+
// Local
36+
let dependencies
37+
38+
function list (file, context) {
39+
const pkg = folders.readPackage(file, context)
40+
dependencies = []
41+
dependencies = dependencies.concat(
42+
findDependencies(pkg.devDependencies || {}, 'devDependencies', context)
43+
)
44+
dependencies = dependencies.concat(
45+
findDependencies(pkg.dependencies || {}, 'dependencies', context)
46+
)
47+
return dependencies
48+
}
49+
50+
function findOne (id, context) {
51+
return dependencies.find(
52+
p => p.id === id
53+
)
54+
}
55+
56+
function findDependencies (deps, type, context) {
57+
return Object.keys(deps).filter(
58+
id => !isPlugin(id) && id !== CLI_SERVICE
59+
).map(
60+
id => ({
61+
id,
62+
versionRange: deps[id],
63+
installed: fs.existsSync(getPath(id)),
64+
website: getLink(id, context),
65+
type
66+
})
67+
)
68+
}
69+
70+
function getPath (id) {
71+
return resolveModuleRoot(resolveModule(path.join(id, 'package.json'), cwd.get()), id)
72+
}
73+
74+
function readPackage (id, context) {
75+
try {
76+
return folders.readPackage(getPath(id), context)
77+
} catch (e) {
78+
console.log(e)
79+
}
80+
return {}
81+
}
82+
83+
function invalidatePackage (id, context) {
84+
return folders.invalidatePackage(getPath(id), context)
85+
}
86+
87+
async function getVersion ({ id, installed, versionRange }, context) {
88+
let current
89+
if (installed) {
90+
const pkg = readPackage(id, context)
91+
current = pkg.version
92+
} else {
93+
current = null
94+
}
95+
let latest, wanted
96+
const metadata = await getMetadata(id, context)
97+
if (metadata) {
98+
latest = metadata['dist-tags'].latest
99+
100+
const versions = Object.keys(metadata.versions)
101+
wanted = semver.maxSatisfying(versions, versionRange)
102+
}
103+
104+
if (!latest) latest = current
105+
if (!wanted) wanted = current
106+
107+
return {
108+
current,
109+
latest,
110+
wanted,
111+
range: versionRange
112+
}
113+
}
114+
115+
async function getDescription ({ id }, context) {
116+
const metadata = await getMetadata(id, context)
117+
if (metadata) {
118+
return metadata.description
119+
}
120+
return null
121+
}
122+
123+
async function getMetadata (id, context) {
124+
let metadata = metadataCache.get(id)
125+
if (metadata) {
126+
return metadata
127+
}
128+
129+
const res = await getPackageVersion(id)
130+
if (res.statusCode === 200) {
131+
metadata = res.body
132+
}
133+
134+
if (metadata) {
135+
metadataCache.set(id, metadata)
136+
return metadata
137+
}
138+
}
139+
140+
function getLink (id, context) {
141+
const pkg = readPackage(id, context)
142+
return pkg.homepage ||
143+
(pkg.repository && pkg.repository.url) ||
144+
`https://www.npmjs.com/package/${id.replace(`/`, `%2F`)}`
145+
}
146+
147+
function install ({ id, type }, context) {
148+
return progress.wrap(PROGRESS_ID, context, async setProgress => {
149+
setProgress({
150+
status: 'dependency-install',
151+
args: [id]
152+
})
153+
await installPackage(cwd.get(), getCommand(), null, id, type === 'devDependencies')
154+
155+
logs.add({
156+
message: `Dependency ${id} installed`,
157+
type: 'info'
158+
}, context)
159+
160+
notify({
161+
title: `Dependency installed`,
162+
message: `Dependency ${id} successfully installed`,
163+
icon: 'done'
164+
})
165+
166+
list(cwd.get(), context)
167+
168+
return findOne(id, context)
169+
})
170+
}
171+
172+
function uninstall ({ id }, context) {
173+
return progress.wrap(PROGRESS_ID, context, async setProgress => {
174+
setProgress({
175+
status: 'dependency-uninstall',
176+
args: [id]
177+
})
178+
179+
const dep = findOne(id, context)
180+
181+
await uninstallPackage(cwd.get(), getCommand(), null, id)
182+
183+
logs.add({
184+
message: `Dependency ${id} uninstalled`,
185+
type: 'info'
186+
}, context)
187+
188+
notify({
189+
title: `Dependency uninstalled`,
190+
message: `Dependency ${id} successfully uninstalled`,
191+
icon: 'done'
192+
})
193+
194+
return dep
195+
})
196+
}
197+
198+
function update ({ id }, context) {
199+
return progress.wrap(PROGRESS_ID, context, async setProgress => {
200+
setProgress({
201+
status: 'dependency-update',
202+
args: [id]
203+
})
204+
205+
const dep = findOne(id, context)
206+
const { current, wanted } = await getVersion(dep, context)
207+
await updatePackage(cwd.get(), getCommand(), null, id)
208+
209+
logs.add({
210+
message: `Dependency ${id} updated from ${current} to ${wanted}`,
211+
type: 'info'
212+
}, context)
213+
214+
notify({
215+
title: `Dependency updated`,
216+
message: `Dependency ${id} was successfully updated`,
217+
icon: 'done'
218+
})
219+
220+
invalidatePackage(id)
221+
222+
return findOne(id)
223+
})
224+
}
225+
226+
function updateAll (context) {
227+
return progress.wrap(PROGRESS_ID, context, async setProgress => {
228+
const deps = list(cwd.get(), context)
229+
let updatedDeps = []
230+
for (const dep of deps) {
231+
const version = await getVersion(dep, context)
232+
if (version.current !== version.wanted) {
233+
updatedDeps.push(dep)
234+
invalidatePackage(dep.id, context)
235+
}
236+
}
237+
238+
if (!updatedDeps.length) {
239+
notify({
240+
title: `No updates available`,
241+
message: `No dependency to update in the version ranges declared in package.json`,
242+
icon: 'done'
243+
})
244+
return []
245+
}
246+
247+
setProgress({
248+
status: 'dependencies-update',
249+
args: [updatedDeps.length]
250+
})
251+
252+
await updatePackage(cwd.get(), getCommand(), null, updatedDeps.map(
253+
p => p.id
254+
).join(' '))
255+
256+
notify({
257+
title: `Dependencies updated`,
258+
message: `${updatedDeps.length} dependencies were successfully updated`,
259+
icon: 'done'
260+
})
261+
262+
return updatedDeps
263+
})
264+
}
265+
266+
function setup (context) {
267+
// Package installation progress events
268+
installProgress.on('progress', value => {
269+
if (progress.get(PROGRESS_ID)) {
270+
progress.set({ id: PROGRESS_ID, progress: value }, context)
271+
}
272+
})
273+
installProgress.on('log', message => {
274+
if (progress.get(PROGRESS_ID)) {
275+
progress.set({ id: PROGRESS_ID, info: message }, context)
276+
}
277+
})
278+
}
279+
280+
setup(getContext())
281+
282+
module.exports = {
283+
list,
284+
findOne,
285+
getPath,
286+
getMetadata,
287+
getLink,
288+
getDescription,
289+
getVersion,
290+
install,
291+
uninstall,
292+
update,
293+
updateAll,
294+
invalidatePackage
295+
}

packages/@vue/cli-ui/apollo-server/connectors/folders.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,12 @@ function writePackage ({ file, data }, context) {
109109
fs.outputJsonSync(path.join(file, 'package.json'), data, {
110110
spaces: 2
111111
})
112+
invalidatePackage(file)
113+
return true
114+
}
115+
116+
function invalidatePackage (file, context) {
117+
pkgCache.del(file)
112118
return true
113119
}
114120

@@ -165,6 +171,7 @@ module.exports = {
165171
isPackage,
166172
readPackage,
167173
writePackage,
174+
invalidatePackage,
168175
isVueProject,
169176
isFavorite,
170177
listFavorite,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy