From 145c72c9700f8e5f0c4cf8d640b6afeb16053d4e Mon Sep 17 00:00:00 2001 From: Diego Imbert Date: Wed, 13 May 2026 17:52:10 +0200 Subject: [PATCH] refactor(frontend): drop legacy-migration shape guard We assume Windmill is the only app on the origin, so the isPlausibleLegacyValue per-kind shape check was just dead weight. Keep the cheap "decoded is an object" guard for malformed payloads. --- .../src/lib/userDraftLegacyMigration.test.ts | 12 -------- frontend/src/lib/userDraftLegacyMigration.ts | 28 +------------------ 2 files changed, 1 insertion(+), 39 deletions(-) diff --git a/frontend/src/lib/userDraftLegacyMigration.test.ts b/frontend/src/lib/userDraftLegacyMigration.test.ts index a6cbfe5469..8d76ab2b55 100644 --- a/frontend/src/lib/userDraftLegacyMigration.test.ts +++ b/frontend/src/lib/userDraftLegacyMigration.test.ts @@ -91,18 +91,6 @@ describe('migrateLegacyUserDrafts', () => { expect(localStorage.getItem('userdraft/w/main/app/u/me/dash')).toBe(existingNew) }) - it('skips legacy keys whose decoded payload does not look like a Windmill draft', () => { - // A co-resident app on the same origin happens to use `app-foo`. We must - // not touch it. - const unrelated = btoa(encodeURIComponent(JSON.stringify({ random: 'data' }))) - localStorage.setItem('app-some_other_app', unrelated) - - migrateLegacyUserDrafts('main') - - expect(localStorage.getItem('app-some_other_app')).toBe(unrelated) - expect(localStorage.getItem('userdraft/w/main/app/some_other_app')).toBeNull() - }) - it('is idempotent — the second invocation is a no-op', () => { localStorage.setItem( 'app-u/me/dash', diff --git a/frontend/src/lib/userDraftLegacyMigration.ts b/frontend/src/lib/userDraftLegacyMigration.ts index b25330bbae..1c77f9d883 100644 --- a/frontend/src/lib/userDraftLegacyMigration.ts +++ b/frontend/src/lib/userDraftLegacyMigration.ts @@ -56,28 +56,6 @@ function decodeLegacyState(raw: string): unknown { } } -/** - * Defensive shape check. The legacy keys (`app-foo`, `flow-foo`, ...) are - * unusual but not unique to Windmill — a co-resident app on the same origin - * might use the same name space. We require the decoded payload to have at - * least one of the fields the old format wrote. - */ -function isPlausibleLegacyValue(kind: LegacyKind, decoded: unknown): boolean { - if (decoded == null || typeof decoded !== 'object') return false - const obj = decoded as Record - switch (kind) { - case 'flow': - return 'flow' in obj && obj.flow != null && typeof obj.flow === 'object' - case 'app': - // `$appStore` (an App) was saved directly — it has `summary` / `value` / - // `policy` / `path` etc. The four-of-any check below tolerates pre-1.x - // shapes that didn't carry all four. - return 'summary' in obj || 'value' in obj || 'policy' in obj || 'path' in obj - case 'raw_app': - return 'files' in obj || 'runnables' in obj || 'data' in obj - } -} - function transformLegacyValue(kind: LegacyKind, decoded: unknown): unknown { const obj = decoded as Record switch (kind) { @@ -135,11 +113,7 @@ export function migrateLegacyUserDrafts(workspace: string): void { try { const decoded = decodeLegacyState(raw) - if (!isPlausibleLegacyValue(match.newKind, decoded)) { - // Doesn't smell like a Windmill draft — leave it alone for the - // neighbouring app to deal with. - continue - } + if (decoded == null || typeof decoded !== 'object') continue const value = transformLegacyValue(match.newKind, decoded) const target = newKey(workspace, match.newKind, match.path) if (value !== undefined && localStorage.getItem(target) == null) {