@atomic-ehr/codegen 0.0.1-canary.20250821160126.c552195 → 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.
- package/dist/api/builder.d.ts +3 -3
- package/dist/api/builder.d.ts.map +1 -1
- package/dist/api/builder.js +374 -0
- package/dist/api/generators/base/BaseGenerator.d.ts +4 -4
- package/dist/api/generators/base/BaseGenerator.d.ts.map +1 -1
- package/dist/api/generators/base/BaseGenerator.js +572 -0
- package/dist/api/generators/base/FileManager.d.ts +2 -2
- package/dist/api/generators/base/FileManager.d.ts.map +1 -1
- package/dist/api/generators/base/FileManager.js +204 -0
- package/dist/api/generators/base/PythonTypeMapper.d.ts +2 -2
- package/dist/api/generators/base/PythonTypeMapper.d.ts.map +1 -1
- package/dist/api/generators/base/PythonTypeMapper.js +71 -0
- package/dist/api/generators/base/TemplateEngine.d.ts +1 -1
- package/dist/api/generators/base/TemplateEngine.d.ts.map +1 -1
- package/dist/api/generators/base/TemplateEngine.js +133 -0
- package/dist/api/generators/base/TypeMapper.js +153 -0
- package/dist/api/generators/base/TypeScriptTypeMapper.d.ts +1 -1
- package/dist/api/generators/base/TypeScriptTypeMapper.d.ts.map +1 -1
- package/dist/api/generators/base/TypeScriptTypeMapper.js +232 -0
- package/dist/api/generators/base/builders/DirectoryBuilder.d.ts +4 -4
- package/dist/api/generators/base/builders/DirectoryBuilder.d.ts.map +1 -1
- package/dist/api/generators/base/builders/DirectoryBuilder.js +215 -0
- package/dist/api/generators/base/builders/FileBuilder.d.ts +2 -2
- package/dist/api/generators/base/builders/FileBuilder.d.ts.map +1 -1
- package/dist/api/generators/base/builders/FileBuilder.js +408 -0
- package/dist/api/generators/base/builders/IndexBuilder.d.ts +2 -2
- package/dist/api/generators/base/builders/IndexBuilder.d.ts.map +1 -1
- package/dist/api/generators/base/builders/IndexBuilder.js +290 -0
- package/dist/api/generators/base/enhanced-errors.d.ts +2 -2
- package/dist/api/generators/base/enhanced-errors.d.ts.map +1 -1
- package/dist/api/generators/base/enhanced-errors.js +259 -0
- package/dist/api/generators/base/error-handler.d.ts +1 -1
- package/dist/api/generators/base/error-handler.d.ts.map +1 -1
- package/dist/api/generators/base/error-handler.js +243 -0
- package/dist/api/generators/base/errors.d.ts +2 -2
- package/dist/api/generators/base/errors.d.ts.map +1 -1
- package/dist/api/generators/base/errors.js +694 -0
- package/dist/api/generators/base/index.d.ts +22 -22
- package/dist/api/generators/base/index.d.ts.map +1 -1
- package/dist/api/generators/base/index.js +161 -0
- package/dist/api/generators/base/types.d.ts +2 -2
- package/dist/api/generators/base/types.d.ts.map +1 -1
- package/dist/api/generators/base/types.js +12 -0
- package/dist/api/generators/rest-client.d.ts +2 -2
- package/dist/api/generators/rest-client.d.ts.map +1 -1
- package/dist/api/generators/rest-client.js +847 -0
- package/dist/api/generators/search-parameter-enhancer.d.ts +1 -1
- package/dist/api/generators/search-parameter-enhancer.d.ts.map +1 -1
- package/dist/api/generators/search-parameter-enhancer.js +801 -0
- package/dist/api/generators/types.js +4 -0
- package/dist/api/generators/typescript.d.ts +3 -3
- package/dist/api/generators/typescript.d.ts.map +1 -1
- package/dist/api/generators/typescript.js +537 -0
- package/dist/api/generators/validation-generator.js +632 -0
- package/dist/api/index.d.ts +10 -10
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +51 -0
- package/dist/cli/commands/generate/typescript.d.ts +1 -1
- package/dist/cli/commands/generate/typescript.d.ts.map +1 -1
- package/dist/cli/commands/generate/typescript.js +52 -0
- package/dist/cli/commands/generate.d.ts +5 -12
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +158 -0
- package/dist/cli/commands/index.d.ts +2 -1
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +100 -0
- package/dist/cli/commands/typeschema/generate.js +130 -0
- package/dist/cli/commands/typeschema.js +48 -0
- package/dist/cli/index.js +12 -8664
- package/dist/cli/utils/log.d.ts +2 -2
- package/dist/cli/utils/log.d.ts.map +1 -1
- package/dist/cli/utils/log.js +23 -0
- package/dist/cli/utils/prompts.js +224 -0
- package/dist/cli/utils/spinner.js +270 -0
- package/dist/config.d.ts +22 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +703 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +84 -38
- package/dist/logger.js +290 -0
- package/dist/typeschema/cache.d.ts +2 -2
- package/dist/typeschema/cache.d.ts.map +1 -1
- package/dist/typeschema/cache.js +285 -0
- package/dist/typeschema/core/binding.d.ts +1 -1
- package/dist/typeschema/core/binding.d.ts.map +1 -1
- package/dist/typeschema/core/binding.js +187 -0
- package/dist/typeschema/core/field-builder.d.ts +1 -1
- package/dist/typeschema/core/field-builder.d.ts.map +1 -1
- package/dist/typeschema/core/field-builder.js +259 -0
- package/dist/typeschema/core/identifier.js +117 -0
- package/dist/typeschema/core/nested-types.d.ts +1 -1
- package/dist/typeschema/core/nested-types.d.ts.map +1 -1
- package/dist/typeschema/core/nested-types.js +111 -0
- package/dist/typeschema/core/transformer.d.ts +2 -2
- package/dist/typeschema/core/transformer.d.ts.map +1 -1
- package/dist/typeschema/core/transformer.js +345 -0
- package/dist/typeschema/generator.d.ts +3 -3
- package/dist/typeschema/generator.d.ts.map +1 -1
- package/dist/typeschema/generator.js +352 -0
- package/dist/typeschema/index.d.ts +14 -14
- package/dist/typeschema/index.d.ts.map +1 -1
- package/dist/typeschema/index.js +92 -0
- package/dist/typeschema/parser.d.ts +2 -2
- package/dist/typeschema/parser.d.ts.map +1 -1
- package/dist/typeschema/parser.js +310 -0
- package/dist/typeschema/profile/processor.d.ts +1 -1
- package/dist/typeschema/profile/processor.d.ts.map +1 -1
- package/dist/typeschema/profile/processor.js +268 -0
- package/dist/typeschema/schema.js +456 -0
- package/dist/typeschema/type-schema.types.js +39 -0
- package/dist/typeschema/types.js +4 -0
- package/dist/typeschema/utils.d.ts +1 -1
- package/dist/typeschema/utils.d.ts.map +1 -1
- package/dist/typeschema/utils.js +13 -0
- package/dist/typeschema/value-set/processor.d.ts +1 -1
- package/dist/typeschema/value-set/processor.d.ts.map +1 -1
- package/dist/typeschema/value-set/processor.js +168 -0
- package/dist/utils/codegen-logger.js +204 -0
- package/dist/utils.js +42 -0
- package/package.json +15 -4
- package/dist/index-e7pfye24.js +0 -8532
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Value Set Processing
|
|
3
|
+
*
|
|
4
|
+
* Functions for transforming FHIR ValueSets into TypeSchema format
|
|
5
|
+
*/
|
|
6
|
+
import { buildValueSetIdentifier } from "../core/identifier.js";
|
|
7
|
+
/**
|
|
8
|
+
* Extract concepts from a CodeSystem
|
|
9
|
+
*/
|
|
10
|
+
async function extractCodeSystemConcepts(codeSystemUrl, manager) {
|
|
11
|
+
try {
|
|
12
|
+
const codeSystem = await manager.resolve(codeSystemUrl);
|
|
13
|
+
if (!codeSystem || codeSystem.resourceType !== "CodeSystem") {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
const concepts = [];
|
|
17
|
+
// Recursive function to extract concepts (including nested ones)
|
|
18
|
+
const extractConcepts = (conceptList, system) => {
|
|
19
|
+
for (const concept of conceptList) {
|
|
20
|
+
concepts.push({
|
|
21
|
+
system,
|
|
22
|
+
code: concept.code,
|
|
23
|
+
display: concept.display,
|
|
24
|
+
});
|
|
25
|
+
// Handle nested concepts
|
|
26
|
+
if (concept.concept) {
|
|
27
|
+
extractConcepts(concept.concept, system);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
if (codeSystem.concept) {
|
|
32
|
+
extractConcepts(codeSystem.concept, codeSystemUrl);
|
|
33
|
+
}
|
|
34
|
+
return concepts;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Process ValueSet compose include/exclude
|
|
42
|
+
*/
|
|
43
|
+
async function processComposeItem(item, manager) {
|
|
44
|
+
const concepts = [];
|
|
45
|
+
// Direct concept list
|
|
46
|
+
if (item.concept) {
|
|
47
|
+
for (const concept of item.concept) {
|
|
48
|
+
concepts.push({
|
|
49
|
+
system: item.system,
|
|
50
|
+
code: concept.code,
|
|
51
|
+
display: concept.display,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return concepts;
|
|
55
|
+
}
|
|
56
|
+
// Include all from CodeSystem (no filter)
|
|
57
|
+
if (item.system && !item.filter) {
|
|
58
|
+
const csConcepts = await extractCodeSystemConcepts(item.system, manager);
|
|
59
|
+
if (csConcepts) {
|
|
60
|
+
concepts.push(...csConcepts);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Include from another ValueSet
|
|
64
|
+
if (item.valueSet) {
|
|
65
|
+
for (const vsUrl of item.valueSet) {
|
|
66
|
+
try {
|
|
67
|
+
const vs = await manager.resolve(vsUrl);
|
|
68
|
+
if (vs) {
|
|
69
|
+
const vsConcepts = await extractValueSetConcepts(vs, manager);
|
|
70
|
+
if (vsConcepts) {
|
|
71
|
+
concepts.push(...vsConcepts);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// Ignore if we can't resolve
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return concepts;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Extract all concepts from a ValueSet
|
|
84
|
+
*/
|
|
85
|
+
export async function extractValueSetConcepts(valueSet, manager) {
|
|
86
|
+
try {
|
|
87
|
+
const concepts = [];
|
|
88
|
+
if (valueSet.compose) {
|
|
89
|
+
// Process includes
|
|
90
|
+
if (valueSet.compose.include) {
|
|
91
|
+
for (const include of valueSet.compose.include) {
|
|
92
|
+
const includeConcepts = await processComposeItem(include, manager);
|
|
93
|
+
concepts.push(...includeConcepts);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Process excludes (remove them from the list)
|
|
97
|
+
if (valueSet.compose.exclude) {
|
|
98
|
+
const excludeConcepts = new Set();
|
|
99
|
+
for (const exclude of valueSet.compose.exclude) {
|
|
100
|
+
const excludeList = await processComposeItem(exclude, manager);
|
|
101
|
+
for (const concept of excludeList) {
|
|
102
|
+
excludeConcepts.add(`${concept.system}|${concept.code}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Filter out excluded concepts
|
|
106
|
+
return concepts.filter((c) => !excludeConcepts.has(`${c.system}|${c.code}`));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return concepts.length > 0 ? concepts : undefined;
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
console.error("Error extracting ValueSet concepts:", error);
|
|
113
|
+
return undefined;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Transform a FHIR ValueSet to TypeSchema format
|
|
118
|
+
*/
|
|
119
|
+
export async function transformValueSet(valueSet, manager, packageInfo) {
|
|
120
|
+
const identifier = buildValueSetIdentifier(valueSet.url, valueSet, packageInfo);
|
|
121
|
+
const typeSchemaValueSet = {
|
|
122
|
+
identifier,
|
|
123
|
+
};
|
|
124
|
+
// Add description if present
|
|
125
|
+
if (valueSet.description) {
|
|
126
|
+
typeSchemaValueSet.description = valueSet.description;
|
|
127
|
+
}
|
|
128
|
+
// Try to extract concepts
|
|
129
|
+
const concepts = await extractValueSetConcepts(valueSet, manager);
|
|
130
|
+
if (concepts && concepts.length > 0) {
|
|
131
|
+
// If we can expand, include the concepts
|
|
132
|
+
typeSchemaValueSet.concept = concepts;
|
|
133
|
+
}
|
|
134
|
+
else if (valueSet.compose) {
|
|
135
|
+
// If we can't expand, include the compose structure
|
|
136
|
+
typeSchemaValueSet.compose = valueSet.compose;
|
|
137
|
+
}
|
|
138
|
+
// Extract dependencies from compose
|
|
139
|
+
if (valueSet.compose) {
|
|
140
|
+
const deps = [];
|
|
141
|
+
// Helper to process include/exclude
|
|
142
|
+
const processCompose = (items) => {
|
|
143
|
+
for (const item of items) {
|
|
144
|
+
if (item.system) {
|
|
145
|
+
deps.push({
|
|
146
|
+
kind: "value-set",
|
|
147
|
+
package: packageInfo?.name || "undefined",
|
|
148
|
+
version: packageInfo?.version || "undefined",
|
|
149
|
+
name: item.system.split("/").pop() || "unknown",
|
|
150
|
+
url: item.system,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
if (item.valueSet) {
|
|
154
|
+
for (const vsUrl of item.valueSet) {
|
|
155
|
+
deps.push(buildValueSetIdentifier(vsUrl, undefined, packageInfo));
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
if (valueSet.compose.include) {
|
|
161
|
+
processCompose(valueSet.compose.include);
|
|
162
|
+
}
|
|
163
|
+
if (valueSet.compose.exclude) {
|
|
164
|
+
processCompose(valueSet.compose.exclude);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return typeSchemaValueSet;
|
|
168
|
+
}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CodeGen Logger
|
|
3
|
+
*
|
|
4
|
+
* Clean, colorful logging designed for code generation tools
|
|
5
|
+
*/
|
|
6
|
+
import pc from "picocolors";
|
|
7
|
+
/**
|
|
8
|
+
* Simple code generation logger with pretty colors and clean formatting
|
|
9
|
+
*/
|
|
10
|
+
export class CodegenLogger {
|
|
11
|
+
options;
|
|
12
|
+
constructor(options = {}) {
|
|
13
|
+
this.options = {
|
|
14
|
+
timestamp: false,
|
|
15
|
+
verbose: false,
|
|
16
|
+
...options,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
formatMessage(level, message, color) {
|
|
20
|
+
const timestamp = this.options.timestamp
|
|
21
|
+
? `${pc.gray(new Date().toLocaleTimeString())} `
|
|
22
|
+
: "";
|
|
23
|
+
const prefix = this.options.prefix
|
|
24
|
+
? `${pc.cyan(`[${this.options.prefix}]`)} `
|
|
25
|
+
: "";
|
|
26
|
+
return `${timestamp}${color(level)} ${prefix}${message}`;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Success message with checkmark
|
|
30
|
+
*/
|
|
31
|
+
success(message) {
|
|
32
|
+
console.log(this.formatMessage("✅", message, pc.green));
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Error message with X mark
|
|
36
|
+
*/
|
|
37
|
+
error(message, error) {
|
|
38
|
+
console.error(this.formatMessage("❌", message, pc.red));
|
|
39
|
+
if (error && this.options.verbose) {
|
|
40
|
+
console.error(pc.red(` ${error.message}`));
|
|
41
|
+
if (error.stack) {
|
|
42
|
+
console.error(pc.gray(error.stack));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Warning message with warning sign
|
|
48
|
+
*/
|
|
49
|
+
warn(message) {
|
|
50
|
+
console.warn(this.formatMessage("⚠️", message, pc.yellow));
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Info message with info icon
|
|
54
|
+
*/
|
|
55
|
+
info(message) {
|
|
56
|
+
console.log(this.formatMessage("ℹ️", message, pc.blue));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Debug message (only shows in verbose mode)
|
|
60
|
+
*/
|
|
61
|
+
debug(message) {
|
|
62
|
+
if (this.options.verbose) {
|
|
63
|
+
console.log(this.formatMessage("🐛", message, pc.magenta));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Step message with rocket
|
|
68
|
+
*/
|
|
69
|
+
step(message) {
|
|
70
|
+
console.log(this.formatMessage("🚀", message, pc.cyan));
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Progress message with clock
|
|
74
|
+
*/
|
|
75
|
+
progress(message) {
|
|
76
|
+
console.log(this.formatMessage("⏳", message, pc.blue));
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Plain message (no icon, just colored text)
|
|
80
|
+
*/
|
|
81
|
+
plain(message, color = (s) => s) {
|
|
82
|
+
const timestamp = this.options.timestamp
|
|
83
|
+
? `${pc.gray(new Date().toLocaleTimeString())} `
|
|
84
|
+
: "";
|
|
85
|
+
const prefix = this.options.prefix
|
|
86
|
+
? `${pc.cyan(`[${this.options.prefix}]`)} `
|
|
87
|
+
: "";
|
|
88
|
+
console.log(`${timestamp}${prefix}${color(message)}`);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Dimmed/gray text for less important info
|
|
92
|
+
*/
|
|
93
|
+
dim(message) {
|
|
94
|
+
this.plain(message, pc.gray);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Create a child logger with a prefix
|
|
98
|
+
*/
|
|
99
|
+
child(prefix) {
|
|
100
|
+
return new CodegenLogger({
|
|
101
|
+
...this.options,
|
|
102
|
+
prefix: this.options.prefix ? `${this.options.prefix}:${prefix}` : prefix,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Update options
|
|
107
|
+
*/
|
|
108
|
+
configure(options) {
|
|
109
|
+
this.options = { ...this.options, ...options };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Quick logging functions for simple usage
|
|
114
|
+
*/
|
|
115
|
+
const defaultLogger = new CodegenLogger();
|
|
116
|
+
export function success(message) {
|
|
117
|
+
defaultLogger.success(message);
|
|
118
|
+
}
|
|
119
|
+
export function error(message, err) {
|
|
120
|
+
defaultLogger.error(message, err);
|
|
121
|
+
}
|
|
122
|
+
export function warn(message) {
|
|
123
|
+
defaultLogger.warn(message);
|
|
124
|
+
}
|
|
125
|
+
export function info(message) {
|
|
126
|
+
defaultLogger.info(message);
|
|
127
|
+
}
|
|
128
|
+
export function debug(message) {
|
|
129
|
+
defaultLogger.debug(message);
|
|
130
|
+
}
|
|
131
|
+
export function step(message) {
|
|
132
|
+
defaultLogger.step(message);
|
|
133
|
+
}
|
|
134
|
+
export function progress(message) {
|
|
135
|
+
defaultLogger.progress(message);
|
|
136
|
+
}
|
|
137
|
+
export function plain(message, color) {
|
|
138
|
+
defaultLogger.plain(message, color);
|
|
139
|
+
}
|
|
140
|
+
export function dim(message) {
|
|
141
|
+
defaultLogger.dim(message);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Configure the default logger
|
|
145
|
+
*/
|
|
146
|
+
export function configure(options) {
|
|
147
|
+
defaultLogger.configure(options);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Create a new logger instance
|
|
151
|
+
*/
|
|
152
|
+
export function createLogger(options = {}) {
|
|
153
|
+
return new CodegenLogger(options);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Convenience functions for common CLI patterns
|
|
157
|
+
*/
|
|
158
|
+
/**
|
|
159
|
+
* Show a command header with separator
|
|
160
|
+
*/
|
|
161
|
+
export function header(title) {
|
|
162
|
+
console.log();
|
|
163
|
+
console.log(pc.cyan(pc.bold(`━━━ ${title} ━━━`)));
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Show a section break
|
|
167
|
+
*/
|
|
168
|
+
export function section(title) {
|
|
169
|
+
console.log();
|
|
170
|
+
console.log(pc.bold(title));
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Show completion message with stats
|
|
174
|
+
*/
|
|
175
|
+
export function complete(message, duration, stats) {
|
|
176
|
+
let msg = message;
|
|
177
|
+
if (duration) {
|
|
178
|
+
msg += ` ${pc.gray(`(${duration}ms)`)}`;
|
|
179
|
+
}
|
|
180
|
+
success(msg);
|
|
181
|
+
if (stats) {
|
|
182
|
+
Object.entries(stats).forEach(([key, value]) => {
|
|
183
|
+
dim(` ${key}: ${value}`);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Show a list of items
|
|
189
|
+
*/
|
|
190
|
+
export function list(items, bullet = "•") {
|
|
191
|
+
items.forEach((item) => {
|
|
192
|
+
console.log(pc.gray(` ${bullet} ${item}`));
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Show key-value pairs
|
|
197
|
+
*/
|
|
198
|
+
export function table(data) {
|
|
199
|
+
const maxKeyLength = Math.max(...Object.keys(data).map((k) => k.length));
|
|
200
|
+
Object.entries(data).forEach(([key, value]) => {
|
|
201
|
+
const paddedKey = key.padEnd(maxKeyLength);
|
|
202
|
+
console.log(` ${pc.blue(paddedKey)} ${pc.gray("─")} ${value}`);
|
|
203
|
+
});
|
|
204
|
+
}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a string into PascalCase.
|
|
3
|
+
* Examples:
|
|
4
|
+
* - "patient-name" -> "PatientName"
|
|
5
|
+
* - "Patient name" -> "PatientName"
|
|
6
|
+
* - "patient_name" -> "PatientName"
|
|
7
|
+
* - "patientName" -> "PatientName"
|
|
8
|
+
*/
|
|
9
|
+
export function toPascalCase(input) {
|
|
10
|
+
const parts = input
|
|
11
|
+
.replace(/[^A-Za-z0-9]+/g, " ")
|
|
12
|
+
.split(" ")
|
|
13
|
+
.map((p) => p.trim())
|
|
14
|
+
.filter(Boolean);
|
|
15
|
+
if (parts.length === 0)
|
|
16
|
+
return "";
|
|
17
|
+
return parts.map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join("");
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Split an array into chunks of a given size.
|
|
21
|
+
*
|
|
22
|
+
* Examples:
|
|
23
|
+
* - chunkArray([1,2,3,4,5], 2) -> [[1,2],[3,4],[5]]
|
|
24
|
+
* - chunkArray([], 3) -> []
|
|
25
|
+
*
|
|
26
|
+
* @param arr - The array to split.
|
|
27
|
+
* @param size - The maximum size of each chunk (must be >= 1).
|
|
28
|
+
* @returns An array of chunks (each chunk is an array of T).
|
|
29
|
+
* @throws RangeError if size is less than 1.
|
|
30
|
+
*/
|
|
31
|
+
export function chunkArray(arr, size) {
|
|
32
|
+
if (!Number.isInteger(size) || size < 1) {
|
|
33
|
+
throw new RangeError("chunk size must be an integer greater than 0");
|
|
34
|
+
}
|
|
35
|
+
const result = [];
|
|
36
|
+
if (!arr || arr.length === 0)
|
|
37
|
+
return result;
|
|
38
|
+
for (let i = 0; i < arr.length; i += size) {
|
|
39
|
+
result.push(arr.slice(i, i + size));
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atomic-ehr/codegen",
|
|
3
|
-
"version": "0.0.1-canary.
|
|
3
|
+
"version": "0.0.1-canary.20250822150706.c3b8669",
|
|
4
4
|
"description": "Code generation tools for FHIR resources and TypeSchema definitions",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fhir",
|
|
@@ -10,9 +10,20 @@
|
|
|
10
10
|
"ehr",
|
|
11
11
|
"typeschema"
|
|
12
12
|
],
|
|
13
|
-
"module": "./dist/index.js",
|
|
14
13
|
"main": "./dist/index.js",
|
|
15
14
|
"types": "./dist/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"import": "./dist/index.js",
|
|
19
|
+
"default": "./dist/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./cli": {
|
|
22
|
+
"types": "./dist/cli/index.d.ts",
|
|
23
|
+
"import": "./dist/cli/index.js",
|
|
24
|
+
"default": "./dist/cli/index.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
16
27
|
"type": "module",
|
|
17
28
|
"bin": {
|
|
18
29
|
"atomic-codegen": "./dist/cli/index.js"
|
|
@@ -31,9 +42,9 @@
|
|
|
31
42
|
"test:verbose": "bun test --verbose",
|
|
32
43
|
"test:helpers": "bun test test/helpers/",
|
|
33
44
|
"test:quick": "bun test test/unit/ --timeout 5000",
|
|
34
|
-
"build": "rm -rf dist &&
|
|
45
|
+
"build": "rm -rf dist && bunx tsc --project tsconfig.build.json && chmod +x dist/cli/index.js",
|
|
35
46
|
"typecheck": "bunx tsc --noEmit",
|
|
36
|
-
"lint": "biome check --write
|
|
47
|
+
"lint": "biome check --write",
|
|
37
48
|
"quality": "bun run typecheck && bun run lint && bun run test:unit",
|
|
38
49
|
"cli": "bun run src/cli/index.ts",
|
|
39
50
|
"codegen": "bun run src/cli/index.ts",
|