@mafly/bdev-cli 1.0.4 → 1.0.5
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/dist/commands/build.js +7 -1
- package/dist/commands/dev.js +28 -3
- package/dist/commands/init.js +20 -2
- package/dist/utils/manifest.d.ts +8 -0
- package/dist/utils/manifest.js +234 -0
- package/package.json +1 -1
package/dist/commands/build.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { runBuild } from "../utils/bundler.js";
|
|
4
|
-
import { validateManifest } from "../utils/manifest.js";
|
|
4
|
+
import { validateManifest, syncManifestDependencies, addResourcePack, } from "../utils/manifest.js";
|
|
5
5
|
import { logger } from "../utils/logger.js";
|
|
6
6
|
export async function buildCommand(dirArg, options = {}) {
|
|
7
7
|
const rootDir = path.resolve(dirArg || ".");
|
|
8
8
|
const bpDir = path.join(rootDir, "behavior_pack");
|
|
9
9
|
const bpManifestPath = path.join(bpDir, "manifest.json");
|
|
10
|
+
// Sync @minecraft/* dependencies from package.json into manifest.json
|
|
11
|
+
syncManifestDependencies(rootDir);
|
|
10
12
|
// 1. Validate Behavior Pack Manifest
|
|
11
13
|
if (!fs.existsSync(bpManifestPath)) {
|
|
12
14
|
logger.error(`Behavior pack manifest not found: ${bpManifestPath}`);
|
|
@@ -25,6 +27,10 @@ export async function buildCommand(dirArg, options = {}) {
|
|
|
25
27
|
// Validate Resource Pack Manifest if exists
|
|
26
28
|
const rpDir = path.join(rootDir, "resource_pack");
|
|
27
29
|
const rpManifestPath = path.join(rpDir, "manifest.json");
|
|
30
|
+
if (fs.existsSync(rpDir) && !fs.existsSync(rpManifestPath)) {
|
|
31
|
+
logger.info("Found resource_pack folder without manifest. Initializing Resource Pack...");
|
|
32
|
+
addResourcePack(rootDir);
|
|
33
|
+
}
|
|
28
34
|
if (fs.existsSync(rpManifestPath)) {
|
|
29
35
|
const rpValidation = validateManifest(rpManifestPath);
|
|
30
36
|
if (!rpValidation.valid) {
|
package/dist/commands/dev.js
CHANGED
|
@@ -7,13 +7,13 @@ import { findMojangPath, linkPack } from "../utils/mojang.js";
|
|
|
7
7
|
import { saveConfig } from "../utils/config.js";
|
|
8
8
|
import { BedrockHotReloadServer } from "../utils/wsserver.js";
|
|
9
9
|
import { logger } from "../utils/logger.js";
|
|
10
|
-
import { validateManifest } from "../utils/manifest.js";
|
|
10
|
+
import { validateManifest, getLastManifestSyncTime } from "../utils/manifest.js";
|
|
11
11
|
export async function devCommand(dirArg, options = {}) {
|
|
12
12
|
const rootDir = path.resolve(dirArg || ".");
|
|
13
13
|
const bpDir = path.join(rootDir, "behavior_pack");
|
|
14
14
|
const rpDir = path.join(rootDir, "resource_pack");
|
|
15
15
|
const hasBp = fs.existsSync(bpDir);
|
|
16
|
-
|
|
16
|
+
let hasRp = fs.existsSync(rpDir);
|
|
17
17
|
if (!hasBp && !hasRp) {
|
|
18
18
|
logger.error(`No behavior_pack or resource_pack found in ${rootDir}. Run 'bdev init' first.`);
|
|
19
19
|
process.exit(1);
|
|
@@ -33,8 +33,8 @@ export async function devCommand(dirArg, options = {}) {
|
|
|
33
33
|
}
|
|
34
34
|
// 2. Setup symlinks to com.mojang
|
|
35
35
|
const shouldLink = options.link !== false;
|
|
36
|
+
const mojang = shouldLink ? findMojangPath(options.path, rootDir) : null;
|
|
36
37
|
if (shouldLink) {
|
|
37
|
-
const mojang = findMojangPath(options.path, rootDir);
|
|
38
38
|
if (!mojang) {
|
|
39
39
|
logger.warn("Minecraft com.mojang directory not found.");
|
|
40
40
|
logger.warn("Tip: Set with 'bdev set-path <path>' or pass '-p <path>' or 'BEDROCK_MOJANG_PATH'.");
|
|
@@ -93,6 +93,10 @@ export async function devCommand(dirArg, options = {}) {
|
|
|
93
93
|
if (hasRp) {
|
|
94
94
|
watchPaths.push(rpDir);
|
|
95
95
|
}
|
|
96
|
+
const pkgJsonPath = path.join(rootDir, "package.json");
|
|
97
|
+
if (fs.existsSync(pkgJsonPath)) {
|
|
98
|
+
watchPaths.push(pkgJsonPath);
|
|
99
|
+
}
|
|
96
100
|
logger.info(`Starting file watcher on: ${watchPaths.map((p) => path.relative(rootDir, p)).join(", ")}`);
|
|
97
101
|
logger.info("Press Ctrl+C to stop.");
|
|
98
102
|
let isRebuilding = false;
|
|
@@ -120,6 +124,22 @@ export async function devCommand(dirArg, options = {}) {
|
|
|
120
124
|
rebuildPending = false;
|
|
121
125
|
const rel = path.relative(rootDir, triggerPath);
|
|
122
126
|
try {
|
|
127
|
+
// If resource_pack was added while dev server is running
|
|
128
|
+
if (!hasRp && fs.existsSync(rpDir)) {
|
|
129
|
+
hasRp = true;
|
|
130
|
+
watcher.add(rpDir);
|
|
131
|
+
logger.info("Detected new Resource Pack. Watching resource_pack...");
|
|
132
|
+
if (shouldLink && mojang) {
|
|
133
|
+
const destRp = path.join(mojang.devResourcePacks, `${folderName}_RP`);
|
|
134
|
+
try {
|
|
135
|
+
linkPack(rpDir, destRp);
|
|
136
|
+
logger.success(`Linked Resource Pack -> ${destRp}`);
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
logger.error(`Failed to link Resource Pack: ${err.message}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
123
143
|
if (triggerPath.endsWith("manifest.json")) {
|
|
124
144
|
const res = validateManifest(triggerPath);
|
|
125
145
|
if (res.valid) {
|
|
@@ -157,6 +177,11 @@ export async function devCommand(dirArg, options = {}) {
|
|
|
157
177
|
}
|
|
158
178
|
};
|
|
159
179
|
const triggerRebuild = (filePath) => {
|
|
180
|
+
// Ignore internal writes to manifest.json caused by syncManifestDependencies
|
|
181
|
+
if (filePath.endsWith("manifest.json") &&
|
|
182
|
+
Date.now() - getLastManifestSyncTime() < 600) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
160
185
|
const rel = path.relative(rootDir, filePath);
|
|
161
186
|
logger.info(`Change detected in ${rel}`);
|
|
162
187
|
if (isRebuilding) {
|
package/dist/commands/init.js
CHANGED
|
@@ -1,16 +1,34 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { generateManifests } from "../utils/manifest.js";
|
|
3
|
+
import { generateManifests, addResourcePack, DEFAULT_ICON_BASE64, } from "../utils/manifest.js";
|
|
4
4
|
import { saveConfig } from "../utils/config.js";
|
|
5
5
|
import { resolveMinecraftDependencies } from "../utils/npm.js";
|
|
6
6
|
import { logger } from "../utils/logger.js";
|
|
7
|
-
const DEFAULT_ICON_BASE64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==";
|
|
8
7
|
export async function initCommand(targetDirArg, options) {
|
|
9
8
|
const targetDir = path.resolve(targetDirArg || ".");
|
|
10
9
|
const projectName = options.name || path.basename(targetDir) || "my-bedrock-addon";
|
|
11
10
|
const projectDesc = options.desc || `${projectName} - Bedrock Addon created with bdev`;
|
|
12
11
|
const isTs = options.lang !== "js";
|
|
13
12
|
const hasRp = options.rp !== false;
|
|
13
|
+
const existingBpManifest = path.join(targetDir, "behavior_pack", "manifest.json");
|
|
14
|
+
if (fs.existsSync(existingBpManifest)) {
|
|
15
|
+
if (hasRp) {
|
|
16
|
+
const existingRpManifest = path.join(targetDir, "resource_pack", "manifest.json");
|
|
17
|
+
if (!fs.existsSync(existingRpManifest)) {
|
|
18
|
+
logger.info("Existing Behavior Pack project detected without Resource Pack.");
|
|
19
|
+
addResourcePack(targetDir, { name: projectName, description: projectDesc });
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
logger.warn("Project already initialized with Behavior Pack and Resource Pack.");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
logger.warn("Project is already initialized.");
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
14
32
|
logger.info(`Scaffolding Bedrock Addon project: ${projectName}`);
|
|
15
33
|
logger.info(`Directory: ${targetDir}`);
|
|
16
34
|
logger.info(`Language: ${isTs ? "TypeScript" : "JavaScript"} | Resource Pack: ${hasRp ? "Yes" : "No"}`);
|
package/dist/utils/manifest.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export declare const DEFAULT_ICON_BASE64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==";
|
|
1
2
|
export interface ManifestHeader {
|
|
2
3
|
name: string;
|
|
3
4
|
description: string;
|
|
@@ -40,3 +41,10 @@ export declare function generateManifests(opts: {
|
|
|
40
41
|
bpManifest: BedrockManifest;
|
|
41
42
|
rpManifest?: BedrockManifest;
|
|
42
43
|
};
|
|
44
|
+
export interface AddResourcePackOptions {
|
|
45
|
+
name?: string;
|
|
46
|
+
description?: string;
|
|
47
|
+
}
|
|
48
|
+
export declare function addResourcePack(rootDir: string, options?: AddResourcePackOptions): boolean;
|
|
49
|
+
export declare function getLastManifestSyncTime(): number;
|
|
50
|
+
export declare function syncManifestDependencies(rootDir: string): boolean;
|
package/dist/utils/manifest.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
2
3
|
import { v4 as uuidv4, validate as validateUuid } from "uuid";
|
|
4
|
+
import { logger } from "./logger.js";
|
|
5
|
+
export const DEFAULT_ICON_BASE64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==";
|
|
3
6
|
export function validateManifest(manifestPath) {
|
|
4
7
|
const errors = [];
|
|
5
8
|
if (!fs.existsSync(manifestPath)) {
|
|
@@ -144,3 +147,234 @@ export function generateManifests(opts) {
|
|
|
144
147
|
}
|
|
145
148
|
return { bpManifest, rpManifest };
|
|
146
149
|
}
|
|
150
|
+
export function addResourcePack(rootDir, options = {}) {
|
|
151
|
+
const bpDir = path.join(rootDir, "behavior_pack");
|
|
152
|
+
const bpManifestPath = path.join(bpDir, "manifest.json");
|
|
153
|
+
if (!fs.existsSync(bpManifestPath)) {
|
|
154
|
+
logger.error(`Behavior pack manifest not found in ${rootDir}. Run 'bdev init' first.`);
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
const rpDir = path.join(rootDir, "resource_pack");
|
|
158
|
+
const rpManifestPath = path.join(rpDir, "manifest.json");
|
|
159
|
+
let bpManifest;
|
|
160
|
+
try {
|
|
161
|
+
bpManifest = JSON.parse(fs.readFileSync(bpManifestPath, "utf-8"));
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
logger.error(`Failed to parse ${bpManifestPath}: ${err.message}`);
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
if (fs.existsSync(rpManifestPath)) {
|
|
168
|
+
try {
|
|
169
|
+
const rpManifest = JSON.parse(fs.readFileSync(rpManifestPath, "utf-8"));
|
|
170
|
+
const rpUuid = rpManifest?.header?.uuid;
|
|
171
|
+
if (rpUuid) {
|
|
172
|
+
if (!Array.isArray(bpManifest.dependencies)) {
|
|
173
|
+
bpManifest.dependencies = [];
|
|
174
|
+
}
|
|
175
|
+
const hasDep = bpManifest.dependencies.some((d) => d.uuid?.toLowerCase() === rpUuid.toLowerCase());
|
|
176
|
+
if (!hasDep) {
|
|
177
|
+
bpManifest.dependencies.push({
|
|
178
|
+
uuid: rpUuid,
|
|
179
|
+
version: rpManifest.header?.version || [1, 0, 0],
|
|
180
|
+
});
|
|
181
|
+
fs.writeFileSync(bpManifestPath, JSON.stringify(bpManifest, null, 2) + "\n");
|
|
182
|
+
logger.success("Linked existing Resource Pack to Behavior Pack manifest.");
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
// ignore
|
|
189
|
+
}
|
|
190
|
+
logger.warn("Resource pack already exists in this project.");
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
let projectName = options.name;
|
|
194
|
+
let projectDesc = options.description;
|
|
195
|
+
const pkgJsonPath = path.join(rootDir, "package.json");
|
|
196
|
+
if ((!projectName || !projectDesc) && fs.existsSync(pkgJsonPath)) {
|
|
197
|
+
try {
|
|
198
|
+
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8"));
|
|
199
|
+
if (!projectName && pkg.name)
|
|
200
|
+
projectName = pkg.name;
|
|
201
|
+
if (!projectDesc && pkg.description)
|
|
202
|
+
projectDesc = pkg.description;
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
// ignore
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
if (!projectName) {
|
|
209
|
+
projectName = (bpManifest.header?.name || path.basename(rootDir)).replace(/\s*\(BP\)$/i, "");
|
|
210
|
+
}
|
|
211
|
+
if (!projectDesc) {
|
|
212
|
+
projectDesc = bpManifest.header?.description || `${projectName} Resource Pack`;
|
|
213
|
+
}
|
|
214
|
+
const minEngineVersion = bpManifest.header?.min_engine_version || [1, 21, 0];
|
|
215
|
+
const rpHeaderUuid = uuidv4();
|
|
216
|
+
const rpModuleUuid = uuidv4();
|
|
217
|
+
const rpManifest = {
|
|
218
|
+
format_version: 2,
|
|
219
|
+
header: {
|
|
220
|
+
name: `${projectName} (RP)`,
|
|
221
|
+
description: projectDesc,
|
|
222
|
+
uuid: rpHeaderUuid,
|
|
223
|
+
version: [1, 0, 0],
|
|
224
|
+
min_engine_version: minEngineVersion,
|
|
225
|
+
},
|
|
226
|
+
modules: [
|
|
227
|
+
{
|
|
228
|
+
description: "Resource Pack Modules",
|
|
229
|
+
type: "resources",
|
|
230
|
+
uuid: rpModuleUuid,
|
|
231
|
+
version: [1, 0, 0],
|
|
232
|
+
},
|
|
233
|
+
],
|
|
234
|
+
};
|
|
235
|
+
fs.mkdirSync(rpDir, { recursive: true });
|
|
236
|
+
fs.writeFileSync(rpManifestPath, JSON.stringify(rpManifest, null, 2) + "\n");
|
|
237
|
+
const bpIconPath = path.join(bpDir, "pack_icon.png");
|
|
238
|
+
const rpIconPath = path.join(rpDir, "pack_icon.png");
|
|
239
|
+
if (fs.existsSync(bpIconPath)) {
|
|
240
|
+
fs.copyFileSync(bpIconPath, rpIconPath);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
fs.writeFileSync(rpIconPath, Buffer.from(DEFAULT_ICON_BASE64, "base64"));
|
|
244
|
+
}
|
|
245
|
+
const textsDir = path.join(rpDir, "texts");
|
|
246
|
+
fs.mkdirSync(textsDir, { recursive: true });
|
|
247
|
+
fs.writeFileSync(path.join(textsDir, "en_US.lang"), `pack.name=${projectName}\npack.description=${projectDesc}\n`);
|
|
248
|
+
if (!Array.isArray(bpManifest.dependencies)) {
|
|
249
|
+
bpManifest.dependencies = [];
|
|
250
|
+
}
|
|
251
|
+
const existingRpIndex = bpManifest.dependencies.findIndex((d) => d.uuid && !d.module_name);
|
|
252
|
+
if (existingRpIndex !== -1) {
|
|
253
|
+
bpManifest.dependencies[existingRpIndex] = {
|
|
254
|
+
uuid: rpHeaderUuid,
|
|
255
|
+
version: [1, 0, 0],
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
bpManifest.dependencies.push({
|
|
260
|
+
uuid: rpHeaderUuid,
|
|
261
|
+
version: [1, 0, 0],
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
fs.writeFileSync(bpManifestPath, JSON.stringify(bpManifest, null, 2) + "\n");
|
|
265
|
+
logger.success(`Resource Pack created and linked to Behavior Pack at ${rpDir}`);
|
|
266
|
+
return true;
|
|
267
|
+
}
|
|
268
|
+
let lastManifestSyncTime = 0;
|
|
269
|
+
export function getLastManifestSyncTime() {
|
|
270
|
+
return lastManifestSyncTime;
|
|
271
|
+
}
|
|
272
|
+
export function syncManifestDependencies(rootDir) {
|
|
273
|
+
const pkgPath = path.join(rootDir, "package.json");
|
|
274
|
+
const bpManifestPath = path.join(rootDir, "behavior_pack", "manifest.json");
|
|
275
|
+
if (!fs.existsSync(pkgPath) || !fs.existsSync(bpManifestPath)) {
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
let pkg;
|
|
279
|
+
let bpManifest;
|
|
280
|
+
try {
|
|
281
|
+
pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
282
|
+
bpManifest = JSON.parse(fs.readFileSync(bpManifestPath, "utf-8"));
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
const targetDeps = new Map();
|
|
288
|
+
if (pkg.devDependencies && typeof pkg.devDependencies === "object") {
|
|
289
|
+
for (const [name, ver] of Object.entries(pkg.devDependencies)) {
|
|
290
|
+
if (name.startsWith("@minecraft/") && typeof ver === "string") {
|
|
291
|
+
targetDeps.set(name, ver.replace(/^[~^>=v\s]+/, ""));
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
if (pkg.dependencies && typeof pkg.dependencies === "object") {
|
|
296
|
+
for (const [name, ver] of Object.entries(pkg.dependencies)) {
|
|
297
|
+
if (name.startsWith("@minecraft/") && typeof ver === "string") {
|
|
298
|
+
targetDeps.set(name, ver.replace(/^[~^>=v\s]+/, ""));
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
if (!Array.isArray(bpManifest.dependencies)) {
|
|
303
|
+
bpManifest.dependencies = [];
|
|
304
|
+
}
|
|
305
|
+
let modified = false;
|
|
306
|
+
const updatedModules = [];
|
|
307
|
+
// 1. Update existing @minecraft/* entries or prune removed ones
|
|
308
|
+
const toRemoveIndices = [];
|
|
309
|
+
bpManifest.dependencies.forEach((dep, idx) => {
|
|
310
|
+
if (dep.module_name && dep.module_name.startsWith("@minecraft/")) {
|
|
311
|
+
const targetVer = targetDeps.get(dep.module_name);
|
|
312
|
+
if (targetVer) {
|
|
313
|
+
if (dep.version !== targetVer) {
|
|
314
|
+
dep.version = targetVer;
|
|
315
|
+
modified = true;
|
|
316
|
+
updatedModules.push(`${dep.module_name}@${targetVer}`);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
else if (dep.module_name !== "@minecraft/server") {
|
|
320
|
+
// Removed from package.json
|
|
321
|
+
toRemoveIndices.push(idx);
|
|
322
|
+
modified = true;
|
|
323
|
+
updatedModules.push(`-${dep.module_name}`);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
if (toRemoveIndices.length > 0) {
|
|
328
|
+
bpManifest.dependencies = bpManifest.dependencies.filter((_, idx) => !toRemoveIndices.includes(idx));
|
|
329
|
+
}
|
|
330
|
+
// 2. Add new @minecraft/* dependencies from package.json that are missing in manifest
|
|
331
|
+
for (const [name, ver] of targetDeps.entries()) {
|
|
332
|
+
const exists = bpManifest.dependencies.some((d) => d.module_name === name);
|
|
333
|
+
if (!exists) {
|
|
334
|
+
bpManifest.dependencies.push({
|
|
335
|
+
module_name: name,
|
|
336
|
+
version: ver,
|
|
337
|
+
});
|
|
338
|
+
modified = true;
|
|
339
|
+
updatedModules.push(`+${name}@${ver}`);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
// 3. Link resource pack if exists and not linked
|
|
343
|
+
const rpManifestPath = path.join(rootDir, "resource_pack", "manifest.json");
|
|
344
|
+
if (fs.existsSync(rpManifestPath)) {
|
|
345
|
+
try {
|
|
346
|
+
const rpManifest = JSON.parse(fs.readFileSync(rpManifestPath, "utf-8"));
|
|
347
|
+
const rpUuid = rpManifest?.header?.uuid;
|
|
348
|
+
if (rpUuid) {
|
|
349
|
+
const hasRpDep = bpManifest.dependencies.some((d) => d.uuid && d.uuid.toLowerCase() === rpUuid.toLowerCase());
|
|
350
|
+
if (!hasRpDep) {
|
|
351
|
+
const staleRpIndex = bpManifest.dependencies.findIndex((d) => d.uuid && !d.module_name);
|
|
352
|
+
if (staleRpIndex !== -1) {
|
|
353
|
+
bpManifest.dependencies[staleRpIndex] = {
|
|
354
|
+
uuid: rpUuid,
|
|
355
|
+
version: rpManifest.header?.version || [1, 0, 0],
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
bpManifest.dependencies.push({
|
|
360
|
+
uuid: rpUuid,
|
|
361
|
+
version: rpManifest.header?.version || [1, 0, 0],
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
modified = true;
|
|
365
|
+
updatedModules.push(`linked RP (${rpUuid.slice(0, 8)}...)`);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
catch {
|
|
370
|
+
// ignore
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
if (modified) {
|
|
374
|
+
lastManifestSyncTime = Date.now();
|
|
375
|
+
fs.writeFileSync(bpManifestPath, JSON.stringify(bpManifest, null, 2) + "\n");
|
|
376
|
+
logger.success(`Synchronized manifest.json dependencies: ${updatedModules.join(", ")}`);
|
|
377
|
+
return true;
|
|
378
|
+
}
|
|
379
|
+
return false;
|
|
380
|
+
}
|