migration.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. "use strict";
  2. var _path2 = _interopRequireDefault(require("path"));
  3. var _helper = _interopRequireDefault(require("./helper"));
  4. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  5. function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
  6. function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
  7. /**
  8. * @class Migration
  9. */
  10. module.exports = class Migration {
  11. /**
  12. * Wrapper function for migration methods.
  13. *
  14. * @callback Migration~wrap
  15. * @param {function} - Migration method to be wrapped.
  16. * @return {*|Promise}
  17. */
  18. /**
  19. * Constructs Migration.
  20. *
  21. * @param {String} path - Path of the migration file.
  22. * @param {Object} options
  23. * @param {String} options.upName - Name of the method `up` in migration
  24. * module.
  25. * @param {String} options.downName - Name of the method `down` in migration
  26. * module.
  27. * @param {Object} options.migrations
  28. * @param {Migration~wrap} options.migrations.wrap - Wrapper function for
  29. * migration methods.
  30. * @param {Migration~customResolver} [options.migrations.customResolver] - A
  31. * function that specifies how to get a migration object from a path. This
  32. * should return an object of the form { up: Function, down: Function }.
  33. * Without this defined, a regular javascript import will be performed.
  34. * @constructs Migration
  35. */
  36. constructor(path, options) {
  37. this.path = _path2.default.resolve(path);
  38. this.file = _path2.default.basename(this.path);
  39. this.options = options;
  40. }
  41. /**
  42. * Tries to require migration module. CoffeeScript support requires
  43. * 'coffee-script' to be installed.
  44. * To require other file types, like TypeScript or raw sql files, a
  45. * custom resolver can be used.
  46. *
  47. * @returns {Promise.<Object>} Required migration module
  48. */
  49. migration() {
  50. if (typeof this.options.migrations.customResolver === 'function') {
  51. return this.options.migrations.customResolver(this.path);
  52. }
  53. if (this.path.match(/\.coffee$/)) {
  54. // 2.x compiler registration
  55. _helper.default.resolve('coffeescript/register') || // 1.7.x compiler registration
  56. _helper.default.resolve('coffee-script/register') || // Prior to 1.7.x compiler registration
  57. _helper.default.resolve('coffee-script') ||
  58. /* jshint expr: true */
  59. function () {
  60. console.error('You have to add "coffee-script" to your package.json.');
  61. process.exit(1);
  62. }();
  63. }
  64. return require(this.path);
  65. }
  66. /**
  67. * Executes method `up` of migration.
  68. *
  69. * @returns {Promise}
  70. */
  71. up() {
  72. return this._exec(this.options.upName, [].slice.apply(arguments));
  73. }
  74. /**
  75. * Executes method `down` of migration.
  76. *
  77. * @returns {Promise}
  78. */
  79. down() {
  80. return this._exec(this.options.downName, [].slice.apply(arguments));
  81. }
  82. /**
  83. * Check if migration file name is starting with needle.
  84. * @param {String} needle - The beginning of the file name.
  85. * @returns {boolean}
  86. */
  87. testFileName(needle) {
  88. return this.file.indexOf(needle) === 0;
  89. }
  90. /**
  91. * Executes a given method of migration with given arguments.
  92. *
  93. * @param {String} method - Name of the method to be called.
  94. * @param {*} args - Arguments to be used when called the method.
  95. * @returns {Promise}
  96. * @private
  97. */
  98. _exec(method, args) {
  99. var _this = this;
  100. return _asyncToGenerator(function* () {
  101. const migration = yield _this.migration();
  102. let fun = migration[method];
  103. if (migration.default) {
  104. fun = migration.default[method] || migration[method];
  105. }
  106. if (!fun) throw new Error('Could not find migration method: ' + method);
  107. const wrappedFun = _this.options.migrations.wrap(fun);
  108. const result = wrappedFun.apply(migration, args);
  109. if (!result || typeof result.then !== 'function') {
  110. throw new Error(`Migration ${_this.file} (or wrapper) didn't return a promise`);
  111. }
  112. yield result;
  113. })();
  114. }
  115. };