@temelj/mdx 0.7.0 → 0.8.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.
Files changed (47) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/README.md +1 -1
  3. package/compiler.test.ts +117 -0
  4. package/compiler.ts +124 -0
  5. package/{types → dist}/compiler.d.ts +1 -2
  6. package/{esm → dist}/compiler.js +3 -18
  7. package/dist/mod.d.ts +3 -0
  8. package/dist/mod.js +3 -0
  9. package/{types → dist}/plugins/heading-id/plugin.d.ts +1 -2
  10. package/dist/plugins/mod.d.ts +4 -0
  11. package/dist/plugins/mod.js +4 -0
  12. package/{types → dist}/plugins/remove-imports-exports.d.ts +1 -2
  13. package/{types → dist}/plugins/syntax-highlight/code-meta.d.ts +1 -2
  14. package/{types → dist}/plugins/syntax-highlight/plugin.d.ts +1 -2
  15. package/{esm → dist}/plugins/syntax-highlight/plugin.js +1 -1
  16. package/{types → dist}/plugins/tree-processor/plugin.d.ts +1 -2
  17. package/{types → dist}/types.d.ts +0 -1
  18. package/mod.ts +3 -0
  19. package/package.json +23 -25
  20. package/plugins/heading-id/plugin.ts +42 -0
  21. package/plugins/mod.ts +4 -0
  22. package/plugins/remove-imports-exports.ts +18 -0
  23. package/plugins/syntax-highlight/code-meta.test.ts +22 -0
  24. package/plugins/syntax-highlight/code-meta.ts +76 -0
  25. package/plugins/syntax-highlight/plugin.ts +266 -0
  26. package/plugins/tree-processor/plugin.ts +54 -0
  27. package/tsconfig.json +18 -0
  28. package/types.ts +3 -0
  29. package/esm/mod.js +0 -3
  30. package/esm/package.json +0 -3
  31. package/esm/plugins/mod.js +0 -4
  32. package/types/compiler.d.ts.map +0 -1
  33. package/types/mod.d.ts +0 -4
  34. package/types/mod.d.ts.map +0 -1
  35. package/types/plugins/heading-id/plugin.d.ts.map +0 -1
  36. package/types/plugins/mod.d.ts +0 -5
  37. package/types/plugins/mod.d.ts.map +0 -1
  38. package/types/plugins/remove-imports-exports.d.ts.map +0 -1
  39. package/types/plugins/syntax-highlight/code-meta.d.ts.map +0 -1
  40. package/types/plugins/syntax-highlight/plugin.d.ts.map +0 -1
  41. package/types/plugins/tree-processor/plugin.d.ts.map +0 -1
  42. package/types/types.d.ts.map +0 -1
  43. /package/{esm → dist}/plugins/heading-id/plugin.js +0 -0
  44. /package/{esm → dist}/plugins/remove-imports-exports.js +0 -0
  45. /package/{esm → dist}/plugins/syntax-highlight/code-meta.js +0 -0
  46. /package/{esm → dist}/plugins/tree-processor/plugin.js +0 -0
  47. /package/{esm → dist}/types.js +0 -0
@@ -0,0 +1,4 @@
1
+
2
+ > @temelj/mdx@0.8.0 build /home/runner/work/temelj/temelj/packages/mdx
3
+ > tsc
4
+
package/README.md CHANGED
@@ -38,7 +38,7 @@ $ deno add jsr:@temelj/mdx # or jsr add @temelj/mdx
38
38
  ## Compile
39
39
 
