mikro-orm-markdown 0.1.0-alpha.4 → 0.1.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/README.ko.md +53 -0
- package/README.md +53 -0
- package/dist/cli.cjs +48 -9
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +48 -9
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +19 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +19 -8
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.1.0-alpha.5] - 2026-06-29
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `--mermaid-layout <layout>` and `--mermaid-theme <theme>` CLI options to inject Mermaid YAML frontmatter into each `erDiagram` fence
|
|
13
|
+
- `mermaid` option in the programmatic API (`generateMarkdown({ mermaid: { layout, theme } })`) with the same effect
|
|
14
|
+
- `MermaidLayout`, `MermaidTheme`, and `MermaidRenderOptions` types exported from the public API
|
|
15
|
+
- When neither option is set, output is identical to previous versions — no frontmatter is emitted
|
|
16
|
+
|
|
8
17
|
## [0.1.0-alpha.4] - 2026-06-29
|
|
9
18
|
|
|
10
19
|
### Fixed
|
package/README.ko.md
CHANGED
|
@@ -79,6 +79,8 @@ npm run erd
|
|
|
79
79
|
| `-d, --description <string>` | — | 제목 아래에 표시할 설명 문단 (선택) |
|
|
80
80
|
| `--tsconfig <path>` | — | `.ts` config 로드 시 사용할 `tsconfig.json`; 기본값은 config 파일 근처의 가장 가까운 파일 |
|
|
81
81
|
| `--src <paths...>` | — | 원본 TypeScript 엔티티 소스 경로/glob; MikroORM이 컴파일된 JavaScript에서 엔티티를 discovery할 때만 필요 |
|
|
82
|
+
| `--mermaid-layout <layout>` | — | Mermaid 레이아웃 엔진 (`dagre\|elk\|elk.stress`). 생략하면 뷰어 기본값 사용. |
|
|
83
|
+
| `--mermaid-theme <theme>` | — | Mermaid 테마 (`default\|neutral\|dark\|forest\|base`). 생략하면 뷰어 기본값 사용. |
|
|
82
84
|
|
|
83
85
|
> 설명이 길거나 여러 줄이라면 CLI 대신 [프로그래밍 API](#프로그래밍-api)를 사용하세요 — 쉘 인용 부호 제약 없이 문자열을 그대로 전달할 수 있습니다.
|
|
84
86
|
|
|
@@ -392,6 +394,7 @@ await writeFile('./ERD.md', markdown, 'utf-8');
|
|
|
392
394
|
| `description` | 제목 아래에 표시할 설명 문단입니다. CLI flag와 달리 쉘 quoting 제약 없이 문자열을 그대로 전달할 수 있습니다. |
|
|
393
395
|
| `src` | 원본 TypeScript 엔티티 소스 경로/glob입니다. `orm.entities`가 컴파일된 JavaScript를 discovery할 때만 필요합니다. |
|
|
394
396
|
| `onWarn` | 컴파일된 JavaScript에서 JSDoc을 읽지 못하는 상황 같은 non-fatal warning을 받을 callback입니다. |
|
|
397
|
+
| `mermaid` | Mermaid 렌더링 옵션입니다. 아래 [Mermaid 렌더링 옵션](#mermaid-렌더링-옵션)을 참고하세요. |
|
|
395
398
|
|
|
396
399
|
MikroORM config를 비동기적으로 만들어야 한다면 직접 resolve한 뒤 결과 options object를 전달하세요:
|
|
397
400
|
|
|
@@ -400,6 +403,56 @@ const ormConfig = await createOrmConfig();
|
|
|
400
403
|
const markdown = await generateMarkdown({ orm: ormConfig });
|
|
401
404
|
```
|
|
402
405
|
|
|
406
|
+
### Mermaid 렌더링 옵션
|
|
407
|
+
|
|
408
|
+
기본적으로 mikro-orm-markdown은 Mermaid frontmatter config를 출력하지 않습니다. 이렇게 해야 각 Markdown 뷰어의 기본 Mermaid 렌더링 동작이 유지됩니다.
|
|
409
|
+
|
|
410
|
+
CLI에서 Mermaid 렌더링 옵션을 사용하려면:
|
|
411
|
+
|
|
412
|
+
```bash
|
|
413
|
+
mikro-orm-markdown --config ./mikro-orm.config.ts --mermaid-layout elk
|
|
414
|
+
mikro-orm-markdown --config ./mikro-orm.config.ts --mermaid-theme forest
|
|
415
|
+
mikro-orm-markdown --config ./mikro-orm.config.ts --mermaid-layout elk --mermaid-theme neutral
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
프로그래밍 API에서는:
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
const markdown = await generateMarkdown({
|
|
422
|
+
orm: ormConfig,
|
|
423
|
+
mermaid: {
|
|
424
|
+
layout: 'elk',
|
|
425
|
+
theme: 'forest',
|
|
426
|
+
},
|
|
427
|
+
});
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
layout 또는 theme을 지정하면 각 `erDiagram` 펜스 앞에 YAML frontmatter 블록이 삽입됩니다:
|
|
431
|
+
|
|
432
|
+
````markdown
|
|
433
|
+
```mermaid
|
|
434
|
+
---
|
|
435
|
+
config:
|
|
436
|
+
layout: elk
|
|
437
|
+
theme: forest
|
|
438
|
+
---
|
|
439
|
+
erDiagram
|
|
440
|
+
...
|
|
441
|
+
```
|
|
442
|
+
````
|
|
443
|
+
|
|
444
|
+
**사용 가능한 layout 값:**
|
|
445
|
+
|
|
446
|
+
| 값 | 설명 |
|
|
447
|
+
| -- | ---- |
|
|
448
|
+
| `dagre` | Mermaid 기본 레이아웃 엔진. |
|
|
449
|
+
| `elk` | 대체 레이아웃 엔진. 엔티티가 많거나 관계선이 복잡한 ERD에서 선 라우팅을 개선할 수 있습니다. |
|
|
450
|
+
| `elk.stress` | ELK stress 레이아웃 변형. Mermaid 버전과 뷰어에 따라 지원 여부가 다릅니다. |
|
|
451
|
+
|
|
452
|
+
**사용 가능한 theme 값:** `default`, `neutral`, `dark`, `forest`, `base`.
|
|
453
|
+
|
|
454
|
+
> `elk`와 theme 지원 여부는 뷰어마다 다릅니다. `--mermaid-layout`이나 `--mermaid-theme`을 지정하지 않으면 frontmatter는 출력되지 않습니다.
|
|
455
|
+
|
|
403
456
|
## 라이선스
|
|
404
457
|
|
|
405
458
|
MIT
|
package/README.md
CHANGED
|
@@ -79,6 +79,8 @@ npm run erd
|
|
|
79
79
|
| `-d, --description <string>` | — | Optional description paragraph shown below the title |
|
|
80
80
|
| `--tsconfig <path>` | — | `tsconfig.json` used when loading a `.ts` config; defaults to the nearest one beside the config file |
|
|
81
81
|
| `--src <paths...>` | — | Original TypeScript entity source paths/globs; only needed when MikroORM discovers entities from compiled JavaScript |
|
|
82
|
+
| `--mermaid-layout <layout>` | — | Mermaid layout engine (`dagre\|elk\|elk.stress`). Omit to use the viewer's default. |
|
|
83
|
+
| `--mermaid-theme <theme>` | — | Mermaid theme (`default\|neutral\|dark\|forest\|base`). Omit to use the viewer's default. |
|
|
82
84
|
|
|
83
85
|
> For a long or multiline description, use the [programmatic API](#programmatic-api) instead — it accepts any string directly, without shell quoting limits.
|
|
84
86
|
|
|
@@ -392,6 +394,7 @@ Programmatic options:
|
|
|
392
394
|
| `description` | Optional paragraph below the title. Unlike the CLI flag, this can be any string without shell quoting concerns. |
|
|
393
395
|
| `src` | Original TypeScript entity source paths/globs. Only needed when `orm.entities` discovers compiled JavaScript. |
|
|
394
396
|
| `onWarn` | Callback for non-fatal warnings, such as compiled JavaScript JSDoc loss. |
|
|
397
|
+
| `mermaid` | Optional Mermaid rendering options. See [Mermaid rendering options](#mermaid-rendering-options) below. |
|
|
395
398
|
|
|
396
399
|
If your MikroORM config is asynchronous, resolve it yourself and pass the resulting options object:
|
|
397
400
|
|
|
@@ -400,6 +403,56 @@ const ormConfig = await createOrmConfig();
|
|
|
400
403
|
const markdown = await generateMarkdown({ orm: ormConfig });
|
|
401
404
|
```
|
|
402
405
|
|
|
406
|
+
### Mermaid rendering options
|
|
407
|
+
|
|
408
|
+
By default, mikro-orm-markdown does not emit Mermaid frontmatter config. This preserves each Markdown viewer's default Mermaid rendering behavior.
|
|
409
|
+
|
|
410
|
+
You can opt into Mermaid rendering options via the CLI:
|
|
411
|
+
|
|
412
|
+
```bash
|
|
413
|
+
mikro-orm-markdown --config ./mikro-orm.config.ts --mermaid-layout elk
|
|
414
|
+
mikro-orm-markdown --config ./mikro-orm.config.ts --mermaid-theme forest
|
|
415
|
+
mikro-orm-markdown --config ./mikro-orm.config.ts --mermaid-layout elk --mermaid-theme neutral
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
Or via the programmatic API:
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
const markdown = await generateMarkdown({
|
|
422
|
+
orm: ormConfig,
|
|
423
|
+
mermaid: {
|
|
424
|
+
layout: 'elk',
|
|
425
|
+
theme: 'forest',
|
|
426
|
+
},
|
|
427
|
+
});
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
When a layout or theme is set, a YAML frontmatter block is prepended to each `erDiagram` fence:
|
|
431
|
+
|
|
432
|
+
````markdown
|
|
433
|
+
```mermaid
|
|
434
|
+
---
|
|
435
|
+
config:
|
|
436
|
+
layout: elk
|
|
437
|
+
theme: forest
|
|
438
|
+
---
|
|
439
|
+
erDiagram
|
|
440
|
+
...
|
|
441
|
+
```
|
|
442
|
+
````
|
|
443
|
+
|
|
444
|
+
**Available layout values:**
|
|
445
|
+
|
|
446
|
+
| Value | Description |
|
|
447
|
+
| ----- | ----------- |
|
|
448
|
+
| `dagre` | Mermaid's default layered layout. |
|
|
449
|
+
| `elk` | Alternative layout engine; can improve line routing on larger or denser ERDs. |
|
|
450
|
+
| `elk.stress` | ELK stress layout variant. Support varies by Mermaid version and viewer. |
|
|
451
|
+
|
|
452
|
+
**Available theme values:** `default`, `neutral`, `dark`, `forest`, `base`.
|
|
453
|
+
|
|
454
|
+
> Viewer support for `elk` and theme values varies. If no `--mermaid-layout` or `--mermaid-theme` is provided, no frontmatter is emitted.
|
|
455
|
+
|
|
403
456
|
## License
|
|
404
457
|
|
|
405
458
|
MIT
|
package/dist/cli.cjs
CHANGED
|
@@ -281,6 +281,8 @@ function toMarkdownAnchor(value) {
|
|
|
281
281
|
}
|
|
282
282
|
|
|
283
283
|
// src/render/mermaid.ts
|
|
284
|
+
var MERMAID_LAYOUTS = ["dagre", "elk", "elk.stress"];
|
|
285
|
+
var MERMAID_THEMES = ["default", "neutral", "dark", "forest", "base"];
|
|
284
286
|
var FORMULA_DUMMY_TABLE = {
|
|
285
287
|
alias: "e0",
|
|
286
288
|
name: "",
|
|
@@ -567,8 +569,19 @@ function normalizeType(type) {
|
|
|
567
569
|
}
|
|
568
570
|
return type;
|
|
569
571
|
}
|
|
570
|
-
function renderErDiagram(model) {
|
|
571
|
-
const lines = [
|
|
572
|
+
function renderErDiagram(model, mermaid) {
|
|
573
|
+
const lines = [];
|
|
574
|
+
if (mermaid?.layout !== void 0 || mermaid?.theme !== void 0) {
|
|
575
|
+
lines.push("---", "config:");
|
|
576
|
+
if (mermaid.layout !== void 0) {
|
|
577
|
+
lines.push(` layout: ${mermaid.layout}`);
|
|
578
|
+
}
|
|
579
|
+
if (mermaid.theme !== void 0) {
|
|
580
|
+
lines.push(` theme: ${mermaid.theme}`);
|
|
581
|
+
}
|
|
582
|
+
lines.push("---");
|
|
583
|
+
}
|
|
584
|
+
lines.push("erDiagram");
|
|
572
585
|
for (const entity of model.entities) {
|
|
573
586
|
lines.push(` ${toMermaidIdentifier(entity.className)} {`);
|
|
574
587
|
for (const col of entity.columns) {
|
|
@@ -787,7 +800,7 @@ async function withTsMorphMetadataProvider(options, onWarn) {
|
|
|
787
800
|
}
|
|
788
801
|
|
|
789
802
|
// src/render/markdown.ts
|
|
790
|
-
function renderMarkdown(docModel) {
|
|
803
|
+
function renderMarkdown(docModel, mermaid) {
|
|
791
804
|
const sections = [`# ${escapeMarkdownInline(docModel.title)}`];
|
|
792
805
|
if (docModel.description) {
|
|
793
806
|
sections.push(escapeMarkdownParagraph(docModel.description));
|
|
@@ -796,7 +809,7 @@ function renderMarkdown(docModel) {
|
|
|
796
809
|
sections.push(renderTableOfContents(docModel.groups));
|
|
797
810
|
}
|
|
798
811
|
for (const group of docModel.groups) {
|
|
799
|
-
sections.push(renderGroupSection(group));
|
|
812
|
+
sections.push(renderGroupSection(group, mermaid));
|
|
800
813
|
}
|
|
801
814
|
return sections.join("\n\n");
|
|
802
815
|
}
|
|
@@ -813,14 +826,14 @@ function renderTableOfContents(groups) {
|
|
|
813
826
|
return `- [${label}](#${toMarkdownAnchor(group.name)})`;
|
|
814
827
|
});
|
|
815
828
|
}
|
|
816
|
-
function renderGroupSection(group) {
|
|
829
|
+
function renderGroupSection(group, mermaid) {
|
|
817
830
|
const parts = [`## ${escapeMarkdownInline(group.name)}`];
|
|
818
831
|
if (group.erdEntities.length > 0) {
|
|
819
832
|
const diagramModel = {
|
|
820
833
|
entities: group.erdEntities.map((e) => e.model),
|
|
821
834
|
relations: group.erdRelations
|
|
822
835
|
};
|
|
823
|
-
parts.push("```mermaid\n" + renderErDiagram(diagramModel) + "\n```");
|
|
836
|
+
parts.push("```mermaid\n" + renderErDiagram(diagramModel, mermaid) + "\n```");
|
|
824
837
|
}
|
|
825
838
|
for (const entity of group.textEntities) {
|
|
826
839
|
parts.push(renderEntitySection(entity));
|
|
@@ -976,7 +989,7 @@ async function loadEntityMetadataWithTsMorphFallback(originalOrm, effectiveOrm)
|
|
|
976
989
|
}
|
|
977
990
|
}
|
|
978
991
|
async function generateMarkdown(options) {
|
|
979
|
-
const { orm, title = "Database Schema", description, src, onWarn } = options;
|
|
992
|
+
const { orm, title = "Database Schema", description, src, onWarn, mermaid } = options;
|
|
980
993
|
const effectiveOrm = await withTsMorphMetadataProvider(orm, onWarn);
|
|
981
994
|
const { metas, sourcePaths } = await loadEntityMetadataWithTsMorphFallback(orm, effectiveOrm);
|
|
982
995
|
const jsDocResult = loadJsDoc(resolveJsDocSources(sourcePaths, src, onWarn));
|
|
@@ -984,7 +997,7 @@ async function generateMarkdown(options) {
|
|
|
984
997
|
assertExplicitJsDocSourceCoverage(metas, jsDocResult, src, onWarn);
|
|
985
998
|
}
|
|
986
999
|
const docModel = buildDocumentModel(metas, jsDocResult, title, description, onWarn);
|
|
987
|
-
return renderMarkdown(docModel);
|
|
1000
|
+
return renderMarkdown(docModel, mermaid);
|
|
988
1001
|
}
|
|
989
1002
|
|
|
990
1003
|
// src/cli.ts
|
|
@@ -1099,9 +1112,34 @@ async function writeMarkdownFile(outPath, markdown) {
|
|
|
1099
1112
|
${formatFileSystemError(cause)}`, { cause });
|
|
1100
1113
|
}
|
|
1101
1114
|
}
|
|
1115
|
+
function parseMermaidOptions(opts) {
|
|
1116
|
+
const { mermaidLayout, mermaidTheme } = opts;
|
|
1117
|
+
if (mermaidLayout !== void 0 && !MERMAID_LAYOUTS.includes(mermaidLayout)) {
|
|
1118
|
+
process.stderr.write(
|
|
1119
|
+
`Error: Invalid --mermaid-layout "${mermaidLayout}". Allowed values: ${MERMAID_LAYOUTS.join(", ")}
|
|
1120
|
+
`
|
|
1121
|
+
);
|
|
1122
|
+
process.exit(1);
|
|
1123
|
+
}
|
|
1124
|
+
if (mermaidTheme !== void 0 && !MERMAID_THEMES.includes(mermaidTheme)) {
|
|
1125
|
+
process.stderr.write(
|
|
1126
|
+
`Error: Invalid --mermaid-theme "${mermaidTheme}". Allowed values: ${MERMAID_THEMES.join(", ")}
|
|
1127
|
+
`
|
|
1128
|
+
);
|
|
1129
|
+
process.exit(1);
|
|
1130
|
+
}
|
|
1131
|
+
if (mermaidLayout === void 0 && mermaidTheme === void 0) {
|
|
1132
|
+
return void 0;
|
|
1133
|
+
}
|
|
1134
|
+
return {
|
|
1135
|
+
...mermaidLayout !== void 0 && { layout: mermaidLayout },
|
|
1136
|
+
...mermaidTheme !== void 0 && { theme: mermaidTheme }
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1102
1139
|
async function run(opts) {
|
|
1103
1140
|
const configPath = path2.resolve(opts.config);
|
|
1104
1141
|
const outPath = path2.resolve(opts.out);
|
|
1142
|
+
const mermaid = parseMermaidOptions(opts);
|
|
1105
1143
|
let ormOptions;
|
|
1106
1144
|
try {
|
|
1107
1145
|
ormOptions = await loadOrmOptions(configPath, opts.tsconfig);
|
|
@@ -1120,6 +1158,7 @@ ${err instanceof Error ? err.message : String(err)}
|
|
|
1120
1158
|
title: opts.title,
|
|
1121
1159
|
...opts.description !== void 0 && { description: opts.description },
|
|
1122
1160
|
...opts.src !== void 0 && { src: opts.src },
|
|
1161
|
+
...mermaid !== void 0 && { mermaid },
|
|
1123
1162
|
onWarn: (message) => void process.stderr.write(`Warning: ${message}
|
|
1124
1163
|
`)
|
|
1125
1164
|
});
|
|
@@ -1144,7 +1183,7 @@ var program = new import_commander.Command().name("mikro-orm-markdown").descript
|
|
|
1144
1183
|
).option(
|
|
1145
1184
|
"--src <paths...>",
|
|
1146
1185
|
"Source .ts file globs to read JSDoc from when entities run from compiled .js (comments are stripped at build time)"
|
|
1147
|
-
).action(run);
|
|
1186
|
+
).option("--mermaid-layout <layout>", `Mermaid layout engine injected as frontmatter (${MERMAID_LAYOUTS.join("|")})`).option("--mermaid-theme <theme>", `Mermaid theme injected as frontmatter (${MERMAID_THEMES.join("|")})`).action(run);
|
|
1148
1187
|
function isDirectCliExecution() {
|
|
1149
1188
|
const entryPoint = process.argv[1];
|
|
1150
1189
|
if (entryPoint === void 0) {
|