apiaryio / Paw-APIBlueprintImporter

Paw extension to import API Blueprint
https://paw.cloud/extensions/APIBlueprintImporter
MIT License
8 stars 6 forks source link

Don't use the `const item of items` syntax as it fails on macOS 10.10 #27

Closed JonathanMontane closed 5 years ago

JonathanMontane commented 7 years ago

Setup details

Issue

The importer fails with the following error

TypeError: [object Object] is not iterable! 

Reason

The javascriptCore library version is generally bound to the OS version it is run in. The Yosemite version of javascriptCore is a bastard version of early es5 which causes many issues with the Babel transpiler (for instance, promises are incorrectly implemented, and resolving before attaching a then function will fail to call the function). One of the main issue with this version of javascriptCore is that objects are not considered as iterable and the for (const x of y) {...} syntax is not transpiled into code that works for macOS Yosemite.

Suggested fix

Replace every instance of

for (const x of y) { ... }

by

for (const key in y) {
  if (y.hasOwnProperty(key)) {
    const x = y[key]
    ...
  }
}
kylef commented 7 years ago

We're using webpack to transpile the ES6 into ES5. There are no for (const in the shipped bundle:

$ npm run build
$ grep 'for (const' build/io.apiary.PawExtensions.APIBlueprintImporter/APIBlueprintImporter.js

How did you install the module?

JonathanMontane commented 7 years ago

@kylef The culprit here is how babel replaces const x of y in es5 code. This bundle was installed directly from https://paw.cloud/extensions/APIBlueprintImporter

The function responsible for this error is a Babel internal:

/***/ }),
/* 74 */
/***/ (function(module, exports, __webpack_require__) {

var anObject = __webpack_require__(9)
  , get      = __webpack_require__(73);
module.exports = __webpack_require__(10).getIterator = function(it){
  var iterFn = get(it);
  if(typeof iterFn != 'function')throw TypeError(it + ' is not iterable!');
  return anObject(iterFn.call(it));
};

which is called by function number 49, which is called by function number 23, which is called as _getIterator2 in the following bit of code:

var _getIterator2 = __webpack_require__(23);
var _getIterator3 = _interopRequireDefault(_getIterator2);

which is the shim that is used by babel for the syntax const x of y.

JonathanMontane commented 7 years ago

(Sorry for the nearly useless edge case)

kylef commented 7 years ago

Ah, I was under the impression that babel-plugin-transform-es2015-for-of would've made this compatible with ES5. I'll see what we can do.

JonathanMontane commented 7 years ago

@kylef I thought so too, but apparently, javascriptCore is pretty fickle on Yosemite. We had a similar issue a while ago for the SwaggerImporter.

I can write the PR, if you want. It's not super complex to fix.