d5-mermaid 0.3.0
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/LICENSE +21 -0
- package/README.md +212 -0
- package/dist/index.cjs +4081 -0
- package/dist/index.d.cts +280 -0
- package/dist/index.d.ts +280 -0
- package/dist/index.js +4079 -0
- package/package.json +61 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 D5 Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# d5-mermaid
|
|
2
|
+
|
|
3
|
+
A [Mermaid.js](https://mermaid.js.org/) extension for **D5 (Domain Driven Design Definitive Diagrams)** — visualize DDD strategic and tactical patterns as diagrams.
|
|
4
|
+
|
|
5
|
+
D5 provides four diagram types at progressive zoom levels, inspired by the C4 model but focused on the domain model rather than technical architecture. This package implements the [D5 specification](https://github.com/MutterPedro/d5-spec) as custom Mermaid diagram types.
|
|
6
|
+
|
|
7
|
+
## Diagram Types
|
|
8
|
+
|
|
9
|
+
| Diagram | Keyword | What it shows |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| **Domain** | `d5-domain` | Strategic overview: subdomains and their relationships |
|
|
12
|
+
| **Subdomain** | `d5-subdomain` | Context map: bounded contexts and DDD relationship patterns |
|
|
13
|
+
| **Context** | `d5-context` | Tactical structure: aggregates, ubiquitous language, domain events, policies and read models within a bounded context |
|
|
14
|
+
| **Aggregate** | `d5-aggregate` | Domain objects: entities, value objects and invariants within an aggregate |
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install d5-mermaid mermaid
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import mermaid from 'mermaid';
|
|
26
|
+
import { d5Diagrams } from 'd5-mermaid';
|
|
27
|
+
|
|
28
|
+
mermaid.initialize({ startOnLoad: false });
|
|
29
|
+
await mermaid.registerExternalDiagrams(d5Diagrams);
|
|
30
|
+
|
|
31
|
+
const { svg } = await mermaid.render('my-diagram', `d5-domain
|
|
32
|
+
title ACME Retail Platform
|
|
33
|
+
|
|
34
|
+
Domain(acme, "ACME Retail") {
|
|
35
|
+
Subdomain(catalog, "Product Catalog", core)
|
|
36
|
+
Subdomain(ordering, "Order Management", core)
|
|
37
|
+
Subdomain(inventory, "Inventory", supporting)
|
|
38
|
+
Subdomain(payments, "Payments", generic)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
Rel(ordering, catalog, "depends on")
|
|
42
|
+
Rel(ordering, payments, "depends on")
|
|
43
|
+
`);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Syntax Reference
|
|
47
|
+
|
|
48
|
+
### Common
|
|
49
|
+
|
|
50
|
+
- `title <text>` — optional, first line after the diagram keyword.
|
|
51
|
+
- `direction <LR|RL|TB|TD|BT>` — optional layout hint. Default `LR` for `d5-subdomain`, `TB` for `d5-domain` and `d5-context`.
|
|
52
|
+
- `%%` — line and inline comments.
|
|
53
|
+
|
|
54
|
+
### d5-domain
|
|
55
|
+
|
|
56
|
+
Strategic overview of the business domain. Subdomain types: `core`, `supporting`, `generic`.
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
d5-domain
|
|
60
|
+
title ACME Retail Platform
|
|
61
|
+
direction LR
|
|
62
|
+
|
|
63
|
+
Domain(acme, "ACME Retail") {
|
|
64
|
+
Subdomain(catalog, "Product Catalog", core)
|
|
65
|
+
Subdomain(ordering, "Order Management", core)
|
|
66
|
+
Subdomain(inventory, "Inventory", supporting)
|
|
67
|
+
Subdomain(payments, "Payments", generic)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
Rel(ordering, catalog, "depends on")
|
|
71
|
+
Rel(ordering, payments, "depends on")
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### d5-subdomain
|
|
75
|
+
|
|
76
|
+
Context map: bounded contexts within subdomains and the DDD relationship pattern between
|
|
77
|
+
each pair. `source` is the upstream context, `target` the downstream one.
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
d5-subdomain
|
|
81
|
+
title Context Map
|
|
82
|
+
direction LR
|
|
83
|
+
|
|
84
|
+
Subdomain(catalog, "Product Catalog", core) {
|
|
85
|
+
BoundedContext(product_ctx, "Product Context", team: "Catalog Team")
|
|
86
|
+
BoundedContext(pricing_ctx, "Pricing Context")
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
Subdomain(ordering, "Order Management", core) {
|
|
90
|
+
BoundedContext(order_ctx, "Order Context", team: "Order Squad")
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
Subdomain(identity, "Identity", generic) {
|
|
94
|
+
BoundedContext(auth_ctx, "Auth Context")
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
Rel(pricing_ctx, product_ctx, "Partnership")
|
|
98
|
+
Rel(order_ctx, pricing_ctx, "Conformist")
|
|
99
|
+
Rel(auth_ctx, order_ctx, "Open Host Service")
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
A relationship label that matches one of Evans' context-map patterns is drawn as a compact
|
|
103
|
+
badge with `U`/`D` (or `S`/`C`) role markers and pattern-specific decoration — an
|
|
104
|
+
Anti-Corruption Layer gate, an Open Host Service socket, no-arrowhead lines for
|
|
105
|
+
Partnership / Shared Kernel, a dashed line for Separate Ways — plus a legend of the
|
|
106
|
+
patterns used. Matching is case-, spacing- and abbreviation-insensitive:
|
|
107
|
+
|
|
108
|
+
| Pattern | Accepted labels |
|
|
109
|
+
|---|---|
|
|
110
|
+
| Partnership | `Partnership`, `P` |
|
|
111
|
+
| Shared Kernel | `Shared Kernel`, `SK` |
|
|
112
|
+
| Customer-Supplier | `Customer-Supplier`, `Customer/Supplier`, `CS` |
|
|
113
|
+
| Conformist | `Conformist`, `CF` |
|
|
114
|
+
| Anti-Corruption Layer | `Anti-Corruption Layer`, `AntiCorruption`, `ACL` |
|
|
115
|
+
| Open Host Service | `Open Host Service`, `OHS` |
|
|
116
|
+
| Published Language | `Published Language`, `PL` |
|
|
117
|
+
| Separate Ways | `Separate Ways`, `SW` |
|
|
118
|
+
| Big Ball of Mud | `Big Ball of Mud`, `BBoM` |
|
|
119
|
+
|
|
120
|
+
Any other label renders as a plain text pill.
|
|
121
|
+
|
|
122
|
+
### d5-context
|
|
123
|
+
|
|
124
|
+
Tactical structure within a single bounded context.
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
d5-context
|
|
128
|
+
title Ordering Context
|
|
129
|
+
direction LR
|
|
130
|
+
|
|
131
|
+
BoundedContext(order_ctx, "Ordering", team: "Order Squad") {
|
|
132
|
+
|
|
133
|
+
Language {
|
|
134
|
+
Term("Order", "A confirmed purchase request with one or more line items")
|
|
135
|
+
Term("Order Item", "A product line: product id, unit price captured at order time, quantity")
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
Aggregate(order_agg, "Order", root: "Order", fields: "Buyer, Order Items, Total, Status")
|
|
139
|
+
Aggregate(buyer_agg, "Buyer", root: "Buyer", fields: "Identity GUID, Payment Methods")
|
|
140
|
+
|
|
141
|
+
ReadModel(order_view, "My Orders / Order Detail")
|
|
142
|
+
|
|
143
|
+
Rel(order_agg, buyer_agg, "references the buyer & payment method by id")
|
|
144
|
+
|
|
145
|
+
Event(order_agg, buyer_agg, "OrderStarted")
|
|
146
|
+
Event(order_agg, order_view, "OrderStatusChanged")
|
|
147
|
+
|
|
148
|
+
Policy(order_agg, order_agg, "when stock is confirmed for every item, advance the order and request payment")
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
- **`Aggregate(id, "Label", root: "Name")`** — `root:` required; optional `fields:` is a
|
|
153
|
+
comma-separated shorthand for the aggregate's shape.
|
|
154
|
+
- **`Language { Term("Name", "Definition") }`** — the ubiquitous language, drawn as a sidebar.
|
|
155
|
+
- **`ReadModel(id, "Label")`** — a CQRS query-side projection; drawn as a table-shaped node,
|
|
156
|
+
fed by `Event(...)` edges whose `target` is the read model.
|
|
157
|
+
- **`Rel(source, target, "label")`** — a structural by-id reference between aggregates.
|
|
158
|
+
- **`Event(source, target, "EventName")`** — a domain event: `source` emits, `target` reacts.
|
|
159
|
+
Drawn as a dashed amber arrow with an Event Storming tag. Multiple per pair allowed.
|
|
160
|
+
- **`Policy(source, target, "whenever … then …")`** — a reactive policy. Drawn as a dashed
|
|
161
|
+
violet arrow; `source === target` for a scheduled / self-directed policy.
|
|
162
|
+
|
|
163
|
+
### d5-aggregate
|
|
164
|
+
|
|
165
|
+
Internal composition of a single aggregate. No `Rel` — containment implies direct references.
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
d5-aggregate
|
|
169
|
+
title Order Aggregate
|
|
170
|
+
|
|
171
|
+
Aggregate(order_agg, "Order", root: "Order") {
|
|
172
|
+
Entity(order, "Order")
|
|
173
|
+
Entity(order_item, "Order Item")
|
|
174
|
+
ValueObject(money, "Money")
|
|
175
|
+
ValueObject(quantity, "Quantity")
|
|
176
|
+
ValueObject(shipping_address, "Shipping Address")
|
|
177
|
+
|
|
178
|
+
Invariants {
|
|
179
|
+
Invariant("An order always has at least one order item")
|
|
180
|
+
Invariant("Status", "Only advances Placed → Paid → Shipped → Delivered")
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
The optional **`Invariants { Invariant("rule") | Invariant("Subject", "rule") }`** block
|
|
186
|
+
lists the business rules the aggregate keeps true on every transaction. It renders as a
|
|
187
|
+
band inside the aggregate boundary, attributed to the root.
|
|
188
|
+
|
|
189
|
+
## Examples
|
|
190
|
+
|
|
191
|
+
`examples/` contains D5 models of seven real-world DDD codebases and techniques
|
|
192
|
+
(dddsample-core, ddd-by-examples/library, IDDD_Samples, eShopOnContainers, Wolff
|
|
193
|
+
Microservices, a Nick-Tune-style Core Domain Chart, all-things-cqrs) — 39 diagrams across
|
|
194
|
+
every zoom level.
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
npm run gallery # builds and opens examples/gallery.html
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Development
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
npm install
|
|
204
|
+
npm test # run tests (vitest + jsdom)
|
|
205
|
+
npm run test:watch # watch mode
|
|
206
|
+
npm run build # build for distribution (tsup: ESM + CJS + types)
|
|
207
|
+
npm run lint # type-check (tsc --noEmit)
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## License
|
|
211
|
+
|
|
212
|
+
[MIT](LICENSE)
|