Skip to content

Commit 80d7d08

Browse files
authored
New Components - pdforge (#16722)
* pdforge init * [Components] pdforge #16687 Actions - Generate PDF From HTML - Generate PDF From TEMPLATE * pnpm update
1 parent 6147d90 commit 80d7d08

File tree

7 files changed

+346
-15
lines changed

7 files changed

+346
-15
lines changed
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import fs from "fs";
2+
import stream from "stream";
3+
import { promisify } from "util";
4+
import {
5+
checkTmp,
6+
clearObj,
7+
} from "../../common/utils.mjs";
8+
import pdforge from "../../pdforge.app.mjs";
9+
10+
export default {
11+
props: {
12+
pdforge,
13+
convertToImage: {
14+
type: "boolean",
15+
label: "Convert to Image",
16+
description: "If true, will return a .PNG file instead of a .PDF file",
17+
default: false,
18+
},
19+
asyncMode: {
20+
type: "boolean",
21+
label: "Async Mode",
22+
description: "If `true`, the request will be executed in the background and the response will be sent to the webhook URL.",
23+
default: false,
24+
reloadProps: true,
25+
},
26+
saveS3: {
27+
type: "boolean",
28+
label: "Save to S3",
29+
description: "If `true`, the generated file will be saved to the provided s3 bucket; if `false`, the generated file will be saved to the Pipedream `/tmp` directory.",
30+
default: true,
31+
reloadProps: true,
32+
hidden: true,
33+
},
34+
s3bucket: {
35+
propDefinition: [
36+
pdforge,
37+
"s3bucket",
38+
],
39+
hidden: true,
40+
},
41+
s3key: {
42+
propDefinition: [
43+
pdforge,
44+
"s3key",
45+
],
46+
hidden: true,
47+
},
48+
fileName: {
49+
propDefinition: [
50+
pdforge,
51+
"fileName",
52+
],
53+
hidden: true,
54+
},
55+
webhook: {
56+
propDefinition: [
57+
pdforge,
58+
"webhook",
59+
],
60+
hidden: true,
61+
},
62+
},
63+
async additionalProps(props) {
64+
const isAsync = this.asyncMode;
65+
const saveAtS3 = this.saveS3;
66+
67+
props.webhook.hidden = !isAsync;
68+
props.saveS3.hidden = isAsync;
69+
70+
const showS3 = !isAsync && saveAtS3;
71+
props.s3bucket.hidden = !showS3;
72+
props.s3key.hidden = !showS3;
73+
props.fileName.hidden = showS3;
74+
return {};
75+
},
76+
async run({ $ }) {
77+
let response;
78+
79+
const data = {
80+
...this.getAdditionalData(),
81+
convertToImage: this.convertToImage,
82+
webhook: this.webhook,
83+
};
84+
85+
if (this.saveS3) {
86+
data.s3Bucked = this.s3Bucked;
87+
data.s3Key = this.s3Key;
88+
}
89+
90+
if (this.asyncMode) {
91+
data.webhook = this.webhook;
92+
}
93+
94+
const fn = this.getFunction();
95+
96+
const asyncResponse = await fn({
97+
$,
98+
asyncMode: this.asyncMode,
99+
data: clearObj(data),
100+
});
101+
102+
response = asyncResponse;
103+
104+
if (!this.saveS3 && !this.asyncMode) {
105+
const fileStream = await this.pdforge._makeRequest({
106+
baseUrl: response.signedUrl,
107+
responseType: "stream",
108+
removeHeader: true,
109+
});
110+
111+
const filePath = checkTmp(
112+
`${this.fileName}.${this.convertToImage
113+
? "PNG"
114+
: "PDF"}`,
115+
);
116+
117+
const pipeline = promisify(stream.pipeline);
118+
await pipeline(fileStream, fs.createWriteStream(filePath));
119+
120+
response = {
121+
...asyncResponse,
122+
filePath,
123+
};
124+
}
125+
126+
if (this.asyncMode) {
127+
$.export("$summary", "Asynchronous request initiated. Await the webhook callback for completion.");
128+
} else {
129+
$.export("$summary", this.getSummary(this));
130+
}
131+
132+
return response;
133+
},
134+
};
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { parseObject } from "../../common/utils.mjs";
2+
import common from "../common/base.mjs";
3+
4+
export default {
5+
...common,
6+
key: "pdforge-generate-pdf-from-html",
7+
name: "Generate PDF from HTML",
8+
description: "Generate a PDF document from HTML content. [See the documentation](https://docs.pdforge.com/html-to-pdf-conversion/synchronous-request)",
9+
version: "0.0.1",
10+
type: "action",
11+
props: {
12+
...common.props,
13+
html: {
14+
type: "string",
15+
label: "HTML",
16+
description: "The HTML content you want to render",
17+
},
18+
pdfParams: {
19+
type: "object",
20+
label: "PDF Params",
21+
description: "The object containing the parameters for your PDF. [See all the options here](https://docs.pdforge.com/options/pdf-params).",
22+
optional: true,
23+
},
24+
},
25+
methods: {
26+
getAdditionalData() {
27+
return {
28+
html: this.html,
29+
pdfParams: parseObject(this.pdfParams),
30+
};
31+
},
32+
getFunction() {
33+
return this.pdforge.generatePDFfromHTML;
34+
},
35+
getSummary({ convertToImage }) {
36+
return `${convertToImage
37+
? "PNG"
38+
: "PDF"} successfully generated from provided HTML content.`;
39+
},
40+
},
41+
};
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { parseObject } from "../../common/utils.mjs";
2+
import common from "../common/base.mjs";
3+
4+
export default {
5+
...common,
6+
key: "pdforge-generate-pdf-from-template",
7+
name: "Generate PDF from Template",
8+
description: "Generate a document from a selected template. [See the documentation](https://docs.pdforge.com/pdfs-from-templates/synchronous-request)",
9+
version: "0.0.1",
10+
type: "action",
11+
props: {
12+
...common.props,
13+
templateId: {
14+
type: "string",
15+
label: "Template ID",
16+
description: "The ID of the template from which to generate the document",
17+
},
18+
data: {
19+
type: "object",
20+
label: "Data",
21+
description: "The object containing the variables for your PDF template",
22+
},
23+
},
24+
methods: {
25+
getAdditionalData() {
26+
return {
27+
templateId: this.templateId,
28+
data: parseObject(this.data),
29+
};
30+
},
31+
getFunction() {
32+
return this.pdforge.generateDocumentFromTemplate;
33+
},
34+
getSummary({ convertToImage }) {
35+
return `${convertToImage
36+
? "PNG"
37+
: "PDF"} generated successfully from template ID: ${this.templateId}`;
38+
},
39+
},
40+
};
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
export const checkTmp = (filename) => {
2+
if (!filename.startsWith("/tmp")) {
3+
return `/tmp/${filename}`;
4+
}
5+
return filename;
6+
};
7+
8+
export const parseObject = (obj) => {
9+
if (!obj) return undefined;
10+
11+
if (Array.isArray(obj)) {
12+
return obj.map((item) => {
13+
if (typeof item === "string") {
14+
try {
15+
return JSON.parse(item);
16+
} catch (e) {
17+
return item;
18+
}
19+
}
20+
return item;
21+
});
22+
}
23+
if (typeof obj === "string") {
24+
try {
25+
return JSON.parse(obj);
26+
} catch (e) {
27+
return obj;
28+
}
29+
}
30+
return obj;
31+
};
32+
33+
export const clearObj = (obj) => {
34+
return Object.entries(obj)
35+
.filter(([
36+
,
37+
v,
38+
]) => (v != null && v != "" && JSON.stringify(v) != "{}"))
39+
.reduce((acc, [
40+
k,
41+
v,
42+
]) => ({
43+
...acc,
44+
[k]: (!Array.isArray(v) && v === Object(v))
45+
? clearObj(v)
46+
: v,
47+
}), {});
48+
};

components/pdforge/package.json

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

components/pdforge/pdforge.app.mjs

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,72 @@
1+
import { axios } from "@pipedream/platform";
2+
13
export default {
24
type: "app",
35
app: "pdforge",
4-
propDefinitions: {},
6+
propDefinitions: {
7+
s3bucket: {
8+
type: "string",
9+
label: "S3 Bucket",
10+
description: "The ID of the active S3 connection to store the generated file on",
11+
},
12+
s3key: {
13+
type: "string",
14+
label: "S3 Key",
15+
description: "The path and filename without extension for saving the file in the S3 bucket",
16+
secret: true,
17+
},
18+
fileName: {
19+
type: "string",
20+
label: "File Name",
21+
description: "The filename without extension for saving the file in the `/tmp` direcrtory",
22+
},
23+
webhook: {
24+
type: "string",
25+
label: "Webhook URL",
26+
description: "The URL of your webhook endpoint",
27+
},
28+
},
529
methods: {
6-
// this.$auth contains connected account data
7-
authKeys() {
8-
console.log(Object.keys(this.$auth));
30+
_baseUrl(baseUrl) {
31+
return baseUrl || "https://api.pdforge.com/v1";
32+
},
33+
_headers(removeHeader = false) {
34+
return removeHeader
35+
? {}
36+
: {
37+
Authorization: `Bearer ${this.$auth.api_key}`,
38+
};
39+
},
40+
_makeRequest({
41+
$ = this, baseUrl, removeHeader, path = "", ...opts
42+
}) {
43+
return axios($, {
44+
url: this._baseUrl(baseUrl) + path,
45+
headers: this._headers(removeHeader),
46+
...opts,
47+
});
48+
},
49+
generateDocumentFromTemplate({
50+
asyncMode, ...opts
51+
}) {
52+
return this._makeRequest({
53+
method: "POST",
54+
path: `/pdf/${asyncMode
55+
? "async"
56+
: "sync"}`,
57+
...opts,
58+
});
59+
},
60+
generatePDFfromHTML({
61+
asyncMode, ...opts
62+
}) {
63+
return this._makeRequest({
64+
method: "POST",
65+
path: `/html-to-pdf/${asyncMode
66+
? "async"
67+
: "sync"}`,
68+
...opts,
69+
});
970
},
1071
},
1172
};

pnpm-lock.yaml

Lines changed: 11 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)