選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 

174 行
8.1 KiB

  1. const fs = require('fs-extra');
  2. const mime = require('mime-types');
  3. const { join, basename, dirname } = require('path');
  4. const { toSystemPath } = require('../core/path');
  5. module.exports = {
  6. provider: function (options, name) {
  7. this.setS3Provider(name, options);
  8. },
  9. createBucket: async function (options) {
  10. const provider = this.parseRequired(options.provider, 'string', 's3.createBucket: provider is required.');
  11. const Bucket = this.parseRequired(options.bucket, 'string', 's3.createBucket: bucket is required.');
  12. const ACL = this.parseOptional(options.acl, 'string', undefined);
  13. const s3 = this.getS3Provider(provider);
  14. if (!s3) throw new Error(`S3 provider "${provider}" doesn't exist.`);
  15. return s3.createBucket({ Bucket, ACL });
  16. },
  17. listBuckets: async function (options) {
  18. const provider = this.parseRequired(options.provider, 'string', 's3.listBuckets: provider is required.');
  19. const s3 = this.getS3Provider(provider);
  20. if (!s3) throw new Error(`S3 provider "${provider}" doesn't exist.`);
  21. return s3.listBuckets({});
  22. },
  23. deleteBucket: async function (options) {
  24. const provider = this.parseRequired(options.provider, 'string', 's3.deleteBucket: provider is required.');
  25. const Bucket = this.parseRequired(options.bucket, 'string', 's3.deleteBucket: bucket is required.');
  26. const s3 = this.getS3Provider(provider);
  27. if (!s3) throw new Error(`S3 provider "${provider}" doesn't exist.`);
  28. return s3.deleteBucket({ Bucket });
  29. },
  30. listFiles: async function (options) {
  31. const provider = this.parseRequired(options.provider, 'string', 's3.listFiles: provider is required.');
  32. const Bucket = this.parseRequired(options.bucket, 'string', 's3.listFiles: bucket is required.');
  33. const MaxKeys = this.parseOptional(options.maxKeys, 'number', undefined);
  34. const Prefix = this.parseOptional(options.prefix, 'string', undefined);
  35. const ContinuationToken = this.parseOptional(options.continuationToken, 'string', undefined);
  36. const StartAfter = this.parseOptional(options.startAfter, 'string', undefined);
  37. const s3 = this.getS3Provider(provider);
  38. if (!s3) throw new Error(`S3 provider "${provider}" doesn't exist.`);
  39. return s3.listObjectsV2({ Bucket, MaxKeys, Prefix, ContinuationToken, StartAfter });
  40. },
  41. putFile: async function (options) {
  42. const provider = this.parseRequired(options.provider, 'string', 's3.uploadFile: provider is required.');
  43. const Bucket = this.parseRequired(options.bucket, 'string', 's3.uploadFile: bucket is required.');
  44. const path = toSystemPath(this.parseRequired(options.path, 'string', 's3.uploadFile: path is required.'));
  45. const Key = this.parseRequired(options.key, 'string', 's3.uploadFile: key is required.');
  46. const ContentType = this.parseOptional(options.contentType, 'string', mime.lookup(Key) || 'application/octet-stream');
  47. const ContentDisposition = this.parseOptional(options.contentDisposition, 'string', undefined);
  48. const ACL = this.parseOptional(options.acl, 'string', undefined);
  49. const s3 = this.getS3Provider(provider);
  50. if (!s3) throw new Error(`S3 provider "${provider}" doesn't exist.`);
  51. let Body = fs.createReadStream(path);
  52. const result = await s3.putObject({ Bucket, ACL, Key, ContentType, ContentDisposition, Body });
  53. try {
  54. const endpoint = await s3.config.endpoint();
  55. result.Location = `https://${Bucket}.${endpoint.hostname}/${Key}`;
  56. } catch (e) {}
  57. return result;
  58. },
  59. getFile: async function (options) {
  60. const provider = this.parseRequired(options.provider, 'string', 's3.getFile: provider is required.');
  61. const Bucket = this.parseRequired(options.bucket, 'string', 's3.getFile: bucket is required.');
  62. const Key = this.parseRequired(options.key, 'string', 's3.getFile: key is required.');
  63. const path = toSystemPath(this.parseRequired(options.path, 'string', 's3.getFile: path is required.'));
  64. const stripKeyPath = this.parseOptional(options.stripKeyPath, 'boolean', false);
  65. const s3 = this.getS3Provider(provider);
  66. if (!s3) throw new Error(`S3 provider "${provider}" doesn't exist.`);
  67. const file = Key;
  68. if (stripKeyPath) file = basename(file);
  69. const destination = join(path, file);
  70. await fs.ensureDir(dirname(destination));
  71. const writer = fs.createWriteStream(destination);
  72. const { Body } = await s3.getObject({ Bucket, Key });
  73. Body.pipe(writer);
  74. return new Promise((resolve, reject) => {
  75. writer.on('finish', resolve);
  76. writer.on('error', reject);
  77. });
  78. },
  79. deleteFile: async function (options) {
  80. const provider = this.parseRequired(options.provider, 'string', 's3.deleteFile: provider is required.');
  81. const Bucket = this.parseRequired(options.bucket, 'string', 's3.deleteFile: bucket is required.');
  82. const Key = this.parseRequired(options.key, 'string', 's3.deleteFile: key is required.');
  83. const s3 = this.getS3Provider(provider);
  84. if (!s3) throw new Error(`S3 provider "${provider}" doesn't exist.`);
  85. return s3.deleteObject({ Bucket, Key });
  86. },
  87. downloadFile: async function (options) {
  88. const provider = this.parseRequired(options.provider, 'string', 's3.downloadFile: profider is required.');
  89. const Bucket = this.parseRequired(options.bucket, 'string', 's3.downloadFile: bucket is required.');
  90. const Key = this.parseRequired(options.key, 'string', 's3.downloadFile: key is required.');
  91. const s3 = this.getS3Provider(provider);
  92. if (!s3) throw new Error(`S3 provider "${provider}" doesn't exist.`);
  93. const data = await s3.headObject({ Bucket, Key });
  94. this.res.set('Content-Length', data.ContentLength);
  95. this.res.attachment(basename(Key));
  96. const { Body } = await s3.getObject({ Bucket, Key });
  97. Body.pipe(this.res);
  98. this.noOutput = true;
  99. },
  100. signDownloadUrl: async function (options) {
  101. const provider = this.parseRequired(options.provider, 'string', 's3.signDownloadUrl: provider is required.');
  102. const Bucket = this.parseRequired(options.bucket, 'string', 's3.signDownloadUrl: bucket is required.');
  103. const Key = this.parseRequired(options.key, 'string', 's3.signDownloadUrl: key is required.');
  104. const expiresIn = this.parseOptional(options.expires, 'number', 300);
  105. const s3 = this.getS3Provider(provider);
  106. if (!s3) throw new Error(`S3 provider "${provider}" doesn't exist.`);
  107. const { getSignedUrl } = require("@aws-sdk/s3-request-presigner");
  108. const { GetObjectCommand } = require('@aws-sdk/client-s3');
  109. const command = new GetObjectCommand({ Bucket, Key });
  110. return getSignedUrl(s3, command, { expiresIn });
  111. },
  112. signUploadUrl: async function (options) {
  113. const provider = this.parseRequired(options.provider, 'string', 's3.signUploadUrl: provider is required.');
  114. const Bucket = this.parseRequired(options.bucket, 'string', 's3.signUploadUrl: bucket is required.');
  115. const Key = this.parseRequired(options.key, 'string', 's3.signUploadUrl: key is required.');
  116. const ContentType = this.parseOptional(options.contentType, 'string', mime.lookup(Key) || 'application/octet-stream');
  117. const expiresIn = this.parseOptional(options.expires, 'number', 300);
  118. const ACL = this.parseOptional(options.acl, 'string', undefined);
  119. const s3 = this.getS3Provider(provider);
  120. if (!s3) throw new Error(`S3 provider "${provider}" doesn't exist.`);
  121. const { getSignedUrl } = require("@aws-sdk/s3-request-presigner");
  122. const { PutObjectCommand } = require('@aws-sdk/client-s3');
  123. const command = new PutObjectCommand({ Bucket, Key, ContentType, ACL });
  124. return getSignedUrl(s3, command, { expiresIn });
  125. }
  126. };