awslabs / aws-mobile-appsync-sdk-js

JavaScript library files for Offline, Sync, Sigv4. includes support for React Native
Apache License 2.0
919 stars 266 forks source link

`replaceUsingMap` mutates objects in objects with three levels of nesting #665

Open david-gettins opened 3 years ago

david-gettins commented 3 years ago

Note: If your issue/feature-request/question is regarding the AWS AppSync service, please log it in the official AWS AppSync forum

Do you want to request a feature or report a bug?

Bug

What is the current behavior?

When using React Native, when I have a query that has three nested levels of objects, in debug mode, when enqueued mutations are being committed, I get an error about mutating a frozen object.

After investigation I found it is happening in the replaceUsingMap function. This is the only place in the offline-link.js file that mutates objects, everywhere else in this file Object.assign (or polyfill function) is used. You can find the offending line in offline-link.js:441.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem.

  1. Create a GQL query that has three levels of nested objects,
  2. Go offline and perform a mutaiton on that object or a subset of that object,
  3. Go online,
  4. Wait for enqueued mutations to fire,
  5. See error or crash.

What is the expected behavior?

The replaceUsingMap does not mutate objects when they are nested more than two levels deep.

Which versions and which environment (browser, react-native, nodejs) / OS are affected by this issue? Did this work in previous versions?

I don't know if this occurred in earlier versions.

david-gettins commented 3 years ago

Is this because I am doing something wrong or is it an oversight by this lib's authors?

david-gettins commented 3 years ago

This fixes the error:

diff --git a/node_modules/aws-appsync/lib/link/offline-link.js b/node_modules/aws-appsync/lib/link/offline-link.js
index d22c09b..084712b 100644
--- a/node_modules/aws-appsync/lib/link/offline-link.js
+++ b/node_modules/aws-appsync/lib/link/offline-link.js
@@ -438,7 +438,7 @@ exports.replaceUsingMap = function (obj, map) {
                 obj[key] = val.map(function (v, i) { return exports.replaceUsingMap(v, map); });
             }
             else if (typeof val === 'object') {
-                obj[key] = exports.replaceUsingMap(val, map);
+                obj = __assign(__assign({}, obj), {[key]: exports.replaceUsingMap(val, map)});
             }
             else {
                 var newVal_1 = map[val];