@defold-typescript/types 0.40.0 → 0.42.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 (224) hide show
  1. package/api-availability.json +3963 -772
  2. package/api-migrations.json +27 -0
  3. package/api-signatures.json +18069 -10240
  4. package/api-targets.json +448 -11
  5. package/examples/translations.json +560 -89
  6. package/fixtures/messages_doc.json +96 -0
  7. package/generated/b2d.d.ts +680 -4
  8. package/generated/b2d_body.d.ts +29 -103
  9. package/generated/b2d_chain.d.ts +5 -6
  10. package/generated/b2d_fixture.d.ts +34 -38
  11. package/generated/b2d_joint.d.ts +503 -25
  12. package/generated/b2d_shape.d.ts +183 -20
  13. package/generated/b2d_world.d.ts +57 -63
  14. package/generated/buffer.d.ts +16 -15
  15. package/generated/builtin-messages.d.ts +7 -1
  16. package/generated/bullet3d.d.ts +91 -0
  17. package/generated/bullet3d_collision_object.d.ts +433 -0
  18. package/generated/bullet3d_constraint.d.ts +818 -0
  19. package/generated/bullet3d_rigid_body.d.ts +429 -0
  20. package/generated/bullet3d_shape.d.ts +123 -0
  21. package/generated/bullet3d_world.d.ts +492 -0
  22. package/generated/camera.d.ts +29 -32
  23. package/generated/collectionfactory.d.ts +15 -18
  24. package/generated/collectionproxy.d.ts +22 -6
  25. package/generated/compute.d.ts +12 -238
  26. package/generated/crash.d.ts +24 -10
  27. package/generated/editor-vm/http.d.ts +90 -7
  28. package/generated/editor-vm/image.d.ts +7 -7
  29. package/generated/editor-vm/json.d.ts +11 -0
  30. package/generated/editor-vm/localization.d.ts +7 -7
  31. package/generated/editor-vm/tilemap_tiles.d.ts +56 -10
  32. package/generated/editor-vm/zip.d.ts +28 -0
  33. package/generated/editor.d.ts +1496 -430
  34. package/generated/factory.d.ts +21 -25
  35. package/generated/font.d.ts +64 -22
  36. package/generated/go.d.ts +235 -182
  37. package/generated/graphics.d.ts +335 -97
  38. package/generated/gui.d.ts +240 -471
  39. package/generated/html5.d.ts +2 -2
  40. package/generated/http.d.ts +28 -35
  41. package/generated/image.d.ts +105 -72
  42. package/generated/json.d.ts +34 -16
  43. package/generated/kinds/gui-script.d.ts +7 -0
  44. package/generated/kinds/render-script.d.ts +7 -0
  45. package/generated/kinds/script.d.ts +7 -0
  46. package/generated/label.d.ts +77 -7
  47. package/generated/liveupdate.d.ts +13 -10
  48. package/generated/material.d.ts +312 -360
  49. package/generated/model.d.ts +40 -39
  50. package/generated/particlefx.d.ts +19 -28
  51. package/generated/physics.d.ts +365 -133
  52. package/generated/profiler.d.ts +13 -23
  53. package/generated/render.d.ts +237 -297
  54. package/generated/resource.d.ts +664 -583
  55. package/generated/socket.d.ts +120 -133
  56. package/generated/sound.d.ts +62 -31
  57. package/generated/sprite.d.ts +31 -17
  58. package/generated/sys.d.ts +234 -190
  59. package/generated/tilemap.d.ts +21 -16
  60. package/generated/timer.d.ts +34 -21
  61. package/generated/versions/defold-1.12.4/b2d_body.d.ts +0 -7
  62. package/generated/versions/defold-1.12.4/buffer.d.ts +1 -3
  63. package/generated/versions/defold-1.12.4/camera.d.ts +21 -21
  64. package/generated/versions/defold-1.12.4/collectionfactory.d.ts +9 -9
  65. package/generated/versions/defold-1.12.4/collectionproxy.d.ts +2 -2
  66. package/generated/versions/defold-1.12.4/crash.d.ts +2 -2
  67. package/generated/versions/defold-1.12.4/factory.d.ts +15 -16
  68. package/generated/versions/defold-1.12.4/go.d.ts +6 -12
  69. package/generated/versions/defold-1.12.4/gui.d.ts +77 -175
  70. package/generated/versions/defold-1.12.4/html5.d.ts +1 -1
  71. package/generated/versions/defold-1.12.4/http.d.ts +0 -13
  72. package/generated/versions/defold-1.12.4/image.d.ts +16 -33
  73. package/generated/versions/defold-1.12.4/index.d.ts +1 -0
  74. package/generated/versions/defold-1.12.4/json.d.ts +10 -6
  75. package/generated/versions/defold-1.12.4/label.d.ts +2 -3
  76. package/generated/versions/defold-1.12.4/liveupdate.d.ts +5 -3
  77. package/generated/versions/defold-1.12.4/model.d.ts +2 -10
  78. package/generated/versions/defold-1.12.4/particlefx.d.ts +2 -5
  79. package/generated/versions/defold-1.12.4/physics.d.ts +69 -67
  80. package/generated/versions/defold-1.12.4/profiler.d.ts +2 -5
  81. package/generated/versions/defold-1.12.4/render.d.ts +99 -128
  82. package/generated/versions/defold-1.12.4/resource.d.ts +120 -148
  83. package/generated/versions/defold-1.12.4/socket.d.ts +34 -60
  84. package/generated/versions/defold-1.12.4/sound.d.ts +8 -8
  85. package/generated/versions/defold-1.12.4/sprite.d.ts +15 -5
  86. package/generated/versions/defold-1.12.4/sys.d.ts +37 -71
  87. package/generated/versions/defold-1.12.4/tilemap.d.ts +18 -11
  88. package/generated/versions/defold-1.12.4/timer.d.ts +5 -3
  89. package/generated/versions/defold-1.12.4/vmath.d.ts +0 -21
  90. package/generated/versions/defold-1.12.4/window.d.ts +1 -16
  91. package/generated/versions/defold-1.13.0/b2d_body.d.ts +10 -55
  92. package/generated/versions/defold-1.13.0/b2d_fixture.d.ts +25 -25
  93. package/generated/versions/defold-1.13.0/b2d_shape.d.ts +169 -8
  94. package/generated/versions/defold-1.13.0/b2d_world.d.ts +16 -10
  95. package/generated/versions/defold-1.13.0/buffer.d.ts +1 -3
  96. package/generated/versions/defold-1.13.0/camera.d.ts +25 -25
  97. package/generated/versions/defold-1.13.0/collectionfactory.d.ts +9 -9
  98. package/generated/versions/defold-1.13.0/collectionproxy.d.ts +2 -2
  99. package/generated/versions/defold-1.13.0/compute.d.ts +0 -69
  100. package/generated/versions/defold-1.13.0/crash.d.ts +2 -2
  101. package/generated/versions/defold-1.13.0/editor-vm/tilemap_tiles.d.ts +3 -3
  102. package/generated/versions/defold-1.13.0/editor.d.ts +34 -24
  103. package/generated/versions/defold-1.13.0/factory.d.ts +15 -16
  104. package/generated/versions/defold-1.13.0/go.d.ts +6 -12
  105. package/generated/versions/defold-1.13.0/graphics.d.ts +73 -37
  106. package/generated/versions/defold-1.13.0/gui.d.ts +77 -175
  107. package/generated/versions/defold-1.13.0/html5.d.ts +1 -1
  108. package/generated/versions/defold-1.13.0/http.d.ts +0 -13
  109. package/generated/versions/defold-1.13.0/image.d.ts +16 -33
  110. package/generated/versions/defold-1.13.0/index.d.ts +1 -0
  111. package/generated/versions/defold-1.13.0/json.d.ts +10 -6
  112. package/generated/versions/defold-1.13.0/label.d.ts +2 -3
  113. package/generated/versions/defold-1.13.0/liveupdate.d.ts +7 -5
  114. package/generated/versions/defold-1.13.0/material.d.ts +68 -106
  115. package/generated/versions/defold-1.13.0/model.d.ts +2 -10
  116. package/generated/versions/defold-1.13.0/particlefx.d.ts +2 -5
  117. package/generated/versions/defold-1.13.0/physics.d.ts +69 -67
  118. package/generated/versions/defold-1.13.0/profiler.d.ts +2 -5
  119. package/generated/versions/defold-1.13.0/render.d.ts +99 -128
  120. package/generated/versions/defold-1.13.0/resource.d.ts +126 -150
  121. package/generated/versions/defold-1.13.0/socket.d.ts +34 -60
  122. package/generated/versions/defold-1.13.0/sound.d.ts +8 -8
  123. package/generated/versions/defold-1.13.0/sprite.d.ts +15 -5
  124. package/generated/versions/defold-1.13.0/sys.d.ts +37 -71
  125. package/generated/versions/defold-1.13.0/tilemap.d.ts +18 -11
  126. package/generated/versions/defold-1.13.0/timer.d.ts +5 -3
  127. package/generated/versions/defold-1.13.0/vmath.d.ts +0 -21
  128. package/generated/versions/defold-1.13.0/window.d.ts +1 -16
  129. package/generated/versions/defold-1.13.1/b2d.d.ts +33 -0
  130. package/generated/versions/defold-1.13.1/b2d_body.d.ts +636 -0
  131. package/generated/versions/defold-1.13.1/b2d_chain.d.ts +106 -0
  132. package/generated/versions/defold-1.13.1/b2d_fixture.d.ts +157 -0
  133. package/generated/versions/defold-1.13.1/b2d_joint.d.ts +823 -0
  134. package/generated/versions/defold-1.13.1/b2d_shape.d.ts +400 -0
  135. package/generated/versions/defold-1.13.1/b2d_world.d.ts +320 -0
  136. package/generated/versions/defold-1.13.1/buffer.d.ts +189 -0
  137. package/generated/versions/defold-1.13.1/camera.d.ts +303 -0
  138. package/generated/versions/defold-1.13.1/collectionfactory.d.ts +151 -0
  139. package/generated/versions/defold-1.13.1/collectionproxy.d.ts +93 -0
  140. package/generated/versions/defold-1.13.1/compute.d.ts +237 -0
  141. package/generated/versions/defold-1.13.1/crash.d.ts +143 -0
  142. package/generated/versions/defold-1.13.1/editor-vm/http.d.ts +56 -0
  143. package/generated/versions/defold-1.13.1/editor-vm/image.d.ts +48 -0
  144. package/generated/versions/defold-1.13.1/editor-vm/json.d.ts +10 -0
  145. package/generated/versions/defold-1.13.1/editor-vm/localization.d.ts +42 -0
  146. package/generated/versions/defold-1.13.1/editor-vm/tilemap_tiles.d.ts +80 -0
  147. package/generated/versions/defold-1.13.1/editor-vm/zip.d.ts +10 -0
  148. package/generated/versions/defold-1.13.1/editor-vm/zlib.d.ts +24 -0
  149. package/generated/versions/defold-1.13.1/editor.d.ts +1121 -0
  150. package/generated/versions/defold-1.13.1/factory.d.ts +124 -0
  151. package/generated/versions/defold-1.13.1/font.d.ts +81 -0
  152. package/generated/versions/defold-1.13.1/go.d.ts +1107 -0
  153. package/generated/versions/defold-1.13.1/graphics.d.ts +411 -0
  154. package/generated/versions/defold-1.13.1/gui.d.ts +2353 -0
  155. package/generated/versions/defold-1.13.1/html5.d.ts +55 -0
  156. package/generated/versions/defold-1.13.1/http.d.ts +77 -0
  157. package/generated/versions/defold-1.13.1/image.d.ts +131 -0
  158. package/generated/versions/defold-1.13.1/index.d.ts +57 -0
  159. package/generated/versions/defold-1.13.1/json.d.ts +80 -0
  160. package/generated/versions/defold-1.13.1/kinds/editor-script.d.ts +14 -0
  161. package/generated/versions/defold-1.13.1/label.d.ts +93 -0
  162. package/generated/versions/defold-1.13.1/liveupdate.d.ts +142 -0
  163. package/generated/versions/defold-1.13.1/material.d.ts +408 -0
  164. package/generated/versions/defold-1.13.1/model.d.ts +272 -0
  165. package/generated/versions/defold-1.13.1/msg.d.ts +10 -0
  166. package/generated/versions/defold-1.13.1/particlefx.d.ts +163 -0
  167. package/generated/versions/defold-1.13.1/physics.d.ts +559 -0
  168. package/generated/versions/defold-1.13.1/profiler.d.ts +235 -0
  169. package/generated/versions/defold-1.13.1/render.d.ts +1190 -0
  170. package/generated/versions/defold-1.13.1/resource.d.ts +1523 -0
  171. package/generated/versions/defold-1.13.1/socket.d.ts +784 -0
  172. package/generated/versions/defold-1.13.1/sound.d.ts +292 -0
  173. package/generated/versions/defold-1.13.1/sprite.d.ts +175 -0
  174. package/generated/versions/defold-1.13.1/sys.d.ts +678 -0
  175. package/generated/versions/defold-1.13.1/tilemap.d.ts +208 -0
  176. package/generated/versions/defold-1.13.1/timer.d.ts +125 -0
  177. package/generated/versions/defold-1.13.1/types.d.ts +61 -0
  178. package/generated/versions/defold-1.13.1/vmath.d.ts +774 -0
  179. package/generated/versions/defold-1.13.1/window.d.ts +183 -0
  180. package/generated/versions/defold-1.13.1/zlib.d.ts +41 -0
  181. package/generated/vmath.d.ts +1 -21
  182. package/generated/window.d.ts +71 -71
  183. package/identity-vocabulary.json +561 -0
  184. package/index.d.ts +7 -0
  185. package/package.json +18 -2
  186. package/scripts/example-store-io.ts +12 -1
  187. package/scripts/extension-goldens.ts +1 -0
  188. package/scripts/fidelity-baseline.json +146 -46
  189. package/scripts/generate-api-availability.ts +90 -12
  190. package/scripts/generate-api-signatures.ts +12 -2
  191. package/scripts/import-defold-release.ts +106 -26
  192. package/scripts/prose-constants.ts +77 -16
  193. package/scripts/regen.ts +391 -77
  194. package/scripts/shared-handle-methods.ts +53 -0
  195. package/scripts/signature-store-fs.ts +1 -0
  196. package/scripts/sync-api-docs.ts +48 -10
  197. package/src/api-availability.ts +0 -0
  198. package/src/api-doc.ts +201 -3
  199. package/src/api-identity.ts +252 -0
  200. package/src/core-types.ts +26 -3
  201. package/src/correction-pins.ts +49 -0
  202. package/src/doc-comment.ts +104 -11
  203. package/src/doc-corrections.ts +108 -0
  204. package/src/editor-vm-globals.d.ts +5 -2
  205. package/src/emit-dts.ts +2064 -281
  206. package/src/emit-messages.ts +52 -0
  207. package/src/example-store.ts +125 -14
  208. package/src/field-correction-coverage.ts +204 -0
  209. package/src/fnv1a.ts +16 -0
  210. package/src/go-overloads.d.ts +25 -6
  211. package/src/index-base-table.ts +145 -0
  212. package/src/index-slot-classifications.ts +588 -0
  213. package/src/index.ts +38 -5
  214. package/src/library-index-slot-classifications.ts +332 -0
  215. package/src/lifecycle.ts +61 -199
  216. package/src/luals-type-expr.ts +354 -0
  217. package/src/msg-overloads.d.ts +0 -1
  218. package/src/param-correction-provenance.ts +8 -11
  219. package/src/render-overloads.d.ts +0 -15
  220. package/src/return-correction-provenance.ts +58 -16
  221. package/src/sys-overloads.d.ts +48 -0
  222. package/src/vmath-overloads.d.ts +27 -1
  223. package/src/window-event-guard.d.ts +6 -9
  224. package/url-parameters.json +1 -2
