@sfmc-bds/bds-tools 0.2.0-beta.7 → 0.2.0-beta.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bds-manager.d.ts.map +1 -1
- package/dist/bds-manager.js +40 -65
- package/dist/bds-manager.js.map +2 -2
- package/dist/check-update.d.ts.map +1 -1
- package/dist/check-update.js +4 -6
- package/dist/check-update.js.map +2 -2
- package/dist/fsx.d.ts +2 -7
- package/dist/fsx.d.ts.map +1 -1
- package/dist/fsx.js +0 -11
- 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/pack-manager.d.ts.map +1 -1
- package/dist/pack-manager.js +6 -1
- 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/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/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/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/qq-events-notify.test.d.ts +5 -0
- package/dist/qq-events-notify.test.d.ts.map +1 -0
- package/dist/qq-events-notify.test.js +41 -0
- package/dist/qq-events-notify.test.js.map +7 -0
- package/dist/qqutil.d.ts +2 -1
- package/dist/qqutil.d.ts.map +1 -1
- package/dist/qqutil.js +49 -8
- package/dist/qqutil.js.map +2 -2
- package/dist/upstream.d.ts +4 -3
- 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 +0 -2
- package/dist/world-packs.d.ts.map +1 -1
- package/dist/world-packs.js +0 -2
- package/dist/world-packs.js.map +2 -2
- package/package.json +8 -6
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/pack-update/deps.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * pack-update \u4F9D\u8D56\u6CE8\u5165\u5951\u7EA6\uFF08CLI \u6CE8\u5165 i18n/theme/log\uFF1B\u5E93\u6D4B\u8BD5\u53EF\u4F20\u82F1\u6587\u56DE\u9000\uFF09\n */\n\nexport type PackUpdateDeps = {\n rootDir: string;\n resolveBdsContext: () => { bdsRoot: string; levelName: string };\n log: (text: string, level?: \"info\" | \"warn\" | \"error\" | \"success\") => void;\n askConfirm: (message: string) => Promise<boolean>;\n /** i18n\uFF1ACLI \u4F20 t()\uFF1B\u6D4B\u8BD5\u53EF\u4F20 key \u6216\u82F1\u6587\u56DE\u9000 */\n t: (key: string, params?: Record<string, string | number>) => string;\n /** \u53EF\u9009\u7740\u8272\uFF1B\u7701\u7565\u65F6\u7528 identity */\n paint: {\n green: (s: string) => string;\n yellow: (s: string) => string;\n red: (s: string) => string;\n dim: (s: string) => string;\n cyan: (s: string) => string;\n bold: (s: string) => string;\n };\n};\n\nconst id = (s: string): string => s;\n\n/** \u65E0 ANSI \u7684 identity paint\uFF08\u6D4B\u8BD5 / \u975E TTY \u56DE\u9000\uFF09 */\nexport function identityPaint(): PackUpdateDeps[\"paint\"] {\n return { green: id, yellow: id, red: id, dim: id, cyan: id, bold: id };\n}\n\n/** \u6700\u5C0F\u6D4B\u8BD5\u4F9D\u8D56\uFF1A\u4EC5 rootDir\uFF0C\u5176\u4F59 noop / identity */\nexport function createTestPackUpdateDeps(rootDir: string): PackUpdateDeps {\n return {\n rootDir,\n resolveBdsContext: () => ({ bdsRoot: \"\", levelName: \"\" }),\n log: () => {},\n askConfirm: async () => true,\n t: (key) => key,\n paint: identityPaint(),\n };\n}\n"],
|
|
5
|
+
"mappings": "AAsBA,MAAM,KAAK,CAAC,MAAsB;AAG3B,SAAS,gBAAyC;AACvD,SAAO,EAAE,OAAO,IAAI,QAAQ,IAAI,KAAK,IAAI,KAAK,IAAI,MAAM,IAAI,MAAM,GAAG;AACvE;AAGO,SAAS,yBAAyB,SAAiC;AACxE,SAAO;AAAA,IACL;AAAA,IACA,mBAAmB,OAAO,EAAE,SAAS,IAAI,WAAW,GAAG;AAAA,IACvD,KAAK,MAAM;AAAA,IAAC;AAAA,IACZ,YAAY,YAAY;AAAA,IACxB,GAAG,CAAC,QAAQ;AAAA,IACZ,OAAO,cAAc;AAAA,EACvB;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { createTestPackUpdateDeps, identityPaint, type PackUpdateDeps } from "./deps.js";
|
|
2
|
+
import { createPackSourceProvider, providerShortLabel, resolveConfiguredPackProvider } from "./providers/index.js";
|
|
3
|
+
export type { PackUpdateDeps };
|
|
4
|
+
export { createTestPackUpdateDeps, identityPaint };
|
|
5
|
+
export type { CurseForgeProviderConfig, PackProviderId, PackReleaseType, PackSourceBinding, PackSourceProvider, PackSourcesFile, PackUpdateConfig, PackUpdateMatchConfig, PackUninstallConfig, SemVer3, SourceFileRef, SourceSearchHit, VersionCompareResult, VersionPolicyConfig, } from "./types.js";
|
|
6
|
+
export { DEFAULT_PACK_UNINSTALL } from "./types.js";
|
|
7
|
+
export { buildSearchQueries, buildSearchQueriesFromSources, bumpSemVer3, collectQuerySeeds, compareSemVer3, decideVersionPolicy, extractLatinPhrase, insertCjkLatinBoundaries, isNewer, maxSemVer3, nextEnabledVersion, normalizePackSearchName, packSourceScore, toCfSlugCandidate, } from "./version-policy.js";
|
|
8
|
+
export type { SearchQueryPlan, SearchQuerySource } from "./version-policy.js";
|
|
9
|
+
export { createPackSourceProvider, CurseForgeBedrockProvider, providerShortLabel, resolveConfiguredPackProvider, } from "./providers/index.js";
|
|
10
|
+
export type { PackUpdateBindingsApi } from "./bindings.js";
|
|
11
|
+
export type { PackUpdateConfigApi } from "./config.js";
|
|
12
|
+
export type { PackUpdateServiceApi } from "./service.js";
|
|
13
|
+
export declare function createPackUpdateApi(deps: PackUpdateDeps): {
|
|
14
|
+
packSourcesPath: () => string;
|
|
15
|
+
readPackSources: () => import("./types.js").PackSourcesFile;
|
|
16
|
+
writePackSources: (data: import("./types.js").PackSourcesFile) => void;
|
|
17
|
+
getBinding: (bpUuid: string) => import("./types.js").PackSourceBinding | null;
|
|
18
|
+
setBinding: (bpUuid: string, binding: import("./types.js").PackSourceBinding) => void;
|
|
19
|
+
removeBinding: (bpUuid: string) => boolean;
|
|
20
|
+
listBindings: () => Array<{
|
|
21
|
+
bpUuid: string;
|
|
22
|
+
binding: import("./types.js").PackSourceBinding;
|
|
23
|
+
}>;
|
|
24
|
+
packUpdateConfigPath: () => string;
|
|
25
|
+
loadPackUpdateConfig: () => import("./types.js").PackUpdateConfig;
|
|
26
|
+
getPackMatchConfig: (cfg: import("./types.js").PackUpdateConfig) => import("./types.js").PackUpdateMatchConfig;
|
|
27
|
+
resolvePackTrashDir: (cfg?: import("./types.js").PackUpdateConfig) => string;
|
|
28
|
+
isPackUninstallRecycleBin: (cfg?: import("./types.js").PackUpdateConfig) => boolean;
|
|
29
|
+
resolveUninstallTrashDir: (opts?: {
|
|
30
|
+
purge?: boolean;
|
|
31
|
+
cfg?: import("./types.js").PackUpdateConfig;
|
|
32
|
+
}) => string | null;
|
|
33
|
+
ensurePackUpdateConfigFile: () => string;
|
|
34
|
+
pairedRpUuidFromBpDir: (bpDir: string) => string | null;
|
|
35
|
+
probeSourceAfterInstall: (opts: {
|
|
36
|
+
info: import("../world-packs.js").PackManifestInfo;
|
|
37
|
+
packDir?: string;
|
|
38
|
+
folderName?: string;
|
|
39
|
+
interactive?: boolean;
|
|
40
|
+
}) => Promise<void>;
|
|
41
|
+
searchRemote: (query: string) => Promise<string>;
|
|
42
|
+
bindPackSource: (packId: string, ref: string) => Promise<string>;
|
|
43
|
+
formatSourcesList: () => string;
|
|
44
|
+
checkPackUpdates: (opts?: {
|
|
45
|
+
packId?: string;
|
|
46
|
+
apply?: boolean;
|
|
47
|
+
}) => Promise<string>;
|
|
48
|
+
runPackUpdatesOnBdsStart: () => Promise<void>;
|
|
49
|
+
bindingLabelForUuid: (uuid: string) => string;
|
|
50
|
+
createPackSourceProvider: typeof createPackSourceProvider;
|
|
51
|
+
providerShortLabel: typeof providerShortLabel;
|
|
52
|
+
resolveConfiguredPackProvider: typeof resolveConfiguredPackProvider;
|
|
53
|
+
};
|
|
54
|
+
export type PackUpdateApi = ReturnType<typeof createPackUpdateApi>;
|
|
55
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pack-update/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,wBAAwB,EAAE,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AACzF,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,6BAA6B,EAC9B,MAAM,sBAAsB,CAAC;AAG9B,YAAY,EAAE,cAAc,EAAE,CAAC;AAC/B,OAAO,EAAE,wBAAwB,EAAE,aAAa,EAAE,CAAC;AAEnD,YAAY,EACV,wBAAwB,EACxB,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,EACnB,OAAO,EACP,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEpD,OAAO,EACL,kBAAkB,EAClB,6BAA6B,EAC7B,WAAW,EACX,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,EACxB,OAAO,EACP,UAAU,EACV,kBAAkB,EAClB,uBAAuB,EACvB,eAAe,EACf,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE9E,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,kBAAkB,EAClB,6BAA6B,GAC9B,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC3D,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEzD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAcvD;AAED,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { createPackUpdateBindingsApi } from "./bindings.js";
|
|
2
|
+
import { createPackUpdateConfigApi } from "./config.js";
|
|
3
|
+
import { createTestPackUpdateDeps, identityPaint } from "./deps.js";
|
|
4
|
+
import {
|
|
5
|
+
createPackSourceProvider,
|
|
6
|
+
providerShortLabel,
|
|
7
|
+
resolveConfiguredPackProvider
|
|
8
|
+
} from "./providers/index.js";
|
|
9
|
+
import { createPackUpdateServiceApi } from "./service.js";
|
|
10
|
+
import { DEFAULT_PACK_UNINSTALL } from "./types.js";
|
|
11
|
+
import {
|
|
12
|
+
buildSearchQueries,
|
|
13
|
+
buildSearchQueriesFromSources,
|
|
14
|
+
bumpSemVer3,
|
|
15
|
+
collectQuerySeeds,
|
|
16
|
+
compareSemVer3,
|
|
17
|
+
decideVersionPolicy,
|
|
18
|
+
extractLatinPhrase,
|
|
19
|
+
insertCjkLatinBoundaries,
|
|
20
|
+
isNewer,
|
|
21
|
+
maxSemVer3,
|
|
22
|
+
nextEnabledVersion,
|
|
23
|
+
normalizePackSearchName,
|
|
24
|
+
packSourceScore,
|
|
25
|
+
toCfSlugCandidate
|
|
26
|
+
} from "./version-policy.js";
|
|
27
|
+
import {
|
|
28
|
+
createPackSourceProvider as createPackSourceProvider2,
|
|
29
|
+
CurseForgeBedrockProvider,
|
|
30
|
+
providerShortLabel as providerShortLabel2,
|
|
31
|
+
resolveConfiguredPackProvider as resolveConfiguredPackProvider2
|
|
32
|
+
} from "./providers/index.js";
|
|
33
|
+
function createPackUpdateApi(deps) {
|
|
34
|
+
const paint = deps.paint ?? identityPaint();
|
|
35
|
+
const resolved = { ...deps, paint };
|
|
36
|
+
const config = createPackUpdateConfigApi(resolved);
|
|
37
|
+
const bindings = createPackUpdateBindingsApi(resolved);
|
|
38
|
+
const service = createPackUpdateServiceApi(resolved, config, bindings);
|
|
39
|
+
return {
|
|
40
|
+
...config,
|
|
41
|
+
...bindings,
|
|
42
|
+
...service,
|
|
43
|
+
createPackSourceProvider,
|
|
44
|
+
providerShortLabel,
|
|
45
|
+
resolveConfiguredPackProvider
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
CurseForgeBedrockProvider,
|
|
50
|
+
DEFAULT_PACK_UNINSTALL,
|
|
51
|
+
buildSearchQueries,
|
|
52
|
+
buildSearchQueriesFromSources,
|
|
53
|
+
bumpSemVer3,
|
|
54
|
+
collectQuerySeeds,
|
|
55
|
+
compareSemVer3,
|
|
56
|
+
createPackSourceProvider2 as createPackSourceProvider,
|
|
57
|
+
createPackUpdateApi,
|
|
58
|
+
createTestPackUpdateDeps,
|
|
59
|
+
decideVersionPolicy,
|
|
60
|
+
extractLatinPhrase,
|
|
61
|
+
identityPaint,
|
|
62
|
+
insertCjkLatinBoundaries,
|
|
63
|
+
isNewer,
|
|
64
|
+
maxSemVer3,
|
|
65
|
+
nextEnabledVersion,
|
|
66
|
+
normalizePackSearchName,
|
|
67
|
+
packSourceScore,
|
|
68
|
+
providerShortLabel2 as providerShortLabel,
|
|
69
|
+
resolveConfiguredPackProvider2 as resolveConfiguredPackProvider,
|
|
70
|
+
toCfSlugCandidate
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/pack-update/index.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * pack-update \u516C\u5171\u5165\u53E3\uFF1A\u4F9D\u8D56\u6CE8\u5165\u5DE5\u5382 + \u7EAF\u51FD\u6570/\u7C7B\u578B\u518D\u5BFC\u51FA\n */\nimport { createPackUpdateBindingsApi } from \"./bindings.js\";\nimport { createPackUpdateConfigApi } from \"./config.js\";\nimport { createTestPackUpdateDeps, identityPaint, type PackUpdateDeps } from \"./deps.js\";\nimport {\n createPackSourceProvider,\n providerShortLabel,\n resolveConfiguredPackProvider,\n} from \"./providers/index.js\";\nimport { createPackUpdateServiceApi } from \"./service.js\";\n\nexport type { PackUpdateDeps };\nexport { createTestPackUpdateDeps, identityPaint };\n\nexport type {\n CurseForgeProviderConfig,\n PackProviderId,\n PackReleaseType,\n PackSourceBinding,\n PackSourceProvider,\n PackSourcesFile,\n PackUpdateConfig,\n PackUpdateMatchConfig,\n PackUninstallConfig,\n SemVer3,\n SourceFileRef,\n SourceSearchHit,\n VersionCompareResult,\n VersionPolicyConfig,\n} from \"./types.js\";\nexport { DEFAULT_PACK_UNINSTALL } from \"./types.js\";\n\nexport {\n buildSearchQueries,\n buildSearchQueriesFromSources,\n bumpSemVer3,\n collectQuerySeeds,\n compareSemVer3,\n decideVersionPolicy,\n extractLatinPhrase,\n insertCjkLatinBoundaries,\n isNewer,\n maxSemVer3,\n nextEnabledVersion,\n normalizePackSearchName,\n packSourceScore,\n toCfSlugCandidate,\n} from \"./version-policy.js\";\nexport type { SearchQueryPlan, SearchQuerySource } from \"./version-policy.js\";\n\nexport {\n createPackSourceProvider,\n CurseForgeBedrockProvider,\n providerShortLabel,\n resolveConfiguredPackProvider,\n} from \"./providers/index.js\";\n\nexport type { PackUpdateBindingsApi } from \"./bindings.js\";\nexport type { PackUpdateConfigApi } from \"./config.js\";\nexport type { PackUpdateServiceApi } from \"./service.js\";\n\nexport function createPackUpdateApi(deps: PackUpdateDeps) {\n const paint = deps.paint ?? identityPaint();\n const resolved: PackUpdateDeps = { ...deps, paint };\n const config = createPackUpdateConfigApi(resolved);\n const bindings = createPackUpdateBindingsApi(resolved);\n const service = createPackUpdateServiceApi(resolved, config, bindings);\n return {\n ...config,\n ...bindings,\n ...service,\n createPackSourceProvider,\n providerShortLabel,\n resolveConfiguredPackProvider,\n };\n}\n\nexport type PackUpdateApi = ReturnType<typeof createPackUpdateApi>;\n"],
|
|
5
|
+
"mappings": "AAGA,SAAS,mCAAmC;AAC5C,SAAS,iCAAiC;AAC1C,SAAS,0BAA0B,qBAA0C;AAC7E;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kCAAkC;AAqB3C,SAAS,8BAA8B;AAEvC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP;AAAA,EACE,4BAAAA;AAAA,EACA;AAAA,EACA,sBAAAC;AAAA,EACA,iCAAAC;AAAA,OACK;AAMA,SAAS,oBAAoB,MAAsB;AACxD,QAAM,QAAQ,KAAK,SAAS,cAAc;AAC1C,QAAM,WAA2B,EAAE,GAAG,MAAM,MAAM;AAClD,QAAM,SAAS,0BAA0B,QAAQ;AACjD,QAAM,WAAW,4BAA4B,QAAQ;AACrD,QAAM,UAAU,2BAA2B,UAAU,QAAQ,QAAQ;AACrE,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
|
|
6
|
+
"names": ["createPackSourceProvider", "providerShortLabel", "resolveConfiguredPackProvider"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { CurseForgeProviderConfig, PackSourceProvider, SourceFileRef, SourceSearchHit } from "../types.js";
|
|
2
|
+
export declare class CurseForgeBedrockProvider implements PackSourceProvider {
|
|
3
|
+
private readonly cfg;
|
|
4
|
+
readonly id: "curseforge";
|
|
5
|
+
private classIdCache;
|
|
6
|
+
constructor(cfg: CurseForgeProviderConfig);
|
|
7
|
+
isConfigured(): boolean;
|
|
8
|
+
private gameId;
|
|
9
|
+
private searchBase;
|
|
10
|
+
private officialBase;
|
|
11
|
+
private headers;
|
|
12
|
+
private looksLikeLegacyUploadToken;
|
|
13
|
+
private buildUrl;
|
|
14
|
+
private fetchJson;
|
|
15
|
+
/** 官方 Core API GET */
|
|
16
|
+
private apiGet;
|
|
17
|
+
resolveClassId(): Promise<number | null>;
|
|
18
|
+
search(query: string): Promise<SourceSearchHit[]>;
|
|
19
|
+
resolveProject(ref: string | number): Promise<SourceSearchHit | null>;
|
|
20
|
+
getLatestFile(projectId: number): Promise<SourceFileRef | null>;
|
|
21
|
+
download(file: SourceFileRef, destPath: string, onProgress?: (dl: number, total: number) => void): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=curseforge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"curseforge.d.ts","sourceRoot":"","sources":["../../../src/pack-update/providers/curseforge.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,wBAAwB,EAExB,kBAAkB,EAClB,aAAa,EACb,eAAe,EAChB,MAAM,aAAa,CAAC;AAyDrB,qBAAa,yBAA0B,YAAW,kBAAkB;IAItD,OAAO,CAAC,QAAQ,CAAC,GAAG;IAHhC,QAAQ,CAAC,EAAE,EAAG,YAAY,CAAU;IACpC,OAAO,CAAC,YAAY,CAAuB;IAE3C,YAA6B,GAAG,EAAE,wBAAwB,EAAI;IAE9D,YAAY,IAAI,OAAO,CAEtB;IAED,OAAO,CAAC,MAAM;IAMd,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,OAAO;IAQf,OAAO,CAAC,0BAA0B;IAIlC,OAAO,CAAC,QAAQ;YAaF,SAAS;IA4BvB,sBAAsB;IACtB,OAAO,CAAC,MAAM;IAUR,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiB7C;IAEK,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CA0BtD;IAEK,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAa1E;IAEK,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CA6DpE;IAEK,QAAQ,CACZ,IAAI,EAAE,aAAa,EACnB,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GAC/C,OAAO,CAAC,IAAI,CAAC,CAiBf;CACF"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { bindByteProgressToBar, createTerminalProgress } from "@sfmc-bds/sdk/logs";
|
|
2
|
+
import { httpDownload } from "../../http.js";
|
|
3
|
+
const RELEASE_MAP = {
|
|
4
|
+
1: "release",
|
|
5
|
+
2: "beta",
|
|
6
|
+
3: "alpha"
|
|
7
|
+
};
|
|
8
|
+
const LEGACY_BAD_GAME_IDS = /* @__PURE__ */ new Set([459]);
|
|
9
|
+
const BEDROCK_GAME_ID = 78022;
|
|
10
|
+
const BEDROCK_ADDONS_CLASS_ID = 4984;
|
|
11
|
+
const DEFAULT_SEARCH_BASE = "https://api.curse.tools/v1/cf";
|
|
12
|
+
function releaseRank(t, preferred) {
|
|
13
|
+
if (!t) return 999;
|
|
14
|
+
const i = preferred.indexOf(t);
|
|
15
|
+
return i >= 0 ? i : 100 + (t === "release" ? 0 : t === "beta" ? 1 : 2);
|
|
16
|
+
}
|
|
17
|
+
function mapHits(mods) {
|
|
18
|
+
return (mods ?? []).map((m) => {
|
|
19
|
+
const hit = {
|
|
20
|
+
provider: "curseforge",
|
|
21
|
+
projectId: m.id,
|
|
22
|
+
slug: m.slug,
|
|
23
|
+
name: m.name,
|
|
24
|
+
summary: m.summary ?? "",
|
|
25
|
+
websiteUrl: m.links?.websiteUrl ?? `https://www.curseforge.com/minecraft-bedrock/addons/${m.slug}`
|
|
26
|
+
};
|
|
27
|
+
if (typeof m.downloadCount === "number") hit.downloadCount = m.downloadCount;
|
|
28
|
+
return hit;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
class CurseForgeBedrockProvider {
|
|
32
|
+
constructor(cfg) {
|
|
33
|
+
this.cfg = cfg;
|
|
34
|
+
}
|
|
35
|
+
cfg;
|
|
36
|
+
id = "curseforge";
|
|
37
|
+
classIdCache = null;
|
|
38
|
+
isConfigured() {
|
|
39
|
+
return !!(this.cfg.enabled && this.cfg.apiKey?.trim());
|
|
40
|
+
}
|
|
41
|
+
gameId() {
|
|
42
|
+
const id = this.cfg.gameId;
|
|
43
|
+
if (!id || LEGACY_BAD_GAME_IDS.has(id)) return BEDROCK_GAME_ID;
|
|
44
|
+
return id;
|
|
45
|
+
}
|
|
46
|
+
searchBase() {
|
|
47
|
+
return (this.cfg.searchBaseUrl || DEFAULT_SEARCH_BASE).replace(/\/$/, "");
|
|
48
|
+
}
|
|
49
|
+
officialBase() {
|
|
50
|
+
return this.cfg.baseUrl.replace(/\/$/, "");
|
|
51
|
+
}
|
|
52
|
+
headers(includeKey = true) {
|
|
53
|
+
const h = { Accept: "application/json" };
|
|
54
|
+
if (includeKey && this.cfg.apiKey?.trim()) {
|
|
55
|
+
h["x-api-key"] = this.cfg.apiKey.trim();
|
|
56
|
+
}
|
|
57
|
+
return h;
|
|
58
|
+
}
|
|
59
|
+
looksLikeLegacyUploadToken(key) {
|
|
60
|
+
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(key.trim());
|
|
61
|
+
}
|
|
62
|
+
buildUrl(base, pathname, query) {
|
|
63
|
+
const url = new URL(`${base}${pathname.startsWith("/") ? pathname : `/${pathname}`}`);
|
|
64
|
+
for (const [k, v] of Object.entries(query)) {
|
|
65
|
+
if (v === void 0 || v === null || v === "") continue;
|
|
66
|
+
url.searchParams.set(k, String(v));
|
|
67
|
+
}
|
|
68
|
+
return url;
|
|
69
|
+
}
|
|
70
|
+
async fetchJson(base, pathname, query, opts) {
|
|
71
|
+
const requireKey = opts?.requireKey !== false;
|
|
72
|
+
if (requireKey && !this.isConfigured()) {
|
|
73
|
+
throw new Error("CurseForge API key \u672A\u914D\u7F6E\uFF08configs/pack-update.json \u6216 CURSEFORGE_API_KEY\uFF09");
|
|
74
|
+
}
|
|
75
|
+
const key = this.cfg.apiKey.trim();
|
|
76
|
+
const url = this.buildUrl(base, pathname, query);
|
|
77
|
+
const res = await fetch(url, { headers: this.headers(requireKey || !!key) });
|
|
78
|
+
if (!res.ok) {
|
|
79
|
+
const body = await res.text().catch(() => "");
|
|
80
|
+
if (res.status === 403 && requireKey) {
|
|
81
|
+
const hint = this.looksLikeLegacyUploadToken(key) ? "\u5F53\u524D key \u50CF legacy Upload UUID Token\u3002\u8BF7\u5230 https://console.curseforge.com/ \u7533\u8BF7 Studios Key\u3002" : "\u82E5\u4EC5\u641C\u7D22\u5931\u8D25\uFF1A\u5B98\u65B9 /mods/search \u53EF\u80FD\u5BF9\u4F60\u7684 key \u8FD4\u56DE 403\uFF08\u5C06\u81EA\u52A8\u6539\u7528 curse.tools\uFF09\u3002\u5176\u5B83\u63A5\u53E3\u4ECD\u9700\u6709\u6548 Studios Key\u3002";
|
|
82
|
+
throw new Error(
|
|
83
|
+
`CurseForge HTTP 403 (${opts?.label ?? pathname}): ${body.slice(0, 80).trim() || "Forbidden"} \u2014 ${hint}`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
throw new Error(`CurseForge HTTP ${res.status} (${opts?.label ?? pathname}): ${body.slice(0, 200)}`);
|
|
87
|
+
}
|
|
88
|
+
return await res.json();
|
|
89
|
+
}
|
|
90
|
+
/** 官方 Core API GET */
|
|
91
|
+
apiGet(pathname, query) {
|
|
92
|
+
return this.fetchJson(this.officialBase(), pathname, query, {
|
|
93
|
+
requireKey: true,
|
|
94
|
+
label: `official${pathname}`
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
async resolveClassId() {
|
|
98
|
+
if (this.cfg.classId != null) return this.cfg.classId;
|
|
99
|
+
if (this.classIdCache != null) return this.classIdCache;
|
|
100
|
+
try {
|
|
101
|
+
const data = await this.apiGet(
|
|
102
|
+
"/v1/categories",
|
|
103
|
+
{ gameId: this.gameId(), classesOnly: "true" }
|
|
104
|
+
);
|
|
105
|
+
const hit = data.data?.find((c) => /^addons?$/i.test(c.name)) ?? data.data?.find((c) => /addon/i.test(c.name));
|
|
106
|
+
this.classIdCache = hit?.id ?? BEDROCK_ADDONS_CLASS_ID;
|
|
107
|
+
return this.classIdCache;
|
|
108
|
+
} catch {
|
|
109
|
+
this.classIdCache = BEDROCK_ADDONS_CLASS_ID;
|
|
110
|
+
return this.classIdCache;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async search(query) {
|
|
114
|
+
const classId = await this.resolveClassId() ?? BEDROCK_ADDONS_CLASS_ID;
|
|
115
|
+
const q = {
|
|
116
|
+
gameId: this.gameId(),
|
|
117
|
+
classId,
|
|
118
|
+
searchFilter: query,
|
|
119
|
+
pageSize: this.cfg.pageSize,
|
|
120
|
+
sortField: 2,
|
|
121
|
+
sortOrder: "desc"
|
|
122
|
+
};
|
|
123
|
+
try {
|
|
124
|
+
const data2 = await this.apiGet("/v1/mods/search", q);
|
|
125
|
+
return mapHits(data2.data ?? []);
|
|
126
|
+
} catch (e) {
|
|
127
|
+
const msg = e.message || "";
|
|
128
|
+
if (!/HTTP 403/.test(msg)) throw e;
|
|
129
|
+
}
|
|
130
|
+
const data = await this.fetchJson(this.searchBase(), "/mods/search", q, {
|
|
131
|
+
requireKey: false,
|
|
132
|
+
label: "search-mirror"
|
|
133
|
+
});
|
|
134
|
+
return mapHits(data.data ?? []);
|
|
135
|
+
}
|
|
136
|
+
async resolveProject(ref) {
|
|
137
|
+
if (typeof ref === "number" || /^\d+$/.test(String(ref))) {
|
|
138
|
+
const id = Number(ref);
|
|
139
|
+
const data = await this.apiGet(`/v1/mods/${id}`, {});
|
|
140
|
+
const m = data.data;
|
|
141
|
+
if (!m) return null;
|
|
142
|
+
return mapHits([m])[0] ?? null;
|
|
143
|
+
}
|
|
144
|
+
const s = String(ref).trim();
|
|
145
|
+
const urlMatch = s.match(/curseforge\.com\/minecraft-bedrock\/[^/]+\/([^/?#]+)/i);
|
|
146
|
+
const slug = urlMatch?.[1] ?? s;
|
|
147
|
+
const hits = await this.search(slug);
|
|
148
|
+
return hits.find((h) => h.slug === slug) ?? hits[0] ?? null;
|
|
149
|
+
}
|
|
150
|
+
async getLatestFile(projectId) {
|
|
151
|
+
const data = await this.apiGet(`/v1/mods/${projectId}/files`, {
|
|
152
|
+
pageSize: 50
|
|
153
|
+
});
|
|
154
|
+
const files = [...data.data ?? []];
|
|
155
|
+
files.sort((a, b) => {
|
|
156
|
+
const ra = releaseRank(RELEASE_MAP[a.releaseType ?? 1], this.cfg.preferredReleaseTypes);
|
|
157
|
+
const rb = releaseRank(RELEASE_MAP[b.releaseType ?? 1], this.cfg.preferredReleaseTypes);
|
|
158
|
+
if (ra !== rb) return ra - rb;
|
|
159
|
+
const da = a.fileDate ? Date.parse(a.fileDate) : 0;
|
|
160
|
+
const db = b.fileDate ? Date.parse(b.fileDate) : 0;
|
|
161
|
+
return db - da;
|
|
162
|
+
});
|
|
163
|
+
const best = files[0];
|
|
164
|
+
if (!best) return null;
|
|
165
|
+
let downloadUrl = best.downloadUrl ?? "";
|
|
166
|
+
if (!downloadUrl) {
|
|
167
|
+
try {
|
|
168
|
+
const dl = await this.apiGet(
|
|
169
|
+
`/v1/mods/${projectId}/files/${best.id}/download-url`,
|
|
170
|
+
{}
|
|
171
|
+
);
|
|
172
|
+
downloadUrl = dl.data ?? "";
|
|
173
|
+
} catch {
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (!downloadUrl) {
|
|
177
|
+
let allowDist;
|
|
178
|
+
let slug = String(projectId);
|
|
179
|
+
try {
|
|
180
|
+
const mod = await this.apiGet(`/v1/mods/${projectId}`, {});
|
|
181
|
+
allowDist = mod.data?.allowModDistribution;
|
|
182
|
+
if (mod.data?.slug) slug = mod.data.slug;
|
|
183
|
+
} catch {
|
|
184
|
+
}
|
|
185
|
+
if (allowDist === false) {
|
|
186
|
+
throw new Error(
|
|
187
|
+
`CurseForge\u300C${slug}\u300D\u4F5C\u8005\u5173\u95ED\u4E86\u7B2C\u4E09\u65B9\u5206\u53D1\uFF08allowModDistribution=false\uFF09\uFF0CAPI \u65E0\u6CD5\u4E0B\u8F7D\u3002\u8BF7\u624B\u52A8\u4ECE https://www.curseforge.com/minecraft-bedrock/addons/${slug} \u4E0B\u8F7D\u540E\u653E\u5165 packs/inbox\uFF0C\u6216\u8054\u7CFB\u4F5C\u8005\u5F00\u542F\u5206\u53D1\u3002`
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
throw new Error(
|
|
191
|
+
`CurseForge \u65E0\u6CD5\u89E3\u6790\u4E0B\u8F7D\u5730\u5740\uFF08project=${projectId} file=${best.id}\uFF09\u3002\u82E5\u5B98\u65B9\u9875\u53EF\u4E0B\u800C\u6B64\u5904\u5931\u8D25\uFF0C\u591A\u534A\u662F\u4F5C\u8005\u9650\u5236\u4E86 API \u5206\u53D1\u3002`
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
const out = {
|
|
195
|
+
provider: "curseforge",
|
|
196
|
+
projectId,
|
|
197
|
+
fileId: best.id,
|
|
198
|
+
fileName: best.fileName,
|
|
199
|
+
displayName: best.displayName,
|
|
200
|
+
downloadUrl
|
|
201
|
+
};
|
|
202
|
+
if (best.fileDate) out.fileDate = best.fileDate;
|
|
203
|
+
const rt = RELEASE_MAP[best.releaseType ?? 1];
|
|
204
|
+
if (rt) out.releaseType = rt;
|
|
205
|
+
return out;
|
|
206
|
+
}
|
|
207
|
+
async download(file, destPath, onProgress) {
|
|
208
|
+
const bar = createTerminalProgress({
|
|
209
|
+
stream: process.stderr,
|
|
210
|
+
format: `\u4E0B\u8F7D ${file.fileName} | {bar} | {percentage}% | {value}/{total} MB | {speed}`
|
|
211
|
+
});
|
|
212
|
+
const onByteProgress = bindByteProgressToBar(bar, {
|
|
213
|
+
speedSampleMs: 250,
|
|
214
|
+
...onProgress ? { onProgress } : {}
|
|
215
|
+
});
|
|
216
|
+
try {
|
|
217
|
+
await httpDownload(file.downloadUrl, destPath, {
|
|
218
|
+
headers: this.headers(true),
|
|
219
|
+
onProgress: onByteProgress
|
|
220
|
+
});
|
|
221
|
+
} finally {
|
|
222
|
+
if (bar.active) bar.stop();
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
export {
|
|
227
|
+
CurseForgeBedrockProvider
|
|
228
|
+
};
|
|
229
|
+
//# sourceMappingURL=curseforge.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/pack-update/providers/curseforge.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * CurseForge Bedrock SourceProvider\n *\n * - \u5B98\u65B9 api.curseforge.com\uFF1AgetMod / files / download\uFF08\u9700 Studios x-api-key\uFF09\n * - \u641C\u7D22\uFF1A\u4F18\u5148\u5B98\u65B9\uFF1B\u82E5 403 \u5219\u56DE\u9000 api.curse.tools\uFF08\u90E8\u5206 key \u5BF9 /v1/mods/search \u88AB\u62D2\uFF09\n * - Bedrock gameId = 78022\uFF0CAddons classId = 4984\n * - \u4E0B\u8F7D\u8D70 bds-tools httpDownload\uFF08\u6D41\u5F0F\u843D\u76D8\uFF0C\u4E0E BDS \u66F4\u65B0\u540C\u4E00\u6743\u5A01 \u2014 DRY/DIP\uFF09\n */\nimport { bindByteProgressToBar, createTerminalProgress } from \"@sfmc-bds/sdk/logs\";\nimport { httpDownload } from \"../../http.js\";\nimport type {\n CurseForgeProviderConfig,\n PackReleaseType,\n PackSourceProvider,\n SourceFileRef,\n SourceSearchHit,\n} from \"../types.js\";\n\ninterface CfMod {\n id: number;\n name: string;\n slug: string;\n summary?: string;\n downloadCount?: number;\n links?: { websiteUrl?: string };\n classId?: number;\n /** \u4F5C\u8005\u662F\u5426\u5141\u8BB8\u7B2C\u4E09\u65B9/API \u5206\u53D1\uFF1Bfalse \u65F6 files[].downloadUrl \u6052\u4E3A null */\n allowModDistribution?: boolean;\n}\n\ninterface CfFile {\n id: number;\n displayName: string;\n fileName: string;\n downloadUrl?: string | null;\n fileDate?: string;\n releaseType?: number;\n fileStatus?: number;\n}\n\nconst RELEASE_MAP: Record<number, PackReleaseType> = {\n 1: \"release\",\n 2: \"beta\",\n 3: \"alpha\",\n};\n\n/** \u5386\u53F2\u9519\u8BEF\u9ED8\u8BA4\u503C \u2192 \u7EA0\u6B63\u4E3A Bedrock */\nconst LEGACY_BAD_GAME_IDS = new Set([459]);\nconst BEDROCK_GAME_ID = 78022;\nconst BEDROCK_ADDONS_CLASS_ID = 4984;\nconst DEFAULT_SEARCH_BASE = \"https://api.curse.tools/v1/cf\";\n\nfunction releaseRank(t: PackReleaseType | undefined, preferred: PackReleaseType[]): number {\n if (!t) return 999;\n const i = preferred.indexOf(t);\n return i >= 0 ? i : 100 + (t === \"release\" ? 0 : t === \"beta\" ? 1 : 2);\n}\n\nfunction mapHits(mods: CfMod[]): SourceSearchHit[] {\n return (mods ?? []).map((m) => {\n const hit: SourceSearchHit = {\n provider: \"curseforge\",\n projectId: m.id,\n slug: m.slug,\n name: m.name,\n summary: m.summary ?? \"\",\n websiteUrl: m.links?.websiteUrl ?? `https://www.curseforge.com/minecraft-bedrock/addons/${m.slug}`,\n };\n if (typeof m.downloadCount === \"number\") hit.downloadCount = m.downloadCount;\n return hit;\n });\n}\n\nexport class CurseForgeBedrockProvider implements PackSourceProvider {\n readonly id = \"curseforge\" as const;\n private classIdCache: number | null = null;\n\n constructor(private readonly cfg: CurseForgeProviderConfig) {}\n\n isConfigured(): boolean {\n return !!(this.cfg.enabled && this.cfg.apiKey?.trim());\n }\n\n private gameId(): number {\n const id = this.cfg.gameId;\n if (!id || LEGACY_BAD_GAME_IDS.has(id)) return BEDROCK_GAME_ID;\n return id;\n }\n\n private searchBase(): string {\n return (this.cfg.searchBaseUrl || DEFAULT_SEARCH_BASE).replace(/\\/$/, \"\");\n }\n\n private officialBase(): string {\n return this.cfg.baseUrl.replace(/\\/$/, \"\");\n }\n\n private headers(includeKey = true): Record<string, string> {\n const h: Record<string, string> = { Accept: \"application/json\" };\n if (includeKey && this.cfg.apiKey?.trim()) {\n h[\"x-api-key\"] = this.cfg.apiKey.trim();\n }\n return h;\n }\n\n private looksLikeLegacyUploadToken(key: string): boolean {\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(key.trim());\n }\n\n private buildUrl(\n base: string,\n pathname: string,\n query: Record<string, string | number | undefined>\n ): URL {\n const url = new URL(`${base}${pathname.startsWith(\"/\") ? pathname : `/${pathname}`}`);\n for (const [k, v] of Object.entries(query)) {\n if (v === undefined || v === null || v === \"\") continue;\n url.searchParams.set(k, String(v));\n }\n return url;\n }\n\n private async fetchJson<T>(\n base: string,\n pathname: string,\n query: Record<string, string | number | undefined>,\n opts?: { requireKey?: boolean; label?: string }\n ): Promise<T> {\n const requireKey = opts?.requireKey !== false;\n if (requireKey && !this.isConfigured()) {\n throw new Error(\"CurseForge API key \u672A\u914D\u7F6E\uFF08configs/pack-update.json \u6216 CURSEFORGE_API_KEY\uFF09\");\n }\n const key = this.cfg.apiKey.trim();\n const url = this.buildUrl(base, pathname, query);\n const res = await fetch(url, { headers: this.headers(requireKey || !!key) });\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n if (res.status === 403 && requireKey) {\n const hint = this.looksLikeLegacyUploadToken(key)\n ? \"\u5F53\u524D key \u50CF legacy Upload UUID Token\u3002\u8BF7\u5230 https://console.curseforge.com/ \u7533\u8BF7 Studios Key\u3002\"\n : \"\u82E5\u4EC5\u641C\u7D22\u5931\u8D25\uFF1A\u5B98\u65B9 /mods/search \u53EF\u80FD\u5BF9\u4F60\u7684 key \u8FD4\u56DE 403\uFF08\u5C06\u81EA\u52A8\u6539\u7528 curse.tools\uFF09\u3002\u5176\u5B83\u63A5\u53E3\u4ECD\u9700\u6709\u6548 Studios Key\u3002\";\n throw new Error(\n `CurseForge HTTP 403 (${opts?.label ?? pathname}): ${body.slice(0, 80).trim() || \"Forbidden\"} \u2014 ${hint}`\n );\n }\n throw new Error(`CurseForge HTTP ${res.status} (${opts?.label ?? pathname}): ${body.slice(0, 200)}`);\n }\n return (await res.json()) as T;\n }\n\n /** \u5B98\u65B9 Core API GET */\n private apiGet<T>(\n pathname: string,\n query: Record<string, string | number | undefined>\n ): Promise<T> {\n return this.fetchJson<T>(this.officialBase(), pathname, query, {\n requireKey: true,\n label: `official${pathname}`,\n });\n }\n\n async resolveClassId(): Promise<number | null> {\n if (this.cfg.classId != null) return this.cfg.classId;\n if (this.classIdCache != null) return this.classIdCache;\n try {\n const data = await this.apiGet<{ data: Array<{ id: number; name: string; isClass?: boolean }> }>(\n \"/v1/categories\",\n { gameId: this.gameId(), classesOnly: \"true\" }\n );\n const hit =\n data.data?.find((c) => /^addons?$/i.test(c.name)) ??\n data.data?.find((c) => /addon/i.test(c.name));\n this.classIdCache = hit?.id ?? BEDROCK_ADDONS_CLASS_ID;\n return this.classIdCache;\n } catch {\n this.classIdCache = BEDROCK_ADDONS_CLASS_ID;\n return this.classIdCache;\n }\n }\n\n async search(query: string): Promise<SourceSearchHit[]> {\n const classId = (await this.resolveClassId()) ?? BEDROCK_ADDONS_CLASS_ID;\n const q = {\n gameId: this.gameId(),\n classId,\n searchFilter: query,\n pageSize: this.cfg.pageSize,\n sortField: 2,\n sortOrder: \"desc\",\n };\n\n /* 1) \u5B98\u65B9\u641C\u7D22\uFF08\u90E8\u5206 Studios key \u4F1A\u5BF9 /mods/search \u6052 403\uFF09 */\n try {\n const data = await this.apiGet<{ data: CfMod[] }>(\"/v1/mods/search\", q);\n return mapHits(data.data ?? []);\n } catch (e) {\n const msg = (e as Error).message || \"\";\n if (!/HTTP 403/.test(msg)) throw e;\n }\n\n /* 2) curse.tools \u955C\u50CF\uFF08\u4E0E\u5B98\u65B9\u540C\u8DEF\u5F84\u7EA6\u5B9A\uFF09 */\n const data = await this.fetchJson<{ data: CfMod[] }>(this.searchBase(), \"/mods/search\", q, {\n requireKey: false,\n label: \"search-mirror\",\n });\n return mapHits(data.data ?? []);\n }\n\n async resolveProject(ref: string | number): Promise<SourceSearchHit | null> {\n if (typeof ref === \"number\" || /^\\d+$/.test(String(ref))) {\n const id = Number(ref);\n const data = await this.apiGet<{ data: CfMod }>(`/v1/mods/${id}`, {});\n const m = data.data;\n if (!m) return null;\n return mapHits([m])[0] ?? null;\n }\n const s = String(ref).trim();\n const urlMatch = s.match(/curseforge\\.com\\/minecraft-bedrock\\/[^/]+\\/([^/?#]+)/i);\n const slug = urlMatch?.[1] ?? s;\n const hits = await this.search(slug);\n return hits.find((h) => h.slug === slug) ?? hits[0] ?? null;\n }\n\n async getLatestFile(projectId: number): Promise<SourceFileRef | null> {\n const data = await this.apiGet<{ data: CfFile[] }>(`/v1/mods/${projectId}/files`, {\n pageSize: 50,\n });\n const files = [...(data.data ?? [])];\n files.sort((a, b) => {\n const ra = releaseRank(RELEASE_MAP[a.releaseType ?? 1], this.cfg.preferredReleaseTypes);\n const rb = releaseRank(RELEASE_MAP[b.releaseType ?? 1], this.cfg.preferredReleaseTypes);\n if (ra !== rb) return ra - rb;\n const da = a.fileDate ? Date.parse(a.fileDate) : 0;\n const db = b.fileDate ? Date.parse(b.fileDate) : 0;\n return db - da;\n });\n const best = files[0];\n if (!best) return null;\n let downloadUrl = best.downloadUrl ?? \"\";\n if (!downloadUrl) {\n try {\n const dl = await this.apiGet<{ data: string }>(\n `/v1/mods/${projectId}/files/${best.id}/download-url`,\n {}\n );\n downloadUrl = dl.data ?? \"\";\n } catch {\n /* \u4E0B\u65B9\u7EDF\u4E00\u8BCA\u65AD allowModDistribution */\n }\n }\n if (!downloadUrl) {\n /* \u4F5C\u8005\u5173\u95ED\u7B2C\u4E09\u65B9\u5206\u53D1\u65F6 downloadUrl \u4E3A\u7A7A\u4E14 download-url \u6052 403 \u2014 \u4E0E API key \u65E0\u5173 */\n let allowDist: boolean | undefined;\n let slug = String(projectId);\n try {\n const mod = await this.apiGet<{ data: CfMod }>(`/v1/mods/${projectId}`, {});\n allowDist = mod.data?.allowModDistribution;\n if (mod.data?.slug) slug = mod.data.slug;\n } catch {\n /* ignore */\n }\n if (allowDist === false) {\n throw new Error(\n `CurseForge\u300C${slug}\u300D\u4F5C\u8005\u5173\u95ED\u4E86\u7B2C\u4E09\u65B9\u5206\u53D1\uFF08allowModDistribution=false\uFF09\uFF0CAPI \u65E0\u6CD5\u4E0B\u8F7D\u3002` +\n `\u8BF7\u624B\u52A8\u4ECE https://www.curseforge.com/minecraft-bedrock/addons/${slug} \u4E0B\u8F7D\u540E\u653E\u5165 packs/inbox\uFF0C\u6216\u8054\u7CFB\u4F5C\u8005\u5F00\u542F\u5206\u53D1\u3002`\n );\n }\n throw new Error(\n `CurseForge \u65E0\u6CD5\u89E3\u6790\u4E0B\u8F7D\u5730\u5740\uFF08project=${projectId} file=${best.id}\uFF09\u3002` +\n `\u82E5\u5B98\u65B9\u9875\u53EF\u4E0B\u800C\u6B64\u5904\u5931\u8D25\uFF0C\u591A\u534A\u662F\u4F5C\u8005\u9650\u5236\u4E86 API \u5206\u53D1\u3002`\n );\n }\n const out: SourceFileRef = {\n provider: \"curseforge\",\n projectId,\n fileId: best.id,\n fileName: best.fileName,\n displayName: best.displayName,\n downloadUrl,\n };\n if (best.fileDate) out.fileDate = best.fileDate;\n const rt = RELEASE_MAP[best.releaseType ?? 1];\n if (rt) out.releaseType = rt;\n return out;\n }\n\n async download(\n file: SourceFileRef,\n destPath: string,\n onProgress?: (dl: number, total: number) => void\n ): Promise<void> {\n const bar = createTerminalProgress({\n stream: process.stderr,\n format: `\u4E0B\u8F7D ${file.fileName} | {bar} | {percentage}% | {value}/{total} MB | {speed}`,\n });\n const onByteProgress = bindByteProgressToBar(bar, {\n speedSampleMs: 250,\n ...(onProgress ? { onProgress } : {}),\n });\n try {\n await httpDownload(file.downloadUrl, destPath, {\n headers: this.headers(true),\n onProgress: onByteProgress,\n });\n } finally {\n if (bar.active) bar.stop();\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["data"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 源提供者注册表:按 id 构造 PackSourceProvider(OCP:新源加 case,不改编排层)。
|
|
3
|
+
*/
|
|
4
|
+
import type { PackProviderId, PackSourceProvider, PackUpdateConfig } from "../types.js";
|
|
5
|
+
import { CurseForgeBedrockProvider } from "./curseforge.js";
|
|
6
|
+
export declare function createPackSourceProvider(cfg: PackUpdateConfig, id?: PackProviderId): PackSourceProvider;
|
|
7
|
+
/** 短标签(列表 / i18n 共用;新源只改此处 — OCP) */
|
|
8
|
+
export declare function providerShortLabel(id: PackProviderId): string;
|
|
9
|
+
/**
|
|
10
|
+
* 解析已配置完备的源。
|
|
11
|
+
* - 指定 id:只检查该源
|
|
12
|
+
* - 未指定:按 providers 键顺序取第一个 isConfigured() 的源(入口勿再写死 curseforge — OCP/LSP)
|
|
13
|
+
*/
|
|
14
|
+
export declare function resolveConfiguredPackProvider(cfg: PackUpdateConfig, id?: PackProviderId): PackSourceProvider | null;
|
|
15
|
+
export { CurseForgeBedrockProvider };
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/pack-update/providers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACxF,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAE5D,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,gBAAgB,EACrB,EAAE,GAAE,cAA6B,GAChC,kBAAkB,CASpB;AAED,qCAAqC;AACrC,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,cAAc,GAAG,MAAM,CAS7D;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAC3C,GAAG,EAAE,gBAAgB,EACrB,EAAE,CAAC,EAAE,cAAc,GAClB,kBAAkB,GAAG,IAAI,CAU3B;AAED,OAAO,EAAE,yBAAyB,EAAE,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { CurseForgeBedrockProvider } from "./curseforge.js";
|
|
2
|
+
function createPackSourceProvider(cfg, id = "curseforge") {
|
|
3
|
+
switch (id) {
|
|
4
|
+
case "curseforge":
|
|
5
|
+
return new CurseForgeBedrockProvider(cfg.providers.curseforge);
|
|
6
|
+
default: {
|
|
7
|
+
const _exhaustive = id;
|
|
8
|
+
throw new Error(`\u672A\u77E5 pack \u6E90\u63D0\u4F9B\u8005: ${String(_exhaustive)}`);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function providerShortLabel(id) {
|
|
13
|
+
switch (id) {
|
|
14
|
+
case "curseforge":
|
|
15
|
+
return "cf";
|
|
16
|
+
default: {
|
|
17
|
+
const _exhaustive = id;
|
|
18
|
+
return String(_exhaustive);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function resolveConfiguredPackProvider(cfg, id) {
|
|
23
|
+
const candidates = id ? [id] : Object.keys(cfg.providers);
|
|
24
|
+
for (const pid of candidates) {
|
|
25
|
+
if (!(pid in cfg.providers)) continue;
|
|
26
|
+
const provider = createPackSourceProvider(cfg, pid);
|
|
27
|
+
if (provider.isConfigured()) return provider;
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
CurseForgeBedrockProvider,
|
|
33
|
+
createPackSourceProvider,
|
|
34
|
+
providerShortLabel,
|
|
35
|
+
resolveConfiguredPackProvider
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/pack-update/providers/index.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * \u6E90\u63D0\u4F9B\u8005\u6CE8\u518C\u8868\uFF1A\u6309 id \u6784\u9020 PackSourceProvider\uFF08OCP\uFF1A\u65B0\u6E90\u52A0 case\uFF0C\u4E0D\u6539\u7F16\u6392\u5C42\uFF09\u3002\n */\nimport type { PackProviderId, PackSourceProvider, PackUpdateConfig } from \"../types.js\";\nimport { CurseForgeBedrockProvider } from \"./curseforge.js\";\n\nexport function createPackSourceProvider(\n cfg: PackUpdateConfig,\n id: PackProviderId = \"curseforge\"\n): PackSourceProvider {\n switch (id) {\n case \"curseforge\":\n return new CurseForgeBedrockProvider(cfg.providers.curseforge);\n default: {\n const _exhaustive: never = id;\n throw new Error(`\u672A\u77E5 pack \u6E90\u63D0\u4F9B\u8005: ${String(_exhaustive)}`);\n }\n }\n}\n\n/** \u77ED\u6807\u7B7E\uFF08\u5217\u8868 / i18n \u5171\u7528\uFF1B\u65B0\u6E90\u53EA\u6539\u6B64\u5904 \u2014 OCP\uFF09 */\nexport function providerShortLabel(id: PackProviderId): string {\n switch (id) {\n case \"curseforge\":\n return \"cf\";\n default: {\n const _exhaustive: never = id;\n return String(_exhaustive);\n }\n }\n}\n\n/**\n * \u89E3\u6790\u5DF2\u914D\u7F6E\u5B8C\u5907\u7684\u6E90\u3002\n * - \u6307\u5B9A id\uFF1A\u53EA\u68C0\u67E5\u8BE5\u6E90\n * - \u672A\u6307\u5B9A\uFF1A\u6309 providers \u952E\u987A\u5E8F\u53D6\u7B2C\u4E00\u4E2A isConfigured() \u7684\u6E90\uFF08\u5165\u53E3\u52FF\u518D\u5199\u6B7B curseforge \u2014 OCP/LSP\uFF09\n */\nexport function resolveConfiguredPackProvider(\n cfg: PackUpdateConfig,\n id?: PackProviderId\n): PackSourceProvider | null {\n const candidates: PackProviderId[] = id\n ? [id]\n : (Object.keys(cfg.providers) as PackProviderId[]);\n for (const pid of candidates) {\n if (!(pid in cfg.providers)) continue;\n const provider = createPackSourceProvider(cfg, pid);\n if (provider.isConfigured()) return provider;\n }\n return null;\n}\n\nexport { CurseForgeBedrockProvider };\n"],
|
|
5
|
+
"mappings": "AAIA,SAAS,iCAAiC;AAEnC,SAAS,yBACd,KACA,KAAqB,cACD;AACpB,UAAQ,IAAI;AAAA,IACV,KAAK;AACH,aAAO,IAAI,0BAA0B,IAAI,UAAU,UAAU;AAAA,IAC/D,SAAS;AACP,YAAM,cAAqB;AAC3B,YAAM,IAAI,MAAM,+CAAiB,OAAO,WAAW,CAAC,EAAE;AAAA,IACxD;AAAA,EACF;AACF;AAGO,SAAS,mBAAmB,IAA4B;AAC7D,UAAQ,IAAI;AAAA,IACV,KAAK;AACH,aAAO;AAAA,IACT,SAAS;AACP,YAAM,cAAqB;AAC3B,aAAO,OAAO,WAAW;AAAA,IAC3B;AAAA,EACF;AACF;AAOO,SAAS,8BACd,KACA,IAC2B;AAC3B,QAAM,aAA+B,KACjC,CAAC,EAAE,IACF,OAAO,KAAK,IAAI,SAAS;AAC9B,aAAW,OAAO,YAAY;AAC5B,QAAI,EAAE,OAAO,IAAI,WAAY;AAC7B,UAAM,WAAW,yBAAyB,KAAK,GAAG;AAClD,QAAI,SAAS,aAAa,EAAG,QAAO;AAAA,EACtC;AACA,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pack-update 编排:探测绑定 / 检查 / 应用更新
|
|
3
|
+
*/
|
|
4
|
+
import { type PackManifestInfo } from "../world-packs.js";
|
|
5
|
+
import type { PackUpdateBindingsApi } from "./bindings.js";
|
|
6
|
+
import type { PackUpdateConfigApi } from "./config.js";
|
|
7
|
+
import type { PackUpdateDeps } from "./deps.js";
|
|
8
|
+
export declare function createPackUpdateServiceApi(deps: PackUpdateDeps, config: PackUpdateConfigApi, bindings: PackUpdateBindingsApi): {
|
|
9
|
+
pairedRpUuidFromBpDir: (bpDir: string) => string | null;
|
|
10
|
+
probeSourceAfterInstall: (opts: {
|
|
11
|
+
info: PackManifestInfo;
|
|
12
|
+
packDir?: string;
|
|
13
|
+
/** 安装后的文件夹名(优先于 basename(packDir)) */
|
|
14
|
+
folderName?: string;
|
|
15
|
+
interactive?: boolean;
|
|
16
|
+
}) => Promise<void>;
|
|
17
|
+
searchRemote: (query: string) => Promise<string>;
|
|
18
|
+
bindPackSource: (packId: string, ref: string) => Promise<string>;
|
|
19
|
+
formatSourcesList: () => string;
|
|
20
|
+
checkPackUpdates: (opts?: {
|
|
21
|
+
packId?: string;
|
|
22
|
+
apply?: boolean;
|
|
23
|
+
}) => Promise<string>;
|
|
24
|
+
runPackUpdatesOnBdsStart: () => Promise<void>;
|
|
25
|
+
bindingLabelForUuid: (uuid: string) => string;
|
|
26
|
+
};
|
|
27
|
+
export type PackUpdateServiceApi = ReturnType<typeof createPackUpdateServiceApi>;
|
|
28
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/pack-update/service.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAWL,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;AAI3B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAoBhD,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,mBAAmB,EAC3B,QAAQ,EAAE,qBAAqB;mCAgGO,MAAM,KAAG,MAAM,GAAG,IAAI;oCAKf;QAC3C,IAAI,EAAE,gBAAgB,CAAC;QACvB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,sCAAsC;QACtC,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,OAAO,CAAC;KACvB,KAAG,OAAO,CAAC,IAAI,CAAC;0BAqHkB,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;6BAkBrB,MAAM,OAAO,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;6BAkC7C,MAAM;8BAoVG;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,KAAG,OAAO,CAAC,MAAM,CAAC;oCAuDlD,OAAO,CAAC,IAAI,CAAC;gCAWrB,MAAM,KAAG,MAAM;EAkBnD;AAED,MAAM,MAAM,oBAAoB,GAAG,UAAU,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
|