mirror of
				https://github.com/mermaid-js/mermaid.git
				synced 2025-10-31 10:54:15 +01:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			@mermaid-j
			...
			usecase_di
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 5c04a8d09d | 
| @@ -143,6 +143,7 @@ typeof | ||||
| typestr | ||||
| unshift | ||||
| urlsafe | ||||
| usecase | ||||
| verifymethod | ||||
| VERIFYMTHD | ||||
| WARN_DOCSDIR_DOESNT_MATCH | ||||
|   | ||||
| @@ -28,6 +28,7 @@ import architecture from '../diagrams/architecture/architectureDetector.js'; | ||||
| import { registerLazyLoadedDiagrams } from './detectType.js'; | ||||
| import { registerDiagram } from './diagramAPI.js'; | ||||
| import { treemap } from '../diagrams/treemap/detector.js'; | ||||
| import { usecase } from '../diagrams/usecase/detector.js'; | ||||
| import '../type.d.ts'; | ||||
|  | ||||
| let hasLoadedDiagrams = false; | ||||
| @@ -101,6 +102,7 @@ export const addDiagrams = () => { | ||||
|     xychart, | ||||
|     block, | ||||
|     radar, | ||||
|     treemap | ||||
|     treemap, | ||||
|     usecase | ||||
|   ); | ||||
| }; | ||||
|   | ||||
							
								
								
									
										38
									
								
								packages/mermaid/src/diagrams/usecase/db.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								packages/mermaid/src/diagrams/usecase/db.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| import type { DiagramDB } from '../../diagram-api/types.js'; | ||||
