cloudcommerce 2.7.3 → 2.7.4

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.
Files changed (49) hide show
  1. package/.github/workflows/create-release.yml +1 -2
  2. package/CHANGELOG.md +9 -0
  3. package/ecomplus-stores/barradoce/functions/many/package.json +3 -3
  4. package/ecomplus-stores/barradoce/functions/ssr/package.json +6 -6
  5. package/ecomplus-stores/barradoce/functions/with-apps/package.json +3 -3
  6. package/ecomplus-stores/barradoce/package.json +2 -2
  7. package/package.json +2 -2
  8. package/packages/api/package.json +1 -1
  9. package/packages/apps/affiliate-program/package.json +1 -1
  10. package/packages/apps/correios/package.json +1 -1
  11. package/packages/apps/custom-payment/package.json +1 -1
  12. package/packages/apps/custom-shipping/package.json +1 -1
  13. package/packages/apps/datafrete/package.json +1 -1
  14. package/packages/apps/discounts/package.json +1 -1
  15. package/packages/apps/emails/package.json +1 -1
  16. package/packages/apps/fb-conversions/package.json +1 -1
  17. package/packages/apps/flash-courier/package.json +1 -1
  18. package/packages/apps/frenet/package.json +1 -1
  19. package/packages/apps/galaxpay/package.json +1 -1
  20. package/packages/apps/google-analytics/package.json +1 -1
  21. package/packages/apps/jadlog/package.json +1 -1
  22. package/packages/apps/loyalty-points/package.json +1 -1
  23. package/packages/apps/mandae/package.json +1 -1
  24. package/packages/apps/melhor-envio/package.json +1 -1
  25. package/packages/apps/mercadopago/package.json +1 -1
  26. package/packages/apps/pagarme/package.json +1 -1
  27. package/packages/apps/pagarme-v5/package.json +1 -1
  28. package/packages/apps/paghiper/package.json +1 -1
  29. package/packages/apps/pix/package.json +1 -1
  30. package/packages/apps/tiny-erp/package.json +1 -1
  31. package/packages/apps/webhooks/package.json +1 -1
  32. package/packages/cli/ci/bunny-config-base.sh +21 -0
  33. package/packages/cli/package.json +1 -1
  34. package/packages/config/package.json +1 -1
  35. package/packages/emails/package.json +1 -1
  36. package/packages/eslint/package.json +1 -1
  37. package/packages/events/package.json +1 -1
  38. package/packages/feeds/package.json +1 -1
  39. package/packages/firebase/package.json +1 -1
  40. package/packages/i18n/package.json +1 -1
  41. package/packages/modules/package.json +1 -1
  42. package/packages/passport/package.json +1 -1
  43. package/packages/ssr/lib/lib/cron-ssr-save-views.js +149 -45
  44. package/packages/ssr/lib/lib/cron-ssr-save-views.js.map +1 -1
  45. package/packages/ssr/package.json +3 -3
  46. package/packages/ssr/src/lib/cron-ssr-save-views.ts +161 -45
  47. package/packages/storefront/package.json +3 -3
  48. package/packages/test-base/package.json +1 -1
  49. package/packages/types/package.json +1 -1
@@ -13,10 +13,9 @@ jobs:
13
13
  with:
14
14
  fetch-depth: 0
15
15
 
16
- - uses: Akryum/release-tag@8eeb62bcf949a368763f4057c34e7eb834467122
16
+ - uses: Akryum/release-tag@v4.0.7
17
17
  id: release_tag
18
18
  env:
19
19
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
20
20
  with:
21
21
  tag_name: ${{ github.ref }}
