babelfhir-ts 1.0.13 → 1.0.14
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/out/generator/index.js +6 -3
- package/out/generator/interfaceGenerator.js +2 -10
- package/out/main.js +79 -32
- package/package.json +1 -1
package/out/generator/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import { generateValidateProfileFunction } from './validatorGenerator';
|
|
|
9
9
|
import { loadExamplesFromPackage, generateTestFile } from './testGenerator';
|
|
10
10
|
import { generateValueSetTypeScript, generateValueSetRegistry } from './valueSetGenerator.js';
|
|
11
11
|
import { logger } from '../logger';
|
|
12
|
+
import fhirInterfaceNames from './fhirInterfaces.json';
|
|
12
13
|
/** Ensure RandomSupport.ts exists in a generation output directory */
|
|
13
14
|
function ensureRandomSupportFile(dir) {
|
|
14
15
|
const filePath = path.join(dir, 'RandomSupport.ts');
|
|
@@ -63,12 +64,14 @@ async function processStructureDefinition(sd, ctx) {
|
|
|
63
64
|
if (profileIdToName?.has(baseResource)) {
|
|
64
65
|
baseResource = profileIdToName.get(baseResource);
|
|
65
66
|
}
|
|
66
|
-
if (
|
|
67
|
-
|
|
67
|
+
// Generic fallback: if baseResource isn't a known FHIR type, prefer the declared SD type (core resource)
|
|
68
|
+
const isFhirType = (name) => !!name && (name === 'FhirResource' || fhirInterfaceNames.includes(name));
|
|
69
|
+
if (!isFhirType(baseResource) && sd.type && isFhirType(sd.type)) {
|
|
70
|
+
baseResource = sd.type;
|
|
68
71
|
}
|
|
69
72
|
const parsed = await parseStructureDefinition(sd, fhirSourceHint, valueSetCodesMap);
|
|
70
73
|
if (!parsed.newFields.length) {
|
|
71
|
-
|
|
74
|
+
logger.log(`No new SD fields for ${interfaceName}, skipping.`);
|
|
72
75
|
return;
|
|
73
76
|
}
|
|
74
77
|
const aligned = alignFields(parsed.newFields, parsed.oldFields);
|
|
@@ -1518,12 +1518,7 @@ export function generateInterfaces(interfaceName, newFields, baseResource, baseF
|
|
|
1518
1518
|
}
|
|
1519
1519
|
if (baseResource && !isPrimitiveType(baseResource) && sanitizeIdentifier(baseResource) !== 'Base') {
|
|
1520
1520
|
const sanitizedBase = sanitizeIdentifier(baseResource);
|
|
1521
|
-
|
|
1522
|
-
if (/^coverage_de_/.test(sanitizedBase)) {
|
|
1523
|
-
// Treat as Coverage
|
|
1524
|
-
imports.add('Coverage');
|
|
1525
|
-
}
|
|
1526
|
-
else if (!isFhirType(sanitizedBase)) {
|
|
1521
|
+
if (!isFhirType(sanitizedBase)) {
|
|
1527
1522
|
// Check if this profile exists in our generated files
|
|
1528
1523
|
if (existingProfiles?.has(sanitizedBase)) {
|
|
1529
1524
|
customImports.add(sanitizedBase);
|
|
@@ -1583,10 +1578,7 @@ export function generateInterfaces(interfaceName, newFields, baseResource, baseF
|
|
|
1583
1578
|
if (baseResource && sanitizeIdentifier(baseResource) !== 'Base') {
|
|
1584
1579
|
const sanitizedBase = sanitizeIdentifier(baseResource);
|
|
1585
1580
|
// Ensure import of the base resource type
|
|
1586
|
-
if (
|
|
1587
|
-
imports.add('Coverage');
|
|
1588
|
-
}
|
|
1589
|
-
else if (!isFhirType(sanitizedBase)) {
|
|
1581
|
+
if (!isFhirType(sanitizedBase)) {
|
|
1590
1582
|
customImports.add(sanitizedBase);
|
|
1591
1583
|
}
|
|
1592
1584
|
else {
|
package/out/main.js
CHANGED
|
@@ -114,48 +114,94 @@ async function downloadPackage(packageSpec, registry) {
|
|
|
114
114
|
throw error;
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
|
+
function parseCliArgs(argv) {
|
|
118
|
+
const out = {
|
|
119
|
+
registry: 'https://packages.simplifier.net',
|
|
120
|
+
logLevel: 'none',
|
|
121
|
+
packageSpec: null,
|
|
122
|
+
flags: { noCache: false, noClasses: false, logLevel: 'none' },
|
|
123
|
+
positionals: []
|
|
124
|
+
};
|
|
125
|
+
for (let i = 0; i < argv.length; i++) {
|
|
126
|
+
const arg = argv[i];
|
|
127
|
+
if (arg === '--help' || arg === '-h' || arg === '--version' || arg === '-v' || arg === 'install') {
|
|
128
|
+
// Commands or special flags handled later as positionals to preserve order
|
|
129
|
+
out.positionals.push(arg);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (arg === '--no-cache') {
|
|
133
|
+
out.flags.noCache = true;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (arg === '--no-classes') {
|
|
137
|
+
out.flags.noClasses = true;
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
if (arg === '--log') {
|
|
141
|
+
const val = argv[i + 1];
|
|
142
|
+
if (!val || val.startsWith('-')) {
|
|
143
|
+
throw new Error('Missing value for --log');
|
|
144
|
+
}
|
|
145
|
+
if (!['none', 'console', 'file'].includes(val)) {
|
|
146
|
+
throw new Error(`Invalid --log value: ${val}. Must be: none, console, or file`);
|
|
147
|
+
}
|
|
148
|
+
out.logLevel = val;
|
|
149
|
+
out.flags.logLevel = out.logLevel;
|
|
150
|
+
i++;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
if (arg === '--package') {
|
|
154
|
+
const val = argv[i + 1];
|
|
155
|
+
if (!val || val.startsWith('-'))
|
|
156
|
+
throw new Error('Missing value for --package');
|
|
157
|
+
out.packageSpec = val;
|
|
158
|
+
i++;
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (arg === '--registry') {
|
|
162
|
+
const val = argv[i + 1];
|
|
163
|
+
if (!val || val.startsWith('-'))
|
|
164
|
+
throw new Error('Missing value for --registry');
|
|
165
|
+
out.registry = val;
|
|
166
|
+
i++;
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
// Anything else that doesn't start with -- is positional
|
|
170
|
+
if (!arg.startsWith('--')) {
|
|
171
|
+
out.positionals.push(arg);
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
// Unknown --flag -> keep as positional to trigger usage error later
|
|
175
|
+
out.positionals.push(arg);
|
|
176
|
+
}
|
|
177
|
+
return out;
|
|
178
|
+
}
|
|
117
179
|
async function run() {
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
if (registryIndex !== -1 && args[registryIndex + 1]) {
|
|
123
|
-
registry = args[registryIndex + 1];
|
|
180
|
+
const argv = process.argv.slice(2);
|
|
181
|
+
let parsed;
|
|
182
|
+
try {
|
|
183
|
+
parsed = parseCliArgs(argv);
|
|
124
184
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if (!['none', 'console', 'file'].includes(logLevel)) {
|
|
129
|
-
console.error(`Invalid --log value: ${logLevel}. Must be: none, console, or file`);
|
|
185
|
+
catch (e) {
|
|
186
|
+
console.error(`Error: ${e.message}`);
|
|
187
|
+
printUsage();
|
|
130
188
|
process.exit(1);
|
|
131
189
|
}
|
|
132
|
-
|
|
133
|
-
const packageIndex = args.indexOf('--package');
|
|
134
|
-
const packageSpec = packageIndex !== -1 && args[packageIndex + 1] ? args[packageIndex + 1] : null;
|
|
135
|
-
// Parse flags
|
|
136
|
-
const flags = {
|
|
137
|
-
noCache: args.includes('--no-cache'),
|
|
138
|
-
noClasses: args.includes('--no-classes'),
|
|
139
|
-
logLevel: logLevel
|
|
140
|
-
};
|
|
141
|
-
// Filter out flags to get positional arguments
|
|
142
|
-
const positionalArgs = args.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
|
|
143
|
-
let firstArg = args.find(arg => !arg.startsWith('--') || arg === '--help' || arg === '--version');
|
|
144
|
-
const secondArg = positionalArgs[1];
|
|
190
|
+
const { registry, packageSpec, flags, positionals } = parsed;
|
|
145
191
|
// Check for help flags
|
|
146
|
-
if (
|
|
192
|
+
if (positionals.includes('--help') || positionals.includes('-h')) {
|
|
147
193
|
printUsage();
|
|
148
194
|
process.exit(0);
|
|
149
195
|
}
|
|
150
196
|
// Check for version flag
|
|
151
|
-
if (
|
|
197
|
+
if (positionals.includes('--version') || positionals.includes('-v')) {
|
|
152
198
|
console.log(`babelfhir-ts version ${packageJson.version}`);
|
|
153
199
|
process.exit(0);
|
|
154
200
|
}
|
|
155
201
|
// Handle install command
|
|
156
|
-
if (
|
|
202
|
+
if (positionals[0] === 'install') {
|
|
157
203
|
// Package can come from --package flag OR as positional argument after 'install'
|
|
158
|
-
const packageToInstall = packageSpec ||
|
|
204
|
+
const packageToInstall = packageSpec || positionals[1];
|
|
159
205
|
if (!packageToInstall) {
|
|
160
206
|
console.error('Error: install command requires a package name');
|
|
161
207
|
console.error('Example: babelfhir-ts install de.gematik.isik-basismodul@3.1.0');
|
|
@@ -212,7 +258,7 @@ async function run() {
|
|
|
212
258
|
if (flags.noCache) {
|
|
213
259
|
cleanupCache();
|
|
214
260
|
}
|
|
215
|
-
console.log(`\n✓ Package ${
|
|
261
|
+
console.log(`\n✓ Package ${packageToInstall} installed and ready to use!`);
|
|
216
262
|
return;
|
|
217
263
|
}
|
|
218
264
|
catch (error) {
|
|
@@ -259,12 +305,11 @@ async function run() {
|
|
|
259
305
|
process.exit(1);
|
|
260
306
|
}
|
|
261
307
|
}
|
|
262
|
-
if (
|
|
308
|
+
if (positionals.length === 0) {
|
|
263
309
|
// Default: attempt input -> output
|
|
264
310
|
if (fs.existsSync('input') && fs.lstatSync('input').isDirectory()) {
|
|
265
|
-
firstArg = 'input';
|
|
266
311
|
const outputDir = 'output';
|
|
267
|
-
await generateForDirectory(
|
|
312
|
+
await generateForDirectory('input', outputDir, flags);
|
|
268
313
|
console.log(`Batch generation complete. Output in: ${outputDir}`);
|
|
269
314
|
if (flags.noCache) {
|
|
270
315
|
cleanupCache();
|
|
@@ -274,6 +319,8 @@ async function run() {
|
|
|
274
319
|
printError();
|
|
275
320
|
process.exit(1);
|
|
276
321
|
}
|
|
322
|
+
const firstArg = positionals[0];
|
|
323
|
+
const secondArg = positionals[1];
|
|
277
324
|
if (!fs.existsSync(firstArg)) {
|
|
278
325
|
console.error(`Path does not exist: ${firstArg}`);
|
|
279
326
|
console.error("Use --help for usage information");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "babelfhir-ts",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.14",
|
|
4
4
|
"description": "BabelFHIR-TS: generate TypeScript interfaces, validators, and helper classes from FHIR R4 StructureDefinitions (profiles) directly inside package archives.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "out/main.js",
|