Skip to content

Commit

Permalink
Merge branch 'main' into rohin/support-nulls-openapi
Browse files Browse the repository at this point in the history
  • Loading branch information
RohinBhargava authored Feb 7, 2025
2 parents b68f9c5 + cf2db62 commit 78b0df5
Show file tree
Hide file tree
Showing 194 changed files with 4,362 additions and 218 deletions.
21 changes: 19 additions & 2 deletions fern.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1727,7 +1727,14 @@
],
"additionalProperties": false
},
"service.TypeReferenceDeclarationWithContentTypeSchema": {
"service.FormDataBodyEncodingStyle": {
"type": "string",
"enum": [
"json",
"exploded"
]
},
"service.HttpInlineFileRequestBodyPropertySchema": {
"type": "object",
"properties": {
"type": {
Expand Down Expand Up @@ -1813,6 +1820,16 @@
}
]
},
"style": {
"oneOf": [
{
"$ref": "#/definitions/service.FormDataBodyEncodingStyle"
},
{
"type": "null"
}
]
},
"content-type": {
"oneOf": [
{
Expand All @@ -1835,7 +1852,7 @@
"type": "string"
},
{
"$ref": "#/definitions/service.TypeReferenceDeclarationWithContentTypeSchema"
"$ref": "#/definitions/service.HttpInlineFileRequestBodyPropertySchema"
}
]
},
Expand Down
12 changes: 10 additions & 2 deletions fern/apis/fern-definition/definition/service.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,20 @@ types:
discriminated: false
union:
- string
- TypeReferenceDeclarationWithContentTypeSchema
- HttpInlineFileRequestBodyPropertySchema

TypeReferenceDeclarationWithContentTypeSchema:
HttpInlineFileRequestBodyPropertySchema:
extends: types.TypeReferenceDeclarationWithName
properties:
style:
type: optional<FormDataBodyEncodingStyle>
docs: Defaults to json encoding
content-type: optional<string>

FormDataBodyEncodingStyle:
enum:
- json
- exploded

HttpQueryParameterSchema:
discriminated: false
Expand Down
3 changes: 3 additions & 0 deletions fern/pages/changelogs/php-sdk/2025-02-07.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 0.5.0
**`(feat):`** Add the `__toString()` magic method to all generated class types.

2 changes: 1 addition & 1 deletion generators/browser-compatible-base/src/ast/Argument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export type Arguments = NamedArgument[] | UnnamedArgument[];

export interface NamedArgument {
name: string;
assignment: AbstractAstNode;
assignment: AbstractAstNode | string;
}

export type UnnamedArgument = AbstractAstNode;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,70 @@
import { FernIr } from "@fern-api/dynamic-ir-sdk";

import { AbstractDynamicSnippetsGeneratorContext } from "./AbstractDynamicSnippetsGeneratorContext";
import { AbstractEndpointSnippetGenerator } from "./AbstractEndpointSnippetGenerator";
import { Result } from "./Result";

export abstract class AbstractDynamicSnippetsGenerator<
Context extends AbstractDynamicSnippetsGeneratorContext,
EndpointSnippetRequest,
EndpointSnippetResponse
EndpointSnippetGenerator extends AbstractEndpointSnippetGenerator<Context>
> {
public constructor(public readonly context: Context) {}

/**
* Generates code for the specified request.
* @param request
*/
public abstract generate(request: EndpointSnippetRequest): Promise<EndpointSnippetResponse>;
protected abstract createSnippetGenerator(context: Context): EndpointSnippetGenerator;

public async generate(
request: FernIr.dynamic.EndpointSnippetRequest
): Promise<FernIr.dynamic.EndpointSnippetResponse> {
const endpoints = this.context.resolveEndpointLocationOrThrow(request.endpoint);
if (endpoints.length === 0) {
throw new Error(`No endpoints found that match "${request.endpoint.method} ${request.endpoint.path}"`);
}
const result = new Result();
for (const endpoint of endpoints) {
const context = this.context.clone() as Context;
const snippetGenerator = this.createSnippetGenerator(context);
try {
const snippet = await snippetGenerator.generateSnippet({ endpoint, request });
if (context.errors.empty()) {
return {
snippet,
errors: undefined
};
}
result.update({ context, snippet });
} catch (error) {
if (result.err == null) {
result.err = error as Error;
}
}
}
return result.getResponseOrThrow({ endpoint: request.endpoint });
}

/**
* Generates code for the specified request.
* @param request
*/
public abstract generateSync(request: EndpointSnippetRequest): EndpointSnippetResponse;
public generateSync(request: FernIr.dynamic.EndpointSnippetRequest): FernIr.dynamic.EndpointSnippetResponse {
const endpoints = this.context.resolveEndpointLocationOrThrow(request.endpoint);
if (endpoints.length === 0) {
throw new Error(`No endpoints found that match "${request.endpoint.method} ${request.endpoint.path}"`);
}
const result = new Result();
for (const endpoint of endpoints) {
const context = this.context.clone() as Context;
const snippetGenerator = this.createSnippetGenerator(context);
try {
const snippet = snippetGenerator.generateSnippetSync({ endpoint, request });
if (context.errors.empty()) {
return {
snippet,
errors: undefined
};
}
result.update({ context, snippet });
} catch (error) {
if (result.err == null) {
result.err = error as Error;
}
}
}
return result.getResponseOrThrow({ endpoint: request.endpoint });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export abstract class AbstractDynamicSnippetsGeneratorContext {
this.httpEndpointReferenceParser = new HttpEndpointReferenceParser();
}

public abstract clone(): AbstractDynamicSnippetsGeneratorContext;

public associateQueryParametersByWireValue({
parameters,
values
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { FernIr } from "@fern-api/dynamic-ir-sdk";

import { AbstractDynamicSnippetsGeneratorContext } from "./AbstractDynamicSnippetsGeneratorContext";

export abstract class AbstractEndpointSnippetGenerator<Context extends AbstractDynamicSnippetsGeneratorContext> {
// eslint-disable-next-line @typescript-eslint/no-empty-function
public constructor({ context }: { context: Context }) {
// eslint-disable-line @typescript-eslint/no-useless-constructor
}

public abstract generateSnippet({
endpoint,
request
}: {
endpoint: FernIr.dynamic.Endpoint;
request: FernIr.dynamic.EndpointSnippetRequest;
}): Promise<string>;

public abstract generateSnippetSync({
endpoint,
request
}: {
endpoint: FernIr.dynamic.Endpoint;
request: FernIr.dynamic.EndpointSnippetRequest;
}): string;
}
2 changes: 1 addition & 1 deletion generators/csharp/codegen/src/ast/ClassInstantiation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export class ClassInstantiation extends AstNode {
this.arguments_.forEach((argument, idx) => {
if (isNamedArgument(argument)) {
writer.write(`${argument.name} = `);
argument.assignment.write(writer);
writer.writeNodeOrString(argument.assignment);
} else {
argument.write(writer);
}
Expand Down
2 changes: 1 addition & 1 deletion generators/go-v2/ast/src/ast/utils/writeArguments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export function writeArguments({ writer, arguments_ }: { writer: Writer; argumen

function writeArgument({ writer, argument }: { writer: Writer; argument: Argument }): void {
if (isNamedArgument(argument)) {
argument.assignment.write(writer);
writer.writeNodeOrString(argument.assignment);
} else {
argument.write(writer);
}
Expand Down
68 changes: 4 additions & 64 deletions generators/go-v2/dynamic-snippets/src/DynamicSnippetsGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import {
AbstractDynamicSnippetsGenerator,
AbstractFormatter,
FernGeneratorExec,
Result
FernGeneratorExec
} from "@fern-api/browser-compatible-base-generator";
import { FernIr } from "@fern-api/dynamic-ir-sdk";

Expand All @@ -11,8 +10,7 @@ import { DynamicSnippetsGeneratorContext } from "./context/DynamicSnippetsGenera

export class DynamicSnippetsGenerator extends AbstractDynamicSnippetsGenerator<
DynamicSnippetsGeneratorContext,
FernIr.dynamic.EndpointSnippetRequest,
FernIr.dynamic.EndpointSnippetResponse
EndpointSnippetGenerator
> {
private formatter: AbstractFormatter | undefined;

Expand All @@ -29,65 +27,7 @@ export class DynamicSnippetsGenerator extends AbstractDynamicSnippetsGenerator<
this.formatter = formatter;
}

public async generate(
request: FernIr.dynamic.EndpointSnippetRequest
): Promise<FernIr.dynamic.EndpointSnippetResponse> {
const endpoints = this.context.resolveEndpointLocationOrThrow(request.endpoint);
if (endpoints.length === 0) {
throw new Error(`No endpoints found that match "${request.endpoint.method} ${request.endpoint.path}"`);
}
const result = new Result();
for (const endpoint of endpoints) {
const context = this.context.clone();
const snippetGenerator = new EndpointSnippetGenerator({
context,
formatter: this.formatter
});
try {
const snippet = await snippetGenerator.generateSnippet({ endpoint, request });
if (context.errors.empty()) {
return {
snippet,
errors: undefined
};
}
result.update({ context, snippet });
} catch (error) {
if (result.err == null) {
result.err = error as Error;
}
}
}
return result.getResponseOrThrow({ endpoint: request.endpoint });
}

public generateSync(request: FernIr.dynamic.EndpointSnippetRequest): FernIr.dynamic.EndpointSnippetResponse {
const endpoints = this.context.resolveEndpointLocationOrThrow(request.endpoint);
if (endpoints.length === 0) {
throw new Error(`No endpoints found that match "${request.endpoint.method} ${request.endpoint.path}"`);
}
const result = new Result();
for (const endpoint of endpoints) {
const context = this.context.clone();
const snippetGenerator = new EndpointSnippetGenerator({
context,
formatter: this.formatter
});
try {
const snippet = snippetGenerator.generateSnippetSync({ endpoint, request });
if (context.errors.empty()) {
return {
snippet,
errors: undefined
};
}
result.update({ context, snippet });
} catch (error) {
if (result.err == null) {
result.err = error as Error;
}
}
}
return result.getResponseOrThrow({ endpoint: request.endpoint });
protected createSnippetGenerator(context: DynamicSnippetsGeneratorContext): EndpointSnippetGenerator {
return new EndpointSnippetGenerator({ context, formatter: this.formatter });
}
}
Loading

0 comments on commit 78b0df5

Please sign in to comment.