Comparing version 8.1.0 to 9.0.0
@@ -156,3 +156,3 @@ 'use strict' | ||
robot.run() | ||
await robot.run() | ||
})() |
{ | ||
"name": "hubot", | ||
"version": "8.1.0", | ||
"version": "9.0.0", | ||
"author": "hubot", | ||
@@ -27,13 +27,8 @@ "keywords": [ | ||
"devDependencies": { | ||
"chai": "^4.3.7", | ||
"is-circular": "^1.0.2", | ||
"mocha": "^10.2.0", | ||
"semantic-release": "^21.0.1", | ||
"sinon": "^15.0.4", | ||
"sinon-chai": "^3.7.0", | ||
"standard": "^17.1.0" | ||
}, | ||
"engines": { | ||
"node": "> 16.20.2", | ||
"npm": "> 8.19.4" | ||
"node": ">= 18", | ||
"npm": ">= 9" | ||
}, | ||
@@ -47,3 +42,3 @@ "main": "./index", | ||
"pretest": "standard", | ||
"test": "mocha --exit", | ||
"test": "node --test test/*_test.js", | ||
"test:smoke": "node src/**/*.js", | ||
@@ -50,0 +45,0 @@ "test:e2e": "bin/e2e-test.sh" |
@@ -30,3 +30,3 @@ 'use strict' | ||
async emote (envelope, ...strings) { | ||
return this.senda(envelope, ...strings) | ||
return this.send(envelope, ...strings) | ||
} | ||
@@ -61,4 +61,4 @@ | ||
// | ||
// Returns nothing. | ||
run () {} | ||
// Returns whatever the extended adapter returns. | ||
async run () {} | ||
@@ -68,3 +68,5 @@ // Public: Raw method for shutting the bot down. Extend this. | ||
// Returns nothing. | ||
close () {} | ||
close () { | ||
this.removeAllListeners() | ||
} | ||
@@ -81,4 +83,5 @@ // Public: Dispatch a received message to the robot. | ||
// Returns an Array of User objects. | ||
// @deprecated Use @robot.brain | ||
users () { | ||
this.robot.logger.warning('@users() is going to be deprecated in 3.0.0 use @robot.brain.users()') | ||
this.robot.logger.warning('@users() is going to be deprecated in 11.0.0 use @robot.brain.users()') | ||
return this.robot.brain.users() | ||
@@ -90,4 +93,5 @@ } | ||
// Returns a User instance of the specified user. | ||
// @deprecated Use @robot.brain | ||
userForId (id, options) { | ||
this.robot.logger.warning('@userForId() is going to be deprecated in 3.0.0 use @robot.brain.userForId()') | ||
this.robot.logger.warning('@userForId() is going to be deprecated in 11.0.0 use @robot.brain.userForId()') | ||
return this.robot.brain.userForId(id, options) | ||
@@ -99,4 +103,5 @@ } | ||
// Returns a User instance for the user with the specified name. | ||
// @deprecated Use @robot.brain | ||
userForName (name) { | ||
this.robot.logger.warning('@userForName() is going to be deprecated in 3.0.0 use @robot.brain.userForName()') | ||
this.robot.logger.warning('@userForName() is going to be deprecated in 11.0.0 use @robot.brain.userForName()') | ||
return this.robot.brain.userForName(name) | ||
@@ -110,4 +115,5 @@ } | ||
// Returns an Array of User instances matching the fuzzy name. | ||
// @deprecated Use @robot.brain | ||
usersForRawFuzzyName (fuzzyName) { | ||
this.robot.logger.warning('@userForRawFuzzyName() is going to be deprecated in 3.0.0 use @robot.brain.userForRawFuzzyName()') | ||
this.robot.logger.warning('@userForRawFuzzyName() is going to be deprecated in 11.0.0 use @robot.brain.userForRawFuzzyName()') | ||
return this.robot.brain.usersForRawFuzzyName(fuzzyName) | ||
@@ -121,4 +127,5 @@ } | ||
// Returns an Array of User instances matching the fuzzy name. | ||
// @deprecated Use @robot.brain | ||
usersForFuzzyName (fuzzyName) { | ||
this.robot.logger.warning('@userForFuzzyName() is going to be deprecated in 3.0.0 use @robot.brain.userForFuzzyName()') | ||
this.robot.logger.warning('@userForFuzzyName() is going to be deprecated in 11.0.0 use @robot.brain.userForFuzzyName()') | ||
return this.robot.brain.usersForFuzzyName(fuzzyName) | ||
@@ -133,4 +140,5 @@ } | ||
// Returns a ScopedClient instance. | ||
// @deprecated Use node.js fetch. | ||
http (url) { | ||
this.robot.logger.warning('@http() is going to be deprecated in 3.0.0 use @robot.http()') | ||
this.robot.logger.warning('@http() is going to be deprecated in 11.0.0 use @robot.http()') | ||
return this.robot.http(url) | ||
@@ -137,0 +145,0 @@ } |
@@ -85,3 +85,3 @@ 'use strict' | ||
run () { | ||
async run () { | ||
const self = this | ||
@@ -88,0 +88,0 @@ |
@@ -20,2 +20,3 @@ 'use strict' | ||
class Shell extends Adapter { | ||
#rl = null | ||
constructor (robot) { | ||
@@ -39,17 +40,23 @@ super(robot) | ||
run () { | ||
async run () { | ||
this.buildCli() | ||
loadHistory((error, history) => { | ||
if (error) { | ||
console.log(error.message) | ||
} | ||
try { | ||
const { readlineInterface, history } = await this.#loadHistory() | ||
this.cli.history(history) | ||
this.cli.interact(`${this.robot.name}> `) | ||
return this.emit('connected', this) | ||
}) | ||
this.cli.interact(`${this.robot.name ?? this.robot.alias}> `) | ||
this.#rl = readlineInterface | ||
this.emit('connected', this) | ||
} catch (error) { | ||
console.log(error) | ||
} | ||
} | ||
shutdown () { | ||
this.robot.shutdown() | ||
return process.exit(0) | ||
close () { | ||
super.close() | ||
// Getting an error message on GitHubt Actions: error: 'this[#rl].close is not a function' | ||
if (this.#rl?.close) { | ||
this.#rl.close() | ||
} | ||
this.cli.removeAllListeners() | ||
this.cli.close() | ||
} | ||
@@ -60,3 +67,3 @@ | ||
this.cli.command('*', input => { | ||
this.cli.command('*', async input => { | ||
let userId = process.env.HUBOT_SHELL_USER_ID || '1' | ||
@@ -69,3 +76,3 @@ if (userId.match(/A\d+z/)) { | ||
const user = this.robot.brain.userForId(userId, { name: userName, room: 'Shell' }) | ||
this.receive(new TextMessage(user, input, 'messageId')) | ||
await this.receive(new TextMessage(user, input, 'messageId')) | ||
}) | ||
@@ -93,3 +100,3 @@ | ||
if (history.length <= historySize) { | ||
return this.shutdown() | ||
return | ||
} | ||
@@ -104,3 +111,2 @@ | ||
const outstream = fs.createWriteStream(historyPath, fileOpts) | ||
outstream.on('end', this.shutdown.bind(this)) | ||
for (i = 0, len = history.length; i < len; i++) { | ||
@@ -110,4 +116,29 @@ item = history[i] | ||
} | ||
outstream.end() | ||
}) | ||
} | ||
async #loadHistory () { | ||
if (!fs.existsSync(historyPath)) { | ||
return new Error('No history available') | ||
} | ||
const instream = fs.createReadStream(historyPath) | ||
const outstream = new Stream() | ||
outstream.readable = true | ||
outstream.writable = true | ||
const history = [] | ||
const readlineInterface = readline.createInterface({ input: instream, output: outstream, terminal: false }) | ||
return new Promise((resolve, reject) => { | ||
readlineInterface.on('line', line => { | ||
line = line.trim() | ||
if (line.length > 0) { | ||
history.push(line) | ||
} | ||
}) | ||
readlineInterface.on('close', () => { | ||
resolve({ readlineInterface, history }) | ||
}) | ||
readlineInterface.on('error', reject) | ||
}) | ||
} | ||
} | ||
@@ -118,27 +149,1 @@ | ||
exports.use = robot => new Shell(robot) | ||
// load history from .hubot_history. | ||
// | ||
// callback - A Function that is called with the loaded history items (or an empty array if there is no history) | ||
function loadHistory (callback) { | ||
if (!fs.existsSync(historyPath)) { | ||
return callback(new Error('No history available')) | ||
} | ||
const instream = fs.createReadStream(historyPath) | ||
const outstream = new Stream() | ||
outstream.readable = true | ||
outstream.writable = true | ||
const items = [] | ||
readline.createInterface({ input: instream, output: outstream, terminal: false }) | ||
.on('line', function (line) { | ||
line = line.trim() | ||
if (line.length > 0) { | ||
items.push(line) | ||
} | ||
}) | ||
.on('close', () => callback(null, items)) | ||
.on('error', callback) | ||
} |
@@ -112,2 +112,3 @@ 'use strict' | ||
this.emit('close') | ||
this.removeAllListeners() | ||
} | ||
@@ -114,0 +115,0 @@ |
@@ -16,4 +16,4 @@ 'use strict' | ||
// Value can be any JSON-serializable type. | ||
set (key, value) { | ||
return this._set(key, value, 'global') | ||
async set (key, value) { | ||
return await this._set(key, value, 'global') | ||
} | ||
@@ -24,8 +24,7 @@ | ||
// present, it's instantiated as an empty object. | ||
setObject (key, objectKey, value) { | ||
return this.get(key).then((object) => { | ||
const target = object || {} | ||
target[objectKey] = value | ||
return this.set(key, target) | ||
}) | ||
async setObject (key, objectKey, value) { | ||
const object = await this.get(key) | ||
const target = object || {} | ||
target[objectKey] = value | ||
return await this.set(key, target) | ||
} | ||
@@ -36,13 +35,12 @@ | ||
// present, it's instantiated as an empty array. | ||
setArray (key, value) { | ||
return this.get(key).then((object) => { | ||
const target = object || [] | ||
// Extend the array if the value is also an array, otherwise | ||
// push the single value on the end. | ||
if (Array.isArray(value)) { | ||
return this.set(key, target.push.apply(target, value)) | ||
} else { | ||
return this.set(key, target.concat(value)) | ||
} | ||
}) | ||
async setArray (key, value) { | ||
const object = await this.get(key) | ||
const target = object ?? [] | ||
// Extend the array if the value is also an array, otherwise | ||
// push the single value on the end. | ||
if (Array.isArray(value)) { | ||
return await this.set(key, target.concat(value)) | ||
} else { | ||
return await this.set(key, target.concat([value])) | ||
} | ||
} | ||
@@ -53,4 +51,4 @@ | ||
// requested value. | ||
get (key) { | ||
return this._get(key, 'global') | ||
async get (key) { | ||
return await this._get(key, 'global') | ||
} | ||
@@ -61,7 +59,6 @@ | ||
// contain an `objectKey`, returns `undefined`. | ||
getObject (key, objectKey) { | ||
return this.get(key).then((object) => { | ||
const target = object || {} | ||
return target[objectKey] | ||
}) | ||
async getObject (key, objectKey) { | ||
const object = await this.get(key) | ||
const target = object || {} | ||
return target[objectKey] | ||
} | ||
@@ -78,3 +75,3 @@ | ||
_set (key, value, table) { | ||
return Promise.reject(new DataStoreUnavailable('Setter called on the abstract class.')) | ||
throw new DataStoreUnavailable('Setter called on the abstract class.') | ||
} | ||
@@ -91,3 +88,3 @@ | ||
_get (key, table) { | ||
return Promise.reject(new DataStoreUnavailable('Getter called on the abstract class.')) | ||
throw new DataStoreUnavailable('Getter called on the abstract class.') | ||
} | ||
@@ -94,0 +91,0 @@ } |
'use strict' | ||
const DataStore = require('../datastore').DataStore | ||
const DataStore = require('../datastore.js').DataStore | ||
@@ -14,7 +14,7 @@ class InMemoryDataStore extends DataStore { | ||
_get (key, table) { | ||
async _get (key, table) { | ||
return Promise.resolve(this.data[table][key]) | ||
} | ||
_set (key, value, table) { | ||
async _set (key, value, table) { | ||
return Promise.resolve(this.data[table][key] = value) | ||
@@ -21,0 +21,0 @@ } |
@@ -68,3 +68,3 @@ 'use strict' | ||
async play (...strings) { | ||
return await this.#runWithMiddleware('play', ...strings) | ||
return await this.#runWithMiddleware('play', {}, ...strings) | ||
} | ||
@@ -71,0 +71,0 @@ |
@@ -53,7 +53,2 @@ 'use strict' | ||
}) | ||
Reflect.defineProperty(this.logger, 'warning', { | ||
value: this.logger.warn, | ||
enumerable: true, | ||
configurable: true | ||
}) | ||
@@ -76,6 +71,2 @@ this.pingIntervalId = null | ||
}) | ||
this.onUncaughtException = err => { | ||
return this.emit('error', err) | ||
} | ||
process.on('uncaughtException', this.onUncaughtException) | ||
} | ||
@@ -237,5 +228,4 @@ | ||
this.listen(isCatchAllMessage, options, function listenCallback (msg) { | ||
msg.message = msg.message.message | ||
callback(msg) | ||
this.listen(isCatchAllMessage, options, async msg => { | ||
await callback(msg.message) | ||
}) | ||
@@ -382,3 +372,3 @@ } | ||
this.logger.error(`Unable to load ${full}: ${error.stack}`) | ||
process.exit(1) | ||
throw error | ||
} | ||
@@ -418,3 +408,3 @@ } | ||
this.logger.error(`Error loading scripts from npm package - ${error.stack}`) | ||
process.exit(1) | ||
throw error | ||
} | ||
@@ -467,5 +457,4 @@ } | ||
} catch (error) { | ||
const err = error | ||
this.logger.error(`Error trying to start HTTP server: ${err}\n${err.stack}`) | ||
process.exit(1) | ||
this.logger.error(`Error trying to start HTTP server: ${error}\n${error.stack}`) | ||
throw error | ||
} | ||
@@ -529,5 +518,5 @@ | ||
} | ||
} catch (err) { | ||
this.logger.error(`Cannot load adapter ${adapterPath ?? '[no path set]'} ${this.adapterName} - ${err}`) | ||
process.exit(1) | ||
} catch (error) { | ||
this.logger.error(`Cannot load adapter ${adapterPath ?? '[no path set]'} ${this.adapterName} - ${error}`) | ||
throw error | ||
} | ||
@@ -664,7 +653,7 @@ } | ||
// | ||
// Returns nothing. | ||
run () { | ||
// Returns whatever the adapter returns. | ||
async run () { | ||
this.emit('running') | ||
this.adapter.run() | ||
return await this.adapter.run() | ||
} | ||
@@ -679,9 +668,8 @@ | ||
} | ||
process.removeListener('uncaughtException', this.onUncaughtException) | ||
this.adapter.close() | ||
this.adapter?.close() | ||
if (this.server) { | ||
this.server.close() | ||
} | ||
this.brain.close() | ||
this.events.removeAllListeners() | ||
} | ||
@@ -688,0 +676,0 @@ |
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
92308
2
2367