@idajs/create-mod 0.2.11 → 0.2.15-dev.37
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 +6 -0
- package/_project.config/AGENTS.md +25 -0
- package/_project.config/CLAUDE.md +1 -0
- package/_project.config/archive.js +107 -0
- package/_project.config/build.js +22 -37
- package/_project.config/package.template.json +14 -14
- package/_project.config/project.js +120 -0
- package/_project.config/remote.js +157 -0
- package/_project.config/run-remote.js +75 -0
- package/_project.config/start.js +60 -0
- package/_project.config/sync.js +21 -60
- package/_project.config/watch.js +90 -24
- package/index.js +145 -19
- package/install.js +160 -45
- package/package.json +1 -1
package/_project.config/sync.js
CHANGED
|
@@ -1,88 +1,50 @@
|
|
|
1
1
|
const { execSync } = require("child_process");
|
|
2
2
|
const path = require("path");
|
|
3
3
|
const fs = require("fs");
|
|
4
|
-
const os = require("os");
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
function getIdaJsPath() {
|
|
8
|
-
// Try local config first, then user home config
|
|
9
|
-
const configPaths = [path.join(__dirname, ".idajs.json"), path.join(os.homedir(), ".idajs.json")];
|
|
5
|
+
const { getArgValue, getIdaJsPath, getPackageName, isTypeScriptProject } = require("./project");
|
|
10
6
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
15
|
-
if (config.installDir) {
|
|
16
|
-
return config.installDir;
|
|
17
|
-
}
|
|
18
|
-
} catch (err) {
|
|
19
|
-
// Ignore parse errors and try next config
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// Get package name from command line argument
|
|
28
|
-
const packageName = process.argv[2];
|
|
29
|
-
|
|
30
|
-
if (!packageName) {
|
|
31
|
-
console.error("Error: Package name is required as an argument");
|
|
32
|
-
console.error("Usage: node sync.js <package-name>");
|
|
33
|
-
process.exit(1);
|
|
34
|
-
}
|
|
7
|
+
const args = process.argv.slice(2);
|
|
8
|
+
const packageName = getPackageName();
|
|
9
|
+
const targetRoot = getArgValue("--target-root", args);
|
|
35
10
|
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
if (!
|
|
39
|
-
|
|
40
|
-
console.error("Please build IdaJS first or create .idajs.json with 'installDir' property.");
|
|
41
|
-
process.exit(1);
|
|
42
|
-
}
|
|
11
|
+
let resolvedTargetRoot = targetRoot;
|
|
12
|
+
const typeScriptProject = isTypeScriptProject();
|
|
13
|
+
if (!resolvedTargetRoot) {
|
|
14
|
+
const idaJsPath = getIdaJsPath();
|
|
43
15
|
|
|
44
|
-
if (!
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const isTypeScriptProject = (() => {
|
|
51
|
-
// Check if tsconfig.json exists
|
|
52
|
-
if (!fs.existsSync("tsconfig.json")) {
|
|
53
|
-
return false;
|
|
16
|
+
if (!idaJsPath) {
|
|
17
|
+
console.error("Error: .idajs.json not found in current directory or user home directory.");
|
|
18
|
+
console.error("Please build IdaJS first or create .idajs.json with 'installDir' property.");
|
|
19
|
+
process.exit(1);
|
|
54
20
|
}
|
|
55
21
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
22
|
+
if (!fs.existsSync(idaJsPath)) {
|
|
23
|
+
console.error(`Error: IdaJS installation directory does not exist: ${idaJsPath}`);
|
|
24
|
+
console.error("Please build IdaJS first.");
|
|
25
|
+
process.exit(1);
|
|
59
26
|
}
|
|
60
27
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
})();
|
|
28
|
+
resolvedTargetRoot = path.join(idaJsPath, "GameRun", "mods");
|
|
29
|
+
}
|
|
64
30
|
|
|
65
|
-
const targetBase = path.join(
|
|
31
|
+
const targetBase = path.join(resolvedTargetRoot, packageName);
|
|
66
32
|
const deleteExcludeArgs = '--delete-exclude "*.ida" --delete-exclude "*.md5"';
|
|
67
33
|
|
|
68
34
|
console.log(`Syncing ${packageName}...`);
|
|
69
35
|
|
|
70
|
-
|
|
71
|
-
if (isTypeScriptProject) {
|
|
36
|
+
if (typeScriptProject) {
|
|
72
37
|
console.log("TypeScript project detected, compiling...");
|
|
73
38
|
|
|
74
|
-
// Clean dist folder
|
|
75
39
|
if (fs.existsSync("dist")) {
|
|
76
40
|
console.log("Cleaning dist folder...");
|
|
77
41
|
fs.rmSync("dist", { recursive: true, force: true });
|
|
78
42
|
}
|
|
79
43
|
|
|
80
|
-
// Compile TypeScript
|
|
81
44
|
execSync("tsc", { stdio: "inherit" });
|
|
82
45
|
console.log("Compilation complete!");
|
|
83
46
|
}
|
|
84
47
|
|
|
85
|
-
// Sync media folder if it exists
|
|
86
48
|
if (fs.existsSync("media")) {
|
|
87
49
|
const mediaSyncCmd = `idasync media "${path.join(targetBase, "media")}" ${deleteExcludeArgs}`;
|
|
88
50
|
console.log(`Running: ${mediaSyncCmd}`);
|
|
@@ -91,8 +53,7 @@ if (fs.existsSync("media")) {
|
|
|
91
53
|
console.log("No media folder found, skipping media sync");
|
|
92
54
|
}
|
|
93
55
|
|
|
94
|
-
|
|
95
|
-
const sourceFolder = isTypeScriptProject ? "dist" : "src";
|
|
56
|
+
const sourceFolder = typeScriptProject ? "dist" : "src";
|
|
96
57
|
const srcSyncCmd = `idasync "${sourceFolder}" "${targetBase}" ${deleteExcludeArgs} --delete-exclude "media/*"`;
|
|
97
58
|
console.log(`Running: ${srcSyncCmd}`);
|
|
98
59
|
execSync(srcSyncCmd, { stdio: "inherit" });
|
package/_project.config/watch.js
CHANGED
|
@@ -1,54 +1,121 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Watches for file changes in the src/ and media/ directories
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Watches for file changes in the src/ and media/ directories.
|
|
3
|
+
* Local mode syncs directly into the game mod directory.
|
|
4
|
+
* Remote mode stages the mod into a session temp folder and uploads a full zip.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
const chokidar = require("chokidar");
|
|
8
|
-
const {
|
|
8
|
+
const { exec } = require("child_process");
|
|
9
9
|
const { promisify } = require("util");
|
|
10
10
|
|
|
11
|
+
const { getArgValue, parseServerAddress } = require("./project");
|
|
12
|
+
const { getRemoteGameStatus, killRemoteGame, stageAndZip, stageMod, uploadMod } = require("./remote");
|
|
13
|
+
|
|
11
14
|
const execAsync = promisify(exec);
|
|
12
15
|
const PROC_NAME = "LBA2.exe";
|
|
16
|
+
const args = process.argv.slice(2);
|
|
17
|
+
const serverArg = getArgValue("--server", args);
|
|
18
|
+
const sessionRoot = getArgValue("--session-root", args);
|
|
19
|
+
const server = serverArg ? parseServerAddress(serverArg) : null;
|
|
20
|
+
|
|
21
|
+
if (server && !sessionRoot) {
|
|
22
|
+
console.error("Remote watch mode requires --session-root <path>.");
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let syncing = false;
|
|
27
|
+
let syncQueued = false;
|
|
13
28
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
29
|
+
async function runLocalSync() {
|
|
30
|
+
if (syncing) {
|
|
31
|
+
syncQueued = true;
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
syncing = true;
|
|
36
|
+
do {
|
|
37
|
+
syncQueued = false;
|
|
38
|
+
try {
|
|
39
|
+
await stageMod();
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.error(error.message);
|
|
42
|
+
}
|
|
43
|
+
} while (syncQueued);
|
|
44
|
+
syncing = false;
|
|
19
45
|
}
|
|
20
46
|
|
|
21
|
-
|
|
47
|
+
async function runRemoteSync() {
|
|
48
|
+
if (syncing) {
|
|
49
|
+
syncQueued = true;
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
syncing = true;
|
|
54
|
+
do {
|
|
55
|
+
syncQueued = false;
|
|
56
|
+
try {
|
|
57
|
+
const { modName, zipPath } = await stageAndZip(sessionRoot);
|
|
58
|
+
await uploadMod(server, modName, zipPath);
|
|
59
|
+
} catch (error) {
|
|
60
|
+
console.error(error.message);
|
|
61
|
+
}
|
|
62
|
+
} while (syncQueued);
|
|
63
|
+
syncing = false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const watcher = chokidar.watch(["src/**/*.js", "src/**/*.ts", "media/**/*.png"], {
|
|
22
67
|
ignoreInitial: true,
|
|
23
68
|
});
|
|
24
69
|
|
|
25
|
-
watcher.on("all", () =>
|
|
70
|
+
watcher.on("all", async () => {
|
|
71
|
+
if (server) {
|
|
72
|
+
await runRemoteSync();
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
26
75
|
|
|
27
|
-
|
|
76
|
+
await runLocalSync();
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
async function isLocalProcRunning() {
|
|
28
80
|
try {
|
|
29
81
|
const { stdout } = await execAsync(
|
|
30
|
-
`
|
|
82
|
+
`tasklist /FI "IMAGENAME eq ${PROC_NAME}" /FO CSV /NH`,
|
|
31
83
|
{
|
|
32
84
|
timeout: 5000,
|
|
33
85
|
}
|
|
34
86
|
);
|
|
35
|
-
return stdout.
|
|
87
|
+
return stdout.toLowerCase().includes(`"${PROC_NAME.toLowerCase()}"`);
|
|
36
88
|
} catch (error) {
|
|
37
|
-
// Process not found or command failed
|
|
38
89
|
return false;
|
|
39
90
|
}
|
|
40
91
|
}
|
|
41
92
|
|
|
42
|
-
async function
|
|
93
|
+
async function killLocalGameProc() {
|
|
43
94
|
try {
|
|
44
|
-
await execAsync(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
} catch (e) {
|
|
48
|
-
// Process may already be stopped
|
|
95
|
+
await execAsync(`taskkill /IM "${PROC_NAME}" /F /T`);
|
|
96
|
+
} catch (error) {
|
|
97
|
+
// Process may already be stopped.
|
|
49
98
|
}
|
|
50
99
|
}
|
|
51
100
|
|
|
101
|
+
async function isProcRunning() {
|
|
102
|
+
if (server) {
|
|
103
|
+
const status = await getRemoteGameStatus(server);
|
|
104
|
+
return Boolean(status && status.running);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return isLocalProcRunning();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function killGameProc() {
|
|
111
|
+
if (server) {
|
|
112
|
+
await killRemoteGame(server);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
await killLocalGameProc();
|
|
117
|
+
}
|
|
118
|
+
|
|
52
119
|
const interval = setInterval(async () => {
|
|
53
120
|
try {
|
|
54
121
|
const alive = await isProcRunning();
|
|
@@ -59,12 +126,11 @@ const interval = setInterval(async () => {
|
|
|
59
126
|
await watcher.close();
|
|
60
127
|
process.exit(0);
|
|
61
128
|
}
|
|
62
|
-
} catch (
|
|
63
|
-
|
|
129
|
+
} catch (error) {
|
|
130
|
+
console.error(error.message);
|
|
64
131
|
}
|
|
65
132
|
}, 1000);
|
|
66
133
|
|
|
67
|
-
// Ctrl+C cleanup
|
|
68
134
|
process.on("SIGINT", async () => {
|
|
69
135
|
console.log("Caught interrupt signal. Exiting watcher.");
|
|
70
136
|
|
package/index.js
CHANGED
|
@@ -4,6 +4,7 @@ const fs = require("fs");
|
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const os = require("os");
|
|
6
6
|
const { execSync } = require("child_process");
|
|
7
|
+
const readline = require("readline");
|
|
7
8
|
const IdaSync = require("@idajs/sync");
|
|
8
9
|
|
|
9
10
|
// Parse command line arguments
|
|
@@ -26,7 +27,9 @@ const idajsDir = getArgValue("--idajs-dir") || getArgValue("--idajs");
|
|
|
26
27
|
const useTypeScript = args.includes("--typescript") || args.includes("--ts");
|
|
27
28
|
const useJavaScript = args.includes("--javascript") || args.includes("--js");
|
|
28
29
|
const skipInstall = args.includes("--skip-install");
|
|
30
|
+
const updateMode = args.includes("--update");
|
|
29
31
|
const helpRequested = args.includes("--help") || args.includes("-h");
|
|
32
|
+
const requiredUpdatePackages = ["@idajs/types", "@idajs/sync"];
|
|
30
33
|
|
|
31
34
|
// Show help if requested
|
|
32
35
|
if (helpRequested) {
|
|
@@ -41,7 +44,8 @@ Options:
|
|
|
41
44
|
--idajs-dir, --idajs <path> IdaJS installation directory
|
|
42
45
|
--typescript, --ts Use TypeScript
|
|
43
46
|
--javascript, --js Use JavaScript
|
|
44
|
-
--
|
|
47
|
+
--update Refresh scaffolder-managed files in the current mod folder
|
|
48
|
+
--skip-install Skip npm install (and type update in --update mode)
|
|
45
49
|
-h, --help Show this help message
|
|
46
50
|
|
|
47
51
|
Examples:
|
|
@@ -50,6 +54,7 @@ Examples:
|
|
|
50
54
|
npx @idajs/create-mod my-mod --typescript
|
|
51
55
|
npx @idajs/create-mod my-mod --dir ./projects/my-mod --idajs C:/Projects/idajs --js
|
|
52
56
|
npx @idajs/create-mod my-mod --skip-install
|
|
57
|
+
npx @idajs/create-mod --update
|
|
53
58
|
`);
|
|
54
59
|
process.exit(0);
|
|
55
60
|
}
|
|
@@ -70,9 +75,124 @@ function getIdaJsDirFromConfig() {
|
|
|
70
75
|
return null;
|
|
71
76
|
}
|
|
72
77
|
|
|
78
|
+
function normalizeServerAddress(value) {
|
|
79
|
+
const trimmed = String(value || "").trim();
|
|
80
|
+
const input = trimmed.includes("://") ? trimmed : `http://${trimmed}`;
|
|
81
|
+
const url = new URL(input);
|
|
82
|
+
return `${url.hostname}:${url.port || 7770}`;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function parseIdaConnection(value) {
|
|
86
|
+
const trimmed = String(value || "").trim();
|
|
87
|
+
|
|
88
|
+
if (!trimmed) {
|
|
89
|
+
throw new Error("IdaJS installation directory or host[:port] is required");
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (fs.existsSync(trimmed)) {
|
|
93
|
+
return {
|
|
94
|
+
installDir: trimmed,
|
|
95
|
+
server: null,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (trimmed.includes("/") || trimmed.includes("\\") || /^[A-Za-z]:/.test(trimmed)) {
|
|
100
|
+
throw new Error(`Directory does not exist: ${trimmed}`);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
installDir: null,
|
|
105
|
+
server: normalizeServerAddress(trimmed),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function loadJson(filePath) {
|
|
110
|
+
try {
|
|
111
|
+
return JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
112
|
+
} catch (error) {
|
|
113
|
+
throw new Error(`Failed to parse JSON file: ${filePath}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function isInteractiveTerminal() {
|
|
118
|
+
return Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function askYesNo(question) {
|
|
122
|
+
return new Promise((resolve) => {
|
|
123
|
+
const rl = readline.createInterface({
|
|
124
|
+
input: process.stdin,
|
|
125
|
+
output: process.stdout,
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
rl.question(question, (answer) => {
|
|
129
|
+
rl.close();
|
|
130
|
+
const normalized = String(answer || "").trim().toLowerCase();
|
|
131
|
+
resolve(normalized === "y" || normalized === "yes");
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async function runUpdateMode() {
|
|
137
|
+
const targetDir = process.cwd();
|
|
138
|
+
const packageJsonPath = path.join(targetDir, "package.json");
|
|
139
|
+
|
|
140
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
141
|
+
console.error(`\n❌ Error: No package.json found in ${targetDir}`);
|
|
142
|
+
console.error("Run this command from inside an existing IdaJS mod folder.");
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const packageJson = loadJson(packageJsonPath);
|
|
147
|
+
const devDependencies = packageJson.devDependencies || {};
|
|
148
|
+
const missingPackages = requiredUpdatePackages.filter((name) => !devDependencies[name]);
|
|
149
|
+
|
|
150
|
+
if (missingPackages.length > 0) {
|
|
151
|
+
console.warn(
|
|
152
|
+
`\n⚠️ Warning: Missing IdaJS devDependencies: ${missingPackages.join(", ")}.`
|
|
153
|
+
);
|
|
154
|
+
console.warn("This may not be an IdaJS mod, or the project may differ significantly from the scaffold.");
|
|
155
|
+
|
|
156
|
+
if (!isInteractiveTerminal()) {
|
|
157
|
+
console.error("\n❌ Error: Confirmation required. Rerun this command in an interactive terminal to continue.");
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const confirmed = await askYesNo("Continue with scaffolder update? [y/N] ");
|
|
162
|
+
if (!confirmed) {
|
|
163
|
+
console.log("\nUpdate cancelled.");
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
console.log(`\nUpdating IdaJS mod in ${targetDir}...`);
|
|
169
|
+
|
|
170
|
+
const installScript = path.join(__dirname, "install.js");
|
|
171
|
+
const installArgs = [installScript, targetDir, "--update"];
|
|
172
|
+
|
|
173
|
+
if (skipInstall) {
|
|
174
|
+
installArgs.push("--skip-install");
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
execSync(`node ${installArgs.map((arg) => `"${arg}"`).join(" ")}`, {
|
|
179
|
+
stdio: "inherit",
|
|
180
|
+
});
|
|
181
|
+
console.log("\n✅ Scaffolder update completed successfully.");
|
|
182
|
+
} catch (error) {
|
|
183
|
+
console.error(`\n❌ Error updating project: ${error.message}`);
|
|
184
|
+
process.exit(1);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
73
188
|
async function main() {
|
|
74
189
|
console.log("Welcome to IdaJS Mod Creator!\n");
|
|
75
190
|
|
|
191
|
+
if (updateMode) {
|
|
192
|
+
await runUpdateMode();
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
76
196
|
// Determine if we need prompts
|
|
77
197
|
const needsPrompts =
|
|
78
198
|
!projectName || (!useTypeScript && !useJavaScript) || (!idajsDir && !getIdaJsDirFromConfig());
|
|
@@ -124,16 +244,15 @@ async function main() {
|
|
|
124
244
|
if (!config.idajsDir) {
|
|
125
245
|
questions.push({
|
|
126
246
|
type: "text",
|
|
127
|
-
name: "
|
|
128
|
-
message: "IdaJS installation directory:",
|
|
247
|
+
name: "idajsConnection",
|
|
248
|
+
message: "IdaJS installation directory or host[:port]:",
|
|
129
249
|
validate: (value) => {
|
|
130
|
-
|
|
131
|
-
|
|
250
|
+
try {
|
|
251
|
+
parseIdaConnection(value);
|
|
252
|
+
return true;
|
|
253
|
+
} catch (error) {
|
|
254
|
+
return error.message;
|
|
132
255
|
}
|
|
133
|
-
if (!fs.existsSync(value)) {
|
|
134
|
-
return `Directory does not exist: ${value}`;
|
|
135
|
-
}
|
|
136
|
-
return true;
|
|
137
256
|
},
|
|
138
257
|
});
|
|
139
258
|
}
|
|
@@ -159,6 +278,13 @@ async function main() {
|
|
|
159
278
|
});
|
|
160
279
|
|
|
161
280
|
config = { ...config, ...response };
|
|
281
|
+
|
|
282
|
+
if (response.idajsConnection) {
|
|
283
|
+
const parsedConnection = parseIdaConnection(response.idajsConnection);
|
|
284
|
+
config.idajsDir = parsedConnection.installDir;
|
|
285
|
+
config.server = parsedConnection.server;
|
|
286
|
+
delete config.idajsConnection;
|
|
287
|
+
}
|
|
162
288
|
}
|
|
163
289
|
|
|
164
290
|
// Set target directory to project name if not specified
|
|
@@ -171,7 +297,7 @@ async function main() {
|
|
|
171
297
|
: path.join(process.cwd(), config.targetDirectory);
|
|
172
298
|
|
|
173
299
|
// Validate IdaJS directory exists
|
|
174
|
-
if (!fs.existsSync(config.idajsDir)) {
|
|
300
|
+
if (config.idajsDir && !fs.existsSync(config.idajsDir)) {
|
|
175
301
|
console.error(`\n❌ Error: IdaJS installation directory does not exist: ${config.idajsDir}`);
|
|
176
302
|
process.exit(1);
|
|
177
303
|
}
|
|
@@ -184,7 +310,7 @@ async function main() {
|
|
|
184
310
|
|
|
185
311
|
console.log(`\nCreating IdaJS mod in ${targetDir}...`);
|
|
186
312
|
console.log(`Language: ${config.language === "js" ? "JavaScript" : "TypeScript"}`);
|
|
187
|
-
console.log(`IdaJS: ${config.idajsDir}\n`);
|
|
313
|
+
console.log(`IdaJS: ${config.idajsDir || config.server}\n`);
|
|
188
314
|
|
|
189
315
|
try {
|
|
190
316
|
// Create project directory
|
|
@@ -218,14 +344,14 @@ async function main() {
|
|
|
218
344
|
fs.writeFileSync(packageTemplatePath, JSON.stringify(packageTemplate, null, 2) + "\n");
|
|
219
345
|
console.log("✓ Updated package.template.json");
|
|
220
346
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
installDir
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
);
|
|
347
|
+
const idajsConfig = {};
|
|
348
|
+
if (config.idajsDir) {
|
|
349
|
+
idajsConfig.installDir = config.idajsDir;
|
|
350
|
+
}
|
|
351
|
+
if (config.server) {
|
|
352
|
+
idajsConfig.server = config.server;
|
|
353
|
+
}
|
|
354
|
+
fs.writeFileSync(path.join(targetDir, ".idajs.json"), JSON.stringify(idajsConfig, null, 2) + "\n");
|
|
229
355
|
console.log("✓ Created .idajs.json");
|
|
230
356
|
|
|
231
357
|
// Call Samples/install.js to set up the project
|