c4-gen 1.5.1 → 1.5.2

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/markdown.js +43 -20
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "c4-gen",
3
- "version": "1.5.1",
3
+ "version": "1.5.2",
4
4
  "description": "Công cụ tự động sinh tài liệu kiến trúc C4 Model từ source code sử dụng AI",
5
5
  "main": "index.js",
6
6
  "type": "module",
package/src/markdown.js CHANGED
@@ -693,59 +693,71 @@ ${seq.mermaidCode || generateSequenceMermaid(seq)}
693
693
 
694
694
  ## 2. Class Diagrams & Details
695
695
 
696
- ${code.classes?.map((cls, index) => `
696
+ ${code.classes?.map((cls, index) => {
697
+ if (!cls || !cls.name) return '';
698
+ return `
697
699
  ### ${index + 1}. ${cls.name}
698
700
 
699
701
  | Property | Value |
700
702
  |----------|-------|
701
- | **Type** | ${cls.type} |
702
- | **File** | \`${cls.file}\` |
703
+ | **Type** | ${cls.type || 'class'} |
704
+ | **File** | \`${cls.file || 'Not specified'}\` |
703
705
  | **Extends** | ${cls.extends || 'None'} |
704
706
  | **Implements** | ${cls.implements?.join(', ') || 'None'} |
705
707
 
706
- **Description:** ${cls.description}
708
+ **Description:** ${cls.description || 'No description'}
707
709
 
708
710
  #### Design Patterns:
709
711
  ${cls.designPatterns?.map(p => `- ${p}`).join('\n') || '- None'}
710
712
 
711
713
  #### Properties:
712
714
 
713
- ${cls.properties?.map(prop => `
714
- - **\`${prop.name}\`** (${prop.type})
715
+ ${cls.properties?.map(prop => {
716
+ if (!prop || !prop.name) return '';
717
+ return `
718
+ - **\`${prop.name}\`** (${prop.type || 'any'})
715
719
  - Visibility: ${prop.visibility || 'public'}
716
720
  - Required: ${prop.isRequired ? 'Yes' : 'No'}
717
721
  ${prop.defaultValue ? `- Default: \`${prop.defaultValue}\`` : ''}
718
- - Description: ${prop.description}
719
- `).join('\n') || '- No properties'}
722
+ - Description: ${prop.description || 'N/A'}
723
+ `;
724
+ }).filter(p => p).join('\n') || '- No properties'}
720
725
 
721
726
  #### Methods:
722
727
 
