isaacscript 2.0.4 → 2.0.7

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 (150) hide show
  1. package/dist/src/commands/init/createMod.js +9 -9
  2. package/dist/src/commands/init/git.js +3 -3
  3. package/dist/src/commands/init/init.js +2 -2
  4. package/dist/src/commands/monitor/monitor.js +13 -13
  5. package/dist/src/commands/monitor/saveDatWriter/saveDatWriter.js +2 -2
  6. package/dist/src/configFile.js +1 -1
  7. package/dist/src/constants.js +12 -9
  8. package/dist/src/file.js +1 -1
  9. package/dist/src/main.js +3 -3
  10. package/dist/src/utils.js +5 -5
  11. package/dist/src/validateInIsaacScriptProject.js +1 -1
  12. package/package.json +11 -6
  13. package/.cspell-base.json +0 -38
  14. package/.cspell-check-unused.json +0 -7
  15. package/.cspell.json +0 -53
  16. package/.eslintrc.js +0 -28
  17. package/.gitattributes +0 -9
  18. package/.github/workflows/ci.yml +0 -47
  19. package/.prettierignore +0 -5
  20. package/.prettierrc.js +0 -42
  21. package/.vscode/extensions.json +0 -9
  22. package/.vscode/settings.json +0 -73
  23. package/build.sh +0 -30
  24. package/check-file-updates.sh +0 -57
  25. package/check-gitignore.sh +0 -26
  26. package/check-orphaned-words.sh +0 -53
  27. package/dist/package.json +0 -50
  28. package/dist/src/checkForWindowsTerminalBugs.js.map +0 -1
  29. package/dist/src/commands/copy/copy.js.map +0 -1
  30. package/dist/src/commands/init/checkIfProjectPathExists.js.map +0 -1
  31. package/dist/src/commands/init/checkModSubdirectory.js.map +0 -1
  32. package/dist/src/commands/init/checkModTargetDirectory.js.map +0 -1
  33. package/dist/src/commands/init/createMod.js.map +0 -1
  34. package/dist/src/commands/init/getModsDir.js.map +0 -1
  35. package/dist/src/commands/init/getProjectPath.js.map +0 -1
  36. package/dist/src/commands/init/git.js.map +0 -1
  37. package/dist/src/commands/init/init.js.map +0 -1
  38. package/dist/src/commands/init/installVSCodeExtensions.js.map +0 -1
  39. package/dist/src/commands/init/promptSaveSlot.js.map +0 -1
  40. package/dist/src/commands/init/promptVSCode.js.map +0 -1
  41. package/dist/src/commands/monitor/copyWatcherMod.js.map +0 -1
  42. package/dist/src/commands/monitor/modDirectorySyncer/modDirectorySyncer.js.map +0 -1
  43. package/dist/src/commands/monitor/monitor.js.map +0 -1
  44. package/dist/src/commands/monitor/notifyGame.js.map +0 -1
  45. package/dist/src/commands/monitor/saveDatWriter/saveDatWriter.js.map +0 -1
  46. package/dist/src/commands/monitor/saveDatWriter/types.js.map +0 -1
  47. package/dist/src/commands/monitor/spawnSaveDatWriter.js.map +0 -1
  48. package/dist/src/commands/monitor/touchWatcherSaveDatFiles.js.map +0 -1
  49. package/dist/src/commands/publish/publish.js.map +0 -1
  50. package/dist/src/configFile.js.map +0 -1
  51. package/dist/src/constants.js.map +0 -1
  52. package/dist/src/exec.js.map +0 -1
  53. package/dist/src/file.js.map +0 -1
  54. package/dist/src/main.js.map +0 -1
  55. package/dist/src/parseArgs.js.map +0 -1
  56. package/dist/src/prompt.js.map +0 -1
  57. package/dist/src/types/Command.js.map +0 -1
  58. package/dist/src/types/Config.js.map +0 -1
  59. package/dist/src/types/GitHubCLIHostsYAML.js.map +0 -1
  60. package/dist/src/utils.js.map +0 -1
  61. package/dist/src/validateInIsaacScriptProject.js.map +0 -1
  62. package/dist/src/validateNodeVersion.js.map +0 -1
  63. package/dist/src/validateOS.js.map +0 -1
  64. package/eslint-debug.sh +0 -11
  65. package/file-templates/dynamic/README.md +0 -3
  66. package/file-templates/dynamic/gitignore +0 -144
  67. package/file-templates/dynamic/main.ts +0 -19
  68. package/file-templates/dynamic/metadata.vdf +0 -6
  69. package/file-templates/dynamic/metadata.xml +0 -10
  70. package/file-templates/dynamic/package.json +0 -19
  71. package/file-templates/static/.cspell-check-unused.json +0 -9
  72. package/file-templates/static/.cspell.json.template +0 -9
  73. package/file-templates/static/.env_template +0 -2
  74. package/file-templates/static/.eslintrc.js +0 -24
  75. package/file-templates/static/.gitattributes +0 -9
  76. package/file-templates/static/.github/workflows/ci.yml +0 -53
  77. package/file-templates/static/.prettierignore +0 -14
  78. package/file-templates/static/.prettierrc.js +0 -42
  79. package/file-templates/static/.vscode/extensions.json +0 -10
  80. package/file-templates/static/.vscode/settings.json +0 -76
  81. package/file-templates/static/LICENSE +0 -674
  82. package/file-templates/static/build.sh +0 -15
  83. package/file-templates/static/check-orphaned-words.sh +0 -53
  84. package/file-templates/static/lint.sh +0 -39
  85. package/file-templates/static/nuke.sh +0 -18
  86. package/file-templates/static/plugins/addCrashDebugStatements.ts +0 -40
  87. package/file-templates/static/plugins/addIsaacScriptCommentHeader.ts +0 -37
  88. package/file-templates/static/plugins/noExtendedEnums.ts +0 -66
  89. package/file-templates/static/publish.sh +0 -10
  90. package/file-templates/static/run.sh +0 -10
  91. package/file-templates/static/src/bundleEntry.ts +0 -10
  92. package/file-templates/static/tsconfig.eslint.json +0 -11
  93. package/file-templates/static/tsconfig.json +0 -33
  94. package/file-templates/static/update.sh +0 -21
  95. package/file-templates/static-alt/.cspell-base.json +0 -38
  96. package/file-templates/static-alt/.cspell-check-unused-base.json +0 -7
  97. package/file-templates/static-alt/.prettierignore-base +0 -5
  98. package/file-templates/static-alt/.prettierrc-base.js +0 -30
  99. package/file-templates/static-alt/.vscode/extensions-typescript.json +0 -9
  100. package/file-templates/static-alt/.vscode/settings-typescript.json +0 -63
  101. package/isaacscript-watcher/.luacheckrc +0 -96
  102. package/isaacscript-watcher/README.md +0 -8
  103. package/isaacscript-watcher/main.lua +0 -270
  104. package/isaacscript-watcher/metadata.xml +0 -7
  105. package/isaacscript-watcher/resources/gfx/logo.anm2 +0 -27
  106. package/isaacscript-watcher/resources/gfx/logo.png +0 -0
  107. package/lint.sh +0 -38
  108. package/misc/logo.png +0 -0
  109. package/misc/mouseover.png +0 -0
  110. package/nuke.sh +0 -18
  111. package/publish.sh +0 -11
  112. package/src/checkForWindowsTerminalBugs.ts +0 -106
  113. package/src/commands/copy/copy.ts +0 -41
  114. package/src/commands/init/checkIfProjectPathExists.ts +0 -34
  115. package/src/commands/init/checkModSubdirectory.ts +0 -20
  116. package/src/commands/init/checkModTargetDirectory.ts +0 -42
  117. package/src/commands/init/createMod.ts +0 -196
  118. package/src/commands/init/getModsDir.ts +0 -107
  119. package/src/commands/init/getProjectPath.ts +0 -111
  120. package/src/commands/init/git.ts +0 -249
  121. package/src/commands/init/init.ts +0 -93
  122. package/src/commands/init/installVSCodeExtensions.ts +0 -47
  123. package/src/commands/init/promptSaveSlot.ts +0 -27
  124. package/src/commands/init/promptVSCode.ts +0 -33
  125. package/src/commands/monitor/copyWatcherMod.ts +0 -54
  126. package/src/commands/monitor/modDirectorySyncer/modDirectorySyncer.ts +0 -67
  127. package/src/commands/monitor/monitor.ts +0 -180
  128. package/src/commands/monitor/notifyGame.ts +0 -59
  129. package/src/commands/monitor/saveDatWriter/saveDatWriter.ts +0 -145
  130. package/src/commands/monitor/saveDatWriter/types.ts +0 -6
  131. package/src/commands/monitor/spawnSaveDatWriter.ts +0 -36
  132. package/src/commands/monitor/touchWatcherSaveDatFiles.ts +0 -20
  133. package/src/commands/publish/publish.ts +0 -392
  134. package/src/configFile.ts +0 -80
  135. package/src/constants.ts +0 -85
  136. package/src/exec.ts +0 -125
  137. package/src/file.ts +0 -235
  138. package/src/main.ts +0 -131
  139. package/src/parseArgs.ts +0 -127
  140. package/src/prompt.ts +0 -109
  141. package/src/types/Command.ts +0 -3
  142. package/src/types/Config.ts +0 -23
  143. package/src/types/GitHubCLIHostsYAML.ts +0 -7
  144. package/src/utils.ts +0 -92
  145. package/src/validateInIsaacScriptProject.ts +0 -35
  146. package/src/validateNodeVersion.ts +0 -29
  147. package/src/validateOS.ts +0 -20
  148. package/tsconfig.eslint.json +0 -11
  149. package/tsconfig.json +0 -21
  150. package/update.sh +0 -21
