moontraze 1.0.3 → 1.0.5

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/moon.js CHANGED
@@ -1,68 +1,172 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
3
  * moon <platform> <command>
4
- * Example: moon moontraze login
5
- * moon moontraze deploy --prod
4
+ * Example:
5
+ * moon moontraze login
6
+ * moon myproject deploy --prod
7
+ * moon platform add myproject --api https://api.myproject.com
6
8
  */
7
9
  const chalk = require('chalk');
8
10
  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
- };
11
+ const {
12
+ getConfig,
13
+ getPlatform,
14
+ addPlatform,
15
+ removePlatform,
16
+ setConfig,
17
+ } = require('../lib/config');
18
18
 
19
19
  function printRootHelp() {
20
+ const cfg = getConfig();
21
+ const platforms = Object.keys(cfg.platforms || {}).join(', ') || 'moontraze';
22
+
20
23
  console.log(`
21
24
  ${chalk.bold('moon')} — multi-platform CLI
22
25
 
23
26
  Usage:
24
27
  moon <platform> <command>
28
+ moon platform <add|list|remove|use> ...
25
29
 
26
30
  Platforms:
27
- moontraze Moontraze hosting (moontraze.com)
31
+ ${platforms}
28
32
 
29
33
  Examples:
30
34
  moon moontraze login
31
- moon moontraze link my-site
32
35
  moon moontraze deploy --prod
33
- moon moontraze --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
34
44
 
35
45
  Same as:
36
46
  npx moontraze login
37
- npx moontraze deploy --prod
38
47
  `);
39
48
  }
40
49
 
41
50
  const args = process.argv.slice(2);
42
- const platform = (args[0] || '').toLowerCase();
51
+ const first = (args[0] || '').toLowerCase();
43
52
 
44
- if (!platform || platform === '-h' || platform === '--help' || platform === 'help') {
53
+ // Help
54
+ if (!first || first === '-h' || first === '--help' || first === 'help') {
45
55
  printRootHelp();
46
56
  process.exit(0);
47
57
  }
48
58
 
49
- if (platform === '-v' || platform === '--version') {
59
+ // Version
60
+ if (first === '-v' || first === '--version') {
50
61
  try {
51
62
  console.log(require('../package.json').version);
52
63
  } catch {
53
- console.log('0.0.0');
64
+ console.log('1.0.0');
54
65
  }
55
66
  process.exit(0);
56
67
  }
57
68
 
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'));
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'));
63
157
  process.exit(1);
64
158
  }
65
159
 
66
- // Forward remaining args to platform CLI
67
- process.argv = [process.argv[0], meta.runner, ...args.slice(1)];
68
- require(meta.runner);
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);
package/bin/moontraze.js CHANGED
@@ -2,31 +2,52 @@
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 {
6
+ getConfig,
7
+ getPlatform,
8
+ getProject,
9
+ setProject,
10
+ setPlatformToken,
11
+ } = require('../lib/config');
6
12
  const { deploy } = require('../lib/deploy');
7
13
 
8
14
  const program = new Command();
9
15
 
16
+ // Current platform (moon.js se inject hota hai)
17
+ const platformName = process.env.MOON_CURRENT_PLATFORM || 'moontraze';
18
+ const platform = getPlatform(platformName) || getConfig().platforms?.moontraze;
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';
22
+
10
23
  program
11
- .name('moontraze')
12
- .description('Deploy sites to Moontraze hosting (moontraze.com)')
13
- .version('1.0.3');
24
+ .name(platformName)
25
+ .description(`Deploy sites using ${platform?.label || platformName}`)
26
+ .version('1.0.4');
14
27
 
15
- // moon moontraze login | npx moontraze login
28
+ // ========== login ==========
16
29
  program
17
30
  .command('login')
18
31
  .description('Log in with email/password or token')
19
32
  .option('--token <jwt>', 'JWT token (advanced, skip interactive login)')
