@e-mc/cloud 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 +11 -0
- package/README.md +5 -0
- package/atlas/index.js +193 -0
- package/aws/download/index.js +44 -0
- package/aws/index.js +381 -0
- package/aws/upload/index.js +137 -0
- package/aws-v3/download/index.js +42 -0
- package/aws-v3/index.js +285 -0
- package/aws-v3/upload/index.js +157 -0
- package/azure/download/index.js +40 -0
- package/azure/index.js +236 -0
- package/azure/upload/index.js +124 -0
- package/gcp/download/index.js +86 -0
- package/gcp/index.js +801 -0
- package/gcp/upload/index.js +234 -0
- package/ibm/download/index.js +13 -0
- package/ibm/index.js +229 -0
- package/ibm/upload/index.js +13 -0
- package/index.d.ts +6 -0
- package/index.js +832 -0
- package/minio/download/index.js +44 -0
- package/minio/index.js +182 -0
- package/minio/upload/index.js +135 -0
- package/oci/download/index.js +13 -0
- package/oci/index.js +183 -0
- package/oci/upload/index.js +13 -0
- package/package.json +26 -0
- package/types.d.ts +29 -0
- package/util.d.ts +12 -0
- package/util.js +46 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const index_1 = require("../index");
|
|
4
|
+
const util_1 = require("../../util");
|
|
5
|
+
const types_1 = require("../../../types");
|
|
6
|
+
const module_1 = require("../../../module");
|
|
7
|
+
const index_2 = require("../../index");
|
|
8
|
+
function download(credential, service) {
|
|
9
|
+
const minio = index_1.createStorageClient.call(this, credential);
|
|
10
|
+
return (data, callback) => {
|
|
11
|
+
const { bucket: bucketName, download: target } = data;
|
|
12
|
+
const { filename, versionId } = target;
|
|
13
|
+
if (!bucketName || !filename) {
|
|
14
|
+
callback((0, types_1.errorValue)('Missing property', !bucketName ? 'Bucket' : 'Key'));
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
minio.getObject(bucketName, filename, { versionId }, (error, result) => {
|
|
18
|
+
if (!error) {
|
|
19
|
+
(0, util_1.readableAsBuffer)(result).then(buffer => callback(null, buffer)).catch(err => callback(err));
|
|
20
|
+
const deleteObject = target.deleteObject;
|
|
21
|
+
if (deleteObject) {
|
|
22
|
+
minio.removeObject(bucketName, filename, (0, types_1.isPlainObject)(deleteObject) ? deleteObject : { versionId }, err => {
|
|
23
|
+
const location = module_1.default.joinPath(bucketName, filename);
|
|
24
|
+
if (!err) {
|
|
25
|
+
this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, "Delete success" /* CMD_CLOUD.DELETE_FILE */, location, { ...index_2.default.LOG_CLOUD_DELETE });
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
this.formatFail(64 /* LOG_TYPE.CLOUD */, service, ["Delete failed" /* ERR_CLOUD.DELETE_FAIL */, location], err, { ...index_2.default.LOG_CLOUD_FAIL, fatal: !!target.active });
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
callback(error);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
exports.default = download;
|
|
40
|
+
|
|
41
|
+
if (exports.default) {
|
|
42
|
+
module.exports = exports.default;
|
|
43
|
+
module.exports.default = exports.default;
|
|
44
|
+
}
|
package/minio/index.js
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deleteObjectsV2 = exports.deleteObjects = exports.setBucketPolicy = exports.createBucketV2 = exports.createBucket = exports.createStorageClient = exports.validateStorage = void 0;
|
|
4
|
+
const types_1 = require("../../types");
|
|
5
|
+
const module_1 = require("../../module");
|
|
6
|
+
const index_1 = require("../index");
|
|
7
|
+
function createAWSPolicy(bucket, Sid) {
|
|
8
|
+
const Resource = [`arn:aws:s3:::${bucket}/*`, `arn:aws:s3:::${bucket}`];
|
|
9
|
+
let Action;
|
|
10
|
+
switch (Sid) {
|
|
11
|
+
case 'readonly':
|
|
12
|
+
Action = ["s3:GetBucketLocation", "s3:GetObject"];
|
|
13
|
+
break;
|
|
14
|
+
case 'writeonly':
|
|
15
|
+
Action = ["s3:PutObject"];
|
|
16
|
+
Resource.pop();
|
|
17
|
+
break;
|
|
18
|
+
case 'readwrite':
|
|
19
|
+
Action = ["s3:GetBucketLocation", "s3:GetObject", "s3:PutObject"];
|
|
20
|
+
break;
|
|
21
|
+
case 'public-read':
|
|
22
|
+
Action = ["s3:GetObject", "s3:GetObjectVersion"];
|
|
23
|
+
Resource.pop();
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
return JSON.stringify({
|
|
27
|
+
"Version": "2012-10-17",
|
|
28
|
+
"Statement": [{
|
|
29
|
+
"Sid": Sid,
|
|
30
|
+
"Effect": "Allow",
|
|
31
|
+
"Principal": {
|
|
32
|
+
"AWS": ["*"]
|
|
33
|
+
},
|
|
34
|
+
"Action": Action,
|
|
35
|
+
"Resource": Resource
|
|
36
|
+
}]
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function validateStorage(credential, data) {
|
|
40
|
+
if (typeof credential.port === 'string') {
|
|
41
|
+
credential.port = parseInt(credential.port) || 0;
|
|
42
|
+
}
|
|
43
|
+
if (!credential.endPoint && module_1.default.enabled("process.env.apply" /* KEY_NAME.PROCESS_ENV_APPLY */)) {
|
|
44
|
+
credential.endPoint = process.env.MINIO_ENDPOINT;
|
|
45
|
+
}
|
|
46
|
+
const upload = data?.upload;
|
|
47
|
+
if (upload && !upload.endpoint && data.bucket) {
|
|
48
|
+
const { endPoint, port = 0, useSSL } = credential;
|
|
49
|
+
if (endPoint) {
|
|
50
|
+
upload.endpoint = (useSSL === false ? 'http' : 'https') + '://' + credential.endPoint + (port > 0 ? ':' + port : '') + '/' + data.bucket;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (credential.accessKey && credential.secretKey) {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
if (module_1.default.enabled("process.env.apply" /* KEY_NAME.PROCESS_ENV_APPLY */) && (credential.accessKey = process.env.MINIO_ACCESS_KEY) && (credential.secretKey = process.env.MINIO_SECRET_KEY)) {
|
|
57
|
+
credential.sessionToken || (credential.sessionToken = process.env.MINIO_SESSION_TOKEN);
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
exports.validateStorage = validateStorage;
|
|
63
|
+
function createStorageClient(credential) {
|
|
64
|
+
try {
|
|
65
|
+
const { Client } = require('minio');
|
|
66
|
+
credential.endPoint || (credential.endPoint = 'localhost');
|
|
67
|
+
return new Client(credential);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
this.checkPackage(err, 'minio', { passThrough: true });
|
|
71
|
+
throw err;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
exports.createStorageClient = createStorageClient;
|
|
75
|
+
async function createBucket(credential, bucketName, publicRead) {
|
|
76
|
+
return createBucketV2.call(this, credential, bucketName, publicRead ? 'public-read' : undefined);
|
|
77
|
+
}
|
|
78
|
+
exports.createBucket = createBucket;
|
|
79
|
+
async function createBucketV2(credential, bucketName, policy) {
|
|
80
|
+
const minio = createStorageClient.call(this, credential);
|
|
81
|
+
const errorMesssage = (err) => this.formatFail(64 /* LOG_TYPE.CLOUD */, "minio" /* MINIO.SERVICE */, ["Unable to create bucket" /* ERR_CLOUD.CREATE_BUCKET */, bucketName], err, { ...index_1.default.LOG_CLOUD_FAIL });
|
|
82
|
+
return minio.bucketExists(bucketName)
|
|
83
|
+
.then(exists => {
|
|
84
|
+
if (!exists) {
|
|
85
|
+
return minio.makeBucket(bucketName, credential.region || "us-east-1" /* MINIO.REGION */)
|
|
86
|
+
.then(() => {
|
|
87
|
+
this.formatMessage(64 /* LOG_TYPE.CLOUD */, "minio" /* MINIO.SERVICE */, ["Bucket created" /* CMD_CLOUD.CREATE_BUCKET */, bucketName], '', { ...index_1.default.LOG_CLOUD_COMMAND });
|
|
88
|
+
if (policy) {
|
|
89
|
+
setBucketPolicy.call(this, credential, bucketName, policy);
|
|
90
|
+
}
|
|
91
|
+
return true;
|
|
92
|
+
})
|
|
93
|
+
.catch(err => {
|
|
94
|
+
errorMesssage(err);
|
|
95
|
+
return false;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
if (policy) {
|
|
99
|
+
setBucketPolicy.call(this, credential, bucketName, policy);
|
|
100
|
+
}
|
|
101
|
+
return true;
|
|
102
|
+
})
|
|
103
|
+
.catch(err => {
|
|
104
|
+
errorMesssage(err);
|
|
105
|
+
return false;
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
exports.createBucketV2 = createBucketV2;
|
|
109
|
+
async function setBucketPolicy(credential, bucketName, bucketPolicy) {
|
|
110
|
+
if ((0, types_1.isObject)(bucketPolicy)) {
|
|
111
|
+
bucketPolicy = JSON.stringify(bucketPolicy);
|
|
112
|
+
}
|
|
113
|
+
if (!(0, types_1.isString)(bucketPolicy)) {
|
|
114
|
+
this.formatMessage(64 /* LOG_TYPE.CLOUD */, "minio" /* MINIO.SERVICE */, ["Invalid bucket policy" /* ERR_CLOUD.POLICY_INVALID */, bucketName], '', { ...index_1.default.LOG_CLOUD_WARN });
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
const minio = createStorageClient.call(this, credential);
|
|
118
|
+
return minio.bucketExists(bucketName)
|
|
119
|
+
.then(exists => {
|
|
120
|
+
if (exists) {
|
|
121
|
+
switch (bucketPolicy) {
|
|
122
|
+
case 'readonly':
|
|
123
|
+
case 'readwrite':
|
|
124
|
+
case 'writeonly':
|
|
125
|
+
case 'public-read':
|
|
126
|
+
bucketPolicy = createAWSPolicy(bucketName, bucketPolicy);
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
return minio.setBucketPolicy(bucketName, bucketPolicy)
|
|
130
|
+
.then(() => {
|
|
131
|
+
this.formatMessage(64 /* LOG_TYPE.CLOUD */, "minio" /* MINIO.SERVICE */, ["Bucket policy configured" /* CMD_CLOUD.POLICY_BUCKET */, bucketName], '', { ...index_1.default.LOG_CLOUD_COMMAND });
|
|
132
|
+
return true;
|
|
133
|
+
})
|
|
134
|
+
.catch(err => {
|
|
135
|
+
this.formatFail(64 /* LOG_TYPE.CLOUD */, "minio" /* MINIO.SERVICE */, ["Unable to update bucket policy" /* ERR_CLOUD.POLICY_BUCKET */, bucketName], err, { ...index_1.default.LOG_CLOUD_FAIL, fatal: false });
|
|
136
|
+
return false;
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return false;
|
|
140
|
+
})
|
|
141
|
+
.catch(err => {
|
|
142
|
+
this.formatFail(64 /* LOG_TYPE.CLOUD */, "minio" /* MINIO.SERVICE */, ["Unknown" /* ERR_MESSAGE.UNKNOWN */, bucketName], err, { ...index_1.default.LOG_CLOUD_FAIL, fatal: false });
|
|
143
|
+
return false;
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
exports.setBucketPolicy = setBucketPolicy;
|
|
147
|
+
function deleteObjects(credential, bucketName) {
|
|
148
|
+
return deleteObjectsV2.call(this, credential, bucketName, true);
|
|
149
|
+
}
|
|
150
|
+
exports.deleteObjects = deleteObjects;
|
|
151
|
+
async function deleteObjectsV2(credential, bucketName, recursive = true) {
|
|
152
|
+
const minio = createStorageClient.call(this, credential);
|
|
153
|
+
return new Promise((resolve, reject) => {
|
|
154
|
+
minio.bucketExists(bucketName)
|
|
155
|
+
.then(exists => {
|
|
156
|
+
if (exists) {
|
|
157
|
+
const stream = minio.listObjectsV2(bucketName, '', recursive);
|
|
158
|
+
const items = [];
|
|
159
|
+
stream.on('data', item => {
|
|
160
|
+
items.push(item);
|
|
161
|
+
});
|
|
162
|
+
stream.on('end', () => {
|
|
163
|
+
minio.removeObjects(bucketName, items.map(item => item.name), err => {
|
|
164
|
+
if (!err) {
|
|
165
|
+
this.formatMessage(64 /* LOG_TYPE.CLOUD */, "minio" /* MINIO.SERVICE */, ["Bucket emptied" /* CMD_CLOUD.EMPTY_BUCKET */ + ` (${items.length} files)`, bucketName], '', { ...index_1.default.LOG_CLOUD_COMMAND });
|
|
166
|
+
resolve();
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
reject(err);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
stream.on('error', err => reject(err));
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
resolve();
|
|
177
|
+
}
|
|
178
|
+
})
|
|
179
|
+
.catch(err => reject(err));
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
exports.deleteObjectsV2 = deleteObjectsV2;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const index_1 = require("../index");
|
|
6
|
+
const util_1 = require("../../util");
|
|
7
|
+
const types_1 = require("../../../types");
|
|
8
|
+
const module_1 = require("../../../module");
|
|
9
|
+
const index_2 = require("../../index");
|
|
10
|
+
const BUCKET_SESSION = new Set();
|
|
11
|
+
const BUCKET_RESPONSE = {};
|
|
12
|
+
const getBucketKey = (credential, bucket, acl = '') => module_1.default.asString(credential, true) + bucket + '_' + acl;
|
|
13
|
+
function upload(credential, service) {
|
|
14
|
+
const minio = index_1.createStorageClient.call(this, credential);
|
|
15
|
+
return async (data, callback) => {
|
|
16
|
+
var _a;
|
|
17
|
+
const { bucket: bucketName, localUri } = data;
|
|
18
|
+
const { pathname = '', fileGroup, contentType, metadata = {}, endpoint, active, acl, publicRead, admin = {}, overwrite, options } = data.upload;
|
|
19
|
+
let filename = data.upload.filename || path.basename(localUri), bucketKey;
|
|
20
|
+
const cleanup = () => {
|
|
21
|
+
BUCKET_SESSION.delete(bucketName);
|
|
22
|
+
if (bucketKey) {
|
|
23
|
+
delete BUCKET_RESPONSE[bucketKey];
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const errorResponse = (err) => {
|
|
27
|
+
cleanup();
|
|
28
|
+
callback(err);
|
|
29
|
+
};
|
|
30
|
+
if (!BUCKET_SESSION.has(bucketName)) {
|
|
31
|
+
const bucketAcl = admin.publicRead ? 'public-read' : admin.acl;
|
|
32
|
+
const response = BUCKET_RESPONSE[_a = bucketKey = getBucketKey(credential, bucketName, bucketAcl)] || (BUCKET_RESPONSE[_a] = index_1.createBucketV2.call(this, credential, bucketName, bucketAcl));
|
|
33
|
+
if (!await response) {
|
|
34
|
+
errorResponse(null);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
BUCKET_SESSION.add(bucketName);
|
|
38
|
+
}
|
|
39
|
+
if (!overwrite) {
|
|
40
|
+
const current = filename;
|
|
41
|
+
const next = (0, util_1.generateFilename)(filename);
|
|
42
|
+
let i = 0, exists;
|
|
43
|
+
do {
|
|
44
|
+
if (i > 0) {
|
|
45
|
+
[filename, exists] = next(i);
|
|
46
|
+
if (!exists) {
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exists = await minio.statObject(bucketName, pathname ? module_1.default.joinPath(pathname, filename) : filename)
|
|
51
|
+
.then(() => true)
|
|
52
|
+
.catch((err) => {
|
|
53
|
+
if (err instanceof Error && err.code !== 'NotFound') {
|
|
54
|
+
filename = (0, types_1.generateUUID)() + path.extname(current);
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
return false;
|
|
58
|
+
});
|
|
59
|
+
} while (exists && ++i);
|
|
60
|
+
if (i > 0) {
|
|
61
|
+
this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, ["File renamed" /* CMD_CLOUD.RENAME_FILE */, current], filename, { ...index_2.default.LOG_CLOUD_WARN });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const Key = [filename];
|
|
65
|
+
const Body = [data.buffer];
|
|
66
|
+
const ContentType = [contentType];
|
|
67
|
+
const addLog = (err) => err instanceof Error && this.addLog(this.statusType.WARN, err.message, service + ': ' + bucketName);
|
|
68
|
+
if (fileGroup) {
|
|
69
|
+
for (const [content, ext, localFile] of fileGroup) {
|
|
70
|
+
try {
|
|
71
|
+
Body.push(typeof content === 'string' ? fs.readFileSync(content) : content);
|
|
72
|
+
Key.push(ext === '.map' && localFile ? path.basename(localFile) : filename + ext);
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
addLog(err);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
for (let i = 0; i < Key.length; ++i) {
|
|
80
|
+
const first = i === 0;
|
|
81
|
+
if (this.aborted) {
|
|
82
|
+
if (first) {
|
|
83
|
+
errorResponse((0, types_1.createAbortError)());
|
|
84
|
+
}
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const objectName = pathname + Key[i];
|
|
88
|
+
const type = ContentType[i] || module_1.default.lookupMime(Key[i]) || 'application/octet-stream';
|
|
89
|
+
const params = first && metadata ? { ...metadata } : { ...options };
|
|
90
|
+
const readable = publicRead || active && publicRead !== false && !acl;
|
|
91
|
+
if (first) {
|
|
92
|
+
params['Content-Type'] || (params['Content-Type'] = type);
|
|
93
|
+
if (readable) {
|
|
94
|
+
params['x-amz-acl'] = 'public-read';
|
|
95
|
+
}
|
|
96
|
+
else if (acl) {
|
|
97
|
+
params['x-amz-acl'] = acl;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
params['Content-Type'] = type;
|
|
102
|
+
if (!params['x-amz-acl']) {
|
|
103
|
+
if (readable) {
|
|
104
|
+
params['x-amz-acl'] = 'public-read';
|
|
105
|
+
}
|
|
106
|
+
else if (acl) {
|
|
107
|
+
params['x-amz-acl'] = acl;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
minio.putObject(bucketName, objectName, Body[i], Buffer.byteLength(Body[i]), params, err => {
|
|
112
|
+
if (!err) {
|
|
113
|
+
const url = module_1.default.joinPath(endpoint || module_1.default.joinPath("http://localhost:9000" /* MINIO.SERVER */, bucketName), objectName);
|
|
114
|
+
this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, "Upload success" /* CMD_CLOUD.UPLOAD_FILE */, url, { ...index_2.default.LOG_CLOUD_UPLOAD });
|
|
115
|
+
if (first) {
|
|
116
|
+
cleanup();
|
|
117
|
+
callback(null, url);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else if (first) {
|
|
121
|
+
errorResponse(err);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
addLog(err);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
exports.default = upload;
|
|
131
|
+
|
|
132
|
+
if (exports.default) {
|
|
133
|
+
module.exports = exports.default;
|
|
134
|
+
module.exports.default = exports.default;
|
|
135
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const index_1 = require("../index");
|
|
4
|
+
function download(credential, service = 'oci') {
|
|
5
|
+
(0, index_1.setStorageCredential)(credential);
|
|
6
|
+
return require('../../aws/download').call(this, credential, service);
|
|
7
|
+
}
|
|
8
|
+
exports.default = download;
|
|
9
|
+
|
|
10
|
+
if (exports.default) {
|
|
11
|
+
module.exports = exports.default;
|
|
12
|
+
module.exports.default = exports.default;
|
|
13
|
+
}
|
package/oci/index.js
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.executeBatchQuery = exports.executeQuery = exports.deleteObjectsV2 = exports.deleteObjects = exports.setBucketWebsite = exports.setBucketPolicy = exports.createBucketV2 = exports.createBucket = exports.createDatabaseClient = exports.setStorageCredential = exports.validateDatabase = exports.validateStorage = void 0;
|
|
4
|
+
const types_1 = require("../../types");
|
|
5
|
+
const aws_1 = require("../aws");
|
|
6
|
+
const util_1 = require("../util");
|
|
7
|
+
const module_1 = require("../../module");
|
|
8
|
+
function validateStorage(credential) {
|
|
9
|
+
return !!(credential.accessKeyId && credential.secretAccessKey && (credential.region && credential.namespace || credential.endpoint));
|
|
10
|
+
}
|
|
11
|
+
exports.validateStorage = validateStorage;
|
|
12
|
+
function validateDatabase(credential, data) {
|
|
13
|
+
return !!(data.table && (credential.password && (credential.user || credential.username) && (credential.connectString || credential.connectionString) || credential.poolAlias));
|
|
14
|
+
}
|
|
15
|
+
exports.validateDatabase = validateDatabase;
|
|
16
|
+
function setStorageCredential(credential) {
|
|
17
|
+
if (credential.endpoint) {
|
|
18
|
+
credential.region || (credential.region = /([^.]+)\.oraclecloud\.com$/.exec(credential.endpoint)?.[1]);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
credential.endpoint || (credential.endpoint = `https://${credential.namespace}.compat.objectstorage.${credential.region}.oraclecloud.com`);
|
|
22
|
+
}
|
|
23
|
+
credential.s3ForcePathStyle = true;
|
|
24
|
+
credential.signatureVersion = 'v4';
|
|
25
|
+
}
|
|
26
|
+
exports.setStorageCredential = setStorageCredential;
|
|
27
|
+
function createDatabaseClient(credential) {
|
|
28
|
+
try {
|
|
29
|
+
if (credential.username) {
|
|
30
|
+
credential.user || (credential.user = credential.username);
|
|
31
|
+
delete credential.username;
|
|
32
|
+
}
|
|
33
|
+
const { getConnection } = require('oracledb');
|
|
34
|
+
return getConnection(credential);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
this.checkPackage(err, 'oracledb', { passThrough: true });
|
|
38
|
+
throw err;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.createDatabaseClient = createDatabaseClient;
|
|
42
|
+
function createBucket(credential, bucket, publicRead) {
|
|
43
|
+
return aws_1.createBucketV2.call(this, credential, bucket, publicRead ? 'public-read' : undefined, undefined, 'oci');
|
|
44
|
+
}
|
|
45
|
+
exports.createBucket = createBucket;
|
|
46
|
+
function createBucketV2(credential, bucket, ACL, options) {
|
|
47
|
+
return aws_1.createBucketV2.call(this, credential, bucket, ACL, options, 'oci');
|
|
48
|
+
}
|
|
49
|
+
exports.createBucketV2 = createBucketV2;
|
|
50
|
+
function setBucketPolicy(credential, bucket, options) {
|
|
51
|
+
return aws_1.setBucketPolicy.call(this, credential, bucket, options, 'oci');
|
|
52
|
+
}
|
|
53
|
+
exports.setBucketPolicy = setBucketPolicy;
|
|
54
|
+
function setBucketWebsite(credential, bucket, options) {
|
|
55
|
+
return aws_1.setBucketWebsite.call(this, credential, bucket, options, 'oci');
|
|
56
|
+
}
|
|
57
|
+
exports.setBucketWebsite = setBucketWebsite;
|
|
58
|
+
function deleteObjects(credential, bucket) {
|
|
59
|
+
return deleteObjectsV2.call(this, credential, bucket, true);
|
|
60
|
+
}
|
|
61
|
+
exports.deleteObjects = deleteObjects;
|
|
62
|
+
function deleteObjectsV2(credential, bucket, recursive = true) {
|
|
63
|
+
setStorageCredential(credential);
|
|
64
|
+
return aws_1.deleteObjectsV2.call(this, credential, bucket, recursive, 'oci');
|
|
65
|
+
}
|
|
66
|
+
exports.deleteObjectsV2 = deleteObjectsV2;
|
|
67
|
+
async function executeQuery(credential, data, sessionKey) {
|
|
68
|
+
return (await executeBatchQuery.call(this, credential, [data], sessionKey))[0] || [];
|
|
69
|
+
}
|
|
70
|
+
exports.executeQuery = executeQuery;
|
|
71
|
+
async function executeBatchQuery(credential, batch, sessionKey) {
|
|
72
|
+
const length = batch.length;
|
|
73
|
+
const result = new Array(length);
|
|
74
|
+
const caching = length > 0 && this.hasCache(batch[0].service, sessionKey);
|
|
75
|
+
const cacheValue = { value: this.valueOfKey(credential, 'cache'), sessionKey };
|
|
76
|
+
let client;
|
|
77
|
+
const createClient = () => createDatabaseClient.call(this, length === 1 ? credential : { ...credential });
|
|
78
|
+
const closeClient = () => client?.close();
|
|
79
|
+
for (let i = 0; i < length; ++i) {
|
|
80
|
+
const item = batch[i];
|
|
81
|
+
const { service, table, id, query, ignoreCache } = item;
|
|
82
|
+
if (!table) {
|
|
83
|
+
closeClient();
|
|
84
|
+
throw (0, util_1.formatError)(item, "Missing database table" /* ERR_DB.TABLE */);
|
|
85
|
+
}
|
|
86
|
+
const renewCache = ignoreCache === 0;
|
|
87
|
+
const getCache = (value) => {
|
|
88
|
+
if (ignoreCache === 1) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
cacheValue.renewCache = renewCache;
|
|
92
|
+
return this.getQueryResult(service, credential, value, cacheValue);
|
|
93
|
+
};
|
|
94
|
+
let rows, queryString = caching && ignoreCache !== true || ignoreCache === false || ignoreCache === 1 || renewCache ? table + '_' : '';
|
|
95
|
+
invalid: {
|
|
96
|
+
if (id) {
|
|
97
|
+
const update = item.update;
|
|
98
|
+
if (queryString) {
|
|
99
|
+
queryString += id;
|
|
100
|
+
if (!update && (rows = getCache(queryString))) {
|
|
101
|
+
result[i] = rows;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const db = await (client || (client = await createClient())).getSodaDatabase().openCollection(table);
|
|
106
|
+
if (!db) {
|
|
107
|
+
closeClient();
|
|
108
|
+
throw (0, util_1.formatError)(item, "Missing database table" /* ERR_DB.TABLE */);
|
|
109
|
+
}
|
|
110
|
+
const row = db.find().key(id);
|
|
111
|
+
let document = await row.getOne();
|
|
112
|
+
if (document) {
|
|
113
|
+
rows = [document.getContent()];
|
|
114
|
+
}
|
|
115
|
+
if (update) {
|
|
116
|
+
const failed = (message, fatal) => {
|
|
117
|
+
if (fatal) {
|
|
118
|
+
item.transactionFail = true;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
delete item.update;
|
|
122
|
+
}
|
|
123
|
+
this.addLog(types_1.STATUS_TYPE.WARN, service + `-> ${message} (_id=${id})`);
|
|
124
|
+
};
|
|
125
|
+
if (rows) {
|
|
126
|
+
const status = await row.replaceOne({ ...rows[0], ...update });
|
|
127
|
+
if (status.replaced) {
|
|
128
|
+
rows = undefined;
|
|
129
|
+
if (document = await row.getOne()) {
|
|
130
|
+
rows = [document.getContent()];
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
failed('Update success (GET failed)');
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
failed('Update failed');
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
failed('Row does not exist', true);
|
|
142
|
+
break invalid;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else if (query) {
|
|
147
|
+
const maxRows = typeof item.limit === 'number' ? Math.max(item.limit, 0) : undefined;
|
|
148
|
+
if ((0, types_1.isPlainObject)(query)) {
|
|
149
|
+
if (queryString && (rows = getCache(queryString += module_1.default.asString(query, true) + (maxRows ? maxRows : '')))) {
|
|
150
|
+
result[i] = rows;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
const db = await (client || (client = await createClient())).getSodaDatabase().openCollection(table);
|
|
154
|
+
if (!db) {
|
|
155
|
+
closeClient();
|
|
156
|
+
throw (0, util_1.formatError)(item, "Missing database table" /* ERR_DB.TABLE */);
|
|
157
|
+
}
|
|
158
|
+
let operation = db.find().filter(query);
|
|
159
|
+
if (maxRows) {
|
|
160
|
+
operation = operation.limit(maxRows);
|
|
161
|
+
}
|
|
162
|
+
rows = (await operation.getDocuments()).map(doc => doc.getContent());
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
const { params, options } = item;
|
|
166
|
+
if (queryString && (rows = getCache(queryString += query + module_1.default.asString(params, true) + module_1.default.asString(options, true) + (maxRows ? maxRows : '')))) {
|
|
167
|
+
result[i] = rows;
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
({ rows } = await (client || (client = await createClient())).execute(query, params || [], { ...options, outFormat: 4002 /* OUT_FORMAT.OBJECT */, maxRows, resultSet: false, autoCommit: true }));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
closeClient();
|
|
175
|
+
throw (0, util_1.formatError)(item, "Missing database query" /* ERR_DB.QUERY */);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
result[i] = this.setQueryResult(service, credential, queryString, rows, cacheValue);
|
|
179
|
+
}
|
|
180
|
+
closeClient();
|
|
181
|
+
return result;
|
|
182
|
+
}
|
|
183
|
+
exports.executeBatchQuery = executeBatchQuery;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const index_1 = require("../index");
|
|
4
|
+
function upload(credential, service = 'oci') {
|
|
5
|
+
(0, index_1.setStorageCredential)(credential);
|
|
6
|
+
return require('../../aws/upload').call(this, credential, service);
|
|
7
|
+
}
|
|
8
|
+
exports.default = upload;
|
|
9
|
+
|
|
10
|
+
if (exports.default) {
|
|
11
|
+
module.exports = exports.default;
|
|
12
|
+
module.exports.default = exports.default;
|
|
13
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@e-mc/cloud",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Cloud constructor for e-mc.",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/anpham6/e-mc.git",
|
|
13
|
+
"directory": "src/cloud"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"squared",
|
|
17
|
+
"squared-functions"
|
|
18
|
+
],
|
|
19
|
+
"author": "An Pham <anpham6@gmail.com>",
|
|
20
|
+
"license": "BSD 3-Clause",
|
|
21
|
+
"homepage": "https://github.com/anpham6/e-mc#readme",
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@e-mc/core": "0.0.1",
|
|
24
|
+
"@e-mc/db": "0.0.1"
|
|
25
|
+
}
|
|
26
|
+
}
|
package/types.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ICloud, IFileManager, IModule, IScopeOrigin } from '../types/lib';
|
|
2
|
+
import type { BucketWebsiteOptions, CloudAsset, CloudDatabase, CloudService, CloudStorageUpload, DownloadData, UploadData } from '../types/lib/cloud';
|
|
3
|
+
import type { BatchQueryResult, QueryResult } from '../types/lib/db';
|
|
4
|
+
|
|
5
|
+
export interface ICloudServiceClient<T extends CloudDatabase = CloudDatabase> {
|
|
6
|
+
validateStorage?(credential: unknown, data?: CloudService): boolean;
|
|
7
|
+
validateDatabase?(credential: unknown, data?: CloudService): boolean;
|
|
8
|
+
createStorageClient?<U>(this: IModule, credential: unknown, service?: string): U;
|
|
9
|
+
createDatabaseClient?<U>(this: IModule, credential: unknown, data?: CloudService): U;
|
|
10
|
+
createBucket?(this: IModule, credential: unknown, bucket: string, publicRead?: boolean, service?: string, sdk?: string): Promise<boolean>;
|
|
11
|
+
createBucketV2?(this: IModule, credential: unknown, bucket: string, acl?: unknown, options?: unknown, service?: string, sdk?: string): Promise<boolean>;
|
|
12
|
+
setBucketPolicy?(this: IModule, credential: unknown, bucket: string, options: unknown, service?: string, sdk?: string): Promise<boolean>;
|
|
13
|
+
setBucketWebsite?(this: IModule, credential: unknown, bucket: string, options: BucketWebsiteOptions, service?: string, sdk?: string): Promise<boolean>;
|
|
14
|
+
deleteObjects?(this: IModule, credential: unknown, bucket: string, service?: string, sdk?: string, recursive?: boolean): Promise<void>;
|
|
15
|
+
deleteObjectsV2?(this: IModule, credential: unknown, bucket: string, recursive?: boolean, service?: string, sdk?: string): Promise<void>;
|
|
16
|
+
executeQuery?(this: ICloud, credential: unknown, data: T, sessionKey?: string): Promise<QueryResult>;
|
|
17
|
+
executeBatchQuery?(this: ICloud, credential: unknown, batch: T[], sessionKey?: string): Promise<BatchQueryResult>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface CloudScopeOrigin<T extends IFileManager<U>, U extends CloudAsset = CloudAsset, V extends ICloud = ICloud> extends Required<IScopeOrigin<T, V>> {
|
|
21
|
+
bucketGroup: string;
|
|
22
|
+
localStorage: Map<U, CloudStorageUpload>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type ServiceHost<T> = (this: IModule, credential: unknown, service?: string, sdk?: string) => T;
|
|
26
|
+
export type UploadCallback = (data: UploadData, callback: (err: unknown, value?: string) => void) => void;
|
|
27
|
+
export type DownloadCallback = (data: DownloadData, callback: (err: unknown, value?: Null<BufferContent>) => void) => void;
|
|
28
|
+
export type UploadHost = ServiceHost<UploadCallback>;
|
|
29
|
+
export type DownloadHost = ServiceHost<DownloadCallback>;
|
package/util.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Readable } from 'stream';
|
|
2
|
+
|
|
3
|
+
declare namespace util {
|
|
4
|
+
function readableAsBuffer(stream: Readable): Promise<Buffer | null>;
|
|
5
|
+
function generateFilename(filename: string): (i: number) => [string, boolean];
|
|
6
|
+
function getBasicAuth(auth: AuthValue): string;
|
|
7
|
+
function getBasicAuth(username: unknown, password?: unknown): string;
|
|
8
|
+
function hasBasicAuth(value: string): boolean;
|
|
9
|
+
function formatError(title: string | { service: string; }, message: string, hint?: string): Error;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export = util;
|