@atomic-ehr/codegen 0.0.1-canary.20251006070905.fb6ed98 → 0.0.1-canary.20251006094042.7f0be72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +45 -124
- package/dist/index.d.ts +2130 -62
- package/dist/index.js +5865 -84
- package/dist/index.js.map +1 -0
- package/package.json +3 -7
- package/dist/api/builder.d.ts +0 -154
- package/dist/api/builder.js +0 -341
- package/dist/api/generators/base/BaseGenerator.d.ts +0 -186
- package/dist/api/generators/base/BaseGenerator.js +0 -565
- package/dist/api/generators/base/FileManager.d.ts +0 -88
- package/dist/api/generators/base/FileManager.js +0 -202
- package/dist/api/generators/base/PythonTypeMapper.d.ts +0 -16
- package/dist/api/generators/base/PythonTypeMapper.js +0 -71
- package/dist/api/generators/base/TemplateEngine.d.ts +0 -126
- package/dist/api/generators/base/TemplateEngine.js +0 -133
- package/dist/api/generators/base/TypeMapper.d.ts +0 -129
- package/dist/api/generators/base/TypeMapper.js +0 -153
- package/dist/api/generators/base/TypeScriptTypeMapper.d.ts +0 -51
- package/dist/api/generators/base/TypeScriptTypeMapper.js +0 -232
- package/dist/api/generators/base/builders/DirectoryBuilder.d.ts +0 -99
- package/dist/api/generators/base/builders/DirectoryBuilder.js +0 -215
- package/dist/api/generators/base/builders/FileBuilder.d.ts +0 -160
- package/dist/api/generators/base/builders/FileBuilder.js +0 -406
- package/dist/api/generators/base/builders/IndexBuilder.d.ts +0 -126
- package/dist/api/generators/base/builders/IndexBuilder.js +0 -290
- package/dist/api/generators/base/enhanced-errors.d.ts +0 -84
- package/dist/api/generators/base/enhanced-errors.js +0 -259
- package/dist/api/generators/base/error-handler.d.ts +0 -89
- package/dist/api/generators/base/error-handler.js +0 -243
- package/dist/api/generators/base/errors.d.ts +0 -251
- package/dist/api/generators/base/errors.js +0 -692
- package/dist/api/generators/base/index.d.ts +0 -99
- package/dist/api/generators/base/index.js +0 -160
- package/dist/api/generators/base/types.d.ts +0 -433
- package/dist/api/generators/base/types.js +0 -12
- package/dist/api/generators/types.d.ts +0 -53
- package/dist/api/generators/types.js +0 -4
- package/dist/api/generators/typescript.d.ts +0 -190
- package/dist/api/generators/typescript.js +0 -819
- package/dist/api/index.d.ts +0 -51
- package/dist/api/index.js +0 -50
- package/dist/cli/commands/generate/typescript.d.ts +0 -10
- package/dist/cli/commands/generate/typescript.js +0 -52
- package/dist/cli/commands/generate.d.ts +0 -15
- package/dist/cli/commands/generate.js +0 -159
- package/dist/cli/commands/index.d.ts +0 -29
- package/dist/cli/commands/index.js +0 -100
- package/dist/cli/commands/typeschema/generate.d.ts +0 -19
- package/dist/cli/commands/typeschema/generate.js +0 -124
- package/dist/cli/commands/typeschema.d.ts +0 -10
- package/dist/cli/commands/typeschema.js +0 -47
- package/dist/cli/index.d.ts +0 -9
- package/dist/cli/utils/log.d.ts +0 -10
- package/dist/cli/utils/log.js +0 -23
- package/dist/cli/utils/prompts.d.ts +0 -56
- package/dist/cli/utils/prompts.js +0 -202
- package/dist/cli/utils/spinner.d.ts +0 -110
- package/dist/cli/utils/spinner.js +0 -266
- package/dist/config.d.ts +0 -217
- package/dist/config.js +0 -591
- package/dist/logger.d.ts +0 -157
- package/dist/logger.js +0 -281
- package/dist/typeschema/cache.d.ts +0 -80
- package/dist/typeschema/cache.js +0 -239
- package/dist/typeschema/core/binding.d.ts +0 -11
- package/dist/typeschema/core/binding.js +0 -143
- package/dist/typeschema/core/field-builder.d.ts +0 -12
- package/dist/typeschema/core/field-builder.js +0 -123
- package/dist/typeschema/core/identifier.d.ts +0 -13
- package/dist/typeschema/core/identifier.js +0 -94
- package/dist/typeschema/core/nested-types.d.ts +0 -9
- package/dist/typeschema/core/nested-types.js +0 -94
- package/dist/typeschema/core/transformer.d.ts +0 -11
- package/dist/typeschema/core/transformer.js +0 -235
- package/dist/typeschema/generator.d.ts +0 -43
- package/dist/typeschema/generator.js +0 -264
- package/dist/typeschema/index.d.ts +0 -15
- package/dist/typeschema/index.js +0 -15
- package/dist/typeschema/parser.d.ts +0 -79
- package/dist/typeschema/parser.js +0 -274
- package/dist/typeschema/profile/processor.d.ts +0 -14
- package/dist/typeschema/profile/processor.js +0 -262
- package/dist/typeschema/register.d.ts +0 -21
- package/dist/typeschema/register.js +0 -117
- package/dist/typeschema/types.d.ts +0 -240
- package/dist/typeschema/types.js +0 -19
- package/dist/utils/codegen-logger.d.ts +0 -102
- package/dist/utils/codegen-logger.js +0 -196
- package/dist/utils.d.ts +0 -22
- package/dist/utils.js +0 -42
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TypeSchema Parser
|
|
3
|
-
*
|
|
4
|
-
* Parser for reading and manipulating TypeSchema documents from various formats.
|
|
5
|
-
* Supports both NDJSON and JSON formats with automatic format detection.
|
|
6
|
-
*/
|
|
7
|
-
import type { Identifier, TypeSchema, TypeschemaParserOptions } from "@typeschema/types";
|
|
8
|
-
/**
|
|
9
|
-
* TypeSchema Parser class
|
|
10
|
-
*
|
|
11
|
-
* Provides functionality to read, parse, and manipulate TypeSchema documents
|
|
12
|
-
* from files or strings in various formats.
|
|
13
|
-
*/
|
|
14
|
-
export declare class TypeSchemaParser {
|
|
15
|
-
private options;
|
|
16
|
-
constructor(options?: TypeschemaParserOptions);
|
|
17
|
-
/**
|
|
18
|
-
* Parse TypeSchema from file
|
|
19
|
-
*/
|
|
20
|
-
parseFromFile(filePath: string): Promise<TypeSchema[]>;
|
|
21
|
-
/**
|
|
22
|
-
* Parse TypeSchema from string content
|
|
23
|
-
*/
|
|
24
|
-
parseFromString(content: string, format?: "ndjson" | "json"): Promise<TypeSchema[]>;
|
|
25
|
-
/**
|
|
26
|
-
* Parse multiple TypeSchema files
|
|
27
|
-
*/
|
|
28
|
-
parseFromFiles(filePaths: string[]): Promise<TypeSchema[]>;
|
|
29
|
-
/**
|
|
30
|
-
* Parse a single TypeSchema object
|
|
31
|
-
*/
|
|
32
|
-
parseSchema(schemaData: any): TypeSchema;
|
|
33
|
-
/**
|
|
34
|
-
* Find schemas by identifier
|
|
35
|
-
*/
|
|
36
|
-
findByIdentifier(schemas: TypeSchema[], identifier: Partial<Identifier>): TypeSchema[];
|
|
37
|
-
/**
|
|
38
|
-
* Find schema by URL
|
|
39
|
-
*/
|
|
40
|
-
findByUrl(schemas: TypeSchema[], url: string): TypeSchema | undefined;
|
|
41
|
-
/**
|
|
42
|
-
* Find schemas by kind
|
|
43
|
-
*/
|
|
44
|
-
findByKind(schemas: TypeSchema[], kind: Identifier["kind"]): TypeSchema[];
|
|
45
|
-
/**
|
|
46
|
-
* Find schemas by package
|
|
47
|
-
*/
|
|
48
|
-
findByPackage(schemas: TypeSchema[], packageName: string): TypeSchema[];
|
|
49
|
-
/**
|
|
50
|
-
* Get all dependencies from a schema
|
|
51
|
-
*/
|
|
52
|
-
/**
|
|
53
|
-
* Resolve schema dependencies
|
|
54
|
-
*/
|
|
55
|
-
/**
|
|
56
|
-
* Detect format from content or filename
|
|
57
|
-
*/
|
|
58
|
-
private detectFormat;
|
|
59
|
-
/**
|
|
60
|
-
* Parse NDJSON format
|
|
61
|
-
*/
|
|
62
|
-
private parseNDJSON;
|
|
63
|
-
/**
|
|
64
|
-
* Parse JSON format
|
|
65
|
-
*/
|
|
66
|
-
private parseJSON;
|
|
67
|
-
/**
|
|
68
|
-
* Validate schemas
|
|
69
|
-
*/
|
|
70
|
-
private validateSchemas;
|
|
71
|
-
/**
|
|
72
|
-
* Validate identifier structure
|
|
73
|
-
*/
|
|
74
|
-
private isValidIdentifier;
|
|
75
|
-
/**
|
|
76
|
-
* Check if identifier matches criteria
|
|
77
|
-
*/
|
|
78
|
-
private matchesIdentifier;
|
|
79
|
-
}
|
|
@@ -1,274 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TypeSchema Parser
|
|
3
|
-
*
|
|
4
|
-
* Parser for reading and manipulating TypeSchema documents from various formats.
|
|
5
|
-
* Supports both NDJSON and JSON formats with automatic format detection.
|
|
6
|
-
*/
|
|
7
|
-
import { readFile } from "node:fs/promises";
|
|
8
|
-
/**
|
|
9
|
-
* TypeSchema Parser class
|
|
10
|
-
*
|
|
11
|
-
* Provides functionality to read, parse, and manipulate TypeSchema documents
|
|
12
|
-
* from files or strings in various formats.
|
|
13
|
-
*/
|
|
14
|
-
export class TypeSchemaParser {
|
|
15
|
-
options;
|
|
16
|
-
constructor(options = {}) {
|
|
17
|
-
this.options = {
|
|
18
|
-
format: "auto",
|
|
19
|
-
validate: true,
|
|
20
|
-
strict: false,
|
|
21
|
-
...options,
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Parse TypeSchema from file
|
|
26
|
-
*/
|
|
27
|
-
async parseFromFile(filePath) {
|
|
28
|
-
const content = await readFile(filePath, "utf-8");
|
|
29
|
-
const format = this.options.format === "auto" ? this.detectFormat(content, filePath) : this.options.format;
|
|
30
|
-
return this.parseFromString(content, format);
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Parse TypeSchema from string content
|
|
34
|
-
*/
|
|
35
|
-
async parseFromString(content, format) {
|
|
36
|
-
const actualFormat = format || this.detectFormat(content);
|
|
37
|
-
let schemas;
|
|
38
|
-
if (actualFormat === "ndjson") {
|
|
39
|
-
schemas = this.parseNDJSON(content);
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
-
schemas = this.parseJSON(content);
|
|
43
|
-
}
|
|
44
|
-
if (this.options.validate) {
|
|
45
|
-
this.validateSchemas(schemas);
|
|
46
|
-
}
|
|
47
|
-
return schemas;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Parse multiple TypeSchema files
|
|
51
|
-
*/
|
|
52
|
-
async parseFromFiles(filePaths) {
|
|
53
|
-
const allSchemas = [];
|
|
54
|
-
for (const filePath of filePaths) {
|
|
55
|
-
const schemas = await this.parseFromFile(filePath);
|
|
56
|
-
allSchemas.push(...schemas);
|
|
57
|
-
}
|
|
58
|
-
return allSchemas;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Parse a single TypeSchema object
|
|
62
|
-
*/
|
|
63
|
-
parseSchema(schemaData) {
|
|
64
|
-
// Basic validation of required fields
|
|
65
|
-
if (!schemaData.identifier) {
|
|
66
|
-
throw new Error("TypeSchema must have an identifier");
|
|
67
|
-
}
|
|
68
|
-
if (!this.isValidIdentifier(schemaData.identifier)) {
|
|
69
|
-
throw new Error("TypeSchema identifier is invalid");
|
|
70
|
-
}
|
|
71
|
-
// Return the schema (assuming it's already in correct format)
|
|
72
|
-
// Additional validation would be performed by the validator
|
|
73
|
-
return schemaData;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Find schemas by identifier
|
|
77
|
-
*/
|
|
78
|
-
findByIdentifier(schemas, identifier) {
|
|
79
|
-
return schemas.filter((schema) => this.matchesIdentifier(schema.identifier, identifier));
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Find schema by URL
|
|
83
|
-
*/
|
|
84
|
-
findByUrl(schemas, url) {
|
|
85
|
-
return schemas.find((schema) => schema.identifier.url === url);
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Find schemas by kind
|
|
89
|
-
*/
|
|
90
|
-
findByKind(schemas, kind) {
|
|
91
|
-
return schemas.filter((schema) => schema.identifier.kind === kind);
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Find schemas by package
|
|
95
|
-
*/
|
|
96
|
-
findByPackage(schemas, packageName) {
|
|
97
|
-
return schemas.filter((schema) => schema.identifier.package === packageName);
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Get all dependencies from a schema
|
|
101
|
-
*/
|
|
102
|
-
// getDependencies(schema: TypeSchema): Identifier[] {
|
|
103
|
-
// const dependencies: Identifier[] = [];
|
|
104
|
-
// // Add base dependency
|
|
105
|
-
// if ("base" in schema && schema.base) {
|
|
106
|
-
// dependencies.push(schema.base);
|
|
107
|
-
// }
|
|
108
|
-
// // Add explicit dependencies
|
|
109
|
-
// if ("dependencies" in schema && schema.dependencies) {
|
|
110
|
-
// dependencies.push(...schema.dependencies);
|
|
111
|
-
// }
|
|
112
|
-
// // Add field type dependencies
|
|
113
|
-
// if ("fields" in schema && schema.fields) {
|
|
114
|
-
// for (const field of Object.values(schema.fields)) {
|
|
115
|
-
// if ("type" in field && field.type) {
|
|
116
|
-
// dependencies.push(field.type);
|
|
117
|
-
// }
|
|
118
|
-
// if ("binding" in field && field.binding) {
|
|
119
|
-
// dependencies.push(field.binding);
|
|
120
|
-
// }
|
|
121
|
-
// if ("reference" in field && field.reference) {
|
|
122
|
-
// dependencies.push(...field.reference);
|
|
123
|
-
// }
|
|
124
|
-
// }
|
|
125
|
-
// }
|
|
126
|
-
// if ("nested" in schema && schema.nested) {
|
|
127
|
-
// for (const nested of schema.nested) {
|
|
128
|
-
// dependencies.push(nested.identifier);
|
|
129
|
-
// dependencies.push(nested.base);
|
|
130
|
-
// for (const field of Object.values(nested.fields)) {
|
|
131
|
-
// if ("type" in field && field.type) {
|
|
132
|
-
// dependencies.push(field.type);
|
|
133
|
-
// }
|
|
134
|
-
// if ("binding" in field && field.binding) {
|
|
135
|
-
// dependencies.push(field.binding);
|
|
136
|
-
// }
|
|
137
|
-
// if ("reference" in field && field.reference) {
|
|
138
|
-
// dependencies.push(...field.reference);
|
|
139
|
-
// }
|
|
140
|
-
// }
|
|
141
|
-
// }
|
|
142
|
-
// }
|
|
143
|
-
// // Add binding dependencies
|
|
144
|
-
// if ("valueset" in schema) {
|
|
145
|
-
// const bindingSchema = schema as any;
|
|
146
|
-
// dependencies.push(bindingSchema.valueset);
|
|
147
|
-
// if (bindingSchema.type) {
|
|
148
|
-
// dependencies.push(bindingSchema.type);
|
|
149
|
-
// }
|
|
150
|
-
// }
|
|
151
|
-
// // Remove duplicates
|
|
152
|
-
// return this.deduplicateDependencies(dependencies);
|
|
153
|
-
// }
|
|
154
|
-
/**
|
|
155
|
-
* Resolve schema dependencies
|
|
156
|
-
*/
|
|
157
|
-
// resolveDependencies(
|
|
158
|
-
// schemas: TypeSchema[],
|
|
159
|
-
// targetSchema: TypeSchema,
|
|
160
|
-
// ): TypeSchema[] {
|
|
161
|
-
// const dependencies = this.getDependencies(targetSchema);
|
|
162
|
-
// const resolved: TypeSchema[] = [];
|
|
163
|
-
// for (const dep of dependencies) {
|
|
164
|
-
// const depSchema = this.findByUrl(schemas, dep.url);
|
|
165
|
-
// if (depSchema) {
|
|
166
|
-
// resolved.push(depSchema);
|
|
167
|
-
// }
|
|
168
|
-
// }
|
|
169
|
-
// return resolved;
|
|
170
|
-
// }
|
|
171
|
-
/**
|
|
172
|
-
* Detect format from content or filename
|
|
173
|
-
*/
|
|
174
|
-
detectFormat(content, filename) {
|
|
175
|
-
// Check file extension first
|
|
176
|
-
if (filename) {
|
|
177
|
-
if (filename.endsWith(".ndjson"))
|
|
178
|
-
return "ndjson";
|
|
179
|
-
if (filename.endsWith(".json"))
|
|
180
|
-
return "json";
|
|
181
|
-
}
|
|
182
|
-
// Check content format
|
|
183
|
-
const trimmed = content.trim();
|
|
184
|
-
// NDJSON typically has multiple lines with JSON objects
|
|
185
|
-
if (trimmed.includes("\n")) {
|
|
186
|
-
const lines = trimmed.split("\n").filter((line) => line.trim());
|
|
187
|
-
if (lines.length > 1) {
|
|
188
|
-
try {
|
|
189
|
-
if (lines[0]) {
|
|
190
|
-
JSON.parse(lines[0]);
|
|
191
|
-
}
|
|
192
|
-
return "ndjson";
|
|
193
|
-
}
|
|
194
|
-
catch {
|
|
195
|
-
// Fall through to JSON detection
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
// Default to JSON for single objects or arrays
|
|
200
|
-
return "json";
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Parse NDJSON format
|
|
204
|
-
*/
|
|
205
|
-
parseNDJSON(content) {
|
|
206
|
-
const schemas = [];
|
|
207
|
-
const lines = content.split("\n").filter((line) => line.trim());
|
|
208
|
-
for (const line of lines) {
|
|
209
|
-
try {
|
|
210
|
-
const parsed = JSON.parse(line);
|
|
211
|
-
schemas.push(this.parseSchema(parsed));
|
|
212
|
-
}
|
|
213
|
-
catch (error) {
|
|
214
|
-
if (this.options.strict) {
|
|
215
|
-
throw new Error(`Failed to parse NDJSON line: ${error}`);
|
|
216
|
-
}
|
|
217
|
-
// Skip invalid lines in non-strict mode
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
return schemas;
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* Parse JSON format
|
|
224
|
-
*/
|
|
225
|
-
parseJSON(content) {
|
|
226
|
-
try {
|
|
227
|
-
const parsed = JSON.parse(content);
|
|
228
|
-
if (Array.isArray(parsed)) {
|
|
229
|
-
return parsed.map((item) => this.parseSchema(item));
|
|
230
|
-
}
|
|
231
|
-
else {
|
|
232
|
-
return [this.parseSchema(parsed)];
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
catch (error) {
|
|
236
|
-
throw new Error(`Failed to parse JSON: ${error}`);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
/**
|
|
240
|
-
* Validate schemas
|
|
241
|
-
*/
|
|
242
|
-
validateSchemas(schemas) {
|
|
243
|
-
for (const schema of schemas) {
|
|
244
|
-
if (!schema.identifier) {
|
|
245
|
-
throw new Error("Schema missing identifier");
|
|
246
|
-
}
|
|
247
|
-
if (!this.isValidIdentifier(schema.identifier)) {
|
|
248
|
-
throw new Error(`Invalid identifier in schema: ${JSON.stringify(schema.identifier)}`);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Validate identifier structure
|
|
254
|
-
*/
|
|
255
|
-
isValidIdentifier(identifier) {
|
|
256
|
-
return (typeof identifier === "object" &&
|
|
257
|
-
identifier !== null &&
|
|
258
|
-
typeof identifier.kind === "string" &&
|
|
259
|
-
typeof identifier.package === "string" &&
|
|
260
|
-
typeof identifier.version === "string" &&
|
|
261
|
-
typeof identifier.name === "string" &&
|
|
262
|
-
typeof identifier.url === "string");
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Check if identifier matches criteria
|
|
266
|
-
*/
|
|
267
|
-
matchesIdentifier(identifier, criteria) {
|
|
268
|
-
return ((!criteria.kind || identifier.kind === criteria.kind) &&
|
|
269
|
-
(!criteria.package || identifier.package === criteria.package) &&
|
|
270
|
-
(!criteria.version || identifier.version === criteria.version) &&
|
|
271
|
-
(!criteria.name || identifier.name === criteria.name) &&
|
|
272
|
-
(!criteria.url || identifier.url === criteria.url));
|
|
273
|
-
}
|
|
274
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Profile Processor (DEPRECATED - Profiles not in core TypeSchema spec)
|
|
3
|
-
*
|
|
4
|
-
* Handles transformation of FHIR profiles to TypeSchema format
|
|
5
|
-
* This file is deprecated as profiles are not part of the core TypeSchema specification
|
|
6
|
-
*/
|
|
7
|
-
import type { Register } from "@root/typeschema/register";
|
|
8
|
-
import type { RichFHIRSchema } from "@typeschema/types";
|
|
9
|
-
import type { ProfileTypeSchema } from "../types";
|
|
10
|
-
/**
|
|
11
|
-
* Transform a FHIR profile to TypeSchema format
|
|
12
|
-
* Profiles are treated as specialized resources that extend base resources
|
|
13
|
-
*/
|
|
14
|
-
export declare function transformProfile(register: Register, fhirSchema: RichFHIRSchema): Promise<ProfileTypeSchema>;
|
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Profile Processor (DEPRECATED - Profiles not in core TypeSchema spec)
|
|
3
|
-
*
|
|
4
|
-
* Handles transformation of FHIR profiles to TypeSchema format
|
|
5
|
-
* This file is deprecated as profiles are not part of the core TypeSchema specification
|
|
6
|
-
*/
|
|
7
|
-
import { mkIdentifier } from "../core/identifier";
|
|
8
|
-
import { mkFields } from "../core/transformer";
|
|
9
|
-
/**
|
|
10
|
-
* Transform a FHIR profile to TypeSchema format
|
|
11
|
-
* Profiles are treated as specialized resources that extend base resources
|
|
12
|
-
*/
|
|
13
|
-
export async function transformProfile(register, fhirSchema) {
|
|
14
|
-
// Build profile identifier
|
|
15
|
-
const identifier = mkIdentifier(fhirSchema);
|
|
16
|
-
const _packageInfo = fhirSchema.package_meta;
|
|
17
|
-
// Ensure this is recognized as a profile
|
|
18
|
-
if (identifier.kind !== "profile") {
|
|
19
|
-
throw new Error(`Expected profile, got ${identifier.kind} for ${fhirSchema.name}`);
|
|
20
|
-
}
|
|
21
|
-
// Build base identifier - profiles always have a base
|
|
22
|
-
let base;
|
|
23
|
-
if (fhirSchema.base) {
|
|
24
|
-
const baseUrl = fhirSchema.base.includes("/")
|
|
25
|
-
? fhirSchema.base
|
|
26
|
-
: `http://hl7.org/fhir/StructureDefinition/${fhirSchema.base}`;
|
|
27
|
-
const baseName = fhirSchema.base.split("/").pop() || fhirSchema.base;
|
|
28
|
-
// Determine base kind - could be another profile or a base resource
|
|
29
|
-
const baseKind = await determineBaseKind(baseUrl, register);
|
|
30
|
-
// For standard FHIR types, use the standard package
|
|
31
|
-
const isStandardFhir = baseUrl.startsWith("http://hl7.org/fhir/");
|
|
32
|
-
base = {
|
|
33
|
-
kind: baseKind,
|
|
34
|
-
package: isStandardFhir ? "hl7.fhir.r4.core" : fhirSchema.package_meta.name || "undefined",
|
|
35
|
-
version: isStandardFhir ? "4.0.1" : fhirSchema.package_meta.version || "undefined",
|
|
36
|
-
name: baseName,
|
|
37
|
-
url: baseUrl,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
// Initialize the profile schema
|
|
41
|
-
const profileSchema = {
|
|
42
|
-
identifier,
|
|
43
|
-
base: base,
|
|
44
|
-
dependencies: base ? [base] : [],
|
|
45
|
-
};
|
|
46
|
-
// Add description if present
|
|
47
|
-
if (fhirSchema.description) {
|
|
48
|
-
profileSchema.description = fhirSchema.description;
|
|
49
|
-
}
|
|
50
|
-
// Add profile-specific metadata
|
|
51
|
-
const metadata = extractProfileMetadata(fhirSchema);
|
|
52
|
-
if (Object.keys(metadata).length > 0) {
|
|
53
|
-
profileSchema.metadata = metadata;
|
|
54
|
-
}
|
|
55
|
-
// Process profile fields from differential elements
|
|
56
|
-
if (fhirSchema.elements) {
|
|
57
|
-
const fields = await mkFields(register, fhirSchema, [], fhirSchema.elements);
|
|
58
|
-
if (fields && Object.keys(fields).length > 0) {
|
|
59
|
-
profileSchema.fields = fields;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
// Process profile constraints
|
|
63
|
-
const constraints = await processProfileConstraints(fhirSchema, register);
|
|
64
|
-
if (Object.keys(constraints).length > 0) {
|
|
65
|
-
profileSchema.constraints = constraints;
|
|
66
|
-
}
|
|
67
|
-
// Process extensions
|
|
68
|
-
const extensions = await processProfileExtensions(fhirSchema, register);
|
|
69
|
-
if (extensions.length > 0) {
|
|
70
|
-
profileSchema.extensions = extensions;
|
|
71
|
-
}
|
|
72
|
-
// Add validation rules
|
|
73
|
-
const validationRules = extractValidationRules(fhirSchema);
|
|
74
|
-
if (validationRules.length > 0) {
|
|
75
|
-
profileSchema.validation = validationRules;
|
|
76
|
-
}
|
|
77
|
-
return profileSchema;
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Determine the kind of the base type for a profile
|
|
81
|
-
*/
|
|
82
|
-
async function determineBaseKind(baseUrl, register) {
|
|
83
|
-
try {
|
|
84
|
-
// Try to resolve the base schema
|
|
85
|
-
const baseSchema = register.resolveFs(baseUrl);
|
|
86
|
-
if (!baseSchema)
|
|
87
|
-
return "resource";
|
|
88
|
-
if (baseSchema) {
|
|
89
|
-
// If it's also a constraint, it's likely another profile
|
|
90
|
-
if (baseSchema.derivation === "constraint") {
|
|
91
|
-
return "profile";
|
|
92
|
-
}
|
|
93
|
-
// Otherwise, use the base schema's kind
|
|
94
|
-
if (baseSchema.kind === "resource")
|
|
95
|
-
return "resource";
|
|
96
|
-
if (baseSchema.kind === "complex-type")
|
|
97
|
-
return "complex-type";
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
catch (error) {
|
|
101
|
-
// If we can't resolve, make a reasonable guess
|
|
102
|
-
console.warn(`Could not resolve base schema ${baseUrl}:`, error);
|
|
103
|
-
}
|
|
104
|
-
// Check if the URL suggests it's a profile from any implementation guide
|
|
105
|
-
// Non-standard FHIR StructureDefinition URLs (not from base FHIR) are likely profiles
|
|
106
|
-
// Check if it's any other profile URL pattern
|
|
107
|
-
if (baseUrl.includes("StructureDefinition/") && !baseUrl.startsWith("http://hl7.org/fhir/StructureDefinition/")) {
|
|
108
|
-
// Non-standard FHIR StructureDefinition URLs are likely profiles
|
|
109
|
-
return "profile";
|
|
110
|
-
}
|
|
111
|
-
// Default to resource for profiles
|
|
112
|
-
return "resource";
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Extract profile metadata from FHIR schema
|
|
116
|
-
*/
|
|
117
|
-
function extractProfileMetadata(fhirSchema) {
|
|
118
|
-
const metadata = {};
|
|
119
|
-
const packageInfo = fhirSchema.package_meta;
|
|
120
|
-
// Add profile-specific metadata
|
|
121
|
-
// @ts-ignore
|
|
122
|
-
if (fhirSchema.publisher)
|
|
123
|
-
metadata.publisher = fhirSchema.publisher;
|
|
124
|
-
// @ts-ignore
|
|
125
|
-
if (fhirSchema.contact)
|
|
126
|
-
metadata.contact = fhirSchema.contact;
|
|
127
|
-
// @ts-ignore
|
|
128
|
-
if (fhirSchema.copyright)
|
|
129
|
-
metadata.copyright = fhirSchema.copyright;
|
|
130
|
-
// @ts-ignore
|
|
131
|
-
if (fhirSchema.purpose)
|
|
132
|
-
metadata.purpose = fhirSchema.purpose;
|
|
133
|
-
// @ts-ignore
|
|
134
|
-
if (fhirSchema.experimental !== undefined) {
|
|
135
|
-
// @ts-ignore
|
|
136
|
-
metadata.experimental = fhirSchema.experimental;
|
|
137
|
-
}
|
|
138
|
-
// @ts-ignore
|
|
139
|
-
if (fhirSchema.date)
|
|
140
|
-
metadata.date = fhirSchema.date;
|
|
141
|
-
// @ts-ignore
|
|
142
|
-
if (fhirSchema.jurisdiction)
|
|
143
|
-
metadata.jurisdiction = fhirSchema.jurisdiction;
|
|
144
|
-
// Add package-specific metadata from packageInfo or schema
|
|
145
|
-
// @ts-ignore
|
|
146
|
-
if (packageInfo?.name) {
|
|
147
|
-
metadata.package = packageInfo.name;
|
|
148
|
-
// @ts-ignore
|
|
149
|
-
}
|
|
150
|
-
else if (fhirSchema.package_meta.name) {
|
|
151
|
-
// @ts-ignore
|
|
152
|
-
metadata.package = fhirSchema.package_meta.name;
|
|
153
|
-
}
|
|
154
|
-
return metadata;
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Process profile constraints from FHIR schema elements
|
|
158
|
-
*/
|
|
159
|
-
async function processProfileConstraints(fhirSchema, _manager) {
|
|
160
|
-
const constraints = {};
|
|
161
|
-
if (!fhirSchema.elements)
|
|
162
|
-
return constraints;
|
|
163
|
-
// Process each element for constraints
|
|
164
|
-
for (const [path, element] of Object.entries(fhirSchema.elements)) {
|
|
165
|
-
const elementConstraints = {};
|
|
166
|
-
// Cardinality constraints
|
|
167
|
-
if (element.min !== undefined)
|
|
168
|
-
elementConstraints.min = element.min;
|
|
169
|
-
if (element.max !== undefined)
|
|
170
|
-
elementConstraints.max = String(element.max);
|
|
171
|
-
// Must Support elements
|
|
172
|
-
if (element.mustSupport)
|
|
173
|
-
elementConstraints.mustSupport = true;
|
|
174
|
-
// Fixed values
|
|
175
|
-
// @ts-ignore
|
|
176
|
-
if (element.fixedValue !== undefined)
|
|
177
|
-
// @ts-ignore
|
|
178
|
-
elementConstraints.fixedValue = element.fixedValue;
|
|
179
|
-
// @ts-ignore
|
|
180
|
-
if (element.patternValue !== undefined)
|
|
181
|
-
// @ts-ignore
|
|
182
|
-
elementConstraints.patternValue = element.patternValue;
|
|
183
|
-
// Value set bindings
|
|
184
|
-
if (element.binding) {
|
|
185
|
-
elementConstraints.binding = {
|
|
186
|
-
strength: element.binding.strength,
|
|
187
|
-
valueSet: element.binding.valueSet ?? "",
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
// Type constraints
|
|
191
|
-
if (element.type && Array.isArray(element.type) && element.type.length > 0) {
|
|
192
|
-
elementConstraints.types = element.type.map((t) => {
|
|
193
|
-
const typeConstraint = { code: t.code };
|
|
194
|
-
if (t.profile)
|
|
195
|
-
typeConstraint.profile = t.profile;
|
|
196
|
-
if (t.targetProfile)
|
|
197
|
-
typeConstraint.targetProfile = t.targetProfile;
|
|
198
|
-
return typeConstraint;
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
// Slicing information
|
|
202
|
-
if (element.slicing) {
|
|
203
|
-
elementConstraints.slicing = {
|
|
204
|
-
discriminator: element.slicing.discriminator ?? [],
|
|
205
|
-
rules: String(element.slicing),
|
|
206
|
-
ordered: element.slicing.ordered,
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
if (Object.keys(elementConstraints).length > 0) {
|
|
210
|
-
constraints[path] = elementConstraints;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
return constraints;
|
|
214
|
-
}
|
|
215
|
-
/**
|
|
216
|
-
* Process profile extensions
|
|
217
|
-
*/
|
|
218
|
-
async function processProfileExtensions(fhirSchema, _manager) {
|
|
219
|
-
const extensions = [];
|
|
220
|
-
if (!fhirSchema.elements)
|
|
221
|
-
return extensions;
|
|
222
|
-
// Look for extension elements
|
|
223
|
-
for (const [path, element] of Object.entries(fhirSchema.elements)) {
|
|
224
|
-
if (path.includes("extension") && element.type && Array.isArray(element.type)) {
|
|
225
|
-
for (const type of element.type) {
|
|
226
|
-
if (type.code === "Extension" && type.profile) {
|
|
227
|
-
extensions.push({
|
|
228
|
-
path,
|
|
229
|
-
profile: type.profile,
|
|
230
|
-
min: element.min,
|
|
231
|
-
max: String(element.max),
|
|
232
|
-
mustSupport: element.mustSupport,
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
return extensions;
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* Extract validation rules from profile
|
|
242
|
-
*/
|
|
243
|
-
function extractValidationRules(fhirSchema) {
|
|
244
|
-
const rules = [];
|
|
245
|
-
if (!fhirSchema.elements)
|
|
246
|
-
return rules;
|
|
247
|
-
// Extract invariants and constraints
|
|
248
|
-
for (const [path, element] of Object.entries(fhirSchema.elements)) {
|
|
249
|
-
if (element.constraint && Array.isArray(element.constraint)) {
|
|
250
|
-
for (const constraint of element.constraint) {
|
|
251
|
-
rules.push({
|
|
252
|
-
path,
|
|
253
|
-
key: constraint.key,
|
|
254
|
-
severity: constraint.severity,
|
|
255
|
-
human: constraint.human,
|
|
256
|
-
expression: constraint.expression,
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
return rules;
|
|
262
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { CanonicalManager } from "@atomic-ehr/fhir-canonical-manager";
|
|
2
|
-
import type { FHIRSchema, FHIRSchemaElement, StructureDefinition } from "@atomic-ehr/fhirschema";
|
|
3
|
-
import type { CodegenLogger } from "@root/utils/codegen-logger";
|
|
4
|
-
import type { CanonicalUrl, Name, PackageMeta, RichFHIRSchema, RichValueSet } from "@typeschema/types";
|
|
5
|
-
export type Register = {
|
|
6
|
-
appendFs(fs: FHIRSchema): void;
|
|
7
|
-
ensureCanonicalUrl(name: string | Name | CanonicalUrl): CanonicalUrl;
|
|
8
|
-
resolveSd(canonicalUrl: CanonicalUrl): StructureDefinition | undefined;
|
|
9
|
-
resolveFs(canonicalUrl: CanonicalUrl): RichFHIRSchema | undefined;
|
|
10
|
-
resolveFsGenealogy(canonicalUrl: CanonicalUrl): RichFHIRSchema[];
|
|
11
|
-
allSd(): StructureDefinition[];
|
|
12
|
-
allFs(): RichFHIRSchema[];
|
|
13
|
-
allVs(): RichValueSet[];
|
|
14
|
-
resolveVs(canonicalUrl: CanonicalUrl): RichValueSet | undefined;
|
|
15
|
-
complexTypeDict(): Record<string, RichFHIRSchema>;
|
|
16
|
-
resolveAny(canonicalUrl: CanonicalUrl): any | undefined;
|
|
17
|
-
} & ReturnType<typeof CanonicalManager>;
|
|
18
|
-
export declare const registerFromManager: (manager: ReturnType<typeof CanonicalManager>, logger?: CodegenLogger, packageInfo?: PackageMeta) => Promise<Register>;
|
|
19
|
-
export declare const registerFromPackageMetas: (packageMetas: PackageMeta[], logger?: CodegenLogger) => Promise<Register>;
|
|
20
|
-
export declare const resolveFsElementGenealogy: (genealogy: RichFHIRSchema[], path: string[]) => FHIRSchemaElement[];
|
|
21
|
-
export declare function fsElementSnapshot(genealogy: FHIRSchemaElement[]): FHIRSchemaElement;
|