Skip to content

Commit

Permalink
Merge branch 'main' into amckinney/go/file-upload
Browse files Browse the repository at this point in the history
  • Loading branch information
amckinney authored Nov 22, 2024
2 parents 9969c8a + 9f4ae0b commit 82dd61d
Show file tree
Hide file tree
Showing 273 changed files with 1,344 additions and 655 deletions.
8 changes: 8 additions & 0 deletions generators/typescript/sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.42.4] - 2024-11-21

- Fix: Improve `GeneratedTimeoutSdkError` error to include endpoint name in message.

## [0.42.3] - 2024-11-22

- Fix: Fixed issue with snippets used for pagination endpoints.

## [0.42.2] - 2024-11-21

- Improvement: Added documentation for pagination in the README. The snippet below will
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.42.2
0.42.4
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
ResponseError,
TypeReference
} from "@fern-fern/ir-sdk/api";
import { getTextOfTsNode, PackageId, StreamingFetcher } from "@fern-typescript/commons";
import { getFullPathForEndpoint, getTextOfTsNode, PackageId, StreamingFetcher } from "@fern-typescript/commons";
import { GeneratedSdkEndpointTypeSchemas, SdkContext } from "@fern-typescript/contexts";
import { ErrorResolver } from "@fern-typescript/resolvers";
import { ts } from "ts-morph";
Expand Down Expand Up @@ -772,7 +772,14 @@ export class GeneratedThrowingEndpointResponse implements GeneratedEndpointRespo
),
[
ts.factory.createThrowStatement(
context.timeoutSdkError.getGeneratedTimeoutSdkError().build(context)
context.timeoutSdkError
.getGeneratedTimeoutSdkError()
.build(
context,
`Timeout exceeded when calling ${this.endpoint.method} ${getFullPathForEndpoint(
this.endpoint
)}.`
)
)
]
),
Expand Down
21 changes: 3 additions & 18 deletions generators/typescript/sdk/generator/src/SdkGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
ExportedDirectory,
ExportedFilePath,
ExportsManager,
getFullPathForEndpoint,
getTextOfTsNode,
ImportsManager,
JavaScriptRuntime,
Expand All @@ -43,7 +44,6 @@ import { TypeReferenceExampleGenerator } from "@fern-typescript/type-reference-e
import { TypeSchemaGenerator } from "@fern-typescript/type-schema-generator";
import { writeFile } from "fs/promises";
import { Directory, Project, SourceFile, ts } from "ts-morph";
import urlJoin from "url-join";
import { v4 as uuidv4 } from "uuid";
import { SdkContextImpl } from "./contexts/SdkContextImpl";
import { EndpointDeclarationReferencer } from "./declaration-referencers/EndpointDeclarationReferencer";
Expand Down Expand Up @@ -900,7 +900,7 @@ export class SdkGenerator {
}).generateSnippetTemplate();

