@kontor/kontor-sdk 1.0.0-alpha.39 → 1.0.0-alpha.40

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 (270) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/sdk/actions/kontor/public/call-view.js.map +1 -1
  3. package/dist/cjs/sdk/chains/definitions/signet.js +2 -2
  4. package/dist/cjs/sdk/test/e2e.test-deprecated.js +2 -0
  5. package/dist/cjs/sdk/test/e2e.test-deprecated.js.map +1 -0
  6. package/dist/cjs/sdk/utils/wit/codecs/bool.js +9 -21
  7. package/dist/cjs/sdk/utils/wit/codecs/bool.js.map +1 -1
  8. package/dist/cjs/sdk/utils/wit/codecs/contract-address.js +92 -0
  9. package/dist/cjs/sdk/utils/wit/codecs/contract-address.js.map +1 -0
  10. package/dist/cjs/sdk/utils/wit/codecs/index.js +29 -0
  11. package/dist/cjs/sdk/utils/wit/codecs/index.js.map +1 -0
  12. package/dist/cjs/sdk/utils/wit/codecs/list.js +21 -95
  13. package/dist/cjs/sdk/utils/wit/codecs/list.js.map +1 -1
  14. package/dist/cjs/sdk/utils/wit/codecs/numerics.js +228 -0
  15. package/dist/cjs/sdk/utils/wit/codecs/numerics.js.map +1 -0
  16. package/dist/cjs/sdk/utils/wit/codecs/option.js +21 -72
  17. package/dist/cjs/sdk/utils/wit/codecs/option.js.map +1 -1
  18. package/dist/cjs/sdk/utils/wit/codecs/result.js +32 -0
  19. package/dist/cjs/sdk/utils/wit/codecs/result.js.map +1 -0
  20. package/dist/cjs/sdk/utils/wit/codecs/string.js +16 -21
  21. package/dist/cjs/sdk/utils/wit/codecs/string.js.map +1 -1
  22. package/dist/cjs/sdk/utils/wit/codecs/unit.js +11 -19
  23. package/dist/cjs/sdk/utils/wit/codecs/unit.js.map +1 -1
  24. package/dist/cjs/sdk/utils/wit/codecs/util.js +185 -0
  25. package/dist/cjs/sdk/utils/wit/codecs/util.js.map +1 -0
  26. package/dist/cjs/sdk/utils/wit/decode-wit-parameter.js +297 -163
  27. package/dist/cjs/sdk/utils/wit/decode-wit-parameter.js.map +1 -1
  28. package/dist/cjs/sdk/utils/wit/encode-wit-parameters.js +214 -221
  29. package/dist/cjs/sdk/utils/wit/encode-wit-parameters.js.map +1 -1
  30. package/dist/cjs/tsconfig.build.tsbuildinfo +1 -1
  31. package/dist/cjs/wit/built-ins.js +19 -0
  32. package/dist/cjs/wit/built-ins.js.map +1 -0
  33. package/dist/cjs/wit/regex.js +1 -1
  34. package/dist/cjs/wit/regex.js.map +1 -1
  35. package/dist/cjs/wit/wit-parser/core/errors/signature.js +17 -2
  36. package/dist/cjs/wit/wit-parser/core/errors/signature.js.map +1 -1
  37. package/dist/cjs/wit/wit-parser/core/signatures.js +18 -0
  38. package/dist/cjs/wit/wit-parser/core/signatures.js.map +1 -1
  39. package/dist/cjs/wit/wit-parser/core/types/{records.js → user-defined.js} +1 -1
  40. package/dist/cjs/wit/wit-parser/core/types/user-defined.js.map +1 -0
  41. package/dist/cjs/wit/wit-parser/core/user-defined.js +271 -0
  42. package/dist/cjs/wit/wit-parser/core/user-defined.js.map +1 -0
  43. package/dist/cjs/wit/wit-parser/core/utils.js +29 -7
  44. package/dist/cjs/wit/wit-parser/core/utils.js.map +1 -1
  45. package/dist/cjs/wit/wit-parser/parse-wit-parameter.js +9 -3
  46. package/dist/cjs/wit/wit-parser/parse-wit-parameter.js.map +1 -1
  47. package/dist/cjs/wit/wit-parser/parse-wit.js +7 -3
  48. package/dist/cjs/wit/wit-parser/parse-wit.js.map +1 -1
  49. package/dist/esm/sdk/actions/kontor/public/call-view.js.map +1 -1
  50. package/dist/esm/sdk/chains/definitions/signet.js +2 -2
  51. package/dist/esm/sdk/test/e2e.test-deprecated.js +197 -0
  52. package/dist/esm/sdk/test/e2e.test-deprecated.js.map +1 -0
  53. package/dist/esm/sdk/utils/wit/codecs/bool.js +9 -21
  54. package/dist/esm/sdk/utils/wit/codecs/bool.js.map +1 -1
  55. package/dist/esm/sdk/utils/wit/codecs/contract-address.js +92 -0
  56. package/dist/esm/sdk/utils/wit/codecs/contract-address.js.map +1 -0
  57. package/dist/esm/sdk/utils/wit/codecs/index.js +9 -0
  58. package/dist/esm/sdk/utils/wit/codecs/index.js.map +1 -0
  59. package/dist/esm/sdk/utils/wit/codecs/list.js +20 -114
  60. package/dist/esm/sdk/utils/wit/codecs/list.js.map +1 -1
  61. package/dist/esm/sdk/utils/wit/codecs/numerics.js +234 -0
  62. package/dist/esm/sdk/utils/wit/codecs/numerics.js.map +1 -0
  63. package/dist/esm/sdk/utils/wit/codecs/option.js +21 -88
  64. package/dist/esm/sdk/utils/wit/codecs/option.js.map +1 -1
  65. package/dist/esm/sdk/utils/wit/codecs/result.js +29 -0
  66. package/dist/esm/sdk/utils/wit/codecs/result.js.map +1 -0
  67. package/dist/esm/sdk/utils/wit/codecs/string.js +22 -22
  68. package/dist/esm/sdk/utils/wit/codecs/string.js.map +1 -1
  69. package/dist/esm/sdk/utils/wit/codecs/unit.js +12 -21
  70. package/dist/esm/sdk/utils/wit/codecs/unit.js.map +1 -1
  71. package/dist/esm/sdk/utils/wit/codecs/util.js +181 -0
  72. package/dist/esm/sdk/utils/wit/codecs/util.js.map +1 -0
  73. package/dist/esm/sdk/utils/wit/decode-wit-parameter.js +322 -188
  74. package/dist/esm/sdk/utils/wit/decode-wit-parameter.js.map +1 -1
  75. package/dist/esm/sdk/utils/wit/encode-wit-parameters.js +230 -233
  76. package/dist/esm/sdk/utils/wit/encode-wit-parameters.js.map +1 -1
  77. package/dist/esm/tsconfig.build.tsbuildinfo +1 -1
  78. package/dist/esm/wit/built-ins.js +16 -0
  79. package/dist/esm/wit/built-ins.js.map +1 -0
  80. package/dist/esm/wit/regex.js +1 -1
  81. package/dist/esm/wit/regex.js.map +1 -1
  82. package/dist/esm/wit/wit-parser/core/errors/signature.js +15 -1
  83. package/dist/esm/wit/wit-parser/core/errors/signature.js.map +1 -1
  84. package/dist/esm/wit/wit-parser/core/signatures.js +14 -0
  85. package/dist/esm/wit/wit-parser/core/signatures.js.map +1 -1
  86. package/dist/esm/wit/wit-parser/core/types/signatures.js.map +1 -1
  87. package/dist/esm/wit/wit-parser/core/types/user-defined.js +2 -0
  88. package/dist/esm/wit/wit-parser/core/types/user-defined.js.map +1 -0
  89. package/dist/esm/wit/wit-parser/core/types/utils.js +25 -0
  90. package/dist/esm/wit/wit-parser/core/types/utils.js.map +1 -1
  91. package/dist/esm/wit/wit-parser/core/user-defined.js +280 -0
  92. package/dist/esm/wit/wit-parser/core/user-defined.js.map +1 -0
  93. package/dist/esm/wit/wit-parser/core/utils.js +33 -36
  94. package/dist/esm/wit/wit-parser/core/utils.js.map +1 -1
  95. package/dist/esm/wit/wit-parser/parse-wit-parameter.js +10 -4
  96. package/dist/esm/wit/wit-parser/parse-wit-parameter.js.map +1 -1
  97. package/dist/esm/wit/wit-parser/parse-wit.js +8 -4
  98. package/dist/esm/wit/wit-parser/parse-wit.js.map +1 -1
  99. package/dist/types/sdk/actions/kontor/public/call-view.d.ts +2 -1
  100. package/dist/types/sdk/actions/kontor/public/call-view.d.ts.map +1 -1
  101. package/dist/types/sdk/chains/definitions/signet.d.ts +2 -2
  102. package/dist/types/sdk/test/e2e.test-deprecated.d.ts +2 -0
  103. package/dist/types/sdk/test/e2e.test-deprecated.d.ts.map +1 -0
  104. package/dist/types/sdk/types/contract.d.ts +5 -5
  105. package/dist/types/sdk/types/contract.d.ts.map +1 -1
  106. package/dist/types/sdk/utils/wit/codecs/bool.d.ts +2 -2
  107. package/dist/types/sdk/utils/wit/codecs/bool.d.ts.map +1 -1
  108. package/dist/types/sdk/utils/wit/codecs/contract-address.d.ts +5 -0
  109. package/dist/types/sdk/utils/wit/codecs/contract-address.d.ts.map +1 -0
  110. package/dist/types/sdk/utils/wit/codecs/index.d.ts +9 -0
  111. package/dist/types/sdk/utils/wit/codecs/index.d.ts.map +1 -0
  112. package/dist/types/sdk/utils/wit/codecs/list.d.ts +2 -16
  113. package/dist/types/sdk/utils/wit/codecs/list.d.ts.map +1 -1
  114. package/dist/types/sdk/utils/wit/codecs/numerics.d.ts +14 -0
  115. package/dist/types/sdk/utils/wit/codecs/numerics.d.ts.map +1 -0
  116. package/dist/types/sdk/utils/wit/codecs/option.d.ts +3 -23
  117. package/dist/types/sdk/utils/wit/codecs/option.d.ts.map +1 -1
  118. package/dist/types/sdk/utils/wit/codecs/result.d.ts +4 -0
  119. package/dist/types/sdk/utils/wit/codecs/result.d.ts.map +1 -0
  120. package/dist/types/sdk/utils/wit/codecs/string.d.ts +6 -2
  121. package/dist/types/sdk/utils/wit/codecs/string.d.ts.map +1 -1
  122. package/dist/types/sdk/utils/wit/codecs/types.d.ts +4 -0
  123. package/dist/types/sdk/utils/wit/codecs/types.d.ts.map +1 -1
  124. package/dist/types/sdk/utils/wit/codecs/unit.d.ts +2 -11
  125. package/dist/types/sdk/utils/wit/codecs/unit.d.ts.map +1 -1
  126. package/dist/types/sdk/utils/wit/codecs/util.d.ts +12 -0
  127. package/dist/types/sdk/utils/wit/codecs/util.d.ts.map +1 -0
  128. package/dist/types/sdk/utils/wit/decode-wit-parameter.d.ts +9 -31
  129. package/dist/types/sdk/utils/wit/decode-wit-parameter.d.ts.map +1 -1
  130. package/dist/types/sdk/utils/wit/encode-wit-parameters.d.ts +9 -1
  131. package/dist/types/sdk/utils/wit/encode-wit-parameters.d.ts.map +1 -1
  132. package/dist/types/wit/built-ins.d.ts +6 -0
  133. package/dist/types/wit/built-ins.d.ts.map +1 -0
  134. package/dist/types/wit/regex.d.ts.map +1 -1
  135. package/dist/types/wit/utils.d.ts +53 -33
  136. package/dist/types/wit/utils.d.ts.map +1 -1
  137. package/dist/types/wit/wit-parser/core/errors/signature.d.ts +7 -1
  138. package/dist/types/wit/wit-parser/core/errors/signature.d.ts.map +1 -1
  139. package/dist/types/wit/wit-parser/core/signatures.d.ts +10 -0
  140. package/dist/types/wit/wit-parser/core/signatures.d.ts.map +1 -1
  141. package/dist/types/wit/wit-parser/core/types/signatures.d.ts +6 -2
  142. package/dist/types/wit/wit-parser/core/types/signatures.d.ts.map +1 -1
  143. package/dist/types/wit/wit-parser/core/types/user-defined.d.ts +134 -0
  144. package/dist/types/wit/wit-parser/core/types/user-defined.d.ts.map +1 -0
  145. package/dist/types/wit/wit-parser/core/types/utils.d.ts +86 -11
  146. package/dist/types/wit/wit-parser/core/types/utils.d.ts.map +1 -1
  147. package/dist/types/wit/wit-parser/core/user-defined.d.ts +19 -0
  148. package/dist/types/wit/wit-parser/core/user-defined.d.ts.map +1 -0
  149. package/dist/types/wit/wit-parser/core/utils.d.ts +8 -4
  150. package/dist/types/wit/wit-parser/core/utils.d.ts.map +1 -1
  151. package/dist/types/wit/wit-parser/parse-wit-parameter.d.ts +11 -5
  152. package/dist/types/wit/wit-parser/parse-wit-parameter.d.ts.map +1 -1
  153. package/dist/types/wit/wit-parser/parse-wit.d.ts +7 -3
  154. package/dist/types/wit/wit-parser/parse-wit.d.ts.map +1 -1
  155. package/dist/types/wit/wit.d.ts +20 -12
  156. package/dist/types/wit/wit.d.ts.map +1 -1
  157. package/package.json +1 -1
  158. package/src/sdk/actions/get-contract.test-d.ts +430 -50
  159. package/src/sdk/actions/get-contract.test.ts +324 -24
  160. package/src/sdk/actions/kontor/public/call-view.ts +2 -1
  161. package/src/sdk/actions/kontor/public/proc-contract.test-d.ts +107 -0
  162. package/src/sdk/actions/kontor/public/proc-contract.test.ts +234 -21
  163. package/src/sdk/actions/kontor/public/view-contract.test-d.ts +240 -0
  164. package/src/sdk/actions/kontor/public/view-contract.test.ts +613 -18
  165. package/src/sdk/chains/definitions/signet.ts +2 -2
  166. package/src/sdk/clients/base/create-rpc-client.test.ts +2 -2
  167. package/src/sdk/clients/create-public-client.test.ts +2 -2
  168. package/src/sdk/clients/kontor/create-public-client.test.ts +2 -2
  169. package/src/sdk/clients/transports/http-rpc.test.ts +0 -24
  170. package/src/sdk/test/e2e.test-deprecated.ts +195 -0
  171. package/src/sdk/types/contract.test-d.ts +489 -55
  172. package/src/sdk/types/contract.ts +6 -7
  173. package/src/sdk/utils/wit/codecs/bool.test.ts +29 -0
  174. package/src/sdk/utils/wit/codecs/bool.ts +10 -25
  175. package/src/sdk/utils/wit/codecs/contract-address.test.ts +37 -0
  176. package/src/sdk/utils/wit/codecs/contract-address.ts +114 -0
  177. package/src/sdk/utils/wit/codecs/index.ts +20 -0
  178. package/src/sdk/utils/wit/codecs/list.test-d.ts +13 -0
  179. package/src/sdk/utils/wit/codecs/list.test.ts +55 -0
  180. package/src/sdk/utils/wit/codecs/list.ts +21 -150
  181. package/src/sdk/utils/wit/codecs/numerics.test.ts +399 -0
  182. package/src/sdk/utils/wit/codecs/numerics.ts +304 -0
  183. package/src/sdk/utils/wit/codecs/option.test.ts +71 -0
  184. package/src/sdk/utils/wit/codecs/option.ts +21 -120
  185. package/src/sdk/utils/wit/codecs/result.test.ts +82 -0
  186. package/src/sdk/utils/wit/codecs/result.ts +37 -0
  187. package/src/sdk/utils/wit/codecs/string.test.ts +62 -0
  188. package/src/sdk/utils/wit/codecs/string.ts +23 -25
  189. package/src/sdk/utils/wit/codecs/types.ts +5 -0
  190. package/src/sdk/utils/wit/codecs/unit.test.ts +27 -0
  191. package/src/sdk/utils/wit/codecs/unit.ts +14 -38
  192. package/src/sdk/utils/wit/codecs/util.test.ts +221 -0
  193. package/src/sdk/utils/wit/codecs/util.ts +193 -0
  194. package/src/sdk/utils/wit/decode-wit-parameter.test.ts +1264 -32
  195. package/src/sdk/utils/wit/decode-wit-parameter.ts +508 -211
  196. package/src/sdk/utils/wit/encode-wit-parameters.test.ts +955 -91
  197. package/src/sdk/utils/wit/encode-wit-parameters.ts +277 -274
  198. package/src/sdk/utils/wit/get-wit-item.test.ts +1 -1
  199. package/src/wit/built-ins.ts +23 -0
  200. package/src/wit/regex.ts +1 -1
  201. package/src/wit/utils.ts +120 -74
  202. package/src/wit/wit-parser/core/errors/signature.ts +13 -2
  203. package/src/wit/wit-parser/core/signatures.ts +28 -0
  204. package/src/wit/wit-parser/core/types/signatures.test-d.ts +21 -0
  205. package/src/wit/wit-parser/core/types/signatures.ts +19 -2
  206. package/src/wit/wit-parser/core/types/user-defined.test-d.ts +1308 -0
  207. package/src/wit/wit-parser/core/types/user-defined.ts +412 -0
  208. package/src/wit/wit-parser/core/types/utils.test-d.ts +43 -2
  209. package/src/wit/wit-parser/core/types/utils.ts +143 -14
  210. package/src/wit/wit-parser/core/user-defined.test.ts +609 -0
  211. package/src/wit/wit-parser/core/user-defined.ts +392 -0
  212. package/src/wit/wit-parser/core/utils.test.ts +334 -115
  213. package/src/wit/wit-parser/core/utils.ts +54 -38
  214. package/src/wit/wit-parser/parse-wit-parameter.test.ts +282 -4
  215. package/src/wit/wit-parser/parse-wit-parameter.ts +37 -11
  216. package/src/wit/wit-parser/parse-wit.test.ts +738 -12
  217. package/src/wit/wit-parser/parse-wit.ts +25 -10
  218. package/src/wit/wit.ts +37 -16
  219. package/vitest.config.ts +5 -0
  220. package/dist/cjs/sdk/utils/wit/codecs/decimal.js +0 -148
  221. package/dist/cjs/sdk/utils/wit/codecs/decimal.js.map +0 -1
  222. package/dist/cjs/sdk/utils/wit/codecs/enum.js +0 -94
  223. package/dist/cjs/sdk/utils/wit/codecs/enum.js.map +0 -1
  224. package/dist/cjs/sdk/utils/wit/codecs/integer.js +0 -125
  225. package/dist/cjs/sdk/utils/wit/codecs/integer.js.map +0 -1
  226. package/dist/cjs/sdk/utils/wit/codecs/s64.js +0 -57
  227. package/dist/cjs/sdk/utils/wit/codecs/s64.js.map +0 -1
  228. package/dist/cjs/sdk/utils/wit/codecs/u64.js +0 -56
  229. package/dist/cjs/sdk/utils/wit/codecs/u64.js.map +0 -1
  230. package/dist/cjs/wit/wit-parser/core/records.js +0 -70
  231. package/dist/cjs/wit/wit-parser/core/records.js.map +0 -1
  232. package/dist/cjs/wit/wit-parser/core/types/records.js.map +0 -1
  233. package/dist/esm/sdk/utils/wit/codecs/decimal.js +0 -165
  234. package/dist/esm/sdk/utils/wit/codecs/decimal.js.map +0 -1
  235. package/dist/esm/sdk/utils/wit/codecs/enum.js +0 -104
  236. package/dist/esm/sdk/utils/wit/codecs/enum.js.map +0 -1
  237. package/dist/esm/sdk/utils/wit/codecs/integer.js +0 -167
  238. package/dist/esm/sdk/utils/wit/codecs/integer.js.map +0 -1
  239. package/dist/esm/sdk/utils/wit/codecs/s64.js +0 -65
  240. package/dist/esm/sdk/utils/wit/codecs/s64.js.map +0 -1
  241. package/dist/esm/sdk/utils/wit/codecs/u64.js +0 -63
  242. package/dist/esm/sdk/utils/wit/codecs/u64.js.map +0 -1
  243. package/dist/esm/wit/wit-parser/core/records.js +0 -73
  244. package/dist/esm/wit/wit-parser/core/records.js.map +0 -1
  245. package/dist/esm/wit/wit-parser/core/types/records.js +0 -2
  246. package/dist/esm/wit/wit-parser/core/types/records.js.map +0 -1
  247. package/dist/types/sdk/utils/wit/codecs/decimal.d.ts +0 -42
  248. package/dist/types/sdk/utils/wit/codecs/decimal.d.ts.map +0 -1
  249. package/dist/types/sdk/utils/wit/codecs/enum.d.ts +0 -49
  250. package/dist/types/sdk/utils/wit/codecs/enum.d.ts.map +0 -1
  251. package/dist/types/sdk/utils/wit/codecs/integer.d.ts +0 -36
  252. package/dist/types/sdk/utils/wit/codecs/integer.d.ts.map +0 -1
  253. package/dist/types/sdk/utils/wit/codecs/s64.d.ts +0 -23
  254. package/dist/types/sdk/utils/wit/codecs/s64.d.ts.map +0 -1
  255. package/dist/types/sdk/utils/wit/codecs/u64.d.ts +0 -23
  256. package/dist/types/sdk/utils/wit/codecs/u64.d.ts.map +0 -1
  257. package/dist/types/wit/wit-parser/core/records.d.ts +0 -4
  258. package/dist/types/wit/wit-parser/core/records.d.ts.map +0 -1
  259. package/dist/types/wit/wit-parser/core/types/records.d.ts +0 -51
  260. package/dist/types/wit/wit-parser/core/types/records.d.ts.map +0 -1
  261. package/src/sdk/test/e2e.test.ts +0 -194
  262. package/src/sdk/utils/wit/codecs/decimal.ts +0 -215
  263. package/src/sdk/utils/wit/codecs/enum.ts +0 -114
  264. package/src/sdk/utils/wit/codecs/integer.ts +0 -193
  265. package/src/sdk/utils/wit/codecs/s64.ts +0 -76
  266. package/src/sdk/utils/wit/codecs/u64.ts +0 -73
  267. package/src/wit/wit-parser/core/records.test.ts +0 -69
  268. package/src/wit/wit-parser/core/records.ts +0 -101
  269. package/src/wit/wit-parser/core/types/records.test-d.ts +0 -331
  270. package/src/wit/wit-parser/core/types/records.ts +0 -91
