slipway-cli 0.0.1 → 0.0.2
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/package.json +1 -1
- package/src/commands/slide.js +69 -11
- package/src/lib/utils.js +8 -3
package/package.json
CHANGED
package/src/commands/slide.js
CHANGED
|
@@ -4,6 +4,56 @@ import { api } from '../lib/api.js'
|
|
|
4
4
|
import { isLoggedIn, getCredentials } from '../lib/config.js'
|
|
5
5
|
import { error, requireProject, createSpinner } from '../lib/utils.js'
|
|
6
6
|
|
|
7
|
+
const maritimeMessages = {
|
|
8
|
+
pending: [
|
|
9
|
+
'Waiting for the tide...',
|
|
10
|
+
'Checking the compass...',
|
|
11
|
+
'Reading the stars...',
|
|
12
|
+
'Gathering the crew...',
|
|
13
|
+
],
|
|
14
|
+
building: [
|
|
15
|
+
'Hoisting the sails...',
|
|
16
|
+
'Loading the cargo...',
|
|
17
|
+
'Checking the rigging...',
|
|
18
|
+
'Swabbing the deck...',
|
|
19
|
+
'Tying the knots...',
|
|
20
|
+
'Hammering the hull...',
|
|
21
|
+
],
|
|
22
|
+
pushing: [
|
|
23
|
+
'Signaling the fleet...',
|
|
24
|
+
'Sending up a flare...',
|
|
25
|
+
'Raising the flag...',
|
|
26
|
+
],
|
|
27
|
+
deploying: [
|
|
28
|
+
'Charting the course...',
|
|
29
|
+
'Setting sail...',
|
|
30
|
+
'Catching the wind...',
|
|
31
|
+
'Navigating the waters...',
|
|
32
|
+
'Full speed ahead...',
|
|
33
|
+
'Approaching the harbor...',
|
|
34
|
+
],
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const statusLabels = {
|
|
38
|
+
pending: 'Waiting',
|
|
39
|
+
building: 'Building',
|
|
40
|
+
pushing: 'Pushing',
|
|
41
|
+
deploying: 'Deploying',
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function createMessageRotator(spinner, status) {
|
|
45
|
+
const messages = maritimeMessages[status]
|
|
46
|
+
if (!messages) return null
|
|
47
|
+
let index = 0
|
|
48
|
+
const label = statusLabels[status] || status
|
|
49
|
+
spinner.setText(`${label} — ${c.dim(messages[0])}`)
|
|
50
|
+
index = 1
|
|
51
|
+
return setInterval(() => {
|
|
52
|
+
spinner.setText(`${label} — ${c.dim(messages[index % messages.length])}`)
|
|
53
|
+
index++
|
|
54
|
+
}, 4000)
|
|
55
|
+
}
|
|
56
|
+
|
|
7
57
|
export default async function slide(options) {
|
|
8
58
|
if (!isLoggedIn()) {
|
|
9
59
|
error('Not logged in. Run `slipway login` first.')
|
|
@@ -183,9 +233,11 @@ function watchDeploymentSSE(deploymentId) {
|
|
|
183
233
|
const controller = new AbortController()
|
|
184
234
|
let currentSpin = null
|
|
185
235
|
let lastStatus = ''
|
|
236
|
+
let messageRotatorInterval = null
|
|
186
237
|
|
|
187
238
|
const timeout = setTimeout(() => {
|
|
188
239
|
controller.abort()
|
|
240
|
+
if (messageRotatorInterval) clearInterval(messageRotatorInterval)
|
|
189
241
|
if (currentSpin) currentSpin.stop()
|
|
190
242
|
reject(new Error('timeout'))
|
|
191
243
|
}, 10 * 60 * 1000) // 10 minute timeout
|
|
@@ -207,6 +259,7 @@ function watchDeploymentSSE(deploymentId) {
|
|
|
207
259
|
let buffer = ''
|
|
208
260
|
|
|
209
261
|
currentSpin = createSpinner('Building...').start()
|
|
262
|
+
messageRotatorInterval = createMessageRotator(currentSpin, 'building')
|
|
210
263
|
|
|
211
264
|
while (true) {
|
|
212
265
|
const { done, value } = await reader.read()
|
|
@@ -227,12 +280,12 @@ function watchDeploymentSSE(deploymentId) {
|
|
|
227
280
|
// Update spinner based on status
|
|
228
281
|
if (data.status !== lastStatus) {
|
|
229
282
|
lastStatus = data.status
|
|
283
|
+
if (messageRotatorInterval) clearInterval(messageRotatorInterval)
|
|
230
284
|
if (currentSpin) currentSpin.stop()
|
|
231
285
|
|
|
232
|
-
if (
|
|
233
|
-
currentSpin = createSpinner('
|
|
234
|
-
|
|
235
|
-
currentSpin = createSpinner('Deploying...').start()
|
|
286
|
+
if (['building', 'pushing', 'deploying'].includes(data.status)) {
|
|
287
|
+
currentSpin = createSpinner('...').start()
|
|
288
|
+
messageRotatorInterval = createMessageRotator(currentSpin, data.status)
|
|
236
289
|
} else if (data.status === 'running' || data.status === 'failed' || data.status === 'cancelled') {
|
|
237
290
|
clearTimeout(timeout)
|
|
238
291
|
controller.abort()
|
|
@@ -243,10 +296,12 @@ function watchDeploymentSSE(deploymentId) {
|
|
|
243
296
|
|
|
244
297
|
// Show build output if available
|
|
245
298
|
if (data.output) {
|
|
299
|
+
if (messageRotatorInterval) clearInterval(messageRotatorInterval)
|
|
246
300
|
if (currentSpin) currentSpin.stop()
|
|
247
301
|
console.log(` ${c.dim(data.output)}`)
|
|
248
|
-
if (
|
|
249
|
-
currentSpin = createSpinner(
|
|
302
|
+
if (['building', 'pushing', 'deploying'].includes(lastStatus)) {
|
|
303
|
+
currentSpin = createSpinner('...').start()
|
|
304
|
+
messageRotatorInterval = createMessageRotator(currentSpin, lastStatus)
|
|
250
305
|
}
|
|
251
306
|
}
|
|
252
307
|
} catch {
|
|
@@ -258,6 +313,7 @@ function watchDeploymentSSE(deploymentId) {
|
|
|
258
313
|
|
|
259
314
|
// Stream ended — resolve with last known status or fall back to polling
|
|
260
315
|
clearTimeout(timeout)
|
|
316
|
+
if (messageRotatorInterval) clearInterval(messageRotatorInterval)
|
|
261
317
|
if (currentSpin) currentSpin.stop()
|
|
262
318
|
if (lastStatus && ['running', 'failed', 'cancelled'].includes(lastStatus)) {
|
|
263
319
|
resolve({ status: lastStatus })
|
|
@@ -267,6 +323,7 @@ function watchDeploymentSSE(deploymentId) {
|
|
|
267
323
|
})
|
|
268
324
|
.catch((err) => {
|
|
269
325
|
clearTimeout(timeout)
|
|
326
|
+
if (messageRotatorInterval) clearInterval(messageRotatorInterval)
|
|
270
327
|
if (currentSpin) currentSpin.stop()
|
|
271
328
|
if (err.name !== 'AbortError') {
|
|
272
329
|
reject(err)
|
|
@@ -281,6 +338,7 @@ function watchDeploymentSSE(deploymentId) {
|
|
|
281
338
|
async function watchDeploymentPolling(deploymentId) {
|
|
282
339
|
const spin = createSpinner('Building...').start()
|
|
283
340
|
let lastStatus = ''
|
|
341
|
+
let messageRotatorInterval = createMessageRotator(spin, 'building')
|
|
284
342
|
|
|
285
343
|
const maxAttempts = 300 // 10 minutes at 2s intervals
|
|
286
344
|
let attempts = 0
|
|
@@ -296,13 +354,12 @@ async function watchDeploymentPolling(deploymentId) {
|
|
|
296
354
|
// Update spinner text based on status
|
|
297
355
|
if (status !== lastStatus) {
|
|
298
356
|
lastStatus = status
|
|
299
|
-
|
|
357
|
+
if (messageRotatorInterval) clearInterval(messageRotatorInterval)
|
|
300
358
|
|
|
301
|
-
if (
|
|
302
|
-
|
|
303
|
-
} else if (status === 'deploying') {
|
|
304
|
-
createSpinner('Deploying...').start()
|
|
359
|
+
if (['building', 'pushing', 'deploying'].includes(status)) {
|
|
360
|
+
messageRotatorInterval = createMessageRotator(spin, status)
|
|
305
361
|
} else if (status === 'running' || status === 'failed' || status === 'cancelled') {
|
|
362
|
+
spin.stop()
|
|
306
363
|
return { status }
|
|
307
364
|
}
|
|
308
365
|
}
|
|
@@ -311,6 +368,7 @@ async function watchDeploymentPolling(deploymentId) {
|
|
|
311
368
|
}
|
|
312
369
|
}
|
|
313
370
|
|
|
371
|
+
if (messageRotatorInterval) clearInterval(messageRotatorInterval)
|
|
314
372
|
spin.stop()
|
|
315
373
|
return { status: 'timeout' }
|
|
316
374
|
}
|
package/src/lib/utils.js
CHANGED
|
@@ -68,22 +68,27 @@ export function createSpinner(text) {
|
|
|
68
68
|
const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
|
|
69
69
|
let i = 0
|
|
70
70
|
let interval = null
|
|
71
|
+
let currentText = text
|
|
71
72
|
|
|
72
73
|
return {
|
|
73
74
|
start() {
|
|
74
|
-
process.stdout.write(`\r${c.info(frames[0])} ${
|
|
75
|
+
process.stdout.write(`\r${c.info(frames[0])} ${currentText}`)
|
|
75
76
|
interval = setInterval(() => {
|
|
76
77
|
i = (i + 1) % frames.length
|
|
77
|
-
process.stdout.write(`\r${c.info(frames[i])} ${
|
|
78
|
+
process.stdout.write(`\x1b[2K\r${c.info(frames[i])} ${currentText}`)
|
|
78
79
|
}, 80)
|
|
79
80
|
return this
|
|
80
81
|
},
|
|
82
|
+
setText(newText) {
|
|
83
|
+
currentText = newText
|
|
84
|
+
return this
|
|
85
|
+
},
|
|
81
86
|
stop(finalText) {
|
|
82
87
|
if (interval) {
|
|
83
88
|
clearInterval(interval)
|
|
84
89
|
interval = null
|
|
85
90
|
}
|
|
86
|
-
process.stdout.write(
|
|
91
|
+
process.stdout.write(`\x1b[2K\r`)
|
|
87
92
|
if (finalText) console.log(finalText)
|
|
88
93
|
return this
|
|
89
94
|
},
|