├── .gitignore
├── .node-version
├── Procfile
├── README.md
├── assets
├── integrations.png
└── integrations
│ ├── canny.png
│ ├── github.png
│ ├── heroku.png
│ └── rollbar.png
├── docs
└── integrations
│ ├── canny
│ ├── README.md
│ ├── add-webhook.png
│ ├── copy-webhook.png
│ └── example.png
│ ├── github
│ ├── README.md
│ ├── add-webhook.png
│ ├── copy-webhook.png
│ └── example.png
│ ├── heroku
│ ├── README.md
│ ├── add-webhook-1.png
│ ├── add-webhook-2.png
│ ├── copy-webhook.png
│ └── example.png
│ └── rollbar
│ ├── README.md
│ ├── add-webhook.png
│ ├── copy-webhook.png
│ └── example.png
├── lib
├── index.js
├── integration.js
└── integrations
│ ├── canny.js
│ ├── github.js
│ ├── heroku.js
│ └── rollbar.js
├── package.json
├── server.js
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | .env
2 |
3 | node_modules/
4 | npm-debug.log
5 | yarn-debug.log
6 | yarn-error.log
7 |
--------------------------------------------------------------------------------
/.node-version:
--------------------------------------------------------------------------------
1 | 18.14.1
2 |
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | web: yarn start
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |

