/* eslint-disable no-console */ const fs = require('fs/promises') const { resolve } = require('path') const { commands, aliases } = require('../lib/utils/cmd-list.js') const { definitions } = require('@npmcli/config/lib/definitions') async function main () { const file = resolve(__dirname, '..', 'lib', 'utils', 'completion.fish') console.log(await fs.readFile(file, 'utf-8')) const cmds = {} for (const cmd of commands) { cmds[cmd] = { aliases: [cmd] } const cmdClass = require(`../lib/commands/${cmd}.js`) cmds[cmd].description = cmdClass.description cmds[cmd].params = cmdClass.params } for (const alias in aliases) { cmds[aliases[alias]].aliases.push(alias) } for (const cmd in cmds) { console.log(`# ${cmd}`) const { aliases: cmdAliases, description, params = [] } = cmds[cmd] // If npm completion could return all commands in a fish friendly manner // like we do w/ run-script these wouldn't be needed. /* eslint-disable-next-line max-len */ console.log(`complete -x -c npm -n __fish_npm_needs_command -a '${cmdAliases.join(' ')}' -d '${description}'`) const shorts = params.map(p => { // Our multi-character short params (e.g. -ws) are not very standard and // don't work with things that assume short params are only ever single // characters. if (definitions[p].short?.length === 1) { return `-s ${definitions[p].short}` } }).filter(p => p).join(' ') // The config descriptions are not appropriate for -d here. We may want to // consider having a more terse description for these. // We can also have a mechanism to auto-generate the long form of options // that have predefined values. // params completion /* eslint-disable-next-line max-len */ console.log(`complete -x -c npm -n '__fish_seen_subcommand_from ${cmdAliases.join(' ')}' ${params.map(p => `-l ${p}`).join(' ')} ${shorts}`) // builtin npm completion /* eslint-disable-next-line max-len */ console.log(`complete -x -c npm -n '__fish_seen_subcommand_from ${cmdAliases.join(' ')}' -a '(__fish_complete_npm)'`) } } main().then(() => { return process.exit() }).catch(err => { console.error(err) process.exit(1) })