22
- preset: angular
package/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [2.7.4](https://github.com/ecomplus/cloud-commerce/compare/v2.7.3...v2.7.4) (2024-03-02)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * **cli:** Add "Force mime text/html" edge rule to bunny.net CI config base ([37d2c2b](https://github.com/ecomplus/cloud-commerce/commit/37d2c2bc942aa1033fe6be6f5395b54fead16b3e))
11
+ * **ssr:** Revert ISR with bunny.net by directly updating perma-cache storage files ([858f883](https://github.com/ecomplus/cloud-commerce/commit/858f88309dc7c85c3e98ae4462f2f671c409dc9c))
12
+ * **storefront:** Bump Astro to latest v4.4.9 ([3a315f0](https://github.com/ecomplus/cloud-commerce/commit/3a315f09958812d0d23a4c65b0ae262c94515f8e))
13
+
5
14
  ### [2.7.3](https://github.com/ecomplus/cloud-commerce/compare/v2.7.2...v2.7.3) (2024-03-01)
6
15
 
7
16
  ### [2.7.2](https://github.com/ecomplus/cloud-commerce/compare/v2.7.1...v2.7.2) (2024-03-01)
@@ -15,8 +15,8 @@
15
15
  },
16
16
  "main": "index.js",
17
17
  "dependencies": {
18
- "@cloudcommerce/feeds": "^2.6.5",
19
- "@cloudcommerce/firebase": "^2.6.5",
20
- "@cloudcommerce/passport": "^2.6.5"
18
+ "@cloudcommerce/feeds": "^2.7.3",
19
+ "@cloudcommerce/firebase": "^2.7.3",
20
+ "@cloudcommerce/passport": "^2.7.3"
21
21
  }
22
22
  }
@@ -19,16 +19,16 @@
19
19
  },
20
20
  "main": "index.js",
21
21
  "dependencies": {
22
- "@cloudcommerce/api": "^2.6.5",
23
- "@cloudcommerce/firebase": "^2.6.5",
24
- "@cloudcommerce/ssr": "^2.6.5",
22
+ "@cloudcommerce/api": "^2.7.3",
23
+ "@cloudcommerce/firebase": "^2.7.3",
24
+ "@cloudcommerce/ssr": "^2.7.3",
25
25
  "@headlessui/vue": "^1.7.18",
26
26
  "micromark": "^4.0.0"
27
27
  },
28
28
  "devDependencies": {
29
- "@cloudcommerce/i18n": "^2.6.5",
30
- "@cloudcommerce/storefront": "^2.6.5",
31
- "@cloudcommerce/types": "^2.6.5",
29
+ "@cloudcommerce/i18n": "^2.7.3",
30
+ "@cloudcommerce/storefront": "^2.7.3",
31
+ "@cloudcommerce/types": "^2.7.3",
32
32
  "@iconify-json/mingcute": "^1.1.16",
33
33
  "photoswipe": "^5.4.3"
34
34
  }
@@ -15,8 +15,8 @@
15
15
  },
16
16
  "main": "index.js",
17
17
  "dependencies": {
18
- "@cloudcommerce/events": "^2.6.5",
19
- "@cloudcommerce/firebase": "^2.6.5",
20
- "@cloudcommerce/modules": "^2.6.5"
18
+ "@cloudcommerce/events": "^2.7.3",
19
+ "@cloudcommerce/firebase": "^2.7.3",
20
+ "@cloudcommerce/modules": "^2.7.3"
21
21
  }
22
22
  }
@@ -26,10 +26,10 @@
26
26
  "url": "https://github.com/ecomplus/cloud-commerce/issues"
27
27
  },
28
28
  "dependencies": {
29
- "@cloudcommerce/cli": "^2.6.5"
29
+ "@cloudcommerce/cli": "^2.7.3"
30
30
  },
31
31
  "devDependencies": {
32
- "@cloudcommerce/eslint": "^2.6.5",
32
+ "@cloudcommerce/eslint": "^2.7.3",
33
33
  "husky": "^9.0.10",
34
34
  "lint-staged": "^15.2.2"
35
35
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "cloudcommerce",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "Open fair-code headless commerce platform: API-first, microservices based, event driven and cloud native",
6
6
  "main": "packages/api/lib/index.js",
7
7
  "author": "E-Com Club Softwares para E-commerce <ti@e-com.club>",
@@ -36,7 +36,7 @@
36
36
  "vite": "^5.1.4",
37
37
  "vitest": "^1.3.1",
38
38
  "zx": "^7.2.3",
39
- "@cloudcommerce/eslint": "2.7.3"
39
+ "@cloudcommerce/eslint": "2.7.4"
40
40
  },
