Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(go): Add support for file upload dynamic snippets #5252

Merged
merged 3 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions generators/go-v2/ast/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@
"@fern-api/core-utils": "workspace:*",
"@fern-api/fs-utils": "workspace:*",
"@fern-api/generator-commons": "workspace:*",
"@fern-fern/ir-sdk": "^53.19.0",
"@fern-fern/ir-sdk": "^53.21.0",
"zod": "^3.22.3"
},
"devDependencies": {
"@fern-api/fs-utils": "workspace:*",
"@fern-api/generator-commons": "workspace:*",
"@fern-fern/ir-sdk": "^53.19.0",
"@fern-fern/ir-sdk": "^53.21.0",
"@types/jest": "^29.5.12",
"@types/node": "^18.7.18",
"depcheck": "^1.4.6",
Expand Down
16 changes: 16 additions & 0 deletions generators/go-v2/ast/src/ast/TypeInstantiation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type InternalTypeInstantiation =
| Nil
| Nop
| Optional
| Reference
| Slice
| String_
| Struct
Expand Down Expand Up @@ -96,6 +97,11 @@ interface Nop {
type: "nop";
}

interface Reference {
type: "reference";
value: AstNode;
}

interface Slice {
type: "slice";
valueType: Type;
Expand Down Expand Up @@ -167,6 +173,9 @@ export class TypeInstantiation extends AstNode {
case "optional":
this.writeOptional({ writer, type: this.internalType.value });
break;
case "reference":
writer.writeNode(this.internalType.value);
break;
case "slice":
this.writeSlice({ writer, slice: this.internalType });
break;
Expand Down Expand Up @@ -292,6 +301,13 @@ export class TypeInstantiation extends AstNode {
});
}

public static reference(value: AstNode): TypeInstantiation {
return new this({
type: "reference",
value
});
}

public static slice({ valueType, values }: { valueType: Type; values: TypeInstantiation[] }): TypeInstantiation {
return new this({
type: "slice",
Expand Down
2 changes: 1 addition & 1 deletion generators/go-v2/dynamic-snippets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"@fern-api/project-loader": "workspace:*",
"@fern-api/task-context": "workspace:*",
"@fern-api/workspace-loader": "workspace:*",
"@fern-fern/ir-sdk": "^53.19.0",
"@fern-fern/ir-sdk": "^53.21.0",
"@types/jest": "^29.5.12",
"@types/node": "^18.7.18",
"depcheck": "^1.4.6",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { dynamic as DynamicSnippets } from "@fern-fern/ir-sdk/api";
import { AbstractDynamicSnippetsGenerator } from "@fern-api/dynamic-snippets";
import { ErrorReporter, Severity } from "./context/ErrorReporter";
import { Scope } from "./Scope";
import { assertNever } from "@fern-api/core-utils";
import { FilePropertyInfo } from "./context/FilePropertyMapper";

const SNIPPET_PACKAGE_NAME = "example";
const SNIPPET_IMPORT_PATH = "fern";
Expand Down Expand Up @@ -384,29 +386,62 @@ export class DynamicSnippetsGenerator extends AbstractDynamicSnippetsGenerator<D
}
this.context.errors.unscope();

if (!this.context.customConfig?.inlinePathParameters) {
this.context.errors.scope(Scope.RequestBody);
const filePropertyInfo = this.getFilePropertyInfo({ request, snippet });
this.context.errors.unscope();

if (!this.context.includePathParametersInWrappedRequest({ request })) {
args.push(...pathParameterFields.map((field) => field.value));
}
if (this.context.doesInlinedRequestExist({ request })) {

if (!this.context.customConfig?.inlineFileProperties) {
args.push(...filePropertyInfo.fileFields.map((field) => field.value));
}

if (this.context.needsRequestParameter({ request })) {
args.push(
this.getInlinedRequestArg({
request,
snippet,
pathParameterFields: this.context.customConfig?.inlinePathParameters ? pathParameterFields : []
pathParameterFields: this.context.includePathParametersInWrappedRequest({ request })
? pathParameterFields
: [],
filePropertyInfo
})
);
}
return args;
}

private getFilePropertyInfo({
request,
snippet
}: {
request: DynamicSnippets.InlinedRequest;
snippet: DynamicSnippets.EndpointSnippetRequest;
}): FilePropertyInfo {
if (request.body == null || !this.context.isFileUploadRequestBody(request.body)) {
return {
fileFields: [],
bodyPropertyFields: []
};
}
return this.context.filePropertyMapper.getFilePropertyInfo({
body: request.body,
value: snippet.requestBody
});
}

private getInlinedRequestArg({
request,
snippet,
pathParameterFields
pathParameterFields,
filePropertyInfo
}: {
request: DynamicSnippets.InlinedRequest;
snippet: DynamicSnippets.EndpointSnippetRequest;
pathParameterFields: go.StructField[];
filePropertyInfo: FilePropertyInfo;
}): go.TypeInstantiation {
this.context.errors.scope(Scope.QueryParameters);
const queryParameters = this.context.associateQueryParametersByWireValue({
Expand All @@ -433,7 +468,11 @@ export class DynamicSnippetsGenerator extends AbstractDynamicSnippetsGenerator<D
this.context.errors.scope(Scope.RequestBody);
const requestBodyFields =
request.body != null
? this.getInlinedRequestBodyStructFields({ body: request.body, value: snippet.requestBody })
? this.getInlinedRequestBodyStructFields({
body: request.body,
value: snippet.requestBody,
filePropertyInfo
})
: [];
this.context.errors.unscope();

Expand All @@ -448,19 +487,32 @@ export class DynamicSnippetsGenerator extends AbstractDynamicSnippetsGenerator<D

private getInlinedRequestBodyStructFields({
body,
value
value,
filePropertyInfo
}: {
body: DynamicSnippets.InlinedRequestBody;
value: unknown;
filePropertyInfo: FilePropertyInfo;
}): go.StructField[] {
switch (body.type) {
case "properties":
return this.getInlinedRequestBodyPropertyStructFields({ parameters: body.value, value });
case "referenced":
return [this.getReferencedRequestBodyPropertyStructField({ body, value })];
case "fileUpload":
throw new Error("TODO: Implement me!");
return this.getFileUploadRequestBodyStructFields({ filePropertyInfo });
}
}

private getFileUploadRequestBodyStructFields({
filePropertyInfo
}: {
filePropertyInfo: FilePropertyInfo;
}): go.StructField[] {
if (this.context.customConfig?.inlineFileProperties) {
return [...filePropertyInfo.fileFields, ...filePropertyInfo.bodyPropertyFields];
}
return filePropertyInfo.bodyPropertyFields;
}

private getReferencedRequestBodyPropertyStructField({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`file-upload (success) > 'POST /' 1`] = `
"package example

import (
context "context"
acme "github.com/acme/acme-go"
client "github.com/acme/acme-go/client"
io "io"
strings "strings"
)

func do() {
client := client.NewClient()
client.Service.Post(
context.TODO(),
&acme.MyRequest{
File: strings.NewReader(
"Hello, world!",
),
FileList: []io.Reader{
strings.NewReader(
"First",
),
strings.NewReader(
"Second",
),
},
},
)
}
"
`;

exports[`file-upload (success) > 'POST /just-file (simple)' 1`] = `
"package example

import (
context "context"
acme "github.com/acme/acme-go"
client "github.com/acme/acme-go/client"
strings "strings"
)

func do() {
client := client.NewClient()
client.Service.JustFile(
context.TODO(),
&acme.JustFileRequet{
File: strings.NewReader(
"Hello, world!",
),
},
)
}
"
`;

exports[`file-upload (success) > 'POST /just-file-with-query-params (si…' 1`] = `
"package example

import (
context "context"
acme "github.com/acme/acme-go"
client "github.com/acme/acme-go/client"
strings "strings"
)

func do() {
client := client.NewClient()
client.Service.JustFileWithQueryParams(
context.TODO(),
&acme.JustFileWithQueryParamsRequet{
Integer: 42,
MaybeString: acme.String(
"exists",
),
File: strings.NewReader(
"Hello, world!",
),
},
)
}
"
`;
Original file line number Diff line number Diff line change
Expand Up @@ -4795,7 +4795,6 @@ package example

import (
context "context"
acme "github.com/acme/acme-go"
client "github.com/acme/acme-go/client"
)

Expand All @@ -4804,7 +4803,6 @@ func do() {
client.User.GetUser(
context.TODO(),
"userId",
&acme.GetUsersRequest{},
)
}

Expand All @@ -4814,7 +4812,6 @@ package example

import (
context "context"
acme "github.com/acme/acme-go"
client "github.com/acme/acme-go/client"
)

Expand All @@ -4824,7 +4821,6 @@ func do() {
context.TODO(),
"organizationId",
"userId",
&acme.GetOrganizationUserRequest{},
)
}

Expand Down Expand Up @@ -4857,14 +4853,20 @@ package example

import (
context "context"
acme "github.com/acme/acme-go"
client "github.com/acme/acme-go/client"
)

func do() {
client := client.NewClient()
client.User.GetOrganization(
client.User.SearchOrganizations(
context.TODO(),
"organizationId",
&acme.SearchOrganizationsRequest{
Limit: acme.Int(
1,
),
},
)
}
"
Expand Down
Loading
Loading