@sfmc-bds/bds-tools 0.2.0-beta.17 → 0.2.0-beta.18
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/bds-manager.d.ts.map +1 -1
- package/dist/bds-manager.js +8 -1
- package/dist/bds-manager.js.map +2 -2
- package/dist/changelog.d.ts +11 -7
- package/dist/changelog.d.ts.map +1 -1
- package/dist/changelog.js +60 -34
- package/dist/changelog.js.map +2 -2
- package/dist/check-update.d.ts.map +1 -1
- package/dist/check-update.js +50 -13
- package/dist/check-update.js.map +2 -2
- package/dist/qq-events-notify.d.ts +1 -1
- package/dist/qq-events-notify.d.ts.map +1 -1
- package/dist/qq-events-notify.js.map +1 -1
- package/dist/qqutil.d.ts.map +1 -1
- package/dist/qqutil.js +14 -12
- package/dist/qqutil.js.map +2 -2
- package/dist/server-properties-i18n.d.ts.map +1 -1
- package/dist/server-properties-i18n.js +4 -0
- package/dist/server-properties-i18n.js.map +2 -2
- package/dist/server-properties.d.ts +3 -0
- package/dist/server-properties.d.ts.map +1 -1
- package/dist/server-properties.js +15 -0
- package/dist/server-properties.js.map +2 -2
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/dist/dependency-negotiator.test.js +0 -120
- package/dist/dependency-negotiator.test.js.map +0 -7
- package/dist/fsx.test.js +0 -60
- package/dist/fsx.test.js.map +0 -7
- package/dist/level-dat.test.js +0 -172
- package/dist/level-dat.test.js.map +0 -7
- package/dist/pack-manager-lifecycle.test.js +0 -252
- package/dist/pack-manager-lifecycle.test.js.map +0 -7
- package/dist/pack-update/config.test.js +0 -75
- package/dist/pack-update/config.test.js.map +0 -7
- package/dist/pack-update/version-policy.test.js +0 -137
- package/dist/pack-update/version-policy.test.js.map +0 -7
- package/dist/process-probe.test.js +0 -76
- package/dist/process-probe.test.js.map +0 -7
- package/dist/server-properties.test.js +0 -127
- package/dist/server-properties.test.js.map +0 -7
- package/dist/world-packs.test.js +0 -698
- package/dist/world-packs.test.js.map +0 -7
- package/dist/zipx.test.js +0 -36
- package/dist/zipx.test.js.map +0 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sfmc-bds/bds-tools",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.18",
|
|
4
4
|
"description": "SFMC BDS auto-updater, lifecycle manager, and behavior-pack assembler",
|
|
5
5
|
"author": "Shiroha7z",
|
|
6
6
|
"license": "AGPL-3.0-only",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"./pack-manager": "./dist/cli-pack-manager.js",
|
|
34
34
|
"./pack-manager-lib": "./dist/pack-manager.js",
|
|
35
35
|
"./process-probe": "./dist/process-probe.js",
|
|
36
|
+
"./qq-events-notify": "./dist/qq-events-notify.js",
|
|
36
37
|
"./package.json": "./package.json",
|
|
37
38
|
"./taskbar": "./dist/taskbar.js",
|
|
38
39
|
"./types": {
|
|
@@ -53,10 +54,10 @@
|
|
|
53
54
|
"dependencies": {
|
|
54
55
|
"jszip": "^3.10.1",
|
|
55
56
|
"node-html-parser": "^9.0.0",
|
|
56
|
-
"@sfmc-bds/sdk": "0.2.0-beta.
|
|
57
|
+
"@sfmc-bds/sdk": "0.2.0-beta.18"
|
|
57
58
|
},
|
|
58
59
|
"devDependencies": {
|
|
59
|
-
"@sfmc-bds/tools": "0.2.0-beta.
|
|
60
|
+
"@sfmc-bds/tools": "0.2.0-beta.19"
|
|
60
61
|
},
|
|
61
62
|
"publishConfig": {
|
|
62
63
|
"access": "public",
|
|
@@ -70,7 +71,6 @@
|
|
|
70
71
|
"start": "node dist/bds-manager.js start",
|
|
71
72
|
"status": "node dist/bds-manager.js status",
|
|
72
73
|
"stop": "node dist/bds-manager.js stop",
|
|
73
|
-
"test": "pnpm run build && node --test \"dist/**/*.test.js\"",
|
|
74
74
|
"typecheck": "tsc7 --noEmit",
|
|
75
75
|
"update": "node dist/check-update.js",
|
|
76
76
|
"update:check": "node dist/check-update.js --check-only",
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import test from "node:test";
|
|
3
|
-
import {
|
|
4
|
-
BASELINE_BEDROCK_DEPENDENCIES,
|
|
5
|
-
cleanBedrockVersion,
|
|
6
|
-
compareBedrockVersion,
|
|
7
|
-
isGametestBetaRequired,
|
|
8
|
-
negotiateBedrockDependencies
|
|
9
|
-
} from "./dependency-negotiator.js";
|
|
10
|
-
test("cleanBedrockVersion: \u6E05\u7406 npm range \u7B26\u53F7", () => {
|
|
11
|
-
assert.equal(cleanBedrockVersion("^2.0.0-beta"), "2.0.0-beta");
|
|
12
|
-
assert.equal(cleanBedrockVersion(">=2.0.0-beta <3.0.0"), "2.0.0-beta");
|
|
13
|
-
assert.equal(cleanBedrockVersion("~1.3.0"), "1.3.0");
|
|
14
|
-
assert.equal(cleanBedrockVersion("v1.18.0"), "1.18.0");
|
|
15
|
-
assert.equal(cleanBedrockVersion(" 1.2.0 "), "1.2.0");
|
|
16
|
-
});
|
|
17
|
-
test("compareBedrockVersion: \u5927\u7248\u672C\u4E0E\u6B21\u7248\u672C\u6BD4\u8F83", () => {
|
|
18
|
-
assert.ok(compareBedrockVersion("1.18.0", "1.3.0") > 0);
|
|
19
|
-
assert.ok(compareBedrockVersion("1.3.0", "1.18.0") < 0);
|
|
20
|
-
assert.equal(compareBedrockVersion("1.3.0", "1.3.0"), 0);
|
|
21
|
-
});
|
|
22
|
-
test("compareBedrockVersion: Beta \u4E0E\u6B63\u5F0F\u7248\u6BD4\u8F83\uFF08\u8DE8\u5927\u7248\u672C\u63D0\u5347\uFF09", () => {
|
|
23
|
-
assert.ok(compareBedrockVersion("2.0.0-beta", "1.3.0") > 0);
|
|
24
|
-
assert.ok(compareBedrockVersion("2.0.0", "2.0.0-beta") > 0);
|
|
25
|
-
assert.ok(compareBedrockVersion("2.2.0-beta", "2.0.0-beta") > 0);
|
|
26
|
-
});
|
|
27
|
-
test("isGametestBetaRequired: \u51C6\u786E\u8BC6\u522B\u6D4B\u8BD5\u7248\u73A9\u6CD5\u9700\u6C42", () => {
|
|
28
|
-
assert.equal(
|
|
29
|
-
isGametestBetaRequired({ module_name: "@minecraft/server-ui", version: "2.0.0-beta" }),
|
|
30
|
-
true
|
|
31
|
-
);
|
|
32
|
-
assert.equal(
|
|
33
|
-
isGametestBetaRequired({ module_name: "@minecraft/server", version: "2.10.0-beta" }),
|
|
34
|
-
true
|
|
35
|
-
);
|
|
36
|
-
assert.equal(
|
|
37
|
-
isGametestBetaRequired({ module_name: "@minecraft/server-gametest", version: "1.0.0" }),
|
|
38
|
-
true
|
|
39
|
-
);
|
|
40
|
-
assert.equal(
|
|
41
|
-
isGametestBetaRequired({ module_name: "@minecraft/server-ui", version: "1.3.0" }),
|
|
42
|
-
false
|
|
43
|
-
);
|
|
44
|
-
assert.equal(
|
|
45
|
-
isGametestBetaRequired({ module_name: "@minecraft/server", version: "1.18.0" }),
|
|
46
|
-
false
|
|
47
|
-
);
|
|
48
|
-
assert.equal(
|
|
49
|
-
isGametestBetaRequired({ module_name: "@minecraft/server-net", version: "1.0.0-beta" }),
|
|
50
|
-
false
|
|
51
|
-
);
|
|
52
|
-
assert.equal(
|
|
53
|
-
isGametestBetaRequired({ module_name: "@minecraft/server-admin", version: "1.0.0-beta" }),
|
|
54
|
-
false
|
|
55
|
-
);
|
|
56
|
-
});
|
|
57
|
-
test("negotiateBedrockDependencies: \u65E0\u6A21\u7EC4\u9700\u6C42\u65F6\u4FDD\u6301\u57FA\u51C6\u4F9D\u8D56", () => {
|
|
58
|
-
const result = negotiateBedrockDependencies(BASELINE_BEDROCK_DEPENDENCIES, []);
|
|
59
|
-
assert.equal(result.dependencies.length, BASELINE_BEDROCK_DEPENDENCIES.length);
|
|
60
|
-
assert.equal(result.promotions.length, 0);
|
|
61
|
-
assert.equal(result.hasBetaApis, false);
|
|
62
|
-
const uiDep = result.dependencies.find((d) => d.module_name === "@minecraft/server-ui");
|
|
63
|
-
assert.equal(uiDep?.version, "1.3.0");
|
|
64
|
-
});
|
|
65
|
-
test("negotiateBedrockDependencies: \u5355\u6A21\u5757\u63D0\u5347 @minecraft/server-ui \u81F3 2.0.0-beta", () => {
|
|
66
|
-
const result = negotiateBedrockDependencies(BASELINE_BEDROCK_DEPENDENCIES, [
|
|
67
|
-
{
|
|
68
|
-
folderId: "custom-menu",
|
|
69
|
-
dependencies: [
|
|
70
|
-
{ module_name: "@minecraft/server-ui", version: "2.0.0-beta" }
|
|
71
|
-
]
|
|
72
|
-
}
|
|
73
|
-
]);
|
|
74
|
-
const uiDep = result.dependencies.find((d) => d.module_name === "@minecraft/server-ui");
|
|
75
|
-
assert.equal(uiDep?.version, "2.0.0-beta");
|
|
76
|
-
assert.equal(result.hasBetaApis, true);
|
|
77
|
-
assert.equal(result.promotions.length, 1);
|
|
78
|
-
assert.equal(result.promotions[0].moduleName, "@minecraft/server-ui");
|
|
79
|
-
assert.equal(result.promotions[0].from, "1.3.0");
|
|
80
|
-
assert.equal(result.promotions[0].to, "2.0.0-beta");
|
|
81
|
-
assert.deepEqual(result.promotions[0].requestedBy, ["custom-menu"]);
|
|
82
|
-
});
|
|
83
|
-
test("negotiateBedrockDependencies: \u591A\u6A21\u5757\u4E0D\u540C\u7248\u672C\u9700\u6C42\u53D6\u6700\u9AD8\u517C\u5BB9", () => {
|
|
84
|
-
const result = negotiateBedrockDependencies(BASELINE_BEDROCK_DEPENDENCIES, [
|
|
85
|
-
{
|
|
86
|
-
folderId: "mod-a",
|
|
87
|
-
dependencies: [
|
|
88
|
-
{ module_name: "@minecraft/server-ui", version: "2.0.0-beta" }
|
|
89
|
-
]
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
folderId: "mod-b",
|
|
93
|
-
dependencies: [
|
|
94
|
-
{ module_name: "@minecraft/server-ui", version: "2.2.0-beta" }
|
|
95
|
-
]
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
folderId: "mod-c",
|
|
99
|
-
dependencies: [
|
|
100
|
-
{ module_name: "@minecraft/server-ui", version: "1.3.0" }
|
|
101
|
-
]
|
|
102
|
-
}
|
|
103
|
-
]);
|
|
104
|
-
const uiDep = result.dependencies.find((d) => d.module_name === "@minecraft/server-ui");
|
|
105
|
-
assert.equal(uiDep?.version, "2.2.0-beta");
|
|
106
|
-
assert.equal(result.hasBetaApis, true);
|
|
107
|
-
});
|
|
108
|
-
test("negotiateBedrockDependencies: \u652F\u6301\u5F15\u5165\u57FA\u51C6\u5916\u65B0\u539F\u751F\u6A21\u5757", () => {
|
|
109
|
-
const result = negotiateBedrockDependencies(BASELINE_BEDROCK_DEPENDENCIES, [
|
|
110
|
-
{
|
|
111
|
-
folderId: "mod-gametest",
|
|
112
|
-
dependencies: [
|
|
113
|
-
{ module_name: "@minecraft/server-gametest", version: "1.0.0-beta" }
|
|
114
|
-
]
|
|
115
|
-
}
|
|
116
|
-
]);
|
|
117
|
-
assert.ok(result.dependencies.some((d) => d.module_name === "@minecraft/server-gametest"));
|
|
118
|
-
assert.equal(result.hasBetaApis, true);
|
|
119
|
-
});
|
|
120
|
-
//# sourceMappingURL=dependency-negotiator.test.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/dependency-negotiator.test.ts"],
|
|
4
|
-
"sourcesContent": ["import assert from \"node:assert/strict\";\nimport test from \"node:test\";\nimport {\n BASELINE_BEDROCK_DEPENDENCIES,\n cleanBedrockVersion,\n compareBedrockVersion,\n isGametestBetaRequired,\n negotiateBedrockDependencies,\n} from \"./dependency-negotiator.js\";\n\ntest(\"cleanBedrockVersion: \u6E05\u7406 npm range \u7B26\u53F7\", () => {\n assert.equal(cleanBedrockVersion(\"^2.0.0-beta\"), \"2.0.0-beta\");\n assert.equal(cleanBedrockVersion(\">=2.0.0-beta <3.0.0\"), \"2.0.0-beta\");\n assert.equal(cleanBedrockVersion(\"~1.3.0\"), \"1.3.0\");\n assert.equal(cleanBedrockVersion(\"v1.18.0\"), \"1.18.0\");\n assert.equal(cleanBedrockVersion(\" 1.2.0 \"), \"1.2.0\");\n});\n\ntest(\"compareBedrockVersion: \u5927\u7248\u672C\u4E0E\u6B21\u7248\u672C\u6BD4\u8F83\", () => {\n assert.ok(compareBedrockVersion(\"1.18.0\", \"1.3.0\") > 0);\n assert.ok(compareBedrockVersion(\"1.3.0\", \"1.18.0\") < 0);\n assert.equal(compareBedrockVersion(\"1.3.0\", \"1.3.0\"), 0);\n});\n\ntest(\"compareBedrockVersion: Beta \u4E0E\u6B63\u5F0F\u7248\u6BD4\u8F83\uFF08\u8DE8\u5927\u7248\u672C\u63D0\u5347\uFF09\", () => {\n // 2.0.0-beta \u5E94\u9AD8\u4E8E 1.3.0\n assert.ok(compareBedrockVersion(\"2.0.0-beta\", \"1.3.0\") > 0);\n // \u540C\u7248\u672C\u4E0B\u6B63\u5F0F\u7248\u9AD8\u4E8E\u6D4B\u8BD5\u7248\n assert.ok(compareBedrockVersion(\"2.0.0\", \"2.0.0-beta\") > 0);\n // \u4E24\u4E2A beta \u4E4B\u95F4\u6B21\u7248\u672C\u5BF9\u6BD4\n assert.ok(compareBedrockVersion(\"2.2.0-beta\", \"2.0.0-beta\") > 0);\n});\n\ntest(\"isGametestBetaRequired: \u51C6\u786E\u8BC6\u522B\u6D4B\u8BD5\u7248\u73A9\u6CD5\u9700\u6C42\", () => {\n // \u9700\u8981\u6D4B\u8BD5\u73A9\u6CD5\u7684\u9879\n assert.equal(\n isGametestBetaRequired({ module_name: \"@minecraft/server-ui\", version: \"2.0.0-beta\" }),\n true\n );\n assert.equal(\n isGametestBetaRequired({ module_name: \"@minecraft/server\", version: \"2.10.0-beta\" }),\n true\n );\n assert.equal(\n isGametestBetaRequired({ module_name: \"@minecraft/server-gametest\", version: \"1.0.0\" }),\n true\n );\n\n // \u4E0D\u9700\u8981\u6D4B\u8BD5\u73A9\u6CD5\u7684\u7A33\u5B9A\u7248\u6216\u7EAF\u6743\u9650\u6A21\u5757\n assert.equal(\n isGametestBetaRequired({ module_name: \"@minecraft/server-ui\", version: \"1.3.0\" }),\n false\n );\n assert.equal(\n isGametestBetaRequired({ module_name: \"@minecraft/server\", version: \"1.18.0\" }),\n false\n );\n assert.equal(\n isGametestBetaRequired({ module_name: \"@minecraft/server-net\", version: \"1.0.0-beta\" }),\n false\n );\n assert.equal(\n isGametestBetaRequired({ module_name: \"@minecraft/server-admin\", version: \"1.0.0-beta\" }),\n false\n );\n});\n\ntest(\"negotiateBedrockDependencies: \u65E0\u6A21\u7EC4\u9700\u6C42\u65F6\u4FDD\u6301\u57FA\u51C6\u4F9D\u8D56\", () => {\n const result = negotiateBedrockDependencies(BASELINE_BEDROCK_DEPENDENCIES, []);\n assert.equal(result.dependencies.length, BASELINE_BEDROCK_DEPENDENCIES.length);\n assert.equal(result.promotions.length, 0);\n assert.equal(result.hasBetaApis, false);\n\n const uiDep = result.dependencies.find((d) => d.module_name === \"@minecraft/server-ui\");\n assert.equal(uiDep?.version, \"1.3.0\");\n});\n\ntest(\"negotiateBedrockDependencies: \u5355\u6A21\u5757\u63D0\u5347 @minecraft/server-ui \u81F3 2.0.0-beta\", () => {\n const result = negotiateBedrockDependencies(BASELINE_BEDROCK_DEPENDENCIES, [\n {\n folderId: \"custom-menu\",\n dependencies: [\n { module_name: \"@minecraft/server-ui\", version: \"2.0.0-beta\" },\n ],\n },\n ]);\n\n const uiDep = result.dependencies.find((d) => d.module_name === \"@minecraft/server-ui\");\n assert.equal(uiDep?.version, \"2.0.0-beta\");\n assert.equal(result.hasBetaApis, true);\n assert.equal(result.promotions.length, 1);\n assert.equal(result.promotions[0].moduleName, \"@minecraft/server-ui\");\n assert.equal(result.promotions[0].from, \"1.3.0\");\n assert.equal(result.promotions[0].to, \"2.0.0-beta\");\n assert.deepEqual(result.promotions[0].requestedBy, [\"custom-menu\"]);\n});\n\ntest(\"negotiateBedrockDependencies: \u591A\u6A21\u5757\u4E0D\u540C\u7248\u672C\u9700\u6C42\u53D6\u6700\u9AD8\u517C\u5BB9\", () => {\n const result = negotiateBedrockDependencies(BASELINE_BEDROCK_DEPENDENCIES, [\n {\n folderId: \"mod-a\",\n dependencies: [\n { module_name: \"@minecraft/server-ui\", version: \"2.0.0-beta\" },\n ],\n },\n {\n folderId: \"mod-b\",\n dependencies: [\n { module_name: \"@minecraft/server-ui\", version: \"2.2.0-beta\" },\n ],\n },\n {\n folderId: \"mod-c\",\n dependencies: [\n { module_name: \"@minecraft/server-ui\", version: \"1.3.0\" },\n ],\n },\n ]);\n\n const uiDep = result.dependencies.find((d) => d.module_name === \"@minecraft/server-ui\");\n assert.equal(uiDep?.version, \"2.2.0-beta\");\n assert.equal(result.hasBetaApis, true);\n});\n\ntest(\"negotiateBedrockDependencies: \u652F\u6301\u5F15\u5165\u57FA\u51C6\u5916\u65B0\u539F\u751F\u6A21\u5757\", () => {\n const result = negotiateBedrockDependencies(BASELINE_BEDROCK_DEPENDENCIES, [\n {\n folderId: \"mod-gametest\",\n dependencies: [\n { module_name: \"@minecraft/server-gametest\", version: \"1.0.0-beta\" },\n ],\n },\n ]);\n\n assert.ok(result.dependencies.some((d) => d.module_name === \"@minecraft/server-gametest\"));\n assert.equal(result.hasBetaApis, true);\n});\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/fsx.test.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import fs from "node:fs";
|
|
3
|
-
import os from "node:os";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
import { describe, it } from "node:test";
|
|
6
|
-
import { copyDirSync, copyFileSyncSafe, getDirSize, rmSafe } from "./fsx.js";
|
|
7
|
-
describe("fsx: copyDirSync & copyFileSyncSafe", () => {
|
|
8
|
-
it("copyDirSync \u81EA\u52A8\u5FFD\u7565 .git / node_modules \u7B49\u5143\u6570\u636E", () => {
|
|
9
|
-
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "sfmc-fsx-test-"));
|
|
10
|
-
try {
|
|
11
|
-
const src = path.join(tmp, "src");
|
|
12
|
-
const dest = path.join(tmp, "dest");
|
|
13
|
-
fs.mkdirSync(path.join(src, ".git", "objects"), { recursive: true });
|
|
14
|
-
fs.mkdirSync(path.join(src, "scripts"), { recursive: true });
|
|
15
|
-
fs.writeFileSync(path.join(src, ".git", "HEAD"), "ref: refs/heads/main\n");
|
|
16
|
-
fs.writeFileSync(path.join(src, "scripts", "main.js"), "console.log('hello');\n");
|
|
17
|
-
fs.writeFileSync(path.join(src, ".DS_Store"), "junk");
|
|
18
|
-
copyDirSync(src, dest);
|
|
19
|
-
assert.ok(fs.existsSync(path.join(dest, "scripts", "main.js")));
|
|
20
|
-
assert.ok(!fs.existsSync(path.join(dest, ".git")));
|
|
21
|
-
assert.ok(!fs.existsSync(path.join(dest, ".DS_Store")));
|
|
22
|
-
} finally {
|
|
23
|
-
rmSafe(tmp);
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
it("copyFileSyncSafe \u80FD\u591F\u5B89\u5168\u8986\u5199 Windows \u5E73\u53F0\u4E0B\u7684\u53EA\u8BFB\u53EA\u8BFB\u5C5E\u6027\u6587\u4EF6", () => {
|
|
27
|
-
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "sfmc-fsx-ro-"));
|
|
28
|
-
try {
|
|
29
|
-
const src = path.join(tmp, "src.txt");
|
|
30
|
-
const dest = path.join(tmp, "dest.txt");
|
|
31
|
-
fs.writeFileSync(src, "version 2");
|
|
32
|
-
fs.writeFileSync(dest, "version 1");
|
|
33
|
-
fs.chmodSync(dest, 292);
|
|
34
|
-
copyFileSyncSafe(src, dest);
|
|
35
|
-
assert.equal(fs.readFileSync(dest, "utf8"), "version 2");
|
|
36
|
-
fs.writeFileSync(src, "version 3");
|
|
37
|
-
copyFileSyncSafe(src, dest);
|
|
38
|
-
assert.equal(fs.readFileSync(dest, "utf8"), "version 3");
|
|
39
|
-
} finally {
|
|
40
|
-
try {
|
|
41
|
-
fs.chmodSync(path.join(tmp, "dest.txt"), 438);
|
|
42
|
-
} catch {
|
|
43
|
-
}
|
|
44
|
-
rmSafe(tmp);
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
it("getDirSize \u5FFD\u7565 .git \u76EE\u5F55\u5927\u5C0F", () => {
|
|
48
|
-
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "sfmc-fsx-size-"));
|
|
49
|
-
try {
|
|
50
|
-
fs.mkdirSync(path.join(tmp, ".git"), { recursive: true });
|
|
51
|
-
fs.writeFileSync(path.join(tmp, ".git", "pack"), "x".repeat(1e4));
|
|
52
|
-
fs.writeFileSync(path.join(tmp, "data.txt"), "hello");
|
|
53
|
-
const size = getDirSize(tmp);
|
|
54
|
-
assert.equal(size, 5);
|
|
55
|
-
} finally {
|
|
56
|
-
rmSafe(tmp);
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
//# sourceMappingURL=fsx.test.js.map
|
package/dist/fsx.test.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/fsx.test.ts"],
|
|
4
|
-
"sourcesContent": ["import assert from \"node:assert/strict\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { describe, it } from \"node:test\";\nimport { copyDirSync, copyFileSyncSafe, getDirSize, rmSafe } from \"./fsx.js\";\n\ndescribe(\"fsx: copyDirSync & copyFileSyncSafe\", () => {\n it(\"copyDirSync \u81EA\u52A8\u5FFD\u7565 .git / node_modules \u7B49\u5143\u6570\u636E\", () => {\n const tmp = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-fsx-test-\"));\n try {\n const src = path.join(tmp, \"src\");\n const dest = path.join(tmp, \"dest\");\n fs.mkdirSync(path.join(src, \".git\", \"objects\"), { recursive: true });\n fs.mkdirSync(path.join(src, \"scripts\"), { recursive: true });\n fs.writeFileSync(path.join(src, \".git\", \"HEAD\"), \"ref: refs/heads/main\\n\");\n fs.writeFileSync(path.join(src, \"scripts\", \"main.js\"), \"console.log('hello');\\n\");\n fs.writeFileSync(path.join(src, \".DS_Store\"), \"junk\");\n\n copyDirSync(src, dest);\n\n assert.ok(fs.existsSync(path.join(dest, \"scripts\", \"main.js\")));\n assert.ok(!fs.existsSync(path.join(dest, \".git\")));\n assert.ok(!fs.existsSync(path.join(dest, \".DS_Store\")));\n } finally {\n rmSafe(tmp);\n }\n });\n\n it(\"copyFileSyncSafe \u80FD\u591F\u5B89\u5168\u8986\u5199 Windows \u5E73\u53F0\u4E0B\u7684\u53EA\u8BFB\u53EA\u8BFB\u5C5E\u6027\u6587\u4EF6\", () => {\n const tmp = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-fsx-ro-\"));\n try {\n const src = path.join(tmp, \"src.txt\");\n const dest = path.join(tmp, \"dest.txt\");\n fs.writeFileSync(src, \"version 2\");\n fs.writeFileSync(dest, \"version 1\");\n // \u8BBE\u7F6E\u76EE\u6807\u6587\u4EF6\u53EA\u8BFB (Windows 0444)\n fs.chmodSync(dest, 0o444);\n\n // copyFileSyncSafe \u5E94\u5F53\u6355\u83B7 EPERM \u5E76\u8986\u5199\u6210\u529F\uFF0C\u800C\u4E0D\u662F\u5D29\u6E83\n copyFileSyncSafe(src, dest);\n\n assert.equal(fs.readFileSync(dest, \"utf8\"), \"version 2\");\n\n // \u518D\u6B21\u8986\u5199\uFF0C\u786E\u4FDD\u4E0D\u4F1A\u9057\u7559\u53EA\u8BFB\u963B\u65AD\u4E0B\u4E00\u6B21\u5907\u4EFD\n fs.writeFileSync(src, \"version 3\");\n copyFileSyncSafe(src, dest);\n assert.equal(fs.readFileSync(dest, \"utf8\"), \"version 3\");\n } finally {\n try {\n fs.chmodSync(path.join(tmp, \"dest.txt\"), 0o666);\n } catch {}\n rmSafe(tmp);\n }\n });\n\n it(\"getDirSize \u5FFD\u7565 .git \u76EE\u5F55\u5927\u5C0F\", () => {\n const tmp = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-fsx-size-\"));\n try {\n fs.mkdirSync(path.join(tmp, \".git\"), { recursive: true });\n fs.writeFileSync(path.join(tmp, \".git\", \"pack\"), \"x\".repeat(10000));\n fs.writeFileSync(path.join(tmp, \"data.txt\"), \"hello\");\n\n const size = getDirSize(tmp);\n assert.equal(size, 5);\n } finally {\n rmSafe(tmp);\n }\n });\n});\n"],
|
|
5
|
-
"mappings": "AAAA,OAAO,YAAY;AACnB,OAAO,QAAQ;AACf,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,UAAU,UAAU;AAC7B,SAAS,aAAa,kBAAkB,YAAY,cAAc;AAElE,SAAS,uCAAuC,MAAM;AACpD,KAAG,qFAA6C,MAAM;AACpD,UAAM,MAAM,GAAG,YAAY,KAAK,KAAK,GAAG,OAAO,GAAG,gBAAgB,CAAC;AACnE,QAAI;AACF,YAAM,MAAM,KAAK,KAAK,KAAK,KAAK;AAChC,YAAM,OAAO,KAAK,KAAK,KAAK,MAAM;AAClC,SAAG,UAAU,KAAK,KAAK,KAAK,QAAQ,SAAS,GAAG,EAAE,WAAW,KAAK,CAAC;AACnE,SAAG,UAAU,KAAK,KAAK,KAAK,SAAS,GAAG,EAAE,WAAW,KAAK,CAAC;AAC3D,SAAG,cAAc,KAAK,KAAK,KAAK,QAAQ,MAAM,GAAG,wBAAwB;AACzE,SAAG,cAAc,KAAK,KAAK,KAAK,WAAW,SAAS,GAAG,yBAAyB;AAChF,SAAG,cAAc,KAAK,KAAK,KAAK,WAAW,GAAG,MAAM;AAEpD,kBAAY,KAAK,IAAI;AAErB,aAAO,GAAG,GAAG,WAAW,KAAK,KAAK,MAAM,WAAW,SAAS,CAAC,CAAC;AAC9D,aAAO,GAAG,CAAC,GAAG,WAAW,KAAK,KAAK,MAAM,MAAM,CAAC,CAAC;AACjD,aAAO,GAAG,CAAC,GAAG,WAAW,KAAK,KAAK,MAAM,WAAW,CAAC,CAAC;AAAA,IACxD,UAAE;AACA,aAAO,GAAG;AAAA,IACZ;AAAA,EACF,CAAC;AAED,KAAG,0IAAgD,MAAM;AACvD,UAAM,MAAM,GAAG,YAAY,KAAK,KAAK,GAAG,OAAO,GAAG,cAAc,CAAC;AACjE,QAAI;AACF,YAAM,MAAM,KAAK,KAAK,KAAK,SAAS;AACpC,YAAM,OAAO,KAAK,KAAK,KAAK,UAAU;AACtC,SAAG,cAAc,KAAK,WAAW;AACjC,SAAG,cAAc,MAAM,WAAW;AAElC,SAAG,UAAU,MAAM,GAAK;AAGxB,uBAAiB,KAAK,IAAI;AAE1B,aAAO,MAAM,GAAG,aAAa,MAAM,MAAM,GAAG,WAAW;AAGvD,SAAG,cAAc,KAAK,WAAW;AACjC,uBAAiB,KAAK,IAAI;AAC1B,aAAO,MAAM,GAAG,aAAa,MAAM,MAAM,GAAG,WAAW;AAAA,IACzD,UAAE;AACA,UAAI;AACF,WAAG,UAAU,KAAK,KAAK,KAAK,UAAU,GAAG,GAAK;AAAA,MAChD,QAAQ;AAAA,MAAC;AACT,aAAO,GAAG;AAAA,IACZ;AAAA,EACF,CAAC;AAED,KAAG,yDAA2B,MAAM;AAClC,UAAM,MAAM,GAAG,YAAY,KAAK,KAAK,GAAG,OAAO,GAAG,gBAAgB,CAAC;AACnE,QAAI;AACF,SAAG,UAAU,KAAK,KAAK,KAAK,MAAM,GAAG,EAAE,WAAW,KAAK,CAAC;AACxD,SAAG,cAAc,KAAK,KAAK,KAAK,QAAQ,MAAM,GAAG,IAAI,OAAO,GAAK,CAAC;AAClE,SAAG,cAAc,KAAK,KAAK,KAAK,UAAU,GAAG,OAAO;AAEpD,YAAM,OAAO,WAAW,GAAG;AAC3B,aAAO,MAAM,MAAM,CAAC;AAAA,IACtB,UAAE;AACA,aAAO,GAAG;AAAA,IACZ;AAAA,EACF,CAAC;AACH,CAAC;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/level-dat.test.js
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import fs from "node:fs";
|
|
3
|
-
import os from "node:os";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
import test from "node:test";
|
|
6
|
-
import {
|
|
7
|
-
enableBetaApisInLevelDat,
|
|
8
|
-
enableExperimentsInLevelDat,
|
|
9
|
-
KNOWN_EXPERIMENTS,
|
|
10
|
-
parseBedrockLevelDat,
|
|
11
|
-
readLevelDatExperiments,
|
|
12
|
-
resolveExperimentDefinition,
|
|
13
|
-
TAG_BYTE,
|
|
14
|
-
TAG_COMPOUND,
|
|
15
|
-
TAG_END
|
|
16
|
-
} from "./level-dat.js";
|
|
17
|
-
function buildMockLevelDat(includeExperiments, gametestVal) {
|
|
18
|
-
const rootName = "";
|
|
19
|
-
const rootNameBuf = Buffer.from(rootName, "utf8");
|
|
20
|
-
const childBuffers = [];
|
|
21
|
-
const sampleName = Buffer.from("LevelName", "utf8");
|
|
22
|
-
const sampleVal = Buffer.from("TestWorld", "utf8");
|
|
23
|
-
const strTag = Buffer.alloc(1 + 2 + sampleName.length + 2 + sampleVal.length);
|
|
24
|
-
strTag.writeUInt8(8, 0);
|
|
25
|
-
strTag.writeUInt16LE(sampleName.length, 1);
|
|
26
|
-
sampleName.copy(strTag, 3);
|
|
27
|
-
strTag.writeUInt16LE(sampleVal.length, 3 + sampleName.length);
|
|
28
|
-
sampleVal.copy(strTag, 5 + sampleName.length);
|
|
29
|
-
childBuffers.push(strTag);
|
|
30
|
-
if (includeExperiments) {
|
|
31
|
-
const expName = Buffer.from("experiments", "utf8");
|
|
32
|
-
const expChildren = [];
|
|
33
|
-
const everUsedName = Buffer.from("experiments_ever_used", "utf8");
|
|
34
|
-
const b1 = Buffer.alloc(1 + 2 + everUsedName.length + 1);
|
|
35
|
-
b1.writeUInt8(TAG_BYTE, 0);
|
|
36
|
-
b1.writeUInt16LE(everUsedName.length, 1);
|
|
37
|
-
everUsedName.copy(b1, 3);
|
|
38
|
-
b1.writeInt8(0, 3 + everUsedName.length);
|
|
39
|
-
expChildren.push(b1);
|
|
40
|
-
if (gametestVal !== void 0) {
|
|
41
|
-
const gtName = Buffer.from("gametest", "utf8");
|
|
42
|
-
const b2 = Buffer.alloc(1 + 2 + gtName.length + 1);
|
|
43
|
-
b2.writeUInt8(TAG_BYTE, 0);
|
|
44
|
-
b2.writeUInt16LE(gtName.length, 1);
|
|
45
|
-
gtName.copy(b2, 3);
|
|
46
|
-
b2.writeInt8(gametestVal, 3 + gtName.length);
|
|
47
|
-
expChildren.push(b2);
|
|
48
|
-
}
|
|
49
|
-
expChildren.push(Buffer.from([TAG_END]));
|
|
50
|
-
const expHeader = Buffer.alloc(1 + 2 + expName.length);
|
|
51
|
-
expHeader.writeUInt8(TAG_COMPOUND, 0);
|
|
52
|
-
expHeader.writeUInt16LE(expName.length, 1);
|
|
53
|
-
expName.copy(expHeader, 3);
|
|
54
|
-
childBuffers.push(Buffer.concat([expHeader, ...expChildren]));
|
|
55
|
-
}
|
|
56
|
-
childBuffers.push(Buffer.from([TAG_END]));
|
|
57
|
-
const rootHeader = Buffer.alloc(1 + 2 + rootNameBuf.length);
|
|
58
|
-
rootHeader.writeUInt8(TAG_COMPOUND, 0);
|
|
59
|
-
rootHeader.writeUInt16LE(rootNameBuf.length, 1);
|
|
60
|
-
rootNameBuf.copy(rootHeader, 3);
|
|
61
|
-
const nbtBody = Buffer.concat([rootHeader, ...childBuffers]);
|
|
62
|
-
const fileHeader = Buffer.alloc(8);
|
|
63
|
-
fileHeader.writeUInt32LE(10, 0);
|
|
64
|
-
fileHeader.writeUInt32LE(nbtBody.length, 4);
|
|
65
|
-
return Buffer.concat([fileHeader, nbtBody]);
|
|
66
|
-
}
|
|
67
|
-
test("readLevelDatExperiments: correctly reads experiments status", () => {
|
|
68
|
-
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sfmc-lvl-test-"));
|
|
69
|
-
try {
|
|
70
|
-
const file = path.join(tmpDir, "level.dat");
|
|
71
|
-
fs.writeFileSync(file, buildMockLevelDat(true));
|
|
72
|
-
const info1 = readLevelDatExperiments(file);
|
|
73
|
-
assert.ok(info1);
|
|
74
|
-
assert.equal(info1.hasBetaApis, false);
|
|
75
|
-
assert.equal(info1.experimentsEverUsed, false);
|
|
76
|
-
assert.equal(info1.knownExperiments.gametest, false);
|
|
77
|
-
assert.equal(info1.knownExperiments.upcoming_creator_features, false);
|
|
78
|
-
fs.writeFileSync(file, buildMockLevelDat(true, 1));
|
|
79
|
-
const info2 = readLevelDatExperiments(file);
|
|
80
|
-
assert.ok(info2);
|
|
81
|
-
assert.equal(info2.hasBetaApis, true);
|
|
82
|
-
assert.equal(info2.knownExperiments.gametest, true);
|
|
83
|
-
} finally {
|
|
84
|
-
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
test("resolveExperimentDefinition: resolves aliases and canonical ids", () => {
|
|
88
|
-
assert.equal(resolveExperimentDefinition("upcoming")?.id, "upcoming_creator_features");
|
|
89
|
-
assert.equal(resolveExperimentDefinition("cameras")?.id, "experimental_creator_cameras");
|
|
90
|
-
assert.equal(resolveExperimentDefinition("voxel")?.id, "voxel_shapes");
|
|
91
|
-
assert.equal(resolveExperimentDefinition("trades")?.id, "villager_trades_rebalance");
|
|
92
|
-
assert.equal(resolveExperimentDefinition("drop3")?.id, "drop_3_2026");
|
|
93
|
-
assert.equal(resolveExperimentDefinition("wilderness_bound")?.id, "drop_3_2026");
|
|
94
|
-
assert.equal(resolveExperimentDefinition("edu")?.id, "education");
|
|
95
|
-
assert.equal(resolveExperimentDefinition("unknown_feature"), null);
|
|
96
|
-
});
|
|
97
|
-
test("enableBetaApisInLevelDat: enables gametest and updates header length", async () => {
|
|
98
|
-
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sfmc-lvl-test-"));
|
|
99
|
-
try {
|
|
100
|
-
const file = path.join(tmpDir, "level.dat");
|
|
101
|
-
fs.writeFileSync(file, buildMockLevelDat(true));
|
|
102
|
-
const res1 = await enableBetaApisInLevelDat(file);
|
|
103
|
-
assert.equal(res1.success, true);
|
|
104
|
-
assert.equal(res1.changed, true);
|
|
105
|
-
assert.ok(res1.backupPath && fs.existsSync(res1.backupPath));
|
|
106
|
-
const info = readLevelDatExperiments(file);
|
|
107
|
-
assert.ok(info);
|
|
108
|
-
assert.equal(info.hasBetaApis, true);
|
|
109
|
-
assert.equal(info.experimentsEverUsed, true);
|
|
110
|
-
assert.equal(info.savedWithToggledExperiments, true);
|
|
111
|
-
const finalBuf = fs.readFileSync(file);
|
|
112
|
-
const parsed = parseBedrockLevelDat(finalBuf);
|
|
113
|
-
assert.equal(parsed.dataLength, finalBuf.length - 8);
|
|
114
|
-
const res2 = await enableBetaApisInLevelDat(file);
|
|
115
|
-
assert.equal(res2.success, true);
|
|
116
|
-
assert.equal(res2.changed, false);
|
|
117
|
-
} finally {
|
|
118
|
-
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
test("enableExperimentsInLevelDat: enables all known experiments and handles education root tag", async () => {
|
|
122
|
-
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sfmc-lvl-test-"));
|
|
123
|
-
try {
|
|
124
|
-
const file = path.join(tmpDir, "level.dat");
|
|
125
|
-
fs.writeFileSync(file, buildMockLevelDat(true));
|
|
126
|
-
const res = await enableExperimentsInLevelDat(file, "all");
|
|
127
|
-
assert.equal(res.success, true);
|
|
128
|
-
assert.equal(res.changed, true);
|
|
129
|
-
const info = readLevelDatExperiments(file);
|
|
130
|
-
assert.ok(info);
|
|
131
|
-
assert.equal(info.hasBetaApis, true);
|
|
132
|
-
assert.equal(info.experimentsEverUsed, true);
|
|
133
|
-
assert.equal(info.savedWithToggledExperiments, true);
|
|
134
|
-
for (const def of KNOWN_EXPERIMENTS) {
|
|
135
|
-
assert.equal(info.knownExperiments[def.id], true, `Experiment ${def.id} should be enabled`);
|
|
136
|
-
}
|
|
137
|
-
const finalBuf = fs.readFileSync(file);
|
|
138
|
-
const parsed = parseBedrockLevelDat(finalBuf);
|
|
139
|
-
assert.equal(parsed.dataLength, finalBuf.length - 8);
|
|
140
|
-
const eduRoot = parsed.rootChildren.get("educationFeaturesEnabled");
|
|
141
|
-
assert.ok(eduRoot);
|
|
142
|
-
assert.equal(eduRoot.value, 1);
|
|
143
|
-
const res2 = await enableExperimentsInLevelDat(file, "all");
|
|
144
|
-
assert.equal(res2.success, true);
|
|
145
|
-
assert.equal(res2.changed, false);
|
|
146
|
-
} finally {
|
|
147
|
-
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
test("enableExperimentsInLevelDat: enables specific subset from scratch (no experiments compound)", async () => {
|
|
151
|
-
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sfmc-lvl-test-"));
|
|
152
|
-
try {
|
|
153
|
-
const file = path.join(tmpDir, "level.dat");
|
|
154
|
-
fs.writeFileSync(file, buildMockLevelDat(false));
|
|
155
|
-
const res = await enableExperimentsInLevelDat(file, ["upcoming", "voxel", "edu"]);
|
|
156
|
-
assert.equal(res.success, true);
|
|
157
|
-
assert.equal(res.changed, true);
|
|
158
|
-
const info = readLevelDatExperiments(file);
|
|
159
|
-
assert.ok(info);
|
|
160
|
-
assert.equal(info.knownExperiments.upcoming_creator_features, true);
|
|
161
|
-
assert.equal(info.knownExperiments.voxel_shapes, true);
|
|
162
|
-
assert.equal(info.knownExperiments.education, true);
|
|
163
|
-
assert.equal(info.knownExperiments.gametest, false);
|
|
164
|
-
assert.equal(info.knownExperiments.villager_trades_rebalance, false);
|
|
165
|
-
const finalBuf = fs.readFileSync(file);
|
|
166
|
-
const parsed = parseBedrockLevelDat(finalBuf);
|
|
167
|
-
assert.equal(parsed.dataLength, finalBuf.length - 8);
|
|
168
|
-
} finally {
|
|
169
|
-
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
170
|
-
}
|
|
171
|
-
});
|
|
172
|
-
//# sourceMappingURL=level-dat.test.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/level-dat.test.ts"],
|
|
4
|
-
"sourcesContent": ["import assert from \"node:assert/strict\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport test from \"node:test\";\nimport {\n enableBetaApisInLevelDat,\n enableExperimentsInLevelDat,\n KNOWN_EXPERIMENTS,\n parseBedrockLevelDat,\n readLevelDatExperiments,\n resolveExperimentDefinition,\n TAG_BYTE,\n TAG_COMPOUND,\n TAG_END,\n} from \"./level-dat.js\";\n\nfunction buildMockLevelDat(includeExperiments: boolean, gametestVal?: number): Buffer {\n const rootName = \"\";\n const rootNameBuf = Buffer.from(rootName, \"utf8\");\n\n const childBuffers: Buffer[] = [];\n\n // Random sample tag\n const sampleName = Buffer.from(\"LevelName\", \"utf8\");\n const sampleVal = Buffer.from(\"TestWorld\", \"utf8\");\n const strTag = Buffer.alloc(1 + 2 + sampleName.length + 2 + sampleVal.length);\n strTag.writeUInt8(8, 0); // TAG_String\n strTag.writeUInt16LE(sampleName.length, 1);\n sampleName.copy(strTag, 3);\n strTag.writeUInt16LE(sampleVal.length, 3 + sampleName.length);\n sampleVal.copy(strTag, 5 + sampleName.length);\n childBuffers.push(strTag);\n\n if (includeExperiments) {\n const expName = Buffer.from(\"experiments\", \"utf8\");\n const expChildren: Buffer[] = [];\n\n // experiments_ever_used = 0\n const everUsedName = Buffer.from(\"experiments_ever_used\", \"utf8\");\n const b1 = Buffer.alloc(1 + 2 + everUsedName.length + 1);\n b1.writeUInt8(TAG_BYTE, 0);\n b1.writeUInt16LE(everUsedName.length, 1);\n everUsedName.copy(b1, 3);\n b1.writeInt8(0, 3 + everUsedName.length);\n expChildren.push(b1);\n\n if (gametestVal !== undefined) {\n const gtName = Buffer.from(\"gametest\", \"utf8\");\n const b2 = Buffer.alloc(1 + 2 + gtName.length + 1);\n b2.writeUInt8(TAG_BYTE, 0);\n b2.writeUInt16LE(gtName.length, 1);\n gtName.copy(b2, 3);\n b2.writeInt8(gametestVal, 3 + gtName.length);\n expChildren.push(b2);\n }\n\n expChildren.push(Buffer.from([TAG_END]));\n\n const expHeader = Buffer.alloc(1 + 2 + expName.length);\n expHeader.writeUInt8(TAG_COMPOUND, 0);\n expHeader.writeUInt16LE(expName.length, 1);\n expName.copy(expHeader, 3);\n\n childBuffers.push(Buffer.concat([expHeader, ...expChildren]));\n }\n\n childBuffers.push(Buffer.from([TAG_END]));\n\n const rootHeader = Buffer.alloc(1 + 2 + rootNameBuf.length);\n rootHeader.writeUInt8(TAG_COMPOUND, 0);\n rootHeader.writeUInt16LE(rootNameBuf.length, 1);\n rootNameBuf.copy(rootHeader, 3);\n\n const nbtBody = Buffer.concat([rootHeader, ...childBuffers]);\n\n const fileHeader = Buffer.alloc(8);\n fileHeader.writeUInt32LE(10, 0); // version 10\n fileHeader.writeUInt32LE(nbtBody.length, 4);\n\n return Buffer.concat([fileHeader, nbtBody]);\n}\n\ntest(\"readLevelDatExperiments: correctly reads experiments status\", () => {\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-lvl-test-\"));\n try {\n const file = path.join(tmpDir, \"level.dat\");\n\n // 1. Without gametest\n fs.writeFileSync(file, buildMockLevelDat(true));\n const info1 = readLevelDatExperiments(file);\n assert.ok(info1);\n assert.equal(info1.hasBetaApis, false);\n assert.equal(info1.experimentsEverUsed, false);\n assert.equal(info1.knownExperiments.gametest, false);\n assert.equal(info1.knownExperiments.upcoming_creator_features, false);\n\n // 2. With gametest = 1\n fs.writeFileSync(file, buildMockLevelDat(true, 1));\n const info2 = readLevelDatExperiments(file);\n assert.ok(info2);\n assert.equal(info2.hasBetaApis, true);\n assert.equal(info2.knownExperiments.gametest, true);\n } finally {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n }\n});\n\ntest(\"resolveExperimentDefinition: resolves aliases and canonical ids\", () => {\n assert.equal(resolveExperimentDefinition(\"upcoming\")?.id, \"upcoming_creator_features\");\n assert.equal(resolveExperimentDefinition(\"cameras\")?.id, \"experimental_creator_cameras\");\n assert.equal(resolveExperimentDefinition(\"voxel\")?.id, \"voxel_shapes\");\n assert.equal(resolveExperimentDefinition(\"trades\")?.id, \"villager_trades_rebalance\");\n assert.equal(resolveExperimentDefinition(\"drop3\")?.id, \"drop_3_2026\");\n assert.equal(resolveExperimentDefinition(\"wilderness_bound\")?.id, \"drop_3_2026\");\n assert.equal(resolveExperimentDefinition(\"edu\")?.id, \"education\");\n assert.equal(resolveExperimentDefinition(\"unknown_feature\"), null);\n});\n\ntest(\"enableBetaApisInLevelDat: enables gametest and updates header length\", async () => {\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-lvl-test-\"));\n try {\n const file = path.join(tmpDir, \"level.dat\");\n fs.writeFileSync(file, buildMockLevelDat(true));\n\n const res1 = await enableBetaApisInLevelDat(file);\n assert.equal(res1.success, true);\n assert.equal(res1.changed, true);\n assert.ok(res1.backupPath && fs.existsSync(res1.backupPath));\n\n // Check after change\n const info = readLevelDatExperiments(file);\n assert.ok(info);\n assert.equal(info.hasBetaApis, true);\n assert.equal(info.experimentsEverUsed, true);\n assert.equal(info.savedWithToggledExperiments, true);\n\n // Verify header length matches buffer length\n const finalBuf = fs.readFileSync(file);\n const parsed = parseBedrockLevelDat(finalBuf);\n assert.equal(parsed.dataLength, finalBuf.length - 8);\n\n // Idempotency test: second run shouldn't change\n const res2 = await enableBetaApisInLevelDat(file);\n assert.equal(res2.success, true);\n assert.equal(res2.changed, false);\n } finally {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n }\n});\n\ntest(\"enableExperimentsInLevelDat: enables all known experiments and handles education root tag\", async () => {\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-lvl-test-\"));\n try {\n const file = path.join(tmpDir, \"level.dat\");\n fs.writeFileSync(file, buildMockLevelDat(true));\n\n const res = await enableExperimentsInLevelDat(file, \"all\");\n assert.equal(res.success, true);\n assert.equal(res.changed, true);\n\n const info = readLevelDatExperiments(file);\n assert.ok(info);\n assert.equal(info.hasBetaApis, true);\n assert.equal(info.experimentsEverUsed, true);\n assert.equal(info.savedWithToggledExperiments, true);\n\n // All known experiments must be true\n for (const def of KNOWN_EXPERIMENTS) {\n assert.equal(info.knownExperiments[def.id], true, `Experiment ${def.id} should be enabled`);\n }\n\n // Verify root educationFeaturesEnabled is 1\n const finalBuf = fs.readFileSync(file);\n const parsed = parseBedrockLevelDat(finalBuf);\n assert.equal(parsed.dataLength, finalBuf.length - 8);\n\n const eduRoot = parsed.rootChildren.get(\"educationFeaturesEnabled\");\n assert.ok(eduRoot);\n assert.equal(eduRoot.value, 1);\n\n // Second run should be idempotent\n const res2 = await enableExperimentsInLevelDat(file, \"all\");\n assert.equal(res2.success, true);\n assert.equal(res2.changed, false);\n } finally {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n }\n});\n\ntest(\"enableExperimentsInLevelDat: enables specific subset from scratch (no experiments compound)\", async () => {\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-lvl-test-\"));\n try {\n const file = path.join(tmpDir, \"level.dat\");\n fs.writeFileSync(file, buildMockLevelDat(false));\n\n const res = await enableExperimentsInLevelDat(file, [\"upcoming\", \"voxel\", \"edu\"]);\n assert.equal(res.success, true);\n assert.equal(res.changed, true);\n\n const info = readLevelDatExperiments(file);\n assert.ok(info);\n assert.equal(info.knownExperiments.upcoming_creator_features, true);\n assert.equal(info.knownExperiments.voxel_shapes, true);\n assert.equal(info.knownExperiments.education, true);\n assert.equal(info.knownExperiments.gametest, false);\n assert.equal(info.knownExperiments.villager_trades_rebalance, false);\n\n const finalBuf = fs.readFileSync(file);\n const parsed = parseBedrockLevelDat(finalBuf);\n assert.equal(parsed.dataLength, finalBuf.length - 8);\n } finally {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n }\n});\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|