Skip to content

Commit

Permalink
fix, ts: leverage the full package path for reference.md (#3083)
Browse files Browse the repository at this point in the history
  • Loading branch information
armandobelardo authored Feb 29, 2024
1 parent 1e7886e commit 41d12bd
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 48 deletions.
61 changes: 36 additions & 25 deletions generators/typescript/sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,48 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [0.12.3-rc1] - 2024-02-27

- Fix: Previously SDK code snippets would not support generation with undiscriminated
unions. Now, it does.
- Fix: Previously reference.md was just leveraging the function name for the reference, now it leverages the full package-scoped path, mirroring how the function would be used in reality.

```ts
seedExamples.getException(...)

// is now

seedExamples.file.notification.service.getException(...)
```

## [0.12.3-rc1] - 2024-02-27

- Fix: Previously SDK code snippets would not support generation with undiscriminated unions. Now, it does.

## [0.12.2] - 2024-02-27

- Fix: Previously SDK code snippets would not take into account default parameter values
and would always include a `{}`. This was odd and didn't represent how a developer
would use the SDK. Now, the snippets check for default parameter values and omit
if there are no fields specified.
and would always include a `{}`. This was odd and didn't represent how a developer
would use the SDK. Now, the snippets check for default parameter values and omit
if there are no fields specified.

```ts
// Before
client.users.list({})
client.users.list({});

// After
client.users.list()
client.users.list();
```

## [0.12.1] - 2024-02-27

- Fix: Optional objects in deep query parameters were previously being incorrectly
- Fix: Optional objects in deep query parameters were previously being incorrectly
serialized. Before this change, optional objects were just being JSON.stringified
which would send the incorrect contents over the wire.
which would send the incorrect contents over the wire.

```ts
// Before
if (foo != null) {
_queryParams["foo"] = JSON.stringify(foo);
}
// After
// After
if (foo != null) {
_queryParams["foo"] = foo;
}
Expand All @@ -48,21 +58,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
_queryParams["foo"] = serializers.Foo.jsonOrThrow(foo, {
skipValidation: false,
breadcrumbs: ["request", "foo"]
})
});
}
```

## [0.12.0] - 2024-02-26

- Feature: support deep object query parameter serialization. If, query parameters are
objects then Fern will support serializing them.
- Feature: support deep object query parameter serialization. If, query parameters are
objects then Fern will support serializing them.

```yaml
MyFoo:
properties:
bar: optional<string>
MyFoo:
properties:
bar: optional<string>
query-parameters:
query-parameters:
foo: MyFoo
```

Expand All @@ -71,22 +81,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
```ts
client.doThing({
foo: {
bar: "...",
bar: "..."
}
})
});
```

## [0.11.5] - 2024-02-15

- Fix: Previously `core.Stream` would not work in the Browser. Now the generated Fern SDK
includes a polyfill for `ReadableStream` and uses `TextDecoder` instead of `Buffer`.
- Fix: Previously `core.Stream` would not work in the Browser. Now the generated Fern SDK
includes a polyfill for `ReadableStream` and uses `TextDecoder` instead of `Buffer`.

- Feature: add in a reference markdown file, this shows a quick outline of the available endpoints,
- Feature: add in a reference markdown file, this shows a quick outline of the available endpoints,
it's documentation, code snippet, and parameters.

This feature is currently behind a feature flag called `includeApiReference` and can be used
This feature is currently behind a feature flag called `includeApiReference` and can be used

```yaml
config:
config:
includeApiReference: true
```

Expand Down
2 changes: 1 addition & 1 deletion generators/typescript/sdk/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.12.3-rc1
0.12.4
24 changes: 12 additions & 12 deletions generators/typescript/sdk/generator/src/ReferenceGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
export declare namespace ReferenceGenerator {
export interface Init {
clientName: string;
apiName?: string;
apiName: string;
}
}
export declare namespace ReferenceGeneratorSection {
export interface Init {
clientName: string;
apiName: string;
// Heading is essentially just the endpoint name in the root package OR
heading: string;
}
Expand All @@ -21,6 +20,7 @@ export interface ReferenceParameterDeclaration {
export interface EndpointDeclaration {
functionPath?: string;
functionName: string;
clientPath?: string;
returnType: string | undefined;
returnTypePath?: string;
codeSnippet: string | undefined;
Expand All @@ -44,12 +44,12 @@ function writeSignature(parameters: ReferenceParameterDeclaration[]): string {
}

class ReferenceGeneratorSection {
clientName: string;
apiName: string;
heading: string;
endpoints: EndpointDeclaration[];

constructor(init: ReferenceGeneratorSection.Init) {
this.clientName = init.clientName;
this.apiName = init.apiName;
this.heading = init.heading;
this.endpoints = [];
}
Expand Down Expand Up @@ -89,9 +89,10 @@ class ReferenceGeneratorSection {
: "";

return `
<details><summary> <code>${this.clientName}.${wrapInLink(endpoint.functionName, endpoint.functionPath)}${writeSignature(
endpoint.parameters
)} -> ${wrapInLink(
<details><summary> <code>${endpoint.clientPath ?? this.apiName}.${wrapInLink(
endpoint.functionName,
endpoint.functionPath
)}${writeSignature(endpoint.parameters)} -> ${wrapInLink(
endpoint.returnType === undefined ? "void" : endpoint.returnType,
endpoint.returnTypePath
)}</code> </summary>
Expand All @@ -112,18 +113,17 @@ ${this.endpoints.map((endpoint) => this.writeEndpoint(endpoint)).join("\n")}
}

export class ReferenceGenerator {
apiName: string | undefined;
clientName: string;
apiName: string;
sections: ReferenceGeneratorSection[];

constructor(init: ReferenceGenerator.Init) {
this.clientName = init.clientName;
this.apiName = init.apiName;
this.apiName = init.apiName;
this.sections = [];
}

public addSection(heading: string): ReferenceGeneratorSection {
const section = new ReferenceGeneratorSection({ clientName: this.clientName, heading });
const section = new ReferenceGeneratorSection({ apiName: this.apiName, heading });
this.sections.push(section);
return section;
}
Expand Down
14 changes: 13 additions & 1 deletion generators/typescript/sdk/generator/src/SdkGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,6 @@ module.exports = {
let refGenerator: ReferenceGenerator | undefined;
if (this.config.includeApiReference) {
refGenerator = new ReferenceGenerator({
clientName: this.intermediateRepresentation.apiName.camelCase.safeName,
apiName: this.namespaceExport === "api" ? "client" : this.namespaceExport
});
}
Expand Down Expand Up @@ -640,6 +639,7 @@ module.exports = {

if (serviceReference !== undefined) {
let returnType = undefined;
let endpointClientAccess: ts.Expression | undefined = undefined;
const parameters: ReferenceParameterDeclaration[] = [];
const referenceSnippet = this.withSnippet({
run: ({ sourceFile, importsManager }): ts.Node[] | undefined => {
Expand All @@ -662,6 +662,10 @@ module.exports = {
}) ?? [])
);

endpointClientAccess = clientClass.accessFromRootClient({
referenceToRootClient: context.sdkInstanceReferenceForSnippet
});

return this.runWithSnippet({
sourceFile,
importsManager,
Expand All @@ -675,7 +679,15 @@ module.exports = {
includeImports: false
});

let statement = undefined;
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (endpointClientAccess !== undefined) {
statement = getTextOfTsNode(endpointClientAccess);
}

serviceReference.addEndpoint({
// clientPath: getTextOfTsNode(statement),
clientPath: statement,
functionPath: serviceFilepath,
functionName: endpoint.name.camelCase.unsafeName,
returnType,
Expand Down
5 changes: 5 additions & 0 deletions packages/seed/fern/definition/features.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ types:
docs: |
The SDK should provide a way to access additional properties on the response object.
This is useful for when the API adds new fields to the response object and the user wants to grab them without upgrading the SDK.
apiReferenceGeneration:
type: FeatureImplementation
docs: |
The SDK should generate an API reference markdown file (refrence.md at the root level) that shows all the endpoints, their documentation,
their parameters, and their responses.
whitelabel:
type: FeatureImplementation
docs: |
Expand Down
1 change: 1 addition & 0 deletions seed/ruby-sdk/seed.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ features:
forwardCompatibleEnums: true
additionalProperties: true
whitelabel: false
apiReferenceGeneration: false
16 changes: 8 additions & 8 deletions seed/ts-sdk/examples/examples-with-api-reference/reference.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion seed/ts-sdk/seed.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,3 @@ allowedFailures:
- exhaustive:dev-dependencies
- audiences
- enum # throws b/c of undiscriminated union examples
- examples:examples-with-api-reference # throws b/c of undiscriminated union examples

0 comments on commit 41d12bd

Please sign in to comment.