Repository: FormidableLabs/urql
Pull request #2074 (2021-11-10 15:09:23)

(core) - Fix maskTypename not handling nested arrays
resolves https://github.com/FormidableLabs/urql/issues/2072

## Summary

`maskTypename` wasn't taking array shapes in account when traversing the result shape

## Set of changes

- add `isArray` argument to `maskTypename` so the recursion can hold on to array shapes


changeset-bot[bot]: ###  🦋  Changeset detected

Latest commit: 438420ac7f665e7b455e08bd0e1b67cc297c0f11

**The changes in this PR will be included in the next version bump.**

<details><summary>This PR includes changesets to release 1 package</summary>

  | Name       | Type  |
| ---------- | ----- |
| @urql/core | Patch |

</details>

Not sure what this means? [Click here  to learn what changesets are](https://github.com/changesets/changesets/blob/master/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add another changeset to this PR](https://github.com/FormidableLabs/urql/new/doc-cache-bug?filename=.changeset/happy-llamas-sin.md&value=---%0A%22%40urql%2Fcore%22%3A%20patch%0A---%0A%0ADoc%20cache%20bug%0A)



Patch:
diff --git a/.changeset/metal-monkeys-knock.md b/.changeset/metal-monkeys-knock.md
new file mode 100644
index 00000000..4ea2e25e
--- /dev/null
+++ b/.changeset/metal-monkeys-knock.md
@@ -0,0 +1,5 @@
+---
+'@urql/core': patch
+---
+
+Fix issue where `maskTypename` would ignore array shapes
diff --git a/packages/core/src/utils/maskTypename.ts b/packages/core/src/utils/maskTypename.ts
index 24401773..3297335e 100644
--- a/packages/core/src/utils/maskTypename.ts
+++ b/packages/core/src/utils/maskTypename.ts
@@ -1,21 +1,24 @@
 export const maskTypename = (data: any): any => {
   if (!data || typeof data !== 'object') return data;
 
-  return Object.keys(data).reduce((acc, key: string) => {
-    const value = data[key];
-    if (key === '__typename') {
-      Object.defineProperty(acc, '__typename', {
-        enumerable: false,
-        value,
-      });
-    } else if (Array.isArray(value)) {
-      acc[key] = value.map(maskTypename);
-    } else if (value && typeof value === 'object' && '__typename' in value) {
-      acc[key] = maskTypename(value);
-    } else {
-      acc[key] = value;
-    }
+  return Object.keys(data).reduce(
+    (acc, key: string) => {
+      const value = data[key];
+      if (key === '__typename') {
+        Object.defineProperty(acc, '__typename', {
+          enumerable: false,
+          value,
+        });
+      } else if (Array.isArray(value)) {
+        acc[key] = value.map(maskTypename);
+      } else if (value && typeof value === 'object' && '__typename' in value) {
+        acc[key] = maskTypename(value);
+      } else {
+        acc[key] = value;
+      }
 
-    return acc;
-  }, {});
+      return acc;
+    },
+    Array.isArray(data) ? [] : {}
+  );
 };


Test patch:
diff --git a/packages/core/src/utils/maskTypename.test.ts b/packages/core/src/utils/maskTypename.test.ts
index 3b57737c..e90a3f73 100644
--- a/packages/core/src/utils/maskTypename.test.ts
+++ b/packages/core/src/utils/maskTypename.test.ts
@@ -25,6 +25,20 @@ it('strips typename from nested objects', () => {
   ).toEqual({ id: 1, author: { id: 2 } });
 });
 
+it('works with nested arrays', () => {
+  expect(
+    maskTypename({
+      __typename: 'Todo',
+      id: 1,
+      nodes: [[4, 5]],
+      author: {
+        id: 2,
+        __typename: 'Author',
+      },
+    })
+  ).toEqual({ id: 1, nodes: [[4, 5]], author: { id: 2 } });
+});
+
 it('strips typename from nested objects with arrays', () => {
   expect(
     maskTypename({