@defold-typescript/types 0.34.0 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/api-signatures.json +9547 -186
  2. package/api-targets.json +9 -66
  3. package/examples/translations.json +6 -6
  4. package/generated/buffer.d.ts +2 -2
  5. package/generated/collectionfactory.d.ts +2 -2
  6. package/generated/factory.d.ts +13 -12
  7. package/generated/gui.d.ts +23 -23
  8. package/generated/kinds/gui-script.d.ts +0 -4
  9. package/generated/kinds/render-script.d.ts +1 -4
  10. package/generated/kinds/script.d.ts +0 -4
  11. package/generated/model.d.ts +2 -2
  12. package/generated/profiler.d.ts +2 -4
  13. package/generated/render.d.ts +7 -155
  14. package/generated/sys.d.ts +1 -1
  15. package/generated/versions/defold-1.12.4/buffer.d.ts +2 -2
  16. package/generated/versions/defold-1.12.4/collectionfactory.d.ts +2 -2
  17. package/generated/versions/defold-1.12.4/factory.d.ts +13 -12
  18. package/generated/versions/defold-1.12.4/gui.d.ts +23 -23
  19. package/generated/versions/defold-1.12.4/index.d.ts +9 -4
  20. package/generated/versions/defold-1.12.4/model.d.ts +2 -2
  21. package/generated/versions/defold-1.12.4/profiler.d.ts +2 -4
  22. package/generated/versions/defold-1.12.4/render.d.ts +7 -155
  23. package/generated/versions/defold-1.12.4/sys.d.ts +1 -1
  24. package/generated/versions/defold-1.12.4/vmath.d.ts +0 -19
  25. package/generated/versions/defold-1.12.4/window.d.ts +2 -4
  26. package/generated/versions/defold-1.12.4/zlib.d.ts +2 -1
  27. package/generated/versions/defold-1.13.0/buffer.d.ts +2 -2
  28. package/generated/versions/defold-1.13.0/collectionfactory.d.ts +2 -2
  29. package/generated/versions/defold-1.13.0/factory.d.ts +13 -12
  30. package/generated/versions/defold-1.13.0/gui.d.ts +23 -23
  31. package/generated/versions/defold-1.13.0/index.d.ts +9 -4
  32. package/generated/versions/defold-1.13.0/model.d.ts +2 -2
  33. package/generated/versions/defold-1.13.0/profiler.d.ts +2 -4
  34. package/generated/versions/defold-1.13.0/render.d.ts +7 -155
  35. package/generated/versions/defold-1.13.0/sys.d.ts +1 -1
  36. package/generated/versions/defold-1.13.0/vmath.d.ts +0 -19
  37. package/generated/versions/defold-1.13.0/window.d.ts +2 -4
  38. package/generated/versions/defold-1.13.0/zlib.d.ts +2 -1
  39. package/generated/vmath.d.ts +0 -19
  40. package/generated/window.d.ts +2 -4
  41. package/generated/zlib.d.ts +2 -1
  42. package/index.d.ts +2 -4
  43. package/package.json +7 -2
  44. package/scripts/extension-goldens.ts +23 -0
  45. package/scripts/generate-api-signatures.ts +72 -8
  46. package/scripts/materialize-version.ts +15 -1
  47. package/scripts/regen.ts +109 -27
  48. package/scripts/signature-store-fs.ts +1 -0
  49. package/scripts/sync-api-docs.ts +5 -61
  50. package/src/emit-dts.ts +359 -58
  51. package/src/index.ts +1 -0
  52. package/src/optional-correction-provenance.ts +13 -2
  53. package/src/render-overloads.d.ts +46 -0
  54. package/src/vmath-overloads.d.ts +19 -0
  55. package/generated/iac.d.ts +0 -18
  56. package/generated/iap.d.ts +0 -60
  57. package/generated/push.d.ts +0 -66
  58. package/generated/versions/defold-1.12.4/iac.d.ts +0 -18
  59. package/generated/versions/defold-1.12.4/iap.d.ts +0 -60
  60. package/generated/versions/defold-1.12.4/push.d.ts +0 -66
  61. package/generated/versions/defold-1.12.4/webview.d.ts +0 -71
  62. package/generated/versions/defold-1.13.0/iac.d.ts +0 -18
  63. package/generated/versions/defold-1.13.0/iap.d.ts +0 -60
  64. package/generated/versions/defold-1.13.0/push.d.ts +0 -66
  65. package/generated/versions/defold-1.13.0/webview.d.ts +0 -71
  66. package/generated/webview.d.ts +0 -71
  67. package/scripts/fidelity-audit.ts +0 -684
