gtx-cli 2.6.31 → 2.7.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 (348) hide show
  1. package/CHANGELOG.md +4 -1261
  2. package/README.md +12 -3
  3. package/dist/bin/bin-entry.js +2 -1
  4. package/dist/config/generateSettings.d.ts +1 -9
  5. package/dist/config/generateSettings.js +1 -214
  6. package/dist/config/resolveConfig.d.ts +1 -4
  7. package/dist/config/resolveConfig.js +1 -33
  8. package/dist/fs/config/setupConfig.d.ts +1 -17
  9. package/dist/fs/config/setupConfig.js +1 -50
  10. package/dist/fs/matchFiles.d.ts +1 -1
  11. package/dist/fs/matchFiles.js +1 -8
  12. package/dist/functions.d.ts +1 -7
  13. package/dist/functions.js +1 -6
  14. package/dist/index.d.ts +1 -4
  15. package/dist/index.js +1 -27
  16. package/dist/main.js +2 -2
  17. package/dist/next/parse/handleInitGT.d.ts +1 -7
  18. package/dist/next/parse/handleInitGT.js +1 -157
  19. package/dist/next/parse/wrapContent.d.ts +1 -12
  20. package/dist/next/parse/wrapContent.js +1 -164
  21. package/dist/react/parse/wrapContent.d.ts +1 -12
  22. package/dist/react/parse/wrapContent.js +1 -162
  23. package/dist/types/index.d.ts +1 -243
  24. package/dist/types/index.js +1 -1
  25. package/dist/utils/installPackage.d.ts +1 -3
  26. package/dist/utils/installPackage.js +1 -77
  27. package/dist/utils/packageInfo.d.ts +1 -3
  28. package/dist/utils/packageInfo.js +1 -17
  29. package/dist/utils/packageJson.d.ts +1 -6
  30. package/dist/utils/packageJson.js +1 -68
  31. package/dist/utils/packageManager.d.ts +1 -28
  32. package/dist/utils/packageManager.js +1 -269
  33. package/package.json +11 -97
  34. package/dist/api/collectUserEditDiffs.d.ts +0 -9
  35. package/dist/api/collectUserEditDiffs.js +0 -159
  36. package/dist/api/downloadFileBatch.d.ts +0 -23
  37. package/dist/api/downloadFileBatch.js +0 -190
  38. package/dist/api/saveLocalEdits.d.ts +0 -6
  39. package/dist/api/saveLocalEdits.js +0 -38
  40. package/dist/cli/base.d.ts +0 -59
  41. package/dist/cli/base.js +0 -529
  42. package/dist/cli/commands/download.d.ts +0 -8
  43. package/dist/cli/commands/download.js +0 -51
  44. package/dist/cli/commands/enqueue.d.ts +0 -9
  45. package/dist/cli/commands/enqueue.js +0 -27
  46. package/dist/cli/commands/setupProject.d.ts +0 -7
  47. package/dist/cli/commands/setupProject.js +0 -37
  48. package/dist/cli/commands/stage.d.ts +0 -9
  49. package/dist/cli/commands/stage.js +0 -59
  50. package/dist/cli/commands/translate.d.ts +0 -7
  51. package/dist/cli/commands/translate.js +0 -70
  52. package/dist/cli/commands/upload.d.ts +0 -13
  53. package/dist/cli/commands/upload.js +0 -142
  54. package/dist/cli/commands/utils/validation.d.ts +0 -13
  55. package/dist/cli/commands/utils/validation.js +0 -38
  56. package/dist/cli/flags.d.ts +0 -15
  57. package/dist/cli/flags.js +0 -70
  58. package/dist/cli/inline.d.ts +0 -17
  59. package/dist/cli/inline.js +0 -135
  60. package/dist/cli/next.d.ts +0 -10
  61. package/dist/cli/next.js +0 -12
  62. package/dist/cli/node.d.ts +0 -10
  63. package/dist/cli/node.js +0 -9
  64. package/dist/cli/react.d.ts +0 -12
  65. package/dist/cli/react.js +0 -72
  66. package/dist/config/optionPresets.d.ts +0 -3
  67. package/dist/config/optionPresets.js +0 -65
  68. package/dist/config/utils.d.ts +0 -2
  69. package/dist/config/utils.js +0 -4
  70. package/dist/config/validateSettings.d.ts +0 -3
  71. package/dist/config/validateSettings.js +0 -32
  72. package/dist/console/colors.d.ts +0 -6
  73. package/dist/console/colors.js +0 -19
  74. package/dist/console/displayTranslateSummary.d.ts +0 -1
  75. package/dist/console/displayTranslateSummary.js +0 -42
  76. package/dist/console/formatting.d.ts +0 -1
  77. package/dist/console/formatting.js +0 -7
  78. package/dist/console/index.d.ts +0 -34
  79. package/dist/console/index.js +0 -46
  80. package/dist/console/logger.d.ts +0 -35
  81. package/dist/console/logger.js +0 -250
  82. package/dist/console/logging.d.ts +0 -52
  83. package/dist/console/logging.js +0 -175
  84. package/dist/formats/files/aggregateFiles.d.ts +0 -4
  85. package/dist/formats/files/aggregateFiles.js +0 -156
  86. package/dist/formats/files/collectFiles.d.ts +0 -6
  87. package/dist/formats/files/collectFiles.js +0 -49
  88. package/dist/formats/files/convertToFileTranslationData.d.ts +0 -15
  89. package/dist/formats/files/convertToFileTranslationData.js +0 -21
  90. package/dist/formats/files/fileMapping.d.ts +0 -11
  91. package/dist/formats/files/fileMapping.js +0 -115
  92. package/dist/formats/files/preprocess/mdx.d.ts +0 -6
  93. package/dist/formats/files/preprocess/mdx.js +0 -14
  94. package/dist/formats/files/preprocess/mintlify.d.ts +0 -5
  95. package/dist/formats/files/preprocess/mintlify.js +0 -15
  96. package/dist/formats/files/preprocessContent.d.ts +0 -8
  97. package/dist/formats/files/preprocessContent.js +0 -23
  98. package/dist/formats/files/save.d.ts +0 -5
  99. package/dist/formats/files/save.js +0 -17
  100. package/dist/formats/files/supportedFiles.d.ts +0 -11
  101. package/dist/formats/files/supportedFiles.js +0 -20
  102. package/dist/formats/json/extractJson.d.ts +0 -15
  103. package/dist/formats/json/extractJson.js +0 -101
  104. package/dist/formats/json/flattenJson.d.ts +0 -14
  105. package/dist/formats/json/flattenJson.js +0 -64
  106. package/dist/formats/json/mergeJson.d.ts +0 -13
  107. package/dist/formats/json/mergeJson.js +0 -367
  108. package/dist/formats/json/parseJson.d.ts +0 -2
  109. package/dist/formats/json/parseJson.js +0 -109
  110. package/dist/formats/json/utils.d.ts +0 -47
  111. package/dist/formats/json/utils.js +0 -150
  112. package/dist/formats/utils.d.ts +0 -2
  113. package/dist/formats/utils.js +0 -24
  114. package/dist/formats/yaml/mergeYaml.d.ts +0 -5
  115. package/dist/formats/yaml/mergeYaml.js +0 -61
  116. package/dist/formats/yaml/parseYaml.d.ts +0 -5
  117. package/dist/formats/yaml/parseYaml.js +0 -24
  118. package/dist/formats/yaml/utils.d.ts +0 -2
  119. package/dist/formats/yaml/utils.js +0 -23
  120. package/dist/fs/clearLocaleDirs.d.ts +0 -8
  121. package/dist/fs/clearLocaleDirs.js +0 -126
  122. package/dist/fs/config/downloadedVersions.d.ts +0 -21
  123. package/dist/fs/config/downloadedVersions.js +0 -50
  124. package/dist/fs/config/loadConfig.d.ts +0 -1
  125. package/dist/fs/config/loadConfig.js +0 -9
  126. package/dist/fs/config/parseFilesConfig.d.ts +0 -27
  127. package/dist/fs/config/parseFilesConfig.js +0 -150
  128. package/dist/fs/config/updateConfig.d.ts +0 -21
  129. package/dist/fs/config/updateConfig.js +0 -57
  130. package/dist/fs/config/updateVersions.d.ts +0 -11
  131. package/dist/fs/config/updateVersions.js +0 -30
  132. package/dist/fs/copyFile.d.ts +0 -7
  133. package/dist/fs/copyFile.js +0 -39
  134. package/dist/fs/createLoadTranslationsFile.d.ts +0 -1
  135. package/dist/fs/createLoadTranslationsFile.js +0 -49
  136. package/dist/fs/determineFramework.d.ts +0 -5
  137. package/dist/fs/determineFramework.js +0 -53
  138. package/dist/fs/findFilepath.d.ts +0 -36
  139. package/dist/fs/findFilepath.js +0 -90
  140. package/dist/fs/index.d.ts +0 -1
  141. package/dist/fs/index.js +0 -1
  142. package/dist/fs/loadJSON.d.ts +0 -6
  143. package/dist/fs/loadJSON.js +0 -17
  144. package/dist/fs/saveJSON.d.ts +0 -1
  145. package/dist/fs/saveJSON.js +0 -7
  146. package/dist/fs/utils.d.ts +0 -1
  147. package/dist/fs/utils.js +0 -16
  148. package/dist/generated/version.d.ts +0 -1
  149. package/dist/generated/version.js +0 -2
  150. package/dist/git/branches.d.ts +0 -7
  151. package/dist/git/branches.js +0 -88
  152. package/dist/hooks/postProcess.d.ts +0 -4
  153. package/dist/hooks/postProcess.js +0 -110
  154. package/dist/locadex/setupFlow.d.ts +0 -2
  155. package/dist/locadex/setupFlow.js +0 -9
  156. package/dist/next/config/parseNextConfig.d.ts +0 -10
  157. package/dist/next/config/parseNextConfig.js +0 -53
  158. package/dist/next/jsx/utils.d.ts +0 -7
  159. package/dist/next/jsx/utils.js +0 -42
  160. package/dist/react/config/createESBuildConfig.d.ts +0 -2
  161. package/dist/react/config/createESBuildConfig.js +0 -119
  162. package/dist/react/jsx/evaluateJsx.d.ts +0 -24
  163. package/dist/react/jsx/evaluateJsx.js +0 -123
  164. package/dist/react/jsx/utils/buildImportMap.d.ts +0 -9
  165. package/dist/react/jsx/utils/buildImportMap.js +0 -30
  166. package/dist/react/jsx/utils/constants.d.ts +0 -15
  167. package/dist/react/jsx/utils/constants.js +0 -49
  168. package/dist/react/jsx/utils/getCalleeNameFromExpression.d.ts +0 -9
  169. package/dist/react/jsx/utils/getCalleeNameFromExpression.js +0 -32
  170. package/dist/react/jsx/utils/getPathsAndAliases.d.ts +0 -21
  171. package/dist/react/jsx/utils/getPathsAndAliases.js +0 -91
  172. package/dist/react/jsx/utils/isNumberLiteral.d.ts +0 -7
  173. package/dist/react/jsx/utils/isNumberLiteral.js +0 -13
  174. package/dist/react/jsx/utils/jsxParsing/addGTIdentifierToSyntaxTree.d.ts +0 -9
  175. package/dist/react/jsx/utils/jsxParsing/addGTIdentifierToSyntaxTree.js +0 -138
  176. package/dist/react/jsx/utils/jsxParsing/handleChildrenWhitespace.d.ts +0 -6
  177. package/dist/react/jsx/utils/jsxParsing/handleChildrenWhitespace.js +0 -197
  178. package/dist/react/jsx/utils/jsxParsing/multiplication/findMultiplicationNode.d.ts +0 -13
  179. package/dist/react/jsx/utils/jsxParsing/multiplication/findMultiplicationNode.js +0 -42
  180. package/dist/react/jsx/utils/jsxParsing/multiplication/multiplyJsxTree.d.ts +0 -5
  181. package/dist/react/jsx/utils/jsxParsing/multiplication/multiplyJsxTree.js +0 -69
  182. package/dist/react/jsx/utils/jsxParsing/parseJsx.d.ts +0 -33
  183. package/dist/react/jsx/utils/jsxParsing/parseJsx.js +0 -918
  184. package/dist/react/jsx/utils/jsxParsing/parseTProps.d.ts +0 -8
  185. package/dist/react/jsx/utils/jsxParsing/parseTProps.js +0 -65
  186. package/dist/react/jsx/utils/jsxParsing/removeNullChildrenFields.d.ts +0 -2
  187. package/dist/react/jsx/utils/jsxParsing/removeNullChildrenFields.js +0 -61
  188. package/dist/react/jsx/utils/jsxParsing/types.d.ts +0 -48
  189. package/dist/react/jsx/utils/jsxParsing/types.js +0 -34
  190. package/dist/react/jsx/utils/mapAttributeName.d.ts +0 -11
  191. package/dist/react/jsx/utils/mapAttributeName.js +0 -12
  192. package/dist/react/jsx/utils/parseAst.d.ts +0 -31
  193. package/dist/react/jsx/utils/parseAst.js +0 -278
  194. package/dist/react/jsx/utils/parseDeclareStatic.d.ts +0 -15
  195. package/dist/react/jsx/utils/parseDeclareStatic.js +0 -540
  196. package/dist/react/jsx/utils/parseString.d.ts +0 -25
  197. package/dist/react/jsx/utils/parseString.js +0 -540
  198. package/dist/react/jsx/utils/parseStringFunction.d.ts +0 -30
  199. package/dist/react/jsx/utils/parseStringFunction.js +0 -348
  200. package/dist/react/jsx/utils/resolveImportPath.d.ts +0 -11
  201. package/dist/react/jsx/utils/resolveImportPath.js +0 -111
  202. package/dist/react/jsx/utils/stringParsing/processTranslationCall/extractStringEntryMetadata.d.ts +0 -29
  203. package/dist/react/jsx/utils/stringParsing/processTranslationCall/extractStringEntryMetadata.js +0 -86
  204. package/dist/react/jsx/utils/stringParsing/processTranslationCall/handleInvalidTranslationCall.d.ts +0 -14
  205. package/dist/react/jsx/utils/stringParsing/processTranslationCall/handleInvalidTranslationCall.js +0 -24
  206. package/dist/react/jsx/utils/stringParsing/processTranslationCall/handleLiteralTranslationCall.d.ts +0 -19
  207. package/dist/react/jsx/utils/stringParsing/processTranslationCall/handleLiteralTranslationCall.js +0 -31
  208. package/dist/react/jsx/utils/stringParsing/processTranslationCall/handleStaticTranslationCall.d.ts +0 -22
  209. package/dist/react/jsx/utils/stringParsing/processTranslationCall/handleStaticTranslationCall.js +0 -51
  210. package/dist/react/jsx/utils/stringParsing/processTranslationCall/index.d.ts +0 -18
  211. package/dist/react/jsx/utils/stringParsing/processTranslationCall/index.js +0 -39
  212. package/dist/react/jsx/utils/stringParsing/processTranslationCall/routeTranslationCall.d.ts +0 -24
  213. package/dist/react/jsx/utils/stringParsing/processTranslationCall/routeTranslationCall.js +0 -68
  214. package/dist/react/jsx/utils/stringParsing/types.d.ts +0 -41
  215. package/dist/react/jsx/utils/stringParsing/types.js +0 -1
  216. package/dist/react/jsx/utils/types.d.ts +0 -14
  217. package/dist/react/jsx/utils/types.js +0 -1
  218. package/dist/react/jsx/utils/validateStringFunction.d.ts +0 -7
  219. package/dist/react/jsx/utils/validateStringFunction.js +0 -31
  220. package/dist/react/jsx/wrapJsx.d.ts +0 -51
  221. package/dist/react/jsx/wrapJsx.js +0 -387
  222. package/dist/react/parse/addVitePlugin/index.d.ts +0 -22
  223. package/dist/react/parse/addVitePlugin/index.js +0 -41
  224. package/dist/react/parse/addVitePlugin/installCompiler.d.ts +0 -8
  225. package/dist/react/parse/addVitePlugin/installCompiler.js +0 -22
  226. package/dist/react/parse/addVitePlugin/updateViteConfig.d.ts +0 -19
  227. package/dist/react/parse/addVitePlugin/updateViteConfig.js +0 -120
  228. package/dist/react/parse/addVitePlugin/utils/addCompilerImport.d.ts +0 -9
  229. package/dist/react/parse/addVitePlugin/utils/addCompilerImport.js +0 -34
  230. package/dist/react/parse/addVitePlugin/utils/addPluginInvocation.d.ts +0 -11
  231. package/dist/react/parse/addVitePlugin/utils/addPluginInvocation.js +0 -48
  232. package/dist/react/parse/addVitePlugin/utils/checkCompilerImport.d.ts +0 -15
  233. package/dist/react/parse/addVitePlugin/utils/checkCompilerImport.js +0 -113
  234. package/dist/react/parse/addVitePlugin/utils/checkPluginInvocation.d.ts +0 -12
  235. package/dist/react/parse/addVitePlugin/utils/checkPluginInvocation.js +0 -32
  236. package/dist/react/parse/createDictionaryUpdates.d.ts +0 -3
  237. package/dist/react/parse/createDictionaryUpdates.js +0 -187
  238. package/dist/react/parse/createInlineUpdates.d.ts +0 -13
  239. package/dist/react/parse/createInlineUpdates.js +0 -161
  240. package/dist/react/utils/flattenDictionary.d.ts +0 -20
  241. package/dist/react/utils/flattenDictionary.js +0 -75
  242. package/dist/react/utils/getEntryAndMetadata.d.ts +0 -5
  243. package/dist/react/utils/getEntryAndMetadata.js +0 -11
  244. package/dist/react/utils/getVariableName.d.ts +0 -25
  245. package/dist/react/utils/getVariableName.js +0 -37
  246. package/dist/setup/agentInstructions.d.ts +0 -24
  247. package/dist/setup/agentInstructions.js +0 -138
  248. package/dist/setup/detectFramework.d.ts +0 -31
  249. package/dist/setup/detectFramework.js +0 -106
  250. package/dist/setup/frameworkUtils.d.ts +0 -3
  251. package/dist/setup/frameworkUtils.js +0 -30
  252. package/dist/setup/instructions/base.md +0 -29
  253. package/dist/setup/instructions/gt-next.md +0 -107
  254. package/dist/setup/instructions/gt-react.md +0 -98
  255. package/dist/setup/userInput.d.ts +0 -4
  256. package/dist/setup/userInput.js +0 -32
  257. package/dist/setup/wizard.d.ts +0 -3
  258. package/dist/setup/wizard.js +0 -147
  259. package/dist/state/recentDownloads.d.ts +0 -12
  260. package/dist/state/recentDownloads.js +0 -18
  261. package/dist/state/translateWarnings.d.ts +0 -10
  262. package/dist/state/translateWarnings.js +0 -13
  263. package/dist/translation/parse.d.ts +0 -17
  264. package/dist/translation/parse.js +0 -77
  265. package/dist/translation/stage.d.ts +0 -3
  266. package/dist/translation/stage.js +0 -44
  267. package/dist/translation/validate.d.ts +0 -14
  268. package/dist/translation/validate.js +0 -100
  269. package/dist/types/branch.d.ts +0 -14
  270. package/dist/types/branch.js +0 -1
  271. package/dist/types/data/json.d.ts +0 -6
  272. package/dist/types/data/json.js +0 -1
  273. package/dist/types/data.d.ts +0 -37
  274. package/dist/types/data.js +0 -1
  275. package/dist/types/files.d.ts +0 -8
  276. package/dist/types/files.js +0 -1
  277. package/dist/types/libraries.d.ts +0 -31
  278. package/dist/types/libraries.js +0 -72
  279. package/dist/types/parsing.d.ts +0 -3
  280. package/dist/types/parsing.js +0 -1
  281. package/dist/utils/addExplicitAnchorIds.d.ts +0 -24
  282. package/dist/utils/addExplicitAnchorIds.js +0 -416
  283. package/dist/utils/constants.d.ts +0 -5
  284. package/dist/utils/constants.js +0 -6
  285. package/dist/utils/credentials.d.ts +0 -12
  286. package/dist/utils/credentials.js +0 -120
  287. package/dist/utils/flattenJsonFiles.d.ts +0 -2
  288. package/dist/utils/flattenJsonFiles.js +0 -36
  289. package/dist/utils/gitDiff.d.ts +0 -8
  290. package/dist/utils/gitDiff.js +0 -34
  291. package/dist/utils/gt.d.ts +0 -2
  292. package/dist/utils/gt.js +0 -2
  293. package/dist/utils/hash.d.ts +0 -6
  294. package/dist/utils/hash.js +0 -11
  295. package/dist/utils/headers.d.ts +0 -1
  296. package/dist/utils/headers.js +0 -14
  297. package/dist/utils/localizeRelativeAssets.d.ts +0 -8
  298. package/dist/utils/localizeRelativeAssets.js +0 -166
  299. package/dist/utils/localizeStaticImports.d.ts +0 -15
  300. package/dist/utils/localizeStaticImports.js +0 -397
  301. package/dist/utils/localizeStaticUrls.d.ts +0 -19
  302. package/dist/utils/localizeStaticUrls.js +0 -450
  303. package/dist/utils/mintlifyTitleFallback.d.ts +0 -6
  304. package/dist/utils/mintlifyTitleFallback.js +0 -80
  305. package/dist/utils/parse/needsCJS.d.ts +0 -20
  306. package/dist/utils/parse/needsCJS.js +0 -72
  307. package/dist/utils/persistPostprocessHashes.d.ts +0 -12
  308. package/dist/utils/persistPostprocessHashes.js +0 -39
  309. package/dist/utils/processAnchorIds.d.ts +0 -6
  310. package/dist/utils/processAnchorIds.js +0 -56
  311. package/dist/utils/processOpenApi.d.ts +0 -8
  312. package/dist/utils/processOpenApi.js +0 -651
  313. package/dist/utils/sanitizeFileContent.d.ts +0 -6
  314. package/dist/utils/sanitizeFileContent.js +0 -29
  315. package/dist/utils/sharedStaticAssets.d.ts +0 -9
  316. package/dist/utils/sharedStaticAssets.js +0 -384
  317. package/dist/utils/validateMdx.d.ts +0 -10
  318. package/dist/utils/validateMdx.js +0 -25
  319. package/dist/utils/wrapPlainUrls.d.ts +0 -8
  320. package/dist/utils/wrapPlainUrls.js +0 -72
  321. package/dist/workflows/download.d.ts +0 -32
  322. package/dist/workflows/download.js +0 -131
  323. package/dist/workflows/enqueue.d.ts +0 -17
  324. package/dist/workflows/enqueue.js +0 -59
  325. package/dist/workflows/setupProject.d.ts +0 -13
  326. package/dist/workflows/setupProject.js +0 -48
  327. package/dist/workflows/stage.d.ts +0 -18
  328. package/dist/workflows/stage.js +0 -59
  329. package/dist/workflows/steps/BranchStep.d.ts +0 -13
  330. package/dist/workflows/steps/BranchStep.js +0 -161
  331. package/dist/workflows/steps/DownloadStep.d.ts +0 -19
  332. package/dist/workflows/steps/DownloadStep.js +0 -131
  333. package/dist/workflows/steps/EnqueueStep.d.ts +0 -15
  334. package/dist/workflows/steps/EnqueueStep.js +0 -33
  335. package/dist/workflows/steps/PollJobsStep.d.ts +0 -31
  336. package/dist/workflows/steps/PollJobsStep.js +0 -288
  337. package/dist/workflows/steps/SetupStep.d.ts +0 -16
  338. package/dist/workflows/steps/SetupStep.js +0 -72
  339. package/dist/workflows/steps/UploadSourcesStep.d.ts +0 -27
  340. package/dist/workflows/steps/UploadSourcesStep.js +0 -131
  341. package/dist/workflows/steps/UploadTranslationsStep.d.ts +0 -22
  342. package/dist/workflows/steps/UploadTranslationsStep.js +0 -71
  343. package/dist/workflows/steps/UserEditDiffsStep.d.ts +0 -11
  344. package/dist/workflows/steps/UserEditDiffsStep.js +0 -30
  345. package/dist/workflows/steps/WorkflowStep.d.ts +0 -4
  346. package/dist/workflows/steps/WorkflowStep.js +0 -2
  347. package/dist/workflows/upload.d.ts +0 -15
  348. package/dist/workflows/upload.js +0 -47
