Skip to content

Commit 212e8c3

Browse files
committed
[Components] azure_storage - new components
1 parent e51b8b1 commit 212e8c3

File tree

15 files changed

+616
-13
lines changed

15 files changed

+616
-13
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import app from "../../azure_storage.app.mjs";
2+
3+
export default {
4+
key: "azure_storage-create-container",
5+
name: "Create Container",
6+
description: "Creates a new container under the specified account. If a container with the same name already exists, the operation fails. [See the documentation](https://learn.microsoft.com/en-us/rest/api/storageservices/create-container?tabs=microsoft-entra-id).",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
app,
11+
containerName: {
12+
type: "string",
13+
label: "Container Name",
14+
description: "The name of the container within the specified storage account.",
15+
},
16+
},
17+
methods: {
18+
createContainer({
19+
containerName, params, ...args
20+
} = {}) {
21+
return this.app.put({
22+
...args,
23+
path: `/${containerName}`,
24+
params: {
25+
...params,
26+
restype: "container",
27+
},
28+
});
29+
},
30+
},
31+
async run({ $ }) {
32+
const {
33+
createContainer,
34+
containerName,
35+
} = this;
36+
37+
await createContainer({
38+
$,
39+
containerName,
40+
});
41+
42+
$.export("$summary", "Successfully created container.");
43+
44+
return {
45+
success: true,
46+
};
47+
},
48+
};
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import app from "../../azure_storage.app.mjs";
2+
3+
export default {
4+
key: "azure_storage-delete-blob",
5+
name: "Delete Blob",
6+
description: "Deletes a specific blob from a container in Azure Storage. [See the documentation](https://learn.microsoft.com/en-us/rest/api/storageservices/delete-blob?tabs=microsoft-entra-id).",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
app,
11+
// eslint-disable-next-line pipedream/props-label, pipedream/props-description
12+
info: {
13+
type: "alert",
14+
alertType: "info",
15+
content: "In order to have the right permissions to use this feature you need to go to the Azure Console in `Storage Account > IAM > Add role assignment`, and add the special permissions for this type of request:\n - Storage Blob Data Contributor\n - Storage Queue Data Contributor\n [See the documentation](https://learn.microsoft.com/en-us/rest/api/storageservices/delete-blob?tabs=microsoft-entra-id#permissions).",
16+
},
17+
containerName: {
18+
propDefinition: [
19+
app,
20+
"containerName",
21+
],
22+
},
23+
blobName: {
24+
propDefinition: [
25+
app,
26+
"blobName",
27+
({ containerName }) => ({
28+
containerName,
29+
}),
30+
],
31+
},
32+
},
33+
methods: {
34+
deleteBlob({
35+
containerName, blobName,
36+
} = {}) {
37+
return this.app.delete({
38+
path: `/${containerName}/${blobName}`,
39+
});
40+
},
41+
},
42+
async run({ $ }) {
43+
const {
44+
deleteBlob,
45+
containerName,
46+
blobName,
47+
} = this;
48+
49+
await deleteBlob({
50+
$,
51+
containerName,
52+
blobName,
53+
});
54+
55+
$.export("$summary", "Successfully deleted blob.");
56+
return {
57+
success: true,
58+
};
59+
},
60+
};
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import app from "../../azure_storage.app.mjs";
2+
import utils from "../../common/utils.mjs";
3+
4+
export default {
5+
key: "azure_storage-upload-blob",
6+
name: "Upload Blob",
7+
description: "Uploads a new blob to a specified container in Azure Storage. [See the documentation](https://learn.microsoft.com/en-us/rest/api/storageservices/put-blob?tabs=microsoft-entra-id).",
8+
version: "0.0.1",
9+
type: "action",
10+
props: {
11+
app,
12+
// eslint-disable-next-line pipedream/props-label, pipedream/props-description
13+
info: {
14+
type: "alert",
15+
alertType: "info",
16+
content: "In order to have the right permissions to use this feature you need to go to the Azure Console in `Storage Account > IAM > Add role assignment`, and add the special permissions for this type of request:\n - Storage Blob Data Contributor\n - Storage Queue Data Contributor\n [See the documentation](https://learn.microsoft.com/en-us/rest/api/storageservices/put-blob?tabs=microsoft-entra-id#permissions).",
17+
},
18+
containerName: {
19+
propDefinition: [
20+
app,
21+
"containerName",
22+
],
23+
},
24+
blobName: {
25+
type: "string",
26+
label: "Blob Name",
27+
description: "The name of the blob within the specified container.",
28+
},
29+
filePath: {
30+
type: "string",
31+
label: "File",
32+
description: "The file to be uploaded, please provide a file from `/tmp` Eg. `/tmp/my-file.txt`. To upload a file to `/tmp` folder, please follow the doc [here](https://pipedream.com/docs/code/nodejs/working-with-files/#writing-a-file-to-tmp)",
33+
},
34+
},
35+
methods: {
36+
uploadBlob({
37+
containerName, blobName, ...args
38+
} = {}) {
39+
return this.app.put({
40+
path: `/${containerName}/${blobName}`,
41+
...args,
42+
});
43+
},
44+
},
45+
async run({ $ }) {
46+
const {
47+
uploadBlob,
48+
containerName,
49+
blobName,
50+
filePath,
51+
} = this;
52+
53+
const data = utils.getDataFromFile(filePath);
54+
const fileName = utils.getFilenameFromPath(filePath);
55+
56+
await uploadBlob({
57+
$,
58+
containerName,
59+
blobName,
60+
data,
61+
headers: {
62+
"x-ms-blob-type": "BlockBlob",
63+
"Content-Type": "text/plain; charset=UTF-8",
64+
"x-ms-blob-content-disposition": `attachment; filename=${fileName}`,
65+
"x-ms-meta-m1": "v1",
66+
"x-ms-meta-m2": "v2",
67+
"Content-Length": data?.length,
68+
},
69+
});
70+
71+
$.export("$summary", "Successfully uploaded the blob.");
72+
return {
73+
success: true,
74+
};
75+
},
76+
};
Lines changed: 112 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,119 @@
1+
import { XMLParser } from "fast-xml-parser";
2+
import { axios } from "@pipedream/platform";
3+
import constants from "./common/constants.mjs";
4+
5+
const parser = new XMLParser({
6+
ignoreAttributes: false,
7+
arrayMode: true,
8+
textNodeName: "value",
9+
});
10+
111
export default {
212
type: "app",
313
app: "azure_storage",
4-
propDefinitions: {},
14+
propDefinitions: {
15+
containerName: {
16+
type: "string",
17+
label: "Container Name",
18+
description: "The name of the container within the specified storage account.",
19+
async options() {
20+
const { EnumerationResults: { Containers: { Container: containers } } } =
21+
await this.listContainers();
22+
return Array.isArray(containers)
23+
? containers.map(({ Name: value }) => value)
24+
: [
25+
containers.Name,
26+
];
27+
},
28+
},
29+
blobName: {
30+
type: "string",
31+
label: "Blob Name",
32+
description: "The name of the blob within the specified container.",
33+
async options({ containerName }) {
34+
const { EnumerationResults: { Blobs: { Blob: blobs } } } = await this.listBlobs({
35+
containerName,
36+
});
37+
return Array.isArray(blobs)
38+
? blobs.map(({ Name: value }) => value)
39+
: [
40+
blobs.Name,
41+
];
42+
},
43+
},
44+
},
545
methods: {
6-
// this.$auth contains connected account data
7-
authKeys() {
8-
console.log(Object.keys(this.$auth));
46+
getUrl(path) {
47+
const { storage_account_name: storageAccount } = this.$auth;
48+
const baseUrl = constants.BASE_URL
49+
.replace(constants.STORAGE_ACCOUNT_PLACEHOLDER, storageAccount);
50+
return `${baseUrl}${path}`;
51+
},
52+
getHeaders(headers) {
53+
return {
54+
...headers,
55+
"x-ms-date": new Date().toUTCString(),
56+
"x-ms-version": constants.API_VERSION,
57+
"Authorization": `Bearer ${this.$auth.oauth_access_token}`,
58+
};
59+
},
60+
async _makeRequest({
61+
$ = this, path, headers, jsonOutput = true, ...args
62+
} = {}) {
63+
let response;
64+
try {
65+
response = await axios($, {
66+
...args,
67+
url: this.getUrl(path),
68+
headers: this.getHeaders(headers),
69+
});
70+
71+
} catch (error) {
72+
const errorResponse = parser.parse(error.response.data);
73+
if (errorResponse.Error) {
74+
throw new Error(JSON.stringify(errorResponse.Error, null, 2));
75+
}
76+
throw error;
77+
}
78+
79+
return jsonOutput
80+
? parser.parse(response)
81+
: response;
82+
},
83+
put(args = {}) {
84+
return this._makeRequest({
85+
method: "PUT",
86+
...args,
87+
});
88+
},
89+
delete(args = {}) {
90+
return this._makeRequest({
91+
method: "DELETE",
92+
...args,
93+
});
94+
},
95+
listContainers(args = {}) {
96+
return this._makeRequest({
97+
...args,
98+
path: "/",
99+
params: {
100+
...args.params,
101+
comp: "list",
102+
},
103+
});
104+
},
105+
listBlobs({
106+
containerName, ...args
107+
} = {}) {
108+
return this._makeRequest({
109+
...args,
110+
path: `/${containerName}`,
111+
params: {
112+
...args.params,
113+
restype: "container",
114+
comp: "list",
115+
},
116+
});
9117
},
10118
},
11119
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const STORAGE_ACCOUNT_PLACEHOLDER = "{storageAccount}";
2+
const BASE_URL = `https://${STORAGE_ACCOUNT_PLACEHOLDER}.blob.core.windows.net`;
3+
const API_VERSION = "2025-01-05";
4+
5+
export default {
6+
STORAGE_ACCOUNT_PLACEHOLDER,
7+
BASE_URL,
8+
API_VERSION,
9+
};
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import fs from "fs";
2+
import { ConfigurationError } from "@pipedream/platform";
3+
4+
function checkTmp(filePath) {
5+
const adjustedPath = filePath.startsWith("/tmp")
6+
? filePath
7+
: `/tmp/${filePath}`;
8+
9+
if (!fs.existsSync(adjustedPath)) {
10+
throw new ConfigurationError("File does not exist!");
11+
}
12+
13+
return adjustedPath;
14+
}
15+
16+
function getDataFromFile(filePath) {
17+
const path = checkTmp(filePath);
18+
const file = fs.readFileSync(path, "utf8");
19+
return file;
20+
}
21+
22+
function getFilenameFromPath(filePath) {
23+
const pathParts = filePath.split("/");
24+
return pathParts[pathParts.length - 1];
25+
}
26+
27+
export default {
28+
getDataFromFile,
29+
getFilenameFromPath,
30+
};

components/azure_storage/package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pipedream/azure_storage",
3-
"version": "0.0.1",
3+
"version": "0.1.0",
44
"description": "Pipedream Azure Storage Components",
55
"main": "azure_storage.app.mjs",
66
"keywords": [
@@ -11,5 +11,8 @@
1111
"author": "Pipedream <[email protected]> (https://pipedream.com/)",
1212
"publishConfig": {
1313
"access": "public"
14+
},
15+
"dependencies": {
16+
"@pipedream/platform": "^3.0.3"
1417
}
15-
}
18+
}

0 commit comments

Comments
 (0)