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: OpenApi Parser multiple success responses, error response descriptions, better examples #1913

Closed
wants to merge 29 commits into from
Closed
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
3c40232
add tag conversion
fern-support Dec 10, 2024
5913f3b
server name and tags, tests needed
RohinBhargava Dec 10, 2024
dcc756b
checkpoint
RohinBhargava Dec 12, 2024
ceac2c1
pnpm lock
RohinBhargava Dec 12, 2024
53274dc
Merge remote-tracking branch 'origin/main' into uploadcare-experiment
RohinBhargava Dec 13, 2024
a79a06a
added example parsers, need to add tests and merge examples in a mean…
RohinBhargava Dec 13, 2024
81daa61
add tests and fix compile errors
RohinBhargava Dec 17, 2024
def2f73
merge from main
RohinBhargava Dec 17, 2024
662ed6e
remove type_: from type alias
RohinBhargava Dec 17, 2024
b95ff56
feat: redoc example parsing (#1906)
RohinBhargava Dec 17, 2024
23d96f0
code compiles, testing
RohinBhargava Dec 18, 2024
cd5b548
update tests
RohinBhargava Dec 18, 2024
8fad42e
many examples working, multiple request responses, error defaults sho…
RohinBhargava Dec 19, 2024
91bff16
empty snippets & removed redundancy
RohinBhargava Dec 19, 2024
0d77cab
remove test file
RohinBhargava Dec 19, 2024
e7cee2c
update snapshot
RohinBhargava Dec 19, 2024
cec5db2
pnpm lock
RohinBhargava Dec 19, 2024
73ba050
merge from main
RohinBhargava Dec 19, 2024
d06d9c5
bump version and fix some tests
RohinBhargava Dec 19, 2024
1c6f33a
update and add tests
RohinBhargava Dec 20, 2024
223a89f
example object tests
RohinBhargava Dec 20, 2024
2c70167
Merge branch 'uploadcare-experiment' into rohin/multiple-success-resp…
RohinBhargava Dec 20, 2024
0551cae
merge from main
RohinBhargava Dec 20, 2024
e730db8
try removing cross product from converter
RohinBhargava Dec 20, 2024
ece2427
return statement
RohinBhargava Dec 20, 2024
767c824
snippet old logic for curl
RohinBhargava Dec 20, 2024
d4635ea
Merge remote-tracking branch 'origin/main' into rohin/multiple-succes…
RohinBhargava Dec 20, 2024
0618a87
merge from main
RohinBhargava Dec 20, 2024
db1f552
merge from rebase
RohinBhargava Dec 20, 2024
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 fern/apis/fdr/definition/api/latest/endpoint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ types:
queryParameters: optional<list<type.ObjectProperty>>
requestHeaders: optional<list<type.ObjectProperty>>
responseHeaders: optional<list<type.ObjectProperty>> # this is not being used currently
request: optional<HttpRequest>
response: optional<HttpResponse>
requests: optional<list<HttpRequest>>
responses: optional<list<HttpResponse>>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to confirm -- this break is okay because we are not persisting this data anywhere? @abvthecity can you confirm

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from what I saw on CLI, and on FE, only V1 DB shape is stored, and V1 write and read are used in APIs, yes

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack, this is ok

errors: optional<list<ErrorResponse>>
examples: optional<list<ExampleEndpointCall>>
snippetTemplates: optional<EndpointSnippetTemplates>
Expand Down
8 changes: 4 additions & 4 deletions packages/fdr-sdk/src/api-definition/__test__/join.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ const endpoint1: Latest.EndpointDefinition = {
],
requestHeaders: undefined,
responseHeaders: undefined,
request: undefined,
response: undefined,
requests: undefined,
responses: undefined,
auth: undefined,
description: undefined,
availability: undefined,
Expand Down Expand Up @@ -83,8 +83,8 @@ const endpoint2: Latest.EndpointDefinition = {
},
],
responseHeaders: undefined,
request: undefined,
response: undefined,
requests: undefined,
responses: undefined,
auth: [Latest.AuthSchemeId("auth")],
description: undefined,
availability: undefined,
Expand Down
8 changes: 4 additions & 4 deletions packages/fdr-sdk/src/api-definition/__test__/prune.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ const endpoint1: Latest.EndpointDefinition = {
],
requestHeaders: undefined,
responseHeaders: undefined,
request: undefined,
response: undefined,
requests: undefined,
responses: undefined,
auth: undefined,
description: undefined,
availability: undefined,
Expand Down Expand Up @@ -83,8 +83,8 @@ const endpoint2: Latest.EndpointDefinition = {
},
],
responseHeaders: undefined,
request: undefined,
response: undefined,
requests: undefined,
responses: undefined,
auth: [Latest.AuthSchemeId("auth")],
description: undefined,
availability: undefined,
Expand Down
148 changes: 76 additions & 72 deletions packages/fdr-sdk/src/api-definition/migrators/v1ToV2.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { isNonNullish } from "@fern-api/ui-core-utils";
import titleCase from "@fern-api/ui-core-utils/titleCase";
import visitDiscriminatedUnion from "@fern-api/ui-core-utils/visitDiscriminatedUnion";
import { mapValues } from "es-toolkit/object";
Expand Down Expand Up @@ -163,8 +164,8 @@ export class ApiDefinitionV1ToLatest {
queryParameters: this.migrateParameters(v1.queryParameters),
requestHeaders: this.migrateParameters(v1.headers),
responseHeaders: undefined,
request: this.migrateHttpRequest(v1.request),
response: this.migrateHttpResponse(v1.response),
requests: [this.migrateHttpRequest(v1.request)].filter(isNonNullish),
responses: [this.migrateHttpResponse(v1.response)].filter(isNonNullish),
errors: this.migrateHttpErrors(v1.errorsV2),
examples: undefined,
snippetTemplates: v1.snippetTemplates,
Expand Down Expand Up @@ -406,69 +407,70 @@ export class ApiDefinitionV1ToLatest {
if (examples.length === 0) {
return undefined;
}
return examples.map((example): V2.ExampleEndpointCall => {
const toRet: V2.ExampleEndpointCall = {
path: example.path,
responseStatusCode: example.responseStatusCode,
name: example.name,
description: example.description,
pathParameters: example.pathParameters,
queryParameters: example.queryParameters,
headers: example.headers,
requestBody: example.requestBodyV3,
responseBody: example.responseBodyV3,
snippets: undefined,
};

if (example.requestBodyV3) {
toRet.requestBody = visitDiscriminatedUnion(
example.requestBodyV3,
)._visit<APIV1Read.ExampleEndpointRequest>({
bytes: (value) => value,
json: (value) => ({
type: "json",
value: sortKeysByShape(value.value, endpoint.request?.body, this.types),
}),
form: (value) => ({
type: "form",
value: mapValues(value.value, (formValue, key): APIV1Read.FormValue => {
if (formValue.type === "json") {
const shape =
endpoint.request?.body.type === "formData"
? endpoint.request.body.fields.find(
(field): field is V2.FormDataField.Property =>
field.key === key && field.type === "property",
)?.valueShape
: undefined;
return {
type: "json",
value: sortKeysByShape(formValue.value, shape, this.types),
};
} else {
return formValue;
}
}),
}),
});
}

if (toRet.responseBody) {
toRet.responseBody.value = sortKeysByShape(
toRet.responseBody.value,
endpoint.response?.body,
this.types,
);
}

toRet.snippets = this.migrateEndpointSnippets(
endpoint,
toRet,
example.codeSamples,
example.codeExamples,
this.flags,
// We take the cross product of requests and responses
return endpoint.responses?.flatMap((response) => {
return (endpoint.requests ?? []).flatMap((request) =>
examples.map((example): V2.ExampleEndpointCall => {
const toRet: V2.ExampleEndpointCall = {
path: example.path,
responseStatusCode: example.responseStatusCode,
name: example.name,
description: example.description,
pathParameters: example.pathParameters,
queryParameters: example.queryParameters,
headers: example.headers,
requestBody: example.requestBodyV3,
responseBody: example.responseBodyV3,
snippets: undefined,
};

if (example.requestBodyV3) {
toRet.requestBody = visitDiscriminatedUnion(
example.requestBodyV3,
)._visit<APIV1Read.ExampleEndpointRequest>({
bytes: (value) => value,
json: (value) => ({
type: "json",
value: sortKeysByShape(value.value, request.body, this.types),
}),
form: (value) => ({
type: "form",
value: mapValues(value.value, (formValue, key): APIV1Read.FormValue => {
if (formValue.type === "json") {
const shape =
request.body.type === "formData"
? request.body.fields.find(
(field): field is V2.FormDataField.Property =>
field.key === key && field.type === "property",
)?.valueShape
: undefined;
return {
type: "json",
value: sortKeysByShape(formValue.value, shape, this.types),
};
} else {
return formValue;
}
}),
}),
});
}

if (toRet.responseBody) {
toRet.responseBody.value = sortKeysByShape(toRet.responseBody.value, response.body, this.types);
}

toRet.snippets = this.migrateEndpointSnippets(
endpoint,
toRet,
example.codeSamples,
example.codeExamples,
this.flags,
);

return toRet;
}),
);

return toRet;
});
};

Expand Down Expand Up @@ -643,14 +645,16 @@ export class ApiDefinitionV1ToLatest {
});

if (!userProvidedLanguages.has(SupportedLanguage.Curl)) {
const code = convertToCurl(toSnippetHttpRequest(endpoint, example, this.auth), flags);
push(SupportedLanguage.Curl, {
language: SupportedLanguage.Curl,
code,
name: undefined,
install: undefined,
generated: true,
description: undefined,
toSnippetHttpRequest(endpoint, example, this.auth).forEach((snippet) => {
const code = convertToCurl(snippet, flags);
push(SupportedLanguage.Curl, {
language: SupportedLanguage.Curl,
code,
name: undefined,
install: undefined,
generated: true,
description: undefined,
});
});
}

Expand Down
Loading
Loading