@beauraines/node-helpers 4.3.0 → 5.1.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 +18 -0
- package/eslint.config.mjs +1 -0
- package/index.js +4 -2
- package/package.json +1 -1
- package/src/ado.js +1 -1
- package/src/azure.js +133 -29
- package/src/azure.test.js +85 -5
- package/src/cli-arguments.js +78 -0
- package/src/credentials.js +0 -1
- package/src/database.js +0 -1
- package/src/database.test.js +0 -1
- package/src/helpers.js +3 -3
- package/src/jira.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,24 @@
|
|
|
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
|
+
## [5.1.0](https://github.com/beauraines/node-helpers/compare/v5.0.0...v5.1.0) (2024-10-16)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* adds cli argument module ([#155](https://github.com/beauraines/node-helpers/issues/155)) ([b7943b6](https://github.com/beauraines/node-helpers/commit/b7943b6cf55a221ecc1a55afec2ab9505ed88347))
|
|
11
|
+
|
|
12
|
+
## [5.0.0](https://github.com/beauraines/node-helpers/compare/v4.3.0...v5.0.0) (2024-10-14)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### ⚠ BREAKING CHANGES
|
|
16
|
+
|
|
17
|
+
* Updates and adds Storage Queue functions (#154)
|
|
18
|
+
|
|
19
|
+
### Features
|
|
20
|
+
|
|
21
|
+
* Updates and adds Storage Queue functions ([#154](https://github.com/beauraines/node-helpers/issues/154)) ([7301e37](https://github.com/beauraines/node-helpers/commit/7301e37e5e819a5d9ac222602a5e4f7be8e0816c))
|
|
22
|
+
|
|
5
23
|
## [4.3.0](https://github.com/beauraines/node-helpers/compare/v4.2.1...v4.3.0) (2024-10-14)
|
|
6
24
|
|
|
7
25
|
|
package/eslint.config.mjs
CHANGED
package/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
const ado = require("./src/ado");
|
|
3
3
|
const AzureStorage = require("./src/azure")
|
|
4
|
+
const cliArguments = require('./src/cli-arguments.js');
|
|
4
5
|
const config = require('./src/config.js')
|
|
5
6
|
const credentials = require("./src/credentials.js");
|
|
6
7
|
const database = require("./src/database");
|
|
@@ -8,12 +9,13 @@ const helpers = require("./src/helpers");
|
|
|
8
9
|
const jira = require("./src/jira");
|
|
9
10
|
|
|
10
11
|
module.exports = {
|
|
12
|
+
ado,
|
|
11
13
|
AzureStorage,
|
|
14
|
+
cliArguments,
|
|
12
15
|
config,
|
|
13
16
|
credentials,
|
|
14
17
|
database,
|
|
15
18
|
helpers,
|
|
16
|
-
jira
|
|
17
|
-
ado
|
|
19
|
+
jira
|
|
18
20
|
}
|
|
19
21
|
|
package/package.json
CHANGED
package/src/ado.js
CHANGED
|
@@ -82,7 +82,7 @@ async function getDistinctParentWorkItems(workItemAPI, ids) {
|
|
|
82
82
|
async function callRestApi(url, username, token) {
|
|
83
83
|
// console.log(url) // Only display this in verbose mode
|
|
84
84
|
// Bearer token format for ADO
|
|
85
|
-
|
|
85
|
+
|
|
86
86
|
let bearerToken = Buffer.from(`${username}:${token}`).toString('base64');
|
|
87
87
|
|
|
88
88
|
let response;
|
package/src/azure.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const dayjs = require('dayjs')
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
const { streamToBuffer } = require('./helpers.js')
|
|
4
|
-
const { BlobServiceClient, StorageSharedKeyCredential } = require("@azure/storage-blob");
|
|
5
|
-
const {
|
|
4
|
+
const { BlobServiceClient, StorageSharedKeyCredential:BlobStorageSharedKeyCredential } = require("@azure/storage-blob");
|
|
5
|
+
const { QueueServiceClient ,StorageSharedKeyCredential:QueueStorageSharedKeyCredential } = require("@azure/storage-queue");
|
|
6
6
|
var path = require('path');
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -74,44 +74,148 @@ class AzureStorage {
|
|
|
74
74
|
/**
|
|
75
75
|
* Sends a message to the specified storage queue. The messages are given a TTL based upon the
|
|
76
76
|
* class's `queueMessageTTLSeconds` value.
|
|
77
|
+
*
|
|
78
|
+
* The response includes the `expiresOn`, `messageId` and `requestId` as well as a status code in
|
|
79
|
+
* `_response.status`
|
|
80
|
+
*
|
|
77
81
|
* @param {string} queueUrl The URL to the storage queue
|
|
78
82
|
* @param {string} messageContent The message to send to the queue
|
|
83
|
+
*
|
|
84
|
+
* @returns {Object} sendMessageResponse
|
|
79
85
|
*/
|
|
80
|
-
async sendMessageToQueue(
|
|
86
|
+
async sendMessageToQueue(queueName, messageContent) {
|
|
81
87
|
try {
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
new
|
|
88
|
+
const queueServiceClient = new QueueServiceClient(
|
|
89
|
+
this.host('queue',this.cloudName),
|
|
90
|
+
new QueueStorageSharedKeyCredential(this.storageAccountName, this.storageAccountKey)
|
|
85
91
|
);
|
|
92
|
+
|
|
93
|
+
const queueClient = queueServiceClient.getQueueClient(queueName);
|
|
94
|
+
|
|
86
95
|
let queueOptions = {
|
|
87
96
|
messageTimeToLive: this.queueMessageTTLSeconds
|
|
88
97
|
};
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
98
|
+
|
|
99
|
+
let sendMessageResponse = await queueClient.sendMessage(messageContent,queueOptions);
|
|
100
|
+
sendMessageResponse.status = sendMessageResponse._response.status;
|
|
101
|
+
delete sendMessageResponse._response;
|
|
102
|
+
return sendMessageResponse;
|
|
103
|
+
|
|
94
104
|
} catch (error) {
|
|
95
|
-
console.
|
|
105
|
+
console.log(error.message)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Gets any number of messages from the queue. The messages themselves are in the property
|
|
111
|
+
* `receivedMessageItems[]messageText` Use the options to control the number of messages returned,
|
|
112
|
+
* defaults are 1 with a 30 second timeout. You will need the `messageId` and `popReceipt` to
|
|
113
|
+
* delete the message after processing.
|
|
114
|
+
*
|
|
115
|
+
* @param {string} queueName The name of the queue
|
|
116
|
+
* @param {object} options Any options such as `numberOfMessages` or `visibilityTimeout`
|
|
117
|
+
* @returns {object} The queue messages response
|
|
118
|
+
*/
|
|
119
|
+
async getQueueMessages(queueName,options) {
|
|
120
|
+
const queueServiceClient = new QueueServiceClient(
|
|
121
|
+
this.host('queue',this.cloudName),
|
|
122
|
+
new QueueStorageSharedKeyCredential(this.storageAccountName, this.storageAccountKey)
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
const queueClient = queueServiceClient.getQueueClient(queueName);
|
|
126
|
+
const receivedMessagesResponse = await queueClient.receiveMessages(options);
|
|
127
|
+
return receivedMessagesResponse;
|
|
128
|
+
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Deletes a message, by `messageId` and `popReceipt` from a named queue
|
|
134
|
+
*
|
|
135
|
+
* @param {string} queueName The name of the queue that has the message
|
|
136
|
+
* @param {string} messageId The message id to be deleted
|
|
137
|
+
* @param {string} popReceipt The popReceipt of teh message to be deleted
|
|
138
|
+
* @returns object with a nothing really useful
|
|
139
|
+
*/
|
|
140
|
+
async deleteQueueMessage(queueName,messageId,popReceipt) {
|
|
141
|
+
const queueServiceClient = new QueueServiceClient(
|
|
142
|
+
this.host('queue',this.cloudName),
|
|
143
|
+
new QueueStorageSharedKeyCredential(this.storageAccountName, this.storageAccountKey)
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
const queueClient = queueServiceClient.getQueueClient(queueName);
|
|
147
|
+
const deleteMessageResponse = await queueClient.deleteMessage(messageId,popReceipt);
|
|
148
|
+
return deleteMessageResponse
|
|
149
|
+
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Gets the named queues properties, which includes the approximateMessagesCount
|
|
154
|
+
*
|
|
155
|
+
* @param {string} queueName
|
|
156
|
+
*
|
|
157
|
+
* @returns {Object} the queues properties
|
|
158
|
+
*/
|
|
159
|
+
async getQueueProperties(queueName) {
|
|
160
|
+
const queueServiceClient = new QueueServiceClient(
|
|
161
|
+
this.host('queue',this.cloudName),
|
|
162
|
+
new QueueStorageSharedKeyCredential(this.storageAccountName, this.storageAccountKey)
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
const queueClient = queueServiceClient.getQueueClient(queueName);
|
|
166
|
+
const properties = await queueClient.getProperties();
|
|
167
|
+
return properties
|
|
168
|
+
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Lists storage queues in the storage account
|
|
173
|
+
*
|
|
174
|
+
* @returns Array
|
|
175
|
+
*/
|
|
176
|
+
async listsQueues() {
|
|
177
|
+
try {
|
|
178
|
+
const queueServiceClient = new QueueServiceClient(
|
|
179
|
+
this.host('queue',this.cloudName),
|
|
180
|
+
new QueueStorageSharedKeyCredential(this.storageAccountName, this.storageAccountKey)
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
let queues = []
|
|
184
|
+
for await (const queue of queueServiceClient.listQueues()) {
|
|
185
|
+
queues.push(queue)
|
|
96
186
|
}
|
|
187
|
+
|
|
188
|
+
return queues;
|
|
189
|
+
|
|
190
|
+
} catch (error) {
|
|
191
|
+
console.log(error.message)
|
|
97
192
|
}
|
|
193
|
+
}
|
|
98
194
|
|
|
99
195
|
/**
|
|
100
|
-
* Gets a SAS
|
|
196
|
+
* Gets a SAS URL for the storage queue
|
|
101
197
|
* .
|
|
102
|
-
* @param {string}
|
|
198
|
+
* @param {string} queueName The name of the storage queue
|
|
103
199
|
* @param {object} options Should include `permissions: "raup"` or some combination thereof Any additional options supported. https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas
|
|
200
|
+
*
|
|
201
|
+
* @returns {string} SAS URL for the specified queue
|
|
104
202
|
*/
|
|
105
|
-
getStorageQueueSignedURL(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
203
|
+
getStorageQueueSignedURL(queueName,options) {
|
|
204
|
+
const queueServiceClient = new QueueServiceClient(
|
|
205
|
+
this.host('queue',this.cloudName),
|
|
206
|
+
new QueueStorageSharedKeyCredential(this.storageAccountName, this.storageAccountKey)
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
const queueClient = queueServiceClient.getQueueClient(queueName);
|
|
210
|
+
|
|
112
211
|
options = {
|
|
113
|
-
|
|
114
|
-
|
|
212
|
+
startsOn: dayjs().toDate(),
|
|
213
|
+
expiresOn: dayjs().add(this.tokenExpiry,'minutes'),
|
|
214
|
+
...options
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (!options.permissions || !options.expiresOn) {
|
|
218
|
+
throw new Error("Must provide 'permissions' and 'expiresOn' for Queue SAS generation when 'identifier' is not provided");
|
|
115
219
|
}
|
|
116
220
|
|
|
117
221
|
return queueClient.generateSasUrl(options)
|
|
@@ -130,7 +234,7 @@ getStorageQueueSignedURL(queueUrl,options) {
|
|
|
130
234
|
|
|
131
235
|
const blobServiceClient = new BlobServiceClient(
|
|
132
236
|
this.host('blob',this.cloudName),
|
|
133
|
-
new
|
|
237
|
+
new BlobStorageSharedKeyCredential(this.storageAccountName, this.storageAccountKey)
|
|
134
238
|
);
|
|
135
239
|
const containerClient = blobServiceClient.getContainerClient(containerName);
|
|
136
240
|
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
|
@@ -158,7 +262,7 @@ getStorageQueueSignedURL(queueUrl,options) {
|
|
|
158
262
|
async uploadBlobFromFile(containerName,file) {
|
|
159
263
|
const blobServiceClient = new BlobServiceClient(
|
|
160
264
|
this.host('blob',this.cloudName),
|
|
161
|
-
new
|
|
265
|
+
new BlobStorageSharedKeyCredential(this.storageAccountName, this.storageAccountKey)
|
|
162
266
|
);
|
|
163
267
|
const containerClient = blobServiceClient.getContainerClient(containerName);
|
|
164
268
|
|
|
@@ -194,7 +298,7 @@ getStorageQueueSignedURL(queueUrl,options) {
|
|
|
194
298
|
async downloadBlobToFile(containerName,blobName,file) {
|
|
195
299
|
const blobServiceClient = new BlobServiceClient(
|
|
196
300
|
this.host('blob',this.cloudName),
|
|
197
|
-
new
|
|
301
|
+
new BlobStorageSharedKeyCredential(this.storageAccountName, this.storageAccountKey)
|
|
198
302
|
);
|
|
199
303
|
const containerClient = blobServiceClient.getContainerClient(containerName);
|
|
200
304
|
const blobClient = containerClient.getBlobClient(blobName);
|
|
@@ -219,7 +323,7 @@ getStorageQueueSignedURL(queueUrl,options) {
|
|
|
219
323
|
async getBlob(containerName,blobName) {
|
|
220
324
|
const blobServiceClient = new BlobServiceClient(
|
|
221
325
|
this.host('blob',this.cloudName),
|
|
222
|
-
new
|
|
326
|
+
new BlobStorageSharedKeyCredential(this.storageAccountName, this.storageAccountKey)
|
|
223
327
|
);
|
|
224
328
|
const containerClient = blobServiceClient.getContainerClient(containerName);
|
|
225
329
|
const blobClient = containerClient.getBlobClient(blobName);
|
|
@@ -246,7 +350,7 @@ getStorageQueueSignedURL(queueUrl,options) {
|
|
|
246
350
|
async getBinaryBlob(containerName,blobName) {
|
|
247
351
|
const blobServiceClient = new BlobServiceClient(
|
|
248
352
|
this.host('blob',this.cloudName),
|
|
249
|
-
new
|
|
353
|
+
new BlobStorageSharedKeyCredential(this.storageAccountName, this.storageAccountKey)
|
|
250
354
|
);
|
|
251
355
|
const containerClient = blobServiceClient.getContainerClient(containerName);
|
|
252
356
|
const blobClient = containerClient.getBlobClient(blobName);
|
|
@@ -268,7 +372,7 @@ getStorageQueueSignedURL(queueUrl,options) {
|
|
|
268
372
|
async listBlobs(containerName) {
|
|
269
373
|
const blobServiceClient = new BlobServiceClient(
|
|
270
374
|
this.host('blob',this.cloudName),
|
|
271
|
-
new
|
|
375
|
+
new BlobStorageSharedKeyCredential(this.storageAccountName, this.storageAccountKey)
|
|
272
376
|
);
|
|
273
377
|
const containerClient = blobServiceClient.getContainerClient(containerName);
|
|
274
378
|
let blobs = []
|
package/src/azure.test.js
CHANGED
|
@@ -77,8 +77,6 @@ describe('Azure Storage module', () => {
|
|
|
77
77
|
expect(success)
|
|
78
78
|
})
|
|
79
79
|
|
|
80
|
-
it.todo('should send a message to the storage queue')
|
|
81
|
-
|
|
82
80
|
it.skip('should get a blob from azure storage', async () =>{
|
|
83
81
|
const account = "devstoreaccount1";
|
|
84
82
|
const accountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
|
|
@@ -102,9 +100,6 @@ describe('Azure Storage module', () => {
|
|
|
102
100
|
expect(fileExists(file))
|
|
103
101
|
})
|
|
104
102
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
103
|
it.skip('should list blobs from azure storage', async () => {
|
|
109
104
|
const account = "devstoreaccount1";
|
|
110
105
|
const accountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
|
|
@@ -118,4 +113,89 @@ describe('Azure Storage module', () => {
|
|
|
118
113
|
expect(blobs.filter(b => b.name == blobName).length).toBe(1)
|
|
119
114
|
})
|
|
120
115
|
|
|
116
|
+
it.skip('should send a message to the storage queue', async () => {
|
|
117
|
+
const account = "devstoreaccount1";
|
|
118
|
+
const accountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
|
|
119
|
+
let azure = new AzureStorage(account,accountKey,{cloudName:'Azurite'})
|
|
120
|
+
const message = {foo:"bar"}
|
|
121
|
+
const queueName = 'node-helpers-testing'
|
|
122
|
+
let response = await azure.sendMessageToQueue(queueName,JSON.stringify(message))
|
|
123
|
+
expect(response.status).toBe(201)
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
it.skip('should error when generating a SAS URL for the storage queue without permissions', async () => {
|
|
127
|
+
const account = "devstoreaccount1";
|
|
128
|
+
const accountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
|
|
129
|
+
let azure = new AzureStorage(account,accountKey,{cloudName:'Azurite'})
|
|
130
|
+
const queueName = 'node-helpers-testing'
|
|
131
|
+
expect(() => azure.getStorageQueueSignedURL(queueName)).toThrow();
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
it.skip('should generate a SAS URL for the storage queue', async () => {
|
|
135
|
+
const account = "devstoreaccount1";
|
|
136
|
+
const accountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
|
|
137
|
+
let azure = new AzureStorage(account,accountKey,{cloudName:'Azurite'})
|
|
138
|
+
const queueName = 'node-helpers-testing'
|
|
139
|
+
const options = {permissions:"r"}
|
|
140
|
+
let response = await azure.getStorageQueueSignedURL(queueName,options)
|
|
141
|
+
expect(response.includes('sp=r')).toBe(true) // Read permissions
|
|
142
|
+
expect(response.includes('http://127.0.0.1:10001/devstoreaccount1/node-helpers-testing')).toBe(true) // Azurite URL for storage queue
|
|
143
|
+
// TODO compute the expected expiration time
|
|
144
|
+
// expect(response.includes('se=2024-10-13T23%3A59%3A02Z')).toBe(true) // Expiration time defaults to 30 minutes
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
it.skip('should list the queues in the storage account', async () => {
|
|
149
|
+
const account = "devstoreaccount1";
|
|
150
|
+
const accountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
|
|
151
|
+
let azure = new AzureStorage(account,accountKey,{cloudName:'Azurite'})
|
|
152
|
+
const queueName = 'node-helpers-testing';
|
|
153
|
+
let queues = await azure.listsQueues();
|
|
154
|
+
expect(queues.map(x => x.name).indexOf(queueName)).toBeGreaterThan(-1)
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
it.skip('should get the queue properties', async () => {
|
|
158
|
+
const account = "devstoreaccount1";
|
|
159
|
+
const accountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
|
|
160
|
+
let azure = new AzureStorage(account,accountKey,{cloudName:'Azurite'})
|
|
161
|
+
const queueName = 'node-helpers-testing';
|
|
162
|
+
let properties = await azure.getQueueProperties(queueName);
|
|
163
|
+
expect(properties.approximateMessagesCount).toBeGreaterThan(0)
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
it.skip('should get a message from the queue', async () => {
|
|
167
|
+
const account = "devstoreaccount1";
|
|
168
|
+
const accountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
|
|
169
|
+
let azure = new AzureStorage(account,accountKey,{cloudName:'Azurite'})
|
|
170
|
+
const queueName = 'node-helpers-testing';
|
|
171
|
+
let response = await azure.getQueueMessages(queueName);
|
|
172
|
+
const expectedMessage = {foo:"bar"}
|
|
173
|
+
expect(response._response.status).toBe(200)
|
|
174
|
+
expect(response.receivedMessageItems.length).toBeGreaterThan(0)
|
|
175
|
+
expect(response.receivedMessageItems[0].messageText).toBe(JSON.stringify(expectedMessage))
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
it.skip('should get multiple messages from the queue', async () => {
|
|
179
|
+
const account = "devstoreaccount1";
|
|
180
|
+
const accountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
|
|
181
|
+
let azure = new AzureStorage(account,accountKey,{cloudName:'Azurite'})
|
|
182
|
+
const queueName = 'node-helpers-testing';
|
|
183
|
+
let response = await azure.getQueueMessages(queueName,{numberOfMessages:5});
|
|
184
|
+
expect(response._response.status).toBe(200)
|
|
185
|
+
expect(response.receivedMessageItems.length).toBeGreaterThan(1)
|
|
186
|
+
expect(response.receivedMessageItems.length).toBeLessThan(6)
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
it.skip('should delete a message from the queue',async () => {
|
|
190
|
+
const account = "devstoreaccount1";
|
|
191
|
+
const accountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
|
|
192
|
+
let azure = new AzureStorage(account,accountKey,{cloudName:'Azurite'})
|
|
193
|
+
const queueName = 'node-helpers-testing';
|
|
194
|
+
expect(() => azure.deleteQueueMessage(queueName,undefined,undefined)).toThrow() // popReceipt cannot be null
|
|
195
|
+
let addedMessage = await azure.sendMessageToQueue(queueName,'abc123')
|
|
196
|
+
let response = await azure.deleteQueueMessage(queueName,addedMessage.messageId,addedMessage.popReceipt);
|
|
197
|
+
expect(response.errorCode).toBe(undefined)
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
|
|
121
201
|
})
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses command-line parameters and returns an array of the parameters. This is really getting the
|
|
3
|
+
* "arguments" passed from the command-line, but there is no additional parsing or formatting, so
|
|
4
|
+
* this is best suited to just parameters. You could handle each element in the array yourself for
|
|
5
|
+
* involved processing
|
|
6
|
+
*
|
|
7
|
+
* `node script.js beau 42`
|
|
8
|
+
*
|
|
9
|
+
* returns
|
|
10
|
+
* `[ 'beau', '42' ]`
|
|
11
|
+
*
|
|
12
|
+
* *
|
|
13
|
+
* @returns Array
|
|
14
|
+
*/
|
|
15
|
+
const getParameters = () => {
|
|
16
|
+
// process.argv is an array where:
|
|
17
|
+
// - The first element is the path to the Node.js executable (e.g., '/usr/local/bin/node')
|
|
18
|
+
// - The second element is the path to the script file (e.g., '/path/to/script.js')
|
|
19
|
+
// - The subsequent elements are the command-line arguments
|
|
20
|
+
|
|
21
|
+
// Get the arguments starting from the third element
|
|
22
|
+
const args = process.argv.slice(2).length > 0 ? process.argv.slice(2) : []
|
|
23
|
+
return args
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Parses named command-line arguments. This only supports long-named arguments prefixed with a `--`.
|
|
28
|
+
* Short arguments .e.g. `-d` are not supported. The value can either be space separated or with an
|
|
29
|
+
* equals sign
|
|
30
|
+
*
|
|
31
|
+
* `node name-arguments.js --age=42 --name=Beau`
|
|
32
|
+
*
|
|
33
|
+
* Using this function this will return
|
|
34
|
+
*
|
|
35
|
+
* { age: '42', name: 'Beau' }
|
|
36
|
+
*
|
|
37
|
+
*
|
|
38
|
+
* @returns Object
|
|
39
|
+
*/
|
|
40
|
+
const getNamedArguments = () => {
|
|
41
|
+
const args = {};
|
|
42
|
+
|
|
43
|
+
const argv =process.argv;
|
|
44
|
+
// Start from index 2 to skip the node executable and script file paths
|
|
45
|
+
for (let i = 2; i < argv.length; i++) {
|
|
46
|
+
let arg = argv[i];
|
|
47
|
+
|
|
48
|
+
if (arg.startsWith('--')) {
|
|
49
|
+
// Remove the leading --
|
|
50
|
+
arg = arg.slice(2);
|
|
51
|
+
|
|
52
|
+
// Handle --key=value
|
|
53
|
+
if (arg.includes('=')) {
|
|
54
|
+
const [key, value] = arg.split('=');
|
|
55
|
+
args[key] = value;
|
|
56
|
+
} else {
|
|
57
|
+
// Handle --key value
|
|
58
|
+
const key = arg;
|
|
59
|
+
const value = argv[i + 1];
|
|
60
|
+
|
|
61
|
+
if (!value || value.startsWith('--')) {
|
|
62
|
+
args[key] = true; // For flags without values
|
|
63
|
+
} else {
|
|
64
|
+
args[key] = value;
|
|
65
|
+
i++; // Skip the next item as it's the value for this key
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return args;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
module.exports = {
|
|
76
|
+
getNamedArguments,
|
|
77
|
+
getParameters
|
|
78
|
+
}
|
package/src/credentials.js
CHANGED
package/src/database.js
CHANGED
package/src/database.test.js
CHANGED
package/src/helpers.js
CHANGED
|
@@ -137,7 +137,7 @@ function getEpochMillis() {
|
|
|
137
137
|
*
|
|
138
138
|
* @returns
|
|
139
139
|
*/
|
|
140
|
-
|
|
140
|
+
|
|
141
141
|
function sparkline(data,label,options) {
|
|
142
142
|
|
|
143
143
|
options = {
|
|
@@ -192,11 +192,11 @@ async function streamToBuffer(readableStream) {
|
|
|
192
192
|
return new Promise((resolve, reject) => {
|
|
193
193
|
const chunks = [];
|
|
194
194
|
readableStream.on("data", (data) => {
|
|
195
|
-
|
|
195
|
+
|
|
196
196
|
chunks.push(data instanceof Buffer ? data : Buffer.from(data));
|
|
197
197
|
});
|
|
198
198
|
readableStream.on("end", () => {
|
|
199
|
-
|
|
199
|
+
|
|
200
200
|
resolve(Buffer.concat(chunks));
|
|
201
201
|
});
|
|
202
202
|
readableStream.on("error", reject);
|
package/src/jira.js
CHANGED