@rackbops/docket-types 0.11.1 → 0.13.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/README.md CHANGED
@@ -201,7 +201,11 @@ The tracker's task types, built on `@rackbops/docket-core`'s contract. Shipped s
201
201
  Fetch port, never eBay), `bggSource` (BGG's XML API, with the host's token) and `inboxSource`
202
202
  (listings the host stored for the watch's inbox key: alert emails, or searches someone ran in
203
203
  their own browser and sent in; `submittedListing` cleans each one, and the judge opens no
204
- page for such a watch).
204
+ page for such a watch) and `shopifySource` (new copies in stock at Shopify stores, from
205
+ Shopify's catalog search through Firecrawl's Alexandria, 5 credits a look; a product counts only
206
+ when every word of the search is in its title, and the judge opens no store for it) and
207
+ `ebaySource` (eBay listings from eBay's own Browse API, with the host's eBay app token; the
208
+ judge opens no eBay page for it).
205
209
  - `wantjudge` (category 2, plan 5.4, item 63): the same watch on the execute lane. New listings
206
210
  are read in plain code (no charge), then one Job has the model judge each one and its seller
207
211
  (WebFetch only on the watch's own host, never WebSearch or the runner's files; 12 turns,
@@ -216,6 +220,21 @@ host:
216
220
 
217
221
  - its Fetch port refuses any hop to eBay when a read carries the `NEVER_EBAY` header, and does
218
222
  not send that header on;
223
+ - `shopifySource(scrape)` gets a `scrape(request)` that sends `request` as the `alexandria` field
224
+ of Firecrawl's `POST https://api.firecrawl.dev/v2/scrape` with the host's own key, and hands back
225
+ the HTTP status and the parsed JSON body (bounded in time and size). The watch's `target` is
226
+ the words to search for; its top price and currency narrow the search itself. Each look is
227
+ paid for (5 credits), and the type sets no floor on how often a `poll` runs, so the host keeps
228
+ a Shopify watch's interval long (the tracker's floor is a day);
229
+ - `ebaySource(browse)` gets a `browse(request)` that sends `GET https://api.ebay.com` +
230
+ `request.path` with `request.params` as the query, `X-EBAY-C-MARKETPLACE-ID: request.marketplace`
231
+ and an application token (client credentials, scope `https://api.ebay.com/oauth/api_scope`) from
232
+ the host's own eBay keys, and hands back the HTTP status and the parsed JSON body (bounded in
233
+ time and size). The watch's `target` is the words to search for. eBay's API License wants
234
+ listing data shown no more than six hours old: a plain watch DMs what it read at once, and a
235
+ judged one once the model has looked. An eBay watch stores no findings (`keepsFindings`), so a
236
+ host that keeps no eBay data also clears the run's recorded DM after a while, and does not judge
237
+ one whose Job a queue would keep;
219
238
  - its Fetch port reaches only public addresses, checked after the name lookup: the judge grants
220
239
  the runner WebFetch on the watch's own host only because the host's reads already reach it;
221
240
  - `bggSource` gets a Fetch that hands back the body as sent and follows no redirect, so BGG's
@@ -230,7 +249,7 @@ host:
230
249
 
231
250
  ```ts
232
251
  import { TASK_TYPES, reminder, renewal, price, research, scout, TYPE_IDS, isTypeId } from "@rackbops/docket-types"
233
- import { bggSource, inboxSource, pageSource, wantjudgeType, wantlistType } from "@rackbops/docket-types"
252
+ import { bggSource, ebaySource, inboxSource, pageSource, shopifySource, wantjudgeType, wantlistType } from "@rackbops/docket-types"
234
253
  ```
235
254
 
236
255
  `TASK_TYPES` is every shipped type keyed by id, ready for the dispatcher. Every type is declared
