appshot-cli 0.8.7 → 0.9.1

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.
Files changed (65) hide show
  1. package/README.md +784 -15
  2. package/dist/cli.js +24 -5
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/build.d.ts.map +1 -1
  5. package/dist/commands/build.js +16 -2
  6. package/dist/commands/build.js.map +1 -1
  7. package/dist/commands/export.d.ts +3 -0
  8. package/dist/commands/export.d.ts.map +1 -0
  9. package/dist/commands/export.js +382 -0
  10. package/dist/commands/export.js.map +1 -0
  11. package/dist/commands/order.d.ts +3 -0
  12. package/dist/commands/order.d.ts.map +1 -0
  13. package/dist/commands/order.js +321 -0
  14. package/dist/commands/order.js.map +1 -0
  15. package/dist/commands/preset.d.ts +5 -0
  16. package/dist/commands/preset.d.ts.map +1 -0
  17. package/dist/commands/preset.js +191 -0
  18. package/dist/commands/preset.js.map +1 -0
  19. package/dist/commands/quickstart.d.ts +3 -0
  20. package/dist/commands/quickstart.d.ts.map +1 -0
  21. package/dist/commands/quickstart.js +326 -0
  22. package/dist/commands/quickstart.js.map +1 -0
  23. package/dist/commands/style.d.ts.map +1 -1
  24. package/dist/commands/style.js +98 -0
  25. package/dist/commands/style.js.map +1 -1
  26. package/dist/commands/template.d.ts +3 -0
  27. package/dist/commands/template.d.ts.map +1 -0
  28. package/dist/commands/template.js +399 -0
  29. package/dist/commands/template.js.map +1 -0
  30. package/dist/core/compose.d.ts +16 -0
  31. package/dist/core/compose.d.ts.map +1 -1
  32. package/dist/core/compose.js +342 -83
  33. package/dist/core/compose.js.map +1 -1
  34. package/dist/services/doctor.js +1 -1
  35. package/dist/services/export-validator.d.ts +23 -0
  36. package/dist/services/export-validator.d.ts.map +1 -0
  37. package/dist/services/export-validator.js +209 -0
  38. package/dist/services/export-validator.js.map +1 -0
  39. package/dist/services/fastlane-config-generator.d.ts +17 -0
  40. package/dist/services/fastlane-config-generator.d.ts.map +1 -0
  41. package/dist/services/fastlane-config-generator.js +343 -0
  42. package/dist/services/fastlane-config-generator.js.map +1 -0
  43. package/dist/services/fastlane-language-mapper.d.ts +33 -0
  44. package/dist/services/fastlane-language-mapper.d.ts.map +1 -0
  45. package/dist/services/fastlane-language-mapper.js +167 -0
  46. package/dist/services/fastlane-language-mapper.js.map +1 -0
  47. package/dist/services/screenshot-order.d.ts +41 -0
  48. package/dist/services/screenshot-order.d.ts.map +1 -0
  49. package/dist/services/screenshot-order.js +211 -0
  50. package/dist/services/screenshot-order.js.map +1 -0
  51. package/dist/services/screenshot-organizer.d.ts +44 -0
  52. package/dist/services/screenshot-organizer.d.ts.map +1 -0
  53. package/dist/services/screenshot-organizer.js +234 -0
  54. package/dist/services/screenshot-organizer.js.map +1 -0
  55. package/dist/templates/registry.d.ts +73 -0
  56. package/dist/templates/registry.d.ts.map +1 -0
  57. package/dist/templates/registry.js +724 -0
  58. package/dist/templates/registry.js.map +1 -0
  59. package/dist/types.d.ts +15 -0
  60. package/dist/types.d.ts.map +1 -1
  61. package/dist/utils/validation.d.ts +36 -0
  62. package/dist/utils/validation.d.ts.map +1 -0
  63. package/dist/utils/validation.js +143 -0
  64. package/dist/utils/validation.js.map +1 -0
  65. package/package.json +3 -2
