@decocms/blocks 7.21.1 → 7.22.1
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 +1 -1
- package/src/cms/resolve.test.ts +31 -0
- package/src/cms/resolve.ts +14 -1
package/package.json
CHANGED
package/src/cms/resolve.test.ts
CHANGED
|
@@ -308,6 +308,37 @@ describe("commerce loader auto-injects URL search params as props", () => {
|
|
|
308
308
|
warnSpy.mockRestore();
|
|
309
309
|
}
|
|
310
310
|
});
|
|
311
|
+
|
|
312
|
+
it("never auto-injects `page` — loaders that read __pageUrl apply their own index-base conversion (#391)", async () => {
|
|
313
|
+
const calls: Array<Record<string, unknown>> = [];
|
|
314
|
+
registerCommerceLoader(KEY, async (props: Record<string, unknown>) => {
|
|
315
|
+
calls.push({ ...props });
|
|
316
|
+
return null;
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
await resolveValue({ __resolveType: KEY }, undefined, {
|
|
320
|
+
url: "https://store.com/?page=3",
|
|
321
|
+
path: "/",
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
expect(calls[0]?.page).toBeUndefined();
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
it("coerces `count`/`pageOffset` to numbers instead of injecting raw strings", async () => {
|
|
328
|
+
const calls: Array<Record<string, unknown>> = [];
|
|
329
|
+
registerCommerceLoader(KEY, async (props: Record<string, unknown>) => {
|
|
330
|
+
calls.push({ ...props });
|
|
331
|
+
return null;
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
await resolveValue({ __resolveType: KEY }, undefined, {
|
|
335
|
+
url: "https://store.com/?count=24&pageOffset=2",
|
|
336
|
+
path: "/",
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
expect(calls[0]?.count).toBe(24);
|
|
340
|
+
expect(calls[0]?.pageOffset).toBe(2);
|
|
341
|
+
});
|
|
311
342
|
});
|
|
312
343
|
|
|
313
344
|
describe("commerce loader resolves legacy .ts-suffixed resolveType", () => {
|
package/src/cms/resolve.ts
CHANGED
|
@@ -880,7 +880,20 @@ async function internalResolve(value: unknown, rctx: ResolveContext): Promise<un
|
|
|
880
880
|
if (URL.canParse(rctx.matcherCtx.url)) {
|
|
881
881
|
const url = new URL(rctx.matcherCtx.url);
|
|
882
882
|
for (const [k, v] of url.searchParams.entries()) {
|
|
883
|
-
if (resolvedProps[k]
|
|
883
|
+
if (resolvedProps[k] !== undefined) continue;
|
|
884
|
+
// `page` is skipped on purpose (#391): loaders that read `page`
|
|
885
|
+
// from `__pageUrl` themselves (e.g. VTEX's PLP loader) apply their
|
|
886
|
+
// own 1-indexed-URL -> 0-indexed-internal conversion. Auto-injecting
|
|
887
|
+
// the raw 1-indexed URL string here as `props.page` bypasses that
|
|
888
|
+
// conversion and produces an off-by-one, on top of arriving as an
|
|
889
|
+
// un-coerced string. Numeric conventional names get coerced so a
|
|
890
|
+
// loader declaring `count?: number` doesn't receive a raw string.
|
|
891
|
+
if (k === "page") continue;
|
|
892
|
+
if ((k === "count" || k === "pageOffset") && Number.isFinite(Number(v))) {
|
|
893
|
+
resolvedProps[k] = Number(v);
|
|
894
|
+
continue;
|
|
895
|
+
}
|
|
896
|
+
resolvedProps[k] = v;
|
|
884
897
|
}
|
|
885
898
|
} else {
|
|
886
899
|
// Loud warning instead of silent swallow: matcherCtx.url should
|