@skmtc/core 0.0.783 → 0.0.785
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/dsl/File.d.ts +208 -0
- package/esm/dsl/File.d.ts.map +1 -1
- package/esm/dsl/File.js +197 -0
- package/esm/dsl/model/ModelBase.d.ts +257 -0
- package/esm/dsl/model/ModelBase.d.ts.map +1 -1
- package/esm/dsl/model/ModelBase.js +248 -0
- package/esm/dsl/operation/OperationBase.d.ts +175 -0
- package/esm/dsl/operation/OperationBase.d.ts.map +1 -1
- package/esm/dsl/operation/OperationBase.js +166 -0
- package/package.json +5 -1
- package/script/dsl/File.d.ts +208 -0
- package/script/dsl/File.d.ts.map +1 -1
- package/script/dsl/File.js +197 -0
- package/script/dsl/model/ModelBase.d.ts +257 -0
- package/script/dsl/model/ModelBase.d.ts.map +1 -1
- package/script/dsl/model/ModelBase.js +248 -0
- package/script/dsl/operation/OperationBase.d.ts +175 -0
- package/script/dsl/operation/OperationBase.d.ts.map +1 -1
- package/script/dsl/operation/OperationBase.js +166 -0
|
@@ -2,21 +2,134 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ModelBase = void 0;
|
|
4
4
|
const ContentBase_js_1 = require("../ContentBase.js");
|
|
5
|
+
/**
|
|
6
|
+
* Base class for model generators in the SKMTC DSL system.
|
|
7
|
+
*
|
|
8
|
+
* `ModelBase` extends {@link ContentBase} to provide specialized functionality for
|
|
9
|
+
* generating code from OpenAPI schema models. It offers type-safe methods for
|
|
10
|
+
* inserting related models, managing schema references, and handling enrichments.
|
|
11
|
+
*
|
|
12
|
+
* This class serves as the foundation for creating custom model generators that
|
|
13
|
+
* transform OpenAPI schemas into various code artifacts like TypeScript interfaces,
|
|
14
|
+
* validation schemas, or database models.
|
|
15
|
+
*
|
|
16
|
+
* ## Key Features
|
|
17
|
+
*
|
|
18
|
+
* - **Model Insertion**: Insert related models with automatic reference resolution
|
|
19
|
+
* - **Schema Normalization**: Handle complex schema references and fallbacks
|
|
20
|
+
* - **Export Management**: Control which models are exported from generated files
|
|
21
|
+
* - **Enrichment Support**: Extend functionality with custom enrichment data
|
|
22
|
+
* - **Type Safety**: Full TypeScript support with generic enrichment types
|
|
23
|
+
*
|
|
24
|
+
* @template EnrichmentType - Optional type for custom enrichment data
|
|
25
|
+
*
|
|
26
|
+
* @example Basic model generator
|
|
27
|
+
* ```typescript
|
|
28
|
+
* import { ModelBase, Definition } from '@skmtc/core';
|
|
29
|
+
*
|
|
30
|
+
* class TypeScriptInterface extends ModelBase {
|
|
31
|
+
* toDefinition(): Definition {
|
|
32
|
+
* const schema = this.context.getSchema(this.refName);
|
|
33
|
+
*
|
|
34
|
+
* return new Definition({
|
|
35
|
+
* name: this.refName,
|
|
36
|
+
* content: `export interface ${this.refName} {
|
|
37
|
+
* ${this.generateProperties(schema)}
|
|
38
|
+
* }`
|
|
39
|
+
* });
|
|
40
|
+
* }
|
|
41
|
+
*
|
|
42
|
+
* private generateProperties(schema: OasSchema): string {
|
|
43
|
+
* // Generate interface properties from schema
|
|
44
|
+
* return Object.entries(schema.properties || {})
|
|
45
|
+
* .map(([key, prop]) => `${key}: ${this.getPropertyType(prop)}`)
|
|
46
|
+
* .join(';\n ');
|
|
47
|
+
* }
|
|
48
|
+
* }
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* @example With enrichments
|
|
52
|
+
* ```typescript
|
|
53
|
+
* type ValidationEnrichment = {
|
|
54
|
+
* validators: string[];
|
|
55
|
+
* customRules: Record<string, string>;
|
|
56
|
+
* };
|
|
57
|
+
*
|
|
58
|
+
* class ValidationModel extends ModelBase<ValidationEnrichment> {
|
|
59
|
+
* toDefinition(): Definition {
|
|
60
|
+
* const enrichment = this.settings.enrichment;
|
|
61
|
+
* const validators = enrichment?.validators || [];
|
|
62
|
+
*
|
|
63
|
+
* return new Definition({
|
|
64
|
+
* name: `${this.refName}Validator`,
|
|
65
|
+
* content: this.generateValidator(validators)
|
|
66
|
+
* });
|
|
67
|
+
* }
|
|
68
|
+
* }
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @example Inserting related models
|
|
72
|
+
* ```typescript
|
|
73
|
+
* class ApiModel extends ModelBase {
|
|
74
|
+
* toDefinition(): Definition {
|
|
75
|
+
* const schema = this.context.getSchema(this.refName);
|
|
76
|
+
*
|
|
77
|
+
* // Insert related models automatically
|
|
78
|
+
* if (schema.properties?.user) {
|
|
79
|
+
* this.insertNormalizedModel(
|
|
80
|
+
* new TypeScriptInterface({ ... }),
|
|
81
|
+
* { schema: schema.properties.user, fallbackName: 'User' }
|
|
82
|
+
* );
|
|
83
|
+
* }
|
|
84
|
+
*
|
|
85
|
+
* return new Definition({
|
|
86
|
+
* name: this.refName,
|
|
87
|
+
* content: this.generateInterface(schema)
|
|
88
|
+
* });
|
|
89
|
+
* }
|
|
90
|
+
* }
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
5
93
|
class ModelBase extends ContentBase_js_1.ContentBase {
|
|
94
|
+
/**
|
|
95
|
+
* Creates a new ModelBase instance.
|
|
96
|
+
*
|
|
97
|
+
* @param args - Model generator configuration
|
|
98
|
+
* @param args.context - The generation context providing pipeline access
|
|
99
|
+
* @param args.settings - Content settings with export path and enrichments
|
|
100
|
+
* @param args.generatorKey - Unique identifier for this generator type
|
|
101
|
+
* @param args.refName - Reference name for the model being generated
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```typescript
|
|
105
|
+
* const model = new ModelBase({
|
|
106
|
+
* context: generateContext,
|
|
107
|
+
* settings: {
|
|
108
|
+
* exportPath: './src/models.ts',
|
|
109
|
+
* enrichment: customEnrichments
|
|
110
|
+
* },
|
|
111
|
+
* generatorKey: 'typescript-models',
|
|
112
|
+
* refName: 'UserModel'
|
|
113
|
+
* });
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
6
116
|
constructor({ context, settings, generatorKey, refName }) {
|
|
7
117
|
super({ context });
|
|
118
|
+
/** Content settings including export path and enrichment configuration */
|
|
8
119
|
Object.defineProperty(this, "settings", {
|
|
9
120
|
enumerable: true,
|
|
10
121
|
configurable: true,
|
|
11
122
|
writable: true,
|
|
12
123
|
value: void 0
|
|
13
124
|
});
|
|
125
|
+
/** Reference name for the model being generated */
|
|
14
126
|
Object.defineProperty(this, "refName", {
|
|
15
127
|
enumerable: true,
|
|
16
128
|
configurable: true,
|
|
17
129
|
writable: true,
|
|
18
130
|
value: void 0
|
|
19
131
|
});
|
|
132
|
+
/** Generator key identifying this generator type */
|
|
20
133
|
Object.defineProperty(this, "generatorKey", {
|
|
21
134
|
enumerable: true,
|
|
22
135
|
configurable: true,
|
|
@@ -27,6 +140,43 @@ class ModelBase extends ContentBase_js_1.ContentBase {
|
|
|
27
140
|
this.refName = refName;
|
|
28
141
|
this.settings = settings;
|
|
29
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Inserts a related model with forced generation.
|
|
145
|
+
*
|
|
146
|
+
* This method adds a related model to the current generation context, ensuring
|
|
147
|
+
* it will be generated regardless of whether it already exists. The inserted
|
|
148
|
+
* model will be exported to the same destination path as this model unless
|
|
149
|
+
* `noExport` is specified.
|
|
150
|
+
*
|
|
151
|
+
* @template V - Type of generated value returned by the insertable
|
|
152
|
+
* @template EnrichmentType - Type of enrichment data for the insertable
|
|
153
|
+
* @param insertable - The model generator to insert
|
|
154
|
+
* @param refName - Reference name for the inserted model
|
|
155
|
+
* @param options - Insertion options
|
|
156
|
+
* @param options.noExport - Whether to skip exporting the inserted model
|
|
157
|
+
* @returns Inserted model reference with generated value
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```typescript
|
|
161
|
+
* class UserModel extends ModelBase {
|
|
162
|
+
* toDefinition(): Definition {
|
|
163
|
+
* // Insert an address model that's always generated
|
|
164
|
+
* const address = this.insertModel(
|
|
165
|
+
* new AddressModel({ ... }),
|
|
166
|
+
* 'Address',
|
|
167
|
+
* { noExport: false }
|
|
168
|
+
* );
|
|
169
|
+
*
|
|
170
|
+
* return new Definition({
|
|
171
|
+
* name: this.refName,
|
|
172
|
+
* content: `export interface ${this.refName} {
|
|
173
|
+
* address: ${address.value}
|
|
174
|
+
* }`
|
|
175
|
+
* });
|
|
176
|
+
* }
|
|
177
|
+
* }
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
30
180
|
insertModel(insertable, refName, options = {}) {
|
|
31
181
|
return this.context.insertModel(insertable, refName, {
|
|
32
182
|
generation: 'force',
|
|
@@ -34,6 +184,63 @@ class ModelBase extends ContentBase_js_1.ContentBase {
|
|
|
34
184
|
noExport: options.noExport
|
|
35
185
|
});
|
|
36
186
|
}
|
|
187
|
+
/**
|
|
188
|
+
* Inserts a related model with automatic schema normalization and reference resolution.
|
|
189
|
+
*
|
|
190
|
+
* This method intelligently handles schema references by automatically resolving
|
|
191
|
+
* them to appropriate model names. If the schema is a reference, it uses the
|
|
192
|
+
* referenced name; otherwise it falls back to the provided fallback name.
|
|
193
|
+
*
|
|
194
|
+
* This is particularly useful when working with complex nested schemas where
|
|
195
|
+
* you want to automatically generate models for referenced types.
|
|
196
|
+
*
|
|
197
|
+
* @template V - Type of generated value returned by the insertable
|
|
198
|
+
* @template Schema - Type of OpenAPI schema (schema object, reference, or void)
|
|
199
|
+
* @template EnrichmentType - Type of enrichment data for the insertable
|
|
200
|
+
* @param insertable - The model generator to insert
|
|
201
|
+
* @param args - Schema normalization arguments
|
|
202
|
+
* @param args.schema - The OpenAPI schema to normalize (can be reference or actual schema)
|
|
203
|
+
* @param args.fallbackName - Name to use if schema is not a reference
|
|
204
|
+
* @param options - Insertion options
|
|
205
|
+
* @param options.noExport - Whether to skip exporting the inserted model
|
|
206
|
+
* @returns Inserted model reference with normalized name and generated value
|
|
207
|
+
*
|
|
208
|
+
* @example Handling schema references
|
|
209
|
+
* ```typescript
|
|
210
|
+
* class OrderModel extends ModelBase {
|
|
211
|
+
* toDefinition(): Definition {
|
|
212
|
+
* const schema = this.context.getSchema(this.refName);
|
|
213
|
+
*
|
|
214
|
+
* // Handle customer property - could be reference or inline schema
|
|
215
|
+
* if (schema.properties?.customer) {
|
|
216
|
+
* const customer = this.insertNormalizedModel(
|
|
217
|
+
* new CustomerModel({ ... }),
|
|
218
|
+
* {
|
|
219
|
+
* schema: schema.properties.customer,
|
|
220
|
+
* fallbackName: 'Customer'
|
|
221
|
+
* }
|
|
222
|
+
* );
|
|
223
|
+
* // customer.refName will be 'Customer' or the referenced schema name
|
|
224
|
+
* }
|
|
225
|
+
*
|
|
226
|
+
* return new Definition({ ... });
|
|
227
|
+
* }
|
|
228
|
+
* }
|
|
229
|
+
* ```
|
|
230
|
+
*
|
|
231
|
+
* @example With complex nested schemas
|
|
232
|
+
* ```typescript
|
|
233
|
+
* // If schema.properties.items is { $ref: '#/components/schemas/Product' }
|
|
234
|
+
* // Then the inserted model will use refName 'Product'
|
|
235
|
+
* const items = this.insertNormalizedModel(
|
|
236
|
+
* new ProductModel({ ... }),
|
|
237
|
+
* {
|
|
238
|
+
* schema: schema.properties.items,
|
|
239
|
+
* fallbackName: 'Item' // Won't be used since schema has $ref
|
|
240
|
+
* }
|
|
241
|
+
* );
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
37
244
|
insertNormalizedModel(insertable, { schema, fallbackName }, options = {}) {
|
|
38
245
|
return this.context.insertNormalisedModel(insertable, {
|
|
39
246
|
schema,
|
|
@@ -41,6 +248,47 @@ class ModelBase extends ContentBase_js_1.ContentBase {
|
|
|
41
248
|
destinationPath: this.settings.exportPath
|
|
42
249
|
}, options);
|
|
43
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* Registers a file-level artifact with the generation context.
|
|
253
|
+
*
|
|
254
|
+
* This method allows the model generator to register additional content
|
|
255
|
+
* (like imports, exports, or file-level definitions) that should be included
|
|
256
|
+
* in the generated file. The registration is automatically scoped to this
|
|
257
|
+
* model's export path.
|
|
258
|
+
*
|
|
259
|
+
* @param args - Registration arguments
|
|
260
|
+
* @param args.content - The content to register (import, export, etc.)
|
|
261
|
+
* @param args.phase - When to register the content ('pre' or 'post')
|
|
262
|
+
*
|
|
263
|
+
* @example Registering imports
|
|
264
|
+
* ```typescript
|
|
265
|
+
* class ApiModel extends ModelBase {
|
|
266
|
+
* toDefinition(): Definition {
|
|
267
|
+
* // Register an import that all generated models need
|
|
268
|
+
* this.register({
|
|
269
|
+
* content: "import { BaseModel } from './base';",
|
|
270
|
+
* phase: 'pre'
|
|
271
|
+
* });
|
|
272
|
+
*
|
|
273
|
+
* return new Definition({ ... });
|
|
274
|
+
* }
|
|
275
|
+
* }
|
|
276
|
+
* ```
|
|
277
|
+
*
|
|
278
|
+
* @example Registering type exports
|
|
279
|
+
* ```typescript
|
|
280
|
+
* class TypeModel extends ModelBase {
|
|
281
|
+
* toDefinition(): Definition {
|
|
282
|
+
* this.register({
|
|
283
|
+
* content: "export type * from './types';",
|
|
284
|
+
* phase: 'post'
|
|
285
|
+
* });
|
|
286
|
+
*
|
|
287
|
+
* return new Definition({ ... });
|
|
288
|
+
* }
|
|
289
|
+
* }
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
44
292
|
register(args) {
|
|
45
293
|
this.context.register({
|
|
46
294
|
...args,
|
|
@@ -12,17 +12,192 @@ import type { RefName } from '../../types/RefName.js';
|
|
|
12
12
|
import { OasSchema } from '../../oas/schema/Schema.js';
|
|
13
13
|
import { OasRef } from '../../oas/ref/Ref.js';
|
|
14
14
|
import { OasVoid } from '../../oas/void/Void.js';
|
|
15
|
+
/**
|
|
16
|
+
* Constructor arguments for {@link OperationBase}.
|
|
17
|
+
*
|
|
18
|
+
* @template EnrichmentType - Optional type for custom enrichment data
|
|
19
|
+
*/
|
|
15
20
|
export type OperationBaseArgs<EnrichmentType = undefined> = {
|
|
21
|
+
/** The generation context providing access to the processing pipeline */
|
|
16
22
|
context: GenerateContext;
|
|
23
|
+
/** Content settings including export path and enrichment configuration */
|
|
17
24
|
settings: ContentSettings<EnrichmentType>;
|
|
25
|
+
/** Unique identifier for this generator type */
|
|
18
26
|
generatorKey: GeneratorKey;
|
|
27
|
+
/** The OpenAPI operation being processed */
|
|
19
28
|
operation: OasOperation;
|
|
20
29
|
};
|
|
30
|
+
/**
|
|
31
|
+
* Base class for operation generators in the SKMTC DSL system.
|
|
32
|
+
*
|
|
33
|
+
* `OperationBase` extends {@link ContentBase} to provide specialized functionality for
|
|
34
|
+
* generating code from OpenAPI operations. It offers type-safe methods for inserting
|
|
35
|
+
* related operations and models, managing complex operation dependencies, and handling
|
|
36
|
+
* enrichments specific to API operations.
|
|
37
|
+
*
|
|
38
|
+
* This class serves as the foundation for creating custom operation generators that
|
|
39
|
+
* transform OpenAPI operations into various code artifacts like API clients, server
|
|
40
|
+
* handlers, validation middleware, or documentation.
|
|
41
|
+
*
|
|
42
|
+
* ## Key Features
|
|
43
|
+
*
|
|
44
|
+
* - **Operation Insertion**: Insert related operations with automatic dependency tracking
|
|
45
|
+
* - **Model Integration**: Seamlessly insert related models from operation schemas
|
|
46
|
+
* - **Schema Normalization**: Handle complex request/response schema references
|
|
47
|
+
* - **Export Management**: Control which operations are exported from generated files
|
|
48
|
+
* - **Enrichment Support**: Extend functionality with operation-specific enrichment data
|
|
49
|
+
* - **Type Safety**: Full TypeScript support with generic enrichment types
|
|
50
|
+
*
|
|
51
|
+
* @template EnrichmentType - Optional type for custom enrichment data
|
|
52
|
+
*
|
|
53
|
+
* @example Basic API client generator
|
|
54
|
+
* ```typescript
|
|
55
|
+
* import { OperationBase, Definition } from '@skmtc/core';
|
|
56
|
+
*
|
|
57
|
+
* class ApiClientMethod extends OperationBase {
|
|
58
|
+
* toDefinition(): Definition {
|
|
59
|
+
* const { method, path, operationId } = this.operation;
|
|
60
|
+
*
|
|
61
|
+
* return new Definition({
|
|
62
|
+
* name: operationId || `${method}${this.pascalCasePath()}`,
|
|
63
|
+
* content: `async ${operationId}(${this.generateParameters()}) {
|
|
64
|
+
* return this.request('${method}', '${path}', ${this.generateRequestBody()});
|
|
65
|
+
* }`
|
|
66
|
+
* });
|
|
67
|
+
* }
|
|
68
|
+
* }
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @example With request/response models
|
|
72
|
+
* ```typescript
|
|
73
|
+
* class TypedApiMethod extends OperationBase {
|
|
74
|
+
* toDefinition(): Definition {
|
|
75
|
+
* const operation = this.operation;
|
|
76
|
+
*
|
|
77
|
+
* // Generate request model if needed
|
|
78
|
+
* let requestType = 'void';
|
|
79
|
+
* if (operation.requestBody?.content?.['application/json']?.schema) {
|
|
80
|
+
* const requestModel = this.insertNormalizedModel(
|
|
81
|
+
* new RequestModel({ ... }),
|
|
82
|
+
* {
|
|
83
|
+
* schema: operation.requestBody.content['application/json'].schema,
|
|
84
|
+
* fallbackName: `${operation.operationId}Request`
|
|
85
|
+
* }
|
|
86
|
+
* );
|
|
87
|
+
* requestType = requestModel.value;
|
|
88
|
+
* }
|
|
89
|
+
*
|
|
90
|
+
* // Generate response model
|
|
91
|
+
* const responseSchema = operation.responses?.['200']?.content?.['application/json']?.schema;
|
|
92
|
+
* const responseModel = this.insertNormalizedModel(
|
|
93
|
+
* new ResponseModel({ ... }),
|
|
94
|
+
* { schema: responseSchema, fallbackName: `${operation.operationId}Response` }
|
|
95
|
+
* );
|
|
96
|
+
*
|
|
97
|
+
* return new Definition({
|
|
98
|
+
* name: operation.operationId,
|
|
99
|
+
* content: `async ${operation.operationId}(data: ${requestType}): Promise<${responseModel.value}> {
|
|
100
|
+
* return this.request('${operation.method}', '${operation.path}', data);
|
|
101
|
+
* }`
|
|
102
|
+
* });
|
|
103
|
+
* }
|
|
104
|
+
* }
|
|
105
|
+
* ```
|
|
106
|
+
*
|
|
107
|
+
* @example With enrichments
|
|
108
|
+
* ```typescript
|
|
109
|
+
* type AuthEnrichment = {
|
|
110
|
+
* requiresAuth: boolean;
|
|
111
|
+
* permissions: string[];
|
|
112
|
+
* };
|
|
113
|
+
*
|
|
114
|
+
* class SecuredApiMethod extends OperationBase<AuthEnrichment> {
|
|
115
|
+
* toDefinition(): Definition {
|
|
116
|
+
* const enrichment = this.settings.enrichment;
|
|
117
|
+
* const requiresAuth = enrichment?.requiresAuth ?? false;
|
|
118
|
+
*
|
|
119
|
+
* const authCheck = requiresAuth
|
|
120
|
+
* ? 'this.checkAuth();'
|
|
121
|
+
* : '';
|
|
122
|
+
*
|
|
123
|
+
* return new Definition({
|
|
124
|
+
* name: this.operation.operationId,
|
|
125
|
+
* content: `async ${this.operation.operationId}() {
|
|
126
|
+
* ${authCheck}
|
|
127
|
+
* return this.request('${this.operation.method}', '${this.operation.path}');
|
|
128
|
+
* }`
|
|
129
|
+
* });
|
|
130
|
+
* }
|
|
131
|
+
* }
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
21
134
|
export declare class OperationBase<EnrichmentType = undefined> extends ContentBase {
|
|
135
|
+
/** Content settings including export path and enrichment configuration */
|
|
22
136
|
settings: ContentSettings<EnrichmentType>;
|
|
137
|
+
/** The OpenAPI operation being processed */
|
|
23
138
|
operation: OasOperation;
|
|
139
|
+
/** Generator key identifying this generator type */
|
|
24
140
|
generatorKey: GeneratorKey;
|
|
141
|
+
/**
|
|
142
|
+
* Creates a new OperationBase instance.
|
|
143
|
+
*
|
|
144
|
+
* @param args - Operation generator configuration
|
|
145
|
+
* @param args.context - The generation context providing pipeline access
|
|
146
|
+
* @param args.settings - Content settings with export path and enrichments
|
|
147
|
+
* @param args.generatorKey - Unique identifier for this generator type
|
|
148
|
+
* @param args.operation - The OpenAPI operation being processed
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```typescript
|
|
152
|
+
* const operation = new OperationBase({
|
|
153
|
+
* context: generateContext,
|
|
154
|
+
* settings: {
|
|
155
|
+
* exportPath: './src/api.ts',
|
|
156
|
+
* enrichment: customEnrichments
|
|
157
|
+
* },
|
|
158
|
+
* generatorKey: 'api-client',
|
|
159
|
+
* operation: oasOperation
|
|
160
|
+
* });
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
25
163
|
constructor({ context, generatorKey, settings, operation }: OperationBaseArgs<EnrichmentType>);
|
|
164
|
+
/**
|
|
165
|
+
* Inserts a related operation with forced generation.
|
|
166
|
+
*
|
|
167
|
+
* This method adds a related operation to the current generation context, ensuring
|
|
168
|
+
* it will be generated regardless of whether it already exists. This is useful for
|
|
169
|
+
* operations that depend on other operations or need to generate helper operations.
|
|
170
|
+
*
|
|
171
|
+
* @template V - Type of generated value returned by the insertable
|
|
172
|
+
* @template EnrichmentType - Type of enrichment data for the insertable
|
|
173
|
+
* @param insertable - The operation generator to insert
|
|
174
|
+
* @param operation - The OpenAPI operation to process
|
|
175
|
+
* @param options - Insertion options
|
|
176
|
+
* @param options.noExport - Whether to skip exporting the inserted operation
|
|
177
|
+
* @returns Inserted operation reference with generated value
|
|
178
|
+
*
|
|
179
|
+
* @example Inserting helper operations
|
|
180
|
+
* ```typescript
|
|
181
|
+
* class CrudApiClient extends OperationBase {
|
|
182
|
+
* toDefinition(): Definition {
|
|
183
|
+
* // Insert a related validation operation
|
|
184
|
+
* const validator = this.insertOperation(
|
|
185
|
+
* new ValidationOperation({ ... }),
|
|
186
|
+
* this.operation,
|
|
187
|
+
* { noExport: true }
|
|
188
|
+
* );
|
|
189
|
+
*
|
|
190
|
+
* return new Definition({
|
|
191
|
+
* name: this.operation.operationId,
|
|
192
|
+
* content: `async ${this.operation.operationId}(data: any) {
|
|
193
|
+
* ${validator.value}(data);
|
|
194
|
+
* return this.request('${this.operation.method}', '${this.operation.path}', data);
|
|
195
|
+
* }`
|
|
196
|
+
* });
|
|
197
|
+
* }
|
|
198
|
+
* }
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
26
201
|
insertOperation<V extends GeneratedValue, EnrichmentType = undefined>(insertable: OperationInsertable<V, EnrichmentType>, operation: OasOperation, options?: Pick<InsertOperationOptions<'force'>, 'noExport'>): Inserted<V, 'force', EnrichmentType>;
|
|
27
202
|
insertModel<V extends GeneratedValue, EnrichmentType = undefined>(insertable: ModelInsertable<V, EnrichmentType>, refName: RefName, options?: Pick<InsertModelOptions<'force'>, 'noExport'>): Inserted<V, 'force', EnrichmentType>;
|
|
28
203
|
insertNormalizedModel<V extends GeneratedValue, Schema extends OasSchema | OasRef<'schema'> | OasVoid, EnrichmentType = undefined>(insertable: ModelInsertable<V, EnrichmentType>, { schema, fallbackName }: Omit<InsertNormalisedModelArgs<Schema>, 'destinationPath'>, options?: Pick<InsertModelOptions<'force'>, 'noExport'>): InsertNormalisedModelReturn<V, Schema>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OperationBase.d.ts","sourceRoot":"","sources":["../../../src/dsl/operation/OperationBase.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAC5D,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EAEf,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,yBAAyB,EACzB,2BAA2B,EAC5B,MAAM,kCAAkC,CAAA;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAElD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAEhD,MAAM,MAAM,iBAAiB,CAAC,cAAc,GAAG,SAAS,IAAI;IAC1D,OAAO,EAAE,eAAe,CAAA;IACxB,QAAQ,EAAE,eAAe,CAAC,cAAc,CAAC,CAAA;IACzC,YAAY,EAAE,YAAY,CAAA;IAC1B,SAAS,EAAE,YAAY,CAAA;CACxB,CAAA;AAED,qBAAa,aAAa,CAAC,cAAc,GAAG,SAAS,CAAE,SAAQ,WAAW;IACxE,QAAQ,EAAE,eAAe,CAAC,cAAc,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"OperationBase.d.ts","sourceRoot":"","sources":["../../../src/dsl/operation/OperationBase.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,21 +2,150 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.OperationBase = void 0;
|
|
4
4
|
const ContentBase_js_1 = require("../ContentBase.js");
|
|
5
|
+
/**
|
|
6
|
+
* Base class for operation generators in the SKMTC DSL system.
|
|
7
|
+
*
|
|
8
|
+
* `OperationBase` extends {@link ContentBase} to provide specialized functionality for
|
|
9
|
+
* generating code from OpenAPI operations. It offers type-safe methods for inserting
|
|
10
|
+
* related operations and models, managing complex operation dependencies, and handling
|
|
11
|
+
* enrichments specific to API operations.
|
|
12
|
+
*
|
|
13
|
+
* This class serves as the foundation for creating custom operation generators that
|
|
14
|
+
* transform OpenAPI operations into various code artifacts like API clients, server
|
|
15
|
+
* handlers, validation middleware, or documentation.
|
|
16
|
+
*
|
|
17
|
+
* ## Key Features
|
|
18
|
+
*
|
|
19
|
+
* - **Operation Insertion**: Insert related operations with automatic dependency tracking
|
|
20
|
+
* - **Model Integration**: Seamlessly insert related models from operation schemas
|
|
21
|
+
* - **Schema Normalization**: Handle complex request/response schema references
|
|
22
|
+
* - **Export Management**: Control which operations are exported from generated files
|
|
23
|
+
* - **Enrichment Support**: Extend functionality with operation-specific enrichment data
|
|
24
|
+
* - **Type Safety**: Full TypeScript support with generic enrichment types
|
|
25
|
+
*
|
|
26
|
+
* @template EnrichmentType - Optional type for custom enrichment data
|
|
27
|
+
*
|
|
28
|
+
* @example Basic API client generator
|
|
29
|
+
* ```typescript
|
|
30
|
+
* import { OperationBase, Definition } from '@skmtc/core';
|
|
31
|
+
*
|
|
32
|
+
* class ApiClientMethod extends OperationBase {
|
|
33
|
+
* toDefinition(): Definition {
|
|
34
|
+
* const { method, path, operationId } = this.operation;
|
|
35
|
+
*
|
|
36
|
+
* return new Definition({
|
|
37
|
+
* name: operationId || `${method}${this.pascalCasePath()}`,
|
|
38
|
+
* content: `async ${operationId}(${this.generateParameters()}) {
|
|
39
|
+
* return this.request('${method}', '${path}', ${this.generateRequestBody()});
|
|
40
|
+
* }`
|
|
41
|
+
* });
|
|
42
|
+
* }
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @example With request/response models
|
|
47
|
+
* ```typescript
|
|
48
|
+
* class TypedApiMethod extends OperationBase {
|
|
49
|
+
* toDefinition(): Definition {
|
|
50
|
+
* const operation = this.operation;
|
|
51
|
+
*
|
|
52
|
+
* // Generate request model if needed
|
|
53
|
+
* let requestType = 'void';
|
|
54
|
+
* if (operation.requestBody?.content?.['application/json']?.schema) {
|
|
55
|
+
* const requestModel = this.insertNormalizedModel(
|
|
56
|
+
* new RequestModel({ ... }),
|
|
57
|
+
* {
|
|
58
|
+
* schema: operation.requestBody.content['application/json'].schema,
|
|
59
|
+
* fallbackName: `${operation.operationId}Request`
|
|
60
|
+
* }
|
|
61
|
+
* );
|
|
62
|
+
* requestType = requestModel.value;
|
|
63
|
+
* }
|
|
64
|
+
*
|
|
65
|
+
* // Generate response model
|
|
66
|
+
* const responseSchema = operation.responses?.['200']?.content?.['application/json']?.schema;
|
|
67
|
+
* const responseModel = this.insertNormalizedModel(
|
|
68
|
+
* new ResponseModel({ ... }),
|
|
69
|
+
* { schema: responseSchema, fallbackName: `${operation.operationId}Response` }
|
|
70
|
+
* );
|
|
71
|
+
*
|
|
72
|
+
* return new Definition({
|
|
73
|
+
* name: operation.operationId,
|
|
74
|
+
* content: `async ${operation.operationId}(data: ${requestType}): Promise<${responseModel.value}> {
|
|
75
|
+
* return this.request('${operation.method}', '${operation.path}', data);
|
|
76
|
+
* }`
|
|
77
|
+
* });
|
|
78
|
+
* }
|
|
79
|
+
* }
|
|
80
|
+
* ```
|
|
81
|
+
*
|
|
82
|
+
* @example With enrichments
|
|
83
|
+
* ```typescript
|
|
84
|
+
* type AuthEnrichment = {
|
|
85
|
+
* requiresAuth: boolean;
|
|
86
|
+
* permissions: string[];
|
|
87
|
+
* };
|
|
88
|
+
*
|
|
89
|
+
* class SecuredApiMethod extends OperationBase<AuthEnrichment> {
|
|
90
|
+
* toDefinition(): Definition {
|
|
91
|
+
* const enrichment = this.settings.enrichment;
|
|
92
|
+
* const requiresAuth = enrichment?.requiresAuth ?? false;
|
|
93
|
+
*
|
|
94
|
+
* const authCheck = requiresAuth
|
|
95
|
+
* ? 'this.checkAuth();'
|
|
96
|
+
* : '';
|
|
97
|
+
*
|
|
98
|
+
* return new Definition({
|
|
99
|
+
* name: this.operation.operationId,
|
|
100
|
+
* content: `async ${this.operation.operationId}() {
|
|
101
|
+
* ${authCheck}
|
|
102
|
+
* return this.request('${this.operation.method}', '${this.operation.path}');
|
|
103
|
+
* }`
|
|
104
|
+
* });
|
|
105
|
+
* }
|
|
106
|
+
* }
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
5
109
|
class OperationBase extends ContentBase_js_1.ContentBase {
|
|
110
|
+
/**
|
|
111
|
+
* Creates a new OperationBase instance.
|
|
112
|
+
*
|
|
113
|
+
* @param args - Operation generator configuration
|
|
114
|
+
* @param args.context - The generation context providing pipeline access
|
|
115
|
+
* @param args.settings - Content settings with export path and enrichments
|
|
116
|
+
* @param args.generatorKey - Unique identifier for this generator type
|
|
117
|
+
* @param args.operation - The OpenAPI operation being processed
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```typescript
|
|
121
|
+
* const operation = new OperationBase({
|
|
122
|
+
* context: generateContext,
|
|
123
|
+
* settings: {
|
|
124
|
+
* exportPath: './src/api.ts',
|
|
125
|
+
* enrichment: customEnrichments
|
|
126
|
+
* },
|
|
127
|
+
* generatorKey: 'api-client',
|
|
128
|
+
* operation: oasOperation
|
|
129
|
+
* });
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
6
132
|
constructor({ context, generatorKey, settings, operation }) {
|
|
7
133
|
super({ context });
|
|
134
|
+
/** Content settings including export path and enrichment configuration */
|
|
8
135
|
Object.defineProperty(this, "settings", {
|
|
9
136
|
enumerable: true,
|
|
10
137
|
configurable: true,
|
|
11
138
|
writable: true,
|
|
12
139
|
value: void 0
|
|
13
140
|
});
|
|
141
|
+
/** The OpenAPI operation being processed */
|
|
14
142
|
Object.defineProperty(this, "operation", {
|
|
15
143
|
enumerable: true,
|
|
16
144
|
configurable: true,
|
|
17
145
|
writable: true,
|
|
18
146
|
value: void 0
|
|
19
147
|
});
|
|
148
|
+
/** Generator key identifying this generator type */
|
|
20
149
|
Object.defineProperty(this, "generatorKey", {
|
|
21
150
|
enumerable: true,
|
|
22
151
|
configurable: true,
|
|
@@ -27,6 +156,43 @@ class OperationBase extends ContentBase_js_1.ContentBase {
|
|
|
27
156
|
this.operation = operation;
|
|
28
157
|
this.settings = settings;
|
|
29
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* Inserts a related operation with forced generation.
|
|
161
|
+
*
|
|
162
|
+
* This method adds a related operation to the current generation context, ensuring
|
|
163
|
+
* it will be generated regardless of whether it already exists. This is useful for
|
|
164
|
+
* operations that depend on other operations or need to generate helper operations.
|
|
165
|
+
*
|
|
166
|
+
* @template V - Type of generated value returned by the insertable
|
|
167
|
+
* @template EnrichmentType - Type of enrichment data for the insertable
|
|
168
|
+
* @param insertable - The operation generator to insert
|
|
169
|
+
* @param operation - The OpenAPI operation to process
|
|
170
|
+
* @param options - Insertion options
|
|
171
|
+
* @param options.noExport - Whether to skip exporting the inserted operation
|
|
172
|
+
* @returns Inserted operation reference with generated value
|
|
173
|
+
*
|
|
174
|
+
* @example Inserting helper operations
|
|
175
|
+
* ```typescript
|
|
176
|
+
* class CrudApiClient extends OperationBase {
|
|
177
|
+
* toDefinition(): Definition {
|
|
178
|
+
* // Insert a related validation operation
|
|
179
|
+
* const validator = this.insertOperation(
|
|
180
|
+
* new ValidationOperation({ ... }),
|
|
181
|
+
* this.operation,
|
|
182
|
+
* { noExport: true }
|
|
183
|
+
* );
|
|
184
|
+
*
|
|
185
|
+
* return new Definition({
|
|
186
|
+
* name: this.operation.operationId,
|
|
187
|
+
* content: `async ${this.operation.operationId}(data: any) {
|
|
188
|
+
* ${validator.value}(data);
|
|
189
|
+
* return this.request('${this.operation.method}', '${this.operation.path}', data);
|
|
190
|
+
* }`
|
|
191
|
+
* });
|
|
192
|
+
* }
|
|
193
|
+
* }
|
|
194
|
+
* ```
|
|
195
|
+
*/
|
|
30
196
|
insertOperation(insertable, operation, options = {}) {
|
|
31
197
|
return this.context.insertOperation(insertable, operation, {
|
|
32
198
|
generation: 'force',
|