Skip to content
Open
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
8 changes: 8 additions & 0 deletions src/core/fileOperations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,14 @@ export class fileOperations {
}

getFolderContents(folder: string) {
// A scoped run (e.g. a models-only sync) legitimately skips downloading some
// element types, so their instance subfolder is never created. Create the
// folder on demand and return an empty listing instead of throwing ENOENT,
// matching how readJsonFilesFromFolder/listFilesInFolder already degrade.
if (!fs.existsSync(folder)) {
fs.mkdirSync(folder, { recursive: true });
return [];
}
return fs.readdirSync(folder);
}

Expand Down
25 changes: 25 additions & 0 deletions src/core/tests/fileOperations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,31 @@ describe("listFilesInFolder", () => {
});
});

// ─── getFolderContents ────────────────────────────────────────────────────────

describe("getFolderContents", () => {
it("lists the entries of an existing folder", () => {
const dir = path.join(tmpDir, "fc-guid", "galleries");
fs.mkdirSync(dir, { recursive: true });
fs.writeFileSync(path.join(dir, "1.json"), "{}");
fs.writeFileSync(path.join(dir, "2.json"), "{}");

const ops = new fileOperations("fc-guid");
expect(ops.getFolderContents(dir).sort()).toEqual(["1.json", "2.json"]);
});

it("creates the folder and returns [] when it does not exist (models-only sync regression)", () => {
const dir = path.join(tmpDir, "fc-missing-guid", "galleries");
expect(fs.existsSync(dir)).toBe(false);

const ops = new fileOperations("fc-missing-guid");
expect(ops.getFolderContents(dir)).toEqual([]);
// The folder is created on demand so a scoped run that skipped downloading
// galleries does not crash later in the push pipeline with ENOENT.
expect(fs.existsSync(dir)).toBe(true);
});
});

// ─── saveMappingFile / getMappingFile ─────────────────────────────────────────

describe("saveMappingFile / getMappingFile", () => {
Expand Down
16 changes: 13 additions & 3 deletions src/lib/getters/filesystem/tests/get-galleries.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,20 @@ function makeFileOps(subDir: string): fileOperations {
}

describe("getGalleriesFromFileSystem", () => {
it("throws or returns empty when galleries folder does not exist", () => {
it("returns empty and creates the folder when galleries folder does not exist", () => {
const fileOps = makeFileOps("galleries-missing");
// getFolderContents (readdirSync) throws when directory does not exist
expect(() => getGalleriesFromFileSystem(fileOps)).toThrow();
const galleriesDir = path.join(fileOps.instancePath, "galleries");
expect(fs.existsSync(galleriesDir)).toBe(false);

// A models-only sync skips downloading galleries, so the folder is absent.
// getFolderContents creates it on demand and returns [] instead of throwing
// ENOENT, which previously crashed the push phase (PROD-2277).
let result: any;
expect(() => {
result = getGalleriesFromFileSystem(fileOps);
}).not.toThrow();
expect(result).toEqual([]);
expect(fs.existsSync(galleriesDir)).toBe(true);
});

it("returns an empty array when galleries folder is empty", () => {
Expand Down
Loading