moontraze 1.0.4 → 1.0.6
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/bin/moontraze.js +22 -21
- package/lib/auth.js +36 -51
- package/lib/config.js +4 -17
- package/lib/deploy.js +34 -22
- package/lib/zip.js +11 -4
- package/package.json +17 -6
- package/bin/moon.js +0 -68
package/bin/moontraze.js
CHANGED
|
@@ -2,31 +2,37 @@
|
|
|
2
2
|
const { Command } = require('commander');
|
|
3
3
|
const chalk = require('chalk');
|
|
4
4
|
const { login } = require('../lib/auth');
|
|
5
|
-
const { getConfig, getProject, setProject } = require('../lib/config');
|
|
5
|
+
const { getConfig, setConfig, getProject, setProject } = require('../lib/config');
|
|
6
6
|
const { deploy } = require('../lib/deploy');
|
|
7
7
|
|
|
8
8
|
const program = new Command();
|
|
9
9
|
|
|
10
|
+
// Moon CLI se aata hai
|
|
11
|
+
const platformName = process.env.MOON_PLATFORM || 'moontraze';
|
|
12
|
+
const apiUrl = process.env.MOON_API || getConfig().apiUrl || 'https://api.moontraze.com';
|
|
13
|
+
const domain = process.env.MOON_DOMAIN || getConfig().domain || 'moontraze.com';
|
|
14
|
+
|
|
10
15
|
program
|
|
11
|
-
.name(
|
|
12
|
-
.description(
|
|
13
|
-
.version('1.0.
|
|
16
|
+
.name(platformName)
|
|
17
|
+
.description(`Deploy sites using ${platformName}`)
|
|
18
|
+
.version('1.0.5');
|
|
14
19
|
|
|
15
|
-
//
|
|
20
|
+
// login
|
|
16
21
|
program
|
|
17
22
|
.command('login')
|
|
18
23
|
.description('Log in with email/password or token')
|
|
19
|
-
.option('--token <jwt>', 'JWT token (
|
|
24
|
+
.option('--token <jwt>', 'JWT token (skip interactive login)')
|
|
20
25
|
.action(async (opts) => {
|
|
21
26
|
try {
|
|
22
|
-
await login(opts.token);
|
|
27
|
+
await login(opts.token, { apiUrl });
|
|
28
|
+
console.log(chalk.green(`✓ Logged in to ${platformName}`));
|
|
23
29
|
} catch (e) {
|
|
24
30
|
console.error(chalk.red('Login failed:'), e.message);
|
|
25
31
|
process.exit(1);
|
|
26
32
|
}
|
|
27
33
|
});
|
|
28
34
|
|
|
29
|
-
//
|
|
35
|
+
// link
|
|
30
36
|
program
|
|
31
37
|
.command('link [name]')
|
|
32
38
|
.description('Link this folder to a hosting project name')
|
|
@@ -49,22 +55,22 @@ program
|
|
|
49
55
|
if (!projectName) process.exit(1);
|
|
50
56
|
projectName = projectName.toLowerCase().replace(/[^a-z0-9-]/g, '');
|
|
51
57
|
setProject({ projectName });
|
|
52
|
-
const domain = getConfig().domain || 'moontraze.com';
|
|
53
58
|
console.log(chalk.green(`Linked → ${projectName}.${domain}`));
|
|
54
|
-
console.log(
|
|
55
|
-
chalk.gray('(saved .moontraze/project.json — same as .vercel)')
|
|
56
|
-
);
|
|
59
|
+
console.log(chalk.gray('(saved .moontraze/project.json)'));
|
|
57
60
|
} catch (e) {
|
|
58
61
|
console.error(chalk.red(e.message));
|
|
59
62
|
process.exit(1);
|
|
60
63
|
}
|
|
61
64
|
});
|
|
62
65
|
|
|
66
|
+
// deploy
|
|
63
67
|
async function runDeploy(opts) {
|
|
64
68
|
try {
|
|
65
69
|
await deploy({
|
|
66
70
|
prod: !!(opts.prod || opts.production),
|
|
67
71
|
projectName: opts.project || opts.name,
|
|
72
|
+
apiUrl,
|
|
73
|
+
domain,
|
|
68
74
|
});
|
|
69
75
|
} catch (e) {
|
|
70
76
|
console.error(chalk.red('\nDeploy failed:'), e.message);
|
|
@@ -80,7 +86,6 @@ program
|
|
|
80
86
|
.option('-p, --project <name>', 'Project name (or use link)')
|
|
81
87
|
.action(runDeploy);
|
|
82
88
|
|
|
83
|
-
// moon moontraze --prod
|
|
84
89
|
program
|
|
85
90
|
.option('--prod', 'Deploy to production')
|
|
86
91
|
.option('--production', 'Deploy to production')
|
|
@@ -98,14 +103,10 @@ program.addHelpText(
|
|
|
98
103
|
'after',
|
|
99
104
|
`
|
|
100
105
|
Examples:
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
moon moontraze login
|
|
106
|
-
moon moontraze link my-site
|
|
107
|
-
moon moontraze deploy --prod
|
|
108
|
-
moon moontraze --prod
|
|
106
|
+
moon ${platformName} login
|
|
107
|
+
moon ${platformName} link my-site
|
|
108
|
+
moon ${platformName} deploy --prod
|
|
109
|
+
moon ${platformName} --prod
|
|
109
110
|
`
|
|
110
111
|
);
|
|
111
112
|
|
package/lib/auth.js
CHANGED
|
@@ -2,16 +2,24 @@ const prompts = require('prompts');
|
|
|
2
2
|
const chalk = require('chalk');
|
|
3
3
|
const http = require('http');
|
|
4
4
|
const { URL } = require('url');
|
|
5
|
-
const {
|
|
5
|
+
const { getConfig, setConfig } = require('./config');
|
|
6
6
|
|
|
7
|
-
async function login(tokenArg) {
|
|
8
|
-
|
|
7
|
+
async function login(tokenArg, options = {}) {
|
|
8
|
+
const apiUrl =
|
|
9
|
+
options.apiUrl ||
|
|
10
|
+
process.env.MOON_API ||
|
|
11
|
+
getConfig().apiUrl ||
|
|
12
|
+
'https://api.moontraze.com';
|
|
13
|
+
|
|
14
|
+
const label = process.env.MOON_LABEL || process.env.MOON_PLATFORM || 'Moontraze';
|
|
15
|
+
|
|
16
|
+
// --token (hidden power user)
|
|
9
17
|
if (tokenArg && String(tokenArg).trim()) {
|
|
10
|
-
return saveAndValidateToken(String(tokenArg).trim());
|
|
18
|
+
return saveAndValidateToken(String(tokenArg).trim(), { apiUrl, label });
|
|
11
19
|
}
|
|
12
20
|
|
|
13
21
|
console.log('');
|
|
14
|
-
console.log(chalk.cyan(
|
|
22
|
+
console.log(chalk.cyan(`${label} Login`));
|
|
15
23
|
console.log('');
|
|
16
24
|
|
|
17
25
|
const { method } = await prompts({
|
|
@@ -24,25 +32,22 @@ async function login(tokenArg) {
|
|
|
24
32
|
],
|
|
25
33
|
});
|
|
26
34
|
|
|
27
|
-
if (!method)
|
|
28
|
-
throw new Error('Login cancelled');
|
|
29
|
-
}
|
|
35
|
+
if (!method) throw new Error('Login cancelled');
|
|
30
36
|
|
|
31
37
|
if (method === 'email') {
|
|
32
|
-
await loginWithEmail();
|
|
38
|
+
await loginWithEmail({ apiUrl, label });
|
|
33
39
|
} else {
|
|
34
|
-
await loginWithMoonID();
|
|
40
|
+
await loginWithMoonID({ apiUrl, label });
|
|
35
41
|
}
|
|
36
42
|
}
|
|
37
43
|
|
|
38
|
-
async function loginWithEmail() {
|
|
44
|
+
async function loginWithEmail({ apiUrl, label }) {
|
|
39
45
|
const answers = await prompts([
|
|
40
46
|
{
|
|
41
47
|
type: 'text',
|
|
42
48
|
name: 'email',
|
|
43
49
|
message: 'Email',
|
|
44
|
-
validate: (v) =>
|
|
45
|
-
v && v.includes('@') ? true : 'Enter a valid email',
|
|
50
|
+
validate: (v) => (v && v.includes('@') ? true : 'Enter a valid email'),
|
|
46
51
|
},
|
|
47
52
|
{
|
|
48
53
|
type: 'password',
|
|
@@ -56,10 +61,8 @@ async function loginWithEmail() {
|
|
|
56
61
|
throw new Error('Login cancelled');
|
|
57
62
|
}
|
|
58
63
|
|
|
59
|
-
const cfg = getConfig();
|
|
60
64
|
const fetch = require('node-fetch');
|
|
61
|
-
|
|
62
|
-
const res = await fetch(`${cfg.apiUrl}/api/platform/login`, {
|
|
65
|
+
const res = await fetch(`${apiUrl}/api/platform/login`, {
|
|
63
66
|
method: 'POST',
|
|
64
67
|
headers: { 'Content-Type': 'application/json' },
|
|
65
68
|
body: JSON.stringify({
|
|
@@ -70,31 +73,24 @@ async function loginWithEmail() {
|
|
|
70
73
|
|
|
71
74
|
const data = await res.json().catch(() => ({}));
|
|
72
75
|
|
|
73
|
-
if (!res.ok)
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
+
if (!res.ok) throw new Error(data.error || 'Invalid email or password');
|
|
77
|
+
if (!data.token) throw new Error('Login succeeded but no token returned');
|
|
76
78
|
|
|
77
|
-
|
|
78
|
-
throw new Error('Login succeeded but no token returned');
|
|
79
|
-
}
|
|
79
|
+
setConfig({ token: data.token, apiUrl });
|
|
80
80
|
|
|
81
|
-
setConfig({ token: data.token });
|
|
82
81
|
console.log('');
|
|
83
82
|
console.log(chalk.green('✓ Logged in'));
|
|
84
|
-
if (data.user?.email) {
|
|
85
|
-
console.log(chalk.gray(` ${data.user.email}`));
|
|
86
|
-
}
|
|
83
|
+
if (data.user?.email) console.log(chalk.gray(` ${data.user.email}`));
|
|
87
84
|
console.log(chalk.gray(` Config: ~/.moontraze/config.json`));
|
|
88
85
|
console.log('');
|
|
89
86
|
}
|
|
90
87
|
|
|
91
|
-
async function loginWithMoonID() {
|
|
92
|
-
const cfg = getConfig();
|
|
88
|
+
async function loginWithMoonID({ apiUrl, label }) {
|
|
93
89
|
const state = Math.random().toString(36).substring(2, 12);
|
|
94
90
|
const port = 17321 + Math.floor(Math.random() * 100);
|
|
95
91
|
const redirectUri = `http://127.0.0.1:${port}/callback`;
|
|
96
|
-
|
|
97
92
|
const appId = 'com.moonstorage.app';
|
|
93
|
+
|
|
98
94
|
const deepLink =
|
|
99
95
|
`moonid://auth` +
|
|
100
96
|
`?app_id=${encodeURIComponent(appId)}` +
|
|
@@ -107,7 +103,7 @@ async function loginWithMoonID() {
|
|
|
107
103
|
)}`;
|
|
108
104
|
|
|
109
105
|
console.log('');
|
|
110
|
-
console.log(chalk.cyan(
|
|
106
|
+
console.log(chalk.cyan(`${label} — MoonID Login`));
|
|
111
107
|
console.log(chalk.gray('1. Open MoonID app on your phone'));
|
|
112
108
|
console.log(chalk.gray('2. Scan the QR code (open link below in browser)'));
|
|
113
109
|
console.log(chalk.gray('3. Approve login'));
|
|
@@ -115,28 +111,20 @@ async function loginWithMoonID() {
|
|
|
115
111
|
console.log(chalk.yellow('QR code image:'));
|
|
116
112
|
console.log(chalk.underline(qrImageUrl));
|
|
117
113
|
console.log('');
|
|
118
|
-
console.log(chalk.gray('Deep link (if needed):'));
|
|
119
|
-
console.log(chalk.gray(deepLink));
|
|
120
|
-
console.log('');
|
|
121
114
|
console.log(chalk.gray('Waiting for approval... (Ctrl+C to cancel)'));
|
|
122
115
|
console.log('');
|
|
123
116
|
|
|
124
|
-
// Local server — MoonID redirect yahan aayega
|
|
125
117
|
const token = await waitForMoonIDCallback({ port, state, timeoutMs: 120000 });
|
|
118
|
+
if (!token) throw new Error('MoonID login timed out or denied');
|
|
126
119
|
|
|
127
|
-
|
|
128
|
-
throw new Error('MoonID login timed out or denied');
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
await saveAndValidateToken(token);
|
|
120
|
+
await saveAndValidateToken(token, { apiUrl, label });
|
|
132
121
|
}
|
|
133
122
|
|
|
134
123
|
function waitForMoonIDCallback({ port, state, timeoutMs }) {
|
|
135
|
-
return new Promise((resolve
|
|
124
|
+
return new Promise((resolve) => {
|
|
136
125
|
const server = http.createServer((req, res) => {
|
|
137
126
|
try {
|
|
138
127
|
const u = new URL(req.url, `http://127.0.0.1:${port}`);
|
|
139
|
-
|
|
140
128
|
if (u.pathname !== '/callback') {
|
|
141
129
|
res.writeHead(404);
|
|
142
130
|
res.end('Not found');
|
|
@@ -169,41 +157,37 @@ function waitForMoonIDCallback({ port, state, timeoutMs }) {
|
|
|
169
157
|
if (!token) {
|
|
170
158
|
res.writeHead(400, { 'Content-Type': 'text/html' });
|
|
171
159
|
res.end(
|
|
172
|
-
'<html><body style="font-family:sans-serif;text-align:center;padding:40px"><h2>No token received</h2
|
|
160
|
+
'<html><body style="font-family:sans-serif;text-align:center;padding:40px"><h2>No token received</h2></body></html>'
|
|
173
161
|
);
|
|
174
162
|
return;
|
|
175
163
|
}
|
|
176
164
|
|
|
177
165
|
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
178
166
|
res.end(
|
|
179
|
-
'<html><body style="font-family:sans-serif;text-align:center;padding:40px"><h2>✓ Login successful</h2><p>You can close this tab
|
|
167
|
+
'<html><body style="font-family:sans-serif;text-align:center;padding:40px"><h2>✓ Login successful</h2><p>You can close this tab.</p></body></html>'
|
|
180
168
|
);
|
|
181
169
|
server.close();
|
|
182
170
|
resolve(token);
|
|
183
|
-
} catch
|
|
171
|
+
} catch {
|
|
184
172
|
res.writeHead(500);
|
|
185
173
|
res.end('Error');
|
|
186
174
|
}
|
|
187
175
|
});
|
|
188
176
|
|
|
189
177
|
server.listen(port, '127.0.0.1');
|
|
190
|
-
|
|
191
178
|
const timer = setTimeout(() => {
|
|
192
179
|
try {
|
|
193
180
|
server.close();
|
|
194
181
|
} catch (_) {}
|
|
195
182
|
resolve(null);
|
|
196
183
|
}, timeoutMs);
|
|
197
|
-
|
|
198
184
|
server.on('close', () => clearTimeout(timer));
|
|
199
185
|
});
|
|
200
186
|
}
|
|
201
187
|
|
|
202
|
-
async function saveAndValidateToken(token) {
|
|
203
|
-
const cfg = getConfig();
|
|
188
|
+
async function saveAndValidateToken(token, { apiUrl, label }) {
|
|
204
189
|
const fetch = require('node-fetch');
|
|
205
|
-
|
|
206
|
-
const res = await fetch(`${cfg.apiUrl}/api/hosting/quota`, {
|
|
190
|
+
const res = await fetch(`${apiUrl}/api/hosting/quota`, {
|
|
207
191
|
headers: { Authorization: `Bearer ${token}` },
|
|
208
192
|
});
|
|
209
193
|
|
|
@@ -211,7 +195,8 @@ async function saveAndValidateToken(token) {
|
|
|
211
195
|
throw new Error('Invalid or expired token');
|
|
212
196
|
}
|
|
213
197
|
|
|
214
|
-
setConfig({ token });
|
|
198
|
+
setConfig({ token, apiUrl });
|
|
199
|
+
|
|
215
200
|
console.log('');
|
|
216
201
|
console.log(chalk.green('✓ Logged in'));
|
|
217
202
|
console.log(chalk.gray(` Config: ~/.moontraze/config.json`));
|
package/lib/config.js
CHANGED
|
@@ -13,27 +13,14 @@ function ensureDir(d) {
|
|
|
13
13
|
|
|
14
14
|
const DEFAULTS = {
|
|
15
15
|
token: null,
|
|
16
|
-
apiUrl: process.env.
|
|
17
|
-
domain: process.env.
|
|
16
|
+
apiUrl: process.env.MOON_API || 'https://api.moontraze.com',
|
|
17
|
+
domain: process.env.MOON_DOMAIN || 'moontraze.com',
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
-
function migrate(cfg) {
|
|
21
|
-
const next = { ...DEFAULTS, ...cfg };
|
|
22
|
-
// old frelanceo → moontraze
|
|
23
|
-
if (next.apiUrl && String(next.apiUrl).includes('frelanceo')) {
|
|
24
|
-
next.apiUrl = DEFAULTS.apiUrl;
|
|
25
|
-
}
|
|
26
|
-
if (next.domain && String(next.domain).includes('frelanceo')) {
|
|
27
|
-
next.domain = DEFAULTS.domain;
|
|
28
|
-
}
|
|
29
|
-
return next;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
20
|
function getConfig() {
|
|
33
21
|
try {
|
|
34
22
|
if (fs.existsSync(GLOBAL_FILE)) {
|
|
35
|
-
|
|
36
|
-
return migrate(saved);
|
|
23
|
+
return { ...DEFAULTS, ...JSON.parse(fs.readFileSync(GLOBAL_FILE, 'utf8')) };
|
|
37
24
|
}
|
|
38
25
|
} catch (_) {}
|
|
39
26
|
return { ...DEFAULTS };
|
|
@@ -41,7 +28,7 @@ function getConfig() {
|
|
|
41
28
|
|
|
42
29
|
function setConfig(partial) {
|
|
43
30
|
ensureDir(GLOBAL_DIR);
|
|
44
|
-
const next =
|
|
31
|
+
const next = { ...getConfig(), ...partial };
|
|
45
32
|
fs.writeFileSync(GLOBAL_FILE, JSON.stringify(next, null, 2));
|
|
46
33
|
return next;
|
|
47
34
|
}
|
package/lib/deploy.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
2
|
const fetch = require('node-fetch');
|
|
4
3
|
const FormData = require('form-data');
|
|
5
4
|
const ora = require('ora');
|
|
@@ -7,11 +6,32 @@ const chalk = require('chalk');
|
|
|
7
6
|
const { getConfig, getProject } = require('./config');
|
|
8
7
|
const { zipCwd } = require('./zip');
|
|
9
8
|
|
|
10
|
-
async function deploy({
|
|
9
|
+
async function deploy({
|
|
10
|
+
prod = true,
|
|
11
|
+
projectName,
|
|
12
|
+
apiUrl: apiUrlArg,
|
|
13
|
+
domain: domainArg,
|
|
14
|
+
} = {}) {
|
|
11
15
|
const cfg = getConfig();
|
|
12
|
-
|
|
16
|
+
|
|
17
|
+
const api =
|
|
18
|
+
apiUrlArg ||
|
|
19
|
+
process.env.MOON_API ||
|
|
20
|
+
cfg.apiUrl ||
|
|
21
|
+
'https://api.moontraze.com';
|
|
22
|
+
|
|
23
|
+
const domain =
|
|
24
|
+
domainArg ||
|
|
25
|
+
process.env.MOON_DOMAIN ||
|
|
26
|
+
cfg.domain ||
|
|
27
|
+
'moontraze.com';
|
|
28
|
+
|
|
29
|
+
const token = cfg.token || process.env.MOON_TOKEN || null;
|
|
30
|
+
const label = process.env.MOON_LABEL || process.env.MOON_PLATFORM || 'Moontraze';
|
|
31
|
+
|
|
32
|
+
if (!token) {
|
|
13
33
|
throw new Error(
|
|
14
|
-
'Not logged in. Run: moon moontraze login
|
|
34
|
+
'Not logged in. Run: moon moontraze login\n or: npx moontraze login'
|
|
15
35
|
);
|
|
16
36
|
}
|
|
17
37
|
|
|
@@ -19,18 +39,16 @@ async function deploy({ prod = true, projectName } = {}) {
|
|
|
19
39
|
const name = (projectName || linked?.projectName || '')
|
|
20
40
|
.toLowerCase()
|
|
21
41
|
.replace(/[^a-z0-9-]/g, '');
|
|
42
|
+
|
|
22
43
|
if (!name || name.length < 3) {
|
|
23
44
|
throw new Error(
|
|
24
|
-
'No project linked. Run: moon moontraze link my-site
|
|
45
|
+
'No project linked. Run: moon moontraze link my-site\n or: npx moontraze link my-site'
|
|
25
46
|
);
|
|
26
47
|
}
|
|
27
48
|
|
|
28
|
-
const domain = cfg.domain || 'moontraze.com';
|
|
29
|
-
const api = cfg.apiUrl || 'https://api.moontraze.com';
|
|
30
|
-
|
|
31
49
|
console.log('');
|
|
32
|
-
console.log(chalk.cyan(
|
|
33
|
-
console.log(`
|
|
50
|
+
console.log(chalk.cyan(label));
|
|
51
|
+
console.log(` API ${api}`);
|
|
34
52
|
console.log(` Project ${name}`);
|
|
35
53
|
console.log(` Target https://${name}.${domain}`);
|
|
36
54
|
console.log('');
|
|
@@ -45,9 +63,10 @@ async function deploy({ prod = true, projectName } = {}) {
|
|
|
45
63
|
|
|
46
64
|
spinner.text = 'Checking project...';
|
|
47
65
|
let alreadyExists = false;
|
|
66
|
+
|
|
48
67
|
try {
|
|
49
68
|
const statusRes = await fetch(`${api}/api/hosting/status/${name}`, {
|
|
50
|
-
headers: { Authorization: `Bearer ${
|
|
69
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
51
70
|
});
|
|
52
71
|
if (statusRes.ok) {
|
|
53
72
|
const statusData = await statusRes.json();
|
|
@@ -65,22 +84,16 @@ async function deploy({ prod = true, projectName } = {}) {
|
|
|
65
84
|
filename: `${name}.zip`,
|
|
66
85
|
contentType: 'application/zip',
|
|
67
86
|
});
|
|
87
|
+
form.append('redeploy', alreadyExists ? 'true' : 'false');
|
|
68
88
|
|
|
69
|
-
// existing → redeploy; new → deploy
|
|
70
89
|
const endpoint = alreadyExists
|
|
71
90
|
? `${api}/api/hosting/redeploy`
|
|
72
91
|
: `${api}/api/hosting/deploy`;
|
|
73
92
|
|
|
74
|
-
if (alreadyExists) {
|
|
75
|
-
form.append('redeploy', 'true');
|
|
76
|
-
} else {
|
|
77
|
-
form.append('redeploy', 'false');
|
|
78
|
-
}
|
|
79
|
-
|
|
80
93
|
const res = await fetch(endpoint, {
|
|
81
94
|
method: 'POST',
|
|
82
95
|
headers: {
|
|
83
|
-
Authorization: `Bearer ${
|
|
96
|
+
Authorization: `Bearer ${token}`,
|
|
84
97
|
...form.getHeaders(),
|
|
85
98
|
},
|
|
86
99
|
body: form,
|
|
@@ -102,15 +115,14 @@ async function deploy({ prod = true, projectName } = {}) {
|
|
|
102
115
|
}
|
|
103
116
|
|
|
104
117
|
spinner.succeed(`Ready in ${sec}s`);
|
|
118
|
+
|
|
105
119
|
const url = data.url || `https://${name}.${domain}`;
|
|
106
120
|
console.log('');
|
|
107
121
|
console.log(chalk.green(` Production ${url}`));
|
|
108
122
|
if (data.deployment?.version) {
|
|
109
123
|
console.log(chalk.gray(` Version ${data.deployment.version}`));
|
|
110
124
|
}
|
|
111
|
-
console.log(
|
|
112
|
-
chalk.green(alreadyExists ? '✓ Redeployed' : '✓ Deployed')
|
|
113
|
-
);
|
|
125
|
+
console.log(chalk.green(alreadyExists ? '✓ Redeployed' : '✓ Deployed'));
|
|
114
126
|
console.log('');
|
|
115
127
|
} finally {
|
|
116
128
|
if (zipPath && fs.existsSync(zipPath)) {
|
package/lib/zip.js
CHANGED
|
@@ -11,7 +11,8 @@ const SKIP = new Set([
|
|
|
11
11
|
'build',
|
|
12
12
|
'out',
|
|
13
13
|
'.vercel',
|
|
14
|
-
'.
|
|
14
|
+
'.moon',
|
|
15
|
+
'.moontraze', // purana bhi skip
|
|
15
16
|
'.netlify',
|
|
16
17
|
'coverage',
|
|
17
18
|
]);
|
|
@@ -25,8 +26,9 @@ function zipCwd() {
|
|
|
25
26
|
return new Promise((resolve, reject) => {
|
|
26
27
|
const outPath = path.join(
|
|
27
28
|
os.tmpdir(),
|
|
28
|
-
`
|
|
29
|
+
`moon-${Date.now()}.zip`
|
|
29
30
|
);
|
|
31
|
+
|
|
30
32
|
const output = fs.createWriteStream(outPath);
|
|
31
33
|
const archive = archiver('zip', { zlib: { level: 9 } });
|
|
32
34
|
|
|
@@ -38,10 +40,15 @@ function zipCwd() {
|
|
|
38
40
|
for (const name of fs.readdirSync(dir)) {
|
|
39
41
|
const full = path.join(dir, name);
|
|
40
42
|
const rel = base ? path.join(base, name) : name;
|
|
43
|
+
|
|
41
44
|
if (shouldSkip(rel)) continue;
|
|
45
|
+
|
|
42
46
|
const st = fs.statSync(full);
|
|
43
|
-
if (st.isDirectory())
|
|
44
|
-
|
|
47
|
+
if (st.isDirectory()) {
|
|
48
|
+
walk(full, rel);
|
|
49
|
+
} else {
|
|
50
|
+
archive.file(full, { name: rel.replace(/\\/g, '/') });
|
|
51
|
+
}
|
|
45
52
|
}
|
|
46
53
|
};
|
|
47
54
|
|
package/package.json
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "moontraze",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "Deploy to Moontraze hosting — like vercel CLI",
|
|
5
5
|
"bin": {
|
|
6
|
-
"
|
|
7
|
-
"
|
|
6
|
+
"moon": "./bin/moon.js",
|
|
7
|
+
"moontraze": "./bin/moontraze.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"lib"
|
|
12
|
+
],
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=18"
|
|
8
15
|
},
|
|
9
|
-
"files": ["bin", "lib"],
|
|
10
|
-
"engines": { "node": ">=18" },
|
|
11
16
|
"dependencies": {
|
|
12
17
|
"archiver": "^7.0.1",
|
|
13
18
|
"commander": "^12.1.0",
|
|
@@ -17,6 +22,12 @@
|
|
|
17
22
|
"chalk": "^4.1.2",
|
|
18
23
|
"prompts": "^2.4.2"
|
|
19
24
|
},
|
|
20
|
-
"keywords": [
|
|
25
|
+
"keywords": [
|
|
26
|
+
"moontraze",
|
|
27
|
+
"deploy",
|
|
28
|
+
"hosting",
|
|
29
|
+
"moon",
|
|
30
|
+
"cli"
|
|
31
|
+
],
|
|
21
32
|
"license": "MIT"
|
|
22
33
|
}
|
package/bin/moon.js
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* moon <platform> <command>
|
|
4
|
-
* Example: moon moontraze login
|
|
5
|
-
* moon moontraze deploy --prod
|
|
6
|
-
*/
|
|
7
|
-
const chalk = require('chalk');
|
|
8
|
-
const path = require('path');
|
|
9
|
-
|
|
10
|
-
const PLATFORMS = {
|
|
11
|
-
moontraze: {
|
|
12
|
-
label: 'Moontraze',
|
|
13
|
-
runner: path.join(__dirname, 'moontraze.js'),
|
|
14
|
-
},
|
|
15
|
-
// future:
|
|
16
|
-
// otherapp: { label: 'Other', runner: path.join(__dirname, 'other.js') },
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
function printRootHelp() {
|
|
20
|
-
console.log(`
|
|
21
|
-
${chalk.bold('moon')} — multi-platform CLI
|
|
22
|
-
|
|
23
|
-
Usage:
|
|
24
|
-
moon <platform> <command>
|
|
25
|
-
|
|
26
|
-
Platforms:
|
|
27
|
-
moontraze Moontraze hosting (moontraze.com)
|
|
28
|
-
|
|
29
|
-
Examples:
|
|
30
|
-
moon moontraze login
|
|
31
|
-
moon moontraze link my-site
|
|
32
|
-
moon moontraze deploy --prod
|
|
33
|
-
moon moontraze --prod
|
|
34
|
-
|
|
35
|
-
Same as:
|
|
36
|
-
npx moontraze login
|
|
37
|
-
npx moontraze deploy --prod
|
|
38
|
-
`);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const args = process.argv.slice(2);
|
|
42
|
-
const platform = (args[0] || '').toLowerCase();
|
|
43
|
-
|
|
44
|
-
if (!platform || platform === '-h' || platform === '--help' || platform === 'help') {
|
|
45
|
-
printRootHelp();
|
|
46
|
-
process.exit(0);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (platform === '-v' || platform === '--version') {
|
|
50
|
-
try {
|
|
51
|
-
console.log(require('../package.json').version);
|
|
52
|
-
} catch {
|
|
53
|
-
console.log('0.0.0');
|
|
54
|
-
}
|
|
55
|
-
process.exit(0);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const meta = PLATFORMS[platform];
|
|
59
|
-
if (!meta) {
|
|
60
|
-
console.error(chalk.red(`Unknown platform: "${platform}"`));
|
|
61
|
-
console.error(chalk.gray('Known: ' + Object.keys(PLATFORMS).join(', ')));
|
|
62
|
-
console.error(chalk.gray('Example: moon moontraze login'));
|
|
63
|
-
process.exit(1);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Forward remaining args to platform CLI
|
|
67
|
-
process.argv = [process.argv[0], meta.runner, ...args.slice(1)];
|
|
68
|
-
require(meta.runner);
|