if (snippetTemplate != null) {
const endpointPath = FernGeneratorExec.EndpointPath(this.getFullPathForEndpoint(endpoint));
const endpointPath = FernGeneratorExec.EndpointPath(getFullPathForEndpoint(endpoint));
this.context.logger.debug(
`Snippet template created for endpoint: ${endpoint.method} ${endpointPath}`
);
Expand Down Expand Up @@ -950,7 +950,7 @@ export class SdkGenerator {
if (snippet != null) {
const endpointSnippet: FernGeneratorExec.Endpoint = {
id: {
path: FernGeneratorExec.EndpointPath(this.getFullPathForEndpoint(endpoint)),
path: FernGeneratorExec.EndpointPath(getFullPathForEndpoint(endpoint)),
method: endpoint.method,
identifierOverride: endpoint.id
},
Expand Down Expand Up @@ -1070,21 +1070,6 @@ export class SdkGenerator {
.join(", ")})`;
}

// TODO(dsinghvi): HACKHACK Move this to IR
private getFullPathForEndpoint(endpoint: HttpEndpoint): string {
let url = "";
if (endpoint.fullPath.head.length > 0) {
url = urlJoin(url, endpoint.fullPath.head);
}
for (const part of endpoint.fullPath.parts) {
url = urlJoin(url, "{" + part.pathParameter + "}");
if (part.tail.length > 0) {
url = urlJoin(url, part.tail);
}
}
return url.startsWith("/") ? url : `/${url}`;
}

private generateVersion(): void {
if (this.intermediateRepresentation.apiVersion == null) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { getTextOfTsNode } from "@fern-typescript/commons";
import { SdkContext } from "@fern-typescript/contexts";
import { code, Code } from "ts-poet";
import { AbstractReadmeSnippetBuilder } from "@fern-api/generator-commons";
import { isNonNullish } from "@fern-api/core-utils";

interface EndpointWithFilepath {
endpoint: HttpEndpoint;
Expand Down Expand Up @@ -84,24 +85,50 @@ export class ReadmeSnippetBuilder extends AbstractReadmeSnippetBuilder {
return snippets;
}

private buildSnippetsForFeature(featureId: FernGeneratorCli.feature.FeatureId): string[] {
const usageEndpointIds = this.getEndpointIdsForFeature(featureId);
if (usageEndpointIds != null) {
return usageEndpointIds.map((endpointId) => this.getSnippetForEndpointId(endpointId));
private getExplicitlyConfiguredSnippets(featureId: FeatureId): string[] | undefined {
const endpointIds = this.getEndpointIdsForFeature(featureId);
if (endpointIds != null) {
return endpointIds.map((endpointId) => this.getSnippetForEndpointId(endpointId)).filter(isNonNullish);
}
return [this.getSnippetForEndpointId(this.defaultEndpointId)];
return undefined;
}

private buildStreamingSnippets(): string[] {
return this.buildSnippetsForFeature(FernGeneratorCli.StructuredFeatureId.Streaming);
const explicitlyConfigured = this.getExplicitlyConfiguredSnippets(
FernGeneratorCli.StructuredFeatureId.Streaming
);
if (explicitlyConfigured != null) {
return explicitlyConfigured;
}
const streamingEndpoint = this.getEndpointWithStreaming();
if (streamingEndpoint != null) {
const snippet = this.getSnippetForEndpointId(streamingEndpoint.endpoint.id);
return snippet != null ? [snippet] : [];
}
return [];
}

private buildPaginationSnippets(): string[] {
return this.buildSnippetsForFeature(FernGeneratorCli.StructuredFeatureId.Pagination);
const explicitlyConfigured = this.getExplicitlyConfiguredSnippets(
FernGeneratorCli.StructuredFeatureId.Pagination
);
if (explicitlyConfigured != null) {
return explicitlyConfigured;
}
const paginationEndpoint = this.getEndpointWithPagination();
if (paginationEndpoint != null) {
const snippet = this.getSnippetForEndpointId(paginationEndpoint.endpoint.id);
return snippet != null ? [snippet] : [];
}
return [];
}

private buildUsageSnippets(): string[] {
return this.buildSnippetsForFeature(FernGeneratorCli.StructuredFeatureId.Usage);
const explicitlyConfigured = this.getExplicitlyConfiguredSnippets(FernGeneratorCli.StructuredFeatureId.Usage);
if (explicitlyConfigured != null) {
return explicitlyConfigured;
}
return [this.getSnippetForEndpointIdOrThrow(this.defaultEndpointId)];
}

private buildExceptionHandlingSnippets(): string[] {
Expand Down Expand Up @@ -275,22 +302,54 @@ const ${this.clientVariableName} = new ${this.rootClientConstructorName}({
return snippets;
}

private getSnippetForEndpointId(endpointId: EndpointId): string {
const snippet = this.snippets[endpointId];
private getSnippetForEndpointIdOrThrow(endpointId: EndpointId): string {
const snippet = this.getSnippetForEndpointId(endpointId);
if (snippet == null) {
throw new Error(`Internal error; missing snippet for endpoint ${endpointId}`);
}
return snippet;
}

private getSnippetForEndpointId(endpointId: EndpointId): string | undefined {
return this.snippets[endpointId];
}

private getEndpointWithPagination(): EndpointWithFilepath | undefined {
return this.filterEndpoint((endpointWithFilepath) => {
if (endpointWithFilepath.endpoint.pagination != null) {
return endpointWithFilepath;
}
return undefined;
});
}

private getEndpointWithStreaming(): EndpointWithFilepath | undefined {
return this.filterEndpoint((endpointWithFilepath) => {
if (endpointWithFilepath.endpoint.response?.body?.type === "streaming") {
return endpointWithFilepath;
}
return undefined;
});
}

private getEndpointWithRequest(): EndpointWithRequest | undefined {
for (const endpointWithFilepath of Object.values(this.endpoints)) {
return this.filterEndpoint((endpointWithFilepath) => {
if (endpointWithFilepath.endpoint.sdkRequest?.shape?.type === "wrapper") {
return {
endpoint: endpointWithFilepath.endpoint,
requestWrapper: endpointWithFilepath.endpoint.sdkRequest.shape
};
}
return undefined;
});
}

private filterEndpoint<T>(transform: (endpoint: EndpointWithFilepath) => T | undefined): T | undefined {
for (const endpointWithFilepath of Object.values(this.endpoints)) {
const result = transform(endpointWithFilepath);
if (result !== undefined) {
return result;
}
}
return undefined;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,50 @@ export class GeneratedTimeoutSdkErrorImpl
extends AbstractErrorClassGenerator<SdkContext>
implements GeneratedTimeoutSdkError
{
private static MESSAGE_CONSTRUCTOR_PARAMETER_NAME = "message";

public writeToFile(context: SdkContext): void {
super.writeToSourceFile(context);
}

public build(context: SdkContext): ts.NewExpression {
public build(context: SdkContext, message: string): ts.NewExpression {
return ts.factory.createNewExpression(
context.timeoutSdkError.getReferenceToTimeoutSdkError().getExpression(),
undefined,
undefined
[ts.factory.createStringLiteral(message)]
);
}

public buildConstructorArguments(message: ts.Expression): ts.Expression[] {
const properties: ts.ObjectLiteralElementLike[] = [];
if (message != null) {
properties.push(
ts.factory.createPropertyAssignment(
GeneratedTimeoutSdkErrorImpl.MESSAGE_CONSTRUCTOR_PARAMETER_NAME,
message
)
);
}

return [ts.factory.createObjectLiteralExpression(properties, true)];
}

protected getClassProperties(): OptionalKind<PropertyDeclarationStructure>[] {
return [];
}

protected getConstructorParameters(): OptionalKind<ParameterDeclarationStructure>[] {
return [];
return [
{
name: GeneratedTimeoutSdkErrorImpl.MESSAGE_CONSTRUCTOR_PARAMETER_NAME,
type: "string",
hasQuestionToken: false
}
];
}

protected getSuperArguments(): ts.Expression[] {
return [ts.factory.createStringLiteral("Timeout")];
return [ts.factory.createIdentifier(GeneratedTimeoutSdkErrorImpl.MESSAGE_CONSTRUCTOR_PARAMETER_NAME)];
}

protected getConstructorStatements(): ts.Statement[] {
Expand Down
16 changes: 16 additions & 0 deletions generators/typescript/utils/commons/src/getFullPathForEndpoint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { HttpEndpoint } from "@fern-fern/ir-sdk/api";
import urlJoin from "url-join";

export function getFullPathForEndpoint(endpoint: HttpEndpoint): string {
let url = "";
if (endpoint.fullPath.head.length > 0) {
url = urlJoin(url, endpoint.fullPath.head);
}
for (const part of endpoint.fullPath.parts) {
url = urlJoin(url, "{" + part.pathParameter + "}");
if (part.tail.length > 0) {
url = urlJoin(url, part.tail);
}
}
return url.startsWith("/") ? url : `/${url}`;
}
1 change: 1 addition & 0 deletions generators/typescript/utils/commons/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export * from "./express";
export { type ExpressionReferenceNode } from "./ExpressionReferenceNode";
export * from "./external-dependencies";
export * from "./imports-manager";
export { getFullPathForEndpoint } from "./getFullPathForEndpoint";
export { JavaScriptRuntime, visitJavaScriptRuntime, type JavaScriptRuntimeVisitor } from "./JavaScriptRuntime";
export { type NpmPackage, type PublishInfo } from "./NpmPackage";
export { type PackageId } from "./PackageId";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ import { GeneratedFile } from "../../commons/GeneratedFile";
import { SdkContext } from "../SdkContext";

export interface GeneratedTimeoutSdkError extends GeneratedFile<SdkContext> {
build: (context: SdkContext) => ts.NewExpression;
build: (context: SdkContext, message: string) => ts.NewExpression;
}
12 changes: 10 additions & 2 deletions packages/cli/cli/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,10 @@ function addIrCommand(cli: Argv<GlobalCliOptions>, cliContext: CliContext) {
string: true,
default: new Array<string>(),
description: "Filter the IR for certain audiences"
})
.option("smart-casing", {
boolean: true,
description: "Whether to use smart casing"
}),
async (argv) => {
await generateIrForWorkspaces({
Expand All @@ -486,7 +490,7 @@ function addIrCommand(cli: Argv<GlobalCliOptions>, cliContext: CliContext) {
audiences: argv.audience.length > 0 ? { type: "select", audiences: argv.audience } : { type: "all" },
version: argv.version,
keywords: undefined,
smartCasing: false,
smartCasing: argv.smartCasing ?? false,
readme: undefined
});
}
Expand Down Expand Up @@ -555,6 +559,10 @@ function addDynamicIrCommand(cli: Argv<GlobalCliOptions>, cliContext: CliContext
string: true,
default: new Array<string>(),
description: "Filter the IR for certain audiences"
})
.option("smart-casing", {
boolean: true,
description: "Whether to use smart casing"
}),
async (argv) => {
await generateDynamicIrForWorkspaces({
Expand All @@ -569,7 +577,7 @@ function addDynamicIrCommand(cli: Argv<GlobalCliOptions>, cliContext: CliContext
audiences: { type: "all" },
version: argv.version,
keywords: undefined,
smartCasing: false
smartCasing: argv.smartCasing ?? false
});
}
);
Expand Down
7 changes: 7 additions & 0 deletions packages/cli/cli/versions.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
- changelogEntry:
- summary: |
Add support for the `smart-casing` flags in the IR commands.
type: internal
irVersion: 53
version: 0.45.0-rc53

- changelogEntry:
- summary: |
Fix bug where max length validation for strings were incorrectly plumbed.
Expand Down
4 changes: 3 additions & 1 deletion seed/ts-sdk/alias-extends/src/Client.ts

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

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

2 changes: 1 addition & 1 deletion seed/ts-sdk/alias/src/Client.ts

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

Loading

0 comments on commit 82dd61d

Please sign in to comment.