babelfhir-ts 1.3.0 → 1.3.2

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/README.md CHANGED
@@ -17,9 +17,9 @@
17
17
 
18
18
  <!-- Tech Stack Badges -->
19
19
  <p align="center">
20
- <img src="https://img.shields.io/badge/TypeScript-5.8-3178c6?logo=typescript" alt="TypeScript">
20
+ <img src="https://img.shields.io/badge/TypeScript-6.0-3178c6?logo=typescript" alt="TypeScript">
21
21
  <img src="https://img.shields.io/badge/Node.js-18%2B-339933?logo=node.js" alt="Node.js">
22
- <img src="https://img.shields.io/badge/Zod-3.x-3068b7?logo=zod" alt="Zod">
22
+ <img src="https://img.shields.io/badge/Zod-4.x-3068b7?logo=zod" alt="Zod">
23
23
  </p>
24
24
 
25
25
  <!-- FHIR Client Packages -->
@@ -32,8 +32,7 @@
32
32
 
33
33
  <!-- Validation & Imaging Packages -->
34
34
  <p align="center">
35
- <a href="https://www.npmjs.com/package/@babelfhir-ts/zod-r4"><img src="https://img.shields.io/npm/v/@babelfhir-ts/zod-r4.svg?label=%40babelfhir-ts%2Fzod-r4" alt="zod-r4"></a>
36
- <a href="https://www.npmjs.com/package/@babelfhir-ts/zod-r4b"><img src="https://img.shields.io/npm/v/@babelfhir-ts/zod-r4b.svg?label=%40babelfhir-ts%2Fzod-r4b" alt="zod-r4b"></a>
35
+ <a href="https://www.npmjs.com/package/@babelfhir-ts/zod"><img src="https://img.shields.io/npm/v/@babelfhir-ts/zod.svg?label=%40babelfhir-ts%2Fzod" alt="zod"></a>
37
36
  <a href="https://www.npmjs.com/package/@babelfhir-ts/dicomweb"><img src="https://img.shields.io/npm/v/@babelfhir-ts/dicomweb.svg?label=%40babelfhir-ts%2Fdicomweb" alt="dicomweb"></a>
38
37
  </p>
39
38
 
