builtwith-api 3.1.0 → 3.2.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/cli.js CHANGED
@@ -15,6 +15,7 @@ var ResponseFormatSchema = z.enum(["xml", "json", "txt", "csv", "tsv"]);
15
15
  var ClientOptionsSchema = z.strictObject({
16
16
  responseFormat: ResponseFormatSchema.optional()
17
17
  });
18
+ var dateRangePattern = /^\d{4}-\d{2}-\d{2}(-\d{4}-\d{2}-\d{2})?$/;
18
19
  var DomainParamsSchema = z.strictObject({
19
20
  hideAll: z.boolean().optional(),
20
21
  hideDescriptionAndLinks: z.boolean().optional(),
@@ -22,8 +23,8 @@ var DomainParamsSchema = z.strictObject({
22
23
  noMetaData: z.boolean().optional(),
23
24
  noAttributeData: z.boolean().optional(),
24
25
  noPII: z.boolean().optional(),
25
- firstDetectedRange: z.string().optional(),
26
- lastDetectedRange: z.string().optional()
26
+ firstDetectedRange: z.string().regex(dateRangePattern, "Expected YYYY-MM-DD or YYYY-MM-DD-YYYY-MM-DD").optional(),
27
+ lastDetectedRange: z.string().regex(dateRangePattern, "Expected YYYY-MM-DD or YYYY-MM-DD-YYYY-MM-DD").optional()
27
28
  });
28
29
  var ListsParamsSchema = z.strictObject({
29
30
  includeMetaData: z.boolean().optional(),
@@ -42,21 +43,18 @@ var TrustParamsSchema = z.strictObject({
42
43
  live: z.boolean().optional()
43
44
  });
44
45
  var SingleLookupSchema = z.string().min(1);
45
- var MultiLookupSchema = z.union([
46
- z.string().min(1),
47
- z.array(z.string().min(1)).min(1).max(16)
48
- ]);
49
- var FreeResponseSchema = z.object({
46
+ var MultiLookupSchema = z.union([z.string().min(1), z.array(z.string().min(1)).min(1).max(16)]);
47
+ var FreeResponseSchema = z.strictObject({
50
48
  domain: z.string(),
51
49
  first: z.number(),
52
50
  last: z.number(),
53
- groups: z.array(z.object({
51
+ groups: z.array(z.strictObject({
54
52
  name: z.string(),
55
53
  live: z.number(),
56
54
  dead: z.number(),
57
55
  latest: z.number(),
58
56
  oldest: z.number(),
59
- categories: z.array(z.object({
57
+ categories: z.array(z.strictObject({
60
58
  live: z.number(),
61
59
  dead: z.number(),
62
60
  latest: z.number(),
@@ -65,7 +63,7 @@ var FreeResponseSchema = z.object({
65
63
  }))
66
64
  }))
67
65
  });
68
- var TechnologySchema = z.object({
66
+ var TechnologySchema = z.strictObject({
69
67
  Name: z.string(),
70
68
  Description: z.string(),
71
69
  Link: z.string(),
@@ -76,7 +74,7 @@ var TechnologySchema = z.object({
76
74
  IsPremium: z.string(),
77
75
  Categories: z.array(z.string()).optional()
78
76
  });
79
- var PathSchema = z.object({
77
+ var PathSchema = z.strictObject({
80
78
  Technologies: z.array(TechnologySchema),
81
79
  FirstIndexed: z.number(),
82
80
  LastIndexed: z.number(),
@@ -84,7 +82,7 @@ var PathSchema = z.object({
84
82
  Url: z.string(),
85
83
  SubDomain: z.string()
86
84
  });
87
- var MetaSchema = z.object({
85
+ var MetaSchema = z.strictObject({
88
86
  Majestic: z.number(),
89
87
  Vertical: z.string(),
90
88
  Social: z.array(z.string()),
@@ -95,7 +93,7 @@ var MetaSchema = z.object({
95
93
  State: z.string(),
96
94
  Postcode: z.string(),
97
95
  Country: z.string(),
98
- Names: z.array(z.object({
96
+ Names: z.array(z.strictObject({
99
97
  Name: z.string(),
100
98
  Type: z.number(),
101
99
  Level: z.string(),
@@ -104,7 +102,7 @@ var MetaSchema = z.object({
104
102
  ARank: z.number(),
105
103
  QRank: z.number()
106
104
  });
107
- var AttributesSchema = z.object({
105
+ var AttributesSchema = z.strictObject({
108
106
  MJRank: z.number(),
109
107
  MJTLDRank: z.number(),
110
108
  RefSN: z.number(),
@@ -118,10 +116,10 @@ var AttributesSchema = z.object({
118
116
  CGoals: z.number(),
119
117
  CMetrics: z.number()
120
118
  });
121
- var DomainResponseSchema = z.object({
122
- Results: z.array(z.object({
123
- Result: z.object({
124
- SpendHistory: z.array(z.object({
119
+ var DomainResponseSchema = z.strictObject({
120
+ Results: z.array(z.strictObject({
121
+ Result: z.strictObject({
122
+ SpendHistory: z.array(z.strictObject({
125
123
  D: z.number(),
126
124
  S: z.number()
127
125
  })),
@@ -138,9 +136,9 @@ var DomainResponseSchema = z.object({
138
136
  })),
139
137
  Errors: z.array(z.string())
140
138
  });
141
- var ListsResponseSchema = z.object({
139
+ var ListsResponseSchema = z.strictObject({
142
140
  NextOffset: z.string(),
143
- Results: z.array(z.object({
141
+ Results: z.array(z.strictObject({
144
142
  D: z.string(),
145
143
  FI: z.number().optional(),
146
144
  LI: z.number().optional(),
@@ -159,15 +157,15 @@ var ListsResponseSchema = z.object({
159
157
  Country: z.string().optional()
160
158
  }))
161
159
  });
162
- var RelationshipsResponseSchema = z.object({
163
- Relationships: z.array(z.object({
160
+ var RelationshipsResponseSchema = z.strictObject({
161
+ Relationships: z.array(z.strictObject({
164
162
  Domain: z.string(),
165
- Identifiers: z.array(z.object({
163
+ Identifiers: z.array(z.strictObject({
166
164
  Value: z.string(),
167
165
  Type: z.string(),
168
166
  First: z.number(),
169
167
  Last: z.number(),
170
- Matches: z.array(z.object({
168
+ Matches: z.array(z.strictObject({
171
169
  Domain: z.string(),
172
170
  First: z.number(),
173
171
  Last: z.number(),
@@ -181,14 +179,14 @@ var RelationshipsResponseSchema = z.object({
181
179
  next_skip: z.number(),
182
180
  more_results: z.boolean()
183
181
  });
184
- var KeywordsResponseSchema = z.object({
185
- Keywords: z.array(z.object({
182
+ var KeywordsResponseSchema = z.strictObject({
183
+ Keywords: z.array(z.strictObject({
186
184
  Domain: z.string(),
187
185
  Keywords: z.array(z.string())
188
186
  }))
189
187
  });
190
- var TrendsResponseSchema = z.object({
191
- Tech: z.object({
188
+ var TrendsResponseSchema = z.strictObject({
189
+ Tech: z.strictObject({
192
190
  icon: z.string(),
193
191
  categories: z.array(z.string()),
194
192
  tag: z.string(),
@@ -197,7 +195,7 @@ var TrendsResponseSchema = z.object({
197
195
  description: z.string(),
198
196
  link: z.string(),
199
197
  trends_link: z.string(),
200
- coverage: z.object({
198
+ coverage: z.strictObject({
201
199
  ten_k: z.number(),
202
200
  hundred_k: z.number(),
203
201
  milly: z.number(),
@@ -206,7 +204,7 @@ var TrendsResponseSchema = z.object({
206
204
  })
207
205
  })
208
206
  });
209
- var CompanyToUrlResponseSchema = z.array(z.object({
207
+ var CompanyToUrlResponseSchema = z.array(z.strictObject({
210
208
  Domain: z.string(),
211
209
  CompanyName: z.string(),
212
210
  Spend: z.number(),
@@ -219,9 +217,9 @@ var CompanyToUrlResponseSchema = z.array(z.object({
219
217
  City: z.string(),
220
218
  Socials: z.array(z.string())
221
219
  }));
222
- var TrustResponseSchema = z.object({
220
+ var TrustResponseSchema = z.strictObject({
223
221
  Domain: z.string(),
224
- DBRecord: z.object({
222
+ DBRecord: z.strictObject({
225
223
  EarliestRecord: z.number(),
226
224
  LatestUpdate: z.number(),
227
225
  PremiumTechs: z.number(),
@@ -237,18 +235,18 @@ var TrustResponseSchema = z.object({
237
235
  LiveRecord: z.object({}).passthrough().nullable(),
238
236
  Status: z.number()
239
237
  });
240
- var TagsResponseSchema = z.array(z.object({
238
+ var TagsResponseSchema = z.array(z.strictObject({
241
239
  Value: z.string(),
242
- Matches: z.array(z.object({
240
+ Matches: z.array(z.strictObject({
243
241
  Domain: z.string(),
244
242
  First: z.string(),
245
243
  Last: z.string()
246
244
  }))
247
245
  }));
248
- var RecommendationsResponseSchema = z.array(z.object({
246
+ var RecommendationsResponseSchema = z.array(z.strictObject({
249
247
  Domain: z.string(),
250
248
  Compiled: z.string(),
251
- Recommendations: z.array(z.object({
249
+ Recommendations: z.array(z.strictObject({
252
250
  link: z.string(),
253
251
  name: z.string(),
254
252
  tag: z.string(),
@@ -257,20 +255,20 @@ var RecommendationsResponseSchema = z.array(z.object({
257
255
  match: z.number()
258
256
  }))
259
257
  }));
260
- var RedirectsResponseSchema = z.object({
258
+ var RedirectsResponseSchema = z.strictObject({
261
259
  Lookup: z.string(),
262
- Inbound: z.array(z.object({
260
+ Inbound: z.array(z.strictObject({
263
261
  Domain: z.string(),
264
262
  FirstDetected: z.string(),
265
263
  LastDetected: z.string()
266
264
  })),
267
- Outbound: z.array(z.object({
265
+ Outbound: z.array(z.strictObject({
268
266
  Domain: z.string(),
269
267
  FirstDetected: z.string(),
270
268
  LastDetected: z.string()
271
269
  }))
272
270
  });
273
- var ProductResponseSchema = z.object({
271
+ var ProductResponseSchema = z.strictObject({
274
272
  query: z.string(),
275
273
  is_more: z.boolean(),
276
274
  page: z.number(),
@@ -282,9 +280,9 @@ var ProductResponseSchema = z.object({
282
280
  remaining: z.number(),
283
281
  used_this_query: z.number(),
284
282
  next_page: z.string(),
285
- shops: z.array(z.object({
283
+ shops: z.array(z.strictObject({
286
284
  Domain: z.string(),
287
- Products: z.array(z.object({
285
+ Products: z.array(z.strictObject({
288
286
  Title: z.string(),
289
287
  Url: z.string(),
290
288
  Indexed: z.string(),
@@ -299,10 +297,7 @@ var ProductResponseSchema = z.object({
299
297
  // src/params.ts
300
298
  var toQueryString = (params) => Object.entries(params).filter((entry) => entry[1] !== undefined).map(([k, v]) => `${k}=${encodeURIComponent(v).replace(/%2C/gi, ",")}`).join("&");
301
299
  var booleanFlag = (value) => value ? "yes" : undefined;
302
- var booleanParams = (params, mapping) => Object.fromEntries(Object.entries(mapping).map(([jsKey, apiKey]) => [
303
- apiKey,
304
- booleanFlag(params?.[jsKey])
305
- ]));
300
+ var booleanParams = (params, mapping) => Object.fromEntries(Object.entries(mapping).map(([jsKey, apiKey]) => [apiKey, booleanFlag(params?.[jsKey])]));
306
301
  var cleanWords = (words) => words ? words.split(",").map((w) => w.trim()).join(",") : undefined;
307
302
  var buildURL = (apiKey, format, path, params, subdomain = "api") => {
308
303
  const base = `https://${subdomain}.builtwith.com/${path}/api.${format}?KEY=${apiKey}`;
@@ -470,28 +465,6 @@ function createClient(apiKey, moduleParams = {}) {
470
465
  };
471
466
  }
472
467
 
473
- // src/errors.ts
474
- import { z as z2 } from "zod/v4";
475
- function formatError(err) {
476
- if (err instanceof z2.ZodError) {
477
- const fields = err.issues.map((i) => {
478
- const path = i.path.length > 0 ? i.path.join(".") : "response";
479
- return ` ${path}: ${i.message}`;
480
- });
481
- return `BuiltWith API returned an unexpected response:
482
- ${fields.join(`
483
- `)}`;
484
- }
485
- if (err instanceof Error) {
486
- return err.message;
487
- }
488
- return String(err);
489
- }
490
-
491
- // src/cli.ts
492
- import { createRequire } from "node:module";
493
- import { parseArgs } from "node:util";
494
-
495
468
  // src/commands.ts
496
469
  function splitLookup(value) {
497
470
  const str = String(value);
@@ -501,23 +474,36 @@ var commands = [
501
474
  {
502
475
  name: "free",
503
476
  description: "Free lookup — basic technology profile for a domain",
504
- args: [
505
- { name: "lookup", description: "Domain to look up", type: "string", required: true }
506
- ],
477
+ args: [{ name: "lookup", description: "Domain to look up", type: "string", required: true }],
507
478
  execute: (client, args) => client.free(String(args.lookup))
508
479
  },
509
480
  {
510
481
  name: "domain",
511
482
  description: "Detailed technology profile for one or more domains (comma-separated)",
512
483
  args: [
513
- { name: "lookup", description: "Domain(s) to look up (comma-separated for multiple)", type: "string", required: true },
484
+ {
485
+ name: "lookup",
486
+ description: "Domain(s) to look up (comma-separated for multiple)",
487
+ type: "string",
488
+ required: true
489
+ },
514
490
  { name: "hideAll", description: "Hide description text and links", type: "boolean", required: false },
515
- { name: "hideDescriptionAndLinks", description: "Hide description and links only", type: "boolean", required: false },
491
+ {
492
+ name: "hideDescriptionAndLinks",
493
+ description: "Hide description and links only",
494
+ type: "boolean",
495
+ required: false
496
+ },
516
497
  { name: "onlyLiveTechnologies", description: "Only return live technologies", type: "boolean", required: false },
517
498
  { name: "noMetaData", description: "Exclude metadata", type: "boolean", required: false },
518
499
  { name: "noAttributeData", description: "Exclude attribute data", type: "boolean", required: false },
519
500
  { name: "noPII", description: "Exclude personally identifiable information", type: "boolean", required: false },
520
- { name: "firstDetectedRange", description: "Filter by first detected date range", type: "string", required: false },
501
+ {
502
+ name: "firstDetectedRange",
503
+ description: "Filter by first detected date range",
504
+ type: "string",
505
+ required: false
506
+ },
521
507
  { name: "lastDetectedRange", description: "Filter by last detected date range", type: "string", required: false }
522
508
  ],
523
509
  execute: (client, args) => {
@@ -544,7 +530,12 @@ var commands = [
544
530
  name: "relationships",
545
531
  description: "Find related domains via shared identifiers",
546
532
  args: [
547
- { name: "lookup", description: "Domain(s) to look up (comma-separated for multiple)", type: "string", required: true }
533
+ {
534
+ name: "lookup",
535
+ description: "Domain(s) to look up (comma-separated for multiple)",
536
+ type: "string",
537
+ required: true
538
+ }
548
539
  ],
549
540
  execute: (client, args) => client.relationships(splitLookup(args.lookup))
550
541
  },
@@ -552,7 +543,12 @@ var commands = [
552
543
  name: "keywords",
553
544
  description: "Get keywords for one or more domains",
554
545
  args: [
555
- { name: "lookup", description: "Domain(s) to look up (comma-separated for multiple)", type: "string", required: true }
546
+ {
547
+ name: "lookup",
548
+ description: "Domain(s) to look up (comma-separated for multiple)",
549
+ type: "string",
550
+ required: true
551
+ }
556
552
  ],
557
553
  execute: (client, args) => client.keywords(splitLookup(args.lookup))
558
554
  },
@@ -584,9 +580,7 @@ var commands = [
584
580
  {
585
581
  name: "domainLive",
586
582
  description: "Live technology lookup for a domain",
587
- args: [
588
- { name: "lookup", description: "Domain to look up", type: "string", required: true }
589
- ],
583
+ args: [{ name: "lookup", description: "Domain to look up", type: "string", required: true }],
590
584
  execute: (client, args) => client.domainLive(String(args.lookup))
591
585
  },
592
586
  {
@@ -605,37 +599,89 @@ var commands = [
605
599
  {
606
600
  name: "tags",
607
601
  description: "Get tracking/analytics tags for a domain",
608
- args: [
609
- { name: "lookup", description: "Domain to look up", type: "string", required: true }
610
- ],
602
+ args: [{ name: "lookup", description: "Domain to look up", type: "string", required: true }],
611
603
  execute: (client, args) => client.tags(String(args.lookup))
612
604
  },
613
605
  {
614
606
  name: "recommendations",
615
607
  description: "Get technology recommendations for a domain",
616
- args: [
617
- { name: "lookup", description: "Domain to look up", type: "string", required: true }
618
- ],
608
+ args: [{ name: "lookup", description: "Domain to look up", type: "string", required: true }],
619
609
  execute: (client, args) => client.recommendations(String(args.lookup))
620
610
  },
621
611
  {
622
612
  name: "redirects",
623
613
  description: "Get redirect chains for a domain",
624
- args: [
625
- { name: "lookup", description: "Domain to look up", type: "string", required: true }
626
- ],
614
+ args: [{ name: "lookup", description: "Domain to look up", type: "string", required: true }],
627
615
  execute: (client, args) => client.redirects(String(args.lookup))
628
616
  },
629
617
  {
630
618
  name: "product",
631
619
  description: "Search for products across e-commerce sites",
632
- args: [
633
- { name: "query", description: "Product search query", type: "string", required: true }
634
- ],
620
+ args: [{ name: "query", description: "Product search query", type: "string", required: true }],
635
621
  execute: (client, args) => client.product(String(args.query))
636
622
  }
637
623
  ];
638
624
 
625
+ // src/errors.ts
626
+ import { z as z2 } from "zod/v4";
627
+ function formatError(err) {
628
+ if (err instanceof z2.ZodError) {
629
+ const fields = err.issues.map((i) => {
630
+ const path = i.path.length > 0 ? i.path.join(".") : "response";
631
+ return ` ${path}: ${i.message}`;
632
+ });
633
+ return `BuiltWith API returned an unexpected response:
634
+ ${fields.join(`
635
+ `)}`;
636
+ }
637
+ if (err instanceof Error) {
638
+ return err.message;
639
+ }
640
+ return String(err);
641
+ }
642
+
643
+ // src/cli.ts
644
+ import { createRequire } from "node:module";
645
+ import { parseArgs } from "node:util";
646
+
647
+ // src/format.ts
648
+ function formatTable(data, indent = 0) {
649
+ const pad = " ".repeat(indent);
650
+ if (data === null || data === undefined)
651
+ return `${pad}(none)`;
652
+ if (typeof data !== "object")
653
+ return `${pad}${data}`;
654
+ if (Array.isArray(data)) {
655
+ if (data.length === 0)
656
+ return `${pad}(empty)`;
657
+ const allFlatObjects = data.every((item) => typeof item === "object" && item !== null && !Array.isArray(item) && Object.values(item).every((v) => v === null || typeof v !== "object"));
658
+ if (allFlatObjects) {
659
+ const keys = [...new Set(data.flatMap((item) => Object.keys(item)))];
660
+ const widths = keys.map((k) => Math.max(k.length, ...data.map((item) => String(item[k] ?? "").length)));
661
+ const header = keys.map((k, i) => k.padEnd(widths[i])).join(" ");
662
+ const separator = keys.map((_, i) => "─".repeat(widths[i])).join(" ");
663
+ const rows = data.map((item) => keys.map((k, i) => String(item[k] ?? "").padEnd(widths[i])).join(" "));
664
+ return [pad + header, pad + separator, ...rows.map((r) => pad + r)].join(`
665
+ `);
666
+ }
667
+ return data.map((item, i) => `${pad}[${i}]
668
+ ${formatTable(item, indent + 1)}`).join(`
669
+ `);
670
+ }
671
+ const entries = Object.entries(data);
672
+ if (entries.length === 0)
673
+ return `${pad}(empty)`;
674
+ const maxKey = Math.max(...entries.map(([k]) => k.length));
675
+ return entries.map(([key, value]) => {
676
+ if (typeof value === "object" && value !== null) {
677
+ return `${pad}${key}:
678
+ ${formatTable(value, indent + 1)}`;
679
+ }
680
+ return `${pad}${key.padEnd(maxKey)} ${value}`;
681
+ }).join(`
682
+ `);
683
+ }
684
+
639
685
  // src/cli.ts
640
686
  var require2 = createRequire(import.meta.url);
641
687
  var { version } = require2("../package.json");
@@ -647,11 +693,13 @@ ${commands.map((c) => ` ${c.name.padEnd(16)} ${c.description}`).join(`
647
693
 
648
694
  Options:
649
695
  --api-key <key> BuiltWith API key (or set BUILTWITH_API_KEY env var)
696
+ --table Pretty-print output as a readable table instead of JSON
650
697
  --version Show version number
651
698
  --help Show help
652
699
 
653
700
  Examples:
654
701
  builtwith free example.com
702
+ builtwith free example.com --table
655
703
  builtwith domain example.com --hideAll --onlyLiveTechnologies
656
704
  builtwith domain "example.com,other.com"
657
705
  builtwith lists Shopify --since 2024-01-01
@@ -701,7 +749,8 @@ function run() {
701
749
  }
702
750
  const flagArgs = cmd.args.filter((a) => !a.required);
703
751
  const options = {
704
- "api-key": { type: "string" }
752
+ "api-key": { type: "string" },
753
+ table: { type: "boolean" }
705
754
  };
706
755
  for (const f of flagArgs) {
707
756
  options[f.name] = { type: f.type === "boolean" ? "boolean" : "string" };
@@ -711,6 +760,7 @@ function run() {
711
760
  options,
712
761
  strict: false
713
762
  });
763
+ const useTable = Boolean(values.table);
714
764
  const apiKey = values["api-key"] || process.env.BUILTWITH_API_KEY;
715
765
  if (!apiKey) {
716
766
  console.error("Error: pass --api-key or set BUILTWITH_API_KEY environment variable.");
@@ -731,7 +781,11 @@ function run() {
731
781
  }
732
782
  const client = createClient(apiKey);
733
783
  cmd.execute(client, args).then((result) => {
734
- console.log(JSON.stringify(result, null, 2));
784
+ if (useTable) {
785
+ console.log(formatTable(result));
786
+ } else {
787
+ console.log(JSON.stringify(result, null, 2));
788
+ }
735
789
  }).catch((err) => {
736
790
  console.error(formatError(err));
737
791
  process.exit(1);
@@ -739,4 +793,4 @@ function run() {
739
793
  }
740
794
  run();
741
795
 
742
- //# debugId=D76DF713FC3000FE64756E2164756E21
796
+ //# debugId=6C78BC6092EC44B564756E2164756E21