40
40
  ```ts
41
- import { assert, assertEquals } from "@std/assert";
41
+ import { expect, test } from "vitest";
42
42
  import {
43
43
  type HastElement,
44
44
  headingIdPlugin,
@@ -0,0 +1,117 @@
1
+ import { expect, test } from "vitest";
2
+ import { z } from "zod";
3
+
4
+ import { MdxCompiler } from "./compiler";
5
+ import { headingIdPlugin } from "./plugins/heading-id/plugin";
6
+ import { syntaxHighlightPlugin } from "./plugins/syntax-highlight/plugin";
7
+ import { treeProcessorPlugin } from "./plugins/tree-processor/plugin";
8
+
9
+ test("mdx - compile", async () => {
10
+ let headingCount = 0;
11
+ const compiler = new MdxCompiler()
12
+ .withRehypePlugin(headingIdPlugin, {
13
+ prefix: "h-",
14
+ })
15
+ .withRehypePlugin(treeProcessorPlugin, {
16
+ process: (element) => {
17
+ if (element.tagName.startsWith("h")) {
18
+ headingCount++;
19
+ }
20
+ },
21
+ })
22
+ .withRehypePlugin(syntaxHighlightPlugin, {
23
+ includeDataAttributes: ["language", "source-code", "line-count"],
24
+ highlight: {
25
+ transformer: { classActiveLine: "hl" },
26
+ },
27
+ lineNumbers: {},
28
+ });
29
+
30
+ const frontmatterSchema = z.object({
31
+ title: z.string(),
32
+ x: z.optional(z.number()),
33
+ b: z.optional(z.boolean()).default(true),
34
+ });
35
+
36
+ const artifact = await compiler.compile(
37
+ `
38
+ ---
39
+ title: Test
40
+ x: 42
41
+ ---
42
+
43
+ # Hello
44
+ ## Title 2
45
+ ## Duplicate
46
+ ## Duplicate
47
+
48
+ \`\`\`ts {"highlight":"2", "showLineNumbers":true}
49
+ type Mdx = never; // [!code highlight]
50
+ const x1 = 1;
51
+ \`\`\`
52
+ `.trim(),
53
+ {},
54
+ frontmatterSchema,
55
+ );
56
+
57
+ expect(headingCount).toBe(4);
58
+ expect(artifact.frontmatter.title).toBe("Test");
59
+ expect(artifact.frontmatter.x).toBe(42);
60
+ expect(artifact.frontmatter.b).toBe(true);
61
+
62
+ await expect(() =>
63
+ compiler.compile("", {}, frontmatterSchema),
64
+ ).rejects.toThrow(z.ZodError);
65
+
66
+ const value = artifact.compiled;
67
+ expect(typeof value === "string").toBe(true);
68
+ expect(value?.includes('"Hello"')).toBe(true);
69
+ expect(value?.includes('"h-title-2"')).toBe(true);
70
+
71
+ expect(value?.includes('"data-language": "ts"')).toBe(true);
72
+ expect(value?.includes('"data-line-count": "2"')).toBe(true);
73
+ expect(value?.includes('"data-source-code": "')).toBe(true);
74
+
75
+ expect(
76
+ value?.includes('"data-line": "1"') && value?.includes('"data-line": "2"'),
77
+ ).toBe(true);
78
+ expect(value?.includes('className: "line hl line-number"')).toBe(true);
79
+ });
80
+
81
+ test("mdx - parse frontmatter", async () => {
82
+ async function compile<TFrontmatterSchema extends z.ZodSchema>(
83
+ frontmatter: Record<string, unknown>,
84
+ schema: TFrontmatterSchema,
85
+ ): Promise<z.output<TFrontmatterSchema>> {
86
+ const compiler = new MdxCompiler();
87
+
88
+ const artifact = await compiler.compile(
89
+ `
90
+ ---
91
+ ${JSON.stringify(frontmatter)}
92
+ ---
93
+ `.trim(),
94
+ {},
95
+ schema,
96
+ );
97
+ return artifact.frontmatter;
98
+ }
99
+
100
+ const fm1 = await compile(
101
+ { x: 42 },
102
+ z.object({
103
+ x: z.number(),
104
+ }),
105
+ );
106
+ const _fm1type: { x: number } = fm1;
107
+ expect(fm1).toStrictEqual({ x: 42 });
108
+
109
+ const fm2 = await compile(
110
+ { s: "abc" },
111
+ z.object({
112
+ s: z.string(),
113
+ }),
114
+ );
115
+ const _fm2type: { s: string } = fm2;
116
+ expect(fm2).toStrictEqual({ s: "abc" });
117
+ });
package/compiler.ts ADDED
@@ -0,0 +1,124 @@
1
+ import {
2
+ compile as compileMdxJs,
3
+ type CompileOptions as MdxJsCompileOptions,
4
+ } from "@mdx-js/mdx";
5
+ import remarkFrontmatterPlugin from "remark-frontmatter";
6
+ import remarkGfmPlugin from "remark-gfm";
7
+ import { VFile } from "vfile";
8
+ import { matter } from "vfile-matter";
9
+ import type { Pluggable, PluggableList, Plugin } from "unified";
10
+ import type { z } from "zod";
11
+
12
+ import type { HastNode } from "./types";
13
+
14
+ export { remarkFrontmatterPlugin, remarkGfmPlugin };
15
+
16
+ /**
17
+ * Represents the source content for an MDX document.
18
+ */
19
+ export type MdxSource = string | Uint8Array;
20
+
21
+ /**
22
+ * Options for compiling an MDX document.
23
+ */
24
+ export interface MdxCompileOptions {
25
+ frontmatterOnly?: boolean | undefined;
26
+ mdxOptions?: MdxJsCompileOptions;
27
+ }
28
+
29
+ /**
30
+ * The result of compiling an MDX document.
31
+ * Compiled content is optional, because sometimes we only need the frontmatter.
32
+ */
33
+ export interface MdxArtifact<TFrontmatter = Record<string, unknown>> {
34
+ compiled?: string | undefined;
35
+ frontmatter: TFrontmatter;
36
+ }
37
+
38
+ /**
39
+ * A reusable compiler for compiling MDX.
40
+ */
41
+ export class MdxCompiler {
42
+ private readonly mdxOptions: MdxJsCompileOptions;
43
+ private readonly remarkPlugins: PluggableList;
44
+ private readonly rehypePlugins: PluggableList;
45
+
46
+ public constructor(mdxOptions: MdxJsCompileOptions = {}) {
47
+ this.mdxOptions = mdxOptions;
48
+ this.remarkPlugins = [remarkFrontmatterPlugin, remarkGfmPlugin];
49
+ this.rehypePlugins = [];
50
+ }
51
+
52
+ public withRemarkPlugin<TOptions>(
53
+ plugin: Plugin<[TOptions?], HastNode, HastNode>,
54
+ options?: TOptions,
55
+ ): MdxCompiler {
56
+ if (options === undefined) {
57
+ this.remarkPlugins.push(plugin as Pluggable);
58
+ } else {
59
+ this.remarkPlugins.push([plugin, options] as Pluggable);
60
+ }
61
+ return this;
62
+ }
63
+
64
+ public withRehypePlugin<TOptions>(
65
+ plugin: Plugin<[TOptions?], HastNode, HastNode>,
66
+ options?: TOptions,
67
+ ): MdxCompiler {
68
+ if (options === undefined) {
69
+ this.rehypePlugins.push(plugin as Pluggable);
70
+ } else {
71
+ this.rehypePlugins.push([plugin, options] as Pluggable);
72
+ }
73
+ return this;
74
+ }
75
+
76
+ public async compile<TFrontmatterSchema extends z.ZodSchema>(
77
+ source: MdxSource,
78
+ { frontmatterOnly = false, mdxOptions }: MdxCompileOptions = {},
79
+ frontmatterSchema?: TFrontmatterSchema,
80
+ ): Promise<MdxArtifact<z.output<TFrontmatterSchema>>> {
81
+ const vfile = new VFile({
82
+ value: source,
83
+ // Needed so vfile doesn't need to access fs.
84
+ cwd: "/",
85
+ path: "/",
86
+ message: {},
87
+ messages: {},
88
+ });
89
+ matter(vfile, { strip: true });
90
+
91
+ const remarkPlugins = [
92
+ ...this.remarkPlugins,
93
+ ...(this.mdxOptions?.remarkPlugins ?? []),
94
+ ...(mdxOptions?.remarkPlugins ?? []),
95
+ ];
96
+ const rehypePlugins = [
97
+ ...this.rehypePlugins,
98
+ ...(this.mdxOptions?.rehypePlugins ?? []),
99
+ ...(mdxOptions?.rehypePlugins ?? []),
100
+ ];
101
+
102
+ let compiled: string | undefined;
103
+ if (!frontmatterOnly) {
104
+ const compiledFile = await compileMdxJs(vfile, {
105
+ outputFormat: "function-body",
106
+ ...(this.mdxOptions ?? {}),
107
+ ...(mdxOptions ?? {}),
108
+ remarkPlugins,
109
+ rehypePlugins,
110
+ });
111
+ compiled = compiledFile.value.toString();
112
+ }
113
+
114
+ const frontmatter =
115
+ frontmatterSchema === undefined
116
+ ? (vfile.data.matter ?? {})
117
+ : frontmatterSchema.parse(vfile.data.matter ?? {});
118
+
119
+ return {
120
+ compiled,
121
+ frontmatter: frontmatter as z.output<TFrontmatterSchema>,
122
+ };
123
+ }
124
+ }
@@ -3,7 +3,7 @@ import remarkFrontmatterPlugin from "remark-frontmatter";
3
3
  import remarkGfmPlugin from "remark-gfm";
