All files / src/lib package-json.js

100% Statements 38/38
100% Branches 34/34
100% Functions 6/6
100% Lines 32/32
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 771x 1x       67x 67x   67x 43x 43x   25x           52x 52x   52x   44x       21x 21x   21x   4x               43x 2x 1x   1x   2x             41x 10x 10x 10x     31x   8x   6x 6x   23x         13x       67x  
const fs = require('fs');
const { join } = require('path');
 
class PackageJson {
  constructor(packageJson, path = process.cwd()) {
    this.path = path;
    this.packageJson = packageJson;
 
    if (!this.packageJson) {
      try {
        this.packageJson = require(join(this.path, 'package.json'));
      } catch (e) {
        this.packageJson = {};
      }
    }
  }
 
  get(key, opts = { build: false }) {
    const rootProperty = this.packageJson[key];
    const buildProperty = (this.packageJson.build || {})[key];
 
    if (opts.build === true) return buildProperty;
 
    return buildProperty || rootProperty;
  }
 
  has(key, opts = { build: false }) {
    const existsInRoot = typeof this.packageJson[key] !== 'undefined';
    const existsInBuild = typeof (this.packageJson.build || {})[key] !== 'undefined';
 
    if (opts.build === true) return existsInBuild;
 
    return existsInRoot || existsInBuild;
  }
 
  set(key, value, opts = { root: false, build: false }) {
    // If the `root` option is set, then attempt to set with a priority
    // in the root as opposed to in `build`. This is useful for updating
    // the `version` property of the package.json when it hasn't
    // diverged from the base version
    if (opts.root === true) {
      if (this.packageJson.build && this.packageJson.build[key]) {
        this.packageJson.build[key] = value;
      } else {
        this.packageJson[key] = value;
      }
      return;
    }
 
    // If the `build` option is set, then set in `build` instead of
    // attempting to set in the root first. This is useful for updating
    // the `private` property of the package.json which when in the root
    // means that a package shouldn't be deployed to npm
    if (opts.build === true) {
      if (!this.packageJson.build) this.packageJson.build = {};
      this.packageJson.build[key] = value;
      return;
    }
 
    if (this.packageJson[key]) {
      // Ignore property if it's the same
      if (this.packageJson[key] === value) return;
 
      if (!this.packageJson.build) this.packageJson.build = {};
      this.packageJson.build[key] = value;
    } else {
      this.packageJson[key] = value;
    }
  }
 
  write() {
    return fs.writeFileSync(join(this.path, 'package.json'), JSON.stringify(this.packageJson, undefined, 2));
  }
}
 
module.exports = (...args) => new PackageJson(...args);