@@ -1,93 +0,0 @@
1
- import chalk from "chalk";
2
- import commandExists from "command-exists";
3
- import path from "path";
4
- import { CWD, PROJECT_NAME } from "../../constants";
5
- import { checkIfProjectPathExists } from "./checkIfProjectPathExists";
6
- import { checkModSubdirectory } from "./checkModSubdirectory";
7
- import { checkModTargetDirectory } from "./checkModTargetDirectory";
8
- import { createMod } from "./createMod";
9
- import { getModsDir } from "./getModsDir";
10
- import { getProjectPath } from "./getProjectPath";
11
- import { promptGitHubRepoOrGitRemoteURL } from "./git";
12
- import { installVSCodeExtensions } from "./installVSCodeExtensions";
13
- import { promptSaveSlot } from "./promptSaveSlot";
14
- import { promptVSCode } from "./promptVSCode";
15
-
16
- export async function init(argv: Record<string, unknown>): Promise<void> {
17
- const skipNPMInstall = argv["skipNpmInstall"] === true;
18
- const useCurrentDir = argv["useCurrentDir"] === true;
19
- const verbose = argv["verbose"] === true;
20
- const vscode = argv["vscode"] === true;
21
- const yes = argv["yes"] === true;
22
- const forceName = argv["forceName"] === true;
23
-
24
- // Prompt the end-user for some information (and validate it as we go)
25
- const [projectPath, createNewDir] = await getProjectPath(
26
- argv,
27
- useCurrentDir,
28
- yes,
29
- forceName,
30
- );
31
- await checkIfProjectPathExists(projectPath, yes, verbose);
32
- const modsDirectory = await getModsDir(argv, verbose);
33
- checkModSubdirectory(projectPath, modsDirectory);
34
- const projectName = path.basename(projectPath);
35
- await checkModTargetDirectory(modsDirectory, projectName, yes, verbose);
36
- const saveSlot = await promptSaveSlot(argv, yes);
37
- const gitRemoteURL = await promptGitHubRepoOrGitRemoteURL(
38
- projectName,
39
- yes,
40
- verbose,
41
- );
42
-
43
- // Now that we have asked the user all of the questions we need, we can create the project
44
- createMod(
45
- projectName,
46
- projectPath,
47
- createNewDir,
48
- modsDirectory,
49
- saveSlot,
50
- gitRemoteURL,
51
- skipNPMInstall,
52
- verbose,
53
- );
54
-
55
- await openVSCode(projectPath, vscode, verbose);
56
- printFinishMessage(projectPath, projectName);
57
- }
58
-
59
- async function openVSCode(
60
- projectPath: string,
61
- vscode: boolean,
62
- verbose: boolean,
63
- ) {
64
- const VSCodeCommand = getVSCodeCommand();
65
- if (VSCodeCommand === null) {
66
- console.log(
67
- 'VSCode does not seem to be installed. (The "code" command is not in the path.) Skipping VSCode-related things.',
68
- );
69
- return;
70
- }
71
-
72
- installVSCodeExtensions(projectPath, VSCodeCommand, verbose);
73
- await promptVSCode(projectPath, VSCodeCommand, vscode, verbose);
74
- }
75
-
76
- function getVSCodeCommand() {
77
- for (const VSCodeCommand of ["code", "codium", "code-oss", "code-insiders"]) {
78
- if (commandExists.sync(VSCodeCommand)) {
79
- return VSCodeCommand;
80
- }
81
- }
82
-
83
- return null;
84
- }
85
-
86
- function printFinishMessage(projectPath: string, projectName: string) {
87
- let commandsToType = "";
88
- if (projectPath !== CWD) {
89
- commandsToType += `"${chalk.green(`cd ${projectName}`)}" and `;
90
- }
91
- commandsToType += `"${chalk.green("npx isaacscript")}"`;
92
- console.log(`Now, start ${PROJECT_NAME} by typing ${commandsToType}.`);
93
- }
@@ -1,47 +0,0 @@
1
- import chalk from "chalk";
2
- import * as JSONC from "jsonc-parser";
3
- import path from "path";
4
- import { execShell } from "../../exec";
5
- import * as file from "../../file";
6
- import { error } from "../../utils";
7
-
8
- export function installVSCodeExtensions(
9
- projectPath: string,
10
- VSCodeCommand: string,
11
- verbose: boolean,
12
- ): void {
13
- const extensions = getExtensionsFromJSON(projectPath, verbose);
14
- for (const extensionName of extensions) {
15
- execShell(VSCodeCommand, ["--install-extension", extensionName], verbose);
16
- }
17
- }
18
-
19
- interface ExtensionsJSON {
20
- recommendations: string[];
21
- }
22
-
23
- function getExtensionsFromJSON(projectPath: string, verbose: boolean) {
24
- const extensionsJSONPath = path.join(
25
- projectPath,
26
- ".vscode",
27
- "extensions.json",
28
- );
29
-
30
- if (!file.exists(extensionsJSONPath, verbose)) {
31
- return [];
32
- }
33
-
34
- const extensionsJSONRaw = file.read(extensionsJSONPath, verbose);
35
-
36
- let extensionsJSON: ExtensionsJSON;
37
- try {
38
- extensionsJSON = JSONC.parse(extensionsJSONRaw) as ExtensionsJSON;
39
- } catch (err) {
40
- error(
41
- `Failed to parse the "${chalk.green(extensionsJSONPath)}" file:`,
42
- err,
43
- );
44
- }
45
-
46
- return extensionsJSON.recommendations;
47
- }
@@ -1,27 +0,0 @@
1
- import { getInputInt } from "../../prompt";
2
- import { error } from "../../utils";
3
-
4
- export async function promptSaveSlot(
5
- argv: Record<string, unknown>,
6
- yes: boolean,
7
- ): Promise<number> {
8
- if (argv["saveSlot"] !== undefined) {
9
- // They specified the "--save-slot" command-line flag, so there is no need to prompt the user
10
- // for it.
11
- return argv["saveSlot"] as number; // yargs converts this to a number
12
- }
13
-
14
- if (yes) {
15
- return 1;
16
- }
17
-
18
- const saveSlot = await getInputInt(
19
- "In-game, will you test your mod on save slot 1, 2, or 3?",
20
- );
21
-
22
- if (saveSlot !== 1 && saveSlot !== 2 && saveSlot !== 3) {
23
- error("Error: You must choose a number between 1 and 3.");
24
- }
25
-
26
- return saveSlot;
27
- }
@@ -1,33 +0,0 @@
1
- import path from "path";
2
- import { MAIN_TS } from "../../constants";
3
- import { execShell } from "../../exec";
4
- import { getInputYesNo } from "../../prompt";
5
-
6
- export async function promptVSCode(
7
- projectPath: string,
8
- VSCodeCommand: string,
9
- vscode: boolean,
10
- verbose: boolean,
11
- ): Promise<void> {
12
- if (vscode) {
13
- // They supplied the "--vscode" command-line flag, so there is no need to prompt the user.
14
- openVSCode(projectPath, VSCodeCommand, verbose);
15
- return;
16
- }
17
-
18
- const shouldOpenVSCode = await getInputYesNo(
19
- "Do you want to open your new project in VSCode now?",
20
- );
21
- if (shouldOpenVSCode) {
22
- openVSCode(projectPath, VSCodeCommand, verbose);
23
- }
24
- }
25
-
26
- function openVSCode(
27
- projectPath: string,
28
- VSCodeCommand: string,
29
- verbose: boolean,
30
- ) {
31
- const MAIN_TS_PATH = path.join(projectPath, "src", MAIN_TS);
32
- execShell(VSCodeCommand, [projectPath, MAIN_TS_PATH], verbose);
33
- }
@@ -1,54 +0,0 @@
1
- import path from "path";
2
- import {
3
- DISABLE_IT_FILE,
4
- MAIN_LUA,
5
- WATCHER_MOD_NAME,
6
- WATCHER_MOD_SOURCE_PATH,
7
- } from "../../constants";
8
- import * as file from "../../file";
9
- import { Config } from "../../types/Config";
10
-
11
- export function copyWatcherMod(config: Config, verbose: boolean): void {
12
- // Check to see if this mod was disabled.
13
- const watcherModPath = path.join(config.modsDirectory, WATCHER_MOD_NAME);
14
- const disableItPath = path.join(watcherModPath, DISABLE_IT_FILE);
15
- const watcherModDisabled = file.exists(disableItPath, verbose);
16
-
17
- // Delete and re-copy the watcher mod every time IsaacScript starts. This ensures that it is
18
- // always the latest version.
19
- if (file.exists(watcherModPath, verbose)) {
20
- file.deleteFileOrDirectory(watcherModPath, verbose);
21
- }
22
-
23
- file.copy(WATCHER_MOD_SOURCE_PATH, watcherModPath, verbose);
24
-
25
- if (watcherModDisabled) {
26
- // Since we deleted the directory, the "disable.it" file was deleted. Restore it.
27
- file.write(disableItPath, "", verbose);
28
- }
29
-
30
- // By default, the IsaacScript watcher mod automatically restarts the game, so we only need to
31
- // disable it if the config option is explicitly set to false.
32
- if (config.enableIsaacScriptWatcherAutoRestart === false) {
33
- disableIsaacScriptWatcherAutomaticRestart(watcherModPath, verbose);
34
- }
35
-
36
- // If we copied a new version of the watcher mod into place, but the user currently has the game
37
- // open, then the old version will stay loaded. However, if the watcher mod reloads itself, the
38
- // game will crash, so there is no automated solution for this.
39
- }
40
-
41
- function disableIsaacScriptWatcherAutomaticRestart(
42
- watcherModPath: string,
43
- verbose: boolean,
44
- ) {
45
- const mainLuaPath = path.join(watcherModPath, MAIN_LUA);
46
- const mainLua = file.read(mainLuaPath, verbose);
47
-
48
- const modifiedMainLua = mainLua.replace(
49
- "local RESTART_GAME_ON_RECOMPILATION = true",
50
- "local RESTART_GAME_ON_RECOMPILATION = false",
51
- );
52
-
53
- file.write(mainLuaPath, modifiedMainLua, verbose);
54
- }
@@ -1,67 +0,0 @@
1
- import syncDirectory from "sync-directory";
2
- import { FILE_SYNCED_MESSAGE } from "../../../constants";
3
-
4
- const SUBPROCESS_NAME = "directory syncer";
5
- const BASE_ARGV_LENGTH = 2;
6
-
7
- let modSourcePath: string;
8
- let modTargetPath: string;
9
-
10
- init();
11
-
12
- function init() {
13
- const firstArg = process.argv[BASE_ARGV_LENGTH];
14
- if (firstArg === undefined) {
15
- throw new Error(
16
- `The ${SUBPROCESS_NAME} process did not get a valid first argument.`,
17
- );
18
- }
19
-
20
- const secondArg = process.argv[BASE_ARGV_LENGTH + 1];
21
- if (secondArg === undefined) {
22
- throw new Error(
23
- `The ${SUBPROCESS_NAME} process did not get the right amount of arguments.`,
24
- );
25
- }
26
-
27
- modSourcePath = firstArg;
28
- modTargetPath = secondArg;
29
-
30
- syncDirectory(modSourcePath, modTargetPath, {
31
- watch: true,
32
- type: "copy",
33
- afterEachSync,
34
- onError,
35
- chokidarWatchOptions: {
36
- awaitWriteFinish: {
37
- stabilityThreshold: 1000,
38
- },
39
- },
40
- });
41
- }
42
-
43
- function afterEachSync(params?: {
44
- eventType: string;
45
- nodeType: string;
46
- relativePath: string;
47
- srcPath: string;
48
- targetPath: string;
49
- }) {
50
- if (params === undefined) {
51
- return;
52
- }
53
-
54
- if (params.eventType !== "init:copy") {
55
- send(`${FILE_SYNCED_MESSAGE} ${params.relativePath}`);
56
- }
57
- }
58
-
59
- function onError(err: Error) {
60
- send(`The directory syncer encountered an error: ${err}`);
61
- }
62
-
63
- function send(msg: string) {
64
- if (process.send !== undefined) {
65
- process.send(msg);
66
- }
67
- }
@@ -1,180 +0,0 @@
1
- import chalk from "chalk";
2
- import { fork, spawn } from "child_process";
3
- import * as JSONC from "jsonc-parser";
4
- import path from "path";
5
- import {
6
- CWD,
7
- FILE_SYNCED_MESSAGE,
8
- MAIN_LUA,
9
- MOD_SOURCE_PATH,
10
- PROJECT_NAME,
11
- TSCONFIG_PATH,
12
- } from "../../constants";
13
- import * as file from "../../file";
14
- import { Config } from "../../types/Config";
15
- import { error, getModTargetDirectoryName } from "../../utils";
16
- import { copyWatcherMod } from "./copyWatcherMod";
17
- import * as notifyGame from "./notifyGame";
18
- import { spawnSaveDatWriter } from "./spawnSaveDatWriter";
19
- import { touchWatcherSaveDatFiles } from "./touchWatcherSaveDatFiles";
20
-
21
- export function monitor(argv: Record<string, unknown>, config: Config): void {
22
- const verbose = argv["verbose"] === true;
23
-
24
- // If they specified some command-line flags, override the values found in the config file
25
- if (argv["modsDirectory"] !== undefined) {
26
- config.modsDirectory = argv["modsDirectory"] as string; // eslint-disable-line no-param-reassign
27
- }
28
- if (argv["saveSlot"] !== undefined) {
29
- config.saveSlot = argv["saveSlot"] as number; // eslint-disable-line no-param-reassign
30
- }
31
-
32
- // Read the "tsconfig.json" file
33
- const tsConfigInclude = getFirstTSConfigIncludePath(verbose);
34
- const resolvedIncludePath = path.resolve(CWD, tsConfigInclude);
35
- const modTargetDirectoryName = getModTargetDirectoryName(config);
36
- const modTargetPath = path.join(config.modsDirectory, modTargetDirectoryName);
37
-
38
- // Prepare the IsaacScript watcher mod
39
- copyWatcherMod(config, verbose);
40
- touchWatcherSaveDatFiles(config, verbose);
41
-
42
- // Delete and re-copy the mod every time IsaacScript starts. This ensures that it is always the
43
- // latest version.
44
- if (file.exists(modTargetPath, verbose)) {
45
- file.deleteFileOrDirectory(modTargetPath, true);
46
- }
47
-
48
- // Subprocess #1 - The "save#.dat" file writer
49
- spawnSaveDatWriter(config);
50
-
51
- // Subprocess #2 - The mod directory syncer
52
- spawnModDirectorySyncer(config);
53
-
54
- // Subprocess #3 - tstl --watch (to automatically convert TypeScript to Lua)
55
- spawnTSTLWatcher();
56
-
57
- // Also, start constantly pinging the watcher mod
58
- setInterval(() => {
59
- notifyGame.ping();
60
- }, 1000); // Every second
61
-
62
- console.log("Automatically monitoring the following for changes:");
63
- console.log(
64
- `1) your TypeScript code: ${chalk.green(resolvedIncludePath)}`,
65
- );
66
- console.log(`2) the source mod directory: ${chalk.green(MOD_SOURCE_PATH)}`);
67
- console.log("");
68
- console.log(`Copying files to: ${chalk.green(modTargetPath)}`);
69
- console.log("");
70
- // (the process will now continue indefinitely for as long as the subprocesses exist)
71
- }
72
-
73
- function spawnModDirectorySyncer(config: Config) {
74
- const processName = "modDirectorySyncer";
75
- const processDescription = "Directory syncer";
76
- const processPath = path.join(__dirname, processName, processName);
77
- const modTargetName = getModTargetDirectoryName(config);
78
- const modTargetPath = path.join(config.modsDirectory, modTargetName);
79
- const directorySycner = fork(processPath, [MOD_SOURCE_PATH, modTargetPath]);
80
-
81
- directorySycner.on("message", (msg: string) => {
82
- notifyGame.msg(msg);
83
-
84
- // If the "main.lua" file was successfully copied over, we also have to tell isaacscript-watcher
85
- // to reload the mod. Look for something like: "File synced: \main.lua"
86
- if (msg === `${FILE_SYNCED_MESSAGE} ${path.sep}${MAIN_LUA}`) {
87
- notifyGame.command(`luamod ${modTargetName}`);
88
- notifyGame.command("restart");
89
- notifyGame.msg("Reloaded the mod.");
90
- }
91
- });
92
-
93
- directorySycner.on("close", (code: number | null) => {
94
- error(`Error: ${processDescription} subprocess closed with code: ${code}`);
95
- });
96
-
97
- directorySycner.on("exit", (code: number | null) => {
98
- error(`Error: ${processDescription} subprocess exited with code: ${code}`);
99
- });
100
- }
101
-
102
- function spawnTSTLWatcher() {
103
- const processDescription = "tstl";
104
- const tstl = spawn("npx", ["tstl", "--watch", "--preserveWatchOutput"], {
105
- shell: true,
106
- });
107
-
108
- tstl.stdout.on("data", (data: Buffer[]) => {
109
- const msg = data.toString().trim();
110
- if (msg.includes("Starting compilation in watch mode...")) {
111
- const newMsg = `${PROJECT_NAME} is now watching for changes.`;
112
- notifyGame.msg(newMsg);
113
- } else if (
114
- msg.includes("File change detected. Starting incremental compilation...")
115
- ) {
116
- const newMsg = "TypeScript change detected. Compiling...";
117
- notifyGame.msg(newMsg);
118
- } else if (msg.includes("Found 0 errors. Watching for file changes.")) {
119
- const newMsg = "Compilation successful.";
120
- notifyGame.msg(newMsg);
121
- } else {
122
- notifyGame.msg(msg);
123
- }
124
- });
125
-
126
- tstl.stderr.on("data", (data: Buffer[]) => {
127
- const msg = data.toString().trim();
128
- if (msg === "^C") {
129
- // Hide the line that appears when you cancel the program with Ctrl + c
130
- return;
131
- }
132
- notifyGame.msg(`Error: ${msg}`);
133
- });
134
-
135
- tstl.on("close", (code) => {
136
- error(`Error: ${processDescription} subprocess exited with code: ${code}`);
137
- });
138
-
139
- tstl.on("exit", (code) => {
140
- error(`Error: ${processDescription} subprocess exited with code: ${code}`);
141
- });
142
- }
143
-
144
- function getFirstTSConfigIncludePath(verbose: boolean): string {
145
- const tsConfigRaw = file.read(TSCONFIG_PATH, verbose);
146
- let tsConfig: Record<string, string[]>;
147
- try {
148
- tsConfig = JSONC.parse(tsConfigRaw) as Record<string, string[]>;
149
- } catch (err) {
150
- error(`Failed to parse "${chalk.green(TSCONFIG_PATH)}":`, err);
151
- }
152
-
153
- const include = tsConfig["include"];
154
- if (include === undefined) {
155
- error(
156
- `Your "${chalk.green(
157
- TSCONFIG_PATH,
158
- )}" file does not have an "include" property, which is surely a mistake. Delete the file and re-run ${PROJECT_NAME}.`,
159
- );
160
- }
161
-
162
- if (!Array.isArray(include)) {
163
- error(
164
- `Your "${chalk.green(
165
- TSCONFIG_PATH,
166
- )}" file has an "include" property that is not an array, which is surely a mistake. Delete the file and re-run ${PROJECT_NAME}.`,
167
- );
168
- }
169
-
170
- const firstInclude = include[0];
171
- if (firstInclude === undefined) {
172
- error(
173
- `Your "${chalk.green(
174
- TSCONFIG_PATH,
175
- )}" file has an empty "include" property, which is surely a mistake. Delete the file and re-run ${PROJECT_NAME}.`,
176
- );
177
- }
178
-
179
- return firstInclude;
180
- }
@@ -1,59 +0,0 @@
1
- import chalk from "chalk";
2
- import { getTime } from "../../utils";
3
- import { sendMsgToSaveDatWriter } from "./spawnSaveDatWriter";
4
-
5
- export function msg(data: string): void {
6
- const formattedData = data
7
- .replace(/\r\n/g, "\n") // Replace Windows newlines with Unix newlines
8
- .trim(); // Trim whitespace
9
-
10
- for (const line of formattedData.split("\n")) {
11
- const trimmedLine = line.trim();
12
- if (trimmedLine === "") {
13
- continue;
14
- }
15
-
16
- // Ignore the final message from tstl upon exiting the program.
17
- if (trimmedLine === "Terminate batch job (Y/N)?") {
18
- return;
19
- }
20
-
21
- // Add a time prefix.
22
- const formattedLine = `[${getTime()}] ${trimmedLine}`;
23
-
24
- sendMsgToSaveDatWriter({
25
- type: "msg",
26
- data: formattedLine,
27
- });
28
-
29
- // We also print the message to standard out so that the end-user can choose between reading
30
- // tstl errors from the IsaacScript terminal window or from looking at the in-game output.
31
- printMsgToStandardOut(formattedLine);
32
- }
33
- }
34
-
35
- function printMsgToStandardOut(data: string) {
36
- let coloredData = data;
37
-
38
- if (data.match(/Compilation successful./g) !== null) {
39
- coloredData = chalk.green(data);
40
- } else if (data.match(/error/g) !== null) {
41
- coloredData = chalk.red(data);
42
- }
43
-
44
- console.log(coloredData);
45
- }
46
-
47
- export function command(data: string): void {
48
- sendMsgToSaveDatWriter({
49
- type: "command",
50
- data,
51
- });
52
- }
53
-
54
- export function ping(): void {
55
- sendMsgToSaveDatWriter({
56
- type: "ping",
57
- data: "",
58
- });
59
- }