moontraze 2.0.6 → 2.0.7
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/lib/deploy.js +109 -13
- package/package.json +1 -1
package/lib/deploy.js
CHANGED
|
@@ -6,6 +6,75 @@ const chalk = require('chalk');
|
|
|
6
6
|
const { getConfig, getProject } = require('./config');
|
|
7
7
|
const { zipCwd } = require('./zip');
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Job status poll + Vercel-style gray progress
|
|
11
|
+
*/
|
|
12
|
+
async function waitForDeployJob({ apiUrl, token, jobId }) {
|
|
13
|
+
const start = Date.now();
|
|
14
|
+
const timeoutMs = 15 * 60 * 1000; // 15 min
|
|
15
|
+
let lastMessage = '';
|
|
16
|
+
|
|
17
|
+
const printProgress = (msg) => {
|
|
18
|
+
if (!msg || msg === lastMessage) return;
|
|
19
|
+
lastMessage = msg;
|
|
20
|
+
// same line update (gray)
|
|
21
|
+
process.stdout.write('\r\x1b[K' + chalk.gray(' ' + msg));
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
printProgress('Queued...');
|
|
25
|
+
|
|
26
|
+
while (Date.now() - start < timeoutMs) {
|
|
27
|
+
await new Promise((r) => setTimeout(r, 1500));
|
|
28
|
+
|
|
29
|
+
let data = {};
|
|
30
|
+
try {
|
|
31
|
+
const res = await fetch(
|
|
32
|
+
`${apiUrl}/api/hosting/deployments/job/${encodeURIComponent(jobId)}`,
|
|
33
|
+
{ headers: { Authorization: `Bearer ${token}` } }
|
|
34
|
+
);
|
|
35
|
+
data = await res.json().catch(() => ({}));
|
|
36
|
+
if (!res.ok) {
|
|
37
|
+
throw new Error(data.error || `Status check failed (${res.status})`);
|
|
38
|
+
}
|
|
39
|
+
} catch (e) {
|
|
40
|
+
// network blip — keep polling
|
|
41
|
+
printProgress('Checking status...');
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const state = data.state;
|
|
46
|
+
const progress = data.progress;
|
|
47
|
+
|
|
48
|
+
let message = 'Working...';
|
|
49
|
+
if (typeof progress === 'object' && progress?.message) {
|
|
50
|
+
message = progress.message;
|
|
51
|
+
} else if (typeof progress === 'number') {
|
|
52
|
+
message = `Building... ${progress}%`;
|
|
53
|
+
} else if (state === 'waiting' || state === 'delayed') {
|
|
54
|
+
message = 'Queued — waiting for worker...';
|
|
55
|
+
} else if (state === 'active') {
|
|
56
|
+
message = 'Building...';
|
|
57
|
+
} else if (state === 'completed') {
|
|
58
|
+
message = 'Done';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
printProgress(message);
|
|
62
|
+
|
|
63
|
+
if (state === 'completed') {
|
|
64
|
+
process.stdout.write('\n');
|
|
65
|
+
return data.result || {};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (state === 'failed') {
|
|
69
|
+
process.stdout.write('\n');
|
|
70
|
+
throw new Error(data.error || 'Deploy failed');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
process.stdout.write('\n');
|
|
75
|
+
throw new Error('Deploy timed out. Check dashboard or try again.');
|
|
76
|
+
}
|
|
77
|
+
|
|
9
78
|
async function deploy({
|
|
10
79
|
prod = true,
|
|
11
80
|
projectName,
|
|
@@ -13,21 +82,19 @@ async function deploy({
|
|
|
13
82
|
domain: domainArg,
|
|
14
83
|
} = {}) {
|
|
15
84
|
const cfg = getConfig();
|
|
16
|
-
|
|
17
85
|
const api =
|
|
18
86
|
apiUrlArg ||
|
|
19
87
|
process.env.MOON_API ||
|
|
20
88
|
cfg.apiUrl ||
|
|
21
89
|
'https://api.moontraze.com';
|
|
22
|
-
|
|
23
90
|
const domain =
|
|
24
91
|
domainArg ||
|
|
25
92
|
process.env.MOON_DOMAIN ||
|
|
26
93
|
cfg.domain ||
|
|
27
94
|
'moontraze.com';
|
|
28
|
-
|
|
29
95
|
const token = cfg.token || process.env.MOON_TOKEN || null;
|
|
30
|
-
const label =
|
|
96
|
+
const label =
|
|
97
|
+
process.env.MOON_LABEL || process.env.MOON_PLATFORM || 'Moontraze';
|
|
31
98
|
|
|
32
99
|
if (!token) {
|
|
33
100
|
throw new Error(
|
|
@@ -63,7 +130,6 @@ async function deploy({
|
|
|
63
130
|
|
|
64
131
|
spinner.text = 'Checking project...';
|
|
65
132
|
let alreadyExists = false;
|
|
66
|
-
|
|
67
133
|
try {
|
|
68
134
|
const statusRes = await fetch(`${api}/api/hosting/status/${name}`, {
|
|
69
135
|
headers: { Authorization: `Bearer ${token}` },
|
|
@@ -72,9 +138,7 @@ async function deploy({
|
|
|
72
138
|
const statusData = await statusRes.json();
|
|
73
139
|
alreadyExists = !!statusData.exists;
|
|
74
140
|
}
|
|
75
|
-
} catch (_) {
|
|
76
|
-
// assume new
|
|
77
|
-
}
|
|
141
|
+
} catch (_) {}
|
|
78
142
|
|
|
79
143
|
spinner.text = `Uploading (${mb} MB)...`;
|
|
80
144
|
|
|
@@ -86,9 +150,9 @@ async function deploy({
|
|
|
86
150
|
});
|
|
87
151
|
form.append('redeploy', alreadyExists ? 'true' : 'false');
|
|
88
152
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
153
|
+
// Always use /deploy — backend queue handle karega
|
|
154
|
+
// (redeploy bhi same endpoint se queue ho sakta hai)
|
|
155
|
+
const endpoint = `${api}/api/hosting/deploy`;
|
|
92
156
|
|
|
93
157
|
const res = await fetch(endpoint, {
|
|
94
158
|
method: 'POST',
|
|
@@ -107,15 +171,47 @@ async function deploy({
|
|
|
107
171
|
data = { error: text };
|
|
108
172
|
}
|
|
109
173
|
|
|
110
|
-
|
|
174
|
+
// ---------- Queued (new flow) ----------
|
|
175
|
+
if (res.status === 202 && data.jobId) {
|
|
176
|
+
spinner.stop();
|
|
177
|
+
console.log(chalk.gray(` Upload done — build starting...`));
|
|
178
|
+
console.log('');
|
|
111
179
|
|
|
180
|
+
const result = await waitForDeployJob({
|
|
181
|
+
apiUrl: api,
|
|
182
|
+
token,
|
|
183
|
+
jobId: data.jobId,
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
const sec = ((Date.now() - t0) / 1000).toFixed(1);
|
|
187
|
+
const url =
|
|
188
|
+
result?.url || data.url || `https://${name}.${domain}`;
|
|
189
|
+
|
|
190
|
+
console.log('');
|
|
191
|
+
console.log(chalk.green(` Production ${url}`));
|
|
192
|
+
if (result?.version || data.deployment?.version) {
|
|
193
|
+
console.log(
|
|
194
|
+
chalk.gray(
|
|
195
|
+
` Version ${result?.version || data.deployment?.version}`
|
|
196
|
+
)
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
console.log(chalk.gray(` Time ${sec}s`));
|
|
200
|
+
console.log(
|
|
201
|
+
chalk.green(alreadyExists || data.redeploy ? '✓ Redeployed' : '✓ Deployed')
|
|
202
|
+
);
|
|
203
|
+
console.log('');
|
|
204
|
+
return result;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// ---------- Old sync success (fallback) ----------
|
|
208
|
+
const sec = ((Date.now() - t0) / 1000).toFixed(1);
|
|
112
209
|
if (!res.ok) {
|
|
113
210
|
spinner.fail(`Failed (${sec}s)`);
|
|
114
211
|
throw new Error(data.error || `HTTP ${res.status}`);
|
|
115
212
|
}
|
|
116
213
|
|
|
117
214
|
spinner.succeed(`Ready in ${sec}s`);
|
|
118
|
-
|
|
119
215
|
const url = data.url || `https://${name}.${domain}`;
|
|
120
216
|
console.log('');
|
|
121
217
|
console.log(chalk.green(` Production ${url}`));
|