From fa179d0cbb9ea378240b9e3b335ac79bc332779f Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Wed, 24 Sep 2025 15:43:25 +0200 Subject: [PATCH] feat: juno hosting deploy or clear --- src/commands/clear.ts | 30 --------------- src/commands/deploy.ts | 22 ----------- src/commands/deprecated/clear.ts | 16 ++++++++ src/commands/deprecated/deploy.ts | 16 ++++++++ src/commands/hosting.ts | 37 +++++++++++++++++++ src/constants/help.constants.ts | 9 +++-- src/help/clear.help.ts | 29 --------------- src/help/help.ts | 8 ++-- src/help/hosting.clear.help.ts | 29 +++++++++++++++ ...{deploy.help.ts => hosting.deploy.help.ts} | 12 +++--- src/help/hosting.help.ts | 32 ++++++++++++++++ src/index.ts | 21 +++++++---- .../_deploy/deploy.individual.services.ts | 4 +- src/services/assets/clear.services.ts | 33 +++++++++++++++-- src/services/assets/deploy.services.ts | 20 ++++++++++ 15 files changed, 210 insertions(+), 108 deletions(-) delete mode 100644 src/commands/clear.ts delete mode 100644 src/commands/deploy.ts create mode 100644 src/commands/deprecated/clear.ts create mode 100644 src/commands/deprecated/deploy.ts create mode 100644 src/commands/hosting.ts delete mode 100644 src/help/clear.help.ts create mode 100644 src/help/hosting.clear.help.ts rename src/help/{deploy.help.ts => hosting.deploy.help.ts} (73%) create mode 100644 src/help/hosting.help.ts diff --git a/src/commands/clear.ts b/src/commands/clear.ts deleted file mode 100644 index cffbd7fb..00000000 --- a/src/commands/clear.ts +++ /dev/null @@ -1,30 +0,0 @@ -import {isNullish} from '@dfinity/utils'; -import {hasArgs, nextArg} from '@junobuild/cli-tools'; -import {yellow} from 'kleur'; -import {noJunoConfig} from '../configs/juno.config'; -import {clearAsset, clear as clearServices} from '../services/assets/clear.services'; -import {consoleNoConfigFound} from '../utils/msg.utils'; - -export const clear = async (args?: string[]) => { - if (await noJunoConfig()) { - consoleNoConfigFound(); - return; - } - - if (hasArgs({args, options: ['-f', '--fullpath', '--fullPath']})) { - const file = - nextArg({args, option: '-f'}) ?? - nextArg({args, option: '--fullpath'}) ?? - nextArg({args, option: '--fullPath'}); - - if (isNullish(file)) { - console.log(`You did not provide a ${yellow('fullPath')} to delete.`); - return; - } - - await clearAsset({fullPath: file}); - return; - } - - await clearServices(); -}; diff --git a/src/commands/deploy.ts b/src/commands/deploy.ts deleted file mode 100644 index c6d93cba..00000000 --- a/src/commands/deploy.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {hasArgs} from '@junobuild/cli-tools'; -import {noJunoConfig} from '../configs/juno.config'; -import {deploy as deployServices} from '../services/assets/deploy.services'; -import {config} from '../services/config/config.services'; -import {links} from '../services/links.services'; -import {init} from './init'; - -export const deploy = async (args?: string[]) => { - if (await noJunoConfig()) { - await init(); - } - - await deployServices(args); - - const configOption = hasArgs({args, options: ['--config']}); - if (configOption) { - console.log(''); - await config(args); - } - - await links(); -}; diff --git a/src/commands/deprecated/clear.ts b/src/commands/deprecated/clear.ts new file mode 100644 index 00000000..04c56776 --- /dev/null +++ b/src/commands/deprecated/clear.ts @@ -0,0 +1,16 @@ +import {logHelpEmulatorClear} from '../../help/hosting.clear.help'; +import {clear as clearServices} from '../../services/assets/clear.services'; + +/** + * @deprecated alias for backwards compatibility + */ +export const clear = async (args?: string[]) => { + await clearServices(args); +}; + +/** + * @deprecated + */ +export const helpClear = (args?: string[]) => { + logHelpEmulatorClear(args); +}; diff --git a/src/commands/deprecated/deploy.ts b/src/commands/deprecated/deploy.ts new file mode 100644 index 00000000..ecf28711 --- /dev/null +++ b/src/commands/deprecated/deploy.ts @@ -0,0 +1,16 @@ +import {logHelpHostingDeploy} from '../../help/hosting.deploy.help'; +import {deploy as deployServices} from '../../services/assets/deploy.services'; + +/** + * @deprecated alias for backwards compatibility + */ +export const deploy = async (args?: string[]) => { + await deployServices(args); +}; + +/** + * @deprecated + */ +export const helpDeploy = (args?: string[]) => { + logHelpHostingDeploy(args); +}; diff --git a/src/commands/hosting.ts b/src/commands/hosting.ts new file mode 100644 index 00000000..7f9d8dce --- /dev/null +++ b/src/commands/hosting.ts @@ -0,0 +1,37 @@ +import {red} from 'kleur'; +import {logHelpEmulatorClear} from '../help/hosting.clear.help'; +import {logHelpHostingDeploy} from '../help/hosting.deploy.help'; +import {logHelpHosting} from '../help/hosting.help'; +import {clear} from '../services/assets/clear.services'; +import {deploy} from '../services/assets/deploy.services'; + +export const hosting = async (args?: string[]) => { + const [subCommand] = args ?? []; + + switch (subCommand) { + case 'deploy': + await deploy(args); + break; + case 'clear': + await clear(args); + break; + default: + console.log(red('Unknown subcommand.')); + logHelpHosting(args); + } +}; + +export const helpHosting = (args?: string[]) => { + const [subCommand] = args ?? []; + + switch (subCommand) { + case 'deploy': + logHelpHostingDeploy(args); + break; + case 'clear': + logHelpEmulatorClear(args); + break; + default: + logHelpHosting(args); + } +}; diff --git a/src/constants/help.constants.ts b/src/constants/help.constants.ts index 2c6e6743..42e6de58 100644 --- a/src/constants/help.constants.ts +++ b/src/constants/help.constants.ts @@ -1,10 +1,9 @@ import {magenta, yellow} from 'kleur'; export const CHANGES_DESCRIPTION = 'Review and apply changes submitted to your module.'; -export const CLEAR_DESCRIPTION = - 'Clear existing app code by removing JavaScript, HTML, CSS, and other files from your satellite.'; export const CONFIG_DESCRIPTION = 'Apply configuration to satellite.'; -export const DEPLOY_DESCRIPTION = 'Deploy your app to your satellite.'; +export const HOSTING_DESCRIPTION = + 'Deploy or clear the frontend code of your app on your satellite.'; export const EMULATOR_DESCRIPTION = 'Handle tasks related to the emulator like starting/stopping a local network.'; export const FUNCTIONS_DESCRIPTION = "Build and upgrade your satellite's serverless functions."; @@ -25,6 +24,10 @@ export const WHOAMI_DESCRIPTION = 'Display your current profile, access key, and links to your satellite.'; export const RUN_DESCRIPTION = 'Run a custom script in the CLI context.'; +export const HOSTING_DEPLOY_DESCRIPTION = 'Deploy your app to your satellite.'; +export const HOSTING_CLEAR_DESCRIPTION = + 'Remove frontend files (JS, HTML, CSS, etc.) from your satellite.'; + export const EMULATOR_START_DESCRIPTION = 'Start the emulator for local development.'; export const EMULATOR_WAIT_DESCRIPTION = 'Wait until the emulator is ready.'; diff --git a/src/help/clear.help.ts b/src/help/clear.help.ts deleted file mode 100644 index 49d5cd9a..00000000 --- a/src/help/clear.help.ts +++ /dev/null @@ -1,29 +0,0 @@ -import {cyan, green, yellow} from 'kleur'; -import {CLEAR_DESCRIPTION, OPTIONS_ENV, OPTION_HELP} from '../constants/help.constants'; -import {helpOutput} from './common.help'; -import {TITLE} from './help'; - -const usage = `Usage: ${green('juno')} ${cyan('clear')} ${yellow('[options]')} - -Options: - ${yellow('-f, --fullPath')} Clear a particular file of your app. - ${OPTIONS_ENV} - ${OPTION_HELP}`; - -const doc = `${CLEAR_DESCRIPTION} - -\`\`\` -${usage} -\`\`\` -`; - -const help = `${TITLE} - -${CLEAR_DESCRIPTION} - -${usage} -`; - -export const logHelpClear = (args?: string[]) => { - console.log(helpOutput(args) === 'doc' ? doc : help); -}; diff --git a/src/help/help.ts b/src/help/help.ts index 12d4ac47..5419a6c8 100644 --- a/src/help/help.ts +++ b/src/help/help.ts @@ -1,11 +1,10 @@ import {cyan, green, grey} from 'kleur'; import {version} from '../../package.json'; import { - CLEAR_DESCRIPTION, CONFIG_DESCRIPTION, - DEPLOY_DESCRIPTION, EMULATOR_DESCRIPTION, FUNCTIONS_DESCRIPTION, + HOSTING_DESCRIPTION, INIT_DESCRIPTION, LOGIN_DESCRIPTION, LOGOUT_DESCRIPTION, @@ -35,13 +34,12 @@ ${TITLE} Usage: ${green('juno')} ${cyan('')} Commands: - ${cyan('clear')} ${CLEAR_DESCRIPTION} ${cyan('config')} ${CONFIG_DESCRIPTION} - ${cyan('deploy')} ${DEPLOY_DESCRIPTION} ${cyan('emulator')} ${EMULATOR_DESCRIPTION} ${cyan('functions')} ${FUNCTIONS_DESCRIPTION} - ${cyan('init')} ${INIT_DESCRIPTION} ${cyan('help')} Display help information. + ${cyan('hosting')} ${HOSTING_DESCRIPTION} + ${cyan('init')} ${INIT_DESCRIPTION} ${cyan('login')} ${LOGIN_DESCRIPTION} ${cyan('logout')} ${LOGOUT_DESCRIPTION} ${cyan('open')} ${OPEN_DESCRIPTION} diff --git a/src/help/hosting.clear.help.ts b/src/help/hosting.clear.help.ts new file mode 100644 index 00000000..0cac26db --- /dev/null +++ b/src/help/hosting.clear.help.ts @@ -0,0 +1,29 @@ +import {cyan, green, magenta, yellow} from 'kleur'; +import {HOSTING_CLEAR_DESCRIPTION, OPTIONS_ENV, OPTION_HELP} from '../constants/help.constants'; +import {helpOutput} from './common.help'; +import {TITLE} from './help'; + +const usage = `Usage: ${green('juno')} ${cyan('hosting')} ${magenta('clear')} ${yellow('[options]')} + +Options: + ${yellow('-f, --fullPath')} Clear a particular file of your app. + ${OPTIONS_ENV} + ${OPTION_HELP}`; + +const doc = `${HOSTING_CLEAR_DESCRIPTION} + +\`\`\` +${usage} +\`\`\` +`; + +const help = `${TITLE} + +${HOSTING_CLEAR_DESCRIPTION} + +${usage} +`; + +export const logHelpEmulatorClear = (args?: string[]) => { + console.log(helpOutput(args) === 'doc' ? doc : help); +}; diff --git a/src/help/deploy.help.ts b/src/help/hosting.deploy.help.ts similarity index 73% rename from src/help/deploy.help.ts rename to src/help/hosting.deploy.help.ts index 35624cd3..98b7599b 100644 --- a/src/help/deploy.help.ts +++ b/src/help/hosting.deploy.help.ts @@ -1,6 +1,6 @@ -import {cyan, green, yellow} from 'kleur'; +import {cyan, green, magenta, yellow} from 'kleur'; import { - DEPLOY_DESCRIPTION, + HOSTING_DEPLOY_DESCRIPTION, NOTE_KEEP_STAGED, OPTION_HELP, OPTION_KEEP_STAGED, @@ -9,7 +9,7 @@ import { import {helpOutput} from './common.help'; import {TITLE} from './help'; -const usage = `Usage: ${green('juno')} ${cyan('deploy')} ${yellow('[options]')} +const usage = `Usage: ${green('juno')} ${cyan('hosting')} ${magenta('deploy')} ${yellow('[options]')} Options: ${yellow('--batch')} Number of files to upload in parallel per batch (default: 50). @@ -25,7 +25,7 @@ Notes: - ${NOTE_KEEP_STAGED}`; -const doc = `${DEPLOY_DESCRIPTION} +const doc = `${HOSTING_DEPLOY_DESCRIPTION} \`\`\` ${usage} @@ -34,11 +34,11 @@ ${usage} const help = `${TITLE} -${DEPLOY_DESCRIPTION} +${HOSTING_DEPLOY_DESCRIPTION} ${usage} `; -export const logHelpDeploy = (args?: string[]) => { +export const logHelpHostingDeploy = (args?: string[]) => { console.log(helpOutput(args) === 'doc' ? doc : help); }; diff --git a/src/help/hosting.help.ts b/src/help/hosting.help.ts new file mode 100644 index 00000000..888bb2c2 --- /dev/null +++ b/src/help/hosting.help.ts @@ -0,0 +1,32 @@ +import {cyan, green, magenta, yellow} from 'kleur'; +import { + HOSTING_CLEAR_DESCRIPTION, + HOSTING_DEPLOY_DESCRIPTION, + HOSTING_DESCRIPTION +} from '../constants/help.constants'; +import {helpOutput} from './common.help'; +import {TITLE} from './help'; + +const usage = `Usage: ${green('juno')} ${cyan('hosting')} ${magenta('')} ${yellow('[options]')} + +Subcommands: + ${magenta('deploy')} ${HOSTING_DEPLOY_DESCRIPTION} + ${magenta('clear')} ${HOSTING_CLEAR_DESCRIPTION}`; + +const doc = `${HOSTING_DESCRIPTION} + +\`\`\` +${usage} +\`\`\` +`; + +const help = `${TITLE} + +${HOSTING_DESCRIPTION} + +${usage} +`; + +export const logHelpHosting = (args?: string[]) => { + console.log(helpOutput(args) === 'doc' ? doc : help); +}; diff --git a/src/index.ts b/src/index.ts index 5c794c26..08deccc6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,12 +2,13 @@ import {hasArgs} from '@junobuild/cli-tools'; import {red} from 'kleur'; import {login, logout} from './commands/auth'; import {changes, helpChanges} from './commands/changes'; -import {clear} from './commands/clear'; import {config} from './commands/config'; -import {deploy} from './commands/deploy'; +import {clear, helpClear} from './commands/deprecated/clear'; +import {deploy, helpDeploy} from './commands/deprecated/deploy'; import {dev, helpDev} from './commands/dev'; import {emulator, helpEmulator} from './commands/emulator'; import {functions, helpFunctions} from './commands/functions'; +import {helpHosting, hosting} from './commands/hosting'; import {init} from './commands/init'; import {open} from './commands/open'; import {helpRun, run as runCmd} from './commands/run'; @@ -17,9 +18,7 @@ import {status} from './commands/status'; import {upgrade} from './commands/upgrade'; import {version as versionCommand} from './commands/version'; import {whoami} from './commands/whoami'; -import {logHelpClear} from './help/clear.help'; import {logHelpConfig} from './help/config.help'; -import {logHelpDeploy} from './help/deploy.help'; import {help} from './help/help'; import {logHelpInit} from './help/init.help'; import {logHelpLogin} from './help/login.help'; @@ -71,14 +70,17 @@ export const run = async () => { case 'open': logHelpOpen(args); break; - case 'clear': - logHelpClear(args); - break; case 'config': logHelpConfig(args); break; + case 'clear': + helpClear(args); + break; case 'deploy': - logHelpDeploy(args); + helpDeploy(args); + break; + case 'hosting': + helpHosting(args); break; case 'emulator': helpEmulator(args); @@ -170,6 +172,9 @@ export const run = async () => { case 'emulator': await emulator(args); break; + case 'hosting': + await hosting(args); + break; case 'dev': await dev(args); break; diff --git a/src/services/assets/_deploy/deploy.individual.services.ts b/src/services/assets/_deploy/deploy.individual.services.ts index 4f52eb6b..1411c72c 100644 --- a/src/services/assets/_deploy/deploy.individual.services.ts +++ b/src/services/assets/_deploy/deploy.individual.services.ts @@ -6,7 +6,7 @@ import { type DeployOptions, type UploadFileFnParams } from '../../../types/deploy'; -import {clear} from '../clear.services'; +import {executeClear} from '../clear.services'; import {executeDeployImmediate} from './deploy.execute.services'; export const deployImmediate = async ({ @@ -16,7 +16,7 @@ export const deployImmediate = async ({ clearOption: boolean; } & DeployOptions) => { if (clearOption) { - await clear(); + await executeClear(); } const deployFn = async ({deploy: {params, upload}}: DeployFnParams): Promise => diff --git a/src/services/assets/clear.services.ts b/src/services/assets/clear.services.ts index 64ae0feb..64ea9873 100644 --- a/src/services/assets/clear.services.ts +++ b/src/services/assets/clear.services.ts @@ -1,11 +1,38 @@ +import {isNullish} from '@dfinity/utils'; import {deleteAssets, listCustomDomains, setCustomDomains} from '@junobuild/admin'; -import {COLLECTION_DAPP} from '@junobuild/cli-tools'; +import {COLLECTION_DAPP, hasArgs, nextArg} from '@junobuild/cli-tools'; import {deleteAsset} from '@junobuild/core'; -import {green} from 'kleur'; +import {green, yellow} from 'kleur'; import ora from 'ora'; +import {noJunoConfig} from '../../configs/juno.config'; +import {consoleNoConfigFound} from '../../utils/msg.utils'; import {assertConfigAndLoadSatelliteContext} from '../../utils/satellite.utils'; -export const clear = async () => { +export const clear = async (args?: string[]) => { + if (await noJunoConfig()) { + consoleNoConfigFound(); + return; + } + + if (hasArgs({args, options: ['-f', '--fullpath', '--fullPath']})) { + const file = + nextArg({args, option: '-f'}) ?? + nextArg({args, option: '--fullpath'}) ?? + nextArg({args, option: '--fullPath'}); + + if (isNullish(file)) { + console.log(`You did not provide a ${yellow('fullPath')} to delete.`); + return; + } + + await clearAsset({fullPath: file}); + return; + } + + await executeClear(); +}; + +export const executeClear = async () => { const {satellite} = await assertConfigAndLoadSatelliteContext(); const spinner = ora('Clearing app assets...').start(); diff --git a/src/services/assets/deploy.services.ts b/src/services/assets/deploy.services.ts index 0660bbd5..139b8414 100644 --- a/src/services/assets/deploy.services.ts +++ b/src/services/assets/deploy.services.ts @@ -2,13 +2,33 @@ import {isEmptyString} from '@dfinity/utils'; import {hasArgs, nextArg} from '@junobuild/cli-tools'; import {yellow} from 'kleur'; import {compare} from 'semver'; +import {init} from '../../commands/init'; +import {noJunoConfig} from '../../configs/juno.config'; import {type DeployOptions} from '../../types/deploy'; import {clearProposalStagedAssets} from '../changes/changes.clear.services'; +import {config} from '../config/config.services'; +import {links} from '../links.services'; import {getSatelliteVersion} from '../version.services'; import {deployImmediate} from './_deploy/deploy.individual.services'; import {deployWithProposal as executeDeployWithProposal} from './_deploy/deploy.with-proposal.services'; export const deploy = async (args?: string[]) => { + if (await noJunoConfig()) { + await init(); + } + + await executeDeploy(args); + + const configOption = hasArgs({args, options: ['--config']}); + if (configOption) { + console.log(''); + await config(args); + } + + await links(); +}; + +const executeDeploy = async (args?: string[]) => { // TODO: Remove fetching the version. We use it for backwards compatibility reasons. const result = await getSatelliteVersion();