1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | Object.defineProperty(exports, "__esModule", { value: true });
|
19 | const _ = require("lodash");
|
20 | const azureStorage = require("azure-storage");
|
21 | const crypto = require("crypto");
|
22 | const isStream = require("is-stream");
|
23 | const mimeTypes = require("mime-types");
|
24 | const sanitizeFilename = require("sanitize-filename");
|
25 | const streams_1 = require("../streams");
|
26 | const index_1 = require("../index");
|
27 | const fs_extra_1 = require("fs-extra");
|
28 | const path_1 = require("path");
|
29 | const fs_1 = require("../fs");
|
30 |
|
31 |
|
32 |
|
33 | class AzureStorageClient {
|
34 | |
35 |
|
36 |
|
37 |
|
38 |
|
39 | constructor(options) {
|
40 | this.options = options;
|
41 | if (_.isNil(this.options)) {
|
42 | this.options = {};
|
43 | }
|
44 | }
|
45 | |
46 |
|
47 |
|
48 |
|
49 |
|
50 | async createBlobService() {
|
51 | let provider = this.options.blobServiceProvider;
|
52 | if (_.isNil(provider)) {
|
53 |
|
54 | provider = () => azureStorage.createBlobService();
|
55 | }
|
56 | return Promise.resolve(provider());
|
57 | }
|
58 | |
59 |
|
60 |
|
61 |
|
62 |
|
63 | static fromEnvironment() {
|
64 | return new AzureStorageClient();
|
65 | }
|
66 | |
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 | getBlobInfo(path) {
|
74 | return new Promise(async (resolve, reject) => {
|
75 | try {
|
76 | const BLOBS = await this.createBlobService();
|
77 | const CONTAINER = index_1.toStringSafe(await this.getContainer());
|
78 | const BLOB_NAME = index_1.toStringSafe(await this.toFullPath(path));
|
79 | BLOBS.doesBlobExist(CONTAINER, BLOB_NAME, (err, result) => {
|
80 | if (err) {
|
81 | reject(err);
|
82 | }
|
83 | else {
|
84 | if (index_1.toBooleanSafe(result.exists)) {
|
85 | resolve(result);
|
86 | }
|
87 | else {
|
88 | resolve(false);
|
89 | }
|
90 | }
|
91 | });
|
92 | }
|
93 | catch (e) {
|
94 | reject(e);
|
95 | }
|
96 | });
|
97 | }
|
98 | getContainer() {
|
99 | let containerProvider = this.options.blobContainerProvider;
|
100 | if (_.isNil(containerProvider)) {
|
101 |
|
102 | containerProvider = () => process.env
|
103 | .AZURE_STORAGE_CONTAINER
|
104 | .trim();
|
105 | }
|
106 | else {
|
107 | if (!_.isFunction(containerProvider)) {
|
108 | const CONTAINER_PROVIDER = index_1.toStringSafe(containerProvider);
|
109 | containerProvider = () => {
|
110 | return CONTAINER_PROVIDER;
|
111 | };
|
112 | }
|
113 | }
|
114 | return Promise.resolve(containerProvider());
|
115 | }
|
116 | |
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 | loadBlob(path) {
|
124 | return new Promise(async (resolve, reject) => {
|
125 | try {
|
126 | const BLOBS = await this.createBlobService();
|
127 | const DATA = await fs_1.tempFile((tmpFile) => {
|
128 | return new Promise(async (res, rej) => {
|
129 | try {
|
130 | const STREAM = fs_extra_1.createWriteStream(tmpFile);
|
131 | const CONTAINER = index_1.toStringSafe(await this.getContainer());
|
132 | const BLOB_NAME = index_1.toStringSafe(await this.toFullPath(path));
|
133 | BLOBS.getBlobToStream(CONTAINER, BLOB_NAME, STREAM, (err) => {
|
134 | if (err) {
|
135 | rej(err);
|
136 | }
|
137 | else {
|
138 | try {
|
139 | res(fs_extra_1.readFileSync(tmpFile));
|
140 | }
|
141 | catch (e) {
|
142 | rej(e);
|
143 | }
|
144 | }
|
145 | });
|
146 | }
|
147 | catch (e) {
|
148 | rej(e);
|
149 | }
|
150 | });
|
151 | });
|
152 | resolve(DATA);
|
153 | }
|
154 | catch (e) {
|
155 | reject(e);
|
156 | }
|
157 | });
|
158 | }
|
159 | |
160 |
|
161 |
|
162 |
|
163 |
|
164 |
|
165 | saveBlob(path, data) {
|
166 | return new Promise(async (resolve, reject) => {
|
167 | try {
|
168 | const BLOBS = await this.createBlobService();
|
169 | let mimeDetector = this.options.blobContentTypeDetector;
|
170 | if (_.isNil(mimeDetector)) {
|
171 |
|
172 | mimeDetector = (p) => {
|
173 | let mime = mimeTypes.lookup(p);
|
174 | if (false === mime) {
|
175 | mime = 'application/octet-stream';
|
176 | }
|
177 | return mime;
|
178 | };
|
179 | }
|
180 | const BLOB_NAME = index_1.toStringSafe(await this.toFullPath(path));
|
181 | const CONTENT_TYPE = index_1.toStringSafe(await Promise.resolve(mimeDetector(BLOB_NAME)));
|
182 | const CONTAINER = index_1.toStringSafe(await this.getContainer());
|
183 | let dataToStore;
|
184 | if (_.isNil(data)) {
|
185 | dataToStore = Buffer.alloc(0);
|
186 | }
|
187 | else {
|
188 | if (Buffer.isBuffer(data)) {
|
189 | dataToStore = data;
|
190 | }
|
191 | else if (isStream.readable(data)) {
|
192 | dataToStore = await streams_1.readAll(data);
|
193 | }
|
194 | else {
|
195 | dataToStore = Buffer.from(index_1.toStringSafe(data), 'utf8');
|
196 | }
|
197 | }
|
198 | BLOBS.createBlockBlobFromText(CONTAINER, BLOB_NAME, dataToStore, {
|
199 | contentSettings: {
|
200 | contentMD5: crypto.createHash('md5')
|
201 | .update(data).digest('base64'),
|
202 | contentType: CONTENT_TYPE,
|
203 | },
|
204 | }, (err) => {
|
205 | if (err) {
|
206 | reject(err);
|
207 | }
|
208 | else {
|
209 | resolve();
|
210 | }
|
211 | });
|
212 | }
|
213 | catch (e) {
|
214 | reject(e);
|
215 | }
|
216 | });
|
217 | }
|
218 | |
219 |
|
220 |
|
221 |
|
222 |
|
223 |
|
224 |
|
225 |
|
226 | async saveUniqueBlob(path, data) {
|
227 | let blobNameCreator = this.options.uniqueBlobNameCreator;
|
228 | if (_.isNil(blobNameCreator)) {
|
229 |
|
230 | blobNameCreator = (orgName) => {
|
231 | const BLOB_DIR = path_1.dirname(orgName);
|
232 | const BLOB_EXT = path_1.extname(orgName);
|
233 | const BLOB_NAME = `${index_1.uuid().split('-').join('')}_${Math.round(Math.random() * 597923979)}_tmmk`;
|
234 | return path_1.join(BLOB_DIR, BLOB_NAME + BLOB_EXT);
|
235 | };
|
236 | }
|
237 | const BLOB_NAME_NEW = index_1.toStringSafe(await Promise.resolve(blobNameCreator(index_1.toStringSafe(path))));
|
238 | await this.saveBlob(BLOB_NAME_NEW, data);
|
239 | return await this.toFullPath(BLOB_NAME_NEW);
|
240 | }
|
241 | toFullPath(p) {
|
242 | let tfp = this.options.toFullBlobPath;
|
243 | if (_.isNil(tfp)) {
|
244 |
|
245 | tfp = toFullBlobPath;
|
246 | }
|
247 | return Promise.resolve(tfp(p));
|
248 | }
|
249 | }
|
250 | exports.AzureStorageClient = AzureStorageClient;
|
251 |
|
252 |
|
253 |
|
254 |
|
255 |
|
256 |
|
257 |
|
258 | function normalizeAzureBlobPath(p) {
|
259 | return index_1.toStringSafe(p).trim();
|
260 | }
|
261 | exports.normalizeAzureBlobPath = normalizeAzureBlobPath;
|
262 | function toFullBlobPath(p) {
|
263 | let prefix = sanitizeFilename(index_1.normalizeString(process.env.APP_ENV));
|
264 | if ('' === prefix) {
|
265 | prefix = 'prod';
|
266 | }
|
267 | let fullPath = prefix + '/' +
|
268 | normalizeAzureBlobPath(p);
|
269 | fullPath = fullPath.split(path_1.sep).join('/');
|
270 | return fullPath;
|
271 | }
|
272 |
|
\ | No newline at end of file |