Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(init): setup and publish SDK #5

Merged
merged 6 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions .fernignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
# Specify files that shouldn't be modified by Fern

src/Client.ts
src/core/form-data-utils/FormDataWrapper.ts
src/core/form-data-utils/index.ts
src/core/index.ts
README.md
package.json

## Support content type on form data
src/core/form-data-utils
src/Client.ts
src/core/fetcher

## Change response signature
src/wrapper
src/index.ts

# Helper
src/generateFromHtml.ts

## Tests
tests/custom.test.ts

## Node v20
.github/workflows/ci.yml
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ jobs:

- name: Set up node
uses: actions/setup-node@v3
with:
node-version: 20

- name: Compile
run: yarn && yarn build
Expand All @@ -25,6 +27,8 @@ jobs:

- name: Set up node
uses: actions/setup-node@v3
with:
node-version: 20

- name: Compile
run: yarn && yarn test
Expand All @@ -40,6 +44,8 @@ jobs:

- name: Set up node
uses: actions/setup-node@v3
with:
node-version: 20

- name: Install dependencies
run: yarn install
Expand Down
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fileforge",
"version": "0.0.9",
"name": "@fileforge/client",
"version": "0.1.0",
"private": false,
"repository": "https://github.com/OnedocLabs/fileforge-node-sdk",
"license": "MIT",
Expand All @@ -15,11 +15,11 @@
"dependencies": {
"url-join": "4.0.1",
"form-data": "4.0.0",
"formdata-node": "^6.0.3",
"node-fetch": "2.7.0",
"qs": "6.11.2",
"formdata-node": "^6.0.3",
"form-data-encoder": "^4.0.2",
"js-base64": "3.7.2"
"mime-types": "^2.1.35"
},
"devDependencies": {
"@types/url-join": "4.0.1",
Expand All @@ -31,6 +31,7 @@
"jest-environment-jsdom": "29.7.0",
"@types/node": "17.0.33",
"prettier": "2.7.1",
"typescript": "4.6.4"
"typescript": "4.6.4",
"@types/mime-types": "^2.1.4"
}
}
166 changes: 141 additions & 25 deletions src/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,41 @@
import * as environments from "./environments";
import * as core from "./core";
import * as fs from "fs";
import * as FileForge from "./api/index";
import * as Fileforge from "./api/index";
import * as stream from "stream";
import urlJoin from "url-join";
import * as errors from "./errors/index";
import * as serializers from "./serialization/index";

export declare namespace FileForgeClient {
export declare namespace FileforgeClient {
interface Options {
environment?: core.Supplier<environments.FileForgeEnvironment | string>;
environment?: core.Supplier<environments.FileforgeEnvironment | string>;
apiKey: core.Supplier<string>;
}

interface RequestOptions {
timeoutInSeconds?: number;
maxRetries?: number;
abortSignal?: AbortSignal;
}
}

export class FileForgeClient {
constructor(protected readonly _options: FileForgeClient.Options) {}
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}
* @throws {@link FileForge.BadGatewayError}
* @throws {@link Fileforge.BadRequestError}
* @throws {@link Fileforge.UnauthorizedError}
* @throws {@link Fileforge.InternalServerError}
* @throws {@link Fileforge.BadGatewayError}
*/
public async generate(
files: File[] | fs.ReadStream[],
request: FileForge.GenerateRequest,
requestOptions?: FileForgeClient.RequestOptions
request: Fileforge.GenerateRequest,
requestOptions?: FileforgeClient.RequestOptions
): Promise<stream.Readable> {
const _request = core.newFormData();
const _request = new core.FormDataWrapper();
const options = await serializers.GenerateRequestOptions.jsonOrThrow(request.options, {
unrecognizedObjectKeys: "passthrough",
allowUnrecognizedUnionMembers: false,
Expand All @@ -49,49 +50,164 @@ export class FileForgeClient {
for (const _file of files) {
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,
(await core.Supplier.get(this._options.environment)) ?? environments.FileforgeEnvironment.Default,
"pdf/generate/"
),
method: "POST",
headers: {
"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-SDK-Name": "@fileforge/client",
"X-Fern-SDK-Version": "0.1.0",
"X-Fern-Runtime": core.RUNTIME.type,
"X-Fern-Runtime-Version": core.RUNTIME.version,
...(await _request.getHeaders()),
...(await this._getCustomAuthorizationHeaders()),
...(await _maybeEncodedRequest.getHeaders()),
},
body: await _request.getBody(),
body: await _maybeEncodedRequest.getBody(),
responseType: "streaming",
timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000,
maxRetries: requestOptions?.maxRetries,
abortSignal: requestOptions?.abortSignal,
});
if (_response.ok) {
return _response.body;
}

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

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

/**
* @throws {@link Fileforge.BadRequestError}
* @throws {@link Fileforge.UnauthorizedError}
* @throws {@link Fileforge.InternalServerError}
*/
public async merge(
files: File[] | fs.ReadStream[],
request: Fileforge.MergeRequest,
requestOptions?: FileforgeClient.RequestOptions
): Promise<stream.Readable> {
const _request = new core.FormDataWrapper();
const options = await serializers.MergeRequestOptions.jsonOrThrow(request.options, {
unrecognizedObjectKeys: "passthrough",
allowUnrecognizedUnionMembers: false,
allowUnrecognizedEnumValues: false,
breadcrumbsPrefix: [""],
});
await _request.append("options", new Blob([JSON.stringify(options)], { type: "application/json" }));
for (const _file of files) {
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,
"pdf/merge/"
),
method: "POST",
headers: {
"X-Fern-Language": "JavaScript",
"X-Fern-SDK-Name": "@fileforge/client",
"X-Fern-SDK-Version": "0.1.0",
"X-Fern-Runtime": core.RUNTIME.type,
"X-Fern-Runtime-Version": core.RUNTIME.version,
...(await this._getCustomAuthorizationHeaders()),
...(await _maybeEncodedRequest.getHeaders()),
},
body: await _maybeEncodedRequest.getBody(),
responseType: "streaming",
timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000,
maxRetries: requestOptions?.maxRetries,
abortSignal: requestOptions?.abortSignal,
});
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,
});
}
}

protected async _getCustomAuthorizationHeaders() {
const apiKeyValue = await core.Supplier.get(this._options.apiKey);
return { "X-API-Key": apiKeyValue };
}
}
38 changes: 0 additions & 38 deletions src/api/client/requests/ConvertDocxRequest.ts

This file was deleted.

4 changes: 2 additions & 2 deletions src/api/client/requests/GenerateRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
* This file was auto-generated by Fern from our API Definition.
*/

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

/**
* @example
* {}
*/
export interface GenerateRequest {
/** Conversion options. This field is required even if empty. */
options: FileForge.GenerateRequestOptions;
options: Fileforge.GenerateRequestOptions;
}
4 changes: 2 additions & 2 deletions src/api/client/requests/MergeRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
* This file was auto-generated by Fern from our API Definition.
*/

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

/**
* @example
* {}
*/
export interface MergeRequest {
options: FileForge.MergeRequestOptions;
options: Fileforge.MergeRequestOptions;
}
1 change: 0 additions & 1 deletion src/api/client/requests/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export { type ConvertDocxRequest } from "./ConvertDocxRequest";
export { type GenerateRequest } from "./GenerateRequest";
export { type MergeRequest } from "./MergeRequest";
Loading
Loading