@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.
- package/dist/commands/scraps.js +64 -0
- package/package.json +1 -1
package/dist/commands/scraps.js
CHANGED
|
@@ -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>')
|