feat(catalog-sync): report sources that can only be compared, not imported
CI / check (push) Successful in 47s
CI / tests-integration (push) Successful in 2m36s
CI / tests-unit (push) Successful in 2m52s
CI / tests-ui (push) Successful in 3m28s
CI / preflight (push) Skipped
CI / tests-quality (push) Successful in 1m30s
CI / tests-imaging-browsers (push) Successful in 2m47s
CI / deploy (push) Successful in 3m21s

The Habbo presets (and the other furnidata-only sources) carry no
`nitroBaseUrl`, so the clone importer's `${nitroBaseUrl}/${classname}.nitro`
download can never work against them — an `--import-new` run would have failed
for every single item instead of saying why. The SWF path that does work against
`images.habbo.com` lives in `furni-import.ts`, not in the clone importer this
CLI uses.

`stepImportNew` now skips those sources up-front, lists them under
"compared only" in the summary, and the menu prints the same warning when an
import step is chosen with such a source, pointing at the sources that do serve
bundles. Verified: Habbo (COM) reports compare-only, while Habboon and
VirtualCity list real candidates.
This commit is contained in:
openhands committed 2026-10-15 20:18:34 +02:00
1 parent f56b345598
commit 77a0d1010c
3 files changed
+78 -4

No files matched your search

+29 -4
View File
@@ -83,6 +83,22 @@ export interface ImportOutcome {
skipped: number;
failed: number;
failures: Array<{ classname: string; error: string }>;
/** Sources that were skipped because they cannot serve bundles. */
skippedSources: string[];
}
/**
* Whether a source can actually be imported from.
*
* The clone import downloads `${nitroBaseUrl}/${classname}.nitro` and gives up
* when that is not reachable. Habbo's own entries carry no nitro/icon base URLs
* (their furnidata is served, their assets are not), so they are compare-only:
* perfect for finding out what this hotel lacks, useless for actually fetching
* it. The SWF-based path that works against `images.habbo.com` lives in
* `furni-import.ts`, not in the clone importer this CLI uses.
*/
export function canImportBundles(source: SourceRef): boolean {
return Boolean(source.nitroBaseUrl?.trim());
}
export interface CatalogSyncFlags {
@@ -420,8 +436,16 @@ async function stepImportNew(
itemType: string;
}> = [];
let lastSource = "";
const skippedSources: string[] = [];
for (const source of sources) {
if (!canImportBundles(source)) {
log(
`! ${source.name} serves no .nitro bundles — it can be compared against, but nothing can be imported from it`,
);
skippedSources.push(source.name);
continue;
}
if (flags.importLimit > 0 && planned >= flags.importLimit) break;
const remaining = flags.importLimit
? flags.importLimit - planned
@@ -515,6 +539,7 @@ async function stepImportNew(
skipped,
failed,
failures: failures.slice(0, 25),
skippedSources,
};
}
@@ -736,12 +761,12 @@ function printSummary(report: AuditReport, started: number): void {
console.log(
` imported from source ${outcome.imported} new (${outcome.skipped} already present, ${outcome.failed} failed)`,
);
if (outcome.skippedSources.length > 0)
console.log(
` compared only ${outcome.skippedSources.join(", ")} (no .nitro bundles to import from)`,
);
for (const failure of outcome.failures)
console.log(` ${failure.classname}: ${failure.error}`);
if (outcome.failures.length > 0)
console.log(
` import failures are per-item: a failed download never aborts the run.`,
);
}
if (report.missingFromSources.length > 0) {