Skip to content

Commit

Permalink
Release 0.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
fern-api[bot] committed May 14, 2024
1 parent 201b47e commit e7d96e6
Show file tree
Hide file tree
Showing 17 changed files with 345 additions and 58 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@
"test": "jest"
},
"dependencies": {
"form-data": "4.0.0",
"url-join": "4.0.1",
"form-data": "4.0.0",
"formdata-node": "^6.0.3",
"node-fetch": "2.7.0",
"qs": "6.11.2",
"form-data-encoder": "^4.0.2",
"js-base64": "3.7.2"
},
"devDependencies": {
Expand Down
13 changes: 7 additions & 6 deletions src/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import * as core from "./core";
import * as fs from "fs";
import * as FileForge from "./api/index";
import * as stream from "stream";
import { default as FormData } from "form-data";
import urlJoin from "url-join";
import * as errors from "./errors/index";
import * as serializers from "./serialization/index";
Expand All @@ -31,6 +30,7 @@ export class FileForgeClient {
constructor(protected readonly _options: FileForgeClient.Options) {}

/**
* Generates a PDF document from web assets.
* @throws {@link FileForge.BadRequestError}
* @throws {@link FileForge.UnauthorizedError}
* @throws {@link FileForge.InternalServerError}
Expand All @@ -41,12 +41,13 @@ export class FileForgeClient {
request: FileForge.GenerateRequest,
requestOptions?: FileForgeClient.RequestOptions
): Promise<stream.Readable> {
const _request = new FormData();
_request.append("options", JSON.stringify(request.options));
const _request = new core.FormDataWrapper();
await _request.append("options", JSON.stringify(request.options));
for (const _file of files) {
_request.append("files", _file);
await _request.append("files", _file);
}

const _maybeEncodedRequest = _request.getRequest();
const _response = await core.fetcher<stream.Readable>({
url: urlJoin(
(await core.Supplier.get(this._options.environment)) ?? environments.FileForgeEnvironment.Default,
Expand All @@ -61,9 +62,9 @@ export class FileForgeClient {
"X-Fern-SDK-Version": "0.0.1",
"X-Fern-Runtime": core.RUNTIME.type,
"X-Fern-Runtime-Version": core.RUNTIME.version,
...(await _maybeEncodedRequest.getHeaders()),
},
contentType: "multipart/form-data; boundary=" + _request.getBoundary(),
body: _request,
body: await _maybeEncodedRequest.getBody(),
responseType: "streaming",
timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000,
maxRetries: requestOptions?.maxRetries,
Expand Down
1 change: 1 addition & 0 deletions src/api/client/requests/GenerateRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ import * as FileForge from "../../index";
* {}
*/
export interface GenerateRequest {
/** Conversion options. This field is required even if empty. */
options: FileForge.GenerateRequestOptions;
}
113 changes: 107 additions & 6 deletions src/api/resources/pdf/client/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import * as core from "../../../../core";
import * as fs from "fs";
import * as FileForge from "../../../index";
import * as stream from "stream";
import { default as FormData } from "form-data";
import urlJoin from "url-join";
import * as errors from "../../../../errors/index";
import * as serializers from "../../../../serialization/index";
Expand All @@ -29,6 +28,107 @@ export declare namespace Pdf {
export class Pdf {
constructor(protected readonly _options: Pdf.Options) {}

/**
* Converts a Microsoft Word document (.DOCX or .DOC) file to a PDF document.
*
* This service uses a LibreOffice headless server to perform the conversion, and may not support all features of the original document.
*
* **Known discrepancies**
*
* - Some fonts may not be available in the server, and may be substituted by a closest match.
* - Some complex formatting may not be preserved, such as background graphics.
*
* **Variables**
*
* Variable replacement is supported with various methods:
*
* - Templated litterals: `{{name}}`
* - Word variables, as listed in the document metadata: `{DOCVARIABLE "name"}`
*
* To enable variable replacement as Word variables for your account, please contact the FileForge support.
* @throws {@link FileForge.BadRequestError}
* @throws {@link FileForge.UnauthorizedError}
* @throws {@link FileForge.InternalServerError}
*/
public async convertsADocOrDocxDocumentToPdf(
file: File | fs.ReadStream,
request: FileForge.PostPdfDocxRequest,
requestOptions?: Pdf.RequestOptions
): Promise<stream.Readable> {
const _request = new core.FormDataWrapper();
await _request.append("options", JSON.stringify(request.options));
await _request.append("file", file);
const _maybeEncodedRequest = _request.getRequest();
const _response = await core.fetcher<stream.Readable>({
url: urlJoin(
(await core.Supplier.get(this._options.environment)) ?? environments.FileForgeEnvironment.Default,
"pdf/docx/"
),
method: "POST",
headers: {
Authorization: await this._getAuthorizationHeader(),
"X-API-Key": await core.Supplier.get(this._options.apiKey),
"X-Fern-Language": "JavaScript",
"X-Fern-SDK-Name": "fileforge",
"X-Fern-SDK-Version": "0.0.1",
"X-Fern-Runtime": core.RUNTIME.type,
"X-Fern-Runtime-Version": core.RUNTIME.version,
...(await _maybeEncodedRequest.getHeaders()),
},
body: await _maybeEncodedRequest.getBody(),
responseType: "streaming",
timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000,
maxRetries: requestOptions?.maxRetries,
});
if (_response.ok) {
return _response.body;
}

if (_response.error.reason === "status-code") {
switch (_response.error.statusCode) {
case 400:
throw new FileForge.BadRequestError(
await serializers.ErrorSchema.parseOrThrow(_response.error.body, {
unrecognizedObjectKeys: "passthrough",
allowUnrecognizedUnionMembers: true,
allowUnrecognizedEnumValues: true,
breadcrumbsPrefix: ["response"],
})
);
case 401:
throw new FileForge.UnauthorizedError(
await serializers.ErrorSchema.parseOrThrow(_response.error.body, {
unrecognizedObjectKeys: "passthrough",
allowUnrecognizedUnionMembers: true,
allowUnrecognizedEnumValues: true,
breadcrumbsPrefix: ["response"],
})
);
case 500:
throw new FileForge.InternalServerError(_response.error.body);
default:
throw new errors.FileForgeError({
statusCode: _response.error.statusCode,
body: _response.error.body,
});
}
}

switch (_response.error.reason) {
case "non-json":
throw new errors.FileForgeError({
statusCode: _response.error.statusCode,
body: _response.error.rawBody,
});
case "timeout":
throw new errors.FileForgeTimeoutError();
case "unknown":
throw new errors.FileForgeError({
message: _response.error.errorMessage,
});
}
}

/**
* @throws {@link FileForge.BadRequestError}
* @throws {@link FileForge.UnauthorizedError}
Expand All @@ -39,12 +139,13 @@ export class Pdf {
request: FileForge.PostPdfMergeRequest,
requestOptions?: Pdf.RequestOptions
): Promise<stream.Readable> {
const _request = new FormData();
_request.append("options", JSON.stringify(request.options));
const _request = new core.FormDataWrapper();
await _request.append("options", JSON.stringify(request.options));
for (const _file of files) {
_request.append("files", _file);
await _request.append("files", _file);
}

const _maybeEncodedRequest = _request.getRequest();
const _response = await core.fetcher<stream.Readable>({
url: urlJoin(
(await core.Supplier.get(this._options.environment)) ?? environments.FileForgeEnvironment.Default,
Expand All @@ -59,9 +160,9 @@ export class Pdf {
"X-Fern-SDK-Version": "0.0.1",
"X-Fern-Runtime": core.RUNTIME.type,
"X-Fern-Runtime-Version": core.RUNTIME.version,
...(await _maybeEncodedRequest.getHeaders()),
},
contentType: "multipart/form-data; boundary=" + _request.getBoundary(),
body: _request,
body: await _maybeEncodedRequest.getBody(),
responseType: "streaming",
timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000,
maxRetries: requestOptions?.maxRetries,
Expand Down
38 changes: 38 additions & 0 deletions src/api/resources/pdf/client/requests/PostPdfDocxRequest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* This file was auto-generated by Fern from our API Definition.
*/

import * as FileForge from "../../../../index";

/**
* @example
* {}
*/
export interface PostPdfDocxRequest {
/**
* Conversion options. This field is required even if empty.
*
* **Options**
*
* * `templateLiterals`: Map of template literals to replace in the document. Template literals should be enclosed in double curly braces, e.g. `{{name}}`. Variables name can contain alphanumeric characters and hyphens. All variables are case-sensitive. The value for each variable should be a string. If a value of undefined is passed, the variable will not be removed from the document. If you need to remove a variable, pass an empty string as the value.
*
* **NB** variables should **not** have surrounding spaces, e.g. `{{ name }}`.
*
* **Example**
*
* In the Word document: `{{name}} {{nickname}}. was born on {{date}}.`
*
* ```json
* {
* "templateLiterals": {
* "name": "John Doe",
* "date": "2021-12-31",
* "nickname": ""
* }
* }
* ```
*
* There will not be an error if a variable is not found in the document, nor if variables found in the document are not in the options.
*/
options: FileForge.PostPdfDocxRequestOptions;
}
1 change: 1 addition & 0 deletions src/api/resources/pdf/client/requests/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { type PostPdfDocxRequest } from "./PostPdfDocxRequest";
export { type PostPdfMergeRequest } from "./PostPdfMergeRequest";
33 changes: 33 additions & 0 deletions src/api/resources/pdf/types/PostPdfDocxRequestOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* This file was auto-generated by Fern from our API Definition.
*/

/**
* Conversion options. This field is required even if empty.
*
* **Options**
*
* - `templateLiterals`: Map of template literals to replace in the document. Template literals should be enclosed in double curly braces, e.g. `{{name}}`. Variables name can contain alphanumeric characters and hyphens. All variables are case-sensitive. The value for each variable should be a string. If a value of undefined is passed, the variable will not be removed from the document. If you need to remove a variable, pass an empty string as the value.
*
* **NB** variables should **not** have surrounding spaces, e.g. `{{ name }}`.
*
* **Example**
*
* In the Word document: `{{name}} {{nickname}}. was born on {{date}}.`
*
* ```json
* {
* "templateLiterals": {
* "name": "John Doe",
* "date": "2021-12-31",
* "nickname": ""
* }
* }
* ```
*
* There will not be an error if a variable is not found in the document, nor if variables found in the document are not in the options.
*/
export interface PostPdfDocxRequestOptions {
/** Map of template literals to replace in the document. */
templateLiterals?: Record<string, string>;
}
1 change: 1 addition & 0 deletions src/api/resources/pdf/types/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./PostPdfDocxRequestOptions";
export * from "./PostPdfMergeRequestOptions";
2 changes: 1 addition & 1 deletion src/api/types/ErrorSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ export interface ErrorSchema {
statusCode: number;
/** A machine-readable error code */
code: string;
/** A human-readable message */
/** A human-readable message. This field may also provide additional context to the error code. */
message: string;
}
3 changes: 3 additions & 0 deletions src/api/types/GenerateRequestOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
* This file was auto-generated by Fern from our API Definition.
*/

/**
* Conversion options. This field is required even if empty.
*/
export interface GenerateRequestOptions {
/** Generate a test document instead of a production document. The generated document will contain a watermark. Defaults to true. */
test?: boolean;
Expand Down
28 changes: 21 additions & 7 deletions src/core/fetcher/Fetcher.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { default as FormData } from "form-data";
import qs from "qs";
import { RUNTIME } from "../runtime";
import { APIResponse } from "./APIResponse";
Expand Down Expand Up @@ -67,13 +66,28 @@ async function fetcherImpl<R = unknown>(args: Fetcher.Args): Promise<APIResponse
: args.url;

let body: BodyInit | undefined = undefined;
if (args.body instanceof FormData) {
// @ts-expect-error
body = args.body;
} else if (args.body instanceof Uint8Array) {
body = args.body;
const maybeStringifyBody = (body: any) => {
if (body instanceof Uint8Array) {
return body;
} else {
return JSON.stringify(body);
}
};

if (RUNTIME.type === "node") {
if (args.body instanceof (await import("formdata-node")).FormData) {
// @ts-expect-error
body = args.body;
} else {
body = maybeStringifyBody(args.body);
}
} else {
body = JSON.stringify(args.body);
if (args.body instanceof (await import("form-data")).default) {
// @ts-expect-error
body = args.body;
} else {
body = maybeStringifyBody(args.body);
}
}

// In Node.js environments, the SDK always uses`node-fetch`.
Expand Down
Loading

0 comments on commit e7d96e6

Please sign in to comment.