Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/lib/downloaders/download-operations-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,14 @@ export class DownloadOperationsRegistry {
}

if (fromPush) {
// A sync/push normally downloads everything so the push pipeline has complete data for change
// detection. Exception: when the operation is scoped to models only — `--elements="Models"` or
// the simple `--models` filter — only model definitions are needed, so skip assets, galleries,
// content, etc. (`--models-with-deps` still needs the full renderable tree and is NOT treated as
// models-only here.)
if (this.isModelsOnlyScope(resolvedElements)) {
return Object.values(DOWNLOAD_OPERATIONS).filter((operation) => operation.elements.includes("Models"));
}
return Object.values(DOWNLOAD_OPERATIONS);
}

Expand All @@ -117,6 +125,23 @@ export class DownloadOperationsRegistry {
return relevantOperations;
}

/**
* A models-only operation needs only model definitions downloaded — no assets, galleries, content,
* templates, containers, or pages. True when the user scoped elements to just "Models", or used the
* simple `--models` filter. `--models-with-deps` is intentionally excluded: it pulls the full
* dependency tree (assets included) and therefore is NOT models-only.
*/
private static isModelsOnlyScope(resolvedElements: string[]): boolean {
const state = getState();

const simpleModelsOnly =
!!(state.models && state.models.trim()) && !(state.modelsWithDeps && state.modelsWithDeps.trim());

const elementsModelsOnly = resolvedElements.length === 1 && resolvedElements[0] === "Models";

return simpleModelsOnly || elementsModelsOnly;
}

/**
* Resolve element dependencies
*/
Expand Down
24 changes: 24 additions & 0 deletions src/lib/downloaders/tests/download-operations-config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,30 @@ describe("DownloadOperationsRegistry.getOperationsForElements", () => {
expect(ops.length).toBe(Object.keys(DOWNLOAD_OPERATIONS).length);
});

it("skips assets (and other non-model ops) on a sync scoped to --elements=Models", () => {
setState({ elements: "Models" });
const ops = DownloadOperationsRegistry.getOperationsForElements(true);
const names = ops.map((o: OperationConfig) => o.name);
expect(names).toEqual(["downloadAllModels"]);
expect(names).not.toContain("downloadAllAssets");
expect(names).not.toContain("downloadAllGalleries");
});

it("skips assets on a sync that uses the simple --models filter", () => {
setState({ models: "FooterLinks" }); // elements stays at the full default
const ops = DownloadOperationsRegistry.getOperationsForElements(true);
const names = ops.map((o: OperationConfig) => o.name);
expect(names).toEqual(["downloadAllModels"]);
expect(names).not.toContain("downloadAllAssets");
});

it("still downloads everything on a --models-with-deps sync (full tree needs assets)", () => {
setState({ modelsWithDeps: "FooterLinks" });
const ops = DownloadOperationsRegistry.getOperationsForElements(true);
expect(ops.length).toBe(Object.keys(DOWNLOAD_OPERATIONS).length);
expect(ops.map((o: OperationConfig) => o.name)).toContain("downloadAllAssets");
});

it("returns only operations matching state.elements when fromPush is false", () => {
setState({ elements: "Models" });
const ops = DownloadOperationsRegistry.getOperationsForElements(false);
Expand Down
Loading