Skip to content

Commit 2f40bba

Browse files
committed
(fix): pdf generation works
1 parent 3c8cd66 commit 2f40bba

File tree

4 files changed

+55
-93
lines changed

4 files changed

+55
-93
lines changed

src/Client.ts

+1-8
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,7 @@ export class FileForgeClient {
4545
allowUnrecognizedEnumValues: false,
4646
breadcrumbsPrefix: [""],
4747
});
48-
console.log(options);
49-
await _request.append(
50-
"options",
51-
JSON.stringify(options),
52-
{ contentType: "application/json" }
53-
);
48+
await _request.append("options", new Blob([JSON.stringify(options)], { type: "application/json" }));
5449
for (const _file of files) {
5550
await _request.append("files", _file);
5651
}
@@ -74,9 +69,7 @@ export class FileForgeClient {
7469
timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000,
7570
maxRetries: requestOptions?.maxRetries,
7671
});
77-
console.log("_response", JSON.stringify(_response))
7872
if (_response.ok) {
79-
console.log("_response.body", _response.body);
8073
return _response.body;
8174
}
8275

src/core/fetcher/Fetcher.ts

+10-22
Original file line numberDiff line numberDiff line change
@@ -66,39 +66,25 @@ async function fetcherImpl<R = unknown>(args: Fetcher.Args): Promise<APIResponse
6666
: args.url;
6767

6868
let body: BodyInit | undefined = undefined;
69-
const maybeStringifyBody = (body: any) => {
69+
const maybeStringifyBody = async (body: any) => {
7070
if (body instanceof Uint8Array) {
7171
return body;
72+
} else if (body instanceof FormData
73+
|| body instanceof (await import("formdata-node")).FormData
74+
|| body instanceof (await import("form-data")).default) {
75+
return body as any;
7276
} else {
7377
return JSON.stringify(body);
7478
}
7579
};
7680

77-
if (RUNTIME.type === "node") {
78-
if (args.body instanceof (await import("formdata-node")).FormData) {
79-
// @ts-expect-error
80-
body = args.body;
81-
} else {
82-
body = maybeStringifyBody(args.body);
83-
}
84-
} else {
85-
if (args.body instanceof (await import("form-data")).default) {
86-
// @ts-expect-error
87-
body = args.body;
88-
} else {
89-
body = maybeStringifyBody(args.body);
90-
}
91-
}
81+
body = await maybeStringifyBody(args.body);
9282

9383
// In Node.js environments, the SDK always uses`node-fetch`.
9484
// If not in Node.js the SDK uses global fetch if available,
9585
// and falls back to node-fetch.
9686
const fetchFn =
97-
RUNTIME.type === "node"
98-
? // `.default` is required due to this issue:
99-
// https://github.com/node-fetch/node-fetch/issues/450#issuecomment-387045223
100-
((await import("node-fetch")).default as any)
101-
: typeof fetch == "function"
87+
typeof fetch == "function"
10288
? fetch
10389
: ((await import("node-fetch")).default as any);
10490

@@ -139,6 +125,8 @@ async function fetcherImpl<R = unknown>(args: Fetcher.Args): Promise<APIResponse
139125
}
140126
}
141127

128+
console.log(response.body);
129+
142130
let body: unknown;
143131
if (response.body != null && args.responseType === "blob") {
144132
body = await response.blob();
@@ -208,4 +196,4 @@ async function fetcherImpl<R = unknown>(args: Fetcher.Args): Promise<APIResponse
208196
}
209197
}
210198

211-
export const fetcher: FetchFunction = fetcherImpl;
199+
export const fetcher: FetchFunction = fetcherImpl;

src/core/form-data-utils/FormData.ts

+13-26
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
import { RUNTIME } from "../runtime";
22

