@defold-typescript/types 0.52.0 → 0.54.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 (521) hide show
  1. package/api-signatures.json +2074 -1964
  2. package/dist/cli-runtime.js +8966 -0
  3. package/dist/identity-vocabulary.json +660 -0
  4. package/dist/src/index.d.ts +18 -0
  5. package/examples/translations.json +15 -15
  6. package/fixtures/defold-1.12.4/b2d_body_doc.json +1327 -0
  7. package/fixtures/defold-1.12.4/b2d_doc.json +107 -0
  8. package/fixtures/defold-1.12.4/base_doc.json +758 -0
  9. package/fixtures/defold-1.12.4/bit_doc.json +404 -0
  10. package/fixtures/defold-1.12.4/buffer_doc.json +422 -0
  11. package/fixtures/defold-1.12.4/camera_doc.json +664 -0
  12. package/fixtures/defold-1.12.4/collectionfactory_doc.json +219 -0
  13. package/fixtures/defold-1.12.4/collectionproxy_doc.json +289 -0
  14. package/fixtures/defold-1.12.4/coroutine_doc.json +151 -0
  15. package/fixtures/defold-1.12.4/crash_doc.json +497 -0
  16. package/fixtures/defold-1.12.4/debug_doc.json +410 -0
  17. package/fixtures/defold-1.12.4/factory_doc.json +219 -0
  18. package/fixtures/defold-1.12.4/font_doc.json +141 -0
  19. package/fixtures/defold-1.12.4/globals_doc.json +42 -0
  20. package/fixtures/defold-1.12.4/go-instance-functions.json +111 -0
  21. package/fixtures/defold-1.12.4/go_doc.json +1901 -0
  22. package/fixtures/defold-1.12.4/graphics_doc.json +1634 -0
  23. package/fixtures/defold-1.12.4/gui_doc.json +5249 -0
  24. package/fixtures/defold-1.12.4/html5_doc.json +64 -0
  25. package/fixtures/defold-1.12.4/http_doc.json +66 -0
  26. package/fixtures/defold-1.12.4/image_doc.json +170 -0
  27. package/fixtures/defold-1.12.4/io_doc.json +399 -0
  28. package/fixtures/defold-1.12.4/json_doc.json +97 -0
  29. package/fixtures/defold-1.12.4/label_doc.json +220 -0
  30. package/fixtures/defold-1.12.4/liveupdate_doc.json +308 -0
  31. package/fixtures/defold-1.12.4/math_doc.json +702 -0
  32. package/fixtures/defold-1.12.4/messages_doc.json +579 -0
  33. package/fixtures/defold-1.12.4/model_doc.json +315 -0
  34. package/fixtures/defold-1.12.4/msg_doc.json +137 -0
  35. package/fixtures/defold-1.12.4/os_doc.json +266 -0
  36. package/fixtures/defold-1.12.4/package_doc.json +139 -0
  37. package/fixtures/defold-1.12.4/particlefx_doc.json +249 -0
  38. package/fixtures/defold-1.12.4/physics_doc.json +1120 -0
  39. package/fixtures/defold-1.12.4/profiler_doc.json +375 -0
  40. package/fixtures/defold-1.12.4/render_doc.json +1167 -0
  41. package/fixtures/defold-1.12.4/resource_doc.json +762 -0
  42. package/fixtures/defold-1.12.4/socket_doc.json +2194 -0
  43. package/fixtures/defold-1.12.4/sound_doc.json +582 -0
  44. package/fixtures/defold-1.12.4/sprite_doc.json +245 -0
  45. package/fixtures/defold-1.12.4/string_doc.json +412 -0
  46. package/fixtures/defold-1.12.4/sys_doc.json +853 -0
  47. package/fixtures/defold-1.12.4/table_doc.json +166 -0
  48. package/fixtures/defold-1.12.4/tilemap_doc.json +374 -0
  49. package/fixtures/defold-1.12.4/timer_doc.json +153 -0
  50. package/fixtures/defold-1.12.4/types_doc.json +212 -0
  51. package/fixtures/defold-1.12.4/vmath_doc.json +1814 -0
  52. package/fixtures/defold-1.12.4/window_doc.json +388 -0
  53. package/fixtures/defold-1.12.4/zlib_doc.json +70 -0
  54. package/fixtures/defold-1.13.0/b2d_body_doc.json +2428 -0
  55. package/fixtures/defold-1.13.0/b2d_chain_doc.json +394 -0
  56. package/fixtures/defold-1.13.0/b2d_doc.json +128 -0
  57. package/fixtures/defold-1.13.0/b2d_fixture_doc.json +594 -0
  58. package/fixtures/defold-1.13.0/b2d_joint_doc.json +3315 -0
  59. package/fixtures/defold-1.13.0/b2d_shape_doc.json +802 -0
  60. package/fixtures/defold-1.13.0/b2d_world_doc.json +1314 -0
  61. package/fixtures/defold-1.13.0/base_doc.json +758 -0
  62. package/fixtures/defold-1.13.0/bit_doc.json +404 -0
  63. package/fixtures/defold-1.13.0/buffer_doc.json +422 -0
  64. package/fixtures/defold-1.13.0/camera_doc.json +900 -0
  65. package/fixtures/defold-1.13.0/collectionfactory_doc.json +219 -0
  66. package/fixtures/defold-1.13.0/collectionproxy_doc.json +289 -0
  67. package/fixtures/defold-1.13.0/compute_doc.json +182 -0
  68. package/fixtures/defold-1.13.0/coroutine_doc.json +151 -0
  69. package/fixtures/defold-1.13.0/crash_doc.json +497 -0
  70. package/fixtures/defold-1.13.0/debug_doc.json +410 -0
  71. package/fixtures/defold-1.13.0/editor_doc.json +3665 -0
  72. package/fixtures/defold-1.13.0/editor_http_doc.json +273 -0
  73. package/fixtures/defold-1.13.0/editor_json_doc.json +59 -0
  74. package/fixtures/defold-1.13.0/editor_localization_doc.json +138 -0
  75. package/fixtures/defold-1.13.0/editor_pprint_doc.json +36 -0
  76. package/fixtures/defold-1.13.0/editor_tilemap_tiles_doc.json +235 -0
  77. package/fixtures/defold-1.13.0/editor_zip_doc.json +163 -0
  78. package/fixtures/defold-1.13.0/editor_zlib_doc.json +48 -0
  79. package/fixtures/defold-1.13.0/factory_doc.json +219 -0
  80. package/fixtures/defold-1.13.0/font_doc.json +141 -0
  81. package/fixtures/defold-1.13.0/globals_doc.json +42 -0
  82. package/fixtures/defold-1.13.0/go-instance-functions.json +101 -0
  83. package/fixtures/defold-1.13.0/go_doc.json +1989 -0
  84. package/fixtures/defold-1.13.0/graphics_doc.json +1886 -0
  85. package/fixtures/defold-1.13.0/gui_doc.json +5277 -0
  86. package/fixtures/defold-1.13.0/html5_doc.json +64 -0
  87. package/fixtures/defold-1.13.0/http_doc.json +66 -0
  88. package/fixtures/defold-1.13.0/image_doc.json +170 -0
  89. package/fixtures/defold-1.13.0/import-manifest.json +10558 -0
  90. package/fixtures/defold-1.13.0/io_doc.json +399 -0
  91. package/fixtures/defold-1.13.0/json_doc.json +97 -0
  92. package/fixtures/defold-1.13.0/label_doc.json +220 -0
  93. package/fixtures/defold-1.13.0/liveupdate_doc.json +330 -0
  94. package/fixtures/defold-1.13.0/material_doc.json +238 -0
  95. package/fixtures/defold-1.13.0/math_doc.json +702 -0
  96. package/fixtures/defold-1.13.0/model_doc.json +412 -0
  97. package/fixtures/defold-1.13.0/msg_doc.json +137 -0
  98. package/fixtures/defold-1.13.0/os_doc.json +266 -0
  99. package/fixtures/defold-1.13.0/package_doc.json +139 -0
  100. package/fixtures/defold-1.13.0/particlefx_doc.json +249 -0
  101. package/fixtures/defold-1.13.0/physics_doc.json +1492 -0
  102. package/fixtures/defold-1.13.0/profiler_doc.json +375 -0
  103. package/fixtures/defold-1.13.0/render_doc.json +1381 -0
  104. package/fixtures/defold-1.13.0/resource_doc.json +762 -0
  105. package/fixtures/defold-1.13.0/socket_doc.json +2194 -0
  106. package/fixtures/defold-1.13.0/sound_doc.json +582 -0
  107. package/fixtures/defold-1.13.0/sprite_doc.json +335 -0
  108. package/fixtures/defold-1.13.0/string_doc.json +412 -0
  109. package/fixtures/defold-1.13.0/sys_doc.json +1142 -0
  110. package/fixtures/defold-1.13.0/table_doc.json +166 -0
  111. package/fixtures/defold-1.13.0/tilemap_doc.json +402 -0
  112. package/fixtures/defold-1.13.0/timer_doc.json +153 -0
  113. package/fixtures/defold-1.13.0/types_doc.json +212 -0
  114. package/fixtures/defold-1.13.0/vmath_doc.json +1814 -0
  115. package/fixtures/defold-1.13.0/window_doc.json +388 -0
  116. package/fixtures/defold-1.13.0/zlib_doc.json +70 -0
  117. package/fixtures/defold-1.13.1/b2d_body_doc.json +2428 -0
  118. package/fixtures/defold-1.13.1/b2d_chain_doc.json +394 -0
  119. package/fixtures/defold-1.13.1/b2d_doc.json +128 -0
  120. package/fixtures/defold-1.13.1/b2d_fixture_doc.json +594 -0
  121. package/fixtures/defold-1.13.1/b2d_joint_doc.json +3315 -0
  122. package/fixtures/defold-1.13.1/b2d_shape_doc.json +802 -0
  123. package/fixtures/defold-1.13.1/b2d_world_doc.json +1314 -0
  124. package/fixtures/defold-1.13.1/base_doc.json +758 -0
  125. package/fixtures/defold-1.13.1/bit_doc.json +404 -0
  126. package/fixtures/defold-1.13.1/buffer_doc.json +422 -0
  127. package/fixtures/defold-1.13.1/camera_doc.json +900 -0
  128. package/fixtures/defold-1.13.1/collectionfactory_doc.json +219 -0
  129. package/fixtures/defold-1.13.1/collectionproxy_doc.json +323 -0
  130. package/fixtures/defold-1.13.1/compute_doc.json +182 -0
  131. package/fixtures/defold-1.13.1/coroutine_doc.json +151 -0
  132. package/fixtures/defold-1.13.1/crash_doc.json +497 -0
  133. package/fixtures/defold-1.13.1/debug_doc.json +410 -0
  134. package/fixtures/defold-1.13.1/editor_doc.json +3880 -0
  135. package/fixtures/defold-1.13.1/editor_http_doc.json +273 -0
  136. package/fixtures/defold-1.13.1/editor_image_doc.json +128 -0
  137. package/fixtures/defold-1.13.1/editor_json_doc.json +59 -0
  138. package/fixtures/defold-1.13.1/editor_localization_doc.json +138 -0
  139. package/fixtures/defold-1.13.1/editor_pprint_doc.json +36 -0
  140. package/fixtures/defold-1.13.1/editor_tilemap_tiles_doc.json +235 -0
  141. package/fixtures/defold-1.13.1/editor_zip_doc.json +163 -0
  142. package/fixtures/defold-1.13.1/editor_zlib_doc.json +48 -0
  143. package/fixtures/defold-1.13.1/factory_doc.json +219 -0
  144. package/fixtures/defold-1.13.1/font_doc.json +141 -0
  145. package/fixtures/defold-1.13.1/globals_doc.json +42 -0
  146. package/fixtures/defold-1.13.1/go-instance-functions.json +102 -0
  147. package/fixtures/defold-1.13.1/go_doc.json +1989 -0
  148. package/fixtures/defold-1.13.1/graphics_doc.json +1886 -0
  149. package/fixtures/defold-1.13.1/gui_doc.json +5277 -0
  150. package/fixtures/defold-1.13.1/html5_doc.json +64 -0
  151. package/fixtures/defold-1.13.1/http_doc.json +66 -0
  152. package/fixtures/defold-1.13.1/image_doc.json +170 -0
  153. package/fixtures/defold-1.13.1/import-manifest.json +10091 -0
  154. package/fixtures/defold-1.13.1/io_doc.json +399 -0
  155. package/fixtures/defold-1.13.1/json_doc.json +97 -0
  156. package/fixtures/defold-1.13.1/label_doc.json +220 -0
  157. package/fixtures/defold-1.13.1/liveupdate_doc.json +330 -0
  158. package/fixtures/defold-1.13.1/material_doc.json +238 -0
  159. package/fixtures/defold-1.13.1/math_doc.json +702 -0
  160. package/fixtures/defold-1.13.1/model_doc.json +412 -0
  161. package/fixtures/defold-1.13.1/msg_doc.json +137 -0
  162. package/fixtures/defold-1.13.1/os_doc.json +266 -0
  163. package/fixtures/defold-1.13.1/package_doc.json +139 -0
  164. package/fixtures/defold-1.13.1/particlefx_doc.json +249 -0
  165. package/fixtures/defold-1.13.1/physics_doc.json +1492 -0
  166. package/fixtures/defold-1.13.1/profiler_doc.json +375 -0
  167. package/fixtures/defold-1.13.1/render_doc.json +1381 -0
  168. package/fixtures/defold-1.13.1/resource_doc.json +762 -0
  169. package/fixtures/defold-1.13.1/socket_doc.json +2194 -0
  170. package/fixtures/defold-1.13.1/sound_doc.json +582 -0
  171. package/fixtures/defold-1.13.1/sprite_doc.json +335 -0
  172. package/fixtures/defold-1.13.1/string_doc.json +412 -0
  173. package/fixtures/defold-1.13.1/sys_doc.json +1142 -0
  174. package/fixtures/defold-1.13.1/table_doc.json +166 -0
  175. package/fixtures/defold-1.13.1/tilemap_doc.json +402 -0
  176. package/fixtures/defold-1.13.1/timer_doc.json +153 -0
  177. package/fixtures/defold-1.13.1/types_doc.json +212 -0
  178. package/fixtures/defold-1.13.1/vmath_doc.json +1814 -0
  179. package/fixtures/defold-1.13.1/window_doc.json +388 -0
  180. package/fixtures/defold-1.13.1/zlib_doc.json +70 -0
  181. package/fixtures/defold-1.13.2/b2d_body_doc.json +2359 -0
  182. package/fixtures/defold-1.13.2/b2d_chain_doc.json +395 -0
  183. package/fixtures/defold-1.13.2/b2d_doc.json +1945 -0
  184. package/fixtures/defold-1.13.2/b2d_fixture_doc.json +595 -0
  185. package/fixtures/defold-1.13.2/b2d_joint_doc.json +3178 -0
  186. package/fixtures/defold-1.13.2/b2d_shape_doc.json +767 -0
  187. package/fixtures/defold-1.13.2/b2d_world_doc.json +1315 -0
  188. package/fixtures/defold-1.13.2/base_doc.json +759 -0
  189. package/fixtures/defold-1.13.2/bit_doc.json +405 -0
  190. package/fixtures/defold-1.13.2/buffer_doc.json +393 -0
  191. package/fixtures/defold-1.13.2/bullet3d_collision_object_doc.json +1206 -0
  192. package/fixtures/defold-1.13.2/bullet3d_constraint_doc.json +2455 -0
  193. package/fixtures/defold-1.13.2/bullet3d_doc.json +215 -0
  194. package/fixtures/defold-1.13.2/bullet3d_rigid_body_doc.json +1376 -0
  195. package/fixtures/defold-1.13.2/bullet3d_shape_doc.json +430 -0
  196. package/fixtures/defold-1.13.2/bullet3d_world_doc.json +855 -0
  197. package/fixtures/defold-1.13.2/camera_doc.json +887 -0
  198. package/fixtures/defold-1.13.2/collectionfactory_doc.json +206 -0
  199. package/fixtures/defold-1.13.2/collectionproxy_doc.json +397 -0
  200. package/fixtures/defold-1.13.2/compute_doc.json +183 -0
  201. package/fixtures/defold-1.13.2/coroutine_doc.json +152 -0
  202. package/fixtures/defold-1.13.2/crash_doc.json +483 -0
  203. package/fixtures/defold-1.13.2/debug_doc.json +411 -0
  204. package/fixtures/defold-1.13.2/editor_doc.json +6320 -0
  205. package/fixtures/defold-1.13.2/editor_http_doc.json +476 -0
  206. package/fixtures/defold-1.13.2/editor_image_doc.json +129 -0
  207. package/fixtures/defold-1.13.2/editor_json_doc.json +81 -0
  208. package/fixtures/defold-1.13.2/editor_localization_doc.json +139 -0
  209. package/fixtures/defold-1.13.2/editor_pprint_doc.json +37 -0
  210. package/fixtures/defold-1.13.2/editor_tilemap_tiles_doc.json +292 -0
  211. package/fixtures/defold-1.13.2/editor_zip_doc.json +237 -0
  212. package/fixtures/defold-1.13.2/editor_zlib_doc.json +49 -0
  213. package/fixtures/defold-1.13.2/factory_doc.json +206 -0
  214. package/fixtures/defold-1.13.2/font_doc.json +230 -0
  215. package/fixtures/defold-1.13.2/globals_doc.json +64 -0
  216. package/fixtures/defold-1.13.2/go-instance-functions.json +106 -0
  217. package/fixtures/defold-1.13.2/go_doc.json +1789 -0
  218. package/fixtures/defold-1.13.2/graphics_doc.json +1211 -0
  219. package/fixtures/defold-1.13.2/gui_doc.json +4735 -0
  220. package/fixtures/defold-1.13.2/html5_doc.json +65 -0
  221. package/fixtures/defold-1.13.2/http_doc.json +174 -0
  222. package/fixtures/defold-1.13.2/image_doc.json +298 -0
  223. package/fixtures/defold-1.13.2/import-manifest.json +10902 -0
  224. package/fixtures/defold-1.13.2/io_doc.json +400 -0
  225. package/fixtures/defold-1.13.2/json_doc.json +140 -0
  226. package/fixtures/defold-1.13.2/label_doc.json +427 -0
  227. package/fixtures/defold-1.13.2/liveupdate_doc.json +221 -0
  228. package/fixtures/defold-1.13.2/material_doc.json +773 -0
  229. package/fixtures/defold-1.13.2/math_doc.json +703 -0
  230. package/fixtures/defold-1.13.2/model_doc.json +472 -0
  231. package/fixtures/defold-1.13.2/msg_doc.json +169 -0
  232. package/fixtures/defold-1.13.2/os_doc.json +269 -0
  233. package/fixtures/defold-1.13.2/package_doc.json +140 -0
  234. package/fixtures/defold-1.13.2/particlefx_doc.json +249 -0
  235. package/fixtures/defold-1.13.2/physics_doc.json +1624 -0
  236. package/fixtures/defold-1.13.2/profiler_doc.json +348 -0
  237. package/fixtures/defold-1.13.2/render_doc.json +1623 -0
  238. package/fixtures/defold-1.13.2/resource_doc.json +1539 -0
  239. package/fixtures/defold-1.13.2/socket_doc.json +2335 -0
  240. package/fixtures/defold-1.13.2/sound_doc.json +673 -0
  241. package/fixtures/defold-1.13.2/sprite_doc.json +364 -0
  242. package/fixtures/defold-1.13.2/string_doc.json +413 -0
  243. package/fixtures/defold-1.13.2/sys_doc.json +1347 -0
  244. package/fixtures/defold-1.13.2/table_doc.json +167 -0
  245. package/fixtures/defold-1.13.2/tilemap_doc.json +369 -0
  246. package/fixtures/defold-1.13.2/timer_doc.json +214 -0
  247. package/fixtures/defold-1.13.2/types_doc.json +213 -0
  248. package/fixtures/defold-1.13.2/vmath_doc.json +2056 -0
  249. package/fixtures/defold-1.13.2/window_doc.json +426 -0
  250. package/fixtures/defold-1.13.2/zlib_doc.json +71 -0
  251. package/fixtures/defold-1.14.0/b2d_body_doc.json +2359 -0
  252. package/fixtures/defold-1.14.0/b2d_chain_doc.json +395 -0
  253. package/fixtures/defold-1.14.0/b2d_doc.json +1973 -0
  254. package/fixtures/defold-1.14.0/b2d_fixture_doc.json +595 -0
  255. package/fixtures/defold-1.14.0/b2d_joint_doc.json +3178 -0
  256. package/fixtures/defold-1.14.0/b2d_shape_doc.json +767 -0
  257. package/fixtures/defold-1.14.0/b2d_world_doc.json +1315 -0
  258. package/fixtures/defold-1.14.0/base_doc.json +759 -0
  259. package/fixtures/defold-1.14.0/bit_doc.json +405 -0
  260. package/fixtures/defold-1.14.0/buffer_doc.json +393 -0
  261. package/fixtures/defold-1.14.0/bullet3d_collision_object_doc.json +1206 -0
  262. package/fixtures/defold-1.14.0/bullet3d_constraint_doc.json +2455 -0
  263. package/fixtures/defold-1.14.0/bullet3d_doc.json +243 -0
  264. package/fixtures/defold-1.14.0/bullet3d_rigid_body_doc.json +1376 -0
  265. package/fixtures/defold-1.14.0/bullet3d_shape_doc.json +430 -0
  266. package/fixtures/defold-1.14.0/bullet3d_world_doc.json +855 -0
  267. package/fixtures/defold-1.14.0/camera_doc.json +887 -0
  268. package/fixtures/defold-1.14.0/collectionfactory_doc.json +206 -0
  269. package/fixtures/defold-1.14.0/collectionproxy_doc.json +397 -0
  270. package/fixtures/defold-1.14.0/compute_doc.json +183 -0
  271. package/fixtures/defold-1.14.0/coroutine_doc.json +152 -0
  272. package/fixtures/defold-1.14.0/crash_doc.json +483 -0
  273. package/fixtures/defold-1.14.0/debug_doc.json +411 -0
  274. package/fixtures/defold-1.14.0/editor_doc.json +6320 -0
  275. package/fixtures/defold-1.14.0/editor_http_doc.json +476 -0
  276. package/fixtures/defold-1.14.0/editor_image_doc.json +129 -0
  277. package/fixtures/defold-1.14.0/editor_json_doc.json +81 -0
  278. package/fixtures/defold-1.14.0/editor_localization_doc.json +139 -0
  279. package/fixtures/defold-1.14.0/editor_pprint_doc.json +37 -0
  280. package/fixtures/defold-1.14.0/editor_tilemap_tiles_doc.json +292 -0
  281. package/fixtures/defold-1.14.0/editor_zip_doc.json +237 -0
  282. package/fixtures/defold-1.14.0/editor_zlib_doc.json +49 -0
  283. package/fixtures/defold-1.14.0/factory_doc.json +206 -0
  284. package/fixtures/defold-1.14.0/font_doc.json +230 -0
  285. package/fixtures/defold-1.14.0/globals_doc.json +64 -0
  286. package/fixtures/defold-1.14.0/go-instance-functions.json +106 -0
  287. package/fixtures/defold-1.14.0/go_doc.json +1789 -0
  288. package/fixtures/defold-1.14.0/graphics_doc.json +1257 -0
  289. package/fixtures/defold-1.14.0/gui_doc.json +4735 -0
  290. package/fixtures/defold-1.14.0/html5_doc.json +65 -0
  291. package/fixtures/defold-1.14.0/http_doc.json +174 -0
  292. package/fixtures/defold-1.14.0/image_doc.json +298 -0
  293. package/fixtures/defold-1.14.0/import-manifest.json +10260 -0
  294. package/fixtures/defold-1.14.0/io_doc.json +400 -0
  295. package/fixtures/defold-1.14.0/json_doc.json +140 -0
  296. package/fixtures/defold-1.14.0/label_doc.json +427 -0
  297. package/fixtures/defold-1.14.0/liveupdate_doc.json +221 -0
  298. package/fixtures/defold-1.14.0/material_doc.json +773 -0
  299. package/fixtures/defold-1.14.0/math_doc.json +703 -0
  300. package/fixtures/defold-1.14.0/model_doc.json +472 -0
  301. package/fixtures/defold-1.14.0/msg_doc.json +169 -0
  302. package/fixtures/defold-1.14.0/os_doc.json +269 -0
  303. package/fixtures/defold-1.14.0/package_doc.json +140 -0
  304. package/fixtures/defold-1.14.0/particlefx_doc.json +249 -0
  305. package/fixtures/defold-1.14.0/physics_doc.json +1624 -0
  306. package/fixtures/defold-1.14.0/profiler_doc.json +348 -0
  307. package/fixtures/defold-1.14.0/render_doc.json +1628 -0
  308. package/fixtures/defold-1.14.0/resource_doc.json +1539 -0
  309. package/fixtures/defold-1.14.0/socket_doc.json +2335 -0
  310. package/fixtures/defold-1.14.0/sound_doc.json +673 -0
  311. package/fixtures/defold-1.14.0/sprite_doc.json +364 -0
  312. package/fixtures/defold-1.14.0/string_doc.json +413 -0
  313. package/fixtures/defold-1.14.0/sys_doc.json +1347 -0
  314. package/fixtures/defold-1.14.0/table_doc.json +167 -0
  315. package/fixtures/defold-1.14.0/tilemap_doc.json +369 -0
  316. package/fixtures/defold-1.14.0/timer_doc.json +214 -0
  317. package/fixtures/defold-1.14.0/types_doc.json +213 -0
  318. package/fixtures/defold-1.14.0/vmath_doc.json +2056 -0
  319. package/fixtures/defold-1.14.0/window_doc.json +426 -0
  320. package/fixtures/defold-1.14.0/zlib_doc.json +71 -0
  321. package/generated/b2d.d.ts +39 -39
  322. package/generated/b2d_body.d.ts +11 -11
  323. package/generated/b2d_chain.d.ts +3 -3
  324. package/generated/b2d_fixture.d.ts +5 -5
  325. package/generated/b2d_joint.d.ts +29 -29
  326. package/generated/b2d_shape.d.ts +13 -13
  327. package/generated/b2d_world.d.ts +15 -15
  328. package/generated/buffer.d.ts +5 -6
  329. package/generated/bullet3d.d.ts +6 -6
  330. package/generated/bullet3d_collision_object.d.ts +9 -9
  331. package/generated/bullet3d_constraint.d.ts +78 -78
  332. package/generated/bullet3d_rigid_body.d.ts +3 -3
  333. package/generated/bullet3d_shape.d.ts +11 -11
  334. package/generated/bullet3d_world.d.ts +20 -20
  335. package/generated/camera.d.ts +4 -4
  336. package/generated/collectionfactory.d.ts +2 -3
  337. package/generated/collectionproxy.d.ts +5 -5
  338. package/generated/compute.d.ts +5 -5
  339. package/generated/crash.d.ts +7 -7
  340. package/generated/editor-vm/http.d.ts +13 -13
  341. package/generated/editor-vm/image.d.ts +4 -4
  342. package/generated/editor-vm/json.d.ts +1 -1
  343. package/generated/editor-vm/tilemap_tiles.d.ts +9 -9
  344. package/generated/editor-vm/zip.d.ts +4 -4
  345. package/generated/editor.d.ts +183 -183
  346. package/generated/factory.d.ts +2 -3
  347. package/generated/font.d.ts +4 -4
  348. package/generated/go.d.ts +10 -12
  349. package/generated/graphics.d.ts +23 -26
  350. package/generated/gui.d.ts +44 -58
  351. package/generated/http.d.ts +2 -2
  352. package/generated/image.d.ts +12 -12
  353. package/generated/json.d.ts +4 -4
  354. package/generated/label.d.ts +5 -5
  355. package/generated/liveupdate.d.ts +3 -3
  356. package/generated/material.d.ts +48 -48
  357. package/generated/model.d.ts +46 -14
  358. package/generated/particlefx.d.ts +5 -5
  359. package/generated/physics.d.ts +19 -19
  360. package/generated/profiler.d.ts +3 -5
  361. package/generated/render-script-modules/b2d.d.ts +39 -39
  362. package/generated/render-script-modules/bullet3d.d.ts +5 -5
  363. package/generated/render-script-modules/collectionfactory.d.ts +1 -2
  364. package/generated/render-script-modules/collectionproxy.d.ts +3 -3
  365. package/generated/render-script-modules/factory.d.ts +1 -2
  366. package/generated/render-script-modules/go.d.ts +8 -10
  367. package/generated/render-script-modules/label.d.ts +2 -2
  368. package/generated/render-script-modules/model.d.ts +43 -11
  369. package/generated/render-script-modules/particlefx.d.ts +3 -3
  370. package/generated/render-script-modules/physics.d.ts +12 -12
  371. package/generated/render-script-modules/resource.d.ts +52 -53
  372. package/generated/render-script-modules/sound.d.ts +4 -4
  373. package/generated/render-script-modules/sprite.d.ts +2 -2
  374. package/generated/render-script-modules/tilemap.d.ts +2 -2
  375. package/generated/render.d.ts +44 -45
  376. package/generated/resource.d.ts +58 -59
  377. package/generated/socket.d.ts +18 -23
  378. package/generated/sound.d.ts +6 -6
  379. package/generated/sprite.d.ts +3 -3
  380. package/generated/sys.d.ts +20 -21
  381. package/generated/tilemap.d.ts +3 -3
  382. package/generated/timer.d.ts +3 -3
  383. package/generated/versions/defold-1.12.4/b2d.d.ts +2 -2
  384. package/generated/versions/defold-1.12.4/b2d_body.d.ts +2 -2
  385. package/generated/versions/defold-1.12.4/go.d.ts +2 -2
  386. package/generated/versions/defold-1.12.4/graphics.d.ts +1 -1
  387. package/generated/versions/defold-1.12.4/gui.d.ts +18 -19
  388. package/generated/versions/defold-1.12.4/label.d.ts +1 -1
  389. package/generated/versions/defold-1.12.4/model.d.ts +42 -10
  390. package/generated/versions/defold-1.12.4/particlefx.d.ts +1 -1
  391. package/generated/versions/defold-1.12.4/physics.d.ts +1 -1
  392. package/generated/versions/defold-1.12.4/render.d.ts +5 -5
  393. package/generated/versions/defold-1.12.4/resource.d.ts +8 -8
  394. package/generated/versions/defold-1.12.4/socket.d.ts +12 -12
  395. package/generated/versions/defold-1.12.4/sound.d.ts +1 -1
  396. package/generated/versions/defold-1.12.4/sprite.d.ts +1 -1
  397. package/generated/versions/defold-1.12.4/sys.d.ts +2 -2
  398. package/generated/versions/defold-1.12.4/tilemap.d.ts +1 -1
  399. package/generated/versions/defold-1.12.4/window.d.ts +3 -4
  400. package/generated/versions/defold-1.13.0/b2d.d.ts +2 -2
  401. package/generated/versions/defold-1.13.0/b2d_body.d.ts +2 -2
  402. package/generated/versions/defold-1.13.0/b2d_chain.d.ts +1 -1
  403. package/generated/versions/defold-1.13.0/b2d_joint.d.ts +1 -1
  404. package/generated/versions/defold-1.13.0/b2d_shape.d.ts +1 -1
  405. package/generated/versions/defold-1.13.0/camera.d.ts +1 -1
  406. package/generated/versions/defold-1.13.0/go.d.ts +2 -2
  407. package/generated/versions/defold-1.13.0/graphics.d.ts +1 -1
  408. package/generated/versions/defold-1.13.0/gui.d.ts +18 -19
  409. package/generated/versions/defold-1.13.0/label.d.ts +1 -1
  410. package/generated/versions/defold-1.13.0/model.d.ts +42 -10
  411. package/generated/versions/defold-1.13.0/particlefx.d.ts +1 -1
  412. package/generated/versions/defold-1.13.0/physics.d.ts +1 -1
  413. package/generated/versions/defold-1.13.0/render.d.ts +5 -5
  414. package/generated/versions/defold-1.13.0/resource.d.ts +8 -8
  415. package/generated/versions/defold-1.13.0/socket.d.ts +12 -12
  416. package/generated/versions/defold-1.13.0/sound.d.ts +1 -1
  417. package/generated/versions/defold-1.13.0/sprite.d.ts +1 -1
  418. package/generated/versions/defold-1.13.0/sys.d.ts +2 -2
  419. package/generated/versions/defold-1.13.0/tilemap.d.ts +1 -1
  420. package/generated/versions/defold-1.13.0/window.d.ts +3 -4
  421. package/generated/versions/defold-1.13.1/b2d.d.ts +2 -2
  422. package/generated/versions/defold-1.13.1/b2d_body.d.ts +2 -2
  423. package/generated/versions/defold-1.13.1/b2d_chain.d.ts +1 -1
  424. package/generated/versions/defold-1.13.1/b2d_joint.d.ts +1 -1
  425. package/generated/versions/defold-1.13.1/b2d_shape.d.ts +1 -1
  426. package/generated/versions/defold-1.13.1/camera.d.ts +1 -1
  427. package/generated/versions/defold-1.13.1/go.d.ts +2 -2
  428. package/generated/versions/defold-1.13.1/graphics.d.ts +1 -1
  429. package/generated/versions/defold-1.13.1/gui.d.ts +18 -19
  430. package/generated/versions/defold-1.13.1/label.d.ts +1 -1
  431. package/generated/versions/defold-1.13.1/model.d.ts +42 -10
  432. package/generated/versions/defold-1.13.1/particlefx.d.ts +1 -1
  433. package/generated/versions/defold-1.13.1/physics.d.ts +1 -1
  434. package/generated/versions/defold-1.13.1/render.d.ts +5 -5
  435. package/generated/versions/defold-1.13.1/resource.d.ts +8 -8
  436. package/generated/versions/defold-1.13.1/socket.d.ts +12 -12
  437. package/generated/versions/defold-1.13.1/sound.d.ts +1 -1
  438. package/generated/versions/defold-1.13.1/sprite.d.ts +1 -1
  439. package/generated/versions/defold-1.13.1/sys.d.ts +2 -2
  440. package/generated/versions/defold-1.13.1/tilemap.d.ts +1 -1
  441. package/generated/versions/defold-1.13.1/window.d.ts +3 -4
  442. package/generated/versions/defold-1.13.2/b2d.d.ts +39 -39
  443. package/generated/versions/defold-1.13.2/b2d_body.d.ts +11 -11
  444. package/generated/versions/defold-1.13.2/b2d_chain.d.ts +3 -3
  445. package/generated/versions/defold-1.13.2/b2d_fixture.d.ts +5 -5
  446. package/generated/versions/defold-1.13.2/b2d_joint.d.ts +29 -29
  447. package/generated/versions/defold-1.13.2/b2d_shape.d.ts +13 -13
  448. package/generated/versions/defold-1.13.2/b2d_world.d.ts +15 -15
  449. package/generated/versions/defold-1.13.2/buffer.d.ts +5 -6
  450. package/generated/versions/defold-1.13.2/bullet3d.d.ts +6 -6
  451. package/generated/versions/defold-1.13.2/bullet3d_collision_object.d.ts +9 -9
  452. package/generated/versions/defold-1.13.2/bullet3d_constraint.d.ts +78 -78
  453. package/generated/versions/defold-1.13.2/bullet3d_rigid_body.d.ts +3 -3
  454. package/generated/versions/defold-1.13.2/bullet3d_shape.d.ts +11 -11
  455. package/generated/versions/defold-1.13.2/bullet3d_world.d.ts +20 -20
  456. package/generated/versions/defold-1.13.2/camera.d.ts +4 -4
  457. package/generated/versions/defold-1.13.2/collectionfactory.d.ts +2 -3
  458. package/generated/versions/defold-1.13.2/collectionproxy.d.ts +5 -5
  459. package/generated/versions/defold-1.13.2/compute.d.ts +5 -5
  460. package/generated/versions/defold-1.13.2/crash.d.ts +7 -7
  461. package/generated/versions/defold-1.13.2/editor-vm/http.d.ts +13 -13
  462. package/generated/versions/defold-1.13.2/editor-vm/image.d.ts +4 -4
  463. package/generated/versions/defold-1.13.2/editor-vm/json.d.ts +1 -1
  464. package/generated/versions/defold-1.13.2/editor-vm/tilemap_tiles.d.ts +9 -9
  465. package/generated/versions/defold-1.13.2/editor-vm/zip.d.ts +4 -4
  466. package/generated/versions/defold-1.13.2/editor.d.ts +183 -183
  467. package/generated/versions/defold-1.13.2/factory.d.ts +2 -3
  468. package/generated/versions/defold-1.13.2/font.d.ts +4 -4
  469. package/generated/versions/defold-1.13.2/go.d.ts +10 -12
  470. package/generated/versions/defold-1.13.2/graphics.d.ts +22 -25
  471. package/generated/versions/defold-1.13.2/gui.d.ts +44 -58
  472. package/generated/versions/defold-1.13.2/http.d.ts +2 -2
  473. package/generated/versions/defold-1.13.2/image.d.ts +12 -12
  474. package/generated/versions/defold-1.13.2/json.d.ts +4 -4
  475. package/generated/versions/defold-1.13.2/label.d.ts +5 -5
  476. package/generated/versions/defold-1.13.2/liveupdate.d.ts +3 -3
  477. package/generated/versions/defold-1.13.2/material.d.ts +48 -48
  478. package/generated/versions/defold-1.13.2/model.d.ts +46 -14
  479. package/generated/versions/defold-1.13.2/particlefx.d.ts +5 -5
  480. package/generated/versions/defold-1.13.2/physics.d.ts +19 -19
  481. package/generated/versions/defold-1.13.2/profiler.d.ts +3 -5
  482. package/generated/versions/defold-1.13.2/render.d.ts +43 -44
  483. package/generated/versions/defold-1.13.2/resource.d.ts +58 -59
  484. package/generated/versions/defold-1.13.2/socket.d.ts +18 -23
  485. package/generated/versions/defold-1.13.2/sound.d.ts +6 -6
  486. package/generated/versions/defold-1.13.2/sprite.d.ts +3 -3
  487. package/generated/versions/defold-1.13.2/sys.d.ts +20 -21
  488. package/generated/versions/defold-1.13.2/tilemap.d.ts +3 -3
  489. package/generated/versions/defold-1.13.2/timer.d.ts +3 -3
  490. package/generated/versions/defold-1.13.2/vmath.d.ts +0 -1
  491. package/generated/versions/defold-1.13.2/window.d.ts +8 -10
  492. package/generated/vmath.d.ts +0 -1
  493. package/generated/window.d.ts +8 -10
  494. package/identity-vocabulary.json +41 -34
  495. package/package.json +13 -5
  496. package/scripts/cli-runtime.ts +18 -0
  497. package/scripts/example-store-io.ts +2 -2
  498. package/scripts/extension-goldens.ts +9 -5
  499. package/scripts/generate-api-availability.ts +10 -4
  500. package/scripts/generate-api-signatures.ts +1 -1
  501. package/scripts/import-defold-release.ts +1 -1
  502. package/scripts/regen.ts +35 -9
  503. package/scripts/shared-handle-methods.ts +3 -2
  504. package/scripts/signature-store-fs.ts +37 -17
  505. package/scripts/sync-api-docs.ts +127 -20
  506. package/src/api-doc.ts +19 -4
  507. package/src/api-identity.ts +32 -1
  508. package/src/component-properties.d.ts +8 -8
  509. package/src/core-types.ts +29 -13
  510. package/src/doc-corrections.ts +9 -0
  511. package/src/emit-dts.ts +770 -214
  512. package/src/engine-type-name.ts +33 -0
  513. package/src/go-overloads.d.ts +10 -10
  514. package/src/gui-overloads.d.ts +11 -11
  515. package/src/index-slot-classifications.ts +75 -9
  516. package/src/index.ts +4 -1
  517. package/src/lifecycle.ts +2 -2
  518. package/src/publish-dts.ts +16 -0
  519. package/src/script-api.ts +36 -38
  520. package/src/socket-types.d.ts +3 -3
  521. package/src/library-index-slot-classifications.ts +0 -332
