index.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. var path = require('path');
  2. var cloneStats = require('clone-stats');
  3. var isBuffer = require('./lib/isBuffer');
  4. var isStream = require('./lib/isStream');
  5. var isNull = require('./lib/isNull');
  6. var inspectStream = require('./lib/inspectStream');
  7. var cloneBuffer = require('./lib/cloneBuffer');
  8. function File(file) {
  9. if (!file) file = {};
  10. // TODO: should this be moved to vinyl-fs?
  11. this.cwd = file.cwd || process.cwd();
  12. this.base = file.base || this.cwd;
  13. this.path = file.path || null;
  14. // stat = fs stats object
  15. // TODO: should this be moved to vinyl-fs?
  16. this.stat = file.stat || null;
  17. // contents = stream, buffer, or null if not read
  18. this.contents = file.contents || null;
  19. }
  20. File.prototype.isBuffer = function() {
  21. return isBuffer(this.contents);
  22. };
  23. File.prototype.isStream = function() {
  24. return isStream(this.contents);
  25. };
  26. File.prototype.isNull = function() {
  27. return isNull(this.contents);
  28. };
  29. // TODO: should this be moved to vinyl-fs?
  30. File.prototype.isDirectory = function() {
  31. return this.isNull() && this.stat && this.stat.isDirectory();
  32. };
  33. File.prototype.clone = function() {
  34. var clonedContents = this.isBuffer() ? cloneBuffer(this.contents) : this.contents;
  35. var clonedStat = this.stat ? cloneStats(this.stat) : null;
  36. return new File({
  37. cwd: this.cwd,
  38. base: this.base,
  39. path: this.path,
  40. stat: clonedStat,
  41. contents: clonedContents
  42. });
  43. };
  44. File.prototype.pipe = function(stream, opt) {
  45. if (!opt) opt = {};
  46. if (typeof opt.end === 'undefined') opt.end = true;
  47. if (this.isStream()) {
  48. return this.contents.pipe(stream, opt);
  49. }
  50. if (this.isBuffer()) {
  51. if (opt.end) {
  52. stream.end(this.contents);
  53. } else {
  54. stream.write(this.contents);
  55. }
  56. return stream;
  57. }
  58. if (this.isNull()) {
  59. if (opt.end) stream.end();
  60. return stream;
  61. }
  62. return stream;
  63. };
  64. File.prototype.inspect = function() {
  65. var inspect = [];
  66. // use relative path if possible
  67. var filePath = (this.base && this.path) ? this.relative : this.path;
  68. if (filePath) {
  69. inspect.push('"'+filePath+'"');
  70. }
  71. if (this.isBuffer()) {
  72. inspect.push(this.contents.inspect());
  73. }
  74. if (this.isStream()) {
  75. inspect.push(inspectStream(this.contents));
  76. }
  77. return '<File '+inspect.join(' ')+'>';
  78. };
  79. // virtual attributes
  80. // or stuff with extra logic
  81. Object.defineProperty(File.prototype, 'contents', {
  82. get: function() {
  83. return this._contents;
  84. },
  85. set: function(val) {
  86. if (!isBuffer(val) && !isStream(val) && !isNull(val)) {
  87. throw new Error("File.contents can only be a Buffer, a Stream, or null.");
  88. }
  89. this._contents = val;
  90. }
  91. });
  92. // TODO: should this be moved to vinyl-fs?
  93. Object.defineProperty(File.prototype, 'relative', {
  94. get: function() {
  95. if (!this.base) throw new Error('No base specified! Can not get relative.');
  96. if (!this.path) throw new Error('No path specified! Can not get relative.');
  97. return path.relative(this.base, this.path);
  98. },
  99. set: function() {
  100. throw new Error('File.relative is generated from the base and path attributes. Do not modify it.');
  101. }
  102. });
  103. module.exports = File;