builtwith-official-cli 1.5.3 → 1.5.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/README.md +5 -1
- package/lib/commands/lists.js +52 -2
- package/lib/commands/mcp.js +25 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -101,14 +101,18 @@ bw change lookup shopify.com,builtwith.com --since "last month"
|
|
|
101
101
|
### 📋 Lists
|
|
102
102
|
|
|
103
103
|
```bash
|
|
104
|
-
bw lists tech <tech> [--offset <n>] [--limit <n>]
|
|
104
|
+
bw lists tech <tech> [--other-techs <names>] [--country <codes>] [--since <date>] [--revenue <filter>] [--spend <filter>] [--offset <n>] [--limit <n>]
|
|
105
105
|
```
|
|
106
106
|
|
|
107
107
|
```bash
|
|
108
108
|
bw lists tech WordPress
|
|
109
109
|
bw lists tech Shopify --limit 50 --offset 100
|
|
110
|
+
bw lists tech Google-Analytics --other-techs Meta-Pixel
|
|
111
|
+
bw lists tech Shopify --revenue "100000|GT" --spend "100|GTE" --country US
|
|
110
112
|
```
|
|
111
113
|
|
|
114
|
+
Lists numeric filters use `number|operator`, where operator is `EQ`, `LT`, `LTE`, `GT`, or `GTE`. Supported attribute filters include `--spend`, `--revenue`, `--sku`, `--followers`, `--employees`, `--sitemap`, `--page-rank`, `--bw-rank`, `--tranco`, `--majestic`, `--bws`, `--ecat`, `--aim`, `--aio`, `--air`, and `--aiv`.
|
|
115
|
+
|
|
112
116
|
### 🔗 Relationships
|
|
113
117
|
|
|
114
118
|
```bash
|
package/lib/commands/lists.js
CHANGED
|
@@ -7,15 +7,45 @@ const { validateInput, validatePosInt } = require('../validate');
|
|
|
7
7
|
const output = require('../output');
|
|
8
8
|
const ora = require('ora');
|
|
9
9
|
|
|
10
|
+
const ATTRIBUTE_FILTERS = [
|
|
11
|
+
['spend', 'SPEND', 'Monthly technology spend filter, e.g. 100|GT'],
|
|
12
|
+
['revenue', 'REVENUE', 'Estimated ecommerce sales revenue filter, e.g. 100000|GT'],
|
|
13
|
+
['sku', 'SKU', 'Product count filter, e.g. 1000|GTE'],
|
|
14
|
+
['followers', 'FOLLOWERS', 'Followers filter, e.g. 5000|GTE'],
|
|
15
|
+
['employees', 'EMPLOYEES', 'Employee count filter, e.g. 50|GTE'],
|
|
16
|
+
['sitemap', 'SITEMAP', 'Sitemap URL count filter, e.g. 100|GT'],
|
|
17
|
+
['pageRank', 'PAGERANK', 'Page rank filter, e.g. 1000000|LT'],
|
|
18
|
+
['bwRank', 'BWRANK', 'BuiltWith rank filter, e.g. 50000|LTE'],
|
|
19
|
+
['tranco', 'TRANCO', 'Tranco rank filter, e.g. 100000|LTE'],
|
|
20
|
+
['majestic', 'MAJESTIC', 'Majestic rank filter, e.g. 100000|LTE'],
|
|
21
|
+
['bws', 'BWS', 'BuiltWith score filter, e.g. 50|GTE'],
|
|
22
|
+
['ecat', 'ECAT', 'Ecommerce category id filter, e.g. 123|EQ'],
|
|
23
|
+
['aim', 'AIM', 'AI maturity filter, e.g. 50|GTE'],
|
|
24
|
+
['aio', 'AIO', 'AI openness filter, e.g. 50|GTE'],
|
|
25
|
+
['air', 'AIR', 'AI readiness filter, e.g. 50|GTE'],
|
|
26
|
+
['aiv', 'AIV', 'AI visibility filter, e.g. 50|GTE'],
|
|
27
|
+
];
|
|
28
|
+
|
|
10
29
|
module.exports = function registerLists(program) {
|
|
11
30
|
const lists = program.command('lists').description('Technology lists');
|
|
12
31
|
|
|
13
|
-
lists
|
|
32
|
+
const techCommand = lists
|
|
14
33
|
.command('tech <tech>')
|
|
15
34
|
.description('Get list of sites using a technology')
|
|
35
|
+
.option('--other-techs <names>', 'Comma-separated additional required technologies')
|
|
36
|
+
.option('--country <codes>', 'Comma-separated country filters, e.g. US,CA')
|
|
37
|
+
.option('--since <date>', 'Date or relative time filter, e.g. "30 days ago"')
|
|
16
38
|
.option('--offset <n>', 'Result offset', '0')
|
|
17
39
|
.option('--limit <n>', 'Max results', '20')
|
|
18
|
-
.
|
|
40
|
+
.option('--meta', 'Include metadata')
|
|
41
|
+
.option('--all', 'Include historical sites');
|
|
42
|
+
|
|
43
|
+
for (const [, apiName, description] of ATTRIBUTE_FILTERS) {
|
|
44
|
+
const optionName = apiName.toLowerCase().replace('pagerank', 'page-rank').replace('bwrank', 'bw-rank');
|
|
45
|
+
techCommand.option(`--${optionName} <filter>`, description);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
techCommand.action(async (tech, cmdOpts) => {
|
|
19
49
|
const opts = program.opts();
|
|
20
50
|
if (opts.noColor) output.setNoColor(true);
|
|
21
51
|
const key = requireKey(opts.key);
|
|
@@ -23,6 +53,26 @@ module.exports = function registerLists(program) {
|
|
|
23
53
|
const offset = validatePosInt(cmdOpts.offset, 'offset');
|
|
24
54
|
const limit = validatePosInt(cmdOpts.limit, 'limit');
|
|
25
55
|
const params = { KEY: key, TECH: tech, OFFSET: offset, LIMIT: limit };
|
|
56
|
+
if (cmdOpts.otherTechs) {
|
|
57
|
+
validateInput(cmdOpts.otherTechs, 'otherTechs');
|
|
58
|
+
params.OTHERTECHS = cmdOpts.otherTechs;
|
|
59
|
+
}
|
|
60
|
+
if (cmdOpts.country) {
|
|
61
|
+
validateInput(cmdOpts.country, 'country');
|
|
62
|
+
params.COUNTRY = cmdOpts.country;
|
|
63
|
+
}
|
|
64
|
+
if (cmdOpts.since) {
|
|
65
|
+
validateInput(cmdOpts.since, 'since');
|
|
66
|
+
params.SINCE = cmdOpts.since;
|
|
67
|
+
}
|
|
68
|
+
if (cmdOpts.meta) params.META = 'yes';
|
|
69
|
+
if (cmdOpts.all) params.ALL = 'yes';
|
|
70
|
+
for (const [optionKey, apiName] of ATTRIBUTE_FILTERS) {
|
|
71
|
+
if (cmdOpts[optionKey]) {
|
|
72
|
+
validateInput(cmdOpts[optionKey], optionKey);
|
|
73
|
+
params[apiName] = cmdOpts[optionKey];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
26
76
|
|
|
27
77
|
if (opts.params) {
|
|
28
78
|
let extra;
|
package/lib/commands/mcp.js
CHANGED
|
@@ -51,6 +51,17 @@ const TOOLS = [
|
|
|
51
51
|
type: 'object',
|
|
52
52
|
properties: {
|
|
53
53
|
tech: { type: 'string', description: 'Technology name (e.g. "WordPress", "Shopify")' },
|
|
54
|
+
otherTechs: { type: 'string', description: 'Comma-separated additional required technologies, max 16' },
|
|
55
|
+
country: { type: 'string', description: 'Comma-separated country filters, e.g. US,CA' },
|
|
56
|
+
since: { type: 'string', description: 'Date or relative time filter, e.g. "30 days ago"' },
|
|
57
|
+
spend: { type: 'string', description: 'Monthly technology spend filter, e.g. 100|GT' },
|
|
58
|
+
revenue: { type: 'string', description: 'Estimated ecommerce sales revenue filter, e.g. 100000|GT' },
|
|
59
|
+
employees: { type: 'string', description: 'Employee count filter, e.g. 50|GTE' },
|
|
60
|
+
filters: {
|
|
61
|
+
type: 'object',
|
|
62
|
+
description: 'Additional Lists API attribute filters keyed by API parameter name, e.g. {"SKU":"1000|GTE","AIM":"50|GTE"}',
|
|
63
|
+
additionalProperties: { type: 'string' },
|
|
64
|
+
},
|
|
54
65
|
offset: { type: 'number', description: 'Result offset for pagination (default 0)' },
|
|
55
66
|
limit: { type: 'number', description: 'Number of results (default 20)' },
|
|
56
67
|
},
|
|
@@ -208,8 +219,20 @@ async function callTool(name, args, key, debug) {
|
|
|
208
219
|
if (args.since) params.SINCE = args.since;
|
|
209
220
|
return request('change', params, opts);
|
|
210
221
|
}
|
|
211
|
-
case 'lists_tech':
|
|
212
|
-
|
|
222
|
+
case 'lists_tech': {
|
|
223
|
+
const params = { KEY: key, TECH: args.tech, OTHERTECHS: args.otherTechs, OFFSET: args.offset || 0, LIMIT: args.limit || 20 };
|
|
224
|
+
if (args.country) params.COUNTRY = args.country;
|
|
225
|
+
if (args.since) params.SINCE = args.since;
|
|
226
|
+
if (args.spend) params.SPEND = args.spend;
|
|
227
|
+
if (args.revenue) params.REVENUE = args.revenue;
|
|
228
|
+
if (args.employees) params.EMPLOYEES = args.employees;
|
|
229
|
+
if (args.filters && typeof args.filters === 'object') {
|
|
230
|
+
for (const [filterKey, filterValue] of Object.entries(args.filters)) {
|
|
231
|
+
params[filterKey.toUpperCase()] = filterValue;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return request('lists', params, opts);
|
|
235
|
+
}
|
|
213
236
|
case 'relationships_lookup':
|
|
214
237
|
return request('relationships', { KEY: key, LOOKUP: args.domain }, opts);
|
|
215
238
|
case 'free_lookup':
|