11 |
Missive mixes team email and threaded group chat for productive teams.
12 |
A single app for all your internal and external communication and a full work management solution.
13 |
14 |
--------------------------------------------------------------------------------
/assets/integrations.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/missive/missive-webhooks/437a833897a80a64331902fd1c1df4d3cccb1ef6/assets/integrations.png
--------------------------------------------------------------------------------
/assets/integrations/canny.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/missive/missive-webhooks/437a833897a80a64331902fd1c1df4d3cccb1ef6/assets/integrations/canny.png
--------------------------------------------------------------------------------
/assets/integrations/github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/missive/missive-webhooks/437a833897a80a64331902fd1c1df4d3cccb1ef6/assets/integrations/github.png
--------------------------------------------------------------------------------
/assets/integrations/heroku.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/missive/missive-webhooks/437a833897a80a64331902fd1c1df4d3cccb1ef6/assets/integrations/heroku.png
--------------------------------------------------------------------------------
/assets/integrations/rollbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/missive/missive-webhooks/437a833897a80a64331902fd1c1df4d3cccb1ef6/assets/integrations/rollbar.png
--------------------------------------------------------------------------------
/docs/integrations/canny/README.md:
--------------------------------------------------------------------------------
1 | # Install Canny integration on Missive
2 |
3 |
4 | ## Setup and copy webhook from Missive
5 |
6 |
7 | ## Add a webhook in your Canny settings
8 |
9 |
--------------------------------------------------------------------------------
/docs/integrations/canny/add-webhook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/missive/missive-webhooks/437a833897a80a64331902fd1c1df4d3cccb1ef6/docs/integrations/canny/add-webhook.png
--------------------------------------------------------------------------------
/docs/integrations/canny/copy-webhook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/missive/missive-webhooks/437a833897a80a64331902fd1c1df4d3cccb1ef6/docs/integrations/canny/copy-webhook.png
--------------------------------------------------------------------------------
/docs/integrations/canny/example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/missive/missive-webhooks/437a833897a80a64331902fd1c1df4d3cccb1ef6/docs/integrations/canny/example.png
--------------------------------------------------------------------------------
/docs/integrations/github/README.md:
--------------------------------------------------------------------------------
1 | # Install GitHub integration on Missive
2 |
3 |
4 | ## Setup and copy webhook from Missive
5 |
6 |
7 | ## Add an `application/json` webhook to your GitHub repo
8 |
9 |
--------------------------------------------------------------------------------
/docs/integrations/github/add-webhook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/missive/missive-webhooks/437a833897a80a64331902fd1c1df4d3cccb1ef6/docs/integrations/github/add-webhook.png
--------------------------------------------------------------------------------
/docs/integrations/github/copy-webhook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/missive/missive-webhooks/437a833897a80a64331902fd1c1df4d3cccb1ef6/docs/integrations/github/copy-webhook.png
--------------------------------------------------------------------------------
/docs/integrations/github/example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/missive/missive-webhooks/437a833897a80a64331902fd1c1df4d3cccb1ef6/docs/integrations/github/example.png
--------------------------------------------------------------------------------
/docs/integrations/heroku/README.md:
--------------------------------------------------------------------------------
1 | # Install Heroku integration on Missive
2 |
3 |
4 | ## Setup and copy webhook from Missive
5 |
6 |
7 | ## Add a `Deploy Hooks (HTTP Post Hook)` add-on to your Heroku app
8 | https://dashboard.heroku.com/apps/YOUR_APP/resources/new?addonService=deployhooks
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/docs/integrations/heroku/add-webhook-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/missive/missive-webhooks/437a833897a80a64331902fd1c1df4d3cccb1ef6/docs/integrations/heroku/add-webhook-1.png
--------------------------------------------------------------------------------
/docs/integrations/heroku/add-webhook-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/missive/missive-webhooks/437a833897a80a64331902fd1c1df4d3cccb1ef6/docs/integrations/heroku/add-webhook-2.png
--------------------------------------------------------------------------------
/docs/integrations/heroku/copy-webhook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/missive/missive-webhooks/437a833897a80a64331902fd1c1df4d3cccb1ef6/docs/integrations/heroku/copy-webhook.png
--------------------------------------------------------------------------------
/docs/integrations/heroku/example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/missive/missive-webhooks/437a833897a80a64331902fd1c1df4d3cccb1ef6/docs/integrations/heroku/example.png
--------------------------------------------------------------------------------
/docs/integrations/rollbar/README.md:
--------------------------------------------------------------------------------
1 | # Install Rollbar integration on Missive
2 |
3 |
4 | ## Setup and copy webhook from Missive
5 | `Account` and `Project` are required for Rollbar integration.
6 |
7 |
8 |
9 | ## Configure `Webhook` channel in your project’s Notifications settings
10 | https://rollbar.com/ACCOUNT/PROJECT/settings/notifications/webhook/
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/integrations/rollbar/add-webhook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/missive/missive-webhooks/437a833897a80a64331902fd1c1df4d3cccb1ef6/docs/integrations/rollbar/add-webhook.png
--------------------------------------------------------------------------------
/docs/integrations/rollbar/copy-webhook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/missive/missive-webhooks/437a833897a80a64331902fd1c1df4d3cccb1ef6/docs/integrations/rollbar/copy-webhook.png
--------------------------------------------------------------------------------
/docs/integrations/rollbar/example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/missive/missive-webhooks/437a833897a80a64331902fd1c1df4d3cccb1ef6/docs/integrations/rollbar/example.png
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | const Canny = require('./integrations/canny')
2 | const GitHub = require('./integrations/github')
3 | const Heroku = require('./integrations/heroku')
4 | const Rollbar = require('./integrations/rollbar')
5 |
6 | module.exports = {
7 | canny: new Canny,
8 | github: new GitHub,
9 | heroku: new Heroku,
10 | rollbar: new Rollbar,
11 | }
12 |
--------------------------------------------------------------------------------
/lib/integration.js:
--------------------------------------------------------------------------------
1 | class Integration {
2 | get name() { return this.constructor.name }
3 | get avatar() { return `https://raw.githubusercontent.com/missive/missive-webhooks/master/assets/integrations/${this.id}.png` }
4 | get icon() { return `https://raw.githubusercontent.com/missive/missive-webhooks/master/assets/integrations/${this.id}.png` }
5 | get schema() { return { options: [] } }
6 |
7 | link(url, label) {
8 | if (this.sanitizing) {
9 | return label || url
10 | }
11 |
12 | if (label) {
13 | return `<${url}|${label}>`
14 | } else {
15 | return `<${url}>`
16 | }
17 | }
18 |
19 | codeLink(url, label) {
20 | return this.link(url, `\`${label}\``)
21 | }
22 |
23 | sanitize(callbacks) {
24 | if (!Array.isArray(callbacks)) callbacks = [callbacks]
25 |
26 | let chunks = []
27 | let sanitizedChunks = []
28 |
29 | let exec = () => {
30 | return callbacks.map((cb) => cb()).join('')
31 | }
32 |
33 | let string = new String(exec())
34 | string.callbacks = callbacks
35 | string.add = (callback) => {
36 | return this.sanitize(string.callbacks.concat(callback))
37 | }
38 |
39 | this.sanitizing = true
40 | string.sanitized = exec()
41 | this.sanitizing = false
42 |
43 | return string
44 | }
45 |
46 | capitalize(string) {
47 | if (!string) return ''
48 | return string.charAt(0).toUpperCase() + string.substring(1).toLowerCase()
49 | }
50 |
51 | toJSON() {
52 | return {
53 | id: this.id,
54 | name: this.name,
55 | avatar: this.avatar,
56 | icon: this.icon,
57 | schema: this.schema,
58 | }
59 | }
60 | }
61 |
62 | module.exports = Integration
63 |
--------------------------------------------------------------------------------
/lib/integrations/canny.js:
--------------------------------------------------------------------------------
1 | const Integration = require('../integration')
2 |
3 | const COLORS = {
4 | comment: '#999',
5 | vote: '#535df0',
6 | status: {
7 | open: '#999',
8 | under_review: '#85b5b5',
9 | planned: '#1fa0ff',
10 | in_progress: '#c17aff',
11 | complete: '#6dd345',
12 | closed: '#ed2b2b',
13 | },
14 | }
15 |
16 | class Canny extends Integration {
17 | get id() { return 'canny' }
18 |
19 | process(payload, req) {
20 | let type = payload.type.replace('.', '_')
21 |
22 | if (this[type]) {
23 | return this[type](payload)
24 | }
25 | }
26 |
27 | // Supported event types
28 | post_created(payload) {
29 | let { object } = payload
30 | let { id, author, board, details, title, url, imageURLs } = object
31 |
32 | let pretext = this.sanitize(() => `${author.name} created a new post in ${this.boardLink(board)}`)
33 | let imageURL = undefined
34 | let color = this.getColorForPost(object)
35 |
36 | if (imageURLs && imageURLs.length) {
37 | imageURL = imageURLs[0]
38 | }
39 |
40 | return {
41 | references: [`${board.id}/${id}`],
42 | subject: title,
43 | color: color,
44 | notification: pretext.sanitized,
45 | attachment: {
46 | pretext: pretext.toString(),
47 | title: title,
48 | title_link: url,
49 | text: details,
50 | image_url: imageURL,
51 | color: color,
52 | }
53 | }
54 | }
55 |
56 | post_status_changed(payload) {
57 | let { object } = payload
58 | let { id, board, title, status, changeComment } = object
59 |
60 | let text = this.sanitize(() => `${this.postLink(object, board)} has been marked as *${status}*`)
61 | let color = this.getColorForPost(object)
62 |
63 | let attachments = [
64 | {
65 | text: text.toString(),
66 | color: color,
67 | }
68 | ]
69 |
70 | if (changeComment) {
71 | let { imageURLs, value } = changeComment
72 | let imageURL = undefined
73 |
74 | if (imageURLs && imageURLs.length) {
75 | imageURL = imageURLs[0]
76 | }
77 |
78 | if (value || imageURL) {
79 | attachments.push({
80 | text: value,
81 | image_url: imageURL,
82 | color: COLORS.comment,
83 | })
84 | }
85 | }
86 |
87 | return {
88 | references: [`${board.id}/${id}`],
89 | subject: title,
90 | color: color,
91 | notification: text.sanitized,
92 | attachments: attachments,
93 | }
94 | }
95 |
96 | vote_created(payload) {
97 | let { object } = payload
98 | let { board, post } = object
99 |
100 | if (post.score % 5) return
101 |
102 | let text = this.sanitize(() => `${this.postLink(post, board)} hit *${post.score} votes*`)
103 |
104 | return {
105 | references: [`${board.id}/${post.id}`],
106 | subject: post.title,
107 | color: this.getColorForPost(post),
108 | notification: text.sanitized,
109 | attachment: {
110 | text: text.toString(),
111 | color: COLORS.vote,
112 | }
113 | }
114 | }
115 |
116 | comment_created(payload) {
117 | let { object } = payload
118 | let { author, board, post, value, imageURLs } = object
119 |
120 | let pretext = this.sanitize(() => `${author.name} posted a new comment in ${this.postLink(post, board)}`)
121 | let imageURL = undefined
122 |
123 | if (imageURLs && imageURLs.length) {
124 | imageURL = imageURLs[0]
125 | }
126 |
127 | return {
128 | references: [`${board.id}/${post.id}`],
129 | subject: post.title,
130 | color: this.getColorForPost(post),
131 | notification: pretext.sanitized,
132 | attachment: {
133 | pretext: pretext.toString(),
134 | text: value,
135 | color: COLORS.comment,
136 | image_url: imageURL,
137 | }
138 | }
139 | }
140 |
141 | // Helpers
142 | getColorForPost(post) {
143 | let { status } = post
144 | status = status.replace(/\s/g, '_')
145 |
146 | return COLORS.status[status]
147 | }
148 |
149 | boardLink(board) {
150 | return this.link(board.url, board.name)
151 | }
152 |
153 | postLink(post, board) {
154 | let title = post.title
155 |
156 | if (board) {
157 | title = `${board.name}: ${title}`
158 | }
159 |
160 | return this.link(post.url, title)
161 | }
162 | }
163 |
164 | module.exports = Canny
165 |
--------------------------------------------------------------------------------
/lib/integrations/github.js:
--------------------------------------------------------------------------------
1 | const Integration = require('../integration')
2 |
3 | const COLORS = {
4 | commit: '#0093ce',
5 | commitComment: '#00acf0',
6 | issue: '#de5c00',
7 | issueComment: '#ff7d22',
8 | pr: '#009e61',
9 | prComment: '#00c76e',
10 | rejected: '#c6474e',
11 | deploy: '#430098',
12 | }
13 |
14 | class GitHub extends Integration {
15 | get id() { return 'github' }
16 |
17 | process(payload, req) {
18 | let type = req.get('X-GitHub-Event')
19 | let contentType = req.get('Content-Type')
20 |
21 | if (contentType == 'application/x-www-form-urlencoded') {
22 | if (payload && payload.payload) {
23 | payload = JSON.parse(`${payload.payload}`)
24 | }
25 | }
26 |
27 | if (this[type]) {
28 | return this[type](payload)
29 | }
30 | }
31 |
32 | // Supported event types
33 | ping (payload) {
34 | return { references: ['pong'] }
35 | }
36 |
37 | commit_comment (payload) {
38 | if (['created'].indexOf(payload.action) == -1) return
39 |
40 | var { comment, repository, sender } = payload
41 | var pretext = this.sanitize(() => `New comment by ${sender.login} on commit ${this.link(comment.html_url, this.shortCommit(comment.commit_id))}`)
42 |
43 | if (comment.line) {
44 | pretext = pretext.add(() => ` on line ${comment.line}`)
45 | }
46 |
47 | return {
48 | references: this.referencesForRepository(repository),
49 | subject: this.subjectForRepository(repository),
50 | notification: pretext.sanitized,
51 | attachment: {
52 | pretext: pretext.toString(),
53 | markdown: comment.body,
54 | color: COLORS.commitComment,
55 | }
56 | }
57 | }
58 |
59 | create (payload) {
60 | if (['tag'].indexOf(payload.ref_type) == -1) return
61 |
62 | var { ref, ref_type, repository, sender } = payload
63 | var text = this.sanitize(() => `New ${ref_type} ${this.branchLink(ref, repository)} was pushed by ${sender.login}`)
64 |
65 | return {
66 | references: this.referencesForRepository(repository),
67 | subject: this.subjectForRepository(repository),
68 | notification: text.sanitized,
69 | attachment: {
70 | text: text.toString(),
71 | color: COLORS.commit,
72 | }
73 | }
74 | }
75 |
76 | delete (payload) {
77 | if (['tag'].indexOf(payload.ref_type) == -1) return
78 |
79 | var { ref, ref_type, repository, sender } = payload
80 | var text = this.sanitize(() => `The ${ref_type} “${ref}” was deleted by ${sender.login}`)
81 |
82 | return {
83 | references: this.referencesForRepository(repository),
84 | subject: this.subjectForRepository(repository),
85 | notification: text.sanitized,
86 | attachment: { text: text.toString() },
87 | }
88 | }
89 |
90 | deployment (payload) { /* TODO */ }
91 |
92 | deployment_status (payload) {
93 | const { deployment_status, deployment, sender, repository } = payload
94 | if (['success', 'failure'].indexOf(payload.deployment_status.state) == -1) return
95 |
96 | var text, color
97 |
98 | if (deployment_status.state == 'success') {
99 | text = this.sanitize(() => `${sender.login} ${this.link(deployment_status.target_url, 'deployed')} ${this.commitLink(deployment.sha, repository)} to ${this.link(deployment.payload.web_url, deployment.environment)}`)
100 | color = COLORS.deploy
101 | } else if (deployment_status.state == 'failure') {
102 | text = this.sanitize(() => `${sender.login} ${this.link(deployment_status.target_url, 'failed to deploy')} ${this.commitLink(deployment.sha, repository)} to ${this.link(deployment.payload.web_url, deployment.environment)}`)
103 | color = COLORS.rejected
104 | }
105 |
106 | var notification = text.sanitized
107 | text = text.toString()
108 |
109 | return {
110 | references: this.referencesForRepository(repository),
111 | subject: this.subjectForRepository(repository),
112 | notification: notification,
113 | attachment: { text, color },
114 | }
115 | }
116 |
117 | fork (payload) { /* TODO */ }
118 | gollum (payload) { /* TODO */ }
119 |
120 | issue_comment(payload) {
121 | if (['created'].indexOf(payload.action) == -1) return
122 |
123 | var { issue, comment, repository, sender } = payload
124 | var pretext = this.sanitize(() => `New ${this.link(comment.html_url, 'comment')} by ${sender.login}`)
125 | var isPR = /\/pull\/\d+$/.test(issue.html_url)
126 |
127 | return {
128 | references: this.referencesForIssue(issue, repository),
129 | subject: this.subjectForIssue(issue, repository),
130 | notification: pretext.sanitized,
131 | attachment: {
132 | pretext: pretext.toString(),
133 | markdown: comment.body,
134 | color: isPR ? COLORS.prComment : COLORS.issueComment,
135 | }
136 | }
137 | }
138 |
139 | issues(payload) {
140 | if (['opened', 'closed', 'reopened'].indexOf(payload.action) == -1) return
141 | var { issue, repository, sender } = payload
142 |
143 | var title, title_link, text, markdown, color, pretext = this.sanitize(() => `${this.link(issue.html_url, 'Issue')} ${payload.action} by ${sender.login}`)
144 | var notification = pretext.sanitized
145 |
146 | if (payload.action == 'opened') {
147 | title = issue.title
148 | title_link = issue.html_url
149 | markdown = issue.body
150 | pretext = pretext.toString()
151 | } else {
152 | text = pretext.toString()
153 | pretext = undefined
154 | }
155 |
156 | if (payload.action != 'closed') {
157 | color = COLORS.issue
158 | }
159 |
160 | return {
161 | references: this.referencesForIssue(issue, repository),
162 | subject: this.subjectForIssue(issue, repository),
163 | notification: notification,
164 | attachment: { title, title_link, pretext, text, markdown, color },
165 | }
166 | }
167 |
168 | member (payload) {
169 | if (['added'].indexOf(payload.action) == -1) return
170 |
171 | var { member, repository, sender } = payload
172 | var text = this.sanitize(() => `${sender.login} added ${this.userLink(member)} as a collaborator`)
173 |
174 | return {
175 | references: this.referencesForRepository(repository),
176 | subject: this.subjectForRepository(repository),
177 | attachment: { text: text.toString() },
178 | }
179 | }
180 |
181 | page_build (payload) {
182 | if (['built', 'errored'].indexOf(payload.build.status) == -1) return
183 |
184 | var { build, repository } = payload
185 | var text
186 |
187 | switch (build.status) {
188 | case 'built':
189 | text = this.sanitize(() => `Page was successfully built: ${this.pageLink(repository)}`)
190 | break
191 |
192 | case 'errored':
193 | text = this.sanitize(() => `There was an error building the page: ${this.pageLink(repository)}`)
194 | break
195 | }
196 |
197 | return {
198 | references: this.referencesForRepository(repository),
199 | subject: this.subjectForRepository(repository),
200 | notification: text.sanitized,
201 | attachment: { text: text.toString() },
202 | }
203 | }
204 |
205 | public (payload) {
206 | var { repository, sender } = payload
207 | var text = this.sanitize(() => `${sender.login} open sourced ${this.link(repository.html_url, repository.name)}`)
208 |
209 | return {
210 | references: this.referencesForRepository(repository),
211 | subject: this.subjectForRepository(repository),
212 | attachment: { text: text.toString() },
213 | }
214 | }
215 |
216 | pull_request(payload) {
217 | if (['opened', 'closed', 'reopened', 'assigned', 'unassigned', 'review_requested', 'review_request_removed'].indexOf(payload.action) == -1) return
218 |
219 | var { action, pull_request, repository, sender } = payload
220 | var title, title_link, text, pretext, markdown, color, notification
221 |
222 | if (action == 'closed' && pull_request.merged) {
223 | action = 'merged'
224 | }
225 |
226 | if (action == 'assigned' || action == 'unassigned') {
227 | var { assignee } = payload
228 | var fromTo = action == 'assigned' ? 'to' : 'from'
229 |
230 | pretext = this.sanitize(() => `${sender.login} ${action} ${assignee.login} ${fromTo} ${this.pullRequestLink(pull_request, repository)}`)
231 | } else if (action == 'review_requested' || action == 'review_request_removed') {
232 | var { requested_reviewer } = payload
233 | var theAction = ''
234 |
235 | if (action == 'review_requested') {
236 | theAction = 'requested a review'
237 | } else {
238 | theAction = 'removed the review request'
239 | }
240 |
241 | pretext = this.sanitize(() => `${sender.login} ${theAction} from ${requested_reviewer.login} on ${this.pullRequestLink(pull_request, repository)}`)
242 | } else {
243 | pretext = this.sanitize(() => `${this.pullRequestLink(pull_request, repository)} ${action} by ${sender.login}`)
244 | }
245 |
246 | notification = pretext.sanitized
247 |
248 | if (action == 'opened') {
249 | title = pull_request.title
250 | title_link = pull_request.html_url
251 | markdown = pull_request.body
252 | pretext = pretext.toString()
253 | } else {
254 | text = pretext.toString()
255 | pretext = undefined
256 | }
257 |
258 | if (action != 'closed') {
259 | color = COLORS.pr
260 | }
261 |
262 | return {
263 | references: this.referencesForIssue(pull_request, repository),
264 | subject: this.subjectForIssue(pull_request, repository),
265 | update_existing_conversation_subject: true,
266 | notification: notification,
267 | attachment: { title, title_link, pretext, text, markdown, color },
268 | }
269 | }
270 |
271 | pull_request_review(payload) {
272 | if (['submitted'].indexOf(payload.action) == -1) return
273 |
274 | var { pull_request, review, repository, sender } = payload
275 | var pretext, color = COLORS.prComment
276 |
277 | if (review.state == 'changes_requested') {
278 | pretext = this.sanitize(() => `New changes requested by ${sender.login} in ${this.link(review.html_url, 'review')}`)
279 | color = COLORS.rejected
280 | } else if (review.state == 'approved') {
281 | pretext = this.sanitize(() => `New changes approved by ${sender.login} in ${this.link(review.html_url, 'review')}`)
282 | } else {
283 | if (!review.body) return
284 | pretext = this.sanitize(() => `New ${this.link(review.html_url, 'review')} by ${sender.login}`)
285 | }
286 |
287 | return {
288 | references: this.referencesForIssue(pull_request, repository),
289 | subject: this.subjectForIssue(pull_request, repository),
290 | notification: pretext.sanitized,
291 | attachment: {
292 | pretext: pretext.toString(),
293 | markdown: review.body,
294 | color: color,
295 | }
296 | }
297 | }
298 |
299 | pull_request_review_comment(payload) {
300 | if (['created'].indexOf(payload.action) == -1) return
301 |
302 | var { pull_request, comment, repository, sender } = payload
303 | var pretext = this.sanitize(() => `New ${this.link(comment.html_url, 'comment')} by ${sender.login}`)
304 |
305 | return {
306 | references: this.referencesForIssue(pull_request, repository),
307 | subject: this.subjectForIssue(pull_request, repository),
308 | notification: pretext.sanitized,
309 | attachment: {
310 | pretext: pretext.toString(),
311 | markdown: comment.body,
312 | color: COLORS.prComment,
313 | }
314 | }
315 | }
316 |
317 | push (payload) {
318 | var { ref, created, deleted, forced, head_commit, compare, commits, repository, sender } = payload
319 | var text = [], pretext, notification, branch, size, includeCommits, color
320 |
321 | if (!ref.startsWith('refs/heads/')) return
322 |
323 | branch = ref.replace('refs/heads/', '')
324 | if (branch.startsWith('gh-readonly-queue')) return
325 |
326 | size = commits.length
327 | color = COLORS.commit
328 |
329 | if (created) {
330 | pretext = this.sanitize(() => `${sender.login} created new branch ${this.branchLink(branch, repository)}`)
331 | if (size > 0) {
332 | pretext = pretext.add(() => ' and')
333 | includeCommits = true
334 | }
335 | } else if (deleted) {
336 | pretext = this.sanitize(() => `${sender.login} deleted “${branch}”`)
337 | color = undefined
338 | } else if (forced) {
339 | pretext = this.sanitize(() => `${sender.login} force-pushed ${this.branchLink(branch, repository)} to ${this.link(this.commitUrl(head_commit), this.shortCommit(head_commit.id))}`)
340 | } else {
341 | pretext = this.sanitize(() => `${sender.login}`)
342 | includeCommits = true
343 | }
344 |
345 | const referencedConversations = []
346 |
347 | if (includeCommits && size > 0) {
348 | pretext = pretext.add(() => ` pushed ${this.link(compare, `${size} new commit${size > 1 ? 's' : ''}`)} to ${this.branchLink(branch, repository)}`)
349 | commits.forEach((commit) => {
350 | const msg = commit.message.split('\n')[0]
351 | let line = `${this.codeLink(this.commitUrl(commit), this.shortCommit(commit.id))} ${msg}`
352 |
353 | if (commit.author.username && commit.author.username.toLowerCase() != sender.login.toLowerCase()) {
354 | line += ` - ${commit.author.username}`
355 | }
356 |
357 | // Detect if commit contains conversation links
358 | if (commit.distinct) {
359 | const protocols = ['https', 'missive']
360 | const domain = 'mail.missiveapp.com'
361 | const mailboxType = '(?:[^\/]+)'
362 | const uuid = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
363 | const regex = new RegExp(`(?:${protocols.join('|')}):\/\/${domain}\/#${mailboxType}.*\/conversations\/(${uuid})`, 'gi')
364 |
365 | let match
366 | while (match = regex.exec(commit.message)) {
367 | const conversation = match[1]
368 | referencedConversations.push({ conversation, commit })
369 | }
370 | }
371 |
372 | text.push(line)
373 | })
374 |
375 | text = text.join('\n')
376 | }
377 |
378 | notification = pretext.sanitized
379 | pretext = pretext.toString()
380 |
381 | if (!text.length) {
382 | text = pretext
383 | pretext = undefined
384 | }
385 |
386 | return {
387 | references: [`${repository.id}/${branch}`],
388 | subject: this.subjectForRepository(null, repository, branch),
389 | notification: notification,
390 | attachment: { pretext, text, color },
391 | callback: (conversationId, { createPost }) => {
392 | if (!referencedConversations.length) return
393 | for (const { conversation, commit } of referencedConversations) {
394 | if (conversationId == conversation) continue
395 |
396 | let text = this.sanitize(() => `${commit.author.username} referenced this conversation in ${this.codeLink(this.commitUrl(commit), this.repositoryCommit(repository, commit))}`)
397 |
398 | const notification = text.sanitized
399 | const color = COLORS.commit
400 | text = text.toString()
401 |
402 | createPost({
403 | conversation: conversation,
404 | notification: notification,
405 | attachment: { text, color },
406 | })
407 | }
408 | },
409 | }
410 | }
411 |
412 | release (payload) { /* TODO */ }
413 | repository (payload) { /* TODO */ }
414 | status (payload) { /* TODO */ }
415 | team_add (payload) { /* TODO */ }
416 | watch (payload) { /* TODO */ }
417 |
418 | // Helpers
419 | userLink(user) {
420 | return this.link(user.html_url, user.login)
421 | }
422 |
423 | pageLink(repository) {
424 | return this.link(`https://${repository.owner.login}.github.io/${repository.name}`)
425 | }
426 |
427 | branchLink(branch, repository) {
428 | return this.link(`${repository.html_url}/tree/${branch}`, `${repository.name}/${branch}`)
429 | }
430 |
431 | pullRequestLink(pull_request, repository) {
432 | return this.link(`${pull_request.html_url}`, `${repository.name}/${pull_request.number}`)
433 | }
434 |
435 | commitLink(commitId, repository) {
436 | return this.codeLink(`${repository.html_url}/commit/${commitId}`, this.shortCommit(commitId))
437 | }
438 |
439 | repositoryCommit(repository, commit) {
440 | return `${repository.full_name}@${this.shortCommit(commit.id)}`
441 | }
442 |
443 | shortCommit(commitId) {
444 | return commitId.substr(0, 7)
445 | }
446 |
447 | commitUrl(commit) {
448 | return `${commit.url}?w=1`
449 | }
450 |
451 | referencesForRepository(repository, ref = 'master') {
452 | return [`${repository.id}/${ref}`]
453 | }
454 |
455 | referencesForIssue(issue, repository) {
456 | let references = [`${repository.id}/${issue.number}`]
457 |
458 | // When `issue` is a pull-request from the same repo,
459 | // add branch reference so that everything related to that PR
460 | // is added to the branch conversation
461 | if (issue.head && issue.head.repo.id == repository.id) {
462 | let branch = issue.head.ref
463 | references.unshift(`${repository.id}/${branch}`)
464 | }
465 |
466 | return references
467 | }
468 |
469 | subjectForIssue(issue, repository) {
470 | let { number, title, head } = issue
471 | let subject = `#${number} ${title}`
472 | let branch
473 |
474 | // When `issue` is a pull-request from the same repo,
475 | // add branch to the subject
476 | if (head && head.repo.id == repository.id) {
477 | branch = head.ref
478 | }
479 |
480 | return this.subjectForRepository(subject, repository, branch)
481 | }
482 |
483 | subjectForRepository(subject, repository, branch) {
484 | if (!repository) {
485 | repository = subject
486 | subject = null
487 | }
488 |
489 | let repoName = `[${repository.name}${branch ? `:${branch}` : ''}]`
490 |
491 | if (!subject) {
492 | return repoName
493 | } else {
494 | return `${subject} ${repoName}`
495 | }
496 | }
497 | }
498 |
499 | module.exports = GitHub
500 |
--------------------------------------------------------------------------------
/lib/integrations/heroku.js:
--------------------------------------------------------------------------------
1 | const Integration = require('../integration')
2 |
3 | class Heroku extends Integration {
4 | get deprecated() { return true }
5 | get id() { return 'heroku' }
6 |
7 | process(payload, req) {
8 | var { app, user, url, head, git_log, release } = payload
9 | var pretext = this.sanitize(() => `${user} deployed version *${release || head}* of ${this.link(url, app)}`)
10 |
11 | return {
12 | references: [app],
13 | subject: app,
14 | notification: pretext.sanitized,
15 | attachment: {
16 | pretext: pretext.toString(),
17 | markdown: git_log,
18 | color: '#430098',
19 | }
20 | }
21 | }
22 | }
23 |
24 | module.exports = Heroku
25 |
--------------------------------------------------------------------------------
/lib/integrations/rollbar.js:
--------------------------------------------------------------------------------
1 | const Integration = require('../integration')
2 |
3 | const COLORS = {
4 | resolved: '#009e61',
5 | level: {
6 | critical: '#c00',
7 | error: '#c00',
8 | warning: '#ffc258',
9 | info: '#0093ce',
10 | debug: '#bab6b6',
11 | },
12 | }
13 |
14 | class Rollbar extends Integration {
15 | get id() { return 'rollbar' }
16 | get schema() {
17 | return {
18 | options: [
19 | { key: 'account', type: 'String', required: true },
20 | { key: 'project', type: 'String', required: true },
21 | ]
22 | }
23 | }
24 |
25 | process(payload, req, options) {
26 | let { event_name, data } = payload
27 | this.options = options || {}
28 |
29 | if (this[event_name]) {
30 | return this[event_name](data)
31 | }
32 | }
33 |
34 | // Supported event types
35 | test(payload) {
36 | return { references: ['test'] }
37 | }
38 |
39 | deploy(payload) {
40 | let { deploy } = payload
41 | }
42 |
43 | exp_repeat_item(payload) {
44 | let { item, occurrences } = payload
45 | let { title } = item
46 | let text = this.sanitize(() => `${occurrences}th occurrence: ${title.replace('\n', '')}\n${this.linksForItem(item)}`)
47 |
48 | return {
49 | references: [item.id],
50 | subject: item.title,
51 | notification: text.sanitized,
52 | attachment: {
53 | text: text.toString(),
54 | color: COLORS.level.info,
55 | }
56 | }
57 | }
58 |
59 | item_velocity(payload) {
60 | let { item, trigger } = payload
61 | let { title } = item
62 | let text = this.sanitize(() => `${trigger.threshold} occurrences in ${trigger.window_size_description}: ${title.replace('\n', '')}\n${this.linksForItem(item)}`)
63 |
64 | return {
65 | references: [item.id],
66 | subject: item.title,
67 | notification: text.sanitized,
68 | attachment: {
69 | text: text.toString(),
70 | color: COLORS.level.info,
71 | }
72 | }
73 | }
74 |
75 | new_item(payload) {
76 | let { item } = payload
77 | let { title } = item
78 | let text = this.sanitize(() => `New item: ${title.replace('\n', '')}\n${this.linksForItem(item)}`)
79 |
80 | return {
81 | references: [item.id],
82 | subject: item.title,
83 | notification: text.sanitized,
84 | attachment: {
85 | color: COLORS.level.info,
86 | text: text.toString(),
87 | }
88 | }
89 | }
90 |
91 | occurrence(payload) {
92 | let { item, occurrence } = payload
93 | let { title } = item
94 | let { version, person, client, level } = occurrence
95 |
96 | let text = this.sanitize(() => `${title.replace('\n', '')} (${this.capitalize(level)})\n${this.linksForItem(item, true)}`)
97 | let color = COLORS.level[level] || COLORS.level.error
98 | let fields = []
99 |
100 | if (person) {
101 | fields.push({
102 | title: 'User',
103 | value: person.email || person.id,
104 | short: true,
105 | })
106 | }
107 |
108 | if (version) {
109 | fields.push({
110 | title: 'Version',
111 | value: version,
112 | short: true,
113 | })
114 | }
115 |
116 | return {
117 | references: [item.id],
118 | subject: item.title,
119 | color: color,
120 | notification: text.sanitized,
121 | attachment: {
122 | text: text.toString(),
123 | color: color,
124 | fields: fields,
125 | }
126 | }
127 | }
128 |
129 | reactivated_item(payload) {
130 | let { item } = payload
131 | let { title } = item
132 | let text = this.sanitize(() => `Reactivated: ${title.replace('\n', '')}\n${this.linksForItem(item)}`)
133 |
134 | return {
135 | references: [item.id],
136 | subject: item.title,
137 | notification: text.sanitized,
138 | attachment: {
139 | color: COLORS.level.info,
140 | text: text.toString(),
141 | }
142 | }
143 | }
144 |
145 | reopened_item(payload) {
146 | let { item } = payload
147 | let { title } = item
148 | let text = this.sanitize(() => `Reopened: ${title.replace('\n', '')}\n${this.linksForItem(item)}`)
149 |
150 | return {
151 | references: [item.id],
152 | subject: item.title,
153 | notification: text.sanitized,
154 | attachment: {
155 | color: COLORS.level.info,
156 | text: text.toString(),
157 | }
158 | }
159 | }
160 |
161 | resolved_item(payload) {
162 | let { item } = payload
163 | let { title } = item
164 | let text = this.sanitize(() => `Resolved: ${title.replace('\n', '')}\n${this.linksForItem(item)}`)
165 | let color = COLORS.resolved
166 |
167 | return {
168 | references: [item.id],
169 | subject: item.title,
170 | color: color,
171 | notification: text.sanitized,
172 | attachment: {
173 | color: color,
174 | text: text.toString(),
175 | }
176 | }
177 | }
178 |
179 | // Helpers
180 | linksForItem(item, occurrence) {
181 | let { counter, last_occurrence_id } = item
182 |
183 | let baseURL = `https://rollbar.com/${this.options.account}/${this.options.project}`
184 | let itemURL = `${baseURL}/items/${counter}`
185 |
186 | if (occurrence) {
187 | let occurrenceURL = `${itemURL}/occurrences/${last_occurrence_id}`
188 | return `${this.link(itemURL)} (${this.link(occurrenceURL, 'Occurrence')})`
189 | } else {
190 | return this.link(itemURL)
191 | }
192 | }
193 | }
194 |
195 | module.exports = Rollbar
196 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "missive-webhooks",
3 | "version": "1.0.0",
4 | "description": "Missive built-in integrations",
5 | "main": "lib/index.js",
6 | "scripts": {
7 | "start": "node server.js"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+ssh://git@github.com/missive/missive-webhooks.git"
12 | },
13 | "author": "",
14 | "license": "MIT",
15 | "bugs": {
16 | "url": "https://github.com/missive/missive-webhooks/issues"
17 | },
18 | "homepage": "https://github.com/missive/missive-webhooks#readme",
19 | "dependencies": {
20 | "atob": "2.1.2",
21 | "body-parser": "1.18.2",
22 | "cors": "2.8.5",
23 | "express": "4.18.2",
24 | "request": "2.88.2",
25 | "rollbar": "2.4.2"
26 | },
27 | "devDependencies": {
28 | "dotenv": "4.0.0"
29 | },
30 | "engines": {
31 | "node": "18.14.1"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | process.env.NODE_ENV || (process.env.NODE_ENV = 'development')
2 | if (process.env.NODE_ENV != 'production') {
3 | require('dotenv').config()
4 | }
5 |
6 | const Atob = require('atob')
7 | const BodyParser = require('body-parser')
8 | const Express = require('express')
9 | const Port = process.env.PORT || 8080
10 | const Request = require('request')
11 | const Rollbar = require('rollbar')
12 | const Cors = require('cors')
13 |
14 | const Integrations = require('.')
15 |
16 | let app = Express()
17 | app.disable('x-powered-by')
18 | app.use(BodyParser.json({ limit: '10mb' }))
19 | app.use(BodyParser.urlencoded({ extended: true, limit: '10mb' }))
20 | app.use(Cors())
21 |
22 | app.use((req, res, next) => {
23 | res.header('Content-Security-Policy', "default-src 'none'; style-src 'unsafe-inline'")
24 | res.header('X-Content-Type-Options', 'nosniff')
25 | res.header('X-Frame-Options', 'SAMEORIGIN')
26 | res.header('X-XSS-Protection', '1; mode=block')
27 |
28 | // Force HTTPS
29 | if (req.secure || req.header('X-Forwarded-Proto') == 'https') {
30 | res.header('Strict-Transport-Security', 'max-age=31536000; includeSubDomains')
31 | return next()
32 | }
33 | res.redirect(`https://${req.hostname}${req.url}`)
34 | })
35 |
36 | app.post('/:provider', (req, res) => {
37 | let { provider } = req.params
38 | let integration, base64JSON = req.query.t
39 |
40 | let notFound = () => {
41 | res.status(404).send(`Integration not found: ${provider}`)
42 | }
43 |
44 | if (!base64JSON) {
45 | return notFound()
46 | }
47 |
48 | let data = null
49 | try {
50 | data = JSON.parse(Atob(base64JSON))
51 | } catch (e) {
52 | return notFound()
53 | }
54 |
55 | const { token: bearer, options } = data
56 |
57 | const createPost = (payload = {}) => {
58 | const posts = JSON.parse(JSON.stringify(options || {}))
59 |
60 | const { references, conversation, subject, color, update_existing_conversation_subject, attachment, text, markdown, notification, callback } = payload
61 | const attachments = attachment ? [attachment] : payload.attachments
62 |
63 | if ((references || conversation) && (text || markdown || attachments)) {
64 | posts.username = integration.name
65 | posts.username_icon = integration.avatar
66 | posts.text = text
67 | posts.markdown = markdown
68 | posts.attachments = attachments
69 | posts.notification = {
70 | title: subject,
71 | body: notification,
72 | }
73 |
74 | if (conversation) {
75 | posts.conversation = conversation
76 | delete posts.organization
77 | delete posts.add_shared_labels
78 | delete posts.add_users
79 | } else {
80 | posts.references = references.map((ref) => `<${provider}/${ref}@missive-integrations>`)
81 | posts.conversation_subject = subject
82 | posts.conversation_color = color
83 | posts.update_existing_conversation_subject = update_existing_conversation_subject || false
84 | posts.conversation_icon = integration.icon
85 | }
86 |
87 | return Request.post({
88 | baseUrl: process.env.MISSIVE_API_BASE_URL,
89 | uri: '/posts',
90 | json: { posts },
91 | auth: { bearer },
92 | callback: (err, response, body) => {
93 | if (err) return
94 | callback && callback(body.posts.conversation, { createPost })
95 | },
96 | })
97 | }
98 | }
99 |
100 | if (integration = Integrations[provider]) {
101 | const payload = integration.process(req.body, req, data[provider])
102 | const request = createPost(payload)
103 |
104 | if (request) {
105 | return request.pipe(res)
106 | }
107 |
108 | return res.status(200).send('Event type not implemented')
109 | }
110 |
111 | notFound()
112 | })
113 |
114 | app.post('/', (req, res) => {
115 | res.send('Pong')
116 | })
117 |
118 | app.get('/', (req, res) => {
119 | res.send(`
120 |
137 |
138 |
139 | 🖖
140 |
141 | `)
142 | })
143 |
144 | app.get('/integrations', (req, res) => {
145 | let integrations = {}
146 |
147 | for (let provider in Integrations) {
148 | let integration = Integrations[provider]
149 | if (integration.deprecated) continue
150 |
151 | integrations[provider] = integration.toJSON()
152 | }
153 |
154 | res.send(integrations)
155 | })
156 |
157 | app.get('*', (req, res) => {
158 | res.status(404).send('Not Found')
159 | })
160 |
161 | // Rollbar
162 | // Must be added after all routes are registered
163 | if (process.env.ROLLBAR_SERVER_ACCESS_TOKEN) {
164 | let rollbar = new Rollbar({
165 | accessToken: process.env.ROLLBAR_SERVER_ACCESS_TOKEN,
166 | captureUncaught: true,
167 | captureUnhandledRejections: true,
168 | })
169 |
170 | app.use(rollbar.errorHandler())
171 | rollbar.handleUncaughtExceptions()
172 | }
173 |
174 | app.listen(Port, () => {
175 | console.log(`Missive Webhooks listening on port ${Port}`)
176 | })
177 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | accepts@~1.3.8:
6 | version "1.3.8"
7 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
8 | integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==
9 | dependencies:
10 | mime-types "~2.1.34"
11 | negotiator "0.6.3"
12 |
13 | ajv@^6.12.3:
14 | version "6.12.6"
15 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
16 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
17 | dependencies:
18 | fast-deep-equal "^3.1.1"
19 | fast-json-stable-stringify "^2.0.0"
20 | json-schema-traverse "^0.4.1"
21 | uri-js "^4.2.2"
22 |
23 | array-flatten@1.1.1:
24 | version "1.1.1"
25 | resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
26 | integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=
27 |
28 | asn1@~0.2.3:
29 | version "0.2.6"
30 | resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d"
31 | integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==
32 | dependencies:
33 | safer-buffer "~2.1.0"
34 |
35 | assert-plus@1.0.0, assert-plus@^1.0.0:
36 | version "1.0.0"
37 | resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
38 | integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==
39 |
40 | async@~1.2.1:
41 | version "1.2.1"
42 | resolved "https://registry.yarnpkg.com/async/-/async-1.2.1.tgz#a4816a17cd5ff516dfa2c7698a453369b9790de0"
43 | integrity sha1-pIFqF81f9RbfosdpikUzabl5DeA=
44 |
45 | asynckit@^0.4.0:
46 | version "0.4.0"
47 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
48 | integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
49 |
50 | atob@2.1.2:
51 | version "2.1.2"
52 | resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
53 | integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
54 |
55 | aws-sign2@~0.7.0:
56 | version "0.7.0"
57 | resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
58 | integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
59 |
60 | aws4@^1.8.0:
61 | version "1.11.0"
62 | resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59"
63 | integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==
64 |
65 | bcrypt-pbkdf@^1.0.0:
66 | version "1.0.2"
67 | resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
68 | integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==
69 | dependencies:
70 | tweetnacl "^0.14.3"
71 |
72 | body-parser@1.18.2:
73 | version "1.18.2"
74 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454"
75 | integrity sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=
76 | dependencies:
77 | bytes "3.0.0"
78 | content-type "~1.0.4"
79 | debug "2.6.9"
80 | depd "~1.1.1"
81 | http-errors "~1.6.2"
82 | iconv-lite "0.4.19"
83 | on-finished "~2.3.0"
84 | qs "6.5.1"
85 | raw-body "2.3.2"
86 | type-is "~1.6.15"
87 |
88 | body-parser@1.20.1:
89 | version "1.20.1"
90 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668"
91 | integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==
92 | dependencies:
93 | bytes "3.1.2"
94 | content-type "~1.0.4"
95 | debug "2.6.9"
96 | depd "2.0.0"
97 | destroy "1.2.0"
98 | http-errors "2.0.0"
99 | iconv-lite "0.4.24"
100 | on-finished "2.4.1"
101 | qs "6.11.0"
102 | raw-body "2.5.1"
103 | type-is "~1.6.18"
104 | unpipe "1.0.0"
105 |
106 | bytes@3.0.0:
107 | version "3.0.0"
108 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
109 | integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=
110 |
111 | bytes@3.1.2:
112 | version "3.1.2"
113 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
114 | integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
115 |
116 | call-bind@^1.0.0:
117 | version "1.0.2"
118 | resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
119 | integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==
120 | dependencies:
121 | function-bind "^1.1.1"
122 | get-intrinsic "^1.0.2"
123 |
124 | caseless@~0.12.0:
125 | version "0.12.0"
126 | resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
127 | integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
128 |
129 | combined-stream@^1.0.6, combined-stream@~1.0.6:
130 | version "1.0.8"
131 | resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
132 | integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
133 | dependencies:
134 | delayed-stream "~1.0.0"
135 |
136 | console-polyfill@0.3.0:
137 | version "0.3.0"
138 | resolved "https://registry.yarnpkg.com/console-polyfill/-/console-polyfill-0.3.0.tgz#84900902a18c47a5eba932be75fa44d23e8af861"
139 | integrity sha512-w+JSDZS7XML43Xnwo2x5O5vxB0ID7T5BdqDtyqT6uiCAX2kZAgcWxNaGqT97tZfSHzfOcvrfsDAodKcJ3UvnXQ==
140 |
141 | content-disposition@0.5.4:
142 | version "0.5.4"
143 | resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe"
144 | integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==
145 | dependencies:
146 | safe-buffer "5.2.1"
147 |
148 | content-type@~1.0.4:
149 | version "1.0.4"
150 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
151 | integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
152 |
153 | cookie-signature@1.0.6:
154 | version "1.0.6"
155 | resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
156 | integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw=
157 |
158 | cookie@0.5.0:
159 | version "0.5.0"
160 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
161 | integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
162 |
163 | core-util-is@1.0.2:
164 | version "1.0.2"
165 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
166 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
167 |
168 | cors@2.8.5:
169 | version "2.8.5"
170 | resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29"
171 | integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==
172 | dependencies:
173 | object-assign "^4"
174 | vary "^1"
175 |
176 | dashdash@^1.12.0:
177 | version "1.14.1"
178 | resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
179 | integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==
180 | dependencies:
181 | assert-plus "^1.0.0"
182 |
183 | debug@2.6.9:
184 | version "2.6.9"
185 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
186 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
187 | dependencies:
188 | ms "2.0.0"
189 |
190 | decache@^3.0.5:
191 | version "3.1.0"
192 | resolved "https://registry.yarnpkg.com/decache/-/decache-3.1.0.tgz#4f5036fbd6581fcc97237ac3954a244b9536c2da"
193 | integrity sha1-T1A2+9ZYH8yXI3rDlUokS5U2wto=
194 | dependencies:
195 | find "^0.2.4"
196 |
197 | delayed-stream@~1.0.0:
198 | version "1.0.0"
199 | resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
200 | integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
201 |
202 | depd@1.1.1, depd@~1.1.1:
203 | version "1.1.1"
204 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359"
205 | integrity sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=
206 |
207 | depd@2.0.0:
208 | version "2.0.0"
209 | resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
210 | integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
211 |
212 | destroy@1.2.0:
213 | version "1.2.0"
214 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
215 | integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
216 |
217 | dotenv@4.0.0:
218 | version "4.0.0"
219 | resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-4.0.0.tgz#864ef1379aced55ce6f95debecdce179f7a0cd1d"
220 | integrity sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0=
221 |
222 | ecc-jsbn@~0.1.1:
223 | version "0.1.2"
224 | resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
225 | integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==
226 | dependencies:
227 | jsbn "~0.1.0"
228 | safer-buffer "^2.1.0"
229 |
230 | ee-first@1.1.1:
231 | version "1.1.1"
232 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
233 | integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
234 |
235 | encodeurl@~1.0.2:
236 | version "1.0.2"
237 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
238 | integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
239 |
240 | error-stack-parser@1.3.3:
241 | version "1.3.3"
242 | resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-1.3.3.tgz#fada6e3a9cd2b0e080e6d6fc751418649734f35c"
243 | integrity sha1-+tpuOpzSsOCA5tb8dRQYZJc081w=
244 | dependencies:
245 | stackframe "^0.3.1"
246 |
247 | escape-html@~1.0.3:
248 | version "1.0.3"
249 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
250 | integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
251 |
252 | etag@~1.8.1:
253 | version "1.8.1"
254 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
255 | integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
256 |
257 | express@4.18.2:
258 | version "4.18.2"
259 | resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
260 | integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
261 | dependencies:
262 | accepts "~1.3.8"
263 | array-flatten "1.1.1"
264 | body-parser "1.20.1"
265 | content-disposition "0.5.4"
266 | content-type "~1.0.4"
267 | cookie "0.5.0"
268 | cookie-signature "1.0.6"
269 | debug "2.6.9"
270 | depd "2.0.0"
271 | encodeurl "~1.0.2"
272 | escape-html "~1.0.3"
273 | etag "~1.8.1"
274 | finalhandler "1.2.0"
275 | fresh "0.5.2"
276 | http-errors "2.0.0"
277 | merge-descriptors "1.0.1"
278 | methods "~1.1.2"
279 | on-finished "2.4.1"
280 | parseurl "~1.3.3"
281 | path-to-regexp "0.1.7"
282 | proxy-addr "~2.0.7"
283 | qs "6.11.0"
284 | range-parser "~1.2.1"
285 | safe-buffer "5.2.1"
286 | send "0.18.0"
287 | serve-static "1.15.0"
288 | setprototypeof "1.2.0"
289 | statuses "2.0.1"
290 | type-is "~1.6.18"
291 | utils-merge "1.0.1"
292 | vary "~1.1.2"
293 |
294 | extend@~3.0.2:
295 | version "3.0.2"
296 | resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
297 | integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
298 |
299 | extsprintf@1.3.0:
300 | version "1.3.0"
301 | resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
302 | integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
303 |
304 | extsprintf@^1.2.0:
305 | version "1.4.0"
306 | resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
307 | integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
308 |
309 | fast-deep-equal@^3.1.1:
310 | version "3.1.3"
311 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
312 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
313 |
314 | fast-json-stable-stringify@^2.0.0:
315 | version "2.0.0"
316 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
317 | integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
318 |
319 | finalhandler@1.2.0:
320 | version "1.2.0"
321 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32"
322 | integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==
323 | dependencies:
324 | debug "2.6.9"
325 | encodeurl "~1.0.2"
326 | escape-html "~1.0.3"
327 | on-finished "2.4.1"
328 | parseurl "~1.3.3"
329 | statuses "2.0.1"
330 | unpipe "~1.0.0"
331 |
332 | find@^0.2.4:
333 | version "0.2.9"
334 | resolved "https://registry.yarnpkg.com/find/-/find-0.2.9.tgz#4b73f1ff9e56ad91b76e716407fe5ffe6554bb8c"
335 | integrity sha1-S3Px/55WrZG3bnFkB/5f/mVUu4w=
336 | dependencies:
337 | traverse-chain "~0.1.0"
338 |
339 | forever-agent@~0.6.1:
340 | version "0.6.1"
341 | resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
342 | integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
343 |
344 | form-data@~2.3.2:
345 | version "2.3.3"
346 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
347 | integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
348 | dependencies:
349 | asynckit "^0.4.0"
350 | combined-stream "^1.0.6"
351 | mime-types "^2.1.12"
352 |
353 | forwarded@0.2.0:
354 | version "0.2.0"
355 | resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
356 | integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
357 |
358 | fresh@0.5.2:
359 | version "0.5.2"
360 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
361 | integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
362 |
363 | function-bind@^1.1.1:
364 | version "1.1.1"
365 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
366 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
367 |
368 | get-intrinsic@^1.0.2:
369 | version "1.1.3"
370 | resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385"
371 | integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==
372 | dependencies:
373 | function-bind "^1.1.1"
374 | has "^1.0.3"
375 | has-symbols "^1.0.3"
376 |
377 | getpass@^0.1.1:
378 | version "0.1.7"
379 | resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
380 | integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==
381 | dependencies:
382 | assert-plus "^1.0.0"
383 |
384 | har-schema@^2.0.0:
385 | version "2.0.0"
386 | resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
387 | integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
388 |
389 | har-validator@~5.1.3:
390 | version "5.1.5"
391 | resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd"
392 | integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==
393 | dependencies:
394 | ajv "^6.12.3"
395 | har-schema "^2.0.0"
396 |
397 | has-symbols@^1.0.3:
398 | version "1.0.3"
399 | resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
400 | integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
401 |
402 | has@^1.0.3:
403 | version "1.0.3"
404 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
405 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
406 | dependencies:
407 | function-bind "^1.1.1"
408 |
409 | http-errors@1.6.2, http-errors@~1.6.2:
410 | version "1.6.2"
411 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736"
412 | integrity sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=
413 | dependencies:
414 | depd "1.1.1"
415 | inherits "2.0.3"
416 | setprototypeof "1.0.3"
417 | statuses ">= 1.3.1 < 2"
418 |
419 | http-errors@2.0.0:
420 | version "2.0.0"
421 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
422 | integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==
423 | dependencies:
424 | depd "2.0.0"
425 | inherits "2.0.4"
426 | setprototypeof "1.2.0"
427 | statuses "2.0.1"
428 | toidentifier "1.0.1"
429 |
430 | http-signature@~1.2.0:
431 | version "1.2.0"
432 | resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
433 | integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
434 | dependencies:
435 | assert-plus "^1.0.0"
436 | jsprim "^1.2.2"
437 | sshpk "^1.7.0"
438 |
439 | iconv-lite@0.4.19:
440 | version "0.4.19"
441 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
442 | integrity sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==
443 |
444 | iconv-lite@0.4.24:
445 | version "0.4.24"
446 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
447 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
448 | dependencies:
449 | safer-buffer ">= 2.1.2 < 3"
450 |
451 | inherits@2.0.3:
452 | version "2.0.3"
453 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
454 | integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
455 |
456 | inherits@2.0.4:
457 | version "2.0.4"
458 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
459 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
460 |
461 | ipaddr.js@1.9.1:
462 | version "1.9.1"
463 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
464 | integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
465 |
466 | is-typedarray@~1.0.0:
467 | version "1.0.0"
468 | resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
469 | integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
470 |
471 | is_js@^0.9.0:
472 | version "0.9.0"
473 | resolved "https://registry.yarnpkg.com/is_js/-/is_js-0.9.0.tgz#0ab94540502ba7afa24c856aa985561669e9c52d"
474 | integrity sha1-CrlFQFArp6+iTIVqqYVWFmnpxS0=
475 |
476 | isstream@~0.1.2:
477 | version "0.1.2"
478 | resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
479 | integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
480 |
481 | jsbn@~0.1.0:
482 | version "0.1.1"
483 | resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
484 | integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==
485 |
486 | json-schema-traverse@^0.4.1:
487 | version "0.4.1"
488 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
489 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
490 |
491 | json-schema@0.2.3:
492 | version "0.2.3"
493 | resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
494 | integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
495 |
496 | json-stringify-safe@~5.0.0, json-stringify-safe@~5.0.1:
497 | version "5.0.1"
498 | resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
499 | integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
500 |
501 | jsprim@^1.2.2:
502 | version "1.4.1"
503 | resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
504 | integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
505 | dependencies:
506 | assert-plus "1.0.0"
507 | extsprintf "1.3.0"
508 | json-schema "0.2.3"
509 | verror "1.10.0"
510 |
511 | lru-cache@~2.2.1:
512 | version "2.2.4"
513 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.2.4.tgz#6c658619becf14031d0d0b594b16042ce4dc063d"
514 | integrity sha1-bGWGGb7PFAMdDQtZSxYELOTcBj0=
515 |
516 | media-typer@0.3.0:
517 | version "0.3.0"
518 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
519 | integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
520 |
521 | merge-descriptors@1.0.1:
522 | version "1.0.1"
523 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
524 | integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=
525 |
526 | methods@~1.1.2:
527 | version "1.1.2"
528 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
529 | integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
530 |
531 | mime-db@1.52.0:
532 | version "1.52.0"
533 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
534 | integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
535 |
536 | mime-db@~1.30.0:
537 | version "1.30.0"
538 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01"
539 | integrity sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=
540 |
541 | mime-types@^2.1.12, mime-types@~2.1.15:
542 | version "2.1.17"
543 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a"
544 | integrity sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=
545 | dependencies:
546 | mime-db "~1.30.0"
547 |
548 | mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34:
549 | version "2.1.35"
550 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
551 | integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
552 | dependencies:
553 | mime-db "1.52.0"
554 |
555 | mime@1.6.0:
556 | version "1.6.0"
557 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
558 | integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
559 |
560 | ms@2.0.0:
561 | version "2.0.0"
562 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
563 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
564 |
565 | ms@2.1.3:
566 | version "2.1.3"
567 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
568 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
569 |
570 | negotiator@0.6.3:
571 | version "0.6.3"
572 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
573 | integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
574 |
575 | oauth-sign@~0.9.0:
576 | version "0.9.0"
577 | resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
578 | integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
579 |
580 | object-assign@^4:
581 | version "4.1.1"
582 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
583 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
584 |
585 | object-inspect@^1.9.0:
586 | version "1.12.2"
587 | resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea"
588 | integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==
589 |
590 | on-finished@2.4.1:
591 | version "2.4.1"
592 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
593 | integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
594 | dependencies:
595 | ee-first "1.1.1"
596 |
597 | on-finished@~2.3.0:
598 | version "2.3.0"
599 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
600 | integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=
601 | dependencies:
602 | ee-first "1.1.1"
603 |
604 | parseurl@~1.3.3:
605 | version "1.3.3"
606 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
607 | integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
608 |
609 | path-to-regexp@0.1.7:
610 | version "0.1.7"
611 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
612 | integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
613 |
614 | performance-now@^2.1.0:
615 | version "2.1.0"
616 | resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
617 | integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
618 |
619 | proxy-addr@~2.0.7:
620 | version "2.0.7"
621 | resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025"
622 | integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==
623 | dependencies:
624 | forwarded "0.2.0"
625 | ipaddr.js "1.9.1"
626 |
627 | psl@^1.1.28:
628 | version "1.9.0"
629 | resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"
630 | integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==
631 |
632 | punycode@^2.1.0, punycode@^2.1.1:
633 | version "2.1.1"
634 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
635 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
636 |
637 | qs@6.11.0:
638 | version "6.11.0"
639 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
640 | integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==
641 | dependencies:
642 | side-channel "^1.0.4"
643 |
644 | qs@6.5.1:
645 | version "6.5.1"
646 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
647 | integrity sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==
648 |
649 | qs@~6.5.2:
650 | version "6.5.3"
651 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"
652 | integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==
653 |
654 | range-parser@~1.2.1:
655 | version "1.2.1"
656 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
657 | integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
658 |
659 | raw-body@2.3.2:
660 | version "2.3.2"
661 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89"
662 | integrity sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=
663 | dependencies:
664 | bytes "3.0.0"
665 | http-errors "1.6.2"
666 | iconv-lite "0.4.19"
667 | unpipe "1.0.0"
668 |
669 | raw-body@2.5.1:
670 | version "2.5.1"
671 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857"
672 | integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==
673 | dependencies:
674 | bytes "3.1.2"
675 | http-errors "2.0.0"
676 | iconv-lite "0.4.24"
677 | unpipe "1.0.0"
678 |
679 | request-ip@~2.0.1:
680 | version "2.0.2"
681 | resolved "https://registry.yarnpkg.com/request-ip/-/request-ip-2.0.2.tgz#deeae6d4af21768497db8cd05fa37143f8f1257e"
682 | integrity sha1-3urm1K8hdoSX24zQX6NxQ/jxJX4=
683 | dependencies:
684 | is_js "^0.9.0"
685 |
686 | request@2.88.2:
687 | version "2.88.2"
688 | resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
689 | integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
690 | dependencies:
691 | aws-sign2 "~0.7.0"
692 | aws4 "^1.8.0"
693 | caseless "~0.12.0"
694 | combined-stream "~1.0.6"
695 | extend "~3.0.2"
696 | forever-agent "~0.6.1"
697 | form-data "~2.3.2"
698 | har-validator "~5.1.3"
699 | http-signature "~1.2.0"
700 | is-typedarray "~1.0.0"
701 | isstream "~0.1.2"
702 | json-stringify-safe "~5.0.1"
703 | mime-types "~2.1.19"
704 | oauth-sign "~0.9.0"
705 | performance-now "^2.1.0"
706 | qs "~6.5.2"
707 | safe-buffer "^5.1.2"
708 | tough-cookie "~2.5.0"
709 | tunnel-agent "^0.6.0"
710 | uuid "^3.3.2"
711 |
712 | rollbar@2.4.2:
713 | version "2.4.2"
714 | resolved "https://registry.yarnpkg.com/rollbar/-/rollbar-2.4.2.tgz#44286aec383a49d7849da92b5b9e31999847cfc9"
715 | integrity sha512-7k3eTkdOBZ/ieKhdq2GUrYZpSyD8T+lrpzx9kBJpAhtj/aGCQkVyT1ZVPUxusGXrovv90Ap/1XwcpzAH1BUWjA==
716 | dependencies:
717 | async "~1.2.1"
718 | console-polyfill "0.3.0"
719 | debug "2.6.9"
720 | error-stack-parser "1.3.3"
721 | json-stringify-safe "~5.0.0"
722 | lru-cache "~2.2.1"
723 | request-ip "~2.0.1"
724 | uuid "3.0.x"
725 | optionalDependencies:
726 | decache "^3.0.5"
727 |
728 | safe-buffer@5.2.1, safe-buffer@^5.1.2:
729 | version "5.2.1"
730 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
731 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
732 |
733 | safe-buffer@^5.0.1:
734 | version "5.1.1"
735 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
736 | integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==
737 |
738 | "safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
739 | version "2.1.2"
740 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
741 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
742 |
743 | send@0.18.0:
744 | version "0.18.0"
745 | resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
746 | integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==
747 | dependencies:
748 | debug "2.6.9"
749 | depd "2.0.0"
750 | destroy "1.2.0"
751 | encodeurl "~1.0.2"
752 | escape-html "~1.0.3"
753 | etag "~1.8.1"
754 | fresh "0.5.2"
755 | http-errors "2.0.0"
756 | mime "1.6.0"
757 | ms "2.1.3"
758 | on-finished "2.4.1"
759 | range-parser "~1.2.1"
760 | statuses "2.0.1"
761 |
762 | serve-static@1.15.0:
763 | version "1.15.0"
764 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540"
765 | integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==
766 | dependencies:
767 | encodeurl "~1.0.2"
768 | escape-html "~1.0.3"
769 | parseurl "~1.3.3"
770 | send "0.18.0"
771 |
772 | setprototypeof@1.0.3:
773 | version "1.0.3"
774 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04"
775 | integrity sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=
776 |
777 | setprototypeof@1.2.0:
778 | version "1.2.0"
779 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
780 | integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
781 |
782 | side-channel@^1.0.4:
783 | version "1.0.4"
784 | resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
785 | integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
786 | dependencies:
787 | call-bind "^1.0.0"
788 | get-intrinsic "^1.0.2"
789 | object-inspect "^1.9.0"
790 |
791 | sshpk@^1.7.0:
792 | version "1.17.0"
793 | resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5"
794 | integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==
795 | dependencies:
796 | asn1 "~0.2.3"
797 | assert-plus "^1.0.0"
798 | bcrypt-pbkdf "^1.0.0"
799 | dashdash "^1.12.0"
800 | ecc-jsbn "~0.1.1"
801 | getpass "^0.1.1"
802 | jsbn "~0.1.0"
803 | safer-buffer "^2.0.2"
804 | tweetnacl "~0.14.0"
805 |
806 | stackframe@^0.3.1:
807 | version "0.3.1"
808 | resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-0.3.1.tgz#33aa84f1177a5548c8935533cbfeb3420975f5a4"
809 | integrity sha1-M6qE8Rd6VUjIk1Uzy/6zQgl19aQ=
810 |
811 | statuses@2.0.1:
812 | version "2.0.1"
813 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
814 | integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
815 |
816 | "statuses@>= 1.3.1 < 2":
817 | version "1.4.0"
818 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087"
819 | integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==
820 |
821 | toidentifier@1.0.1:
822 | version "1.0.1"
823 | resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
824 | integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
825 |
826 | tough-cookie@~2.5.0:
827 | version "2.5.0"
828 | resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
829 | integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
830 | dependencies:
831 | psl "^1.1.28"
832 | punycode "^2.1.1"
833 |
834 | traverse-chain@~0.1.0:
835 | version "0.1.0"
836 | resolved "https://registry.yarnpkg.com/traverse-chain/-/traverse-chain-0.1.0.tgz#61dbc2d53b69ff6091a12a168fd7d433107e40f1"
837 | integrity sha1-YdvC1Ttp/2CRoSoWj9fUMxB+QPE=
838 |
839 | tunnel-agent@^0.6.0:
840 | version "0.6.0"
841 | resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
842 | integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
843 | dependencies:
844 | safe-buffer "^5.0.1"
845 |
846 | tweetnacl@^0.14.3, tweetnacl@~0.14.0:
847 | version "0.14.5"
848 | resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
849 | integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==
850 |
851 | type-is@~1.6.15:
852 | version "1.6.15"
853 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410"
854 | integrity sha1-yrEPtJCeRByChC6v4a1kbIGARBA=
855 | dependencies:
856 | media-typer "0.3.0"
857 | mime-types "~2.1.15"
858 |
859 | type-is@~1.6.18:
860 | version "1.6.18"
861 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
862 | integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
863 | dependencies:
864 | media-typer "0.3.0"
865 | mime-types "~2.1.24"
866 |
867 | unpipe@1.0.0, unpipe@~1.0.0:
868 | version "1.0.0"
869 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
870 | integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=
871 |
872 | uri-js@^4.2.2:
873 | version "4.4.1"
874 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
875 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
876 | dependencies:
877 | punycode "^2.1.0"
878 |
879 | utils-merge@1.0.1:
880 | version "1.0.1"
881 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
882 | integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
883 |
884 | uuid@3.0.x:
885 | version "3.0.1"
886 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1"
887 | integrity sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE=
888 |
889 | uuid@^3.3.2:
890 | version "3.4.0"
891 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
892 | integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
893 |
894 | vary@^1, vary@~1.1.2:
895 | version "1.1.2"
896 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
897 | integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
898 |
899 | verror@1.10.0:
900 | version "1.10.0"
901 | resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
902 | integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
903 | dependencies:
904 | assert-plus "^1.0.0"
905 | core-util-is "1.0.2"
906 | extsprintf "^1.2.0"
907 |
--------------------------------------------------------------------------------