Hubot: Adds some missing, new, types to bring up to date for v3 (#42756)

* Hubot: build off existing types to match more closely with API Surface are of v3

* fix base tests

* Fixes some unnecessary generics

* fix some more style items

* fix some generics

* adding more robot tests

* see if this fixes some

* specify version

* Despecify

* move comments up a bit

* up again

* add some brain tests

* Make robot properties readonly to help protect against silliness

* set bug version

* don't want a patch version apparently

* drop the ts version

* drop unnecessary unknowndata interface

* 3.0 for unknown
This commit is contained in:
Jon Phenow 2020-03-06 16:50:24 -06:00 committed by GitHub
parent accdb12060
commit 43f3067cde
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 256 additions and 51 deletions

View File

@ -1,19 +1,78 @@
import * as Hubot from "hubot";
import { Robot, Adapter, Brain, Message, User } from 'hubot';
const robot = new Hubot.Robot<{}>(
'src/adapters',
'slack',
false,
'hubot',
);
robot; // $ExpectType Robot<{}>
robot.adapter; // $ExpectType {}
const user = new User('123');
const message = new Message(user);
const robot = new Robot<Adapter>('src/adapters', 'slack', false, 'hubot');
robot; // $ExpectType Robot<Adapter>
robot.adapter; // $ExpectType Adapter
robot.name; // $ExpectType string
robot.brain; // $ExpectType Brain<Adapter>
robot.catchAll(() => null); // $ExpectType void
robot.emit('test', 'arg'); // $ExpectType void
robot.enter(() => null); // $ExpectType void
robot.error(err => null); // $ExpectType void
robot.hear(/hello/, () => null); // $ExpectType void
robot.on('test', () => null); // $ExpectType Robot<{}>
robot.emit('test', 'arg'); // $ExpectType boolean
robot.helpCommands(); // $ExpectType string[]
robot.http('https://google.com'); // $ExpectType ScopedClient
robot.leave(() => null); // $ExpectType void
// $ExpectType void
robot.listen(
() => true,
() => null,
);
// $ExpectType void
robot.listenerMiddleware((context, next, done) => {
next(done);
});
robot.messageRoom('general', 'Hello friends'); // $ExpectType void
robot.on('test', () => null); // $ExpectType Robot<Adapter>
robot.receive(message, () => null); // $ExpectType void
// $ExpectType void
robot.receiveMiddleware((context, next, done) => {
next(done);
});
// $ExpectType void
robot.reply(
{
message,
user,
room: 'general',
},
'Replying to friends',
);
robot.respond(/hello/, () => null); // $ExpectType void
robot.respondPattern(/hello/); // $ExpectType RegExp
// $ExpectType void
robot.responseMiddleware((context, next, done) => {
next(done);
});
robot.run(); // $ExpectType void
// $ExpectType void
robot.send(
{
message,
user,
room: 'general',
},
'Replying to friends',
);
robot.shutdown(); // $ExpectType void
robot.topic(message => null); // $ExpectType void
const brain = new Hubot.Brain(robot);
brain; // $ExpectType Brain<{}>
brain.userForName('someone'); // $ExpectType User
const brain = new Brain(robot);
brain; // $ExpectType Brain<Adapter>
brain.userForName('someone'); // $ExpectType User | null
brain.get('test'); // $ExpectType any
brain.set('test', 'test'); // $ExpectType Brain<{}>
brain.set('test', 'test'); // $ExpectType Brain<Adapter>
brain.remove('test'); // $ExpectType Brain<Adapter>
brain.setAutoSave(false); // $ExpectType void
brain.resetSaveInterval(15); // $ExpectType void
brain.mergeData({ foo: 'bar' }); // $ExpectType void
brain.users(); // $ExpectType User[]
brain.userForId('123'); // $ExpectType User
brain.userForName('jon'); // $ExpectType User | null
brain.usersForRawFuzzyName('fuzzy'); // $ExpectType User[]
brain.usersForFuzzyName('fuzzy'); // $ExpectType User[]
brain.save(); // $ExpectType void
brain.close(); // $ExpectType void

218
types/hubot/index.d.ts vendored
View File

@ -1,17 +1,59 @@
// Type definitions for hubot 2.19
// Type definitions for hubot 3.3
// Project: https://github.com/hubotio/hubot
// Definitions by: Dirk Gadsden <https://github.com/dirk>
// Kees C. Bakker <https://github.com/KeesCBakker>
// Emil Marklund <https://github.com/eeemil>
// Jon Phenow <https://github.com/jphenow>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.3
/// <reference types="node" />
// TypeScript Version: 3.0
import { EventEmitter } from 'events';
import { Options as HttpOptions, ScopedClient } from 'scoped-http-client';
import { Server } from 'http';
import { Express } from 'express';
declare namespace Hubot {
class Brain<A> extends EventEmitter {
class Adapter extends EventEmitter {
constructor(robot: Robot);
send(envelope: Envelope, ...strings: string[]): void;
emote(envelope: Envelope, ...strings: string[]): void;
reply(envelope: Envelope, ...strings: string[]): void;
topic(envelope: Envelope, ...strings: string[]): void;
play(envelope: Envelope, ...strings: string[]): void;
run(): void;
close(): void;
receive(message: Message): void;
http(url: string): ScopedClient;
users(): User[];
userForId(id: string, options?: {}): User;
userForName(name: string): User | null;
usersForRawFuzzyName(fuzzyName: string): User[];
usersForFuzzyName(fuzzyName: string): User[];
}
class DataStore {
constructor(robot: Robot);
set(key: string, value: any): Promise<void>;
setObject(key: string, objectKey: string, value: any): Promise<void>;
setArray(key: string, value: any): Promise<void>;
get(key: string): Promise<any>;
getObject(key: string, objectKey: string): Promise<any>;
}
class DataStoreUnavailable extends Error {}
class Middleware<T extends Adapter = Adapter> {
stack: Array<MiddlewareHandler<T>>;
constructor(robot: Robot<T>);
execute(context: MiddlewareContext<T>, next: NextFunction, done: DoneFunction): void;
register(middleware: MiddlewareHandler<T>): void;
}
class Brain<A extends Adapter> extends EventEmitter {
constructor(robot: Robot<A>);
set(key: string, value: any): this;
get(key: string): any;
@ -20,34 +62,71 @@ declare namespace Hubot {
close(): void;
setAutoSave(enabled: boolean): void;
resetSaveInterval(seconds: number): void;
mergeData(data: any): void;
mergeData(data: {}): void;
users(): User[];
userForId(id: any): User;
userForName(name: string): User;
userForRawFuzzyName(fuzzyName: string): User;
userForFuzzyName(fuzzyName: string): User;
userForId(id: string, options?: {}): User;
userForName(name: string): User | null;
usersForRawFuzzyName(fuzzyName: string): User[];
usersForFuzzyName(fuzzyName: string): User[];
}
class User {
constructor(id: any, options?: any);
id: any;
constructor(id: string, options?: {});
id: string;
name: string;
[property: string]: any;
set(key: string, value: any): this;
get(key: string): any;
[property: string]: unknown;
}
class Message {
constructor(user: User, done?: boolean)
user: User;
text: string;
constructor(user: User, done?: boolean);
id: string;
user: User;
text: string | null;
room: string;
finish(): void;
}
class Response<R> {
match: RegExpMatchArray;
class TextMessage extends Message {
text: string;
constructor(user: User, text: string, id: string);
match(regex: RegExp): RegExpMatchArray;
toString(): string;
}
class EnterMessage extends Message {
text: null;
}
class LeaveMessage extends Message {
text: null;
}
class TopicMessage extends TextMessage {
text: string;
}
class CatchAllMessage extends Message {
message: Message;
constructor(robot: R, message: Message, match: RegExpMatchArray);
constructor(message: Message);
}
interface Envelope {
room: string;
user: User;
message: Message;
}
class Response<A extends Adapter = Adapter, M extends Message = Message> {
match: RegExpMatchArray;
message: Message;
envelope: Envelope;
constructor(robot: Robot<A>, message: Message, match: RegExpMatchArray);
send(...strings: string[]): void;
emote(...strings: string[]): void;
reply(...strings: string[]): void;
@ -55,31 +134,98 @@ declare namespace Hubot {
play(...strings: string[]): void;
locked(...strings: string[]): void;
random<T>(items: T[]): T;
finish(): void;
http(url: string, options?: HttpOptions): ScopedClient;
}
type ListenerCallback<R> = (response: Response<R>) => void;
type ListenerCallback<A extends Adapter = Adapter, M extends Message = Message> = (
response: Response<A, M>,
) => void;
type DoneFunction = () => void;
type NextFunction = (done: DoneFunction) => void;
interface MiddlewareContext<T extends Adapter = Adapter> {
response?: Response<T>;
[key: string]: unknown;
}
type MiddlewareHandler<T extends Adapter = Adapter> = (
context: MiddlewareContext<T>,
next: NextFunction,
done: DoneFunction,
) => void;
class Robot<A> {
alias: string;
brain: Brain<A>;
name: string;
interface LogLevel {
(...messages: any[]): void;
disable(): void;
enable(): void;
}
interface Log {
(...messages: any[]): void;
get(namespace: string): Log;
debug: LogLevel;
info: LogLevel;
notice: LogLevel;
warning: LogLevel;
error: LogLevel;
}
class Robot<A extends Adapter = Adapter> {
readonly name: string;
readonly events: EventEmitter;
readonly brain: Brain<A>;
readonly alias: string;
readonly adapterPath: string;
readonly adapterName: string;
readonly adapter: A;
readonly errorHandlers: [];
readonly onUncaughtException: (err: Error) => void;
readonly datastore: null | DataStore;
readonly commands: [];
readonly middleware: {
listener: Middleware<A>;
response: Middleware<A>;
receive: Middleware<A>;
};
readonly logger: Log;
readonly pingIntervalId: null | NodeJS.Timeout;
readonly globalHttpOptions: HttpOptions;
readonly version: string;
readonly server?: Server;
readonly router: Express;
constructor(adapterPath: string, adapter: string, httpd: boolean, name: string, alias?: string);
catchAll(callback: ListenerCallback<this>): void;
catchAll(options: any, callback: ListenerCallback<this>): void;
hear(regex: RegExp, callback: ListenerCallback<this>): void;
hear(regex: RegExp, options: any, callback: ListenerCallback<this>): void;
catchAll(callback: ListenerCallback<A, CatchAllMessage>): void;
catchAll(options: {}, callback: ListenerCallback<A, CatchAllMessage>): void;
emit(event: string | symbol, ...args: unknown[]): void;
enter(callback: ListenerCallback<A, EnterMessage>): void;
enter(options: {}, callback: ListenerCallback<A, EnterMessage>): void;
error(cb: (error: Error) => void): void;
hear(regex: RegExp, callback: ListenerCallback<A, TextMessage>): void;
hear(regex: RegExp, options: {}, callback: ListenerCallback<A, TextMessage>): void;
helpCommands(): string[];
http(url: string, options?: HttpOptions): ScopedClient;
leave(callback: ListenerCallback<A, LeaveMessage>): void;
leave(options: {}, callback: ListenerCallback<A, LeaveMessage>): void;
listen(matcher: (message: Message) => boolean, callback: ListenerCallback<A>): void;
listen(matcher: (message: Message) => boolean, options: {}, callback: ListenerCallback<A>): void;
listenerMiddleware(middleware: MiddlewareHandler<A>): void;
loadExternalScripts(packages: string[]): void;
loadFile(directory: string, fileName: string): void;
respond(regex: RegExp, callback: ListenerCallback<this>): void;
respond(regex: RegExp, options: any, callback: ListenerCallback<this>): void;
enter(callback: ListenerCallback<this>): void;
enter(options: any, callback: ListenerCallback<this>): void;
topic(callback: ListenerCallback<this>): void;
topic(options: any, callback: ListenerCallback<this>): void;
on(event: string | symbol, listener: (...args: any[]) => void): this;
emit(event: string | symbol, ...args: any[]): boolean;
loadHubotScripts(path: string, scripts: string[]): void;
messageRoom(room: string, ...strings: string[]): void;
on(event: string | symbol, listener: (...args: unknown[]) => void): this;
receive(message: Message, cb?: () => void): void;
receiveMiddleware(middleware: MiddlewareHandler<A>): void;
reply(envelope: Envelope, ...strings: string[]): void;
respond(regex: RegExp, callback: ListenerCallback<A, TextMessage>): void;
respond(regex: RegExp, options: {}, callback: ListenerCallback<A, TextMessage>): void;
respondPattern(regex: RegExp): RegExp;
responseMiddleware(middleware: MiddlewareHandler<A>): void;
run(): void;
send(envelope: Envelope, ...strings: string[]): void;
shutdown(): void;
topic(callback: ListenerCallback<A, TopicMessage>): void;
topic(options: {}, callback: ListenerCallback<A, TopicMessage>): void;
}
}