d2 icon indicating copy to clipboard operation
d2 copied to clipboard

d2js: Typescript definitions

Open alixander opened this issue 11 months ago • 4 comments

alixander avatar Jan 14 '25 06:01 alixander

This what I used in one of my projects


export type D2Options = {
  /**
   * @default 0
   * Set the diagram theme ID.
   */
  theme?: number;
  /**
   * @default -1
   * The theme to use when the viewer's browser is in dark mode.
   * When left unset --theme is used for both light and dark mode.
   * Be aware that explicit styles set in D2 code will still be
   * applied and this may produce unexpected results. We plan on
   * resolving this by making style maps in D2 light/dark mode
   * specific. See https://github.com/terrastruct/d2/issues/831.
   */
  darkTheme?: number;
  /**
   * Set the diagram layout engine to the passed string. For a
   * list of available options, run layout.
   */
  layout?: "elk" | "dagre";
  /**
   * @default 100
   * Pixels padded around the rendered diagram.
   */
  pad?: number;
  /**
   * @default -1
   * Scale the output. E.g., 0.5 to halve the default size.
   * Default -1 means that SVG's will fit to screen and all others
   * will use their default render size. Setting to 1 turns off
   * SVG fitting to screen.
   */
  scale?: number;
  /**
   * @default false
   * Renders the diagram to look like it was sketched by hand.
   */
  sketch?: boolean;
  /**
   * @default true
   * Bundle all assets and layers into the output svg.
   */
  bundle?: boolean;
  /**
   * Center the SVG in the containing viewbox, such as your
   * browser screen.
   */
  center?: boolean;
};

stereobooster avatar Jan 17 '25 20:01 stereobooster

Is there one data structure, or two? I thought there are CompileOptions and RenderOptions.

Overall, I'm very interested in this too.

awhitford avatar Feb 28 '25 09:02 awhitford

I wonder if https://github.com/gzuidhof/tygo can be used for this?

stereobooster avatar Mar 02 '25 15:03 stereobooster

I was experimenting with integrating d2js into https://github.com/terrastruct/d2-obsidian and wrote these definitions here. I only have a working prototype for now, but the type definitions seem mostly accurate for the current code.

d2.d.ts
declare module "@terrastruct/d2" {
  interface RenderOptions {
    /** Enable sketch mode [default: false] */
    sketch?: boolean;
    /** Theme ID to use [default: 0] */
    themeID?: number;
    /** Theme ID to use when client is in dark mode */
    darkThemeID?: number;
    /** Center the SVG in the containing viewbox [default: false] */
    center?: boolean;
    /** Pixels padded around the rendered diagram [default: 100] */
    pad?: number;
    /** Scale the output. E.g., 0.5 to halve the default size. The default will render SVG's that will fit to screen. Setting to 1 turns off SVG fitting to screen. */
    scale?: number;
    /** Adds an appendix for tooltips and links [default: false] */
    forceAppendix?: boolean;
    /** Target board/s to render. If target ends with '', it will be rendered with all of its scenarios, steps, and layers. Otherwise, only the target board will be rendered. E.g. target: 'layers.x.*' to render layer 'x' with all of its children. Pass '' to render all scenarios, steps, and layers. By default, only the root board is rendered. Multi-board outputs are currently only supported for animated SVGs and so animateInterval must be set to a value greater than 0 when targeting multiple boards. */
    target?: string;
    /** If given, multiple boards are packaged as 1 SVG which transitions through each board at the interval (in milliseconds). */
    animateInterval?: number;
    /** Add a salt value to ensure the output uses unique IDs. This is useful when generating multiple identical diagrams to be included in the same HTML doc, so that duplicate IDs do not cause invalid HTML. The salt value is a string that will be appended to IDs in the output. */
    salt?: string;
    /** Omit XML tag (<?xml ...?>) from output SVG files. Useful when generating SVGs for direct HTML embedding. */
    noXMLTag?: boolean;
  }

  interface CompileOptions extends RenderOptions {
    /** Layout engine to use ('dagre' | 'elk') [default: 'dagre'] */
    layout?: string;
    /** A byte array containing .ttf file to use for the regular font. If none provided, Source Sans Pro Regular is used. */
    fontRegular?: Uint8Array;
    /** A byte array containing .ttf file to use for the italic font. If none provided, Source Sans Pro Italic is used. */
    fontItalic?: Uint8Array;
    /** A byte array containing .ttf file to use for the bold font. If none provided, Source Sans Pro Bold is used. */
    fontBold?: Uint8Array;
    /** A byte array containing .ttf file to use for the semibold font. If none provided, Source Sans Pro Semibold is used. */
    fontSemibold?: Uint8Array;
  }

  interface CompileRequest {
    /** A mapping of D2 file paths to their content*/
    fs: Record<string, string>;
    /** The path of the entry D2 file [default: index]*/
    inputPath: string;
    /** The CompileOptions to pass to the compiler*/
    options: CompileOptions;
  }

  interface Diagram {
    config: RenderOptions;
  }

  interface CompileResult {
    /**  Compiled D2 diagram*/
    diagram: Diagram;
    /** RenderOptions: Render options merged with configuration set in diagram*/
    renderOptions: RenderOptions;
    fs: Record<string, string>;
    graph: unknown;
  }

  class D2 {
    compile(input: string | CompileRequest, options?: CompileOptions): Promise<CompileResult>;
    render(diagram: Diagram, options?: RenderOptions): Promise<string>;
  }
}

I have noticed that the CompileResult doesn't seem to be documented quite accurately at the moment.

hpr1999 avatar Mar 07 '25 23:03 hpr1999

Using version 0.1.23, the simple import: import { D2, type CompileOptions } from '@terrastruct/d2' Doesn't really work. I'm getting ts(7016):

Could not find a declaration file for module '@terrastruct/d2'. '/Users/anthony/github/awhitford/astro-d2/node_modules/.pnpm/@[email protected]/node_modules/@terrastruct/d2/dist/node-esm/index.js' implicitly has an 'any' type. There are types at '/Users/anthony/github/awhitford/astro-d2/packages/astro-d2/node_modules/@terrastruct/d2/index.d.ts', but this result could not be resolved when respecting package.json "exports". The '@terrastruct/d2' library may need to update its package.json or typings.

This suggests to me that there is a bug in the package.json file.

awhitford avatar Mar 23 '25 01:03 awhitford

This suggests to me that there is a bug in the package.json file.

Yes. It was fixed in https://github.com/terrastruct/d2/pull/2441, but not published yet

Additionally I found one more case https://github.com/terrastruct/d2/issues/1448#issuecomment-2802593347. Some tools require .cjs file extension for require files.

ReferenceError [Error]: module is not defined in ES module scope This file is being treated as an ES module because it has a '.js' file extension and 'node_modules/.pnpm/@[email protected]/node_modules/@terrastruct/d2/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.

stereobooster avatar Apr 22 '25 10:04 stereobooster

Update: I've opened the PR https://github.com/terrastruct/d2/pull/2594 that fixed this issue 🙏

mateothegreat avatar Aug 05 '25 06:08 mateothegreat