Skip to content

Commit b822081

Browse files
authored
Merge pull request #5 from OnedocLabs/v0
(init): setup and publish SDK
2 parents 2f40bba + d180eaf commit b822081

36 files changed

+837
-523
lines changed

.fernignore

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,21 @@
11
# Specify files that shouldn't be modified by Fern
22

3-
src/Client.ts
4-
src/core/form-data-utils/FormDataWrapper.ts
5-
src/core/form-data-utils/index.ts
6-
src/core/index.ts
73
README.md
8-
package.json
4+
5+
## Support content type on form data
6+
src/core/form-data-utils
7+
src/Client.ts
8+
src/core/fetcher
9+
10+
## Change response signature
11+
src/wrapper
12+
src/index.ts
13+
14+
# Helper
15+
src/generateFromHtml.ts
16+
17+
## Tests
18+
tests/custom.test.ts
19+
20+
## Node v20
21+
.github/workflows/ci.yml

.github/workflows/ci.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ jobs:
1212

1313
- name: Set up node
1414
uses: actions/setup-node@v3
15+
with:
16+
node-version: 20
1517

1618
- name: Compile
1719
run: yarn && yarn build
@@ -25,6 +27,8 @@ jobs:
2527

2628
- name: Set up node
2729
uses: actions/setup-node@v3
30+
with:
31+
node-version: 20
2832

2933
- name: Compile
3034
run: yarn && yarn test
@@ -40,6 +44,8 @@ jobs:
4044

4145
- name: Set up node
4246
uses: actions/setup-node@v3
47+
with:
48+
node-version: 20
4349

4450
- name: Install dependencies
4551
run: yarn install

package.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"name": "fileforge",
3-
"version": "0.0.9",
2+
"name": "@fileforge/client",
3+
"version": "0.1.0",
44
"private": false,
55
"repository": "https://github.com/OnedocLabs/fileforge-node-sdk",
66
"license": "MIT",
@@ -15,11 +15,11 @@
1515
"dependencies": {
1616
"url-join": "4.0.1",
1717
"form-data": "4.0.0",
18+
"formdata-node": "^6.0.3",
1819
"node-fetch": "2.7.0",
1920
"qs": "6.11.2",
20-
"formdata-node": "^6.0.3",
2121
"form-data-encoder": "^4.0.2",
22-
"js-base64": "3.7.2"
22+
"mime-types": "^2.1.35"
2323
},
2424
"devDependencies": {
2525
"@types/url-join": "4.0.1",
@@ -31,6 +31,7 @@
3131
"jest-environment-jsdom": "29.7.0",
3232
"@types/node": "17.0.33",
3333
"prettier": "2.7.1",
34-
"typescript": "4.6.4"
34+
"typescript": "4.6.4",
35+
"@types/mime-types": "^2.1.4"
3536
}
3637
}

src/Client.ts

Lines changed: 141 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,40 +5,41 @@
55
import * as environments from "./environments";
66
import * as core from "./core";
77
import * as fs from "fs";
8-
import * as FileForge from "./api/index";
8+
import * as Fileforge from "./api/index";
99
import * as stream from "stream";
1010
import urlJoin from "url-join";
1111
import * as errors from "./errors/index";
1212
import * as serializers from "./serialization/index";
1313