4
4
  import type { Plugin } from "unified";
5
5
  import type { z } from "zod";
6
- import type { HastNode } from "./types.js";
6
+ import type { HastNode } from "./types";
7
7
  export { remarkFrontmatterPlugin, remarkGfmPlugin };
8
8
  /**
9
9
  * Represents the source content for an MDX document.
@@ -36,4 +36,3 @@ export declare class MdxCompiler {
36
36
  withRehypePlugin<TOptions>(plugin: Plugin<[TOptions?], HastNode, HastNode>, options?: TOptions): MdxCompiler;
37
37
  compile<TFrontmatterSchema extends z.ZodSchema>(source: MdxSource, { frontmatterOnly, mdxOptions }?: MdxCompileOptions, frontmatterSchema?: TFrontmatterSchema): Promise<MdxArtifact<z.output<TFrontmatterSchema>>>;
38
38
  }
39
- //# sourceMappingURL=compiler.d.ts.map
@@ -8,25 +8,10 @@ export { remarkFrontmatterPlugin, remarkGfmPlugin };
8
8
  * A reusable compiler for compiling MDX.
9
9
  */
10
10
  export class MdxCompiler {
11
+ mdxOptions;
12
+ remarkPlugins;
13
+ rehypePlugins;
11
14
  constructor(mdxOptions = {}) {
12
- Object.defineProperty(this, "mdxOptions", {
13
- enumerable: true,
14
- configurable: true,
15
- writable: true,
16
- value: void 0
17
- });
18
- Object.defineProperty(this, "remarkPlugins", {
19
- enumerable: true,
20
- configurable: true,
21
- writable: true,
22
- value: void 0
23
- });
24
- Object.defineProperty(this, "rehypePlugins", {
25
- enumerable: true,
26
- configurable: true,
27
- writable: true,
28
- value: void 0
29
- });
30
15
  this.mdxOptions = mdxOptions;
31
16
  this.remarkPlugins = [remarkFrontmatterPlugin, remarkGfmPlugin];
32
17
  this.rehypePlugins = [];
package/dist/mod.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./plugins/mod";
2
+ export * from "./types";
3
+ export * from "./compiler";
package/dist/mod.js ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./plugins/mod";
2
+ export * from "./types";
3
+ export * from "./compiler";
@@ -1,5 +1,5 @@
1
1
  import type { Plugin } from "unified";
2
- import type { HastNode } from "../../types.js";
2
+ import type { HastNode } from "../../types";
3
3
  /**
4
4
  * Options for {@linkcode headingIdPlugin}.
5
5
  */
@@ -13,4 +13,3 @@ export interface HeadingIdPluginOptions {
13
13
  export declare const headingIdPlugin: Plugin<[
14
14
  HeadingIdPluginOptions?
15
15
  ], HastNode, HastNode>;
16
- //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1,4 @@
1
+ export * from "./heading-id/plugin";
2
+ export * from "./syntax-highlight/plugin";
3
+ export * from "./tree-processor/plugin";
4
+ export * from "./remove-imports-exports";
@@ -0,0 +1,4 @@
1
+ export * from "./heading-id/plugin";
2
+ export * from "./syntax-highlight/plugin";
3
+ export * from "./tree-processor/plugin";
4
+ export * from "./remove-imports-exports";
@@ -1,9 +1,8 @@
1
1
  import type { Plugin } from "unified";
2
- import type { HastNode } from "../types.js";
2
+ import type { HastNode } from "../types";
3
3
  /**
4
4
  * A remark plugin which removes all import and export statements.
5
5
  */
6
6
  export declare const removeImportsExportsPlugin: Plugin<[
7
7
  unknown
8
8
  ], HastNode, HastNode>;
9
- //# sourceMappingURL=remove-imports-exports.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { type NumericRange } from "@temelj/iterator";
2
- import type { HastElement } from "../../types.js";
2
+ import type { HastElement } from "../../types";
3
3
  export interface MdxCodeMeta {
4
4
  highlight?: MdxCodeMetaHighlightLine;
5
5
  showLineNumbers?: MdxCodeMetaLineNumbers;
@@ -16,4 +16,3 @@ export type MdxCodeMetaCommandLine = {
16
16
  commandRange: NumericRange;
17
17
  };
18
18
  export declare function extractCodeMeta(node: HastElement): MdxCodeMeta;
19
- //# sourceMappingURL=code-meta.d.ts.map
@@ -1,7 +1,7 @@
1
1
  import { type BundledLanguage, type BundledTheme, type CodeToHastOptions } from "shiki";
2
2
  import { type TransformerNotationHighlightOptions } from "@shikijs/transformers";
3
3
  import type { Plugin } from "unified";
4
- import type { HastNode } from "../../types.js";
4
+ import type { HastNode } from "../../types";
5
5
  type ShikiHastOptions = Partial<CodeToHastOptions<BundledLanguage, BundledTheme>>;
6
6
  type SyntaxDataAttribute = "source-code" | "language" | "line-count";
7
7
  /**
@@ -54,4 +54,3 @@ export declare const syntaxHighlightPlugin: Plugin<[
54
54
  SyntaxHighlightPluginOptions?
55
55
  ], HastNode, HastNode>;
56
56
  export {};
57
- //# sourceMappingURL=plugin.d.ts.map
@@ -3,7 +3,7 @@ import { codeToHast, ShikiError, } from "shiki";
3
3
  import { visit } from "unist-util-visit";
4
4
  import { transformerNotationHighlight, } from "@shikijs/transformers";
5
5
  import { numericRangeContains } from "@temelj/iterator";
6
- import { extractCodeMeta } from "./code-meta.js";
6
+ import { extractCodeMeta } from "./code-meta";
7
7
  /**
8
8
  * A plugin that highlights code blocks using Shiki.
9
9
  */
@@ -1,5 +1,5 @@
1
1
  import type { Plugin } from "unified";
2
- import type { HastElement, HastNode } from "../../types.js";
2
+ import type { HastElement, HastNode } from "../../types";
3
3
  export type MdxTreeProcessor = (node: HastElement, index: number, parent: HastElement) => void | Promise<void>;
4
4
  /**
5
5
  * Options for {@linkcode treeProcessorPlugin}.
@@ -16,4 +16,3 @@ export declare const treeProcessorPlugin: Plugin<[
16
16
  TreeProcessorPluginOptions?
17
17
  ], HastNode, HastNode>;
18
18
  export {};
19
- //# sourceMappingURL=plugin.d.ts.map
@@ -1,3 +1,2 @@
1
1
  import type { Element, Node } from "hast";
2
2
  export type { Element as HastElement, Node as HastNode };
3
- //# sourceMappingURL=types.d.ts.map
package/mod.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./plugins/mod";
2
+ export * from "./types";
3
+ export * from "./compiler";
package/package.json CHANGED
@@ -1,48 +1,46 @@
1
1
  {
2
2
  "name": "@temelj/mdx",
3
- "version": "0.7.0",
4
- "description": "Utilities for working with MDX.",
5
- "keywords": [
6
- "mdx"
7
- ],
8
- "repository": {
9
- "type": "git",
10
- "url": "git+https://github.com/tinrab/temelj.git"
11
- },
3
+ "description": "MDX processing utilities.",
12
4
  "license": "MIT",
13
- "bugs": {
14
- "url": "https://github.com/tinrab/temelj/issues"
15
- },
16
- "module": "./esm/mod.js",
17
- "types": "./types/mod.d.ts",
5
+ "version": "0.8.0",
6
+ "type": "module",
7
+ "main": "./dist/mod.js",
8
+ "types": "./dist/mod.d.ts",
18
9
  "exports": {
19
10
  ".": {
20
- "import": {
21
- "types": "./types/mod.d.ts",
22
- "default": "./esm/mod.js"
23
- }
11
+ "types": "./dist/mod.d.ts",
12
+ "import": "./dist/mod.js"
24
13
  }
25
14
  },
26
15
  "dependencies": {
27
- "@temelj/iterator": "^0.7.0",
28
- "@mdx-js/mdx": "^3.1.0",
29
- "@shikijs/transformers": "^3.8.0",
16
+ "@mdx-js/mdx": "^3.1.1",
17
+ "@shikijs/transformers": "^3.15.0",
30
18
  "@types/hast": "^3.0.4",
31
19
  "github-slugger": "^2.0.0",
32
20
  "hast": "^1.0.0",
33
21
  "hast-util-to-string": "^3.0.1",
34
22
  "remark-frontmatter": "^5.0.0",
35
23
  "remark-gfm": "^4.0.1",
36
- "shiki": "^3.8.0",
24
+ "remark-parse": "^11.0.0",
25
+ "shiki": "^3.15.0",
37
26
  "unified": "^11.0.5",
38
27
  "unist-util-remove": "^4.0.0",
39
28
  "unist-util-visit": "^5.0.0",
40
29
  "vfile": "^6.0.3",
41
30
  "vfile-matter": "^5.0.1",
42
- "zod": "^4.0.5"
31
+ "zod": "^4.1.12",
32
+ "@temelj/iterator": "0.8.0"
43
33
  },
44
34
  "devDependencies": {
45
- "@types/node": "^20.9.0"
35
+ "@types/mdast": "^4.0.4",
36
+ "@types/node": "24.10.0",
37
+ "typescript": "^5.9.3",
38
+ "vitest": "^4.0.8"
46
39
  },
47
- "_generatedBy": "dnt@dev"
40
+ "scripts": {
41
+ "build": "tsc",
42
+ "test": "vitest run",
43
+ "typecheck": "tsc --noEmit",
44
+ "clean": "shx rm -rf dist"
45
+ }
48
46
  }
@@ -0,0 +1,42 @@
1
+ import GithubSlugger from "github-slugger";
2
+ import { toString as hastToString } from "hast-util-to-string";
3
+ import { visit } from "unist-util-visit";
4
+ import type { Plugin } from "unified";
5
+
6
+ import type { HastElement, HastNode } from "../../types";
7
+
8
+ /**
9
+ * Options for {@linkcode headingIdPlugin}.
10
+ */
11
+ export interface HeadingIdPluginOptions {
12
+ /** Prefix for title slugs. */
13
+ prefix?: string;
14
+ }
15
+
16
+ /**
17
+ * A rehype plugin that adds IDs to heading tags.
18
+ */
19
+ export const headingIdPlugin: Plugin<
20
+ [HeadingIdPluginOptions?],
21
+ HastNode,
22
+ HastNode
23
+ > = ({ prefix } = {}) => {
24
+ const slugger = new GithubSlugger();
25
+ return (tree) => {
26
+ slugger.reset();
27
+ visit(
28
+ tree,
29
+ "element",
30
+ function visitor(
31
+ node: HastElement,
32
+ index: number,
33
+ parent: HastElement,
34
+ ): void {
35
+ if (!parent || index === null || !node.tagName.startsWith("h")) return;
36
+ const id = (prefix ?? "") + slugger.slug(hastToString(node));
37
+ node.properties.id = id;
38
+ },
39
+ );
40
+ return tree;
41
+ };
42
+ };
package/plugins/mod.ts ADDED
@@ -0,0 +1,4 @@
1
+ export * from "./heading-id/plugin";
2
+ export * from "./syntax-highlight/plugin";
3
+ export * from "./tree-processor/plugin";
4
+ export * from "./remove-imports-exports";
@@ -0,0 +1,18 @@
1
+ import { remove } from "unist-util-remove";
2
+ import type { Plugin } from "unified";
3
+
4
+ import type { HastNode } from "../types";
5
+
6
+ /**
7
+ * A remark plugin which removes all import and export statements.
8
+ */
9
+ export const removeImportsExportsPlugin: Plugin<
10
+ [unknown],
11
+ HastNode,
12
+ HastNode
13
+ > = () => {
14
+ return (tree: HastNode) => {
15
+ remove(tree, "mdxjsEsm");
16
+ return tree;
17
+ };
18
+ };
@@ -0,0 +1,22 @@
1
+ import { expect, test } from "vitest";
2
+
3
+ import { extractCodeMeta } from "./code-meta";
4
+
5
+ test("code meta - extract", () => {
6
+ expect(
7
+ extractCodeMeta({
8
+ type: "element",
9
+ tagName: "pre",
10
+ properties: {},
11
+ children: [],
12
+ data: {
13
+ meta: '{"highlight": "3..5", "showLineNumbers":true, "fileName":"test"}',
14
+ },
15
+ }),
16
+ {
17
+ highlight: { lineRange: [{ from: 3, to: 4 }] },
18
+ showLineNumbers: { lineRange: [] },
19
+ fileName: "test",
20
+ },
21
+ );
22
+ });
@@ -0,0 +1,76 @@
1
+ import { type NumericRange, parseNumericRange } from "@temelj/iterator";
2
+ import { z } from "zod";
3
+
4
+ import type { HastElement } from "../../types";
5
+
6
+ export interface MdxCodeMeta {
7
+ highlight?: MdxCodeMetaHighlightLine;
8
+ showLineNumbers?: MdxCodeMetaLineNumbers;
9
+ commandLine?: MdxCodeMetaCommandLine;
10
+ fileName?: string;
11
+ }
12
+
13
+ export type MdxCodeMetaHighlightLine = {
14
+ lineRange: NumericRange;
15
+ };
16
+
17
+ export type MdxCodeMetaLineNumbers = {
18
+ lineRange: NumericRange;
19
+ };
20
+
21
+ export type MdxCodeMetaCommandLine = {
22
+ commandRange: NumericRange;
23
+ };
24
+
25
+ export function extractCodeMeta(node: HastElement): MdxCodeMeta {
26
+ const meta = node?.data?.meta ?? node?.properties?.metastring ?? "";
27
+ return parseMetaString(meta as string);
28
+ }
29
+
30
+ const metaSchema = z.object({
31
+ highlight: z.optional(z.string()),
32
+ showLineNumbers: z.optional(z.union([z.boolean(), z.string()])),
33
+ commandLine: z.optional(z.union([z.boolean(), z.string()])),
34
+ fileName: z.optional(z.string()),
35
+ });
36
+
37
+ function parseMetaString(meta: string): MdxCodeMeta {
38
+ let raw: unknown;
39
+ try {
40
+ raw = JSON.parse(meta.trim());
41
+ } catch {
42
+ return {};
43
+ }
44
+ const parsed = metaSchema.parse(raw);
45
+ const options: MdxCodeMeta = {};
46
+
47
+ if (parsed.highlight !== undefined) {
48
+ options.highlight = { lineRange: parseNumericRange(parsed.highlight) };
49
+ }
50
+
51
+ if (parsed.showLineNumbers !== undefined) {
52
+ if (typeof parsed.showLineNumbers === "string") {
53
+ options.showLineNumbers = {
54
+ lineRange: parseNumericRange(parsed.showLineNumbers),
55
+ };
56
+ } else if (parsed.showLineNumbers) {
57
+ options.showLineNumbers = { lineRange: [] };
58
+ }
59
+ }
60
+
61
+ if (parsed.commandLine !== undefined) {
62
+ if (typeof parsed.commandLine === "string") {
63
+ options.commandLine = {
64
+ commandRange: parseNumericRange(parsed.commandLine),
65
+ };
66
+ } else if (parsed.commandLine) {
67
+ options.commandLine = { commandRange: [] };
68
+ }
69
+ }
70
+
71
+ if (parsed.fileName !== undefined) {
72
+ options.fileName = parsed.fileName.trim();
73
+ }
74
+
75
+ return options;
76
+ }
@@ -0,0 +1,266 @@
1
+ import { toString as hastToString } from "hast-util-to-string";
2
+ import {
3
+ type BundledLanguage,
4
+ type BundledTheme,
5
+ codeToHast,
6
+ type CodeToHastOptions,
7
+ ShikiError,
8
+ } from "shiki";
9
+ import { visit } from "unist-util-visit";
10
+ import {
11
+ transformerNotationHighlight,
12
+ type TransformerNotationHighlightOptions,
13
+ } from "@shikijs/transformers";
14
+ import { numericRangeContains } from "@temelj/iterator";
15
+ import type { Plugin } from "unified";
16
+ import type { Properties } from "hast";
17
+
18
+ import type { HastElement, HastNode } from "../../types";
19
+
20
+ import { extractCodeMeta } from "./code-meta";
21
+
22
+ type ShikiHastOptions = Partial<
23
+ CodeToHastOptions<BundledLanguage, BundledTheme>
24
+ >;
25
+
26
+ type SyntaxDataAttribute = "source-code" | "language" | "line-count";
27
+
28
+ /**
29
+ * Options for {@linkcode syntaxHighlightPlugin}.
30
+ */
31
+ export interface SyntaxHighlightPluginOptions {
32
+ /**
33
+ * Include these data attributes on the `<pre>` element.
34
+ * These might be useful to have when building custom code components.
35
+ */
36
+ includeDataAttributes?: SyntaxDataAttribute[];
37
+
38
+ /**
39
+ * Options for the highlight transformer.
40
+ */
41
+ highlight?: {
42
+ transformer?: TransformerNotationHighlightOptions;
43
+ };
44
+
45
+ /**
46
+ * Options for line numbers.
47
+ */
48
+ lineNumbers?: {
49
+ /**
50
+ * The name of the variable that contains the line number width.
51
+ * This is used for padding the line numbers so that they align.
52
+ */
53
+ widthVariableName?: string;
54
+ /**
55
+ * A class name to be added to the line numbers.
56
+ */
57
+ className?: string;
58
+ };
59
+
60
+ /**
61
+ * Options for command line.
62
+ */
63
+ commandLine?: {
64
+ /**
65
+ * A class name to be added to the prompt line.
66
+ */
67
+ className?: string;
68
+ };
69
+
70
+ /**
71
+ * Extra options for the Shiki hast transformer.
72
+ */
73
+ shikiHastOptions?: ShikiHastOptions;
74
+ }
75
+
76
+ /**
77
+ * A plugin that highlights code blocks using Shiki.
78
+ */
79
+ export const syntaxHighlightPlugin: Plugin<
80
+ [SyntaxHighlightPluginOptions?],
81
+ HastNode,
82
+ HastNode
83
+ > = (options: SyntaxHighlightPluginOptions = {}) => {
84
+ return async (tree) => {
85
+ const promises: Promise<void>[] = [];
86
+
87
+ async function visitor(
88
+ node: HastElement,
89
+ index: number,
90
+ parent: HastElement,
91
+ ): Promise<void> {
92
+ if (!parent || index === null || node.tagName !== "pre") {
93
+ return;
94
+ }
95
+
96
+ const codeNode = node.children[0];
97
+ if (
98
+ !codeNode ||
99
+ codeNode.type !== "element" ||
100
+ codeNode.tagName !== "code" ||
101
+ !codeNode.properties
102
+ ) {
103
+ return;
104
+ }
105
+
106
+ const lang = getNodeLanguage(codeNode);
107
+ if (typeof lang !== "string") {
108
+ return;
109
+ }
110
+
111
+ const meta = extractCodeMeta(codeNode);
112
+
113
+ const sourceCode = hastToString(codeNode).trim();
114
+
115
+ const hastOptions: CodeToHastOptions<BundledLanguage, BundledTheme> = {
116
+ tokenizeTimeLimit: 10_000,
117
+ lang,
118
+ themes: {
119
+ light: "github-light-default",
120
+ dark: "github-dark-default",
121
+ },
122
+ ...(options.shikiHastOptions ?? {}),
123
+ };
124
+ if (hastOptions.transformers === undefined) {
125
+ hastOptions.transformers = [];
126
+ }
127
+
128
+ if (options.highlight) {
129
+ hastOptions.transformers.push(
130
+ transformerNotationHighlight({
131
+ ...(options.highlight.transformer ?? {}),
132
+ matchAlgorithm: "v3",
133
+ }),
134
+ );
135
+ }
136
+
137
+ let lineCount = 0;
138
+ hastOptions.transformers.push({
139
+ code(node): void {
140
+ let lineIndex = 0;
141
+ for (const line of node.children.filter(
142
+ (node: HastNode) => node.type === "element",
143
+ ) as HastElement[]) {
144
+ line.properties["data-line"] = lineIndex + 1;
145
+
146
+ if (options.highlight) {
147
+ if (
148
+ meta.highlight &&
149
+ numericRangeContains(meta.highlight.lineRange, lineIndex)
150
+ ) {
151
+ this.addClassToHast(
152
+ line,
153
+ options.highlight.transformer?.classActiveLine ??
154
+ "highlighted",
155
+ );
156
+ }
157
+ }
158
+
159
+ if (
160
+ options.lineNumbers &&
161
+ meta.showLineNumbers &&
162
+ (meta.showLineNumbers.lineRange.length === 0 ||
163
+ numericRangeContains(meta.showLineNumbers.lineRange, lineIndex))
164
+ ) {
165
+ this.addClassToHast(
166
+ line,
167
+ options.lineNumbers.className ?? "line-number",
168
+ );
169
+ }
170
+
171
+ if (
172
+ options.commandLine &&
173
+ meta.commandLine &&
174
+ (meta.commandLine.commandRange.length === 0 ||
175
+ numericRangeContains(meta.commandLine.commandRange, lineIndex))
176
+ ) {
177
+ this.addClassToHast(
178
+ line,
179
+ options.commandLine.className ?? "line-command",
180
+ );
181
+ }
182
+
183
+ lineIndex++;
184
+ }
185
+
186
+ lineCount = lineIndex;
187
+
188
+ if (meta.showLineNumbers) {
189
+ if (typeof node.properties.style !== "string") {
190
+ node.properties.style = "";
191
+ }
192
+ node.properties.style += `--${
193
+ options.lineNumbers?.widthVariableName ?? "line-number-width"
194
+ }:${1 + Math.floor(Math.log10(this.lines.length))}ch;`;
195
+ }
196
+ },
197
+ });
198
+
199
+ try {
200
+ const hast = await codeToHast(sourceCode, hastOptions);
201
+
202
+ // Insert highlighted code into parent
203
+ const hastPre = hast.children[0] as HastElement;
204
+
205
+ const properties: Properties = {
206
+ ...hastPre.properties,
207
+ dataFileName: meta.fileName,
208
+ };
209
+ if (options.includeDataAttributes) {
210
+ if (options.includeDataAttributes.includes("language")) {
211
+ properties.dataLanguage = lang;
212
+ }
213
+ if (options.includeDataAttributes.includes("source-code")) {
214
+ properties.dataSourceCode = sourceCode;
215
+ }
216
+ if (options.includeDataAttributes.includes("line-count")) {
217
+ properties.dataLineCount = lineCount;
218
+ }
219
+ }
220
+
221
+ parent.children.splice(index, 1, {
222
+ ...hastPre,
223
+ properties,
224
+ });
225
+ } catch (error) {
226
+ if (error instanceof ShikiError) {
227
+ if (
228
+ error.message.includes(
229
+ "Language `math` is not included in this bundle",
230
+ )
231
+ ) {
232
+ // Skip if the block is math block.
233
+ return;
234
+ }
235
+ }
236
+ throw error;
237
+ }
238
+ }
239
+
240
+ visit(
241
+ tree,
242
+ "element",
243
+ (node: HastElement, index: number, parent: HastElement) => {
244
+ promises.push(visitor(node, index, parent));
245
+ },
246
+ );
247
+
248
+ await Promise.all(promises);
249
+
250
+ return tree;
251
+ };
252
+ };
253
+
254
+ function getNodeLanguage(node: HastElement): string | undefined {
255
+ if (!Array.isArray(node.properties.className)) {
256
+ return undefined;
257
+ }
258
+ const prefix = "language-";
259
+ const language = node.properties.className.find(
260
+ (name) => typeof name === "string" && name.startsWith(prefix),
261
+ ) as string | undefined;
262
+ if (typeof language === "string") {
263
+ return language.slice(prefix.length);
264
+ }
265
+ return language;
266
+ }
@@ -0,0 +1,54 @@
1
+ import { visit } from "unist-util-visit";
2
+ import type { Plugin } from "unified";
3
+
4
+ import type { HastElement, HastNode } from "../../types";
5
+
6
+ export type MdxTreeProcessor = (
7
+ node: HastElement,
8
+ index: number,
9
+ parent: HastElement,
10
+ ) => void | Promise<void>;
11
+
12
+ /**
13
+ * Options for {@linkcode treeProcessorPlugin}.
14
+ */
15
+ type TreeProcessorPluginOptions = {
16
+ /** The processor. */
17
+ process: MdxTreeProcessor;
18
+ };
19
+
20
+ /**
21
+ * A plugin that allows to process MDX tree nodes.
22
+ * It can be async or sync.
23
+ */
24
+ export const treeProcessorPlugin: Plugin<
25
+ [TreeProcessorPluginOptions?],
26
+ HastNode,
27
+ HastNode
28
+ > = ({ process } = { process: () => {} }) => {
29
+ return async (tree) => {
30
+ const promises: Promise<void>[] = [];
31
+
32
+ visit(
33
+ tree,
34
+ "element",
35
+ function visitor(
36
+ node: HastElement,
37
+ index: number,
38
+ parent: HastElement,
39
+ ): void {
40
+ const p = process(node, index, parent);
41
+ if (
42
+ p instanceof Promise ||
43
+ Object.prototype.toString.call(p) === "[object Promise]"
44
+ ) {
45
+ promises.push(p as Promise<void>);
46
+ }
47
+ },
48
+ );
49
+
50
+ await Promise.allSettled(promises);
51
+
52
+ return tree;
53
+ };
54
+ };
package/tsconfig.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "declaration": true,
7
+ "outDir": "./dist",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "paths": {
13
+ "@temelj/iterator": ["../iterator/src/mod"]
14
+ }
15
+ },
16
+ "include": ["./**/*"],
17
+ "exclude": ["node_modules", "dist", "**/*.test.ts"]
18
+ }
package/types.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { Element, Node } from "hast";
2
+
3
+ export type { Element as HastElement, Node as HastNode };
package/esm/mod.js DELETED
@@ -1,3 +0,0 @@
1
- export * from "./plugins/mod.js";
2
- export * from "./types.js";
3
- export * from "./compiler.js";
package/esm/package.json DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "type": "module"
3
- }
@@ -1,4 +0,0 @@
1
- export * from "./heading-id/plugin.js";
2
- export * from "./syntax-highlight/plugin.js";
3
- export * from "./tree-processor/plugin.js";
4
- export * from "./remove-imports-exports.js";
@@ -1 +0,0 @@
1
- {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,IAAI,mBAAmB,EAC3C,MAAM,aAAa,CAAC;AACrB,OAAO,uBAAuB,MAAM,oBAAoB,CAAC;AACzD,OAAO,eAAe,MAAM,YAAY,CAAC;AAGzC,OAAO,KAAK,EAA4B,MAAM,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,EAAE,uBAAuB,EAAE,eAAe,EAAE,CAAC;AAEpD;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,eAAe,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,UAAU,CAAC,EAAE,mBAAmB,CAAC;CAClC;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW,CAAC,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACjE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,WAAW,EAAE,YAAY,CAAC;CAC3B;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsB;IACjD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;gBAE3B,UAAU,GAAE,mBAAwB;IAMhD,gBAAgB,CAAC,QAAQ,EAC9B,MAAM,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAC/C,OAAO,CAAC,EAAE,QAAQ,GACjB,WAAW;IASP,gBAAgB,CAAC,QAAQ,EAC9B,MAAM,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAC/C,OAAO,CAAC,EAAE,QAAQ,GACjB,WAAW;IASD,OAAO,CAAC,kBAAkB,SAAS,CAAC,CAAC,SAAS,EACzD,MAAM,EAAE,SAAS,EACjB,EAAE,eAAuB,EAAE,UAAU,EAAE,GAAE,iBAAsB,EAC/D,iBAAiB,CAAC,EAAE,kBAAkB,GACrC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC;CA2CtD"}
package/types/mod.d.ts DELETED
@@ -1,4 +0,0 @@
1
- export * from "./plugins/mod.js";
2
- export * from "./types.js";
3
- export * from "./compiler.js";
4
- //# sourceMappingURL=mod.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/heading-id/plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,OAAO,KAAK,EAAe,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,8BAA8B;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAClC;IAAC,sBAAsB,CAAC;CAAC,EACzB,QAAQ,EACR,QAAQ,CAoBT,CAAC"}
@@ -1,5 +0,0 @@
1
- export * from "./heading-id/plugin.js";
2
- export * from "./syntax-highlight/plugin.js";
3
- export * from "./tree-processor/plugin.js";
4
- export * from "./remove-imports-exports.js";
5
- //# sourceMappingURL=mod.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/plugins/mod.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"remove-imports-exports.d.ts","sourceRoot":"","sources":["../../src/plugins/remove-imports-exports.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C;;GAEG;AACH,eAAO,MAAM,0BAA0B,EAAE,MAAM,CAC7C;IAAC,OAAO;CAAC,EACT,QAAQ,EACR,QAAQ,CAMT,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"code-meta.d.ts","sourceRoot":"","sources":["../../../src/plugins/syntax-highlight/code-meta.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAqB,MAAM,kBAAkB,CAAC;AAGxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,wBAAwB,CAAC;IACrC,eAAe,CAAC,EAAE,sBAAsB,CAAC;IACzC,WAAW,CAAC,EAAE,sBAAsB,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,YAAY,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,YAAY,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,YAAY,EAAE,YAAY,CAAC;CAC5B,CAAC;AAEF,wBAAgB,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,WAAW,CAG9D"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/syntax-highlight/plugin.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,YAAY,EAEjB,KAAK,iBAAiB,EAEvB,MAAM,OAAO,CAAC;AAEf,OAAO,EAEL,KAAK,mCAAmC,EACzC,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAGtC,OAAO,KAAK,EAAe,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAI5D,KAAK,gBAAgB,GAAG,OAAO,CAC7B,iBAAiB,CAAC,eAAe,EAAE,YAAY,CAAC,CACjD,CAAC;AAEF,KAAK,mBAAmB,GAAG,aAAa,GAAG,UAAU,GAAG,YAAY,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;OAGG;IACH,qBAAqB,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAE9C;;OAEG;IACH,SAAS,CAAC,EAAE;QACV,WAAW,CAAC,EAAE,mCAAmC,CAAC;KACnD,CAAC;IAEF;;OAEG;IACH,WAAW,CAAC,EAAE;QACZ;;;WAGG;QACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B;;WAEG;QACH,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IAEF;;OAEG;IACH,WAAW,CAAC,EAAE;QACZ;;WAEG;QACH,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IAEF;;OAEG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAED;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CACxC;IAAC,4BAA4B,CAAC;CAAC,EAC/B,QAAQ,EACR,QAAQ,CA4KT,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/tree-processor/plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE5D,MAAM,MAAM,gBAAgB,GAAG,CAC7B,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,WAAW,KAChB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B;;GAEG;AACH,KAAK,0BAA0B,GAAG;IAChC,qBAAqB;IACrB,OAAO,EAAE,gBAAgB,CAAC;CAC3B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CACtC;IAAC,0BAA0B,CAAC;CAAC,EAC7B,QAAQ,EACR,QAAQ,CA2BT,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE1C,YAAY,EAAE,OAAO,IAAI,WAAW,EAAE,IAAI,IAAI,QAAQ,EAAE,CAAC"}
File without changes
File without changes
File without changes
File without changes