723
- ${cls.methods?.map(method => `
724
- ##### \`${method.name}(${method.parameters?.map(p => `${p.name}: ${p.type}`).join(', ') || ''})\`
728
+ ${cls.methods?.map(method => {
729
+ if (!method || !method.name) return '';
730
+ return `
731
+ ##### \`${method.name}(${method.parameters?.map(p => `${p.name || 'param'}: ${p.type || 'any'}`).join(', ') || ''})\`
725
732
 
726
733
  - **Visibility:** ${method.visibility || 'public'}
727
734
  - **Static:** ${method.isStatic ? 'Yes' : 'No'}
728
735
  - **Async:** ${method.isAsync ? 'Yes' : 'No'}
729
- - **Returns:** ${method.returnType}
730
- - **Description:** ${method.description}
736
+ - **Returns:** ${method.returnType || 'void'}
737
+ - **Description:** ${method.description || 'N/A'}
731
738
 
732
739
  ${method.parameters?.length > 0 ? `**Parameters:**
733
- ${method.parameters.map(p => `- \`${p.name}\` (${p.type}) ${p.isOptional ? '[Optional]' : '[Required]'}: ${p.description}`).join('\n')}
740
+ ${method.parameters.map(p => `- \`${p.name || 'param'}\` (${p.type || 'any'}) ${p.isOptional ? '[Optional]' : '[Required]'}: ${p.description || 'N/A'}`).join('\n')}
734
741
  ` : ''}
735
742
 
736
743
  ${method.exceptions?.length > 0 ? `**Exceptions:** ${method.exceptions.join(', ')}` : ''}
737
- `).join('\n') || '- No methods'}
744
+ `;
745
+ }).filter(m => m).join('\n') || '- No methods'}
738
746
 
739
747
  #### Relationships:
740
748
 
741
- ${cls.relationships?.map(rel => `
749
+ ${cls.relationships?.map(rel => {
750
+ if (!rel || !rel.type || !rel.to) return '';
751
+ return `
742
752
  - **${rel.type}** → **${rel.to}**
743
- - Description: ${rel.description}
753
+ - Description: ${rel.description || 'N/A'}
744
754
  - Cardinality: ${rel.cardinality || 'Not specified'}
745
- `).join('\n') || '- No relationships'}
755
+ `;
756
+ }).filter(r => r).join('\n') || '- No relationships'}
746
757
 
747
758
  ---
748
- `).join('\n') || 'No classes documented'}
759
+ `;
760
+ }).filter(c => c).join('\n') || 'No classes documented'}
749
761
 
750
762
  ---
751
763
 
@@ -791,8 +803,13 @@ ${generateClassMermaid(code)}
791
803
  }
792
804
 
793
805
  function generateSequenceMermaid(seq) {
806
+ if (!seq || !seq.steps || !Array.isArray(seq.steps)) {
807
+ return 'sequenceDiagram\n Note: No steps defined\n';
808
+ }
809
+
794
810
  let mermaid = 'sequenceDiagram\n';
795
811
  seq.steps?.forEach(step => {
812
+ if (!step || !step.from || !step.to || !step.action) return;
796
813
  mermaid += ` ${step.from}->>+${step.to}: ${step.action}\n`;
797
814
  if (step.responseType) {
798
815
  mermaid += ` ${step.to}-->>-${step.from}: ${step.responseType}\n`;
@@ -804,26 +821,32 @@ function generateSequenceMermaid(seq) {
804
821
  function generateClassMermaid(code) {
805
822
  const classes = code.classes || [];
806
823
  return classes.map(cls => {
824
+ // Safe check for class name
825
+ if (!cls || !cls.name) return '';
826
+
807
827
  const className = cls.name.replace(/[^a-zA-Z0-9]/g, '_');
808
828
  let mermaid = ` class ${className} {\n`;
809
829
 
810
830
  // Properties
811
831
  cls.properties?.forEach(prop => {
832
+ if (!prop || !prop.name || !prop.type) return;
812
833
  const visibility = prop.visibility === 'private' ? '-' : prop.visibility === 'protected' ? '#' : '+';
813
834
  mermaid += ` ${visibility}${prop.type} ${prop.name}\n`;
814
835
  });
815
836
 
816
837
  // Methods
817
838
  cls.methods?.forEach(method => {
839
+ if (!method || !method.name) return;
818
840
  const visibility = method.visibility === 'private' ? '-' : method.visibility === 'protected' ? '#' : '+';
819
841
  const params = method.parameters?.map(p => `${p.name}: ${p.type}`).join(', ') || '';
820
- mermaid += ` ${visibility}${method.name}(${params}) ${method.returnType}\n`;
842
+ mermaid += ` ${visibility}${method.name}(${params}) ${method.returnType || 'void'}\n`;
821
843
  });
822
844
 
823
845
  mermaid += ' }\n';
824
846
 
825
847
  // Relationships
826
848
  cls.relationships?.forEach(rel => {
849
+ if (!rel || !rel.to || !rel.type) return;
827
850
  const target = rel.to.replace(/[^a-zA-Z0-9]/g, '_');
828
851
  if (rel.type === 'extends') {
829
852
  mermaid += ` ${target} <|-- ${className}\n`;
@@ -835,7 +858,7 @@ function generateClassMermaid(code) {
835
858
  });
836
859
 
837
860
  return mermaid;
838
- }).join('\n');
861
+ }).filter(m => m).join('\n'); // Filter out empty strings
839
862
  }
840
863
 
841
864
  function generateDatabaseSchemaDoc(schema) {