@swell/apps-sdk 1.0.168 → 1.0.170

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 CHANGED
@@ -42,6 +42,7 @@ __export(index_exports, {
42
42
  CartResource: () => CartResource,
43
43
  CategoriesResource: () => CategoriesResource,
44
44
  CategoryResource: () => CategoryResource,
45
+ ContentCache: () => ContentCache,
45
46
  DEFAULT_CACHE_RULES: () => DEFAULT_CACHE_RULES,
46
47
  DEFAULT_QUERY_PAGE_LIMIT: () => DEFAULT_QUERY_PAGE_LIMIT,
47
48
  DeferredShopifyResource: () => DeferredShopifyResource,
@@ -1254,10 +1255,10 @@ var FILE_DATA_INCLUDE_QUERY = {
1254
1255
  { content_type: { $regex: "^image/svg" } }
1255
1256
  ]
1256
1257
  },
1257
- // Do not return assets unless they end with .liquid.[ext] or css/js/svg
1258
+ // Do not return assets unless they end with .liquid or css/js/svg
1258
1259
  $or: [
1259
1260
  { file_path: { $regex: "^(?!theme/assets/)" } },
1260
- { file_path: { $regex: ".liquid.[a-zA-Z0-9]+$" } },
1261
+ { file_path: { $regex: ".liquid$" } },
1261
1262
  { file_path: { $regex: ".(css|js|svg)$" } }
1262
1263
  ]
1263
1264
  }
@@ -7780,6 +7781,33 @@ var ThemeFileCache = class {
7780
7781
  }
7781
7782
  };
7782
7783
 
7784
+ // src/cache/content-cache.ts
7785
+ var DEFAULT_TTL2 = 90 * 24 * 60 * 60 * 1e3;
7786
+ var ContentCache = class {
7787
+ cache;
7788
+ defaultTtl;
7789
+ constructor(options) {
7790
+ const { defaultTtl, ...cacheOptions } = options || {};
7791
+ this.defaultTtl = defaultTtl ?? DEFAULT_TTL2;
7792
+ this.cache = new Cache({
7793
+ ttl: this.defaultTtl,
7794
+ ...cacheOptions
7795
+ });
7796
+ }
7797
+ /**
7798
+ * Get content from cache
7799
+ */
7800
+ async get(key) {
7801
+ return this.cache.get(key);
7802
+ }
7803
+ /**
7804
+ * Set content in cache
7805
+ */
7806
+ async set(key, value, ttl) {
7807
+ await this.cache.set(key, value, ttl ?? this.defaultTtl);
7808
+ }
7809
+ };
7810
+
7783
7811
  // src/resources/addresses.ts
7784
7812
  var SwellAddresses = class extends SwellStorefrontCollection {
7785
7813
  constructor(swell, query) {
@@ -15904,7 +15932,10 @@ function ShopifyCollection(instance, category) {
15904
15932
  tags: [],
15905
15933
  template_suffix: defer(() => category.theme_template),
15906
15934
  title: defer(() => category.name),
15907
- url: deferWith(category, (category2) => `/collections/${category2.slug}`)
15935
+ url: deferWith(
15936
+ category,
15937
+ (category2) => category2.slug ? `/collections/${category2.slug}` : ""
15938
+ )
15908
15939
  });
15909
15940
  }
