@typia/utils 13.0.0-dev.20260427-3 → 13.0.0-dev.20260501

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 (345) hide show
  1. package/lib/converters/LlmSchemaConverter.js +6 -6
  2. package/lib/converters/LlmSchemaConverter.js.map +1 -1
  3. package/lib/converters/LlmSchemaConverter.mjs +2 -7
  4. package/lib/converters/LlmSchemaConverter.mjs.map +1 -1
  5. package/lib/converters/LlmSchemaConverter2.mjs +449 -451
  6. package/lib/converters/LlmSchemaConverter2.mjs.map +1 -1
  7. package/lib/converters/OpenApiConverter.mjs +2 -7
  8. package/lib/converters/OpenApiConverter.mjs.map +1 -1
  9. package/lib/converters/OpenApiConverter2.mjs +163 -164
  10. package/lib/converters/OpenApiConverter2.mjs.map +1 -1
  11. package/lib/converters/index.mjs +1 -7
  12. package/lib/converters/index.mjs.map +1 -1
  13. package/lib/converters/index2.mjs +31 -32
  14. package/lib/converters/index2.mjs.map +1 -1
  15. package/lib/converters/internal/LlmDescriptionInverter.mjs +2 -7
  16. package/lib/converters/internal/LlmDescriptionInverter.mjs.map +1 -1
  17. package/lib/converters/internal/LlmDescriptionInverter2.mjs +143 -150
  18. package/lib/converters/internal/LlmDescriptionInverter2.mjs.map +1 -1
  19. package/lib/converters/internal/LlmParametersComposer.mjs +2 -7
  20. package/lib/converters/internal/LlmParametersComposer.mjs.map +1 -1
  21. package/lib/converters/internal/LlmParametersComposer2.mjs +37 -44
  22. package/lib/converters/internal/LlmParametersComposer2.mjs.map +1 -1
  23. package/lib/converters/internal/OpenApiConstraintShifter.mjs +2 -7
  24. package/lib/converters/internal/OpenApiConstraintShifter.mjs.map +1 -1
  25. package/lib/converters/internal/OpenApiConstraintShifter2.mjs +105 -112
  26. package/lib/converters/internal/OpenApiConstraintShifter2.mjs.map +1 -1
  27. package/lib/converters/internal/OpenApiExclusiveEmender.mjs +2 -7
  28. package/lib/converters/internal/OpenApiExclusiveEmender.mjs.map +1 -1
  29. package/lib/converters/internal/OpenApiExclusiveEmender2.mjs +32 -40
  30. package/lib/converters/internal/OpenApiExclusiveEmender2.mjs.map +1 -1
  31. package/lib/converters/internal/OpenApiV3Downgrader.mjs +2 -7
  32. package/lib/converters/internal/OpenApiV3Downgrader.mjs.map +1 -1
  33. package/lib/converters/internal/OpenApiV3Downgrader2.mjs +237 -244
  34. package/lib/converters/internal/OpenApiV3Downgrader2.mjs.map +1 -1
  35. package/lib/converters/internal/OpenApiV3Upgrader.mjs +2 -7
  36. package/lib/converters/internal/OpenApiV3Upgrader.mjs.map +1 -1
  37. package/lib/converters/internal/OpenApiV3Upgrader2.mjs +300 -305
  38. package/lib/converters/internal/OpenApiV3Upgrader2.mjs.map +1 -1
  39. package/lib/converters/internal/OpenApiV3_1Downgrader.mjs +2 -7
  40. package/lib/converters/internal/OpenApiV3_1Downgrader.mjs.map +1 -1
  41. package/lib/converters/internal/OpenApiV3_1Downgrader2.mjs +193 -200
  42. package/lib/converters/internal/OpenApiV3_1Downgrader2.mjs.map +1 -1
  43. package/lib/converters/internal/OpenApiV3_1Upgrader.mjs +2 -7
  44. package/lib/converters/internal/OpenApiV3_1Upgrader.mjs.map +1 -1
  45. package/lib/converters/internal/OpenApiV3_1Upgrader2.mjs +424 -429
  46. package/lib/converters/internal/OpenApiV3_1Upgrader2.mjs.map +1 -1
  47. package/lib/converters/internal/OpenApiV3_2Upgrader.mjs +2 -7
  48. package/lib/converters/internal/OpenApiV3_2Upgrader.mjs.map +1 -1
  49. package/lib/converters/internal/OpenApiV3_2Upgrader2.mjs +202 -208
  50. package/lib/converters/internal/OpenApiV3_2Upgrader2.mjs.map +1 -1
  51. package/lib/converters/internal/SwaggerV2Downgrader.mjs +2 -7
  52. package/lib/converters/internal/SwaggerV2Downgrader.mjs.map +1 -1
  53. package/lib/converters/internal/SwaggerV2Downgrader2.mjs +287 -294
  54. package/lib/converters/internal/SwaggerV2Downgrader2.mjs.map +1 -1
  55. package/lib/converters/internal/SwaggerV2Upgrader.mjs +2 -7
  56. package/lib/converters/internal/SwaggerV2Upgrader.mjs.map +1 -1
  57. package/lib/converters/internal/SwaggerV2Upgrader2.mjs +370 -375
  58. package/lib/converters/internal/SwaggerV2Upgrader2.mjs.map +1 -1
  59. package/lib/http/HttpError.mjs +2 -7
  60. package/lib/http/HttpError.mjs.map +1 -1
  61. package/lib/http/HttpError2.mjs +69 -77
  62. package/lib/http/HttpError2.mjs.map +1 -1
  63. package/lib/http/HttpLlm.mjs +2 -7
  64. package/lib/http/HttpLlm.mjs.map +1 -1
  65. package/lib/http/HttpLlm2.mjs +107 -112
  66. package/lib/http/HttpLlm2.mjs.map +1 -1
  67. package/lib/http/HttpMigration.mjs +2 -7
  68. package/lib/http/HttpMigration.mjs.map +1 -1
  69. package/lib/http/HttpMigration2.mjs +58 -63
  70. package/lib/http/HttpMigration2.mjs.map +1 -1
  71. package/lib/http/index.mjs +1 -7
  72. package/lib/http/index.mjs.map +1 -1
  73. package/lib/http/index2.mjs +30 -31
  74. package/lib/http/index2.mjs.map +1 -1
  75. package/lib/http/internal/HttpLlmApplicationComposer.mjs +2 -7
  76. package/lib/http/internal/HttpLlmApplicationComposer.mjs.map +1 -1
  77. package/lib/http/internal/HttpLlmApplicationComposer2.mjs +301 -306
  78. package/lib/http/internal/HttpLlmApplicationComposer2.mjs.map +1 -1
  79. package/lib/http/internal/HttpLlmFunctionFetcher.mjs +2 -7
  80. package/lib/http/internal/HttpLlmFunctionFetcher.mjs.map +1 -1
  81. package/lib/http/internal/HttpLlmFunctionFetcher2.mjs +26 -33
  82. package/lib/http/internal/HttpLlmFunctionFetcher2.mjs.map +1 -1
  83. package/lib/http/internal/HttpMigrateApplicationComposer.mjs +2 -7
  84. package/lib/http/internal/HttpMigrateApplicationComposer.mjs.map +1 -1
  85. package/lib/http/internal/HttpMigrateApplicationComposer2.mjs +51 -56
  86. package/lib/http/internal/HttpMigrateApplicationComposer2.mjs.map +1 -1
  87. package/lib/http/internal/HttpMigrateRouteAccessor.mjs +2 -7
  88. package/lib/http/internal/HttpMigrateRouteAccessor.mjs.map +1 -1
  89. package/lib/http/internal/HttpMigrateRouteAccessor2.mjs +113 -118
  90. package/lib/http/internal/HttpMigrateRouteAccessor2.mjs.map +1 -1
  91. package/lib/http/internal/HttpMigrateRouteComposer.mjs +2 -7
  92. package/lib/http/internal/HttpMigrateRouteComposer.mjs.map +1 -1
  93. package/lib/http/internal/HttpMigrateRouteComposer2.mjs +376 -381
  94. package/lib/http/internal/HttpMigrateRouteComposer2.mjs.map +1 -1
  95. package/lib/http/internal/HttpMigrateRouteFetcher.mjs +2 -7
  96. package/lib/http/internal/HttpMigrateRouteFetcher.mjs.map +1 -1
  97. package/lib/http/internal/HttpMigrateRouteFetcher2.mjs +182 -189
  98. package/lib/http/internal/HttpMigrateRouteFetcher2.mjs.map +1 -1
  99. package/lib/index.mjs +1 -7
  100. package/lib/index.mjs.map +1 -1
  101. package/lib/index2.mjs +33 -33
  102. package/lib/index2.mjs.map +1 -1
  103. package/lib/utils/ArrayUtil.mjs +2 -7
  104. package/lib/utils/ArrayUtil.mjs.map +1 -1
  105. package/lib/utils/ArrayUtil2.mjs +29 -37
  106. package/lib/utils/ArrayUtil2.mjs.map +1 -1
  107. package/lib/utils/LlmJson.mjs +2 -7
  108. package/lib/utils/LlmJson.mjs.map +1 -1
  109. package/lib/utils/LlmJson2.mjs +166 -169
  110. package/lib/utils/LlmJson2.mjs.map +1 -1
  111. package/lib/utils/MapUtil.mjs +2 -7
  112. package/lib/utils/MapUtil.mjs.map +1 -1
  113. package/lib/utils/MapUtil2.mjs +16 -24
  114. package/lib/utils/MapUtil2.mjs.map +1 -1
  115. package/lib/utils/NamingConvention.mjs +2 -7
  116. package/lib/utils/NamingConvention.mjs.map +1 -1
  117. package/lib/utils/NamingConvention2.mjs +199 -207
  118. package/lib/utils/NamingConvention2.mjs.map +1 -1
  119. package/lib/utils/Singleton.d.ts +1 -6
  120. package/lib/utils/Singleton.js +1 -0
  121. package/lib/utils/Singleton.js.map +1 -1
  122. package/lib/utils/Singleton.mjs +2 -7
  123. package/lib/utils/Singleton.mjs.map +1 -1
  124. package/lib/utils/Singleton2.mjs +17 -24
  125. package/lib/utils/Singleton2.mjs.map +1 -1
  126. package/lib/utils/StringUtil.mjs +2 -7
  127. package/lib/utils/StringUtil.mjs.map +1 -1
  128. package/lib/utils/StringUtil2.mjs +14 -22
  129. package/lib/utils/StringUtil2.mjs.map +1 -1
  130. package/lib/utils/dedent.mjs +2 -7
  131. package/lib/utils/dedent.mjs.map +1 -1
  132. package/lib/utils/dedent2.mjs +50 -58
  133. package/lib/utils/dedent2.mjs.map +1 -1
  134. package/lib/utils/index.mjs +1 -7
  135. package/lib/utils/index.mjs.map +1 -1
  136. package/lib/utils/index2.mjs +42 -39
  137. package/lib/utils/index2.mjs.map +1 -1
  138. package/lib/utils/internal/EndpointUtil.mjs +2 -7
  139. package/lib/utils/internal/EndpointUtil.mjs.map +1 -1
  140. package/lib/utils/internal/EndpointUtil2.mjs +39 -46
  141. package/lib/utils/internal/EndpointUtil2.mjs.map +1 -1
  142. package/lib/utils/internal/JsonDescriptor.mjs +2 -7
  143. package/lib/utils/internal/JsonDescriptor.mjs.map +1 -1
  144. package/lib/utils/internal/JsonDescriptor2.mjs +55 -61
  145. package/lib/utils/internal/JsonDescriptor2.mjs.map +1 -1
  146. package/lib/utils/internal/OpenApiTypeCheckerBase.js +23 -14
  147. package/lib/utils/internal/OpenApiTypeCheckerBase.js.map +1 -1
  148. package/lib/utils/internal/OpenApiTypeCheckerBase.mjs +2 -7
  149. package/lib/utils/internal/OpenApiTypeCheckerBase.mjs.map +1 -1
  150. package/lib/utils/internal/OpenApiTypeCheckerBase2.mjs +539 -536
  151. package/lib/utils/internal/OpenApiTypeCheckerBase2.mjs.map +1 -1
  152. package/lib/utils/internal/coerceLlmArguments.js +27 -1
  153. package/lib/utils/internal/coerceLlmArguments.js.map +1 -1
  154. package/lib/utils/internal/coerceLlmArguments.mjs +2 -7
  155. package/lib/utils/internal/coerceLlmArguments.mjs.map +1 -1
  156. package/lib/utils/internal/coerceLlmArguments2.mjs +278 -258
  157. package/lib/utils/internal/coerceLlmArguments2.mjs.map +1 -1
  158. package/lib/utils/internal/parseLenientJson.mjs +2 -7
  159. package/lib/utils/internal/parseLenientJson.mjs.map +1 -1
  160. package/lib/utils/internal/parseLenientJson2.mjs +803 -811
  161. package/lib/utils/internal/parseLenientJson2.mjs.map +1 -1
  162. package/lib/utils/internal/stringifyValidationFailure.mjs +2 -7
  163. package/lib/utils/internal/stringifyValidationFailure.mjs.map +1 -1
  164. package/lib/utils/internal/stringifyValidationFailure2.mjs +310 -316
  165. package/lib/utils/internal/stringifyValidationFailure2.mjs.map +1 -1
  166. package/lib/validators/LlmTypeChecker.mjs +2 -7
  167. package/lib/validators/LlmTypeChecker.mjs.map +1 -1
  168. package/lib/validators/LlmTypeChecker2.mjs +314 -320
  169. package/lib/validators/LlmTypeChecker2.mjs.map +1 -1
  170. package/lib/validators/OpenApiTypeChecker.mjs +2 -7
  171. package/lib/validators/OpenApiTypeChecker.mjs.map +1 -1
  172. package/lib/validators/OpenApiTypeChecker2.mjs +209 -216
  173. package/lib/validators/OpenApiTypeChecker2.mjs.map +1 -1
  174. package/lib/validators/OpenApiV3TypeChecker.mjs +2 -7
  175. package/lib/validators/OpenApiV3TypeChecker.mjs.map +1 -1
  176. package/lib/validators/OpenApiV3TypeChecker2.mjs +30 -38
  177. package/lib/validators/OpenApiV3TypeChecker2.mjs.map +1 -1
  178. package/lib/validators/OpenApiV3_1TypeChecker.mjs +2 -7
  179. package/lib/validators/OpenApiV3_1TypeChecker.mjs.map +1 -1
  180. package/lib/validators/OpenApiV3_1TypeChecker2.mjs +34 -42
  181. package/lib/validators/OpenApiV3_1TypeChecker2.mjs.map +1 -1
  182. package/lib/validators/OpenApiValidator.mjs +2 -7
  183. package/lib/validators/OpenApiValidator.mjs.map +1 -1
  184. package/lib/validators/OpenApiValidator2.mjs +73 -80
  185. package/lib/validators/OpenApiValidator2.mjs.map +1 -1
  186. package/lib/validators/SwaggerV2TypeChecker.mjs +2 -7
  187. package/lib/validators/SwaggerV2TypeChecker.mjs.map +1 -1
  188. package/lib/validators/SwaggerV2TypeChecker2.mjs +31 -39
  189. package/lib/validators/SwaggerV2TypeChecker2.mjs.map +1 -1
  190. package/lib/validators/functional/_isBigintString.mjs +2 -7
  191. package/lib/validators/functional/_isBigintString.mjs.map +1 -1
  192. package/lib/validators/functional/_isBigintString2.mjs +14 -22
  193. package/lib/validators/functional/_isBigintString2.mjs.map +1 -1
  194. package/lib/validators/functional/_isFormatByte.mjs +2 -7
  195. package/lib/validators/functional/_isFormatByte.mjs.map +1 -1
  196. package/lib/validators/functional/_isFormatByte2.mjs +10 -18
  197. package/lib/validators/functional/_isFormatByte2.mjs.map +1 -1
  198. package/lib/validators/functional/_isFormatDate.mjs +2 -7
  199. package/lib/validators/functional/_isFormatDate.mjs.map +1 -1
  200. package/lib/validators/functional/_isFormatDate2.mjs +7 -15
  201. package/lib/validators/functional/_isFormatDate2.mjs.map +1 -1
  202. package/lib/validators/functional/_isFormatDateTime.mjs +2 -7
  203. package/lib/validators/functional/_isFormatDateTime.mjs.map +1 -1
  204. package/lib/validators/functional/_isFormatDateTime2.mjs +7 -15
  205. package/lib/validators/functional/_isFormatDateTime2.mjs.map +1 -1
  206. package/lib/validators/functional/_isFormatDuration.mjs +2 -7
  207. package/lib/validators/functional/_isFormatDuration.mjs.map +1 -1
  208. package/lib/validators/functional/_isFormatDuration2.mjs +7 -15
  209. package/lib/validators/functional/_isFormatDuration2.mjs.map +1 -1
  210. package/lib/validators/functional/_isFormatEmail.mjs +2 -7
  211. package/lib/validators/functional/_isFormatEmail.mjs.map +1 -1
  212. package/lib/validators/functional/_isFormatEmail2.mjs +7 -15
  213. package/lib/validators/functional/_isFormatEmail2.mjs.map +1 -1
  214. package/lib/validators/functional/_isFormatHostname.mjs +2 -7
  215. package/lib/validators/functional/_isFormatHostname.mjs.map +1 -1
  216. package/lib/validators/functional/_isFormatHostname2.mjs +7 -15
  217. package/lib/validators/functional/_isFormatHostname2.mjs.map +1 -1
  218. package/lib/validators/functional/_isFormatIdnEmail.mjs +2 -7
  219. package/lib/validators/functional/_isFormatIdnEmail.mjs.map +1 -1
  220. package/lib/validators/functional/_isFormatIdnEmail2.mjs +7 -15
  221. package/lib/validators/functional/_isFormatIdnEmail2.mjs.map +1 -1
  222. package/lib/validators/functional/_isFormatIdnHostname.mjs +2 -7
  223. package/lib/validators/functional/_isFormatIdnHostname.mjs.map +1 -1
  224. package/lib/validators/functional/_isFormatIdnHostname2.mjs +7 -15
  225. package/lib/validators/functional/_isFormatIdnHostname2.mjs.map +1 -1
  226. package/lib/validators/functional/_isFormatIpv4.mjs +2 -7
  227. package/lib/validators/functional/_isFormatIpv4.mjs.map +1 -1
  228. package/lib/validators/functional/_isFormatIpv42.mjs +7 -15
  229. package/lib/validators/functional/_isFormatIpv42.mjs.map +1 -1
  230. package/lib/validators/functional/_isFormatIpv6.mjs +2 -7
  231. package/lib/validators/functional/_isFormatIpv6.mjs.map +1 -1
  232. package/lib/validators/functional/_isFormatIpv62.mjs +7 -15
  233. package/lib/validators/functional/_isFormatIpv62.mjs.map +1 -1
  234. package/lib/validators/functional/_isFormatIri.mjs +2 -7
  235. package/lib/validators/functional/_isFormatIri.mjs.map +1 -1
  236. package/lib/validators/functional/_isFormatIri2.mjs +7 -15
  237. package/lib/validators/functional/_isFormatIri2.mjs.map +1 -1
  238. package/lib/validators/functional/_isFormatIriReference.mjs +2 -7
  239. package/lib/validators/functional/_isFormatIriReference.mjs.map +1 -1
  240. package/lib/validators/functional/_isFormatIriReference2.mjs +7 -15
  241. package/lib/validators/functional/_isFormatIriReference2.mjs.map +1 -1
  242. package/lib/validators/functional/_isFormatJsonPointer.mjs +2 -7
  243. package/lib/validators/functional/_isFormatJsonPointer.mjs.map +1 -1
  244. package/lib/validators/functional/_isFormatJsonPointer2.mjs +7 -15
  245. package/lib/validators/functional/_isFormatJsonPointer2.mjs.map +1 -1
  246. package/lib/validators/functional/_isFormatPassword.mjs +2 -7
  247. package/lib/validators/functional/_isFormatPassword.mjs.map +1 -1
  248. package/lib/validators/functional/_isFormatPassword2.mjs +6 -14
  249. package/lib/validators/functional/_isFormatPassword2.mjs.map +1 -1
  250. package/lib/validators/functional/_isFormatRegex.mjs +2 -7
  251. package/lib/validators/functional/_isFormatRegex.mjs.map +1 -1
  252. package/lib/validators/functional/_isFormatRegex2.mjs +14 -22
  253. package/lib/validators/functional/_isFormatRegex2.mjs.map +1 -1
  254. package/lib/validators/functional/_isFormatRelativeJsonPointer.mjs +2 -7
  255. package/lib/validators/functional/_isFormatRelativeJsonPointer.mjs.map +1 -1
  256. package/lib/validators/functional/_isFormatRelativeJsonPointer2.mjs +7 -15
  257. package/lib/validators/functional/_isFormatRelativeJsonPointer2.mjs.map +1 -1
  258. package/lib/validators/functional/_isFormatTime.mjs +2 -7
  259. package/lib/validators/functional/_isFormatTime.mjs.map +1 -1
  260. package/lib/validators/functional/_isFormatTime2.mjs +7 -15
  261. package/lib/validators/functional/_isFormatTime2.mjs.map +1 -1
  262. package/lib/validators/functional/_isFormatUri.mjs +2 -7
  263. package/lib/validators/functional/_isFormatUri.mjs.map +1 -1
  264. package/lib/validators/functional/_isFormatUri2.mjs +8 -16
  265. package/lib/validators/functional/_isFormatUri2.mjs.map +1 -1
  266. package/lib/validators/functional/_isFormatUriReference.mjs +2 -7
  267. package/lib/validators/functional/_isFormatUriReference.mjs.map +1 -1
  268. package/lib/validators/functional/_isFormatUriReference2.mjs +7 -15
  269. package/lib/validators/functional/_isFormatUriReference2.mjs.map +1 -1
  270. package/lib/validators/functional/_isFormatUriTemplate.mjs +2 -7
  271. package/lib/validators/functional/_isFormatUriTemplate.mjs.map +1 -1
  272. package/lib/validators/functional/_isFormatUriTemplate2.mjs +7 -15
  273. package/lib/validators/functional/_isFormatUriTemplate2.mjs.map +1 -1
  274. package/lib/validators/functional/_isFormatUrl.mjs +2 -7
  275. package/lib/validators/functional/_isFormatUrl.mjs.map +1 -1
  276. package/lib/validators/functional/_isFormatUrl2.mjs +7 -15
  277. package/lib/validators/functional/_isFormatUrl2.mjs.map +1 -1
  278. package/lib/validators/functional/_isFormatUuid.mjs +2 -7
  279. package/lib/validators/functional/_isFormatUuid.mjs.map +1 -1
  280. package/lib/validators/functional/_isFormatUuid2.mjs +7 -15
  281. package/lib/validators/functional/_isFormatUuid2.mjs.map +1 -1
  282. package/lib/validators/functional/_isUniqueItems.mjs +2 -7
  283. package/lib/validators/functional/_isUniqueItems.mjs.map +1 -1
  284. package/lib/validators/functional/_isUniqueItems2.mjs +140 -148
  285. package/lib/validators/functional/_isUniqueItems2.mjs.map +1 -1
  286. package/lib/validators/index.mjs +1 -7
  287. package/lib/validators/index.mjs.map +1 -1
  288. package/lib/validators/index2.mjs +42 -40
  289. package/lib/validators/index2.mjs.map +1 -1
  290. package/lib/validators/internal/IOpenApiValidatorContext.mjs +2 -7
  291. package/lib/validators/internal/IOpenApiValidatorContext.mjs.map +1 -1
  292. package/lib/validators/internal/IOpenApiValidatorContext2.mjs +2 -10
  293. package/lib/validators/internal/IOpenApiValidatorContext2.mjs.map +1 -1
  294. package/lib/validators/internal/OpenApiArrayValidator.mjs +2 -7
  295. package/lib/validators/internal/OpenApiArrayValidator.mjs.map +1 -1
  296. package/lib/validators/internal/OpenApiArrayValidator2.mjs +36 -42
  297. package/lib/validators/internal/OpenApiArrayValidator2.mjs.map +1 -1
  298. package/lib/validators/internal/OpenApiBooleanValidator.mjs +2 -7
  299. package/lib/validators/internal/OpenApiBooleanValidator.mjs.map +1 -1
  300. package/lib/validators/internal/OpenApiBooleanValidator2.mjs +10 -18
  301. package/lib/validators/internal/OpenApiBooleanValidator2.mjs.map +1 -1
  302. package/lib/validators/internal/OpenApiConstantValidator.mjs +2 -7
  303. package/lib/validators/internal/OpenApiConstantValidator.mjs.map +1 -1
  304. package/lib/validators/internal/OpenApiConstantValidator2.mjs +10 -18
  305. package/lib/validators/internal/OpenApiConstantValidator2.mjs.map +1 -1
  306. package/lib/validators/internal/OpenApiIntegerValidator.mjs +2 -7
  307. package/lib/validators/internal/OpenApiIntegerValidator.mjs.map +1 -1
  308. package/lib/validators/internal/OpenApiIntegerValidator2.mjs +33 -41
  309. package/lib/validators/internal/OpenApiIntegerValidator2.mjs.map +1 -1
  310. package/lib/validators/internal/OpenApiNumberValidator.mjs +2 -7
  311. package/lib/validators/internal/OpenApiNumberValidator.mjs.map +1 -1
  312. package/lib/validators/internal/OpenApiNumberValidator2.mjs +33 -41
  313. package/lib/validators/internal/OpenApiNumberValidator2.mjs.map +1 -1
  314. package/lib/validators/internal/OpenApiObjectValidator.js +2 -3
  315. package/lib/validators/internal/OpenApiObjectValidator.js.map +1 -1
  316. package/lib/validators/internal/OpenApiObjectValidator.mjs +2 -7
  317. package/lib/validators/internal/OpenApiObjectValidator.mjs.map +1 -1
  318. package/lib/validators/internal/OpenApiObjectValidator2.mjs +55 -62
  319. package/lib/validators/internal/OpenApiObjectValidator2.mjs.map +1 -1
  320. package/lib/validators/internal/OpenApiOneOfValidator.mjs +2 -7
  321. package/lib/validators/internal/OpenApiOneOfValidator.mjs.map +1 -1
  322. package/lib/validators/internal/OpenApiOneOfValidator2.mjs +188 -193
  323. package/lib/validators/internal/OpenApiOneOfValidator2.mjs.map +1 -1
  324. package/lib/validators/internal/OpenApiSchemaNamingRule.mjs +2 -7
  325. package/lib/validators/internal/OpenApiSchemaNamingRule.mjs.map +1 -1
  326. package/lib/validators/internal/OpenApiSchemaNamingRule2.mjs +124 -131
  327. package/lib/validators/internal/OpenApiSchemaNamingRule2.mjs.map +1 -1
  328. package/lib/validators/internal/OpenApiStationValidator.mjs +2 -7
  329. package/lib/validators/internal/OpenApiStationValidator.mjs.map +1 -1
  330. package/lib/validators/internal/OpenApiStationValidator2.mjs +86 -83
  331. package/lib/validators/internal/OpenApiStationValidator2.mjs.map +1 -1
  332. package/lib/validators/internal/OpenApiStringValidator.mjs +2 -7
  333. package/lib/validators/internal/OpenApiStringValidator.mjs.map +1 -1
  334. package/lib/validators/internal/OpenApiStringValidator2.mjs +115 -102
  335. package/lib/validators/internal/OpenApiStringValidator2.mjs.map +1 -1
  336. package/lib/validators/internal/OpenApiTupleValidator.mjs +2 -7
  337. package/lib/validators/internal/OpenApiTupleValidator.mjs.map +1 -1
  338. package/lib/validators/internal/OpenApiTupleValidator2.mjs +33 -40
  339. package/lib/validators/internal/OpenApiTupleValidator2.mjs.map +1 -1
  340. package/package.json +4 -4
  341. package/src/converters/LlmSchemaConverter.ts +1 -1
  342. package/src/utils/Singleton.ts +1 -0
  343. package/src/utils/internal/OpenApiTypeCheckerBase.ts +12 -3
  344. package/src/utils/internal/coerceLlmArguments.ts +27 -1
  345. package/src/validators/internal/OpenApiObjectValidator.ts +1 -2
