index.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. const fs = require('graceful-fs');
  2. const directory = require('./directory');
  3. const Stream = require('stream');
  4. module.exports = {
  5. buffer: function(buffer, options) {
  6. const source = {
  7. stream: function(offset, length) {
  8. const stream = Stream.PassThrough();
  9. const end = length ? offset + length : undefined;
  10. stream.end(buffer.slice(offset, end));
  11. return stream;
  12. },
  13. size: function() {
  14. return Promise.resolve(buffer.length);
  15. }
  16. };
  17. return directory(source, options);
  18. },
  19. file: function(filename, options) {
  20. const source = {
  21. stream: function(start, length) {
  22. const end = length ? start + length : undefined;
  23. return fs.createReadStream(filename, {start, end});
  24. },
  25. size: function() {
  26. return new Promise(function(resolve, reject) {
  27. fs.stat(filename, function(err, d) {
  28. if (err)
  29. reject(err);
  30. else
  31. resolve(d.size);
  32. });
  33. });
  34. }
  35. };
  36. return directory(source, options);
  37. },
  38. url: function(request, params, options) {
  39. if (typeof params === 'string')
  40. params = {url: params};
  41. if (!params.url)
  42. throw 'URL missing';
  43. params.headers = params.headers || {};
  44. const source = {
  45. stream : function(offset, length) {
  46. const options = Object.create(params);
  47. const end = length ? offset + length : '';
  48. options.headers = Object.create(params.headers);
  49. options.headers.range = 'bytes='+offset+'-' + end;
  50. return request(options);
  51. },
  52. size: function() {
  53. return new Promise(function(resolve, reject) {
  54. const req = request(params);
  55. req.on('response', function(d) {
  56. req.abort();
  57. if (!d.headers['content-length'])
  58. reject(new Error('Missing content length header'));
  59. else
  60. resolve(d.headers['content-length']);
  61. }).on('error', reject);
  62. });
  63. }
  64. };
  65. return directory(source, options);
  66. },
  67. s3 : function(client, params, options) {
  68. const source = {
  69. size: function() {
  70. return new Promise(function(resolve, reject) {
  71. client.headObject(params, function(err, d) {
  72. if (err)
  73. reject(err);
  74. else
  75. resolve(d.ContentLength);
  76. });
  77. });
  78. },
  79. stream: function(offset, length) {
  80. const d = {};
  81. for (const key in params)
  82. d[key] = params[key];
  83. const end = length ? offset + length : '';
  84. d.Range = 'bytes='+offset+'-' + end;
  85. return client.getObject(d).createReadStream();
  86. }
  87. };
  88. return directory(source, options);
  89. },
  90. s3_v3: function (client, params, options) {
  91. //@ts-ignore
  92. const { GetObjectCommand, HeadObjectCommand } = require('@aws-sdk/client-s3');
  93. const source = {
  94. size: async () => {
  95. const head = await client.send(
  96. new HeadObjectCommand({
  97. Bucket: params.Bucket,
  98. Key: params.Key,
  99. })
  100. );
  101. if(!head.ContentLength) {
  102. return 0;
  103. }
  104. return head.ContentLength;
  105. },
  106. stream: (offset, length) => {
  107. const stream = Stream.PassThrough();
  108. const end = length ? offset + length : "";
  109. client
  110. .send(
  111. new GetObjectCommand({
  112. Bucket: params.Bucket,
  113. Key: params.Key,
  114. Range: `bytes=${offset}-${end}`,
  115. })
  116. )
  117. .then((response) => {
  118. response.Body.pipe(stream);
  119. })
  120. .catch((error) => {
  121. stream.emit("error", error);
  122. });
  123. return stream;
  124. },
  125. };
  126. return directory(source, options);
  127. },
  128. custom: function(source, options) {
  129. return directory(source, options);
  130. }
  131. };