Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

quasar-app-extension-qautomate

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

quasar-app-extension-qautomate - npm Package Compare versions

Comparing version 1.0.0-alpha.2 to 1.0.0-alpha.3

src/prompts.js

6

package.json
{
"name": "quasar-app-extension-qautomate",
"version": "1.0.0-alpha.2",
"description": "Automatically add components, directives and plugins to quasar.conf.js",
"version": "1.0.0-alpha.3",
"description": "Automatically add missing Quasar components, directives and plugins to quasar.conf.js",
"author": "webnoob <allangaunt@gmail.com>",

@@ -36,3 +36,5 @@ "license": "MIT",

"dependencies": {
"chalk": "^2.4.2",
"fs-extra": "^8.1.0",
"inquirer": "^6.4.1",
"param-case": "^2.1.1",

@@ -39,0 +41,0 @@ "ware-loader": "^0.2.4"

@@ -25,6 +25,5 @@ QAutomate

(yet to be implemented):
**Mode** [Automatic | Manual | Warn] - How QAutomate should behave when missing items are detected.
1. AutoFix - Whether or not the AE should auto add to the Quasar conf or just notify in console.
2. Manual Mode - Show a list of missing components / directives / plugins and allow you to select which ones to add.
**Sort** [True | False] - Should QAutomate sort the items in components, directives or plugins?

@@ -48,3 +47,3 @@ # Uninstall

# Patreon
# Support Us
If you like (and use) this App Extension, please consider becoming a Quasar [GH Sponsor](https://donate.quasar.dev).

@@ -9,4 +9,104 @@ /**

const QAutomate = require('./lib/QAutomate')
const chalk = require('chalk')
const inquirer = require('inquirer')
let qAutomate = null
class QAutomatePlugin {
constructor (api) {
this.quasarConfFixMode = api.prompts.quasarConfFixMode
}
apply(compiler) {
compiler.hooks.done.tap('done-compiling', async () => {
switch (this.quasarConfFixMode) {
case 'automatic':
// Needs a rework to get this working as the quasar.conf.js save on auto triggers a complete reload
// and we lose the stored value in our qAutomate class.
printSummary('bgGreen', 'Automatically added the following:')
qAutomate.applyChanges()
break
case 'warn':
printSummary('bgRed', 'Found missing items')
break
case 'manual':
await presentManualOptions()
break
}
// Write the buffer to console (gets cleared on HMR so handled internally)
qAutomate.writeLog()
// Reset the qAutomate instance for the next scan.
qAutomate.reset()
})
}
}
const presentManualOptions = () => {
return new Promise(resolve => {
const missingItems = qAutomate.getAnalysisResult().missing
let choices = []
for (let group in missingItems) {
choices.push(new inquirer.Separator(chalk`
{bgWhite {black ${group}}}
`))
for (let item of missingItems[group]) {
choices.push({
name: item
})
}
}
inquirer.prompt([
{
type: 'checkbox',
message: chalk`{bgGreen Select items to add to quasar.conf.js}`,
name: 'items',
choices: choices,
prefix: '',
pageSize: 20
}
]).then(answers => {
qAutomate.applyChanges(answers.items)
resolve()
})
console.log(`
`) // To add a line before the dev server message.
})
}
const printSummary = (colorStyle, msg) => {
const missingItems = qAutomate.getAnalysisResult().missing
if (Object.keys(missingItems).length > 0) {
qAutomate.addLog(chalk`{bold {${colorStyle} App Extension (qautomate) Info: ${msg}}}`)
}
for (let group in missingItems) {
qAutomate.addLog(chalk`
{bold {green ${group}}}`
)
for (let item of missingItems[group]) {
qAutomate.addLog(` ${item}`)
}
}
qAutomate.addLog(`
`)
}
const handlePromptType = (src, prompts) => {
switch (prompts.quasarConfFixMode) {
case 'automatic':
case 'manual':
default:
qAutomate.analyse(src)
return src
}
}
/**

@@ -19,3 +119,3 @@ * Setup a loader that will allow us to hook into file changes and get the source code.

const chainWebpack = function (api, chain, { isClient }) {
console.log(` App Extension (qautomate) Info: Hooking up loader for file component checks.`)
console.log(chalk` {green app:extension} Extension(qautomate): Hooking up loader for file component checks.`)
const rule = chain.module.rule('qautomate-vue')

@@ -31,3 +131,3 @@ .test(/\.(js|vue)$/)

raw: true,
middleware: src => qAutomate.run(src)
middleware: src => handlePromptType(src, api.prompts)
})

@@ -37,4 +137,12 @@ }

module.exports = function (api) {
qAutomate = new QAutomate(api)
qAutomate = new QAutomate(api, {
sort: api.prompts.sort
})
api.chainWebpack((chain, { isClient }) => chainWebpack(api, chain, isClient))
// Register a plugin with a hook for logging etc.
api.extendWebpack((cfg, { isClient, isServer }, api) => {
cfg.plugins.push(new QAutomatePlugin(api))
})
}

@@ -6,8 +6,31 @@ const path = require('path')

module.exports = class QAutomate {
constructor (api) {
constructor (api, options) {
this._api = api
this._whitelists = {}
this._quasarConfPath = path.join(this._api.appDir, 'quasar.conf.js')
this._quasarConf = require(this._quasarConfPath)(this._api.ctx)
this._quasarConfFileData = fs.readFileSync(this._quasarConfPath, 'utf8')
this._originalQuasarConfFileData = this._quasarConfFileData
this._options = options
this._forceApplyChanges = false
this.reset()
this.buildWhitelist()
}
reset () {
this._whitelists = {}
this._analysis = {
existing: {},
missing: {},
merged: {}
}
this.clearLog()
// If we're requiring changes to be saved, make sure they are before the reset happens.
if (this._forceApplyChanges) {
this.applyChanges()
}
}
/**

@@ -38,8 +61,7 @@ * Find the quasar package installed and build an allowed list of tags we can look for based on the API.json files.

* Scan the source template and get all the Quasar items
* NOTE: This is currently HTML only and won't support PUG.
* @param group
* @param source
* @param group - The type we're looking for i.e Components, Directives or Plugins.
* @param source - HTML / PUG / Text to scan
* @returns {string[]}
*/
getSourceItems (group, source) {
scanForSourceItems (group, source) {
const result = []

@@ -67,28 +89,4 @@ for (let wlItem of this._whitelists[group]) {

/**
* Receive a list of items for a given group to check and return a list of items that need to be added.
* @param group - i.e components, directives, plugins
* @param quasarConf - The actual conf file
* @param itemsInUseInSource - The current list of {group} items in use within the source file.
* @param quasarConfFileData - The string of file data from quasarconf file.
* @returns {*}
*/
getMissingGroupItems (group, quasarConf, itemsInUseInSource, quasarConfFileData) {
const missingItems = itemsInUseInSource.filter(e => !quasarConf.framework[group].includes(e))
if (missingItems.length > 0) {
let currentItems = this.getFrameworkGroup(group, quasarConfFileData)
for (let missingItem of missingItems) {
if (currentItems[group].indexOf(missingItem) === -1) {
console.log(` App Extension (qautomate) Info: Adding missing [${group}] to quasar.conf.js [${missingItem}]`)
currentItems[group].push(missingItem)
}
}
return currentItems
}
return itemsInUseInSource
}
/**
* Convert a list of items back into a format suitable for the quasar.conf.js file.
* TODO: There has to be a better way of doing this - quasar.conf.js is a function file so have parsed manually.
* @param group

@@ -98,4 +96,4 @@ * @param data

*/
stringifyConf (group, data) {
return JSON.stringify(data)
stringifyConfGroup (group, items) {
return JSON.stringify( { [group] : items })
.replace('{', '')

@@ -121,51 +119,128 @@ .replace('}', '')

/**
* Get a group section i.e `components: [ 'QInput' ]` from
* the quasar.conf.js file and return the array for processing.
* @param group
* @param fileData
* @returns {any}
* Analyse the source for missing items (items based on the type set in Quasar's api.json files)
* Eg: Components, Directives and Plugins
* @param source
* @returns {{}|*}
*/
getFrameworkGroup (group, fileData) {
let componentsGroup = fileData.match(this.getGroupRegex(group))[0]
componentsGroup = `{
${componentsGroup
.replace(group, `"${group}"`)
.replace(/'/g, '"')
analyse (source) {
// Loop through our groups we want to check and process them.
for (let group in this._whitelists) {
const sourceItems = this.scanForSourceItems(group, source)
// Build an array of missing items, grouped by type (i.e component, plugin, directive)
// without duplicates also taking into account the group might not have been initialised
// as an array.
const missingItems = sourceItems.filter(e =>
!this._quasarConf.framework[group].includes(e) &&
!(this._analysis.missing[group] || []).includes(e)
)
if (missingItems.length > 0) {
this._analysis.missing[group] = this.mergeArrays(this._analysis.missing[group], missingItems)
}
}`
return JSON.parse(componentsGroup)
this._analysis.existing[group] = this._quasarConf.framework[group]
this._analysis.merged[group] = this.mergeArrays(this._analysis.existing[group], this._analysis.missing[group])
// If sorting is enabled, check to see if we need to apply sorting.
// Then flag to force a save if reset is called before applyChanges()
if (this._options.sort) {
this._analysis.merged[group].sort()
// Using stringify here as as I know the data will always be an array.
if (JSON.stringify(this._analysis.existing[group]) !== JSON.stringify(this._analysis.merged[group])) {
this._forceApplyChanges = true
}
}
}
}
/**
* Find any components, directives or plugins in use in the source code that aren't contained
* in the quasar.conf.js file and add them in.
* @param source
* @param api
* Apply all the analysis results that have been run.
* @param analysisResult
* @returns {*}
*/
run (source) {
const
quasarConfPath = path.join(this._api.appDir, 'quasar.conf.js'),
quasarConf = require(quasarConfPath)(this._api.ctx),
quasarConfFileData = fs.readFileSync(quasarConfPath, 'utf8')
let newData = quasarConfFileData
// Loop through our groups we want to check and process them.
for (let groupKey in this._whitelists) {
const sourceItems = this.getSourceItems(groupKey, source)
let newGroupItemList = this.getMissingGroupItems(groupKey, quasarConf, sourceItems, newData)
if (newGroupItemList.length !== sourceItems.length) {
newData = newData.replace(this.getGroupRegex(groupKey), this.stringifyConf(groupKey, newGroupItemList))
applyChanges (selectedItems = []) {
for (let group in this._analysis.merged) {
// Pick out only the selected items for this group or add them all based on selectedItems
let itemsToReplace = selectedItems.length > 0
? this.mergeArrays(this._analysis.existing[group], this._analysis.missing[group], f => selectedItems.includes(f))
: this._analysis.merged[group]
// Call sort again as the manual items may have thrown off sorting.
if (this._options.sort) {
itemsToReplace.sort()
}
if (itemsToReplace !== void 0) {
this._quasarConfFileData = this._quasarConfFileData.replace(this.getGroupRegex(group), this.stringifyConfGroup(group, itemsToReplace))
}
}
if (newData !== quasarConfFileData) {
fs.writeFileSync(quasarConfPath, newData, 'utf8')
if (this._quasarConfFileData !== this._originalQuasarConfFileData) {
this._originalQuasarConfFileData = this._quasarConfFileData
fs.writeFileSync(this._quasarConfPath, this._quasarConfFileData, 'utf8')
}
this._forceApplyChanges = false
}
/**
* Simple helper to merge 2 arrays with filter even if arrays aren't initialised.
* @param arr1
* @param arr2
* @param filterFn
* @returns {*[]}
*/
mergeArrays (arr1, arr2, filterFn) {
const arr = arr2 || []
const filteredArray = typeof filterFn === 'function'
? arr.filter(filterFn)
: arr
return [].concat.apply([], [arr1 || [], filteredArray])
}
return source
/**
* this.analyse() the source and then this.applyChanges()
* @param source
* @returns {*}
*/
analyseAndApply (source) {
this.analyse(source)
return this.applyChanges()
}
/**
* External access to the accumulative scan result.
* @returns {{existing: {}, missing: {}, merged: {}}|*}
*/
getAnalysisResult () {
return this._analysis
}
/**
* HMR console logging will be cleared so maintain an internal version
* @param msg
*/
addLog (msg) {
this._logs.push(msg)
}
/**
* Clear current internal log buffer
*/
clearLog () {
this._logs = []
}
/**
* Write the current log buffer to console
* To be used when HMR has finished to avoid
*/
writeLog () {
for (let log of this._logs) {
console.log(log)
}
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc