@swell/apps-sdk 1.0.157 → 1.0.159
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 +81 -164
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +81 -164
- package/dist/index.js.map +4 -4
- package/dist/index.mjs +81 -164
- package/dist/index.mjs.map +4 -4
- package/dist/src/theme/theme-loader.d.ts +9 -0
- package/dist/types/shopify.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -285,7 +285,7 @@ var CFWorkerKVKeyvAdapter = class {
|
|
|
285
285
|
if (typeof ttl === "number") {
|
|
286
286
|
ttl = Math.max(60, ttl / 1e3);
|
|
287
287
|
}
|
|
288
|
-
logger.debug("[SDK] kv.set", { key });
|
|
288
|
+
logger.debug("[SDK] kv.set", { key, ttl });
|
|
289
289
|
return this.store.put(key, value, { expirationTtl: ttl });
|
|
290
290
|
}
|
|
291
291
|
async delete(key) {
|
|
@@ -864,7 +864,6 @@ var RESOURCE_CLONE_PROPS = Object.freeze([
|
|
|
864
864
|
"_getResourceObject",
|
|
865
865
|
"_collection",
|
|
866
866
|
"_swell",
|
|
867
|
-
"_query",
|
|
868
867
|
"_params",
|
|
869
868
|
"_id",
|
|
870
869
|
"_resourceName"
|
|
@@ -7428,6 +7427,14 @@ function buildStores2() {
|
|
|
7428
7427
|
|
|
7429
7428
|
// src/cache/theme-cache.ts
|
|
7430
7429
|
var TTL = 90 * 24 * 60 * 60 * 1e3;
|
|
7430
|
+
var ThemeCache = class extends Cache {
|
|
7431
|
+
constructor(options) {
|
|
7432
|
+
super({
|
|
7433
|
+
ttl: TTL,
|
|
7434
|
+
...options
|
|
7435
|
+
});
|
|
7436
|
+
}
|
|
7437
|
+
};
|
|
7431
7438
|
|
|
7432
7439
|
// src/cache/theme-file-storage.ts
|
|
7433
7440
|
var import_bluebird2 = __toESM(require("bluebird"), 1);
|
|
@@ -7769,139 +7776,29 @@ var MINUTE = 60 * SECOND;
|
|
|
7769
7776
|
var HOUR = 60 * MINUTE;
|
|
7770
7777
|
var DAY = 24 * HOUR;
|
|
7771
7778
|
var YEAR = 365 * DAY;
|
|
7772
|
-
var MAX_TTL = YEAR;
|
|
7773
7779
|
var SHORT_TTL = 5 * SECOND;
|
|
7774
7780
|
|
|
7775
|
-
// src/cache/worker-cache-proxy.ts
|
|
7776
|
-
var CACHE_NAME = "swell-cache-v011";
|
|
7777
|
-
var CACHE_KEY_ORIGIN = "https://cache.swell.store";
|
|
7778
|
-
var WorkerCacheProxy = class {
|
|
7779
|
-
swell;
|
|
7780
|
-
constructor(swell) {
|
|
7781
|
-
this.swell = swell;
|
|
7782
|
-
}
|
|
7783
|
-
/**
|
|
7784
|
-
* Reads a JSON value from Worker Cache using a key built from path+query.
|
|
7785
|
-
* Returns null on miss or if running outside of a Worker environment.
|
|
7786
|
-
*/
|
|
7787
|
-
async get(path, query, opts) {
|
|
7788
|
-
if (typeof caches === "undefined") {
|
|
7789
|
-
return null;
|
|
7790
|
-
}
|
|
7791
|
-
const { keyUrl } = await this.buildKeyUrl(path, query, opts?.version);
|
|
7792
|
-
try {
|
|
7793
|
-
const cache = await caches.open(CACHE_NAME);
|
|
7794
|
-
const match = await cache.match(keyUrl);
|
|
7795
|
-
if (!match) return null;
|
|
7796
|
-
const data = await match.json();
|
|
7797
|
-
return data;
|
|
7798
|
-
} catch {
|
|
7799
|
-
return null;
|
|
7800
|
-
}
|
|
7801
|
-
}
|
|
7802
|
-
/**
|
|
7803
|
-
* Stores a JSON value in Worker Cache under key built from path+query.
|
|
7804
|
-
* No-ops outside of a Worker environment.
|
|
7805
|
-
*/
|
|
7806
|
-
async put(path, query, value, opts) {
|
|
7807
|
-
if (typeof caches === "undefined") {
|
|
7808
|
-
return;
|
|
7809
|
-
}
|
|
7810
|
-
const { keyUrl, hasVersion } = await this.buildKeyUrl(
|
|
7811
|
-
path,
|
|
7812
|
-
query,
|
|
7813
|
-
opts?.version
|
|
7814
|
-
);
|
|
7815
|
-
const ttlMs = hasVersion ? MAX_TTL : SHORT_TTL;
|
|
7816
|
-
try {
|
|
7817
|
-
const cache = await caches.open(CACHE_NAME);
|
|
7818
|
-
const response = new Response(JSON.stringify(value), {
|
|
7819
|
-
headers: {
|
|
7820
|
-
"Content-Type": "application/json",
|
|
7821
|
-
"Cache-Control": `public, max-age=${Math.floor(ttlMs / 1e3)}`
|
|
7822
|
-
}
|
|
7823
|
-
});
|
|
7824
|
-
await cache.put(keyUrl, response);
|
|
7825
|
-
logger.debug("[SDK] cache put done", { keyUrl });
|
|
7826
|
-
} catch {
|
|
7827
|
-
}
|
|
7828
|
-
}
|
|
7829
|
-
/**
|
|
7830
|
-
* Builds a deterministic key URL for Worker Cache from the backend API URL
|
|
7831
|
-
* composed using path and query. Includes tenant and auth isolation and an
|
|
7832
|
-
* optional version segment.
|
|
7833
|
-
*/
|
|
7834
|
-
async buildKeyUrl(path, query, explicitVersion) {
|
|
7835
|
-
const apiHost = this.swell.backend?.apiHost;
|
|
7836
|
-
const endpointPath = String(path).startsWith("/") ? String(path).substring(1) : String(path);
|
|
7837
|
-
let queryString = "";
|
|
7838
|
-
if (query && this.swell.backend) {
|
|
7839
|
-
queryString = this.swell.backend.stringifyQuery(query);
|
|
7840
|
-
}
|
|
7841
|
-
const fullUrl = `${apiHost}/${endpointPath}${queryString ? `?${queryString}` : ""}`;
|
|
7842
|
-
const instanceId = this.swell.instanceId || "";
|
|
7843
|
-
const authKey = String(this.swell.swellHeaders?.["swell-auth-key"] || "");
|
|
7844
|
-
const tenantHash = await this.sha256Hex(`${instanceId}|${authKey}`);
|
|
7845
|
-
const version = explicitVersion !== void 0 ? explicitVersion : this.swell.swellHeaders?.["theme-version-hash"] || null;
|
|
7846
|
-
const hasVersion = Boolean(version);
|
|
7847
|
-
const versionHash = hasVersion ? await this.sha256Hex(String(version)) : null;
|
|
7848
|
-
const urlHash = await this.sha256Hex(fullUrl);
|
|
7849
|
-
const keyUrl = versionHash ? `${CACHE_KEY_ORIGIN}/v1/${tenantHash}/${versionHash}/${urlHash}` : `${CACHE_KEY_ORIGIN}/v1/${tenantHash}/${urlHash}`;
|
|
7850
|
-
return { keyUrl, hasVersion };
|
|
7851
|
-
}
|
|
7852
|
-
/**
|
|
7853
|
-
* SHA-256 digest with hex encoding. Requires Worker crypto; callers
|
|
7854
|
-
* should avoid invoking this outside of Worker code paths.
|
|
7855
|
-
*/
|
|
7856
|
-
async sha256Hex(input) {
|
|
7857
|
-
if (typeof crypto !== "undefined" && crypto.subtle && crypto.subtle.digest) {
|
|
7858
|
-
const encoder = new TextEncoder();
|
|
7859
|
-
const digest = await crypto.subtle.digest(
|
|
7860
|
-
"SHA-256",
|
|
7861
|
-
encoder.encode(input)
|
|
7862
|
-
);
|
|
7863
|
-
const bytes = new Uint8Array(digest);
|
|
7864
|
-
return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
7865
|
-
}
|
|
7866
|
-
return md5(input);
|
|
7867
|
-
}
|
|
7868
|
-
};
|
|
7869
|
-
|
|
7870
7781
|
// src/cache/worker-html-cache.ts
|
|
7871
|
-
var
|
|
7872
|
-
var
|
|
7782
|
+
var CACHE_NAME = "swell-html-v0";
|
|
7783
|
+
var CACHE_KEY_ORIGIN = "https://cache.swell.store";
|
|
7873
7784
|
var TTL_CONFIG = {
|
|
7874
7785
|
LIVE: {
|
|
7875
|
-
DEFAULT:
|
|
7876
|
-
|
|
7877
|
-
|
|
7878
|
-
|
|
7879
|
-
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
// 15 minutes
|
|
7883
|
-
PAGE: 3600,
|
|
7884
|
-
// 1 hour
|
|
7885
|
-
BLOG: 1800,
|
|
7886
|
-
// 30 minutes
|
|
7887
|
-
SWR: 3600
|
|
7888
|
-
// 1 hour stale-while-revalidate
|
|
7786
|
+
DEFAULT: 20,
|
|
7787
|
+
HOME: 20,
|
|
7788
|
+
PRODUCT: 20,
|
|
7789
|
+
COLLECTION: 20,
|
|
7790
|
+
PAGE: 20,
|
|
7791
|
+
BLOG: 20,
|
|
7792
|
+
SWR: 180
|
|
7889
7793
|
},
|
|
7890
7794
|
PREVIEW: {
|
|
7891
|
-
DEFAULT:
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
// 3 minutes
|
|
7899
|
-
PAGE: 5,
|
|
7900
|
-
// 5 minutes
|
|
7901
|
-
BLOG: 5,
|
|
7902
|
-
// 5 minutes
|
|
7903
|
-
SWR: 600
|
|
7904
|
-
// 10 minutes stale-while-revalidate
|
|
7795
|
+
DEFAULT: 20,
|
|
7796
|
+
HOME: 20,
|
|
7797
|
+
PRODUCT: 20,
|
|
7798
|
+
COLLECTION: 20,
|
|
7799
|
+
PAGE: 20,
|
|
7800
|
+
BLOG: 20,
|
|
7801
|
+
SWR: 180
|
|
7905
7802
|
}
|
|
7906
7803
|
};
|
|
7907
7804
|
var WorkerHtmlCache = class {
|
|
@@ -7920,7 +7817,7 @@ var WorkerHtmlCache = class {
|
|
|
7920
7817
|
return { found: false, cacheable: false };
|
|
7921
7818
|
}
|
|
7922
7819
|
try {
|
|
7923
|
-
const cache = await caches.open(
|
|
7820
|
+
const cache = await caches.open(CACHE_NAME + this.epoch);
|
|
7924
7821
|
const cacheKey = this.buildCacheKey(request);
|
|
7925
7822
|
const cached = await cache.match(cacheKey);
|
|
7926
7823
|
if (!cached) {
|
|
@@ -8023,7 +7920,7 @@ var WorkerHtmlCache = class {
|
|
|
8023
7920
|
return;
|
|
8024
7921
|
}
|
|
8025
7922
|
try {
|
|
8026
|
-
const cache = await caches.open(
|
|
7923
|
+
const cache = await caches.open(CACHE_NAME + this.epoch);
|
|
8027
7924
|
const cacheKey = this.buildCacheKey(request);
|
|
8028
7925
|
await cache.delete(cacheKey);
|
|
8029
7926
|
const ttl = this.getTTLForRequest(request);
|
|
@@ -8083,7 +7980,7 @@ var WorkerHtmlCache = class {
|
|
|
8083
7980
|
const versionHash = this.generateVersionHash(request.headers);
|
|
8084
7981
|
const normalizedQuery = this.normalizeSearchParams(url.searchParams);
|
|
8085
7982
|
const cacheKeyPath = `${versionHash}${url.pathname}`;
|
|
8086
|
-
const keyUrl = new URL(`${
|
|
7983
|
+
const keyUrl = new URL(`${CACHE_KEY_ORIGIN}${cacheKeyPath}`);
|
|
8087
7984
|
if (normalizedQuery) {
|
|
8088
7985
|
keyUrl.search = `?${normalizedQuery}`;
|
|
8089
7986
|
}
|
|
@@ -15412,15 +15309,32 @@ function ShopifyBlog(instance, blogCategory) {
|
|
|
15412
15309
|
return new ShopifyResource({
|
|
15413
15310
|
all_tags: allTags,
|
|
15414
15311
|
articles: deferWith(blogCategory, (blogCategory2) => {
|
|
15415
|
-
|
|
15416
|
-
|
|
15417
|
-
|
|
15418
|
-
|
|
15419
|
-
|
|
15420
|
-
|
|
15421
|
-
|
|
15312
|
+
const { page, limit: limit2 } = instance.swell.queryParams;
|
|
15313
|
+
const categoryBlogs = new SwellStorefrontCollection(
|
|
15314
|
+
instance.swell,
|
|
15315
|
+
"content/blogs",
|
|
15316
|
+
{
|
|
15317
|
+
page,
|
|
15318
|
+
limit: limit2,
|
|
15319
|
+
category_id: blogCategory2.id,
|
|
15320
|
+
expand: "author"
|
|
15321
|
+
},
|
|
15322
|
+
async function() {
|
|
15323
|
+
return this._defaultGetter().call(this);
|
|
15422
15324
|
}
|
|
15423
|
-
)
|
|
15325
|
+
);
|
|
15326
|
+
return categoryBlogs._cloneWithCompatibilityResult((blogs) => {
|
|
15327
|
+
return {
|
|
15328
|
+
...blogs,
|
|
15329
|
+
results: blogs?.results?.map(
|
|
15330
|
+
(blog) => ShopifyArticle(
|
|
15331
|
+
instance,
|
|
15332
|
+
blog,
|
|
15333
|
+
blogCategory2
|
|
15334
|
+
)
|
|
15335
|
+
)
|
|
15336
|
+
};
|
|
15337
|
+
}) || [];
|
|
15424
15338
|
}),
|
|
15425
15339
|
articles_count: deferWith(blogCategory.blogs, (blogs) => blogs?.count || 0),
|
|
15426
15340
|
handle: defer(() => blogCategory.slug),
|
|
@@ -20581,7 +20495,8 @@ function getLiquidFS(getThemeConfig, extName) {
|
|
|
20581
20495
|
|
|
20582
20496
|
// src/theme/theme-loader.ts
|
|
20583
20497
|
var MAX_INDIVIDUAL_CONFIGS_TO_FETCH = 50;
|
|
20584
|
-
var ThemeLoader = class {
|
|
20498
|
+
var ThemeLoader = class _ThemeLoader {
|
|
20499
|
+
static cache = null;
|
|
20585
20500
|
swell;
|
|
20586
20501
|
configs;
|
|
20587
20502
|
constructor(swell) {
|
|
@@ -20722,24 +20637,14 @@ var ThemeLoader = class {
|
|
|
20722
20637
|
limit: 1e3,
|
|
20723
20638
|
type: "theme",
|
|
20724
20639
|
fields: "id, name, type, file, file_path, hash"
|
|
20725
|
-
// NO file_data
|
|
20726
20640
|
};
|
|
20727
|
-
const cache = new WorkerCacheProxy(this.swell);
|
|
20728
20641
|
const versionHash = this.swell.swellHeaders["theme-version-hash"];
|
|
20729
|
-
|
|
20730
|
-
|
|
20731
|
-
|
|
20732
|
-
|
|
20733
|
-
|
|
20734
|
-
|
|
20735
|
-
}
|
|
20736
|
-
);
|
|
20737
|
-
if (cached) {
|
|
20738
|
-
logger.debug("[ThemeLoader] Config metadata cache hit");
|
|
20739
|
-
return cached;
|
|
20740
|
-
}
|
|
20741
|
-
} catch (err) {
|
|
20742
|
-
logger.warn("[ThemeLoader] Cache read failed, fetching from API", err);
|
|
20642
|
+
const cacheKey = this.buildMetadataCacheKey(versionHash, query);
|
|
20643
|
+
const cache = this.getCache();
|
|
20644
|
+
const cached = await cache.get(cacheKey);
|
|
20645
|
+
if (cached) {
|
|
20646
|
+
logger.debug("[ThemeLoader] Config metadata cache hit");
|
|
20647
|
+
return cached;
|
|
20743
20648
|
}
|
|
20744
20649
|
logger.debug("[ThemeLoader] Fetching config metadata from API");
|
|
20745
20650
|
const response = await this.swell.get(
|
|
@@ -20747,14 +20652,7 @@ var ThemeLoader = class {
|
|
|
20747
20652
|
query
|
|
20748
20653
|
);
|
|
20749
20654
|
const configs = response?.results || [];
|
|
20750
|
-
|
|
20751
|
-
if (ctx && typeof ctx.waitUntil === "function") {
|
|
20752
|
-
ctx.waitUntil(
|
|
20753
|
-
cache.put("/:themes:configs", query, configs, {
|
|
20754
|
-
version: versionHash || null
|
|
20755
|
-
})
|
|
20756
|
-
);
|
|
20757
|
-
}
|
|
20655
|
+
await cache.set(cacheKey, configs);
|
|
20758
20656
|
return configs;
|
|
20759
20657
|
}
|
|
20760
20658
|
/**
|
|
@@ -20859,6 +20757,25 @@ var ThemeLoader = class {
|
|
|
20859
20757
|
preview: swellHeaders["deployment-mode"] === "editor" || swellHeaders["deployment-mode"] === "preview" ? true : { $ne: true }
|
|
20860
20758
|
};
|
|
20861
20759
|
}
|
|
20760
|
+
/**
|
|
20761
|
+
* Build cache key with tenant isolation for metadata
|
|
20762
|
+
*/
|
|
20763
|
+
buildMetadataCacheKey(version, query) {
|
|
20764
|
+
const args = [this.swell.instanceId, version || "default", query];
|
|
20765
|
+
return `theme_configs:${md5(JSON.stringify(args))}`;
|
|
20766
|
+
}
|
|
20767
|
+
/**
|
|
20768
|
+
* Get or create the theme cache instance
|
|
20769
|
+
*/
|
|
20770
|
+
getCache() {
|
|
20771
|
+
if (!_ThemeLoader.cache) {
|
|
20772
|
+
_ThemeLoader.cache = new ThemeCache({
|
|
20773
|
+
kvStore: this.swell.workerEnv?.THEME,
|
|
20774
|
+
workerCtx: this.swell.workerCtx
|
|
20775
|
+
});
|
|
20776
|
+
}
|
|
20777
|
+
return _ThemeLoader.cache;
|
|
20778
|
+
}
|
|
20862
20779
|
};
|
|
20863
20780
|
|
|
20864
20781
|
// src/globals.ts
|