@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
package/scripts/regen.ts CHANGED
@@ -1,20 +1,34 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { dirname, resolve } from "node:path";
3
3
  import messagesDoc from "../fixtures/messages_doc.json" with { type: "json" };
4
- import { type ApiModule, parseDefoldApiDoc } from "../src/api-doc";
5
4
  import {
6
- defaultMapType,
5
+ type ApiModule,
6
+ parseDefoldApiDoc,
7
+ type SkipOverloadRule,
8
+ withholdOverloads,
9
+ } from "../src/api-doc";
10
+ import {
11
+ declaredTypePaths,
7
12
  emitDeclarations,
8
13
  emitSymbolSignatures,
14
+ routeTypeDeclarations,
9
15
  type SymbolSignature,
10
16
  } from "../src/emit-dts";
11
17
  import {
12
18
  applyMessageDeprecations,
19
+ applyMessageFieldCorrections,
13
20
  type EmitBuiltinMessagesOptions,
14
21
  emitBuiltinMessages,
15
22
  parseMessagesDoc,
16
23
  } from "../src/emit-messages";
17
24
  import type { TranslationStore } from "../src/example-store";
25
+ import {
26
+ type FieldCorrectionGap,
27
+ type FieldCorrectionTables,
28
+ fieldCorrectionGaps,
29
+ formatFieldCorrectionGaps,
30
+ } from "../src/field-correction-coverage";
31
+ import type { IndexBaseSource } from "../src/index-slot-classifications";
18
32
  import { wrapAsAmbientGlobal, wrapAsModule } from "../src/publish-dts";
19
33
  import type { UrlParameterTable } from "../src/url-parameters";
20
34
  import {
@@ -27,6 +41,7 @@ import {
27
41
  } from "./doc-source";
28
42
  import { loadTranslations } from "./example-store-io";
29
43
  import { synthesizeProseConstants } from "./prose-constants";
44
+ import { restoreSharedHandleMethods } from "./shared-handle-methods";
30
45
  import { type readZip, SYNC_MANIFEST, type SyncManifestEntry } from "./sync-api-docs";
31
46
 
32
47
  export interface ApiTargetModule {
@@ -34,6 +49,7 @@ export interface ApiTargetModule {
34
49
  readonly fixture: string;
35
50
  readonly outFile: string;
36
51
  readonly skipFunctions?: readonly string[];
52
+ readonly skipOverloads?: readonly SkipOverloadRule[];
37
53
  }
38
54
 
39
55
  // An editor-VM document declared by a target. It carries two things a runtime
@@ -96,6 +112,14 @@ export function loadApiTargets(
96
112
  return targets;
97
113
  }
98
114
 
115
+ function withSkipRules(entry: ModuleManifestEntry, module: ApiTargetModule): ModuleManifestEntry {
116
+ return {
117
+ ...entry,
118
+ ...(module.skipFunctions ? { skipFunctions: module.skipFunctions } : {}),
119
+ ...(module.skipOverloads ? { skipOverloads: module.skipOverloads } : {}),
120
+ };
121
+ }
122
+
99
123
  export function loadTargetModules(
100
124
  target: ApiTarget,
101
125
  packageRoot: string = PACKAGE_ROOT,
@@ -116,27 +140,34 @@ export function loadTargetModules(
116
140
  outFile: module.outFile,
117
141
  importsFrom: target.coreTypesImport,
118
142
  };
119
- return module.skipFunctions ? { ...entry, skipFunctions: module.skipFunctions } : entry;
143
+ return withSkipRules(entry, module);
120
144
  });
121
- return synthesizeProseConstants(modules);
145
+ return restoreSharedHandleMethods(synthesizeProseConstants(modules));
122
146
  }
123
147
 