@@ -1,651 +0,0 @@
1
- import fs from 'node:fs';
2
- import path from 'node:path';
3
- import { unified } from 'unified';
4
- import remarkParse from 'remark-parse';
5
- import remarkFrontmatter from 'remark-frontmatter';
6
- import YAML, { isMap, isScalar } from 'yaml';
7
- import { logger } from '../console/logger.js';
8
- import { createFileMapping } from '../formats/files/fileMapping.js';
9
- const HTTP_METHODS = new Set([
10
- 'GET',
11
- 'POST',
12
- 'PUT',
13
- 'PATCH',
14
- 'DELETE',
15
- 'OPTIONS',
16
- 'HEAD',
17
- 'TRACE',
18
- ]);
19
- const OPENAPI_SPEC_EXTENSIONS = new Set(['.json', '.yaml', '.yml']);
20
- /**
21
- * Postprocess Mintlify OpenAPI references to point to locale-specific spec files.
22
- * - Uses openapi.files (ordered) to resolve ambiguities (first match wins).
23
- * - Relies on the user's json transform rules for locale paths.
24
- * - Warns on missing/ambiguous references but keeps behavior deterministic.
25
- */
26
- export default async function processOpenApi(settings, includeFiles) {
27
- const openapiConfig = settings.options?.mintlify?.openapi;
28
- if (!openapiConfig || !openapiConfig.files?.length)
29
- return;
30
- if (!settings.files)
31
- return;
32
- const configDir = path.dirname(settings.config);
33
- const specAnalyses = buildSpecAnalyses(openapiConfig.files, configDir);
34
- if (!specAnalyses.length)
35
- return;
36
- const warnings = new Set();
37
- const { resolvedPaths, placeholderPaths, transformPaths } = settings.files;
38
- const fileMapping = createFileMapping(resolvedPaths, placeholderPaths, transformPaths, settings.locales, settings.defaultLocale);
39
- const fileMappingAbs = {};
40
- for (const [locale, mapping] of Object.entries(fileMapping)) {
41
- fileMappingAbs[locale] = {};
42
- for (const [src, dest] of Object.entries(mapping)) {
43
- const absSrc = path.resolve(configDir, src);
44
- const absDest = path.resolve(configDir, dest);
45
- fileMappingAbs[locale][absSrc] = absDest;
46
- }
47
- }
48
- // Also rewrite default-locale source files so they use the deterministic spec selection
49
- const defaultFiles = [
50
- ...(resolvedPaths.mdx || []),
51
- ...(resolvedPaths.md || []),
52
- ];
53
- for (const filePath of defaultFiles) {
54
- if (!fs.existsSync(filePath))
55
- continue;
56
- const content = fs.readFileSync(filePath, 'utf8');
57
- const updated = rewriteFrontmatter(content, filePath, settings.defaultLocale, specAnalyses, fileMappingAbs, warnings, configDir);
58
- if (updated?.changed) {
59
- await fs.promises.writeFile(filePath, updated.content, 'utf8');
60
- }
61
- }
62
- for (const [locale, filesMap] of Object.entries(fileMapping)) {
63
- const targetFiles = Object.values(filesMap).filter((p) => (p.endsWith('.md') || p.endsWith('.mdx')) &&
64
- (!includeFiles || includeFiles.has(p)));
65
- for (const filePath of targetFiles) {
66
- if (!fs.existsSync(filePath))
67
- continue;
68
- const content = fs.readFileSync(filePath, 'utf8');
69
- const updated = rewriteFrontmatter(content, filePath, locale, specAnalyses, fileMappingAbs, warnings, configDir);
70
- if (updated?.changed) {
71
- await fs.promises.writeFile(filePath, updated.content, 'utf8');
72
- }
73
- }
74
- }
75
- const docsJsonTargets = collectDocsJsonTargets(settings, fileMapping, includeFiles);
76
- for (const target of docsJsonTargets) {
77
- if (!fs.existsSync(target.path))
78
- continue;
79
- const content = fs.readFileSync(target.path, 'utf8');
80
- const updated = rewriteDocsJsonOpenApi(content, target.path, target.localeHint, specAnalyses, fileMappingAbs, fileMapping, warnings, configDir, settings.defaultLocale);
81
- if (updated?.changed) {
82
- await fs.promises.writeFile(target.path, updated.content, 'utf8');
83
- }
84
- }
85
- for (const message of warnings) {
86
- logger.warn(message);
87
- }
88
- }
89
- function collectDocsJsonTargets(settings, fileMapping, includeFiles) {
90
- const targets = [];
91
- const seen = new Map();
92
- const addTarget = (filePath, locale) => {
93
- const canonicalPath = path.resolve(filePath);
94
- if (includeFiles &&
95
- !includeFiles.has(filePath) &&
96
- !includeFiles.has(canonicalPath)) {
97
- return;
98
- }
99
- const locales = seen.get(canonicalPath) ?? new Set();
100
- if (locale)
101
- locales.add(locale);
102
- seen.set(canonicalPath, locales);
103
- };
104
- if (!includeFiles && settings.files?.resolvedPaths.json) {
105
- for (const filePath of settings.files.resolvedPaths.json) {
106
- addTarget(filePath, settings.defaultLocale);
107
- }
108
- }
109
- for (const [locale, filesMap] of Object.entries(fileMapping)) {
110
- for (const filePath of Object.values(filesMap)) {
111
- if (!filePath.endsWith('.json'))
112
- continue;
113
- addTarget(filePath, locale);
114
- }
115
- }
116
- for (const [filePath, locales] of seen.entries()) {
117
- const localeHint = locales.size === 1 ? Array.from(locales)[0] : undefined;
118
- targets.push({ path: filePath, localeHint });
119
- }
120
- return targets;
121
- }
122
- function isMintlifyDocsJson(filePath, json) {
123
- if (!isRecord(json))
124
- return false;
125
- const schema = json.$schema;
126
- if (typeof schema === 'string') {
127
- return (schema.includes('mintlify.com/docs.json') ||
128
- schema.includes('mintlify.com/mint.json'));
129
- }
130
- const base = path.basename(filePath);
131
- return base === 'docs.json' || base === 'mint.json';
132
- }
133
- function rewriteDocsJsonOpenApi(content, filePath, localeHint, specs, fileMappingAbs, fileMappingRel, warnings, configDir, defaultLocale) {
134
- let json;
135
- try {
136
- json = JSON.parse(content);
137
- }
138
- catch {
139
- return null;
140
- }
141
- if (!isMintlifyDocsJson(filePath, json))
142
- return null;
143
- let changed = false;
144
- const visitNode = (node, activeLocale) => {
145
- if (Array.isArray(node)) {
146
- node.forEach((item) => visitNode(item, activeLocale));
147
- return;
148
- }
149
- if (!isRecord(node))
150
- return;
151
- let nextLocale = activeLocale;
152
- if (typeof node.language === 'string') {
153
- nextLocale = node.language;
154
- }
155
- const locale = nextLocale || localeHint || defaultLocale;
156
- if (typeof node.openapi === 'string') {
157
- const sourceValue = node.openapi;
158
- const localizedSource = localizeDocsJsonSpecPath(sourceValue, locale, filePath, specs, fileMappingAbs, fileMappingRel, warnings, configDir);
159
- if (localizedSource && localizedSource !== sourceValue) {
160
- node.openapi = localizedSource;
161
- changed = true;
162
- }
163
- }
164
- else if (isRecord(node.openapi)) {
165
- const openapiConfig = node.openapi;
166
- const sourceValue = openapiConfig.source;
167
- if (typeof sourceValue === 'string') {
168
- const localizedSource = localizeDocsJsonSpecPath(sourceValue, locale, filePath, specs, fileMappingAbs, fileMappingRel, warnings, configDir);
169
- if (localizedSource && localizedSource !== sourceValue) {
170
- openapiConfig.source = localizedSource;
171
- changed = true;
172
- }
173
- }
174
- }
175
- if (Array.isArray(node.pages)) {
176
- const pages = node.pages;
177
- for (let i = 0; i < pages.length; i += 1) {
178
- const page = pages[i];
179
- if (typeof page !== 'string')
180
- continue;
181
- const updated = stripLocaleFromOpenApiPage(page, locale);
182
- if (updated !== page) {
183
- pages[i] = updated;
184
- changed = true;
185
- }
186
- }
187
- }
188
- for (const value of Object.values(node)) {
189
- visitNode(value, nextLocale);
190
- }
191
- };
192
- visitNode(json, undefined);
193
- if (!changed)
194
- return null;
195
- return { changed, content: JSON.stringify(json, null, 2) };
196
- }
197
- function stripLocaleFromOpenApiPage(value, locale) {
198
- const trimmed = value.trim();
199
- const prefix = `${locale}/`;
200
- if (!trimmed.startsWith(prefix))
201
- return value;
202
- const candidate = trimmed.slice(prefix.length);
203
- const parsed = parseOpenApiValue(candidate);
204
- if (!parsed)
205
- return value;
206
- return candidate;
207
- }
208
- function localizeDocsJsonSpecPath(source, locale, filePath, specs, fileMappingAbs, _fileMappingRel, warnings, configDir) {
209
- const resolvedAbs = resolveDocsJsonSpecPath(source, filePath, configDir);
210
- const matched = matchSpecBySource(source, resolvedAbs, specs, warnings);
211
- if (!matched)
212
- return source;
213
- const localizedSpecPath = resolveLocalizedSpecPath(matched, locale, fileMappingAbs, configDir, source);
214
- const localizedAbs = resolveDocsJsonSpecPath(localizedSpecPath, filePath, configDir);
215
- if (!fs.existsSync(localizedAbs)) {
216
- warnings.add(`OpenAPI source "${source}" localized for locale "${locale}" points to a missing file (${localizedAbs}). Keeping original source.`);
217
- return source;
218
- }
219
- const rel = normalizeSlashes(path.relative(configDir, localizedAbs));
220
- return formatSpecPathForDocsJson(rel, source);
221
- }
222
- function resolveDocsJsonSpecPath(source, filePath, configDir) {
223
- if (source.startsWith('/')) {
224
- return path.resolve(configDir, source.replace(/^\/+/, ''));
225
- }
226
- if (source.startsWith('./') || source.startsWith('../')) {
227
- return path.resolve(path.dirname(filePath), source);
228
- }
229
- return path.resolve(configDir, source);
230
- }
231
- function matchSpecBySource(source, resolvedAbs, specs, warnings) {
232
- const exact = specs.find((spec) => samePath(resolvedAbs, spec.absPath));
233
- if (exact)
234
- return exact;
235
- const normalizedExplicit = normalizeSlashes(source).replace(/^\.?\/+/, '');
236
- const explicitWithoutExt = stripExtension(normalizedExplicit);
237
- const explicitBase = path.basename(normalizedExplicit);
238
- const explicitBaseWithoutExt = stripExtension(explicitBase);
239
- const matches = specs.filter((spec) => {
240
- const configPath = normalizeSlashes(spec.configPath).replace(/^\.?\/+/, '');
241
- const configBase = path.basename(configPath);
242
- const configPathNoExt = stripExtension(configPath);
243
- const configBaseNoExt = stripExtension(configBase);
244
- return (configPath === normalizedExplicit ||
245
- configPathNoExt === explicitWithoutExt ||
246
- configBase === explicitBase ||
247
- configBaseNoExt === explicitBaseWithoutExt);
248
- });
249
- if (matches.length === 1)
250
- return matches[0];
251
- if (matches.length > 1) {
252
- warnings.add(`OpenAPI source "${source}" matches multiple specs (${matches
253
- .map((m) => m.configPath)
254
- .join(', ')}). Using the first configured match (${matches[0].configPath}).`);
255
- return matches[0];
256
- }
257
- return null;
258
- }
259
- function formatSpecPathForDocsJson(relativePath, originalPathText) {
260
- const normalized = normalizeSlashes(relativePath);
261
- const base = normalized.replace(/^\.\//, '').replace(/\/+/g, '/');
262
- if (originalPathText.startsWith('/')) {
263
- return `/${base.replace(/^\/+/, '')}`;
264
- }
265
- if (originalPathText.startsWith('../')) {
266
- return normalized;
267
- }
268
- if (originalPathText.startsWith('./')) {
269
- return `./${base.replace(/^\/+/, '')}`;
270
- }
271
- return base.replace(/^\/+/, '');
272
- }
273
- /**
274
- * Resolve configured OpenAPI files to absolute paths and collect the operations,
275
- * schemas, and webhooks they expose. Warns and skips when files are missing,
276
- * unsupported (non-JSON/YAML), or fail to parse so later steps can continue gracefully.
277
- */
278
- function buildSpecAnalyses(openapiFiles, configDir) {
279
- const analyses = [];
280
- for (const configEntry of openapiFiles) {
281
- const absPath = path.resolve(configDir, configEntry);
282
- if (!fs.existsSync(absPath)) {
283
- logger.warn(`OpenAPI file not found: ${configEntry}`);
284
- continue;
285
- }
286
- const ext = path.extname(absPath).toLowerCase();
287
- if (!OPENAPI_SPEC_EXTENSIONS.has(ext)) {
288
- logger.warn(`Skipping OpenAPI file (only .json/.yml/.yaml supported): ${configEntry}`);
289
- continue;
290
- }
291
- let spec;
292
- try {
293
- const raw = fs.readFileSync(absPath, 'utf8');
294
- spec = ext === '.json' ? JSON.parse(raw) : YAML.parse(raw);
295
- }
296
- catch {
297
- const format = ext === '.json' ? 'JSON' : 'YAML';
298
- logger.warn(`Failed to parse OpenAPI ${format}: ${configEntry}`);
299
- continue;
300
- }
301
- analyses.push({
302
- absPath,
303
- configPath: configEntry,
304
- operations: extractOperations(spec),
305
- schemas: extractSchemas(spec),
306
- webhooks: extractWebhooks(spec),
307
- });
308
- }
309
- return analyses;
310
- }
311
- function isRecord(val) {
312
- return typeof val === 'object' && val !== null;
313
- }
314
- /**
315
- * Collect path+method identifiers (e.g., "POST /foo") from an OpenAPI spec.
316
- * Safely no-ops when paths is missing or malformed.
317
- */
318
- function extractOperations(spec) {
319
- const ops = new Set();
320
- if (!isRecord(spec) || !isRecord(spec.paths))
321
- return ops;
322
- const paths = spec.paths;
323
- for (const [route, methods] of Object.entries(paths)) {
324
- if (!isRecord(methods))
325
- continue;
326
- for (const [method, operation] of Object.entries(methods)) {
327
- if (!isRecord(operation))
328
- continue;
329
- const upper = method.toUpperCase();
330
- if (!HTTP_METHODS.has(upper))
331
- continue;
332
- ops.add(`${upper} ${route}`);
333
- }
334
- }
335
- return ops;
336
- }
337
- /**
338
- * Collect schema names from components.schemas.
339
- * Returns empty set if components/schemas are missing or malformed.
340
- */
341
- function extractSchemas(spec) {
342
- if (!isRecord(spec) || !isRecord(spec.components))
343
- return new Set();
344
- const components = spec.components;
345
- if (!isRecord(components.schemas))
346
- return new Set();
347
- return new Set(Object.keys(components.schemas));
348
- }
349
- /**
350
- * Collect webhook names from webhooks (OpenAPI 3.1+).
351
- * Returns empty set if webhooks is missing or malformed.
352
- */
353
- function extractWebhooks(spec) {
354
- if (!isRecord(spec) || !isRecord(spec.webhooks))
355
- return new Set();
356
- return new Set(Object.keys(spec.webhooks));
357
- }
358
- /**
359
- * Parse MDX/MD frontmatter, rewrite openapi/openapi-schema entries to the
360
- * resolved (possibly localized) spec path, and return updated content.
361
- * Uses remark to find the YAML node so the rest of the document remains
362
- * untouched. When parsing fails or no relevant keys exist, it returns null.
363
- */
364
- function rewriteFrontmatter(content, filePath, locale, specs, fileMapping, warnings, configDir) {
365
- let tree;
366
- try {
367
- tree = unified()
368
- .use(remarkParse)
369
- .use(remarkFrontmatter, ['yaml', 'toml'])
370
- .parse(content);
371
- }
372
- catch {
373
- return null;
374
- }
375
- const yamlNode = tree.children.find((node) => node.type === 'yaml');
376
- if (!yamlNode ||
377
- !yamlNode.position ||
378
- yamlNode.position.start?.offset === undefined) {
379
- return null;
380
- }
381
- const start = yamlNode.position.start.offset;
382
- const end = yamlNode.position.end.offset;
383
- const frontmatterRaw = yamlNode.value || '';
384
- const doc = YAML.parseDocument(frontmatterRaw, {
385
- prettyErrors: false,
386
- keepSourceTokens: true,
387
- });
388
- if (doc.errors?.length)
389
- return null;
390
- if (!isMap(doc.contents))
391
- return null;
392
- let changed = false;
393
- const openapiNode = doc.get('openapi', true);
394
- if (isScalar(openapiNode) && typeof openapiNode.value === 'string') {
395
- const parsedValue = parseOpenApiValue(openapiNode.value);
396
- if (parsedValue) {
397
- const matchKey = parsedValue.kind === 'operation'
398
- ? {
399
- type: 'operation',
400
- key: `${parsedValue.method.toUpperCase()} ${parsedValue.operationPath}`,
401
- }
402
- : { type: 'webhook', key: parsedValue.name };
403
- const spec = resolveSpec(parsedValue.specPath, specs, filePath, configDir, warnings, describeOpenApiRef(parsedValue), matchKey);
404
- if (spec) {
405
- const descriptor = formatOpenApiDescriptor(parsedValue);
406
- const localizedSpecPath = resolveLocalizedSpecPath(spec, locale, fileMapping, configDir, parsedValue.specPath || spec.configPath);
407
- const newValue = `${localizedSpecPath} ${descriptor}`.trim();
408
- if (newValue !== openapiNode.value) {
409
- doc.set('openapi', newValue);
410
- changed = true;
411
- }
412
- }
413
- }
414
- }
415
- const schemaNode = doc.get('openapi-schema', true);
416
- if (isScalar(schemaNode) && typeof schemaNode.value === 'string') {
417
- const parsedValue = parseSchemaValue(schemaNode.value);
418
- if (parsedValue) {
419
- const spec = resolveSpec(parsedValue.specPath, specs, filePath, configDir, warnings, `schema "${parsedValue.schemaName}"`, { type: 'schema', key: parsedValue.schemaName });
420
- if (spec) {
421
- const localizedSpecPath = resolveLocalizedSpecPath(spec, locale, fileMapping, configDir, parsedValue.specPath || spec.configPath);
422
- const newValue = `${localizedSpecPath} ${parsedValue.schemaName}`.trim();
423
- if (newValue !== schemaNode.value) {
424
- doc.set('openapi-schema', newValue);
425
- changed = true;
426
- }
427
- }
428
- }
429
- }
430
- if (!changed)
431
- return null;
432
- const fmString = doc.toString().trimEnd();
433
- const rebuilt = `${content.slice(0, start)}---\n${fmString}\n---${content.slice(end)}`;
434
- return { changed, content: rebuilt };
435
- }
436
- function stripWrappingQuotes(value) {
437
- return value.trim().replace(/^['"]|['"]$/g, '');
438
- }
439
- /**
440
- * Parse frontmatter openapi string into spec/method/path or webhook.
441
- * Supports optional leading spec file, the webhook keyword, quoted values,
442
- * and forgiving whitespace. Returns null when the structure is unrecognized.
443
- */
444
- function parseOpenApiValue(value) {
445
- const stripped = stripWrappingQuotes(value);
446
- const tokens = stripped.split(/\s+/).filter(Boolean);
447
- if (!tokens.length)
448
- return null;
449
- let cursor = 0;
450
- let specPath;
451
- const first = tokens[0];
452
- const second = tokens[1];
453
- const methodCandidate = second?.toUpperCase();
454
- const firstLooksLikeSpec = hasOpenApiSpecExtension(first) ||
455
- (second &&
456
- (second.toLowerCase() === 'webhook' ||
457
- (methodCandidate && HTTP_METHODS.has(methodCandidate))));
458
- if (firstLooksLikeSpec) {
459
- specPath = tokens[0];
460
- cursor = 1;
461
- }
462
- if (cursor >= tokens.length)
463
- return null;
464
- const keyword = tokens[cursor];
465
- if (keyword.toLowerCase() === 'webhook') {
466
- const name = tokens.slice(cursor + 1).join(' ');
467
- if (!name)
468
- return null;
469
- return { kind: 'webhook', specPath, name };
470
- }
471
- const method = keyword.toUpperCase();
472
- if (!HTTP_METHODS.has(method))
473
- return null;
474
- const operationPath = tokens.slice(cursor + 1).join(' ');
475
- if (!operationPath)
476
- return null;
477
- return { kind: 'operation', specPath, method, operationPath };
478
- }
479
- /**
480
- * Parse frontmatter openapi-schema string into spec/schemaName.
481
- * Accepts optional leading spec file and quoted values; returns null on invalid
482
- * shapes so callers can skip rewrites gracefully.
483
- */
484
- function parseSchemaValue(value) {
485
- const stripped = stripWrappingQuotes(value);
486
- const tokens = stripped.split(/\s+/).filter(Boolean);
487
- if (!tokens.length)
488
- return null;
489
- let cursor = 0;
490
- let specPath;
491
- if (hasOpenApiSpecExtension(tokens[0])) {
492
- specPath = tokens[0];
493
- cursor = 1;
494
- }
495
- const schemaName = tokens.slice(cursor).join(' ');
496
- if (!schemaName)
497
- return null;
498
- return { specPath, schemaName };
499
- }
500
- /**
501
- * Choose which configured spec a reference should use.
502
- * - If an explicit spec path is provided, resolve it relative to the config
503
- * and the referencing file, warn when unknown, and bail.
504
- * - Otherwise, try to match by operation/webhook/schema name; resolve
505
- * ambiguity using config order and warn when ambiguous or missing.
506
- */
507
- function resolveSpec(explicitPath, specs, filePath, configDir, warnings, refDescription, match) {
508
- if (!specs.length)
509
- return null;
510
- if (explicitPath) {
511
- const normalizedExplicit = normalizeSlashes(explicitPath.replace(/^\.?\/+/, ''));
512
- const candidates = [
513
- path.resolve(configDir, normalizedExplicit),
514
- path.resolve(path.dirname(filePath), normalizedExplicit),
515
- ];
516
- const foundSpec = specs.find((spec) => {
517
- const normalizedSpecPath = normalizeSlashes(spec.absPath);
518
- return candidates.some((candidate) => samePath(candidate, normalizedSpecPath));
519
- });
520
- if (foundSpec) {
521
- if (specHasMatch(foundSpec, match)) {
522
- return foundSpec;
523
- }
524
- const alternatives = specs.filter((spec) => spec !== foundSpec && specHasMatch(spec, match));
525
- if (alternatives.length === 1) {
526
- warnings.add(`OpenAPI reference ${refDescription} in ${filePath} points to ${foundSpec.configPath}, but the entry was not found there. Using ${alternatives[0].configPath} instead.`);
527
- return alternatives[0];
528
- }
529
- if (alternatives.length > 1) {
530
- warnings.add(`OpenAPI reference ${refDescription} in ${filePath} points to ${foundSpec.configPath}, but the entry was not found there and matches multiple specs (${alternatives
531
- .map((spec) => spec.configPath)
532
- .join(', ')}). Skipping localization for this reference.`);
533
- return null;
534
- }
535
- warnings.add(`OpenAPI reference ${refDescription} in ${filePath} points to ${foundSpec.configPath}, but the entry was not found in any configured spec. Skipping localization for this reference.`);
536
- return null;
537
- }
538
- const explicitWithoutExt = stripExtension(normalizedExplicit);
539
- const explicitBase = path.basename(normalizedExplicit);
540
- const explicitBaseWithoutExt = stripExtension(explicitBase);
541
- const matches = specs.filter((spec) => {
542
- const configPath = normalizeSlashes(spec.configPath).replace(/^\.?\/+/, '');
543
- const configBase = path.basename(configPath);
544
- const configPathNoExt = stripExtension(configPath);
545
- const configBaseNoExt = stripExtension(configBase);
546
- return (configPath === normalizedExplicit ||
547
- configPathNoExt === explicitWithoutExt ||
548
- configBase === explicitBase ||
549
- configBaseNoExt === explicitBaseWithoutExt);
550
- });
551
- if (matches.length === 1)
552
- return matches[0];
553
- if (matches.length > 1) {
554
- warnings.add(`OpenAPI reference ${refDescription} in ${filePath} matches multiple specs (${matches
555
- .map((m) => m.configPath)
556
- .join(', ')}). Using the first configured match (${matches[0].configPath}).`);
557
- return matches[0];
558
- }
559
- warnings.add(`OpenAPI reference ${refDescription} in ${filePath} points to an unconfigured spec (${explicitPath}). Skipping localization for this reference.`);
560
- return null;
561
- }
562
- // No explicit spec: try to find by contents
563
- const matches = specs.filter((spec) => {
564
- if (match.type === 'schema') {
565
- return spec.schemas.has(match.key);
566
- }
567
- if (match.type === 'webhook') {
568
- return spec.webhooks.has(match.key);
569
- }
570
- // operation
571
- return spec.operations.has(match.key);
572
- });
573
- if (matches.length === 1)
574
- return matches[0];
575
- if (matches.length > 1) {
576
- warnings.add(`OpenAPI reference ${refDescription} in ${filePath} is available in multiple specs. Skipping localization for this reference.`);
577
- return null;
578
- }
579
- warnings.add(`OpenAPI reference ${refDescription} in ${filePath} was not found in any configured spec. Skipping localization for this reference.`);
580
- return null;
581
- }
582
- function specHasMatch(spec, match) {
583
- if (match.type === 'schema') {
584
- return spec.schemas.has(match.key);
585
- }
586
- if (match.type === 'webhook') {
587
- return spec.webhooks.has(match.key);
588
- }
589
- return spec.operations.has(match.key);
590
- }
591
- /**
592
- * Map a spec to the locale-specific file path when available and normalize it
593
- * for frontmatter. Falls back to the source spec when the locale copy does
594
- * not exist to preserve deterministic behavior.
595
- */
596
- function resolveLocalizedSpecPath(spec, locale, fileMapping, configDir, originalPathText) {
597
- const mapping = fileMapping[locale]?.[spec.absPath];
598
- const chosenAbs = mapping || spec.absPath;
599
- const rel = normalizeSlashes(path.relative(configDir, chosenAbs));
600
- const rooted = `/${rel.replace(/^\/+/, '')}`;
601
- return formatSpecPathForFrontmatter(rooted, originalPathText || spec.configPath);
602
- }
603
- /**
604
- * Format the path that will be written back to frontmatter:
605
- * - Preserve the user's absolute style when they used a leading slash.
606
- * - Preserve upward relative references (../) exactly.
607
- * - Otherwise return a repo-root-relative path with a leading slash so Mintlify
608
- * resolves consistently regardless of the MDX file location.
609
- */
610
- function formatSpecPathForFrontmatter(relativePath, originalPathText) {
611
- const normalized = normalizeSlashes(relativePath);
612
- const base = normalized.replace(/^\.\//, '').replace(/\/+/g, '/');
613
- if (originalPathText.startsWith('/')) {
614
- // Force repo-root absolute style
615
- return `/${base.replace(/^\/+/, '')}`;
616
- }
617
- if (originalPathText.startsWith('../')) {
618
- // Preserve explicit relative upward references
619
- return normalized;
620
- }
621
- // Default to repo-root relative with leading slash to avoid resolving relative to the MDX directory
622
- return `/${base.replace(/^\/+/, '')}`;
623
- }
624
- /** Normalize the descriptive portion after the spec path for frontmatter. */
625
- function formatOpenApiDescriptor(value) {
626
- if (value.kind === 'webhook')
627
- return `webhook ${value.name}`;
628
- return `${value.method.toUpperCase()} ${value.operationPath}`;
629
- }
630
- /** Human-readable description a specific OpenAPI reference. */
631
- function describeOpenApiRef(value) {
632
- if (value.kind === 'webhook')
633
- return `webhook ${value.name}`;
634
- return `${value.method.toUpperCase()} ${value.operationPath}`;
635
- }
636
- /** Remove a single trailing file extension while preserving directory segments. */
637
- function stripExtension(p) {
638
- const parsed = path.parse(p);
639
- return normalizeSlashes(path.join(parsed.dir, parsed.name));
640
- }
641
- function hasOpenApiSpecExtension(value) {
642
- return OPENAPI_SPEC_EXTENSIONS.has(path.extname(value).toLowerCase());
643
- }
644
- /** Normalize separators for stable comparisons and output. */
645
- function normalizeSlashes(p) {
646
- return p.replace(/\\/g, '/');
647
- }
648
- /** Compare paths after resolution to avoid casing/separator mismatches. */
649
- function samePath(a, b) {
650
- return path.resolve(a) === path.resolve(b);
651
- }
@@ -1,6 +0,0 @@
1
- /**
2
- * Processes content to escape curl commands within tick marks and existing escape strings
3
- * @param content - The content to process
4
- * @returns the processed content with escaped curl commands
5
- */
6
- export default function sanitizeFileContent(content: string): string;
@@ -1,29 +0,0 @@
1
- /**
2
- * Processes content to escape curl commands within tick marks and existing escape strings
3
- * @param content - The content to process
4
- * @returns the processed content with escaped curl commands
5
- */
6
- export default function sanitizeFileContent(content) {
7
- const ESCAPE_STRING = '_GT_INTERNAL_ESCAPE';
8
- const allTickMarkRegex = /`([^`]*)`/g;
9
- let processedContent = content;
10
- // First, escape any existing tick marks followed by _GT_INTERNAL_ESCAPE
11
- // This protects pre-existing escapes
12
- processedContent = processedContent.replace(new RegExp('`' + ESCAPE_STRING, 'g'), '`' + ESCAPE_STRING + ESCAPE_STRING);
13
- // Then find ALL tick mark pairs and process them individually
14
- // This approach is more reliable than negative lookahead with modified content
15
- processedContent = processedContent.replace(allTickMarkRegex, (match, innerContent) => {
16
- // Skip if this already starts with our escape string (protected or already processed)
17
- if (innerContent.startsWith(ESCAPE_STRING)) {
18
- return match;
19
- }
20
- // Check if the content contains a curl command
21
- if (/\bcurl\b/i.test(innerContent)) {
22
- // Insert escape string after opening tick
23
- return '`' + ESCAPE_STRING + innerContent + '`';
24
- }
25
- // Return original match if no curl command found
26
- return match;
27
- });
28
- return processedContent;
29
- }