From bde013e56d40669314d5dd4744bf3bb84974f486 Mon Sep 17 00:00:00 2001 From: Wojtek Naruniec Date: Fri, 10 Apr 2026 15:59:31 +0200 Subject: [PATCH 1/3] Add archiver patches back to fix following symlinks on export --- apps/cli/lib/archive.ts | 2 +- .../export/exporters/default-exporter.ts | 2 +- apps/cli/patches/@types+archiver+7.0.0.patch | 12 ++++++++++++ apps/cli/patches/archiver+7.0.1.patch | 14 ++++++++++++++ apps/studio/patches/@types+archiver+7.0.0.patch | 12 ++++++++++++ apps/studio/patches/archiver+7.0.1.patch | 14 ++++++++++++++ .../export/exporters/default-exporter.ts | 2 +- 7 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 apps/cli/patches/@types+archiver+7.0.0.patch create mode 100644 apps/cli/patches/archiver+7.0.1.patch create mode 100644 apps/studio/patches/@types+archiver+7.0.0.patch create mode 100644 apps/studio/patches/archiver+7.0.1.patch diff --git a/apps/cli/lib/archive.ts b/apps/cli/lib/archive.ts index a316478135..c164a90c77 100644 --- a/apps/cli/lib/archive.ts +++ b/apps/cli/lib/archive.ts @@ -18,7 +18,7 @@ export async function archiveSiteContent( const archiveBuilder = archiver( 'zip', { zlib: { level: ZIP_COMPRESSION_LEVEL }, followSymlinks: true, - } as archiver.ArchiverOptions ); + } ); output.on( 'close', () => { resolve( archiveBuilder ); diff --git a/apps/cli/lib/import-export/export/exporters/default-exporter.ts b/apps/cli/lib/import-export/export/exporters/default-exporter.ts index eb5601008e..7ffcf8bac8 100644 --- a/apps/cli/lib/import-export/export/exporters/default-exporter.ts +++ b/apps/cli/lib/import-export/export/exporters/default-exporter.ts @@ -153,7 +153,7 @@ export class DefaultExporter extends EventEmitter implements Exporter { this.emit( ExportEvents.BACKUP_CREATE_START ); const isZip = this.options.backupFile.endsWith( '.zip' ); const format = isZip ? 'zip' : 'tar'; - return archiver( format, ARCHIVER_OPTIONS[ format ] as archiver.ArchiverOptions ); + return archiver( format, ARCHIVER_OPTIONS[ format ] ); } private setupArchiveListeners( output: fs.WriteStream ): Promise< void > { diff --git a/apps/cli/patches/@types+archiver+7.0.0.patch b/apps/cli/patches/@types+archiver+7.0.0.patch new file mode 100644 index 0000000000..63a126f151 --- /dev/null +++ b/apps/cli/patches/@types+archiver+7.0.0.patch @@ -0,0 +1,12 @@ +diff --git a/node_modules/@types/archiver/index.d.ts b/node_modules/@types/archiver/index.d.ts +index 03d2d7d..76ad877 100644 +--- a/node_modules/@types/archiver/index.d.ts ++++ b/node_modules/@types/archiver/index.d.ts +@@ -106,6 +106,7 @@ + + interface CoreOptions { + statConcurrency?: number | undefined; ++ followSymlinks?: boolean | undefined; + } + + interface TransformOptions { diff --git a/apps/cli/patches/archiver+7.0.1.patch b/apps/cli/patches/archiver+7.0.1.patch new file mode 100644 index 0000000000..58b35f023c --- /dev/null +++ b/apps/cli/patches/archiver+7.0.1.patch @@ -0,0 +1,14 @@ +diff --git a/node_modules/archiver/lib/core.js b/node_modules/archiver/lib/core.js +index 7c0a74d..2934fe5 100644 +--- a/node_modules/archiver/lib/core.js ++++ b/node_modules/archiver/lib/core.js +@@ -631,7 +631,8 @@ + + var globOptions = { + stat: true, +- dot: true ++ dot: true, ++ follow: this.options.followSymlinks + }; + + function onGlobEnd() { diff --git a/apps/studio/patches/@types+archiver+7.0.0.patch b/apps/studio/patches/@types+archiver+7.0.0.patch new file mode 100644 index 0000000000..63a126f151 --- /dev/null +++ b/apps/studio/patches/@types+archiver+7.0.0.patch @@ -0,0 +1,12 @@ +diff --git a/node_modules/@types/archiver/index.d.ts b/node_modules/@types/archiver/index.d.ts +index 03d2d7d..76ad877 100644 +--- a/node_modules/@types/archiver/index.d.ts ++++ b/node_modules/@types/archiver/index.d.ts +@@ -106,6 +106,7 @@ + + interface CoreOptions { + statConcurrency?: number | undefined; ++ followSymlinks?: boolean | undefined; + } + + interface TransformOptions { diff --git a/apps/studio/patches/archiver+7.0.1.patch b/apps/studio/patches/archiver+7.0.1.patch new file mode 100644 index 0000000000..58b35f023c --- /dev/null +++ b/apps/studio/patches/archiver+7.0.1.patch @@ -0,0 +1,14 @@ +diff --git a/node_modules/archiver/lib/core.js b/node_modules/archiver/lib/core.js +index 7c0a74d..2934fe5 100644 +--- a/node_modules/archiver/lib/core.js ++++ b/node_modules/archiver/lib/core.js +@@ -631,7 +631,8 @@ + + var globOptions = { + stat: true, +- dot: true ++ dot: true, ++ follow: this.options.followSymlinks + }; + + function onGlobEnd() { diff --git a/apps/studio/src/lib/import-export/export/exporters/default-exporter.ts b/apps/studio/src/lib/import-export/export/exporters/default-exporter.ts index 6719280465..cbf3a09115 100644 --- a/apps/studio/src/lib/import-export/export/exporters/default-exporter.ts +++ b/apps/studio/src/lib/import-export/export/exporters/default-exporter.ts @@ -154,7 +154,7 @@ export class DefaultExporter extends EventEmitter implements Exporter { this.emit( ExportEvents.BACKUP_CREATE_START ); const isZip = this.options.backupFile.endsWith( '.zip' ); const format = isZip ? 'zip' : 'tar'; - return archiver( format, ARCHIVER_OPTIONS[ format ] as archiver.ArchiverOptions ); + return archiver( format, ARCHIVER_OPTIONS[ format ] ); } private setupArchiveListeners( output: fs.WriteStream ): Promise< void > { From 0aac9af8e2c2778590ea29128a2730de2e3f538a Mon Sep 17 00:00:00 2001 From: Roberto Aranda Date: Fri, 10 Apr 2026 18:59:42 +0200 Subject: [PATCH 2/3] Remove @types/archiver patches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The @types/archiver patches added followSymlinks to CoreOptions, but this is unnecessary — ARCHIVER_OPTIONS in constants.ts uses plain object inference so followSymlinks is never checked against CoreOptions. The CLI patch also broke CI because install:bundle uses --omit=dev, meaning @types/archiver is absent when patch-package runs. --- apps/cli/patches/@types+archiver+7.0.0.patch | 12 ------------ apps/studio/patches/@types+archiver+7.0.0.patch | 12 ------------ 2 files changed, 24 deletions(-) delete mode 100644 apps/cli/patches/@types+archiver+7.0.0.patch delete mode 100644 apps/studio/patches/@types+archiver+7.0.0.patch diff --git a/apps/cli/patches/@types+archiver+7.0.0.patch b/apps/cli/patches/@types+archiver+7.0.0.patch deleted file mode 100644 index 63a126f151..0000000000 --- a/apps/cli/patches/@types+archiver+7.0.0.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/node_modules/@types/archiver/index.d.ts b/node_modules/@types/archiver/index.d.ts -index 03d2d7d..76ad877 100644 ---- a/node_modules/@types/archiver/index.d.ts -+++ b/node_modules/@types/archiver/index.d.ts -@@ -106,6 +106,7 @@ - - interface CoreOptions { - statConcurrency?: number | undefined; -+ followSymlinks?: boolean | undefined; - } - - interface TransformOptions { diff --git a/apps/studio/patches/@types+archiver+7.0.0.patch b/apps/studio/patches/@types+archiver+7.0.0.patch deleted file mode 100644 index 63a126f151..0000000000 --- a/apps/studio/patches/@types+archiver+7.0.0.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/node_modules/@types/archiver/index.d.ts b/node_modules/@types/archiver/index.d.ts -index 03d2d7d..76ad877 100644 ---- a/node_modules/@types/archiver/index.d.ts -+++ b/node_modules/@types/archiver/index.d.ts -@@ -106,6 +106,7 @@ - - interface CoreOptions { - statConcurrency?: number | undefined; -+ followSymlinks?: boolean | undefined; - } - - interface TransformOptions { From 77155d12bd9a86a6dfc4b69aea371165f88d1861 Mon Sep 17 00:00:00 2001 From: Roberto Aranda Date: Fri, 10 Apr 2026 19:08:54 +0200 Subject: [PATCH 3/3] Remove @types/archiver patches and restore ArchiverOptions casts The @types/archiver patches added followSymlinks to CoreOptions, but @types/archiver@7 dropped followSymlinks from CoreOptions (it's still supported at runtime). The CLI patch also broke CI because install:bundle uses --omit=dev, meaning @types/archiver is absent when patch-package runs. Restore the `as archiver.ArchiverOptions` casts at call sites. --- apps/cli/lib/archive.ts | 2 +- .../export/exporters/default-exporter.ts | 2 +- apps/cli/patches/@types+archiver+7.0.0.patch | 12 ------------ apps/studio/patches/@types+archiver+7.0.0.patch | 12 ------------ .../export/exporters/default-exporter.ts | 2 +- 5 files changed, 3 insertions(+), 27 deletions(-) delete mode 100644 apps/cli/patches/@types+archiver+7.0.0.patch delete mode 100644 apps/studio/patches/@types+archiver+7.0.0.patch diff --git a/apps/cli/lib/archive.ts b/apps/cli/lib/archive.ts index c164a90c77..a316478135 100644 --- a/apps/cli/lib/archive.ts +++ b/apps/cli/lib/archive.ts @@ -18,7 +18,7 @@ export async function archiveSiteContent( const archiveBuilder = archiver( 'zip', { zlib: { level: ZIP_COMPRESSION_LEVEL }, followSymlinks: true, - } ); + } as archiver.ArchiverOptions ); output.on( 'close', () => { resolve( archiveBuilder ); diff --git a/apps/cli/lib/import-export/export/exporters/default-exporter.ts b/apps/cli/lib/import-export/export/exporters/default-exporter.ts index 7ffcf8bac8..eb5601008e 100644 --- a/apps/cli/lib/import-export/export/exporters/default-exporter.ts +++ b/apps/cli/lib/import-export/export/exporters/default-exporter.ts @@ -153,7 +153,7 @@ export class DefaultExporter extends EventEmitter implements Exporter { this.emit( ExportEvents.BACKUP_CREATE_START ); const isZip = this.options.backupFile.endsWith( '.zip' ); const format = isZip ? 'zip' : 'tar'; - return archiver( format, ARCHIVER_OPTIONS[ format ] ); + return archiver( format, ARCHIVER_OPTIONS[ format ] as archiver.ArchiverOptions ); } private setupArchiveListeners( output: fs.WriteStream ): Promise< void > { diff --git a/apps/cli/patches/@types+archiver+7.0.0.patch b/apps/cli/patches/@types+archiver+7.0.0.patch deleted file mode 100644 index 63a126f151..0000000000 --- a/apps/cli/patches/@types+archiver+7.0.0.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/node_modules/@types/archiver/index.d.ts b/node_modules/@types/archiver/index.d.ts -index 03d2d7d..76ad877 100644 ---- a/node_modules/@types/archiver/index.d.ts -+++ b/node_modules/@types/archiver/index.d.ts -@@ -106,6 +106,7 @@ - - interface CoreOptions { - statConcurrency?: number | undefined; -+ followSymlinks?: boolean | undefined; - } - - interface TransformOptions { diff --git a/apps/studio/patches/@types+archiver+7.0.0.patch b/apps/studio/patches/@types+archiver+7.0.0.patch deleted file mode 100644 index 63a126f151..0000000000 --- a/apps/studio/patches/@types+archiver+7.0.0.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/node_modules/@types/archiver/index.d.ts b/node_modules/@types/archiver/index.d.ts -index 03d2d7d..76ad877 100644 ---- a/node_modules/@types/archiver/index.d.ts -+++ b/node_modules/@types/archiver/index.d.ts -@@ -106,6 +106,7 @@ - - interface CoreOptions { - statConcurrency?: number | undefined; -+ followSymlinks?: boolean | undefined; - } - - interface TransformOptions { diff --git a/apps/studio/src/lib/import-export/export/exporters/default-exporter.ts b/apps/studio/src/lib/import-export/export/exporters/default-exporter.ts index cbf3a09115..6719280465 100644 --- a/apps/studio/src/lib/import-export/export/exporters/default-exporter.ts +++ b/apps/studio/src/lib/import-export/export/exporters/default-exporter.ts @@ -154,7 +154,7 @@ export class DefaultExporter extends EventEmitter implements Exporter { this.emit( ExportEvents.BACKUP_CREATE_START ); const isZip = this.options.backupFile.endsWith( '.zip' ); const format = isZip ? 'zip' : 'tar'; - return archiver( format, ARCHIVER_OPTIONS[ format ] ); + return archiver( format, ARCHIVER_OPTIONS[ format ] as archiver.ArchiverOptions ); } private setupArchiveListeners( output: fs.WriteStream ): Promise< void > {