Skip to content

Commit cdaf76a

Browse files
committed
feat: Add draw command
You can draw class diagrams (with mermaid). Specify a folder where typescript types (from typescript command) are and a mermaid file will be created.
1 parent 16afe92 commit cdaf76a

7 files changed

Lines changed: 686 additions & 22 deletions

File tree

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
},
6666
"dependencies": {
6767
"commander": "^14.0.3",
68-
"dotenv": "^17.3.1",
68+
"dotenv": "^17.4.1",
6969
"handlebars": "^4.7.9",
7070
"mkdirp": "^3.0.1",
7171
"prettier": "^3.8.1",
@@ -81,7 +81,7 @@
8181
"@semantic-release/github": "^12.0.6",
8282
"@semantic-release/npm": "^13.1.5",
8383
"@semantic-release/release-notes-generator": "^14.1.0",
84-
"@types/node": "^25.5.0",
84+
"@types/node": "^25.5.2",
8585
"semantic-release-export-data": "^1.2.0"
8686
}
8787
}

pnpm-lock.yaml

Lines changed: 10 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cli.ts

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import { loadConfig, printConfig } from "./features/config/index.js";
77
import {
88
del,
99
down,
10+
draw,
1011
typescript,
1112
up,
1213
type CLI_DeleteType,
1314
type CLI_DownType,
15+
type CLI_DrawType,
1416
type CLI_UpType,
1517
type TypescriptConversionOptions,
1618
} from "./features/schema/index.js";
@@ -41,7 +43,7 @@ async function main() {
4143
.option(
4244
"--prefix <prefix>",
4345
"Only classes with the given prefix will be pulled",
44-
"",
46+
""
4547
)
4648
.option("--ignore <ignore...>", "Class(es) to ignore", "")
4749
.description("Fetch the schema from Parse Server")
@@ -58,7 +60,7 @@ async function main() {
5860
.option(
5961
"--prefix <prefix>",
6062
"Only classes with the given prefix will be pushed or removed",
61-
"",
63+
""
6264
)
6365
.option("--ignore <ignore...>", "Class(es) to ignore", "")
6466
.option("--safe", "This will prevent destructive operations", "")
@@ -83,7 +85,7 @@ async function main() {
8385
.option(
8486
"--prefix <prefix>",
8587
"Only classes with the given prefix will be deleted",
86-
"",
88+
""
8789
)
8890
.option("--deleteNonEmptyClass", "Delete non-empty classes", false)
8991
.description("Delete the local schema from Parse Server")
@@ -101,40 +103,83 @@ async function main() {
101103
.option(
102104
"--include <include...>",
103105
"Class(es) to include (overrides --ignore)",
104-
"",
106+
""
105107
)
106108
.option("--no-class", "Don't create and register custom Parse.Object")
107109
.option("--no-sdk", "Don't use Parse JS SDK, just TS without dependencies")
108110
.option(
109111
"--import-parse-statement <statement>",
110112
"Custom import statement for Parse (e.g., 'import Parse from \"parse/node.js\"')",
111-
"",
113+
""
112114
)
113115
.option("--is-esm", "Use ES module imports in generated files.", false)
114116
.option(
115117
"--resolve-referenced-classes",
116118
"Generate all referenced classes, even if they are not in the fetched schema.",
117-
false,
119+
false
118120
)
119121
.option(
120122
"--custom-class-field-types-config <path>",
121-
"Path to .json config file for custom class field types",
123+
"Path to .json config file for custom class field types"
122124
)
123125
.option(
124126
"--verbose",
125127
"Enable verbose logging including dependency graph",
126-
false,
128+
false
127129
)
128130
.action(
129131
async (
130132
typescriptPath: string,
131-
options: TypescriptConversionOptions | undefined,
133+
options: TypescriptConversionOptions | undefined
132134
) => {
133135
loadConfig(program.opts().configPath);
134136

135137
await typescript(typescriptPath, options);
136-
},
138+
}
137139
);
138140

141+
program
142+
.command("draw <inputPath>")
143+
.description(
144+
"Generate a UML class diagram from a local schema folder. " +
145+
"Accepts a folder with .json files (output of `down`) or " +
146+
".ts files (output of `typescript`), or a single .json file."
147+
)
148+
.option(
149+
"--output <path>",
150+
"Output file path (default: schema-diagram.mmd / .md / .html)"
151+
)
152+
.option(
153+
"--format <format>",
154+
"Output format: mermaid | markdown | html (default: mermaid)",
155+
"mermaid"
156+
)
157+
.option(
158+
"--prefix <prefix>",
159+
"Only include classes with the given prefix",
160+
""
161+
)
162+
.option(
163+
"--font-size <px>",
164+
"Mermaid font size in pixels for the generated diagram",
165+
"44"
166+
)
167+
.option(
168+
"--default-renderer <renderer>",
169+
"Class diagram layout engine: dagre-wrapper | dagre-d3 | elk",
170+
"elk"
171+
)
172+
.option("--ignore <ignore...>", "Class(es) to ignore")
173+
.action(async (inputPath: string, options: CLI_DrawType) => {
174+
await draw(inputPath, {
175+
output: options.output,
176+
format: options.format,
177+
prefix: options.prefix || undefined,
178+
ignore: options.ignore,
179+
fontSize: Number.parseInt(String(options.fontSize ?? "44"), 10),
180+
defaultRenderer: options.defaultRenderer,
181+
});
182+
});
183+
139184
await program.parseAsync(process.argv);
140185
}

src/features/schema/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export * from "./helper/typescriptHelpers.js";
55
// Services
66
export { del } from "./services/del.js";
77
export { down } from "./services/down.js";
8+
export { draw } from "./services/draw.js";
89
export { typescript } from "./services/typescript.js";
910
export { up } from "./services/up.js";
1011

@@ -23,4 +24,9 @@ export {
2324

2425
export { type CLI_DeleteType, type DeleteType } from "./types/DeleteTypes.js";
2526
export { type CLI_DownType, type DownType } from "./types/DownTypes.js";
27+
export {
28+
type CLI_DrawType,
29+
type DrawFormat,
30+
type DrawOptions,
31+
} from "./types/DrawTypes.js";
2632
export { type CLI_UpType, type UpType } from "./types/UpTypes.js";

0 commit comments

Comments
 (0)