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 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
- const fs = require('fs')
4
- const pathResolve = require('path').resolve
5
-
6
- const OptParse = require('../src/OptParse.js')
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. "shell" (to load the default hubot shell adapter)'],
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
- module.exports = robot
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
- if (!fs.existsSync(externalScripts)) {
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 coffee
1
+ #!/usr/bin/env node
2
2
 
3
- # While all other files have been converted to JavaScript via https://github.com/github/hubot/pull/1347,
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": "10.0.5",
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
- const EventEmitter = require('events').EventEmitter
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
- module.exports = Adapter
139
+ export default Adapter
@@ -1,8 +1,7 @@
1
1
  'use strict'
2
2
 
3
- const EventEmitter = require('events').EventEmitter
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
- module.exports = Brain
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
- module.exports = {
88
+ export default {
89
89
  DataStore,
90
90
  DataStoreUnavailable
91
91
  }
@@ -1,6 +1,6 @@
1
- const { spawnSync } = require('child_process')
2
- const File = require('fs')
3
- const path = require('path')
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
- spawnSync('npm', ['i', options.hubotInstallationPath].concat(options.adapter, 'hubot-help', 'hubot-rules', 'hubot-diagnostics'))
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
- module.exports = (hubotDirectory, options) => {
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
- const path = require('path')
37
- const http = require('http')
38
- const https = require('https')
39
- const qs = require('querystring')
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
- exports.create = (url, options) => new ScopedClient(url, options)
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
- const inspect = require('util').inspect
4
-
5
- const TextMessage = require('./message').TextMessage
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
- module.exports = {
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
- module.exports = {
81
+ export default {
82
82
  Message,
83
83
  TextMessage,
84
84
  EnterMessage,
@@ -42,4 +42,4 @@ class Middleware {
42
42
  }
43
43
  }
44
44
 
45
- module.exports = Middleware
45
+ export default Middleware
@@ -1,4 +1,4 @@
1
- const EventEmitter = require('node:events')
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
- module.exports = OptParse
44
+ export default OptParse
@@ -123,4 +123,4 @@ class Response {
123
123
  }
124
124
  }
125
125
 
126
- module.exports = Response
126
+ export default Response
@@ -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
- const pino = require('pino')
8
- const HttpClient = require('./httpclient')
9
-
10
- const Brain = require('./brain')
11
- const Response = require('./response')
12
- const Listener = require('./listener')
13
- const Message = require('./message')
14
- const Middleware = require('./middleware')
15
-
16
- const HUBOT_DEFAULT_ADAPTERS = ['campfire', 'shell']
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.Listener(this, matcher, options, callback))
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 Listener.TextListener(this, regex, options, callback))
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 = require(filePath)
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', 'coffee'].indexOf(ext) === -1) {
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
- return packages.forEach(pkg => require(pkg)(this))
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 = require('express')
417
- const basicAuth = require('express-basic-auth')
418
- const multipart = require('connect-multiparty')
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 ?? '') ?? '.js'
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', '.coffee'].includes(ext)) {
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 require(adapaterPath).use(this)
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
- // path - A String path to the file on disk.
535
+ // filePath - A String path to the file on disk.
523
536
  //
524
537
  // Returns nothing.
525
- parseHelp (path) {
538
+ parseHelp (filePath) {
526
539
  const scriptDocumentation = {}
527
- const body = fs.readFileSync(require.resolve(path), 'utf-8')
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 = require(path.join(__dirname, '..', 'package.json'))
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/* , ...sources */) {
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
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const DataStoreUnavailable = require('./datastore').DataStoreUnavailable
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
- module.exports = User
65
+ export default User
@@ -1,16 +1,9 @@
1
1
  'use strict'
2
2
 
3
- const HTTPS = require('https')
4
- const EventEmitter = require('events').EventEmitter
5
-
6
- const Adapter = require('../adapter')
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
- const fs = require('fs')
4
- const readline = require('node:readline')
5
- const Adapter = require('../adapter')
6
- const { TextMessage } = require('../message')
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 shell and exit')
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
- exports.use = robot => new Shell(robot)
115
+ export default {
116
+ use (robot) {
117
+ return new Shell(robot)
118
+ }
119
+ }
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const DataStore = require('../datastore.js').DataStore
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
- module.exports = InMemoryDataStore
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
- }