@budibase/backend-core 2.11.43 → 2.11.45
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/dist/index.js +372 -344
- package/dist/index.js.map +3 -3
- package/dist/index.js.meta.json +1 -1
- package/dist/package.json +4 -4
- package/dist/src/objectStore/buckets/app.d.ts +7 -10
- package/dist/src/objectStore/buckets/app.js +40 -27
- package/dist/src/objectStore/buckets/app.js.map +1 -1
- package/dist/src/objectStore/buckets/plugins.d.ts +4 -4
- package/dist/src/objectStore/buckets/plugins.js +19 -19
- package/dist/src/objectStore/buckets/plugins.js.map +1 -1
- package/dist/src/objectStore/objectStore.d.ts +19 -16
- package/dist/src/objectStore/objectStore.js +257 -218
- package/dist/src/objectStore/objectStore.js.map +1 -1
- package/package.json +4 -4
- package/src/objectStore/buckets/app.ts +36 -23
- package/src/objectStore/buckets/plugins.ts +8 -8
- package/src/objectStore/buckets/tests/app.spec.ts +16 -26
- package/src/objectStore/objectStore.ts +38 -24
package/dist/index.js
CHANGED
|
@@ -4734,7 +4734,282 @@ function sanitizeKey(input) {
|
|
|
4734
4734
|
function sanitizeBucket(input) {
|
|
4735
4735
|
return input.replace(new RegExp(APP_DEV_PREFIX, "g"), APP_PREFIX);
|
|
4736
4736
|
}
|
|
4737
|
-
|
|
4737
|
+
function ObjectStore(bucket, opts = { presigning: false }) {
|
|
4738
|
+
const config = {
|
|
4739
|
+
s3ForcePathStyle: true,
|
|
4740
|
+
signatureVersion: "v4",
|
|
4741
|
+
apiVersion: "2006-03-01",
|
|
4742
|
+
accessKeyId: environment_default.MINIO_ACCESS_KEY,
|
|
4743
|
+
secretAccessKey: environment_default.MINIO_SECRET_KEY,
|
|
4744
|
+
region: environment_default.AWS_REGION
|
|
4745
|
+
};
|
|
4746
|
+
if (bucket) {
|
|
4747
|
+
config.params = {
|
|
4748
|
+
Bucket: sanitizeBucket(bucket)
|
|
4749
|
+
};
|
|
4750
|
+
}
|
|
4751
|
+
if (environment_default.MINIO_URL) {
|
|
4752
|
+
if (opts.presigning && environment_default.MINIO_ENABLED) {
|
|
4753
|
+
config.endpoint = "minio-service";
|
|
4754
|
+
} else {
|
|
4755
|
+
config.endpoint = environment_default.MINIO_URL;
|
|
4756
|
+
}
|
|
4757
|
+
}
|
|
4758
|
+
return new import_aws_sdk.default.S3(config);
|
|
4759
|
+
}
|
|
4760
|
+
async function makeSureBucketExists(client, bucketName) {
|
|
4761
|
+
bucketName = sanitizeBucket(bucketName);
|
|
4762
|
+
try {
|
|
4763
|
+
await client.headBucket({
|
|
4764
|
+
Bucket: bucketName
|
|
4765
|
+
}).promise();
|
|
4766
|
+
} catch (err) {
|
|
4767
|
+
const promises = STATE.bucketCreationPromises;
|
|
4768
|
+
const doesntExist = err.statusCode === 404, noAccess = err.statusCode === 403;
|
|
4769
|
+
if (promises[bucketName]) {
|
|
4770
|
+
await promises[bucketName];
|
|
4771
|
+
} else if (doesntExist || noAccess) {
|
|
4772
|
+
if (doesntExist) {
|
|
4773
|
+
promises[bucketName] = client.createBucket({
|
|
4774
|
+
Bucket: bucketName
|
|
4775
|
+
}).promise();
|
|
4776
|
+
await promises[bucketName];
|
|
4777
|
+
delete promises[bucketName];
|
|
4778
|
+
}
|
|
4779
|
+
} else {
|
|
4780
|
+
throw new Error("Unable to write to object store bucket.");
|
|
4781
|
+
}
|
|
4782
|
+
}
|
|
4783
|
+
}
|
|
4784
|
+
async function upload({
|
|
4785
|
+
bucket: bucketName,
|
|
4786
|
+
filename,
|
|
4787
|
+
path: path2,
|
|
4788
|
+
type,
|
|
4789
|
+
metadata
|
|
4790
|
+
}) {
|
|
4791
|
+
const extension = filename.split(".").pop();
|
|
4792
|
+
const fileBytes = import_fs3.default.readFileSync(path2);
|
|
4793
|
+
const objectStore = ObjectStore(bucketName);
|
|
4794
|
+
await makeSureBucketExists(objectStore, bucketName);
|
|
4795
|
+
let contentType = type;
|
|
4796
|
+
if (!contentType) {
|
|
4797
|
+
contentType = extension ? CONTENT_TYPE_MAP[extension.toLowerCase()] : CONTENT_TYPE_MAP.txt;
|
|
4798
|
+
}
|
|
4799
|
+
const config = {
|
|
4800
|
+
// windows file paths need to be converted to forward slashes for s3
|
|
4801
|
+
Key: sanitizeKey(filename),
|
|
4802
|
+
Body: fileBytes,
|
|
4803
|
+
ContentType: contentType
|
|
4804
|
+
};
|
|
4805
|
+
if (metadata && typeof metadata === "object") {
|
|
4806
|
+
for (let key of Object.keys(metadata)) {
|
|
4807
|
+
if (!metadata[key] || typeof metadata[key] !== "string") {
|
|
4808
|
+
delete metadata[key];
|
|
4809
|
+
}
|
|
4810
|
+
}
|
|
4811
|
+
config.Metadata = metadata;
|
|
4812
|
+
}
|
|
4813
|
+
return objectStore.upload(config).promise();
|
|
4814
|
+
}
|
|
4815
|
+
async function streamUpload(bucketName, filename, stream2, extra = {}) {
|
|
4816
|
+
const objectStore = ObjectStore(bucketName);
|
|
4817
|
+
await makeSureBucketExists(objectStore, bucketName);
|
|
4818
|
+
if (filename?.endsWith(".js")) {
|
|
4819
|
+
extra = {
|
|
4820
|
+
...extra,
|
|
4821
|
+
ContentType: "application/javascript"
|
|
4822
|
+
};
|
|
4823
|
+
} else if (filename?.endsWith(".svg")) {
|
|
4824
|
+
extra = {
|
|
4825
|
+
...extra,
|
|
4826
|
+
ContentType: "image"
|
|
4827
|
+
};
|
|
4828
|
+
}
|
|
4829
|
+
const params2 = {
|
|
4830
|
+
Bucket: sanitizeBucket(bucketName),
|
|
4831
|
+
Key: sanitizeKey(filename),
|
|
4832
|
+
Body: stream2,
|
|
4833
|
+
...extra
|
|
4834
|
+
};
|
|
4835
|
+
return objectStore.upload(params2).promise();
|
|
4836
|
+
}
|
|
4837
|
+
async function retrieve(bucketName, filepath) {
|
|
4838
|
+
const objectStore = ObjectStore(bucketName);
|
|
4839
|
+
const params2 = {
|
|
4840
|
+
Bucket: sanitizeBucket(bucketName),
|
|
4841
|
+
Key: sanitizeKey(filepath)
|
|
4842
|
+
};
|
|
4843
|
+
const response = await objectStore.getObject(params2).promise();
|
|
4844
|
+
if (STRING_CONTENT_TYPES.includes(response.ContentType)) {
|
|
4845
|
+
return response.Body.toString("utf8");
|
|
4846
|
+
} else {
|
|
4847
|
+
return response.Body;
|
|
4848
|
+
}
|
|
4849
|
+
}
|
|
4850
|
+
async function listAllObjects(bucketName, path2) {
|
|
4851
|
+
const objectStore = ObjectStore(bucketName);
|
|
4852
|
+
const list = (params2 = {}) => {
|
|
4853
|
+
return objectStore.listObjectsV2({
|
|
4854
|
+
...params2,
|
|
4855
|
+
Bucket: sanitizeBucket(bucketName),
|
|
4856
|
+
Prefix: sanitizeKey(path2)
|
|
4857
|
+
}).promise();
|
|
4858
|
+
};
|
|
4859
|
+
let isTruncated = false, token, objects = [];
|
|
4860
|
+
do {
|
|
4861
|
+
let params2 = {};
|
|
4862
|
+
if (token) {
|
|
4863
|
+
params2.ContinuationToken = token;
|
|
4864
|
+
}
|
|
4865
|
+
const response = await list(params2);
|
|
4866
|
+
if (response.Contents) {
|
|
4867
|
+
objects = objects.concat(response.Contents);
|
|
4868
|
+
}
|
|
4869
|
+
isTruncated = !!response.IsTruncated;
|
|
4870
|
+
} while (isTruncated);
|
|
4871
|
+
return objects;
|
|
4872
|
+
}
|
|
4873
|
+
function getPresignedUrl(bucketName, key, durationSeconds = 3600) {
|
|
4874
|
+
const objectStore = ObjectStore(bucketName, { presigning: true });
|
|
4875
|
+
const params2 = {
|
|
4876
|
+
Bucket: sanitizeBucket(bucketName),
|
|
4877
|
+
Key: sanitizeKey(key),
|
|
4878
|
+
Expires: durationSeconds
|
|
4879
|
+
};
|
|
4880
|
+
const url = objectStore.getSignedUrl("getObject", params2);
|
|
4881
|
+
if (!environment_default.MINIO_ENABLED) {
|
|
4882
|
+
return url;
|
|
4883
|
+
} else {
|
|
4884
|
+
const signedUrl = new URL(url);
|
|
4885
|
+
const path2 = signedUrl.pathname;
|
|
4886
|
+
const query = signedUrl.search;
|
|
4887
|
+
return `/files/signed${path2}${query}`;
|
|
4888
|
+
}
|
|
4889
|
+
}
|
|
4890
|
+
async function retrieveToTmp(bucketName, filepath) {
|
|
4891
|
+
bucketName = sanitizeBucket(bucketName);
|
|
4892
|
+
filepath = sanitizeKey(filepath);
|
|
4893
|
+
const data = await retrieve(bucketName, filepath);
|
|
4894
|
+
const outputPath = (0, import_path2.join)(budibaseTempDir(), (0, import_uuid2.v4)());
|
|
4895
|
+
import_fs3.default.writeFileSync(outputPath, data);
|
|
4896
|
+
return outputPath;
|
|
4897
|
+
}
|
|
4898
|
+
async function retrieveDirectory(bucketName, path2) {
|
|
4899
|
+
let writePath = (0, import_path2.join)(budibaseTempDir(), (0, import_uuid2.v4)());
|
|
4900
|
+
import_fs3.default.mkdirSync(writePath);
|
|
4901
|
+
const objects = await listAllObjects(bucketName, path2);
|
|
4902
|
+
let fullObjects = await Promise.all(
|
|
4903
|
+
objects.map((obj) => retrieve(bucketName, obj.Key))
|
|
4904
|
+
);
|
|
4905
|
+
let count = 0;
|
|
4906
|
+
for (let obj of objects) {
|
|
4907
|
+
const filename = obj.Key;
|
|
4908
|
+
const data = fullObjects[count++];
|
|
4909
|
+
const possiblePath = filename.split("/");
|
|
4910
|
+
if (possiblePath.length > 1) {
|
|
4911
|
+
const dirs = possiblePath.slice(0, possiblePath.length - 1);
|
|
4912
|
+
import_fs3.default.mkdirSync((0, import_path2.join)(writePath, ...dirs), { recursive: true });
|
|
4913
|
+
}
|
|
4914
|
+
import_fs3.default.writeFileSync((0, import_path2.join)(writePath, ...possiblePath), data);
|
|
4915
|
+
}
|
|
4916
|
+
return writePath;
|
|
4917
|
+
}
|
|
4918
|
+
async function deleteFile(bucketName, filepath) {
|
|
4919
|
+
const objectStore = ObjectStore(bucketName);
|
|
4920
|
+
await makeSureBucketExists(objectStore, bucketName);
|
|
4921
|
+
const params2 = {
|
|
4922
|
+
Bucket: bucketName,
|
|
4923
|
+
Key: sanitizeKey(filepath)
|
|
4924
|
+
};
|
|
4925
|
+
return objectStore.deleteObject(params2).promise();
|
|
4926
|
+
}
|
|
4927
|
+
async function deleteFiles(bucketName, filepaths) {
|
|
4928
|
+
const objectStore = ObjectStore(bucketName);
|
|
4929
|
+
await makeSureBucketExists(objectStore, bucketName);
|
|
4930
|
+
const params2 = {
|
|
4931
|
+
Bucket: bucketName,
|
|
4932
|
+
Delete: {
|
|
4933
|
+
Objects: filepaths.map((path2) => ({ Key: sanitizeKey(path2) }))
|
|
4934
|
+
}
|
|
4935
|
+
};
|
|
4936
|
+
return objectStore.deleteObjects(params2).promise();
|
|
4937
|
+
}
|
|
4938
|
+
async function deleteFolder(bucketName, folder) {
|
|
4939
|
+
bucketName = sanitizeBucket(bucketName);
|
|
4940
|
+
folder = sanitizeKey(folder);
|
|
4941
|
+
const client = ObjectStore(bucketName);
|
|
4942
|
+
const listParams = {
|
|
4943
|
+
Bucket: bucketName,
|
|
4944
|
+
Prefix: folder
|
|
4945
|
+
};
|
|
4946
|
+
const existingObjectsResponse = await client.listObjects(listParams).promise();
|
|
4947
|
+
if (existingObjectsResponse.Contents?.length === 0) {
|
|
4948
|
+
return;
|
|
4949
|
+
}
|
|
4950
|
+
const deleteParams = {
|
|
4951
|
+
Bucket: bucketName,
|
|
4952
|
+
Delete: {
|
|
4953
|
+
Objects: []
|
|
4954
|
+
}
|
|
4955
|
+
};
|
|
4956
|
+
existingObjectsResponse.Contents?.forEach((content) => {
|
|
4957
|
+
deleteParams.Delete.Objects.push({ Key: content.Key });
|
|
4958
|
+
});
|
|
4959
|
+
const deleteResponse = await client.deleteObjects(deleteParams).promise();
|
|
4960
|
+
if (deleteResponse.Deleted?.length === 1e3) {
|
|
4961
|
+
return deleteFolder(bucketName, folder);
|
|
4962
|
+
}
|
|
4963
|
+
}
|
|
4964
|
+
async function uploadDirectory(bucketName, localPath, bucketPath) {
|
|
4965
|
+
bucketName = sanitizeBucket(bucketName);
|
|
4966
|
+
let uploads = [];
|
|
4967
|
+
const files = import_fs3.default.readdirSync(localPath, { withFileTypes: true });
|
|
4968
|
+
for (let file of files) {
|
|
4969
|
+
const path2 = sanitizeKey((0, import_path2.join)(bucketPath, file.name));
|
|
4970
|
+
const local = (0, import_path2.join)(localPath, file.name);
|
|
4971
|
+
if (file.isDirectory()) {
|
|
4972
|
+
uploads.push(uploadDirectory(bucketName, local, path2));
|
|
4973
|
+
} else {
|
|
4974
|
+
uploads.push(streamUpload(bucketName, path2, import_fs3.default.createReadStream(local)));
|
|
4975
|
+
}
|
|
4976
|
+
}
|
|
4977
|
+
await Promise.all(uploads);
|
|
4978
|
+
return files;
|
|
4979
|
+
}
|
|
4980
|
+
async function downloadTarballDirect(url, path2, headers = {}) {
|
|
4981
|
+
path2 = sanitizeKey(path2);
|
|
4982
|
+
const response = await (0, import_node_fetch3.default)(url, { headers });
|
|
4983
|
+
if (!response.ok) {
|
|
4984
|
+
throw new Error(`unexpected response ${response.statusText}`);
|
|
4985
|
+
}
|
|
4986
|
+
await streamPipeline(response.body, import_zlib.default.createUnzip(), import_tar_fs.default.extract(path2));
|
|
4987
|
+
}
|
|
4988
|
+
async function downloadTarball(url, bucketName, path2) {
|
|
4989
|
+
bucketName = sanitizeBucket(bucketName);
|
|
4990
|
+
path2 = sanitizeKey(path2);
|
|
4991
|
+
const response = await (0, import_node_fetch3.default)(url);
|
|
4992
|
+
if (!response.ok) {
|
|
4993
|
+
throw new Error(`unexpected response ${response.statusText}`);
|
|
4994
|
+
}
|
|
4995
|
+
const tmpPath = (0, import_path2.join)(budibaseTempDir(), path2);
|
|
4996
|
+
await streamPipeline(response.body, import_zlib.default.createUnzip(), import_tar_fs.default.extract(tmpPath));
|
|
4997
|
+
if (!environment_default.isTest() && environment_default.SELF_HOSTED) {
|
|
4998
|
+
await uploadDirectory(bucketName, tmpPath, path2);
|
|
4999
|
+
}
|
|
5000
|
+
return tmpPath;
|
|
5001
|
+
}
|
|
5002
|
+
async function getReadStream(bucketName, path2) {
|
|
5003
|
+
bucketName = sanitizeBucket(bucketName);
|
|
5004
|
+
path2 = sanitizeKey(path2);
|
|
5005
|
+
const client = ObjectStore(bucketName);
|
|
5006
|
+
const params2 = {
|
|
5007
|
+
Bucket: bucketName,
|
|
5008
|
+
Key: path2
|
|
5009
|
+
};
|
|
5010
|
+
return client.getObject(params2).createReadStream();
|
|
5011
|
+
}
|
|
5012
|
+
var import_aws_sdk, import_stream, import_node_fetch3, import_tar_fs, import_zlib, import_util, import_path2, import_fs3, import_uuid2, sanitize, streamPipeline, STATE, CONTENT_TYPE_MAP, STRING_CONTENT_TYPES;
|
|
4738
5013
|
var init_objectStore = __esm({
|
|
4739
5014
|
"src/objectStore/objectStore.ts"() {
|
|
4740
5015
|
"use strict";
|
|
@@ -4769,271 +5044,6 @@ var init_objectStore = __esm({
|
|
|
4769
5044
|
CONTENT_TYPE_MAP.js,
|
|
4770
5045
|
CONTENT_TYPE_MAP.json
|
|
4771
5046
|
];
|
|
4772
|
-
ObjectStore = (bucket, opts = { presigning: false }) => {
|
|
4773
|
-
const config = {
|
|
4774
|
-
s3ForcePathStyle: true,
|
|
4775
|
-
signatureVersion: "v4",
|
|
4776
|
-
apiVersion: "2006-03-01",
|
|
4777
|
-
accessKeyId: environment_default.MINIO_ACCESS_KEY,
|
|
4778
|
-
secretAccessKey: environment_default.MINIO_SECRET_KEY,
|
|
4779
|
-
region: environment_default.AWS_REGION
|
|
4780
|
-
};
|
|
4781
|
-
if (bucket) {
|
|
4782
|
-
config.params = {
|
|
4783
|
-
Bucket: sanitizeBucket(bucket)
|
|
4784
|
-
};
|
|
4785
|
-
}
|
|
4786
|
-
if (environment_default.MINIO_URL) {
|
|
4787
|
-
if (opts.presigning && environment_default.MINIO_ENABLED) {
|
|
4788
|
-
config.endpoint = "minio-service";
|
|
4789
|
-
} else {
|
|
4790
|
-
config.endpoint = environment_default.MINIO_URL;
|
|
4791
|
-
}
|
|
4792
|
-
}
|
|
4793
|
-
return new import_aws_sdk.default.S3(config);
|
|
4794
|
-
};
|
|
4795
|
-
makeSureBucketExists = async (client, bucketName) => {
|
|
4796
|
-
bucketName = sanitizeBucket(bucketName);
|
|
4797
|
-
try {
|
|
4798
|
-
await client.headBucket({
|
|
4799
|
-
Bucket: bucketName
|
|
4800
|
-
}).promise();
|
|
4801
|
-
} catch (err) {
|
|
4802
|
-
const promises = STATE.bucketCreationPromises;
|
|
4803
|
-
const doesntExist = err.statusCode === 404, noAccess = err.statusCode === 403;
|
|
4804
|
-
if (promises[bucketName]) {
|
|
4805
|
-
await promises[bucketName];
|
|
4806
|
-
} else if (doesntExist || noAccess) {
|
|
4807
|
-
if (doesntExist) {
|
|
4808
|
-
promises[bucketName] = client.createBucket({
|
|
4809
|
-
Bucket: bucketName
|
|
4810
|
-
}).promise();
|
|
4811
|
-
await promises[bucketName];
|
|
4812
|
-
delete promises[bucketName];
|
|
4813
|
-
}
|
|
4814
|
-
} else {
|
|
4815
|
-
throw new Error("Unable to write to object store bucket.");
|
|
4816
|
-
}
|
|
4817
|
-
}
|
|
4818
|
-
};
|
|
4819
|
-
upload = async ({
|
|
4820
|
-
bucket: bucketName,
|
|
4821
|
-
filename,
|
|
4822
|
-
path: path2,
|
|
4823
|
-
type,
|
|
4824
|
-
metadata
|
|
4825
|
-
}) => {
|
|
4826
|
-
const extension = filename.split(".").pop();
|
|
4827
|
-
const fileBytes = import_fs3.default.readFileSync(path2);
|
|
4828
|
-
const objectStore = ObjectStore(bucketName);
|
|
4829
|
-
await makeSureBucketExists(objectStore, bucketName);
|
|
4830
|
-
let contentType = type;
|
|
4831
|
-
if (!contentType) {
|
|
4832
|
-
contentType = extension ? CONTENT_TYPE_MAP[extension.toLowerCase()] : CONTENT_TYPE_MAP.txt;
|
|
4833
|
-
}
|
|
4834
|
-
const config = {
|
|
4835
|
-
// windows file paths need to be converted to forward slashes for s3
|
|
4836
|
-
Key: sanitizeKey(filename),
|
|
4837
|
-
Body: fileBytes,
|
|
4838
|
-
ContentType: contentType
|
|
4839
|
-
};
|
|
4840
|
-
if (metadata && typeof metadata === "object") {
|
|
4841
|
-
for (let key of Object.keys(metadata)) {
|
|
4842
|
-
if (!metadata[key] || typeof metadata[key] !== "string") {
|
|
4843
|
-
delete metadata[key];
|
|
4844
|
-
}
|
|
4845
|
-
}
|
|
4846
|
-
config.Metadata = metadata;
|
|
4847
|
-
}
|
|
4848
|
-
return objectStore.upload(config).promise();
|
|
4849
|
-
};
|
|
4850
|
-
streamUpload = async (bucketName, filename, stream2, extra = {}) => {
|
|
4851
|
-
const objectStore = ObjectStore(bucketName);
|
|
4852
|
-
await makeSureBucketExists(objectStore, bucketName);
|
|
4853
|
-
if (filename?.endsWith(".js")) {
|
|
4854
|
-
extra = {
|
|
4855
|
-
...extra,
|
|
4856
|
-
ContentType: "application/javascript"
|
|
4857
|
-
};
|
|
4858
|
-
} else if (filename?.endsWith(".svg")) {
|
|
4859
|
-
extra = {
|
|
4860
|
-
...extra,
|
|
4861
|
-
ContentType: "image"
|
|
4862
|
-
};
|
|
4863
|
-
}
|
|
4864
|
-
const params2 = {
|
|
4865
|
-
Bucket: sanitizeBucket(bucketName),
|
|
4866
|
-
Key: sanitizeKey(filename),
|
|
4867
|
-
Body: stream2,
|
|
4868
|
-
...extra
|
|
4869
|
-
};
|
|
4870
|
-
return objectStore.upload(params2).promise();
|
|
4871
|
-
};
|
|
4872
|
-
retrieve = async (bucketName, filepath) => {
|
|
4873
|
-
const objectStore = ObjectStore(bucketName);
|
|
4874
|
-
const params2 = {
|
|
4875
|
-
Bucket: sanitizeBucket(bucketName),
|
|
4876
|
-
Key: sanitizeKey(filepath)
|
|
4877
|
-
};
|
|
4878
|
-
const response = await objectStore.getObject(params2).promise();
|
|
4879
|
-
if (STRING_CONTENT_TYPES.includes(response.ContentType)) {
|
|
4880
|
-
return response.Body.toString("utf8");
|
|
4881
|
-
} else {
|
|
4882
|
-
return response.Body;
|
|
4883
|
-
}
|
|
4884
|
-
};
|
|
4885
|
-
listAllObjects = async (bucketName, path2) => {
|
|
4886
|
-
const objectStore = ObjectStore(bucketName);
|
|
4887
|
-
const list = (params2 = {}) => {
|
|
4888
|
-
return objectStore.listObjectsV2({
|
|
4889
|
-
...params2,
|
|
4890
|
-
Bucket: sanitizeBucket(bucketName),
|
|
4891
|
-
Prefix: sanitizeKey(path2)
|
|
4892
|
-
}).promise();
|
|
4893
|
-
};
|
|
4894
|
-
let isTruncated = false, token, objects = [];
|
|
4895
|
-
do {
|
|
4896
|
-
let params2 = {};
|
|
4897
|
-
if (token) {
|
|
4898
|
-
params2.ContinuationToken = token;
|
|
4899
|
-
}
|
|
4900
|
-
const response = await list(params2);
|
|
4901
|
-
if (response.Contents) {
|
|
4902
|
-
objects = objects.concat(response.Contents);
|
|
4903
|
-
}
|
|
4904
|
-
isTruncated = !!response.IsTruncated;
|
|
4905
|
-
} while (isTruncated);
|
|
4906
|
-
return objects;
|
|
4907
|
-
};
|
|
4908
|
-
getPresignedUrl = (bucketName, key, durationSeconds = 3600) => {
|
|
4909
|
-
const objectStore = ObjectStore(bucketName, { presigning: true });
|
|
4910
|
-
const params2 = {
|
|
4911
|
-
Bucket: sanitizeBucket(bucketName),
|
|
4912
|
-
Key: sanitizeKey(key),
|
|
4913
|
-
Expires: durationSeconds
|
|
4914
|
-
};
|
|
4915
|
-
const url = objectStore.getSignedUrl("getObject", params2);
|
|
4916
|
-
if (!environment_default.MINIO_ENABLED) {
|
|
4917
|
-
return url;
|
|
4918
|
-
} else {
|
|
4919
|
-
const signedUrl = new URL(url);
|
|
4920
|
-
const path2 = signedUrl.pathname;
|
|
4921
|
-
const query = signedUrl.search;
|
|
4922
|
-
return `/files/signed${path2}${query}`;
|
|
4923
|
-
}
|
|
4924
|
-
};
|
|
4925
|
-
retrieveToTmp = async (bucketName, filepath) => {
|
|
4926
|
-
bucketName = sanitizeBucket(bucketName);
|
|
4927
|
-
filepath = sanitizeKey(filepath);
|
|
4928
|
-
const data = await retrieve(bucketName, filepath);
|
|
4929
|
-
const outputPath = (0, import_path2.join)(budibaseTempDir(), (0, import_uuid2.v4)());
|
|
4930
|
-
import_fs3.default.writeFileSync(outputPath, data);
|
|
4931
|
-
return outputPath;
|
|
4932
|
-
};
|
|
4933
|
-
retrieveDirectory = async (bucketName, path2) => {
|
|
4934
|
-
let writePath = (0, import_path2.join)(budibaseTempDir(), (0, import_uuid2.v4)());
|
|
4935
|
-
import_fs3.default.mkdirSync(writePath);
|
|
4936
|
-
const objects = await listAllObjects(bucketName, path2);
|
|
4937
|
-
let fullObjects = await Promise.all(
|
|
4938
|
-
objects.map((obj) => retrieve(bucketName, obj.Key))
|
|
4939
|
-
);
|
|
4940
|
-
let count = 0;
|
|
4941
|
-
for (let obj of objects) {
|
|
4942
|
-
const filename = obj.Key;
|
|
4943
|
-
const data = fullObjects[count++];
|
|
4944
|
-
const possiblePath = filename.split("/");
|
|
4945
|
-
if (possiblePath.length > 1) {
|
|
4946
|
-
const dirs = possiblePath.slice(0, possiblePath.length - 1);
|
|
4947
|
-
import_fs3.default.mkdirSync((0, import_path2.join)(writePath, ...dirs), { recursive: true });
|
|
4948
|
-
}
|
|
4949
|
-
import_fs3.default.writeFileSync((0, import_path2.join)(writePath, ...possiblePath), data);
|
|
4950
|
-
}
|
|
4951
|
-
return writePath;
|
|
4952
|
-
};
|
|
4953
|
-
deleteFile = async (bucketName, filepath) => {
|
|
4954
|
-
const objectStore = ObjectStore(bucketName);
|
|
4955
|
-
await makeSureBucketExists(objectStore, bucketName);
|
|
4956
|
-
const params2 = {
|
|
4957
|
-
Bucket: bucketName,
|
|
4958
|
-
Key: sanitizeKey(filepath)
|
|
4959
|
-
};
|
|
4960
|
-
return objectStore.deleteObject(params2).promise();
|
|
4961
|
-
};
|
|
4962
|
-
deleteFiles = async (bucketName, filepaths) => {
|
|
4963
|
-
const objectStore = ObjectStore(bucketName);
|
|
4964
|
-
await makeSureBucketExists(objectStore, bucketName);
|
|
4965
|
-
const params2 = {
|
|
4966
|
-
Bucket: bucketName,
|
|
4967
|
-
Delete: {
|
|
4968
|
-
Objects: filepaths.map((path2) => ({ Key: sanitizeKey(path2) }))
|
|
4969
|
-
}
|
|
4970
|
-
};
|
|
4971
|
-
return objectStore.deleteObjects(params2).promise();
|
|
4972
|
-
};
|
|
4973
|
-
deleteFolder = async (bucketName, folder) => {
|
|
4974
|
-
bucketName = sanitizeBucket(bucketName);
|
|
4975
|
-
folder = sanitizeKey(folder);
|
|
4976
|
-
const client = ObjectStore(bucketName);
|
|
4977
|
-
const listParams = {
|
|
4978
|
-
Bucket: bucketName,
|
|
4979
|
-
Prefix: folder
|
|
4980
|
-
};
|
|
4981
|
-
const existingObjectsResponse = await client.listObjects(listParams).promise();
|
|
4982
|
-
if (existingObjectsResponse.Contents?.length === 0) {
|
|
4983
|
-
return;
|
|
4984
|
-
}
|
|
4985
|
-
const deleteParams = {
|
|
4986
|
-
Bucket: bucketName,
|
|
4987
|
-
Delete: {
|
|
4988
|
-
Objects: []
|
|
4989
|
-
}
|
|
4990
|
-
};
|
|
4991
|
-
existingObjectsResponse.Contents?.forEach((content) => {
|
|
4992
|
-
deleteParams.Delete.Objects.push({ Key: content.Key });
|
|
4993
|
-
});
|
|
4994
|
-
const deleteResponse = await client.deleteObjects(deleteParams).promise();
|
|
4995
|
-
if (deleteResponse.Deleted?.length === 1e3) {
|
|
4996
|
-
return deleteFolder(bucketName, folder);
|
|
4997
|
-
}
|
|
4998
|
-
};
|
|
4999
|
-
uploadDirectory = async (bucketName, localPath, bucketPath) => {
|
|
5000
|
-
bucketName = sanitizeBucket(bucketName);
|
|
5001
|
-
let uploads = [];
|
|
5002
|
-
const files = import_fs3.default.readdirSync(localPath, { withFileTypes: true });
|
|
5003
|
-
for (let file of files) {
|
|
5004
|
-
const path2 = sanitizeKey((0, import_path2.join)(bucketPath, file.name));
|
|
5005
|
-
const local = (0, import_path2.join)(localPath, file.name);
|
|
5006
|
-
if (file.isDirectory()) {
|
|
5007
|
-
uploads.push(uploadDirectory(bucketName, local, path2));
|
|
5008
|
-
} else {
|
|
5009
|
-
uploads.push(streamUpload(bucketName, path2, import_fs3.default.createReadStream(local)));
|
|
5010
|
-
}
|
|
5011
|
-
}
|
|
5012
|
-
await Promise.all(uploads);
|
|
5013
|
-
return files;
|
|
5014
|
-
};
|
|
5015
|
-
downloadTarballDirect = async (url, path2, headers = {}) => {
|
|
5016
|
-
path2 = sanitizeKey(path2);
|
|
5017
|
-
const response = await (0, import_node_fetch3.default)(url, { headers });
|
|
5018
|
-
if (!response.ok) {
|
|
5019
|
-
throw new Error(`unexpected response ${response.statusText}`);
|
|
5020
|
-
}
|
|
5021
|
-
await streamPipeline(response.body, import_zlib.default.createUnzip(), import_tar_fs.default.extract(path2));
|
|
5022
|
-
};
|
|
5023
|
-
downloadTarball = async (url, bucketName, path2) => {
|
|
5024
|
-
bucketName = sanitizeBucket(bucketName);
|
|
5025
|
-
path2 = sanitizeKey(path2);
|
|
5026
|
-
const response = await (0, import_node_fetch3.default)(url);
|
|
5027
|
-
if (!response.ok) {
|
|
5028
|
-
throw new Error(`unexpected response ${response.statusText}`);
|
|
5029
|
-
}
|
|
5030
|
-
const tmpPath = (0, import_path2.join)(budibaseTempDir(), path2);
|
|
5031
|
-
await streamPipeline(response.body, import_zlib.default.createUnzip(), import_tar_fs.default.extract(tmpPath));
|
|
5032
|
-
if (!environment_default.isTest() && environment_default.SELF_HOSTED) {
|
|
5033
|
-
await uploadDirectory(bucketName, tmpPath, path2);
|
|
5034
|
-
}
|
|
5035
|
-
return tmpPath;
|
|
5036
|
-
};
|
|
5037
5047
|
}
|
|
5038
5048
|
});
|
|
5039
5049
|
|
|
@@ -5079,35 +5089,51 @@ var init_cloudfront = __esm({
|
|
|
5079
5089
|
});
|
|
5080
5090
|
|
|
5081
5091
|
// src/objectStore/buckets/app.ts
|
|
5082
|
-
|
|
5092
|
+
function clientLibraryPath(appId) {
|
|
5093
|
+
return `${sanitizeKey(appId)}/budibase-client.js`;
|
|
5094
|
+
}
|
|
5095
|
+
function clientLibraryCDNUrl(appId, version) {
|
|
5096
|
+
let file = clientLibraryPath(appId);
|
|
5097
|
+
if (environment_default.CLOUDFRONT_CDN) {
|
|
5098
|
+
if (version) {
|
|
5099
|
+
file += `?v=${version}`;
|
|
5100
|
+
}
|
|
5101
|
+
return getUrl(file);
|
|
5102
|
+
} else {
|
|
5103
|
+
return getPresignedUrl(environment_default.APPS_BUCKET_NAME, file);
|
|
5104
|
+
}
|
|
5105
|
+
}
|
|
5106
|
+
function clientLibraryUrl(appId, version) {
|
|
5107
|
+
let tenantId, qsParams;
|
|
5108
|
+
try {
|
|
5109
|
+
tenantId = getTenantId();
|
|
5110
|
+
} finally {
|
|
5111
|
+
qsParams = {
|
|
5112
|
+
appId,
|
|
5113
|
+
version
|
|
5114
|
+
};
|
|
5115
|
+
}
|
|
5116
|
+
if (tenantId && tenantId !== DEFAULT_TENANT_ID) {
|
|
5117
|
+
qsParams.tenantId = tenantId;
|
|
5118
|
+
}
|
|
5119
|
+
return `/api/assets/client?${import_querystring.default.encode(qsParams)}`;
|
|
5120
|
+
}
|
|
5121
|
+
function getAppFileUrl(s3Key) {
|
|
5122
|
+
if (environment_default.CLOUDFRONT_CDN) {
|
|
5123
|
+
return getPresignedUrl2(s3Key);
|
|
5124
|
+
} else {
|
|
5125
|
+
return getPresignedUrl(environment_default.APPS_BUCKET_NAME, s3Key);
|
|
5126
|
+
}
|
|
5127
|
+
}
|
|
5128
|
+
var import_querystring;
|
|
5083
5129
|
var init_app5 = __esm({
|
|
5084
5130
|
"src/objectStore/buckets/app.ts"() {
|
|
5085
5131
|
"use strict";
|
|
5086
5132
|
init_environment2();
|
|
5087
5133
|
init_objectStore();
|
|
5088
5134
|
init_cloudfront();
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
let file = `${sanitizeKey(appId)}/budibase-client.js`;
|
|
5092
|
-
if (environment_default.CLOUDFRONT_CDN) {
|
|
5093
|
-
if (version) {
|
|
5094
|
-
file += `?v=${version}`;
|
|
5095
|
-
}
|
|
5096
|
-
return getUrl(file);
|
|
5097
|
-
} else {
|
|
5098
|
-
return getPresignedUrl(environment_default.APPS_BUCKET_NAME, file);
|
|
5099
|
-
}
|
|
5100
|
-
} else {
|
|
5101
|
-
return `/api/assets/client`;
|
|
5102
|
-
}
|
|
5103
|
-
};
|
|
5104
|
-
getAppFileUrl = (s3Key) => {
|
|
5105
|
-
if (environment_default.CLOUDFRONT_CDN) {
|
|
5106
|
-
return getPresignedUrl2(s3Key);
|
|
5107
|
-
} else {
|
|
5108
|
-
return getPresignedUrl(environment_default.APPS_BUCKET_NAME, s3Key);
|
|
5109
|
-
}
|
|
5110
|
-
};
|
|
5135
|
+
import_querystring = __toESM(require("querystring"));
|
|
5136
|
+
init_context2();
|
|
5111
5137
|
}
|
|
5112
5138
|
});
|
|
5113
5139
|
|
|
@@ -5143,7 +5169,59 @@ var init_global3 = __esm({
|
|
|
5143
5169
|
});
|
|
5144
5170
|
|
|
5145
5171
|
// src/objectStore/buckets/plugins.ts
|
|
5146
|
-
|
|
5172
|
+
function enrichPluginURLs(plugins) {
|
|
5173
|
+
if (!plugins || !plugins.length) {
|
|
5174
|
+
return [];
|
|
5175
|
+
}
|
|
5176
|
+
return plugins.map((plugin) => {
|
|
5177
|
+
const jsUrl = getPluginJSUrl(plugin);
|
|
5178
|
+
const iconUrl = getPluginIconUrl(plugin);
|
|
5179
|
+
return { ...plugin, jsUrl, iconUrl };
|
|
5180
|
+
});
|
|
5181
|
+
}
|
|
5182
|
+
function getPluginJSUrl(plugin) {
|
|
5183
|
+
const s3Key = getPluginJSKey(plugin);
|
|
5184
|
+
return getPluginUrl(s3Key);
|
|
5185
|
+
}
|
|
5186
|
+
function getPluginIconUrl(plugin) {
|
|
5187
|
+
const s3Key = getPluginIconKey(plugin);
|
|
5188
|
+
if (!s3Key) {
|
|
5189
|
+
return;
|
|
5190
|
+
}
|
|
5191
|
+
return getPluginUrl(s3Key);
|
|
5192
|
+
}
|
|
5193
|
+
function getPluginUrl(s3Key) {
|
|
5194
|
+
if (environment_default.CLOUDFRONT_CDN) {
|
|
5195
|
+
return getPresignedUrl2(s3Key);
|
|
5196
|
+
} else {
|
|
5197
|
+
return getPresignedUrl(environment_default.PLUGIN_BUCKET_NAME, s3Key);
|
|
5198
|
+
}
|
|
5199
|
+
}
|
|
5200
|
+
function getPluginJSKey(plugin) {
|
|
5201
|
+
return getPluginS3Key(plugin, "plugin.min.js");
|
|
5202
|
+
}
|
|
5203
|
+
function getPluginIconKey(plugin) {
|
|
5204
|
+
const iconFileName = plugin.iconUrl ? "icon.svg" : plugin.iconFileName;
|
|
5205
|
+
if (!iconFileName) {
|
|
5206
|
+
return;
|
|
5207
|
+
}
|
|
5208
|
+
return getPluginS3Key(plugin, iconFileName);
|
|
5209
|
+
}
|
|
5210
|
+
function getPluginS3Key(plugin, fileName) {
|
|
5211
|
+
const s3Key = getPluginS3Dir(plugin.name);
|
|
5212
|
+
return `${s3Key}/${fileName}`;
|
|
5213
|
+
}
|
|
5214
|
+
function getPluginS3Dir(pluginName) {
|
|
5215
|
+
let s3Key = `${pluginName}`;
|
|
5216
|
+
if (environment_default.MULTI_TENANCY) {
|
|
5217
|
+
const tenantId = getTenantId();
|
|
5218
|
+
s3Key = `${tenantId}/${s3Key}`;
|
|
5219
|
+
}
|
|
5220
|
+
if (environment_default.CLOUDFRONT_CDN) {
|
|
5221
|
+
s3Key = `plugins/${s3Key}`;
|
|
5222
|
+
}
|
|
5223
|
+
return s3Key;
|
|
5224
|
+
}
|
|
5147
5225
|
var init_plugins = __esm({
|
|
5148
5226
|
"src/objectStore/buckets/plugins.ts"() {
|
|
5149
5227
|
"use strict";
|
|
@@ -5151,59 +5229,6 @@ var init_plugins = __esm({
|
|
|
5151
5229
|
init_objectStore();
|
|
5152
5230
|
init_context2();
|
|
5153
5231
|
init_cloudfront();
|
|
5154
|
-
enrichPluginURLs = (plugins) => {
|
|
5155
|
-
if (!plugins || !plugins.length) {
|
|
5156
|
-
return [];
|
|
5157
|
-
}
|
|
5158
|
-
return plugins.map((plugin) => {
|
|
5159
|
-
const jsUrl = getPluginJSUrl(plugin);
|
|
5160
|
-
const iconUrl = getPluginIconUrl(plugin);
|
|
5161
|
-
return { ...plugin, jsUrl, iconUrl };
|
|
5162
|
-
});
|
|
5163
|
-
};
|
|
5164
|
-
getPluginJSUrl = (plugin) => {
|
|
5165
|
-
const s3Key = getPluginJSKey(plugin);
|
|
5166
|
-
return getPluginUrl(s3Key);
|
|
5167
|
-
};
|
|
5168
|
-
getPluginIconUrl = (plugin) => {
|
|
5169
|
-
const s3Key = getPluginIconKey(plugin);
|
|
5170
|
-
if (!s3Key) {
|
|
5171
|
-
return;
|
|
5172
|
-
}
|
|
5173
|
-
return getPluginUrl(s3Key);
|
|
5174
|
-
};
|
|
5175
|
-
getPluginUrl = (s3Key) => {
|
|
5176
|
-
if (environment_default.CLOUDFRONT_CDN) {
|
|
5177
|
-
return getPresignedUrl2(s3Key);
|
|
5178
|
-
} else {
|
|
5179
|
-
return getPresignedUrl(environment_default.PLUGIN_BUCKET_NAME, s3Key);
|
|
5180
|
-
}
|
|
5181
|
-
};
|
|
5182
|
-
getPluginJSKey = (plugin) => {
|
|
5183
|
-
return getPluginS3Key(plugin, "plugin.min.js");
|
|
5184
|
-
};
|
|
5185
|
-
getPluginIconKey = (plugin) => {
|
|
5186
|
-
const iconFileName = plugin.iconUrl ? "icon.svg" : plugin.iconFileName;
|
|
5187
|
-
if (!iconFileName) {
|
|
5188
|
-
return;
|
|
5189
|
-
}
|
|
5190
|
-
return getPluginS3Key(plugin, iconFileName);
|
|
5191
|
-
};
|
|
5192
|
-
getPluginS3Key = (plugin, fileName) => {
|
|
5193
|
-
const s3Key = getPluginS3Dir(plugin.name);
|
|
5194
|
-
return `${s3Key}/${fileName}`;
|
|
5195
|
-
};
|
|
5196
|
-
getPluginS3Dir = (pluginName) => {
|
|
5197
|
-
let s3Key = `${pluginName}`;
|
|
5198
|
-
if (environment_default.MULTI_TENANCY) {
|
|
5199
|
-
const tenantId = getTenantId();
|
|
5200
|
-
s3Key = `${tenantId}/${s3Key}`;
|
|
5201
|
-
}
|
|
5202
|
-
if (environment_default.CLOUDFRONT_CDN) {
|
|
5203
|
-
s3Key = `plugins/${s3Key}`;
|
|
5204
|
-
}
|
|
5205
|
-
return s3Key;
|
|
5206
|
-
};
|
|
5207
5232
|
}
|
|
5208
5233
|
});
|
|
5209
5234
|
|
|
@@ -5223,6 +5248,8 @@ __export(objectStore_exports2, {
|
|
|
5223
5248
|
ObjectStore: () => ObjectStore,
|
|
5224
5249
|
ObjectStoreBuckets: () => ObjectStoreBuckets,
|
|
5225
5250
|
budibaseTempDir: () => budibaseTempDir,
|
|
5251
|
+
clientLibraryCDNUrl: () => clientLibraryCDNUrl,
|
|
5252
|
+
clientLibraryPath: () => clientLibraryPath,
|
|
5226
5253
|
clientLibraryUrl: () => clientLibraryUrl,
|
|
5227
5254
|
deleteFile: () => deleteFile,
|
|
5228
5255
|
deleteFiles: () => deleteFiles,
|
|
@@ -5237,6 +5264,7 @@ __export(objectStore_exports2, {
|
|
|
5237
5264
|
getPluginJSKey: () => getPluginJSKey,
|
|
5238
5265
|
getPluginS3Dir: () => getPluginS3Dir,
|
|
5239
5266
|
getPresignedUrl: () => getPresignedUrl,
|
|
5267
|
+
getReadStream: () => getReadStream,
|
|
5240
5268
|
listAllObjects: () => listAllObjects,
|
|
5241
5269
|
makeSureBucketExists: () => makeSureBucketExists,
|
|
5242
5270
|
retrieve: () => retrieve,
|
|
@@ -10656,7 +10684,7 @@ var DEFINITIONS = [
|
|
|
10656
10684
|
},
|
|
10657
10685
|
{
|
|
10658
10686
|
type: "global" /* GLOBAL */,
|
|
10659
|
-
name: "
|
|
10687
|
+
name: "sync_quotas_2" /* SYNC_QUOTAS */
|
|
10660
10688
|
},
|
|
10661
10689
|
{
|
|
10662
10690
|
type: "app" /* APP */,
|