1

I'm attempting to transpile Salesforce Commerce Cloud's .ds files to JavaScript so we can apply standard testing tools (Jest, Mocha, etc.). The SFCC docs indicate that .ds files are "Rhino JavaScript", with a non-standard extension for Flow-like type checking.

So far, stripping out the type annotations has been simple, using the transform-flow-strip-types plugin. But SFCC supports a deprecated "for each...in" statement from JavaScript 1.6 that Babel is choking on.

All code below is available on github.

Here's my source src/index.ds file:

function dump(a: Array) {
    for each (var x in a) {
        console.log(x);
    }
}
module.exports = dump;

And my gulfile.js:

const gulp = require('gulp');
const babel = require('gulp-babel');

gulp.task('test', function () {
    gulp.src('src/**/*.ds')
        .pipe(babel())
        .pipe(gulp.dest('dst'));
});

And this is my package.json:

{
  "name": "dspoc",
  "version": "1.0.0",
  "description": "poc",
  "main": "index.ds",
  "author": "cjr",
  "license": "ISC",
  "devDependencies": {
    "babel": "^6.23.0",
    "babel-core": "^6.26.3",
    "babel-plugin-transform-flow-strip-types": "^6.22.0",
    "gulp": "^3.9.1",
    "gulp-babel": "^7.0.1"
  },
  "babel": {
    "plugins": [
      "transform-flow-strip-types"
    ]
  }
}

When I run gulp test, I get this:

%> gulp test
[11:23:06] Using gulpfile ~/dev/dspoc/gulpfile.js
[11:23:06] Starting 'test'...
[11:23:06] Finished 'test' after 9.15 ms

events.js:163
      throw er; // Unhandled 'error' event
      ^
SyntaxError: /Users/craser/dev/dspoc/src/index.ds: Unexpected token, expected ( (2:5)
  1 | function dump(a: Array) {
> 2 |   for each (var x in a) {
    |       ^
  3 |       console.log(x);
  4 |   }
  5 | }
    at Parser.pp$5.raise (/Users/craser/dev/dspoc/node_modules/babylon/lib/index.js:4454:13)
    at Parser.pp.unexpected (/Users/craser/dev/dspoc/node_modules/babylon/lib/index.js:1761:8)
    at Parser.pp.expect (/Users/craser/dev/dspoc/node_modules/babylon/lib/index.js:1749:33)
    at Parser.pp$1.parseForStatement (/Users/craser/dev/dspoc/node_modules/babylon/lib/index.js:2008:8)
    at Parser.pp$1.parseStatement (/Users/craser/dev/dspoc/node_modules/babylon/lib/index.js:1836:19)
    at Parser.parseStatement (/Users/craser/dev/dspoc/node_modules/babylon/lib/index.js:5910:22)
    at Parser.pp$1.parseBlockBody (/Users/craser/dev/dspoc/node_modules/babylon/lib/index.js:2268:21)
    at Parser.pp$1.parseBlock (/Users/craser/dev/dspoc/node_modules/babylon/lib/index.js:2247:8)
    at Parser.pp$3.parseFunctionBody (/Users/craser/dev/dspoc/node_modules/babylon/lib/index.js:4235:22)
    at Parser.parseFunctionBody (/Users/craser/dev/dspoc/node_modules/babylon/lib/index.js:5897:20)

I've spent quite a bit of time digging for a plugin that will let Babel transpile this to something like the for...of statement, but I can't seem to find anything.

I'm now at the precipice of digging into the for-of transform was built and creating something similar to transform for each...in, but I really don't want to have to put that work in if I can avoid it.

I feel like I'm missing something obvious here. Anyone know how this can be done?

DeathB4Decaf
  • 390
  • 1
  • 10

1 Answers1

2

for each...in was never an official part of the spec and didn't exist by the time Babel came around, so it is not supported by Babel. I'm afraid you've have to update all usage of that syntax before Babel will be able to process it.

loganfsmyth
  • 156,129
  • 30
  • 331
  • 251
  • Unfortunately, updating the source is a non-starter for this project. (At least for the moment.) Looks like I'll either hack together my own pre-processor, or write a transform for Babel to deal with this. – DeathB4Decaf May 25 '18 at 21:28
  • Babel doesn't support custom parsing, just custom transformations, so you'd have to make your own fork of the parser with support for it, FYI. – loganfsmyth May 25 '18 at 22:13
  • When we wanted to apply Mocha/Istanbul to SFCC we opted to use standard JavaScript instead of ds. It's fairly easy to get rid of the type annotations with a regex. Maybe you can try the same for the for..each statement. Depends also on how legacy your code base is and how comfortable you feel doing this big change. You can also perhaps exclude the problematic files from your babel configuration and just apply babel/mocha/jest to the files that don't contain for-each to begin with. Again depends on how well structured your code is. – Nikolaos Georgiou May 26 '18 at 05:01