@@ -0,0 +1,1308 @@
1
+ import { expectTypeOf, test } from "vitest";
2
+ import type {
3
+ ParseTypes,
4
+ ParseRecords,
5
+ ParseVariants,
6
+ ParseEnums,
7
+ } from "./user-defined.js";
8
+
9
+ // ============================================================================
10
+ // Enum Tests
11
+ // ============================================================================
12
+
13
+ test("ParseEnums - basic enum", () => {
14
+ expectTypeOf<
15
+ ParseEnums<["enum color { red, green, blue }"]>
16
+ >().toEqualTypeOf<{
17
+ color: readonly ["red", "green", "blue"];
18
+ }>();
19
+ });
20
+
21
+ test("ParseEnums - multiple enums", () => {
22
+ expectTypeOf<
23
+ ParseEnums<
24
+ [
25
+ "enum color { red, green, blue }",
26
+ "enum status { pending, complete, failed }",
27
+ ]
28
+ >
29
+ >().toEqualTypeOf<{
30
+ color: readonly ["red", "green", "blue"];
31
+ status: readonly ["pending", "complete", "failed"];
32
+ }>();
33
+ });
34
+
35
+ // ============================================================================
36
+ // Basic Record Tests
37
+ // ============================================================================
38
+
39
+ test("ParseRecords - basic records", () => {
40
+ expectTypeOf<
41
+ ParseRecords<
42
+ [
43
+ "record contract-address { name: string, height: s64, tx-index: s64 }",
44
+ "record token-pair { a: contract-address, b: contract-address }",
45
+ ]
46
+ >
47
+ >().toEqualTypeOf<{
48
+ "contract-address": readonly [
49
+ {
50
+ readonly name: "name";
51
+ readonly type: "string";
52
+ readonly internalType: "string";
53
+ },
54
+ {
55
+ readonly name: "height";
56
+ readonly type: "s64";
57
+ readonly internalType: "s64";
58
+ },
59
+ {
60
+ readonly name: "tx-index";
61
+ readonly type: "s64";
62
+ readonly internalType: "s64";
63
+ },
64
+ ];
65
+ "token-pair": readonly [
66
+ {
67
+ readonly name: "a";
68
+ readonly type: "contract-address";
69
+ readonly internalType: "contract-address";
70
+ },
71
+ {
72
+ readonly name: "b";
73
+ readonly type: "contract-address";
74
+ readonly internalType: "contract-address";
75
+ },
76
+ ];
77
+ }>();
78
+ });
79
+
80
+ test("ParseRecords - with generics", () => {
81
+ expectTypeOf<
82
+ ParseRecords<
83
+ [
84
+ "record contract-address { name: string, height: s64, tx-index: s64 }",
85
+ "record generic { as-list: list<contract-address>, as-option: option<contract-address>, as-result: result<contract-address, error> }",
86
+ ]
87
+ >
88
+ >().toEqualTypeOf<{
89
+ "contract-address": readonly [
90
+ {
91
+ readonly name: "name";
92
+ readonly type: "string";
93
+ readonly internalType: "string";
94
+ },
95
+ {
96
+ readonly name: "height";
97
+ readonly type: "s64";
98
+ readonly internalType: "s64";
99
+ },
100
+ {
101
+ readonly name: "tx-index";
102
+ readonly type: "s64";
103
+ readonly internalType: "s64";
104
+ },
105
+ ];
106
+ generic: readonly [
107
+ {
108
+ readonly name: "as-list";
109
+ readonly type: "list<contract-address>";
110
+ readonly internalType: "list<contract-address>";
111
+ },
112
+ {
113
+ readonly name: "as-option";
114
+ readonly type: "option<contract-address>";
115
+ readonly internalType: "option<contract-address>";
116
+ },
117
+ {
118
+ readonly name: "as-result";
119
+ readonly type: "result<contract-address, error>";
120
+ readonly internalType: "result<contract-address, error>";
121
+ },
122
+ ];
123
+ }>();
124
+ });
125
+
126
+ // ============================================================================
127
+ // Basic Variant Tests
128
+ // ============================================================================
129
+
130
+ test("ParseVariants - basic variants", () => {
131
+ expectTypeOf<
132
+ ParseVariants<
133
+ [
134
+ "variant response { ok(string), err(string) }",
135
+ "variant complex { success(response), failure(string) }",
136
+ ]
137
+ >
138
+ >().toEqualTypeOf<{
139
+ response: readonly [
140
+ {
141
+ readonly name: "ok";
142
+ readonly type: "string";
143
+ readonly internalType: "string";
144
+ },
145
+ {
146
+ readonly name: "err";
147
+ readonly type: "string";
148
+ readonly internalType: "string";
149
+ },
150
+ ];
151
+ complex: readonly [
152
+ {
153
+ readonly name: "success";
154
+ readonly type: "response";
155
+ readonly internalType: "response";
156
+ },
157
+ {
158
+ readonly name: "failure";
159
+ readonly type: "string";
160
+ readonly internalType: "string";
161
+ },
162
+ ];
163
+ }>();
164
+ });
165
+
166
+ test("ParseVariants - with unit cases", () => {
167
+ expectTypeOf<
168
+ ParseVariants<
169
+ [
170
+ "variant rainbow { red, orange, yellow, green, blue, indigo, violet }",
171
+ "variant color { hex(string), literal(rainbow) }",
172
+ ]
173
+ >
174
+ >().toEqualTypeOf<{
175
+ rainbow: readonly [
176
+ { readonly name: "red"; readonly type: "_"; readonly internalType: "_" },
177
+ {
178
+ readonly name: "orange";
179
+ readonly type: "_";
180
+ readonly internalType: "_";
181
+ },
182
+ {
183
+ readonly name: "yellow";
184
+ readonly type: "_";
185
+ readonly internalType: "_";
186
+ },
187
+ {
188
+ readonly name: "green";
189
+ readonly type: "_";
190
+ readonly internalType: "_";
191
+ },
192
+ { readonly name: "blue"; readonly type: "_"; readonly internalType: "_" },
193
+ {
194
+ readonly name: "indigo";
195
+ readonly type: "_";
196
+ readonly internalType: "_";
197
+ },
198
+ {
199
+ readonly name: "violet";
200
+ readonly type: "_";
201
+ readonly internalType: "_";
202
+ },
203
+ ];
204
+ color: readonly [
205
+ {
206
+ readonly name: "hex";
207
+ readonly type: "string";
208
+ readonly internalType: "string";
209
+ },
210
+ {
211
+ readonly name: "literal";
212
+ readonly type: "rainbow";
213
+ readonly internalType: "rainbow";
214
+ },
215
+ ];
216
+ }>();
217
+ });
218
+
219
+ test("ParseVariants - with generics", () => {
220
+ expectTypeOf<
221
+ ParseVariants<
222
+ [
223
+ "variant response { ok(string), err(string) }",
224
+ "variant envelope { maybe(option<string>), many(list<string>), nested(response) }",
225
+ ]
226
+ >
227
+ >().toEqualTypeOf<{
228
+ response: readonly [
229
+ {
230
+ readonly name: "ok";
231
+ readonly type: "string";
232
+ readonly internalType: "string";
233
+ },
234
+ {
235
+ readonly name: "err";
236
+ readonly type: "string";
237
+ readonly internalType: "string";
238
+ },
239
+ ];
240
+ envelope: readonly [
241
+ {
242
+ readonly name: "maybe";
243
+ readonly type: "option<string>";
244
+ readonly internalType: "option<string>";
245
+ },
246
+ {
247
+ readonly name: "many";
248
+ readonly type: "list<string>";
249
+ readonly internalType: "list<string>";
250
+ },
251
+ {
252
+ readonly name: "nested";
253
+ readonly type: "response";
254
+ readonly internalType: "response";
255
+ },
256
+ ];
257
+ }>();
258
+ });
259
+
260
+ // ============================================================================
261
+ // Cross-Type Reference Tests
262
+ // ============================================================================
263
+
264
+ test("ParseTypes - record referencing variant", () => {
265
+ expectTypeOf<
266
+ ParseTypes<
267
+ [
268
+ "variant color { hex(string), literal(string) }",
269
+ "record palette { a: color, b: list<color> }",
270
+ ]
271
+ >
272
+ >().toEqualTypeOf<{
273
+ records: {
274
+ palette: readonly [
275
+ {
276
+ readonly name: "a";
277
+ readonly type: "variant";
278
+ readonly internalType: "color";
279
+ readonly components: readonly [
280
+ {
281
+ readonly name: "hex";
282
+ readonly type: "string";
283
+ readonly internalType: "string";
284
+ },
285
+ {
286
+ readonly name: "literal";
287
+ readonly type: "string";
288
+ readonly internalType: "string";
289
+ },
290
+ ];
291
+ },
292
+ {
293
+ readonly name: "b";
294
+ readonly type: "list<variant>";
295
+ readonly internalType: "list<color>";
296
+ readonly components: readonly [
297
+ {
298
+ readonly name: "hex";
299
+ readonly type: "string";
300
+ readonly internalType: "string";
301
+ },
302
+ {
303
+ readonly name: "literal";
304
+ readonly type: "string";
305
+ readonly internalType: "string";
306
+ },
307
+ ];
308
+ },
309
+ ];
310
+ };
311
+ variants: {
312
+ color: readonly [
313
+ {
314
+ readonly name: "hex";
315
+ readonly type: "string";
316
+ readonly internalType: "string";
317
+ },
318
+ {
319
+ readonly name: "literal";
320
+ readonly type: "string";
321
+ readonly internalType: "string";
322
+ },
323
+ ];
324
+ };
325
+ enums: {};
326
+ }>();
327
+ });
328
+
329
+ test("ParseTypes - record referencing enum", () => {
330
+ expectTypeOf<
331
+ ParseTypes<
332
+ [
333
+ "enum color { red, green, blue }",
334
+ "record palette { primary: color, secondary: color }",
335
+ ]
336
+ >
337
+ >().toEqualTypeOf<{
338
+ variants: {};
339
+ records: {
340
+ palette: readonly [
341
+ {
342
+ readonly name: "primary";
343
+ readonly type: "enum";
344
+ readonly internalType: "color";
345
+ readonly components: readonly [
346
+ { readonly name: "red"; readonly type: "_" },
347
+ { readonly name: "green"; readonly type: "_" },
348
+ { readonly name: "blue"; readonly type: "_" },
349
+ ];
350
+ },
351
+ {
352
+ readonly name: "secondary";
353
+ readonly type: "enum";
354
+ readonly internalType: "color";
355
+ readonly components: readonly [
356
+ { readonly name: "red"; readonly type: "_" },
357
+ { readonly name: "green"; readonly type: "_" },
358
+ { readonly name: "blue"; readonly type: "_" },
359
+ ];
360
+ },
361
+ ];
362
+ };
363
+ enums: {
364
+ color: readonly ["red", "green", "blue"];
365
+ };
366
+ }>();
367
+ });
368
+
369
+ test("ParseTypes - variant referencing enum", () => {
370
+ expectTypeOf<
371
+ ParseTypes<
372
+ [
373
+ "enum status { pending, complete, failed }",
374
+ "variant response { ok(status), err(string) }",
375
+ ]
376
+ >
377
+ >().toEqualTypeOf<{
378
+ records: {};
379
+ variants: {
380
+ response: readonly [
381
+ {
382
+ readonly name: "ok";
383
+ readonly type: "enum";
384
+ readonly internalType: "status";
385
+ readonly components: readonly [
386
+ { readonly name: "pending"; readonly type: "_" },
387
+ { readonly name: "complete"; readonly type: "_" },
388
+ { readonly name: "failed"; readonly type: "_" },
389
+ ];
390
+ },
391
+ {
392
+ readonly name: "err";
393
+ readonly type: "string";
394
+ readonly internalType: "string";
395
+ },
396
+ ];
397
+ };
398
+ enums: {
399
+ status: readonly ["pending", "complete", "failed"];
400
+ };
401
+ }>();
402
+ });
403
+
404
+ test("ParseTypes - variant with nested record", () => {
405
+ expectTypeOf<
406
+ ParseTypes<
407
+ [
408
+ "record rgb { r: u8, g: u8, b: u8 }",
409
+ "variant color { hex(string), name(string), rgb(rgb) }",
410
+ "record palette { primary: color, secondary: color }",
411
+ ]
412
+ >
413
+ >().toEqualTypeOf<{
414
+ enums: {};
415
+ records: {
416
+ rgb: readonly [
417
+ {
418
+ readonly name: "r";
419
+ readonly type: "u8";
420
+ readonly internalType: "u8";
421
+ },
422
+ {
423
+ readonly name: "g";
424
+ readonly type: "u8";
425
+ readonly internalType: "u8";
426
+ },
427
+ {
428
+ readonly name: "b";
429
+ readonly type: "u8";
430
+ readonly internalType: "u8";
431
+ },
432
+ ];
433
+ palette: readonly [
434
+ {
435
+ readonly name: "primary";
436
+ readonly type: "variant";
437
+ readonly internalType: "color";
438
+ readonly components: readonly [
439
+ {
440
+ readonly name: "hex";
441
+ readonly type: "string";
442
+ readonly internalType: "string";
443
+ },
444
+ {
445
+ readonly name: "name";
446
+ readonly type: "string";
447
+ readonly internalType: "string";
448
+ },
449
+ {
450
+ readonly name: "rgb";
451
+ readonly type: "record";
452
+ readonly internalType: "rgb";
453
+ readonly components: readonly [
454
+ {
455
+ readonly name: "r";
456
+ readonly type: "u8";
457
+ readonly internalType: "u8";
458
+ },
459
+ {
460
+ readonly name: "g";
461
+ readonly type: "u8";
462
+ readonly internalType: "u8";
463
+ },
464
+ {
465
+ readonly name: "b";
466
+ readonly type: "u8";
467
+ readonly internalType: "u8";
468
+ },
469
+ ];
470
+ },
471
+ ];
472
+ },
473
+ {
474
+ readonly name: "secondary";
475
+ readonly type: "variant";
476
+ readonly internalType: "color";
477
+ readonly components: readonly [
478
+ {
479
+ readonly name: "hex";
480
+ readonly type: "string";
481
+ readonly internalType: "string";
482
+ },
483
+ {
484
+ readonly name: "name";
485
+ readonly type: "string";
486
+ readonly internalType: "string";
487
+ },
488
+ {
489
+ readonly name: "rgb";
490
+ readonly type: "record";
491
+ readonly internalType: "rgb";
492
+ readonly components: readonly [
493
+ {
494
+ readonly name: "r";
495
+ readonly type: "u8";
496
+ readonly internalType: "u8";
497
+ },
498
+ {
499
+ readonly name: "g";
500
+ readonly type: "u8";
501
+ readonly internalType: "u8";
502
+ },
503
+ {
504
+ readonly name: "b";
505
+ readonly type: "u8";
506
+ readonly internalType: "u8";
507
+ },
508
+ ];
509
+ },
510
+ ];
511
+ },
512
+ ];
513
+ };
514
+ variants: {
515
+ color: readonly [
516
+ {
517
+ readonly name: "hex";
518
+ readonly type: "string";
519
+ readonly internalType: "string";
520
+ },
521
+ {
522
+ readonly name: "name";
523
+ readonly type: "string";
524
+ readonly internalType: "string";
525
+ },
526
+ {
527
+ readonly name: "rgb";
528
+ readonly type: "record";
529
+ readonly internalType: "rgb";
530
+ readonly components: readonly [
531
+ {
532
+ readonly name: "r";
533
+ readonly type: "u8";
534
+ readonly internalType: "u8";
535
+ },
536
+ {
537
+ readonly name: "g";
538
+ readonly type: "u8";
539
+ readonly internalType: "u8";
540
+ },
541
+ {
542
+ readonly name: "b";
543
+ readonly type: "u8";
544
+ readonly internalType: "u8";
545
+ },
546
+ ];
547
+ },
548
+ ];
549
+ };
550
+ }>();
551
+ });
552
+
553
+ test("ParseTypes - enum wrapped in generics", () => {
554
+ expectTypeOf<
555
+ ParseTypes<
556
+ [
557
+ "enum status { pending, complete, failed }",
558
+ "record task { current: status, history: list<status> }",
559
+ ]
560
+ >
561
+ >().toEqualTypeOf<{
562
+ variants: {};
563
+ records: {
564
+ task: readonly [
565
+ {
566
+ readonly name: "current";
567
+ readonly type: "enum";
568
+ readonly internalType: "status";
569
+ readonly components: readonly [
570
+ { readonly name: "pending"; readonly type: "_" },
571
+ { readonly name: "complete"; readonly type: "_" },
572
+ { readonly name: "failed"; readonly type: "_" },
573
+ ];
574
+ },
575
+ {
576
+ readonly name: "history";
577
+ readonly type: "list<enum>";
578
+ readonly internalType: "list<status>";
579
+ readonly components: readonly [
580
+ { readonly name: "pending"; readonly type: "_" },
581
+ { readonly name: "complete"; readonly type: "_" },
582
+ { readonly name: "failed"; readonly type: "_" },
583
+ ];
584
+ },
585
+ ];
586
+ };
587
+ enums: {
588
+ status: readonly ["pending", "complete", "failed"];
589
+ };
590
+ }>();
591
+ });
592
+
593
+ // ============================================================================
594
+ // Complex Mixed Type Tests
595
+ // ============================================================================
596
+
597
+ test("ParseTypes - all three types together", () => {
598
+ expectTypeOf<
599
+ ParseTypes<
600
+ [
601
+ "enum status { pending, complete, failed }",
602
+ "record user { name: string, status: status }",
603
+ "variant response { ok(user), err(string) }",
604
+ ]
605
+ >
606
+ >().toEqualTypeOf<{
607
+ enums: {
608
+ status: readonly ["pending", "complete", "failed"];
609
+ };
610
+ records: {
611
+ user: readonly [
612
+ {
613
+ readonly name: "name";
614
+ readonly type: "string";
615
+ readonly internalType: "string";
616
+ },
617
+ {
618
+ readonly name: "status";
619
+ readonly type: "enum";
620
+ readonly internalType: "status";
621
+ readonly components: readonly [
622
+ {
623
+ readonly name: "pending";
624
+ readonly type: "_";
625
+ },
626
+ {
627
+ readonly name: "complete";
628
+ readonly type: "_";
629
+ },
630
+ {
631
+ readonly name: "failed";
632
+ readonly type: "_";
633
+ },
634
+ ];
635
+ },
636
+ ];
637
+ };
638
+
639
+ variants: {
640
+ response: readonly [
641
+ {
642
+ readonly name: "ok";
643
+ readonly type: "record";
644
+ readonly internalType: "user";
645
+ readonly components: readonly [
646
+ {
647
+ readonly name: "name";
648
+ readonly type: "string";
649
+ readonly internalType: "string";
650
+ },
651
+ {
652
+ readonly name: "status";
653
+ readonly type: "enum";
654
+ readonly internalType: "status";
655
+ readonly components: readonly [
656
+ {
657
+ readonly name: "pending";
658
+ readonly type: "_";
659
+ },
660
+ {
661
+ readonly name: "complete";
662
+ readonly type: "_";
663
+ },
664
+ {
665
+ readonly name: "failed";
666
+ readonly type: "_";
667
+ },
668
+ ];
669
+ },
670
+ ];
671
+ },
672
+ {
673
+ readonly name: "err";
674
+ readonly type: "string";
675
+ readonly internalType: "string";
676
+ },
677
+ ];
678
+ };
679
+ }>();
680
+ });
681
+
682
+ test("ParseTypes - deeply nested types", () => {
683
+ expectTypeOf<
684
+ ParseTypes<
685
+ [
686
+ "enum color { red, green, blue }",
687
+ "record point { x: u32, y: u32 }",
688
+ "variant shape { circle(u32), colored(color) }",
689
+ "record canvas { shape: shape }",
690
+ ]
691
+ >
692
+ >().toEqualTypeOf<{
693
+ enums: {
694
+ color: readonly ["red", "green", "blue"];
695
+ };
696
+ records: {
697
+ point: readonly [
698
+ {
699
+ readonly name: "x";
700
+ readonly type: "u32";
701
+ readonly internalType: "u32";
702
+ },
703
+ {
704
+ readonly name: "y";
705
+ readonly type: "u32";
706
+ readonly internalType: "u32";
707
+ },
708
+ ];
709
+ canvas: readonly [
710
+ {
711
+ readonly name: "shape";
712
+ readonly type: "variant";
713
+ readonly internalType: "shape";
714
+ readonly components: readonly [
715
+ {
716
+ readonly name: "circle";
717
+ readonly type: "u32";
718
+ readonly internalType: "u32";
719
+ },
720
+ {
721
+ readonly name: "colored";
722
+ readonly type: "enum";
723
+ readonly internalType: "color";
724
+ readonly components: readonly [
725
+ { readonly name: "red"; readonly type: "_" },
726
+ { readonly name: "green"; readonly type: "_" },
727
+ { readonly name: "blue"; readonly type: "_" },
728
+ ];
729
+ },
730
+ ];
731
+ },
732
+ ];
733
+ };
734
+ variants: {
735
+ shape: readonly [
736
+ {
737
+ readonly name: "circle";
738
+ readonly type: "u32";
739
+ readonly internalType: "u32";
740
+ },
741
+ {
742
+ readonly name: "colored";
743
+ readonly type: "enum";
744
+ readonly internalType: "color";
745
+ readonly components: readonly [
746
+ { readonly name: "red"; readonly type: "_" },
747
+ { readonly name: "green"; readonly type: "_" },
748
+ { readonly name: "blue"; readonly type: "_" },
749
+ ];
750
+ },
751
+ ];
752
+ };
753
+ }>();
754
+ });
755
+
756
+ // ============================================================================
757
+ // Circular Reference Tests
758
+ // ============================================================================
759
+
760
+ test("ParseTypes - detects circular record reference", () => {
761
+ expectTypeOf<
762
+ ParseTypes<["record a { b: b }", "record b { a: a }"]>
763
+ >().toEqualTypeOf<{
764
+ records: {
765
+ a: readonly [
766
+ {
767
+ readonly name: "b";
768
+ readonly type: "record";
769
+ readonly internalType: "b";
770
+ readonly components: readonly [
771
+ {
772
+ readonly name: "a";
773
+ readonly type: "record";
774
+ readonly internalType: "a";
775
+ readonly components: readonly [
776
+ ['Error: Circular reference detected at "b".'],
777
+ ];
778
+ },
779
+ ];
780
+ },
781
+ ];
782
+ b: readonly [
783
+ {
784
+ readonly name: "a";
785
+ readonly type: "record";
786
+ readonly internalType: "a";
787
+ readonly components: readonly [
788
+ {
789
+ readonly name: "b";
790
+ readonly type: "record";
791
+ readonly internalType: "b";
792
+ readonly components: readonly [
793
+ ['Error: Circular reference detected at "a".'],
794
+ ];
795
+ },
796
+ ];
797
+ },
798
+ ];
799
+ };
800
+ variants: {};
801
+ enums: ParseEnums<["record a { b: b }", "record b { a: a }"]>;
802
+ }>();
803
+ });
804
+
805
+ test("ParseTypes - detects circular variant reference", () => {
806
+ type T = ParseTypes<["variant a { wraps(b) }", "variant b { wraps(a) }"]>;
807
+
808
+ expectTypeOf<T>().toEqualTypeOf<{
809
+ records: {};
810
+ variants: {
811
+ a: readonly [
812
+ {
813
+ readonly name: "wraps";
814
+ readonly type: "variant";
815
+ readonly internalType: "b";
816
+ readonly components: readonly [
817
+ {
818
+ readonly name: "wraps";
819
+ readonly type: "variant";
820
+ readonly internalType: "a";
821
+ readonly components: readonly [
822
+ ['Error: Circular reference detected at "b".'],
823
+ ];
824
+ },
825
+ ];
826
+ },
827
+ ];
828
+ b: readonly [
829
+ {
830
+ readonly name: "wraps";
831
+ readonly type: "variant";
832
+ readonly internalType: "a";
833
+ readonly components: readonly [
834
+ {
835
+ readonly name: "wraps";
836
+ readonly type: "variant";
837
+ readonly internalType: "b";
838
+ readonly components: readonly [
839
+ ['Error: Circular reference detected at "a".'],
840
+ ];
841
+ },
842
+ ];
843
+ },
844
+ ];
845
+ };
846
+ enums: {};
847
+ }>();
848
+ });
849
+
850
+ test("ParseTypes - detects circular reference across record and variant", () => {
851
+ expectTypeOf<
852
+ ParseTypes<["record r { value: v }", "variant v { wraps(r) }"]>
853
+ >().toMatchTypeOf<{
854
+ records: {
855
+ r: readonly [
856
+ {
857
+ readonly name: "value";
858
+ readonly type: "variant";
859
+ readonly internalType: "v";
860
+ readonly components: readonly [
861
+ {
862
+ readonly name: "wraps";
863
+ readonly type: "record";
864
+ readonly internalType: "r";
865
+ readonly components: readonly [
866
+ ['Error: Circular reference detected at "v".'],
867
+ ];
868
+ },
869
+ ];
870
+ },
871
+ ];
872
+ };
873
+ variants: {
874
+ v: readonly [
875
+ {
876
+ readonly name: "wraps";
877
+ readonly type: "record";
878
+ readonly internalType: "r";
879
+ readonly components: readonly [
880
+ {
881
+ readonly name: "value";
882
+ readonly type: "variant";
883
+ readonly internalType: "v";
884
+ readonly components: readonly [
885
+ ['Error: Circular reference detected at "r".'],
886
+ ];
887
+ },
888
+ ];
889
+ },
890
+ ];
891
+ };
892
+ }>();
893
+ });
894
+
895
+ test("ParseTypes - detects circular reference with enum in the chain", () => {
896
+ expectTypeOf<
897
+ ParseTypes<
898
+ [
899
+ "enum status { pending, complete }",
900
+ "record task { status: status, next: task }",
901
+ ]
902
+ >
903
+ >().toEqualTypeOf<{
904
+ records: {
905
+ task: readonly [
906
+ {
907
+ readonly name: "status";
908
+ readonly type: "enum";
909
+ readonly internalType: "status";
910
+ readonly components: readonly [
911
+ {
912
+ readonly name: "pending";
913
+ readonly type: "_";
914
+ },
915
+ {
916
+ readonly name: "complete";
917
+ readonly type: "_";
918
+ },
919
+ ];
920
+ },
921
+ {
922
+ readonly name: "next";
923
+ readonly type: "record";
924
+ readonly internalType: "task";
925
+ readonly components: readonly [
926
+ {
927
+ readonly name: "status";
928
+ readonly type: "enum";
929
+ readonly internalType: "status";
930
+ readonly components: readonly [
931
+ {
932
+ readonly name: "pending";
933
+ readonly type: "_";
934
+ },
935
+ {
936
+ readonly name: "complete";
937
+ readonly type: "_";
938
+ },
939
+ ];
940
+ },
941
+ ['Error: Circular reference detected at "task".'],
942
+ ];
943
+ },
944
+ ];
945
+ };
946
+ enums: {
947
+ status: readonly ["pending", "complete"];
948
+ };
949
+ variants: {};
950
+ }>();
951
+ });
952
+
953
+ test("ParseTypes - detects multi-level circular reference", () => {
954
+ expectTypeOf<
955
+ ParseTypes<["record a { b: b }", "record b { c: c }", "record c { a: a }"]>
956
+ >().toEqualTypeOf<{
957
+ records: {
958
+ a: readonly [
959
+ {
960
+ readonly name: "b";
961
+ readonly type: "record";
962
+ readonly internalType: "b";
963
+ readonly components: readonly [
964
+ {
965
+ readonly name: "c";
966
+ readonly type: "record";
967
+ readonly internalType: "c";
968
+ readonly components: readonly [
969
+ {
970
+ readonly name: "a";
971
+ readonly type: "record";
972
+ readonly internalType: "a";
973
+ readonly components: readonly [
974
+ ['Error: Circular reference detected at "b".'],
975
+ ];
976
+ },
977
+ ];
978
+ },
979
+ ];
980
+ },
981
+ ];
982
+ b: readonly [
983
+ {
984
+ readonly name: "c";
985
+ readonly type: "record";
986
+ readonly internalType: "c";
987
+ readonly components: readonly [
988
+ {
989
+ readonly name: "a";
990
+ readonly type: "record";
991
+ readonly internalType: "a";
992
+ readonly components: readonly [
993
+ {
994
+ readonly name: "b";
995
+ readonly type: "record";
996
+ readonly internalType: "b";
997
+ readonly components: readonly [
998
+ ['Error: Circular reference detected at "c".'],
999
+ ];
1000
+ },
1001
+ ];
1002
+ },
1003
+ ];
1004
+ },
1005
+ ];
1006
+ c: readonly [
1007
+ {
1008
+ readonly name: "a";
1009
+ readonly type: "record";
1010
+ readonly internalType: "a";
1011
+ readonly components: readonly [
1012
+ {
1013
+ readonly name: "b";
1014
+ readonly type: "record";
1015
+ readonly internalType: "b";
1016
+ readonly components: readonly [
1017
+ {
1018
+ readonly name: "c";
1019
+ readonly type: "record";
1020
+ readonly internalType: "c";
1021
+ readonly components: readonly [
1022
+ ['Error: Circular reference detected at "a".'],
1023
+ ];
1024
+ },
1025
+ ];
1026
+ },
1027
+ ];
1028
+ },
1029
+ ];
1030
+ };
1031
+ variants: {};
1032
+ enums: {};
1033
+ }>();
1034
+ });
1035
+
1036
+ /**
1037
+ * This test file focuses on the specific issue where ParseVariants
1038
+ * doesn't fully resolve record types within variant components.
1039
+ *
1040
+ * The issue: When a variant has a component like `rgb(rgb)` where
1041
+ * the parameter type references a record, ParseVariants should:
1042
+ * 1. Recognize it's a record type (✅ works)
1043
+ * 2. Set internalType to the record name (❌ currently just "record")
1044
+ * 3. Include components with the record's fields (❌ currently missing)
1045
+ */
1046
+
1047
+ test("ParseVariants - should NOT expand records (current behavior)", () => {
1048
+ // This test documents the CURRENT (incorrect) behavior
1049
+ type Result = ParseVariants<
1050
+ [
1051
+ "record rgb { r: u8, g: u8, b: u8 }",
1052
+ "record hsv { h: u16, s: u8, v: u8 }",
1053
+ "variant color { hex(string), rgb(rgb), hsv(hsv), named(string) }",
1054
+ ]
1055
+ >;
1056
+
1057
+ // Currently, ParseVariants doesn't expand the record definitions
1058
+ // It just stores the type name without resolving the fields
1059
+ expectTypeOf<Result>().toEqualTypeOf<{
1060
+ color: readonly [
1061
+ {
1062
+ readonly name: "hex";
1063
+ readonly type: "string";
1064
+ readonly internalType: "string";
1065
+ },
1066
+ {
1067
+ readonly name: "rgb";
1068
+ readonly type: "rgb"; // Just the type name
1069
+ readonly internalType: "rgb";
1070
+ // ❌ Missing: components with r, g, b fields
1071
+ },
1072
+ {
1073
+ readonly name: "hsv";
1074
+ readonly type: "hsv"; // Just the type name
1075
+ readonly internalType: "hsv";
1076
+ // ❌ Missing: components with h, s, v fields
1077
+ },
1078
+ {
1079
+ readonly name: "named";
1080
+ readonly type: "string";
1081
+ readonly internalType: "string";
1082
+ },
1083
+ ];
1084
+ }>();
1085
+ });
1086
+
1087
+ test("ParseTypes - DOES expand records in variants (expected behavior)", () => {
1088
+ // However, ParseTypes (which wraps ParseVariants) DOES expand them
1089
+ type Result = ParseTypes<
1090
+ [
1091
+ "record rgb { r: u8, g: u8, b: u8 }",
1092
+ "record hsv { h: u16, s: u8, v: u8 }",
1093
+ "variant color { hex(string), rgb(rgb), hsv(hsv), named(string) }",
1094
+ ]
1095
+ >;
1096
+
1097
+ // ParseTypes correctly expands the record fields inline
1098
+ expectTypeOf<Result["variants"]["color"]>().toEqualTypeOf<
1099
+ readonly [
1100
+ {
1101
+ readonly name: "hex";
1102
+ readonly type: "string";
1103
+ readonly internalType: "string";
1104
+ },
1105
+ {
1106
+ readonly name: "rgb";
1107
+ readonly type: "record"; // ✅ Becomes "record"
1108
+ readonly internalType: "rgb"; // ✅ Preserves record name
1109
+ readonly components: readonly [
1110
+ // ✅ Has the record fields
1111
+ {
1112
+ readonly name: "r";
1113
+ readonly type: "u8";
1114
+ readonly internalType: "u8";
1115
+ },
1116
+ {
1117
+ readonly name: "g";
1118
+ readonly type: "u8";
1119
+ readonly internalType: "u8";
1120
+ },
1121
+ {
1122
+ readonly name: "b";
1123
+ readonly type: "u8";
1124
+ readonly internalType: "u8";
1125
+ },
1126
+ ];
1127
+ },
1128
+ {
1129
+ readonly name: "hsv";
1130
+ readonly type: "record"; // ✅ Becomes "record"
1131
+ readonly internalType: "hsv"; // ✅ Preserves record name
1132
+ readonly components: readonly [
1133
+ // ✅ Has the record fields
1134
+ {
1135
+ readonly name: "h";
1136
+ readonly type: "u16";
1137
+ readonly internalType: "u16";
1138
+ },
1139
+ {
1140
+ readonly name: "s";
1141
+ readonly type: "u8";
1142
+ readonly internalType: "u8";
1143
+ },
1144
+ {
1145
+ readonly name: "v";
1146
+ readonly type: "u8";
1147
+ readonly internalType: "u8";
1148
+ },
1149
+ ];
1150
+ },
1151
+ {
1152
+ readonly name: "named";
1153
+ readonly type: "string";
1154
+ readonly internalType: "string";
1155
+ },
1156
+ ]
1157
+ >();
1158
+ });
1159
+
1160
+ test("ParseTypes - records in variants are recursively expanded", () => {
1161
+ // This is the same test from user-defined.test.ts that already passes
1162
+ expectTypeOf<
1163
+ ParseTypes<
1164
+ [
1165
+ "record rgb { r: u8, g: u8, b: u8 }",
1166
+ "variant color { hex(string), name(string), rgb(rgb) }",
1167
+ "record palette { primary: color, secondary: color }",
1168
+ ]
1169
+ >
1170
+ >().toEqualTypeOf<{
1171
+ enums: {};
1172
+ records: {
1173
+ rgb: readonly [
1174
+ {
1175
+ readonly name: "r";
1176
+ readonly type: "u8";
1177
+ readonly internalType: "u8";
1178
+ },
1179
+ {
1180
+ readonly name: "g";
1181
+ readonly type: "u8";
1182
+ readonly internalType: "u8";
1183
+ },
1184
+ {
1185
+ readonly name: "b";
1186
+ readonly type: "u8";
1187
+ readonly internalType: "u8";
1188
+ },
1189
+ ];
1190
+ palette: readonly [
1191
+ {
1192
+ readonly name: "primary";
1193
+ readonly type: "variant";
1194
+ readonly internalType: "color";
1195
+ readonly components: readonly [
1196
+ {
1197
+ readonly name: "hex";
1198
+ readonly type: "string";
1199
+ readonly internalType: "string";
1200
+ },
1201
+ {
1202
+ readonly name: "name";
1203
+ readonly type: "string";
1204
+ readonly internalType: "string";
1205
+ },
1206
+ {
1207
+ readonly name: "rgb";
1208
+ readonly type: "record";
1209
+ readonly internalType: "rgb";
1210
+ readonly components: readonly [
1211
+ {
1212
+ readonly name: "r";
1213
+ readonly type: "u8";
1214
+ readonly internalType: "u8";
1215
+ },
1216
+ {
1217
+ readonly name: "g";
1218
+ readonly type: "u8";
1219
+ readonly internalType: "u8";
1220
+ },
1221
+ {
1222
+ readonly name: "b";
1223
+ readonly type: "u8";
1224
+ readonly internalType: "u8";
1225
+ },
1226
+ ];
1227
+ },
1228
+ ];
1229
+ },
1230
+ {
1231
+ readonly name: "secondary";
1232
+ readonly type: "variant";
1233
+ readonly internalType: "color";
1234
+ readonly components: readonly [
1235
+ {
1236
+ readonly name: "hex";
1237
+ readonly type: "string";
1238
+ readonly internalType: "string";
1239
+ },
1240
+ {
1241
+ readonly name: "name";
1242
+ readonly type: "string";
1243
+ readonly internalType: "string";
1244
+ },
1245
+ {
1246
+ readonly name: "rgb";
1247
+ readonly type: "record";
1248
+ readonly internalType: "rgb";
1249
+ readonly components: readonly [
1250
+ {
1251
+ readonly name: "r";
1252
+ readonly type: "u8";
1253
+ readonly internalType: "u8";
1254
+ },
1255
+ {
1256
+ readonly name: "g";
1257
+ readonly type: "u8";
1258
+ readonly internalType: "u8";
1259
+ },
1260
+ {
1261
+ readonly name: "b";
1262
+ readonly type: "u8";
1263
+ readonly internalType: "u8";
1264
+ },
1265
+ ];
1266
+ },
1267
+ ];
1268
+ },
1269
+ ];
1270
+ };
1271
+ variants: {
1272
+ color: readonly [
1273
+ {
1274
+ readonly name: "hex";
1275
+ readonly type: "string";
1276
+ readonly internalType: "string";
1277
+ },
1278
+ {
1279
+ readonly name: "name";
1280
+ readonly type: "string";
1281
+ readonly internalType: "string";
1282
+ },
1283
+ {
1284
+ readonly name: "rgb";
1285
+ readonly type: "record";
1286
+ readonly internalType: "rgb";
1287
+ readonly components: readonly [
1288
+ {
1289
+ readonly name: "r";
1290
+ readonly type: "u8";
1291
+ readonly internalType: "u8";
1292
+ },
1293
+ {
1294
+ readonly name: "g";
1295
+ readonly type: "u8";
1296
+ readonly internalType: "u8";
1297
+ },
1298
+ {
1299
+ readonly name: "b";
1300
+ readonly type: "u8";
1301
+ readonly internalType: "u8";
1302
+ },
1303
+ ];
1304
+ },
1305
+ ];
1306
+ };
1307
+ }>();
1308
+ });