@shikijs/twoslash 1.13.0 → 1.14.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/dist/core.d.mts CHANGED
@@ -43,6 +43,11 @@ interface TransformerTwoslashOptions {
43
43
  * Custom renderers to decide how each info should be rendered
44
44
  */
45
45
  renderer?: TwoslashRenderer;
46
+ /**
47
+ * A map to store code for `@include` directive
48
+ * Provide your own instance if you want to clear the map between each transformation
49
+ */
50
+ includesMap?: Map<string, string>;
46
51
  /**
47
52
  * Strictly throw when there is an error
48
53
  * @default true
package/dist/core.d.ts CHANGED
@@ -43,6 +43,11 @@ interface TransformerTwoslashOptions {
43
43
  * Custom renderers to decide how each info should be rendered
44
44
  */
45
45
  renderer?: TwoslashRenderer;
46
+ /**
47
+ * A map to store code for `@include` directive
48
+ * Provide your own instance if you want to clear the map between each transformation
49
+ */
50
+ includesMap?: Map<string, string>;
46
51
  /**
47
52
  * Strictly throw when there is an error
48
53
  * @default true
package/dist/core.mjs CHANGED
@@ -7,6 +7,52 @@ class ShikiTwoslashError extends Error {
7
7
  }
8
8
  }
9
9
 
10
+ class TwoslashIncludesManager {
11
+ constructor(map = /* @__PURE__ */ new Map()) {
12
+ this.map = map;
13
+ }
14
+ add(name, code) {
15
+ const lines = [];
16
+ code.split("\n").forEach((l, _i) => {
17
+ const trimmed = l.trim();
18
+ if (trimmed.startsWith("// - ")) {
19
+ const key = trimmed.split("// - ")[1].split(" ")[0];
20
+ this.map.set(`${name}-${key}`, lines.join("\n"));
21
+ } else {
22
+ lines.push(l);
23
+ }
24
+ });
25
+ this.map.set(name, lines.join("\n"));
26
+ }
27
+ applyInclude(code) {
28
+ const reMarker = /\/\/ @include: (.*)$/gm;
29
+ const toReplace = [];
30
+ for (const match of code.matchAll(reMarker)) {
31
+ const key = match[1];
32
+ const replaceWith = this.map.get(key);
33
+ if (!replaceWith) {
34
+ const msg = `Could not find an include with the key: '${key}'.
35
+ There is: ${Array.from(this.map.keys())}.`;
36
+ throw new Error(msg);
37
+ } else {
38
+ toReplace.push([match.index, match[0].length, replaceWith]);
39
+ }
40
+ }
41
+ let newCode = code.toString();
42
+ toReplace.reverse().forEach((r) => {
43
+ newCode = newCode.slice(0, r[0]) + r[2] + newCode.slice(r[0] + r[1]);
44
+ });
45
+ return newCode;
46
+ }
47
+ }
48
+ const INCLUDE_META_REGEX = /include\s+([\w-]+)\b.*/;
49
+ function parseIncludeMeta(meta) {
50
+ if (!meta)
51
+ return null;
52
+ const match = meta.match(INCLUDE_META_REGEX);
53
+ return match?.[1] ?? null;
54
+ }
55
+
10
56
  const module = {
11
57
  type: "element",
12
58
  tagName: "svg",
@@ -1046,7 +1092,8 @@ function createTransformerFactory(defaultTwoslasher, defaultRenderer) {
1046
1092
  twoslasher = defaultTwoslasher,
1047
1093
  explicitTrigger = false,
1048
1094
  renderer = defaultRenderer,
1049
- throws = true
1095
+ throws = true,
1096
+ includesMap = /* @__PURE__ */ new Map()
1050
1097
  } = options;
1051
1098
  const onTwoslashError = options.onTwoslashError || (throws ? (error) => {
1052
1099
  throw error;
@@ -1059,6 +1106,7 @@ function createTransformerFactory(defaultTwoslasher, defaultRenderer) {
1059
1106
  throw new ShikiTwoslashError("Missing renderer");
1060
1107
  const map = /* @__PURE__ */ new WeakMap();
1061
1108
  const filter = options.filter || ((lang, _, options2) => langs.includes(lang) && (!explicitTrigger || trigger.test(options2.meta?.__raw || "")));
1109
+ const includes = new TwoslashIncludesManager(includesMap);
1062
1110
  return {
1063
1111
  preprocess(code) {
1064
1112
  let lang = this.options.lang;
@@ -1066,7 +1114,11 @@ function createTransformerFactory(defaultTwoslasher, defaultRenderer) {
1066
1114
  lang = langAlias[this.options.lang];
1067
1115
  if (filter(lang, code, this.options)) {
1068
1116
  try {
1069
- const twoslash = twoslasher(code, lang, twoslashOptions);
1117
+ const include = parseIncludeMeta(this.options.meta?.__raw);
1118
+ if (include)
1119
+ includes.add(include, code);
1120
+ const codeWithIncludes = includes.applyInclude(code);
1121
+ const twoslash = twoslasher(codeWithIncludes, lang, twoslashOptions);
1070
1122
  map.set(this.meta, twoslash);
1071
1123
  this.meta.twoslash = twoslash;
1072
1124
  this.options.lang = twoslash.meta?.extension || lang;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shikijs/twoslash",
3
3
  "type": "module",
4
- "version": "1.13.0",
4
+ "version": "1.14.0",
5
5
  "description": "Shiki transformer for twoslash",
6
6
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -50,7 +50,7 @@
50
50
  ],
51
51
  "dependencies": {
52
52
  "twoslash": "^0.2.9",
53
- "@shikijs/core": "1.13.0"
53
+ "@shikijs/core": "1.14.0"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@iconify-json/carbon": "^1.1.37",