module.exports = api => { const { registerWidget, onAction, setSharedData } = api.namespace('org.vue.widgets.') if (process.env.VUE_APP_CLI_UI_DEV) { api.addClientAddon({ id: 'org.vue.widgets.client-addon.dev', url: 'http://localhost:8097/index.js' }) } else { api.addClientAddon({ id: 'org.vue.widgets.client-addon', path: '@vue/cli-ui-addon-widgets/dist' }) } // Welcome widget registerWidget({ id: 'welcome', title: 'org.vue.widgets.welcome.title', description: 'org.vue.widgets.welcome.description', icon: 'mood', component: 'org.vue.widgets.components.welcome', minWidth: 3, minHeight: 4, maxWidth: 3, maxHeight: 4, maxCount: 1 }) // Kill port widget registerWidget({ id: 'kill-port', title: 'org.vue.widgets.kill-port.title', description: 'org.vue.widgets.kill-port.description', icon: 'flash_on', component: 'org.vue.widgets.components.kill-port', minWidth: 2, minHeight: 1, maxWidth: 2, maxHeight: 1, maxCount: 1 }) setSharedData('kill-port.status', 'idle') onAction('actions.kill-port', async params => { const fkill = require('fkill') setSharedData('kill-port.status', 'killing') try { await fkill(`:${params.port}`) setSharedData('kill-port.status', 'killed') } catch (e) { console.log(e) setSharedData('kill-port.status', 'error') } }) // Plugin updates setSharedData('plugin-updates.status', { status: 'ok', lastUpdate: Date.now() }) registerWidget({ id: 'plugin-updates', title: 'org.vue.widgets.plugin-updates.title', description: 'org.vue.widgets.plugin-updates.description', icon: 'extension', component: 'org.vue.widgets.components.plugin-updates', minWidth: 2, minHeight: 1, maxWidth: 2, maxHeight: 1, maxCount: 1 }) // Dependency updates setSharedData('dependency-updates.status', { status: 'loading', lastUpdate: null }) registerWidget({ id: 'dependency-updates', title: 'org.vue.widgets.dependency-updates.title', description: 'org.vue.widgets.dependency-updates.description', icon: 'collections_bookmark', component: 'org.vue.widgets.components.dependency-updates', minWidth: 2, minHeight: 1, maxWidth: 2, maxHeight: 1, maxCount: 1 }) // Vulnerability check let lastAudit = null setSharedData('vulnerability.status', { status: 'loading', lastUpdate: lastAudit, count: 0, message: null }) setSharedData('vulnerability.details', { vulnerabilities: [], summary: {} }) registerWidget({ id: 'vulnerability', title: 'org.vue.widgets.vulnerability.title', description: 'org.vue.widgets.vulnerability.description', icon: 'verified_user', component: 'org.vue.widgets.components.vulnerability', detailsComponent: 'org.vue.widgets.components.vulnerability-details', minWidth: 2, minHeight: 1, maxWidth: 2, maxHeight: 1, maxCount: 1 }) async function checkVulnerability (params) { setSharedData('vulnerability.status', { status: 'loading', lastUpdate: lastAudit, count: 0, message: null }) const { auditProject } = require('./utils/audit') const { status, details } = await auditProject(api.getCwd()) status.lastUpdate = lastAudit = Date.now() setSharedData('vulnerability.status', status) setSharedData('vulnerability.details', details) } onAction('actions.check-vunerability', checkVulnerability) checkVulnerability() // Run task registerWidget({ id: 'run-task', title: 'org.vue.widgets.run-task.title', description: 'org.vue.widgets.run-task.description', icon: 'assignment', component: 'org.vue.widgets.components.run-task', minWidth: 2, minHeight: 1, maxWidth: 2, maxHeight: 1, needsUserConfig: true, onConfigOpen: async ({ context }) => { const tasks = require('@vue/cli-ui/apollo-server/connectors/tasks') return { prompts: [ { name: 'task', type: 'list', message: 'org.vue.widgets.run-task.prompts.task', choices: (await tasks.list(undefined, context)).map(task => ({ name: task.name, value: task.id })) } ] } } }) // News registerWidget({ id: 'news', title: 'org.vue.widgets.news.title', description: 'org.vue.widgets.news.description', icon: 'rss_feed', component: 'org.vue.widgets.components.news', detailsComponent: 'org.vue.widgets.components.news', minWidth: 2, minHeight: 1, maxWidth: 6, maxHeight: 6, defaultWidth: 2, defaultHeight: 3, openDetailsButton: true, defaultConfig: () => ({ url: 'https://vuenews.fireside.fm/rss' }), onConfigOpen: async ({ context }) => { return { prompts: [ { name: 'url', type: 'input', message: 'org.vue.widgets.news.prompts.url', validate: input => !!input } ] } } }) const newsCache = global['org.vue.newsCache'] = global['org.vue.newsCache'] || {} let parser onAction('actions.fetch-news', async params => { if (!parser) { const Parser = require('rss-parser') parser = new Parser() } if (!params.force) { const cached = newsCache[params.url] if (cached) return cached } let url = params.url // GitHub repo if (url.match(/^[\w_.-]+\/[\w_.-]+$/)) { url = `https://github.com/${url}/releases.atom` } const result = await parser.parseURL(url) newsCache[params.url] = result return result }) }