mage-remote-run 0.12.0 → 0.14.0
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/mage-remote-run.js +68 -74
- package/lib/command-registry.js +68 -0
- package/lib/commands/adobe-io-events.js +4 -0
- package/lib/commands/company.js +8 -0
- package/lib/commands/connections.js +47 -1
- package/lib/commands/console.js +300 -0
- package/lib/commands/customers.js +28 -0
- package/lib/commands/eav.js +8 -0
- package/lib/commands/inventory.js +20 -0
- package/lib/commands/orders.js +23 -3
- package/lib/commands/products.js +24 -0
- package/lib/commands/stores.js +36 -0
- package/lib/commands/tax.js +8 -0
- package/lib/commands/webhooks.js +4 -0
- package/lib/commands/websites.js +16 -0
- package/lib/mcp.js +263 -0
- package/package.json +4 -2
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import repl from 'repl';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { createClient } from '../api/factory.js';
|
|
5
|
+
import { loadConfig, getActiveProfile } from '../config.js';
|
|
6
|
+
import { registerCommands } from '../command-registry.js';
|
|
7
|
+
import { expandCommandAbbreviations } from '../command-helper.js';
|
|
8
|
+
|
|
9
|
+
export function registerConsoleCommand(program) {
|
|
10
|
+
program
|
|
11
|
+
.command('console')
|
|
12
|
+
.alias('repl')
|
|
13
|
+
.description('Start an interactive console')
|
|
14
|
+
.option('-d, --debug', 'Enable debug output')
|
|
15
|
+
.action(async (options) => {
|
|
16
|
+
if (options.debug) {
|
|
17
|
+
process.env.DEBUG = '1';
|
|
18
|
+
console.log(chalk.gray('Debug mode enabled'));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
console.log(chalk.bold.blue('Mage Remote Run Interactive Console'));
|
|
22
|
+
console.log(chalk.gray('Type your commands directly or write JS code.'));
|
|
23
|
+
console.log(chalk.gray('Global variables available: client (async factory), config, chalk'));
|
|
24
|
+
console.log(chalk.gray('Example JS: await (await client()).get("V1/store/websites")'));
|
|
25
|
+
console.log(chalk.gray('Type "list" to see available commands.'));
|
|
26
|
+
console.log(chalk.gray('Type .exit to quit.\n'));
|
|
27
|
+
|
|
28
|
+
// State for the REPL
|
|
29
|
+
let localProgram;
|
|
30
|
+
let currentProfile;
|
|
31
|
+
|
|
32
|
+
// Function to load/reload commands based on current profile
|
|
33
|
+
const loadLocalCommands = async () => {
|
|
34
|
+
// Create a fresh program instance for the REPL
|
|
35
|
+
localProgram = new Command();
|
|
36
|
+
|
|
37
|
+
// Configure custom output for REPL to avoid duplicate error printing
|
|
38
|
+
localProgram.configureOutput({
|
|
39
|
+
writeOut: (str) => process.stdout.write(str),
|
|
40
|
+
writeErr: (str) => process.stderr.write(str),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Apply exitOverride recursively
|
|
44
|
+
const applyExitOverride = (cmd) => {
|
|
45
|
+
cmd.exitOverride((err) => {
|
|
46
|
+
throw err;
|
|
47
|
+
});
|
|
48
|
+
if (cmd.commands) {
|
|
49
|
+
cmd.commands.forEach(applyExitOverride);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// Get current profile and register commands
|
|
54
|
+
const profile = await getActiveProfile();
|
|
55
|
+
registerCommands(localProgram, profile);
|
|
56
|
+
applyExitOverride(localProgram);
|
|
57
|
+
|
|
58
|
+
// Update current profile state (store simple unique string for comparison)
|
|
59
|
+
currentProfile = profile ? `${profile.name}:${profile.type}` : 'null';
|
|
60
|
+
|
|
61
|
+
return { localProgram, profile };
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// Initial load
|
|
65
|
+
await loadLocalCommands();
|
|
66
|
+
|
|
67
|
+
// Use 'stream' module to create dummy REPL for capturing defaults
|
|
68
|
+
const { PassThrough } = await import('stream');
|
|
69
|
+
const dummy = repl.start({ input: new PassThrough(), output: new PassThrough(), terminal: false });
|
|
70
|
+
const defaultCompleter = dummy.completer;
|
|
71
|
+
const defaultEval = dummy.eval;
|
|
72
|
+
dummy.close();
|
|
73
|
+
|
|
74
|
+
// Custom completer definition
|
|
75
|
+
const myCompleter = (line, callback) => {
|
|
76
|
+
const parts = line.split(/\s+/);
|
|
77
|
+
if (parts[0] === '') parts.shift();
|
|
78
|
+
|
|
79
|
+
let current = '';
|
|
80
|
+
let contextParts = [];
|
|
81
|
+
|
|
82
|
+
if (line.match(/\s$/)) {
|
|
83
|
+
current = '';
|
|
84
|
+
contextParts = parts.filter(p => p.length > 0);
|
|
85
|
+
} else {
|
|
86
|
+
current = parts.pop();
|
|
87
|
+
contextParts = parts;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const getCandidates = (cmdObj) => {
|
|
91
|
+
return cmdObj.commands.map(c => c.name());
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
let hits = [];
|
|
95
|
+
|
|
96
|
+
if (contextParts.length === 0) {
|
|
97
|
+
const candidates = getCandidates(localProgram);
|
|
98
|
+
hits = candidates.filter(c => c.startsWith(current));
|
|
99
|
+
} else {
|
|
100
|
+
let cmd = localProgram;
|
|
101
|
+
let validContext = true;
|
|
102
|
+
|
|
103
|
+
for (const part of contextParts) {
|
|
104
|
+
const found = cmd.commands.find(c => c.name() === part || (c.aliases && c.aliases().includes(part)));
|
|
105
|
+
if (found) {
|
|
106
|
+
cmd = found;
|
|
107
|
+
} else {
|
|
108
|
+
validContext = false;
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (validContext) {
|
|
114
|
+
const candidates = getCandidates(cmd);
|
|
115
|
+
hits = candidates.filter(c => c.startsWith(current));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (hits.length > 0) {
|
|
120
|
+
return callback(null, [hits, current]);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return defaultCompleter(line, callback);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// Custom evaluator definition
|
|
127
|
+
const myEval = async function (cmd, context, filename, callback) {
|
|
128
|
+
// 'this' is the REPLServer instance
|
|
129
|
+
const rInstance = this;
|
|
130
|
+
|
|
131
|
+
cmd = cmd.trim();
|
|
132
|
+
|
|
133
|
+
if (!cmd) {
|
|
134
|
+
callback(null);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (cmd === 'list') {
|
|
139
|
+
console.log(chalk.bold('\nAvailable Commands:'));
|
|
140
|
+
localProgram.commands.filter(c => !c._hidden).sort((a, b) => a.name().localeCompare(b.name())).forEach(c => {
|
|
141
|
+
console.log(` ${chalk.cyan(c.name().padEnd(25))} ${c.description()}`);
|
|
142
|
+
});
|
|
143
|
+
console.log('');
|
|
144
|
+
callback(null);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (cmd === 'help') {
|
|
149
|
+
localProgram.outputHelp();
|
|
150
|
+
callback(null);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
try {
|
|
155
|
+
const args = (cmd.match(/[^\s"']+|"([^"]*)"|'([^']*)'/g) || []).map(arg => {
|
|
156
|
+
if (arg.startsWith('"') && arg.endsWith('"')) return arg.slice(1, -1);
|
|
157
|
+
if (arg.startsWith("'") && arg.endsWith("'")) return arg.slice(1, -1);
|
|
158
|
+
return arg;
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
if (args.length > 0) {
|
|
162
|
+
if (process.env.DEBUG) {
|
|
163
|
+
console.log(chalk.gray('DEBUG: Parsing args:'), args);
|
|
164
|
+
}
|
|
165
|
+
let expandedArgs;
|
|
166
|
+
try {
|
|
167
|
+
expandedArgs = expandCommandAbbreviations(localProgram, args);
|
|
168
|
+
if (process.env.DEBUG) {
|
|
169
|
+
console.log(chalk.gray('DEBUG: Expanded args:'), expandedArgs);
|
|
170
|
+
}
|
|
171
|
+
} catch (e) {
|
|
172
|
+
if (e.isAmbiguous) {
|
|
173
|
+
console.error(chalk.red(e.message));
|
|
174
|
+
callback(null);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
throw e;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const firstWord = expandedArgs[0];
|
|
181
|
+
const knownCommands = localProgram.commands.map(c => c.name());
|
|
182
|
+
|
|
183
|
+
if (knownCommands.includes(firstWord)) {
|
|
184
|
+
// Valid command found
|
|
185
|
+
let keypressListeners = [];
|
|
186
|
+
try {
|
|
187
|
+
rInstance.pause();
|
|
188
|
+
|
|
189
|
+
// Capture and remove keypress listeners to prevent REPL from intercepting input
|
|
190
|
+
// intended for interactive commands (like inquirer)
|
|
191
|
+
keypressListeners = process.stdin.listeners('keypress');
|
|
192
|
+
process.stdin.removeAllListeners('keypress');
|
|
193
|
+
|
|
194
|
+
if (process.stdin.isTTY) {
|
|
195
|
+
process.stdin.setRawMode(false);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
await localProgram.parseAsync(['node', 'mage-remote-run', ...expandedArgs]);
|
|
199
|
+
|
|
200
|
+
// Check for profile change after command execution
|
|
201
|
+
const newProfileObj = await getActiveProfile();
|
|
202
|
+
const newProfileKey = newProfileObj ? `${newProfileObj.name}:${newProfileObj.type}` : 'null';
|
|
203
|
+
|
|
204
|
+
if (process.env.DEBUG) {
|
|
205
|
+
console.log(chalk.gray(`DEBUG: Check Profile Switch. Current: ${currentProfile}, New: ${newProfileKey}`));
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (newProfileKey !== currentProfile) {
|
|
209
|
+
await loadLocalCommands();
|
|
210
|
+
// Update context variables
|
|
211
|
+
rInstance.context.config = await loadConfig();
|
|
212
|
+
|
|
213
|
+
if (process.env.DEBUG) {
|
|
214
|
+
console.log(chalk.green(`\nConnection switched to ${newProfileObj ? newProfileObj.name : 'none'}. Commands reloaded.`));
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Restore REPL state
|
|
219
|
+
setTimeout(() => {
|
|
220
|
+
// Restore keypress listeners
|
|
221
|
+
keypressListeners.forEach(fn => process.stdin.on('keypress', fn));
|
|
222
|
+
|
|
223
|
+
if (process.stdin.isTTY) {
|
|
224
|
+
process.stdin.setRawMode(true);
|
|
225
|
+
}
|
|
226
|
+
process.stdin.resume();
|
|
227
|
+
|
|
228
|
+
// Flush stdin to remove any buffered leftovers
|
|
229
|
+
let chunk;
|
|
230
|
+
while ((chunk = process.stdin.read()) !== null) { }
|
|
231
|
+
|
|
232
|
+
rInstance.resume();
|
|
233
|
+
rInstance.displayPrompt(true);
|
|
234
|
+
}, 100);
|
|
235
|
+
|
|
236
|
+
} catch (e) {
|
|
237
|
+
// Restore listeners in error case too!
|
|
238
|
+
keypressListeners.forEach(fn => process.stdin.on('keypress', fn));
|
|
239
|
+
|
|
240
|
+
if (process.stdin.isTTY) {
|
|
241
|
+
process.stdin.setRawMode(true);
|
|
242
|
+
}
|
|
243
|
+
process.stdin.resume();
|
|
244
|
+
rInstance.resume();
|
|
245
|
+
|
|
246
|
+
// Flush stdin
|
|
247
|
+
let chunk;
|
|
248
|
+
while ((chunk = process.stdin.read()) !== null) { }
|
|
249
|
+
|
|
250
|
+
if (e.code === 'commander.helpDisplayed') {
|
|
251
|
+
// Help was displayed, clean exit for us
|
|
252
|
+
setImmediate(() => rInstance.displayPrompt());
|
|
253
|
+
} else if (e.code === 'commander.unknownOption' || e.code === 'commander.unknownCommand') {
|
|
254
|
+
console.error(chalk.red(e.message));
|
|
255
|
+
setImmediate(() => rInstance.displayPrompt());
|
|
256
|
+
} else {
|
|
257
|
+
if (e.code) {
|
|
258
|
+
// Likely a commander exit error we rethrew
|
|
259
|
+
setImmediate(() => rInstance.displayPrompt());
|
|
260
|
+
} else {
|
|
261
|
+
console.error(chalk.red('Command execution error:'), e);
|
|
262
|
+
setImmediate(() => rInstance.displayPrompt());
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
callback(null);
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
} catch (e) {
|
|
271
|
+
// unexpected error
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Fallback to default eval which supports top-level await
|
|
275
|
+
return defaultEval.call(rInstance, cmd, context, filename, callback);
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
const r = repl.start({
|
|
279
|
+
prompt: chalk.green('mage> '),
|
|
280
|
+
eval: myEval,
|
|
281
|
+
completer: myCompleter
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
r.context.client = createClient;
|
|
285
|
+
r.context.config = await loadConfig();
|
|
286
|
+
r.context.chalk = chalk;
|
|
287
|
+
|
|
288
|
+
// Helper to reload config if changed
|
|
289
|
+
r.context.reload = async () => {
|
|
290
|
+
r.context.config = await loadConfig();
|
|
291
|
+
// We should also reload commands here in case a manual config edit changed the type
|
|
292
|
+
await loadLocalCommands();
|
|
293
|
+
console.log(chalk.gray('Config and commands reloaded.'));
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
r.on('exit', () => {
|
|
297
|
+
process.exit();
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
}
|
|
@@ -6,6 +6,10 @@ import inquirer from 'inquirer';
|
|
|
6
6
|
export function registerCustomersCommands(program) {
|
|
7
7
|
const customers = program.command('customer').description('Manage customers');
|
|
8
8
|
|
|
9
|
+
|
|
10
|
+
//-------------------------------------------------------
|
|
11
|
+
// "customer list" Command
|
|
12
|
+
//-------------------------------------------------------
|
|
9
13
|
customers.command('list')
|
|
10
14
|
.description('List customers')
|
|
11
15
|
.option('-p, --page <number>', 'Page number', '1')
|
|
@@ -45,6 +49,10 @@ Examples:
|
|
|
45
49
|
} catch (e) { handleError(e); }
|
|
46
50
|
});
|
|
47
51
|
|
|
52
|
+
|
|
53
|
+
//-------------------------------------------------------
|
|
54
|
+
// "customer search" Command
|
|
55
|
+
//-------------------------------------------------------
|
|
48
56
|
customers.command('search <query>')
|
|
49
57
|
.description('Search customers by email')
|
|
50
58
|
.addHelpText('after', `
|
|
@@ -65,6 +73,10 @@ Examples:
|
|
|
65
73
|
} catch (e) { handleError(e); }
|
|
66
74
|
});
|
|
67
75
|
|
|
76
|
+
|
|
77
|
+
//-------------------------------------------------------
|
|
78
|
+
// "customer edit" Command
|
|
79
|
+
//-------------------------------------------------------
|
|
68
80
|
customers.command('edit <id>')
|
|
69
81
|
.description('Edit a customer')
|
|
70
82
|
.addHelpText('after', `
|
|
@@ -96,6 +108,10 @@ Examples:
|
|
|
96
108
|
} catch (e) { handleError(e); }
|
|
97
109
|
});
|
|
98
110
|
|
|
111
|
+
|
|
112
|
+
//-------------------------------------------------------
|
|
113
|
+
// "customer show" Command
|
|
114
|
+
//-------------------------------------------------------
|
|
99
115
|
customers.command('show <customerId>')
|
|
100
116
|
.description('Show detailed customer information')
|
|
101
117
|
.option('-f, --format <type>', 'Output format (text, json, xml)', 'text')
|
|
@@ -156,6 +172,10 @@ Examples:
|
|
|
156
172
|
} catch (e) { handleError(e); }
|
|
157
173
|
});
|
|
158
174
|
|
|
175
|
+
|
|
176
|
+
//-------------------------------------------------------
|
|
177
|
+
// "customer delete" Command
|
|
178
|
+
//-------------------------------------------------------
|
|
159
179
|
customers.command('delete <customerId>')
|
|
160
180
|
.description('Delete a customer')
|
|
161
181
|
.option('--force', 'Force delete without confirmation')
|
|
@@ -185,6 +205,10 @@ Examples:
|
|
|
185
205
|
} catch (e) { handleError(e); }
|
|
186
206
|
});
|
|
187
207
|
|
|
208
|
+
|
|
209
|
+
//-------------------------------------------------------
|
|
210
|
+
// "customer confirm" Command
|
|
211
|
+
//-------------------------------------------------------
|
|
188
212
|
customers.command('confirm [customerId]')
|
|
189
213
|
.description('Resend customer confirmation email')
|
|
190
214
|
.option('--redirect-url <url>', 'Redirect URL after confirmation')
|
|
@@ -242,6 +266,10 @@ Examples:
|
|
|
242
266
|
});
|
|
243
267
|
const groups = customers.command('group').description('Manage customer groups');
|
|
244
268
|
|
|
269
|
+
|
|
270
|
+
//-------------------------------------------------------
|
|
271
|
+
// "customer group list" Command
|
|
272
|
+
//-------------------------------------------------------
|
|
245
273
|
groups.command('list')
|
|
246
274
|
.description('List customer groups')
|
|
247
275
|
.option('-p, --page <number>', 'Page number', '1')
|
package/lib/commands/eav.js
CHANGED
|
@@ -8,6 +8,10 @@ export function registerEavCommands(program) {
|
|
|
8
8
|
// Attribute Sets
|
|
9
9
|
const attributeSets = eav.command('attribute-set').description('Manage attribute sets');
|
|
10
10
|
|
|
11
|
+
|
|
12
|
+
//-------------------------------------------------------
|
|
13
|
+
// "eav attribute-set list" Command
|
|
14
|
+
//-------------------------------------------------------
|
|
11
15
|
attributeSets.command('list')
|
|
12
16
|
.description('List all attribute sets')
|
|
13
17
|
.option('-p, --page <number>', 'Page number', '1')
|
|
@@ -51,6 +55,10 @@ Examples:
|
|
|
51
55
|
} catch (e) { handleError(e); }
|
|
52
56
|
});
|
|
53
57
|
|
|
58
|
+
|
|
59
|
+
//-------------------------------------------------------
|
|
60
|
+
// "eav attribute-set show" Command
|
|
61
|
+
//-------------------------------------------------------
|
|
54
62
|
attributeSets.command('show <id>')
|
|
55
63
|
.description('Show attribute set details')
|
|
56
64
|
.addHelpText('after', `
|
|
@@ -8,6 +8,10 @@ export function registerInventoryCommands(program) {
|
|
|
8
8
|
|
|
9
9
|
const stock = inventory.command('stock').description('Manage inventory stocks');
|
|
10
10
|
|
|
11
|
+
|
|
12
|
+
//-------------------------------------------------------
|
|
13
|
+
// "inventory stock list" Command
|
|
14
|
+
//-------------------------------------------------------
|
|
11
15
|
stock.command('list')
|
|
12
16
|
.description('List inventory stocks')
|
|
13
17
|
.addHelpText('after', `
|
|
@@ -28,6 +32,10 @@ Examples:
|
|
|
28
32
|
} catch (e) { handleError(e); }
|
|
29
33
|
});
|
|
30
34
|
|
|
35
|
+
|
|
36
|
+
//-------------------------------------------------------
|
|
37
|
+
// "inventory stock show" Command
|
|
38
|
+
//-------------------------------------------------------
|
|
31
39
|
stock.command('show <stockId>')
|
|
32
40
|
.description('Show stock details')
|
|
33
41
|
.addHelpText('after', `
|
|
@@ -52,6 +60,10 @@ Examples:
|
|
|
52
60
|
} catch (e) { handleError(e); }
|
|
53
61
|
});
|
|
54
62
|
|
|
63
|
+
|
|
64
|
+
//-------------------------------------------------------
|
|
65
|
+
// "inventory resolve-stock" Command
|
|
66
|
+
//-------------------------------------------------------
|
|
55
67
|
inventory.command('resolve-stock <type> <code>')
|
|
56
68
|
.description('Resolve stock for a sales channel')
|
|
57
69
|
.addHelpText('after', `
|
|
@@ -68,6 +80,10 @@ Examples:
|
|
|
68
80
|
|
|
69
81
|
const source = inventory.command('source').description('Manage inventory sources');
|
|
70
82
|
|
|
83
|
+
|
|
84
|
+
//-------------------------------------------------------
|
|
85
|
+
// "inventory source list" Command
|
|
86
|
+
//-------------------------------------------------------
|
|
71
87
|
source.command('list')
|
|
72
88
|
.description('List inventory sources')
|
|
73
89
|
.option('-p, --page <number>', 'Page number', '1')
|
|
@@ -108,6 +124,10 @@ Examples:
|
|
|
108
124
|
|
|
109
125
|
const ssa = source.command('selection-algorithm').description('Manage source selection algorithms');
|
|
110
126
|
|
|
127
|
+
|
|
128
|
+
//-------------------------------------------------------
|
|
129
|
+
// "inventory source selection-algorithm list" Command
|
|
130
|
+
//-------------------------------------------------------
|
|
111
131
|
ssa.command('list')
|
|
112
132
|
.description('List available source selection algorithms')
|
|
113
133
|
.addHelpText('after', `
|
package/lib/commands/orders.js
CHANGED
|
@@ -6,6 +6,10 @@ import inquirer from 'inquirer';
|
|
|
6
6
|
export function registerOrdersCommands(program) {
|
|
7
7
|
const orders = program.command('order').description('Manage orders');
|
|
8
8
|
|
|
9
|
+
|
|
10
|
+
//-------------------------------------------------------
|
|
11
|
+
// "order list" Command
|
|
12
|
+
//-------------------------------------------------------
|
|
9
13
|
orders.command('list')
|
|
10
14
|
.option('-p, --page <number>', 'Page number', '1')
|
|
11
15
|
.option('-s, --size <number>', 'Page size', '20')
|
|
@@ -44,6 +48,10 @@ Examples:
|
|
|
44
48
|
} catch (e) { handleError(e); }
|
|
45
49
|
});
|
|
46
50
|
|
|
51
|
+
|
|
52
|
+
//-------------------------------------------------------
|
|
53
|
+
// "order search" Command
|
|
54
|
+
//-------------------------------------------------------
|
|
47
55
|
orders.command('search <query>')
|
|
48
56
|
.description('Search orders by Increment ID')
|
|
49
57
|
.addHelpText('after', `
|
|
@@ -64,6 +72,10 @@ Examples:
|
|
|
64
72
|
} catch (e) { handleError(e); }
|
|
65
73
|
});
|
|
66
74
|
|
|
75
|
+
|
|
76
|
+
//-------------------------------------------------------
|
|
77
|
+
// "order edit" Command
|
|
78
|
+
//-------------------------------------------------------
|
|
67
79
|
orders.command('edit <id>')
|
|
68
80
|
.description('Update order status (via Comment)')
|
|
69
81
|
.addHelpText('after', `
|
|
@@ -92,6 +104,10 @@ Examples:
|
|
|
92
104
|
console.log(chalk.green(`Order ${id} updated.`));
|
|
93
105
|
} catch (e) { handleError(e); }
|
|
94
106
|
});
|
|
107
|
+
|
|
108
|
+
//-------------------------------------------------------
|
|
109
|
+
// "order show" Command
|
|
110
|
+
//-------------------------------------------------------
|
|
95
111
|
orders.command('show <identifier>')
|
|
96
112
|
.description('Show detailed order information by ID or Increment ID')
|
|
97
113
|
.option('-f, --format <type>', 'Output format (text, json, xml)', 'text')
|
|
@@ -106,6 +122,10 @@ Examples:
|
|
|
106
122
|
} catch (e) { handleError(e); }
|
|
107
123
|
});
|
|
108
124
|
|
|
125
|
+
|
|
126
|
+
//-------------------------------------------------------
|
|
127
|
+
// "order latest" Command
|
|
128
|
+
//-------------------------------------------------------
|
|
109
129
|
orders.command('latest')
|
|
110
130
|
.description('List latest orders sorted by created_at DESC with selection')
|
|
111
131
|
.option('-p, --page <number>', 'Page number', '1')
|
|
@@ -199,7 +219,7 @@ async function showOrder(identifier, format = 'text') {
|
|
|
199
219
|
order = await client.get(`V1/orders/${order.entity_id}`, {}, { headers });
|
|
200
220
|
} catch (subError) {
|
|
201
221
|
// ignore or log? If we fail to get formatted, fallback or throw?
|
|
202
|
-
// If we found it via search, 'order' is the object.
|
|
222
|
+
// If we found it via search, 'order' is the object.
|
|
203
223
|
// If format is json, we are good.
|
|
204
224
|
// If format is xml, we NEED to re-fetch because 'order' is currently a JS object from JSON response.
|
|
205
225
|
if (format === 'xml') throw subError;
|
|
@@ -267,8 +287,8 @@ function statusColor(status) {
|
|
|
267
287
|
// Basic color coding
|
|
268
288
|
if (['pending'].includes(status)) return status;
|
|
269
289
|
if (['processing'].includes(status)) return status;
|
|
270
|
-
if (['complete'].includes(status)) return status; // green?
|
|
271
|
-
// Since we don't have direct chalk access in this helper easily without passing it,
|
|
290
|
+
if (['complete'].includes(status)) return status; // green?
|
|
291
|
+
// Since we don't have direct chalk access in this helper easily without passing it,
|
|
272
292
|
// and I don't want to import it again if I can avoid it or I can just return string.
|
|
273
293
|
// Actually, I can import properly in module scope if I change top imports but I am overwriting the file so I can add imports.
|
|
274
294
|
return status;
|
package/lib/commands/products.js
CHANGED
|
@@ -5,6 +5,10 @@ import chalk from 'chalk';
|
|
|
5
5
|
export function registerProductsCommands(program) {
|
|
6
6
|
const products = program.command('product').description('Manage products');
|
|
7
7
|
|
|
8
|
+
|
|
9
|
+
//-------------------------------------------------------
|
|
10
|
+
// "product list" Command
|
|
11
|
+
//-------------------------------------------------------
|
|
8
12
|
products.command('list')
|
|
9
13
|
.description('List products')
|
|
10
14
|
.option('-p, --page <number>', 'Page number', '1')
|
|
@@ -48,6 +52,10 @@ Examples:
|
|
|
48
52
|
} catch (e) { handleError(e); }
|
|
49
53
|
});
|
|
50
54
|
|
|
55
|
+
|
|
56
|
+
//-------------------------------------------------------
|
|
57
|
+
// "product show" Command
|
|
58
|
+
//-------------------------------------------------------
|
|
51
59
|
products.command('show <sku>')
|
|
52
60
|
.description('Show product details')
|
|
53
61
|
.option('-f, --format <type>', 'Output format (text, json, xml)', 'text')
|
|
@@ -165,6 +173,10 @@ Examples:
|
|
|
165
173
|
|
|
166
174
|
const types = products.command('type').description('Manage product types');
|
|
167
175
|
|
|
176
|
+
|
|
177
|
+
//-------------------------------------------------------
|
|
178
|
+
// "product type list" Command
|
|
179
|
+
//-------------------------------------------------------
|
|
168
180
|
types.command('list')
|
|
169
181
|
.description('List available product types')
|
|
170
182
|
.addHelpText('after', `
|
|
@@ -182,6 +194,10 @@ Examples:
|
|
|
182
194
|
|
|
183
195
|
const attributes = products.command('attribute').description('Manage product attributes');
|
|
184
196
|
|
|
197
|
+
|
|
198
|
+
//-------------------------------------------------------
|
|
199
|
+
// "product attribute list" Command
|
|
200
|
+
//-------------------------------------------------------
|
|
185
201
|
attributes.command('list')
|
|
186
202
|
.description('List product attributes')
|
|
187
203
|
.option('-p, --page <number>', 'Page number', '1')
|
|
@@ -213,6 +229,10 @@ Examples:
|
|
|
213
229
|
} catch (e) { handleError(e); }
|
|
214
230
|
});
|
|
215
231
|
|
|
232
|
+
|
|
233
|
+
//-------------------------------------------------------
|
|
234
|
+
// "product attribute show" Command
|
|
235
|
+
//-------------------------------------------------------
|
|
216
236
|
attributes.command('show <attributeCode>')
|
|
217
237
|
.description('Show product attribute details')
|
|
218
238
|
.option('-f, --format <type>', 'Output format (text, json, xml)', 'text')
|
|
@@ -293,6 +313,10 @@ Examples:
|
|
|
293
313
|
});
|
|
294
314
|
|
|
295
315
|
const attributeTypes = attributes.command('type').description('Manage attribute types');
|
|
316
|
+
|
|
317
|
+
//-------------------------------------------------------
|
|
318
|
+
// "product attribute type list" Command
|
|
319
|
+
//-------------------------------------------------------
|
|
296
320
|
attributeTypes.command('list')
|
|
297
321
|
.description('List product attribute types')
|
|
298
322
|
.addHelpText('after', `
|