@skmtc/core 0.0.788 → 0.0.790
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/esm/context/ParseContext.d.ts +178 -0
- package/esm/context/ParseContext.d.ts.map +1 -1
- package/esm/context/ParseContext.js +108 -0
- package/esm/context/RenderContext.d.ts +190 -0
- package/esm/context/RenderContext.d.ts.map +1 -1
- package/esm/context/RenderContext.js +179 -0
- package/esm/dsl/Inserted.d.ts +240 -0
- package/esm/dsl/Inserted.d.ts.map +1 -1
- package/esm/dsl/Inserted.js +231 -0
- package/esm/helpers/refFns.d.ts +160 -0
- package/esm/helpers/refFns.d.ts.map +1 -1
- package/esm/helpers/refFns.js +156 -0
- package/esm/oas/boolean/Boolean.d.ts +142 -1
- package/esm/oas/boolean/Boolean.d.ts.map +1 -1
- package/esm/oas/boolean/Boolean.js +130 -1
- package/esm/oas/components/Components.d.ts +252 -2
- package/esm/oas/components/Components.d.ts.map +1 -1
- package/esm/oas/components/Components.js +241 -2
- package/esm/oas/parameter/Parameter.d.ts +160 -0
- package/esm/oas/parameter/Parameter.d.ts.map +1 -1
- package/esm/oas/parameter/Parameter.js +144 -0
- package/esm/oas/union/Union.d.ts +119 -5
- package/esm/oas/union/Union.d.ts.map +1 -1
- package/esm/oas/union/Union.js +108 -5
- package/package.json +1 -1
- package/script/context/ParseContext.d.ts +178 -0
- package/script/context/ParseContext.d.ts.map +1 -1
- package/script/context/ParseContext.js +108 -0
- package/script/context/RenderContext.d.ts +190 -0
- package/script/context/RenderContext.d.ts.map +1 -1
- package/script/context/RenderContext.js +179 -0
- package/script/dsl/Inserted.d.ts +240 -0
- package/script/dsl/Inserted.d.ts.map +1 -1
- package/script/dsl/Inserted.js +231 -0
- package/script/helpers/refFns.d.ts +160 -0
- package/script/helpers/refFns.d.ts.map +1 -1
- package/script/helpers/refFns.js +156 -0
- package/script/oas/boolean/Boolean.d.ts +142 -1
- package/script/oas/boolean/Boolean.d.ts.map +1 -1
- package/script/oas/boolean/Boolean.js +130 -1
- package/script/oas/components/Components.d.ts +252 -2
- package/script/oas/components/Components.d.ts.map +1 -1
- package/script/oas/components/Components.js +241 -2
- package/script/oas/parameter/Parameter.d.ts +160 -0
- package/script/oas/parameter/Parameter.d.ts.map +1 -1
- package/script/oas/parameter/Parameter.js +144 -0
- package/script/oas/union/Union.d.ts +119 -5
- package/script/oas/union/Union.d.ts.map +1 -1
- package/script/oas/union/Union.js +108 -5
|
@@ -8,16 +8,206 @@ import type * as log from '../deps/jsr.io/@std/log/0.224.14/mod.js';
|
|
|
8
8
|
import { File } from '../dsl/File.js';
|
|
9
9
|
import type { Preview, Mapping } from '../types/Preview.js';
|
|
10
10
|
import type { JsonFile } from '../dsl/JsonFile.js';
|
|
11
|
+
/**
|
|
12
|
+
* Constructor arguments for {@link RenderContext}.
|
|
13
|
+
*/
|
|
11
14
|
type ConstructorArgs = {
|
|
15
|
+
/** Map of generated files to render */
|
|
12
16
|
files: Map<string, File | JsonFile>;
|
|
17
|
+
/** Preview data for generated content */
|
|
13
18
|
previews: Record<string, Record<string, Preview>>;
|
|
19
|
+
/** Mapping data for file relationships */
|
|
14
20
|
mappings: Record<string, Record<string, Mapping>>;
|
|
21
|
+
/** Optional Prettier configuration for code formatting */
|
|
15
22
|
prettierConfig?: PrettierConfigType;
|
|
23
|
+
/** Base path for resolving file paths */
|
|
16
24
|
basePath: string | undefined;
|
|
25
|
+
/** Stack trail for distributed tracing */
|
|
17
26
|
stackTrail: StackTrail;
|
|
27
|
+
/** Logger instance for debug information */
|
|
18
28
|
logger: log.Logger;
|
|
29
|
+
/** Function to capture result status */
|
|
19
30
|
captureCurrentResult: (result: ResultType) => void;
|
|
20
31
|
};
|
|
32
|
+
/**
|
|
33
|
+
* The rendering context for the final phase of the SKMTC transformation pipeline.
|
|
34
|
+
*
|
|
35
|
+
* `RenderContext` is responsible for taking the generated artifacts from the generation
|
|
36
|
+
* phase and rendering them into their final form with proper formatting, path resolution,
|
|
37
|
+
* and file preparation. It handles code formatting via Prettier, path normalization,
|
|
38
|
+
* and produces the final artifacts ready for writing to the filesystem.
|
|
39
|
+
*
|
|
40
|
+
* This context represents the culmination of the three-phase SKMTC pipeline, transforming
|
|
41
|
+
* generator outputs into production-ready code files with proper formatting and structure.
|
|
42
|
+
*
|
|
43
|
+
* ## Key Features
|
|
44
|
+
*
|
|
45
|
+
* - **Code Formatting**: Automatic Prettier formatting for generated TypeScript/JavaScript code
|
|
46
|
+
* - **Path Resolution**: Intelligent path resolution with base path support
|
|
47
|
+
* - **Content Collation**: Combines all generated content into organized file structures
|
|
48
|
+
* - **Metadata Generation**: Tracks file statistics (lines, characters) and relationships
|
|
49
|
+
* - **Error Tracking**: Comprehensive error handling with Sentry integration
|
|
50
|
+
* - **Performance Monitoring**: Built-in tracing and performance measurement
|
|
51
|
+
*
|
|
52
|
+
* @example Basic rendering usage
|
|
53
|
+
* ```typescript
|
|
54
|
+
* import { RenderContext } from '@skmtc/core';
|
|
55
|
+
*
|
|
56
|
+
* const renderContext = new RenderContext({
|
|
57
|
+
* files: generatedFiles,
|
|
58
|
+
* previews: previewData,
|
|
59
|
+
* mappings: mappingData,
|
|
60
|
+
* prettierConfig: {
|
|
61
|
+
* semi: false,
|
|
62
|
+
* singleQuote: true,
|
|
63
|
+
* trailingComma: 'all'
|
|
64
|
+
* },
|
|
65
|
+
* basePath: './src/generated',
|
|
66
|
+
* stackTrail: traceStack,
|
|
67
|
+
* logger: myLogger,
|
|
68
|
+
* captureCurrentResult: (result) => console.log(result)
|
|
69
|
+
* });
|
|
70
|
+
*
|
|
71
|
+
* const rendered = await renderContext.render();
|
|
72
|
+
*
|
|
73
|
+
* // Access rendered files
|
|
74
|
+
* Object.entries(rendered.artifacts).forEach(([path, content]) => {
|
|
75
|
+
* console.log(`Rendered ${path}: ${rendered.files[path].lines} lines`);
|
|
76
|
+
* // Write to filesystem
|
|
77
|
+
* await Deno.writeTextFile(path, content);
|
|
78
|
+
* });
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @example With custom Prettier configuration
|
|
82
|
+
* ```typescript
|
|
83
|
+
* const renderContext = new RenderContext({
|
|
84
|
+
* files: generatedFiles,
|
|
85
|
+
* previews: {},
|
|
86
|
+
* mappings: {},
|
|
87
|
+
* prettierConfig: {
|
|
88
|
+
* parser: 'typescript',
|
|
89
|
+
* printWidth: 120,
|
|
90
|
+
* tabWidth: 2,
|
|
91
|
+
* semi: true,
|
|
92
|
+
* singleQuote: true,
|
|
93
|
+
* trailingComma: 'es5',
|
|
94
|
+
* bracketSpacing: true,
|
|
95
|
+
* arrowParens: 'avoid'
|
|
96
|
+
* },
|
|
97
|
+
* basePath: './packages/api-client/src',
|
|
98
|
+
* stackTrail: stack,
|
|
99
|
+
* logger: logger,
|
|
100
|
+
* captureCurrentResult: resultHandler
|
|
101
|
+
* });
|
|
102
|
+
*
|
|
103
|
+
* const result = await renderContext.render();
|
|
104
|
+
*
|
|
105
|
+
* // All TypeScript files are automatically formatted
|
|
106
|
+
* console.log('Formatted files:', Object.keys(result.artifacts).length);
|
|
107
|
+
* ```
|
|
108
|
+
*
|
|
109
|
+
* @example Processing render results
|
|
110
|
+
* ```typescript
|
|
111
|
+
* const rendered = await renderContext.render();
|
|
112
|
+
*
|
|
113
|
+
* // Analyze file statistics
|
|
114
|
+
* const totalLines = Object.values(rendered.files)
|
|
115
|
+
* .reduce((sum, file) => sum + file.lines, 0);
|
|
116
|
+
* const totalChars = Object.values(rendered.files)
|
|
117
|
+
* .reduce((sum, file) => sum + file.characters, 0);
|
|
118
|
+
*
|
|
119
|
+
* console.log(`Generated ${Object.keys(rendered.artifacts).length} files`);
|
|
120
|
+
* console.log(`Total lines: ${totalLines}`);
|
|
121
|
+
* console.log(`Total characters: ${totalChars}`);
|
|
122
|
+
*
|
|
123
|
+
* // Check for large files
|
|
124
|
+
* const largeFiles = Object.entries(rendered.files)
|
|
125
|
+
* .filter(([_, metadata]) => metadata.lines > 1000)
|
|
126
|
+
* .map(([path, metadata]) => ({ path, lines: metadata.lines }));
|
|
127
|
+
*
|
|
128
|
+
* if (largeFiles.length > 0) {
|
|
129
|
+
* console.log('Large files detected:', largeFiles);
|
|
130
|
+
* }
|
|
131
|
+
*
|
|
132
|
+
* // Access preview and mapping data
|
|
133
|
+
* console.log('Previews available:', Object.keys(rendered.previews));
|
|
134
|
+
* console.log('Mappings available:', Object.keys(rendered.mappings));
|
|
135
|
+
* ```
|
|
136
|
+
*
|
|
137
|
+
* @example Integration with CoreContext
|
|
138
|
+
* ```typescript
|
|
139
|
+
* // Typically used within CoreContext.toArtifacts()
|
|
140
|
+
* class CustomCoreContext extends CoreContext {
|
|
141
|
+
* async renderWithPostProcessing(
|
|
142
|
+
* files: Map<string, File | JsonFile>,
|
|
143
|
+
* previews: Record<string, Record<string, Preview>>,
|
|
144
|
+
* mappings: Record<string, Record<string, Mapping>>
|
|
145
|
+
* ) {
|
|
146
|
+
* const renderContext = new RenderContext({
|
|
147
|
+
* files,
|
|
148
|
+
* previews,
|
|
149
|
+
* mappings,
|
|
150
|
+
* prettierConfig: this.prettierConfig,
|
|
151
|
+
* basePath: this.settings?.basePath,
|
|
152
|
+
* stackTrail: this.stackTrail,
|
|
153
|
+
* logger: this.logger,
|
|
154
|
+
* captureCurrentResult: this.captureCurrentResult.bind(this)
|
|
155
|
+
* });
|
|
156
|
+
*
|
|
157
|
+
* const rendered = await renderContext.render();
|
|
158
|
+
*
|
|
159
|
+
* // Post-process rendered files
|
|
160
|
+
* const processedArtifacts: Record<string, string> = {};
|
|
161
|
+
*
|
|
162
|
+
* for (const [path, content] of Object.entries(rendered.artifacts)) {
|
|
163
|
+
* // Add file headers, license notices, etc.
|
|
164
|
+
* const processedContent = this.addFileHeader(content, path);
|
|
165
|
+
* processedArtifacts[path] = processedContent;
|
|
166
|
+
* }
|
|
167
|
+
*
|
|
168
|
+
* return {
|
|
169
|
+
* ...rendered,
|
|
170
|
+
* artifacts: processedArtifacts
|
|
171
|
+
* };
|
|
172
|
+
* }
|
|
173
|
+
* }
|
|
174
|
+
* ```
|
|
175
|
+
*
|
|
176
|
+
* @example Error handling during rendering
|
|
177
|
+
* ```typescript
|
|
178
|
+
* try {
|
|
179
|
+
* const renderContext = new RenderContext({
|
|
180
|
+
* files: generatedFiles,
|
|
181
|
+
* previews: {},
|
|
182
|
+
* mappings: {},
|
|
183
|
+
* prettierConfig: prettierConfig,
|
|
184
|
+
* basePath: './invalid-path', // This might cause issues
|
|
185
|
+
* stackTrail: stack,
|
|
186
|
+
* logger: logger,
|
|
187
|
+
* captureCurrentResult: (result) => {
|
|
188
|
+
* if (result === 'error') {
|
|
189
|
+
* console.error('Render error detected');
|
|
190
|
+
* }
|
|
191
|
+
* }
|
|
192
|
+
* });
|
|
193
|
+
*
|
|
194
|
+
* const result = await renderContext.render();
|
|
195
|
+
*
|
|
196
|
+
* // Check if any files failed to render
|
|
197
|
+
* const failedFiles = Object.entries(result.files)
|
|
198
|
+
* .filter(([path, metadata]) => metadata.lines === 0)
|
|
199
|
+
* .map(([path]) => path);
|
|
200
|
+
*
|
|
201
|
+
* if (failedFiles.length > 0) {
|
|
202
|
+
* console.warn('Files with no content:', failedFiles);
|
|
203
|
+
* }
|
|
204
|
+
*
|
|
205
|
+
* } catch (error) {
|
|
206
|
+
* console.error('Render operation failed:', error);
|
|
207
|
+
* // Sentry automatically captures the error
|
|
208
|
+
* }
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
21
211
|
export declare class RenderContext {
|
|
22
212
|
#private;
|
|
23
213
|
files: Map<string, File | JsonFile>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RenderContext.d.ts","sourceRoot":"","sources":["../../src/context/RenderContext.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAEpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAGrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,KAAK,KAAK,GAAG,MAAM,yCAAyC,CAAA;AACnE,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;AACrC,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAE3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAElD,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,GAAG,QAAQ,CAAC,CAAA;IACnC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IACjD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IACjD,cAAc,CAAC,EAAE,kBAAkB,CAAA;IACnC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5B,UAAU,EAAE,UAAU,CAAA;IACtB,MAAM,EAAE,GAAG,CAAC,MAAM,CAAA;IAClB,oBAAoB,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAA;CACnD,CAAA;
|
|
1
|
+
{"version":3,"file":"RenderContext.d.ts","sourceRoot":"","sources":["../../src/context/RenderContext.ts"],"names":[],"mappings":"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"}
|
|
@@ -56,6 +56,185 @@ const toResolvedArtifactPath_js_1 = require("../helpers/toResolvedArtifactPath.j
|
|
|
56
56
|
const tracer_js_1 = require("../helpers/tracer.js");
|
|
57
57
|
const File_js_1 = require("../dsl/File.js");
|
|
58
58
|
const prettier = __importStar(require("prettier"));
|
|
59
|
+
/**
|
|
60
|
+
* The rendering context for the final phase of the SKMTC transformation pipeline.
|
|
61
|
+
*
|
|
62
|
+
* `RenderContext` is responsible for taking the generated artifacts from the generation
|
|
63
|
+
* phase and rendering them into their final form with proper formatting, path resolution,
|
|
64
|
+
* and file preparation. It handles code formatting via Prettier, path normalization,
|
|
65
|
+
* and produces the final artifacts ready for writing to the filesystem.
|
|
66
|
+
*
|
|
67
|
+
* This context represents the culmination of the three-phase SKMTC pipeline, transforming
|
|
68
|
+
* generator outputs into production-ready code files with proper formatting and structure.
|
|
69
|
+
*
|
|
70
|
+
* ## Key Features
|
|
71
|
+
*
|
|
72
|
+
* - **Code Formatting**: Automatic Prettier formatting for generated TypeScript/JavaScript code
|
|
73
|
+
* - **Path Resolution**: Intelligent path resolution with base path support
|
|
74
|
+
* - **Content Collation**: Combines all generated content into organized file structures
|
|
75
|
+
* - **Metadata Generation**: Tracks file statistics (lines, characters) and relationships
|
|
76
|
+
* - **Error Tracking**: Comprehensive error handling with Sentry integration
|
|
77
|
+
* - **Performance Monitoring**: Built-in tracing and performance measurement
|
|
78
|
+
*
|
|
79
|
+
* @example Basic rendering usage
|
|
80
|
+
* ```typescript
|
|
81
|
+
* import { RenderContext } from '@skmtc/core';
|
|
82
|
+
*
|
|
83
|
+
* const renderContext = new RenderContext({
|
|
84
|
+
* files: generatedFiles,
|
|
85
|
+
* previews: previewData,
|
|
86
|
+
* mappings: mappingData,
|
|
87
|
+
* prettierConfig: {
|
|
88
|
+
* semi: false,
|
|
89
|
+
* singleQuote: true,
|
|
90
|
+
* trailingComma: 'all'
|
|
91
|
+
* },
|
|
92
|
+
* basePath: './src/generated',
|
|
93
|
+
* stackTrail: traceStack,
|
|
94
|
+
* logger: myLogger,
|
|
95
|
+
* captureCurrentResult: (result) => console.log(result)
|
|
96
|
+
* });
|
|
97
|
+
*
|
|
98
|
+
* const rendered = await renderContext.render();
|
|
99
|
+
*
|
|
100
|
+
* // Access rendered files
|
|
101
|
+
* Object.entries(rendered.artifacts).forEach(([path, content]) => {
|
|
102
|
+
* console.log(`Rendered ${path}: ${rendered.files[path].lines} lines`);
|
|
103
|
+
* // Write to filesystem
|
|
104
|
+
* await Deno.writeTextFile(path, content);
|
|
105
|
+
* });
|
|
106
|
+
* ```
|
|
107
|
+
*
|
|
108
|
+
* @example With custom Prettier configuration
|
|
109
|
+
* ```typescript
|
|
110
|
+
* const renderContext = new RenderContext({
|
|
111
|
+
* files: generatedFiles,
|
|
112
|
+
* previews: {},
|
|
113
|
+
* mappings: {},
|
|
114
|
+
* prettierConfig: {
|
|
115
|
+
* parser: 'typescript',
|
|
116
|
+
* printWidth: 120,
|
|
117
|
+
* tabWidth: 2,
|
|
118
|
+
* semi: true,
|
|
119
|
+
* singleQuote: true,
|
|
120
|
+
* trailingComma: 'es5',
|
|
121
|
+
* bracketSpacing: true,
|
|
122
|
+
* arrowParens: 'avoid'
|
|
123
|
+
* },
|
|
124
|
+
* basePath: './packages/api-client/src',
|
|
125
|
+
* stackTrail: stack,
|
|
126
|
+
* logger: logger,
|
|
127
|
+
* captureCurrentResult: resultHandler
|
|
128
|
+
* });
|
|
129
|
+
*
|
|
130
|
+
* const result = await renderContext.render();
|
|
131
|
+
*
|
|
132
|
+
* // All TypeScript files are automatically formatted
|
|
133
|
+
* console.log('Formatted files:', Object.keys(result.artifacts).length);
|
|
134
|
+
* ```
|
|
135
|
+
*
|
|
136
|
+
* @example Processing render results
|
|
137
|
+
* ```typescript
|
|
138
|
+
* const rendered = await renderContext.render();
|
|
139
|
+
*
|
|
140
|
+
* // Analyze file statistics
|
|
141
|
+
* const totalLines = Object.values(rendered.files)
|
|
142
|
+
* .reduce((sum, file) => sum + file.lines, 0);
|
|
143
|
+
* const totalChars = Object.values(rendered.files)
|
|
144
|
+
* .reduce((sum, file) => sum + file.characters, 0);
|
|
145
|
+
*
|
|
146
|
+
* console.log(`Generated ${Object.keys(rendered.artifacts).length} files`);
|
|
147
|
+
* console.log(`Total lines: ${totalLines}`);
|
|
148
|
+
* console.log(`Total characters: ${totalChars}`);
|
|
149
|
+
*
|
|
150
|
+
* // Check for large files
|
|
151
|
+
* const largeFiles = Object.entries(rendered.files)
|
|
152
|
+
* .filter(([_, metadata]) => metadata.lines > 1000)
|
|
153
|
+
* .map(([path, metadata]) => ({ path, lines: metadata.lines }));
|
|
154
|
+
*
|
|
155
|
+
* if (largeFiles.length > 0) {
|
|
156
|
+
* console.log('Large files detected:', largeFiles);
|
|
157
|
+
* }
|
|
158
|
+
*
|
|
159
|
+
* // Access preview and mapping data
|
|
160
|
+
* console.log('Previews available:', Object.keys(rendered.previews));
|
|
161
|
+
* console.log('Mappings available:', Object.keys(rendered.mappings));
|
|
162
|
+
* ```
|
|
163
|
+
*
|
|
164
|
+
* @example Integration with CoreContext
|
|
165
|
+
* ```typescript
|
|
166
|
+
* // Typically used within CoreContext.toArtifacts()
|
|
167
|
+
* class CustomCoreContext extends CoreContext {
|
|
168
|
+
* async renderWithPostProcessing(
|
|
169
|
+
* files: Map<string, File | JsonFile>,
|
|
170
|
+
* previews: Record<string, Record<string, Preview>>,
|
|
171
|
+
* mappings: Record<string, Record<string, Mapping>>
|
|
172
|
+
* ) {
|
|
173
|
+
* const renderContext = new RenderContext({
|
|
174
|
+
* files,
|
|
175
|
+
* previews,
|
|
176
|
+
* mappings,
|
|
177
|
+
* prettierConfig: this.prettierConfig,
|
|
178
|
+
* basePath: this.settings?.basePath,
|
|
179
|
+
* stackTrail: this.stackTrail,
|
|
180
|
+
* logger: this.logger,
|
|
181
|
+
* captureCurrentResult: this.captureCurrentResult.bind(this)
|
|
182
|
+
* });
|
|
183
|
+
*
|
|
184
|
+
* const rendered = await renderContext.render();
|
|
185
|
+
*
|
|
186
|
+
* // Post-process rendered files
|
|
187
|
+
* const processedArtifacts: Record<string, string> = {};
|
|
188
|
+
*
|
|
189
|
+
* for (const [path, content] of Object.entries(rendered.artifacts)) {
|
|
190
|
+
* // Add file headers, license notices, etc.
|
|
191
|
+
* const processedContent = this.addFileHeader(content, path);
|
|
192
|
+
* processedArtifacts[path] = processedContent;
|
|
193
|
+
* }
|
|
194
|
+
*
|
|
195
|
+
* return {
|
|
196
|
+
* ...rendered,
|
|
197
|
+
* artifacts: processedArtifacts
|
|
198
|
+
* };
|
|
199
|
+
* }
|
|
200
|
+
* }
|
|
201
|
+
* ```
|
|
202
|
+
*
|
|
203
|
+
* @example Error handling during rendering
|
|
204
|
+
* ```typescript
|
|
205
|
+
* try {
|
|
206
|
+
* const renderContext = new RenderContext({
|
|
207
|
+
* files: generatedFiles,
|
|
208
|
+
* previews: {},
|
|
209
|
+
* mappings: {},
|
|
210
|
+
* prettierConfig: prettierConfig,
|
|
211
|
+
* basePath: './invalid-path', // This might cause issues
|
|
212
|
+
* stackTrail: stack,
|
|
213
|
+
* logger: logger,
|
|
214
|
+
* captureCurrentResult: (result) => {
|
|
215
|
+
* if (result === 'error') {
|
|
216
|
+
* console.error('Render error detected');
|
|
217
|
+
* }
|
|
218
|
+
* }
|
|
219
|
+
* });
|
|
220
|
+
*
|
|
221
|
+
* const result = await renderContext.render();
|
|
222
|
+
*
|
|
223
|
+
* // Check if any files failed to render
|
|
224
|
+
* const failedFiles = Object.entries(result.files)
|
|
225
|
+
* .filter(([path, metadata]) => metadata.lines === 0)
|
|
226
|
+
* .map(([path]) => path);
|
|
227
|
+
*
|
|
228
|
+
* if (failedFiles.length > 0) {
|
|
229
|
+
* console.warn('Files with no content:', failedFiles);
|
|
230
|
+
* }
|
|
231
|
+
*
|
|
232
|
+
* } catch (error) {
|
|
233
|
+
* console.error('Render operation failed:', error);
|
|
234
|
+
* // Sentry automatically captures the error
|
|
235
|
+
* }
|
|
236
|
+
* ```
|
|
237
|
+
*/
|
|
59
238
|
class RenderContext {
|
|
60
239
|
constructor({ files, previews, mappings, prettierConfig, basePath, logger, stackTrail, captureCurrentResult }) {
|
|
61
240
|
Object.defineProperty(this, "files", {
|
package/script/dsl/Inserted.d.ts
CHANGED
|
@@ -1,17 +1,257 @@
|
|
|
1
1
|
import type { GeneratedDefinition, GeneratedValue, GenerationType } from '../types/GeneratedValue.js';
|
|
2
2
|
import type { ContentSettings } from './ContentSettings.js';
|
|
3
3
|
import type { Identifier } from './Identifier.js';
|
|
4
|
+
/**
|
|
5
|
+
* Constructor arguments for {@link Inserted}.
|
|
6
|
+
*
|
|
7
|
+
* @template V - The type of generated value
|
|
8
|
+
* @template T - The generation type ('force' or 'lazy')
|
|
9
|
+
* @template EnrichmentType - Optional enrichment data type
|
|
10
|
+
*/
|
|
4
11
|
type ConstructorArgs<V extends GeneratedValue, T extends GenerationType, EnrichmentType> = {
|
|
12
|
+
/** Content settings including identifier and export path */
|
|
5
13
|
settings: ContentSettings<EnrichmentType>;
|
|
14
|
+
/** The generated definition with its value */
|
|
6
15
|
definition: GeneratedDefinition<V, T>;
|
|
7
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* Represents a successfully inserted generator artifact in the SKMTC DSL system.
|
|
19
|
+
*
|
|
20
|
+
* The `Inserted` class is returned when generators are inserted into the generation
|
|
21
|
+
* context, providing access to the generated content, metadata, and configuration.
|
|
22
|
+
* It acts as a bridge between the insertion process and the consuming code that
|
|
23
|
+
* needs to reference or use the generated artifacts.
|
|
24
|
+
*
|
|
25
|
+
* This class provides type-safe access to generated values with proper handling
|
|
26
|
+
* of both forced and lazy generation modes, ensuring the correct optionality
|
|
27
|
+
* of the generated content based on the generation strategy used.
|
|
28
|
+
*
|
|
29
|
+
* ## Key Features
|
|
30
|
+
*
|
|
31
|
+
* - **Type Safety**: Generic parameters preserve exact types from generators
|
|
32
|
+
* - **Generation Modes**: Handles both 'force' and 'lazy' generation strategies
|
|
33
|
+
* - **Metadata Access**: Provides access to identifiers, export paths, and settings
|
|
34
|
+
* - **Value Extraction**: Type-safe value extraction with proper optionality
|
|
35
|
+
* - **Enrichment Support**: Full support for custom enrichment data types
|
|
36
|
+
*
|
|
37
|
+
* @template V - The type of generated value (preserves generator output type)
|
|
38
|
+
* @template T - The generation type ('force' ensures non-null, 'lazy' allows undefined)
|
|
39
|
+
* @template EnrichmentType - Optional type for custom enrichment data
|
|
40
|
+
*
|
|
41
|
+
* @example Basic usage with forced generation
|
|
42
|
+
* ```typescript
|
|
43
|
+
* import { Inserted } from '@skmtc/core';
|
|
44
|
+
*
|
|
45
|
+
* class MyGenerator extends ModelBase {
|
|
46
|
+
* generate(): Definition {
|
|
47
|
+
* // Insert a related model with forced generation
|
|
48
|
+
* const userModel = this.insertModel(
|
|
49
|
+
* new UserModelGenerator({ ... }),
|
|
50
|
+
* 'User'
|
|
51
|
+
* ); // Returns Inserted<UserModelValue, 'force', EnrichmentType>
|
|
52
|
+
*
|
|
53
|
+
* // Access the generated value (guaranteed to be present)
|
|
54
|
+
* const userTypeName = userModel.toValue(); // UserModelValue (not undefined)
|
|
55
|
+
* const exportPath = userModel.toExportPath(); // './src/models.ts'
|
|
56
|
+
* const identifier = userModel.toName(); // 'User'
|
|
57
|
+
*
|
|
58
|
+
* return new Definition({
|
|
59
|
+
* identifier: Identifier.createType(this.refName),
|
|
60
|
+
* value: {
|
|
61
|
+
* generatorKey: this.generatorKey,
|
|
62
|
+
* content: `export interface Order { user: ${userTypeName}; }`
|
|
63
|
+
* }
|
|
64
|
+
* });
|
|
65
|
+
* }
|
|
66
|
+
* }
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* @example Working with lazy generation
|
|
70
|
+
* ```typescript
|
|
71
|
+
* class ConditionalGenerator extends ModelBase {
|
|
72
|
+
* generate(): Definition {
|
|
73
|
+
* // Insert with lazy generation (may not generate if already exists)
|
|
74
|
+
* const optionalModel = this.insertModel(
|
|
75
|
+
* new OptionalModelGenerator({ ... }),
|
|
76
|
+
* 'OptionalModel',
|
|
77
|
+
* { generation: 'lazy' }
|
|
78
|
+
* ); // Returns Inserted<OptionalValue, 'lazy', EnrichmentType>
|
|
79
|
+
*
|
|
80
|
+
* // Value might be undefined with lazy generation
|
|
81
|
+
* const value = optionalModel.toValue(); // OptionalValue | undefined
|
|
82
|
+
*
|
|
83
|
+
* if (value) {
|
|
84
|
+
* // Use the generated value
|
|
85
|
+
* return this.createDefinitionWith(value);
|
|
86
|
+
* } else {
|
|
87
|
+
* // Handle case where generation was skipped
|
|
88
|
+
* return this.createFallbackDefinition();
|
|
89
|
+
* }
|
|
90
|
+
* }
|
|
91
|
+
* }
|
|
92
|
+
* ```
|
|
93
|
+
*
|
|
94
|
+
* @example Accessing insertion metadata
|
|
95
|
+
* ```typescript
|
|
96
|
+
* class MetadataAwareGenerator extends OperationBase {
|
|
97
|
+
* generate(): Definition {
|
|
98
|
+
* const requestModel = this.insertModel(
|
|
99
|
+
* new RequestModelGenerator({ ... }),
|
|
100
|
+
* 'CreateUserRequest'
|
|
101
|
+
* );
|
|
102
|
+
*
|
|
103
|
+
* // Access various metadata
|
|
104
|
+
* const modelName = requestModel.toName(); // 'CreateUserRequest'
|
|
105
|
+
* const identifier = requestModel.toIdentifier(); // Full Identifier object
|
|
106
|
+
* const exportPath = requestModel.toExportPath(); // './src/api/types.ts'
|
|
107
|
+
* const enrichments = requestModel.settings.enrichments; // Custom data
|
|
108
|
+
*
|
|
109
|
+
* console.log(`Generated ${modelName} in ${exportPath}`);
|
|
110
|
+
*
|
|
111
|
+
* return new Definition({
|
|
112
|
+
* identifier: Identifier.createVariable(this.operation.operationId!),
|
|
113
|
+
* value: {
|
|
114
|
+
* generatorKey: this.generatorKey,
|
|
115
|
+
* content: `async function createUser(data: ${modelName}) { ... }`
|
|
116
|
+
* }
|
|
117
|
+
* });
|
|
118
|
+
* }
|
|
119
|
+
* }
|
|
120
|
+
* ```
|
|
121
|
+
*
|
|
122
|
+
* @example With enrichment data
|
|
123
|
+
* ```typescript
|
|
124
|
+
* type ValidationEnrichment = {
|
|
125
|
+
* validators: string[];
|
|
126
|
+
* required: boolean;
|
|
127
|
+
* };
|
|
128
|
+
*
|
|
129
|
+
* class EnrichedGenerator extends ModelBase<ValidationEnrichment> {
|
|
130
|
+
* generate(): Definition {
|
|
131
|
+
* const validatedModel = this.insertModel(
|
|
132
|
+
* new ValidatedModelGenerator({ ... }),
|
|
133
|
+
* 'ValidatedUser'
|
|
134
|
+
* ); // Returns Inserted<ModelValue, 'force', ValidationEnrichment>
|
|
135
|
+
*
|
|
136
|
+
* // Access enrichment data
|
|
137
|
+
* const enrichment = validatedModel.settings.enrichments;
|
|
138
|
+
* const validators = enrichment?.validators ?? [];
|
|
139
|
+
* const isRequired = enrichment?.required ?? false;
|
|
140
|
+
*
|
|
141
|
+
* return new Definition({
|
|
142
|
+
* identifier: Identifier.createType(this.refName),
|
|
143
|
+
* value: {
|
|
144
|
+
* generatorKey: this.generatorKey,
|
|
145
|
+
* content: this.generateWithValidation(validatedModel.toValue(), validators)
|
|
146
|
+
* }
|
|
147
|
+
* });
|
|
148
|
+
* }
|
|
149
|
+
* }
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
8
152
|
export declare class Inserted<V extends GeneratedValue, T extends GenerationType, EnrichmentType> {
|
|
153
|
+
/** Content settings including identifier and export path */
|
|
9
154
|
settings: ContentSettings<EnrichmentType>;
|
|
155
|
+
/** The generated definition with its value */
|
|
10
156
|
definition: GeneratedDefinition<V, T>;
|
|
157
|
+
/**
|
|
158
|
+
* Creates a new Inserted instance.
|
|
159
|
+
*
|
|
160
|
+
* @param args - Insertion configuration
|
|
161
|
+
* @param args.settings - Content settings with identifier and export path
|
|
162
|
+
* @param args.definition - The generated definition containing the value
|
|
163
|
+
*/
|
|
11
164
|
constructor({ settings, definition }: ConstructorArgs<V, T, EnrichmentType>);
|
|
165
|
+
/**
|
|
166
|
+
* Gets the name of the inserted artifact.
|
|
167
|
+
*
|
|
168
|
+
* This method returns the string name from the identifier, which is commonly
|
|
169
|
+
* used when referencing the generated artifact in code or templates.
|
|
170
|
+
*
|
|
171
|
+
* @returns The name of the inserted artifact
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```typescript
|
|
175
|
+
* const userModel = this.insertModel(generator, 'User');
|
|
176
|
+
* const name = userModel.toName(); // 'User'
|
|
177
|
+
*
|
|
178
|
+
* // Use in generated code
|
|
179
|
+
* const code = `interface Order { user: ${name}; }`;
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
12
182
|
toName(): string;
|
|
183
|
+
/**
|
|
184
|
+
* Gets the full identifier of the inserted artifact.
|
|
185
|
+
*
|
|
186
|
+
* This method returns the complete Identifier object, which includes both
|
|
187
|
+
* the name and type information. Useful when you need access to entity type
|
|
188
|
+
* or type annotations.
|
|
189
|
+
*
|
|
190
|
+
* @returns The complete Identifier object
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* ```typescript
|
|
194
|
+
* const model = this.insertModel(generator, 'User');
|
|
195
|
+
* const identifier = model.toIdentifier();
|
|
196
|
+
*
|
|
197
|
+
* console.log(identifier.name); // 'User'
|
|
198
|
+
* console.log(identifier.entityType); // EntityType instance
|
|
199
|
+
* console.log(identifier.typeName); // Optional type annotation
|
|
200
|
+
* ```
|
|
201
|
+
*/
|
|
13
202
|
toIdentifier(): Identifier;
|
|
203
|
+
/**
|
|
204
|
+
* Gets the export path where the artifact was generated.
|
|
205
|
+
*
|
|
206
|
+
* This method returns the file path where the generated artifact is located,
|
|
207
|
+
* which is useful for creating import statements or understanding the file
|
|
208
|
+
* structure of generated code.
|
|
209
|
+
*
|
|
210
|
+
* @returns The export path of the generated artifact
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```typescript
|
|
214
|
+
* const userModel = this.insertModel(generator, 'User');
|
|
215
|
+
* const exportPath = userModel.toExportPath(); // './src/models/User.ts'
|
|
216
|
+
*
|
|
217
|
+
* // Create import statement
|
|
218
|
+
* const importStmt = `import { User } from '${exportPath}';`;
|
|
219
|
+
* ```
|
|
220
|
+
*/
|
|
14
221
|
toExportPath(): string;
|
|
222
|
+
/**
|
|
223
|
+
* Gets the generated value from the inserted artifact.
|
|
224
|
+
*
|
|
225
|
+
* This method returns the actual generated content with proper type safety
|
|
226
|
+
* based on the generation mode. For 'force' generation, the value is guaranteed
|
|
227
|
+
* to be present. For 'lazy' generation, the value might be undefined if
|
|
228
|
+
* generation was skipped.
|
|
229
|
+
*
|
|
230
|
+
* @returns The generated value, with optionality based on generation type
|
|
231
|
+
*
|
|
232
|
+
* @example Forced generation (guaranteed value)
|
|
233
|
+
* ```typescript
|
|
234
|
+
* const userModel = this.insertModel(generator, 'User'); // 'force' by default
|
|
235
|
+
* const value = userModel.toValue(); // UserModelValue (never undefined)
|
|
236
|
+
*
|
|
237
|
+
* // Safe to use directly
|
|
238
|
+
* const code = `type OrderUser = ${value};`;
|
|
239
|
+
* ```
|
|
240
|
+
*
|
|
241
|
+
* @example Lazy generation (optional value)
|
|
242
|
+
* ```typescript
|
|
243
|
+
* const optionalModel = this.insertModel(generator, 'Optional', { generation: 'lazy' });
|
|
244
|
+
* const value = optionalModel.toValue(); // OptionalValue | undefined
|
|
245
|
+
*
|
|
246
|
+
* if (value) {
|
|
247
|
+
* // Use the generated value
|
|
248
|
+
* const code = `type Optional = ${value};`;
|
|
249
|
+
* } else {
|
|
250
|
+
* // Handle missing value (generation was skipped)
|
|
251
|
+
* const code = 'type Optional = any; // Fallback';
|
|
252
|
+
* }
|
|
253
|
+
* ```
|
|
254
|
+
*/
|
|
15
255
|
toValue(): T extends 'force' ? V : V | undefined;
|
|
16
256
|
}
|
|
17
257
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Inserted.d.ts","sourceRoot":"","sources":["../../src/dsl/Inserted.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,cAAc,EACd,cAAc,EACf,MAAM,4BAA4B,CAAA;AACnC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,KAAK,eAAe,CAAC,CAAC,SAAS,cAAc,EAAE,CAAC,SAAS,cAAc,EAAE,cAAc,IAAI;IACzF,QAAQ,EAAE,eAAe,CAAC,cAAc,CAAC,CAAA;IACzC,UAAU,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;CACtC,CAAA;AAED,qBAAa,QAAQ,CAAC,CAAC,SAAS,cAAc,EAAE,CAAC,SAAS,cAAc,EAAE,cAAc;IACtF,QAAQ,EAAE,eAAe,CAAC,cAAc,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"Inserted.d.ts","sourceRoot":"","sources":["../../src/dsl/Inserted.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,cAAc,EACd,cAAc,EACf,MAAM,4BAA4B,CAAA;AACnC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD;;;;;;GAMG;AACH,KAAK,eAAe,CAAC,CAAC,SAAS,cAAc,EAAE,CAAC,SAAS,cAAc,EAAE,cAAc,IAAI;IACzF,4DAA4D;IAC5D,QAAQ,EAAE,eAAe,CAAC,cAAc,CAAC,CAAA;IACzC,8CAA8C;IAC9C,UAAU,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;CACtC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsIG;AACH,qBAAa,QAAQ,CAAC,CAAC,SAAS,cAAc,EAAE,CAAC,SAAS,cAAc,EAAE,cAAc;IACtF,4DAA4D;IAC5D,QAAQ,EAAE,eAAe,CAAC,cAAc,CAAC,CAAA;IAEzC,8CAA8C;IAC9C,UAAU,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAErC;;;;;;OAMG;gBACS,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,cAAc,CAAC;IAK3E;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,IAAI,MAAM;IAIhB;;;;;;;;;;;;;;;;;;OAkBG;IACH,YAAY,IAAI,UAAU;IAI1B;;;;;;;;;;;;;;;;;OAiBG;IACH,YAAY,IAAI,MAAM;IAItB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACH,OAAO,IAAI,CAAC,SAAS,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS;CAGjD"}
|