@defold-typescript/types 0.48.0 → 0.50.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 +696 -624
- package/api-signatures.json +6799 -160
- package/api-targets.json +393 -2
- package/examples/translations.json +12 -0
- package/generated/b2d.d.ts +15 -0
- package/generated/bullet3d.d.ts +16 -0
- package/generated/font.d.ts +7 -3
- package/generated/graphics.d.ts +7 -0
- package/generated/gui.d.ts +5 -4
- package/generated/label.d.ts +3 -3
- package/generated/render.d.ts +16 -1
- package/generated/versions/defold-1.13.2/b2d.d.ts +709 -0
- package/generated/versions/defold-1.13.2/b2d_body.d.ts +593 -0
- package/generated/versions/defold-1.13.2/b2d_chain.d.ts +105 -0
- package/generated/versions/defold-1.13.2/b2d_fixture.d.ts +175 -0
- package/generated/versions/defold-1.13.2/b2d_joint.d.ts +1301 -0
- package/generated/versions/defold-1.13.2/b2d_shape.d.ts +423 -0
- package/generated/versions/defold-1.13.2/b2d_world.d.ts +308 -0
- package/generated/versions/defold-1.13.2/buffer.d.ts +192 -0
- package/generated/versions/defold-1.13.2/bullet3d.d.ts +91 -0
- package/generated/versions/defold-1.13.2/bullet3d_collision_object.d.ts +433 -0
- package/generated/versions/defold-1.13.2/bullet3d_constraint.d.ts +818 -0
- package/generated/versions/defold-1.13.2/bullet3d_rigid_body.d.ts +429 -0
- package/generated/versions/defold-1.13.2/bullet3d_shape.d.ts +123 -0
- package/generated/versions/defold-1.13.2/bullet3d_world.d.ts +492 -0
- package/generated/versions/defold-1.13.2/camera.d.ts +300 -0
- package/generated/versions/defold-1.13.2/collectionfactory.d.ts +148 -0
- package/generated/versions/defold-1.13.2/collectionproxy.d.ts +109 -0
- package/generated/versions/defold-1.13.2/compute.d.ts +107 -0
- package/generated/versions/defold-1.13.2/crash.d.ts +157 -0
- package/generated/versions/defold-1.13.2/editor-vm/http.d.ts +139 -0
- package/generated/versions/defold-1.13.2/editor-vm/image.d.ts +48 -0
- package/generated/versions/defold-1.13.2/editor-vm/json.d.ts +21 -0
- package/generated/versions/defold-1.13.2/editor-vm/localization.d.ts +42 -0
- package/generated/versions/defold-1.13.2/editor-vm/tilemap_tiles.d.ts +126 -0
- package/generated/versions/defold-1.13.2/editor-vm/zip.d.ts +38 -0
- package/generated/versions/defold-1.13.2/editor-vm/zlib.d.ts +24 -0
- package/generated/versions/defold-1.13.2/editor.d.ts +2177 -0
- package/generated/versions/defold-1.13.2/factory.d.ts +121 -0
- package/generated/versions/defold-1.13.2/font.d.ts +123 -0
- package/generated/versions/defold-1.13.2/go.d.ts +1166 -0
- package/generated/versions/defold-1.13.2/graphics.d.ts +613 -0
- package/generated/versions/defold-1.13.2/gui.d.ts +2212 -0
- package/generated/versions/defold-1.13.2/html5.d.ts +55 -0
- package/generated/versions/defold-1.13.2/http.d.ts +83 -0
- package/generated/versions/defold-1.13.2/image.d.ts +181 -0
- package/generated/versions/defold-1.13.2/index.d.ts +63 -0
- package/generated/versions/defold-1.13.2/json.d.ts +94 -0
- package/generated/versions/defold-1.13.2/kinds/editor-script.d.ts +14 -0
- package/generated/versions/defold-1.13.2/label.d.ts +164 -0
- package/generated/versions/defold-1.13.2/liveupdate.d.ts +143 -0
- package/generated/versions/defold-1.13.2/material.d.ts +490 -0
- package/generated/versions/defold-1.13.2/model.d.ts +287 -0
- package/generated/versions/defold-1.13.2/msg.d.ts +10 -0
- package/generated/versions/defold-1.13.2/particlefx.d.ts +155 -0
- package/generated/versions/defold-1.13.2/physics.d.ts +789 -0
- package/generated/versions/defold-1.13.2/profiler.d.ts +228 -0
- package/generated/versions/defold-1.13.2/render.d.ts +1153 -0
- package/generated/versions/defold-1.13.2/resource.d.ts +1628 -0
- package/generated/versions/defold-1.13.2/socket.d.ts +797 -0
- package/generated/versions/defold-1.13.2/sound.d.ts +323 -0
- package/generated/versions/defold-1.13.2/sprite.d.ts +179 -0
- package/generated/versions/defold-1.13.2/sys.d.ts +754 -0
- package/generated/versions/defold-1.13.2/tilemap.d.ts +206 -0
- package/generated/versions/defold-1.13.2/timer.d.ts +136 -0
- package/generated/versions/defold-1.13.2/types.d.ts +61 -0
- package/generated/versions/defold-1.13.2/vmath.d.ts +775 -0
- package/generated/versions/defold-1.13.2/window.d.ts +196 -0
- package/generated/versions/defold-1.13.2/zlib.d.ts +41 -0
- package/hsm/debug.d.ts +6 -3
- package/hsm/index.d.ts +309 -77
- package/identity-vocabulary.json +1 -0
- package/package.json +2 -2
- package/scripts/import-defold-release.ts +3 -31
- package/scripts/materialize-version.ts +13 -7
- package/scripts/regen.ts +63 -29
- package/scripts/sync-api-docs.ts +31 -2
- package/src/emit-dts.ts +25 -3
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
EDITOR_MANIFEST,
|
|
8
8
|
type ExtractedFixture,
|
|
9
9
|
extractAnnotationFixtures,
|
|
10
|
+
groupDocsByNamespace,
|
|
10
11
|
IGNORED_UPSTREAM,
|
|
11
12
|
mergeApiDocs,
|
|
12
13
|
readZip,
|
|
@@ -15,7 +16,6 @@ import {
|
|
|
15
16
|
} from "./sync-api-docs";
|
|
16
17
|
|
|
17
18
|
const EXACT_VERSION = /^\d+\.\d+\.\d+$/;
|
|
18
|
-
const LUA_NAMESPACE = /^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)*$/;
|
|
19
19
|
const DECLARED_NAME_KINDS = new Set(["CONSTANT", "ENUM", "STRUCT", "TYPEDEF", "CLASS"]);
|
|
20
20
|
const PACKAGE_ROOT = resolve(import.meta.dir, "..");
|
|
21
21
|
|
|
@@ -75,11 +75,6 @@ interface RawElement extends Record<string, unknown> {
|
|
|
75
75
|
name?: string;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
interface RawApiDoc extends Record<string, unknown> {
|
|
79
|
-
info?: { namespace?: string };
|
|
80
|
-
elements?: RawElement[];
|
|
81
|
-
}
|
|
82
|
-
|
|
83
78
|
export interface ReleaseBaselineModule {
|
|
84
79
|
readonly namespace: string;
|
|
85
80
|
readonly fixture: string;
|
|
@@ -177,20 +172,6 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|
|
177
172
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
178
173
|
}
|
|
179
174
|
|
|
180
|
-
function parsedDoc(raw: string): RawApiDoc | null {
|
|
181
|
-
try {
|
|
182
|
-
const value: unknown = JSON.parse(raw);
|
|
183
|
-
return isRecord(value) ? (value as RawApiDoc) : null;
|
|
184
|
-
} catch {
|
|
185
|
-
return null;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
function namespaceOf(doc: RawApiDoc): string | null {
|
|
190
|
-
const namespace = isRecord(doc.info) ? doc.info.namespace : undefined;
|
|
191
|
-
return typeof namespace === "string" && LUA_NAMESPACE.test(namespace) ? namespace : null;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
175
|
function elementsOf(doc: unknown): RawElement[] {
|
|
195
176
|
if (!isRecord(doc) || !Array.isArray(doc.elements)) return [];
|
|
196
177
|
return doc.elements.filter(isRecord) as RawElement[];
|
|
@@ -297,16 +278,7 @@ export function buildReleaseImportPlan(input: {
|
|
|
297
278
|
throw new Error(`expected an exact Defold release version, received '${input.version}'`);
|
|
298
279
|
}
|
|
299
280
|
|
|
300
|
-
const grouped =
|
|
301
|
-
for (const zipEntry of [...input.zip.entries()].sort()) {
|
|
302
|
-
const doc = parsedDoc(input.zip.read(zipEntry));
|
|
303
|
-
if (!doc) continue;
|
|
304
|
-
const namespace = namespaceOf(doc);
|
|
305
|
-
if (!namespace) continue;
|
|
306
|
-
const group = grouped.get(namespace) ?? [];
|
|
307
|
-
group.push({ entry: zipEntry, doc });
|
|
308
|
-
grouped.set(namespace, group);
|
|
309
|
-
}
|
|
281
|
+
const grouped = groupDocsByNamespace(input.zip);
|
|
310
282
|
|
|
311
283
|
const baselineModules = [...input.baseline.modules, ...input.baseline.luaStdlib];
|
|
312
284
|
const generatedNamespaces = new Set(input.baseline.modules.map((module) => module.namespace));
|
|
@@ -319,7 +291,7 @@ export function buildReleaseImportPlan(input: {
|
|
|
319
291
|
};
|
|
320
292
|
|
|
321
293
|
const sources: ReleaseSource[] = incomingNamespaces.map((namespace) => {
|
|
322
|
-
const group = grouped.get(namespace)
|
|
294
|
+
const group = grouped.get(namespace) ?? [];
|
|
323
295
|
return {
|
|
324
296
|
namespace,
|
|
325
297
|
entries: group.map(({ entry }) => entry).sort(),
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
loadSrcAugmentations,
|
|
12
12
|
loadTargetEditorModules,
|
|
13
13
|
MESSAGES_MANIFEST,
|
|
14
|
+
type ModuleManifestEntry,
|
|
14
15
|
type ResolveTargetOptions,
|
|
15
16
|
resolveTargetModules,
|
|
16
17
|
} from "./regen";
|
|
@@ -138,13 +139,18 @@ export async function buildVersionedSurfaceFiles(
|
|
|
138
139
|
opts.augmentations ?? loadSrcAugmentations(opts.resolveOpts?.packageRoot ?? undefined)
|
|
139
140
|
).filter((file) => kept(file.path));
|
|
140
141
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
142
|
+
// Re-rooting an entry makes it a new object no committed manifest holds, so
|
|
143
|
+
// each lane is handed to the emit as the surface it routes: a type one module
|
|
144
|
+
// declares for another, or names from another, resolves only across the set.
|
|
145
|
+
const rerooted = (entries: readonly ModuleManifestEntry[]): ModuleManifestEntry[] =>
|
|
146
|
+
entries.map((entry) => ({ ...entry, importsFrom: surfaceCoreTypesImport(entry.outFile) }));
|
|
147
|
+
const files: VersionedSurfaceFile[] = [rerooted(modules), rerooted(editorModules)].flatMap(
|
|
148
|
+
(surface) =>
|
|
149
|
+
surface.map((entry) => ({
|
|
150
|
+
path: entry.outFile,
|
|
151
|
+
contents: generateModuleDeclaration(entry, { surface }).contents,
|
|
152
|
+
})),
|
|
153
|
+
);
|
|
148
154
|
|
|
149
155
|
files.push(...augmentations);
|
|
150
156
|
files.push({ path: "core-types.d.ts", contents: CORE_TYPES_REEXPORT });
|
package/scripts/regen.ts
CHANGED
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
import { loadTranslations } from "./example-store-io";
|
|
43
43
|
import { synthesizeProseConstants } from "./prose-constants";
|
|
44
44
|
import { restoreSharedHandleMethods } from "./shared-handle-methods";
|
|
45
|
-
import {
|
|
45
|
+
import { groupDocsByNamespace, mergeApiDocs, type readZip } from "./sync-api-docs";
|
|
46
46
|
|
|
47
47
|
export interface ApiTargetModule {
|
|
48
48
|
readonly namespace: string;
|
|
@@ -120,6 +120,12 @@ function withSkipRules(entry: ModuleManifestEntry, module: ApiTargetModule): Mod
|
|
|
120
120
|
};
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
// Shared by both module sources: a step applied in one branch alone gives a
|
|
124
|
+
// ref-doc surface different members from a committed one.
|
|
125
|
+
function restoreOmittedMembers(modules: readonly ModuleManifestEntry[]): ModuleManifestEntry[] {
|
|
126
|
+
return restoreSharedHandleMethods(synthesizeProseConstants(modules));
|
|
127
|
+
}
|
|
128
|
+
|
|
123
129
|
export function loadTargetModules(
|
|
124
130
|
target: ApiTarget,
|
|
125
131
|
packageRoot: string = PACKAGE_ROOT,
|
|
@@ -142,7 +148,7 @@ export function loadTargetModules(
|
|
|
142
148
|
};
|
|
143
149
|
return withSkipRules(entry, module);
|
|
144
150
|
});
|
|
145
|
-
return
|
|
151
|
+
return restoreOmittedMembers(modules);
|
|
146
152
|
}
|
|
147
153
|
|
|
148
154
|
export interface ModuleManifestEntry {
|
|
@@ -174,7 +180,6 @@ export interface ResolveTargetOptions {
|
|
|
174
180
|
readonly cacheDir?: string;
|
|
175
181
|
readonly download?: DownloadRefDoc;
|
|
176
182
|
readonly readZip?: typeof readZip;
|
|
177
|
-
readonly syncManifest?: readonly SyncManifestEntry[];
|
|
178
183
|
readonly packageRoot?: string;
|
|
179
184
|
readonly channel?: RefDocChannel;
|
|
180
185
|
readonly fetchChannelInfo?: FetchChannelInfo;
|
|
@@ -182,8 +187,8 @@ export interface ResolveTargetOptions {
|
|
|
182
187
|
|
|
183
188
|
// Source-aware module resolution: a `null`-source target reads committed
|
|
184
189
|
// fixtures from disk (delegates to loadTargetModules); a `ref-doc` target
|
|
185
|
-
// resolves its docs on demand from the version's ref-doc zip,
|
|
186
|
-
//
|
|
190
|
+
// resolves its docs on demand from the version's ref-doc zip, reading every
|
|
191
|
+
// doc the zip declares for the namespace, merged.
|
|
187
192
|
export async function resolveTargetModules(
|
|
188
193
|
target: ApiTarget,
|
|
189
194
|
opts: ResolveTargetOptions = {},
|
|
@@ -200,24 +205,24 @@ export async function resolveTargetModules(
|
|
|
200
205
|
...(opts.readZip ? { readZip: opts.readZip } : {}),
|
|
201
206
|
...(opts.fetchChannelInfo ? { fetchChannelInfo: opts.fetchChannelInfo } : {}),
|
|
202
207
|
});
|
|
203
|
-
const
|
|
208
|
+
const grouped = groupDocsByNamespace(zip);
|
|
204
209
|
const modules = target.modules.map((module) => {
|
|
205
|
-
const
|
|
206
|
-
if (!
|
|
210
|
+
const group = grouped.get(module.namespace);
|
|
211
|
+
if (!group) {
|
|
207
212
|
throw new Error(
|
|
208
|
-
`api-targets.json: target "${target.id}" module "${module.namespace}": no
|
|
213
|
+
`api-targets.json: target "${target.id}" module "${module.namespace}": no doc in the ref-doc zip declares this namespace`,
|
|
209
214
|
);
|
|
210
215
|
}
|
|
211
216
|
const entry: ModuleManifestEntry = {
|
|
212
217
|
namespace: module.namespace,
|
|
213
|
-
doc:
|
|
218
|
+
doc: mergeApiDocs(group.map((item) => item.doc)),
|
|
214
219
|
outFile: module.outFile,
|
|
215
220
|
importsFrom: target.coreTypesImport,
|
|
216
221
|
sourceProvenance: provenance,
|
|
217
222
|
};
|
|
218
223
|
return withSkipRules(entry, module);
|
|
219
224
|
});
|
|
220
|
-
return
|
|
225
|
+
return restoreOmittedMembers(modules);
|
|
221
226
|
}
|
|
222
227
|
|
|
223
228
|
const API_TARGETS = loadApiTargets();
|
|
@@ -451,6 +456,10 @@ export interface GenerateOptions {
|
|
|
451
456
|
translations?: TranslationStore;
|
|
452
457
|
urlParameters?: UrlParameterTable;
|
|
453
458
|
registeredConstants?: ReadonlySet<string>;
|
|
459
|
+
// The modules the entry is emitted beside, the entry among them. Routing
|
|
460
|
+
// reads this set instead of looking the entry up in a committed manifest, so
|
|
461
|
+
// a surface built with its own import root still routes as a whole.
|
|
462
|
+
surface?: readonly ModuleManifestEntry[];
|
|
454
463
|
}
|
|
455
464
|
|
|
456
465
|
interface PreparedGeneratedModule {
|
|
@@ -472,7 +481,7 @@ function prepareGeneratedModule(
|
|
|
472
481
|
entry: ModuleManifestEntry,
|
|
473
482
|
options?: GenerateOptions,
|
|
474
483
|
): PreparedGeneratedModule {
|
|
475
|
-
const routed = routedModuleOf(entry);
|
|
484
|
+
const routed = routedModuleOf(entry, options?.surface);
|
|
476
485
|
const { module, dropped } = routed?.prepared ?? withheldApiModule(entry);
|
|
477
486
|
const knownConstantFqns = options?.knownConstantFqns ?? collectConstantFqns();
|
|
478
487
|
const translations = options?.translations ?? loadTranslations();
|
|
@@ -495,36 +504,61 @@ interface RoutedSurface {
|
|
|
495
504
|
}
|
|
496
505
|
|
|
497
506
|
const routedSurfaces = new Map<string, RoutedSurface>();
|
|
507
|
+
const routedCallerSurfaces = new WeakMap<readonly ModuleManifestEntry[], RoutedSurface>();
|
|
508
|
+
|
|
509
|
+
function routeSurface(entries: readonly ModuleManifestEntry[]): RoutedSurface {
|
|
510
|
+
const withheld = entries.map(withheldApiModule);
|
|
511
|
+
const routed = routeTypeDeclarations(withheld.map(({ module }) => module));
|
|
512
|
+
return {
|
|
513
|
+
modules: new Map(
|
|
514
|
+
entries.map((member, index) => [
|
|
515
|
+
member,
|
|
516
|
+
{
|
|
517
|
+
module: routed[index] as ApiModule,
|
|
518
|
+
dropped: (withheld[index] as { dropped: string[] }).dropped,
|
|
519
|
+
},
|
|
520
|
+
]),
|
|
521
|
+
),
|
|
522
|
+
declaredTypes: declaredTypePaths(routed),
|
|
523
|
+
};
|
|
524
|
+
}
|
|
498
525
|
|
|
499
526
|
// A doc may declare a type another module owns (`b2d.joint.revolute_definition`
|
|
500
527
|
// in the `b2d` doc) or name one another doc declares (`material.constant_info`
|
|
501
528
|
// 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.
|
|
503
|
-
//
|
|
504
|
-
|
|
529
|
+
// modules and the editor modules of one target, never across targets. A caller
|
|
530
|
+
// that names its own surface routes that set instead. An entry with neither, and
|
|
531
|
+
// outside every committed manifest, routes alone, as a single-module surface.
|
|
532
|
+
function routedModuleOf(
|
|
533
|
+
entry: ModuleManifestEntry,
|
|
534
|
+
callerSurface?: readonly ModuleManifestEntry[],
|
|
535
|
+
):
|
|
505
536
|
| {
|
|
506
537
|
prepared: { module: ApiModule; dropped: string[] };
|
|
507
538
|
declaredTypes: ReadonlyMap<string, string>;
|
|
508
539
|
}
|
|
509
540
|
| undefined {
|
|
541
|
+
if (callerSurface !== undefined) {
|
|
542
|
+
let surface = routedCallerSurfaces.get(callerSurface);
|
|
543
|
+
if (surface === undefined) {
|
|
544
|
+
surface = routeSurface(callerSurface);
|
|
545
|
+
routedCallerSurfaces.set(callerSurface, surface);
|
|
546
|
+
}
|
|
547
|
+
const prepared = surface.modules.get(entry);
|
|
548
|
+
// Falling back to a lone module here would emit `unknown` for every type a
|
|
549
|
+
// sibling declares, which type-checks and so goes unnoticed.
|
|
550
|
+
if (prepared === undefined) {
|
|
551
|
+
throw new Error(
|
|
552
|
+
`module "${entry.namespace}" is not a member of the surface it is emitted in`,
|
|
553
|
+
);
|
|
554
|
+
}
|
|
555
|
+
return { prepared, declaredTypes: surface.declaredTypes };
|
|
556
|
+
}
|
|
510
557
|
const located = committedSurfaceOf(entry);
|
|
511
558
|
if (located === undefined) return undefined;
|
|
512
559
|
let surface = routedSurfaces.get(located.key);
|
|
513
560
|
if (surface === undefined) {
|
|
514
|
-
|
|
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
|
-
};
|
|
561
|
+
surface = routeSurface(located.entries);
|
|
528
562
|
routedSurfaces.set(located.key, surface);
|
|
529
563
|
}
|
|
530
564
|
const prepared = surface.modules.get(located.member);
|
package/scripts/sync-api-docs.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { MODULE_MANIFEST } from "./regen";
|
|
|
11
11
|
// model because the per-package `rootDir` boundary forbids a types-package
|
|
12
12
|
// module importing outside its own tree; `scripts/release-model.test.ts`
|
|
13
13
|
// correspondence-guards these against the model so drift fails CI.
|
|
14
|
-
export const DEFOLD_VERSION = "1.
|
|
14
|
+
export const DEFOLD_VERSION = "1.14.0";
|
|
15
15
|
export const refDocUrl = (version = DEFOLD_VERSION): string =>
|
|
16
16
|
`https://github.com/defold/defold/releases/download/${version}/ref-doc.zip`;
|
|
17
17
|
|
|
@@ -216,7 +216,7 @@ function editorVm(namespace: string): SyncManifestEntry {
|
|
|
216
216
|
function entry(
|
|
217
217
|
namespace: string,
|
|
218
218
|
zipEntry: string,
|
|
219
|
-
fixture: string = `fixtures/defold-1.
|
|
219
|
+
fixture: string = `fixtures/defold-1.14.0/${namespace.replace(/\./g, "_")}_doc.json`,
|
|
220
220
|
mergeEntries?: readonly string[],
|
|
221
221
|
): SyncManifestEntry {
|
|
222
222
|
return { namespace, zipEntry, fixture, ...(mergeEntries ? { mergeEntries } : {}) };
|
|
@@ -538,6 +538,35 @@ export interface CoverageInput {
|
|
|
538
538
|
ignoredUpstream?: ReadonlyMap<string, string>;
|
|
539
539
|
}
|
|
540
540
|
|
|
541
|
+
// The Lua docs of a zip, grouped by the namespace each one declares. Entry names
|
|
542
|
+
// belong to one release (`label` is one entry in 1.9.8 and two in 1.14.0), so
|
|
543
|
+
// the declared namespace picks the docs. Entries are read in sorted order
|
|
544
|
+
// because `mergeApiDocs` keeps the first doc's `info` and the docs' element
|
|
545
|
+
// order; only `.json` entries are read because each read of a real zip is one
|
|
546
|
+
// `unzip -p` process.
|
|
547
|
+
export function groupDocsByNamespace(
|
|
548
|
+
zip: ZipAccessor,
|
|
549
|
+
): Map<string, { entry: string; doc: Record<string, unknown> }[]> {
|
|
550
|
+
const grouped = new Map<string, { entry: string; doc: Record<string, unknown> }[]>();
|
|
551
|
+
for (const entry of [...zip.entries()].sort()) {
|
|
552
|
+
if (!entry.endsWith(".json")) continue;
|
|
553
|
+
const raw = zip.read(entry);
|
|
554
|
+
let doc: unknown;
|
|
555
|
+
try {
|
|
556
|
+
doc = JSON.parse(raw);
|
|
557
|
+
} catch {
|
|
558
|
+
continue;
|
|
559
|
+
}
|
|
560
|
+
if (!isRecord(doc)) continue;
|
|
561
|
+
const namespace = isRecord(doc.info) ? doc.info.namespace : undefined;
|
|
562
|
+
if (typeof namespace !== "string" || !LUA_NAMESPACE.test(namespace)) continue;
|
|
563
|
+
const group = grouped.get(namespace) ?? [];
|
|
564
|
+
group.push({ entry, doc });
|
|
565
|
+
grouped.set(namespace, group);
|
|
566
|
+
}
|
|
567
|
+
return grouped;
|
|
568
|
+
}
|
|
569
|
+
|
|
541
570
|
// Enumerate every `doc/*.json` zip entry, reading its `info.namespace` and the
|
|
542
571
|
// count of FUNCTION elements. Only function-bearing docs are returned, so
|
|
543
572
|
// message-only / struct-only docs never reach the coverage guard.
|
package/src/emit-dts.ts
CHANGED
|
@@ -5639,6 +5639,27 @@ function unionFromTokens(tokens: readonly string[], mapType: DefoldTypeMapper):
|
|
|
5639
5639
|
}
|
|
5640
5640
|
|
|
5641
5641
|
const BRAND_ARM = /^(?:number|string) & \{ readonly __brand: "([^"]+)" \}$/;
|
|
5642
|
+
const OPAQUE_ARM = /^Opaque<("[^"]+"(?: \| "[^"]+")*)>$/;
|
|
5643
|
+
|
|
5644
|
+
// Drops each `Opaque` arm whose brands are a proper subset of another `Opaque`
|
|
5645
|
+
// arm's. `Opaque<Name>` holds `Name` in one readonly property, so a narrower
|
|
5646
|
+
// brand set is assignable to a wider one and the narrower arm adds nothing.
|
|
5647
|
+
// An arm of any other shape (`Opaque<"x">[]`, an intersection) is never dropped
|
|
5648
|
+
// and never causes a drop.
|
|
5649
|
+
function withoutSubsumedOpaqueArms(mapped: readonly string[]): string[] {
|
|
5650
|
+
const brandSets = mapped.map((arm) => {
|
|
5651
|
+
const match = OPAQUE_ARM.exec(arm);
|
|
5652
|
+
return match === null ? undefined : new Set((match[1] as string).split(" | "));
|
|
5653
|
+
});
|
|
5654
|
+
return mapped.filter((_, index) => {
|
|
5655
|
+
const own = brandSets[index];
|
|
5656
|
+
if (own === undefined) return true;
|
|
5657
|
+
return !brandSets.some(
|
|
5658
|
+
(other) =>
|
|
5659
|
+
other !== undefined && other.size > own.size && [...own].every((b) => other.has(b)),
|
|
5660
|
+
);
|
|
5661
|
+
});
|
|
5662
|
+
}
|
|
5642
5663
|
|
|
5643
5664
|
// Joins already-mapped arms, collapsing the branded ones to their alias when
|
|
5644
5665
|
// they are exactly a `CONSTANT_UNION_ALIASES` member set. The alias takes the
|
|
@@ -5646,16 +5667,17 @@ const BRAND_ARM = /^(?:number|string) & \{ readonly __brand: "([^"]+)" \}$/;
|
|
|
5646
5667
|
// (`gui.Easing | Vector`). Arms that are not constants are untouched, and a set
|
|
5647
5668
|
// with no row keeps every arm inline.
|
|
5648
5669
|
function joinUnionArms(mapped: readonly string[]): string {
|
|
5670
|
+
const arms = withoutSubsumedOpaqueArms(mapped);
|
|
5649
5671
|
const branded: string[] = [];
|
|
5650
|
-
for (const arm of
|
|
5672
|
+
for (const arm of arms) {
|
|
5651
5673
|
const match = BRAND_ARM.exec(arm);
|
|
5652
5674
|
if (match !== null) branded.push(match[1] as string);
|
|
5653
5675
|
}
|
|
5654
5676
|
const alias = constantUnionAlias(branded);
|
|
5655
|
-
if (alias === undefined) return
|
|
5677
|
+
if (alias === undefined) return arms.join(" | ");
|
|
5656
5678
|
const out: string[] = [];
|
|
5657
5679
|
let placed = false;
|
|
5658
|
-
for (const arm of
|
|
5680
|
+
for (const arm of arms) {
|
|
5659
5681
|
if (BRAND_ARM.test(arm)) {
|
|
5660
5682
|
if (placed) continue;
|
|
5661
5683
|
out.push(`${alias.home}.${alias.name}`);
|