storage.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. 'use strict';
  2. const assert = require('assert');
  3. const _ = require('lodash');
  4. /**
  5. * Storage instances handle a json file where Generator authors can store data.
  6. *
  7. * The `Generator` class instantiate the storage named `config` by default.
  8. *
  9. * @constructor
  10. * @param {String} name The name of the new storage (this is a namespace)
  11. * @param {mem-fs-editor} fs A mem-fs editor instance
  12. * @param {String} configPath The filepath used as a storage.
  13. *
  14. * @example
  15. * class extend Generator {
  16. * writing: function() {
  17. * this.config.set('coffeescript', false);
  18. * }
  19. * }
  20. */
  21. class Storage {
  22. constructor(name, fs, configPath) {
  23. assert(name, 'A name parameter is required to create a storage');
  24. assert(configPath, 'A config filepath is required to create a storage');
  25. this.path = configPath;
  26. this.name = name;
  27. this.fs = fs;
  28. this.existed = Object.keys(this._store).length > 0;
  29. }
  30. /**
  31. * Return the current store as JSON object
  32. * @return {Object} the store content
  33. * @private
  34. */
  35. get _store() {
  36. return this.fs.readJSON(this.path, {})[this.name] || {};
  37. }
  38. /**
  39. * Persist a configuration to disk
  40. * @param {Object} val - current configuration values
  41. * @private
  42. */
  43. _persist(val) {
  44. const fullStore = this.fs.readJSON(this.path, {});
  45. fullStore[this.name] = val;
  46. this.fs.write(this.path, JSON.stringify(fullStore, null, ' '));
  47. }
  48. /**
  49. * Save a new object of values
  50. * @return {null}
  51. */
  52. save() {
  53. this._persist(this._store);
  54. }
  55. /**
  56. * Get a stored value
  57. * @param {String} key The key under which the value is stored.
  58. * @return {*} The stored value. Any JSON valid type could be returned
  59. */
  60. get(key) {
  61. return this._store[key];
  62. }
  63. /**
  64. * Get all the stored values
  65. * @return {Object} key-value object
  66. */
  67. getAll() {
  68. return _.cloneDeep(this._store);
  69. }
  70. /**
  71. * Assign a key to a value and schedule a save.
  72. * @param {String} key The key under which the value is stored
  73. * @param {*} val Any valid JSON type value (String, Number, Array, Object).
  74. * @return {*} val Whatever was passed in as val.
  75. */
  76. set(key, val) {
  77. assert(!_.isFunction(val), 'Storage value can\'t be a function');
  78. const store = this._store;
  79. if (_.isObject(key)) {
  80. val = _.extend(store, key);
  81. } else {
  82. store[key] = val;
  83. }
  84. this._persist(store);
  85. return val;
  86. }
  87. /**
  88. * Delete a key from the store and schedule a save.
  89. * @param {String} key The key under which the value is stored.
  90. * @return {null}
  91. */
  92. delete(key) {
  93. const store = this._store;
  94. delete store[key];
  95. this._persist(store);
  96. }
  97. /**
  98. * Setup the store with defaults value and schedule a save.
  99. * If keys already exist, the initial value is kept.
  100. * @param {Object} defaults Key-value object to store.
  101. * @return {*} val Returns the merged options.
  102. */
  103. defaults(defaults) {
  104. assert(_.isObject(defaults), 'Storage `defaults` method only accept objects');
  105. const val = _.defaults(this.getAll(), defaults);
  106. this.set(val);
  107. return val;
  108. }
  109. }
  110. module.exports = Storage;