mirror of
				https://github.com/mermaid-js/mermaid.git
				synced 2025-10-27 00:44:08 +01:00 
			
		
		
		
	Compare commits
	
		
			17 Commits
		
	
	
		
			mermaid@11
			...
			sidv/biome
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 83fb2d933c | ||
|   | 48303a030d | ||
|   | 054ed6c69c | ||
|   | 89e061aa51 | ||
|   | a1badd5167 | ||
|   | 55a8e4cf7e | ||
|   | e7577ed51e | ||
|   | d2b42ebd74 | ||
|   | ba34386a69 | ||
|   | a23b891f20 | ||
|   | 3a5793f948 | ||
|   | 0a5315cd5a | ||
|   | 98f32bfdfe | ||
|   | 22a00a5f8b | ||
|   | 3381717e86 | ||
|   | 08dfdfed82 | ||
|   | 2c80d806cc | 
| @@ -2,7 +2,7 @@ import { build } from 'esbuild'; | ||||
| import { mkdir, writeFile } from 'node:fs/promises'; | ||||
| import { packageOptions } from '../.build/common.js'; | ||||
| import { generateLangium } from '../.build/generateLangium.js'; | ||||
| import { MermaidBuildOptions, defaultOptions, getBuildConfig } from './util.js'; | ||||
| import { type MermaidBuildOptions, defaultOptions, getBuildConfig } from './util.js'; | ||||
|  | ||||
| const shouldVisualize = process.argv.includes('--visualize'); | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import { readFile } from 'node:fs/promises'; | ||||
| import { transformJison } from '../.build/jisonTransformer.js'; | ||||
| import { Plugin } from 'esbuild'; | ||||
| import type { Plugin } from 'esbuild'; | ||||
|  | ||||
| export const jisonPlugin: Plugin = { | ||||
|   name: 'jison', | ||||
|   | ||||
| @@ -56,7 +56,7 @@ export const getBuildConfig = (options: MermaidBuildOptions): BuildOptions => { | ||||
|   const external: string[] = ['require', 'fs', 'path']; | ||||
|   const { name, file, packageName } = packageOptions[entryName]; | ||||
|   const outFileName = getFileName(name, options); | ||||
|   let output: BuildOptions = buildOptions({ | ||||
|   const output: BuildOptions = buildOptions({ | ||||
|     absWorkingDir: resolve(__dirname, `../packages/${packageName}`), | ||||
|     entryPoints: { | ||||
|       [outFileName]: `src/${file}`, | ||||
|   | ||||
							
								
								
									
										4
									
								
								.github/workflows/lint.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/lint.yml
									
									
									
									
										vendored
									
									
								
							| @@ -37,9 +37,9 @@ jobs: | ||||
|       - name: Run Linting | ||||
|         shell: bash | ||||
|         run: | | ||||
|           if ! pnpm run lint; then | ||||
|           if ! pnpm run lint:ci; then | ||||
|               # print a nice error message on lint failure | ||||
|               ERROR_MESSAGE='Running `pnpm run lint` failed.' | ||||
|               ERROR_MESSAGE='Running `pnpm run lint:ci` failed.' | ||||
|               ERROR_MESSAGE+=' Running `pnpm -w run lint:fix` may fix this issue. ' | ||||
|               ERROR_MESSAGE+=" If this error doesn't occur on your local machine," | ||||
|               ERROR_MESSAGE+=' make sure your packages are up-to-date by running `pnpm install`.' | ||||
|   | ||||
| @@ -1,10 +1,6 @@ | ||||
| export default { | ||||
|   '!(docs/**/*)*.{ts,js,html,md,mts}': [ | ||||
|     'eslint --cache --cache-strategy content --fix', | ||||
|     // don't cache prettier yet, since we use `prettier-plugin-jsdoc`, | ||||
|     // and prettier doesn't invalidate cache on plugin updates" | ||||
|     // https://prettier.io/docs/en/cli.html#--cache | ||||
|     'prettier --write', | ||||
|     'biome check --no-errors-on-unmatched --files-ignore-unknown=true --write', | ||||
|   ], | ||||
|   '.cspell/*.txt': ['tsx scripts/fixCSpell.ts'], | ||||
|   '**/*.jison': ['pnpm -w run lint:jison'], | ||||
|   | ||||
| @@ -1,18 +0,0 @@ | ||||
| dist | ||||
| cypress/platform/xss3.html | ||||
| .cache | ||||
| .pnpm-store | ||||
| coverage | ||||
| # Autogenerated by PNPM | ||||
| pnpm-lock.yaml | ||||
| stats | ||||
| **/.vitepress/components.d.ts | ||||
| **/.vitepress/cache | ||||
| .nyc_output | ||||
| # Autogenerated by `pnpm run --filter mermaid types:build-config` | ||||
| packages/mermaid/src/config.type.ts | ||||
| # autogenereated by langium-cli | ||||
| generated/ | ||||
| # Ignore the files creates in /demos/dev except for example.html | ||||
| demos/dev/** | ||||
| !/demos/dev/example.html | ||||
| @@ -1,8 +0,0 @@ | ||||
| { | ||||
|   "endOfLine": "auto", | ||||
|   "printWidth": 100, | ||||
|   "singleQuote": true, | ||||
|   "useTabs": false, | ||||
|   "tabWidth": 2, | ||||
|   "trailingComma": "es5" | ||||
| } | ||||
| @@ -1,4 +1,4 @@ | ||||
| import { build, InlineConfig, type PluginOption } from 'vite'; | ||||
| import { build, type InlineConfig, type PluginOption } from 'vite'; | ||||
| import { resolve } from 'path'; | ||||
| import { fileURLToPath } from 'url'; | ||||
| import jisonPlugin from './jisonPlugin.js'; | ||||
| @@ -48,7 +48,7 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions) | ||||
|   const external: (string | RegExp)[] = ['require', 'fs', 'path']; | ||||
|   console.log(entryName, packageOptions[entryName]); | ||||
|   const { name, file, packageName } = packageOptions[entryName]; | ||||
|   let output: OutputOptions = [ | ||||
|   const output: OutputOptions = [ | ||||
|     { | ||||
|       name, | ||||
|       format: 'esm', | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import { PluginOption } from 'vite'; | ||||
| import type { PluginOption } from 'vite'; | ||||
| import { getDefaults, getSchema, loadSchema } from '../.build/jsonSchema.js'; | ||||
|  | ||||
| /** | ||||
|   | ||||
							
								
								
									
										229
									
								
								biome.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										229
									
								
								biome.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,229 @@ | ||||
| { | ||||
|   "$schema": "https://biomejs.dev/schemas/1.8.2/schema.json", | ||||
|   "files": { | ||||
|     "ignore": [ | ||||
|       "**/contributor-names.json", | ||||
|       "**/generated/", | ||||
|       "**/knsv*.html", | ||||
|       "**/local*.html", | ||||
|       "**/stats/", | ||||
|       "**/user-avatars/*", | ||||
|       "./.vscode/**", | ||||
|       "cypress/platform/current.html", | ||||
|       "cypress/platform/experimental.html", | ||||
|       "cypress/platform/xss3.html", | ||||
|       "cypress/screenshots/", | ||||
|       "cypress/snapshots/", | ||||
|       "demos/dev/**", | ||||
|       "packages/mermaid/src/config.type.ts" | ||||
|     ] | ||||
|   }, | ||||
|   "formatter": { | ||||
|     "enabled": true, | ||||
|     "formatWithErrors": false, | ||||
|     "indentStyle": "space", | ||||
|     "indentWidth": 2, | ||||
|     "lineEnding": "lf", | ||||
|     "lineWidth": 100, | ||||
|     "attributePosition": "auto" | ||||
|   }, | ||||
|   "organizeImports": { "enabled": false }, | ||||
|   "linter": { | ||||
|     "enabled": true, | ||||
|     "rules": { | ||||
|       "recommended": false, | ||||
|       "complexity": { | ||||
|         "noBannedTypes": "error", | ||||
|         "noExtraBooleanCast": "error", | ||||
|         "noMultipleSpacesInRegularExpressionLiterals": "error", | ||||
|         "noUselessCatch": "error", | ||||
|         "noUselessThisAlias": "error", | ||||
|         "noUselessTypeConstraint": "error", | ||||
|         "noWith": "error", | ||||
|         "useFlatMap": "error" | ||||
|       }, | ||||
|       "correctness": { | ||||
|         "noConstAssign": "error", | ||||
|         "noConstantCondition": "error", | ||||
|         "noEmptyCharacterClassInRegex": "error", | ||||
|         "noEmptyPattern": "error", | ||||
|         "noGlobalObjectCalls": "error", | ||||
|         "noInnerDeclarations": "error", | ||||
|         "noInvalidConstructorSuper": "error", | ||||
|         "noNewSymbol": "error", | ||||
|         "noNonoctalDecimalEscape": "error", | ||||
|         "noPrecisionLoss": "error", | ||||
|         "noSelfAssign": "error", | ||||
|         "noSetterReturn": "error", | ||||
|         "noSwitchDeclarations": "error", | ||||
|         "noUndeclaredVariables": "error", | ||||
|         "noUnreachable": "error", | ||||
|         "noUnreachableSuper": "error", | ||||
|         "noUnsafeFinally": "error", | ||||
|         "noUnsafeOptionalChaining": "error", | ||||
|         "noUnusedLabels": "error", | ||||
|         "noUnusedVariables": "off", | ||||
|         "useArrayLiterals": "off", | ||||
|         "useIsNan": "error", | ||||
|         "useValidForDirection": "error", | ||||
|         "useYield": "error" | ||||
|       }, | ||||
|       "style": { | ||||
|         "noNamespace": "error", | ||||
|         "useAsConstAssertion": "error", | ||||
|         "useBlockStatements": "error", | ||||
|         "useForOf": "error", | ||||
|         "useImportType": "error", | ||||
|         "useNamingConvention": { | ||||
|           "level": "off", | ||||
|           "options": { "strictCase": false } | ||||
|         } | ||||
|       }, | ||||
|       "suspicious": { | ||||
|         "noAssignInExpressions": "warn", | ||||
|         "noAsyncPromiseExecutor": "error", | ||||
|         "noCatchAssign": "error", | ||||
|         "noClassAssign": "error", | ||||
|         "noCompareNegZero": "error", | ||||
|         "noConsoleLog": "off", | ||||
|         "noControlCharactersInRegex": "error", | ||||
|         "noDebugger": "error", | ||||
|         "noDuplicateCase": "error", | ||||
|         "noDuplicateClassMembers": "error", | ||||
|         "noDuplicateObjectKeys": "error", | ||||
|         "noDuplicateParameters": "error", | ||||
|         "noEmptyBlockStatements": "off", | ||||
|         "noExplicitAny": "off", | ||||
|         "noExtraNonNullAssertion": "error", | ||||
|         "noFallthroughSwitchClause": "error", | ||||
|         "noFunctionAssign": "error", | ||||
|         "noGlobalAssign": "error", | ||||
|         "noImportAssign": "error", | ||||
|         "noMisleadingCharacterClass": "error", | ||||
|         "noMisleadingInstantiator": "error", | ||||
|         "noPrototypeBuiltins": "off", | ||||
|         "noRedeclare": "error", | ||||
|         "noShadowRestrictedNames": "error", | ||||
|         "noUnsafeDeclarationMerging": "error", | ||||
|         "noUnsafeNegation": "error", | ||||
|         "useGetterReturn": "error", | ||||
|         "useIsArray": "error", | ||||
|         "useValidTypeof": "error" | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   "javascript": { | ||||
|     "formatter": { | ||||
|       "jsxQuoteStyle": "double", | ||||
|       "quoteProperties": "asNeeded", | ||||
|       "trailingCommas": "es5", | ||||
|       "semicolons": "always", | ||||
|       "arrowParentheses": "always", | ||||
|       "bracketSpacing": true, | ||||
|       "bracketSameLine": false, | ||||
|       "quoteStyle": "single", | ||||
|       "attributePosition": "auto" | ||||
|     }, | ||||
|     "globals": [ | ||||
|       "it", | ||||
|       "describe", | ||||
|       "beforeEach", | ||||
|       "beforeAll", | ||||
|       "afterEach", | ||||
|       "cy", | ||||
|       "expect", | ||||
|       "context", | ||||
|       "Cypress" | ||||
|     ] | ||||
|   }, | ||||
|   "overrides": [ | ||||
|     { | ||||
|       "include": ["cypress/**", "demos/**", "**/scripts"], | ||||
|       "linter": { "rules": { "suspicious": { "noConsoleLog": "off" } } } | ||||
|     }, | ||||
|     { "include": ["*.{js,jsx,mjs,cjs}"], "linter": { "rules": {} } }, | ||||
|     { "include": ["*.{ts,tsx}"], "linter": { "rules": {} } }, | ||||
|     { | ||||
|       "include": ["*.spec.{ts,js}", "cypress/**", "demos/**", "**/docs/**"], | ||||
|       "linter": { | ||||
|         "rules": { | ||||
|           "correctness": { "noUnusedVariables": "off" }, | ||||
|           "style": { | ||||
|             "useNamingConvention": "off" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "include": ["*.spec.{ts,js}", "tests/**", "cypress/**/*.js"], | ||||
|       "linter": { | ||||
|         "rules": { | ||||
|           "style": { | ||||
|             "useNamingConvention": "off" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "include": ["*.html", "*.md", "**/*.md/*"], | ||||
|       "linter": { | ||||
|         "rules": { | ||||
|           "correctness": { | ||||
|             "noUndeclaredVariables": "off", | ||||
|             "noUnusedVariables": "off" | ||||
|           }, | ||||
|           "style": { "noVar": "error" } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { "include": ["*.md"] }, | ||||
|     { | ||||
|       "include": ["**/*.md/**"], | ||||
|       "linter": { | ||||
|         "rules": { | ||||
|           "correctness": { | ||||
|             "noUndeclaredVariables": "off", | ||||
|             "noUnusedVariables": "off" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "include": ["*.ts", "*.tsx", "*.mts", "*.cts"], | ||||
|       "linter": { | ||||
|         "rules": { | ||||
|           "correctness": { | ||||
|             "noConstAssign": "off", | ||||
|             "noGlobalObjectCalls": "off", | ||||
|             "noInvalidConstructorSuper": "off", | ||||
|             "noNewSymbol": "off", | ||||
|             "noSetterReturn": "off", | ||||
|             "noUndeclaredVariables": "off", | ||||
|             "noUnreachable": "off", | ||||
|             "noUnreachableSuper": "off" | ||||
|           }, | ||||
|           "style": { | ||||
|             "noArguments": "error", | ||||
|             "noVar": "error", | ||||
|             "useConst": "error" | ||||
|           }, | ||||
|           "suspicious": { | ||||
|             "noDuplicateClassMembers": "off", | ||||
|             "noDuplicateObjectKeys": "off", | ||||
|             "noDuplicateParameters": "off", | ||||
|             "noFunctionAssign": "off", | ||||
|             "noImportAssign": "off", | ||||
|             "noRedeclare": "off", | ||||
|             "noUnsafeNegation": "off", | ||||
|             "useGetterReturn": "off" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   ], | ||||
|   "vcs": { | ||||
|     "enabled": true, | ||||
|     "clientKind": "git", | ||||
|     "useIgnoreFile": true | ||||
|   } | ||||
| } | ||||
							
								
								
									
										16
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								package.json
									
									
									
									
									
								
							| @@ -25,8 +25,9 @@ | ||||
|     "dev:vite": "tsx .vite/server.ts", | ||||
|     "dev:coverage": "pnpm coverage:cypress:clean && VITE_COVERAGE=true pnpm dev:vite", | ||||
|     "release": "pnpm build", | ||||
|     "lint": "cross-env NODE_OPTIONS=--max_old_space_size=8192 eslint --cache --cache-strategy content . && pnpm lint:jison && prettier --cache --check .", | ||||
|     "lint:fix": "cross-env NODE_OPTIONS=--max_old_space_size=8192 eslint --cache --cache-strategy content --fix . && prettier --write . && tsx scripts/fixCSpell.ts", | ||||
|     "lint": "pnpm biome check && pnpm lint:jison", | ||||
|     "lint:fix": "pnpm biome check --write", | ||||
|     "lint:ci": "cross-env NODE_OPTIONS=--max_old_space_size=8192 eslint --cache --cache-strategy content . && pnpm lint", | ||||
|     "lint:jison": "tsx ./scripts/jison/lint.mts", | ||||
|     "contributors": "tsx scripts/updateContributors.ts", | ||||
|     "cypress": "cypress run", | ||||
| @@ -51,18 +52,13 @@ | ||||
|   "author": "Knut Sveidqvist", | ||||
|   "license": "MIT", | ||||
|   "standard": { | ||||
|     "ignore": [ | ||||
|       "**/parser/*.js", | ||||
|       "dist/**/*.js", | ||||
|       "cypress/**/*.js" | ||||
|     ], | ||||
|     "globals": [ | ||||
|       "page" | ||||
|     ] | ||||
|     "ignore": ["**/parser/*.js", "dist/**/*.js", "cypress/**/*.js"], | ||||
|     "globals": ["page"] | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@applitools/eyes-cypress": "^3.42.3", | ||||
|     "@argos-ci/cypress": "^2.0.5", | ||||
|     "@biomejs/biome": "1.8.2", | ||||
|     "@cspell/eslint-plugin": "^8.6.0", | ||||
|     "@cypress/code-coverage": "^3.12.30", | ||||
|     "@rollup/plugin-typescript": "^11.1.6", | ||||
|   | ||||
| @@ -12,12 +12,7 @@ | ||||
|     }, | ||||
|     "./*": "./*" | ||||
|   }, | ||||
|   "keywords": [ | ||||
|     "diagram", | ||||
|     "markdown", | ||||
|     "example", | ||||
|     "mermaid" | ||||
|   ], | ||||
|   "keywords": ["diagram", "markdown", "example", "mermaid"], | ||||
|   "scripts": { | ||||
|     "prepublishOnly": "pnpm -w run build" | ||||
|   }, | ||||
| @@ -28,14 +23,8 @@ | ||||
|   "author": "Knut Sveidqvist", | ||||
|   "license": "MIT", | ||||
|   "standard": { | ||||
|     "ignore": [ | ||||
|       "**/parser/*.js", | ||||
|       "dist/**/*.js", | ||||
|       "cypress/**/*.js" | ||||
|     ], | ||||
|     "globals": [ | ||||
|       "page" | ||||
|     ] | ||||
|     "ignore": ["**/parser/*.js", "dist/**/*.js", "cypress/**/*.js"], | ||||
|     "globals": ["page"] | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@braintree/sanitize-url": "^7.0.0", | ||||
| @@ -47,11 +36,6 @@ | ||||
|     "mermaid": "workspace:*", | ||||
|     "rimraf": "^5.0.5" | ||||
|   }, | ||||
|   "files": [ | ||||
|     "dist" | ||||
|   ], | ||||
|   "sideEffects": [ | ||||
|     "**/*.css", | ||||
|     "**/*.scss" | ||||
|   ] | ||||
|   "files": ["dist"], | ||||
|   "sideEffects": ["**/*.css", "**/*.scss"] | ||||
| } | ||||
|   | ||||
| @@ -13,7 +13,7 @@ export const draw = (text, id, version) => { | ||||
|   try { | ||||
|     const conf = getConfig(); | ||||
|     log.debug('Rendering example diagram\n' + text, 'Conf: '); | ||||
|     const THEME_COLOR_LIMIT = getConfig().themeVariables.THEME_COLOR_LIMIT; | ||||
|     const themeColorLimit = getConfig().themeVariables.THEME_COLOR_LIMIT; | ||||
|     const securityLevel = getConfig().securityLevel; | ||||
|     // Handle root and Document for when rendering in sandbox mode | ||||
|     let sandboxElement; | ||||
| @@ -30,7 +30,7 @@ export const draw = (text, id, version) => { | ||||
|     const g = svg.append('g'); | ||||
|  | ||||
|     let i; | ||||
|     for (i = 0; i < THEME_COLOR_LIMIT; i++) { | ||||
|     for (i = 0; i < themeColorLimit; i++) { | ||||
|       const section = g.append('g').attr('class', 'section-' + i); | ||||
|       section | ||||
|         .append('rect') | ||||
|   | ||||
| @@ -12,13 +12,7 @@ | ||||
|     }, | ||||
|     "./*": "./*" | ||||
|   }, | ||||
|   "keywords": [ | ||||
|     "diagram", | ||||
|     "markdown", | ||||
|     "flowchart", | ||||
|     "elk", | ||||
|     "mermaid" | ||||
|   ], | ||||
|   "keywords": ["diagram", "markdown", "flowchart", "elk", "mermaid"], | ||||
|   "scripts": { | ||||
|     "prepublishOnly": "pnpm -w run build" | ||||
|   }, | ||||
| @@ -39,7 +33,5 @@ | ||||
|     "mermaid": "workspace:^", | ||||
|     "rimraf": "^5.0.5" | ||||
|   }, | ||||
|   "files": [ | ||||
|     "dist" | ||||
|   ] | ||||
|   "files": ["dist"] | ||||
| } | ||||
|   | ||||
| @@ -447,16 +447,19 @@ export const addEdges = function (edges, diagObj, graph, svg) { | ||||
|  | ||||
|     /* eslint-disable no-fallthrough */ | ||||
|     switch (edge.type) { | ||||
|       // biome-ignore lint/suspicious/noFallthroughSwitchClause: <explanation> | ||||
|       case 'double_arrow_cross': | ||||
|         edgeData.arrowTypeStart = 'arrow_cross'; | ||||
|       case 'arrow_cross': | ||||
|         edgeData.arrowTypeEnd = 'arrow_cross'; | ||||
|         break; | ||||
|       // biome-ignore lint/suspicious/noFallthroughSwitchClause: <explanation> | ||||
|       case 'double_arrow_point': | ||||
|         edgeData.arrowTypeStart = 'arrow_point'; | ||||
|       case 'arrow_point': | ||||
|         edgeData.arrowTypeEnd = 'arrow_point'; | ||||
|         break; | ||||
|       // biome-ignore lint/suspicious/noFallthroughSwitchClause: <explanation> | ||||
|       case 'double_arrow_circle': | ||||
|         edgeData.arrowTypeStart = 'arrow_circle'; | ||||
|       case 'arrow_circle': | ||||
|   | ||||
| @@ -12,12 +12,7 @@ | ||||
|     }, | ||||
|     "./*": "./*" | ||||
|   }, | ||||
|   "keywords": [ | ||||
|     "diagram", | ||||
|     "markdown", | ||||
|     "zenuml", | ||||
|     "mermaid" | ||||
|   ], | ||||
|   "keywords": ["diagram", "markdown", "zenuml", "mermaid"], | ||||
|   "scripts": { | ||||
|     "clean": "rimraf dist", | ||||
|     "prepublishOnly": "pnpm -w run build" | ||||
| @@ -42,7 +37,5 @@ | ||||
|   "peerDependencies": { | ||||
|     "mermaid": "workspace:>=10.0.0" | ||||
|   }, | ||||
|   "files": [ | ||||
|     "dist" | ||||
|   ] | ||||
|   "files": ["dist"] | ||||
| } | ||||
|   | ||||
| @@ -58,14 +58,8 @@ | ||||
|   "author": "Knut Sveidqvist", | ||||
|   "license": "MIT", | ||||
|   "standard": { | ||||
|     "ignore": [ | ||||
|       "**/parser/*.js", | ||||
|       "dist/**/*.js", | ||||
|       "cypress/**/*.js" | ||||
|     ], | ||||
|     "globals": [ | ||||
|       "page" | ||||
|     ] | ||||
|     "ignore": ["**/parser/*.js", "dist/**/*.js", "cypress/**/*.js"], | ||||
|     "globals": ["page"] | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@braintree/sanitize-url": "^7.0.1", | ||||
| @@ -103,8 +97,6 @@ | ||||
|     "@types/prettier": "^3.0.0", | ||||
|     "@types/stylis": "^4.2.5", | ||||
|     "@types/uuid": "^9.0.8", | ||||
|     "@typescript-eslint/eslint-plugin": "^7.3.1", | ||||
|     "@typescript-eslint/parser": "^7.3.1", | ||||
|     "ajv": "^8.12.0", | ||||
|     "chokidar": "^3.6.0", | ||||
|     "concurrently": "^8.2.2", | ||||
| @@ -132,10 +124,7 @@ | ||||
|     "vitepress": "^1.0.1", | ||||
|     "vitepress-plugin-search": "1.0.4-alpha.22" | ||||
|   }, | ||||
|   "files": [ | ||||
|     "dist/", | ||||
|     "README.md" | ||||
|   ], | ||||
|   "files": ["dist/", "README.md"], | ||||
|   "sideEffects": false, | ||||
|   "publishConfig": { | ||||
|     "access": "public" | ||||
|   | ||||
| @@ -18,7 +18,7 @@ import { execFile } from 'node:child_process'; | ||||
| import { readFile, writeFile } from 'node:fs/promises'; | ||||
| import { join } from 'node:path'; | ||||
| import { promisify } from 'node:util'; | ||||
| import prettier from 'prettier'; | ||||
| import { prettierConfig } from './prettier.js'; | ||||
|  | ||||
| // Workaround for wrong AJV types, see | ||||
| // https://github.com/ajv-validator/ajv/issues/2132#issuecomment-1290409907 | ||||
| @@ -141,7 +141,7 @@ async function generateTypescript(mermaidConfigSchema: JSONSchemaType<MermaidCon | ||||
|     { | ||||
|       additionalProperties: false, // in JSON Schema 2019-09, these are called `unevaluatedProperties` | ||||
|       unreachableDefinitions: true, // definition for FontConfig is unreachable | ||||
|       style: (await prettier.resolveConfig('.')) ?? {}, | ||||
|       style: prettierConfig, | ||||
|     } | ||||
|   ); | ||||
|  | ||||
|   | ||||
| @@ -52,6 +52,7 @@ import mm from 'micromatch'; | ||||
| // @ts-ignore No typescript declaration file | ||||
| import flatmap from 'unist-util-flatmap'; | ||||
| import { visit } from 'unist-util-visit'; | ||||
| import { prettierConfig } from './prettier.js'; | ||||
|  | ||||
| export const MERMAID_RELEASE_VERSION = JSON.parse(readFileSync('../mermaid/package.json', 'utf8')) | ||||
|   .version as string; | ||||
| @@ -85,7 +86,6 @@ const LOGMSG_COPIED = `, and copied to ${FINAL_DOCS_DIR}`; | ||||
|  | ||||
| const WARN_DOCSDIR_DOESNT_MATCH = `Changed files were transformed in ${SOURCE_DOCS_DIR} but do not match the files in ${FINAL_DOCS_DIR}. Please run 'pnpm --filter mermaid run docs:build' after making changes to ${SOURCE_DOCS_DIR} to update the ${FINAL_DOCS_DIR} directory with the transformed files.`; | ||||
|  | ||||
| const prettierConfig = (await prettier.resolveConfig('.')) ?? {}; | ||||
| // From https://github.com/vuejs/vitepress/blob/428eec3750d6b5648a77ac52d88128df0554d4d1/src/node/markdownToVue.ts#L20-L21 | ||||
| const includesRE = /<!--\s*@include:\s*(.*?)\s*-->/g; | ||||
| const includedFiles: Set<string> = new Set(); | ||||
| @@ -367,26 +367,26 @@ async function transformJsonSchema(file: string) { | ||||
|   }); | ||||
|  | ||||
|   /** Location of the `schema.yaml` files */ | ||||
|   const SCHEMA_INPUT_DIR = 'src/schemas/'; | ||||
|   const schemaInputDir = 'src/schemas/'; | ||||
|   /** | ||||
|    * Location to store the generated `schema.json` file for the website | ||||
|    * | ||||
|    * Because Vitepress doesn't handle bundling `.json` files properly, we need | ||||
|    * to instead place it into a `public/` subdirectory. | ||||
|    */ | ||||
|   const SCHEMA_OUTPUT_DIR = 'src/docs/public/schemas/'; | ||||
|   const VITEPRESS_PUBLIC_DIR = 'src/docs/public'; | ||||
|   const schemaOutputDir = 'src/docs/public/schemas/'; | ||||
|   const vitepressPublicDir = 'src/docs/public'; | ||||
|   /** | ||||
|    * Location to store the generated Schema Markdown docs. | ||||
|    * Links to JSON Schemas should automatically be rewritten to point to | ||||
|    * `SCHEMA_OUTPUT_DIR`. | ||||
|    */ | ||||
|   const SCHEMA_MARKDOWN_OUTPUT_DIR = join('src', 'docs', 'config', 'schema-docs'); | ||||
|   const schemaMarkdownOutputDir = join('src', 'docs', 'config', 'schema-docs'); | ||||
|  | ||||
|   // write .schema.json files | ||||
|   const jsonFileName = file | ||||
|     .replace('.schema.yaml', '.schema.json') | ||||
|     .replace(SCHEMA_INPUT_DIR, SCHEMA_OUTPUT_DIR); | ||||
|     .replace(schemaInputDir, schemaOutputDir); | ||||
|   copyTransformedContents(jsonFileName, !verifyOnly, JSON.stringify(jsonSchema, undefined, 2)); | ||||
|  | ||||
|   const schemas = traverseSchemas([schemaLoader()(jsonFileName, jsonSchema)]); | ||||
| @@ -414,7 +414,7 @@ async function transformJsonSchema(file: string) { | ||||
|      * @returns New absolute Vitepress path to schema | ||||
|      */ | ||||
|     rewritelinks: (origin: string) => { | ||||
|       return `/${relative(VITEPRESS_PUBLIC_DIR, origin)}`; | ||||
|       return `/${relative(vitepressPublicDir, origin)}`; | ||||
|     }, | ||||
|   })(schemas); | ||||
|  | ||||
| @@ -458,7 +458,7 @@ async function transformJsonSchema(file: string) { | ||||
|       parser: 'markdown', | ||||
|       ...prettierConfig, | ||||
|     }); | ||||
|     const newFileName = join(SCHEMA_MARKDOWN_OUTPUT_DIR, `${name}.md`); | ||||
|     const newFileName = join(schemaMarkdownOutputDir, `${name}.md`); | ||||
|     copyTransformedContents(newFileName, !verifyOnly, formatted); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -24,11 +24,11 @@ describe('docs.mts', () => { | ||||
|  | ||||
|       describe('is a code block', () => { | ||||
|         const beforeCodeLine = 'test\n'; | ||||
|         const diagram_text = 'graph\n A --> B\n'; | ||||
|         const diagramText = 'graph\n A --> B\n'; | ||||
|  | ||||
|         describe('language = "mermaid-nocode"', () => { | ||||
|           const lang_keyword = 'mermaid-nocode'; | ||||
|           const contents = beforeCodeLine + '```' + lang_keyword + '\n' + diagram_text + '\n```\n'; | ||||
|           const langKeyword = 'mermaid-nocode'; | ||||
|           const contents = beforeCodeLine + '```' + langKeyword + '\n' + diagramText + '\n```\n'; | ||||
|  | ||||
|           it('changes the language to "mermaid"', async () => { | ||||
|             const result = ( | ||||
| @@ -37,17 +37,16 @@ describe('docs.mts', () => { | ||||
|                 .process(contents) | ||||
|             ).toString(); | ||||
|             expect(result).toEqual( | ||||
|               beforeCodeLine + '\n' + '```' + 'mermaid' + '\n' + diagram_text + '\n```\n' | ||||
|               beforeCodeLine + '\n' + '```' + 'mermaid' + '\n' + diagramText + '\n```\n' | ||||
|             ); | ||||
|           }); | ||||
|         }); | ||||
|  | ||||
|         describe('language = "mermaid" | "mmd" | "mermaid-example"', () => { | ||||
|           const mermaid_keywords = ['mermaid', 'mmd', 'mermaid-example']; | ||||
|           const mermaidKeywords = ['mermaid', 'mmd', 'mermaid-example']; | ||||
|  | ||||
|           mermaid_keywords.forEach((lang_keyword) => { | ||||
|             const contents = | ||||
|               beforeCodeLine + '```' + lang_keyword + '\n' + diagram_text + '\n```\n'; | ||||
|           mermaidKeywords.forEach((langKeyword) => { | ||||
|             const contents = beforeCodeLine + '```' + langKeyword + '\n' + diagramText + '\n```\n'; | ||||
|  | ||||
|             it('changes the language to "mermaid-example" and adds a copy of the code block with language = "mermaid"', async () => { | ||||
|               const result = ( | ||||
| @@ -59,10 +58,10 @@ describe('docs.mts', () => { | ||||
|                 beforeCodeLine + | ||||
|                   '\n' + | ||||
|                   '```mermaid-example\n' + | ||||
|                   diagram_text + | ||||
|                   diagramText + | ||||
|                   '\n```\n' + | ||||
|                   '\n```mermaid\n' + | ||||
|                   diagram_text + | ||||
|                   diagramText + | ||||
|                   '\n```\n' | ||||
|               ); | ||||
|             }); | ||||
| @@ -70,9 +69,9 @@ describe('docs.mts', () => { | ||||
|         }); | ||||
|  | ||||
|         it('calls transformToBlockQuote with the node information', async () => { | ||||
|           const lang_keyword = 'note'; | ||||
|           const langKeyword = 'note'; | ||||
|           const contents = | ||||
|             beforeCodeLine + '```' + lang_keyword + '\n' + 'This is the text\n' + '```\n'; | ||||
|             beforeCodeLine + '```' + langKeyword + '\n' + 'This is the text\n' + '```\n'; | ||||
|  | ||||
|           const result = ( | ||||
|             await remarkBuilder().use(transformMarkdownAst, { originalFilename }).process(contents) | ||||
|   | ||||
							
								
								
									
										8
									
								
								packages/mermaid/scripts/prettier.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								packages/mermaid/scripts/prettier.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| export const prettierConfig = { | ||||
|   endOfLine: 'auto', | ||||
|   printWidth: 100, | ||||
|   singleQuote: true, | ||||
|   useTabs: false, | ||||
|   tabWidth: 2, | ||||
|   trailingComma: 'es5', | ||||
| } as const; | ||||
| @@ -8,32 +8,32 @@ describe('when working with site config', () => { | ||||
|     configApi.setSiteConfig({}); | ||||
|   }); | ||||
|   it('should set site config and config properly', () => { | ||||
|     const config_0 = { fontFamily: 'foo-font', fontSize: 150 }; | ||||
|     configApi.setSiteConfig(config_0); | ||||
|     const config_1 = configApi.getSiteConfig(); | ||||
|     const config_2 = configApi.getConfig(); | ||||
|     expect(config_1.fontFamily).toEqual(config_0.fontFamily); | ||||
|     expect(config_1.fontSize).toEqual(config_0.fontSize); | ||||
|     expect(config_1).toEqual(config_2); | ||||
|     const config0 = { fontFamily: 'foo-font', fontSize: 150 }; | ||||
|     configApi.setSiteConfig(config0); | ||||
|     const config1 = configApi.getSiteConfig(); | ||||
|     const config2 = configApi.getConfig(); | ||||
|     expect(config1.fontFamily).toEqual(config0.fontFamily); | ||||
|     expect(config1.fontSize).toEqual(config0.fontSize); | ||||
|     expect(config1).toEqual(config2); | ||||
|   }); | ||||
|   it('should respect secure keys when applying directives', () => { | ||||
|     const config_0: MermaidConfig = { | ||||
|     const config0: MermaidConfig = { | ||||
|       fontFamily: 'foo-font', | ||||
|       securityLevel: 'strict', // can't be changed | ||||
|       fontSize: 12345, // can't be changed | ||||
|       secure: [...configApi.defaultConfig.secure!, 'fontSize'], | ||||
|     }; | ||||
|     configApi.setSiteConfig(config_0); | ||||
|     configApi.setSiteConfig(config0); | ||||
|     const directive: MermaidConfig = { | ||||
|       fontFamily: 'baf', | ||||
|       // fontSize and securityLevel shouldn't be changed | ||||
|       fontSize: 54321, | ||||
|       securityLevel: 'loose', | ||||
|     }; | ||||
|     const cfg: MermaidConfig = configApi.updateCurrentConfig(config_0, [directive]); | ||||
|     const cfg: MermaidConfig = configApi.updateCurrentConfig(config0, [directive]); | ||||
|     expect(cfg.fontFamily).toEqual(directive.fontFamily); | ||||
|     expect(cfg.fontSize).toBe(config_0.fontSize); | ||||
|     expect(cfg.securityLevel).toBe(config_0.securityLevel); | ||||
|     expect(cfg.fontSize).toBe(config0.fontSize); | ||||
|     expect(cfg.securityLevel).toBe(config0.securityLevel); | ||||
|   }); | ||||
|   it('should allow setting partial options', () => { | ||||
|     const defaultConfig = configApi.getConfig(); | ||||
| @@ -52,30 +52,30 @@ describe('when working with site config', () => { | ||||
|     ); | ||||
|   }); | ||||
|   it('should set reset config properly', () => { | ||||
|     const config_0 = { fontFamily: 'foo-font', fontSize: 150 }; | ||||
|     configApi.setSiteConfig(config_0); | ||||
|     const config_1 = { fontFamily: 'baf' }; | ||||
|     configApi.setConfig(config_1); | ||||
|     const config_2 = configApi.getConfig(); | ||||
|     expect(config_2.fontFamily).toEqual(config_1.fontFamily); | ||||
|     const config0 = { fontFamily: 'foo-font', fontSize: 150 }; | ||||
|     configApi.setSiteConfig(config0); | ||||
|     const config1 = { fontFamily: 'baf' }; | ||||
|     configApi.setConfig(config1); | ||||
|     const config2 = configApi.getConfig(); | ||||
|     expect(config2.fontFamily).toEqual(config1.fontFamily); | ||||
|     configApi.reset(); | ||||
|     const config_3 = configApi.getConfig(); | ||||
|     expect(config_3.fontFamily).toEqual(config_0.fontFamily); | ||||
|     const config_4 = configApi.getSiteConfig(); | ||||
|     expect(config_4.fontFamily).toEqual(config_0.fontFamily); | ||||
|     const config3 = configApi.getConfig(); | ||||
|     expect(config3.fontFamily).toEqual(config0.fontFamily); | ||||
|     const config4 = configApi.getSiteConfig(); | ||||
|     expect(config4.fontFamily).toEqual(config0.fontFamily); | ||||
|   }); | ||||
|   it('should set global reset config properly', () => { | ||||
|     const config_0 = { fontFamily: 'foo-font', fontSize: 150 }; | ||||
|     configApi.setSiteConfig(config_0); | ||||
|     const config_1 = configApi.getSiteConfig(); | ||||
|     expect(config_1.fontFamily).toEqual(config_0.fontFamily); | ||||
|     const config_2 = configApi.getConfig(); | ||||
|     expect(config_2.fontFamily).toEqual(config_0.fontFamily); | ||||
|     const config0 = { fontFamily: 'foo-font', fontSize: 150 }; | ||||
|     configApi.setSiteConfig(config0); | ||||
|     const config1 = configApi.getSiteConfig(); | ||||
|     expect(config1.fontFamily).toEqual(config0.fontFamily); | ||||
|     const config2 = configApi.getConfig(); | ||||
|     expect(config2.fontFamily).toEqual(config0.fontFamily); | ||||
|     configApi.setConfig({ altFontFamily: 'bar-font' }); | ||||
|     const config_3 = configApi.getConfig(); | ||||
|     expect(config_3.altFontFamily).toEqual('bar-font'); | ||||
|     const config3 = configApi.getConfig(); | ||||
|     expect(config3.altFontFamily).toEqual('bar-font'); | ||||
|     configApi.reset(); | ||||
|     const config_4 = configApi.getConfig(); | ||||
|     expect(config_4.altFontFamily).toBeUndefined(); | ||||
|     const config4 = configApi.getConfig(); | ||||
|     expect(config4.altFontFamily).toBeUndefined(); | ||||
|   }); | ||||
| }); | ||||
|   | ||||
| @@ -13,13 +13,13 @@ export default intersectPolygon; | ||||
|  * @param point | ||||
|  */ | ||||
| function intersectPolygon(node, polyPoints, point) { | ||||
|   var x1 = node.x; | ||||
|   var y1 = node.y; | ||||
|   let x1 = node.x; | ||||
|   let y1 = node.y; | ||||
|  | ||||
|   var intersections = []; | ||||
|   let intersections = []; | ||||
|  | ||||
|   var minX = Number.POSITIVE_INFINITY; | ||||
|   var minY = Number.POSITIVE_INFINITY; | ||||
|   let minX = Number.POSITIVE_INFINITY; | ||||
|   let minY = Number.POSITIVE_INFINITY; | ||||
|   if (typeof polyPoints.forEach === 'function') { | ||||
|     polyPoints.forEach(function (entry) { | ||||
|       minX = Math.min(minX, entry.x); | ||||
| @@ -30,13 +30,13 @@ function intersectPolygon(node, polyPoints, point) { | ||||
|     minY = Math.min(minY, polyPoints.y); | ||||
|   } | ||||
|  | ||||
|   var left = x1 - node.width / 2 - minX; | ||||
|   var top = y1 - node.height / 2 - minY; | ||||
|   let left = x1 - node.width / 2 - minX; | ||||
|   let top = y1 - node.height / 2 - minY; | ||||
|  | ||||
|   for (var i = 0; i < polyPoints.length; i++) { | ||||
|     var p1 = polyPoints[i]; | ||||
|     var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0]; | ||||
|     var intersect = intersectLine( | ||||
|   for (let i = 0; i < polyPoints.length; i++) { | ||||
|     let p1 = polyPoints[i]; | ||||
|     let p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0]; | ||||
|     let intersect = intersectLine( | ||||
|       node, | ||||
|       point, | ||||
|       { x: left + p1.x, y: top + p1.y }, | ||||
| @@ -55,13 +55,13 @@ function intersectPolygon(node, polyPoints, point) { | ||||
|   if (intersections.length > 1) { | ||||
|     // More intersections, find the one nearest to edge end point | ||||
|     intersections.sort(function (p, q) { | ||||
|       var pdx = p.x - point.x; | ||||
|       var pdy = p.y - point.y; | ||||
|       var distp = Math.sqrt(pdx * pdx + pdy * pdy); | ||||
|       let pdx = p.x - point.x; | ||||
|       let pdy = p.y - point.y; | ||||
|       let distp = Math.sqrt(pdx * pdx + pdy * pdy); | ||||
|  | ||||
|       var qdx = q.x - point.x; | ||||
|       var qdy = q.y - point.y; | ||||
|       var distq = Math.sqrt(qdx * qdx + qdy * qdy); | ||||
|       let qdx = q.x - point.x; | ||||
|       let qdy = q.y - point.y; | ||||
|       let distq = Math.sqrt(qdx * qdx + qdy * qdy); | ||||
|  | ||||
|       return distp < distq ? -1 : distp === distq ? 0 : 1; | ||||
|     }); | ||||
|   | ||||
| @@ -119,7 +119,7 @@ const hexagon = async (parent, node) => { | ||||
|   return shapeSvg; | ||||
| }; | ||||
|  | ||||
| const block_arrow = async (parent, node) => { | ||||
| const blockArrow = async (parent, node) => { | ||||
|   const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true); | ||||
|  | ||||
|   const f = 2; | ||||
| @@ -140,7 +140,7 @@ const block_arrow = async (parent, node) => { | ||||
|   return shapeSvg; | ||||
| }; | ||||
|  | ||||
| const rect_left_inv_arrow = async (parent, node) => { | ||||
| const rectLeftInvArrow = async (parent, node) => { | ||||
|   const { shapeSvg, bbox } = await labelHelper( | ||||
|     parent, | ||||
|     node, | ||||
| @@ -171,7 +171,7 @@ const rect_left_inv_arrow = async (parent, node) => { | ||||
|   return shapeSvg; | ||||
| }; | ||||
|  | ||||
| const lean_right = async (parent, node) => { | ||||
| const leanRight = async (parent, node) => { | ||||
|   const { shapeSvg, bbox } = await labelHelper(parent, node, getClassesFromNode(node), true); | ||||
|  | ||||
|   const w = bbox.width + node.padding; | ||||
| @@ -194,7 +194,7 @@ const lean_right = async (parent, node) => { | ||||
|   return shapeSvg; | ||||
| }; | ||||
|  | ||||
| const lean_left = async (parent, node) => { | ||||
| const leanLeft = async (parent, node) => { | ||||
|   const { shapeSvg, bbox } = await labelHelper( | ||||
|     parent, | ||||
|     node, | ||||
| @@ -250,7 +250,7 @@ const trapezoid = async (parent, node) => { | ||||
|   return shapeSvg; | ||||
| }; | ||||
|  | ||||
| const inv_trapezoid = async (parent, node) => { | ||||
| const invTrapezoid = async (parent, node) => { | ||||
|   const { shapeSvg, bbox } = await labelHelper( | ||||
|     parent, | ||||
|     node, | ||||
| @@ -278,7 +278,7 @@ const inv_trapezoid = async (parent, node) => { | ||||
|   return shapeSvg; | ||||
| }; | ||||
|  | ||||
| const rect_right_inv_arrow = async (parent, node) => { | ||||
| const rectRightInvArrow = async (parent, node) => { | ||||
|   const { shapeSvg, bbox } = await labelHelper( | ||||
|     parent, | ||||
|     node, | ||||
| @@ -875,7 +875,7 @@ const end = (parent, node) => { | ||||
|   return shapeSvg; | ||||
| }; | ||||
|  | ||||
| const class_box = (parent, node) => { | ||||
| const classBox = (parent, node) => { | ||||
|   const halfPadding = node.padding / 2; | ||||
|   const rowPadding = 4; | ||||
|   const lineHeight = 8; | ||||
| @@ -1111,13 +1111,13 @@ const shapes = { | ||||
|   doublecircle, | ||||
|   stadium, | ||||
|   hexagon, | ||||
|   block_arrow, | ||||
|   rect_left_inv_arrow, | ||||
|   lean_right, | ||||
|   lean_left, | ||||
|   block_arrow: blockArrow, | ||||
|   rect_left_inv_arrow: rectLeftInvArrow, | ||||
|   lean_right: leanRight, | ||||
|   lean_left: leanLeft, | ||||
|   trapezoid, | ||||
|   inv_trapezoid, | ||||
|   rect_right_inv_arrow, | ||||
|   inv_trapezoid: invTrapezoid, | ||||
|   rect_right_inv_arrow: rectRightInvArrow, | ||||
|   cylinder, | ||||
|   start, | ||||
|   end, | ||||
| @@ -1125,7 +1125,7 @@ const shapes = { | ||||
|   subroutine, | ||||
|   fork: forkJoin, | ||||
|   join: forkJoin, | ||||
|   class_box, | ||||
|   class_box: classBox, | ||||
| }; | ||||
|  | ||||
| let nodeElems = {}; | ||||
|   | ||||
| @@ -70,8 +70,9 @@ describe('diagram detection', () => { | ||||
|       --------------^ | ||||
|       Expecting 'AMP', 'COLON', 'PIPE', 'TESTSTR', 'DOWN', 'DEFAULT', 'NUM', 'COMMA', 'NODE_STRING', 'BRKT', 'MINUS', 'MULT', 'UNICODE_TEXT', got 'EOF'] | ||||
|     `); | ||||
|     await expect(Diagram.fromText('sequenceDiagram; A-->B')).rejects | ||||
|       .toThrowErrorMatchingInlineSnapshot(` | ||||
|     await expect( | ||||
|       Diagram.fromText('sequenceDiagram; A-->B') | ||||
|     ).rejects.toThrowErrorMatchingInlineSnapshot(` | ||||
|       [Error: Parse error on line 1: | ||||
|       ...quenceDiagram; A-->B | ||||
|       -----------------------^ | ||||
|   | ||||
| @@ -78,28 +78,28 @@ export const drawEdge = function (elem, path, relation, conf, diagObj) { | ||||
|   x = labelPosition.x; | ||||
|   y = labelPosition.y; | ||||
|  | ||||
|   let p1_card_x, p1_card_y; | ||||
|   let p2_card_x, p2_card_y; | ||||
|   let p1CardX, p1CardY; | ||||
|   let p2CardX, p2CardY; | ||||
|  | ||||
|   if (l % 2 !== 0 && l > 1) { | ||||
|     let cardinality_1_point = utils.calcCardinalityPosition( | ||||
|     let cardinality1Point = utils.calcCardinalityPosition( | ||||
|       relation.relation.type1 !== 'none', | ||||
|       path.points, | ||||
|       path.points[0] | ||||
|     ); | ||||
|     let cardinality_2_point = utils.calcCardinalityPosition( | ||||
|     let cardinality2Point = utils.calcCardinalityPosition( | ||||
|       relation.relation.type2 !== 'none', | ||||
|       path.points, | ||||
|       path.points[l - 1] | ||||
|     ); | ||||
|  | ||||
|     log.debug('cardinality_1_point ' + JSON.stringify(cardinality_1_point)); | ||||
|     log.debug('cardinality_2_point ' + JSON.stringify(cardinality_2_point)); | ||||
|     log.debug('cardinality_1_point ' + JSON.stringify(cardinality1Point)); | ||||
|     log.debug('cardinality_2_point ' + JSON.stringify(cardinality2Point)); | ||||
|  | ||||
|     p1_card_x = cardinality_1_point.x; | ||||
|     p1_card_y = cardinality_1_point.y; | ||||
|     p2_card_x = cardinality_2_point.x; | ||||
|     p2_card_y = cardinality_2_point.y; | ||||
|     p1CardX = cardinality1Point.x; | ||||
|     p1CardY = cardinality1Point.y; | ||||
|     p2CardX = cardinality2Point.x; | ||||
|     p2CardY = cardinality2Point.y; | ||||
|   } | ||||
|  | ||||
|   if (relation.title !== undefined) { | ||||
| @@ -129,8 +129,8 @@ export const drawEdge = function (elem, path, relation, conf, diagObj) { | ||||
|     const g = elem.append('g').attr('class', 'cardinality'); | ||||
|     g.append('text') | ||||
|       .attr('class', 'type1') | ||||
|       .attr('x', p1_card_x) | ||||
|       .attr('y', p1_card_y) | ||||
|       .attr('x', p1CardX) | ||||
|       .attr('y', p1CardY) | ||||
|       .attr('fill', 'black') | ||||
|       .attr('font-size', '6') | ||||
|       .text(relation.relationTitle1); | ||||
| @@ -139,8 +139,8 @@ export const drawEdge = function (elem, path, relation, conf, diagObj) { | ||||
|     const g = elem.append('g').attr('class', 'cardinality'); | ||||
|     g.append('text') | ||||
|       .attr('class', 'type2') | ||||
|       .attr('x', p2_card_x) | ||||
|       .attr('y', p2_card_y) | ||||
|       .attr('x', p2CardX) | ||||
|       .attr('y', p2CardY) | ||||
|       .attr('fill', 'black') | ||||
|       .attr('font-size', '6') | ||||
|       .text(relation.relationTitle2); | ||||
|   | ||||
| @@ -30,18 +30,18 @@ const setupDompurifyHooksIfNotSetup = (() => { | ||||
| })(); | ||||
|  | ||||
| function setupDompurifyHooks() { | ||||
|   const TEMPORARY_ATTRIBUTE = 'data-temp-href-target'; | ||||
|   const temporaryAttribute = 'data-temp-href-target'; | ||||
|  | ||||
|   DOMPurify.addHook('beforeSanitizeAttributes', (node: Element) => { | ||||
|     if (node.tagName === 'A' && node.hasAttribute('target')) { | ||||
|       node.setAttribute(TEMPORARY_ATTRIBUTE, node.getAttribute('target') || ''); | ||||
|       node.setAttribute(temporaryAttribute, node.getAttribute('target') || ''); | ||||
|     } | ||||
|   }); | ||||
|  | ||||
|   DOMPurify.addHook('afterSanitizeAttributes', (node: Element) => { | ||||
|     if (node.tagName === 'A' && node.hasAttribute(TEMPORARY_ATTRIBUTE)) { | ||||
|       node.setAttribute('target', node.getAttribute(TEMPORARY_ATTRIBUTE) || ''); | ||||
|       node.removeAttribute(TEMPORARY_ATTRIBUTE); | ||||
|     if (node.tagName === 'A' && node.hasAttribute(temporaryAttribute)) { | ||||
|       node.setAttribute('target', node.getAttribute(temporaryAttribute) || ''); | ||||
|       node.removeAttribute(temporaryAttribute); | ||||
|       if (node.getAttribute('target') === '_blank') { | ||||
|         node.setAttribute('rel', 'noopener'); | ||||
|       } | ||||
|   | ||||
| @@ -53,7 +53,7 @@ function hexagon(parent, bbox, node) { | ||||
|  * @param bbox | ||||
|  * @param node | ||||
|  */ | ||||
| function rect_left_inv_arrow(parent, bbox, node) { | ||||
| function rectLeftInvArrow(parent, bbox, node) { | ||||
|   const w = bbox.width; | ||||
|   const h = bbox.height; | ||||
|   const points = [ | ||||
| @@ -75,7 +75,7 @@ function rect_left_inv_arrow(parent, bbox, node) { | ||||
|  * @param bbox | ||||
|  * @param node | ||||
|  */ | ||||
| function lean_right(parent, bbox, node) { | ||||
| function leanRight(parent, bbox, node) { | ||||
|   const w = bbox.width; | ||||
|   const h = bbox.height; | ||||
|   const points = [ | ||||
| @@ -96,7 +96,7 @@ function lean_right(parent, bbox, node) { | ||||
|  * @param bbox | ||||
|  * @param node | ||||
|  */ | ||||
| function lean_left(parent, bbox, node) { | ||||
| function leanLeft(parent, bbox, node) { | ||||
|   const w = bbox.width; | ||||
|   const h = bbox.height; | ||||
|   const points = [ | ||||
| @@ -138,7 +138,7 @@ function trapezoid(parent, bbox, node) { | ||||
|  * @param bbox | ||||
|  * @param node | ||||
|  */ | ||||
| function inv_trapezoid(parent, bbox, node) { | ||||
| function invTrapezoid(parent, bbox, node) { | ||||
|   const w = bbox.width; | ||||
|   const h = bbox.height; | ||||
|   const points = [ | ||||
| @@ -159,7 +159,7 @@ function inv_trapezoid(parent, bbox, node) { | ||||
|  * @param bbox | ||||
|  * @param node | ||||
|  */ | ||||
| function rect_right_inv_arrow(parent, bbox, node) { | ||||
| function rectRightInvArrow(parent, bbox, node) { | ||||
|   const w = bbox.width; | ||||
|   const h = bbox.height; | ||||
|   const points = [ | ||||
| @@ -308,22 +308,22 @@ export function addToRender(render) { | ||||
|   render.shapes().cylinder = cylinder; | ||||
|  | ||||
|   // Add custom shape for box with inverted arrow on left side | ||||
|   render.shapes().rect_left_inv_arrow = rect_left_inv_arrow; | ||||
|   render.shapes().rect_left_inv_arrow = rectLeftInvArrow; | ||||
|  | ||||
|   // Add custom shape for box with inverted arrow on left side | ||||
|   render.shapes().lean_right = lean_right; | ||||
|   render.shapes().lean_right = leanRight; | ||||
|  | ||||
|   // Add custom shape for box with inverted arrow on left side | ||||
|   render.shapes().lean_left = lean_left; | ||||
|   render.shapes().lean_left = leanLeft; | ||||
|  | ||||
|   // Add custom shape for box with inverted arrow on left side | ||||
|   render.shapes().trapezoid = trapezoid; | ||||
|  | ||||
|   // Add custom shape for box with inverted arrow on left side | ||||
|   render.shapes().inv_trapezoid = inv_trapezoid; | ||||
|   render.shapes().inv_trapezoid = invTrapezoid; | ||||
|  | ||||
|   // Add custom shape for box with inverted arrow on right side | ||||
|   render.shapes().rect_right_inv_arrow = rect_right_inv_arrow; | ||||
|   render.shapes().rect_right_inv_arrow = rectRightInvArrow; | ||||
| } | ||||
|  | ||||
| /** @param addShape */ | ||||
| @@ -335,22 +335,22 @@ export function addToRenderV2(addShape) { | ||||
|   addShape({ cylinder }); | ||||
|  | ||||
|   // Add custom shape for box with inverted arrow on left side | ||||
|   addShape({ rect_left_inv_arrow }); | ||||
|   addShape({ rect_left_inv_arrow: rectLeftInvArrow }); | ||||
|  | ||||
|   // Add custom shape for box with inverted arrow on left side | ||||
|   addShape({ lean_right }); | ||||
|   addShape({ lean_right: leanRight }); | ||||
|  | ||||
|   // Add custom shape for box with inverted arrow on left side | ||||
|   addShape({ lean_left }); | ||||
|   addShape({ lean_left: leanLeft }); | ||||
|  | ||||
|   // Add custom shape for box with inverted arrow on left side | ||||
|   addShape({ trapezoid }); | ||||
|  | ||||
|   // Add custom shape for box with inverted arrow on left side | ||||
|   addShape({ inv_trapezoid }); | ||||
|   addShape({ inv_trapezoid: invTrapezoid }); | ||||
|  | ||||
|   // Add custom shape for box with inverted arrow on right side | ||||
|   addShape({ rect_right_inv_arrow }); | ||||
|   addShape({ rect_right_inv_arrow: rectRightInvArrow }); | ||||
| } | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -246,16 +246,19 @@ export const addEdges = async function (edges, g, diagObj) { | ||||
|  | ||||
|     /* eslint-disable no-fallthrough */ | ||||
|     switch (edge.type) { | ||||
|       // biome-ignore lint/suspicious/noFallthroughSwitchClause: <explanation> | ||||
|       case 'double_arrow_cross': | ||||
|         edgeData.arrowTypeStart = 'arrow_cross'; | ||||
|       case 'arrow_cross': | ||||
|         edgeData.arrowTypeEnd = 'arrow_cross'; | ||||
|         break; | ||||
|       // biome-ignore lint/suspicious/noFallthroughSwitchClause: <explanation> | ||||
|       case 'double_arrow_point': | ||||
|         edgeData.arrowTypeStart = 'arrow_point'; | ||||
|       case 'arrow_point': | ||||
|         edgeData.arrowTypeEnd = 'arrow_point'; | ||||
|         break; | ||||
|       // biome-ignore lint/suspicious/noFallthroughSwitchClause: <explanation> | ||||
|       case 'double_arrow_circle': | ||||
|         edgeData.arrowTypeStart = 'arrow_circle'; | ||||
|       case 'arrow_circle': | ||||
| @@ -425,9 +428,9 @@ export const draw = async function (text, id, _version, diagObj) { | ||||
|  | ||||
|     selectAll('cluster').append('text'); | ||||
|  | ||||
|     for (let j = 0; j < subG.nodes.length; j++) { | ||||
|       log.info('Setting up subgraphs', subG.nodes[j], subG.id); | ||||
|       g.setParent(subG.nodes[j], subG.id); | ||||
|     for (const node of subG.nodes) { | ||||
|       log.info('Setting up subgraphs', node, subG.id); | ||||
|       g.setParent(node, subG.id); | ||||
|     } | ||||
|   } | ||||
|   await addVertices(vert, g, id, root, doc, diagObj); | ||||
|   | ||||
| @@ -339,14 +339,14 @@ export const draw = async function (text, id, _version, diagObj) { | ||||
|  | ||||
|     selectAll('cluster').append('text'); | ||||
|  | ||||
|     for (let j = 0; j < subG.nodes.length; j++) { | ||||
|     for (const subGNode of subG.nodes) { | ||||
|       log.warn( | ||||
|         'Setting subgraph', | ||||
|         subG.nodes[j], | ||||
|         diagObj.db.lookUpDomId(subG.nodes[j]), | ||||
|         subGNode, | ||||
|         diagObj.db.lookUpDomId(subGNode), | ||||
|         diagObj.db.lookUpDomId(subG.id) | ||||
|       ); | ||||
|       g.setParent(diagObj.db.lookUpDomId(subG.nodes[j]), diagObj.db.lookUpDomId(subG.id)); | ||||
|       g.setParent(diagObj.db.lookUpDomId(subGNode), diagObj.db.lookUpDomId(subG.id)); | ||||
|     } | ||||
|   } | ||||
|   await addVertices(vert, g, id, root, doc, diagObj); | ||||
| @@ -429,8 +429,8 @@ export const draw = async function (text, id, _version, diagObj) { | ||||
|       te.attr('transform', `translate(${xPos + _width / 2}, ${yPos + 14})`); | ||||
|       te.attr('id', id + 'Text'); | ||||
|  | ||||
|       for (let j = 0; j < subG.classes.length; j++) { | ||||
|         clusterEl[0].classList.add(subG.classes[j]); | ||||
|       for (const subGClass of subG.classes) { | ||||
|         clusterEl[0].classList.add(subGClass); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   | ||||
| @@ -591,7 +591,7 @@ describe('[Text] when parsing', () => { | ||||
|  | ||||
|   it('should throw error for escaping quotes in text state', function () { | ||||
|     //prettier-ignore | ||||
|     const str = 'graph TD; A[This is a \"()\" in text];'; //eslint-disable-line no-useless-escape | ||||
|     const str = 'graph TD; A[This is a "()" in text];'; //eslint-disable-line no-useless-escape | ||||
|  | ||||
|     expect(() => flow.parser.parse(str)).toThrowError("got 'STR'"); | ||||
|   }); | ||||
|   | ||||
| @@ -724,6 +724,7 @@ export const draw = function (text, id, version, diagObj) { | ||||
|       .attr('x', 10) | ||||
|       .attr('y', function (d, i) { | ||||
|         if (i > 0) { | ||||
|           // biome-ignore lint/correctness/noUnreachable: <explanation> | ||||
|           for (let j = 0; j < i; j++) { | ||||
|             prevGap += numOccurrences[i - 1][1]; | ||||
|             return (d[1] * theGap) / 2 + prevGap * theGap + theTopPad; | ||||
|   | ||||
| @@ -157,30 +157,40 @@ describe('when parsing a gantt diagram it', function () { | ||||
|     ${'crit'}                | ${false}  | ${false} | ${true}  | ${false} | ||||
|     ${'active'}              | ${false}  | ${false} | ${false} | ${true} | ||||
|     ${'crit,milestone,done'} | ${true}   | ${true}  | ${true}  | ${false} | ||||
|   `)('should handle a task with tags $tags', ({ tags, milestone, done, crit, active }) => { | ||||
|     const str = | ||||
|       'gantt\n' + | ||||
|       'dateFormat YYYY-MM-DD\n' + | ||||
|       'title Adding gantt diagram functionality to mermaid\n' + | ||||
|       'section Documentation\n' + | ||||
|       'test task:' + | ||||
|       tags + | ||||
|       ', 2014-01-01, 2014-01-04'; | ||||
|   `)( | ||||
|     'should handle a task with tags $tags', | ||||
|     ({ | ||||
|       tags, | ||||
|       // Do not remove, these are used in eval. | ||||
|       milestone, | ||||
|       done, | ||||
|       crit, | ||||
|       active, | ||||
|     }) => { | ||||
|       const str = | ||||
|         'gantt\n' + | ||||
|         'dateFormat YYYY-MM-DD\n' + | ||||
|         'title Adding gantt diagram functionality to mermaid\n' + | ||||
|         'section Documentation\n' + | ||||
|         'test task:' + | ||||
|         tags + | ||||
|         ', 2014-01-01, 2014-01-04'; | ||||
|  | ||||
|     const allowedTags = ['active', 'done', 'crit', 'milestone']; | ||||
|       const allowedTags = ['active', 'done', 'crit', 'milestone']; | ||||
|  | ||||
|     expect(parserFnConstructor(str)).not.toThrow(); | ||||
|       expect(parserFnConstructor(str)).not.toThrow(); | ||||
|  | ||||
|     const tasks = parser.yy.getTasks(); | ||||
|       const tasks = parser.yy.getTasks(); | ||||
|  | ||||
|     allowedTags.forEach(function (t) { | ||||
|       if (eval(t)) { | ||||
|         expect(tasks[0][t]).toBeTruthy(); | ||||
|       } else { | ||||
|         expect(tasks[0][t]).toBeFalsy(); | ||||
|       } | ||||
|     }); | ||||
|   }); | ||||
|       allowedTags.forEach(function (t) { | ||||
|         if (eval(t)) { | ||||
|           expect(tasks[0][t]).toBeTruthy(); | ||||
|         } else { | ||||
|           expect(tasks[0][t]).toBeFalsy(); | ||||
|         } | ||||
|       }); | ||||
|     } | ||||
|   ); | ||||
|   it('should parse callback specifier with no args', function () { | ||||
|     spyOn(ganttDb, 'setClickEvent'); | ||||
|     const str = | ||||
| @@ -207,7 +217,6 @@ describe('when parsing a gantt diagram it', function () { | ||||
|       'click cl2 call ganttTestClick("test0", test1, test2)\n'; | ||||
|  | ||||
|     expect(parserFnConstructor(str)).not.toThrow(); | ||||
|     const args = '"test1", "test2", "test3"'; | ||||
|     expect(ganttDb.setClickEvent).toHaveBeenCalledWith( | ||||
|       'cl2', | ||||
|       'ganttTestClick', | ||||
|   | ||||
| @@ -147,9 +147,9 @@ export const branch = function (name, order) { | ||||
|   } | ||||
| }; | ||||
|  | ||||
| export const merge = function (otherBranch, custom_id, override_type, custom_tag) { | ||||
| export const merge = function (otherBranch, customId, overrideType, customTag) { | ||||
|   otherBranch = common.sanitizeText(otherBranch, getConfig()); | ||||
|   custom_id = common.sanitizeText(custom_id, getConfig()); | ||||
|   customId = common.sanitizeText(customId, getConfig()); | ||||
|  | ||||
|   const currentCommit = commits.get(branches.get(curBranch)); | ||||
|   const otherCommit = commits.get(branches.get(otherBranch)); | ||||
| @@ -209,19 +209,19 @@ export const merge = function (otherBranch, custom_id, override_type, custom_tag | ||||
|       expected: ['branch abc'], | ||||
|     }; | ||||
|     throw error; | ||||
|   } else if (custom_id && commits.has(custom_id)) { | ||||
|   } else if (customId && commits.has(customId)) { | ||||
|     let error = new Error( | ||||
|       'Incorrect usage of "merge". Commit with id:' + | ||||
|         custom_id + | ||||
|         customId + | ||||
|         ' already exists, use different custom Id' | ||||
|     ); | ||||
|     error.hash = { | ||||
|       text: 'merge ' + otherBranch + custom_id + override_type + custom_tag, | ||||
|       token: 'merge ' + otherBranch + custom_id + override_type + custom_tag, | ||||
|       text: 'merge ' + otherBranch + customId + overrideType + customTag, | ||||
|       token: 'merge ' + otherBranch + customId + overrideType + customTag, | ||||
|       line: '1', | ||||
|       loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, | ||||
|       expected: [ | ||||
|         'merge ' + otherBranch + ' ' + custom_id + '_UNIQUE ' + override_type + ' ' + custom_tag, | ||||
|         'merge ' + otherBranch + ' ' + customId + '_UNIQUE ' + overrideType + ' ' + customTag, | ||||
|       ], | ||||
|     }; | ||||
|  | ||||
| @@ -237,15 +237,15 @@ export const merge = function (otherBranch, custom_id, override_type, custom_tag | ||||
|   // } else { | ||||
|   // create merge commit | ||||
|   const commit = { | ||||
|     id: custom_id ? custom_id : seq + '-' + getId(), | ||||
|     id: customId ? customId : seq + '-' + getId(), | ||||
|     message: 'merged branch ' + otherBranch + ' into ' + curBranch, | ||||
|     seq: seq++, | ||||
|     parents: [head == null ? null : head.id, branches.get(otherBranch)], | ||||
|     branch: curBranch, | ||||
|     type: commitType.MERGE, | ||||
|     customType: override_type, | ||||
|     customId: custom_id ? true : false, | ||||
|     tag: custom_tag ? custom_tag : '', | ||||
|     customType: overrideType, | ||||
|     customId: customId ? true : false, | ||||
|     tag: customTag ? customTag : '', | ||||
|   }; | ||||
|   head = commit; | ||||
|   commits.set(commit.id, commit); | ||||
|   | ||||
| @@ -405,11 +405,11 @@ const drawCommits = (svg, commits, modifyGraph) => { | ||||
|             text.attr('transform', 'rotate(' + -45 + ', ' + x + ', ' + y + ')'); | ||||
|             labelBkg.attr('transform', 'rotate(' + -45 + ', ' + x + ', ' + y + ')'); | ||||
|           } else { | ||||
|             let r_x = -7.5 - ((bbox.width + 10) / 25) * 9.5; | ||||
|             let r_y = 10 + (bbox.width / 25) * 8.5; | ||||
|             let rX = -7.5 - ((bbox.width + 10) / 25) * 9.5; | ||||
|             let rY = 10 + (bbox.width / 25) * 8.5; | ||||
|             wrapper.attr( | ||||
|               'transform', | ||||
|               'translate(' + r_x + ', ' + r_y + ') rotate(' + -45 + ', ' + pos + ', ' + y + ')' | ||||
|               'translate(' + rX + ', ' + rY + ') rotate(' + -45 + ', ' + pos + ', ' + y + ')' | ||||
|             ); | ||||
|           } | ||||
|         } | ||||
|   | ||||
| @@ -40,9 +40,9 @@ export const draw: DrawDefinition = (text, id, _version, diagObj) => { | ||||
|   const db = diagObj.db as PieDB; | ||||
|   const globalConfig: MermaidConfig = getConfig(); | ||||
|   const pieConfig: Required<PieDiagramConfig> = cleanAndMerge(db.getConfig(), globalConfig.pie); | ||||
|   const MARGIN = 40; | ||||
|   const LEGEND_RECT_SIZE = 18; | ||||
|   const LEGEND_SPACING = 4; | ||||
|   const margin = 40; | ||||
|   const legendRectSize = 18; | ||||
|   const legendSpacing = 4; | ||||
|   const height = 450; | ||||
|   const pieWidth: number = height; | ||||
|   const svg: SVG = selectSvgElement(id); | ||||
| @@ -54,7 +54,7 @@ export const draw: DrawDefinition = (text, id, _version, diagObj) => { | ||||
|   outerStrokeWidth ??= 2; | ||||
|  | ||||
|   const textPosition: number = pieConfig.textPosition; | ||||
|   const radius: number = Math.min(pieWidth, height) / 2 - MARGIN; | ||||
|   const radius: number = Math.min(pieWidth, height) / 2 - margin; | ||||
|   // Shape helper to build arcs: | ||||
|   const arcGenerator: d3.Arc<unknown, d3.PieArcDatum<D3Section>> = arc<d3.PieArcDatum<D3Section>>() | ||||
|     .innerRadius(0) | ||||
| @@ -139,25 +139,25 @@ export const draw: DrawDefinition = (text, id, _version, diagObj) => { | ||||
|     .append('g') | ||||
|     .attr('class', 'legend') | ||||
|     .attr('transform', (_datum, index: number): string => { | ||||
|       const height = LEGEND_RECT_SIZE + LEGEND_SPACING; | ||||
|       const height = legendRectSize + legendSpacing; | ||||
|       const offset = (height * color.domain().length) / 2; | ||||
|       const horizontal = 12 * LEGEND_RECT_SIZE; | ||||
|       const horizontal = 12 * legendRectSize; | ||||
|       const vertical = index * height - offset; | ||||
|       return 'translate(' + horizontal + ',' + vertical + ')'; | ||||
|     }); | ||||
|  | ||||
|   legend | ||||
|     .append('rect') | ||||
|     .attr('width', LEGEND_RECT_SIZE) | ||||
|     .attr('height', LEGEND_RECT_SIZE) | ||||
|     .attr('width', legendRectSize) | ||||
|     .attr('height', legendRectSize) | ||||
|     .style('fill', color) | ||||
|     .style('stroke', color); | ||||
|  | ||||
|   legend | ||||
|     .data(arcs) | ||||
|     .append('text') | ||||
|     .attr('x', LEGEND_RECT_SIZE + LEGEND_SPACING) | ||||
|     .attr('y', LEGEND_RECT_SIZE - LEGEND_SPACING) | ||||
|     .attr('x', legendRectSize + legendSpacing) | ||||
|     .attr('y', legendRectSize - legendSpacing) | ||||
|     .text((datum: d3.PieArcDatum<D3Section>): string => { | ||||
|       const { label, value } = datum.data; | ||||
|       if (db.getShowData()) { | ||||
| @@ -173,7 +173,7 @@ export const draw: DrawDefinition = (text, id, _version, diagObj) => { | ||||
|       .map((node) => (node as Element)?.getBoundingClientRect().width ?? 0) | ||||
|   ); | ||||
|  | ||||
|   const totalWidth = pieWidth + MARGIN + LEGEND_RECT_SIZE + LEGEND_SPACING + longestTextWidth; | ||||
|   const totalWidth = pieWidth + margin + legendRectSize + legendSpacing + longestTextWidth; | ||||
|  | ||||
|   // Set viewBox | ||||
|   svg.attr('viewBox', `0 0 ${totalWidth} ${height}`); | ||||
|   | ||||
| @@ -45,13 +45,13 @@ class SankeyNode { | ||||
|   constructor(public ID: string) {} | ||||
| } | ||||
|  | ||||
| const findOrCreateNode = (ID: string): SankeyNode => { | ||||
|   ID = common.sanitizeText(ID, getConfig()); | ||||
| const findOrCreateNode = (id: string): SankeyNode => { | ||||
|   id = common.sanitizeText(id, getConfig()); | ||||
|  | ||||
|   let node = nodesMap.get(ID); | ||||
|   let node = nodesMap.get(id); | ||||
|   if (node === undefined) { | ||||
|     node = new SankeyNode(ID); | ||||
|     nodesMap.set(ID, node); | ||||
|     node = new SankeyNode(id); | ||||
|     nodesMap.set(id, node); | ||||
|     nodes.push(node); | ||||
|   } | ||||
|   return node; | ||||
|   | ||||
| @@ -49,11 +49,11 @@ export const drawPopup = function (elem, actor, minMenuWidth, textAttrs, forceMe | ||||
|   rectElem.attr('height', rectData.height); | ||||
|   rectElem.attr('rx', rectData.rx); | ||||
|   rectElem.attr('ry', rectData.ry); | ||||
|   let linkY = 20; | ||||
|   if (links != null) { | ||||
|     var linkY = 20; | ||||
|     for (let key in links) { | ||||
|       var linkElem = g.append('a'); | ||||
|       var sanitizedLink = sanitizeUrl(links[key]); | ||||
|       const linkElem = g.append('a'); | ||||
|       const sanitizedLink = sanitizeUrl(links[key]); | ||||
|       linkElem.attr('xlink:href', sanitizedLink); | ||||
|       linkElem.attr('target', '_blank'); | ||||
|  | ||||
|   | ||||
| @@ -88,9 +88,9 @@ describe('ClassDefs and classes when parsing a State diagram', () => { | ||||
|         expect(classes.get('exampleStyleClass').styles[0]).toEqual('background:#bbb'); | ||||
|         expect(classes.get('exampleStyleClass').styles[1]).toEqual('border:1px solid red'); | ||||
|  | ||||
|         const state_a = stateDb.getState('a'); | ||||
|         expect(state_a.classes.length).toEqual(1); | ||||
|         expect(state_a.classes[0]).toEqual('exampleStyleClass'); | ||||
|         const stateA = stateDb.getState('a'); | ||||
|         expect(stateA.classes.length).toEqual(1); | ||||
|         expect(stateA.classes[0]).toEqual('exampleStyleClass'); | ||||
|       }); | ||||
|  | ||||
|       it('can be applied to a state with an id containing _', function () { | ||||
| @@ -109,9 +109,9 @@ describe('ClassDefs and classes when parsing a State diagram', () => { | ||||
|         expect(classes.get('exampleStyleClass').styles[0]).toBe('background:#bbb'); | ||||
|         expect(classes.get('exampleStyleClass').styles[1]).toBe('border:1px solid red'); | ||||
|  | ||||
|         const state_a_a = stateDiagram.parser.yy.getState('a_a'); | ||||
|         expect(state_a_a.classes.length).toEqual(1); | ||||
|         expect(state_a_a.classes[0]).toEqual('exampleStyleClass'); | ||||
|         const stateAA = stateDiagram.parser.yy.getState('a_a'); | ||||
|         expect(stateAA.classes.length).toEqual(1); | ||||
|         expect(stateAA.classes[0]).toEqual('exampleStyleClass'); | ||||
|       }); | ||||
|  | ||||
|       describe('::: syntax', () => { | ||||
|   | ||||
| @@ -130,12 +130,12 @@ describe('state diagram V2, ', function () { | ||||
|         stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2()); | ||||
|  | ||||
|         const rels = stateDb.getRelations(); | ||||
|         const rel_1_2 = rels.find((rel) => rel.id1 === 'State1' && rel.id2 === 'State2'); | ||||
|         expect(rel_1_2.relationTitle).toEqual('Transition 1'); | ||||
|         const rel_1_3 = rels.find((rel) => rel.id1 === 'State1' && rel.id2 === 'State3'); | ||||
|         expect(rel_1_3.relationTitle).toEqual('Transition 2'); | ||||
|         const rel_1_4 = rels.find((rel) => rel.id1 === 'State1' && rel.id2 === 'State4'); | ||||
|         expect(rel_1_4.relationTitle).toEqual('Transition 3'); | ||||
|         const rel12 = rels.find((rel) => rel.id1 === 'State1' && rel.id2 === 'State2'); | ||||
|         expect(rel12.relationTitle).toEqual('Transition 1'); | ||||
|         const rel13 = rels.find((rel) => rel.id1 === 'State1' && rel.id2 === 'State3'); | ||||
|         expect(rel13.relationTitle).toEqual('Transition 2'); | ||||
|         const rel14 = rels.find((rel) => rel.id1 === 'State1' && rel.id2 === 'State4'); | ||||
|         expect(rel14.relationTitle).toEqual('Transition 3'); | ||||
|       }); | ||||
|     }); | ||||
|  | ||||
| @@ -408,10 +408,10 @@ describe('state diagram V2, ', function () { | ||||
|       expect(states.get('Active').doc[0].id).toEqual('Idle'); | ||||
|  | ||||
|       const rels = stateDb.getRelations(); | ||||
|       const rel_Inactive_Idle = rels.find((rel) => rel.id1 === 'Inactive' && rel.id2 === 'Idle'); | ||||
|       expect(rel_Inactive_Idle.relationTitle).toEqual('ACT'); | ||||
|       const rel_Active_Active = rels.find((rel) => rel.id1 === 'Active' && rel.id2 === 'Active'); | ||||
|       expect(rel_Active_Active.relationTitle).toEqual('LOG'); | ||||
|       const relInactiveIdle = rels.find((rel) => rel.id1 === 'Inactive' && rel.id2 === 'Idle'); | ||||
|       expect(relInactiveIdle.relationTitle).toEqual('ACT'); | ||||
|       const relActiveActive = rels.find((rel) => rel.id1 === 'Active' && rel.id2 === 'Active'); | ||||
|       expect(relActiveActive.relationTitle).toEqual('LOG'); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
|   | ||||
| @@ -362,8 +362,7 @@ const setupDoc = (g, parentParsedItem, doc, diagramStates, diagramDb, altFlag) = | ||||
| const getDir = (parsedItem, defaultDir = DEFAULT_NESTED_DOC_DIR) => { | ||||
|   let dir = defaultDir; | ||||
|   if (parsedItem.doc) { | ||||
|     for (let i = 0; i < parsedItem.doc.length; i++) { | ||||
|       const parsedItemDoc = parsedItem.doc[i]; | ||||
|     for (const parsedItemDoc of parsedItem.doc) { | ||||
|       if (parsedItemDoc.stmt === 'dir') { | ||||
|         dir = parsedItemDoc.value; | ||||
|       } | ||||
|   | ||||
| @@ -15,9 +15,7 @@ const genSections = (options) => { | ||||
|   for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) { | ||||
|     const sw = '' + (17 - 3 * i); | ||||
|     sections += ` | ||||
|     .section-${i - 1} rect, .section-${i - 1} path, .section-${i - 1} circle, .section-${ | ||||
|       i - 1 | ||||
|     } path  { | ||||
|     .section-${i - 1} rect, .section-${i - 1} path, .section-${i - 1} circle, .section-${i - 1} path  { | ||||
|       fill: ${options['cScale' + i]}; | ||||
|     } | ||||
|     .section-${i - 1} text { | ||||
|   | ||||
| @@ -29,7 +29,7 @@ export const draw = function (text: string, id: string, version: string, diagObj | ||||
|   //1. Fetch the configuration | ||||
|   const conf = getConfig(); | ||||
|   // @ts-expect-error - wrong config? | ||||
|   const LEFT_MARGIN = conf.leftMargin ?? 50; | ||||
|   const leftMargin = conf.leftMargin ?? 50; | ||||
|  | ||||
|   log.debug('timeline', diagObj.db); | ||||
|  | ||||
| @@ -68,7 +68,7 @@ export const draw = function (text: string, id: string, version: string, diagObj | ||||
|   //let sectionBeginX = 0; | ||||
|   let depthY = 0; | ||||
|   let sectionBeginY = 0; | ||||
|   let masterX = 50 + LEFT_MARGIN; | ||||
|   let masterX = 50 + leftMargin; | ||||
|   //sectionBeginX = masterX; | ||||
|   let masterY = 50; | ||||
|   sectionBeginY = 50; | ||||
| @@ -115,8 +115,7 @@ export const draw = function (text: string, id: string, version: string, diagObj | ||||
|     maxEventCount = Math.max(maxEventCount, task.events.length); | ||||
|     //calculate maxEventLineLength | ||||
|     let maxEventLineLengthTemp = 0; | ||||
|     for (let j = 0; j < task.events.length; j++) { | ||||
|       const event = task.events[j]; | ||||
|     for (const event of task.events) { | ||||
|       const eventNode = { | ||||
|         descr: event, | ||||
|         section: task.section, | ||||
| @@ -203,7 +202,7 @@ export const draw = function (text: string, id: string, version: string, diagObj | ||||
|     svg | ||||
|       .append('text') | ||||
|       .text(title) | ||||
|       .attr('x', box.width / 2 - LEFT_MARGIN) | ||||
|       .attr('x', box.width / 2 - leftMargin) | ||||
|       .attr('font-size', '4ex') | ||||
|       .attr('font-weight', 'bold') | ||||
|       .attr('y', 20); | ||||
| @@ -215,9 +214,9 @@ export const draw = function (text: string, id: string, version: string, diagObj | ||||
|   // Draw activity line | ||||
|   lineWrapper | ||||
|     .append('line') | ||||
|     .attr('x1', LEFT_MARGIN) | ||||
|     .attr('x1', leftMargin) | ||||
|     .attr('y1', depthY) // One section head + one task + margins | ||||
|     .attr('x2', box.width + 3 * LEFT_MARGIN) // Subtract stroke width so arrow point is retained | ||||
|     .attr('x2', box.width + 3 * leftMargin) // Subtract stroke width so arrow point is retained | ||||
|     .attr('y2', depthY) | ||||
|     .attr('stroke-width', 4) | ||||
|     .attr('stroke', 'black') | ||||
|   | ||||
| @@ -75,8 +75,8 @@ function textSanitizer(text: string) { | ||||
|   return sanitizeText(text.trim(), config); | ||||
| } | ||||
|  | ||||
| function setTmpSVGG(SVGG: Group) { | ||||
|   tmpSVGGroup = SVGG; | ||||
| function setTmpSVGG(svgg: Group) { | ||||
|   tmpSVGGroup = svgg; | ||||
| } | ||||
| function setOrientation(orientation: string) { | ||||
|   if (orientation === 'horizontal') { | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import { defineConfig, MarkdownOptions } from 'vitepress'; | ||||
| import { defineConfig, type MarkdownOptions } from 'vitepress'; | ||||
| import { version } from '../../../package.json'; | ||||
| import MermaidExample from './mermaid-markdown-all.js'; | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import contributorUsernamesJson from './contributor-names.json'; | ||||
| import { CoreTeam, knut, plainTeamMembers } from './teamMembers.js'; | ||||
| import { type CoreTeam, knut, plainTeamMembers } from './teamMembers.js'; | ||||
|  | ||||
| const contributorUsernames: string[] = contributorUsernamesJson; | ||||
|  | ||||
|   | ||||
| @@ -32,7 +32,7 @@ async function fetchAvatars() { | ||||
|   }); | ||||
|  | ||||
|   contributors = JSON.parse(await readFile(pathContributors, { encoding: 'utf-8' })); | ||||
|   let avatars = contributors.map((name) => { | ||||
|   const avatars = contributors.map((name) => { | ||||
|     download(`https://github.com/${name}.png?size=100`, getAvatarPath(name)); | ||||
|   }); | ||||
|  | ||||
|   | ||||
| @@ -61,7 +61,7 @@ onMounted(async () => { | ||||
|  | ||||
|   //refresh images on first render | ||||
|   const hasImages = /<img([\w\W]+?)>/.exec(code.value)?.length > 0; | ||||
|   if (hasImages) | ||||
|   if (hasImages) { | ||||
|     setTimeout(() => { | ||||
|       let imgElements = document.getElementsByTagName('img'); | ||||
|       let imgs = Array.from(imgElements); | ||||
| @@ -80,6 +80,7 @@ onMounted(async () => { | ||||
|         }); | ||||
|       } | ||||
|     }, 100); | ||||
|   } | ||||
| }); | ||||
|  | ||||
| onUnmounted(() => mut.disconnect()); | ||||
|   | ||||
| @@ -170,8 +170,9 @@ describe('when using mermaid and ', () => { | ||||
|       ).resolves.not.toThrow(); | ||||
|     }); | ||||
|     it('should throw for an invalid flow definition', async () => { | ||||
|       await expect(mermaid.parse('graph TQ;A--x|text including URL space|B;')).rejects | ||||
|         .toThrowErrorMatchingInlineSnapshot(` | ||||
|       await expect( | ||||
|         mermaid.parse('graph TQ;A--x|text including URL space|B;') | ||||
|       ).rejects.toThrowErrorMatchingInlineSnapshot(` | ||||
|         [Error: Lexical error on line 1. Unrecognized text. | ||||
|         graph TQ;A--x|text includ | ||||
|         -----^] | ||||
|   | ||||
| @@ -98,7 +98,7 @@ const run = async function ( | ||||
|   } | ||||
| ) { | ||||
|   try { | ||||
|     await runThrowsErrors(options); | ||||
|     await runThrowsErrors(42); | ||||
|   } catch (e) { | ||||
|     if (isDetailedError(e)) { | ||||
|       log.error(e.str); | ||||
|   | ||||
| @@ -207,7 +207,7 @@ describe('mermaidAPI', () => { | ||||
|     }); | ||||
|  | ||||
|     it('uses the height and appends px from the svgElement given', () => { | ||||
|       const faux_svgElement = { | ||||
|       const fauxSvgElement = { | ||||
|         viewBox: { | ||||
|           baseVal: { | ||||
|             height: 42, | ||||
| @@ -215,7 +215,7 @@ describe('mermaidAPI', () => { | ||||
|         }, | ||||
|       }; | ||||
|  | ||||
|       const result = putIntoIFrame(inputSvgCode, faux_svgElement); | ||||
|       const result = putIntoIFrame(inputSvgCode, fauxSvgElement); | ||||
|       expect(result).toMatch(/style="(.*)height:42px;/); | ||||
|     }); | ||||
|   }); | ||||
| @@ -226,54 +226,54 @@ describe('mermaidAPI', () => { | ||||
|  | ||||
|   describe('appendDivSvgG', () => { | ||||
|     const fauxGNode = new MockedD3(); | ||||
|     const parent_append_spy = vi.spyOn(fauxParentNode, 'append').mockReturnValue(fauxEnclosingDiv); | ||||
|     const div_append_spy = vi.spyOn(fauxEnclosingDiv, 'append').mockReturnValue(fauxSvgNode); | ||||
|     const parentAppendSpy = vi.spyOn(fauxParentNode, 'append').mockReturnValue(fauxEnclosingDiv); | ||||
|     const divAppendSpy = vi.spyOn(fauxEnclosingDiv, 'append').mockReturnValue(fauxSvgNode); | ||||
|     // @ts-ignore @todo TODO why is this getting a type error? | ||||
|     const div_attr_spy = vi.spyOn(fauxEnclosingDiv, 'attr').mockReturnValue(fauxEnclosingDiv); | ||||
|     const svg_append_spy = vi.spyOn(fauxSvgNode, 'append').mockReturnValue(fauxGNode); | ||||
|     const divAttrSpy = vi.spyOn(fauxEnclosingDiv, 'attr').mockReturnValue(fauxEnclosingDiv); | ||||
|     const svgAppendSpy = vi.spyOn(fauxSvgNode, 'append').mockReturnValue(fauxGNode); | ||||
|     // @ts-ignore @todo TODO why is this getting a type error? | ||||
|     const svg_attr_spy = vi.spyOn(fauxSvgNode, 'attr').mockReturnValue(fauxSvgNode); | ||||
|     const svgAttrSpy = vi.spyOn(fauxSvgNode, 'attr').mockReturnValue(fauxSvgNode); | ||||
|  | ||||
|     // cspell:ignore dthe | ||||
|  | ||||
|     it('appends a div node', () => { | ||||
|       appendDivSvgG(fauxParentNode, 'theId', 'dtheId'); | ||||
|       expect(parent_append_spy).toHaveBeenCalledWith('div'); | ||||
|       expect(div_append_spy).toHaveBeenCalledWith('svg'); | ||||
|       expect(parentAppendSpy).toHaveBeenCalledWith('div'); | ||||
|       expect(divAppendSpy).toHaveBeenCalledWith('svg'); | ||||
|     }); | ||||
|     it('the id for the div is "d" with the id appended', () => { | ||||
|       appendDivSvgG(fauxParentNode, 'theId', 'dtheId'); | ||||
|       expect(div_attr_spy).toHaveBeenCalledWith('id', 'dtheId'); | ||||
|       expect(divAttrSpy).toHaveBeenCalledWith('id', 'dtheId'); | ||||
|     }); | ||||
|  | ||||
|     it('sets the style for the div if one is given', () => { | ||||
|       appendDivSvgG(fauxParentNode, 'theId', 'dtheId', 'given div style', 'given x link'); | ||||
|       expect(div_attr_spy).toHaveBeenCalledWith('style', 'given div style'); | ||||
|       expect(divAttrSpy).toHaveBeenCalledWith('style', 'given div style'); | ||||
|     }); | ||||
|  | ||||
|     it('appends a svg node to the div node', () => { | ||||
|       appendDivSvgG(fauxParentNode, 'theId', 'dtheId'); | ||||
|       expect(div_attr_spy).toHaveBeenCalledWith('id', 'dtheId'); | ||||
|       expect(divAttrSpy).toHaveBeenCalledWith('id', 'dtheId'); | ||||
|     }); | ||||
|     it('sets the svg width to 100%', () => { | ||||
|       appendDivSvgG(fauxParentNode, 'theId', 'dtheId'); | ||||
|       expect(svg_attr_spy).toHaveBeenCalledWith('width', '100%'); | ||||
|       expect(svgAttrSpy).toHaveBeenCalledWith('width', '100%'); | ||||
|     }); | ||||
|     it('the svg id is the id', () => { | ||||
|       appendDivSvgG(fauxParentNode, 'theId', 'dtheId'); | ||||
|       expect(svg_attr_spy).toHaveBeenCalledWith('id', 'theId'); | ||||
|       expect(svgAttrSpy).toHaveBeenCalledWith('id', 'theId'); | ||||
|     }); | ||||
|     it('the svg xml namespace is the 2000 standard', () => { | ||||
|       appendDivSvgG(fauxParentNode, 'theId', 'dtheId'); | ||||
|       expect(svg_attr_spy).toHaveBeenCalledWith('xmlns', 'http://www.w3.org/2000/svg'); | ||||
|       expect(svgAttrSpy).toHaveBeenCalledWith('xmlns', 'http://www.w3.org/2000/svg'); | ||||
|     }); | ||||
|     it('sets the  svg xlink if one is given', () => { | ||||
|       appendDivSvgG(fauxParentNode, 'theId', 'dtheId', 'div style', 'given x link'); | ||||
|       expect(svg_attr_spy).toHaveBeenCalledWith('xmlns:xlink', 'given x link'); | ||||
|       expect(svgAttrSpy).toHaveBeenCalledWith('xmlns:xlink', 'given x link'); | ||||
|     }); | ||||
|     it('appends a g (group) node to the svg node', () => { | ||||
|       appendDivSvgG(fauxParentNode, 'theId', 'dtheId'); | ||||
|       expect(svg_append_spy).toHaveBeenCalledWith('g'); | ||||
|       expect(svgAppendSpy).toHaveBeenCalledWith('g'); | ||||
|     }); | ||||
|     it('returns the given parentRoot d3 nodes', () => { | ||||
|       expect(appendDivSvgG(fauxParentNode, 'theId', 'dtheId')).toEqual(fauxParentNode); | ||||
| @@ -283,7 +283,7 @@ describe('mermaidAPI', () => { | ||||
|   describe('createCssStyles', () => { | ||||
|     const serif = 'serif'; | ||||
|     const sansSerif = 'sans-serif'; | ||||
|     const mocked_config_with_htmlLabels: MermaidConfig = { | ||||
|     const mockedConfigWithHtmlLabels: MermaidConfig = { | ||||
|       themeCSS: 'default', | ||||
|       fontFamily: serif, | ||||
|       altFontFamily: sansSerif, | ||||
| @@ -291,15 +291,15 @@ describe('mermaidAPI', () => { | ||||
|     }; | ||||
|  | ||||
|     it('gets the cssStyles from the theme', () => { | ||||
|       const styles = createCssStyles(mocked_config_with_htmlLabels, null); | ||||
|       const styles = createCssStyles(mockedConfigWithHtmlLabels, null); | ||||
|       expect(styles).toMatch(/^\ndefault(.*)/); | ||||
|     }); | ||||
|     it('gets the fontFamily from the config', () => { | ||||
|       const styles = createCssStyles(mocked_config_with_htmlLabels, new Map()); | ||||
|       const styles = createCssStyles(mockedConfigWithHtmlLabels, new Map()); | ||||
|       expect(styles).toMatch(/(.*)\n:root { --mermaid-font-family: serif(.*)/); | ||||
|     }); | ||||
|     it('gets the alt fontFamily from the config', () => { | ||||
|       const styles = createCssStyles(mocked_config_with_htmlLabels, undefined); | ||||
|       const styles = createCssStyles(mockedConfigWithHtmlLabels, undefined); | ||||
|       expect(styles).toMatch(/(.*)\n:root { --mermaid-alt-font-family: sans-serif(.*)/); | ||||
|     }); | ||||
|  | ||||
| @@ -310,13 +310,13 @@ describe('mermaidAPI', () => { | ||||
|       const classDefs = { classDef1, classDef2, classDef3 }; | ||||
|  | ||||
|       describe('the graph supports classDefs', () => { | ||||
|         const REGEXP_SPECIALS = ['^', '$', '?', '(', '{', '[', '.', '*', '!']; | ||||
|         const regexpSpecials = ['^', '$', '?', '(', '{', '[', '.', '*', '!']; | ||||
|  | ||||
|         // prefix any special RegExp characters in the given string with a \ so we can use the literal character in a RegExp | ||||
|         function escapeForRegexp(str: string) { | ||||
|           const strChars = [...str]; // split into array of every char | ||||
|           const strEscaped = strChars.map((char) => { | ||||
|             if (REGEXP_SPECIALS.includes(char)) { | ||||
|             if (regexpSpecials.includes(char)) { | ||||
|               return `\\${char}`; | ||||
|             } else { | ||||
|               return char; | ||||
| @@ -326,7 +326,7 @@ describe('mermaidAPI', () => { | ||||
|         } | ||||
|  | ||||
|         // Common test expecting given styles to have .classDef1 and .classDef2 statements but not .classDef3 | ||||
|         function expect_styles_matchesHtmlElements(styles: string, htmlElement: string) { | ||||
|         function expectStylesMatchesHtmlElements(styles: string, htmlElement: string) { | ||||
|           expect(styles).toMatch( | ||||
|             new RegExp( | ||||
|               `\\.classDef1 ${escapeForRegexp( | ||||
| @@ -344,7 +344,7 @@ describe('mermaidAPI', () => { | ||||
|         } | ||||
|  | ||||
|         // Common test expecting given textStyles to have .classDef2 and .classDef3 statements but not .classDef1 | ||||
|         function expect_textStyles_matchesHtmlElements(textStyles: string, htmlElement: string) { | ||||
|         function expectTextStylesMatchesHtmlElements(textStyles: string, htmlElement: string) { | ||||
|           expect(textStyles).toMatch( | ||||
|             new RegExp( | ||||
|               `\\.classDef2 ${escapeForRegexp(htmlElement)} \\{ textStyle2-1 !important; }` | ||||
| @@ -367,7 +367,7 @@ describe('mermaidAPI', () => { | ||||
|         } | ||||
|  | ||||
|         // common suite and tests to verify that the right styles are created with the right htmlElements | ||||
|         function expect_correct_styles_with_htmlElements(mocked_config: MermaidConfig) { | ||||
|         function expectCorrectStylesWithHtmlElements(mockedConfig: MermaidConfig) { | ||||
|           describe('creates styles for "> *" and  "span" elements', () => { | ||||
|             const htmlElements = ['> *', 'span']; | ||||
|  | ||||
| @@ -375,21 +375,21 @@ describe('mermaidAPI', () => { | ||||
|               // @todo TODO Can't figure out how to spy on the cssImportantStyles method. | ||||
|               //   That would be a much better approach than manually checking the result | ||||
|  | ||||
|               const styles = createCssStyles(mocked_config, new Map(Object.entries(classDefs))); | ||||
|               const styles = createCssStyles(mockedConfig, new Map(Object.entries(classDefs))); | ||||
|               htmlElements.forEach((htmlElement) => { | ||||
|                 expect_styles_matchesHtmlElements(styles, htmlElement); | ||||
|                 expectStylesMatchesHtmlElements(styles, htmlElement); | ||||
|               }); | ||||
|               expect_textStyles_matchesHtmlElements(styles, 'tspan'); | ||||
|               expectTextStylesMatchesHtmlElements(styles, 'tspan'); | ||||
|             }); | ||||
|           }); | ||||
|         } | ||||
|  | ||||
|         it('there are htmlLabels in the configuration', () => { | ||||
|           expect_correct_styles_with_htmlElements(mocked_config_with_htmlLabels); | ||||
|           expectCorrectStylesWithHtmlElements(mockedConfigWithHtmlLabels); | ||||
|         }); | ||||
|  | ||||
|         it('there are flowchart.htmlLabels in the configuration', () => { | ||||
|           const mocked_config_flowchart_htmlLabels: MermaidConfig = { | ||||
|           const mockedConfigFlowchartHtmlLabels: MermaidConfig = { | ||||
|             themeCSS: 'default', | ||||
|             fontFamily: 'serif', | ||||
|             altFontFamily: 'sans-serif', | ||||
| @@ -397,11 +397,11 @@ describe('mermaidAPI', () => { | ||||
|               htmlLabels: true, | ||||
|             }, | ||||
|           }; | ||||
|           expect_correct_styles_with_htmlElements(mocked_config_flowchart_htmlLabels); | ||||
|           expectCorrectStylesWithHtmlElements(mockedConfigFlowchartHtmlLabels); | ||||
|         }); | ||||
|  | ||||
|         describe('no htmlLabels in the configuration', () => { | ||||
|           const mocked_config_no_htmlLabels = { | ||||
|           const mockedConfigNoHtmlLabels = { | ||||
|             themeCSS: 'default', | ||||
|             fontFamily: 'serif', | ||||
|             altFontFamily: 'sans-serif', | ||||
| @@ -414,13 +414,13 @@ describe('mermaidAPI', () => { | ||||
|               // TODO Can't figure out how to spy on the cssImportantStyles method. That would be a much better approach than manually checking the result. | ||||
|  | ||||
|               const styles = createCssStyles( | ||||
|                 mocked_config_no_htmlLabels, | ||||
|                 mockedConfigNoHtmlLabels, | ||||
|                 new Map(Object.entries(classDefs)) | ||||
|               ); | ||||
|               htmlElements.forEach((htmlElement) => { | ||||
|                 expect_styles_matchesHtmlElements(styles, htmlElement); | ||||
|                 expectStylesMatchesHtmlElements(styles, htmlElement); | ||||
|               }); | ||||
|               expect_textStyles_matchesHtmlElements(styles, 'tspan'); | ||||
|               expectTextStylesMatchesHtmlElements(styles, 'tspan'); | ||||
|             }); | ||||
|           }); | ||||
|         }); | ||||
| @@ -692,8 +692,9 @@ describe('mermaidAPI', () => { | ||||
|       ).resolves.toBe(false); | ||||
|     }); | ||||
|     it('resolves for valid definition', async () => { | ||||
|       await expect(mermaidAPI.parse('graph TD;A--x|text including URL space|B;')).resolves | ||||
|         .toMatchInlineSnapshot(` | ||||
|       await expect( | ||||
|         mermaidAPI.parse('graph TD;A--x|text including URL space|B;') | ||||
|       ).resolves.toMatchInlineSnapshot(` | ||||
|         { | ||||
|           "diagramType": "flowchart-v2", | ||||
|         } | ||||
| @@ -748,15 +749,12 @@ describe('mermaidAPI', () => { | ||||
|           const expectedDiagramType = testedDiagram.expectedType; | ||||
|  | ||||
|           it('should set aria-roledescription to the diagram type AND should call addSVGa11yTitleDescription', async () => { | ||||
|             const a11yDiagramInfo_spy = vi.spyOn(accessibility, 'setA11yDiagramInfo'); | ||||
|             const a11yTitleDesc_spy = vi.spyOn(accessibility, 'addSVGa11yTitleDescription'); | ||||
|             const a11yDiagramInfoSpy = vi.spyOn(accessibility, 'setA11yDiagramInfo'); | ||||
|             const a11yTitleDescSpy = vi.spyOn(accessibility, 'addSVGa11yTitleDescription'); | ||||
|             const result = await mermaidAPI.render(id, diagramText); | ||||
|             expect(result.diagramType).toBe(expectedDiagramType); | ||||
|             expect(a11yDiagramInfo_spy).toHaveBeenCalledWith( | ||||
|               expect.anything(), | ||||
|               expectedDiagramType | ||||
|             ); | ||||
|             expect(a11yTitleDesc_spy).toHaveBeenCalled(); | ||||
|             expect(a11yDiagramInfoSpy).toHaveBeenCalledWith(expect.anything(), expectedDiagramType); | ||||
|             expect(a11yTitleDescSpy).toHaveBeenCalled(); | ||||
|           }); | ||||
|         }); | ||||
|       }); | ||||
|   | ||||
| @@ -363,14 +363,14 @@ const render = async function ( | ||||
|  | ||||
|   const idSelector = '#' + id; | ||||
|   const iFrameID = 'i' + id; | ||||
|   const iFrameID_selector = '#' + iFrameID; | ||||
|   const iFrameIdSelector = '#' + iFrameID; | ||||
|   const enclosingDivID = 'd' + id; | ||||
|   const enclosingDivID_selector = '#' + enclosingDivID; | ||||
|   const enclosingDivIdSelector = '#' + enclosingDivID; | ||||
|  | ||||
|   const removeTempElements = () => { | ||||
|     // ------------------------------------------------------------------------------- | ||||
|     // Remove the temporary HTML element if appropriate | ||||
|     const tmpElementSelector = isSandboxed ? iFrameID_selector : enclosingDivID_selector; | ||||
|     const tmpElementSelector = isSandboxed ? iFrameIdSelector : enclosingDivIdSelector; | ||||
|     const node = select(tmpElementSelector).node(); | ||||
|     if (node && 'remove' in node) { | ||||
|       node.remove(); | ||||
| @@ -442,7 +442,7 @@ const render = async function ( | ||||
|   } | ||||
|  | ||||
|   // Get the temporary div element containing the svg | ||||
|   const element = root.select(enclosingDivID_selector).node(); | ||||
|   const element = root.select(enclosingDivIdSelector).node(); | ||||
|   const diagramType = diag.type; | ||||
|  | ||||
|   // ------------------------------------------------------------------------------- | ||||
| @@ -473,7 +473,7 @@ const render = async function ( | ||||
|   } | ||||
|  | ||||
|   // This is the d3 node for the svg element | ||||
|   const svgNode = root.select(`${enclosingDivID_selector} svg`); | ||||
|   const svgNode = root.select(`${enclosingDivIdSelector} svg`); | ||||
|   const a11yTitle: string | undefined = diag.db.getAccTitle?.(); | ||||
|   const a11yDescr: string | undefined = diag.db.getAccDescription?.(); | ||||
|   addA11yInfo(diagramType, svgNode, a11yTitle, a11yDescr); | ||||
| @@ -482,13 +482,13 @@ const render = async function ( | ||||
|   root.select(`[id="${id}"]`).selectAll('foreignobject > *').attr('xmlns', XMLNS_XHTML_STD); | ||||
|  | ||||
|   // Fix for when the base tag is used | ||||
|   let svgCode: string = root.select(enclosingDivID_selector).node().innerHTML; | ||||
|   let svgCode: string = root.select(enclosingDivIdSelector).node().innerHTML; | ||||
|  | ||||
|   log.debug('config.arrowMarkerAbsolute', config.arrowMarkerAbsolute); | ||||
|   svgCode = cleanUpSvgCode(svgCode, isSandboxed, evaluate(config.arrowMarkerAbsolute)); | ||||
|  | ||||
|   if (isSandboxed) { | ||||
|     const svgEl = root.select(enclosingDivID_selector + ' svg').node(); | ||||
|     const svgEl = root.select(enclosingDivIdSelector + ' svg').node(); | ||||
|     svgCode = putIntoIFrame(svgCode, svgEl); | ||||
|   } else if (!isLooseSecurityLevel) { | ||||
|     // Sanitize the svgCode using DOMPurify | ||||
|   | ||||
| @@ -74,6 +74,7 @@ export class MockedD3 { | ||||
|   attr(attrName: string): undefined | string; | ||||
|   attr(attrName: string, attrValue: string): MockedD3; | ||||
|   attr(attrName: string, attrValue?: string): undefined | string | MockedD3 { | ||||
|     // biome-ignore lint/style/noArguments: <explanation> | ||||
|     if (arguments.length === 1) { | ||||
|       return this.attribs.get(attrName); | ||||
|     } else { | ||||
| @@ -105,8 +106,8 @@ export class MockedD3 { | ||||
|   // Real implementation returns an HTML Element | ||||
|   public node = vi.fn().mockImplementation(() => { | ||||
|     const topElem = this._containingHTMLdoc.createElement('svg'); | ||||
|     const elem_svgChild = this._containingHTMLdoc.createElement('svg'); // another svg element | ||||
|     topElem.appendChild(elem_svgChild); | ||||
|     const elemSvgChild = this._containingHTMLdoc.createElement('svg'); // another svg element | ||||
|     topElem.appendChild(elemSvgChild); | ||||
|     return topElem; | ||||
|   }); | ||||
|  | ||||
|   | ||||
| @@ -11,51 +11,51 @@ addDiagrams(); | ||||
|  | ||||
| describe('when assignWithDepth: should merge objects within objects', function () { | ||||
|   it('should handle simple, depth:1 types (identity)', function () { | ||||
|     const config_0 = { foo: 'bar', bar: 0 }; | ||||
|     const config_1 = { foo: 'bar', bar: 0 }; | ||||
|     const result = assignWithDepth(config_0, config_1); | ||||
|     expect(result).toEqual(config_1); | ||||
|     const config0 = { foo: 'bar', bar: 0 }; | ||||
|     const config1 = { foo: 'bar', bar: 0 }; | ||||
|     const result = assignWithDepth(config0, config1); | ||||
|     expect(result).toEqual(config1); | ||||
|   }); | ||||
|   it('should handle simple, depth:1 types (dst: undefined)', function () { | ||||
|     const config_0 = undefined; | ||||
|     const config_1 = { foo: 'bar', bar: 0 }; | ||||
|     const result = assignWithDepth(config_0, config_1); | ||||
|     expect(result).toEqual(config_1); | ||||
|     const config0 = undefined; | ||||
|     const config1 = { foo: 'bar', bar: 0 }; | ||||
|     const result = assignWithDepth(config0, config1); | ||||
|     expect(result).toEqual(config1); | ||||
|   }); | ||||
|   it('should handle simple, depth:1 types (src: undefined)', function () { | ||||
|     const config_0 = { foo: 'bar', bar: 0 }; | ||||
|     const config_1 = undefined; | ||||
|     const result = assignWithDepth(config_0, config_1); | ||||
|     expect(result).toEqual(config_0); | ||||
|     const config0 = { foo: 'bar', bar: 0 }; | ||||
|     const config1 = undefined; | ||||
|     const result = assignWithDepth(config0, config1); | ||||
|     expect(result).toEqual(config0); | ||||
|   }); | ||||
|   it('should handle simple, depth:1 types (merge)', function () { | ||||
|     const config_0 = { foo: 'bar', bar: 0 }; | ||||
|     const config_1 = { foo: 'foo' }; | ||||
|     const result = assignWithDepth(config_0, config_1); | ||||
|     const config0 = { foo: 'bar', bar: 0 }; | ||||
|     const config1 = { foo: 'foo' }; | ||||
|     const result = assignWithDepth(config0, config1); | ||||
|     expect(result).toEqual({ foo: 'foo', bar: 0 }); | ||||
|   }); | ||||
|   it('should handle depth:2 types (dst: orphan)', function () { | ||||
|     const config_0 = { foo: 'bar', bar: { foo: 'bar' } }; | ||||
|     const config_1 = { foo: 'bar' }; | ||||
|     const result = assignWithDepth(config_0, config_1); | ||||
|     expect(result).toEqual(config_0); | ||||
|     const config0 = { foo: 'bar', bar: { foo: 'bar' } }; | ||||
|     const config1 = { foo: 'bar' }; | ||||
|     const result = assignWithDepth(config0, config1); | ||||
|     expect(result).toEqual(config0); | ||||
|   }); | ||||
|   it('should handle depth:2 types (dst: object, src: simple type)', function () { | ||||
|     const config_0 = { foo: 'bar', bar: { foo: 'bar' } }; | ||||
|     const config_1 = { foo: 'foo', bar: 'should NOT clobber' }; | ||||
|     const result = assignWithDepth(config_0, config_1); | ||||
|     const config0 = { foo: 'bar', bar: { foo: 'bar' } }; | ||||
|     const config1 = { foo: 'foo', bar: 'should NOT clobber' }; | ||||
|     const result = assignWithDepth(config0, config1); | ||||
|     expect(result).toEqual({ foo: 'foo', bar: { foo: 'bar' } }); | ||||
|   }); | ||||
|   it('should handle depth:2 types (src: orphan)', function () { | ||||
|     const config_0 = { foo: 'bar' }; | ||||
|     const config_1 = { foo: 'bar', bar: { foo: 'bar' } }; | ||||
|     const result = assignWithDepth(config_0, config_1); | ||||
|     expect(result).toEqual(config_1); | ||||
|     const config0 = { foo: 'bar' }; | ||||
|     const config1 = { foo: 'bar', bar: { foo: 'bar' } }; | ||||
|     const result = assignWithDepth(config0, config1); | ||||
|     expect(result).toEqual(config1); | ||||
|   }); | ||||
|   it('should handle depth:2 types (merge)', function () { | ||||
|     const config_0 = { foo: 'bar', bar: { foo: 'bar' }, boofar: 1 }; | ||||
|     const config_1 = { foo: 'foo', bar: { bar: 0 }, foobar: 'foobar' }; | ||||
|     const result = assignWithDepth(config_0, config_1); | ||||
|     const config0 = { foo: 'bar', bar: { foo: 'bar' }, boofar: 1 }; | ||||
|     const config1 = { foo: 'foo', bar: { bar: 0 }, foobar: 'foobar' }; | ||||
|     const result = assignWithDepth(config0, config1); | ||||
|     expect(result).toEqual({ | ||||
|       foo: 'foo', | ||||
|       bar: { foo: 'bar', bar: 0 }, | ||||
| @@ -64,17 +64,17 @@ describe('when assignWithDepth: should merge objects within objects', function ( | ||||
|     }); | ||||
|   }); | ||||
|   it('should handle depth:3 types (merge with clobber because assignWithDepth::depth == 2)', function () { | ||||
|     const config_0 = { | ||||
|     const config0 = { | ||||
|       foo: 'bar', | ||||
|       bar: { foo: 'bar', bar: { foo: { message: 'this', willbe: 'clobbered' } } }, | ||||
|       boofar: 1, | ||||
|     }; | ||||
|     const config_1 = { | ||||
|     const config1 = { | ||||
|       foo: 'foo', | ||||
|       bar: { foo: 'foo', bar: { foo: { message: 'clobbered other foo' } } }, | ||||
|       foobar: 'foobar', | ||||
|     }; | ||||
|     const result = assignWithDepth(config_0, config_1); | ||||
|     const result = assignWithDepth(config0, config1); | ||||
|     expect(result).toEqual({ | ||||
|       foo: 'foo', | ||||
|       bar: { foo: 'foo', bar: { foo: { message: 'clobbered other foo' } } }, | ||||
| @@ -83,7 +83,7 @@ describe('when assignWithDepth: should merge objects within objects', function ( | ||||
|     }); | ||||
|   }); | ||||
|   it('should handle depth:3 types (merge with clobber because assignWithDepth::depth == 1)', function () { | ||||
|     const config_0 = { | ||||
|     const config0 = { | ||||
|       foo: 'bar', | ||||
|       bar: { | ||||
|         foo: 'bar', | ||||
| @@ -91,12 +91,12 @@ describe('when assignWithDepth: should merge objects within objects', function ( | ||||
|       }, | ||||
|       boofar: 1, | ||||
|     }; | ||||
|     const config_1 = { | ||||
|     const config1 = { | ||||
|       foo: 'foo', | ||||
|       bar: { foo: 'foo', bar: { foo: { message: 'this' } } }, | ||||
|       foobar: 'foobar', | ||||
|     }; | ||||
|     const result = assignWithDepth(config_0, config_1, { depth: 1 }); | ||||
|     const result = assignWithDepth(config0, config1, { depth: 1 }); | ||||
|     expect(result).toEqual({ | ||||
|       foo: 'foo', | ||||
|       bar: { foo: 'foo', bar: { foo: { message: 'this' } } }, | ||||
| @@ -105,17 +105,17 @@ describe('when assignWithDepth: should merge objects within objects', function ( | ||||
|     }); | ||||
|   }); | ||||
|   it('should handle depth:3 types (merge with no clobber because assignWithDepth::depth == 3)', function () { | ||||
|     const config_0 = { | ||||
|     const config0 = { | ||||
|       foo: 'bar', | ||||
|       bar: { foo: 'bar', bar: { foo: { message: '', willbe: 'present' } } }, | ||||
|       boofar: 1, | ||||
|     }; | ||||
|     const config_1 = { | ||||
|     const config1 = { | ||||
|       foo: 'foo', | ||||
|       bar: { foo: 'foo', bar: { foo: { message: 'this' } } }, | ||||
|       foobar: 'foobar', | ||||
|     }; | ||||
|     const result = assignWithDepth(config_0, config_1, { depth: 3 }); | ||||
|     const result = assignWithDepth(config0, config1, { depth: 3 }); | ||||
|     expect(result).toEqual({ | ||||
|       foo: 'foo', | ||||
|       bar: { foo: 'foo', bar: { foo: { message: 'this', willbe: 'present' } } }, | ||||
|   | ||||
| @@ -173,6 +173,7 @@ export const detectDirective = function ( | ||||
|     ); | ||||
|     let match: RegExpExecArray | null; | ||||
|     const result: Directive[] = []; | ||||
|     // biome-ignore lint/suspicious/noAssignInExpressions: <explanation> | ||||
|     while ((match = directiveRegex.exec(text)) !== null) { | ||||
|       // This is necessary to avoid infinite loops with zero-width matches | ||||
|       if (match.index === directiveRegex.lastIndex) { | ||||
| @@ -443,7 +444,10 @@ function calcTerminalLabelPosition( | ||||
|  * @param arr - Declarations | ||||
|  * @returns The styles grouped as strings | ||||
|  */ | ||||
| export function getStylesFromArray(arr: string[]): { style: string; labelStyle: string } { | ||||
| export function getStylesFromArray(arr: string[]): { | ||||
|   style: string; | ||||
|   labelStyle: string; | ||||
| } { | ||||
|   let style = ''; | ||||
|   let labelStyle = ''; | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,7 @@ import * as configApi from '../config.js'; | ||||
|  | ||||
| describe('getSubGraphTitleMargins', () => { | ||||
|   it('should get subgraph title margins after config has been set', () => { | ||||
|     const config_0 = { | ||||
|     const config0 = { | ||||
|       flowchart: { | ||||
|         subGraphTitleMargin: { | ||||
|           top: 10, | ||||
| @@ -12,8 +12,8 @@ describe('getSubGraphTitleMargins', () => { | ||||
|       }, | ||||
|     }; | ||||
|  | ||||
|     configApi.setSiteConfig(config_0); | ||||
|     expect(getSubGraphTitleMargins(config_0)).toEqual({ | ||||
|     configApi.setSiteConfig(config0); | ||||
|     expect(getSubGraphTitleMargins(config0)).toEqual({ | ||||
|       subGraphTitleTopMargin: 10, | ||||
|       subGraphTitleBottomMargin: 5, | ||||
|       subGraphTitleTotalMargin: 15, | ||||
|   | ||||
| @@ -3,10 +3,7 @@ | ||||
|   "version": "0.1.0-rc.1", | ||||
|   "description": "MermaidJS parser", | ||||
|   "author": "Yokozuna59", | ||||
|   "contributors": [ | ||||
|     "Yokozuna59", | ||||
|     "Sidharth Vinod (https://sidharth.dev)" | ||||
|   ], | ||||
|   "contributors": ["Yokozuna59", "Sidharth Vinod (https://sidharth.dev)"], | ||||
|   "homepage": "https://github.com/mermaid-js/mermaid/tree/develop/packages/mermaid/parser/#readme", | ||||
|   "types": "dist/src/index.d.ts", | ||||
|   "type": "module", | ||||
| @@ -28,20 +25,14 @@ | ||||
|     "directory": "packages/parser" | ||||
|   }, | ||||
|   "license": "MIT", | ||||
|   "keywords": [ | ||||
|     "mermaid", | ||||
|     "parser", | ||||
|     "ast" | ||||
|   ], | ||||
|   "keywords": ["mermaid", "parser", "ast"], | ||||
|   "dependencies": { | ||||
|     "langium": "3.0.0" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "chevrotain": "^11.0.3" | ||||
|   }, | ||||
|   "files": [ | ||||
|     "dist/" | ||||
|   ], | ||||
|   "files": ["dist/"], | ||||
|   "publishConfig": { | ||||
|     "access": "public" | ||||
|   } | ||||
|   | ||||
							
								
								
									
										97
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										97
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							| @@ -14,6 +14,9 @@ importers: | ||||
|       '@argos-ci/cypress': | ||||
|         specifier: ^2.0.5 | ||||
|         version: 2.0.5(cypress@13.7.3) | ||||
|       '@biomejs/biome': | ||||
|         specifier: 1.8.2 | ||||
|         version: 1.8.2 | ||||
|       '@cspell/eslint-plugin': | ||||
|         specifier: ^8.6.0 | ||||
|         version: 8.7.0(eslint@8.57.0) | ||||
| @@ -300,12 +303,6 @@ importers: | ||||
|       '@types/uuid': | ||||
|         specifier: ^9.0.8 | ||||
|         version: 9.0.8 | ||||
|       '@typescript-eslint/eslint-plugin': | ||||
|         specifier: ^7.3.1 | ||||
|         version: 7.6.0(@typescript-eslint/parser@7.6.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) | ||||
|       '@typescript-eslint/parser': | ||||
|         specifier: ^7.3.1 | ||||
|         version: 7.6.0(eslint@8.57.0)(typescript@5.4.5) | ||||
|       ajv: | ||||
|         specifier: ^8.12.0 | ||||
|         version: 8.12.0 | ||||
| @@ -1517,6 +1514,59 @@ packages: | ||||
|   '@bcoe/v8-coverage@0.2.3': | ||||
|     resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} | ||||
|  | ||||
|   '@biomejs/biome@1.8.2': | ||||
|     resolution: {integrity: sha512-XafCzLgs0xbH0bCjYKxQ63ig2V86fZQMq1jiy5pyLToWk9aHxA8GAUxyBtklPHtPYZPGEPOYglQHj4jyfUp+Iw==} | ||||
|     engines: {node: '>=14.21.3'} | ||||
|     hasBin: true | ||||
|  | ||||
|   '@biomejs/cli-darwin-arm64@1.8.2': | ||||
|     resolution: {integrity: sha512-l9msLsTcSIAPqMsPIhodQmb50sEfaXPLQ0YW4cdj6INmd8iaOh/V9NceQb2366vACTJgcWDQ2RzlvURek1T68g==} | ||||
|     engines: {node: '>=14.21.3'} | ||||
|     cpu: [arm64] | ||||
|     os: [darwin] | ||||
|  | ||||
|   '@biomejs/cli-darwin-x64@1.8.2': | ||||
|     resolution: {integrity: sha512-Fc4y/FuIxRSiB3TJ+y27vFDE/HJt4QgBuymktsIKEcBZvnKfsRjxvzVDunccRn4xbKgepnp+fn6BoS+ZIg/I3Q==} | ||||
|     engines: {node: '>=14.21.3'} | ||||
|     cpu: [x64] | ||||
|     os: [darwin] | ||||
|  | ||||
|   '@biomejs/cli-linux-arm64-musl@1.8.2': | ||||
|     resolution: {integrity: sha512-WpT41QJJvkZa1eZq0WmD513zkC6AYaMI39HJKmKeiUeX2NZirG+bxv1YRDhqkns1NbBqo3+qrJqBkPmOW+xAVA==} | ||||
|     engines: {node: '>=14.21.3'} | ||||
|     cpu: [arm64] | ||||
|     os: [linux] | ||||
|  | ||||
|   '@biomejs/cli-linux-arm64@1.8.2': | ||||
|     resolution: {integrity: sha512-Q99qwP0qibkZxm2kfnt37OxeIlliDYf5ogi3zX9ij2DULzc+KtPA9Uj0wCljcJofOBsBYaHc7597Q+Bf/251ww==} | ||||
|     engines: {node: '>=14.21.3'} | ||||
|     cpu: [arm64] | ||||
|     os: [linux] | ||||
|  | ||||
|   '@biomejs/cli-linux-x64-musl@1.8.2': | ||||
|     resolution: {integrity: sha512-rk1Wj4d3LIlAlIAS1m2jlyfOjkNbuY1lfwKvWIAeZC51yDMzwhRD7cReE5PE+jqLDtq60PX38hDPeKd7nA1S6A==} | ||||
|     engines: {node: '>=14.21.3'} | ||||
|     cpu: [x64] | ||||
|     os: [linux] | ||||
|  | ||||
|   '@biomejs/cli-linux-x64@1.8.2': | ||||
|     resolution: {integrity: sha512-bjhhUVFchFid2gOjrvBe4fg8BShcpyFQTHuB/QQnfGxs1ddrGP30yq3fHfc6S6MoCcz9Tjd3Zzq1EfWfyy5iHA==} | ||||
|     engines: {node: '>=14.21.3'} | ||||
|     cpu: [x64] | ||||
|     os: [linux] | ||||
|  | ||||
|   '@biomejs/cli-win32-arm64@1.8.2': | ||||
|     resolution: {integrity: sha512-EUbqmCmNWT5xhnxHrCAEBzJB1AnLqxTYoRjlxiCMzGvsy5jQzhCanJ8CT9kNsApW3pfPWBWkoTa7qrwWmwnEGA==} | ||||
|     engines: {node: '>=14.21.3'} | ||||
|     cpu: [arm64] | ||||
|     os: [win32] | ||||
|  | ||||
|   '@biomejs/cli-win32-x64@1.8.2': | ||||
|     resolution: {integrity: sha512-n9H5oRUCk1uNezMgyJh9+hZdtfD8PXLLeq8DUzTycIhl0I1BulIoZ/uxWgRVDFDwAR1JHu1AykISCRFNGnc4iA==} | ||||
|     engines: {node: '>=14.21.3'} | ||||
|     cpu: [x64] | ||||
|     os: [win32] | ||||
|  | ||||
|   '@braintree/sanitize-url@7.0.1': | ||||
|     resolution: {integrity: sha512-URg8UM6lfC9ZYqFipItRSxYJdgpU5d2Z4KnjsJ+rj6tgAmGme7E+PQNCiud8g0HDaZKMovu2qjfa0f5Ge0Vlsg==} | ||||
|  | ||||
| @@ -11061,6 +11111,41 @@ snapshots: | ||||
|  | ||||
|   '@bcoe/v8-coverage@0.2.3': {} | ||||
|  | ||||
|   '@biomejs/biome@1.8.2': | ||||
|     optionalDependencies: | ||||
|       '@biomejs/cli-darwin-arm64': 1.8.2 | ||||
|       '@biomejs/cli-darwin-x64': 1.8.2 | ||||
|       '@biomejs/cli-linux-arm64': 1.8.2 | ||||
|       '@biomejs/cli-linux-arm64-musl': 1.8.2 | ||||
|       '@biomejs/cli-linux-x64': 1.8.2 | ||||
|       '@biomejs/cli-linux-x64-musl': 1.8.2 | ||||
|       '@biomejs/cli-win32-arm64': 1.8.2 | ||||
|       '@biomejs/cli-win32-x64': 1.8.2 | ||||
|  | ||||
|   '@biomejs/cli-darwin-arm64@1.8.2': | ||||
|     optional: true | ||||
|  | ||||
|   '@biomejs/cli-darwin-x64@1.8.2': | ||||
|     optional: true | ||||
|  | ||||
|   '@biomejs/cli-linux-arm64-musl@1.8.2': | ||||
|     optional: true | ||||
|  | ||||
|   '@biomejs/cli-linux-arm64@1.8.2': | ||||
|     optional: true | ||||
|  | ||||
|   '@biomejs/cli-linux-x64-musl@1.8.2': | ||||
|     optional: true | ||||
|  | ||||
|   '@biomejs/cli-linux-x64@1.8.2': | ||||
|     optional: true | ||||
|  | ||||
|   '@biomejs/cli-win32-arm64@1.8.2': | ||||
|     optional: true | ||||
|  | ||||
|   '@biomejs/cli-win32-x64@1.8.2': | ||||
|     optional: true | ||||
|  | ||||
|   '@braintree/sanitize-url@7.0.1': {} | ||||
|  | ||||
|   '@chevrotain/cst-dts-gen@11.0.3': | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| { | ||||
|   "$schema": "https://docs.renovatebot.com/renovate-schema.json", | ||||
|   "extends": [ | ||||
|     "config:base", | ||||
|     ":rebaseStalePrs", | ||||
| @@ -7,7 +8,8 @@ | ||||
|     ":automergeTesters", | ||||
|     ":automergeLinters", | ||||
|     ":automergeTypes", | ||||
|     ":automergePatch" | ||||
|     ":automergePatch", | ||||
|     "customManagers:biomeVersions" | ||||
|   ], | ||||
|   "packageRules": [ | ||||
|     { | ||||
|   | ||||
| @@ -1,8 +1,6 @@ | ||||
| { | ||||
|   // extend your base config to share compilerOptions, etc | ||||
|   "extends": "./tsconfig.json", | ||||
|   "compilerOptions": { | ||||
|     // ensure that nobody can accidentally use this config for a build | ||||
|     "noEmit": true | ||||
|   }, | ||||
|   "include": [ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user