1- Guide to Extending the Code Generator
2- =====================================
1+ # Guide to Extending the Code Generator
32
43This document provides detailed instructions on how to extend the ` cdd-web-ng ` generator to support new frameworks (
54like [ React] ( https://react.dev ) and [ Vue] ( https://vuejs.org ) ) and integrate different HTTP clients (
@@ -26,7 +25,7 @@ graph LR
2625
2726 subgraph Gen [Layer 3: Generation]
2827 Base(<strong>Generator Engine</strong>)
29-
28+
3029 %% The Fork
3130 subgraph Targets [Targets]
3231 direction TB
@@ -40,7 +39,7 @@ graph LR
4039 Input --> Parser
4140 Parser --> IR
4241 IR --> Base
43-
42+
4443 Base -- "Existing" --> T_Ang
4544 Base -- "Extension 1" --> T_React
4645 Base -. "Extension N" .-> T_Other
@@ -68,58 +67,58 @@ graph LR
6867
69682 . ** Analysis / IR Layer (` src/analysis ` )** : This is the "brain" of the generator. It analyzes the parsed specification
7069 and converts it into a highly abstracted ** Intermediate Representation (IR)** .
71- * ` ServiceMethodModel ` : Describes * what * an API call looks like (inputs, outputs, serialization rules) without
72- specifying * how * to call it.
73- * ` FormAnalysisResult ` : Describes a form's structure (groups, arrays, validation rules) without coupling to Angular
70+ - ` ServiceMethodModel ` : Describes _ what _ an API call looks like (inputs, outputs, serialization rules) without
71+ specifying _ how _ to call it.
72+ - ` FormAnalysisResult ` : Describes a form's structure (groups, arrays, validation rules) without coupling to Angular
7473 Forms or React Hook Form.
75- * ` ListViewModel ` : Describes a data table structure.
76- * ** Key Takeaway** : This layer decouples the "What" from the "How". It is reusable across * all * target frameworks.
77-
78- * Visualizing how the Form IR is translated:*
79-
80- ``` mermaid
81- graph TD
82- %% --- TOP ---
83- FormIR(<strong>FormAnalysisResult</strong><br/>Agnostic Schema Definition)
84-
85- %% --- MIDDLE: GENERATORS ---
86- subgraph Strategies [Generation Strategies]
87- direction LR
88-
89- ReactStrategy(<strong>React Generator</strong><br/>e.g. React Hook Form)
90- AngStrategy(<strong>Angular Generator</strong><br/>e.g. Reactive Forms)
91- OtherStrategy(<strong>...</strong><br/>e.g. Vue / Svelte)
92- end
93-
94- %% --- BOTTOM: OUTPUT ---
95- subgraph Result [Final Code]
96- direction LR
97-
98- R_Comp(<strong>React Component</strong>)
99- A_Comp(<strong>Angular Component</strong>)
100- O_Comp(<strong>...</strong>)
101- end
102-
103- %% --- EDGES ---
104- FormIR --> ReactStrategy
105- FormIR --> AngStrategy
106- FormIR -.-> OtherStrategy
107-
108- ReactStrategy --> R_Comp
109- AngStrategy --> A_Comp
110- OtherStrategy -.-> O_Comp
111-
112- %% --- STYLING ---
113- classDef analysis fill:#34a853,color:#ffffff,stroke:#20344b,stroke-width:0px
114- classDef gen fill:#4285f4,color:#ffffff,stroke:#20344b,stroke-width:0px
115- classDef output fill:#ffffff,color:#20344b,stroke:#20344b,stroke-width:2px
116- classDef future fill:#ffffff,stroke:#20344b,color:#20344b,stroke-width:2px,stroke-dasharray: 5 5
117-
118- class FormIR analysis
119- class ReactStrategy,AngStrategy gen
120- class R_Comp,A_Comp output
121- class OtherStrategy,O_Comp future
122- ```
74+ - ` ListViewModel ` : Describes a data table structure.
75+ - ** Key Takeaway** : This layer decouples the "What" from the "How". It is reusable across _ all _ target frameworks.
76+
77+ _ Visualizing how the Form IR is translated:_
78+
79+ ``` mermaid
80+ graph TD
81+ %% --- TOP ---
82+ FormIR(<strong>FormAnalysisResult</strong><br/>Agnostic Schema Definition)
83+
84+ %% --- MIDDLE: GENERATORS ---
85+ subgraph Strategies [Generation Strategies]
86+ direction LR
87+
88+ ReactStrategy(<strong>React Generator</strong><br/>e.g. React Hook Form)
89+ AngStrategy(<strong>Angular Generator</strong><br/>e.g. Reactive Forms)
90+ OtherStrategy(<strong>...</strong><br/>e.g. Vue / Svelte)
91+ end
92+
93+ %% --- BOTTOM: OUTPUT ---
94+ subgraph Result [Final Code]
95+ direction LR
96+
97+ R_Comp(<strong>React Component</strong>)
98+ A_Comp(<strong>Angular Component</strong>)
99+ O_Comp(<strong>...</strong>)
100+ end
101+
102+ %% --- EDGES ---
103+ FormIR --> ReactStrategy
104+ FormIR --> AngStrategy
105+ FormIR -.-> OtherStrategy
106+
107+ ReactStrategy --> R_Comp
108+ AngStrategy --> A_Comp
109+ OtherStrategy -.-> O_Comp
110+
111+ %% --- STYLING ---
112+ classDef analysis fill:#34a853,color:#ffffff,stroke:#20344b,stroke-width:0px
113+ classDef gen fill:#4285f4,color:#ffffff,stroke:#20344b,stroke-width:0px
114+ classDef output fill:#ffffff,color:#20344b,stroke:#20344b,stroke-width:2px
115+ classDef future fill:#ffffff,stroke:#20344b,color:#20344b,stroke-width:2px,stroke-dasharray: 5 5
116+
117+ class FormIR analysis
118+ class ReactStrategy,AngStrategy gen
119+ class R_Comp,A_Comp output
120+ class OtherStrategy,O_Comp future
121+ ```
123122
1241233. **Generation Layer (`src/generators`)**: Consumes the IR and emits framework-specific strings (TypeScript, HTML,
125124 CSS). All framework-specific logic (Angular Services, React Hooks, Vue Composables) lives exclusively here.
@@ -168,8 +167,12 @@ import { ParameterSerializerGenerator } from '../shared/parameter-serializer.gen
168167import { ReactAxiosGenerator } from ' ./service/axios-service.generator.js' ;
169168
170169export class ReactClientGenerator extends AbstractClientGenerator {
171- public async generate(project : Project , parser : SwaggerParser , config : GeneratorConfig , outputDir : string ): Promise <void > {
172-
170+ public async generate(
171+ project : Project ,
172+ parser : SwaggerParser ,
173+ config : GeneratorConfig ,
174+ outputDir : string ,
175+ ): Promise <void > {
173176 // Step 1: Generate Models (Reusable!)
174177 // The TypeGenerator creates pure TypeScript interfaces found in /models
175178 new TypeGenerator (parser , project , config ).generate (outputDir );
@@ -210,7 +213,6 @@ import { AbstractServiceGenerator } from '../../base/service.base.js';
210213import { ServiceMethodAnalyzer } from ' @src/analysis/service-method-analyzer.js' ;
211214
212215export class ReactAxiosGenerator extends AbstractServiceGenerator {
213-
214216 // Define the file naming convention (e.g., useUserApi.ts)
215217 protected getFileName(controllerName : string ): string {
216218 return ` use${controllerName }Api.ts ` ;
@@ -220,16 +222,16 @@ export class ReactAxiosGenerator extends AbstractServiceGenerator {
220222 protected generateImports(sourceFile : SourceFile , operations : PathInfo []): void {
221223 sourceFile .addImportDeclaration ({
222224 moduleSpecifier: ' react' ,
223- namedImports: [' useCallback' ]
225+ namedImports: [' useCallback' ],
224226 });
225227 sourceFile .addImportDeclaration ({
226228 moduleSpecifier: ' axios' ,
227- defaultImport: ' axios'
229+ defaultImport: ' axios' ,
228230 });
229231 // Import the shared serializer!
230232 sourceFile .addImportDeclaration ({
231233 moduleSpecifier: ' ../utils/parameter-serializer' ,
232- namedImports: [' ParameterSerializer' ]
234+ namedImports: [' ParameterSerializer' ],
233235 });
234236 }
235237
@@ -240,7 +242,7 @@ export class ReactAxiosGenerator extends AbstractServiceGenerator {
240242 const hook = sourceFile .addFunction ({
241243 name: hookName ,
242244 isExported: true ,
243- statements: [] // Body
245+ statements: [], // Body
244246 });
245247
246248 // Use the Analyzer to interpret the spec!
@@ -303,13 +305,13 @@ graph TD
303305 %% --- THE IMPLEMENTATIONS ---
304306 subgraph Endpoint [Implementation Output]
305307 direction LR
306-
308+
307309 Impl_Ang("<strong>Angular HttpClient</strong>")
308-
310+
309311 Impl_Axios("<strong>Axios</strong><br/>(Promise based)")
310-
312+
311313 Impl_Fetch("<strong>Fetch API</strong><br/>(Native)")
312-
314+
313315 Impl_Other("<strong>...</strong><br/>(e.g. Ky / SuperAgent)")
314316 end
315317
@@ -323,7 +325,7 @@ graph TD
323325 GenReact --> Impl_Axios
324326 GenReact --> Impl_Fetch
325327 GenReact -.-> Impl_Other
326-
328+
327329 GenMore -.- Impl_Other
328330
329331 %% ALL depend on the Serializer
@@ -396,5 +398,5 @@ axios.get(url, { params });
3963982 . ** Import ` ParameterSerializer ` ** in your generated service file.
3973993 . ** Map the abstract ` ServiceMethodModel ` headers/cookies/query** to the specific syntax of your client library using
398400 the serializer's output.
399- * Example: Map ` cookieParams ` logic -> ` document.cookie = ... ` or ` axios ` interceptor.
400- * Example: Map ` headerParams ` logic -> ` headers: { ... } ` object.
401+ - Example: Map ` cookieParams ` logic -> ` document.cookie = ... ` or ` axios ` interceptor.
402+ - Example: Map ` headerParams ` logic -> ` headers: { ... } ` object.
0 commit comments