@pi-r/azure 0.10.3 → 0.11.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/client/index.js +49 -20
- package/download/index.js +26 -15
- package/package.json +6 -6
- package/upload/index.js +29 -29
package/client/index.js
CHANGED
|
@@ -10,6 +10,7 @@ exports.setBucketWebsite = setBucketWebsite;
|
|
|
10
10
|
exports.deleteObjects = deleteObjects;
|
|
11
11
|
exports.deleteObjectsV2 = deleteObjectsV2;
|
|
12
12
|
exports.deleteObjectsV3 = deleteObjectsV3;
|
|
13
|
+
exports.copyObject = copyObject;
|
|
13
14
|
exports.executeQuery = executeQuery;
|
|
14
15
|
exports.executeBatchQuery = executeBatchQuery;
|
|
15
16
|
const path = require("node:path");
|
|
@@ -19,11 +20,15 @@ const identity = require("@azure/identity");
|
|
|
19
20
|
const Cloud = require("@e-mc/cloud");
|
|
20
21
|
const types_1 = require("@e-mc/types");
|
|
21
22
|
const util_1 = require("@e-mc/cloud/util");
|
|
22
|
-
function
|
|
23
|
+
function isEnvironmentCredential() {
|
|
23
24
|
const env = process.env;
|
|
24
|
-
|
|
25
|
+
return !!(env.AZURE_TENANT_ID && env.AZURE_CLIENT_ID && (env.AZURE_CLIENT_SECRET || env.AZURE_CLIENT_CERTIFICATE_PATH));
|
|
26
|
+
}
|
|
27
|
+
function validateStorage(credential) {
|
|
28
|
+
if (credential.accountName && (credential.accountKey || credential.accountSas) || credential.connectionString || credential.sharedAccessSignature || isEnvironmentCredential()) {
|
|
25
29
|
return true;
|
|
26
30
|
}
|
|
31
|
+
const env = process.env;
|
|
27
32
|
return Cloud.enabled("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));
|
|
28
33
|
}
|
|
29
34
|
function validateDatabase(credential, data) {
|
|
@@ -59,6 +64,9 @@ function createStorageClient(credential) {
|
|
|
59
64
|
else if (accountName && accountKey) {
|
|
60
65
|
serviceCredential = new storage.StorageSharedKeyCredential(accountName, accountKey);
|
|
61
66
|
}
|
|
67
|
+
else if (isEnvironmentCredential()) {
|
|
68
|
+
serviceCredential = new identity.EnvironmentCredential();
|
|
69
|
+
}
|
|
62
70
|
else {
|
|
63
71
|
serviceCredential = new identity.DefaultAzureCredential(credential.defaultAzureOptions);
|
|
64
72
|
}
|
|
@@ -73,12 +81,15 @@ function createDatabaseClient(credential) {
|
|
|
73
81
|
delete credential.tenantId;
|
|
74
82
|
delete credential.clientId;
|
|
75
83
|
}
|
|
84
|
+
else if (isEnvironmentCredential()) {
|
|
85
|
+
credential.aadCredentials = new identity.EnvironmentCredential();
|
|
86
|
+
}
|
|
76
87
|
return new cosmos.CosmosClient(credential);
|
|
77
88
|
}
|
|
78
|
-
async function createBucket(credential, bucket, publicRead, service =
|
|
89
|
+
async function createBucket(credential, bucket, publicRead, service = "azure") {
|
|
79
90
|
return createBucketV2.call(this, credential, bucket, publicRead ? 'blob' : 'container', undefined, service);
|
|
80
91
|
}
|
|
81
|
-
async function createBucketV2(credential, bucket, access, options, service =
|
|
92
|
+
async function createBucketV2(credential, bucket, access, options, service = "azure") {
|
|
82
93
|
switch (access) {
|
|
83
94
|
case 'blob':
|
|
84
95
|
case 'container':
|
|
@@ -87,10 +98,10 @@ async function createBucketV2(credential, bucket, access, options, service = 'az
|
|
|
87
98
|
access = undefined;
|
|
88
99
|
break;
|
|
89
100
|
}
|
|
90
|
-
const containerClient = createStorageClient
|
|
101
|
+
const containerClient = createStorageClient(credential).getContainerClient(bucket);
|
|
91
102
|
const setAccessPolicy = async () => {
|
|
92
103
|
return containerClient.setAccessPolicy(access).catch((err) => {
|
|
93
|
-
this.formatMessage(64, service, ["Unable to configure container", bucket], err,
|
|
104
|
+
this.formatMessage(64, service, ["Unable to configure container", bucket], err, Cloud.optionsLogMessage('WARN'));
|
|
94
105
|
});
|
|
95
106
|
};
|
|
96
107
|
if (await containerClient.exists().catch(() => false)) {
|
|
@@ -108,25 +119,25 @@ async function createBucketV2(credential, bucket, access, options, service = 'az
|
|
|
108
119
|
.then(response => {
|
|
109
120
|
const { requestId, errorCode } = response;
|
|
110
121
|
if (errorCode) {
|
|
111
|
-
this.formatMessage(64, service, ['Container created with errors', bucket], (0, types_1.errorMessage)("Error code", errorCode),
|
|
122
|
+
this.formatMessage(64, service, ['Container created with errors', bucket], (0, types_1.errorMessage)("Error code", errorCode), Cloud.optionsLogMessage('WARN'));
|
|
112
123
|
}
|
|
113
124
|
else {
|
|
114
|
-
this.formatMessage(64, service, ['Container created', bucket], requestId,
|
|
125
|
+
this.formatMessage(64, service, ['Container created', bucket], requestId, Cloud.optionsLogMessage('COMMAND'));
|
|
115
126
|
}
|
|
116
127
|
return true;
|
|
117
128
|
})
|
|
118
129
|
.catch(async (err) => {
|
|
119
|
-
if (
|
|
130
|
+
if ((0, types_1.isErrorCode)(err, 'ContainerAlreadyExists')) {
|
|
120
131
|
if (access) {
|
|
121
132
|
await setAccessPolicy();
|
|
122
133
|
}
|
|
123
134
|
return true;
|
|
124
135
|
}
|
|
125
|
-
this.formatFail(64, service, ["Unable to create container", bucket], err,
|
|
136
|
+
this.formatFail(64, service, ["Unable to create container", bucket], err, Cloud.optionsLogMessage('FAIL'));
|
|
126
137
|
return false;
|
|
127
138
|
});
|
|
128
139
|
}
|
|
129
|
-
async function setBucketWebsite(credential, bucket, options, service =
|
|
140
|
+
async function setBucketWebsite(credential, bucket, options, service = "azure") {
|
|
130
141
|
const staticWebsite = { enabled: true };
|
|
131
142
|
const { indexPage, indexPath, errorPath } = options;
|
|
132
143
|
if ((0, types_1.isString)(indexPage)) {
|
|
@@ -138,19 +149,19 @@ async function setBucketWebsite(credential, bucket, options, service = 'azure')
|
|
|
138
149
|
if ((0, types_1.isString)(errorPath)) {
|
|
139
150
|
staticWebsite.errorDocument404Path = Cloud.joinPath(bucket, errorPath);
|
|
140
151
|
}
|
|
141
|
-
return createStorageClient
|
|
152
|
+
return createStorageClient(credential).setProperties({ staticWebsite })
|
|
142
153
|
.then(response => {
|
|
143
154
|
const { requestId, errorCode } = response;
|
|
144
155
|
if (errorCode) {
|
|
145
|
-
this.formatMessage(64, service, ["Bucket website configured" + ' with errors', bucket], (0, types_1.errorMessage)("Error code", errorCode),
|
|
156
|
+
this.formatMessage(64, service, ["Bucket website configured" + ' with errors', bucket], (0, types_1.errorMessage)("Error code", errorCode), Cloud.optionsLogMessage('WARN'));
|
|
146
157
|
}
|
|
147
158
|
else {
|
|
148
|
-
this.formatMessage(64, service, ["Bucket website configured", bucket], requestId,
|
|
159
|
+
this.formatMessage(64, service, ["Bucket website configured", bucket], requestId, Cloud.optionsLogMessage('COMMAND'));
|
|
149
160
|
}
|
|
150
161
|
return true;
|
|
151
162
|
})
|
|
152
163
|
.catch((err) => {
|
|
153
|
-
this.formatFail(64, service, ["Unable to set bucket website", bucket], err,
|
|
164
|
+
this.formatFail(64, service, ["Unable to set bucket website", bucket], err, Cloud.optionsLogMessage('FAIL', { fatal: false }));
|
|
154
165
|
return false;
|
|
155
166
|
});
|
|
156
167
|
}
|
|
@@ -160,8 +171,8 @@ async function deleteObjects(credential, bucket, service, sdk, recursive = true)
|
|
|
160
171
|
async function deleteObjectsV2(credential, bucket, recursive = true, service) {
|
|
161
172
|
return deleteObjectsV3.call(this, credential, bucket, { recursive }, service);
|
|
162
173
|
}
|
|
163
|
-
async function deleteObjectsV3(credential, bucket, options = {}, service =
|
|
164
|
-
const containerClient = createStorageClient
|
|
174
|
+
async function deleteObjectsV3(credential, bucket, options = {}, service = "azure") {
|
|
175
|
+
const containerClient = createStorageClient(credential).getContainerClient(bucket);
|
|
165
176
|
if (await containerClient.exists().catch(() => false)) {
|
|
166
177
|
try {
|
|
167
178
|
options = { ...options };
|
|
@@ -183,14 +194,32 @@ async function deleteObjectsV3(credential, bucket, options = {}, service = 'azur
|
|
|
183
194
|
}
|
|
184
195
|
fileCount = tasks.length;
|
|
185
196
|
await this.allSettled(tasks, ["Unable to delete blob", bucket], 64).then(() => {
|
|
186
|
-
this.formatMessage(64, service, ['Container emptied' + (recursive ? ' (recursive)' : ''), bucket], fileCount + ' files',
|
|
197
|
+
this.formatMessage(64, service, ['Container emptied' + (recursive ? ' (recursive)' : ''), bucket], fileCount + ' files', Cloud.optionsLogMessage('COMMAND'));
|
|
187
198
|
});
|
|
188
199
|
}
|
|
189
200
|
catch (err) {
|
|
190
|
-
this.formatFail(64, service, ["Unable to list bucket", bucket], err,
|
|
201
|
+
this.formatFail(64, service, ["Unable to list bucket", bucket], err, Cloud.optionsLogMessage('FAIL', { fatal: false }));
|
|
191
202
|
}
|
|
192
203
|
}
|
|
193
204
|
}
|
|
205
|
+
async function copyObject(credential, bucketSource, keySource, bucket, key, options = {}, service = "azure") {
|
|
206
|
+
const storageClient = createStorageClient(credential);
|
|
207
|
+
const client = storageClient.getContainerClient(bucketSource).getBlobClient(keySource);
|
|
208
|
+
const destination = storageClient.getContainerClient(bucket).getBlobClient(key);
|
|
209
|
+
const poller = await destination.beginCopyFromURL(client.url, { ...options, abortSignal: this.signal });
|
|
210
|
+
return poller.pollUntilDone()
|
|
211
|
+
.then(response => {
|
|
212
|
+
if (response.errorCode) {
|
|
213
|
+
this.formatMessage(64, service, ["Copy success" + ' with errors', bucket], (0, types_1.errorMessage)("Error code", response.errorCode, bucketSource), Cloud.optionsLogMessage('WARN'));
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
this.formatMessage(64, service, ["Copy success", bucket], bucketSource + '/' + keySource, Cloud.optionsLogMessage('COMMAND'));
|
|
217
|
+
}
|
|
218
|
+
})
|
|
219
|
+
.catch((err) => {
|
|
220
|
+
this.formatFail(64, service, ["Copy failed", bucket + '/' + key], err, Cloud.optionsLogMessage('FAIL', { fatal: false }));
|
|
221
|
+
});
|
|
222
|
+
}
|
|
194
223
|
async function executeQuery(credential, data, sessionKey) {
|
|
195
224
|
return (await executeBatchQuery.call(this, credential, [data], sessionKey))[0] || [];
|
|
196
225
|
}
|
|
@@ -201,7 +230,7 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
201
230
|
const cacheValue = { value: this.valueOfKey(credential, 'cache'), sessionKey };
|
|
202
231
|
let client;
|
|
203
232
|
const createClient = (name, table) => {
|
|
204
|
-
client ||= createDatabaseClient
|
|
233
|
+
client ||= createDatabaseClient(credential);
|
|
205
234
|
return client.database(name).container(table);
|
|
206
235
|
};
|
|
207
236
|
const attachSignal = (opts) => {
|
package/download/index.js
CHANGED
|
@@ -2,44 +2,55 @@
|
|
|
2
2
|
const path = require("node:path");
|
|
3
3
|
const Cloud = require("@e-mc/cloud");
|
|
4
4
|
const types_1 = require("@e-mc/types");
|
|
5
|
+
const util_1 = require("@e-mc/cloud/util");
|
|
5
6
|
const client_1 = require("@pi-r/azure");
|
|
6
|
-
function download(credential, service =
|
|
7
|
-
const blobServiceClient = client_1.createStorageClient
|
|
7
|
+
function download(credential, service = "azure") {
|
|
8
|
+
const blobServiceClient = (0, client_1.createStorageClient)(credential);
|
|
8
9
|
return (data, callback) => {
|
|
9
|
-
const { bucket
|
|
10
|
-
const
|
|
11
|
-
if (!
|
|
12
|
-
callback((0, types_1.errorValue)('Missing property', !
|
|
10
|
+
const { bucket, download: target } = data;
|
|
11
|
+
const key = target.keyname || target.filename;
|
|
12
|
+
if (!bucket || !key) {
|
|
13
|
+
callback((0, types_1.errorValue)('Missing property', !bucket ? 'Container' : 'Name'));
|
|
13
14
|
return;
|
|
14
15
|
}
|
|
15
16
|
const { flags = 0 } = target;
|
|
16
|
-
const containerClient = blobServiceClient.getContainerClient(
|
|
17
|
-
const blobClient = containerClient.getBlockBlobClient(
|
|
17
|
+
const containerClient = blobServiceClient.getContainerClient(bucket);
|
|
18
|
+
const blobClient = containerClient.getBlockBlobClient(key);
|
|
18
19
|
const blockSize = (flags & 4) && (0, types_1.alignSize)(target.chunkSize, 1024) || 0;
|
|
19
20
|
const tempDir = blockSize >= 2097152000 ? (0, types_1.getTempDir)(true, service) : null;
|
|
20
21
|
let diskClient, destination;
|
|
21
22
|
if (tempDir) {
|
|
22
|
-
destination = path.join(tempDir, path.basename(target.filename ||
|
|
23
|
+
destination = path.join(tempDir, path.basename(target.filename || key));
|
|
23
24
|
diskClient = blobClient.downloadToFile(destination, 0, undefined, { snapshot: target.versionId, abortSignal: this.signal });
|
|
24
25
|
}
|
|
25
26
|
else {
|
|
26
27
|
diskClient = blobClient.downloadToBuffer(0, 0, { ...target.options, blockSize, concurrency: blockSize > 0 ? target.chunkLimit : undefined, abortSignal: this.signal });
|
|
27
28
|
}
|
|
28
29
|
diskClient
|
|
29
|
-
.then((value) => {
|
|
30
|
+
.then(async (value) => {
|
|
30
31
|
callback(null, destination || value);
|
|
32
|
+
const copyTo = (0, util_1.intoArray)(target.copyObject);
|
|
33
|
+
if (copyTo) {
|
|
34
|
+
const tasks = [];
|
|
35
|
+
for (const { bucket: bucketName, pathname, filename, options } of copyTo) {
|
|
36
|
+
const keyObject = filename ? Cloud.joinPath(pathname, filename, true) : key;
|
|
37
|
+
tasks.push(client_1.copyObject
|
|
38
|
+
.call(this, credential, bucket, key, bucketName, keyObject, options)
|
|
39
|
+
.catch((0, util_1.createErrorHandler)(this, service, bucket)));
|
|
40
|
+
}
|
|
41
|
+
await Promise.all(tasks);
|
|
42
|
+
}
|
|
31
43
|
const deleteObject = target.deleteObject;
|
|
32
44
|
if (deleteObject) {
|
|
33
|
-
const location = Cloud.joinPath(
|
|
45
|
+
const location = Cloud.joinPath(bucket, key);
|
|
34
46
|
containerClient.delete((0, types_1.isPlainObject)(deleteObject) ? { ...deleteObject, abortSignal: this.signal } : { abortSignal: this.signal })
|
|
35
47
|
.then(() => {
|
|
36
|
-
this.formatMessage(64, service, "Delete success", location,
|
|
48
|
+
this.formatMessage(64, service, "Delete success", location, Cloud.optionsLogMessage('DELETE'));
|
|
37
49
|
})
|
|
38
50
|
.catch((err) => {
|
|
39
|
-
if (
|
|
40
|
-
|
|
51
|
+
if (!(0, types_1.isErrorCode)(err, 'BlobNotFound')) {
|
|
52
|
+
this.formatFail(64, service, ["Delete failed", location], err, Cloud.optionsLogMessage('FAIL', { fatal: !!target.active }));
|
|
41
53
|
}
|
|
42
|
-
this.formatFail(64, service, ["Delete failed", location], err, { ...Cloud.LOG_CLOUD_FAIL, fatal: !!target.active });
|
|
43
54
|
});
|
|
44
55
|
}
|
|
45
56
|
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-r/azure",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Azure cloud functions for E-mc.",
|
|
5
5
|
"main": "client/index.js",
|
|
6
6
|
"publishConfig": {
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
"license": "MIT",
|
|
20
20
|
"homepage": "https://github.com/anpham6/pi-r#readme",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@e-mc/cloud": "^0.
|
|
23
|
-
"@e-mc/module": "^0.
|
|
24
|
-
"@e-mc/types": "^0.
|
|
25
|
-
"@azure/cosmos": "^4.
|
|
22
|
+
"@e-mc/cloud": "^0.13.0",
|
|
23
|
+
"@e-mc/module": "^0.13.0",
|
|
24
|
+
"@e-mc/types": "^0.13.0",
|
|
25
|
+
"@azure/cosmos": "^4.6.0",
|
|
26
26
|
"@azure/identity": "*",
|
|
27
|
-
"@azure/storage-blob": "^12.
|
|
27
|
+
"@azure/storage-blob": "^12.29.1"
|
|
28
28
|
}
|
|
29
29
|
}
|
package/upload/index.js
CHANGED
|
@@ -9,43 +9,33 @@ const client_1 = require("@pi-r/azure");
|
|
|
9
9
|
const BUCKET_SESSION = new Set();
|
|
10
10
|
const BUCKET_RESPONSE = {};
|
|
11
11
|
const getBucketKey = (credential, bucket, acl = '') => Cloud.asString(credential, true) + bucket + '_' + acl;
|
|
12
|
-
function upload(credential, service =
|
|
13
|
-
const blobServiceClient = client_1.createStorageClient
|
|
12
|
+
function upload(credential, service = "azure") {
|
|
13
|
+
const blobServiceClient = (0, client_1.createStorageClient)(credential);
|
|
14
14
|
return async (data, callback) => {
|
|
15
15
|
const { bucket, localUri } = data;
|
|
16
|
-
const { pathname
|
|
16
|
+
const { pathname, flags = 0, fileGroup, contentType, metadata, tags, endpoint, admin = {}, overwrite, options } = data.upload;
|
|
17
17
|
const containerClient = blobServiceClient.getContainerClient(bucket);
|
|
18
18
|
let filename = data.upload.filename || path.basename(localUri), bucketKey;
|
|
19
|
-
const
|
|
19
|
+
const complete = (err, url) => {
|
|
20
20
|
BUCKET_SESSION.delete(bucket);
|
|
21
21
|
if (bucketKey) {
|
|
22
22
|
delete BUCKET_RESPONSE[bucketKey];
|
|
23
23
|
}
|
|
24
|
+
callback(err, url);
|
|
24
25
|
};
|
|
25
|
-
const
|
|
26
|
-
cleanup();
|
|
27
|
-
callback(err);
|
|
28
|
-
};
|
|
29
|
-
const addLog = (err) => {
|
|
30
|
-
if (err instanceof Error) {
|
|
31
|
-
this.addLog(this.statusType.WARN, err, service, bucket);
|
|
32
|
-
}
|
|
33
|
-
};
|
|
26
|
+
const addLog = (0, util_1.createErrorHandler)(this, bucket, service);
|
|
34
27
|
const configBucket = admin.configBucket;
|
|
35
28
|
if (!BUCKET_SESSION.has(bucket)) {
|
|
36
29
|
const bucketAcl = admin.publicRead ? 'blob' : admin.acl;
|
|
37
30
|
const response = BUCKET_RESPONSE[bucketKey = getBucketKey(credential, bucket, bucketAcl)] ||= client_1.createBucketV2.call(this, credential, bucket, bucketAcl, configBucket?.create);
|
|
38
31
|
if (!await response) {
|
|
39
|
-
|
|
32
|
+
complete(null);
|
|
40
33
|
return;
|
|
41
34
|
}
|
|
42
35
|
BUCKET_SESSION.add(bucket);
|
|
43
36
|
}
|
|
44
|
-
|
|
37
|
+
const retentionPolicy = (0, util_1.intoArray)(configBucket?.retentionPolicy);
|
|
45
38
|
if (retentionPolicy) {
|
|
46
|
-
if (!Array.isArray(retentionPolicy)) {
|
|
47
|
-
retentionPolicy = [retentionPolicy];
|
|
48
|
-
}
|
|
49
39
|
try {
|
|
50
40
|
if (this.hasCoerce(service, 'options')) {
|
|
51
41
|
for (const policy of retentionPolicy) {
|
|
@@ -58,7 +48,7 @@ function upload(credential, service = 'azure') {
|
|
|
58
48
|
containerClient.setAccessPolicy('container', retentionPolicy)
|
|
59
49
|
.then(() => {
|
|
60
50
|
const { expiresOn, startsOn, permissions } = retentionPolicy[0].accessPolicy;
|
|
61
|
-
this.formatMessage(64, service, ["Bucket configured" + ' (retention policy)', bucket], expiresOn ? expiresOn.toLocaleString() + ' (expires)' : startsOn ? startsOn.toLocaleString() + ' (starts)' : permissions,
|
|
51
|
+
this.formatMessage(64, service, ["Bucket configured" + ' (retention policy)', bucket], expiresOn ? expiresOn.toLocaleString() + ' (expires)' : startsOn ? startsOn.toLocaleString() + ' (starts)' : permissions, Cloud.optionsLogMessage('COMMAND'));
|
|
62
52
|
})
|
|
63
53
|
.catch(addLog);
|
|
64
54
|
}
|
|
@@ -74,7 +64,7 @@ function upload(credential, service = 'azure') {
|
|
|
74
64
|
break;
|
|
75
65
|
}
|
|
76
66
|
}
|
|
77
|
-
const name =
|
|
67
|
+
const name = Cloud.joinPath(pathname, filename, true);
|
|
78
68
|
for await (const blob of containerClient.listBlobsFlat({ includeUncommitedBlobs: true })) {
|
|
79
69
|
if (blob.name === name) {
|
|
80
70
|
exists = true;
|
|
@@ -83,11 +73,11 @@ function upload(credential, service = 'azure') {
|
|
|
83
73
|
}
|
|
84
74
|
} while (exists && ++i);
|
|
85
75
|
if (i > 0) {
|
|
86
|
-
this.formatMessage(64, service, ["File renamed", current], filename,
|
|
76
|
+
this.formatMessage(64, service, ["File renamed", current], filename, Cloud.optionsLogMessage('WARN'));
|
|
87
77
|
}
|
|
88
78
|
}
|
|
89
79
|
catch (err) {
|
|
90
|
-
|
|
80
|
+
complete(err);
|
|
91
81
|
return;
|
|
92
82
|
}
|
|
93
83
|
}
|
|
@@ -112,7 +102,7 @@ function upload(credential, service = 'azure') {
|
|
|
112
102
|
}
|
|
113
103
|
}
|
|
114
104
|
catch (err) {
|
|
115
|
-
|
|
105
|
+
complete(err);
|
|
116
106
|
return;
|
|
117
107
|
}
|
|
118
108
|
}
|
|
@@ -140,11 +130,11 @@ function upload(credential, service = 'azure') {
|
|
|
140
130
|
const first = i === 0;
|
|
141
131
|
if (this.aborted) {
|
|
142
132
|
if (first) {
|
|
143
|
-
|
|
133
|
+
complete((0, types_1.createAbortError)());
|
|
144
134
|
}
|
|
145
135
|
return;
|
|
146
136
|
}
|
|
147
|
-
const blobName = Cloud.joinPath(pathname, Key[i]);
|
|
137
|
+
const blobName = Cloud.joinPath(pathname, Key[i], true);
|
|
148
138
|
const params = { ...options, abortSignal: this.signal };
|
|
149
139
|
const headers = params.blobHTTPHeaders ||= {};
|
|
150
140
|
if (first) {
|
|
@@ -181,15 +171,25 @@ function upload(credential, service = 'azure') {
|
|
|
181
171
|
.then(result => {
|
|
182
172
|
let requestUrl = result._response.request.url;
|
|
183
173
|
const url = endpoint ? Cloud.joinPath(endpoint, blobName) : Cloud.isFile(requestUrl = decodeURIComponent(requestUrl), 'http/s') ? requestUrl : Cloud.joinPath(`https://${credential.accountName}.blob.core.windows.net`, bucket, blobName);
|
|
184
|
-
this.formatMessage(64, service, "Upload success", url,
|
|
174
|
+
this.formatMessage(64, service, "Upload success", url, Cloud.optionsLogMessage('UPLOAD'));
|
|
185
175
|
if (first) {
|
|
186
|
-
|
|
187
|
-
|
|
176
|
+
const copyTo = (0, util_1.intoArray)(data.upload.copyObject);
|
|
177
|
+
if (copyTo) {
|
|
178
|
+
const tasks = [];
|
|
179
|
+
for (const { bucket: bucketName, pathname: pathObject = pathname, filename: fileObject, options: copyOptions } of copyTo) {
|
|
180
|
+
const keyObject = fileObject ? Cloud.joinPath(pathObject, fileObject, true) : blobName;
|
|
181
|
+
tasks.push(client_1.copyObject
|
|
182
|
+
.call(this, credential, bucket, blobName, bucketName, keyObject, copyOptions)
|
|
183
|
+
.catch(addLog));
|
|
184
|
+
}
|
|
185
|
+
void Promise.all(tasks);
|
|
186
|
+
}
|
|
187
|
+
complete(null, url);
|
|
188
188
|
}
|
|
189
189
|
})
|
|
190
190
|
.catch((err) => {
|
|
191
191
|
if (first) {
|
|
192
|
-
|
|
192
|
+
complete(err);
|
|
193
193
|
}
|
|
194
194
|
else {
|
|
195
195
|
addLog(err);
|