UNPKG

2.46 kBJavaScriptView Raw
1'use strict'
2
3const cli = require('heroku-cli-util')
4const path = require('path')
5const wait = ms => new Promise(resolve => setTimeout(resolve, ms))
6
7async function run (context, heroku) {
8 const debug = require('debug')('heroku-pg')
9 const fetcher = require('../lib/fetcher')(heroku)
10 const host = require('../lib/host')
11 const app = context.app
12 const db = context.args.database
13 const notify = require('../lib/notify')(context)
14
15 let waitFor = async function waitFor (db) {
16 let interval = parseInt(context.flags['wait-interval'])
17 if (!interval || interval < 0) interval = 5
18
19 let status
20 let waiting = false
21 let name = 'db'
22 let retries = 20
23
24 while (true) {
25 try {
26 status = await heroku.request({
27 host: host(db),
28 path: `/client/v11/databases/${db.id}/wait_status`
29 })
30 } catch (err) {
31 debug(err)
32 if (!retries || err.statusCode !== 404) throw err
33 retries--
34 status = { 'waiting?': true }
35 }
36
37 if (status['error?']) {
38 notify({
39 sound: true,
40 subtitle: 'error',
41 message: `${name} ${status['message']}`,
42 contentImage: path.join(__dirname, '../assets/error.png')
43 })
44 cli.error(status['message'])
45 cli.exit(1)
46 }
47
48 if (!status['waiting?']) {
49 if (waiting) {
50 notify({
51 sound: true,
52 message: `${name} is ${status['message']}`,
53 contentImage: path.join(__dirname, '../assets/success.png')
54 })
55 cli.action.done(status.message)
56 }
57 return
58 }
59
60 if (!waiting) {
61 waiting = true
62 name = db.name
63 cli.action.start(`Waiting for database ${cli.color.addon(db.name)}`)
64 }
65
66 cli.action.status(status.message)
67
68 await wait(interval * 1000)
69 }
70 }
71
72 let dbs = []
73 if (db) {
74 dbs = [ await fetcher.addon(app, db) ]
75 } else {
76 dbs = await fetcher.all(app)
77 }
78
79 for (let db of dbs) await waitFor(db)
80}
81
82module.exports = {
83 topic: 'pg',
84 command: 'wait',
85 description: 'blocks until database is available',
86 needsApp: true,
87 needsAuth: true,
88 args: [{ name: 'database', optional: true }],
89 flags: [
90 { name: 'wait-interval', description: 'how frequently to poll in seconds (to avoid rate limiting)', hasValue: true },
91 { name: 'no-notify', description: 'do not show OS notification' }
92 ],
93 run: cli.command({ preauth: true }, run)
94}