@sfmc-bds/bds-tools 0.2.0-beta.0 → 0.2.0-beta.10
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/LICENSE +663 -0
- package/dist/bds-manager.d.ts +16 -6
- package/dist/bds-manager.d.ts.map +1 -1
- package/dist/bds-manager.js +40 -65
- package/dist/bds-manager.js.map +2 -2
- package/dist/check-update.d.ts.map +1 -1
- package/dist/check-update.js +15 -17
- package/dist/check-update.js.map +2 -2
- package/dist/cli-pack-manager.js +7 -3
- package/dist/cli-pack-manager.js.map +2 -2
- package/dist/fsx.d.ts +6 -1
- package/dist/fsx.d.ts.map +1 -1
- package/dist/fsx.js +9 -1
- package/dist/fsx.js.map +2 -2
- package/dist/host-platform.d.ts +25 -0
- package/dist/host-platform.d.ts.map +1 -0
- package/dist/host-platform.js +50 -0
- package/dist/host-platform.js.map +7 -0
- package/dist/http.d.ts +49 -11
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js.map +2 -2
- package/dist/log.d.ts +2 -3
- package/dist/log.d.ts.map +1 -1
- package/dist/log.js +0 -1
- package/dist/log.js.map +2 -2
- package/dist/pack-manager-lifecycle.test.js +252 -0
- package/dist/pack-manager-lifecycle.test.js.map +7 -0
- package/dist/pack-manager.d.ts +24 -29
- package/dist/pack-manager.d.ts.map +1 -1
- package/dist/pack-manager.js +11 -4
- package/dist/pack-manager.js.map +2 -2
- package/dist/pack-update/bindings.d.ts +16 -0
- package/dist/pack-update/bindings.d.ts.map +1 -0
- package/dist/pack-update/bindings.js +69 -0
- package/dist/pack-update/bindings.js.map +7 -0
- package/dist/pack-update/config.d.ts +16 -0
- package/dist/pack-update/config.d.ts.map +1 -0
- package/dist/pack-update/config.js +146 -0
- package/dist/pack-update/config.js.map +7 -0
- package/dist/pack-update/config.test.js +75 -0
- package/dist/pack-update/config.test.js.map +7 -0
- package/dist/pack-update/deps.d.ts +28 -0
- package/dist/pack-update/deps.d.ts.map +1 -0
- package/dist/pack-update/deps.js +20 -0
- package/dist/pack-update/deps.js.map +7 -0
- package/dist/pack-update/index.d.ts +55 -0
- package/dist/pack-update/index.d.ts.map +1 -0
- package/dist/pack-update/index.js +72 -0
- package/dist/pack-update/index.js.map +7 -0
- package/dist/pack-update/providers/curseforge.d.ts +23 -0
- package/dist/pack-update/providers/curseforge.d.ts.map +1 -0
- package/dist/pack-update/providers/curseforge.js +229 -0
- package/dist/pack-update/providers/curseforge.js.map +7 -0
- package/dist/pack-update/providers/index.d.ts +16 -0
- package/dist/pack-update/providers/index.d.ts.map +1 -0
- package/dist/pack-update/providers/index.js +37 -0
- package/dist/pack-update/providers/index.js.map +7 -0
- package/dist/pack-update/service.d.ts +28 -0
- package/dist/pack-update/service.d.ts.map +1 -0
- package/dist/pack-update/service.js +570 -0
- package/dist/pack-update/service.js.map +7 -0
- package/dist/pack-update/types.d.ts +126 -0
- package/dist/pack-update/types.d.ts.map +1 -0
- package/dist/pack-update/types.js +8 -0
- package/dist/pack-update/types.js.map +7 -0
- package/dist/pack-update/version-policy.d.ts +81 -0
- package/dist/pack-update/version-policy.d.ts.map +1 -0
- package/dist/pack-update/version-policy.js +210 -0
- package/dist/pack-update/version-policy.js.map +7 -0
- package/dist/pack-update/version-policy.test.js +137 -0
- package/dist/pack-update/version-policy.test.js.map +7 -0
- package/dist/paths.d.ts +1 -1
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +3 -5
- package/dist/paths.js.map +2 -2
- package/dist/process-probe.d.ts +34 -0
- package/dist/process-probe.d.ts.map +1 -0
- package/dist/process-probe.js +152 -0
- package/dist/process-probe.js.map +7 -0
- package/dist/process-probe.test.js +76 -0
- package/dist/process-probe.test.js.map +7 -0
- package/dist/qq-events-notify.d.ts +16 -0
- package/dist/qq-events-notify.d.ts.map +1 -0
- package/dist/qq-events-notify.js +70 -0
- package/dist/qq-events-notify.js.map +7 -0
- package/dist/qqutil.d.ts +10 -5
- package/dist/qqutil.d.ts.map +1 -1
- package/dist/qqutil.js +49 -8
- package/dist/qqutil.js.map +2 -2
- package/dist/update-result.d.ts +8 -2
- package/dist/update-result.d.ts.map +1 -1
- package/dist/update-result.js +7 -5
- package/dist/update-result.js.map +2 -2
- package/dist/upstream.d.ts +18 -9
- package/dist/upstream.d.ts.map +1 -1
- package/dist/upstream.js +8 -7
- package/dist/upstream.js.map +2 -2
- package/dist/version.js +2 -2
- package/dist/version.js.map +2 -2
- package/dist/world-packs.d.ts +158 -5
- package/dist/world-packs.d.ts.map +1 -1
- package/dist/world-packs.js +294 -48
- package/dist/world-packs.js.map +2 -2
- package/dist/world-packs.test.js +676 -0
- package/dist/world-packs.test.js.map +7 -0
- package/dist/zipx.test.js +36 -0
- package/dist/zipx.test.js.map +7 -0
- package/package.json +43 -39
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/world-packs.test.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * world-packs \u539F\u8BED\u5355\u6D4B\uFF1Aformat / bump / discover / list-installed\n */\nimport assert from \"node:assert/strict\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { after, before, describe, it } from \"node:test\";\nimport { fileURLToPath } from \"node:url\";\nimport { spawnSync } from \"node:child_process\";\n\nconst CLI = path.join(path.dirname(fileURLToPath(import.meta.url)), \"..\", \"dist\", \"cli-pack-manager.js\");\n\nfunction run(args) {\n const r = spawnSync(process.execPath, [CLI, ...args], { encoding: \"utf8\" });\n return { status: r.status, out: r.stdout ?? \"\", err: r.stderr ?? \"\" };\n}\n\nfunction writeManifest(dir, { name, uuid, version, type }) {\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(\n path.join(dir, \"manifest.json\"),\n JSON.stringify(\n {\n format_version: 2,\n header: { name, uuid, version, description: \"test\" },\n modules: [{ type, uuid: cryptoRandom(), version }],\n },\n null,\n 2\n )\n );\n}\n\nfunction cryptoRandom() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\ndescribe(\"world-packs primitives\", () => {\n /** @type {string} */\n let tmp;\n before(() => {\n tmp = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-wp-\"));\n });\n after(() => {\n fs.rmSync(tmp, { recursive: true, force: true });\n });\n\n it(\"formatWorldPackFolderName \u53BB\u683C\u5F0F\u7801/\u540E\u7F00\u5E76\u52A0\u524D\u7F00\", async () => {\n const { formatWorldPackFolderName, isGenericPackFolderStem } = await import(\"./world-packs.js\");\n assert.equal(formatWorldPackFolderName(\"\u00A7aCool\u00A7l Textures.mcpack\", \"resource\"), \"[RP] Cool Textures\");\n assert.equal(formatWorldPackFolderName(\"My BP.zip\", \"behavior\"), \"[BP] My BP\");\n assert.equal(formatWorldPackFolderName(\"[RP] Already\", \"resource\"), \"[RP] Already\");\n assert.equal(isGenericPackFolderStem(\"B\"), true);\n assert.equal(isGenericPackFolderStem(\"[RP] R\"), true);\n assert.equal(isGenericPackFolderStem(\"Slash Blade\"), false);\n });\n\n it(\"discoverPackRoots maxDepth=2\", async () => {\n const { discoverPackRoots } = await import(\"./world-packs.js\");\n const root = path.join(tmp, \"discover\");\n const nested = path.join(root, \"outer\", \"inner-pack\");\n writeManifest(nested, {\n name: \"Inner\",\n uuid: \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n version: [1, 0, 0],\n type: \"resources\",\n });\n const found = discoverPackRoots(root, { maxDepth: 2 });\n assert.ok(found.some((p) => path.resolve(p) === path.resolve(nested)));\n });\n\n it(\"resolvePackRoots\uFF1A\u6241\u5E73\u76EE\u5F55 / \u5B50\u76EE\u5F55 BP+RP\", async () => {\n const { resolvePackRoots, readPackManifestInfo } = await import(\"./world-packs.js\");\n const flat = path.join(tmp, \"flat-pack\");\n writeManifest(flat, {\n name: \"FlatBP\",\n uuid: \"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb\",\n version: [1, 0, 0],\n type: \"data\",\n });\n const flatRes = await resolvePackRoots(flat);\n try {\n assert.equal(flatRes.roots.length, 1);\n assert.equal(readPackManifestInfo(flatRes.roots[0])?.name, \"FlatBP\");\n } finally {\n flatRes.dispose();\n }\n\n const nest = path.join(tmp, \"nest-dir\");\n writeManifest(path.join(nest, \"BP\"), {\n name: \"NestBP\",\n uuid: \"cccccccc-cccc-cccc-cccc-cccccccccccc\",\n version: [1, 0, 0],\n type: \"data\",\n });\n writeManifest(path.join(nest, \"RP\"), {\n name: \"NestRP\",\n uuid: \"dddddddd-dddd-dddd-dddd-dddddddddddd\",\n version: [1, 0, 0],\n type: \"resources\",\n });\n const nestRes = await resolvePackRoots(nest);\n try {\n assert.equal(nestRes.roots.length, 2);\n const kinds = nestRes.roots.map((r) => readPackManifestInfo(r)?.kind).sort();\n assert.deepEqual(kinds, [\"behavior\", \"resource\"]);\n } finally {\n nestRes.dispose();\n }\n });\n\n it(\"resolvePackRoots\uFF1Amcaddon \u5185\u5D4C mcpack + zip \u5957\u5A03\", async () => {\n const JSZip = (await import(\"jszip\")).default;\n const { resolvePackRoots, readPackManifestInfo } = await import(\"./world-packs.js\");\n\n async function zipDirAsArchive(entries, outFile) {\n const zip = new JSZip();\n for (const [name, content] of entries) {\n zip.file(name, content);\n }\n const buf = await zip.generateAsync({ type: \"nodebuffer\" });\n fs.mkdirSync(path.dirname(outFile), { recursive: true });\n fs.writeFileSync(outFile, buf);\n }\n\n function manifestJson({ name, uuid, version, type }) {\n return JSON.stringify({\n format_version: 2,\n header: { name, uuid, version, description: \"test\" },\n modules: [{ type, uuid: cryptoRandom(), version }],\n });\n }\n\n /* \u5185\u5C42 RP \u4F5C\u4E3A .mcpack */\n const rpMcpack = path.join(tmp, \"nested-build\", \"inner-rp.mcpack\");\n await zipDirAsArchive(\n [\n [\n \"manifest.json\",\n manifestJson({\n name: \"InnerRP\",\n uuid: \"eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee\",\n version: [1, 0, 0],\n type: \"resources\",\n }),\n ],\n ],\n rpMcpack\n );\n\n /* \u5916\u5C42 .mcaddon\uFF1A\u6587\u4EF6\u5939 BP + \u5D4C\u5957 .mcpack */\n const bpManifest = manifestJson({\n name: \"OuterBP\",\n uuid: \"ffffffff-ffff-ffff-ffff-ffffffffffff\",\n version: [1, 0, 0],\n type: \"data\",\n });\n const addon = path.join(tmp, \"nested-build\", \"bundle.mcaddon\");\n const zip = new JSZip();\n zip.file(\"BP/manifest.json\", bpManifest);\n zip.file(\"inner-rp.mcpack\", fs.readFileSync(rpMcpack));\n fs.writeFileSync(addon, await zip.generateAsync({ type: \"nodebuffer\" }));\n\n const addonRes = await resolvePackRoots(addon);\n try {\n assert.equal(addonRes.roots.length, 2, `roots=${JSON.stringify(addonRes.roots)}`);\n const names = addonRes.roots.map((r) => readPackManifestInfo(r)?.name).sort();\n assert.deepEqual(names, [\"InnerRP\", \"OuterBP\"]);\n } finally {\n addonRes.dispose();\n }\n\n /* zip \u2192 mcpack \u2192 pack\uFF08\u53CC\u5C42\u5957\u5A03\uFF09 */\n const leafMcpack = path.join(tmp, \"nested-build\", \"leaf.mcpack\");\n await zipDirAsArchive(\n [\n [\n \"manifest.json\",\n manifestJson({\n name: \"LeafPack\",\n uuid: \"12121212-1212-1212-1212-121212121212\",\n version: [2, 0, 0],\n type: \"data\",\n }),\n ],\n ],\n leafMcpack\n );\n const outerZip = path.join(tmp, \"nested-build\", \"outer.zip\");\n const z2 = new JSZip();\n z2.file(\"leaf.mcpack\", fs.readFileSync(leafMcpack));\n fs.writeFileSync(outerZip, await z2.generateAsync({ type: \"nodebuffer\" }));\n\n const zipRes = await resolvePackRoots(outerZip);\n try {\n assert.equal(zipRes.roots.length, 1);\n assert.equal(readPackManifestInfo(zipRes.roots[0])?.name, \"LeafPack\");\n } finally {\n zipRes.dispose();\n }\n });\n\n it(\"bumpPackPatchVersion \u540C\u6B65 header \u4E0E modules\", async () => {\n const { bumpPackPatchVersion, readPackManifestInfo } = await import(\"./world-packs.js\");\n const dir = path.join(tmp, \"bump-rp\");\n writeManifest(dir, {\n name: \"BumpMe\",\n uuid: \"11111111-2222-3333-4444-555555555555\",\n version: [1, 2, 3],\n type: \"resources\",\n });\n const next = bumpPackPatchVersion(dir);\n assert.deepEqual(next, [1, 2, 4]);\n const info = readPackManifestInfo(dir);\n assert.deepEqual(info?.version, [1, 2, 4]);\n const raw = JSON.parse(fs.readFileSync(path.join(dir, \"manifest.json\"), \"utf8\"));\n assert.deepEqual(raw.modules[0].version, [1, 2, 4]);\n });\n\n it(\"ensureVersionGreaterThan / nextEnabledVersion\uFF1Abump(max(\u65B0\u5305, \u65E7\u7248))\", async () => {\n const { ensureVersionGreaterThan, nextEnabledVersion, readPackManifestInfo } = await import(\n \"./world-packs.js\"\n );\n assert.deepEqual(nextEnabledVersion([1, 0, 0], [1, 21, 100], \"patch\"), [1, 21, 101]);\n /* \u590D\u73B0\uFF1A\u65E7 Slash Blade RP=[1,21,100]\uFF0C\u8FDC\u7A0B\u65B0\u5305=[1,0,0] */\n const dir = path.join(tmp, \"bump-floor\");\n writeManifest(dir, {\n name: \"SlashRp\",\n uuid: \"8b450660-c968-3d5e-696e-b7f14c03388a\",\n version: [1, 0, 0],\n type: \"resources\",\n });\n const next = ensureVersionGreaterThan(dir, [1, 21, 100], \"patch\");\n assert.deepEqual(next, [1, 21, 101]);\n assert.deepEqual(readPackManifestInfo(dir)?.version, [1, 21, 101]);\n });\n\n it(\"list-installed CLI + listInstalledWorldPacks\", async () => {\n const { listInstalledWorldPacks } = await import(\"./world-packs.js\");\n const bds = path.join(tmp, \"bds\");\n const level = \"Bedrock level\";\n const rpDir = path.join(bds, \"worlds\", level, \"resource_packs\", \"[RP] Tex\");\n writeManifest(rpDir, {\n name: \"Tex\",\n uuid: \"99999999-8888-7777-6666-555555555555\",\n version: [0, 1, 0],\n type: \"resources\",\n });\n fs.mkdirSync(path.join(bds, \"worlds\", level), { recursive: true });\n fs.writeFileSync(\n path.join(bds, \"worlds\", level, \"world_resource_packs.json\"),\n JSON.stringify([{ pack_id: \"99999999-8888-7777-6666-555555555555\", version: [0, 1, 0] }])\n );\n\n const list = listInstalledWorldPacks(bds, level);\n assert.equal(list.length, 1);\n assert.equal(list[0].enabled, true);\n assert.equal(list[0].kind, \"resource\");\n\n const cli = run([\"list-installed\", \"--bds-root\", bds, \"--level\", level]);\n assert.equal(cli.status, 0, cli.err || cli.out);\n const parsed = JSON.parse(cli.out.trim());\n assert.equal(parsed.length, 1);\n });\n\n it(\"bump-version CLI\", async () => {\n const dir = path.join(tmp, \"cli-bump\");\n writeManifest(dir, {\n name: \"CliBump\",\n uuid: \"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa\",\n version: [2, 0, 0],\n type: \"resources\",\n });\n const cli = run([\"bump-version\", \"--pack-dir\", dir]);\n assert.equal(cli.status, 0, cli.err || cli.out);\n const { version } = JSON.parse(cli.out.trim());\n assert.deepEqual(version, [2, 0, 1]);\n });\n\n it(\"scanDestOccupancy / readPackDirOccupancy\uFF1A\u5B8C\u6574\u4E0E\u6B8B\u7F3A manifest\", async () => {\n const { scanDestOccupancy, readPackDirOccupancy, formatWorldPackFolderName } = await import(\n \"./world-packs.js\"\n );\n const parent = path.join(tmp, \"occupancy-scan\");\n const fullName = formatWorldPackFolderName(\"Full\", \"resource\");\n const brokenName = formatWorldPackFolderName(\"Broken\", \"behavior\");\n const fullDir = path.join(parent, fullName);\n const brokenDir = path.join(parent, brokenName);\n writeManifest(fullDir, {\n name: \"Full Pack\",\n uuid: \"11111111-1111-1111-1111-111111111111\",\n version: [2, 3, 4],\n type: \"resources\",\n });\n fs.mkdirSync(brokenDir, { recursive: true });\n fs.writeFileSync(\n path.join(brokenDir, \"manifest.json\"),\n JSON.stringify({\n format_version: 2,\n header: {\n name: \"Broken Pack\",\n uuid: \"22222222-2222-2222-2222-222222222222\",\n version: [9, 0, 1],\n },\n modules: [],\n })\n );\n\n const fullFacts = readPackDirOccupancy(fullDir);\n assert.equal(fullFacts?.uuid, \"11111111-1111-1111-1111-111111111111\");\n assert.deepEqual(fullFacts?.version, [2, 3, 4]);\n assert.equal(fullFacts?.kind, \"resource\");\n\n const brokenFacts = readPackDirOccupancy(brokenDir);\n assert.equal(brokenFacts?.uuid, \"22222222-2222-2222-2222-222222222222\");\n assert.deepEqual(brokenFacts?.version, [9, 0, 1]);\n assert.equal(brokenFacts?.kind, undefined);\n\n const occ = scanDestOccupancy(parent);\n assert.equal(occ.length, 2);\n const byFolder = Object.fromEntries(occ.map((o) => [o.folderName, o]));\n assert.equal(byFolder[fullName]?.uuid, \"11111111-1111-1111-1111-111111111111\");\n assert.equal(byFolder[fullName]?.kind, \"resource\");\n assert.equal(byFolder[brokenName]?.uuid, \"22222222-2222-2222-2222-222222222222\");\n assert.equal(byFolder[brokenName]?.kind, undefined);\n });\n\n it(\"decidePackInstallPlan \u8868\u9A71\u52A8\", async () => {\n const { decidePackInstallPlan, formatWorldPackFolderName } = await import(\"./world-packs.js\");\n const uuidA = \"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa\";\n const uuidB = \"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb\";\n const mk = (over) => ({\n name: \"Foo\",\n uuid: uuidB,\n version: [1, 0, 0],\n kind: \"behavior\",\n ...over,\n });\n\n const cases = [\n {\n title: \"\u7A7A\u5360\u7528 + hint B \u2192 fresh \u7528 manifest \u540D\",\n incoming: mk({ name: \"Foo\", uuid: uuidB }),\n hint: \"B\",\n occupancy: [],\n force: false,\n expectKind: \"fresh\",\n expectFolder: \"[BP] Foo\",\n },\n {\n title: \"\u5DF2\u6709 [BP] B uuidA + \u65B0 uuidB hint B \u2192 fresh \u4E14\u4E0D\u5360\u7528 B\",\n incoming: mk({ name: \"pack.name\", uuid: uuidB, version: [5, 0, 4] }),\n hint: \"B\",\n occupancy: [\n {\n folderName: \"[BP] B\",\n dir: \"/x/[BP] B\",\n uuid: uuidA,\n version: [1, 0, 0],\n name: \"Slash\",\n },\n ],\n force: false,\n expectKind: \"fresh\",\n expectFolderNot: \"[BP] B\",\n },\n {\n title: \"\u540C uuid \u7248\u672C\u66F4\u9AD8 !force \u2192 overwriteInPlace\",\n incoming: mk({ name: \"Slash v2\", uuid: uuidA, version: [1, 2, 0] }),\n hint: \"Other\",\n occupancy: [\n {\n folderName: \"[BP] B\",\n dir: \"/x/[BP] B\",\n uuid: uuidA,\n version: [1, 1, 0],\n name: \"Slash\",\n },\n ],\n force: false,\n expectKind: \"overwriteInPlace\",\n expectFolder: \"[BP] B\",\n },\n {\n title: \"\u540C uuid \u7248\u672C\u76F8\u7B49 !force \u2192 needConfirm\",\n incoming: mk({ name: \"Slash\", uuid: uuidA, version: [1, 1, 0] }),\n hint: \"Other\",\n occupancy: [\n {\n folderName: \"[BP] B\",\n dir: \"/x/[BP] B\",\n uuid: uuidA,\n version: [1, 1, 0],\n name: \"Slash\",\n },\n ],\n force: false,\n expectKind: \"needConfirm\",\n expectFolder: \"[BP] B\",\n },\n {\n title: \"\u540C uuid \u7248\u672C\u66F4\u4F4E !force \u2192 needConfirm\",\n incoming: mk({ name: \"Slash\", uuid: uuidA, version: [1, 0, 0] }),\n hint: \"Other\",\n occupancy: [\n {\n folderName: \"[BP] B\",\n dir: \"/x/[BP] B\",\n uuid: uuidA,\n version: [1, 1, 0],\n name: \"Slash\",\n },\n ],\n force: false,\n expectKind: \"needConfirm\",\n expectFolder: \"[BP] B\",\n },\n {\n title: \"\u540C uuid \u964D\u7EA7 + force \u2192 overwriteInPlace\",\n incoming: mk({ name: \"Slash old\", uuid: uuidA, version: [1, 0, 0] }),\n hint: \"Other\",\n occupancy: [\n {\n folderName: \"[BP] B\",\n dir: \"/x/[BP] B\",\n uuid: uuidA,\n version: [1, 1, 0],\n name: \"Slash\",\n },\n ],\n force: true,\n expectKind: \"overwriteInPlace\",\n expectFolder: \"[BP] B\",\n },\n {\n title: \"\u4E24\u4EBA\u540D\u649E\u8F66 \u2192 fresh \u5E26 uuid \u540E\u7F00\",\n incoming: mk({ name: \"Cool\", uuid: uuidB, version: [1, 0, 0] }),\n hint: \"Cool\",\n occupancy: [\n {\n folderName: formatWorldPackFolderName(\"Cool\", \"behavior\"),\n dir: \"/x/a\",\n uuid: uuidA,\n version: [1, 0, 0],\n },\n ],\n force: false,\n expectKind: \"fresh\",\n expectFolder: formatWorldPackFolderName(`Cool ${uuidB.slice(0, 8)}`, \"behavior\"),\n },\n ];\n\n for (const c of cases) {\n const plan = decidePackInstallPlan({\n incoming: c.incoming,\n hint: c.hint,\n occupancy: c.occupancy,\n force: c.force,\n });\n assert.equal(plan.kind, c.expectKind, c.title);\n if (c.expectFolder) assert.equal(plan.folderName, c.expectFolder, c.title);\n if (c.expectFolderNot) assert.notEqual(plan.folderName, c.expectFolderNot, c.title);\n if (plan.kind === \"overwriteInPlace\" || plan.kind === \"needConfirm\") {\n assert.equal(plan.folderName, c.occupancy[0].folderName, `${c.title}: \u5FC5\u987B\u539F\u5730`);\n }\n }\n });\n\n it(\"installPackDirectory FS\uFF1A\u5F02 uuid \u6362\u540D\uFF1B\u7248\u672C\u5347\u7EA7\u9759\u9ED8\u8986\u76D6\uFF1B\u540C\u7248\u9700 force\", async () => {\n const { installPackDirectory, formatWorldPackFolderName, readPackManifestInfo } = await import(\n \"./world-packs.js\"\n );\n const dest = path.join(tmp, \"conflict-parent\");\n\n const existingB = path.join(dest, formatWorldPackFolderName(\"B\", \"behavior\"));\n writeManifest(existingB, {\n name: \"Slash Blade\",\n uuid: \"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa\",\n version: [1, 0, 0],\n type: \"data\",\n });\n\n /* \u5F02 uuid + hint B \u2192 \u6362\u540D\uFF0C\u4E0D\u78B0\u65E7\u5305 */\n const src = path.join(tmp, \"incoming-bp\");\n writeManifest(src, {\n name: \"pack.name\",\n uuid: \"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb\",\n version: [5, 0, 4],\n type: \"data\",\n });\n const r = await installPackDirectory({\n srcDir: src,\n destParent: dest,\n folderName: \"B\",\n force: false,\n });\n assert.equal(r.ok, true, r.reason);\n assert.notEqual(path.basename(r.destDir), path.basename(existingB));\n assert.equal(readPackManifestInfo(existingB)?.uuid, \"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa\");\n\n /* \u540C uuid \u7248\u672C\u66F4\u9AD8 \u2192 \u9759\u9ED8\u539F\u5730\u8986\u76D6\uFF08\u65E0\u9700 force\uFF09 */\n const srcUp = path.join(tmp, \"incoming-upgrade\");\n writeManifest(srcUp, {\n name: \"Slash Blade v2\",\n uuid: \"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa\",\n version: [2, 0, 0],\n type: \"data\",\n });\n const up = await installPackDirectory({\n srcDir: srcUp,\n destParent: dest,\n folderName: \"Totally Different Hint\",\n force: false,\n });\n assert.equal(up.ok, true, up.reason);\n assert.equal(up.conflict, undefined);\n assert.equal(up.destDir && path.basename(up.destDir), path.basename(existingB));\n assert.equal(readPackManifestInfo(existingB)?.version.join(\".\"), \"2.0.0\");\n assert.equal(fs.readdirSync(dest).filter((n) => n.startsWith(\"[BP]\")).length, 2);\n\n /* \u540C\u7248 \u2192 needConfirm\uFF1Bforce \u540E\u539F\u5730 */\n const srcSame = path.join(tmp, \"incoming-same-ver\");\n writeManifest(srcSame, {\n name: \"Slash Blade v2b\",\n uuid: \"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa\",\n version: [2, 0, 0],\n type: \"data\",\n });\n const c = await installPackDirectory({\n srcDir: srcSame,\n destParent: dest,\n force: false,\n });\n assert.equal(c.ok, false);\n assert.equal(c.reason, \"conflict\");\n\n const forced = await installPackDirectory({\n srcDir: srcSame,\n destParent: dest,\n force: true,\n });\n assert.equal(forced.ok, true, forced.reason);\n assert.equal(forced.destDir && path.basename(forced.destDir), path.basename(existingB));\n assert.equal(readPackManifestInfo(existingB)?.name, \"Slash Blade v2b\");\n });\n\n it(\"installPackDirectory\uFF1A\u6B8B\u7F3A manifest \u5360\u7528\u76EE\u5F55\u65F6\u6362\u540D\u800C\u975E\u8986\u76D6\", async () => {\n const { installPackDirectory, formatWorldPackFolderName } = await import(\"./world-packs.js\");\n const dest = path.join(tmp, \"broken-parent\");\n const folderName = formatWorldPackFolderName(\"Broken\", \"resource\");\n const existingDir = path.join(dest, folderName);\n fs.mkdirSync(existingDir, { recursive: true });\n fs.writeFileSync(\n path.join(existingDir, \"manifest.json\"),\n JSON.stringify({\n format_version: 2,\n header: {\n name: \"Broken\",\n uuid: \"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb\",\n version: [1, 0, 0],\n },\n modules: [],\n })\n );\n const src = path.join(tmp, \"incoming-rp\");\n writeManifest(src, {\n name: \"Incoming\",\n uuid: \"cccccccc-cccc-cccc-cccc-cccccccccccc\",\n version: [1, 0, 0],\n type: \"resources\",\n });\n const r = await installPackDirectory({\n srcDir: src,\n destParent: dest,\n folderName: \"Broken\",\n force: false,\n });\n assert.equal(r.ok, true, r.reason);\n assert.notEqual(r.destDir && path.basename(r.destDir), folderName);\n const still = JSON.parse(fs.readFileSync(path.join(existingDir, \"manifest.json\"), \"utf8\"));\n assert.equal(still.header.uuid, \"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb\");\n });\n\n it(\"installPackDirectory\uFF1A\u6B8B\u7F3A manifest \u540C uuid \u2192 \u6309\u7248\u672C\u51B3\u7B56\uFF08\u975E\u65C1\u8DEF\u65B0\u76EE\u5F55\uFF09\", async () => {\n const { installPackDirectory, formatWorldPackFolderName, readPackManifestInfo } = await import(\n \"./world-packs.js\"\n );\n const dest = path.join(tmp, \"broken-same-uuid\");\n const folderName = formatWorldPackFolderName(\"Legacy\", \"behavior\");\n const existingDir = path.join(dest, folderName);\n fs.mkdirSync(existingDir, { recursive: true });\n const uuid = \"eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee\";\n fs.writeFileSync(\n path.join(existingDir, \"manifest.json\"),\n JSON.stringify({\n format_version: 2,\n header: { name: \"Legacy\", uuid, version: [1, 0, 0] },\n modules: [],\n })\n );\n const srcSame = path.join(tmp, \"incoming-same-broken\");\n writeManifest(srcSame, {\n name: \"Fixed\",\n uuid,\n version: [1, 0, 0],\n type: \"data\",\n });\n const c = await installPackDirectory({\n srcDir: srcSame,\n destParent: dest,\n folderName: \"OtherHint\",\n force: false,\n });\n assert.equal(c.ok, false);\n assert.equal(c.reason, \"conflict\");\n assert.equal(c.conflict?.existing.dir, existingDir);\n\n const srcUp = path.join(tmp, \"incoming-up-broken\");\n writeManifest(srcUp, {\n name: \"Fixed v2\",\n uuid,\n version: [1, 1, 0],\n type: \"data\",\n });\n const up = await installPackDirectory({\n srcDir: srcUp,\n destParent: dest,\n folderName: \"OtherHint\",\n force: false,\n });\n assert.equal(up.ok, true, up.reason);\n assert.equal(up.destDir, existingDir);\n assert.equal(readPackManifestInfo(existingDir)?.version.join(\".\"), \"1.1.0\");\n });\n\n it(\"uninstallInstalledPack\uFF1A\u56DE\u6536\u7AD9 / purge / \u76EE\u5F55\u7F3A\u5931\", async () => {\n const { uninstallInstalledPack, listInstalledWorldPacks } = await import(\"./world-packs.js\");\n const bds = path.join(tmp, \"uninstall-bds\");\n const level = \"Bedrock level\";\n const folder = \"[BP] Gone\";\n const uuid = \"dddddddd-dddd-dddd-dddd-dddddddddddd\";\n const packDir = path.join(bds, \"worlds\", level, \"behavior_packs\", folder);\n writeManifest(packDir, {\n name: \"Gone\",\n uuid,\n version: [1, 0, 0],\n type: \"data\",\n });\n fs.mkdirSync(path.join(bds, \"worlds\", level), { recursive: true });\n fs.writeFileSync(\n path.join(bds, \"worlds\", level, \"world_behavior_packs.json\"),\n JSON.stringify([{ pack_id: uuid, version: [1, 0, 0] }])\n );\n\n const packs = listInstalledWorldPacks(bds, level);\n assert.equal(packs.length, 1);\n const trash = path.join(tmp, \"trash-bin\");\n const trashed = await uninstallInstalledPack({\n bdsRoot: bds,\n levelName: level,\n pack: packs[0],\n trashDir: trash,\n });\n assert.equal(trashed.action, \"trashed\");\n assert.ok(trashed.dest && fs.existsSync(trashed.dest));\n assert.equal(fs.existsSync(packDir), false);\n const enable = JSON.parse(\n fs.readFileSync(path.join(bds, \"worlds\", level, \"world_behavior_packs.json\"), \"utf8\")\n );\n assert.equal(enable.length, 0);\n\n /* \u76EE\u5F55\u5DF2\u4E0D\u5728 list \u4E2D\uFF1B\u6784\u9020 missing \u573A\u666F */\n const phantom = {\n ...packs[0],\n dir: path.join(bds, \"worlds\", level, \"behavior_packs\", \"no-such\"),\n enabled: false,\n };\n const missing = await uninstallInstalledPack({\n bdsRoot: bds,\n levelName: level,\n pack: phantom,\n trashDir: trash,\n });\n assert.equal(missing.action, \"missing\");\n\n /* purge\uFF1A\u518D\u88C5\u4E00\u4E2A\u76F4\u63A5\u5220 */\n const folder2 = \"[BP] PurgeMe\";\n const uuid2 = \"eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee\";\n const packDir2 = path.join(bds, \"worlds\", level, \"behavior_packs\", folder2);\n writeManifest(packDir2, {\n name: \"PurgeMe\",\n uuid: uuid2,\n version: [1, 0, 0],\n type: \"data\",\n });\n fs.writeFileSync(\n path.join(bds, \"worlds\", level, \"world_behavior_packs.json\"),\n JSON.stringify([{ pack_id: uuid2, version: [1, 0, 0] }])\n );\n const packs2 = listInstalledWorldPacks(bds, level);\n const purged = await uninstallInstalledPack({\n bdsRoot: bds,\n levelName: level,\n pack: packs2.find((p) => p.uuid === uuid2),\n trashDir: null,\n });\n assert.equal(purged.action, \"deleted\");\n assert.equal(fs.existsSync(packDir2), false);\n });\n\n it(\"readPackManifestInfo \u9047 UTF-8 BOM \u4ECD\u53EF\u8BFB\u51FA uuid/name\uFF08\u5265\u79BB\u517C\u5BB9\uFF09\", async () => {\n const { readPackManifestInfo } = await import(\"./world-packs.js\");\n const dir = path.join(tmp, \"bom-rp\");\n fs.mkdirSync(dir, { recursive: true });\n const body = JSON.stringify(\n {\n format_version: 2,\n header: {\n name: \"\u00A7l\u00A7a\u795E\u91D1\",\n uuid: \"2b6de4b1-1f74-4c6e-937b-77f5e9c1f199\",\n version: [1, 0, 4],\n },\n modules: [{ type: \"resources\", uuid: \"1c710355-15e2-4293-8574-788eec05d35f\", version: [1, 0, 4] }],\n },\n null,\n 2\n );\n fs.writeFileSync(path.join(dir, \"manifest.json\"), `\\uFEFF${body}`, \"utf8\");\n const info = readPackManifestInfo(dir);\n assert.ok(info);\n assert.equal(info.uuid, \"2b6de4b1-1f74-4c6e-937b-77f5e9c1f199\");\n assert.equal(info.name, \"\u00A7l\u00A7a\u795E\u91D1\");\n assert.equal(info.kind, \"resource\");\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["zip"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
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 JSZip from "jszip";
|
|
7
|
+
import { extractZipBufferToDir, resolveSafeZipEntryPath } from "./zipx.js";
|
|
8
|
+
test("resolveSafeZipEntryPath rejects .. and absolute", () => {
|
|
9
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), "sfmc-zipx-"));
|
|
10
|
+
assert.throws(() => resolveSafeZipEntryPath(root, "../evil.txt"));
|
|
11
|
+
assert.throws(() => resolveSafeZipEntryPath(root, "foo/../../evil.txt"));
|
|
12
|
+
assert.throws(() => resolveSafeZipEntryPath(root, "/etc/passwd"));
|
|
13
|
+
const ok = resolveSafeZipEntryPath(root, "pack/manifest.json");
|
|
14
|
+
assert.equal(ok, path.resolve(root, "pack", "manifest.json"));
|
|
15
|
+
fs.rmSync(root, { recursive: true, force: true });
|
|
16
|
+
});
|
|
17
|
+
test("extractZipBufferToDir rejects zip-slip entries", async () => {
|
|
18
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), "sfmc-zipx-"));
|
|
19
|
+
const zip = new JSZip();
|
|
20
|
+
zip.file("../../escape.txt", "pwned");
|
|
21
|
+
const buf = await zip.generateAsync({ type: "nodebuffer" });
|
|
22
|
+
await assert.rejects(() => extractZipBufferToDir(buf, root), /unsafe zip entry|escapes/);
|
|
23
|
+
assert.equal(fs.existsSync(path.join(root, "escape.txt")), false);
|
|
24
|
+
fs.rmSync(root, { recursive: true, force: true });
|
|
25
|
+
});
|
|
26
|
+
test("extractZipBufferToDir writes nested safe entries", async () => {
|
|
27
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), "sfmc-zipx-"));
|
|
28
|
+
const zip = new JSZip();
|
|
29
|
+
zip.file("inner/manifest.json", '{"ok":true}');
|
|
30
|
+
const buf = await zip.generateAsync({ type: "nodebuffer" });
|
|
31
|
+
await extractZipBufferToDir(buf, root);
|
|
32
|
+
const text = fs.readFileSync(path.join(root, "inner", "manifest.json"), "utf8");
|
|
33
|
+
assert.match(text, /"ok"\s*:\s*true/);
|
|
34
|
+
fs.rmSync(root, { recursive: true, force: true });
|
|
35
|
+
});
|
|
36
|
+
//# sourceMappingURL=zipx.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/zipx.test.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * zipx \u5B89\u5168\u8DEF\u5F84 + \u89E3\u538B\u5355\u6D4B\uFF08zip-slip\uFF09\n */\nimport 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 JSZip from \"jszip\";\nimport { extractZipBufferToDir, resolveSafeZipEntryPath } from \"./zipx.js\";\n\ntest(\"resolveSafeZipEntryPath rejects .. and absolute\", () => {\n const root = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-zipx-\"));\n assert.throws(() => resolveSafeZipEntryPath(root, \"../evil.txt\"));\n assert.throws(() => resolveSafeZipEntryPath(root, \"foo/../../evil.txt\"));\n assert.throws(() => resolveSafeZipEntryPath(root, \"/etc/passwd\"));\n const ok = resolveSafeZipEntryPath(root, \"pack/manifest.json\");\n assert.equal(ok, path.resolve(root, \"pack\", \"manifest.json\"));\n fs.rmSync(root, { recursive: true, force: true });\n});\n\ntest(\"extractZipBufferToDir rejects zip-slip entries\", async () => {\n const root = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-zipx-\"));\n const zip = new JSZip();\n zip.file(\"../../escape.txt\", \"pwned\");\n const buf = await zip.generateAsync({ type: \"nodebuffer\" });\n await assert.rejects(() => extractZipBufferToDir(buf, root), /unsafe zip entry|escapes/);\n assert.equal(fs.existsSync(path.join(root, \"escape.txt\")), false);\n fs.rmSync(root, { recursive: true, force: true });\n});\n\ntest(\"extractZipBufferToDir writes nested safe entries\", async () => {\n const root = fs.mkdtempSync(path.join(os.tmpdir(), \"sfmc-zipx-\"));\n const zip = new JSZip();\n zip.file(\"inner/manifest.json\", '{\"ok\":true}');\n const buf = await zip.generateAsync({ type: \"nodebuffer\" });\n await extractZipBufferToDir(buf, root);\n const text = fs.readFileSync(path.join(root, \"inner\", \"manifest.json\"), \"utf8\");\n assert.match(text, /\"ok\"\\s*:\\s*true/);\n fs.rmSync(root, { recursive: true, force: true });\n});\n"],
|
|
5
|
+
"mappings": "AAGA,OAAO,YAAY;AACnB,OAAO,QAAQ;AACf,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,OAAO,UAAU;AACjB,OAAO,WAAW;AAClB,SAAS,uBAAuB,+BAA+B;AAE/D,KAAK,mDAAmD,MAAM;AAC5D,QAAM,OAAO,GAAG,YAAY,KAAK,KAAK,GAAG,OAAO,GAAG,YAAY,CAAC;AAChE,SAAO,OAAO,MAAM,wBAAwB,MAAM,aAAa,CAAC;AAChE,SAAO,OAAO,MAAM,wBAAwB,MAAM,oBAAoB,CAAC;AACvE,SAAO,OAAO,MAAM,wBAAwB,MAAM,aAAa,CAAC;AAChE,QAAM,KAAK,wBAAwB,MAAM,oBAAoB;AAC7D,SAAO,MAAM,IAAI,KAAK,QAAQ,MAAM,QAAQ,eAAe,CAAC;AAC5D,KAAG,OAAO,MAAM,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAClD,CAAC;AAED,KAAK,kDAAkD,YAAY;AACjE,QAAM,OAAO,GAAG,YAAY,KAAK,KAAK,GAAG,OAAO,GAAG,YAAY,CAAC;AAChE,QAAM,MAAM,IAAI,MAAM;AACtB,MAAI,KAAK,oBAAoB,OAAO;AACpC,QAAM,MAAM,MAAM,IAAI,cAAc,EAAE,MAAM,aAAa,CAAC;AAC1D,QAAM,OAAO,QAAQ,MAAM,sBAAsB,KAAK,IAAI,GAAG,0BAA0B;AACvF,SAAO,MAAM,GAAG,WAAW,KAAK,KAAK,MAAM,YAAY,CAAC,GAAG,KAAK;AAChE,KAAG,OAAO,MAAM,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAClD,CAAC;AAED,KAAK,oDAAoD,YAAY;AACnE,QAAM,OAAO,GAAG,YAAY,KAAK,KAAK,GAAG,OAAO,GAAG,YAAY,CAAC;AAChE,QAAM,MAAM,IAAI,MAAM;AACtB,MAAI,KAAK,uBAAuB,aAAa;AAC7C,QAAM,MAAM,MAAM,IAAI,cAAc,EAAE,MAAM,aAAa,CAAC;AAC1D,QAAM,sBAAsB,KAAK,IAAI;AACrC,QAAM,OAAO,GAAG,aAAa,KAAK,KAAK,MAAM,SAAS,eAAe,GAAG,MAAM;AAC9E,SAAO,MAAM,MAAM,iBAAiB;AACpC,KAAG,OAAO,MAAM,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAClD,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,73 +1,77 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sfmc-bds/bds-tools",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.10",
|
|
4
4
|
"description": "SFMC BDS auto-updater, lifecycle manager, and behavior-pack assembler",
|
|
5
5
|
"author": "Shiroha7z",
|
|
6
|
+
"license": "AGPL-3.0-only",
|
|
6
7
|
"type": "module",
|
|
7
|
-
"
|
|
8
|
-
"homepage": "https://github.com/DogeLakeDev/ScriptsForMinecraftServer/tree/main/bds-tools#readme",
|
|
8
|
+
"homepage": "https://github.com/DogeLakeDev/ScriptsForMinecraftServer/tree/main/packages/bds-tools#readme",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
11
11
|
"url": "git+https://github.com/DogeLakeDev/ScriptsForMinecraftServer.git",
|
|
12
|
-
"directory": "bds-tools"
|
|
12
|
+
"directory": "packages/bds-tools"
|
|
13
13
|
},
|
|
14
14
|
"bugs": {
|
|
15
15
|
"url": "https://github.com/DogeLakeDev/ScriptsForMinecraftServer/issues"
|
|
16
16
|
},
|
|
17
17
|
"keywords": [
|
|
18
|
+
"bds",
|
|
18
19
|
"minecraft-bedrock",
|
|
20
|
+
"scriptsforminecraftserver",
|
|
19
21
|
"sfmc",
|
|
20
|
-
"
|
|
21
|
-
"updater",
|
|
22
|
-
"scriptsforminecraftserver"
|
|
22
|
+
"updater"
|
|
23
23
|
],
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=22.13.0"
|
|
26
|
+
},
|
|
24
27
|
"main": "dist/bds-manager.js",
|
|
25
|
-
"files": [
|
|
26
|
-
"dist",
|
|
27
|
-
"README.md"
|
|
28
|
-
],
|
|
29
28
|
"exports": {
|
|
30
29
|
".": "./dist/bds-manager.js",
|
|
31
|
-
"./check-update": "./dist/check-update.js",
|
|
32
30
|
"./bds-manager": "./dist/bds-manager.js",
|
|
31
|
+
"./check-update": "./dist/check-update.js",
|
|
32
|
+
"./host-platform": "./dist/host-platform.js",
|
|
33
33
|
"./pack-manager": "./dist/cli-pack-manager.js",
|
|
34
34
|
"./pack-manager-lib": "./dist/pack-manager.js",
|
|
35
|
-
"./
|
|
36
|
-
"./http": "./dist/http.js",
|
|
37
|
-
"./taskbar": "./dist/taskbar.js",
|
|
38
|
-
"./update-result": "./dist/update-result.js",
|
|
39
|
-
"./zipx": "./dist/zipx.js",
|
|
35
|
+
"./process-probe": "./dist/process-probe.js",
|
|
40
36
|
"./package.json": "./package.json",
|
|
37
|
+
"./taskbar": "./dist/taskbar.js",
|
|
41
38
|
"./types": {
|
|
42
39
|
"types": "./dist/types.d.ts"
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"typecheck": "tsc7 --noEmit",
|
|
49
|
-
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
50
|
-
"test": "node --test is-main.test.mjs pack-manager-lifecycle.test.mjs server-properties.test.mjs world-packs.test.mjs zipx.test.mjs",
|
|
51
|
-
"update": "node dist/check-update.js",
|
|
52
|
-
"update:check": "node dist/check-update.js --check-only",
|
|
53
|
-
"update:force": "node dist/check-update.js --force",
|
|
54
|
-
"rollback": "node recovery.js",
|
|
55
|
-
"start": "node dist/bds-manager.js start",
|
|
56
|
-
"stop": "node dist/bds-manager.js stop",
|
|
57
|
-
"status": "node dist/bds-manager.js status",
|
|
58
|
-
"watch": "node dist/bds-manager.js watch",
|
|
59
|
-
"prepublishOnly": "npm run build"
|
|
40
|
+
},
|
|
41
|
+
"./update-result": "./dist/update-result.js",
|
|
42
|
+
"./world-packs": "./dist/world-packs.js",
|
|
43
|
+
"./pack-update": "./dist/pack-update/index.js",
|
|
44
|
+
"./zipx": "./dist/zipx.js"
|
|
60
45
|
},
|
|
46
|
+
"files": [
|
|
47
|
+
"dist",
|
|
48
|
+
"README.md"
|
|
49
|
+
],
|
|
61
50
|
"dependencies": {
|
|
62
|
-
"@sfmc-bds/sdk": "^0.2.0-beta.0",
|
|
63
51
|
"jszip": "^3.10.1",
|
|
64
|
-
"node-html-parser": "^9.0.0"
|
|
52
|
+
"node-html-parser": "^9.0.0",
|
|
53
|
+
"@sfmc-bds/sdk": "0.2.0-beta.10"
|
|
65
54
|
},
|
|
66
|
-
"
|
|
67
|
-
"
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@sfmc-bds/tools": "0.2.0-beta.11"
|
|
68
57
|
},
|
|
69
58
|
"publishConfig": {
|
|
70
59
|
"access": "public",
|
|
71
60
|
"registry": "https://registry.npmjs.org/"
|
|
61
|
+
},
|
|
62
|
+
"scripts": {
|
|
63
|
+
"build": "sfmc-esbuild-transpile --dts",
|
|
64
|
+
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
65
|
+
"dev": "tsx src/bds-manager.ts",
|
|
66
|
+
"rollback": "node recovery.js",
|
|
67
|
+
"start": "node dist/bds-manager.js start",
|
|
68
|
+
"status": "node dist/bds-manager.js status",
|
|
69
|
+
"stop": "node dist/bds-manager.js stop",
|
|
70
|
+
"test": "pnpm run build && node --test \"dist/**/*.test.js\"",
|
|
71
|
+
"typecheck": "tsc7 --noEmit",
|
|
72
|
+
"update": "node dist/check-update.js",
|
|
73
|
+
"update:check": "node dist/check-update.js --check-only",
|
|
74
|
+
"update:force": "node dist/check-update.js --force",
|
|
75
|
+
"watch": "node dist/bds-manager.js watch"
|
|
72
76
|
}
|
|
73
|
-
}
|
|
77
|
+
}
|