@swell/apps-sdk 1.0.150 → 1.0.152
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/dist/index.cjs +767 -185
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +747 -185
- package/dist/index.js.map +4 -4
- package/dist/index.mjs +757 -185
- package/dist/index.mjs.map +4 -4
- package/dist/src/cache/cache-api-stub.d.ts +25 -0
- package/dist/src/cache/index.d.ts +2 -0
- package/dist/src/cache/worker-html-cache.d.ts +43 -0
- package/dist/src/compatibility/drops/all_products.d.ts +1 -1
- package/dist/src/compatibility/drops/articles.d.ts +1 -1
- package/dist/src/compatibility/drops/blogs.d.ts +1 -1
- package/dist/src/compatibility/drops/collections.d.ts +2 -3
- package/dist/src/compatibility/drops/images.d.ts +1 -1
- package/dist/src/compatibility/drops/pages.d.ts +2 -3
- package/dist/src/compatibility/shopify-objects/collections.d.ts +2 -2
- package/dist/src/content.d.ts +3 -3
- package/dist/src/index.d.ts +3 -0
- package/dist/src/liquid/filters/shopify/default_pagination.d.ts +1 -1
- package/dist/src/resources/account.d.ts +4 -4
- package/dist/src/resources/addresses.d.ts +7 -0
- package/dist/src/resources/blog.d.ts +5 -4
- package/dist/src/resources/blog_category.d.ts +5 -4
- package/dist/src/resources/cart.d.ts +4 -4
- package/dist/src/resources/categories.d.ts +7 -0
- package/dist/src/resources/category.d.ts +5 -4
- package/dist/src/resources/index.d.ts +18 -9
- package/dist/src/resources/order.d.ts +5 -4
- package/dist/src/resources/orders.d.ts +7 -0
- package/dist/src/resources/page.d.ts +5 -4
- package/dist/src/resources/predictive_search.d.ts +6 -0
- package/dist/src/resources/product.d.ts +5 -19
- package/dist/src/resources/product_helpers.d.ts +12 -2
- package/dist/src/resources/product_recommendations.d.ts +6 -0
- package/dist/src/resources/search.d.ts +6 -0
- package/dist/src/resources/subscription.d.ts +7 -0
- package/dist/src/resources/subscriptions.d.ts +7 -0
- package/dist/src/resources/swell_types.d.ts +66 -9
- package/dist/src/resources/variant.d.ts +8 -8
- package/dist/src/resources.d.ts +11 -12
- package/dist/types/shopify.d.ts +2 -2
- package/dist/types/swell.d.ts +3 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -66,25 +66,35 @@ __export(index_exports, {
|
|
|
66
66
|
StorefrontResource: () => StorefrontResource,
|
|
67
67
|
Swell: () => Swell,
|
|
68
68
|
SwellAccount: () => SwellAccount,
|
|
69
|
+
SwellAddresses: () => SwellAddresses,
|
|
69
70
|
SwellBackendAPI: () => SwellBackendAPI,
|
|
70
71
|
SwellBlog: () => SwellBlog,
|
|
71
72
|
SwellBlogCategory: () => SwellBlogCategory,
|
|
72
73
|
SwellCart: () => SwellCart,
|
|
74
|
+
SwellCategories: () => SwellCategories,
|
|
73
75
|
SwellCategory: () => SwellCategory,
|
|
74
76
|
SwellError: () => SwellError,
|
|
75
77
|
SwellOrder: () => SwellOrder,
|
|
78
|
+
SwellOrders: () => SwellOrders,
|
|
76
79
|
SwellPage: () => SwellPage,
|
|
80
|
+
SwellPredictiveSearch: () => SwellPredictiveSearch,
|
|
77
81
|
SwellProduct: () => SwellProduct,
|
|
82
|
+
SwellProductRecommendations: () => SwellProductRecommendations,
|
|
83
|
+
SwellSearch: () => SwellSearch,
|
|
78
84
|
SwellStorefrontCollection: () => SwellStorefrontCollection,
|
|
79
85
|
SwellStorefrontPagination: () => SwellStorefrontPagination,
|
|
80
86
|
SwellStorefrontRecord: () => SwellStorefrontRecord,
|
|
81
87
|
SwellStorefrontResource: () => SwellStorefrontResource,
|
|
82
88
|
SwellStorefrontSingleton: () => SwellStorefrontSingleton,
|
|
89
|
+
SwellSubscription: () => SwellSubscription,
|
|
90
|
+
SwellSubscriptions: () => SwellSubscriptions,
|
|
83
91
|
SwellTheme: () => SwellTheme3,
|
|
92
|
+
SwellVariant: () => SwellVariant,
|
|
84
93
|
ThemeColor: () => ThemeColor,
|
|
85
94
|
ThemeFont: () => ThemeFont,
|
|
86
95
|
ThemeForm: () => ThemeForm,
|
|
87
96
|
ThemeFormErrors: () => ThemeFormErrors,
|
|
97
|
+
WorkerHtmlCache: () => WorkerHtmlCache,
|
|
88
98
|
adaptShopifyFontData: () => adaptShopifyFontData,
|
|
89
99
|
adaptShopifyFormData: () => adaptShopifyFormData,
|
|
90
100
|
adaptShopifyMenuData: () => adaptShopifyMenuData,
|
|
@@ -151,72 +161,6 @@ var import_qs2 = __toESM(require("qs"), 1);
|
|
|
151
161
|
var import_keyv = require("keyv");
|
|
152
162
|
var import_cache_manager = require("cache-manager");
|
|
153
163
|
|
|
154
|
-
// src/cache/cf-worker-kv-keyv-adapter.ts
|
|
155
|
-
var CFWorkerKVKeyvAdapter = class {
|
|
156
|
-
store;
|
|
157
|
-
namespace;
|
|
158
|
-
// magically passed in from Keyv
|
|
159
|
-
opts;
|
|
160
|
-
constructor(store) {
|
|
161
|
-
this.store = store;
|
|
162
|
-
this.opts = null;
|
|
163
|
-
this.namespace = "dummy";
|
|
164
|
-
}
|
|
165
|
-
async has(key) {
|
|
166
|
-
const stream = await this.store.get(key, "stream");
|
|
167
|
-
if (stream !== null) {
|
|
168
|
-
await stream.cancel();
|
|
169
|
-
return true;
|
|
170
|
-
}
|
|
171
|
-
return false;
|
|
172
|
-
}
|
|
173
|
-
async get(key) {
|
|
174
|
-
const value = await this.store.get(key);
|
|
175
|
-
return value !== null ? value : void 0;
|
|
176
|
-
}
|
|
177
|
-
set(key, value, ttl) {
|
|
178
|
-
if (typeof ttl === "number") {
|
|
179
|
-
ttl = Math.max(60, ttl / 1e3);
|
|
180
|
-
}
|
|
181
|
-
return this.store.put(key, value, { expirationTtl: ttl });
|
|
182
|
-
}
|
|
183
|
-
async delete(key) {
|
|
184
|
-
await this.store.delete(key);
|
|
185
|
-
return true;
|
|
186
|
-
}
|
|
187
|
-
async clear() {
|
|
188
|
-
let cursor = "";
|
|
189
|
-
let complete = false;
|
|
190
|
-
const prefix = `${this.namespace}:`;
|
|
191
|
-
do {
|
|
192
|
-
const response = await this.store.list({
|
|
193
|
-
prefix,
|
|
194
|
-
cursor: cursor || void 0
|
|
195
|
-
});
|
|
196
|
-
cursor = response.cursor ?? "";
|
|
197
|
-
complete = response.list_complete;
|
|
198
|
-
if (response.keys.length > 0) {
|
|
199
|
-
await Promise.all(
|
|
200
|
-
response.keys.map((key) => {
|
|
201
|
-
return this.store.delete(key.name);
|
|
202
|
-
})
|
|
203
|
-
);
|
|
204
|
-
}
|
|
205
|
-
} while (!complete);
|
|
206
|
-
}
|
|
207
|
-
on(_event, _listener) {
|
|
208
|
-
return this;
|
|
209
|
-
}
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
// src/utils/index.ts
|
|
213
|
-
var import_qs = __toESM(require("qs"), 1);
|
|
214
|
-
var import_lodash_es3 = require("lodash-es");
|
|
215
|
-
var import_json52 = __toESM(require("json5"), 1);
|
|
216
|
-
|
|
217
|
-
// src/resources.ts
|
|
218
|
-
var import_lodash_es2 = require("lodash-es");
|
|
219
|
-
|
|
220
164
|
// src/utils/logger.ts
|
|
221
165
|
var logLevels = {
|
|
222
166
|
error: 0,
|
|
@@ -308,6 +252,80 @@ function createTraceId(data) {
|
|
|
308
252
|
return (hash >>> 0).toString(16);
|
|
309
253
|
}
|
|
310
254
|
|
|
255
|
+
// src/cache/cf-worker-kv-keyv-adapter.ts
|
|
256
|
+
var CFWorkerKVKeyvAdapter = class {
|
|
257
|
+
store;
|
|
258
|
+
namespace;
|
|
259
|
+
// magically passed in from Keyv
|
|
260
|
+
opts;
|
|
261
|
+
constructor(store) {
|
|
262
|
+
this.store = store;
|
|
263
|
+
this.opts = null;
|
|
264
|
+
this.namespace = "dummy";
|
|
265
|
+
}
|
|
266
|
+
async has(key) {
|
|
267
|
+
const stream = await this.store.get(key, "stream");
|
|
268
|
+
if (stream !== null) {
|
|
269
|
+
await stream.cancel();
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
async get(key) {
|
|
275
|
+
const trace = createTraceId();
|
|
276
|
+
logger.debug("[SDK] kv.get", { key, trace });
|
|
277
|
+
const value = await this.store.get(key);
|
|
278
|
+
const result = value !== null ? value : void 0;
|
|
279
|
+
logger.debug(`[SDK] kv.get ${value !== null ? "HIT" : "MISS"}`, {
|
|
280
|
+
key,
|
|
281
|
+
trace
|
|
282
|
+
});
|
|
283
|
+
return result;
|
|
284
|
+
}
|
|
285
|
+
set(key, value, ttl) {
|
|
286
|
+
if (typeof ttl === "number") {
|
|
287
|
+
ttl = Math.max(60, ttl / 1e3);
|
|
288
|
+
}
|
|
289
|
+
logger.debug("[SDK] kv.set", { key });
|
|
290
|
+
return this.store.put(key, value, { expirationTtl: ttl });
|
|
291
|
+
}
|
|
292
|
+
async delete(key) {
|
|
293
|
+
await this.store.delete(key);
|
|
294
|
+
return true;
|
|
295
|
+
}
|
|
296
|
+
async clear() {
|
|
297
|
+
let cursor = "";
|
|
298
|
+
let complete = false;
|
|
299
|
+
const prefix = `${this.namespace}:`;
|
|
300
|
+
do {
|
|
301
|
+
const response = await this.store.list({
|
|
302
|
+
prefix,
|
|
303
|
+
cursor: cursor || void 0
|
|
304
|
+
});
|
|
305
|
+
cursor = response.cursor ?? "";
|
|
306
|
+
complete = response.list_complete;
|
|
307
|
+
if (response.keys.length > 0) {
|
|
308
|
+
await Promise.all(
|
|
309
|
+
response.keys.map((key) => {
|
|
310
|
+
return this.store.delete(key.name);
|
|
311
|
+
})
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
} while (!complete);
|
|
315
|
+
}
|
|
316
|
+
on(_event, _listener) {
|
|
317
|
+
return this;
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
// src/utils/index.ts
|
|
322
|
+
var import_qs = __toESM(require("qs"), 1);
|
|
323
|
+
var import_lodash_es3 = require("lodash-es");
|
|
324
|
+
var import_json52 = __toESM(require("json5"), 1);
|
|
325
|
+
|
|
326
|
+
// src/resources.ts
|
|
327
|
+
var import_lodash_es2 = require("lodash-es");
|
|
328
|
+
|
|
311
329
|
// src/liquid/utils.ts
|
|
312
330
|
var import_liquidjs = require("liquidjs");
|
|
313
331
|
|
|
@@ -763,18 +781,12 @@ var StorefrontResource = class {
|
|
|
763
781
|
}
|
|
764
782
|
return instance[prop];
|
|
765
783
|
}
|
|
766
|
-
// add additional properties to the loaded result
|
|
767
|
-
_transformResult(result) {
|
|
768
|
-
return result;
|
|
769
|
-
}
|
|
770
784
|
async _get(..._args) {
|
|
771
785
|
if (this._getter) {
|
|
772
786
|
const getter = this._getter.bind(
|
|
773
787
|
this
|
|
774
788
|
);
|
|
775
789
|
return Promise.resolve().then(getter).then((result) => {
|
|
776
|
-
return this._transformResult(result);
|
|
777
|
-
}).then((result) => {
|
|
778
790
|
this._result = result ?? null;
|
|
779
791
|
if (result) {
|
|
780
792
|
Object.assign(this, result);
|
|
@@ -857,7 +869,6 @@ function cloneStorefrontResource(input) {
|
|
|
857
869
|
});
|
|
858
870
|
const clone = new ClonedClass(input._getter);
|
|
859
871
|
clone._params = input._params;
|
|
860
|
-
clone._transformResult = input._transformResult.bind(clone);
|
|
861
872
|
Object.defineProperty(clone, "_resourceName", {
|
|
862
873
|
value: resourceName
|
|
863
874
|
});
|
|
@@ -911,7 +922,11 @@ var SwellStorefrontCollection = class _SwellStorefrontCollection extends SwellSt
|
|
|
911
922
|
limit = DEFAULT_QUERY_PAGE_LIMIT;
|
|
912
923
|
name;
|
|
913
924
|
constructor(swell, collection, query = {}, getter) {
|
|
914
|
-
super(
|
|
925
|
+
super(
|
|
926
|
+
swell,
|
|
927
|
+
collection,
|
|
928
|
+
getter
|
|
929
|
+
);
|
|
915
930
|
this._query = this._initQuery(query);
|
|
916
931
|
if (!getter) {
|
|
917
932
|
this._setGetter(this._defaultGetter());
|
|
@@ -954,6 +969,7 @@ var SwellStorefrontCollection = class _SwellStorefrontCollection extends SwellSt
|
|
|
954
969
|
this._collection,
|
|
955
970
|
this._query,
|
|
956
971
|
this._swell.queryParams,
|
|
972
|
+
// TODO: consider to exlcude
|
|
957
973
|
this._getterHash
|
|
958
974
|
],
|
|
959
975
|
getter,
|
|
@@ -1082,13 +1098,12 @@ var SwellStorefrontRecord = class extends SwellStorefrontResource {
|
|
|
1082
1098
|
this._id,
|
|
1083
1099
|
this._query,
|
|
1084
1100
|
this._swell.queryParams,
|
|
1101
|
+
// TODO: consider to exlcude
|
|
1085
1102
|
this._getterHash
|
|
1086
1103
|
],
|
|
1087
1104
|
getter,
|
|
1088
1105
|
isResourceCacheble(this._collection)
|
|
1089
1106
|
).then((result) => {
|
|
1090
|
-
return this._transformResult(result);
|
|
1091
|
-
}).then((result) => {
|
|
1092
1107
|
this._result = result;
|
|
1093
1108
|
if (result) {
|
|
1094
1109
|
Object.assign(this, result);
|
|
@@ -7312,8 +7327,6 @@ var Cache = class {
|
|
|
7312
7327
|
* This will always return the cached value immediately if exists
|
|
7313
7328
|
*/
|
|
7314
7329
|
async fetchSWR(key, fetchFn, ttl = DEFAULT_SWR_TTL, isCacheble = true) {
|
|
7315
|
-
const trace = createTraceId();
|
|
7316
|
-
logger.debug("[SDK] Cache fetch start", { key, trace });
|
|
7317
7330
|
const cacheValue = isCacheble ? await this.client.get(key) : void 0;
|
|
7318
7331
|
let promise = SWR_PROMISE_MAP.get(key);
|
|
7319
7332
|
if (promise === void 0) {
|
|
@@ -7321,7 +7334,6 @@ var Cache = class {
|
|
|
7321
7334
|
const isNull = value === null || value === void 0;
|
|
7322
7335
|
if (isCacheble) {
|
|
7323
7336
|
await this.client.set(key, isNull ? NULL_VALUE : value, ttl);
|
|
7324
|
-
logger.debug("[SDK] Cache update done", { key, trace });
|
|
7325
7337
|
}
|
|
7326
7338
|
return value;
|
|
7327
7339
|
}).finally(() => {
|
|
@@ -7333,12 +7345,9 @@ var Cache = class {
|
|
|
7333
7345
|
this.workerCtx.waitUntil(promise);
|
|
7334
7346
|
}
|
|
7335
7347
|
if (cacheValue !== void 0) {
|
|
7336
|
-
logger.debug("[SDK] Cache check done", { status: "HIT", key, trace });
|
|
7337
7348
|
return cacheValue === NULL_VALUE ? null : cacheValue;
|
|
7338
7349
|
}
|
|
7339
|
-
logger.debug("[SDK] Cache check done", { status: "MISS", key, trace });
|
|
7340
7350
|
const result = await promise;
|
|
7341
|
-
logger.debug("[SDK] Cache fetch end", { key, trace });
|
|
7342
7351
|
return result;
|
|
7343
7352
|
}
|
|
7344
7353
|
async get(key) {
|
|
@@ -7845,59 +7854,466 @@ var WorkerCacheProxy = class {
|
|
|
7845
7854
|
}
|
|
7846
7855
|
};
|
|
7847
7856
|
|
|
7857
|
+
// src/cache/worker-html-cache.ts
|
|
7858
|
+
var CACHE_NAME2 = "swell-html-v1";
|
|
7859
|
+
var CACHE_KEY_ORIGIN2 = "https://cache.swell.store";
|
|
7860
|
+
var TTL_CONFIG = {
|
|
7861
|
+
DEFAULT: 300,
|
|
7862
|
+
// 5 minutes
|
|
7863
|
+
DEFAULT_SWR: 3600,
|
|
7864
|
+
// 1 hour stale-while-revalidate
|
|
7865
|
+
HOME: 300,
|
|
7866
|
+
// 5 minutes
|
|
7867
|
+
PRODUCT: 600,
|
|
7868
|
+
// 10 minutes
|
|
7869
|
+
COLLECTION: 900,
|
|
7870
|
+
// 15 minutes
|
|
7871
|
+
PAGE: 3600,
|
|
7872
|
+
// 1 hour
|
|
7873
|
+
BLOG: 1800
|
|
7874
|
+
// 30 minutes
|
|
7875
|
+
};
|
|
7876
|
+
var WorkerHtmlCache = class {
|
|
7877
|
+
epoch;
|
|
7878
|
+
constructor(epoch) {
|
|
7879
|
+
this.epoch = epoch;
|
|
7880
|
+
}
|
|
7881
|
+
async get(request) {
|
|
7882
|
+
const trace = createTraceId();
|
|
7883
|
+
if (request.method !== "GET") {
|
|
7884
|
+
logger.debug("[SDK Html-cache] non-cacheable", { trace });
|
|
7885
|
+
return { found: false, cacheable: false };
|
|
7886
|
+
}
|
|
7887
|
+
if (!this.isCacheable(request)) {
|
|
7888
|
+
logger.debug("[SDK Html-cache] non-cacheable", { trace });
|
|
7889
|
+
return { found: false, cacheable: false };
|
|
7890
|
+
}
|
|
7891
|
+
try {
|
|
7892
|
+
const cache = await caches.open(CACHE_NAME2 + this.epoch);
|
|
7893
|
+
const cacheKey = this.buildCacheKey(request);
|
|
7894
|
+
const cached = await cache.match(cacheKey);
|
|
7895
|
+
if (!cached) {
|
|
7896
|
+
logger.debug("[SDK Html-cache] cacheable, MISS", { trace });
|
|
7897
|
+
return { found: false, cacheable: true };
|
|
7898
|
+
}
|
|
7899
|
+
const age = this.getResponseAge(cached);
|
|
7900
|
+
const ttl = parseInt(cached.headers.get("X-Original-TTL") || "") || this.getTTLForRequest(request);
|
|
7901
|
+
const swr = parseInt(cached.headers.get("X-Original-SWR") || "") || TTL_CONFIG.DEFAULT_SWR;
|
|
7902
|
+
const isStale = age >= ttl;
|
|
7903
|
+
const isExpired = age >= ttl + swr;
|
|
7904
|
+
if (!isExpired) {
|
|
7905
|
+
logger.debug("[SDK Html-cache] cacheable, HIT", {
|
|
7906
|
+
stale: isStale,
|
|
7907
|
+
age,
|
|
7908
|
+
trace
|
|
7909
|
+
});
|
|
7910
|
+
const clientResponse = this.buildClientResponse(
|
|
7911
|
+
cached,
|
|
7912
|
+
ttl,
|
|
7913
|
+
swr,
|
|
7914
|
+
isStale,
|
|
7915
|
+
age
|
|
7916
|
+
);
|
|
7917
|
+
return {
|
|
7918
|
+
found: true,
|
|
7919
|
+
stale: isStale,
|
|
7920
|
+
response: clientResponse,
|
|
7921
|
+
cacheable: true,
|
|
7922
|
+
age: Math.floor(age)
|
|
7923
|
+
};
|
|
7924
|
+
}
|
|
7925
|
+
logger.debug("[SDK Html-cache] cacheable, hit, expired", { trace });
|
|
7926
|
+
return { found: false, cacheable: true };
|
|
7927
|
+
} catch (_) {
|
|
7928
|
+
logger.warn("[SDK Html-cache] no get support", { trace });
|
|
7929
|
+
return null;
|
|
7930
|
+
}
|
|
7931
|
+
}
|
|
7932
|
+
async put(request, response) {
|
|
7933
|
+
const trace = createTraceId();
|
|
7934
|
+
if (request.method !== "GET" || !response.ok) {
|
|
7935
|
+
logger.debug("[SDK Html-cache] put skipped", { trace });
|
|
7936
|
+
return;
|
|
7937
|
+
}
|
|
7938
|
+
if (!this.isCacheable(request) || !this.isResponseCacheable(response)) {
|
|
7939
|
+
logger.debug("[SDK Html-cache] put skipped, non-cacheable", {
|
|
7940
|
+
trace
|
|
7941
|
+
});
|
|
7942
|
+
return;
|
|
7943
|
+
}
|
|
7944
|
+
try {
|
|
7945
|
+
const cache = await caches.open(CACHE_NAME2 + this.epoch);
|
|
7946
|
+
const cacheKey = this.buildCacheKey(request);
|
|
7947
|
+
const ttl = this.getTTLForRequest(request);
|
|
7948
|
+
const swr = TTL_CONFIG.DEFAULT_SWR;
|
|
7949
|
+
const headers = new Headers(response.headers);
|
|
7950
|
+
const existingCacheControl = response.headers.get("Cache-Control");
|
|
7951
|
+
if (!existingCacheControl || existingCacheControl === "public") {
|
|
7952
|
+
const internalMaxAge = ttl + swr;
|
|
7953
|
+
headers.set("Cache-Control", `public, max-age=${internalMaxAge}`);
|
|
7954
|
+
}
|
|
7955
|
+
headers.set("X-Cache-Time", (/* @__PURE__ */ new Date()).toISOString());
|
|
7956
|
+
headers.set("X-Original-TTL", ttl.toString());
|
|
7957
|
+
headers.set("X-Original-SWR", swr.toString());
|
|
7958
|
+
const cacheableResponse = new Response(response.body, {
|
|
7959
|
+
status: response.status,
|
|
7960
|
+
statusText: response.statusText,
|
|
7961
|
+
headers
|
|
7962
|
+
});
|
|
7963
|
+
await cache.put(cacheKey, cacheableResponse);
|
|
7964
|
+
logger.debug("[SDK Html-cache] put done", { trace });
|
|
7965
|
+
} catch (_) {
|
|
7966
|
+
logger.warn("[SDK Html-cache] no put support", { trace });
|
|
7967
|
+
}
|
|
7968
|
+
}
|
|
7969
|
+
/**
|
|
7970
|
+
* Build client response with correct headers
|
|
7971
|
+
*/
|
|
7972
|
+
buildClientResponse(cachedResponse, ttl, swr, isStale, age) {
|
|
7973
|
+
const headers = new Headers(cachedResponse.headers);
|
|
7974
|
+
headers.set(
|
|
7975
|
+
"Cache-Control",
|
|
7976
|
+
`public, max-age=${ttl}, stale-while-revalidate=${swr}`
|
|
7977
|
+
);
|
|
7978
|
+
headers.set("X-Cache-Status", isStale ? "STALE" : "HIT");
|
|
7979
|
+
headers.set("X-Cache-Age", Math.floor(age).toString());
|
|
7980
|
+
headers.delete("X-Original-TTL");
|
|
7981
|
+
headers.delete("X-Original-SWR");
|
|
7982
|
+
return new Response(cachedResponse.body, {
|
|
7983
|
+
status: cachedResponse.status,
|
|
7984
|
+
statusText: cachedResponse.statusText,
|
|
7985
|
+
headers
|
|
7986
|
+
});
|
|
7987
|
+
}
|
|
7988
|
+
/**
|
|
7989
|
+
* Build cache key from request using two-level structure
|
|
7990
|
+
*/
|
|
7991
|
+
buildCacheKey(request) {
|
|
7992
|
+
const url = new URL(request.url);
|
|
7993
|
+
const versionHash = this.generateVersionHash(request.headers);
|
|
7994
|
+
const normalizedQuery = this.normalizeSearchParams(url.searchParams);
|
|
7995
|
+
const cacheKeyPath = `${versionHash}${url.pathname}`;
|
|
7996
|
+
const keyUrl = new URL(`${CACHE_KEY_ORIGIN2}${cacheKeyPath}`);
|
|
7997
|
+
if (normalizedQuery) {
|
|
7998
|
+
keyUrl.search = `?${normalizedQuery}`;
|
|
7999
|
+
}
|
|
8000
|
+
const sanitizedHeaders = this.sanitizeHeaders(request.headers);
|
|
8001
|
+
return new Request(keyUrl.toString(), {
|
|
8002
|
+
method: "GET",
|
|
8003
|
+
headers: sanitizedHeaders
|
|
8004
|
+
});
|
|
8005
|
+
}
|
|
8006
|
+
/**
|
|
8007
|
+
* Sanitize headers for cache operations - minimal whitelist approach
|
|
8008
|
+
*/
|
|
8009
|
+
sanitizeHeaders(originalHeaders) {
|
|
8010
|
+
const CACHE_RELEVANT_HEADERS = [
|
|
8011
|
+
// Content negotiation (affects response format)
|
|
8012
|
+
"accept",
|
|
8013
|
+
"accept-encoding",
|
|
8014
|
+
"accept-language",
|
|
8015
|
+
// Cache control directives from client/proxy
|
|
8016
|
+
"cache-control",
|
|
8017
|
+
"pragma",
|
|
8018
|
+
// Legacy cache control
|
|
8019
|
+
// Conditional request headers (for 304 responses)
|
|
8020
|
+
"if-none-match",
|
|
8021
|
+
"if-modified-since"
|
|
8022
|
+
];
|
|
8023
|
+
const sanitized = new Headers();
|
|
8024
|
+
CACHE_RELEVANT_HEADERS.forEach((header) => {
|
|
8025
|
+
const value = originalHeaders.get(header);
|
|
8026
|
+
if (value) {
|
|
8027
|
+
sanitized.set(header, value);
|
|
8028
|
+
}
|
|
8029
|
+
});
|
|
8030
|
+
return sanitized;
|
|
8031
|
+
}
|
|
8032
|
+
/**
|
|
8033
|
+
* Generate version hash from headers and cookies
|
|
8034
|
+
*/
|
|
8035
|
+
generateVersionHash(headers) {
|
|
8036
|
+
const swellData = this.extractSwellData(headers);
|
|
8037
|
+
const versionFactors = {
|
|
8038
|
+
store: headers.get("swell-storefront-id") || "",
|
|
8039
|
+
auth: headers.get("swell-access-token") || "",
|
|
8040
|
+
theme: headers.get("swell-theme-version-hash") || "",
|
|
8041
|
+
currency: swellData["swell-currency"] || "USD",
|
|
8042
|
+
locale: headers.get("x-locale") || headers.get("accept-language")?.split(",")[0] || "default",
|
|
8043
|
+
context: headers.get("swell-storefront-context"),
|
|
8044
|
+
epoch: this.epoch
|
|
8045
|
+
};
|
|
8046
|
+
return md5(JSON.stringify(versionFactors));
|
|
8047
|
+
}
|
|
8048
|
+
/**
|
|
8049
|
+
* Extract swell-data from cookies
|
|
8050
|
+
*/
|
|
8051
|
+
extractSwellData(headers) {
|
|
8052
|
+
const cookie = headers.get("cookie");
|
|
8053
|
+
if (!cookie) return {};
|
|
8054
|
+
const swellDataMatch = cookie.match(/swell-data=([^;]+)/);
|
|
8055
|
+
if (!swellDataMatch) return {};
|
|
8056
|
+
try {
|
|
8057
|
+
const parsed = JSON.parse(decodeURIComponent(swellDataMatch[1]));
|
|
8058
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
8059
|
+
return parsed;
|
|
8060
|
+
}
|
|
8061
|
+
return {};
|
|
8062
|
+
} catch {
|
|
8063
|
+
return {};
|
|
8064
|
+
}
|
|
8065
|
+
}
|
|
8066
|
+
isCacheable(request) {
|
|
8067
|
+
const url = new URL(request.url);
|
|
8068
|
+
const headers = request.headers;
|
|
8069
|
+
if (headers.get("swell-deployment-mode") === "editor") {
|
|
8070
|
+
return false;
|
|
8071
|
+
}
|
|
8072
|
+
const skipPaths = ["/checkout"];
|
|
8073
|
+
if (skipPaths.some((path) => url.pathname.startsWith(path))) {
|
|
8074
|
+
return false;
|
|
8075
|
+
}
|
|
8076
|
+
if (headers.get("cache-control")?.includes("no-cache")) {
|
|
8077
|
+
return false;
|
|
8078
|
+
}
|
|
8079
|
+
return true;
|
|
8080
|
+
}
|
|
8081
|
+
isResponseCacheable(response) {
|
|
8082
|
+
const contentType = response.headers.get("content-type");
|
|
8083
|
+
if (!contentType?.includes("text/html")) {
|
|
8084
|
+
return false;
|
|
8085
|
+
}
|
|
8086
|
+
const cacheControl = response.headers.get("cache-control");
|
|
8087
|
+
if (cacheControl?.includes("no-store") || cacheControl?.includes("private")) {
|
|
8088
|
+
return false;
|
|
8089
|
+
}
|
|
8090
|
+
return true;
|
|
8091
|
+
}
|
|
8092
|
+
getTTLForRequest(request) {
|
|
8093
|
+
const url = new URL(request.url);
|
|
8094
|
+
const path = url.pathname;
|
|
8095
|
+
if (path === "/") {
|
|
8096
|
+
return TTL_CONFIG.HOME;
|
|
8097
|
+
}
|
|
8098
|
+
if (path.startsWith("/products/")) {
|
|
8099
|
+
return TTL_CONFIG.PRODUCT;
|
|
8100
|
+
}
|
|
8101
|
+
if (path.startsWith("/categories/")) {
|
|
8102
|
+
return TTL_CONFIG.COLLECTION;
|
|
8103
|
+
}
|
|
8104
|
+
if (path.startsWith("/pages/")) {
|
|
8105
|
+
return TTL_CONFIG.PAGE;
|
|
8106
|
+
}
|
|
8107
|
+
if (path.startsWith("/blogs/")) {
|
|
8108
|
+
return TTL_CONFIG.BLOG;
|
|
8109
|
+
}
|
|
8110
|
+
return TTL_CONFIG.DEFAULT;
|
|
8111
|
+
}
|
|
8112
|
+
getResponseAge(response) {
|
|
8113
|
+
const cacheTime = response.headers.get("X-Cache-Time");
|
|
8114
|
+
if (!cacheTime) {
|
|
8115
|
+
return Infinity;
|
|
8116
|
+
}
|
|
8117
|
+
const cacheDate = new Date(cacheTime);
|
|
8118
|
+
if (isNaN(cacheDate.getTime())) {
|
|
8119
|
+
return Infinity;
|
|
8120
|
+
}
|
|
8121
|
+
const age = (Date.now() - cacheDate.getTime()) / 1e3;
|
|
8122
|
+
return Math.max(0, age);
|
|
8123
|
+
}
|
|
8124
|
+
getMaxAge(response) {
|
|
8125
|
+
const cacheControl = response.headers.get("Cache-Control");
|
|
8126
|
+
if (!cacheControl) {
|
|
8127
|
+
return TTL_CONFIG.DEFAULT;
|
|
8128
|
+
}
|
|
8129
|
+
const maxAgeMatch = cacheControl.match(/max-age=(\d+)/);
|
|
8130
|
+
if (maxAgeMatch) {
|
|
8131
|
+
return parseInt(maxAgeMatch[1], 10);
|
|
8132
|
+
}
|
|
8133
|
+
return TTL_CONFIG.DEFAULT;
|
|
8134
|
+
}
|
|
8135
|
+
getStaleWindow(response) {
|
|
8136
|
+
const cacheControl = response.headers.get("Cache-Control");
|
|
8137
|
+
if (!cacheControl) {
|
|
8138
|
+
return TTL_CONFIG.DEFAULT_SWR;
|
|
8139
|
+
}
|
|
8140
|
+
const swrMatch = cacheControl.match(/stale-while-revalidate=(\d+)/);
|
|
8141
|
+
if (swrMatch) {
|
|
8142
|
+
return parseInt(swrMatch[1], 10);
|
|
8143
|
+
}
|
|
8144
|
+
return TTL_CONFIG.DEFAULT_SWR;
|
|
8145
|
+
}
|
|
8146
|
+
/**
|
|
8147
|
+
* Normalize search params for cache key
|
|
8148
|
+
*/
|
|
8149
|
+
normalizeSearchParams(searchParams) {
|
|
8150
|
+
const ignoredParams = [
|
|
8151
|
+
"utm_source",
|
|
8152
|
+
"utm_medium",
|
|
8153
|
+
"utm_campaign",
|
|
8154
|
+
"utm_content",
|
|
8155
|
+
"utm_term",
|
|
8156
|
+
"fbclid",
|
|
8157
|
+
"gclid",
|
|
8158
|
+
"gbraid",
|
|
8159
|
+
"wbraid",
|
|
8160
|
+
"ref",
|
|
8161
|
+
"source",
|
|
8162
|
+
"mc_cid",
|
|
8163
|
+
"mc_eid"
|
|
8164
|
+
];
|
|
8165
|
+
const relevantParams = [];
|
|
8166
|
+
searchParams.forEach((value, key) => {
|
|
8167
|
+
if (!ignoredParams.includes(key)) {
|
|
8168
|
+
relevantParams.push(
|
|
8169
|
+
`${encodeURIComponent(key)}=${encodeURIComponent(value)}`
|
|
8170
|
+
);
|
|
8171
|
+
}
|
|
8172
|
+
});
|
|
8173
|
+
return relevantParams.sort().join("&");
|
|
8174
|
+
}
|
|
8175
|
+
};
|
|
8176
|
+
|
|
8177
|
+
// src/resources/addresses.ts
|
|
8178
|
+
var SwellAddresses = class extends SwellStorefrontCollection {
|
|
8179
|
+
constructor(swell, query) {
|
|
8180
|
+
const { page, limit: limit2 } = swell.queryParams;
|
|
8181
|
+
super(swell, "accounts:addresses", { page, limit: limit2, ...query }, function() {
|
|
8182
|
+
return this._swell.storefront.account.listAddresses(
|
|
8183
|
+
this._query
|
|
8184
|
+
);
|
|
8185
|
+
});
|
|
8186
|
+
}
|
|
8187
|
+
};
|
|
8188
|
+
|
|
8189
|
+
// src/resources/orders.ts
|
|
8190
|
+
var SwellOrders = class extends SwellStorefrontCollection {
|
|
8191
|
+
constructor(swell, query) {
|
|
8192
|
+
const { page, limit: limit2 } = swell.queryParams;
|
|
8193
|
+
super(swell, "accounts:orders", { page, limit: limit2, ...query }, function() {
|
|
8194
|
+
return this._swell.storefront.account.listOrders(this._query);
|
|
8195
|
+
});
|
|
8196
|
+
}
|
|
8197
|
+
};
|
|
8198
|
+
|
|
8199
|
+
// src/resources/subscriptions.ts
|
|
8200
|
+
var SwellSubscriptions = class extends SwellStorefrontCollection {
|
|
8201
|
+
constructor(swell, query) {
|
|
8202
|
+
const { page, limit: limit2 } = swell.queryParams;
|
|
8203
|
+
super(
|
|
8204
|
+
swell,
|
|
8205
|
+
"accounts:subscriptions",
|
|
8206
|
+
{ page, limit: limit2, ...query },
|
|
8207
|
+
function() {
|
|
8208
|
+
return this._swell.storefront.subscriptions.list(
|
|
8209
|
+
this._query
|
|
8210
|
+
);
|
|
8211
|
+
}
|
|
8212
|
+
);
|
|
8213
|
+
}
|
|
8214
|
+
};
|
|
8215
|
+
|
|
7848
8216
|
// src/resources/account.ts
|
|
7849
8217
|
var SwellAccount = class extends SwellStorefrontSingleton {
|
|
7850
|
-
constructor(swell
|
|
7851
|
-
super(swell, "account",
|
|
8218
|
+
constructor(swell) {
|
|
8219
|
+
super(swell, "account", async function() {
|
|
8220
|
+
const account = await this._defaultGetter().call(this);
|
|
8221
|
+
if (!account) {
|
|
8222
|
+
return null;
|
|
8223
|
+
}
|
|
8224
|
+
account.addresses = new SwellAddresses(
|
|
8225
|
+
this._swell
|
|
8226
|
+
);
|
|
8227
|
+
account.orders = new SwellOrders(
|
|
8228
|
+
this._swell
|
|
8229
|
+
);
|
|
8230
|
+
account.subscriptions = new SwellSubscriptions(
|
|
8231
|
+
this._swell
|
|
8232
|
+
);
|
|
8233
|
+
return account;
|
|
8234
|
+
});
|
|
7852
8235
|
return this._getProxy();
|
|
7853
8236
|
}
|
|
7854
8237
|
};
|
|
7855
8238
|
|
|
7856
8239
|
// src/resources/blog_category.ts
|
|
7857
8240
|
var SwellBlogCategory = class extends SwellStorefrontRecord {
|
|
7858
|
-
constructor(swell, id, query
|
|
7859
|
-
super(swell, "content/blog-categories", id, query,
|
|
8241
|
+
constructor(swell, id, query) {
|
|
8242
|
+
super(swell, "content/blog-categories", id, query, async function() {
|
|
8243
|
+
const category = await this._defaultGetter().call(this);
|
|
8244
|
+
if (!category) {
|
|
8245
|
+
return null;
|
|
8246
|
+
}
|
|
8247
|
+
category.blogs = new SwellStorefrontCollection(
|
|
8248
|
+
this._swell,
|
|
8249
|
+
"content/blogs",
|
|
8250
|
+
{
|
|
8251
|
+
category_id: category.id,
|
|
8252
|
+
expand: "author"
|
|
8253
|
+
}
|
|
8254
|
+
);
|
|
8255
|
+
return category;
|
|
8256
|
+
});
|
|
7860
8257
|
return this._getProxy();
|
|
7861
8258
|
}
|
|
7862
8259
|
};
|
|
7863
8260
|
|
|
7864
8261
|
// src/resources/blog.ts
|
|
7865
8262
|
var SwellBlog = class extends SwellStorefrontRecord {
|
|
7866
|
-
constructor(swell,
|
|
7867
|
-
super(swell, "content/blogs",
|
|
8263
|
+
constructor(swell, blogId, categoryId, query) {
|
|
8264
|
+
super(swell, "content/blogs", blogId, query, async function() {
|
|
8265
|
+
this._query = { ...this._query, expand: "author" };
|
|
8266
|
+
const blog = await this._defaultGetter().call(this);
|
|
8267
|
+
if (!blog) {
|
|
8268
|
+
return null;
|
|
8269
|
+
}
|
|
8270
|
+
if (categoryId) {
|
|
8271
|
+
blog.category = new SwellStorefrontRecord(
|
|
8272
|
+
this._swell,
|
|
8273
|
+
"content/blog-categories",
|
|
8274
|
+
categoryId
|
|
8275
|
+
);
|
|
8276
|
+
}
|
|
8277
|
+
return blog;
|
|
8278
|
+
});
|
|
7868
8279
|
return this._getProxy();
|
|
7869
8280
|
}
|
|
7870
8281
|
};
|
|
7871
8282
|
|
|
7872
8283
|
// src/resources/cart.ts
|
|
7873
8284
|
var SwellCart = class extends SwellStorefrontSingleton {
|
|
7874
|
-
constructor(swell
|
|
7875
|
-
super(swell, "cart"
|
|
7876
|
-
return this._getProxy();
|
|
7877
|
-
}
|
|
7878
|
-
};
|
|
7879
|
-
|
|
7880
|
-
// src/resources/category.ts
|
|
7881
|
-
var SwellCategory = class extends SwellStorefrontRecord {
|
|
7882
|
-
constructor(swell, id, query = {}, getter) {
|
|
7883
|
-
super(swell, "categories", id, query, getter);
|
|
7884
|
-
return this._getProxy();
|
|
7885
|
-
}
|
|
7886
|
-
};
|
|
7887
|
-
|
|
7888
|
-
// src/resources/order.ts
|
|
7889
|
-
var SwellOrder = class extends SwellStorefrontRecord {
|
|
7890
|
-
constructor(swell, id, query = {}, getter) {
|
|
7891
|
-
super(swell, "orders", id, query, getter);
|
|
8285
|
+
constructor(swell) {
|
|
8286
|
+
super(swell, "cart");
|
|
7892
8287
|
return this._getProxy();
|
|
7893
8288
|
}
|
|
7894
8289
|
};
|
|
7895
8290
|
|
|
7896
|
-
// src/resources/
|
|
7897
|
-
var
|
|
7898
|
-
constructor(swell,
|
|
7899
|
-
super(
|
|
7900
|
-
|
|
8291
|
+
// src/resources/categories.ts
|
|
8292
|
+
var SwellCategories = class extends SwellStorefrontCollection {
|
|
8293
|
+
constructor(swell, query) {
|
|
8294
|
+
super(
|
|
8295
|
+
swell,
|
|
8296
|
+
"categories",
|
|
8297
|
+
{
|
|
8298
|
+
limit: 100,
|
|
8299
|
+
top_id: null,
|
|
8300
|
+
...query
|
|
8301
|
+
},
|
|
8302
|
+
async function() {
|
|
8303
|
+
const categories = await this._defaultGetter().call(this);
|
|
8304
|
+
if (!categories) {
|
|
8305
|
+
return null;
|
|
8306
|
+
}
|
|
8307
|
+
for (const category of categories.results) {
|
|
8308
|
+
category.products = new SwellStorefrontCollection(
|
|
8309
|
+
this._swell,
|
|
8310
|
+
"products",
|
|
8311
|
+
{ category: category.id }
|
|
8312
|
+
);
|
|
8313
|
+
}
|
|
8314
|
+
return categories;
|
|
8315
|
+
}
|
|
8316
|
+
);
|
|
7901
8317
|
}
|
|
7902
8318
|
};
|
|
7903
8319
|
|
|
@@ -8057,6 +8473,143 @@ function getSelectedSubscriptionPurchaseOptionPlan(selectedPurchaseOptionType, s
|
|
|
8057
8473
|
}
|
|
8058
8474
|
return selectedPlan || subscriptionPurchaseOption.plans[0];
|
|
8059
8475
|
}
|
|
8476
|
+
var SORT_OPTIONS = Object.freeze([
|
|
8477
|
+
{ value: "", name: "Featured" },
|
|
8478
|
+
{ value: "popularity", name: "Popularity", query: "popularity desc" },
|
|
8479
|
+
{ value: "price_asc", name: "Price, low to high", query: "price asc" },
|
|
8480
|
+
{ value: "price_desc", name: "Price, high to low", query: "price desc" },
|
|
8481
|
+
{ value: "date_asc", name: "Date, old to new", query: "date asc" },
|
|
8482
|
+
{ value: "date_desc", name: "Date, new to old", query: "date desc" },
|
|
8483
|
+
{ value: "name_asc", name: "Product name, A-Z", query: "name asc" },
|
|
8484
|
+
{ value: "name_desc", name: "Product name, Z-A", query: "name desc" }
|
|
8485
|
+
]);
|
|
8486
|
+
async function getProductFilters(swell, productQuery) {
|
|
8487
|
+
const sortBy = swell.queryParams.sort || "";
|
|
8488
|
+
const filterQuery = productQueryWithFilters(swell, productQuery);
|
|
8489
|
+
return {
|
|
8490
|
+
filter_options: await getProductFiltersByQuery(swell, filterQuery),
|
|
8491
|
+
sort: SORT_OPTIONS.find((option) => option.value === sortBy)?.value,
|
|
8492
|
+
sort_options: [...SORT_OPTIONS]
|
|
8493
|
+
};
|
|
8494
|
+
}
|
|
8495
|
+
async function getProductFiltersByQuery(swell, query = {}) {
|
|
8496
|
+
const filters2 = await swell.get("/products/:filters", {
|
|
8497
|
+
...query,
|
|
8498
|
+
sort: void 0
|
|
8499
|
+
}) || [];
|
|
8500
|
+
if (!Array.isArray(filters2)) {
|
|
8501
|
+
throw new Error("Product filters must be an array");
|
|
8502
|
+
}
|
|
8503
|
+
for (const filter of filters2) {
|
|
8504
|
+
filter.param_name = `filter_${filter.id}`;
|
|
8505
|
+
if (Array.isArray(filter.options)) {
|
|
8506
|
+
filter.active_options = [];
|
|
8507
|
+
filter.inactive_options = [];
|
|
8508
|
+
for (const option of filter.options) {
|
|
8509
|
+
const queryValue = swell.queryParams[filter.param_name];
|
|
8510
|
+
option.active = Array.isArray(queryValue) ? queryValue.includes(option.value) : queryValue === option.value;
|
|
8511
|
+
const list = option.active ? filter.active_options : filter.inactive_options;
|
|
8512
|
+
list.push(option);
|
|
8513
|
+
}
|
|
8514
|
+
}
|
|
8515
|
+
}
|
|
8516
|
+
return filters2;
|
|
8517
|
+
}
|
|
8518
|
+
function productQueryWithFilters(swell, query) {
|
|
8519
|
+
const filters2 = Object.keys(swell.queryParams).reduce(
|
|
8520
|
+
(acc, key) => {
|
|
8521
|
+
if (key.startsWith("filter_")) {
|
|
8522
|
+
const qkey = key.replace("filter_", "");
|
|
8523
|
+
const value = swell.queryParams[key];
|
|
8524
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value) && (value.gte !== void 0 || value.lte !== void 0)) {
|
|
8525
|
+
acc[qkey] = [value.gte || 0, value.lte || void 0];
|
|
8526
|
+
} else {
|
|
8527
|
+
acc[qkey] = value;
|
|
8528
|
+
}
|
|
8529
|
+
}
|
|
8530
|
+
return acc;
|
|
8531
|
+
},
|
|
8532
|
+
{}
|
|
8533
|
+
);
|
|
8534
|
+
const sortBy = swell.queryParams.sort || "";
|
|
8535
|
+
return {
|
|
8536
|
+
sort: SORT_OPTIONS.find((option) => option.value === sortBy)?.query || void 0,
|
|
8537
|
+
$filters: filters2,
|
|
8538
|
+
...query
|
|
8539
|
+
};
|
|
8540
|
+
}
|
|
8541
|
+
|
|
8542
|
+
// src/resources/category.ts
|
|
8543
|
+
var SwellCategory = class extends SwellStorefrontRecord {
|
|
8544
|
+
constructor(swell, id, query) {
|
|
8545
|
+
super(swell, "categories", id, query, async function() {
|
|
8546
|
+
let category = await this._defaultGetter().call(this);
|
|
8547
|
+
if (!category && this._id === "all") {
|
|
8548
|
+
category = {
|
|
8549
|
+
name: "Products",
|
|
8550
|
+
id: "all",
|
|
8551
|
+
slug: "all",
|
|
8552
|
+
filter_options: [],
|
|
8553
|
+
sort_options: []
|
|
8554
|
+
};
|
|
8555
|
+
}
|
|
8556
|
+
if (!category) {
|
|
8557
|
+
return null;
|
|
8558
|
+
}
|
|
8559
|
+
const productFilters = await getProductFilters(
|
|
8560
|
+
this._swell,
|
|
8561
|
+
category.id !== "all" ? { category: category.id, $variants: true } : { $variants: true }
|
|
8562
|
+
);
|
|
8563
|
+
Object.assign(category, productFilters);
|
|
8564
|
+
return category;
|
|
8565
|
+
});
|
|
8566
|
+
return this._getProxy();
|
|
8567
|
+
}
|
|
8568
|
+
};
|
|
8569
|
+
|
|
8570
|
+
// src/resources/order.ts
|
|
8571
|
+
var SwellOrder = class extends SwellStorefrontRecord {
|
|
8572
|
+
constructor(swell, id, query) {
|
|
8573
|
+
super(swell, "accounts:orders", id, query, function() {
|
|
8574
|
+
return this._swell.storefront.account.getOrder(this._id);
|
|
8575
|
+
});
|
|
8576
|
+
return this._getProxy();
|
|
8577
|
+
}
|
|
8578
|
+
};
|
|
8579
|
+
|
|
8580
|
+
// src/resources/page.ts
|
|
8581
|
+
var SwellPage = class extends SwellStorefrontRecord {
|
|
8582
|
+
constructor(swell, id, query) {
|
|
8583
|
+
super(swell, "content/pages", id, query);
|
|
8584
|
+
return this._getProxy();
|
|
8585
|
+
}
|
|
8586
|
+
};
|
|
8587
|
+
|
|
8588
|
+
// src/resources/predictive_search.ts
|
|
8589
|
+
var SwellPredictiveSearch = class extends StorefrontResource {
|
|
8590
|
+
constructor(swell, query) {
|
|
8591
|
+
super(async function() {
|
|
8592
|
+
const performed = String(query || "").length > 0;
|
|
8593
|
+
let products;
|
|
8594
|
+
if (performed) {
|
|
8595
|
+
products = new SwellStorefrontCollection(
|
|
8596
|
+
swell,
|
|
8597
|
+
"products",
|
|
8598
|
+
{
|
|
8599
|
+
search: query,
|
|
8600
|
+
limit: 10
|
|
8601
|
+
}
|
|
8602
|
+
);
|
|
8603
|
+
await products.resolve();
|
|
8604
|
+
}
|
|
8605
|
+
return {
|
|
8606
|
+
query,
|
|
8607
|
+
performed,
|
|
8608
|
+
products
|
|
8609
|
+
};
|
|
8610
|
+
});
|
|
8611
|
+
}
|
|
8612
|
+
};
|
|
8060
8613
|
|
|
8061
8614
|
// src/resources/variant.ts
|
|
8062
8615
|
function transformSwellVariant(params, product, variant) {
|
|
@@ -8076,27 +8629,30 @@ function transformSwellVariant(params, product, variant) {
|
|
|
8076
8629
|
)
|
|
8077
8630
|
};
|
|
8078
8631
|
}
|
|
8632
|
+
var SwellVariant = class extends SwellStorefrontRecord {
|
|
8633
|
+
product;
|
|
8634
|
+
constructor(swell, product, id, query) {
|
|
8635
|
+
super(swell, "products:variants", id, query, async function() {
|
|
8636
|
+
const variant = await this._swell.get(
|
|
8637
|
+
"/products:variants/{id}",
|
|
8638
|
+
{ id: this._id }
|
|
8639
|
+
);
|
|
8640
|
+
return variant ?? null;
|
|
8641
|
+
});
|
|
8642
|
+
this.product = product;
|
|
8643
|
+
}
|
|
8644
|
+
};
|
|
8079
8645
|
|
|
8080
8646
|
// src/resources/product.ts
|
|
8081
|
-
var SORT_OPTIONS = [
|
|
8082
|
-
{ value: "", name: "Featured" },
|
|
8083
|
-
{ value: "popularity", name: "Popularity", query: "popularity desc" },
|
|
8084
|
-
{ value: "price_asc", name: "Price, low to high", query: "price asc" },
|
|
8085
|
-
{ value: "price_desc", name: "Price, high to low", query: "price desc" },
|
|
8086
|
-
{ value: "date_asc", name: "Date, old to new", query: "date asc" },
|
|
8087
|
-
{ value: "date_desc", name: "Date, new to old", query: "date desc" },
|
|
8088
|
-
{ value: "name_asc", name: "Product name, A-Z", query: "name asc" },
|
|
8089
|
-
{ value: "name_desc", name: "Product name, Z-A", query: "name desc" }
|
|
8090
|
-
];
|
|
8091
8647
|
function transformSwellProduct(params, product) {
|
|
8092
8648
|
if (!product) {
|
|
8093
|
-
return
|
|
8649
|
+
return null;
|
|
8094
8650
|
}
|
|
8095
8651
|
const newProduct = {
|
|
8096
8652
|
...product,
|
|
8097
8653
|
// add swell properties there
|
|
8098
8654
|
selected_option_values: getSelectedVariantOptionValues(product, params),
|
|
8099
|
-
purchase_options: getPurchaseOptions(product, params)
|
|
8655
|
+
purchase_options: getPurchaseOptions(product, params) ?? void 0
|
|
8100
8656
|
};
|
|
8101
8657
|
if (Array.isArray(newProduct.variants?.results)) {
|
|
8102
8658
|
newProduct.variants = {
|
|
@@ -8109,43 +8665,49 @@ function transformSwellProduct(params, product) {
|
|
|
8109
8665
|
return newProduct;
|
|
8110
8666
|
}
|
|
8111
8667
|
var SwellProduct = class extends SwellStorefrontRecord {
|
|
8112
|
-
|
|
8113
|
-
|
|
8114
|
-
super(swell, "products", id, query,
|
|
8115
|
-
|
|
8668
|
+
constructor(swell, id, query) {
|
|
8669
|
+
const params = swell.queryParams;
|
|
8670
|
+
super(swell, "products", id, query, async function() {
|
|
8671
|
+
const result = await this._defaultGetter().call(this);
|
|
8672
|
+
return transformSwellProduct(params, result);
|
|
8673
|
+
});
|
|
8116
8674
|
return this._getProxy();
|
|
8117
8675
|
}
|
|
8118
|
-
|
|
8119
|
-
|
|
8120
|
-
|
|
8121
|
-
|
|
8122
|
-
|
|
8123
|
-
);
|
|
8124
|
-
|
|
8676
|
+
};
|
|
8677
|
+
|
|
8678
|
+
// src/resources/product_recommendations.ts
|
|
8679
|
+
var SwellProductRecommendations = class extends SwellProduct {
|
|
8680
|
+
constructor(swell, id, query) {
|
|
8681
|
+
super(swell, id, { ...query, $recommendations: true });
|
|
8682
|
+
}
|
|
8683
|
+
};
|
|
8684
|
+
|
|
8685
|
+
// src/resources/search.ts
|
|
8686
|
+
var SwellSearch = class extends StorefrontResource {
|
|
8687
|
+
constructor(swell, query) {
|
|
8688
|
+
super(async () => {
|
|
8689
|
+
const performed = String(query || "").length > 0;
|
|
8690
|
+
const productFilters = await getProductFilters(
|
|
8691
|
+
swell,
|
|
8692
|
+
performed ? { search: query } : void 0
|
|
8693
|
+
);
|
|
8694
|
+
return {
|
|
8695
|
+
query,
|
|
8696
|
+
performed,
|
|
8697
|
+
...productFilters
|
|
8698
|
+
};
|
|
8699
|
+
});
|
|
8700
|
+
}
|
|
8701
|
+
};
|
|
8702
|
+
|
|
8703
|
+
// src/resources/subscription.ts
|
|
8704
|
+
var SwellSubscription = class extends SwellStorefrontRecord {
|
|
8705
|
+
constructor(swell, id, query) {
|
|
8706
|
+
super(swell, "accounts:subscriptions", id, query, function() {
|
|
8707
|
+
return this._swell.storefront.subscriptions.get(this._id, this._query);
|
|
8708
|
+
});
|
|
8125
8709
|
}
|
|
8126
8710
|
};
|
|
8127
|
-
function productQueryWithFilters(swell, query = {}) {
|
|
8128
|
-
const sortBy = swell.queryParams.sort || "";
|
|
8129
|
-
const filters2 = Object.entries(swell.queryParams).reduce(
|
|
8130
|
-
(acc, [key, value]) => {
|
|
8131
|
-
if (key.startsWith("filter_")) {
|
|
8132
|
-
const qkey = key.replace("filter_", "");
|
|
8133
|
-
if (value?.gte !== void 0 || value?.lte !== void 0) {
|
|
8134
|
-
acc[qkey] = [value.gte || 0, value.lte || void 0];
|
|
8135
|
-
} else {
|
|
8136
|
-
acc[qkey] = value;
|
|
8137
|
-
}
|
|
8138
|
-
}
|
|
8139
|
-
return acc;
|
|
8140
|
-
},
|
|
8141
|
-
{}
|
|
8142
|
-
);
|
|
8143
|
-
return {
|
|
8144
|
-
sort: SORT_OPTIONS.find((option) => option.value === sortBy)?.query || void 0,
|
|
8145
|
-
$filters: filters2,
|
|
8146
|
-
...query
|
|
8147
|
-
};
|
|
8148
|
-
}
|
|
8149
8711
|
|
|
8150
8712
|
// src/api.ts
|
|
8151
8713
|
var DEFAULT_API_HOST = "https://api.schema.io";
|
|
@@ -8439,13 +9001,19 @@ var Swell = class _Swell {
|
|
|
8439
9001
|
const storefrontRequest = storefront.request;
|
|
8440
9002
|
return (method, url, id, data, opt) => {
|
|
8441
9003
|
if (this.isStorefrontRequestCacheable(method, url, opt)) {
|
|
8442
|
-
|
|
8443
|
-
|
|
8444
|
-
|
|
8445
|
-
|
|
8446
|
-
|
|
8447
|
-
|
|
8448
|
-
|
|
9004
|
+
const key = getCacheKey("request", [
|
|
9005
|
+
this.instanceId,
|
|
9006
|
+
method,
|
|
9007
|
+
url,
|
|
9008
|
+
id,
|
|
9009
|
+
data,
|
|
9010
|
+
opt
|
|
9011
|
+
]);
|
|
9012
|
+
return this.getRequestCache().fetchSWR(key, () => {
|
|
9013
|
+
const requestUrl = id ? `${url}/${id}` : url;
|
|
9014
|
+
logger.debug("[SDK] Cacheable API request", { url: requestUrl, key });
|
|
9015
|
+
return storefrontRequest(method, url, id, data, opt);
|
|
9016
|
+
});
|
|
8449
9017
|
}
|
|
8450
9018
|
switch (method) {
|
|
8451
9019
|
case "delete":
|
|
@@ -8492,7 +9060,9 @@ var Swell = class _Swell {
|
|
|
8492
9060
|
};
|
|
8493
9061
|
function getCacheKey(key, args) {
|
|
8494
9062
|
if (Array.isArray(args) && args.length > 0) {
|
|
8495
|
-
|
|
9063
|
+
const fullKey = `${key}_${md5(JSON.stringify(args))}`;
|
|
9064
|
+
logger.debug(`[SDK] make cache key: ${fullKey}`);
|
|
9065
|
+
return fullKey;
|
|
8496
9066
|
}
|
|
8497
9067
|
return key;
|
|
8498
9068
|
}
|
|
@@ -15716,11 +16286,9 @@ function getProducts(instance, object, mapper) {
|
|
|
15716
16286
|
return this._defaultGetter().call(this);
|
|
15717
16287
|
}
|
|
15718
16288
|
);
|
|
15719
|
-
return products._cloneWithCompatibilityResult(
|
|
15720
|
-
(
|
|
15721
|
-
|
|
15722
|
-
}
|
|
15723
|
-
);
|
|
16289
|
+
return products._cloneWithCompatibilityResult((products2) => {
|
|
16290
|
+
return { ...products2, results: products2.results.map(mapper) };
|
|
16291
|
+
});
|
|
15724
16292
|
});
|
|
15725
16293
|
}
|
|
15726
16294
|
function makeProductsCollectionResolve(instance, object, mapper) {
|
|
@@ -15737,19 +16305,24 @@ function makeProductsCollectionResolve(instance, object, mapper) {
|
|
|
15737
16305
|
|
|
15738
16306
|
// src/compatibility/shopify-objects/collections.ts
|
|
15739
16307
|
function ShopifyCollections(instance, categories) {
|
|
15740
|
-
return new SwellStorefrontCollection(
|
|
15741
|
-
|
|
15742
|
-
|
|
15743
|
-
|
|
15744
|
-
|
|
15745
|
-
|
|
15746
|
-
|
|
15747
|
-
|
|
15748
|
-
|
|
15749
|
-
|
|
15750
|
-
|
|
15751
|
-
|
|
15752
|
-
|
|
16308
|
+
return new SwellStorefrontCollection(
|
|
16309
|
+
instance.swell,
|
|
16310
|
+
categories._collection,
|
|
16311
|
+
categories._query,
|
|
16312
|
+
async () => {
|
|
16313
|
+
const results = (await categories.results)?.map((category) => {
|
|
16314
|
+
return ShopifyCollection(instance, category);
|
|
16315
|
+
});
|
|
16316
|
+
return {
|
|
16317
|
+
page: categories.page ?? 1,
|
|
16318
|
+
count: categories.count ?? 0,
|
|
16319
|
+
results: results ?? [],
|
|
16320
|
+
page_count: categories.page_count ?? 0,
|
|
16321
|
+
limit: categories.limit,
|
|
16322
|
+
pages: categories.pages ?? {}
|
|
16323
|
+
};
|
|
16324
|
+
}
|
|
16325
|
+
);
|
|
15753
16326
|
}
|
|
15754
16327
|
|
|
15755
16328
|
// src/compatibility/shopify-objects/address.ts
|
|
@@ -16936,13 +17509,12 @@ var ImagesDrop = class extends import_liquidjs7.Drop {
|
|
|
16936
17509
|
var SwellImage = class extends StorefrontResource {
|
|
16937
17510
|
constructor(swell, name) {
|
|
16938
17511
|
super(async () => {
|
|
16939
|
-
const
|
|
17512
|
+
const file = await swell.get("/:files/:last", {
|
|
16940
17513
|
private: { $ne: true },
|
|
16941
17514
|
content_type: { $regex: "^image/" },
|
|
16942
17515
|
filename: name
|
|
16943
17516
|
});
|
|
16944
|
-
|
|
16945
|
-
if (file === null) {
|
|
17517
|
+
if (!file) {
|
|
16946
17518
|
return null;
|
|
16947
17519
|
}
|
|
16948
17520
|
return { file };
|
|
@@ -22237,25 +22809,35 @@ function getResourceQuery(slug, query) {
|
|
|
22237
22809
|
StorefrontResource,
|
|
22238
22810
|
Swell,
|
|
22239
22811
|
SwellAccount,
|
|
22812
|
+
SwellAddresses,
|
|
22240
22813
|
SwellBackendAPI,
|
|
22241
22814
|
SwellBlog,
|
|
22242
22815
|
SwellBlogCategory,
|
|
22243
22816
|
SwellCart,
|
|
22817
|
+
SwellCategories,
|
|
22244
22818
|
SwellCategory,
|
|
22245
22819
|
SwellError,
|
|
22246
22820
|
SwellOrder,
|
|
22821
|
+
SwellOrders,
|
|
22247
22822
|
SwellPage,
|
|
22823
|
+
SwellPredictiveSearch,
|
|
22248
22824
|
SwellProduct,
|
|
22825
|
+
SwellProductRecommendations,
|
|
22826
|
+
SwellSearch,
|
|
22249
22827
|
SwellStorefrontCollection,
|
|
22250
22828
|
SwellStorefrontPagination,
|
|
22251
22829
|
SwellStorefrontRecord,
|
|
22252
22830
|
SwellStorefrontResource,
|
|
22253
22831
|
SwellStorefrontSingleton,
|
|
22832
|
+
SwellSubscription,
|
|
22833
|
+
SwellSubscriptions,
|
|
22254
22834
|
SwellTheme,
|
|
22835
|
+
SwellVariant,
|
|
22255
22836
|
ThemeColor,
|
|
22256
22837
|
ThemeFont,
|
|
22257
22838
|
ThemeForm,
|
|
22258
22839
|
ThemeFormErrors,
|
|
22840
|
+
WorkerHtmlCache,
|
|
22259
22841
|
adaptShopifyFontData,
|
|
22260
22842
|
adaptShopifyFormData,
|
|
22261
22843
|
adaptShopifyMenuData,
|