41
41
  "scripts": {
42
42
  "fix-install": "bash scripts/pre-install.sh && pnpm i",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/api",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce APIs client/adapter",
6
6
  "main": "lib/api.js",
7
7
  "types": "lib/api.d.ts",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-affiliate-program",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app for simple affiliate program",
6
6
  "main": "lib/index.js",
7
7
  "repository": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-correios",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app for Correios shipping calculation",
6
6
  "main": "lib/index.js",
7
7
  "exports": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-custom-payment",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app for simple custom payment methods",
6
6
  "main": "lib/index.js",
7
7
  "repository": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-custom-shipping",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app for custom shipping methods",
6
6
  "main": "lib/custom-shipping.js",
7
7
  "repository": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-datafrete",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app to integrate Datafrete shipping gateway ",
6
6
  "main": "lib/datafrete.js",
7
7
  "exports": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-discounts",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app for complex discount rules",
6
6
  "main": "lib/discounts.js",
7
7
  "repository": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-emails",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce default transactional email app",
6
6
  "main": "lib/index.js",
7
7
  "repository": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-fb-conversions",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app to send carts/orders to Facebook Conversions API",
6
6
  "main": "lib/index.js",
7
7
  "repository": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-flash-courier",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app to integrate Flash Courier",
6
6
  "main": "lib/index.js",
7
7
  "exports": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-frenet",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app for Frenet shipping calculation",
6
6
  "main": "lib/frenet.js",
7
7
  "exports": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-galaxpay",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app to integrate Galax Pay for recurring payments",
6
6
  "main": "lib/galaxpay.js",
7
7
  "exports": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-google-analytics",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app to send carts/orders events to GA Measurement Protocol",
6
6
  "main": "lib/index.js",
7
7
  "repository": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-jadlog",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app for Jadlog shipping calculation",
6
6
  "main": "lib/index.js",
7
7
  "repository": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-loyalty-points",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app to handle simple loyalty points programs",
6
6
  "main": "lib/loyalty-points.js",
7
7
  "exports": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-mandae",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app to integrate Mandaê shipping intermediator",
6
6
  "main": "lib/index.js",
7
7
  "repository": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-melhor-envio",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app to integrate Melhor Envio",
6
6
  "main": "lib/index.js",
7
7
  "exports": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-mercadopago",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app to integrate Mercado Pago",
6
6
  "main": "lib/mercadopago.js",
7
7
  "exports": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-pagarme",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app to integrate Pagar.me",
6
6
  "main": "lib/pagarme.js",
7
7
  "exports": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-pagarme-v5",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app to integrate Pagar.me API v5 with recurring payments",
6
6
  "main": "lib/index.js",
7
7
  "exports": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-paghiper",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app to integrate PagHiper",
6
6
  "main": "lib/paghiper.js",
7
7
  "exports": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-pix",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app to integrate Pix API (Bacen)",
6
6
  "main": "lib/pix.js",
7
7
  "exports": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-tiny-erp",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app for Tiny ERP",
6
6
  "main": "lib/tiny-erp.js",
7
7
  "repository": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-webhooks",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app for general order webhooks",
6
6
  "main": "lib/index.js",
7
7
  "repository": {
@@ -227,3 +227,24 @@ configure_edge_rule "SSR browser cache" '
227
227
  "Enabled": true
228
228
  }
229
229
  '
230
+
231
+ configure_edge_rule "Force mime text/html" '
232
+ {
233
+ "ActionType": 5,
234
+ "ActionParameter1": "Content-Type",
235
+ "ActionParameter2": "text/html",
236
+ "Triggers": [
237
+ {
238
+ "Type": 2,
239
+ "PatternMatchingType": 0,
240
+ "PatternMatches": [
241
+ "application/octet-stream"
242
+ ],
243
+ "Parameter1": "Content-Type"
244
+ }
245
+ ],
246
+ "TriggerMatchingType": 1,
247
+ "Description": "Force mime text/html",
248
+ "Enabled": true
249
+ }
250
+ '
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/cli",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce CLI tools",
6
6
  "bin": {
7
7
  "cloudcommerce": "./bin/run.mjs"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/config",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce base config",
6
6
  "main": "lib/config.js",
7
7
  "exports": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/emails",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce email sender",
6
6
  "main": "lib/index.js",
7
7
  "types": "lib/index.d.ts",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/eslint",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce ESLint config",
6
6
  "main": "lib/index.js",
7
7
  "repository": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/events",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce app events",
6
6
  "main": "lib/index.js",
7
7
  "exports": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/feeds",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce catalog feeds",
6
6
  "main": "lib/index.js",
7
7
  "exports": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/firebase",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce on Firebase",
6
6
  "main": "lib/index.js",
7
7
  "types": "lib/index.d.ts",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/i18n",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce i18n",
6
6
  "main": "lib/all.js",
7
7
  "exports": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/modules",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce modules API",
6
6
  "main": "lib/index.cjs",
7
7
  "exports": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/passport",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce customers authentication (passport) API",
6
6
  "main": "lib/index.js",
7
7
  "exports": {
@@ -5,8 +5,77 @@ import api from '@cloudcommerce/api';
5
5
  import config from '@cloudcommerce/firebase/lib/config';
6
6
  import { deleteQueryBatch } from '@cloudcommerce/firebase/lib/helpers/firestore';
7
7
 
8
+ const loadBunnyStorageKeys = async ({ projectId, bunnyAxios, bunnyStorageKeysRef }) => {
9
+ let bunnyStorageName = process.env.BUNNYNET_STORAGE_NAME;
10
+ let bunnyStoragePass = process.env.BUNNYNET_STORAGE_PASS;
11
+ const bunnyZoneName = process.env.BUNNYNET_ZONE_NAME || projectId;
12
+ let permaCacheZoneFolder = '';
13
+ if (!bunnyStorageName || !bunnyStoragePass) {
14
+ const savedKeysData = (await bunnyStorageKeysRef.get()).data();
15
+ if (savedKeysData) {
16
+ bunnyStorageName = savedKeysData.bunnyStorageName;
17
+ bunnyStoragePass = savedKeysData.bunnyStoragePass;
18
+ permaCacheZoneFolder = savedKeysData.permaCacheZoneFolder;
19
+ } else {
20
+ const { data } = await bunnyAxios.get('/storagezone');
21
+ for (let i = 0; i < data.length; i++) {
22
+ const bunnyStorage = data[i];
23
+ if (bunnyStorageName) {
24
+ if (bunnyStorage.Name === bunnyStorageName) {
25
+ bunnyStoragePass = bunnyStorage.Password;
26
+ break;
27
+ }
28
+ continue;
29
+ }
30
+ if (bunnyStorage.Name.startsWith('storefront-isr-')) {
31
+ bunnyStorageName = bunnyStorage.Name;
32
+ bunnyStoragePass = bunnyStorage.Password;
33
+ break;
34
+ }
35
+ }
36
+ }
37
+ }
38
+ if (bunnyStorageName && bunnyStoragePass && !permaCacheZoneFolder) {
39
+ const { data } = await axios({
40
+ url: `https://storage.bunnycdn.com/${bunnyStorageName}/__bcdn_perma_cache__/`,
41
+ headers: {
42
+ AccessKey: bunnyStoragePass,
43
+ },
44
+ });
45
+ for (let i = 0; i < data.length; i++) {
46
+ const { ObjectName } = data[i];
47
+ if (ObjectName.startsWith(`pullzone__${bunnyZoneName}__`)
48
+ && (!permaCacheZoneFolder || permaCacheZoneFolder < ObjectName)) {
49
+ permaCacheZoneFolder = ObjectName;
50
+ }
51
+ }
52
+ if (permaCacheZoneFolder) {
53
+ bunnyStorageKeysRef.set({
54
+ bunnyStorageName,
55
+ bunnyStoragePass,
56
+ permaCacheZoneFolder,
57
+ });
58
+ }
59
+ }
60
+ const bunnyStorageAxios = axios.create({
61
+ baseURL: `https://storage.bunnycdn.com/${bunnyStorageName}/`,
62
+ headers: {
63
+ 'Content-Type': 'text/html',
64
+ Accept: 'application/json',
65
+ AccessKey: bunnyStoragePass,
66
+ },
67
+ });
68
+ return {
69
+ bunnyStorageName,
70
+ bunnyStoragePass,
71
+ bunnyStorageAxios,
72
+ bunnyZoneName,
73
+ permaCacheZoneFolder,
74
+ };
75
+ };
8
76
  const saveViews = async () => {
9
77
  const deployRand = process.env.DEPLOY_RAND || '_';
78
+ const projectId = process.env.GCLOUD_PROJECT;
10
79
  const db = getFirestore();
11
80
  const productViewsSnapshot = await db.collection('ssrProductViews')
12
81
  .limit(500).get();
@@ -31,54 +100,89 @@ const saveViews = async () => {
31
100
  }
32
101
  const { domain } = config.get().settingsContent;
33
102
  if (domain && process.env.BUNNYNET_API_KEY) {
34
- const bunnyAxios = axios.create({
35
- baseURL: 'https://api.bunny.net/',
36
- headers: {
37
- AccessKey: process.env.BUNNYNET_API_KEY,
38
- },
39
- });
40
- try {
41
- const sMaxAge = Number(process.env.SSR_CACHE_MAX_AGE) || 179;
42
- const pageViewsSnapshot = await db.collection('ssrPageViews')
43
- .where('at', '>', new Date(Date.now() - 1000 * 60 * 20))
44
- .where('at', '<', new Date(Date.now() - 1000 * sMaxAge))
45
- .get();
46
- const purgedUrls = [];
47
- const purgeReqs = [];
48
- for (let i = 0; i < pageViewsSnapshot.docs.length; i++) {
49
- const doc = pageViewsSnapshot.docs[i];
50
- const data = doc.data();
51
- if (data.isCachePurged) {
52
- continue;
103
+ const sMaxAge = Number(process.env.SSR_CACHE_MAX_AGE) || 179;
104
+ const pageViewsSnapshot = await db.collection('ssrPageViews')
105
+ .where('at', '>', new Date(Date.now() - 1000 * 60 * 20))
106
+ .where('at', '<', new Date(Date.now() - 1000 * sMaxAge))
107
+ .get();
108
+ const pageViewDocs = [];
109
+ for (let i = 0; i < pageViewsSnapshot.docs.length; i++) {
110
+ const doc = pageViewsSnapshot.docs[i];
111
+ const data = doc.data();
112
+ if (data.isCachePurged) {
113
+ continue;
114
+ }
115
+ const url = data.url.replace(/\?.*$/, '');
116
+ pageViewDocs.push({ ref: doc.ref, url });
117
+ }
118
+ if (pageViewDocs.length) {
119
+ const bunnyAxios = axios.create({
120
+ baseURL: 'https://api.bunny.net/',
121
+ headers: {
122
+ AccessKey: process.env.BUNNYNET_API_KEY,
123
+ },
124
+ });
125
+ const bunnyStorageKeysRef = db.doc('ssrBunnyNet/storageKeys');
126
+ try {
127
+ const { bunnyStorageAxios, permaCacheZoneFolder } = await loadBunnyStorageKeys({
128
+ projectId,
129
+ bunnyAxios,
130
+ bunnyStorageKeysRef,
131
+ });
132
+ const purgedUrls = [];
133
+ const purgeReqs = [];
134
+ for (let i = 0; i < pageViewDocs.length; i++) {
135
+ const { ref, url } = pageViewDocs[i];
136
+ ref.update({ isCachePurged: true });
137
+ if (url?.startsWith(`https://${domain}`) && !purgedUrls.includes(url)) {
138
+ purgeReqs.push(bunnyAxios('/purge', {
139
+ method: 'POST',
140
+ params: {
141
+ async: 'false',
142
+ url,
143
+ },
144
+ }));
145
+ purgedUrls.push(url);
146
+ if (permaCacheZoneFolder) {
147
+ let pathname = url.replace(`https://${domain}`, '');
148
+ const freshHtmlUrl = `https://${projectId}.web.app${pathname}`
149
+ + `?__isrV=${deployRand}&t=${Date.now()}`;
150
+ purgeReqs.push(
151
+ // eslint-disable-next-line no-loop-func
152
+ axios.get(freshHtmlUrl).then(({ data: freshHtml }) => {
153
+ if (pathname.charAt(0) === '/') {
154
+ pathname = pathname.slice(1);
155
+ }
156
+ const paths = pathname.split('/');
157
+ const filename = paths.pop() || '';
158
+ let folderpath = paths.join('/');
159
+ if (folderpath) folderpath += '/';
160
+ // https://support.bunny.net/hc/en-us/articles/360017048720-Perma-Cache-Folder-Structure-Explained
161
+ const permaCachePath = `__bcdn_perma_cache__/${permaCacheZoneFolder}`
162
+ + `/${folderpath}___${filename}___/___file___`;
163
+ bunnyStorageAxios({
164
+ method: 'PUT',
165
+ url: `/${permaCachePath}`,
166
+ data: freshHtml,
167
+ });
168
+ }),
169
+ );
170
+ }
171
+ }
53
172
  }
54
- const url = data.url.replace(/\?.*$/, '').replace(/#.*$/, '');
55
- if (url?.startsWith(`https://${domain}`) && !purgedUrls.includes(url)) {
56
- purgeReqs.push(bunnyAxios('/purge', {
57
- method: 'POST',
58
- params: {
59
- // async: 'false',
60
- url,
61
- },
62
- }).then(async () => {
63
- doc.ref.update({ isCachePurged: true });
64
- const freshHtmlUrl = `${url}?__isrV=${deployRand}&t=${Date.now()}`;
65
- await axios.get(freshHtmlUrl);
66
- // info(`Cache bump ${url}`);
67
- }));
68
- purgedUrls.push(url);
173
+ await Promise.all(purgeReqs);
174
+ } catch (err) {
175
+ bunnyStorageKeysRef.delete();
176
+ if (err.response) {
177
+ const _err = new Error('Cant purge bunny.net cache');
178
+ _err.config = err.config;
179
+ _err.statusCode = err.response.status;
180
+ _err.data = err.response.data;
181
+ error(_err);
182
+ } else {
183
+ error(err);
69
184
  }
70
185
  }
71
- await Promise.all(purgeReqs);
72
- } catch (err) {
73
- if (err.response) {
74
- const _err = new Error('Cant purge bunny.net cache');
75
- _err.config = err.config;
76
- _err.statusCode = err.response.status;
77
- _err.data = err.response.data;
78
- error(_err);
79
- } else {
80
- error(err);
81
- }
82
186
  }
83
187
  }
84
188
  const date = new Date();
@@ -1 +1 @@
1
- {"version":3,"file":"cron-ssr-save-views.js","sourceRoot":"","sources":["../../src/lib/cron-ssr-save-views.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cron-ssr-save-views.js","sourceRoot":"","sources":["../../src/lib/cron-ssr-save-views.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/ssr",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce storefront SSR",
6
6
  "main": "lib/index.js",
7
7
  "exports": {
@@ -26,13 +26,13 @@
26
26
  "build:workers": "npx tsc -p src/cloudflare --outDir cloudflare && npx eslint --ext .js cloudflare --fix"
27
27
  },
28
28
  "dependencies": {
29
- "@astrojs/node": "8.2.1",
29
+ "@astrojs/node": "8.2.3",
30
30
  "@cloudcommerce/api": "workspace:*",
31
31
  "@cloudcommerce/firebase": "workspace:*",
32
32
  "@cloudcommerce/i18n": "workspace:*",
33
33
  "@ecomplus/utils": "1.5.0-rc.6",
34
34
  "@vueuse/core": "10.8.0",
35
- "astro": "4.4.6",
35
+ "astro": "4.4.9",
36
36
  "astro-capo": "^0.0.1",
37
37
  "axios": "^1.6.7",
38
38
  "firebase-admin": "^12.0.0",
@@ -1,3 +1,5 @@
1
+ import type { DocumentReference } from 'firebase-admin/firestore';
2
+ import type { AxiosInstance } from 'axios';
1
3
  import { getFirestore } from 'firebase-admin/firestore';
2
4
  import { error } from 'firebase-functions/logger';
3
5
  import axios from 'axios';
@@ -5,8 +7,84 @@ import api from '@cloudcommerce/api';
5
7
  import config from '@cloudcommerce/firebase/lib/config';
6
8
  import { deleteQueryBatch } from '@cloudcommerce/firebase/lib/helpers/firestore';
7
9
 
10
+ const loadBunnyStorageKeys = async ({ projectId, bunnyAxios, bunnyStorageKeysRef }: {
11
+ projectId: string,
12
+ bunnyAxios: AxiosInstance,
13
+ bunnyStorageKeysRef: DocumentReference,
14
+ }) => {
15
+ let bunnyStorageName = process.env.BUNNYNET_STORAGE_NAME;
16
+ let bunnyStoragePass = process.env.BUNNYNET_STORAGE_PASS;
17
+ const bunnyZoneName = process.env.BUNNYNET_ZONE_NAME || projectId;
18
+ let permaCacheZoneFolder = '';
19
+ if (!bunnyStorageName || !bunnyStoragePass) {
20
+ const savedKeysData = (await bunnyStorageKeysRef.get()).data();
21
+ if (savedKeysData) {
22
+ bunnyStorageName = savedKeysData.bunnyStorageName;
23
+ bunnyStoragePass = savedKeysData.bunnyStoragePass;
24
+ permaCacheZoneFolder = savedKeysData.permaCacheZoneFolder;
25
+ } else {
26
+ const { data } = await bunnyAxios.get('/storagezone');
27
+ for (let i = 0; i < data.length; i++) {
28
+ const bunnyStorage = data[i];
29
+ if (bunnyStorageName) {
30
+ if (bunnyStorage.Name === bunnyStorageName) {
31
+ bunnyStoragePass = bunnyStorage.Password;
32
+ break;
33
+ }
34
+ continue;
35
+ }
36
+ if (bunnyStorage.Name.startsWith('storefront-isr-')) {
37
+ bunnyStorageName = bunnyStorage.Name;
38
+ bunnyStoragePass = bunnyStorage.Password;
39
+ break;
40
+ }
41
+ }
42
+ }
43
+ }
44
+ if (bunnyStorageName && bunnyStoragePass && !permaCacheZoneFolder) {
45
+ const { data } = await axios({
46
+ url: `https://storage.bunnycdn.com/${bunnyStorageName}/__bcdn_perma_cache__/`,
47
+ headers: {
48
+ AccessKey: bunnyStoragePass,
49
+ },
50
+ });
51
+ for (let i = 0; i < data.length; i++) {
52
+ const { ObjectName } = data[i];
53
+ if (
54
+ ObjectName.startsWith(`pullzone__${bunnyZoneName}__`)
55
+ && (!permaCacheZoneFolder || permaCacheZoneFolder < ObjectName)
56
+ ) {
57
+ permaCacheZoneFolder = ObjectName;
58
+ }
59
+ }
60
+ if (permaCacheZoneFolder) {
61
+ bunnyStorageKeysRef.set({
62
+ bunnyStorageName,
63
+ bunnyStoragePass,
64
+ permaCacheZoneFolder,
65
+ });
66
+ }
67
+ }
68
+ const bunnyStorageAxios = axios.create({
69
+ baseURL: `https://storage.bunnycdn.com/${bunnyStorageName}/`,
70
+ headers: {
71
+ 'Content-Type': 'text/html',
72
+ Accept: 'application/json',
73
+ AccessKey: bunnyStoragePass,
74
+ },
75
+ });
76
+ return {
77
+ bunnyStorageName,
78
+ bunnyStoragePass,
79
+ bunnyStorageAxios,
80
+ bunnyZoneName,
81
+ permaCacheZoneFolder,
82
+ };
83
+ };
84
+
8
85
  const saveViews = async () => {
9
86
  const deployRand = process.env.DEPLOY_RAND || '_';
87
+ const projectId = process.env.GCLOUD_PROJECT as string;
10
88
  const db = getFirestore();
11
89
  const productViewsSnapshot = await db.collection('ssrProductViews')
12
90
  .limit(500).get();
@@ -31,54 +109,92 @@ const saveViews = async () => {
31
109
  }
32
110
  const { domain } = config.get().settingsContent;
33
111
  if (domain && process.env.BUNNYNET_API_KEY) {
34
- const bunnyAxios = axios.create({
35
- baseURL: 'https://api.bunny.net/',
36
- headers: {
37
- AccessKey: process.env.BUNNYNET_API_KEY,
38
- },
39
- });
40
- try {
41
- const sMaxAge = Number(process.env.SSR_CACHE_MAX_AGE) || 179;
42
- const pageViewsSnapshot = await db.collection('ssrPageViews')
43
- .where('at', '>', new Date(Date.now() - 1000 * 60 * 20))
44
- .where('at', '<', new Date(Date.now() - 1000 * sMaxAge))
45
- .get();
46
- const purgedUrls: string[] = [];
47
- const purgeReqs: Promise<any>[] = [];
48
- for (let i = 0; i < pageViewsSnapshot.docs.length; i++) {
49
- const doc = pageViewsSnapshot.docs[i];
50
- const data = doc.data() as { url: string, isCachePurged?: true };
51
- if (data.isCachePurged) {
52
- continue;
112
+ const sMaxAge = Number(process.env.SSR_CACHE_MAX_AGE) || 179;
113
+ const pageViewsSnapshot = await db.collection('ssrPageViews')
114
+ .where('at', '>', new Date(Date.now() - 1000 * 60 * 20))
115
+ .where('at', '<', new Date(Date.now() - 1000 * sMaxAge))
116
+ .get();
117
+ const pageViewDocs: Array<{ ref: DocumentReference, url: string }> = [];
118
+ for (let i = 0; i < pageViewsSnapshot.docs.length; i++) {
119
+ const doc = pageViewsSnapshot.docs[i];
120
+ const data = doc.data() as { url: string, isCachePurged?: true };
121
+ if (data.isCachePurged) {
122
+ continue;
123
+ }
124
+ const url = data.url.replace(/\?.*$/, '');
125
+ pageViewDocs.push({ ref: doc.ref, url });
126
+ }
127
+ if (pageViewDocs.length) {
128
+ const bunnyAxios = axios.create({
129
+ baseURL: 'https://api.bunny.net/',
130
+ headers: {
131
+ AccessKey: process.env.BUNNYNET_API_KEY,
132
+ },
133
+ });
134
+ const bunnyStorageKeysRef = db.doc('ssrBunnyNet/storageKeys');
135
+ try {
136
+ const {
137
+ bunnyStorageAxios,
138
+ permaCacheZoneFolder,
139
+ } = await loadBunnyStorageKeys({
140
+ projectId,
141
+ bunnyAxios,
142
+ bunnyStorageKeysRef,
143
+ });
144
+ const purgedUrls: string[] = [];
145
+ const purgeReqs: Promise<any>[] = [];
146
+ for (let i = 0; i < pageViewDocs.length; i++) {
147
+ const { ref, url } = pageViewDocs[i];
148
+ ref.update({ isCachePurged: true });
149
+ if (url?.startsWith(`https://${domain}`) && !purgedUrls.includes(url)) {
150
+ purgeReqs.push(bunnyAxios('/purge', {
151
+ method: 'POST',
152
+ params: {
153
+ async: 'false',
154
+ url,
155
+ },
156
+ }));
157
+ purgedUrls.push(url);
158
+ if (permaCacheZoneFolder) {
159
+ let pathname = url.replace(`https://${domain}`, '');
160
+ const freshHtmlUrl = `https://${projectId}.web.app${pathname}`
161
+ + `?__isrV=${deployRand}&t=${Date.now()}`;
162
+ purgeReqs.push(
163
+ // eslint-disable-next-line no-loop-func
164
+ axios.get(freshHtmlUrl).then(({ data: freshHtml }: { data: string }) => {
165
+ if (pathname.charAt(0) === '/') {
166
+ pathname = pathname.slice(1);
167
+ }
168
+ const paths = pathname.split('/');
169
+ const filename = paths.pop() || '';
170
+ let folderpath = paths.join('/');
171
+ if (folderpath) folderpath += '/';
172
+ // https://support.bunny.net/hc/en-us/articles/360017048720-Perma-Cache-Folder-Structure-Explained
173
+ const permaCachePath = `__bcdn_perma_cache__/${permaCacheZoneFolder}`
174
+ + `/${folderpath}___${filename}___/___file___`;
175
+ bunnyStorageAxios({
176
+ method: 'PUT',
177
+ url: `/${permaCachePath}`,
178
+ data: freshHtml,
179
+ });
180
+ }),
181
+ );
182
+ }
183
+ }
53
184
  }
54
- const url = data.url.replace(/\?.*$/, '').replace(/#.*$/, '');
55
- if (url?.startsWith(`https://${domain}`) && !purgedUrls.includes(url)) {
56
- purgeReqs.push(bunnyAxios('/purge', {
57
- method: 'POST',
58
- params: {
59
- // async: 'false',
60
- url,
61
- },
62
- }).then(async () => {
63
- doc.ref.update({ isCachePurged: true });
64
- const freshHtmlUrl = `${url}?__isrV=${deployRand}&t=${Date.now()}`;
65
- await axios.get(freshHtmlUrl);
66
- // info(`Cache bump ${url}`);
67
- }));
68
- purgedUrls.push(url);
185
+ await Promise.all(purgeReqs);
186
+ } catch (err: any) {
187
+ bunnyStorageKeysRef.delete();
188
+ if (err.response) {
189
+ const _err: any = new Error('Cant purge bunny.net cache');
190
+ _err.config = err.config;
191
+ _err.statusCode = err.response.status;
192
+ _err.data = err.response.data;
193
+ error(_err);
194
+ } else {
195
+ error(err);
69
196
  }
70
197
  }
71
- await Promise.all(purgeReqs);
72
- } catch (err: any) {
73
- if (err.response) {
74
- const _err: any = new Error('Cant purge bunny.net cache');
75
- _err.config = err.config;
76
- _err.statusCode = err.response.status;
77
- _err.data = err.response.data;
78
- error(_err);
79
- } else {
80
- error(err);
81
- }
82
198
  }
83
199
  }
84
200
  const date = new Date();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/storefront",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce storefront with Astro",
6
6
  "bin": {
7
7
  "storefront": "./scripts/build-prod.sh"
@@ -30,7 +30,7 @@
30
30
  "lint:fix": "eslint -c ../eslint/storefront.staged.eslintrc.cjs src/lib/**/*.{ts,vue,astro} --fix"
31
31
  },
32
32
  "dependencies": {
33
- "@astrojs/node": "8.2.1",
33
+ "@astrojs/node": "8.2.3",
34
34
  "@astrojs/vue": "4.0.8",
35
35
  "@cloudcommerce/api": "workspace:*",
36
36
  "@cloudcommerce/config": "workspace:*",
@@ -44,7 +44,7 @@
44
44
  "@vite-pwa/astro": "^0.3.0",
45
45
  "@vueuse/core": "10.8.0",
46
46
  "@webcontainer/api": "^1.1.9",
47
- "astro": "4.4.6",
47
+ "astro": "4.4.9",
48
48
  "astro-capo": "^0.0.1",
49
49
  "chroma-js": "^2.4.2",
50
50
  "dotenv": "^16.4.5",
@@ -2,7 +2,7 @@
2
2
  "name": "@cloudcommerce/test-base",
3
3
  "private": true,
4
4
  "type": "module",
5
- "version": "2.7.3",
5
+ "version": "2.7.4",
6
6
  "description": "E-Com Plus Cloud Commerce basic setup for testing",
7
7
  "main": "lib/index.js",
8
8
  "repository": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/types",
3
3
  "type": "module",
4
- "version": "2.7.3",
4
+ "version": "2.7.4",
5
5
  "description": "E-Com Plus Cloud Commerce reusable type definitions",
6
6
  "main": "index.ts",
7
7
  "repository": {