| import type { UsecaseDiagramConfig, UsecaseNode } from './types.js'; | ||||
| import { cleanAndMerge } from '../../utils.js'; | ||||
|  | ||||
| export class UsecaseDiagramDB implements DiagramDB { | ||||
|   public getNodes() { | ||||
|     return []; | ||||
|   } | ||||
|  | ||||
|   public getConfig() { | ||||
|     return cleanAndMerge({}) as Required<UsecaseDiagramConfig>; | ||||
|   } | ||||
|  | ||||
|   public addNode(node: UsecaseNode, level: number) { | ||||
|     if (level === 0) { | ||||
|       // TODO | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   public getRoot() { | ||||
|     return { name: '', children: [] }; | ||||
|   } | ||||
|  | ||||
|   public addClass(_id: string, _style: string) { | ||||
|     // TODO | ||||
|   } | ||||
|   public getClasses() { | ||||
|     // TODO | ||||
|   } | ||||
|  | ||||
|   public getStylesForClass(_classSelector: string) { | ||||
|     // TODO | ||||
|   } | ||||
|  | ||||
|   public clear() { | ||||
|     // commonClear(); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										22
									
								
								packages/mermaid/src/diagrams/usecase/detector.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								packages/mermaid/src/diagrams/usecase/detector.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| import type { | ||||
|   DiagramDetector, | ||||
|   DiagramLoader, | ||||
|   ExternalDiagramDefinition, | ||||
| } from '../../diagram-api/types.js'; | ||||
|  | ||||
| const id = 'usecase'; | ||||
|  | ||||
| const detector: DiagramDetector = (txt) => { | ||||
|   return /^\s*usecase/.test(txt); | ||||
| }; | ||||
|  | ||||
| const loader: DiagramLoader = async () => { | ||||
|   const { diagram } = await import('./diagram.js'); | ||||
|   return { id, diagram }; | ||||
| }; | ||||
|  | ||||
| export const usecase: ExternalDiagramDefinition = { | ||||
|   id, | ||||
|   detector, | ||||
|   loader, | ||||
| }; | ||||
							
								
								
									
										14
									
								
								packages/mermaid/src/diagrams/usecase/diagram.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								packages/mermaid/src/diagrams/usecase/diagram.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| import type { DiagramDefinition } from '../../diagram-api/types.js'; | ||||
| import { UsecaseDiagramDB } from './db.js'; | ||||
| import { parser } from './parser.js'; | ||||
| import { renderer } from './renderer.js'; | ||||
| import styles from './styles.js'; | ||||
|  | ||||
| export const diagram: DiagramDefinition = { | ||||
|   parser, | ||||
|   get db() { | ||||
|     return new UsecaseDiagramDB(); | ||||
|   }, | ||||
|   renderer, | ||||
|   styles, | ||||
| }; | ||||
							
								
								
									
										40
									
								
								packages/mermaid/src/diagrams/usecase/parser.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								packages/mermaid/src/diagrams/usecase/parser.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| import { parse } from '@mermaid-js/parser'; | ||||
| import type { ParserDefinition } from '../../diagram-api/types.js'; | ||||
| import { log } from '../../logger.js'; | ||||
| import { populateCommonDb } from '../common/populateCommonDb.js'; | ||||
| import type { UsecaseAst } from './types.js'; | ||||
| import { UsecaseDiagramDB } from './db.js'; | ||||
|  | ||||
| /** | ||||
|  * Populates the database with data from the Usecase AST | ||||
|  * @param ast - The Usecase AST | ||||
|  */ | ||||
| const populate = (ast: UsecaseAst, db: UsecaseDiagramDB) => { | ||||
|   // We need to bypass the type checking for populateCommonDb | ||||
|   // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||||
|   populateCommonDb(ast as any, db); | ||||
| }; | ||||
|  | ||||
| export const parser: ParserDefinition = { | ||||
|   // @ts-expect-error - UsecaseDB is not assignable to DiagramDB | ||||
|   parser: { yy: undefined }, | ||||
|   parse: async (text: string): Promise<void> => { | ||||
|     try { | ||||
|       // Use a generic parse that accepts any diagram type | ||||
|  | ||||
|       const parseFunc = parse as (diagramType: string, text: string) => Promise<UsecaseAst>; | ||||
|       const ast = await parseFunc('usecase', text); | ||||
|       log.debug('Usecase AST:', ast); | ||||
|       const db = parser.parser?.yy; | ||||
|       if (!(db instanceof UsecaseDiagramDB)) { | ||||
|         throw new Error( | ||||
|           'parser.parser?.yy was not a UsecaseDiagramDB. This is due to a bug within Mermaid, please report this issue at https://github.com/mermaid-js/mermaid/issues.' | ||||
|         ); | ||||
|       } | ||||
|       populate(ast, db); | ||||
|     } catch (error) { | ||||
|       log.error('Error parsing usecase:', error); | ||||
|       throw error; | ||||
|     } | ||||
|   }, | ||||
| }; | ||||
							
								
								
									
										21
									
								
								packages/mermaid/src/diagrams/usecase/renderer.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								packages/mermaid/src/diagrams/usecase/renderer.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| import type { Diagram } from '../../Diagram.js'; | ||||
| import type { | ||||
|   DiagramRenderer, | ||||
|   DiagramStyleClassDef, | ||||
|   DrawDefinition, | ||||
| } from '../../diagram-api/types.js'; | ||||
|  | ||||
| /** | ||||
|  * Draws the Usecase diagram | ||||
|  */ | ||||
| const draw: DrawDefinition = (_text, _id, _version, _diagram: Diagram) => { | ||||
|   // TODO: Implement the draw function for the usecase diagram | ||||
| }; | ||||
|  | ||||
| const getClasses = function ( | ||||
|   _text: string, | ||||
|   _diagramObj: Pick<Diagram, 'db'> | ||||
| ): Map<string, DiagramStyleClassDef> { | ||||
|   return new Map<string, DiagramStyleClassDef>(); | ||||
| }; | ||||
| export const renderer: DiagramRenderer = { draw, getClasses }; | ||||
							
								
								
									
										51
									
								
								packages/mermaid/src/diagrams/usecase/styles.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								packages/mermaid/src/diagrams/usecase/styles.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| import type { DiagramStylesProvider } from '../../diagram-api/types.js'; | ||||
| import { cleanAndMerge } from '../../utils.js'; | ||||
| import type { UsecaseStyleOptions } from './types.js'; | ||||
|  | ||||
| const defaultUsecaseStyleOptions: UsecaseStyleOptions = { | ||||
|   sectionStrokeColor: 'black', | ||||
|   sectionStrokeWidth: '1', | ||||
|   sectionFillColor: '#efefef', | ||||
|   leafStrokeColor: 'black', | ||||
|   leafStrokeWidth: '1', | ||||
|   leafFillColor: '#efefef', | ||||
|   labelColor: 'black', | ||||
|   labelFontSize: '12px', | ||||
|   valueFontSize: '10px', | ||||
|   valueColor: 'black', | ||||
|   titleColor: 'black', | ||||
|   titleFontSize: '14px', | ||||
| }; | ||||
|  | ||||
| export const getStyles: DiagramStylesProvider = ({ | ||||
|   usecase, | ||||
| }: { usecase?: UsecaseStyleOptions } = {}) => { | ||||
|   const options = cleanAndMerge(defaultUsecaseStyleOptions, usecase); | ||||
|  | ||||
|   return ` | ||||
|   .usecaseNode.section { | ||||
|     stroke: ${options.sectionStrokeColor}; | ||||
|     stroke-width: ${options.sectionStrokeWidth}; | ||||
|     fill: ${options.sectionFillColor}; | ||||
|   } | ||||
|   .usecaseNode.leaf { | ||||
|     stroke: ${options.leafStrokeColor}; | ||||
|     stroke-width: ${options.leafStrokeWidth}; | ||||
|     fill: ${options.leafFillColor}; | ||||
|   } | ||||
|   .usecaseLabel { | ||||
|     fill: ${options.labelColor}; | ||||
|     font-size: ${options.labelFontSize}; | ||||
|   } | ||||
|   .usecaseValue { | ||||
|     fill: ${options.valueColor}; | ||||
|     font-size: ${options.valueFontSize}; | ||||
|   } | ||||
|   .usecaseTitle { | ||||
|     fill: ${options.titleColor}; | ||||
|     font-size: ${options.titleFontSize}; | ||||
|   } | ||||
|   `; | ||||
| }; | ||||
|  | ||||
| export default getStyles; | ||||
							
								
								
									
										68
									
								
								packages/mermaid/src/diagrams/usecase/types.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								packages/mermaid/src/diagrams/usecase/types.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| import type { DiagramDBBase, DiagramStyleClassDef } from '../../diagram-api/types.js'; | ||||
| import type { BaseDiagramConfig } from '../../config.type.js'; | ||||
|  | ||||
| export interface UsecaseNode { | ||||
|   name: string; | ||||
|   children?: UsecaseNode[]; | ||||
|   value?: number; | ||||
|   parent?: UsecaseNode; | ||||
|   classSelector?: string; | ||||
|   cssCompiledStyles?: string[]; | ||||
| } | ||||
|  | ||||
| export interface UsecaseDiagramDB extends DiagramDBBase<UsecaseDiagramConfig> { | ||||
|   getNodes: () => UsecaseNode[]; | ||||
|   addNode: (node: UsecaseNode, level: number) => void; | ||||
|   getRoot: () => UsecaseNode | undefined; | ||||
|   getClasses: () => Map<string, DiagramStyleClassDef>; | ||||
|   addClass: (className: string, style: string) => void; | ||||
|   getStylesForClass: (classSelector: string) => string[]; | ||||
|   // Update | ||||
| } | ||||
|  | ||||
| export interface UsecaseStyleOptions { | ||||
|   sectionStrokeColor?: string; | ||||
|   sectionStrokeWidth?: string; | ||||
|   sectionFillColor?: string; | ||||
|   leafStrokeColor?: string; | ||||
|   leafStrokeWidth?: string; | ||||
|   leafFillColor?: string; | ||||
|   labelColor?: string; | ||||
|   labelFontSize?: string; | ||||
|   valueFontSize?: string; | ||||
|   valueColor?: string; | ||||
|   titleColor?: string; | ||||
|   titleFontSize?: string; | ||||
| } | ||||
|  | ||||
| export interface UsecaseData { | ||||
|   nodes: UsecaseNode[]; | ||||
|   levels: Map<UsecaseNode, number>; | ||||
|   root?: UsecaseNode; | ||||
|   outerNodes: UsecaseNode[]; | ||||
| } | ||||
|  | ||||
| export interface UsecaseItem { | ||||
|   $type: string; | ||||
|   name: string; | ||||
|   value?: number; | ||||
|   classSelector?: string; | ||||
| } | ||||
|  | ||||
| export interface UsecaseAst { | ||||
|   title?: string; | ||||
|   description?: string; | ||||
| } | ||||
|  | ||||
| // Define the UsecaseDiagramConfig interface | ||||
| export interface UsecaseDiagramConfig extends BaseDiagramConfig { | ||||
|   padding?: number; | ||||
|   diagramPadding?: number; | ||||
|   showValues?: boolean; | ||||
|   nodeWidth?: number; | ||||
|   nodeHeight?: number; | ||||
|   borderWidth?: number; | ||||
|   valueFontSize?: number; | ||||
|   labelFontSize?: number; | ||||
|   valueFormat?: string; | ||||
| } | ||||
| @@ -35,6 +35,11 @@ | ||||
|       "id": "treemap", | ||||
|       "grammar": "src/language/treemap/treemap.langium", | ||||
|       "fileExtensions": [".mmd", ".mermaid"] | ||||
|     }, | ||||
|     { | ||||
|       "id": "usecase", | ||||
|       "grammar": "src/language/usecase/usecase.langium", | ||||
|       "fileExtensions": [".mmd", ".mermaid"] | ||||
|     } | ||||
|   ], | ||||
|   "mode": "production", | ||||
|   | ||||
| @@ -9,6 +9,7 @@ export { | ||||
|   GitGraph, | ||||
|   Radar, | ||||
|   Treemap, | ||||
|   Usecase, | ||||
|   Branch, | ||||
|   Commit, | ||||
|   Merge, | ||||
| @@ -24,6 +25,7 @@ export { | ||||
|   isBranch, | ||||
|   isCommit, | ||||
|   isMerge, | ||||
|   isUsecase, | ||||
| } from './generated/ast.js'; | ||||
|  | ||||
| export { | ||||
| @@ -35,6 +37,7 @@ export { | ||||
|   GitGraphGeneratedModule, | ||||
|   RadarGeneratedModule, | ||||
|   TreemapGeneratedModule, | ||||
|   UsecaseGeneratedModule, | ||||
| } from './generated/module.js'; | ||||
|  | ||||
| export * from './gitGraph/index.js'; | ||||
| @@ -45,3 +48,4 @@ export * from './pie/index.js'; | ||||
| export * from './architecture/index.js'; | ||||
| export * from './radar/index.js'; | ||||
| export * from './treemap/index.js'; | ||||
| export * from './usecase/index.js'; | ||||
|   | ||||
							
								
								
									
										1
									
								
								packages/parser/src/language/usecase/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								packages/parser/src/language/usecase/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| export * from './module.js'; | ||||
							
								
								
									
										35
									
								
								packages/parser/src/language/usecase/module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								packages/parser/src/language/usecase/module.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| import { type DefaultSharedCoreModuleContext, type LangiumCoreServices } from 'langium'; | ||||
| import type { Module, PartialLangiumCoreServices } from 'langium'; | ||||
| import { EmptyFileSystem } from 'langium'; | ||||
| import { UsecaseTokenBuilder } from './tokenBuilder.js'; | ||||
| import { UsecaseValueConverter } from './valueConverter.js'; | ||||
| import { UsecaseValidator } from './usecase-validator.js'; | ||||
|  | ||||
| interface UsecaseAddedServices { | ||||
|   parser: { | ||||
|     TokenBuilder: UsecaseTokenBuilder; | ||||
|     ValueConverter: UsecaseValueConverter; | ||||
|   }; | ||||
|   validation: { | ||||
|     UsecaseValidator: UsecaseValidator; | ||||
|   }; | ||||
| } | ||||
|  | ||||
| export type UsecaseServices = LangiumCoreServices & UsecaseAddedServices; | ||||
|  | ||||
| export const UsecaseModule: Module< | ||||
|   UsecaseServices, | ||||
|   PartialLangiumCoreServices & UsecaseAddedServices | ||||
| > = { | ||||
|   parser: { | ||||
|     TokenBuilder: () => new UsecaseTokenBuilder(), | ||||
|     ValueConverter: () => new UsecaseValueConverter(), | ||||
|   }, | ||||
|   validation: { | ||||
|     UsecaseValidator: () => new UsecaseValidator(), | ||||
|   }, | ||||
| }; | ||||
|  | ||||
| export function createUsecaseServices(_context: DefaultSharedCoreModuleContext = EmptyFileSystem) { | ||||
|   // TODO | ||||
| } | ||||
							
								
								
									
										7
									
								
								packages/parser/src/language/usecase/tokenBuilder.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								packages/parser/src/language/usecase/tokenBuilder.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| import { AbstractMermaidTokenBuilder } from '../common/index.js'; | ||||
|  | ||||
| export class UsecaseTokenBuilder extends AbstractMermaidTokenBuilder { | ||||
|   public constructor() { | ||||
|     super(['usecase']); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										12
									
								
								packages/parser/src/language/usecase/usecase-validator.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								packages/parser/src/language/usecase/usecase-validator.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| import type { UsecaseServices } from './module.js'; | ||||
| /** | ||||
|  * Register custom validation checks. | ||||
|  */ | ||||
| export function registerValidationChecks(_services: UsecaseServices) { | ||||
|   // TODO | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Implementation of custom validations. | ||||
|  */ | ||||
| export class UsecaseValidator {} | ||||
							
								
								
									
										1
									
								
								packages/parser/src/language/usecase/usecase.langium
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								packages/parser/src/language/usecase/usecase.langium
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| // TODO | ||||
							
								
								
									
										12
									
								
								packages/parser/src/language/usecase/valueConverter.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								packages/parser/src/language/usecase/valueConverter.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| import type { CstNode, GrammarAST, ValueType } from 'langium'; | ||||
| import { AbstractMermaidValueConverter } from '../common/index.js'; | ||||
|  | ||||
| export class UsecaseValueConverter extends AbstractMermaidValueConverter { | ||||
|   protected runCustomConverter( | ||||
|     _rule: GrammarAST.AbstractRule, | ||||
|     _input: string, | ||||
|     _cstNode: CstNode | ||||
|   ): ValueType | undefined { | ||||
|     return undefined; | ||||
|   } | ||||
| } | ||||
| @@ -1,6 +1,15 @@ | ||||
| import type { LangiumParser, ParseResult } from 'langium'; | ||||
|  | ||||
| import type { Info, Packet, Pie, Architecture, GitGraph, Radar, Treemap } from './index.js'; | ||||
| import type { | ||||
|   Info, | ||||
|   Packet, | ||||
|   Pie, | ||||
|   Architecture, | ||||
|   GitGraph, | ||||
|   Radar, | ||||
|   Treemap, | ||||
|   // Usecase, | ||||
| } from './index.js'; | ||||
|  | ||||
| export type DiagramAST = Info | Packet | Pie | Architecture | GitGraph | Radar; | ||||
|  | ||||
| @@ -41,6 +50,11 @@ const initializers = { | ||||
|     const parser = createTreemapServices().Treemap.parser.LangiumParser; | ||||
|     parsers.treemap = parser; | ||||
|   }, | ||||
|   // usecase: async () => { | ||||
|   //   const { createUsecaseServices } = await import('./language/usecase/index.js'); | ||||
|   //   const parser = createUsecaseServices().Usecase.parser.LangiumParser; | ||||
|   //   parsers.usecase = parser; | ||||
|   // }, | ||||
| } as const; | ||||
|  | ||||
| export async function parse(diagramType: 'info', text: string): Promise<Info>; | ||||
| @@ -50,6 +64,7 @@ export async function parse(diagramType: 'architecture', text: string): Promise< | ||||
| export async function parse(diagramType: 'gitGraph', text: string): Promise<GitGraph>; | ||||
| export async function parse(diagramType: 'radar', text: string): Promise<Radar>; | ||||
| export async function parse(diagramType: 'treemap', text: string): Promise<Treemap>; | ||||
| // export async function parse(diagramType: 'usecase', text: string): Promise<Usecase>; | ||||
|  | ||||
| export async function parse<T extends DiagramAST>( | ||||
|   diagramType: keyof typeof initializers, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user