hot-updater 0.31.0 → 0.31.1
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/index.mjs +303 -4
- package/package.json +14 -14
package/dist/index.mjs
CHANGED
|
@@ -49715,6 +49715,9 @@ const INFRASTRUCTURE_RECOVERY_COMMANDS = [
|
|
|
49715
49715
|
"hot-updater db migrate",
|
|
49716
49716
|
"hot-updater db generate"
|
|
49717
49717
|
];
|
|
49718
|
+
const FINGERPRINT_RECOVERY_COMMANDS = ["npx hot-updater fingerprint create"];
|
|
49719
|
+
const EXPORT_PUBLIC_KEY_COMMANDS = ["npx hot-updater keys export-public"];
|
|
49720
|
+
const REMOVE_PUBLIC_KEY_COMMANDS = ["npx hot-updater keys remove"];
|
|
49718
49721
|
const INFRASTRUCTURE_UPDATE_TARGETS = [
|
|
49719
49722
|
{
|
|
49720
49723
|
version: "0.13.0",
|
|
@@ -49780,7 +49783,267 @@ function resolveVersionEndpoint(serverBaseUrl) {
|
|
|
49780
49783
|
url.pathname = `${pathname}/version`;
|
|
49781
49784
|
return url.toString();
|
|
49782
49785
|
}
|
|
49783
|
-
const createInfrastructureRemediation = () => ({
|
|
49786
|
+
const createInfrastructureRemediation = () => ({
|
|
49787
|
+
fixability: "blocked",
|
|
49788
|
+
reason: "Server infrastructure changes usually need provider credentials, environment variables, and redeploy access.",
|
|
49789
|
+
commands: [...INFRASTRUCTURE_RECOVERY_COMMANDS]
|
|
49790
|
+
});
|
|
49791
|
+
const toRelativePath = (cwd, filePath) => path$1.relative(cwd, filePath);
|
|
49792
|
+
const resolveProjectPath = (cwd, filePath) => path$1.isAbsolute(filePath) ? filePath : path$1.join(cwd, filePath);
|
|
49793
|
+
const findNativeFiles = ({ cwd, platform, pattern }) => {
|
|
49794
|
+
const platformRoot = path$1.join(cwd, platform);
|
|
49795
|
+
if (!fs$2.existsSync(platformRoot)) return [];
|
|
49796
|
+
return import_out.default.sync(pattern, {
|
|
49797
|
+
cwd: platformRoot,
|
|
49798
|
+
absolute: true,
|
|
49799
|
+
onlyFiles: true,
|
|
49800
|
+
ignore: [
|
|
49801
|
+
"**/Pods/**",
|
|
49802
|
+
"**/build/**",
|
|
49803
|
+
"**/Build/**",
|
|
49804
|
+
"**/*.app/**",
|
|
49805
|
+
"**/*.xcarchive/**"
|
|
49806
|
+
]
|
|
49807
|
+
}).map((filePath) => toRelativePath(cwd, filePath)).sort();
|
|
49808
|
+
};
|
|
49809
|
+
const findFirstMatchingFile = async ({ cwd, files, patterns }) => {
|
|
49810
|
+
for (const filePath of files) {
|
|
49811
|
+
const absolutePath = resolveProjectPath(cwd, filePath);
|
|
49812
|
+
const content = await fs$2.promises.readFile(absolutePath, "utf-8");
|
|
49813
|
+
if (patterns.some((pattern) => pattern.test(content))) return filePath;
|
|
49814
|
+
}
|
|
49815
|
+
return null;
|
|
49816
|
+
};
|
|
49817
|
+
const readLocalFingerprintFile = async (cwd) => {
|
|
49818
|
+
const fingerprintJsonPath = path$1.join(cwd, "fingerprint.json");
|
|
49819
|
+
try {
|
|
49820
|
+
const content = await fs$2.promises.readFile(fingerprintJsonPath, "utf-8");
|
|
49821
|
+
return {
|
|
49822
|
+
path: "fingerprint.json",
|
|
49823
|
+
value: JSON.parse(content)
|
|
49824
|
+
};
|
|
49825
|
+
} catch {
|
|
49826
|
+
return null;
|
|
49827
|
+
}
|
|
49828
|
+
};
|
|
49829
|
+
const checkIosNativeStatus = async ({ cwd, config, requireFingerprint, expectedFingerprintHash }) => {
|
|
49830
|
+
const configuredPaths = config.platform.ios.infoPlistPaths;
|
|
49831
|
+
if (!(fs$2.existsSync(path$1.join(cwd, "ios")) || configuredPaths.length > 0)) return { issues: [] };
|
|
49832
|
+
const iosParser = new IosConfigParser(configuredPaths);
|
|
49833
|
+
const files = configuredPaths.filter((filePath) => fs$2.existsSync(resolveProjectPath(cwd, filePath)));
|
|
49834
|
+
const issues = [];
|
|
49835
|
+
if (!await iosParser.exists()) issues.push({
|
|
49836
|
+
type: "error",
|
|
49837
|
+
platform: "ios",
|
|
49838
|
+
code: "NATIVE_FILES_NOT_FOUND",
|
|
49839
|
+
message: "iOS Info.plist files were not found.",
|
|
49840
|
+
resolution: "Check platform.ios.infoPlistPaths in hot-updater.config.ts or run iOS prebuild first.",
|
|
49841
|
+
fixability: "auto",
|
|
49842
|
+
paths: configuredPaths
|
|
49843
|
+
});
|
|
49844
|
+
const channel = await iosParser.get("HOT_UPDATER_CHANNEL");
|
|
49845
|
+
const fingerprintHash = requireFingerprint ? await iosParser.get("HOT_UPDATER_FINGERPRINT_HASH") : void 0;
|
|
49846
|
+
if (requireFingerprint && !fingerprintHash?.value) issues.push({
|
|
49847
|
+
type: "error",
|
|
49848
|
+
platform: "ios",
|
|
49849
|
+
code: "MISSING_FINGERPRINT_HASH",
|
|
49850
|
+
message: "HOT_UPDATER_FINGERPRINT_HASH is missing from Info.plist.",
|
|
49851
|
+
resolution: "Run `npx hot-updater fingerprint create` or rebuild through the Expo config plugin.",
|
|
49852
|
+
fixability: "command",
|
|
49853
|
+
commands: [...FINGERPRINT_RECOVERY_COMMANDS],
|
|
49854
|
+
paths: fingerprintHash?.paths.length ? fingerprintHash.paths : files
|
|
49855
|
+
});
|
|
49856
|
+
else if (requireFingerprint && expectedFingerprintHash && fingerprintHash?.value !== expectedFingerprintHash) issues.push({
|
|
49857
|
+
type: "error",
|
|
49858
|
+
platform: "ios",
|
|
49859
|
+
code: "FINGERPRINT_HASH_MISMATCH",
|
|
49860
|
+
message: "HOT_UPDATER_FINGERPRINT_HASH does not match fingerprint.json.",
|
|
49861
|
+
resolution: "Run `npx hot-updater fingerprint create` and rebuild your iOS app.",
|
|
49862
|
+
fixability: "command",
|
|
49863
|
+
commands: [...FINGERPRINT_RECOVERY_COMMANDS],
|
|
49864
|
+
paths: fingerprintHash?.paths ?? files
|
|
49865
|
+
});
|
|
49866
|
+
const appDelegateFiles = findNativeFiles({
|
|
49867
|
+
cwd,
|
|
49868
|
+
platform: "ios",
|
|
49869
|
+
pattern: "**/AppDelegate.{swift,mm,m}"
|
|
49870
|
+
});
|
|
49871
|
+
let bundleProviderConfigured = false;
|
|
49872
|
+
if (appDelegateFiles.length === 0) issues.push({
|
|
49873
|
+
type: "error",
|
|
49874
|
+
platform: "ios",
|
|
49875
|
+
code: "APP_DELEGATE_NOT_FOUND",
|
|
49876
|
+
message: "iOS AppDelegate file was not found.",
|
|
49877
|
+
resolution: "Add HotUpdater.bundleURL() to the app's iOS bundleURL provider.",
|
|
49878
|
+
fixability: "auto"
|
|
49879
|
+
});
|
|
49880
|
+
else {
|
|
49881
|
+
bundleProviderConfigured = await findFirstMatchingFile({
|
|
49882
|
+
cwd,
|
|
49883
|
+
files: appDelegateFiles,
|
|
49884
|
+
patterns: [/HotUpdater\.bundleURL\s*\(/, /\[HotUpdater\s+bundleURL(?:WithBundle)?:?/]
|
|
49885
|
+
}) !== null;
|
|
49886
|
+
if (!bundleProviderConfigured) issues.push({
|
|
49887
|
+
type: "error",
|
|
49888
|
+
platform: "ios",
|
|
49889
|
+
code: "MISSING_IOS_BUNDLE_PROVIDER",
|
|
49890
|
+
message: "iOS AppDelegate does not use HotUpdater.bundleURL().",
|
|
49891
|
+
resolution: "Replace the release JS bundle URL provider with HotUpdater.bundleURL().",
|
|
49892
|
+
fixability: "auto",
|
|
49893
|
+
paths: appDelegateFiles
|
|
49894
|
+
});
|
|
49895
|
+
}
|
|
49896
|
+
return {
|
|
49897
|
+
status: {
|
|
49898
|
+
detected: true,
|
|
49899
|
+
files: [...files, ...appDelegateFiles],
|
|
49900
|
+
channel: channel.value ?? void 0,
|
|
49901
|
+
fingerprintHash: fingerprintHash?.value ?? void 0,
|
|
49902
|
+
bundleProviderConfigured
|
|
49903
|
+
},
|
|
49904
|
+
issues
|
|
49905
|
+
};
|
|
49906
|
+
};
|
|
49907
|
+
const checkAndroidNativeStatus = async ({ cwd, config, requireFingerprint, expectedFingerprintHash }) => {
|
|
49908
|
+
const configuredPaths = config.platform.android.stringResourcePaths;
|
|
49909
|
+
if (!(fs$2.existsSync(path$1.join(cwd, "android")) || configuredPaths.length > 0)) return { issues: [] };
|
|
49910
|
+
const androidParser = new AndroidConfigParser(configuredPaths);
|
|
49911
|
+
const files = configuredPaths.filter((filePath) => fs$2.existsSync(resolveProjectPath(cwd, filePath)));
|
|
49912
|
+
const issues = [];
|
|
49913
|
+
if (!await androidParser.exists()) issues.push({
|
|
49914
|
+
type: "error",
|
|
49915
|
+
platform: "android",
|
|
49916
|
+
code: "NATIVE_FILES_NOT_FOUND",
|
|
49917
|
+
message: "Android strings.xml files were not found.",
|
|
49918
|
+
resolution: "Check platform.android.stringResourcePaths in hot-updater.config.ts or run Android prebuild first.",
|
|
49919
|
+
fixability: "auto",
|
|
49920
|
+
paths: configuredPaths
|
|
49921
|
+
});
|
|
49922
|
+
const channel = await androidParser.get("hot_updater_channel");
|
|
49923
|
+
const fingerprintHash = requireFingerprint ? await androidParser.get("hot_updater_fingerprint_hash") : void 0;
|
|
49924
|
+
if (requireFingerprint && !fingerprintHash?.value) issues.push({
|
|
49925
|
+
type: "error",
|
|
49926
|
+
platform: "android",
|
|
49927
|
+
code: "MISSING_FINGERPRINT_HASH",
|
|
49928
|
+
message: "hot_updater_fingerprint_hash is missing from strings.xml.",
|
|
49929
|
+
resolution: "Run `npx hot-updater fingerprint create` or rebuild through the Expo config plugin.",
|
|
49930
|
+
fixability: "command",
|
|
49931
|
+
commands: [...FINGERPRINT_RECOVERY_COMMANDS],
|
|
49932
|
+
paths: fingerprintHash?.paths.length ? fingerprintHash.paths : files
|
|
49933
|
+
});
|
|
49934
|
+
else if (requireFingerprint && expectedFingerprintHash && fingerprintHash?.value !== expectedFingerprintHash) issues.push({
|
|
49935
|
+
type: "error",
|
|
49936
|
+
platform: "android",
|
|
49937
|
+
code: "FINGERPRINT_HASH_MISMATCH",
|
|
49938
|
+
message: "hot_updater_fingerprint_hash does not match fingerprint.json.",
|
|
49939
|
+
resolution: "Run `npx hot-updater fingerprint create` and rebuild your Android app.",
|
|
49940
|
+
fixability: "command",
|
|
49941
|
+
commands: [...FINGERPRINT_RECOVERY_COMMANDS],
|
|
49942
|
+
paths: fingerprintHash?.paths ?? files
|
|
49943
|
+
});
|
|
49944
|
+
const mainApplicationFiles = findNativeFiles({
|
|
49945
|
+
cwd,
|
|
49946
|
+
platform: "android",
|
|
49947
|
+
pattern: "**/MainApplication.{kt,java}"
|
|
49948
|
+
});
|
|
49949
|
+
let bundleProviderConfigured = false;
|
|
49950
|
+
if (mainApplicationFiles.length === 0) issues.push({
|
|
49951
|
+
type: "error",
|
|
49952
|
+
platform: "android",
|
|
49953
|
+
code: "MAIN_APPLICATION_NOT_FOUND",
|
|
49954
|
+
message: "Android MainApplication file was not found.",
|
|
49955
|
+
resolution: "Add HotUpdater.getJSBundleFile(applicationContext) to the Android host configuration.",
|
|
49956
|
+
fixability: "auto"
|
|
49957
|
+
});
|
|
49958
|
+
else {
|
|
49959
|
+
bundleProviderConfigured = await findFirstMatchingFile({
|
|
49960
|
+
cwd,
|
|
49961
|
+
files: mainApplicationFiles,
|
|
49962
|
+
patterns: [/HotUpdater\s*(?:\.\s*Companion\s*)?\.\s*getJSBundleFile\s*\(/]
|
|
49963
|
+
}) !== null;
|
|
49964
|
+
if (!bundleProviderConfigured) issues.push({
|
|
49965
|
+
type: "error",
|
|
49966
|
+
platform: "android",
|
|
49967
|
+
code: "MISSING_ANDROID_BUNDLE_PROVIDER",
|
|
49968
|
+
message: "Android MainApplication does not use HotUpdater.getJSBundleFile().",
|
|
49969
|
+
resolution: "Pass HotUpdater.getJSBundleFile(applicationContext) to React Native's JS bundle provider.",
|
|
49970
|
+
fixability: "auto",
|
|
49971
|
+
paths: mainApplicationFiles
|
|
49972
|
+
});
|
|
49973
|
+
}
|
|
49974
|
+
return {
|
|
49975
|
+
status: {
|
|
49976
|
+
detected: true,
|
|
49977
|
+
files: [...files, ...mainApplicationFiles],
|
|
49978
|
+
channel: channel.value ?? void 0,
|
|
49979
|
+
fingerprintHash: fingerprintHash?.value ?? void 0,
|
|
49980
|
+
bundleProviderConfigured
|
|
49981
|
+
},
|
|
49982
|
+
issues
|
|
49983
|
+
};
|
|
49984
|
+
};
|
|
49985
|
+
const toNativeIssue = (issue) => {
|
|
49986
|
+
if (issue.code === "NATIVE_FILES_NOT_FOUND") return {
|
|
49987
|
+
type: issue.type,
|
|
49988
|
+
platform: issue.platform,
|
|
49989
|
+
code: issue.code,
|
|
49990
|
+
message: issue.message,
|
|
49991
|
+
resolution: issue.resolution,
|
|
49992
|
+
fixability: "auto"
|
|
49993
|
+
};
|
|
49994
|
+
return {
|
|
49995
|
+
type: issue.type,
|
|
49996
|
+
platform: issue.platform,
|
|
49997
|
+
code: issue.code,
|
|
49998
|
+
message: issue.message,
|
|
49999
|
+
resolution: issue.resolution,
|
|
50000
|
+
fixability: "command",
|
|
50001
|
+
commands: issue.code === "ORPHAN_PUBLIC_KEY" ? [...REMOVE_PUBLIC_KEY_COMMANDS] : [...EXPORT_PUBLIC_KEY_COMMANDS]
|
|
50002
|
+
};
|
|
50003
|
+
};
|
|
50004
|
+
async function checkNativeStatus({ cwd }) {
|
|
50005
|
+
if (!(fs$2.existsSync(path$1.join(cwd, "ios")) || fs$2.existsSync(path$1.join(cwd, "android")))) return;
|
|
50006
|
+
const config = await loadConfig(null);
|
|
50007
|
+
const localFingerprint = await readLocalFingerprintFile(cwd);
|
|
50008
|
+
const requireFingerprint = config.updateStrategy === "fingerprint";
|
|
50009
|
+
const [ios, android, signing] = await Promise.all([
|
|
50010
|
+
checkIosNativeStatus({
|
|
50011
|
+
cwd,
|
|
50012
|
+
config,
|
|
50013
|
+
requireFingerprint,
|
|
50014
|
+
expectedFingerprintHash: localFingerprint?.value.ios?.hash
|
|
50015
|
+
}),
|
|
50016
|
+
checkAndroidNativeStatus({
|
|
50017
|
+
cwd,
|
|
50018
|
+
config,
|
|
50019
|
+
requireFingerprint,
|
|
50020
|
+
expectedFingerprintHash: localFingerprint?.value.android?.hash
|
|
50021
|
+
}),
|
|
50022
|
+
validateSigningConfig(config)
|
|
50023
|
+
]);
|
|
50024
|
+
const issues = [
|
|
50025
|
+
...ios.issues,
|
|
50026
|
+
...android.issues,
|
|
50027
|
+
...signing.issues.map(toNativeIssue)
|
|
50028
|
+
];
|
|
50029
|
+
if (requireFingerprint && !localFingerprint) issues.push({
|
|
50030
|
+
type: "error",
|
|
50031
|
+
platform: "project",
|
|
50032
|
+
code: "MISSING_FINGERPRINT_JSON",
|
|
50033
|
+
message: "fingerprint.json is missing for fingerprint update strategy.",
|
|
50034
|
+
resolution: "Run `npx hot-updater fingerprint create`.",
|
|
50035
|
+
fixability: "command",
|
|
50036
|
+
commands: [...FINGERPRINT_RECOVERY_COMMANDS],
|
|
50037
|
+
paths: ["fingerprint.json"]
|
|
50038
|
+
});
|
|
50039
|
+
return {
|
|
50040
|
+
updateStrategy: config.updateStrategy,
|
|
50041
|
+
fingerprintJsonPath: localFingerprint?.path,
|
|
50042
|
+
ios: ios.status,
|
|
50043
|
+
android: android.status,
|
|
50044
|
+
issues
|
|
50045
|
+
};
|
|
50046
|
+
}
|
|
49784
50047
|
async function checkInfrastructureStatus({ serverBaseUrl, fetchImpl = fetch, requiredVersion = getRequiredInfrastructureVersion() }) {
|
|
49785
50048
|
const versionEndpoint = resolveVersionEndpoint(serverBaseUrl);
|
|
49786
50049
|
const baseUrl = serverBaseUrl.trim();
|
|
@@ -49850,6 +50113,7 @@ async function doctor(options = {}) {
|
|
|
49850
50113
|
error: "hot-updater CLI not found. Please install it first."
|
|
49851
50114
|
};
|
|
49852
50115
|
const hotUpdaterPackages = Object.keys(allDependencies).filter((key) => key.startsWith("@hot-updater/"));
|
|
50116
|
+
const hasReactNativePackage = allDependencies["@hot-updater/react-native"] !== void 0;
|
|
49853
50117
|
const versionMismatches = [];
|
|
49854
50118
|
for (const packageName of hotUpdaterPackages) {
|
|
49855
50119
|
const currentVersion = allDependencies[packageName];
|
|
@@ -49872,9 +50136,11 @@ async function doctor(options = {}) {
|
|
|
49872
50136
|
});
|
|
49873
50137
|
if (details.infrastructure.error !== void 0 || details.infrastructure.needsUpdate === true) details.infrastructure.remediation = createInfrastructureRemediation();
|
|
49874
50138
|
}
|
|
50139
|
+
if (hasReactNativePackage) details.native = await checkNativeStatus({ cwd });
|
|
49875
50140
|
if (versionMismatches.length > 0) details.versionMismatches = versionMismatches;
|
|
49876
50141
|
const hasInfrastructureIssue = details.infrastructure?.error !== void 0 || details.infrastructure?.needsUpdate === true;
|
|
49877
|
-
|
|
50142
|
+
const hasNativeIssue = details.native?.issues.some((issue) => issue.type === "error") === true;
|
|
50143
|
+
if (versionMismatches.length > 0 || hasInfrastructureIssue || hasNativeIssue) return {
|
|
49878
50144
|
success: false,
|
|
49879
50145
|
details
|
|
49880
50146
|
};
|
|
@@ -49882,6 +50148,10 @@ async function doctor(options = {}) {
|
|
|
49882
50148
|
success: true,
|
|
49883
50149
|
details
|
|
49884
50150
|
};
|
|
50151
|
+
if (details.native) return {
|
|
50152
|
+
success: true,
|
|
50153
|
+
details
|
|
50154
|
+
};
|
|
49885
50155
|
return true;
|
|
49886
50156
|
} catch (error) {
|
|
49887
50157
|
return {
|
|
@@ -49890,6 +50160,10 @@ async function doctor(options = {}) {
|
|
|
49890
50160
|
};
|
|
49891
50161
|
}
|
|
49892
50162
|
}
|
|
50163
|
+
const normalizeDoctorResult = (result) => {
|
|
50164
|
+
if (result === true) return { success: true };
|
|
50165
|
+
return result;
|
|
50166
|
+
};
|
|
49893
50167
|
const promptServerBaseUrl = async () => {
|
|
49894
50168
|
if (!process.stdin.isTTY || !process.stdout.isTTY) return;
|
|
49895
50169
|
const serverBaseUrl = await p.text({
|
|
@@ -49912,7 +50186,13 @@ const promptServerBaseUrl = async () => {
|
|
|
49912
50186
|
const trimmed = serverBaseUrl.trim();
|
|
49913
50187
|
return trimmed ? trimmed : void 0;
|
|
49914
50188
|
};
|
|
49915
|
-
const handleDoctor = async ({ serverBaseUrl } = {}) => {
|
|
50189
|
+
const handleDoctor = async ({ serverBaseUrl, json = false } = {}) => {
|
|
50190
|
+
if (json) {
|
|
50191
|
+
const result = normalizeDoctorResult(await doctor({ serverBaseUrl }));
|
|
50192
|
+
console.log(JSON.stringify(result, null, 2));
|
|
50193
|
+
if (!result.success) process.exit(1);
|
|
50194
|
+
return;
|
|
50195
|
+
}
|
|
49916
50196
|
p.intro("Hot Updater doctor");
|
|
49917
50197
|
const result = await doctor({ serverBaseUrl: serverBaseUrl ?? await promptServerBaseUrl() });
|
|
49918
50198
|
if (result === true) {
|
|
@@ -49948,6 +50228,25 @@ const handleDoctor = async ({ serverBaseUrl } = {}) => {
|
|
|
49948
50228
|
"then redeploy server"
|
|
49949
50229
|
]))]));
|
|
49950
50230
|
}
|
|
50231
|
+
if (details?.native) {
|
|
50232
|
+
const native = details.native;
|
|
50233
|
+
const lines = [ui.kv("Strategy", native.updateStrategy)];
|
|
50234
|
+
if (native.ios?.detected) {
|
|
50235
|
+
lines.push(ui.kv("iOS", native.ios.bundleProviderConfigured ? ui.status(true) : ui.status(false)));
|
|
50236
|
+
if (native.ios.channel) lines.push(ui.kv("iOS channel", ui.channel(native.ios.channel)));
|
|
50237
|
+
}
|
|
50238
|
+
if (native.android?.detected) {
|
|
50239
|
+
lines.push(ui.kv("Android", native.android.bundleProviderConfigured ? ui.status(true) : ui.status(false)));
|
|
50240
|
+
if (native.android.channel) lines.push(ui.kv("Android channel", ui.channel(native.android.channel)));
|
|
50241
|
+
}
|
|
50242
|
+
p.log.message(ui.block("Native", lines));
|
|
50243
|
+
for (const issue of native.issues) {
|
|
50244
|
+
const message = `${issue.platform}: ${issue.message}`;
|
|
50245
|
+
if (issue.type === "error") p.log.error(message);
|
|
50246
|
+
else p.log.warn(message);
|
|
50247
|
+
p.log.info(issue.resolution);
|
|
50248
|
+
}
|
|
50249
|
+
}
|
|
49951
50250
|
if (details?.versionMismatches && details.versionMismatches.length > 0) {
|
|
49952
50251
|
p.log.warn("Version mismatches found:");
|
|
49953
50252
|
for (const mismatch of details.versionMismatches) p.log.error(`${mismatch.packageName}: ${mismatch.currentVersion} (expected ${mismatch.expectedVersion})`);
|
|
@@ -51250,7 +51549,7 @@ const parseRolloutCohortCount = (value) => {
|
|
|
51250
51549
|
const program = new Command();
|
|
51251
51550
|
program.name("hot-updater").description(banner(version)).version(version);
|
|
51252
51551
|
program.command("init").description("Initialize Hot Updater").action(init);
|
|
51253
|
-
program.command("doctor").description("Check the health of Hot Updater").option("--server-base-url <url>", "server base URL used by update checks (doctor appends /version)").action(handleDoctor);
|
|
51552
|
+
program.command("doctor").description("Check the health of Hot Updater").option("--server-base-url <url>", "server base URL used by update checks (doctor appends /version)").option("--json", "output machine-readable doctor result").action(handleDoctor);
|
|
51254
51553
|
const fingerprintCommand = program.command("fingerprint").description("Generate fingerprint");
|
|
51255
51554
|
fingerprintCommand.action(handleFingerprint);
|
|
51256
51555
|
fingerprintCommand.command("create").description("Create fingerprint").action(handleCreateFingerprint);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hot-updater",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.31.
|
|
4
|
+
"version": "0.31.1",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20.19.0"
|
|
7
7
|
},
|
|
@@ -49,13 +49,13 @@
|
|
|
49
49
|
"jiti": "2.6.1",
|
|
50
50
|
"kysely": "0.28.16",
|
|
51
51
|
"sql-formatter": "15.6.10",
|
|
52
|
-
"@hot-updater/
|
|
53
|
-
"@hot-updater/
|
|
54
|
-
"@hot-updater/
|
|
55
|
-
"@hot-updater/core": "0.31.
|
|
56
|
-
"@hot-updater/
|
|
57
|
-
"@hot-updater/
|
|
58
|
-
"@hot-updater/server": "0.31.
|
|
52
|
+
"@hot-updater/android-helper": "0.31.1",
|
|
53
|
+
"@hot-updater/apple-helper": "0.31.1",
|
|
54
|
+
"@hot-updater/cli-tools": "0.31.1",
|
|
55
|
+
"@hot-updater/plugin-core": "0.31.1",
|
|
56
|
+
"@hot-updater/core": "0.31.1",
|
|
57
|
+
"@hot-updater/console": "0.31.1",
|
|
58
|
+
"@hot-updater/server": "0.31.1"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@bacons/xcode": "1.0.0-alpha.24",
|
|
@@ -74,12 +74,12 @@
|
|
|
74
74
|
"plist": "^3.1.0",
|
|
75
75
|
"semver": "^7.6.3",
|
|
76
76
|
"typescript": "6.0.2",
|
|
77
|
-
"@hot-updater/aws": "0.31.
|
|
78
|
-
"@hot-updater/cloudflare": "0.31.
|
|
79
|
-
"@hot-updater/firebase": "0.31.
|
|
80
|
-
"@hot-updater/server": "0.31.
|
|
81
|
-
"@hot-updater/supabase": "0.31.
|
|
82
|
-
"@hot-updater/test-utils": "0.31.
|
|
77
|
+
"@hot-updater/aws": "0.31.1",
|
|
78
|
+
"@hot-updater/cloudflare": "0.31.1",
|
|
79
|
+
"@hot-updater/firebase": "0.31.1",
|
|
80
|
+
"@hot-updater/server": "0.31.1",
|
|
81
|
+
"@hot-updater/supabase": "0.31.1",
|
|
82
|
+
"@hot-updater/test-utils": "0.31.1"
|
|
83
83
|
},
|
|
84
84
|
"peerDependencies": {
|
|
85
85
|
"@hot-updater/aws": "*",
|