@trawlme/cli 1.12.0 → 1.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.
@@ -91,6 +91,7 @@ scraps
91
91
  console.log(chalk.dim(` Last run: `) + lastRun(data));
92
92
  console.log(chalk.dim(` Updated: `) + new Date(data.updatedAt).toLocaleString());
93
93
  });
94
+ const VALID_TIERS = ['tier0', 'tier1', 'tier2', 'tier3', 'tier4'];
94
95
  // create
95
96
  scraps
96
97
  .command('create')
@@ -99,13 +100,20 @@ scraps
99
100
  .option('-u, --url <url>', 'Target URL')
100
101
  .option('-r, --request <request>', 'Request/query')
101
102
  .option('-d, --description <text>', 'Scrap description')
103
+ .option('--tier <tier>', `Force proxy tier (${VALID_TIERS.join('|')})`)
102
104
  .action(async (opts) => {
105
+ if (opts.tier !== undefined && !VALID_TIERS.includes(opts.tier)) {
106
+ console.log(chalk.red(`✗ Invalid --tier "${opts.tier}" (allowed: ${VALID_TIERS.join(', ')})`));
107
+ process.exitCode = 1;
108
+ return;
109
+ }
103
110
  const spinner = ora('Creating scrap…').start();
104
111
  const data = await api.post('/api/scraps', {
105
112
  title: opts.title,
106
113
  ...(opts.url && { url: opts.url }),
107
114
  request: opts.request || '',
108
115
  ...(opts.description !== undefined && { description: opts.description }),
116
+ ...(opts.tier !== undefined && { proxyTier: opts.tier }),
109
117
  });
110
118
  spinner.succeed(`Scrap created: ${chalk.bold(data._id)}`);
111
119
  console.log(chalk.dim(` Title: ${data.title}`));
@@ -126,8 +134,14 @@ scraps
126
134
  .option('--no-autofix', 'Disable AI Fix')
127
135
  .option('-p, --params <json>', 'Runtime params as JSON array of objects (e.g. \'[{"TRAWL.paramName":"value"}]\')')
128
136
  .option('--params-file <path>', 'Runtime params from a JSON file')
137
+ .option('--tier <tier>', `Force proxy tier (${VALID_TIERS.join('|')})`)
129
138
  .action(async (id, opts) => {
130
139
  validateObjectId(id);
140
+ if (opts.tier !== undefined && !VALID_TIERS.includes(opts.tier)) {
141
+ console.log(chalk.red(`✗ Invalid --tier "${opts.tier}" (allowed: ${VALID_TIERS.join(', ')})`));
142
+ process.exitCode = 1;
143
+ return;
144
+ }
131
145
  const body = {};
132
146
  if (opts.title !== undefined)
133
147
  body.title = opts.title;
@@ -174,6 +188,8 @@ scraps
174
188
  }
175
189
  body.params = parsed;
176
190
  }
191
+ if (opts.tier !== undefined)
192
+ body.proxyTier = opts.tier;
177
193
  if (Object.keys(body).length === 0) {
178
194
  console.log(chalk.yellow('Nothing to update. Provide at least one option.'));
179
195
  return;
@@ -396,6 +412,54 @@ account
396
412
  await api.delete(`/api/scraps/${id}/account/session`);
397
413
  spinner.succeed('Session cleared');
398
414
  });
415
+ // account session subcommand group
416
+ const accountSession = account
417
+ .command('session')
418
+ .description('Manage scrap account session cookies (flavour B BYO-cookies)');
419
+ // account session set
420
+ accountSession
421
+ .command('set <id>')
422
+ .description('Upload browser session cookies for a scrap (Puppeteer cookie JSON array)')
423
+ .requiredOption('-c, --cookies <file>', 'Path to a Puppeteer cookie JSON array file')
424
+ .action(async (id, opts) => {
425
+ validateObjectId(id);
426
+ const { existsSync, readFileSync } = await import('fs');
427
+ if (!existsSync(opts.cookies)) {
428
+ console.log(chalk.red(`✗ File not found: ${opts.cookies}`));
429
+ process.exitCode = 1;
430
+ return;
431
+ }
432
+ let cookies;
433
+ try {
434
+ const raw = readFileSync(opts.cookies, 'utf-8');
435
+ cookies = JSON.parse(raw);
436
+ }
437
+ catch (e) {
438
+ console.log(chalk.red(`✗ Failed to parse cookies file: ${e.message}`));
439
+ process.exitCode = 1;
440
+ return;
441
+ }
442
+ if (!Array.isArray(cookies)) {
443
+ console.log(chalk.red('✗ Cookies file must contain a JSON array'));
444
+ process.exitCode = 1;
445
+ return;
446
+ }
447
+ if (cookies.length === 0) {
448
+ console.log(chalk.red('✗ Cookies array must not be empty'));
449
+ process.exitCode = 1;
450
+ return;
451
+ }
452
+ if (!cookies.every((c) => c && typeof c.name === 'string' && typeof c.value === 'string')) {
453
+ console.log(chalk.red('✗ Each cookie must have a name (string) and value (string)'));
454
+ process.exitCode = 1;
455
+ return;
456
+ }
457
+ const spinner = ora('Uploading session cookies…').start();
458
+ const data = await api.put(`/api/scraps/${id}/account/session`, { cookies });
459
+ spinner.succeed(`Session cookies saved for scrap ${chalk.bold(id)}`);
460
+ const acc = data.account;
461
+ console.log(chalk.dim(' Session: ') + (acc.hasSession ? chalk.green('✓ active') : chalk.dim('none')));
462
+ });
399
463
  // account status
400
464
  account
401
465
  .command('status <id>')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trawlme/cli",
3
- "version": "1.12.0",
3
+ "version": "1.14.0",
4
4
  "description": "Trawl CLI — manage scraps from the terminal",
5
5
  "type": "module",
6
6
  "bin": {