From aa74e00f06b09b0a99e07cddd3b677ac6fc43252 Mon Sep 17 00:00:00 2001 From: Samuel Maddock Date: Fri, 20 Dec 2024 20:33:49 -0500 Subject: [PATCH] feat: load new extension after update --- .../src/browser/index.ts | 2 +- .../src/browser/loader.ts | 2 +- .../src/browser/updater.ts | 52 +++++++++++++------ 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/packages/electron-chrome-web-store/src/browser/index.ts b/packages/electron-chrome-web-store/src/browser/index.ts index 80dce66..32f0ec5 100644 --- a/packages/electron-chrome-web-store/src/browser/index.ts +++ b/packages/electron-chrome-web-store/src/browser/index.ts @@ -98,6 +98,6 @@ export async function installChromeWebStore(opts: ElectronChromeWebStoreOptions } if (autoUpdate) { - await initUpdater(webStoreState) + void initUpdater(webStoreState) } } diff --git a/packages/electron-chrome-web-store/src/browser/loader.ts b/packages/electron-chrome-web-store/src/browser/loader.ts index 74266a2..1d038f8 100644 --- a/packages/electron-chrome-web-store/src/browser/loader.ts +++ b/packages/electron-chrome-web-store/src/browser/loader.ts @@ -135,7 +135,7 @@ export async function loadAllExtensions( d('skipping loading existing extension %s', ext.id) continue } - d('loading extension %s', ext.id) + d('loading extension %s', `${ext.id}@${ext.manifest.version}`) await session.loadExtension(ext.path) } else if (options.allowUnpacked) { d('loading unpacked extension %s', ext.path) diff --git a/packages/electron-chrome-web-store/src/browser/updater.ts b/packages/electron-chrome-web-store/src/browser/updater.ts index 80a538c..e70907e 100644 --- a/packages/electron-chrome-web-store/src/browser/updater.ts +++ b/packages/electron-chrome-web-store/src/browser/updater.ts @@ -76,7 +76,7 @@ const getSessionId = (() => { return () => sessionId || (sessionId = crypto.randomUUID()) })() -const getOmahaPlatform = () => { +const getOmahaPlatform = (): string => { switch (process.platform) { case 'win32': return 'win' @@ -87,14 +87,14 @@ const getOmahaPlatform = () => { } } -const getOmahaArch = () => { +const getOmahaArch = (): string => { switch (process.arch) { case 'ia32': return 'x86' case 'x64': return 'x64' default: - process.arch + return process.arch } } @@ -107,7 +107,6 @@ async function requestExtensionUpdates(extensions: Electron.Extension[]) { }), {}, ) - d('checking extensions for updates', extensionIds) const chromeVersion = getChromeVersion() const url = 'https://update.googleapis.com/service/update2/json' @@ -197,26 +196,49 @@ async function requestExtensionUpdates(extensions: Electron.Extension[]) { return updates } -async function updateExtension(update: ExtensionUpdate) { - d('updating %s', update.id) - const updateDir = path.join(update.extension.path, '..', `${update.version}_0`) +async function updateExtension(session: Electron.Session, update: ExtensionUpdate) { + const oldExtension = update.extension + d('updating %s %s -> %s', update.id, oldExtension.version, update.version) + + // Updates must be installed in adjacent directories. Ensure the old install + // was contained in a versioned directory structure. + const oldVersionDirectoryName = path.basename(oldExtension.path) + if (!oldVersionDirectoryName.startsWith(oldExtension.version)) { + console.error( + `updateExtension: extension ${update.id} must conform to versioned directory names`, + { + oldPath: oldExtension.path, + }, + ) + d('skipping %s update due to invalid install path %s', update.id, oldExtension.path) + return + } + + // Download update + const updateDir = path.join(oldExtension.path, '..', `${update.version}_0`) await downloadCrx(update.url, updateDir) - d('updated %s', update.id) - // TODO: load new extension version + d('downloaded update %s@%s', update.id, update.version) + + // Replace extension + session.removeExtension(update.id) + await session.loadExtension(updateDir) + d('loaded update %s@%s', update.id, update.version) + + // TODO: remove old extension } -async function checkForUpdates(extensions: Electron.Extension[]) { - d('checking for updates', extensions) +async function checkForUpdates(session: Electron.Session, extensions: Electron.Extension[]) { + d('checking for updates: %s', extensions.map((ext) => `${ext.id}@${ext.version}`).join(',')) const updates = await requestExtensionUpdates(extensions) - if (!updates) { + if (!updates || updates.length === 0) { d('no updates found') return } - d('updating %d extensions', updates.length) + d('updating %d extension(s)', updates.length) for (const update of updates) { - await updateExtension(update) + await updateExtension(session, update) } } @@ -246,7 +268,7 @@ async function maybeCheckForUpdates(session: Electron.Session) { return } - await checkForUpdates(extensions) + await checkForUpdates(session, extensions) } export async function initUpdater(state: WebStoreState) {