diff --git a/packages/contentstack-utilities/.mocharc.json b/packages/contentstack-utilities/.mocharc.json index ef6efe7ed4..52667fac1b 100644 --- a/packages/contentstack-utilities/.mocharc.json +++ b/packages/contentstack-utilities/.mocharc.json @@ -2,7 +2,8 @@ "require": [ "test/helpers/init.js", "ts-node/register", - "source-map-support/register" + "source-map-support/register", + "test/helpers/mocha-root-hooks.js" ], "watch-extensions": [ "ts" diff --git a/packages/contentstack-utilities/package.json b/packages/contentstack-utilities/package.json index a3bd71d299..d92ca47921 100644 --- a/packages/contentstack-utilities/package.json +++ b/packages/contentstack-utilities/package.json @@ -37,7 +37,7 @@ "@contentstack/marketplace-sdk": "^1.5.0", "@oclif/core": "^4.3.0", "axios": "^1.13.5", - "chalk": "^4.1.2", + "chalk": "^5.6.2", "cli-cursor": "^3.1.0", "cli-progress": "^3.12.0", "cli-table": "^0.3.11", diff --git a/packages/contentstack-utilities/src/chalk.ts b/packages/contentstack-utilities/src/chalk.ts new file mode 100644 index 0000000000..593b9b8ddb --- /dev/null +++ b/packages/contentstack-utilities/src/chalk.ts @@ -0,0 +1,27 @@ +/** + * Chalk 5 is ESM-only. We load it via dynamic import and cache for use in CommonJS. + */ +let chalkInstance: typeof import('chalk').default | null = null; + +export type ChalkInstance = typeof import('chalk').default; + +/** + * Load chalk (ESM) and cache it. Call this once during CLI init before any chalk usage. + */ +export async function loadChalk(): Promise { + if (!chalkInstance) { + const chalkModule = await import('chalk'); + chalkInstance = chalkModule.default; + } + return chalkInstance; +} + +/** + * Get the cached chalk instance. Must call loadChalk() first (e.g. in init hook). + */ +export function getChalk(): ChalkInstance { + if (!chalkInstance) { + throw new Error('Chalk not loaded. Ensure loadChalk() is called during init (e.g. in utils-init hook).'); + } + return chalkInstance; +} diff --git a/packages/contentstack-utilities/src/cli-ux.ts b/packages/contentstack-utilities/src/cli-ux.ts index a4f6417dc7..945b38669e 100644 --- a/packages/contentstack-utilities/src/cli-ux.ts +++ b/packages/contentstack-utilities/src/cli-ux.ts @@ -1,4 +1,4 @@ -import chalk, { Chalk } from 'chalk'; +import { getChalk, ChalkInstance } from './chalk'; import inquirer from 'inquirer'; import { ux as cliux, Args, Flags, Command } from '@oclif/core'; import { Ora, default as ora } from 'ora'; @@ -29,10 +29,11 @@ class CLIInterface { print(message: string, opts?: PrintOptions): void { if (opts) { - let chalkFn: Chalk = chalk; + const chalk = getChalk(); + let chalkFn: ChalkInstance = chalk; - if (opts.color) chalkFn = chalkFn[opts.color] as Chalk; - if (opts.bold) chalkFn = chalkFn.bold as Chalk; + if (opts.color) chalkFn = chalkFn[opts.color] as ChalkInstance; + if (opts.bold) chalkFn = chalkFn.bold as ChalkInstance; cliux.stdout(chalkFn(messageHandler.parse(message))); return; @@ -42,11 +43,11 @@ class CLIInterface { } success(message: string): void { - cliux.stdout(chalk.green(messageHandler.parse(message))); + cliux.stdout(getChalk().green(messageHandler.parse(message))); } error(message: string, ...params: any): void { - cliux.stdout(chalk.red(messageHandler.parse(message) + (params && params.length > 0 ? ': ' : '')), ...params); + cliux.stdout(getChalk().red(messageHandler.parse(message) + (params && params.length > 0 ? ': ' : '')), ...params); } loader(message: string = ''): void { diff --git a/packages/contentstack-utilities/src/config-handler.ts b/packages/contentstack-utilities/src/config-handler.ts index 45f24f49b4..446efd8879 100644 --- a/packages/contentstack-utilities/src/config-handler.ts +++ b/packages/contentstack-utilities/src/config-handler.ts @@ -2,7 +2,7 @@ import Conf from 'conf'; import has from 'lodash/has'; import { v4 as uuid } from 'uuid'; import { existsSync, unlinkSync, readFileSync } from 'fs'; -import chalk from 'chalk'; +import { getChalk } from './chalk'; import { cliux } from '.'; const ENC_KEY = process.env.ENC_KEY || 'encryptionKey'; @@ -85,7 +85,7 @@ class Config { safeDeleteConfigIfInvalid(configFilePath: string) { if (existsSync(configFilePath) && !this.isConfigFileValid(configFilePath)) { - console.warn(chalk.yellow(`Warning: Detected corrupted config at ${configFilePath}. Removing...`)); + console.warn(getChalk().yellow(`Warning: Detected corrupted config at ${configFilePath}. Removing...`)); unlinkSync(configFilePath); } } @@ -152,7 +152,7 @@ class Config { const oldConfigData = this.getConfigDataAndUnlinkConfigFile(config); this.getEncryptedConfig(oldConfigData, true); } catch (_error) { - cliux.print(chalk.red('Error: Config file is corrupted')); + cliux.print(getChalk().red('Error: Config file is corrupted')); cliux.print(_error); process.exit(1); } @@ -203,7 +203,7 @@ class Config { this.getDecryptedConfig(_configData); // NOTE reinitialize the config with old data and new decrypted file } catch (__error) { // console.trace(error.message) - cliux.print(chalk.red('Error: Config file is corrupted')); + cliux.print(getChalk().red('Error: Config file is corrupted')); cliux.print(_error); process.exit(1); } diff --git a/packages/contentstack-utilities/src/content-type-utils.ts b/packages/contentstack-utilities/src/content-type-utils.ts index c3c4fbf5ff..0edfe85b38 100644 --- a/packages/contentstack-utilities/src/content-type-utils.ts +++ b/packages/contentstack-utilities/src/content-type-utils.ts @@ -1,21 +1,24 @@ +import { existsSync, readdirSync, readFileSync } from 'node:fs'; import { resolve as pResolve } from 'node:path'; -import { FsUtility } from './fs-utility'; /** * Reads all content type schema files from a directory * @param dirPath - Path to content types directory * @param ignoredFiles - Files to ignore (defaults to schema.json, .DS_Store, __master.json, __priority.json) - * @returns Array of content type schemas + * @returns Array of content type schemas (empty if the path is missing or has no eligible files) */ export function readContentTypeSchemas( dirPath: string, ignoredFiles: string[] = ['schema.json', '.DS_Store', '__master.json', '__priority.json', 'field_rules_uid.json'], -): Record[] | null { - const fsUtil = new FsUtility(); - const files = fsUtil.readdir(dirPath); +): Record[] { + if (!existsSync(dirPath)) { + return []; + } + + const files = readdirSync(dirPath); if (!files || files.length === 0) { - return null; + return []; } const contentTypes: Record[] = []; @@ -33,7 +36,8 @@ export function readContentTypeSchemas( try { const filePath = pResolve(dirPath, file); - const contentType = fsUtil.readFile(filePath); + const raw = readFileSync(filePath, 'utf8'); + const contentType = JSON.parse(raw) as Record; if (contentType) { contentTypes.push(contentType as Record); } diff --git a/packages/contentstack-utilities/src/index.ts b/packages/contentstack-utilities/src/index.ts index 5e0df53290..52861c9926 100644 --- a/packages/contentstack-utilities/src/index.ts +++ b/packages/contentstack-utilities/src/index.ts @@ -76,6 +76,8 @@ export { export { FlagInput, ArgInput, FlagDefinition } from '@oclif/core/lib/interfaces/parser'; export { default as TablePrompt } from './inquirer-table-prompt'; +export { loadChalk, getChalk } from './chalk'; +export type { ChalkInstance } from './chalk'; export { Logger }; export { default as authenticationHandler } from './authentication-handler'; diff --git a/packages/contentstack-utilities/src/inquirer-table-prompt.ts b/packages/contentstack-utilities/src/inquirer-table-prompt.ts index 31b4956233..bec536b71d 100644 --- a/packages/contentstack-utilities/src/inquirer-table-prompt.ts +++ b/packages/contentstack-utilities/src/inquirer-table-prompt.ts @@ -5,7 +5,7 @@ */ import * as readline from 'readline'; -import chalk from 'chalk'; +import { getChalk } from './chalk'; import figures from 'figures'; import cliCursor from 'cli-cursor'; import Table from 'cli-table'; @@ -182,13 +182,13 @@ class TablePrompt { if (!this.spaceKeyPressed) { msg += ' (Press ' + - chalk.cyan.bold('') + + getChalk().cyan.bold('') + ' to select, ' + - chalk.cyan.bold('') + + getChalk().cyan.bold('') + ' rows, ' + - chalk.cyan.bold('') + + getChalk().cyan.bold('') + ' columns, ' + - chalk.cyan.bold('') + + getChalk().cyan.bold('') + ' to confirm)'; } return msg; @@ -197,8 +197,8 @@ class TablePrompt { private render(): void { const [firstIndex, lastIndex] = this.paginate(); const table = new Table({ - head: [chalk.reset.dim(`${firstIndex + 1}-${lastIndex + 1} of ${this.rows.length}`)].concat( - this.columns.map((c) => chalk.reset.bold(pluckName(c))), + head: [getChalk().reset.dim(`${firstIndex + 1}-${lastIndex + 1} of ${this.rows.length}`)].concat( + this.columns.map((c) => getChalk().reset.bold(pluckName(c))), ), }); @@ -214,7 +214,7 @@ class TablePrompt { columnValues.push(`${isSelected ? '[' : ' '} ${cellValue} ${isSelected ? ']' : ' '}`); } const chalkModifier = - this.status !== 'answered' && this.pointer === rowIndex ? chalk.reset.bold.cyan : chalk.reset; + this.status !== 'answered' && this.pointer === rowIndex ? getChalk().reset.bold.cyan : getChalk().reset; table.push({ [chalkModifier(pluckName(row))]: columnValues }); } diff --git a/packages/contentstack-utilities/src/progress-summary/cli-progress-manager.ts b/packages/contentstack-utilities/src/progress-summary/cli-progress-manager.ts index 54200e2f13..751adc7fff 100644 --- a/packages/contentstack-utilities/src/progress-summary/cli-progress-manager.ts +++ b/packages/contentstack-utilities/src/progress-summary/cli-progress-manager.ts @@ -1,4 +1,4 @@ -import chalk from 'chalk'; +import { getChalk } from '../chalk'; import ora, { Ora } from 'ora'; import ProgressBar from 'cli-progress'; import SummaryManager from './summary-manager'; @@ -86,11 +86,11 @@ export default class CLIProgressManager { const safeBranchName = branchName || 'main'; const branchInfo = headerTitle || `${safeBranchName?.toUpperCase()} CONTENT`; - console.log('\n' + chalk.bold('='.repeat(80))); + console.log('\n' + getChalk().bold('='.repeat(80))); if (branchInfo) { - console.log(chalk.bold.white(` ${branchInfo}`)); + console.log(getChalk().bold.white(` ${branchInfo}`)); } - console.log(chalk.bold('='.repeat(80)) + '\n'); + console.log(getChalk().bold('='.repeat(80)) + '\n'); } /** @@ -103,6 +103,10 @@ export default class CLIProgressManager { return; } + if (configHandler.get('log')?.showConsoleLogs) { + return; + } + // Apply strategy-based corrections before printing CLIProgressManager.applyStrategyCorrections(); @@ -298,7 +302,7 @@ export default class CLIProgressManager { { clearOnComplete: false, hideCursor: true, - format: ' {label} |' + chalk.cyan('{bar}') + '| {percentage}% | {value}/{total} | {status}', + format: ' {label} |' + getChalk().cyan('{bar}') + '| {percentage}% | {value}/{total} | {status}', barCompleteChar: '\u2588', barIncompleteChar: '\u2591', }, @@ -306,15 +310,15 @@ export default class CLIProgressManager { ); if (!this.showConsoleLogs) { - console.log(chalk.bold.cyan(`\n${this.moduleName}:`)); + console.log(getChalk().bold.cyan(`\n${this.moduleName}:`)); } } else if (this.total > 0) { if (!this.showConsoleLogs) { - console.log(chalk.bold.cyan(`\n${this.moduleName}:`)); + console.log(getChalk().bold.cyan(`\n${this.moduleName}:`)); } this.progressBar = new ProgressBar.SingleBar({ - format: ' {label} |' + chalk.cyan('{bar}') + '| {percentage}% | {value}/{total} | {status}', + format: ' {label} |' + getChalk().cyan('{bar}') + '| {percentage}% | {value}/{total} | {status}', barCompleteChar: '\u2588', barIncompleteChar: '\u2591', hideCursor: true, @@ -322,12 +326,12 @@ export default class CLIProgressManager { const formattedName = this.formatModuleName(this.moduleName); const displayName = formattedName.length > 20 ? formattedName.substring(0, 17) + '...' : formattedName; this.progressBar.start(this.total, 0, { - label: chalk.gray(` └─ ${displayName}`.padEnd(25)), - status: chalk.gray('Starting...'), + label: getChalk().gray(` └─ ${displayName}`.padEnd(25)), + status: getChalk().gray('Starting...'), percentage: ' 0', }); } else { - this.spinner = ora(`${chalk.bold(this.moduleName)}: Processing...`).start(); + this.spinner = ora(`${getChalk().bold(this.moduleName)}: Processing...`).start(); } } @@ -351,8 +355,8 @@ export default class CLIProgressManager { const displayName = this.formatProcessName(processName); const indentedLabel = ` ├─ ${displayName}`.padEnd(25); process.progressBar = this.multiBar.create(total, 0, { - label: chalk.gray(indentedLabel), - status: chalk.gray('Pending'), + label: getChalk().gray(indentedLabel), + status: getChalk().gray('Pending'), percentage: ' 0', }); } @@ -391,8 +395,8 @@ export default class CLIProgressManager { const displayName = this.formatProcessName(processName); const indentedLabel = ` ├─ ${displayName}`.padEnd(25); process.progressBar.update(0, { - label: chalk.yellow(indentedLabel), - status: chalk.yellow('Processing'), + label: getChalk().yellow(indentedLabel), + status: getChalk().yellow('Processing'), percentage: ' 0', }); } @@ -424,12 +428,12 @@ export default class CLIProgressManager { const percentage = Math.round((totalProcessed / process.total) * 100); const formattedPercentage = this.formatPercentage(percentage); const statusText = success - ? chalk.green(`✓ Complete (${process.successCount}/${process.current})`) - : chalk.red(`✗ Failed (${process.successCount}/${process.current})`); + ? getChalk().green(`✓ Complete (${process.successCount}/${process.current})`) + : getChalk().red(`✗ Failed (${process.successCount}/${process.current})`); const displayName = this.formatProcessName(processName); const indentedLabel = ` ├─ ${displayName}`.padEnd(25); process.progressBar.update(process.total, { - label: success ? chalk.green(indentedLabel) : chalk.red(indentedLabel), + label: success ? getChalk().green(indentedLabel) : getChalk().red(indentedLabel), status: statusText, percentage: formattedPercentage, }); @@ -451,8 +455,8 @@ export default class CLIProgressManager { const displayName = this.formatProcessName(processName); const indentedLabel = ` ├─ ${displayName}`.padEnd(25); process.progressBar.update(process.current, { - label: chalk.yellow(indentedLabel), - status: chalk.yellow(message), + label: getChalk().yellow(indentedLabel), + status: getChalk().yellow(message), percentage: formattedPercentage, }); } @@ -462,12 +466,12 @@ export default class CLIProgressManager { const formattedName = this.formatModuleName(this.moduleName); const displayName = formattedName.length > 20 ? formattedName.substring(0, 17) + '...' : formattedName; this.progressBar.update(this.progressBar.getProgress() * this.total, { - label: chalk.yellow(` └─ ${displayName}`.padEnd(25)), - status: chalk.yellow(message), + label: getChalk().yellow(` └─ ${displayName}`.padEnd(25)), + status: getChalk().yellow(message), percentage: formattedPercentage, }); } else if (this.spinner) { - this.spinner.text = `${chalk.bold(this.moduleName)}: ${message}`; + this.spinner.text = `${getChalk().bold(this.moduleName)}: ${message}`; } } return this; @@ -514,8 +518,8 @@ export default class CLIProgressManager { const displayName = this.formatProcessName(targetProcess); const indentedLabel = ` ├─ ${displayName}`.padEnd(25); process.progressBar.increment(1, { - label: chalk.cyan(indentedLabel), - status: chalk.cyan(statusText), + label: getChalk().cyan(indentedLabel), + status: getChalk().cyan(statusText), percentage: formattedPercentage, }); } @@ -532,12 +536,12 @@ export default class CLIProgressManager { const statusText = totalProcessed >= this.total ? this.failureCount === 0 - ? chalk.green(`✓ Complete (${this.successCount}/${totalProcessed})`) - : chalk.yellow(`✓ Complete (${this.successCount}/${totalProcessed})`) - : chalk.cyan(`${this.successCount}✓ ${this.failureCount}✗`); + ? getChalk().green(`✓ Complete (${this.successCount}/${totalProcessed})`) + : getChalk().yellow(`✓ Complete (${this.successCount}/${totalProcessed})`) + : getChalk().cyan(`${this.successCount}✓ ${this.failureCount}✗`); const labelColor = - totalProcessed >= this.total ? (this.failureCount === 0 ? chalk.green : chalk.yellow) : chalk.cyan; + totalProcessed >= this.total ? (this.failureCount === 0 ? getChalk().green : getChalk().yellow) : getChalk().cyan; const formattedName = this.formatModuleName(this.moduleName); const displayName = formattedName.length > 20 ? formattedName.substring(0, 17) + '...' : formattedName; @@ -548,7 +552,7 @@ export default class CLIProgressManager { }); } else if (this.spinner) { const total = this.successCount + this.failureCount; - this.spinner.text = `${chalk.bold(this.moduleName)}: ${total} items (${this.successCount}✓ ${ + this.spinner.text = `${getChalk().bold(this.moduleName)}: ${total} items (${this.successCount}✓ ${ this.failureCount }✗)`; } @@ -599,14 +603,14 @@ export default class CLIProgressManager { if (!this.enableNestedProgress) { // Simple summary for single progress - this.log('\n' + chalk.bold(`${this.moduleName} Summary:`)); - this.log(`✓ Success: ${chalk.green(this.successCount)}`); - this.log(`✗ Failures: ${chalk.red(this.failureCount)}`); + this.log('\n' + getChalk().bold(`${this.moduleName} Summary:`)); + this.log(`✓ Success: ${getChalk().green(this.successCount)}`); + this.log(`✗ Failures: ${getChalk().red(this.failureCount)}`); return; } // Detailed summary for nested progress - this.log('\n' + chalk.bold(`${this.moduleName} Detailed Summary:`)); + this.log('\n' + getChalk().bold(`${this.moduleName} Detailed Summary:`)); for (const [processName, process] of this.processes) { const status = diff --git a/packages/contentstack-utilities/src/progress-summary/summary-manager.ts b/packages/contentstack-utilities/src/progress-summary/summary-manager.ts index 9153968b2b..12b3cfc7b6 100644 --- a/packages/contentstack-utilities/src/progress-summary/summary-manager.ts +++ b/packages/contentstack-utilities/src/progress-summary/summary-manager.ts @@ -1,4 +1,4 @@ -import chalk from 'chalk'; +import { getChalk } from '../chalk'; import { ModuleResult, SummaryOptions } from '../interfaces/index'; import { getSessionLogPath } from '../logger/log'; @@ -97,21 +97,21 @@ export default class SummaryManager { const totalSuccess = Array.from(this.modules.values()).reduce((sum, m) => sum + m.successCount, 0); const totalFailures = Array.from(this.modules.values()).reduce((sum, m) => sum + m.failureCount, 0); - console.log('\n' + chalk.bold('='.repeat(80))); - console.log(chalk.bold(`${this.operationName} SUMMARY`)); - console.log('\n' + chalk.bold('Overall Statistics:')); - console.log(` Total ${this.operationName} Time: ${chalk.cyan(this.formatDuration(totalDuration))}`); - console.log(` Modules Processed: ${chalk.cyan(completedModules)}/${chalk.cyan(totalModules)}`); + console.log('\n' + getChalk().bold('='.repeat(80))); + console.log(getChalk().bold(`${this.operationName} SUMMARY`)); + console.log('\n' + getChalk().bold('Overall Statistics:')); + console.log(` Total ${this.operationName} Time: ${getChalk().cyan(this.formatDuration(totalDuration))}`); + console.log(` Modules Processed: ${getChalk().cyan(completedModules)}/${getChalk().cyan(totalModules)}`); console.log( - ` Items Processed: ${chalk.green(totalSuccess)} success, ${chalk.red(totalFailures)} failed of ${chalk.cyan( + ` Items Processed: ${getChalk().green(totalSuccess)} success, ${getChalk().red(totalFailures)} failed of ${getChalk().cyan( totalItems, )} total`, ); - console.log(` Success Rate: ${chalk.cyan(this.calculateSuccessRate(totalSuccess, totalItems))}%`); + console.log(` Success Rate: ${getChalk().cyan(this.calculateSuccessRate(totalSuccess, totalItems))}%`); // Module Details - console.log('\n' + chalk.bold('Module Details:')); - console.log(chalk.gray('-'.repeat(80))); + console.log('\n' + getChalk().bold('Module Details:')); + console.log(getChalk().gray('-'.repeat(80))); Array.from(this.modules.values()).forEach((module) => { const status = this.getStatusIcon(module.status); @@ -130,19 +130,19 @@ export default class SummaryManager { }); // Final Status - console.log('\n' + chalk.bold('Final Status:')); + console.log('\n' + getChalk().bold('Final Status:')); if (!this.hasFailures() && failedModules === 0) { - console.log(chalk.bold.green(`✅ ${this.operationName} completed successfully!`)); + console.log(getChalk().bold.green(`✅ ${this.operationName} completed successfully!`)); } else if (this.hasFailures() || failedModules > 0) { console.log( - chalk.bold.yellow(`⚠️ ${this.operationName} completed with failures, see the logs for more details.`), + getChalk().bold.yellow(`⚠️ ${this.operationName} completed with failures, see the logs for more details.`), ); } else { - console.log(chalk.bold.red(`❌ ${this.operationName} failed`)); + console.log(getChalk().bold.red(`❌ ${this.operationName} failed`)); } - console.log(chalk.bold('='.repeat(80))); - console.log(chalk.bold('='.repeat(80))); + console.log(getChalk().bold('='.repeat(80))); + console.log(getChalk().bold('='.repeat(80))); // Simple failure summary with log reference this.printFailureSummaryWithLogReference(); @@ -162,40 +162,40 @@ export default class SummaryManager { const totalFailures = modulesWithFailures.reduce((sum, m) => sum + m.failures.length, 0); - console.log('\n' + chalk.bold.red('Failure Summary:')); - console.log(chalk.red('-'.repeat(50))); + console.log('\n' + getChalk().bold.red('Failure Summary:')); + console.log(getChalk().red('-'.repeat(50))); modulesWithFailures.forEach((module) => { - console.log(`${chalk.bold.red('✗')} ${chalk.bold(module.name)}: ${chalk.red(module.failures.length)} failures`); + console.log(`${getChalk().bold.red('✗')} ${getChalk().bold(module.name)}: ${getChalk().red(module.failures.length)} failures`); // Show just first 2-3 failures briefly const preview = module.failures.slice(0, 2); preview.forEach((failure) => { - console.log(` • ${chalk.gray(failure.item)}`); + console.log(` • ${getChalk().gray(failure.item)}`); }); if (module.failures.length > 2) { - console.log(` ${chalk.gray(`... and ${module.failures.length - 2} more`)}`); + console.log(` ${getChalk().gray(`... and ${module.failures.length - 2} more`)}`); } }); - console.log(chalk.blue('\n📋 For detailed error information, check the log files:')); - //console.log(chalk.blue(` ${getSessionLogPath()}`)); - console.log(chalk.gray(' Recent errors are logged with full context and stack traces.')); + console.log(getChalk().blue('\n📋 For detailed error information, check the log files:')); + //console.log(getChalk().blue(` ${getSessionLogPath()}`)); + console.log(getChalk().gray(' Recent errors are logged with full context and stack traces.')); } private getStatusIcon(status: string): string { switch (status) { case 'completed': - return chalk.green('✓'); + return getChalk().green('✓'); case 'failed': - return chalk.red('✗'); + return getChalk().red('✗'); case 'running': - return chalk.yellow('●'); + return getChalk().yellow('●'); case 'pending': - return chalk.gray('○'); + return getChalk().gray('○'); default: - return chalk.gray('?'); + return getChalk().gray('?'); } } diff --git a/packages/contentstack-utilities/test/helpers/mocha-root-hooks.js b/packages/contentstack-utilities/test/helpers/mocha-root-hooks.js new file mode 100644 index 0000000000..61d15442cb --- /dev/null +++ b/packages/contentstack-utilities/test/helpers/mocha-root-hooks.js @@ -0,0 +1,12 @@ +/** + * Chalk 5 is ESM-only and loaded asynchronously; production code calls loadChalk() at CLI init. + * Tests must preload chalk before any getChalk() usage. + */ +const { loadChalk } = require('../../src/chalk'); + +exports.mochaHooks = { + beforeAll() { + this.timeout(30_000); + return loadChalk(); + }, +}; diff --git a/packages/contentstack/package.json b/packages/contentstack/package.json index 145b8e7c96..2b42090c29 100755 --- a/packages/contentstack/package.json +++ b/packages/contentstack/package.json @@ -45,7 +45,7 @@ "@oclif/plugin-help": "^6.2.37", "@oclif/plugin-not-found": "^3.2.74", "@oclif/plugin-plugins": "^5.4.56", - "chalk": "^4.1.2", + "chalk": "^5.6.2", "cli-progress": "^3.12.0", "debug": "^4.4.3", "figlet": "1.8.2", diff --git a/packages/contentstack/src/hooks/init/utils-init.ts b/packages/contentstack/src/hooks/init/utils-init.ts index a532d07909..cee8d31e86 100644 --- a/packages/contentstack/src/hooks/init/utils-init.ts +++ b/packages/contentstack/src/hooks/init/utils-init.ts @@ -1,9 +1,10 @@ -import { messageHandler, cliux, managementSDKInitiator, marketplaceSDKInitiator } from '@contentstack/cli-utilities'; +import { messageHandler, cliux, managementSDKInitiator, marketplaceSDKInitiator, loadChalk } from '@contentstack/cli-utilities'; /** * Initialize the utilities */ -export default function (_opts): void { +export default async function (_opts): Promise { + await loadChalk(); const { context } = this.config; messageHandler.init(context); cliux.init(context); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index deaa59ace8..8f27411398 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -87,8 +87,8 @@ importers: specifier: ^5.4.56 version: 5.4.58 chalk: - specifier: ^4.1.2 - version: 4.1.2 + specifier: ^5.6.2 + version: 5.6.2 cli-progress: specifier: ^3.12.0 version: 3.12.0 @@ -434,8 +434,8 @@ importers: specifier: ^1.13.5 version: 1.13.6(debug@4.4.3) chalk: - specifier: ^4.1.2 - version: 4.1.2 + specifier: ^5.6.2 + version: 5.6.2 cli-cursor: specifier: ^3.1.0 version: 3.1.0 @@ -10222,7 +10222,7 @@ snapshots: dependencies: '@types/chai': 4.3.20 '@types/lodash': 4.17.24 - '@types/node': 14.18.63 + '@types/node': 18.19.130 '@types/sinon': 21.0.0 lodash: 4.17.23 mock-stdin: 1.0.0