UNPKG

@quasar/app-vite

Version:

Quasar Framework App CLI with Vite

582 lines (490 loc) 14.6 kB
import parseArgs from 'minimist' import { green, red, italic, underline } from 'kolorist' import { fatal, dot } from '../utils/logger.js' import { getApi } from '../utils/get-api.js' import { getCtx } from '../utils/get-ctx.js' const partArgs = { p: 'props', s: 'slots', m: 'methods', c: 'computedProps', e: 'events', v: 'value', a: 'arg', M: 'modifiers', i: 'injection', q: 'quasar', d: 'docs' } const partArgsKeys = Object.keys(partArgs) const argv = parseArgs(process.argv.slice(2), { alias: { h: 'help', f: 'filter', ...partArgs }, boolean: ['h', ...partArgsKeys], string: ['f'] }) const item = argv._[0] if (!item || argv.help) { console.log(` Description Describes a component API for project's Quasar version being used Usage $ quasar describe <component/directive/Quasar plugin> # list all available API entries: $ quasar describe list # list available API entries that contain a String (ex "storage"): $ quasar describe list storage # display everything: $ quasar describe QIcon # displaying only props: $ quasar describe QIcon -p # displaying props and methods only: $ quasar describe QIcon -p -m # filtering by "si": $ quasar describe QIcon -f si # filtering only props by "co": $ quasar describe QIcon -p -f co # Open docs URL: $ quasar describe QIcon -d Options --filter, -f <filter> Filters the API --props, -p Displays the API props --slots, -s Displays the API slots --events, -e Displays the API events --methods, -m Displays the API methods --computedProps, -c Displays the API computed props --value, -v Displays the API value --arg, -a Displays the API arg --modifiers, -M Displays the API modifiers --injection, -i Displays the API injection --quasar, -q Displays the API quasar conf options --docs, -d Opens the docs API URL --help, -h Displays this message `) process.exit(0) } const ctx = getCtx() const apiParts = {} if (partArgsKeys.some(part => argv[part])) { Object.values(partArgs).forEach(part => { apiParts[part] = argv[part] }) } else { Object.values(partArgs).forEach(part => { if (part !== 'docs') { apiParts[part] = true } }) } function getEventParams(event) { const params = !event.params || event.params.length === 0 ? '' : Object.keys(event.params).join(', ') return ' -> function(' + params + ')' } function getMethodParams(method, noRequired) { if (!method.params || method.params.length === 0) { return ' ()' } if (noRequired === true) { return ` (${Object.keys(method.params).join(', ')})` } const params = Object.keys(method.params) const optionalIndex = params.findIndex( param => method.params[param].required !== true ) const str = optionalIndex !== -1 ? params.slice(0, optionalIndex).join(', ') + (optionalIndex < params.length ? '[' + (optionalIndex > 0 ? ', ' : '') + params.slice(optionalIndex).join(', ') + ']' : '') : params.join(', ') return ' (' + str + ')' } function getMethodReturnValue(method) { return ' => ' + (!method.returns ? 'void 0' : method.returns.type) } function getStringType(type) { return Array.isArray(type) ? type.join(' | ') : type } function printProp(prop, propName, indentLevel) { let indent = ' '.repeat(indentLevel) const type = getStringType(prop.type) if (propName !== void 0) { console.log( `${indent}${green(propName)} ${type ? `(${type})` : ''}${type !== 'Function' && prop.required ? red(' [Required]') : ''}${prop.reactive ? red(' [Reactive]') : ''}` ) indentLevel += 2 indent += ' ' } console.log(`${indent}Description: ${prop.desc}`) if (prop.alias) { console.log(`${indent}Alias: ${prop.alias}`) } if (type === 'Function') { console.log( `${indent}Function form:${getMethodParams(prop, true)}${getMethodReturnValue(prop)}` ) } if (prop.sync) { console.log(`${indent}".sync" modifier required!`) } if (prop.link) { console.log(`${indent}Link: ${prop.link}`) } if (prop.values) { console.log(`${indent}Accepted values: ${prop.values.join(' | ')}`) } if (prop.default) { console.log(`${indent}Default value: ${prop.default}`) } if (prop.definition) { console.log(`${indent}Props:`) for (const defPropName in prop.definition) { printProp(prop.definition[defPropName], defPropName, indentLevel + 2) } } if (prop.params) { console.log(`${indent}Params:`) for (const paramName in prop.params) { printProp(prop.params[paramName], paramName, indentLevel + 2) } } if (prop.returns) { console.log(`${indent}Returns ${getStringType(prop.returns.type)}:`) printProp(prop.returns, void 0, indentLevel + 2) } if (prop.scope) { console.log(`${indent}Scope:`) for (const scopePropName in prop.scope) { printProp(prop.scope[scopePropName], scopePropName, indentLevel + 2) } } if (prop.examples !== void 0) { console.log(`${indent}Example${prop.examples.length > 1 ? 's' : ''}:`) prop.examples.forEach(example => { console.log(`${indent} ${example}`) }) } } function printProperties({ props }) { const keys = Object.keys(props || {}) console.log('\n ' + underline('Properties')) if (keys.length === 0) { console.log('\n ' + italic('*No properties*')) return } if (argv.filter) { keys.forEach(key => { if (key.indexOf(argv.filter) === -1) { delete props[key] } }) if (Object.keys(props).length === 0) { console.log('\n ' + italic('*No matching properties*')) return } } for (const propName in props) { console.log() printProp(props[propName], propName, 3) } } function printSlots({ slots }) { const keys = Object.keys(slots || {}) console.log('\n ' + underline('Slots')) if (keys.length === 0) { console.log('\n ' + italic('*No slots*')) return } if (argv.filter !== void 0) { keys.forEach(key => { if (key.indexOf(argv.filter) === -1) { delete slots[key] } }) if (Object.keys(slots).length === 0) { console.log('\n ' + italic('*No matching slots*')) return } } for (const slot in slots) { console.log() printProp(slots[slot], slot, 3) } } function printEvents({ events }) { const keys = Object.keys(events || {}) console.log('\n ' + underline('Events')) if (keys.length === 0) { console.log('\n ' + italic('*No events*')) return } if (argv.filter !== void 0) { keys.forEach(key => { if (key.indexOf(argv.filter) === -1) { delete events[key] } }) if (Object.keys(events).length === 0) { console.log('\n ' + italic('*No matching events*')) return } } for (const eventName in events) { const event = events[eventName] console.log('\n @' + green(eventName) + getEventParams(event)) console.log(' Description: ' + event.desc) if (!event.params) { console.log(' Parameters: ' + italic('*None*')) } else { console.log(' Parameters:') for (const paramName in event.params) { printProp(event.params[paramName], paramName, 7) } } } } function printMethods({ methods }) { const keys = Object.keys(methods || {}) console.log('\n ' + underline('Methods')) if (keys.length === 0) { console.log('\n ' + italic('*No methods*')) return } if (argv.filter !== void 0) { keys.forEach(key => { if (key.indexOf(argv.filter) === -1) { delete methods[key] } }) if (Object.keys(methods).length === 0) { console.log('\n ' + italic('*No matching methods*')) return } } for (const methodName in methods) { const method = methods[methodName] console.log( '\n ' + green(methodName) + getMethodParams(method) + getMethodReturnValue(method) ) console.log(' ' + method.desc) if (method.params) { console.log(' Parameters:') for (const paramName in method.params) { printProp(method.params[paramName], paramName, 7) } } if (method.returns) { console.log(` Returns ${getStringType(method.returns.type)}:`) printProp(method.returns, void 0, 7) } } } function printComputedProps({ computedProps }) { const keys = Object.keys(computedProps || {}) console.log('\n ' + underline('Computed Properties')) if (keys.length === 0) { console.log('\n ' + italic('*No computed properties*')) return } if (argv.filter) { keys.forEach(key => { if (key.indexOf(argv.filter) === -1) { delete computedProps[key] } }) if (Object.keys(computedProps).length === 0) { console.log('\n ' + italic('*No matching computed properties*')) return } } for (const propName in computedProps) { console.log() printProp(computedProps[propName], propName, 3) } } function printValue({ value }) { console.log('\n ' + underline('Value')) if (value === void 0) { console.log('\n ' + italic('*No value*')) } else { console.log('\n Type:', value.type) printProp(value, void 0, 3) } } function printArg({ arg }) { console.log('\n ' + underline('Arg')) if (arg === void 0) { console.log('\n ' + italic('*No arg*')) } else { console.log('\n Type:', arg.type) printProp(arg, void 0, 3) } } function printModifiers({ modifiers }) { const keys = Object.keys(modifiers || {}) console.log('\n ' + underline('Modifiers')) if (keys.length === 0) { console.log('\n ' + italic('*No modifiers*')) return } if (argv.filter !== void 0) { keys.forEach(key => { if (key.indexOf(argv.filter) === -1) { delete modifiers[key] } }) if (Object.keys(modifiers).length === 0) { console.log('\n ' + italic('*No matching modifiers*')) return } } for (const modifierName in modifiers) { const modifier = modifiers[modifierName] console.log('\n ' + green(modifierName)) printProp(modifier, modifierName, 5) } } function printInjection({ injection }) { console.log('\n ' + underline('Injection')) if (injection === void 0) { console.log('\n ' + italic('*No injection*')) } else { console.log('\n ' + green(injection)) } } function printQuasarConfOptions({ quasarConfOptions }) { const conf = quasarConfOptions !== void 0 ? quasarConfOptions.definition || {} : {} const keys = Object.keys(conf) console.log('\n ' + underline('quasar.config file > framework > config')) if (keys.length === 0) { console.log('\n ' + italic('*No configuration options*')) return } if (argv.filter !== void 0) { keys.forEach(key => { if (key.indexOf(argv.filter) === -1) { delete conf[key] } }) if (Object.keys(conf).length === 0) { console.log('\n ' + italic('*No matching configuration options*')) return } } console.log('\n Property name: ' + green(quasarConfOptions.propName)) console.log(' Definition:') for (const propName in conf) { console.log() printProp(conf[propName], propName, 5) } } function describe(api) { switch (api.type) { case 'component': if (apiParts.quasar === true) printQuasarConfOptions(api) if (apiParts.props === true) printProperties(api) if (apiParts.slots === true) printSlots(api) if (apiParts.events === true) printEvents(api) if (apiParts.methods === true) printMethods(api) if (apiParts.computedProps === true) printComputedProps(api) break case 'directive': if (apiParts.quasar === true) printQuasarConfOptions(api) if (apiParts.value === true) printValue(api) if (apiParts.arg === true) printArg(api) if (apiParts.modifiers === true) printModifiers(api) break case 'plugin': if (apiParts.injection === true) printInjection(api) if (apiParts.quasar === true) printQuasarConfOptions(api) if (apiParts.props === true) printProperties(api) if (apiParts.methods === true) printMethods(api) break } if (api.meta && api.meta.docsUrl) { console.log('\n ' + underline('Documentation URL')) console.log('\n ' + green(api.meta.docsUrl)) } } async function run() { try { const { api, supplier } = await getApi(item, ctx) console.log() if (apiParts.docs) { if (api.meta && api.meta.docsUrl) { const { openBrowser } = await import('../utils/open-browser.js') openBrowser({ url: api.meta.docsUrl, wait: false }) } else { console.log( ' Please report this issue to: https://github.com/quasarframework/quasar/issues/' ) console.log( ' Write down the command that you tried along with a complete log of "quasar info" command output' ) console.log() } } else { console.log(` Describing ${green(item)} ${api.type} API`) if (supplier === void 0) { console.log( ` ${italic("Description is based on your project's Quasar version")}` ) } else { console.log(` ${italic(`Supplied by "${supplier}" App Extension`)}`) } describe(api) console.log() } } catch (e) { fatal(e) } } async function listElements() { const { getPackage } = await import('../utils/get-package.js') let api = await getPackage( 'quasar/dist/transforms/api-list.json', ctx.appPaths.appDir ) if (api === void 0) { fatal(' Could not retrieve list...') } const filter = argv._[1] if (filter) { const needle = filter.toLowerCase() const filterBanner = green(filter) api = api.filter(entry => entry.toLowerCase().indexOf(needle) !== -1) if (api.length === 0) { console.log( `\n Nothing matches "${filterBanner}". Please refine the search term.\n` ) process.exit(0) } console.log(`\n The list of API elements that match "${filterBanner}":\n`) } else { console.log('\n The complete list of API elements:\n') } const prefix = green(` ${dot} `) api.forEach(entry => { console.log(prefix + entry) }) console.log() } if (item === 'list') { listElements() } else { run() }