diff --git a/.talismanrc b/.talismanrc index 7efa0e61f..0315195c9 100644 --- a/.talismanrc +++ b/.talismanrc @@ -39,4 +39,8 @@ fileignoreconfig: checksum: a64a4d396eddd936a63b799eff58c5c6660b5dcaa3a310fd8b09a027932f1789 - filename: packages/contentstack-migration/README.md checksum: e96006c1a948f766c88ae972b29582fa58eaf8184606bf011eebddc5a06cd7b6 +- filename: packages/contentstack-asset-management/test/unit/import/base.test.ts + checksum: 5985575816f6e298c6c4e8169389d960b2a9ab3d43336e8c9e9b25302ba10353 +- filename: packages/contentstack-asset-management/test/unit/export/base.test.ts + checksum: 68711c9a31e14982195efdb352903fe7782085a6a56a10b963cd0fd8db7ec668 version: "" diff --git a/packages/contentstack-asset-management/src/export/base.ts b/packages/contentstack-asset-management/src/export/base.ts index 13e4016e1..43dd2ac91 100644 --- a/packages/contentstack-asset-management/src/export/base.ts +++ b/packages/contentstack-asset-management/src/export/base.ts @@ -1,6 +1,6 @@ import { resolve as pResolve } from 'node:path'; import { writeFile } from 'node:fs/promises'; -import { FsUtility, log, CLIProgressManager, configHandler } from '@contentstack/cli-utilities'; +import { FsUtility, log, CLIProgressManager } from '@contentstack/cli-utilities'; import type { CSAssetsAPIConfig } from '../types/cs-assets-api'; import type { ExportContext } from '../types/export-types'; @@ -48,9 +48,7 @@ export class CSAssetsExportAdapter extends CSAssetsAdapter { this.progressManager = this.parentProgressManager; return this.parentProgressManager; } - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; - this.progressManager = CLIProgressManager.createNested(moduleName, showConsoleLogs); + this.progressManager = CLIProgressManager.createNested(moduleName); return this.progressManager; } diff --git a/packages/contentstack-asset-management/src/export/spaces.ts b/packages/contentstack-asset-management/src/export/spaces.ts index df1bc6f57..9e831e25a 100644 --- a/packages/contentstack-asset-management/src/export/spaces.ts +++ b/packages/contentstack-asset-management/src/export/spaces.ts @@ -1,6 +1,6 @@ import { resolve as pResolve } from 'node:path'; import { mkdir } from 'node:fs/promises'; -import { log, CLIProgressManager, configHandler, handleAndLogError } from '@contentstack/cli-utilities'; +import { log, CLIProgressManager, handleAndLogError } from '@contentstack/cli-utilities'; import type { AssetManagementExportOptions, CSAssetsAPIConfig } from '../types/cs-assets-api'; import type { ExportContext } from '../types/export-types'; @@ -193,9 +193,7 @@ export class ExportSpaces { this.progressManager = this.parentProgressManager; return this.parentProgressManager; } - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; - this.progressManager = CLIProgressManager.createNested(CS_ASSETS_MAIN_PROCESS_NAME, showConsoleLogs); + this.progressManager = CLIProgressManager.createNested(CS_ASSETS_MAIN_PROCESS_NAME); return this.progressManager; } } diff --git a/packages/contentstack-asset-management/src/import/base.ts b/packages/contentstack-asset-management/src/import/base.ts index 7bb8e9914..6aa10cb68 100644 --- a/packages/contentstack-asset-management/src/import/base.ts +++ b/packages/contentstack-asset-management/src/import/base.ts @@ -1,5 +1,5 @@ import { resolve as pResolve } from 'node:path'; -import { CLIProgressManager, configHandler } from '@contentstack/cli-utilities'; +import { CLIProgressManager } from '@contentstack/cli-utilities'; import type { CSAssetsAPIConfig, ImportContext } from '../types/cs-assets-api'; import { CSAssetsAdapter } from '../utils/cs-assets-api-adapter'; @@ -46,9 +46,7 @@ export class CSAssetsImportAdapter extends CSAssetsAdapter { this.progressManager = this.parentProgressManager; return this.parentProgressManager; } - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; - this.progressManager = CLIProgressManager.createNested(moduleName, showConsoleLogs); + this.progressManager = CLIProgressManager.createNested(moduleName); return this.progressManager; } diff --git a/packages/contentstack-asset-management/src/import/spaces.ts b/packages/contentstack-asset-management/src/import/spaces.ts index faec9d13d..e2ac54d45 100644 --- a/packages/contentstack-asset-management/src/import/spaces.ts +++ b/packages/contentstack-asset-management/src/import/spaces.ts @@ -1,7 +1,7 @@ import { join, resolve as pResolve } from 'node:path'; import { mkdirSync, readdirSync, statSync } from 'node:fs'; import { writeFile } from 'node:fs/promises'; -import { log, CLIProgressManager, configHandler, handleAndLogError } from '@contentstack/cli-utilities'; +import { log, CLIProgressManager, handleAndLogError } from '@contentstack/cli-utilities'; import type { CSAssetsAPIConfig, @@ -231,9 +231,7 @@ export class ImportSpaces { this.progressManager = this.parentProgressManager; return this.parentProgressManager; } - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; - this.progressManager = CLIProgressManager.createNested(CS_ASSETS_MAIN_PROCESS_NAME, showConsoleLogs); + this.progressManager = CLIProgressManager.createNested(CS_ASSETS_MAIN_PROCESS_NAME); return this.progressManager; } } diff --git a/packages/contentstack-asset-management/test/unit/export/base.test.ts b/packages/contentstack-asset-management/test/unit/export/base.test.ts index 22f41d67e..dabae6c36 100644 --- a/packages/contentstack-asset-management/test/unit/export/base.test.ts +++ b/packages/contentstack-asset-management/test/unit/export/base.test.ts @@ -105,8 +105,7 @@ describe('CSAssetsExportAdapter (base)', () => { }); describe('createNestedProgress', () => { - it('should create a new CLIProgressManager with the given name and showConsoleLogs flag', () => { - sinon.stub(configHandler, 'get').returns({ showConsoleLogs: true }); + it('should create a new CLIProgressManager with the given name', () => { const fakeProgress = { tick: sinon.stub() } as any; const createNestedStub = sinon.stub(CLIProgressManager, 'createNested').returns(fakeProgress); @@ -126,15 +125,14 @@ describe('CSAssetsExportAdapter (base)', () => { expect(result).to.equal(fakeParent); }); - it('should default showConsoleLogs to false when log config is missing', () => { - sinon.stub(configHandler, 'get').returns(null); + it('should not pass a showConsoleLogs argument — the manager resolves the policy itself', () => { const fakeProgress = { tick: sinon.stub() } as any; const createNestedStub = sinon.stub(CLIProgressManager, 'createNested').returns(fakeProgress); const adapter = new TestAdapter(apiConfig, exportContext); adapter.callCreateNestedProgress('test'); - expect(createNestedStub.firstCall.args[1]).to.be.false; + expect(createNestedStub.firstCall.args).to.deep.equal(['test']); }); }); diff --git a/packages/contentstack-asset-management/test/unit/import/base.test.ts b/packages/contentstack-asset-management/test/unit/import/base.test.ts index eee4c3c9b..86db72a3b 100644 --- a/packages/contentstack-asset-management/test/unit/import/base.test.ts +++ b/packages/contentstack-asset-management/test/unit/import/base.test.ts @@ -75,7 +75,6 @@ describe('CSAssetsImportAdapter (base)', () => { describe('createNestedProgress', () => { it('creates a CLIProgressManager when no parent is set', () => { - sinon.stub(configHandler, 'get').returns({ showConsoleLogs: true }); const fakeProgress = { tick: sinon.stub() } as any; const createNestedStub = sinon.stub(CLIProgressManager, 'createNested').returns(fakeProgress); const adapter = new TestImportAdapter(apiConfig, importContext); @@ -92,13 +91,12 @@ describe('CSAssetsImportAdapter (base)', () => { expect(result).to.equal(fakeParent); }); - it('defaults showConsoleLogs to false when log config is missing', () => { - sinon.stub(configHandler, 'get').returns(null); + it('passes no showConsoleLogs argument — the manager resolves the policy itself', () => { const fakeProgress = { tick: sinon.stub() } as any; const createNestedStub = sinon.stub(CLIProgressManager, 'createNested').returns(fakeProgress); const adapter = new TestImportAdapter(apiConfig, importContext); adapter.callCreateNestedProgress('test'); - expect(createNestedStub.firstCall.args[1]).to.be.false; + expect(createNestedStub.firstCall.args).to.deep.equal(['test']); }); }); diff --git a/packages/contentstack-audit/src/audit-base-command.ts b/packages/contentstack-audit/src/audit-base-command.ts index e099280c7..ffca7ebae 100644 --- a/packages/contentstack-audit/src/audit-base-command.ts +++ b/packages/contentstack-audit/src/audit-base-command.ts @@ -10,9 +10,8 @@ import { TableFlags, TableHeader, log, - configHandler, + isConsoleLogEnabled, CLIProgressManager, - clearProgressModuleSetting, readContentTypeSchemas, readGlobalFieldSchemas, generateUid, @@ -73,15 +72,6 @@ export abstract class AuditBaseCommand extends BaseCommand { this.currentCommand = command; - // Set progress supported module and console logs setting BEFORE any log calls - // This ensures the logger respects the setting when it's initialized - const logConfig = configHandler.get('log') || {}; - // Default to false so progress bars are shown instead of console logs - if (logConfig.showConsoleLogs === undefined) { - configHandler.set('log.showConsoleLogs', false); - } - configHandler.set('log.progressSupportedModule', 'audit'); - // Initialize global summary for progress tracking CLIProgressManager.initializeGlobalSummary('AUDIT', '', 'Auditing content...'); @@ -190,9 +180,6 @@ export abstract class AuditBaseCommand extends BaseCommand = await new ModuleDataReader(cloneDeep(constructorParam)).run(); log.debug(`Data module wise: ${JSON.stringify(dataModuleWise)}`, this.auditContext); - // Extract logConfig and showConsoleLogs once before the loop to reuse throughout - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; + // Resolve the console-log policy once before the loop to reuse throughout + const showConsoleLogs = isConsoleLogEnabled(); for (const module of this.sharedConfig.flags.modules || this.sharedConfig.modules) { // Update audit context with current module diff --git a/packages/contentstack-audit/src/modules/assets.ts b/packages/contentstack-audit/src/modules/assets.ts index 6d574fa4b..4468e95aa 100644 --- a/packages/contentstack-audit/src/modules/assets.ts +++ b/packages/contentstack-audit/src/modules/assets.ts @@ -1,6 +1,6 @@ import { join, resolve } from 'path'; import { existsSync, readFileSync, readdirSync, writeFileSync } from 'fs'; -import { FsUtility, sanitizePath, cliux, log, configHandler } from '@contentstack/cli-utilities'; +import { FsUtility, sanitizePath, cliux, log, isConsoleLogEnabled } from '@contentstack/cli-utilities'; import { ContentTypeStruct, CtConstructorParam, ModuleConstructorParam, EntryStruct } from '../types'; import auditConfig from '../config'; import { $t, auditFixMsg, auditMsg, commonMsg } from '../messages'; @@ -298,8 +298,7 @@ export default class Assets extends BaseClass { */ async lookForReference(): Promise { log.debug('Starting asset reference validation', this.config.auditContext); - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; + const showConsoleLogs = isConsoleLogEnabled(); if (!this.resolvedBasePaths.length) { this.resolvedBasePaths = this.resolveAssetBasePaths(); diff --git a/packages/contentstack-audit/src/modules/base-class.ts b/packages/contentstack-audit/src/modules/base-class.ts index d1a8329cf..17c2afc13 100644 --- a/packages/contentstack-audit/src/modules/base-class.ts +++ b/packages/contentstack-audit/src/modules/base-class.ts @@ -1,4 +1,4 @@ -import { CLIProgressManager, configHandler } from '@contentstack/cli-utilities'; +import { CLIProgressManager } from '@contentstack/cli-utilities'; import { ConfigType, ModuleConstructorParam } from '../types'; export default abstract class BaseClass { @@ -15,9 +15,7 @@ export default abstract class BaseClass { */ protected createSimpleProgress(moduleName: string, total?: number): CLIProgressManager { this.currentModuleName = moduleName; - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; - this.progressManager = CLIProgressManager.createSimple(moduleName, total, showConsoleLogs); + this.progressManager = CLIProgressManager.createSimple(moduleName, total); return this.progressManager; } @@ -26,9 +24,7 @@ export default abstract class BaseClass { */ protected createNestedProgress(moduleName: string): CLIProgressManager { this.currentModuleName = moduleName; - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; - this.progressManager = CLIProgressManager.createNested(moduleName, showConsoleLogs); + this.progressManager = CLIProgressManager.createNested(moduleName); return this.progressManager; } @@ -44,13 +40,6 @@ export default abstract class BaseClass { * Execute action with loading spinner (if console logs are disabled) */ protected async withLoadingSpinner(message: string, action: () => Promise): Promise { - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; - - if (showConsoleLogs) { - // If console logs are enabled, don't show spinner, just execute the action - return await action(); - } return await CLIProgressManager.withLoadingSpinner(message, action); } } diff --git a/packages/contentstack-audit/test/unit/audit-base-command.test.ts b/packages/contentstack-audit/test/unit/audit-base-command.test.ts index a74e51768..d4e6c94e3 100644 --- a/packages/contentstack-audit/test/unit/audit-base-command.test.ts +++ b/packages/contentstack-audit/test/unit/audit-base-command.test.ts @@ -5,7 +5,11 @@ import { resolve } from 'path'; import { fancy } from 'fancy-test'; import { PassThrough } from 'stream'; import { expect } from 'chai'; -import { ux, cliux, CLIProgressManager, configHandler, clearProgressModuleSetting } from '@contentstack/cli-utilities'; +import { ux, cliux, CLIProgressManager, configHandler } from '@contentstack/cli-utilities'; +import { + setConsoleLogPolicy, + resetConsoleLogPolicy, +} from '@contentstack/cli-utilities/lib/logger/console-policy'; import { AuditBaseCommand } from '../../src/audit-base-command'; import { @@ -437,7 +441,6 @@ describe('AuditBaseCommand class', () => { try { CLIProgressManager.clearGlobalSummary(); - clearProgressModuleSetting(); } catch (e) { // Ignore } @@ -529,10 +532,12 @@ describe('AuditBaseCommand class', () => { // Import print function from the correct path const logModule = require('../../src/util/log'); printSpy = sinon.spy(logModule, 'print'); - configHandlerGetStub = sinon.stub(configHandler, 'get'); + configHandlerGetStub = sinon.stub(configHandler, 'get').returns({}); }); afterEach(() => { + resetConsoleLogPolicy(); + try { // Clear global summary first CLIProgressManager.clearGlobalSummary(); @@ -584,15 +589,15 @@ describe('AuditBaseCommand class', () => { .stub(FieldRule.prototype, 'run', () => ({ fr_1: {} })) .stub(AuditBaseCommand.prototype, 'showOutputOnScreenWorkflowsAndExtension', () => {}) .stub(fs, 'createWriteStream', () => new PassThrough()) - .it('should hide spinner messages when showConsoleLogs is false', async function() { + .it('should hide spinner messages when the console-log policy is off', async function() { this.timeout(5000); // Set timeout to 5 seconds if (!configHandlerGetStub || !printSpy) { throw new Error('Spies not initialized'); } - configHandlerGetStub.returns({ showConsoleLogs: false }); + setConsoleLogPolicy(false); await AuditCMD.run(['--data-dir', resolve(__dirname, 'mock', 'contents')]); - - // Print should not be called for spinner messages when showConsoleLogs is false + + // Print should not be called for spinner messages when the console-log policy is off const printCalls = printSpy.getCalls(); const spinnerCalls = printCalls.filter((call: any) => call.args[0]?.[0]?.message?.includes('scanning') @@ -620,15 +625,15 @@ describe('AuditBaseCommand class', () => { .stub(FieldRule.prototype, 'run', () => ({ fr_1: {} })) .stub(AuditBaseCommand.prototype, 'showOutputOnScreenWorkflowsAndExtension', () => {}) .stub(fs, 'createWriteStream', () => new PassThrough()) - .it('should show spinner messages when showConsoleLogs is true', async function() { + .it('should show spinner messages when the console-log policy is on', async function() { this.timeout(5000); // Set timeout to 5 seconds if (!configHandlerGetStub || !printSpy) { throw new Error('Spies not initialized'); } - configHandlerGetStub.returns({ showConsoleLogs: true }); + setConsoleLogPolicy(true); await AuditCMD.run(['--data-dir', resolve(__dirname, 'mock', 'contents')]); - - // Print should be called for spinner messages when showConsoleLogs is true + + // Print should be called for spinner messages when the console-log policy is on const printCalls = printSpy.getCalls(); const spinnerCalls = printCalls.filter((call: any) => call.args[0]?.[0]?.message?.includes('scanning') diff --git a/packages/contentstack-audit/test/unit/modules/base-class.test.ts b/packages/contentstack-audit/test/unit/modules/base-class.test.ts index dc0b5563c..c952fd478 100644 --- a/packages/contentstack-audit/test/unit/modules/base-class.test.ts +++ b/packages/contentstack-audit/test/unit/modules/base-class.test.ts @@ -3,6 +3,10 @@ import { fancy } from 'fancy-test'; import sinon from 'sinon'; import { resolve } from 'node:path'; import { CLIProgressManager, configHandler } from '@contentstack/cli-utilities'; +import { + setConsoleLogPolicy, + resetConsoleLogPolicy, +} from '@contentstack/cli-utilities/lib/logger/console-policy'; import config from '../../../src/config'; import BaseClass from '../../../src/modules/base-class'; @@ -99,6 +103,8 @@ describe('BaseClass Progress Manager', () => { }); afterEach(() => { + resetConsoleLogPolicy(); + try { // Complete any running progress managers if (testInstance && testInstance['progressManager']) { @@ -165,12 +171,12 @@ describe('BaseClass Progress Manager', () => { } }); - fancy.it('should respect showConsoleLogs setting from config', () => { - configHandler.set('log.showConsoleLogs', true); + fancy.it('should create a manager under either console-log policy', () => { + setConsoleLogPolicy(true); const progress1 = testInstance.testCreateSimpleProgress('test-module', 100); expect(progress1).to.be.instanceOf(CLIProgressManager); - configHandler.set('log.showConsoleLogs', false); + setConsoleLogPolicy(false); const progress2 = testInstance.testCreateSimpleProgress('test-module-2', 100); expect(progress2).to.be.instanceOf(CLIProgressManager); @@ -184,8 +190,7 @@ describe('BaseClass Progress Manager', () => { } }); - fancy.it('should default showConsoleLogs to false when not set', () => { - configHandler.set('log', {}); + fancy.it('should create a manager under the default (files-only) policy', () => { const progress = testInstance.testCreateSimpleProgress('test-module', 100); expect(progress).to.be.instanceOf(CLIProgressManager); @@ -215,8 +220,8 @@ describe('BaseClass Progress Manager', () => { } }); - fancy.it('should respect showConsoleLogs setting from config', () => { - configHandler.set('log.showConsoleLogs', false); + fancy.it('should create a nested manager when the console-log policy is off', () => { + setConsoleLogPolicy(false); const progress = testInstance.testCreateNestedProgress('test-module'); expect(progress).to.be.instanceOf(CLIProgressManager); @@ -231,8 +236,8 @@ describe('BaseClass Progress Manager', () => { }); describe('withLoadingSpinner', () => { - fancy.it('should execute action directly when showConsoleLogs is true', async () => { - configHandler.set('log.showConsoleLogs', true); + fancy.it('should not start a spinner when the console-log policy is on', async () => { + setConsoleLogPolicy(true); const action = sinon.stub().resolves('result'); const result = await testInstance.testWithLoadingSpinner('Loading...', action); @@ -242,8 +247,8 @@ describe('BaseClass Progress Manager', () => { expect(mockOra.called).to.be.false; }); - fancy.it('should use spinner when showConsoleLogs is false', async () => { - configHandler.set('log.showConsoleLogs', false); + fancy.it('should use the spinner when the console-log policy is off', async () => { + setConsoleLogPolicy(false); const action = sinon.stub().resolves('result'); const result = await testInstance.testWithLoadingSpinner('Loading...', action); @@ -253,7 +258,7 @@ describe('BaseClass Progress Manager', () => { }); fancy.it('should handle errors in action', async () => { - configHandler.set('log.showConsoleLogs', true); + setConsoleLogPolicy(true); const error = new Error('Test error'); const action = sinon.stub().rejects(error); diff --git a/packages/contentstack-bulk-operations/src/base-bulk-command.ts b/packages/contentstack-bulk-operations/src/base-bulk-command.ts index 3251e19ab..ecef6bbd2 100644 --- a/packages/contentstack-bulk-operations/src/base-bulk-command.ts +++ b/packages/contentstack-bulk-operations/src/base-bulk-command.ts @@ -8,9 +8,7 @@ import { FlagInput, getChalk, loadChalk, - configHandler, CLIProgressManager, - clearProgressModuleSetting, } from '@contentstack/cli-utilities'; import config from './config'; @@ -306,13 +304,6 @@ export abstract class BaseBulkCommand extends Command { * Build operation configuration */ protected async buildConfiguration(flags: any): Promise { - // Enable the progress-bar UI + suppress the timestamped console logs for the whole command. - // Set here (command lifecycle, runs before the first log call) rather than in the pure - // buildConfig() util so it isn't triggered by direct/unit-test callers of buildConfig. - // Cleared on every exit path: finally() on normal runs, and finalizeProgressSummary() before - // the validation exit(1) below and the revert/retry exit(0). - configHandler.set('log.progressSupportedModule', 'bulk-operations'); - this.bulkOperationConfig = buildConfig(flags); // buildConfig splits comma-separated oclif `multiple` values; mirror onto flags so @@ -463,7 +454,6 @@ export abstract class BaseBulkCommand extends Command { * success. The printed status URL remains the source of truth for the real publish outcome. */ protected recordModuleSummary(result: BulkOperationResult, submittedCount: number): void { - const showConsoleLogs = Boolean(configHandler.get('log')?.showConsoleLogs); const publishMode = this.bulkOperationConfig?.publishMode || PublishMode.BULK; const total = result?.total || submittedCount || 0; @@ -482,7 +472,7 @@ export abstract class BaseBulkCommand extends Command { failed = Math.min(Math.max(failed, 0), total); success = Math.min(Math.max(success, 0), total - failed); - const progress = CLIProgressManager.createSimple(this.resourceType, total, showConsoleLogs); + const progress = CLIProgressManager.createSimple(this.resourceType, total); for (let i = 0; i < success; i++) progress.tick(true); for (let i = 0; i < failed; i++) progress.tick(false); progress.complete(failed === 0); @@ -491,13 +481,11 @@ export abstract class BaseBulkCommand extends Command { /** * Print the run-level summary once and clear progress state. Idempotent: subclasses call * finally() explicitly AND oclif calls it again, so clearing the summary after printing makes - * the second invocation a no-op. Also clears the progress-module flag so it never leaks into - * a later command in the same process (mirrors export/import/clone). + * the second invocation a no-op. */ protected finalizeProgressSummary(): void { CLIProgressManager.printGlobalSummary(); CLIProgressManager.clearGlobalSummary(); - clearProgressModuleSetting(); } /** diff --git a/packages/contentstack-bulk-operations/test/unit/base-bulk-command.test.ts b/packages/contentstack-bulk-operations/test/unit/base-bulk-command.test.ts index dc6c6e83f..4db00505a 100644 --- a/packages/contentstack-bulk-operations/test/unit/base-bulk-command.test.ts +++ b/packages/contentstack-bulk-operations/test/unit/base-bulk-command.test.ts @@ -532,9 +532,7 @@ describe('BaseBulkCommand', () => { sandbox.stub(cliUtils.CLIProgressManager, 'initializeGlobalSummary').returns({} as any); sandbox.stub(cliUtils.CLIProgressManager, 'printGlobalSummary').callsFake(() => {}); sandbox.stub(cliUtils.CLIProgressManager, 'clearGlobalSummary').callsFake(() => {}); - // clearProgressModuleSetting is a frozen re-export (not stubbable); let the real one run - // and drive/assert it through configHandler instead. - sandbox.stub(cliUtils.configHandler, 'get').returns({ showConsoleLogs: false }); + sandbox.stub(cliUtils.configHandler, 'get').returns({}); sandbox.stub(cliUtils.configHandler, 'set').callsFake(() => {}); }); @@ -637,16 +635,6 @@ describe('BaseBulkCommand', () => { expect(cliUtils.CLIProgressManager.printGlobalSummary.calledOnce).to.be.true; expect(cliUtils.CLIProgressManager.clearGlobalSummary.calledOnce).to.be.true; }); - - it('clears the persisted progress-module flag', () => { - // Simulate the flag being set, then verify clearProgressModuleSetting removes it. - cliUtils.configHandler.get.returns({ progressSupportedModule: 'bulk-operations', showConsoleLogs: false }); - - (command as any).finalizeProgressSummary(); - - expect(cliUtils.configHandler.set.calledWith('log', sinon.match((v: any) => !('progressSupportedModule' in v)))).to - .be.true; - }); }); }); diff --git a/packages/contentstack-cli-tsgen/package.json b/packages/contentstack-cli-tsgen/package.json index 21a6e4d04..62c419773 100644 --- a/packages/contentstack-cli-tsgen/package.json +++ b/packages/contentstack-cli-tsgen/package.json @@ -67,6 +67,7 @@ "format": "eslint \"src/**/*.ts\" --fix" }, "csdxConfig": { + "showConsoleLogs": true, "shortCommandName": { "tsgen": "TSGEN" } diff --git a/packages/contentstack-clone/src/commands/cm/stacks/clone.ts b/packages/contentstack-clone/src/commands/cm/stacks/clone.ts index 2e826f738..b7e9ac2ea 100644 --- a/packages/contentstack-clone/src/commands/cm/stacks/clone.ts +++ b/packages/contentstack-clone/src/commands/cm/stacks/clone.ts @@ -1,5 +1,6 @@ import { Command } from '@contentstack/cli-command'; import { + cliux, configHandler, flags, isAuthenticated, @@ -159,10 +160,6 @@ Use this plugin to automate the process of cloning a stack in few steps. async run(): Promise { try { const self = this; - // Clear any stale progressSupportedModule persisted from a previous run so that - // auth/pre-flight errors always reach the console regardless of showConsoleLogs setting. - // It will be re-set inside handleClone() once authentication passes. - configHandler.set('log.progressSupportedModule', null); const { flags: cloneCommandFlags } = await self.parse(StackCloneCommand); const { yes, @@ -181,7 +178,6 @@ Use this plugin to automate the process of cloning a stack in few steps. } = cloneCommandFlags; const handleClone = async (): Promise => { - configHandler.set('log.progressSupportedModule', 'clone'); const listOfTokens = configHandler.get('tokens'); const authenticationMethod = this.determineAuthenticationMethod( sourceManagementTokenAlias, @@ -234,20 +230,18 @@ Use this plugin to automate the process of cloning a stack in few steps. config.source_stack = listOfTokens[sourceManagementTokenAlias].apiKey; log.debug(`Using source token alias: ${sourceManagementTokenAlias}`, cloneContext); } else if (sourceManagementTokenAlias) { - log.warn( - `Provided source token alias (${sourceManagementTokenAlias}) not found in your config.!`, - cloneContext, - ); + const msg = `Provided source token alias (${sourceManagementTokenAlias}) not found in your config.!`; + log.warn(msg, cloneContext); + cliux.print(msg, { color: 'yellow' }); } if (destinationManagementTokenAlias && listOfTokens?.[destinationManagementTokenAlias]) { config.destination_alias = destinationManagementTokenAlias; config.target_stack = listOfTokens[destinationManagementTokenAlias].apiKey; log.debug(`Using destination token alias: ${destinationManagementTokenAlias}`, cloneContext); } else if (destinationManagementTokenAlias) { - log.warn( - `Provided destination token alias (${destinationManagementTokenAlias}) not found in your config.!`, - cloneContext, - ); + const msg = `Provided destination token alias (${destinationManagementTokenAlias}) not found in your config.!`; + log.warn(msg, cloneContext); + cliux.print(msg, { color: 'yellow' }); } if (importWebhookStatus) { config.importWebhookStatus = importWebhookStatus; diff --git a/packages/contentstack-clone/test/commands/cm/stacks/clone.test.ts b/packages/contentstack-clone/test/commands/cm/stacks/clone.test.ts index b62603d7a..d39109890 100644 --- a/packages/contentstack-clone/test/commands/cm/stacks/clone.test.ts +++ b/packages/contentstack-clone/test/commands/cm/stacks/clone.test.ts @@ -543,7 +543,7 @@ describe('StackCloneCommand', () => { flags: mockFlags, }); const configHandlerGetStub = sandbox.stub(cliUtilities.configHandler, 'get').returns(undefined); - const configHandlerSetStub = sandbox.stub(cliUtilities.configHandler, 'set'); + sandbox.stub(cliUtilities.configHandler, 'set'); const logStub = { error: sandbox.stub(), warn: sandbox.stub(), debug: sandbox.stub(), info: sandbox.stub() }; sandbox.stub(cliUtilities, 'log').value(logStub); // exit(1) throws inside run()'s own try/catch which swallows it — stub cleanUp to @@ -557,8 +557,6 @@ describe('StackCloneCommand', () => { expect(exitStub.calledOnce).to.be.true; expect(logStub.error.called).to.be.true; expect(logStub.error.firstCall.args[0]).to.include('Please login'); - // progressSupportedModule must NOT be set when auth fails - expect(configHandlerSetStub.calledWith('log.progressSupportedModule', 'clone')).to.be.false; }); it('should exit when management token aliases provided but not authenticated and branches provided', async () => { @@ -571,7 +569,7 @@ describe('StackCloneCommand', () => { }, }); const configHandlerGetStub = sandbox.stub(cliUtilities.configHandler, 'get').returns(undefined); - const configHandlerSetStub = sandbox.stub(cliUtilities.configHandler, 'set'); + sandbox.stub(cliUtilities.configHandler, 'set'); const logStub = { error: sandbox.stub(), warn: sandbox.stub(), debug: sandbox.stub(), info: sandbox.stub() }; sandbox.stub(cliUtilities, 'log').value(logStub); const cleanUpStub = sandbox.stub(command, 'cleanUp').resolves(); @@ -583,8 +581,6 @@ describe('StackCloneCommand', () => { expect(exitStub.calledOnce).to.be.true; expect(logStub.error.called).to.be.true; expect(logStub.error.firstCall.args[0]).to.include('Log in'); - // progressSupportedModule must NOT be set when auth fails - expect(configHandlerSetStub.calledWith('log.progressSupportedModule', 'clone')).to.be.false; }); it('should handle run error and cleanup', async () => { @@ -794,7 +790,7 @@ describe('StackCloneCommand', () => { 'destination-management-token-alias': 'dest-alias', }, }); - const configHandlerSetStub = sandbox.stub(cliUtilities.configHandler, 'set'); + sandbox.stub(cliUtilities.configHandler, 'set'); const configHandlerStub = sandbox.stub(cliUtilities.configHandler, 'get'); // Stub authorisationType to 'OAUTH' to make isAuthenticated() return true configHandlerStub.callsFake((key: string) => { @@ -836,8 +832,6 @@ describe('StackCloneCommand', () => { expect(cloneHandlerExecuteStub.calledOnce).to.be.true; // Verify all config flags were set expect(logStub.debug.called).to.be.true; - // progressSupportedModule must be set inside handleClone (after auth passes) - expect(configHandlerSetStub.calledWith('log.progressSupportedModule', 'clone')).to.be.true; }); it('should handle CloneHandler.execute error (covers line 263)', async () => { diff --git a/packages/contentstack-export-to-csv/package.json b/packages/contentstack-export-to-csv/package.json index d9bfb9886..117d45db9 100644 --- a/packages/contentstack-export-to-csv/package.json +++ b/packages/contentstack-export-to-csv/package.json @@ -54,6 +54,7 @@ "repositoryPrefix": "<%- repo %>/blob/main/packages/contentstack-export-to-csv/<%- commandPath %>" }, "csdxConfig": { + "showConsoleLogs": true, "shortCommandName": { "cm:export-to-csv": "EXPRTCSV" } diff --git a/packages/contentstack-export-to-csv/src/commands/cm/export-to-csv.ts b/packages/contentstack-export-to-csv/src/commands/cm/export-to-csv.ts index bcda11584..f074dd87a 100644 --- a/packages/contentstack-export-to-csv/src/commands/cm/export-to-csv.ts +++ b/packages/contentstack-export-to-csv/src/commands/cm/export-to-csv.ts @@ -280,6 +280,7 @@ export default class ExportToCsvCommand extends BaseCommand { } log.success('Export completed successfully', this.commandContext); + cliux.print('Export completed successfully', { color: 'green' }); } catch (error) { log.debug('Export failed', { ...this.commandContext, error }); handleAndLogError(error, this.commandContext); @@ -408,6 +409,7 @@ export default class ExportToCsvCommand extends BaseCommand { } log.success('Entries exported successfully', this.commandContext); + cliux.print('Entries exported successfully', { color: 'green' }); } catch (error) { log.debug('Entries export failed', { ...this.commandContext, error }); handleAndLogError(error, this.commandContext, 'Failed to export entries'); @@ -460,6 +462,7 @@ export default class ExportToCsvCommand extends BaseCommand { write(this, listOfUsers, fileName, 'organization details', delimiter); log.success('Users exported successfully', this.commandContext); + cliux.print('Users exported successfully', { color: 'green' }); } catch (error) { log.debug('Users export failed', { ...this.commandContext, error }); handleAndLogError(error, this.commandContext, 'Failed to export users'); @@ -498,6 +501,7 @@ export default class ExportToCsvCommand extends BaseCommand { await exportTeams(managementAPIClient, organization, teamUid, delimiter); log.success('Teams exported successfully', this.commandContext); + cliux.print('Teams exported successfully', { color: 'green' }); } catch (error) { log.debug('Teams export failed', { ...this.commandContext, error }); handleAndLogError(error, this.commandContext, 'Failed to export teams'); @@ -573,6 +577,7 @@ export default class ExportToCsvCommand extends BaseCommand { }); log.success('Taxonomies exported successfully', this.commandContext); + cliux.print('Taxonomies exported successfully', { color: 'green' }); } catch (error) { log.debug('Taxonomies export failed', { ...this.commandContext, error }); handleAndLogError(error, this.commandContext, 'Failed to export taxonomies'); diff --git a/packages/contentstack-export-to-csv/src/utils/teams-export.ts b/packages/contentstack-export-to-csv/src/utils/teams-export.ts index 4b78dc64f..d97b2b277 100644 --- a/packages/contentstack-export-to-csv/src/utils/teams-export.ts +++ b/packages/contentstack-export-to-csv/src/utils/teams-export.ts @@ -96,6 +96,7 @@ export async function exportTeams( await exportRoleMappings(managementAPIClient, allTeamsData, teamUid, delimiter); log.success('Teams export completed', logContext); + cliux.print('Teams export completed', { color: 'green' }); } /** diff --git a/packages/contentstack-export/src/commands/cm/stacks/export.ts b/packages/contentstack-export/src/commands/cm/stacks/export.ts index 5a769cfad..c1ca25400 100644 --- a/packages/contentstack-export/src/commands/cm/stacks/export.ts +++ b/packages/contentstack-export/src/commands/cm/stacks/export.ts @@ -9,11 +9,11 @@ import { pathValidator, sanitizePath, configHandler, + isConsoleLogEnabled, log, handleAndLogError, getSessionLogPath, CLIProgressManager, - clearProgressModuleSetting, loadChalk, } from '@contentstack/cli-utilities'; @@ -130,17 +130,13 @@ export default class ExportCommand extends Command { // Print comprehensive summary at the end if (!exportConfig.branches) CLIProgressManager.printGlobalSummary(); - if (!configHandler.get('log')?.showConsoleLogs) { + if (!isConsoleLogEnabled()) { cliux.print(`The log has been stored at '${sessionLogPath}'`, { color: 'green' }); } - // Clear progress module setting now that export is complete - clearProgressModuleSetting(); } catch (error) { - // Clear progress module setting even on error - clearProgressModuleSetting(); handleAndLogError(error); const sessionLogPath = getSessionLogPath(); - if (!configHandler.get('log')?.showConsoleLogs) { + if (!isConsoleLogEnabled()) { cliux.print(`Error: ${error}`, { color: 'red' }); cliux.print(`The log has been stored at '${sessionLogPath}'`, { color: 'green' }); } diff --git a/packages/contentstack-export/src/export/modules/base-class.ts b/packages/contentstack-export/src/export/modules/base-class.ts index d591e3355..2d6e5ecae 100644 --- a/packages/contentstack-export/src/export/modules/base-class.ts +++ b/packages/contentstack-export/src/export/modules/base-class.ts @@ -8,7 +8,6 @@ import isEqual from 'lodash/isEqual'; import { log, CLIProgressManager, - configHandler, getSessionLogPath, handleAndLogError, } from '@contentstack/cli-utilities'; @@ -82,9 +81,7 @@ export default abstract class BaseClass { */ protected createSimpleProgress(moduleName: string, total?: number): CLIProgressManager { this.currentModuleName = moduleName; - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; // Default to true for better UX - this.progressManager = CLIProgressManager.createSimple(moduleName, total, showConsoleLogs); + this.progressManager = CLIProgressManager.createSimple(moduleName, total); return this.progressManager; } @@ -93,9 +90,7 @@ export default abstract class BaseClass { */ protected createNestedProgress(moduleName: string): CLIProgressManager { this.currentModuleName = moduleName; - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; // Default to true for better UX - this.progressManager = CLIProgressManager.createNested(moduleName, showConsoleLogs); + this.progressManager = CLIProgressManager.createNested(moduleName); return this.progressManager; } @@ -140,13 +135,6 @@ export default abstract class BaseClass { } protected async withLoadingSpinner(message: string, action: () => Promise): Promise { - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; - - if (showConsoleLogs) { - // If console logs are enabled, don't show spinner, just execute the action - return await action(); - } return await CLIProgressManager.withLoadingSpinner(message, action); } diff --git a/packages/contentstack-export/src/utils/export-config-handler.ts b/packages/contentstack-export/src/utils/export-config-handler.ts index 522bc9990..d835586a4 100644 --- a/packages/contentstack-export/src/utils/export-config-handler.ts +++ b/packages/contentstack-export/src/utils/export-config-handler.ts @@ -17,10 +17,6 @@ import { filter, includes } from 'lodash'; import { ExportConfig } from '../types'; const setupConfig = async (exportCmdFlags: any, context?: any): Promise => { - // Set progress supported module FIRST, before any log calls - // This ensures the logger respects the showConsoleLogs setting correctly - configHandler.set('log.progressSupportedModule', 'export'); - let config = merge({}, defaultConfig); // Track authentication method diff --git a/packages/contentstack-import-setup/src/commands/cm/stacks/import-setup.ts b/packages/contentstack-import-setup/src/commands/cm/stacks/import-setup.ts index 8f55bcd75..9665d2a3c 100644 --- a/packages/contentstack-import-setup/src/commands/cm/stacks/import-setup.ts +++ b/packages/contentstack-import-setup/src/commands/cm/stacks/import-setup.ts @@ -12,6 +12,7 @@ import { log, handleAndLogError, configHandler, + isConsoleLogEnabled, createLogContext, cliux, loadChalk @@ -107,11 +108,10 @@ export default class ImportSetupCommand extends Command { log.success(successMessage, importSetupConfig.context); log.success(backupPathMessage, importSetupConfig.context); - // log.success maps to the info level, which is suppressed on the console for - // progress-supported modules when showConsoleLogs is false. Print the backup - // folder path directly so it is always visible, regardless of that setting. - const showConsoleLogs = configHandler.get('log')?.showConsoleLogs ?? false; - if (!showConsoleLogs) { + // log.success maps to the info level, which only reaches the console when the + // console-log policy is on. Print the backup folder path directly so it is + // always visible when it is off. + if (!isConsoleLogEnabled()) { cliux.print(successMessage); cliux.print(backupPathMessage); } diff --git a/packages/contentstack-import-setup/src/import/modules/base-setup.ts b/packages/contentstack-import-setup/src/import/modules/base-setup.ts index 69bea1cde..b392aabb8 100644 --- a/packages/contentstack-import-setup/src/import/modules/base-setup.ts +++ b/packages/contentstack-import-setup/src/import/modules/base-setup.ts @@ -1,7 +1,7 @@ import { log, fsUtil } from '../../utils'; import { ApiOptions, CustomPromiseHandler, EnvType, ImportConfig, ModuleClassParams } from '../../types'; import { chunk, entries, isEmpty, isEqual, last } from 'lodash'; -import { CLIProgressManager, configHandler } from '@contentstack/cli-utilities'; +import { CLIProgressManager } from '@contentstack/cli-utilities'; export default class BaseImportSetup { public config: ImportConfig; @@ -214,9 +214,7 @@ export default class BaseImportSetup { */ protected createSimpleProgress(moduleName: string, total?: number): CLIProgressManager { this.currentModuleName = moduleName; - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; - this.progressManager = CLIProgressManager.createSimple(moduleName, total, showConsoleLogs); + this.progressManager = CLIProgressManager.createSimple(moduleName, total); return this.progressManager; } @@ -225,9 +223,7 @@ export default class BaseImportSetup { */ protected createNestedProgress(moduleName: string): CLIProgressManager { this.currentModuleName = moduleName; - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; - this.progressManager = CLIProgressManager.createNested(moduleName, showConsoleLogs); + this.progressManager = CLIProgressManager.createNested(moduleName); return this.progressManager; } @@ -243,13 +239,6 @@ export default class BaseImportSetup { * Show a loading spinner before initializing progress */ protected async withLoadingSpinner(message: string, action: () => Promise): Promise { - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; - - if (showConsoleLogs) { - // If console logs are enabled, don't show spinner, just execute the action - return await action(); - } return await CLIProgressManager.withLoadingSpinner(message, action); } } diff --git a/packages/contentstack-import-setup/src/utils/import-config-handler.ts b/packages/contentstack-import-setup/src/utils/import-config-handler.ts index 6b2481961..eec37f278 100644 --- a/packages/contentstack-import-setup/src/utils/import-config-handler.ts +++ b/packages/contentstack-import-setup/src/utils/import-config-handler.ts @@ -8,10 +8,6 @@ import login from './login-handler'; import { ImportConfig } from '../types'; const setupConfig = async (importCmdFlags: any): Promise => { - // Set progress supported module FIRST, before any log calls - // This ensures the logger respects the showConsoleLogs setting correctly - configHandler.set('log.progressSupportedModule', 'import-setup'); - const config: ImportConfig = merge({}, defaultConfig); // setup the config // if (importCmdFlags['config']) { diff --git a/packages/contentstack-import-setup/test/unit/modules/base-setup.test.ts b/packages/contentstack-import-setup/test/unit/modules/base-setup.test.ts index 620ea95da..3520b4659 100644 --- a/packages/contentstack-import-setup/test/unit/modules/base-setup.test.ts +++ b/packages/contentstack-import-setup/test/unit/modules/base-setup.test.ts @@ -3,7 +3,11 @@ import { stub, restore, SinonStub } from 'sinon'; import BaseImportSetup from '../../../src/import/modules/base-setup'; import * as loggerModule from '../../../src/utils/logger'; import { ImportConfig } from '../../../src/types'; -import { CLIProgressManager, configHandler } from '@contentstack/cli-utilities'; +import { CLIProgressManager } from '@contentstack/cli-utilities'; +import { + setConsoleLogPolicy, + resetConsoleLogPolicy, +} from '@contentstack/cli-utilities/lib/logger/console-policy'; describe('BaseImportSetup', () => { let baseSetup: BaseImportSetup; @@ -122,7 +126,6 @@ describe('BaseImportSetup', () => { }); describe('Progress Manager', () => { - let configHandlerGetStub: SinonStub; let createSimpleStub: SinonStub; let createNestedStub: SinonStub; let withLoadingSpinnerStub: SinonStub; @@ -138,45 +141,40 @@ describe('BaseImportSetup', () => { completeProcess: stub().returnsThis(), }; - configHandlerGetStub = stub(configHandler, 'get'); createSimpleStub = stub(CLIProgressManager, 'createSimple'); createNestedStub = stub(CLIProgressManager, 'createNested'); withLoadingSpinnerStub = stub(CLIProgressManager, 'withLoadingSpinner'); }); afterEach(() => { + resetConsoleLogPolicy(); restore(); }); describe('createSimpleProgress', () => { - it('should create a simple progress manager with default showConsoleLogs', () => { - configHandlerGetStub.returns({}); + it('should create a simple progress manager', () => { createSimpleStub.returns(mockProgressManager); const result = (baseSetup as any).createSimpleProgress('test-module', 100); - expect(configHandlerGetStub.calledWith('log')).to.be.true; expect(createSimpleStub.calledOnce).to.be.true; - expect(createSimpleStub.firstCall.args[0]).to.equal('test-module'); - expect(createSimpleStub.firstCall.args[1]).to.equal(100); - expect(createSimpleStub.firstCall.args[2]).to.equal(false); + expect(createSimpleStub.firstCall.args).to.deep.equal(['test-module', 100]); expect(result).to.equal(mockProgressManager); expect((baseSetup as any).currentModuleName).to.equal('test-module'); expect((baseSetup as any).progressManager).to.equal(mockProgressManager); }); - it('should create a simple progress manager with showConsoleLogs enabled', () => { - configHandlerGetStub.returns({ showConsoleLogs: true }); + it('should not forward a policy argument when the console-log policy is on', () => { + setConsoleLogPolicy(true); createSimpleStub.returns(mockProgressManager); const result = (baseSetup as any).createSimpleProgress('test-module', 50); - expect(createSimpleStub.firstCall.args[2]).to.equal(true); + expect(createSimpleStub.firstCall.args).to.deep.equal(['test-module', 50]); expect(result).to.equal(mockProgressManager); }); it('should create a simple progress manager without total count', () => { - configHandlerGetStub.returns({}); createSimpleStub.returns(mockProgressManager); (baseSetup as any).createSimpleProgress('test-module'); @@ -186,28 +184,25 @@ describe('BaseImportSetup', () => { }); describe('createNestedProgress', () => { - it('should create a nested progress manager with default showConsoleLogs', () => { - configHandlerGetStub.returns({}); + it('should create a nested progress manager', () => { createNestedStub.returns(mockProgressManager); const result = (baseSetup as any).createNestedProgress('test-module'); - expect(configHandlerGetStub.calledWith('log')).to.be.true; expect(createNestedStub.calledOnce).to.be.true; - expect(createNestedStub.firstCall.args[0]).to.equal('test-module'); - expect(createNestedStub.firstCall.args[1]).to.equal(false); + expect(createNestedStub.firstCall.args).to.deep.equal(['test-module']); expect(result).to.equal(mockProgressManager); expect((baseSetup as any).currentModuleName).to.equal('test-module'); expect((baseSetup as any).progressManager).to.equal(mockProgressManager); }); - it('should create a nested progress manager with showConsoleLogs enabled', () => { - configHandlerGetStub.returns({ showConsoleLogs: true }); + it('should not forward a policy argument when the console-log policy is on', () => { + setConsoleLogPolicy(true); createNestedStub.returns(mockProgressManager); const result = (baseSetup as any).createNestedProgress('test-module'); - expect(createNestedStub.firstCall.args[1]).to.equal(true); + expect(createNestedStub.firstCall.args).to.deep.equal(['test-module']); expect(result).to.equal(mockProgressManager); }); }); @@ -244,45 +239,35 @@ describe('BaseImportSetup', () => { }); describe('withLoadingSpinner', () => { - it('should execute action directly when showConsoleLogs is enabled', async () => { - configHandlerGetStub.returns({ showConsoleLogs: true }); - const action = stub().resolves('result'); - - const result = await (baseSetup as any).withLoadingSpinner('Loading...', action); - - expect(action.calledOnce).to.be.true; - expect(withLoadingSpinnerStub.called).to.be.false; - expect(result).to.equal('result'); - }); - - it('should use CLIProgressManager.withLoadingSpinner when showConsoleLogs is disabled', async () => { - configHandlerGetStub.returns({ showConsoleLogs: false }); + it('should delegate to CLIProgressManager.withLoadingSpinner even when the policy is on', async () => { + setConsoleLogPolicy(true); const action = stub().resolves('result'); withLoadingSpinnerStub.resolves('result'); const result = await (baseSetup as any).withLoadingSpinner('Loading...', action); expect(withLoadingSpinnerStub.calledOnce).to.be.true; - expect(withLoadingSpinnerStub.firstCall.args[0]).to.equal('Loading...'); expect(withLoadingSpinnerStub.firstCall.args[1]).to.equal(action); expect(result).to.equal('result'); }); - it('should use CLIProgressManager.withLoadingSpinner when log config is empty', async () => { - configHandlerGetStub.returns({}); + it('should use CLIProgressManager.withLoadingSpinner when the policy is off', async () => { const action = stub().resolves('result'); withLoadingSpinnerStub.resolves('result'); const result = await (baseSetup as any).withLoadingSpinner('Loading...', action); expect(withLoadingSpinnerStub.calledOnce).to.be.true; + expect(withLoadingSpinnerStub.firstCall.args[0]).to.equal('Loading...'); + expect(withLoadingSpinnerStub.firstCall.args[1]).to.equal(action); expect(result).to.equal('result'); }); - it('should handle errors in action when showConsoleLogs is enabled', async () => { - configHandlerGetStub.returns({ showConsoleLogs: true }); + it('should handle errors in action when the policy is on', async () => { + setConsoleLogPolicy(true); const error = new Error('Action failed'); const action = stub().rejects(error); + withLoadingSpinnerStub.rejects(error); try { await (baseSetup as any).withLoadingSpinner('Loading...', action); @@ -292,8 +277,7 @@ describe('BaseImportSetup', () => { } }); - it('should handle errors in action when showConsoleLogs is disabled', async () => { - configHandlerGetStub.returns({ showConsoleLogs: false }); + it('should handle errors in action when the policy is off', async () => { const error = new Error('Action failed'); const action = stub().rejects(error); withLoadingSpinnerStub.rejects(error); diff --git a/packages/contentstack-import/src/commands/cm/stacks/import.ts b/packages/contentstack-import/src/commands/cm/stacks/import.ts index e2b7a0cad..687ae4fba 100644 --- a/packages/contentstack-import/src/commands/cm/stacks/import.ts +++ b/packages/contentstack-import/src/commands/cm/stacks/import.ts @@ -8,10 +8,10 @@ import { log, handleAndLogError, configHandler, + isConsoleLogEnabled, getSessionLogPath, CLIProgressManager, cliux, - clearProgressModuleSetting, createLogContext, } from '@contentstack/cli-utilities'; @@ -195,12 +195,7 @@ export default class ImportCommand extends Command { ); } this.logSuccessAndBackupMessages(backupDir, importConfig); - // Clear progress module setting now that import is complete - clearProgressModuleSetting(); } catch (error) { - // Clear progress module setting even on error - clearProgressModuleSetting(); - handleAndLogError(error); this.logAndPrintErrorDetails(error, importConfig); } @@ -219,8 +214,7 @@ export default class ImportCommand extends Command { log.info(logMsg); log.info(backupDirMsg); - const showConsoleLogs = configHandler.get('log')?.showConsoleLogs; - if (!showConsoleLogs) { + if (!isConsoleLogEnabled()) { cliux.print(`Error: ${error}`, { color: 'red' }); cliux.print(logMsg, { color: 'blue' }); cliux.print(backupDirMsg, { color: 'blue' }); @@ -236,8 +230,7 @@ export default class ImportCommand extends Command { log.success(logMsg, importConfig.context); log.info(backupDirMsg, importConfig.context); - const showConsoleLogs = configHandler.get('log')?.showConsoleLogs; - if (!showConsoleLogs) { + if (!isConsoleLogEnabled()) { cliux.print(logMsg, { color: 'blue' }); cliux.print(backupDirMsg, { color: 'blue' }); } diff --git a/packages/contentstack-import/src/import/modules/base-class.ts b/packages/contentstack-import/src/import/modules/base-class.ts index 1fb60cd00..06bd792d3 100644 --- a/packages/contentstack-import/src/import/modules/base-class.ts +++ b/packages/contentstack-import/src/import/modules/base-class.ts @@ -19,7 +19,6 @@ import { WorkflowData, RoleData, CLIProgressManager, - configHandler, getSessionLogPath } from '@contentstack/cli-utilities'; import { ImportConfig, ModuleClassParams } from '../../types'; @@ -126,9 +125,7 @@ export default abstract class BaseClass { */ protected createSimpleProgress(moduleName: string, total?: number): CLIProgressManager { this.currentModuleName = moduleName; - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; // Default to true for better UX - this.progressManager = CLIProgressManager.createSimple(moduleName, total, showConsoleLogs); + this.progressManager = CLIProgressManager.createSimple(moduleName, total); return this.progressManager; } @@ -137,9 +134,7 @@ export default abstract class BaseClass { */ protected createNestedProgress(moduleName: string): CLIProgressManager { this.currentModuleName = moduleName; - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; // Default to true for better UX - this.progressManager = CLIProgressManager.createNested(moduleName, showConsoleLogs); + this.progressManager = CLIProgressManager.createNested(moduleName); return this.progressManager; } @@ -182,13 +177,6 @@ export default abstract class BaseClass { } protected async withLoadingSpinner(message: string, action: () => Promise): Promise { - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; - - if (showConsoleLogs) { - // If console logs are enabled, don't show spinner, just execute the action - return await action(); - } return await CLIProgressManager.withLoadingSpinner(message, action); } diff --git a/packages/contentstack-import/src/utils/import-config-handler.ts b/packages/contentstack-import/src/utils/import-config-handler.ts index 244ca4002..21f316dae 100644 --- a/packages/contentstack-import/src/utils/import-config-handler.ts +++ b/packages/contentstack-import/src/utils/import-config-handler.ts @@ -18,10 +18,6 @@ import { ImportConfig } from '../types'; import { existsSync } from 'fs'; const setupConfig = async (importCmdFlags: any, context?: any): Promise => { - // Set progress supported module FIRST, before any log calls - // This ensures the logger respects the showConsoleLogs setting correctly - configHandler.set('log.progressSupportedModule', 'import'); - let config: ImportConfig = merge({}, defaultConfig); // Track authentication method let authenticationMethod = 'unknown'; diff --git a/packages/contentstack-query-export/package.json b/packages/contentstack-query-export/package.json index c87abf7e5..3ad7ff9b2 100644 --- a/packages/contentstack-query-export/package.json +++ b/packages/contentstack-query-export/package.json @@ -87,6 +87,7 @@ "repositoryPrefix": "<%- repo %>/blob/main/packages/contentstack-query-export/<%- commandPath %>" }, "csdxConfig": { + "showConsoleLogs": true, "shortCommandName": { "cm:stacks:export-query": "EXPRTQRY", "cm:export:query": "EXPRTQRY" diff --git a/packages/contentstack-variants/src/utils/personalization-api-adapter.ts b/packages/contentstack-variants/src/utils/personalization-api-adapter.ts index ee2ed613d..b19a4d069 100644 --- a/packages/contentstack-variants/src/utils/personalization-api-adapter.ts +++ b/packages/contentstack-variants/src/utils/personalization-api-adapter.ts @@ -1,5 +1,5 @@ import { AdapterHelper } from './adapter-helper'; -import { HttpClient, authenticationHandler, log, CLIProgressManager, configHandler } from '@contentstack/cli-utilities'; +import { HttpClient, authenticationHandler, log, CLIProgressManager } from '@contentstack/cli-utilities'; import { ProjectStruct, @@ -66,9 +66,7 @@ export class PersonalizationAdapter extends AdapterHelper impl return this.progressManager; } - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; - this.progressManager = CLIProgressManager.createSimple(moduleName, total, showConsoleLogs); + this.progressManager = CLIProgressManager.createSimple(moduleName, total); return this.progressManager; } @@ -84,9 +82,7 @@ export class PersonalizationAdapter extends AdapterHelper impl return this.progressManager; } - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; - this.progressManager = CLIProgressManager.createNested(moduleName, showConsoleLogs); + this.progressManager = CLIProgressManager.createNested(moduleName); return this.progressManager; } @@ -105,13 +101,6 @@ export class PersonalizationAdapter extends AdapterHelper impl * Execute action with loading spinner for initial setup tasks */ protected async withLoadingSpinner(message: string, action: () => Promise): Promise { - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; - - if (showConsoleLogs) { - // If console logs are enabled, don't show spinner, just execute the action - return await action(); - } return await CLIProgressManager.withLoadingSpinner(message, action); } diff --git a/packages/contentstack-variants/src/utils/variant-api-adapter.ts b/packages/contentstack-variants/src/utils/variant-api-adapter.ts index 611d4c909..e84ec08f7 100644 --- a/packages/contentstack-variants/src/utils/variant-api-adapter.ts +++ b/packages/contentstack-variants/src/utils/variant-api-adapter.ts @@ -10,7 +10,6 @@ import { authenticationHandler, log, CLIProgressManager, - configHandler, } from '@contentstack/cli-utilities'; import { @@ -439,9 +438,7 @@ export class VariantAdapter { return this.progressManager; } - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; - this.progressManager = CLIProgressManager.createSimple(moduleName, total, showConsoleLogs); + this.progressManager = CLIProgressManager.createSimple(moduleName, total); return this.progressManager; } @@ -457,9 +454,7 @@ export class VariantAdapter { return this.progressManager; } - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; - this.progressManager = CLIProgressManager.createNested(moduleName, showConsoleLogs); + this.progressManager = CLIProgressManager.createNested(moduleName); return this.progressManager; } @@ -478,13 +473,6 @@ export class VariantAdapter { * Execute action with loading spinner for initial setup tasks */ protected async withLoadingSpinner(message: string, action: () => Promise): Promise { - const logConfig = configHandler.get('log') || {}; - const showConsoleLogs = logConfig.showConsoleLogs ?? false; - - if (showConsoleLogs) { - // If console logs are enabled, don't show spinner, just execute the action - return await action(); - } return await CLIProgressManager.withLoadingSpinner(message, action); }