@pi-r/azure 0.0.1
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/LICENSE +7 -0
- package/README.md +5 -0
- package/client/index.js +236 -0
- package/download/index.js +36 -0
- package/package.json +29 -0
- package/upload/index.js +120 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright 2023 An Pham
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/client/index.js
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.executeBatchQuery = exports.executeQuery = exports.deleteObjectsV2 = exports.deleteObjects = exports.setBucketWebsite = exports.createBucketV2 = exports.createBucket = exports.createDatabaseClient = exports.createStorageClient = exports.validateDatabase = exports.validateStorage = void 0;
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const types_1 = require("@e-mc/types");
|
|
6
|
+
const util_1 = require("@e-mc/cloud/util");
|
|
7
|
+
const Module = require("@e-mc/module");
|
|
8
|
+
const Cloud = require("@e-mc/cloud");
|
|
9
|
+
function validateStorage(credential) {
|
|
10
|
+
const env = process.env;
|
|
11
|
+
if (credential.accountName && credential.accountKey || credential.connectionString || credential.sharedAccessSignature || env.AZURE_TENANT_ID && env.AZURE_CLIENT_ID && env.AZURE_CLIENT_SECRET && (credential.accountName || env.AZURE_STORAGE_ACCOUNT)) {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
return Module.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));
|
|
15
|
+
}
|
|
16
|
+
exports.validateStorage = validateStorage;
|
|
17
|
+
function validateDatabase(credential, data) {
|
|
18
|
+
return !!(data.name && data.table && (credential.endpoint && credential.key || Module.enabled("process.env.apply" /* KEY_NAME.PROCESS_ENV_APPLY */) && (credential.endpoint = process.env.AZURE_COSMOS_ENDPOINT) && (credential.key = process.env.AZURE_COSMOS_KEY)));
|
|
19
|
+
}
|
|
20
|
+
exports.validateDatabase = validateDatabase;
|
|
21
|
+
function createStorageClient(credential) {
|
|
22
|
+
let packageName = '';
|
|
23
|
+
try {
|
|
24
|
+
const { BlobServiceClient, StorageSharedKeyCredential } = require(packageName = '@azure/storage-blob');
|
|
25
|
+
const { accountName, accountKey, connectionString, sharedAccessSignature } = credential;
|
|
26
|
+
if (connectionString) {
|
|
27
|
+
credential.accountName || (credential.accountName = /AccountName=([^;]+);/.exec(connectionString)?.[1]);
|
|
28
|
+
return BlobServiceClient.fromConnectionString(connectionString);
|
|
29
|
+
}
|
|
30
|
+
if (sharedAccessSignature) {
|
|
31
|
+
credential.accountName || (credential.accountName = /^https:\/\/([a-z\d]+)\./.exec(sharedAccessSignature)?.[1]);
|
|
32
|
+
return new BlobServiceClient(sharedAccessSignature);
|
|
33
|
+
}
|
|
34
|
+
let azureCredential;
|
|
35
|
+
if (accountName && accountKey) {
|
|
36
|
+
azureCredential = new StorageSharedKeyCredential(accountName, accountKey);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
const { DefaultAzureCredential } = require(packageName = '@azure/identity');
|
|
40
|
+
azureCredential = new DefaultAzureCredential();
|
|
41
|
+
}
|
|
42
|
+
return new BlobServiceClient(`https://${accountName || process.env.AZURE_STORAGE_ACCOUNT}.blob.core.windows.net`, azureCredential);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
this.checkPackage(err, packageName, { passThrough: true });
|
|
46
|
+
throw err;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.createStorageClient = createStorageClient;
|
|
50
|
+
function createDatabaseClient(credential) {
|
|
51
|
+
try {
|
|
52
|
+
const { CosmosClient } = require('@azure/cosmos');
|
|
53
|
+
return new CosmosClient(credential);
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
this.checkPackage(err, '@azure/cosmos', { passThrough: true });
|
|
57
|
+
throw err;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.createDatabaseClient = createDatabaseClient;
|
|
61
|
+
async function createBucket(credential, bucket, publicRead, service = 'azure') {
|
|
62
|
+
return createBucketV2.call(this, credential, bucket, publicRead ? 'blob' : 'container', undefined, service);
|
|
63
|
+
}
|
|
64
|
+
exports.createBucket = createBucket;
|
|
65
|
+
async function createBucketV2(credential, bucket, access, options, service = 'azure') {
|
|
66
|
+
switch (access) {
|
|
67
|
+
case 'blob':
|
|
68
|
+
case 'container':
|
|
69
|
+
break;
|
|
70
|
+
default:
|
|
71
|
+
access = undefined;
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
const containerClient = createStorageClient.call(this, credential).getContainerClient(bucket);
|
|
75
|
+
const setAccessPolicy = () => containerClient.setAccessPolicy(access).catch(err => this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, ["Unable to configure container" /* ERR_AZURE.CONFIGURE_CONTAINER */, bucket], err, { ...Cloud.LOG_CLOUD_WARN }));
|
|
76
|
+
if (await containerClient.exists().catch(() => false)) {
|
|
77
|
+
if (access) {
|
|
78
|
+
await setAccessPolicy();
|
|
79
|
+
}
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
options = { ...options };
|
|
83
|
+
if (access) {
|
|
84
|
+
options.access = access;
|
|
85
|
+
}
|
|
86
|
+
options.abortSignal = this.signal;
|
|
87
|
+
return containerClient.create(options)
|
|
88
|
+
.then(response => {
|
|
89
|
+
if (response.errorCode) {
|
|
90
|
+
this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, ['Container created with errors', bucket], (0, types_1.errorMessage)("Error code" /* ERR_MESSAGE.ERROR_CODE */, response.errorCode), { ...Cloud.LOG_CLOUD_WARN });
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, ['Container created', bucket], response.requestId, { ...Cloud.LOG_CLOUD_COMMAND });
|
|
94
|
+
}
|
|
95
|
+
return true;
|
|
96
|
+
})
|
|
97
|
+
.catch(async (err) => {
|
|
98
|
+
if (err instanceof Error && err.code === 'ContainerAlreadyExists') {
|
|
99
|
+
if (access) {
|
|
100
|
+
await setAccessPolicy();
|
|
101
|
+
}
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
this.formatFail(64 /* LOG_TYPE.CLOUD */, service, ["Unable to create container" /* ERR_AZURE.CREATE_CONTAINER */, bucket], err, { ...Cloud.LOG_CLOUD_FAIL });
|
|
105
|
+
return false;
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
exports.createBucketV2 = createBucketV2;
|
|
109
|
+
function setBucketWebsite(credential, bucket, options, service = 'azure') {
|
|
110
|
+
const staticWebsite = { enabled: true };
|
|
111
|
+
if ((0, types_1.isString)(options.indexPage)) {
|
|
112
|
+
staticWebsite.indexDocument = path.basename(options.indexPage);
|
|
113
|
+
}
|
|
114
|
+
if ((0, types_1.isString)(options.indexPath)) {
|
|
115
|
+
staticWebsite.defaultIndexDocumentPath = Module.joinPath(bucket, options.indexPath);
|
|
116
|
+
}
|
|
117
|
+
if ((0, types_1.isString)(options.errorPath)) {
|
|
118
|
+
staticWebsite.errorDocument404Path = Module.joinPath(bucket, options.errorPath);
|
|
119
|
+
}
|
|
120
|
+
return createStorageClient.call(this, credential).setProperties({ staticWebsite })
|
|
121
|
+
.then(() => {
|
|
122
|
+
this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, ["Bucket configured" /* VAL_CLOUD.CONFIGURE_BUCKET */, bucket], options, { ...Cloud.LOG_CLOUD_COMMAND });
|
|
123
|
+
return true;
|
|
124
|
+
})
|
|
125
|
+
.catch(err => {
|
|
126
|
+
this.formatFail(64 /* LOG_TYPE.CLOUD */, service, ["Unable to configure bucket" /* ERR_CLOUD.CONFIGURE_BUCKET */, bucket], err, { ...Cloud.LOG_CLOUD_FAIL, fatal: false });
|
|
127
|
+
return false;
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
exports.setBucketWebsite = setBucketWebsite;
|
|
131
|
+
function deleteObjects(credential, Bucket, service) {
|
|
132
|
+
return deleteObjectsV2.call(this, credential, Bucket, true, service);
|
|
133
|
+
}
|
|
134
|
+
exports.deleteObjects = deleteObjects;
|
|
135
|
+
async function deleteObjectsV2(credential, bucket, recursive = true, service = 'azure') {
|
|
136
|
+
const containerClient = createStorageClient.call(this, credential).getContainerClient(bucket);
|
|
137
|
+
if (await containerClient.exists().catch(() => false)) {
|
|
138
|
+
try {
|
|
139
|
+
const tasks = [];
|
|
140
|
+
let fileCount = 0;
|
|
141
|
+
for await (const blob of containerClient.listBlobsFlat({ includeUncommitedBlobs: true })) {
|
|
142
|
+
if (!recursive && blob.name.indexOf('/') !== -1) {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
tasks.push(containerClient.deleteBlob(blob.name, { versionId: blob.versionId }).catch(() => { --fileCount; }));
|
|
146
|
+
}
|
|
147
|
+
fileCount = tasks.length;
|
|
148
|
+
return this.allSettled(tasks, ["Unable to delete blob" /* ERR_AZURE.DELETE_BLOB */, bucket], 64 /* LOG_TYPE.CLOUD */).then(() => {
|
|
149
|
+
const files = fileCount + ' files';
|
|
150
|
+
this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, [`Container emptied (${recursive ? 'recursive' : files})`, bucket], recursive ? files : '', { ...Cloud.LOG_CLOUD_COMMAND });
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
this.formatFail(64 /* LOG_TYPE.CLOUD */, service, ["Unable to list bucket" /* ERR_CLOUD.LIST_BUCKET */, bucket], err, { ...Cloud.LOG_CLOUD_FAIL, fatal: false });
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
exports.deleteObjectsV2 = deleteObjectsV2;
|
|
159
|
+
async function executeQuery(credential, data, sessionKey) {
|
|
160
|
+
return (await executeBatchQuery.call(this, credential, [data], sessionKey))[0] || [];
|
|
161
|
+
}
|
|
162
|
+
exports.executeQuery = executeQuery;
|
|
163
|
+
async function executeBatchQuery(credential, batch, sessionKey) {
|
|
164
|
+
const length = batch.length;
|
|
165
|
+
const result = new Array(length);
|
|
166
|
+
const caching = length > 0 && this.hasCache(batch[0].service, sessionKey);
|
|
167
|
+
const cacheValue = { value: this.valueOfKey(credential, 'cache'), sessionKey };
|
|
168
|
+
let client;
|
|
169
|
+
const createClient = (name, table) => {
|
|
170
|
+
client || (client = createDatabaseClient.call(this, length === 1 ? credential : { ...credential }));
|
|
171
|
+
return client.database(name).container(table);
|
|
172
|
+
};
|
|
173
|
+
const closeClient = () => client?.dispose();
|
|
174
|
+
for (let i = 0; i < length; ++i) {
|
|
175
|
+
const item = batch[i];
|
|
176
|
+
const { service, name, table, id, query, storedProcedureId, partitionKey, params, limit = 0, update, ignoreCache } = item;
|
|
177
|
+
if (!name || !table) {
|
|
178
|
+
closeClient();
|
|
179
|
+
throw (0, util_1.formatError)(item, name ? "Missing database table" /* ERR_DB.TABLE */ : "Missing database name" /* ERR_DB.NAME */);
|
|
180
|
+
}
|
|
181
|
+
const renewCache = ignoreCache === 0;
|
|
182
|
+
const getCache = (value) => {
|
|
183
|
+
if (ignoreCache === 1) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
cacheValue.renewCache = renewCache;
|
|
187
|
+
return this.getQueryResult(service, credential, value, cacheValue);
|
|
188
|
+
};
|
|
189
|
+
let rows, queryString = caching && ignoreCache !== true || ignoreCache === false || ignoreCache === 1 || renewCache ? name + '_' + table + '_' : '';
|
|
190
|
+
if (storedProcedureId && params) {
|
|
191
|
+
const { options } = item;
|
|
192
|
+
if (queryString && (rows = getCache(queryString += (partitionKey || '') + '_' + storedProcedureId + Module.asString(params, true) + Module.asString(options, true)))) {
|
|
193
|
+
result[i] = rows;
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
const { statusCode, resource } = await createClient(name, table).scripts.storedProcedure(storedProcedureId).execute(partitionKey, params, options);
|
|
197
|
+
if (statusCode === 200 /* HTTP_STATUS.OK */) {
|
|
198
|
+
rows = Array.isArray(resource) ? resource : [resource];
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
else if (id) {
|
|
202
|
+
const { options } = item;
|
|
203
|
+
if (queryString) {
|
|
204
|
+
queryString += (partitionKey || '') + '_' + id + Module.asString(options, true);
|
|
205
|
+
if (!update && (rows = getCache(queryString))) {
|
|
206
|
+
result[i] = rows;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
const db = createClient(name, table).item(id, partitionKey);
|
|
211
|
+
const { statusCode, resource } = update ? await db.patch(update, options) : await db.read(options);
|
|
212
|
+
if (statusCode === 200 /* HTTP_STATUS.OK */) {
|
|
213
|
+
rows = [resource];
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
else if (query) {
|
|
217
|
+
let { options } = item;
|
|
218
|
+
if (limit > 0) {
|
|
219
|
+
(options || (options = {})).maxItemCount = limit;
|
|
220
|
+
}
|
|
221
|
+
if (queryString && (rows = getCache(queryString += Module.asString(query, true) + Module.asString(options, true)))) {
|
|
222
|
+
result[i] = rows;
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
rows = (await createClient(name, table).items.query(query, options).fetchAll()).resources;
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
closeClient();
|
|
229
|
+
throw (0, util_1.formatError)(item, "Missing database query" /* ERR_DB.QUERY */);
|
|
230
|
+
}
|
|
231
|
+
result[i] = this.setQueryResult(service, credential, queryString, rows, cacheValue);
|
|
232
|
+
}
|
|
233
|
+
closeClient();
|
|
234
|
+
return result;
|
|
235
|
+
}
|
|
236
|
+
exports.executeBatchQuery = executeBatchQuery;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const client_1 = require("../client");
|
|
4
|
+
const types_1 = require("@e-mc/types");
|
|
5
|
+
const Module = require("@e-mc/module");
|
|
6
|
+
const Cloud = require("@e-mc/cloud");
|
|
7
|
+
function download(credential, service = 'azure') {
|
|
8
|
+
const blobServiceClient = client_1.createStorageClient.call(this, credential);
|
|
9
|
+
return (data, callback) => {
|
|
10
|
+
const { bucket: Bucket, download: target } = data;
|
|
11
|
+
const Key = target.filename;
|
|
12
|
+
if (!Bucket || !Key) {
|
|
13
|
+
callback((0, types_1.errorValue)('Missing property', !Bucket ? 'Container' : 'Name'));
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const location = Module.joinPath(Bucket, Key);
|
|
17
|
+
const blobClient = blobServiceClient.getContainerClient(Bucket);
|
|
18
|
+
blobClient.getBlockBlobClient(Key).downloadToBuffer()
|
|
19
|
+
.then(value => {
|
|
20
|
+
callback(null, value);
|
|
21
|
+
const deleteObject = target.deleteObject;
|
|
22
|
+
if (target.deleteObject) {
|
|
23
|
+
blobClient.delete((0, types_1.isPlainObject)(deleteObject) && (deleteObject.abortSignal = this.signal) ? deleteObject : undefined)
|
|
24
|
+
.then(() => this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, "Delete success" /* VAL_CLOUD.DELETE_FILE */, location, { ...Cloud.LOG_CLOUD_DELETE }))
|
|
25
|
+
.catch((err) => {
|
|
26
|
+
if (!(err instanceof Error && err.code === 'BlobNotFound')) {
|
|
27
|
+
this.formatFail(64 /* LOG_TYPE.CLOUD */, service, ["Delete failed" /* ERR_CLOUD.DELETE_FAIL */, location], err, { ...Cloud.LOG_CLOUD_FAIL, fatal: !!target.active });
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
.catch(err => callback(err));
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = download;
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pi-r/azure",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Azure cloud functions for E-mc.",
|
|
5
|
+
"main": "client/index.js",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/anpham6/pi-r.git",
|
|
12
|
+
"directory": "src/cloud/azure"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"squared",
|
|
16
|
+
"e-mc",
|
|
17
|
+
"squared-functions"
|
|
18
|
+
],
|
|
19
|
+
"author": "An Pham <anpham6@gmail.com>",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"homepage": "https://github.com/anpham6/pi-r#readme",
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@e-mc/cloud": "^0.4.0",
|
|
24
|
+
"@e-mc/module": "^0.4.0",
|
|
25
|
+
"@e-mc/types": "^0.4.0",
|
|
26
|
+
"@azure/cosmos": "^3.17.3",
|
|
27
|
+
"@azure/storage-blob": "^12.13.0"
|
|
28
|
+
}
|
|
29
|
+
}
|
package/upload/index.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const client_1 = require("../client");
|
|
6
|
+
const util_1 = require("@e-mc/cloud/util");
|
|
7
|
+
const types_1 = require("@e-mc/types");
|
|
8
|
+
const Module = require("@e-mc/module");
|
|
9
|
+
const Cloud = require("@e-mc/cloud");
|
|
10
|
+
const BUCKET_SESSION = new Set();
|
|
11
|
+
const BUCKET_RESPONSE = {};
|
|
12
|
+
const getBucketKey = (credential, bucket, acl = '') => Module.asString(credential, true) + bucket + '_' + acl;
|
|
13
|
+
function upload(credential, service = 'azure') {
|
|
14
|
+
const blobServiceClient = client_1.createStorageClient.call(this, credential);
|
|
15
|
+
return async (data, callback) => {
|
|
16
|
+
var _a, _b;
|
|
17
|
+
const { bucket, localUri } = data;
|
|
18
|
+
const { pathname = '', fileGroup, contentType, metadata, endpoint, admin = {}, overwrite, options } = data.upload;
|
|
19
|
+
const containerClient = blobServiceClient.getContainerClient(bucket);
|
|
20
|
+
let filename = data.upload.filename || path.basename(localUri), bucketKey;
|
|
21
|
+
const cleanup = () => {
|
|
22
|
+
BUCKET_SESSION.delete(bucket);
|
|
23
|
+
if (bucketKey) {
|
|
24
|
+
delete BUCKET_RESPONSE[bucketKey];
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const errorResponse = (err) => {
|
|
28
|
+
cleanup();
|
|
29
|
+
callback(err);
|
|
30
|
+
};
|
|
31
|
+
if (!BUCKET_SESSION.has(bucket)) {
|
|
32
|
+
const bucketAcl = admin.publicRead ? 'blob' : admin.acl;
|
|
33
|
+
const response = BUCKET_RESPONSE[_a = bucketKey = getBucketKey(credential, bucket, bucketAcl)] || (BUCKET_RESPONSE[_a] = client_1.createBucketV2.call(this, credential, bucket, bucketAcl, admin.configBucket?.create));
|
|
34
|
+
if (!await response) {
|
|
35
|
+
errorResponse(null);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
BUCKET_SESSION.add(bucket);
|
|
39
|
+
}
|
|
40
|
+
if (!overwrite) {
|
|
41
|
+
try {
|
|
42
|
+
const current = filename;
|
|
43
|
+
const next = (0, util_1.generateFilename)(filename);
|
|
44
|
+
let i = 0, exists;
|
|
45
|
+
do {
|
|
46
|
+
if (i > 0) {
|
|
47
|
+
[filename, exists] = next(i);
|
|
48
|
+
if (!exists) {
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const name = pathname ? Module.joinPath(pathname, filename) : filename;
|
|
53
|
+
for await (const blob of containerClient.listBlobsFlat({ includeUncommitedBlobs: true })) {
|
|
54
|
+
if (blob.name === name) {
|
|
55
|
+
exists = true;
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
} while (exists && ++i);
|
|
60
|
+
if (i > 0) {
|
|
61
|
+
this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, ["File renamed" /* VAL_CLOUD.RENAME_FILE */, current], filename, { ...Cloud.LOG_CLOUD_WARN });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
errorResponse(err);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const Key = [filename];
|
|
70
|
+
const Body = [data.buffer];
|
|
71
|
+
const ContentType = [contentType];
|
|
72
|
+
const addLog = (err) => err instanceof Error && this.addLog(this.statusType.WARN, err.message, service + ': ' + bucket);
|
|
73
|
+
if (fileGroup) {
|
|
74
|
+
for (const [content, ext, localFile] of fileGroup) {
|
|
75
|
+
try {
|
|
76
|
+
Body.push(typeof content === 'string' ? fs.readFileSync(content) : content);
|
|
77
|
+
Key.push(ext === '.map' && localFile ? path.basename(localFile) : filename + ext);
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
addLog(err);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
for (let i = 0; i < Key.length; ++i) {
|
|
85
|
+
const first = i === 0;
|
|
86
|
+
if (this.aborted) {
|
|
87
|
+
if (first) {
|
|
88
|
+
errorResponse((0, types_1.createAbortError)());
|
|
89
|
+
}
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const blobName = Module.joinPath(pathname, Key[i]);
|
|
93
|
+
const params = { ...options, abortSignal: this.signal };
|
|
94
|
+
if (first && metadata) {
|
|
95
|
+
params.metadata = metadata;
|
|
96
|
+
}
|
|
97
|
+
(_b = (params.blobHTTPHeaders || (params.blobHTTPHeaders = {}))).blobContentType || (_b.blobContentType = ContentType[i]);
|
|
98
|
+
containerClient.getBlockBlobClient(blobName).upload(Body[i], Body[i].byteLength, params)
|
|
99
|
+
.then(result => {
|
|
100
|
+
let requestUrl = result._response.request.url;
|
|
101
|
+
const url = endpoint ? Module.joinPath(endpoint, blobName) : Module.isFile(requestUrl = decodeURIComponent(requestUrl), 'http/s') ? requestUrl : Module.joinPath(`https://${credential.accountName}.blob.core.windows.net`, bucket, blobName);
|
|
102
|
+
this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, "Upload success" /* VAL_CLOUD.UPLOAD_FILE */, url, { ...Cloud.LOG_CLOUD_UPLOAD });
|
|
103
|
+
if (first) {
|
|
104
|
+
cleanup();
|
|
105
|
+
callback(null, url);
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
.catch(err => {
|
|
109
|
+
if (first) {
|
|
110
|
+
errorResponse(err);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
addLog(err);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
module.exports = upload;
|