index.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. "use strict";
  2. var __importDefault = (this && this.__importDefault) || function (mod) {
  3. return (mod && mod.__esModule) ? mod : { "default": mod };
  4. };
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. const request_1 = __importDefault(require("request"));
  7. const fs_1 = __importDefault(require("fs"));
  8. const httpRequest_1 = __importDefault(require("../utils/httpRequest"));
  9. const xml2js_1 = require("xml2js");
  10. const utils_1 = require("../utils/utils");
  11. const code_1 = require("../const/code");
  12. const cloudbase_1 = require("../cloudbase");
  13. async function parseXML(str) {
  14. return new Promise((resolve, reject) => {
  15. xml2js_1.parseString(str, (err, result) => {
  16. if (err) {
  17. reject(err);
  18. }
  19. else {
  20. resolve(result);
  21. }
  22. });
  23. });
  24. }
  25. exports.parseXML = parseXML;
  26. /*
  27. * 上传文件
  28. * @param {string} cloudPath 上传后的文件路径
  29. * @param {fs.ReadStream} fileContent 上传文件的二进制流
  30. */
  31. async function uploadFile(cloudbase, { cloudPath, fileContent }, opts) {
  32. const { data: { url, token, authorization, fileId, cosFileId } } = await getUploadMetadata(cloudbase, { cloudPath }, opts);
  33. const formData = {
  34. Signature: authorization,
  35. 'x-cos-security-token': token,
  36. 'x-cos-meta-fileid': cosFileId,
  37. key: cloudPath,
  38. file: fileContent
  39. };
  40. let body = await new Promise((resolve, reject) => {
  41. request_1.default({ url, formData: formData, method: 'post' }, function (err, res, body) {
  42. if (err) {
  43. reject(err);
  44. }
  45. else {
  46. resolve(body);
  47. }
  48. });
  49. });
  50. body = await parseXML(body);
  51. if (body && body.Error) {
  52. const { Code: [code], Message: [message] } = body.Error;
  53. if (code === 'SignatureDoesNotMatch') {
  54. return utils_1.processReturn(cloudbase.config.throwOnCode, Object.assign({}, code_1.ERROR.SYS_ERR, { message }));
  55. }
  56. return utils_1.processReturn(cloudbase.config.throwOnCode, Object.assign({}, code_1.ERROR.STORAGE_REQUEST_FAIL, { message }));
  57. }
  58. return {
  59. fileID: fileId
  60. };
  61. }
  62. exports.uploadFile = uploadFile;
  63. /**
  64. * 删除文件
  65. * @param {Array.<string>} fileList 文件id数组
  66. */
  67. async function deleteFile(cloudbase, { fileList }, opts) {
  68. if (!fileList || !Array.isArray(fileList)) {
  69. return utils_1.processReturn(cloudbase.config.throwOnCode, Object.assign({}, code_1.ERROR.INVALID_PARAM, { message: 'fileList必须是非空的数组' }));
  70. }
  71. for (let file of fileList) {
  72. if (!file || typeof file !== 'string') {
  73. return utils_1.processReturn(cloudbase.config.throwOnCode, Object.assign({}, code_1.ERROR.INVALID_PARAM, { message: 'fileList的元素必须是非空的字符串' }));
  74. }
  75. }
  76. let params = {
  77. action: 'storage.batchDeleteFile',
  78. fileid_list: fileList
  79. };
  80. return httpRequest_1.default({
  81. config: cloudbase.config,
  82. params,
  83. method: 'post',
  84. opts,
  85. headers: {
  86. 'content-type': 'application/json'
  87. }
  88. }).then(res => {
  89. if (res.code) {
  90. return res;
  91. }
  92. // throw E({ ...res })
  93. // } else {
  94. return {
  95. fileList: res.data.delete_list,
  96. requestId: res.requestId
  97. };
  98. // }
  99. });
  100. }
  101. exports.deleteFile = deleteFile;
  102. /**
  103. * 获取文件下载链接
  104. * @param {Array.<Object>} fileList
  105. */
  106. async function getTempFileURL(cloudbase, { fileList }, opts) {
  107. if (!fileList || !Array.isArray(fileList)) {
  108. return utils_1.processReturn(cloudbase.config.throwOnCode, Object.assign({}, code_1.ERROR.INVALID_PARAM, { message: 'fileList必须是非空的数组' }));
  109. }
  110. let file_list = [];
  111. for (let file of fileList) {
  112. if (typeof file === 'object') {
  113. if (!file.hasOwnProperty('fileID') || !file.hasOwnProperty('maxAge')) {
  114. return utils_1.processReturn(cloudbase.config.throwOnCode, Object.assign({}, code_1.ERROR.INVALID_PARAM, { message: 'fileList的元素如果是对象,必须是包含fileID和maxAge的对象' }));
  115. }
  116. file_list.push({
  117. fileid: file.fileID,
  118. max_age: file.maxAge
  119. });
  120. }
  121. else if (typeof file === 'string') {
  122. file_list.push({
  123. fileid: file
  124. });
  125. }
  126. else {
  127. return utils_1.processReturn(cloudbase.config.throwOnCode, Object.assign({}, code_1.ERROR.INVALID_PARAM, { message: 'fileList的元素如果不是对象,则必须是字符串' }));
  128. }
  129. }
  130. let params = {
  131. action: 'storage.batchGetDownloadUrl',
  132. file_list
  133. };
  134. // console.log(params);
  135. return httpRequest_1.default({
  136. config: cloudbase.config,
  137. params,
  138. method: 'post',
  139. opts,
  140. headers: {
  141. 'content-type': 'application/json'
  142. }
  143. }).then(res => {
  144. if (res.code) {
  145. return res;
  146. }
  147. // if (res.code) {
  148. // throw E({ ...res })
  149. // } else {
  150. return {
  151. fileList: res.data.download_list,
  152. requestId: res.requestId
  153. };
  154. // }
  155. });
  156. }
  157. exports.getTempFileURL = getTempFileURL;
  158. async function downloadFile(cloudbase, params, opts) {
  159. let tmpUrl;
  160. const { fileID, tempFilePath } = params;
  161. const tmpUrlRes = await getTempFileURL(cloudbase, {
  162. fileList: [
  163. {
  164. fileID,
  165. maxAge: 600
  166. }
  167. ]
  168. }, opts);
  169. // console.log(tmpUrlRes);
  170. const res = tmpUrlRes.fileList[0];
  171. if (res.code !== 'SUCCESS') {
  172. return utils_1.processReturn(cloudbase.config.throwOnCode, Object.assign({}, res));
  173. }
  174. tmpUrl = res.tempFileURL;
  175. tmpUrl = encodeURI(tmpUrl);
  176. let req = request_1.default({
  177. url: tmpUrl,
  178. encoding: null,
  179. proxy: cloudbase.config.proxy
  180. });
  181. return new Promise((resolve, reject) => {
  182. let fileContent = Buffer.alloc(0);
  183. req.on('response', function (response) {
  184. /* istanbul ignore else */
  185. if (response && Number(response.statusCode) === 200) {
  186. if (tempFilePath) {
  187. response.pipe(fs_1.default.createWriteStream(tempFilePath));
  188. }
  189. else {
  190. response.on('data', data => {
  191. fileContent = Buffer.concat([fileContent, data]);
  192. });
  193. }
  194. response.on('end', () => {
  195. resolve({
  196. fileContent: tempFilePath ? undefined : fileContent,
  197. message: '文件下载完成'
  198. });
  199. });
  200. }
  201. else {
  202. reject(response);
  203. }
  204. });
  205. });
  206. }
  207. exports.downloadFile = downloadFile;
  208. async function getUploadMetadata(cloudbase, { cloudPath }, opts) {
  209. let params = {
  210. action: 'storage.getUploadMetadata',
  211. path: cloudPath
  212. };
  213. const res = await httpRequest_1.default({
  214. config: cloudbase.config,
  215. params,
  216. method: 'post',
  217. opts,
  218. headers: {
  219. 'content-type': 'application/json'
  220. }
  221. });
  222. // if (res.code) {
  223. // throw E({
  224. // ...ERROR.STORAGE_REQUEST_FAIL,
  225. // message: 'get upload metadata failed: ' + res.code
  226. // })
  227. // } else {
  228. return res;
  229. // }
  230. }
  231. exports.getUploadMetadata = getUploadMetadata;
  232. async function getFileAuthority(cloudbase, { fileList }, opts) {
  233. const { LOGINTYPE } = cloudbase_1.CloudBase.getCloudbaseContext();
  234. if (!Array.isArray(fileList)) {
  235. throw utils_1.E(Object.assign({}, code_1.ERROR.INVALID_PARAM, { message: '[node-sdk] getCosFileAuthority fileList must be a array' }));
  236. }
  237. if (fileList.some(file => {
  238. if (!file || !file.path) {
  239. return true;
  240. }
  241. if (['READ', 'WRITE', 'READWRITE'].indexOf(file.type) === -1) {
  242. return true;
  243. }
  244. return false;
  245. })) {
  246. throw utils_1.E(Object.assign({}, code_1.ERROR.INVALID_PARAM, { message: '[node-sdk] getCosFileAuthority fileList param error' }));
  247. }
  248. const userInfo = cloudbase.auth().getUserInfo();
  249. const { openId, uid } = userInfo;
  250. if (!openId && !uid) {
  251. throw utils_1.E(Object.assign({}, code_1.ERROR.INVALID_PARAM, { message: '[node-sdk] admin do not need getCosFileAuthority.' }));
  252. }
  253. let params = {
  254. action: 'storage.getFileAuthority',
  255. openId,
  256. uid,
  257. loginType: LOGINTYPE,
  258. fileList
  259. };
  260. const res = await httpRequest_1.default({
  261. config: cloudbase.config,
  262. params,
  263. method: 'post',
  264. headers: {
  265. 'content-type': 'application/json'
  266. }
  267. });
  268. if (res.code) {
  269. /* istanbul ignore next */
  270. throw utils_1.E(Object.assign({}, res, { message: '[node-sdk] getCosFileAuthority failed: ' + res.code }));
  271. }
  272. else {
  273. return res;
  274. }
  275. }
  276. exports.getFileAuthority = getFileAuthority;