@atomic-ehr/codegen 0.0.1-canary.20251006092200.fdb4a88 → 0.0.1-canary.20251006094042.7f0be72
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 +45 -124
- package/dist/index.d.ts +2130 -62
- package/dist/index.js +5865 -84
- package/dist/index.js.map +1 -0
- package/package.json +3 -7
- package/dist/api/builder.d.ts +0 -154
- package/dist/api/builder.js +0 -341
- package/dist/api/generators/base/BaseGenerator.d.ts +0 -186
- package/dist/api/generators/base/BaseGenerator.js +0 -565
- package/dist/api/generators/base/FileManager.d.ts +0 -88
- package/dist/api/generators/base/FileManager.js +0 -202
- package/dist/api/generators/base/PythonTypeMapper.d.ts +0 -16
- package/dist/api/generators/base/PythonTypeMapper.js +0 -71
- package/dist/api/generators/base/TemplateEngine.d.ts +0 -126
- package/dist/api/generators/base/TemplateEngine.js +0 -133
- package/dist/api/generators/base/TypeMapper.d.ts +0 -129
- package/dist/api/generators/base/TypeMapper.js +0 -153
- package/dist/api/generators/base/TypeScriptTypeMapper.d.ts +0 -51
- package/dist/api/generators/base/TypeScriptTypeMapper.js +0 -232
- package/dist/api/generators/base/builders/DirectoryBuilder.d.ts +0 -99
- package/dist/api/generators/base/builders/DirectoryBuilder.js +0 -215
- package/dist/api/generators/base/builders/FileBuilder.d.ts +0 -160
- package/dist/api/generators/base/builders/FileBuilder.js +0 -406
- package/dist/api/generators/base/builders/IndexBuilder.d.ts +0 -126
- package/dist/api/generators/base/builders/IndexBuilder.js +0 -290
- package/dist/api/generators/base/enhanced-errors.d.ts +0 -84
- package/dist/api/generators/base/enhanced-errors.js +0 -259
- package/dist/api/generators/base/error-handler.d.ts +0 -89
- package/dist/api/generators/base/error-handler.js +0 -243
- package/dist/api/generators/base/errors.d.ts +0 -251
- package/dist/api/generators/base/errors.js +0 -692
- package/dist/api/generators/base/index.d.ts +0 -99
- package/dist/api/generators/base/index.js +0 -160
- package/dist/api/generators/base/types.d.ts +0 -433
- package/dist/api/generators/base/types.js +0 -12
- package/dist/api/generators/types.d.ts +0 -53
- package/dist/api/generators/types.js +0 -4
- package/dist/api/generators/typescript.d.ts +0 -190
- package/dist/api/generators/typescript.js +0 -819
- package/dist/api/index.d.ts +0 -51
- package/dist/api/index.js +0 -50
- package/dist/cli/commands/generate/typescript.d.ts +0 -10
- package/dist/cli/commands/generate/typescript.js +0 -52
- package/dist/cli/commands/generate.d.ts +0 -15
- package/dist/cli/commands/generate.js +0 -159
- package/dist/cli/commands/index.d.ts +0 -29
- package/dist/cli/commands/index.js +0 -100
- package/dist/cli/commands/typeschema/generate.d.ts +0 -19
- package/dist/cli/commands/typeschema/generate.js +0 -124
- package/dist/cli/commands/typeschema.d.ts +0 -10
- package/dist/cli/commands/typeschema.js +0 -47
- package/dist/cli/index.d.ts +0 -9
- package/dist/cli/utils/log.d.ts +0 -10
- package/dist/cli/utils/log.js +0 -23
- package/dist/cli/utils/prompts.d.ts +0 -56
- package/dist/cli/utils/prompts.js +0 -202
- package/dist/cli/utils/spinner.d.ts +0 -110
- package/dist/cli/utils/spinner.js +0 -266
- package/dist/config.d.ts +0 -217
- package/dist/config.js +0 -591
- package/dist/logger.d.ts +0 -157
- package/dist/logger.js +0 -281
- package/dist/typeschema/cache.d.ts +0 -80
- package/dist/typeschema/cache.js +0 -239
- package/dist/typeschema/core/binding.d.ts +0 -11
- package/dist/typeschema/core/binding.js +0 -143
- package/dist/typeschema/core/field-builder.d.ts +0 -12
- package/dist/typeschema/core/field-builder.js +0 -123
- package/dist/typeschema/core/identifier.d.ts +0 -13
- package/dist/typeschema/core/identifier.js +0 -94
- package/dist/typeschema/core/nested-types.d.ts +0 -9
- package/dist/typeschema/core/nested-types.js +0 -93
- package/dist/typeschema/core/transformer.d.ts +0 -11
- package/dist/typeschema/core/transformer.js +0 -235
- package/dist/typeschema/generator.d.ts +0 -36
- package/dist/typeschema/generator.js +0 -243
- package/dist/typeschema/index.d.ts +0 -15
- package/dist/typeschema/index.js +0 -15
- package/dist/typeschema/parser.d.ts +0 -79
- package/dist/typeschema/parser.js +0 -274
- package/dist/typeschema/profile/processor.d.ts +0 -14
- package/dist/typeschema/profile/processor.js +0 -261
- package/dist/typeschema/register.d.ts +0 -21
- package/dist/typeschema/register.js +0 -117
- package/dist/typeschema/types.d.ts +0 -240
- package/dist/typeschema/types.js +0 -19
- package/dist/utils/codegen-logger.d.ts +0 -102
- package/dist/utils/codegen-logger.js +0 -196
- package/dist/utils.d.ts +0 -22
- package/dist/utils.js +0 -42
|
@@ -1,290 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Index file builder for automated exports
|
|
3
|
-
*
|
|
4
|
-
* Automatically generates index files that export all types and functions
|
|
5
|
-
* from a directory, with support for grouping and namespaces.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Builder for index files with intelligent export management
|
|
9
|
-
*
|
|
10
|
-
* Features:
|
|
11
|
-
* - Automatic export detection
|
|
12
|
-
* - Namespace support
|
|
13
|
-
* - Export grouping
|
|
14
|
-
* - Custom headers
|
|
15
|
-
* - Template support
|
|
16
|
-
*/
|
|
17
|
-
export class IndexBuilder {
|
|
18
|
-
config;
|
|
19
|
-
exports = new Map(); // symbol -> from path
|
|
20
|
-
namespaces = new Map(); // namespace -> path
|
|
21
|
-
reExports = new Map(); // export all from path
|
|
22
|
-
header = "";
|
|
23
|
-
footer = "";
|
|
24
|
-
groupingFunction;
|
|
25
|
-
sortFunction;
|
|
26
|
-
constructor(config) {
|
|
27
|
-
this.config = config;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Add exports from a specific file
|
|
31
|
-
* @param exportNames Export names
|
|
32
|
-
* @param fromPath Path to file (without extension)
|
|
33
|
-
*/
|
|
34
|
-
withExports(exportNames, fromPath) {
|
|
35
|
-
for (const name of exportNames) {
|
|
36
|
-
this.exports.set(name, fromPath);
|
|
37
|
-
}
|
|
38
|
-
return this;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Add a single export
|
|
42
|
-
* @param exportName Export name
|
|
43
|
-
* @param fromPath Path to file
|
|
44
|
-
*/
|
|
45
|
-
withExport(exportName, fromPath) {
|
|
46
|
-
this.exports.set(exportName, fromPath);
|
|
47
|
-
return this;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Add namespace exports
|
|
51
|
-
* @param namespaces Map of namespace to path
|
|
52
|
-
*/
|
|
53
|
-
withNamespaces(namespaces) {
|
|
54
|
-
for (const [ns, path] of Object.entries(namespaces)) {
|
|
55
|
-
this.namespaces.set(ns, path);
|
|
56
|
-
}
|
|
57
|
-
return this;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Add namespace export
|
|
61
|
-
* @param namespace Namespace name
|
|
62
|
-
* @param path Path to export as namespace
|
|
63
|
-
*/
|
|
64
|
-
withNamespace(namespace, path) {
|
|
65
|
-
this.namespaces.set(namespace, path);
|
|
66
|
-
return this;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Re-export all from paths
|
|
70
|
-
* @param paths Paths to re-export all from
|
|
71
|
-
*/
|
|
72
|
-
withReExports(paths) {
|
|
73
|
-
for (const path of paths) {
|
|
74
|
-
this.reExports.set(path, path);
|
|
75
|
-
}
|
|
76
|
-
return this;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Add re-export
|
|
80
|
-
* @param path Path to re-export all from
|
|
81
|
-
*/
|
|
82
|
-
withReExport(path) {
|
|
83
|
-
this.reExports.set(path, path);
|
|
84
|
-
return this;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Set header content
|
|
88
|
-
* @param header Header content
|
|
89
|
-
*/
|
|
90
|
-
withHeader(header) {
|
|
91
|
-
this.header = header;
|
|
92
|
-
return this;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Set footer content
|
|
96
|
-
* @param footer Footer content
|
|
97
|
-
*/
|
|
98
|
-
withFooter(footer) {
|
|
99
|
-
this.footer = footer;
|
|
100
|
-
return this;
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Group exports by function
|
|
104
|
-
* @param fn Function that returns group name for export
|
|
105
|
-
*/
|
|
106
|
-
groupBy(fn) {
|
|
107
|
-
this.groupingFunction = fn;
|
|
108
|
-
return this;
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Sort exports by function
|
|
112
|
-
* @param fn Sort function for [exportName, fromPath] tuples
|
|
113
|
-
*/
|
|
114
|
-
sortBy(fn) {
|
|
115
|
-
this.sortFunction = fn;
|
|
116
|
-
return this;
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Auto-discover exports from directory
|
|
120
|
-
* @param filePattern Pattern to match files (e.g., "*.ts")
|
|
121
|
-
*/
|
|
122
|
-
async autoDiscover(_filePattern) {
|
|
123
|
-
// This is a placeholder - in a real implementation, this would:
|
|
124
|
-
// 1. Read all files in the directory
|
|
125
|
-
// 2. Parse TypeScript/JavaScript to extract exports
|
|
126
|
-
// 3. Add them to the exports map
|
|
127
|
-
this.config.logger.debug(`Auto-discovering exports in ${this.config.directory}`);
|
|
128
|
-
// For now, just log that this feature would be implemented
|
|
129
|
-
this.config.logger.warn("Auto-discovery not yet implemented - manually add exports");
|
|
130
|
-
return this;
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Save the index file
|
|
134
|
-
*/
|
|
135
|
-
async save() {
|
|
136
|
-
const content = this.generateContent();
|
|
137
|
-
const indexPath = `${this.config.directory}/index.ts`;
|
|
138
|
-
const result = await this.config.fileManager.writeFile(indexPath, content);
|
|
139
|
-
this.config.logger.debug(`Generated index file: ${indexPath}`);
|
|
140
|
-
return result.path;
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Build content without saving (for preview)
|
|
144
|
-
*/
|
|
145
|
-
build() {
|
|
146
|
-
return this.generateContent();
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Generate the index file content
|
|
150
|
-
*/
|
|
151
|
-
generateContent() {
|
|
152
|
-
const lines = [];
|
|
153
|
-
// Add header
|
|
154
|
-
if (this.header) {
|
|
155
|
-
lines.push(this.header);
|
|
156
|
-
lines.push("");
|
|
157
|
-
}
|
|
158
|
-
// Add re-exports first
|
|
159
|
-
if (this.reExports.size > 0) {
|
|
160
|
-
lines.push("// Re-exports");
|
|
161
|
-
for (const path of this.reExports.values()) {
|
|
162
|
-
lines.push(`export * from './${path}';`);
|
|
163
|
-
}
|
|
164
|
-
lines.push("");
|
|
165
|
-
}
|
|
166
|
-
// Process exports
|
|
167
|
-
if (this.exports.size > 0) {
|
|
168
|
-
if (this.groupingFunction) {
|
|
169
|
-
this.generateGroupedExports(lines);
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
172
|
-
this.generateSimpleExports(lines);
|
|
173
|
-
}
|
|
174
|
-
lines.push("");
|
|
175
|
-
}
|
|
176
|
-
// Add namespace exports
|
|
177
|
-
if (this.namespaces.size > 0) {
|
|
178
|
-
lines.push("// Namespace exports");
|
|
179
|
-
const sortedNamespaces = Array.from(this.namespaces.entries()).sort();
|
|
180
|
-
for (const [ns, path] of sortedNamespaces) {
|
|
181
|
-
lines.push(`export * as ${ns} from './${path}';`);
|
|
182
|
-
}
|
|
183
|
-
lines.push("");
|
|
184
|
-
}
|
|
185
|
-
// Add footer
|
|
186
|
-
if (this.footer) {
|
|
187
|
-
lines.push(this.footer);
|
|
188
|
-
}
|
|
189
|
-
// Clean up extra empty lines
|
|
190
|
-
const content = lines
|
|
191
|
-
.join("\n")
|
|
192
|
-
.replace(/\n{3,}/g, "\n\n")
|
|
193
|
-
.trim();
|
|
194
|
-
return `${content}\n`; // Ensure file ends with newline
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Generate simple exports without grouping
|
|
198
|
-
*/
|
|
199
|
-
generateSimpleExports(lines) {
|
|
200
|
-
lines.push("// Exports");
|
|
201
|
-
let exportEntries = Array.from(this.exports.entries());
|
|
202
|
-
// Apply custom sorting if provided
|
|
203
|
-
if (this.sortFunction) {
|
|
204
|
-
exportEntries = exportEntries.sort(this.sortFunction);
|
|
205
|
-
}
|
|
206
|
-
else {
|
|
207
|
-
// Default: sort by export name
|
|
208
|
-
exportEntries = exportEntries.sort(([a], [b]) => a.localeCompare(b));
|
|
209
|
-
}
|
|
210
|
-
// Group by path for cleaner output
|
|
211
|
-
const exportsByPath = new Map();
|
|
212
|
-
for (const [exportName, fromPath] of exportEntries) {
|
|
213
|
-
if (!exportsByPath.has(fromPath)) {
|
|
214
|
-
exportsByPath.set(fromPath, []);
|
|
215
|
-
}
|
|
216
|
-
exportsByPath.get(fromPath)?.push(exportName);
|
|
217
|
-
}
|
|
218
|
-
// Generate export statements
|
|
219
|
-
for (const [path, exports] of exportsByPath) {
|
|
220
|
-
const sortedExports = exports.sort();
|
|
221
|
-
if (sortedExports.length === 1) {
|
|
222
|
-
lines.push(`export type { ${sortedExports[0]} } from './${path}';`);
|
|
223
|
-
}
|
|
224
|
-
else if (sortedExports.length <= 3) {
|
|
225
|
-
lines.push(`export type { ${sortedExports.join(", ")} } from './${path}';`);
|
|
226
|
-
}
|
|
227
|
-
else {
|
|
228
|
-
lines.push(`export type {`);
|
|
229
|
-
sortedExports.forEach((exp, index) => {
|
|
230
|
-
const isLast = index === sortedExports.length - 1;
|
|
231
|
-
lines.push(`\t${exp}${isLast ? "" : ","}`);
|
|
232
|
-
});
|
|
233
|
-
lines.push(`} from './${path}';`);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Generate grouped exports
|
|
239
|
-
*/
|
|
240
|
-
generateGroupedExports(lines) {
|
|
241
|
-
if (!this.groupingFunction)
|
|
242
|
-
return;
|
|
243
|
-
const groups = new Map();
|
|
244
|
-
// Group exports
|
|
245
|
-
for (const [exportName, fromPath] of this.exports) {
|
|
246
|
-
const group = this.groupingFunction(exportName);
|
|
247
|
-
if (!groups.has(group)) {
|
|
248
|
-
groups.set(group, new Map());
|
|
249
|
-
}
|
|
250
|
-
const groupMap = groups.get(group);
|
|
251
|
-
if (!groupMap.has(fromPath)) {
|
|
252
|
-
groupMap.set(fromPath, []);
|
|
253
|
-
}
|
|
254
|
-
groupMap.get(fromPath)?.push(exportName);
|
|
255
|
-
}
|
|
256
|
-
// Generate grouped output
|
|
257
|
-
const sortedGroups = Array.from(groups.entries()).sort();
|
|
258
|
-
for (const [groupName, groupExports] of sortedGroups) {
|
|
259
|
-
lines.push(`// ${groupName}`);
|
|
260
|
-
for (const [path, exports] of groupExports) {
|
|
261
|
-
const sortedExports = exports.sort();
|
|
262
|
-
if (sortedExports.length === 1) {
|
|
263
|
-
lines.push(`export type { ${sortedExports[0]} } from './${path}';`);
|
|
264
|
-
}
|
|
265
|
-
else {
|
|
266
|
-
lines.push(`export type { ${sortedExports.join(", ")} } from './${path}';`);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
lines.push("");
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
/**
|
|
273
|
-
* Get current exports (for testing/debugging)
|
|
274
|
-
*/
|
|
275
|
-
getExports() {
|
|
276
|
-
return new Map(this.exports);
|
|
277
|
-
}
|
|
278
|
-
/**
|
|
279
|
-
* Get current namespaces (for testing/debugging)
|
|
280
|
-
*/
|
|
281
|
-
getNamespaces() {
|
|
282
|
-
return new Map(this.namespaces);
|
|
283
|
-
}
|
|
284
|
-
/**
|
|
285
|
-
* Get current re-exports (for testing/debugging)
|
|
286
|
-
*/
|
|
287
|
-
getReExports() {
|
|
288
|
-
return new Map(this.reExports);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Enhanced error handling with rich context and suggestions
|
|
3
|
-
*
|
|
4
|
-
* This module builds on the basic GeneratorError classes to provide
|
|
5
|
-
* even more detailed error context, smarter suggestions, and better
|
|
6
|
-
* user experience for developers at all skill levels.
|
|
7
|
-
*/
|
|
8
|
-
import type { TypeSchema } from "@typeschema/index";
|
|
9
|
-
import { GeneratorError } from "./errors";
|
|
10
|
-
/**
|
|
11
|
-
* Enhanced schema validation error with smart suggestions
|
|
12
|
-
*/
|
|
13
|
-
export declare class EnhancedSchemaValidationError extends GeneratorError {
|
|
14
|
-
readonly schema: TypeSchema;
|
|
15
|
-
readonly validationErrors: string[];
|
|
16
|
-
readonly userContext?: {
|
|
17
|
-
isBeginnerMode?: boolean;
|
|
18
|
-
previousSuccessfulSchemas?: string[];
|
|
19
|
-
commonPatterns?: string[];
|
|
20
|
-
} | undefined;
|
|
21
|
-
constructor(message: string, schema: TypeSchema, validationErrors: string[], userContext?: {
|
|
22
|
-
isBeginnerMode?: boolean;
|
|
23
|
-
previousSuccessfulSchemas?: string[];
|
|
24
|
-
commonPatterns?: string[];
|
|
25
|
-
} | undefined);
|
|
26
|
-
getSuggestions(): string[];
|
|
27
|
-
/**
|
|
28
|
-
* Get formatted error message for display
|
|
29
|
-
*/
|
|
30
|
-
getFormattedMessage(): string;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Enhanced file operation error with recovery suggestions
|
|
34
|
-
*/
|
|
35
|
-
export declare class EnhancedFileOperationError extends GeneratorError {
|
|
36
|
-
readonly operation: "create" | "write" | "read" | "delete";
|
|
37
|
-
readonly filePath: string;
|
|
38
|
-
readonly originalError?: Error | undefined;
|
|
39
|
-
readonly recoveryOptions?: {
|
|
40
|
-
canRetry?: boolean;
|
|
41
|
-
alternativePaths?: string[];
|
|
42
|
-
permissionFix?: string;
|
|
43
|
-
} | undefined;
|
|
44
|
-
constructor(message: string, operation: "create" | "write" | "read" | "delete", filePath: string, originalError?: Error | undefined, recoveryOptions?: {
|
|
45
|
-
canRetry?: boolean;
|
|
46
|
-
alternativePaths?: string[];
|
|
47
|
-
permissionFix?: string;
|
|
48
|
-
} | undefined);
|
|
49
|
-
getSuggestions(): string[];
|
|
50
|
-
/**
|
|
51
|
-
* Check if this error is recoverable
|
|
52
|
-
*/
|
|
53
|
-
isRecoverable(): boolean;
|
|
54
|
-
/**
|
|
55
|
-
* Get recovery actions user can take
|
|
56
|
-
*/
|
|
57
|
-
getRecoveryActions(): Array<{
|
|
58
|
-
action: string;
|
|
59
|
-
command?: string;
|
|
60
|
-
automatic?: boolean;
|
|
61
|
-
}>;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Enhanced template error with template debugging info
|
|
65
|
-
*/
|
|
66
|
-
export declare class EnhancedTemplateError extends GeneratorError {
|
|
67
|
-
readonly templateName: string;
|
|
68
|
-
readonly templateContext: Record<string, unknown>;
|
|
69
|
-
readonly debugInfo?: {
|
|
70
|
-
availableTemplates?: string[];
|
|
71
|
-
missingVariables?: string[];
|
|
72
|
-
templateSource?: string;
|
|
73
|
-
lineNumber?: number;
|
|
74
|
-
} | undefined;
|
|
75
|
-
constructor(message: string, templateName: string, templateContext: Record<string, unknown>, debugInfo?: {
|
|
76
|
-
availableTemplates?: string[];
|
|
77
|
-
missingVariables?: string[];
|
|
78
|
-
templateSource?: string;
|
|
79
|
-
lineNumber?: number;
|
|
80
|
-
} | undefined);
|
|
81
|
-
getSuggestions(): string[];
|
|
82
|
-
private findSimilarTemplates;
|
|
83
|
-
private levenshteinDistance;
|
|
84
|
-
}
|
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Enhanced error handling with rich context and suggestions
|
|
3
|
-
*
|
|
4
|
-
* This module builds on the basic GeneratorError classes to provide
|
|
5
|
-
* even more detailed error context, smarter suggestions, and better
|
|
6
|
-
* user experience for developers at all skill levels.
|
|
7
|
-
*/
|
|
8
|
-
import { GeneratorError } from "./errors";
|
|
9
|
-
/**
|
|
10
|
-
* Enhanced schema validation error with smart suggestions
|
|
11
|
-
*/
|
|
12
|
-
export class EnhancedSchemaValidationError extends GeneratorError {
|
|
13
|
-
schema;
|
|
14
|
-
validationErrors;
|
|
15
|
-
userContext;
|
|
16
|
-
constructor(message, schema, validationErrors, userContext) {
|
|
17
|
-
super(message, "validation", {
|
|
18
|
-
schemaName: schema.identifier.name,
|
|
19
|
-
schemaKind: schema.identifier.kind,
|
|
20
|
-
schemaPackage: schema.identifier.package,
|
|
21
|
-
validationErrors,
|
|
22
|
-
userContext,
|
|
23
|
-
});
|
|
24
|
-
this.schema = schema;
|
|
25
|
-
this.validationErrors = validationErrors;
|
|
26
|
-
this.userContext = userContext;
|
|
27
|
-
}
|
|
28
|
-
getSuggestions() {
|
|
29
|
-
const suggestions = [];
|
|
30
|
-
// Basic suggestions
|
|
31
|
-
suggestions.push("Check the schema structure matches TypeSchema specification");
|
|
32
|
-
suggestions.push("Verify all required fields are present");
|
|
33
|
-
// Context-aware suggestions based on validation errors
|
|
34
|
-
for (const error of this.validationErrors) {
|
|
35
|
-
if (error.includes("identifier.name")) {
|
|
36
|
-
suggestions.push("Add missing identifier.name field to the schema");
|
|
37
|
-
suggestions.push("Ensure identifier.name is a non-empty string");
|
|
38
|
-
}
|
|
39
|
-
if (error.includes("identifier.kind")) {
|
|
40
|
-
suggestions.push("Set identifier.kind to one of: resource, complex-type, profile, primitive-type");
|
|
41
|
-
suggestions.push("Check FHIR specification for valid kind values");
|
|
42
|
-
}
|
|
43
|
-
if (error.includes("circular")) {
|
|
44
|
-
suggestions.push("Remove circular references between schemas");
|
|
45
|
-
suggestions.push("Use forward references for recursive types");
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
// Beginner-friendly suggestions
|
|
49
|
-
if (this.userContext?.isBeginnerMode) {
|
|
50
|
-
suggestions.push("📚 Review the TypeSchema documentation at: docs/typeschema.md");
|
|
51
|
-
suggestions.push("🔍 Use --verbose flag for more detailed error information");
|
|
52
|
-
if (this.userContext.previousSuccessfulSchemas?.length) {
|
|
53
|
-
suggestions.push(`✅ Compare with working schema: ${this.userContext.previousSuccessfulSchemas[0]}`);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return suggestions;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Get formatted error message for display
|
|
60
|
-
*/
|
|
61
|
-
getFormattedMessage() {
|
|
62
|
-
const lines = [
|
|
63
|
-
`❌ Schema Validation Failed: ${this.message}`,
|
|
64
|
-
"",
|
|
65
|
-
"📍 Context:",
|
|
66
|
-
` Schema: ${this.schema.identifier.name}`,
|
|
67
|
-
` Kind: ${this.schema.identifier.kind}`,
|
|
68
|
-
` Package: ${this.schema.identifier.package || "unknown"}`,
|
|
69
|
-
"",
|
|
70
|
-
];
|
|
71
|
-
if (this.validationErrors.length > 0) {
|
|
72
|
-
lines.push("🔍 Validation Errors:");
|
|
73
|
-
this.validationErrors.forEach((error, index) => {
|
|
74
|
-
lines.push(` ${index + 1}. ${error}`);
|
|
75
|
-
});
|
|
76
|
-
lines.push("");
|
|
77
|
-
}
|
|
78
|
-
const suggestions = this.getSuggestions();
|
|
79
|
-
if (suggestions.length > 0) {
|
|
80
|
-
lines.push("💡 Suggestions:");
|
|
81
|
-
suggestions.forEach((suggestion) => {
|
|
82
|
-
lines.push(` • ${suggestion}`);
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
return lines.join("\n");
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Enhanced file operation error with recovery suggestions
|
|
90
|
-
*/
|
|
91
|
-
export class EnhancedFileOperationError extends GeneratorError {
|
|
92
|
-
operation;
|
|
93
|
-
filePath;
|
|
94
|
-
originalError;
|
|
95
|
-
recoveryOptions;
|
|
96
|
-
constructor(message, operation, filePath, originalError, recoveryOptions) {
|
|
97
|
-
super(message, "writing", {
|
|
98
|
-
operation,
|
|
99
|
-
filePath,
|
|
100
|
-
originalError: originalError?.message,
|
|
101
|
-
recoveryOptions,
|
|
102
|
-
});
|
|
103
|
-
this.operation = operation;
|
|
104
|
-
this.filePath = filePath;
|
|
105
|
-
this.originalError = originalError;
|
|
106
|
-
this.recoveryOptions = recoveryOptions;
|
|
107
|
-
}
|
|
108
|
-
getSuggestions() {
|
|
109
|
-
const suggestions = [];
|
|
110
|
-
// Operation-specific suggestions
|
|
111
|
-
switch (this.operation) {
|
|
112
|
-
case "create":
|
|
113
|
-
case "write":
|
|
114
|
-
suggestions.push("Check if the directory exists and is writable");
|
|
115
|
-
suggestions.push("Verify you have permission to write to this location");
|
|
116
|
-
if (this.filePath.includes(" ")) {
|
|
117
|
-
suggestions.push("File path contains spaces - ensure proper escaping");
|
|
118
|
-
}
|
|
119
|
-
if (this.recoveryOptions?.alternativePaths?.length) {
|
|
120
|
-
suggestions.push("Try alternative output directory:");
|
|
121
|
-
this.recoveryOptions.alternativePaths.forEach((path) => {
|
|
122
|
-
suggestions.push(` • ${path}`);
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
break;
|
|
126
|
-
case "read":
|
|
127
|
-
suggestions.push("Verify the file exists at the specified path");
|
|
128
|
-
suggestions.push("Check file permissions are readable");
|
|
129
|
-
break;
|
|
130
|
-
case "delete":
|
|
131
|
-
suggestions.push("Check if file is locked by another process");
|
|
132
|
-
suggestions.push("Verify delete permissions for this directory");
|
|
133
|
-
break;
|
|
134
|
-
}
|
|
135
|
-
// Permission-specific suggestions
|
|
136
|
-
if (this.originalError?.message.includes("EACCES")) {
|
|
137
|
-
suggestions.push("Permission denied - try running with elevated permissions");
|
|
138
|
-
if (this.recoveryOptions?.permissionFix) {
|
|
139
|
-
suggestions.push(`Fix command: ${this.recoveryOptions.permissionFix}`);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
// Space-related suggestions
|
|
143
|
-
if (this.originalError?.message.includes("ENOSPC")) {
|
|
144
|
-
suggestions.push("Insufficient disk space - free up space and retry");
|
|
145
|
-
suggestions.push("Consider using a different output directory");
|
|
146
|
-
}
|
|
147
|
-
// Recovery suggestions
|
|
148
|
-
if (this.recoveryOptions?.canRetry) {
|
|
149
|
-
suggestions.push("This operation can be retried safely");
|
|
150
|
-
}
|
|
151
|
-
return suggestions;
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Check if this error is recoverable
|
|
155
|
-
*/
|
|
156
|
-
isRecoverable() {
|
|
157
|
-
return this.recoveryOptions?.canRetry || false;
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* Get recovery actions user can take
|
|
161
|
-
*/
|
|
162
|
-
getRecoveryActions() {
|
|
163
|
-
const actions = [];
|
|
164
|
-
if (this.originalError?.message.includes("EACCES")) {
|
|
165
|
-
actions.push({
|
|
166
|
-
action: "Fix file permissions",
|
|
167
|
-
command: `chmod 755 "${this.filePath}"`,
|
|
168
|
-
automatic: false,
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
if (this.originalError?.message.includes("ENOENT")) {
|
|
172
|
-
actions.push({
|
|
173
|
-
action: "Create missing directory",
|
|
174
|
-
command: `mkdir -p "${this.filePath}"`,
|
|
175
|
-
automatic: true,
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
return actions;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Enhanced template error with template debugging info
|
|
183
|
-
*/
|
|
184
|
-
export class EnhancedTemplateError extends GeneratorError {
|
|
185
|
-
templateName;
|
|
186
|
-
templateContext;
|
|
187
|
-
debugInfo;
|
|
188
|
-
constructor(message, templateName, templateContext, debugInfo) {
|
|
189
|
-
super(message, "generation", {
|
|
190
|
-
templateName,
|
|
191
|
-
contextKeys: Object.keys(templateContext),
|
|
192
|
-
debugInfo,
|
|
193
|
-
});
|
|
194
|
-
this.templateName = templateName;
|
|
195
|
-
this.templateContext = templateContext;
|
|
196
|
-
this.debugInfo = debugInfo;
|
|
197
|
-
}
|
|
198
|
-
getSuggestions() {
|
|
199
|
-
const suggestions = [];
|
|
200
|
-
// Template existence suggestions
|
|
201
|
-
if (this.debugInfo?.availableTemplates?.length) {
|
|
202
|
-
suggestions.push("Available templates:");
|
|
203
|
-
this.debugInfo.availableTemplates.forEach((template) => {
|
|
204
|
-
suggestions.push(` • ${template}`);
|
|
205
|
-
});
|
|
206
|
-
// Suggest similar template names
|
|
207
|
-
const similar = this.findSimilarTemplates(this.templateName, this.debugInfo.availableTemplates);
|
|
208
|
-
if (similar.length > 0) {
|
|
209
|
-
suggestions.push("Did you mean:");
|
|
210
|
-
similar.forEach((template) => {
|
|
211
|
-
suggestions.push(` • ${template}`);
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
// Missing variables suggestions
|
|
216
|
-
if (this.debugInfo?.missingVariables?.length) {
|
|
217
|
-
suggestions.push("Missing template variables:");
|
|
218
|
-
this.debugInfo.missingVariables.forEach((variable) => {
|
|
219
|
-
suggestions.push(` • ${variable}`);
|
|
220
|
-
});
|
|
221
|
-
suggestions.push("Add these variables to the template context");
|
|
222
|
-
}
|
|
223
|
-
// Template syntax suggestions
|
|
224
|
-
if (this.debugInfo?.lineNumber) {
|
|
225
|
-
suggestions.push(`Check template syntax around line ${this.debugInfo.lineNumber}`);
|
|
226
|
-
}
|
|
227
|
-
suggestions.push("Enable template debugging: { debug: true }");
|
|
228
|
-
suggestions.push("Verify template file exists and has correct syntax");
|
|
229
|
-
return suggestions;
|
|
230
|
-
}
|
|
231
|
-
findSimilarTemplates(target, available) {
|
|
232
|
-
return available
|
|
233
|
-
.filter((template) => {
|
|
234
|
-
const distance = this.levenshteinDistance(target.toLowerCase(), template.toLowerCase());
|
|
235
|
-
return distance <= 2 && distance > 0;
|
|
236
|
-
})
|
|
237
|
-
.slice(0, 3);
|
|
238
|
-
}
|
|
239
|
-
levenshteinDistance(str1, str2) {
|
|
240
|
-
const matrix = [];
|
|
241
|
-
for (let i = 0; i <= str2.length; i++) {
|
|
242
|
-
matrix[i] = [i];
|
|
243
|
-
}
|
|
244
|
-
for (let j = 0; j <= str1.length; j++) {
|
|
245
|
-
matrix[0][j] = j;
|
|
246
|
-
}
|
|
247
|
-
for (let i = 1; i <= str2.length; i++) {
|
|
248
|
-
for (let j = 1; j <= str1.length; j++) {
|
|
249
|
-
if (str2.charAt(i - 1) === str1.charAt(j - 1)) {
|
|
250
|
-
matrix[i][j] = matrix[i - 1]?.[j - 1];
|
|
251
|
-
}
|
|
252
|
-
else {
|
|
253
|
-
matrix[i][j] = Math.min(matrix[i - 1]?.[j - 1] + 1, matrix[i]?.[j - 1] + 1, matrix[i - 1]?.[j] + 1);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
return matrix[str2.length]?.[str1.length];
|
|
258
|
-
}
|
|
259
|
-
}
|