@pi-r/azure 0.6.0 → 0.6.2
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/README.md +2 -0
- package/client/index.js +63 -42
- package/download/index.js +1 -1
- package/package.json +5 -5
- package/upload/index.js +4 -10
package/README.md
CHANGED
package/client/index.js
CHANGED
|
@@ -7,42 +7,51 @@ const cosmos = require("@azure/cosmos");
|
|
|
7
7
|
const identity = require("@azure/identity");
|
|
8
8
|
const types_1 = require("@e-mc/types");
|
|
9
9
|
const util_1 = require("@e-mc/cloud/util");
|
|
10
|
-
const Module = require("@e-mc/module");
|
|
11
10
|
const Cloud = require("@e-mc/cloud");
|
|
12
11
|
function validateStorage(credential) {
|
|
13
12
|
const env = process.env;
|
|
14
|
-
if (credential.accountName && credential.accountKey || credential.connectionString || credential.sharedAccessSignature || env.AZURE_TENANT_ID && env.AZURE_CLIENT_ID && env.AZURE_CLIENT_SECRET
|
|
13
|
+
if (credential.accountName && credential.accountKey || credential.connectionString || credential.sharedAccessSignature || env.AZURE_TENANT_ID && env.AZURE_CLIENT_ID && env.AZURE_CLIENT_SECRET) {
|
|
15
14
|
return true;
|
|
16
15
|
}
|
|
17
|
-
return
|
|
16
|
+
return Cloud.enabled("process.env.apply" /* KEY_NAME.PROCESS_ENV_APPLY */) && !!((credential.connectionString = env.AZURE_STORAGE_CONNECTION_STRING) || (credential.sharedAccessSignature = env.AZURE_STORAGE_SAS_TOKEN) || (credential.accountName = env.AZURE_STORAGE_ACCOUNT) && (credential.accountKey = env.AZURE_STORAGE_KEY));
|
|
18
17
|
}
|
|
19
18
|
exports.validateStorage = validateStorage;
|
|
20
19
|
function validateDatabase(credential, data) {
|
|
21
|
-
return !!(data.name && data.table && (credential.endpoint && credential.key ||
|
|
20
|
+
return !!(data.name && data.table && (credential.endpoint && credential.key || credential.username && credential.password && (credential.tenantId && credential.clientId || (credential.tenantId = process.env.AZURE_TENANT_ID) && (credential.clientId = process.env.AZURE_CLIENT_ID)) || Cloud.enabled("process.env.apply" /* KEY_NAME.PROCESS_ENV_APPLY */) && (credential.endpoint = process.env.AZURE_COSMOS_ENDPOINT) && (credential.key = process.env.AZURE_COSMOS_KEY)));
|
|
22
21
|
}
|
|
23
22
|
exports.validateDatabase = validateDatabase;
|
|
24
23
|
function createStorageClient(credential) {
|
|
25
|
-
|
|
26
|
-
const { accountName, accountKey, connectionString, sharedAccessSignature } = credential;
|
|
24
|
+
let { accountName, accountKey, connectionString, sharedAccessSignature } = credential;
|
|
27
25
|
if (connectionString) {
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
if (!accountName) {
|
|
27
|
+
credential.accountName = /AccountName=([^;]+);/.exec(connectionString)?.[1];
|
|
28
|
+
}
|
|
29
|
+
return storage.BlobServiceClient.fromConnectionString(connectionString);
|
|
30
30
|
}
|
|
31
|
+
const url = `https://${accountName || process.env.AZURE_STORAGE_ACCOUNT}.blob.core.windows.net`;
|
|
31
32
|
if (sharedAccessSignature) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
if (accountName) {
|
|
34
|
+
if (!Cloud.isURL(sharedAccessSignature)) {
|
|
35
|
+
sharedAccessSignature = url + (!sharedAccessSignature.startsWith('?') ? '?' : '') + sharedAccessSignature;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
credential.accountName || (credential.accountName = /^https:\/\/([a-z\d]+)\./.exec(sharedAccessSignature)?.[1]);
|
|
40
|
+
}
|
|
41
|
+
return new storage.BlobServiceClient(sharedAccessSignature);
|
|
41
42
|
}
|
|
42
|
-
return new BlobServiceClient(
|
|
43
|
+
return new storage.BlobServiceClient(url, accountName && accountKey ? new storage.StorageSharedKeyCredential(accountName, accountKey) : new identity.DefaultAzureCredential());
|
|
43
44
|
}
|
|
44
45
|
exports.createStorageClient = createStorageClient;
|
|
45
46
|
function createDatabaseClient(credential) {
|
|
47
|
+
if (credential.username && credential.password && credential.tenantId && credential.clientId) {
|
|
48
|
+
credential.aadCredentials = new identity.UsernamePasswordCredential(credential.username, credential.password, credential.tenantId, credential.clientId);
|
|
49
|
+
credential = { ...credential };
|
|
50
|
+
delete credential.username;
|
|
51
|
+
delete credential.password;
|
|
52
|
+
delete credential.tenantId;
|
|
53
|
+
delete credential.clientId;
|
|
54
|
+
}
|
|
46
55
|
return new cosmos.CosmosClient(credential);
|
|
47
56
|
}
|
|
48
57
|
exports.createDatabaseClient = createDatabaseClient;
|
|
@@ -102,14 +111,20 @@ async function setBucketWebsite(credential, bucket, options, service = 'azure')
|
|
|
102
111
|
staticWebsite.indexDocument = path.basename(indexPage);
|
|
103
112
|
}
|
|
104
113
|
if ((0, types_1.isString)(indexPath)) {
|
|
105
|
-
staticWebsite.defaultIndexDocumentPath =
|
|
114
|
+
staticWebsite.defaultIndexDocumentPath = Cloud.joinPath(bucket, indexPath);
|
|
106
115
|
}
|
|
107
116
|
if ((0, types_1.isString)(errorPath)) {
|
|
108
|
-
staticWebsite.errorDocument404Path =
|
|
117
|
+
staticWebsite.errorDocument404Path = Cloud.joinPath(bucket, errorPath);
|
|
109
118
|
}
|
|
110
119
|
return createStorageClient.call(this, credential).setProperties({ staticWebsite })
|
|
111
|
-
.then(
|
|
112
|
-
|
|
120
|
+
.then(response => {
|
|
121
|
+
const { requestId, errorCode } = response;
|
|
122
|
+
if (errorCode) {
|
|
123
|
+
this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, ["Bucket configured" /* VAL_CLOUD.CONFIGURE_BUCKET */ + ' with errors', bucket], (0, types_1.errorMessage)("Error code" /* ERR_MESSAGE.ERROR_CODE */, errorCode), { ...Cloud.LOG_CLOUD_WARN });
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, ["Bucket configured" /* VAL_CLOUD.CONFIGURE_BUCKET */, bucket], requestId, { ...Cloud.LOG_CLOUD_COMMAND });
|
|
127
|
+
}
|
|
113
128
|
return true;
|
|
114
129
|
})
|
|
115
130
|
.catch(err => {
|
|
@@ -129,15 +144,15 @@ async function deleteObjectsV2(credential, bucket, recursive = true, service = '
|
|
|
129
144
|
const tasks = [];
|
|
130
145
|
let fileCount = 0;
|
|
131
146
|
for await (const blob of containerClient.listBlobsFlat({ includeUncommitedBlobs: true })) {
|
|
132
|
-
if (
|
|
133
|
-
|
|
147
|
+
if (recursive || !blob.name.includes('/')) {
|
|
148
|
+
tasks.push(containerClient.deleteBlob(blob.name, { versionId: blob.versionId }).catch(() => {
|
|
149
|
+
--fileCount;
|
|
150
|
+
}));
|
|
134
151
|
}
|
|
135
|
-
tasks.push(containerClient.deleteBlob(blob.name, { versionId: blob.versionId }).catch(() => { --fileCount; }));
|
|
136
152
|
}
|
|
137
153
|
fileCount = tasks.length;
|
|
138
154
|
return this.allSettled(tasks, ["Unable to delete blob" /* ERR_AZURE.DELETE_BLOB */, bucket], 64 /* LOG_TYPE.CLOUD */).then(() => {
|
|
139
|
-
|
|
140
|
-
this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, [`Container emptied (${recursive ? 'recursive' : files})`, bucket], recursive ? files : '', { ...Cloud.LOG_CLOUD_COMMAND });
|
|
155
|
+
this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, ['Container emptied' + (recursive ? ' (recursive)' : ''), bucket], fileCount + ' files', { ...Cloud.LOG_CLOUD_COMMAND });
|
|
141
156
|
});
|
|
142
157
|
}
|
|
143
158
|
catch (err) {
|
|
@@ -157,7 +172,7 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
157
172
|
const cacheValue = { value: this.valueOfKey(credential, 'cache'), sessionKey };
|
|
158
173
|
let client;
|
|
159
174
|
const createClient = (name, table) => {
|
|
160
|
-
client || (client = createDatabaseClient.call(this,
|
|
175
|
+
client || (client = createDatabaseClient.call(this, credential));
|
|
161
176
|
return client.database(name).container(table);
|
|
162
177
|
};
|
|
163
178
|
const closeClient = () => client?.dispose();
|
|
@@ -168,17 +183,17 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
168
183
|
closeClient();
|
|
169
184
|
throw (0, util_1.formatError)(item, name ? "Missing database table" /* ERR_DB.TABLE */ : "Missing database name" /* ERR_DB.NAME */);
|
|
170
185
|
}
|
|
171
|
-
const renewCache = ignoreCache === 0;
|
|
172
186
|
const getCache = (value) => {
|
|
173
187
|
if (ignoreCache !== 1) {
|
|
174
|
-
cacheValue.renewCache =
|
|
188
|
+
cacheValue.renewCache = ignoreCache === 0;
|
|
175
189
|
return this.getQueryResult(service, credential, value, cacheValue);
|
|
176
190
|
}
|
|
177
191
|
};
|
|
178
|
-
|
|
192
|
+
cacheValue.exclusiveOf = Array.isArray(ignoreCache) ? ignoreCache : undefined;
|
|
193
|
+
let rows, queryString = caching && ignoreCache !== true ? name + '_' + table + '_' : '';
|
|
179
194
|
if (storedProcedureId && params) {
|
|
180
195
|
const { options } = item;
|
|
181
|
-
if (queryString && (rows = getCache(queryString +=
|
|
196
|
+
if (queryString && (rows = getCache(queryString += Cloud.asString(partitionKey, true) + '_' + storedProcedureId + Cloud.asString(params, true) + Cloud.asString(options, true)))) {
|
|
182
197
|
result[i] = rows;
|
|
183
198
|
continue;
|
|
184
199
|
}
|
|
@@ -190,7 +205,7 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
190
205
|
else if (id) {
|
|
191
206
|
const { options } = item;
|
|
192
207
|
if (queryString) {
|
|
193
|
-
queryString +=
|
|
208
|
+
queryString += Cloud.asString(partitionKey, true) + '_' + id + Cloud.asString(options, true);
|
|
194
209
|
if (!update && (rows = getCache(queryString))) {
|
|
195
210
|
result[i] = rows;
|
|
196
211
|
continue;
|
|
@@ -202,20 +217,26 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
202
217
|
rows = [resource];
|
|
203
218
|
}
|
|
204
219
|
}
|
|
205
|
-
else
|
|
220
|
+
else {
|
|
206
221
|
let { options } = item;
|
|
222
|
+
if (partitionKey) {
|
|
223
|
+
(options || (options = {})).partitionKey = partitionKey;
|
|
224
|
+
}
|
|
207
225
|
if (limit > 0) {
|
|
208
226
|
(options || (options = {})).maxItemCount = limit;
|
|
209
227
|
}
|
|
210
|
-
if (
|
|
211
|
-
|
|
212
|
-
|
|
228
|
+
if (query || (0, types_1.isPlainObject)(options)) {
|
|
229
|
+
if (queryString && (rows = getCache(queryString += (query ? Cloud.asString(query, true) : '') + Cloud.asString(options, true)))) {
|
|
230
|
+
result[i] = rows;
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
const items = createClient(name, table).items;
|
|
234
|
+
({ resources: rows } = await (query ? items.query(query, options).fetchAll() : items.readAll(options).fetchAll()));
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
closeClient();
|
|
238
|
+
throw (0, util_1.formatError)(item, "Missing database query" /* ERR_DB.QUERY */);
|
|
213
239
|
}
|
|
214
|
-
rows = (await createClient(name, table).items.query(query, options).fetchAll()).resources;
|
|
215
|
-
}
|
|
216
|
-
else {
|
|
217
|
-
closeClient();
|
|
218
|
-
throw (0, util_1.formatError)(item, "Missing database query" /* ERR_DB.QUERY */);
|
|
219
240
|
}
|
|
220
241
|
result[i] = this.setQueryResult(service, credential, queryString, rows, cacheValue);
|
|
221
242
|
}
|
package/download/index.js
CHANGED
|
@@ -20,7 +20,7 @@ function download(credential, service = 'azure') {
|
|
|
20
20
|
callback(null, value);
|
|
21
21
|
const deleteObject = target.deleteObject;
|
|
22
22
|
if (deleteObject) {
|
|
23
|
-
blobClient.delete((0, types_1.isPlainObject)(deleteObject)
|
|
23
|
+
blobClient.delete((0, types_1.isPlainObject)(deleteObject) ? (deleteObject.abortSignal = this.signal, deleteObject) : { abortSignal: this.signal })
|
|
24
24
|
.then(() => this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, "Delete success" /* VAL_CLOUD.DELETE_FILE */, location, { ...Cloud.LOG_CLOUD_DELETE }))
|
|
25
25
|
.catch((err) => {
|
|
26
26
|
if (!(err instanceof Error && err.code === 'BlobNotFound')) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-r/azure",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"description": "Azure cloud functions for E-mc.",
|
|
5
5
|
"main": "client/index.js",
|
|
6
6
|
"publishConfig": {
|
|
@@ -20,11 +20,11 @@
|
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"homepage": "https://github.com/anpham6/pi-r#readme",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@e-mc/cloud": "^0.8.
|
|
24
|
-
"@e-mc/module": "^0.8.
|
|
25
|
-
"@e-mc/types": "^0.8.
|
|
23
|
+
"@e-mc/cloud": "^0.8.2",
|
|
24
|
+
"@e-mc/module": "^0.8.2",
|
|
25
|
+
"@e-mc/types": "^0.8.2",
|
|
26
26
|
"@azure/cosmos": "^4.0.0",
|
|
27
|
-
"@azure/identity": "^4.0.
|
|
27
|
+
"@azure/identity": "^4.0.1",
|
|
28
28
|
"@azure/storage-blob": "^12.17.0"
|
|
29
29
|
}
|
|
30
30
|
}
|
package/upload/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const path = require("path");
|
|
4
|
-
const fs = require("fs");
|
|
5
4
|
const util_1 = require("@e-mc/cloud/util");
|
|
6
5
|
const types_1 = require("@e-mc/types");
|
|
7
6
|
const Module = require("@e-mc/module");
|
|
@@ -84,15 +83,10 @@ function upload(credential, service = 'azure') {
|
|
|
84
83
|
const Body = [data.buffer];
|
|
85
84
|
const ContentType = [contentType];
|
|
86
85
|
if (fileGroup) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
catch (err) {
|
|
93
|
-
addLog(err);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
86
|
+
const [key, body, type] = (0, util_1.createKeyAndBody)(filename, fileGroup, addLog);
|
|
87
|
+
Key.push(...key);
|
|
88
|
+
Body.push(...body);
|
|
89
|
+
ContentType.push(...type);
|
|
96
90
|
}
|
|
97
91
|
for (let i = 0; i < Key.length; ++i) {
|
|
98
92
|
const first = i === 0;
|