mikro-orm-markdown 0.1.0-alpha.2 → 0.1.0-alpha.3
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 +53 -0
- package/CODE_OF_CONDUCT.md +25 -0
- package/LICENSE +1 -1
- package/README.ko.md +248 -41
- package/README.md +248 -41
- package/SECURITY.md +28 -0
- package/dist/cli.cjs +670 -134
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +51 -0
- package/dist/cli.d.ts +51 -0
- package/dist/cli.js +650 -136
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +500 -119
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -17
- package/dist/index.d.ts +21 -17
- package/dist/index.js +489 -119
- package/dist/index.js.map +1 -1
- package/package.json +30 -6
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,59 @@ 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.3] - 2026-06-29
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `--tsconfig <path>` CLI option to override the tsconfig used when loading a `.ts` config
|
|
13
|
+
- `--src <paths...>` CLI option and `src` programmatic option to read JSDoc from the original `.ts` sources when entities run from compiled JavaScript
|
|
14
|
+
- Actual DB table name shown under each entity heading (`*Table: \`name\`*`)
|
|
15
|
+
- `@Enum` allowed values listed in the column description (`One of: ...`)
|
|
16
|
+
- STI child discriminator value shown in the Extends note
|
|
17
|
+
- End-to-end smoke test running the built CLI from the repo root (plus a CI step)
|
|
18
|
+
- Type-omitted properties (e.g. `@Property() name: string`) are now documented: when the config picks no metadata provider and `@mikro-orm/reflection` is installed, both the CLI and the programmatic API auto-use `TsMorphMetadataProvider` to read types from your TypeScript sources
|
|
19
|
+
- `.ts` configs default to `preferTs: true`, so MikroORM discovers your `entitiesTs` sources without extra config
|
|
20
|
+
- `npm pack` smoke test (`test:pack`) that installs the built tarball into a temporary project
|
|
21
|
+
- Metadata discovery smoke tests for SQLite, PostgreSQL, MySQL, and MariaDB drivers
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- Auto-applying `TsMorphMetadataProvider` no longer breaks explicit-type runtime/JavaScript entity configs when TypeScript source files are unavailable; generation falls back to MikroORM's default provider if the auto provider cannot find source files and the original config can still discover metadata
|
|
26
|
+
- `.ts` config loading no longer depends on the current working directory — the tsconfig beside the config file is resolved and passed to `tsx`
|
|
27
|
+
- Discovery failures now surface the underlying cause (missing driver, bad entities glob, …) instead of only a generic message
|
|
28
|
+
- Parameterized SQL types (e.g. `varchar(255)`) are preserved in the markdown table instead of being sanitized
|
|
29
|
+
- Non-abstract STI roots are classified correctly, no longer leaking subclass columns
|
|
30
|
+
- `object: true` / `array: true` embeddeds render as a single JSON column
|
|
31
|
+
- Non-string `@Formula` return values no longer crash rendering
|
|
32
|
+
- `loadJsDoc` never throws on an unreadable source file
|
|
33
|
+
- A warning is emitted when `@atLeastOne` cannot be matched to a relation edge
|
|
34
|
+
- FK columns referencing a `@hidden` entity are dropped instead of dangling
|
|
35
|
+
- Guarded against missing `prop.type` / `prop.fieldNames` during rendering
|
|
36
|
+
- Discovery failures from missing decorator metadata now explain that the CLI's `tsx` loader cannot honor `emitDecoratorMetadata`, pointing at `@mikro-orm/reflection` or explicit `type:`/`entity:` attributes
|
|
37
|
+
- Config default exports are validated to be a plain object (primitives and arrays are rejected with a clear message)
|
|
38
|
+
- Abstract STI parent entities are no longer flagged as errors when `--src` does not cover their source file; a warning is now emitted instead, explaining that `@hidden`/`@namespace` tags will not apply
|
|
39
|
+
- `@mikro-orm/reflection` load failures (e.g. version mismatch) now emit a warning via the `onWarn` callback instead of writing directly to `process.stderr`
|
|
40
|
+
- Metadata cache (`temp/`) is now always disabled during doc generation regardless of which `metadataProvider` is in use, so `temp/` is never created
|
|
41
|
+
|
|
42
|
+
### Changed
|
|
43
|
+
|
|
44
|
+
- Driver-support wording clarified around metadata-based generation and automated SQL driver smoke coverage
|
|
45
|
+
- `@Formula` computed columns now render as nullable
|
|
46
|
+
- Index and unique constraint properties in the generated document now show actual DB column names (mapped through NamingStrategy) instead of TypeScript property names
|
|
47
|
+
- Metadata cache is always disabled for doc generation runs; a user-supplied `metadataCache: { enabled: true }` in the MikroORM config is intentionally overridden to prevent `temp/` from being created
|
|
48
|
+
|
|
49
|
+
## [0.1.0-alpha.2] - 2026-06-15
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
|
|
53
|
+
- Metadata discovery no longer opens a database connection
|
|
54
|
+
- CLI `--src` option help text was cleaned up
|
|
55
|
+
|
|
56
|
+
### Changed
|
|
57
|
+
|
|
58
|
+
- Added tag-based npm release automation and repository contribution templates
|
|
59
|
+
- Migrated linting and formatting setup to Biome
|
|
60
|
+
|
|
8
61
|
## [0.1.0-alpha.1] - 2026-06-11
|
|
9
62
|
|
|
10
63
|
### Added
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Standards
|
|
4
|
+
|
|
5
|
+
This project aims to be a respectful and practical space for users and contributors.
|
|
6
|
+
|
|
7
|
+
Examples of expected behavior:
|
|
8
|
+
|
|
9
|
+
- Use welcoming and inclusive language
|
|
10
|
+
- Respect differing viewpoints and experience levels
|
|
11
|
+
- Give constructive feedback focused on the work
|
|
12
|
+
- Report bugs with enough detail to help reproduce them
|
|
13
|
+
|
|
14
|
+
Examples of unacceptable behavior:
|
|
15
|
+
|
|
16
|
+
- Harassment, insults, or discriminatory language
|
|
17
|
+
- Personal attacks or sustained disruption
|
|
18
|
+
- Publishing private information without permission
|
|
19
|
+
- Sharing security exploit details in public issues
|
|
20
|
+
|
|
21
|
+
## Enforcement
|
|
22
|
+
|
|
23
|
+
Project maintainers may remove comments, close issues, or block participants when behavior harms the project or its community.
|
|
24
|
+
|
|
25
|
+
If you need to report a conduct issue, contact the maintainer privately where possible. If no private channel is available, open a brief public issue asking for a private contact path without including sensitive details.
|
package/LICENSE
CHANGED
package/README.ko.md
CHANGED
|
@@ -10,25 +10,35 @@
|
|
|
10
10
|
|
|
11
11
|
> [@samchon](https://github.com/samchon)의 [prisma-markdown](https://github.com/samchon/prisma-markdown)에서 큰 영감을 받았습니다. 좋은 아이디어에 감사드립니다.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
## 주요 기능
|
|
14
14
|
|
|
15
|
-
- **
|
|
16
|
-
- **
|
|
17
|
-
-
|
|
15
|
+
- **Mermaid ERD 다이어그램** — MikroORM 엔티티 메타데이터에서 생성합니다
|
|
16
|
+
- **Markdown 스키마 문서** — 엔티티별 컬럼 테이블, 실제 DB 컬럼명, 키, nullable 여부, 설명, 인덱스, 제약 조건을 포함합니다
|
|
17
|
+
- **JSDoc 기반 그룹화 및 노출 제어** — `@namespace`, `@erd`, `@describe`, `@hidden`을 사용합니다
|
|
18
|
+
- **실행 중인 DB 연결 불필요** — MikroORM config의 메타데이터 discovery를 사용합니다
|
|
19
|
+
- **일반적인 SQL 드라이버 지원** — SQLite, PostgreSQL, MySQL, MariaDB smoke test로 검증합니다
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
### MikroORM 고유 개념
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
Prisma 기반 도구로는 표현할 수 없는 MikroORM 고유 개념도 함께 시각화합니다.
|
|
24
|
+
|
|
25
|
+
- **Embeddable** — 소유 엔티티의 테이블 안에 저장되는 값 객체입니다. `@Embedded` 옵션에 따라 펼쳐진 컬럼(예: `address_street`, `address_city`) 또는 JSON 컬럼으로 저장됩니다. 별도 테이블은 생성되지 않습니다.
|
|
26
|
+
- **Single Table Inheritance (STI)** — `Dog`, `Cat` 같은 자식 클래스가 `animals` 테이블 하나를 공유합니다. `type` 같은 discriminator 컬럼으로 어떤 자식 클래스인지 구분합니다.
|
|
27
|
+
- **@Formula** — 실제 DB 컬럼 없이 SELECT 시 SQL 식으로 값을 계산하는 가상 컬럼입니다. 예를 들어 `LENGTH(name)`은 DB에 컬럼이 없지만 조회 시 이름의 길이를 반환합니다.
|
|
23
28
|
|
|
24
|
-
|
|
29
|
+
> 이들은 MikroORM의 일급 기능이지만, 모든 프로젝트에서 전부 사용하는 것은 아닙니다. `Embeddable`은 `Address`를 `address_*` 컬럼이나 JSON으로 저장하는 값 객체에 특히 유용하며, 여러 엔티티가 같은 컬럼 묶음을 공유할 때 중복을 줄이는 데에도 사용할 수 있습니다.
|
|
25
30
|
|
|
26
31
|
## 요구사항
|
|
27
32
|
|
|
28
|
-
- Node.js >= 18
|
|
29
|
-
- `@mikro-orm/core
|
|
30
|
-
-
|
|
31
|
-
-
|
|
33
|
+
- **Node.js >= 18**
|
|
34
|
+
- **MikroORM >= 6** — `@mikro-orm/core`는 peer dependency입니다.
|
|
35
|
+
- **MikroORM config 파일** — CLI는 plain MikroORM options object를 default export로 내보내는 파일을 기대합니다.
|
|
36
|
+
- **사용할 DB에 맞는 MikroORM 드라이버 패키지** — 예를 들어 `@mikro-orm/postgresql`, `@mikro-orm/mysql`, `@mikro-orm/mariadb`, `@mikro-orm/sqlite`가 있습니다. 실행 중인 DB 연결은 필요 없지만, MikroORM이 메타데이터를 discovery하려면 드라이버는 필요합니다.
|
|
37
|
+
- **데코레이터 기반 엔티티** — 엔티티는 `@Entity()` 클래스여야 합니다. `EntitySchema`로 정의한 엔티티는 현재 지원하지 않습니다.
|
|
38
|
+
- **해석 가능한 프로퍼티 타입** — 각 엔티티 프로퍼티의 타입은 MikroORM discovery 시점에 알려져야 합니다. `type:` / `entity:` 같은 명시적인 데코레이터 옵션을 사용하거나, `@mikro-orm/reflection`을 설치해 CLI가 TypeScript 소스에 대해 `TsMorphMetadataProvider`를 자동으로 사용하게 하세요.
|
|
39
|
+
- **TypeScript config 파일을 위한 `tsx`** — CLI에서 `.ts` MikroORM config를 로드할 때만 필요합니다. `.js` config 파일에는 필요하지 않습니다.
|
|
40
|
+
|
|
41
|
+
> `@mikro-orm/reflection`을 설치한다면 **`@mikro-orm/core`와 정확히 같은 버전**으로 맞추세요. MikroORM은 공식 `@mikro-orm/*` 패키지들이 하나의 버전을 공유한다고 기대하며, 버전이 다르면 discovery가 실패할 수 있습니다.
|
|
32
42
|
|
|
33
43
|
## 설치
|
|
34
44
|
|
|
@@ -40,25 +50,18 @@ pnpm add -D mikro-orm-markdown
|
|
|
40
50
|
|
|
41
51
|
## 빠른 시작
|
|
42
52
|
|
|
43
|
-
`package.json`에 스크립트를
|
|
53
|
+
`package.json`에 스크립트를 추가하고, `--config`에 MikroORM config 파일 경로를 지정하세요:
|
|
44
54
|
|
|
45
55
|
```json
|
|
46
56
|
{
|
|
47
57
|
"scripts": {
|
|
48
|
-
"erd": "mikro-orm-markdown --config ./mikro-orm.config.
|
|
58
|
+
"erd": "mikro-orm-markdown --config ./mikro-orm.config.ts --out ./ERD.md --title 'My Database'"
|
|
49
59
|
}
|
|
50
60
|
}
|
|
51
61
|
```
|
|
52
62
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
```json
|
|
56
|
-
{
|
|
57
|
-
"scripts": {
|
|
58
|
-
"erd": "tsx ./node_modules/.bin/mikro-orm-markdown --config ./mikro-orm.config.ts --out ./ERD.md --title 'My Database' --src 'src/entities/**/*.ts'"
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
```
|
|
63
|
+
- **`.ts` config** — `tsx`를 devDependency로 설치하세요 (`npm install -D tsx`). CLI가 자동으로 로드하며, `preferTs`를 명시하지 않았다면 MikroORM discovery가 `entitiesTs`를 우선 사용하도록 설정합니다.
|
|
64
|
+
- **`.js` config** — 추가 패키지 불필요. 직접 작성한 파일이든, 빌드 결과물(예: `./dist/mikro-orm.config.js`)이든 상관없습니다.
|
|
62
65
|
|
|
63
66
|
이후에는 아래 명령어 하나로 실행합니다:
|
|
64
67
|
|
|
@@ -73,11 +76,17 @@ npm run erd
|
|
|
73
76
|
| `-c, --config <path>` | _(필수)_ | MikroORM 설정 파일 경로 |
|
|
74
77
|
| `-o, --out <path>` | `./ERD.md` | 출력 Markdown 파일 경로 |
|
|
75
78
|
| `-t, --title <string>` | `Database Schema` | 문서 H1 제목 |
|
|
76
|
-
| `-
|
|
79
|
+
| `-d, --description <string>` | — | 제목 아래에 표시할 설명 문단 (선택) |
|
|
80
|
+
| `--tsconfig <path>` | — | `.ts` config 로드 시 사용할 `tsconfig.json`; 기본값은 config 파일 근처의 가장 가까운 파일 |
|
|
81
|
+
| `--src <paths...>` | — | 원본 TypeScript 엔티티 소스 경로/glob; MikroORM이 컴파일된 JavaScript에서 엔티티를 discovery할 때만 필요 |
|
|
82
|
+
|
|
83
|
+
> 설명이 길거나 여러 줄이라면 CLI 대신 [프로그래밍 API](#프로그래밍-api)를 사용하세요 — 쉘 인용 부호 제약 없이 문자열을 그대로 전달할 수 있습니다.
|
|
77
84
|
|
|
78
85
|
## JSDoc 태그
|
|
79
86
|
|
|
80
|
-
엔티티 클래스에 JSDoc 태그를 추가해 문서의 섹션과 노출 여부를 제어합니다.
|
|
87
|
+
엔티티 클래스에 JSDoc 태그를 추가해 문서의 섹션과 노출 여부를 제어합니다. JSDoc 주석은 TypeScript 엔티티 소스 파일에서 읽습니다.
|
|
88
|
+
|
|
89
|
+
> **권장 설정:** `.ts` MikroORM config를 사용하고 `entitiesTs`가 소스 엔티티를 가리키게 하세요. 이 설정에서는 JSDoc을 원본 TypeScript 파일에서 읽으므로 `--src`가 필요하지 않습니다.
|
|
81
90
|
|
|
82
91
|
```typescript
|
|
83
92
|
/**
|
|
@@ -92,6 +101,8 @@ export class Post {
|
|
|
92
101
|
}
|
|
93
102
|
```
|
|
94
103
|
|
|
104
|
+
태그가 없는 일반 JSDoc 텍스트는 설명이 됩니다. **클래스** 위 텍스트는 엔티티 설명, **프로퍼티** 위 텍스트는 해당 컬럼 설명이 됩니다. 프로퍼티에 JSDoc이 없으면 `@Property({ comment })` 값(DDL 컬럼 코멘트)을 컬럼 설명으로 대신 사용합니다.
|
|
105
|
+
|
|
95
106
|
| 태그 | 설명 |
|
|
96
107
|
| ------------------- | ------------------------------------- |
|
|
97
108
|
| `@namespace <Name>` | `Name` 섹션에 포함 (ERD + 본문 표) |
|
|
@@ -102,14 +113,101 @@ export class Post {
|
|
|
102
113
|
태그가 없는 엔티티는 `default` 섹션에 들어갑니다.
|
|
103
114
|
하나의 엔티티에 여러 태그를 지정할 수 있습니다.
|
|
104
115
|
|
|
105
|
-
|
|
116
|
+
### 컴파일된 JavaScript 빌드
|
|
117
|
+
|
|
118
|
+
MikroORM config가 `entities: ['./dist/**/*.js']`처럼 컴파일된 `.js` 파일에서 엔티티를 discovery한다면, 엔티티 구조는 여전히 찾을 수 있지만 JSDoc 주석은 빌드 과정에서 제거되었을 수 있습니다.
|
|
119
|
+
|
|
120
|
+
이 경우 설명과 `@namespace`, `@hidden` 같은 태그를 해당 `.js` 파일에서 읽을 수 없습니다.
|
|
121
|
+
|
|
122
|
+
이 경우에만 `--src`를 사용하세요:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
mikro-orm-markdown \
|
|
126
|
+
--config ./dist/mikro-orm.config.js \
|
|
127
|
+
--src "src/**/*.entity.ts"
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
`--src`가 어떤 파일과도 매칭되지 않거나 발견된 엔티티 선언을 빠뜨리면, 불완전한 문서를 조용히 생성하는 대신 실패합니다.
|
|
131
|
+
|
|
132
|
+
### 관계 카디널리티: `@atLeastOne`
|
|
133
|
+
|
|
134
|
+
`@atLeastOne`은 TypeScript decorator가 아니라 JSDoc 태그입니다.
|
|
135
|
+
|
|
136
|
+
컬렉션 관계(`1:N` 또는 `M:N`)는 기본적으로 _0개 이상_으로 렌더링됩니다. 컬렉션 프로퍼티에 `@atLeastOne`를 붙이면 해당 컬렉션 쪽이 _1개 이상_으로 표시됩니다:
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
@Entity()
|
|
140
|
+
export class Author {
|
|
141
|
+
/** @atLeastOne */
|
|
142
|
+
@OneToMany(() => Post, (post) => post.author)
|
|
143
|
+
posts = new Collection<Post>(this);
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
이렇게 하면 ERD 관계선이 `Post }o--|| Author`에서 `Post }|--|| Author`로 바뀝니다. 이는 문서용 힌트일 뿐이며 — MikroORM에는 스키마 레벨의 최소 개수 개념이 없어 실제로 강제되지는 않습니다. (Mermaid는 0개 이상 / 1개 이상만 구분하므로 그보다 큰 최소값은 표현할 수 없습니다.)
|
|
148
|
+
|
|
149
|
+
하나의 관계선은 **양 끝이 따로 결정**됩니다:
|
|
150
|
+
|
|
151
|
+
- **단수(1) 쪽** (`@ManyToOne`, 또는 소유 측 `@OneToOne`) — 스키마에서 자동으로 읽으며 태그가 필요 없습니다: 기본 _정확히 1_ (`||`), `nullable: true`이면 _0 또는 1_ (`o|`).
|
|
152
|
+
- **컬렉션(N) 쪽** (`@OneToMany` / `@ManyToMany`) — 기본 _0개 이상_이며, `@atLeastOne`을 붙이면 해당 쪽이 _1개 이상_으로 바뀝니다. Mermaid에서는 컬렉션이 렌더링되는 방향에 따라 `}o` → `}|` 또는 `o{` → `|{`를 사용합니다.
|
|
153
|
+
|
|
154
|
+
네 가지 조합 (`Post` ↔ `Author`):
|
|
155
|
+
|
|
156
|
+
```text
|
|
157
|
+
Post }o--|| Author → 작성자 글 0개+, 글은 작성자 정확히 1명 (기본)
|
|
158
|
+
Post }o--o| Author → 작성자 글 0개+, 글은 작성자 0~1명 (nullable: true)
|
|
159
|
+
Post }|--|| Author → 작성자 글 1개+, 글은 작성자 정확히 1명 (@atLeastOne)
|
|
160
|
+
Post }|--o| Author → 작성자 글 1개+, 글은 작성자 0~1명 (둘 다)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
> **NestJS Swagger Plugin**: `@namespace`, `@erd`, `@describe`, `@hidden`, `@atLeastOne`은 `mikro-orm-markdown`용 커스텀 태그입니다. NestJS Swagger는 이 태그들을 OpenAPI 메타데이터로 사용하지 않습니다. 엔티티 클래스를 DTO로 직접 사용하고 Swagger comment introspection을 켠 경우, 일반 JSDoc 설명은 Swagger 문서에도 표시될 수 있지만 이 커스텀 태그들이 기능적인 충돌을 만들지는 않습니다.
|
|
106
164
|
|
|
107
165
|
## 출력 예시
|
|
108
166
|
|
|
109
|
-
|
|
167
|
+
다음과 같은 엔티티가 있다고 가정합니다:
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
/**
|
|
171
|
+
* 등록된 사용자가 작성한 블로그 게시글입니다.
|
|
172
|
+
* @namespace Blog
|
|
173
|
+
*/
|
|
174
|
+
@Entity()
|
|
175
|
+
export class Post {
|
|
176
|
+
@PrimaryKey({ type: 'integer' })
|
|
177
|
+
id!: number;
|
|
178
|
+
|
|
179
|
+
/** 게시글 제목 */
|
|
180
|
+
@Property({ type: 'string' })
|
|
181
|
+
title!: string;
|
|
182
|
+
|
|
183
|
+
@Property({ type: 'text', nullable: true })
|
|
184
|
+
body?: string;
|
|
185
|
+
|
|
186
|
+
@ManyToOne({ entity: () => Author })
|
|
187
|
+
author!: Author;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/** @namespace Blog */
|
|
191
|
+
@Entity()
|
|
192
|
+
export class Author {
|
|
193
|
+
@PrimaryKey({ type: 'integer' })
|
|
194
|
+
id!: number;
|
|
195
|
+
|
|
196
|
+
@Property({ type: 'string' })
|
|
197
|
+
name!: string;
|
|
198
|
+
|
|
199
|
+
@Property({ type: 'string', unique: true })
|
|
200
|
+
email!: string;
|
|
201
|
+
|
|
202
|
+
/** @atLeastOne */
|
|
203
|
+
@OneToMany({ entity: () => Post, mappedBy: 'author' })
|
|
204
|
+
posts = new Collection<Post>(this);
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
> **예시 참고:** import 문은 간결성을 위해 생략했습니다. 이 예시는 별도 reflection 설정 없이 동작하도록 `type:`을 명시합니다. `@mikro-orm/reflection`이 설치되어 있다면 MikroORM은 `@Property() title!: string` 같은 단순 scalar 타입도 discovery할 수 있습니다.
|
|
110
209
|
|
|
111
|
-
|
|
112
|
-
## Blog
|
|
210
|
+
두 엔티티 모두 `@namespace Blog` 태그를 가지므로 하나의 `## Blog` 섹션에 묶입니다. MikroORM의 기본 naming strategy를 기준으로 생성된 `ERD.md`에는 다음과 같은 ERD가 포함됩니다:
|
|
113
211
|
|
|
114
212
|
```mermaid
|
|
115
213
|
erDiagram
|
|
@@ -117,18 +215,41 @@ erDiagram
|
|
|
117
215
|
integer id PK
|
|
118
216
|
string title
|
|
119
217
|
text body
|
|
120
|
-
integer author_id FK
|
|
218
|
+
integer author_id FK
|
|
121
219
|
}
|
|
122
220
|
Author {
|
|
123
221
|
integer id PK
|
|
124
222
|
string name
|
|
125
223
|
string email UK
|
|
126
224
|
}
|
|
127
|
-
Post }
|
|
225
|
+
Post }|--|| Author : "author"
|
|
128
226
|
```
|
|
129
227
|
|
|
228
|
+
**코드가 출력으로 어떻게 매핑되는가:**
|
|
229
|
+
|
|
230
|
+
- `@namespace Blog` → 두 엔티티가 `## Blog` 섹션 아래로 묶임
|
|
231
|
+
- `@ManyToOne({ entity: () => Author })` → `Post`에서 `Author`로 향하는 관계선과 `author_id FK` 컬럼
|
|
232
|
+
- `Author.posts`의 `@atLeastOne` → 컬렉션 쪽이 1개 이상으로 렌더링됨: `Post }|--|| Author`
|
|
233
|
+
- `email`의 `unique: true` → `email`이 `UK`(unique key)로 표시됨
|
|
234
|
+
- `body`의 `@Property({ nullable: true })` → `Nullable` 칸이 `Y`로 표시됨
|
|
235
|
+
- `/** 게시글 제목 */` → `title`의 **Description** 칸을 채움
|
|
236
|
+
|
|
237
|
+
**키 표기:**
|
|
238
|
+
|
|
239
|
+
| 표기 | 의미 |
|
|
240
|
+
| ---- | ---- |
|
|
241
|
+
| `PK` | Primary key |
|
|
242
|
+
| `FK` | Foreign key |
|
|
243
|
+
| `UK` | Unique key |
|
|
244
|
+
| `Nullable`의 `Y` | nullable 컬럼 |
|
|
245
|
+
|
|
246
|
+
각 엔티티는 컬럼 표로도 표현됩니다. 예를 들어 생성된 `Post` 섹션은 다음과 같습니다:
|
|
247
|
+
|
|
248
|
+
```markdown
|
|
130
249
|
### Post
|
|
131
250
|
|
|
251
|
+
*Table: `post`*
|
|
252
|
+
|
|
132
253
|
> 등록된 사용자가 작성한 블로그 게시글입니다.
|
|
133
254
|
|
|
134
255
|
| Column | Type | Key | Nullable | Description |
|
|
@@ -137,13 +258,13 @@ erDiagram
|
|
|
137
258
|
| title | string | | | 게시글 제목 |
|
|
138
259
|
| body | text | | Y | |
|
|
139
260
|
| author_id | integer | FK (author) | | |
|
|
140
|
-
|
|
261
|
+
```
|
|
141
262
|
|
|
142
|
-
|
|
263
|
+
**생성 결과의 MikroORM 전용 표기 의미:**
|
|
143
264
|
|
|
144
265
|
| 표기 | 의미 |
|
|
145
266
|
| ------------------ | -------------------------------------------- |
|
|
146
|
-
| `formula: <expr>` | `@Formula` 계산
|
|
267
|
+
| `formula: <expr>` | `@Formula` 계산 컬럼의 Mermaid 주석 |
|
|
147
268
|
| `[EmbeddableType]` | `@Embedded` 값 객체에서 flat으로 저장된 컬럼 |
|
|
148
269
|
| `discriminator` | STI 구분자 컬럼 |
|
|
149
270
|
|
|
@@ -156,23 +277,91 @@ STI는 여러 엔티티 클래스가 하나의 DB 테이블을 공유하는 패
|
|
|
156
277
|
```typescript
|
|
157
278
|
@Entity({ discriminatorColumn: 'type', abstract: true })
|
|
158
279
|
export class Animal {
|
|
159
|
-
@PrimaryKey()
|
|
280
|
+
@PrimaryKey({ type: 'integer' })
|
|
160
281
|
id!: number;
|
|
161
282
|
|
|
162
|
-
@Property()
|
|
283
|
+
@Property({ type: 'string' })
|
|
163
284
|
name!: string;
|
|
164
285
|
}
|
|
165
286
|
|
|
166
287
|
@Entity({ discriminatorValue: 'dog' })
|
|
167
288
|
export class Dog extends Animal {
|
|
168
|
-
@Property({ nullable: true })
|
|
289
|
+
@Property({ type: 'string', nullable: true })
|
|
169
290
|
breed?: string;
|
|
170
291
|
}
|
|
171
292
|
```
|
|
172
293
|
|
|
173
|
-
엔티티에 `discriminatorColumn`이 설정되어 있으면 `mikro-orm-markdown`이 자동으로
|
|
294
|
+
엔티티에 `discriminatorColumn`이 설정되어 있으면 `mikro-orm-markdown`이 자동으로 감지합니다. 서브클래스들은 물리적으로 하나의 테이블을 공유하지만, 다이어그램에서는 **각 클래스가 별도 박스**로 그려져 서브클래스마다 실제 컬럼 구성을 보여줍니다:
|
|
295
|
+
|
|
296
|
+
```mermaid
|
|
297
|
+
erDiagram
|
|
298
|
+
Animal {
|
|
299
|
+
integer id PK
|
|
300
|
+
string name
|
|
301
|
+
string type "discriminator"
|
|
302
|
+
}
|
|
303
|
+
Dog {
|
|
304
|
+
integer id PK
|
|
305
|
+
string name
|
|
306
|
+
string type
|
|
307
|
+
string breed
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
루트(`Animal`)는 공유 컬럼만 나열하고 discriminator(`type`)를 표시하며, 각 서브클래스(`Dog`)는 상속 컬럼을 반복한 뒤 자기 컬럼을 추가합니다.
|
|
312
|
+
|
|
313
|
+
생성된 Markdown 표에도 STI note가 함께 표시됩니다. 루트에는 `STI root — discriminator column: type`, 각 서브클래스에는 `Extends Animal (Single Table Inheritance, discriminator value: dog)` 같은 문구가 추가됩니다.
|
|
314
|
+
|
|
315
|
+
> **트레이드오프:** STI는 여러 엔티티 타입을 하나의 테이블에 보관할 수 있게 하지만, 쿼리 복잡도를 높이고 nullable 컬럼이 많이 생길 수 있습니다. 하나의 테이블을 공유하는 것이 모델의 의도일 때 사용하세요.
|
|
316
|
+
|
|
317
|
+
## 문제 해결
|
|
318
|
+
|
|
319
|
+
**"엔티티가 발견되지 않았습니다" (No entities were discovered)**
|
|
174
320
|
|
|
175
|
-
|
|
321
|
+
MikroORM config가 엔티티를 0개 찾은 경우입니다. 보통 CLI가 config를 로드하는 방식과 엔티티 경로가 맞지 않아 발생합니다.
|
|
322
|
+
|
|
323
|
+
- `.ts` config를 사용 중이라면(CLI가 `tsx`를 자동으로 로드하고 기본적으로 `preferTs: true`를 적용합니다), `entitiesTs`가 TypeScript 소스 파일을 가리키는지 확인하세요.
|
|
324
|
+
- 빌드된 `.js` config를 사용 중이라면, `entities`가 **빌드 결과물**(예: `./dist/**/*.entity.js`)을 가리키고 빌드를 먼저 실행했는지 확인하세요.
|
|
325
|
+
- MikroORM은 TypeScript 모드에서는 `entitiesTs`를, 그 외에는 `entities`를 사용합니다. 폴더/파일 기반 discovery를 쓴다면 두 옵션을 모두 지정하세요.
|
|
326
|
+
|
|
327
|
+
**"Please provide either 'type' or 'entity' attribute"**
|
|
328
|
+
|
|
329
|
+
MikroORM이 metadata discovery 중 프로퍼티 타입을 해석하지 못한 경우입니다. CLI는 `.ts` config를 `tsx`로 로드하므로, 이 경로에서는 `emitDecoratorMetadata`를 켜는 것만으로는 해결되지 않습니다.
|
|
330
|
+
|
|
331
|
+
다음 중 하나로 해결하세요:
|
|
332
|
+
|
|
333
|
+
- `@Property({ type: 'string' })`, `@ManyToOne({ entity: () => User })`처럼 데코레이터 옵션을 명시합니다.
|
|
334
|
+
- `@mikro-orm/reflection`을 `@mikro-orm/core`와 정확히 같은 버전으로 설치해 CLI가 `TsMorphMetadataProvider`를 자동으로 사용하게 합니다.
|
|
335
|
+
|
|
336
|
+
**"Cannot find module '@/...'" (경로 alias)**
|
|
337
|
+
|
|
338
|
+
config나 엔티티에서 `tsconfig`의 경로 alias(예: `@/entities/user`)를 사용한다면, `tsx`가 올바른 `tsconfig.json`을 찾지 못했을 때 alias를 해석하지 못할 수 있습니다. config 파일을 `tsconfig.json`과 같은 프로젝트 루트에 두면 이 문제를 피할 수 있습니다. config가 다른 위치에 있다면 명시적으로 전달하세요:
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
mikro-orm-markdown --config ./packages/api/mikro-orm.config.ts --tsconfig ./packages/api/tsconfig.json
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
**JSDoc 태그가 누락되거나 `@hidden` 엔티티가 노출되는 경우**
|
|
345
|
+
|
|
346
|
+
엔티티가 컴파일된 JavaScript에서 discovery되고 있을 가능성이 큽니다. 빌드 도구는 `.js` 파일에서 주석을 제거할 수 있으므로, 설명과 `@namespace`, `@hidden`을 읽지 못할 수 있습니다.
|
|
347
|
+
|
|
348
|
+
가능하면 `.ts` config와 원본 소스 파일을 가리키는 `entitiesTs`를 사용하세요. 반드시 컴파일된 `.js`에서 실행해야 한다면 원본 TypeScript 소스를 함께 전달하세요:
|
|
349
|
+
|
|
350
|
+
```bash
|
|
351
|
+
mikro-orm-markdown --config ./dist/mikro-orm.config.js --src "src/**/*.entity.ts"
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
**Config 파일 요구사항**
|
|
355
|
+
|
|
356
|
+
config 파일은 일반 설정 객체를 **default export** 해야 합니다.
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
export default defineConfig({ ... }); // ✅
|
|
360
|
+
export const config = defineConfig({ ... }); // ❌ named export 미지원
|
|
361
|
+
export default async () => defineConfig({ ... }); // ❌ 함수/Promise 미지원
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
config를 비동기적으로 만들어야 한다면, 아래 프로그래밍 API를 사용하세요.
|
|
176
365
|
|
|
177
366
|
## 고급 사용법
|
|
178
367
|
|
|
@@ -181,16 +370,34 @@ export class Dog extends Animal {
|
|
|
181
370
|
커스텀 빌드 스크립트에 통합하거나 출력 결과를 직접 가공해야 할 때 사용합니다:
|
|
182
371
|
|
|
183
372
|
```typescript
|
|
373
|
+
import { writeFile } from 'node:fs/promises';
|
|
184
374
|
import { generateMarkdown } from 'mikro-orm-markdown';
|
|
185
375
|
import ormConfig from './mikro-orm.config.js';
|
|
186
376
|
|
|
187
377
|
const markdown = await generateMarkdown({
|
|
188
378
|
orm: ormConfig,
|
|
189
379
|
title: 'My Database',
|
|
190
|
-
|
|
380
|
+
description: 'MikroORM metadata에서 생성한 스키마 문서입니다.',
|
|
191
381
|
});
|
|
192
382
|
|
|
193
|
-
await
|
|
383
|
+
await writeFile('./ERD.md', markdown, 'utf-8');
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
프로그래밍 API 옵션:
|
|
387
|
+
|
|
388
|
+
| 옵션 | 설명 |
|
|
389
|
+
| ---- | ---- |
|
|
390
|
+
| `orm` | MikroORM options object입니다. 필수입니다. |
|
|
391
|
+
| `title` | H1 제목입니다. 기본값은 `Database Schema`입니다. |
|
|
392
|
+
| `description` | 제목 아래에 표시할 설명 문단입니다. CLI flag와 달리 쉘 quoting 제약 없이 문자열을 그대로 전달할 수 있습니다. |
|
|
393
|
+
| `src` | 원본 TypeScript 엔티티 소스 경로/glob입니다. `orm.entities`가 컴파일된 JavaScript를 discovery할 때만 필요합니다. |
|
|
394
|
+
| `onWarn` | 컴파일된 JavaScript에서 JSDoc을 읽지 못하는 상황 같은 non-fatal warning을 받을 callback입니다. |
|
|
395
|
+
|
|
396
|
+
MikroORM config를 비동기적으로 만들어야 한다면 직접 resolve한 뒤 결과 options object를 전달하세요:
|
|
397
|
+
|
|
398
|
+
```typescript
|
|
399
|
+
const ormConfig = await createOrmConfig();
|
|
400
|
+
const markdown = await generateMarkdown({ orm: ormConfig });
|
|
194
401
|
```
|
|
195
402
|
|
|
196
403
|
## 라이선스
|