@sfmc-bds/cli 0.2.0-beta.20 → 0.2.0-beta.21

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 (61) hide show
  1. package/dist/bds-runtime-version.d.ts +3 -0
  2. package/dist/bds-runtime-version.d.ts.map +1 -0
  3. package/dist/bds-runtime-version.js +15 -0
  4. package/dist/bds-runtime-version.js.map +7 -0
  5. package/dist/commands.d.ts.map +1 -1
  6. package/dist/commands.js +78 -75
  7. package/dist/commands.js.map +2 -2
  8. package/dist/llbot-launch.d.ts +3 -3
  9. package/dist/llbot-launch.js.map +1 -1
  10. package/dist/logs.js +3 -3
  11. package/dist/logs.js.map +2 -2
  12. package/dist/repl-windows/service-window.d.ts.map +1 -1
  13. package/dist/repl-windows/service-window.js +1 -0
  14. package/dist/repl-windows/service-window.js.map +2 -2
  15. package/dist/repl.d.ts.map +1 -1
  16. package/dist/repl.js +18 -12
  17. package/dist/repl.js.map +2 -2
  18. package/dist/send-target.d.ts.map +1 -1
  19. package/dist/send-target.js +2 -0
  20. package/dist/send-target.js.map +2 -2
  21. package/dist/services.d.ts +8 -1
  22. package/dist/services.d.ts.map +1 -1
  23. package/dist/services.js +151 -15
  24. package/dist/services.js.map +2 -2
  25. package/dist/ui-command.d.ts.map +1 -1
  26. package/dist/ui-command.js.map +2 -2
  27. package/dist/wizard.d.ts.map +1 -1
  28. package/dist/wizard.js +15 -8
  29. package/dist/wizard.js.map +2 -2
  30. package/package.json +4 -5
  31. package/scripts/module-install/lib/catalog.mjs +1 -1
  32. package/dist/command-surface.test.js +0 -92
  33. package/dist/command-surface.test.js.map +0 -7
  34. package/dist/debug-command.test.js +0 -76
  35. package/dist/debug-command.test.js.map +0 -7
  36. package/dist/log-filter.test.js +0 -181
  37. package/dist/log-filter.test.js.map +0 -7
  38. package/dist/log-translator.test.js +0 -120
  39. package/dist/log-translator.test.js.map +0 -7
  40. package/dist/logs-blank-line.test.js +0 -16
  41. package/dist/logs-blank-line.test.js.map +0 -7
  42. package/dist/module-toggle.test.js +0 -37
  43. package/dist/module-toggle.test.js.map +0 -7
  44. package/dist/pack-bundle.test.js +0 -111
  45. package/dist/pack-bundle.test.js.map +0 -7
  46. package/dist/player-session.test.js +0 -19
  47. package/dist/player-session.test.js.map +0 -7
  48. package/dist/repl-windows/host.test.js +0 -72
  49. package/dist/repl-windows/host.test.js.map +0 -7
  50. package/dist/services-output.test.js +0 -9
  51. package/dist/services-output.test.js.map +0 -7
  52. package/dist/world-packs-list.test.js +0 -11
  53. package/dist/world-packs-list.test.js.map +0 -7
  54. package/dist/world-packs-uninstall.test.js +0 -54
  55. package/dist/world-packs-uninstall.test.js.map +0 -7
  56. package/scripts/module-install/test/check-modules-config.test.ts +0 -46
  57. package/scripts/module-install/test/config-seeding.test.ts +0 -99
  58. package/scripts/module-install/test/install-resolver.test.ts +0 -47
  59. package/scripts/module-install/test/link-local.test.ts +0 -50
  60. package/scripts/module-install/test/local-resolver.test.ts +0 -44
  61. package/scripts/module-install/test/registry-index.test.ts +0 -27
