@atomic-ehr/codegen 0.0.1-canary.20250822114054.4ca1428 → 0.0.1-canary.20250822150706.c3b8669

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.
Files changed (120) hide show
  1. package/dist/api/builder.d.ts +3 -3
  2. package/dist/api/builder.d.ts.map +1 -1
  3. package/dist/api/builder.js +374 -0
  4. package/dist/api/generators/base/BaseGenerator.d.ts +4 -4
  5. package/dist/api/generators/base/BaseGenerator.d.ts.map +1 -1
  6. package/dist/api/generators/base/BaseGenerator.js +572 -0
  7. package/dist/api/generators/base/FileManager.d.ts +2 -2
  8. package/dist/api/generators/base/FileManager.d.ts.map +1 -1
  9. package/dist/api/generators/base/FileManager.js +204 -0
  10. package/dist/api/generators/base/PythonTypeMapper.d.ts +2 -2
  11. package/dist/api/generators/base/PythonTypeMapper.d.ts.map +1 -1
  12. package/dist/api/generators/base/PythonTypeMapper.js +71 -0
  13. package/dist/api/generators/base/TemplateEngine.d.ts +1 -1
  14. package/dist/api/generators/base/TemplateEngine.d.ts.map +1 -1
  15. package/dist/api/generators/base/TemplateEngine.js +133 -0
  16. package/dist/api/generators/base/TypeMapper.js +153 -0
  17. package/dist/api/generators/base/TypeScriptTypeMapper.d.ts +1 -1
  18. package/dist/api/generators/base/TypeScriptTypeMapper.d.ts.map +1 -1
  19. package/dist/api/generators/base/TypeScriptTypeMapper.js +232 -0
  20. package/dist/api/generators/base/builders/DirectoryBuilder.d.ts +4 -4
  21. package/dist/api/generators/base/builders/DirectoryBuilder.d.ts.map +1 -1
  22. package/dist/api/generators/base/builders/DirectoryBuilder.js +215 -0
  23. package/dist/api/generators/base/builders/FileBuilder.d.ts +2 -2
  24. package/dist/api/generators/base/builders/FileBuilder.d.ts.map +1 -1
  25. package/dist/api/generators/base/builders/FileBuilder.js +408 -0
  26. package/dist/api/generators/base/builders/IndexBuilder.d.ts +2 -2
  27. package/dist/api/generators/base/builders/IndexBuilder.d.ts.map +1 -1
  28. package/dist/api/generators/base/builders/IndexBuilder.js +290 -0
  29. package/dist/api/generators/base/enhanced-errors.d.ts +2 -2
  30. package/dist/api/generators/base/enhanced-errors.d.ts.map +1 -1
  31. package/dist/api/generators/base/enhanced-errors.js +259 -0
  32. package/dist/api/generators/base/error-handler.d.ts +1 -1
  33. package/dist/api/generators/base/error-handler.d.ts.map +1 -1
  34. package/dist/api/generators/base/error-handler.js +243 -0
  35. package/dist/api/generators/base/errors.d.ts +2 -2
  36. package/dist/api/generators/base/errors.d.ts.map +1 -1
  37. package/dist/api/generators/base/errors.js +694 -0
  38. package/dist/api/generators/base/index.d.ts +22 -22
  39. package/dist/api/generators/base/index.d.ts.map +1 -1
  40. package/dist/api/generators/base/index.js +161 -0
  41. package/dist/api/generators/base/types.d.ts +2 -2
  42. package/dist/api/generators/base/types.d.ts.map +1 -1
  43. package/dist/api/generators/base/types.js +12 -0
  44. package/dist/api/generators/rest-client.d.ts +2 -2
  45. package/dist/api/generators/rest-client.d.ts.map +1 -1
  46. package/dist/api/generators/rest-client.js +847 -0
  47. package/dist/api/generators/search-parameter-enhancer.d.ts +1 -1
  48. package/dist/api/generators/search-parameter-enhancer.d.ts.map +1 -1
  49. package/dist/api/generators/search-parameter-enhancer.js +801 -0
  50. package/dist/api/generators/types.js +4 -0
  51. package/dist/api/generators/typescript.d.ts +3 -3
  52. package/dist/api/generators/typescript.d.ts.map +1 -1
  53. package/dist/api/generators/typescript.js +537 -0
  54. package/dist/api/generators/validation-generator.js +632 -0
  55. package/dist/api/index.d.ts +10 -10
  56. package/dist/api/index.d.ts.map +1 -1
  57. package/dist/api/index.js +51 -0
  58. package/dist/cli/commands/generate/typescript.d.ts +1 -1
  59. package/dist/cli/commands/generate/typescript.d.ts.map +1 -1
  60. package/dist/cli/commands/generate/typescript.js +52 -0
  61. package/dist/cli/commands/generate.d.ts +5 -12
  62. package/dist/cli/commands/generate.d.ts.map +1 -1
  63. package/dist/cli/commands/generate.js +158 -0
  64. package/dist/cli/commands/index.d.ts +2 -1
  65. package/dist/cli/commands/index.d.ts.map +1 -1
  66. package/dist/cli/commands/index.js +100 -0
  67. package/dist/cli/commands/typeschema/generate.js +130 -0
  68. package/dist/cli/commands/typeschema.js +48 -0
  69. package/dist/cli/index.js +12 -8664
  70. package/dist/cli/utils/log.d.ts +2 -2
  71. package/dist/cli/utils/log.d.ts.map +1 -1
  72. package/dist/cli/utils/log.js +23 -0
  73. package/dist/cli/utils/prompts.js +224 -0
  74. package/dist/cli/utils/spinner.js +270 -0
  75. package/dist/config.js +703 -0
  76. package/dist/index.d.ts +2 -2
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +84 -40
  79. package/dist/logger.js +290 -0
  80. package/dist/typeschema/cache.d.ts +2 -2
  81. package/dist/typeschema/cache.d.ts.map +1 -1
  82. package/dist/typeschema/cache.js +285 -0
  83. package/dist/typeschema/core/binding.d.ts +1 -1
  84. package/dist/typeschema/core/binding.d.ts.map +1 -1
  85. package/dist/typeschema/core/binding.js +187 -0
  86. package/dist/typeschema/core/field-builder.d.ts +1 -1
  87. package/dist/typeschema/core/field-builder.d.ts.map +1 -1
  88. package/dist/typeschema/core/field-builder.js +259 -0
  89. package/dist/typeschema/core/identifier.js +117 -0
  90. package/dist/typeschema/core/nested-types.d.ts +1 -1
  91. package/dist/typeschema/core/nested-types.d.ts.map +1 -1
  92. package/dist/typeschema/core/nested-types.js +111 -0
  93. package/dist/typeschema/core/transformer.d.ts +2 -2
  94. package/dist/typeschema/core/transformer.d.ts.map +1 -1
  95. package/dist/typeschema/core/transformer.js +345 -0
  96. package/dist/typeschema/generator.d.ts +3 -3
  97. package/dist/typeschema/generator.d.ts.map +1 -1
  98. package/dist/typeschema/generator.js +352 -0
  99. package/dist/typeschema/index.d.ts +14 -14
  100. package/dist/typeschema/index.d.ts.map +1 -1
  101. package/dist/typeschema/index.js +92 -0
  102. package/dist/typeschema/parser.d.ts +2 -2
  103. package/dist/typeschema/parser.d.ts.map +1 -1
  104. package/dist/typeschema/parser.js +310 -0
  105. package/dist/typeschema/profile/processor.d.ts +1 -1
  106. package/dist/typeschema/profile/processor.d.ts.map +1 -1
  107. package/dist/typeschema/profile/processor.js +268 -0
  108. package/dist/typeschema/schema.js +456 -0
  109. package/dist/typeschema/type-schema.types.js +39 -0
  110. package/dist/typeschema/types.js +4 -0
  111. package/dist/typeschema/utils.d.ts +1 -1
  112. package/dist/typeschema/utils.d.ts.map +1 -1
  113. package/dist/typeschema/utils.js +13 -0
  114. package/dist/typeschema/value-set/processor.d.ts +1 -1
  115. package/dist/typeschema/value-set/processor.d.ts.map +1 -1
  116. package/dist/typeschema/value-set/processor.js +168 -0
  117. package/dist/utils/codegen-logger.js +204 -0
  118. package/dist/utils.js +42 -0
  119. package/package.json +15 -4
  120. package/dist/index-fgcebdva.js +0 -8515
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Core file management system with batching and performance optimizations
3
+ *
4
+ * This replaces scattered writeFile calls with a comprehensive file management
5
+ * system that provides better error handling, performance, and maintainability.
6
+ */
7
+ import { access, mkdir, rm, stat, writeFile } from "node:fs/promises";
8
+ import { dirname, join, relative } from "node:path";
9
+ import { FileOperationError } from "./errors.js";
10
+ /**
11
+ * High-performance file manager with batching and error recovery
12
+ *
13
+ * Features:
14
+ * - Automatic directory creation
15
+ * - Batch operations for better performance
16
+ * - Comprehensive error handling with recovery suggestions
17
+ * - Import path resolution
18
+ * - File existence checks
19
+ */
20
+ export class FileManager {
21
+ options;
22
+ logger;
23
+ constructor(options) {
24
+ this.options = {
25
+ overwrite: true,
26
+ batchSize: 10,
27
+ ...options,
28
+ };
29
+ this.logger = options.logger;
30
+ }
31
+ /**
32
+ * Write a file with automatic directory creation
33
+ * @param relativePath Path relative to output directory
34
+ * @param content File content
35
+ * @param options Write options
36
+ */
37
+ async writeFile(relativePath, content, options = {}) {
38
+ const startTime = performance.now();
39
+ const fullPath = join(this.options.outputDir, relativePath);
40
+ const encoding = options.encoding || "utf-8";
41
+ const overwrite = options.overwrite ?? this.options.overwrite;
42
+ try {
43
+ // Check if file exists and overwrite is disabled
44
+ if (!overwrite) {
45
+ try {
46
+ await access(fullPath);
47
+ this.logger.debug(`Skipping existing file: ${relativePath}`);
48
+ const stats = await stat(fullPath);
49
+ return {
50
+ path: fullPath,
51
+ size: stats.size,
52
+ writeTime: 0,
53
+ };
54
+ }
55
+ catch {
56
+ // File doesn't exist, continue with write
57
+ }
58
+ }
59
+ // Ensure directory exists
60
+ await this.ensureDirectory(dirname(fullPath));
61
+ // Write file
62
+ await writeFile(fullPath, content, encoding);
63
+ const writeTime = performance.now() - startTime;
64
+ const size = Buffer.byteLength(content, encoding);
65
+ this.logger.debug(`Written ${relativePath} (${size} bytes, ${writeTime.toFixed(2)}ms)`);
66
+ return {
67
+ path: fullPath,
68
+ size,
69
+ writeTime,
70
+ };
71
+ }
72
+ catch (error) {
73
+ throw new FileOperationError(`Failed to write file '${relativePath}': ${error}`, "write", fullPath, error instanceof Error ? error : undefined, {
74
+ canRetry: true,
75
+ alternativePaths: [
76
+ join(process.cwd(), "backup-output", relativePath),
77
+ ],
78
+ });
79
+ }
80
+ }
81
+ /**
82
+ * Write multiple files in batch for better performance
83
+ * @param files Map of relative path to content
84
+ */
85
+ async writeBatch(files) {
86
+ this.logger.debug(`Writing batch of ${files.size} files`);
87
+ const entries = Array.from(files.entries());
88
+ const results = [];
89
+ // Process in batches to avoid overwhelming the filesystem
90
+ for (let i = 0; i < entries.length; i += this.options.batchSize) {
91
+ const batch = entries.slice(i, i + this.options.batchSize);
92
+ const batchPromises = batch.map(([path, content]) => this.writeFile(path, content));
93
+ const batchResults = await Promise.all(batchPromises);
94
+ results.push(...batchResults);
95
+ // Small delay between batches to be filesystem-friendly
96
+ if (i + this.options.batchSize < entries.length) {
97
+ await new Promise((resolve) => setTimeout(resolve, 10));
98
+ }
99
+ }
100
+ return results;
101
+ }
102
+ /**
103
+ * Ensure directory exists, creating parent directories as needed
104
+ * @param dirPath Full directory path
105
+ */
106
+ async ensureDirectory(dirPath) {
107
+ try {
108
+ await mkdir(dirPath, { recursive: true });
109
+ }
110
+ catch (error) {
111
+ throw new FileOperationError(`Failed to create directory '${dirPath}': ${error}`, "create", dirPath, error instanceof Error ? error : undefined, {
112
+ canRetry: true,
113
+ permissionFix: `chmod 755 "${dirname(dirPath)}"`,
114
+ });
115
+ }
116
+ }
117
+ /**
118
+ * Clean directory by removing all contents
119
+ * @param relativePath Path relative to output directory
120
+ */
121
+ async cleanDirectory(relativePath = ".") {
122
+ const fullPath = join(this.options.outputDir, relativePath);
123
+ try {
124
+ await access(fullPath);
125
+ this.logger.debug(`Cleaning directory: ${relativePath}`);
126
+ await rm(fullPath, { recursive: true, force: true });
127
+ }
128
+ catch (error) {
129
+ // Directory doesn't exist - that's fine
130
+ if (error?.code !== "ENOENT") {
131
+ throw new FileOperationError(`Failed to clean directory '${relativePath}': ${error}`, "delete", fullPath, error instanceof Error ? error : undefined, {
132
+ canRetry: true,
133
+ });
134
+ }
135
+ }
136
+ }
137
+ /**
138
+ * Get relative import path between two files
139
+ * @param fromFile Source file path
140
+ * @param toFile Target file path
141
+ */
142
+ getRelativeImportPath(fromFile, toFile) {
143
+ const from = dirname(join(this.options.outputDir, fromFile));
144
+ const to = join(this.options.outputDir, toFile);
145
+ let relativePath = relative(from, to);
146
+ // Ensure relative imports start with './' or '../'
147
+ if (!relativePath.startsWith(".")) {
148
+ relativePath = `./${relativePath}`;
149
+ }
150
+ // Remove file extension for imports (handle .d.ts files properly)
151
+ return relativePath.replace(/\.(d\.ts|ts|tsx|js|jsx)$/, "");
152
+ }
153
+ /**
154
+ * Check if a file would be overwritten
155
+ * @param relativePath Path relative to output directory
156
+ */
157
+ async wouldOverwrite(relativePath) {
158
+ const fullPath = join(this.options.outputDir, relativePath);
159
+ try {
160
+ await access(fullPath);
161
+ return true;
162
+ }
163
+ catch {
164
+ return false;
165
+ }
166
+ }
167
+ /**
168
+ * Get file statistics
169
+ * @param relativePath Path relative to output directory
170
+ */
171
+ async getFileStats(relativePath) {
172
+ const fullPath = join(this.options.outputDir, relativePath);
173
+ try {
174
+ const stats = await stat(fullPath);
175
+ return {
176
+ size: stats.size,
177
+ generationTime: 0, // Will be set by caller
178
+ writeTime: 0, // Will be set by caller
179
+ };
180
+ }
181
+ catch {
182
+ return null;
183
+ }
184
+ }
185
+ /**
186
+ * Get output directory
187
+ */
188
+ getOutputDirectory() {
189
+ return this.options.outputDir;
190
+ }
191
+ /**
192
+ * Set batch size for operations
193
+ * @param size Batch size
194
+ */
195
+ setBatchSize(size) {
196
+ this.options.batchSize = Math.max(1, Math.min(50, size));
197
+ }
198
+ /**
199
+ * Get current batch size
200
+ */
201
+ getBatchSize() {
202
+ return this.options.batchSize;
203
+ }
204
+ }
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Python type mapper implementation (basic version)
3
3
  */
