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 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)