@@ -1,181 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import { compileLogFilterRegex, evaluateLogFilter } from "./log-filter.js";
4
- const entry = (over = {}) => ({
5
- text: "Player connected: Steve",
6
- source: "bds",
7
- level: "info",
8
- ...over
9
- });
10
- const baseCfg = (over = {}) => ({
11
- enabled: true,
12
- mode: "drop",
13
- applyTo: "display",
14
- rules: [],
15
- ...over
16
- });
17
- test("enabled=false \u6C38\u4E0D\u4E22\u5F03", () => {
18
- const r = evaluateLogFilter(
19
- entry(),
20
- baseCfg({
21
- enabled: false,
22
- mode: "keep",
23
- rules: [{ sources: ["bds"] }]
24
- })
25
- );
26
- assert.equal(r.dropDisplay, false);
27
- assert.equal(r.dropDisk, false);
28
- });
29
- test("drop \xD7 sources \u547D\u4E2D\u5219\u4E22\u5F03\u5C55\u793A", () => {
30
- const r = evaluateLogFilter(entry(), baseCfg({ rules: [{ sources: ["bds", "pack"] }] }));
31
- assert.equal(r.matched, true);
32
- assert.equal(r.dropDisplay, true);
33
- assert.equal(r.dropDisk, false);
34
- });
35
- test("drop \xD7 sources \u672A\u547D\u4E2D\u5219\u4FDD\u7559", () => {
36
- const r = evaluateLogFilter(entry({ source: "system" }), baseCfg({ rules: [{ sources: ["bds"] }] }));
37
- assert.equal(r.matched, false);
38
- assert.equal(r.dropDisplay, false);
39
- });
40
- test("drop \xD7 levels", () => {
41
- const hit = evaluateLogFilter(entry({ level: "debug" }), baseCfg({ rules: [{ levels: ["debug", "info"] }] }));
42
- const miss = evaluateLogFilter(entry({ level: "error" }), baseCfg({ rules: [{ levels: ["debug"] }] }));
43
- assert.equal(hit.dropDisplay, true);
44
- assert.equal(miss.dropDisplay, false);
45
- });
46
- test("drop \xD7 contains\uFF08\u5927\u5C0F\u5199\u654F\u611F\uFF09", () => {
47
- const hit = evaluateLogFilter(entry(), baseCfg({ rules: [{ contains: "Player connected" }] }));
48
- const miss = evaluateLogFilter(entry(), baseCfg({ rules: [{ contains: "player connected" }] }));
49
- assert.equal(hit.dropDisplay, true);
50
- assert.equal(miss.dropDisplay, false);
51
- });
52
- test("drop \xD7 regex \u4E0E (?i) \u65D7\u6807", () => {
53
- const hit = evaluateLogFilter(
54
- entry({ text: "GAMERULE keepInventory" }),
55
- baseCfg({ rules: [{ regex: "(?i)gamerule|syntax error" }] })
56
- );
57
- const miss = evaluateLogFilter(entry({ text: "hello" }), baseCfg({ rules: [{ regex: "(?i)gamerule" }] }));
58
- assert.equal(hit.dropDisplay, true);
59
- assert.equal(miss.dropDisplay, false);
60
- assert.ok(compileLogFilterRegex("(?i)ABC")?.test("abc"));
61
- assert.equal(compileLogFilterRegex("("), null);
62
- });
63
- test("\u540C\u6761 AND\uFF1Asources + contains \u987B\u540C\u65F6\u6EE1\u8DB3", () => {
64
- const both = evaluateLogFilter(entry(), baseCfg({ rules: [{ sources: ["bds"], contains: "Player" }] }));
65
- const onlySource = evaluateLogFilter(
66
- entry({ text: "nope" }),
67
- baseCfg({ rules: [{ sources: ["bds"], contains: "Player" }] })
68
- );
69
- assert.equal(both.dropDisplay, true);
70
- assert.equal(onlySource.dropDisplay, false);
71
- });
72
- test("\u591A\u6761 OR\uFF1A\u4EFB\u4E00\u547D\u4E2D\u5373\u53EF", () => {
73
- const r = evaluateLogFilter(
74
- entry({ source: "pack", text: "done" }),
75
- baseCfg({
76
- rules: [{ sources: ["bds"] }, { sources: ["pack"], contains: "done" }]
77
- })
78
- );
79
- assert.equal(r.matched, true);
80
- assert.equal(r.dropDisplay, true);
81
- });
82
- test("rule.enabled=false \u8DF3\u8FC7", () => {
83
- const r = evaluateLogFilter(entry(), baseCfg({ rules: [{ enabled: false, sources: ["bds"] }] }));
84
- assert.equal(r.matched, false);
85
- assert.equal(r.dropDisplay, false);
86
- });
87
- test("keep \u6A21\u5F0F\uFF1A\u4EC5\u4FDD\u7559\u5339\u914D\uFF0C\u672A\u5339\u914D\u4E22\u5F03", () => {
88
- const cfg = baseCfg({
89
- mode: "keep",
90
- rules: [{ levels: ["error"] }]
91
- });
92
- const keep = evaluateLogFilter(entry({ level: "error" }), cfg);
93
- const drop = evaluateLogFilter(entry({ level: "info" }), cfg);
94
- assert.equal(keep.dropDisplay, false);
95
- assert.equal(drop.dropDisplay, true);
96
- });
97
- test("applyTo=all \u65F6\u843D\u76D8\u4E0E\u5C55\u793A\u4E00\u5E76\u8FC7\u6EE4", () => {
98
- const r = evaluateLogFilter(
99
- entry(),
100
- baseCfg({
101
- applyTo: "all",
102
- rules: [{ sources: ["bds"] }]
103
- })
104
- );
105
- assert.equal(r.dropDisplay, true);
106
- assert.equal(r.dropDisk, true);
107
- });
108
- test("applyTo=display \u65F6\u4EC5\u5F71\u54CD\u5C55\u793A", () => {
109
- const r = evaluateLogFilter(
110
- entry(),
111
- baseCfg({
112
- applyTo: "display",
113
- rules: [{ sources: ["bds"] }]
114
- })
115
- );
116
- assert.equal(r.dropDisplay, true);
117
- assert.equal(r.dropDisk, false);
118
- });
119
- test("evaluateLogFilter: \u5185\u7F6E BDS \u7FFB\u8BD1\u81EA\u52A8\u751F\u6548", () => {
120
- const r = evaluateLogFilter(
121
- entry({
122
- source: "bds",
123
- text: "Server started."
124
- }),
125
- baseCfg({
126
- enabled: false,
127
- translate: true
128
- })
129
- );
130
- assert.equal(r.transformedEntry.text, "[\u670D\u52A1\u7AEF] BDS \u670D\u52A1\u7AEF\u5DF2\u6210\u529F\u542F\u52A8\uFF0C\u51C6\u5907\u5C31\u7EEA\u3002");
131
- });
132
- test("evaluateLogFilter: \u81EA\u5B9A\u4E49 rule.replace \u4F18\u5148\u4E8E\u5185\u7F6E\u7FFB\u8BD1", () => {
133
- const r = evaluateLogFilter(
134
- entry({
135
- source: "bds",
136
- text: "Server started."
137
- }),
138
- baseCfg({
139
- enabled: true,
140
- rules: [
141
- {
142
- sources: ["bds"],
143
- contains: "Server started.",
144
- replace: ">> \u670D\u52A1\u5668\u51C6\u5907\u5B8C\u6BD5 <<"
145
- }
146
- ]
147
- })
148
- );
149
- assert.equal(r.transformedEntry.text, ">> \u670D\u52A1\u5668\u51C6\u5907\u5B8C\u6BD5 <<");
150
- });
151
- test("evaluateLogFilter: \u81EA\u5B9A\u4E49 rule.replace \u652F\u6301\u6B63\u5219\u6355\u83B7\u7EC4", () => {
152
- const r = evaluateLogFilter(
153
- entry({
154
- source: "system",
155
- text: "Job backup_world completed in 42ms"
156
- }),
157
- baseCfg({
158
- enabled: true,
159
- rules: [
160
- {
161
- regex: "Job (\\w+) completed in (\\d+)ms",
162
- replace: "\u4EFB\u52A1 $1 \u5B8C\u6210 (\u8017\u65F6: $2\u6BEB\u79D2)"
163
- }
164
- ]
165
- })
166
- );
167
- assert.equal(r.transformedEntry.text, "\u4EFB\u52A1 backup_world \u5B8C\u6210 (\u8017\u65F6: 42\u6BEB\u79D2)");
168
- });
169
- test("evaluateLogFilter: translate=false \u65F6\u4E0D\u89E6\u53D1\u5185\u7F6E\u7FFB\u8BD1", () => {
170
- const r = evaluateLogFilter(
171
- entry({
172
- source: "bds",
173
- text: "Server started."
174
- }),
175
- baseCfg({
176
- translate: false
177
- })
178
- );
179
- assert.equal(r.transformedEntry.text, "Server started.");
180
- });
181
- //# sourceMappingURL=log-filter.test.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/log-filter.test.ts"],
4
- "sourcesContent": ["/**\n * log-filter \u7EAF\u51FD\u6570\u8868\u9A71\u52A8\uFF08\u4E0D\u6D4B IO\uFF09\n */\nimport assert from \"node:assert/strict\";\nimport test from \"node:test\";\nimport { compileLogFilterRegex, evaluateLogFilter } from \"./log-filter.js\";\n\nconst entry = (over: Record<string, unknown> = {}) => ({\n text: \"Player connected: Steve\",\n source: \"bds\",\n level: \"info\",\n ...over,\n});\n\nconst baseCfg = (over: Record<string, unknown> = {}) => ({\n enabled: true,\n mode: \"drop\",\n applyTo: \"display\",\n rules: [],\n ...over,\n});\n\ntest(\"enabled=false \u6C38\u4E0D\u4E22\u5F03\", () => {\n const r = evaluateLogFilter(\n entry(),\n baseCfg({\n enabled: false,\n mode: \"keep\",\n rules: [{ sources: [\"bds\"] }],\n })\n );\n assert.equal(r.dropDisplay, false);\n assert.equal(r.dropDisk, false);\n});\n\ntest(\"drop \u00D7 sources \u547D\u4E2D\u5219\u4E22\u5F03\u5C55\u793A\", () => {\n const r = evaluateLogFilter(entry(), baseCfg({ rules: [{ sources: [\"bds\", \"pack\"] }] }));\n assert.equal(r.matched, true);\n assert.equal(r.dropDisplay, true);\n assert.equal(r.dropDisk, false);\n});\n\ntest(\"drop \u00D7 sources \u672A\u547D\u4E2D\u5219\u4FDD\u7559\", () => {\n const r = evaluateLogFilter(entry({ source: \"system\" }), baseCfg({ rules: [{ sources: [\"bds\"] }] }));\n assert.equal(r.matched, false);\n assert.equal(r.dropDisplay, false);\n});\n\ntest(\"drop \u00D7 levels\", () => {\n const hit = evaluateLogFilter(entry({ level: \"debug\" }), baseCfg({ rules: [{ levels: [\"debug\", \"info\"] }] }));\n const miss = evaluateLogFilter(entry({ level: \"error\" }), baseCfg({ rules: [{ levels: [\"debug\"] }] }));\n assert.equal(hit.dropDisplay, true);\n assert.equal(miss.dropDisplay, false);\n});\n\ntest(\"drop \u00D7 contains\uFF08\u5927\u5C0F\u5199\u654F\u611F\uFF09\", () => {\n const hit = evaluateLogFilter(entry(), baseCfg({ rules: [{ contains: \"Player connected\" }] }));\n const miss = evaluateLogFilter(entry(), baseCfg({ rules: [{ contains: \"player connected\" }] }));\n assert.equal(hit.dropDisplay, true);\n assert.equal(miss.dropDisplay, false);\n});\n\ntest(\"drop \u00D7 regex \u4E0E (?i) \u65D7\u6807\", () => {\n const hit = evaluateLogFilter(\n entry({ text: \"GAMERULE keepInventory\" }),\n baseCfg({ rules: [{ regex: \"(?i)gamerule|syntax error\" }] })\n );\n const miss = evaluateLogFilter(entry({ text: \"hello\" }), baseCfg({ rules: [{ regex: \"(?i)gamerule\" }] }));\n assert.equal(hit.dropDisplay, true);\n assert.equal(miss.dropDisplay, false);\n assert.ok(compileLogFilterRegex(\"(?i)ABC\")?.test(\"abc\"));\n assert.equal(compileLogFilterRegex(\"(\"), null);\n});\n\ntest(\"\u540C\u6761 AND\uFF1Asources + contains \u987B\u540C\u65F6\u6EE1\u8DB3\", () => {\n const both = evaluateLogFilter(entry(), baseCfg({ rules: [{ sources: [\"bds\"], contains: \"Player\" }] }));\n const onlySource = evaluateLogFilter(\n entry({ text: \"nope\" }),\n baseCfg({ rules: [{ sources: [\"bds\"], contains: \"Player\" }] })\n );\n assert.equal(both.dropDisplay, true);\n assert.equal(onlySource.dropDisplay, false);\n});\n\ntest(\"\u591A\u6761 OR\uFF1A\u4EFB\u4E00\u547D\u4E2D\u5373\u53EF\", () => {\n const r = evaluateLogFilter(\n entry({ source: \"pack\", text: \"done\" }),\n baseCfg({\n rules: [{ sources: [\"bds\"] }, { sources: [\"pack\"], contains: \"done\" }],\n })\n );\n assert.equal(r.matched, true);\n assert.equal(r.dropDisplay, true);\n});\n\ntest(\"rule.enabled=false \u8DF3\u8FC7\", () => {\n const r = evaluateLogFilter(entry(), baseCfg({ rules: [{ enabled: false, sources: [\"bds\"] }] }));\n assert.equal(r.matched, false);\n assert.equal(r.dropDisplay, false);\n});\n\ntest(\"keep \u6A21\u5F0F\uFF1A\u4EC5\u4FDD\u7559\u5339\u914D\uFF0C\u672A\u5339\u914D\u4E22\u5F03\", () => {\n const cfg = baseCfg({\n mode: \"keep\",\n rules: [{ levels: [\"error\"] }],\n });\n const keep = evaluateLogFilter(entry({ level: \"error\" }), cfg);\n const drop = evaluateLogFilter(entry({ level: \"info\" }), cfg);\n assert.equal(keep.dropDisplay, false);\n assert.equal(drop.dropDisplay, true);\n});\n\ntest(\"applyTo=all \u65F6\u843D\u76D8\u4E0E\u5C55\u793A\u4E00\u5E76\u8FC7\u6EE4\", () => {\n const r = evaluateLogFilter(\n entry(),\n baseCfg({\n applyTo: \"all\",\n rules: [{ sources: [\"bds\"] }],\n })\n );\n assert.equal(r.dropDisplay, true);\n assert.equal(r.dropDisk, true);\n});\n\ntest(\"applyTo=display \u65F6\u4EC5\u5F71\u54CD\u5C55\u793A\", () => {\n const r = evaluateLogFilter(\n entry(),\n baseCfg({\n applyTo: \"display\",\n rules: [{ sources: [\"bds\"] }],\n })\n );\n assert.equal(r.dropDisplay, true);\n assert.equal(r.dropDisk, false);\n});\n\ntest(\"evaluateLogFilter: \u5185\u7F6E BDS \u7FFB\u8BD1\u81EA\u52A8\u751F\u6548\", () => {\n const r = evaluateLogFilter(\n entry({\n source: \"bds\",\n text: \"Server started.\",\n }),\n baseCfg({\n enabled: false,\n translate: true,\n })\n );\n assert.equal(r.transformedEntry.text, \"[\u670D\u52A1\u7AEF] BDS \u670D\u52A1\u7AEF\u5DF2\u6210\u529F\u542F\u52A8\uFF0C\u51C6\u5907\u5C31\u7EEA\u3002\");\n});\n\ntest(\"evaluateLogFilter: \u81EA\u5B9A\u4E49 rule.replace \u4F18\u5148\u4E8E\u5185\u7F6E\u7FFB\u8BD1\", () => {\n const r = evaluateLogFilter(\n entry({\n source: \"bds\",\n text: \"Server started.\",\n }),\n baseCfg({\n enabled: true,\n rules: [\n {\n sources: [\"bds\"],\n contains: \"Server started.\",\n replace: \">> \u670D\u52A1\u5668\u51C6\u5907\u5B8C\u6BD5 <<\",\n },\n ],\n })\n );\n assert.equal(r.transformedEntry.text, \">> \u670D\u52A1\u5668\u51C6\u5907\u5B8C\u6BD5 <<\");\n});\n\ntest(\"evaluateLogFilter: \u81EA\u5B9A\u4E49 rule.replace \u652F\u6301\u6B63\u5219\u6355\u83B7\u7EC4\", () => {\n const r = evaluateLogFilter(\n entry({\n source: \"system\",\n text: \"Job backup_world completed in 42ms\",\n }),\n baseCfg({\n enabled: true,\n rules: [\n {\n regex: \"Job (\\\\w+) completed in (\\\\d+)ms\",\n replace: \"\u4EFB\u52A1 $1 \u5B8C\u6210 (\u8017\u65F6: $2\u6BEB\u79D2)\",\n },\n ],\n })\n );\n assert.equal(r.transformedEntry.text, \"\u4EFB\u52A1 backup_world \u5B8C\u6210 (\u8017\u65F6: 42\u6BEB\u79D2)\");\n});\n\ntest(\"evaluateLogFilter: translate=false \u65F6\u4E0D\u89E6\u53D1\u5185\u7F6E\u7FFB\u8BD1\", () => {\n const r = evaluateLogFilter(\n entry({\n source: \"bds\",\n text: \"Server started.\",\n }),\n baseCfg({\n translate: false,\n })\n );\n assert.equal(r.transformedEntry.text, \"Server started.\");\n});\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,120 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import {
4
- applyRuleReplacement,
5
- interpolateRegexTemplate,
6
- translateBdsLog
7
- } from "./log-translator.js";
8
- test("translateBdsLog: Beta APIs \u7F3A\u5931\u963B\u65AD", () => {
9
- const line = "Plugin [sfmc-modules - 1.0.0] - requesting dependency on beta APIs [@minecraft/server-admin - 1.0.0-beta], but the Beta APIs experiment is not enabled.";
10
- const res = translateBdsLog(line, "zh-CN");
11
- assert.equal(res.translated, true);
12
- assert.equal(res.ruleId, "beta-apis-missing");
13
- assert.ok(res.text.includes("\u63D2\u4EF6\u300Csfmc-modules - 1.0.0\u300D\u4F9D\u8D56\u6D4B\u8BD5\u7248 API (@minecraft/server-admin - 1.0.0-beta)"));
14
- assert.ok(res.text.includes("\u672A\u5F00\u542F\u300C\u6D4B\u8BD5\u7248 API (Beta APIs)\u300D\u5B9E\u9A8C\u5F00\u5173"));
15
- });
16
- test("translateBdsLog: \u811A\u672C\u8BED\u6CD5\u9519\u8BEF missing export", () => {
17
- const line = "SyntaxError: Could not find export 'Vector3' in module '@minecraft/server'";
18
- const res = translateBdsLog(line, "zh-CN");
19
- assert.equal(res.translated, true);
20
- assert.equal(res.ruleId, "script-syntax-missing-export");
21
- assert.ok(res.text.includes("\u6A21\u7EC4\u5C1D\u8BD5\u4ECE\u300C@minecraft/server\u300D\u5BFC\u5165\u4E0D\u5B58\u5728\u7684\u7B26\u53F7\u300CVector3\u300D"));
22
- });
23
- test("translateBdsLog: \u6FC0\u6D3B\u5305\u5728\u672C\u5730\u7F3A\u5931", () => {
24
- const line = "Configured pack (id: 3116e462-9838-48bf-be53-354958c1810f, version: 1.21.100) was not found and was ignored";
25
- const res = translateBdsLog(line, "zh-CN");
26
- assert.equal(res.translated, true);
27
- assert.equal(res.ruleId, "configured-pack-missing");
28
- assert.ok(res.text.includes("UUID: 3116e462-9838-48bf-be53-354958c1810f"));
29
- assert.ok(res.text.includes("\u7248\u672C: 1.21.100"));
30
- });
31
- test("translateBdsLog: \u81EA\u5B9A\u4E49\u65B9\u5757\u5F62\u6001\u6570\u91CF\u8D85\u9650", () => {
32
- const line = "World with over 65536 block permutations may degrade performance. Current world has 74227 permutations.";
33
- const res = translateBdsLog(line, "zh-CN");
34
- assert.equal(res.translated, true);
35
- assert.equal(res.ruleId, "block-permutations-limit");
36
- assert.ok(res.text.includes("74227 \u4E2A"));
37
- assert.ok(res.text.includes("\u8D85\u51FA\u63A8\u8350\u4E0A\u9650 65,536"));
38
- });
39
- test("translateBdsLog: \u914D\u65B9\u7269\u54C1\u7F3A\u5931", () => {
40
- const line = "[Recipes] recipes/japanese/mochi_rice.json | amp:mochi_rice | The Item: amp:mochi_rice is missing or invalid, can't make the recipe";
41
- const res = translateBdsLog(line, "zh-CN");
42
- assert.equal(res.translated, true);
43
- assert.equal(res.ruleId, "recipe-item-missing");
44
- assert.ok(res.text.includes("\u914D\u65B9\u6587\u4EF6\u300Crecipes/japanese/mochi_rice.json\u300D"));
45
- assert.ok(res.text.includes("\u7269\u54C1\u300Camp:mochi_rice\u300D\u4E0D\u5B58\u5728\u6216\u65E0\u6548"));
46
- });
47
- test("translateBdsLog: \u914D\u65B9\u539F\u6599\u7F3A\u5931", () => {
48
- const line = "[Recipes] recipes/japanese/rice_eel.json | amp:rice_eel | Recipe for: amp:rice_eel is missing (unknown) ingredient";
49
- const res = translateBdsLog(line, "zh-CN");
50
- assert.equal(res.translated, true);
51
- assert.equal(res.ruleId, "recipe-ingredient-missing");
52
- assert.ok(res.text.includes("\u4EA7\u7269: amp:rice_eel"));
53
- assert.ok(res.text.includes("\u7F3A\u5C11\u6709\u6548\u539F\u6599"));
54
- });
55
- test("translateBdsLog: \u914D\u65B9\u4EA7\u7269\u683C\u5F0F\u9519\u8BEF", () => {
56
- const line = "[Recipes] recipes/furniture/money.json | amp:money | Recipe result malformed";
57
- const res = translateBdsLog(line, "zh-CN");
58
- assert.equal(res.translated, true);
59
- assert.equal(res.ruleId, "recipe-result-malformed");
60
- assert.ok(res.text.includes("\u4EA7\u7269\u7ED3\u679C\u5B9A\u4E49\u683C\u5F0F\u9519\u8BEF"));
61
- });
62
- test("translateBdsLog: \u65B9\u5757 Schema \u672A\u77E5\u7EC4\u4EF6\u4E0E\u5B50\u5C5E\u6027\u9519\u8BEF", () => {
63
- const line1 = "[Blocks] block_definitions | worlds/Bedrock level/behavior_packs/[BP] TouHouLittleMaid_BP | blocks/skull/fairy_skull_2.json | -> components -> tlm:skull: this component was found in the input, but is not present in the Schema";
64
- const res1 = translateBdsLog(line1, "zh-CN");
65
- assert.equal(res1.translated, true);
66
- assert.equal(res1.ruleId, "block-component-schema-unknown");
67
- assert.ok(res1.text.includes("blocks/skull/fairy_skull_2.json"));
68
- assert.ok(res1.text.includes("\u672A\u77E5\u7EC4\u4EF6: components -> tlm:skull"));
69
- const line2 = "[Blocks] block_definitions | worlds/Bedrock level/behavior_packs/[BP] [BM] [\u81EA\u7814] [\u73A9\u6CD5] GlobalCuisine_BP | blocks/steamer/steamer.json | worlds/Bedrock level/behavior_packs/[BP] [BM] [\u81EA\u7814] [\u73A9\u6CD5] GlobalCuisine_BP | blocks/steamer/steamer.json | amp:steamer | components | amp:steamer | child 'amp:steamer' not valid here.";
70
- const res2 = translateBdsLog(line2, "zh-CN");
71
- assert.equal(res2.translated, true);
72
- assert.equal(res2.ruleId, "block-child-component-invalid");
73
- assert.ok(res2.text.includes("blocks/steamer/steamer.json"));
74
- assert.ok(res2.text.includes("\u5B50\u5C5E\u6027\u300Camp:steamer\u300D\u5728\u6B64\u5904\u65E0\u6548"));
75
- });
76
- test("translateBdsLog: \u811A\u672C\u7EC4\u4EF6\u672A\u6CE8\u518C", () => {
77
- const line = "[Scripting] Component 'tlm:deprecated' was not registered in script but used on an item";
78
- const res = translateBdsLog(line, "zh-CN");
79
- assert.equal(res.translated, true);
80
- assert.equal(res.ruleId, "script-component-not-registered");
81
- assert.ok(res.text.includes("\u81EA\u5B9A\u4E49\u7EC4\u4EF6\u300Ctlm:deprecated\u300D"));
82
- });
83
- test("translateBdsLog: \u670D\u52A1\u7AEF\u751F\u547D\u5468\u671F\u4E0E\u7AEF\u53E3", () => {
84
- assert.equal(translateBdsLog("Server started.", "zh-CN").text, "[\u670D\u52A1\u7AEF] BDS \u670D\u52A1\u7AEF\u5DF2\u6210\u529F\u542F\u52A8\uFF0C\u51C6\u5907\u5C31\u7EEA\u3002");
85
- assert.equal(translateBdsLog("Stopping server...", "zh-CN").text, "[\u670D\u52A1\u7AEF] \u6B63\u5728\u5173\u95ED\u670D\u52A1\u7AEF...");
86
- assert.equal(translateBdsLog("Quit correctly", "zh-CN").text, "[\u670D\u52A1\u7AEF] \u670D\u52A1\u7AEF\u5DF2\u6B63\u5E38\u5B89\u5168\u9000\u51FA\u3002");
87
- assert.equal(
88
- translateBdsLog("IPv4 supported, port: 19132: Used for gameplay and LAN discovery", "zh-CN").text,
89
- "[\u7F51\u7EDC] IPv4 \u6E38\u620F\u4E0E\u5C40\u57DF\u7F51\u53D1\u73B0\u7AEF\u53E3: 19132 (UDP)"
90
- );
91
- assert.equal(
92
- translateBdsLog("Allow list is enabled but contains no entries.", "zh-CN").text,
93
- "[\u767D\u540D\u5355\u8B66\u544A] \u767D\u540D\u5355\u529F\u80FD\u5DF2\u5F00\u542F\u4F46\u540D\u5355\u4E3A\u7A7A\uFF01\u9664\u7BA1\u7406\u5458\u5916\u5176\u4ED6\u73A9\u5BB6\u5C06\u65E0\u6CD5\u52A0\u5165\u670D\u52A1\u5668\u3002"
94
- );
95
- });
96
- test("translateBdsLog: \u73A9\u5BB6\u52A0\u5165\u4E0E\u79BB\u5F00", () => {
97
- const join = translateBdsLog("Player connected: Steve, xuid: 2535412345678901", "zh-CN");
98
- assert.equal(join.text, "[\u73A9\u5BB6\u8FDE\u63A5] \u73A9\u5BB6 Steve \u5DF2\u52A0\u5165\u4E16\u754C (XUID: 2535412345678901)");
99
- const leave = translateBdsLog("Player disconnected: Steve, xuid: 2535412345678901", "zh-CN");
100
- assert.equal(leave.text, "[\u73A9\u5BB6\u65AD\u5F00] \u73A9\u5BB6 Steve \u5DF2\u79BB\u5F00\u4E16\u754C (XUID: 2535412345678901)");
101
- });
102
- test("translateBdsLog: \u672A\u5339\u914D\u884C\u539F\u6837\u8FD4\u56DE", () => {
103
- const plain = "A custom line that has no translation rule.";
104
- const res = translateBdsLog(plain, "zh-CN");
105
- assert.equal(res.translated, false);
106
- assert.equal(res.text, plain);
107
- });
108
- test("interpolateRegexTemplate & applyRuleReplacement", () => {
109
- const m = "Hello world 123".match(/Hello (\w+) (\d+)/);
110
- assert.ok(m);
111
- const out = interpolateRegexTemplate(m, "Greeting $1 with id $2");
112
- assert.equal(out, "Greeting world with id 123");
113
- const replaced = applyRuleReplacement(
114
- "Warning: player Steve did action 5",
115
- /Warning: player (\w+) did action (\d+)/,
116
- "\u8B66\u544A: \u73A9\u5BB6 $1 \u89E6\u53D1\u4E86\u884C\u4E3A $2"
117
- );
118
- assert.equal(replaced, "\u8B66\u544A: \u73A9\u5BB6 Steve \u89E6\u53D1\u4E86\u884C\u4E3A 5");
119
- });
120
- //# sourceMappingURL=log-translator.test.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/log-translator.test.ts"],
4
- "sourcesContent": ["/**\n * log-translator.test.ts \u2014 BDS \u539F\u7248\u65E5\u5FD7\u672C\u5730\u5316\u7FFB\u8BD1\u5355\u6D4B\n */\nimport assert from \"node:assert/strict\";\nimport test from \"node:test\";\nimport {\n applyRuleReplacement,\n interpolateRegexTemplate,\n translateBdsLog,\n} from \"./log-translator.js\";\n\ntest(\"translateBdsLog: Beta APIs \u7F3A\u5931\u963B\u65AD\", () => {\n const line =\n \"Plugin [sfmc-modules - 1.0.0] - requesting dependency on beta APIs [@minecraft/server-admin - 1.0.0-beta], but the Beta APIs experiment is not enabled.\";\n const res = translateBdsLog(line, \"zh-CN\");\n assert.equal(res.translated, true);\n assert.equal(res.ruleId, \"beta-apis-missing\");\n assert.ok(res.text.includes(\"\u63D2\u4EF6\u300Csfmc-modules - 1.0.0\u300D\u4F9D\u8D56\u6D4B\u8BD5\u7248 API (@minecraft/server-admin - 1.0.0-beta)\"));\n assert.ok(res.text.includes(\"\u672A\u5F00\u542F\u300C\u6D4B\u8BD5\u7248 API (Beta APIs)\u300D\u5B9E\u9A8C\u5F00\u5173\"));\n});\n\ntest(\"translateBdsLog: \u811A\u672C\u8BED\u6CD5\u9519\u8BEF missing export\", () => {\n const line = \"SyntaxError: Could not find export 'Vector3' in module '@minecraft/server'\";\n const res = translateBdsLog(line, \"zh-CN\");\n assert.equal(res.translated, true);\n assert.equal(res.ruleId, \"script-syntax-missing-export\");\n assert.ok(res.text.includes(\"\u6A21\u7EC4\u5C1D\u8BD5\u4ECE\u300C@minecraft/server\u300D\u5BFC\u5165\u4E0D\u5B58\u5728\u7684\u7B26\u53F7\u300CVector3\u300D\"));\n});\n\ntest(\"translateBdsLog: \u6FC0\u6D3B\u5305\u5728\u672C\u5730\u7F3A\u5931\", () => {\n const line = \"Configured pack (id: 3116e462-9838-48bf-be53-354958c1810f, version: 1.21.100) was not found and was ignored\";\n const res = translateBdsLog(line, \"zh-CN\");\n assert.equal(res.translated, true);\n assert.equal(res.ruleId, \"configured-pack-missing\");\n assert.ok(res.text.includes(\"UUID: 3116e462-9838-48bf-be53-354958c1810f\"));\n assert.ok(res.text.includes(\"\u7248\u672C: 1.21.100\"));\n});\n\ntest(\"translateBdsLog: \u81EA\u5B9A\u4E49\u65B9\u5757\u5F62\u6001\u6570\u91CF\u8D85\u9650\", () => {\n const line = \"World with over 65536 block permutations may degrade performance. Current world has 74227 permutations.\";\n const res = translateBdsLog(line, \"zh-CN\");\n assert.equal(res.translated, true);\n assert.equal(res.ruleId, \"block-permutations-limit\");\n assert.ok(res.text.includes(\"74227 \u4E2A\"));\n assert.ok(res.text.includes(\"\u8D85\u51FA\u63A8\u8350\u4E0A\u9650 65,536\"));\n});\n\ntest(\"translateBdsLog: \u914D\u65B9\u7269\u54C1\u7F3A\u5931\", () => {\n const line =\n \"[Recipes] recipes/japanese/mochi_rice.json | amp:mochi_rice | The Item: amp:mochi_rice is missing or invalid, can't make the recipe\";\n const res = translateBdsLog(line, \"zh-CN\");\n assert.equal(res.translated, true);\n assert.equal(res.ruleId, \"recipe-item-missing\");\n assert.ok(res.text.includes(\"\u914D\u65B9\u6587\u4EF6\u300Crecipes/japanese/mochi_rice.json\u300D\"));\n assert.ok(res.text.includes(\"\u7269\u54C1\u300Camp:mochi_rice\u300D\u4E0D\u5B58\u5728\u6216\u65E0\u6548\"));\n});\n\ntest(\"translateBdsLog: \u914D\u65B9\u539F\u6599\u7F3A\u5931\", () => {\n const line =\n \"[Recipes] recipes/japanese/rice_eel.json | amp:rice_eel | Recipe for: amp:rice_eel is missing (unknown) ingredient\";\n const res = translateBdsLog(line, \"zh-CN\");\n assert.equal(res.translated, true);\n assert.equal(res.ruleId, \"recipe-ingredient-missing\");\n assert.ok(res.text.includes(\"\u4EA7\u7269: amp:rice_eel\"));\n assert.ok(res.text.includes(\"\u7F3A\u5C11\u6709\u6548\u539F\u6599\"));\n});\n\ntest(\"translateBdsLog: \u914D\u65B9\u4EA7\u7269\u683C\u5F0F\u9519\u8BEF\", () => {\n const line = \"[Recipes] recipes/furniture/money.json | amp:money | Recipe result malformed\";\n const res = translateBdsLog(line, \"zh-CN\");\n assert.equal(res.translated, true);\n assert.equal(res.ruleId, \"recipe-result-malformed\");\n assert.ok(res.text.includes(\"\u4EA7\u7269\u7ED3\u679C\u5B9A\u4E49\u683C\u5F0F\u9519\u8BEF\"));\n});\n\ntest(\"translateBdsLog: \u65B9\u5757 Schema \u672A\u77E5\u7EC4\u4EF6\u4E0E\u5B50\u5C5E\u6027\u9519\u8BEF\", () => {\n const line1 =\n \"[Blocks] block_definitions | worlds/Bedrock level/behavior_packs/[BP] TouHouLittleMaid_BP | blocks/skull/fairy_skull_2.json | -> components -> tlm:skull: this component was found in the input, but is not present in the Schema\";\n const res1 = translateBdsLog(line1, \"zh-CN\");\n assert.equal(res1.translated, true);\n assert.equal(res1.ruleId, \"block-component-schema-unknown\");\n assert.ok(res1.text.includes(\"blocks/skull/fairy_skull_2.json\"));\n assert.ok(res1.text.includes(\"\u672A\u77E5\u7EC4\u4EF6: components -> tlm:skull\"));\n\n const line2 =\n \"[Blocks] block_definitions | worlds/Bedrock level/behavior_packs/[BP] [BM] [\u81EA\u7814] [\u73A9\u6CD5] GlobalCuisine_BP | blocks/steamer/steamer.json | worlds/Bedrock level/behavior_packs/[BP] [BM] [\u81EA\u7814] [\u73A9\u6CD5] GlobalCuisine_BP | blocks/steamer/steamer.json | amp:steamer | components | amp:steamer | child 'amp:steamer' not valid here.\";\n const res2 = translateBdsLog(line2, \"zh-CN\");\n assert.equal(res2.translated, true);\n assert.equal(res2.ruleId, \"block-child-component-invalid\");\n assert.ok(res2.text.includes(\"blocks/steamer/steamer.json\"));\n assert.ok(res2.text.includes(\"\u5B50\u5C5E\u6027\u300Camp:steamer\u300D\u5728\u6B64\u5904\u65E0\u6548\"));\n});\n\ntest(\"translateBdsLog: \u811A\u672C\u7EC4\u4EF6\u672A\u6CE8\u518C\", () => {\n const line = \"[Scripting] Component 'tlm:deprecated' was not registered in script but used on an item\";\n const res = translateBdsLog(line, \"zh-CN\");\n assert.equal(res.translated, true);\n assert.equal(res.ruleId, \"script-component-not-registered\");\n assert.ok(res.text.includes(\"\u81EA\u5B9A\u4E49\u7EC4\u4EF6\u300Ctlm:deprecated\u300D\"));\n});\n\ntest(\"translateBdsLog: \u670D\u52A1\u7AEF\u751F\u547D\u5468\u671F\u4E0E\u7AEF\u53E3\", () => {\n assert.equal(translateBdsLog(\"Server started.\", \"zh-CN\").text, \"[\u670D\u52A1\u7AEF] BDS \u670D\u52A1\u7AEF\u5DF2\u6210\u529F\u542F\u52A8\uFF0C\u51C6\u5907\u5C31\u7EEA\u3002\");\n assert.equal(translateBdsLog(\"Stopping server...\", \"zh-CN\").text, \"[\u670D\u52A1\u7AEF] \u6B63\u5728\u5173\u95ED\u670D\u52A1\u7AEF...\");\n assert.equal(translateBdsLog(\"Quit correctly\", \"zh-CN\").text, \"[\u670D\u52A1\u7AEF] \u670D\u52A1\u7AEF\u5DF2\u6B63\u5E38\u5B89\u5168\u9000\u51FA\u3002\");\n assert.equal(\n translateBdsLog(\"IPv4 supported, port: 19132: Used for gameplay and LAN discovery\", \"zh-CN\").text,\n \"[\u7F51\u7EDC] IPv4 \u6E38\u620F\u4E0E\u5C40\u57DF\u7F51\u53D1\u73B0\u7AEF\u53E3: 19132 (UDP)\"\n );\n assert.equal(\n translateBdsLog(\"Allow list is enabled but contains no entries.\", \"zh-CN\").text,\n \"[\u767D\u540D\u5355\u8B66\u544A] \u767D\u540D\u5355\u529F\u80FD\u5DF2\u5F00\u542F\u4F46\u540D\u5355\u4E3A\u7A7A\uFF01\u9664\u7BA1\u7406\u5458\u5916\u5176\u4ED6\u73A9\u5BB6\u5C06\u65E0\u6CD5\u52A0\u5165\u670D\u52A1\u5668\u3002\"\n );\n});\n\ntest(\"translateBdsLog: \u73A9\u5BB6\u52A0\u5165\u4E0E\u79BB\u5F00\", () => {\n const join = translateBdsLog(\"Player connected: Steve, xuid: 2535412345678901\", \"zh-CN\");\n assert.equal(join.text, \"[\u73A9\u5BB6\u8FDE\u63A5] \u73A9\u5BB6 Steve \u5DF2\u52A0\u5165\u4E16\u754C (XUID: 2535412345678901)\");\n\n const leave = translateBdsLog(\"Player disconnected: Steve, xuid: 2535412345678901\", \"zh-CN\");\n assert.equal(leave.text, \"[\u73A9\u5BB6\u65AD\u5F00] \u73A9\u5BB6 Steve \u5DF2\u79BB\u5F00\u4E16\u754C (XUID: 2535412345678901)\");\n});\n\ntest(\"translateBdsLog: \u672A\u5339\u914D\u884C\u539F\u6837\u8FD4\u56DE\", () => {\n const plain = \"A custom line that has no translation rule.\";\n const res = translateBdsLog(plain, \"zh-CN\");\n assert.equal(res.translated, false);\n assert.equal(res.text, plain);\n});\n\ntest(\"interpolateRegexTemplate & applyRuleReplacement\", () => {\n const m = \"Hello world 123\".match(/Hello (\\w+) (\\d+)/);\n assert.ok(m);\n const out = interpolateRegexTemplate(m, \"Greeting $1 with id $2\");\n assert.equal(out, \"Greeting world with id 123\");\n\n const replaced = applyRuleReplacement(\n \"Warning: player Steve did action 5\",\n /Warning: player (\\w+) did action (\\d+)/,\n \"\u8B66\u544A: \u73A9\u5BB6 $1 \u89E6\u53D1\u4E86\u884C\u4E3A $2\"\n );\n assert.equal(replaced, \"\u8B66\u544A: \u73A9\u5BB6 Steve \u89E6\u53D1\u4E86\u884C\u4E3A 5\");\n});\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,16 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import { describe, it } from "node:test";
3
- import { normalizeBdsLogBody } from "./logs.js";
4
- describe("BDS \u7A7A\u65E5\u5FD7\u6B63\u6587", () => {
5
- it("\u8FC7\u6EE4\u7EAF\u7A7A\u767D\u4EE5\u53CA\u4EC5\u542B BDS \u524D\u7F00\u7684\u884C", () => {
6
- assert.equal(normalizeBdsLogBody("\r"), null);
7
- assert.equal(normalizeBdsLogBody("[2026-09-09 18:07:44:123 INFO] \r"), null);
8
- });
9
- it("\u5265\u79BB\u524D\u7F00\u540E\u4FDD\u7559\u771F\u5B9E\u6B63\u6587", () => {
10
- assert.equal(
11
- normalizeBdsLogBody("[2026-09-09 18:07:44:123 WARN] [Scripting] farmersdelight:cutting_board_recipe"),
12
- "[Scripting] farmersdelight:cutting_board_recipe"
13
- );
14
- });
15
- });
16
- //# sourceMappingURL=logs-blank-line.test.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/logs-blank-line.test.ts"],
4
- "sourcesContent": ["/**\n * BDS \u6392\u7248\u7A7A\u884C\u5951\u7EA6\uFF1A\u5265\u79BB\u5176\u81EA\u5E26\u65F6\u95F4\u6233\u548C\u7B49\u7EA7\u540E\u4E3A\u7A7A\u7684\u884C\u4E0D\u5F97\u8FDB\u5165\u7EDF\u4E00\u65E5\u5FD7\u3002\n */\nimport assert from \"node:assert/strict\";\nimport { describe, it } from \"node:test\";\nimport { normalizeBdsLogBody } from \"./logs.js\";\n\ndescribe(\"BDS \u7A7A\u65E5\u5FD7\u6B63\u6587\", () => {\n it(\"\u8FC7\u6EE4\u7EAF\u7A7A\u767D\u4EE5\u53CA\u4EC5\u542B BDS \u524D\u7F00\u7684\u884C\", () => {\n assert.equal(normalizeBdsLogBody(\"\\r\"), null);\n assert.equal(normalizeBdsLogBody(\"[2026-09-09 18:07:44:123 INFO] \\r\"), null);\n });\n\n it(\"\u5265\u79BB\u524D\u7F00\u540E\u4FDD\u7559\u771F\u5B9E\u6B63\u6587\", () => {\n assert.equal(\n normalizeBdsLogBody(\"[2026-09-09 18:07:44:123 WARN] [Scripting] farmersdelight:cutting_board_recipe\"),\n \"[Scripting] farmersdelight:cutting_board_recipe\"\n );\n });\n});\n"],
5
- "mappings": "AAGA,OAAO,YAAY;AACnB,SAAS,UAAU,UAAU;AAC7B,SAAS,2BAA2B;AAEpC,SAAS,sCAAa,MAAM;AAC1B,KAAG,uFAAsB,MAAM;AAC7B,WAAO,MAAM,oBAAoB,IAAI,GAAG,IAAI;AAC5C,WAAO,MAAM,oBAAoB,qCAAqC,GAAG,IAAI;AAAA,EAC/E,CAAC;AAED,KAAG,sEAAe,MAAM;AACtB,WAAO;AAAA,MACL,oBAAoB,gFAAgF;AAAA,MACpG;AAAA,IACF;AAAA,EACF,CAAC;AACH,CAAC;",
6
- "names": []
7
- }
@@ -1,37 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import { applyLockEnabled, finalizeToggle, resolveToggleTarget } from "./module-toggle.js";
4
- const candidates = [
5
- { logicalId: "feature-afk", folderId: "afk", configKey: "afk", canDisable: true },
6
- { logicalId: "core-gui", folderId: "gui", configKey: "gui", canDisable: false }
7
- ];
8
- test("resolveToggleTarget\uFF1AfolderId / logicalId / configKey", () => {
9
- assert.equal(resolveToggleTarget("afk", candidates)?.logicalId, "feature-afk");
10
- assert.equal(resolveToggleTarget("feature-afk", candidates)?.logicalId, "feature-afk");
11
- assert.equal(resolveToggleTarget("afk", candidates)?.folderId, "afk");
12
- assert.equal(resolveToggleTarget("missing", candidates), null);
13
- });
14
- test("resolveToggleTarget\uFF1AcanDisable \u6765\u81EA\u5019\u9009", () => {
15
- assert.equal(resolveToggleTarget("gui", candidates)?.canDisable, false);
16
- assert.equal(resolveToggleTarget("core-gui", candidates)?.canDisable, false);
17
- });
18
- test("applyLockEnabled\uFF1A\u5199\u5165 enabled + updatedAt", () => {
19
- const lock = { version: 1, modules: {} };
20
- const next = applyLockEnabled(lock, "feature-afk", true);
21
- assert.equal(next.modules["feature-afk"]?.enabled, true);
22
- assert.equal(typeof next.modules["feature-afk"]?.updatedAt, "number");
23
- assert.equal(lock.modules["feature-afk"]?.enabled, true);
24
- });
25
- test("finalizeToggle\uFF1A\u672C\u5730\u5DF2\u5199 + \u901A\u77E5\u5931\u8D25 \u2192 ok \u4E14 warn", () => {
26
- assert.deepEqual(finalizeToggle(true, { ok: true }), { ok: true, warnNotify: false });
27
- assert.deepEqual(finalizeToggle(true, { ok: false, reason: "unreachable" }), {
28
- ok: true,
29
- warnNotify: true
30
- });
31
- assert.deepEqual(finalizeToggle(true, { ok: false, reason: "http", detail: "x" }), {
32
- ok: true,
33
- warnNotify: true
34
- });
35
- assert.deepEqual(finalizeToggle(false, { ok: true }), { ok: false, warnNotify: false });
36
- });
37
- //# sourceMappingURL=module-toggle.test.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/module-toggle.test.ts"],
4
- "sourcesContent": ["/**\n * module-toggle \u672C\u5730\u5199 lock + \u901A\u77E5\u7ED3\u679C\u4FE1\u5C01\uFF08\u7EAF\u51FD\u6570\uFF09\n */\nimport assert from \"node:assert/strict\";\nimport test from \"node:test\";\nimport { applyLockEnabled, finalizeToggle, resolveToggleTarget } from \"./module-toggle.js\";\n\nconst candidates = [\n { logicalId: \"feature-afk\", folderId: \"afk\", configKey: \"afk\", canDisable: true },\n { logicalId: \"core-gui\", folderId: \"gui\", configKey: \"gui\", canDisable: false },\n];\n\ntest(\"resolveToggleTarget\uFF1AfolderId / logicalId / configKey\", () => {\n assert.equal(resolveToggleTarget(\"afk\", candidates)?.logicalId, \"feature-afk\");\n assert.equal(resolveToggleTarget(\"feature-afk\", candidates)?.logicalId, \"feature-afk\");\n assert.equal(resolveToggleTarget(\"afk\", candidates)?.folderId, \"afk\");\n assert.equal(resolveToggleTarget(\"missing\", candidates), null);\n});\n\ntest(\"resolveToggleTarget\uFF1AcanDisable \u6765\u81EA\u5019\u9009\", () => {\n assert.equal(resolveToggleTarget(\"gui\", candidates)?.canDisable, false);\n assert.equal(resolveToggleTarget(\"core-gui\", candidates)?.canDisable, false);\n});\n\ntest(\"applyLockEnabled\uFF1A\u5199\u5165 enabled + updatedAt\", () => {\n const lock = { version: 1, modules: {} as Record<string, { enabled: boolean; updatedAt?: number }> };\n const next = applyLockEnabled(lock, \"feature-afk\", true);\n assert.equal(next.modules[\"feature-afk\"]?.enabled, true);\n assert.equal(typeof next.modules[\"feature-afk\"]?.updatedAt, \"number\");\n assert.equal(lock.modules[\"feature-afk\"]?.enabled, true);\n});\n\ntest(\"finalizeToggle\uFF1A\u672C\u5730\u5DF2\u5199 + \u901A\u77E5\u5931\u8D25 \u2192 ok \u4E14 warn\", () => {\n assert.deepEqual(finalizeToggle(true, { ok: true }), { ok: true, warnNotify: false });\n assert.deepEqual(finalizeToggle(true, { ok: false, reason: \"unreachable\" }), {\n ok: true,\n warnNotify: true,\n });\n assert.deepEqual(finalizeToggle(true, { ok: false, reason: \"http\", detail: \"x\" }), {\n ok: true,\n warnNotify: true,\n });\n assert.deepEqual(finalizeToggle(false, { ok: true }), { ok: false, warnNotify: false });\n});\n"],
5
- "mappings": "AAGA,OAAO,YAAY;AACnB,OAAO,UAAU;AACjB,SAAS,kBAAkB,gBAAgB,2BAA2B;AAEtE,MAAM,aAAa;AAAA,EACjB,EAAE,WAAW,eAAe,UAAU,OAAO,WAAW,OAAO,YAAY,KAAK;AAAA,EAChF,EAAE,WAAW,YAAY,UAAU,OAAO,WAAW,OAAO,YAAY,MAAM;AAChF;AAEA,KAAK,6DAAwD,MAAM;AACjE,SAAO,MAAM,oBAAoB,OAAO,UAAU,GAAG,WAAW,aAAa;AAC7E,SAAO,MAAM,oBAAoB,eAAe,UAAU,GAAG,WAAW,aAAa;AACrF,SAAO,MAAM,oBAAoB,OAAO,UAAU,GAAG,UAAU,KAAK;AACpE,SAAO,MAAM,oBAAoB,WAAW,UAAU,GAAG,IAAI;AAC/D,CAAC;AAED,KAAK,gEAAuC,MAAM;AAChD,SAAO,MAAM,oBAAoB,OAAO,UAAU,GAAG,YAAY,KAAK;AACtE,SAAO,MAAM,oBAAoB,YAAY,UAAU,GAAG,YAAY,KAAK;AAC7E,CAAC;AAED,KAAK,0DAA2C,MAAM;AACpD,QAAM,OAAO,EAAE,SAAS,GAAG,SAAS,CAAC,EAA8D;AACnG,QAAM,OAAO,iBAAiB,MAAM,eAAe,IAAI;AACvD,SAAO,MAAM,KAAK,QAAQ,aAAa,GAAG,SAAS,IAAI;AACvD,SAAO,MAAM,OAAO,KAAK,QAAQ,aAAa,GAAG,WAAW,QAAQ;AACpE,SAAO,MAAM,KAAK,QAAQ,aAAa,GAAG,SAAS,IAAI;AACzD,CAAC;AAED,KAAK,iGAA0C,MAAM;AACnD,SAAO,UAAU,eAAe,MAAM,EAAE,IAAI,KAAK,CAAC,GAAG,EAAE,IAAI,MAAM,YAAY,MAAM,CAAC;AACpF,SAAO,UAAU,eAAe,MAAM,EAAE,IAAI,OAAO,QAAQ,cAAc,CAAC,GAAG;AAAA,IAC3E,IAAI;AAAA,IACJ,YAAY;AAAA,EACd,CAAC;AACD,SAAO,UAAU,eAAe,MAAM,EAAE,IAAI,OAAO,QAAQ,QAAQ,QAAQ,IAAI,CAAC,GAAG;AAAA,IACjF,IAAI;AAAA,IACJ,YAAY;AAAA,EACd,CAAC;AACD,SAAO,UAAU,eAAe,OAAO,EAAE,IAAI,KAAK,CAAC,GAAG,EAAE,IAAI,OAAO,YAAY,MAAM,CAAC;AACxF,CAAC;",
6
- "names": []
7
- }
@@ -1,111 +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 { build } from "esbuild";
7
- import { createSdkResolvePlugin } from "./pack-lifecycle.js";
8
- import { resolveSdkPackageRoot } from "./runtime.js";
9
- test("pack bundling: sfmc:host bundles installHostBootstrap without unbundled SDK imports", async () => {
10
- const sdkRoot = resolveSdkPackageRoot();
11
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sfmc-bundle-test-"));
12
- const dummyModFile = path.join(tmpDir, "dummy-mod.ts");
13
- fs.writeFileSync(
14
- dummyModFile,
15
- `
16
- import { ModuleRegistry } from "@sfmc-bds/sdk/module-loader";
17
- import { Command, Permission } from "@sfmc-bds/sdk/sapi/runtime";
18
- globalThis.__testEvalOrder = (globalThis.__testEvalOrder || []).concat("module");
19
- Command.register("dummy", Permission.Any, () => undefined, "dummy", "test-feature");
20
- ModuleRegistry.register({ id: "test-feature", lifecycle: {} });
21
- `
22
- );
23
- try {
24
- const res = await build({
25
- stdin: {
26
- contents: [
27
- 'import "sfmc:host";',
28
- `import ${JSON.stringify(dummyModFile.replace(/\\/g, "/"))};`
29
- ].join("\n"),
30
- resolveDir: tmpDir,
31
- sourcefile: "bootstrap.ts",
32
- loader: "ts"
33
- },
34
- write: false,
35
- bundle: true,
36
- platform: "neutral",
37
- format: "esm",
38
- target: "es2022",
39
- external: ["@minecraft/*"],
40
- plugins: [createSdkResolvePlugin(sdkRoot)]
41
- });
42
- const code = res.outputFiles[0].text;
43
- assert.doesNotMatch(
44
- code,
45
- /import\s+.*from\s+["']@sfmc(?:-bds)?\/sdk/i,
46
- "Bundle must not contain unbundled @sfmc-bds/sdk bare imports"
47
- );
48
- assert.match(code, /installHostBootstrap\(\)/, "Bundle must call installHostBootstrap()");
49
- const importLines = code.split("\n").map((l) => l.trim()).filter((l) => l.startsWith("import ") && l.includes(" from "));
50
- for (const line of importLines) {
51
- assert.match(
52
- line,
53
- /from\s+["']@minecraft\//,
54
- `Unexpected external import line in bundle: ${line}`
55
- );
56
- }
57
- const hostCallIdx = code.indexOf("installHostBootstrap();");
58
- const modMarkerIdx = code.indexOf("__testEvalOrder");
59
- assert.ok(hostCallIdx !== -1, "installHostBootstrap call exists");
60
- assert.ok(modMarkerIdx !== -1, "module eval marker exists");
61
- assert.ok(
62
- hostCallIdx < modMarkerIdx,
63
- `installHostBootstrap() (idx: ${hostCallIdx}) must execute before module evaluation (idx: ${modMarkerIdx})`
64
- );
65
- const commandStateRefs = code.match(/__sfmcCommandState/g)?.length ?? 0;
66
- const permissionStateRefs = code.match(/__sfmcPermissionRegistry/g)?.length ?? 0;
67
- assert.ok(commandStateRefs >= 2, "Bundled SDK copies must share __sfmcCommandState");
68
- assert.ok(permissionStateRefs >= 2, "Bundled SDK copies must share __sfmcPermissionRegistry");
69
- } finally {
70
- fs.rmSync(tmpDir, { recursive: true, force: true });
71
- }
72
- });
73
- test("extractModuleBedrockDependencies: \u4ECE sapi/manifest.json \u4E0E package.json \u63D0\u53D6\u539F\u751F\u4F9D\u8D56", async () => {
74
- const { extractModuleBedrockDependencies } = await import("./pack-lifecycle.js");
75
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sfmc-extract-dep-test-"));
76
- try {
77
- fs.mkdirSync(path.join(tmpDir, "sapi"), { recursive: true });
78
- fs.writeFileSync(
79
- path.join(tmpDir, "sapi", "manifest.json"),
80
- JSON.stringify({
81
- schemaVersion: 2,
82
- id: "test-menu",
83
- name: "\u6D4B\u8BD5\u83DC\u5355",
84
- configKey: "test",
85
- requires: [],
86
- permissions: [],
87
- dependencies: [
88
- { module_name: "@minecraft/server-ui", version: "2.0.0-beta" }
89
- ]
90
- })
91
- );
92
- fs.writeFileSync(
93
- path.join(tmpDir, "package.json"),
94
- JSON.stringify({
95
- peerDependencies: {
96
- "@minecraft/server": ">=1.18.0"
97
- },
98
- devDependencies: {
99
- "@minecraft/server": "2.10.0-beta.1.26.40-preview.30"
100
- }
101
- })
102
- );
103
- const deps = await extractModuleBedrockDependencies(tmpDir);
104
- assert.equal(deps.length, 2);
105
- assert.ok(deps.some((d) => d.module_name === "@minecraft/server-ui" && d.version === "2.0.0-beta"));
106
- assert.ok(deps.some((d) => d.module_name === "@minecraft/server" && d.version === ">=1.18.0"));
107
- } finally {
108
- fs.rmSync(tmpDir, { recursive: true, force: true });
109
- }
110
- });
111
- //# sourceMappingURL=pack-bundle.test.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/pack-bundle.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 { build } from \"esbuild\";\nimport { createSdkResolvePlugin } from \"./pack-lifecycle.js\";\nimport { resolveSdkPackageRoot } from \"./runtime.js\";\n\ntest(\"pack bundling: sfmc:host bundles installHostBootstrap without unbundled SDK imports\", async () => {\n const sdkRoot = resolveSdkPackageRoot();\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-bundle-test-\"));\n const dummyModFile = path.join(tmpDir, \"dummy-mod.ts\");\n\n fs.writeFileSync(\n dummyModFile,\n `\nimport { ModuleRegistry } from \"@sfmc-bds/sdk/module-loader\";\nimport { Command, Permission } from \"@sfmc-bds/sdk/sapi/runtime\";\nglobalThis.__testEvalOrder = (globalThis.__testEvalOrder || []).concat(\"module\");\nCommand.register(\"dummy\", Permission.Any, () => undefined, \"dummy\", \"test-feature\");\nModuleRegistry.register({ id: \"test-feature\", lifecycle: {} });\n`\n );\n\n try {\n const res = await build({\n stdin: {\n contents: [\n 'import \"sfmc:host\";',\n `import ${JSON.stringify(dummyModFile.replace(/\\\\/g, \"/\"))};`,\n ].join(\"\\n\"),\n resolveDir: tmpDir,\n sourcefile: \"bootstrap.ts\",\n loader: \"ts\",\n },\n write: false,\n bundle: true,\n platform: \"neutral\",\n format: \"esm\",\n target: \"es2022\",\n external: [\"@minecraft/*\"],\n plugins: [createSdkResolvePlugin(sdkRoot)],\n });\n\n const code = res.outputFiles[0].text;\n\n // 1. \u786E\u4FDD\u672A\u6B8B\u7559\u672A\u6253\u5305\u7684 @sfmc-bds/sdk import\n assert.doesNotMatch(\n code,\n /import\\s+.*from\\s+[\"']@sfmc(?:-bds)?\\/sdk/i,\n \"Bundle must not contain unbundled @sfmc-bds/sdk bare imports\"\n );\n\n // 2. \u786E\u4FDD installHostBootstrap \u5305\u542B\u5728\u4EA7\u7269\u4E2D\u4E14\u5DF2\u88AB\u8C03\u7528\n assert.match(code, /installHostBootstrap\\(\\)/, \"Bundle must call installHostBootstrap()\");\n\n // 3. \u786E\u4FDD\u6240\u6709\u5916\u90E8 import \u5747\u5C40\u9650\u4E8E @minecraft/* \u539F\u751F\u6A21\u5757\n const importLines = code\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter((l) => l.startsWith(\"import \") && l.includes(\" from \"));\n for (const line of importLines) {\n assert.match(\n line,\n /from\\s+[\"']@minecraft\\//,\n `Unexpected external import line in bundle: ${line}`\n );\n }\n\n // 4. \u786E\u4FDD installHostBootstrap \u5728\u4E1A\u52A1\u6A21\u5757 evaluation \u4E4B\u524D\u6267\u884C\n const hostCallIdx = code.indexOf(\"installHostBootstrap();\");\n const modMarkerIdx = code.indexOf(\"__testEvalOrder\");\n assert.ok(hostCallIdx !== -1, \"installHostBootstrap call exists\");\n assert.ok(modMarkerIdx !== -1, \"module eval marker exists\");\n assert.ok(\n hostCallIdx < modMarkerIdx,\n `installHostBootstrap() (idx: ${hostCallIdx}) must execute before module evaluation (idx: ${modMarkerIdx})`\n );\n\n // 5. SDK \u5B50\u8DEF\u5F84\u4F1A\u5206\u522B\u9884\u6253\u5305\uFF0C\u4F46\u6240\u6709\u526F\u672C\u5FC5\u987B\u7ED1\u5B9A\u540C\u4E00\u4E2A\u5168\u5C40\u547D\u4EE4/\u6743\u9650\u72B6\u6001\u3002\n const commandStateRefs = code.match(/__sfmcCommandState/g)?.length ?? 0;\n const permissionStateRefs = code.match(/__sfmcPermissionRegistry/g)?.length ?? 0;\n assert.ok(commandStateRefs >= 2, \"Bundled SDK copies must share __sfmcCommandState\");\n assert.ok(permissionStateRefs >= 2, \"Bundled SDK copies must share __sfmcPermissionRegistry\");\n } finally {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n }\n});\n\ntest(\"extractModuleBedrockDependencies: \u4ECE sapi/manifest.json \u4E0E package.json \u63D0\u53D6\u539F\u751F\u4F9D\u8D56\", async () => {\n const { extractModuleBedrockDependencies } = await import(\"./pack-lifecycle.js\");\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-extract-dep-test-\"));\n try {\n fs.mkdirSync(path.join(tmpDir, \"sapi\"), { recursive: true });\n fs.writeFileSync(\n path.join(tmpDir, \"sapi\", \"manifest.json\"),\n JSON.stringify({\n schemaVersion: 2,\n id: \"test-menu\",\n name: \"\u6D4B\u8BD5\u83DC\u5355\",\n configKey: \"test\",\n requires: [],\n permissions: [],\n dependencies: [\n { module_name: \"@minecraft/server-ui\", version: \"2.0.0-beta\" },\n ],\n })\n );\n fs.writeFileSync(\n path.join(tmpDir, \"package.json\"),\n JSON.stringify({\n peerDependencies: {\n \"@minecraft/server\": \">=1.18.0\",\n },\n devDependencies: {\n \"@minecraft/server\": \"2.10.0-beta.1.26.40-preview.30\",\n },\n })\n );\n\n const deps = await extractModuleBedrockDependencies(tmpDir);\n assert.equal(deps.length, 2);\n assert.ok(deps.some((d) => d.module_name === \"@minecraft/server-ui\" && d.version === \"2.0.0-beta\"));\n assert.ok(deps.some((d) => d.module_name === \"@minecraft/server\" && d.version === \">=1.18.0\"));\n } finally {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n }\n});\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,19 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import { parseBdsPlayerSession } from "./player-session.js";
4
- test("\u89E3\u6790 BDS \u73A9\u5BB6\u8FDE\u63A5\u65E5\u5FD7", () => {
5
- assert.deepEqual(parseBdsPlayerSession("[INFO] Player connected: Steve, xuid: 2535412345678901"), {
6
- connected: true,
7
- playerName: "Steve",
8
- xuid: "2535412345678901"
9
- });
10
- });
11
- test("\u89E3\u6790 BDS \u73A9\u5BB6\u65AD\u5F00\u65E5\u5FD7", () => {
12
- assert.deepEqual(parseBdsPlayerSession("Player disconnected: Alex, xuid: 42"), {
13
- connected: false,
14
- playerName: "Alex",
15
- xuid: "42"
16
- });
17
- assert.equal(parseBdsPlayerSession("Server started."), null);
18
- });
19
- //# sourceMappingURL=player-session.test.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/player-session.test.ts"],
4
- "sourcesContent": ["import assert from \"node:assert/strict\";\nimport test from \"node:test\";\nimport { parseBdsPlayerSession } from \"./player-session.js\";\n\ntest(\"\u89E3\u6790 BDS \u73A9\u5BB6\u8FDE\u63A5\u65E5\u5FD7\", () => {\n assert.deepEqual(parseBdsPlayerSession(\"[INFO] Player connected: Steve, xuid: 2535412345678901\"), {\n connected: true,\n playerName: \"Steve\",\n xuid: \"2535412345678901\",\n });\n});\n\ntest(\"\u89E3\u6790 BDS \u73A9\u5BB6\u65AD\u5F00\u65E5\u5FD7\", () => {\n assert.deepEqual(parseBdsPlayerSession(\"Player disconnected: Alex, xuid: 42\"), {\n connected: false,\n playerName: \"Alex\",\n xuid: \"42\",\n });\n assert.equal(parseBdsPlayerSession(\"Server started.\"), null);\n});\n"],
5
- "mappings": "AAAA,OAAO,YAAY;AACnB,OAAO,UAAU;AACjB,SAAS,6BAA6B;AAEtC,KAAK,yDAAiB,MAAM;AAC1B,SAAO,UAAU,sBAAsB,wDAAwD,GAAG;AAAA,IAChG,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,MAAM;AAAA,EACR,CAAC;AACH,CAAC;AAED,KAAK,yDAAiB,MAAM;AAC1B,SAAO,UAAU,sBAAsB,qCAAqC,GAAG;AAAA,IAC7E,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,MAAM;AAAA,EACR,CAAC;AACD,SAAO,MAAM,sBAAsB,iBAAiB,GAAG,IAAI;AAC7D,CAAC;",
6
- "names": []
7
- }