Skip to content

Commit ab75fc5

Browse files
authored
Merge branch 'main' into ij/add-registry-support
2 parents f7622d4 + 27719de commit ab75fc5

9 files changed

Lines changed: 355 additions & 76 deletions

File tree

README.md

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -122,25 +122,47 @@ Actual examples of type generation and usage can be found here: [examples/typesc
122122

123123
- `demo.ts` - a simple script that creates resources and demonstrates how to work with profiles
124124
- `generate.ts` - script to generate types
125+
- [`examples/local-structure-package.ts`](examples/local-structure-package.ts) - demonstrates loading local profiles, installing dependencies, and tree shaking the output
126+
- [`examples/local-package-folder/generate.ts`](examples/local-package-folder/generate.ts) - demonstrates pointing the builder at an existing FHIR package folder without publishing it
125127

126-
### Generate Types for a Custom Profile (Draft)
128+
### Load Local StructureDefinitions, Local Packages & TGZ Archives
129+
130+
Use the new `localPackage` helper to point the builder at an on-disk FHIR package folder (for example, an unpublished implementation guide). If you only have loose StructureDefinition JSON files, group them under a folder and pass it to `localStructureDefinitions`. Canonical Manager handles copying, indexing, and dependency installation in both scenarios, so the API builder only needs to describe where the files live and what upstream packages they depend on.
127131

128132
```typescript
129-
import { APIBuilder } from '@atomic-ehr/codegen';
133+
import { APIBuilder } from "@atomic-ehr/codegen";
130134

131135
const builder = new APIBuilder();
132136

133-
// Load custom profile
134137
await builder
135-
.fromProfile('./profiles/my-patient-profile.json')
136-
.withBaseProfile('http://hl7.org/fhir/StructureDefinition/Patient')
137-
.typescript({
138-
outputDir: './generated/profiles',
139-
includeValidators: true,
138+
.localPackage({
139+
package: { name: "example.folder.structures", version: "0.0.1" },
140+
path: "./packages/example-ig/package",
141+
dependencies: [{ name: "hl7.fhir.r4.core", version: "4.0.1" }],
140142
})
143+
.localStructureDefinitions({
144+
package: { name: "example.local.structures", version: "0.0.1" },
145+
path: "./custom-profiles",
146+
dependencies: [{ name: "hl7.fhir.r4.core", version: "4.0.1" }],
147+
})
148+
.localTgzPackage("./packages/my-custom-ig.tgz")
149+
.typescript({ generateIndex: true })
150+
.treeShake({
151+
"example.local.structures#0.0.1": {
152+
"http://example.org/fhir/StructureDefinition/ExampleNotebook": {},
153+
},
154+
"hl7.fhir.r4.core#4.0.1": {
155+
"http://hl7.org/fhir/StructureDefinition/Patient": {},
156+
},
157+
})
158+
.outputTo("./generated/local-profiles")
141159
.generate();
142160
```
143161

162+
The example above points Canonical Manager at `./custom-profiles`, installs the HL7 R4 core dependency automatically, and then limits generation to the custom `ExampleNotebook` logical model plus the standard R4 `Patient` resource via tree shaking. The `localTgzPackage` helper registers `.tgz` artifacts that Canonical Manager already knows how to unpack.
163+
164+
`localPackage` is ideal when you already have an extracted Implementation Guide on disk (for example, after running `fhirpack` or `npm pack`). The helper copies that folder into Canonical Manager's cache, synthesizes an index if necessary, and makes the package available to the rest of the pipeline without publishing it anywhere.
165+
144166
### Generate with Custom Templates (Draft)
145167

146168
```typescript

bun.lock

Lines changed: 49 additions & 50 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ This directory contains examples demonstrating the current capabilities and futu
1010
- Basic FHIR R4 core type generation
1111
- TypeScript generation with configuration
1212
- Type-safe resource creation examples
13+
- **`local-package-folder/generate.ts`** - Registers an existing on-disk FHIR package (folder) and runs the generators without publishing the package to npm
1314

1415
### 🔮 Preview Examples
1516

@@ -61,4 +62,4 @@ These limitations are being addressed in Phase 0 of our roadmap.
6162

6263
---
6364

64-
**Note**: Examples marked with 🔮 show planned API design but are not yet functional. They serve as specifications for future development.
65+
**Note**: Examples marked with 🔮 show planned API design but are not yet functional. They serve as specifications for future development.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import * as Path from "node:path";
2+
import { fileURLToPath } from "node:url";
3+
import { APIBuilder, LogLevel } from "../../src/api";
4+
5+
const __dirname = Path.dirname(fileURLToPath(import.meta.url));
6+
7+
async function generateFromLocalPackageFolder() {
8+
const builder = new APIBuilder({
9+
logLevel: LogLevel.INFO,
10+
});
11+
12+
await builder
13+
.localStructureDefinitions({
14+
package: { name: "example.folder.structures", version: "0.0.1" },
15+
path: Path.join(__dirname, "structure-definitions"),
16+
dependencies: [{ name: "hl7.fhir.r4.core", version: "4.0.1" }],
17+
})
18+
.typescript({})
19+
.treeShake({
20+
"example.folder.structures": {
21+
"http://example.org/fhir/StructureDefinition/ExampleNotebook": {},
22+
},
23+
})
24+
.outputTo("./examples/local-package-folder")
25+
.generate();
26+
}
27+
28+
generateFromLocalPackageFolder().catch((error) => {
29+
console.error(error);
30+
process.exit(1);
31+
});
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
{
2+
"resourceType": "StructureDefinition",
3+
"id": "example-notebook",
4+
"url": "http://example.org/fhir/StructureDefinition/ExampleNotebook",
5+
"version": "0.0.1",
6+
"name": "ExampleNotebook",
7+
"title": "Example Notebook Logical Model",
8+
"status": "draft",
9+
"date": "2024-01-01",
10+
"publisher": "Atomic Example Studio",
11+
"description": "Logical resource showcasing a simple notebook record with fields used in examples.",
12+
"fhirVersion": "4.0.1",
13+
"kind": "logical",
14+
"abstract": false,
15+
"type": "ExampleNotebook",
16+
"baseDefinition": "http://hl7.org/fhir/StructureDefinition/DomainResource",
17+
"derivation": "specialization",
18+
"snapshot": {
19+
"element": [
20+
{
21+
"id": "ExampleNotebook",
22+
"path": "ExampleNotebook",
23+
"short": "Example logical notebook resource",
24+
"definition": "A lightweight notebook entry capturing author, title, and content.",
25+
"min": 0,
26+
"max": "*",
27+
"type": [
28+
{
29+
"code": "DomainResource"
30+
}
31+
]
32+
},
33+
{
34+
"id": "ExampleNotebook.identifier",
35+
"path": "ExampleNotebook.identifier",
36+
"min": 1,
37+
"max": "1",
38+
"short": "Unique identifier for the notebook entry",
39+
"type": [
40+
{
41+
"code": "Identifier"
42+
}
43+
]
44+
},
45+
{
46+
"id": "ExampleNotebook.title",
47+
"path": "ExampleNotebook.title",
48+
"min": 1,
49+
"max": "1",
50+
"short": "Human readable title",
51+
"type": [
52+
{
53+
"code": "string"
54+
}
55+
]
56+
},
57+
{
58+
"id": "ExampleNotebook.author",
59+
"path": "ExampleNotebook.author",
60+
"min": 1,
61+
"max": "1",
62+
"short": "Reference to the author of the notebook entry",
63+
"type": [
64+
{
65+
"code": "Reference",
66+
"targetProfile": [
67+
"http://hl7.org/fhir/StructureDefinition/Practitioner",
68+
"http://hl7.org/fhir/StructureDefinition/Patient"
69+
]
70+
}
71+
]
72+
},
73+
{
74+
"id": "ExampleNotebook.content",
75+
"path": "ExampleNotebook.content",
76+
"min": 1,
77+
"max": "1",
78+
"short": "Markdown content of the notebook entry",
79+
"type": [
80+
{
81+
"code": "markdown"
82+
}
83+
]
84+
},
85+
{
86+
"id": "ExampleNotebook.tag",
87+
"path": "ExampleNotebook.tag",
88+
"min": 0,
89+
"max": "*",
90+
"short": "User defined tags",
91+
"type": [
92+
{
93+
"code": "Coding"
94+
}
95+
]
96+
}
97+
]
98+
},
99+
"differential": {
100+
"element": [
101+
{
102+
"id": "ExampleNotebook",
103+
"path": "ExampleNotebook",
104+
"short": "Example logical notebook resource",
105+
"definition": "A lightweight notebook entry capturing author, title, and content.",
106+
"min": 0,
107+
"max": "*"
108+
},
109+
{
110+
"id": "ExampleNotebook.identifier",
111+
"path": "ExampleNotebook.identifier",
112+
"min": 1,
113+
"max": "1",
114+
"short": "Unique identifier for the notebook entry",
115+
"type": [
116+
{
117+
"code": "Identifier"
118+
}
119+
]
120+
},
121+
{
122+
"id": "ExampleNotebook.title",
123+
"path": "ExampleNotebook.title",
124+
"min": 1,
125+
"max": "1",
126+
"short": "Human readable title",
127+
"type": [
128+
{
129+
"code": "string"
130+
}
131+
]
132+
},
133+
{
134+
"id": "ExampleNotebook.author",
135+
"path": "ExampleNotebook.author",
136+
"min": 1,
137+
"max": "1",
138+
"short": "Reference to the author",
139+
"type": [
140+
{
141+
"code": "Reference",
142+
"targetProfile": [
143+
"http://hl7.org/fhir/StructureDefinition/Practitioner",
144+
"http://hl7.org/fhir/StructureDefinition/Patient"
145+
]
146+
}
147+
]
148+
},
149+
{
150+
"id": "ExampleNotebook.content",
151+
"path": "ExampleNotebook.content",
152+
"min": 1,
153+
"max": "1",
154+
"short": "Markdown content of the notebook entry",
155+
"type": [
156+
{
157+
"code": "markdown"
158+
}
159+
]
160+
},
161+
{
162+
"id": "ExampleNotebook.tag",
163+
"path": "ExampleNotebook.tag",
164+
"min": 0,
165+
"max": "*",
166+
"short": "User defined tags",
167+
"type": [
168+
{
169+
"code": "Coding"
170+
}
171+
]
172+
}
173+
]
174+
}
175+
}

examples/typescript-sql-on-fhir/generate.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { APIBuilder } from "../../src/api/builder";
33
const builder = new APIBuilder()
44
.throwException()
55
.typescript({ withDebugComment: false, generateProfile: false })
6-
.fromPackageRef("https://build.fhir.org/ig/FHIR/sql-on-fhir-v2//package.tgz")
6+
.fromPackageRef("https://build.fhir.org/ig/FHIR/sql-on-fhir-v2/package.tgz")
77
.outputTo("./examples/typescript-sql-on-fhir/fhir-types")
88
.writeTypeTree("./examples/typescript-sql-on-fhir/tree.yaml")
99
.treeShake({

package.json

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,19 +62,20 @@
6262
},
6363
"homepage": "https://github.com/atomic-ehr/codegen#readme",
6464
"dependencies": {
65-
"@atomic-ehr/fhir-canonical-manager": "^0.0.15",
65+
"@atomic-ehr/fhir-canonical-manager": "canary",
6666
"@atomic-ehr/fhirschema": "^0.0.5",
6767
"picocolors": "^1.1.1",
68-
"yaml": "^2.8.1",
68+
"tinyglobby": "^0.2.15",
69+
"yaml": "^2.8.2",
6970
"yargs": "^18.0.0"
7071
},
7172
"devDependencies": {
72-
"@biomejs/biome": "^2.1.4",
73-
"@types/bun": "^1.2.23",
74-
"@types/node": "^22.17.1",
75-
"@types/yargs": "^17.0.33",
76-
"knip": "^5.27.2",
73+
"@biomejs/biome": "^2.3.9",
74+
"@types/bun": "^1.3.4",
75+
"@types/node": "^22.19.3",
76+
"@types/yargs": "^17.0.35",
77+
"knip": "^5.73.4",
7778
"tsup": "^8.5.1",
78-
"typescript": "^5.9.2"
79+
"typescript": "^5.9.3"
7980
}
8081
}

0 commit comments

Comments
 (0)