Skip to content
Closed
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
2 changes: 1 addition & 1 deletion atomic-codegen.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default defineConfig({
typescript: {
includeDocuments: true,
namingConvention: "PascalCase",
includeProfiles: false,
includeProfiles: true,
includeExtensions: false,
generateIndex: true,
strictMode: true,
Expand Down
1 change: 1 addition & 0 deletions examples/typescript-us-core/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fhir-types
24,166 changes: 24,166 additions & 0 deletions examples/typescript-us-core/examples/typescript-us-core/type-tree.yaml

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions examples/typescript-us-core/generate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Run this script using Bun CLI with:
// bun run examples/typescript-us-core/generate.ts

import { APIBuilder } from "../../src/api/builder";
import { LogLevel } from "../../src/utils/codegen-logger";

if (require.main === module) {
console.log("📦 Generating FHIR R4 Core Types...");

const builder = new APIBuilder()
.throwException()
.logLevel(LogLevel.INFO)
.fromPackage("hl7.fhir.us.core", "6.1.0")
.typescript({ withDebugComment: false, generateProfile: true })
.outputTo("./examples/typescript-us-core/fhir-types")
.writeTypeTree("./examples/typescript-us-core/type-tree.yaml")
.cleanOutput(true);

const report = await builder.generate();

console.log(report);

if (report.success) {
console.log("✅ FHIR R4 types generated successfully!");
} else {
console.error("❌ FHIR R4 types generation failed.");
process.exit(1);
}
}
89 changes: 89 additions & 0 deletions examples/typescript-us-core/test-usage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* Test file to verify generated profile types work correctly
*/

import type { Patient } from "./fhir-types/hl7-fhir-r4-core/Patient";
import {
createUSCorePatientProfile,
USCorePatientProfile,
} from "./fhir-types/hl7-fhir-us-core/profiles/USCorePatientProfile";

// Test 1: Create a profile from an existing patient resource
const patientResource: Patient = {
resourceType: "Patient",
id: "example",
meta: {
profile: ["http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient"],
},
name: [
{
family: "Smith",
given: ["John"],
},
],
gender: "male",
birthDate: "1990-01-01",
};

const profile = new USCorePatientProfile(patientResource);

// Test 2: Access constrained fields via property accessors
console.log("Gender:", profile.gender); // ✅ Constrained field (required in profile)
profile.gender = "female"; // ✅ Property setter with validation

// Test 3: Access unconstrained fields via readonly resource property
console.log("Birth date:", profile.resource.birthDate); // ✅ Read access
// profile.resource.birthDate = "1990-01-15"; // ❌ TypeScript error: readonly
// Note: Unconstrained fields should be set on the resource before creating the profile

// Test 4: Use array helpers for constrained array fields (new feature!)
profile.addIdentifier({
system: "http://example.org/mrn",
value: "12345",
}); // ✅ Add to constrained field

console.log("Identifiers:", profile.identifier.length);

// Remove identifiers
const removed = profile.removeIdentifier((id) => id.value === "12345"); // ✅ Remove by predicate
console.log("Removed identifiers:", removed);

// Test 5: Use extension accessors (new feature!)
profile.birthsex = {
url: "http://hl7.org/fhir/us/core/StructureDefinition/us-core-birthsex",
valueCode: "M",
}; // ✅ Property setter for extension

console.log("Birth sex:", profile.birthsex?.valueCode); // ✅ Property getter for extension

// Test 5: Collection extension
profile.addGenderIdentity({
url: "http://hl7.org/fhir/us/core/StructureDefinition/us-core-genderIdentity",
valueCodeableConcept: {
coding: [
{
system: "http://terminology.hl7.org/CodeSystem/v3-NullFlavor",
code: "ASKU",
display: "asked but unknown",
},
],
},
}); // ✅ Add to collection extension

console.log("Gender identity extensions:", profile.genderIdentity.length);

// Test 7: Use factory function
const newProfile = createUSCorePatientProfile(); // ✅ Factory creates with proper meta.profile
console.log("New profile URL:", newProfile.resource.meta?.profile?.[0]);

// Test 8: toJSON for serialization
const jsonString = JSON.stringify(profile); // ✅ Serializes to underlying Patient resource
const parsed = JSON.parse(jsonString);
console.log("Serialized resourceType:", parsed.resourceType); // "Patient"
console.log("Has meta.profile:", !!parsed.meta?.profile); // true

// Test 9: Type safety - these should cause TypeScript errors if uncommented:
// profile.resource.birthDate = 123; // ❌ Error: Type 'number' is not assignable to type 'string | undefined'
// profile.addIdentifier("not an identifier"); // ❌ Error: Argument of type 'string' is not assignable to parameter of type 'Identifier'

console.log("✅ All type checks passed!");
Loading
Loading