@atomic-ehr/codegen 0.0.1-canary.20251010120621.05ce13f → 0.0.1-canary.20251010131311.9439f74
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 +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -29,7 +29,7 @@ import Or from'yargs';import {hideBin}from'yargs/helpers';import'perf_hooks';imp
|
|
|
29
29
|
${i}`:r}filterAndSortSchemas(e){return this.collectedValueSets=this.collectValueSets(e),e.filter(t=>!this.shouldSkipSchema(t))}async validateContent(e,t){let r=/export\s+(interface|class|type|enum)\s+\w+/.test(e),i=e.includes("{")&&e.includes("}");if(!r)throw new Error(`Generated content for ${t.schema.identifier.name} does not contain valid export statements`);if(!i)throw new Error(`Generated content for ${t.schema.identifier.name} has invalid syntax (missing braces)`)}async transformSchemas(e){let t=[];for(let r of e){let i=await this.transformSchema(r);i&&t.push(i);}return t}async transformSchema(e){if(this.shouldSkipSchema(e))return;let t={schema:e,typeMapper:this.typeMapper,filename:this.getFilenameForSchema(e),language:"TypeScript",timestamp:new Date().toISOString()},r=await this.generateSchemaContent(e,t);if(!r.trim())return;let i=this.extractImportsFromContent(r,e),n=this.extractExportsFromContent(r,e),o=this.getFilenameForSchema(e);return {content:r,imports:i,exports:Array.from(n),filename:o}}shouldGenerateValueSet(e){if(!Be(e)||!e.enum||!Array.isArray(e.enum)||e.enum.length===0)return false;switch(this.options.valueSetMode||"required-only"){case "all":return true;case "required-only":return e.strength==="required";case "custom":return (this.options.valueSetStrengths||["required"]).includes(e.strength);default:return e.strength==="required"}}collectValueSets(e){let t=new Map;for(let r of e)if(this.shouldGenerateValueSet(r)&&Be(r)){let i=this.typeMapper.formatTypeName(r.identifier.name);t.set(i,r);}return t}shouldUseValueSetType(e){if(!e||!this.tsOptions.generateValueSets)return false;let t=this.typeMapper.formatTypeName(e.name);return this.collectedValueSets.has(t)}getValueSetTypeName(e){return this.typeMapper.formatTypeName(e.name)}shouldUseInlineEnum(e){return !e||this.tsOptions.generateValueSets?false:e.enum&&Array.isArray(e.enum)&&e.enum.length>0}generateInlineEnumType(e){return !e.enum||!Array.isArray(e.enum)?"string":e.enum.map(r=>`'${r}'`).join(" | ")}shouldSkipSchema(e){if(e.identifier.kind==="value-set"||e.identifier.kind==="binding"||e.identifier.kind==="primitive-type")return true;if(!this.tsOptions.includeExtensions){let t=e.identifier.url;if(t?.includes("StructureDefinition/")){let r=t.split("StructureDefinition/")[1];if(r){let i=r.includes("-"),n=e.identifier.kind==="profile";if(i&&n)return true}}}return false}getFilenameForSchema(e){return `${this.typeMapper.formatFileName(e.identifier.name)}${this.getFileExtension()}`}extractImportsFromContent(e,t){let r=new Map,i=/import\s+(?:type\s+)?{\s*([^}]+)\s*}\s+from\s+['"]([^'"]+)['"];?/g,n;for(;(n=i.exec(e))!==null;){let o=n[1],a=n[2];if(!o||!a)continue;let c=o.split(",").map(l=>l.trim());for(let l of c)r.set(l,a);}return r}extractExportsFromContent(e,t){let r=new Set,i=/export\s+(?:interface|class|enum|type)\s+([A-Za-z_$][A-Za-z0-9_$]*)/g,n;for(;(n=i.exec(e))!==null;)n[1]&&r.add(n[1]);return r.add(this.typeMapper.formatTypeName(t.identifier.name)),r}generateReferenceInterface(e){let t=[],r=new Set;if("fields"in e&&e.fields)for(let[,i]of Object.entries(e.fields))this.collectFieldImports(i).forEach(o=>r.add(o));if(t.push("import type { ResourceType } from './utilities.js';"),r.size>0){let i=Array.from(r).sort();for(let n of i)t.push(`import type { ${n} } from './${n}.js';`);}if(t.push(""),this.tsOptions.includeDocuments&&e.description&&(t.push("/**"),t.push(` * ${e.description}`),e.identifier.url&&t.push(` * @see ${e.identifier.url}`),e.identifier.package&&t.push(` * @package ${e.identifier.package}`),t.push(" * @template T - The resource type being referenced"),t.push(" */")),t.push("export interface Reference<T extends ResourceType = ResourceType> {"),"fields"in e&&e.fields)for(let[i,n]of Object.entries(e.fields))if(i==="type")t.push(" type?: T;");else {let o=this.generateFieldLines(i,n);for(let a of o)a&&t.push(` ${a}`);}return t.push("}"),t.join(`
|
|
30
30
|
`)}generateTypeScriptInterface(e){let t=[],r=this.typeMapper.formatTypeName(e.identifier.name),i=new Set,n=new Set;if("fields"in e&&e.fields)for(let[,o]of Object.entries(e.fields)){let a=this.collectFieldImports(o);for(let c of a)this.collectedValueSets.has(c)?n.add(c):i.add(c);}if("nested"in e&&e.nested&&Array.isArray(e.nested)){for(let o of e.nested)if(o.fields)for(let[,a]of Object.entries(o.fields)){let c=this.collectFieldImports(a);for(let l of c)this.collectedValueSets.has(l)?n.add(l):i.add(l);}}if(i.size>0){let o=Array.from(i).sort();for(let a of o)t.push(`import type { ${a} } from './${a}.js';`);}if(n.size>0){let a=Array.from(n).sort().join(", ");t.push(`import type { ${a} } from './valuesets/index.js';`);}if((i.size>0||n.size>0)&&t.push(""),this.tsOptions.includeDocuments&&e.description&&(t.push("/**"),t.push(` * ${e.description}`),e.identifier.url&&t.push(` * @see ${e.identifier.url}`),e.identifier.package&&t.push(` * @package ${e.identifier.package}`),t.push(" */")),t.push(`export interface ${r} {`),e.identifier.kind==="resource"&&t.push(` resourceType: '${r}';`),"fields"in e&&e.fields)for(let[o,a]of Object.entries(e.fields)){let c=this.generateFieldLines(o,a);for(let l of c)l&&t.push(` ${l}`);}return t.push("}"),t.join(`
|
|
31
31
|
`)}collectFieldImports(e){let t=[];if("choices"in e&&e.choices&&Array.isArray(e.choices))return t;if(e.binding&&this.shouldUseValueSetType(e.binding)){let r=this.getValueSetTypeName(e.binding);return t.push(r),t}if("type"in e&&e.type){if(e.type.kind==="nested")return t;let r=this.typeMapper.mapType(e.type);!r.isPrimitive&&r.name!=="any"&&(["string","number","boolean","Date","object","unknown","any"].includes(r.name)||t.push(r.name));}return [...new Set(t)]}extractReferenceTypes(e){let t=[];if(!Array.isArray(e))return t;for(let r of e)if(!(!r||typeof r!="object")&&r.kind==="resource"&&r.name){let i=this.typeMapper.formatTypeName(r.name);t.push(i);}return [...new Set(t)]}generateNestedTypeInterface(e,t){let r=[],i=this.typeMapper.formatTypeName(`${e}${this.capitalizeFirst(t.identifier.name)}`);if(this.tsOptions.includeDocuments&&t.description&&(r.push("/**"),r.push(` * ${t.description}`),t.identifier.url&&r.push(` * @see ${t.identifier.url}`),r.push(" */")),r.push(`export interface ${i} {`),t.fields)for(let[n,o]of Object.entries(t.fields)){let a=this.generateFieldLines(n,o);for(let c of a)c&&r.push(` ${c}`);}return r.push("}"),r.join(`
|
|
32
|
-
`)}capitalizeFirst(e){return e.charAt(0).toUpperCase()+e.slice(1)}generateFieldLines(e,t){if("choices"in t&&t.choices&&Array.isArray(t.choices))return [];let r=this.generateFieldLine(e,t);return r?[r]:[]}generateFieldLine(e,t){let r="any",i=false,n=false;if("type"in t&&t.type){if(t.binding&&this.shouldUseValueSetType(t.binding))r=this.getValueSetTypeName(t.binding);else if(t.binding&&this.shouldUseInlineEnum(t))r=this.generateInlineEnumType(t);else if(r=this.typeMapper.mapType(t.type).name,t.type.kind==="nested"){let l=t.type.url?.split("#")||[];if(l.length===2){let d=l[0].split("/").pop()||"",u=t.type.name;r=this.typeMapper.formatTypeName(`${d}${this.capitalizeFirst(u)}`);}else r=this.typeMapper.formatTypeName(t.type.name);}else if(r==="Reference"&&t.reference&&Array.isArray(t.reference)){let l=this.extractReferenceTypes(t.reference);l.length>0&&(l.forEach(u=>this.resourceTypes.add(u)),r=`Reference<${l.map(u=>`'${u}'`).join(" | ")}>`);}}
|
|
32
|
+
`)}capitalizeFirst(e){return e.charAt(0).toUpperCase()+e.slice(1)}generateFieldLines(e,t){if("choices"in t&&t.choices&&Array.isArray(t.choices))return [];let r=this.generateFieldLine(e,t);return r?[r]:[]}generateFieldLine(e,t){let r="any",i=false,n=false;if("type"in t&&t.type){if(t.binding&&this.shouldUseValueSetType(t.binding))r=this.getValueSetTypeName(t.binding);else if(t.binding&&this.shouldUseInlineEnum(t))r=this.generateInlineEnumType(t);else if(r=this.typeMapper.mapType(t.type).name,t.type.kind==="nested"){let l=t.type.url?.split("#")||[];if(l.length===2){let d=l[0].split("/").pop()||"",u=t.type.name;r=this.typeMapper.formatTypeName(`${d}${this.capitalizeFirst(u)}`);}else r=this.typeMapper.formatTypeName(t.type.name);}else if(r==="Reference"&&t.reference&&Array.isArray(t.reference)){let l=this.extractReferenceTypes(t.reference);l.length>0&&(l.forEach(u=>this.resourceTypes.add(u)),r=`Reference<${l.map(u=>`'${u}'`).join(" | ")}>`);}}"required"in t&&(i=t.required),"array"in t&&(n=t.array);let o=i?"":"?",a=n?"[]":"";return `${e.replace("-","_")}${o}: ${r}${a};`}extractExports(e){let t=[],r=/export\s*\{\s*([^}]+)\s*\}/g,i;for(;(i=r.exec(e))!==null;)if(i[1]){let o=i[1].split(",").map(a=>a.trim()).filter(Boolean);t.push(...o);}let n=[/export\s+interface\s+(\w+)/g,/export\s+type\s+(\w+)/g,/export\s+class\s+(\w+)/g,/export\s+enum\s+(\w+)/g,/export\s+const\s+(\w+)/g,/export\s+function\s+(\w+)/g];for(let o of n){let a;for(;(a=o.exec(e))!==null;)a[1]&&t.push(a[1]);}return [...new Set(t)]}setOutputDir(e){this.options.outputDir=e;}setOptions(e){this.options={...this.options,...e};}getOptions(){return {...this.options}}async generate(e){return await this.fileManager.cleanDirectory(),this.logger.debug("Cleaned output directory before generation"),super.generate(e)}async runPostGenerationHooks(){await super.runPostGenerationHooks(),await this.generateValueSetFiles(),await this.generateUtilitiesFile(),await this.generateMainIndexFile();}async generateUtilitiesFile(){if(this.resourceTypes.size===0){this.logger.warn("No resource types found, skipping utilities.ts generation");return}let e=[];e.push("/**"),e.push(" * FHIR Resource Type Utilities"),e.push(" * This file contains utility types for FHIR resources."),e.push(" * "),e.push(" * @generated This file is auto-generated. Do not edit manually."),e.push(" */"),e.push("");let t=Array.from(this.resourceTypes).sort();e.push("/**"),e.push(" * Union of all FHIR resource types in this package"),e.push(" */"),e.push("export type ResourceType =");for(let i=0;i<t.length;i++){let o=i===t.length-1?";":"";e.push(` | '${t[i]}'${o}`);}e.push(""),e.push("/**"),e.push(" * Helper type for creating typed References"),e.push(" * @example Reference<'Patient' | 'Practitioner'> - Reference that can point to Patient or Practitioner"),e.push(" */"),e.push("export type TypedReference<T extends ResourceType> = {"),e.push(" reference?: string;"),e.push(" type?: T;"),e.push(" identifier?: any; // Simplified for utility"),e.push(" display?: string;"),e.push("};");let r=e.join(`
|
|
33
33
|
`);await this.fileManager.writeFile("utilities.ts",r),this.logger.info(`Generated utilities.ts with ${this.resourceTypes.size} resource types`);}generateValueSetFile(e){let t=this.typeMapper.formatTypeName(e.identifier.name),r=e.enum?.map(n=>` '${n}'`).join(`,
|
|
34
34
|
`)||"",i=[];return this.options.includeDocuments&&(i.push("/**"),i.push(` * ${e.identifier.name} value set`),e.description&&i.push(` * ${e.description}`),e.valueset?.url&&i.push(` * @see ${e.valueset.url}`),e.identifier.package&&i.push(` * @package ${e.identifier.package}`),i.push(" * @generated This file is auto-generated. Do not edit manually."),i.push(" */"),i.push("")),i.push(`export const ${t}Values = [`),r&&i.push(r),i.push("] as const;"),i.push(""),i.push(`export type ${t} = typeof ${t}Values[number];`),this.tsOptions.includeValueSetHelpers&&(i.push(""),i.push(`export const isValid${t} = (value: string): value is ${t} =>`),i.push(` ${t}Values.includes(value as ${t});`)),i.join(`
|
|
35
35
|
`)}async generateValueSetFiles(){if(!(!this.tsOptions.generateValueSets||this.collectedValueSets.size===0)){for(let[e,t]of this.collectedValueSets){let r=this.generateValueSetFile(t),i=`valuesets/${e}.ts`;await this.fileManager.writeFile(i,r),this.logger.info(`Generated value set: ${i}`);}await this.generateValueSetIndexFile();}}async generateValueSetIndexFile(){let e=[];this.tsOptions.includeDocuments&&(e.push("/**"),e.push(" * FHIR Value Sets"),e.push(" * This file re-exports all generated value sets."),e.push(" * "),e.push(" * @generated This file is auto-generated. Do not edit manually."),e.push(" */"),e.push(""));let t=Array.from(this.collectedValueSets.keys()).sort();for(let i of t)e.push(`export * from './${i}.js';`);let r=e.join(`
|
package/dist/index.js
CHANGED
|
@@ -4890,7 +4890,7 @@ ${nestedInterfaces}`;
|
|
|
4890
4890
|
}
|
|
4891
4891
|
const optional = required ? "" : "?";
|
|
4892
4892
|
const arrayType = isArray ? "[]" : "";
|
|
4893
|
-
return `${fieldName}${optional}: ${typeString}${arrayType};`;
|
|
4893
|
+
return `${fieldName.replace("-", "_")}${optional}: ${typeString}${arrayType};`;
|
|
4894
4894
|
}
|
|
4895
4895
|
// ==========================================
|
|
4896
4896
|
/**
|