20
33
  .action(async (opts) => {
21
34
  try {
22
- await login(opts.token);
35
+ // login function ko current apiUrl dena zaroori hai
36
+ const token = await login(opts.token, { apiUrl, platformName });
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}`));
23
44
  } catch (e) {
24
45
  console.error(chalk.red('Login failed:'), e.message);
25
46
  process.exit(1);
26
47
  }
27
48
  });
28
49
 
29
- // moon moontraze link [name]
50
+ // ========== link ==========
30
51
  program
31
52
  .command('link [name]')
32
53
  .description('Link this folder to a hosting project name')
@@ -34,6 +55,7 @@ program
34
55
  try {
35
56
  const prompts = require('prompts');
36
57
  let projectName = name;
58
+
37
59
  if (!projectName) {
38
60
  const a = await prompts({
39
61
  type: 'text',
@@ -46,25 +68,29 @@ program
46
68
  });
47
69
  projectName = a.n;
48
70
  }
71
+
49
72
  if (!projectName) process.exit(1);
73
+
50
74
  projectName = projectName.toLowerCase().replace(/[^a-z0-9-]/g, '');
51
- setProject({ projectName });
52
- const domain = getConfig().domain || 'moontraze.com';
75
+ setProject({ projectName, platform: platformName });
76
+
53
77
  console.log(chalk.green(`Linked → ${projectName}.${domain}`));
54
- console.log(
55
- chalk.gray('(saved .moontraze/project.json — same as .vercel)')
56
- );
78
+ console.log(chalk.gray('(saved .moon/project.json)'));
57
79
  } catch (e) {
58
80
  console.error(chalk.red(e.message));
59
81
  process.exit(1);
60
82
  }
61
83
  });
62
84
 
85
+ // ========== deploy ==========
63
86
  async function runDeploy(opts) {
64
87
  try {
65
88
  await deploy({
66
89
  prod: !!(opts.prod || opts.production),
67
90
  projectName: opts.project || opts.name,
91
+ apiUrl, // ← important
92
+ platformName,
93
+ domain,
68
94
  });
69
95
  } catch (e) {
70
96
  console.error(chalk.red('\nDeploy failed:'), e.message);
@@ -80,7 +106,7 @@ program
80
106
  .option('-p, --project <name>', 'Project name (or use link)')
81
107
  .action(runDeploy);
82
108
 
83
- // moon moontraze --prod
109
+ // Direct flags: moon moontraze --prod
84
110
  program
85
111
  .option('--prod', 'Deploy to production')
86
112
  .option('--production', 'Deploy to production')
@@ -98,14 +124,10 @@ program.addHelpText(
98
124
  'after',
99
125
  `
100
126
  Examples:
101
- npx moontraze login
102
- npx moontraze link my-site
103
- npx moontraze deploy --prod
104
-
105
- moon moontraze login
106
- moon moontraze link my-site
107
- moon moontraze deploy --prod
108
- moon moontraze --prod
127
+ moon ${platformName} login
128
+ moon ${platformName} link my-site
129
+ moon ${platformName} deploy --prod
130
+ moon ${platformName} --prod
109
131
  `
110
132
  );
111
133
 
package/lib/auth.js CHANGED
@@ -2,16 +2,25 @@ const prompts = require('prompts');
2
2
  const chalk = require('chalk');
3
3
  const http = require('http');
4
4
  const { URL } = require('url');
5
- const { setConfig, getConfig } = require('./config');
5
+ const {
6
+ getConfig,
7
+ getPlatform,
8
+ setPlatformToken,
9
+ setConfig,
10
+ } = require('./config');
11
+
12
+ async function login(tokenArg, options = {}) {
13
+ const platformName = options.platformName || process.env.MOON_CURRENT_PLATFORM || 'moontraze';
14
+ const platform = getPlatform(platformName);
15
+ const apiUrl = options.apiUrl || process.env.MOON_API || platform?.apiUrl || 'https://api.moontraze.com';
6
16
 
7
- async function login(tokenArg) {
8
17
  // Power user: --token still works (hidden)
9
18
  if (tokenArg && String(tokenArg).trim()) {
10
- return saveAndValidateToken(String(tokenArg).trim());
19
+ return saveAndValidateToken(String(tokenArg).trim(), { apiUrl, platformName });
11
20
  }
12
21
 
13
22
  console.log('');
14
- console.log(chalk.cyan('Moontraze Login'));
23
+ console.log(chalk.cyan(`${platform?.label || platformName} Login`));
15
24
  console.log('');
16
25
 
17
26
  const { method } = await prompts({
@@ -29,20 +38,19 @@ async function login(tokenArg) {
29
38
  }
30
39
 
31
40
  if (method === 'email') {
32
- await loginWithEmail();
41
+ await loginWithEmail({ apiUrl, platformName, platform });
33
42
  } else {
34
- await loginWithMoonID();
43
+ await loginWithMoonID({ apiUrl, platformName, platform });
35
44
  }
36
45
  }
37
46
 
38
- async function loginWithEmail() {
47
+ async function loginWithEmail({ apiUrl, platformName, platform }) {
39
48
  const answers = await prompts([
40
49
  {
41
50
  type: 'text',
42
51
  name: 'email',
43
52
  message: 'Email',
44
- validate: (v) =>
45
- v && v.includes('@') ? true : 'Enter a valid email',
53
+ validate: (v) => (v && v.includes('@') ? true : 'Enter a valid email'),
46
54
  },
47
55
  {
48
56
  type: 'password',
@@ -56,10 +64,8 @@ async function loginWithEmail() {
56
64
  throw new Error('Login cancelled');
57
65
  }
58
66
 
59
- const cfg = getConfig();
60
67
  const fetch = require('node-fetch');
61
-
62
- const res = await fetch(`${cfg.apiUrl}/api/platform/login`, {
68
+ const res = await fetch(`${apiUrl}/api/platform/login`, {
63
69
  method: 'POST',
64
70
  headers: { 'Content-Type': 'application/json' },
65
71
  body: JSON.stringify({
@@ -73,28 +79,29 @@ async function loginWithEmail() {
73
79
  if (!res.ok) {
74
80
  throw new Error(data.error || 'Invalid email or password');
75
81
  }
76
-
77
82
  if (!data.token) {
78
83
  throw new Error('Login succeeded but no token returned');
79
84
  }
80
85
 
81
- setConfig({ token: data.token });
86
+ // Token us platform ke under save hoga
87
+ setPlatformToken(platformName, data.token);
88
+
82
89
  console.log('');
83
90
  console.log(chalk.green('✓ Logged in'));
84
91
  if (data.user?.email) {
85
92
  console.log(chalk.gray(` ${data.user.email}`));
86
93
  }
87
- console.log(chalk.gray(` Config: ~/.moontraze/config.json`));
94
+ console.log(chalk.gray(` Platform: ${platformName}`));
95
+ console.log(chalk.gray(` Config: ~/.moon/config.json`));
88
96
  console.log('');
89
97
  }
90
98
 
91
- async function loginWithMoonID() {
92
- const cfg = getConfig();
99
+ async function loginWithMoonID({ apiUrl, platformName, platform }) {
93
100
  const state = Math.random().toString(36).substring(2, 12);
94
101
  const port = 17321 + Math.floor(Math.random() * 100);
95
102
  const redirectUri = `http://127.0.0.1:${port}/callback`;
96
-
97
103
  const appId = 'com.moonstorage.app';
104
+
98
105
  const deepLink =
99
106
  `moonid://auth` +
100
107
  `?app_id=${encodeURIComponent(appId)}` +
@@ -107,7 +114,7 @@ async function loginWithMoonID() {
107
114
  )}`;
108
115
 
109
116
  console.log('');
110
- console.log(chalk.cyan('MoonID Login'));
117
+ console.log(chalk.cyan(`${platform?.label || platformName} — MoonID Login`));
111
118
  console.log(chalk.gray('1. Open MoonID app on your phone'));
112
119
  console.log(chalk.gray('2. Scan the QR code (open link below in browser)'));
113
120
  console.log(chalk.gray('3. Approve login'));
@@ -121,18 +128,17 @@ async function loginWithMoonID() {
121
128
  console.log(chalk.gray('Waiting for approval... (Ctrl+C to cancel)'));
122
129
  console.log('');
123
130
 
124
- // Local server — MoonID redirect yahan aayega
125
131
  const token = await waitForMoonIDCallback({ port, state, timeoutMs: 120000 });
126
132
 
127
133
  if (!token) {
128
134
  throw new Error('MoonID login timed out or denied');
129
135
  }
130
136
 
131
- await saveAndValidateToken(token);
137
+ await saveAndValidateToken(token, { apiUrl, platformName });
132
138
  }
133
139
 
134
140
  function waitForMoonIDCallback({ port, state, timeoutMs }) {
135
- return new Promise((resolve, reject) => {
141
+ return new Promise((resolve) => {
136
142
  const server = http.createServer((req, res) => {
137
143
  try {
138
144
  const u = new URL(req.url, `http://127.0.0.1:${port}`);
@@ -199,11 +205,10 @@ function waitForMoonIDCallback({ port, state, timeoutMs }) {
199
205
  });