@@ -1,815 +1,807 @@
1
- import { __exports as parseLenientJson } from '../../_virtual/parseLenientJson.mjs';
1
+ import { __exports as parseLenientJson$1 } from '../../_virtual/parseLenientJson.mjs';
2
2
 
3
- var hasRequiredParseLenientJson;
4
-
5
- function requireParseLenientJson () {
6
- if (hasRequiredParseLenientJson) return parseLenientJson;
7
- hasRequiredParseLenientJson = 1;
8
- Object.defineProperty(parseLenientJson, "__esModule", { value: true });
9
- parseLenientJson.parseLenientJson = parseLenientJson$1;
10
- /**
11
- * Parse lenient JSON that may be incomplete or malformed.
12
- *
13
- * Handles:
14
- *
15
- * - Unclosed brackets `{`, `[` - parses as much as possible
16
- * - Trailing commas `[1, 2, ]` - ignores them
17
- * - Unclosed strings `"hello` - returns partial string
18
- * - Junk text before JSON (LLM often adds explanatory text)
19
- * - Markdown code blocks (extracts content from `json ... `)
20
- * - Incomplete keywords like `tru`, `fal`, `nul`
21
- * - Unicode escape sequences including surrogate pairs (emoji)
22
- * - JavaScript-style comments (single-line and multi-line)
23
- * - Unquoted object keys (JavaScript identifier style)
24
- *
25
- * @param input Raw JSON string (potentially incomplete)
26
- * @returns Parse result with data, original input, and any errors
27
- * @internal
28
- */
29
- function parseLenientJson$1(input) {
30
- // For safe guard
31
- if (typeof input !== "string")
32
- input = String(input);
33
- // Try native JSON.parse first (faster for valid JSON)
34
- let error = null;
35
- try {
36
- return {
37
- success: true,
38
- data: JSON.parse(input),
39
- };
40
- }
41
- catch (e) {
42
- // Fall back to lenient parser
43
- error = e instanceof Error ? e : new Error(String(e));
44
- }
45
- try {
46
- return iterate(input);
47
- }
48
- catch (_a) {
49
- // actually unreachable, maybe?
50
- return {
51
- success: false,
52
- data: undefined,
53
- input,
54
- errors: [
55
- {
56
- path: "$input",
57
- expected: "valid JSON",
58
- description: error.message,
59
- },
60
- ],
61
- };
62
- }
63
- }
64
- function iterate(input) {
65
- // Extract markdown code block if present
66
- const codeBlockContent = extractMarkdownCodeBlock(input);
67
- const jsonSource = codeBlockContent !== null ? codeBlockContent : input;
68
- // Check if input is empty or whitespace-only
69
- const trimmed = jsonSource.trim();
70
- if (trimmed.length === 0) {
71
- return {
72
- success: false,
73
- data: undefined,
74
- input,
75
- errors: [
76
- {
77
- path: "$input",
78
- expected: "JSON value",
79
- description: "empty input",
80
- },
81
- ],
82
- };
83
- }
84
- // Check if input starts with a primitive value (no junk prefix skipping needed)
85
- if (startsWithPrimitive(trimmed)) {
86
- const errors = [];
87
- const parser = new LenientJsonParser(jsonSource, errors);
88
- const data = parser.parse();
89
- if (errors.length > 0) {
90
- return { success: false, data: data, input, errors };
91
- }
92
- return { success: true, data: data };
93
- }
94
- // Find JSON start position (skip junk prefix from LLM)
95
- const jsonStart = findJsonStart(jsonSource);
96
- if (jsonStart === -1) {
97
- // No object/array found - check if there's a primitive after skipping comments
98
- const skipped = skipCommentsAndWhitespace(jsonSource);
99
- if (skipped.length > 0 && startsWithPrimitive(skipped)) {
100
- const errors = [];
101
- const parser = new LenientJsonParser(jsonSource, errors);
102
- const data = parser.parse();
103
- if (errors.length > 0) {
104
- return { success: false, data: data, input, errors };
105
- }
106
- return { success: true, data: data };
107
- }
108
- // No valid JSON found - return failure
109
- return {
110
- success: false,
111
- data: undefined,
112
- input,
113
- errors: [
114
- {
115
- path: "$input",
116
- expected: "JSON value",
117
- description: jsonSource,
118
- },
119
- ],
120
- };
121
- }
122
- // Extract JSON portion (skip junk prefix)
123
- const jsonInput = jsonStart > 0 ? jsonSource.slice(jsonStart) : jsonSource;
124
- const errors = [];
125
- const parser = new LenientJsonParser(jsonInput, errors);
126
- const data = parser.parse();
127
- if (errors.length > 0) {
128
- return {
129
- success: false,
130
- data: data,
131
- input,
132
- errors,
133
- };
134
- }
135
- return {
136
- success: true,
137
- data: data,
138
- };
139
- }
140
- /**
141
- * Check if a string is a valid 4-character hexadecimal string.
142
- *
143
- * @internal
144
- */
145
- function isHexString(s) {
146
- if (s.length !== 4)
147
- return false;
148
- for (let i = 0; i < 4; i++) {
149
- const c = s.charCodeAt(i);
150
- if (!((c >= 48 && c <= 57) || (c >= 65 && c <= 70) || (c >= 97 && c <= 102))) {
151
- return false;
152
- }
153
- }
154
- return true;
155
- }
156
- /**
157
- * Extract JSON content from markdown code block if present.
158
- *
159
- * LLM outputs often wrap JSON in markdown code blocks like:
160
- *
161
- * Here is your result:
162
- *
163
- * ```json
164
- * { "name": "test" }
165
- * ```
166
- *
167
- * This function extracts the content between the backticks.
168
- *
169
- * IMPORTANT: Only extracts if the input doesn't already start with JSON. If
170
- * input (after trim) starts with `{`, `[`, or `"`, it's already JSON and any
171
- * markdown inside is part of a string value.
172
- *
173
- * @param input Text that may contain markdown code block
174
- * @returns Extracted content or null if no code block found
175
- * @internal
176
- */
177
- function extractMarkdownCodeBlock(input) {
178
- // Must be ```json specifically, not just ```
179
- const codeBlockStart = input.indexOf("```json");
180
- if (codeBlockStart === -1)
181
- return null;
182
- // Check if input already starts with JSON (after trimming whitespace)
183
- // If so, don't extract - the markdown is inside a JSON string value
184
- const trimmed = input.trimStart();
185
- if (trimmed.length > 0) {
186
- const firstChar = trimmed[0];
187
- if (firstChar === "{" || firstChar === "[" || firstChar === '"') {
188
- return null;
189
- }
190
- }
191
- // Find the end of the opening line (after ```json)
192
- let contentStart = codeBlockStart + 7; // length of "```json"
193
- while (contentStart < input.length && input[contentStart] !== "\n") {
194
- contentStart++;
195
- }
196
- if (contentStart >= input.length)
197
- return null;
198
- contentStart++; // skip the newline
199
- // Find the closing ```
200
- const codeBlockEnd = input.indexOf("```", contentStart);
201
- if (codeBlockEnd === -1) {
202
- // No closing ``` - return everything after opening
203
- return input.slice(contentStart);
204
- }
205
- return input.slice(contentStart, codeBlockEnd);
206
- }
207
- /**
208
- * Find the start position of JSON object/array content in text that may have
209
- * junk prefix.
210
- *
211
- * LLM outputs often contain text before JSON like:
212
- *
213
- * - "Here is your JSON: {"name": "test"}"
214
- * - "Sure! [1, 2, 3]"
215
- *
216
- * This function skips over comments and strings to find the real JSON start.
217
- * Primitive values (strings, numbers, booleans) are handled directly by the
218
- * parser.
219
- *
220
- * @param input Text that may contain JSON with junk prefix
221
- * @returns Index of first `{` or `[` outside comments/strings, or -1 if not
222
- * found
223
- * @internal
224
- */
225
- function findJsonStart(input) {
226
- let pos = 0;
227
- const len = input.length;
228
- while (pos < len) {
229
- const ch = input[pos];
230
- // Found JSON start
231
- if (ch === "{" || ch === "[") {
232
- return pos;
233
- }
234
- // Skip single-line comment
235
- if (ch === "/" && pos + 1 < len && input[pos + 1] === "/") {
236
- pos += 2;
237
- while (pos < len && input[pos] !== "\n" && input[pos] !== "\r") {
238
- pos++;
239
- }
240
- continue;
241
- }
242
- // Skip multi-line comment
243
- if (ch === "/" && pos + 1 < len && input[pos + 1] === "*") {
244
- pos += 2;
245
- while (pos + 1 < len) {
246
- if (input[pos] === "*" && input[pos + 1] === "/") {
247
- pos += 2;
248
- break;
249
- }
250
- pos++;
251
- }
252
- // If unclosed comment, move to end
253
- if (pos + 1 >= len) {
254
- pos = len;
255
- }
256
- continue;
257
- }
258
- // Skip string literal (to avoid matching { or [ inside strings)
259
- if (ch === '"') {
260
- pos++;
261
- while (pos < len) {
262
- if (input[pos] === "\\") {
263
- pos += 2; // skip escape sequence
264
- continue;
265
- }
266
- if (input[pos] === '"') {
267
- pos++;
268
- break;
269
- }
270
- pos++;
271
- }
272
- continue;
273
- }
274
- pos++;
275
- }
276
- return -1;
277
- }
278
- /**
279
- * Skip leading comments and whitespace from input.
280
- *
281
- * @param input Text that may start with comments or whitespace
282
- * @returns Input with leading comments and whitespace removed
283
- * @internal
284
- */
285
- function skipCommentsAndWhitespace(input) {
286
- let pos = 0;
287
- const len = input.length;
288
- while (pos < len) {
289
- const ch = input[pos];
290
- // Skip whitespace
291
- if (ch === " " || ch === "\t" || ch === "\n" || ch === "\r") {
292
- pos++;
293
- continue;
294
- }
295
- // Skip single-line comment
296
- if (ch === "/" && pos + 1 < len && input[pos + 1] === "/") {
297
- pos += 2;
298
- while (pos < len && input[pos] !== "\n" && input[pos] !== "\r") {
299
- pos++;
300
- }
301
- continue;
302
- }
303
- // Skip multi-line comment
304
- if (ch === "/" && pos + 1 < len && input[pos + 1] === "*") {
305
- pos += 2;
306
- while (pos + 1 < len) {
307
- if (input[pos] === "*" && input[pos + 1] === "/") {
308
- pos += 2;
309
- break;
310
- }
311
- pos++;
312
- }
313
- if (pos + 1 >= len) {
314
- pos = len;
315
- }
316
- continue;
317
- }
318
- // Not whitespace or comment
319
- break;
320
- }
321
- return input.slice(pos);
322
- }
323
- /**
324
- * Check if input starts with a valid JSON primitive token.
325
- *
326
- * @param input Trimmed input string
327
- * @returns True if input starts with a primitive value
328
- * @internal
329
- */
330
- function startsWithPrimitive(input) {
331
- if (input.length === 0)
332
- return false;
333
- const ch = input[0];
334
- // String
335
- if (ch === '"')
336
- return true;
337
- // Number (digit or minus)
338
- if ((ch >= "0" && ch <= "9") || ch === "-")
339
- return true;
340
- // Keywords
341
- if (input.startsWith("true") ||
342
- input.startsWith("false") ||
343
- input.startsWith("null"))
344
- return true;
345
- // Partial keywords (note: "null" requires at least 2 chars to match parseKeywordOrIdentifier logic)
346
- if ("true".startsWith(input) ||
347
- "false".startsWith(input) ||
348
- ("null".startsWith(input) && input.length >= 2))
349
- return true;
350
- // Boolean string variants (note: "n" is intentionally excluded)
351
- const lower = input.toLowerCase();
352
- if (lower === "yes" ||
353
- lower === "y" ||
354
- lower === "on" ||
355
- lower === "no" ||
356
- lower === "off")
357
- return true;
358
- return false;
359
- }
360
- /**
361
- * Lenient JSON parser that handles incomplete JSON.
362
- *
363
- * @internal
364
- */
365
- class LenientJsonParser {
366
- constructor(input, errors) {
367
- this.pos = 0;
368
- this.depth = 0;
369
- this.input = input;
370
- this.errors = errors;
371
- }
372
- parse() {
373
- this.skipWhitespace();
374
- if (this.pos >= this.input.length) {
375
- return undefined;
376
- }
377
- return this.parseValue("$input");
378
- }
379
- parseValue(path) {
380
- this.skipWhitespace();
381
- if (this.pos >= this.input.length) {
382
- return undefined;
383
- }
384
- // Check for maximum depth to prevent stack overflow
385
- if (this.depth >= MAX_DEPTH) {
386
- this.errors.push({
387
- path,
388
- expected: "value (max depth exceeded)",
389
- description: undefined,
390
- });
391
- return undefined;
392
- }
393
- const char = this.input[this.pos];
394
- if (char === "{")
395
- return this.parseObject(path);
396
- if (char === "[")
397
- return this.parseArray(path);
398
- if (char === '"')
399
- return this.parseString();
400
- if (char === "-" || (char >= "0" && char <= "9"))
401
- return this.parseNumber();
402
- // Handle keywords (true, false, null) or invalid identifiers
403
- if (this.isIdentifierStart(char)) {
404
- return this.parseKeywordOrIdentifier(path);
405
- }
406
- // Don't skip structural characters - let the caller handle them
407
- const ch = this.input[this.pos];
408
- if (ch === "}" || ch === "]" || ch === ",") {
409
- // Not an error - just no value here (e.g., {"a":} or [,])
410
- return undefined;
411
- }
412
- this.errors.push({
413
- path,
414
- expected: "JSON value",
415
- description: this.getErrorContext(),
416
- });
417
- // Skip the problematic character and try to continue
418
- this.pos++;
419
- return undefined;
420
- }
421
- getErrorContext() {
422
- // Get surrounding context for better error messages
423
- const start = Math.max(0, this.pos - 10);
424
- const end = Math.min(this.input.length, this.pos + 20);
425
- const before = this.input.slice(start, this.pos);
426
- const after = this.input.slice(this.pos, end);
427
- return ((start > 0 ? "..." : "") +
428
- before +
429
- "→" +
430
- after +
431
- (end < this.input.length ? "..." : ""));
432
- }
433
- parseKeywordOrIdentifier(path) {
434
- // Extract the token (sequence of identifier characters)
435
- const start = this.pos;
436
- while (this.pos < this.input.length &&
437
- this.isIdentifierChar(this.input[this.pos])) {
438
- this.pos++;
439
- }
440
- const token = this.input.slice(start, this.pos);
441
- // Check for complete or partial keyword matches
442
- if (token === "true")
443
- return true;
444
- if (token === "false")
445
- return false;
446
- if (token === "null")
447
- return null;
448
- // Boolean string coercion: "yes", "y", "on" -> true, "no", "off" -> false
449
- // Note: "n" is intentionally NOT handled (neither null nor false)
450
- const lower = token.toLowerCase();
451
- if (lower === "yes" || lower === "y" || lower === "on")
452
- return true;
453
- if (lower === "no" || lower === "off")
454
- return false;
455
- // Partial match for lenient parsing (e.g., "tru" -> true, "fal" -> false)
456
- if ("true".startsWith(token) && token.length > 0)
457
- return true;
458
- if ("false".startsWith(token) && token.length > 0)
459
- return false;
460
- if ("null".startsWith(token) && token.length >= 2)
461
- return null;
462
- // Check if this looks like a string with missing opening quote (e.g., abcdefg")
463
- if (this.pos < this.input.length && this.input[this.pos] === '"') {
464
- // Treat as unquoted string value - skip the errant closing quote and return as string
465
- this.pos++; // skip the closing quote
466
- this.errors.push({
467
- path,
468
- expected: "quoted string",
469
- description: "missing opening quote for '" + token + "'",
470
- });
471
- return token;
472
- }
473
- // Invalid identifier as value - provide helpful error message
474
- this.errors.push({
475
- path,
476
- expected: "JSON value (string, number, boolean, null, object, or array)",
477
- description: "unquoted string '" + token + "' - did you forget quotes?",
478
- });
479
- // Skip to next comma, closing brace/bracket for recovery
480
- this.skipToRecoveryPoint();
481
- return undefined;
482
- }
483
- skipToRecoveryPoint() {
484
- while (this.pos < this.input.length) {
485
- const ch = this.input[this.pos];
486
- if (ch === "," || ch === "}" || ch === "]") {
487
- return;
488
- }
489
- this.pos++;
490
- }
491
- }
492
- parseObject(path) {
493
- const result = {};
494
- this.pos++; // skip '{'
495
- this.depth++;
496
- this.skipWhitespace();
497
- while (this.pos < this.input.length) {
498
- this.skipWhitespace();
499
- // Handle end of object or end of input
500
- if (this.pos >= this.input.length || this.input[this.pos] === "}") {
501
- if (this.pos < this.input.length)
502
- this.pos++; // skip '}'
503
- this.depth--;
504
- return result;
505
- }
506
- // Skip trailing comma
507
- if (this.input[this.pos] === ",") {
508
- this.pos++;
509
- this.skipWhitespace();
510
- continue;
511
- }
512
- // Parse key (quoted string or unquoted identifier)
513
- let key;
514
- if (this.input[this.pos] === '"') {
515
- key = this.parseString();
516
- }
517
- else if (this.isIdentifierStart(this.input[this.pos])) {
518
- key = this.parseIdentifier();
519
- }
520
- else {
521
- this.errors.push({
522
- path,
523
- expected: "string key",
524
- description: this.input[this.pos],
525
- });
526
- // Try to recover by skipping to next meaningful character
527
- this.depth--;
528
- return result;
529
- }
530
- if (typeof key !== "string") {
531
- this.depth--;
532
- return result;
533
- }
534
- this.skipWhitespace();
535
- // Expect colon - but if we're at end of input, it's just incomplete (not an error)
536
- if (this.pos >= this.input.length) {
537
- this.depth--;
538
- return result;
539
- }
540
- if (this.input[this.pos] !== ":") {
541
- this.errors.push({
542
- path: path + "." + key,
543
- expected: "':'",
544
- description: this.input[this.pos],
545
- });
546
- this.depth--;
547
- return result;
548
- }
549
- this.pos++; // skip ':'
550
- this.skipWhitespace();
551
- // Parse value
552
- if (this.pos >= this.input.length) {
553
- // No value - incomplete but not an error for lenient parsing
554
- this.depth--;
555
- return result;
556
- }
557
- const value = this.parseValue(path + "." + key);
558
- result[key] = value;
559
- this.skipWhitespace();
560
- // Handle comma or end
561
- if (this.pos < this.input.length && this.input[this.pos] === ",") {
562
- this.pos++;
563
- }
564
- }
565
- this.depth--;
566
- return result;
567
- }
568
- parseArray(path) {
569
- const result = [];
570
- this.pos++; // skip '['
571
- this.depth++;
572
- this.skipWhitespace();
573
- let index = 0;
574
- while (this.pos < this.input.length) {
575
- this.skipWhitespace();
576
- // Handle end of array or end of input
577
- if (this.pos >= this.input.length || this.input[this.pos] === "]") {
578
- if (this.pos < this.input.length)
579
- this.pos++; // skip ']'
580
- this.depth--;
581
- return result;
582
- }
583
- // Skip trailing comma
584
- if (this.input[this.pos] === ",") {
585
- this.pos++;
586
- this.skipWhitespace();
587
- continue;
588
- }
589
- // Parse value
590
- const prevPos = this.pos;
591
- const value = this.parseValue(path + "[" + index + "]");
592
- // Guard: if parseValue didn't advance, skip unexpected char to prevent infinite loop
593
- if (this.pos === prevPos && this.pos < this.input.length) {
594
- this.pos++;
595
- continue;
596
- }
597
- result.push(value);
598
- index++;
599
- this.skipWhitespace();
600
- // Handle comma or end
601
- if (this.pos < this.input.length && this.input[this.pos] === ",") {
602
- this.pos++;
603
- }
604
- }
605
- this.depth--;
606
- return result;
607
- }
608
- parseString() {
609
- this.pos++; // skip opening '"'
610
- let result = "";
611
- let escaped = false;
612
- while (this.pos < this.input.length) {
613
- const char = this.input[this.pos];
614
- if (escaped) {
615
- switch (char) {
616
- case '"':
617
- result += '"';
618
- break;
619
- case "\\":
620
- result += "\\";
621
- break;
622
- case "/":
623
- result += "/";
624
- break;
625
- case "b":
626
- result += "\b";
627
- break;
628
- case "f":
629
- result += "\f";
630
- break;
631
- case "n":
632
- result += "\n";
633
- break;
634
- case "r":
635
- result += "\r";
636
- break;
637
- case "t":
638
- result += "\t";
639
- break;
640
- case "u":
641
- // Parse unicode escape
642
- if (this.pos + 4 <= this.input.length) {
643
- const hex = this.input.slice(this.pos + 1, this.pos + 5);
644
- if (isHexString(hex)) {
645
- const highCode = parseInt(hex, 16);
646
- this.pos += 4;
647
- // Check for surrogate pair (emoji and characters > U+FFFF)
648
- if (highCode >= 0xd800 &&
649
- highCode <= 0xdbff &&
650
- this.pos + 6 <= this.input.length &&
651
- this.input[this.pos + 1] === "\\" &&
652
- this.input[this.pos + 2] === "u") {
653
- const lowHex = this.input.slice(this.pos + 3, this.pos + 7);
654
- if (isHexString(lowHex)) {
655
- const lowCode = parseInt(lowHex, 16);
656
- if (lowCode >= 0xdc00 && lowCode <= 0xdfff) {
657
- result += String.fromCharCode(highCode, lowCode);
658
- this.pos += 6;
659
- break;
660
- }
661
- }
662
- }
663
- result += String.fromCharCode(highCode);
664
- }
665
- else {
666
- // Invalid hex - preserve escape sequence literally
667
- result += "\\u" + hex;
668
- this.pos += 4;
669
- }
670
- }
671
- else {
672
- // Incomplete unicode escape - add partial sequence
673
- const partial = this.input.slice(this.pos + 1);
674
- result += "\\u" + partial;
675
- this.pos = this.input.length - 1;
676
- }
677
- break;
678
- default:
679
- result += char;
680
- }
681
- escaped = false;
682
- this.pos++;
683
- continue;
684
- }
685
- if (char === "\\") {
686
- escaped = true;
687
- this.pos++;
688
- continue;
689
- }
690
- if (char === '"') {
691
- this.pos++; // skip closing '"'
692
- return result;
693
- }
694
- result += char;
695
- this.pos++;
696
- }
697
- // Unclosed string - return what we have (lenient)
698
- return result;
699
- }
700
- parseNumber() {
701
- const start = this.pos;
702
- // Handle negative sign
703
- if (this.input[this.pos] === "-") {
704
- this.pos++;
705
- }
706
- // Parse integer part
707
- while (this.pos < this.input.length &&
708
- this.input[this.pos] >= "0" &&
709
- this.input[this.pos] <= "9") {
710
- this.pos++;
711
- }
712
- // Parse decimal part
713
- if (this.pos < this.input.length && this.input[this.pos] === ".") {
714
- this.pos++;
715
- while (this.pos < this.input.length &&
716
- this.input[this.pos] >= "0" &&
717
- this.input[this.pos] <= "9") {
718
- this.pos++;
719
- }
720
- }
721
- // Parse exponent
722
- if (this.pos < this.input.length &&
723
- (this.input[this.pos] === "e" || this.input[this.pos] === "E")) {
724
- this.pos++;
725
- if (this.pos < this.input.length &&
726
- (this.input[this.pos] === "+" || this.input[this.pos] === "-")) {
727
- this.pos++;
728
- }
729
- while (this.pos < this.input.length &&
730
- this.input[this.pos] >= "0" &&
731
- this.input[this.pos] <= "9") {
732
- this.pos++;
733
- }
734
- }
735
- const numStr = this.input.slice(start, this.pos);
736
- const num = Number(numStr);
737
- return Number.isNaN(num) ? 0 : num;
738
- }
739
- isIdentifierStart(ch) {
740
- return ((ch >= "a" && ch <= "z") ||
741
- (ch >= "A" && ch <= "Z") ||
742
- ch === "_" ||
743
- ch === "$");
744
- }
745
- isIdentifierChar(ch) {
746
- return ((ch >= "a" && ch <= "z") ||
747
- (ch >= "A" && ch <= "Z") ||
748
- (ch >= "0" && ch <= "9") ||
749
- ch === "_" ||
750
- ch === "$");
751
- }
752
- parseIdentifier() {
753
- const start = this.pos;
754
- while (this.pos < this.input.length &&
755
- this.isIdentifierChar(this.input[this.pos])) {
756
- this.pos++;
757
- }
758
- return this.input.slice(start, this.pos);
759
- }
760
- skipWhitespace() {
761
- while (this.pos < this.input.length) {
762
- const ch = this.input[this.pos];
763
- // Skip standard whitespace
764
- if (ch === " " || ch === "\t" || ch === "\n" || ch === "\r") {
765
- this.pos++;
766
- continue;
767
- }
768
- // Skip single-line comment: // ...
769
- if (ch === "/" &&
770
- this.pos + 1 < this.input.length &&
771
- this.input[this.pos + 1] === "/") {
772
- this.pos += 2;
773
- while (this.pos < this.input.length &&
774
- this.input[this.pos] !== "\n" &&
775
- this.input[this.pos] !== "\r") {
776
- this.pos++;
777
- }
778
- continue;
779
- }
780
- // Skip multi-line comment: /* ... */
781
- if (ch === "/" &&
782
- this.pos + 1 < this.input.length &&
783
- this.input[this.pos + 1] === "*") {
784
- this.pos += 2;
785
- while (this.pos + 1 < this.input.length) {
786
- if (this.input[this.pos] === "*" &&
787
- this.input[this.pos + 1] === "/") {
788
- this.pos += 2;
789
- break;
790
- }
791
- this.pos++;
792
- }
793
- // Handle unclosed comment - move to end
794
- if (this.pos + 1 >= this.input.length) {
795
- this.pos = this.input.length;
796
- }
797
- continue;
798
- }
799
- // Not whitespace or comment
800
- break;
801
- }
802
- }
803
- }
804
- /**
805
- * Maximum nesting depth to prevent stack overflow attacks.
806
- *
807
- * @internal
808
- */
809
- const MAX_DEPTH = 512;
810
-
811
- return parseLenientJson;
3
+ Object.defineProperty(parseLenientJson$1, "__esModule", { value: true });
4
+ var parseLenientJson_2 = parseLenientJson$1.parseLenientJson = parseLenientJson;
5
+ /**
6
+ * Parse lenient JSON that may be incomplete or malformed.
7
+ *
8
+ * Handles:
9
+ *
10
+ * - Unclosed brackets `{`, `[` - parses as much as possible
11
+ * - Trailing commas `[1, 2, ]` - ignores them
12
+ * - Unclosed strings `"hello` - returns partial string
13
+ * - Junk text before JSON (LLM often adds explanatory text)
14
+ * - Markdown code blocks (extracts content from `json ... `)
15
+ * - Incomplete keywords like `tru`, `fal`, `nul`
16
+ * - Unicode escape sequences including surrogate pairs (emoji)
17
+ * - JavaScript-style comments (single-line and multi-line)
18
+ * - Unquoted object keys (JavaScript identifier style)
19
+ *
20
+ * @param input Raw JSON string (potentially incomplete)
21
+ * @returns Parse result with data, original input, and any errors
22
+ * @internal
23
+ */
24
+ function parseLenientJson(input) {
25
+ // For safe guard
26
+ if (typeof input !== "string")
27
+ input = String(input);
28
+ // Try native JSON.parse first (faster for valid JSON)
29
+ let error = null;
30
+ try {
31
+ return {
32
+ success: true,
33
+ data: JSON.parse(input),
34
+ };
35
+ }
36
+ catch (e) {
37
+ // Fall back to lenient parser
38
+ error = e instanceof Error ? e : new Error(String(e));
39
+ }
40
+ try {
41
+ return iterate(input);
42
+ }
43
+ catch (_a) {
44
+ // actually unreachable, maybe?
45
+ return {
46
+ success: false,
47
+ data: undefined,
48
+ input,
49
+ errors: [
50
+ {
51
+ path: "$input",
52
+ expected: "valid JSON",
53
+ description: error.message,
54
+ },
55
+ ],
56
+ };
57
+ }
58
+ }
59
+ function iterate(input) {
60
+ // Extract markdown code block if present
61
+ const codeBlockContent = extractMarkdownCodeBlock(input);
62
+ const jsonSource = codeBlockContent !== null ? codeBlockContent : input;
63
+ // Check if input is empty or whitespace-only
64
+ const trimmed = jsonSource.trim();
65
+ if (trimmed.length === 0) {
66
+ return {
67
+ success: false,
68
+ data: undefined,
69
+ input,
70
+ errors: [
71
+ {
72
+ path: "$input",
73
+ expected: "JSON value",
74
+ description: "empty input",
75
+ },
76
+ ],
77
+ };
78
+ }
79
+ // Check if input starts with a primitive value (no junk prefix skipping needed)
80
+ if (startsWithPrimitive(trimmed)) {
81
+ const errors = [];
82
+ const parser = new LenientJsonParser(jsonSource, errors);
83
+ const data = parser.parse();
84
+ if (errors.length > 0) {
85
+ return { success: false, data: data, input, errors };
86
+ }
87
+ return { success: true, data: data };
88
+ }
89
+ // Find JSON start position (skip junk prefix from LLM)
90
+ const jsonStart = findJsonStart(jsonSource);
91
+ if (jsonStart === -1) {
92
+ // No object/array found - check if there's a primitive after skipping comments
93
+ const skipped = skipCommentsAndWhitespace(jsonSource);
94
+ if (skipped.length > 0 && startsWithPrimitive(skipped)) {
95
+ const errors = [];
96
+ const parser = new LenientJsonParser(jsonSource, errors);
97
+ const data = parser.parse();
98
+ if (errors.length > 0) {
99
+ return { success: false, data: data, input, errors };
100
+ }
101
+ return { success: true, data: data };
102
+ }
103
+ // No valid JSON found - return failure
104
+ return {
105
+ success: false,
106
+ data: undefined,
107
+ input,
108
+ errors: [
109
+ {
110
+ path: "$input",
111
+ expected: "JSON value",
112
+ description: jsonSource,
113
+ },
114
+ ],
115
+ };
116
+ }
117
+ // Extract JSON portion (skip junk prefix)
118
+ const jsonInput = jsonStart > 0 ? jsonSource.slice(jsonStart) : jsonSource;
119
+ const errors = [];
120
+ const parser = new LenientJsonParser(jsonInput, errors);
121
+ const data = parser.parse();
122
+ if (errors.length > 0) {
123
+ return {
124
+ success: false,
125
+ data: data,
126
+ input,
127
+ errors,
128
+ };
129
+ }
130
+ return {
131
+ success: true,
132
+ data: data,
133
+ };
134
+ }
135
+ /**
136
+ * Check if a string is a valid 4-character hexadecimal string.
137
+ *
138
+ * @internal
139
+ */
140
+ function isHexString(s) {
141
+ if (s.length !== 4)
142
+ return false;
143
+ for (let i = 0; i < 4; i++) {
144
+ const c = s.charCodeAt(i);
145
+ if (!((c >= 48 && c <= 57) || (c >= 65 && c <= 70) || (c >= 97 && c <= 102))) {
146
+ return false;
147
+ }
148
+ }
149
+ return true;
150
+ }
151
+ /**
152
+ * Extract JSON content from markdown code block if present.
153
+ *
154
+ * LLM outputs often wrap JSON in markdown code blocks like:
155
+ *
156
+ * Here is your result:
157
+ *
158
+ * ```json
159
+ * { "name": "test" }
160
+ * ```
161
+ *
162
+ * This function extracts the content between the backticks.
163
+ *
164
+ * IMPORTANT: Only extracts if the input doesn't already start with JSON. If
165
+ * input (after trim) starts with `{`, `[`, or `"`, it's already JSON and any
166
+ * markdown inside is part of a string value.
167
+ *
168
+ * @param input Text that may contain markdown code block
169
+ * @returns Extracted content or null if no code block found
170
+ * @internal
171
+ */
172
+ function extractMarkdownCodeBlock(input) {
173
+ // Must be ```json specifically, not just ```
174
+ const codeBlockStart = input.indexOf("```json");
175
+ if (codeBlockStart === -1)
176
+ return null;
177
+ // Check if input already starts with JSON (after trimming whitespace)
178
+ // If so, don't extract - the markdown is inside a JSON string value
179
+ const trimmed = input.trimStart();
180
+ if (trimmed.length > 0) {
181
+ const firstChar = trimmed[0];
182
+ if (firstChar === "{" || firstChar === "[" || firstChar === '"') {
183
+ return null;
184
+ }
185
+ }
186
+ // Find the end of the opening line (after ```json)
187
+ let contentStart = codeBlockStart + 7; // length of "```json"
188
+ while (contentStart < input.length && input[contentStart] !== "\n") {
189
+ contentStart++;
190
+ }
191
+ if (contentStart >= input.length)
192
+ return null;
193
+ contentStart++; // skip the newline
194
+ // Find the closing ```
195
+ const codeBlockEnd = input.indexOf("```", contentStart);
196
+ if (codeBlockEnd === -1) {
197
+ // No closing ``` - return everything after opening
198
+ return input.slice(contentStart);
199
+ }
200
+ return input.slice(contentStart, codeBlockEnd);
201
+ }
202
+ /**
203
+ * Find the start position of JSON object/array content in text that may have
204
+ * junk prefix.
205
+ *
206
+ * LLM outputs often contain text before JSON like:
207
+ *
208
+ * - "Here is your JSON: {"name": "test"}"
209
+ * - "Sure! [1, 2, 3]"
210
+ *
211
+ * This function skips over comments and strings to find the real JSON start.
212
+ * Primitive values (strings, numbers, booleans) are handled directly by the
213
+ * parser.
214
+ *
215
+ * @param input Text that may contain JSON with junk prefix
216
+ * @returns Index of first `{` or `[` outside comments/strings, or -1 if not
217
+ * found
218
+ * @internal
219
+ */
220
+ function findJsonStart(input) {
221
+ let pos = 0;
222
+ const len = input.length;
223
+ while (pos < len) {
224
+ const ch = input[pos];
225
+ // Found JSON start
226
+ if (ch === "{" || ch === "[") {
227
+ return pos;
228
+ }
229
+ // Skip single-line comment
230
+ if (ch === "/" && pos + 1 < len && input[pos + 1] === "/") {
231
+ pos += 2;
232
+ while (pos < len && input[pos] !== "\n" && input[pos] !== "\r") {
233
+ pos++;
234
+ }
235
+ continue;
236
+ }
237
+ // Skip multi-line comment
238
+ if (ch === "/" && pos + 1 < len && input[pos + 1] === "*") {
239
+ pos += 2;
240
+ while (pos + 1 < len) {
241
+ if (input[pos] === "*" && input[pos + 1] === "/") {
242
+ pos += 2;
243
+ break;
244
+ }
245
+ pos++;
246
+ }
247
+ // If unclosed comment, move to end
248
+ if (pos + 1 >= len) {
249
+ pos = len;
250
+ }
251
+ continue;
252
+ }
253
+ // Skip string literal (to avoid matching { or [ inside strings)
254
+ if (ch === '"') {
255
+ pos++;
256
+ while (pos < len) {
257
+ if (input[pos] === "\\") {
258
+ pos += 2; // skip escape sequence
259
+ continue;
260
+ }
261
+ if (input[pos] === '"') {
262
+ pos++;
263
+ break;
264
+ }
265
+ pos++;
266
+ }
267
+ continue;
268
+ }
269
+ pos++;
270
+ }
271
+ return -1;
272
+ }
273
+ /**
274
+ * Skip leading comments and whitespace from input.
275
+ *
276
+ * @param input Text that may start with comments or whitespace
277
+ * @returns Input with leading comments and whitespace removed
278
+ * @internal
279
+ */
280
+ function skipCommentsAndWhitespace(input) {
281
+ let pos = 0;
282
+ const len = input.length;
283
+ while (pos < len) {
284
+ const ch = input[pos];
285
+ // Skip whitespace
286
+ if (ch === " " || ch === "\t" || ch === "\n" || ch === "\r") {
287
+ pos++;
288
+ continue;
289
+ }
290
+ // Skip single-line comment
291
+ if (ch === "/" && pos + 1 < len && input[pos + 1] === "/") {
292
+ pos += 2;
293
+ while (pos < len && input[pos] !== "\n" && input[pos] !== "\r") {
294
+ pos++;
295
+ }
296
+ continue;
297
+ }
298
+ // Skip multi-line comment
299
+ if (ch === "/" && pos + 1 < len && input[pos + 1] === "*") {
300
+ pos += 2;
301
+ while (pos + 1 < len) {
302
+ if (input[pos] === "*" && input[pos + 1] === "/") {
303
+ pos += 2;
304
+ break;
305
+ }
306
+ pos++;
307
+ }
308
+ if (pos + 1 >= len) {
309
+ pos = len;
310
+ }
311
+ continue;
312
+ }
313
+ // Not whitespace or comment
314
+ break;
315
+ }
316
+ return input.slice(pos);
317
+ }
318
+ /**
319
+ * Check if input starts with a valid JSON primitive token.
320
+ *
321
+ * @param input Trimmed input string
322
+ * @returns True if input starts with a primitive value
323
+ * @internal
324
+ */
325
+ function startsWithPrimitive(input) {
326
+ if (input.length === 0)
327
+ return false;
328
+ const ch = input[0];
329
+ // String
330
+ if (ch === '"')
331
+ return true;
332
+ // Number (digit or minus)
333
+ if ((ch >= "0" && ch <= "9") || ch === "-")
334
+ return true;
335
+ // Keywords
336
+ if (input.startsWith("true") ||
337
+ input.startsWith("false") ||
338
+ input.startsWith("null"))
339
+ return true;
340
+ // Partial keywords (note: "null" requires at least 2 chars to match parseKeywordOrIdentifier logic)
341
+ if ("true".startsWith(input) ||
342
+ "false".startsWith(input) ||
343
+ ("null".startsWith(input) && input.length >= 2))
344
+ return true;
345
+ // Boolean string variants (note: "n" is intentionally excluded)
346
+ const lower = input.toLowerCase();
347
+ if (lower === "yes" ||
348
+ lower === "y" ||
349
+ lower === "on" ||
350
+ lower === "no" ||
351
+ lower === "off")
352
+ return true;
353
+ return false;
354
+ }
355
+ /**
356
+ * Lenient JSON parser that handles incomplete JSON.
357
+ *
358
+ * @internal
359
+ */
360
+ class LenientJsonParser {
361
+ constructor(input, errors) {
362
+ this.pos = 0;
363
+ this.depth = 0;
364
+ this.input = input;
365
+ this.errors = errors;
366
+ }
367
+ parse() {
368
+ this.skipWhitespace();
369
+ if (this.pos >= this.input.length) {
370
+ return undefined;
371
+ }
372
+ return this.parseValue("$input");
373
+ }
374
+ parseValue(path) {
375
+ this.skipWhitespace();
376
+ if (this.pos >= this.input.length) {
377
+ return undefined;
378
+ }
379
+ // Check for maximum depth to prevent stack overflow
380
+ if (this.depth >= MAX_DEPTH) {
381
+ this.errors.push({
382
+ path,
383
+ expected: "value (max depth exceeded)",
384
+ description: undefined,
385
+ });
386
+ return undefined;
387
+ }
388
+ const char = this.input[this.pos];
389
+ if (char === "{")
390
+ return this.parseObject(path);
391
+ if (char === "[")
392
+ return this.parseArray(path);
393
+ if (char === '"')
394
+ return this.parseString();
395
+ if (char === "-" || (char >= "0" && char <= "9"))
396
+ return this.parseNumber();
397
+ // Handle keywords (true, false, null) or invalid identifiers
398
+ if (this.isIdentifierStart(char)) {
399
+ return this.parseKeywordOrIdentifier(path);
400
+ }
401
+ // Don't skip structural characters - let the caller handle them
402
+ const ch = this.input[this.pos];
403
+ if (ch === "}" || ch === "]" || ch === ",") {
404
+ // Not an error - just no value here (e.g., {"a":} or [,])
405
+ return undefined;
406
+ }
407
+ this.errors.push({
408
+ path,
409
+ expected: "JSON value",
410
+ description: this.getErrorContext(),
411
+ });
412
+ // Skip the problematic character and try to continue
413
+ this.pos++;
414
+ return undefined;
415
+ }
416
+ getErrorContext() {
417
+ // Get surrounding context for better error messages
418
+ const start = Math.max(0, this.pos - 10);
419
+ const end = Math.min(this.input.length, this.pos + 20);
420
+ const before = this.input.slice(start, this.pos);
421
+ const after = this.input.slice(this.pos, end);
422
+ return ((start > 0 ? "..." : "") +
423
+ before +
424
+ "→" +
425
+ after +
426
+ (end < this.input.length ? "..." : ""));
427
+ }
428
+ parseKeywordOrIdentifier(path) {
429
+ // Extract the token (sequence of identifier characters)
430
+ const start = this.pos;
431
+ while (this.pos < this.input.length &&
432
+ this.isIdentifierChar(this.input[this.pos])) {
433
+ this.pos++;
434
+ }
435
+ const token = this.input.slice(start, this.pos);
436
+ // Check for complete or partial keyword matches
437
+ if (token === "true")
438
+ return true;
439
+ if (token === "false")
440
+ return false;
441
+ if (token === "null")
442
+ return null;
443
+ // Boolean string coercion: "yes", "y", "on" -> true, "no", "off" -> false
444
+ // Note: "n" is intentionally NOT handled (neither null nor false)
445
+ const lower = token.toLowerCase();
446
+ if (lower === "yes" || lower === "y" || lower === "on")
447
+ return true;
448
+ if (lower === "no" || lower === "off")
449
+ return false;
450
+ // Partial match for lenient parsing (e.g., "tru" -> true, "fal" -> false)
451
+ if ("true".startsWith(token) && token.length > 0)
452
+ return true;
453
+ if ("false".startsWith(token) && token.length > 0)
454
+ return false;
455
+ if ("null".startsWith(token) && token.length >= 2)
456
+ return null;
457
+ // Check if this looks like a string with missing opening quote (e.g., abcdefg")
458
+ if (this.pos < this.input.length && this.input[this.pos] === '"') {
459
+ // Treat as unquoted string value - skip the errant closing quote and return as string
460
+ this.pos++; // skip the closing quote
461
+ this.errors.push({
462
+ path,
463
+ expected: "quoted string",
464
+ description: "missing opening quote for '" + token + "'",
465
+ });
466
+ return token;
467
+ }
468
+ // Invalid identifier as value - provide helpful error message
469
+ this.errors.push({
470
+ path,
471
+ expected: "JSON value (string, number, boolean, null, object, or array)",
472
+ description: "unquoted string '" + token + "' - did you forget quotes?",
473
+ });
474
+ // Skip to next comma, closing brace/bracket for recovery
475
+ this.skipToRecoveryPoint();
476
+ return undefined;
477
+ }
478
+ skipToRecoveryPoint() {
479
+ while (this.pos < this.input.length) {
480
+ const ch = this.input[this.pos];
481
+ if (ch === "," || ch === "}" || ch === "]") {
482
+ return;
483
+ }
484
+ this.pos++;
485
+ }
486
+ }
487
+ parseObject(path) {
488
+ const result = {};
489
+ this.pos++; // skip '{'
490
+ this.depth++;
491
+ this.skipWhitespace();
492
+ while (this.pos < this.input.length) {
493
+ this.skipWhitespace();
494
+ // Handle end of object or end of input
495
+ if (this.pos >= this.input.length || this.input[this.pos] === "}") {
496
+ if (this.pos < this.input.length)
497
+ this.pos++; // skip '}'
498
+ this.depth--;
499
+ return result;
500
+ }
501
+ // Skip trailing comma
502
+ if (this.input[this.pos] === ",") {
503
+ this.pos++;
504
+ this.skipWhitespace();
505
+ continue;
506
+ }
507
+ // Parse key (quoted string or unquoted identifier)
508
+ let key;
509
+ if (this.input[this.pos] === '"') {
510
+ key = this.parseString();
511
+ }
512
+ else if (this.isIdentifierStart(this.input[this.pos])) {
513
+ key = this.parseIdentifier();
514
+ }
515
+ else {
516
+ this.errors.push({
517
+ path,
518
+ expected: "string key",
519
+ description: this.input[this.pos],
520
+ });
521
+ // Try to recover by skipping to next meaningful character
522
+ this.depth--;
523
+ return result;
524
+ }
525
+ if (typeof key !== "string") {
526
+ this.depth--;
527
+ return result;
528
+ }
529
+ this.skipWhitespace();
530
+ // Expect colon - but if we're at end of input, it's just incomplete (not an error)
531
+ if (this.pos >= this.input.length) {
532
+ this.depth--;
533
+ return result;
534
+ }
535
+ if (this.input[this.pos] !== ":") {
536
+ this.errors.push({
537
+ path: path + "." + key,
538
+ expected: "':'",
539
+ description: this.input[this.pos],
540
+ });
541
+ this.depth--;
542
+ return result;
543
+ }
544
+ this.pos++; // skip ':'
545
+ this.skipWhitespace();
546
+ // Parse value
547
+ if (this.pos >= this.input.length) {
548
+ // No value - incomplete but not an error for lenient parsing
549
+ this.depth--;
550
+ return result;
551
+ }
552
+ const value = this.parseValue(path + "." + key);
553
+ result[key] = value;
554
+ this.skipWhitespace();
555
+ // Handle comma or end
556
+ if (this.pos < this.input.length && this.input[this.pos] === ",") {
557
+ this.pos++;
558
+ }
559
+ }
560
+ this.depth--;
561
+ return result;
562
+ }
563
+ parseArray(path) {
564
+ const result = [];
565
+ this.pos++; // skip '['
566
+ this.depth++;
567
+ this.skipWhitespace();
568
+ let index = 0;
569
+ while (this.pos < this.input.length) {
570
+ this.skipWhitespace();
571
+ // Handle end of array or end of input
572
+ if (this.pos >= this.input.length || this.input[this.pos] === "]") {
573
+ if (this.pos < this.input.length)
574
+ this.pos++; // skip ']'
575
+ this.depth--;
576
+ return result;
577
+ }
578
+ // Skip trailing comma
579
+ if (this.input[this.pos] === ",") {
580
+ this.pos++;
581
+ this.skipWhitespace();
582
+ continue;
583
+ }
584
+ // Parse value
585
+ const prevPos = this.pos;
586
+ const value = this.parseValue(path + "[" + index + "]");
587
+ // Guard: if parseValue didn't advance, skip unexpected char to prevent infinite loop
588
+ if (this.pos === prevPos && this.pos < this.input.length) {
589
+ this.pos++;
590
+ continue;
591
+ }
592
+ result.push(value);
593
+ index++;
594
+ this.skipWhitespace();
595
+ // Handle comma or end
596
+ if (this.pos < this.input.length && this.input[this.pos] === ",") {
597
+ this.pos++;
598
+ }
599
+ }
600
+ this.depth--;
601
+ return result;
602
+ }
603
+ parseString() {
604
+ this.pos++; // skip opening '"'
605
+ let result = "";
606
+ let escaped = false;
607
+ while (this.pos < this.input.length) {
608
+ const char = this.input[this.pos];
609
+ if (escaped) {
610
+ switch (char) {
611
+ case '"':
612
+ result += '"';
613
+ break;
614
+ case "\\":
615
+ result += "\\";
616
+ break;
617
+ case "/":
618
+ result += "/";
619
+ break;
620
+ case "b":
621
+ result += "\b";
622
+ break;
623
+ case "f":
624
+ result += "\f";
625
+ break;
626
+ case "n":
627
+ result += "\n";
628
+ break;
629
+ case "r":
630
+ result += "\r";
631
+ break;
632
+ case "t":
633
+ result += "\t";
634
+ break;
635
+ case "u":
636
+ // Parse unicode escape
637
+ if (this.pos + 4 <= this.input.length) {
638
+ const hex = this.input.slice(this.pos + 1, this.pos + 5);
639
+ if (isHexString(hex)) {
640
+ const highCode = parseInt(hex, 16);
641
+ this.pos += 4;
642
+ // Check for surrogate pair (emoji and characters > U+FFFF)
643
+ if (highCode >= 0xd800 &&
644
+ highCode <= 0xdbff &&
645
+ this.pos + 6 <= this.input.length &&
646
+ this.input[this.pos + 1] === "\\" &&
647
+ this.input[this.pos + 2] === "u") {
648
+ const lowHex = this.input.slice(this.pos + 3, this.pos + 7);
649
+ if (isHexString(lowHex)) {
650
+ const lowCode = parseInt(lowHex, 16);
651
+ if (lowCode >= 0xdc00 && lowCode <= 0xdfff) {
652
+ result += String.fromCharCode(highCode, lowCode);
653
+ this.pos += 6;
654
+ break;
655
+ }
656
+ }
657
+ }
658
+ result += String.fromCharCode(highCode);
659
+ }
660
+ else {
661
+ // Invalid hex - preserve escape sequence literally
662
+ result += "\\u" + hex;
663
+ this.pos += 4;
664
+ }
665
+ }
666
+ else {
667
+ // Incomplete unicode escape - add partial sequence
668
+ const partial = this.input.slice(this.pos + 1);
669
+ result += "\\u" + partial;
670
+ this.pos = this.input.length - 1;
671
+ }
672
+ break;
673
+ default:
674
+ result += char;
675
+ }
676
+ escaped = false;
677
+ this.pos++;
678
+ continue;
679
+ }
680
+ if (char === "\\") {
681
+ escaped = true;
682
+ this.pos++;
683
+ continue;
684
+ }
685
+ if (char === '"') {
686
+ this.pos++; // skip closing '"'
687
+ return result;
688
+ }
689
+ result += char;
690
+ this.pos++;
691
+ }
692
+ // Unclosed string - return what we have (lenient)
693
+ return result;
694
+ }
695
+ parseNumber() {
696
+ const start = this.pos;
697
+ // Handle negative sign
698
+ if (this.input[this.pos] === "-") {
699
+ this.pos++;
700
+ }
701
+ // Parse integer part
702
+ while (this.pos < this.input.length &&
703
+ this.input[this.pos] >= "0" &&
704
+ this.input[this.pos] <= "9") {
705
+ this.pos++;
706
+ }
707
+ // Parse decimal part
708
+ if (this.pos < this.input.length && this.input[this.pos] === ".") {
709
+ this.pos++;
710
+ while (this.pos < this.input.length &&
711
+ this.input[this.pos] >= "0" &&
712
+ this.input[this.pos] <= "9") {
713
+ this.pos++;
714
+ }
715
+ }
716
+ // Parse exponent
717
+ if (this.pos < this.input.length &&
718
+ (this.input[this.pos] === "e" || this.input[this.pos] === "E")) {
719
+ this.pos++;
720
+ if (this.pos < this.input.length &&
721
+ (this.input[this.pos] === "+" || this.input[this.pos] === "-")) {
722
+ this.pos++;
723
+ }
724
+ while (this.pos < this.input.length &&
725
+ this.input[this.pos] >= "0" &&
726
+ this.input[this.pos] <= "9") {
727
+ this.pos++;
728
+ }
729
+ }
730
+ const numStr = this.input.slice(start, this.pos);
731
+ const num = Number(numStr);
732
+ return Number.isNaN(num) ? 0 : num;
733
+ }
734
+ isIdentifierStart(ch) {
735
+ return ((ch >= "a" && ch <= "z") ||
736
+ (ch >= "A" && ch <= "Z") ||
737
+ ch === "_" ||
738
+ ch === "$");
739
+ }
740
+ isIdentifierChar(ch) {
741
+ return ((ch >= "a" && ch <= "z") ||
742
+ (ch >= "A" && ch <= "Z") ||
743
+ (ch >= "0" && ch <= "9") ||
744
+ ch === "_" ||
745
+ ch === "$");
746
+ }
747
+ parseIdentifier() {
748
+ const start = this.pos;
749
+ while (this.pos < this.input.length &&
750
+ this.isIdentifierChar(this.input[this.pos])) {
751
+ this.pos++;
752
+ }
753
+ return this.input.slice(start, this.pos);
754
+ }
755
+ skipWhitespace() {
756
+ while (this.pos < this.input.length) {
757
+ const ch = this.input[this.pos];
758
+ // Skip standard whitespace
759
+ if (ch === " " || ch === "\t" || ch === "\n" || ch === "\r") {
760
+ this.pos++;
761
+ continue;
762
+ }
763
+ // Skip single-line comment: // ...
764
+ if (ch === "/" &&
765
+ this.pos + 1 < this.input.length &&
766
+ this.input[this.pos + 1] === "/") {
767
+ this.pos += 2;
768
+ while (this.pos < this.input.length &&
769
+ this.input[this.pos] !== "\n" &&
770
+ this.input[this.pos] !== "\r") {
771
+ this.pos++;
772
+ }
773
+ continue;
774
+ }
775
+ // Skip multi-line comment: /* ... */
776
+ if (ch === "/" &&
777
+ this.pos + 1 < this.input.length &&
778
+ this.input[this.pos + 1] === "*") {
779
+ this.pos += 2;
780
+ while (this.pos + 1 < this.input.length) {
781
+ if (this.input[this.pos] === "*" &&
782
+ this.input[this.pos + 1] === "/") {
783
+ this.pos += 2;
784
+ break;
785
+ }
786
+ this.pos++;
787
+ }
788
+ // Handle unclosed comment - move to end
789
+ if (this.pos + 1 >= this.input.length) {
790
+ this.pos = this.input.length;
791
+ }
792
+ continue;
793
+ }
794
+ // Not whitespace or comment
795
+ break;
796
+ }
797
+ }
812
798
  }
799
+ /**
800
+ * Maximum nesting depth to prevent stack overflow attacks.
801
+ *
802
+ * @internal
803
+ */
804
+ const MAX_DEPTH = 512;
813
805
 
814
- export { requireParseLenientJson as __require };
806
+ export { parseLenientJson$1 as default, parseLenientJson_2 as parseLenientJson };
815
807
  //# sourceMappingURL=parseLenientJson2.mjs.map