@@ -0,0 +1,321 @@
1
+ import { Command } from 'commander';
2
+ import { promises as fs } from 'fs';
3
+ import path from 'path';
4
+ import pc from 'picocolors';
5
+ import { select, confirm } from '@inquirer/prompts';
6
+ import { loadOrderConfig, saveOrderConfig, getAvailableScreenshots, displayOrder, applyOrder } from '../services/screenshot-order.js';
7
+ export default function orderCmd() {
8
+ const cmd = new Command('order')
9
+ .description('Manage screenshot ordering for App Store submissions')
10
+ .option('--device <name>', 'Specific device to order (iphone|ipad|mac|watch)')
11
+ .option('--source <dir>', 'Source directory containing screenshots', './final')
12
+ .option('--lang <code>', 'Language code for screenshots', 'en')
13
+ .option('--show', 'Display current order without editing')
14
+ .option('--reset', 'Reset ordering to defaults')
15
+ .option('--apply', 'Apply saved order by adding numeric prefixes to files')
16
+ .option('--remove-prefixes', 'Remove numeric prefixes from filenames')
17
+ .addHelpText('after', `
18
+ ${pc.bold('Examples:')}
19
+ ${pc.dim('# Interactive ordering for iPhone screenshots')}
20
+ $ appshot order --device iphone
21
+
22
+ ${pc.dim('# Show current order without editing')}
23
+ $ appshot order --show
24
+
25
+ ${pc.dim('# Apply numeric prefixes based on saved order')}
26
+ $ appshot order --apply --device iphone
27
+
28
+ ${pc.dim('# Remove numeric prefixes from files')}
29
+ $ appshot order --remove-prefixes --device iphone
30
+
31
+ ${pc.dim('# Reset to smart defaults')}
32
+ $ appshot order --reset
33
+
34
+ ${pc.bold('How it works:')}
35
+ 1. Run 'appshot order --device [device]' to set the order
36
+ 2. Use arrow keys to reorder screenshots interactively
37
+ 3. Order is saved to .appshot/screenshot-order.json
38
+ 4. Run 'appshot export --order' to use the saved order
39
+
40
+ ${pc.bold('Smart Defaults:')}
41
+ The command automatically prioritizes common screenshot names:
42
+ • home/main/dashboard (first)
43
+ • features/content screens (middle)
44
+ • settings/about (last)
45
+ `)
46
+ .action(async (opts) => {
47
+ try {
48
+ // Handle show option
49
+ if (opts.show) {
50
+ await showCurrentOrder(opts.source, opts.lang);
51
+ return;
52
+ }
53
+ // Handle reset option
54
+ if (opts.reset) {
55
+ await resetOrder();
56
+ return;
57
+ }
58
+ // Handle remove prefixes option
59
+ if (opts.removePrefixes) {
60
+ await removePrefixes(opts.device, opts.source, opts.lang);
61
+ return;
62
+ }
63
+ // Handle apply option
64
+ if (opts.apply) {
65
+ if (!opts.device) {
66
+ console.error(pc.red('Error: --device is required with --apply'));
67
+ process.exit(1);
68
+ }
69
+ await applyOrderToFiles(opts.device, opts.source, opts.lang);
70
+ return;
71
+ }
72
+ // Interactive ordering mode
73
+ let device = opts.device;
74
+ if (!device) {
75
+ // Let user select device
76
+ const devices = await getAvailableDevices(opts.source, opts.lang);
77
+ if (devices.length === 0) {
78
+ console.error(pc.red('No screenshots found in the source directory'));
79
+ console.log(pc.dim(` Checked: ${path.join(opts.source, '*', opts.lang)}`));
80
+ process.exit(1);
81
+ }
82
+ // Build choices with screenshot counts
83
+ const choices = [];
84
+ for (const d of devices) {
85
+ const count = (await getAvailableScreenshots(d, opts.source, opts.lang)).length;
86
+ choices.push({
87
+ name: `${d} (${count} screenshots)`,
88
+ value: d
89
+ });
90
+ }
91
+ device = await select({
92
+ message: 'Select device to order screenshots for:',
93
+ choices
94
+ });
95
+ }
96
+ // Get screenshots for the device
97
+ const screenshots = await getAvailableScreenshots(device, opts.source, opts.lang);
98
+ if (screenshots.length === 0) {
99
+ console.error(pc.red(`No screenshots found for ${device}`));
100
+ console.log(pc.dim(` Checked: ${path.join(opts.source, device, opts.lang)}`));
101
+ process.exit(1);
102
+ }
103
+ // Load existing order or use smart defaults
104
+ const existingConfig = await loadOrderConfig();
105
+ const currentOrder = applyOrder(screenshots, device, existingConfig);
106
+ console.log(pc.cyan(`\nšŸ“± Ordering screenshots for ${device}`));
107
+ console.log(pc.dim(` Found ${screenshots.length} screenshots`));
108
+ // Interactive reordering using a simpler approach
109
+ const orderedScreenshots = await interactiveOrder(currentOrder);
110
+ // Save the new order (always save clean names without prefixes)
111
+ const orders = existingConfig?.orders || {};
112
+ // Remove any numeric prefixes before saving
113
+ const cleanOrderedScreenshots = orderedScreenshots.map(file => file.replace(/^\d+[-_.]/, ''));
114
+ orders[device] = cleanOrderedScreenshots;
115
+ await saveOrderConfig(orders);
116
+ console.log(pc.green('\nāœ“ Screenshot order saved!'));
117
+ displayOrder(orderedScreenshots, device);
118
+ // Ask if user wants to apply prefixes now
119
+ const shouldApply = await confirm({
120
+ message: 'Add numeric prefixes to files now?',
121
+ default: false
122
+ });
123
+ if (shouldApply) {
124
+ await applyOrderToFiles(device, opts.source, opts.lang);
125
+ }
126
+ else {
127
+ console.log(pc.dim('\nTo apply this order when exporting:'));
128
+ console.log(pc.cyan(' $ appshot export --order'));
129
+ }
130
+ }
131
+ catch (error) {
132
+ console.error(pc.red('Error:'), error);
133
+ process.exit(1);
134
+ }
135
+ });
136
+ return cmd;
137
+ }
138
+ /**
139
+ * Interactive ordering UI
140
+ */
141
+ async function interactiveOrder(screenshots) {
142
+ const ordered = [...screenshots];
143
+ let currentIndex = 0;
144
+ let done = false;
145
+ console.log('\n' + pc.bold('Reorder screenshots:'));
146
+ console.log(pc.dim(' ↑/↓: Navigate │ Space: Select │ ↑/↓: Move selected │ Enter: Done\n'));
147
+ while (!done) {
148
+ // Display current order
149
+ console.clear();
150
+ console.log('\n' + pc.bold('Screenshot Order:'));
151
+ console.log(pc.dim(' Use arrow keys to navigate, space to select/move, enter when done\n'));
152
+ ordered.forEach((file, index) => {
153
+ const num = String(index + 1).padStart(2, '0');
154
+ const prefix = index === currentIndex ? pc.cyan('→') : ' ';
155
+ const highlight = index === currentIndex ? pc.cyan(file) : file;
156
+ console.log(` ${prefix} ${pc.dim(num)}. ${highlight}`);
157
+ });
158
+ // Simple menu for now - will enhance later
159
+ const action = await select({
160
+ message: '\nChoose action:',
161
+ choices: [
162
+ { name: 'Move current item up', value: 'up', disabled: currentIndex === 0 },
163
+ { name: 'Move current item down', value: 'down', disabled: currentIndex === ordered.length - 1 },
164
+ { name: 'Jump to item...', value: 'jump' },
165
+ { name: 'Reset to alphabetical', value: 'reset' },
166
+ { name: 'Done - save this order', value: 'done' }
167
+ ]
168
+ });
169
+ switch (action) {
170
+ case 'up':
171
+ if (currentIndex > 0) {
172
+ [ordered[currentIndex - 1], ordered[currentIndex]] = [ordered[currentIndex], ordered[currentIndex - 1]];
173
+ currentIndex--;
174
+ }
175
+ break;
176
+ case 'down':
177
+ if (currentIndex < ordered.length - 1) {
178
+ [ordered[currentIndex], ordered[currentIndex + 1]] = [ordered[currentIndex + 1], ordered[currentIndex]];
179
+ currentIndex++;
180
+ }
181
+ break;
182
+ case 'jump':
183
+ const target = await select({
184
+ message: 'Select screenshot to jump to:',
185
+ choices: ordered.map((file, idx) => ({
186
+ name: `${String(idx + 1).padStart(2, '0')}. ${file}`,
187
+ value: idx
188
+ }))
189
+ });
190
+ currentIndex = target;
191
+ break;
192
+ case 'reset':
193
+ ordered.sort();
194
+ currentIndex = 0;
195
+ break;
196
+ case 'done':
197
+ done = true;
198
+ break;
199
+ }
200
+ }
201
+ return ordered;
202
+ }
203
+ /**
204
+ * Get available devices from source directory
205
+ */
206
+ async function getAvailableDevices(sourcePath, language) {
207
+ const devices = ['iphone', 'ipad', 'mac', 'watch'];
208
+ const available = [];
209
+ for (const device of devices) {
210
+ const screenshots = await getAvailableScreenshots(device, sourcePath, language);
211
+ if (screenshots.length > 0) {
212
+ available.push(device);
213
+ }
214
+ }
215
+ return available;
216
+ }
217
+ /**
218
+ * Show current order for all devices
219
+ */
220
+ async function showCurrentOrder(_sourcePath, _language) {
221
+ const config = await loadOrderConfig();
222
+ if (!config) {
223
+ console.log(pc.yellow('No order configuration found'));
224
+ console.log(pc.dim('Run "appshot order --device [device]" to create one'));
225
+ return;
226
+ }
227
+ console.log(pc.bold('\nCurrent screenshot order:'));
228
+ console.log(pc.dim(' Config: .appshot/screenshot-order.json'));
229
+ console.log(pc.dim(` Modified: ${new Date(config.modified).toLocaleString()}\n`));
230
+ for (const [device, order] of Object.entries(config.orders)) {
231
+ if (order && order.length > 0) {
232
+ displayOrder(order, device);
233
+ }
234
+ }
235
+ }
236
+ /**
237
+ * Reset order configuration
238
+ */
239
+ async function resetOrder() {
240
+ const configPath = path.join(process.cwd(), '.appshot/screenshot-order.json');
241
+ try {
242
+ await fs.unlink(configPath);
243
+ console.log(pc.green('āœ“ Order configuration reset'));
244
+ console.log(pc.dim('Screenshots will use smart defaults'));
245
+ }
246
+ catch (error) {
247
+ if (error.code === 'ENOENT') {
248
+ console.log(pc.yellow('No order configuration to reset'));
249
+ }
250
+ else {
251
+ throw error;
252
+ }
253
+ }
254
+ }
255
+ /**
256
+ * Apply order to files by adding numeric prefixes
257
+ */
258
+ async function applyOrderToFiles(device, sourcePath, language) {
259
+ const config = await loadOrderConfig();
260
+ const screenshots = await getAvailableScreenshots(device, sourcePath, language);
261
+ if (screenshots.length === 0) {
262
+ console.error(pc.red(`No screenshots found for ${device}`));
263
+ return;
264
+ }
265
+ const ordered = applyOrder(screenshots, device, config);
266
+ const devicePath = path.join(sourcePath, device, language);
267
+ console.log(pc.cyan(`\nApplying numeric prefixes to ${device} screenshots...`));
268
+ for (let i = 0; i < ordered.length; i++) {
269
+ const oldName = ordered[i];
270
+ const oldPath = path.join(devicePath, oldName);
271
+ // Remove existing prefix if present
272
+ const cleanName = oldName.replace(/^\d+[-_.]/, '');
273
+ const newName = `${String(i + 1).padStart(2, '0')}_${cleanName}`;
274
+ const newPath = path.join(devicePath, newName);
275
+ if (oldPath !== newPath) {
276
+ await fs.rename(oldPath, newPath);
277
+ console.log(pc.dim(` ${oldName} → ${newName}`));
278
+ }
279
+ }
280
+ console.log(pc.green(`āœ“ Applied order to ${ordered.length} screenshots`));
281
+ }
282
+ /**
283
+ * Remove numeric prefixes from files
284
+ */
285
+ async function removePrefixes(device, sourcePath, language) {
286
+ if (!device) {
287
+ console.error(pc.red('Error: --device is required with --remove-prefixes'));
288
+ process.exit(1);
289
+ }
290
+ const devicePath = path.join(sourcePath, device, language);
291
+ const files = await fs.readdir(devicePath);
292
+ const screenshots = files.filter(f => f.match(/\.(png|jpg|jpeg)$/i) && !f.startsWith('.'));
293
+ console.log(pc.cyan(`\nRemoving numeric prefixes from ${device} screenshots...`));
294
+ let renamed = 0;
295
+ for (const file of screenshots) {
296
+ if (/^\d+[-_.]/.test(file)) {
297
+ const oldPath = path.join(devicePath, file);
298
+ const newName = file.replace(/^\d+[-_.]/, '');
299
+ const newPath = path.join(devicePath, newName);
300
+ // Check if target already exists
301
+ try {
302
+ await fs.access(newPath);
303
+ console.log(pc.yellow(` ⚠ Cannot rename ${file} → ${newName} (file exists)`));
304
+ continue;
305
+ }
306
+ catch {
307
+ // File doesn't exist, safe to rename
308
+ }
309
+ await fs.rename(oldPath, newPath);
310
+ console.log(pc.dim(` ${file} → ${newName}`));
311
+ renamed++;
312
+ }
313
+ }
314
+ if (renamed > 0) {
315
+ console.log(pc.green(`āœ“ Removed prefixes from ${renamed} screenshots`));
316
+ }
317
+ else {
318
+ console.log(pc.yellow('No numeric prefixes found'));
319
+ }
320
+ }
321
+ //# sourceMappingURL=order.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"order.js","sourceRoot":"","sources":["../../src/commands/order.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { Command } from 'commander';
2
+ export declare const presetCommand: Command;
3
+ export declare const quickPresetCommand: Command;
4
+ export default function presetCmd(): Command;
5
+ //# sourceMappingURL=preset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset.d.ts","sourceRoot":"","sources":["../../src/commands/preset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuBpC,eAAO,MAAM,aAAa,SA0KtB,CAAC;AAGL,eAAO,MAAM,kBAAkB,SAmC3B,CAAC;AAEL,MAAM,CAAC,OAAO,UAAU,SAAS,YAEhC"}
@@ -0,0 +1,191 @@
1
+ import { Command } from 'commander';
2
+ import { existsSync, readFileSync, writeFileSync, readdirSync, mkdirSync } from 'fs';
3
+ import * as path from 'path';
4
+ import chalk from 'chalk';
5
+ import { templates } from '../templates/registry.js';
6
+ import { execFileSync } from 'child_process';
7
+ import { sanitizeDevices, sanitizeLanguages, sanitizePath, validateTemplateId, sanitizeCaption } from '../utils/validation.js';
8
+ export const presetCommand = new Command('preset')
9
+ .description('Apply template preset and build in one command')
10
+ .argument('<preset>', 'Preset name (modern, bold, minimal, elegant, corporate, playful, showcase, nerdy)')
11
+ .option('-c, --caption <text>', 'Add caption to all screenshots')
12
+ .option('-d, --devices <list>', 'Comma-separated device list (iphone,ipad,watch,mac)')
13
+ .option('-l, --langs <list>', 'Comma-separated language codes (en,es,fr,de,etc)')
14
+ .option('-o, --output <path>', 'Output directory', './final')
15
+ .option('--dry-run', 'Preview without building')
16
+ .option('-v, --verbose', 'Show detailed output')
17
+ .action(async (presetName, options) => {
18
+ try {
19
+ // Security: Validate template ID first
20
+ if (!validateTemplateId(presetName)) {
21
+ console.error(chalk.red(`āŒ Preset "${presetName}" not found`));
22
+ console.log('\nAvailable presets:');
23
+ templates.forEach((t) => {
24
+ console.log(` ${chalk.cyan(t.id.padEnd(12))} - ${t.name}`);
25
+ });
26
+ process.exit(1);
27
+ }
28
+ // Get template from registry (now guaranteed to exist)
29
+ const template = templates.find((t) => t.id === presetName);
30
+ // Load current config
31
+ const configPath = path.join(process.cwd(), '.appshot', 'config.json');
32
+ if (!existsSync(configPath)) {
33
+ console.error(chalk.red('āŒ No appshot project found. Run "appshot init" first.'));
34
+ process.exit(1);
35
+ }
36
+ if (options.dryRun) {
37
+ console.log(chalk.cyan('šŸ” Dry Run Mode - Preview Only\n'));
38
+ console.log(chalk.bold(`Preset: ${template.name}`));
39
+ console.log(`Description: ${template.description}`);
40
+ console.log(`Style: ${template.category}`);
41
+ if (template.background?.gradient) {
42
+ const colors = template.background.gradient.colors;
43
+ console.log(`Gradient: ${colors.join(' → ')}`);
44
+ }
45
+ const displayDevices = options.devices ? sanitizeDevices(options.devices) : 'all';
46
+ const displayLangs = options.langs ? sanitizeLanguages(options.langs) : 'en';
47
+ const displayOutput = options.output ? sanitizePath(options.output) : './final';
48
+ console.log(`\nDevices: ${displayDevices}`);
49
+ console.log(`Languages: ${displayLangs}`);
50
+ console.log(`Output: ${displayOutput}`);
51
+ if (options.caption) {
52
+ const sanitizedCaption = sanitizeCaption(options.caption);
53
+ console.log(`Caption: "${sanitizedCaption}"`);
54
+ }
55
+ console.log(chalk.gray('\nRun without --dry-run to build screenshots'));
56
+ return;
57
+ }
58
+ // Step 1: Apply template
59
+ if (options.verbose) {
60
+ console.log(chalk.gray('Applying template...'));
61
+ }
62
+ // Backup current config
63
+ const backupPath = path.join(process.cwd(), '.appshot', 'config.backup.json');
64
+ const currentConfig = JSON.parse(readFileSync(configPath, 'utf-8'));
65
+ writeFileSync(backupPath, JSON.stringify(currentConfig, null, 2));
66
+ // Apply template config
67
+ const templateConfig = template;
68
+ const newConfig = {
69
+ ...currentConfig,
70
+ background: templateConfig.background,
71
+ caption: templateConfig.caption,
72
+ devices: {
73
+ ...currentConfig.devices,
74
+ ...templateConfig.devices
75
+ }
76
+ };
77
+ // Override output if specified (with sanitization)
78
+ if (options.output) {
79
+ newConfig.output = sanitizePath(options.output);
80
+ }
81
+ writeFileSync(configPath, JSON.stringify(newConfig, null, 2));
82
+ console.log(chalk.green(`✨ Preset "${template.name}" applied`));
83
+ // Step 2: Add captions if provided
84
+ if (options.caption) {
85
+ if (options.verbose) {
86
+ console.log(chalk.gray('Adding captions...'));
87
+ }
88
+ const sanitizedCaption = sanitizeCaption(options.caption);
89
+ const deviceInput = options.devices ? sanitizeDevices(options.devices) : 'iphone,ipad,watch,mac';
90
+ const devices = deviceInput.split(',');
91
+ for (const device of devices) {
92
+ const captionFile = path.join(process.cwd(), '.appshot', 'captions', `${device}.json`);
93
+ // Get screenshots for this device
94
+ const screenshotDir = path.join(process.cwd(), 'screenshots', device.trim());
95
+ if (!existsSync(screenshotDir))
96
+ continue;
97
+ const screenshots = readdirSync(screenshotDir)
98
+ .filter((f) => /\.(png|jpg|jpeg)$/i.test(f));
99
+ if (screenshots.length > 0) {
100
+ // Create captions object with the provided caption for first screenshot
101
+ const captions = {};
102
+ captions[screenshots[0]] = sanitizedCaption;
103
+ // Ensure captions directory exists
104
+ mkdirSync(path.dirname(captionFile), { recursive: true });
105
+ writeFileSync(captionFile, JSON.stringify(captions, null, 2));
106
+ if (options.verbose) {
107
+ console.log(chalk.gray(` Added caption for ${device}`));
108
+ }
109
+ }
110
+ }
111
+ }
112
+ // Step 3: Build screenshots
113
+ console.log(chalk.cyan('\nšŸ“ø Building screenshots...\n'));
114
+ // Security: Build command args safely
115
+ const buildArgs = ['build'];
116
+ if (options.devices) {
117
+ const sanitizedDevices = sanitizeDevices(options.devices);
118
+ buildArgs.push('--devices', sanitizedDevices);
119
+ }
120
+ if (options.langs) {
121
+ const sanitizedLangs = sanitizeLanguages(options.langs);
122
+ buildArgs.push('--langs', sanitizedLangs);
123
+ }
124
+ if (options.verbose) {
125
+ console.log(chalk.gray(`Running: appshot ${buildArgs.join(' ')}`));
126
+ }
127
+ try {
128
+ execFileSync('appshot', buildArgs, {
129
+ stdio: options.verbose ? 'inherit' : 'pipe',
130
+ cwd: process.cwd()
131
+ });
132
+ console.log(chalk.green('\nāœ… Screenshots generated successfully!'));
133
+ console.log(chalk.gray(`Output: ${options.output || './final'}`));
134
+ }
135
+ catch (buildError) {
136
+ console.error(chalk.red('āŒ Build failed'));
137
+ if (buildError instanceof Error) {
138
+ console.error(chalk.gray(`Error: ${buildError.message}`));
139
+ }
140
+ if (!options.verbose) {
141
+ console.log(chalk.gray('Run with --verbose for details'));
142
+ }
143
+ process.exit(1);
144
+ }
145
+ }
146
+ catch (error) {
147
+ console.error(chalk.red('Error:'), error instanceof Error ? error.message : error);
148
+ process.exit(1);
149
+ }
150
+ });
151
+ // Also create a simpler alias
152
+ export const quickPresetCommand = new Command('qp')
153
+ .description('Quick preset (alias for preset)')
154
+ .argument('<preset>', 'Preset name')
155
+ .option('-c, --caption <text>', 'Caption text')
156
+ .option('-d, --devices <list>', 'Device list')
157
+ .action((preset, options) => {
158
+ // Security: Validate preset ID first
159
+ if (!validateTemplateId(preset)) {
160
+ console.error(chalk.red(`āŒ Invalid preset: ${preset}`));
161
+ process.exit(1);
162
+ }
163
+ // Build args safely
164
+ const args = ['preset', preset];
165
+ if (options.caption) {
166
+ try {
167
+ const sanitizedCaption = sanitizeCaption(options.caption);
168
+ args.push('--caption', sanitizedCaption);
169
+ }
170
+ catch (err) {
171
+ console.error(chalk.red(`āŒ ${err instanceof Error ? err.message : 'Invalid caption'}`));
172
+ process.exit(1);
173
+ }
174
+ }
175
+ if (options.devices) {
176
+ // Validate devices before passing
177
+ try {
178
+ const validDevices = sanitizeDevices(options.devices);
179
+ args.push('--devices', validDevices);
180
+ }
181
+ catch (err) {
182
+ console.error(chalk.red(`āŒ ${err instanceof Error ? err.message : 'Invalid devices'}`));
183
+ process.exit(1);
184
+ }
185
+ }
186
+ execFileSync('appshot', args, { stdio: 'inherit' });
187
+ });
188
+ export default function presetCmd() {
189
+ return presetCommand;
190
+ }
191
+ //# sourceMappingURL=preset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset.js","sourceRoot":"","sources":["../../src/commands/preset.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export default function quickstartCmd(): Command;
3
+ //# sourceMappingURL=quickstart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quickstart.d.ts","sourceRoot":"","sources":["../../src/commands/quickstart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBpC,MAAM,CAAC,OAAO,UAAU,aAAa,YAgMpC"}