3-
export function newFormData(): FormData {
3+
export function newFormData(): CrossRuntimeFormData {
44
if (RUNTIME.type === "node") {
55
return new NodeFormData();
66
} else {
77
return new WebFormData();
88
}
99
}
1010

11-
export declare namespace FormData {
11+
export declare namespace CrossRuntimeFormData {
1212
interface AppendOptions {
1313
contentType?: string;
1414
}
1515
}
1616

17-
export abstract class FormData {
17+
export abstract class CrossRuntimeFormData {
1818
public abstract append(key: string, value: any, options?: { contentType?: string }): Promise<void>;
1919

2020
/**
@@ -28,48 +28,35 @@ export abstract class FormData {
2828
public abstract getHeaders(): Promise<Record<string, string>>;
2929
}
3030

31-
class NodeFormData implements FormData {
32-
private encoder: any | undefined;
31+
class NodeFormData implements CrossRuntimeFormData {
3332
private fd: any | undefined;
3433

35-
public async initialize(): Promise<void> {
36-
this.fd = new (await import("formdata-node")).FormData();
37-
this.encoder = new (await import("form-data-encoder")).FormDataEncoder(this.fd);
34+
public constructor() {
35+
this.fd = new FormData();
3836
}
3937

4038
public async append(
4139
key: string,
4240
value: any,
4341
options?: { contentType?: string | undefined } | undefined
4442
): Promise<void> {
45-
if (this.fd == null) {
46-
await this.initialize();
47-
}
48-
if (options?.contentType == null) {
49-
this.fd.append(key, value);
43+
if (options?.contentType != null) {
44+
this.fd.append(key, new Blob([value], { type: options?.contentType }));
5045
} else {
51-
this.fd.append(key, new Blob([value], { type: options.contentType }));
46+
this.fd.append(key, value);
5247
}
5348
}
54-
49+
5550
public async getBody(): Promise<any> {
56-
if (this.encoder == null) {
57-
await this.initialize();
58-
}
59-
return (await import("node:stream")).Readable.from(this.encoder);
51+
return this.fd;
6052
}
6153

6254
public async getHeaders(): Promise<Record<string, string>> {
63-
if (this.encoder == null) {
64-
await this.initialize();
65-
}
66-
return {
67-
"Content-Length": this.encoder.length,
68-
};
55+
return {};
6956
}
7057
}
7158

72-
class WebFormData implements FormData {
59+
class WebFormData implements CrossRuntimeFormData {
7360
private fd: any;
7461

7562
public async initialize(): Promise<void> {

tests/custom.test.ts

+31-37
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
import stream from "stream";
2+
import * as core from "../src/core";
23
import { FileForgeClient } from "../src";
34
import fs from "fs";
5+
import { writeFile } from "fs/promises";
6+
7+
const HTML = `<!DOCTYPE html>
8+
<html>
9+
<head>
10+
<title>My First Web Page</title>
11+
</head>
12+
<body>
13+
<h1>Hello World!</h1>
14+
</body>
15+
</html>
16+
`;
417

518
/**
619
* This is a custom test file, if you wish to add more tests
@@ -12,44 +25,25 @@ import fs from "fs";
1225
*/
1326
describe("test", () => {
1427
it("should generate a PDF", async () => {
15-
const apiKeySupplier = async () => "ebec0c4c-214f-4796-afd2-b5c9b12281b6"; // Replace with your actual API key supplier
16-
const environmentSupplier = async () => "https://api.fileforge.com"; // Replace with your actual environment endpoint
17-
18-
const client = new FileForgeClient({
19-
apiKey: apiKeySupplier,
20-
environment: environmentSupplier,
28+
const blob = new Blob([HTML], {
29+
type: "text/html",
2130
});
31+
const htmlFile = new File([blob], "index.html", { type: "text/html" });
2232

23-
// Write HTML content to a file
24-
const htmlContent = "<h1>Hello World!</h1>";
25-
const blob = new Blob([htmlContent], { type: "text/html" });
26-
const file = new File([blob], "index.html", { type: "text/html" });
27-
28-
const request = {
29-
options: {
30-
fileName: "test.pdf",
31-
test: false,
32-
host: false,
33-
},
34-
};
35-
36-
const pdfStream: stream.Readable = await client.generate([file], request);
37-
console.log(pdfStream);
38-
const pdfFilePath = "output.pdf";
39-
const writeStream = fs.createWriteStream(pdfFilePath);
40-
41-
pdfStream.pipe(writeStream);
42-
43-
return new Promise((resolve, reject) => {
44-
writeStream.on("finish", () => {
45-
console.log("PDF generated and saved to", pdfFilePath);
46-
resolve(true);
47-
});
48-
49-
writeStream.on("error", (error) => {
50-
console.error("Error generating PDF:", error);
51-
reject(error);
52-
});
33+
const ff = new FileForgeClient({
34+
apiKey: "480039ed-ccf0-48be-9103-6875d0559012"
5335
});
54-
});
36+
const pdf = await ff.generate(
37+
[htmlFile],
38+
{
39+
options: {}
40+
}
41+
);
42+
43+
const chunks: any[] = []
44+
for await (let chunk of pdf) {
45+
chunks.push(chunk)
46+
}
47+
await writeFile("output.pdf", Buffer.concat(chunks));
48+
}, 10_000_000);
5549
});

0 commit comments

Comments
 (0)