15910
15941
  function getFirstImage(category) {
@@ -15933,9 +15964,7 @@ function convertToShopifySorting(value) {
15933
15964
  function getProducts(instance, object, mapper) {
15934
15965
  return deferWith(object, (object2) => {
15935
15966
  const { page, limit: limit2 } = instance.swell.queryParams;
15936
- const productQuery = {
15937
- $variants: true
15938
- };
15967
+ const productQuery = { $variants: true };
15939
15968
  if (typeof object2.id === "string" && object2.id !== "all") {
15940
15969
  productQuery.category = object2.id;
15941
15970
  }
@@ -15946,11 +15975,7 @@ function getProducts(instance, object, mapper) {
15946
15975
  const products = new SwellStorefrontCollection(
15947
15976
  instance.swell,
15948
15977
  "products",
15949
- {
15950
- page,
15951
- limit: limit2,
15952
- ...filterQuery
15953
- },
15978
+ { page, limit: limit2, ...filterQuery },
15954
15979
  async function() {
15955
15980
  return this._defaultGetter().call(this);
15956
15981
  }
@@ -17457,10 +17482,9 @@ var ShopifyCompatibility2 = class {
17457
17482
  ({ from }) => from === key || from.startsWith(keyObject)
17458
17483
  );
17459
17484
  if (resourceMap && value instanceof StorefrontResource) {
17460
- const resource = resourceMap.object(this, value);
17461
- const composed = Object.assign({}, value.toObject(), resource);
17462
- Object.setPrototypeOf(composed, Object.getPrototypeOf(resource));
17463
- pageData[resourceMap.to] = composed;
17485
+ const resourceProps = resourceMap.object(this, value);
17486
+ value.setCompatibilityProps(resourceProps);
17487
+ pageData[resourceMap.to] = value;
17464
17488
  }
17465
17489
  }
17466
17490
  }
@@ -18702,7 +18726,9 @@ function bind15(liquidSwell) {
18702
18726
  scope[filepath] = yield (0, import_liquidjs25.evalToken)(this.withVar, ctx);
18703
18727
  }
18704
18728
  ctx.push(ctx.opts.jekyllInclude ? { include: scope } : scope);
18705
- const output = yield liquidSwell.getComponentPath(filepath).then((path) => liquidSwell.getThemeConfig(path)).then((themeConfig) => liquidSwell.renderTemplate(themeConfig, scope));
18729
+ const output = yield liquidSwell.getComponentPath(filepath).then((path) => liquidSwell.getThemeConfig(path)).then(
18730
+ (themeConfig) => liquidSwell.renderTemplate(themeConfig, ctx.getAll())
18731
+ );
18706
18732
  emitter.write(output);
18707
18733
  ctx.pop();
18708
18734
  ctx.restoreRegister(saved);
@@ -18796,7 +18822,7 @@ var tags = {
18796
18822
  };
18797
18823
  function bindTags(liquidSwell) {
18798
18824
  Object.entries(tags).forEach(
18799
- ([tag, bind64]) => liquidSwell.registerTag(tag, bind64(liquidSwell))
18825
+ ([tag, bind65]) => liquidSwell.registerTag(tag, bind65(liquidSwell))
18800
18826
  );
18801
18827
  }
18802
18828
 
@@ -18958,7 +18984,7 @@ function applyDateFormat(type, date) {
18958
18984
  }
18959
18985
  }
18960
18986
  function isCustomDateFormat(format) {
18961
- return format.includes("%");
18987
+ return Boolean(format) && format.includes("%");
18962
18988
  }
18963
18989
  function applyStrftimeFormat(format, date) {
18964
18990
  return (0, import_strftime.default)(format, date);
@@ -19493,6 +19519,38 @@ function bind57(_liquidSwell) {
19493
19519
  };
19494
19520
  }
19495
19521
 
19522
+ // src/liquid/filters/shopify/img_url.ts
19523
+ function bind58(_liquidSwell) {
19524
+ return function filterImgUrl(input, ...params) {
19525
+ if (!input) return "";
19526
+ let url;
19527
+ if (typeof input === "object") {
19528
+ if (input.url) {
19529
+ url = input.url;
19530
+ } else {
19531
+ return "";
19532
+ }
19533
+ } else {
19534
+ url = String(input);
19535
+ }
19536
+ const query = [];
19537
+ params.forEach((param) => {
19538
+ if (!param) {
19539
+ return;
19540
+ }
19541
+ const [key, value] = param.includes(":") ? param.split(":").map((s) => s.trim()) : [param, void 0];
19542
+ if (/^w\d+$/.test(key)) {
19543
+ query.push(`width=${key.slice(1)}`);
19544
+ } else if (/^h\d+$/.test(key)) {
19545
+ query.push(`height=${key.slice(1)}`);
19546
+ } else if (key === "crop" && value) {
19547
+ query.push(`crop=${encodeURIComponent(value)}`);
19548
+ }
19549
+ });
19550
+ return query.length ? `${url}?${query.join("&")}` : url;
19551
+ };
19552
+ }
19553
+
19496
19554
  // src/liquid/filters/shopify/item_count_for_variant.ts
19497
19555
  var item_count_for_variant_default = {
19498
19556
  bind(_liquidSwell) {
@@ -19507,14 +19565,14 @@ var item_count_for_variant_default = {
19507
19565
  };
19508
19566
 
19509
19567
  // src/liquid/filters/shopify/payment_button.ts
19510
- function bind58(_liquidSwell) {
19568
+ function bind59(_liquidSwell) {
19511
19569
  return (form) => {
19512
19570
  return null;
19513
19571
  };
19514
19572
  }
19515
19573
 
19516
19574
  // src/liquid/filters/shopify/payment_terms.ts
19517
- function bind59(_liquidSwell) {
19575
+ function bind60(_liquidSwell) {
19518
19576
  return (form) => {
19519
19577
  return null;
19520
19578
  };
@@ -19616,7 +19674,7 @@ var svgs = {
19616
19674
  var placeholder_svgs_default = svgs;
19617
19675
 
19618
19676
  // src/liquid/filters/shopify/placeholder_svg_tag.ts
19619
- function bind60(_liquidSwell) {
19677
+ function bind61(_liquidSwell) {
19620
19678
  return function filterPlaceholderSvgTag(name, className) {
19621
19679
  const svg = placeholder_svgs_default[name];
19622
19680
  if (typeof svg === "object" && svg !== null) {
@@ -19627,7 +19685,7 @@ function bind60(_liquidSwell) {
19627
19685
  }
19628
19686
 
19629
19687
  // src/liquid/filters/shopify/shopify_asset_url.ts
19630
- function bind61(_liquidSwell) {
19688
+ function bind62(_liquidSwell) {
19631
19689
  return function filterShopifyAssetUrl(input) {
19632
19690
  if (typeof input === "string") {
19633
19691
  switch (input) {
@@ -19652,7 +19710,7 @@ function bind61(_liquidSwell) {
19652
19710
  }
19653
19711
 
19654
19712
  // src/liquid/filters/shopify/structured_data.ts
19655
- function bind62(_liquidSwell) {
19713
+ function bind63(_liquidSwell) {
19656
19714
  return async function filterStructuredData(input) {
19657
19715
  let value = input;
19658
19716
  if (value instanceof StorefrontResource) {
@@ -19730,7 +19788,7 @@ function convertToSchemaOrgProductGroup(product) {
19730
19788
  }
19731
19789
 
19732
19790
  // src/liquid/filters/inline_editable.ts
19733
- function bind63(_liquidSwell) {
19791
+ function bind64(_liquidSwell) {
19734
19792
  return (value, key) => {
19735
19793
  if (typeof value === "object" && "value" in value) {
19736
19794
  value = value.value;
@@ -19788,14 +19846,15 @@ var filters = {
19788
19846
  // Shopify compatibility only
19789
19847
  asset_img_url: bind56,
19790
19848
  hex_to_rgba: bind57,
19849
+ img_url: bind58,
19791
19850
  item_count_for_variant: item_count_for_variant_default,
19792
- payment_button: bind58,
19793
- payment_terms: bind59,
19794
- placeholder_svg_tag: bind60,
19795
- shopify_asset_url: bind61,
19796
- structured_data: bind62,
19851
+ payment_button: bind59,
19852
+ payment_terms: bind60,
19853
+ placeholder_svg_tag: bind61,
19854
+ shopify_asset_url: bind62,
19855
+ structured_data: bind63,
19797
19856
  // Swell only
19798
- inline_editable: bind63
19857
+ inline_editable: bind64
19799
19858
  };
19800
19859
  function bindFilters(liquidSwell) {
19801
19860
  for (const [tag, handler] of Object.entries(filters)) {
@@ -19809,8 +19868,8 @@ function bindFilters(liquidSwell) {
19809
19868
  }
19810
19869
  }
19811
19870
  }
19812
- function bindWithResolvedProps(liquidSwell, bind64, resolve = []) {
19813
- const handler = bind64(liquidSwell);
19871
+ function bindWithResolvedProps(liquidSwell, bind65, resolve = []) {
19872
+ const handler = bind65(liquidSwell);
19814
19873
  if (!Array.isArray(resolve)) {
19815
19874
  return handler;
19816
19875
  }
@@ -20620,6 +20679,7 @@ var SwellTheme3 = class {
20620
20679
  globals;
20621
20680
  forms;
20622
20681
  resources;
20682
+ dynamicAssetUrl;
20623
20683
  liquidSwell;
20624
20684
  themeLoader;
20625
20685
  page;
@@ -20633,13 +20693,20 @@ var SwellTheme3 = class {
20633
20693
  themeSettingFilePath = "theme/config/theme.json";
20634
20694
  pageSectionGroups = null;
20635
20695
  constructor(swell, options = {}) {
20636
- const { forms, resources, globals, shopifyCompatibilityClass } = options;
20696
+ const {
20697
+ forms,
20698
+ resources,
20699
+ globals,
20700
+ dynamicAssetUrl,
20701
+ shopifyCompatibilityClass
20702
+ } = options;
20637
20703
  this.swell = swell;
20638
20704
  this.props = this.getSwellAppThemeProps(swell.config);
20639
20705
  this.shopifyCompatibilityConfig = swell.shopifyCompatibilityConfig || null;
20640
20706
  this.globals = globals || {};
20641
20707
  this.forms = forms;
20642
20708
  this.resources = resources;
20709
+ this.dynamicAssetUrl = dynamicAssetUrl;
20643
20710
  this.shopifyCompatibilityClass = shopifyCompatibilityClass || ShopifyCompatibility2;
20644
20711
  this.liquidSwell = new LiquidSwell30({
20645
20712
  theme: this,
@@ -20704,10 +20771,7 @@ var SwellTheme3 = class {
20704
20771
  geo,
20705
20772
  configs,
20706
20773
  language: configs?.language,
20707
- ...pageRecord ? getRecordGlobals(this, pageRecord) : {
20708
- page_title: page.title,
20709
- page_description: page.description
20710
- },
20774
+ ...pageRecord ? getRecordGlobals(this, pageRecord) : { page_title: page.title, page_description: page.description },
20711
20775
  all_country_option_tags: countryOptions,
20712
20776
  country_option_tags: countryOptions,
20713
20777
  canonical_url: `${store.url}${this.swell.url?.pathname || ""}`,
@@ -20735,13 +20799,8 @@ var SwellTheme3 = class {
20735
20799
  if (this.shopifyCompatibility) {
20736
20800
  this.shopifyCompatibility.adaptGlobals(globals, this.globals);
20737
20801
  }
20738
- this.globals = {
20739
- ...this.globals,
20740
- ...globals
20741
- };
20742
- this.liquidSwell.options.globals = {
20743
- ...this.globals
20744
- };
20802
+ this.globals = { ...this.globals, ...globals };
20803
+ this.liquidSwell.options.globals = { ...this.globals };
20745
20804
  }
20746
20805
  async getSettingsAndConfigs() {
20747
20806
  const geo = GEO_DATA;
@@ -20993,10 +21052,7 @@ var SwellTheme3 = class {
20993
21052
  return Object.keys(serializedFormData).length > 0 ? serializedFormData : null;
20994
21053
  }
20995
21054
  setGlobalData(data = {}) {
20996
- this.globalData = {
20997
- ...this.globalData,
20998
- ...data
20999
- };
21055
+ this.globalData = { ...this.globalData, ...data };
21000
21056
  this.setGlobals(this.globalData);
21001
21057
  }
21002
21058
  serializeGlobalData() {
@@ -21315,11 +21371,31 @@ var SwellTheme3 = class {
21315
21371
  async getAssetConfig(assetName) {
21316
21372
  return await this.getThemeConfig(`theme/assets/${assetName}`) ?? await this.getThemeConfig(`assets/${assetName}`) ?? null;
21317
21373
  }
21374
+ async getDynamicAssetUrl(filePath) {
21375
+ if (!this.dynamicAssetUrl) {
21376
+ return null;
21377
+ }
21378
+ const assetName = `${filePath}.liquid`;
21379
+ const assetConfig = await this.getAssetConfig(assetName);
21380
+ if (!assetConfig) {
21381
+ return null;
21382
+ }
21383
+ if (!this.dynamicAssetUrl.endsWith("/")) {
21384
+ this.dynamicAssetUrl += "/";
21385
+ }
21386
+ const settingsConfig = this._getTemplateConfigByType(
21387
+ "config",
21388
+ "settings_data",
21389
+ "json"
21390
+ );
21391
+ const settingsHash = settingsConfig?.hash;
21392
+ return settingsHash ? `${this.dynamicAssetUrl}v/${settingsHash}/${assetName}` : `${this.dynamicAssetUrl}${assetName}`;
21393
+ }
21318
21394
  async getAssetUrl(filePath) {
21319
21395
  const assetConfig = await this.getAssetConfig(filePath);
21320
21396
  const file = assetConfig?.file;
21321
21397
  if (!file) {
21322
- return null;
21398
+ return this.getDynamicAssetUrl(filePath);
21323
21399
  }
21324
21400
  const fileUrl = file.url || null;
21325
21401
  if (!fileUrl) {
@@ -21407,10 +21483,7 @@ var SwellTheme3 = class {
21407
21483
  if (schemaStartIndex === -1 || schemaEndIndex === -1) {
21408
21484
  return null;
21409
21485
  }
21410
- return {
21411
- ...config,
21412
- file_data: schemaTag + schemaData + schemaEndTag
21413
- };
21486
+ return { ...config, file_data: schemaTag + schemaData + schemaEndTag };
21414
21487
  }
21415
21488
  async renderThemeTemplate(filePath, data) {
21416
21489
  const config = await this.getThemeTemplateConfig(filePath);
@@ -21586,9 +21659,7 @@ ${content.slice(pos)}`;
21586
21659
  const pageSectionGroup = {
21587
21660
  // use original pageId to return exactly the requested section id
21588
21661
  id: originalPageId,
21589
- sections: {
21590
- [sectionKey]: oldSections[sectionKey]
21591
- }
21662
+ sections: { [sectionKey]: oldSections[sectionKey] }
21592
21663
  };
21593
21664
  const [pageSection] = await this.renderPageSections(
21594
21665
  pageSectionGroup,
@@ -21735,10 +21806,7 @@ ${this.shopifyCompatibility.getContentForHeader()}`;
21735
21806
  }
21736
21807
  return {
21737
21808
  ...block,
21738
- settings: {
21739
- ...blockDefaults,
21740
- ...block.settings || void 0
21741
- }
21809
+ settings: { ...blockDefaults, ...block.settings || void 0 }
21742
21810
  };
21743
21811
  }
21744
21812
  );
@@ -21875,10 +21943,7 @@ ${this.shopifyCompatibility.getContentForHeader()}`;
21875
21943
  )}</style>`;
21876
21944
  }
21877
21945
  }
21878
- return {
21879
- ...sectionConfig,
21880
- output
21881
- };
21946
+ return { ...sectionConfig, output };
21882
21947
  })
21883
21948
  );
21884
21949
  }
@@ -21941,10 +22006,7 @@ function resolveSectionSettings(theme, sectionConfig, index) {
21941
22006
  return settings;
21942
22007
  }
21943
22008
  const editorSettings = [
21944
- {
21945
- label: schema.label,
21946
- fields: schema.fields
21947
- }
22009
+ { label: schema.label, fields: schema.fields }
21948
22010
  ];
21949
22011
  let blocks = settings.section.blocks?.filter(
21950
22012
  (block) => block.disabled !== true
@@ -22777,7 +22839,6 @@ var HtmlCache = class {
22777
22839
  }
22778
22840
  generateVersionHash(headers) {
22779
22841
  const swellData = this.extractSwellData(headers);
22780
- const acceptLang = headers.get("accept-language") || "";
22781
22842
  const versionFactors = {
22782
22843
  store: headers.get("swell-storefront-id") || "",
22783
22844
  app: (headers.get("swell-app-id") || "") + "@" + (headers.get("host") || ""),
@@ -22785,7 +22846,7 @@ var HtmlCache = class {
22785
22846
  theme: headers.get("swell-theme-version-hash") || "",
22786
22847
  modified: headers.get("swell-cache-modified") || "",
22787
22848
  currency: swellData["swell-currency"] || "USD",
22788
- locale: headers.get("x-locale") || acceptLang.split(",")[0].trim().toLowerCase() || "default",
22849
+ locale: headers.get("x-locale") || swellData["swell-locale"] || "en-US",
22789
22850
  context: headers.get("swell-storefront-context"),
22790
22851
  epoch: this.epoch
22791
22852
  };
@@ -23080,6 +23141,7 @@ function getHtmlCache(env, cacheRules) {
23080
23141
  CartResource,
23081
23142
  CategoriesResource,
23082
23143
  CategoryResource,
23144
+ ContentCache,
23083
23145
  DEFAULT_CACHE_RULES,
23084
23146
  DEFAULT_QUERY_PAGE_LIMIT,
23085
23147
  DeferredShopifyResource,