@usethrottle/catalog 1.1.0 → 1.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/CHANGELOG.md +28 -0
- package/README.md +135 -24
- package/dist/admin.cjs +16 -16
- package/dist/admin.d.cts +6 -2
- package/dist/admin.d.ts +6 -2
- package/dist/admin.js +1 -1
- package/dist/{catalog-error-s1BINNkt.d.cts → catalog-error-BOaSKgY3.d.cts} +12 -2
- package/dist/{catalog-error-C_zLOtYA.d.ts → catalog-error-CSoPS0-d.d.ts} +12 -2
- package/dist/{chunk-4ORXUW2U.cjs → chunk-2YQNMBDI.cjs} +119 -33
- package/dist/{chunk-JK2UY4CD.js → chunk-3DLH56OX.js} +99 -13
- package/dist/chunk-CADIHOIR.js +496 -0
- package/dist/chunk-GU63WFXI.cjs +496 -0
- package/dist/{client-c2F-eCaL.d.ts → client-6j1Iz-iJ.d.cts} +2 -9
- package/dist/{client-BAoq6jmM.d.cts → client-B3mL2-xJ.d.ts} +2 -9
- package/dist/{contract-types-DhiThMEr.d.cts → contract-types-BRyonOYH.d.cts} +23 -21
- package/dist/{contract-types-DhiThMEr.d.ts → contract-types-BRyonOYH.d.ts} +23 -21
- package/dist/index.cjs +24 -2
- package/dist/index.d.cts +13 -7
- package/dist/index.d.ts +13 -7
- package/dist/index.js +25 -3
- package/dist/react-extras.cjs +42 -0
- package/dist/react-extras.d.cts +23 -0
- package/dist/react-extras.d.ts +23 -0
- package/dist/react-extras.js +42 -0
- package/dist/react.cjs +286 -491
- package/dist/react.d.cts +44 -38
- package/dist/react.d.ts +44 -38
- package/dist/react.js +289 -494
- package/dist/server.cjs +19 -14
- package/dist/server.d.cts +4 -3
- package/dist/server.d.ts +4 -3
- package/dist/server.js +7 -2
- package/dist/{types-DsjoG8ce.d.cts → types-BfveENg1.d.ts} +76 -3
- package/dist/{types-xQLID-4j.d.ts → types-D0PywKnN.d.cts} +76 -3
- package/dist/url.d.cts +2 -1
- package/dist/url.d.ts +2 -1
- package/dist/use-query-CR7r5tam.d.ts +40 -0
- package/dist/use-query-UWf6Pi5g.d.cts +40 -0
- package/dist/version-ev3p03v2.d.cts +8 -0
- package/dist/version-ev3p03v2.d.ts +8 -0
- package/package.json +13 -2
|
@@ -1,9 +1,24 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
2
|
|
|
3
3
|
var _chunkETV4XYOVcjs = require('./chunk-ETV4XYOV.cjs');
|
|
4
4
|
|
|
5
5
|
// src/version.ts
|
|
6
|
-
var SDK_VERSION = true ? "1.
|
|
6
|
+
var SDK_VERSION = true ? "1.3.0" : "0.0.0-dev";
|
|
7
|
+
|
|
8
|
+
// src/index.ts
|
|
9
|
+
var _money = require('@usethrottle/money'); var money = _interopRequireWildcard(_money);
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
7
22
|
|
|
8
23
|
// src/errors/catalog-error.ts
|
|
9
24
|
var _errors = require('@usethrottle/errors');
|
|
@@ -141,6 +156,7 @@ var ERROR_KINDS = Object.freeze({
|
|
|
141
156
|
CUSTOMER_TOKEN_INVALID: "customerToken",
|
|
142
157
|
ORIGIN_NOT_ALLOWED: "origin",
|
|
143
158
|
SERVER_KEY_IN_BROWSER: "origin",
|
|
159
|
+
KEY_NOT_ALLOWED_IN_URL: "origin",
|
|
144
160
|
NOT_FOUND: "base",
|
|
145
161
|
RATE_LIMITED: "rateLimited",
|
|
146
162
|
STOREFRONT_UNAVAILABLE: "base",
|
|
@@ -189,6 +205,8 @@ var ERROR_KINDS = Object.freeze({
|
|
|
189
205
|
cart_session_not_found: "base",
|
|
190
206
|
origin_not_allowed: "origin",
|
|
191
207
|
checkout_unavailable: "base",
|
|
208
|
+
cart_owner_mismatch: "base",
|
|
209
|
+
cart_resolver_mismatch: "base",
|
|
192
210
|
// Client codes.
|
|
193
211
|
TIMEOUT: "timeout",
|
|
194
212
|
NETWORK_ERROR: "network",
|
|
@@ -434,6 +452,10 @@ function resolveOptions(options) {
|
|
|
434
452
|
const publishableKey = checkKey(options.publishableKey);
|
|
435
453
|
const timeoutMs = checkTimeout(_nullishCoalesce(options.timeoutMs, () => ( DEFAULT_TIMEOUT_MS)));
|
|
436
454
|
const retry = options.indexingRetry;
|
|
455
|
+
const keyInQuery = options.keyInQuery;
|
|
456
|
+
if (keyInQuery !== void 0 && typeof keyInQuery !== "boolean") {
|
|
457
|
+
throw optionError("INVALID_REQUEST", "keyInQuery must be a boolean.");
|
|
458
|
+
}
|
|
437
459
|
return {
|
|
438
460
|
publishableKey,
|
|
439
461
|
baseUrl: checkBaseUrl(_nullishCoalesce(options.baseUrl, () => ( DEFAULT_BASE_URL))).replace(
|
|
@@ -450,7 +472,8 @@ function resolveOptions(options) {
|
|
|
450
472
|
cache: options.cache,
|
|
451
473
|
cacheScope: options.cacheScope,
|
|
452
474
|
indexingMaxWaitSeconds: retry === false ? null : _nullishCoalesce(_optionalChain([retry, 'optionalAccess', _14 => _14.maxWaitSeconds]), () => ( INDEXING_MAX_WAIT_S)),
|
|
453
|
-
headers: checkHeaders(options.headers)
|
|
475
|
+
headers: checkHeaders(options.headers),
|
|
476
|
+
keyInQuery: keyInQuery === true
|
|
454
477
|
};
|
|
455
478
|
}
|
|
456
479
|
|
|
@@ -516,6 +539,25 @@ function guarded(work, callerSignal, timeoutMs) {
|
|
|
516
539
|
);
|
|
517
540
|
});
|
|
518
541
|
}
|
|
542
|
+
var KEY_VALUE = /([?&]key=)[^&\s"']*/gu;
|
|
543
|
+
var KEPT_DETAILS = ["name", "code", "errno", "type"];
|
|
544
|
+
var MAX_REDACT_DEPTH = 5;
|
|
545
|
+
function redactKey(cause, depth = 0) {
|
|
546
|
+
if (typeof cause !== "object" || cause === null) return cause;
|
|
547
|
+
const source = cause;
|
|
548
|
+
if (typeof source.message !== "string") return cause;
|
|
549
|
+
if (depth >= MAX_REDACT_DEPTH) return void 0;
|
|
550
|
+
const original = source.message;
|
|
551
|
+
const message = original.replace(KEY_VALUE, "$1[redacted]");
|
|
552
|
+
const nested = redactKey(source.cause, depth + 1);
|
|
553
|
+
if (message === original && nested === source.cause) return cause;
|
|
554
|
+
const copy = new Error(message);
|
|
555
|
+
for (const name of KEPT_DETAILS) {
|
|
556
|
+
if (source[name] !== void 0) copy[name] = source[name];
|
|
557
|
+
}
|
|
558
|
+
if (nested !== void 0) copy.cause = nested;
|
|
559
|
+
return copy;
|
|
560
|
+
}
|
|
519
561
|
function send(fetchFn, url, init, signal, timeoutMs) {
|
|
520
562
|
return guarded(
|
|
521
563
|
async (attemptSignal) => {
|
|
@@ -526,13 +568,13 @@ function send(fetchFn, url, init, signal, timeoutMs) {
|
|
|
526
568
|
signal: attemptSignal
|
|
527
569
|
});
|
|
528
570
|
} catch (cause) {
|
|
529
|
-
throw new NetworkError({ cause });
|
|
571
|
+
throw new NetworkError({ cause: redactKey(cause) });
|
|
530
572
|
}
|
|
531
573
|
let text;
|
|
532
574
|
try {
|
|
533
575
|
text = await response.text();
|
|
534
576
|
} catch (cause) {
|
|
535
|
-
throw new NetworkError({ cause });
|
|
577
|
+
throw new NetworkError({ cause: redactKey(cause) });
|
|
536
578
|
}
|
|
537
579
|
return { status: response.status, headers: response.headers, text };
|
|
538
580
|
},
|
|
@@ -584,6 +626,8 @@ function createTransport(o) {
|
|
|
584
626
|
pairs.push(["currency", currency]);
|
|
585
627
|
if (locale !== void 0) pairs.push(["locale", locale]);
|
|
586
628
|
}
|
|
629
|
+
const keyInUrl = isGet && o.keyInQuery;
|
|
630
|
+
if (keyInUrl) pairs = [..._nullishCoalesce(pairs, () => ( [])), ["key", o.publishableKey]];
|
|
587
631
|
const url = o.baseUrl + spec.path + (pairs === void 0 ? "" : queryString(pairs));
|
|
588
632
|
const timeoutMs = call.timeoutMs === void 0 ? o.timeoutMs : checkTimeout(call.timeoutMs);
|
|
589
633
|
if (isGet && (spec.body !== void 0 || _optionalChain([call, 'access', _24 => _24.fetchInit, 'optionalAccess', _25 => _25.body]) !== void 0)) {
|
|
@@ -591,20 +635,22 @@ function createTransport(o) {
|
|
|
591
635
|
}
|
|
592
636
|
let cacheKey;
|
|
593
637
|
let cached;
|
|
594
|
-
|
|
638
|
+
const bypassCache = spec.tokenFree === true && keyInUrl;
|
|
639
|
+
if (isGet && !bypassCache && o.cache !== void 0 && spec.ifNoneMatch === void 0) {
|
|
595
640
|
try {
|
|
596
|
-
|
|
641
|
+
const scope = o.cacheScope === void 0 || spec.tokenFree === true ? "" : o.cacheScope();
|
|
642
|
+
cacheKey = `${url}\0${scope}`;
|
|
597
643
|
cached = o.cache.get(cacheKey);
|
|
598
644
|
} catch (e3) {
|
|
599
645
|
cacheKey = void 0;
|
|
600
646
|
}
|
|
601
647
|
}
|
|
602
|
-
const ifNoneMatch = _nullishCoalesce(spec.ifNoneMatch, () => ( _optionalChain([cached, 'optionalAccess', _26 => _26.etag])));
|
|
648
|
+
const ifNoneMatch = bypassCache ? void 0 : _nullishCoalesce(spec.ifNoneMatch, () => ( _optionalChain([cached, 'optionalAccess', _26 => _26.etag])));
|
|
603
649
|
const headers = {
|
|
604
650
|
...o.headers,
|
|
605
|
-
accept: "application/json"
|
|
606
|
-
"x-catalog-key": o.publishableKey
|
|
651
|
+
accept: "application/json"
|
|
607
652
|
};
|
|
653
|
+
if (!keyInUrl) headers["x-catalog-key"] = o.publishableKey;
|
|
608
654
|
if (!isGet) headers["content-type"] = "application/json";
|
|
609
655
|
if (ifNoneMatch !== void 0) headers["if-none-match"] = ifNoneMatch;
|
|
610
656
|
if (spec.idempotencyKey !== void 0)
|
|
@@ -612,7 +658,7 @@ function createTransport(o) {
|
|
|
612
658
|
const body = isGet ? void 0 : JSON.stringify(_nullishCoalesce(spec.body, () => ( {})));
|
|
613
659
|
const source = o.customerToken;
|
|
614
660
|
const tokenRead = () => source === void 0 ? Promise.resolve(null) : guarded(() => readToken(source), signal, timeoutMs);
|
|
615
|
-
const first = spec.customerToken === "none" ? null : await tokenRead();
|
|
661
|
+
const first = spec.customerToken === "none" || spec.tokenFree === true ? null : await tokenRead();
|
|
616
662
|
if (first === false && spec.tokenFallback === "throw") {
|
|
617
663
|
throw new CustomerTokenInvalidError({
|
|
618
664
|
code: "CUSTOMER_TOKEN_INVALID",
|
|
@@ -702,6 +748,9 @@ function createTransport(o) {
|
|
|
702
748
|
function createCartSession(options, sessionId, throttleBaseUrl) {
|
|
703
749
|
const base = (_nullishCoalesce(throttleBaseUrl, () => ( THROTTLE_API_URL))).replace(/\/+$/u, "");
|
|
704
750
|
async function call(method, tail, body, opts, accept) {
|
|
751
|
+
return (await exchange(method, tail, body, opts, accept)).data;
|
|
752
|
+
}
|
|
753
|
+
async function exchange(method, tail, body, opts, accept) {
|
|
705
754
|
const signal = _optionalChain([opts, 'optionalAccess', _30 => _30.signal]);
|
|
706
755
|
if (_optionalChain([signal, 'optionalAccess', _31 => _31.aborted])) throw signal.reason;
|
|
707
756
|
const timeoutMs = _optionalChain([opts, 'optionalAccess', _32 => _32.timeoutMs]) === void 0 ? options.timeoutMs : checkTimeout(opts.timeoutMs);
|
|
@@ -739,7 +788,10 @@ function createCartSession(options, sessionId, throttleBaseUrl) {
|
|
|
739
788
|
retryable: false
|
|
740
789
|
});
|
|
741
790
|
}
|
|
742
|
-
return
|
|
791
|
+
return {
|
|
792
|
+
data,
|
|
793
|
+
meta: parsed.meta
|
|
794
|
+
};
|
|
743
795
|
}
|
|
744
796
|
throw toCatalogError(mapInput);
|
|
745
797
|
}
|
|
@@ -782,6 +834,27 @@ function createCartSession(options, sessionId, throttleBaseUrl) {
|
|
|
782
834
|
opts,
|
|
783
835
|
(data) => isHttpUrl(data.checkoutUrl)
|
|
784
836
|
);
|
|
837
|
+
},
|
|
838
|
+
absorb: async (fromSessionId, opts) => {
|
|
839
|
+
const { data, meta } = await exchange(
|
|
840
|
+
"POST",
|
|
841
|
+
() => "/absorb",
|
|
842
|
+
{ fromSessionId },
|
|
843
|
+
opts
|
|
844
|
+
);
|
|
845
|
+
if (typeof data.cart !== "object" || data.cart === null)
|
|
846
|
+
throw new CatalogError({
|
|
847
|
+
code: "INVALID_RESPONSE",
|
|
848
|
+
message: "Throttle answered an absorb without a cart.",
|
|
849
|
+
statusCode: 200,
|
|
850
|
+
source: "throttle",
|
|
851
|
+
retryable: false
|
|
852
|
+
});
|
|
853
|
+
const warnings = _optionalChain([meta, 'optionalAccess', _36 => _36.warnings]);
|
|
854
|
+
return {
|
|
855
|
+
cart: data.cart,
|
|
856
|
+
warnings: Array.isArray(warnings) ? warnings : []
|
|
857
|
+
};
|
|
785
858
|
}
|
|
786
859
|
};
|
|
787
860
|
}
|
|
@@ -810,7 +883,7 @@ function createCarts(transport, options) {
|
|
|
810
883
|
// The input's own currency and locale win over the call's and the
|
|
811
884
|
// client's; the return URLs are sent unchanged (P6-R2).
|
|
812
885
|
create: async (input, opts) => {
|
|
813
|
-
if (_optionalChain([opts, 'optionalAccess',
|
|
886
|
+
if (_optionalChain([opts, 'optionalAccess', _37 => _37.signal, 'optionalAccess', _38 => _38.aborted])) throw opts.signal.reason;
|
|
814
887
|
for (const field of [
|
|
815
888
|
"returnUrl",
|
|
816
889
|
"cancelUrl",
|
|
@@ -833,12 +906,12 @@ function createCarts(transport, options) {
|
|
|
833
906
|
customerToken: "optional",
|
|
834
907
|
tokenFallback: "throw",
|
|
835
908
|
featureRoute: true,
|
|
836
|
-
..._optionalChain([opts, 'optionalAccess',
|
|
909
|
+
..._optionalChain([opts, 'optionalAccess', _39 => _39.idempotencyKey]) === void 0 ? {} : { idempotencyKey: opts.idempotencyKey }
|
|
837
910
|
},
|
|
838
911
|
opts
|
|
839
912
|
);
|
|
840
913
|
},
|
|
841
|
-
session: (sessionId, opts) => createCartSession(options, sessionId, _optionalChain([opts, 'optionalAccess',
|
|
914
|
+
session: (sessionId, opts) => createCartSession(options, sessionId, _optionalChain([opts, 'optionalAccess', _40 => _40.throttleBaseUrl]))
|
|
842
915
|
};
|
|
843
916
|
}
|
|
844
917
|
|
|
@@ -879,11 +952,11 @@ function productsQuery(query = {}) {
|
|
|
879
952
|
featured: query.featured,
|
|
880
953
|
handles: query.handles,
|
|
881
954
|
skus: query.skus,
|
|
882
|
-
year: _optionalChain([vehicle, 'optionalAccess',
|
|
883
|
-
make: _optionalChain([vehicle, 'optionalAccess',
|
|
884
|
-
model: _optionalChain([vehicle, 'optionalAccess',
|
|
885
|
-
submodel: _optionalChain([vehicle, 'optionalAccess',
|
|
886
|
-
engine: _optionalChain([vehicle, 'optionalAccess',
|
|
955
|
+
year: _optionalChain([vehicle, 'optionalAccess', _41 => _41.year]),
|
|
956
|
+
make: _optionalChain([vehicle, 'optionalAccess', _42 => _42.make]),
|
|
957
|
+
model: _optionalChain([vehicle, 'optionalAccess', _43 => _43.model]),
|
|
958
|
+
submodel: _optionalChain([vehicle, 'optionalAccess', _44 => _44.submodel]),
|
|
959
|
+
engine: _optionalChain([vehicle, 'optionalAccess', _45 => _45.engine]),
|
|
887
960
|
sort: query.sort,
|
|
888
961
|
limit: query.limit,
|
|
889
962
|
page: query.page,
|
|
@@ -921,7 +994,7 @@ function createProducts(transport) {
|
|
|
921
994
|
path: `${SF}/products/${pathSegment(handle)}`,
|
|
922
995
|
// Always the full product (P6-R18).
|
|
923
996
|
query: buildQuery(
|
|
924
|
-
{ fields: "full", include: commaList(_optionalChain([opts, 'optionalAccess',
|
|
997
|
+
{ fields: "full", include: commaList(_optionalChain([opts, 'optionalAccess', _46 => _46.include])) },
|
|
925
998
|
["fields", "include"]
|
|
926
999
|
),
|
|
927
1000
|
customerToken: "optional",
|
|
@@ -937,7 +1010,7 @@ function createProducts(transport) {
|
|
|
937
1010
|
method: "GET",
|
|
938
1011
|
path: `${SF}/products/${pathSegment(handle)}/related`,
|
|
939
1012
|
query: buildQuery(
|
|
940
|
-
{ limit: _optionalChain([opts, 'optionalAccess',
|
|
1013
|
+
{ limit: _optionalChain([opts, 'optionalAccess', _47 => _47.limit]), fields: commaList(_optionalChain([opts, 'optionalAccess', _48 => _48.fields])) },
|
|
941
1014
|
["limit", "fields"]
|
|
942
1015
|
),
|
|
943
1016
|
customerToken: "optional",
|
|
@@ -973,8 +1046,10 @@ function createSuggest(transport) {
|
|
|
973
1046
|
{
|
|
974
1047
|
method: "GET",
|
|
975
1048
|
path: `${SF}/suggest`,
|
|
976
|
-
query: buildQuery({ q, limit: _optionalChain([opts, 'optionalAccess',
|
|
977
|
-
|
|
1049
|
+
query: buildQuery({ q, limit: _optionalChain([opts, 'optionalAccess', _49 => _49.limit]) }, ["q", "limit"]),
|
|
1050
|
+
// Never a customer token (P8-R22): list prices for everyone.
|
|
1051
|
+
customerToken: "none",
|
|
1052
|
+
tokenFree: true,
|
|
978
1053
|
tokenFallback: "anonymous",
|
|
979
1054
|
featureRoute: true,
|
|
980
1055
|
context: "priced"
|
|
@@ -996,10 +1071,10 @@ function createReviews(transport) {
|
|
|
996
1071
|
path: reviewsPath(handle),
|
|
997
1072
|
query: buildQuery(
|
|
998
1073
|
{
|
|
999
|
-
sort: _optionalChain([opts, 'optionalAccess',
|
|
1000
|
-
rating: _optionalChain([opts, 'optionalAccess',
|
|
1001
|
-
limit: _optionalChain([opts, 'optionalAccess',
|
|
1002
|
-
cursor: _optionalChain([opts, 'optionalAccess',
|
|
1074
|
+
sort: _optionalChain([opts, 'optionalAccess', _50 => _50.sort]),
|
|
1075
|
+
rating: _optionalChain([opts, 'optionalAccess', _51 => _51.rating]),
|
|
1076
|
+
limit: _optionalChain([opts, 'optionalAccess', _52 => _52.limit]),
|
|
1077
|
+
cursor: _optionalChain([opts, 'optionalAccess', _53 => _53.cursor])
|
|
1003
1078
|
},
|
|
1004
1079
|
["sort", "rating", "limit", "cursor"]
|
|
1005
1080
|
),
|
|
@@ -1031,7 +1106,7 @@ function createReviews(transport) {
|
|
|
1031
1106
|
customerToken: "required",
|
|
1032
1107
|
tokenFallback: "throw",
|
|
1033
1108
|
featureRoute: false,
|
|
1034
|
-
..._optionalChain([opts, 'optionalAccess',
|
|
1109
|
+
..._optionalChain([opts, 'optionalAccess', _54 => _54.idempotencyKey]) === void 0 ? {} : { idempotencyKey: opts.idempotencyKey }
|
|
1035
1110
|
},
|
|
1036
1111
|
opts
|
|
1037
1112
|
)
|
|
@@ -1047,7 +1122,7 @@ function createCategories(transport) {
|
|
|
1047
1122
|
{
|
|
1048
1123
|
method: "GET",
|
|
1049
1124
|
path: `${SF2}/categories`,
|
|
1050
|
-
query: buildQuery({ depth: _optionalChain([opts, 'optionalAccess',
|
|
1125
|
+
query: buildQuery({ depth: _optionalChain([opts, 'optionalAccess', _55 => _55.depth]) }, ["depth"]),
|
|
1051
1126
|
customerToken: "none",
|
|
1052
1127
|
tokenFallback: "anonymous",
|
|
1053
1128
|
featureRoute: true,
|
|
@@ -1076,7 +1151,7 @@ function createTags(transport) {
|
|
|
1076
1151
|
{
|
|
1077
1152
|
method: "GET",
|
|
1078
1153
|
path: `${SF2}/tags`,
|
|
1079
|
-
query: buildQuery({ q: _optionalChain([opts, 'optionalAccess',
|
|
1154
|
+
query: buildQuery({ q: _optionalChain([opts, 'optionalAccess', _56 => _56.q]), limit: _optionalChain([opts, 'optionalAccess', _57 => _57.limit]) }, ["q", "limit"]),
|
|
1080
1155
|
customerToken: "none",
|
|
1081
1156
|
tokenFallback: "anonymous",
|
|
1082
1157
|
featureRoute: true
|
|
@@ -1092,7 +1167,7 @@ function createCollections(transport) {
|
|
|
1092
1167
|
{
|
|
1093
1168
|
method: "GET",
|
|
1094
1169
|
path: `${SF2}/collections`,
|
|
1095
|
-
query: buildQuery({ limit: _optionalChain([opts, 'optionalAccess',
|
|
1170
|
+
query: buildQuery({ limit: _optionalChain([opts, 'optionalAccess', _58 => _58.limit]), cursor: _optionalChain([opts, 'optionalAccess', _59 => _59.cursor]) }, [
|
|
1096
1171
|
"limit",
|
|
1097
1172
|
"cursor"
|
|
1098
1173
|
]),
|
|
@@ -1178,4 +1253,15 @@ function createCatalogClient(options) {
|
|
|
1178
1253
|
|
|
1179
1254
|
|
|
1180
1255
|
|
|
1181
|
-
|
|
1256
|
+
|
|
1257
|
+
|
|
1258
|
+
|
|
1259
|
+
|
|
1260
|
+
|
|
1261
|
+
|
|
1262
|
+
|
|
1263
|
+
|
|
1264
|
+
|
|
1265
|
+
|
|
1266
|
+
|
|
1267
|
+
exports.SDK_VERSION = SDK_VERSION; exports.CatalogError = CatalogError; exports.RateLimitedError = RateLimitedError; exports.OriginNotAllowedError = OriginNotAllowedError; exports.CustomerTokenInvalidError = CustomerTokenInvalidError; exports.CartLineError = CartLineError; exports.TimeoutError = TimeoutError; exports.NetworkError = NetworkError; exports.FeatureUnavailableError = FeatureUnavailableError; exports.isCatalogError = isCatalogError; exports.DEFAULT_BASE_URL = DEFAULT_BASE_URL; exports.THROTTLE_CHECKOUT_URL = THROTTLE_CHECKOUT_URL; exports.RATE_LIMIT_DEFAULT_RETRY_S = RATE_LIMIT_DEFAULT_RETRY_S; exports.STALE_MS = STALE_MS; exports.CACHE_MAX_ENTRIES = CACHE_MAX_ENTRIES; exports.SUGGEST_DEBOUNCE_MS = SUGGEST_DEBOUNCE_MS; exports.SUGGEST_MIN_CHARS = SUGGEST_MIN_CHARS; exports.INDEXING_REVALIDATE_MS = INDEXING_REVALIDATE_MS; exports.CACHE_TAG = CACHE_TAG; exports.TAG_MAX_CHARS = TAG_MAX_CHARS; exports.DEFAULT_REVALIDATE_S = DEFAULT_REVALIDATE_S; exports.LIST_PAGE_SIZE = LIST_PAGE_SIZE; exports.LIST_MAX_HANDLES = LIST_MAX_HANDLES; exports.CATEGORY_TREE_MAX_DEPTH = CATEGORY_TREE_MAX_DEPTH; exports.createCatalogClient = createCatalogClient; exports.money = money; exports.CURRENCIES = _money.CURRENCIES; exports.UnknownCurrencyError = _money.UnknownCurrencyError; exports.currencySymbol = _money.currencySymbol; exports.formatMoney = _money.formatMoney; exports.isKnownCurrency = _money.isKnownCurrency; exports.minorUnitsOf = _money.minorUnitsOf; exports.moneyValue = _money.moneyValue; exports.parseMoney = _money.parseMoney; exports.toDecimalString = _money.toDecimalString; exports.toMinor = _money.toMinor;
|
|
@@ -3,7 +3,22 @@ import {
|
|
|
3
3
|
} from "./chunk-PKBMQBKP.js";
|
|
4
4
|
|
|
5
5
|
// src/version.ts
|
|
6
|
-
var SDK_VERSION = true ? "1.
|
|
6
|
+
var SDK_VERSION = true ? "1.3.0" : "0.0.0-dev";
|
|
7
|
+
|
|
8
|
+
// src/index.ts
|
|
9
|
+
import * as money from "@usethrottle/money";
|
|
10
|
+
import {
|
|
11
|
+
CURRENCIES,
|
|
12
|
+
UnknownCurrencyError,
|
|
13
|
+
currencySymbol,
|
|
14
|
+
formatMoney,
|
|
15
|
+
isKnownCurrency,
|
|
16
|
+
minorUnitsOf,
|
|
17
|
+
moneyValue,
|
|
18
|
+
parseMoney,
|
|
19
|
+
toDecimalString,
|
|
20
|
+
toMinor
|
|
21
|
+
} from "@usethrottle/money";
|
|
7
22
|
|
|
8
23
|
// src/errors/catalog-error.ts
|
|
9
24
|
import { ThrottleError } from "@usethrottle/errors";
|
|
@@ -141,6 +156,7 @@ var ERROR_KINDS = Object.freeze({
|
|
|
141
156
|
CUSTOMER_TOKEN_INVALID: "customerToken",
|
|
142
157
|
ORIGIN_NOT_ALLOWED: "origin",
|
|
143
158
|
SERVER_KEY_IN_BROWSER: "origin",
|
|
159
|
+
KEY_NOT_ALLOWED_IN_URL: "origin",
|
|
144
160
|
NOT_FOUND: "base",
|
|
145
161
|
RATE_LIMITED: "rateLimited",
|
|
146
162
|
STOREFRONT_UNAVAILABLE: "base",
|
|
@@ -189,6 +205,8 @@ var ERROR_KINDS = Object.freeze({
|
|
|
189
205
|
cart_session_not_found: "base",
|
|
190
206
|
origin_not_allowed: "origin",
|
|
191
207
|
checkout_unavailable: "base",
|
|
208
|
+
cart_owner_mismatch: "base",
|
|
209
|
+
cart_resolver_mismatch: "base",
|
|
192
210
|
// Client codes.
|
|
193
211
|
TIMEOUT: "timeout",
|
|
194
212
|
NETWORK_ERROR: "network",
|
|
@@ -434,6 +452,10 @@ function resolveOptions(options) {
|
|
|
434
452
|
const publishableKey = checkKey(options.publishableKey);
|
|
435
453
|
const timeoutMs = checkTimeout(options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
436
454
|
const retry = options.indexingRetry;
|
|
455
|
+
const keyInQuery = options.keyInQuery;
|
|
456
|
+
if (keyInQuery !== void 0 && typeof keyInQuery !== "boolean") {
|
|
457
|
+
throw optionError("INVALID_REQUEST", "keyInQuery must be a boolean.");
|
|
458
|
+
}
|
|
437
459
|
return {
|
|
438
460
|
publishableKey,
|
|
439
461
|
baseUrl: checkBaseUrl(options.baseUrl ?? DEFAULT_BASE_URL).replace(
|
|
@@ -450,7 +472,8 @@ function resolveOptions(options) {
|
|
|
450
472
|
cache: options.cache,
|
|
451
473
|
cacheScope: options.cacheScope,
|
|
452
474
|
indexingMaxWaitSeconds: retry === false ? null : retry?.maxWaitSeconds ?? INDEXING_MAX_WAIT_S,
|
|
453
|
-
headers: checkHeaders(options.headers)
|
|
475
|
+
headers: checkHeaders(options.headers),
|
|
476
|
+
keyInQuery: keyInQuery === true
|
|
454
477
|
};
|
|
455
478
|
}
|
|
456
479
|
|
|
@@ -516,6 +539,25 @@ function guarded(work, callerSignal, timeoutMs) {
|
|
|
516
539
|
);
|
|
517
540
|
});
|
|
518
541
|
}
|
|
542
|
+
var KEY_VALUE = /([?&]key=)[^&\s"']*/gu;
|
|
543
|
+
var KEPT_DETAILS = ["name", "code", "errno", "type"];
|
|
544
|
+
var MAX_REDACT_DEPTH = 5;
|
|
545
|
+
function redactKey(cause, depth = 0) {
|
|
546
|
+
if (typeof cause !== "object" || cause === null) return cause;
|
|
547
|
+
const source = cause;
|
|
548
|
+
if (typeof source.message !== "string") return cause;
|
|
549
|
+
if (depth >= MAX_REDACT_DEPTH) return void 0;
|
|
550
|
+
const original = source.message;
|
|
551
|
+
const message = original.replace(KEY_VALUE, "$1[redacted]");
|
|
552
|
+
const nested = redactKey(source.cause, depth + 1);
|
|
553
|
+
if (message === original && nested === source.cause) return cause;
|
|
554
|
+
const copy = new Error(message);
|
|
555
|
+
for (const name of KEPT_DETAILS) {
|
|
556
|
+
if (source[name] !== void 0) copy[name] = source[name];
|
|
557
|
+
}
|
|
558
|
+
if (nested !== void 0) copy.cause = nested;
|
|
559
|
+
return copy;
|
|
560
|
+
}
|
|
519
561
|
function send(fetchFn, url, init, signal, timeoutMs) {
|
|
520
562
|
return guarded(
|
|
521
563
|
async (attemptSignal) => {
|
|
@@ -526,13 +568,13 @@ function send(fetchFn, url, init, signal, timeoutMs) {
|
|
|
526
568
|
signal: attemptSignal
|
|
527
569
|
});
|
|
528
570
|
} catch (cause) {
|
|
529
|
-
throw new NetworkError({ cause });
|
|
571
|
+
throw new NetworkError({ cause: redactKey(cause) });
|
|
530
572
|
}
|
|
531
573
|
let text;
|
|
532
574
|
try {
|
|
533
575
|
text = await response.text();
|
|
534
576
|
} catch (cause) {
|
|
535
|
-
throw new NetworkError({ cause });
|
|
577
|
+
throw new NetworkError({ cause: redactKey(cause) });
|
|
536
578
|
}
|
|
537
579
|
return { status: response.status, headers: response.headers, text };
|
|
538
580
|
},
|
|
@@ -584,6 +626,8 @@ function createTransport(o) {
|
|
|
584
626
|
pairs.push(["currency", currency]);
|
|
585
627
|
if (locale !== void 0) pairs.push(["locale", locale]);
|
|
586
628
|
}
|
|
629
|
+
const keyInUrl = isGet && o.keyInQuery;
|
|
630
|
+
if (keyInUrl) pairs = [...pairs ?? [], ["key", o.publishableKey]];
|
|
587
631
|
const url = o.baseUrl + spec.path + (pairs === void 0 ? "" : queryString(pairs));
|
|
588
632
|
const timeoutMs = call.timeoutMs === void 0 ? o.timeoutMs : checkTimeout(call.timeoutMs);
|
|
589
633
|
if (isGet && (spec.body !== void 0 || call.fetchInit?.body !== void 0)) {
|
|
@@ -591,20 +635,22 @@ function createTransport(o) {
|
|
|
591
635
|
}
|
|
592
636
|
let cacheKey;
|
|
593
637
|
let cached;
|
|
594
|
-
|
|
638
|
+
const bypassCache = spec.tokenFree === true && keyInUrl;
|
|
639
|
+
if (isGet && !bypassCache && o.cache !== void 0 && spec.ifNoneMatch === void 0) {
|
|
595
640
|
try {
|
|
596
|
-
|
|
641
|
+
const scope = o.cacheScope === void 0 || spec.tokenFree === true ? "" : o.cacheScope();
|
|
642
|
+
cacheKey = `${url}\0${scope}`;
|
|
597
643
|
cached = o.cache.get(cacheKey);
|
|
598
644
|
} catch {
|
|
599
645
|
cacheKey = void 0;
|
|
600
646
|
}
|
|
601
647
|
}
|
|
602
|
-
const ifNoneMatch = spec.ifNoneMatch ?? cached?.etag;
|
|
648
|
+
const ifNoneMatch = bypassCache ? void 0 : spec.ifNoneMatch ?? cached?.etag;
|
|
603
649
|
const headers = {
|
|
604
650
|
...o.headers,
|
|
605
|
-
accept: "application/json"
|
|
606
|
-
"x-catalog-key": o.publishableKey
|
|
651
|
+
accept: "application/json"
|
|
607
652
|
};
|
|
653
|
+
if (!keyInUrl) headers["x-catalog-key"] = o.publishableKey;
|
|
608
654
|
if (!isGet) headers["content-type"] = "application/json";
|
|
609
655
|
if (ifNoneMatch !== void 0) headers["if-none-match"] = ifNoneMatch;
|
|
610
656
|
if (spec.idempotencyKey !== void 0)
|
|
@@ -612,7 +658,7 @@ function createTransport(o) {
|
|
|
612
658
|
const body = isGet ? void 0 : JSON.stringify(spec.body ?? {});
|
|
613
659
|
const source = o.customerToken;
|
|
614
660
|
const tokenRead = () => source === void 0 ? Promise.resolve(null) : guarded(() => readToken(source), signal, timeoutMs);
|
|
615
|
-
const first = spec.customerToken === "none" ? null : await tokenRead();
|
|
661
|
+
const first = spec.customerToken === "none" || spec.tokenFree === true ? null : await tokenRead();
|
|
616
662
|
if (first === false && spec.tokenFallback === "throw") {
|
|
617
663
|
throw new CustomerTokenInvalidError({
|
|
618
664
|
code: "CUSTOMER_TOKEN_INVALID",
|
|
@@ -702,6 +748,9 @@ function createTransport(o) {
|
|
|
702
748
|
function createCartSession(options, sessionId, throttleBaseUrl) {
|
|
703
749
|
const base = (throttleBaseUrl ?? THROTTLE_API_URL).replace(/\/+$/u, "");
|
|
704
750
|
async function call(method, tail, body, opts, accept) {
|
|
751
|
+
return (await exchange(method, tail, body, opts, accept)).data;
|
|
752
|
+
}
|
|
753
|
+
async function exchange(method, tail, body, opts, accept) {
|
|
705
754
|
const signal = opts?.signal;
|
|
706
755
|
if (signal?.aborted) throw signal.reason;
|
|
707
756
|
const timeoutMs = opts?.timeoutMs === void 0 ? options.timeoutMs : checkTimeout(opts.timeoutMs);
|
|
@@ -739,7 +788,10 @@ function createCartSession(options, sessionId, throttleBaseUrl) {
|
|
|
739
788
|
retryable: false
|
|
740
789
|
});
|
|
741
790
|
}
|
|
742
|
-
return
|
|
791
|
+
return {
|
|
792
|
+
data,
|
|
793
|
+
meta: parsed.meta
|
|
794
|
+
};
|
|
743
795
|
}
|
|
744
796
|
throw toCatalogError(mapInput);
|
|
745
797
|
}
|
|
@@ -782,6 +834,27 @@ function createCartSession(options, sessionId, throttleBaseUrl) {
|
|
|
782
834
|
opts,
|
|
783
835
|
(data) => isHttpUrl(data.checkoutUrl)
|
|
784
836
|
);
|
|
837
|
+
},
|
|
838
|
+
absorb: async (fromSessionId, opts) => {
|
|
839
|
+
const { data, meta } = await exchange(
|
|
840
|
+
"POST",
|
|
841
|
+
() => "/absorb",
|
|
842
|
+
{ fromSessionId },
|
|
843
|
+
opts
|
|
844
|
+
);
|
|
845
|
+
if (typeof data.cart !== "object" || data.cart === null)
|
|
846
|
+
throw new CatalogError({
|
|
847
|
+
code: "INVALID_RESPONSE",
|
|
848
|
+
message: "Throttle answered an absorb without a cart.",
|
|
849
|
+
statusCode: 200,
|
|
850
|
+
source: "throttle",
|
|
851
|
+
retryable: false
|
|
852
|
+
});
|
|
853
|
+
const warnings = meta?.warnings;
|
|
854
|
+
return {
|
|
855
|
+
cart: data.cart,
|
|
856
|
+
warnings: Array.isArray(warnings) ? warnings : []
|
|
857
|
+
};
|
|
785
858
|
}
|
|
786
859
|
};
|
|
787
860
|
}
|
|
@@ -974,7 +1047,9 @@ function createSuggest(transport) {
|
|
|
974
1047
|
method: "GET",
|
|
975
1048
|
path: `${SF}/suggest`,
|
|
976
1049
|
query: buildQuery({ q, limit: opts?.limit }, ["q", "limit"]),
|
|
977
|
-
|
|
1050
|
+
// Never a customer token (P8-R22): list prices for everyone.
|
|
1051
|
+
customerToken: "none",
|
|
1052
|
+
tokenFree: true,
|
|
978
1053
|
tokenFallback: "anonymous",
|
|
979
1054
|
featureRoute: true,
|
|
980
1055
|
context: "priced"
|
|
@@ -1177,5 +1252,16 @@ export {
|
|
|
1177
1252
|
LIST_PAGE_SIZE,
|
|
1178
1253
|
LIST_MAX_HANDLES,
|
|
1179
1254
|
CATEGORY_TREE_MAX_DEPTH,
|
|
1180
|
-
createCatalogClient
|
|
1255
|
+
createCatalogClient,
|
|
1256
|
+
money,
|
|
1257
|
+
CURRENCIES,
|
|
1258
|
+
UnknownCurrencyError,
|
|
1259
|
+
currencySymbol,
|
|
1260
|
+
formatMoney,
|
|
1261
|
+
isKnownCurrency,
|
|
1262
|
+
minorUnitsOf,
|
|
1263
|
+
moneyValue,
|
|
1264
|
+
parseMoney,
|
|
1265
|
+
toDecimalString,
|
|
1266
|
+
toMinor
|
|
1181
1267
|
};
|