@ls-stack/utils 3.63.0 → 3.66.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 (328) hide show
  1. package/dist/{arrayUtils.d.cts → arrayUtils.d.mts} +24 -23
  2. package/dist/arrayUtils.mjs +249 -0
  3. package/dist/assertions-qMxfVhSu.mjs +207 -0
  4. package/dist/{assertions.d.ts → assertions.d.mts} +4 -3
  5. package/dist/assertions.mjs +3 -0
  6. package/dist/asyncQueue.d.mts +497 -0
  7. package/dist/asyncQueue.mjs +757 -0
  8. package/dist/{awaitDebounce.d.cts → awaitDebounce.d.mts} +11 -6
  9. package/dist/awaitDebounce.mjs +54 -0
  10. package/dist/{cache.d.ts → cache.d.mts} +76 -68
  11. package/dist/cache.mjs +355 -0
  12. package/dist/castValues-DfICShCc.mjs +19 -0
  13. package/dist/{castValues.d.cts → castValues.d.mts} +3 -2
  14. package/dist/castValues.mjs +3 -0
  15. package/dist/{concurrentCalls.d.ts → concurrentCalls.d.mts} +74 -65
  16. package/dist/concurrentCalls.mjs +295 -0
  17. package/dist/consoleFmt.d.mts +55 -0
  18. package/dist/consoleFmt.mjs +63 -0
  19. package/dist/conversions-DTmwEMIu.mjs +12 -0
  20. package/dist/conversions.d.mts +4 -0
  21. package/dist/conversions.mjs +3 -0
  22. package/dist/createThrottleController.d.mts +18 -0
  23. package/dist/createThrottleController.mjs +40 -0
  24. package/dist/debounce.d.mts +47 -0
  25. package/dist/debounce.mjs +117 -0
  26. package/dist/dedent.d.mts +74 -0
  27. package/dist/dedent.mjs +80 -0
  28. package/dist/deepEqual-C7EZEixx.mjs +78 -0
  29. package/dist/{deepEqual.d.cts → deepEqual.d.mts} +3 -2
  30. package/dist/deepEqual.mjs +3 -0
  31. package/dist/{deepReplaceValues.d.cts → deepReplaceValues.d.mts} +4 -3
  32. package/dist/deepReplaceValues.mjs +61 -0
  33. package/dist/diffParser.d.mts +63 -0
  34. package/dist/diffParser.mjs +410 -0
  35. package/dist/enhancedMap.d.mts +21 -0
  36. package/dist/enhancedMap.mjs +69 -0
  37. package/dist/exhaustiveMatch.d.mts +10 -0
  38. package/dist/exhaustiveMatch.mjs +48 -0
  39. package/dist/{filterObjectOrArrayKeys.d.cts → filterObjectOrArrayKeys.d.mts} +15 -8
  40. package/dist/filterObjectOrArrayKeys.mjs +497 -0
  41. package/dist/{getAutoIncrementId.d.cts → getAutoIncrementId.d.mts} +9 -5
  42. package/dist/getAutoIncrementId.mjs +53 -0
  43. package/dist/{getCompositeKey.d.cts → getCompositeKey.d.mts} +3 -2
  44. package/dist/getCompositeKey.mjs +50 -0
  45. package/dist/{getValueStableKey.d.cts → getValueStableKey.d.mts} +5 -3
  46. package/dist/getValueStableKey.mjs +17 -0
  47. package/dist/{hash.d.cts → hash.d.mts} +3 -2
  48. package/dist/hash.mjs +28 -0
  49. package/dist/interpolate.d.mts +17 -0
  50. package/dist/interpolate.mjs +28 -0
  51. package/dist/{iteratorUtils.d.cts → iteratorUtils.d.mts} +5 -4
  52. package/dist/iteratorUtils.mjs +39 -0
  53. package/dist/keepPrevIfUnchanged.d.mts +12 -0
  54. package/dist/keepPrevIfUnchanged.mjs +9 -0
  55. package/dist/keyedMap.d.mts +76 -0
  56. package/dist/keyedMap.mjs +139 -0
  57. package/dist/keyedSet.d.mts +77 -0
  58. package/dist/keyedSet.mjs +129 -0
  59. package/dist/{levenshtein.d.cts → levenshtein.d.mts} +3 -2
  60. package/dist/levenshtein.mjs +121 -0
  61. package/dist/main.d.mts +4 -0
  62. package/dist/main.mjs +7 -0
  63. package/dist/matchPath.d.mts +50 -0
  64. package/dist/matchPath.mjs +81 -0
  65. package/dist/mathUtils-BDP1lM_z.mjs +81 -0
  66. package/dist/{mathUtils.d.cts → mathUtils.d.mts} +3 -2
  67. package/dist/mathUtils.mjs +3 -0
  68. package/dist/{mutationUtils.d.cts → mutationUtils.d.mts} +6 -5
  69. package/dist/mutationUtils.mjs +44 -0
  70. package/dist/{objUtils.d.ts → objUtils.d.mts} +8 -6
  71. package/dist/objUtils.mjs +115 -0
  72. package/dist/parallelAsyncCalls.d.mts +83 -0
  73. package/dist/parallelAsyncCalls.mjs +121 -0
  74. package/dist/partialEqual.d.mts +139 -0
  75. package/dist/partialEqual.mjs +1055 -0
  76. package/dist/promiseUtils.d.mts +9 -0
  77. package/dist/promiseUtils.mjs +17 -0
  78. package/dist/regexUtils.d.mts +18 -0
  79. package/dist/regexUtils.mjs +34 -0
  80. package/dist/{retryOnError.d.cts → retryOnError.d.mts} +38 -37
  81. package/dist/retryOnError.mjs +91 -0
  82. package/dist/{runShellCmd.d.ts → runShellCmd.d.mts} +24 -15
  83. package/dist/runShellCmd.mjs +151 -0
  84. package/dist/{safeJson.d.cts → safeJson.d.mts} +3 -2
  85. package/dist/safeJson.mjs +30 -0
  86. package/dist/{saferTyping.d.cts → saferTyping.d.mts} +4 -3
  87. package/dist/saferTyping.mjs +45 -0
  88. package/dist/serializeXML.d.mts +23 -0
  89. package/dist/serializeXML.mjs +74 -0
  90. package/dist/{shallowEqual.d.cts → shallowEqual.d.mts} +3 -2
  91. package/dist/shallowEqual.mjs +54 -0
  92. package/dist/sleep.d.mts +4 -0
  93. package/dist/sleep.mjs +7 -0
  94. package/dist/stringUtils-DjhWOiYn.mjs +113 -0
  95. package/dist/{stringUtils.d.cts → stringUtils.d.mts} +3 -2
  96. package/dist/stringUtils.mjs +3 -0
  97. package/dist/{testUtils.d.ts → testUtils.d.mts} +83 -52
  98. package/dist/testUtils.mjs +310 -0
  99. package/dist/{throttle.d.ts → throttle.d.mts} +18 -17
  100. package/dist/throttle.mjs +102 -0
  101. package/dist/time-sr2lhQRw.mjs +67 -0
  102. package/dist/{time.d.ts → time.d.mts} +8 -7
  103. package/dist/time.mjs +3 -0
  104. package/dist/{timers.d.cts → timers.d.mts} +22 -13
  105. package/dist/timers.mjs +220 -0
  106. package/dist/{tsResult.d.cts → tsResult.d.mts} +52 -48
  107. package/dist/tsResult.mjs +142 -0
  108. package/dist/typeGuards-B1mzA-Rz.mjs +128 -0
  109. package/dist/{typeGuards.d.cts → typeGuards.d.mts} +3 -2
  110. package/dist/typeGuards.mjs +3 -0
  111. package/dist/{typeUtils.d.ts → typeUtils.d.mts} +13 -34
  112. package/dist/typeUtils.mjs +1 -0
  113. package/dist/{typedStrings.d.cts → typedStrings.d.mts} +5 -4
  114. package/dist/typedStrings.mjs +131 -0
  115. package/dist/typingFnUtils-Bb8drgKF.mjs +101 -0
  116. package/dist/{typingFnUtils.d.cts → typingFnUtils.d.mts} +13 -22
  117. package/dist/typingFnUtils.mjs +3 -0
  118. package/dist/{typingTestUtils.d.cts → typingTestUtils.d.mts} +11 -15
  119. package/dist/typingTestUtils.mjs +80 -0
  120. package/dist/typingUtils.d.mts +20 -0
  121. package/dist/typingUtils.mjs +1 -0
  122. package/dist/yamlStringify.d.mts +17 -0
  123. package/dist/yamlStringify.mjs +189 -0
  124. package/package.json +65 -234
  125. package/dist/arrayUtils.cjs +0 -229
  126. package/dist/arrayUtils.d.ts +0 -171
  127. package/dist/arrayUtils.js +0 -42
  128. package/dist/assertions.cjs +0 -107
  129. package/dist/assertions.d.cts +0 -192
  130. package/dist/assertions.js +0 -25
  131. package/dist/asyncQueue.cjs +0 -672
  132. package/dist/asyncQueue.d.cts +0 -488
  133. package/dist/asyncQueue.d.ts +0 -488
  134. package/dist/asyncQueue.js +0 -631
  135. package/dist/awaitDebounce.cjs +0 -106
  136. package/dist/awaitDebounce.d.ts +0 -41
  137. package/dist/awaitDebounce.js +0 -28
  138. package/dist/cache.cjs +0 -367
  139. package/dist/cache.d.cts +0 -228
  140. package/dist/cache.js +0 -19
  141. package/dist/castValues.cjs +0 -50
  142. package/dist/castValues.d.ts +0 -4
  143. package/dist/castValues.js +0 -8
  144. package/dist/chunk-5DZT3Z5Z.js +0 -8
  145. package/dist/chunk-6FBIEPWU.js +0 -96
  146. package/dist/chunk-6FIBVC2P.js +0 -56
  147. package/dist/chunk-7CQPOM5I.js +0 -100
  148. package/dist/chunk-B6DNOZCP.js +0 -369
  149. package/dist/chunk-BM4PYVOX.js +0 -109
  150. package/dist/chunk-C2SVCIWE.js +0 -57
  151. package/dist/chunk-CCUPDGSZ.js +0 -132
  152. package/dist/chunk-DBOWTYR4.js +0 -49
  153. package/dist/chunk-DFXNVEH6.js +0 -14
  154. package/dist/chunk-DX2524CZ.js +0 -314
  155. package/dist/chunk-GMJTLFM6.js +0 -60
  156. package/dist/chunk-IATIXMCE.js +0 -20
  157. package/dist/chunk-II4R3VVX.js +0 -25
  158. package/dist/chunk-JF2MDHOJ.js +0 -40
  159. package/dist/chunk-JQFUKJU5.js +0 -71
  160. package/dist/chunk-MI4UE2PQ.js +0 -561
  161. package/dist/chunk-PUKVXYYL.js +0 -52
  162. package/dist/chunk-QQS7I7ZL.js +0 -16
  163. package/dist/chunk-VAAMRG4K.js +0 -20
  164. package/dist/chunk-WFQJUJTC.js +0 -182
  165. package/dist/chunk-ZXIKIA5B.js +0 -178
  166. package/dist/concurrentCalls.cjs +0 -406
  167. package/dist/concurrentCalls.d.cts +0 -116
  168. package/dist/concurrentCalls.js +0 -346
  169. package/dist/consoleFmt.cjs +0 -85
  170. package/dist/consoleFmt.d.cts +0 -54
  171. package/dist/consoleFmt.d.ts +0 -54
  172. package/dist/consoleFmt.js +0 -60
  173. package/dist/conversions.cjs +0 -44
  174. package/dist/conversions.d.cts +0 -3
  175. package/dist/conversions.d.ts +0 -3
  176. package/dist/conversions.js +0 -6
  177. package/dist/createThrottleController.cjs +0 -193
  178. package/dist/createThrottleController.d.cts +0 -13
  179. package/dist/createThrottleController.d.ts +0 -13
  180. package/dist/createThrottleController.js +0 -61
  181. package/dist/debounce.cjs +0 -157
  182. package/dist/debounce.d.cts +0 -46
  183. package/dist/debounce.d.ts +0 -46
  184. package/dist/debounce.js +0 -8
  185. package/dist/dedent.cjs +0 -104
  186. package/dist/dedent.d.cts +0 -73
  187. package/dist/dedent.d.ts +0 -73
  188. package/dist/dedent.js +0 -79
  189. package/dist/deepEqual.cjs +0 -96
  190. package/dist/deepEqual.d.ts +0 -21
  191. package/dist/deepEqual.js +0 -8
  192. package/dist/deepReplaceValues.cjs +0 -87
  193. package/dist/deepReplaceValues.d.ts +0 -27
  194. package/dist/deepReplaceValues.js +0 -7
  195. package/dist/enhancedMap.cjs +0 -131
  196. package/dist/enhancedMap.d.cts +0 -20
  197. package/dist/enhancedMap.d.ts +0 -20
  198. package/dist/enhancedMap.js +0 -10
  199. package/dist/exhaustiveMatch.cjs +0 -66
  200. package/dist/exhaustiveMatch.d.cts +0 -9
  201. package/dist/exhaustiveMatch.d.ts +0 -9
  202. package/dist/exhaustiveMatch.js +0 -40
  203. package/dist/filterObjectOrArrayKeys.cjs +0 -619
  204. package/dist/filterObjectOrArrayKeys.d.ts +0 -88
  205. package/dist/filterObjectOrArrayKeys.js +0 -9
  206. package/dist/getAutoIncrementId.cjs +0 -44
  207. package/dist/getAutoIncrementId.d.ts +0 -46
  208. package/dist/getAutoIncrementId.js +0 -18
  209. package/dist/getCompositeKey.cjs +0 -86
  210. package/dist/getCompositeKey.d.ts +0 -11
  211. package/dist/getCompositeKey.js +0 -8
  212. package/dist/getValueStableKey.cjs +0 -89
  213. package/dist/getValueStableKey.d.ts +0 -15
  214. package/dist/getValueStableKey.js +0 -11
  215. package/dist/hash.cjs +0 -57
  216. package/dist/hash.d.ts +0 -7
  217. package/dist/hash.js +0 -32
  218. package/dist/interpolate.cjs +0 -88
  219. package/dist/interpolate.d.cts +0 -11
  220. package/dist/interpolate.d.ts +0 -11
  221. package/dist/interpolate.js +0 -46
  222. package/dist/iteratorUtils.cjs +0 -73
  223. package/dist/iteratorUtils.d.ts +0 -10
  224. package/dist/iteratorUtils.js +0 -44
  225. package/dist/keepPrevIfUnchanged.cjs +0 -102
  226. package/dist/keepPrevIfUnchanged.d.cts +0 -7
  227. package/dist/keepPrevIfUnchanged.d.ts +0 -7
  228. package/dist/keepPrevIfUnchanged.js +0 -7
  229. package/dist/levenshtein.cjs +0 -180
  230. package/dist/levenshtein.d.ts +0 -5
  231. package/dist/levenshtein.js +0 -153
  232. package/dist/main.cjs +0 -32
  233. package/dist/main.d.cts +0 -3
  234. package/dist/main.d.ts +0 -3
  235. package/dist/main.js +0 -7
  236. package/dist/matchPath.cjs +0 -155
  237. package/dist/matchPath.d.cts +0 -53
  238. package/dist/matchPath.d.ts +0 -53
  239. package/dist/matchPath.js +0 -108
  240. package/dist/mathUtils.cjs +0 -81
  241. package/dist/mathUtils.d.ts +0 -54
  242. package/dist/mathUtils.js +0 -22
  243. package/dist/mutationUtils.cjs +0 -153
  244. package/dist/mutationUtils.d.ts +0 -15
  245. package/dist/mutationUtils.js +0 -55
  246. package/dist/objUtils.cjs +0 -242
  247. package/dist/objUtils.d.cts +0 -28
  248. package/dist/objUtils.js +0 -38
  249. package/dist/parallelAsyncCalls.cjs +0 -162
  250. package/dist/parallelAsyncCalls.d.cts +0 -82
  251. package/dist/parallelAsyncCalls.d.ts +0 -82
  252. package/dist/parallelAsyncCalls.js +0 -126
  253. package/dist/partialEqual.cjs +0 -1196
  254. package/dist/partialEqual.d.cts +0 -141
  255. package/dist/partialEqual.d.ts +0 -141
  256. package/dist/partialEqual.js +0 -1168
  257. package/dist/promiseUtils.cjs +0 -38
  258. package/dist/promiseUtils.d.cts +0 -8
  259. package/dist/promiseUtils.d.ts +0 -8
  260. package/dist/promiseUtils.js +0 -6
  261. package/dist/regexUtils.cjs +0 -60
  262. package/dist/regexUtils.d.cts +0 -17
  263. package/dist/regexUtils.d.ts +0 -17
  264. package/dist/regexUtils.js +0 -33
  265. package/dist/retryOnError.cjs +0 -130
  266. package/dist/retryOnError.d.ts +0 -83
  267. package/dist/retryOnError.js +0 -101
  268. package/dist/runShellCmd.cjs +0 -127
  269. package/dist/runShellCmd.d.cts +0 -90
  270. package/dist/runShellCmd.js +0 -98
  271. package/dist/safeJson.cjs +0 -45
  272. package/dist/safeJson.d.ts +0 -16
  273. package/dist/safeJson.js +0 -8
  274. package/dist/saferTyping.cjs +0 -52
  275. package/dist/saferTyping.d.ts +0 -47
  276. package/dist/saferTyping.js +0 -23
  277. package/dist/serializeXML.cjs +0 -154
  278. package/dist/serializeXML.d.cts +0 -22
  279. package/dist/serializeXML.d.ts +0 -22
  280. package/dist/serializeXML.js +0 -116
  281. package/dist/shallowEqual.cjs +0 -88
  282. package/dist/shallowEqual.d.ts +0 -4
  283. package/dist/shallowEqual.js +0 -63
  284. package/dist/sleep.cjs +0 -32
  285. package/dist/sleep.d.cts +0 -3
  286. package/dist/sleep.d.ts +0 -3
  287. package/dist/sleep.js +0 -6
  288. package/dist/stringUtils.cjs +0 -155
  289. package/dist/stringUtils.d.ts +0 -55
  290. package/dist/stringUtils.js +0 -50
  291. package/dist/testUtils.cjs +0 -1490
  292. package/dist/testUtils.d.cts +0 -133
  293. package/dist/testUtils.js +0 -359
  294. package/dist/throttle.cjs +0 -282
  295. package/dist/throttle.d.cts +0 -98
  296. package/dist/throttle.js +0 -38
  297. package/dist/time.cjs +0 -152
  298. package/dist/time.d.cts +0 -25
  299. package/dist/time.js +0 -38
  300. package/dist/timers.cjs +0 -194
  301. package/dist/timers.d.ts +0 -121
  302. package/dist/timers.js +0 -156
  303. package/dist/tsResult.cjs +0 -226
  304. package/dist/tsResult.d.ts +0 -114
  305. package/dist/tsResult.js +0 -180
  306. package/dist/typeGuards.cjs +0 -70
  307. package/dist/typeGuards.d.ts +0 -111
  308. package/dist/typeGuards.js +0 -18
  309. package/dist/typeUtils.cjs +0 -18
  310. package/dist/typeUtils.d.cts +0 -61
  311. package/dist/typeUtils.js +0 -0
  312. package/dist/typedStrings.cjs +0 -90
  313. package/dist/typedStrings.d.ts +0 -163
  314. package/dist/typedStrings.js +0 -57
  315. package/dist/typingFnUtils.cjs +0 -96
  316. package/dist/typingFnUtils.d.ts +0 -100
  317. package/dist/typingFnUtils.js +0 -30
  318. package/dist/typingTestUtils.cjs +0 -52
  319. package/dist/typingTestUtils.d.ts +0 -79
  320. package/dist/typingTestUtils.js +0 -27
  321. package/dist/typingUtils.cjs +0 -18
  322. package/dist/typingUtils.d.cts +0 -35
  323. package/dist/typingUtils.d.ts +0 -35
  324. package/dist/typingUtils.js +0 -0
  325. package/dist/yamlStringify.cjs +0 -423
  326. package/dist/yamlStringify.d.cts +0 -10
  327. package/dist/yamlStringify.d.ts +0 -10
  328. package/dist/yamlStringify.js +0 -9