package/dist/index.d.ts CHANGED
@@ -21,9 +21,11 @@ export { BARRED_SITES, blockedKey, type GatheredPage, gatheredPages, MAX_GATHERE
21
21
  export { BGG_CATEGORIES, bggCategoryUrl, FIRECRAWL_TOOLS, WEB_ALLOWED_TOOLS, } from "./research-web.js";
22
22
  export { itemKey, LENS_TEXT, LENSES, type Lens, lensOf, MAX_FOR_CHARS, MAX_INTEREST_CHARS, MAX_INTERESTS, MAX_ITEMS, MAX_SCOUT_NOTES, MAX_SHOWN, MIN_ITEMS, PROMPT_SHOWN, parseScout, renderScout, SCOUT_MAX_BUDGET_USD, SCOUT_MAX_TURNS, SCOUT_SCHEMA, SCOUT_TIMEOUT_MS, type ScoutConfig, type ScoutItem, type ScoutState, type ShownItem, scout, scoutJob, scoutState, } from "./scout.js";
23
23
  export { BGG_ATTRIBUTION, BGG_HOST, BGG_SPACING_MS, type BggOptions, bggSource, bggThingUrl, MAX_SCANNED, parseBggThingId, parseMarketplace, } from "./want-bgg.js";
24
- export { inboxSource, isEbayHost, type Listing, listingKey, listingsFromJsonLd, MAX_LISTINGS, NEVER_EBAY, pageSource, type ReadInbox, readListings, SOURCE_IDS, type Source, type SourceId, SourceMiss, SourceUnavailableError, type Submitted, submittedListing, } from "./want-sources.js";
24
+ export { EBAY_ATTRIBUTION, EBAY_CURRENCY, EBAY_LIMIT, EBAY_MARKETPLACE, EBAY_SEARCH_PATH, type EbayBrowse, type EbayRequest, type EbaySearch, ebayRequest, ebaySource, parseEbayAnswer, } from "./want-ebay.js";
25
+ export { matchesWords, minorUnits, parseShopifyAnswer, SHOPIFY_ATTRIBUTION, SHOPIFY_CAPABILITY, SHOPIFY_COUNTRY, SHOPIFY_CREDITS, SHOPIFY_CURRENCY, SHOPIFY_LIMIT, SHOPIFY_PROVIDER, type ShopifyRequest, type ShopifyScrape, type ShopifySearch, searchWords, shopifyQuery, shopifyRequest, shopifySource, } from "./want-shopify.js";
26
+ export { inboxSource, isEbayHost, type Listing, listingKey, listingsFromJsonLd, MAX_LISTINGS, NEVER_EBAY, pageSource, type ReadInbox, readListings, type SearchLimits, SOURCE_IDS, type Source, type SourceId, SourceMiss, SourceUnavailableError, type Submitted, submittedListing, } from "./want-sources.js";
25
27
  export { FITS, type Fit, JUDGE_MAX_BUDGET_USD, JUDGE_MAX_TURNS, JUDGE_SCHEMA, JUDGE_TIMEOUT_MS, type JudgeOptions, type JudgeState, type JudgeVerdict, judgeHosts, judgeJob, judgeState, parseVerdicts, RETRY_GRACE_MS, renderJudged, renderUnchecked, wantjudgeType, } from "./wantjudge.js";
26
- export { clip, inert, listingFinding, listingLine, MAX_DM_CHARS, MAX_NEW_PER_RUN, MAX_REPORTED, miss, type Polled, pollWant, priceText, renderWant, SHOWN_IN_DM, type WantConfig, type WantState, wantlistType, wantState, withinLimits, } from "./wantlist.js";
28
+ export { clip, inert, keepsFindings, listingFinding, listingLine, MAX_DM_CHARS, MAX_NEW_PER_RUN, MAX_REPORTED, miss, moreLine, type Polled, pollWant, priceText, renderWant, SHOWN_IN_DM, type WantConfig, type WantState, wantlistType, wantState, withinLimits, } from "./wantlist.js";
27
29
  /**
28
30
  * The six task categories the tracker starts with (plan section 1.2), as type identifiers, then
29
31
  * `wantjudge`: category 2's watch with the model's look first (plan 5.4), a type of its own.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -27,9 +27,11 @@ export { BARRED_SITES, blockedKey, gatheredPages, MAX_GATHERED_CHARS, MAX_GATHER
27
27
  export { BGG_CATEGORIES, bggCategoryUrl, FIRECRAWL_TOOLS, WEB_ALLOWED_TOOLS, } from "./research-web.js";
28
28
  export { itemKey, LENS_TEXT, LENSES, lensOf, MAX_FOR_CHARS, MAX_INTEREST_CHARS, MAX_INTERESTS, MAX_ITEMS, MAX_SCOUT_NOTES, MAX_SHOWN, MIN_ITEMS, PROMPT_SHOWN, parseScout, renderScout, SCOUT_MAX_BUDGET_USD, SCOUT_MAX_TURNS, SCOUT_SCHEMA, SCOUT_TIMEOUT_MS, scout, scoutJob, scoutState, } from "./scout.js";
29
29
  export { BGG_ATTRIBUTION, BGG_HOST, BGG_SPACING_MS, bggSource, bggThingUrl, MAX_SCANNED, parseBggThingId, parseMarketplace, } from "./want-bgg.js";
30
+ export { EBAY_ATTRIBUTION, EBAY_CURRENCY, EBAY_LIMIT, EBAY_MARKETPLACE, EBAY_SEARCH_PATH, ebayRequest, ebaySource, parseEbayAnswer, } from "./want-ebay.js";
31
+ export { matchesWords, minorUnits, parseShopifyAnswer, SHOPIFY_ATTRIBUTION, SHOPIFY_CAPABILITY, SHOPIFY_COUNTRY, SHOPIFY_CREDITS, SHOPIFY_CURRENCY, SHOPIFY_LIMIT, SHOPIFY_PROVIDER, searchWords, shopifyQuery, shopifyRequest, shopifySource, } from "./want-shopify.js";
30
32
  export { inboxSource, isEbayHost, listingKey, listingsFromJsonLd, MAX_LISTINGS, NEVER_EBAY, pageSource, readListings, SOURCE_IDS, SourceMiss, SourceUnavailableError, submittedListing, } from "./want-sources.js";
31
33
  export { FITS, JUDGE_MAX_BUDGET_USD, JUDGE_MAX_TURNS, JUDGE_SCHEMA, JUDGE_TIMEOUT_MS, judgeHosts, judgeJob, judgeState, parseVerdicts, RETRY_GRACE_MS, renderJudged, renderUnchecked, wantjudgeType, } from "./wantjudge.js";
32
- export { clip, inert, listingFinding, listingLine, MAX_DM_CHARS, MAX_NEW_PER_RUN, MAX_REPORTED, miss, pollWant, priceText, renderWant, SHOWN_IN_DM, wantlistType, wantState, withinLimits, } from "./wantlist.js";
34
+ export { clip, inert, keepsFindings, listingFinding, listingLine, MAX_DM_CHARS, MAX_NEW_PER_RUN, MAX_REPORTED, miss, moreLine, pollWant, priceText, renderWant, SHOWN_IN_DM, wantlistType, wantState, withinLimits, } from "./wantlist.js";
33
35
  /**
34
36
  * The six task categories the tracker starts with (plan section 1.2), as type identifiers, then
35
37
  * `wantjudge`: category 2's watch with the model's look first (plan 5.4), a type of its own.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ import { type Listing, type Source } from "./want-sources.js";
2
+ /**
3
+ * The eBay source (Rod, 2026-10-20, "Build it" on the eBay Browse API card): listings from eBay's
4
+ * own Browse API, `GET /buy/browse/v1/item_summary/search` (developer.ebay.com, read 2026-10-20),
5
+ * with an application token from the owner's eBay developer keyset. Using eBay's API under its API
6
+ * License Agreement is eBay's own permission, where reading its pages is barred (User Agreement
7
+ * s.3); the tracker still never opens an eBay page, and a judged eBay watch opens none either.
8
+ *
9
+ * A host registers the source only with eBay keys, and runs the request itself (`EbayBrowse`,
10
+ * which adds api.ebay.com, the token and the marketplace header): this library opens nothing.
11
+ *
12
+ * One search a look, the newest `EBAY_LIMIT` listings, fixed-price and auction alike, narrowed by
13
+ * the watch's top price (eBay's own `price` and `priceCurrency` filters). eBay matches the words
14
+ * itself; a listing is still kept only when every word is in its title (`matchesWords`), as for
15
+ * Shopify, so a description-only match is not DMed. An auction's price is its current bid, or its
16
+ * Buy It Now price when it has one. The
17
+ * seller line carries what eBay's answer shows: the seller's name, feedback percentage and score.
18
+ *
19
+ * The answer is untrusted text: every field is capped and cleaned, and an address is kept only as
20
+ * an eBay item's own `https://<eBay host>/itm/<number>`.
21
+ */
22
+ export declare const EBAY_SEARCH_PATH = "/buy/browse/v1/item_summary/search";
23
+ export declare const EBAY_MARKETPLACE = "EBAY_US";
24
+ export declare const EBAY_CURRENCY = "USD";
25
+ export declare const EBAY_LIMIT = 50;
26
+ export declare const EBAY_ATTRIBUTION = "via eBay";
27
+ /** One Browse API search: the path, its query parameters, and the marketplace to send as `X-EBAY-C-MARKETPLACE-ID`. */
28
+ export interface EbayRequest {
29
+ path: typeof EBAY_SEARCH_PATH;
30
+ params: Record<string, string>;
31
+ marketplace: typeof EBAY_MARKETPLACE;
32
+ }
33
+ /** The host's run of one request on api.ebay.com with its application token: the HTTP status and the parsed JSON body (null when it was not JSON). */
34
+ export type EbayBrowse = (request: EbayRequest) => Promise<{
35
+ status: number;
36
+ body: unknown;
37
+ }>;
38
+ export interface EbaySearch {
39
+ query: string;
40
+ maxPrice?: number;
41
+ currency?: string;
42
+ }
43
+ /**
44
+ * The request for a search: the words as sent (cut at a word, like Shopify's), newest first, at
45
+ * most `EBAY_LIMIT`, and at or under the top price. eBay US prices in USD, so the price filter is
46
+ * sent only for a watch in USD (or naming no currency); a watch in another currency gets no filter,
47
+ * and the type's own limits drop what is not in its currency. The filter is in whole units with
48
+ * decimals. Pure.
49
+ */
50
+ export declare function ebayRequest(s: EbaySearch): EbayRequest;
51
+ /**
52
+ * The listings in one search answer: each item summary whose title holds every word of `query`,
53
+ * with an eBay item address, priced (an auction at its current bid), with its condition, "auction"
54
+ * when it is one, and its seller. At most `MAX_LISTINGS`. An answer with no `itemSummaries` is a
55
+ * search with no results (eBay leaves the field out then); one that is not a search answer at all
56
+ * throws `SourceMiss`. Pure.
57
+ */
58
+ export declare function parseEbayAnswer(body: unknown, query: string): Listing[];
59
+ /** The `ebay` source over the host's `browse`: `target` is the words to search for, `limits` the watch's top price and currency. */
60
+ export declare function ebaySource(browse: EbayBrowse): Source;
61
+ //# sourceMappingURL=want-ebay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"want-ebay.d.ts","sourceRoot":"","sources":["../src/want-ebay.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,OAAO,EAEZ,KAAK,MAAM,EAGZ,MAAM,mBAAmB,CAAA;AAE1B;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,eAAO,MAAM,gBAAgB,uCAAuC,CAAA;AACpE,eAAO,MAAM,gBAAgB,YAAY,CAAA;AACzC,eAAO,MAAM,aAAa,QAAQ,CAAA;AAClC,eAAO,MAAM,UAAU,KAAK,CAAA;AAC5B,eAAO,MAAM,gBAAgB,aAAa,CAAA;AAK1C,uHAAuH;AACvH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,OAAO,gBAAgB,CAAA;IAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,WAAW,EAAE,OAAO,gBAAgB,CAAA;CACrC;AAED,sJAAsJ;AACtJ,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,CAAA;AAE7F,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,UAAU,GAAG,WAAW,CAkBtD;AAyCD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,EAAE,CAsCvE;AAED,oIAAoI;AACpI,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAuBrD"}
@@ -0,0 +1,177 @@
1
+ import { clean } from "@rackbops/docket-core";
2
+ import { safeUrl } from "./research-answer.js";
3
+ import { matchesWords, minorUnits, searchWords, shopifyQuery } from "./want-shopify.js";
4
+ import { isEbayHost, MAX_LISTINGS, SourceMiss, SourceUnavailableError, } from "./want-sources.js";
5
+ /**
6
+ * The eBay source (Rod, 2026-10-20, "Build it" on the eBay Browse API card): listings from eBay's
7
+ * own Browse API, `GET /buy/browse/v1/item_summary/search` (developer.ebay.com, read 2026-10-20),
8
+ * with an application token from the owner's eBay developer keyset. Using eBay's API under its API
9
+ * License Agreement is eBay's own permission, where reading its pages is barred (User Agreement
10
+ * s.3); the tracker still never opens an eBay page, and a judged eBay watch opens none either.
11
+ *
12
+ * A host registers the source only with eBay keys, and runs the request itself (`EbayBrowse`,
13
+ * which adds api.ebay.com, the token and the marketplace header): this library opens nothing.
14
+ *
15
+ * One search a look, the newest `EBAY_LIMIT` listings, fixed-price and auction alike, narrowed by
16
+ * the watch's top price (eBay's own `price` and `priceCurrency` filters). eBay matches the words
17
+ * itself; a listing is still kept only when every word is in its title (`matchesWords`), as for
18
+ * Shopify, so a description-only match is not DMed. An auction's price is its current bid, or its
19
+ * Buy It Now price when it has one. The
20
+ * seller line carries what eBay's answer shows: the seller's name, feedback percentage and score.
21
+ *
22
+ * The answer is untrusted text: every field is capped and cleaned, and an address is kept only as
23
+ * an eBay item's own `https://<eBay host>/itm/<number>`.
24
+ */
25
+ export const EBAY_SEARCH_PATH = "/buy/browse/v1/item_summary/search";
26
+ export const EBAY_MARKETPLACE = "EBAY_US";
27
+ export const EBAY_CURRENCY = "USD";
28
+ export const EBAY_LIMIT = 50;
29
+ export const EBAY_ATTRIBUTION = "via eBay";
30
+ const TITLE_CHARS = 150;
31
+ const CONDITION_CHARS = 40;
32
+ const SELLER_CHARS = 80;
33
+ /**
34
+ * The request for a search: the words as sent (cut at a word, like Shopify's), newest first, at
35
+ * most `EBAY_LIMIT`, and at or under the top price. eBay US prices in USD, so the price filter is
36
+ * sent only for a watch in USD (or naming no currency); a watch in another currency gets no filter,
37
+ * and the type's own limits drop what is not in its currency. The filter is in whole units with
38
+ * decimals. Pure.
39
+ */
40
+ export function ebayRequest(s) {
41
+ const asked = (s.currency ?? "").trim().toUpperCase();
42
+ const currency = asked === "" ? EBAY_CURRENCY : asked;
43
+ const params = {
44
+ q: shopifyQuery(s.query),
45
+ limit: String(EBAY_LIMIT),
46
+ sort: "newlyListed",
47
+ };
48
+ if (currency === EBAY_CURRENCY &&
49
+ s.maxPrice !== undefined &&
50
+ Number.isFinite(s.maxPrice) &&
51
+ s.maxPrice >= 0) {
52
+ const digits = Math.round(Math.log10(minorUnits(currency)));
53
+ params.filter = `price:[..${s.maxPrice.toFixed(digits)}],priceCurrency:${currency}`;
54
+ }
55
+ return { path: EBAY_SEARCH_PATH, params, marketplace: EBAY_MARKETPLACE };
56
+ }
57
+ const isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
58
+ /** eBay's `{ value, currency }`, value a decimal string: as a number and a code; null without both. */
59
+ function amountOf(v) {
60
+ if (!isObj(v))
61
+ return null;
62
+ const raw = typeof v.value === "string" || typeof v.value === "number" ? String(v.value) : "";
63
+ const currency = typeof v.currency === "string" ? v.currency.trim().toUpperCase() : "";
64
+ if (!/^[0-9]{1,12}(\.[0-9]{1,4})?$/.test(raw.trim()) || !/^[A-Z]{3}$/.test(currency))
65
+ return null;
66
+ return { value: Number(raw), currency };
67
+ }
68
+ /** An eBay item's own address, `https://<eBay host>/itm/<number>`, or null for anything else. */
69
+ function itemUrl(raw) {
70
+ if (typeof raw !== "string")
71
+ return null;
72
+ let u;
73
+ try {
74
+ u = new URL(raw.trim());
75
+ }
76
+ catch {
77
+ return null;
78
+ }
79
+ if (u.protocol !== "https:" || !isEbayHost(u.hostname))
80
+ return null;
81
+ const item = /^\/itm\/(?:[^/]+\/)?([0-9]{6,20})\/?$/.exec(u.pathname);
82
+ return item ? safeUrl(`https://${u.hostname.toLowerCase()}/itm/${item[1]}`) : null;
83
+ }
84
+ /** "name, 99.8% positive, 1234 feedback": what eBay shows of the seller, or "" with no name. */
85
+ function sellerOf(v) {
86
+ if (!isObj(v) || typeof v.username !== "string")
87
+ return "";
88
+ const name = clean(v.username, 40, true);
89
+ if (!name)
90
+ return "";
91
+ const parts = [name];
92
+ const pct = typeof v.feedbackPercentage === "string" ? v.feedbackPercentage.trim() : "";
93
+ if (/^[0-9]{1,3}(\.[0-9]{1,2})?$/.test(pct))
94
+ parts.push(`${pct}% positive`);
95
+ if (typeof v.feedbackScore === "number" && Number.isInteger(v.feedbackScore))
96
+ parts.push(`${v.feedbackScore} feedback`);
97
+ return clean(parts.join(", "), SELLER_CHARS, true);
98
+ }
99
+ /**
100
+ * The listings in one search answer: each item summary whose title holds every word of `query`,
101
+ * with an eBay item address, priced (an auction at its current bid), with its condition, "auction"
102
+ * when it is one, and its seller. At most `MAX_LISTINGS`. An answer with no `itemSummaries` is a
103
+ * search with no results (eBay leaves the field out then); one that is not a search answer at all
104
+ * throws `SourceMiss`. Pure.
105
+ */
106
+ export function parseEbayAnswer(body, query) {
107
+ if (!isObj(body) || (body.itemSummaries === undefined && typeof body.total !== "number"))
108
+ throw new SourceMiss("eBay's answer was not a search result");
109
+ const items = Array.isArray(body.itemSummaries) ? body.itemSummaries : [];
110
+ const words = searchWords(query);
111
+ const out = [];
112
+ const seen = new Set();
113
+ for (const item of items.slice(0, EBAY_LIMIT * 4)) {
114
+ if (out.length >= MAX_LISTINGS)
115
+ break;
116
+ if (!isObj(item) || typeof item.title !== "string" || typeof item.itemId !== "string")
117
+ continue;
118
+ if (!matchesWords(item.title.slice(0, 2_000), words))
119
+ continue;
120
+ const title = clean(item.title, TITLE_CHARS, true);
121
+ const url = itemUrl(item.itemWebUrl);
122
+ if (!title || !url || item.itemId.length > 120)
123
+ continue;
124
+ // Keyed by the listing's `/itm/<number>`, which its variations share: one listing is told once,
125
+ // whichever variation eBay puts first on a later look.
126
+ const number = /\/itm\/([0-9]+)$/.exec(url)?.[1];
127
+ if (!number || seen.has(number))
128
+ continue;
129
+ seen.add(number);
130
+ const options = Array.isArray(item.buyingOptions) ? item.buyingOptions : [];
131
+ const auction = options.includes("AUCTION");
132
+ const buyNow = options.includes("FIXED_PRICE");
133
+ // A plain auction at its current bid; one with Buy It Now at that price, which buys it outright.
134
+ const price = amountOf(auction && !buyNow ? (item.currentBidPrice ?? item.price) : item.price);
135
+ const state = typeof item.condition === "string" ? clean(item.condition, 30, true) : "";
136
+ const kind = auction ? [buyNow ? "auction, Buy It Now" : "auction"] : [];
137
+ const condition = clean([state, ...kind].filter(Boolean).join(", "), CONDITION_CHARS, true);
138
+ const seller = sellerOf(item.seller);
139
+ out.push({
140
+ id: `ebay:${number}`,
141
+ title,
142
+ url,
143
+ ...(price ? { price: price.value, currency: price.currency } : {}),
144
+ ...(condition ? { condition } : {}),
145
+ ...(seller ? { seller } : {}),
146
+ });
147
+ }
148
+ return out;
149
+ }
150
+ /** The `ebay` source over the host's `browse`: `target` is the words to search for, `limits` the watch's top price and currency. */
151
+ export function ebaySource(browse) {
152
+ return {
153
+ id: "ebay",
154
+ async search(target, _fetch, limits) {
155
+ if (searchWords(target).length === 0)
156
+ throw new SourceMiss("there are no words to search for");
157
+ let status;
158
+ let body;
159
+ try {
160
+ ;
161
+ ({ status, body } = await browse(ebayRequest({ query: target, ...limits })));
162
+ }
163
+ catch (err) {
164
+ throw new SourceMiss(`eBay could not be searched: ${clean(err instanceof Error ? err.message : String(err), 200, true)}`, { cause: err });
165
+ }
166
+ // Keys eBay refuses, or an app without Browse access: no later look succeeds until someone acts.
167
+ if (status === 401 || status === 403)
168
+ throw new SourceUnavailableError("eBay refused the app's keys");
169
+ if (status === 429 || status >= 500)
170
+ throw new SourceMiss(`eBay is busy (HTTP ${status})`);
171
+ if (status !== 200)
172
+ throw new SourceMiss(`eBay answered HTTP ${status}`);
173
+ return parseEbayAnswer(body, target);
174
+ },
175
+ };
176
+ }
177
+ //# sourceMappingURL=want-ebay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"want-ebay.js","sourceRoot":"","sources":["../src/want-ebay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ import { type Listing, type SearchLimits, type Source } from "./want-sources.js";
2
+ /**
3
+ * The Shopify source (Rod, 2026-10-19: "add Shopify to watches, daily"): new copies in stock at
4
+ * Shopify stores, from Shopify's catalog search as Firecrawl's Alexandria runs it -- provider
5
+ * `shopify`, capability `catalog/search_catalog`, 5 Firecrawl credits a search (its contract, read
6
+ * 2026-10-19). A host registers the source only with a Firecrawl key, and runs the request itself
7
+ * (`ShopifyScrape`): this library opens nothing.
8
+ *
9
+ * One search a look, one page of at most `SHOPIFY_LIMIT` products, in stock only and under the top
10
+ * price when one is set (Shopify's own `filters`, in minor units). Shopify's search is loose -- it
11
+ * returns related products too -- so a product is kept only when every word of the watch's search
12
+ * is in its title (`matchesWords`). Only a variant that is available, and new or unmarked, is a
13
+ * listing (a variant whose condition is unmarked is taken as new): the catalog sells new copies. The
14
+ * country filter is Shopify's, and leaky (stores abroad still appear, priced in the asked currency).
15
+ *
16
+ * The answer is untrusted shop text: every field is capped and cleaned, an address is kept only as
17
+ * an absolute http(s) one with no fragment and no query parameter but `variant`, and the walk is bounded.
18
+ */
19
+ export declare const SHOPIFY_PROVIDER = "shopify";
20
+ export declare const SHOPIFY_CAPABILITY = "catalog/search_catalog";
21
+ /** Firecrawl's listed price for one search (its contract, 2026-10-19). */
22
+ export declare const SHOPIFY_CREDITS = 5;
23
+ export declare const SHOPIFY_LIMIT = 50;
24
+ export declare const SHOPIFY_COUNTRY = "US";
25
+ export declare const SHOPIFY_CURRENCY = "USD";
26
+ export declare const SHOPIFY_ATTRIBUTION = "via Shopify";
27
+ /** The Alexandria call for one look: `{ provider, capability, options }`, sent as the `alexandria` field of Firecrawl's `POST /v2/scrape`. */
28
+ export interface ShopifyRequest {
29
+ provider: typeof SHOPIFY_PROVIDER;
30
+ capability: typeof SHOPIFY_CAPABILITY;
31
+ options: {
32
+ query: string;
33
+ country: string;
34
+ currency: string;
35
+ limit: number;
36
+ filters: {
37
+ available: true;
38
+ price?: {
39
+ max: number;
40
+ };
41
+ };
42
+ };
43
+ }
44
+ /** The host's run of one request: Firecrawl's HTTP status and its parsed JSON body (null when it was not JSON). */
45
+ export type ShopifyScrape = (request: ShopifyRequest) => Promise<{
46
+ status: number;
47
+ body: unknown;
48
+ }>;
49
+ export interface ShopifySearch extends SearchLimits {
50
+ query: string;
51
+ }
52
+ /** The request for a search: in stock, at or under the top price (minor units, rounded down), in USD unless the watch names a valid three-letter code. Pure. */
53
+ export declare function shopifyRequest(s: ShopifySearch): ShopifyRequest;
54
+ export declare function shopifyQuery(query: string): string;
55
+ /** The words a title must hold: those of the query as sent, in any order. */
56
+ export declare function searchWords(query: string): string[];
57
+ /** Whether `title` holds every one of `words` as a whole word. Pure. */
58
+ export declare function matchesWords(title: string, words: readonly string[]): boolean;
59
+ /** How many minor units make one of `currency` (100 for USD, 1 for JPY, 1000 for KWD). */
60
+ export declare function minorUnits(currency: string): number;
61
+ /**
62
+ * The listings in one search answer (Firecrawl's body): each product whose title holds every word
63
+ * of `query`, and in it each variant that is available, new or unmarked, with an address -- titled
64
+ * by the product (and the variant, when it names one of its own), priced, and sold by its store. At
65
+ * most `MAX_LISTINGS`. Throws `SourceMiss` when the answer is not a search result. Pure.
66
+ */
67
+ export declare function parseShopifyAnswer(body: unknown, query: string): Listing[];
68
+ /** The `shopify` source over the host's `scrape`: `target` is the words to search for, `limits` the watch's top price and currency. */
69
+ export declare function shopifySource(scrape: ShopifyScrape): Source;
70
+ //# sourceMappingURL=want-shopify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"want-shopify.d.ts","sourceRoot":"","sources":["../src/want-shopify.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,OAAO,EAEZ,KAAK,YAAY,EACjB,KAAK,MAAM,EAGZ,MAAM,mBAAmB,CAAA;AAE1B;;;;;;;;;;;;;;;;GAgBG;AAEH,eAAO,MAAM,gBAAgB,YAAY,CAAA;AACzC,eAAO,MAAM,kBAAkB,2BAA2B,CAAA;AAC1D,0EAA0E;AAC1E,eAAO,MAAM,eAAe,IAAI,CAAA;AAChC,eAAO,MAAM,aAAa,KAAK,CAAA;AAC/B,eAAO,MAAM,eAAe,OAAO,CAAA;AACnC,eAAO,MAAM,gBAAgB,QAAQ,CAAA;AACrC,eAAO,MAAM,mBAAmB,gBAAgB,CAAA;AAKhD,8IAA8I;AAC9I,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,OAAO,gBAAgB,CAAA;IACjC,UAAU,EAAE,OAAO,kBAAkB,CAAA;IACrC,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,MAAM,CAAA;QAChB,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,EAAE;YAAE,SAAS,EAAE,IAAI,CAAC;YAAC,KAAK,CAAC,EAAE;gBAAE,GAAG,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,CAAA;KACtD,CAAA;CACF;AAED,mHAAmH;AACnH,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,CAAA;AAEnG,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,KAAK,EAAE,MAAM,CAAA;CACd;AAED,gKAAgK;AAChK,wBAAgB,cAAc,CAAC,CAAC,EAAE,aAAa,GAAG,cAAc,CAiB/D;AAOD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMlD;AAaD,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAEnD;AAED,wEAAwE;AACxE,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAG7E;AAuBD,0FAA0F;AAC1F,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGnD;AAoBD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,EAAE,CAqD1E;AAED,uIAAuI;AACvI,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CA0B3D"}