Skip to content
This repository has been archived by the owner on Aug 22, 2023. It is now read-only.

Commit

Permalink
feat: add hook context
Browse files Browse the repository at this point in the history
  • Loading branch information
jdx committed Feb 5, 2018
1 parent bb8acf9 commit c287a0e
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 5 deletions.
23 changes: 23 additions & 0 deletions src/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export class ExitError extends Error {
'cli-ux': {
exit: number
}
code?: string

constructor(error?: string | Error | number, exitCode = 0) {
if (typeof error === 'number') {
exitCode = error
error = undefined
}
const addCode = (error: ExitError) => {
error['cli-ux'] = error['cli-ux'] || {}
error['cli-ux'].exit = exitCode
return error
}
if (error instanceof Error) {
return addCode(error as any)
}
super(error || `${exitCode}: ${status}`)
this.code = 'EEXIT'
}
}
10 changes: 9 additions & 1 deletion src/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,12 @@ export interface Hooks {
}
}

export type Hook<K extends keyof Hooks> = (options: Hooks[K] & {config: Config.IConfig}) => any
export type Hook<K extends keyof Hooks> = (this: Hook.Context, options: Hooks[K] & {config: Config.IConfig}) => any

export namespace Hook {
export interface Context {
exit(code?: number): void
error(message: string | Error, options?: {exit?: number}): void
log(message?: any): void
}
}
20 changes: 16 additions & 4 deletions src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import {inspect} from 'util'

import {Command} from './command'
import Debug from './debug'
import {Hooks} from './hooks'
import {ExitError} from './errors'
import {Hook, Hooks} from './hooks'
import {Manifest} from './manifest'
import {PJSON} from './pjson'
import {Topic} from './topic'
Expand Down Expand Up @@ -190,18 +191,29 @@ export class Plugin implements IPlugin {
}

async runHook<T extends Hooks, K extends keyof T>(event: K, opts: T[K]) {
const context: Hook.Context = {
exit(code) {
throw new ExitError(code)
},
log(message) {
process.stdout.write((message || '') + '\n')
},
error(message, options = {}) {
throw new ExitError(message, options.exit)
},
}
const promises = (this.hooks[event] || [])
.map(async hook => {
try {
const p = tsPath(this.root, hook)
debug('hook', event, p)
const search = (m: any) => {
const search = (m: any): Hook<K> => {
if (typeof m === 'function') return m
if (m.default && typeof m.default === 'function') return m.default
return Object.values(m).find((m: any) => typeof m === 'function')
return Object.values(m).find((m: any) => typeof m === 'function') as Hook<K>
}

await search(require(p))(opts)
await search(require(p)).call(context, opts)
} catch (err) {
if (err && err['cli-ux'] && err['cli-ux'].exit !== undefined) throw err
process.emitWarning(err)
Expand Down

0 comments on commit c287a0e

Please sign in to comment.