From f1a7d2218ca541ce475132c930e0c47c95c51504 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Sun, 15 Mar 2026 12:26:38 +0100 Subject: [PATCH 1/7] feat(cli-tools): support for pruning assets --- packages/cli-tools/src/commands/prune.ts | 19 +++++++++++++++++++ packages/cli-tools/src/index.ts | 2 ++ packages/cli-tools/src/types/prune.ts | 6 ++++++ 3 files changed, 27 insertions(+) create mode 100644 packages/cli-tools/src/commands/prune.ts create mode 100644 packages/cli-tools/src/types/prune.ts diff --git a/packages/cli-tools/src/commands/prune.ts b/packages/cli-tools/src/commands/prune.ts new file mode 100644 index 000000000..de65d325a --- /dev/null +++ b/packages/cli-tools/src/commands/prune.ts @@ -0,0 +1,19 @@ +import ora from 'ora'; +import type {FileDetails} from '../types/deploy'; +import {PruneParams} from '../types/prune'; + +export const prune = async ({params}: {params: PruneParams}) => { + const prepareResult = await preparePrune(params); + + if (prepareResult.result === 'skipped') { + return {result: 'skipped'}; + } +}; + +const preparePrune = async (params: Omit): Promise< + {result: 'skipped'} | {result: 'to-prune'; files: FileDetails[]; sourceAbsolutePath: string} +> => { + const spinner = ora('Preparing deploy...').start(); + + +}; diff --git a/packages/cli-tools/src/index.ts b/packages/cli-tools/src/index.ts index c29a11a81..7079887cf 100644 --- a/packages/cli-tools/src/index.ts +++ b/packages/cli-tools/src/index.ts @@ -1,10 +1,12 @@ export * from './commands/build'; export * from './commands/deploy'; export * from './commands/generate'; +export * from './commands/prune'; export * from './commands/publish'; export * from './constants/deploy.constants'; export {ListAssets} from './types/assets'; export type * from './types/deploy'; +export type * from './types/prune'; export type * from './types/pkg'; export type * from './types/proposal'; export type * from './types/publish'; diff --git a/packages/cli-tools/src/types/prune.ts b/packages/cli-tools/src/types/prune.ts new file mode 100644 index 000000000..c20e8f936 --- /dev/null +++ b/packages/cli-tools/src/types/prune.ts @@ -0,0 +1,6 @@ +import type {AssetsParams, PrepareAssetsOptions} from './assets'; +import {PrepareDeployOptions} from './deploy'; + +export type PreparePruneOptions = PrepareAssetsOptions; + +export type PruneParams = PrepareDeployOptions & AssetsParams; \ No newline at end of file From 3ca5ed325fb24948377702b73aa5da1c2bf21a7e Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Sun, 15 Mar 2026 12:28:25 +0100 Subject: [PATCH 2/7] refactor: move types --- packages/cli-tools/src/commands/deploy.ts | 2 +- packages/cli-tools/src/commands/prune.ts | 2 +- packages/cli-tools/src/index.ts | 3 +++ .../src/services/deploy.prepare.services.ts | 4 ++-- .../src/services/upload/_upload.services.ts | 3 ++- .../upload/upload.individual.services.ts | 3 ++- packages/cli-tools/src/types/assets.ts | 18 +++++++++++++++--- packages/cli-tools/src/types/deploy.ts | 14 +------------- 8 files changed, 27 insertions(+), 22 deletions(-) diff --git a/packages/cli-tools/src/commands/deploy.ts b/packages/cli-tools/src/commands/deploy.ts index e4d2f45e2..50e63ed21 100644 --- a/packages/cli-tools/src/commands/deploy.ts +++ b/packages/cli-tools/src/commands/deploy.ts @@ -11,7 +11,6 @@ import type { DeployResult, DeployResultWithProposal, FileAndPaths, - FileDetails, FilePaths, UploadFilesWithProposal, UploadFileWithProposal, @@ -21,6 +20,7 @@ import type { import type {ProposeChangesParams} from '../types/proposal'; import type {UploadFilesParams} from '../types/upload'; import {fullPath} from '../utils/assets.utils'; +import {FileDetails} from '../types/assets'; /** * Executes all configured pre-deploy hooks defined in the Juno configuration. diff --git a/packages/cli-tools/src/commands/prune.ts b/packages/cli-tools/src/commands/prune.ts index de65d325a..646f7ba76 100644 --- a/packages/cli-tools/src/commands/prune.ts +++ b/packages/cli-tools/src/commands/prune.ts @@ -1,6 +1,6 @@ import ora from 'ora'; -import type {FileDetails} from '../types/deploy'; import {PruneParams} from '../types/prune'; +import {FileDetails} from "../types/assets"; export const prune = async ({params}: {params: PruneParams}) => { const prepareResult = await preparePrune(params); diff --git a/packages/cli-tools/src/index.ts b/packages/cli-tools/src/index.ts index 7079887cf..fbd8e6667 100644 --- a/packages/cli-tools/src/index.ts +++ b/packages/cli-tools/src/index.ts @@ -18,3 +18,6 @@ export * from './utils/format.utils'; export * from './utils/fs.utils'; export * from './utils/pkg.utils'; export * from './utils/prompt.utils'; +export {FileDetails} from './types/assets'; +export {FileExtension} from './types/assets'; +export {MimeType} from './types/assets'; diff --git a/packages/cli-tools/src/services/deploy.prepare.services.ts b/packages/cli-tools/src/services/deploy.prepare.services.ts index 378fd63d9..0ea866b70 100644 --- a/packages/cli-tools/src/services/deploy.prepare.services.ts +++ b/packages/cli-tools/src/services/deploy.prepare.services.ts @@ -13,8 +13,8 @@ import { DEPLOY_DEFAULT_PRECOMPRESS, DEPLOY_DEFAULT_SOURCE } from '../constants/deploy.constants'; -import type {ListAssets} from '../types/assets'; -import type {FileDetails, FileExtension, PrepareDeployOptions} from '../types/deploy'; +import type {FileDetails, FileExtension, ListAssets} from '../types/assets'; +import type {PrepareDeployOptions} from '../types/deploy'; import {fullPath} from '../utils/assets.utils'; import {compressFiles} from '../utils/compress.utils'; import {listSourceFilesForDeploy} from '../utils/deploy.utils'; diff --git a/packages/cli-tools/src/services/upload/_upload.services.ts b/packages/cli-tools/src/services/upload/_upload.services.ts index 0bfc514b3..12543892a 100644 --- a/packages/cli-tools/src/services/upload/_upload.services.ts +++ b/packages/cli-tools/src/services/upload/_upload.services.ts @@ -1,9 +1,10 @@ import {nonNullish, notEmptyString} from '@dfinity/utils'; import {readFile} from 'node:fs/promises'; import {basename} from 'node:path'; -import type {FileAndPaths, FileDetails, UploadFileStorage} from '../../types/deploy'; +import type {FileAndPaths, UploadFileStorage} from '../../types/deploy'; import type {UploadFilesParams} from '../../types/upload'; import {splitSourceFiles} from '../../utils/upload.utils'; +import {FileDetails} from "../../types/assets"; export const prepareFileForUpload = async ({ file, diff --git a/packages/cli-tools/src/services/upload/upload.individual.services.ts b/packages/cli-tools/src/services/upload/upload.individual.services.ts index 9eaa806ac..f8daf1e91 100644 --- a/packages/cli-tools/src/services/upload/upload.individual.services.ts +++ b/packages/cli-tools/src/services/upload/upload.individual.services.ts @@ -1,12 +1,13 @@ import {Listr} from 'listr2'; import {relative} from 'node:path'; -import type {FileAndPaths, FileDetails, UploadFile, UploadFileStorage} from '../../types/deploy'; +import type {FileAndPaths, UploadFile, UploadFileStorage} from '../../types/deploy'; import type {UploadFilesParams} from '../../types/upload'; import { type ExecuteUploadFiles, executeUploadFiles, prepareFileForUpload } from './_upload.services'; +import {FileDetails} from "../../types/assets"; export const uploadFilesIndividually = async ({ uploadFile, diff --git a/packages/cli-tools/src/types/assets.ts b/packages/cli-tools/src/types/assets.ts index 05148bc22..2d1d86306 100644 --- a/packages/cli-tools/src/types/assets.ts +++ b/packages/cli-tools/src/types/assets.ts @@ -1,12 +1,24 @@ -import type {CliConfig} from '@junobuild/config'; +import type {CliConfig, EncodingType} from '@junobuild/config'; import type {Asset} from '@junobuild/storage'; -export interface PrepareAssetsOptions { - assertSourceDirExists?: (source: string) => void; +export type MimeType = string; + +export type FileExtension = string; + +export interface FileDetails { + file: string; + // e.g. for index.js.gz -> index.js + alternateFile?: string; + encoding?: EncodingType; + mime?: MimeType; } export type ListAssets = ({startAfter}: {startAfter?: string}) => Promise; +export interface PrepareAssetsOptions { + assertSourceDirExists?: (source: string) => void; +} + export interface AssetsParams { config: CliConfig; listAssets: ListAssets; diff --git a/packages/cli-tools/src/types/deploy.ts b/packages/cli-tools/src/types/deploy.ts index a5fe5e21b..0f7f6ab20 100644 --- a/packages/cli-tools/src/types/deploy.ts +++ b/packages/cli-tools/src/types/deploy.ts @@ -1,18 +1,6 @@ import type {EncodingType} from '@junobuild/config'; import type {OnUploadProgress} from '@junobuild/storage'; -import type {AssetsParams, PrepareAssetsOptions} from './assets'; - -export type MimeType = string; - -export type FileExtension = string; - -export interface FileDetails { - file: string; - // e.g. for index.js.gz -> index.js - alternateFile?: string; - encoding?: EncodingType; - mime?: MimeType; -} +import type {AssetsParams, FileDetails, PrepareAssetsOptions} from './assets'; export type FilePaths = Required> & { filePath: string; From 201987f2680fff4d577e00472c18ed8605ff57a6 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Sun, 15 Mar 2026 12:51:58 +0100 Subject: [PATCH 3/7] feat: prune --- packages/cli-tools/src/commands/deploy.ts | 2 +- packages/cli-tools/src/commands/prune.ts | 38 +++++++++++++--- packages/cli-tools/src/index.ts | 7 ++- .../src/services/deploy.prepare.services.ts | 4 +- .../src/services/prune.prepare.services.ts | 43 +++++++++++++++++++ .../cli-tools/src/services/prune.services.ts | 20 +++++++++ .../src/services/upload/_upload.services.ts | 3 +- .../upload/upload.individual.services.ts | 3 +- packages/cli-tools/src/types/assets.ts | 14 +----- packages/cli-tools/src/types/deploy.ts | 14 +++++- packages/cli-tools/src/types/prune.ts | 10 ++++- packages/cli-tools/src/utils/prune.utils.ts | 28 ++++++++++++ 12 files changed, 153 insertions(+), 33 deletions(-) create mode 100644 packages/cli-tools/src/services/prune.prepare.services.ts create mode 100644 packages/cli-tools/src/services/prune.services.ts create mode 100644 packages/cli-tools/src/utils/prune.utils.ts diff --git a/packages/cli-tools/src/commands/deploy.ts b/packages/cli-tools/src/commands/deploy.ts index 50e63ed21..e4d2f45e2 100644 --- a/packages/cli-tools/src/commands/deploy.ts +++ b/packages/cli-tools/src/commands/deploy.ts @@ -11,6 +11,7 @@ import type { DeployResult, DeployResultWithProposal, FileAndPaths, + FileDetails, FilePaths, UploadFilesWithProposal, UploadFileWithProposal, @@ -20,7 +21,6 @@ import type { import type {ProposeChangesParams} from '../types/proposal'; import type {UploadFilesParams} from '../types/upload'; import {fullPath} from '../utils/assets.utils'; -import {FileDetails} from '../types/assets'; /** * Executes all configured pre-deploy hooks defined in the Juno configuration. diff --git a/packages/cli-tools/src/commands/prune.ts b/packages/cli-tools/src/commands/prune.ts index 646f7ba76..2700b2703 100644 --- a/packages/cli-tools/src/commands/prune.ts +++ b/packages/cli-tools/src/commands/prune.ts @@ -1,19 +1,45 @@ import ora from 'ora'; -import {PruneParams} from '../types/prune'; -import {FileDetails} from "../types/assets"; +import {preparePrune as preparePruneServices} from '../services/prune.prepare.services'; +import {prune as pruneServices} from '../services/prune.services'; +import type {PruneFilesFn, PruneFileStorage, PruneParams} from '../types/prune'; -export const prune = async ({params}: {params: PruneParams}) => { +export const prune = async ({params, pruneFn}: {params: PruneParams; pruneFn: PruneFilesFn}) => { const prepareResult = await preparePrune(params); if (prepareResult.result === 'skipped') { return {result: 'skipped'}; } + + const {files} = prepareResult; + + await pruneServices({files, pruneFn}); }; -const preparePrune = async (params: Omit): Promise< - {result: 'skipped'} | {result: 'to-prune'; files: FileDetails[]; sourceAbsolutePath: string} -> => { +const preparePrune = async ( + params: Omit +): Promise<{result: 'skipped'} | {result: 'to-prune'; files: PruneFileStorage[]}> => { const spinner = ora('Preparing deploy...').start(); + try { + const {files: sourceFiles} = await preparePruneServices(params); + + if (sourceFiles.length === 0) { + spinner.stop(); + + console.log(''); + console.log('šŸ‘ No stale assets found. Satellite is already clean.'); + return {result: 'skipped'}; + } + + spinner.stop(); + + return { + result: 'to-prune', + files: sourceFiles + }; + } catch (err: unknown) { + spinner.stop(); + throw err; + } }; diff --git a/packages/cli-tools/src/index.ts b/packages/cli-tools/src/index.ts index fbd8e6667..3f3b2686e 100644 --- a/packages/cli-tools/src/index.ts +++ b/packages/cli-tools/src/index.ts @@ -6,9 +6,9 @@ export * from './commands/publish'; export * from './constants/deploy.constants'; export {ListAssets} from './types/assets'; export type * from './types/deploy'; -export type * from './types/prune'; export type * from './types/pkg'; export type * from './types/proposal'; +export type * from './types/prune'; export type * from './types/publish'; export * from './utils/args.utils'; export * from './utils/cmd.utils'; @@ -18,6 +18,5 @@ export * from './utils/format.utils'; export * from './utils/fs.utils'; export * from './utils/pkg.utils'; export * from './utils/prompt.utils'; -export {FileDetails} from './types/assets'; -export {FileExtension} from './types/assets'; -export {MimeType} from './types/assets'; + +export {FileDetails, FileExtension, MimeType} from './types/deploy'; diff --git a/packages/cli-tools/src/services/deploy.prepare.services.ts b/packages/cli-tools/src/services/deploy.prepare.services.ts index 0ea866b70..378fd63d9 100644 --- a/packages/cli-tools/src/services/deploy.prepare.services.ts +++ b/packages/cli-tools/src/services/deploy.prepare.services.ts @@ -13,8 +13,8 @@ import { DEPLOY_DEFAULT_PRECOMPRESS, DEPLOY_DEFAULT_SOURCE } from '../constants/deploy.constants'; -import type {FileDetails, FileExtension, ListAssets} from '../types/assets'; -import type {PrepareDeployOptions} from '../types/deploy'; +import type {ListAssets} from '../types/assets'; +import type {FileDetails, FileExtension, PrepareDeployOptions} from '../types/deploy'; import {fullPath} from '../utils/assets.utils'; import {compressFiles} from '../utils/compress.utils'; import {listSourceFilesForDeploy} from '../utils/deploy.utils'; diff --git a/packages/cli-tools/src/services/prune.prepare.services.ts b/packages/cli-tools/src/services/prune.prepare.services.ts new file mode 100644 index 000000000..a40fa4f64 --- /dev/null +++ b/packages/cli-tools/src/services/prune.prepare.services.ts @@ -0,0 +1,43 @@ +import type {CliConfig} from '@junobuild/config'; +import type {Asset} from '@junobuild/storage'; +import {join} from 'node:path'; +import {DEPLOY_DEFAULT_IGNORE, DEPLOY_DEFAULT_SOURCE} from '../constants/deploy.constants'; +import type {ListAssets} from '../types/assets'; +import type {PreparePruneOptions, PruneFileStorage} from '../types/prune'; +import {listSourceFilesForPrune} from '../utils/prune.utils'; + +export const preparePrune = async ({ + config, + listAssets, + assertSourceDirExists +}: { + config: CliConfig; + listAssets: ListAssets; +} & PreparePruneOptions): Promise<{files: PruneFileStorage[]}> => { + const {source = DEPLOY_DEFAULT_SOURCE, ignore = DEPLOY_DEFAULT_IGNORE} = config; + + const sourceAbsolutePath = join(process.cwd(), source); + + assertSourceDirExists?.(sourceAbsolutePath); + + // 1. Scan local build output + const localPaths = listSourceFilesForPrune({sourceAbsolutePath, ignore}); + + const stale = await filterFilesToPrune({localPaths, listAssets}); + + return {files: stale.map(({fullPath}) => ({fullPath}))}; +}; + +const filterFilesToPrune = async ({ + localPaths, + listAssets +}: { + localPaths: Set; + listAssets: ListAssets; +}): Promise => { + // 2. Fetch all live assets (paginated) + const existingAssets = await listAssets({}); + + // 3. Compute stale = live_assets āˆ’ local_files + return existingAssets.filter(({fullPath}) => !localPaths.has(fullPath)); +}; diff --git a/packages/cli-tools/src/services/prune.services.ts b/packages/cli-tools/src/services/prune.services.ts new file mode 100644 index 000000000..d7362a312 --- /dev/null +++ b/packages/cli-tools/src/services/prune.services.ts @@ -0,0 +1,20 @@ +import ora from 'ora'; +import type {PruneFilesFn, PruneFileStorage} from '../types/prune'; + +export const prune = async ({ + files, + pruneFn +}: { + files: PruneFileStorage[]; + pruneFn: PruneFilesFn; +}) => { + const deleteSpinner = ora(`Deleting ${files.length} stale asset(s)...`).start(); + + try { + await pruneFn({files}); + } finally { + deleteSpinner.stop(); + } + + console.log(`\nāœ” Pruned ${files.length} stale asset(s).`); +}; diff --git a/packages/cli-tools/src/services/upload/_upload.services.ts b/packages/cli-tools/src/services/upload/_upload.services.ts index 12543892a..0bfc514b3 100644 --- a/packages/cli-tools/src/services/upload/_upload.services.ts +++ b/packages/cli-tools/src/services/upload/_upload.services.ts @@ -1,10 +1,9 @@ import {nonNullish, notEmptyString} from '@dfinity/utils'; import {readFile} from 'node:fs/promises'; import {basename} from 'node:path'; -import type {FileAndPaths, UploadFileStorage} from '../../types/deploy'; +import type {FileAndPaths, FileDetails, UploadFileStorage} from '../../types/deploy'; import type {UploadFilesParams} from '../../types/upload'; import {splitSourceFiles} from '../../utils/upload.utils'; -import {FileDetails} from "../../types/assets"; export const prepareFileForUpload = async ({ file, diff --git a/packages/cli-tools/src/services/upload/upload.individual.services.ts b/packages/cli-tools/src/services/upload/upload.individual.services.ts index f8daf1e91..9eaa806ac 100644 --- a/packages/cli-tools/src/services/upload/upload.individual.services.ts +++ b/packages/cli-tools/src/services/upload/upload.individual.services.ts @@ -1,13 +1,12 @@ import {Listr} from 'listr2'; import {relative} from 'node:path'; -import type {FileAndPaths, UploadFile, UploadFileStorage} from '../../types/deploy'; +import type {FileAndPaths, FileDetails, UploadFile, UploadFileStorage} from '../../types/deploy'; import type {UploadFilesParams} from '../../types/upload'; import { type ExecuteUploadFiles, executeUploadFiles, prepareFileForUpload } from './_upload.services'; -import {FileDetails} from "../../types/assets"; export const uploadFilesIndividually = async ({ uploadFile, diff --git a/packages/cli-tools/src/types/assets.ts b/packages/cli-tools/src/types/assets.ts index 2d1d86306..a17234294 100644 --- a/packages/cli-tools/src/types/assets.ts +++ b/packages/cli-tools/src/types/assets.ts @@ -1,18 +1,6 @@ -import type {CliConfig, EncodingType} from '@junobuild/config'; +import type {CliConfig} from '@junobuild/config'; import type {Asset} from '@junobuild/storage'; -export type MimeType = string; - -export type FileExtension = string; - -export interface FileDetails { - file: string; - // e.g. for index.js.gz -> index.js - alternateFile?: string; - encoding?: EncodingType; - mime?: MimeType; -} - export type ListAssets = ({startAfter}: {startAfter?: string}) => Promise; export interface PrepareAssetsOptions { diff --git a/packages/cli-tools/src/types/deploy.ts b/packages/cli-tools/src/types/deploy.ts index 0f7f6ab20..a5fe5e21b 100644 --- a/packages/cli-tools/src/types/deploy.ts +++ b/packages/cli-tools/src/types/deploy.ts @@ -1,6 +1,18 @@ import type {EncodingType} from '@junobuild/config'; import type {OnUploadProgress} from '@junobuild/storage'; -import type {AssetsParams, FileDetails, PrepareAssetsOptions} from './assets'; +import type {AssetsParams, PrepareAssetsOptions} from './assets'; + +export type MimeType = string; + +export type FileExtension = string; + +export interface FileDetails { + file: string; + // e.g. for index.js.gz -> index.js + alternateFile?: string; + encoding?: EncodingType; + mime?: MimeType; +} export type FilePaths = Required> & { filePath: string; diff --git a/packages/cli-tools/src/types/prune.ts b/packages/cli-tools/src/types/prune.ts index c20e8f936..fe2028337 100644 --- a/packages/cli-tools/src/types/prune.ts +++ b/packages/cli-tools/src/types/prune.ts @@ -1,6 +1,12 @@ import type {AssetsParams, PrepareAssetsOptions} from './assets'; -import {PrepareDeployOptions} from './deploy'; +import type {PrepareDeployOptions} from './deploy'; export type PreparePruneOptions = PrepareAssetsOptions; -export type PruneParams = PrepareDeployOptions & AssetsParams; \ No newline at end of file +export type PruneParams = PrepareDeployOptions & AssetsParams; + +export interface PruneFileStorage { + fullPath: string; +} + +export type PruneFilesFn = (params: {files: PruneFileStorage[]}) => Promise; diff --git a/packages/cli-tools/src/utils/prune.utils.ts b/packages/cli-tools/src/utils/prune.utils.ts new file mode 100644 index 000000000..f8d5100d8 --- /dev/null +++ b/packages/cli-tools/src/utils/prune.utils.ts @@ -0,0 +1,28 @@ +import type {SatelliteConfig} from '@junobuild/config'; +import {minimatch} from 'minimatch'; +import {fullPath} from './assets.utils'; +import {files} from './fs.utils'; + +/** + * Scans the local source directory and returns a Set of fullPaths that are present. + * Throws if the directory cannot be read. + */ +export const listSourceFilesForPrune = ({ + sourceAbsolutePath, + ignore +}: {sourceAbsolutePath: string} & Required>): Set => { + const allFiles = files(sourceAbsolutePath); + const filteredFiles = allFiles.filter((file) => shouldBeIncluded({file, ignore})); + return new Set(filteredFiles.map((file) => fullPath({file, sourceAbsolutePath}))); +}; + +/** + * Returns true if the file should be excluded based on the ignore patterns. + */ +const isIgnored = ({file, ignore}: {file: string; ignore: string[]}): boolean => + ignore.some((pattern) => minimatch(file, pattern, {matchBase: true})); + +/** + * Returns true if the file should be included for deletion. + */ +const shouldBeIncluded = (params: {file: string; ignore: string[]}): boolean => !isIgnored(params); From 395c86b8a11214fd534c315fa273cf908f2aae57 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Sun, 15 Mar 2026 12:52:40 +0100 Subject: [PATCH 4/7] chore: revert --- packages/cli-tools/src/index.ts | 2 -- packages/cli-tools/src/types/assets.ts | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/cli-tools/src/index.ts b/packages/cli-tools/src/index.ts index 3f3b2686e..62031cbcd 100644 --- a/packages/cli-tools/src/index.ts +++ b/packages/cli-tools/src/index.ts @@ -18,5 +18,3 @@ export * from './utils/format.utils'; export * from './utils/fs.utils'; export * from './utils/pkg.utils'; export * from './utils/prompt.utils'; - -export {FileDetails, FileExtension, MimeType} from './types/deploy'; diff --git a/packages/cli-tools/src/types/assets.ts b/packages/cli-tools/src/types/assets.ts index a17234294..05148bc22 100644 --- a/packages/cli-tools/src/types/assets.ts +++ b/packages/cli-tools/src/types/assets.ts @@ -1,12 +1,12 @@ import type {CliConfig} from '@junobuild/config'; import type {Asset} from '@junobuild/storage'; -export type ListAssets = ({startAfter}: {startAfter?: string}) => Promise; - export interface PrepareAssetsOptions { assertSourceDirExists?: (source: string) => void; } +export type ListAssets = ({startAfter}: {startAfter?: string}) => Promise; + export interface AssetsParams { config: CliConfig; listAssets: ListAssets; From 0a3734006c1512e403d7af769669a225f9d2b1e5 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Sun, 15 Mar 2026 12:53:49 +0100 Subject: [PATCH 5/7] chore: no dev --- packages/cli-tools/src/commands/prune.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/cli-tools/src/commands/prune.ts b/packages/cli-tools/src/commands/prune.ts index 2700b2703..81fb3a30a 100644 --- a/packages/cli-tools/src/commands/prune.ts +++ b/packages/cli-tools/src/commands/prune.ts @@ -23,17 +23,15 @@ const preparePrune = async ( try { const {files: sourceFiles} = await preparePruneServices(params); - if (sourceFiles.length === 0) { - spinner.stop(); + spinner.stop(); + if (sourceFiles.length === 0) { console.log(''); console.log('šŸ‘ No stale assets found. Satellite is already clean.'); return {result: 'skipped'}; } - spinner.stop(); - return { result: 'to-prune', files: sourceFiles From 634e3a259ba2981030ebf66c9ef3930346a759f8 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Sun, 15 Mar 2026 12:55:19 +0100 Subject: [PATCH 6/7] feat: result --- packages/cli-tools/src/commands/prune.ts | 14 +++++++++++--- packages/cli-tools/src/types/prune.ts | 4 +++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/packages/cli-tools/src/commands/prune.ts b/packages/cli-tools/src/commands/prune.ts index 81fb3a30a..7f26a29de 100644 --- a/packages/cli-tools/src/commands/prune.ts +++ b/packages/cli-tools/src/commands/prune.ts @@ -1,9 +1,15 @@ import ora from 'ora'; import {preparePrune as preparePruneServices} from '../services/prune.prepare.services'; import {prune as pruneServices} from '../services/prune.services'; -import type {PruneFilesFn, PruneFileStorage, PruneParams} from '../types/prune'; - -export const prune = async ({params, pruneFn}: {params: PruneParams; pruneFn: PruneFilesFn}) => { +import {PruneFilesFn, PruneFileStorage, PruneParams, PruneResult} from '../types/prune'; + +export const prune = async ({ + params, + pruneFn +}: { + params: PruneParams; + pruneFn: PruneFilesFn; +}): Promise => { const prepareResult = await preparePrune(params); if (prepareResult.result === 'skipped') { @@ -13,6 +19,8 @@ export const prune = async ({params, pruneFn}: {params: PruneParams; pruneFn: Pr const {files} = prepareResult; await pruneServices({files, pruneFn}); + + return {result: 'pruned', files}; }; const preparePrune = async ( diff --git a/packages/cli-tools/src/types/prune.ts b/packages/cli-tools/src/types/prune.ts index fe2028337..57394cdcf 100644 --- a/packages/cli-tools/src/types/prune.ts +++ b/packages/cli-tools/src/types/prune.ts @@ -1,5 +1,5 @@ import type {AssetsParams, PrepareAssetsOptions} from './assets'; -import type {PrepareDeployOptions} from './deploy'; +import {PrepareDeployOptions} from './deploy'; export type PreparePruneOptions = PrepareAssetsOptions; @@ -10,3 +10,5 @@ export interface PruneFileStorage { } export type PruneFilesFn = (params: {files: PruneFileStorage[]}) => Promise; + +export type PruneResult = {result: 'pruned'; files: PruneFileStorage[]} | {result: 'skipped'}; From 814b6bd9cdd02b898825fc88d9f1ff001849dfc1 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Sun, 15 Mar 2026 13:04:27 +0100 Subject: [PATCH 7/7] chore: lint --- packages/cli-tools/src/commands/prune.ts | 2 +- packages/cli-tools/src/types/prune.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli-tools/src/commands/prune.ts b/packages/cli-tools/src/commands/prune.ts index 7f26a29de..6fd6bff44 100644 --- a/packages/cli-tools/src/commands/prune.ts +++ b/packages/cli-tools/src/commands/prune.ts @@ -1,7 +1,7 @@ import ora from 'ora'; import {preparePrune as preparePruneServices} from '../services/prune.prepare.services'; import {prune as pruneServices} from '../services/prune.services'; -import {PruneFilesFn, PruneFileStorage, PruneParams, PruneResult} from '../types/prune'; +import type {PruneFilesFn, PruneFileStorage, PruneParams, PruneResult} from '../types/prune'; export const prune = async ({ params, diff --git a/packages/cli-tools/src/types/prune.ts b/packages/cli-tools/src/types/prune.ts index 57394cdcf..18e65a8a4 100644 --- a/packages/cli-tools/src/types/prune.ts +++ b/packages/cli-tools/src/types/prune.ts @@ -1,5 +1,5 @@ import type {AssetsParams, PrepareAssetsOptions} from './assets'; -import {PrepareDeployOptions} from './deploy'; +import type {PrepareDeployOptions} from './deploy'; export type PreparePruneOptions = PrepareAssetsOptions;