cloudcommerce 0.8.2 → 0.8.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 (51) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/ecomplus-stores/monocard/functions/core/package.json +1 -1
  3. package/ecomplus-stores/monocard/functions/events/package.json +2 -2
  4. package/ecomplus-stores/monocard/functions/modules/package.json +2 -2
  5. package/ecomplus-stores/monocard/functions/passport/package.json +2 -2
  6. package/ecomplus-stores/monocard/functions/ssr/package.json +6 -6
  7. package/ecomplus-stores/monocard/package.json +1 -1
  8. package/package.json +1 -1
  9. package/packages/api/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/frenet/package.json +1 -1
  18. package/packages/apps/galaxpay/package.json +1 -1
  19. package/packages/apps/google-analytics/package.json +1 -1
  20. package/packages/apps/infinitepay/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/melhor-envio/package.json +1 -1
  24. package/packages/apps/mercadopago/package.json +1 -1
  25. package/packages/apps/pagarme/package.json +1 -1
  26. package/packages/apps/paghiper/package.json +1 -1
  27. package/packages/apps/pix/package.json +1 -1
  28. package/packages/apps/tiny-erp/package.json +1 -1
  29. package/packages/apps/webhooks/package.json +1 -1
  30. package/packages/cli/package.json +1 -1
  31. package/packages/config/package.json +1 -1
  32. package/packages/emails/package.json +1 -1
  33. package/packages/events/package.json +1 -1
  34. package/packages/firebase/package.json +1 -1
  35. package/packages/i18n/package.json +1 -1
  36. package/packages/modules/package.json +1 -1
  37. package/packages/passport/package.json +1 -1
  38. package/packages/ssr/lib/firebase/serve-storefront.js +43 -1
  39. package/packages/ssr/lib/firebase/serve-storefront.js.map +1 -1
  40. package/packages/ssr/package.json +1 -1
  41. package/packages/ssr/src/firebase/serve-storefront.ts +44 -0
  42. package/packages/storefront/dist/server/chunks/pages/{all.d97031a1.mjs → all.090434f8.mjs} +74 -58
  43. package/packages/storefront/dist/server/entry.mjs +2 -2
  44. package/packages/storefront/package.json +1 -1
  45. package/packages/storefront/scripts/build-prod.sh +2 -2
  46. package/packages/storefront/src/lib/components/Picture.astro +20 -8
  47. package/packages/storefront/src/lib/layouts/BaseBody.astro +15 -0
  48. package/packages/storefront/src/lib/layouts/BaseHead.astro +15 -7
  49. package/packages/storefront/src/serverless/Picture.runtime.astro +15 -3
  50. package/packages/storefront/src/serverless/get-image.ts +14 -8
  51. package/packages/types/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,33 @@
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
+ ### [0.8.4](https://github.com/ecomplus/cloud-commerce/compare/v0.8.3...v0.8.4) (2023-03-18)
6
+
7
+
8
+ ### Features
9
+
10
+ * **storefront:** Update custom `<Picture>` to support lazy load libs with `hasImg={false}` prop ([be9bbdc](https://github.com/ecomplus/cloud-commerce/commit/be9bbdc46635717b52dd23ab0f5daec11c3a37a8))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **storefront:** Fix built (fav)icon format to png only ([e02b3cc](https://github.com/ecomplus/cloud-commerce/commit/e02b3cc0e35d7330c4c317e1a7d70e0032844afc))
16
+
17
+ ### [0.8.3](https://github.com/ecomplus/cloud-commerce/compare/v0.8.2...v0.8.3) (2023-03-18)
18
+
19
+
20
+ ### Features
21
+
22
+ * **ssr:** Simple fallback to /_image route reading images manifest ([3fb19b0](https://github.com/ecomplus/cloud-commerce/commit/3fb19b06452082f270e9e3c853e53efe1eaa4b51))
23
+ * **storefront:** Add hidden icon (if set) on body with <Picture> to pre-compile [[#129](https://github.com/ecomplus/cloud-commerce/issues/129)] ([a4838f0](https://github.com/ecomplus/cloud-commerce/commit/a4838f00310674a0da747a21e596c57ad5107826))
24
+
25
+
26
+ ### Bug Fixes
27
+
28
+ * **ssr:** Edit /_image route fallback to just return original href if no built image found ([6d38140](https://github.com/ecomplus/cloud-commerce/commit/6d381400648309b39089faa80c5c4a9d32c5b8c2))
29
+ * **storefront:** Prevent fatal error with unmatched built image ([b4dc6f8](https://github.com/ecomplus/cloud-commerce/commit/b4dc6f8acf47ac49e310a8b0b4377c236120e238))
30
+ * **storefront:** Use `STOREFRONT_BASE_DIR` if set to read images manifest files ([bee44a7](https://github.com/ecomplus/cloud-commerce/commit/bee44a73a1f56a5594458100bd42ff959bb7a462))
31
+
5
32
  ### [0.8.2](https://github.com/ecomplus/cloud-commerce/compare/v0.8.1...v0.8.2) (2023-03-17)
6
33
 
7
34
 
@@ -15,6 +15,6 @@
15
15
  },
16
16
  "main": "index.js",
17
17
  "dependencies": {
18
- "@cloudcommerce/firebase": "^0.8.1"
18
+ "@cloudcommerce/firebase": "^0.8.3"
19
19
  }
20
20
  }
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "main": "index.js",
17
17
  "dependencies": {
18
- "@cloudcommerce/events": "^0.8.1",
19
- "@cloudcommerce/firebase": "^0.8.1"
18
+ "@cloudcommerce/events": "^0.8.3",
19
+ "@cloudcommerce/firebase": "^0.8.3"
20
20
  }
21
21
  }
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "main": "index.js",
17
17
  "dependencies": {
18
- "@cloudcommerce/firebase": "^0.8.1",
19
- "@cloudcommerce/modules": "^0.8.1"
18
+ "@cloudcommerce/firebase": "^0.8.3",
19
+ "@cloudcommerce/modules": "^0.8.3"
20
20
  }
21
21
  }
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "main": "index.js",
17
17
  "dependencies": {
18
- "@cloudcommerce/firebase": "^0.8.1",
19
- "@cloudcommerce/passport": "^0.8.1"
18
+ "@cloudcommerce/firebase": "^0.8.3",
19
+ "@cloudcommerce/passport": "^0.8.3"
20
20
  }
21
21
  }
@@ -18,15 +18,15 @@
18
18
  "main": "index.js",
19
19
  "dependencies": {
20
20
  "@astrojs/node": "5.1.0",
21
- "@cloudcommerce/api": "^0.8.1",
22
- "@cloudcommerce/firebase": "^0.8.1",
23
- "@cloudcommerce/ssr": "^0.8.1",
21
+ "@cloudcommerce/api": "^0.8.3",
22
+ "@cloudcommerce/firebase": "^0.8.3",
23
+ "@cloudcommerce/ssr": "^0.8.3",
24
24
  "@vueuse/motion": "2.0.0-beta.22"
25
25
  },
26
26
  "devDependencies": {
27
- "@cloudcommerce/i18n": "^0.8.1",
28
- "@cloudcommerce/storefront": "^0.8.1",
29
- "@cloudcommerce/types": "^0.8.1",
27
+ "@cloudcommerce/i18n": "^0.8.3",
28
+ "@cloudcommerce/storefront": "^0.8.3",
29
+ "@cloudcommerce/types": "^0.8.3",
30
30
  "@fontsource/inter": "^4.5.15",
31
31
  "@iconify-json/ri": "^1.1.5",
32
32
  "@iconify-json/wpf": "^1.1.4",
@@ -23,6 +23,6 @@
23
23
  "url": "https://github.com/ecomplus/cloud-commerce/issues"
24
24
  },
25
25
  "dependencies": {
26
- "@cloudcommerce/cli": "^0.8.1"
26
+ "@cloudcommerce/cli": "^0.8.3"
27
27
  }
28
28
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "cloudcommerce",
3
3
  "type": "module",
4
- "version": "0.8.2",
4
+ "version": "0.8.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>",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/api",
3
3
  "type": "module",
4
- "version": "0.8.2",
4
+ "version": "0.8.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-correios",
3
3
  "type": "module",
4
- "version": "0.8.2",
4
+ "version": "0.8.4",
5
5
  "description": "E-Com Plus Cloud Commerce app for Correios shipping calculation",
6
6
  "main": "lib/correios.js",
7
7
  "repository": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-custom-payment",
3
3
  "type": "module",
4
- "version": "0.8.2",
4
+ "version": "0.8.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": "0.8.2",
4
+ "version": "0.8.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": "0.8.2",
4
+ "version": "0.8.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": "0.8.2",
4
+ "version": "0.8.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": "0.8.2",
4
+ "version": "0.8.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": "0.8.2",
4
+ "version": "0.8.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-frenet",
3
3
  "type": "module",
4
- "version": "0.8.2",
4
+ "version": "0.8.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": "0.8.2",
4
+ "version": "0.8.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": "0.8.2",
4
+ "version": "0.8.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-infinitepay",
3
3
  "type": "module",
4
- "version": "0.8.2",
4
+ "version": "0.8.4",
5
5
  "description": "E-Com Plus Cloud Commerce app to integrate InfinitePay",
6
6
  "main": "lib/infinitepay.js",
7
7
  "exports": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/app-jadlog",
3
3
  "type": "module",
4
- "version": "0.8.2",
4
+ "version": "0.8.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": "0.8.2",
4
+ "version": "0.8.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-melhor-envio",
3
3
  "type": "module",
4
- "version": "0.8.2",
4
+ "version": "0.8.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": "0.8.2",
4
+ "version": "0.8.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": "0.8.2",
4
+ "version": "0.8.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-paghiper",
3
3
  "type": "module",
4
- "version": "0.8.2",
4
+ "version": "0.8.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": "0.8.2",
4
+ "version": "0.8.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": "0.8.2",
4
+ "version": "0.8.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": "0.8.2",
4
+ "version": "0.8.4",
5
5
  "description": "E-Com Plus Cloud Commerce app for general order webhooks",
6
6
  "main": "lib/index.js",
7
7
  "repository": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/cli",
3
3
  "type": "module",
4
- "version": "0.8.2",
4
+ "version": "0.8.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": "0.8.2",
4
+ "version": "0.8.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": "0.8.2",
4
+ "version": "0.8.4",
5
5
  "description": "E-Com Plus Cloud Commerce",
6
6
  "main": "lib/index.js",
7
7
  "types": "lib/index.d.ts",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/events",
3
3
  "type": "module",
4
- "version": "0.8.2",
4
+ "version": "0.8.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/firebase",
3
3
  "type": "module",
4
- "version": "0.8.2",
4
+ "version": "0.8.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": "0.8.2",
4
+ "version": "0.8.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": "0.8.2",
4
+ "version": "0.8.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": "0.8.2",
4
+ "version": "0.8.4",
5
5
  "description": "E-Com Plus Cloud Commerce customers authentication (passport) API",
6
6
  "main": "lib/index.js",
7
7
  "exports": {
@@ -5,6 +5,8 @@ import logger from 'firebase-functions/logger';
5
5
  const { STOREFRONT_BASE_DIR } = process.env;
6
6
  const baseDir = STOREFRONT_BASE_DIR || process.cwd();
7
7
  const clientRoot = new URL(joinPath(baseDir, 'dist/client/'), import.meta.url);
8
+ let imagesManifest;
9
+ const builtImages = [];
8
10
 
9
11
  export default (req, res) => {
10
12
  res.set('X-XSS-Protection', '1; mode=block');
@@ -28,7 +30,47 @@ export default (req, res) => {
28
30
  .send(err.toString());
29
31
  }
30
32
  };
31
- /*
33
+ if (req.path === '/_image') {
34
+ const { href } = req.query;
35
+ if (typeof href === 'string' && href.length > 3) {
36
+ const width = Number(req.query.w);
37
+ const format = String(req.query.f);
38
+ if (width > 0 && /^(webp|avif|png|jpg|jpeg)$/.test(format)) {
39
+ (async () => {
40
+ if (!imagesManifest) {
41
+ const manifestFilepath = joinPath(baseDir, 'dist/server/images.dist.csv');
42
+ imagesManifest = await readFile(manifestFilepath, 'utf-8');
43
+ imagesManifest.split(/\n/).forEach((line) => {
44
+ const [filename, _width, height] = line.split(',');
45
+ builtImages.push({
46
+ filename,
47
+ width: Number(_width),
48
+ height: Number(height),
49
+ });
50
+ });
51
+ builtImages.sort((a, b) => {
52
+ if (a.width < b.width) return -1;
53
+ return 1;
54
+ });
55
+ }
56
+ const filename = href.replace(/^.*\//, '').replace(/.\w+(\?.*)?$/, '');
57
+ const filenameRegExp = new RegExp(`[_.][a-z0-9]+\\.${format}$`, 'i');
58
+ const builtImage = builtImages.find((_builtImage) => {
59
+ return _builtImage.width >= width
60
+ && filename === _builtImage.filename.replace(filenameRegExp, '');
61
+ });
62
+ if (builtImage) {
63
+ return res.redirect(301, `/_astro/${builtImage.filename}`);
64
+ }
65
+ return res.redirect(302, href);
66
+ })();
67
+ return;
68
+ }
69
+ }
70
+ res.sendStatus(400);
71
+ return;
72
+ }
73
+ /*
32
74
  https://github.com/withastro/astro/blob/main/examples/ssr/server/server.mjs
33
75
  import { handler as ssrHandler } from '../dist/server/entry.mjs';
34
76
  global.ssr_handler = ssrHandler;
@@ -1 +1 @@
1
- {"version":3,"file":"serve-storefront.js","sourceRoot":"","sources":["../../src/firebase/serve-storefront.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"serve-storefront.js","sourceRoot":"","sources":["../../src/firebase/serve-storefront.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/ssr",
3
3
  "type": "module",
4
- "version": "0.8.2",
4
+ "version": "0.8.4",
5
5
  "description": "E-Com Plus Cloud Commerce storefront SSR",
6
6
  "main": "lib/index.js",
7
7
  "exports": {
@@ -6,6 +6,9 @@ import logger from 'firebase-functions/logger';
6
6
  const { STOREFRONT_BASE_DIR } = process.env;
7
7
  const baseDir = STOREFRONT_BASE_DIR || process.cwd();
8
8
  const clientRoot = new URL(joinPath(baseDir, 'dist/client/'), import.meta.url);
9
+ let imagesManifest: string;
10
+ type BuiltImage = { filename: string, width: number, height: number };
11
+ const builtImages: BuiltImage[] = [];
9
12
 
10
13
  export default (req: Request, res: Response) => {
11
14
  res.set('X-XSS-Protection', '1; mode=block');
@@ -35,6 +38,47 @@ export default (req: Request, res: Response) => {
35
38
  }
36
39
  };
37
40
 
41
+ if (req.path === '/_image') {
42
+ const { href } = req.query;
43
+ if (typeof href === 'string' && href.length > 3) {
44
+ const width = Number(req.query.w);
45
+ const format = String(req.query.f);
46
+ if (width > 0 && /^(webp|avif|png|jpg|jpeg)$/.test(format)) {
47
+ (async () => {
48
+ if (!imagesManifest) {
49
+ const manifestFilepath = joinPath(baseDir, 'dist/server/images.dist.csv');
50
+ imagesManifest = await readFile(manifestFilepath, 'utf-8');
51
+ imagesManifest.split(/\n/).forEach((line) => {
52
+ const [filename, _width, height] = line.split(',');
53
+ builtImages.push({
54
+ filename,
55
+ width: Number(_width),
56
+ height: Number(height),
57
+ });
58
+ });
59
+ builtImages.sort((a, b) => {
60
+ if (a.width < b.width) return -1;
61
+ return 1;
62
+ });
63
+ }
64
+ const filename = href.replace(/^.*\//, '').replace(/.\w+(\?.*)?$/, '');
65
+ const filenameRegExp = new RegExp(`[_.][a-z0-9]+\\.${format}$`, 'i');
66
+ const builtImage = builtImages.find((_builtImage) => {
67
+ return _builtImage.width >= width
68
+ && filename === _builtImage.filename.replace(filenameRegExp, '');
69
+ });
70
+ if (builtImage) {
71
+ return res.redirect(301, `/_astro/${builtImage.filename}`);
72
+ }
73
+ return res.redirect(302, href);
74
+ })();
75
+ return;
76
+ }
77
+ }
78
+ res.sendStatus(400);
79
+ return;
80
+ }
81
+
38
82
  /*
39
83
  https://github.com/withastro/astro/blob/main/examples/ssr/server/server.mjs
40
84
  import { handler as ssrHandler } from '../dist/server/entry.mjs';
@@ -9,7 +9,7 @@ import 'node:os';
9
9
  import sizeOf from 'image-size';
10
10
  import 'magic-string';
11
11
  import 'node:stream';
12
- import { c as createAstro, a as createComponent, r as renderTemplate, b as addAttribute, d as renderComponent, u as unescapeHTML, F as Fragment, m as maybeRenderHead, e as renderSlot, f as renderHead, s as spreadAttributes } from '../astro.9781c0a7.mjs';
12
+ import { c as createAstro, a as createComponent, r as renderTemplate, b as addAttribute, d as renderComponent, u as unescapeHTML, F as Fragment, m as maybeRenderHead, s as spreadAttributes, e as renderSlot, f as renderHead } from '../astro.9781c0a7.mjs';
13
13
  import api from '@cloudcommerce/api';
14
14
  import { reactive, computed, defineComponent, inject, useSSRContext, mergeProps, ref, watch, toRef, onMounted, onBeforeUnmount, provide, createVNode, resolveDynamicComponent, withCtx, renderSlot as renderSlot$1, withDirectives, vShow, openBlock, createBlock, createCommentVNode, Fragment as Fragment$1, renderList, resolveComponent, withModifiers, Teleport, createTextVNode, toDisplayString, setBlockTracking } from 'vue';
15
15
  import { img, price, formatMoney, nickname, onPromotion } from '@ecomplus/utils';
@@ -476,6 +476,10 @@ const $$Astro$g = createAstro("https://ecom2-002.web.app");
476
476
  const $$BaseHead = createComponent(async ($$result, $$props, $$slots) => {
477
477
  const Astro2 = $$result.createAstro($$Astro$g, $$props, $$slots);
478
478
  Astro2.self = $$BaseHead;
479
+ const deployRand = process.env.DEPLOY_RAND || "_";
480
+ const getIconUrl = (size) => {
481
+ return `/_image?f=png&w=${size}&h=${size}&href=${encodeURIComponent(settings.icon)}&V=${deployRand}`;
482
+ };
479
483
  const {
480
484
  storeId,
481
485
  cmsContent,
@@ -489,7 +493,8 @@ const $$BaseHead = createComponent(async ($$result, $$props, $$slots) => {
489
493
  const state = apiDoc || cmsContent || {};
490
494
  const title = state.meta_title || state.name || state.title || Astro2.props.title || settings.name;
491
495
  const description = state.meta_description || state.short_description || settings.description;
492
- const favicon = settings.icon ? `/_image?f=png&w=32&h=32&format=png&href=${encodeURIComponent(settings.icon)}&V=${({}).DEPLOY_RAND}` : "/favicon.ico";
496
+ const favicon = settings.icon ? getIconUrl(32) : "/favicon.ico";
497
+ const shortcutIcon = settings.icon ? getIconUrl(192) : null;
493
498
  const canonicalUrl = new URL(Astro2.url.pathname, Astro2.site || `https://${domain}`);
494
499
  const cmsMetatags = await cms("metatags");
495
500
  const ogLocale = lang.length === 2 ? lang : lang.substring(0, 2) + lang.slice(3).toUpperCase();
@@ -508,13 +513,14 @@ const $$BaseHead = createComponent(async ($$result, $$props, $$slots) => {
508
513
  return renderTemplate`<meta charset="UTF-8">
509
514
  <meta name="viewport" content="width=device-width">
510
515
  <meta name="theme-color"${addAttribute(primaryColor, "content")}>
511
- <link rel="icon"${addAttribute(favicon, "href")}>
516
+ <link rel="icon" type="image/png"${addAttribute(favicon, "href")} sizes="32x32">
517
+ ${shortcutIcon && renderTemplate`<link rel="icon" type="image/png"${addAttribute(shortcutIcon, "href")} sizes="192x192">`}
512
518
  <title>${title}</title>
513
519
  <meta name="description"${addAttribute(description, "content")}>
514
520
  <meta name="author"${addAttribute(settings.name, "content")}>
515
521
  <meta name="generator"${addAttribute(Astro2.generator, "content")}>
516
522
  <link rel="canonical"${addAttribute(canonicalUrl, "href")}>
517
- <link rel="apple-touch-icon"${addAttribute(settings.icon, "href")}>
523
+ ${shortcutIcon && renderTemplate`<link rel="apple-touch-icon"${addAttribute(shortcutIcon, "href")}>`}
518
524
  <meta name="apple-mobile-web-app-capable" content="yes">
519
525
  <meta name="apple-mobile-web-app-status-bar-style" content="default">
520
526
  <meta property="og:site_name"${addAttribute(settings.name, "content")}>
@@ -599,56 +605,6 @@ window.storefront.context = ${JSON.stringify({
599
605
  return renderTemplate(_a$1 || (_a$1 = __template$1(["<script>", '<\/script>\n<script type="application/ld+json">', "<\/script>"])), unescapeHTML(inlineClientJS), unescapeHTML(inlineJSONLd));
600
606
  }, "/home/leo/code/ecomplus/cloud-commerce/packages/storefront/src/lib/layouts/BaseStateJson.astro");
601
607
 
602
- const $$Astro$e = createAstro("https://ecom2-002.web.app");
603
- const $$BaseBody = createComponent(async ($$result, $$props, $$slots) => {
604
- const Astro2 = $$result.createAstro($$Astro$e, $$props, $$slots);
605
- Astro2.self = $$BaseBody;
606
- return renderTemplate`${maybeRenderHead($$result)}<body>
607
- <div id="teleported-overlap" class="relative z-50"></div>
608
- <div id="teleported-top" class="relative z-0"></div>
609
- ${renderSlot($$result, $$slots["default"])}
610
- ${renderSlot($$result, $$slots["before-body-end"])}
611
- <div id="teleported-bottom" class="relative z-0"></div>
612
- </body>`;
613
- }, "/home/leo/code/ecomplus/cloud-commerce/packages/storefront/src/lib/layouts/BaseBody.astro");
614
-
615
- const $$Astro$d = createAstro("https://ecom2-002.web.app");
616
- const $$Base$1 = createComponent(async ($$result, $$props, $$slots) => {
617
- const Astro2 = $$result.createAstro($$Astro$d, $$props, $$slots);
618
- Astro2.self = $$Base$1;
619
- const { pageContext, title } = Astro2.props;
620
- const { cms } = pageContext;
621
- const cmsCustomCode = await cms("code");
622
- return renderTemplate`<head>
623
- ${renderComponent($$result, "BaseHead", $$BaseHead, { "pageContext": pageContext, "title": title })}
624
- ${renderComponent($$result, "BaseStateJson", $$BaseStateJson, { "pageContext": pageContext })}
625
- ${cmsCustomCode?.css && renderTemplate`<style>{cmsCustomCode.css}</style>`}
626
- ${cmsCustomCode?.html_head && renderTemplate`${renderComponent($$result, "Fragment", Fragment, {}, { "default": ($$result2) => renderTemplate`${unescapeHTML(cmsCustomCode.html_head)}` })}`}
627
- ${renderSlot($$result, $$slots["base-head-scripts"])}
628
- ${renderSlot($$result, $$slots["before-head-end"])}
629
- ${renderHead($$result)}</head>
630
- ${renderComponent($$result, "BaseBody", $$BaseBody, { "pageContext": pageContext }, { "default": ($$result2) => renderTemplate`${renderSlot($$result2, $$slots["default"])}${cmsCustomCode?.html_body && renderTemplate`${renderComponent($$result2, "Fragment", Fragment, {}, { "default": ($$result3) => renderTemplate`${unescapeHTML(cmsCustomCode.html_body)}` })}`}${renderSlot($$result2, $$slots["base-body-scripts"])}${renderSlot($$result2, $$slots["before-body-end"])}` })}`;
631
- }, "/home/leo/code/ecomplus/cloud-commerce/packages/storefront/src/lib/layouts/Base.astro");
632
-
633
- var __freeze = Object.freeze;
634
- var __defProp = Object.defineProperty;
635
- var __template = (cooked, raw) => __freeze(__defProp(cooked, "raw", { value: __freeze(raw || cooked.slice()) }));
636
- var _a;
637
- const $$Astro$c = createAstro("https://ecom2-002.web.app");
638
- const $$InlineScripts = createComponent(async ($$result, $$props, $$slots) => {
639
- const Astro2 = $$result.createAstro($$Astro$c, $$props, $$slots);
640
- Astro2.self = $$InlineScripts;
641
- return renderTemplate(_a || (_a = __template(["<script>\n window.firebaseConfig = {\n apiKey: 'AIzaSyCrVzemDgpyp9i6ni7Yc5ZuEVfXYwl-4J0',\n authDomain: 'ecom2-002.firebaseapp.com',\n projectId: 'ecom2-002',\n storageBucket: 'ecom2-002.appspot.com',\n messagingSenderId: '402807248219',\n appId: '1:402807248219:web:cf7d57759751e74776367e',\n measurementId: 'G-SC592CE0GB',\n };\n<\/script>"])));
642
- }, "/home/leo/code/ecomplus/cloud-commerce/packages/storefront/src/scripts/InlineScripts.astro");
643
-
644
- const $$Astro$b = createAstro("https://ecom2-002.web.app");
645
- const $$Base = createComponent(async ($$result, $$props, $$slots) => {
646
- const Astro2 = $$result.createAstro($$Astro$b, $$props, $$slots);
647
- Astro2.self = $$Base;
648
- const { pageContext, title } = Astro2.props;
649
- return renderTemplate`${renderComponent($$result, "Base", $$Base$1, { "pageContext": pageContext, "title": title }, { "before-head-end": ($$result2) => renderTemplate`${renderComponent($$result2, "InlineScripts", $$InlineScripts, { "slot": "before-head-end" })}`, "default": ($$result2) => renderTemplate`${renderSlot($$result2, $$slots["default"])}` })}`;
650
- }, "/home/leo/code/ecomplus/cloud-commerce/packages/storefront/src/layouts/Base.astro");
651
-
652
608
  function isRemoteImage(src) {
653
609
  return /^(https?:)?\/\//.test(src);
654
610
  }
@@ -835,9 +791,9 @@ async function getPicture(params) {
835
791
  };
836
792
  }
837
793
 
838
- const $$Astro$a = createAstro("https://ecom2-002.web.app");
794
+ const $$Astro$e = createAstro("https://ecom2-002.web.app");
839
795
  const $$Picture = createComponent(async ($$result, $$props, $$slots) => {
840
- const Astro2 = $$result.createAstro($$Astro$a, $$props, $$slots);
796
+ const Astro2 = $$result.createAstro($$Astro$e, $$props, $$slots);
841
797
  Astro2.self = $$Picture;
842
798
  const tryImageSize = (src2) => {
843
799
  let dimensions = {};
@@ -872,6 +828,7 @@ const $$Picture = createComponent(async ($$result, $$props, $$slots) => {
872
828
  formats = ["avif", "webp"],
873
829
  loading = "lazy",
874
830
  decoding = "async",
831
+ hasImg = true,
875
832
  ...attrs
876
833
  } = Astro2.props;
877
834
  let aspectRatio = propAspectRatio;
@@ -897,12 +854,71 @@ const $$Picture = createComponent(async ($$result, $$props, $$slots) => {
897
854
  delete image.src;
898
855
  delete image.width;
899
856
  delete image.height;
900
- return renderTemplate`${maybeRenderHead($$result)}<picture>
857
+ const pictureAttrs = {};
858
+ if (!hasImg) {
859
+ pictureAttrs["data-alt"] = alt;
860
+ Object.assign(pictureAttrs, attrs);
861
+ delete pictureAttrs.width;
862
+ delete pictureAttrs.height;
863
+ }
864
+ return renderTemplate`${maybeRenderHead($$result)}<picture${spreadAttributes(pictureAttrs)}>
901
865
  ${sources.map((attrs2) => renderTemplate`<source${addAttribute(attrs2.type, "type")}${addAttribute(attrs2.srcset.replace(/\s(\w+)$/, `&V=${process.env.DEPLOY_RAND} $1`), "srcset")}${addAttribute(sizes, "sizes")}>`)}
902
- <img${spreadAttributes(image)}${addAttribute(loading, "loading")}${addAttribute(decoding, "decoding")}${addAttribute(imgSrc, "src")}${spreadAttributes(attrs)}>
866
+ ${hasImg && renderTemplate`<img${spreadAttributes(image)}${addAttribute(loading, "loading")}${addAttribute(decoding, "decoding")}${addAttribute(imgSrc, "src")}${spreadAttributes(attrs)}>`}
903
867
  </picture>`;
904
868
  }, "/home/leo/code/ecomplus/cloud-commerce/packages/storefront/src/lib/components/Picture.astro");
905
869
 
870
+ const $$Astro$d = createAstro("https://ecom2-002.web.app");
871
+ const $$BaseBody = createComponent(async ($$result, $$props, $$slots) => {
872
+ const Astro2 = $$result.createAstro($$Astro$d, $$props, $$slots);
873
+ Astro2.self = $$BaseBody;
874
+ const { settings } = Astro2.props.pageContext;
875
+ return renderTemplate`${maybeRenderHead($$result)}<body>
876
+ <div id="teleported-overlap" class="relative z-50"></div>
877
+ <div id="teleported-top" class="relative z-0"></div>
878
+ ${renderSlot($$result, $$slots["default"])}
879
+ ${renderSlot($$result, $$slots["before-body-end"])}
880
+ <div id="teleported-bottom" class="relative z-0"></div>
881
+ ${settings.icon && renderTemplate`${renderComponent($$result, "Picture", $$Picture, { "src": settings.icon, "alt": "Icon", "formats": ["png"], "widths": [32, 192, 512], "sizes": "32px", "class": "hidden absolute", "style": "bottom: -1000px", "hasImg": false })}`}
882
+ </body>`;
883
+ }, "/home/leo/code/ecomplus/cloud-commerce/packages/storefront/src/lib/layouts/BaseBody.astro");
884
+
885
+ const $$Astro$c = createAstro("https://ecom2-002.web.app");
886
+ const $$Base$1 = createComponent(async ($$result, $$props, $$slots) => {
887
+ const Astro2 = $$result.createAstro($$Astro$c, $$props, $$slots);
888
+ Astro2.self = $$Base$1;
889
+ const { pageContext, title } = Astro2.props;
890
+ const { cms } = pageContext;
891
+ const cmsCustomCode = await cms("code");
892
+ return renderTemplate`<head>
893
+ ${renderComponent($$result, "BaseHead", $$BaseHead, { "pageContext": pageContext, "title": title })}
894
+ ${renderComponent($$result, "BaseStateJson", $$BaseStateJson, { "pageContext": pageContext })}
895
+ ${cmsCustomCode?.css && renderTemplate`<style>{cmsCustomCode.css}</style>`}
896
+ ${cmsCustomCode?.html_head && renderTemplate`${renderComponent($$result, "Fragment", Fragment, {}, { "default": ($$result2) => renderTemplate`${unescapeHTML(cmsCustomCode.html_head)}` })}`}
897
+ ${renderSlot($$result, $$slots["base-head-scripts"])}
898
+ ${renderSlot($$result, $$slots["before-head-end"])}
899
+ ${renderHead($$result)}</head>
900
+ ${renderComponent($$result, "BaseBody", $$BaseBody, { "pageContext": pageContext }, { "default": ($$result2) => renderTemplate`${renderSlot($$result2, $$slots["default"])}${cmsCustomCode?.html_body && renderTemplate`${renderComponent($$result2, "Fragment", Fragment, {}, { "default": ($$result3) => renderTemplate`${unescapeHTML(cmsCustomCode.html_body)}` })}`}${renderSlot($$result2, $$slots["base-body-scripts"])}${renderSlot($$result2, $$slots["before-body-end"])}` })}`;
901
+ }, "/home/leo/code/ecomplus/cloud-commerce/packages/storefront/src/lib/layouts/Base.astro");
902
+
903
+ var __freeze = Object.freeze;
904
+ var __defProp = Object.defineProperty;
905
+ var __template = (cooked, raw) => __freeze(__defProp(cooked, "raw", { value: __freeze(raw || cooked.slice()) }));
906
+ var _a;
907
+ const $$Astro$b = createAstro("https://ecom2-002.web.app");
908
+ const $$InlineScripts = createComponent(async ($$result, $$props, $$slots) => {
909
+ const Astro2 = $$result.createAstro($$Astro$b, $$props, $$slots);
910
+ Astro2.self = $$InlineScripts;
911
+ return renderTemplate(_a || (_a = __template(["<script>\n window.firebaseConfig = {\n apiKey: 'AIzaSyCrVzemDgpyp9i6ni7Yc5ZuEVfXYwl-4J0',\n authDomain: 'ecom2-002.firebaseapp.com',\n projectId: 'ecom2-002',\n storageBucket: 'ecom2-002.appspot.com',\n messagingSenderId: '402807248219',\n appId: '1:402807248219:web:cf7d57759751e74776367e',\n measurementId: 'G-SC592CE0GB',\n };\n<\/script>"])));
912
+ }, "/home/leo/code/ecomplus/cloud-commerce/packages/storefront/src/scripts/InlineScripts.astro");
913
+
914
+ const $$Astro$a = createAstro("https://ecom2-002.web.app");
915
+ const $$Base = createComponent(async ($$result, $$props, $$slots) => {
916
+ const Astro2 = $$result.createAstro($$Astro$a, $$props, $$slots);
917
+ Astro2.self = $$Base;
918
+ const { pageContext, title } = Astro2.props;
919
+ return renderTemplate`${renderComponent($$result, "Base", $$Base$1, { "pageContext": pageContext, "title": title }, { "before-head-end": ($$result2) => renderTemplate`${renderComponent($$result2, "InlineScripts", $$InlineScripts, { "slot": "before-head-end" })}`, "default": ($$result2) => renderTemplate`${renderSlot($$result2, $$slots["default"])}` })}`;
920
+ }, "/home/leo/code/ecomplus/cloud-commerce/packages/storefront/src/layouts/Base.astro");
921
+
906
922
  const checkObjNotNull = (obj) => {
907
923
  return Object.values(obj).filter((val) => val).length;
908
924
  };
@@ -14,7 +14,7 @@ import enableDestroy from 'server-destroy';
14
14
  import { defineComponent, computed, useSSRContext, mergeProps, h as h$1, createSSRApp } from 'vue';
15
15
  import { ssrRenderSlotInner, ssrRenderAttrs, ssrRenderSlot, renderToString } from 'vue/server-renderer';
16
16
  import { img, imgSizes, i18n, formatMoney } from '@ecomplus/utils';
17
- /* empty css */import { _ as _export_sfc, a as _page0, b as _page1, c as _page2, d as _page3, e as _page4, f as _page5 } from './chunks/pages/all.d97031a1.mjs';
17
+ /* empty css */import { _ as _export_sfc, a as _page0, b as _page1, c as _page2, d as _page3, e as _page4, f as _page5 } from './chunks/pages/all.090434f8.mjs';
18
18
  import 'mime';
19
19
  import 'cookie';
20
20
  import 'kleur/colors';
@@ -3062,7 +3062,7 @@ const _renderer1 = {
3062
3062
  const pageMap = new Map([["../../node_modules/.pnpm/@astrojs+image@0.16.0_astro@2.1.2+sharp@0.31.3/node_modules/@astrojs/image/dist/endpoint.js", _page0],["src/pages/index.astro", _page1],["src/pages/fallback.astro", _page2],["src/pages/app/index.astro", _page3],["src/pages/app/account.astro", _page4],["src/pages/[...slug].astro", _page5],]);
3063
3063
  const renderers = [Object.assign({"name":"astro:jsx","serverEntrypoint":"astro/jsx/server.js","jsxImportSource":"astro"}, { ssr: server_default }),Object.assign({"name":"@astrojs/vue","clientEntrypoint":"@astrojs/vue/client.js","serverEntrypoint":"@astrojs/vue/server.js"}, { ssr: _renderer1 }),];
3064
3064
 
3065
- const _manifest = Object.assign(deserializeManifest({"adapterName":"@astrojs/node","routes":[{"file":"","links":[],"scripts":[],"routeData":{"type":"endpoint","route":"/_image","pattern":"^\\/_image$","segments":[[{"content":"_image","dynamic":false,"spread":false}]],"params":[],"component":"../../node_modules/.pnpm/@astrojs+image@0.16.0_astro@2.1.2+sharp@0.31.3/node_modules/@astrojs/image/dist/endpoint.js","pathname":"/_image","prerender":false,"_meta":{"trailingSlash":"ignore"}}},{"file":"","links":["_astro/_...slug_.0607a6ef.css","_astro/index.0c833781.css"],"scripts":[{"type":"external","value":"_astro/hoisted.721ad75d.js"}],"routeData":{"route":"/","type":"page","pattern":"^\\/$","segments":[],"params":[],"component":"src/pages/index.astro","pathname":"/","prerender":false,"_meta":{"trailingSlash":"ignore"}}},{"file":"","links":["_astro/_...slug_.0607a6ef.css"],"scripts":[{"type":"external","value":"_astro/hoisted.721ad75d.js"}],"routeData":{"route":"/fallback","type":"page","pattern":"^\\/fallback\\/?$","segments":[[{"content":"fallback","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/fallback.astro","pathname":"/fallback","prerender":false,"_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"routeData":{"route":"/app","type":"page","pattern":"^\\/app\\/?$","segments":[[{"content":"app","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/app/index.astro","pathname":"/app","prerender":false,"_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"routeData":{"route":"/app/account","type":"page","pattern":"^\\/app\\/account\\/?$","segments":[[{"content":"app","dynamic":false,"spread":false}],[{"content":"account","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/app/account.astro","pathname":"/app/account","prerender":false,"_meta":{"trailingSlash":"ignore"}}},{"file":"","links":["_astro/_...slug_.0607a6ef.css"],"scripts":[{"type":"external","value":"_astro/hoisted.721ad75d.js"}],"routeData":{"route":"/[...slug]","type":"page","pattern":"^(?:\\/(.*?))?\\/?$","segments":[[{"content":"...slug","dynamic":true,"spread":true}]],"params":["...slug"],"component":"src/pages/[...slug].astro","prerender":false,"_meta":{"trailingSlash":"ignore"}}}],"site":"https://ecom2-002.web.app","base":"/","markdown":{"drafts":false,"syntaxHighlight":"shiki","shikiConfig":{"langs":[],"theme":"github-dark","wrap":false},"remarkPlugins":[],"rehypePlugins":[],"remarkRehype":{},"gfm":true,"smartypants":true},"pageMap":null,"propagation":[],"renderers":[],"entryModules":{"\u0000@astrojs-ssr-virtual-entry":"_@astrojs-ssr-virtual-entry.mjs","~/components/Prices.vue":"_astro/Prices.55399c72.js","@@sf/components/ProductCard.vue":"_astro/ProductCard.7e891c08.js","/astro/hoisted.js?q=0":"_astro/hoisted.721ad75d.js","@astrojs/vue/client.js":"_astro/client.0de2f274.js","/home/leo/code/ecomplus/cloud-commerce/node_modules/workbox-window/build/workbox-window.prod.es5.mjs":"_astro/workbox-window.prod.es5.295a6886.js","~/components/PitchBar.vue":"_astro/PitchBar.db7cd775.js","~/components/ShopHeader.vue":"_astro/ShopHeader.e93c8274.js","/home/leo/code/ecomplus/cloud-commerce/packages/storefront/src/lib/scripts/firebase-app.ts":"_astro/firebase-app.72e91a3e.js","astro:scripts/before-hydration.js":""},"assets":["/_astro/index.0c833781.css","/_astro/server.1bc2fa51.css","/_astro/_...slug_.0607a6ef.css","/manifest.webmanifest","/robots.txt","/sw.js","/workbox-e0d788d4.js","/_astro/PitchBar.db7cd775.js","/_astro/Prices.55399c72.js","/_astro/ProductCard.7e891c08.js","/_astro/ShopHeader.e93c8274.js","/_astro/_plugin-vue_export-helper.77ed7c18.js","/_astro/client.0de2f274.js","/_astro/firebase-app.72e91a3e.js","/_astro/format-money.ab6b71eb.js","/_astro/hoisted.721ad75d.js","/_astro/idle-callback.889bf0ea.js","/_astro/index.16f33784.js","/_astro/modules-info.06ac0727.js","/_astro/preload-helper.101896b7.js","/_astro/runtime-dom.esm-bundler.d2f39f33.js","/_astro/session-utm.72684b84.js","/_astro/workbox-window.prod.es5.295a6886.js","/admin/config.json","/assets/cms-preview.css","/assets/cms.css","/assets/cvv.png","/assets/img-placeholder.png","/assets/payments.png","/assets/ssl-safe.png","/img/icon.png","/img/large-icon.png","/img/uploads/banner1.png","/img/uploads/banner2.png","/img/uploads/banner2.webp","/img/uploads/favicon.png","/img/uploads/headless.png","/img/uploads/headphone.png","/img/uploads/headphone.webp","/img/uploads/icon.png","/img/uploads/large-icon.png","/img/uploads/logo.png","/img/uploads/logo.webp","/img/uploads/og-image.png","/img/uploads/passion.png","/img/uploads/passion.webp","/img/uploads/pwa-reliable.png","/img/uploads/rect8589.png","/img/uploads/rect859.png","/img/uploads/rect89.png","/img/uploads/rect89.webp","/img/uploads/ssl-safe.png"]}), {
3065
+ const _manifest = Object.assign(deserializeManifest({"adapterName":"@astrojs/node","routes":[{"file":"","links":[],"scripts":[],"routeData":{"type":"endpoint","route":"/_image","pattern":"^\\/_image$","segments":[[{"content":"_image","dynamic":false,"spread":false}]],"params":[],"component":"../../node_modules/.pnpm/@astrojs+image@0.16.0_astro@2.1.2+sharp@0.31.3/node_modules/@astrojs/image/dist/endpoint.js","pathname":"/_image","prerender":false,"_meta":{"trailingSlash":"ignore"}}},{"file":"","links":["_astro/_...slug_.0607a6ef.css","_astro/index.0c833781.css"],"scripts":[{"type":"external","value":"_astro/hoisted.721ad75d.js"}],"routeData":{"route":"/","type":"page","pattern":"^\\/$","segments":[],"params":[],"component":"src/pages/index.astro","pathname":"/","prerender":false,"_meta":{"trailingSlash":"ignore"}}},{"file":"","links":["_astro/_...slug_.0607a6ef.css"],"scripts":[{"type":"external","value":"_astro/hoisted.721ad75d.js"}],"routeData":{"route":"/fallback","type":"page","pattern":"^\\/fallback\\/?$","segments":[[{"content":"fallback","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/fallback.astro","pathname":"/fallback","prerender":false,"_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"routeData":{"route":"/app","type":"page","pattern":"^\\/app\\/?$","segments":[[{"content":"app","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/app/index.astro","pathname":"/app","prerender":false,"_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"routeData":{"route":"/app/account","type":"page","pattern":"^\\/app\\/account\\/?$","segments":[[{"content":"app","dynamic":false,"spread":false}],[{"content":"account","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/app/account.astro","pathname":"/app/account","prerender":false,"_meta":{"trailingSlash":"ignore"}}},{"file":"","links":["_astro/_...slug_.0607a6ef.css"],"scripts":[{"type":"external","value":"_astro/hoisted.721ad75d.js"}],"routeData":{"route":"/[...slug]","type":"page","pattern":"^(?:\\/(.*?))?\\/?$","segments":[[{"content":"...slug","dynamic":true,"spread":true}]],"params":["...slug"],"component":"src/pages/[...slug].astro","prerender":false,"_meta":{"trailingSlash":"ignore"}}}],"site":"https://ecom2-002.web.app","base":"/","markdown":{"drafts":false,"syntaxHighlight":"shiki","shikiConfig":{"langs":[],"theme":"github-dark","wrap":false},"remarkPlugins":[],"rehypePlugins":[],"remarkRehype":{},"gfm":true,"smartypants":true},"pageMap":null,"propagation":[],"renderers":[],"entryModules":{"\u0000@astrojs-ssr-virtual-entry":"_@astrojs-ssr-virtual-entry.mjs","@@sf/components/ProductCard.vue":"_astro/ProductCard.7e891c08.js","~/components/Prices.vue":"_astro/Prices.55399c72.js","~/components/PitchBar.vue":"_astro/PitchBar.db7cd775.js","@astrojs/vue/client.js":"_astro/client.0de2f274.js","/astro/hoisted.js?q=0":"_astro/hoisted.721ad75d.js","/home/leo/code/ecomplus/cloud-commerce/node_modules/workbox-window/build/workbox-window.prod.es5.mjs":"_astro/workbox-window.prod.es5.295a6886.js","~/components/ShopHeader.vue":"_astro/ShopHeader.e93c8274.js","/home/leo/code/ecomplus/cloud-commerce/packages/storefront/src/lib/scripts/firebase-app.ts":"_astro/firebase-app.72e91a3e.js","astro:scripts/before-hydration.js":""},"assets":["/_astro/index.0c833781.css","/_astro/server.1bc2fa51.css","/_astro/_...slug_.0607a6ef.css","/manifest.webmanifest","/robots.txt","/sw.js","/workbox-e0d788d4.js","/_astro/PitchBar.db7cd775.js","/_astro/Prices.55399c72.js","/_astro/ProductCard.7e891c08.js","/_astro/ShopHeader.e93c8274.js","/_astro/_plugin-vue_export-helper.77ed7c18.js","/_astro/client.0de2f274.js","/_astro/firebase-app.72e91a3e.js","/_astro/format-money.ab6b71eb.js","/_astro/hoisted.721ad75d.js","/_astro/idle-callback.889bf0ea.js","/_astro/index.16f33784.js","/_astro/modules-info.06ac0727.js","/_astro/preload-helper.101896b7.js","/_astro/runtime-dom.esm-bundler.d2f39f33.js","/_astro/session-utm.72684b84.js","/_astro/workbox-window.prod.es5.295a6886.js","/admin/config.json","/assets/cms-preview.css","/assets/cms.css","/assets/cvv.png","/assets/img-placeholder.png","/assets/payments.png","/assets/ssl-safe.png","/img/icon.png","/img/large-icon.png","/img/uploads/banner1.png","/img/uploads/banner2.png","/img/uploads/banner2.webp","/img/uploads/favicon.png","/img/uploads/headless.png","/img/uploads/headphone.png","/img/uploads/headphone.webp","/img/uploads/icon.png","/img/uploads/large-icon.png","/img/uploads/logo.png","/img/uploads/logo.webp","/img/uploads/og-image.png","/img/uploads/passion.png","/img/uploads/passion.webp","/img/uploads/pwa-reliable.png","/img/uploads/rect8589.png","/img/uploads/rect859.png","/img/uploads/rect89.png","/img/uploads/rect89.webp","/img/uploads/ssl-safe.png"]}), {
3066
3066
  pageMap: pageMap,
3067
3067
  renderers: renderers
3068
3068
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/storefront",
3
3
  "type": "module",
4
- "version": "0.8.2",
4
+ "version": "0.8.4",
5
5
  "description": "E-Com Plus Cloud Commerce storefront with Astro",
6
6
  "bin": {
7
7
  "storefront": "./scripts/build-prod.sh"
@@ -3,11 +3,11 @@
3
3
  BUILD_OUTPUT=static BUILD_OUT_DIR=./.cloudcommerce/sf-tmp-dist npx astro build
4
4
  DEPLOY_RUNTIME=serverless npx astro build
5
5
 
6
- mv ./.cloudcommerce/sf-tmp-dist/_astro/*.{png,jpg,jpeg,webp,avif,svg} ./dist/client/_astro/
6
+ mv ./.cloudcommerce/sf-tmp-dist/_astro/*.{png,jpg,jpeg,webp,avif,svg} ./dist/client/_astro/ 2>/dev/null
7
7
  rm -rf ./.cloudcommerce/sf-tmp-dist
8
8
 
9
9
  identify -format "%f,%w,%h\n" \
10
- ./dist/client/_astro/*.{png,jpg,jpeg,webp,avif,svg} > ./dist/server/images.dist.csv
10
+ ./dist/client/_astro/*.{png,jpg,jpeg,webp,avif,svg} > ./dist/server/images.dist.csv 2>/dev/null
11
11
 
12
12
  identify -format "assets/%f,%w,%h\n" \
13
13
  ./public/assets/*.{png,jpg,jpeg,webp,avif,svg} > ./dist/server/images.src.csv 2>/dev/null
@@ -7,6 +7,7 @@ import { getPicture } from '@astrojs/image';
7
7
  export type Props = Omit<PictureComponentRemoteImageProps, 'aspectRatio'> & {
8
8
  aspectRatio?: PictureComponentRemoteImageProps['aspectRatio'],
9
9
  fetchpriority?: 'high' | 'low' | 'auto',
10
+ hasImg?: boolean,
10
11
  };
11
12
 
12
13
  const tryImageSize = (src: string) => {
@@ -44,6 +45,7 @@ const {
44
45
  formats = ['avif', 'webp'],
45
46
  loading = 'lazy',
46
47
  decoding = 'async',
48
+ hasImg = true,
47
49
  ...attrs
48
50
  } = Astro.props;
49
51
 
@@ -71,19 +73,29 @@ const imgSrc = `${image.src}&V=${process.env.DEPLOY_RAND}`;
71
73
  delete image.src;
72
74
  delete image.width;
73
75
  delete image.height;
76
+
77
+ const pictureAttrs: Partial<typeof attrs & { alt: string }> = {};
78
+ if (!hasImg) {
79
+ pictureAttrs['data-alt'] = alt;
80
+ Object.assign(pictureAttrs, attrs);
81
+ delete pictureAttrs.width;
82
+ delete pictureAttrs.height;
83
+ }
74
84
  ---
75
85
 
76
- <picture>
86
+ <picture {...pictureAttrs}>
77
87
  {sources.map((attrs) => <source
78
88
  type={attrs.type}
79
89
  srcset={attrs.srcset.replace(/\s(\w+)$/, `&V=${process.env.DEPLOY_RAND} $1`)}
80
90
  sizes={sizes}
81
91
  />)}
82
- <img
83
- {...image}
84
- loading={loading}
85
- decoding={decoding}
86
- src={imgSrc}
87
- {...attrs}
88
- />
92
+ {hasImg &&
93
+ <img
94
+ {...image}
95
+ loading={loading}
96
+ decoding={decoding}
97
+ src={imgSrc}
98
+ {...attrs}
99
+ />
100
+ }
89
101
  </picture>
@@ -5,10 +5,13 @@ import '@@sf/assets/base.css';
5
5
  import '@@sf/assets/forms.css';
6
6
  import '@@sf/assets/tooltip.css';
7
7
  import 'uno.css';
8
+ import Picture from '@@sf/components/Picture.astro';
8
9
 
9
10
  export interface Props {
10
11
  pageContext: PageContext;
11
12
  }
13
+
14
+ const { settings } = Astro.props.pageContext;
12
15
  ---
13
16
 
14
17
  <body>
@@ -17,4 +20,16 @@ export interface Props {
17
20
  <slot />
18
21
  <slot name="before-body-end" />
19
22
  <div id="teleported-bottom" class="relative z-0"></div>
23
+ {settings.icon &&
24
+ <Picture
25
+ src={settings.icon}
26
+ alt="Icon"
27
+ formats={['png']}
28
+ widths={[32, 192, 512]}
29
+ sizes="32px"
30
+ class="hidden absolute"
31
+ style="bottom: -1000px"
32
+ hasImg={false}
33
+ />
34
+ }
20
35
  </body>
@@ -8,6 +8,12 @@ export interface Props {
8
8
  title?: string;
9
9
  }
10
10
 
11
+ const deployRand = process.env.DEPLOY_RAND || '_';
12
+ const getIconUrl = (size: number) => {
13
+ return `/_image?f=png&w=${size}&h=${size}`
14
+ + `&href=${encodeURIComponent(settings.icon)}&V=${deployRand}`;
15
+ };
16
+
11
17
  const {
12
18
  storeId,
13
19
  cmsContent,
@@ -18,13 +24,12 @@ const {
18
24
  settings,
19
25
  cms,
20
26
  } = Astro.props.pageContext;
27
+
21
28
  const state = apiDoc || cmsContent || {};
22
29
  const title = state.meta_title || state.name || state.title || Astro.props.title || settings.name;
23
30
  const description = state.meta_description || state.short_description || settings.description;
24
- const favicon = settings.icon
25
- ? '/_image?f=png&w=32&h=32&format=png'
26
- + `&href=${encodeURIComponent(settings.icon)}&V=${import.meta.env.DEPLOY_RAND}`
27
- : '/favicon.ico';
31
+ const favicon = settings.icon ? getIconUrl(32) : '/favicon.ico';
32
+ const shortcutIcon = settings.icon ? getIconUrl(192) : null;
28
33
  const canonicalUrl = new URL(Astro.url.pathname, Astro.site || `https://${domain}`);
29
34
  const cmsMetatags = await cms('metatags');
30
35
  const ogLocale = lang.length === 2 ? lang : lang.substring(0, 2) + lang.slice(3).toUpperCase();
@@ -46,13 +51,15 @@ if (!ogImage) {
46
51
  <meta charset="UTF-8">
47
52
  <meta name="viewport" content="width=device-width">
48
53
  <meta name="theme-color" content={primaryColor}>
49
- <link rel="icon" href={favicon} />
54
+ <link rel="icon" type="image/png" href={favicon} sizes="32x32" />
55
+ {shortcutIcon &&
56
+ <link rel="icon" type="image/png" href={shortcutIcon} sizes="192x192" />}
50
57
  <title>{title}</title>
51
58
  <meta name="description" content={description}>
52
59
  <meta name="author" content={settings.name}>
53
60
  <meta name="generator" content={Astro.generator} />
54
61
  <link rel="canonical" href={canonicalUrl} />
55
- <link rel="apple-touch-icon" href={settings.icon} />
62
+ {shortcutIcon && <link rel="apple-touch-icon" href={shortcutIcon} />}
56
63
  <meta name="apple-mobile-web-app-capable" content="yes">
57
64
  <meta name="apple-mobile-web-app-status-bar-style" content="default">
58
65
  <meta property="og:site_name" content={settings.name}>
@@ -62,7 +69,8 @@ if (!ogImage) {
62
69
  <meta property="og:type" content="website">
63
70
  <meta property="og:locale" content={ogLocale}>
64
71
  {ogImage && <meta property="og:image" content={ogImage} />}
65
- {cmsMetatags?.fb_app_id && <meta property="fb:app_id" content={cmsMetatags.fb_app_id} />}
72
+ {cmsMetatags?.fb_app_id &&
73
+ <meta property="fb:app_id" content={cmsMetatags.fb_app_id} />}
66
74
  <meta name="twitter:card" content="summary">
67
75
  {cmsMetatags?.twitter_username &&
68
76
  <meta name="twitter:site" content={cmsMetatags.twitter_username} />}
@@ -7,11 +7,14 @@ import { getPicture } from './get-picture';
7
7
  export type Props = Omit<PictureComponentRemoteImageProps, 'aspectRatio'> & {
8
8
  aspectRatio?: PictureComponentRemoteImageProps['aspectRatio'],
9
9
  fetchpriority?: 'high' | 'low' | 'auto',
10
+ hasImg?: boolean,
10
11
  };
11
12
 
13
+ const { STOREFRONT_BASE_DIR } = process.env;
14
+ const baseDir = STOREFRONT_BASE_DIR || process.cwd();
12
15
  type OriginalImage = { filepath: string, width: number, height: number };
13
16
  const originalImages: OriginalImage[] = [];
14
- const manifestFilepath = joinPath(process.cwd(), 'dist/server/images.src.csv');
17
+ const manifestFilepath = joinPath(baseDir, 'dist/server/images.src.csv');
15
18
  readFileSync(manifestFilepath, 'utf-8').split(/\n/).forEach((line) => {
16
19
  const [filepath, width, height] = line.split(',');
17
20
  originalImages.push({
@@ -57,6 +60,7 @@ const {
57
60
  formats = ['avif', 'webp'],
58
61
  loading = 'lazy',
59
62
  decoding = 'async',
63
+ hasImg = true,
60
64
  ...attrs
61
65
  } = Astro.props;
62
66
 
@@ -82,9 +86,17 @@ const { image, sources } = await getPicture({
82
86
  });
83
87
  delete image.width;
84
88
  delete image.height;
89
+
90
+ const pictureAttrs: Partial<typeof attrs & { alt: string }> = {};
91
+ if (!hasImg) {
92
+ pictureAttrs['data-alt'] = alt;
93
+ Object.assign(pictureAttrs, attrs);
94
+ delete pictureAttrs.width;
95
+ delete pictureAttrs.height;
96
+ }
85
97
  ---
86
98
 
87
- <picture>
99
+ <picture {...pictureAttrs}>
88
100
  {sources.map((attrs) => <source {...attrs} sizes={sizes} />)}
89
- <img {...image} loading={loading} decoding={decoding} {...attrs} />
101
+ {hasImg && <img {...image} loading={loading} decoding={decoding} {...attrs} />}
90
102
  </picture>
@@ -2,9 +2,11 @@ import type { OutputFormat } from '@astrojs/image/dist/loaders/';
2
2
  import { join as joinPath } from 'node:path';
3
3
  import { readFileSync } from 'node:fs';
4
4
 
5
+ const { STOREFRONT_BASE_DIR } = process.env;
6
+ const baseDir = STOREFRONT_BASE_DIR || process.cwd();
5
7
  type BuiltImage = { filename: string, width: number, height: number };
6
8
  const builtImages: BuiltImage[] = [];
7
- const manifestFilepath = joinPath(process.cwd(), 'dist/server/images.dist.csv');
9
+ const manifestFilepath = joinPath(baseDir, 'dist/server/images.dist.csv');
8
10
  readFileSync(manifestFilepath, 'utf-8').split(/\n/).forEach((line) => {
9
11
  const [filename, width, height] = line.split(',');
10
12
  builtImages.push({
@@ -25,9 +27,9 @@ type ImageOptions = Record<string, any> & {
25
27
  };
26
28
  const getImage = async ({ src, width, format }: ImageOptions) => {
27
29
  const filename = src.replace(/^.*\//, '').replace(/.\w+(\?.*)?$/, '');
30
+ const filenameRegExp = new RegExp(`[_.][a-z0-9]+\\.${format}$`, 'i');
28
31
  const matchFilename = (_builtImage: BuiltImage) => {
29
- return filename === _builtImage.filename
30
- .replace(new RegExp(`[_.][a-z0-9]+\\.${format}$`, 'i'), '');
32
+ return filename === _builtImage.filename.replace(filenameRegExp, '');
31
33
  };
32
34
  let builtImage = builtImages.find((_builtImage) => {
33
35
  return _builtImage.width >= width && matchFilename(_builtImage);
@@ -35,11 +37,15 @@ const getImage = async ({ src, width, format }: ImageOptions) => {
35
37
  if (!builtImage) {
36
38
  builtImage = builtImages.find(matchFilename);
37
39
  }
38
- return {
39
- src: `/_astro/${builtImage.filename}`,
40
- width: builtImage.width,
41
- height: builtImage.height,
42
- };
40
+ if (builtImage) {
41
+ return {
42
+ src: `/_astro/${builtImage.filename}`,
43
+ width: builtImage.width,
44
+ height: builtImage.height,
45
+ };
46
+ }
47
+ console.warn(`Could not match built ${format} image for ${src} ${width}px`);
48
+ return { src, width };
43
49
  };
44
50
 
45
51
  export default getImage;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/types",
3
3
  "type": "module",
4
- "version": "0.8.2",
4
+ "version": "0.8.4",
5
5
  "description": "E-Com Plus Cloud Commerce reusable type definitions",
6
6
  "main": "index.ts",
7
7
  "repository": {