|
1 | 1 | // @ts-ignore https://github.com/terrastruct/d2/issues/2286
|
2 | 2 | import { D2 } from "@terrastruct/d2";
|
| 3 | +import { glob, GlobOptions } from "tinyglobby"; |
| 4 | +// @ts-expect-error |
| 5 | +import memoizeOne from "async-memoize-one"; |
| 6 | +import fs from "node:fs/promises"; |
3 | 7 |
|
4 | 8 | export type D2Options = {
|
5 | 9 | layout?: "dagre" | "elk";
|
6 | 10 | sketch?: boolean;
|
7 | 11 | themeID?: number;
|
8 | 12 | graphFormat?: "graphology" | "dagre";
|
| 13 | + shared?: string | string[] | GlobOptions; |
9 | 14 | };
|
10 | 15 |
|
| 16 | +const mGlob = memoizeOne(async (x: string | string[] | GlobOptions) => { |
| 17 | + // @ts-expect-error |
| 18 | + const paths = await glob(x); |
| 19 | + const result: Record<string, string> = Object.create(null); |
| 20 | + // probably not the best way to do it, but for small number of files should be ok |
| 21 | + await Promise.all( |
| 22 | + paths.map((path) => |
| 23 | + fs |
| 24 | + .readFile(path, { encoding: "utf-8" }) |
| 25 | + .then((content) => (result[path] = content)) |
| 26 | + ) |
| 27 | + ); |
| 28 | + return result; |
| 29 | +}); |
| 30 | + |
11 | 31 | export async function d2(code: string, options: D2Options) {
|
12 | 32 | const d2Instance = new D2();
|
13 |
| - const result = await d2Instance.compile(code, options); |
| 33 | + |
| 34 | + const fs: Record<string, string> = options.shared |
| 35 | + ? { ...(await mGlob(options.shared)), index: code } |
| 36 | + : { index: code }; |
| 37 | + const result = await d2Instance.compile({ fs }, options); |
14 | 38 |
|
15 | 39 | let data;
|
16 | 40 | if (options.graphFormat) {
|
@@ -62,6 +86,6 @@ export async function d2(code: string, options: D2Options) {
|
62 | 86 | }
|
63 | 87 | }
|
64 | 88 |
|
65 |
| - const svg = await d2Instance.render(result.diagram, options) as string; |
| 89 | + const svg = (await d2Instance.render(result.diagram, options)) as string; |
66 | 90 | return { svg, data };
|
67 | 91 | }
|
0 commit comments