Skip to content

Commit 72a71cd

Browse files
committed
chore: fix api definition resolution
1 parent 454f2c3 commit 72a71cd

File tree

8 files changed

+440
-430
lines changed

8 files changed

+440
-430
lines changed

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,6 @@ jobs:
5050
- name: Publish to npm
5151
run: |
5252
npm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN}
53-
npm publish --access public --tag beta
53+
npm publish --access public
5454
env:
5555
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

README.md

+41-37
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
<!-- ![](assets/logo.svg) -->
77

8-
98
The Fern Typescript library provides access to the Fern's Public API from JavaScript/TypeScript, and from the JavaScript runtime of your choice ([Node, Browser, Deno, Bun and more](#runtime-compatiblity)).
109

1110
## Documentation
@@ -15,13 +14,15 @@ API reference documentation is available [here](https://buildwithfern.com/learn/
1514
This SDK primarily serves as a way to access Fern's **dynamic snippets** API. Fern's dynamic snippets API is meant to allow users to create code snippets for their Fern-generate SDKs with dynamic payloads.
1615

1716
Common use cases include:
17+
1818
1. In-app code examples
1919
2. User-specific code examples in your documentation
2020
3. So much more!
2121

2222
<br/>
2323

2424
Notable features:
25+
2526
1. [Client-side execution](#client-side-execution), ideal for code examples that change often, potentially due to user input in a browser.
2627
2. [Dynamic code examples](#dynamic-code-examples)
2728
3. [Displaying default and auto-generated examples](#default-or-static-code-examples)
@@ -39,6 +40,7 @@ yarn add @fern-api/sdk
3940
## Usage
4041

4142
### Client-side Execution
43+
4244
```typescript
4345
import { FernClient } from "@fern-api/sdk";
4446

@@ -79,6 +81,7 @@ const snippet2 = template.resolve({
7981
```
8082

8183
### Dynamic Code Examples
84+
8285
```typescript
8386
import { FernClient } from "@fern-api/sdk";
8487

@@ -107,6 +110,7 @@ const snippets = await fern.snippets.get({
107110
```
108111

109112
### Default or Static Code Examples
113+
110114
```typescript
111115
import { FernClient } from "@fern-api/sdk";
112116

@@ -117,21 +121,21 @@ const fern = new FernClient({
117121
// Without any payload specified, the SDK returns a snippet with the examples provided within your API spec
118122
// If there are no examples in your spec, a basic example is autogenerated for you.
119123
const snippets = await fern.snippets.get({
120-
endpoint: {
121-
method: "GET",
122-
path: "/api/users",
123-
},
124-
// The name of your organization, found in your `fern.config.json`
125-
orgId: "my_organization",
126-
// The name of the API you'd like to generate snippets for,
127-
apiId: "api",
128-
sdks: [{ "type": "python", "package": "my_package", "version": "0.0.3" }],
124+
endpoint: {
125+
method: "GET",
126+
path: "/api/users",
127+
},
128+
// The name of your organization, found in your `fern.config.json`
129+
orgId: "my_organization",
130+
// The name of the API you'd like to generate snippets for,
131+
apiId: "api",
132+
sdks: [{ type: "python", package: "my_package", version: "0.0.3" }],
129133
});
130134
```
131135

132-
133136
### Handling Errors
134-
When the API returns a non-success status code (4xx or 5xx response),
137+
138+
When the API returns a non-success status code (4xx or 5xx response),
135139
a subclass of [FernError](./src/errors/FernError.ts)
136140
will be thrown:
137141

@@ -142,56 +146,56 @@ try {
142146
await fern.snippets.get(...);
143147
} catch (err) {
144148
if (err instanceof FernError) {
145-
console.log(err.statusCode);
149+
console.log(err.statusCode);
146150
console.log(err.message);
147-
console.log(err.body);
151+
console.log(err.body);
148152
}
149153
}
150154
```
151155

152156
### Request Options
153157

154-
The HTTP Client accepts a `RequestOptions` class where you can specify
155-
a customized timeout.
158+
The HTTP Client accepts a `RequestOptions` class where you can specify
159+
a customized timeout.
156160

157161
```typescript
158162
const snippets = await fern.snippets.get(
159-
{
160-
endpoint: {
161-
method: "GET",
162-
path: "/api/users",
163+
{
164+
endpoint: {
165+
method: "GET",
166+
path: "/api/users",
167+
},
168+
},
169+
{
170+
timeoutInSeconds: 60, // increase timeout in second
163171
}
164-
},
165-
{
166-
timeoutInSeconds: 60 // increase timeout in second
167-
});
172+
);
168173
```
169174

170175
### Runtime compatiblity
171176

172-
The SDK defaults to `node-fetch` but will use the global fetch client if present. The SDK
173-
works in the following runtimes:
177+
The SDK defaults to `node-fetch` but will use the global fetch client if present. The SDK
178+
works in the following runtimes:
174179

175180
The following runtimes are supported:
176181

177-
- Node.js 15+
178-
- Vercel
179-
- Cloudflare Workers
180-
- Deno v1.25+
181-
- Bun 1.0+
182-
182+
- Node.js 15+
183+
- Vercel
184+
- Cloudflare Workers
185+
- Deno v1.25+
186+
- Bun 1.0+
183187

184188
## Beta status
185189

186-
This SDK is in beta, and there may be breaking changes between versions without a major version update. Therefore, we
187-
recommend pinning the package version to a specific version in your package.json file. This way, you can install the
190+
This SDK is in beta, and there may be breaking changes between versions without a major version update. Therefore, we
191+
recommend pinning the package version to a specific version in your package.json file. This way, you can install the
188192
same version each time without breaking changes unless you are intentionally looking for the latest version.
189193

190194
## Contributing
191195

192-
While we value open-source contributions to this SDK, this library is generated programmatically.
193-
Additions made directly to this library would have to be moved over to our generation code, otherwise
194-
they would be overwritten upon the next generated release. Feel free to open a PR as a proof of concept,
196+
While we value open-source contributions to this SDK, this library is generated programmatically.
197+
Additions made directly to this library would have to be moved over to our generation code, otherwise
198+
they would be overwritten upon the next generated release. Feel free to open a PR as a proof of concept,
195199
but know that we will not be able to merge it as-is. We suggest opening an issue first to discuss with us!
196200

197201
On the other hand, contributions to the README are always very welcome!

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@fern-api/sdk",
3-
"version": "0.13.0-beta1",
3+
"version": "0.13.0",
44
"private": false,
55
"repository": "https://github.com/fern-api/typescript-sdk",
66
"license": "MIT",

src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ export * as Fern from "./api";
22
export { FernClient } from "./wrapper/FernClient";
33
export { FernEnvironment } from "./environments";
44
export { FernError, FernTimeoutError } from "./errors";
5-
export { Template } from "./wrapper/Template";
5+
export { Template } from "./wrapper/Template";

src/wrapper/FernClient.ts

-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import { FernClient as GeneratedClient } from "../Client";
22
import { TemplatesClient } from "./TemplatesClient";
33

4-
54
export class FernClient extends GeneratedClient {
6-
75
protected _templates: TemplatesClient | undefined;
86

97
public get templates(): TemplatesClient {

src/wrapper/Template.ts

+32-22
Original file line numberDiff line numberDiff line change
@@ -4,45 +4,49 @@ import { FernRegistry, FernRegistryClient } from "@fern-fern/fdr-cjs-sdk";
44

55
export class Template implements Fern.templates.EndpointSnippetTemplate {
66
private endpointSnippetTemplate: Fern.EndpointSnippetTemplate;
7-
7+
88
constructor(
99
public readonly sdk: Fern.snippets.Sdk,
1010
public readonly endpointId: Fern.commons.EndpointIdentifier,
11-
public readonly snippetTemplate: Fern.templates.VersionedSnippetTemplate
11+
public readonly snippetTemplate: Fern.templates.VersionedSnippetTemplate,
12+
public readonly apiDefinitionId?: Fern.ApiDefinitionId
1213
) {
13-
this.endpointSnippetTemplate = {sdk, endpointId, snippetTemplate};
14+
this.endpointSnippetTemplate = { sdk, endpointId, snippetTemplate, apiDefinitionId };
1415
}
1516

1617
/**
1718
* Resolves a particular request payload against the template to produce a snippet
1819
* @param payload the paylod to resolve against
1920
* @returns the snippet
2021
*/
21-
public resolve(payload: Fern.snippets.CustomSnippetPayload): Fern.snippets.Snippet {
22+
public async resolve(payload: Fern.snippets.CustomSnippetPayload): Promise<Fern.snippets.Snippet> {
23+
const response = this.apiDefinitionId != null ? await new FernRegistryClient().api.v1.read.getApi(FernRegistry.ApiDefinitionId(this.apiDefinitionId)) : undefined;
2224
const _innerResolver = new SnippetTemplateResolver({
2325
payload: {
2426
...payload,
25-
headers: payload.headers?.map((header): FernRegistry.ParameterPayload => { return { name: header.name, value: header.value ?? undefined } }),
26-
pathParameters: payload.pathParameters?.map((header): FernRegistry.ParameterPayload => { return { name: header.name, value: header.value ?? undefined } }),
27-
queryParameters: payload.queryParameters?.map((header): FernRegistry.ParameterPayload => { return { name: header.name, value: header.value ?? undefined } }),
27+
headers: payload.headers?.map((header): FernRegistry.ParameterPayload => {
28+
return { name: header.name, value: header.value ?? undefined };
29+
}),
30+
pathParameters: payload.pathParameters?.map((header): FernRegistry.ParameterPayload => {
31+
return { name: header.name, value: header.value ?? undefined };
32+
}),
33+
queryParameters: payload.queryParameters?.map((header): FernRegistry.ParameterPayload => {
34+
return { name: header.name, value: header.value ?? undefined };
35+
}),
2836
requestBody: payload.requestBody ?? undefined,
2937
auth: payload.auth ?? undefined,
3038
},
3139
endpointSnippetTemplate: this.endpointSnippetTemplate as FernRegistry.EndpointSnippetTemplate,
32-
apiDefinitionGetter: async (id) => {
33-
const response = await new FernRegistryClient().api.v1.read.getApi(FernRegistry.ApiDefinitionId(id));
34-
if (response.ok) {
35-
return response.body;
36-
}
37-
throw new Error(JSON.stringify(response.error));
38-
},
3940
});
40-
41-
return _innerResolver.resolve();
41+
if (response?.ok) {
42+
return _innerResolver.resolve(response.body);
43+
} else {
44+
return _innerResolver.resolve();
45+
}
4246
}
4347

4448
/**
45-
* Resolves a particular request payload against the template to produce a snippet with
49+
* Resolves a particular request payload against the template to produce a snippet with
4650
* formatting.
4751
* @param payload the paylod to resolve against
4852
* @returns the snippet
@@ -51,9 +55,15 @@ export class Template implements Fern.templates.EndpointSnippetTemplate {
5155
const _innerResolver = new SnippetTemplateResolver({
5256
payload: {
5357
...payload,
54-
headers: payload.headers?.map((header): FernRegistry.ParameterPayload => { return { name: header.name, value: header.value ?? undefined } }),
55-
pathParameters: payload.pathParameters?.map((header): FernRegistry.ParameterPayload => { return { name: header.name, value: header.value ?? undefined } }),
56-
queryParameters: payload.queryParameters?.map((header): FernRegistry.ParameterPayload => { return { name: header.name, value: header.value ?? undefined } }),
58+
headers: payload.headers?.map((header): FernRegistry.ParameterPayload => {
59+
return { name: header.name, value: header.value ?? undefined };
60+
}),
61+
pathParameters: payload.pathParameters?.map((header): FernRegistry.ParameterPayload => {
62+
return { name: header.name, value: header.value ?? undefined };
63+
}),
64+
queryParameters: payload.queryParameters?.map((header): FernRegistry.ParameterPayload => {
65+
return { name: header.name, value: header.value ?? undefined };
66+
}),
5767
requestBody: payload.requestBody ?? undefined,
5868
auth: payload.auth ?? undefined,
5969
},
@@ -75,10 +85,10 @@ export class Template implements Fern.templates.EndpointSnippetTemplate {
7585
}
7686

7787
public static from(template: Fern.templates.EndpointSnippetTemplate): Template {
78-
return new Template(template.sdk, template.endpointId, template.snippetTemplate);
88+
return new Template(template.sdk, template.endpointId, template.snippetTemplate, template.apiDefinitionId);
7989
}
8090
}
8191

8292
export function isNonNullish<T>(x: T | null | undefined): x is T {
8393
return x != null;
84-
}
94+
}

src/wrapper/TemplatesClient.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
import { Templates as GeneratedTemplatesClient } from "../api/resources/templates/client/Client"
1+
import { Templates as GeneratedTemplatesClient } from "../api/resources/templates/client/Client";
22
import { Fern } from "../index";
33
import { Template } from "./Template";
44

5-
65
export class TemplatesClient extends GeneratedTemplatesClient {
7-
86
/**
97
* Get the endpoint's snippet template for a particular SDK.
108
* @throws {@link Fern.UnauthorizedError}
@@ -15,6 +13,6 @@ export class TemplatesClient extends GeneratedTemplatesClient {
1513
requestOptions?: GeneratedTemplatesClient.RequestOptions
1614
): Promise<Template> {
1715
const innerTemplate = await super.get(request, requestOptions);
18-
return Template.from(innerTemplate)
16+
return Template.from(innerTemplate);
1917
}
2018
}

0 commit comments

Comments
 (0)