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

improvement: the template resolver now resolves unions #1221

Merged
merged 11 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from 9 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
30 changes: 26 additions & 4 deletions fern/apis/fdr/definition/templates.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
imports:
type: ./api/v1/read/type.yml
commons: commons.yml
snippets: snippets.yml

Expand Down Expand Up @@ -78,6 +79,24 @@ types:
# Internal Snippet structure
TemplateSentinel: literal<"$FERN_INPUT">

UnionTemplateMember:
properties:
type: type.TypeReference
template: Template

UnionTemplateV2:
properties:
imports: optional<list<string>>
isOptional:
type: boolean
docs: |
We might not need this, but the idea here is to be able to omit if it's optional and undefined,
or default if omitted and required.

templateString: string
members: list<UnionTemplateMember>
templateInput: optional<PayloadInput>

UnionTemplate:
properties:
imports: optional<list<string>>
Expand All @@ -92,6 +111,7 @@ types:
type: map<string, Template>
docs: A map of the union member's typeID to the template.
templateInput: optional<PayloadInput>

DiscriminatedUnionTemplate:
properties:
imports: optional<list<string>>
Expand Down Expand Up @@ -175,6 +195,7 @@ types:
enum: EnumTemplate
discriminatedUnion: DiscriminatedUnionTemplate
union: UnionTemplate
union_v2: UnionTemplateV2
dict: DictTemplate
iterable: IterableTemplate

Expand Down Expand Up @@ -206,12 +227,12 @@ types:
clientInstantiation: ClientInstantiation
functionInvocation: Template

ClientInstantiation:
ClientInstantiation:
discriminated: false
union:
union:
- string
- Template
- Template

VersionedSnippetTemplate:
audiences:
- templateResolver
Expand All @@ -237,6 +258,7 @@ types:
properties:
sdk: snippets.SDK
endpointId: commons.EndpointIdentifier
apiDefinitionId: optional<commons.ApiDefinitionId>
snippetTemplate:
type: VersionedSnippetTemplate
docs: The default snippet template to use
Expand Down
2 changes: 1 addition & 1 deletion packages/fdr-sdk/src/client/generated/.fernignore

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.

3 changes: 2 additions & 1 deletion packages/template-resolver/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"test": "vitest --run --passWithNoTests"
},
"dependencies": {
"prettier": "^3.3.2"
"prettier": "^3.3.2",
"@fern-api/fdr-sdk": "workspace:*"
},
"devDependencies": {
"@fern-platform/configs": "workspace:*",
Expand Down
48 changes: 48 additions & 0 deletions packages/template-resolver/src/ResolutionUtilities.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { APIV1Read } from "@fern-api/fdr-sdk";

export class ObjectFlattener {
private flattenedObjects: Map<APIV1Read.TypeId, APIV1Read.ObjectProperty[]> = new Map<
APIV1Read.TypeId,
APIV1Read.ObjectProperty[]
>();

constructor(private readonly apiDefinition: APIV1Read.ApiDefinition) {}

public getFlattenedObjectPropertiesFromObjectType(objectType: APIV1Read.ObjectType): APIV1Read.ObjectProperty[] {
const flattenedProperties: APIV1Read.ObjectProperty[] = [];
flattenedProperties.push(...objectType.properties);
objectType.extends.forEach((ext) => {
flattenedProperties.push(...this.getFlattenedObjectProperties(ext));
});

return flattenedProperties;
}

public getFlattenedObjectProperties(typeId: APIV1Read.TypeId): APIV1Read.ObjectProperty[] {
if (this.flattenedObjects.has(typeId)) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return this.flattenedObjects.get(typeId)!;
}

const maybeType = this.apiDefinition.types[typeId];
if (maybeType == null) {
return [];
}

const flattenedProperties: APIV1Read.ObjectProperty[] = [];
switch (maybeType.shape.type) {
case "object":
flattenedProperties.push(...maybeType.shape.properties);
maybeType.shape.extends.forEach((ext) => {
flattenedProperties.push(...this.getFlattenedObjectProperties(ext));
});
break;
default:
// This mirrors how we expand the properties in Python, we assume the extended type is an object
return [];
}

this.flattenedObjects.set(typeId, flattenedProperties);
return flattenedProperties;
}
}
Loading
Loading