@@ -11,7 +11,7 @@ export function generateClass(className, interfaceName, baseResource, requiredFi
11
11
  const resourceTypeLine = addResourceType && baseResource && baseResource !== 'Resource' ? `resourceType: '${baseResource}',` : (addResourceType ? `resourceType: 'Resource',` : '');
12
12
  // Only true FHIR Resources (not datatypes like Identifier, Attachment, Extension) can carry meta.profile.
13
13
  const enableMetaProfile = addResourceType && !!profileUrl;
14
- const constructorMetaProfile = enableMetaProfile ? `ensureProfile(this.resource, '${profileUrl}');` : '';
14
+ const constructorMetaProfile = enableMetaProfile ? `ensureProfile(this.resource as WithMeta, '${profileUrl}');` : '';
15
15
  const setterMetaProfile = constructorMetaProfile; // same logic
16
16
  const randomMetaProfileInit = enableMetaProfile ? `ensureProfile(base as WithMeta, '${profileUrl}');` : '// (no profileUrl provided or profile targets a datatype – meta.profile not applicable)';
17
17
  // Assemble required field initialisers (excluding id & resourceType)
@@ -35,8 +35,8 @@ const __require = createRequire(import.meta.url);` : ''}
35
35
 
36
36
  // Helper emitted only when meta.profile enforcement is applicable (resource profiles)
37
37
  ${enableMetaProfile ? `type WithMeta = { meta?: { profile?: string[] } };
38
- function ensureProfile<R extends WithMeta>(res: R, profile: string): void {
39
- if (!res.meta) { (res as WithMeta).meta = { profile: [profile] }; return; }
38
+ function ensureProfile(res: WithMeta, profile: string): void {
39
+ if (!res.meta) { res.meta = { profile: [profile] }; return; }
40
40
  if (!res.meta.profile) { res.meta.profile = [profile]; return; }
41
41
  if (!res.meta.profile.includes(profile)) { res.meta.profile = [...res.meta.profile, profile]; }
42
42
  }` : ''}
@@ -2,7 +2,7 @@
2
2
  * Generates Zod schemas from parsed FHIR StructureDefinition fields.
3
3
  * Follows the same Field[] → code string pattern as validatorGenerator.ts and interfaceGenerator.ts.
4
4
  *
5
- * Complex FHIR base types are imported from @babelfhir-ts/zod-<version>
5
+ * Complex FHIR base types are imported from @babelfhir-ts/zod/<version>
6
6
  * instead of being inlined, mirroring the @babelfhir-ts/client-<version> pattern.
7
7
  */
8
8
  import { sanitizeValueSetName } from '../valueset/valueSetGenerator.js';
@@ -217,11 +217,11 @@ export function generateZodSchema(interfaceName, newFields, baseResource, baseFi
217
217
  }
218
218
  // Emit file header
219
219
  lines.push(`import { z } from "zod";`);
220
- // Add base-type imports from @babelfhir-ts/zod-<version>
220
+ // Add base-type imports from @babelfhir-ts/zod/<version>
221
221
  if (baseTypeImports.size > 0) {
222
222
  const sorted = Array.from(baseTypeImports).sort();
223
223
  const specifiers = sorted.map(t => `${t}Schema`).join(', ');
224
- lines.push(`import { ${specifiers} } from "@babelfhir-ts/zod-${versionSlug()}";`);
224
+ lines.push(`import { ${specifiers} } from "@babelfhir-ts/zod/${versionSlug()}";`);
225
225
  }
226
226
  // Add FHIR type imports for referenced complex types (profiled, not base)
227
227
  if (imports.size > 0) {
@@ -329,7 +329,7 @@ function buildZodType(field, valueSets, valueSetImports, complexTypeImports, bas
329
329
  if (zodPrimitive) {
330
330
  return zodPrimitive;
331
331
  }
332
- // Known FHIR complex types — import from @babelfhir-ts/zod-<version>
332
+ // Known FHIR complex types — import from @babelfhir-ts/zod/<version>
333
333
  // Check both isFhirType (interfaces.json) and zodPackageTypes (dataTypes.json)
334
334
  // to handle types like SimpleQuantity that are in zod packages but not in interfaces
335
335
  if (getZodPackageTypes().has(fhirType)) {
@@ -1,7 +1,7 @@
1
1
  /**
2
- * Installs @babelfhir-ts/zod-<version> into the generated output's node_modules.
2
+ * Installs @babelfhir-ts/zod into the generated output's node_modules.
3
3
  *
4
- * If the pre-built runtime package (packages/zod-<version>/dist/) exists,
4
+ * If the pre-built runtime package (packages/zod/dist/<version>/) exists,
5
5
  * the full JS + d.ts files are copied so the generated Zod schemas work both
6
6
  * at compile time AND at runtime (parity tests, generate:random:zod, etc.).
7
7
  *
@@ -28,35 +28,38 @@ function findRepoRoot() {
28
28
  }
29
29
  export function installBaseZodTypes(outputDir) {
30
30
  const slug = versionSlug();
31
- const zodPkg = `zod-${slug}`;
32
- const pkgDir = path.join(outputDir, 'node_modules', '@babelfhir-ts', zodPkg);
31
+ const pkgDir = path.join(outputDir, 'node_modules', '@babelfhir-ts', 'zod');
33
32
  fs.mkdirSync(pkgDir, { recursive: true });
34
33
  // Try to install the full runtime package first
35
34
  const repoRoot = findRepoRoot();
36
- const runtimeDist = path.join(repoRoot, 'packages', zodPkg, 'dist');
35
+ const runtimeDist = path.join(repoRoot, 'packages', 'zod', 'dist', slug);
37
36
  if (fs.existsSync(runtimeDist)) {
38
37
  // Copy the real package.json from the runtime package
39
- const srcPkgJson = path.join(repoRoot, 'packages', zodPkg, 'package.json');
38
+ const srcPkgJson = path.join(repoRoot, 'packages', 'zod', 'package.json');
40
39
  if (fs.existsSync(srcPkgJson)) {
41
40
  fs.copyFileSync(srcPkgJson, path.join(pkgDir, 'package.json'));
42
41
  }
43
- // Copy all runtime dist files (JS + d.ts)
44
- const distDir = path.join(pkgDir, 'dist');
45
- fs.mkdirSync(distDir, { recursive: true });
42
+ // Copy all runtime dist files into the version-specific subdirectory
43
+ const distSlugDir = path.join(pkgDir, slug);
44
+ fs.mkdirSync(distSlugDir, { recursive: true });
46
45
  for (const file of fs.readdirSync(runtimeDist)) {
47
- fs.copyFileSync(path.join(runtimeDist, file), path.join(distDir, file));
46
+ fs.copyFileSync(path.join(runtimeDist, file), path.join(distSlugDir, file));
48
47
  }
49
48
  return;
50
49
  }
51
50
  // Fallback: generate stubs with both types (.d.ts) AND runtime JS (.js)
52
51
  // The runtime JS exports permissive schemas so dynamic imports don't crash.
53
52
  fs.writeFileSync(path.join(pkgDir, 'package.json'), JSON.stringify({
54
- name: `@babelfhir-ts/${zodPkg}`,
53
+ name: '@babelfhir-ts/zod',
55
54
  version: '0.0.0-stubs',
56
55
  type: 'module',
57
- main: 'index.js',
58
- types: 'index.d.ts',
56
+ exports: {
57
+ [`./${slug}`]: { import: `./${slug}/index.js`, types: `./${slug}/index.d.ts` },
58
+ [`./${slug}/*`]: { import: `./${slug}/*.js`, types: `./${slug}/*.d.ts` },
59
+ },
59
60
  }, null, 2));
61
+ const versionDir = path.join(pkgDir, slug);
62
+ fs.mkdirSync(versionDir, { recursive: true });
60
63
  const dtsLines = [
61
64
  `import { z } from "zod";`,
62
65
  '',
@@ -72,6 +75,6 @@ export function installBaseZodTypes(outputDir) {
72
75
  }
73
76
  dtsLines.push('');
74
77
  jsLines.push('');
75
- fs.writeFileSync(path.join(pkgDir, 'index.d.ts'), dtsLines.join('\n'));
76
- fs.writeFileSync(path.join(pkgDir, 'index.js'), jsLines.join('\n'));
78
+ fs.writeFileSync(path.join(versionDir, 'index.d.ts'), dtsLines.join('\n'));
79
+ fs.writeFileSync(path.join(versionDir, 'index.js'), jsLines.join('\n'));
77
80
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * FHIR complex types available in @babelfhir-ts/zod-<version>.
2
+ * FHIR complex types available in @babelfhir-ts/zod/<version>.
3
3
  * Shared between the schema generator (for import resolution) and the
4
4
  * stub installer (for type declaration generation).
5
5
  *
@@ -385,9 +385,9 @@ export async function generateIntoPackage(packageArchivePath, outArchivePath, fl
385
385
  if (!flags?.noClient) {
386
386
  generatedPackageJson.dependencies[`@babelfhir-ts/client-${versionSlug()}`] = '^0.2.0';
387
387
  }
388
- // When zod schemas are generated, add @babelfhir-ts/zod-<version> + zod peer dependency
388
+ // When zod schemas are generated, add @babelfhir-ts/zod + zod peer dependency
389
389
  if (flags?.schema === 'zod') {
390
- generatedPackageJson.dependencies[`@babelfhir-ts/zod-${versionSlug()}`] = '^0.1.0';
390
+ generatedPackageJson.dependencies['@babelfhir-ts/zod'] = '^0.2.0';
391
391
  generatedPackageJson.peerDependencies['zod'] = '^4.0.0';
392
392
  }
393
393
  // When dicomweb is enabled, add @babelfhir-ts/dicomweb dependency
@@ -453,11 +453,11 @@ export async function generateIntoPackage(packageArchivePath, outArchivePath, fl
453
453
  // Remove base client type stubs — they were only needed for tsc to resolve
454
454
  // @babelfhir-ts/client-<version> imports during compilation. The real package is
455
455
  // installed by the consumer via npm.
456
- // Keep @babelfhir-ts/zod-<version> when zod schemas were generated (runtime needed for parity tests)
456
+ // Keep @babelfhir-ts/zod when zod schemas were generated (runtime needed for parity tests)
457
457
  const babelfhirDir = path.join(outputDir, 'node_modules', '@babelfhir-ts');
458
458
  if (fs.existsSync(babelfhirDir)) {
459
459
  for (const entry of fs.readdirSync(babelfhirDir)) {
460
- if (flags?.schema === 'zod' && entry.startsWith('zod-'))
460
+ if (flags?.schema === 'zod' && entry === 'zod')
461
461
  continue;
462
462
  try {
463
463
  fs.rmSync(path.join(babelfhirDir, entry), { recursive: true, force: true });
@@ -587,7 +587,7 @@ export async function generateIntoPackageDirect(packageArchivePath, flags) {
587
587
  generatedPackageJson.dependencies[`@babelfhir-ts/client-${versionSlug()}`] = '^0.2.0';
588
588
  }
589
589
  if (flags?.schema === 'zod') {
590
- generatedPackageJson.dependencies[`@babelfhir-ts/zod-${versionSlug()}`] = '^0.1.0';
590
+ generatedPackageJson.dependencies['@babelfhir-ts/zod'] = '^0.2.0';
591
591
  generatedPackageJson.peerDependencies['zod'] = '^4.0.0';
592
592
  }
593
593
  // When dicomweb is enabled, add @babelfhir-ts/dicomweb dependency
@@ -643,7 +643,7 @@ export async function generateIntoPackageDirect(packageArchivePath, flags) {
643
643
  const babelfhirDir = path.join(outputDir, 'node_modules', '@babelfhir-ts');
644
644
  if (fs.existsSync(babelfhirDir)) {
645
645
  for (const entry of fs.readdirSync(babelfhirDir)) {
646
- if (flags?.schema === 'zod' && entry.startsWith('zod-'))
646
+ if (flags?.schema === 'zod' && entry === 'zod')
647
647
  continue;
648
648
  try {
649
649
  fs.rmSync(path.join(babelfhirDir, entry), { recursive: true, force: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "babelfhir-ts",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "description": "BabelFHIR-TS: generate TypeScript interfaces, validators, and helper classes from FHIR R4/R4B/R5 StructureDefinitions (profiles) directly inside package archives.",
5
5
  "type": "module",
6
6
  "main": "out/src/main.js",