Skip to content

Commit 9745eec

Browse files
Merge pull request #2451 from contentstack/fix/dx-4465-upgrade-chalk-to-v5
Fix/dx 4465 upgrade chalk to v5
2 parents 072fc59 + cd34272 commit 9745eec

File tree

18 files changed

+176
-100
lines changed

18 files changed

+176
-100
lines changed

packages/contentstack-auth/.mocharc.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
"require": [
33
"test/helpers/init.js",
44
"ts-node/register",
5-
"source-map-support/register"
5+
"source-map-support/register",
6+
"test/helpers/mocha-root-hooks.js"
67
],
78
"watch-extensions": [
89
"ts"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* @contentstack/cli-utilities uses lazy-loaded Chalk 5; preload before tests that hit cliux.
3+
*/
4+
const { loadChalk } = require('@contentstack/cli-utilities');
5+
6+
exports.mochaHooks = {
7+
beforeAll() {
8+
this.timeout(30_000);
9+
return loadChalk();
10+
},
11+
};

packages/contentstack-config/.mocharc.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
{
22
"require": [
33
"ts-node/register",
4-
"source-map-support/register"
4+
"source-map-support/register",
5+
"test/helpers/mocha-root-hooks.js"
56
],
67
"watch-extensions": [
78
"ts"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* @contentstack/cli-utilities uses lazy-loaded Chalk 5; preload before tests that hit cliux.success etc.
3+
*/
4+
const { loadChalk } = require('@contentstack/cli-utilities');
5+
6+
exports.mochaHooks = {
7+
beforeAll() {
8+
this.timeout(30_000);
9+
return loadChalk();
10+
},
11+
};

packages/contentstack-utilities/.mocharc.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
"require": [
33
"test/helpers/init.js",
44
"ts-node/register",
5-
"source-map-support/register"
5+
"source-map-support/register",
6+
"test/helpers/mocha-root-hooks.js"
67
],
78
"watch-extensions": [
89
"ts"

packages/contentstack-utilities/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
"@contentstack/marketplace-sdk": "^1.5.0",
3838
"@oclif/core": "^4.3.0",
3939
"axios": "^1.13.5",
40-
"chalk": "^4.1.2",
40+
"chalk": "^5.6.2",
4141
"cli-cursor": "^3.1.0",
4242
"cli-progress": "^3.12.0",
4343
"cli-table": "^0.3.11",
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* Chalk 5 is ESM-only. We load it via dynamic import and cache for use in CommonJS.
3+
*/
4+
let chalkInstance: typeof import('chalk').default | null = null;
5+
6+
export type ChalkInstance = typeof import('chalk').default;
7+
8+
/**
9+
* Load chalk (ESM) and cache it. Call this once during CLI init before any chalk usage.
10+
*/
11+
export async function loadChalk(): Promise<ChalkInstance> {
12+
if (!chalkInstance) {
13+
const chalkModule = await import('chalk');
14+
chalkInstance = chalkModule.default;
15+
}
16+
return chalkInstance;
17+
}
18+
19+
/**
20+
* Get the cached chalk instance. Must call loadChalk() first (e.g. in init hook).
21+
*/
22+
export function getChalk(): ChalkInstance {
23+
if (!chalkInstance) {
24+
throw new Error('Chalk not loaded. Ensure loadChalk() is called during init (e.g. in utils-init hook).');
25+
}
26+
return chalkInstance;
27+
}

packages/contentstack-utilities/src/cli-ux.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import chalk, { Chalk } from 'chalk';
1+
import { getChalk, ChalkInstance } from './chalk';
22
import inquirer from 'inquirer';
33
import { ux as cliux, Args, Flags, Command } from '@oclif/core';
44
import { Ora, default as ora } from 'ora';
@@ -29,10 +29,11 @@ class CLIInterface {
2929

3030
print(message: string, opts?: PrintOptions): void {
3131
if (opts) {
32-
let chalkFn: Chalk = chalk;
32+
const chalk = getChalk();
33+
let chalkFn: ChalkInstance = chalk;
3334

34-
if (opts.color) chalkFn = chalkFn[opts.color] as Chalk;
35-
if (opts.bold) chalkFn = chalkFn.bold as Chalk;
35+
if (opts.color) chalkFn = chalkFn[opts.color] as ChalkInstance;
36+
if (opts.bold) chalkFn = chalkFn.bold as ChalkInstance;
3637

3738
cliux.stdout(chalkFn(messageHandler.parse(message)));
3839
return;
@@ -42,11 +43,11 @@ class CLIInterface {
4243
}
4344

4445
success(message: string): void {
45-
cliux.stdout(chalk.green(messageHandler.parse(message)));
46+
cliux.stdout(getChalk().green(messageHandler.parse(message)));
4647
}
4748

4849
error(message: string, ...params: any): void {
49-
cliux.stdout(chalk.red(messageHandler.parse(message) + (params && params.length > 0 ? ': ' : '')), ...params);
50+
cliux.stdout(getChalk().red(messageHandler.parse(message) + (params && params.length > 0 ? ': ' : '')), ...params);
5051
}
5152

5253
loader(message: string = ''): void {

packages/contentstack-utilities/src/config-handler.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import Conf from 'conf';
22
import has from 'lodash/has';
33
import { v4 as uuid } from 'uuid';
44
import { existsSync, unlinkSync, readFileSync } from 'fs';
5-
import chalk from 'chalk';
5+
import { getChalk } from './chalk';
66
import { cliux } from '.';
77

88
const ENC_KEY = process.env.ENC_KEY || 'encryptionKey';
@@ -85,7 +85,7 @@ class Config {
8585

8686
safeDeleteConfigIfInvalid(configFilePath: string) {
8787
if (existsSync(configFilePath) && !this.isConfigFileValid(configFilePath)) {
88-
console.warn(chalk.yellow(`Warning: Detected corrupted config at ${configFilePath}. Removing...`));
88+
console.warn(getChalk().yellow(`Warning: Detected corrupted config at ${configFilePath}. Removing...`));
8989
unlinkSync(configFilePath);
9090
}
9191
}
@@ -152,7 +152,7 @@ class Config {
152152
const oldConfigData = this.getConfigDataAndUnlinkConfigFile(config);
153153
this.getEncryptedConfig(oldConfigData, true);
154154
} catch (_error) {
155-
cliux.print(chalk.red('Error: Config file is corrupted'));
155+
cliux.print(getChalk().red('Error: Config file is corrupted'));
156156
cliux.print(_error);
157157
process.exit(1);
158158
}
@@ -203,7 +203,7 @@ class Config {
203203
this.getDecryptedConfig(_configData); // NOTE reinitialize the config with old data and new decrypted file
204204
} catch (__error) {
205205
// console.trace(error.message)
206-
cliux.print(chalk.red('Error: Config file is corrupted'));
206+
cliux.print(getChalk().red('Error: Config file is corrupted'));
207207
cliux.print(_error);
208208
process.exit(1);
209209
}

packages/contentstack-utilities/src/content-type-utils.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
1+
import { existsSync, readdirSync, readFileSync } from 'node:fs';
12
import { resolve as pResolve } from 'node:path';
2-
import { FsUtility } from './fs-utility';
33

44
/**
55
* Reads all content type schema files from a directory
66
* @param dirPath - Path to content types directory
77
* @param ignoredFiles - Files to ignore (defaults to schema.json, .DS_Store, __master.json, __priority.json)
8-
* @returns Array of content type schemas
8+
* @returns Array of content type schemas (empty if the path is missing or has no eligible files)
99
*/
1010
export function readContentTypeSchemas(
1111
dirPath: string,
1212
ignoredFiles: string[] = ['schema.json', '.DS_Store', '__master.json', '__priority.json', 'field_rules_uid.json'],
13-
): Record<string, unknown>[] | null {
14-
const fsUtil = new FsUtility();
15-
const files = fsUtil.readdir(dirPath);
13+
): Record<string, unknown>[] {
14+
if (!existsSync(dirPath)) {
15+
return [];
16+
}
17+
18+
const files = readdirSync(dirPath);
1619

1720
if (!files || files.length === 0) {
18-
return null;
21+
return [];
1922
}
2023

2124
const contentTypes: Record<string, unknown>[] = [];
@@ -33,7 +36,8 @@ export function readContentTypeSchemas(
3336

3437
try {
3538
const filePath = pResolve(dirPath, file);
36-
const contentType = fsUtil.readFile(filePath);
39+
const raw = readFileSync(filePath, 'utf8');
40+
const contentType = JSON.parse(raw) as Record<string, unknown>;
3741
if (contentType) {
3842
contentTypes.push(contentType as Record<string, unknown>);
3943
}

0 commit comments

Comments
 (0)