fix(core): parse Kijiji StandardListing records

This commit is contained in:
2026-04-28 21:57:10 -04:00
parent 2a5701aeb9
commit 11dce39428
2 changed files with 180 additions and 8 deletions

View File

@@ -46,6 +46,17 @@ interface ApolloSearchItem {
[k: string]: unknown;
}
type ListingAttribute = {
canonicalName?: string;
canonicalValues?: string[];
};
type ListingAttributes =
| ListingAttribute[]
| {
all?: ListingAttribute[];
};
interface ApolloListingRoot {
url?: string;
title?: string;
@@ -68,7 +79,7 @@ interface ApolloListingRoot {
adSource?: string;
flags?: { topAd?: boolean; priceDrop?: boolean };
posterInfo?: { posterId?: string; rating?: number };
attributes?: Array<{ canonicalName?: string; canonicalValues?: string[] }>;
attributes?: ListingAttributes;
[k: string]: unknown;
}
@@ -323,13 +334,22 @@ function findApolloListingKey(
predicate: (value: Record<string, unknown>) => boolean,
): string | undefined {
return Object.keys(apolloState).find((key) => {
if (!key.startsWith("Listing:")) return false;
if (!isListingRecordKey(key)) return false;
const value = apolloState[key];
return isRecord(value) && predicate(value);
});
}
function isListingRecordKey(key: string): boolean {
return key.startsWith("Listing:") || key.startsWith("StandardListing:");
}
function getListingAttributes(attributes: ListingAttributes | undefined) {
if (Array.isArray(attributes)) return attributes;
return attributes?.all ?? [];
}
/**
* Slugifies a string for Kijiji search URLs
*/
@@ -532,7 +552,7 @@ export function parseSearch(
const results: SearchListing[] = [];
for (const [key, value] of Object.entries(apolloState)) {
if (!key.startsWith("Listing:")) continue;
if (!isListingRecordKey(key)) continue;
if (!isRecord(value)) continue;
const item = value as ApolloSearchItem;
@@ -689,11 +709,9 @@ export async function parseDetailedListing(
// Extract attributes as key-value pairs
const attributeMap: Record<string, string[]> = {};
if (Array.isArray(attributes)) {
for (const attr of attributes) {
if (attr?.canonicalName && Array.isArray(attr.canonicalValues)) {
attributeMap[attr.canonicalName] = attr.canonicalValues;
}
for (const attr of getListingAttributes(attributes)) {
if (attr.canonicalName && Array.isArray(attr.canonicalValues)) {
attributeMap[attr.canonicalName] = attr.canonicalValues;
}
}