@defold-typescript/cli 0.5.2 → 0.5.4
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/README.md +8 -3
- package/dist/bin.js +267 -50
- package/dist/debug-launcher.d.ts +43 -0
- package/dist/index.js +267 -50
- package/dist/init.d.ts +1 -0
- package/dist/mise-scaffold.d.ts +2 -0
- package/package.json +3 -3
- package/src/debug-launcher.ts +165 -0
- package/src/init.ts +126 -52
- package/src/materialize.ts +17 -8
- package/src/mise-scaffold.ts +62 -0
package/dist/index.js
CHANGED
|
@@ -295,6 +295,169 @@ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readdirSync, readFi
|
|
|
295
295
|
import * as path7 from "node:path";
|
|
296
296
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
297
297
|
|
|
298
|
+
// src/debug-launcher.ts
|
|
299
|
+
var PLATFORM_TARGETS = {
|
|
300
|
+
darwin: { enginePlatform: "x86_64-darwin", buildFolder: "x86_64-osx", executable: "dmengine" },
|
|
301
|
+
linux: { enginePlatform: "x86_64-linux", buildFolder: "x86_64-linux", executable: "dmengine" },
|
|
302
|
+
win32: {
|
|
303
|
+
enginePlatform: "x86_64-win32",
|
|
304
|
+
buildFolder: "x86_64-win32",
|
|
305
|
+
executable: "dmengine.exe"
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
var ENGINE_INFO_URL = "https://d.defold.com/stable/info.json";
|
|
309
|
+
var ENGINE_ARCHIVE_BASE = "https://d.defold.com/archive/stable";
|
|
310
|
+
var DEBUG_LAUNCHER_REL = ".vscode/defold-debug.ts";
|
|
311
|
+
function debugLaunchConfig() {
|
|
312
|
+
return {
|
|
313
|
+
name: "Defold: Debug (TypeScript)",
|
|
314
|
+
type: "lua-local",
|
|
315
|
+
request: "launch",
|
|
316
|
+
stopOnEntry: false,
|
|
317
|
+
verbose: false,
|
|
318
|
+
internalConsoleOptions: "openOnSessionStart",
|
|
319
|
+
program: { command: "bun" },
|
|
320
|
+
args: [DEBUG_LAUNCHER_REL]
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
var VSCODE_LAUNCH_CONTENT = {
|
|
324
|
+
version: "0.2.0",
|
|
325
|
+
configurations: [debugLaunchConfig()]
|
|
326
|
+
};
|
|
327
|
+
function renderDebugLauncher() {
|
|
328
|
+
const targets = JSON.stringify(PLATFORM_TARGETS, null, 2);
|
|
329
|
+
return `import { chmodSync, copyFileSync, existsSync, mkdirSync } from "node:fs";
|
|
330
|
+
import * as path from "node:path";
|
|
331
|
+
|
|
332
|
+
// Windows only: paths to OpenAL32.dll and wrap_oal.dll from your Defold SDK
|
|
333
|
+
// (defoldsdk/ext/lib/x86_64-win32/). Leave empty on macOS/Linux.
|
|
334
|
+
const WINDOWS_OPENAL32_PATH = "";
|
|
335
|
+
const WINDOWS_WRAPOAL_PATH = "";
|
|
336
|
+
|
|
337
|
+
interface EngineTarget {
|
|
338
|
+
enginePlatform: string;
|
|
339
|
+
buildFolder: string;
|
|
340
|
+
executable: string;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const PLATFORM_TARGETS: Record<string, EngineTarget> = ${targets};
|
|
344
|
+
|
|
345
|
+
const ENGINE_INFO_URL = "${ENGINE_INFO_URL}";
|
|
346
|
+
const ENGINE_ARCHIVE_BASE = "${ENGINE_ARCHIVE_BASE}";
|
|
347
|
+
|
|
348
|
+
const target = PLATFORM_TARGETS[process.platform];
|
|
349
|
+
if (!target) {
|
|
350
|
+
console.error(\`Unsupported platform: \${process.platform}\`);
|
|
351
|
+
process.exit(1);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const here = path.dirname(new URL(import.meta.url).pathname);
|
|
355
|
+
const stockEnginePath = path.join(here, target.executable);
|
|
356
|
+
|
|
357
|
+
if (!existsSync(stockEnginePath)) {
|
|
358
|
+
const info = (await (await fetch(ENGINE_INFO_URL)).json()) as { sha1: string };
|
|
359
|
+
const url = \`\${ENGINE_ARCHIVE_BASE}/\${info.sha1}/engine/\${target.enginePlatform}/\${target.executable}\`;
|
|
360
|
+
console.log(\`Fetching \${url}\`);
|
|
361
|
+
const res = await fetch(url);
|
|
362
|
+
if (!res.ok) {
|
|
363
|
+
console.error(\`Engine download failed: \${res.status} \${res.statusText}\`);
|
|
364
|
+
process.exit(1);
|
|
365
|
+
}
|
|
366
|
+
await Bun.write(stockEnginePath, res);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
const buildFolder = path.join("build", target.buildFolder);
|
|
370
|
+
const buildEnginePath = path.join(buildFolder, target.executable);
|
|
371
|
+
let enginePath = existsSync(buildEnginePath) ? buildEnginePath : stockEnginePath;
|
|
372
|
+
|
|
373
|
+
if (process.platform === "win32" && enginePath === buildEnginePath) {
|
|
374
|
+
for (const [src, name] of [
|
|
375
|
+
[WINDOWS_OPENAL32_PATH, "OpenAL32.dll"],
|
|
376
|
+
[WINDOWS_WRAPOAL_PATH, "wrap_oal.dll"],
|
|
377
|
+
] as const) {
|
|
378
|
+
const dest = path.join(buildFolder, name);
|
|
379
|
+
if (src && !existsSync(dest)) {
|
|
380
|
+
copyFileSync(src, dest);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// macOS: a build engine launched in place attaches to the editor process; copy
|
|
386
|
+
// it aside first so it runs standalone.
|
|
387
|
+
if (process.platform === "darwin" && enginePath === buildEnginePath) {
|
|
388
|
+
const tempEngine = path.join(buildFolder, "temp", target.executable);
|
|
389
|
+
mkdirSync(path.dirname(tempEngine), { recursive: true });
|
|
390
|
+
copyFileSync(buildEnginePath, tempEngine);
|
|
391
|
+
enginePath = tempEngine;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (process.platform !== "win32") {
|
|
395
|
+
chmodSync(enginePath, 0o755);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const projectc = path.join("build", "default", "game.projectc");
|
|
399
|
+
console.log(\`Launching \${enginePath} \${projectc}\`);
|
|
400
|
+
const proc = Bun.spawn([enginePath, projectc], {
|
|
401
|
+
stdio: ["inherit", "inherit", "inherit"],
|
|
402
|
+
});
|
|
403
|
+
process.exit(await proc.exited);
|
|
404
|
+
`;
|
|
405
|
+
}
|
|
406
|
+
var DEBUG_LAUNCHER_SOURCE = renderDebugLauncher();
|
|
407
|
+
|
|
408
|
+
// src/mise-scaffold.ts
|
|
409
|
+
var MANAGED_MARKER = "# managed by @defold-typescript";
|
|
410
|
+
var MISE_TASKS_TOML = `${MANAGED_MARKER}
|
|
411
|
+
[tasks."defold-typescript:build"]
|
|
412
|
+
description = "Build the TypeScript sources with the installed defold-typescript CLI"
|
|
413
|
+
run = "bunx --no-install defold-typescript build"
|
|
414
|
+
|
|
415
|
+
${MANAGED_MARKER}
|
|
416
|
+
[tasks."defold-typescript:watch"]
|
|
417
|
+
description = "Watch and rebuild the TypeScript sources with the installed defold-typescript CLI"
|
|
418
|
+
run = "bunx --no-install defold-typescript watch"
|
|
419
|
+
|
|
420
|
+
${MANAGED_MARKER}
|
|
421
|
+
[tasks."defold-typescript:upgrade"]
|
|
422
|
+
description = "Upgrade the defold-typescript CLI to its latest release and re-pin the types dependency"
|
|
423
|
+
run = ["bunx @defold-typescript/cli@latest init --force", "bun install"]
|
|
424
|
+
`;
|
|
425
|
+
function stripManagedBlocks(text) {
|
|
426
|
+
const lines = text.split(`
|
|
427
|
+
`);
|
|
428
|
+
const out = [];
|
|
429
|
+
let i = 0;
|
|
430
|
+
while (i < lines.length) {
|
|
431
|
+
const line = lines[i] ?? "";
|
|
432
|
+
if (line.trim() === MANAGED_MARKER) {
|
|
433
|
+
i += 1;
|
|
434
|
+
while (i < lines.length && (lines[i] ?? "").trim() !== "") {
|
|
435
|
+
i += 1;
|
|
436
|
+
}
|
|
437
|
+
if (i < lines.length) {
|
|
438
|
+
i += 1;
|
|
439
|
+
}
|
|
440
|
+
continue;
|
|
441
|
+
}
|
|
442
|
+
out.push(line);
|
|
443
|
+
i += 1;
|
|
444
|
+
}
|
|
445
|
+
return out.join(`
|
|
446
|
+
`);
|
|
447
|
+
}
|
|
448
|
+
function mergeMiseToml(existing) {
|
|
449
|
+
if (existing === undefined) {
|
|
450
|
+
return MISE_TASKS_TOML;
|
|
451
|
+
}
|
|
452
|
+
const userContent = stripManagedBlocks(existing).replace(/\s*$/, "");
|
|
453
|
+
if (userContent === "") {
|
|
454
|
+
return MISE_TASKS_TOML;
|
|
455
|
+
}
|
|
456
|
+
return `${userContent}
|
|
457
|
+
|
|
458
|
+
${MISE_TASKS_TOML}`;
|
|
459
|
+
}
|
|
460
|
+
|
|
298
461
|
// src/script-kind.ts
|
|
299
462
|
var DEFAULT_TYPES_ENTRYPOINT = "@defold-typescript/types";
|
|
300
463
|
var KIND_BY_EXT = {
|
|
@@ -406,43 +569,64 @@ var BIOME_JSON_CONTENT = {
|
|
|
406
569
|
}
|
|
407
570
|
};
|
|
408
571
|
var VSCODE_EXTENSIONS_CONTENT = {
|
|
409
|
-
recommendations: ["sumneko.lua", "astronachos.defold"],
|
|
572
|
+
recommendations: ["sumneko.lua", "astronachos.defold", "tomblind.local-lua-debugger-vscode"],
|
|
410
573
|
unwantedRecommendations: ["johnnymorganz.luau-lsp"]
|
|
411
574
|
};
|
|
412
575
|
var VSCODE_SETTINGS_CONTENT = {
|
|
413
576
|
"Lua.workspace.ignoreDir": ["src"]
|
|
414
577
|
};
|
|
578
|
+
var HOOK_COMMENTS = {
|
|
579
|
+
init: "Initialize the component and return its state.",
|
|
580
|
+
update: "Update the component every frame; `dt` is the time step.",
|
|
581
|
+
fixed_update: "Update at the fixed physics time step.",
|
|
582
|
+
late_update: "Update every frame after `update`.",
|
|
583
|
+
on_message: "Handle an incoming message.",
|
|
584
|
+
on_input: "Handle input once input focus is acquired.",
|
|
585
|
+
final: "Clean up when the component is deleted.",
|
|
586
|
+
on_reload: "React to a hot reload of this script."
|
|
587
|
+
};
|
|
588
|
+
var HOOK_SIGNATURES = {
|
|
589
|
+
init: "",
|
|
590
|
+
update: "self, dt",
|
|
591
|
+
fixed_update: "self, dt",
|
|
592
|
+
late_update: "self, dt",
|
|
593
|
+
on_message: "self, message_id, message, sender",
|
|
594
|
+
on_input: "self, action_id, action",
|
|
595
|
+
final: "self",
|
|
596
|
+
on_reload: "self"
|
|
597
|
+
};
|
|
598
|
+
var SNIPPET_HOOK_ORDER = Object.keys(HOOK_SIGNATURES);
|
|
599
|
+
function hookLines(includeOnInput, startTabStop) {
|
|
600
|
+
const lines = [];
|
|
601
|
+
let tabStop = startTabStop;
|
|
602
|
+
for (const hook of SNIPPET_HOOK_ORDER) {
|
|
603
|
+
if (hook === "init") {
|
|
604
|
+
continue;
|
|
605
|
+
}
|
|
606
|
+
if (hook === "on_input" && !includeOnInput) {
|
|
607
|
+
continue;
|
|
608
|
+
}
|
|
609
|
+
lines.push(` // ${HOOK_COMMENTS[hook]}`);
|
|
610
|
+
lines.push(` ${hook}(${HOOK_SIGNATURES[hook]}) {$${tabStop}},`);
|
|
611
|
+
tabStop += 1;
|
|
612
|
+
}
|
|
613
|
+
return lines;
|
|
614
|
+
}
|
|
415
615
|
function inlineSnippetBody(factory, includeOnInput) {
|
|
416
|
-
|
|
616
|
+
return [
|
|
417
617
|
`import { ${factory} } from "@defold-typescript/types";`,
|
|
418
618
|
"",
|
|
419
619
|
`export const script = ${factory}({`,
|
|
420
|
-
|
|
620
|
+
` // ${HOOK_COMMENTS.init}`,
|
|
421
621
|
" init() {",
|
|
422
622
|
" return { $0 };",
|
|
423
623
|
" },",
|
|
424
|
-
|
|
425
|
-
"
|
|
426
|
-
" // Update at the fixed physics time step.",
|
|
427
|
-
" fixed_update(self, dt) {$2},",
|
|
428
|
-
" // Update every frame after `update`.",
|
|
429
|
-
" late_update(self, dt) {$3},",
|
|
430
|
-
" // Handle an incoming message.",
|
|
431
|
-
" on_message(self, message_id, message, sender) {$4},"
|
|
624
|
+
...hookLines(includeOnInput, 1),
|
|
625
|
+
"});"
|
|
432
626
|
];
|
|
433
|
-
if (includeOnInput) {
|
|
434
|
-
lines.push(" // Handle input once input focus is acquired.");
|
|
435
|
-
lines.push(" on_input(self, action_id, action) {$5},");
|
|
436
|
-
}
|
|
437
|
-
lines.push(" // Clean up when the component is deleted.");
|
|
438
|
-
lines.push(" final(self) {$6},");
|
|
439
|
-
lines.push(" // React to a hot reload of this script.");
|
|
440
|
-
lines.push(" on_reload(self) {$7},");
|
|
441
|
-
lines.push("});");
|
|
442
|
-
return lines;
|
|
443
627
|
}
|
|
444
628
|
function typedSnippetBody(factory, includeOnInput) {
|
|
445
|
-
|
|
629
|
+
return [
|
|
446
630
|
`import { ${factory} } from "@defold-typescript/types";`,
|
|
447
631
|
"",
|
|
448
632
|
"type Self = {",
|
|
@@ -451,29 +635,13 @@ function typedSnippetBody(factory, includeOnInput) {
|
|
|
451
635
|
"};",
|
|
452
636
|
"",
|
|
453
637
|
`export const script = ${factory}<Self>({`,
|
|
454
|
-
|
|
638
|
+
` // ${HOOK_COMMENTS.init}`,
|
|
455
639
|
" init(): Self {",
|
|
456
640
|
" return { $0 };",
|
|
457
641
|
" },",
|
|
458
|
-
|
|
459
|
-
"
|
|
460
|
-
" // Update at the fixed physics time step.",
|
|
461
|
-
" fixed_update(self, dt) {$3},",
|
|
462
|
-
" // Update every frame after `update`.",
|
|
463
|
-
" late_update(self, dt) {$4},",
|
|
464
|
-
" // Handle an incoming message.",
|
|
465
|
-
" on_message(self, message_id, message, sender) {$5},"
|
|
642
|
+
...hookLines(includeOnInput, 2),
|
|
643
|
+
"});"
|
|
466
644
|
];
|
|
467
|
-
if (includeOnInput) {
|
|
468
|
-
lines.push(" // Handle input once input focus is acquired.");
|
|
469
|
-
lines.push(" on_input(self, action_id, action) {$6},");
|
|
470
|
-
}
|
|
471
|
-
lines.push(" // Clean up when the component is deleted.");
|
|
472
|
-
lines.push(" final(self) {$7},");
|
|
473
|
-
lines.push(" // React to a hot reload of this script.");
|
|
474
|
-
lines.push(" on_reload(self) {$8},");
|
|
475
|
-
lines.push("});");
|
|
476
|
-
return lines;
|
|
477
645
|
}
|
|
478
646
|
var VSCODE_SNIPPETS_CONTENT = {
|
|
479
647
|
"Defold script (inferred self)": {
|
|
@@ -544,12 +712,15 @@ function typesVersionSpec() {
|
|
|
544
712
|
}
|
|
545
713
|
var SCAFFOLD_DEV_DEPS = {
|
|
546
714
|
"@defold-typescript/types": typesVersionSpec(),
|
|
715
|
+
"@defold-typescript/cli": typesVersionSpec(),
|
|
547
716
|
"@biomejs/biome": "^2.2.0"
|
|
548
717
|
};
|
|
549
718
|
function repairManagedDevDeps(devDeps, force = false) {
|
|
550
719
|
delete devDeps["@defold-typescript/transpiler"];
|
|
551
|
-
|
|
552
|
-
devDeps["
|
|
720
|
+
for (const name of ["@defold-typescript/types", "@defold-typescript/cli"]) {
|
|
721
|
+
if (force || devDeps[name]?.startsWith("workspace:")) {
|
|
722
|
+
devDeps[name] = typesVersionSpec();
|
|
723
|
+
}
|
|
553
724
|
}
|
|
554
725
|
}
|
|
555
726
|
function writeJson(filePath, value) {
|
|
@@ -586,6 +757,12 @@ function writeBiome(cwd, written) {
|
|
|
586
757
|
writeJson(biomePath, BIOME_JSON_CONTENT);
|
|
587
758
|
written.push("biome.json");
|
|
588
759
|
}
|
|
760
|
+
function writeMiseTasks(cwd, written) {
|
|
761
|
+
const misePath = path7.join(cwd, "mise.toml");
|
|
762
|
+
const existing = existsSync2(misePath) ? readFileSync6(misePath, "utf8") : undefined;
|
|
763
|
+
writeFileSync2(misePath, mergeMiseToml(existing));
|
|
764
|
+
written.push("mise.toml");
|
|
765
|
+
}
|
|
589
766
|
function parseJsonc(text) {
|
|
590
767
|
let out = "";
|
|
591
768
|
let inString = false;
|
|
@@ -707,6 +884,39 @@ function writeVscodeSnippets(cwd, written) {
|
|
|
707
884
|
writeJson(filePath, VSCODE_SNIPPETS_CONTENT);
|
|
708
885
|
written.push(".vscode/defold-typescript.code-snippets");
|
|
709
886
|
}
|
|
887
|
+
function writeVscodeLaunch(cwd, written) {
|
|
888
|
+
const dir = path7.join(cwd, ".vscode");
|
|
889
|
+
const filePath = path7.join(dir, "launch.json");
|
|
890
|
+
const ours = debugLaunchConfig();
|
|
891
|
+
if (existsSync2(filePath)) {
|
|
892
|
+
const existing = readVscodeJson(filePath);
|
|
893
|
+
if (existing === null) {
|
|
894
|
+
return;
|
|
895
|
+
}
|
|
896
|
+
const configs = Array.isArray(existing.configurations) ? [...existing.configurations] : [];
|
|
897
|
+
const names = new Set(configs.map((c) => isJsonObject(c) ? c.name : undefined));
|
|
898
|
+
if (!names.has(ours.name)) {
|
|
899
|
+
configs.push(ours);
|
|
900
|
+
}
|
|
901
|
+
existing.configurations = configs;
|
|
902
|
+
existing.version ??= VSCODE_LAUNCH_CONTENT.version;
|
|
903
|
+
writeJson(filePath, existing);
|
|
904
|
+
return;
|
|
905
|
+
}
|
|
906
|
+
mkdirSync2(dir, { recursive: true });
|
|
907
|
+
writeJson(filePath, VSCODE_LAUNCH_CONTENT);
|
|
908
|
+
written.push(".vscode/launch.json");
|
|
909
|
+
}
|
|
910
|
+
function writeVscodeDebugLauncher(cwd, written) {
|
|
911
|
+
const dir = path7.join(cwd, ".vscode");
|
|
912
|
+
const filePath = path7.join(dir, "defold-debug.ts");
|
|
913
|
+
if (existsSync2(filePath)) {
|
|
914
|
+
return;
|
|
915
|
+
}
|
|
916
|
+
mkdirSync2(dir, { recursive: true });
|
|
917
|
+
writeFileSync2(filePath, DEBUG_LAUNCHER_SOURCE);
|
|
918
|
+
written.push(".vscode/defold-debug.ts");
|
|
919
|
+
}
|
|
710
920
|
function writeTsSurface(cwd, written, force = false) {
|
|
711
921
|
mkdirSync2(path7.join(cwd, "src"), { recursive: true });
|
|
712
922
|
writeFileSync2(path7.join(cwd, "src", "main.ts"), MAIN_TS_CONTENT);
|
|
@@ -748,9 +958,12 @@ function writeTsSurface(cwd, written, force = false) {
|
|
|
748
958
|
writeGitignore(cwd);
|
|
749
959
|
written.push(".gitignore");
|
|
750
960
|
writeBiome(cwd, written);
|
|
961
|
+
writeMiseTasks(cwd, written);
|
|
751
962
|
writeVscodeExtensions(cwd, written);
|
|
752
963
|
writeVscodeSettings(cwd, written);
|
|
753
964
|
writeVscodeSnippets(cwd, written);
|
|
965
|
+
writeVscodeLaunch(cwd, written);
|
|
966
|
+
writeVscodeDebugLauncher(cwd, written);
|
|
754
967
|
return selectScriptKind(kinds);
|
|
755
968
|
}
|
|
756
969
|
function runNewProjectInit(cwd, force = false) {
|
|
@@ -833,7 +1046,7 @@ function materializeApiSurface(opts) {
|
|
|
833
1046
|
const excluded = excludedModulesForKind(opts.scriptKind ?? null);
|
|
834
1047
|
const sources = listDts(sourceGeneratedDir).filter((file) => file !== "index.d.ts").filter((file) => !excluded.has(file.replace(/\.d\.ts$/, "")));
|
|
835
1048
|
const srcDir = path8.resolve(sourceGeneratedDir, "..", "src");
|
|
836
|
-
const overloads = ["msg-overloads.d.ts", "go-overloads.d.ts"].filter((file) => existsSync3(path8.join(srcDir, file)));
|
|
1049
|
+
const overloads = ["msg-overloads.d.ts", "message-guard.d.ts", "go-overloads.d.ts"].filter((file) => existsSync3(path8.join(srcDir, file)));
|
|
837
1050
|
const coreTypesSrc = path8.join(srcDir, "core-types.ts");
|
|
838
1051
|
const includeCoreTypes = overloads.length > 0 && existsSync3(coreTypesSrc);
|
|
839
1052
|
const engineGlobalsSrc = path8.join(srcDir, "engine-globals.d.ts");
|
|
@@ -908,12 +1121,16 @@ function ensureMaterializedReference(cwd, materializedDir) {
|
|
|
908
1121
|
const tsconfigPath = path8.join(cwd, "tsconfig.json");
|
|
909
1122
|
if (existsSync3(tsconfigPath)) {
|
|
910
1123
|
const tsconfig = JSON.parse(readFileSync7(tsconfigPath, "utf8"));
|
|
911
|
-
tsconfig.compilerOptions
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
1124
|
+
const current = tsconfig.compilerOptions ?? {};
|
|
1125
|
+
const alreadyRepointed = JSON.stringify(current.typeRoots) === JSON.stringify([MATERIALIZED_ROOT]) && JSON.stringify(current.types) === JSON.stringify([surfaceId]);
|
|
1126
|
+
if (!alreadyRepointed) {
|
|
1127
|
+
tsconfig.compilerOptions = {
|
|
1128
|
+
...current,
|
|
1129
|
+
typeRoots: [MATERIALIZED_ROOT],
|
|
1130
|
+
types: [surfaceId]
|
|
1131
|
+
};
|
|
1132
|
+
writeJson2(tsconfigPath, tsconfig);
|
|
1133
|
+
}
|
|
917
1134
|
}
|
|
918
1135
|
ensureGitignoreLine(cwd, `${MATERIALIZED_ROOT}/`);
|
|
919
1136
|
}
|
package/dist/init.d.ts
CHANGED
|
@@ -7,5 +7,6 @@ export interface RunInitResult {
|
|
|
7
7
|
readonly written: string[];
|
|
8
8
|
readonly scriptKind: ScriptKind | null;
|
|
9
9
|
}
|
|
10
|
+
export declare const SCAFFOLD_DEV_DEPS: Record<string, string>;
|
|
10
11
|
export declare function runNewProjectInit(cwd: string, force?: boolean): RunInitResult;
|
|
11
12
|
export declare function runInit(opts: RunInitOptions): RunInitResult;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const MISE_TASKS_TOML = "# managed by @defold-typescript\n[tasks.\"defold-typescript:build\"]\ndescription = \"Build the TypeScript sources with the installed defold-typescript CLI\"\nrun = \"bunx --no-install defold-typescript build\"\n\n# managed by @defold-typescript\n[tasks.\"defold-typescript:watch\"]\ndescription = \"Watch and rebuild the TypeScript sources with the installed defold-typescript CLI\"\nrun = \"bunx --no-install defold-typescript watch\"\n\n# managed by @defold-typescript\n[tasks.\"defold-typescript:upgrade\"]\ndescription = \"Upgrade the defold-typescript CLI to its latest release and re-pin the types dependency\"\nrun = [\"bunx @defold-typescript/cli@latest init --force\", \"bun install\"]\n";
|
|
2
|
+
export declare function mergeMiseToml(existing?: string): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@defold-typescript/cli",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "End-user CLI for scaffolding and building Defold projects written in TypeScript.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"test": "bun test"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@defold-typescript/transpiler": "0.5.
|
|
35
|
-
"@defold-typescript/types": "0.5.
|
|
34
|
+
"@defold-typescript/transpiler": "0.5.4",
|
|
35
|
+
"@defold-typescript/types": "0.5.4"
|
|
36
36
|
}
|
|
37
37
|
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
|
|
3
|
+
export interface EngineTarget {
|
|
4
|
+
readonly enginePlatform: string;
|
|
5
|
+
readonly buildFolder: string;
|
|
6
|
+
readonly executable: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// `enginePlatform` keys the d.defold.com download path; `buildFolder` keys the
|
|
10
|
+
// native-extension build output. They diverge on macOS (`x86_64-darwin` vs
|
|
11
|
+
// `x86_64-osx`), which is why they are tracked separately.
|
|
12
|
+
const PLATFORM_TARGETS: Record<string, EngineTarget> = {
|
|
13
|
+
darwin: { enginePlatform: "x86_64-darwin", buildFolder: "x86_64-osx", executable: "dmengine" },
|
|
14
|
+
linux: { enginePlatform: "x86_64-linux", buildFolder: "x86_64-linux", executable: "dmengine" },
|
|
15
|
+
win32: {
|
|
16
|
+
enginePlatform: "x86_64-win32",
|
|
17
|
+
buildFolder: "x86_64-win32",
|
|
18
|
+
executable: "dmengine.exe",
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const ENGINE_INFO_URL = "https://d.defold.com/stable/info.json";
|
|
23
|
+
const ENGINE_ARCHIVE_BASE = "https://d.defold.com/archive/stable";
|
|
24
|
+
|
|
25
|
+
export const DEBUG_LAUNCHER_REL = ".vscode/defold-debug.ts";
|
|
26
|
+
|
|
27
|
+
export function targetPlatform(platform: NodeJS.Platform): EngineTarget {
|
|
28
|
+
const target = PLATFORM_TARGETS[platform];
|
|
29
|
+
if (!target) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
`defold-typescript debug: unsupported platform "${platform}"; expected one of ${Object.keys(
|
|
32
|
+
PLATFORM_TARGETS,
|
|
33
|
+
).join(", ")}.`,
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
return target;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function engineDownloadUrl(
|
|
40
|
+
sha1: string,
|
|
41
|
+
enginePlatform: string,
|
|
42
|
+
executable: string,
|
|
43
|
+
): string {
|
|
44
|
+
return `${ENGINE_ARCHIVE_BASE}/${sha1}/engine/${enginePlatform}/${executable}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface ResolveEngineOptions {
|
|
48
|
+
readonly cwd: string;
|
|
49
|
+
readonly target: EngineTarget;
|
|
50
|
+
readonly stockPath: string;
|
|
51
|
+
readonly probe: (candidate: string) => boolean;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Prefer the native-extension build engine when it exists; the stock engine is
|
|
55
|
+
// the fallback for projects without native extensions.
|
|
56
|
+
export function resolveEnginePath(opts: ResolveEngineOptions): string {
|
|
57
|
+
const { cwd, target, stockPath, probe } = opts;
|
|
58
|
+
const buildEnginePath = path.join(cwd, "build", target.buildFolder, target.executable);
|
|
59
|
+
return probe(buildEnginePath) ? buildEnginePath : stockPath;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function debugLaunchConfig() {
|
|
63
|
+
return {
|
|
64
|
+
name: "Defold: Debug (TypeScript)",
|
|
65
|
+
type: "lua-local",
|
|
66
|
+
request: "launch",
|
|
67
|
+
stopOnEntry: false,
|
|
68
|
+
verbose: false,
|
|
69
|
+
internalConsoleOptions: "openOnSessionStart",
|
|
70
|
+
program: { command: "bun" },
|
|
71
|
+
args: [DEBUG_LAUNCHER_REL],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export const VSCODE_LAUNCH_CONTENT = {
|
|
76
|
+
version: "0.2.0",
|
|
77
|
+
configurations: [debugLaunchConfig()],
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// The scaffolded launcher embeds the same platform table and archive endpoints
|
|
81
|
+
// the helpers above use, so the self-contained `.vscode/defold-debug.ts` and the
|
|
82
|
+
// unit-tested logic stay in lockstep. It is a Bun script: `process.platform` for
|
|
83
|
+
// the OS, `fetch` for the engine download, `Bun.spawn` with inherited stdio for
|
|
84
|
+
// the run (the pipe Local Lua Debugger attaches over). No shell, no Git Bash.
|
|
85
|
+
function renderDebugLauncher(): string {
|
|
86
|
+
const targets = JSON.stringify(PLATFORM_TARGETS, null, 2);
|
|
87
|
+
return `import { chmodSync, copyFileSync, existsSync, mkdirSync } from "node:fs";
|
|
88
|
+
import * as path from "node:path";
|
|
89
|
+
|
|
90
|
+
// Windows only: paths to OpenAL32.dll and wrap_oal.dll from your Defold SDK
|
|
91
|
+
// (defoldsdk/ext/lib/x86_64-win32/). Leave empty on macOS/Linux.
|
|
92
|
+
const WINDOWS_OPENAL32_PATH = "";
|
|
93
|
+
const WINDOWS_WRAPOAL_PATH = "";
|
|
94
|
+
|
|
95
|
+
interface EngineTarget {
|
|
96
|
+
enginePlatform: string;
|
|
97
|
+
buildFolder: string;
|
|
98
|
+
executable: string;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const PLATFORM_TARGETS: Record<string, EngineTarget> = ${targets};
|
|
102
|
+
|
|
103
|
+
const ENGINE_INFO_URL = "${ENGINE_INFO_URL}";
|
|
104
|
+
const ENGINE_ARCHIVE_BASE = "${ENGINE_ARCHIVE_BASE}";
|
|
105
|
+
|
|
106
|
+
const target = PLATFORM_TARGETS[process.platform];
|
|
107
|
+
if (!target) {
|
|
108
|
+
console.error(\`Unsupported platform: \${process.platform}\`);
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const here = path.dirname(new URL(import.meta.url).pathname);
|
|
113
|
+
const stockEnginePath = path.join(here, target.executable);
|
|
114
|
+
|
|
115
|
+
if (!existsSync(stockEnginePath)) {
|
|
116
|
+
const info = (await (await fetch(ENGINE_INFO_URL)).json()) as { sha1: string };
|
|
117
|
+
const url = \`\${ENGINE_ARCHIVE_BASE}/\${info.sha1}/engine/\${target.enginePlatform}/\${target.executable}\`;
|
|
118
|
+
console.log(\`Fetching \${url}\`);
|
|
119
|
+
const res = await fetch(url);
|
|
120
|
+
if (!res.ok) {
|
|
121
|
+
console.error(\`Engine download failed: \${res.status} \${res.statusText}\`);
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
await Bun.write(stockEnginePath, res);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const buildFolder = path.join("build", target.buildFolder);
|
|
128
|
+
const buildEnginePath = path.join(buildFolder, target.executable);
|
|
129
|
+
let enginePath = existsSync(buildEnginePath) ? buildEnginePath : stockEnginePath;
|
|
130
|
+
|
|
131
|
+
if (process.platform === "win32" && enginePath === buildEnginePath) {
|
|
132
|
+
for (const [src, name] of [
|
|
133
|
+
[WINDOWS_OPENAL32_PATH, "OpenAL32.dll"],
|
|
134
|
+
[WINDOWS_WRAPOAL_PATH, "wrap_oal.dll"],
|
|
135
|
+
] as const) {
|
|
136
|
+
const dest = path.join(buildFolder, name);
|
|
137
|
+
if (src && !existsSync(dest)) {
|
|
138
|
+
copyFileSync(src, dest);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// macOS: a build engine launched in place attaches to the editor process; copy
|
|
144
|
+
// it aside first so it runs standalone.
|
|
145
|
+
if (process.platform === "darwin" && enginePath === buildEnginePath) {
|
|
146
|
+
const tempEngine = path.join(buildFolder, "temp", target.executable);
|
|
147
|
+
mkdirSync(path.dirname(tempEngine), { recursive: true });
|
|
148
|
+
copyFileSync(buildEnginePath, tempEngine);
|
|
149
|
+
enginePath = tempEngine;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (process.platform !== "win32") {
|
|
153
|
+
chmodSync(enginePath, 0o755);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const projectc = path.join("build", "default", "game.projectc");
|
|
157
|
+
console.log(\`Launching \${enginePath} \${projectc}\`);
|
|
158
|
+
const proc = Bun.spawn([enginePath, projectc], {
|
|
159
|
+
stdio: ["inherit", "inherit", "inherit"],
|
|
160
|
+
});
|
|
161
|
+
process.exit(await proc.exited);
|
|
162
|
+
`;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export const DEBUG_LAUNCHER_SOURCE = renderDebugLauncher();
|