diff --git a/.bun-version b/.bun-version new file mode 100644 index 00000000..7962dcfd --- /dev/null +++ b/.bun-version @@ -0,0 +1 @@ +1.3.13 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a1d03e8c..f577766c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,6 +16,8 @@ jobs: - name: Setup Bun uses: oven-sh/setup-bun@v2 + with: + bun-version-file: .bun-version - name: Install dependencies run: bun install --frozen-lockfile @@ -37,6 +39,8 @@ jobs: - name: Setup Bun uses: oven-sh/setup-bun@v2 + with: + bun-version-file: .bun-version - name: Install dependencies run: bun install --frozen-lockfile @@ -52,6 +56,8 @@ jobs: - name: Setup Bun uses: oven-sh/setup-bun@v2 + with: + bun-version-file: .bun-version - name: Build and pack run: | @@ -83,6 +89,8 @@ jobs: - name: Setup Bun if: matrix.package-manager == 'bun' uses: oven-sh/setup-bun@v2 + with: + bun-version-file: .bun-version - name: Setup Node.js if: matrix.package-manager != 'bun' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3f6b3980..c70fbd88 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,6 +25,8 @@ jobs: - name: Setup Bun uses: oven-sh/setup-bun@v2 + with: + bun-version-file: .bun-version - name: Install dependencies run: bun install --frozen-lockfile @@ -76,6 +78,8 @@ jobs: - name: Setup Bun uses: oven-sh/setup-bun@v2 + with: + bun-version-file: .bun-version - name: Install dependencies run: bun install --frozen-lockfile diff --git a/.github/workflows/sdk-tests.yml b/.github/workflows/sdk-tests.yml index 3c04dc45..735710d8 100644 --- a/.github/workflows/sdk-tests.yml +++ b/.github/workflows/sdk-tests.yml @@ -15,6 +15,8 @@ jobs: - name: Setup Bun uses: oven-sh/setup-bun@v2 + with: + bun-version-file: .bun-version - name: Setup .NET uses: actions/setup-dotnet@v5 @@ -50,6 +52,8 @@ jobs: - name: Setup Bun uses: oven-sh/setup-bun@v2 + with: + bun-version-file: .bun-version - name: Install dependencies run: bun install --frozen-lockfile @@ -78,6 +82,8 @@ jobs: - name: Setup Bun uses: oven-sh/setup-bun@v2 + with: + bun-version-file: .bun-version - name: Install dependencies run: bun install --frozen-lockfile @@ -107,6 +113,8 @@ jobs: - name: Setup Bun uses: oven-sh/setup-bun@v2 + with: + bun-version-file: .bun-version - name: Install dependencies run: bun install --frozen-lockfile @@ -122,6 +130,8 @@ jobs: - name: Setup Bun uses: oven-sh/setup-bun@v2 + with: + bun-version-file: .bun-version - uses: actions/setup-python@v6 with: @@ -156,6 +166,8 @@ jobs: - name: Setup Bun uses: oven-sh/setup-bun@v2 + with: + bun-version-file: .bun-version - uses: actions/setup-python@v6 with: @@ -190,6 +202,8 @@ jobs: - name: Setup Bun uses: oven-sh/setup-bun@v2 + with: + bun-version-file: .bun-version - name: Install dependencies run: bun install --frozen-lockfile @@ -205,6 +219,8 @@ jobs: - name: Setup Bun uses: oven-sh/setup-bun@v2 + with: + bun-version-file: .bun-version - name: Install dependencies run: bun install --frozen-lockfile @@ -224,6 +240,8 @@ jobs: - name: Setup Bun uses: oven-sh/setup-bun@v2 + with: + bun-version-file: .bun-version - name: Setup Java uses: actions/setup-java@v5 diff --git a/CLAUDE.md b/CLAUDE.md index 121b230a..8d48f065 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -130,6 +130,7 @@ FHIR Package → TypeSchema Generator → TypeSchema Format → Code Generators - Unit tests for core functionality (transformers, builders) - Tests mirror source structure in `test/unit/` - API tests for high-level generators +- SQL-on-FHIR is split into per-language files (`sql-on-fhir-typescript.test.ts`, `sql-on-fhir-python.test.ts`, `sql-on-fhir-csharp.test.ts`) and the `test` Makefile target runs each as a separate `bun test` invocation. The combined file ran out of memory on `ubuntu-latest` (~7 GiB) because all three generators built simultaneously against R5 + the SQL-on-FHIR IG. Each file gets its own bun process so peak memory is bounded to one generator's output at a time. Do not recombine. ### Example Test Structure @@ -354,6 +355,7 @@ Detection uses `mkIsFamilyType(tsIndex)` which checks `schema.typeFamily.resourc 3. **Choice Types**: Supported but representation differs by language 4. **Circular References**: Handled but may affect tree shaking 5. **Large Packages**: May require increased Node.js memory (`--max-old-space-size`) +6. **Bun version pinned via `.bun-version`**: Bun 1.3.14 introduced a memory regression that OOM-kills `make test` on `ubuntu-latest`. Stick to the version pinned in `.bun-version` until a fixed Bun release is verified to pass CI. ## Performance Optimization Tips diff --git a/Makefile b/Makefile index 6bcf8fb9..abc23426 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,10 @@ typecheck: $(TYPECHECK) test: typecheck - bun test + bun test --path-ignore-patterns '**/sql-on-fhir-*.test.ts' + bun test test/api/write-generator/multi-package/sql-on-fhir-typescript.test.ts + bun test test/api/write-generator/multi-package/sql-on-fhir-python.test.ts + bun test test/api/write-generator/multi-package/sql-on-fhir-csharp.test.ts prepare-aidbox-runme: @if [ ! -f "example/docker-compose.yaml" ]; then \ diff --git a/test/api/write-generator/csharp.test.ts b/test/api/write-generator/csharp.test.ts index 03a2532f..cc8471fb 100644 --- a/test/api/write-generator/csharp.test.ts +++ b/test/api/write-generator/csharp.test.ts @@ -20,3 +20,5 @@ describe("C# Writer Generator", async () => { expect(files["generated/types/Helper.cs"]).toMatchSnapshot(); }); }); + +Bun.gc(true); diff --git a/test/api/write-generator/introspection.test.ts b/test/api/write-generator/introspection.test.ts index 5c8814a6..12bf7f5e 100644 --- a/test/api/write-generator/introspection.test.ts +++ b/test/api/write-generator/introspection.test.ts @@ -150,3 +150,5 @@ describe("IntrospectionWriter - StructureDefinition output", async () => { expect(files["generated/structure-definitions.ndjson"]).toMatchSnapshot(); }); }); + +Bun.gc(true); diff --git a/test/api/write-generator/multi-package/__snapshots__/sql-on-fhir-csharp.test.ts.snap b/test/api/write-generator/multi-package/__snapshots__/sql-on-fhir-csharp.test.ts.snap new file mode 100644 index 00000000..843d44cf --- /dev/null +++ b/test/api/write-generator/multi-package/__snapshots__/sql-on-fhir-csharp.test.ts.snap @@ -0,0 +1,120 @@ +// Bun Snapshot v1, https://bun.sh/docs/test/snapshots + +exports[`SQL-on-FHIR C# Generation should generate ViewDefinition 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.OrgSqlOnFhirIg; + +public class ViewDefinition : CanonicalResource { + public ViewDefinitionConstant[]? Constant { get; set; } + public ViewDefinitionFhirVersionBindingEnum[]? FhirVersion { get; set; } + public string? Name { get; set; } + public string[]? Profile { get; set; } + public required string Resource { get; set; } + public required ViewDefinitionSelect[] Select { get; set; } + public ViewDefinitionWhere[]? Where { get; set; } + + public class ViewDefinitionConstant : BackboneElement { + public required string Name { get; set; } + public string? ValueBase64binary { get; set; } + public bool? ValueBoolean { get; set; } + public string? ValueCanonical { get; set; } + public string? ValueCode { get; set; } + public string? ValueDate { get; set; } + public string? ValueDateTime { get; set; } + public decimal? ValueDecimal { get; set; } + public string? ValueId { get; set; } + public string? ValueInstant { get; set; } + public int? ValueInteger { get; set; } + public long? ValueInteger64 { get; set; } + public string? ValueOid { get; set; } + public long? ValuePositiveInt { get; set; } + public string? ValueString { get; set; } + public string? ValueTime { get; set; } + public long? ValueUnsignedInt { get; set; } + public string? ValueUri { get; set; } + public string? ValueUrl { get; set; } + public string? ValueUuid { get; set; } + + public override string ToString() => + JsonSerializer.Serialize(this, Helper.JsonSerializerOptions); + + } + + public class ViewDefinitionSelect : BackboneElement { + public ViewDefinitionSelectColumn[]? Column { get; set; } + public string? ForEach { get; set; } + public string? ForEachOrNull { get; set; } + public string[]? Repeat { get; set; } + public ViewDefinitionSelect[]? Select { get; set; } + public ViewDefinitionSelect[]? UnionAll { get; set; } + + public override string ToString() => + JsonSerializer.Serialize(this, Helper.JsonSerializerOptions); + + } + + public class ViewDefinitionSelectColumn : BackboneElement { + public bool? Collection { get; set; } + public string? Description { get; set; } + public required string Name { get; set; } + public required string Path { get; set; } + public ViewDefinitionSelectColumnTag[]? Tag { get; set; } + public string? Type { get; set; } + + public override string ToString() => + JsonSerializer.Serialize(this, Helper.JsonSerializerOptions); + + } + + public class ViewDefinitionSelectColumnTag : BackboneElement { + public required string Name { get; set; } + public required string Value { get; set; } + + public override string ToString() => + JsonSerializer.Serialize(this, Helper.JsonSerializerOptions); + + } + + public class ViewDefinitionWhere : BackboneElement { + public string? Description { get; set; } + public required string Path { get; set; } + + public override string ToString() => + JsonSerializer.Serialize(this, Helper.JsonSerializerOptions); + + } + + + public override string ToString() => + JsonSerializer.Serialize(this, Helper.JsonSerializerOptions); + +} + +" +`; + +exports[`SQL-on-FHIR C# Generation should generate DomainResource for R5 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.Hl7FhirR5Core; + +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); + +} + +" +`; diff --git a/test/api/write-generator/multi-package/__snapshots__/sql-on-fhir.test.ts.snap b/test/api/write-generator/multi-package/__snapshots__/sql-on-fhir-python.test.ts.snap similarity index 54% rename from test/api/write-generator/multi-package/__snapshots__/sql-on-fhir.test.ts.snap rename to test/api/write-generator/multi-package/__snapshots__/sql-on-fhir-python.test.ts.snap index 12427c37..e6bd07cd 100644 --- a/test/api/write-generator/multi-package/__snapshots__/sql-on-fhir.test.ts.snap +++ b/test/api/write-generator/multi-package/__snapshots__/sql-on-fhir-python.test.ts.snap @@ -1,84 +1,5 @@ // Bun Snapshot v1, https://bun.sh/docs/test/snapshots -exports[`SQL-on-FHIR TypeScript Generation should generate ViewDefinition type 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 { BackboneElement } from "../hl7-fhir-r5-core/BackboneElement"; -import type { CanonicalResource } from "../hl7-fhir-r5-core/CanonicalResource"; - -import type { Element } from "../hl7-fhir-r5-core/Element"; -export type { BackboneElement } from "../hl7-fhir-r5-core/BackboneElement"; - -export interface ViewDefinitionConstant extends BackboneElement { - name: string; - valueBase64Binary?: string; - valueBoolean?: boolean; - valueCanonical?: string; - valueCode?: string; - valueDate?: string; - valueDateTime?: string; - valueDecimal?: number; - valueId?: string; - valueInstant?: string; - valueInteger?: number; - valueInteger64?: number; - valueOid?: string; - valuePositiveInt?: number; - valueString?: string; - valueTime?: string; - valueUnsignedInt?: number; - valueUri?: string; - valueUrl?: string; - valueUuid?: string; -} - -export interface ViewDefinitionSelect extends BackboneElement { - column?: ViewDefinitionSelectColumn[]; - forEach?: string; - forEachOrNull?: string; - repeat?: string[]; - select?: ViewDefinitionSelect[]; - unionAll?: ViewDefinitionSelect[]; -} - -export interface ViewDefinitionSelectColumn extends BackboneElement { - collection?: boolean; - description?: string; - name: string; - path: string; - tag?: ViewDefinitionSelectColumnTag[]; - type?: string; -} - -export interface ViewDefinitionSelectColumnTag extends BackboneElement { - name: string; - value: string; -} - -export interface ViewDefinitionWhere extends BackboneElement { - description?: string; - path: string; -} - -// CanonicalURL: https://sql-on-fhir.org/ig/StructureDefinition/ViewDefinition (pkg: org.sql-on-fhir.ig#2.1.0-pre) -export interface ViewDefinition extends CanonicalResource { - constant?: ViewDefinitionConstant[]; - fhirVersion?: ("0.01" | "0.05" | "0.06" | "0.11" | "0.0" | "0.0.80" | "0.0.81" | "0.0.82" | "0.4" | "0.4.0" | "0.5" | "0.5.0" | "1.0" | "1.0.0" | "1.0.1" | "1.0.2" | "1.1" | "1.1.0" | "1.4" | "1.4.0" | "1.6" | "1.6.0" | "1.8" | "1.8.0" | "3.0" | "3.0.0" | "3.0.1" | "3.0.2" | "3.3" | "3.3.0" | "3.5" | "3.5.0" | "4.0" | "4.0.0" | "4.0.1" | "4.1" | "4.1.0" | "4.2" | "4.2.0" | "4.3" | "4.3.0" | "4.3.0-cibuild" | "4.3.0-snapshot1" | "4.4" | "4.4.0" | "4.5" | "4.5.0" | "4.6" | "4.6.0" | "5.0" | "5.0.0" | "5.0.0-cibuild" | "5.0.0-snapshot1" | "5.0.0-snapshot2" | "5.0.0-ballot" | "5.0.0-snapshot3" | "5.0.0-draft-final")[]; - _fhirVersion?: (Element | null)[]; - name?: string; - _name?: Element; - profile?: string[]; - _profile?: (Element | null)[]; - resource: string; - _resource?: Element; - select: ViewDefinitionSelect[]; - where?: ViewDefinitionWhere[]; -} -" -`; - exports[`SQL-on-FHIR Python Generation should generate ViewDefinition type (promoted logical) 1`] = ` "# WARNING: This file is autogenerated by @atomic-ehr/codegen. # GitHub: https://github.com/atomic-ehr/codegen @@ -215,122 +136,3 @@ class DomainResource(Resource): " `; - -exports[`SQL-on-FHIR C# Generation should generate ViewDefinition 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.OrgSqlOnFhirIg; - -public class ViewDefinition : CanonicalResource { - public ViewDefinitionConstant[]? Constant { get; set; } - public ViewDefinitionFhirVersionBindingEnum[]? FhirVersion { get; set; } - public string? Name { get; set; } - public string[]? Profile { get; set; } - public required string Resource { get; set; } - public required ViewDefinitionSelect[] Select { get; set; } - public ViewDefinitionWhere[]? Where { get; set; } - - public class ViewDefinitionConstant : BackboneElement { - public required string Name { get; set; } - public string? ValueBase64binary { get; set; } - public bool? ValueBoolean { get; set; } - public string? ValueCanonical { get; set; } - public string? ValueCode { get; set; } - public string? ValueDate { get; set; } - public string? ValueDateTime { get; set; } - public decimal? ValueDecimal { get; set; } - public string? ValueId { get; set; } - public string? ValueInstant { get; set; } - public int? ValueInteger { get; set; } - public long? ValueInteger64 { get; set; } - public string? ValueOid { get; set; } - public long? ValuePositiveInt { get; set; } - public string? ValueString { get; set; } - public string? ValueTime { get; set; } - public long? ValueUnsignedInt { get; set; } - public string? ValueUri { get; set; } - public string? ValueUrl { get; set; } - public string? ValueUuid { get; set; } - - public override string ToString() => - JsonSerializer.Serialize(this, Helper.JsonSerializerOptions); - - } - - public class ViewDefinitionSelect : BackboneElement { - public ViewDefinitionSelectColumn[]? Column { get; set; } - public string? ForEach { get; set; } - public string? ForEachOrNull { get; set; } - public string[]? Repeat { get; set; } - public ViewDefinitionSelect[]? Select { get; set; } - public ViewDefinitionSelect[]? UnionAll { get; set; } - - public override string ToString() => - JsonSerializer.Serialize(this, Helper.JsonSerializerOptions); - - } - - public class ViewDefinitionSelectColumn : BackboneElement { - public bool? Collection { get; set; } - public string? Description { get; set; } - public required string Name { get; set; } - public required string Path { get; set; } - public ViewDefinitionSelectColumnTag[]? Tag { get; set; } - public string? Type { get; set; } - - public override string ToString() => - JsonSerializer.Serialize(this, Helper.JsonSerializerOptions); - - } - - public class ViewDefinitionSelectColumnTag : BackboneElement { - public required string Name { get; set; } - public required string Value { get; set; } - - public override string ToString() => - JsonSerializer.Serialize(this, Helper.JsonSerializerOptions); - - } - - public class ViewDefinitionWhere : BackboneElement { - public string? Description { get; set; } - public required string Path { get; set; } - - public override string ToString() => - JsonSerializer.Serialize(this, Helper.JsonSerializerOptions); - - } - - - public override string ToString() => - JsonSerializer.Serialize(this, Helper.JsonSerializerOptions); - -} - -" -`; - -exports[`SQL-on-FHIR C# Generation should generate DomainResource for R5 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.Hl7FhirR5Core; - -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); - -} - -" -`; diff --git a/test/api/write-generator/multi-package/__snapshots__/sql-on-fhir-typescript.test.ts.snap b/test/api/write-generator/multi-package/__snapshots__/sql-on-fhir-typescript.test.ts.snap new file mode 100644 index 00000000..36d703cd --- /dev/null +++ b/test/api/write-generator/multi-package/__snapshots__/sql-on-fhir-typescript.test.ts.snap @@ -0,0 +1,80 @@ +// Bun Snapshot v1, https://bun.sh/docs/test/snapshots + +exports[`SQL-on-FHIR TypeScript Generation should generate ViewDefinition type 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 { BackboneElement } from "../hl7-fhir-r5-core/BackboneElement"; +import type { CanonicalResource } from "../hl7-fhir-r5-core/CanonicalResource"; + +import type { Element } from "../hl7-fhir-r5-core/Element"; +export type { BackboneElement } from "../hl7-fhir-r5-core/BackboneElement"; + +export interface ViewDefinitionConstant extends BackboneElement { + name: string; + valueBase64Binary?: string; + valueBoolean?: boolean; + valueCanonical?: string; + valueCode?: string; + valueDate?: string; + valueDateTime?: string; + valueDecimal?: number; + valueId?: string; + valueInstant?: string; + valueInteger?: number; + valueInteger64?: number; + valueOid?: string; + valuePositiveInt?: number; + valueString?: string; + valueTime?: string; + valueUnsignedInt?: number; + valueUri?: string; + valueUrl?: string; + valueUuid?: string; +} + +export interface ViewDefinitionSelect extends BackboneElement { + column?: ViewDefinitionSelectColumn[]; + forEach?: string; + forEachOrNull?: string; + repeat?: string[]; + select?: ViewDefinitionSelect[]; + unionAll?: ViewDefinitionSelect[]; +} + +export interface ViewDefinitionSelectColumn extends BackboneElement { + collection?: boolean; + description?: string; + name: string; + path: string; + tag?: ViewDefinitionSelectColumnTag[]; + type?: string; +} + +export interface ViewDefinitionSelectColumnTag extends BackboneElement { + name: string; + value: string; +} + +export interface ViewDefinitionWhere extends BackboneElement { + description?: string; + path: string; +} + +// CanonicalURL: https://sql-on-fhir.org/ig/StructureDefinition/ViewDefinition (pkg: org.sql-on-fhir.ig#2.1.0-pre) +export interface ViewDefinition extends CanonicalResource { + constant?: ViewDefinitionConstant[]; + fhirVersion?: ("0.01" | "0.05" | "0.06" | "0.11" | "0.0" | "0.0.80" | "0.0.81" | "0.0.82" | "0.4" | "0.4.0" | "0.5" | "0.5.0" | "1.0" | "1.0.0" | "1.0.1" | "1.0.2" | "1.1" | "1.1.0" | "1.4" | "1.4.0" | "1.6" | "1.6.0" | "1.8" | "1.8.0" | "3.0" | "3.0.0" | "3.0.1" | "3.0.2" | "3.3" | "3.3.0" | "3.5" | "3.5.0" | "4.0" | "4.0.0" | "4.0.1" | "4.1" | "4.1.0" | "4.2" | "4.2.0" | "4.3" | "4.3.0" | "4.3.0-cibuild" | "4.3.0-snapshot1" | "4.4" | "4.4.0" | "4.5" | "4.5.0" | "4.6" | "4.6.0" | "5.0" | "5.0.0" | "5.0.0-cibuild" | "5.0.0-snapshot1" | "5.0.0-snapshot2" | "5.0.0-ballot" | "5.0.0-snapshot3" | "5.0.0-draft-final")[]; + _fhirVersion?: (Element | null)[]; + name?: string; + _name?: Element; + profile?: string[]; + _profile?: (Element | null)[]; + resource: string; + _resource?: Element; + select: ViewDefinitionSelect[]; + where?: ViewDefinitionWhere[]; +} +" +`; diff --git a/test/api/write-generator/multi-package/cda.test.ts b/test/api/write-generator/multi-package/cda.test.ts index cb4c73aa..9d808f1d 100644 --- a/test/api/write-generator/multi-package/cda.test.ts +++ b/test/api/write-generator/multi-package/cda.test.ts @@ -91,3 +91,5 @@ describe("CDA", async () => { }); }); }); + +Bun.gc(true); diff --git a/test/api/write-generator/multi-package/local-package.test.ts b/test/api/write-generator/multi-package/local-package.test.ts index 5b13c3e2..c7608f0b 100644 --- a/test/api/write-generator/multi-package/local-package.test.ts +++ b/test/api/write-generator/multi-package/local-package.test.ts @@ -172,3 +172,5 @@ describe("Local Package Folder - Multi-Package Generation", async () => { }); }); }); + +Bun.gc(true); diff --git a/test/api/write-generator/multi-package/sql-on-fhir-csharp.test.ts b/test/api/write-generator/multi-package/sql-on-fhir-csharp.test.ts new file mode 100644 index 00000000..7b8fb10a --- /dev/null +++ b/test/api/write-generator/multi-package/sql-on-fhir-csharp.test.ts @@ -0,0 +1,51 @@ +import { describe, expect, it } from "bun:test"; +import { APIBuilder } from "@root/api/builder"; +import type { CanonicalUrl } from "@root/typeschema/types"; +import { mkSilentLogger } from "@typeschema-test/utils"; + +/** + * C# generation for the SQL-on-FHIR package. + * Split into its own file so peak memory stays bounded to one generator on CI. + */ +describe("SQL-on-FHIR C# Generation", async () => { + const packageUrl = "https://build.fhir.org/ig/FHIR/sql-on-fhir-v2/package.tgz"; + + const treeShakeConfig = { + "org.sql-on-fhir.ig": { + "https://sql-on-fhir.org/ig/StructureDefinition/ViewDefinition": {}, + }, + }; + + const promoteLogicalConfig = { + "org.sql-on-fhir.ig": ["https://sql-on-fhir.org/ig/StructureDefinition/ViewDefinition" as CanonicalUrl], + }; + + const result = await new APIBuilder({ logger: mkSilentLogger() }) + .fromPackageRef(packageUrl) + .typeSchema({ treeShake: treeShakeConfig, promoteLogical: promoteLogicalConfig }) + .csharp({ inMemoryOnly: true }) + .generate(); + + it("should succeed", () => { + expect(result.success).toBeTrue(); + }); + + it("should generate ViewDefinition type (promoted logical)", () => { + const viewDef = result.filesGenerated.csharp!["generated/types/OrgSqlOnFhirIg/ViewDefinition.cs"]; + expect(viewDef).toBeDefined(); + expect(viewDef).toMatchSnapshot(); + }); + + it("should generate R5 dependency namespace", () => { + // C# generator creates R5 types for dependencies + const files = Object.keys(result.filesGenerated.csharp!); + const r5Files = files.filter((f) => f.includes("Hl7FhirR5Core")); + expect(r5Files.length).toBe(5); + }); + + it("should generate DomainResource for R5", () => { + const domainResource = result.filesGenerated.csharp!["generated/types/Hl7FhirR5Core/DomainResource.cs"]; + expect(domainResource).toBeDefined(); + expect(domainResource).toMatchSnapshot(); + }); +}); diff --git a/test/api/write-generator/multi-package/sql-on-fhir-python.test.ts b/test/api/write-generator/multi-package/sql-on-fhir-python.test.ts new file mode 100644 index 00000000..2a327d54 --- /dev/null +++ b/test/api/write-generator/multi-package/sql-on-fhir-python.test.ts @@ -0,0 +1,50 @@ +import { describe, expect, it } from "bun:test"; +import { APIBuilder } from "@root/api/builder"; +import type { CanonicalUrl } from "@root/typeschema/types"; +import { mkSilentLogger } from "@typeschema-test/utils"; + +/** + * Python generation for the SQL-on-FHIR package. + * Split into its own file so peak memory stays bounded to one generator on CI. + */ +describe("SQL-on-FHIR Python Generation", async () => { + const packageUrl = "https://build.fhir.org/ig/FHIR/sql-on-fhir-v2/package.tgz"; + + const treeShakeConfig = { + "org.sql-on-fhir.ig": { + "https://sql-on-fhir.org/ig/StructureDefinition/ViewDefinition": {}, + }, + }; + + const promoteLogicalConfig = { + "org.sql-on-fhir.ig": ["https://sql-on-fhir.org/ig/StructureDefinition/ViewDefinition" as CanonicalUrl], + }; + + const result = await new APIBuilder({ logger: mkSilentLogger() }) + .fromPackageRef(packageUrl) + .typeSchema({ treeShake: treeShakeConfig, promoteLogical: promoteLogicalConfig }) + .python({ inMemoryOnly: true }) + .generate(); + + it("should succeed", () => { + expect(result.success).toBeTrue(); + }); + + it("should generate ViewDefinition type (promoted logical)", () => { + const viewDef = result.filesGenerated.python!["generated/org_sql_on_fhir_ig/view_definition.py"]; + expect(viewDef).toBeDefined(); + expect(viewDef).toMatchSnapshot(); + }); + + it("should generate R5 dependency package", () => { + // Python generator creates R5 base types for dependencies + expect(result.filesGenerated.python!["generated/hl7_fhir_r5_core/__init__.py"]).toBeDefined(); + expect(result.filesGenerated.python!["generated/hl7_fhir_r5_core/domain_resource.py"]).toBeDefined(); + }); + + it("should generate domain_resource for R5", () => { + const domainResource = result.filesGenerated.python!["generated/hl7_fhir_r5_core/domain_resource.py"]; + expect(domainResource).toBeDefined(); + expect(domainResource).toMatchSnapshot(); + }); +}); diff --git a/test/api/write-generator/multi-package/sql-on-fhir-typescript.test.ts b/test/api/write-generator/multi-package/sql-on-fhir-typescript.test.ts new file mode 100644 index 00000000..ac561f2e --- /dev/null +++ b/test/api/write-generator/multi-package/sql-on-fhir-typescript.test.ts @@ -0,0 +1,48 @@ +import { describe, expect, it } from "bun:test"; +import { APIBuilder } from "@root/api/builder"; +import { mkSilentLogger } from "@typeschema-test/utils"; + +/** + * TypeScript generation for the SQL-on-FHIR package. + * Split into its own file so peak memory stays bounded to one generator on CI. + */ +describe("SQL-on-FHIR TypeScript Generation", async () => { + const packageUrl = "https://build.fhir.org/ig/FHIR/sql-on-fhir-v2/package.tgz"; + + const treeShakeConfig = { + "org.sql-on-fhir.ig": { + "https://sql-on-fhir.org/ig/StructureDefinition/ViewDefinition": {}, + }, + }; + + const result = await new APIBuilder({ logger: mkSilentLogger() }) + .fromPackageRef(packageUrl) + .typeSchema({ treeShake: treeShakeConfig }) + .typescript({ inMemoryOnly: true }) + .generate(); + + it("should succeed", () => { + expect(result.success).toBeTrue(); + }); + + it("should generate ViewDefinition type", () => { + const viewDef = result.filesGenerated.typescript!["generated/types/org-sql-on-fhir-ig/ViewDefinition.ts"]; + expect(viewDef).toBeDefined(); + expect(viewDef).toMatchSnapshot(); + }); + + it("should resolve R5 dependencies (required by SQL-on-FHIR)", () => { + const files = Object.keys(result.filesGenerated.typescript!); + const r5Files = files.filter((f) => f.includes("hl7-fhir-r5-core")); + expect(r5Files.length).toBe(45); + + // Core R5 types should be included + expect(result.filesGenerated.typescript!["generated/types/hl7-fhir-r5-core/Element.ts"]).toBeDefined(); + expect(result.filesGenerated.typescript!["generated/types/hl7-fhir-r5-core/DomainResource.ts"]).toBeDefined(); + }); + + it("should generate package index files", () => { + expect(result.filesGenerated.typescript!["generated/types/org-sql-on-fhir-ig/index.ts"]).toBeDefined(); + expect(result.filesGenerated.typescript!["generated/types/hl7-fhir-r5-core/index.ts"]).toBeDefined(); + }); +}); diff --git a/test/api/write-generator/multi-package/sql-on-fhir.test.ts b/test/api/write-generator/multi-package/sql-on-fhir.test.ts deleted file mode 100644 index 0c2bd722..00000000 --- a/test/api/write-generator/multi-package/sql-on-fhir.test.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { describe, expect, it } from "bun:test"; -import { APIBuilder } from "@root/api/builder"; -import type { CanonicalUrl } from "@root/typeschema/types"; -import { mkSilentLogger } from "@typeschema-test/utils"; - -/** - * Tests for SQL-on-FHIR package. - * The SQL-on-FHIR package depends on hl7.fhir.r5.core. - */ -describe("SQL-on-FHIR", async () => { - const packageUrl = "https://build.fhir.org/ig/FHIR/sql-on-fhir-v2/package.tgz"; - - const treeShakeConfig = { - "org.sql-on-fhir.ig": { - "https://sql-on-fhir.org/ig/StructureDefinition/ViewDefinition": {}, - }, - }; - - const promoteLogicalConfig = { - "org.sql-on-fhir.ig": ["https://sql-on-fhir.org/ig/StructureDefinition/ViewDefinition" as CanonicalUrl], - }; - - describe("TypeScript Generation", async () => { - const result = await new APIBuilder({ logger: mkSilentLogger() }) - .fromPackageRef(packageUrl) - .typeSchema({ treeShake: treeShakeConfig }) - .typescript({ inMemoryOnly: true }) - .generate(); - - it("should succeed", () => { - expect(result.success).toBeTrue(); - }); - - it("should generate ViewDefinition type", () => { - const viewDef = result.filesGenerated.typescript!["generated/types/org-sql-on-fhir-ig/ViewDefinition.ts"]; - expect(viewDef).toBeDefined(); - expect(viewDef).toMatchSnapshot(); - }); - - it("should resolve R5 dependencies (required by SQL-on-FHIR)", () => { - const files = Object.keys(result.filesGenerated.typescript!); - const r5Files = files.filter((f) => f.includes("hl7-fhir-r5-core")); - expect(r5Files.length).toBe(45); - - // Core R5 types should be included - expect(result.filesGenerated.typescript!["generated/types/hl7-fhir-r5-core/Element.ts"]).toBeDefined(); - expect( - result.filesGenerated.typescript!["generated/types/hl7-fhir-r5-core/DomainResource.ts"], - ).toBeDefined(); - }); - - it("should generate package index files", () => { - expect(result.filesGenerated.typescript!["generated/types/org-sql-on-fhir-ig/index.ts"]).toBeDefined(); - expect(result.filesGenerated.typescript!["generated/types/hl7-fhir-r5-core/index.ts"]).toBeDefined(); - }); - }); - - describe("Python Generation", async () => { - const result = await new APIBuilder({ logger: mkSilentLogger() }) - .fromPackageRef(packageUrl) - .typeSchema({ treeShake: treeShakeConfig, promoteLogical: promoteLogicalConfig }) - .python({ inMemoryOnly: true }) - .generate(); - - it("should succeed", () => { - expect(result.success).toBeTrue(); - }); - - it("should generate ViewDefinition type (promoted logical)", () => { - const viewDef = result.filesGenerated.python!["generated/org_sql_on_fhir_ig/view_definition.py"]; - expect(viewDef).toBeDefined(); - expect(viewDef).toMatchSnapshot(); - }); - - it("should generate R5 dependency package", () => { - // Python generator creates R5 base types for dependencies - expect(result.filesGenerated.python!["generated/hl7_fhir_r5_core/__init__.py"]).toBeDefined(); - expect(result.filesGenerated.python!["generated/hl7_fhir_r5_core/domain_resource.py"]).toBeDefined(); - }); - - it("should generate domain_resource for R5", () => { - const domainResource = result.filesGenerated.python!["generated/hl7_fhir_r5_core/domain_resource.py"]; - expect(domainResource).toBeDefined(); - expect(domainResource).toMatchSnapshot(); - }); - }); - - describe("C# Generation", async () => { - const result = await new APIBuilder({ logger: mkSilentLogger() }) - .fromPackageRef(packageUrl) - .typeSchema({ treeShake: treeShakeConfig, promoteLogical: promoteLogicalConfig }) - .csharp({ inMemoryOnly: true }) - .generate(); - - it("should succeed", () => { - expect(result.success).toBeTrue(); - }); - - it("should generate ViewDefinition type (promoted logical)", () => { - const viewDef = result.filesGenerated.csharp!["generated/types/OrgSqlOnFhirIg/ViewDefinition.cs"]; - expect(viewDef).toBeDefined(); - expect(viewDef).toMatchSnapshot(); - }); - - it("should generate R5 dependency namespace", () => { - // C# generator creates R5 types for dependencies - const files = Object.keys(result.filesGenerated.csharp!); - const r5Files = files.filter((f) => f.includes("Hl7FhirR5Core")); - expect(r5Files.length).toBe(5); - }); - - it("should generate DomainResource for R5", () => { - const domainResource = result.filesGenerated.csharp!["generated/types/Hl7FhirR5Core/DomainResource.cs"]; - expect(domainResource).toBeDefined(); - expect(domainResource).toMatchSnapshot(); - }); - }); -}); diff --git a/test/api/write-generator/python.test.ts b/test/api/write-generator/python.test.ts index 26ac7f2b..2ead47c4 100644 --- a/test/api/write-generator/python.test.ts +++ b/test/api/write-generator/python.test.ts @@ -40,3 +40,5 @@ describe("Python Writer Generator", async () => { expect(basePy).toContain("T = TypeVar('T', bound=str, default=str)"); }); }); + +Bun.gc(true); diff --git a/test/api/write-generator/typescript.test.ts b/test/api/write-generator/typescript.test.ts index cd51945e..be62d9f6 100644 --- a/test/api/write-generator/typescript.test.ts +++ b/test/api/write-generator/typescript.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from "bun:test"; import { APIBuilder } from "@root/api/builder"; import type { CanonicalUrl } from "@root/typeschema/types"; -import { ccdaManager, mkErrorLogger, r4Manager } from "@typeschema-test/utils"; +import { mkCCDARegister, mkErrorLogger, r4Manager } from "@typeschema-test/utils"; describe("TypeScript Writer Generator", async () => { const result = await new APIBuilder({ register: r4Manager, logger: mkErrorLogger() }) @@ -57,7 +57,7 @@ describe("TypeScript Writer Generator", async () => { }); describe("TypeScript CDA with Logical Model Promotion to Resource", async () => { - const result = await new APIBuilder({ register: ccdaManager, logger: mkErrorLogger() }) + const result = await new APIBuilder({ register: await mkCCDARegister(), logger: mkErrorLogger() }) .typeSchema({ promoteLogical: { "hl7.cda.uv.core": ["http://hl7.org/cda/stds/core/StructureDefinition/Material" as CanonicalUrl], @@ -171,3 +171,5 @@ describe("TypeScript US Core Example", async () => { expect(files["generated/types/hl7-fhir-us-core/profiles/index.ts"]).toMatchSnapshot(); }); }); + +Bun.gc(true); diff --git a/test/unit/typeschema/utils.ts b/test/unit/typeschema/utils.ts index 219a1ae5..73cd88e3 100644 --- a/test/unit/typeschema/utils.ts +++ b/test/unit/typeschema/utils.ts @@ -43,8 +43,6 @@ export const mkCCDARegister = async () => // logger: createLogger({ verbose: true, prefix: "TEST" }) }); -export const ccdaManager = await mkCCDARegister(); - export const registerFs = (register: Register, fs: PFS) => { const pkg = fs.package_meta ?? { name: "mypackage", version: "0.0.0" }; const rfs = enrichFHIRSchema(fs as FHIRSchema, pkg);