124
148
  export interface ModuleManifestEntry {
125
149
  readonly namespace: string;
126
150
  readonly doc: unknown;
127
151
  readonly outFile: string;
128
- // Each item drops one member of any element kind — a FUNCTION or a VARIABLE —
129
- // by an exact stripped local (`get`), or — when it ends in `.` — a segment
130
- // prefix dropping everything beneath it (`ui.`). The field keeps its historic
131
- // name; its reach is not limited to functions.
152
+ // Each item drops one member of any element kind — a FUNCTION, a VARIABLE, a
153
+ // CONSTANT, an ENUM member, a STRUCT or an aliasing TYPEDEF — by an exact
154
+ // stripped local (`get`), or — when it ends in `.` — a segment prefix dropping
155
+ // everything beneath it (`ui.`). An ENUM whose every member is dropped emits no
156
+ // alias either. The field keeps its historic name; its reach is not limited to
157
+ // functions.
132
158
  readonly skipFunctions?: readonly string[];
159
+ readonly skipOverloads?: readonly SkipOverloadRule[];
133
160
  readonly importsFrom?: string;
134
161
  readonly moduleId?: string;
135
162
  readonly sourceProvenance?: DocSourceProvenance;
136
- // Overrides the shared token -> TS type mapping for this entry alone. Reserved
137
- // for tokens no runtime namespace uses, so `DEFOLD_TYPE_MAP` keeps describing
138
- // only the runtime surface.
139
- readonly mapType?: (token: string) => string;
163
+ // Extra token -> TS type leaves for this entry alone, resolved ahead of the
164
+ // shared mapping and beside the module's declared types. Reserved for tokens no
165
+ // runtime namespace uses, so `DEFOLD_TYPE_MAP` keeps describing only the
166
+ // runtime surface.
167
+ readonly typeLeaves?: Readonly<Record<string, string>>;
168
+ // The classification map this entry's index notes read; absent means the
169
+ // engine map. A library or extension declaration names its page keys.
170
+ readonly indexBaseSource?: IndexBaseSource;
140
171
  }
141
172
 
142
173
  export interface ResolveTargetOptions {
@@ -184,7 +215,7 @@ export async function resolveTargetModules(
184
215
  importsFrom: target.coreTypesImport,
185
216
  sourceProvenance: provenance,
186
217
  };
187
- return module.skipFunctions ? { ...entry, skipFunctions: module.skipFunctions } : entry;
218
+ return withSkipRules(entry, module);
188
219
  });
189
220
  return synthesizeProseConstants(modules);
190
221
  }
@@ -221,17 +252,18 @@ const EDITOR_TYPE_MAP: Readonly<Record<string, string>> = {
221
252
  // `string[`, this token means one thing everywhere it appears — a list of
222
253
  // values to render — so `unknown[]` is sound at all three of its slots.
223
254
  "any[": "unknown[]",
255
+ // 1.13.2 names the same handles with their namespace prefix, slot for slot.
256
+ "editor.command": 'Opaque<"command">',
257
+ "editor.component": 'Opaque<"component">',
258
+ "editor.transaction_step": 'Opaque<"transaction_step">',
259
+ "editor.message": 'Opaque<"message">',
224
260
  };
225
261
 
226
- function mapEditorType(token: string): string {
227
- return EDITOR_TYPE_MAP[token] ?? defaultMapType(token);
228
- }
229
-
230
262
  // The named type maps an `editorModules` entry may select. A closed set, so an
231
263
  // unknown selector fails loudly instead of silently falling back to the runtime
232
264
  // token mapping and emitting `unknown` for every editor handle.
