Skip to content

Commit

Permalink
chore(ts): tsify lib/completion (#1601)
Browse files Browse the repository at this point in the history
* chore(ts): tsify lib/completion
* refactor(ts): get rid of Partial for self type

Co-authored-by: Mael LE GUEN <mael.leguen@laposte.fr>
  • Loading branch information
mleguen and Mael LE GUEN committed Mar 26, 2020
1 parent 16ee006 commit fc18a33
Show file tree
Hide file tree
Showing 21 changed files with 141 additions and 21 deletions.
2 changes: 1 addition & 1 deletion lib/apply-extends.ts
@@ -1,7 +1,7 @@

import * as fs from 'fs'
import * as path from 'path'
import { Dictionary } from './types/dictionary'
import { Dictionary } from './types'
import { YError } from './yerror'

let previouslyVisitedConfigs: string[] = []
Expand Down
39 changes: 24 additions & 15 deletions lib/completion.js → lib/completion.ts
@@ -1,14 +1,24 @@
'use strict'
const path = require('path')
import * as path from 'path'
import * as templates from './completion-templates'
import { isPromise } from './is-promise'
import {
CommandInstance,
CompletionFunction,
CompletionInstance,
Dictionary,
UsageInstance,
YargsInstance
} from './types'
import { isSyncCompletionFunction, isFunctionCommandBuilder } from './type-helpers'

// add bash completions to your
// yargs-powered applications.
module.exports = function completion (yargs, usage, command) {
const self = {
export function completion (yargs: YargsInstance, usage: UsageInstance, command: CommandInstance) {
const self: CompletionInstance = {
completionKey: 'get-yargs-completions'
}
} as CompletionInstance

let aliases
let aliases: Dictionary<string>
self.setParsed = function setParsed (parsed) {
aliases = parsed.aliases
}
Expand All @@ -18,19 +28,19 @@ module.exports = function completion (yargs, usage, command) {
// get a list of completion commands.
// 'args' is the array of strings from the line to be completed
self.getCompletion = function getCompletion (args, done) {
const completions = []
const completions: string[] = []
const current = args.length ? args[args.length - 1] : ''
const argv = yargs.parse(args, true)
const parentCommands = yargs.getContext().commands

// a custom completion function can be provided
// to completion().
if (completionFunction) {
if (completionFunction.length < 3) {
if (isSyncCompletionFunction(completionFunction)) {
const result = completionFunction(current, argv)

// promise based completion function.
if (typeof result.then === 'function') {
if (isPromise(result)) {
return result.then((list) => {
process.nextTick(() => { done(list) })
}).catch((err) => {
Expand All @@ -52,7 +62,7 @@ module.exports = function completion (yargs, usage, command) {
for (let i = 0, ii = args.length; i < ii; ++i) {
if (handlers[args[i]] && handlers[args[i]].builder) {
const builder = handlers[args[i]].builder
if (typeof builder === 'function') {
if (isFunctionCommandBuilder(builder)) {
const y = yargs.reset()
builder(y)
return y.argv
Expand Down Expand Up @@ -83,11 +93,11 @@ module.exports = function completion (yargs, usage, command) {
let keyAndAliases = [key].concat(aliases[key] || [])
if (negable) keyAndAliases = keyAndAliases.concat(keyAndAliases.map(key => `no-${key}`))

function completeOptionKey (key) {
function completeOptionKey (key: string) {
const notInArgs = keyAndAliases.every(val => args.indexOf(`--${val}`) === -1)
if (notInArgs) {
const startsByTwoDashes = s => /^--/.test(s)
const isShortOption = s => /^[^0-9]$/.test(s)
const startsByTwoDashes = (s: string) => /^--/.test(s)
const isShortOption = (s: string) => /^[^0-9]$/.test(s)
const dashes = !startsByTwoDashes(current) && isShortOption(key) ? '-' : '--'
if (!zshShell) {
completions.push(dashes + key)
Expand All @@ -108,7 +118,6 @@ module.exports = function completion (yargs, usage, command) {

// generate the completion script to add to your .bashrc.
self.generateCompletionScript = function generateCompletionScript ($0, cmd) {
const templates = require('../build/lib/completion-templates')
let script = zshShell ? templates.completionZshTemplate : templates.completionShTemplate
const name = path.basename($0)

Expand All @@ -123,7 +132,7 @@ module.exports = function completion (yargs, usage, command) {
// register a function to perform your own custom
// completions., this function can be either
// synchrnous or asynchronous.
let completionFunction = null
let completionFunction: CompletionFunction | null = null
self.registerFunction = (fn) => {
completionFunction = fn
}
Expand Down
2 changes: 1 addition & 1 deletion lib/obj-filter.ts
@@ -1,4 +1,4 @@
import { Dictionary } from './types/dictionary'
import { Dictionary } from './types'

export function objFilter<T = any> (original: Dictionary<T>, filter: (k: string, v: T) => boolean = () => true) {
const obj: Dictionary<T> = {}
Expand Down
2 changes: 1 addition & 1 deletion lib/process-argv.ts
@@ -1,4 +1,4 @@
import { ElectronProcess } from './types/electron-process'
import { ElectronProcess } from './types'

function getProcessArgvBinIndex () {
// The binary name is the first command line argument for:
Expand Down
5 changes: 5 additions & 0 deletions lib/type-helpers/command-builder.ts
@@ -0,0 +1,5 @@
import { CommandBuilder, FunctionCommandBuilder } from '../types'

export function isFunctionCommandBuilder (builder: CommandBuilder): builder is FunctionCommandBuilder {
return typeof builder === 'function'
}
5 changes: 5 additions & 0 deletions lib/type-helpers/completion-function.ts
@@ -0,0 +1,5 @@
import { CompletionFunction, SyncCompletionFunction } from '../types'

export function isSyncCompletionFunction (completionFunction: CompletionFunction): completionFunction is SyncCompletionFunction {
return completionFunction.length < 3
}
2 changes: 2 additions & 0 deletions lib/type-helpers/index.ts
@@ -0,0 +1,2 @@
export * from './completion-function'
export * from './command-builder'
8 changes: 8 additions & 0 deletions lib/types/command-builder.ts
@@ -0,0 +1,8 @@
import { YargsInstance } from './yargs-instance'

// To be completed later with other CommandBuilder flavours
export type CommandBuilder = FunctionCommandBuilder

export interface FunctionCommandBuilder {
(y: YargsInstance): YargsInstance
}
5 changes: 5 additions & 0 deletions lib/types/command-handler.ts
@@ -0,0 +1,5 @@
import { CommandBuilder } from './command-builder'

export interface CommandHandler {
builder: CommandBuilder
}
9 changes: 9 additions & 0 deletions lib/types/command-instance.ts
@@ -0,0 +1,9 @@
import { CommandHandler } from './command-handler'
import { Dictionary } from './dictionary'
import { ParsedCommand } from './parsed-command'

/** Instance of the command module. */
export interface CommandInstance {
getCommandHandlers (): Dictionary<CommandHandler>
parseCommand (cmd: string): ParsedCommand
}
11 changes: 11 additions & 0 deletions lib/types/completion-function.ts
@@ -0,0 +1,11 @@
import { Parsed } from './parsed'

export type CompletionFunction = SyncCompletionFunction | AsyncCompletionFunction

export interface SyncCompletionFunction {
(current: string, argv: Parsed): string[] | Promise<string[]>
}

export interface AsyncCompletionFunction {
(current: string, argv: Parsed, done: (completions: string[]) => any): any
}
11 changes: 11 additions & 0 deletions lib/types/completion-instance.ts
@@ -0,0 +1,11 @@
import { Parsed } from './parsed'
import { CompletionFunction } from './completion-function'

/** Instance of the completion module. */
export interface CompletionInstance {
completionKey: string
generateCompletionScript ($0: string, cmd: string): string
getCompletion (args: string[], done: (completions: string[]) => any): any
registerFunction(fn: CompletionFunction): void
setParsed (parsed: Parsed): void
}
4 changes: 4 additions & 0 deletions lib/types/context.ts
@@ -0,0 +1,4 @@
/** Yargs' context. */
export interface Context {
commands: string[]
}
13 changes: 13 additions & 0 deletions lib/types/index.ts
@@ -0,0 +1,13 @@
export * from './command-builder'
export * from './command-handler'
export * from './command-instance'
export * from './completion-function'
export * from './completion-instance'
export * from './context'
export * from './dictionary'
export * from './electron-process'
export * from './options'
export * from './parsed'
export * from './parsed-command'
export * from './usage-instance'
export * from './yargs-instance'
9 changes: 9 additions & 0 deletions lib/types/options.ts
@@ -0,0 +1,9 @@
import { Dictionary } from './dictionary'

export interface Options {
boolean: string[]
configuration: Dictionary
default: Dictionary
/** Manually set keys */
key: Dictionary<boolean>
}
5 changes: 5 additions & 0 deletions lib/types/parsed-command.ts
@@ -0,0 +1,5 @@
export interface ParsedCommand {
cmd: string
demanded: []
optional: []
}
5 changes: 5 additions & 0 deletions lib/types/parsed.ts
@@ -0,0 +1,5 @@
import { Dictionary } from './dictionary'

export interface Parsed {
aliases: Dictionary<string>
}
7 changes: 7 additions & 0 deletions lib/types/usage-instance.ts
@@ -0,0 +1,7 @@
import { Dictionary } from './dictionary'

/** Instance of the usage module. */
export interface UsageInstance {
getCommands (): string[]
getDescriptions (): Dictionary<string>
}
12 changes: 12 additions & 0 deletions lib/types/yargs-instance.ts
@@ -0,0 +1,12 @@
import { Context } from './context'
import { Options } from './options'
import { Parsed } from './parsed'

/** Instance of the yargs module. */
export interface YargsInstance {
argv: Parsed
getContext (): Context
getOptions (): Options
parse (args: string[], shortCircuit: boolean): Parsed
reset (): YargsInstance
}
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -36,8 +36,8 @@
"@types/chai": "^4.2.11",
"@types/mocha": "^7.0.2",
"@types/node": "^10.0.3",
"@typescript-eslint/eslint-plugin": "^2.23.0",
"@typescript-eslint/parser": "^2.23.0",
"@typescript-eslint/eslint-plugin": "^2.25.0",
"@typescript-eslint/parser": "^2.25.0",
"c8": "^7.0.0",
"chai": "^4.2.0",
"chalk": "^3.0.0",
Expand Down
2 changes: 1 addition & 1 deletion yargs.js
Expand Up @@ -7,7 +7,7 @@ requiresNode8OrGreater()
const argsert = require('./lib/argsert')
const fs = require('fs')
const Command = require('./lib/command')
const Completion = require('./lib/completion')
const { completion: Completion } = require('./build/lib/completion')
const Parser = require('yargs-parser')
const path = require('path')
const Usage = require('./lib/usage')
Expand Down

0 comments on commit fc18a33

Please sign in to comment.