4
- import type { TypeSchemaIdentifier } from "../../../typeschema";
5
- import { type LanguageType, TypeMapper } from "./TypeMapper";
4
+ import type { TypeSchemaIdentifier } from "../../../typeschema/index.js";
5
+ import { type LanguageType, TypeMapper } from "./TypeMapper.js";
6
6
  export declare class PythonTypeMapper extends TypeMapper {
7
7
  getLanguageName(): string;
8
8
  mapPrimitive(fhirType: string): LanguageType;
@@ -1 +1 @@
1
- {"version":3,"file":"PythonTypeMapper.d.ts","sourceRoot":"","sources":["../../../../src/api/generators/base/PythonTypeMapper.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,KAAK,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE7D,qBAAa,gBAAiB,SAAQ,UAAU;IAC/C,eAAe,IAAI,MAAM;IAIzB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY;IAkB5C,YAAY,CAAC,QAAQ,EAAE,oBAAoB,EAAE,GAAG,YAAY;IAS5D,QAAQ,CAAC,WAAW,EAAE,YAAY,GAAG,YAAY;IAUjD,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,GAAG,YAAY;IAUhE,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,YAAY;IAQvD,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIpC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAQrC,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAGpC"}
1
+ {"version":3,"file":"PythonTypeMapper.d.ts","sourceRoot":"","sources":["../../../../src/api/generators/base/PythonTypeMapper.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,KAAK,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEhE,qBAAa,gBAAiB,SAAQ,UAAU;IAC/C,eAAe,IAAI,MAAM;IAIzB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY;IAkB5C,YAAY,CAAC,QAAQ,EAAE,oBAAoB,EAAE,GAAG,YAAY;IAS5D,QAAQ,CAAC,WAAW,EAAE,YAAY,GAAG,YAAY;IAUjD,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,GAAG,YAAY;IAUhE,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,YAAY;IAQvD,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIpC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAQrC,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAGpC"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Python type mapper implementation (basic version)
3
+ */
4
+ import { TypeMapper } from "./TypeMapper.js";
5
+ export class PythonTypeMapper extends TypeMapper {
6
+ getLanguageName() {
7
+ return "Python";
8
+ }
9
+ mapPrimitive(fhirType) {
10
+ const primitiveMap = {
11
+ string: "str",
12
+ integer: "int",
13
+ decimal: "float",
14
+ boolean: "bool",
15
+ dateTime: "datetime",
16
+ date: "date",
17
+ time: "time",
18
+ };
19
+ return {
20
+ name: primitiveMap[fhirType] || "Any",
21
+ isPrimitive: true,
22
+ nullable: false,
23
+ };
24
+ }
25
+ mapReference(_targets) {
26
+ return {
27
+ name: "Reference",
28
+ isPrimitive: false,
29
+ importPath: ".reference",
30
+ nullable: false,
31
+ };
32
+ }
33
+ mapArray(elementType) {
34
+ return {
35
+ name: `List[${elementType.name}]`,
36
+ isPrimitive: false,
37
+ importPath: "typing",
38
+ isArray: true,
39
+ nullable: false,
40
+ };
41
+ }
42
+ mapOptional(type, required) {
43
+ if (required)
44
+ return type;
45
+ return {
46
+ ...type,
47
+ name: `Optional[${type.name}]`,
48
+ nullable: true,
49
+ };
50
+ }
51
+ mapEnum(_values, name) {
52
+ return {
53
+ name: name ? this.formatTypeName(name) : "Literal",
54
+ isPrimitive: false,
55
+ nullable: false,
56
+ };
57
+ }
58
+ formatTypeName(name) {
59
+ return this.applyNamingConvention(name);
60
+ }
61
+ formatFieldName(name) {
62
+ // Convert camelCase to snake_case
63
+ return name
64
+ .replace(/([A-Z])/g, "_$1")
65
+ .toLowerCase()
66
+ .replace(/^_/, "");
67
+ }
68
+ formatFileName(name) {
69
+ return this.formatFieldName(name);
70
+ }
71
+ }
@@ -7,7 +7,7 @@
7
7
  * - Function templates (TypeScript functions)
8
8
  * - Inline templates (template literals)
9
9
  */
10
- import type { CodegenLogger } from "../../../utils/codegen-logger";
10
+ import type { CodegenLogger } from "../../../utils/codegen-logger.js";
11
11
  /**
12
12
  * Template context passed to templates
13
13
  */
@@ -1 +1 @@
1
- {"version":3,"file":"TemplateEngine.d.ts","sourceRoot":"","sources":["../../../../src/api/generators/base/TemplateEngine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TemplateEngine.d.ts","sourceRoot":"","sources":["../../../../src/api/generators/base/TemplateEngine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Abstract template engine for code generation
3
+ *
4
+ * Supports multiple template formats:
5
+ * - Handlebars templates (.hbs)
6
+ * - String templates (.template)
7
+ * - Function templates (TypeScript functions)
8
+ * - Inline templates (template literals)
9
+ */
10
+ import { TemplateError } from "./errors.js";
11
+ /**
12
+ * Abstract template engine
13
+ */
14
+ export class TemplateEngine {
15
+ logger;
16
+ templates = new Map();
17
+ templateCache = new Map();
18
+ helpers = new Map();
19
+ constructor(options) {
20
+ this.logger = options.logger;
21
+ this.registerDefaultHelpers();
22
+ }
23
+ // ==========================================
24
+ // Concrete Methods
25
+ // ==========================================
26
+ /**
27
+ * Register a template helper function
28
+ * @param name Helper name
29
+ * @param helper Helper function
30
+ */
31
+ registerHelper(name, helper) {
32
+ this.helpers.set(name, helper);
33
+ this.logger.debug(`Registered template helper: ${name}`);
34
+ }
35
+ /**
36
+ * Get available template names
37
+ */
38
+ getAvailableTemplates() {
39
+ return Array.from(this.templates.keys()).sort();
40
+ }
41
+ /**
42
+ * Get template information
43
+ * @param templateName Template name
44
+ */
45
+ getTemplateInfo(templateName) {
46
+ const template = this.templates.get(templateName);
47
+ if (!template)
48
+ return undefined;
49
+ return {
50
+ name: templateName,
51
+ format: template.format || "unknown",
52
+ path: template.path,
53
+ description: template.description,
54
+ examples: template.examples || [],
55
+ };
56
+ }
57
+ /**
58
+ * Check if template exists
59
+ * @param templateName Template name
60
+ */
61
+ hasTemplate(templateName) {
62
+ return this.templates.has(templateName);
63
+ }
64
+ /**
65
+ * Remove a template
66
+ * @param templateName Template name
67
+ */
68
+ unregisterTemplate(templateName) {
69
+ const removed = this.templates.delete(templateName);
70
+ this.templateCache.delete(templateName);
71
+ if (removed) {
72
+ this.logger.debug(`Unregistered template: ${templateName}`);
73
+ }
74
+ return removed;
75
+ }
76
+ /**
77
+ * Clear all templates and cache
78
+ */
79
+ clearTemplates() {
80
+ this.templates.clear();
81
+ this.templateCache.clear();
82
+ this.logger.debug("Cleared all templates");
83
+ }
84
+ /**
85
+ * Validate template context
86
+ * @param context Template context
87
+ * @param requiredFields Required context fields
88
+ */
89
+ validateContext(context, requiredFields = []) {
90
+ for (const field of requiredFields) {
91
+ if (!(field in context)) {
92
+ throw new TemplateError(`Missing required context field: ${field}`, "unknown", context, {
93
+ missingVariables: [field],
94
+ availableTemplates: this.getAvailableTemplates(),
95
+ });
96
+ }
97
+ }
98
+ }
99
+ /**
100
+ * Register default template helpers
101
+ */
102
+ registerDefaultHelpers() {
103
+ // String manipulation helpers
104
+ this.registerHelper("capitalize", (str) => str.charAt(0).toUpperCase() + str.slice(1));
105
+ this.registerHelper("lowercase", (str) => str.toLowerCase());
106
+ this.registerHelper("uppercase", (str) => str.toUpperCase());
107
+ this.registerHelper("camelCase", (str) => str.replace(/[-_\s]+(.)/g, (_, char) => char.toUpperCase()));
108
+ this.registerHelper("pascalCase", (str) => {
109
+ const camelCase = str.replace(/[-_\s]+(.)/g, (_, char) => char.toUpperCase());
110
+ return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);
111
+ });
112
+ this.registerHelper("snakeCase", (str) => str
113
+ .replace(/([A-Z])/g, "_$1")
114
+ .replace(/[-\s]+/g, "_")
115
+ .toLowerCase()
116
+ .replace(/^_/, ""));
117
+ // Array helpers
118
+ this.registerHelper("join", (arr, separator = ", ") => Array.isArray(arr) ? arr.join(separator) : "");
119
+ this.registerHelper("length", (arr) => Array.isArray(arr) ? arr.length : 0);
120
+ // Logic helpers
121
+ this.registerHelper("eq", (a, b) => a === b);
122
+ this.registerHelper("ne", (a, b) => a !== b);
123
+ this.registerHelper("gt", (a, b) => a > b);
124
+ this.registerHelper("lt", (a, b) => a < b);
125
+ // Utility helpers
126
+ this.registerHelper("json", (obj) => JSON.stringify(obj, null, 2));
127
+ this.registerHelper("indent", (str, spaces = 2) => str
128
+ .split("\n")
129
+ .map((line) => " ".repeat(spaces) + line)
130
+ .join("\n"));
131
+ this.registerHelper("timestamp", () => new Date().toISOString());
132
+ }
133
+ }
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Abstract base class for language-specific type mapping
3
+ *
4
+ * This provides the interface that all language generators must implement
5
+ * to convert FHIR TypeSchema types into their target language types.
6
+ */
7
+ /**
8
+ * Abstract type mapper for language-specific type conversion
9
+ */
10
+ export class TypeMapper {
11
+ options;
12
+ constructor(options = {}) {
13
+ this.options = {
14
+ generateNullable: true,
15
+ strictTypes: true,
16
+ customMappings: {},
17
+ preferArraySyntax: true,
18
+ namingConvention: "PascalCase",
19
+ ...options,
20
+ };
21
+ }
22
+ // ==========================================
23
+ // Concrete Methods - Shared functionality
24
+ // ==========================================
25
+ /**
26
+ * Main entry point for type mapping
27
+ * @param schemaType Type from TypeSchema
28
+ */
29
+ mapType(schemaType) {
30
+ // Handle primitive types
31
+ if (typeof schemaType === "string") {
32
+ return this.mapPrimitive(schemaType);
33
+ }
34
+ // Handle complex types
35
+ if (schemaType && typeof schemaType === "object") {
36
+ const kind = schemaType.kind || schemaType.type;
37
+ switch (kind) {
38
+ case "primitive-type":
39
+ return this.mapPrimitive(schemaType.name);
40
+ case "reference":
41
+ return this.mapReference(schemaType.targets || []);
42
+ case "array": {
43
+ const elementType = this.mapType(schemaType.element);
44
+ return this.mapArray(elementType);
45
+ }
46
+ case "enum":
47
+ case "coded":
48
+ return this.mapEnum(schemaType.values || [], schemaType.name);
49
+ case "complex-type":
50
+ case "resource":
51
+ return this.mapComplexType(schemaType);
52
+ default:
53
+ return this.mapUnknownType(schemaType);
54
+ }
55
+ }
56
+ return this.mapUnknownType(schemaType);
57
+ }
58
+ /**
59
+ * Map a complex type (resource, complex-type)
60
+ * @param schemaType Complex type from schema
61
+ */
62
+ mapComplexType(schemaType) {
63
+ const typeName = this.formatTypeName(schemaType.name || "Unknown");
64
+ return {
65
+ name: typeName,
66
+ isPrimitive: false,
67
+ importPath: this.calculateImportPath(schemaType),
68
+ nullable: !schemaType.required && this.options.generateNullable,
69
+ metadata: {
70
+ kind: schemaType.kind,
71
+ package: schemaType.package,
72
+ },
73
+ };
74
+ }
75
+ /**
76
+ * Handle unknown/unmapped types
77
+ * @param schemaType Unknown type
78
+ */
79
+ mapUnknownType(schemaType) {
80
+ // console.warn(`Unknown type encountered:`, schemaType);
81
+ return {
82
+ name: "unknown",
83
+ isPrimitive: true,
84
+ nullable: true,
85
+ metadata: {
86
+ originalType: schemaType,
87
+ warning: "unmapped_type",
88
+ },
89
+ };
90
+ }
91
+ /**
92
+ * Calculate import path for a type
93
+ * @param schemaType Type to calculate import for
94
+ */
95
+ calculateImportPath(schemaType) {
96
+ if (!schemaType.name)
97
+ return undefined;
98
+ const fileName = this.formatFileName(schemaType.name);
99
+ return `./${fileName}`;
100
+ }
101
+ /**
102
+ * Apply naming convention to a string
103
+ * @param name Input name
104
+ */
105
+ applyNamingConvention(name) {
106
+ switch (this.options.namingConvention) {
107
+ case "camelCase":
108
+ return toCamelCase(name);
109
+ case "PascalCase":
110
+ return toPascalCase(name);
111
+ case "snake_case":
112
+ return toSnakeCase(name);
113
+ case "kebab-case":
114
+ return toKebabCase(name);
115
+ default:
116
+ return name;
117
+ }
118
+ }
119
+ /**
120
+ * Get custom mapping if available
121
+ * @param type Original type name
122
+ */
123
+ getCustomMapping(type) {
124
+ return this.options.customMappings[type];
125
+ }
126
+ /**
127
+ * Check if type should be nullable
128
+ * @param required Whether field is required
129
+ */
130
+ shouldBeNullable(required) {
131
+ return !required && this.options.generateNullable;
132
+ }
133
+ }
134
+ // ==========================================
135
+ // Utility Functions
136
+ // ==========================================
137
+ function toCamelCase(str) {
138
+ return str.replace(/[-_\s]+(.)?/g, (_, char) => char?.toUpperCase() || "");
139
+ }
140
+ function toPascalCase(str) {
141
+ const camelCase = toCamelCase(str);
142
+ return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);
143
+ }
144
+ function toSnakeCase(str) {
145
+ return str
146
+ .replace(/([A-Z])/g, "_$1")
147
+ .replace(/[-\s]+/g, "_")
148
+ .toLowerCase()
149
+ .replace(/^_/, "");
150
+ }
151
+ function toKebabCase(str) {
152
+ return toSnakeCase(str).replace(/_/g, "-");
153
+ }
@@ -2,7 +2,7 @@
2
2
  * TypeScript-specific type mapper implementation
3
3
  */
4
4
  import type { TypeSchemaIdentifier } from "../../../typeschema/type-schema.types";
5
- import { type LanguageType, TypeMapper, type TypeMapperOptions } from "./TypeMapper";
5
+ import { type LanguageType, TypeMapper, type TypeMapperOptions } from "./TypeMapper.js";
6
6
  /**
7
7
  * TypeScript-specific options
8
8
  */
@@ -1 +1 @@
1
- {"version":3,"file":"TypeScriptTypeMapper.d.ts","sourceRoot":"","sources":["../../../../src/api/generators/base/TypeScriptTypeMapper.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,EACN,KAAK,YAAY,EACjB,UAAU,EACV,KAAK,iBAAiB,EACtB,MAAM,cAAc,CAAC;AAEtB;;GAEG;AACH,MAAM,WAAW,2BAA4B,SAAQ,iBAAiB;IACrE,2DAA2D;IAC3D,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,uDAAuD;IACvD,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,8DAA8D;IAC9D,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,gCAAgC;IAChC,YAAY,CAAC,EAAE,KAAK,GAAG,UAAU,CAAC;CAClC;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,UAAU;IACnD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwC;gBAEtD,OAAO,GAAE,2BAAgC;IAarD,eAAe,IAAI,MAAM;IAIzB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY;IAgE5C,YAAY,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,YAAY;IA6C3D,QAAQ,CAAC,WAAW,EAAE,YAAY,GAAG,YAAY;IA4BjD,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,GAAG,YAAY;IAmBhE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,YAAY;IAiBtD,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIpC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIrC,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIpC;;;;;OAKG;IACH,sBAAsB,CACrB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,YAAY,EACvB,QAAQ,EAAE,OAAO,GACf,MAAM;IAOT;;;OAGG;IACH,uBAAuB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS;IAY/D;;;OAGG;IACH,kBAAkB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE;CAYnD"}
1
+ {"version":3,"file":"TypeScriptTypeMapper.d.ts","sourceRoot":"","sources":["../../../../src/api/generators/base/TypeScriptTypeMapper.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,EACN,KAAK,YAAY,EACjB,UAAU,EACV,KAAK,iBAAiB,EACtB,MAAM,iBAAiB,CAAC;AAEzB;;GAEG;AACH,MAAM,WAAW,2BAA4B,SAAQ,iBAAiB;IACrE,2DAA2D;IAC3D,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,uDAAuD;IACvD,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,8DAA8D;IAC9D,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,gCAAgC;IAChC,YAAY,CAAC,EAAE,KAAK,GAAG,UAAU,CAAC;CAClC;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,UAAU;IACnD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwC;gBAEtD,OAAO,GAAE,2BAAgC;IAarD,eAAe,IAAI,MAAM;IAIzB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY;IAgE5C,YAAY,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,YAAY;IA6C3D,QAAQ,CAAC,WAAW,EAAE,YAAY,GAAG,YAAY;IA4BjD,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,GAAG,YAAY;IAmBhE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,YAAY;IAiBtD,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIpC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIrC,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIpC;;;;;OAKG;IACH,sBAAsB,CACrB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,YAAY,EACvB,QAAQ,EAAE,OAAO,GACf,MAAM;IAOT;;;OAGG;IACH,uBAAuB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS;IAY/D;;;OAGG;IACH,kBAAkB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE;CAYnD"}