@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.
- package/dist/bds-runtime-version.d.ts +3 -0
- package/dist/bds-runtime-version.d.ts.map +1 -0
- package/dist/bds-runtime-version.js +15 -0
- package/dist/bds-runtime-version.js.map +7 -0
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +78 -75
- package/dist/commands.js.map +2 -2
- package/dist/llbot-launch.d.ts +3 -3
- package/dist/llbot-launch.js.map +1 -1
- package/dist/logs.js +3 -3
- package/dist/logs.js.map +2 -2
- package/dist/repl-windows/service-window.d.ts.map +1 -1
- package/dist/repl-windows/service-window.js +1 -0
- package/dist/repl-windows/service-window.js.map +2 -2
- package/dist/repl.d.ts.map +1 -1
- package/dist/repl.js +18 -12
- package/dist/repl.js.map +2 -2
- package/dist/send-target.d.ts.map +1 -1
- package/dist/send-target.js +2 -0
- package/dist/send-target.js.map +2 -2
- package/dist/services.d.ts +8 -1
- package/dist/services.d.ts.map +1 -1
- package/dist/services.js +151 -15
- package/dist/services.js.map +2 -2
- package/dist/ui-command.d.ts.map +1 -1
- package/dist/ui-command.js.map +2 -2
- package/dist/wizard.d.ts.map +1 -1
- package/dist/wizard.js +15 -8
- package/dist/wizard.js.map +2 -2
- package/package.json +4 -5
- package/scripts/module-install/lib/catalog.mjs +1 -1
- package/dist/command-surface.test.js +0 -92
- package/dist/command-surface.test.js.map +0 -7
- package/dist/debug-command.test.js +0 -76
- package/dist/debug-command.test.js.map +0 -7
- package/dist/log-filter.test.js +0 -181
- package/dist/log-filter.test.js.map +0 -7
- package/dist/log-translator.test.js +0 -120
- package/dist/log-translator.test.js.map +0 -7
- package/dist/logs-blank-line.test.js +0 -16
- package/dist/logs-blank-line.test.js.map +0 -7
- package/dist/module-toggle.test.js +0 -37
- package/dist/module-toggle.test.js.map +0 -7
- package/dist/pack-bundle.test.js +0 -111
- package/dist/pack-bundle.test.js.map +0 -7
- package/dist/player-session.test.js +0 -19
- package/dist/player-session.test.js.map +0 -7
- package/dist/repl-windows/host.test.js +0 -72
- package/dist/repl-windows/host.test.js.map +0 -7
- package/dist/services-output.test.js +0 -9
- package/dist/services-output.test.js.map +0 -7
- package/dist/world-packs-list.test.js +0 -11
- package/dist/world-packs-list.test.js.map +0 -7
- package/dist/world-packs-uninstall.test.js +0 -54
- package/dist/world-packs-uninstall.test.js.map +0 -7
- package/scripts/module-install/test/check-modules-config.test.ts +0 -46
- package/scripts/module-install/test/config-seeding.test.ts +0 -99
- package/scripts/module-install/test/install-resolver.test.ts +0 -47
- package/scripts/module-install/test/link-local.test.ts +0 -50
- package/scripts/module-install/test/local-resolver.test.ts +0 -44
- package/scripts/module-install/test/registry-index.test.ts +0 -27
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import test from "node:test";
|
|
3
|
-
import { WindowHost, serviceWindowId } from "./host.js";
|
|
4
|
-
import { createServiceWindow } from "./service-window.js";
|
|
5
|
-
import { createSfmcWindow, SFMC_WINDOW_ID } from "./sfmc-window.js";
|
|
6
|
-
test("WindowHost: \u7BA1\u7406\u670D\u52A1\u7A97\u4E0E SFMC \u5E73\u53F0\u7A97\u751F\u547D\u5468\u671F", () => {
|
|
7
|
-
const written = [];
|
|
8
|
-
const host = new WindowHost({ writeLog: (l) => written.push(l) });
|
|
9
|
-
let activeTargets = ["bds"];
|
|
10
|
-
host.register(createServiceWindow("bds"));
|
|
11
|
-
host.register(createSfmcWindow({ getActiveTargets: () => activeTargets }));
|
|
12
|
-
host.setServiceOrder([serviceWindowId("bds"), SFMC_WINDOW_ID]);
|
|
13
|
-
assert.equal(host.getActiveId(), serviceWindowId("bds"));
|
|
14
|
-
assert.equal(host.getActive()?.title, "BDS");
|
|
15
|
-
assert.equal(host.getActive()?.serviceName, "bds");
|
|
16
|
-
const res1 = host.cycleServiceWindows();
|
|
17
|
-
assert.equal(res1.switched, true);
|
|
18
|
-
assert.equal(res1.serviceName, null);
|
|
19
|
-
assert.equal(host.getActiveId(), SFMC_WINDOW_ID);
|
|
20
|
-
assert.equal(host.getActive()?.title, "SFMC");
|
|
21
|
-
assert.equal(host.getActive()?.serviceName, void 0);
|
|
22
|
-
const res2 = host.cycleServiceWindows();
|
|
23
|
-
assert.equal(res2.switched, true);
|
|
24
|
-
assert.equal(res2.serviceName, "bds");
|
|
25
|
-
assert.equal(host.getActiveId(), serviceWindowId("bds"));
|
|
26
|
-
activeTargets = [];
|
|
27
|
-
host.setServiceOrder([]);
|
|
28
|
-
assert.equal(host.getActiveId(), null);
|
|
29
|
-
assert.equal(host.has(serviceWindowId("bds")), false);
|
|
30
|
-
assert.equal(host.has(SFMC_WINDOW_ID), false);
|
|
31
|
-
});
|
|
32
|
-
test("createSfmcWindow: acceptLog \u8FC7\u6EE4\u6D3B\u8DC3\u670D\u52A1\u65E5\u5FD7\u5E76\u63A5\u6536\u975E\u670D\u52A1/\u5E73\u53F0\u65E5\u5FD7", () => {
|
|
33
|
-
const activeTargets = ["bds", "db"];
|
|
34
|
-
const win = createSfmcWindow({ getActiveTargets: () => activeTargets });
|
|
35
|
-
const now = /* @__PURE__ */ new Date();
|
|
36
|
-
const bdsLog = { time: now, source: "bds", level: "info", text: "Server started" };
|
|
37
|
-
const dbLog = { time: now, source: "db", level: "info", text: "Database ready" };
|
|
38
|
-
const packLog = { time: now, source: "pack", level: "info", text: "assembled BP uuid=xxx" };
|
|
39
|
-
const sysLog = { time: now, source: "system", level: "info", text: "Platform initialized" };
|
|
40
|
-
const qqLog = { time: now, source: "qq", level: "info", text: "QQ stopped" };
|
|
41
|
-
assert.equal(win.acceptLog(bdsLog), false);
|
|
42
|
-
assert.equal(win.acceptLog(dbLog), false);
|
|
43
|
-
assert.equal(win.acceptLog(packLog), true);
|
|
44
|
-
assert.equal(win.acceptLog(sysLog), true);
|
|
45
|
-
assert.equal(win.acceptLog(qqLog), true);
|
|
46
|
-
const formatted = win.formatLogLine(packLog);
|
|
47
|
-
assert.ok(formatted.text.includes("[PAK]"));
|
|
48
|
-
});
|
|
49
|
-
test("WindowHost: routeLog \u5C06\u65E5\u5FD7\u6B63\u786E\u5206\u6D41\u5230\u6D3B\u52A8\u7A97\u53E3\u4E0E\u540E\u53F0\u7A97\u53E3\u7F13\u5B58", () => {
|
|
50
|
-
const written = [];
|
|
51
|
-
const host = new WindowHost({ writeLog: (l) => written.push(l) });
|
|
52
|
-
const activeTargets = ["bds"];
|
|
53
|
-
host.register(createServiceWindow("bds"));
|
|
54
|
-
host.register(createSfmcWindow({ getActiveTargets: () => activeTargets }));
|
|
55
|
-
host.setServiceOrder([serviceWindowId("bds"), SFMC_WINDOW_ID]);
|
|
56
|
-
host.setBuffer(serviceWindowId("bds"), []);
|
|
57
|
-
host.setBuffer(SFMC_WINDOW_ID, []);
|
|
58
|
-
assert.equal(host.getActiveId(), serviceWindowId("bds"));
|
|
59
|
-
const now = /* @__PURE__ */ new Date();
|
|
60
|
-
const bdsLog = { time: now, source: "bds", level: "info", text: "Hello BDS" };
|
|
61
|
-
const packLog = { time: now, source: "pack", level: "info", text: "Building pack" };
|
|
62
|
-
host.routeLog(bdsLog);
|
|
63
|
-
assert.equal(written.length, 1);
|
|
64
|
-
assert.ok(written[0]?.includes("Hello BDS"));
|
|
65
|
-
host.routeLog(packLog);
|
|
66
|
-
assert.equal(written.length, 1);
|
|
67
|
-
const sfmcBuffer = host.getBuffer(SFMC_WINDOW_ID);
|
|
68
|
-
assert.equal(sfmcBuffer.length, 1);
|
|
69
|
-
assert.ok(sfmcBuffer[0]?.includes("Building pack"));
|
|
70
|
-
assert.ok(sfmcBuffer[0]?.includes("[PAK]"));
|
|
71
|
-
});
|
|
72
|
-
//# sourceMappingURL=host.test.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/repl-windows/host.test.ts"],
|
|
4
|
-
"sourcesContent": ["import assert from \"node:assert/strict\";\nimport test from \"node:test\";\nimport type { UnifiedLog } from \"../logs.js\";\nimport type { ServiceName } from \"../services.js\";\nimport { WindowHost, serviceWindowId } from \"./host.js\";\nimport { createServiceWindow } from \"./service-window.js\";\nimport { createSfmcWindow, SFMC_WINDOW_ID } from \"./sfmc-window.js\";\n\ntest(\"WindowHost: \u7BA1\u7406\u670D\u52A1\u7A97\u4E0E SFMC \u5E73\u53F0\u7A97\u751F\u547D\u5468\u671F\", () => {\n const written: string[] = [];\n const host = new WindowHost({ writeLog: (l) => written.push(l) });\n\n let activeTargets: ServiceName[] = [\"bds\"];\n host.register(createServiceWindow(\"bds\"));\n host.register(createSfmcWindow({ getActiveTargets: () => activeTargets }));\n\n host.setServiceOrder([serviceWindowId(\"bds\"), SFMC_WINDOW_ID]);\n\n // \u521D\u59CB\u6FC0\u6D3B\u7B2C 1 \u4E2A\u7A97\u53E3\uFF08bds\uFF09\n assert.equal(host.getActiveId(), serviceWindowId(\"bds\"));\n assert.equal(host.getActive()?.title, \"BDS\");\n assert.equal(host.getActive()?.serviceName, \"bds\");\n\n // Tab \u8F6E\u6362\u81F3 SFMC \u7A97\n const res1 = host.cycleServiceWindows();\n assert.equal(res1.switched, true);\n assert.equal(res1.serviceName, null);\n assert.equal(host.getActiveId(), SFMC_WINDOW_ID);\n assert.equal(host.getActive()?.title, \"SFMC\");\n assert.equal(host.getActive()?.serviceName, undefined);\n\n // \u518D\u6B21 Tab \u8F6E\u6362\u56DE BDS \u7A97\n const res2 = host.cycleServiceWindows();\n assert.equal(res2.switched, true);\n assert.equal(res2.serviceName, \"bds\");\n assert.equal(host.getActiveId(), serviceWindowId(\"bds\"));\n\n // \u670D\u52A1\u505C\u6B62\uFF1AsetServiceOrder \u6E05\u7A7A\u65F6\u5E94\u6CE8\u9500\u670D\u52A1\u7A97\u4E0E SFMC \u7A97\n activeTargets = [];\n host.setServiceOrder([]);\n assert.equal(host.getActiveId(), null);\n assert.equal(host.has(serviceWindowId(\"bds\")), false);\n assert.equal(host.has(SFMC_WINDOW_ID), false);\n});\n\ntest(\"createSfmcWindow: acceptLog \u8FC7\u6EE4\u6D3B\u8DC3\u670D\u52A1\u65E5\u5FD7\u5E76\u63A5\u6536\u975E\u670D\u52A1/\u5E73\u53F0\u65E5\u5FD7\", () => {\n const activeTargets: ServiceName[] = [\"bds\", \"db\"];\n const win = createSfmcWindow({ getActiveTargets: () => activeTargets });\n\n const now = new Date();\n const bdsLog: UnifiedLog = { time: now, source: \"bds\", level: \"info\", text: \"Server started\" };\n const dbLog: UnifiedLog = { time: now, source: \"db\", level: \"info\", text: \"Database ready\" };\n const packLog: UnifiedLog = { time: now, source: \"pack\", level: \"info\", text: \"assembled BP uuid=xxx\" };\n const sysLog: UnifiedLog = { time: now, source: \"system\", level: \"info\", text: \"Platform initialized\" };\n const qqLog: UnifiedLog = { time: now, source: \"qq\", level: \"info\", text: \"QQ stopped\" };\n\n // \u6D3B\u8DC3\u670D\u52A1\uFF08bds, db\uFF09\u7684\u65E5\u5FD7\u5728 SFMC \u7A97\u88AB\u8FC7\u6EE4\n assert.equal(win.acceptLog(bdsLog), false);\n assert.equal(win.acceptLog(dbLog), false);\n\n // \u975E\u6D3B\u8DC3\u670D\u52A1\u6216\u5E73\u53F0\u65E5\u5FD7\uFF08pack, system, qq\uFF09\u5728 SFMC \u7A97\u88AB\u63A5\u6536\n assert.equal(win.acceptLog(packLog), true);\n assert.equal(win.acceptLog(sysLog), true);\n assert.equal(win.acceptLog(qqLog), true);\n\n // \u683C\u5F0F\u5316\u8F93\u51FA\u5E94\u5305\u542B\u6765\u6E90\u6807\u7B7E\uFF08omitSource: false\uFF09\n const formatted = win.formatLogLine(packLog);\n assert.ok(formatted.text.includes(\"[PAK]\"));\n});\n\ntest(\"WindowHost: routeLog \u5C06\u65E5\u5FD7\u6B63\u786E\u5206\u6D41\u5230\u6D3B\u52A8\u7A97\u53E3\u4E0E\u540E\u53F0\u7A97\u53E3\u7F13\u5B58\", () => {\n const written: string[] = [];\n const host = new WindowHost({ writeLog: (l) => written.push(l) });\n\n const activeTargets: ServiceName[] = [\"bds\"];\n host.register(createServiceWindow(\"bds\"));\n host.register(createSfmcWindow({ getActiveTargets: () => activeTargets }));\n host.setServiceOrder([serviceWindowId(\"bds\"), SFMC_WINDOW_ID]);\n\n // \u7ED9\u4E24\u4E2A\u7A97\u53E3\u9884\u8BBE buffer\uFF08\u6A21\u62DF seed\uFF09\n host.setBuffer(serviceWindowId(\"bds\"), []);\n host.setBuffer(SFMC_WINDOW_ID, []);\n\n // \u5F53\u524D\u5728 BDS \u7A97\n assert.equal(host.getActiveId(), serviceWindowId(\"bds\"));\n\n const now = new Date();\n const bdsLog: UnifiedLog = { time: now, source: \"bds\", level: \"info\", text: \"Hello BDS\" };\n const packLog: UnifiedLog = { time: now, source: \"pack\", level: \"info\", text: \"Building pack\" };\n\n // \u4EA7\u751F BDS \u65E5\u5FD7\uFF1A\u6D3B\u52A8\u7A97\u7ACB\u5373\u6536\u5230\u5199\u5165\n host.routeLog(bdsLog);\n assert.equal(written.length, 1);\n assert.ok(written[0]?.includes(\"Hello BDS\"));\n\n // \u4EA7\u751F Pack \u65E5\u5FD7\uFF1A\u5F53\u524D\u5728 BDS \u7A97\uFF0CTty \u4E0D\u76F4\u63A5\u5199\uFF0C\u4F46 SFMC \u7A97\u53E3\u540E\u53F0 buffer \u5E94\u8FFD\u52A0\n host.routeLog(packLog);\n assert.equal(written.length, 1); // \u6CA1\u6709\u76F4\u63A5\u5199\u5230\u5F53\u524D Tty\n const sfmcBuffer = host.getBuffer(SFMC_WINDOW_ID);\n assert.equal(sfmcBuffer.length, 1);\n assert.ok(sfmcBuffer[0]?.includes(\"Building pack\"));\n assert.ok(sfmcBuffer[0]?.includes(\"[PAK]\"));\n});\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import { describe, it } from "node:test";
|
|
3
|
-
import { nonBlankOutputLines } from "./services.js";
|
|
4
|
-
describe("\u5B50\u8FDB\u7A0B\u8F93\u51FA\u5206\u884C", () => {
|
|
5
|
-
it("\u8FC7\u6EE4 LF\u3001CRLF \u4E0E\u7EAF\u7A7A\u767D\u884C\uFF0C\u4FDD\u7559\u771F\u5B9E\u65E5\u5FD7\u5185\u5BB9", () => {
|
|
6
|
-
assert.deepEqual(nonBlankOutputLines("first\r\n\r\n \r\nsecond\r\n"), ["first", "second"]);
|
|
7
|
-
});
|
|
8
|
-
});
|
|
9
|
-
//# sourceMappingURL=services-output.test.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/services-output.test.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * \u5B50\u8FDB\u7A0B\u65E5\u5FD7\u5165\u53E3\u5951\u7EA6\uFF1A\u7EAF\u7A7A\u767D\u884C\u4E0D\u80FD\u8FDB\u5165\u7EDF\u4E00\u65E5\u5FD7\u5E76\u88AB\u5305\u88C5\u6210 [INF]\u3002\n */\nimport assert from \"node:assert/strict\";\nimport { describe, it } from \"node:test\";\nimport { nonBlankOutputLines } from \"./services.js\";\n\ndescribe(\"\u5B50\u8FDB\u7A0B\u8F93\u51FA\u5206\u884C\", () => {\n it(\"\u8FC7\u6EE4 LF\u3001CRLF \u4E0E\u7EAF\u7A7A\u767D\u884C\uFF0C\u4FDD\u7559\u771F\u5B9E\u65E5\u5FD7\u5185\u5BB9\", () => {\n assert.deepEqual(nonBlankOutputLines(\"first\\r\\n\\r\\n \\r\\nsecond\\r\\n\"), [\"first\", \"second\"]);\n });\n});\n"],
|
|
5
|
-
"mappings": "AAGA,OAAO,YAAY;AACnB,SAAS,UAAU,UAAU;AAC7B,SAAS,2BAA2B;AAEpC,SAAS,8CAAW,MAAM;AACxB,KAAG,kHAA6B,MAAM;AACpC,WAAO,UAAU,oBAAoB,+BAA+B,GAAG,CAAC,SAAS,QAAQ,CAAC;AAAA,EAC5F,CAAC;AACH,CAAC;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import { describe, it } from "node:test";
|
|
3
|
-
import { shouldDisplayPackSourceLabel } from "./world-packs.js";
|
|
4
|
-
describe("packs list \u66F4\u65B0\u6E90\u5217", () => {
|
|
5
|
-
it("\u9690\u85CF\u672A\u7ED1\u5B9A\u5360\u4F4D\u7B26\uFF0C\u4FDD\u7559\u5DF2\u7ED1\u5B9A\u4E0E\u5DF2\u505C\u7528\u6765\u6E90", () => {
|
|
6
|
-
assert.equal(shouldDisplayPackSourceLabel("src=-"), false);
|
|
7
|
-
assert.equal(shouldDisplayPackSourceLabel("src=CF:farmers-delight"), true);
|
|
8
|
-
assert.equal(shouldDisplayPackSourceLabel("src=CF:farmers-delight:off"), true);
|
|
9
|
-
});
|
|
10
|
-
});
|
|
11
|
-
//# sourceMappingURL=world-packs-list.test.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/world-packs-list.test.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * packs list \u5C55\u793A\u5951\u7EA6\uFF1A\u672A\u7ED1\u5B9A\u66F4\u65B0\u6E90\u65F6\u4E0D\u8F93\u51FA\u65E0\u610F\u4E49\u7684 src=- \u5217\u3002\n */\nimport assert from \"node:assert/strict\";\nimport { describe, it } from \"node:test\";\nimport { shouldDisplayPackSourceLabel } from \"./world-packs.js\";\n\ndescribe(\"packs list \u66F4\u65B0\u6E90\u5217\", () => {\n it(\"\u9690\u85CF\u672A\u7ED1\u5B9A\u5360\u4F4D\u7B26\uFF0C\u4FDD\u7559\u5DF2\u7ED1\u5B9A\u4E0E\u5DF2\u505C\u7528\u6765\u6E90\", () => {\n assert.equal(shouldDisplayPackSourceLabel(\"src=-\"), false);\n assert.equal(shouldDisplayPackSourceLabel(\"src=CF:farmers-delight\"), true);\n assert.equal(shouldDisplayPackSourceLabel(\"src=CF:farmers-delight:off\"), true);\n });\n});\n"],
|
|
5
|
-
"mappings": "AAGA,OAAO,YAAY;AACnB,SAAS,UAAU,UAAU;AAC7B,SAAS,oCAAoC;AAE7C,SAAS,uCAAmB,MAAM;AAChC,KAAG,4HAAwB,MAAM;AAC/B,WAAO,MAAM,6BAA6B,OAAO,GAAG,KAAK;AACzD,WAAO,MAAM,6BAA6B,wBAAwB,GAAG,IAAI;AACzE,WAAO,MAAM,6BAA6B,4BAA4B,GAAG,IAAI;AAAA,EAC/E,CAAC;AACH,CAAC;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import { describe, it } from "node:test";
|
|
3
|
-
import { isProtectedSfmcPack, resolveUninstallTargets } from "./world-packs.js";
|
|
4
|
-
function fakePack(folderName, uuid = `uuid-${folderName}`) {
|
|
5
|
-
return {
|
|
6
|
-
folderName,
|
|
7
|
-
uuid,
|
|
8
|
-
name: folderName,
|
|
9
|
-
kind: "behavior",
|
|
10
|
-
version: [1, 0, 0],
|
|
11
|
-
enabled: true,
|
|
12
|
-
dir: `/tmp/${folderName}`
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
describe("packs uninstall protection", () => {
|
|
16
|
-
it("\u8BC6\u522B sfmc-modules / sfmc-modules-rp\uFF0C\u5FFD\u7565\u5927\u5C0F\u5199", () => {
|
|
17
|
-
assert.equal(isProtectedSfmcPack({ folderName: "sfmc-modules" }), true);
|
|
18
|
-
assert.equal(isProtectedSfmcPack({ folderName: "SFMC-Modules" }), true);
|
|
19
|
-
assert.equal(isProtectedSfmcPack({ folderName: "sfmc-modules-rp" }), true);
|
|
20
|
-
assert.equal(isProtectedSfmcPack({ folderName: "[BP] MyAddon" }), false);
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
describe("resolveUninstallTargets LSP", () => {
|
|
24
|
-
const packs = [
|
|
25
|
-
fakePack("sfmc-modules", "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"),
|
|
26
|
-
fakePack("[BP] Addon", "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"),
|
|
27
|
-
fakePack("[BP] Other", "cccccccc-cccc-cccc-cccc-cccccccccccc")
|
|
28
|
-
];
|
|
29
|
-
it("\u5355 id \u53D7\u4FDD\u62A4 \u2192 protected", () => {
|
|
30
|
-
const r = resolveUninstallTargets(packs, ["sfmc-modules"]);
|
|
31
|
-
assert.equal(r.status, "protected");
|
|
32
|
-
if (r.status === "protected") assert.equal(r.folder, "sfmc-modules");
|
|
33
|
-
});
|
|
34
|
-
it("\u591A id \u542B\u53D7\u4FDD\u62A4 \u2192 \u6574\u4F53 protected\uFF08\u4E0D\u8FD4\u56DE ok\uFF09", () => {
|
|
35
|
-
const r = resolveUninstallTargets(packs, ["[BP] Addon", "sfmc-modules"]);
|
|
36
|
-
assert.equal(r.status, "protected");
|
|
37
|
-
if (r.status === "protected") assert.equal(r.folder, "sfmc-modules");
|
|
38
|
-
});
|
|
39
|
-
it("\u591A id \u5747\u53EF\u5378 \u2192 ok\uFF0C\u6309 uuid \u53BB\u91CD", () => {
|
|
40
|
-
const r = resolveUninstallTargets(packs, [
|
|
41
|
-
"[BP] Addon",
|
|
42
|
-
"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
|
|
43
|
-
"[BP] Other"
|
|
44
|
-
]);
|
|
45
|
-
assert.equal(r.status, "ok");
|
|
46
|
-
if (r.status === "ok") assert.equal(r.selected.length, 2);
|
|
47
|
-
});
|
|
48
|
-
it("\u7F3A id \u2192 not_found", () => {
|
|
49
|
-
const r = resolveUninstallTargets(packs, ["nope", "[BP] Addon"]);
|
|
50
|
-
assert.equal(r.status, "not_found");
|
|
51
|
-
if (r.status === "not_found") assert.deepEqual(r.missing, ["nope"]);
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
//# sourceMappingURL=world-packs-uninstall.test.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/world-packs-uninstall.test.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * packs uninstall \u7B56\u7565\u5951\u7EA6\uFF1A\u53D7\u4FDD\u62A4\u5E73\u53F0\u5305\u8BC6\u522B + \u591A id \u89E3\u6790\n */\nimport assert from \"node:assert/strict\";\nimport { describe, it } from \"node:test\";\nimport { isProtectedSfmcPack, resolveUninstallTargets, type InstalledWorldPack } from \"./world-packs.js\";\n\nfunction fakePack(folderName: string, uuid = `uuid-${folderName}`): InstalledWorldPack {\n return {\n folderName,\n uuid,\n name: folderName,\n kind: \"behavior\",\n version: [1, 0, 0],\n enabled: true,\n dir: `/tmp/${folderName}`,\n };\n}\n\ndescribe(\"packs uninstall protection\", () => {\n it(\"\u8BC6\u522B sfmc-modules / sfmc-modules-rp\uFF0C\u5FFD\u7565\u5927\u5C0F\u5199\", () => {\n assert.equal(isProtectedSfmcPack({ folderName: \"sfmc-modules\" }), true);\n assert.equal(isProtectedSfmcPack({ folderName: \"SFMC-Modules\" }), true);\n assert.equal(isProtectedSfmcPack({ folderName: \"sfmc-modules-rp\" }), true);\n assert.equal(isProtectedSfmcPack({ folderName: \"[BP] MyAddon\" }), false);\n });\n});\n\ndescribe(\"resolveUninstallTargets LSP\", () => {\n const packs = [\n fakePack(\"sfmc-modules\", \"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa\"),\n fakePack(\"[BP] Addon\", \"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb\"),\n fakePack(\"[BP] Other\", \"cccccccc-cccc-cccc-cccc-cccccccccccc\"),\n ];\n\n it(\"\u5355 id \u53D7\u4FDD\u62A4 \u2192 protected\", () => {\n const r = resolveUninstallTargets(packs, [\"sfmc-modules\"]);\n assert.equal(r.status, \"protected\");\n if (r.status === \"protected\") assert.equal(r.folder, \"sfmc-modules\");\n });\n\n it(\"\u591A id \u542B\u53D7\u4FDD\u62A4 \u2192 \u6574\u4F53 protected\uFF08\u4E0D\u8FD4\u56DE ok\uFF09\", () => {\n const r = resolveUninstallTargets(packs, [\"[BP] Addon\", \"sfmc-modules\"]);\n assert.equal(r.status, \"protected\");\n if (r.status === \"protected\") assert.equal(r.folder, \"sfmc-modules\");\n });\n\n it(\"\u591A id \u5747\u53EF\u5378 \u2192 ok\uFF0C\u6309 uuid \u53BB\u91CD\", () => {\n const r = resolveUninstallTargets(packs, [\n \"[BP] Addon\",\n \"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb\",\n \"[BP] Other\",\n ]);\n assert.equal(r.status, \"ok\");\n if (r.status === \"ok\") assert.equal(r.selected.length, 2);\n });\n\n it(\"\u7F3A id \u2192 not_found\", () => {\n const r = resolveUninstallTargets(packs, [\"nope\", \"[BP] Addon\"]);\n assert.equal(r.status, \"not_found\");\n if (r.status === \"not_found\") assert.deepEqual(r.missing, [\"nope\"]);\n });\n});\n"],
|
|
5
|
-
"mappings": "AAGA,OAAO,YAAY;AACnB,SAAS,UAAU,UAAU;AAC7B,SAAS,qBAAqB,+BAAwD;AAEtF,SAAS,SAAS,YAAoB,OAAO,QAAQ,UAAU,IAAwB;AACrF,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS,CAAC,GAAG,GAAG,CAAC;AAAA,IACjB,SAAS;AAAA,IACT,KAAK,QAAQ,UAAU;AAAA,EACzB;AACF;AAEA,SAAS,8BAA8B,MAAM;AAC3C,KAAG,mFAA2C,MAAM;AAClD,WAAO,MAAM,oBAAoB,EAAE,YAAY,eAAe,CAAC,GAAG,IAAI;AACtE,WAAO,MAAM,oBAAoB,EAAE,YAAY,eAAe,CAAC,GAAG,IAAI;AACtE,WAAO,MAAM,oBAAoB,EAAE,YAAY,kBAAkB,CAAC,GAAG,IAAI;AACzE,WAAO,MAAM,oBAAoB,EAAE,YAAY,eAAe,CAAC,GAAG,KAAK;AAAA,EACzE,CAAC;AACH,CAAC;AAED,SAAS,+BAA+B,MAAM;AAC5C,QAAM,QAAQ;AAAA,IACZ,SAAS,gBAAgB,sCAAsC;AAAA,IAC/D,SAAS,cAAc,sCAAsC;AAAA,IAC7D,SAAS,cAAc,sCAAsC;AAAA,EAC/D;AAEA,KAAG,iDAAwB,MAAM;AAC/B,UAAM,IAAI,wBAAwB,OAAO,CAAC,cAAc,CAAC;AACzD,WAAO,MAAM,EAAE,QAAQ,WAAW;AAClC,QAAI,EAAE,WAAW,YAAa,QAAO,MAAM,EAAE,QAAQ,cAAc;AAAA,EACrE,CAAC;AAED,KAAG,qGAAoC,MAAM;AAC3C,UAAM,IAAI,wBAAwB,OAAO,CAAC,cAAc,cAAc,CAAC;AACvE,WAAO,MAAM,EAAE,QAAQ,WAAW;AAClC,QAAI,EAAE,WAAW,YAAa,QAAO,MAAM,EAAE,QAAQ,cAAc;AAAA,EACrE,CAAC;AAED,KAAG,wEAA2B,MAAM;AAClC,UAAM,IAAI,wBAAwB,OAAO;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,WAAO,MAAM,EAAE,QAAQ,IAAI;AAC3B,QAAI,EAAE,WAAW,KAAM,QAAO,MAAM,EAAE,SAAS,QAAQ,CAAC;AAAA,EAC1D,CAAC;AAED,KAAG,8BAAoB,MAAM;AAC3B,UAAM,IAAI,wBAAwB,OAAO,CAAC,QAAQ,YAAY,CAAC;AAC/D,WAAO,MAAM,EAAE,QAAQ,WAAW;AAClC,QAAI,EAAE,WAAW,YAAa,QAAO,UAAU,EAAE,SAAS,CAAC,MAAM,CAAC;AAAA,EACpE,CAAC;AACH,CAAC;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,46 +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 { validateDefaultConfig } from "../check-modules.mjs";
|
|
7
|
-
|
|
8
|
-
function moduleFixture(files: Record<string, string> = {}) {
|
|
9
|
-
const root = fs.mkdtempSync(path.join(os.tmpdir(), "sfmc-check-config-"));
|
|
10
|
-
const dir = path.join(root, "configs-default");
|
|
11
|
-
if (Object.keys(files).length > 0) fs.mkdirSync(dir, { recursive: true });
|
|
12
|
-
for (const [name, body] of Object.entries(files)) fs.writeFileSync(path.join(dir, name), body);
|
|
13
|
-
return root;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
test("validateDefaultConfig 接受标准对象配置", () => {
|
|
17
|
-
const root = moduleFixture({ "demo.json": '{"enabled":true}' });
|
|
18
|
-
assert.deepEqual(validateDefaultConfig(root, "demo"), { ok: true });
|
|
19
|
-
fs.rmSync(root, { recursive: true, force: true });
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
test("validateDefaultConfig 对缺失默认配置给出警告", () => {
|
|
23
|
-
const root = moduleFixture();
|
|
24
|
-
const result = validateDefaultConfig(root, "demo");
|
|
25
|
-
assert.equal(result.ok, true);
|
|
26
|
-
if (result.ok) assert.match(result.warning ?? "", /未提供默认配置/);
|
|
27
|
-
fs.rmSync(root, { recursive: true, force: true });
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
test("validateDefaultConfig 拒绝错名、损坏及非对象配置", () => {
|
|
31
|
-
const wrong = moduleFixture({ "other.json": "{}" });
|
|
32
|
-
assert.deepEqual(validateDefaultConfig(wrong, "demo").ok, false);
|
|
33
|
-
fs.rmSync(wrong, { recursive: true, force: true });
|
|
34
|
-
|
|
35
|
-
const broken = moduleFixture({ "demo.json": "{" });
|
|
36
|
-
const brokenResult = validateDefaultConfig(broken, "demo");
|
|
37
|
-
assert.equal(brokenResult.ok, false);
|
|
38
|
-
if (!brokenResult.ok) assert.match(brokenResult.error, /解析失败/);
|
|
39
|
-
fs.rmSync(broken, { recursive: true, force: true });
|
|
40
|
-
|
|
41
|
-
const array = moduleFixture({ "demo.json": "[]" });
|
|
42
|
-
const arrayResult = validateDefaultConfig(array, "demo");
|
|
43
|
-
assert.equal(arrayResult.ok, false);
|
|
44
|
-
if (!arrayResult.ok) assert.match(arrayResult.error, /顶层必须是 JSON 对象/);
|
|
45
|
-
fs.rmSync(array, { recursive: true, force: true });
|
|
46
|
-
});
|
|
@@ -1,99 +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 { mergeMissing, seedModuleConfig } from "../lib/config-seeding.mjs";
|
|
7
|
-
|
|
8
|
-
function fixture(defaults?: unknown, current?: unknown) {
|
|
9
|
-
const root = fs.mkdtempSync(path.join(os.tmpdir(), "sfmc-config-seeding-"));
|
|
10
|
-
const moduleRoot = path.join(root, "module");
|
|
11
|
-
const projectRoot = path.join(root, "project");
|
|
12
|
-
fs.mkdirSync(path.join(moduleRoot, "configs-default"), { recursive: true });
|
|
13
|
-
if (defaults !== undefined) {
|
|
14
|
-
const body = typeof defaults === "string" ? defaults : JSON.stringify(defaults);
|
|
15
|
-
fs.writeFileSync(path.join(moduleRoot, "configs-default", "demo.json"), body);
|
|
16
|
-
}
|
|
17
|
-
if (current !== undefined) {
|
|
18
|
-
fs.mkdirSync(path.join(projectRoot, "configs"), { recursive: true });
|
|
19
|
-
const body = typeof current === "string" ? current : JSON.stringify(current);
|
|
20
|
-
fs.writeFileSync(path.join(projectRoot, "configs", "demo.json"), body);
|
|
21
|
-
}
|
|
22
|
-
return { root, moduleRoot, projectRoot, target: path.join(projectRoot, "configs", "demo.json") };
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
test("mergeMissing 递归补缺且不覆盖或修改输入", () => {
|
|
26
|
-
const current = { enabled: false, nested: { keep: 1 }, list: ["user"], extra: true };
|
|
27
|
-
const defaults = { enabled: true, nested: { keep: 0, added: 2 }, list: ["default"], fresh: "x" };
|
|
28
|
-
const before = structuredClone(current);
|
|
29
|
-
const result = mergeMissing(current, defaults);
|
|
30
|
-
assert.deepEqual(current, before);
|
|
31
|
-
assert.deepEqual(result.value, {
|
|
32
|
-
enabled: false,
|
|
33
|
-
nested: { keep: 1, added: 2 },
|
|
34
|
-
list: ["user"],
|
|
35
|
-
extra: true,
|
|
36
|
-
fresh: "x",
|
|
37
|
-
});
|
|
38
|
-
assert.deepEqual(result.addedPaths, ["fresh", "nested.added"]);
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
test("seedModuleConfig 创建、补缺与无变化", () => {
|
|
42
|
-
const f = fixture({ enabled: true, nested: { first: 1 } });
|
|
43
|
-
const created = seedModuleConfig({ ...f, configKey: "demo" });
|
|
44
|
-
assert.equal(created.status, "created");
|
|
45
|
-
assert.deepEqual(JSON.parse(fs.readFileSync(f.target, "utf8")), {
|
|
46
|
-
enabled: true,
|
|
47
|
-
nested: { first: 1 },
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
fs.writeFileSync(f.target, JSON.stringify({ enabled: false, nested: { first: 9 } }));
|
|
51
|
-
fs.writeFileSync(
|
|
52
|
-
path.join(f.moduleRoot, "configs-default", "demo.json"),
|
|
53
|
-
JSON.stringify({ enabled: true, nested: { first: 1, second: 2 }, list: ["default"] })
|
|
54
|
-
);
|
|
55
|
-
const updated = seedModuleConfig({ ...f, configKey: "demo" });
|
|
56
|
-
assert.equal(updated.status, "updated");
|
|
57
|
-
assert.deepEqual(updated.addedPaths, ["list", "nested.second"]);
|
|
58
|
-
assert.deepEqual(JSON.parse(fs.readFileSync(f.target, "utf8")), {
|
|
59
|
-
enabled: false,
|
|
60
|
-
nested: { first: 9, second: 2 },
|
|
61
|
-
list: ["default"],
|
|
62
|
-
});
|
|
63
|
-
assert.equal(seedModuleConfig({ ...f, configKey: "demo" }).status, "unchanged");
|
|
64
|
-
fs.rmSync(f.root, { recursive: true, force: true });
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
test("seedModuleConfig 缺失默认文件时保持兼容", () => {
|
|
68
|
-
const f = fixture();
|
|
69
|
-
assert.equal(seedModuleConfig({ ...f, configKey: "demo" }).status, "missing-defaults");
|
|
70
|
-
assert.equal(fs.existsSync(f.target), false);
|
|
71
|
-
fs.rmSync(f.root, { recursive: true, force: true });
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
test("seedModuleConfig 拒绝与 configKey 不一致的默认文件名", () => {
|
|
75
|
-
const f = fixture();
|
|
76
|
-
fs.writeFileSync(path.join(f.moduleRoot, "configs-default", "other.json"), "{}");
|
|
77
|
-
assert.throws(() => seedModuleConfig({ ...f, configKey: "demo" }), /文件名必须为/);
|
|
78
|
-
fs.rmSync(f.root, { recursive: true, force: true });
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
test("seedModuleConfig 拒绝损坏 JSON、非对象与非法 configKey", () => {
|
|
82
|
-
const brokenDefault = fixture("{");
|
|
83
|
-
assert.throws(() => seedModuleConfig({ ...brokenDefault, configKey: "demo" }), /默认配置.*解析失败/);
|
|
84
|
-
fs.rmSync(brokenDefault.root, { recursive: true, force: true });
|
|
85
|
-
|
|
86
|
-
const scalar = fixture([]);
|
|
87
|
-
assert.throws(() => seedModuleConfig({ ...scalar, configKey: "demo" }), /顶层必须是 JSON 对象/);
|
|
88
|
-
fs.rmSync(scalar.root, { recursive: true, force: true });
|
|
89
|
-
|
|
90
|
-
const brokenUser = fixture({ ok: true }, "{broken");
|
|
91
|
-
const before = fs.readFileSync(brokenUser.target);
|
|
92
|
-
assert.throws(() => seedModuleConfig({ ...brokenUser, configKey: "demo" }), /用户配置.*解析失败/);
|
|
93
|
-
assert.deepEqual(fs.readFileSync(brokenUser.target), before);
|
|
94
|
-
fs.rmSync(brokenUser.root, { recursive: true, force: true });
|
|
95
|
-
|
|
96
|
-
const invalid = fixture({});
|
|
97
|
-
assert.throws(() => seedModuleConfig({ ...invalid, configKey: "../escape" }), /invalid configKey/);
|
|
98
|
-
fs.rmSync(invalid.root, { recursive: true, force: true });
|
|
99
|
-
});
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* install-resolver npm 包名解析表驱动
|
|
3
|
-
*/
|
|
4
|
-
import assert from "node:assert/strict";
|
|
5
|
-
import test from "node:test";
|
|
6
|
-
import {
|
|
7
|
-
folderFromNpmPackageName,
|
|
8
|
-
normalizeNpmPackageName,
|
|
9
|
-
resolveNpmPackageName,
|
|
10
|
-
} from "../lib/npm-resolver.mjs";
|
|
11
|
-
|
|
12
|
-
test("短 id → @sfmc-bds/module-<id>", () => {
|
|
13
|
-
assert.equal(resolveNpmPackageName("land"), "@sfmc-bds/module-land");
|
|
14
|
-
assert.equal(resolveNpmPackageName("my-mod"), "@sfmc-bds/module-my-mod");
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
test("logical id (feature-* / core-*) → @sfmc-bds/module-<folder>", () => {
|
|
18
|
-
assert.equal(resolveNpmPackageName("feature-land"), "@sfmc-bds/module-land");
|
|
19
|
-
assert.equal(resolveNpmPackageName("core-data-backup"), "@sfmc-bds/module-data-backup");
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
test("已带 scope 原样透传", () => {
|
|
23
|
-
assert.equal(resolveNpmPackageName("@alice/sfmc-module-foo"), "@alice/sfmc-module-foo");
|
|
24
|
-
assert.equal(resolveNpmPackageName("@sfmc-bds/module-land"), "@sfmc-bds/module-land");
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
test("非 kebab 报错", () => {
|
|
28
|
-
assert.throws(() => resolveNpmPackageName("NotKebab"), /invalid module id/);
|
|
29
|
-
assert.throws(() => resolveNpmPackageName("feature-"), /invalid module id/);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
test("@ 但无 / → invalid scoped package name", () => {
|
|
33
|
-
assert.throws(() => resolveNpmPackageName("@orphan"), /invalid scoped package name/);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
test("folderFromNpmPackageName 反向解析", () => {
|
|
37
|
-
assert.equal(folderFromNpmPackageName("@sfmc-bds/module-land"), "land");
|
|
38
|
-
assert.equal(folderFromNpmPackageName("@alice/sfmc-module-foo"), "foo");
|
|
39
|
-
assert.equal(folderFromNpmPackageName("@alice/sfmc-module-my-mod"), "my-mod");
|
|
40
|
-
assert.equal(folderFromNpmPackageName("@alice/random"), null);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
test("normalizeNpmPackageName 兼容两种前缀", () => {
|
|
44
|
-
assert.equal(normalizeNpmPackageName("@sfmc-bds/module-land"), "land");
|
|
45
|
-
assert.equal(normalizeNpmPackageName("@alice/sfmc-module-foo"), "foo");
|
|
46
|
-
assert.equal(normalizeNpmPackageName("@alice/module-bar"), "bar");
|
|
47
|
-
});
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* link-local normalizeLinkFrom 表驱动
|
|
3
|
-
*/
|
|
4
|
-
import assert from "node:assert/strict";
|
|
5
|
-
import fs from "node:fs";
|
|
6
|
-
import os from "node:os";
|
|
7
|
-
import path from "node:path";
|
|
8
|
-
import test from "node:test";
|
|
9
|
-
import { normalizeLinkFrom } from "../lib/link-from.mjs";
|
|
10
|
-
|
|
11
|
-
const CWD = process.cwd();
|
|
12
|
-
|
|
13
|
-
test("local 无路径 → dir:cwd", () => {
|
|
14
|
-
const r = normalizeLinkFrom("local", CWD);
|
|
15
|
-
assert.equal(r.ok, true);
|
|
16
|
-
if (r.ok) assert.equal(r.from, `dir:${path.resolve(CWD)}`);
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
test("local:相对目录 → dir:绝对路径", () => {
|
|
20
|
-
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "sfmc-link-rel-"));
|
|
21
|
-
const rel = path.relative(CWD, tmp) || ".";
|
|
22
|
-
const r = normalizeLinkFrom(`local:${rel}`, CWD);
|
|
23
|
-
assert.equal(r.ok, true);
|
|
24
|
-
if (r.ok) assert.equal(r.from, `dir:${path.resolve(CWD, rel)}`);
|
|
25
|
-
fs.rmSync(tmp, { recursive: true, force: true });
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
test("local:file.tgz + link → 拒绝", () => {
|
|
29
|
-
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "sfmc-link-"));
|
|
30
|
-
const tgz = path.join(tmp, "x.tgz");
|
|
31
|
-
fs.writeFileSync(tgz, "");
|
|
32
|
-
const r = normalizeLinkFrom(`local:${tgz}`, CWD);
|
|
33
|
-
assert.equal(r.ok, false);
|
|
34
|
-
if (!r.ok) assert.match(r.error, /tgz|zip|--link/i);
|
|
35
|
-
fs.rmSync(tmp, { recursive: true, force: true });
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
test("dir: 原样通过", () => {
|
|
39
|
-
const r = normalizeLinkFrom("dir:D:/mods/foo", CWD);
|
|
40
|
-
assert.equal(r.ok, true);
|
|
41
|
-
if (r.ok) assert.equal(r.from, "dir:D:/mods/foo");
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
test("裸路径目录 → dir:绝对路径", () => {
|
|
45
|
-
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "sfmc-link-bare-"));
|
|
46
|
-
const r = normalizeLinkFrom(tmp, CWD);
|
|
47
|
-
assert.equal(r.ok, true);
|
|
48
|
-
if (r.ok) assert.equal(r.from, `dir:${path.resolve(tmp)}`);
|
|
49
|
-
fs.rmSync(tmp, { recursive: true, force: true });
|
|
50
|
-
});
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* local-resolver `--from local` 路径解析表驱动
|
|
3
|
-
*/
|
|
4
|
-
import assert from "node:assert/strict";
|
|
5
|
-
import path from "node:path";
|
|
6
|
-
import process from "node:process";
|
|
7
|
-
import test from "node:test";
|
|
8
|
-
|
|
9
|
-
/** 镜像 fetch-module.mjs#resolveLocalPath */
|
|
10
|
-
function resolveLocalPath(tail: string | undefined): string {
|
|
11
|
-
const p = String(tail ?? "").trim();
|
|
12
|
-
if (!p || p === "." || p === "./") return path.resolve(process.cwd());
|
|
13
|
-
return path.isAbsolute(p) ? path.resolve(p) : path.resolve(process.cwd(), p);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const CWD = process.cwd();
|
|
17
|
-
|
|
18
|
-
test("空 → cwd", () => assert.equal(resolveLocalPath(""), path.resolve(CWD)));
|
|
19
|
-
test("undefined → cwd", () => assert.equal(resolveLocalPath(undefined), path.resolve(CWD)));
|
|
20
|
-
test(". → cwd", () => assert.equal(resolveLocalPath("."), path.resolve(CWD)));
|
|
21
|
-
test("./ → cwd", () => assert.equal(resolveLocalPath("./"), path.resolve(CWD)));
|
|
22
|
-
|
|
23
|
-
test("相对 ./foo → 相对 cwd 解析", () => {
|
|
24
|
-
assert.equal(resolveLocalPath("./foo"), path.resolve(CWD, "foo"));
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
test("相对无点 foo", () => {
|
|
28
|
-
assert.equal(resolveLocalPath("foo"), path.resolve(CWD, "foo"));
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
test("绝对路径原样", () => {
|
|
32
|
-
const abs = process.platform === "win32" ? "D:\\work\\my-mod" : "/tmp/my-mod";
|
|
33
|
-
assert.equal(resolveLocalPath(abs), path.resolve(abs));
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
test("绝对路径 .tgz", () => {
|
|
37
|
-
const abs = process.platform === "win32" ? "D:\\work\\foo-1.0.0.tgz" : "/tmp/foo-1.0.0.tgz";
|
|
38
|
-
assert.equal(resolveLocalPath(abs), path.resolve(abs));
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
test("绝对路径 .zip", () => {
|
|
42
|
-
const abs = process.platform === "win32" ? "D:\\work\\foo.zip" : "/tmp/foo.zip";
|
|
43
|
-
assert.equal(resolveLocalPath(abs), path.resolve(abs));
|
|
44
|
-
});
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import test from "node:test";
|
|
3
|
-
import { parseRegistryIndex } from "../lib/registry-index.mjs";
|
|
4
|
-
|
|
5
|
-
test("接受 npm 条目", () => {
|
|
6
|
-
const idx = parseRegistryIndex({
|
|
7
|
-
version: 2,
|
|
8
|
-
modules: {
|
|
9
|
-
land: { npm: "@sfmc-bds/module-land", version: "1.0.0", sdk: ">=0.2.0" },
|
|
10
|
-
},
|
|
11
|
-
});
|
|
12
|
-
assert.equal(idx.land?.npm, "@sfmc-bds/module-land");
|
|
13
|
-
assert.equal(idx.land?.version, "1.0.0");
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
test("仍接受 repo+tag", () => {
|
|
17
|
-
const idx = parseRegistryIndex({
|
|
18
|
-
modules: { afk: { repo: "Tanya7z/sfmc-modules", tag: "modules-v0.4.0" } },
|
|
19
|
-
});
|
|
20
|
-
assert.equal(idx.afk?.repo, "Tanya7z/sfmc-modules");
|
|
21
|
-
assert.equal(idx.afk?.tag, "modules-v0.4.0");
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
test("既无 npm 也无 repo 则跳过", () => {
|
|
25
|
-
const idx = parseRegistryIndex({ modules: { bad: { version: "1" } } });
|
|
26
|
-
assert.equal(idx.bad, undefined);
|
|
27
|
-
});
|