@oclif/core
Advanced tools
Comparing version 0.5.32 to 0.5.33
@@ -5,2 +5,9 @@ # Changelog | ||
### [0.5.33](https://github.com/oclif/core/compare/v0.5.32...v0.5.33) (2021-08-30) | ||
### Bug Fixes | ||
* improve Hooks interface ([#234](https://github.com/oclif/core/issues/234)) ([32d0d62](https://github.com/oclif/core/commit/32d0d62ed30c65cdbca7c6da630b5542b38ab3b1)) | ||
### [0.5.32](https://github.com/oclif/core/compare/v0.5.31...v0.5.32) (2021-08-23) | ||
@@ -7,0 +14,0 @@ |
import { Options, Plugin as IPlugin } from '../interfaces/plugin'; | ||
import { Config as IConfig, ArchTypes, PlatformTypes, LoadOptions } from '../interfaces/config'; | ||
import { Command, PJSON, Topic } from '../interfaces'; | ||
import { Command, Hook, Hooks, PJSON, Topic } from '../interfaces'; | ||
import * as Plugin from './plugin'; | ||
@@ -42,3 +42,3 @@ export declare class Config implements IConfig { | ||
loadUserPlugins(): Promise<void>; | ||
runHook<T>(event: string, opts: T): Promise<any>; | ||
runHook<T extends keyof Hooks>(event: T, opts: Hooks[T]['options'], timeout?: number): Promise<Hook.Result<Hooks[T]['return']>>; | ||
runCommand<T = unknown>(id: string, argv?: string[], cachedCommand?: Command.Plugin): Promise<T>; | ||
@@ -45,0 +45,0 @@ scopedEnvVar(k: string): string | undefined; |
@@ -130,3 +130,3 @@ "use strict"; | ||
} | ||
async runHook(event, opts) { | ||
async runHook(event, opts, timeout) { | ||
debug('start %s hook', event); | ||
@@ -140,3 +140,8 @@ const search = (m) => { | ||
}; | ||
const results = []; | ||
const withTimeout = async (ms, promise) => { | ||
const timeout = new Promise((_, reject) => setTimeout(() => reject(new Error(`Timed out after ${ms} ms.`)), ms)); | ||
return Promise.race([promise, timeout]); | ||
}; | ||
const successes = []; | ||
const failures = []; | ||
for (const p of this.plugins) { | ||
@@ -166,7 +171,10 @@ const debug = require('debug')([this.bin, p.name, 'hooks', event].join(':')); | ||
debug('start', isESM ? '(import)' : '(require)', filePath); | ||
const result = await search(module).call(context, Object.assign(Object.assign({}, opts), { config: this })); | ||
results.push(result); | ||
const result = timeout ? | ||
await withTimeout(timeout, search(module).call(context, Object.assign(Object.assign({}, opts), { config: this }))) : | ||
await search(module).call(context, Object.assign(Object.assign({}, opts), { config: this })); | ||
successes.push({ plugin: p, result }); | ||
debug('done'); | ||
} | ||
catch (error) { | ||
failures.push({ plugin: p, error }); | ||
if (error && error.oclif && error.oclif.exit !== undefined) | ||
@@ -179,3 +187,3 @@ throw error; | ||
debug('%s hook done', event); | ||
return results; | ||
return { successes, failures }; | ||
} | ||
@@ -182,0 +190,0 @@ async runCommand(id, argv = [], cachedCommand) { |
import { PJSON } from './pjson'; | ||
import { Hooks } from './hooks'; | ||
import { Hooks, Hook } from './hooks'; | ||
import { Command } from './command'; | ||
@@ -95,3 +95,3 @@ import { Plugin, Options } from './plugin'; | ||
runCommand<T = unknown>(id: string, argv?: string[], cachedCommand?: Command.Plugin): Promise<T>; | ||
runHook<T extends Hooks, K extends Extract<keyof T, string>>(event: K, opts: T[K]): Promise<any>; | ||
runHook<T extends keyof Hooks>(event: T, opts: Hooks[T]['options'], timeout?: number): Promise<Hook.Result<Hooks[T]['return']>>; | ||
findCommand(id: string, opts: { | ||
@@ -98,0 +98,0 @@ must: true; |
import { Command } from './command'; | ||
import { Config } from './config'; | ||
import { Plugin } from './plugin'; | ||
interface HookMeta { | ||
options: Record<string, unknown>; | ||
return: any; | ||
} | ||
export interface Hooks { | ||
[event: string]: object; | ||
[event: string]: HookMeta; | ||
init: { | ||
id: string | undefined; | ||
argv: string[]; | ||
options: { | ||
id: string | undefined; | ||
argv: string[]; | ||
}; | ||
return: void; | ||
}; | ||
prerun: { | ||
Command: Command.Class; | ||
argv: string[]; | ||
options: { | ||
Command: Command.Class; | ||
argv: string[]; | ||
}; | ||
return: void; | ||
}; | ||
postrun: { | ||
Command: Command.Class; | ||
result?: any; | ||
argv: string[]; | ||
options: { | ||
Command: Command.Class; | ||
result?: any; | ||
argv: string[]; | ||
}; | ||
return: void; | ||
}; | ||
preupdate: { | ||
channel: string; | ||
options: { | ||
channel: string; | ||
}; | ||
return: void; | ||
}; | ||
update: { | ||
channel: string; | ||
options: { | ||
channel: string; | ||
}; | ||
return: void; | ||
}; | ||
'command_not_found': { | ||
id: string; | ||
argv?: string[]; | ||
options: { | ||
id: string; | ||
argv?: string[]; | ||
}; | ||
return: void; | ||
}; | ||
'plugins:preinstall': { | ||
plugin: { | ||
name: string; | ||
tag: string; | ||
type: 'npm'; | ||
} | { | ||
url: string; | ||
type: 'repo'; | ||
options: { | ||
plugin: { | ||
name: string; | ||
tag: string; | ||
type: 'npm'; | ||
} | { | ||
url: string; | ||
type: 'repo'; | ||
}; | ||
}; | ||
return: void; | ||
}; | ||
} | ||
export declare type HookKeyOrOptions<K> = K extends (keyof Hooks) ? Hooks[K] : K; | ||
export declare type Hook<T> = (this: Hook.Context, options: HookKeyOrOptions<T> & { | ||
export declare type Hook<T extends keyof P, P extends Hooks = Hooks> = (this: Hook.Context, options: P[T]['options'] & { | ||
config: Config; | ||
}) => any; | ||
}) => Promise<P[T]['return']>; | ||
export declare namespace Hook { | ||
type Init = Hook<Hooks['init']>; | ||
type PluginsPreinstall = Hook<Hooks['plugins:preinstall']>; | ||
type Prerun = Hook<Hooks['prerun']>; | ||
type Postrun = Hook<Hooks['postrun']>; | ||
type Preupdate = Hook<Hooks['preupdate']>; | ||
type Update = Hook<Hooks['update']>; | ||
type CommandNotFound = Hook<Hooks['command_not_found']>; | ||
type Init = Hook<'init'>; | ||
type PluginsPreinstall = Hook<'plugins:preinstall'>; | ||
type Prerun = Hook<'prerun'>; | ||
type Postrun = Hook<'postrun'>; | ||
type Preupdate = Hook<'preupdate'>; | ||
type Update = Hook<'update'>; | ||
type CommandNotFound = Hook<'command_not_found'>; | ||
interface Context { | ||
@@ -62,2 +87,13 @@ config: Config; | ||
} | ||
interface Result<T> { | ||
successes: Array<{ | ||
result: T; | ||
plugin: Plugin; | ||
}>; | ||
failures: Array<{ | ||
error: typeof Error; | ||
plugin: Plugin; | ||
}>; | ||
} | ||
} | ||
export {}; |
@@ -6,3 +6,3 @@ export { AlphabetLowercase, AlphabetUppercase } from './alphabet'; | ||
export { HelpOptions } from './help'; | ||
export { Hook, HookKeyOrOptions, Hooks } from './hooks'; | ||
export { Hook, Hooks } from './hooks'; | ||
export { Manifest } from './manifest'; | ||
@@ -9,0 +9,0 @@ export { ParserArg, Arg, ParseFn, ParserOutput, ParserInput, ArgToken, OptionalArg, FlagOutput, OutputArgs, OutputFlags, FlagUsageOptions, CLIParseErrorOptions, ArgInput, RequiredArg, Metadata, ParsingToken, FlagToken, List, ListItem, BooleanFlag, Flag, FlagBase, OptionFlag, Input, EnumFlagOptions, DefaultContext, Default, Definition, CompletableOptionFlag, Completion, CompletionContext, FlagInput, CompletableFlag, } from './parser'; |
{ | ||
"name": "@oclif/core", | ||
"description": "base library for oclif CLIs", | ||
"version": "0.5.32", | ||
"version": "0.5.33", | ||
"author": "Jeff Dickey @jdxcode", | ||
@@ -6,0 +6,0 @@ "bugs": "https://github.com/oclif/core/issues", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
204899
5144