Skip to content

Commit

Permalink
(feat, csharp): generate Environments.cs and populate default `Base…
Browse files Browse the repository at this point in the history
…URL` (#3677)
  • Loading branch information
dsinghvi committed May 22, 2024
1 parent 6483e33 commit ae268f9
Show file tree
Hide file tree
Showing 115 changed files with 280 additions and 118 deletions.
2 changes: 1 addition & 1 deletion generators/csharp/codegen/src/asIs/RawClient.Template.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public class ApiResponse

private string BuildUrl(string path, Dictionary<string, object> query)
{
var url = $"{_clientOptions.BaseUrl}/{path}";
var url = $"{_clientOptions.BaseUrl}{path}";
if (query.Count > 0)
{
url += "?";
Expand Down
20 changes: 19 additions & 1 deletion generators/csharp/codegen/src/ast/Field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export declare namespace Field {
init?: boolean;
/* The access level of the method */
access: Access;
/* Whether the field is static */
static_?: boolean;
/* Field annotations */
annotations?: Annotation[];
/* The initializer for the field */
Expand All @@ -39,8 +41,20 @@ export class Field extends AstNode {
private initializer: CodeBlock | undefined;
private summary: string | undefined;
private jsonPropertyName: string | undefined;
private static_: boolean | undefined;

constructor({ name, type, get, init, access, annotations, initializer, summary, jsonPropertyName }: Field.Args) {
constructor({
name,
type,
get,
init,
access,
annotations,
initializer,
summary,
jsonPropertyName,
static_
}: Field.Args) {
super();
this.name = name;
this.type = type;
Expand All @@ -51,6 +65,7 @@ export class Field extends AstNode {
this.initializer = initializer;
this.summary = summary;
this.jsonPropertyName = jsonPropertyName;
this.static_ = static_;

if (this.jsonPropertyName != null) {
this.annotations = [
Expand Down Expand Up @@ -84,6 +99,9 @@ export class Field extends AstNode {
}

writer.write(`${this.access} `);
if (this.static_) {
writer.write("static ");
}
writer.writeNode(this.type);
writer.write(` ${this.name}`);

Expand Down
3 changes: 2 additions & 1 deletion generators/csharp/codegen/src/csharp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,12 @@ export const Types = Type;
export {
Annotation,
Class,
ClassReference,
ClassInstantiation,
ClassReference,
CodeBlock,
Dictionary,
Enum,
Field,
Method,
MethodInvocation,
Parameter,
Expand Down
20 changes: 18 additions & 2 deletions generators/csharp/sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,26 @@ 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.0.12 - 2024-05-22]

- Improvement: The C# generator now generates an `Environments.cs` file which contains
URLs for the different environments. If a default environment is present, then
the `BaseURL` in `ClientOptions.cs` will be initialized to this value.

```csharp
class Environments {

public static string PRODUCTION = "https://api.production.com";

public static string STAGING = "https://api.staging.com";

}
```

## [0.0.11 - 2024-05-20]

- Fix: The C# generator now generates a proper `.csproj` file with version, GitHub url, and
a reference to the SDK README.
- Fix: The C# generator now generates a proper `.csproj` file with version, GitHub url, and
a reference to the SDK README.

## [0.0.10 - 2024-05-15]

Expand Down
2 changes: 1 addition & 1 deletion generators/csharp/sdk/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.11
0.0.12
9 changes: 9 additions & 0 deletions generators/csharp/sdk/src/SdkGeneratorCli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { GeneratorNotificationService } from "@fern-api/generator-commons";
import { FernGeneratorExec } from "@fern-fern/generator-exec-sdk";
import { IntermediateRepresentation } from "@fern-fern/ir-sdk/api";
import { ClientOptionsGenerator } from "./client-options/ClientOptionsGenerator";
import { EnvironmentGenerator } from "./environment/EnvironmentGenerator";
import { RootClientGenerator } from "./root-client/RootClientGenerator";
import { SdkCustomConfigSchema } from "./SdkCustomConfig";
import { SdkGeneratorContext } from "./SdkGeneratorContext";
Expand Down Expand Up @@ -79,6 +80,14 @@ export class SdkGeneratorCLI extends AbstractCsharpGeneratorCli<SdkCustomConfigS
const rootClient = new RootClientGenerator(context);
context.project.addSourceFiles(rootClient.generate());

if (context.ir.environments?.environments.type === "singleBaseUrl") {
const environments = new EnvironmentGenerator({
context,
singleUrlEnvironments: context.ir.environments?.environments
});
context.project.addSourceFiles(environments.generate());
}

const testGenerator = new TestFileGenerator(context);
const test = testGenerator.generate();
context.project.addTestFiles(test);
Expand Down
7 changes: 7 additions & 0 deletions generators/csharp/sdk/src/SdkGeneratorContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,13 @@ export class SdkGeneratorContext extends AbstractCsharpGeneratorContext<SdkCusto
});
}

public getEnvironmentsClassReference(): csharp.ClassReference {
return csharp.classReference({
name: "Environments",
namespace: this.getCoreNamespace()
});
}

public getClientOptionsClassReference(): csharp.ClassReference {
return csharp.classReference({
name: CLIENT_OPTIONS_CLASS_NAME,
Expand Down
44 changes: 34 additions & 10 deletions generators/csharp/sdk/src/client-options/ClientOptionsGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
import { csharp, CSharpFile, FileGenerator } from "@fern-api/csharp-codegen";
import { join, RelativeFilePath } from "@fern-api/fs-utils";
import { SingleBaseUrlEnvironment } from "@fern-fern/ir-sdk/api";
import { SdkCustomConfigSchema } from "../SdkCustomConfig";
import { SdkGeneratorContext } from "../SdkGeneratorContext";

export const BASE_URL_FIELD = csharp.field({
access: "public",
name: "BaseUrl",
get: true,
init: true,
type: csharp.Type.optional(csharp.Type.string()),
summary: "The Base URL for the API."
});

export const HTTP_CLIENT_FIELD = csharp.field({
access: "public",
name: "HttpClient",
Expand Down Expand Up @@ -56,7 +48,7 @@ export class ClientOptionsGenerator extends FileGenerator<CSharpFile, SdkCustomC
partial: true,
access: "public"
});
class_.addField(BASE_URL_FIELD);
class_.addField(this.getBaseUrlField());
class_.addField(HTTP_CLIENT_FIELD);
class_.addField(MAX_RETRIES_FIELD);
class_.addField(TIMEOUT_IN_SECONDS);
Expand All @@ -72,4 +64,36 @@ export class ClientOptionsGenerator extends FileGenerator<CSharpFile, SdkCustomC
RelativeFilePath.of(`${CLIENT_OPTIONS_CLASS_NAME}.cs`)
);
}

private getBaseUrlField(): csharp.Field {
let defaultEnvironment: SingleBaseUrlEnvironment | undefined = undefined;
if (
this.context.ir.environments?.defaultEnvironment != null &&
this.context.ir.environments?.environments.type === "singleBaseUrl"
) {
const singleBaseUrlDefault = this.context.ir.environments.environments.environments.filter(
(singleBaseUrl) => {
return singleBaseUrl.id === this.context.ir.environments?.defaultEnvironment;
}
);
if (singleBaseUrlDefault[0] != null) {
defaultEnvironment = singleBaseUrlDefault[0];
}
}
return csharp.field({
access: "public",
name: "BaseUrl",
get: true,
init: true,
type: csharp.Type.string(),
summary: "The Base URL for the API.",
initializer:
defaultEnvironment != null
? csharp.codeblock((writer) => {
writer.writeNode(this.context.getEnvironmentsClassReference());
writer.write(`.${defaultEnvironment?.name.screamingSnakeCase.safeName}`);
})
: undefined
});
}
}
53 changes: 53 additions & 0 deletions generators/csharp/sdk/src/environment/EnvironmentGenerator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { csharp, CSharpFile, FileGenerator } from "@fern-api/csharp-codegen";
import { join, RelativeFilePath } from "@fern-api/fs-utils";
import { SingleBaseUrlEnvironments } from "@fern-fern/ir-sdk/api";
import { SdkCustomConfigSchema } from "../SdkCustomConfig";
import { SdkGeneratorContext } from "../SdkGeneratorContext";

export declare namespace EnvironmentGenerator {
interface Args {
context: SdkGeneratorContext;
singleUrlEnvironments: SingleBaseUrlEnvironments;
}
}

export class EnvironmentGenerator extends FileGenerator<CSharpFile, SdkCustomConfigSchema, SdkGeneratorContext> {
private singleUrlEnvironments: SingleBaseUrlEnvironments;

constructor({ context, singleUrlEnvironments }: EnvironmentGenerator.Args) {
super(context);
this.singleUrlEnvironments = singleUrlEnvironments;
}

public doGenerate(): CSharpFile {
const class_ = csharp.class_({
...this.context.getEnvironmentsClassReference(),
partial: false,
access: "public"
});

for (const environment of this.singleUrlEnvironments.environments) {
class_.addField(
csharp.field({
access: "public",
name: environment.name.screamingSnakeCase.safeName,
static_: true,
type: csharp.Type.string(),
initializer: csharp.codeblock(`"${environment.url}"`)
})
);
}

return new CSharpFile({
clazz: class_,
directory: RelativeFilePath.of(this.context.getCoreDirectory())
});
}

protected getFilepath(): RelativeFilePath {
return join(
this.context.project.filepaths.getCoreFilesDirectory(),
RelativeFilePath.of(`${this.context.getEnvironmentsClassReference().name}.cs`)
);
}
}
2 changes: 1 addition & 1 deletion seed/csharp-sdk/alias/src/SeedAlias/Core/ClientOptions.cs

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

2 changes: 1 addition & 1 deletion seed/csharp-sdk/alias/src/SeedAlias/Core/RawClient.cs

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.

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.

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.

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.

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.

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.

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

2 changes: 1 addition & 1 deletion seed/csharp-sdk/bytes/src/SeedBytes/Core/ClientOptions.cs

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

Loading

0 comments on commit ae268f9

Please sign in to comment.