moontraze 1.0.5 → 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 +16 -37
- package/lib/auth.js +30 -53
- package/lib/config.js +11 -89
- package/lib/deploy.js +11 -20
- package/package.json +17 -6
- package/bin/moon.js +0 -172
package/bin/moontraze.js
CHANGED
|
@@ -2,52 +2,37 @@
|
|
|
2
2
|
const { Command } = require('commander');
|
|
3
3
|
const chalk = require('chalk');
|
|
4
4
|
const { login } = require('../lib/auth');
|
|
5
|
-
const {
|
|
6
|
-
getConfig,
|
|
7
|
-
getPlatform,
|
|
8
|
-
getProject,
|
|
9
|
-
setProject,
|
|
10
|
-
setPlatformToken,
|
|
11
|
-
} = require('../lib/config');
|
|
5
|
+
const { getConfig, setConfig, getProject, setProject } = require('../lib/config');
|
|
12
6
|
const { deploy } = require('../lib/deploy');
|
|
13
7
|
|
|
14
8
|
const program = new Command();
|
|
15
9
|
|
|
16
|
-
//
|
|
17
|
-
const platformName = process.env.
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
const apiUrl = process.env.MOON_API || platform?.apiUrl || 'https://api.moontraze.com';
|
|
21
|
-
const domain = process.env.MOON_DOMAIN || platform?.domain || 'moontraze.com';
|
|
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';
|
|
22
14
|
|
|
23
15
|
program
|
|
24
16
|
.name(platformName)
|
|
25
|
-
.description(`Deploy sites using ${
|
|
26
|
-
.version('1.0.
|
|
17
|
+
.description(`Deploy sites using ${platformName}`)
|
|
18
|
+
.version('1.0.5');
|
|
27
19
|
|
|
28
|
-
//
|
|
20
|
+
// login
|
|
29
21
|
program
|
|
30
22
|
.command('login')
|
|
31
23
|
.description('Log in with email/password or token')
|
|
32
|
-
.option('--token <jwt>', 'JWT token (
|
|
24
|
+
.option('--token <jwt>', 'JWT token (skip interactive login)')
|
|
33
25
|
.action(async (opts) => {
|
|
34
26
|
try {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
// token us platform ke under save karo
|
|
39
|
-
if (token) {
|
|
40
|
-
setPlatformToken(platformName, token);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
console.log(chalk.green(`✓ Logged in to ${platform?.label || platformName}`));
|
|
27
|
+
await login(opts.token, { apiUrl });
|
|
28
|
+
console.log(chalk.green(`✓ Logged in to ${platformName}`));
|
|
44
29
|
} catch (e) {
|
|
45
30
|
console.error(chalk.red('Login failed:'), e.message);
|
|
46
31
|
process.exit(1);
|
|
47
32
|
}
|
|
48
33
|
});
|
|
49
34
|
|
|
50
|
-
//
|
|
35
|
+
// link
|
|
51
36
|
program
|
|
52
37
|
.command('link [name]')
|
|
53
38
|
.description('Link this folder to a hosting project name')
|
|
@@ -55,7 +40,6 @@ program
|
|
|
55
40
|
try {
|
|
56
41
|
const prompts = require('prompts');
|
|
57
42
|
let projectName = name;
|
|
58
|
-
|
|
59
43
|
if (!projectName) {
|
|
60
44
|
const a = await prompts({
|
|
61
45
|
type: 'text',
|
|
@@ -68,28 +52,24 @@ program
|
|
|
68
52
|
});
|
|
69
53
|
projectName = a.n;
|
|
70
54
|
}
|
|
71
|
-
|
|
72
55
|
if (!projectName) process.exit(1);
|
|
73
|
-
|
|
74
56
|
projectName = projectName.toLowerCase().replace(/[^a-z0-9-]/g, '');
|
|
75
|
-
setProject({ projectName
|
|
76
|
-
|
|
57
|
+
setProject({ projectName });
|
|
77
58
|
console.log(chalk.green(`Linked → ${projectName}.${domain}`));
|
|
78
|
-
console.log(chalk.gray('(saved .
|
|
59
|
+
console.log(chalk.gray('(saved .moontraze/project.json)'));
|
|
79
60
|
} catch (e) {
|
|
80
61
|
console.error(chalk.red(e.message));
|
|
81
62
|
process.exit(1);
|
|
82
63
|
}
|
|
83
64
|
});
|
|
84
65
|
|
|
85
|
-
//
|
|
66
|
+
// deploy
|
|
86
67
|
async function runDeploy(opts) {
|
|
87
68
|
try {
|
|
88
69
|
await deploy({
|
|
89
70
|
prod: !!(opts.prod || opts.production),
|
|
90
71
|
projectName: opts.project || opts.name,
|
|
91
|
-
apiUrl,
|
|
92
|
-
platformName,
|
|
72
|
+
apiUrl,
|
|
93
73
|
domain,
|
|
94
74
|
});
|
|
95
75
|
} catch (e) {
|
|
@@ -106,7 +86,6 @@ program
|
|
|
106
86
|
.option('-p, --project <name>', 'Project name (or use link)')
|
|
107
87
|
.action(runDeploy);
|
|
108
88
|
|
|
109
|
-
// Direct flags: moon moontraze --prod
|
|
110
89
|
program
|
|
111
90
|
.option('--prod', 'Deploy to production')
|
|
112
91
|
.option('--production', 'Deploy to production')
|
package/lib/auth.js
CHANGED
|
@@ -2,25 +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 {
|
|
6
|
-
getConfig,
|
|
7
|
-
getPlatform,
|
|
8
|
-
setPlatformToken,
|
|
9
|
-
setConfig,
|
|
10
|
-
} = require('./config');
|
|
5
|
+
const { getConfig, setConfig } = require('./config');
|
|
11
6
|
|
|
12
7
|
async function login(tokenArg, options = {}) {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
const apiUrl =
|
|
9
|
+
options.apiUrl ||
|
|
10
|
+
process.env.MOON_API ||
|
|
11
|
+
getConfig().apiUrl ||
|
|
12
|
+
'https://api.moontraze.com';
|
|
16
13
|
|
|
17
|
-
|
|
14
|
+
const label = process.env.MOON_LABEL || process.env.MOON_PLATFORM || 'Moontraze';
|
|
15
|
+
|
|
16
|
+
// --token (hidden power user)
|
|
18
17
|
if (tokenArg && String(tokenArg).trim()) {
|
|
19
|
-
return saveAndValidateToken(String(tokenArg).trim(), { apiUrl,
|
|
18
|
+
return saveAndValidateToken(String(tokenArg).trim(), { apiUrl, label });
|
|
20
19
|
}
|
|
21
20
|
|
|
22
21
|
console.log('');
|
|
23
|
-
console.log(chalk.cyan(`${
|
|
22
|
+
console.log(chalk.cyan(`${label} Login`));
|
|
24
23
|
console.log('');
|
|
25
24
|
|
|
26
25
|
const { method } = await prompts({
|
|
@@ -33,18 +32,16 @@ async function login(tokenArg, options = {}) {
|
|
|
33
32
|
],
|
|
34
33
|
});
|
|
35
34
|
|
|
36
|
-
if (!method)
|
|
37
|
-
throw new Error('Login cancelled');
|
|
38
|
-
}
|
|
35
|
+
if (!method) throw new Error('Login cancelled');
|
|
39
36
|
|
|
40
37
|
if (method === 'email') {
|
|
41
|
-
await loginWithEmail({ apiUrl,
|
|
38
|
+
await loginWithEmail({ apiUrl, label });
|
|
42
39
|
} else {
|
|
43
|
-
await loginWithMoonID({ apiUrl,
|
|
40
|
+
await loginWithMoonID({ apiUrl, label });
|
|
44
41
|
}
|
|
45
42
|
}
|
|
46
43
|
|
|
47
|
-
async function loginWithEmail({ apiUrl,
|
|
44
|
+
async function loginWithEmail({ apiUrl, label }) {
|
|
48
45
|
const answers = await prompts([
|
|
49
46
|
{
|
|
50
47
|
type: 'text',
|
|
@@ -76,27 +73,19 @@ async function loginWithEmail({ apiUrl, platformName, platform }) {
|
|
|
76
73
|
|
|
77
74
|
const data = await res.json().catch(() => ({}));
|
|
78
75
|
|
|
79
|
-
if (!res.ok)
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
if (!data.token) {
|
|
83
|
-
throw new Error('Login succeeded but no token returned');
|
|
84
|
-
}
|
|
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');
|
|
85
78
|
|
|
86
|
-
|
|
87
|
-
setPlatformToken(platformName, data.token);
|
|
79
|
+
setConfig({ token: data.token, apiUrl });
|
|
88
80
|
|
|
89
81
|
console.log('');
|
|
90
82
|
console.log(chalk.green('✓ Logged in'));
|
|
91
|
-
if (data.user?.email) {
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
console.log(chalk.gray(` Platform: ${platformName}`));
|
|
95
|
-
console.log(chalk.gray(` Config: ~/.moon/config.json`));
|
|
83
|
+
if (data.user?.email) console.log(chalk.gray(` ${data.user.email}`));
|
|
84
|
+
console.log(chalk.gray(` Config: ~/.moontraze/config.json`));
|
|
96
85
|
console.log('');
|
|
97
86
|
}
|
|
98
87
|
|
|
99
|
-
async function loginWithMoonID({ apiUrl,
|
|
88
|
+
async function loginWithMoonID({ apiUrl, label }) {
|
|
100
89
|
const state = Math.random().toString(36).substring(2, 12);
|
|
101
90
|
const port = 17321 + Math.floor(Math.random() * 100);
|
|
102
91
|
const redirectUri = `http://127.0.0.1:${port}/callback`;
|
|
@@ -114,7 +103,7 @@ async function loginWithMoonID({ apiUrl, platformName, platform }) {
|
|
|
114
103
|
)}`;
|
|
115
104
|
|
|
116
105
|
console.log('');
|
|
117
|
-
console.log(chalk.cyan(`${
|
|
106
|
+
console.log(chalk.cyan(`${label} — MoonID Login`));
|
|
118
107
|
console.log(chalk.gray('1. Open MoonID app on your phone'));
|
|
119
108
|
console.log(chalk.gray('2. Scan the QR code (open link below in browser)'));
|
|
120
109
|
console.log(chalk.gray('3. Approve login'));
|
|
@@ -122,19 +111,13 @@ async function loginWithMoonID({ apiUrl, platformName, platform }) {
|
|
|
122
111
|
console.log(chalk.yellow('QR code image:'));
|
|
123
112
|
console.log(chalk.underline(qrImageUrl));
|
|
124
113
|
console.log('');
|
|
125
|
-
console.log(chalk.gray('Deep link (if needed):'));
|
|
126
|
-
console.log(chalk.gray(deepLink));
|
|
127
|
-
console.log('');
|
|
128
114
|
console.log(chalk.gray('Waiting for approval... (Ctrl+C to cancel)'));
|
|
129
115
|
console.log('');
|
|
130
116
|
|
|
131
117
|
const token = await waitForMoonIDCallback({ port, state, timeoutMs: 120000 });
|
|
118
|
+
if (!token) throw new Error('MoonID login timed out or denied');
|
|
132
119
|
|
|
133
|
-
|
|
134
|
-
throw new Error('MoonID login timed out or denied');
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
await saveAndValidateToken(token, { apiUrl, platformName });
|
|
120
|
+
await saveAndValidateToken(token, { apiUrl, label });
|
|
138
121
|
}
|
|
139
122
|
|
|
140
123
|
function waitForMoonIDCallback({ port, state, timeoutMs }) {
|
|
@@ -142,7 +125,6 @@ function waitForMoonIDCallback({ port, state, timeoutMs }) {
|
|
|
142
125
|
const server = http.createServer((req, res) => {
|
|
143
126
|
try {
|
|
144
127
|
const u = new URL(req.url, `http://127.0.0.1:${port}`);
|
|
145
|
-
|
|
146
128
|
if (u.pathname !== '/callback') {
|
|
147
129
|
res.writeHead(404);
|
|
148
130
|
res.end('Not found');
|
|
@@ -175,39 +157,36 @@ function waitForMoonIDCallback({ port, state, timeoutMs }) {
|
|
|
175
157
|
if (!token) {
|
|
176
158
|
res.writeHead(400, { 'Content-Type': 'text/html' });
|
|
177
159
|
res.end(
|
|
178
|
-
'<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>'
|
|
179
161
|
);
|
|
180
162
|
return;
|
|
181
163
|
}
|
|
182
164
|
|
|
183
165
|
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
184
166
|
res.end(
|
|
185
|
-
'<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>'
|
|
186
168
|
);
|
|
187
169
|
server.close();
|
|
188
170
|
resolve(token);
|
|
189
|
-
} catch
|
|
171
|
+
} catch {
|
|
190
172
|
res.writeHead(500);
|
|
191
173
|
res.end('Error');
|
|
192
174
|
}
|
|
193
175
|
});
|
|
194
176
|
|
|
195
177
|
server.listen(port, '127.0.0.1');
|
|
196
|
-
|
|
197
178
|
const timer = setTimeout(() => {
|
|
198
179
|
try {
|
|
199
180
|
server.close();
|
|
200
181
|
} catch (_) {}
|
|
201
182
|
resolve(null);
|
|
202
183
|
}, timeoutMs);
|
|
203
|
-
|
|
204
184
|
server.on('close', () => clearTimeout(timer));
|
|
205
185
|
});
|
|
206
186
|
}
|
|
207
187
|
|
|
208
|
-
async function saveAndValidateToken(token, { apiUrl,
|
|
188
|
+
async function saveAndValidateToken(token, { apiUrl, label }) {
|
|
209
189
|
const fetch = require('node-fetch');
|
|
210
|
-
|
|
211
190
|
const res = await fetch(`${apiUrl}/api/hosting/quota`, {
|
|
212
191
|
headers: { Authorization: `Bearer ${token}` },
|
|
213
192
|
});
|
|
@@ -216,13 +195,11 @@ async function saveAndValidateToken(token, { apiUrl, platformName }) {
|
|
|
216
195
|
throw new Error('Invalid or expired token');
|
|
217
196
|
}
|
|
218
197
|
|
|
219
|
-
|
|
220
|
-
setPlatformToken(platformName, token);
|
|
198
|
+
setConfig({ token, apiUrl });
|
|
221
199
|
|
|
222
200
|
console.log('');
|
|
223
201
|
console.log(chalk.green('✓ Logged in'));
|
|
224
|
-
console.log(chalk.gray(`
|
|
225
|
-
console.log(chalk.gray(` Config: ~/.moon/config.json`));
|
|
202
|
+
console.log(chalk.gray(` Config: ~/.moontraze/config.json`));
|
|
226
203
|
console.log('');
|
|
227
204
|
}
|
|
228
205
|
|
package/lib/config.js
CHANGED
|
@@ -2,9 +2,9 @@ const fs = require('fs');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const os = require('os');
|
|
4
4
|
|
|
5
|
-
const GLOBAL_DIR = path.join(os.homedir(), '.
|
|
5
|
+
const GLOBAL_DIR = path.join(os.homedir(), '.moontraze');
|
|
6
6
|
const GLOBAL_FILE = path.join(GLOBAL_DIR, 'config.json');
|
|
7
|
-
const LOCAL_DIR = path.join(process.cwd(), '.
|
|
7
|
+
const LOCAL_DIR = path.join(process.cwd(), '.moontraze');
|
|
8
8
|
const LOCAL_FILE = path.join(LOCAL_DIR, 'project.json');
|
|
9
9
|
|
|
10
10
|
function ensureDir(d) {
|
|
@@ -12,93 +12,27 @@ function ensureDir(d) {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
const DEFAULTS = {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
label: 'Moontraze',
|
|
19
|
-
apiUrl: process.env.MOON_API || 'https://api.moontraze.com',
|
|
20
|
-
domain: process.env.MOON_DOMAIN || 'moontraze.com',
|
|
21
|
-
},
|
|
22
|
-
},
|
|
15
|
+
token: null,
|
|
16
|
+
apiUrl: process.env.MOON_API || 'https://api.moontraze.com',
|
|
17
|
+
domain: process.env.MOON_DOMAIN || 'moontraze.com',
|
|
23
18
|
};
|
|
24
19
|
|
|
25
|
-
function migrate(cfg) {
|
|
26
|
-
// old .moontraze → new structure support
|
|
27
|
-
if (cfg.apiUrl && !cfg.platforms) {
|
|
28
|
-
return {
|
|
29
|
-
defaultPlatform: 'moontraze',
|
|
30
|
-
platforms: {
|
|
31
|
-
moontraze: {
|
|
32
|
-
label: 'Moontraze',
|
|
33
|
-
apiUrl: cfg.apiUrl.includes('frelanceo')
|
|
34
|
-
? 'https://api.moontraze.com'
|
|
35
|
-
: cfg.apiUrl,
|
|
36
|
-
domain: cfg.domain?.includes('frelanceo')
|
|
37
|
-
? 'moontraze.com'
|
|
38
|
-
: cfg.domain || 'moontraze.com',
|
|
39
|
-
token: cfg.token || null,
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
return { ...DEFAULTS, ...cfg };
|
|
45
|
-
}
|
|
46
|
-
|
|
47
20
|
function getConfig() {
|
|
48
21
|
try {
|
|
49
22
|
if (fs.existsSync(GLOBAL_FILE)) {
|
|
50
|
-
|
|
51
|
-
return migrate(saved);
|
|
23
|
+
return { ...DEFAULTS, ...JSON.parse(fs.readFileSync(GLOBAL_FILE, 'utf8')) };
|
|
52
24
|
}
|
|
53
25
|
} catch (_) {}
|
|
54
|
-
return
|
|
26
|
+
return { ...DEFAULTS };
|
|
55
27
|
}
|
|
56
28
|
|
|
57
29
|
function setConfig(partial) {
|
|
58
30
|
ensureDir(GLOBAL_DIR);
|
|
59
|
-
const
|
|
60
|
-
const next = { ...current, ...partial };
|
|
31
|
+
const next = { ...getConfig(), ...partial };
|
|
61
32
|
fs.writeFileSync(GLOBAL_FILE, JSON.stringify(next, null, 2));
|
|
62
33
|
return next;
|
|
63
34
|
}
|
|
64
35
|
|
|
65
|
-
function getPlatform(name) {
|
|
66
|
-
const cfg = getConfig();
|
|
67
|
-
const key = (name || cfg.defaultPlatform || 'moontraze').toLowerCase();
|
|
68
|
-
return cfg.platforms[key] || null;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function addPlatform(name, { apiUrl, label, domain }) {
|
|
72
|
-
if (!name || !apiUrl) throw new Error('name and apiUrl required');
|
|
73
|
-
const cfg = getConfig();
|
|
74
|
-
cfg.platforms[name.toLowerCase()] = {
|
|
75
|
-
label: label || name,
|
|
76
|
-
apiUrl,
|
|
77
|
-
domain: domain || null,
|
|
78
|
-
token: null,
|
|
79
|
-
};
|
|
80
|
-
setConfig(cfg);
|
|
81
|
-
return cfg.platforms[name.toLowerCase()];
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function removePlatform(name) {
|
|
85
|
-
const cfg = getConfig();
|
|
86
|
-
name = name.toLowerCase();
|
|
87
|
-
if (name === 'moontraze') throw new Error('Cannot remove default platform "moontraze"');
|
|
88
|
-
if (!cfg.platforms[name]) throw new Error(`Platform "${name}" not found`);
|
|
89
|
-
delete cfg.platforms[name];
|
|
90
|
-
if (cfg.defaultPlatform === name) cfg.defaultPlatform = 'moontraze';
|
|
91
|
-
setConfig(cfg);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function setPlatformToken(name, token) {
|
|
95
|
-
const cfg = getConfig();
|
|
96
|
-
name = (name || cfg.defaultPlatform).toLowerCase();
|
|
97
|
-
if (!cfg.platforms[name]) throw new Error(`Platform "${name}" not found`);
|
|
98
|
-
cfg.platforms[name].token = token;
|
|
99
|
-
setConfig(cfg);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
36
|
function getProject() {
|
|
103
37
|
try {
|
|
104
38
|
if (fs.existsSync(LOCAL_FILE)) {
|
|
@@ -111,26 +45,14 @@ function getProject() {
|
|
|
111
45
|
function setProject(data) {
|
|
112
46
|
ensureDir(LOCAL_DIR);
|
|
113
47
|
fs.writeFileSync(LOCAL_FILE, JSON.stringify(data, null, 2));
|
|
114
|
-
|
|
115
|
-
// auto .gitignore
|
|
116
48
|
const ignore = path.join(process.cwd(), '.gitignore');
|
|
117
49
|
try {
|
|
118
50
|
let g = fs.existsSync(ignore) ? fs.readFileSync(ignore, 'utf8') : '';
|
|
119
|
-
if (!g.includes('.
|
|
120
|
-
fs.appendFileSync(ignore, '\n.
|
|
51
|
+
if (!g.includes('.moontraze')) {
|
|
52
|
+
fs.appendFileSync(ignore, '\n.moontraze/\n');
|
|
121
53
|
}
|
|
122
54
|
} catch (_) {}
|
|
123
55
|
return data;
|
|
124
56
|
}
|
|
125
57
|
|
|
126
|
-
module.exports = {
|
|
127
|
-
getConfig,
|
|
128
|
-
setConfig,
|
|
129
|
-
getPlatform,
|
|
130
|
-
addPlatform,
|
|
131
|
-
removePlatform,
|
|
132
|
-
setPlatformToken,
|
|
133
|
-
getProject,
|
|
134
|
-
setProject,
|
|
135
|
-
GLOBAL_DIR,
|
|
136
|
-
};
|
|
58
|
+
module.exports = { getConfig, setConfig, getProject, setProject, GLOBAL_DIR };
|
package/lib/deploy.js
CHANGED
|
@@ -1,43 +1,37 @@
|
|
|
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');
|
|
6
5
|
const chalk = require('chalk');
|
|
7
|
-
const { getConfig,
|
|
6
|
+
const { getConfig, getProject } = require('./config');
|
|
8
7
|
const { zipCwd } = require('./zip');
|
|
9
8
|
|
|
10
9
|
async function deploy({
|
|
11
10
|
prod = true,
|
|
12
11
|
projectName,
|
|
13
12
|
apiUrl: apiUrlArg,
|
|
14
|
-
platformName: platformNameArg,
|
|
15
13
|
domain: domainArg,
|
|
16
14
|
} = {}) {
|
|
17
|
-
const
|
|
18
|
-
platformNameArg || process.env.MOON_CURRENT_PLATFORM || 'moontraze';
|
|
19
|
-
const platform = getPlatform(platformName);
|
|
15
|
+
const cfg = getConfig();
|
|
20
16
|
|
|
21
17
|
const api =
|
|
22
18
|
apiUrlArg ||
|
|
23
19
|
process.env.MOON_API ||
|
|
24
|
-
|
|
20
|
+
cfg.apiUrl ||
|
|
25
21
|
'https://api.moontraze.com';
|
|
26
22
|
|
|
27
23
|
const domain =
|
|
28
24
|
domainArg ||
|
|
29
25
|
process.env.MOON_DOMAIN ||
|
|
30
|
-
|
|
26
|
+
cfg.domain ||
|
|
31
27
|
'moontraze.com';
|
|
32
28
|
|
|
33
|
-
const token =
|
|
34
|
-
|
|
35
|
-
platform?.token ||
|
|
36
|
-
null;
|
|
29
|
+
const token = cfg.token || process.env.MOON_TOKEN || null;
|
|
30
|
+
const label = process.env.MOON_LABEL || process.env.MOON_PLATFORM || 'Moontraze';
|
|
37
31
|
|
|
38
32
|
if (!token) {
|
|
39
33
|
throw new Error(
|
|
40
|
-
|
|
34
|
+
'Not logged in. Run: moon moontraze login\n or: npx moontraze login'
|
|
41
35
|
);
|
|
42
36
|
}
|
|
43
37
|
|
|
@@ -48,12 +42,12 @@ async function deploy({
|
|
|
48
42
|
|
|
49
43
|
if (!name || name.length < 3) {
|
|
50
44
|
throw new Error(
|
|
51
|
-
|
|
45
|
+
'No project linked. Run: moon moontraze link my-site\n or: npx moontraze link my-site'
|
|
52
46
|
);
|
|
53
47
|
}
|
|
54
48
|
|
|
55
49
|
console.log('');
|
|
56
|
-
console.log(chalk.cyan(
|
|
50
|
+
console.log(chalk.cyan(label));
|
|
57
51
|
console.log(` API ${api}`);
|
|
58
52
|
console.log(` Project ${name}`);
|
|
59
53
|
console.log(` Target https://${name}.${domain}`);
|
|
@@ -90,13 +84,12 @@ async function deploy({
|
|
|
90
84
|
filename: `${name}.zip`,
|
|
91
85
|
contentType: 'application/zip',
|
|
92
86
|
});
|
|
87
|
+
form.append('redeploy', alreadyExists ? 'true' : 'false');
|
|
93
88
|
|
|
94
89
|
const endpoint = alreadyExists
|
|
95
90
|
? `${api}/api/hosting/redeploy`
|
|
96
91
|
: `${api}/api/hosting/deploy`;
|
|
97
92
|
|
|
98
|
-
form.append('redeploy', alreadyExists ? 'true' : 'false');
|
|
99
|
-
|
|
100
93
|
const res = await fetch(endpoint, {
|
|
101
94
|
method: 'POST',
|
|
102
95
|
headers: {
|
|
@@ -129,9 +122,7 @@ async function deploy({
|
|
|
129
122
|
if (data.deployment?.version) {
|
|
130
123
|
console.log(chalk.gray(` Version ${data.deployment.version}`));
|
|
131
124
|
}
|
|
132
|
-
console.log(
|
|
133
|
-
chalk.green(alreadyExists ? '✓ Redeployed' : '✓ Deployed')
|
|
134
|
-
);
|
|
125
|
+
console.log(chalk.green(alreadyExists ? '✓ Redeployed' : '✓ Deployed'));
|
|
135
126
|
console.log('');
|
|
136
127
|
} finally {
|
|
137
128
|
if (zipPath && fs.existsSync(zipPath)) {
|
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,172 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* moon <platform> <command>
|
|
4
|
-
* Example:
|
|
5
|
-
* moon moontraze login
|
|
6
|
-
* moon myproject deploy --prod
|
|
7
|
-
* moon platform add myproject --api https://api.myproject.com
|
|
8
|
-
*/
|
|
9
|
-
const chalk = require('chalk');
|
|
10
|
-
const path = require('path');
|
|
11
|
-
const {
|
|
12
|
-
getConfig,
|
|
13
|
-
getPlatform,
|
|
14
|
-
addPlatform,
|
|
15
|
-
removePlatform,
|
|
16
|
-
setConfig,
|
|
17
|
-
} = require('../lib/config');
|
|
18
|
-
|
|
19
|
-
function printRootHelp() {
|
|
20
|
-
const cfg = getConfig();
|
|
21
|
-
const platforms = Object.keys(cfg.platforms || {}).join(', ') || 'moontraze';
|
|
22
|
-
|
|
23
|
-
console.log(`
|
|
24
|
-
${chalk.bold('moon')} — multi-platform CLI
|
|
25
|
-
|
|
26
|
-
Usage:
|
|
27
|
-
moon <platform> <command>
|
|
28
|
-
moon platform <add|list|remove|use> ...
|
|
29
|
-
|
|
30
|
-
Platforms:
|
|
31
|
-
${platforms}
|
|
32
|
-
|
|
33
|
-
Examples:
|
|
34
|
-
moon moontraze login
|
|
35
|
-
moon moontraze deploy --prod
|
|
36
|
-
moon myproject login
|
|
37
|
-
moon myproject deploy
|
|
38
|
-
|
|
39
|
-
Platform management:
|
|
40
|
-
moon platform add <name> --api <url>
|
|
41
|
-
moon platform list
|
|
42
|
-
moon platform remove <name>
|
|
43
|
-
moon platform use <name> # set default
|
|
44
|
-
|
|
45
|
-
Same as:
|
|
46
|
-
npx moontraze login
|
|
47
|
-
`);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const args = process.argv.slice(2);
|
|
51
|
-
const first = (args[0] || '').toLowerCase();
|
|
52
|
-
|
|
53
|
-
// Help
|
|
54
|
-
if (!first || first === '-h' || first === '--help' || first === 'help') {
|
|
55
|
-
printRootHelp();
|
|
56
|
-
process.exit(0);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Version
|
|
60
|
-
if (first === '-v' || first === '--version') {
|
|
61
|
-
try {
|
|
62
|
-
console.log(require('../package.json').version);
|
|
63
|
-
} catch {
|
|
64
|
-
console.log('1.0.0');
|
|
65
|
-
}
|
|
66
|
-
process.exit(0);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// ========== Platform management commands ==========
|
|
70
|
-
if (first === 'platform') {
|
|
71
|
-
const sub = (args[1] || '').toLowerCase();
|
|
72
|
-
|
|
73
|
-
if (sub === 'list') {
|
|
74
|
-
const cfg = getConfig();
|
|
75
|
-
console.log(chalk.bold('\nConfigured platforms:\n'));
|
|
76
|
-
for (const [name, p] of Object.entries(cfg.platforms || {})) {
|
|
77
|
-
const def = name === cfg.defaultPlatform ? chalk.green(' (default)') : '';
|
|
78
|
-
console.log(` ${chalk.cyan(name)}${def}`);
|
|
79
|
-
console.log(` API: ${p.apiUrl}`);
|
|
80
|
-
if (p.label) console.log(` Label: ${p.label}`);
|
|
81
|
-
console.log();
|
|
82
|
-
}
|
|
83
|
-
process.exit(0);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (sub === 'add') {
|
|
87
|
-
const name = args[2];
|
|
88
|
-
let apiUrl = null;
|
|
89
|
-
let label = null;
|
|
90
|
-
|
|
91
|
-
for (let i = 3; i < args.length; i++) {
|
|
92
|
-
if (args[i] === '--api' && args[i + 1]) apiUrl = args[++i];
|
|
93
|
-
if (args[i] === '--label' && args[i + 1]) label = args[++i];
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (!name || !apiUrl) {
|
|
97
|
-
console.error(chalk.red('Usage: moon platform add <name> --api <url> [--label <label>]'));
|
|
98
|
-
process.exit(1);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
try {
|
|
102
|
-
addPlatform(name, { apiUrl, label });
|
|
103
|
-
console.log(chalk.green(`✓ Platform "${name}" added`));
|
|
104
|
-
console.log(chalk.gray(` API: ${apiUrl}`));
|
|
105
|
-
console.log(chalk.gray(`\nNow you can run: moon ${name} login`));
|
|
106
|
-
} catch (err) {
|
|
107
|
-
console.error(chalk.red(err.message));
|
|
108
|
-
process.exit(1);
|
|
109
|
-
}
|
|
110
|
-
process.exit(0);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (sub === 'remove') {
|
|
114
|
-
const name = args[2];
|
|
115
|
-
if (!name) {
|
|
116
|
-
console.error(chalk.red('Usage: moon platform remove <name>'));
|
|
117
|
-
process.exit(1);
|
|
118
|
-
}
|
|
119
|
-
try {
|
|
120
|
-
removePlatform(name);
|
|
121
|
-
console.log(chalk.green(`✓ Platform "${name}" removed`));
|
|
122
|
-
} catch (err) {
|
|
123
|
-
console.error(chalk.red(err.message));
|
|
124
|
-
process.exit(1);
|
|
125
|
-
}
|
|
126
|
-
process.exit(0);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (sub === 'use') {
|
|
130
|
-
const name = args[2];
|
|
131
|
-
if (!name) {
|
|
132
|
-
console.error(chalk.red('Usage: moon platform use <name>'));
|
|
133
|
-
process.exit(1);
|
|
134
|
-
}
|
|
135
|
-
const p = getPlatform(name);
|
|
136
|
-
if (!p) {
|
|
137
|
-
console.error(chalk.red(`Platform "${name}" not found. Add it first.`));
|
|
138
|
-
process.exit(1);
|
|
139
|
-
}
|
|
140
|
-
setConfig({ defaultPlatform: name.toLowerCase() });
|
|
141
|
-
console.log(chalk.green(`✓ Default platform set to "${name}"`));
|
|
142
|
-
process.exit(0);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
console.error(chalk.red('Unknown platform command. Use: add | list | remove | use'));
|
|
146
|
-
process.exit(1);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// ========== Normal platform command ==========
|
|
150
|
-
const platformName = first;
|
|
151
|
-
const platform = getPlatform(platformName);
|
|
152
|
-
|
|
153
|
-
if (!platform) {
|
|
154
|
-
console.error(chalk.red(`Unknown platform: "${platformName}"`));
|
|
155
|
-
console.error(chalk.gray('Add it first: moon platform add ' + platformName + ' --api https://your-api.com'));
|
|
156
|
-
console.error(chalk.gray('Or see known platforms: moon platform list'));
|
|
157
|
-
process.exit(1);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Inject current platform info so moontraze.js (or generic runner) can use it
|
|
161
|
-
process.env.MOON_CURRENT_PLATFORM = platformName;
|
|
162
|
-
process.env.MOON_API = platform.apiUrl;
|
|
163
|
-
if (platform.domain) process.env.MOON_DOMAIN = platform.domain;
|
|
164
|
-
if (platform.token) process.env.MOON_TOKEN = platform.token;
|
|
165
|
-
|
|
166
|
-
// Forward to the actual platform runner
|
|
167
|
-
// Abhi ke liye sab platforms same runner use karenge (moontraze.js)
|
|
168
|
-
// Future mein alag runner bhi laga sakte ho
|
|
169
|
-
const runner = path.join(__dirname, 'moontraze.js');
|
|
170
|
-
|
|
171
|
-
process.argv = [process.argv[0], runner, ...args.slice(1)];
|
|
172
|
-
require(runner);
|