package/scripts/regen.ts CHANGED
@@ -191,15 +191,6 @@ const DEFAULT_TARGET = API_TARGETS.find((t) => t.default === true) as ApiTarget;
191
191
 
192
192
  export const MODULE_MANIFEST: readonly ModuleManifestEntry[] = loadTargetModules(DEFAULT_TARGET);
193
193
 
194
- // The fidelity audit runs over the promoted default surface (the `default: true`
195
- // target) so the 1.13-only modules (b2d.*, compute, material) and the 1.13 model
196
- // additions are audited too — auditing the older 1.12.4 target left them unseen,
197
- // which is how the promoted surface shipped opaque `Record` fallbacks while the
198
- // gate read `recordTables: 0`.
199
- const FIDELITY_BASELINE_TARGET = DEFAULT_TARGET;
200
- export const FIDELITY_BASELINE_MANIFEST: readonly ModuleManifestEntry[] =
201
- loadTargetModules(FIDELITY_BASELINE_TARGET);
202
-
203
194
  // Handle tokens the editor VM alone exposes. `transaction_step[` is what
204
195
  // upstream literally emits for `transaction_step[]` — the ref-doc's own type
205
196
  // string loses the closing bracket — so it is repaired here, per entry, rather
@@ -544,16 +535,29 @@ export function kindStdlibReferences(entry: KindManifestEntry): string {
544
535
  return `${LUA_51_REFERENCE}${entry.jit === false ? "" : LUA_JIT_ONLY_REFERENCE}`;
545
536
  }
546
537
 