233
- const NAMED_TYPE_MAPS: Readonly<Record<string, (token: string) => string>> = {
234
- editor: mapEditorType,
265
+ const NAMED_TYPE_MAPS: Readonly<Record<string, Readonly<Record<string, string>>>> = {
266
+ editor: EDITOR_TYPE_MAP,
235
267
  };
236
268
 
237
269
  // The subdirectory the namespace-shaped libraries the editor VM exposes
@@ -262,7 +294,20 @@ function oneLevelDeeper(importPath: string): string {
262
294
  // The `skipFunctions` rules a target declares in `api-targets.json` withhold
263
295
  // members for reasons the registry data alone cannot state. Rules are local
264
296
  // names — the `<namespace>.` prefix is stripped before matching — and they
265
- // withhold VARIABLEs as well as FUNCTIONs.
297
+ // withhold any member: FUNCTIONs, VARIABLEs, CONSTANTs, ENUM members, STRUCTs
298
+ // and aliasing TYPEDEFs alike. A TYPEDEF that names no aliased type keeps its
299
+ // flat handle path and is never withheld.
300
+ // An ENUM whose every member is withheld emits no alias.
301
+ //
302
+ // On a `b2d.body` entry they withhold what that release documents but neither
303
+ // Box2D binding registers, so the call would raise: `get_user_data`,
304
+ // `set_user_data` and `get_contact_list` from 1.13, `reset_mass_data` from
305
+ // 1.12.4. The engine-binding diff reports a missing binding the moment one is
306
+ // declared again.
307
+ //
308
+ // On the 1.13.2 `http` entry, `response` withholds the runtime response table:
309
+ // the editor VM's `http.response` handle takes that name in the same global
310
+ // namespace, and the `http.request` callback already types the table inline.
266
311
  //
267
312
  // On the `editor` entry, the editor VM's own `http`/`json`/`zip`/`zlib`/
268
313
  // `pprint`/`localization`/`tilemap.tiles` sit in that same upstream document
@@ -288,7 +333,9 @@ function oneLevelDeeper(importPath: string): string {
288
333
  // and `ZipPackOptions.method?: string` rejects that. Their brief is the literal
289
334
  // value, which looks like a string-literal type until you notice upstream's own
290
335
  // `zip.ON_CONFLICT.OVERWRITE` reads `"skip"`, so no type is derived from it.
291
- // The hand-authored declarations stay authoritative and these stay withheld.
336
+ // Where upstream ships them as ENUM members (1.13.2) they carry a string type,
337
+ // and the same rules still withhold them: the hand-authored declarations stay
338
+ // authoritative and these stay withheld.
292
339
  export function loadTargetEditorModules(
293
340
  target: ApiTarget,
294
341
  packageRoot: string = PACKAGE_ROOT,
@@ -322,7 +369,7 @@ export function loadTargetEditorModules(
322
369
  ? oneLevelDeeper(target.coreTypesImport)
323
370
  : target.coreTypesImport),
324
371
  ...(module.skipFunctions ? { skipFunctions: module.skipFunctions } : {}),
325
- ...(module.mapType ? { mapType: NAMED_TYPE_MAPS[module.mapType] } : {}),
372
+ ...(module.mapType ? { typeLeaves: NAMED_TYPE_MAPS[module.mapType] } : {}),
326
373
  };
327
374
  return entry;
328
375
  });
@@ -358,7 +405,10 @@ export function generateBuiltinMessagesDeclaration(
358
405
  entry: MessagesManifestEntry,
359
406
  opts: EmitBuiltinMessagesOptions = {},
360
407
  ): string {
361
- return emitBuiltinMessages(applyMessageDeprecations(parseMessagesDoc(entry.doc)), opts);
408
+ return emitBuiltinMessages(
409
+ applyMessageFieldCorrections(applyMessageDeprecations(parseMessagesDoc(entry.doc))),
410
+ opts,
411
+ );
362
412
  }
363
413
 
364
414
  export interface GenerateResult {
@@ -400,6 +450,7 @@ export interface GenerateOptions {
400
450
  knownConstantFqns?: ReadonlySet<string>;
401
451
  translations?: TranslationStore;
402
452
  urlParameters?: UrlParameterTable;
453
+ registeredConstants?: ReadonlySet<string>;
403
454
  }
404
455
 
405
456
  interface PreparedGeneratedModule {
@@ -407,11 +458,13 @@ interface PreparedGeneratedModule {
407
458
  knownConstantFqns: ReadonlySet<string>;
408
459
  translations: TranslationStore;
409
460
  urlParameters: UrlParameterTable;
410
- mapType: ((token: string) => string) | undefined;
461
+ registeredConstants: ReadonlySet<string> | undefined;
462
+ typeLeaves: Readonly<Record<string, string>> | undefined;
463
+ declaredTypes: ReadonlyMap<string, string> | undefined;
411
464
  dropped: string[];
412
465
  }
413
466
 
414
- // Parse a manifest entry, apply its `skipFunctions` filter, and resolve the
467
+ // Parse a manifest entry, apply its `skipFunctions` and `skipOverloads` filters, and resolve the
415
468
  // shared constant-brand universe and translations. Both the `.d.ts` emit and
416
469
  // the authoritative-signature emit run off this identical prepared module, so a
417
470
  // dropped member never appears in either surface.
@@ -419,44 +472,251 @@ function prepareGeneratedModule(
419
472
  entry: ModuleManifestEntry,
420
473
  options?: GenerateOptions,
421
474
  ): PreparedGeneratedModule {
422
- const module = parseDefoldApiDoc(entry.doc);
475
+ const routed = routedModuleOf(entry);
476
+ const { module, dropped } = routed?.prepared ?? withheldApiModule(entry);
477
+ const knownConstantFqns = options?.knownConstantFqns ?? collectConstantFqns();
478
+ const translations = options?.translations ?? loadTranslations();
479
+ const urlParameters = options?.urlParameters ?? committedUrlParameters();
480
+ return {
481
+ module,
482
+ knownConstantFqns,
483
+ translations,
484
+ urlParameters,
485
+ registeredConstants: options?.registeredConstants,
486
+ typeLeaves: entry.typeLeaves,
487
+ declaredTypes: routed?.declaredTypes,
488
+ dropped,
489
+ };
490
+ }
491
+
492
+ interface RoutedSurface {
493
+ readonly modules: ReadonlyMap<ModuleManifestEntry, { module: ApiModule; dropped: string[] }>;
494
+ readonly declaredTypes: ReadonlyMap<string, string>;
495
+ }
496
+
497
+ const routedSurfaces = new Map<string, RoutedSurface>();
498
+
499
+ // A doc may declare a type another module owns (`b2d.joint.revolute_definition`
500
+ // in the `b2d` doc) or name one another doc declares (`material.constant_info`
501
+ // in `compute`), so each committed surface is routed as a whole: the runtime
502
+ // modules and the editor modules of one target, never across targets. An entry
503
+ // outside every committed manifest routes alone, as a single-module surface.
504
+ function routedModuleOf(entry: ModuleManifestEntry):
505
+ | {
506
+ prepared: { module: ApiModule; dropped: string[] };
507
+ declaredTypes: ReadonlyMap<string, string>;
508
+ }
509
+ | undefined {
510
+ const located = committedSurfaceOf(entry);
511
+ if (located === undefined) return undefined;
512
+ let surface = routedSurfaces.get(located.key);
513
+ if (surface === undefined) {
514
+ const withheld = located.entries.map(withheldApiModule);
515
+ const routed = routeTypeDeclarations(withheld.map(({ module }) => module));
516
+ surface = {
517
+ modules: new Map(
518
+ located.entries.map((member, index) => [
519
+ member,
520
+ {
521
+ module: routed[index] as ApiModule,
522
+ dropped: (withheld[index] as { dropped: string[] }).dropped,
523
+ },
524
+ ]),
525
+ ),
526
+ declaredTypes: declaredTypePaths(routed),
527
+ };
528
+ routedSurfaces.set(located.key, surface);
529
+ }
530
+ const prepared = surface.modules.get(located.member);
531
+ return prepared === undefined ? undefined : { prepared, declaredTypes: surface.declaredTypes };
532
+ }
533
+
534
+ const committedDocText = new WeakMap<ModuleManifestEntry, string>();
535
+
536
+ // The committed entry `entry` stands for: itself, or — for an entry a caller
537
+ // re-loaded from the registry — the committed one with the same module, output,
538
+ // import root, skip rules and document.
539
+ function committedMemberOf(
540
+ entry: ModuleManifestEntry,
541
+ candidates: readonly ModuleManifestEntry[],
542
+ ): ModuleManifestEntry | undefined {
543
+ if (candidates.includes(entry)) return entry;
544
+ const shape = (member: ModuleManifestEntry) =>
545
+ JSON.stringify([
546
+ member.namespace,
547
+ member.outFile,
548
+ member.importsFrom,
549
+ member.moduleId,
550
+ member.skipFunctions,
551
+ member.skipOverloads,
552
+ ]);
553
+ const same = candidates.filter((candidate) => shape(candidate) === shape(entry));
554
+ if (same.length === 0) return undefined;
555
+ const text = JSON.stringify(entry.doc);
556
+ return same.find((candidate) => {
557
+ let committed = committedDocText.get(candidate);
558
+ if (committed === undefined) {
559
+ committed = JSON.stringify(candidate.doc);
560
+ committedDocText.set(candidate, committed);
561
+ }
562
+ return committed === text;
563
+ });
564
+ }
565
+
566
+ function committedSurfaceOf(
567
+ entry: ModuleManifestEntry,
568
+ ):
569
+ | { key: string; member: ModuleManifestEntry; entries: readonly ModuleManifestEntry[] }
570
+ | undefined {
571
+ const runtime = committedMemberOf(entry, MODULE_MANIFEST);
572
+ if (runtime !== undefined) return { key: "default", member: runtime, entries: MODULE_MANIFEST };
573
+ const editor = committedMemberOf(entry, DEFAULT_EDITOR_MODULES);
574
+ if (editor !== undefined) {
575
+ return { key: "default/editor", member: editor, entries: DEFAULT_EDITOR_MODULES };
576
+ }
577
+ const versioned = committedMemberOf(entry, VERSIONED_MODULE_MANIFEST) as
578
+ | VersionedModuleManifestEntry
579
+ | undefined;
580
+ if (versioned === undefined) return undefined;
581
+ const isEditor = versioned.editor === true;
582
+ return {
583
+ key: `${versioned.versionId}${isEditor ? "/editor" : ""}`,
584
+ member: versioned,
585
+ entries: VERSIONED_MODULE_MANIFEST.filter(
586
+ (member) => member.versionId === versioned.versionId && (member.editor === true) === isEditor,
587
+ ),
588
+ };
589
+ }
590
+
591
+ // The parsed module with the entry's `skipFunctions` and `skipOverloads` applied.
592
+ function withheldApiModule(entry: ModuleManifestEntry): { module: ApiModule; dropped: string[] } {
593
+ let module = parseDefoldApiDoc(entry.doc);
423
594
  const prefix = `${module.namespace}.`;
424
595
  const dropped: string[] = [];
425
596
  const rules = entry.skipFunctions ?? [];
426
597
  const exact = new Set(rules.filter((rule) => !rule.endsWith(".")));
427
598
  const segments = rules.filter((rule) => rule.endsWith("."));
599
+ const localOf = (name: string): string =>
600
+ name.startsWith(prefix) ? name.slice(prefix.length) : name;
428
601
  const withheld = (name: string): boolean => {
429
- const local = name.startsWith(prefix) ? name.slice(prefix.length) : name;
602
+ const local = localOf(name);
430
603
  if (!exact.has(local) && !segments.some((segment) => local.startsWith(segment))) return false;
431
604
  dropped.push(name);
432
605
  return true;
433
606
  };
607
+ // An exact rule a value and a type both answer to (`render_target`) names the
608
+ // value, the member every such rule was written to withhold; a segment rule
609
+ // still takes the whole subtree, types included.
610
+ const valueLocals = new Set(
611
+ [...module.functions, ...module.variables, ...module.constants].map((m) => localOf(m.name)),
612
+ );
613
+ const withheldType = (name: string): boolean => {
614
+ const local = localOf(name);
615
+ if (valueLocals.has(local) && !segments.some((segment) => local.startsWith(segment))) {
616
+ return false;
617
+ }
618
+ return withheld(name);
619
+ };
434
620
  module.functions = module.functions.filter((fn) => !withheld(fn.name));
435
621
  module.variables = module.variables.filter((v) => !withheld(v.name));
436
- const knownConstantFqns = options?.knownConstantFqns ?? collectConstantFqns();
437
- const translations = options?.translations ?? loadTranslations();
438
- const urlParameters = options?.urlParameters ?? committedUrlParameters();
439
- return {
440
- module,
441
- knownConstantFqns,
442
- translations,
443
- urlParameters,
444
- mapType: entry.mapType,
445
- dropped,
446
- };
622
+ const withheldConstants = new Set<string>();
623
+ module.constants = module.constants.filter((c) => {
624
+ if (!withheld(c.name)) return true;
625
+ withheldConstants.add(c.name);
626
+ return false;
627
+ });
628
+ if (module.enums) {
629
+ module.enums = module.enums.filter(
630
+ (e) => e.members.length === 0 || !e.members.every((member) => withheldConstants.has(member)),
631
+ );
632
+ }
633
+ if (module.structs) module.structs = module.structs.filter((s) => !withheldType(s.name));
634
+ module.typedefs = module.typedefs.filter((t) => t.aliasOf === undefined || !withheldType(t.name));
635
+ module = withholdOverloads(module, entry.skipOverloads ?? []);
636
+ return { module, dropped };
637
+ }
638
+
639
+ // The field corrections one target's runtime entries leave inert: every entry is
640
+ // parsed with its skip rules first, so a withheld overload's slot is not judged.
641
+ export function targetFieldCorrectionGaps(
642
+ entries: readonly ModuleManifestEntry[],
643
+ tables?: FieldCorrectionTables,
644
+ ): FieldCorrectionGap[] {
645
+ return fieldCorrectionGaps(
646
+ entries.map((entry) => withheldApiModule(entry).module),
647
+ tables,
648
+ );
649
+ }
650
+
651
+ export interface FieldCorrectionTarget {
652
+ readonly id: string;
653
+ readonly entries: readonly ModuleManifestEntry[];
654
+ }
655
+
656
+ // The runtime surfaces committed generation writes: the default target's, then
657
+ // each fixture-backed version's. ref-doc targets are never pre-baked, and an
658
+ // editor document carries no field correction.
659
+ export function committedFieldCorrectionTargets(
660
+ targets: readonly ApiTarget[] = API_TARGETS,
661
+ runtime: readonly ModuleManifestEntry[] = MODULE_MANIFEST,
662
+ versioned: readonly VersionedModuleManifestEntry[] = VERSIONED_MODULE_MANIFEST,
663
+ ): FieldCorrectionTarget[] {
664
+ const defaultTarget = targets.find((target) => target.default === true);
665
+ return [
666
+ ...(defaultTarget ? [{ id: defaultTarget.id, entries: runtime }] : []),
667
+ ...targets
668
+ .filter((target) => target.default !== true && (target.source ?? null) == null)
669
+ .map((target) => ({
670
+ id: target.id,
671
+ entries: versioned.filter(
672
+ (entry) => entry.versionId === target.id && entry.editor !== true,
673
+ ),
674
+ })),
675
+ ];
676
+ }
677
+
678
+ // Every committed target is judged before any rejection, so one failure names
679
+ // all the stranded corrections at once. Returns how many targets it judged.
680
+ export function assertCommittedFieldCorrectionCoverage(
681
+ targets: readonly FieldCorrectionTarget[] = committedFieldCorrectionTargets(),
682
+ tables?: FieldCorrectionTables,
683
+ ): number {
684
+ const failures = targets.flatMap(({ id, entries }) => {
685
+ const gaps = targetFieldCorrectionGaps(entries, tables);
686
+ return gaps.length === 0
687
+ ? []
688
+ : [
689
+ `target "${id}": field corrections no slot or member carries:\n${formatFieldCorrectionGaps(gaps)}`,
690
+ ];
691
+ });
692
+ if (failures.length > 0) {
693
+ throw new Error(failures.join("\n"));
694
+ }
695
+ return targets.length;
447
696
  }
448
697
 
449
698
  export function generateModuleDeclaration(
450
699
  entry: ModuleManifestEntry,
451
700
  options?: GenerateOptions,
452
701
  ): GenerateResult {
453
- const { module, knownConstantFqns, translations, urlParameters, mapType, dropped } =
454
- prepareGeneratedModule(entry, options);
702
+ const {
703
+ module,
704
+ knownConstantFqns,
705
+ translations,
706
+ urlParameters,
707
+ registeredConstants,
708
+ typeLeaves,
709
+ declaredTypes,
710
+ dropped,
711
+ } = prepareGeneratedModule(entry, options);
455
712
  const emitted = emitDeclarations(module, {
456
713
  knownConstantFqns,
457
714
  translations,
458
715
  urlParameters,
459
- ...(mapType ? { mapType } : {}),
716
+ ...(registeredConstants ? { registeredConstants } : {}),
717
+ ...(typeLeaves ? { typeLeaves } : {}),
718
+ ...(declaredTypes ? { declaredTypes } : {}),
719
+ ...(entry.indexBaseSource ? { indexBaseSource: entry.indexBaseSource } : {}),
460
720
  });
461
721
  const importsFrom = entry.importsFrom ?? "../src/core-types";
462
722
  const contents = entry.moduleId
@@ -473,14 +733,20 @@ export function generateModuleSignatures(
473
733
  entry: ModuleManifestEntry,
474
734
  options?: GenerateOptions,
475
735
  ): SymbolSignature[] {
476
- const { module, knownConstantFqns, urlParameters, mapType } = prepareGeneratedModule(
477
- entry,
478
- options,
479
- );
736
+ const {
737
+ module,
738
+ knownConstantFqns,
739
+ urlParameters,
740
+ registeredConstants,
741
+ typeLeaves,
742
+ declaredTypes,
743
+ } = prepareGeneratedModule(entry, options);
480
744
  return emitSymbolSignatures(module, {
481
745
  knownConstantFqns,
482
746
  urlParameters,
483
- ...(mapType ? { mapType } : {}),
747
+ ...(registeredConstants ? { registeredConstants } : {}),
748
+ ...(typeLeaves ? { typeLeaves } : {}),
749
+ ...(declaredTypes ? { declaredTypes } : {}),
484
750
  });
485
751
  }
486
752
 
@@ -562,6 +828,7 @@ const UNIVERSAL_EXTRA_IMPORTS: readonly UniversalExtraImport[] = [
562
828
  { specifier: "../../src/component-properties" },
563
829
  { specifier: "../../src/render-overloads", restrictedTo: "render" },
564
830
  { specifier: "../../src/vmath-overloads" },
831
+ { specifier: "../../src/sys-overloads" },
565
832
  ];
566
833
 
567
834
  const SRC_IMPORT_PREFIX = "../../src/";
@@ -788,47 +1055,85 @@ export async function assertSrcAugmentationScoping(
788
1055
  return files.length;
789
1056
  }
790
1057
 
791
- if (import.meta.main) {
1058
+ export interface RegenIo {
1059
+ mkdir(path: string): void;
1060
+ write(path: string, contents: string): void;
1061
+ log(line: string): void;
1062
+ }
1063
+
1064
+ export const nodeRegenIo: RegenIo = {
1065
+ mkdir: (path) => mkdirSync(path, { recursive: true }),
1066
+ write: (path, contents) => writeFileSync(path, contents),
1067
+ log: (line) => console.log(line),
1068
+ };
1069
+
1070
+ export async function regenerate(
1071
+ options: { io?: RegenIo; fieldCorrectionTables?: FieldCorrectionTables } = {},
1072
+ ): Promise<void> {
1073
+ const io = options.io ?? nodeRegenIo;
792
1074
  // Ordering contract: `regen-entrypoint.test.ts` reads this line's prefix to
793
1075
  // prove the guard runs before the first write. The count comes from the guard's
794
1076
  // own return value so the marker cannot be printed without a completed guard
795
1077
  // run — do not simplify it back to `SRC_AUGMENTATION_MODULES.length`, which
796
1078
  // would let the guard be deleted or reordered with the line still intact.
797
1079
  const checked = await assertSrcAugmentationScoping();
798
- console.log(`src augmentation scoping checked: ${checked} file(s)`);
1080
+ io.log(`src augmentation scoping checked: ${checked} file(s)`);
1081
+ // Ordering contract: `regen-entrypoint.test.ts` reads this line's prefix to
1082
+ // prove the coverage gate runs before the first write. Print the count the gate
1083
+ // returns — never `committedFieldCorrectionTargets().length` or any other count
1084
+ // not taken from the gate, which would keep the line alive with the gate gone.
1085
+ // The `regenerate` rejection test injects stranded tables and asserts that no
1086
+ // directory or file is written, so the gate must receive `fieldCorrectionTables`
1087
+ // and throw before the first `io.mkdir`.
1088
+ const targets = assertCommittedFieldCorrectionCoverage(
1089
+ committedFieldCorrectionTargets(),
1090
+ options.fieldCorrectionTables,
1091
+ );
1092
+ io.log(`field correction coverage checked: ${targets} target(s)`);
799
1093
 
1094
+ // Imported here rather than at module scope: the vendored engine bindings are
1095
+ // not published, and `resolve` loads this module from an installed package.
1096
+ const { registeredConstantFqns } = await import("./engine-binding-extract");
800
1097
  const generated = resolve(import.meta.dir, "..", "generated");
801
- mkdirSync(resolve(generated, "editor-vm"), { recursive: true });
802
- for (const entry of [
803
- ...MODULE_MANIFEST,
804
- ...EDITOR_MODULE_MANIFEST,
805
- ...EDITOR_VM_MODULE_MANIFEST,
806
- ]) {
1098
+ io.mkdir(resolve(generated, "editor-vm"));
1099
+ const defaultRegistered = registeredConstantFqns(DEFAULT_TARGET);
1100
+ for (const entry of MODULE_MANIFEST) {
1101
+ const { contents, dropped } = generateModuleDeclaration(entry, {
1102
+ ...(defaultRegistered ? { registeredConstants: defaultRegistered } : {}),
1103
+ });
1104
+ if (dropped.length > 0) {
1105
+ io.log(`note: dropped skipped member(s) from ${entry.namespace}: ${dropped.join(", ")}`);
1106
+ }
1107
+ const out = resolve(generated, entry.outFile);
1108
+ io.write(out, contents);
1109
+ io.log(`wrote ${out}`);
1110
+ }
1111
+ for (const entry of [...EDITOR_MODULE_MANIFEST, ...EDITOR_VM_MODULE_MANIFEST]) {
807
1112
  const { contents, dropped } = generateModuleDeclaration(entry);
808
1113
  if (dropped.length > 0) {
809
- console.log(`note: dropped skipped member(s) from ${entry.namespace}: ${dropped.join(", ")}`);
1114
+ io.log(`note: dropped skipped member(s) from ${entry.namespace}: ${dropped.join(", ")}`);
810
1115
  }
811
1116
  const out = resolve(generated, entry.outFile);
812
- writeFileSync(out, contents);
813
- console.log(`wrote ${out}`);
1117
+ io.write(out, contents);
1118
+ io.log(`wrote ${out}`);
814
1119
  }
815
1120
  const messagesOut = resolve(generated, MESSAGES_MANIFEST.outFile);
816
- writeFileSync(messagesOut, generateBuiltinMessagesDeclaration(MESSAGES_MANIFEST));
817
- console.log(`wrote ${messagesOut}`);
1121
+ io.write(messagesOut, generateBuiltinMessagesDeclaration(MESSAGES_MANIFEST));
1122
+ io.log(`wrote ${messagesOut}`);
818
1123
 
819
1124
  // Imported here rather than at module scope: its fixtures are not published,
820
1125
  // and `resolve` loads this module from an installed package.
821
1126
  const { EXTENSION_GOLDENS_DIR, EXTENSION_GOLDEN_MANIFEST } = await import("./extension-goldens");
822
1127
  const goldens = resolve(PACKAGE_ROOT, EXTENSION_GOLDENS_DIR);
823
- mkdirSync(goldens, { recursive: true });
1128
+ io.mkdir(goldens);
824
1129
  for (const entry of EXTENSION_GOLDEN_MANIFEST) {
825
1130
  const { contents, dropped } = generateModuleDeclaration(entry);
826
1131
  if (dropped.length > 0) {
827
- console.log(`note: dropped skipped member(s) from ${entry.namespace}: ${dropped.join(", ")}`);
1132
+ io.log(`note: dropped skipped member(s) from ${entry.namespace}: ${dropped.join(", ")}`);
828
1133
  }
829
1134
  const out = resolve(goldens, entry.outFile);
830
- writeFileSync(out, contents);
831
- console.log(`wrote ${out}`);
1135
+ io.write(out, contents);
1136
+ io.log(`wrote ${out}`);
832
1137
  }
833
1138
 
834
1139
  // The target's own `generatedDir` is where a version lands, so a declaring
@@ -843,21 +1148,26 @@ if (import.meta.main) {
843
1148
  return resolve(PACKAGE_ROOT, target.generatedDir);
844
1149
  };
845
1150
  for (const entry of VERSIONED_MODULE_MANIFEST) {
846
- const { contents, dropped } = generateModuleDeclaration(entry);
1151
+ const target = versionedTargets.find((t) => t.id === entry.versionId);
1152
+ const registeredConstants = target ? registeredConstantFqns(target) : undefined;
1153
+ const { contents, dropped } = generateModuleDeclaration(
1154
+ entry,
1155
+ registeredConstants ? { registeredConstants } : undefined,
1156
+ );
847
1157
  if (dropped.length > 0) {
848
- console.log(
1158
+ io.log(
849
1159
  `note: dropped skipped member(s) from ${entry.versionId}/${entry.namespace}: ${dropped.join(", ")}`,
850
1160
  );
851
1161
  }
852
1162
  const out = resolve(versionDirOf(entry.versionId), entry.outFile);
853
- mkdirSync(dirname(out), { recursive: true });
854
- writeFileSync(out, contents);
855
- console.log(`wrote ${out}`);
1163
+ io.mkdir(dirname(out));
1164
+ io.write(out, contents);
1165
+ io.log(`wrote ${out}`);
856
1166
  }
857
1167
  for (const target of versionedTargets) {
858
1168
  const indexOut = resolve(versionDirOf(target.id), "index.d.ts");
859
- mkdirSync(dirname(indexOut), { recursive: true });
860
- writeFileSync(
1169
+ io.mkdir(dirname(indexOut));
1170
+ io.write(
861
1171
  indexOut,
862
1172
  generateVersionIndex(
863
1173
  target.id,
@@ -865,24 +1175,28 @@ if (import.meta.main) {
865
1175
  versionSrcAugmentationImports(target),
866
1176
  ),
867
1177
  );
868
- console.log(`wrote ${indexOut}`);
1178
+ io.log(`wrote ${indexOut}`);
869
1179
 
870
1180
  const editorKinds = targetKindManifest(target).filter((entry) => entry.only !== undefined);
871
1181
  if (editorKinds.length === 0) continue;
872
1182
  const versionKindsDir = resolve(versionDirOf(target.id), "kinds");
873
- mkdirSync(versionKindsDir, { recursive: true });
1183
+ io.mkdir(versionKindsDir);
874
1184
  for (const entry of editorKinds) {
875
1185
  const out = resolve(versionKindsDir, `${entry.kind}.d.ts`);
876
- writeFileSync(out, generateKindIndex(entry.kind, target));
877
- console.log(`wrote ${out}`);
1186
+ io.write(out, generateKindIndex(entry.kind, target));
1187
+ io.log(`wrote ${out}`);
878
1188
  }
879
1189
  }
880
1190
 
881
1191
  const kindsDir = resolve(generated, "kinds");
882
- mkdirSync(kindsDir, { recursive: true });
1192
+ io.mkdir(kindsDir);
883
1193
  for (const entry of KIND_MODULE_MANIFEST) {
884
1194
  const out = resolve(kindsDir, `${entry.kind}.d.ts`);
885
- writeFileSync(out, generateKindIndex(entry.kind));
886
- console.log(`wrote ${out}`);
1195
+ io.write(out, generateKindIndex(entry.kind));
1196
+ io.log(`wrote ${out}`);
887
1197
  }
888
1198
  }
1199
+
1200
+ if (import.meta.main) {
1201
+ await regenerate();
1202
+ }