@@ -0,0 +1,53 @@
1
+ import type { ModuleManifestEntry } from "./regen";
2
+
3
+ // A method the engine shares across several handle classes where a release's
4
+ // ref-doc documents it on only some of them. The handles it omits are restored
5
+ // from the documented one, so a doc omission never drops a method the engine
6
+ // still binds. Applies only where the source handle documents it.
7
+ export interface SharedHandleMethod {
8
+ readonly namespace: string;
9
+ readonly method: string;
10
+ readonly source: string;
11
+ readonly handles: readonly string[];
12
+ readonly evidence: string;
13
+ }
14
+
15
+ const TCP_ANY =
16
+ 'LuaSocket tcp.c binds it in the one method table every tcp class shares, and checks its argument with auxiliar_checkgroup(L, "tcp{any}", 1)';
17
+
18
+ export const SHARED_HANDLE_METHODS: readonly SharedHandleMethod[] = (
19
+ ["getstats", "setstats"] as const
20
+ ).map((method) => ({
21
+ namespace: "socket",
22
+ method,
23
+ source: "client",
24
+ handles: ["master", "server"],
25
+ evidence: TCP_ANY,
26
+ }));
27
+
28
+ interface DocElement {
29
+ readonly name: string;
30
+ }
31
+
32
+ export function restoreSharedHandleMethods(
33
+ modules: readonly ModuleManifestEntry[],
34
+ ): ModuleManifestEntry[] {
35
+ return modules.map((entry) => {
36
+ const shared = SHARED_HANDLE_METHODS.filter((row) => row.namespace === entry.namespace);
37
+ if (shared.length === 0) return entry;
38
+ const doc = entry.doc as { elements: DocElement[] };
39
+ const declared = new Set(doc.elements.map((element) => element.name));
40
+ const restored: DocElement[] = [];
41
+ for (const { method, source, handles } of shared) {
42
+ const documented = doc.elements.find((element) => element.name === `${source}:${method}`);
43
+ if (documented === undefined) continue;
44
+ for (const handle of handles) {
45
+ const name = `${handle}:${method}`;
46
+ if (!declared.has(name)) restored.push({ ...documented, name });
47
+ }
48
+ }
49
+ return restored.length === 0
50
+ ? entry
51
+ : { ...entry, doc: { ...doc, elements: [...doc.elements, ...restored] } };
52
+ });
53
+ }
@@ -25,6 +25,7 @@ export const VMATH_SIGNATURES_PATH = resolve(import.meta.dir, "..", "signatures"
25
25
  export const GO_SIGNATURES_PATH = resolve(import.meta.dir, "..", "signatures", "go.json");
26
26
  export const MSG_SIGNATURES_PATH = resolve(import.meta.dir, "..", "signatures", "msg.json");
27
27
  export const RENDER_SIGNATURES_PATH = resolve(import.meta.dir, "..", "signatures", "render.json");
28
+ export const SYS_SIGNATURES_PATH = resolve(import.meta.dir, "..", "signatures", "sys.json");
28
29
 
29
30
  export function loadSignatureFile(path: string): SignatureStore {
30
31
  let raw: string;
@@ -1,6 +1,6 @@
1
- import { mkdtempSync, readFileSync, writeFileSync } from "node:fs";
1
+ import { mkdirSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { tmpdir } from "node:os";
3
- import { join, resolve } from "node:path";
3
+ import { dirname, join, resolve } from "node:path";
4
4
  import { type ApiModule, parseDefoldApiDoc } from "../src/api-doc";
5
5
  import { DEFOLD_TYPE_MAP } from "../src/core-types";
6
6
  import { parseScriptApi } from "../src/script-api";
@@ -11,7 +11,7 @@ import { MODULE_MANIFEST } from "./regen";
11
11
  // model because the per-package `rootDir` boundary forbids a types-package
12
12
  // module importing outside its own tree; `scripts/release-model.test.ts`
13
13
  // correspondence-guards these against the model so drift fails CI.
14
- export const DEFOLD_VERSION = "1.13.1";
14
+ export const DEFOLD_VERSION = "1.13.2";
15
15
  export const refDocUrl = (version = DEFOLD_VERSION): string =>
16
16
  `https://github.com/defold/defold/releases/download/${version}/ref-doc.zip`;
17
17
 
@@ -52,13 +52,24 @@ export const SYNC_MANIFEST: readonly SyncManifestEntry[] = [
52
52
  "doc/scripts-box2d-v3-script_box2d_world_v3.cpp_doc.json",
53
53
  ]),
54
54
  entry("buffer", "doc/scripts-script_buffer.cpp_doc.json"),
55
+ entry("bullet3d", "doc/scripts-bullet3d-script_bullet3d.cpp_doc.json"),
56
+ entry(
57
+ "bullet3d.collision_object",
58
+ "doc/scripts-bullet3d-script_bullet3d_collision_object.cpp_doc.json",
59
+ ),
60
+ entry("bullet3d.constraint", "doc/scripts-bullet3d-script_bullet3d_constraint.cpp_doc.json"),
61
+ entry("bullet3d.rigid_body", "doc/scripts-bullet3d-script_bullet3d_rigid_body.cpp_doc.json"),
62
+ entry("bullet3d.shape", "doc/scripts-bullet3d-script_bullet3d_shape.cpp_doc.json"),
63
+ entry("bullet3d.world", "doc/scripts-bullet3d-script_bullet3d_world.cpp_doc.json"),
55
64
  // Camera and component namespaces merge their DDF messages/properties into
56
65
  // the callable script API so release snapshots retain every declared symbol.
57
66
  entry("camera", "doc/gamesys-camera_ddf.proto_doc.json", undefined, [
58
67
  "doc/render-render_script_camera.cpp_doc.json",
59
68
  ]),
60
69
  entry("collectionfactory", "doc/scripts-script_collection_factory.cpp_doc.json"),
61
- entry("collectionproxy", "doc/scripts-script_collectionproxy.cpp_doc.json"),
70
+ entry("collectionproxy", "doc/scripts-script_collectionproxy.cpp_doc.json", undefined, [
71
+ "doc/gamesys-collectionproxy_ddf.proto_doc.json",
72
+ ]),
62
73
  entry("compute", "doc/scripts-script_compute.cpp_doc.json"),
63
74
  entry("crash", "doc/script_crash.cpp_doc.json"),
64
75
  entry("factory", "doc/scripts-script_factory.cpp_doc.json"),
@@ -115,11 +126,11 @@ export const SYNC_MANIFEST: readonly SyncManifestEntry[] = [
115
126
  export const UNMAPPED: ReadonlyMap<string, string> = new Map();
116
127
 
117
128
  // A Lua script namespace is a lowercase, dot-separated identifier (`sys`,
118
- // `b2d.body`). The native C/C++ SDK docs (`dmGraphics`, …), the C# bindings
129
+ // `b2d.body`, `bullet3d.rigid_body`). The native C/C++ SDK docs (`dmGraphics`, …), the C# bindings
119
130
  // (`cs-*`), and the struct-only docs (empty `info.namespace`) fail this shape,
120
131
  // so the upstream-coverage guard skips them structurally rather than listing
121
132
  // each by hand — that keeps the guard self-maintaining as the SDK grows.
122
- const LUA_NAMESPACE = /^[a-z][a-z0-9]*(\.[a-z][a-z0-9]*)*$/;
133
+ const LUA_NAMESPACE = /^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)*$/;
123
134
 
124
135
  // Lowercase-identifier namespaces that pass LUA_NAMESPACE but are intentionally
125
136
  // not wired through SYNC_MANIFEST, each with a sourced reason (mirrors the
@@ -205,7 +216,7 @@ function editorVm(namespace: string): SyncManifestEntry {
205
216
  function entry(
206
217
  namespace: string,
207
218
  zipEntry: string,
208
- fixture: string = `fixtures/defold-1.13.1/${namespace.replace(/\./g, "_")}_doc.json`,
219
+ fixture: string = `fixtures/defold-1.13.2/${namespace.replace(/\./g, "_")}_doc.json`,
209
220
  mergeEntries?: readonly string[],
210
221
  ): SyncManifestEntry {
211
222
  return { namespace, zipEntry, fixture, ...(mergeEntries ? { mergeEntries } : {}) };
@@ -393,6 +404,21 @@ export function extractFixtures(
393
404
  });
394
405
  }
395
406
 
407
+ // Since 1.13.2 the ref-doc zip ships LuaLS annotation files beside the JSON:
408
+ // `doc/<namespace>.lua` for the game runtime and `doc/<namespace>.editor_script`
409
+ // for the editor VM. They are vendored verbatim, never parsed at sync time.
410
+ const ANNOTATION_ENTRY = /^doc\/([^/]+\.(?:lua|editor_script))$/;
411
+
412
+ export function extractAnnotationFixtures(zip: ZipAccessor): ExtractedFixture[] {
413
+ const out: ExtractedFixture[] = [];
414
+ for (const zipEntry of [...zip.entries()].sort()) {
415
+ const file = ANNOTATION_ENTRY.exec(zipEntry)?.[1];
416
+ if (file === undefined) continue;
417
+ out.push({ namespace: file, fixture: `annotations/${file}`, contents: zip.read(zipEntry) });
418
+ }
419
+ return out;
420
+ }
421
+
396
422
  export type FixtureSyncStatus = "clean" | "drift" | "created";
397
423
 
398
424
  export interface FixtureSyncResult {
@@ -431,7 +457,8 @@ export function syncFixtures(zip: ZipAccessor, options: SyncOptions = {}): Fixtu
431
457
 
432
458
  // Compare/write a set of already-extracted fixtures against disk. Shared by
433
459
  // the core (zip) and extension (`.script_api`) sync paths so both honor the
434
- // identical created/clean/drift + format-on-write semantics.
460
+ // identical created/clean/drift + format-on-write semantics. A non-JSON fixture
461
+ // (a vendored annotation file) compares and writes byte-for-byte.
435
462
  export function syncExtractedFixtures(
436
463
  items: readonly ExtractedFixture[],
437
464
  options: Omit<SyncOptions, "manifest"> = {},
@@ -442,15 +469,21 @@ export function syncExtractedFixtures(
442
469
  const results: FixtureSyncResult[] = [];
443
470
  for (const item of items) {
444
471
  const path = resolve(root, item.fixture);
472
+ const json = item.fixture.endsWith(".json");
445
473
  const existing = readFixtureOrNull(path);
446
474
  const status: FixtureSyncStatus =
447
475
  existing === null
448
476
  ? "created"
449
- : canonicalJson(existing) === canonicalJson(item.contents)
477
+ : (
478
+ json
479
+ ? canonicalJson(existing) === canonicalJson(item.contents)
480
+ : existing === item.contents
481
+ )
450
482
  ? "clean"
451
483
  : "drift";
452
484
  if (!check && status !== "clean") {
453
- writeFileSync(path, format(item.contents));
485
+ mkdirSync(dirname(path), { recursive: true });
486
+ writeFileSync(path, json ? format(item.contents) : item.contents);
454
487
  }
455
488
  results.push({ namespace: item.namespace, fixture: item.fixture, status });
456
489
  }
@@ -630,11 +663,16 @@ if (import.meta.main) {
630
663
  const luaStdlibFixtures = extractFixtures(zip, LUA_STDLIB_MANIFEST);
631
664
  const editorFixtures = extractFixtures(zip, EDITOR_MANIFEST);
632
665
  const editorVmFixtures = extractFixtures(zip, EDITOR_VM_MANIFEST);
666
+ const annotationFixtures = extractAnnotationFixtures(zip);
633
667
  const results = [
634
668
  ...syncExtractedFixtures(coreFixtures, { check }),
635
669
  ...syncExtractedFixtures(luaStdlibFixtures, { check }),
636
670
  ...syncExtractedFixtures(editorFixtures, { check }),
637
671
  ...syncExtractedFixtures(editorVmFixtures, { check }),
672
+ ...syncExtractedFixtures(annotationFixtures, {
673
+ check,
674
+ fixturesRoot: resolve(PACKAGE_ROOT, `fixtures/defold-${DEFOLD_VERSION}`),
675
+ }),
638
676
  ];
639
677
  const syncedDocs = coreFixtures.map((f) => ({
640
678
  namespace: f.namespace,
Binary file
package/src/api-doc.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { correctedDoc, docCorrectionKey } from "./doc-corrections";
2
+
1
3
  export interface ApiModule {
2
4
  namespace: string;
3
5
  brief: string;
@@ -7,6 +9,39 @@ export interface ApiModule {
7
9
  constants: ApiConstant[];
8
10
  properties: ApiProperty[];
9
11
  typedefs: ApiTypedef[];
12
+ /**
13
+ * Each ref-doc `ENUM`, whose members are also lowered into `constants`. Absent
14
+ * on a hand-built module, which reads the same as an empty list.
15
+ */
16
+ enums?: ApiEnum[];
17
+ /** Each ref-doc `STRUCT`. Absent on a hand-built module, read as an empty list. */
18
+ structs?: ApiStruct[];
19
+ }
20
+
21
+ /** A ref-doc `STRUCT`: a named table shape. */
22
+ export interface ApiStruct {
23
+ name: string;
24
+ brief: string;
25
+ description: string;
26
+ members: ApiStructMember[];
27
+ }
28
+
29
+ /** One `STRUCT` member; upstream marks an optional one with a `name?` suffix. */
30
+ export interface ApiStructMember {
31
+ name: string;
32
+ doc: string;
33
+ /** One LuaLS type expression. */
34
+ type: string;
35
+ isOptional: boolean;
36
+ }
37
+
38
+ /** A ref-doc `ENUM`: a named set of constants, each lowered into `constants`. */
39
+ export interface ApiEnum {
40
+ name: string;
41
+ brief: string;
42
+ description: string;
43
+ /** The member FQNs, in documentation order. */
44
+ members: string[];
10
45
  }
11
46
 
12
47
  export interface ApiProperty {
@@ -24,6 +59,11 @@ export interface ApiTypedef {
24
59
  types?: string[];
25
60
  /** The type text of each parent an interface-backed typedef extends. */
26
61
  extends?: string[];
62
+ /**
63
+ * The type an engine ref-doc `TYPEDEF` aliases (`parameters[0].types`): a
64
+ * handle's `userdata`/`number`, or the arms of a union, literal or record alias.
65
+ */
66
+ aliasOf?: string[];
27
67
  /** See {@link ApiFunction.global}. */
28
68
  global?: true;
29
69
  }
@@ -32,6 +72,16 @@ export interface ApiConstant {
32
72
  name: string;
33
73
  brief: string;
34
74
  description: string;
75
+ /**
76
+ * Present when the constant is a member of an `ENUM` whose value type is
77
+ * `string` (`parameters[0].types`); absence means a number, as every
78
+ * pre-`ENUM` constant is.
79
+ */
80
+ valueType?: "string";
81
+ /** Present when an `ENUM` member is typed `<ENUM>|nil`: some platforms leave it unset. */
82
+ nilable?: true;
83
+ /** The documented constant a back-filled one shares its value, and so its type, with. */
84
+ aliasOf?: string;
35
85
  /** See {@link ApiFunction.global}. */
36
86
  global?: true;
37
87
  }
@@ -122,6 +172,27 @@ function docSourceKey(element: Record<string, unknown>): { docSource?: "upstream
122
172
  return element.docSource === "upstream" ? { docSource: "upstream" } : {};
123
173
  }
124
174
 
175
+ // A function the ref-doc names differently from the name its engine binding
176
+ // registers, so the documented call raises "attempt to call a nil value". Keyed
177
+ // by the ref-doc FQN; `name` is the registered FQN and `evidence` the
178
+ // registration. The parse renames the element, so the declaration, the signature
179
+ // store, the example translations and every audit read the bound name. An entry
180
+ // is deleted once no retained target documents the old name.
181
+ export interface FunctionNameCorrection {
182
+ readonly name: string;
183
+ readonly evidence: string;
184
+ }
185
+
186
+ export const FUNCTION_NAME_CORRECTIONS: ReadonlyMap<string, FunctionNameCorrection> = new Map([
187
+ [
188
+ "sys.set_render_enable",
189
+ {
190
+ name: "sys.set_render_enabled",
191
+ evidence: 'script_engine.cpp registers {"set_render_enabled", EngineSys_SetRenderEnabled}',
192
+ },
193
+ ],
194
+ ]);
195
+
125
196
  export function parseDefoldApiDoc(input: unknown): ApiModule {
126
197
  if (!isRecord(input)) {
127
198
  throw new Error(`parseDefoldApiDoc: expected object, got ${describeKind(input)}`);
@@ -145,24 +216,99 @@ export function parseDefoldApiDoc(input: unknown): ApiModule {
145
216
  const constants: ApiConstant[] = [];
146
217
  const properties: ApiProperty[] = [];
147
218
  const typedefs: ApiTypedef[] = [];
219
+ const enums: ApiEnum[] = [];
220
+ const structs: ApiStruct[] = [];
148
221
 
149
222
  for (const element of elements) {
150
223
  if (!isRecord(element)) continue;
151
224
  const type = element.type;
152
225
  if (type === "FUNCTION") {
153
- functions.push(parseFunction(element));
226
+ const fn = withDocCorrections(parseFunction(element));
227
+ const corrected = FUNCTION_NAME_CORRECTIONS.get(fn.name);
228
+ functions.push(corrected === undefined ? fn : { ...fn, name: corrected.name });
154
229
  } else if (type === "VARIABLE") {
155
230
  variables.push(parseVariable(element));
156
231
  } else if (type === "CONSTANT") {
157
232
  constants.push(parseConstant(element));
158
233
  } else if (type === "PROPERTY") {
159
- properties.push(parseProperty(element));
234
+ const property = parseProperty(element);
235
+ const doc = correctedDoc(
236
+ docCorrectionKey(namespace, "property", property.name),
237
+ property.description,
238
+ );
239
+ properties.push(doc === property.description ? property : { ...property, description: doc });
160
240
  } else if (type === "TYPEDEF") {
161
241
  typedefs.push(parseTypedef(element));
242
+ } else if (type === "ENUM") {
243
+ const members = parseEnumMembers(element);
244
+ constants.push(...members);
245
+ enums.push({
246
+ name: stringOr(element.name, ""),
247
+ brief: stringOr(element.brief, ""),
248
+ description: stringOr(element.description, ""),
249
+ members: members.map((m) => m.name),
250
+ });
251
+ } else if (type === "STRUCT") {
252
+ structs.push(parseStruct(element));
253
+ }
254
+ }
255
+
256
+ return {
257
+ namespace,
258
+ brief,
259
+ description,
260
+ functions,
261
+ variables,
262
+ constants,
263
+ properties,
264
+ typedefs,
265
+ enums,
266
+ structs,
267
+ };
268
+ }
269
+
270
+ // Withholds one overload of a documented function — the one whose `param` has
271
+ // exactly the upstream type `type` — while its same-named siblings still emit.
272
+ // `name` is the local name, like a `skipFunctions` rule.
273
+ export interface SkipOverloadRule {
274
+ readonly name: string;
275
+ readonly param: string;
276
+ readonly type: string;
277
+ }
278
+
279
+ export function withholdOverloads(
280
+ module: ApiModule,
281
+ rules: readonly SkipOverloadRule[],
282
+ ): ApiModule {
283
+ let functions = module.functions;
284
+ for (const rule of rules) {
285
+ const fqn = `${module.namespace}.${rule.name}`;
286
+ const kept = functions.filter(
287
+ (fn) =>
288
+ fn.name !== fqn ||
289
+ !fn.parameters.some(
290
+ (p) => p.name === rule.param && p.types.length === 1 && p.types[0] === rule.type,
291
+ ),
292
+ );
293
+ if (kept.length === functions.length) {
294
+ throw new Error(`skipOverloads: ${fqn} has no overload whose ${rule.param} is ${rule.type}`);
162
295
  }
296
+ functions = kept;
163
297
  }
298
+ return functions === module.functions ? module : { ...module, functions };
299
+ }
164
300
 
165
- return { namespace, brief, description, functions, variables, constants, properties, typedefs };
301
+ // Keyed by the ref-doc FQN, before any `FUNCTION_NAME_CORRECTIONS` rename.
302
+ function withDocCorrections(fn: ApiFunction): ApiFunction {
303
+ const correct = (slot: "param" | "return") => (p: ApiParameter) => {
304
+ const doc = correctedDoc(docCorrectionKey(fn.name, slot, p.name), p.doc);
305
+ return doc === p.doc ? p : { ...p, doc };
306
+ };
307
+ return {
308
+ ...fn,
309
+ parameters: fn.parameters.map(correct("param")),
310
+ returnValues: fn.returnValues.map(correct("return")),
311
+ };
166
312
  }
167
313
 
168
314
  function parseTypedef(element: Record<string, unknown>): ApiTypedef {
@@ -170,16 +316,41 @@ function parseTypedef(element: Record<string, unknown>): ApiTypedef {
170
316
  const properties = parseVariableList(element.properties);
171
317
  const types = parseStringArray(element.types);
172
318
  const parents = parseStringArray(element.extends);
319
+ const [aliased] = parseParameterList(element.parameters);
320
+ const aliasOf = aliased?.types ?? [];
173
321
  return {
174
322
  name: stringOr(element.name, ""),
175
323
  ...(functions.length > 0 ? { functions } : {}),
176
324
  ...(properties.length > 0 ? { properties } : {}),
177
325
  ...(types.length > 0 ? { types } : {}),
178
326
  ...(parents.length > 0 ? { extends: parents } : {}),
327
+ ...(aliasOf.length > 0 ? { aliasOf } : {}),
179
328
  ...globalKey(element),
180
329
  };
181
330
  }
182
331
 
332
+ function parseStruct(element: Record<string, unknown>): ApiStruct {
333
+ const raw = Array.isArray(element.members) ? element.members : [];
334
+ const members: ApiStructMember[] = [];
335
+ for (const member of raw) {
336
+ if (!isRecord(member)) continue;
337
+ const name = stringOr(member.name, "");
338
+ const isOptional = name.endsWith("?");
339
+ members.push({
340
+ name: isOptional ? name.slice(0, -1) : name,
341
+ doc: stringOr(member.doc, ""),
342
+ type: stringOr(member.type, ""),
343
+ isOptional,
344
+ });
345
+ }
346
+ return {
347
+ name: stringOr(element.name, ""),
348
+ brief: stringOr(element.brief, ""),
349
+ description: stringOr(element.description, ""),
350
+ members,
351
+ };
352
+ }
353
+
183
354
  function parseProperty(element: Record<string, unknown>): ApiProperty {
184
355
  const brief = stringOr(element.brief, "");
185
356
  const span = /<span class="type">([^<]+)<\/span>/.exec(brief);
@@ -207,6 +378,33 @@ function parseConstant(element: Record<string, unknown>): ApiConstant {
207
378
  };
208
379
  }
209
380
 
381
+ // A member carries one `doc` string where a constant carried `brief` and
382
+ // `description`; both take it.
383
+ function parseEnumMembers(element: Record<string, unknown>): ApiConstant[] {
384
+ // A member named bare (1.13.2's bullet3d enums) is registered on the enum's
385
+ // own namespace, so it takes that prefix.
386
+ const enumName = stringOr(element.name, "");
387
+ const owner = enumName.includes(".") ? enumName.slice(0, enumName.lastIndexOf(".")) : "";
388
+ const qualify = (name: string): string =>
389
+ name.includes(".") || owner === "" ? name : `${owner}.${name}`;
390
+ const [value] = parseParameterList(element.parameters);
391
+ const valueType = value?.types.length === 1 && value.types[0] === "string" ? "string" : null;
392
+ const raw = Array.isArray(element.members) ? element.members : [];
393
+ const out: ApiConstant[] = [];
394
+ for (const member of raw) {
395
+ if (!isRecord(member)) continue;
396
+ const doc = stringOr(member.doc, "");
397
+ out.push({
398
+ name: qualify(stringOr(member.name, "")),
399
+ brief: doc,
400
+ description: doc,
401
+ ...(valueType === null ? {} : { valueType }),
402
+ ...(stringOr(member.type, "").endsWith("|nil") ? { nilable: true } : {}),
403
+ });
404
+ }
405
+ return out;
406
+ }
407
+
210
408
  function parseFunction(element: Record<string, unknown>): ApiFunction {
211
409
  return {
212
410
  name: stringOr(element.name, ""),