14-
export declare namespace FileForgeClient {
14+
export declare namespace FileforgeClient {
1515
interface Options {
16-
environment?: core.Supplier<environments.FileForgeEnvironment | string>;
16+
environment?: core.Supplier<environments.FileforgeEnvironment | string>;
1717
apiKey: core.Supplier<string>;
1818
}
1919

2020
interface RequestOptions {
2121
timeoutInSeconds?: number;
2222
maxRetries?: number;
23+
abortSignal?: AbortSignal;
2324
}
2425
}
2526

26-
export class FileForgeClient {
27-
constructor(protected readonly _options: FileForgeClient.Options) {}
27+
export class FileforgeClient {
28+
constructor(protected readonly _options: FileforgeClient.Options) {}
2829

2930
/**
3031
* Generates a PDF document from web assets.
31-
* @throws {@link FileForge.BadRequestError}
32-
* @throws {@link FileForge.UnauthorizedError}
33-
* @throws {@link FileForge.InternalServerError}
34-
* @throws {@link FileForge.BadGatewayError}
32+
* @throws {@link Fileforge.BadRequestError}
33+
* @throws {@link Fileforge.UnauthorizedError}
34+
* @throws {@link Fileforge.InternalServerError}
35+
* @throws {@link Fileforge.BadGatewayError}
3536
*/
3637
public async generate(
3738
files: File[] | fs.ReadStream[],
38-
request: FileForge.GenerateRequest,
39-
requestOptions?: FileForgeClient.RequestOptions
39+
request: Fileforge.GenerateRequest,
40+
requestOptions?: FileforgeClient.RequestOptions
4041
): Promise<stream.Readable> {
41-
const _request = core.newFormData();
42+
const _request = new core.FormDataWrapper();
4243
const options = await serializers.GenerateRequestOptions.jsonOrThrow(request.options, {
4344
unrecognizedObjectKeys: "passthrough",
4445
allowUnrecognizedUnionMembers: false,
@@ -49,49 +50,164 @@ export class FileForgeClient {
4950
for (const _file of files) {
5051
await _request.append("files", _file);
5152
}
53+
54+
const _maybeEncodedRequest = _request.getRequest();
5255
const _response = await core.fetcher<stream.Readable>({
5356
url: urlJoin(
54-
(await core.Supplier.get(this._options.environment)) ?? environments.FileForgeEnvironment.Default,
57+
(await core.Supplier.get(this._options.environment)) ?? environments.FileforgeEnvironment.Default,
5558
"pdf/generate/"
5659
),
5760
method: "POST",
5861
headers: {
59-
"X-API-Key": await core.Supplier.get(this._options.apiKey),
6062
"X-Fern-Language": "JavaScript",
61-
"X-Fern-SDK-Name": "fileforge",
62-
"X-Fern-SDK-Version": "0.0.1",
63+
"X-Fern-SDK-Name": "@fileforge/client",
64+
"X-Fern-SDK-Version": "0.1.0",
6365
"X-Fern-Runtime": core.RUNTIME.type,
6466
"X-Fern-Runtime-Version": core.RUNTIME.version,
65-
...(await _request.getHeaders()),
67+
...(await this._getCustomAuthorizationHeaders()),
68+
...(await _maybeEncodedRequest.getHeaders()),
6669
},
67-
body: await _request.getBody(),
70+
body: await _maybeEncodedRequest.getBody(),
6871
responseType: "streaming",
6972
timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000,
7073
maxRetries: requestOptions?.maxRetries,
74+
abortSignal: requestOptions?.abortSignal,
7175
});
7276
if (_response.ok) {
7377
return _response.body;
7478
}
7579

7680
if (_response.error.reason === "status-code") {
77-
throw new errors.FileForgeError({
78-
statusCode: _response.error.statusCode,
79-
body: _response.error.body,
80-
});
81+
switch (_response.error.statusCode) {
82+
case 500:
83+
throw new Fileforge.InternalServerError(_response.error.body);
84+
case 502:
85+
throw new Fileforge.BadGatewayError(
86+
await serializers.ErrorSchema.parseOrThrow(_response.error.body, {
87+
unrecognizedObjectKeys: "passthrough",
88+
allowUnrecognizedUnionMembers: true,
89+
allowUnrecognizedEnumValues: true,
90+
breadcrumbsPrefix: ["response"],
91+
})
92+
);
93+
default:
94+
throw new errors.FileforgeError({
95+
statusCode: _response.error.statusCode,
96+
body: _response.error.body,
97+
});
98+
}
8199
}
82100

83101
switch (_response.error.reason) {
84102
case "non-json":
85-
throw new errors.FileForgeError({
103+
throw new errors.FileforgeError({
86104
statusCode: _response.error.statusCode,
87105
body: _response.error.rawBody,
88106
});
89107
case "timeout":
90-
throw new errors.FileForgeTimeoutError();
108+
throw new errors.FileforgeTimeoutError();
91109
case "unknown":
92-
throw new errors.FileForgeError({
110+
throw new errors.FileforgeError({
93111
message: _response.error.errorMessage,
94112
});
95113
}
96114
}
115+
116+
/**
117+
* @throws {@link Fileforge.BadRequestError}
118+
* @throws {@link Fileforge.UnauthorizedError}
119+
* @throws {@link Fileforge.InternalServerError}
120+
*/
121+
public async merge(
122+
files: File[] | fs.ReadStream[],
123+
request: Fileforge.MergeRequest,
124+
requestOptions?: FileforgeClient.RequestOptions
125+
): Promise<stream.Readable> {
126+
const _request = new core.FormDataWrapper();
127+
const options = await serializers.MergeRequestOptions.jsonOrThrow(request.options, {
128+
unrecognizedObjectKeys: "passthrough",
129+
allowUnrecognizedUnionMembers: false,
130+
allowUnrecognizedEnumValues: false,
131+
breadcrumbsPrefix: [""],
132+
});
133+
await _request.append("options", new Blob([JSON.stringify(options)], { type: "application/json" }));
134+
for (const _file of files) {
135+
await _request.append("files", _file);
136+
}
137+
138+
const _maybeEncodedRequest = _request.getRequest();
139+
const _response = await core.fetcher<stream.Readable>({
140+
url: urlJoin(
141+
(await core.Supplier.get(this._options.environment)) ?? environments.FileforgeEnvironment.Default,
142+
"pdf/merge/"
143+
),
144+
method: "POST",
145+
headers: {
146+
"X-Fern-Language": "JavaScript",
147+
"X-Fern-SDK-Name": "@fileforge/client",
148+
"X-Fern-SDK-Version": "0.1.0",
149+
"X-Fern-Runtime": core.RUNTIME.type,
150+
"X-Fern-Runtime-Version": core.RUNTIME.version,
151+
...(await this._getCustomAuthorizationHeaders()),
152+
...(await _maybeEncodedRequest.getHeaders()),
153+
},
154+
body: await _maybeEncodedRequest.getBody(),
155+
responseType: "streaming",
156+
timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000,
157+
maxRetries: requestOptions?.maxRetries,
158+
abortSignal: requestOptions?.abortSignal,
159+
});
160+
if (_response.ok) {
161+
return _response.body;
162+
}
163+
164+
if (_response.error.reason === "status-code") {
165+
switch (_response.error.statusCode) {
166+
case 400:
167+
throw new Fileforge.BadRequestError(
168+
await serializers.ErrorSchema.parseOrThrow(_response.error.body, {
169+
unrecognizedObjectKeys: "passthrough",
170+
allowUnrecognizedUnionMembers: true,
171+
allowUnrecognizedEnumValues: true,
172+
breadcrumbsPrefix: ["response"],
173+
})
174+
);
175+
case 401:
176+
throw new Fileforge.UnauthorizedError(
177+
await serializers.ErrorSchema.parseOrThrow(_response.error.body, {
178+
unrecognizedObjectKeys: "passthrough",
179+
allowUnrecognizedUnionMembers: true,
180+
allowUnrecognizedEnumValues: true,
181+
breadcrumbsPrefix: ["response"],
182+
})
183+
);
184+
case 500:
185+
throw new Fileforge.InternalServerError(_response.error.body);
186+
default:
187+
throw new errors.FileforgeError({
188+
statusCode: _response.error.statusCode,
189+
body: _response.error.body,
190+
});
191+
}
192+
}
193+
194+
switch (_response.error.reason) {
195+
case "non-json":
196+
throw new errors.FileforgeError({
197+
statusCode: _response.error.statusCode,
198+
body: _response.error.rawBody,
199+
});
200+
case "timeout":
201+
throw new errors.FileforgeTimeoutError();
202+
case "unknown":
203+
throw new errors.FileforgeError({
204+
message: _response.error.errorMessage,
205+
});
206+
}
207+
}
208+
209+
protected async _getCustomAuthorizationHeaders() {
210+
const apiKeyValue = await core.Supplier.get(this._options.apiKey);
211+
return { "X-API-Key": apiKeyValue };
212+
}
97213
}

src/api/client/requests/ConvertDocxRequest.ts

Lines changed: 0 additions & 38 deletions
This file was deleted.

src/api/client/requests/GenerateRequest.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
* This file was auto-generated by Fern from our API Definition.
33
*/
44

5-
import * as FileForge from "../../index";
5+
import * as Fileforge from "../../index";
66

77
/**
88
* @example
99
* {}
1010
*/
1111
export interface GenerateRequest {
1212
/** Conversion options. This field is required even if empty. */
13-
options: FileForge.GenerateRequestOptions;
13+
options: Fileforge.GenerateRequestOptions;
1414
}

src/api/client/requests/MergeRequest.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
* This file was auto-generated by Fern from our API Definition.
33
*/
44

5-
import * as FileForge from "../../index";
5+
import * as Fileforge from "../../index";
66

77
/**
88
* @example
99
* {}
1010
*/
1111
export interface MergeRequest {
12-
options: FileForge.MergeRequestOptions;
12+
options: Fileforge.MergeRequestOptions;
1313
}

src/api/client/requests/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
export { type ConvertDocxRequest } from "./ConvertDocxRequest";
21
export { type GenerateRequest } from "./GenerateRequest";
32
export { type MergeRequest } from "./MergeRequest";

0 commit comments

Comments
 (0)