@@ -1,1168 +0,0 @@
1
- import {
2
- exhaustiveCheck
3
- } from "./chunk-C2SVCIWE.js";
4
- import "./chunk-JF2MDHOJ.js";
5
-
6
- // src/partialEqual.ts
7
- import { err, ok } from "t-result";
8
- var has = Object.prototype.hasOwnProperty;
9
- function createComparison(type) {
10
- return { "~sc": type };
11
- }
12
- var match = {
13
- noExtraKeys: (partialShape) => createComparison(["withNoExtraKeys", partialShape]),
14
- deepNoExtraKeys: (partialShape) => createComparison(["withDeepNoExtraKeys", partialShape]),
15
- noExtraDefinedKeys: (partialShape) => createComparison(["noExtraDefinedKeys", partialShape]),
16
- deepNoExtraDefinedKeys: (partialShape) => createComparison(["deepNoExtraDefinedKeys", partialShape]),
17
- hasType: {
18
- string: createComparison(["hasType", "string"]),
19
- number: createComparison(["hasType", "number"]),
20
- boolean: createComparison(["hasType", "boolean"]),
21
- object: createComparison(["hasType", "object"]),
22
- array: createComparison(["hasType", "array"]),
23
- function: createComparison(["hasType", "function"])
24
- },
25
- isInstanceOf: (constructor) => createComparison(["isInstanceOf", constructor]),
26
- str: {
27
- contains: (substring) => createComparison(["strContains", substring]),
28
- startsWith: (substring) => createComparison(["strStartsWith", substring]),
29
- endsWith: (substring) => createComparison(["strEndsWith", substring]),
30
- matchesRegex: (regex) => createComparison(["strMatchesRegex", regex])
31
- },
32
- num: {
33
- isGreaterThan: (value) => createComparison(["numIsGreaterThan", value]),
34
- isGreaterThanOrEqual: (value) => createComparison(["numIsGreaterThanOrEqual", value]),
35
- isLessThan: (value) => createComparison(["numIsLessThan", value]),
36
- isLessThanOrEqual: (value) => createComparison(["numIsLessThanOrEqual", value]),
37
- isInRange: (value) => createComparison(["numIsInRange", value])
38
- },
39
- array: {
40
- contains: (elements) => createComparison(["arrayContains", elements]),
41
- containsInOrder: (elements) => createComparison(["arrayContainsInOrder", elements]),
42
- startsWith: (elements) => createComparison(["arrayStartsWith", elements]),
43
- endsWith: (elements) => createComparison(["arrayEndsWith", elements]),
44
- length: (n) => createComparison(["arrayLength", n]),
45
- minLength: (n) => createComparison(["arrayMinLength", n]),
46
- maxLength: (n) => createComparison(["arrayMaxLength", n]),
47
- includes: (element) => createComparison(["arrayIncludes", element]),
48
- every: (matcher) => createComparison(["arrayEvery", matcher["~sc"]]),
49
- some: (matcher) => createComparison(["arraySome", matcher["~sc"]])
50
- },
51
- jsonString: {
52
- hasPartial: (value) => createComparison(["jsonStringHasPartial", value])
53
- },
54
- equal: (value) => createComparison(["deepEqual", value]),
55
- partialEqual: (value) => createComparison(["partialEqual", value]),
56
- custom: (isEqual) => createComparison(["custom", isEqual]),
57
- keyNotBePresent: createComparison(["keyNotBePresent", null]),
58
- any: (...values) => createComparison([
59
- "any",
60
- values.map((v) => {
61
- if (isComparison(v)) return v["~sc"];
62
- if (typeof v === "object" && v !== null)
63
- return ["partialEqual", v];
64
- return ["deepEqual", v];
65
- })
66
- ]),
67
- all: (...values) => createComparison([
68
- "all",
69
- values.map((v) => {
70
- if (isComparison(v)) return v["~sc"];
71
- if (typeof v === "object" && v !== null)
72
- return ["partialEqual", v];
73
- return ["deepEqual", v];
74
- })
75
- ]),
76
- key: {
77
- any: "$pqkc:any$",
78
- anyOther: "$pqkc:anyOther$",
79
- numeric: "$pqkc:numeric$",
80
- startingWith: (substring) => `$pqkc:startingWith:${substring}$`,
81
- endingWith: (substring) => `$pqkc:endingWith:${substring}$`,
82
- containing: (substring) => `$pqkc:contains:${substring}$`,
83
- matchingRegex: (regex) => `$pqkc:matchesRegex:${regex}$`
84
- },
85
- not: {
86
- hasType: {
87
- string: createComparison(["not", ["hasType", "string"]]),
88
- number: createComparison(["not", ["hasType", "number"]]),
89
- boolean: createComparison(["not", ["hasType", "boolean"]]),
90
- object: createComparison(["not", ["hasType", "object"]]),
91
- array: createComparison(["not", ["hasType", "array"]]),
92
- function: createComparison(["not", ["hasType", "function"]])
93
- },
94
- keyNotBePresent: createComparison(["not", ["keyNotBePresent", null]]),
95
- isInstanceOf: (constructor) => createComparison(["not", ["isInstanceOf", constructor]]),
96
- str: {
97
- contains: (substring) => createComparison(["not", ["strContains", substring]]),
98
- startsWith: (substring) => createComparison(["not", ["strStartsWith", substring]]),
99
- endsWith: (substring) => createComparison(["not", ["strEndsWith", substring]]),
100
- matchesRegex: (regex) => createComparison(["not", ["strMatchesRegex", regex]])
101
- },
102
- num: {
103
- isGreaterThan: (value) => createComparison(["not", ["numIsGreaterThan", value]]),
104
- isGreaterThanOrEqual: (value) => createComparison(["not", ["numIsGreaterThanOrEqual", value]]),
105
- isLessThan: (value) => createComparison(["not", ["numIsLessThan", value]]),
106
- isLessThanOrEqual: (value) => createComparison(["not", ["numIsLessThanOrEqual", value]]),
107
- isInRange: (value) => createComparison(["not", ["numIsInRange", value]])
108
- },
109
- array: {
110
- contains: (elements) => createComparison(["not", ["arrayContains", elements]]),
111
- containsInOrder: (elements) => createComparison(["not", ["arrayContainsInOrder", elements]]),
112
- startsWith: (elements) => createComparison(["not", ["arrayStartsWith", elements]]),
113
- endsWith: (elements) => createComparison(["not", ["arrayEndsWith", elements]]),
114
- length: (n) => createComparison(["not", ["arrayLength", n]]),
115
- minLength: (n) => createComparison(["not", ["arrayMinLength", n]]),
116
- maxLength: (n) => createComparison(["not", ["arrayMaxLength", n]]),
117
- includes: (element) => createComparison(["not", ["arrayIncludes", element]]),
118
- every: (matcher) => createComparison(["not", ["arrayEvery", matcher["~sc"]]]),
119
- some: (matcher) => createComparison(["not", ["arraySome", matcher["~sc"]]])
120
- },
121
- jsonString: {
122
- hasPartial: (value) => createComparison(["not", ["jsonStringHasPartial", value]])
123
- },
124
- equal: (value) => createComparison(["not", ["deepEqual", value]]),
125
- partialEqual: (value) => createComparison(["not", ["partialEqual", value]]),
126
- custom: (value) => createComparison(["not", ["custom", value]]),
127
- any: (...values) => createComparison([
128
- "not",
129
- [
130
- "any",
131
- values.map((v) => {
132
- if (isComparison(v)) return v["~sc"];
133
- if (typeof v === "object" && v !== null)
134
- return ["partialEqual", v];
135
- return ["deepEqual", v];
136
- })
137
- ]
138
- ]),
139
- all: (...values) => createComparison([
140
- "not",
141
- [
142
- "all",
143
- values.map((v) => {
144
- if (isComparison(v)) return v["~sc"];
145
- if (typeof v === "object" && v !== null)
146
- return ["partialEqual", v];
147
- return ["deepEqual", v];
148
- })
149
- ]
150
- ]),
151
- noExtraKeys: (partialShape) => createComparison(["not", ["withNoExtraKeys", partialShape]]),
152
- deepNoExtraKeys: (partialShape) => createComparison(["not", ["withDeepNoExtraKeys", partialShape]]),
153
- noExtraDefinedKeys: (partialShape) => createComparison(["not", ["noExtraDefinedKeys", partialShape]]),
154
- deepNoExtraDefinedKeys: (partialShape) => createComparison(["not", ["deepNoExtraDefinedKeys", partialShape]]),
155
- key: {
156
- any: "$pqkc-not:any$",
157
- anyOther: "$pqkc-not:anyOther$",
158
- numeric: "$pqkc-not:numeric$",
159
- startingWith: (substring) => `$pqkc-not:startingWith:${substring}$`,
160
- endingWith: (substring) => `$pqkc-not:endingWith:${substring}$`,
161
- containing: (substring) => `$pqkc-not:contains:${substring}$`,
162
- matchingRegex: (regex) => `$pqkc-not:matchesRegex:${regex}$`
163
- }
164
- }
165
- };
166
- function isComparison(value) {
167
- return value && typeof value === "object" && "~sc" in value;
168
- }
169
- function isKeyMatcher(key) {
170
- return typeof key === "string" && (key.startsWith("$pqkc:") || key.startsWith("$pqkc-not:"));
171
- }
172
- function parseKeyMatcher(key) {
173
- if (!isKeyMatcher(key)) return null;
174
- const negated = key.startsWith("$pqkc-not:");
175
- const prefix = negated ? "$pqkc-not:" : "$pqkc:";
176
- const suffix = "$";
177
- if (!key.endsWith(suffix)) return null;
178
- const content = key.slice(prefix.length, -suffix.length);
179
- if (content === "any") {
180
- return { type: "any", negated };
181
- }
182
- if (content === "anyOther") {
183
- return { type: "anyOther", negated };
184
- }
185
- if (content === "numeric") {
186
- return { type: "numeric", negated };
187
- }
188
- if (content.startsWith("startingWith:")) {
189
- return { type: "startingWith", parameter: content.slice("startingWith:".length), negated };
190
- }
191
- if (content.startsWith("endingWith:")) {
192
- return { type: "endingWith", parameter: content.slice("endingWith:".length), negated };
193
- }
194
- if (content.startsWith("contains:")) {
195
- return { type: "contains", parameter: content.slice("contains:".length), negated };
196
- }
197
- if (content.startsWith("matchesRegex:")) {
198
- const regexStr = content.slice("matchesRegex:".length);
199
- try {
200
- if (regexStr.startsWith("/") && regexStr.lastIndexOf("/") > 0) {
201
- const lastSlashIndex = regexStr.lastIndexOf("/");
202
- const pattern = regexStr.slice(1, lastSlashIndex);
203
- const flags = regexStr.slice(lastSlashIndex + 1);
204
- return { type: "matchesRegex", parameter: new RegExp(pattern, flags), negated };
205
- } else {
206
- return { type: "matchesRegex", parameter: new RegExp(regexStr), negated };
207
- }
208
- } catch {
209
- return null;
210
- }
211
- }
212
- return null;
213
- }
214
- function keyMatchesPattern(key, matcher) {
215
- let matches = false;
216
- switch (matcher.type) {
217
- case "any":
218
- matches = true;
219
- break;
220
- case "anyOther":
221
- matches = true;
222
- break;
223
- case "numeric":
224
- matches = /^\d+$/.test(key);
225
- break;
226
- case "startingWith":
227
- matches = key.startsWith(matcher.parameter);
228
- break;
229
- case "endingWith":
230
- matches = key.endsWith(matcher.parameter);
231
- break;
232
- case "contains":
233
- matches = key.includes(matcher.parameter);
234
- break;
235
- case "matchesRegex":
236
- matches = matcher.parameter.test(key);
237
- break;
238
- }
239
- return matcher.negated ? !matches : matches;
240
- }
241
- function executeComparison(target, comparison, context) {
242
- const [type, value] = comparison;
243
- switch (type) {
244
- case "strStartsWith":
245
- if (typeof target !== "string") {
246
- addError(context, {
247
- message: `Expected string starting with "${value}"`,
248
- received: target
249
- });
250
- return false;
251
- }
252
- if (!target.startsWith(value)) {
253
- addError(context, {
254
- message: `Expected string starting with "${value}"`,
255
- received: target
256
- });
257
- return false;
258
- }
259
- return true;
260
- case "strEndsWith":
261
- if (typeof target !== "string") {
262
- addError(context, {
263
- message: `Expected string ending with "${value}"`,
264
- received: target
265
- });
266
- return false;
267
- }
268
- if (!target.endsWith(value)) {
269
- addError(context, {
270
- message: `Expected string ending with "${value}"`,
271
- received: target
272
- });
273
- return false;
274
- }
275
- return true;
276
- case "strContains":
277
- if (typeof target !== "string") {
278
- addError(context, {
279
- message: `Expected string containing "${value}"`,
280
- received: target
281
- });
282
- return false;
283
- }
284
- if (!target.includes(value)) {
285
- addError(context, {
286
- message: `Expected string containing "${value}"`,
287
- received: target
288
- });
289
- return false;
290
- }
291
- return true;
292
- case "strMatchesRegex":
293
- if (typeof target !== "string") {
294
- addError(context, {
295
- message: `Expected string matching regex ${value}`,
296
- received: target
297
- });
298
- return false;
299
- }
300
- if (!value.test(target)) {
301
- addError(context, {
302
- message: `Expected string matching regex ${value}`,
303
- received: target
304
- });
305
- return false;
306
- }
307
- return true;
308
- case "hasType": {
309
- let actualType;
310
- if (value === "array") {
311
- actualType = Array.isArray(target) ? "array" : typeof target;
312
- } else if (value === "object") {
313
- if (target === null || Array.isArray(target)) {
314
- actualType = "not-object";
315
- } else {
316
- actualType = typeof target;
317
- }
318
- } else {
319
- actualType = typeof target;
320
- }
321
- if (actualType !== value) {
322
- addError(context, {
323
- message: `Expected type ${value}`,
324
- received: target
325
- });
326
- return false;
327
- }
328
- return true;
329
- }
330
- case "deepEqual":
331
- if (!deepEqual(target, value)) {
332
- addError(context, {
333
- message: "Values are not deeply equal",
334
- received: target,
335
- expected: value
336
- });
337
- return false;
338
- }
339
- return true;
340
- case "numIsGreaterThan":
341
- if (typeof target !== "number" || target <= value) {
342
- addError(context, {
343
- message: `Expected number greater than ${value}`,
344
- received: target
345
- });
346
- return false;
347
- }
348
- return true;
349
- case "numIsGreaterThanOrEqual":
350
- if (typeof target !== "number" || target < value) {
351
- addError(context, {
352
- message: `Expected number greater than or equal to ${value}`,
353
- received: target
354
- });
355
- return false;
356
- }
357
- return true;
358
- case "numIsLessThan":
359
- if (typeof target !== "number" || target >= value) {
360
- addError(context, {
361
- message: `Expected number less than ${value}`,
362
- received: target
363
- });
364
- return false;
365
- }
366
- return true;
367
- case "numIsLessThanOrEqual":
368
- if (typeof target !== "number" || target > value) {
369
- addError(context, {
370
- message: `Expected number less than or equal to ${value}`,
371
- received: target
372
- });
373
- return false;
374
- }
375
- return true;
376
- case "numIsInRange":
377
- if (typeof target !== "number" || target < value[0] || target > value[1]) {
378
- addError(context, {
379
- message: `Expected number in range [${value[0]}, ${value[1]}]`,
380
- received: target
381
- });
382
- return false;
383
- }
384
- return true;
385
- case "jsonStringHasPartial":
386
- if (typeof target !== "string") {
387
- addError(context, {
388
- message: "Expected JSON string",
389
- received: target
390
- });
391
- return false;
392
- }
393
- try {
394
- const parsed = JSON.parse(target);
395
- if (!partialEqualInternal(parsed, value, context)) {
396
- return false;
397
- }
398
- } catch {
399
- addError(context, {
400
- message: "Expected valid JSON string",
401
- received: target
402
- });
403
- return false;
404
- }
405
- return true;
406
- case "partialEqual":
407
- return partialEqualInternal(target, value, context);
408
- case "custom": {
409
- const result = value(target);
410
- if (result !== true) {
411
- addError(context, {
412
- message: `Custom validation failed ${typeof result === "object" ? `: ${result.error}` : ""}`,
413
- received: target
414
- });
415
- return false;
416
- }
417
- return true;
418
- }
419
- case "isInstanceOf":
420
- if (!(target instanceof value)) {
421
- addError(context, {
422
- message: `Expected instance of ${value.name}`,
423
- received: target
424
- });
425
- return false;
426
- }
427
- return true;
428
- case "keyNotBePresent":
429
- addError(context, {
430
- message: "This property should not be present",
431
- received: target
432
- });
433
- return false;
434
- case "not": {
435
- const tempContext = {
436
- errors: [],
437
- path: context.path
438
- };
439
- const result = executeComparison(target, value, tempContext);
440
- if (result) {
441
- addError(context, {
442
- message: "Expected negated condition to fail",
443
- received: target,
444
- expected: { "not match": value }
445
- });
446
- return false;
447
- }
448
- return true;
449
- }
450
- case "any": {
451
- for (const subComparison of value) {
452
- const anyTempContext = {
453
- errors: [],
454
- path: context.path
455
- };
456
- if (executeComparison(target, subComparison, anyTempContext)) {
457
- return true;
458
- }
459
- }
460
- addError(context, {
461
- message: "None of the alternative comparisons matched",
462
- received: target,
463
- expected: {
464
- matchAny: value
465
- }
466
- });
467
- return false;
468
- }
469
- case "all": {
470
- let allMatch = true;
471
- for (const subComparison of value) {
472
- if (!executeComparison(target, subComparison, context)) {
473
- allMatch = false;
474
- }
475
- }
476
- return allMatch;
477
- }
478
- case "withNoExtraKeys":
479
- return checkNoExtraKeys(target, value, context, false);
480
- case "withDeepNoExtraKeys":
481
- return checkNoExtraKeys(target, value, context, true);
482
- case "noExtraDefinedKeys":
483
- return checkNoExtraDefinedKeys(target, value, context, false);
484
- case "deepNoExtraDefinedKeys":
485
- return checkNoExtraDefinedKeys(target, value, context, true);
486
- case "arrayContains": {
487
- if (!Array.isArray(target)) {
488
- addError(context, {
489
- message: "Expected array",
490
- received: target
491
- });
492
- return false;
493
- }
494
- for (const element of value) {
495
- let found = false;
496
- for (const targetElement of target) {
497
- const tempContext = {
498
- errors: [],
499
- path: context.path
500
- };
501
- if (partialEqualInternal(targetElement, element, tempContext)) {
502
- found = true;
503
- break;
504
- }
505
- }
506
- if (!found) {
507
- addError(context, {
508
- message: "Array does not contain expected element",
509
- received: target,
510
- expected: element
511
- });
512
- return false;
513
- }
514
- }
515
- return true;
516
- }
517
- case "arrayContainsInOrder": {
518
- if (!Array.isArray(target)) {
519
- addError(context, {
520
- message: "Expected array",
521
- received: target
522
- });
523
- return false;
524
- }
525
- let targetIndex = 0;
526
- for (const element of value) {
527
- let found = false;
528
- for (let i = targetIndex; i < target.length; i++) {
529
- const tempContext = {
530
- errors: [],
531
- path: context.path
532
- };
533
- if (partialEqualInternal(target[i], element, tempContext)) {
534
- targetIndex = i + 1;
535
- found = true;
536
- break;
537
- }
538
- }
539
- if (!found) {
540
- addError(context, {
541
- message: "Array does not contain expected elements in order",
542
- received: target,
543
- expected: value
544
- });
545
- return false;
546
- }
547
- }
548
- return true;
549
- }
550
- case "arrayStartsWith": {
551
- if (!Array.isArray(target)) {
552
- addError(context, {
553
- message: "Expected array",
554
- received: target
555
- });
556
- return false;
557
- }
558
- if (target.length < value.length) {
559
- addError(context, {
560
- message: `Array too short: expected to start with ${value.length} elements, got ${target.length}`,
561
- received: target,
562
- expected: value
563
- });
564
- return false;
565
- }
566
- let allMatch = true;
567
- for (let i = 0; i < value.length; i++) {
568
- const oldPath = context.path;
569
- context.path = [...oldPath, `[${i}]`];
570
- const result = partialEqualInternal(target[i], value[i], context);
571
- context.path = oldPath;
572
- if (!result) allMatch = false;
573
- }
574
- return allMatch;
575
- }
576
- case "arrayEndsWith": {
577
- if (!Array.isArray(target)) {
578
- addError(context, {
579
- message: "Expected array",
580
- received: target
581
- });
582
- return false;
583
- }
584
- if (target.length < value.length) {
585
- addError(context, {
586
- message: `Array too short: expected to end with ${value.length} elements, got ${target.length}`,
587
- received: target,
588
- expected: value
589
- });
590
- return false;
591
- }
592
- let allMatch = true;
593
- const startIndex = target.length - value.length;
594
- for (let i = 0; i < value.length; i++) {
595
- const oldPath = context.path;
596
- context.path = [...oldPath, `[${startIndex + i}]`];
597
- const result = partialEqualInternal(
598
- target[startIndex + i],
599
- value[i],
600
- context
601
- );
602
- context.path = oldPath;
603
- if (!result) allMatch = false;
604
- }
605
- return allMatch;
606
- }
607
- case "arrayLength": {
608
- if (!Array.isArray(target)) {
609
- addError(context, {
610
- message: "Expected array",
611
- received: target
612
- });
613
- return false;
614
- }
615
- if (target.length !== value) {
616
- addError(context, {
617
- message: `Expected array length ${value}, got ${target.length}`,
618
- received: target
619
- });
620
- return false;
621
- }
622
- return true;
623
- }
624
- case "arrayMinLength": {
625
- if (!Array.isArray(target)) {
626
- addError(context, {
627
- message: "Expected array",
628
- received: target
629
- });
630
- return false;
631
- }
632
- if (target.length < value) {
633
- addError(context, {
634
- message: `Expected array with at least ${value} elements, got ${target.length}`,
635
- received: target
636
- });
637
- return false;
638
- }
639
- return true;
640
- }
641
- case "arrayMaxLength": {
642
- if (!Array.isArray(target)) {
643
- addError(context, {
644
- message: "Expected array",
645
- received: target
646
- });
647
- return false;
648
- }
649
- if (target.length > value) {
650
- addError(context, {
651
- message: `Expected array with at most ${value} elements, got ${target.length}`,
652
- received: target
653
- });
654
- return false;
655
- }
656
- return true;
657
- }
658
- case "arrayIncludes": {
659
- if (!Array.isArray(target)) {
660
- addError(context, {
661
- message: "Expected array",
662
- received: target
663
- });
664
- return false;
665
- }
666
- let found = false;
667
- for (const targetElement of target) {
668
- const tempContext = {
669
- errors: [],
670
- path: context.path
671
- };
672
- if (partialEqualInternal(targetElement, value, tempContext)) {
673
- found = true;
674
- break;
675
- }
676
- }
677
- if (!found) {
678
- addError(context, {
679
- message: "Array does not include expected element",
680
- received: target,
681
- expected: value
682
- });
683
- return false;
684
- }
685
- return true;
686
- }
687
- case "arrayEvery": {
688
- if (!Array.isArray(target)) {
689
- addError(context, {
690
- message: "Expected array",
691
- received: target
692
- });
693
- return false;
694
- }
695
- let allMatch = true;
696
- for (let i = 0; i < target.length; i++) {
697
- const oldPath = context.path;
698
- context.path = [...oldPath, `[${i}]`];
699
- const result = executeComparison(target[i], value, context);
700
- context.path = oldPath;
701
- if (!result) allMatch = false;
702
- }
703
- return allMatch;
704
- }
705
- case "arraySome": {
706
- if (!Array.isArray(target)) {
707
- addError(context, {
708
- message: "Expected array",
709
- received: target
710
- });
711
- return false;
712
- }
713
- for (let i = 0; i < target.length; i++) {
714
- const tempContext = {
715
- errors: [],
716
- path: [...context.path, `[${i}]`]
717
- };
718
- if (executeComparison(target[i], value, tempContext)) {
719
- return true;
720
- }
721
- }
722
- addError(context, {
723
- message: "No array element matches the condition",
724
- received: target
725
- });
726
- return false;
727
- }
728
- default:
729
- throw exhaustiveCheck(type);
730
- }
731
- }
732
- function formatPath(path) {
733
- if (path.length === 0) return "";
734
- let result = path[0] || "";
735
- for (let i = 1; i < path.length; i++) {
736
- const segment = path[i];
737
- if (segment && segment.startsWith("[") && segment.endsWith("]")) {
738
- result += segment;
739
- } else if (segment) {
740
- if (result) {
741
- result += `.${segment}`;
742
- } else {
743
- result += segment;
744
- }
745
- }
746
- }
747
- return result;
748
- }
749
- function addError(context, error) {
750
- context.errors.push({
751
- path: formatPath(context.path),
752
- ...error
753
- });
754
- }
755
- function deepEqual(a, b) {
756
- if (a === b) return true;
757
- if (Number.isNaN(a) && Number.isNaN(b)) return true;
758
- if (a === null || b === null) return false;
759
- if (typeof a !== typeof b) return false;
760
- if (Array.isArray(a) && Array.isArray(b)) {
761
- if (a.length !== b.length) return false;
762
- for (let i = 0; i < a.length; i++) {
763
- if (!deepEqual(a[i], b[i])) return false;
764
- }
765
- return true;
766
- }
767
- if (typeof a === "object") {
768
- const keysA = Object.keys(a);
769
- const keysB = Object.keys(b);
770
- if (keysA.length !== keysB.length) return false;
771
- for (const key of keysA) {
772
- if (!has.call(b, key) || !deepEqual(a[key], b[key])) return false;
773
- }
774
- return true;
775
- }
776
- return false;
777
- }
778
- function partialEqualInternal(target, sub, context) {
779
- if (isComparison(sub)) {
780
- return executeComparison(target, sub["~sc"], context);
781
- }
782
- if (isComparison(sub) && sub["~sc"][0] === "keyNotBePresent") {
783
- addError(context, {
784
- message: "This property should not be present",
785
- received: target
786
- });
787
- return false;
788
- }
789
- if (target === sub) return true;
790
- if (Number.isNaN(target) && Number.isNaN(sub)) return true;
791
- if (target === null || sub === null || target === void 0 || sub === void 0) {
792
- if (target !== sub) {
793
- addError(context, {
794
- message: "Value mismatch",
795
- received: target,
796
- expected: sub
797
- });
798
- return false;
799
- }
800
- return true;
801
- }
802
- if (target instanceof Date && sub instanceof Date) {
803
- if (target.getTime() !== sub.getTime()) {
804
- addError(context, {
805
- message: "Date mismatch",
806
- received: target,
807
- expected: sub
808
- });
809
- return false;
810
- }
811
- return true;
812
- }
813
- if (target instanceof RegExp && sub instanceof RegExp) {
814
- if (target.source !== sub.source || target.flags !== sub.flags) {
815
- addError(context, {
816
- message: "RegExp mismatch",
817
- received: target,
818
- expected: sub
819
- });
820
- return false;
821
- }
822
- return true;
823
- }
824
- if (target instanceof Set && sub instanceof Set) {
825
- if (sub.size > target.size) {
826
- addError(context, {
827
- message: "Set too small",
828
- received: target,
829
- expected: sub
830
- });
831
- return false;
832
- }
833
- for (const subValue of sub) {
834
- let found = false;
835
- for (const targetValue of target) {
836
- const tempContext = {
837
- errors: [],
838
- path: context.path
839
- };
840
- if (partialEqualInternal(targetValue, subValue, tempContext)) {
841
- found = true;
842
- break;
843
- }
844
- }
845
- if (!found) {
846
- addError(context, {
847
- message: "Set element not found",
848
- received: target,
849
- expected: sub
850
- });
851
- return false;
852
- }
853
- }
854
- return true;
855
- }
856
- if (target instanceof Map && sub instanceof Map) {
857
- if (sub.size > target.size) {
858
- addError(context, {
859
- message: "Map has less entries than expected",
860
- received: `${target.size} entries`,
861
- expected: `${sub.size} entries`
862
- });
863
- return false;
864
- }
865
- for (const [subKey, subValue] of sub) {
866
- let found = false;
867
- for (const [targetKey, targetValue] of target) {
868
- const tempContextKey = {
869
- errors: [],
870
- path: context.path
871
- };
872
- const tempContextValue = {
873
- errors: [],
874
- path: context.path
875
- };
876
- if (partialEqualInternal(targetKey, subKey, tempContextKey) && partialEqualInternal(targetValue, subValue, tempContextValue)) {
877
- found = true;
878
- break;
879
- }
880
- }
881
- if (!found) {
882
- addError(context, {
883
- message: "Map entry not found",
884
- received: target,
885
- expected: sub
886
- });
887
- return false;
888
- }
889
- }
890
- return true;
891
- }
892
- if (typeof target !== typeof sub) {
893
- addError(context, {
894
- message: "Value mismatch",
895
- received: target,
896
- expected: sub
897
- });
898
- return false;
899
- }
900
- if (Array.isArray(sub)) {
901
- if (!Array.isArray(target)) {
902
- addError(context, {
903
- message: "Expected array",
904
- received: target,
905
- expected: sub
906
- });
907
- return false;
908
- }
909
- if (target.length < sub.length) {
910
- addError(context, {
911
- message: `Array too short: expected at least ${sub.length} elements, got ${target.length}`,
912
- received: target,
913
- expected: sub
914
- });
915
- return false;
916
- }
917
- let allMatch = true;
918
- for (let i = 0; i < sub.length; i++) {
919
- const oldPath = context.path;
920
- context.path = [...oldPath, `[${i}]`];
921
- const result = partialEqualInternal(target[i], sub[i], context);
922
- context.path = oldPath;
923
- if (!result) allMatch = false;
924
- }
925
- return allMatch;
926
- }
927
- if (typeof sub === "object") {
928
- if (typeof target !== "object" || Array.isArray(target)) {
929
- addError(context, {
930
- message: "Expected object",
931
- received: target,
932
- expected: sub
933
- });
934
- return false;
935
- }
936
- let allMatch = true;
937
- const regularKeys = [];
938
- const keyMatchers = [];
939
- for (const key of Object.keys(sub)) {
940
- if (isKeyMatcher(key)) {
941
- const matcher = parseKeyMatcher(key);
942
- if (matcher) {
943
- keyMatchers.push({ key, matcher, value: sub[key] });
944
- }
945
- } else {
946
- regularKeys.push(key);
947
- }
948
- }
949
- const explicitlySpecifiedKeys = /* @__PURE__ */ new Set();
950
- for (const key of regularKeys) {
951
- explicitlySpecifiedKeys.add(key);
952
- if (isComparison(sub[key]) && sub[key]["~sc"][0] === "keyNotBePresent") {
953
- if (has.call(target, key)) {
954
- const oldPath2 = context.path;
955
- context.path = [...oldPath2, key];
956
- addError(context, {
957
- message: "Key should not be present",
958
- received: target[key]
959
- });
960
- context.path = oldPath2;
961
- allMatch = false;
962
- }
963
- continue;
964
- }
965
- if (!has.call(target, key)) {
966
- if (isComparison(sub[key])) {
967
- const comparison = sub[key]["~sc"];
968
- if (comparison[0] === "any") {
969
- const anyComparisons = comparison[1];
970
- const hasKeyNotBePresent = anyComparisons.some(
971
- (comp) => comp[0] === "keyNotBePresent"
972
- );
973
- if (hasKeyNotBePresent) {
974
- continue;
975
- }
976
- }
977
- }
978
- const oldPath2 = context.path;
979
- context.path = [...oldPath2, key];
980
- addError(context, {
981
- message: "Missing property",
982
- expected: sub[key],
983
- received: { objectWithKeys: Object.keys(target) }
984
- });
985
- context.path = oldPath2;
986
- allMatch = false;
987
- continue;
988
- }
989
- const oldPath = context.path;
990
- context.path = [...oldPath, key];
991
- const result = partialEqualInternal(target[key], sub[key], context);
992
- context.path = oldPath;
993
- if (!result) allMatch = false;
994
- }
995
- for (const { matcher, value } of keyMatchers) {
996
- let foundMatch = false;
997
- const matchedKeys = [];
998
- if (matcher.type === "anyOther") {
999
- for (const targetKey of Object.keys(target)) {
1000
- if (!explicitlySpecifiedKeys.has(targetKey)) {
1001
- const matches = keyMatchesPattern(targetKey, matcher);
1002
- if (matches) {
1003
- foundMatch = true;
1004
- matchedKeys.push(targetKey);
1005
- const oldPath = context.path;
1006
- context.path = [...oldPath, targetKey];
1007
- const result = partialEqualInternal(target[targetKey], value, context);
1008
- context.path = oldPath;
1009
- if (!result) allMatch = false;
1010
- }
1011
- }
1012
- }
1013
- } else if (matcher.type === "any") {
1014
- let anyKeyMatched = false;
1015
- for (const targetKey of Object.keys(target)) {
1016
- if (keyMatchesPattern(targetKey, matcher)) {
1017
- foundMatch = true;
1018
- matchedKeys.push(targetKey);
1019
- explicitlySpecifiedKeys.add(targetKey);
1020
- const tempContext = {
1021
- errors: [],
1022
- path: [...context.path, targetKey]
1023
- };
1024
- const result = partialEqualInternal(target[targetKey], value, tempContext);
1025
- if (result) {
1026
- anyKeyMatched = true;
1027
- break;
1028
- }
1029
- }
1030
- }
1031
- if (foundMatch && !anyKeyMatched) {
1032
- addError(context, {
1033
- message: `No keys matching pattern had the expected value`,
1034
- received: { keysChecked: matchedKeys, availableKeys: Object.keys(target) }
1035
- });
1036
- allMatch = false;
1037
- }
1038
- } else {
1039
- for (const targetKey of Object.keys(target)) {
1040
- if (keyMatchesPattern(targetKey, matcher)) {
1041
- foundMatch = true;
1042
- matchedKeys.push(targetKey);
1043
- explicitlySpecifiedKeys.add(targetKey);
1044
- const oldPath = context.path;
1045
- context.path = [...oldPath, targetKey];
1046
- const result = partialEqualInternal(target[targetKey], value, context);
1047
- context.path = oldPath;
1048
- if (!result) allMatch = false;
1049
- }
1050
- }
1051
- }
1052
- if (!foundMatch) {
1053
- const patternDescription = matcher.type === "anyOther" ? "anyOther (keys not explicitly specified)" : `${matcher.type}${matcher.parameter ? ` (${matcher.parameter})` : ""}`;
1054
- addError(context, {
1055
- message: `No keys found matching pattern: ${patternDescription}`,
1056
- received: { availableKeys: Object.keys(target), explicitKeys: Array.from(explicitlySpecifiedKeys) }
1057
- });
1058
- allMatch = false;
1059
- }
1060
- }
1061
- return allMatch;
1062
- }
1063
- if (target !== sub) {
1064
- addError(context, {
1065
- message: "Value mismatch",
1066
- received: target,
1067
- expected: sub
1068
- });
1069
- return false;
1070
- }
1071
- return true;
1072
- }
1073
- function checkNoExtraKeys(target, partialShape, context, deep) {
1074
- if (typeof target !== "object" || target === null || Array.isArray(target)) {
1075
- addError(context, {
1076
- message: "Expected object for key validation",
1077
- received: target
1078
- });
1079
- return false;
1080
- }
1081
- if (!partialEqualInternal(target, partialShape, context)) {
1082
- return false;
1083
- }
1084
- const allowedKeys = new Set(Object.keys(partialShape));
1085
- for (const key of Object.keys(target)) {
1086
- if (!allowedKeys.has(key)) {
1087
- const oldPath = context.path;
1088
- context.path = [...oldPath, key];
1089
- addError(context, {
1090
- message: `Extra key "${key}" should not be present`,
1091
- received: target[key]
1092
- });
1093
- context.path = oldPath;
1094
- return false;
1095
- }
1096
- }
1097
- if (deep) {
1098
- for (const key of Object.keys(partialShape)) {
1099
- if (typeof partialShape[key] === "object" && partialShape[key] !== null && !Array.isArray(partialShape[key]) && !isComparison(partialShape[key])) {
1100
- const oldPath = context.path;
1101
- context.path = [...oldPath, key];
1102
- const result = checkNoExtraKeys(
1103
- target[key],
1104
- partialShape[key],
1105
- context,
1106
- true
1107
- );
1108
- context.path = oldPath;
1109
- if (!result) return false;
1110
- }
1111
- }
1112
- }
1113
- return true;
1114
- }
1115
- function checkNoExtraDefinedKeys(target, partialShape, context, deep) {
1116
- if (typeof target !== "object" || target === null || Array.isArray(target)) {
1117
- addError(context, {
1118
- message: "Expected object for key validation",
1119
- received: target
1120
- });
1121
- return false;
1122
- }
1123
- if (!partialEqualInternal(target, partialShape, context)) {
1124
- return false;
1125
- }
1126
- const allowedKeys = new Set(Object.keys(partialShape));
1127
- for (const key of Object.keys(target)) {
1128
- if (!allowedKeys.has(key) && target[key] !== void 0) {
1129
- const oldPath = context.path;
1130
- context.path = [...oldPath, key];
1131
- addError(context, {
1132
- message: `Extra defined key "${key}" should not be present`,
1133
- received: target[key]
1134
- });
1135
- context.path = oldPath;
1136
- return false;
1137
- }
1138
- }
1139
- if (deep) {
1140
- for (const key of Object.keys(partialShape)) {
1141
- if (typeof partialShape[key] === "object" && partialShape[key] !== null && !Array.isArray(partialShape[key]) && !isComparison(partialShape[key])) {
1142
- const oldPath = context.path;
1143
- context.path = [...oldPath, key];
1144
- const result = checkNoExtraDefinedKeys(
1145
- target[key],
1146
- partialShape[key],
1147
- context,
1148
- true
1149
- );
1150
- context.path = oldPath;
1151
- if (!result) return false;
1152
- }
1153
- }
1154
- }
1155
- return true;
1156
- }
1157
- function partialEqual(target, sub, returnErrors) {
1158
- const context = { errors: [], path: [] };
1159
- const result = partialEqualInternal(target, sub, context);
1160
- if (returnErrors) {
1161
- return result ? ok(void 0) : err(context.errors);
1162
- }
1163
- return result;
1164
- }
1165
- export {
1166
- match,
1167
- partialEqual
1168
- };