diff --git a/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts b/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts index 53bc50c1a..e8bfc9835 100644 --- a/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts +++ b/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts @@ -5,7 +5,15 @@ import { flags, handleAndLogError, log } from '@contentstack/cli-utilities'; import { AssetPublishData, BulkOperationResult, OperationType, ResourceType } from '../../../interfaces'; import { BaseBulkCommand } from '../../../base-bulk-command'; -import { $t, messages, fetchAssets, scanDataDirStats, BATCH_CONSTANTS, categorizeByScanStatus } from '../../../utils'; +import { + $t, + messages, + fetchAssets, + scanDataDirStats, + BATCH_CONSTANTS, + categorizeByScanStatus, + fillMissingFlags, +} from '../../../utils'; import type { DataDirScanStats } from '../../../utils'; import { AssetService } from '../../../services'; @@ -63,7 +71,7 @@ export default class BulkAssets extends BaseBulkCommand { if (flags['data-dir']) { return flags; } - return super.resolveFlagsInteractively(flags); + return fillMissingFlags(flags, { promptDataDir: true }); } async run(): Promise { diff --git a/packages/contentstack-bulk-operations/src/messages/index.ts b/packages/contentstack-bulk-operations/src/messages/index.ts index ab7e6f7d9..c51fe6023 100644 --- a/packages/contentstack-bulk-operations/src/messages/index.ts +++ b/packages/contentstack-bulk-operations/src/messages/index.ts @@ -379,6 +379,11 @@ const interactiveMsg = { TAXONOMY_UNSUPPORTED_RETRY: 'Retry and revert are not supported for bulk-taxonomies.', TAXONOMY_UNSUPPORTED_CROSS_PUBLISH: 'Cross-publish is not supported for bulk-taxonomies.', + // Data-dir (backup folder) prompt + USE_DATA_DIR_PROMPT: 'Do you want to publish assets using publish details from an import backup folder (data-dir)?', + ENTER_DATA_DIR: 'Enter the path to the import backup folder (data-dir):', + DATA_DIR_REQUIRED: 'Backup folder path is required', + // Errors NO_DELIVERY_TOKENS_FOUND: 'No delivery token aliases found. Add one using: csdx auth:tokens:add -a --delivery-token --api-key --environment --type delivery', diff --git a/packages/contentstack-bulk-operations/src/utils/interactive.ts b/packages/contentstack-bulk-operations/src/utils/interactive.ts index 2aa68cdc1..a17485e9a 100644 --- a/packages/contentstack-bulk-operations/src/utils/interactive.ts +++ b/packages/contentstack-bulk-operations/src/utils/interactive.ts @@ -151,7 +151,7 @@ async function promptForSourceAlias(): Promise { /** * Fills in missing required flags by prompting the user */ -export async function fillMissingFlags(flags: any): Promise { +export async function fillMissingFlags(flags: any, options?: { promptDataDir?: boolean }): Promise { const updatedFlags = { ...flags }; // Skip interactive mode for retry/revert operations @@ -169,9 +169,10 @@ export async function fillMissingFlags(flags: any): Promise { // Check if non-localized filter is used const isNonLocalized = updatedFlags.filter === FilterType.NON_LOCALIZED; const needsLocales = !isNonLocalized && (!updatedFlags.locales || updatedFlags.locales.length === 0); + const needsDataDir = options?.promptDataDir && !updatedFlags['data-dir']; // Only show interactive mode header if we need to prompt - if (needsCredentials || needsOperation || needsEnvironments || needsLocales) { + if (needsCredentials || needsOperation || needsEnvironments || needsLocales || needsDataDir) { cliux.print(messages.INTERACTIVE_MODE_START, { color: 'cyan' }); didPrompt = true; } @@ -191,6 +192,26 @@ export async function fillMissingFlags(flags: any): Promise { updatedFlags.operation = await promptForOperation(); } + // 2.5. Data-dir (import backup folder) — alternative to environments/locales for asset publish + if (needsDataDir) { + const useDataDir = await cliux.inquire({ + type: 'confirm', + name: 'useDataDir', + message: messages.USE_DATA_DIR_PROMPT, + default: false, + }); + if (useDataDir) { + updatedFlags['data-dir'] = await cliux.inquire({ + type: 'input', + name: 'dataDir', + message: messages.ENTER_DATA_DIR, + validate: (v: string) => (!v?.trim() ? messages.DATA_DIR_REQUIRED : true), + }); + cliux.print(messages.INTERACTIVE_MODE_COMPLETE, { color: 'green' }); + return updatedFlags; + } + } + // 3. Check for cross-publish mode const isCrossPublish = updatedFlags['source-env'] || updatedFlags['source-alias']; diff --git a/packages/contentstack-import/src/commands/cm/stacks/import.ts b/packages/contentstack-import/src/commands/cm/stacks/import.ts index 1d56aca9a..b1aadbb72 100644 --- a/packages/contentstack-import/src/commands/cm/stacks/import.ts +++ b/packages/contentstack-import/src/commands/cm/stacks/import.ts @@ -159,6 +159,11 @@ export default class ImportCommand extends Command { backupDir = importConfig.backupDir; //Note: Final summary is now handled by summary manager CLIProgressManager.printGlobalSummary(); + if (importConfig.assetScanningEnabled) { + cliux.print('\nAsset Scanning is enabled — assets were not published.', { color: 'yellow' }); + cliux.print(' Once scanning completes, publish your assets using:', { color: 'yellow' }); + cliux.print(` csdx cm:stacks:bulk-assets --data-dir ${backupDir} --stack-api-key ${importConfig.apiKey}`, { color: 'cyan' }); + } this.logSuccessAndBackupMessages(backupDir, importConfig); // Clear progress module setting now that import is complete clearProgressModuleSetting();