henrikrudstrom/oce-wrap

View on GitHub
src/render.js

Summary

Maintainability
A
0 mins
Test Coverage
const arrify = require('arrify');
const fs = require('fs');
const path = require('path');
const mkdirp = require('mkdirp');


require('./settings.js').initialize();

const features = require('./features.js');
features.load();
const conf = require('./conf.js');


function Parts(name) {
  this.name = name;
  this.parts = {};
}
// data structure to store and retrieve rendered fragments
// parts are object containing a `name` and `src`, the `src`
// of parts with the same name are pushed to the same list.
// parts with an extension name are written similarly named
// file.
Parts.prototype = {
  add(parts) {
    parts = arrify(parts);
    parts.forEach((part) => {
      if (!this.parts.hasOwnProperty(part.name))
        this.parts[part.name] = [];
      this.parts[part.name].push(part.src);
    });
  },
  contains(partName) {
    return partName in this.parts;
  },
  get(partName) {
    var parts = this.parts[partName];
    if (parts !== undefined)
      return parts.join('\n');
    return '';
  },
  files() {
    return Object.keys(this.parts)
      .map((key) => {
        return { name: key, src: this.parts[key].join('\n') };
      })
      .filter((prt) => prt.name.endsWith('.i') || prt.name.endsWith('.js'));
  }
};

function renderFeature(method, parts, decl, renderer) {
  if (decl.declarations)
    decl.declarations.forEach((d) => renderFeature(method, parts, d, renderer));

  var res = renderer(decl, parts);
  if (res)
    parts.add(res);
}


function render(method, mod, feats) {
  if (Array.isArray(mod))
    return mod.map((m) => render(method, m, feats));

  if (typeof mod === 'string') {
    mod = JSON.parse(fs.readFileSync(mod));
    conf.mapSources(mod);
  }

  var parts = new Parts(mod.name);
  if (mod.noSwig)
    return parts;

  features.getRenderers(method).forEach(renderer => {
    renderFeature(method, parts, mod, renderer);
  });

  return parts;
}

function writeParts(dest, parts, options) {
  options = options || {};
  if (Array.isArray(parts)) {
    return parts.forEach((p) => writeParts(dest, p, options));
  }

  parts.files().forEach((part) => {
    var file = path.join(dest, parts.name, part.name);
    if (options.flat)
      file = path.join(dest, part.name);
    mkdirp.sync(path.dirname(file));
    fs.writeFileSync(file, part.src);
  });
  return true;
}


module.exports = render;
module.exports.feature = renderFeature;
module.exports.write = writeParts;