@beauraines/node-helpers 2.7.1 → 2.8.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 +14 -0
- package/README.md +19 -0
- package/package.json +2 -1
- package/src/azure.js +55 -1
- package/src/helpers.js +27 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
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.8.0](https://github.com/beauraines/node-helpers/compare/v2.7.1...v2.8.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:** new getBlob function ([876716b](https://github.com/beauraines/node-helpers/commit/876716b8256b090a2eadf45c1d03b097362b2eb2))
|
|
12
|
+
* **helper:** adds file write helper ([9e727e9](https://github.com/beauraines/node-helpers/commit/9e727e9ffe51525d2a73fa66ea933c1804304729))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* **deps:** bump node-fetch from 2.6.11 to 2.6.12 ([786f458](https://github.com/beauraines/node-helpers/commit/786f458fbf0c03fd9462ab67db558c5646afb62e))
|
|
18
|
+
|
|
5
19
|
### [2.7.1](https://github.com/beauraines/node-helpers/compare/v2.7.0...v2.7.1) (2023-06-14)
|
|
6
20
|
|
|
7
21
|
## [2.7.0](https://github.com/beauraines/node-helpers/compare/v2.6.1...v2.7.0) (2023-06-14)
|
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.
|
|
3
|
+
"version": "2.8.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 {
|
|
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,56 @@ 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
|
+
|
|
166
220
|
}
|
|
167
221
|
|
|
168
222
|
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
|
}
|