diff --git a/package-lock.json b/package-lock.json index 9dde54de..43ed30d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "@dfinity/identity": "^2.3.0", "@dfinity/principal": "^2.3.0", "@junobuild/admin": "^0.5.0-next-2025-06-04.3", - "@junobuild/cdn": "^0.1.0-next-2025-06-10.2", + "@junobuild/cdn": "^0.1.0-next-2025-06-10.3", "@junobuild/cli-tools": "^0.2.0-next-2025-06-04.3", "@junobuild/config": "^0.1.8", "@junobuild/config-loader": "^0.2.1", @@ -1480,9 +1480,9 @@ } }, "node_modules/@junobuild/cdn": { - "version": "0.1.0-next-2025-06-10.2", - "resolved": "https://registry.npmjs.org/@junobuild/cdn/-/cdn-0.1.0-next-2025-06-10.2.tgz", - "integrity": "sha512-ssmqucSvkEjTr/N8998FUFAeGybRpn/cMkoK9vzvMHprlfc2PHhxxpdcnjI8/UuaDKb7zpEYkGAB061jb7EzlQ==", + "version": "0.1.0-next-2025-06-10.3", + "resolved": "https://registry.npmjs.org/@junobuild/cdn/-/cdn-0.1.0-next-2025-06-10.3.tgz", + "integrity": "sha512-BotBHWsZWindOsnio03jZ/hZx/9JhK/WzwhJ871jrn9o30jeW50Ziyjx6LUpkfRfoTNe/us+5DFqhFX+2UsEmQ==", "license": "MIT", "peerDependencies": { "@dfinity/agent": "*", @@ -8004,9 +8004,9 @@ "requires": {} }, "@junobuild/cdn": { - "version": "0.1.0-next-2025-06-10.2", - "resolved": "https://registry.npmjs.org/@junobuild/cdn/-/cdn-0.1.0-next-2025-06-10.2.tgz", - "integrity": "sha512-ssmqucSvkEjTr/N8998FUFAeGybRpn/cMkoK9vzvMHprlfc2PHhxxpdcnjI8/UuaDKb7zpEYkGAB061jb7EzlQ==", + "version": "0.1.0-next-2025-06-10.3", + "resolved": "https://registry.npmjs.org/@junobuild/cdn/-/cdn-0.1.0-next-2025-06-10.3.tgz", + "integrity": "sha512-BotBHWsZWindOsnio03jZ/hZx/9JhK/WzwhJ871jrn9o30jeW50Ziyjx6LUpkfRfoTNe/us+5DFqhFX+2UsEmQ==", "requires": {} }, "@junobuild/cli-tools": { diff --git a/package.json b/package.json index b082f1d7..33302676 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "@dfinity/identity": "^2.3.0", "@dfinity/principal": "^2.3.0", "@junobuild/admin": "^0.5.0-next-2025-06-04.3", - "@junobuild/cdn": "^0.1.0-next-2025-06-10.2", + "@junobuild/cdn": "^0.1.0-next-2025-06-10.3", "@junobuild/cli-tools": "^0.2.0-next-2025-06-04.3", "@junobuild/config": "^0.1.8", "@junobuild/config-loader": "^0.2.1", diff --git a/src/help/changes.apply.help.ts b/src/help/changes.apply.help.ts index a080f507..e56bac4f 100644 --- a/src/help/changes.apply.help.ts +++ b/src/help/changes.apply.help.ts @@ -12,6 +12,7 @@ const usage = `Usage: ${green('juno')} ${cyan('changes')} ${magenta('apply')} ${ Options: ${yellow('-i, --id')} The ID of the change to apply. + ${yellow('--snapshot')} Create a snapshot before applying. ${OPTION_HASH} ${OPTION_KEEP_STAGED} ${OPTION_HELP}`; diff --git a/src/services/changes/changes.apply.services.ts b/src/services/changes/changes.apply.services.ts index 73671452..c439df94 100644 --- a/src/services/changes/changes.apply.services.ts +++ b/src/services/changes/changes.apply.services.ts @@ -1,44 +1,73 @@ import {hexStringToUint8Array} from '@dfinity/utils'; -import {commitProposal} from '@junobuild/cdn'; +import { + ApplyProposalProgressStep, + executeApplyProposal, + type ApplyProposalParams, + type ApplyProposalProgress +} from '@junobuild/cdn'; +import {hasArgs} from '@junobuild/cli-tools'; import ora from 'ora'; import type {SatelliteParametersWithId} from '../../types/satellite'; import {readChangesIdAndHash} from '../../utils/changes.utils'; import {assertConfigAndLoadSatelliteContext} from '../../utils/satellite.utils'; -import {clearProposalStagedAssets} from './changes.clear.services'; export const applyChanges = async (args?: string[]) => { const {satellite} = await assertConfigAndLoadSatelliteContext(); const {proposalId, hash} = readChangesIdAndHash(args); - await executeApplyChanges({satellite, proposalId, hash}); + const keepAssets = hasArgs({args, options: ['-k', '--keep-staged']}); + const takeSnapshot = hasArgs({args, options: ['--snapshot']}); - await clearProposalStagedAssets({ - args, - proposalId + await executeApplyChanges({ + satellite, + proposalId, + hash, + clearProposalAssets: !keepAssets, + takeSnapshot }); }; const executeApplyChanges = async ({ satellite, proposalId, - hash + hash, + ...rest }: { proposalId: bigint; hash: string; satellite: SatelliteParametersWithId; -}) => { - const spinner = ora('Applying...').start(); +} & Pick) => { + const spinner = ora().start(); + + const onProgress = ({step}: ApplyProposalProgress) => { + switch (step) { + case ApplyProposalProgressStep.TakingSnapshot: + spinner.text = 'Creating a snapshot...'; + break; + case ApplyProposalProgressStep.CommittingProposal: + spinner.text = 'Applying update...'; + break; + case ApplyProposalProgressStep.ClearingProposalAssets: + spinner.text = 'Clearing staged assets...'; + break; + case ApplyProposalProgressStep.PostApply: + spinner.text = 'Reloading...'; + break; + } + }; try { - await commitProposal({ + await executeApplyProposal({ cdn: { satellite }, proposal: { proposal_id: proposalId, sha256: hexStringToUint8Array(hash) - } + }, + onProgress, + ...rest }); spinner.stop(); diff --git a/src/services/changes/changes.reject.services.ts b/src/services/changes/changes.reject.services.ts index 07f18f9e..35b6e75b 100644 --- a/src/services/changes/changes.reject.services.ts +++ b/src/services/changes/changes.reject.services.ts @@ -1,44 +1,63 @@ import {hexStringToUint8Array} from '@dfinity/utils'; -import {rejectProposal} from '@junobuild/cdn'; +import { + type RejectProposalParams, + type RejectProposalProgress, + RejectProposalProgressStep, + executeRejectProposal +} from '@junobuild/cdn'; +import {hasArgs} from '@junobuild/cli-tools'; import ora from 'ora'; import type {SatelliteParametersWithId} from '../../types/satellite'; import {readChangesIdAndHash} from '../../utils/changes.utils'; import {assertConfigAndLoadSatelliteContext} from '../../utils/satellite.utils'; -import {clearProposalStagedAssets} from './changes.clear.services'; export const rejectChanges = async (args?: string[]) => { const {satellite} = await assertConfigAndLoadSatelliteContext(); const {proposalId, hash} = readChangesIdAndHash(args); - await executeRejectChanges({satellite, proposalId, hash}); + const keepAssets = hasArgs({args, options: ['-k', '--keep-staged']}); - await clearProposalStagedAssets({ - args, - proposalId - }); + await executeRejectChanges({satellite, proposalId, hash, clearProposalAssets: !keepAssets}); }; const executeRejectChanges = async ({ satellite, proposalId, - hash + hash, + ...rest }: { proposalId: bigint; hash: string; satellite: SatelliteParametersWithId; -}) => { - const spinner = ora('Rejecting...').start(); +} & Pick) => { + const spinner = ora().start(); + + const onProgress = ({step}: RejectProposalProgress) => { + switch (step) { + case RejectProposalProgressStep.RejectingProposal: + spinner.text = 'Rejecting...'; + break; + case RejectProposalProgressStep.ClearingProposalAssets: + spinner.text = 'Clearing staged assets...'; + break; + case RejectProposalProgressStep.PostReject: + spinner.text = 'Reloading...'; + break; + } + }; try { - await rejectProposal({ + await executeRejectProposal({ cdn: { satellite }, proposal: { proposal_id: proposalId, sha256: hexStringToUint8Array(hash) - } + }, + onProgress, + ...rest }); spinner.stop();