package/src/emit-dts.ts CHANGED
@@ -15,7 +15,7 @@ import type {
15
15
  ApiTypedef,
16
16
  ApiVariable,
17
17
  } from "./api-doc";
18
- import { DEFOLD_TYPE_MAP } from "./core-types";
18
+ import { DEFOLD_TYPE_MAP, SOCKET_HANDLE_NAMES, type SocketHandleReceiver } from "./core-types";
19
19
  import { correctionPins, pinMatches, propertyCorrectionPins } from "./correction-pins";
20
20
  import {
21
21
  type DocCommentParts,
@@ -26,6 +26,7 @@ import {
26
26
  summaryFor,
27
27
  } from "./doc-comment";
28
28
  import { applyMessageOverlays, parseMessagesDoc } from "./emit-messages";
29
+ import { engineTypeName } from "./engine-type-name";
29
30
  import type { TranslationStore } from "./example-store";
30
31
  import { lookupExampleSegments, translateProseFences } from "./example-store";
31
32
  import {
@@ -73,6 +74,11 @@ export interface EmitOptions {
73
74
  // map; a library or extension declaration passes its page keys (`[]` for one
74
75
  // no page documents), so it never names Defold as the receiver.
75
76
  indexBaseSource?: IndexBaseSource;
77
+ // Whether the module declares the `CONSTANT_UNION_ALIASES` rows homed in its
78
+ // namespace. Defaults to `true`; an extension declaring an engine namespace
79
+ // passes `false`, so it never re-declares an alias the engine module already
80
+ // declares, while its signatures still spell `gui.Playback`.
81
+ ownsConstantUnionAliases?: boolean;
76
82
  // The TS path of each `ENUM`, `STRUCT` and `TYPEDEF` another module declares
77
83
  // (`declaredTypePaths`), so a token naming one resolves instead of widening to
78
84
  // `unknown`. The module's own declarations resolve without it. Read only by the
@@ -87,9 +93,10 @@ export interface EmitOptions {
87
93
  // bindings (a ref-doc target), where every entry the ref-doc omits is emitted.
88
94
  registeredConstants?: ReadonlySet<string>;
89
95
  // The `RETURN_TYPE_CORRECTIONS` and `STRUCT_MEMBER_ADDITIONS` keys whose binding
90
- // pin holds in the target's vendored engine source. A binding-pinned entry
91
- // applies only when its key is here, so a surface with no vendored bindings
92
- // (absent) applies none of them.
96
+ // pin holds in the target's vendored engine source, and the
97
+ // `PROPERTY_KEY_RANGES` keys whose `engine` pins all hold there. A pinned
98
+ // entry applies only when its key is here, so a surface with no vendored
99
+ // bindings (absent) applies none of them.
93
100
  bindingEvidence?: ReadonlySet<string>;
94
101
  // The 1-based parameter slots, keyed by function FQN, that the target's engine
95
102
  // bindings let a call omit but raise on when passed nil. Each optional one
@@ -203,9 +210,10 @@ export const ARBITRARY_TABLE_SLOTS = new Set([
203
210
  // crash.get_modules is "module table".
204
211
  "crash.get_backtrace",
205
212
  "crash.get_modules",
206
- // platform-specific options: the doc is a dead backtick-prose cross-ref to a
207
- // sibling whose function is absent from the fixture (webview.open is not
208
- // documented), so no machine-readable shape exists.
213
+ // platform-specific options: the doc is a backtick-prose cross-ref to
214
+ // webview.open, whose options are documented as structured `.script_api`
215
+ // fields rather than a prose field list, so the cross-reference resolver (which
216
+ // reads a sibling's prose only) finds no machine-readable shape here.
209
217
  "webview.open_raw",
210
218
  // OS-resolver returns: the shape is set by the host resolver, not Defold's
211
219
  // API contract; each fixture doc reads "a table with all information
@@ -554,7 +562,7 @@ export const RETURN_TYPE_CORRECTIONS: ReadonlyMap<string, ReturnTypeCorrection>
554
562
  [
555
563
  "bullet3d.shape.get_shape",
556
564
  {
557
- ts: "bullet3d.shape.definition | { type: typeof bullet3d.shape.SHAPE_TYPE_MESH }",
565
+ ts: "bullet3d.shape.Definition | { type: typeof bullet3d.shape.SHAPE_TYPE_MESH }",
558
566
  upstream: ["bullet3d.shape.definition"],
559
567
  reason:
560
568
  "script_bullet3d_shape.cpp:Shape_GetShape sets only `type` for a triangle mesh, which no shape definition arm matches",
@@ -658,6 +666,36 @@ export const RETURN_TYPE_CORRECTIONS: ReadonlyMap<string, ReturnTypeCorrection>
658
666
  },
659
667
  ] as const,
660
668
  ),
669
+ [
670
+ "gui.get_xanchor",
671
+ {
672
+ ts: "Exclude<gui.Anchor, typeof gui.ANCHOR_BOTTOM | typeof gui.ANCHOR_TOP>",
673
+ upstream: ["constant"],
674
+ retypedUpstream: [["gui.ANCHOR"]],
675
+ reason:
676
+ "gui_script.cpp:LuaGetXAnchor pushes GetNodeXAnchor, an x anchor: XANCHOR_NONE, XANCHOR_LEFT, or XANCHOR_RIGHT",
677
+ binding: {
678
+ file: "gui/src/gui_script.cpp",
679
+ cFunction: "LuaGetXAnchor",
680
+ contains: "lua_pushnumber(L, GetNodeXAnchor(scene, hnode));",
681
+ },
682
+ },
683
+ ],
684
+ [
685
+ "gui.get_yanchor",
686
+ {
687
+ ts: "Exclude<gui.Anchor, typeof gui.ANCHOR_LEFT | typeof gui.ANCHOR_RIGHT>",
688
+ upstream: ["constant"],
689
+ retypedUpstream: [["gui.ANCHOR"]],
690
+ reason:
691
+ "gui_script.cpp:LuaGetYAnchor pushes GetNodeYAnchor, a y anchor: YANCHOR_NONE, YANCHOR_TOP, or YANCHOR_BOTTOM",
692
+ binding: {
693
+ file: "gui/src/gui_script.cpp",
694
+ cFunction: "LuaGetYAnchor",
695
+ contains: "lua_pushnumber(L, GetNodeYAnchor(scene, hnode));",
696
+ },
697
+ },
698
+ ],
661
699
  ]);
662
700
 
663
701
  // A parameter whose declared `types` disagree with what the same element's
@@ -665,23 +703,29 @@ export const RETURN_TYPE_CORRECTIONS: ReadonlyMap<string, ReturnTypeCorrection>
665
703
  // target by resource name, a texture unit, a Lua sequence where `table` is
666
704
  // declared, a hash the binding refuses as a string. Admission rule: only a slot
667
705
  // that evidence contradicts; a slot that is merely imprecise is not a candidate.
668
- // The correction edits the mapped union rather than replacing it: `adds` appends
669
- // what the slot also takes and `removes` drops members the binding raises on, so
670
- // the URL address alias, array curation and constant mapping stay live, and
671
- // optionality stays with `isDocOptional`. Each entry records the upstream tokens
672
- // it contradicts, plus any later spelling of the same defect in
673
- // `retypedUpstream`, and applies only to a slot still declaring one of them;
674
- // `param-correction-provenance.test.ts` pins them against every retained
675
- // vendored ref-doc. Once no retained target still declares any of them the
676
- // entry is deleted, never re-pinned.
677
- export interface ParamTypeCorrection {
678
- readonly adds?: string;
679
- readonly removes?: readonly string[];
706
+ // A correction either replaces the mapped type exactly with `ts`, or edits the
707
+ // mapped union: `adds` appends what the slot also takes and `removes` drops
708
+ // members the binding raises on. Union edits keep the URL address alias, array
709
+ // curation and constant mapping live; optionality stays with `isDocOptional`.
710
+ // Each entry records the upstream tokens it contradicts, plus any later spelling
711
+ // of the same defect in `retypedUpstream`, and applies only to a slot still
712
+ // declaring one of them. An entry with a `binding` also requires its exact
713
+ // `EmitOptions.bindingEvidence` key. `param-correction-provenance.test.ts` pins
714
+ // the ref-doc tokens against every retained target; once no target declares a
715
+ // pin, the entry is deleted rather than re-pinned.
716
+ interface ParamTypeCorrectionBase {
680
717
  readonly upstream: readonly string[];
681
718
  readonly retypedUpstream?: readonly (readonly string[])[];
682
719
  readonly reason: string;
720
+ readonly binding?: BindingPin;
683
721
  }
684
722
 
723
+ export type ParamTypeCorrection = ParamTypeCorrectionBase &
724
+ (
725
+ | { readonly ts: string; readonly adds?: undefined; readonly removes?: undefined }
726
+ | { readonly ts?: undefined; readonly adds?: string; readonly removes?: readonly string[] }
727
+ );
728
+
685
729
  const CAMERA_ADDRESS_REASON =
686
730
  "render_script_camera.cpp:CheckRenderCamera resolves anything but a number handle through ResolveURL, which takes a string or a hash";
687
731
 
@@ -715,6 +759,58 @@ export const PARAM_TYPE_CORRECTIONS: ReadonlyMap<string, ParamTypeCorrection> =
715
759
  string,
716
760
  ParamTypeCorrection
717
761
  >([
762
+ [
763
+ "gui.set_xanchor:param:anchor",
764
+ {
765
+ ts: "Exclude<gui.Anchor, typeof gui.ANCHOR_BOTTOM | typeof gui.ANCHOR_TOP>",
766
+ upstream: ["constant"],
767
+ retypedUpstream: [["gui.ANCHOR"]],
768
+ reason:
769
+ "gui_script.cpp:LuaSetXAnchor rejects every value except XANCHOR_NONE, XANCHOR_LEFT, and XANCHOR_RIGHT",
770
+ binding: {
771
+ file: "gui/src/gui_script.cpp",
772
+ cFunction: "LuaSetXAnchor",
773
+ contains: "anchor != XANCHOR_NONE && anchor != XANCHOR_LEFT && anchor != XANCHOR_RIGHT",
774
+ },
775
+ },
776
+ ],
777
+ [
778
+ "gui.set_yanchor:param:anchor",
779
+ {
780
+ ts: "Exclude<gui.Anchor, typeof gui.ANCHOR_LEFT | typeof gui.ANCHOR_RIGHT>",
781
+ upstream: ["constant"],
782
+ retypedUpstream: [["gui.ANCHOR"]],
783
+ reason:
784
+ "gui_script.cpp:LuaSetYAnchor rejects every value except YANCHOR_NONE, YANCHOR_TOP, and YANCHOR_BOTTOM",
785
+ binding: {
786
+ file: "gui/src/gui_script.cpp",
787
+ cFunction: "LuaSetYAnchor",
788
+ contains: "anchor != YANCHOR_NONE && anchor != YANCHOR_TOP && anchor != YANCHOR_BOTTOM",
789
+ },
790
+ },
791
+ ],
792
+ [
793
+ "go.animate:param:playback",
794
+ {
795
+ ts: "go.Playback",
796
+ upstream: [
797
+ "go.PLAYBACK_ONCE_FORWARD",
798
+ "go.PLAYBACK_ONCE_BACKWARD",
799
+ "go.PLAYBACK_ONCE_PINGPONG",
800
+ "go.PLAYBACK_LOOP_FORWARD",
801
+ "go.PLAYBACK_LOOP_BACKWARD",
802
+ "go.PLAYBACK_LOOP_PINGPONG",
803
+ ],
804
+ retypedUpstream: [["go.PLAYBACK"]],
805
+ reason:
806
+ "gameobject_script.cpp:Script_Animate accepts every playback value below PLAYBACK_COUNT, including PLAYBACK_NONE",
807
+ binding: {
808
+ file: "gameobject/src/gameobject/gameobject_script.cpp",
809
+ cFunction: "Script_Animate",
810
+ contains: "if (playback >= PLAYBACK_COUNT)",
811
+ },
812
+ },
813
+ ],
718
814
  ...CAMERA_SLOT_FUNCTIONS.map(
719
815
  (name) =>
720
816
  [
@@ -921,8 +1017,8 @@ export const PARAM_TYPE_CORRECTIONS: ReadonlyMap<string, ParamTypeCorrection> =
921
1017
  [
922
1018
  `render.${name}:param:state`,
923
1019
  {
924
- adds: "graphics.State",
925
- removes: ["graphics.STATE"],
1020
+ adds: "Exclude<graphics.State, typeof graphics.STATE_ALPHA_TEST_SUPPORTED | typeof graphics.STATE_SCISSOR_TEST>",
1021
+ removes: ["graphics.State"],
926
1022
  upstream: ["graphics.STATE"],
927
1023
  reason: `render_script.cpp:RenderScript_${name === "enable_state" ? "Enable" : "Disable"}State raises "Invalid state" on any state but the six it lists, so graphics.STATE_SCISSOR_TEST and graphics.STATE_ALPHA_TEST_SUPPORTED are rejected`,
928
1024
  },
@@ -997,8 +1093,8 @@ export const PARAM_TYPE_CORRECTIONS: ReadonlyMap<string, ParamTypeCorrection> =
997
1093
  [
998
1094
  "window.set_dim_mode:param:mode",
999
1095
  {
1000
- removes: ["window.DIMMING"],
1001
- adds: "window.DimModeStateSettable",
1096
+ removes: ["window.Dimming"],
1097
+ adds: "Exclude<window.Dimming, typeof window.DIMMING_UNKNOWN>",
1002
1098
  upstream: ["window.DIMMING"],
1003
1099
  reason:
1004
1100
  'script_window.cpp:SetDimMode raises "The dim mode specified is not supported." for anything but DIMMING_ON and DIMMING_OFF',
@@ -1100,16 +1196,70 @@ export const PROPERTY_TYPE_CORRECTIONS: ReadonlyMap<string, PropertyTypeCorrecti
1100
1196
  // saying it, or when the phrase stops stating `first-last`. Curated rather than
1101
1197
  // matched on a trailing `N`, so each new upstream placeholder is a deliberate
1102
1198
  // addition.
1199
+ //
1200
+ // `engine.last` replaces `last` on a target whose vendored engine source shows
1201
+ // every one of `engine.pins` (the `EmitOptions.bindingEvidence` keys); every
1202
+ // other surface, including one generated from a ref-doc alone, keeps the range
1203
+ // `evidence` states.
1103
1204
  export interface PropertyKeyRange {
1104
1205
  readonly prefix: string;
1105
1206
  readonly first: number;
1106
1207
  readonly last: number;
1107
1208
  readonly evidence: string;
1209
+ readonly engine?: { readonly last: number; readonly pins: readonly EngineSourcePin[] };
1108
1210
  }
1109
1211
 
1110
- // Keyed `<namespace>.<property>`, mirroring PROPERTY_TYPE_CORRECTIONS.
1212
+ // A token snippet the target's vendored engine evidence must contain. With
1213
+ // `cFunction` it is matched in that function's body, without it anywhere in
1214
+ // the file.
1215
+ export interface EngineSourcePin {
1216
+ // Relative to the target's vendored `engine/` tree, as `BindingPin.file` is.
1217
+ readonly file: string;
1218
+ readonly cFunction?: string;
1219
+ readonly contains: string;
1220
+ }
1221
+
1222
+ const MODEL_TEXTURE_LOOP =
1223
+ "for (uint32_t i = 0; i < dmRender::RenderObject::MAX_TEXTURE_COUNT; ++i) { if (params.m_PropertyId == PROP_TEXTURE[i])";
1224
+
1225
+ // Keyed `<namespace>.<property>`, mirroring PROPERTY_TYPE_CORRECTIONS; a key
1226
+ // with an `engine` field is also an `EmitOptions.bindingEvidence` key.
1111
1227
  export const PROPERTY_KEY_RANGES: ReadonlyMap<string, PropertyKeyRange> = new Map([
1112
- ["model.textureN", { prefix: "texture", first: 0, last: 7, evidence: "textureN where N is 0-7" }],
1228
+ [
1229
+ "model.textureN",
1230
+ {
1231
+ prefix: "texture",
1232
+ first: 0,
1233
+ last: 7,
1234
+ evidence: "textureN where N is 0-7",
1235
+ engine: {
1236
+ last: 15,
1237
+ pins: [
1238
+ {
1239
+ file: "render/src/dmsdk/render/render.h",
1240
+ contains: "static const uint32_t MAX_TEXTURE_COUNT = 16;",
1241
+ },
1242
+ {
1243
+ file: "gamesys/src/gamesys/gamesys.cpp",
1244
+ contains: `const dmhash_t PROP_TEXTURE[dmRender::RenderObject::MAX_TEXTURE_COUNT] = { ${Array.from(
1245
+ { length: 16 },
1246
+ (_, unit) => `dmHashString64("texture${unit}"),`,
1247
+ ).join(" ")} };`,
1248
+ },
1249
+ {
1250
+ file: "gamesys/src/gamesys/components/comp_model.cpp",
1251
+ cFunction: "CompModelGetProperty",
1252
+ contains: MODEL_TEXTURE_LOOP,
1253
+ },
1254
+ {
1255
+ file: "gamesys/src/gamesys/components/comp_model.cpp",
1256
+ cFunction: "CompModelSetProperty",
1257
+ contains: MODEL_TEXTURE_LOOP,
1258
+ },
1259
+ ],
1260
+ },
1261
+ },
1262
+ ],
1113
1263
  ]);
1114
1264
 
1115
1265
  // A parameter the ref-doc metadata marks required while the same element's prose
@@ -1763,13 +1913,9 @@ export const CONSTANT_SLOT_RESOLUTIONS: ReadonlyMap<string, ConstantSlotResoluti
1763
1913
  ],
1764
1914
  ["gui.new_texture:param:type", { residual: "the doc lists texture type strings only" }],
1765
1915
  ["gui.set_texture_data:param:type", { residual: "the doc lists texture type strings only" }],
1766
- [
1767
- "iap.get_provider_id:return:provider_id",
1768
- { residual: "the doc names iap.PROVIDER_ID_*, which no ref-doc defines as a constant" },
1769
- ],
1770
1916
  ]);
1771
1917
 
1772
- export interface ConstantUnionAlias {
1918
+ export interface ConstantUnionNamedRow {
1773
1919
  // The namespace the alias is declared in. It is the namespace the union
1774
1920
  // *means*, which is not always the one its constants live in: the three
1775
1921
  // buffer keys `render.clear` accepts are `graphics.BUFFER_TYPE_*` constants,
@@ -1780,11 +1926,22 @@ export interface ConstantUnionAlias {
1780
1926
  readonly members: readonly string[];
1781
1927
  }
1782
1928
 
1783
- // A documented constant union gets a public name so a caller can spell the type
1784
- // their own wrapper takes. Identity is the *member set*, never a name prefix:
1785
- // `gui.ANCHOR_*` splits into two rows because the x and y slots accept
1786
- // different thirds of it, and `graphics.BUFFER_TYPE_*` splits because
1787
- // `render.clear` accepts three of the six.
1929
+ // A union that is a strict subset of a named row in the same home. It declares
1930
+ // nothing: each slot spells it `Exclude<<home>.<parent>, ...>`, so one namespace
1931
+ // never carries two names for overlapping sets.
1932
+ export interface ConstantUnionSubsetRow {
1933
+ readonly home: string;
1934
+ readonly parent: string;
1935
+ readonly members: readonly string[];
1936
+ }
1937
+
1938
+ export type ConstantUnionAlias = ConstantUnionNamedRow | ConstantUnionSubsetRow;
1939
+
1940
+ // A documented constant union gets a public spelling so a caller can write the
1941
+ // type their own wrapper takes. Identity is the *member set*, never a name
1942
+ // prefix: the x and y anchor slots accept different thirds of `gui.ANCHOR_*`,
1943
+ // so each is its own subset row of `gui.ANCHOR`, and `graphics.BUFFER_TYPE_*`
1944
+ // splits because `render.clear` accepts three of the six.
1788
1945
  //
1789
1946
  // The table is the only thing the emitter reads, and every name in it has been
1790
1947
  // reviewed: a longest-common-prefix rule proposes, a human disposes. A union
@@ -1794,7 +1951,7 @@ export interface ConstantUnionAlias {
1794
1951
  export const CONSTANT_UNION_ALIASES: readonly ConstantUnionAlias[] = [
1795
1952
  {
1796
1953
  home: "buffer",
1797
- name: "ValueType",
1954
+ name: "VALUE_TYPE",
1798
1955
  members: [
1799
1956
  "buffer.VALUE_TYPE_FLOAT32",
1800
1957
  "buffer.VALUE_TYPE_INT16",
@@ -1809,7 +1966,7 @@ export const CONSTANT_UNION_ALIASES: readonly ConstantUnionAlias[] = [
1809
1966
  },
1810
1967
  {
1811
1968
  home: "collectionfactory",
1812
- name: "Status",
1969
+ name: "STATUS",
1813
1970
  members: [
1814
1971
  "collectionfactory.STATUS_UNLOADED",
1815
1972
  "collectionfactory.STATUS_LOADING",
@@ -1818,12 +1975,12 @@ export const CONSTANT_UNION_ALIASES: readonly ConstantUnionAlias[] = [
1818
1975
  },
1819
1976
  {
1820
1977
  home: "factory",
1821
- name: "Status",
1978
+ name: "STATUS",
1822
1979
  members: ["factory.STATUS_UNLOADED", "factory.STATUS_LOADING", "factory.STATUS_LOADED"],
1823
1980
  },
1824
1981
  {
1825
1982
  home: "go",
1826
- name: "Easing",
1983
+ name: "EASING",
1827
1984
  members: [
1828
1985
  "go.EASING_INBACK",
1829
1986
  "go.EASING_INBOUNCE",
@@ -1870,7 +2027,20 @@ export const CONSTANT_UNION_ALIASES: readonly ConstantUnionAlias[] = [
1870
2027
  },
1871
2028
  {
1872
2029
  home: "go",
1873
- name: "Playback",
2030
+ name: "PLAYBACK",
2031
+ members: [
2032
+ "go.PLAYBACK_LOOP_BACKWARD",
2033
+ "go.PLAYBACK_LOOP_FORWARD",
2034
+ "go.PLAYBACK_LOOP_PINGPONG",
2035
+ "go.PLAYBACK_NONE",
2036
+ "go.PLAYBACK_ONCE_BACKWARD",
2037
+ "go.PLAYBACK_ONCE_FORWARD",
2038
+ "go.PLAYBACK_ONCE_PINGPONG",
2039
+ ],
2040
+ },
2041
+ {
2042
+ home: "go",
2043
+ parent: "PLAYBACK",
1874
2044
  members: [
1875
2045
  "go.PLAYBACK_ONCE_FORWARD",
1876
2046
  "go.PLAYBACK_ONCE_BACKWARD",
@@ -1884,7 +2054,7 @@ export const CONSTANT_UNION_ALIASES: readonly ConstantUnionAlias[] = [
1884
2054
  // target defines the constants; only the newer ones name the union.
1885
2055
  {
1886
2056
  home: "graphics",
1887
- name: "BlendFactor",
2057
+ name: "BLEND_FACTOR",
1888
2058
  members: [
1889
2059
  "graphics.BLEND_FACTOR_ZERO",
1890
2060
  "graphics.BLEND_FACTOR_ONE",
@@ -1905,7 +2075,7 @@ export const CONSTANT_UNION_ALIASES: readonly ConstantUnionAlias[] = [
1905
2075
  },
1906
2076
  {
1907
2077
  home: "graphics",
1908
- name: "BufferType",
2078
+ name: "BUFFER_TYPE",
1909
2079
  members: [
1910
2080
  "graphics.BUFFER_TYPE_COLOR0_BIT",
1911
2081
  "graphics.BUFFER_TYPE_COLOR1_BIT",
@@ -1917,7 +2087,22 @@ export const CONSTANT_UNION_ALIASES: readonly ConstantUnionAlias[] = [
1917
2087
  },
1918
2088
  {
1919
2089
  home: "graphics",
1920
- name: "State",
2090
+ name: "STATE",
2091
+ members: [
2092
+ "graphics.STATE_ALPHA_TEST",
2093
+ "graphics.STATE_ALPHA_TEST_SUPPORTED",
2094
+ "graphics.STATE_BLEND",
2095
+ "graphics.STATE_CULL_FACE",
2096
+ "graphics.STATE_DEPTH_TEST",
2097
+ "graphics.STATE_POLYGON_OFFSET_FILL",
2098
+ "graphics.STATE_SCISSOR_TEST",
2099
+ "graphics.STATE_STENCIL_TEST",
2100
+ ],
2101
+ },
2102
+ // The six render_script.cpp:RenderScript_EnableState accepts.
2103
+ {
2104
+ home: "graphics",
2105
+ parent: "STATE",
1921
2106
  members: [
1922
2107
  "graphics.STATE_DEPTH_TEST",
1923
2108
  "graphics.STATE_STENCIL_TEST",
@@ -1929,12 +2114,33 @@ export const CONSTANT_UNION_ALIASES: readonly ConstantUnionAlias[] = [
1929
2114
  },
1930
2115
  {
1931
2116
  home: "gui",
1932
- name: "AdjustMode",
2117
+ name: "ADJUST",
1933
2118
  members: ["gui.ADJUST_FIT", "gui.ADJUST_ZOOM", "gui.ADJUST_STRETCH"],
1934
2119
  },
1935
2120
  {
1936
2121
  home: "gui",
1937
- name: "BlendMode",
2122
+ name: "ANCHOR",
2123
+ members: [
2124
+ "gui.ANCHOR_BOTTOM",
2125
+ "gui.ANCHOR_LEFT",
2126
+ "gui.ANCHOR_NONE",
2127
+ "gui.ANCHOR_RIGHT",
2128
+ "gui.ANCHOR_TOP",
2129
+ ],
2130
+ },
2131
+ {
2132
+ home: "gui",
2133
+ parent: "ANCHOR",
2134
+ members: ["gui.ANCHOR_NONE", "gui.ANCHOR_LEFT", "gui.ANCHOR_RIGHT"],
2135
+ },
2136
+ {
2137
+ home: "gui",
2138
+ parent: "ANCHOR",
2139
+ members: ["gui.ANCHOR_NONE", "gui.ANCHOR_TOP", "gui.ANCHOR_BOTTOM"],
2140
+ },
2141
+ {
2142
+ home: "gui",
2143
+ name: "BLEND",
1938
2144
  members: [
1939
2145
  "gui.BLEND_ALPHA",
1940
2146
  "gui.BLEND_ADD",
@@ -1945,12 +2151,12 @@ export const CONSTANT_UNION_ALIASES: readonly ConstantUnionAlias[] = [
1945
2151
  },
1946
2152
  {
1947
2153
  home: "gui",
1948
- name: "ClippingMode",
2154
+ name: "CLIPPING_MODE",
1949
2155
  members: ["gui.CLIPPING_MODE_NONE", "gui.CLIPPING_MODE_STENCIL"],
1950
2156
  },
1951
2157
  {
1952
2158
  home: "gui",
1953
- name: "Easing",
2159
+ name: "EASING",
1954
2160
  members: [
1955
2161
  "gui.EASING_INBACK",
1956
2162
  "gui.EASING_INBOUNCE",
@@ -1997,7 +2203,7 @@ export const CONSTANT_UNION_ALIASES: readonly ConstantUnionAlias[] = [
1997
2203
  },
1998
2204
  {
1999
2205
  home: "gui",
2000
- name: "KeyboardType",
2206
+ name: "KEYBOARD_TYPE",
2001
2207
  members: [
2002
2208
  "gui.KEYBOARD_TYPE_DEFAULT",
2003
2209
  "gui.KEYBOARD_TYPE_EMAIL",
@@ -2007,7 +2213,7 @@ export const CONSTANT_UNION_ALIASES: readonly ConstantUnionAlias[] = [
2007
2213
  },
2008
2214
  {
2009
2215
  home: "gui",
2010
- name: "NodeType",
2216
+ name: "TYPE",
2011
2217
  members: [
2012
2218
  "gui.TYPE_BOX",
2013
2219
  "gui.TYPE_TEXT",
@@ -2018,12 +2224,12 @@ export const CONSTANT_UNION_ALIASES: readonly ConstantUnionAlias[] = [
2018
2224
  },
2019
2225
  {
2020
2226
  home: "gui",
2021
- name: "PieBounds",
2227
+ name: "PIEBOUNDS",
2022
2228
  members: ["gui.PIEBOUNDS_RECTANGLE", "gui.PIEBOUNDS_ELLIPSE"],
2023
2229
  },
2024
2230
  {
2025
2231
  home: "gui",
2026
- name: "Pivot",
2232
+ name: "PIVOT",
2027
2233
  members: [
2028
2234
  "gui.PIVOT_CENTER",
2029
2235
  "gui.PIVOT_N",
@@ -2038,7 +2244,7 @@ export const CONSTANT_UNION_ALIASES: readonly ConstantUnionAlias[] = [
2038
2244
  },
2039
2245
  {
2040
2246
  home: "gui",
2041
- name: "Playback",
2247
+ name: "PLAYBACK",
2042
2248
  members: [
2043
2249
  "gui.PLAYBACK_ONCE_FORWARD",
2044
2250
  "gui.PLAYBACK_ONCE_BACKWARD",
@@ -2050,7 +2256,7 @@ export const CONSTANT_UNION_ALIASES: readonly ConstantUnionAlias[] = [
2050
2256
  },
2051
2257
  {
2052
2258
  home: "gui",
2053
- name: "Property",
2259
+ name: "PROP",
2054
2260
  members: [
2055
2261
  "gui.PROP_POSITION",
2056
2262
  "gui.PROP_ROTATION",
@@ -2069,7 +2275,7 @@ export const CONSTANT_UNION_ALIASES: readonly ConstantUnionAlias[] = [
2069
2275
  },
2070
2276
  {
2071
2277
  home: "gui",
2072
- name: "SafeAreaMode",
2278
+ name: "SAFE_AREA",
2073
2279
  members: [
2074
2280
  "gui.SAFE_AREA_NONE",
2075
2281
  "gui.SAFE_AREA_LONG",
@@ -2079,22 +2285,12 @@ export const CONSTANT_UNION_ALIASES: readonly ConstantUnionAlias[] = [
2079
2285
  },
2080
2286
  {
2081
2287
  home: "gui",
2082
- name: "SizeMode",
2288
+ name: "SIZE_MODE",
2083
2289
  members: ["gui.SIZE_MODE_MANUAL", "gui.SIZE_MODE_AUTO"],
2084
2290
  },
2085
- {
2086
- home: "gui",
2087
- name: "XAnchor",
2088
- members: ["gui.ANCHOR_NONE", "gui.ANCHOR_LEFT", "gui.ANCHOR_RIGHT"],
2089
- },
2090
- {
2091
- home: "gui",
2092
- name: "YAnchor",
2093
- members: ["gui.ANCHOR_NONE", "gui.ANCHOR_TOP", "gui.ANCHOR_BOTTOM"],
2094
- },
2095
2291
  {
2096
2292
  home: "profiler",
2097
- name: "Mode",
2293
+ name: "MODE",
2098
2294
  members: [
2099
2295
  "profiler.MODE_RUN",
2100
2296
  "profiler.MODE_PAUSE",
@@ -2104,7 +2300,7 @@ export const CONSTANT_UNION_ALIASES: readonly ConstantUnionAlias[] = [
2104
2300
  },
2105
2301
  {
2106
2302
  home: "profiler",
2107
- name: "ViewMode",
2303
+ name: "VIEW_MODE",
2108
2304
  members: ["profiler.VIEW_MODE_FULL", "profiler.VIEW_MODE_MINIMIZED"],
2109
2305
  },
2110
2306
  {
@@ -2124,7 +2320,7 @@ export const CONSTANT_UNION_ALIASES: readonly ConstantUnionAlias[] = [
2124
2320
  },
2125
2321
  {
2126
2322
  home: "sys",
2127
- name: "NetworkConnectivity",
2323
+ name: "NETWORK",
2128
2324
  members: [
2129
2325
  "sys.NETWORK_DISCONNECTED",
2130
2326
  "sys.NETWORK_CONNECTED_CELLULAR",
@@ -2133,12 +2329,12 @@ export const CONSTANT_UNION_ALIASES: readonly ConstantUnionAlias[] = [
2133
2329
  },
2134
2330
  {
2135
2331
  home: "window",
2136
- name: "DimModeState",
2332
+ name: "DIMMING",
2137
2333
  members: ["window.DIMMING_UNKNOWN", "window.DIMMING_ON", "window.DIMMING_OFF"],
2138
2334
  },
2139
2335
  {
2140
2336
  home: "window",
2141
- name: "DimModeStateSettable",
2337
+ parent: "DIMMING",
2142
2338
  members: ["window.DIMMING_ON", "window.DIMMING_OFF"],
2143
2339
  },
2144
2340
  ];
@@ -2158,11 +2354,47 @@ export function constantUnionAlias(fqns: readonly string[]): ConstantUnionAlias
2158
2354
  return CONSTANT_UNION_ALIAS_BY_MEMBERS.get(constantUnionAliasKey(fqns));
2159
2355
  }
2160
2356
 
2161
- // The alias declarations a module owns, in name order. A row is declared in its
2162
- // home whether or not that module references it, so a cross-namespace row is
2163
- // reachable from the module whose signatures spell it.
2164
- export function constantUnionAliasDeclarations(namespace: string): string[] {
2165
- return CONSTANT_UNION_ALIASES.filter((row) => row.home === namespace)
2357
+ // What a slot taking exactly the row's members is written as: a named row's
2358
+ // qualified name, or a subset row's parent minus the parent's other members,
2359
+ // listed in the parent's order.
2360
+ export function constantUnionSpelling(row: ConstantUnionAlias): string {
2361
+ if ("name" in row) return `${row.home}.${engineTypeName(row.name)}`;
2362
+ const parent = CONSTANT_UNION_ALIASES.find(
2363
+ (candidate): candidate is ConstantUnionNamedRow =>
2364
+ "name" in candidate && candidate.home === row.home && candidate.name === row.parent,
2365
+ );
2366
+ if (parent === undefined) {
2367
+ throw new Error(`constant union subset of ${row.home}.${row.parent}: no such named row`);
2368
+ }
2369
+ const kept = new Set(row.members);
2370
+ const excluded = parent.members.filter((member) => !kept.has(member));
2371
+ return `Exclude<${row.home}.${engineTypeName(row.parent)}, ${excluded.map((m) => `typeof ${m}`).join(" | ")}>`;
2372
+ }
2373
+
2374
+ // The named rows a module owns; a subset row declares nothing. A row is
2375
+ // declared in its home whether or not that module references it, so a
2376
+ // cross-namespace row is reachable from the module whose signatures spell it.
2377
+ // A row whose name the module's own `ENUM` already declares is left to that
2378
+ // `ENUM`, which carries the reference's member order and nilable arms. An
2379
+ // extension module is never a row's home, even when it declares the engine
2380
+ // namespace (`gui`), so its emit skips this (`ownsConstantUnionAliases`).
2381
+ function ownedConstantUnionAliases(
2382
+ namespace: string,
2383
+ enumDeclared: ReadonlySet<string>,
2384
+ ): ConstantUnionNamedRow[] {
2385
+ return CONSTANT_UNION_ALIASES.filter(
2386
+ (row): row is ConstantUnionNamedRow =>
2387
+ "name" in row && row.home === namespace && !enumDeclared.has(row.name),
2388
+ );
2389
+ }
2390
+
2391
+ // The alias declarations a module owns, in name order.
2392
+ export function constantUnionAliasDeclarations(
2393
+ namespace: string,
2394
+ enumDeclared: ReadonlySet<string> = new Set(),
2395
+ ): string[] {
2396
+ return ownedConstantUnionAliases(namespace, enumDeclared)
2397
+ .map((row) => ({ name: engineTypeName(row.name), members: row.members }))
2166
2398
  .sort((a, b) => a.name.localeCompare(b.name))
2167
2399
  .map((row) => unionAliasDeclaration(row.name, row.members));
2168
2400
  }
@@ -2178,10 +2410,12 @@ function unionAliasDeclaration(
2178
2410
  }
2179
2411
 
2180
2412
  // A slot of a function the authored-overload lane declares, published under
2181
- // one alias on every target so the version-independent overload file can
2182
- // name the type each target's own reference gives that slot.
2413
+ // one name on every target so the version-independent overload file can name
2414
+ // the type each target's own reference gives that slot. The name is the
2415
+ // PascalCase name of the newest reference's own declaration for the slot; a
2416
+ // target that declares it emits no alias.
2183
2417
  export const OVERLOAD_SLOT_ALIASES: ReadonlyMap<string, string> = new Map([
2184
- ["render.render_target:param:parameters", "RenderTargetParams"],
2418
+ ["render.render_target:param:parameters", engineTypeName("render_target_params")],
2185
2419
  ]);
2186
2420
 
2187
2421
  const DOC_CONSTANT_TOKEN =
@@ -2358,9 +2592,9 @@ export const HOMOGENEOUS_ARRAY_SLOTS: ReadonlyMap<string, string | readonly stri
2358
2592
  ["iap.list", "string"],
2359
2593
  // push.register's `notifications` is a prose-only array of push.NOTIFICATION_*
2360
2594
  // bitmask constants (the ref example sums NOTIFICATION_BADGE/SOUND/ALERT). The
2361
- // vendored push_doc.json fixture declares no NOTIFICATION_* constant elements, so
2362
- // no brand exists to reference; `number` is the faithful element token for these
2363
- // numeric constants, mirroring the vmath.vector/buffer.* number entries.
2595
+ // slot's prose names no constant the expansion could read, and a summed bitmask
2596
+ // is a plain number rather than any one brand, so `number` is the faithful
2597
+ // element token, mirroring the vmath.vector/buffer.* number entries.
2364
2598
  ["push.register", "number"],
2365
2599
  // camera.get_cameras returns "a table with all camera URLs" (the ref example
2366
2600
  // iterates it with `pairs`) — a homogeneous list of `url`, emitted `Url[]`.
@@ -2395,7 +2629,34 @@ export type TableSlotCuration = (
2395
2629
  | { kind: "verbatim"; ts: string }
2396
2630
  ) & { readonly retypedUpstream?: readonly string[] };
2397
2631
 
2398
- export const SOCKET_HANDLE_TOKENS = ["client", "master", "unconnected"] as const;
2632
+ // The interface a module's component properties are declared on; its PROPERTY
2633
+ // entries carry its members, so it signs no TYPEDEF of its own.
2634
+ export const PROPERTIES_INTERFACE = engineTypeName("properties");
2635
+
2636
+ // The ref-doc tokens of the handles `socket.select` takes and returns, in their
2637
+ // 1.13.2 TYPEDEF spelling, which the type map resolves to each handle's interface.
2638
+ export const SOCKET_HANDLE_TOKENS = (["client", "master", "unconnected"] as const).map(
2639
+ (receiver) => `socket_${receiver}`,
2640
+ );
2641
+
2642
+ // The interface a module's `<receiver>:<method>` colon methods are emitted on:
2643
+ // the socket handles take their `Socket<Receiver>` name, any other receiver
2644
+ // keeps its own.
2645
+ export function handleInterfaceName(namespace: string, receiver: string): string {
2646
+ return namespace === "socket" && Object.hasOwn(SOCKET_HANDLE_NAMES, receiver)
2647
+ ? SOCKET_HANDLE_NAMES[receiver as SocketHandleReceiver]
2648
+ : receiver;
2649
+ }
2650
+
2651
+ // The typedef names a module's handle interfaces stand for, which emit as the
2652
+ // interface rather than an alias: each receiver (1.13.1 `client`) and each
2653
+ // interface name, which the 1.13.2 `socket_client` takes once renamed
2654
+ // (`SocketClient`).
2655
+ function handleTypedefNames(namespace: string, receivers: Iterable<string>): Set<string> {
2656
+ return new Set(
2657
+ [...receivers].flatMap((receiver) => [receiver, handleInterfaceName(namespace, receiver)]),
2658
+ );
2659
+ }
2399
2660
 
2400
2661
  // Shared Box2D (b2d.*) table shapes, curated from the ref-doc prose (the docs
2401
2662
  // name fields in running text, not a machine-readable `<dl>`). Reused across the
@@ -3390,7 +3651,7 @@ export const CALLBACK_SIGNATURE_CURATIONS: ReadonlyMap<string, CallbackSignature
3390
3651
  "(self: unknown, event: (typeof window)[Extract<keyof typeof window, `WINDOW_EVENT_${string}`>], data: Record<string | number, unknown>) => void",
3391
3652
  typed:
3392
3653
  // biome-ignore lint/suspicious/noTemplateCurlyInString: emitted verbatim as a TS template literal type
3393
- "(self: unknown, event: (typeof window)[Extract<keyof typeof window, `WINDOW_EVENT_${string}`>], data: window.event_data) => void",
3654
+ "(self: unknown, event: (typeof window)[Extract<keyof typeof window, `WINDOW_EVENT_${string}`>], data: window.EventData) => void",
3394
3655
  },
3395
3656
  ],
3396
3657
  [
@@ -3458,9 +3719,11 @@ export const NESTED_FIELD_CURATIONS: ReadonlyMap<string, readonly TableField[]>
3458
3719
  // `<element>:<kind>:<slot>:<field>`, mirroring NESTED_FIELD_CURATIONS; a field
3459
3720
  // one level down is `<field>.<member>`, or `<field>[].<member>` inside a list.
3460
3721
  //
3461
- // The atlas animation `playback` field is documented as `constant` with the
3462
- // prose "the default value is go.PLAYBACK_ONCE_FORWARD", which names the enum
3463
- // the bare token cannot.
3722
+ // Unpinned records below rest on ref-doc tokens or prose. The atlas animation
3723
+ // `playback` field is documented as `constant` with the prose "the default value
3724
+ // is go.PLAYBACK_ONCE_FORWARD", which names the enum the bare token cannot; its
3725
+ // records also carry engine binding pins and apply only when the matching
3726
+ // `EmitOptions.bindingEvidence` key holds for the target.
3464
3727
  //
3465
3728
  // `gui.set`'s `options.key` is documented as `hash`, while upstream's own
3466
3729
  // example sets a named font with `{ key = "my_font_name" }`.
@@ -3473,21 +3736,47 @@ export const NESTED_FIELD_CURATIONS: ReadonlyMap<string, readonly TableField[]>
3473
3736
  // script_resource.cpp:CreateSoundData reads it with CheckBufferOrString.
3474
3737
  const CONSTANT_VALUE_TS = "Vector4 | Vector3 | Matrix4 | number | (Vector4 | Matrix4)[]";
3475
3738
  const ATTRIBUTE_VALUE_TS = "Vector4 | Vector3 | Matrix4 | number | number[]";
3476
- export const TABLE_FIELD_TYPE_OVERRIDES: ReadonlyMap<string, string> = new Map([
3477
- ["compute.set_constants:param:constants:value", CONSTANT_VALUE_TS],
3478
- ["material.set_constants:param:constants:value", CONSTANT_VALUE_TS],
3479
- ["material.set_vertex_attributes:param:attributes:value", ATTRIBUTE_VALUE_TS],
3480
- ["material.get_vertex_attributes:return:table:value", ATTRIBUTE_VALUE_TS],
3481
- ["resource.set_atlas:param:table:animations[].playback", "go.Playback"],
3482
- ["resource.create_atlas:param:table:animations[].playback", "go.Playback"],
3483
- ["resource.get_atlas:return:data:animations[].playback", "go.Playback"],
3484
- ["render.set_render_target:param:options:transient", "graphics.BufferType[]"],
3485
- ["resource.create_sound_data:param:options:data", 'string | Opaque<"buffer">'],
3739
+ const ATLAS_BINDING_FILE = "gamesys/src/gamesys/scripts/script_resource.cpp";
3740
+ const ATLAS_INPUT_PLAYBACK_BINDING: BindingPin = {
3741
+ file: ATLAS_BINDING_FILE,
3742
+ cFunction: "MakeTextureSetFromLua",
3743
+ contains: "GameObjectPlaybackToDDFPlayback((dmGameObject::Playback) lua_tointeger(L,-1))",
3744
+ };
3745
+ const ATLAS_OUTPUT_PLAYBACK_BINDING: BindingPin = {
3746
+ file: ATLAS_BINDING_FILE,
3747
+ cFunction: "GetAtlas",
3748
+ contains: "(lua_Integer) DDFPlaybackToGameObjectPlayback(anim.m_Playback)",
3749
+ };
3750
+
3751
+ export interface TableFieldTypeOverride {
3752
+ readonly ts: string;
3753
+ readonly binding?: BindingPin;
3754
+ }
3755
+
3756
+ export const TABLE_FIELD_TYPE_OVERRIDES: ReadonlyMap<string, TableFieldTypeOverride> = new Map([
3757
+ ["compute.set_constants:param:constants:value", { ts: CONSTANT_VALUE_TS }],
3758
+ ["material.set_constants:param:constants:value", { ts: CONSTANT_VALUE_TS }],
3759
+ ["material.set_vertex_attributes:param:attributes:value", { ts: ATTRIBUTE_VALUE_TS }],
3760
+ ["material.get_vertex_attributes:return:table:value", { ts: ATTRIBUTE_VALUE_TS }],
3761
+ [
3762
+ "resource.set_atlas:param:table:animations[].playback",
3763
+ { ts: "go.Playback", binding: ATLAS_INPUT_PLAYBACK_BINDING },
3764
+ ],
3765
+ [
3766
+ "resource.create_atlas:param:table:animations[].playback",
3767
+ { ts: "go.Playback", binding: ATLAS_INPUT_PLAYBACK_BINDING },
3768
+ ],
3769
+ [
3770
+ "resource.get_atlas:return:data:animations[].playback",
3771
+ { ts: "go.Playback", binding: ATLAS_OUTPUT_PLAYBACK_BINDING },
3772
+ ],
3773
+ ["render.set_render_target:param:options:transient", { ts: "graphics.BufferType[]" }],
3774
+ ["resource.create_sound_data:param:options:data", { ts: 'string | Opaque<"buffer">' }],
3486
3775
  // The option bags 1.13.2 types as a STRUCT, whose members still carry the
3487
3776
  // narrower upstream types: `gui.set`'s (its slot is declared in
3488
3777
  // gui-overloads.d.ts) and `resource.create_sound_data`'s.
3489
- ["gui.set_options:member:key", "string | Hash"],
3490
- ["resource.sound_data_options:member:data", 'string | Opaque<"buffer">'],
3778
+ ["gui.set_options:member:key", { ts: "string | Hash" }],
3779
+ ["resource.sound_data_options:member:data", { ts: 'string | Opaque<"buffer">' }],
3491
3780
  // Bitmasks typed as their flag enum: the create_texture example passes
3492
3781
  // TEXTURE_USAGE_FLAG_STORAGE + TEXTURE_USAGE_FLAG_SAMPLE, a sum no single member
3493
3782
  // names, and a reported value combines them the same way.
@@ -3498,13 +3787,15 @@ export const TABLE_FIELD_TYPE_OVERRIDES: ReadonlyMap<string, string> = new Map([
3498
3787
  "resource.render_target_attachment_info",
3499
3788
  "material.texture_info",
3500
3789
  ] as const
3501
- ).map((struct) => [`${struct}:member:flags`, "graphics.TEXTURE_USAGE_FLAG | number"] as const),
3502
- ["render.render_target_buffer_params:member:flags", "render.RENDER_TARGET_FLAG | number"],
3790
+ ).map(
3791
+ (struct) => [`${struct}:member:flags`, { ts: "graphics.TextureUsageFlag | number" }] as const,
3792
+ ),
3793
+ ["render.render_target_buffer_params:member:flags", { ts: "render.RenderTargetFlag | number" }],
3503
3794
  // gamesys_script.cpp:PushSampler, behind both get_samplers, pushes the raw
3504
3795
  // texture type; NormalizeBindableTextureType never runs there. A separate
3505
3796
  // sampler reports TEXTURE_TYPE_SAMPLER (6) and a separate texture binding one
3506
3797
  // of the four TEXTURE_TYPE_TEXTURE_* (7-10), none of which has a Lua constant.
3507
- ["material.sampler_info:member:type", "graphics.TEXTURE_TYPE | 6 | 7 | 8 | 9 | 10"],
3798
+ ["material.sampler_info:member:type", { ts: "graphics.TextureType | 6 | 7 | 8 | 9 | 10" }],
3508
3799
  ]);
3509
3800
 
3510
3801
  // A field the engine accepts on an option bag whose `<dl>` upstream otherwise
@@ -3935,12 +4226,16 @@ export function applyFieldTypeOverrides(
3935
4226
  slotKind: "param" | "return" | undefined,
3936
4227
  slotName: string | undefined,
3937
4228
  fields: readonly TableField[],
4229
+ bindingEvidence: ReadonlySet<string>,
3938
4230
  ): TableField[] {
3939
4231
  if (slotKind === undefined || slotName === undefined) return [...fields];
3940
4232
  const prefix = `${tableSlotKey(elementName, slotKind, slotName)}:`;
3941
4233
  const typed = (field: TableField, path: string): TableField => {
3942
- const override = TABLE_FIELD_TYPE_OVERRIDES.get(`${prefix}${path}`);
3943
- return override === undefined ? field : { ...field, tsType: override };
4234
+ const key = `${prefix}${path}`;
4235
+ const override = TABLE_FIELD_TYPE_OVERRIDES.get(key);
4236
+ return override === undefined || (override.binding !== undefined && !bindingEvidence.has(key))
4237
+ ? field
4238
+ : { ...field, tsType: override.ts };
3944
4239
  };
3945
4240
  return fields.map((field) => {
3946
4241
  const own = typed(field, field.name);
@@ -4315,7 +4610,7 @@ export const TYPEDEF_ALIAS_CORRECTIONS: ReadonlyMap<string, TypedefAliasCorrecti
4315
4610
  upstream: [
4316
4611
  "{ type?:graphics.TEXTURE_TYPE, sample_count?:integer, [graphics.BUFFER_TYPE]:render.render_target_buffer_params }",
4317
4612
  ],
4318
- ts: "{ type?: render.RenderTargetTextureType; sample_count?: number } & { [key: number]: render.render_target_buffer_params }",
4613
+ ts: "{ type?: render.RenderTargetTextureType; sample_count?: number } & { [key: number]: render.RenderTargetBufferParams }",
4319
4614
  reason:
4320
4615
  'render_script.cpp:RenderScript_RenderTarget raises "Invalid render target texture type" on any `type` but graphics.TEXTURE_TYPE_2D and graphics.TEXTURE_TYPE_CUBE_MAP',
4321
4616
  },
@@ -4344,15 +4639,17 @@ export const TYPEDEF_ALIAS_CORRECTIONS: ReadonlyMap<string, TypedefAliasCorrecti
4344
4639
  // function yields.
4345
4640
  //
4346
4641
  // An engine typedef that names its aliased type: a `userdata`/`number` handle the
4347
- // type map resolves (`vector`, `socket_client`) aliases that mapping, an
4642
+ // type map resolves (`timer_handle`, `buffer_data`) aliases that mapping, an
4348
4643
  // unresolved one keeps the brand, and any other aliased type (a union, literals, a
4349
- // record) aliases the type itself.
4644
+ // record) aliases the type itself. A handle the type map resolves to a core
4645
+ // global (`vector` -> `Vector`, `resource_data` -> `Hash`) declares nothing, since
4646
+ // its slots already name the global: `null`.
4350
4647
  function typedefAlias(
4351
4648
  typedef: ApiTypedef,
4352
4649
  local: string,
4353
4650
  rawMapType: (token: string) => string,
4354
4651
  mapType: DefoldTypeMapper,
4355
- ): string {
4652
+ ): string | null {
4356
4653
  const brand = `Opaque<"${typedef.name}">`;
4357
4654
  const aliasOf = typedef.aliasOf ?? [];
4358
4655
  const correction = TYPEDEF_ALIAS_CORRECTIONS.get(typedef.name);
@@ -4371,10 +4668,23 @@ function typedefAlias(
4371
4668
  }
4372
4669
  const mapped = rawMapType(typedef.name);
4373
4670
  if (mapped.startsWith(brand)) return `type ${local} = ${mapped};`;
4671
+ if (aliasOf.length > 0 && CORE_GLOBAL_TYPES.has(mapped)) return null;
4374
4672
  const resolved = aliasOf.length > 0 && mapped !== "unknown" && mapped !== local;
4375
4673
  return `type ${local} = ${resolved ? mapped : brand};`;
4376
4674
  }
4377
4675
 
4676
+ // The global types `core-types.ts` declares that the engine vocabulary maps a
4677
+ // handle to.
4678
+ const CORE_GLOBAL_TYPES: ReadonlySet<string> = new Set([
4679
+ "Hash",
4680
+ "Matrix4",
4681
+ "Quaternion",
4682
+ "Url",
4683
+ "Vector",
4684
+ "Vector3",
4685
+ "Vector4",
4686
+ ]);
4687
+
4378
4688
  function isHandleAlias(aliasOf: readonly string[]): boolean {
4379
4689
  return aliasOf.length === 1 && (aliasOf[0] === "userdata" || aliasOf[0] === "number");
4380
4690
  }
@@ -4391,8 +4701,9 @@ interface TypeDeclaration {
4391
4701
 
4392
4702
  // A typedef with no aliased type keeps the flat-name rule it always had; one that
4393
4703
  // names its aliased type, and every struct, sits at its name less the module
4394
- // prefix, nested when that local is dotted. Typedefs come before structs, each in
4395
- // document order.
4704
+ // prefix, nested when that local is dotted. Every leaf goes through
4705
+ // `engineTypeName`, and `skip` matches a typedef by its reference local or its
4706
+ // renamed path. Typedefs come before structs, each in document order.
4396
4707
  function collectTypeDeclarations(
4397
4708
  module: ApiModule,
4398
4709
  skip: ReadonlySet<string>,
@@ -4409,12 +4720,15 @@ function collectTypeDeclarations(
4409
4720
  for (const t of module.typedefs) {
4410
4721
  const local =
4411
4722
  t.aliasOf === undefined ? (TS_IDENTIFIER.test(t.name) ? t.name : null) : localOf(t.name);
4412
- if (local === null || skip.has(local)) continue;
4413
- const name = local.slice(local.lastIndexOf(".") + 1);
4723
+ if (local === null) continue;
4724
+ const path = renamedLeaf(local);
4725
+ if (skip.has(local) || skip.has(path)) continue;
4726
+ const name = path.slice(path.lastIndexOf(".") + 1);
4414
4727
  const signature = typedefAlias(t, name, rawMapType, mapType);
4728
+ if (signature === null) continue;
4415
4729
  out.push({
4416
4730
  name,
4417
- path: local,
4731
+ path,
4418
4732
  lines: (indent, decl) => [`${indent}${decl}${signature}`],
4419
4733
  signature,
4420
4734
  });
@@ -4472,11 +4786,12 @@ function correctedListMemberType(
4472
4786
 
4473
4787
  function structDeclaration(
4474
4788
  struct: ApiStruct,
4475
- path: string,
4789
+ local: string,
4476
4790
  mapType: DefoldTypeMapper,
4477
4791
  structs: readonly ApiStruct[],
4478
4792
  bindingEvidence: ReadonlySet<string>,
4479
4793
  ): TypeDeclaration {
4794
+ const path = renamedLeaf(local);
4480
4795
  const name = path.slice(path.lastIndexOf(".") + 1);
4481
4796
  const memberPrefix = memberCorrectionKey(struct.name, "");
4482
4797
  const declared = new Set(struct.members.map((member) => member.name));
@@ -4503,7 +4818,9 @@ function structDeclaration(
4503
4818
  const members = [...struct.members, ...added].map((member) => {
4504
4819
  const key = memberCorrectionKey(struct.name, member.name);
4505
4820
  const list = LIST_FIELD_CORRECTIONS.get(key);
4506
- const retyped = TABLE_FIELD_TYPE_OVERRIDES.get(key);
4821
+ const listedRetype = TABLE_FIELD_TYPE_OVERRIDES.get(key);
4822
+ const retyped =
4823
+ listedRetype?.binding === undefined || bindingEvidence.has(key) ? listedRetype : undefined;
4507
4824
  const optional =
4508
4825
  (member.isOptional || OPTIONAL_MEMBER_CORRECTIONS.has(key)) &&
4509
4826
  !REQUIRED_FIELD_CORRECTIONS.has(key);
@@ -4511,7 +4828,7 @@ function structDeclaration(
4511
4828
  list !== undefined
4512
4829
  ? correctedListMemberType(struct, member, list, structs, mapType)
4513
4830
  : retyped !== undefined
4514
- ? retyped
4831
+ ? retyped.ts
4515
4832
  : member.type === ""
4516
4833
  ? "unknown"
4517
4834
  : mapType(member.type);
@@ -4535,7 +4852,10 @@ function structDeclaration(
4535
4852
  `${indent}}`,
4536
4853
  ];
4537
4854
  },
4538
- signature: `interface ${name} { ${members.map((member) => `${member.line} `).join("")}}`,
4855
+ signature: interfaceSignature(
4856
+ name,
4857
+ members.map((member) => member.line),
4858
+ ),
4539
4859
  };
4540
4860
  }
4541
4861
 
@@ -4594,8 +4914,9 @@ function moduleTypeMappers(
4594
4914
  * dropped, so the home's own copy wins; a type sharing a value's name
4595
4915
  * (`resource.atlas`) is untouched. A function moves the same way (1.13.2 files
4596
4916
  * `bullet3d.collision_object.get_shapes` in the shape doc), since the emitter
4597
- * declares only the functions under a module's own namespace. Modules with
4598
- * nothing moved in or out are returned as-is.
4917
+ * declares only the functions under a module's own namespace. A moved type
4918
+ * records the module that declared it as `declaredIn`. Modules with nothing
4919
+ * moved in or out are returned as-is.
4599
4920
  */
4600
4921
  export function routeTypeDeclarations(modules: readonly ApiModule[]): ApiModule[] {
4601
4922
  const homeOf = (name: string, declaring: string): string => {
@@ -4625,14 +4946,14 @@ export function routeTypeDeclarations(modules: readonly ApiModule[]): ApiModule[
4625
4946
  const structs = (module.structs ?? []).filter((struct) => {
4626
4947
  const home = homeOf(struct.name, module.namespace);
4627
4948
  if (home === module.namespace) return true;
4628
- into(home).structs.push(struct);
4949
+ into(home).structs.push({ ...struct, declaredIn: module.namespace });
4629
4950
  return false;
4630
4951
  });
4631
4952
  const typedefs = module.typedefs.filter((typedef) => {
4632
4953
  if (typedef.aliasOf === undefined) return true;
4633
4954
  const home = homeOf(typedef.name, module.namespace);
4634
4955
  if (home === module.namespace) return true;
4635
- into(home).typedefs.push(typedef);
4956
+ into(home).typedefs.push({ ...typedef, declaredIn: module.namespace });
4636
4957
  return false;
4637
4958
  });
4638
4959
  const functions = module.functions.filter((fn) => {
@@ -4675,27 +4996,32 @@ export function routeTypeDeclarations(modules: readonly ApiModule[]): ApiModule[
4675
4996
  /**
4676
4997
  * The TS path of every `ENUM`, `STRUCT` and aliasing `TYPEDEF` the (routed)
4677
4998
  * modules declare, keyed by its Lua name: the name itself when it sits under its
4678
- * module's namespace, else that name nested under the module
4679
- * (`on_input.action` in `go` is `go.on_input.action`).
4999
+ * module's namespace, else that name nested under the module, with its leaf
5000
+ * through `engineTypeName` (`on_input.action` in `go` is `go.on_input.Action`).
4680
5001
  */
4681
5002
  export function declaredTypePaths(modules: readonly ApiModule[]): Map<string, string> {
4682
5003
  const paths = new Map<string, string>();
4683
5004
  for (const module of modules) {
4684
- const names = [
4685
- ...(module.enums ?? []).map((e) => e.name),
4686
- ...(module.structs ?? []).map((struct) => struct.name),
4687
- ...module.typedefs.filter((t) => t.aliasOf !== undefined).map((t) => t.name),
4688
- ];
4689
- for (const name of names) {
4690
- paths.set(
4691
- name,
4692
- name.startsWith(`${module.namespace}.`) ? name : `${module.namespace}.${name}`,
4693
- );
5005
+ const qualified = (name: string): string =>
5006
+ name.startsWith(`${module.namespace}.`) ? name : `${module.namespace}.${name}`;
5007
+ for (const { name } of [
5008
+ ...(module.enums ?? []),
5009
+ ...(module.structs ?? []),
5010
+ ...module.typedefs.filter((t) => t.aliasOf !== undefined),
5011
+ ]) {
5012
+ paths.set(name, renamedLeaf(qualified(name)));
4694
5013
  }
4695
5014
  }
4696
5015
  return paths;
4697
5016
  }
4698
5017
 
5018
+ // A dotted type path with its last segment through `engineTypeName`: the
5019
+ // namespace segments mirror the engine's functions and stay as they are.
5020
+ function renamedLeaf(path: string): string {
5021
+ const dot = path.lastIndexOf(".");
5022
+ return `${path.slice(0, dot + 1)}${engineTypeName(path.slice(dot + 1))}`;
5023
+ }
5024
+
4699
5025
  export function emitDeclarations(documented: ApiModule, options?: EmitOptions): string {
4700
5026
  const module = withUndocumentedConstants(documented, options?.registeredConstants);
4701
5027
  const prefix = `${module.namespace}.`;
@@ -4744,6 +5070,13 @@ export function emitDeclarations(documented: ApiModule, options?: EmitOptions):
4744
5070
  const nestedRoot = collectNestedGroups(module, prefix);
4745
5071
  const enumAliases = collectEnumAliases(module, constants, nestedRoot);
4746
5072
 
5073
+ const resolver = buildTableDocResolver(
5074
+ module.functions.map((fn) => ({
5075
+ name: fn.name,
5076
+ slots: [...fn.parameters, ...fn.returnValues],
5077
+ })),
5078
+ );
5079
+
4747
5080
  // Colon methods (`client:send`) are FUNCTION elements named `<receiver>:<method>`
4748
5081
  // and are NOT namespace-prefixed, so they fail the flat-identifier test in
4749
5082
  // prepareFunction (the colon) and are absent from `functions`. A returned handle
@@ -4751,27 +5084,26 @@ export function emitDeclarations(documented: ApiModule, options?: EmitOptions):
4751
5084
  // interface, the same non-flat recovery the dns nested-namespace pass does one
4752
5085
  // container shape shallower.
4753
5086
  const handleGroups = collectHandleMethodGroups(module);
4754
- const handleReceivers = [...handleGroups.keys()].sort((a, b) => a.localeCompare(b));
4755
-
4756
- const resolver = buildTableDocResolver(
4757
- module.functions.map((fn) => ({
4758
- name: fn.name,
4759
- slots: [...fn.parameters, ...fn.returnValues],
4760
- })),
5087
+ const handleInterfaces = collectHandleInterfaces(
5088
+ module.namespace,
5089
+ handleGroups,
5090
+ mapType,
5091
+ resolver,
5092
+ constantTokens,
5093
+ urlParameters,
5094
+ bindingEvidence,
4761
5095
  );
4762
5096
 
4763
5097
  // A typedef that also has colon methods is emitted as a method-bearing
4764
5098
  // interface below, not an opaque brand alias.
4765
- const typeDeclarations = placeTypeDeclarations(
4766
- collectTypeDeclarations(
4767
- module,
4768
- new Set(handleGroups.keys()),
4769
- rawMapType,
4770
- mapType,
4771
- bindingEvidence,
4772
- ),
4773
- nestedRoot,
5099
+ const collectedTypes = collectTypeDeclarations(
5100
+ module,
5101
+ handleTypedefNames(module.namespace, handleGroups.keys()),
5102
+ rawMapType,
5103
+ mapType,
5104
+ bindingEvidence,
4774
5105
  );
5106
+ const typeDeclarations = placeTypeDeclarations(collectedTypes, nestedRoot);
4775
5107
 
4776
5108
  // A re-export alias (`export { _x as x }`) switches the ambient namespace out
4777
5109
  // of its implicit-export mode, so once any alias is present every sibling
@@ -4788,18 +5120,24 @@ export function emitDeclarations(documented: ApiModule, options?: EmitOptions):
4788
5120
  lines.push(`declare namespace ${module.namespace} {`);
4789
5121
 
4790
5122
  for (const declaration of typeDeclarations) lines.push(...declaration.lines(INDENT, decl));
4791
- for (const aliasDecl of constantUnionAliasDeclarations(module.namespace)) {
4792
- lines.push(`${INDENT}${decl}${aliasDecl}`);
5123
+ if (options?.ownsConstantUnionAliases !== false) {
5124
+ for (const aliasDecl of constantUnionAliasDeclarations(
5125
+ module.namespace,
5126
+ new Set(enumAliases.all.map((alias) => alias.path)),
5127
+ )) {
5128
+ lines.push(`${INDENT}${decl}${aliasDecl}`);
5129
+ }
4793
5130
  }
4794
- for (const aliasDecl of overloadSlotAliasDeclarations(
5131
+ for (const { declaration } of overloadSlotAliasDeclarations(
4795
5132
  [...module.functions, ...(options?.withheldFunctions ?? [])],
5133
+ collectedTypes,
4796
5134
  prefix,
4797
5135
  mapType,
4798
5136
  constantTokens,
4799
5137
  urlParameters,
4800
5138
  bindingEvidence,
4801
5139
  )) {
4802
- lines.push(`${INDENT}${decl}${aliasDecl}`);
5140
+ lines.push(`${INDENT}${decl}${declaration}`);
4803
5141
  }
4804
5142
  for (const alias of enumAliases.topLevel) {
4805
5143
  lines.push(
@@ -4807,16 +5145,13 @@ export function emitDeclarations(documented: ApiModule, options?: EmitOptions):
4807
5145
  );
4808
5146
  }
4809
5147
  const handleIndent = `${INDENT}${INDENT}`;
4810
- for (const receiver of handleReceivers) {
4811
- const group = handleGroups.get(receiver) ?? [];
4812
- lines.push(`${INDENT}${decl}interface ${receiver} {`);
4813
- for (const fn of group) {
5148
+ for (const { name, members } of handleInterfaces) {
5149
+ lines.push(`${INDENT}${decl}interface ${name} {`);
5150
+ for (const { fn, text } of members) {
4814
5151
  for (const docLine of functionDocLines(fn.original, translations, baseNotes, handleIndent)) {
4815
5152
  lines.push(docLine);
4816
5153
  }
4817
- lines.push(
4818
- `${handleIndent}${emitMethod(fn, mapType, resolver, constantTokens, urlParameters, bindingEvidence)}`,
4819
- );
5154
+ lines.push(`${handleIndent}${text}`);
4820
5155
  }
4821
5156
  lines.push(`${INDENT}}`);
4822
5157
  }
@@ -4962,9 +5297,9 @@ export function emitDeclarations(documented: ApiModule, options?: EmitOptions):
4962
5297
 
4963
5298
  if (module.properties.length > 0) {
4964
5299
  const members = [...module.properties].sort((a, b) => a.name.localeCompare(b.name));
4965
- lines.push(`${INDENT}${decl}interface properties {`);
5300
+ lines.push(`${INDENT}${decl}interface ${PROPERTIES_INTERFACE} {`);
4966
5301
  for (const p of members) {
4967
- for (const member of emitPropertyMembers(p, mapType, module.namespace)) {
5302
+ for (const member of emitPropertyMembers(p, mapType, module.namespace, bindingEvidence)) {
4968
5303
  for (const docLine of summaryDocLines(p.brief, p.description, `${INDENT}${INDENT}`)) {
4969
5304
  lines.push(docLine);
4970
5305
  }
@@ -4979,17 +5314,25 @@ export function emitDeclarations(documented: ApiModule, options?: EmitOptions):
4979
5314
  }
4980
5315
 
4981
5316
  // One `type <alias> = <slot type>;` per `OVERLOAD_SLOT_ALIASES` slot these
4982
- // functions carry, in alias order. The type is the one `emitFunction` reports
4983
- // for the slot, so it reads as the function's own signature would. The
4984
- // resolver spans these functions alone, leaving the module's own untouched.
5317
+ // functions carry, in alias order, skipping an alias one of the module's
5318
+ // top-level type `declarations` already names. The type is the one
5319
+ // `emitFunction` reports for the slot, so it reads as the function's own
5320
+ // signature would. The resolver spans these functions alone, leaving the
5321
+ // module's own untouched.
4985
5322
  function overloadSlotAliasDeclarations(
4986
5323
  functions: readonly ApiFunction[],
5324
+ declarations: readonly TypeDeclaration[],
4987
5325
  prefix: string,
4988
5326
  mapType: DefoldTypeMapper,
4989
5327
  constantTokens: ConstantSlotTokens,
4990
5328
  urlParameters: UrlParameterTable,
4991
5329
  bindingEvidence: ReadonlySet<string>,
4992
- ): string[] {
5330
+ ): { name: string; declaration: string }[] {
5331
+ const declared = new Set(
5332
+ declarations
5333
+ .filter((declaration) => declaration.path === declaration.name)
5334
+ .map((declaration) => declaration.name),
5335
+ );
4993
5336
  const resolver = buildTableDocResolver(
4994
5337
  functions.map((fn) => ({ name: fn.name, slots: [...fn.parameters, ...fn.returnValues] })),
4995
5338
  );
@@ -4997,7 +5340,7 @@ function overloadSlotAliasDeclarations(
4997
5340
  for (const fn of functions) {
4998
5341
  for (const [position, p] of fn.parameters.entries()) {
4999
5342
  const alias = OVERLOAD_SLOT_ALIASES.get(tableSlotKey(fn.name, "param", p.name));
5000
- if (alias === undefined) continue;
5343
+ if (alias === undefined || declared.has(alias)) continue;
5001
5344
  const prepared = prepareFunction(fn, prefix);
5002
5345
  if (prepared === null) continue;
5003
5346
  const slots: Record<string, SlotType> = {};
@@ -5024,7 +5367,51 @@ function overloadSlotAliasDeclarations(
5024
5367
  }
5025
5368
  return [...types]
5026
5369
  .sort(([a], [b]) => a.localeCompare(b))
5027
- .map(([alias, type]) => `type ${alias} = ${type};`);
5370
+ .map(([name, type]) => ({ name, declaration: `type ${name} = ${type};` }));
5371
+ }
5372
+
5373
+ // A method of a handle interface: the member text the declarations print inside
5374
+ // the interface, which its FUNCTION entry signs too.
5375
+ interface HandleMember {
5376
+ fn: PreparedFunction;
5377
+ text: string;
5378
+ slotTypes: SlotTypes;
5379
+ }
5380
+
5381
+ // Each handle interface a module's colon methods declare, sorted by name, with
5382
+ // its methods in group order.
5383
+ function collectHandleInterfaces(
5384
+ namespace: string,
5385
+ handleGroups: ReadonlyMap<string, readonly PreparedFunction[]>,
5386
+ mapType: DefoldTypeMapper,
5387
+ resolver: TableDocResolver,
5388
+ constantTokens: ConstantSlotTokens,
5389
+ urlParameters: UrlParameterTable,
5390
+ bindingEvidence: ReadonlySet<string>,
5391
+ ): { name: string; members: HandleMember[] }[] {
5392
+ return [...handleGroups]
5393
+ .map(([receiver, group]) => ({
5394
+ name: handleInterfaceName(namespace, receiver),
5395
+ members: group.map((fn): HandleMember => {
5396
+ const slotTypes: Record<string, SlotType> = {};
5397
+ const text = emitMethod(
5398
+ fn,
5399
+ mapType,
5400
+ resolver,
5401
+ constantTokens,
5402
+ urlParameters,
5403
+ bindingEvidence,
5404
+ slotTypes,
5405
+ );
5406
+ return { fn, text, slotTypes };
5407
+ }),
5408
+ }))
5409
+ .sort((a, b) => a.name.localeCompare(b.name));
5410
+ }
5411
+
5412
+ // An interface signed on one line, each member line followed by a space.
5413
+ function interfaceSignature(name: string, members: readonly string[]): string {
5414
+ return `interface ${name} { ${members.map((member) => `${member} `).join("")}}`;
5028
5415
  }
5029
5416
 
5030
5417
  /**
@@ -5184,24 +5571,29 @@ export function emitSymbolSignatures(
5184
5571
  });
5185
5572
  }
5186
5573
 
5574
+ // A handle interface signs as one line, as a struct does; each member is the
5575
+ // text its method's FUNCTION entry signs.
5187
5576
  const handleGroups = collectHandleMethodGroups(module);
5188
- for (const group of handleGroups.values()) {
5189
- for (const prepared of group) {
5190
- const slotTypes: Record<string, SlotType> = {};
5191
- out.push({
5192
- identity: fnIdentity(prepared.original),
5193
- tsSignature: emitMethod(
5194
- prepared,
5195
- mapType,
5196
- resolver,
5197
- constantTokens,
5198
- urlParameters,
5199
- bindingEvidence,
5200
- slotTypes,
5201
- ),
5202
- slotTypes,
5203
- });
5577
+ for (const { name, members } of collectHandleInterfaces(
5578
+ module.namespace,
5579
+ handleGroups,
5580
+ mapType,
5581
+ resolver,
5582
+ constantTokens,
5583
+ urlParameters,
5584
+ bindingEvidence,
5585
+ )) {
5586
+ for (const { fn, text, slotTypes } of members) {
5587
+ out.push({ identity: fnIdentity(fn.original), tsSignature: text, slotTypes });
5204
5588
  }
5589
+ out.push({
5590
+ identity: { namespace: module.namespace, kind: "TYPEDEF", name, signature: "" },
5591
+ tsSignature: interfaceSignature(
5592
+ name,
5593
+ members.map((member) => member.text),
5594
+ ),
5595
+ slotTypes: NO_SLOTS,
5596
+ });
5205
5597
  }
5206
5598
 
5207
5599
  const constants: PreparedConstant[] = [];
@@ -5230,7 +5622,7 @@ export function emitSymbolSignatures(
5230
5622
  // carries the first, which is verbatim in the `.d.ts` and is what the `/api`
5231
5623
  // render layer reduces to `<placeholder>: <type>`.
5232
5624
  for (const p of module.properties) {
5233
- const [firstMember = ""] = emitPropertyMembers(p, mapType, module.namespace);
5625
+ const [firstMember = ""] = emitPropertyMembers(p, mapType, module.namespace, bindingEvidence);
5234
5626
  out.push({
5235
5627
  identity: { namespace: module.namespace, kind: "PROPERTY", name: p.name, signature: "" },
5236
5628
  tsSignature: firstMember,
@@ -5240,13 +5632,14 @@ export function emitSymbolSignatures(
5240
5632
 
5241
5633
  // A struct signs as its interface on one line; each member line is verbatim in
5242
5634
  // the declarations.
5243
- for (const declaration of collectTypeDeclarations(
5635
+ const typeDeclarations = collectTypeDeclarations(
5244
5636
  module,
5245
- new Set(handleGroups.keys()),
5637
+ handleTypedefNames(module.namespace, handleGroups.keys()),
5246
5638
  rawMapType,
5247
5639
  mapType,
5248
5640
  bindingEvidence,
5249
- )) {
5641
+ );
5642
+ for (const declaration of typeDeclarations) {
5250
5643
  out.push({
5251
5644
  identity: {
5252
5645
  namespace: module.namespace,
@@ -5259,23 +5652,54 @@ export function emitSymbolSignatures(
5259
5652
  });
5260
5653
  }
5261
5654
 
5655
+ // An overload-slot alias is declared exactly where the declarations carry it,
5656
+ // so it signs from the same functions and the same declared set.
5657
+ for (const { name, declaration } of overloadSlotAliasDeclarations(
5658
+ [...module.functions, ...(options?.withheldFunctions ?? [])],
5659
+ typeDeclarations,
5660
+ prefix,
5661
+ mapType,
5662
+ constantTokens,
5663
+ urlParameters,
5664
+ bindingEvidence,
5665
+ )) {
5666
+ out.push({
5667
+ identity: { namespace: module.namespace, kind: "TYPEDEF", name, signature: "" },
5668
+ tsSignature: declaration,
5669
+ slotTypes: NO_SLOTS,
5670
+ });
5671
+ }
5672
+
5262
5673
  // The module's constant-union aliases travel as typedefs too: a signature that
5263
5674
  // names one carries no member list of its own, so the docs read the members
5264
5675
  // from here rather than from the emitter's table.
5265
- for (const row of CONSTANT_UNION_ALIASES.filter((r) => r.home === module.namespace)) {
5676
+ const enumAliases = collectEnumAliases(module, constants, nestedRoot);
5677
+ const ownedAliases =
5678
+ options?.ownsConstantUnionAliases === false
5679
+ ? []
5680
+ : ownedConstantUnionAliases(
5681
+ module.namespace,
5682
+ new Set(enumAliases.all.map((alias) => alias.path)),
5683
+ );
5684
+ for (const row of ownedAliases) {
5685
+ const name = engineTypeName(row.name);
5266
5686
  out.push({
5267
- identity: { namespace: module.namespace, kind: "TYPEDEF", name: row.name, signature: "" },
5268
- tsSignature: unionAliasDeclaration(row.name, row.members),
5687
+ identity: { namespace: module.namespace, kind: "TYPEDEF", name, signature: "" },
5688
+ tsSignature: unionAliasDeclaration(name, row.members),
5269
5689
  slotTypes: NO_SLOTS,
5270
5690
  });
5271
5691
  }
5272
5692
 
5273
- // An enum alias is keyed by its local path (`STATUS`, `ui.COLOR`), as the
5274
- // constant-union aliases above are keyed by their local name.
5275
- const enumAliases = collectEnumAliases(module, constants, nestedRoot);
5693
+ // An enum alias is keyed by its declared local path (`Status`, `ui.Color`),
5694
+ // as the constant-union aliases above are keyed by their declared name.
5276
5695
  for (const alias of enumAliases.all) {
5277
5696
  out.push({
5278
- identity: { namespace: module.namespace, kind: "TYPEDEF", name: alias.path, signature: "" },
5697
+ identity: {
5698
+ namespace: module.namespace,
5699
+ kind: "TYPEDEF",
5700
+ name: renamedLeaf(alias.path),
5701
+ signature: "",
5702
+ },
5279
5703
  tsSignature: unionAliasDeclaration(alias.name, alias.members, alias.nilable),
5280
5704
  slotTypes: NO_SLOTS,
5281
5705
  });
@@ -5317,8 +5741,9 @@ interface NestedGroup {
5317
5741
  children: Map<string, NestedGroup>;
5318
5742
  }
5319
5743
 
5320
- // One `ENUM`'s union alias: `name` is the declared identifier, `path` the local
5321
- // path under the module namespace (`ui.COLOR`), `members` the member FQNs.
5744
+ // One `ENUM`'s union alias: `name` is the declared identifier (`Color`), `path`
5745
+ // the reference's local path under the module namespace (`ui.COLOR`), `members`
5746
+ // the member FQNs.
5322
5747
  interface EnumAlias {
5323
5748
  name: string;
5324
5749
  path: string;
@@ -5447,12 +5872,14 @@ function collectEnumAliases(
5447
5872
  const nilable = new Set(module.constants.filter((c) => c.nilable).map((c) => c.name));
5448
5873
  const topLevel: EnumAlias[] = [];
5449
5874
  const all: EnumAlias[] = [];
5450
- const enums = [...(module.enums ?? [])].sort((a, b) => a.name.localeCompare(b.name));
5875
+ const enums = [...(module.enums ?? [])].sort((a, b) =>
5876
+ renamedLeaf(a.name).localeCompare(renamedLeaf(b.name)),
5877
+ );
5451
5878
  for (const e of enums) {
5452
5879
  if (e.members.length === 0 || !e.members.every((m) => declared.has(m))) continue;
5453
5880
  const path = stripPrefix(e.name, prefix);
5454
5881
  if (TS_IDENTIFIER.test(path)) {
5455
- const alias = { name: path, path, members: e.members, nilable };
5882
+ const alias = { name: engineTypeName(path), path, members: e.members, nilable };
5456
5883
  topLevel.push(alias);
5457
5884
  all.push(alias);
5458
5885
  continue;
@@ -5468,7 +5895,7 @@ function collectEnumAliases(
5468
5895
  level = group.children;
5469
5896
  }
5470
5897
  if (group === undefined) continue;
5471
- const alias = { name, path, members: e.members, nilable };
5898
+ const alias = { name: engineTypeName(name), path, members: e.members, nilable };
5472
5899
  group.enumAliases.push(alias);
5473
5900
  all.push(alias);
5474
5901
  }
@@ -5749,6 +6176,7 @@ function memberSignature(
5749
6176
  constantTokens,
5750
6177
  elementName,
5751
6178
  urlParameters,
6179
+ bindingEvidence,
5752
6180
  required.has(i),
5753
6181
  prepared.retype?.get(i),
5754
6182
  ),
@@ -5764,6 +6192,7 @@ function memberSignature(
5764
6192
  constantTokens,
5765
6193
  elementName,
5766
6194
  urlParameters,
6195
+ bindingEvidence,
5767
6196
  );
5768
6197
  const params = [...positional.map((p) => p.text), ...(rest ? [rest.text] : [])].join(", ");
5769
6198
  const ret = emitReturn(
@@ -6029,6 +6458,7 @@ function parameterType(
6029
6458
  constantTokens: ConstantSlotTokens,
6030
6459
  elementName: string,
6031
6460
  urlParameters: UrlParameterTable,
6461
+ bindingEvidence: ReadonlySet<string>,
6032
6462
  ): string {
6033
6463
  const concrete = p.types.filter((t) => t !== "nil");
6034
6464
  // The caller supplies a parameter, so a string-keyed table in it also takes an
@@ -6050,10 +6480,20 @@ function parameterType(
6050
6480
  elementName,
6051
6481
  "param",
6052
6482
  p.name,
6483
+ bindingEvidence,
6484
+ p.fields,
6053
6485
  )
6054
6486
  : "unknown";
6055
- const correction = PARAM_TYPE_CORRECTIONS.get(tableSlotKey(elementName, "param", p.name));
6056
- if (correction === undefined || !pinMatches(p.types, correctionPins(correction))) return mapped;
6487
+ const key = tableSlotKey(elementName, "param", p.name);
6488
+ const correction = PARAM_TYPE_CORRECTIONS.get(key);
6489
+ if (
6490
+ correction === undefined ||
6491
+ !pinMatches(p.types, correctionPins(correction)) ||
6492
+ (correction.binding !== undefined && !bindingEvidence.has(key))
6493
+ ) {
6494
+ return mapped;
6495
+ }
6496
+ if (correction.ts !== undefined) return correction.ts;
6057
6497
  const kept =
6058
6498
  correction.removes === undefined ? mapped : withoutUnionMembers(mapped, correction.removes);
6059
6499
  if (correction.adds === undefined) return kept;
@@ -6135,13 +6575,22 @@ function emitRestParameter(
6135
6575
  constantTokens: ConstantSlotTokens,
6136
6576
  elementName: string,
6137
6577
  urlParameters: UrlParameterTable,
6578
+ bindingEvidence: ReadonlySet<string>,
6138
6579
  ): { text: string; slots: EmittedSlot[] } {
6139
6580
  const vararg = params[varargIndex];
6140
6581
  if (vararg === undefined) return { text: "", slots: [] };
6141
6582
  const folded = params.slice(varargIndex).map((p, offset) => ({
6142
6583
  position: varargIndex + offset,
6143
6584
  name: p.name,
6144
- ts: parameterType(p, mapType, resolver, constantTokens, elementName, urlParameters),
6585
+ ts: parameterType(
6586
+ p,
6587
+ mapType,
6588
+ resolver,
6589
+ constantTokens,
6590
+ elementName,
6591
+ urlParameters,
6592
+ bindingEvidence,
6593
+ ),
6145
6594
  }));
6146
6595
  const members = [...new Set(folded.map((slot) => slot.ts))];
6147
6596
  const first = members[0] ?? "unknown";
@@ -6169,12 +6618,21 @@ function emitParameter(
6169
6618
  constantTokens: ConstantSlotTokens,
6170
6619
  elementName: string,
6171
6620
  urlParameters: UrlParameterTable,
6621
+ bindingEvidence: ReadonlySet<string>,
6172
6622
  required = false,
6173
6623
  retype: (type: string) => string = (type) => type,
6174
6624
  ): { text: string; type: string; optional: boolean } {
6175
6625
  const name = safeParamName(p.name, index);
6176
6626
  const ts = retype(
6177
- parameterType(p, mapType, resolver, constantTokens, elementName, urlParameters),
6627
+ parameterType(
6628
+ p,
6629
+ mapType,
6630
+ resolver,
6631
+ constantTokens,
6632
+ elementName,
6633
+ urlParameters,
6634
+ bindingEvidence,
6635
+ ),
6178
6636
  );
6179
6637
  // An interior doc-optional param (a required param follows, so the trailing-`?`
6180
6638
  // projection cannot mark it) keeps its optionality as `| undefined` — TSTL
@@ -6246,6 +6704,8 @@ function emitReturn(
6246
6704
  elementName,
6247
6705
  "return",
6248
6706
  rv.name,
6707
+ bindingEvidence,
6708
+ rv.fields,
6249
6709
  )
6250
6710
  : "unknown"),
6251
6711
  };
@@ -6284,6 +6744,8 @@ function emitReturn(
6284
6744
  elementName,
6285
6745
  "return",
6286
6746
  first.name,
6747
+ bindingEvidence,
6748
+ first.fields,
6287
6749
  )
6288
6750
  : "unknown";
6289
6751
  // A LuaLS vararg return (`...`) is every value the call returns, however many.
@@ -6323,12 +6785,17 @@ function emitPropertyMembers(
6323
6785
  p: ApiProperty,
6324
6786
  mapType: DefoldTypeMapper,
6325
6787
  namespace: string,
6788
+ bindingEvidence: ReadonlySet<string>,
6326
6789
  ): readonly string[] {
6327
- const keyRange = PROPERTY_KEY_RANGES.get(`${namespace}.${p.name}`);
6790
+ const rangeKey = `${namespace}.${p.name}`;
6791
+ const keyRange = PROPERTY_KEY_RANGES.get(rangeKey);
6328
6792
  const keys: string[] = [];
6329
6793
  if (keyRange !== undefined) {
6330
- for (let unit = keyRange.first; unit <= keyRange.last; unit++)
6331
- keys.push(`${keyRange.prefix}${unit}`);
6794
+ const last =
6795
+ keyRange.engine !== undefined && bindingEvidence.has(rangeKey)
6796
+ ? keyRange.engine.last
6797
+ : keyRange.last;
6798
+ for (let unit = keyRange.first; unit <= last; unit++) keys.push(`${keyRange.prefix}${unit}`);
6332
6799
  } else {
6333
6800
  keys.push(TS_IDENTIFIER.test(p.name) ? p.name : JSON.stringify(p.name));
6334
6801
  }
@@ -6392,6 +6859,73 @@ function wrappedInParens(text: string): boolean {
6392
6859
  return false;
6393
6860
  }
6394
6861
 
6862
+ // A ref-doc slot's structured `fields` (a `.script_api` callback's `parameters:`
6863
+ // or a table's `fields:`) as the field list `inlineTableType` renders. A field
6864
+ // flagged `is_optional` keeps that flag so a return-side or callback-argument
6865
+ // table marks only it `?`; a nested table's own fields nest the same way.
6866
+ function refDocTableFields(fields: readonly ApiParameter[]): TableField[] {
6867
+ return fields.map((field) => {
6868
+ const out: TableField = { name: field.name, types: field.types };
6869
+ if (field.fields !== undefined) out.fields = refDocTableFields(field.fields);
6870
+ if (field.isOptional) out.optional = true;
6871
+ return out;
6872
+ });
6873
+ }
6874
+
6875
+ // The TS type of one documented callback argument. The engine supplies these
6876
+ // values, so a table argument's fields are required unless flagged optional; a
6877
+ // `self` argument is the calling script instance, typed `unknown` like the
6878
+ // engine callback corrections type it.
6879
+ // A `constant` argument expands to the brands its own doc names, through the
6880
+ // slot's constant resolver; one whose doc names none keeps the generic brand.
6881
+ function callbackArgumentType(
6882
+ field: ApiParameter,
6883
+ mapType: DefoldTypeMapper,
6884
+ constantsNamed: (doc: string) => readonly string[],
6885
+ ): string {
6886
+ if (field.name === "self") return "unknown";
6887
+ if (field.fields !== undefined && field.fields.length > 0) {
6888
+ if (field.types.includes("function")) {
6889
+ return callbackTypeFromFields(field.fields, mapType, constantsNamed);
6890
+ }
6891
+ if (field.types.includes("table")) {
6892
+ return inlineTableType(refDocTableFields(field.fields), mapType, false);
6893
+ }
6894
+ }
6895
+ if (field.types.includes("constant")) {
6896
+ const fqns = constantsNamed(field.doc);
6897
+ if (fqns.length > 0) {
6898
+ const others = field.types.filter((token) => token !== "constant");
6899
+ return unionFromTokens([...fqns, ...others], mapType);
6900
+ }
6901
+ }
6902
+ return field.types.length > 0 ? unionFromTokens(field.types, mapType) : "unknown";
6903
+ }
6904
+
6905
+ // Renders a `function` slot's documented arguments as `(name: T, ...) => void`.
6906
+ // Optionality follows `emitParameter`: a trailing optional run takes `?`, an
6907
+ // interior optional argument takes `| undefined` because TS forbids a required
6908
+ // parameter after an optional one.
6909
+ function callbackTypeFromFields(
6910
+ fields: readonly ApiParameter[],
6911
+ mapType: DefoldTypeMapper,
6912
+ constantsNamed: (doc: string) => readonly string[],
6913
+ ): string {
6914
+ let trailingOptionalFrom = fields.length;
6915
+ while (trailingOptionalFrom > 0 && fields[trailingOptionalFrom - 1]?.isOptional === true) {
6916
+ trailingOptionalFrom--;
6917
+ }
6918
+ const args = fields.map((field, index) => {
6919
+ const name = safeParamName(field.name, index);
6920
+ const ts = callbackArgumentType(field, mapType, constantsNamed);
6921
+ if (index >= trailingOptionalFrom) return `${name}?: ${ts}`;
6922
+ if (!field.isOptional) return `${name}: ${ts}`;
6923
+ const operand = isFunctionTypeText(ts) ? `(${ts})` : ts;
6924
+ return `${name}: ${operand} | undefined`;
6925
+ });
6926
+ return `(${args.join(", ")}) => void`;
6927
+ }
6928
+
6395
6929
  // Like `unionFromTokens`, but a `table` token whose slot doc carries a parseable
6396
6930
  // `<dl>` field list emits an inline object type instead of the opaque `Record`
6397
6931
  // fallback. Other tokens in the union map unchanged. `optionalFields` marks the
@@ -6399,6 +6933,10 @@ function wrappedInParens(text: string): boolean {
6399
6933
  // optionality and an input option-bag's fields are individually omittable (the
6400
6934
  // old `Record` accepted partial/empty objects), so a parameter's fields are
6401
6935
  // optional while a return's fields (engine-populated, all present) stay required.
6936
+ // A slot carrying structured ref-doc `fields` (a `.script_api` conversion) types
6937
+ // a `table` token from them ahead of the prose parser and the curations, the
6938
+ // precedence `slotFieldNames` applies, and a `function` token from them as a
6939
+ // typed callback signature.
6402
6940
  function mapSlotUnion(
6403
6941
  types: readonly string[],
6404
6942
  doc: string,
@@ -6407,8 +6945,10 @@ function mapSlotUnion(
6407
6945
  resolver: TableDocResolver,
6408
6946
  constantTokens: ConstantSlotTokens,
6409
6947
  elementName: string,
6410
- slotKind?: "param" | "return",
6411
- slotName?: string,
6948
+ slotKind: "param" | "return" | undefined,
6949
+ slotName: string | undefined,
6950
+ bindingEvidence: ReadonlySet<string>,
6951
+ fields?: readonly ApiParameter[],
6412
6952
  ): string {
6413
6953
  const mapped: string[] = [];
6414
6954
  const seen = new Set<string>();
@@ -6417,6 +6957,7 @@ function mapSlotUnion(
6417
6957
  seen.add(ts);
6418
6958
  mapped.push(ts);
6419
6959
  };
6960
+ const structured = fields !== undefined && fields.length > 0 ? fields : undefined;
6420
6961
  for (const token of types) {
6421
6962
  if (token === "constant" && slotKind !== undefined && slotName !== undefined) {
6422
6963
  const expanded = constantTokens(elementName, slotKind, slotName, doc);
@@ -6430,7 +6971,15 @@ function mapSlotUnion(
6430
6971
  slotKind !== undefined && slotName !== undefined
6431
6972
  ? TABLE_SLOT_CURATIONS.get(tableSlotKey(elementName, slotKind, slotName))
6432
6973
  : undefined;
6433
- if (token === "table" || slotCuration?.retypedUpstream?.includes(token) === true) {
6974
+ if (token === "table" && structured !== undefined) {
6975
+ ts = inlineTableType(refDocTableFields(structured), mapType, optionalFields);
6976
+ } else if (token === "function" && structured !== undefined) {
6977
+ ts = callbackTypeFromFields(structured, mapType, (fieldDoc) =>
6978
+ slotKind !== undefined && slotName !== undefined
6979
+ ? constantTokens(elementName, slotKind, slotName, fieldDoc)
6980
+ : [],
6981
+ );
6982
+ } else if (token === "table" || slotCuration?.retypedUpstream?.includes(token) === true) {
6434
6983
  const curation = slotCuration;
6435
6984
  const mapping =
6436
6985
  curation?.kind === "mapping" ? curation : MAPPING_TABLE_SLOTS.get(elementName);
@@ -6501,6 +7050,7 @@ function mapSlotUnion(
6501
7050
  slotKind,
6502
7051
  slotName,
6503
7052
  parseTableFields(doc, resolver, slotName) ?? [],
7053
+ bindingEvidence,
6504
7054
  ),
6505
7055
  );
6506
7056
  const object = inlineTableType(parsed, mapType, optionalFields);
@@ -6510,7 +7060,13 @@ function mapSlotUnion(
6510
7060
  if (parsed !== null) {
6511
7061
  const added = applyFieldAdditions(elementName, slotKind, slotName, parsed);
6512
7062
  const nested = applyNestedFieldCurations(elementName, slotKind, slotName, added);
6513
- const typed = applyFieldTypeOverrides(elementName, slotKind, slotName, nested);
7063
+ const typed = applyFieldTypeOverrides(
7064
+ elementName,
7065
+ slotKind,
7066
+ slotName,
7067
+ nested,
7068
+ bindingEvidence,
7069
+ );
6514
7070
  const required = applyRequiredFieldCorrections(
6515
7071
  elementName,
6516
7072
  slotKind,
@@ -6680,8 +7236,8 @@ function withoutSubsumedOpaqueArms(mapped: readonly string[]): string[] {
6680
7236
  });
6681
7237
  }
6682
7238
 
6683
- // Joins already-mapped arms, collapsing the branded ones to their alias when
6684
- // they are exactly a `CONSTANT_UNION_ALIASES` member set. The alias takes the
7239
+ // Joins already-mapped arms, collapsing the branded ones to their row's spelling
7240
+ // when they are exactly a `CONSTANT_UNION_ALIASES` member set. The spelling takes the
6685
7241
  // position of the first branded arm, so a mixed union keeps its reading order
6686
7242
  // (`gui.Easing | Vector`). Arms that are not constants are untouched, and a set
6687
7243
  // with no row keeps every arm inline.
@@ -6699,7 +7255,7 @@ function joinUnionArms(mapped: readonly string[]): string {
6699
7255
  for (const arm of arms) {
6700
7256
  if (BRAND_ARM.test(arm)) {
6701
7257
  if (placed) continue;
6702
- out.push(`${alias.home}.${alias.name}`);
7258
+ out.push(constantUnionSpelling(alias));
6703
7259
  placed = true;
6704
7260
  continue;
6705
7261
  }