@decocms/apps-commerce 7.72.0 → 8.1.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decocms/apps-commerce",
3
- "version": "7.72.0",
3
+ "version": "8.1.0-next.0",
4
4
  "type": "module",
5
5
  "description": "Deco commerce apps: shared types, app-registry, and portable commerce utilities",
6
6
  "repository": {
@@ -26,7 +26,7 @@
26
26
  "lint:unused": "knip"
27
27
  },
28
28
  "dependencies": {
29
- "@decocms/blocks": "7.72.0"
29
+ "@decocms/blocks": "8.1.0-next.0"
30
30
  },
31
31
  "peerDependencies": {
32
32
  "react": "^19.0.0",
@@ -9,18 +9,18 @@
9
9
  * does NOT prove the fetch is actually reached at runtime — for VTEX/Shopify/
10
10
  * Magento that still depends on the *site* calling `setXFetch(createXFetch())`
11
11
  * at boot (they fall back to an uninstrumented `globalThis.fetch` otherwise).
12
- * Only Salesforce is auto-wired via `createHttpClient`'s default fetcher. So
13
- * this catches "a provider shipped with no instrumented fetch at all"; it does
14
- * not catch "a site forgot to wire it".
12
+ * So this catches "a provider shipped with no instrumented fetch at all"; it
13
+ * does not catch "a site forgot to wire it".
15
14
  *
16
15
  * This test reads sibling package source from disk (it does NOT import app
17
16
  * modules) so it stays within the one-way dependency graph. If you add a new
18
17
  * commerce provider, add it to REQUIRED below and give it a
19
18
  * `src/utils/instrumentedFetch.ts` that wires the two symbols.
20
19
  *
21
- * Known exception: `apps-algolia` uses the `algoliasearch` SDK, which owns its
22
- * own transport + cache, so it has no framework-instrumented fetch and is not
23
- * listed here.
20
+ * Thin clients (/next/upstream-clients) are checked separately below: each
21
+ * client module must build its requests on `createInstrumentedFetch` from
22
+ * `@decocms/blocks/fetch`, which measures every request itself, and must not
23
+ * call `fetch` in any form. A new thin client goes in V8_CLIENTS.
24
24
  */
25
25
  import { existsSync, readFileSync } from "node:fs";
26
26
  import { dirname, join } from "node:path";
@@ -42,7 +42,7 @@ function findRepoRoot(): string {
42
42
  const repoRoot = findRepoRoot();
43
43
 
44
44
  /** Commerce apps whose upstream egress must be instrumented. */
45
- const REQUIRED = ["apps-vtex", "apps-shopify", "apps-magento", "apps-salesforce"] as const;
45
+ const REQUIRED = ["apps-vtex", "apps-shopify", "apps-magento"] as const;
46
46
 
47
47
  describe("commerce apps instrumentation guardrail", () => {
48
48
  for (const app of REQUIRED) {
@@ -62,3 +62,37 @@ describe("commerce apps instrumentation guardrail", () => {
62
62
  });
63
63
  }
64
64
  });
65
+
66
+ /**
67
+ * v8 thin clients (/next/upstream-clients): each client module creates its
68
+ * requests with `createInstrumentedFetch` from `@decocms/blocks/fetch` under
69
+ * its own provider name, and never calls a fetch around it. Unlike the v7
70
+ * factories above, nothing has to be wired at boot: the instrumented fetch is
71
+ * the only way the client reaches the network. Each client's own tests assert
72
+ * the operation labels.
73
+ */
74
+ const V8_CLIENTS: Record<string, { file: string; provider: string }> = {
75
+ "apps-shopify": { file: "src/v8/client.ts", provider: "shopify" },
76
+ "apps-vtex": { file: "src/vtexClient.ts", provider: "vtex" },
77
+ "apps-wake": { file: "src/wakeClient.ts", provider: "wake" },
78
+ "apps-magento": { file: "src/magentoClient.ts", provider: "magento" },
79
+ "apps-algolia": { file: "src/index.ts", provider: "algolia" },
80
+ "apps-resend": { file: "src/emails.ts", provider: "resend" },
81
+ "apps-sfmc-personalization": { file: "src/index.ts", provider: "sfmc-personalization" },
82
+ };
83
+
84
+ describe("v8 upstream clients use the instrumented fetch", () => {
85
+ for (const [app, { file, provider }] of Object.entries(V8_CLIENTS)) {
86
+ it(`${app} sends every request through createInstrumentedFetch as "${provider}"`, () => {
87
+ const src = readFileSync(join(repoRoot, "packages", app, file), "utf8");
88
+ const code = src.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/[^\n]*/g, "");
89
+ expect(src).toMatch(
90
+ /import\s*\{[^}]*\bcreateInstrumentedFetch\b[^}]*\}\s*from\s*"@decocms\/blocks\/fetch"/,
91
+ );
92
+ expect(src).toMatch(
93
+ new RegExp(`createInstrumentedFetch\\(\\s*\\{[^}]*\\bprovider:\\s*"${provider}"`),
94
+ );
95
+ expect(code, `${app} must not call fetch directly`).not.toMatch(/\bfetch\s*\(/);
96
+ });
97
+ }
98
+ });