Skip to content

Commit 3dd34e9

Browse files
committed
[FEATURE] Recursive directories upload for S3 - Fixed
1 parent 4bf8df0 commit 3dd34e9

File tree

2 files changed

+52
-34
lines changed

2 files changed

+52
-34
lines changed

components/aws/actions/s3-upload-file-tmp/s3-upload-file-tmp.mjs

Lines changed: 51 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ import { ConfigurationError } from "@pipedream/platform";
77
export default {
88
...common,
99
key: "aws-s3-upload-file-tmp",
10-
name: "S3 - Upload File - /tmp",
10+
name: "S3 - Upload Files - /tmp",
1111
description: toSingleLineString(`
1212
Accepts a file path or folder path starting from /tmp, then uploads the contents to S3.
1313
[See the docs](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html)
1414
`),
15-
version: "1.0.2",
15+
version: "1.0.3",
1616
type: "action",
1717
props: {
1818
aws: common.props.aws,
@@ -25,15 +25,8 @@ export default {
2525
},
2626
path: {
2727
type: "string",
28-
label: "File Path",
29-
description: "A path starting from `/tmp`, i.e. `/tmp/some_text_file.txt`",
30-
optional: true,
31-
},
32-
folderPath: {
33-
type: "string",
34-
label: "Folder Path",
35-
description: "A path starting from `/tmp`, i.e. `/tmp/some_folder`. If provided, all the files inside this path will be uploaded. This will override the `Filename Key` and `File Path` props.",
36-
optional: true,
28+
label: "File Or Folder Path",
29+
description: "Path starting from `/tmp`. If it's a directory, all files will be uploaded.",
3730
},
3831
customFilename: {
3932
type: common.props.key.type,
@@ -44,58 +37,83 @@ export default {
4437
},
4538
methods: {
4639
...common.methods,
47-
async uploadFolderFiles($) {
40+
getFilesRecursive(dir) {
41+
let results = [];
42+
const items = fs.readdirSync(dir);
43+
for (const item of items) {
44+
const itemPath = join(dir, item);
45+
const stat = fs.statSync(itemPath);
46+
if (stat.isDirectory()) {
47+
results = results.concat(this.getFilesRecursive(itemPath));
48+
} else {
49+
results.push(itemPath);
50+
}
51+
}
52+
return results;
53+
},
54+
async uploadFolderFiles($, folderPath) {
4855
const {
4956
uploadFile,
5057
bucket,
51-
folderPath,
5258
prefix,
5359
} = this;
54-
55-
const files = fs.readdirSync(folderPath);
56-
const promises = [];
57-
for (const filename of files) {
58-
const fileContent = fs.readFileSync(join(folderPath, filename), {
60+
const files = this.getFilesRecursive(folderPath);
61+
const response = await Promise.all(files.map(async (filePath) => {
62+
const fileContent = fs.readFileSync(filePath, {
5963
encoding: "base64",
6064
});
61-
promises.push(uploadFile({
65+
const relativePath = filePath.substring(folderPath.length + 1);
66+
const s3Key = join(prefix, relativePath);
67+
68+
await uploadFile({
6269
Bucket: bucket,
63-
Key: join(prefix, filename),
70+
Key: s3Key,
6471
Body: Buffer.from(fileContent, "base64"),
65-
}));
66-
}
67-
const response = await Promise.all(promises);
72+
});
73+
return {
74+
filePath,
75+
s3Key,
76+
status: "uploaded",
77+
};
78+
}));
6879
$.export("$summary", `Uploaded all files from ${folderPath} to S3`);
6980
return response;
7081
},
71-
async uploadSingleFile($) {
82+
async uploadSingleFile($, filePath) {
7283
const {
7384
uploadFile,
7485
bucket,
75-
path,
7686
prefix,
7787
customFilename,
7888
} = this;
7989

80-
if (!path) {
81-
throw new ConfigurationError("File Path is required");
82-
}
83-
const file = fs.readFileSync(path, {
90+
const file = fs.readFileSync(filePath, {
8491
encoding: "base64",
8592
});
86-
const filename = customFilename || path.split("/").pop();
93+
const filename = customFilename || filePath.split("/").pop();
94+
8795
const response = await uploadFile({
8896
Bucket: bucket,
8997
Key: join(prefix, filename),
9098
Body: Buffer.from(file, "base64"),
9199
});
100+
92101
$.export("$summary", `Uploaded file ${filename} to S3`);
93102
return response;
94103
},
95104
},
96105
async run({ $ }) {
97-
return this.folderPath
98-
? await this.uploadFolderFiles($)
99-
: await this.uploadSingleFile($);
106+
const {
107+
uploadSingleFile,
108+
uploadFolderFiles,
109+
path,
110+
} = this;
111+
if (!fs.existsSync(path)) {
112+
throw new ConfigurationError(`The file or directory path \`${path}\` does not exist. Please verify the path and include the leading /tmp if needed.`);
113+
}
114+
const stat = fs.statSync(path);
115+
return stat.isDirectory()
116+
? await uploadFolderFiles($, path)
117+
: await uploadSingleFile($, path);
100118
},
101119
};

components/aws/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pipedream/aws",
3-
"version": "0.7.4",
3+
"version": "0.7.5",
44
"description": "Pipedream Aws Components",
55
"main": "aws.app.mjs",
66
"keywords": [

0 commit comments

Comments
 (0)