@defold-typescript/types 0.1.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-targets.json +84 -0
- package/generated/b2d.d.ts +13 -0
- package/generated/buffer.d.ts +25 -0
- package/generated/builtin-messages.d.ts +42 -0
- package/generated/camera.d.ts +7 -0
- package/generated/collectionfactory.d.ts +17 -0
- package/generated/collectionproxy.d.ts +14 -0
- package/generated/crash.d.ts +31 -0
- package/generated/factory.d.ts +17 -0
- package/generated/go.d.ts +96 -0
- package/generated/graphics.d.ts +115 -0
- package/generated/gui.d.ts +245 -0
- package/generated/http.d.ts +8 -0
- package/generated/iac.d.ts +8 -0
- package/generated/iap.d.ts +16 -0
- package/generated/image.d.ts +16 -0
- package/generated/json.d.ts +11 -0
- package/generated/kinds/gui-script.d.ts +39 -0
- package/generated/kinds/render-script.d.ts +39 -0
- package/generated/kinds/script.d.ts +38 -0
- package/generated/label.d.ts +23 -0
- package/generated/liveupdate.d.ts +23 -0
- package/generated/model.d.ts +23 -0
- package/generated/msg.d.ts +12 -0
- package/generated/particlefx.d.ts +22 -0
- package/generated/physics.d.ts +47 -0
- package/generated/profiler.d.ts +28 -0
- package/generated/push.d.ts +15 -0
- package/generated/render.d.ts +55 -0
- package/generated/resource.d.ts +33 -0
- package/generated/socket.d.ts +25 -0
- package/generated/sound.d.ts +28 -0
- package/generated/sprite.d.ts +23 -0
- package/generated/sys.d.ts +37 -0
- package/generated/tilemap.d.ts +24 -0
- package/generated/timer.d.ts +12 -0
- package/generated/vmath.d.ts +63 -0
- package/generated/webview.d.ts +15 -0
- package/generated/window.d.ts +28 -0
- package/generated/zlib.d.ts +9 -0
- package/index.d.ts +63 -0
- package/package.json +46 -0
- package/scripts/doc-source.ts +100 -0
- package/scripts/fidelity-audit.ts +311 -0
- package/scripts/fidelity-baseline.json +282 -0
- package/scripts/materialize-version.ts +51 -0
- package/scripts/regen.ts +294 -0
- package/scripts/sync-api-docs.ts +375 -0
- package/src/api-doc.ts +168 -0
- package/src/core-types.ts +121 -0
- package/src/emit-dts.ts +754 -0
- package/src/emit-messages.ts +148 -0
- package/src/go-overloads.d.ts +35 -0
- package/src/index.ts +24 -0
- package/src/lifecycle.ts +81 -0
- package/src/msg-overloads.d.ts +21 -0
- package/src/publish-dts.ts +33 -0
- package/src/script-api.ts +95 -0
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { DEFOLD_TYPE_MAP } from "../src/core-types";
|
|
3
|
+
import {
|
|
4
|
+
ARBITRARY_TABLE_SLOTS,
|
|
5
|
+
buildTableDocResolver,
|
|
6
|
+
HOMOGENEOUS_ARRAY_SLOTS,
|
|
7
|
+
MAPPING_TABLE_SLOTS,
|
|
8
|
+
parseTableFields,
|
|
9
|
+
recoverCallbackSignature,
|
|
10
|
+
TS_IDENTIFIER,
|
|
11
|
+
} from "../src/emit-dts";
|
|
12
|
+
import { parseMessagesDoc } from "../src/emit-messages";
|
|
13
|
+
import {
|
|
14
|
+
collectConstantFqns,
|
|
15
|
+
generateModuleDeclaration,
|
|
16
|
+
MESSAGES_MANIFEST,
|
|
17
|
+
MODULE_MANIFEST,
|
|
18
|
+
type ModuleManifestEntry,
|
|
19
|
+
} from "./regen";
|
|
20
|
+
|
|
21
|
+
const NO_KNOWN_CONSTANTS: ReadonlySet<string> = new Set();
|
|
22
|
+
|
|
23
|
+
// These message names are typed by builtin-messages-typing's separate surface
|
|
24
|
+
// (BuiltinMessages), so a fixture `MESSAGE` element of the same name is not a
|
|
25
|
+
// namespace-API loss — it is reclassified out of droppedElements below.
|
|
26
|
+
const BUILTIN_MESSAGE_NAMES: ReadonlySet<string> = new Set(
|
|
27
|
+
parseMessagesDoc(MESSAGES_MANIFEST.doc).entries.map((e) => e.name),
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
export interface FidelityEntry {
|
|
31
|
+
droppedElements: number;
|
|
32
|
+
unknownTokens: string[];
|
|
33
|
+
recordTables: number;
|
|
34
|
+
multiReturn: number;
|
|
35
|
+
droppedMembers: number;
|
|
36
|
+
optionalAsRequired: number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
40
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function elementsOf(doc: unknown): Record<string, unknown>[] {
|
|
44
|
+
if (!isRecord(doc) || !Array.isArray(doc.elements)) return [];
|
|
45
|
+
return doc.elements.filter(isRecord);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function stringArray(raw: unknown): string[] {
|
|
49
|
+
return Array.isArray(raw) ? raw.filter((item): item is string => typeof item === "string") : [];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function paramList(raw: unknown): Record<string, unknown>[] {
|
|
53
|
+
return Array.isArray(raw) ? raw.filter(isRecord) : [];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function docString(raw: unknown): string | undefined {
|
|
57
|
+
return typeof raw === "string" ? raw : undefined;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function isDocOptional(param: Record<string, unknown>): boolean {
|
|
61
|
+
return param.is_optional === "True" || stringArray(param.types).includes("nil");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function trailingOptionalCutoff(params: readonly Record<string, unknown>[]): number {
|
|
65
|
+
let cutoff = params.length;
|
|
66
|
+
for (let i = params.length - 1; i >= 0; i -= 1) {
|
|
67
|
+
const p = params[i];
|
|
68
|
+
if (p && isDocOptional(p)) cutoff = i;
|
|
69
|
+
else break;
|
|
70
|
+
}
|
|
71
|
+
return cutoff;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function auditEntry(
|
|
75
|
+
entry: ModuleManifestEntry,
|
|
76
|
+
knownConstantFqns: ReadonlySet<string>,
|
|
77
|
+
): FidelityEntry {
|
|
78
|
+
const skipFunctions = new Set(entry.skipFunctions ?? []);
|
|
79
|
+
const elements = elementsOf(entry.doc);
|
|
80
|
+
|
|
81
|
+
let droppedElements = 0;
|
|
82
|
+
let recordTables = 0;
|
|
83
|
+
// multiReturn is fully recovered: emitReturn emits LuaMultiReturn<[...]> for
|
|
84
|
+
// every >1-return function, so no documented multi-return is a loss anymore.
|
|
85
|
+
const multiReturn = 0;
|
|
86
|
+
let optionalAsRequired = 0;
|
|
87
|
+
const unknown = new Set<string>();
|
|
88
|
+
|
|
89
|
+
const constantFqns = new Set<string>();
|
|
90
|
+
for (const element of elements) {
|
|
91
|
+
if (element.type === "CONSTANT" && typeof element.name === "string") {
|
|
92
|
+
constantFqns.add(element.name);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Same module-scoped resolver the emitter builds, so a cross-reference table
|
|
97
|
+
// slot is recovered (not counted under recordTables) in lockstep with the
|
|
98
|
+
// emitted surface.
|
|
99
|
+
const resolver = buildTableDocResolver(
|
|
100
|
+
elements
|
|
101
|
+
.filter((element) => element.type === "FUNCTION" && typeof element.name === "string")
|
|
102
|
+
.map((element) => ({
|
|
103
|
+
name: element.name as string,
|
|
104
|
+
slots: [...paramList(element.parameters), ...paramList(element.returnvalues)].map(
|
|
105
|
+
(slot) => ({ types: stringArray(slot.types), doc: docString(slot.doc) ?? "" }),
|
|
106
|
+
),
|
|
107
|
+
})),
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
const considerTypes = (
|
|
111
|
+
types: readonly string[],
|
|
112
|
+
doc?: string,
|
|
113
|
+
arbitraryTable = false,
|
|
114
|
+
mappingSlot?: { key: string; value: string },
|
|
115
|
+
homogeneousElement?: string | readonly string[],
|
|
116
|
+
) => {
|
|
117
|
+
for (const token of types) {
|
|
118
|
+
// A `table` slot whose doc carries a parseable `<dl>` field list is
|
|
119
|
+
// recovered by emit-dts into an inline object type, so it no longer
|
|
120
|
+
// collapses to `Record`: don't count it under recordTables. Instead feed
|
|
121
|
+
// each recovered field's types back through considerTypes so an unmapped
|
|
122
|
+
// field token still surfaces under unknownTokens and a nested `table`
|
|
123
|
+
// field (no doc → not recovered) still counts under recordTables. This
|
|
124
|
+
// keeps the invariant that every loss in the emitted surface is measured.
|
|
125
|
+
if (token === "table") {
|
|
126
|
+
// A mapping-table slot is recovered by emit-dts into `LuaMap<K, V>` from
|
|
127
|
+
// the curated key/value tokens — not a `Record`, so don't count it.
|
|
128
|
+
// Feed the curated tokens back through considerTypes so an unmapped one
|
|
129
|
+
// still surfaces under unknownTokens (none today: hash/node/vector3 map).
|
|
130
|
+
if (mappingSlot !== undefined) {
|
|
131
|
+
considerTypes([mappingSlot.key, mappingSlot.value]);
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
// A homogeneous-array slot is recovered by emit-dts into `T[]` (or a
|
|
135
|
+
// `(A | B)[]` union element) from the curated element token(s) — not a
|
|
136
|
+
// `Record`, so don't count it. Feed the curated token(s) back through
|
|
137
|
+
// considerTypes so an unmapped one still surfaces under unknownTokens
|
|
138
|
+
// (none today: number/hash/string/url map).
|
|
139
|
+
if (homogeneousElement !== undefined) {
|
|
140
|
+
considerTypes(
|
|
141
|
+
typeof homogeneousElement === "string" ? [homogeneousElement] : homogeneousElement,
|
|
142
|
+
);
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const fields = doc !== undefined ? parseTableFields(doc, resolver) : null;
|
|
146
|
+
if (fields !== null) {
|
|
147
|
+
// A recovered field carrying nested fields (the mixed `<dl>`+`<ul>`
|
|
148
|
+
// shape) emits a nested object, not a `Record` — recurse into the
|
|
149
|
+
// nested field types instead of counting the nested `table`.
|
|
150
|
+
for (const field of fields) {
|
|
151
|
+
if (field.fields !== undefined) {
|
|
152
|
+
for (const nested of field.fields) considerTypes(nested.types);
|
|
153
|
+
} else if (field.numberList === true) {
|
|
154
|
+
// Recovered as `number[]` by inlineTableType — no longer a
|
|
155
|
+
// `Record`, so skip it. Re-counting its `table` token here would
|
|
156
|
+
// double-count a slot the emitted surface no longer loses.
|
|
157
|
+
} else {
|
|
158
|
+
considerTypes(field.types);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
// A slot on a serialization/JSON passthrough function is a genuinely
|
|
164
|
+
// arbitrary lua table — its emitted `Record<string | number, unknown>`
|
|
165
|
+
// is faithful, not a loss — so it is not counted under recordTables.
|
|
166
|
+
if (arbitraryTable) continue;
|
|
167
|
+
recordTables += 1;
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
// `nil` is the optional-parameter sentinel (emitParameter strips it), not a
|
|
171
|
+
// real Defold type the mapper fails to resolve — the optionalAsRequired
|
|
172
|
+
// category covers that loss instead. Constant FQNs defined in this module
|
|
173
|
+
// (constantFqns) or in any other manifest module (knownConstantFqns) now
|
|
174
|
+
// resolve to their brand type, and `function(...)` callback signatures
|
|
175
|
+
// recover to typed functions, so none is an unknown token.
|
|
176
|
+
if (
|
|
177
|
+
token !== "nil" &&
|
|
178
|
+
!Object.hasOwn(DEFOLD_TYPE_MAP, token) &&
|
|
179
|
+
!constantFqns.has(token) &&
|
|
180
|
+
!knownConstantFqns.has(token) &&
|
|
181
|
+
recoverCallbackSignature(token) === null
|
|
182
|
+
) {
|
|
183
|
+
unknown.add(token);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
for (const element of elements) {
|
|
189
|
+
const type = element.type;
|
|
190
|
+
// An identifier-named TYPEDEF is recovered into a per-namespace
|
|
191
|
+
// `type <name> = Opaque<"<name>">` alias, under the same TS_IDENTIFIER guard
|
|
192
|
+
// the emitter uses, so the gate and the emitted surface agree. A
|
|
193
|
+
// non-identifier TYPEDEF cannot become an alias and stays dropped.
|
|
194
|
+
if (
|
|
195
|
+
type === "TYPEDEF" &&
|
|
196
|
+
typeof element.name === "string" &&
|
|
197
|
+
TS_IDENTIFIER.test(element.name)
|
|
198
|
+
) {
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
// A MESSAGE element whose name is in the builtin-messages catalog is a
|
|
202
|
+
// built-in message owned by builtin-messages-typing, not a namespace-API
|
|
203
|
+
// member — counting it here double-counts a surface that is fully typed
|
|
204
|
+
// elsewhere. A MESSAGE name absent from the catalog falls through to the
|
|
205
|
+
// catch-all and still counts, so the gate stays honest.
|
|
206
|
+
if (
|
|
207
|
+
type === "MESSAGE" &&
|
|
208
|
+
typeof element.name === "string" &&
|
|
209
|
+
BUILTIN_MESSAGE_NAMES.has(element.name)
|
|
210
|
+
) {
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (type !== "FUNCTION" && type !== "VARIABLE" && type !== "CONSTANT" && type !== "PROPERTY") {
|
|
214
|
+
droppedElements += 1;
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
// PROPERTY is recovered into the per-namespace `interface properties` block;
|
|
218
|
+
// its name+type survive, so it is no longer a dropped element.
|
|
219
|
+
if (type === "CONSTANT" || type === "PROPERTY") continue;
|
|
220
|
+
if (type === "VARIABLE") {
|
|
221
|
+
considerTypes(stringArray(element.types));
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
// Skipped functions are measured as droppedMembers only; counting their
|
|
225
|
+
// params/returns here would double-count losses covered by hand-written d.ts.
|
|
226
|
+
if (typeof element.name === "string" && skipFunctions.has(stripNamespace(element.name))) {
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
const params = paramList(element.parameters);
|
|
230
|
+
const returns = paramList(element.returnvalues);
|
|
231
|
+
const cutoff = trailingOptionalCutoff(params);
|
|
232
|
+
const arbitraryTable =
|
|
233
|
+
typeof element.name === "string" && ARBITRARY_TABLE_SLOTS.has(element.name);
|
|
234
|
+
const mappingSlot =
|
|
235
|
+
typeof element.name === "string" ? MAPPING_TABLE_SLOTS.get(element.name) : undefined;
|
|
236
|
+
const homogeneousElement =
|
|
237
|
+
typeof element.name === "string" ? HOMOGENEOUS_ARRAY_SLOTS.get(element.name) : undefined;
|
|
238
|
+
params.forEach((param, index) => {
|
|
239
|
+
considerTypes(
|
|
240
|
+
stringArray(param.types),
|
|
241
|
+
docString(param.doc),
|
|
242
|
+
arbitraryTable,
|
|
243
|
+
mappingSlot,
|
|
244
|
+
homogeneousElement,
|
|
245
|
+
);
|
|
246
|
+
// Residual: a doc-optional param the emitter cannot mark `?` because a
|
|
247
|
+
// required param follows it. The trailing-run cutoff must match
|
|
248
|
+
// emit-dts so the gate and the emitted surface agree.
|
|
249
|
+
if (isDocOptional(param) && index < cutoff) optionalAsRequired += 1;
|
|
250
|
+
});
|
|
251
|
+
for (const ret of returns)
|
|
252
|
+
considerTypes(
|
|
253
|
+
stringArray(ret.types),
|
|
254
|
+
docString(ret.doc),
|
|
255
|
+
arbitraryTable,
|
|
256
|
+
mappingSlot,
|
|
257
|
+
homogeneousElement,
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return {
|
|
262
|
+
droppedElements,
|
|
263
|
+
unknownTokens: [...unknown].sort(),
|
|
264
|
+
recordTables,
|
|
265
|
+
multiReturn,
|
|
266
|
+
droppedMembers: generateModuleDeclaration(entry, { knownConstantFqns: NO_KNOWN_CONSTANTS })
|
|
267
|
+
.dropped.length,
|
|
268
|
+
optionalAsRequired,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function stripNamespace(name: string): string {
|
|
273
|
+
const index = name.lastIndexOf(".");
|
|
274
|
+
return index === -1 ? name : name.slice(index + 1);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export function buildFidelityReport(
|
|
278
|
+
manifest: readonly ModuleManifestEntry[] = MODULE_MANIFEST,
|
|
279
|
+
): Record<string, FidelityEntry> {
|
|
280
|
+
const report: Record<string, FidelityEntry> = {};
|
|
281
|
+
const knownConstantFqns = collectConstantFqns(manifest);
|
|
282
|
+
for (const namespace of [...manifest.map((e) => e.namespace)].sort()) {
|
|
283
|
+
const entry = manifest.find((e) => e.namespace === namespace);
|
|
284
|
+
if (entry) report[namespace] = auditEntry(entry, knownConstantFqns);
|
|
285
|
+
}
|
|
286
|
+
return report;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function biomeFormatJson(raw: string): string {
|
|
290
|
+
const out = Bun.spawnSync(
|
|
291
|
+
["bunx", "biome", "format", "--stdin-file-path=fidelity-baseline.json"],
|
|
292
|
+
{
|
|
293
|
+
stdin: Buffer.from(raw),
|
|
294
|
+
},
|
|
295
|
+
);
|
|
296
|
+
if (out.exitCode !== 0) {
|
|
297
|
+
throw new Error(`biome format failed: ${out.stderr.toString()}`);
|
|
298
|
+
}
|
|
299
|
+
return out.stdout.toString();
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (import.meta.main) {
|
|
303
|
+
const report = buildFidelityReport();
|
|
304
|
+
if (process.argv.includes("--write")) {
|
|
305
|
+
const path = resolve(import.meta.dir, "fidelity-baseline.json");
|
|
306
|
+
Bun.write(path, biomeFormatJson(JSON.stringify(report)));
|
|
307
|
+
console.log(`wrote ${path}`);
|
|
308
|
+
} else {
|
|
309
|
+
console.log(JSON.stringify(report, null, 2));
|
|
310
|
+
}
|
|
311
|
+
}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
{
|
|
2
|
+
"b2d": {
|
|
3
|
+
"droppedElements": 0,
|
|
4
|
+
"unknownTokens": [],
|
|
5
|
+
"recordTables": 0,
|
|
6
|
+
"multiReturn": 0,
|
|
7
|
+
"droppedMembers": 0,
|
|
8
|
+
"optionalAsRequired": 0
|
|
9
|
+
},
|
|
10
|
+
"buffer": {
|
|
11
|
+
"droppedElements": 0,
|
|
12
|
+
"unknownTokens": [],
|
|
13
|
+
"recordTables": 0,
|
|
14
|
+
"multiReturn": 0,
|
|
15
|
+
"droppedMembers": 0,
|
|
16
|
+
"optionalAsRequired": 0
|
|
17
|
+
},
|
|
18
|
+
"camera": {
|
|
19
|
+
"droppedElements": 0,
|
|
20
|
+
"unknownTokens": [],
|
|
21
|
+
"recordTables": 0,
|
|
22
|
+
"multiReturn": 0,
|
|
23
|
+
"droppedMembers": 0,
|
|
24
|
+
"optionalAsRequired": 0
|
|
25
|
+
},
|
|
26
|
+
"collectionfactory": {
|
|
27
|
+
"droppedElements": 0,
|
|
28
|
+
"unknownTokens": [],
|
|
29
|
+
"recordTables": 2,
|
|
30
|
+
"multiReturn": 0,
|
|
31
|
+
"droppedMembers": 0,
|
|
32
|
+
"optionalAsRequired": 0
|
|
33
|
+
},
|
|
34
|
+
"collectionproxy": {
|
|
35
|
+
"droppedElements": 0,
|
|
36
|
+
"unknownTokens": [],
|
|
37
|
+
"recordTables": 1,
|
|
38
|
+
"multiReturn": 0,
|
|
39
|
+
"droppedMembers": 0,
|
|
40
|
+
"optionalAsRequired": 0
|
|
41
|
+
},
|
|
42
|
+
"crash": {
|
|
43
|
+
"droppedElements": 0,
|
|
44
|
+
"unknownTokens": [],
|
|
45
|
+
"recordTables": 2,
|
|
46
|
+
"multiReturn": 0,
|
|
47
|
+
"droppedMembers": 0,
|
|
48
|
+
"optionalAsRequired": 0
|
|
49
|
+
},
|
|
50
|
+
"factory": {
|
|
51
|
+
"droppedElements": 0,
|
|
52
|
+
"unknownTokens": [],
|
|
53
|
+
"recordTables": 1,
|
|
54
|
+
"multiReturn": 0,
|
|
55
|
+
"droppedMembers": 0,
|
|
56
|
+
"optionalAsRequired": 0
|
|
57
|
+
},
|
|
58
|
+
"go": {
|
|
59
|
+
"droppedElements": 0,
|
|
60
|
+
"unknownTokens": [],
|
|
61
|
+
"recordTables": 2,
|
|
62
|
+
"multiReturn": 0,
|
|
63
|
+
"droppedMembers": 2,
|
|
64
|
+
"optionalAsRequired": 0
|
|
65
|
+
},
|
|
66
|
+
"graphics": {
|
|
67
|
+
"droppedElements": 0,
|
|
68
|
+
"unknownTokens": [],
|
|
69
|
+
"recordTables": 0,
|
|
70
|
+
"multiReturn": 0,
|
|
71
|
+
"droppedMembers": 0,
|
|
72
|
+
"optionalAsRequired": 0
|
|
73
|
+
},
|
|
74
|
+
"gui": {
|
|
75
|
+
"droppedElements": 0,
|
|
76
|
+
"unknownTokens": [],
|
|
77
|
+
"recordTables": 2,
|
|
78
|
+
"multiReturn": 0,
|
|
79
|
+
"droppedMembers": 0,
|
|
80
|
+
"optionalAsRequired": 0
|
|
81
|
+
},
|
|
82
|
+
"http": {
|
|
83
|
+
"droppedElements": 0,
|
|
84
|
+
"unknownTokens": [],
|
|
85
|
+
"recordTables": 1,
|
|
86
|
+
"multiReturn": 0,
|
|
87
|
+
"droppedMembers": 0,
|
|
88
|
+
"optionalAsRequired": 0
|
|
89
|
+
},
|
|
90
|
+
"iac": {
|
|
91
|
+
"droppedElements": 0,
|
|
92
|
+
"unknownTokens": [],
|
|
93
|
+
"recordTables": 1,
|
|
94
|
+
"multiReturn": 0,
|
|
95
|
+
"droppedMembers": 0,
|
|
96
|
+
"optionalAsRequired": 0
|
|
97
|
+
},
|
|
98
|
+
"iap": {
|
|
99
|
+
"droppedElements": 0,
|
|
100
|
+
"unknownTokens": [],
|
|
101
|
+
"recordTables": 3,
|
|
102
|
+
"multiReturn": 0,
|
|
103
|
+
"droppedMembers": 0,
|
|
104
|
+
"optionalAsRequired": 0
|
|
105
|
+
},
|
|
106
|
+
"image": {
|
|
107
|
+
"droppedElements": 0,
|
|
108
|
+
"unknownTokens": [],
|
|
109
|
+
"recordTables": 0,
|
|
110
|
+
"multiReturn": 0,
|
|
111
|
+
"droppedMembers": 0,
|
|
112
|
+
"optionalAsRequired": 0
|
|
113
|
+
},
|
|
114
|
+
"json": {
|
|
115
|
+
"droppedElements": 0,
|
|
116
|
+
"unknownTokens": [],
|
|
117
|
+
"recordTables": 0,
|
|
118
|
+
"multiReturn": 0,
|
|
119
|
+
"droppedMembers": 0,
|
|
120
|
+
"optionalAsRequired": 0
|
|
121
|
+
},
|
|
122
|
+
"label": {
|
|
123
|
+
"droppedElements": 0,
|
|
124
|
+
"unknownTokens": [],
|
|
125
|
+
"recordTables": 0,
|
|
126
|
+
"multiReturn": 0,
|
|
127
|
+
"droppedMembers": 0,
|
|
128
|
+
"optionalAsRequired": 0
|
|
129
|
+
},
|
|
130
|
+
"liveupdate": {
|
|
131
|
+
"droppedElements": 0,
|
|
132
|
+
"unknownTokens": [],
|
|
133
|
+
"recordTables": 1,
|
|
134
|
+
"multiReturn": 0,
|
|
135
|
+
"droppedMembers": 0,
|
|
136
|
+
"optionalAsRequired": 0
|
|
137
|
+
},
|
|
138
|
+
"model": {
|
|
139
|
+
"droppedElements": 0,
|
|
140
|
+
"unknownTokens": [],
|
|
141
|
+
"recordTables": 2,
|
|
142
|
+
"multiReturn": 0,
|
|
143
|
+
"droppedMembers": 0,
|
|
144
|
+
"optionalAsRequired": 0
|
|
145
|
+
},
|
|
146
|
+
"msg": {
|
|
147
|
+
"droppedElements": 0,
|
|
148
|
+
"unknownTokens": [],
|
|
149
|
+
"recordTables": 0,
|
|
150
|
+
"multiReturn": 0,
|
|
151
|
+
"droppedMembers": 1,
|
|
152
|
+
"optionalAsRequired": 0
|
|
153
|
+
},
|
|
154
|
+
"particlefx": {
|
|
155
|
+
"droppedElements": 0,
|
|
156
|
+
"unknownTokens": [],
|
|
157
|
+
"recordTables": 0,
|
|
158
|
+
"multiReturn": 0,
|
|
159
|
+
"droppedMembers": 0,
|
|
160
|
+
"optionalAsRequired": 0
|
|
161
|
+
},
|
|
162
|
+
"physics": {
|
|
163
|
+
"droppedElements": 0,
|
|
164
|
+
"unknownTokens": [],
|
|
165
|
+
"recordTables": 5,
|
|
166
|
+
"multiReturn": 0,
|
|
167
|
+
"droppedMembers": 0,
|
|
168
|
+
"optionalAsRequired": 0
|
|
169
|
+
},
|
|
170
|
+
"profiler": {
|
|
171
|
+
"droppedElements": 0,
|
|
172
|
+
"unknownTokens": [],
|
|
173
|
+
"recordTables": 1,
|
|
174
|
+
"multiReturn": 0,
|
|
175
|
+
"droppedMembers": 0,
|
|
176
|
+
"optionalAsRequired": 0
|
|
177
|
+
},
|
|
178
|
+
"push": {
|
|
179
|
+
"droppedElements": 0,
|
|
180
|
+
"unknownTokens": [],
|
|
181
|
+
"recordTables": 4,
|
|
182
|
+
"multiReturn": 0,
|
|
183
|
+
"droppedMembers": 0,
|
|
184
|
+
"optionalAsRequired": 0
|
|
185
|
+
},
|
|
186
|
+
"render": {
|
|
187
|
+
"droppedElements": 0,
|
|
188
|
+
"unknownTokens": [],
|
|
189
|
+
"recordTables": 4,
|
|
190
|
+
"multiReturn": 0,
|
|
191
|
+
"droppedMembers": 0,
|
|
192
|
+
"optionalAsRequired": 0
|
|
193
|
+
},
|
|
194
|
+
"resource": {
|
|
195
|
+
"droppedElements": 0,
|
|
196
|
+
"unknownTokens": [],
|
|
197
|
+
"recordTables": 3,
|
|
198
|
+
"multiReturn": 0,
|
|
199
|
+
"droppedMembers": 0,
|
|
200
|
+
"optionalAsRequired": 0
|
|
201
|
+
},
|
|
202
|
+
"socket": {
|
|
203
|
+
"droppedElements": 0,
|
|
204
|
+
"unknownTokens": [],
|
|
205
|
+
"recordTables": 8,
|
|
206
|
+
"multiReturn": 0,
|
|
207
|
+
"droppedMembers": 0,
|
|
208
|
+
"optionalAsRequired": 0
|
|
209
|
+
},
|
|
210
|
+
"sound": {
|
|
211
|
+
"droppedElements": 0,
|
|
212
|
+
"unknownTokens": [],
|
|
213
|
+
"recordTables": 0,
|
|
214
|
+
"multiReturn": 0,
|
|
215
|
+
"droppedMembers": 0,
|
|
216
|
+
"optionalAsRequired": 0
|
|
217
|
+
},
|
|
218
|
+
"sprite": {
|
|
219
|
+
"droppedElements": 0,
|
|
220
|
+
"unknownTokens": [],
|
|
221
|
+
"recordTables": 0,
|
|
222
|
+
"multiReturn": 0,
|
|
223
|
+
"droppedMembers": 0,
|
|
224
|
+
"optionalAsRequired": 0
|
|
225
|
+
},
|
|
226
|
+
"sys": {
|
|
227
|
+
"droppedElements": 0,
|
|
228
|
+
"unknownTokens": [],
|
|
229
|
+
"recordTables": 0,
|
|
230
|
+
"multiReturn": 0,
|
|
231
|
+
"droppedMembers": 0,
|
|
232
|
+
"optionalAsRequired": 0
|
|
233
|
+
},
|
|
234
|
+
"tilemap": {
|
|
235
|
+
"droppedElements": 0,
|
|
236
|
+
"unknownTokens": [],
|
|
237
|
+
"recordTables": 2,
|
|
238
|
+
"multiReturn": 0,
|
|
239
|
+
"droppedMembers": 0,
|
|
240
|
+
"optionalAsRequired": 0
|
|
241
|
+
},
|
|
242
|
+
"timer": {
|
|
243
|
+
"droppedElements": 0,
|
|
244
|
+
"unknownTokens": [],
|
|
245
|
+
"recordTables": 0,
|
|
246
|
+
"multiReturn": 0,
|
|
247
|
+
"droppedMembers": 0,
|
|
248
|
+
"optionalAsRequired": 0
|
|
249
|
+
},
|
|
250
|
+
"vmath": {
|
|
251
|
+
"droppedElements": 0,
|
|
252
|
+
"unknownTokens": [],
|
|
253
|
+
"recordTables": 0,
|
|
254
|
+
"multiReturn": 0,
|
|
255
|
+
"droppedMembers": 0,
|
|
256
|
+
"optionalAsRequired": 0
|
|
257
|
+
},
|
|
258
|
+
"webview": {
|
|
259
|
+
"droppedElements": 0,
|
|
260
|
+
"unknownTokens": [],
|
|
261
|
+
"recordTables": 1,
|
|
262
|
+
"multiReturn": 0,
|
|
263
|
+
"droppedMembers": 0,
|
|
264
|
+
"optionalAsRequired": 0
|
|
265
|
+
},
|
|
266
|
+
"window": {
|
|
267
|
+
"droppedElements": 0,
|
|
268
|
+
"unknownTokens": [],
|
|
269
|
+
"recordTables": 0,
|
|
270
|
+
"multiReturn": 0,
|
|
271
|
+
"droppedMembers": 0,
|
|
272
|
+
"optionalAsRequired": 0
|
|
273
|
+
},
|
|
274
|
+
"zlib": {
|
|
275
|
+
"droppedElements": 0,
|
|
276
|
+
"unknownTokens": [],
|
|
277
|
+
"recordTables": 0,
|
|
278
|
+
"multiReturn": 0,
|
|
279
|
+
"droppedMembers": 0,
|
|
280
|
+
"optionalAsRequired": 0
|
|
281
|
+
}
|
|
282
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import {
|
|
4
|
+
type ApiTarget,
|
|
5
|
+
generateModuleDeclaration,
|
|
6
|
+
generateVersionIndex,
|
|
7
|
+
type ResolveTargetOptions,
|
|
8
|
+
resolveTargetModules,
|
|
9
|
+
} from "./regen";
|
|
10
|
+
|
|
11
|
+
export interface MaterializeVersionedSurfaceOptions {
|
|
12
|
+
readonly destDir: string;
|
|
13
|
+
readonly resolveOpts?: ResolveTargetOptions;
|
|
14
|
+
// Bare module names (no `.d.ts`) to omit from the surface — both the emitted
|
|
15
|
+
// file and its aggregate-index import. Lets a caller narrow the surface to a
|
|
16
|
+
// script kind without the generator knowing what a script kind is.
|
|
17
|
+
readonly excludeModules?: readonly string[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Generate a versioned surface on the fly into a project-local faux `@types`
|
|
21
|
+
// package: resolve the target's module docs (ref-doc or committed fixture),
|
|
22
|
+
// emit each module declaration, then write the aggregate side-effect entrypoint
|
|
23
|
+
// and a minimal package.json. ref-doc targets are never pre-baked, so this is
|
|
24
|
+
// the only path that turns a resolved version into a consumable type surface.
|
|
25
|
+
export async function materializeVersionedSurface(
|
|
26
|
+
target: ApiTarget,
|
|
27
|
+
opts: MaterializeVersionedSurfaceOptions,
|
|
28
|
+
): Promise<void> {
|
|
29
|
+
const exclude = new Set(opts.excludeModules ?? []);
|
|
30
|
+
const modules = (await resolveTargetModules(target, opts.resolveOpts ?? {})).filter(
|
|
31
|
+
(entry) => !exclude.has(entry.outFile.replace(/\.d\.ts$/, "")),
|
|
32
|
+
);
|
|
33
|
+
mkdirSync(opts.destDir, { recursive: true });
|
|
34
|
+
|
|
35
|
+
for (const entry of modules) {
|
|
36
|
+
const { contents } = generateModuleDeclaration(entry);
|
|
37
|
+
writeFileSync(resolve(opts.destDir, entry.outFile), contents);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const versioned = modules.map((entry) => ({ ...entry, versionId: target.id }));
|
|
41
|
+
writeFileSync(resolve(opts.destDir, "index.d.ts"), generateVersionIndex(target.id, versioned));
|
|
42
|
+
|
|
43
|
+
writeFileSync(
|
|
44
|
+
resolve(opts.destDir, "package.json"),
|
|
45
|
+
`${JSON.stringify(
|
|
46
|
+
{ name: `@defold-typescript/materialized-${target.id}`, types: "index.d.ts" },
|
|
47
|
+
null,
|
|
48
|
+
2,
|
|
49
|
+
)}\n`,
|
|
50
|
+
);
|
|
51
|
+
}
|