keepa-api 0.2.2 → 0.3.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 +4 -4
- package/dist/index.cjs +337 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +163 -0
- package/dist/index.d.ts +163 -8
- package/dist/index.js +287 -7
- package/dist/index.js.map +1 -1
- package/package.json +14 -5
- package/dist/client.d.ts +0 -21
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -38
- package/dist/client.js.map +0 -1
- package/dist/core/error.d.ts +0 -27
- package/dist/core/error.d.ts.map +0 -1
- package/dist/core/error.js +0 -61
- package/dist/core/error.js.map +0 -1
- package/dist/core/request.d.ts +0 -15
- package/dist/core/request.d.ts.map +0 -1
- package/dist/core/request.js +0 -36
- package/dist/core/request.js.map +0 -1
- package/dist/core/resource.d.ts +0 -6
- package/dist/core/resource.d.ts.map +0 -1
- package/dist/core/resource.js +0 -7
- package/dist/core/resource.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/lib/asin.d.ts +0 -10
- package/dist/lib/asin.d.ts.map +0 -1
- package/dist/lib/asin.js +0 -19
- package/dist/lib/asin.js.map +0 -1
- package/dist/lib/marketplace.d.ts +0 -17
- package/dist/lib/marketplace.d.ts.map +0 -1
- package/dist/lib/marketplace.js +0 -27
- package/dist/lib/marketplace.js.map +0 -1
- package/dist/resources/index.d.ts +0 -2
- package/dist/resources/index.d.ts.map +0 -1
- package/dist/resources/index.js +0 -2
- package/dist/resources/index.js.map +0 -1
- package/dist/resources/products/constant.d.ts +0 -7
- package/dist/resources/products/constant.d.ts.map +0 -1
- package/dist/resources/products/constant.js +0 -15
- package/dist/resources/products/constant.js.map +0 -1
- package/dist/resources/products/error.d.ts +0 -10
- package/dist/resources/products/error.d.ts.map +0 -1
- package/dist/resources/products/error.js +0 -14
- package/dist/resources/products/error.js.map +0 -1
- package/dist/resources/products/index.d.ts +0 -6
- package/dist/resources/products/index.d.ts.map +0 -1
- package/dist/resources/products/index.js +0 -8
- package/dist/resources/products/index.js.map +0 -1
- package/dist/resources/products/product.raw.type.d.ts +0 -36
- package/dist/resources/products/product.raw.type.d.ts.map +0 -1
- package/dist/resources/products/product.raw.type.js +0 -6
- package/dist/resources/products/product.raw.type.js.map +0 -1
- package/dist/resources/products/product.type.d.ts +0 -48
- package/dist/resources/products/product.type.d.ts.map +0 -1
- package/dist/resources/products/product.type.js +0 -2
- package/dist/resources/products/product.type.js.map +0 -1
- package/dist/resources/products/product.util.d.ts +0 -15
- package/dist/resources/products/product.util.d.ts.map +0 -1
- package/dist/resources/products/product.util.js +0 -56
- package/dist/resources/products/product.util.js.map +0 -1
- package/dist/resources/products/products.d.ts +0 -9
- package/dist/resources/products/products.d.ts.map +0 -1
- package/dist/resources/products/products.js +0 -40
- package/dist/resources/products/products.js.map +0 -1
- package/dist/version.d.ts +0 -2
- package/dist/version.d.ts.map +0 -1
- package/dist/version.js +0 -2
- package/dist/version.js.map +0 -1
package/dist/core/error.js
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
/** Replace any `?key=...` or `&key=...` segment with a REDACTED placeholder.
|
|
2
|
-
* Defense-in-depth: keeps the API key out of error messages even when an
|
|
3
|
-
* underlying transport error or upstream response echoes the request URL.
|
|
4
|
-
* Exported for use by callers that build their own error wrappers. */
|
|
5
|
-
export function scrubApiKey(text) {
|
|
6
|
-
return text.replace(/([?&])key=[^&\s]*/gi, '$1key=REDACTED');
|
|
7
|
-
}
|
|
8
|
-
export class KeepaError extends Error {
|
|
9
|
-
constructor(message) {
|
|
10
|
-
super(message);
|
|
11
|
-
this.name = 'KeepaError';
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
export class APIError extends KeepaError {
|
|
15
|
-
status;
|
|
16
|
-
context;
|
|
17
|
-
body;
|
|
18
|
-
constructor(status, context, body, message) {
|
|
19
|
-
const safeBody = scrubApiKey(body);
|
|
20
|
-
super(scrubApiKey(message ?? `Keepa ${context} error (${status}): ${safeBody}`));
|
|
21
|
-
this.name = 'APIError';
|
|
22
|
-
this.status = status;
|
|
23
|
-
this.context = context;
|
|
24
|
-
this.body = safeBody;
|
|
25
|
-
}
|
|
26
|
-
static async from(response, context) {
|
|
27
|
-
const body = await response.text().catch(() => '');
|
|
28
|
-
switch (response.status) {
|
|
29
|
-
case 429:
|
|
30
|
-
return new RateLimitError(context, body);
|
|
31
|
-
case 401:
|
|
32
|
-
return new AuthenticationError(context, body);
|
|
33
|
-
default:
|
|
34
|
-
return new APIError(response.status, context, body);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
export class RateLimitError extends APIError {
|
|
39
|
-
constructor(context, body) {
|
|
40
|
-
super(429, context, body, 'Keepa rate limit exceeded, please wait or upgrade plan');
|
|
41
|
-
this.name = 'RateLimitError';
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
export class AuthenticationError extends APIError {
|
|
45
|
-
constructor(context, body) {
|
|
46
|
-
super(401, context, body, `Keepa authentication failed for ${context}: invalid or missing API key`);
|
|
47
|
-
this.name = 'AuthenticationError';
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
export class NetworkError extends KeepaError {
|
|
51
|
-
context;
|
|
52
|
-
cause;
|
|
53
|
-
constructor(context, cause) {
|
|
54
|
-
const raw = cause instanceof Error ? cause.message : String(cause);
|
|
55
|
-
super(`Keepa ${context} network error: ${scrubApiKey(raw)}`);
|
|
56
|
-
this.name = 'NetworkError';
|
|
57
|
-
this.context = context;
|
|
58
|
-
this.cause = cause;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
//# sourceMappingURL=error.js.map
|
package/dist/core/error.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/core/error.ts"],"names":[],"mappings":"AAAA;;;uEAGuE;AACvE,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,gBAAgB,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,OAAO,QAAS,SAAQ,UAAU;IAC7B,MAAM,CAAS;IACf,OAAO,CAAS;IAChB,IAAI,CAAS;IAEtB,YAAY,MAAc,EAAE,OAAe,EAAE,IAAY,EAAE,OAAgB;QACzE,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QACnC,KAAK,CAAC,WAAW,CAAC,OAAO,IAAI,SAAS,OAAO,WAAW,MAAM,MAAM,QAAQ,EAAE,CAAC,CAAC,CAAC;QACjF,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;IACvB,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAkB,EAAE,OAAe;QACnD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QACnD,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;YACxB,KAAK,GAAG;gBACN,OAAO,IAAI,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAC3C,KAAK,GAAG;gBACN,OAAO,IAAI,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAChD;gBACE,OAAO,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;CACF;AAED,MAAM,OAAO,cAAe,SAAQ,QAAQ;IAC1C,YAAY,OAAe,EAAE,IAAY;QACvC,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,wDAAwD,CAAC,CAAC;QACpF,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,OAAO,mBAAoB,SAAQ,QAAQ;IAC/C,YAAY,OAAe,EAAE,IAAY;QACvC,KAAK,CACH,GAAG,EACH,OAAO,EACP,IAAI,EACJ,mCAAmC,OAAO,8BAA8B,CACzE,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED,MAAM,OAAO,YAAa,SAAQ,UAAU;IACjC,OAAO,CAAS;IACP,KAAK,CAAU;IAEjC,YAAY,OAAe,EAAE,KAAc;QACzC,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnE,KAAK,CAAC,SAAS,OAAO,mBAAmB,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7D,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF"}
|
package/dist/core/request.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export type QueryValue = string | number | string[] | number[] | undefined;
|
|
2
|
-
export type QueryParams = Record<string, QueryValue>;
|
|
3
|
-
export interface RequestArgs {
|
|
4
|
-
path: string;
|
|
5
|
-
query?: QueryParams;
|
|
6
|
-
context: string;
|
|
7
|
-
}
|
|
8
|
-
export interface RequestConfig {
|
|
9
|
-
baseURL: string;
|
|
10
|
-
apiKey: string;
|
|
11
|
-
fetch: typeof globalThis.fetch;
|
|
12
|
-
}
|
|
13
|
-
export declare function buildUrl(baseURL: string, path: string, query?: QueryParams): string;
|
|
14
|
-
export declare function request<T>(config: RequestConfig, args: RequestArgs): Promise<T>;
|
|
15
|
-
//# sourceMappingURL=request.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/core/request.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;AAC3E,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CAChC;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,MAAM,CASnF;AAWD,wBAAsB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAWrF"}
|
package/dist/core/request.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { APIError, NetworkError } from './error.js';
|
|
2
|
-
export function buildUrl(baseURL, path, query) {
|
|
3
|
-
if (!query)
|
|
4
|
-
return `${baseURL}${path}`;
|
|
5
|
-
const parts = [];
|
|
6
|
-
for (const [key, value] of Object.entries(query)) {
|
|
7
|
-
if (value === undefined)
|
|
8
|
-
continue;
|
|
9
|
-
const stringValue = Array.isArray(value) ? value.join(',') : String(value);
|
|
10
|
-
parts.push(`${encodeURIComponent(key)}=${encodeKeepaValue(stringValue)}`);
|
|
11
|
-
}
|
|
12
|
-
return parts.length ? `${baseURL}${path}?${parts.join('&')}` : `${baseURL}${path}`;
|
|
13
|
-
}
|
|
14
|
-
// Keep commas literal — Keepa accepts comma-separated lists (asin=A,B,C, category=1,2,3)
|
|
15
|
-
// and the category endpoint specifically rejects %2C-encoded commas.
|
|
16
|
-
// Currently private to this module: if a future helper builds Keepa URLs outside
|
|
17
|
-
// `request()` (e.g. a paginator) and needs the same encoding, lift this into
|
|
18
|
-
// `core/encoding.ts` rather than duplicating it.
|
|
19
|
-
function encodeKeepaValue(value) {
|
|
20
|
-
return encodeURIComponent(value).replace(/%2C/g, ',');
|
|
21
|
-
}
|
|
22
|
-
export async function request(config, args) {
|
|
23
|
-
const query = { key: config.apiKey, ...args.query };
|
|
24
|
-
const url = buildUrl(config.baseURL, args.path, query);
|
|
25
|
-
let res;
|
|
26
|
-
try {
|
|
27
|
-
res = await config.fetch(url);
|
|
28
|
-
}
|
|
29
|
-
catch (cause) {
|
|
30
|
-
throw new NetworkError(args.context, cause);
|
|
31
|
-
}
|
|
32
|
-
if (!res.ok)
|
|
33
|
-
throw await APIError.from(res, args.context);
|
|
34
|
-
return (await res.json());
|
|
35
|
-
}
|
|
36
|
-
//# sourceMappingURL=request.js.map
|
package/dist/core/request.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/core/request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAiBpD,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,IAAY,EAAE,KAAmB;IACzE,IAAI,CAAC,KAAK;QAAE,OAAO,GAAG,OAAO,GAAG,IAAI,EAAE,CAAC;IACvC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3E,KAAK,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,GAAG,CAAC,IAAI,gBAAgB,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,IAAI,EAAE,CAAC;AACrF,CAAC;AAED,yFAAyF;AACzF,qEAAqE;AACrE,iFAAiF;AACjF,6EAA6E;AAC7E,iDAAiD;AACjD,SAAS,gBAAgB,CAAC,KAAa;IACrC,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAI,MAAqB,EAAE,IAAiB;IACvE,MAAM,KAAK,GAAgB,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;IACjE,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACvD,IAAI,GAAa,CAAC;IAClB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,MAAM,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1D,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAM,CAAC;AACjC,CAAC"}
|
package/dist/core/resource.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../../src/core/resource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE1C,8BAAsB,WAAW;IAC/B,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC;gBAEb,MAAM,EAAE,KAAK;CAG1B"}
|
package/dist/core/resource.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resource.js","sourceRoot":"","sources":["../../src/core/resource.ts"],"names":[],"mappings":"AAEA,MAAM,OAAgB,WAAW;IACrB,OAAO,CAAQ;IAEzB,YAAY,MAAa;QACvB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;CACF"}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,OAAO,EAAE,KAAK,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAE1E,OAAO,EACL,UAAU,EACV,QAAQ,EACR,cAAc,EACd,mBAAmB,EACnB,YAAY,GACb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,QAAQ,GACd,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,WAAW,EACX,UAAU,EACV,WAAW,EACX,cAAc,GACf,MAAM,eAAe,CAAC;AAEvB,cAAc,sBAAsB,CAAC;AAErC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/lib/asin.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export declare const ASIN_LENGTH = 10;
|
|
2
|
-
export declare const ASIN_REGEX: RegExp;
|
|
3
|
-
/** Returns true if the given string is a structurally valid ASIN
|
|
4
|
-
* (10 uppercase alphanumeric characters). Note: a passing ASIN may still
|
|
5
|
-
* not exist in Keepa's database — use `isFoundProduct` to check that. */
|
|
6
|
-
export declare function isValidAsin(value: string): boolean;
|
|
7
|
-
/** Trim + uppercase a list of ASINs and validate each. Returns the normalized
|
|
8
|
-
* list. Throws with all invalid ASINs listed in the error message. */
|
|
9
|
-
export declare function normalizeAsins(asins: string[]): string[];
|
|
10
|
-
//# sourceMappingURL=asin.d.ts.map
|
package/dist/lib/asin.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"asin.d.ts","sourceRoot":"","sources":["../../src/lib/asin.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,KAAK,CAAC;AAC9B,eAAO,MAAM,UAAU,QAAmB,CAAC;AAE3C;;0EAE0E;AAC1E,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAElD;AAED;uEACuE;AACvE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CASxD"}
|
package/dist/lib/asin.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export const ASIN_LENGTH = 10;
|
|
2
|
-
export const ASIN_REGEX = /^[A-Z0-9]{10}$/;
|
|
3
|
-
/** Returns true if the given string is a structurally valid ASIN
|
|
4
|
-
* (10 uppercase alphanumeric characters). Note: a passing ASIN may still
|
|
5
|
-
* not exist in Keepa's database — use `isFoundProduct` to check that. */
|
|
6
|
-
export function isValidAsin(value) {
|
|
7
|
-
return ASIN_REGEX.test(value);
|
|
8
|
-
}
|
|
9
|
-
/** Trim + uppercase a list of ASINs and validate each. Returns the normalized
|
|
10
|
-
* list. Throws with all invalid ASINs listed in the error message. */
|
|
11
|
-
export function normalizeAsins(asins) {
|
|
12
|
-
const normalized = asins.map((asin) => asin.trim().toUpperCase());
|
|
13
|
-
const invalid = normalized.filter((asin) => !isValidAsin(asin));
|
|
14
|
-
if (invalid.length > 0) {
|
|
15
|
-
throw new Error(`Invalid ASIN(s): ${invalid.join(', ')}. ASINs must be ${ASIN_LENGTH} alphanumeric characters (e.g. B00MNV8E0C).`);
|
|
16
|
-
}
|
|
17
|
-
return normalized;
|
|
18
|
-
}
|
|
19
|
-
//# sourceMappingURL=asin.js.map
|
package/dist/lib/asin.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"asin.js","sourceRoot":"","sources":["../../src/lib/asin.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAC9B,MAAM,CAAC,MAAM,UAAU,GAAG,gBAAgB,CAAC;AAE3C;;0EAE0E;AAC1E,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC;AAED;uEACuE;AACvE,MAAM,UAAU,cAAc,CAAC,KAAe;IAC5C,MAAM,UAAU,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;IAClE,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;IAChE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,oBAAoB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,WAAW,6CAA6C,CAClH,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export declare const MARKETPLACE_DOMAINS: {
|
|
2
|
-
readonly US: 1;
|
|
3
|
-
readonly GB: 2;
|
|
4
|
-
readonly DE: 3;
|
|
5
|
-
readonly FR: 4;
|
|
6
|
-
readonly JP: 5;
|
|
7
|
-
readonly CA: 6;
|
|
8
|
-
readonly IT: 8;
|
|
9
|
-
readonly ES: 9;
|
|
10
|
-
readonly IN: 10;
|
|
11
|
-
readonly MX: 11;
|
|
12
|
-
readonly BR: 12;
|
|
13
|
-
};
|
|
14
|
-
export type Marketplace = keyof typeof MARKETPLACE_DOMAINS;
|
|
15
|
-
export type DomainId = (typeof MARKETPLACE_DOMAINS)[Marketplace];
|
|
16
|
-
export declare function resolveDomainId(marketplace: string | undefined): DomainId;
|
|
17
|
-
//# sourceMappingURL=marketplace.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"marketplace.d.ts","sourceRoot":"","sources":["../../src/lib/marketplace.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,mBAAmB;;;;;;;;;;;;CAYtB,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,mBAAmB,CAAC;AAC3D,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,WAAW,CAAC,CAAC;AAIjE,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CASzE"}
|
package/dist/lib/marketplace.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
// The full set of marketplaces Keepa currently supports. Codes are ISO 3166-1
|
|
2
|
-
// alpha-2; the numeric id is Keepa's `domain` query parameter value. Domain 7
|
|
3
|
-
// is reserved (formerly Amazon China, retired). Update the README marketplace
|
|
4
|
-
// table alongside any change here.
|
|
5
|
-
export const MARKETPLACE_DOMAINS = {
|
|
6
|
-
US: 1,
|
|
7
|
-
GB: 2,
|
|
8
|
-
DE: 3,
|
|
9
|
-
FR: 4,
|
|
10
|
-
JP: 5,
|
|
11
|
-
CA: 6,
|
|
12
|
-
IT: 8,
|
|
13
|
-
ES: 9,
|
|
14
|
-
IN: 10,
|
|
15
|
-
MX: 11,
|
|
16
|
-
BR: 12,
|
|
17
|
-
};
|
|
18
|
-
const SUPPORTED_LIST = Object.keys(MARKETPLACE_DOMAINS).join(', ');
|
|
19
|
-
export function resolveDomainId(marketplace) {
|
|
20
|
-
const key = (marketplace ?? 'US').toUpperCase();
|
|
21
|
-
const domainId = MARKETPLACE_DOMAINS[key];
|
|
22
|
-
if (!domainId) {
|
|
23
|
-
throw new Error(`Invalid marketplace "${marketplace}". Supported: ${SUPPORTED_LIST}`);
|
|
24
|
-
}
|
|
25
|
-
return domainId;
|
|
26
|
-
}
|
|
27
|
-
//# sourceMappingURL=marketplace.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"marketplace.js","sourceRoot":"","sources":["../../src/lib/marketplace.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,8EAA8E;AAC9E,8EAA8E;AAC9E,mCAAmC;AACnC,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,EAAE;IACN,EAAE,EAAE,EAAE;IACN,EAAE,EAAE,EAAE;CACE,CAAC;AAKX,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEnE,MAAM,UAAU,eAAe,CAAC,WAA+B;IAC7D,MAAM,GAAG,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC,WAAW,EAAiB,CAAC;IAC/D,MAAM,QAAQ,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC;IAC1C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,wBAAwB,WAAW,iBAAiB,cAAc,EAAE,CACrE,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC"}
|
package/dist/resources/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export declare const PRODUCT_PATH = "/product";
|
|
2
|
-
export declare const PRODUCT_LIST_CONTEXT = "products.list";
|
|
3
|
-
export declare const DEFAULT_DAYS = 1;
|
|
4
|
-
export declare const AMAZON_IMAGE_BASE = "https://m.media-amazon.com/images/I";
|
|
5
|
-
export declare const KEEPA_NO_DATA_SENTINEL = -1;
|
|
6
|
-
export declare const VALID_IMAGE_FILENAME: RegExp;
|
|
7
|
-
//# sourceMappingURL=constant.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constant.d.ts","sourceRoot":"","sources":["../../../src/resources/products/constant.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,aAAa,CAAC;AAIvC,eAAO,MAAM,oBAAoB,kBAAkB,CAAC;AACpD,eAAO,MAAM,YAAY,IAAI,CAAC;AAG9B,eAAO,MAAM,iBAAiB,wCAAwC,CAAC;AAGvE,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAKzC,eAAO,MAAM,oBAAoB,QAA4C,CAAC"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export const PRODUCT_PATH = '/product';
|
|
2
|
-
// Structured tag of the form `<resource>.<method>`. Used as the `context` field on
|
|
3
|
-
// errors thrown from this method — keeps log aggregators able to filter cleanly as
|
|
4
|
-
// more methods land (categories.list, categories.search, bestsellers.retrieve, …).
|
|
5
|
-
export const PRODUCT_LIST_CONTEXT = 'products.list';
|
|
6
|
-
export const DEFAULT_DAYS = 1;
|
|
7
|
-
// Region-neutral Amazon image CDN. Serves the same images globally regardless of marketplace.
|
|
8
|
-
export const AMAZON_IMAGE_BASE = 'https://m.media-amazon.com/images/I';
|
|
9
|
-
// Keepa stores `-1` in salesRanks/price arrays to indicate "no data captured at that timestamp".
|
|
10
|
-
export const KEEPA_NO_DATA_SENTINEL = -1;
|
|
11
|
-
// Allowlist for image filenames in imagesCSV. Defends against path-traversal / SSRF
|
|
12
|
-
// shaped strings (e.g. "../../etc/passwd") in case the CSV is ever influenced by
|
|
13
|
-
// untrusted input. Matches typical Keepa image hashes (e.g. "61abcDEF.jpg").
|
|
14
|
-
export const VALID_IMAGE_FILENAME = /^[A-Za-z0-9._-]+\.(jpg|jpeg|png|webp)$/i;
|
|
15
|
-
//# sourceMappingURL=constant.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constant.js","sourceRoot":"","sources":["../../../src/resources/products/constant.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC;AACvC,mFAAmF;AACnF,mFAAmF;AACnF,mFAAmF;AACnF,MAAM,CAAC,MAAM,oBAAoB,GAAG,eAAe,CAAC;AACpD,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC;AAE9B,8FAA8F;AAC9F,MAAM,CAAC,MAAM,iBAAiB,GAAG,qCAAqC,CAAC;AAEvE,iGAAiG;AACjG,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,CAAC;AAEzC,oFAAoF;AACpF,iFAAiF;AACjF,6EAA6E;AAC7E,MAAM,CAAC,MAAM,oBAAoB,GAAG,yCAAyC,CAAC"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { KeepaError } from '../../core/error.js';
|
|
2
|
-
/** Thrown by `Products.retrieve` when Keepa has no record for the requested ASIN
|
|
3
|
-
* (either no product object returned, or a stub with no title). The `asin`
|
|
4
|
-
* property carries the value the caller passed in, unchanged, so it can be
|
|
5
|
-
* surfaced in user-facing messages without re-deriving it. */
|
|
6
|
-
export declare class ProductNotFoundError extends KeepaError {
|
|
7
|
-
readonly asin: string;
|
|
8
|
-
constructor(asin: string);
|
|
9
|
-
}
|
|
10
|
-
//# sourceMappingURL=error.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../src/resources/products/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD;;;+DAG+D;AAC/D,qBAAa,oBAAqB,SAAQ,UAAU;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,IAAI,EAAE,MAAM;CAKzB"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { KeepaError } from '../../core/error.js';
|
|
2
|
-
/** Thrown by `Products.retrieve` when Keepa has no record for the requested ASIN
|
|
3
|
-
* (either no product object returned, or a stub with no title). The `asin`
|
|
4
|
-
* property carries the value the caller passed in, unchanged, so it can be
|
|
5
|
-
* surfaced in user-facing messages without re-deriving it. */
|
|
6
|
-
export class ProductNotFoundError extends KeepaError {
|
|
7
|
-
asin;
|
|
8
|
-
constructor(asin) {
|
|
9
|
-
super(`Keepa: no product found for ASIN ${asin}`);
|
|
10
|
-
this.name = 'ProductNotFoundError';
|
|
11
|
-
this.asin = asin;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
//# sourceMappingURL=error.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../../src/resources/products/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD;;;+DAG+D;AAC/D,MAAM,OAAO,oBAAqB,SAAQ,UAAU;IACzC,IAAI,CAAS;IAEtB,YAAY,IAAY;QACtB,KAAK,CAAC,oCAAoC,IAAI,EAAE,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export { Products } from './products.js';
|
|
2
|
-
export { extractBsr, isFoundProduct } from './product.util.js';
|
|
3
|
-
export { ProductNotFoundError } from './error.js';
|
|
4
|
-
export type { ProductListParams, ProductRetrieveParams, KeepaProduct, KeepaVariation, KeepaVariationAttribute, KeepaCategoryNode, } from './product.type.js';
|
|
5
|
-
export { PRODUCT_PATH, PRODUCT_LIST_CONTEXT, DEFAULT_DAYS, AMAZON_IMAGE_BASE, KEEPA_NO_DATA_SENTINEL, } from './constant.js';
|
|
6
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/resources/products/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAElD,YAAY,EACV,iBAAiB,EACjB,qBAAqB,EACrB,YAAY,EACZ,cAAc,EACd,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAM3B,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,YAAY,EACZ,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,eAAe,CAAC"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export { Products } from './products.js';
|
|
2
|
-
export { extractBsr, isFoundProduct } from './product.util.js';
|
|
3
|
-
export { ProductNotFoundError } from './error.js';
|
|
4
|
-
// NOTE: raw Keepa wire types (KeepaProductRaw, KeepaProductResponseRaw) are
|
|
5
|
-
// intentionally NOT re-exported. They are an implementation detail — Products.list
|
|
6
|
-
// maps them to the consumer-friendly KeepaProduct shape before returning.
|
|
7
|
-
export { PRODUCT_PATH, PRODUCT_LIST_CONTEXT, DEFAULT_DAYS, AMAZON_IMAGE_BASE, KEEPA_NO_DATA_SENTINEL, } from './constant.js';
|
|
8
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/resources/products/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAWlD,4EAA4E;AAC5E,mFAAmF;AACnF,0EAA0E;AAE1E,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,YAAY,EACZ,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,eAAe,CAAC"}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
export interface KeepaCategoryNodeRaw {
|
|
2
|
-
catId: number;
|
|
3
|
-
name: string;
|
|
4
|
-
}
|
|
5
|
-
export interface KeepaVariationAttributeRaw {
|
|
6
|
-
dimension: string;
|
|
7
|
-
value: string;
|
|
8
|
-
}
|
|
9
|
-
export interface KeepaVariationRaw {
|
|
10
|
-
asin: string;
|
|
11
|
-
attributes?: KeepaVariationAttributeRaw[];
|
|
12
|
-
}
|
|
13
|
-
export interface KeepaImageRaw {
|
|
14
|
-
l: string;
|
|
15
|
-
lH: number;
|
|
16
|
-
lW: number;
|
|
17
|
-
m: string;
|
|
18
|
-
mH: number;
|
|
19
|
-
mW: number;
|
|
20
|
-
}
|
|
21
|
-
export interface KeepaProductRaw {
|
|
22
|
-
asin: string;
|
|
23
|
-
title?: string;
|
|
24
|
-
description?: string;
|
|
25
|
-
parentAsin?: string;
|
|
26
|
-
categoryTree?: KeepaCategoryNodeRaw[];
|
|
27
|
-
rootCategory?: number;
|
|
28
|
-
salesRanks?: Record<string, number[]>;
|
|
29
|
-
images?: KeepaImageRaw[];
|
|
30
|
-
variations?: KeepaVariationRaw[];
|
|
31
|
-
features?: string[];
|
|
32
|
-
}
|
|
33
|
-
export interface KeepaProductResponseRaw {
|
|
34
|
-
products?: KeepaProductRaw[];
|
|
35
|
-
}
|
|
36
|
-
//# sourceMappingURL=product.raw.type.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"product.raw.type.d.ts","sourceRoot":"","sources":["../../../src/resources/products/product.raw.type.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,0BAA0B,EAAE,CAAC;CAC3C;AAID,MAAM,WAAW,aAAa;IAC5B,CAAC,EAAE,MAAM,CAAC;IACV,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,EAAE,MAAM,CAAC;IACV,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;CAC9B"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
// Internal: shapes Keepa actually returns over the wire. The Products resource maps
|
|
2
|
-
// these into the consumer-friendly KeepaProduct (see product.type.ts) before returning,
|
|
3
|
-
// so callers never have to deal with the awkward forms (e.g. comma-separated imagesCSV).
|
|
4
|
-
// Not re-exported through resources/index.ts.
|
|
5
|
-
export {};
|
|
6
|
-
//# sourceMappingURL=product.raw.type.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"product.raw.type.js","sourceRoot":"","sources":["../../../src/resources/products/product.raw.type.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,wFAAwF;AACxF,yFAAyF;AACzF,8CAA8C"}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import type { Marketplace } from '../../lib/marketplace.js';
|
|
2
|
-
export interface ProductListParams {
|
|
3
|
-
asins: string[];
|
|
4
|
-
/** Marketplace code (case-insensitive at runtime). Defaults to 'US'. */
|
|
5
|
-
marketplace?: Marketplace;
|
|
6
|
-
/** Days of price history to include. Defaults to 1. */
|
|
7
|
-
days?: number;
|
|
8
|
-
}
|
|
9
|
-
export interface ProductRetrieveParams {
|
|
10
|
-
asin: string;
|
|
11
|
-
/** Marketplace code (case-insensitive at runtime). Defaults to 'US'. */
|
|
12
|
-
marketplace?: Marketplace;
|
|
13
|
-
/** Days of price history to include. Defaults to 1. */
|
|
14
|
-
days?: number;
|
|
15
|
-
}
|
|
16
|
-
export interface KeepaCategoryNode {
|
|
17
|
-
catId: number;
|
|
18
|
-
name: string;
|
|
19
|
-
}
|
|
20
|
-
export interface KeepaVariationAttribute {
|
|
21
|
-
dimension: string;
|
|
22
|
-
value: string;
|
|
23
|
-
}
|
|
24
|
-
export interface KeepaVariation {
|
|
25
|
-
asin: string;
|
|
26
|
-
attributes?: KeepaVariationAttribute[];
|
|
27
|
-
}
|
|
28
|
-
/** A Keepa product in the consumer-friendly shape. Derived from the raw Keepa
|
|
29
|
-
* response: `imagesCSV` is split into `images: string[]`, and the most-recent
|
|
30
|
-
* real BSR is surfaced as `bsr`. The raw `salesRanks` is preserved for
|
|
31
|
-
* consumers that need to walk the rank history themselves. */
|
|
32
|
-
export interface KeepaProduct {
|
|
33
|
-
asin: string;
|
|
34
|
-
title?: string;
|
|
35
|
-
description?: string;
|
|
36
|
-
parentAsin?: string;
|
|
37
|
-
categoryTree?: KeepaCategoryNode[];
|
|
38
|
-
rootCategory?: number;
|
|
39
|
-
salesRanks?: Record<string, number[]>;
|
|
40
|
-
variations?: KeepaVariation[];
|
|
41
|
-
features?: string[];
|
|
42
|
-
/** Full image URLs derived from imagesCSV using a region-neutral Amazon CDN. */
|
|
43
|
-
images: string[];
|
|
44
|
-
/** Most recent real BSR for the rootCategory. Null when missing or every entry is
|
|
45
|
-
* Keepa's `-1` "no data captured" sentinel. */
|
|
46
|
-
bsr: number | null;
|
|
47
|
-
}
|
|
48
|
-
//# sourceMappingURL=product.type.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"product.type.d.ts","sourceRoot":"","sources":["../../../src/resources/products/product.type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,wEAAwE;IACxE,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,uBAAuB,EAAE,CAAC;CACxC;AAED;;;+DAG+D;AAC/D,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAEpB,gFAAgF;IAChF,MAAM,EAAE,MAAM,EAAE,CAAC;IAEjB;oDACgD;IAChD,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"product.type.js","sourceRoot":"","sources":["../../../src/resources/products/product.type.ts"],"names":[],"mappings":""}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { KeepaProduct } from './product.type.js';
|
|
2
|
-
import type { KeepaProductRaw } from './product.raw.type.js';
|
|
3
|
-
/** Map Keepa's raw wire shape into the consumer-friendly KeepaProduct. */
|
|
4
|
-
export declare function toKeepaProduct(raw: KeepaProductRaw): KeepaProduct;
|
|
5
|
-
/** Returns true when Keepa returned an actual product record (not just a stub
|
|
6
|
-
* for an unknown ASIN). Stubs come back with `title: null`; real listings
|
|
7
|
-
* always have a string. Use as a `.filter()` predicate to drop empty matches. */
|
|
8
|
-
export declare function isFoundProduct(product: KeepaProduct): boolean;
|
|
9
|
-
/** Extract the most recent real BSR from Keepa's `[ts, rank, ts, rank, ...]` salesRanks array.
|
|
10
|
-
* Walks backward through rank entries (odd indices) and skips Keepa's `-1` sentinel which
|
|
11
|
-
* marks "no data captured at that timestamp". Returns `null` if every entry is sentinel.
|
|
12
|
-
* Most consumers won't need this — `Products.list` already fills `bsr` on every returned
|
|
13
|
-
* product. Useful when working with a raw Keepa response. */
|
|
14
|
-
export declare function extractBsr(salesRanks: Record<string, number[]> | undefined, rootCategory: number | undefined): number | null;
|
|
15
|
-
//# sourceMappingURL=product.util.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"product.util.d.ts","sourceRoot":"","sources":["../../../src/resources/products/product.util.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAiB,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE5E,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,GAAG,EAAE,eAAe,GAAG,YAAY,CAcjE;AAYD;;kFAEkF;AAClF,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAE7D;AAED;;;;8DAI8D;AAC9D,wBAAgB,UAAU,CACxB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,SAAS,EAChD,YAAY,EAAE,MAAM,GAAG,SAAS,GAC/B,MAAM,GAAG,IAAI,CAaf"}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { AMAZON_IMAGE_BASE, KEEPA_NO_DATA_SENTINEL, VALID_IMAGE_FILENAME, } from './constant.js';
|
|
2
|
-
/** Map Keepa's raw wire shape into the consumer-friendly KeepaProduct. */
|
|
3
|
-
export function toKeepaProduct(raw) {
|
|
4
|
-
return {
|
|
5
|
-
asin: raw.asin,
|
|
6
|
-
title: raw.title,
|
|
7
|
-
description: raw.description,
|
|
8
|
-
parentAsin: raw.parentAsin,
|
|
9
|
-
categoryTree: raw.categoryTree,
|
|
10
|
-
rootCategory: raw.rootCategory,
|
|
11
|
-
salesRanks: raw.salesRanks,
|
|
12
|
-
variations: raw.variations,
|
|
13
|
-
features: raw.features,
|
|
14
|
-
images: rawImagesToUrls(raw.images),
|
|
15
|
-
bsr: extractBsr(raw.salesRanks, raw.rootCategory),
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
/** Convert Keepa's raw images array into full Amazon image URLs (the large
|
|
19
|
-
* variant). Filters entries whose filename doesn't match the expected
|
|
20
|
-
* alphanumeric image-name pattern as defense-in-depth. */
|
|
21
|
-
function rawImagesToUrls(images) {
|
|
22
|
-
if (!images || images.length === 0)
|
|
23
|
-
return [];
|
|
24
|
-
return images
|
|
25
|
-
.filter((img) => typeof img.l === 'string' && VALID_IMAGE_FILENAME.test(img.l))
|
|
26
|
-
.map((img) => `${AMAZON_IMAGE_BASE}/${img.l}`);
|
|
27
|
-
}
|
|
28
|
-
/** Returns true when Keepa returned an actual product record (not just a stub
|
|
29
|
-
* for an unknown ASIN). Stubs come back with `title: null`; real listings
|
|
30
|
-
* always have a string. Use as a `.filter()` predicate to drop empty matches. */
|
|
31
|
-
export function isFoundProduct(product) {
|
|
32
|
-
return product.title != null;
|
|
33
|
-
}
|
|
34
|
-
/** Extract the most recent real BSR from Keepa's `[ts, rank, ts, rank, ...]` salesRanks array.
|
|
35
|
-
* Walks backward through rank entries (odd indices) and skips Keepa's `-1` sentinel which
|
|
36
|
-
* marks "no data captured at that timestamp". Returns `null` if every entry is sentinel.
|
|
37
|
-
* Most consumers won't need this — `Products.list` already fills `bsr` on every returned
|
|
38
|
-
* product. Useful when working with a raw Keepa response. */
|
|
39
|
-
export function extractBsr(salesRanks, rootCategory) {
|
|
40
|
-
if (!salesRanks || rootCategory === undefined)
|
|
41
|
-
return null;
|
|
42
|
-
const ranks = salesRanks[String(rootCategory)];
|
|
43
|
-
if (!ranks || ranks.length < 2)
|
|
44
|
-
return null;
|
|
45
|
-
// Keepa pairs are [ts, rank, ts, rank, ...]. If length is even, the last index
|
|
46
|
-
// is a rank; if odd (truncated/schema drift), it's a dangling timestamp — skip
|
|
47
|
-
// back one slot so we always start on a rank.
|
|
48
|
-
const start = ranks.length % 2 === 0 ? ranks.length - 1 : ranks.length - 2;
|
|
49
|
-
for (let i = start; i >= 1; i -= 2) {
|
|
50
|
-
const rank = ranks[i];
|
|
51
|
-
if (rank !== undefined && rank !== KEEPA_NO_DATA_SENTINEL)
|
|
52
|
-
return rank;
|
|
53
|
-
}
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
//# sourceMappingURL=product.util.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"product.util.js","sourceRoot":"","sources":["../../../src/resources/products/product.util.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,eAAe,CAAC;AAIvB,0EAA0E;AAC1E,MAAM,UAAU,cAAc,CAAC,GAAoB;IACjD,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,YAAY,EAAE,GAAG,CAAC,YAAY;QAC9B,YAAY,EAAE,GAAG,CAAC,YAAY;QAC9B,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,MAAM,EAAE,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC;QACnC,GAAG,EAAE,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,YAAY,CAAC;KAClD,CAAC;AACJ,CAAC;AAED;;2DAE2D;AAC3D,SAAS,eAAe,CAAC,MAAmC;IAC1D,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC9C,OAAO,MAAM;SACV,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,GAAG,CAAC,CAAC,KAAK,QAAQ,IAAI,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SAC9E,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,iBAAiB,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;AACnD,CAAC;AAED;;kFAEkF;AAClF,MAAM,UAAU,cAAc,CAAC,OAAqB;IAClD,OAAO,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC;AAC/B,CAAC;AAED;;;;8DAI8D;AAC9D,MAAM,UAAU,UAAU,CACxB,UAAgD,EAChD,YAAgC;IAEhC,IAAI,CAAC,UAAU,IAAI,YAAY,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC3D,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/C,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,+EAA+E;IAC/E,+EAA+E;IAC/E,8CAA8C;IAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAC3E,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,sBAAsB;YAAE,OAAO,IAAI,CAAC;IACzE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { APIResource } from '../../core/resource.js';
|
|
2
|
-
import type { KeepaProduct, ProductListParams, ProductRetrieveParams } from './product.type.js';
|
|
3
|
-
export declare class Products extends APIResource {
|
|
4
|
-
list(params: ProductListParams): Promise<KeepaProduct[]>;
|
|
5
|
-
/** Fetch a single product by ASIN. Throws `ProductNotFoundError` when Keepa
|
|
6
|
-
* has no record for the ASIN (no product returned, or a stub with no title). */
|
|
7
|
-
retrieve(params: ProductRetrieveParams): Promise<KeepaProduct>;
|
|
8
|
-
}
|
|
9
|
-
//# sourceMappingURL=products.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"products.d.ts","sourceRoot":"","sources":["../../../src/resources/products/products.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAQrD,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EACjB,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AAK3B,qBAAa,QAAS,SAAQ,WAAW;IACjC,IAAI,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAwB9D;qFACiF;IAC3E,QAAQ,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,YAAY,CAAC;CAQrE"}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { APIResource } from '../../core/resource.js';
|
|
2
|
-
import { resolveDomainId } from '../../lib/marketplace.js';
|
|
3
|
-
import { normalizeAsins } from '../../lib/asin.js';
|
|
4
|
-
import { PRODUCT_PATH, PRODUCT_LIST_CONTEXT, DEFAULT_DAYS, } from './constant.js';
|
|
5
|
-
import { ProductNotFoundError } from './error.js';
|
|
6
|
-
import { toKeepaProduct, isFoundProduct } from './product.util.js';
|
|
7
|
-
export class Products extends APIResource {
|
|
8
|
-
async list(params) {
|
|
9
|
-
if (params.asins.length === 0) {
|
|
10
|
-
throw new Error('At least one ASIN is required');
|
|
11
|
-
}
|
|
12
|
-
if (params.days !== undefined &&
|
|
13
|
-
(!Number.isInteger(params.days) || params.days < 1)) {
|
|
14
|
-
throw new Error(`Invalid days: ${params.days}. Must be a positive integer.`);
|
|
15
|
-
}
|
|
16
|
-
const asins = normalizeAsins(params.asins);
|
|
17
|
-
const domain = resolveDomainId(params.marketplace);
|
|
18
|
-
const data = await this._client._request({
|
|
19
|
-
path: PRODUCT_PATH,
|
|
20
|
-
query: {
|
|
21
|
-
domain,
|
|
22
|
-
asin: asins,
|
|
23
|
-
days: params.days ?? DEFAULT_DAYS,
|
|
24
|
-
},
|
|
25
|
-
context: PRODUCT_LIST_CONTEXT,
|
|
26
|
-
});
|
|
27
|
-
return (data.products ?? []).map(toKeepaProduct);
|
|
28
|
-
}
|
|
29
|
-
/** Fetch a single product by ASIN. Throws `ProductNotFoundError` when Keepa
|
|
30
|
-
* has no record for the ASIN (no product returned, or a stub with no title). */
|
|
31
|
-
async retrieve(params) {
|
|
32
|
-
const { asin, ...rest } = params;
|
|
33
|
-
const [product] = await this.list({ ...rest, asins: [asin] });
|
|
34
|
-
if (!product || !isFoundProduct(product)) {
|
|
35
|
-
throw new ProductNotFoundError(asin);
|
|
36
|
-
}
|
|
37
|
-
return product;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
//# sourceMappingURL=products.js.map
|