Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-scan-dest-occupancy-merge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@sfmc-bds/bds-tools": patch
---

修复 #80/#81 合并后 `scanDestOccupancy` 未赋值 `facts`、引用未声明标识符导致 tsc 构建失败;恢复经 `readPackDirOccupancy` 的 DRY 占用扫描。
18 changes: 4 additions & 14 deletions bds-tools/src/world-packs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ export type PackInstallPlan =

/**
* 读单目录占用事实(info 优先,否则 header)。
* Utf8BomError 上抛,由调用方决定跳过或仍占文件夹名
* 解析失败返回 null;不抛 BOM(readJsonFile 已剥离)
*/
export function readPackDirOccupancy(dir: string): {
uuid: string;
Expand All @@ -590,24 +590,14 @@ export function readPackDirOccupancy(dir: string): {
return null;
}

/** 扫描 destParent 下含 manifest 的目录占用 */
/** 扫描 destParent 下含 manifest 的目录占用(单一事实源:readPackDirOccupancy) */
export function scanDestOccupancy(destParent: string): DestOccupancy[] {
const out: DestOccupancy[] = [];
for (const dir of listPackDirsIn(destParent)) {
let facts: ReturnType<typeof readPackDirOccupancy> = null;
try {
const info = readPackManifestInfo(dir);
if (info) {
uuid = info.uuid;
version = info.version;
name = info.name;
} else {
const header = readPackManifestHeader(dir);
if (header) {
uuid = header.uuid;
version = header.version;
}
}
// DRY:与 readPackDirOccupancy 共用 info→header 回退,禁止内联双读
facts = readPackDirOccupancy(dir);
} catch {
/* manifest 不可读则占位 uuid 为空 */
}
Expand Down
48 changes: 48 additions & 0 deletions bds-tools/world-packs.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,54 @@ describe("world-packs primitives", () => {
assert.deepEqual(version, [2, 0, 1]);
});

it("scanDestOccupancy / readPackDirOccupancy:完整与残缺 manifest", async () => {
const { scanDestOccupancy, readPackDirOccupancy, formatWorldPackFolderName } = await import(
"./dist/world-packs.js"
);
const parent = path.join(tmp, "occupancy-scan");
const fullName = formatWorldPackFolderName("Full", "resource");
const brokenName = formatWorldPackFolderName("Broken", "behavior");
const fullDir = path.join(parent, fullName);
const brokenDir = path.join(parent, brokenName);
writeManifest(fullDir, {
name: "Full Pack",
uuid: "11111111-1111-1111-1111-111111111111",
version: [2, 3, 4],
type: "resources",
});
fs.mkdirSync(brokenDir, { recursive: true });
fs.writeFileSync(
path.join(brokenDir, "manifest.json"),
JSON.stringify({
format_version: 2,
header: {
name: "Broken Pack",
uuid: "22222222-2222-2222-2222-222222222222",
version: [9, 0, 1],
},
modules: [],
})
);

const fullFacts = readPackDirOccupancy(fullDir);
assert.equal(fullFacts?.uuid, "11111111-1111-1111-1111-111111111111");
assert.deepEqual(fullFacts?.version, [2, 3, 4]);
assert.equal(fullFacts?.kind, "resource");

const brokenFacts = readPackDirOccupancy(brokenDir);
assert.equal(brokenFacts?.uuid, "22222222-2222-2222-2222-222222222222");
assert.deepEqual(brokenFacts?.version, [9, 0, 1]);
assert.equal(brokenFacts?.kind, undefined);

const occ = scanDestOccupancy(parent);
assert.equal(occ.length, 2);
const byFolder = Object.fromEntries(occ.map((o) => [o.folderName, o]));
assert.equal(byFolder[fullName]?.uuid, "11111111-1111-1111-1111-111111111111");
assert.equal(byFolder[fullName]?.kind, "resource");
assert.equal(byFolder[brokenName]?.uuid, "22222222-2222-2222-2222-222222222222");
assert.equal(byFolder[brokenName]?.kind, undefined);
});

it("decidePackInstallPlan 表驱动", async () => {
const { decidePackInstallPlan, formatWorldPackFolderName } = await import("./dist/world-packs.js");
const uuidA = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa";
Expand Down