@defold-typescript/types 0.19.4 → 0.20.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.
- package/api-availability.json +2755 -0
- package/api-migrations.json +31 -0
- package/api-signatures.json +2324 -0
- package/api-targets.json +493 -45
- package/generated/b2d.d.ts +6 -0
- package/generated/b2d_body.d.ts +329 -1
- package/generated/b2d_chain.d.ts +106 -0
- package/generated/b2d_fixture.d.ts +155 -0
- package/generated/b2d_joint.d.ts +823 -0
- package/generated/b2d_shape.d.ts +215 -0
- package/generated/b2d_world.d.ts +314 -0
- package/generated/builtin-messages.d.ts +18 -0
- package/generated/camera.d.ts +62 -5
- package/generated/compute.d.ts +306 -0
- package/generated/go.d.ts +29 -4
- package/generated/graphics.d.ts +95 -0
- package/generated/gui.d.ts +1 -3
- package/generated/json.d.ts +2 -2
- package/generated/kinds/gui-script.d.ts +7 -0
- package/generated/kinds/render-script.d.ts +7 -0
- package/generated/kinds/script.d.ts +7 -0
- package/generated/label.d.ts +1 -1
- package/generated/liveupdate.d.ts +22 -4
- package/generated/material.d.ts +444 -0
- package/generated/model.d.ts +46 -5
- package/generated/physics.d.ts +1 -3
- package/generated/profiler.d.ts +2 -3
- package/generated/render.d.ts +25 -9
- package/generated/resource.d.ts +2 -2
- package/generated/sprite.d.ts +15 -1
- package/generated/tilemap.d.ts +14 -0
- package/generated/versions/defold-1.12.4/b2d.d.ts +27 -0
- package/generated/versions/defold-1.12.4/b2d_body.d.ts +348 -0
- package/generated/versions/defold-1.12.4/buffer.d.ts +176 -0
- package/generated/versions/defold-1.12.4/camera.d.ts +245 -0
- package/generated/versions/defold-1.12.4/collectionfactory.d.ts +146 -0
- package/generated/versions/defold-1.12.4/collectionproxy.d.ts +71 -0
- package/generated/versions/defold-1.12.4/crash.d.ts +143 -0
- package/generated/versions/defold-1.12.4/factory.d.ts +123 -0
- package/generated/versions/defold-1.12.4/font.d.ts +81 -0
- package/generated/versions/defold-1.12.4/go.d.ts +1029 -0
- package/generated/versions/defold-1.12.4/graphics.d.ts +226 -0
- package/generated/versions/defold-1.12.4/gui.d.ts +2372 -0
- package/generated/versions/defold-1.12.4/html5.d.ts +53 -0
- package/generated/versions/defold-1.12.4/http.d.ts +84 -0
- package/generated/versions/defold-1.12.4/iac.d.ts +18 -0
- package/generated/versions/defold-1.12.4/iap.d.ts +60 -0
- package/generated/versions/defold-1.12.4/image.d.ts +139 -0
- package/generated/versions/defold-1.12.4/index.d.ts +41 -0
- package/generated/versions/defold-1.12.4/json.d.ts +76 -0
- package/generated/versions/defold-1.12.4/label.d.ts +94 -0
- package/generated/versions/defold-1.12.4/liveupdate.d.ts +122 -0
- package/generated/versions/defold-1.12.4/model.d.ts +205 -0
- package/generated/versions/defold-1.12.4/msg.d.ts +10 -0
- package/generated/versions/defold-1.12.4/particlefx.d.ts +166 -0
- package/generated/versions/defold-1.12.4/physics.d.ts +547 -0
- package/generated/versions/defold-1.12.4/profiler.d.ts +234 -0
- package/generated/versions/defold-1.12.4/push.d.ts +66 -0
- package/generated/versions/defold-1.12.4/render.d.ts +1149 -0
- package/generated/versions/defold-1.12.4/resource.d.ts +1518 -0
- package/generated/versions/defold-1.12.4/socket.d.ts +795 -0
- package/generated/versions/defold-1.12.4/sound.d.ts +291 -0
- package/generated/versions/defold-1.12.4/sprite.d.ts +143 -0
- package/generated/versions/defold-1.12.4/sys.d.ts +695 -0
- package/generated/versions/defold-1.12.4/tilemap.d.ts +181 -0
- package/generated/versions/defold-1.12.4/timer.d.ts +114 -0
- package/generated/versions/defold-1.12.4/types.d.ts +61 -0
- package/generated/versions/defold-1.12.4/vmath.d.ts +806 -0
- package/generated/versions/defold-1.12.4/webview.d.ts +68 -0
- package/generated/versions/defold-1.12.4/window.d.ts +198 -0
- package/generated/versions/defold-1.12.4/zlib.d.ts +40 -0
- package/index.d.ts +22 -0
- package/package.json +8 -1
- package/scripts/fidelity-audit.ts +69 -12
- package/scripts/fidelity-baseline.json +56 -0
- package/scripts/generate-api-availability.ts +139 -0
- package/scripts/generate-api-signatures.ts +66 -0
- package/scripts/import-defold-release.ts +480 -0
- package/scripts/regen.ts +53 -6
- package/scripts/sync-api-docs.ts +89 -41
- package/src/api-availability.ts +0 -0
- package/src/core-types.ts +9 -0
- package/src/emit-dts.ts +674 -17
- package/src/emit-messages.ts +72 -2
- package/src/index.ts +26 -1
- package/src/lifecycle.ts +43 -2
package/src/emit-dts.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ApiSymbolIdentity, normalizedFunctionSignature } from "./api-availability";
|
|
1
2
|
import type {
|
|
2
3
|
ApiConstant,
|
|
3
4
|
ApiFunction,
|
|
@@ -150,6 +151,28 @@ export const ARBITRARY_TABLE_SLOTS = new Set([
|
|
|
150
151
|
"render.set_render_target",
|
|
151
152
|
]);
|
|
152
153
|
|
|
154
|
+
// Per-slot companion to ARBITRARY_TABLE_SLOTS (`element:kind:name`), for a
|
|
155
|
+
// genuinely-undocumented table slot on an element whose *other* slots are
|
|
156
|
+
// documented — an element-level entry would wrongly suppress those. Each slot's
|
|
157
|
+
// doc names no fields (Box2D internal/opaque structs), so `Record` is faithful,
|
|
158
|
+
// not a loss. The audit skips counting these; the emitter already leaves an
|
|
159
|
+
// uncurated slot as `Record`. Add deliberately, one rationale per line.
|
|
160
|
+
export const ARBITRARY_TABLE_SLOT_KEYS = new Set([
|
|
161
|
+
// "the chain definition" / "the shape definition" / "explosion definition" —
|
|
162
|
+
// create-side option tables with no documented field list at this slot.
|
|
163
|
+
"b2d.body.create_chain:param:definition",
|
|
164
|
+
"b2d.body.create_shape:param:definition",
|
|
165
|
+
"b2d.world.explode:param:definition",
|
|
166
|
+
"b2d.joint.create_filter:param:definition", // "optional definition table"
|
|
167
|
+
// opaque Box2D result structs: the doc names no fields.
|
|
168
|
+
"b2d.chain.get_geometry:return:geometry", // "chain geometry table"
|
|
169
|
+
"b2d.body.get_contact_data:return:contacts", // "array of contact tables"
|
|
170
|
+
"b2d.shape.get_contact_data:return:contacts", // "array of contact tables"
|
|
171
|
+
"b2d.world.collide_mover:return:planes", // "array of plane result tables"
|
|
172
|
+
"b2d.world.get_profile:return:profile", // "world profiling data"
|
|
173
|
+
"b2d.world.get_counters:return:counters", // "world counters"
|
|
174
|
+
]);
|
|
175
|
+
|
|
153
176
|
// skipFunction FQNs (see `api-targets.json`'s `skipFunctions`) whose absence
|
|
154
177
|
// from the generated surface is *not* a fidelity loss — each is replaced by a
|
|
155
178
|
// hand-written, better-typed overload in the cited `*-overloads.d.ts`, so the
|
|
@@ -256,10 +279,99 @@ export type TableSlotCuration =
|
|
|
256
279
|
| { kind: "mapping"; key: string; value: string | readonly TableField[] | NestedMapping }
|
|
257
280
|
| { kind: "array"; element: string | readonly string[] }
|
|
258
281
|
| { kind: "object"; fields: readonly TableField[] }
|
|
259
|
-
| { kind: "array-object"; fields: readonly TableField[] }
|
|
282
|
+
| { kind: "array-object"; fields: readonly TableField[] }
|
|
283
|
+
// A `<key> -> <args table>` slot: the doc's `<dl>` describes the *value* shape,
|
|
284
|
+
// keyed by an arbitrary name (constant/sampler/attribute). The parser recovers
|
|
285
|
+
// the inner args fields; emit wraps them as `Record<string, { <fields> }>`,
|
|
286
|
+
// restoring the keyed-by-name layer the flat object curation drops.
|
|
287
|
+
| { kind: "keyed-object" };
|
|
260
288
|
|
|
261
289
|
export const SOCKET_HANDLE_TOKENS = ["client", "master", "unconnected"] as const;
|
|
262
290
|
|
|
291
|
+
// Shared Box2D (b2d.*) table shapes, curated from the ref-doc prose (the docs
|
|
292
|
+
// name fields in running text, not a machine-readable `<dl>`). Reused across the
|
|
293
|
+
// b2d submodule curations below so a single shape is defined once.
|
|
294
|
+
//
|
|
295
|
+
// The shape table is a discriminated union of circle/edge/polygon/box/chain
|
|
296
|
+
// forms keyed by `type` (a b2d.shape.SHAPE_TYPE_* constant); every kind-specific
|
|
297
|
+
// field is optional because only one form's fields are present per value.
|
|
298
|
+
const B2D_SHAPE_TABLE_FIELDS: readonly TableField[] = [
|
|
299
|
+
{ name: "type", types: ["number"] },
|
|
300
|
+
{ name: "radius", types: ["number"], optional: true },
|
|
301
|
+
{ name: "center", types: ["vector3"], optional: true },
|
|
302
|
+
{ name: "v0", types: ["vector3"], optional: true },
|
|
303
|
+
{ name: "v1", types: ["vector3"], optional: true },
|
|
304
|
+
{ name: "v2", types: ["vector3"], optional: true },
|
|
305
|
+
{ name: "v3", types: ["vector3"], optional: true },
|
|
306
|
+
{ name: "vertices", types: ["table"], tsType: "Vector3[]", optional: true },
|
|
307
|
+
{ name: "hx", types: ["number"], optional: true },
|
|
308
|
+
{ name: "hy", types: ["number"], optional: true },
|
|
309
|
+
{ name: "angle", types: ["number"], optional: true },
|
|
310
|
+
{ name: "loop", types: ["boolean"], optional: true },
|
|
311
|
+
{ name: "prev_vertex", types: ["vector3"], optional: true },
|
|
312
|
+
{ name: "next_vertex", types: ["vector3"], optional: true },
|
|
313
|
+
];
|
|
314
|
+
// A fixture info entry (index/type/sensor/density/friction/restitution/child_count).
|
|
315
|
+
const B2D_FIXTURE_INFO_FIELDS: readonly TableField[] = [
|
|
316
|
+
{ name: "index", types: ["number"] },
|
|
317
|
+
{ name: "type", types: ["number"] },
|
|
318
|
+
{ name: "sensor", types: ["boolean"] },
|
|
319
|
+
{ name: "density", types: ["number"] },
|
|
320
|
+
{ name: "friction", types: ["number"] },
|
|
321
|
+
{ name: "restitution", types: ["number"] },
|
|
322
|
+
{ name: "child_count", types: ["number"] },
|
|
323
|
+
];
|
|
324
|
+
// A shape info entry: only `shape_id` is documented ("Each entry includes
|
|
325
|
+
// shape_id"); other members are engine-internal and left untyped.
|
|
326
|
+
const B2D_SHAPE_INFO_FIELDS: readonly TableField[] = [{ name: "shape_id", types: ["number"] }];
|
|
327
|
+
// mass properties: mass/inertia scalars plus the local-space center point.
|
|
328
|
+
const B2D_MASS_DATA_FIELDS: readonly TableField[] = [
|
|
329
|
+
{ name: "mass", types: ["number"] },
|
|
330
|
+
{ name: "center", types: ["vector3"] },
|
|
331
|
+
{ name: "inertia", types: ["number"] },
|
|
332
|
+
];
|
|
333
|
+
// an AABB corner pair.
|
|
334
|
+
const B2D_AABB_FIELDS: readonly TableField[] = [
|
|
335
|
+
{ name: "lower", types: ["vector3"] },
|
|
336
|
+
{ name: "upper", types: ["vector3"] },
|
|
337
|
+
];
|
|
338
|
+
// a broad-phase query filter. group_index is optional on the query side.
|
|
339
|
+
const B2D_QUERY_FILTER_FIELDS: readonly TableField[] = [
|
|
340
|
+
{ name: "category_bits", types: ["number"] },
|
|
341
|
+
{ name: "mask_bits", types: ["number"] },
|
|
342
|
+
{ name: "group_index", types: ["number"], optional: true },
|
|
343
|
+
];
|
|
344
|
+
// the fixture filter data: category/mask bits plus a group index (all documented).
|
|
345
|
+
const B2D_FILTER_DATA_FIELDS: readonly TableField[] = [
|
|
346
|
+
{ name: "category_bits", types: ["number"] },
|
|
347
|
+
{ name: "mask_bits", types: ["number"] },
|
|
348
|
+
{ name: "group_index", types: ["number"] },
|
|
349
|
+
];
|
|
350
|
+
// the mover filter: category/mask bits only (no group index).
|
|
351
|
+
const B2D_MOVER_FILTER_FIELDS: readonly TableField[] = [
|
|
352
|
+
{ name: "category_bits", types: ["number"] },
|
|
353
|
+
{ name: "mask_bits", types: ["number"] },
|
|
354
|
+
];
|
|
355
|
+
// tree traversal stats reported by a broad-phase query.
|
|
356
|
+
const B2D_QUERY_STATS_FIELDS: readonly TableField[] = [
|
|
357
|
+
{ name: "node_visits", types: ["number"] },
|
|
358
|
+
{ name: "leaf_visits", types: ["number"] },
|
|
359
|
+
];
|
|
360
|
+
// a mover capsule.
|
|
361
|
+
const B2D_CAPSULE_FIELDS: readonly TableField[] = [
|
|
362
|
+
{ name: "center1", types: ["vector3"] },
|
|
363
|
+
{ name: "center2", types: ["vector3"] },
|
|
364
|
+
{ name: "radius", types: ["number"] },
|
|
365
|
+
];
|
|
366
|
+
// a raycast/shapecast hit entry.
|
|
367
|
+
const B2D_CAST_HIT_FIELDS: readonly TableField[] = [
|
|
368
|
+
{ name: "fixture", types: ["number"] },
|
|
369
|
+
{ name: "shape", types: ["number"] },
|
|
370
|
+
{ name: "point", types: ["vector3"] },
|
|
371
|
+
{ name: "normal", types: ["vector3"] },
|
|
372
|
+
{ name: "fraction", types: ["number"] },
|
|
373
|
+
];
|
|
374
|
+
|
|
263
375
|
export const TABLE_SLOT_CURATIONS: ReadonlyMap<string, TableSlotCuration> = new Map([
|
|
264
376
|
["collectionfactory.create:return:ids", { kind: "mapping", key: "hash", value: "hash" }],
|
|
265
377
|
// font.get_info's `info` return is a `<dl>` with `path: hash` and a nested
|
|
@@ -560,6 +672,359 @@ export const TABLE_SLOT_CURATIONS: ReadonlyMap<string, TableSlotCuration> = new
|
|
|
560
672
|
],
|
|
561
673
|
},
|
|
562
674
|
],
|
|
675
|
+
// compute/material shader-constant, sampler, and vertex-attribute setters take
|
|
676
|
+
// "a table keyed by <name> with args tables as values": the `<dl>` documents
|
|
677
|
+
// the *value* shape, keyed by an arbitrary constant/sampler/attribute name.
|
|
678
|
+
// The keyed-object curation re-keys the parser-recovered args fields as
|
|
679
|
+
// `Record<string, { … }>`, restoring the keyed-by-name layer a flat object
|
|
680
|
+
// curation drops — so the documented `{ tint: { value: … } }` call compiles.
|
|
681
|
+
["compute.set_constants:param:constants", { kind: "keyed-object" }],
|
|
682
|
+
["compute.set_samplers:param:samplers", { kind: "keyed-object" }],
|
|
683
|
+
["material.set_constants:param:constants", { kind: "keyed-object" }],
|
|
684
|
+
["material.set_samplers:param:samplers", { kind: "keyed-object" }],
|
|
685
|
+
["material.set_vertex_attributes:param:attributes", { kind: "keyed-object" }],
|
|
686
|
+
// compute/material texture setters take "a table keyed by sampler name with
|
|
687
|
+
// texture resources as values" — a name-keyed map to a resource-path hash.
|
|
688
|
+
["compute.set_textures:param:textures", { kind: "mapping", key: "string", value: "hash" }],
|
|
689
|
+
["material.set_textures:param:textures", { kind: "mapping", key: "string", value: "hash" }],
|
|
690
|
+
// model blend weights are a numeric Lua array ("array of weight values"), not
|
|
691
|
+
// an opaque record; get returns the array, set takes it (optional on the param
|
|
692
|
+
// side — omitting it resets the weights).
|
|
693
|
+
["model.get_blend_weights:return:weights", { kind: "array", element: "number" }],
|
|
694
|
+
["model.set_blend_weights:param:weights", { kind: "array", element: "number" }],
|
|
695
|
+
// graphics adapter inspection. get_engine_adapters returns "array of adapter
|
|
696
|
+
// family name strings"; get_adapter_info returns a documented object whose
|
|
697
|
+
// `limits` sub-table is a flat number map, `extensions` a string array, and
|
|
698
|
+
// `features` an array of graphics.CONTEXT_FEATURE_* ids (numbers). The
|
|
699
|
+
// `limits`/`extensions`/`features` shapes live in codehilite blocks the parser
|
|
700
|
+
// cannot read, so the whole object is curated from the prose field list.
|
|
701
|
+
["graphics.get_engine_adapters:return:adapters", { kind: "array", element: "string" }],
|
|
702
|
+
[
|
|
703
|
+
"graphics.get_adapter_info:return:info",
|
|
704
|
+
{
|
|
705
|
+
kind: "object",
|
|
706
|
+
fields: [
|
|
707
|
+
{ name: "family", types: ["string"] },
|
|
708
|
+
{ name: "version_major", types: ["number"] },
|
|
709
|
+
{ name: "version_minor", types: ["number"] },
|
|
710
|
+
{
|
|
711
|
+
name: "limits",
|
|
712
|
+
types: ["table"],
|
|
713
|
+
fields: [
|
|
714
|
+
{ name: "max_texture_size_2d", types: ["number"] },
|
|
715
|
+
{ name: "max_texture_size_3d", types: ["number"] },
|
|
716
|
+
{ name: "max_texture_size_cube", types: ["number"] },
|
|
717
|
+
{ name: "max_texture_array_layers", types: ["number"] },
|
|
718
|
+
{ name: "max_framebuffer_width", types: ["number"] },
|
|
719
|
+
{ name: "max_framebuffer_height", types: ["number"] },
|
|
720
|
+
{ name: "max_color_attachments", types: ["number"] },
|
|
721
|
+
{ name: "max_samplers_per_stage", types: ["number"] },
|
|
722
|
+
{ name: "max_textures_per_stage", types: ["number"] },
|
|
723
|
+
{ name: "max_vertex_attributes", types: ["number"] },
|
|
724
|
+
{ name: "max_vertex_buffers", types: ["number"] },
|
|
725
|
+
{ name: "max_compute_workgroup_size_x", types: ["number"] },
|
|
726
|
+
{ name: "max_compute_workgroup_size_y", types: ["number"] },
|
|
727
|
+
{ name: "max_compute_workgroup_size_z", types: ["number"] },
|
|
728
|
+
{ name: "max_compute_workgroup_invocations", types: ["number"] },
|
|
729
|
+
{ name: "max_compute_shared_memory_size", types: ["number"] },
|
|
730
|
+
{ name: "max_uniform_buffer_range", types: ["number"] },
|
|
731
|
+
{ name: "max_storage_buffer_range", types: ["number"] },
|
|
732
|
+
],
|
|
733
|
+
},
|
|
734
|
+
{ name: "extensions", types: ["table"], tsType: "string[]" },
|
|
735
|
+
{ name: "features", types: ["table"], tsType: "number[]" },
|
|
736
|
+
],
|
|
737
|
+
},
|
|
738
|
+
],
|
|
739
|
+
// ---- Box2D (b2d.*) curated table shapes ----------------------------------
|
|
740
|
+
// All field names come from the ref-doc prose; genuinely-undocumented slots
|
|
741
|
+
// (chain/shape/explosion definitions, contact/plane/profile/counter structs)
|
|
742
|
+
// are per-slot-arbitrary via ARBITRARY_TABLE_SLOT_KEYS, not curated here.
|
|
743
|
+
//
|
|
744
|
+
// b2d root: version info table.
|
|
745
|
+
[
|
|
746
|
+
"b2d.get_version:return:info",
|
|
747
|
+
{
|
|
748
|
+
kind: "object",
|
|
749
|
+
fields: [
|
|
750
|
+
{ name: "version", types: ["number"] },
|
|
751
|
+
{ name: "major", types: ["number"] },
|
|
752
|
+
{ name: "middle", types: ["number"] },
|
|
753
|
+
{ name: "minor", types: ["number"] },
|
|
754
|
+
],
|
|
755
|
+
},
|
|
756
|
+
],
|
|
757
|
+
// b2d.body
|
|
758
|
+
["b2d.body.compute_aabb:return:aabb", { kind: "object", fields: B2D_AABB_FIELDS }],
|
|
759
|
+
[
|
|
760
|
+
"b2d.body.create_fixture:param:definition",
|
|
761
|
+
{
|
|
762
|
+
kind: "object",
|
|
763
|
+
fields: [
|
|
764
|
+
{ name: "shape", types: ["table"], fields: [...B2D_SHAPE_TABLE_FIELDS] },
|
|
765
|
+
{ name: "friction", types: ["number"] },
|
|
766
|
+
{ name: "restitution", types: ["number"] },
|
|
767
|
+
{ name: "density", types: ["number"] },
|
|
768
|
+
{ name: "sensor", types: ["boolean"] },
|
|
769
|
+
{ name: "filter", types: ["table"], fields: [...B2D_FILTER_DATA_FIELDS] },
|
|
770
|
+
],
|
|
771
|
+
},
|
|
772
|
+
],
|
|
773
|
+
["b2d.body.create_fixture:return:fixture", { kind: "object", fields: B2D_FIXTURE_INFO_FIELDS }],
|
|
774
|
+
[
|
|
775
|
+
"b2d.body.create_chain:return:segments",
|
|
776
|
+
{ kind: "array-object", fields: B2D_SHAPE_INFO_FIELDS },
|
|
777
|
+
],
|
|
778
|
+
[
|
|
779
|
+
"b2d.body.get_fixtures:return:fixtures",
|
|
780
|
+
{ kind: "array-object", fields: B2D_FIXTURE_INFO_FIELDS },
|
|
781
|
+
],
|
|
782
|
+
// get_joints returns an array of opaque b2Joint handles (numbers).
|
|
783
|
+
["b2d.body.get_joints:return:joints", { kind: "array", element: "number" }],
|
|
784
|
+
["b2d.body.get_mass_data:return:data", { kind: "object", fields: B2D_MASS_DATA_FIELDS }],
|
|
785
|
+
["b2d.body.set_mass_data:param:data", { kind: "object", fields: B2D_MASS_DATA_FIELDS }],
|
|
786
|
+
["b2d.body.get_shapes:return:shapes", { kind: "array-object", fields: B2D_SHAPE_INFO_FIELDS }],
|
|
787
|
+
[
|
|
788
|
+
"b2d.body.get_transform:return:transform",
|
|
789
|
+
{
|
|
790
|
+
kind: "object",
|
|
791
|
+
fields: [
|
|
792
|
+
{ name: "position", types: ["vector3"] },
|
|
793
|
+
{ name: "angle", types: ["number"] },
|
|
794
|
+
],
|
|
795
|
+
},
|
|
796
|
+
],
|
|
797
|
+
// b2d.chain
|
|
798
|
+
[
|
|
799
|
+
"b2d.chain.get_segments:return:segments",
|
|
800
|
+
{ kind: "array-object", fields: B2D_SHAPE_INFO_FIELDS },
|
|
801
|
+
],
|
|
802
|
+
// b2d.fixture
|
|
803
|
+
["b2d.fixture.get_aabb:return:aabb", { kind: "object", fields: B2D_AABB_FIELDS }],
|
|
804
|
+
["b2d.fixture.get_filter_data:return:filter", { kind: "object", fields: B2D_FILTER_DATA_FIELDS }],
|
|
805
|
+
["b2d.fixture.set_filter_data:param:filter", { kind: "object", fields: B2D_FILTER_DATA_FIELDS }],
|
|
806
|
+
["b2d.fixture.get_shape:return:shape", { kind: "object", fields: B2D_SHAPE_TABLE_FIELDS }],
|
|
807
|
+
["b2d.fixture.set_shape:param:shape", { kind: "object", fields: B2D_SHAPE_TABLE_FIELDS }],
|
|
808
|
+
// b2d.shape
|
|
809
|
+
["b2d.shape.get_shape:return:shape", { kind: "object", fields: B2D_SHAPE_TABLE_FIELDS }],
|
|
810
|
+
["b2d.shape.set_shape:param:definition", { kind: "object", fields: B2D_SHAPE_TABLE_FIELDS }],
|
|
811
|
+
["b2d.shape.get_mass_data:return:data", { kind: "object", fields: B2D_MASS_DATA_FIELDS }],
|
|
812
|
+
[
|
|
813
|
+
"b2d.shape.get_sensor_overlaps:return:overlaps",
|
|
814
|
+
{ kind: "array-object", fields: B2D_SHAPE_INFO_FIELDS },
|
|
815
|
+
],
|
|
816
|
+
[
|
|
817
|
+
"b2d.shape.ray_cast:return:hit",
|
|
818
|
+
{
|
|
819
|
+
kind: "object",
|
|
820
|
+
fields: [
|
|
821
|
+
{ name: "point", types: ["vector3"] },
|
|
822
|
+
{ name: "normal", types: ["vector3"] },
|
|
823
|
+
{ name: "fraction", types: ["number"] },
|
|
824
|
+
{ name: "iterations", types: ["number"] },
|
|
825
|
+
],
|
|
826
|
+
},
|
|
827
|
+
],
|
|
828
|
+
// b2d.joint create_* definitions (each an optional, joint-type-specific option
|
|
829
|
+
// table; every field is optional because the whole `definition` param is).
|
|
830
|
+
[
|
|
831
|
+
"b2d.joint.create_distance:param:definition",
|
|
832
|
+
{
|
|
833
|
+
kind: "object",
|
|
834
|
+
fields: [
|
|
835
|
+
{ name: "local_anchor_a", types: ["vector3"] },
|
|
836
|
+
{ name: "local_anchor_b", types: ["vector3"] },
|
|
837
|
+
{ name: "length", types: ["number"] },
|
|
838
|
+
{ name: "frequency", types: ["number"] },
|
|
839
|
+
{ name: "damping_ratio", types: ["number"] },
|
|
840
|
+
{ name: "collide_connected", types: ["boolean"] },
|
|
841
|
+
],
|
|
842
|
+
},
|
|
843
|
+
],
|
|
844
|
+
[
|
|
845
|
+
"b2d.joint.create_mouse:param:definition",
|
|
846
|
+
{
|
|
847
|
+
kind: "object",
|
|
848
|
+
fields: [
|
|
849
|
+
{ name: "target", types: ["vector3"] },
|
|
850
|
+
{ name: "max_force", types: ["number"] },
|
|
851
|
+
{ name: "frequency", types: ["number"] },
|
|
852
|
+
{ name: "damping_ratio", types: ["number"] },
|
|
853
|
+
{ name: "collide_connected", types: ["boolean"] },
|
|
854
|
+
],
|
|
855
|
+
},
|
|
856
|
+
],
|
|
857
|
+
[
|
|
858
|
+
"b2d.joint.create_prismatic:param:definition",
|
|
859
|
+
{
|
|
860
|
+
kind: "object",
|
|
861
|
+
fields: [
|
|
862
|
+
{ name: "local_anchor_a", types: ["vector3"] },
|
|
863
|
+
{ name: "local_anchor_b", types: ["vector3"] },
|
|
864
|
+
{ name: "local_axis_a", types: ["vector3"] },
|
|
865
|
+
{ name: "reference_angle", types: ["number"] },
|
|
866
|
+
{ name: "enable_limit", types: ["boolean"] },
|
|
867
|
+
{ name: "lower_translation", types: ["number"] },
|
|
868
|
+
{ name: "upper_translation", types: ["number"] },
|
|
869
|
+
{ name: "enable_motor", types: ["boolean"] },
|
|
870
|
+
{ name: "max_motor_force", types: ["number"] },
|
|
871
|
+
{ name: "motor_speed", types: ["number"] },
|
|
872
|
+
{ name: "collide_connected", types: ["boolean"] },
|
|
873
|
+
],
|
|
874
|
+
},
|
|
875
|
+
],
|
|
876
|
+
[
|
|
877
|
+
"b2d.joint.create_revolute:param:definition",
|
|
878
|
+
{
|
|
879
|
+
kind: "object",
|
|
880
|
+
fields: [
|
|
881
|
+
{ name: "local_anchor_a", types: ["vector3"] },
|
|
882
|
+
{ name: "local_anchor_b", types: ["vector3"] },
|
|
883
|
+
{ name: "reference_angle", types: ["number"] },
|
|
884
|
+
{ name: "enable_limit", types: ["boolean"] },
|
|
885
|
+
{ name: "lower_angle", types: ["number"] },
|
|
886
|
+
{ name: "upper_angle", types: ["number"] },
|
|
887
|
+
{ name: "enable_motor", types: ["boolean"] },
|
|
888
|
+
{ name: "max_motor_torque", types: ["number"] },
|
|
889
|
+
{ name: "motor_speed", types: ["number"] },
|
|
890
|
+
{ name: "collide_connected", types: ["boolean"] },
|
|
891
|
+
],
|
|
892
|
+
},
|
|
893
|
+
],
|
|
894
|
+
[
|
|
895
|
+
"b2d.joint.create_weld:param:definition",
|
|
896
|
+
{
|
|
897
|
+
kind: "object",
|
|
898
|
+
fields: [
|
|
899
|
+
{ name: "local_anchor_a", types: ["vector3"] },
|
|
900
|
+
{ name: "local_anchor_b", types: ["vector3"] },
|
|
901
|
+
{ name: "reference_angle", types: ["number"] },
|
|
902
|
+
{ name: "frequency", types: ["number"] },
|
|
903
|
+
{ name: "damping_ratio", types: ["number"] },
|
|
904
|
+
{ name: "collide_connected", types: ["boolean"] },
|
|
905
|
+
],
|
|
906
|
+
},
|
|
907
|
+
],
|
|
908
|
+
[
|
|
909
|
+
"b2d.joint.create_wheel:param:definition",
|
|
910
|
+
{
|
|
911
|
+
kind: "object",
|
|
912
|
+
fields: [
|
|
913
|
+
{ name: "local_anchor_a", types: ["vector3"] },
|
|
914
|
+
{ name: "local_anchor_b", types: ["vector3"] },
|
|
915
|
+
{ name: "local_axis_a", types: ["vector3"] },
|
|
916
|
+
{ name: "enable_motor", types: ["boolean"] },
|
|
917
|
+
{ name: "max_motor_torque", types: ["number"] },
|
|
918
|
+
{ name: "motor_speed", types: ["number"] },
|
|
919
|
+
{ name: "frequency", types: ["number"] },
|
|
920
|
+
{ name: "damping_ratio", types: ["number"] },
|
|
921
|
+
{ name: "collide_connected", types: ["boolean"] },
|
|
922
|
+
],
|
|
923
|
+
},
|
|
924
|
+
],
|
|
925
|
+
[
|
|
926
|
+
"b2d.joint.create_friction:param:definition",
|
|
927
|
+
{
|
|
928
|
+
kind: "object",
|
|
929
|
+
fields: [
|
|
930
|
+
{ name: "local_anchor_a", types: ["vector3"] },
|
|
931
|
+
{ name: "local_anchor_b", types: ["vector3"] },
|
|
932
|
+
{ name: "max_force", types: ["number"] },
|
|
933
|
+
{ name: "max_torque", types: ["number"] },
|
|
934
|
+
{ name: "collide_connected", types: ["boolean"] },
|
|
935
|
+
],
|
|
936
|
+
},
|
|
937
|
+
],
|
|
938
|
+
[
|
|
939
|
+
"b2d.joint.create_rope:param:definition",
|
|
940
|
+
{
|
|
941
|
+
kind: "object",
|
|
942
|
+
fields: [
|
|
943
|
+
{ name: "local_anchor_a", types: ["vector3"] },
|
|
944
|
+
{ name: "local_anchor_b", types: ["vector3"] },
|
|
945
|
+
{ name: "max_length", types: ["number"] },
|
|
946
|
+
{ name: "collide_connected", types: ["boolean"] },
|
|
947
|
+
],
|
|
948
|
+
},
|
|
949
|
+
],
|
|
950
|
+
[
|
|
951
|
+
"b2d.joint.create_pulley:param:definition",
|
|
952
|
+
{
|
|
953
|
+
kind: "object",
|
|
954
|
+
fields: [
|
|
955
|
+
{ name: "ground_anchor_a", types: ["vector3"] },
|
|
956
|
+
{ name: "ground_anchor_b", types: ["vector3"] },
|
|
957
|
+
{ name: "local_anchor_a", types: ["vector3"] },
|
|
958
|
+
{ name: "local_anchor_b", types: ["vector3"] },
|
|
959
|
+
{ name: "length_a", types: ["number"] },
|
|
960
|
+
{ name: "length_b", types: ["number"] },
|
|
961
|
+
{ name: "ratio", types: ["number"] },
|
|
962
|
+
{ name: "collide_connected", types: ["boolean"] },
|
|
963
|
+
],
|
|
964
|
+
},
|
|
965
|
+
],
|
|
966
|
+
[
|
|
967
|
+
"b2d.joint.create_gear:param:definition",
|
|
968
|
+
{ kind: "object", fields: [{ name: "ratio", types: ["number"] }] },
|
|
969
|
+
],
|
|
970
|
+
[
|
|
971
|
+
"b2d.joint.create_motor:param:definition",
|
|
972
|
+
{
|
|
973
|
+
kind: "object",
|
|
974
|
+
fields: [
|
|
975
|
+
{ name: "linear_offset", types: ["vector3"] },
|
|
976
|
+
{ name: "angular_offset", types: ["number"] },
|
|
977
|
+
{ name: "max_force", types: ["number"] },
|
|
978
|
+
{ name: "max_torque", types: ["number"] },
|
|
979
|
+
{ name: "correction_factor", types: ["number"] },
|
|
980
|
+
{ name: "collide_connected", types: ["boolean"] },
|
|
981
|
+
],
|
|
982
|
+
},
|
|
983
|
+
],
|
|
984
|
+
// b2d.world broad-phase queries + movers.
|
|
985
|
+
["b2d.world.overlap_aabb:param:aabb", { kind: "object", fields: B2D_AABB_FIELDS }],
|
|
986
|
+
["b2d.world.overlap_aabb:param:filter", { kind: "object", fields: B2D_QUERY_FILTER_FIELDS }],
|
|
987
|
+
[
|
|
988
|
+
"b2d.world.overlap_aabb:return:fixtures",
|
|
989
|
+
{ kind: "array-object", fields: B2D_FIXTURE_INFO_FIELDS },
|
|
990
|
+
],
|
|
991
|
+
["b2d.world.overlap_aabb:return:hits", { kind: "array-object", fields: B2D_SHAPE_INFO_FIELDS }],
|
|
992
|
+
["b2d.world.overlap_aabb:return:stats", { kind: "object", fields: B2D_QUERY_STATS_FIELDS }],
|
|
993
|
+
["b2d.world.overlap_shape:param:shape", { kind: "object", fields: B2D_SHAPE_TABLE_FIELDS }],
|
|
994
|
+
["b2d.world.overlap_shape:param:filter", { kind: "object", fields: B2D_QUERY_FILTER_FIELDS }],
|
|
995
|
+
[
|
|
996
|
+
"b2d.world.overlap_shape:return:fixtures",
|
|
997
|
+
{ kind: "array-object", fields: B2D_FIXTURE_INFO_FIELDS },
|
|
998
|
+
],
|
|
999
|
+
["b2d.world.overlap_shape:return:hits", { kind: "array-object", fields: B2D_SHAPE_INFO_FIELDS }],
|
|
1000
|
+
["b2d.world.overlap_shape:return:stats", { kind: "object", fields: B2D_QUERY_STATS_FIELDS }],
|
|
1001
|
+
["b2d.world.cast_ray:param:filter", { kind: "object", fields: B2D_QUERY_FILTER_FIELDS }],
|
|
1002
|
+
["b2d.world.cast_ray:return:hits", { kind: "array-object", fields: B2D_CAST_HIT_FIELDS }],
|
|
1003
|
+
["b2d.world.cast_ray:return:stats", { kind: "object", fields: B2D_QUERY_STATS_FIELDS }],
|
|
1004
|
+
["b2d.world.cast_ray_closest:param:filter", { kind: "object", fields: B2D_QUERY_FILTER_FIELDS }],
|
|
1005
|
+
[
|
|
1006
|
+
"b2d.world.cast_ray_closest:return:hit",
|
|
1007
|
+
{
|
|
1008
|
+
kind: "object",
|
|
1009
|
+
fields: [
|
|
1010
|
+
{ name: "fixture", types: ["number"] },
|
|
1011
|
+
{ name: "shape", types: ["number"] },
|
|
1012
|
+
{ name: "point", types: ["vector3"] },
|
|
1013
|
+
{ name: "normal", types: ["vector3"] },
|
|
1014
|
+
{ name: "fraction", types: ["number"] },
|
|
1015
|
+
{ name: "node_visits", types: ["number"] },
|
|
1016
|
+
{ name: "leaf_visits", types: ["number"] },
|
|
1017
|
+
],
|
|
1018
|
+
},
|
|
1019
|
+
],
|
|
1020
|
+
["b2d.world.cast_shape:param:shape", { kind: "object", fields: B2D_SHAPE_TABLE_FIELDS }],
|
|
1021
|
+
["b2d.world.cast_shape:param:filter", { kind: "object", fields: B2D_QUERY_FILTER_FIELDS }],
|
|
1022
|
+
["b2d.world.cast_shape:return:hits", { kind: "array-object", fields: B2D_CAST_HIT_FIELDS }],
|
|
1023
|
+
["b2d.world.cast_shape:return:stats", { kind: "object", fields: B2D_QUERY_STATS_FIELDS }],
|
|
1024
|
+
["b2d.world.cast_mover:param:capsule", { kind: "object", fields: B2D_CAPSULE_FIELDS }],
|
|
1025
|
+
["b2d.world.cast_mover:param:filter", { kind: "object", fields: B2D_MOVER_FILTER_FIELDS }],
|
|
1026
|
+
["b2d.world.collide_mover:param:capsule", { kind: "object", fields: B2D_CAPSULE_FIELDS }],
|
|
1027
|
+
["b2d.world.collide_mover:param:filter", { kind: "object", fields: B2D_MOVER_FILTER_FIELDS }],
|
|
563
1028
|
]);
|
|
564
1029
|
|
|
565
1030
|
// Slot-keyed (`element:param:name`, mirroring TABLE_SLOT_CURATIONS) replacements
|
|
@@ -600,6 +1065,43 @@ export const NESTED_FIELD_CURATIONS: ReadonlyMap<string, readonly TableField[]>
|
|
|
600
1065
|
["resource.get_atlas:return:data:geometries", ATLAS_GEOMETRY_MEMBERS],
|
|
601
1066
|
]);
|
|
602
1067
|
|
|
1068
|
+
// The shader-constant / vertex-attribute `value` field is documented as
|
|
1069
|
+
// `vmath.vector4 | vmath.vector3 | vmath.matrix4 | number | table`, where the
|
|
1070
|
+
// trailing `table` is the *array* form ("a table of vmath.vector4 or
|
|
1071
|
+
// vmath.matrix4" for constants, "a table of numbers" for matrix attributes). The
|
|
1072
|
+
// parser recovers every other field faithfully but leaves that `table` token as
|
|
1073
|
+
// a bare `Record`; this pins only the `value` field's TS type to the documented
|
|
1074
|
+
// array union while every sibling field stays parser-authoritative. Keyed by
|
|
1075
|
+
// `<element>:<kind>:<slot>:<field>`, mirroring NESTED_FIELD_CURATIONS.
|
|
1076
|
+
const CONSTANT_VALUE_TS = "Vector4 | Vector3 | Matrix4 | number | (Vector4 | Matrix4)[]";
|
|
1077
|
+
const ATTRIBUTE_VALUE_TS = "Vector4 | Vector3 | Matrix4 | number | number[]";
|
|
1078
|
+
export const TABLE_FIELD_TYPE_OVERRIDES: ReadonlyMap<string, string> = new Map([
|
|
1079
|
+
["compute.set_constants:param:constants:value", CONSTANT_VALUE_TS],
|
|
1080
|
+
["material.set_constants:param:constants:value", CONSTANT_VALUE_TS],
|
|
1081
|
+
["material.set_vertex_attributes:param:attributes:value", ATTRIBUTE_VALUE_TS],
|
|
1082
|
+
["material.get_vertex_attributes:return:table:value", ATTRIBUTE_VALUE_TS],
|
|
1083
|
+
]);
|
|
1084
|
+
|
|
1085
|
+
// Pin a parser-recovered field's TS type from TABLE_FIELD_TYPE_OVERRIDES,
|
|
1086
|
+
// leaving every other field parser-authoritative. A field the override does not
|
|
1087
|
+
// name is returned unchanged; a field it names gains a `tsType` (emitted
|
|
1088
|
+
// verbatim, treated as recovered by the audit). Returns a new array; never
|
|
1089
|
+
// mutates the parser's result. Mirrors applyNestedFieldCurations.
|
|
1090
|
+
export function applyFieldTypeOverrides(
|
|
1091
|
+
elementName: string,
|
|
1092
|
+
slotKind: "param" | "return" | undefined,
|
|
1093
|
+
slotName: string | undefined,
|
|
1094
|
+
fields: readonly TableField[],
|
|
1095
|
+
): TableField[] {
|
|
1096
|
+
if (slotKind === undefined || slotName === undefined) return [...fields];
|
|
1097
|
+
return fields.map((field) => {
|
|
1098
|
+
const override = TABLE_FIELD_TYPE_OVERRIDES.get(
|
|
1099
|
+
`${elementName}:${slotKind}:${slotName}:${field.name}`,
|
|
1100
|
+
);
|
|
1101
|
+
return override === undefined ? field : { ...field, tsType: override };
|
|
1102
|
+
});
|
|
1103
|
+
}
|
|
1104
|
+
|
|
603
1105
|
/**
|
|
604
1106
|
* Recover a Defold `function(...)` callback-signature token into a TypeScript
|
|
605
1107
|
* function type. The token carries parameter names but no inner types, so each
|
|
@@ -631,16 +1133,30 @@ export function recoverCallbackSignature(token: string): string | null {
|
|
|
631
1133
|
const TABLE_FIELD =
|
|
632
1134
|
/<dt>\s*<code>([^<]+)<\/code>\s*<\/dt>\s*<dd>\s*<span class="type">([^<]+)<\/span>([^<]*)/g;
|
|
633
1135
|
const LIST_PROSE = /\ba list of\b/i;
|
|
634
|
-
// The slot-level array signal ("an array of …" / "a list of …"
|
|
635
|
-
//
|
|
636
|
-
//
|
|
637
|
-
//
|
|
638
|
-
// marker can never wrap the whole
|
|
639
|
-
|
|
640
|
-
|
|
1136
|
+
// The slot-level array signal ("an array of …" / "a list of …" / the
|
|
1137
|
+
// records-collection "table of tables" form) lives in the prose preceding the
|
|
1138
|
+
// field list, never in a field's own `<dd>` (that is the per-field `LIST_PROSE`
|
|
1139
|
+
// path). `isSlotLevelList` therefore tests only the substring before the first
|
|
1140
|
+
// `<dl>`/`<ul>`/`<li>`, so a field-internal list marker can never wrap the whole
|
|
1141
|
+
// slot. The `tables? of tables?` clause wraps the compute/material getters whose
|
|
1142
|
+
// return doc opens "A table of tables, where each entry …".
|
|
1143
|
+
export const SLOT_LEVEL_LIST_PROSE = /\b(an?\s+array of|a\s+list of|tables?\s+of\s+tables?)\b/i;
|
|
1144
|
+
export function isSlotLevelList(doc: string): boolean {
|
|
641
1145
|
const prefix = doc.split(/<dl>|<ul>|<li>/i)[0] ?? "";
|
|
642
1146
|
return SLOT_LEVEL_LIST_PROSE.test(prefix);
|
|
643
1147
|
}
|
|
1148
|
+
// The oracle for the fidelity audit: a records-collection return slot is any
|
|
1149
|
+
// "array/list/collection of tables" or "table of tables" form. Intentionally
|
|
1150
|
+
// broader than `SLOT_LEVEL_LIST_PROSE` (which names only the forms the emitter
|
|
1151
|
+
// actually wraps) so a records-collection wording the wrap trigger stops
|
|
1152
|
+
// recognizing re-surfaces as a counted loss, keeping the gate and the emitted
|
|
1153
|
+
// surface coupled. Scoped to the prose before the field list, same as above.
|
|
1154
|
+
export const RECORDS_COLLECTION_PROSE =
|
|
1155
|
+
/\b(an?\s+(?:array|list|collection)\s+of\s+tables?|tables?\s+of\s+tables?)\b/i;
|
|
1156
|
+
export function isRecordsCollectionSlot(doc: string): boolean {
|
|
1157
|
+
const prefix = doc.split(/<dl>|<ul>|<li>/i)[0] ?? "";
|
|
1158
|
+
return RECORDS_COLLECTION_PROSE.test(prefix);
|
|
1159
|
+
}
|
|
644
1160
|
const FLATTENED_TABLE = /<li>\s*<dl>/;
|
|
645
1161
|
// A number-list slot's element type is read from the brace form a "a list of …"
|
|
646
1162
|
// `<dd>` ends with: `in the form {px0, py0, ..., pxn, pyn}` / `{i0, i1, ..., in}`.
|
|
@@ -726,6 +1242,12 @@ export interface TableField {
|
|
|
726
1242
|
isList?: boolean;
|
|
727
1243
|
numberList?: boolean;
|
|
728
1244
|
optional?: boolean;
|
|
1245
|
+
// A hand-curated field whose faithful TS shape is not a plain token union
|
|
1246
|
+
// (e.g. a nested vector array, or a documented value union with an array
|
|
1247
|
+
// branch): inlineTableType emits this verbatim and the audit treats it as
|
|
1248
|
+
// recovered. Only ever set on a curation-authored field, with already-mapped
|
|
1249
|
+
// TS names — never from the parser — so it introduces no unmapped token.
|
|
1250
|
+
tsType?: string;
|
|
729
1251
|
}
|
|
730
1252
|
|
|
731
1253
|
function parseUlFields(doc: string): TableField[] {
|
|
@@ -1069,6 +1591,114 @@ export function emitDeclarations(module: ApiModule, options?: EmitOptions): stri
|
|
|
1069
1591
|
return `${lines.join("\n")}\n`;
|
|
1070
1592
|
}
|
|
1071
1593
|
|
|
1594
|
+
/** One emitted symbol's identity paired with its rendered TS signature text. */
|
|
1595
|
+
export interface SymbolSignature {
|
|
1596
|
+
readonly identity: ApiSymbolIdentity;
|
|
1597
|
+
readonly tsSignature: string;
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
/**
|
|
1601
|
+
* Render each emitted symbol's authoritative TS signature through the same
|
|
1602
|
+
* prepare/emit helpers {@link emitDeclarations} uses, keyed by the identity the
|
|
1603
|
+
* availability matrix joins on. This is the single declaration-backed source for
|
|
1604
|
+
* the shared `api-signatures.json` artifact: the same `mapType` (constant
|
|
1605
|
+
* branding) and table-doc resolver produce text that appears verbatim in the
|
|
1606
|
+
* committed `.d.ts`. The caller applies the same `skipFunctions` filter the
|
|
1607
|
+
* `.d.ts` generation does, so a dropped member never yields a signature.
|
|
1608
|
+
*/
|
|
1609
|
+
export function emitSymbolSignatures(module: ApiModule, options?: EmitOptions): SymbolSignature[] {
|
|
1610
|
+
const prefix = `${module.namespace}.`;
|
|
1611
|
+
const constantFqns = new Set(module.constants.map((c) => c.name));
|
|
1612
|
+
const knownConstantFqns = options?.knownConstantFqns;
|
|
1613
|
+
const baseMapType = options?.mapType ?? defaultMapType;
|
|
1614
|
+
const mapType = (token: string): string =>
|
|
1615
|
+
constantFqns.has(token) || knownConstantFqns?.has(token)
|
|
1616
|
+
? brandType(token)
|
|
1617
|
+
: baseMapType(token);
|
|
1618
|
+
const resolver = buildTableDocResolver(
|
|
1619
|
+
module.functions.map((fn) => ({
|
|
1620
|
+
name: fn.name,
|
|
1621
|
+
slots: [...fn.parameters, ...fn.returnValues],
|
|
1622
|
+
})),
|
|
1623
|
+
);
|
|
1624
|
+
|
|
1625
|
+
const out: SymbolSignature[] = [];
|
|
1626
|
+
const fnIdentity = (fn: ApiFunction): ApiSymbolIdentity => ({
|
|
1627
|
+
namespace: module.namespace,
|
|
1628
|
+
kind: "FUNCTION",
|
|
1629
|
+
name: fn.name,
|
|
1630
|
+
signature: normalizedFunctionSignature(fn),
|
|
1631
|
+
});
|
|
1632
|
+
const emitName = (name: string): string => (TS_RESERVED_NAMES.has(name) ? `_${name}` : name);
|
|
1633
|
+
|
|
1634
|
+
for (const fn of module.functions) {
|
|
1635
|
+
const prepared = prepareFunction(fn, prefix);
|
|
1636
|
+
if (prepared === null) continue;
|
|
1637
|
+
out.push({
|
|
1638
|
+
identity: fnIdentity(fn),
|
|
1639
|
+
tsSignature: emitFunction(prepared, emitName(prepared.name), mapType, resolver),
|
|
1640
|
+
});
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
const nestedFunctionLocal = /^[A-Za-z_$][\w$]*\.[A-Za-z_$][\w$]*$/;
|
|
1644
|
+
for (const fn of module.functions) {
|
|
1645
|
+
const local = stripPrefix(fn.name, prefix);
|
|
1646
|
+
if (!nestedFunctionLocal.test(local)) continue;
|
|
1647
|
+
const segment = local.slice(0, local.indexOf("."));
|
|
1648
|
+
const prepared = prepareFunction(fn, `${module.namespace}.${segment}.`);
|
|
1649
|
+
if (prepared === null) continue;
|
|
1650
|
+
out.push({
|
|
1651
|
+
identity: fnIdentity(fn),
|
|
1652
|
+
tsSignature: emitFunction(prepared, prepared.name, mapType, resolver),
|
|
1653
|
+
});
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
const handleGroups = collectHandleMethodGroups(module);
|
|
1657
|
+
for (const group of handleGroups.values()) {
|
|
1658
|
+
for (const prepared of group) {
|
|
1659
|
+
out.push({
|
|
1660
|
+
identity: fnIdentity(prepared.original),
|
|
1661
|
+
tsSignature: emitMethod(prepared, mapType, resolver),
|
|
1662
|
+
});
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
|
|
1666
|
+
for (const c of module.constants) {
|
|
1667
|
+
const prepared = prepareConstant(c, prefix);
|
|
1668
|
+
if (prepared === null) continue;
|
|
1669
|
+
out.push({
|
|
1670
|
+
identity: { namespace: module.namespace, kind: "CONSTANT", name: c.name, signature: "" },
|
|
1671
|
+
tsSignature: `const ${prepared.name}: ${brandType(prepared.fqn)};`,
|
|
1672
|
+
});
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
for (const v of module.variables) {
|
|
1676
|
+
const prepared = prepareVariable(v, prefix);
|
|
1677
|
+
if (prepared === null) continue;
|
|
1678
|
+
out.push({
|
|
1679
|
+
identity: { namespace: module.namespace, kind: "VARIABLE", name: v.name, signature: "" },
|
|
1680
|
+
tsSignature: emitVariable(prepared, emitName(prepared.name), mapType),
|
|
1681
|
+
});
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1684
|
+
for (const p of module.properties) {
|
|
1685
|
+
out.push({
|
|
1686
|
+
identity: { namespace: module.namespace, kind: "PROPERTY", name: p.name, signature: "" },
|
|
1687
|
+
tsSignature: emitPropertyMember(p, mapType),
|
|
1688
|
+
});
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1691
|
+
for (const t of module.typedefs) {
|
|
1692
|
+
if (!TS_IDENTIFIER.test(t.name) || handleGroups.has(t.name)) continue;
|
|
1693
|
+
out.push({
|
|
1694
|
+
identity: { namespace: module.namespace, kind: "TYPEDEF", name: t.name, signature: "" },
|
|
1695
|
+
tsSignature: `type ${t.name} = Opaque<"${t.name}">;`,
|
|
1696
|
+
});
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1699
|
+
return out;
|
|
1700
|
+
}
|
|
1701
|
+
|
|
1072
1702
|
interface PreparedConstant {
|
|
1073
1703
|
name: string;
|
|
1074
1704
|
fqn: string;
|
|
@@ -1403,10 +2033,24 @@ function mapSlotUnion(
|
|
|
1403
2033
|
} else if (curation?.kind === "object" || curation?.kind === "array-object") {
|
|
1404
2034
|
const object = inlineTableType(curation.fields, mapType, optionalFields);
|
|
1405
2035
|
ts = curation.kind === "array-object" ? `${object}[]` : object;
|
|
2036
|
+
} else if (curation?.kind === "keyed-object") {
|
|
2037
|
+
// The doc's `<dl>` describes the value shape; parse it and re-key by an
|
|
2038
|
+
// arbitrary name. Reusing the parser keeps the inner fields in lockstep
|
|
2039
|
+
// with the doc instead of a hand-listed drift-prone copy; a documented
|
|
2040
|
+
// array-form field is pinned via TABLE_FIELD_TYPE_OVERRIDES.
|
|
2041
|
+
const parsed = applyFieldTypeOverrides(
|
|
2042
|
+
elementName,
|
|
2043
|
+
slotKind,
|
|
2044
|
+
slotName,
|
|
2045
|
+
parseTableFields(doc, resolver) ?? [],
|
|
2046
|
+
);
|
|
2047
|
+
const object = inlineTableType(parsed, mapType, optionalFields);
|
|
2048
|
+
ts = `Record<string, ${object}>`;
|
|
1406
2049
|
} else {
|
|
1407
2050
|
const parsed = parseTableFields(doc, resolver);
|
|
1408
2051
|
if (parsed !== null) {
|
|
1409
|
-
const
|
|
2052
|
+
const nested = applyNestedFieldCurations(elementName, slotKind, slotName, parsed);
|
|
2053
|
+
const fields = applyFieldTypeOverrides(elementName, slotKind, slotName, nested);
|
|
1410
2054
|
const object = inlineTableType(fields, mapType, optionalFields);
|
|
1411
2055
|
ts = isSlotLevelList(doc) ? `${object}[]` : object;
|
|
1412
2056
|
} else {
|
|
@@ -1488,14 +2132,19 @@ export function inlineTableType(
|
|
|
1488
2132
|
// number-list field carries no member shape but a machine-readable numeric
|
|
1489
2133
|
// element type ("in the form {px0, …}"), so it emits `number[]`.
|
|
1490
2134
|
const ts =
|
|
1491
|
-
field.
|
|
1492
|
-
?
|
|
1493
|
-
: field.
|
|
1494
|
-
? "
|
|
1495
|
-
: field.
|
|
1496
|
-
?
|
|
1497
|
-
:
|
|
1498
|
-
|
|
2135
|
+
field.tsType !== undefined
|
|
2136
|
+
? field.tsType
|
|
2137
|
+
: field.fields !== undefined
|
|
2138
|
+
? `${inlineTableType(field.fields, mapType, optionalFields)}${field.isList ? "[]" : ""}`
|
|
2139
|
+
: field.numberList === true
|
|
2140
|
+
? "number[]"
|
|
2141
|
+
: field.types.length > 0
|
|
2142
|
+
? unionFromTokens(field.types, mapType)
|
|
2143
|
+
: "unknown";
|
|
2144
|
+
// A field is optional when the whole slot is param-side (optionalFields) or
|
|
2145
|
+
// when the curation marks that individual field optional (a return-side
|
|
2146
|
+
// variant field present only for some shape kinds, e.g. a b2d shape table).
|
|
2147
|
+
return `${key}${optionalFields || field.optional === true ? "?" : ""}: ${ts}`;
|
|
1499
2148
|
});
|
|
1500
2149
|
return `{ ${members.join("; ")} }`;
|
|
1501
2150
|
}
|
|
@@ -1512,6 +2161,14 @@ function unionFromTokens(tokens: readonly string[], mapType: (t: string) => stri
|
|
|
1512
2161
|
return mapped.join(" | ");
|
|
1513
2162
|
}
|
|
1514
2163
|
|
|
2164
|
+
export function isKnownDefoldTypeToken(token: string): boolean {
|
|
2165
|
+
return (
|
|
2166
|
+
token === "nil" ||
|
|
2167
|
+
Object.hasOwn(DEFOLD_TYPE_MAP, token) ||
|
|
2168
|
+
recoverCallbackSignature(token) !== null
|
|
2169
|
+
);
|
|
2170
|
+
}
|
|
2171
|
+
|
|
1515
2172
|
function defaultMapType(token: string): string {
|
|
1516
2173
|
if (Object.hasOwn(DEFOLD_TYPE_MAP, token)) {
|
|
1517
2174
|
const mapped = DEFOLD_TYPE_MAP[token];
|