@mintlify/cli 4.0.1432 → 4.0.1434

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.
@@ -1033,6 +1033,7 @@ function getImageWidthFromStyle(style) {
1033
1033
  }
1034
1034
 
1035
1035
  // ../editor/dist/converter/parse/handlers/media.js
1036
+ var isAttributeRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
1036
1037
  function parseImgNode(node, spreadAttrs = false) {
1037
1038
  const attributes = parseMdxAttributes(node.attributes);
1038
1039
  const className = attributes.className;
@@ -1042,7 +1043,7 @@ function parseImgNode(node, spreadAttrs = false) {
1042
1043
  }
1043
1044
  const style = attributes.style;
1044
1045
  let width;
1045
- if (style && typeof style === "object") {
1046
+ if (isAttributeRecord(style)) {
1046
1047
  width = getImageWidthFromStyle(style);
1047
1048
  }
1048
1049
  return {
@@ -1050,8 +1051,18 @@ function parseImgNode(node, spreadAttrs = false) {
1050
1051
  attrs: { imgAttributes: spreadAttrs ? Object.assign({}, attributes) : attributes, align, width }
1051
1052
  };
1052
1053
  }
1054
+ function isVideoSourceElement(child) {
1055
+ return (child.type === "mdxJsxTextElement" || child.type === "mdxJsxFlowElement") && child.name === "source";
1056
+ }
1053
1057
  function parseVideoNode(node) {
1054
- const sources = node.children.filter((child) => (child.type === "mdxJsxTextElement" || child.type === "mdxJsxFlowElement") && child.name === "source").map((child) => parseMdxAttributes(child.attributes));
1058
+ const editable = node.children.every((child) => isVideoSourceElement(child) || child.type === "text" && child.value.trim() === "");
1059
+ if (!editable) {
1060
+ return {
1061
+ type: node.type === "mdxJsxTextElement" ? BLOCK_TYPES.inlineUnknownTag : BLOCK_TYPES.unknownTag,
1062
+ attrs: { mdxJsxNode: node }
1063
+ };
1064
+ }
1065
+ const sources = node.children.filter(isVideoSourceElement).map((child) => parseMdxAttributes(child.attributes));
1055
1066
  return {
1056
1067
  type: BLOCK_TYPES.video,
1057
1068
  attrs: {
@@ -1061,9 +1072,15 @@ function parseVideoNode(node) {
1061
1072
  };
1062
1073
  }
1063
1074
  var DARK_ONLY_CLASSES = /* @__PURE__ */ new Set(["hidden", "dark:block"]);
1075
+ var LIGHT_ONLY_CLASSES = /* @__PURE__ */ new Set(["dark:hidden"]);
1076
+ function readImageAttributes(node) {
1077
+ var _a;
1078
+ const attributes = (_a = node.attrs) === null || _a === void 0 ? void 0 : _a.imgAttributes;
1079
+ return isAttributeRecord(attributes) ? attributes : null;
1080
+ }
1064
1081
  function getImageClassName(node) {
1065
- var _a, _b;
1066
- const className = (_b = (_a = node.attrs) === null || _a === void 0 ? void 0 : _a.imgAttributes) === null || _b === void 0 ? void 0 : _b.className;
1082
+ var _a;
1083
+ const className = (_a = readImageAttributes(node)) === null || _a === void 0 ? void 0 : _a.className;
1067
1084
  return typeof className === "string" ? className : void 0;
1068
1085
  }
1069
1086
  function isDarkOnlyImage(node) {
@@ -1083,18 +1100,35 @@ function isLightOnlyImage(node) {
1083
1100
  return false;
1084
1101
  return className.split(/\s+/).includes("dark:hidden");
1085
1102
  }
1086
- function stripThemeClasses(className) {
1087
- const cleaned = className.split(/\s+/).filter((c) => !DARK_ONLY_CLASSES.has(c) && c !== "dark:hidden").join(" ").trim();
1103
+ function stripThemeClasses(className, role) {
1104
+ if (!className)
1105
+ return void 0;
1106
+ const themeClasses = role === "dark" ? DARK_ONLY_CLASSES : LIGHT_ONLY_CLASSES;
1107
+ const cleaned = className.split(/\s+/).filter((c) => !themeClasses.has(c)).join(" ").trim();
1088
1108
  return cleaned || void 0;
1089
1109
  }
1110
+ function nonThemeAttributeEntries(attrs2) {
1111
+ return Object.entries(attrs2).filter(([key]) => key !== "src" && key !== "className").sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
1112
+ }
1113
+ function canMergeAsThemePair(lightImgAttrs, darkImgAttrs, lightClassName, darkClassName) {
1114
+ const lightBase = stripThemeClasses(lightClassName, "light");
1115
+ const darkBase = stripThemeClasses(darkClassName, "dark");
1116
+ const lightBaseWithoutBlock = (lightBase === null || lightBase === void 0 ? void 0 : lightBase.split(/\s+/).filter((c) => c !== "block").join(" ").trim()) || void 0;
1117
+ if (darkBase !== lightBase && darkBase !== lightBaseWithoutBlock) {
1118
+ return false;
1119
+ }
1120
+ const lightEntries = nonThemeAttributeEntries(lightImgAttrs);
1121
+ const darkEntries = nonThemeAttributeEntries(darkImgAttrs);
1122
+ return lightEntries.length === darkEntries.length && JSON.stringify(lightEntries) === JSON.stringify(darkEntries);
1123
+ }
1090
1124
  function mergeDarkLightImagePairs(nodes2) {
1091
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
1125
+ var _a, _b, _c, _d, _e, _f;
1092
1126
  const result = [];
1093
1127
  let i = 0;
1094
1128
  while (i < nodes2.length) {
1095
- if (i + 1 < nodes2.length) {
1096
- const current = nodes2[i];
1097
- const next = nodes2[i + 1];
1129
+ const current = nodes2[i];
1130
+ const next = nodes2[i + 1];
1131
+ if (current && next) {
1098
1132
  let darkNode;
1099
1133
  let lightNode;
1100
1134
  if (isDarkOnlyImage(current) && isLightOnlyImage(next)) {
@@ -1104,12 +1138,12 @@ function mergeDarkLightImagePairs(nodes2) {
1104
1138
  lightNode = current;
1105
1139
  darkNode = next;
1106
1140
  }
1107
- if (darkNode && lightNode) {
1108
- const darkImgAttrs = (_a = darkNode.attrs) === null || _a === void 0 ? void 0 : _a.imgAttributes;
1109
- const lightImgAttrs = (_b = lightNode.attrs) === null || _b === void 0 ? void 0 : _b.imgAttributes;
1110
- const darkSrc = darkImgAttrs.src;
1111
- const lightSrc = lightImgAttrs.src;
1112
- const baseClassName = stripThemeClasses((_d = (_c = getImageClassName(lightNode)) !== null && _c !== void 0 ? _c : getImageClassName(darkNode)) !== null && _d !== void 0 ? _d : "");
1141
+ const darkImgAttrs = darkNode ? readImageAttributes(darkNode) : null;
1142
+ const lightImgAttrs = lightNode ? readImageAttributes(lightNode) : null;
1143
+ const darkSrc = darkImgAttrs === null || darkImgAttrs === void 0 ? void 0 : darkImgAttrs.src;
1144
+ const lightSrc = lightImgAttrs === null || lightImgAttrs === void 0 ? void 0 : lightImgAttrs.src;
1145
+ if (darkNode && lightNode && darkImgAttrs && lightImgAttrs && typeof darkSrc === "string" && typeof lightSrc === "string" && canMergeAsThemePair(lightImgAttrs, darkImgAttrs, getImageClassName(lightNode), getImageClassName(darkNode))) {
1146
+ const baseClassName = stripThemeClasses(getImageClassName(lightNode), "light");
1113
1147
  const mergedImgAttrs = Object.assign({}, lightImgAttrs);
1114
1148
  delete mergedImgAttrs.src;
1115
1149
  if (baseClassName) {
@@ -1123,15 +1157,16 @@ function mergeDarkLightImagePairs(nodes2) {
1123
1157
  imgAttributes: mergedImgAttrs,
1124
1158
  lightSrc,
1125
1159
  darkSrc,
1126
- align: (_f = (_e = lightNode.attrs) === null || _e === void 0 ? void 0 : _e.align) !== null && _f !== void 0 ? _f : (_g = darkNode.attrs) === null || _g === void 0 ? void 0 : _g.align,
1127
- width: (_j = (_h = lightNode.attrs) === null || _h === void 0 ? void 0 : _h.width) !== null && _j !== void 0 ? _j : (_k = darkNode.attrs) === null || _k === void 0 ? void 0 : _k.width
1160
+ align: (_b = (_a = lightNode.attrs) === null || _a === void 0 ? void 0 : _a.align) !== null && _b !== void 0 ? _b : (_c = darkNode.attrs) === null || _c === void 0 ? void 0 : _c.align,
1161
+ width: (_e = (_d = lightNode.attrs) === null || _d === void 0 ? void 0 : _d.width) !== null && _e !== void 0 ? _e : (_f = darkNode.attrs) === null || _f === void 0 ? void 0 : _f.width
1128
1162
  }
1129
1163
  });
1130
1164
  i += 2;
1131
1165
  continue;
1132
1166
  }
1133
1167
  }
1134
- result.push(nodes2[i]);
1168
+ if (current)
1169
+ result.push(current);
1135
1170
  i++;
1136
1171
  }
1137
1172
  return result;
@@ -1158,7 +1193,7 @@ function convertToInlineImage(node) {
1158
1193
  let width = 100;
1159
1194
  if (attributes.width && typeof attributes.width === "number") {
1160
1195
  width = attributes.width;
1161
- } else if (attributes.style && typeof attributes.style === "object") {
1196
+ } else if (isAttributeRecord(attributes.style)) {
1162
1197
  const styleWidth = getImageWidthFromStyle(attributes.style);
1163
1198
  if (styleWidth)
1164
1199
  width = styleWidth;
@@ -2654,29 +2689,54 @@ function isJSXContent(str) {
2654
2689
  function getTextContent(node) {
2655
2690
  return node.textContent;
2656
2691
  }
2692
+ var BARE_OBJECT_KEY = /^[A-Za-z_$][\w$]*$/;
2657
2693
  function serializePropValue(v) {
2658
2694
  if (v === null || v === void 0)
2659
2695
  return null;
2660
2696
  if (typeof v === "object") {
2661
- const value = JSON.stringify(v).replace(/"([^"]+)":/g, "$1:").replace(/: "([^"]+)"/g, ": '$1'").replace(/^{/g, "{ ").replace(/}$/g, " }");
2662
- return `{${value}}`;
2697
+ const literal = Array.isArray(v) ? serializeJsValue(v) : serializeJsObjectLiteral(v, true);
2698
+ return `{${literal}}`;
2663
2699
  }
2664
2700
  if (typeof v === "string") {
2665
2701
  if (v === "")
2666
- return null;
2667
- if (isJSXContent(v) || v.includes('"') && v.includes("'")) {
2702
+ return '""';
2703
+ if (isJSXContent(v)) {
2668
2704
  return `{${v}}`;
2669
2705
  }
2670
- if (v.includes('"') && !v.includes("'")) {
2706
+ if (v.includes('"') && v.includes("'")) {
2707
+ return `{${JSON.stringify(v)}}`;
2708
+ }
2709
+ if (v.includes('"')) {
2671
2710
  return `'${v}'`;
2672
2711
  }
2673
- return `"${v.replace(/"/g, '\\"')}"`;
2712
+ return `"${v}"`;
2674
2713
  }
2675
2714
  if (typeof v === "number" || typeof v === "boolean") {
2676
2715
  return `{${v}}`;
2677
2716
  }
2678
2717
  return `{${JSON.stringify(v)}}`;
2679
2718
  }
2719
+ function serializeJsValue(value) {
2720
+ var _a;
2721
+ if (value === null || value === void 0)
2722
+ return "null";
2723
+ if (typeof value === "string")
2724
+ return JSON.stringify(value);
2725
+ if (typeof value === "number" || typeof value === "boolean")
2726
+ return String(value);
2727
+ if (Array.isArray(value))
2728
+ return `[${value.map(serializeJsValue).join(",")}]`;
2729
+ if (typeof value === "object")
2730
+ return serializeJsObjectLiteral(value, false);
2731
+ return (_a = JSON.stringify(value)) !== null && _a !== void 0 ? _a : "null";
2732
+ }
2733
+ function serializeJsObjectLiteral(value, outermost) {
2734
+ const entries = Object.entries(value).filter(([, entry]) => entry !== void 0).map(([key, entry]) => {
2735
+ const literalKey = BARE_OBJECT_KEY.test(key) ? key : JSON.stringify(key);
2736
+ return `${literalKey}:${serializeJsValue(entry)}`;
2737
+ });
2738
+ return outermost ? `{ ${entries.join(",")} }` : `{${entries.join(",")}}`;
2739
+ }
2680
2740
  function serializeJsxAttribute(attrs2, key, value) {
2681
2741
  const rawExpression = getNamedExpressionAttr(attrs2, key);
2682
2742
  if (rawExpression !== void 0) {
@@ -2688,9 +2748,10 @@ function serializeJsxAttribute(attrs2, key, value) {
2688
2748
  const serialized = serializePropValue(value);
2689
2749
  return serialized ? `${key}=${serialized}` : null;
2690
2750
  }
2751
+ var isAttributeRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
2691
2752
  function getNamedExpressionAttr(attrs2, key) {
2692
2753
  const raw = attrs2[NAMED_EXPRESSION_ATTRS_KEY];
2693
- if (!raw || typeof raw !== "object" || Array.isArray(raw))
2754
+ if (!isAttributeRecord2(raw))
2694
2755
  return void 0;
2695
2756
  const value = raw[key];
2696
2757
  return typeof value === "string" ? value : void 0;
@@ -2783,7 +2844,7 @@ function renderImage(state, node) {
2783
2844
  return;
2784
2845
  }
2785
2846
  const hasExtraAttrs = Object.keys(imgAttributes).some((attr) => attr !== "src" && attr !== "alt" && attr !== "title");
2786
- if (hasExtraAttrs || width || align) {
2847
+ if (hasExtraAttrs || width || align || !fitsMarkdownImageValues(Object.assign(Object.assign({}, imgAttributes), { src }))) {
2787
2848
  const finalAttrs = Object.assign(Object.assign({}, imgAttributes), { src });
2788
2849
  if (align) {
2789
2850
  finalAttrs["className"] = addAlignClass(finalAttrs["className"], align);
@@ -2843,11 +2904,27 @@ function writeMarkdownImage(state, imgAttributes, src) {
2843
2904
  state.write(`![${alt}](${escapedSrc})`);
2844
2905
  }
2845
2906
  }
2907
+ var MARKDOWN_UNSAFE_SRC = /[\s<>\u0000-\u001F]/;
2908
+ var MARKDOWN_UNSAFE_TEXT = /[\r\n]/;
2909
+ function fitsMarkdownImageValues(attrs2) {
2910
+ const src = attrs2["src"];
2911
+ if (typeof src !== "string" || !src || MARKDOWN_UNSAFE_SRC.test(src))
2912
+ return false;
2913
+ const alt = attrs2["alt"];
2914
+ if (typeof alt === "string" && MARKDOWN_UNSAFE_TEXT.test(alt))
2915
+ return false;
2916
+ const title = attrs2["title"];
2917
+ if (typeof title === "string" && MARKDOWN_UNSAFE_TEXT.test(title))
2918
+ return false;
2919
+ return true;
2920
+ }
2846
2921
  function fitsMarkdownImageSyntax(node, attrs2) {
2847
2922
  if (!node.marks.some((mark) => mark.type.name === "link"))
2848
2923
  return false;
2849
2924
  if (typeof attrs2["src"] !== "string" || !attrs2["src"])
2850
2925
  return false;
2926
+ if (!fitsMarkdownImageValues(attrs2))
2927
+ return false;
2851
2928
  return Object.entries(attrs2).every(([key, value]) => key === "src" || key === "alt" || key === "title" || value == null);
2852
2929
  }
2853
2930
  function renderInlineImage(state, node) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mintlify/cli",
3
- "version": "4.0.1432",
3
+ "version": "4.0.1434",
4
4
  "description": "The Mintlify CLI",
5
5
  "engines": {
6
6
  "node": ">=18.0.0"
@@ -82,7 +82,7 @@
82
82
  "keytar": "7.9.0"
83
83
  },
84
84
  "devDependencies": {
85
- "@mintlify/editor": "0.0.325",
85
+ "@mintlify/editor": "0.0.327",
86
86
  "@mintlify/ts-config": "2.0.2",
87
87
  "@tsconfig/recommended": "1.0.2",
88
88
  "@types/detect-port": "1.3.2",
@@ -101,5 +101,5 @@
101
101
  "vitest": "2.1.9",
102
102
  "vitest-mock-process": "1.0.4"
103
103
  },
104
- "gitHead": "c3a18ca2f7c1a365a15b6a5dc0d467d67a86d2bb"
104
+ "gitHead": "5cb92d6b0de80a8e282e3db6157961e56e1952a4"
105
105
  }