@beauraines/node-helpers 2.7.2 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,7 +2,15 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
- ### [2.7.2](https://github.com/beauraines/node-helpers/compare/v2.7.1...v2.7.2) (2023-06-30)
5
+ ## [2.9.0](https://github.com/beauraines/node-helpers/compare/v2.7.1...v2.9.0) (2023-07-01)
6
+
7
+
8
+ ### Features
9
+
10
+ * adds download blob from azure helper ([08a1571](https://github.com/beauraines/node-helpers/commit/08a1571ab18b9eeeb1273e05b5abed95a7300457))
11
+ * **azure:** adds list blob command ([#42](https://github.com/beauraines/node-helpers/issues/42)) ([e60219b](https://github.com/beauraines/node-helpers/commit/e60219bf75acea70defde417a07219a1508b7c61))
12
+ * **azure:** new getBlob function ([876716b](https://github.com/beauraines/node-helpers/commit/876716b8256b090a2eadf45c1d03b097362b2eb2))
13
+ * **helper:** adds file write helper ([9e727e9](https://github.com/beauraines/node-helpers/commit/9e727e9ffe51525d2a73fa66ea933c1804304729))
6
14
 
7
15
 
8
16
  ### Bug Fixes
package/README.md CHANGED
@@ -5,3 +5,22 @@ This is a set of helpers for node. They're written for quick reuse rather than r
5
5
  My use is primarily in quicker one off scripts that sometime morph into something long lasting...
6
6
 
7
7
 
8
+ ## Azure Storage
9
+
10
+ Get blob from Azure example, downloads `bar.jpg` from `foo` container to `baz.jgp`
11
+
12
+ ```javascript
13
+ const AzureStorage = require('./src/azure.js')
14
+
15
+
16
+ let storageAccountName = 'devstoreaccount1'
17
+ let storageAccountKey = 'Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=='
18
+ let options = {cloudName: 'Azurite'}
19
+
20
+ let azure = new AzureStorage(storageAccountName,storageAccountKey,options)
21
+
22
+ let containerName = 'foo'
23
+ let blob = 'bar.jpg'
24
+ let file = 'baz.jpg'
25
+ await azure.downloadBlobToFile(containerName,blob,file)
26
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beauraines/node-helpers",
3
- "version": "2.7.2",
3
+ "version": "2.9.0",
4
4
  "description": "Collection of node helpers",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -11,6 +11,7 @@
11
11
  "author": "beau.raines@gmail.com",
12
12
  "license": "ISC",
13
13
  "dependencies": {
14
+ "@azure/storage-blob": "^12.14.0",
14
15
  "@azure/storage-queue": "^12.11.0",
15
16
  "azure-devops-node-api": "^12.0.0",
16
17
  "azure-storage": "^2.10.7",
package/src/azure.js CHANGED
@@ -1,6 +1,8 @@
1
1
  const azure = require('azure-storage');
2
2
  const dayjs = require('dayjs')
3
- const { QueueClient, StorageSharedKeyCredential } = require("@azure/storage-queue");
3
+ const { streamToBuffer } = require('./helpers.js')
4
+ const { BlobServiceClient, StorageSharedKeyCredential } = require("@azure/storage-blob");
5
+ const { QueueClient } = require("@azure/storage-queue");
4
6
  var path = require('path');
5
7
 
6
8
  /**
@@ -124,6 +126,7 @@ getStorageQueueSignedURL(queueUrl,options) {
124
126
  * @param {string} blobName The name of the blob to generate the token
125
127
  * @returns {string} the signed URL for the blob
126
128
  */
129
+ //TODO migrate to @azure/storage-blob
127
130
  generateBlobSignedUrl(containerName, blobName) {
128
131
 
129
132
  const sharedAccessPolicy = {
@@ -147,6 +150,7 @@ getStorageQueueSignedURL(queueUrl,options) {
147
150
  * @param {string} containerName the container to which the file will be uploaded
148
151
  * @param {string} file The path the the local file to upload to the container
149
152
  */
153
+ //TODO migrate to @azure/storage-blob
150
154
  uploadBlobFromFile(containerName,file) {
151
155
  const blobService = azure.createBlobService(this.storageAccountName, this.storageAccountKey, this.host('blob',this.cloudName));
152
156
  const options = {
@@ -163,6 +167,79 @@ getStorageQueueSignedURL(queueUrl,options) {
163
167
  });
164
168
  }
165
169
 
170
+ /**
171
+ * Downloads a blob to a local file
172
+ *
173
+ * @param {string} containerName the name of the container to download the blob from
174
+ * @param {string} blob The blob to download
175
+ * @param {string} file The path to the location to write the file
176
+ */
177
+ async downloadBlobToFile(containerName,blobName,file) {
178
+ const blobServiceClient = new BlobServiceClient(
179
+ this.host('blob',this.cloudName),
180
+ new StorageSharedKeyCredential(this.storageAccountName, this.storageAccountKey)
181
+ );
182
+ const containerClient = blobServiceClient.getContainerClient(containerName);
183
+ const blobClient = containerClient.getBlobClient(blobName);
184
+
185
+ const downloadBlockBlobResponse = await blobClient.download();
186
+ let writer = fs.createWriteStream(file)
187
+ downloadBlockBlobResponse.readableStreamBody.pipe(writer)
188
+ console.log(`${blobName} downloaded to ${file}`)
189
+
190
+ }
191
+
192
+ /**
193
+ * Gets a blob and returns the content. The idea is that you can get a blob without
194
+ * having to save it to a file and then re-read it. This may be limited in that it
195
+ * can only deal with non-binary content.
196
+ *
197
+ * @param {string} containerName the container to get the blob from
198
+ * @param {string} blobName the name of the blob to get
199
+ * @returns {string} the downloaded blob as
200
+ */
201
+ async getBlob(containerName,blobName) {
202
+ const blobServiceClient = new BlobServiceClient(
203
+ this.host('blob',this.cloudName),
204
+ new StorageSharedKeyCredential(this.storageAccountName, this.storageAccountKey)
205
+ );
206
+ const containerClient = blobServiceClient.getContainerClient(containerName);
207
+ const blobClient = containerClient.getBlobClient(blobName);
208
+
209
+ // Get blob content from position 0 to the end
210
+ // In Node.js, get downloaded data by accessing downloadBlockBlobResponse.readableStreamBody
211
+ const downloadBlockBlobResponse = await blobClient.download();
212
+ const downloaded = (
213
+ await streamToBuffer(downloadBlockBlobResponse.readableStreamBody)
214
+ ).toString(); // FIXME - what happens with binary content?
215
+ // console.log("Downloaded blob content:", downloaded);
216
+ return downloaded
217
+
218
+ }
219
+
220
+ /**
221
+ * Lists the blobs in a specified container, returning an array of the BlobItem object
222
+ *
223
+ * @param {string} containerName
224
+ * @returns Blob[]
225
+ */
226
+ async listBlobs(containerName) {
227
+ const blobServiceClient = new BlobServiceClient(
228
+ this.host('blob',this.cloudName),
229
+ new StorageSharedKeyCredential(this.storageAccountName, this.storageAccountKey)
230
+ );
231
+ const containerClient = blobServiceClient.getContainerClient(containerName);
232
+ let i = 1;
233
+ let blobs = []
234
+ for await (const blob of containerClient.listBlobsFlat()) {
235
+ blobs.push(blob)
236
+ }
237
+
238
+ return blobs
239
+
240
+ }
241
+
242
+
166
243
  }
167
244
 
168
245
  module.exports = AzureStorage
package/src/helpers.js CHANGED
@@ -42,6 +42,15 @@ async function readFile(filePath) {
42
42
  return fs.readFileSync(filePath,{ encoding: 'utf8', flag: 'r' });
43
43
  }
44
44
 
45
+ /**
46
+ * Asynchronously writes input to filename.
47
+ * @param {string} filePath fully qualified path and filename
48
+ * @returns any
49
+ */
50
+ async function writeFile(filePath,data) {
51
+ return fs.writeFileSync(filePath,data,{ encoding: 'utf8' });
52
+ }
53
+
45
54
  /**
46
55
  * Asynchronously reads the contents of a directory and returns the filenames as an array. Optionally,
47
56
  * filters by the extension
@@ -138,6 +147,21 @@ const getResourceId = (url) => {
138
147
  return id
139
148
  }
140
149
 
150
+
151
+ // [Node.js only] A helper method used to read a Node.js readable stream into a Buffer
152
+ async function streamToBuffer(readableStream) {
153
+ return new Promise((resolve, reject) => {
154
+ const chunks = [];
155
+ readableStream.on("data", (data) => {
156
+ chunks.push(data instanceof Buffer ? data : Buffer.from(data));
157
+ });
158
+ readableStream.on("end", () => {
159
+ resolve(Buffer.concat(chunks));
160
+ });
161
+ readableStream.on("error", reject);
162
+ });
163
+ }
164
+
141
165
  module.exports = {
142
166
  getEpochMillis,
143
167
  getResourceId,
@@ -146,7 +170,9 @@ module.exports = {
146
170
  readFile,
147
171
  listFiles,
148
172
  sparkline,
173
+ streamToBuffer,
149
174
  stripNewLines,
150
175
  toTitleCase,
151
- unixTimestamp
176
+ unixTimestamp,
177
+ writeFile
152
178
  }