@defold-typescript/library-types 0.21.1 → 0.23.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-doc/{bridge.bridge.json → bridge.json} +749 -844
- package/api-doc/decore.json +22 -22
- package/api-doc/druid.json +195 -1790
- package/api-doc/event.json +1074 -0
- package/api-doc/immutable.json +65 -0
- package/api-doc/lang.json +528 -0
- package/api-doc/{event.event.json → log.json} +96 -101
- package/api-doc/narrator.json +647 -0
- package/api-doc/proto.json +995 -0
- package/api-doc/saver.saver.json +713 -263
- package/api-doc/saver.storage.json +282 -52
- package/api-doc/squid.json +846 -0
- package/api-doc/tweener.json +277 -0
- package/generated/bridge.d.ts +468 -0
- package/generated/decore.d.ts +36 -36
- package/generated/druid.d.ts +137 -443
- package/generated/event.d.ts +318 -0
- package/generated/immutable.d.ts +13 -0
- package/generated/lang.d.ts +101 -0
- package/generated/log.d.ts +36 -0
- package/generated/narrator.d.ts +121 -0
- package/generated/proto.d.ts +146 -0
- package/generated/saver.saver.d.ts +287 -42
- package/generated/saver.storage.d.ts +77 -14
- package/generated/squid.d.ts +127 -0
- package/generated/tweener.d.ts +42 -0
- package/library-classification.json +0 -71
- package/library-targets.json +0 -66
- package/luals-targets.json +114 -0
- package/package.json +4 -33
- package/script-api-targets.json +15 -0
- package/scripts/__snapshots__/parse-luals.test.ts.snap +340 -75
- package/scripts/apply-luals-overrides.ts +63 -0
- package/scripts/emit-library-dts.ts +84 -3
- package/scripts/lower-api-doc.ts +48 -16
- package/scripts/luals-fidelity.ts +7 -0
- package/scripts/map-luals-types.ts +34 -1
- package/scripts/parse-luals.ts +423 -18
- package/scripts/sync-luals-types.ts +15 -1
- package/scripts/sync-script-api-types.ts +368 -0
- package/api-doc/immutable.immutable.json +0 -63
- package/api-doc/lang.lang.json +0 -411
- package/api-doc/log.log.json +0 -50
- package/api-doc/narrator.narrator.json +0 -150
- package/api-doc/proto.proto.json +0 -355
- package/api-doc/squid.squid.json +0 -660
- package/api-doc/tweener.tweener.json +0 -419
- package/generated/bridge.bridge.d.ts +0 -533
- package/generated/event.event.d.ts +0 -54
- package/generated/immutable.immutable.d.ts +0 -13
- package/generated/lang.lang.d.ts +0 -33
- package/generated/log.log.d.ts +0 -40
- package/generated/narrator.narrator.d.ts +0 -66
- package/generated/proto.proto.d.ts +0 -36
- package/generated/squid.squid.d.ts +0 -106
- package/generated/tweener.tweener.d.ts +0 -151
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import type { FidelityReport } from "./luals-fidelity";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The script_api ingestion front-end: a third `library-types` corpus mode beside
|
|
7
|
+
* the ts-defold codemod (`sync-library-types.ts`) and the LuaLS front-end
|
|
8
|
+
* (`sync-luals-types.ts`). It ingests a library's own committed `.script_api`
|
|
9
|
+
* snapshot and routes it through the *shared ref-doc emitter* — the exact path
|
|
10
|
+
* the four built-in extensions and the resolve-time extension path use — rather
|
|
11
|
+
* than the LuaLS `emitLibraryDeclarations` (which consumes a `LibraryModel`).
|
|
12
|
+
*
|
|
13
|
+
* Each target pins its exact output paths. Like the LuaLS libraries, a migrated
|
|
14
|
+
* script_api library is the sole maintainer of its namespace, so its goldens are
|
|
15
|
+
* named for the single-segment `namespace` (`generated/bridge.d.ts`,
|
|
16
|
+
* `api-doc/bridge.json`, `fidelity/bridge.json`) at the canonical roots — not the
|
|
17
|
+
* dotted `moduleId` — keeping the docs tree and file layout uniform with druid.
|
|
18
|
+
*/
|
|
19
|
+
export interface ScriptApiTarget {
|
|
20
|
+
repo: string;
|
|
21
|
+
ref: string;
|
|
22
|
+
scriptApi: string;
|
|
23
|
+
moduleId: string;
|
|
24
|
+
namespace: string;
|
|
25
|
+
generated: string;
|
|
26
|
+
apiDoc: string;
|
|
27
|
+
// Defaults to `fidelity/<namespace>.json` when omitted.
|
|
28
|
+
fidelity: string;
|
|
29
|
+
// SPDX-style license id, surfaced by the docs-site provenance block. Optional
|
|
30
|
+
// in the config; defaults to "".
|
|
31
|
+
license?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface ScriptApiTargets {
|
|
35
|
+
targets: ScriptApiTarget[];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const REQUIRED_FIELDS = [
|
|
39
|
+
"repo",
|
|
40
|
+
"ref",
|
|
41
|
+
"scriptApi",
|
|
42
|
+
"moduleId",
|
|
43
|
+
"namespace",
|
|
44
|
+
"generated",
|
|
45
|
+
"apiDoc",
|
|
46
|
+
] as const;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Read `script-api-targets.json`, validate every required field per entry, and
|
|
50
|
+
* fill optional defaults (`fidelity` → `fidelity/<namespace>.json`,
|
|
51
|
+
* `license` → ""). Throws on the first missing field naming both the field and
|
|
52
|
+
* the offending entry (its `moduleId`, or its index when `moduleId` itself is
|
|
53
|
+
* absent) — the loud-fail discipline `readLualsTargets` uses. No network.
|
|
54
|
+
*/
|
|
55
|
+
export function readScriptApiTargets(packageRoot: string): ScriptApiTarget[] {
|
|
56
|
+
const parsed = JSON.parse(readFileSync(join(packageRoot, "script-api-targets.json"), "utf8")) as {
|
|
57
|
+
targets: Partial<ScriptApiTarget>[];
|
|
58
|
+
};
|
|
59
|
+
return parsed.targets.map((entry, index) => {
|
|
60
|
+
const label = typeof entry.moduleId === "string" ? entry.moduleId : `index ${index}`;
|
|
61
|
+
for (const field of REQUIRED_FIELDS) {
|
|
62
|
+
if (entry[field] === undefined) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
`script-api-targets.json: entry ${label} is missing required field "${field}".`,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const moduleId = entry.moduleId as string;
|
|
69
|
+
return {
|
|
70
|
+
repo: entry.repo as string,
|
|
71
|
+
ref: entry.ref as string,
|
|
72
|
+
scriptApi: entry.scriptApi as string,
|
|
73
|
+
moduleId,
|
|
74
|
+
namespace: entry.namespace as string,
|
|
75
|
+
generated: entry.generated as string,
|
|
76
|
+
apiDoc: entry.apiDoc as string,
|
|
77
|
+
fidelity: entry.fidelity ?? `fidelity/${entry.namespace as string}.json`,
|
|
78
|
+
license: entry.license ?? "",
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Fetch the raw text at a URL. Network seam — mirrors `sync-luals-types.ts`. */
|
|
84
|
+
export type FetchText = (url: string) => Promise<string>;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* A GitHub repo URL reduced to the bare `<owner>/<repo>` slug used to address
|
|
88
|
+
* raw content. Mirrors `repoSlug` in the LuaLS front-end.
|
|
89
|
+
*/
|
|
90
|
+
function repoSlug(repo: string): string {
|
|
91
|
+
return repo
|
|
92
|
+
.replace(/^https:\/\/github\.com\//, "")
|
|
93
|
+
.replace(/\.git$/, "")
|
|
94
|
+
.replace(/\/$/, "");
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function rawUrl(target: ScriptApiTarget): string {
|
|
98
|
+
return `https://raw.githubusercontent.com/${repoSlug(target.repo)}/${target.ref}/${target.scriptApi}`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function fixturePath(packageRoot: string, target: ScriptApiTarget): string {
|
|
102
|
+
return join(packageRoot, "fixtures/script-api", `${target.moduleId}.script_api`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Snapshot the pinned `.script_api` into `fixtures/script-api/<moduleId>.script_api`
|
|
107
|
+
* via the raw-content URL. Snapshot only — no codemod. The `fetchText` seam keeps
|
|
108
|
+
* the pass offline-testable; only the CLI `--fetch` arm wires the real network.
|
|
109
|
+
*/
|
|
110
|
+
export async function fetchScriptApiFixture(
|
|
111
|
+
packageRoot: string,
|
|
112
|
+
target: ScriptApiTarget,
|
|
113
|
+
seams: { fetchText: FetchText },
|
|
114
|
+
): Promise<void> {
|
|
115
|
+
const text = await seams.fetchText(rawUrl(target));
|
|
116
|
+
const dest = fixturePath(packageRoot, target);
|
|
117
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
118
|
+
writeFileSync(dest, text);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** A single ref-doc `doc` type slot — a parameter or a return value. */
|
|
122
|
+
export interface ScriptApiDocSlot {
|
|
123
|
+
types: string[];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface ScriptApiDocElement {
|
|
127
|
+
type: string;
|
|
128
|
+
name: string;
|
|
129
|
+
description: string;
|
|
130
|
+
parameters: ScriptApiDocSlot[];
|
|
131
|
+
returnvalues: ScriptApiDocSlot[];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** The core ref-doc JSON shape `scriptApiToFixtureJson` produces. */
|
|
135
|
+
export interface ScriptApiDoc {
|
|
136
|
+
info: { namespace: string };
|
|
137
|
+
elements: ScriptApiDocElement[];
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Reports whether a single ref-doc type token maps to a real TS type. */
|
|
141
|
+
export interface TypeResolver {
|
|
142
|
+
resolves(token: string): boolean;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
interface SyncApiDocsModule {
|
|
146
|
+
scriptApiToFixtureJson: (text: string) => string;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
interface RegenModule {
|
|
150
|
+
generateModuleDeclaration: (entry: {
|
|
151
|
+
namespace: string;
|
|
152
|
+
doc: unknown;
|
|
153
|
+
outFile: string;
|
|
154
|
+
importsFrom?: string;
|
|
155
|
+
moduleId?: string;
|
|
156
|
+
}) => { contents: string; dropped: string[] };
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
interface EmitDtsModule {
|
|
160
|
+
recoverCallbackSignature: (token: string) => string | null;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
interface CoreTypesModule {
|
|
164
|
+
DEFOLD_TYPE_MAP: Readonly<Record<string, string>>;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
interface TypesModules {
|
|
168
|
+
scriptApiToFixtureJson: (text: string) => string;
|
|
169
|
+
generateModuleDeclaration: RegenModule["generateModuleDeclaration"];
|
|
170
|
+
resolver: TypeResolver;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// bridge references no branded engine handle, so `generateModuleDeclaration`
|
|
174
|
+
// emits no core-types import and this value never reaches the golden; it mirrors
|
|
175
|
+
// the built-in extensions' import for the day a script_api target does reference
|
|
176
|
+
// one.
|
|
177
|
+
const SCRIPT_API_CORE_TYPES_IMPORT = "../src/core-types";
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Load the shared ref-doc emitter and the emitter's own type-mapping surface from
|
|
181
|
+
* the sibling `@defold-typescript/types` package by resolved path, mirroring
|
|
182
|
+
* `extension-emit.ts`'s `loadEmitter`: `scriptApiToFixtureJson` (YAML -> ref-doc
|
|
183
|
+
* JSON) and `generateModuleDeclaration` live in the types package's `scripts/`,
|
|
184
|
+
* `recoverCallbackSignature`/`DEFOLD_TYPE_MAP` in its `src/`. This is a repo-only
|
|
185
|
+
* build script (never shipped), so the sibling `../types` path is sufficient.
|
|
186
|
+
*
|
|
187
|
+
* A token resolves iff it is in `DEFOLD_TYPE_MAP` or `recoverCallbackSignature`
|
|
188
|
+
* recognizes it — the exact non-`unknown` predicate `defaultMapType` applies,
|
|
189
|
+
* so fidelity mirrors the emitter's real output (a `string | nil` union, absent
|
|
190
|
+
* from the map, renders `unknown` and counts as an unknown fallback).
|
|
191
|
+
*/
|
|
192
|
+
async function loadTypesModules(packageRoot: string): Promise<TypesModules> {
|
|
193
|
+
const typesRoot = join(packageRoot, "..", "types");
|
|
194
|
+
const sync = (await import(join(typesRoot, "scripts", "sync-api-docs.ts"))) as SyncApiDocsModule;
|
|
195
|
+
const regen = (await import(join(typesRoot, "scripts", "regen.ts"))) as RegenModule;
|
|
196
|
+
const emitDts = (await import(join(typesRoot, "src", "emit-dts.ts"))) as EmitDtsModule;
|
|
197
|
+
const core = (await import(join(typesRoot, "src", "core-types.ts"))) as CoreTypesModule;
|
|
198
|
+
const resolver: TypeResolver = {
|
|
199
|
+
resolves: (token) =>
|
|
200
|
+
Object.hasOwn(core.DEFOLD_TYPE_MAP, token) ||
|
|
201
|
+
emitDts.recoverCallbackSignature(token) !== null,
|
|
202
|
+
};
|
|
203
|
+
return {
|
|
204
|
+
scriptApiToFixtureJson: sync.scriptApiToFixtureJson,
|
|
205
|
+
generateModuleDeclaration: regen.generateModuleDeclaration,
|
|
206
|
+
resolver,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/** The emitter's type-mapping predicate, isolated for direct assertion. */
|
|
211
|
+
export async function loadTypeResolver(packageRoot: string): Promise<TypeResolver> {
|
|
212
|
+
return (await loadTypesModules(packageRoot)).resolver;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function parseFixtureDoc(
|
|
216
|
+
packageRoot: string,
|
|
217
|
+
target: ScriptApiTarget,
|
|
218
|
+
scriptApiToFixtureJson: (text: string) => string,
|
|
219
|
+
): ScriptApiDoc {
|
|
220
|
+
const text = readFileSync(fixturePath(packageRoot, target), "utf8");
|
|
221
|
+
return JSON.parse(scriptApiToFixtureJson(text)) as ScriptApiDoc;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* `.script_api` -> `scriptApiToFixtureJson` -> `generateModuleDeclaration`. Returns
|
|
226
|
+
* an importable module keyed by `moduleId` (`declare module '<moduleId>'`), with
|
|
227
|
+
* one-level nested sub-namespaces intact per the nested-namespace parser slice.
|
|
228
|
+
*/
|
|
229
|
+
export async function emitScriptApiDeclaration(
|
|
230
|
+
packageRoot: string,
|
|
231
|
+
target: ScriptApiTarget,
|
|
232
|
+
): Promise<string> {
|
|
233
|
+
const { scriptApiToFixtureJson, generateModuleDeclaration } = await loadTypesModules(packageRoot);
|
|
234
|
+
const doc = parseFixtureDoc(packageRoot, target, scriptApiToFixtureJson);
|
|
235
|
+
const { contents } = generateModuleDeclaration({
|
|
236
|
+
namespace: target.namespace,
|
|
237
|
+
doc,
|
|
238
|
+
outFile: `${target.moduleId}.d.ts`,
|
|
239
|
+
importsFrom: SCRIPT_API_CORE_TYPES_IMPORT,
|
|
240
|
+
moduleId: target.moduleId,
|
|
241
|
+
});
|
|
242
|
+
return contents;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* The api-doc golden is the parsed ref-doc `doc` itself, pretty-printed — the same
|
|
247
|
+
* `{ info, elements }` shape the built-in extensions' `<ns>_doc.json` fixtures
|
|
248
|
+
* feed the docs-site through `parseDefoldApiDoc`, so the shape stays uniform.
|
|
249
|
+
*/
|
|
250
|
+
export async function lowerScriptApiApiDoc(
|
|
251
|
+
packageRoot: string,
|
|
252
|
+
target: ScriptApiTarget,
|
|
253
|
+
): Promise<string> {
|
|
254
|
+
const { scriptApiToFixtureJson } = await loadTypesModules(packageRoot);
|
|
255
|
+
const doc = parseFixtureDoc(packageRoot, target, scriptApiToFixtureJson);
|
|
256
|
+
return `${JSON.stringify(doc, null, 2)}\n`;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function round3(value: number): number {
|
|
260
|
+
return Math.round(value * 1000) / 1000;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Build the `FidelityReport` (same shape as the LuaLS `fidelity/<ns>.json`) over a
|
|
265
|
+
* parsed ref-doc `doc`. Every function element's param/return type tokens are run
|
|
266
|
+
* through `resolver`; a token the emitter cannot map (`resolver.resolves` false)
|
|
267
|
+
* is counted in `unknownFallbacks` and surfaced in `unknownTokens` rather than
|
|
268
|
+
* hidden behind the coverage number. `undocumentedMembers` counts function
|
|
269
|
+
* elements with an empty description. Deterministic; no I/O.
|
|
270
|
+
*/
|
|
271
|
+
export function computeScriptApiFidelity(
|
|
272
|
+
namespace: string,
|
|
273
|
+
doc: ScriptApiDoc,
|
|
274
|
+
resolver: TypeResolver,
|
|
275
|
+
): FidelityReport {
|
|
276
|
+
let totalMembers = 0;
|
|
277
|
+
let totalTypeTokens = 0;
|
|
278
|
+
let unknownFallbacks = 0;
|
|
279
|
+
let undocumentedMembers = 0;
|
|
280
|
+
const unknownTokens = new Set<string>();
|
|
281
|
+
|
|
282
|
+
for (const element of doc.elements) {
|
|
283
|
+
if (element.type !== "FUNCTION") continue;
|
|
284
|
+
totalMembers++;
|
|
285
|
+
if ((element.description ?? "").trim() === "") undocumentedMembers++;
|
|
286
|
+
for (const slot of [...element.parameters, ...element.returnvalues]) {
|
|
287
|
+
for (const token of slot.types) {
|
|
288
|
+
totalTypeTokens++;
|
|
289
|
+
if (!resolver.resolves(token)) {
|
|
290
|
+
unknownFallbacks++;
|
|
291
|
+
unknownTokens.add(token);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const coverage =
|
|
298
|
+
totalTypeTokens === 0
|
|
299
|
+
? 1
|
|
300
|
+
: round3(Math.max(0, Math.min(1, (totalTypeTokens - unknownFallbacks) / totalTypeTokens)));
|
|
301
|
+
|
|
302
|
+
return {
|
|
303
|
+
namespace,
|
|
304
|
+
totalMembers,
|
|
305
|
+
totalTypeTokens,
|
|
306
|
+
unknownFallbacks,
|
|
307
|
+
unknownTokens: [...unknownTokens].sort(),
|
|
308
|
+
undocumentedMembers,
|
|
309
|
+
coverage,
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export async function buildScriptApiFidelity(
|
|
314
|
+
packageRoot: string,
|
|
315
|
+
target: ScriptApiTarget,
|
|
316
|
+
): Promise<FidelityReport> {
|
|
317
|
+
const { scriptApiToFixtureJson, resolver } = await loadTypesModules(packageRoot);
|
|
318
|
+
const doc = parseFixtureDoc(packageRoot, target, scriptApiToFixtureJson);
|
|
319
|
+
return computeScriptApiFidelity(target.namespace, doc, resolver);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const defaultFetchText: FetchText = async (url) => {
|
|
323
|
+
const res = await fetch(url);
|
|
324
|
+
if (!res.ok) {
|
|
325
|
+
throw new Error(`fetch failed: ${url} -> ${res.status} ${res.statusText}`);
|
|
326
|
+
}
|
|
327
|
+
return res.text();
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
if (import.meta.main) {
|
|
331
|
+
const root = join(import.meta.dir, "..");
|
|
332
|
+
const argv = process.argv.slice(2);
|
|
333
|
+
if (argv.includes("--fetch")) {
|
|
334
|
+
for (const target of readScriptApiTargets(root)) {
|
|
335
|
+
await fetchScriptApiFixture(root, target, { fetchText: defaultFetchText });
|
|
336
|
+
console.log(`snapshotted ${target.moduleId} from ${repoSlug(target.repo)}@${target.ref}`);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
if (argv.includes("--emit")) {
|
|
340
|
+
for (const target of readScriptApiTargets(root)) {
|
|
341
|
+
const contents = await emitScriptApiDeclaration(root, target);
|
|
342
|
+
const dest = join(root, target.generated);
|
|
343
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
344
|
+
writeFileSync(dest, contents);
|
|
345
|
+
console.log(`emitted ${target.moduleId} -> ${target.generated}`);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
if (argv.includes("--api-doc")) {
|
|
349
|
+
for (const target of readScriptApiTargets(root)) {
|
|
350
|
+
const json = await lowerScriptApiApiDoc(root, target);
|
|
351
|
+
const dest = join(root, target.apiDoc);
|
|
352
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
353
|
+
writeFileSync(dest, json);
|
|
354
|
+
console.log(`lowered ${target.moduleId} -> ${target.apiDoc}`);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
if (argv.includes("--fidelity")) {
|
|
358
|
+
for (const target of readScriptApiTargets(root)) {
|
|
359
|
+
const report = await buildScriptApiFidelity(root, target);
|
|
360
|
+
const dest = join(root, target.fidelity);
|
|
361
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
362
|
+
writeFileSync(dest, `${JSON.stringify(report, null, 2)}\n`);
|
|
363
|
+
console.log(
|
|
364
|
+
`${target.moduleId}: coverage ${(report.coverage * 100).toFixed(1)}% (${report.unknownFallbacks} unknown, ${report.undocumentedMembers} undocumented)`,
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"info": {
|
|
3
|
-
"namespace": "immutable.immutable",
|
|
4
|
-
"brief": "Runtime immutable Lua table implementation",
|
|
5
|
-
"description": "Runtime immutable Lua table implementation"
|
|
6
|
-
},
|
|
7
|
-
"elements": [
|
|
8
|
-
{
|
|
9
|
-
"type": "TYPEDEF",
|
|
10
|
-
"name": "table"
|
|
11
|
-
},
|
|
12
|
-
{
|
|
13
|
-
"type": "FUNCTION",
|
|
14
|
-
"name": "make",
|
|
15
|
-
"brief": "",
|
|
16
|
-
"description": "",
|
|
17
|
-
"parameters": [
|
|
18
|
-
{
|
|
19
|
-
"name": "original_table",
|
|
20
|
-
"doc": "",
|
|
21
|
-
"types": [
|
|
22
|
-
"T"
|
|
23
|
-
],
|
|
24
|
-
"is_optional": "False"
|
|
25
|
-
}
|
|
26
|
-
],
|
|
27
|
-
"returnvalues": [
|
|
28
|
-
{
|
|
29
|
-
"name": "",
|
|
30
|
-
"doc": "",
|
|
31
|
-
"types": [
|
|
32
|
-
"Readonly<T>"
|
|
33
|
-
]
|
|
34
|
-
}
|
|
35
|
-
]
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
"type": "FUNCTION",
|
|
39
|
-
"name": "is_immutable",
|
|
40
|
-
"brief": "",
|
|
41
|
-
"description": "",
|
|
42
|
-
"parameters": [
|
|
43
|
-
{
|
|
44
|
-
"name": "table_to_check",
|
|
45
|
-
"doc": "",
|
|
46
|
-
"types": [
|
|
47
|
-
"table"
|
|
48
|
-
],
|
|
49
|
-
"is_optional": "False"
|
|
50
|
-
}
|
|
51
|
-
],
|
|
52
|
-
"returnvalues": [
|
|
53
|
-
{
|
|
54
|
-
"name": "",
|
|
55
|
-
"doc": "",
|
|
56
|
-
"types": [
|
|
57
|
-
"boolean"
|
|
58
|
-
]
|
|
59
|
-
}
|
|
60
|
-
]
|
|
61
|
-
}
|
|
62
|
-
]
|
|
63
|
-
}
|