Skip to content
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
8 changes: 2 additions & 6 deletions src/api/writer-generator/python.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,8 @@ export class Python extends Writer<PythonGeneratorOptions> {

private generateRootPackages(groups: TypeSchemaPackageGroups): void {
this.generateRootInitFile(groups);
if (this.forFhirpyClient)
this.copyAssets(
resolvePyAssets("fhirpy_base_model.py"),
Path.resolve(this.opts.outputDir, "fhirpy_base_model.py"),
);
this.copyAssets(resolvePyAssets("requirements.txt"), Path.resolve(this.opts.outputDir, "requirements.txt"));
if (this.forFhirpyClient) this.copyAssets(resolvePyAssets("fhirpy_base_model.py"), "fhirpy_base_model.py");
this.copyAssets(resolvePyAssets("requirements.txt"), "requirements.txt");
}

private generateSDKPackages(groups: TypeSchemaPackageGroups): void {
Expand Down
1 change: 1 addition & 0 deletions src/api/writer-generator/writer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export abstract class FileSystemWriter<T extends FileSystemWriterOptions = FileS
}

copyAssets(source: string, destination: string) {
destination = Path.normalize(`${this.currentDir ?? this.opts.outputDir}/${destination}`);
const content = fs.readFileSync(source, "utf8");
this.writtenFilesBuffer[destination] = {
relPath: destination,
Expand Down
2 changes: 1 addition & 1 deletion src/typeschema/ir/logic-promotion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export const promoteLogical = (tsIndex: TypeSchemaIndex, promotes: LogicalPromot
return {
...n,
base: replace(n.base),
nested: replaceInFields(n.fields),
fields: replaceInFields(n.fields),
};
});
}
Expand Down
8 changes: 7 additions & 1 deletion test/api/write-generator/__snapshots__/python.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,10 @@ class Patient(DomainResource):
"
`;

exports[`Python Writer Generator static files 1`] = `undefined`;
exports[`Python Writer Generator static files 1`] = `
"requests>=2.32.0,<3.0.0
pytest>=8.3.0,<9.0.0
pydantic>=2.11.0,<3.0.0
mypy>=1.9.0,<2.0.0
types-requests>=2.32.0,<3.0.0"
`;
361 changes: 361 additions & 0 deletions test/api/write-generator/multi-package/__snapshots__/cda.test.ts.snap

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,317 @@
// Bun Snapshot v1, https://bun.sh/docs/test/snapshots

exports[`Local Package Folder - Multi-Package Generation TypeScript Generation should generate ExampleNotebook type in custom package folder 1`] = `
"// WARNING: This file is autogenerated by @atomic-ehr/codegen.
// GitHub: https://github.com/atomic-ehr/codegen
// Any manual changes made to this file may be overwritten.

import type { Coding } from "../hl7-fhir-r4-core/Coding";
import type { DomainResource } from "../hl7-fhir-r4-core/DomainResource";
import type { Identifier } from "../hl7-fhir-r4-core/Identifier";
import type { Reference } from "../hl7-fhir-r4-core/Reference";

import type { Element } from "../hl7-fhir-r4-core/Element";
export type { Coding } from "../hl7-fhir-r4-core/Coding";
export type { Identifier } from "../hl7-fhir-r4-core/Identifier";
export type { Reference } from "../hl7-fhir-r4-core/Reference";

// CanonicalURL: http://example.org/fhir/StructureDefinition/ExampleNotebook (pkg: example.folder.structures#0.0.1)
export interface ExampleNotebook extends DomainResource {
author: Reference<"Patient" | "Practitioner">;
content: string;
_content?: Element;
identifier: Identifier;
tag?: Coding[];
title: string;
_title?: Element;
}
"
`;

exports[`Local Package Folder - Multi-Package Generation Python Generation should generate ExampleNotebook type (promoted logical) 1`] = `
"# WARNING: This file is autogenerated by @atomic-ehr/codegen.
# GitHub: https://github.com/atomic-ehr/codegen
# Any manual changes made to this file may be overwritten.

from __future__ import annotations
from pydantic import BaseModel, ConfigDict, Field, PositiveInt
from typing import List as PyList, Literal

from fhir_types.hl7_fhir_r4_core.base import Coding, Identifier, Reference
from fhir_types.hl7_fhir_r4_core.domain_resource import DomainResource
from fhir_types.hl7_fhir_r4_core.resource_families import DomainResourceFamily


class ExampleNotebook(DomainResource):
model_config = ConfigDict(validate_by_name=True, serialize_by_alias=True, extra="forbid")
resource_type: str = Field(
default='ExampleNotebook',
alias='resourceType',
serialization_alias='resourceType',
frozen=True,
pattern='ExampleNotebook'
)
author: Reference = Field(alias="author", serialization_alias="author")
content: str = Field(alias="content", serialization_alias="content")
identifier: Identifier = Field(alias="identifier", serialization_alias="identifier")
tag: PyList[Coding] | None = Field(None, alias="tag", serialization_alias="tag")
title: str = Field(alias="title", serialization_alias="title")

def to_json(self, indent: int | None = None) -> str:
return self.model_dump_json(exclude_unset=True, exclude_none=True, indent=indent)

@classmethod
def from_json(cls, json: str) -> ExampleNotebook:
return cls.model_validate_json(json)

"
`;

exports[`Local Package Folder - Multi-Package Generation Python Generation should generate base types for dependencies 1`] = `
"# WARNING: This file is autogenerated by @atomic-ehr/codegen.
# GitHub: https://github.com/atomic-ehr/codegen
# Any manual changes made to this file may be overwritten.

from __future__ import annotations
from pydantic import BaseModel, ConfigDict, Field, PositiveInt
from typing import List as PyList, Literal

from fhir_types.hl7_fhir_r4_core.base import Extension, Narrative
from fhir_types.hl7_fhir_r4_core.resource import Resource
from fhir_types.hl7_fhir_r4_core.resource_families import ResourceFamily


class DomainResource(Resource):
model_config = ConfigDict(validate_by_name=True, serialize_by_alias=True, extra="forbid")
resource_type: str = Field(
default='DomainResource',
alias='resourceType',
serialization_alias='resourceType',
frozen=True,
pattern='DomainResource'
)
contained: PyList[ResourceFamily] | None = Field(None, alias="contained", serialization_alias="contained")
extension: PyList[Extension] | None = Field(None, alias="extension", serialization_alias="extension")
modifier_extension: PyList[Extension] | None = Field(None, alias="modifierExtension", serialization_alias="modifierExtension")
text: Narrative | None = Field(None, alias="text", serialization_alias="text")

def to_json(self, indent: int | None = None) -> str:
return self.model_dump_json(exclude_unset=True, exclude_none=True, indent=indent)

@classmethod
def from_json(cls, json: str) -> DomainResource:
return cls.model_validate_json(json)

"
`;

exports[`Local Package Folder - Multi-Package Generation Python Generation should generate Patient resource 1`] = `
"# WARNING: This file is autogenerated by @atomic-ehr/codegen.
# GitHub: https://github.com/atomic-ehr/codegen
# Any manual changes made to this file may be overwritten.

from __future__ import annotations
from pydantic import BaseModel, ConfigDict, Field, PositiveInt
from typing import List as PyList, Literal

from fhir_types.hl7_fhir_r4_core.base import (\\
Address, Attachment, BackboneElement, CodeableConcept, ContactPoint, HumanName, Identifier, Period, Reference
)
from fhir_types.hl7_fhir_r4_core.domain_resource import DomainResource
from fhir_types.hl7_fhir_r4_core.resource_families import DomainResourceFamily


class PatientCommunication(BackboneElement):
model_config = ConfigDict(validate_by_name=True, serialize_by_alias=True, extra="forbid")
language: CodeableConcept = Field(alias="language", serialization_alias="language")
preferred: bool | None = Field(None, alias="preferred", serialization_alias="preferred")

class PatientContact(BackboneElement):
model_config = ConfigDict(validate_by_name=True, serialize_by_alias=True, extra="forbid")
address: Address | None = Field(None, alias="address", serialization_alias="address")
gender: Literal["male", "female", "other", "unknown"] | None = Field(None, alias="gender", serialization_alias="gender")
name: HumanName | None = Field(None, alias="name", serialization_alias="name")
organization: Reference | None = Field(None, alias="organization", serialization_alias="organization")
period: Period | None = Field(None, alias="period", serialization_alias="period")
relationship: PyList[CodeableConcept] | None = Field(None, alias="relationship", serialization_alias="relationship")
telecom: PyList[ContactPoint] | None = Field(None, alias="telecom", serialization_alias="telecom")

class PatientLink(BackboneElement):
model_config = ConfigDict(validate_by_name=True, serialize_by_alias=True, extra="forbid")
other: Reference = Field(alias="other", serialization_alias="other")
type: Literal["replaced-by", "replaces", "refer", "seealso"] = Field(alias="type", serialization_alias="type")


class Patient(DomainResource):
model_config = ConfigDict(validate_by_name=True, serialize_by_alias=True, extra="forbid")
resource_type: str = Field(
default='Patient',
alias='resourceType',
serialization_alias='resourceType',
frozen=True,
pattern='Patient'
)
active: bool | None = Field(None, alias="active", serialization_alias="active")
address: PyList[Address] | None = Field(None, alias="address", serialization_alias="address")
birth_date: str | None = Field(None, alias="birthDate", serialization_alias="birthDate")
communication: PyList[PatientCommunication] | None = Field(None, alias="communication", serialization_alias="communication")
contact: PyList[PatientContact] | None = Field(None, alias="contact", serialization_alias="contact")
deceased_boolean: bool | None = Field(None, alias="deceasedBoolean", serialization_alias="deceasedBoolean")
deceased_date_time: str | None = Field(None, alias="deceasedDateTime", serialization_alias="deceasedDateTime")
gender: Literal["male", "female", "other", "unknown"] | None = Field(None, alias="gender", serialization_alias="gender")
general_practitioner: PyList[Reference] | None = Field(None, alias="generalPractitioner", serialization_alias="generalPractitioner")
identifier: PyList[Identifier] | None = Field(None, alias="identifier", serialization_alias="identifier")
link: PyList[PatientLink] | None = Field(None, alias="link", serialization_alias="link")
managing_organization: Reference | None = Field(None, alias="managingOrganization", serialization_alias="managingOrganization")
marital_status: CodeableConcept | None = Field(None, alias="maritalStatus", serialization_alias="maritalStatus")
multiple_birth_boolean: bool | None = Field(None, alias="multipleBirthBoolean", serialization_alias="multipleBirthBoolean")
multiple_birth_integer: int | None = Field(None, alias="multipleBirthInteger", serialization_alias="multipleBirthInteger")
name: PyList[HumanName] | None = Field(None, alias="name", serialization_alias="name")
photo: PyList[Attachment] | None = Field(None, alias="photo", serialization_alias="photo")
telecom: PyList[ContactPoint] | None = Field(None, alias="telecom", serialization_alias="telecom")

def to_json(self, indent: int | None = None) -> str:
return self.model_dump_json(exclude_unset=True, exclude_none=True, indent=indent)

@classmethod
def from_json(cls, json: str) -> Patient:
return cls.model_validate_json(json)

"
`;

exports[`Local Package Folder - Multi-Package Generation C# Generation should generate ExampleNotebook type (promoted logical) 1`] = `
"// WARNING: This file is autogenerated by @atomic-ehr/codegen.
// GitHub: https://github.com/atomic-ehr/codegen
// Any manual changes made to this file may be overwritten.


namespace Fhir.Types.ExampleFolderStructures;

public class ExampleNotebook : DomainResource {
public required ResourceReference Author { get; set; }
public required string Content { get; set; }
public required Identifier Identifier { get; set; }
public Coding[]? Tag { get; set; }
public required string Title { get; set; }

public override string ToString() =>
JsonSerializer.Serialize(this, Helper.JsonSerializerOptions);

}

"
`;

exports[`Local Package Folder - Multi-Package Generation C# Generation should generate DomainResource base class 1`] = `
"// WARNING: This file is autogenerated by @atomic-ehr/codegen.
// GitHub: https://github.com/atomic-ehr/codegen
// Any manual changes made to this file may be overwritten.


namespace Fhir.Types.Hl7FhirR4Core;

public class DomainResource : Resource {
public Resource[]? Contained { get; set; }
public Extension[]? Extension { get; set; }
public Extension[]? ModifierExtension { get; set; }
public Narrative? Text { get; set; }

public override string ToString() =>
JsonSerializer.Serialize(this, Helper.JsonSerializerOptions);

}

"
`;

exports[`Local Package Folder - Multi-Package Generation C# Generation should generate Resource base class 1`] = `
"// WARNING: This file is autogenerated by @atomic-ehr/codegen.
// GitHub: https://github.com/atomic-ehr/codegen
// Any manual changes made to this file may be overwritten.


namespace Fhir.Types.Hl7FhirR4Core;

public class Resource {
public string? Id { get; set; }
public string? ImplicitRules { get; set; }
public string? Language { get; set; }
public Meta? Meta { get; set; }

public override string ToString() =>
JsonSerializer.Serialize(this, Helper.JsonSerializerOptions);

}

"
`;

exports[`Local Package Folder - Multi-Package Generation C# Generation should generate Patient resource 1`] = `
"// WARNING: This file is autogenerated by @atomic-ehr/codegen.
// GitHub: https://github.com/atomic-ehr/codegen
// Any manual changes made to this file may be overwritten.


namespace Fhir.Types.Hl7FhirR4Core;

public class Patient : DomainResource {
public bool? Active { get; set; }
public Address[]? Address { get; set; }
public string? BirthDate { get; set; }
public PatientCommunication[]? Communication { get; set; }
public PatientContact[]? Contact { get; set; }
public bool? DeceasedBoolean { get; set; }
public string? DeceasedDateTime { get; set; }
public AdministrativeGenderEnum? Gender { get; set; }
public ResourceReference[]? GeneralPractitioner { get; set; }
public Identifier[]? Identifier { get; set; }
public PatientLink[]? Link { get; set; }
public ResourceReference? ManagingOrganization { get; set; }
public CodeableConcept? MaritalStatus { get; set; }
public bool? MultipleBirthBoolean { get; set; }
public int? MultipleBirthInteger { get; set; }
public HumanName[]? Name { get; set; }
public Attachment[]? Photo { get; set; }
public ContactPoint[]? Telecom { get; set; }

public class PatientCommunication : BackboneElement {
public required CodeableConcept Language { get; set; }
public bool? Preferred { get; set; }

public override string ToString() =>
JsonSerializer.Serialize(this, Helper.JsonSerializerOptions);

}

public class PatientContact : BackboneElement {
public Address? Address { get; set; }
public AdministrativeGenderEnum? Gender { get; set; }
public HumanName? Name { get; set; }
public ResourceReference? Organization { get; set; }
public Period? Period { get; set; }
public CodeableConcept[]? Relationship { get; set; }
public ContactPoint[]? Telecom { get; set; }

public override string ToString() =>
JsonSerializer.Serialize(this, Helper.JsonSerializerOptions);

}

public class PatientLink : BackboneElement {
public required ResourceReference Other { get; set; }
public required LinkTypeEnum Type { get; set; }

public override string ToString() =>
JsonSerializer.Serialize(this, Helper.JsonSerializerOptions);

}


public override string ToString() =>
JsonSerializer.Serialize(this, Helper.JsonSerializerOptions);

}

"
`;
Loading