200
206
  }
201
207
 
202
- async function saveAndValidateToken(token) {
203
- const cfg = getConfig();
208
+ async function saveAndValidateToken(token, { apiUrl, platformName }) {
204
209
  const fetch = require('node-fetch');
205
210
 
206
- const res = await fetch(`${cfg.apiUrl}/api/hosting/quota`, {
211
+ const res = await fetch(`${apiUrl}/api/hosting/quota`, {
207
212
  headers: { Authorization: `Bearer ${token}` },
208
213
  });
209
214
 
@@ -211,10 +216,13 @@ async function saveAndValidateToken(token) {
211
216
  throw new Error('Invalid or expired token');
212
217
  }
213
218
 
214
- setConfig({ token });
219
+ // Token specific platform ke under save hoga
220
+ setPlatformToken(platformName, token);
221
+
215
222
  console.log('');
216
223
  console.log(chalk.green('✓ Logged in'));
217
- console.log(chalk.gray(` Config: ~/.moontraze/config.json`));
224
+ console.log(chalk.gray(` Platform: ${platformName}`));
225
+ console.log(chalk.gray(` Config: ~/.moon/config.json`));
218
226
  console.log('');
219
227
  }
220
228
 
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(), '.moontraze');
5
+ const GLOBAL_DIR = path.join(os.homedir(), '.moon');
6
6
  const GLOBAL_FILE = path.join(GLOBAL_DIR, 'config.json');
7
- const LOCAL_DIR = path.join(process.cwd(), '.moontraze');
7
+ const LOCAL_DIR = path.join(process.cwd(), '.moon');
8
8
  const LOCAL_FILE = path.join(LOCAL_DIR, 'project.json');
9
9
 
10
10
  function ensureDir(d) {
@@ -12,29 +12,93 @@ function ensureDir(d) {
12
12
  }
13
13
 
14
14
  const DEFAULTS = {
15
- token: null,
16
- apiUrl: process.env.MOONTRAZE_API || 'https://api.moontraze.com',
17
- domain: process.env.MOONTRAZE_DOMAIN || 'moontraze.com',
15
+ defaultPlatform: 'moontraze',
16
+ platforms: {
17
+ moontraze: {
18
+ label: 'Moontraze',
19
+ apiUrl: process.env.MOON_API || 'https://api.moontraze.com',
20
+ domain: process.env.MOON_DOMAIN || 'moontraze.com',
21
+ },
22
+ },
18
23
  };
19
24
 
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
+
20
47
  function getConfig() {
21
48
  try {
22
49
  if (fs.existsSync(GLOBAL_FILE)) {
23
50
  const saved = JSON.parse(fs.readFileSync(GLOBAL_FILE, 'utf8'));
24
- // merge defaults so old frelanceo.com cache auto-upgrade on missing keys
25
- return { ...DEFAULTS, ...saved };
51
+ return migrate(saved);
26
52
  }
27
53
  } catch (_) {}
28
- return { ...DEFAULTS };
54
+ return JSON.parse(JSON.stringify(DEFAULTS)); // deep copy
29
55
  }
30
56
 
31
57
  function setConfig(partial) {
32
58
  ensureDir(GLOBAL_DIR);
33
- const next = { ...getConfig(), ...partial };
59
+ const current = getConfig();
60
+ const next = { ...current, ...partial };
34
61
  fs.writeFileSync(GLOBAL_FILE, JSON.stringify(next, null, 2));
35
62
  return next;
36
63
  }
37
64
 
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
+
38
102
  function getProject() {
39
103
  try {
40
104
  if (fs.existsSync(LOCAL_FILE)) {
@@ -47,14 +111,26 @@ function getProject() {
47
111
  function setProject(data) {
48
112
  ensureDir(LOCAL_DIR);
49
113
  fs.writeFileSync(LOCAL_FILE, JSON.stringify(data, null, 2));
114
+
115
+ // auto .gitignore
50
116
  const ignore = path.join(process.cwd(), '.gitignore');
51
117
  try {
52
118
  let g = fs.existsSync(ignore) ? fs.readFileSync(ignore, 'utf8') : '';
53
- if (!g.includes('.moontraze')) {
54
- fs.appendFileSync(ignore, '\n.moontraze/\n');
119
+ if (!g.includes('.moon')) {
120
+ fs.appendFileSync(ignore, '\n.moon/\n');
55
121
  }
56
122
  } catch (_) {}
57
123
  return data;
58
124
  }
59
125
 
60
- module.exports = { getConfig, setConfig, getProject, setProject, GLOBAL_DIR };
126
+ module.exports = {
127
+ getConfig,
128
+ setConfig,
129
+ getPlatform,
130
+ addPlatform,
131
+ removePlatform,
132
+ setPlatformToken,
133
+ getProject,
134
+ setProject,
135
+ GLOBAL_DIR,
136
+ };
package/lib/deploy.js CHANGED
@@ -4,14 +4,40 @@ const fetch = require('node-fetch');
4
4
  const FormData = require('form-data');
5
5
  const ora = require('ora');
6
6
  const chalk = require('chalk');
7
- const { getConfig, getProject } = require('./config');
7
+ const { getConfig, getPlatform, getProject } = require('./config');
8
8
  const { zipCwd } = require('./zip');
9
9
 
10
- async function deploy({ prod = true, projectName } = {}) {
11
- const cfg = getConfig();
12
- if (!cfg.token) {
10
+ async function deploy({
11
+ prod = true,
12
+ projectName,
13
+ apiUrl: apiUrlArg,
14
+ platformName: platformNameArg,
15
+ domain: domainArg,
16
+ } = {}) {
17
+ const platformName =
18
+ platformNameArg || process.env.MOON_CURRENT_PLATFORM || 'moontraze';
19
+ const platform = getPlatform(platformName);
20
+
21
+ const api =
22
+ apiUrlArg ||
23
+ process.env.MOON_API ||
24
+ platform?.apiUrl ||
25
+ 'https://api.moontraze.com';
26
+
27
+ const domain =
28
+ domainArg ||
29
+ process.env.MOON_DOMAIN ||
30
+ platform?.domain ||
31
+ 'moontraze.com';
32
+
33
+ const token =
34
+ process.env.MOON_TOKEN ||
35
+ platform?.token ||
36
+ null;
37
+
38
+ if (!token) {
13
39
  throw new Error(
14
- 'Not logged in. Run: moon moontraze login (or: npx moontraze login)'
40
+ `Not logged in. Run: moon ${platformName} login`
15
41
  );
16
42
  }
17
43
 
@@ -19,18 +45,16 @@ async function deploy({ prod = true, projectName } = {}) {
19
45
  const name = (projectName || linked?.projectName || '')
20
46
  .toLowerCase()
21
47
  .replace(/[^a-z0-9-]/g, '');
48
+
22
49
  if (!name || name.length < 3) {
23
50
  throw new Error(
24
- 'No project linked. Run: moon moontraze link my-site (or: npx moontraze link my-site)'
51
+ `No project linked. Run: moon ${platformName} link my-site`
25
52
  );
26
53
  }
27
54
 
28
- const domain = cfg.domain || 'moontraze.com';
29
- const api = cfg.apiUrl || 'https://api.moontraze.com';
30
-
31
55
  console.log('');
32
- console.log(chalk.cyan('Moontraze'));
33
- console.log(` Inspect ${api}`);
56
+ console.log(chalk.cyan(platform?.label || platformName));
57
+ console.log(` API ${api}`);
34
58
  console.log(` Project ${name}`);
35
59
  console.log(` Target https://${name}.${domain}`);
36
60
  console.log('');
@@ -45,9 +69,10 @@ async function deploy({ prod = true, projectName } = {}) {
45
69
 
46
70
  spinner.text = 'Checking project...';
47
71
  let alreadyExists = false;
72
+
48
73
  try {
49
74
  const statusRes = await fetch(`${api}/api/hosting/status/${name}`, {
50
- headers: { Authorization: `Bearer ${cfg.token}` },
75
+ headers: { Authorization: `Bearer ${token}` },
51
76
  });
52
77
  if (statusRes.ok) {
53
78
  const statusData = await statusRes.json();
@@ -66,21 +91,16 @@ async function deploy({ prod = true, projectName } = {}) {
66
91
  contentType: 'application/zip',
67
92
  });
68
93
 
69
- // existing → redeploy; new → deploy
70
94
  const endpoint = alreadyExists
71
95
  ? `${api}/api/hosting/redeploy`
72
96
  : `${api}/api/hosting/deploy`;
73
97
 
74
- if (alreadyExists) {
75
- form.append('redeploy', 'true');
76
- } else {
77
- form.append('redeploy', 'false');
78
- }
98
+ form.append('redeploy', alreadyExists ? 'true' : 'false');
79
99
 
80
100
  const res = await fetch(endpoint, {
81
101
  method: 'POST',
82
102
  headers: {
83
- Authorization: `Bearer ${cfg.token}`,
103
+ Authorization: `Bearer ${token}`,
84
104
  ...form.getHeaders(),
85
105
  },
86
106
  body: form,
@@ -102,6 +122,7 @@ async function deploy({ prod = true, projectName } = {}) {
102
122
  }
103
123
 
104
124
  spinner.succeed(`Ready in ${sec}s`);
125
+
105
126
  const url = data.url || `https://${name}.${domain}`;
106
127
  console.log('');
107
128
  console.log(chalk.green(` Production ${url}`));
package/lib/zip.js CHANGED
@@ -11,7 +11,8 @@ const SKIP = new Set([
11
11
  'build',
12
12
  'out',
13
13
  '.vercel',
14
- '.moontraze',
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
- `moontraze-${Date.now()}.zip`
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()) walk(full, rel);
44
- else archive.file(full, { name: rel.replace(/\\/g, '/') });
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,6 +1,6 @@
1
1
  {
2
2
  "name": "moontraze",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Deploy to Moontraze hosting — like vercel CLI",
5
5
  "bin": {
6
6
  "moontraze": "./bin/moontraze.js",