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
6 changes: 5 additions & 1 deletion src/installer-message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ export const normalizeInstallSuccessMessage = (message: string): string =>
? "Identical to previous version -- not replacing"
: "Successful deploy";

// Both are empty-developer-slot signals: newer devices report "no plugin
// installed", while older ones (e.g. Roku Stick 3500X) fail a delete/replace of
// an empty slot with "No such file or directory". Treating either as an empty
// slot makes delete idempotent and lets a Replace fall back to a fresh Install.
export const isEmptyDeveloperSlotMessage = (message: string): boolean =>
/no plugin installed/i.test(message);
/no plugin installed/i.test(message) || /no such file or directory/i.test(message);

export const isDeleteSuccess = (message: string): boolean =>
isRecognizedInstallerMessage(message) &&
Expand Down
19 changes: 19 additions & 0 deletions test/installer-message.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { describe, expect, it } from "vite-plus/test";
import { isDeleteSuccess, isEmptyDeveloperSlotMessage } from "../src/installer-message.js";

describe("installer message classification", () => {
it("recognizes both empty developer-slot phrasings", () => {
expect(isEmptyDeveloperSlotMessage("No plugin installed")).toBe(true);
// Older devices fail a delete/replace of an empty slot this way.
expect(isEmptyDeveloperSlotMessage("Delete Failed: No such file or directory")).toBe(true);
expect(isEmptyDeveloperSlotMessage("Some unrelated installer message")).toBe(false);
});

it("treats delete success and empty-slot deletes as success, rejects real failures", () => {
expect(isDeleteSuccess("Delete Succeeded.")).toBe(true);
expect(isDeleteSuccess("Delete Failed: No such file or directory")).toBe(true);
expect(isDeleteSuccess("No plugin installed")).toBe(true);
expect(isDeleteSuccess("Install Failure: compilation failed")).toBe(false);
expect(isDeleteSuccess("Empty Roku installer response")).toBe(false);
});
});