hubot 10.0.5 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -3
- package/bin/{hubot.js → Hubot.mjs} +14 -22
- package/bin/hubot +2 -8
- package/index.mjs +52 -0
- package/package.json +2 -3
- package/src/{adapter.js → Adapter.mjs} +2 -2
- package/src/{brain.js → Brain.mjs} +3 -4
- package/src/{datastore.js → DataStore.mjs} +3 -3
- package/src/{GenHubot.js → GenHubot.mjs} +18 -6
- package/src/{httpclient.js → HttpClient.mjs} +9 -6
- package/src/{listener.js → Listener.mjs} +4 -5
- package/src/{message.js → Message.mjs} +7 -7
- package/src/{middleware.js → Middleware.mjs} +1 -1
- package/src/{OptParse.js → OptParse.mjs} +2 -2
- package/src/{response.js → Response.mjs} +1 -1
- package/src/{robot.js → Robot.mjs} +57 -46
- package/src/{user.js → User.mjs} +2 -2
- package/src/adapters/{campfire.js → Campfire.mjs} +10 -13
- package/src/adapters/{shell.js → Shell.mjs} +10 -6
- package/src/datastores/{memory.js → Memory.mjs} +2 -2
- package/es2015.js +0 -31
- package/index.js +0 -40
package/README.md
CHANGED
|
@@ -6,9 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
# Hubot
|
|
8
8
|
|
|
9
|
-
**Note: v10.0.4 contains the removal of CoffeeScript**
|
|
10
|
-
|
|
11
|
-
Semver is looking for **BREAKING CHANGE** singular, not **BREAKING CHANGES**. As a result, the removal of CoffeeScript was marked as the `v10.0.4` release.
|
|
9
|
+
**Note: v10.0.4 accidentaly contains the removal of CoffeeScript; v10.0.5 puts it back in**
|
|
10
|
+
**Note: v11 removes CoffeeScript and converts this codebase to ESM**
|
|
12
11
|
|
|
13
12
|
Hubot is a framework to build chat bots, modeled after GitHub's Campfire bot of the same name, hubot.
|
|
14
13
|
He's pretty cool. He's [extendable with scripts](https://hubotio.github.io/hubot/docs#scripts) and can work
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const Hubot = require('..')
|
|
9
|
-
const create = require('../src/GenHubot.js')
|
|
3
|
+
import fs from 'node:fs'
|
|
4
|
+
import { resolve as pathResolve } from 'node:path'
|
|
5
|
+
import OptParse from '../src/OptParse.mjs'
|
|
6
|
+
import Hubot from '../index.mjs'
|
|
7
|
+
import create from '../src/GenHubot.mjs'
|
|
10
8
|
|
|
11
9
|
const switches = [
|
|
12
|
-
['-a', '--adapter HUBOT_ADAPTER', 'The Adapter to use, e.g. "
|
|
10
|
+
['-a', '--adapter HUBOT_ADAPTER', 'The Adapter to use, e.g. "Shell" (to load the default hubot Shell adapter)'],
|
|
13
11
|
['-f', '--file HUBOT_FILE', 'Path to adapter file, e.g. "./adapters/CustomAdapter.mjs"'],
|
|
14
12
|
['-c', '--create HUBOT_CREATE', 'Create a deployable hubot'],
|
|
15
13
|
['-d', '--disable-httpd HUBOT_HTTPD', 'Disable the HTTP server'],
|
|
@@ -97,13 +95,13 @@ if (options.file) {
|
|
|
97
95
|
}
|
|
98
96
|
|
|
99
97
|
const robot = Hubot.loadBot(options.adapter, options.enableHttpd, options.name, options.alias)
|
|
100
|
-
|
|
98
|
+
export default robot
|
|
101
99
|
|
|
102
100
|
async function loadScripts () {
|
|
103
101
|
await robot.load(pathResolve('.', 'scripts'))
|
|
104
102
|
await robot.load(pathResolve('.', 'src', 'scripts'))
|
|
105
103
|
|
|
106
|
-
loadExternalScripts()
|
|
104
|
+
await loadExternalScripts()
|
|
107
105
|
|
|
108
106
|
const tasks = options.scripts.map((scriptPath) => {
|
|
109
107
|
if (scriptPath[0] === '/') {
|
|
@@ -115,25 +113,19 @@ async function loadScripts () {
|
|
|
115
113
|
await Promise.all(tasks)
|
|
116
114
|
}
|
|
117
115
|
|
|
118
|
-
function loadExternalScripts () {
|
|
116
|
+
async function loadExternalScripts () {
|
|
119
117
|
const externalScripts = pathResolve('.', 'external-scripts.json')
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
return
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
fs.readFile(externalScripts, function (error, data) {
|
|
126
|
-
if (error) {
|
|
127
|
-
throw error
|
|
128
|
-
}
|
|
129
|
-
|
|
118
|
+
try {
|
|
119
|
+
const data = await fs.promises.readFile(externalScripts)
|
|
130
120
|
try {
|
|
131
121
|
robot.loadExternalScripts(JSON.parse(data))
|
|
132
122
|
} catch (error) {
|
|
133
123
|
console.error(`Error parsing JSON data from external-scripts.json: ${error}`)
|
|
134
124
|
process.exit(1)
|
|
135
125
|
}
|
|
136
|
-
})
|
|
126
|
+
} catch (e) {
|
|
127
|
+
robot.logger.info('No external-scripts.json found. Skipping.')
|
|
128
|
+
}
|
|
137
129
|
}
|
|
138
130
|
|
|
139
131
|
(async () => {
|
package/bin/hubot
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
# we left the `bin/hubot` file to remain in CoffeeScript in order prevent
|
|
5
|
-
# breaking existing 3rd party adapters of which some are still written in
|
|
6
|
-
# CoffeeScript themselves. We will deprecate and eventually remove this file
|
|
7
|
-
# in a future version of hubot
|
|
8
|
-
|
|
9
|
-
require './hubot.js'
|
|
3
|
+
import('./Hubot.mjs').then(async ({ default: robot }) => {})
|
package/index.mjs
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import User from './src/User.mjs'
|
|
4
|
+
import Brain from './src/Brain.mjs'
|
|
5
|
+
import Robot from './src/Robot.mjs'
|
|
6
|
+
import Adapter from './src/Adapter.mjs'
|
|
7
|
+
import Response from './src/Response.mjs'
|
|
8
|
+
import Middleware from './src/Middleware.mjs'
|
|
9
|
+
import { Listener, TextListener } from './src/Listener.mjs'
|
|
10
|
+
import { TextMessage, EnterMessage, LeaveMessage, TopicMessage, CatchAllMessage, Message } from './src/Message.mjs'
|
|
11
|
+
import { DataStore, DataStoreUnavailable } from './src/DataStore.mjs'
|
|
12
|
+
|
|
13
|
+
const loadBot = (adapter, enableHttpd, name, alias) => new Robot(adapter, enableHttpd, name, alias)
|
|
14
|
+
export {
|
|
15
|
+
Adapter,
|
|
16
|
+
User,
|
|
17
|
+
Brain,
|
|
18
|
+
Robot,
|
|
19
|
+
Response,
|
|
20
|
+
Listener,
|
|
21
|
+
TextListener,
|
|
22
|
+
Message,
|
|
23
|
+
TextMessage,
|
|
24
|
+
EnterMessage,
|
|
25
|
+
LeaveMessage,
|
|
26
|
+
TopicMessage,
|
|
27
|
+
CatchAllMessage,
|
|
28
|
+
DataStore,
|
|
29
|
+
DataStoreUnavailable,
|
|
30
|
+
Middleware,
|
|
31
|
+
loadBot
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default {
|
|
35
|
+
Adapter,
|
|
36
|
+
User,
|
|
37
|
+
Brain,
|
|
38
|
+
Robot,
|
|
39
|
+
Response,
|
|
40
|
+
Listener,
|
|
41
|
+
TextListener,
|
|
42
|
+
Message,
|
|
43
|
+
TextMessage,
|
|
44
|
+
EnterMessage,
|
|
45
|
+
LeaveMessage,
|
|
46
|
+
TopicMessage,
|
|
47
|
+
CatchAllMessage,
|
|
48
|
+
DataStore,
|
|
49
|
+
DataStoreUnavailable,
|
|
50
|
+
Middleware,
|
|
51
|
+
loadBot
|
|
52
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hubot",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "11.0.0",
|
|
4
4
|
"author": "hubot",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"github",
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
"url": "https://github.com/hubotio/hubot.git"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"coffeescript": "^2.7.0",
|
|
19
18
|
"connect-multiparty": "^2.2.0",
|
|
20
19
|
"express": "^4.18.2",
|
|
21
20
|
"express-basic-auth": "^1.2.1",
|
|
@@ -28,7 +27,7 @@
|
|
|
28
27
|
"node": ">= 18",
|
|
29
28
|
"npm": ">= 9"
|
|
30
29
|
},
|
|
31
|
-
"main": "./index",
|
|
30
|
+
"main": "./index.mjs",
|
|
32
31
|
"bin": {
|
|
33
32
|
"hubot": "./bin/hubot"
|
|
34
33
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import EventEmitter from 'node:events'
|
|
4
4
|
|
|
5
5
|
class Adapter extends EventEmitter {
|
|
6
6
|
// An adapter is a specific interface to a chat source for robots.
|
|
@@ -136,4 +136,4 @@ class Adapter extends EventEmitter {
|
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
|
|
139
|
+
export default Adapter
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const User = require('./user')
|
|
3
|
+
import EventEmitter from 'node:events'
|
|
4
|
+
import User from './User.mjs'
|
|
6
5
|
|
|
7
6
|
// If necessary, reconstructs a User object. Returns either:
|
|
8
7
|
//
|
|
@@ -239,4 +238,4 @@ class Brain extends EventEmitter {
|
|
|
239
238
|
}
|
|
240
239
|
}
|
|
241
240
|
|
|
242
|
-
|
|
241
|
+
export default Brain
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
class DataStore {
|
|
3
|
+
export class DataStore {
|
|
4
4
|
// Represents a persistent, database-backed storage for the robot. Extend this.
|
|
5
5
|
//
|
|
6
6
|
// Returns a new Datastore with no storage.
|
|
@@ -83,9 +83,9 @@ class DataStore {
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
class DataStoreUnavailable extends Error {}
|
|
86
|
+
export class DataStoreUnavailable extends Error {}
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
export default {
|
|
89
89
|
DataStore,
|
|
90
90
|
DataStoreUnavailable
|
|
91
91
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { spawnSync } from 'node:child_process'
|
|
2
|
+
import File from 'node:fs'
|
|
3
|
+
import path from 'node:path'
|
|
4
4
|
|
|
5
5
|
function runCommands (hubotDirectory, options) {
|
|
6
6
|
options.hubotInstallationPath = options?.hubotInstallationPath ?? 'hubot'
|
|
@@ -13,8 +13,19 @@ function runCommands (hubotDirectory, options) {
|
|
|
13
13
|
const envFilePath = path.resolve(process.cwd(), '.env')
|
|
14
14
|
process.chdir(hubotDirectory)
|
|
15
15
|
|
|
16
|
-
spawnSync('npm', ['init', '-y'])
|
|
17
|
-
|
|
16
|
+
let output = spawnSync('npm', ['init', '-y'])
|
|
17
|
+
console.log('npm init', output.stderr.toString())
|
|
18
|
+
if (options.hubotInstallationPath !== 'hubot') {
|
|
19
|
+
output = spawnSync('npm', ['pack', `${options.hubotInstallationPath}`])
|
|
20
|
+
console.log('npm pack', output.stderr.toString(), output.stdout.toString())
|
|
21
|
+
const customHubotPackage = JSON.parse(File.readFileSync(`${options.hubotInstallationPath}/package.json`, 'utf8'))
|
|
22
|
+
output = spawnSync('npm', ['i', `${customHubotPackage.name}-${customHubotPackage.version}.tgz`])
|
|
23
|
+
console.log(`npm i ${customHubotPackage.name}-${customHubotPackage.version}.tgz`, output.stderr.toString(), output.stdout.toString())
|
|
24
|
+
} else {
|
|
25
|
+
output = spawnSync('npm', ['i', 'hubot@latest'])
|
|
26
|
+
}
|
|
27
|
+
output = spawnSync('npm', ['i', 'hubot-help@latest', 'hubot-rules@latest', 'hubot-diagnostics@latest'].concat([options.adapter]).filter(Boolean))
|
|
28
|
+
console.log('npm i', output.stderr.toString(), output.stdout.toString())
|
|
18
29
|
spawnSync('mkdir', ['scripts'])
|
|
19
30
|
spawnSync('touch', ['external-scripts.json'])
|
|
20
31
|
|
|
@@ -50,6 +61,7 @@ export default (robot) => {
|
|
|
50
61
|
packageJson.scripts = {
|
|
51
62
|
start: 'hubot'
|
|
52
63
|
}
|
|
64
|
+
packageJson.description = 'A simple helpful robot for your Company'
|
|
53
65
|
if (options.adapter) {
|
|
54
66
|
packageJson.scripts.start += ` --adapter ${options.adapter}`
|
|
55
67
|
}
|
|
@@ -79,7 +91,7 @@ export default (robot) => {
|
|
|
79
91
|
console.log('.env file not found, continuing to the next operation.')
|
|
80
92
|
}
|
|
81
93
|
}
|
|
82
|
-
|
|
94
|
+
export default (hubotDirectory, options) => {
|
|
83
95
|
try {
|
|
84
96
|
runCommands(hubotDirectory, options)
|
|
85
97
|
} catch (error) {
|
|
@@ -33,10 +33,10 @@ Implement a phased approach to deprecate `robot.http` all together in favor of `
|
|
|
33
33
|
2. Add a deprecation warning to `robot.http`
|
|
34
34
|
3. Remove `robot.http` in a future release
|
|
35
35
|
*/
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
import path from 'node:path'
|
|
37
|
+
import http from 'node:http'
|
|
38
|
+
import https from 'node:https'
|
|
39
|
+
import qs from 'node:querystring'
|
|
40
40
|
|
|
41
41
|
const nonPassThroughOptions = [
|
|
42
42
|
'headers', 'hostname', 'encoding', 'auth', 'port',
|
|
@@ -308,5 +308,8 @@ const reduce = function (a, b) {
|
|
|
308
308
|
}
|
|
309
309
|
return a
|
|
310
310
|
}
|
|
311
|
-
|
|
312
|
-
|
|
311
|
+
export default {
|
|
312
|
+
create (url, options) {
|
|
313
|
+
return new ScopedClient(url, options)
|
|
314
|
+
}
|
|
315
|
+
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const Middleware = require('./middleware')
|
|
3
|
+
import { inspect } from 'node:util'
|
|
4
|
+
import { TextMessage } from './Message.mjs'
|
|
5
|
+
import Middleware from './Middleware.mjs'
|
|
7
6
|
|
|
8
7
|
class Listener {
|
|
9
8
|
// Listeners receive every message from the chat source and decide if they
|
|
@@ -108,7 +107,7 @@ class TextListener extends Listener {
|
|
|
108
107
|
}
|
|
109
108
|
}
|
|
110
109
|
|
|
111
|
-
|
|
110
|
+
export {
|
|
112
111
|
Listener,
|
|
113
112
|
TextListener
|
|
114
113
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
class Message {
|
|
3
|
+
export class Message {
|
|
4
4
|
// Represents an incoming message from the chat.
|
|
5
5
|
//
|
|
6
6
|
// user - A User instance that sent the message.
|
|
@@ -18,7 +18,7 @@ class Message {
|
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
class TextMessage extends Message {
|
|
21
|
+
export class TextMessage extends Message {
|
|
22
22
|
// Represents an incoming message from the chat.
|
|
23
23
|
//
|
|
24
24
|
// user - A User instance that sent the message.
|
|
@@ -52,23 +52,23 @@ class TextMessage extends Message {
|
|
|
52
52
|
// user - A User instance for the user who entered.
|
|
53
53
|
// text - Always null.
|
|
54
54
|
// id - A String of the message ID.
|
|
55
|
-
class EnterMessage extends Message {}
|
|
55
|
+
export class EnterMessage extends Message {}
|
|
56
56
|
|
|
57
57
|
// Represents an incoming user exit notification.
|
|
58
58
|
//
|
|
59
59
|
// user - A User instance for the user who left.
|
|
60
60
|
// text - Always null.
|
|
61
61
|
// id - A String of the message ID.
|
|
62
|
-
class LeaveMessage extends Message {}
|
|
62
|
+
export class LeaveMessage extends Message {}
|
|
63
63
|
|
|
64
64
|
// Represents an incoming topic change notification.
|
|
65
65
|
//
|
|
66
66
|
// user - A User instance for the user who changed the topic.
|
|
67
67
|
// text - A String of the new topic
|
|
68
68
|
// id - A String of the message ID.
|
|
69
|
-
class TopicMessage extends TextMessage {}
|
|
69
|
+
export class TopicMessage extends TextMessage {}
|
|
70
70
|
|
|
71
|
-
class CatchAllMessage extends Message {
|
|
71
|
+
export class CatchAllMessage extends Message {
|
|
72
72
|
// Represents a message that no matchers matched.
|
|
73
73
|
//
|
|
74
74
|
// message - The original message.
|
|
@@ -78,7 +78,7 @@ class CatchAllMessage extends Message {
|
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
export default {
|
|
82
82
|
Message,
|
|
83
83
|
TextMessage,
|
|
84
84
|
EnterMessage,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import EventEmitter from 'node:events'
|
|
2
2
|
class OptParse extends EventEmitter {
|
|
3
3
|
constructor (switches) {
|
|
4
4
|
super()
|
|
@@ -41,4 +41,4 @@ ${this.switches.map(([key, description]) => ` ${key}, ${description}`).join('\n
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
export default OptParse
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
-
const EventEmitter = require('events').EventEmitter
|
|
3
|
-
const fs = require('fs')
|
|
4
|
-
const path = require('path')
|
|
5
|
-
const pathToFileURL = require('url').pathToFileURL
|
|
6
2
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
3
|
+
import EventEmitter from 'node:events'
|
|
4
|
+
import fs from 'node:fs'
|
|
5
|
+
import path from 'node:path'
|
|
6
|
+
import { pathToFileURL, fileURLToPath } from 'node:url'
|
|
7
|
+
import pino from 'pino'
|
|
8
|
+
import HttpClient from './HttpClient.mjs'
|
|
9
|
+
import Brain from './Brain.mjs'
|
|
10
|
+
import Response from './Response.mjs'
|
|
11
|
+
import { Listener, TextListener } from './Listener.mjs'
|
|
12
|
+
import Message from './Message.mjs'
|
|
13
|
+
import Middleware from './Middleware.mjs'
|
|
14
|
+
|
|
15
|
+
const HUBOT_DEFAULT_ADAPTERS = ['Campfire', 'Shell']
|
|
17
16
|
const HUBOT_DOCUMENTATION_SECTIONS = ['description', 'dependencies', 'configuration', 'commands', 'notes', 'author', 'authors', 'examples', 'tags', 'urls']
|
|
18
17
|
|
|
18
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
19
|
+
const __dirname = path.dirname(__filename)
|
|
20
|
+
|
|
19
21
|
class Robot {
|
|
20
22
|
// Robots receive messages from a chat source (Campfire, irc, etc), and
|
|
21
23
|
// dispatch them to matching listeners.
|
|
@@ -37,6 +39,14 @@ class Robot {
|
|
|
37
39
|
this.brain = new Brain(this)
|
|
38
40
|
this.alias = alias
|
|
39
41
|
this.adapter = null
|
|
42
|
+
this.adaptername = 'Shell'
|
|
43
|
+
if (adapter && typeof (adapter) === 'object') {
|
|
44
|
+
this.adapter = adapter
|
|
45
|
+
this.adapterName = adapter.name ?? adapter.constructor.name
|
|
46
|
+
} else {
|
|
47
|
+
this.adapterName = adapter ?? this.adaptername
|
|
48
|
+
}
|
|
49
|
+
|
|
40
50
|
this.shouldEnableHttpd = httpd ?? true
|
|
41
51
|
this.datastore = null
|
|
42
52
|
this.Response = Response
|
|
@@ -56,7 +66,6 @@ class Robot {
|
|
|
56
66
|
this.globalHttpOptions = {}
|
|
57
67
|
|
|
58
68
|
this.parseVersion()
|
|
59
|
-
this.adapterName = adapter ?? 'shell'
|
|
60
69
|
this.errorHandlers = []
|
|
61
70
|
|
|
62
71
|
this.on('error', (err, res) => {
|
|
@@ -78,7 +87,7 @@ class Robot {
|
|
|
78
87
|
//
|
|
79
88
|
// Returns nothing.
|
|
80
89
|
listen (matcher, options, callback) {
|
|
81
|
-
this.listeners.push(new Listener
|
|
90
|
+
this.listeners.push(new Listener(this, matcher, options, callback))
|
|
82
91
|
}
|
|
83
92
|
|
|
84
93
|
// Public: Adds a Listener that attempts to match incoming messages based on
|
|
@@ -91,7 +100,7 @@ class Robot {
|
|
|
91
100
|
//
|
|
92
101
|
// Returns nothing.
|
|
93
102
|
hear (regex, options, callback) {
|
|
94
|
-
this.listeners.push(new
|
|
103
|
+
this.listeners.push(new TextListener(this, regex, options, callback))
|
|
95
104
|
}
|
|
96
105
|
|
|
97
106
|
// Public: Adds a Listener that attempts to match incoming messages directed
|
|
@@ -328,12 +337,8 @@ class Robot {
|
|
|
328
337
|
}
|
|
329
338
|
}
|
|
330
339
|
|
|
331
|
-
async loadcoffee (filePath) {
|
|
332
|
-
return await this.loadjs(filePath)
|
|
333
|
-
}
|
|
334
|
-
|
|
335
340
|
async loadjs (filePath) {
|
|
336
|
-
const script =
|
|
341
|
+
const script = (await import(filePath)).default
|
|
337
342
|
if (typeof script === 'function') {
|
|
338
343
|
script(this)
|
|
339
344
|
} else {
|
|
@@ -352,7 +357,7 @@ class Robot {
|
|
|
352
357
|
const full = path.join(filepath, path.basename(filename))
|
|
353
358
|
|
|
354
359
|
// see https://github.com/hubotio/hubot/issues/1355
|
|
355
|
-
if (['js', 'mjs'
|
|
360
|
+
if (['js', 'mjs'].indexOf(ext) === -1) {
|
|
356
361
|
this.logger.debug(`Skipping unsupported file type ${full}`)
|
|
357
362
|
return
|
|
358
363
|
}
|
|
@@ -386,15 +391,19 @@ class Robot {
|
|
|
386
391
|
// packages - An Array of packages containing hubot scripts to load.
|
|
387
392
|
//
|
|
388
393
|
// Returns nothing.
|
|
389
|
-
loadExternalScripts (packages) {
|
|
394
|
+
async loadExternalScripts (packages) {
|
|
390
395
|
this.logger.debug('Loading external-scripts from npm packages')
|
|
391
396
|
|
|
392
397
|
try {
|
|
393
398
|
if (Array.isArray(packages)) {
|
|
394
|
-
|
|
399
|
+
for await (const pkg of packages) {
|
|
400
|
+
(await import(pkg)).default(this)
|
|
401
|
+
}
|
|
402
|
+
return
|
|
403
|
+
}
|
|
404
|
+
for await (const key of Object.keys(packages)) {
|
|
405
|
+
(await import(key)).default(this, packages[key])
|
|
395
406
|
}
|
|
396
|
-
|
|
397
|
-
Object.keys(packages).forEach(key => require(key)(this, packages[key]))
|
|
398
407
|
} catch (error) {
|
|
399
408
|
this.logger.error(`Error loading scripts from npm package - ${error.stack}`)
|
|
400
409
|
throw error
|
|
@@ -413,9 +422,9 @@ class Robot {
|
|
|
413
422
|
const limit = process.env.EXPRESS_LIMIT || '100kb'
|
|
414
423
|
const paramLimit = parseInt(process.env.EXPRESS_PARAMETER_LIMIT) || 1000
|
|
415
424
|
|
|
416
|
-
const express =
|
|
417
|
-
const basicAuth =
|
|
418
|
-
const multipart =
|
|
425
|
+
const express = (await import('express')).default
|
|
426
|
+
const basicAuth = (await import('express-basic-auth')).default
|
|
427
|
+
const multipart = (await import('connect-multiparty')).default
|
|
419
428
|
|
|
420
429
|
const app = express()
|
|
421
430
|
|
|
@@ -475,19 +484,23 @@ class Robot {
|
|
|
475
484
|
//
|
|
476
485
|
// Returns nothing.
|
|
477
486
|
async loadAdapter (adapterPath = null) {
|
|
487
|
+
if (this.adapter) {
|
|
488
|
+
this.adapter = await this.adapter.use(this)
|
|
489
|
+
return
|
|
490
|
+
}
|
|
478
491
|
this.logger.debug(`Loading adapter ${adapterPath ?? 'from npmjs:'} ${this.adapterName}`)
|
|
479
|
-
const ext = path.extname(adapterPath ?? '') ?? '.
|
|
492
|
+
const ext = path.extname(adapterPath ?? '') ?? '.mjs'
|
|
480
493
|
try {
|
|
481
494
|
if (Array.from(HUBOT_DEFAULT_ADAPTERS).indexOf(this.adapterName) > -1) {
|
|
482
|
-
this.adapter = this.requireAdapterFrom(path.resolve(path.join(__dirname, 'adapters', this.adapterName)))
|
|
483
|
-
} else if (['.js', '.cjs'
|
|
484
|
-
this.adapter = this.requireAdapterFrom(path.resolve(adapterPath))
|
|
495
|
+
this.adapter = await this.requireAdapterFrom(path.resolve(path.join(__dirname, 'adapters', `${this.adapterName}.mjs`)))
|
|
496
|
+
} else if (['.js', '.cjs'].includes(ext)) {
|
|
497
|
+
this.adapter = await this.requireAdapterFrom(path.resolve(adapterPath))
|
|
485
498
|
} else if (['.mjs'].includes(ext)) {
|
|
486
499
|
this.adapter = await this.importAdapterFrom(pathToFileURL(path.resolve(adapterPath)).href)
|
|
487
500
|
} else {
|
|
488
501
|
const adapterPathInCurrentWorkingDirectory = this.adapterName
|
|
489
502
|
try {
|
|
490
|
-
this.adapter = this.requireAdapterFrom(adapterPathInCurrentWorkingDirectory)
|
|
503
|
+
this.adapter = await this.requireAdapterFrom(adapterPathInCurrentWorkingDirectory)
|
|
491
504
|
} catch (err) {
|
|
492
505
|
if (err.name === 'SyntaxError') {
|
|
493
506
|
this.adapter = await this.importAdapterFrom(adapterPathInCurrentWorkingDirectory)
|
|
@@ -502,8 +515,8 @@ class Robot {
|
|
|
502
515
|
}
|
|
503
516
|
}
|
|
504
517
|
|
|
505
|
-
requireAdapterFrom (adapaterPath) {
|
|
506
|
-
return
|
|
518
|
+
async requireAdapterFrom (adapaterPath) {
|
|
519
|
+
return await this.importAdapterFrom(adapaterPath)
|
|
507
520
|
}
|
|
508
521
|
|
|
509
522
|
async importAdapterFrom (adapterPath) {
|
|
@@ -519,12 +532,12 @@ class Robot {
|
|
|
519
532
|
|
|
520
533
|
// Private: load help info from a loaded script.
|
|
521
534
|
//
|
|
522
|
-
//
|
|
535
|
+
// filePath - A String path to the file on disk.
|
|
523
536
|
//
|
|
524
537
|
// Returns nothing.
|
|
525
|
-
parseHelp (
|
|
538
|
+
parseHelp (filePath) {
|
|
526
539
|
const scriptDocumentation = {}
|
|
527
|
-
const body = fs.readFileSync(
|
|
540
|
+
const body = fs.readFileSync(path.resolve(filePath), 'utf-8')
|
|
528
541
|
|
|
529
542
|
const useStrictHeaderRegex = /^["']use strict['"];?\s+/
|
|
530
543
|
const lines = body.replace(useStrictHeaderRegex, '').split(/(?:\n|\r\n|\r)/)
|
|
@@ -661,7 +674,7 @@ class Robot {
|
|
|
661
674
|
//
|
|
662
675
|
// Returns a String of the version number.
|
|
663
676
|
parseVersion () {
|
|
664
|
-
const pkg =
|
|
677
|
+
const pkg = fs.readFileSync(path.join(__dirname, '..', 'package.json'))
|
|
665
678
|
this.version = pkg.version
|
|
666
679
|
|
|
667
680
|
return this.version
|
|
@@ -720,8 +733,6 @@ class Robot {
|
|
|
720
733
|
}
|
|
721
734
|
}
|
|
722
735
|
|
|
723
|
-
module.exports = Robot
|
|
724
|
-
|
|
725
736
|
function isCatchAllMessage (message) {
|
|
726
737
|
return message instanceof Message.CatchAllMessage
|
|
727
738
|
}
|
|
@@ -748,9 +759,7 @@ function removeCommentPrefix (line) {
|
|
|
748
759
|
return line.replace(/^[#/]+\s*/, '')
|
|
749
760
|
}
|
|
750
761
|
|
|
751
|
-
function extend (obj
|
|
752
|
-
const sources = [].slice.call(arguments, 1)
|
|
753
|
-
|
|
762
|
+
function extend (obj, ...sources) {
|
|
754
763
|
sources.forEach((source) => {
|
|
755
764
|
if (typeof source !== 'object') {
|
|
756
765
|
return
|
|
@@ -763,3 +772,5 @@ function extend (obj/* , ...sources */) {
|
|
|
763
772
|
|
|
764
773
|
return obj
|
|
765
774
|
}
|
|
775
|
+
|
|
776
|
+
export default Robot
|
package/src/{user.js → User.mjs}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import { DataStoreUnavailable } from './DataStore.mjs'
|
|
4
4
|
|
|
5
5
|
class User {
|
|
6
6
|
// Represents a participating user in the chat.
|
|
@@ -62,4 +62,4 @@ class User {
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
export default User
|
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const Message = require('../message')
|
|
9
|
-
|
|
10
|
-
const TextMessage = Message.TextMessage
|
|
11
|
-
const EnterMessage = Message.EnterMessage
|
|
12
|
-
const LeaveMessage = Message.LeaveMessage
|
|
13
|
-
const TopicMessage = Message.TopicMessage
|
|
3
|
+
import HTTPS from 'node:https'
|
|
4
|
+
import EventEmitter from 'node:events'
|
|
5
|
+
import Adapter from '../Adapter.mjs'
|
|
6
|
+
import { TextMessage, EnterMessage, LeaveMessage, TopicMessage } from '../Message.mjs'
|
|
14
7
|
|
|
15
8
|
class Campfire extends Adapter {
|
|
16
9
|
send (envelope/* , ...strings */) {
|
|
@@ -157,8 +150,6 @@ class Campfire extends Adapter {
|
|
|
157
150
|
}
|
|
158
151
|
}
|
|
159
152
|
|
|
160
|
-
exports.use = robot => new Campfire(robot)
|
|
161
|
-
|
|
162
153
|
class CampfireStreaming extends EventEmitter {
|
|
163
154
|
constructor (options, robot) {
|
|
164
155
|
super()
|
|
@@ -392,3 +383,9 @@ class CampfireStreaming extends EventEmitter {
|
|
|
392
383
|
return request.on('error', err => logger.error(`Campfire request error: ${err}`))
|
|
393
384
|
}
|
|
394
385
|
}
|
|
386
|
+
|
|
387
|
+
export default {
|
|
388
|
+
use (robot) {
|
|
389
|
+
return new Campfire(robot)
|
|
390
|
+
}
|
|
391
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
import fs from 'node:fs'
|
|
4
|
+
import readline from 'node:readline'
|
|
5
|
+
import Adapter from '../Adapter.mjs'
|
|
6
|
+
import { TextMessage } from '../Message.mjs'
|
|
7
7
|
|
|
8
8
|
const historySize = process.env.HUBOT_SHELL_HISTSIZE != null ? parseInt(process.env.HUBOT_SHELL_HISTSIZE) : 1024
|
|
9
9
|
const historyPath = '.hubot_history'
|
|
@@ -16,7 +16,7 @@ const completer = line => {
|
|
|
16
16
|
}
|
|
17
17
|
const showHelp = () => {
|
|
18
18
|
console.log('usage:')
|
|
19
|
-
console.log('\\q, exit - close
|
|
19
|
+
console.log('\\q, exit - close Shell and exit')
|
|
20
20
|
console.log('\\?, help - show this help')
|
|
21
21
|
console.log('\\c, clear - clear screen')
|
|
22
22
|
}
|
|
@@ -112,4 +112,8 @@ class Shell extends Adapter {
|
|
|
112
112
|
|
|
113
113
|
// Prevent output buffer "swallowing" every other character on OSX / Node version > 16.19.0.
|
|
114
114
|
process.stdout._handle.setBlocking(false)
|
|
115
|
-
|
|
115
|
+
export default {
|
|
116
|
+
use (robot) {
|
|
117
|
+
return new Shell(robot)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import { DataStore } from '../DataStore.mjs'
|
|
4
4
|
|
|
5
5
|
class InMemoryDataStore extends DataStore {
|
|
6
6
|
constructor (robot) {
|
|
@@ -20,4 +20,4 @@ class InMemoryDataStore extends DataStore {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
export default InMemoryDataStore
|
package/es2015.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const User = require('./src/user')
|
|
4
|
-
const Brain = require('./src/brain')
|
|
5
|
-
const Robot = require('./src/robot')
|
|
6
|
-
const Adapter = require('./src/adapter')
|
|
7
|
-
const Response = require('./src/response')
|
|
8
|
-
const Listener = require('./src/listener')
|
|
9
|
-
const Message = require('./src/message')
|
|
10
|
-
const DataStore = require('./src/datastore')
|
|
11
|
-
|
|
12
|
-
module.exports = {
|
|
13
|
-
User,
|
|
14
|
-
Brain,
|
|
15
|
-
Robot,
|
|
16
|
-
Adapter,
|
|
17
|
-
Response,
|
|
18
|
-
Listener: Listener.Listener,
|
|
19
|
-
TextListener: Listener.TextListener,
|
|
20
|
-
Message: Message.Message,
|
|
21
|
-
TextMessage: Message.TextMessage,
|
|
22
|
-
EnterMessage: Message.EnterMessage,
|
|
23
|
-
LeaveMessage: Message.LeaveMessage,
|
|
24
|
-
TopicMessage: Message.TopicMessage,
|
|
25
|
-
CatchAllMessage: Message.CatchAllMessage,
|
|
26
|
-
DataStore: DataStore.DataStore,
|
|
27
|
-
DataStoreUnavailable: DataStore.DataStoreUnavailable,
|
|
28
|
-
loadBot (adapter, enableHttpd, name, alias) {
|
|
29
|
-
return new module.exports.Robot(adapter, enableHttpd, name, alias)
|
|
30
|
-
}
|
|
31
|
-
}
|
package/index.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
require('coffeescript/register')
|
|
3
|
-
|
|
4
|
-
const inherits = require('util').inherits
|
|
5
|
-
|
|
6
|
-
const hubotExport = require('./es2015')
|
|
7
|
-
|
|
8
|
-
// make all es2015 class declarations compatible with CoffeeScript’s extend
|
|
9
|
-
// see https://github.com/hubotio/evolution/pull/4#issuecomment-306437501
|
|
10
|
-
module.exports = Object.keys(hubotExport).reduce((map, current) => {
|
|
11
|
-
if (current !== 'loadBot') {
|
|
12
|
-
map[current] = makeClassCoffeeScriptCompatible(hubotExport[current])
|
|
13
|
-
} else {
|
|
14
|
-
map[current] = hubotExport[current]
|
|
15
|
-
}
|
|
16
|
-
return map
|
|
17
|
-
}, {})
|
|
18
|
-
|
|
19
|
-
function makeClassCoffeeScriptCompatible (klass) {
|
|
20
|
-
function CoffeeScriptCompatibleClass () {
|
|
21
|
-
const Hack = Function.prototype.bind.apply(klass, [null].concat([].slice.call(arguments)))
|
|
22
|
-
const instance = new Hack()
|
|
23
|
-
|
|
24
|
-
// pass methods from child to returned instance
|
|
25
|
-
for (const key in this) {
|
|
26
|
-
instance[key] = this[key]
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// support for constructor methods which call super()
|
|
30
|
-
// in which this.* properties are set
|
|
31
|
-
for (const key in instance) {
|
|
32
|
-
this[key] = instance[key]
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return instance
|
|
36
|
-
}
|
|
37
|
-
inherits(CoffeeScriptCompatibleClass, klass)
|
|
38
|
-
|
|
39
|
-
return CoffeeScriptCompatibleClass
|
|
40
|
-
}
|