diff --git a/docs/cli.md b/docs/cli.md index f7813f6..136f02c 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -69,8 +69,9 @@ builtwith domain "example.com,other.com" | `--noMetaData` | Exclude metadata | | `--noAttributeData` | Exclude attribute data | | `--noPII` | Exclude personally identifiable information | -| `--firstDetectedRange` | Filter by first detected date range | -| `--lastDetectedRange` | Filter by last detected date range | +| `--includeTrust` | Include Trust API data (uses an additional API credit) | +| `--firstDetectedRange` | Filter by first detected date range (`YYYY-MM-DD` or `YYYY-MM-DD\|YYYY-MM-DD`) | +| `--lastDetectedRange` | Filter by last detected date range (`YYYY-MM-DD` or `YYYY-MM-DD\|YYYY-MM-DD`) | ### `domainLive` diff --git a/docs/guide/library.md b/docs/guide/library.md index 927b4b9..fe1e9ea 100644 --- a/docs/guide/library.md +++ b/docs/guide/library.md @@ -60,8 +60,9 @@ const filtered = await client.domain("example.com", { | `noMetaData` | `boolean` | Exclude company metadata | | `noAttributeData` | `boolean` | Exclude attribute data | | `noPII` | `boolean` | Exclude personally identifiable information | -| `firstDetectedRange` | `string` | Filter by first detected date range | -| `lastDetectedRange` | `string` | Filter by last detected date range | +| `includeTrust` | `boolean` | Include Trust API data (uses an additional API credit) | +| `firstDetectedRange` | `string` | Filter by first detected date range (`YYYY-MM-DD` or `YYYY-MM-DD\|YYYY-MM-DD`) | +| `lastDetectedRange` | `string` | Filter by last detected date range (`YYYY-MM-DD` or `YYYY-MM-DD\|YYYY-MM-DD`) | ### `domainLive(lookup)` diff --git a/packages/builtwith-api/src/commands.ts b/packages/builtwith-api/src/commands.ts index ecf3892..9cce7df 100644 --- a/packages/builtwith-api/src/commands.ts +++ b/packages/builtwith-api/src/commands.ts @@ -54,13 +54,24 @@ export const commands: CommandDefinition[] = [ { name: "noMetaData", description: "Exclude metadata", type: "boolean", required: false }, { name: "noAttributeData", description: "Exclude attribute data", type: "boolean", required: false }, { name: "noPII", description: "Exclude personally identifiable information", type: "boolean", required: false }, + { + name: "includeTrust", + description: "Include Trust API data (uses an additional API credit)", + type: "boolean", + required: false, + }, { name: "firstDetectedRange", - description: "Filter by first detected date range", + description: "Filter by first detected date range (YYYY-MM-DD|YYYY-MM-DD)", + type: "string", + required: false, + }, + { + name: "lastDetectedRange", + description: "Filter by last detected date range (YYYY-MM-DD|YYYY-MM-DD)", type: "string", required: false, }, - { name: "lastDetectedRange", description: "Filter by last detected date range", type: "string", required: false }, ], execute: (client, args) => { const lookup = splitLookup(args.lookup); diff --git a/packages/builtwith-api/src/index.ts b/packages/builtwith-api/src/index.ts index 274a1bb..d94b95d 100644 --- a/packages/builtwith-api/src/index.ts +++ b/packages/builtwith-api/src/index.ts @@ -41,6 +41,7 @@ const DOMAIN_BOOLEANS: BooleanMapping = { noMetaData: "NOMETA", noAttributeData: "NOATTR", noPII: "NOPII", + includeTrust: "TRUST", }; /** diff --git a/packages/builtwith-api/src/schemas.ts b/packages/builtwith-api/src/schemas.ts index ede4f21..48f91b2 100644 --- a/packages/builtwith-api/src/schemas.ts +++ b/packages/builtwith-api/src/schemas.ts @@ -26,8 +26,8 @@ export const ClientOptionsSchema = z.strictObject({ */ export type ClientOptions = z.infer; -/** Matches YYYY-MM-DD or YYYY-MM-DD-YYYY-MM-DD date range format. */ -const dateRangePattern = /^\d{4}-\d{2}-\d{2}(-\d{4}-\d{2}-\d{2})?$/; +/** Matches YYYY-MM-DD or a pipe-joined YYYY-MM-DD|YYYY-MM-DD range (v23 FDRANGE/LDRANGE format). */ +const dateRangePattern = /^\d{4}-\d{2}-\d{2}(\|\d{4}-\d{2}-\d{2})?$/; /** Validation schema for {@link DomainParams}. */ export const DomainParamsSchema = z.strictObject({ @@ -37,8 +37,9 @@ export const DomainParamsSchema = z.strictObject({ noMetaData: z.boolean().optional(), noAttributeData: z.boolean().optional(), noPII: z.boolean().optional(), - firstDetectedRange: z.string().regex(dateRangePattern, "Expected YYYY-MM-DD or YYYY-MM-DD-YYYY-MM-DD").optional(), - lastDetectedRange: z.string().regex(dateRangePattern, "Expected YYYY-MM-DD or YYYY-MM-DD-YYYY-MM-DD").optional(), + includeTrust: z.boolean().optional(), + firstDetectedRange: z.string().regex(dateRangePattern, "Expected YYYY-MM-DD or YYYY-MM-DD|YYYY-MM-DD").optional(), + lastDetectedRange: z.string().regex(dateRangePattern, "Expected YYYY-MM-DD or YYYY-MM-DD|YYYY-MM-DD").optional(), }); /** * Optional parameters for the Domain API endpoint. @@ -171,8 +172,9 @@ const PathSchema = z.strictObject({ const MetaSchema = z.strictObject({ Majestic: z.number(), + Umbrella: z.number().optional(), Vertical: z.string(), - Social: z.array(z.string()), + Social: z.array(z.string()).optional(), CompanyName: z.string(), Telephones: z.array(z.string()), Emails: z.array(z.string()), @@ -205,14 +207,17 @@ const AttributesSchema = z.strictObject({ CDimensions: z.number(), CGoals: z.number(), CMetrics: z.number(), - Followers: z.number(), - Employees: z.number(), + Followers: z.number().optional(), + Employees: z.number().optional(), ProductCount: z.number().optional(), Revenue: z.number().optional(), PageRank: z.number().optional(), BWRank: z.number().optional(), Tranco: z.number().optional(), BWS: z.number().optional(), + EcommerceCategory: z.number().optional(), + TTFB: z.number().optional(), + SourceBytes: z.number().optional(), AIMaturity: z.number().optional(), AIOpenness: z.number().optional(), AIReadiness: z.number().optional(), diff --git a/packages/builtwith-api/test/params.test.ts b/packages/builtwith-api/test/params.test.ts index 7fb3d22..759958f 100644 --- a/packages/builtwith-api/test/params.test.ts +++ b/packages/builtwith-api/test/params.test.ts @@ -114,8 +114,12 @@ describe("date range validation", () => { expect(() => DomainParamsSchema.parse({ firstDetectedRange: "2024-01-15" })).not.toThrow(); }); - it("accepts YYYY-MM-DD-YYYY-MM-DD range format", () => { - expect(() => DomainParamsSchema.parse({ firstDetectedRange: "2020-01-01-2024-12-31" })).not.toThrow(); + it("accepts pipe-joined YYYY-MM-DD|YYYY-MM-DD range format", () => { + expect(() => DomainParamsSchema.parse({ firstDetectedRange: "2020-01-01|2024-12-31" })).not.toThrow(); + }); + + it("rejects the legacy dash-joined range format", () => { + expect(() => DomainParamsSchema.parse({ firstDetectedRange: "2020-01-01-2024-12-31" })).toThrow(); }); it("accepts lastDetectedRange with valid format", () => { diff --git a/packages/builtwith-api/test/schemas.test.ts b/packages/builtwith-api/test/schemas.test.ts index 1dcf803..06bad5d 100644 --- a/packages/builtwith-api/test/schemas.test.ts +++ b/packages/builtwith-api/test/schemas.test.ts @@ -86,6 +86,7 @@ describe("DomainResponseSchema", () => { }, Meta: { Majestic: 12345, + Umbrella: 6423, Vertical: "Technology", Social: ["https://twitter.com/example"], CompanyName: "Example Inc",