547
- const UNIVERSAL_EXTRA_IMPORTS: readonly string[] = [
548
- "../builtin-messages",
549
- "../../src/custom-messages",
550
- "../../src/engine-globals",
551
- "../../src/msg-overloads",
552
- "../../src/message-guard",
553
- "../../src/window-event-guard",
554
- "../../src/scene-addresses",
555
- "../../src/go-overloads",
556
- "../../src/vmath-overloads",
538
+ // One augmentation a complete script surface imports. `restrictedTo` names the
539
+ // kind-restricted namespace the augmentation re-opens: such an entry belongs on
540
+ // that namespace's kind index alone, or it would re-open a wall the kind closes.
541
+ // The marker is declared rather than parsed out of the `.d.ts`, so
542
+ // `generateKindIndex` stays pure; `srcAugmentationScopingViolations` in
543
+ // `./augmentation-namespaces` is what catches a future restricted augmentation
544
+ // added without one, by reading the namespaces each file really re-opens.
545
+ interface UniversalExtraImport {
546
+ readonly specifier: string;
547
+ readonly restrictedTo?: string;
548
+ }
549
+
550
+ const UNIVERSAL_EXTRA_IMPORTS: readonly UniversalExtraImport[] = [
551
+ { specifier: "../builtin-messages" },
552
+ { specifier: "../../src/custom-messages" },
553
+ { specifier: "../../src/engine-globals" },
554
+ { specifier: "../../src/msg-overloads" },
555
+ { specifier: "../../src/message-guard" },
556
+ { specifier: "../../src/window-event-guard" },
557
+ { specifier: "../../src/scene-addresses" },
558
+ { specifier: "../../src/go-overloads" },
559
+ { specifier: "../../src/render-overloads", restrictedTo: "render" },
560
+ { specifier: "../../src/vmath-overloads" },
557
561
  ];
558
562
 
559
563
  const SRC_IMPORT_PREFIX = "../../src/";
@@ -561,9 +565,18 @@ const SRC_IMPORT_PREFIX = "../../src/";
561
565
  // The hand-authored `src/*` augmentations a complete script surface needs,
562
566
  // derived from the one declaration the generated kind index renders from so a
563
567
  // new augmentation reaches every materialization path with no second edit.
564
- export const SRC_AUGMENTATION_MODULES: readonly string[] = UNIVERSAL_EXTRA_IMPORTS.filter(
565
- (specifier) => specifier.startsWith(SRC_IMPORT_PREFIX),
566
- ).map((specifier) => specifier.slice(SRC_IMPORT_PREFIX.length));
568
+ export const SRC_AUGMENTATION_MODULES: readonly string[] = UNIVERSAL_EXTRA_IMPORTS.filter((entry) =>
569
+ entry.specifier.startsWith(SRC_IMPORT_PREFIX),
570
+ ).map((entry) => entry.specifier.slice(SRC_IMPORT_PREFIX.length));
571
+
572
+ // The `src/*` augmentations bound to a kind-restricted namespace, as
573
+ // `<module name> -> <namespace>`. Exported so the CLI's materialization scopes
574
+ // them the same way the in-repo kind indexes do, from one declaration.
575
+ export const RESTRICTED_SRC_AUGMENTATIONS: Readonly<Record<string, string>> = Object.fromEntries(
576
+ UNIVERSAL_EXTRA_IMPORTS.filter(
577
+ (entry) => entry.restrictedTo !== undefined && entry.specifier.startsWith(SRC_IMPORT_PREFIX),
578
+ ).map((entry) => [entry.specifier.slice(SRC_IMPORT_PREFIX.length), entry.restrictedTo as string]),
579
+ );
567
580
 
568
581
  // Read those augmentations as surface-root files. Mirrors
569
582
  // `loadTargetEditorModules`: a missing file throws with its path rather than
@@ -664,9 +677,14 @@ export function generateKindIndex(kind: string, target: ApiTarget = DEFAULT_TARG
664
677
  const universalNamespaces = MODULE_MANIFEST.filter(
665
678
  (m) => !Object.hasOwn(RESTRICTED_NAMESPACES, m.namespace),
666
679
  ).map((m) => `../${m.outFile.replace(/\.d\.ts$/, "")}`);
680
+ // An augmentation bound to a restricted namespace rides only that namespace's
681
+ // kind index; every unmarked entry stays universal.
682
+ const extraImports = UNIVERSAL_EXTRA_IMPORTS.filter(
683
+ (extra) => extra.restrictedTo === undefined || extra.restrictedTo === entry.restricted,
684
+ ).map((extra) => extra.specifier);
667
685
  const modules = (
668
686
  entry.only === undefined
669
- ? [...new Set([...universalNamespaces.sort(), ...[...UNIVERSAL_EXTRA_IMPORTS].sort()])]
687
+ ? [...new Set([...universalNamespaces.sort(), ...extraImports.sort()])]
670
688
  : [...editorKindModules(target), ...(entry.extraModules ?? [])]
671
689
  ).map((path) => retargetSrcPath(path, srcPrefix));
672
690
  const lines = modules.map((path) => `import "${path}";`);
@@ -687,8 +705,10 @@ export function generateKindIndex(kind: string, target: ApiTarget = DEFAULT_TARG
687
705
  export function generateVersionIndex(
688
706
  versionId: string,
689
707
  manifest: readonly VersionedModuleManifestEntry[] = VERSIONED_MODULE_MANIFEST,
690
- // Bare names appended after the module imports. A materialized surface carries
691
- // the `src/*` augmentations beside its modules; the in-repo emit does not.
708
+ // Names appended after the module imports. A materialized surface carries the
709
+ // `src/*` augmentations beside its modules and names them bare; the in-repo
710
+ // emit reaches back into the package and passes an already-relative specifier,
711
+ // which is kept verbatim rather than re-anchored to the surface directory.
692
712
  extraImports: readonly string[] = [],
693
713
  ): string {
694
714
  const imports = [
@@ -698,7 +718,7 @@ export function generateVersionIndex(
698
718
  .sort(),
699
719
  ...extraImports,
700
720
  ]
701
- .map((module) => `import "./${module}";`)
721
+ .map((module) => `import "${module.startsWith(".") ? module : `./${module}`}";`)
702
722
  .join("\n");
703
723
  // A pinned consumer names this surface in `types` and never loads the
704
724
  // package entrypoint, so the stdlib directives have to lead here too. A
@@ -706,6 +726,16 @@ export function generateVersionIndex(
706
726
  return `${LUA_STDLIB_REFERENCES}${imports}\n\nexport {};\n`;
707
727
  }
708
728
 
729
+ // The authored augmentations a committed per-version index imports, addressed
730
+ // back into the package's `src/`. The in-repo surface has no copies beside its
731
+ // modules, so a skipped symbol would otherwise be declared on no versioned
732
+ // surface at all. Derived from `SRC_AUGMENTATION_MODULES`, so a new augmentation
733
+ // reaches the pinned surfaces on the same edit that reaches the materialized ones.
734
+ export function versionSrcAugmentationImports(target: ApiTarget): string[] {
735
+ const srcPrefix = target.coreTypesImport.slice(0, -"core-types".length);
736
+ return SRC_AUGMENTATION_MODULES.map((name) => `${srcPrefix}${name}`);
737
+ }
738
+
709
739
  // The `src/`-relative prefix a kind index living in `<generatedDir>/kinds/` needs
710
740
  // to reach the package's hand-authored modules. The target's own
711
741
  // `coreTypesImport` already measures its generated dir's depth; the kind index
@@ -732,7 +762,37 @@ export function targetKindManifest(target: ApiTarget): readonly KindManifestEntr
732
762
  return [...RUNTIME_KIND_MANIFEST, ...KIND_MODULE_MANIFEST.filter((e) => e.only !== undefined)];
733
763
  }
734
764
 
765
+ // Every `src/*` augmentation bound to a kind-restricted namespace carries its
766
+ // `restrictedTo` marker, and every marker names a namespace its file re-opens.
767
+ // Exported so a test can reach the guard the entry point runs; never called on
768
+ // import, so the dynamic import below stays unreached from an installed package.
769
+ export async function assertSrcAugmentationScoping(
770
+ packageRoot: string = PACKAGE_ROOT,
771
+ ): Promise<number> {
772
+ // Imported here rather than at module scope: it imports the devDependency
773
+ // `typescript`, and `resolve` loads this module from an installed package.
774
+ const { srcAugmentationScopingViolations } = await import("./augmentation-namespaces");
775
+ const files = loadSrcAugmentations(packageRoot);
776
+ const violations = srcAugmentationScopingViolations(
777
+ files,
778
+ RESTRICTED_SRC_AUGMENTATIONS,
779
+ RESTRICTED_NAMESPACES,
780
+ );
781
+ if (violations.length > 0) {
782
+ throw new Error(`src augmentation scoping violations:\n${violations.join("\n")}`);
783
+ }
784
+ return files.length;
785
+ }
786
+
735
787
  if (import.meta.main) {
788
+ // Ordering contract: `regen-entrypoint.test.ts` reads this line's prefix to
789
+ // prove the guard runs before the first write. The count comes from the guard's
790
+ // own return value so the marker cannot be printed without a completed guard
791
+ // run — do not simplify it back to `SRC_AUGMENTATION_MODULES.length`, which
792
+ // would let the guard be deleted or reordered with the line still intact.
793
+ const checked = await assertSrcAugmentationScoping();
794
+ console.log(`src augmentation scoping checked: ${checked} file(s)`);
795
+
736
796
  const generated = resolve(import.meta.dir, "..", "generated");
737
797
  mkdirSync(resolve(generated, "editor-vm"), { recursive: true });
738
798
  for (const entry of [
@@ -752,6 +812,21 @@ if (import.meta.main) {
752
812
  writeFileSync(messagesOut, generateBuiltinMessagesDeclaration(MESSAGES_MANIFEST));
753
813
  console.log(`wrote ${messagesOut}`);
754
814
 
815
+ // Imported here rather than at module scope: its fixtures are not published,
816
+ // and `resolve` loads this module from an installed package.
817
+ const { EXTENSION_GOLDENS_DIR, EXTENSION_GOLDEN_MANIFEST } = await import("./extension-goldens");
818
+ const goldens = resolve(PACKAGE_ROOT, EXTENSION_GOLDENS_DIR);
819
+ mkdirSync(goldens, { recursive: true });
820
+ for (const entry of EXTENSION_GOLDEN_MANIFEST) {
821
+ const { contents, dropped } = generateModuleDeclaration(entry);
822
+ if (dropped.length > 0) {
823
+ console.log(`note: dropped skipped member(s) from ${entry.namespace}: ${dropped.join(", ")}`);
824
+ }
825
+ const out = resolve(goldens, entry.outFile);
826
+ writeFileSync(out, contents);
827
+ console.log(`wrote ${out}`);
828
+ }
829
+
755
830
  // The target's own `generatedDir` is where a version lands, so a declaring
756
831
  // target's editor surface (and its `editor-vm/` subdirectory) rides the same
757
832
  // destination rule as its runtime modules rather than a second convention.
@@ -778,7 +853,14 @@ if (import.meta.main) {
778
853
  for (const target of versionedTargets) {
779
854
  const indexOut = resolve(versionDirOf(target.id), "index.d.ts");
780
855
  mkdirSync(dirname(indexOut), { recursive: true });
781
- writeFileSync(indexOut, generateVersionIndex(target.id));
856
+ writeFileSync(
857
+ indexOut,
858
+ generateVersionIndex(
859
+ target.id,
860
+ VERSIONED_MODULE_MANIFEST,
861
+ versionSrcAugmentationImports(target),
862
+ ),
863
+ );
782
864
  console.log(`wrote ${indexOut}`);
783
865
 
784
866
  const editorKinds = targetKindManifest(target).filter((entry) => entry.only !== undefined);
@@ -24,6 +24,7 @@ export const SOCKET_SIGNATURES_PATH = resolve(import.meta.dir, "..", "signatures
24
24
  export const VMATH_SIGNATURES_PATH = resolve(import.meta.dir, "..", "signatures", "vmath.json");
25
25
  export const GO_SIGNATURES_PATH = resolve(import.meta.dir, "..", "signatures", "go.json");
26
26
  export const MSG_SIGNATURES_PATH = resolve(import.meta.dir, "..", "signatures", "msg.json");
27
+ export const RENDER_SIGNATURES_PATH = resolve(import.meta.dir, "..", "signatures", "render.json");
27
28
 
28
29
  export function loadSignatureFile(path: string): SignatureStore {
29
30
  let raw: string;
@@ -109,9 +109,9 @@ export const SYNC_MANIFEST: readonly SyncManifestEntry[] = [
109
109
  entry("zlib", "doc/src-script_zlib.cpp_doc.json"),
110
110
  ];
111
111
 
112
- // Checklist namespaces with no machine-readable doc anywhere (neither core
113
- // ref-doc.zip nor a published extension `.script_api`). Currently empty: the
114
- // four extension-only surfaces are wired via EXTENSION_MANIFEST below.
112
+ // Checklist namespaces with no machine-readable doc anywhere in core
113
+ // ref-doc.zip. Currently empty: extension namespaces are not engine surfaces;
114
+ // they are typed through `resolve` from each extension's own `.script_api`.
115
115
  export const UNMAPPED: ReadonlyMap<string, string> = new Map();
116
116
 
117
117
  // A Lua script namespace is a lowercase, dot-separated identifier (`sys`,
@@ -211,53 +211,18 @@ function entry(
211
211
  return { namespace, zipEntry, fixture, ...(mergeEntries ? { mergeEntries } : {}) };
212
212
  }
213
213
 
214
- export interface ExtensionManifestEntry {
215
- readonly namespace: string;
216
- readonly repo: string;
217
- readonly tag: string;
218
- readonly path: string;
219
- readonly fixture: string;
220
- }
221
-
222
- // Extension-only namespaces: each ships a single `.script_api` (YAML) doc in
223
- // its own repo rather than appearing in core ref-doc.zip. Pinned to a release
224
- // tag and converted to the core ref-doc JSON shape via parseScriptApi so they
225
- // flow through MODULE_MANIFEST and the drift guard like every core namespace.
226
- export const EXTENSION_MANIFEST: readonly ExtensionManifestEntry[] = [
227
- ext("iac", "defold/extension-iac", "1.4.0", "extension-iac/api/iac.script_api"),
228
- ext("iap", "defold/extension-iap", "8.4.0", "extension-iap/api/iap.script_api"),
229
- ext("push", "defold/extension-push", "4.1.0", "extension-push/api/push.script_api"),
230
- ext("webview", "defold/extension-webview", "1.5.0", "webview/api/webview.script_api"),
231
- ];
232
-
233
- function ext(namespace: string, repo: string, tag: string, path: string): ExtensionManifestEntry {
234
- return {
235
- namespace,
236
- repo,
237
- tag,
238
- path,
239
- fixture: `fixtures/defold-1.13.1/${namespace}_doc.json`,
240
- };
241
- }
242
-
243
214
  // Every vendored fixture set the coverage report audits, and the namespaces it
244
215
  // counts as reached from upstream. Composed once here so the `--check` run and
245
216
  // the guard over it cannot disagree about which sets are in scope.
246
217
  export const COVERAGE_MANIFEST: readonly { readonly namespace: string }[] = [
247
218
  ...SYNC_MANIFEST,
248
- ...EXTENSION_MANIFEST,
249
219
  ...EDITOR_MANIFEST,
250
220
  ];
251
221
 
252
222
  export const UPSTREAM_MAPPED_NAMESPACES: ReadonlySet<string> = new Set(
253
- [...SYNC_MANIFEST, ...EXTENSION_MANIFEST, ...LUA_STDLIB_MANIFEST, ...EDITOR_MANIFEST].map(
254
- (e) => e.namespace,
255
- ),
223
+ [...SYNC_MANIFEST, ...LUA_STDLIB_MANIFEST, ...EDITOR_MANIFEST].map((e) => e.namespace),
256
224
  );
257
225
 
258
- export const extensionRawUrl = (e: ExtensionManifestEntry): string =>
259
- `https://raw.githubusercontent.com/${e.repo}/${e.tag}/${e.path}`;
260
-
261
226
  // Convert a raw `.script_api` YAML doc to the core ref-doc JSON string written
262
227
  // to fixtures/<ns>_doc.json. The result is byte-compared by the same drift
263
228
  // semantics core fixtures use.
@@ -492,25 +457,6 @@ export function syncExtractedFixtures(
492
457
  return results;
493
458
  }
494
459
 
495
- export async function downloadExtensionFixtures(
496
- manifest: readonly ExtensionManifestEntry[] = EXTENSION_MANIFEST,
497
- ): Promise<ExtractedFixture[]> {
498
- const out: ExtractedFixture[] = [];
499
- for (const e of manifest) {
500
- const url = extensionRawUrl(e);
501
- const res = await fetch(url);
502
- if (!res.ok) {
503
- throw new Error(`extension doc download failed: ${url} -> ${res.status} ${res.statusText}`);
504
- }
505
- out.push({
506
- namespace: e.namespace,
507
- fixture: e.fixture,
508
- contents: scriptApiToFixtureJson(await res.text()),
509
- });
510
- }
511
- return out;
512
- }
513
-
514
460
  function readFixtureOrNull(path: string): string | null {
515
461
  try {
516
462
  return readFileSync(path, "utf8");
@@ -681,18 +627,16 @@ if (import.meta.main) {
681
627
  const zip = zipPath ? readZip(zipPath) : await downloadZip();
682
628
 
683
629
  const coreFixtures = extractFixtures(zip);
684
- const extensionFixtures = await downloadExtensionFixtures();
685
630
  const luaStdlibFixtures = extractFixtures(zip, LUA_STDLIB_MANIFEST);
686
631
  const editorFixtures = extractFixtures(zip, EDITOR_MANIFEST);
687
632
  const editorVmFixtures = extractFixtures(zip, EDITOR_VM_MANIFEST);
688
633
  const results = [
689
634
  ...syncExtractedFixtures(coreFixtures, { check }),
690
- ...syncExtractedFixtures(extensionFixtures, { check }),
691
635
  ...syncExtractedFixtures(luaStdlibFixtures, { check }),
692
636
  ...syncExtractedFixtures(editorFixtures, { check }),
693
637
  ...syncExtractedFixtures(editorVmFixtures, { check }),
694
638
  ];
695
- const syncedDocs = [...coreFixtures, ...extensionFixtures].map((f) => ({
639
+ const syncedDocs = coreFixtures.map((f) => ({
696
640
  namespace: f.namespace,
697
641
  doc: JSON.parse(f.contents),
698
642
  }));