From 694c800e69271d419cc1f3bd2916d3331270db74 Mon Sep 17 00:00:00 2001 From: Aman Kumar Date: Thu, 5 Jun 2025 23:08:09 +0530 Subject: [PATCH 01/68] feat: integrated v2Logger in export plugin --- .../contentstack-export/messages/index.json | 69 +++++++++++++++++- .../src/commands/cm/stacks/export.ts | 71 ++++++++++++++----- .../src/export/module-exporter.ts | 24 +++++-- .../src/export/modules/assets.ts | 56 +++++++++------ .../src/export/modules/base-class.ts | 7 +- .../src/export/modules/content-types.ts | 39 ++++++---- .../src/export/modules/custom-roles.ts | 17 ++--- .../src/export/modules/entries.ts | 62 ++++++++++------ .../src/export/modules/environments.ts | 19 ++--- .../src/export/modules/extensions.ts | 18 ++--- .../src/export/modules/global-fields.ts | 26 ++++--- .../src/export/modules/index.ts | 15 +++- .../src/export/modules/labels.ts | 18 ++--- .../src/export/modules/locales.ts | 34 ++++++--- .../src/export/modules/marketplace-apps.ts | 54 +++++++++----- .../src/export/modules/personalize.ts | 16 +++-- .../src/export/modules/stack.ts | 26 ++++--- .../src/export/modules/taxonomies.ts | 41 ++++------- .../src/export/modules/webhooks.ts | 18 ++--- .../src/export/modules/workflows.ts | 26 ++++--- .../src/types/export-config.ts | 3 +- .../contentstack-export/src/types/index.ts | 10 +++ .../src/utils/basic-login.ts | 29 +++----- .../src/utils/common-helper.ts | 2 +- .../src/utils/marketplace-app-helper.ts | 5 +- .../src/utils/setup-branches.ts | 6 +- .../src/utils/setup-export-dir.ts | 3 +- .../src/constants/logging.ts | 4 +- packages/contentstack-utilities/src/index.ts | 1 + .../src/interfaces/index.ts | 10 ++- .../src/logger/cliErrorHandler.ts | 15 ++-- .../contentstack-utilities/src/logger/log.ts | 8 +-- .../src/logger/logger.ts | 45 ++++++------ .../src/export/attributes.ts | 14 ++-- .../src/export/audiences.ts | 13 ++-- .../src/export/events.ts | 15 ++-- .../src/export/experiences.ts | 28 +++++--- .../src/export/projects.ts | 10 +-- .../src/export/variant-entries.ts | 28 +++++--- .../src/types/export-config.ts | 3 +- .../contentstack-variants/src/types/utils.ts | 11 +++ 41 files changed, 591 insertions(+), 328 deletions(-) diff --git a/packages/contentstack-export/messages/index.json b/packages/contentstack-export/messages/index.json index 9e26dfeeb6..9c147dbd05 100644 --- a/packages/contentstack-export/messages/index.json +++ b/packages/contentstack-export/messages/index.json @@ -1 +1,68 @@ -{} \ No newline at end of file +{ +"ASSET_EXPORT_COMPLETE": "Asset export process completed successfully", +"ASSET_FOLDERS_EXPORT_COMPLETE": "Asset folder structure exported successfully", +"ASSET_METADATA_EXPORT_COMPLETE": "Asset metadata exported successfully", +"ASSET_VERSIONED_METADATA_EXPORT_COMPLETE": "Versioned asset metadata exported successfully", +"ASSET_DOWNLOAD_COMPLETE": "Asset download completed successfully", +"ASSET_DOWNLOAD_SUCCESS": "Asset '%s' (UID: %s) downloaded successfully", +"ASSET_DOWNLOAD_FAILED": "Failed to download asset '%s' (UID: %s)", +"ASSET_WRITE_FAILED": "Failed to write asset file '%s' (UID: %s)", +"ASSET_QUERY_FAILED": "Failed to query asset data from the API", +"ASSET_VERSIONED_QUERY_FAILED": "Failed to query versioned asset data from the API", +"ASSET_COUNT_QUERY_FAILED": "Failed to retrieve total asset count", + +"CONTENT_TYPE_EXPORT_COMPLETE": "Content types exported successfully", +"CONTENT_TYPE_NO_TYPES": "No content types found", +"CONTENT_TYPE_EXPORT_FAILED": "Failed to export content types", +"CONTENT_TYPE_NO_TYPES_RETURNED": "API returned no content types for the given query", + +"ENVIRONMENT_EXPORT_COMPLETE": "Successfully exported %s environment(s)", +"ENVIRONMENT_EXPORT_SUCCESS": "Environment '%s' exported successfully", +"ENVIRONMENT_NOT_FOUND": "No environments found in the current stack", + +"EXTENSION_EXPORT_COMPLETE": "Successfully exported %s extension(s)", +"EXTENSION_EXPORT_SUCCESS": "Extension '%s' exported successfully", +"EXTENSION_NOT_FOUND": "No extensions found in the current stack", + +"GLOBAL_FIELDS_EXPORT_COMPLETE": "Successfully exported %s global field(s)", + +"LABELS_EXPORT_COMPLETE": "Successfully exported %s label(s)", +"LABEL_EXPORT_SUCCESS": "Label '%s' exported successfully", +"LABELS_NOT_FOUND": "No labels found in the current stack", + +"LOCALES_EXPORT_COMPLETE": "Successfully exported %s locale(s) including %s master locale(s)", + +"TAXONOMY_EXPORT_COMPLETE": "Successfully exported %s taxonomy entries", +"TAXONOMY_EXPORT_SUCCESS": "Taxonomy '%s' exported successfully", +"TAXONOMY_NOT_FOUND": "No taxonomies found in the current stack", + +"WEBHOOK_EXPORT_COMPLETE": "Successfully exported %s webhook(s)", +"WEBHOOK_EXPORT_SUCCESS": "Webhook '%s' exported successfully", +"WEBHOOK_NOT_FOUND": "No webhooks found in the current stack", + +"WORKFLOW_EXPORT_COMPLETE": "Successfully exported %s workflow(s)", +"WORKFLOW_EXPORT_SUCCESS": "Workflow '%s' exported successfully", +"WORKFLOW_NOT_FOUND": "No workflows found in the current stack", + +"PERSONALIZE_URL_NOT_SET": "Cannot export Personalize project: URL not configured", +"PERSONALIZE_SKIPPING_WITH_MANAGEMENT_TOKEN": "Skipping Personalize project export: Management token not supported", +"PERSONALIZE_MODULE_NOT_IMPLEMENTED": "Module '%s' implementation not found", +"PERSONALIZE_NOT_ENABLED": "Personalize feature is not enabled for this organization", + +"MARKETPLACE_APPS_EXPORT_COMPLETE": "Successfully exported %s marketplace app(s)", +"MARKETPLACE_APP_CONFIG_EXPORT": "Exporting configuration for app '%s'", +"MARKETPLACE_APP_CONFIG_SUCCESS": "Successfully exported configuration for app '%s'", +"MARKETPLACE_APP_EXPORT_SUCCESS": "Successfully exported app '%s'", +"MARKETPLACE_APPS_NOT_FOUND": "No marketplace apps found in the current stack", +"MARKETPLACE_APP_CONFIG_EXPORT_FAILED": "Failed to export configuration for app '%s'", +"MARKETPLACE_APP_MANIFEST_EXPORT_FAILED": "Failed to export manifest for app '%s'", + +"ENTRIES_EXPORT_COMPLETE": "Successfully exported entries (Content Type: %s, Locale: %s)", +"ENTRIES_EXPORT_SUCCESS": "All entries exported successfully", +"ENTRIES_VERSIONED_EXPORT_SUCCESS": "Successfully exported versioned entry (Content Type: %s, UID: %s, Locale: %s)", +"ENTRIES_EXPORT_VERSIONS_FAILED": "Failed to export versions for content type '%s' (UID: %s)", + +"BRANCH_EXPORT_FAILED": "Failed to export contents from branch (UID: %s)", + +"ROLES_NO_CUSTOM_ROLES": "No custom roles found in the current stack" +} diff --git a/packages/contentstack-export/src/commands/cm/stacks/export.ts b/packages/contentstack-export/src/commands/cm/stacks/export.ts index 9ea35b0403..88c3f012f0 100644 --- a/packages/contentstack-export/src/commands/cm/stacks/export.ts +++ b/packages/contentstack-export/src/commands/cm/stacks/export.ts @@ -10,10 +10,13 @@ import { FlagInput, pathValidator, sanitizePath, + configHandler, + v2Logger, + handleAndLogError } from '@contentstack/cli-utilities'; import { ModuleExporter } from '../../../export'; -import { setupExportConfig, log, formatError, writeExportMetaFile } from '../../../utils'; -import { ExportConfig } from '../../../types'; +import { setupExportConfig, writeExportMetaFile } from '../../../utils'; +import { Context, ExportConfig } from '../../../types'; export default class ExportCommand extends Command { static description: string = messageHandler.parse('Export content from a stack'); @@ -72,19 +75,22 @@ export default class ExportCommand extends Command { }), module: flags.string({ char: 'm', - description: '[optional] Specific module name. If not specified, the export command will export all the modules to the stack. The available modules are assets, content-types, entries, environments, extensions, marketplace-apps, global-fields, labels, locales, webhooks, workflows, custom-roles, and taxonomies.', + description: + '[optional] Specific module name. If not specified, the export command will export all the modules to the stack. The available modules are assets, content-types, entries, environments, extensions, marketplace-apps, global-fields, labels, locales, webhooks, workflows, custom-roles, and taxonomies.', parse: printFlagDeprecation(['-m'], ['--module']), }), 'content-types': flags.string({ char: 't', - description: '[optional] The UID of the content type(s) whose content you want to export. In case of multiple content types, specify the IDs separated by spaces.', + description: + '[optional] The UID of the content type(s) whose content you want to export. In case of multiple content types, specify the IDs separated by spaces.', multiple: true, parse: printFlagDeprecation(['-t'], ['--content-types']), }), branch: flags.string({ char: 'B', // default: 'main', - description: '[optional] The name of the branch where you want to export your content. If you don\'t mention the branch name, then by default the content will be exported from all the branches of your stack.', + description: + "[optional] The name of the branch where you want to export your content. If you don't mention the branch name, then by default the content will be exported from all the branches of your stack.", parse: printFlagDeprecation(['-B'], ['--branch']), }), 'secured-assets': flags.boolean({ @@ -101,14 +107,17 @@ export default class ExportCommand extends Command { async run(): Promise { let exportDir: string = pathValidator('logs'); + let exportConfig: ExportConfig; try { const { flags } = await this.parse(ExportCommand); - let exportConfig = await setupExportConfig(flags); - // Note setting host to create cma client - exportConfig.host = this.cmaHost; - exportConfig.region = this.region; - if(this.developerHubUrl) exportConfig.developerHubBaseUrl = this.developerHubUrl; - if (this.personalizeUrl) exportConfig.modules.personalize.baseURL[exportConfig.region.name] = this.personalizeUrl; + exportConfig = await setupExportConfig(flags); + // Prepare the context object + const context = this.createExportContext(); + exportConfig.context = context; + + // Assign exportConfig variables + this.assignExportConfig(exportConfig); + exportDir = sanitizePath(exportConfig.cliLogsPath || exportConfig.data || exportConfig.exportDir); const managementAPIClient: ContentstackClient = await managementSDKClient(exportConfig); const moduleExporter = new ModuleExporter(managementAPIClient, exportConfig); @@ -116,15 +125,39 @@ export default class ExportCommand extends Command { if (!exportConfig.branches?.length) { writeExportMetaFile(exportConfig); } - log(exportConfig, `The content of the stack ${exportConfig.apiKey} has been exported successfully!`, 'success'); - log( - exportConfig, - `The log has been stored at '${pathValidator(path.join(exportDir, 'logs', 'export'))}'`, - 'success', - ); + v2Logger.success(`The content of the stack ${exportConfig.apiKey} has been exported successfully!`,exportConfig.context) + v2Logger.success(`The log has been stored at '${pathValidator(path.join(process.cwd(), 'logs'))}'`, exportConfig.context) } catch (error) { - log({ data: exportDir } as ExportConfig, `Failed to export stack content - ${formatError(error)}`, 'error'); - log({ data: exportDir } as ExportConfig, `The log has been stored at ${exportDir}`, 'info'); + handleAndLogError(error, { ...exportConfig.context }); + } + } + + // Create export context object + private createExportContext(): Context { + return { + command: this.context.info.command, + module: '', + userId: configHandler.get('userId'), + email: configHandler.get('email'), + sessionId: this.context.sessionId, + clientId: this.context.clientId, + apiKey: configHandler.get('apiKey') || '', + orgId: configHandler.get('organization_uid') || '', + }; + } + + // Assign values to exportConfig + private assignExportConfig(exportConfig: ExportConfig): void { + // Note setting host to create cma client + exportConfig.host = this.cmaHost; + exportConfig.region = this.region; + + if (this.developerHubUrl) { + exportConfig.developerHubBaseUrl = this.developerHubUrl; + } + + if (this.personalizeUrl) { + exportConfig.modules.personalize.baseURL[exportConfig.region.name] = this.personalizeUrl; } } } diff --git a/packages/contentstack-export/src/export/module-exporter.ts b/packages/contentstack-export/src/export/module-exporter.ts index 4daaa797f9..a90f53c9c9 100644 --- a/packages/contentstack-export/src/export/module-exporter.ts +++ b/packages/contentstack-export/src/export/module-exporter.ts @@ -1,5 +1,5 @@ import * as path from 'path'; -import { ContentstackClient } from '@contentstack/cli-utilities'; +import { ContentstackClient, handleAndLogError, messageHandler, v2Logger } from '@contentstack/cli-utilities'; import { setupBranches, setupExportDir, log, formatError, writeExportMetaFile } from '../utils'; import startModuleExport from './modules'; import startJSModuleExport from './modules-js'; @@ -38,19 +38,29 @@ class ModuleExporter { this.exportConfig.branchName = branch.uid; this.stackAPIClient.stackHeaders.branch = branch.uid; this.exportConfig.branchDir = path.join(this.exportConfig.exportDir, branch.uid); - log(this.exportConfig, `Exporting content from branch ${branch.uid}`, 'success'); + v2Logger.info(`Exporting content from branch ${branch.uid}`, this.exportConfig.context); writeExportMetaFile(this.exportConfig, this.exportConfig.branchDir); await this.export(); - log(this.exportConfig, `The content of branch ${branch.uid} has been exported successfully!`, 'success'); + v2Logger.success( + `The content of branch ${branch.uid} has been exported successfully!`, + this.exportConfig.context, + ); } catch (error) { - log(this.exportConfig, formatError(error), 'error'); - throw new Error(`Failed to export contents from branch ${branch.uid}`); + handleAndLogError( + error, + { ...this.exportConfig.context, branch: branch.uid }, + messageHandler.parse('FAILED_EXPORT_CONTENT_BRANCH', { branch: branch.uid }), + ); + throw new Error(messageHandler.parse('FAILED_EXPORT_CONTENT_BRANCH', { branch: branch.uid })); } } } async export() { - log(this.exportConfig, `Started to export content, version is ${this.exportConfig.contentVersion}`, 'info'); + v2Logger.info( + `Started to export content, version is ${this.exportConfig.contentVersion}`, + this.exportConfig.context, + ); // checks for single module or all modules if (this.exportConfig.singleModuleExport) { return this.exportSingleModule(this.exportConfig.moduleName); @@ -59,7 +69,7 @@ class ModuleExporter { } async exportByModuleByName(moduleName: Modules) { - log(this.exportConfig, `Starting export of ${moduleName} module`, 'info'); + v2Logger.info(`Exporting module: ${moduleName}`, this.exportConfig.context); // export the modules by name // calls the module runner which inturn calls the module itself let exportedModuleResponse; diff --git a/packages/contentstack-export/src/export/modules/assets.ts b/packages/contentstack-export/src/export/modules/assets.ts index 429c7f82a3..575d3ca619 100644 --- a/packages/contentstack-export/src/export/modules/assets.ts +++ b/packages/contentstack-export/src/export/modules/assets.ts @@ -11,11 +11,17 @@ import includes from 'lodash/includes'; import progress from 'progress-stream'; import { createWriteStream } from 'node:fs'; import { resolve as pResolve } from 'node:path'; -import { FsUtility, getDirectories, configHandler } from '@contentstack/cli-utilities'; +import { + FsUtility, + getDirectories, + configHandler, + v2Logger, + handleAndLogError, + messageHandler, +} from '@contentstack/cli-utilities'; import { ModuleClassParams } from '../../types'; import config from '../../config'; -import { log } from '../../utils'; import BaseClass, { CustomPromiseHandler, CustomPromiseHandlerInput } from './base-class'; export default class ExportAssets extends BaseClass { @@ -26,6 +32,7 @@ export default class ExportAssets extends BaseClass { constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); + this.exportConfig.context.module = 'assets'; } get commonQueryParam(): Record { @@ -56,8 +63,7 @@ export default class ExportAssets extends BaseClass { // NOTE step 4: Download all assets await this.downloadAssets(); - - log(this.exportConfig, 'Assets exported successfully.!', 'info'); + v2Logger.success(messageHandler.parse('ASSET_EXPORT_COMPLETE'), this.exportConfig.context); } /** @@ -77,8 +83,7 @@ export default class ExportAssets extends BaseClass { if (!isEmpty(items)) this.assetsFolder.push(...items); }; const onReject = ({ error }: any) => { - log(this.exportConfig, 'Export asset folder query failed', 'error'); - log(this.exportConfig, error, 'error'); + handleAndLogError(error, { ...this.exportConfig.context }); }; return this.makeConcurrentCall({ @@ -98,7 +103,10 @@ export default class ExportAssets extends BaseClass { this.assetsFolder, ); } - log(this.exportConfig, 'Assets folder Exported successfully.!', 'info'); + v2Logger.info( + messageHandler.parse('ASSET_FOLDERS_EXPORT_COMPLETE', this.assetsFolder.length), + this.exportConfig.context, + ); }); } @@ -133,8 +141,7 @@ export default class ExportAssets extends BaseClass { } const onReject = ({ error }: any) => { - log(this.exportConfig, 'Export asset query failed', 'error'); - log(this.exportConfig, error.message, 'error'); + handleAndLogError(error, { ...this.exportConfig.context }, messageHandler.parse('ASSET_QUERY_FAILED')); }; const onSuccess = ({ response: { items } }: any) => { @@ -163,7 +170,7 @@ export default class ExportAssets extends BaseClass { concurrencyLimit: this.assetConfig.fetchConcurrency, }).then(() => { fs?.completeFile(true); - log(this.exportConfig, 'Assets metadata exported successfully.!', 'info'); + v2Logger.info(messageHandler.parse('ASSET_METADATA_EXPORT_COMPLETE'), this.exportConfig.context); }); } @@ -221,8 +228,7 @@ export default class ExportAssets extends BaseClass { }); }; const onReject = ({ error }: any) => { - log(this.exportConfig, 'Export versioned asset query failed', 'error'); - log(this.exportConfig, error, 'error'); + handleAndLogError(error, { ...this.exportConfig.context }, messageHandler.parse('ASSET_VERSIONED_QUERY_FAILED')); }; return this.makeConcurrentCall( @@ -241,7 +247,7 @@ export default class ExportAssets extends BaseClass { promisifyHandler, ).then(() => { fs?.completeFile(true); - log(this.exportConfig, 'Assets folder Exported successfully.!', 'info'); + v2Logger.info(messageHandler.parse('ASSET_VERSIONED_METADATA_EXPORT_COMPLETE'), this.exportConfig.context); }); } @@ -265,8 +271,7 @@ export default class ExportAssets extends BaseClass { .count() .then(({ assets }: any) => assets) .catch((error: Error) => { - log(this.exportConfig, 'Get count query failed', 'error'); - log(this.exportConfig, error, 'error'); + handleAndLogError(error, { ...this.exportConfig.context }, messageHandler.parse('ASSET_COUNT_QUERY_FAILED')); }); } @@ -306,8 +311,11 @@ export default class ExportAssets extends BaseClass { const assetWriterStream = createWriteStream(assetFilePath); assetWriterStream.on('error', (error) => { - log(this.exportConfig, `Downloaded failed ${asset.filename}: ${asset.uid}!`, 'error'); - log(this.exportConfig, error, 'error'); + handleAndLogError( + error, + { ...this.exportConfig.context, uid: asset.uid, filename: asset.fileName }, + messageHandler.parse('ASSET_DOWNLOAD_FAILED', asset.filename, asset.uid), + ); }); /** * NOTE if pipe not working as expected add the following code below to fix the issue @@ -330,13 +338,19 @@ export default class ExportAssets extends BaseClass { data.pipe(assetWriterStream); } - log(this.exportConfig, `Downloaded ${asset.filename}: ${asset.uid} successfully!`, 'success'); + v2Logger.success( + messageHandler.parse('ASSET_DOWNLOAD_SUCCESS', asset.filename, asset.uid), + this.exportConfig.context, + ); }; const onReject = ({ error, additionalInfo }: any) => { const { asset } = additionalInfo; - log(this.exportConfig, `Downloaded failed ${asset.filename}: ${asset.uid}!`, 'error'); - log(this.exportConfig, error, 'error'); + handleAndLogError( + error, + { ...this.exportConfig.context, uid: asset.uid, filename: asset.filename }, + messageHandler.parse('ASSET_DOWNLOAD_FAILED', asset.filename, asset.uid), + ); }; const promisifyHandler: CustomPromiseHandler = (input: CustomPromiseHandlerInput) => { @@ -364,7 +378,7 @@ export default class ExportAssets extends BaseClass { }, promisifyHandler, ).then(() => { - log(this.exportConfig, 'Assets download completed successfully.!', 'info'); + v2Logger.success(messageHandler.parse('ASSET_DOWNLOAD_COMPLETE'), this.exportConfig.context); }); } } diff --git a/packages/contentstack-export/src/export/modules/base-class.ts b/packages/contentstack-export/src/export/modules/base-class.ts index 8cd2473c78..6e91a455d7 100644 --- a/packages/contentstack-export/src/export/modules/base-class.ts +++ b/packages/contentstack-export/src/export/modules/base-class.ts @@ -5,8 +5,8 @@ import chunk from 'lodash/chunk'; import isEmpty from 'lodash/isEmpty'; import entries from 'lodash/entries'; import isEqual from 'lodash/isEqual'; +import { v2Logger } from '@contentstack/cli-utilities'; -import { log } from '../../utils'; import { ExportConfig, ModuleClassParams } from '../../types'; export type ApiOptions = { @@ -134,7 +134,10 @@ export default abstract class BaseClass { async logMsgAndWaitIfRequired(module: string, start: number, batchNo: number): Promise { const end = Date.now(); const exeTime = end - start; - log(this.exportConfig, `Batch No. ${batchNo} of ${module} is complete.`, 'success'); + v2Logger.success( + `Batch No. ${batchNo} of ${module} is complete. Time taken: ${exeTime} milliseconds`, + this.exportConfig.context, + ); if (this.exportConfig.modules.assets.displayExecutionTime) { console.log( diff --git a/packages/contentstack-export/src/export/modules/content-types.ts b/packages/contentstack-export/src/export/modules/content-types.ts index 9e714ec9d0..0488044fcc 100644 --- a/packages/contentstack-export/src/export/modules/content-types.ts +++ b/packages/contentstack-export/src/export/modules/content-types.ts @@ -1,9 +1,15 @@ import * as path from 'path'; -import { ContentstackClient } from '@contentstack/cli-utilities'; -import { log, formatError, fsUtil, executeTask } from '../../utils'; -import { ExportConfig, ModuleClassParams } from '../../types'; +import { + ContentstackClient, + handleAndLogError, + messageHandler, + v2Logger, + sanitizePath, +} from '@contentstack/cli-utilities'; + import BaseClass from './base-class'; -import { sanitizePath } from '@contentstack/cli-utilities'; +import { fsUtil, executeTask } from '../../utils'; +import { ExportConfig, ModuleClassParams } from '../../types'; export default class ContentTypesExport extends BaseClass { private stackAPIClient: ReturnType; @@ -14,7 +20,7 @@ export default class ContentTypesExport extends BaseClass { skip?: number; limit?: number; include_global_field_schema: boolean; - uid?: Record + uid?: Record; }; private contentTypesConfig: { dirName?: string; @@ -38,29 +44,29 @@ export default class ContentTypesExport extends BaseClass { include_global_field_schema: true, }; - // If content type id is provided then use it as part of query - if (Array.isArray(this.exportConfig.contentTypes) && this.exportConfig.contentTypes.length > 0) { + // If content type id is provided then use it as part of query + if (Array.isArray(this.exportConfig.contentTypes) && this.exportConfig.contentTypes.length > 0) { this.qs.uid = { $in: this.exportConfig.contentTypes }; - } - + } + this.contentTypesDirPath = path.resolve( sanitizePath(exportConfig.data), sanitizePath(exportConfig.branchName || ''), sanitizePath(this.contentTypesConfig.dirName), ); this.contentTypes = []; + this.exportConfig.context.module = 'content-types'; } async start() { try { - log(this.exportConfig, 'Starting content type export', 'success'); await fsUtil.makeDirectory(this.contentTypesDirPath); await this.getContentTypes(); await this.writeContentTypes(this.contentTypes); - log(this.exportConfig, 'Content type(s) exported successfully', 'success'); + v2Logger.success(messageHandler.parse('CONTENT_TYPE_EXPORT_COMPLETE'), this.exportConfig.context); } catch (error) { - log(this.exportConfig, `Failed to export content types ${formatError(error)}`, 'error'); - throw new Error('Failed to export content types'); + handleAndLogError(error, { ...this.exportConfig.context }); + throw new Error(messageHandler.parse('CONTENT_TYPE_EXPORT_FAILED')); } } @@ -79,7 +85,7 @@ export default class ContentTypesExport extends BaseClass { } return await this.getContentTypes(skip); } else { - log(this.exportConfig, 'No content types returned for the given query', 'info'); + v2Logger.info(messageHandler.parse('CONTENT_TYPE_NO_TYPES'), this.exportConfig.context); } } @@ -99,7 +105,10 @@ export default class ContentTypesExport extends BaseClass { async writeContentTypes(contentTypes: Record[]) { function write(contentType: Record) { return fsUtil.writeFile( - path.join(sanitizePath(this.contentTypesDirPath), sanitizePath(`${contentType.uid === 'schema' ? 'schema|1' : contentType.uid}.json`)), + path.join( + sanitizePath(this.contentTypesDirPath), + sanitizePath(`${contentType.uid === 'schema' ? 'schema|1' : contentType.uid}.json`), + ), contentType, ); } diff --git a/packages/contentstack-export/src/export/modules/custom-roles.ts b/packages/contentstack-export/src/export/modules/custom-roles.ts index 74397555c0..a77b17aad7 100644 --- a/packages/contentstack-export/src/export/modules/custom-roles.ts +++ b/packages/contentstack-export/src/export/modules/custom-roles.ts @@ -3,9 +3,10 @@ import find from 'lodash/find'; import forEach from 'lodash/forEach'; import values from 'lodash/values'; import { resolve as pResolve } from 'node:path'; +import { handleAndLogError, messageHandler, v2Logger } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; -import { log, formatError, fsUtil } from '../../utils'; +import { fsUtil } from '../../utils'; import { CustomRoleConfig, ModuleClassParams } from '../../types'; export default class ExportCustomRoles extends BaseClass { @@ -24,10 +25,10 @@ export default class ExportCustomRoles extends BaseClass { this.existingRoles = { Admin: 1, Developer: 1, 'Content Manager': 1 }; this.localesMap = {}; this.sourceLocalesMap = {}; + this.exportConfig.context.module = 'custom-roles'; } async start(): Promise { - log(this.exportConfig, 'Starting custom roles export', 'info'); this.rolesFolderPath = pResolve( this.exportConfig.data, @@ -46,16 +47,16 @@ export default class ExportCustomRoles extends BaseClass { .role() .fetchAll({ include_rules: true, include_permissions: true }) .then((data: any) => data) - .catch((err: any) => log(this.exportConfig, `Failed to fetch roles. ${formatError(err)}`, 'error')); + .catch((err: any) => handleAndLogError(err, { ...this.exportConfig.context })); const customRoles = roles.items.filter((role: any) => !this.existingRoles[role.name]); if (!customRoles.length) { - log(this.exportConfig, 'No custom roles were found in the Stack', 'info'); + v2Logger.info(messageHandler.parse('ROLES_NO_CUSTOM_ROLES'), this.exportConfig.context); return; } customRoles.forEach((role: any) => { - log(this.exportConfig, `'${role?.name}' role was exported successfully`, 'info'); + v2Logger.info(`Exporting role: ${role.name}`, this.exportConfig.context); this.customRoles[role.uid] = role; }); fsUtil.writeFile(pResolve(this.rolesFolderPath, this.customRolesConfig.fileName), this.customRoles); @@ -67,7 +68,7 @@ export default class ExportCustomRoles extends BaseClass { .query({}) .find() .then((data: any) => data) - .catch((err: any) => log(this.exportConfig, `Failed to fetch locales. ${formatError(err)}`, 'error')); + .catch((err: any) => handleAndLogError(err, { ...this.exportConfig.context })); for (const locale of locales.items) { this.sourceLocalesMap[locale.uid] = locale; } @@ -75,12 +76,12 @@ export default class ExportCustomRoles extends BaseClass { async getCustomRolesLocales() { for (const role of values(this.customRoles)) { - const customRole = role as Record; + const customRole = role as Record; const rulesLocales = find(customRole.rules, (rule: any) => rule.module === 'locale'); if (rulesLocales?.locales?.length) { forEach(rulesLocales.locales, (locale: any) => { this.localesMap[locale] = 1; - }) + }); } } diff --git a/packages/contentstack-export/src/export/modules/entries.ts b/packages/contentstack-export/src/export/modules/entries.ts index 11e0a8ac5d..c55ec817dd 100644 --- a/packages/contentstack-export/src/export/modules/entries.ts +++ b/packages/contentstack-export/src/export/modules/entries.ts @@ -1,11 +1,17 @@ import * as path from 'path'; -import { ContentstackClient, FsUtility } from '@contentstack/cli-utilities'; -import { LogType, Export, ExportProjects } from '@contentstack/cli-variants'; +import { + ContentstackClient, + FsUtility, + handleAndLogError, + messageHandler, + v2Logger, +} from '@contentstack/cli-utilities'; +import { Export, ExportProjects } from '@contentstack/cli-variants'; +import { sanitizePath } from '@contentstack/cli-utilities'; -import { log, formatError, fsUtil } from '../../utils'; -import { ExportConfig, ModuleClassParams } from '../../types'; +import { fsUtil } from '../../utils'; import BaseClass, { ApiOptions } from './base-class'; -import { sanitizePath } from '@contentstack/cli-utilities'; +import { ExportConfig, ModuleClassParams } from '../../types'; export default class EntriesExport extends BaseClass { private stackAPIClient: ReturnType; @@ -52,15 +58,15 @@ export default class EntriesExport extends BaseClass { 'schema.json', ); this.projectInstance = new ExportProjects(this.exportConfig); + this.exportConfig.context.module = 'entries'; } async start() { try { - log(this.exportConfig, 'Starting entries export', 'info'); const locales = fsUtil.readFile(this.localesFilePath) as Array>; const contentTypes = fsUtil.readFile(this.schemaFilePath) as Array>; if (contentTypes.length === 0) { - log(this.exportConfig, 'No content types found to export entries', 'info'); + v2Logger.info(messageHandler.parse('CONTENT_TYPE_NO_TYPES'), this.exportConfig.context); return; } @@ -77,7 +83,7 @@ export default class EntriesExport extends BaseClass { this.variantEntries = new Export.VariantEntries(Object.assign(this.exportConfig, { project_id })); } catch (error) { - log(this.exportConfig, `Failed to export variant entries ${error}`, 'error'); + handleAndLogError(error, { ...this.exportConfig.context }); } } @@ -85,16 +91,18 @@ export default class EntriesExport extends BaseClass { for (let entryRequestOption of entryRequestOptions) { await this.getEntries(entryRequestOption); this.entriesFileHelper?.completeFile(true); - log( - this.exportConfig, - `Exported entries of type '${entryRequestOption.contentType}' locale '${entryRequestOption.locale}'`, - 'success', + v2Logger.success( + messageHandler.parse( + 'ENTRIES_EXPORT_COMPLETE', + entryRequestOption.contentType, + entryRequestOption.locale, + ), + this.exportConfig.context, ); } - log(this.exportConfig, 'Entries exported successfully', 'success'); + v2Logger.success(messageHandler.parse('ENTRIES_EXPORT_SUCCESS'), this.exportConfig.context); } catch (error) { - log(this.exportConfig, `Failed to export entries ${formatError(error)}`, 'error'); - throw new Error('Failed to export entries'); + handleAndLogError(error, { ...this.exportConfig.context }); } } @@ -142,8 +150,11 @@ export default class EntriesExport extends BaseClass { .query(requestObject) .find(); } catch (error) { - log(this.exportConfig, `Failed to export entries ${formatError(error)}`, 'error'); - throw new Error('Failed to export entries'); + handleAndLogError(error, { + ...this.exportConfig.context, + contentType: options.contentType, + locale: options.locale, + }); } if (Array.isArray(entriesSearchResponse.items) && entriesSearchResponse.items.length > 0) { @@ -205,15 +216,20 @@ export default class EntriesExport extends BaseClass { path.join(sanitizePath(options.versionedEntryPath), sanitizePath(`${entry.uid}.json`)), response, ); - log( - this.exportConfig, - `Exported versioned entries of type '${options.contentType}' locale '${options.locale}'`, - 'success', + v2Logger.success( + messageHandler.parse('ENTRIES_VERSIONED_EXPORT_SUCCESS', options.contentType, entry.uid, options.locale), + this.exportConfig.context, ); }; const onReject = ({ error, apiData: { uid } = undefined }: any) => { - log(this.exportConfig, `failed to export versions of entry ${uid}`, 'error'); - log(this.exportConfig, formatError(error), 'error'); + handleAndLogError( + error, + { + ...this.exportConfig.context, + uid, + }, + messageHandler.parse('ENTRIES_EXPORT_VERSIONS_FAILED', uid), + ); }; return await this.makeConcurrentCall( diff --git a/packages/contentstack-export/src/export/modules/environments.ts b/packages/contentstack-export/src/export/modules/environments.ts index 25e02dadac..ce5de2d94d 100644 --- a/packages/contentstack-export/src/export/modules/environments.ts +++ b/packages/contentstack-export/src/export/modules/environments.ts @@ -1,9 +1,10 @@ import { resolve as pResolve } from 'node:path'; import omit from 'lodash/omit'; import isEmpty from 'lodash/isEmpty'; +import { handleAndLogError, messageHandler, v2Logger } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; -import { log, formatError, fsUtil } from '../../utils'; +import { fsUtil } from '../../utils'; import { EnvironmentConfig, ModuleClassParams } from '../../types'; export default class ExportEnvironments extends BaseClass { @@ -20,12 +21,10 @@ export default class ExportEnvironments extends BaseClass { this.environments = {}; this.environmentConfig = exportConfig.modules.environments; this.qs = { include_count: true }; + this.exportConfig.context.module = 'environments'; } - async start(): Promise { - log(this.exportConfig, 'Starting environment export', 'info'); - this.environmentsFolderPath = pResolve( this.exportConfig.data, this.exportConfig.branchName || '', @@ -36,10 +35,13 @@ export default class ExportEnvironments extends BaseClass { await this.getEnvironments(); if (this.environments === undefined || isEmpty(this.environments)) { - log(this.exportConfig, 'No environments found', 'info'); + v2Logger.info(messageHandler.parse('ENVIRONMENT_NOT_FOUND'), this.exportConfig.context); } else { fsUtil.writeFile(pResolve(this.environmentsFolderPath, this.environmentConfig.fileName), this.environments); - log(this.exportConfig, 'All the environments have been exported successfully!', 'success'); + v2Logger.success( + messageHandler.parse('ENVIRONMENT_EXPORT_COMPLETE', Object.keys(this.environments).length), + this.exportConfig.context, + ); } } @@ -63,8 +65,7 @@ export default class ExportEnvironments extends BaseClass { } }) .catch((error: any) => { - log(this.exportConfig, `Failed to export environments. ${formatError(error)}`, 'error'); - log(this.exportConfig, error, 'error'); + handleAndLogError(error, { ...this.exportConfig.context }); }); } @@ -73,7 +74,7 @@ export default class ExportEnvironments extends BaseClass { const extUid = environments[index].uid; const envName = environments[index]?.name; this.environments[extUid] = omit(environments[index], ['ACL']); - log(this.exportConfig, `'${envName}' environment was exported successfully`, 'success'); + v2Logger.success(messageHandler.parse('ENVIRONMENT_EXPORT_SUCCESS', envName ), this.exportConfig.context); } } } diff --git a/packages/contentstack-export/src/export/modules/extensions.ts b/packages/contentstack-export/src/export/modules/extensions.ts index 5eb51b2433..e1552a1174 100644 --- a/packages/contentstack-export/src/export/modules/extensions.ts +++ b/packages/contentstack-export/src/export/modules/extensions.ts @@ -1,9 +1,10 @@ import omit from 'lodash/omit'; import isEmpty from 'lodash/isEmpty'; import { resolve as pResolve } from 'node:path'; +import { handleAndLogError, messageHandler, v2Logger } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; -import { log, formatError, fsUtil } from '../../utils'; +import { fsUtil } from '../../utils'; import { ExtensionsConfig, ModuleClassParams } from '../../types'; export default class ExportExtensions extends BaseClass { @@ -20,11 +21,10 @@ export default class ExportExtensions extends BaseClass { this.extensions = {}; this.extensionConfig = exportConfig.modules.extensions; this.qs = { include_count: true }; + this.exportConfig.context.module = 'extensions'; } async start(): Promise { - log(this.exportConfig, 'Starting extension export', 'info'); - this.extensionsFolderPath = pResolve( this.exportConfig.data, this.exportConfig.branchName || '', @@ -35,10 +35,13 @@ export default class ExportExtensions extends BaseClass { await this.getExtensions(); if (this.extensions === undefined || isEmpty(this.extensions)) { - log(this.exportConfig, 'No extensions found', 'info'); + v2Logger.info(messageHandler.parse('EXTENSION_NOT_FOUND'), this.exportConfig.context); } else { fsUtil.writeFile(pResolve(this.extensionsFolderPath, this.extensionConfig.fileName), this.extensions); - log(this.exportConfig, 'All the extensions have been exported successfully!', 'success'); + v2Logger.success( + messageHandler.parse('EXTENSION_EXPORT_COMPLETE', Object.keys(this.extensions).length ), + this.exportConfig.context, + ); } } @@ -62,8 +65,7 @@ export default class ExportExtensions extends BaseClass { } }) .catch((error: any) => { - log(this.exportConfig, `Failed to export extensions. ${formatError(error)}`, 'error'); - log(this.exportConfig, error, 'error'); + handleAndLogError(error, { ...this.exportConfig.context }); }); } @@ -72,7 +74,7 @@ export default class ExportExtensions extends BaseClass { const extUid = extensions[index].uid; const extTitle = extensions[index]?.title; this.extensions[extUid] = omit(extensions[index], ['SYS_ACL']); - log(this.exportConfig, `'${extTitle}' extension was exported successfully`, 'success'); + v2Logger.info(messageHandler.parse('EXTENSION_EXPORT_SUCCESS', extTitle), this.exportConfig.context); } } } diff --git a/packages/contentstack-export/src/export/modules/global-fields.ts b/packages/contentstack-export/src/export/modules/global-fields.ts index e7cdda46c0..238d53efa1 100644 --- a/packages/contentstack-export/src/export/modules/global-fields.ts +++ b/packages/contentstack-export/src/export/modules/global-fields.ts @@ -1,9 +1,15 @@ import * as path from 'path'; -import { ContentstackClient } from '@contentstack/cli-utilities'; -import { log, formatError, fsUtil } from '../../utils'; +import { + ContentstackClient, + handleAndLogError, + messageHandler, + v2Logger, + sanitizePath, +} from '@contentstack/cli-utilities'; + +import { fsUtil } from '../../utils'; import { ExportConfig, ModuleClassParams } from '../../types'; import BaseClass from './base-class'; -import { sanitizePath } from '@contentstack/cli-utilities'; export default class GlobalFieldsExport extends BaseClass { private stackAPIClient: ReturnType; @@ -35,7 +41,7 @@ export default class GlobalFieldsExport extends BaseClass { asc: 'updated_at', include_count: true, limit: this.globalFieldsConfig.limit, - include_global_field_schema: true + include_global_field_schema: true, }; this.globalFieldsDirPath = path.resolve( sanitizePath(exportConfig.data), @@ -43,18 +49,20 @@ export default class GlobalFieldsExport extends BaseClass { sanitizePath(this.globalFieldsConfig.dirName), ); this.globalFields = []; + this.exportConfig.context.module = 'global-fields'; } async start() { try { - log(this.exportConfig, 'Starting global fields export', 'success'); await fsUtil.makeDirectory(this.globalFieldsDirPath); await this.getGlobalFields(); fsUtil.writeFile(path.join(this.globalFieldsDirPath, this.globalFieldsConfig.fileName), this.globalFields); - log(this.exportConfig, 'Completed global fields export', 'success'); + v2Logger.success( + messageHandler.parse('GLOBAL_FIELDS_EXPORT_COMPLETE', this.globalFields.length), + this.exportConfig.context, + ); } catch (error) { - log(this.exportConfig, `Failed to export global fields. ${formatError(error)}`, 'error'); - throw new Error('Failed to export global fields'); + handleAndLogError(error, { ...this.exportConfig.context }); } } @@ -62,7 +70,7 @@ export default class GlobalFieldsExport extends BaseClass { if (skip) { this.qs.skip = skip; } - let globalFieldsFetchResponse = await this.stackAPIClient.globalField({api_version: '3.2'}).query(this.qs).find(); + let globalFieldsFetchResponse = await this.stackAPIClient.globalField({ api_version: '3.2' }).query(this.qs).find(); if (Array.isArray(globalFieldsFetchResponse.items) && globalFieldsFetchResponse.items.length > 0) { this.sanitizeAttribs(globalFieldsFetchResponse.items); skip += this.globalFieldsConfig.limit || 100; diff --git a/packages/contentstack-export/src/export/modules/index.ts b/packages/contentstack-export/src/export/modules/index.ts index 361339b1fc..f13bc4fa3d 100644 --- a/packages/contentstack-export/src/export/modules/index.ts +++ b/packages/contentstack-export/src/export/modules/index.ts @@ -1,9 +1,18 @@ +import { handleAndLogError } from '@contentstack/cli-utilities'; import { ModuleClassParams } from '../../types'; export default async function startModuleExport(modulePayload: ModuleClassParams) { - const { default: ModuleRunner } = await import(`./${modulePayload.moduleName}`); - const moduleRunner = new ModuleRunner(modulePayload); - return moduleRunner.start(); + try { + const { default: ModuleRunner } = await import(`./${modulePayload.moduleName}`); + const moduleRunner = new ModuleRunner(modulePayload); + return moduleRunner.start(); + } catch (error) { + handleAndLogError(error, { + ...modulePayload.exportConfig.context, + module: modulePayload.moduleName, + }); + throw error; + } } export { default as ExportAssets } from './assets'; diff --git a/packages/contentstack-export/src/export/modules/labels.ts b/packages/contentstack-export/src/export/modules/labels.ts index 3bbb680f8b..b033ed3374 100644 --- a/packages/contentstack-export/src/export/modules/labels.ts +++ b/packages/contentstack-export/src/export/modules/labels.ts @@ -1,9 +1,10 @@ import omit from 'lodash/omit'; import isEmpty from 'lodash/isEmpty'; import { resolve as pResolve } from 'node:path'; +import { handleAndLogError, messageHandler, v2Logger } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; -import { log, formatError, fsUtil } from '../../utils'; +import { fsUtil } from '../../utils'; import { LabelConfig, ModuleClassParams } from '../../types'; export default class ExportLabels extends BaseClass { @@ -20,11 +21,10 @@ export default class ExportLabels extends BaseClass { this.labels = {}; this.labelConfig = exportConfig.modules.labels; this.qs = { include_count: true }; + this.exportConfig.context.module = 'labels'; } async start(): Promise { - log(this.exportConfig, 'Starting labels export', 'info'); - this.labelsFolderPath = pResolve( this.exportConfig.data, this.exportConfig.branchName || '', @@ -34,10 +34,13 @@ export default class ExportLabels extends BaseClass { await fsUtil.makeDirectory(this.labelsFolderPath); await this.getLabels(); if (this.labels === undefined || isEmpty(this.labels)) { - log(this.exportConfig, 'No labels found', 'info'); + v2Logger.info(messageHandler.parse('LABELS_NOT_FOUND'), this.exportConfig.context); } else { fsUtil.writeFile(pResolve(this.labelsFolderPath, this.labelConfig.fileName), this.labels); - log(this.exportConfig, 'All the labels have been exported successfully!', 'success'); + v2Logger.success( + messageHandler.parse('LABELS_EXPORT_COMPLETE', Object.keys(this.labels).length), + this.exportConfig.context, + ); } } @@ -61,8 +64,7 @@ export default class ExportLabels extends BaseClass { } }) .catch((error: any) => { - log(this.exportConfig, `Failed to export labels. ${formatError(error)}`, 'error'); - log(this.exportConfig, error, 'error'); + handleAndLogError(error, { ...this.exportConfig.context }); }); } @@ -71,7 +73,7 @@ export default class ExportLabels extends BaseClass { const labelUid = labels[index].uid; const labelName = labels[index]?.name; this.labels[labelUid] = omit(labels[index], this.labelConfig.invalidKeys); - log(this.exportConfig, `'${labelName}' label was exported successfully`, 'success'); + v2Logger.info(messageHandler.parse('LABEL_EXPORT_SUCCESS', labelName), this.exportConfig.context); } } } diff --git a/packages/contentstack-export/src/export/modules/locales.ts b/packages/contentstack-export/src/export/modules/locales.ts index 602da209bd..4584f25868 100644 --- a/packages/contentstack-export/src/export/modules/locales.ts +++ b/packages/contentstack-export/src/export/modules/locales.ts @@ -1,9 +1,15 @@ import * as path from 'path'; -import { ContentstackClient } from '@contentstack/cli-utilities'; -import { log, formatError, fsUtil } from '../../utils'; -import { ExportConfig, ModuleClassParams } from '../../types'; +import { + ContentstackClient, + handleAndLogError, + messageHandler, + v2Logger, + sanitizePath, +} from '@contentstack/cli-utilities'; + +import { fsUtil } from '../../utils'; import BaseClass from './base-class'; -import { sanitizePath } from '@contentstack/cli-utilities'; +import { ExportConfig, ModuleClassParams } from '../../types'; export default class LocaleExport extends BaseClass { private stackAPIClient: ReturnType; @@ -41,22 +47,32 @@ export default class LocaleExport extends BaseClass { BASE: this.localeConfig.requiredKeys, }, }; - this.localesPath = path.resolve(sanitizePath(exportConfig.data), sanitizePath(exportConfig.branchName || ''),sanitizePath(this.localeConfig.dirName)); + this.localesPath = path.resolve( + sanitizePath(exportConfig.data), + sanitizePath(exportConfig.branchName || ''), + sanitizePath(this.localeConfig.dirName), + ); this.locales = {}; this.masterLocale = {}; + this.exportConfig.context.module = 'locales'; } async start() { try { - log(this.exportConfig, 'Starting locale export', 'success'); await fsUtil.makeDirectory(this.localesPath); await this.getLocales(); fsUtil.writeFile(path.join(this.localesPath, this.localeConfig.fileName), this.locales); fsUtil.writeFile(path.join(this.localesPath, this.masterLocaleConfig.fileName), this.masterLocale); - log(this.exportConfig, 'Completed locale export', 'success'); + v2Logger.success( + messageHandler.parse( + 'LOCALES_EXPORT_COMPLETE', + Object.keys(this.locales).length, + Object.keys(this.masterLocale).length, + ), + this.exportConfig.context, + ); } catch (error) { - log(this.exportConfig, `Failed to export locales. ${formatError(error)}`, 'error'); - throw new Error('Failed to export locales'); + handleAndLogError(error, { ...this.exportConfig.context }); } } diff --git a/packages/contentstack-export/src/export/modules/marketplace-apps.ts b/packages/contentstack-export/src/export/modules/marketplace-apps.ts index ff34d2400f..64605c344b 100644 --- a/packages/contentstack-export/src/export/modules/marketplace-apps.ts +++ b/packages/contentstack-export/src/export/modules/marketplace-apps.ts @@ -5,17 +5,20 @@ import omitBy from 'lodash/omitBy'; import entries from 'lodash/entries'; import isEmpty from 'lodash/isEmpty'; import { resolve as pResolve } from 'node:path'; +import { Command } from '@contentstack/cli-command'; import { cliux, NodeCrypto, isAuthenticated, marketplaceSDKClient, ContentstackMarketplaceClient, + v2Logger, + messageHandler, + handleAndLogError, } from '@contentstack/cli-utilities'; +import { fsUtil, getOrgUid, createNodeCryptoInstance, getDeveloperHubUrl } from '../../utils'; import { ModuleClassParams, MarketplaceAppsConfig, ExportConfig, Installation, Manifest } from '../../types'; -import { log, fsUtil, getOrgUid, formatError, createNodeCryptoInstance, getDeveloperHubUrl } from '../../utils'; -import { Command } from '@contentstack/cli-command'; export default class ExportMarketplaceApps { protected marketplaceAppConfig: MarketplaceAppsConfig; @@ -30,6 +33,7 @@ export default class ExportMarketplaceApps { constructor({ exportConfig }: Omit) { this.exportConfig = exportConfig; this.marketplaceAppConfig = exportConfig.modules.marketplace_apps; + this.exportConfig.context.module = 'marketplace-apps'; } async start(): Promise { @@ -41,8 +45,6 @@ export default class ExportMarketplaceApps { return Promise.resolve(); } - log(this.exportConfig, 'Starting marketplace app export', 'info'); - this.marketplaceAppPath = pResolve( this.exportConfig.data, this.exportConfig.branchName || '', @@ -85,7 +87,7 @@ export default class ExportMarketplaceApps { */ async getAppManifestAndAppConfig(): Promise { if (isEmpty(this.installedApps)) { - log(this.exportConfig, 'No marketplace apps found', 'info'); + v2Logger.info(messageHandler.parse('MARKETPLACE_APPS_NOT_FOUND'), this.exportConfig.context); } else { for (const [index, app] of entries(this.installedApps)) { if (app.manifest.visibility === 'private') { @@ -99,7 +101,10 @@ export default class ExportMarketplaceApps { fsUtil.writeFile(pResolve(this.marketplaceAppPath, this.marketplaceAppConfig.fileName), this.installedApps); - log(this.exportConfig, 'All the marketplace apps have been exported successfully', 'info'); + v2Logger.success( + messageHandler.parse('MARKETPLACE_APPS_EXPORT_COMPLETE', Object.keys(this.installedApps).length), + this.exportConfig.context, + ); } } @@ -118,7 +123,13 @@ export default class ExportMarketplaceApps { .app(appInstallation.manifest.uid) .fetch({ include_oauth: true }) .catch((error) => { - log(this.exportConfig, error, 'error'); + handleAndLogError( + error, + { + ...this.exportConfig.context, + }, + messageHandler.parse('MARKETPLACE_APP_MANIFEST_EXPORT_FAILED', appInstallation.manifest.name), + ); }); if (manifest) { @@ -140,7 +151,7 @@ export default class ExportMarketplaceApps { const appName = appInstallation?.manifest?.name; const appUid = appInstallation?.manifest?.uid; const app = appName || appUid; - log(this.exportConfig, `Exporting ${app} app and it's config.`, 'info'); + v2Logger.info(messageHandler.parse('MARKETPLACE_APP_CONFIG_EXPORT', app), this.exportConfig.context); await this.appSdk .marketplace(this.exportConfig.org_uid) @@ -160,18 +171,28 @@ export default class ExportMarketplaceApps { if (!isEmpty(data?.server_configuration)) { this.installedApps[index]['server_configuration'] = this.nodeCrypto.encrypt(data.server_configuration); - log(this.exportConfig, `Exported ${app} app and it's config.`, 'success'); + v2Logger.success(messageHandler.parse('MARKETPLACE_APP_CONFIG_SUCCESS', app), this.exportConfig.context); } else { - log(this.exportConfig, `Exported ${app} app`, 'success'); + v2Logger.success(messageHandler.parse('MARKETPLACE_APP_EXPORT_SUCCESS', app), this.exportConfig.context); } } else if (error) { - log(this.exportConfig, `Error on exporting ${app} app and it's config.`, 'error'); - log(this.exportConfig, error, 'error'); + handleAndLogError( + error, + { + ...this.exportConfig.context, + }, + messageHandler.parse('MARKETPLACE_APP_CONFIG_EXPORT_FAILED', app), + ); } }) .catch((error: any) => { - log(this.exportConfig, `Failed to export ${app} app config ${formatError(error)}`, 'error'); - log(this.exportConfig, error, 'error'); + handleAndLogError( + error, + { + ...this.exportConfig.context, + }, + messageHandler.parse('MARKETPLACE_APP_CONFIG_EXPORT_FAILED', app), + ); }); } @@ -188,8 +209,9 @@ export default class ExportMarketplaceApps { .installation() .fetchAll({ target_uids: this.exportConfig.source_stack, skip }) .catch((error) => { - log(this.exportConfig, `Failed to export marketplace-apps ${formatError(error)}`, 'error'); - log(this.exportConfig, error, 'error'); + handleAndLogError(error, { + ...this.exportConfig.context, + }); }); if (collection) { diff --git a/packages/contentstack-export/src/export/modules/personalize.ts b/packages/contentstack-export/src/export/modules/personalize.ts index 6fa5f89b33..913cda7300 100644 --- a/packages/contentstack-export/src/export/modules/personalize.ts +++ b/packages/contentstack-export/src/export/modules/personalize.ts @@ -6,8 +6,8 @@ import { ExportAudiences, AnyProperty, } from '@contentstack/cli-variants'; +import { handleAndLogError, messageHandler, v2Logger } from '@contentstack/cli-utilities'; -import { log } from '../../utils'; import { ModuleClassParams, ExportConfig } from '../../types'; export default class ExportPersonalize { @@ -16,17 +16,18 @@ export default class ExportPersonalize { constructor({ exportConfig }: ModuleClassParams) { this.exportConfig = exportConfig; this.personalizeConfig = exportConfig.modules.personalize; + this.exportConfig.context.module = 'personalize'; } async start(): Promise { try { if (!this.personalizeConfig.baseURL[this.exportConfig.region.name]) { - log(this.exportConfig, 'Skipping Personalize project export, personalize url is not set', 'info'); + v2Logger.info(messageHandler.parse('PERSONALIZE_URL_NOT_SET'), this.exportConfig.context); this.exportConfig.personalizationEnabled = false; return; } if (this.exportConfig.management_token) { - log(this.exportConfig, 'Skipping Personalize project export when using management token', 'info'); + v2Logger.info(messageHandler.parse('PERSONALIZE_SKIPPING_WITH_MANAGEMENT_TOKEN'), this.exportConfig.context); this.exportConfig.personalizationEnabled = false; return; } @@ -46,15 +47,18 @@ export default class ExportPersonalize { if (moduleMapper[module]) { await moduleMapper[module].start(); } else { - log(this.exportConfig, `No implementation found for the module ${module}`, 'info'); + v2Logger.info( + messageHandler.parse('PERSONALIZE_MODULE_NOT_IMPLEMENTED', module), + this.exportConfig.context, + ); } } } } catch (error) { if (error === 'Forbidden') { - log(this.exportConfig, "Personalize is not enabled in the given organization!", 'info'); + v2Logger.info(messageHandler.parse('PERSONALIZE_NOT_ENABLED'), this.exportConfig.context); } else { - log(this.exportConfig, error, 'error'); + handleAndLogError(error, { ...this.exportConfig.context }); } this.exportConfig.personalizationEnabled = false; } diff --git a/packages/contentstack-export/src/export/modules/stack.ts b/packages/contentstack-export/src/export/modules/stack.ts index 59174022b5..7e77873b37 100644 --- a/packages/contentstack-export/src/export/modules/stack.ts +++ b/packages/contentstack-export/src/export/modules/stack.ts @@ -1,9 +1,9 @@ import find from 'lodash/find'; import { resolve as pResolve } from 'node:path'; -import { isAuthenticated, managementSDKClient } from '@contentstack/cli-utilities'; +import { handleAndLogError, isAuthenticated, managementSDKClient, v2Logger } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; -import { log, formatError, fsUtil } from '../../utils'; +import { fsUtil } from '../../utils'; import { StackConfig, ModuleClassParams } from '../../types'; export default class ExportStack extends BaseClass { @@ -19,6 +19,7 @@ export default class ExportStack extends BaseClass { this.stackConfig = exportConfig.modules.stack; this.qs = { include_count: true }; this.stackFolderPath = pResolve(this.exportConfig.data, this.stackConfig.dirName); + this.exportConfig.context.module = 'stack'; } async start(): Promise { @@ -65,7 +66,11 @@ export default class ExportStack extends BaseClass { if (masterLocalObj) { return masterLocalObj; } else if (skip >= count) { - log(this.exportConfig, 'Master locale not found', 'error'); + v2Logger.error( + `Master locale not found in the stack ${this.exportConfig.source_stack}. Please ensure that the stack has a master locale.`, + this.exportConfig.context, + ); + return; } else { return await this.getLocales(skip); @@ -73,23 +78,28 @@ export default class ExportStack extends BaseClass { } }) .catch((error: any) => { - log(this.exportConfig, `Failed to export locales. ${formatError(error)}`, 'error'); - log(this.exportConfig, error, 'error'); + handleAndLogError( + error, + { ...this.exportConfig.context }, + `Failed to fetch locales for stack ${this.exportConfig.source_stack}`, + ); }); } async exportStack(): Promise { - log(this.exportConfig, 'Exporting stack details', 'success'); await fsUtil.makeDirectory(this.stackFolderPath); return this.stack .fetch() .then((resp: any) => { fsUtil.writeFile(pResolve(this.stackFolderPath, this.stackConfig.fileName), resp); - log(this.exportConfig, 'Exported stack details successfully!', 'success'); + v2Logger.success( + `Stack details exported successfully for stack ${this.exportConfig.source_stack}`, + this.exportConfig.context, + ); return resp; }) .catch((error: any) => { - log(this.exportConfig, `Failed to export stack. ${formatError(error)}`, 'error'); + handleAndLogError(error, { ...this.exportConfig.context }); }); } } diff --git a/packages/contentstack-export/src/export/modules/taxonomies.ts b/packages/contentstack-export/src/export/modules/taxonomies.ts index 050357e2dd..7fd48ef185 100644 --- a/packages/contentstack-export/src/export/modules/taxonomies.ts +++ b/packages/contentstack-export/src/export/modules/taxonomies.ts @@ -2,9 +2,10 @@ import omit from 'lodash/omit'; import keys from 'lodash/keys'; import isEmpty from 'lodash/isEmpty'; import { resolve as pResolve } from 'node:path'; +import { handleAndLogError, messageHandler, v2Logger } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; -import { log, fsUtil } from '../../utils'; +import { fsUtil } from '../../utils'; import { ModuleClassParams, ExportConfig } from '../../types'; export default class ExportTaxonomies extends BaseClass { @@ -23,11 +24,10 @@ export default class ExportTaxonomies extends BaseClass { this.taxonomies = {}; this.taxonomiesConfig = exportConfig.modules.taxonomies; this.qs = { include_count: true, limit: this.taxonomiesConfig.limit || 100, skip: 0 }; + this.exportConfig.context.module = 'taxonomies'; } async start(): Promise { - log(this.exportConfig, 'Starting taxonomies export', 'info'); - //create taxonomies folder this.taxonomiesFolderPath = pResolve( this.exportConfig.data, @@ -39,14 +39,16 @@ export default class ExportTaxonomies extends BaseClass { //fetch all taxonomies and write into taxonomies folder await this.getAllTaxonomies(); if (this.taxonomies === undefined || isEmpty(this.taxonomies)) { - log(this.exportConfig, 'No taxonomies found!', 'info'); + v2Logger.info(messageHandler.parse('TAXONOMY_NOT_FOUND'), this.exportConfig.context); return; } else { fsUtil.writeFile(pResolve(this.taxonomiesFolderPath, 'taxonomies.json'), this.taxonomies); await this.exportTaxonomies(); } - - log(this.exportConfig, `All taxonomies exported successfully!`, 'success'); + v2Logger.success( + messageHandler.parse('TAXONOMY_EXPORT_COMPLETE', keys(this.taxonomies).length ), + this.exportConfig.context, + ); } /** @@ -76,7 +78,7 @@ export default class ExportTaxonomies extends BaseClass { } }) .catch((error: any) => { - this.handleErrorMsg(error); + handleAndLogError(error, { ...this.exportConfig.context }); }); } @@ -102,18 +104,14 @@ export default class ExportTaxonomies extends BaseClass { const onSuccess = ({ response, uid }: any) => { const filePath = pResolve(this.taxonomiesFolderPath, `${uid}.json`); fsUtil.writeFile(filePath, response); - log(this.exportConfig, `'${uid}' taxonomy exported successfully!`, 'success'); + v2Logger.success( + messageHandler.parse('TAXONOMY_EXPORT_SUCCESS', uid), + this.exportConfig.context, + ); }; const onReject = ({ error, uid }: any) => { - if (error?.errorMessage) { - log(this.exportConfig, `Failed to export taxonomy - '${uid}'! ${error.errorMessage}`, 'error'); - } else if (error?.message) { - const errorMsg = error?.errors?.taxonomy || error?.errors?.term || error?.message; - log(this.exportConfig, `Failed to export taxonomy - '${uid}'! ${errorMsg}`, 'error'); - } else { - log(this.exportConfig, `Failed to export taxonomy - '${uid}'! ${error}`, 'error'); - } + handleAndLogError(error, { ...this.exportConfig.context, uid }); }; for (let index = 0; index < taxonomiesUID?.length; index++) { @@ -126,15 +124,4 @@ export default class ExportTaxonomies extends BaseClass { }); } } - - handleErrorMsg(err: any) { - if (err?.errorMessage) { - log(this.exportConfig, `Failed to export! ${err.errorMessage}`, 'error'); - } else if (err?.message) { - const errorMsg = err?.errors?.taxonomy || err?.errors?.term || err?.message; - log(this.exportConfig, `Failed to export! ${errorMsg}`, 'error'); - } else { - log(this.exportConfig, `Failed to export! ${err}`, 'error'); - } - } } diff --git a/packages/contentstack-export/src/export/modules/webhooks.ts b/packages/contentstack-export/src/export/modules/webhooks.ts index 0d07b67b36..2b52ca5637 100644 --- a/packages/contentstack-export/src/export/modules/webhooks.ts +++ b/packages/contentstack-export/src/export/modules/webhooks.ts @@ -1,9 +1,10 @@ import omit from 'lodash/omit'; import isEmpty from 'lodash/isEmpty'; import { resolve as pResolve } from 'node:path'; +import { handleAndLogError, messageHandler, v2Logger } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; -import { log, formatError, fsUtil } from '../../utils'; +import { fsUtil } from '../../utils'; import { WebhookConfig, ModuleClassParams } from '../../types'; export default class ExportWebhooks extends BaseClass { @@ -21,11 +22,10 @@ export default class ExportWebhooks extends BaseClass { this.webhooks = {}; this.webhookConfig = exportConfig.modules.webhooks; this.qs = { include_count: true, asc: 'updated_at' }; + this.exportConfig.context.module = 'webhooks'; } async start(): Promise { - log(this.exportConfig, 'Starting webhooks export', 'info'); - this.webhooksFolderPath = pResolve( this.exportConfig.data, this.exportConfig.branchName || '', @@ -35,10 +35,13 @@ export default class ExportWebhooks extends BaseClass { await fsUtil.makeDirectory(this.webhooksFolderPath); await this.getWebhooks(); if (this.webhooks === undefined || isEmpty(this.webhooks)) { - log(this.exportConfig, 'No webhooks found', 'info'); + v2Logger.info(messageHandler.parse('WEBHOOK_NOT_FOUND'), this.exportConfig.context); } else { fsUtil.writeFile(pResolve(this.webhooksFolderPath, this.webhookConfig.fileName), this.webhooks); - log(this.exportConfig, 'All the webhooks have been exported successfully!', 'success'); + v2Logger.success( + messageHandler.parse('WEBHOOK_EXPORT_COMPLETE', Object.keys(this.webhooks).length), + this.exportConfig.context, + ); } } @@ -62,8 +65,7 @@ export default class ExportWebhooks extends BaseClass { } }) .catch((error: any) => { - log(this.exportConfig, `Failed to export webhooks.${formatError(error)}`, 'error'); - log(this.exportConfig, error, 'error'); + handleAndLogError(error, { ...this.exportConfig.context }); }); } @@ -72,7 +74,7 @@ export default class ExportWebhooks extends BaseClass { const webhookUid = webhooks[index].uid; const webhookName = webhooks[index]?.name; this.webhooks[webhookUid] = omit(webhooks[index], ['SYS_ACL']); - log(this.exportConfig, `'${webhookName}' webhook was exported successfully`, 'success'); + v2Logger.success(messageHandler.parse('WEBHOOK_EXPORT_SUCCESS', webhookName), this.exportConfig.context); } } } diff --git a/packages/contentstack-export/src/export/modules/workflows.ts b/packages/contentstack-export/src/export/modules/workflows.ts index d757faa7b1..801815c260 100644 --- a/packages/contentstack-export/src/export/modules/workflows.ts +++ b/packages/contentstack-export/src/export/modules/workflows.ts @@ -1,9 +1,10 @@ import omit from 'lodash/omit'; import isEmpty from 'lodash/isEmpty'; import { resolve as pResolve } from 'node:path'; +import { handleAndLogError, messageHandler, v2Logger } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; -import { log, formatError, fsUtil } from '../../utils'; +import { fsUtil } from '../../utils'; import { WorkflowConfig, ModuleClassParams } from '../../types'; export default class ExportWorkFlows extends BaseClass { @@ -20,11 +21,10 @@ export default class ExportWorkFlows extends BaseClass { this.workflows = {}; this.workflowConfig = exportConfig.modules.workflows; this.qs = { include_count: true }; + this.exportConfig.context.module = 'workflows'; } async start(): Promise { - log(this.exportConfig, 'Starting workflows export', 'info'); - this.webhooksFolderPath = pResolve( this.exportConfig.data, this.exportConfig.branchName || '', @@ -35,10 +35,13 @@ export default class ExportWorkFlows extends BaseClass { await this.getWorkflows(); if (this.workflows === undefined || isEmpty(this.workflows)) { - log(this.exportConfig, 'No workflows found', 'info'); + v2Logger.info(messageHandler.parse('WORKFLOW_NOT_FOUND'), this.exportConfig.context); } else { fsUtil.writeFile(pResolve(this.webhooksFolderPath, this.workflowConfig.fileName), this.workflows); - log(this.exportConfig, 'All the workflows have been exported successfully!', 'success'); + v2Logger.success( + messageHandler.parse('WORKFLOW_EXPORT_COMPLETE', Object.keys(this.workflows).length ), + this.exportConfig.context, + ); } } @@ -64,8 +67,7 @@ export default class ExportWorkFlows extends BaseClass { } }) .catch((error: any) => { - log(this.exportConfig, `Failed to export workflows.${formatError(error)}`, 'error'); - log(this.exportConfig, error, 'error'); + handleAndLogError(error, { ...this.exportConfig.context }); }); } @@ -75,7 +77,10 @@ export default class ExportWorkFlows extends BaseClass { const workflowUid = workflows[index].uid; const workflowName = workflows[index]?.name || ''; this.workflows[workflowUid] = omit(workflows[index], this.workflowConfig.invalidKeys); - log(this.exportConfig, `'${workflowName}' workflow was exported successfully`, 'success'); + v2Logger.success( + messageHandler.parse('WORKFLOW_EXPORT_SUCCESS', workflowName), + this.exportConfig.context, + ); } } @@ -95,7 +100,10 @@ export default class ExportWorkFlows extends BaseClass { .fetch({ include_rules: true, include_permissions: true }) .then((data: any) => data) .catch((err: any) => - log(this.exportConfig, `Failed to fetch roles.${formatError(err)}`, 'error'), + handleAndLogError( + err, + { ...this.exportConfig.context } + ), ); } } diff --git a/packages/contentstack-export/src/types/export-config.ts b/packages/contentstack-export/src/types/export-config.ts index 2b6cb62cf5..c44b1ca1cc 100644 --- a/packages/contentstack-export/src/types/export-config.ts +++ b/packages/contentstack-export/src/types/export-config.ts @@ -1,7 +1,8 @@ -import { Modules, Region } from '.'; +import { Context, Modules, Region } from '.'; import DefaultConfig from './default-config'; export default interface ExportConfig extends DefaultConfig { + context: Context; cliLogsPath: string; exportDir: string; data: string; diff --git a/packages/contentstack-export/src/types/index.ts b/packages/contentstack-export/src/types/index.ts index 12fa2a6a54..b07a27eacd 100644 --- a/packages/contentstack-export/src/types/index.ts +++ b/packages/contentstack-export/src/types/index.ts @@ -129,6 +129,16 @@ export interface StackConfig { dependencies?: Modules[]; limit?: number; } +export interface Context { + command: string; + module: string; + userId: string | undefined; + email: string | undefined; + sessionId: string | undefined; + clientId: string | undefined; + apiKey: string; + orgId: string; +} export { default as DefaultConfig } from './default-config'; export { default as ExportConfig } from './export-config'; diff --git a/packages/contentstack-export/src/utils/basic-login.ts b/packages/contentstack-export/src/utils/basic-login.ts index 87e1cc5932..7f8245d56f 100644 --- a/packages/contentstack-export/src/utils/basic-login.ts +++ b/packages/contentstack-export/src/utils/basic-login.ts @@ -7,15 +7,8 @@ * MIT Licensed */ -import { ExportConfig, ExternalConfig } from '../types'; -import { log } from './logger'; -const { - managementSDKClient, - isAuthenticated, - cliux, - configHandler, - authHandler, -} = require('@contentstack/cli-utilities'); +import { v2Logger, managementSDKClient, authHandler } from '@contentstack/cli-utilities'; +import { ExternalConfig } from '../types'; const login = async (config: ExternalConfig): Promise => { const client = await managementSDKClient(config); @@ -29,22 +22,20 @@ const login = async (config: ExternalConfig): Promise => { 'X-User-Agent': 'contentstack-export/v', }; await authHandler.setConfigData('basicAuth', response.user); - log(config, 'Contentstack account authenticated successfully!', 'success'); + v2Logger.success(`Contentstack account authenticated successfully!`, config.context); return config; } else { - log(config, 'Failed to login, Invalid credentials', 'error'); + v2Logger.error(`Failed to login, Invalid credentials`, config.context); process.exit(1); } } else if (!config.email && !config.password && config.source_stack && config.access_token) { - log( - config, - 'Content types, entries, assets, labels, global fields, extensions modules will be exported', - 'success', + v2Logger.info( + `Content types, entries, assets, labels, global fields, extensions modules will be exported`, + config.context, ); - log( - config, - 'Email, password, or management token is not set in the config, cannot export Webhook and label modules', - 'success', + v2Logger.info( + `Email, password, or management token is not set in the config, cannot export Webhook and label modules`, + config.context, ); config.headers = { api_key: config.source_stack, diff --git a/packages/contentstack-export/src/utils/common-helper.ts b/packages/contentstack-export/src/utils/common-helper.ts index 8084b86106..1e37eb9a36 100644 --- a/packages/contentstack-export/src/utils/common-helper.ts +++ b/packages/contentstack-export/src/utils/common-helper.ts @@ -84,7 +84,7 @@ export const executeTask = function ( export const writeExportMetaFile = (exportConfig: ExportConfig, metaFilePath?: string) => { const exportMeta = { contentVersion: exportConfig.contentVersion, - logsPath: path.join(sanitizePath(exportConfig.exportDir), 'logs', 'export'), + logsPath: path.join(process.cwd(), 'logs'), }; fsUtil.writeFile(path.join(sanitizePath(metaFilePath || exportConfig.exportDir), 'export-info.json'), exportMeta); }; diff --git a/packages/contentstack-export/src/utils/marketplace-app-helper.ts b/packages/contentstack-export/src/utils/marketplace-app-helper.ts index db181744ed..970f355277 100644 --- a/packages/contentstack-export/src/utils/marketplace-app-helper.ts +++ b/packages/contentstack-export/src/utils/marketplace-app-helper.ts @@ -1,6 +1,5 @@ -import { cliux, configHandler, NodeCrypto, managementSDKClient, createDeveloperHubUrl } from '@contentstack/cli-utilities'; +import { cliux, handleAndLogError, NodeCrypto, managementSDKClient, createDeveloperHubUrl } from '@contentstack/cli-utilities'; -import { formatError, log } from '../utils'; import { ExportConfig } from '../types'; export const getDeveloperHubUrl = async (exportConfig: ExportConfig) => { @@ -13,7 +12,7 @@ export async function getOrgUid(config: ExportConfig): Promise { .stack({ api_key: config.source_stack }) .fetch() .catch((error: any) => { - log(config, formatError(error), 'error'); + handleAndLogError(error, {...config.context}); }); return tempStackData?.org_uid; diff --git a/packages/contentstack-export/src/utils/setup-branches.ts b/packages/contentstack-export/src/utils/setup-branches.ts index e7ef011b06..e5097800cc 100644 --- a/packages/contentstack-export/src/utils/setup-branches.ts +++ b/packages/contentstack-export/src/utils/setup-branches.ts @@ -1,9 +1,9 @@ import * as path from 'path'; -import { writeFileSync, makeDirectory } from './file-helper'; -import { isAuthenticated, configHandler } from '@contentstack/cli-utilities'; -import { ExportConfig } from '../types'; import { sanitizePath } from '@contentstack/cli-utilities'; +import { ExportConfig } from '../types'; +import { writeFileSync, makeDirectory } from './file-helper'; + const setupBranches = async (config: ExportConfig, stackAPIClient: any) => { if (typeof config !== 'object') { throw new Error('Invalid config to setup the branch'); diff --git a/packages/contentstack-export/src/utils/setup-export-dir.ts b/packages/contentstack-export/src/utils/setup-export-dir.ts index e36237fd08..76de5b364d 100644 --- a/packages/contentstack-export/src/utils/setup-export-dir.ts +++ b/packages/contentstack-export/src/utils/setup-export-dir.ts @@ -1,7 +1,8 @@ import path from 'path'; +import { sanitizePath } from '@contentstack/cli-utilities'; + import { ExportConfig } from '../types'; import { makeDirectory } from './file-helper'; -import { sanitizePath } from '@contentstack/cli-utilities'; export default async function setupExportDir(exportConfig: ExportConfig) { makeDirectory(exportConfig.exportDir); diff --git a/packages/contentstack-utilities/src/constants/logging.ts b/packages/contentstack-utilities/src/constants/logging.ts index e32d6a0699..8cddfd6284 100644 --- a/packages/contentstack-utilities/src/constants/logging.ts +++ b/packages/contentstack-utilities/src/constants/logging.ts @@ -12,6 +12,6 @@ export const levelColors = { error: 'red', warn: 'yellow', success: 'green', // Custom color for success - info: 'blue', - debug: 'white' + info: 'white', + debug: 'blue' }; \ No newline at end of file diff --git a/packages/contentstack-utilities/src/index.ts b/packages/contentstack-utilities/src/index.ts index 35feed155d..b8d45e25ce 100644 --- a/packages/contentstack-utilities/src/index.ts +++ b/packages/contentstack-utilities/src/index.ts @@ -77,3 +77,4 @@ export { default as TablePrompt } from './inquirer-table-prompt'; export { Logger }; export { default as authenticationHandler } from './authentication-handler'; +export {v2Logger, cliErrorHandler, handleAndLogError} from './logger/log' diff --git a/packages/contentstack-utilities/src/interfaces/index.ts b/packages/contentstack-utilities/src/interfaces/index.ts index 6fa5dfcf25..3162dc2d7f 100644 --- a/packages/contentstack-utilities/src/interfaces/index.ts +++ b/packages/contentstack-utilities/src/interfaces/index.ts @@ -88,7 +88,7 @@ export interface PrintOptions { color?: string; } -export type LogType = 'info' | 'warn' | 'error' | 'debug'; +export type LogType = 'info' | 'warn' | 'error' | 'debug' | 'hidden' | 'success'; export type LogsType = LogType | PrintOptions | undefined; export type MessageType = string | Error | Record | Record[]; @@ -102,9 +102,10 @@ export type ClassifiedError = { meta?: Record; context?: string; hidden?: boolean; + stackTrace?: Record; }; -export type ErrorContext = { +export interface ErrorContextBase { operation?: string; component?: string; userId?: string; @@ -113,5 +114,10 @@ export type ErrorContext = { sessionId?: string; orgId?: string; apiKey?: string; +} + +// This allows both known keys and any custom key like `uid`, `filename`, etc. +export type ErrorContext = ErrorContextBase & { + [key: string]: unknown; }; diff --git a/packages/contentstack-utilities/src/logger/cliErrorHandler.ts b/packages/contentstack-utilities/src/logger/cliErrorHandler.ts index 6efd5134fa..29664f4388 100644 --- a/packages/contentstack-utilities/src/logger/cliErrorHandler.ts +++ b/packages/contentstack-utilities/src/logger/cliErrorHandler.ts @@ -60,7 +60,7 @@ export default class CLIErrorHandler { * @throws This method handles its own errors and will return a `ClassifiedError` with type * `ERROR_TYPES.NORMALIZATION` if it fails to normalize or classify the input error. */ - classifyError(error: unknown, context?: ErrorContext): ClassifiedError { + classifyError(error: unknown, context?: ErrorContext, errMessage?: string): ClassifiedError { try { const normalized = this.normalizeToError(error); const isApi = this.isApiError(normalized); @@ -69,14 +69,14 @@ export default class CLIErrorHandler { const result: ClassifiedError = { type, - message: normalized.message || 'Unhandled error', + message: errMessage || normalized.message || 'Unhandled error', error: this.extractErrorPayload(normalized), context: context ? JSON.stringify(context) : undefined, meta: this.extractMeta(context), hidden, }; - if (isApi || this.isDebug) { + if (this.isDebug) { result.debug = this.extractDebugPayload(normalized, context); } @@ -113,8 +113,9 @@ export default class CLIErrorHandler { } private isApiError(error: Error): boolean { + if ((error as AxiosError).isAxiosError) return true; + return ( - (error as AxiosError).isAxiosError || typeof (error as any).status === 'number' || typeof (error as any).statusText === 'string' || (error as any).request !== undefined @@ -171,10 +172,6 @@ export default class CLIErrorHandler { endpoint, }; - if (this.isDebug) { - payload.stack = error.stack; - } - return payload; } @@ -184,7 +181,7 @@ export default class CLIErrorHandler { const status = error.status || error.response?.status; const statusText = error.statusText || error.response?.statusText; const data = error.data || error.response?.data || error.errors || error.error; - + return { command: context?.operation, module: context?.component, diff --git a/packages/contentstack-utilities/src/logger/log.ts b/packages/contentstack-utilities/src/logger/log.ts index 878629ce34..bf6d00ea81 100644 --- a/packages/contentstack-utilities/src/logger/log.ts +++ b/packages/contentstack-utilities/src/logger/log.ts @@ -22,13 +22,13 @@ const cliErrorHandler = new CLIErrorHandler(true); // Enable debug mode for erro * - If debug information is available, it is logged separately with a more specific * debug type and additional details. */ -function handleAndLogError(error: unknown, context?: ErrorContext): void { - const classified = cliErrorHandler.classifyError(error, context); +function handleAndLogError(error: unknown, context?: ErrorContext, errorMessage?: string): void { + const classified = cliErrorHandler.classifyError(error, context, errorMessage); // Always log the error v2Logger.logError({ type: classified.type, - message: classified.message, + message: errorMessage || classified.message, error: classified.error, context: classified.context, hidden: classified.hidden, @@ -43,7 +43,7 @@ function handleAndLogError(error: unknown, context?: ErrorContext): void { debug: { ...classified.debug, // Ensure stack trace is included if not already there - stackTrace: classified.debug.stackTrace || classified.error.stack, + stackTrace: classified?.debug?.stackTrace || classified.error.stack, }, context: classified.context, meta: classified.meta, diff --git a/packages/contentstack-utilities/src/logger/logger.ts b/packages/contentstack-utilities/src/logger/logger.ts index c63c16352b..634c9e9f80 100644 --- a/packages/contentstack-utilities/src/logger/logger.ts +++ b/packages/contentstack-utilities/src/logger/logger.ts @@ -3,7 +3,7 @@ import { klona } from 'klona/full'; import { normalize } from 'path'; import * as winston from 'winston'; import { LogEntry } from 'winston'; -import { logLevels } from '../constants/logging'; +import { levelColors, logLevels } from '../constants/logging'; import { LoggerConfig, LogLevel, LogType } from '../interfaces/index'; export default class Logger { @@ -24,6 +24,8 @@ export default class Logger { constructor(config: LoggerConfig) { this.config = config; + // Add the custom colors first + winston.addColors(levelColors); this.loggers = { error: this.getLoggerInstance('error'), warn: this.getLoggerInstance('warn'), @@ -58,28 +60,23 @@ export default class Logger { new winston.transports.File({ ...this.loggerOptions, filename: `${filePath}/${level}.log`, - format: winston.format.combine( - winston.format.timestamp(), - winston.format.json() - ), + format: winston.format.combine(winston.format.timestamp(), winston.format.json()), }), new winston.transports.Console({ format: winston.format.combine( winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), winston.format.printf((info) => { const colorizer = winston.format.colorize(); - const levelText = info.level.toUpperCase(); + + // Handle success type specifically + const levelToColorize = info.level; + const levelText = levelToColorize.toUpperCase(); + const timestamp = info.timestamp; const message = info.message; - const meta = info.meta; let fullLine = `[${timestamp}] ${levelText}: ${message}`; - if (meta && (info.level !== 'info' && info.level !== 'success')) { - const redactedMeta = this.isLogEntry(meta) ? JSON.stringify(this.redact(meta)) : JSON.stringify(this.redact(meta)); - fullLine += ` - ${redactedMeta}`; - } - - return colorizer.colorize(info.level, fullLine); + return colorizer.colorize(levelToColorize, fullLine); }), ), }), @@ -88,9 +85,7 @@ export default class Logger { } private isSensitiveKey(keyStr: string): boolean { - return keyStr && typeof keyStr === 'string' - ? this.sensitiveKeys.some((regex) => regex.test(keyStr)) - : false; + return keyStr && typeof keyStr === 'string' ? this.sensitiveKeys.some((regex) => regex.test(keyStr)) : false; } private redactObject(obj: any): void { @@ -131,31 +126,31 @@ export default class Logger { public error(message: string, meta?: any): void { if (this.shouldLog('error', 'console') || this.shouldLog('error', 'file')) { - this.loggers.error.error(message, meta); + this.loggers.error.error(message, { ...meta, level: 'error' }); } } public warn(message: string, meta?: any): void { if (this.shouldLog('warn', 'console') || this.shouldLog('warn', 'file')) { - this.loggers.warn.warn(message, meta); + this.loggers.warn.warn(message, { ...meta, level: 'warn' }); } } public info(message: string, meta?: any): void { if (this.shouldLog('info', 'console') || this.shouldLog('info', 'file')) { - this.loggers.info.info(message, meta); + this.loggers.info.info(message, { ...meta, level: 'info' }); } } public success(message: string, meta?: any): void { - if (this.shouldLog('info', 'console') || this.shouldLog('info', 'file')) { - this.loggers.success.info(message, { ...meta, type: 'success' }); + if (this.shouldLog('success', 'console') || this.shouldLog('success', 'file')) { + this.loggers.success.log('success', message, { ...meta }); } } public debug(message: string, meta?: any): void { if (this.shouldLog('debug', 'console') || this.shouldLog('debug', 'file')) { - this.loggers.debug.debug(message, meta); + this.loggers.debug.debug(message, { ...meta, level: 'debug' }); } } @@ -240,7 +235,7 @@ export default class Logger { meta?: Record; }): void { const logPayload = { - level: logLevels.success, + level: 'success', message: params.message, timestamp: new Date(), meta: { @@ -250,8 +245,8 @@ export default class Logger { ...params.meta, }, }; - if (this.shouldLog('info', 'console') || this.shouldLog('info', 'file')) { - this.loggers.success.info(logPayload); + if (this.shouldLog('success', 'console') || this.shouldLog('success', 'file')) { + this.loggers.success.log(logPayload); } } diff --git a/packages/contentstack-variants/src/export/attributes.ts b/packages/contentstack-variants/src/export/attributes.ts index 033ee3260b..c9879a0963 100644 --- a/packages/contentstack-variants/src/export/attributes.ts +++ b/packages/contentstack-variants/src/export/attributes.ts @@ -1,6 +1,6 @@ import omit from 'lodash/omit'; import { resolve as pResolve } from 'node:path'; -import { sanitizePath } from '@contentstack/cli-utilities'; +import { sanitizePath, v2Logger, handleAndLogError } from '@contentstack/cli-utilities'; import { formatError, fsUtil, PersonalizationAdapter, log } from '../utils'; import { PersonalizeConfig, ExportConfig, AttributesConfig, AttributeStruct } from '../types'; @@ -29,24 +29,26 @@ export default class ExportAttributes extends PersonalizationAdapter { @@ -29,23 +30,25 @@ export default class ExportEvents extends PersonalizationAdapter { async start() { try { - log(this.exportConfig, 'Starting events export', 'info'); + v2Logger.info('Starting events export', this.exportConfig.context); await this.init(); await fsUtil.makeDirectory(this.eventsFolderPath); this.events = (await this.getEvents()) as EventStruct[]; if (!this.events?.length) { - log(this.exportConfig, 'No Events found with the given project!', 'info'); + v2Logger.info('No Events found with the given project!', this.exportConfig.context); return; } else { this.sanitizeAttribs(); fsUtil.writeFile(pResolve(this.eventsFolderPath, this.eventsConfig.fileName), this.events); - log(this.exportConfig, 'All the events have been exported successfully!', 'success'); + v2Logger.success( + `Events exported successfully! Total events: ${this.events.length}`, + this.exportConfig.context, + ); return; } } catch (error) { - log(this.exportConfig, `Failed to export events!`, 'error'); - log(this.config, error, 'error'); + handleAndLogError(error, { ...this.exportConfig.context }); } } diff --git a/packages/contentstack-variants/src/export/experiences.ts b/packages/contentstack-variants/src/export/experiences.ts index fbb8a7eb41..780d9541e6 100644 --- a/packages/contentstack-variants/src/export/experiences.ts +++ b/packages/contentstack-variants/src/export/experiences.ts @@ -1,5 +1,5 @@ import * as path from 'path'; -import { sanitizePath } from '@contentstack/cli-utilities'; +import { sanitizePath, v2Logger, handleAndLogError } from '@contentstack/cli-utilities'; import { PersonalizeConfig, ExportConfig, ExperienceStruct } from '../types'; import { formatError, fsUtil, log, PersonalizationAdapter } from '../utils'; @@ -32,13 +32,13 @@ export default class ExportExperiences extends PersonalizationAdapter = (await this.getExperiences()) || []; if (!experiences || experiences?.length < 1) { - log(this.exportConfig, 'No Experiences found with the give project', 'info'); + v2Logger.info('No Experiences found with the given project!', this.exportConfig.context); return; } fsUtil.writeFile(path.resolve(sanitizePath(this.experiencesFolderPath), 'experiences.json'), experiences); @@ -62,10 +62,17 @@ export default class ExportExperiences extends PersonalizationAdapter async start() { try { - log(this.exportConfig, 'Starting projects export', 'info'); + v2Logger.info(`Starting projects export`, this.exportConfig.context); await this.init(); await fsUtil.makeDirectory(this.projectFolderPath); const project = await this.projects({ connectedStackApiKey: this.exportConfig.apiKey }); if (!project || project?.length < 1) { - log(this.exportConfig, 'No Personalize Project connected with the given stack', 'info'); + v2Logger.info(`No Personalize Project connected with the given stack`, this.exportConfig.context); this.exportConfig.personalizationEnabled = false; return; } this.exportConfig.personalizationEnabled = true; this.exportConfig.project_id = project[0]?.uid; fsUtil.writeFile(path.resolve(sanitizePath(this.projectFolderPath), 'projects.json'), project); - log(this.exportConfig, 'Project exported successfully!', 'success'); + v2Logger.success(`Projects exported successfully!`, this.exportConfig.context); } catch (error) { if (error !== 'Forbidden') { - log(this.exportConfig, `Failed to export projects!`, 'error'); + v2Logger.error('Failed to export projects!', this.exportConfig.context); } throw error; } diff --git a/packages/contentstack-variants/src/export/variant-entries.ts b/packages/contentstack-variants/src/export/variant-entries.ts index fd1c11a606..bb322a7a51 100644 --- a/packages/contentstack-variants/src/export/variant-entries.ts +++ b/packages/contentstack-variants/src/export/variant-entries.ts @@ -1,6 +1,6 @@ import { existsSync, mkdirSync } from 'fs'; import { join, resolve } from 'path'; -import { FsUtility, sanitizePath } from '@contentstack/cli-utilities'; +import { FsUtility, sanitizePath, v2Logger, handleAndLogError } from '@contentstack/cli-utilities'; import { APIConfig, AdapterType, ExportConfig, LogType } from '../types'; import VariantAdapter, { VariantHttpClient } from '../utils/variant-api-adapter'; @@ -24,7 +24,11 @@ export default class VariantEntries extends VariantAdapter Date: Fri, 6 Jun 2025 09:59:02 +0530 Subject: [PATCH 02/68] updated talismanrc & handled message in custom role --- .talismanrc | 10 ++++++++++ packages/contentstack-export/messages/index.json | 3 ++- .../src/export/modules/custom-roles.ts | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.talismanrc b/.talismanrc index de36ff0095..193b187bfc 100644 --- a/.talismanrc +++ b/.talismanrc @@ -134,4 +134,14 @@ fileignoreconfig: checksum: 023cf08f215cd0778599fb8478c94419373d4687f04421c4eb99d87de86a4a3e - filename: packages/contentstack-utilities/src/logger/logger.ts checksum: 09f3b73dd995bafc253265c676f06308513e6b1842d9bc01d39e6b6945a54c7d + - filename: packages/contentstack-export/src/export/modules/environments.ts + checksum: 71dd1965e4ba66cefca578838cba125da0c8e4ef02fd95276b8236f66c018dce + - filename: packages/contentstack-export/src/utils/basic-login.ts + checksum: f95d4c0976729bd17238bf64713b3851d8852dbf60591210412c12ddaddd60c9 + - filename: packages/contentstack-utilities/src/interfaces/index.ts + checksum: 70079d81524ae4c196ffc77f13306184a8944b2903b881947dd06120150f31b0 + - filename: packages/contentstack-export/src/commands/cm/stacks/export.ts + checksum: d826ec9fd7729ffcfd0f42399dad7560a8a881cabfdd95693511f5e6b1cb07c7 + - filename: packages/contentstack-utilities/src/logger/logger.ts + checksum: b56504c1e4fb31b676cc1931eb30afc7b9466f03890fe3c76977309e1fd066a6 version: "1.0" diff --git a/packages/contentstack-export/messages/index.json b/packages/contentstack-export/messages/index.json index 9c147dbd05..b2bb7eb664 100644 --- a/packages/contentstack-export/messages/index.json +++ b/packages/contentstack-export/messages/index.json @@ -64,5 +64,6 @@ "BRANCH_EXPORT_FAILED": "Failed to export contents from branch (UID: %s)", -"ROLES_NO_CUSTOM_ROLES": "No custom roles found in the current stack" +"ROLES_NO_CUSTOM_ROLES": "No custom roles found in the current stack", +"ROLES_EXPORTING_ROLE": "Exporting role '%s'" } diff --git a/packages/contentstack-export/src/export/modules/custom-roles.ts b/packages/contentstack-export/src/export/modules/custom-roles.ts index a77b17aad7..3360113dd7 100644 --- a/packages/contentstack-export/src/export/modules/custom-roles.ts +++ b/packages/contentstack-export/src/export/modules/custom-roles.ts @@ -56,7 +56,7 @@ export default class ExportCustomRoles extends BaseClass { } customRoles.forEach((role: any) => { - v2Logger.info(`Exporting role: ${role.name}`, this.exportConfig.context); + v2Logger.info(messageHandler.parse('ROLES_EXPORTING_ROLE', role.name), this.exportConfig.context); this.customRoles[role.uid] = role; }); fsUtil.writeFile(pResolve(this.rolesFolderPath, this.customRolesConfig.fileName), this.customRoles); From c21674bc3db0198b246fd3a95d06d71cb12d9f0d Mon Sep 17 00:00:00 2001 From: Aman Kumar Date: Fri, 6 Jun 2025 10:39:51 +0530 Subject: [PATCH 03/68] added getLogPath method & code clean up --- packages/contentstack-audit/README.md | 16 ++++++++-------- .../src/commands/cm/stacks/export.ts | 15 ++++++++------- .../src/export/modules/assets.ts | 2 +- .../src/utils/common-helper.ts | 10 +++++----- packages/contentstack-utilities/src/index.ts | 2 +- .../contentstack-utilities/src/logger/log.ts | 9 +++++++-- .../src/export/attributes.ts | 2 +- .../src/export/audiences.ts | 2 +- .../src/export/experiences.ts | 2 +- .../contentstack-variants/src/export/projects.ts | 4 ++-- .../src/export/variant-entries.ts | 3 +-- packages/contentstack/README.md | 14 +++++++------- 12 files changed, 43 insertions(+), 38 deletions(-) diff --git a/packages/contentstack-audit/README.md b/packages/contentstack-audit/README.md index 9248cf79c9..0daf3d7f02 100644 --- a/packages/contentstack-audit/README.md +++ b/packages/contentstack-audit/README.md @@ -19,7 +19,7 @@ $ npm install -g @contentstack/cli-audit $ csdx COMMAND running command... $ csdx (--version|-v) -@contentstack/cli-audit/1.12.2 darwin-arm64 node-v22.14.0 +@contentstack/cli-audit/1.13.0 darwin-arm64 node-v22.14.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND @@ -305,7 +305,7 @@ EXAMPLES $ csdx plugins ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.38/src/commands/plugins/index.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.39/src/commands/plugins/index.ts)_ ## `csdx plugins:add PLUGIN` @@ -379,7 +379,7 @@ EXAMPLES $ csdx plugins:inspect myplugin ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.38/src/commands/plugins/inspect.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.39/src/commands/plugins/inspect.ts)_ ## `csdx plugins:install PLUGIN` @@ -428,7 +428,7 @@ EXAMPLES $ csdx plugins:install someuser/someplugin ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.38/src/commands/plugins/install.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.39/src/commands/plugins/install.ts)_ ## `csdx plugins:link PATH` @@ -459,7 +459,7 @@ EXAMPLES $ csdx plugins:link myplugin ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.38/src/commands/plugins/link.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.39/src/commands/plugins/link.ts)_ ## `csdx plugins:remove [PLUGIN]` @@ -500,7 +500,7 @@ FLAGS --reinstall Reinstall all plugins after uninstalling. ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.38/src/commands/plugins/reset.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.39/src/commands/plugins/reset.ts)_ ## `csdx plugins:uninstall [PLUGIN]` @@ -528,7 +528,7 @@ EXAMPLES $ csdx plugins:uninstall myplugin ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.38/src/commands/plugins/uninstall.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.39/src/commands/plugins/uninstall.ts)_ ## `csdx plugins:unlink [PLUGIN]` @@ -572,5 +572,5 @@ DESCRIPTION Update installed plugins. ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.38/src/commands/plugins/update.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.39/src/commands/plugins/update.ts)_ diff --git a/packages/contentstack-export/src/commands/cm/stacks/export.ts b/packages/contentstack-export/src/commands/cm/stacks/export.ts index 88c3f012f0..0fd40cc683 100644 --- a/packages/contentstack-export/src/commands/cm/stacks/export.ts +++ b/packages/contentstack-export/src/commands/cm/stacks/export.ts @@ -1,4 +1,3 @@ -import path from 'path'; import { Command } from '@contentstack/cli-command'; import { cliux, @@ -12,11 +11,13 @@ import { sanitizePath, configHandler, v2Logger, - handleAndLogError + handleAndLogError, + getLogPath } from '@contentstack/cli-utilities'; + import { ModuleExporter } from '../../../export'; -import { setupExportConfig, writeExportMetaFile } from '../../../utils'; import { Context, ExportConfig } from '../../../types'; +import { setupExportConfig, writeExportMetaFile } from '../../../utils'; export default class ExportCommand extends Command { static description: string = messageHandler.parse('Export content from a stack'); @@ -112,7 +113,7 @@ export default class ExportCommand extends Command { const { flags } = await this.parse(ExportCommand); exportConfig = await setupExportConfig(flags); // Prepare the context object - const context = this.createExportContext(); + const context = this.createExportContext(exportConfig.apiKey); exportConfig.context = context; // Assign exportConfig variables @@ -126,14 +127,14 @@ export default class ExportCommand extends Command { writeExportMetaFile(exportConfig); } v2Logger.success(`The content of the stack ${exportConfig.apiKey} has been exported successfully!`,exportConfig.context) - v2Logger.success(`The log has been stored at '${pathValidator(path.join(process.cwd(), 'logs'))}'`, exportConfig.context) + v2Logger.info(`The log has been stored at '${getLogPath()}'`, exportConfig.context) } catch (error) { handleAndLogError(error, { ...exportConfig.context }); } } // Create export context object - private createExportContext(): Context { + private createExportContext(apiKey: string): Context { return { command: this.context.info.command, module: '', @@ -141,7 +142,7 @@ export default class ExportCommand extends Command { email: configHandler.get('email'), sessionId: this.context.sessionId, clientId: this.context.clientId, - apiKey: configHandler.get('apiKey') || '', + apiKey: apiKey || '', orgId: configHandler.get('organization_uid') || '', }; } diff --git a/packages/contentstack-export/src/export/modules/assets.ts b/packages/contentstack-export/src/export/modules/assets.ts index 575d3ca619..716f27994e 100644 --- a/packages/contentstack-export/src/export/modules/assets.ts +++ b/packages/contentstack-export/src/export/modules/assets.ts @@ -20,8 +20,8 @@ import { messageHandler, } from '@contentstack/cli-utilities'; -import { ModuleClassParams } from '../../types'; import config from '../../config'; +import { ModuleClassParams } from '../../types'; import BaseClass, { CustomPromiseHandler, CustomPromiseHandlerInput } from './base-class'; export default class ExportAssets extends BaseClass { diff --git a/packages/contentstack-export/src/utils/common-helper.ts b/packages/contentstack-export/src/utils/common-helper.ts index 1e37eb9a36..0ece3d4205 100644 --- a/packages/contentstack-export/src/utils/common-helper.ts +++ b/packages/contentstack-export/src/utils/common-helper.ts @@ -4,12 +4,12 @@ * MIT Licensed */ -import promiseLimit from 'promise-limit'; import * as path from 'path'; -import { isAuthenticated } from '@contentstack/cli-utilities'; -import { ExternalConfig, ExportConfig } from '../types'; +import promiseLimit from 'promise-limit'; +import { isAuthenticated, getLogPath, sanitizePath } from '@contentstack/cli-utilities'; + import { fsUtil } from './file-helper'; -import { sanitizePath } from '@contentstack/cli-utilities'; +import { ExternalConfig, ExportConfig } from '../types'; export const validateConfig = function (config: ExternalConfig) { if (!config.host || !config.cdn) { @@ -84,7 +84,7 @@ export const executeTask = function ( export const writeExportMetaFile = (exportConfig: ExportConfig, metaFilePath?: string) => { const exportMeta = { contentVersion: exportConfig.contentVersion, - logsPath: path.join(process.cwd(), 'logs'), + logsPath: getLogPath(), }; fsUtil.writeFile(path.join(sanitizePath(metaFilePath || exportConfig.exportDir), 'export-info.json'), exportMeta); }; diff --git a/packages/contentstack-utilities/src/index.ts b/packages/contentstack-utilities/src/index.ts index b8d45e25ce..2be5817d33 100644 --- a/packages/contentstack-utilities/src/index.ts +++ b/packages/contentstack-utilities/src/index.ts @@ -77,4 +77,4 @@ export { default as TablePrompt } from './inquirer-table-prompt'; export { Logger }; export { default as authenticationHandler } from './authentication-handler'; -export {v2Logger, cliErrorHandler, handleAndLogError} from './logger/log' +export {v2Logger, cliErrorHandler, handleAndLogError, getLogPath} from './logger/log' diff --git a/packages/contentstack-utilities/src/logger/log.ts b/packages/contentstack-utilities/src/logger/log.ts index bf6d00ea81..c7cea37cd7 100644 --- a/packages/contentstack-utilities/src/logger/log.ts +++ b/packages/contentstack-utilities/src/logger/log.ts @@ -3,7 +3,7 @@ import { default as Logger } from './logger'; import { CLIErrorHandler } from './cliErrorHandler'; import { ErrorContext } from '../interfaces'; -const v2Logger = new Logger({ basePath: process.env.CS_CLI_LOG_PATH || path.join(process.cwd(), 'logs') }); +const v2Logger = new Logger({ basePath: getLogPath() }); const cliErrorHandler = new CLIErrorHandler(true); // Enable debug mode for error classification /** @@ -51,4 +51,9 @@ function handleAndLogError(error: unknown, context?: ErrorContext, errorMessage? } } -export { v2Logger, cliErrorHandler, handleAndLogError }; +function getLogPath(): string { + return process.env.CS_CLI_LOG_PATH || path.join(process.cwd(), 'logs'); +} + + +export { v2Logger, cliErrorHandler, handleAndLogError, getLogPath }; diff --git a/packages/contentstack-variants/src/export/attributes.ts b/packages/contentstack-variants/src/export/attributes.ts index c9879a0963..35b089daa7 100644 --- a/packages/contentstack-variants/src/export/attributes.ts +++ b/packages/contentstack-variants/src/export/attributes.ts @@ -1,7 +1,7 @@ import omit from 'lodash/omit'; import { resolve as pResolve } from 'node:path'; import { sanitizePath, v2Logger, handleAndLogError } from '@contentstack/cli-utilities'; -import { formatError, fsUtil, PersonalizationAdapter, log } from '../utils'; +import { formatError, fsUtil, PersonalizationAdapter } from '../utils'; import { PersonalizeConfig, ExportConfig, AttributesConfig, AttributeStruct } from '../types'; export default class ExportAttributes extends PersonalizationAdapter { diff --git a/packages/contentstack-variants/src/export/audiences.ts b/packages/contentstack-variants/src/export/audiences.ts index c2863d4a03..30e19b378d 100644 --- a/packages/contentstack-variants/src/export/audiences.ts +++ b/packages/contentstack-variants/src/export/audiences.ts @@ -2,7 +2,7 @@ import omit from 'lodash/omit'; import { resolve as pResolve } from 'node:path'; import { v2Logger, handleAndLogError } from '@contentstack/cli-utilities'; -import { formatError, fsUtil, PersonalizationAdapter, log } from '../utils'; +import { fsUtil, PersonalizationAdapter } from '../utils'; import { PersonalizeConfig, ExportConfig, AudienceStruct, AudiencesConfig } from '../types'; export default class ExportAudiences extends PersonalizationAdapter { diff --git a/packages/contentstack-variants/src/export/experiences.ts b/packages/contentstack-variants/src/export/experiences.ts index 780d9541e6..19f5648231 100644 --- a/packages/contentstack-variants/src/export/experiences.ts +++ b/packages/contentstack-variants/src/export/experiences.ts @@ -1,7 +1,7 @@ import * as path from 'path'; import { sanitizePath, v2Logger, handleAndLogError } from '@contentstack/cli-utilities'; import { PersonalizeConfig, ExportConfig, ExperienceStruct } from '../types'; -import { formatError, fsUtil, log, PersonalizationAdapter } from '../utils'; +import { fsUtil, PersonalizationAdapter } from '../utils'; export default class ExportExperiences extends PersonalizationAdapter { private experiencesFolderPath: string; diff --git a/packages/contentstack-variants/src/export/projects.ts b/packages/contentstack-variants/src/export/projects.ts index 7824ced4e7..8f9a4df27d 100644 --- a/packages/contentstack-variants/src/export/projects.ts +++ b/packages/contentstack-variants/src/export/projects.ts @@ -1,7 +1,7 @@ import * as path from 'path'; -import { sanitizePath, v2Logger, handleAndLogError } from '@contentstack/cli-utilities'; +import { sanitizePath, v2Logger } from '@contentstack/cli-utilities'; import { ExportConfig, PersonalizeConfig } from '../types'; -import { PersonalizationAdapter, log, fsUtil, formatError } from '../utils'; +import { PersonalizationAdapter, fsUtil, } from '../utils'; export default class ExportProjects extends PersonalizationAdapter { private projectFolderPath: string; diff --git a/packages/contentstack-variants/src/export/variant-entries.ts b/packages/contentstack-variants/src/export/variant-entries.ts index bb322a7a51..5c19b20bc7 100644 --- a/packages/contentstack-variants/src/export/variant-entries.ts +++ b/packages/contentstack-variants/src/export/variant-entries.ts @@ -2,9 +2,8 @@ import { existsSync, mkdirSync } from 'fs'; import { join, resolve } from 'path'; import { FsUtility, sanitizePath, v2Logger, handleAndLogError } from '@contentstack/cli-utilities'; -import { APIConfig, AdapterType, ExportConfig, LogType } from '../types'; +import { APIConfig, AdapterType, ExportConfig } from '../types'; import VariantAdapter, { VariantHttpClient } from '../utils/variant-api-adapter'; -import { fsUtil, log } from '../utils'; export default class VariantEntries extends VariantAdapter> { public entriesDirPath: string; diff --git a/packages/contentstack/README.md b/packages/contentstack/README.md index a660ab1932..9f52be2a79 100644 --- a/packages/contentstack/README.md +++ b/packages/contentstack/README.md @@ -3953,7 +3953,7 @@ EXAMPLES $ csdx plugins ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.38/src/commands/plugins/index.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.39/src/commands/plugins/index.ts)_ ## `csdx plugins:add PLUGIN` @@ -4027,7 +4027,7 @@ EXAMPLES $ csdx plugins:inspect myplugin ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.38/src/commands/plugins/inspect.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.39/src/commands/plugins/inspect.ts)_ ## `csdx plugins:install PLUGIN` @@ -4076,7 +4076,7 @@ EXAMPLES $ csdx plugins:install someuser/someplugin ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.38/src/commands/plugins/install.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.39/src/commands/plugins/install.ts)_ ## `csdx plugins:link PATH` @@ -4107,7 +4107,7 @@ EXAMPLES $ csdx plugins:link myplugin ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.38/src/commands/plugins/link.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.39/src/commands/plugins/link.ts)_ ## `csdx plugins:remove [PLUGIN]` @@ -4148,7 +4148,7 @@ FLAGS --reinstall Reinstall all plugins after uninstalling. ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.38/src/commands/plugins/reset.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.39/src/commands/plugins/reset.ts)_ ## `csdx plugins:uninstall [PLUGIN]` @@ -4176,7 +4176,7 @@ EXAMPLES $ csdx plugins:uninstall myplugin ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.38/src/commands/plugins/uninstall.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.39/src/commands/plugins/uninstall.ts)_ ## `csdx plugins:unlink [PLUGIN]` @@ -4220,7 +4220,7 @@ DESCRIPTION Update installed plugins. ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.38/src/commands/plugins/update.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.39/src/commands/plugins/update.ts)_ ## `csdx tokens` From ec836fa728e979d1aa83c5b01558c1fb68b46b20 Mon Sep 17 00:00:00 2001 From: Aman Kumar Date: Fri, 6 Jun 2025 10:42:03 +0530 Subject: [PATCH 04/68] updated talismanrc --- .talismanrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.talismanrc b/.talismanrc index 193b187bfc..3111c5a42a 100644 --- a/.talismanrc +++ b/.talismanrc @@ -141,7 +141,7 @@ fileignoreconfig: - filename: packages/contentstack-utilities/src/interfaces/index.ts checksum: 70079d81524ae4c196ffc77f13306184a8944b2903b881947dd06120150f31b0 - filename: packages/contentstack-export/src/commands/cm/stacks/export.ts - checksum: d826ec9fd7729ffcfd0f42399dad7560a8a881cabfdd95693511f5e6b1cb07c7 + checksum: 4ea47b064ec18532da5fa7e5df47ad173fb7e878eb7899c934d4e1cdf1192956 - filename: packages/contentstack-utilities/src/logger/logger.ts checksum: b56504c1e4fb31b676cc1931eb30afc7b9466f03890fe3c76977309e1fd066a6 version: "1.0" From c4781ffd2e2a3a390dcd81e3d1629721e11b3536 Mon Sep 17 00:00:00 2001 From: Aman Kumar Date: Fri, 6 Jun 2025 11:04:39 +0530 Subject: [PATCH 05/68] refactor: logger & cliErrorHanlder --- .../src/logger/cliErrorHandler.ts | 2 +- packages/contentstack-utilities/src/logger/logger.ts | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/contentstack-utilities/src/logger/cliErrorHandler.ts b/packages/contentstack-utilities/src/logger/cliErrorHandler.ts index 29664f4388..59ef7fef0a 100644 --- a/packages/contentstack-utilities/src/logger/cliErrorHandler.ts +++ b/packages/contentstack-utilities/src/logger/cliErrorHandler.ts @@ -76,7 +76,7 @@ export default class CLIErrorHandler { hidden, }; - if (this.isDebug) { + if (isApi || this.isDebug) { result.debug = this.extractDebugPayload(normalized, context); } diff --git a/packages/contentstack-utilities/src/logger/logger.ts b/packages/contentstack-utilities/src/logger/logger.ts index 634c9e9f80..e413c8f4d7 100644 --- a/packages/contentstack-utilities/src/logger/logger.ts +++ b/packages/contentstack-utilities/src/logger/logger.ts @@ -66,14 +66,15 @@ export default class Logger { format: winston.format.combine( winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), winston.format.printf((info) => { + const redactedInfo = this.redact(info); // Apply redaction here const colorizer = winston.format.colorize(); // Handle success type specifically - const levelToColorize = info.level; + const levelToColorize = redactedInfo.level; const levelText = levelToColorize.toUpperCase(); - const timestamp = info.timestamp; - const message = info.message; + const timestamp = redactedInfo.timestamp; + const message = redactedInfo.message; let fullLine = `[${timestamp}] ${levelText}: ${message}`; return colorizer.colorize(levelToColorize, fullLine); @@ -111,10 +112,6 @@ export default class Logger { } } - private isLogEntry(obj: any): obj is LogEntry { - return typeof obj === 'object' && 'level' in obj && 'message' in obj; - } - private shouldLog(level: LogType, target: 'console' | 'file'): boolean { const configLevel = target === 'console' ? this.config.consoleLogLevel : this.config.logLevel; const minLevel = configLevel ? logLevels[configLevel] : 2; // default: info From a47c2010b0297e8addb188824c848db787f4e3cc Mon Sep 17 00:00:00 2001 From: Aman Kumar Date: Fri, 6 Jun 2025 16:01:37 +0530 Subject: [PATCH 06/68] refactor: exported v2Logger as log to improve clarity --- .../src/commands/cm/stacks/export.ts | 6 +++--- .../src/export/module-exporter.ts | 12 ++++++------ .../src/export/modules/assets.ts | 14 +++++++------- .../src/export/modules/base-class.ts | 4 ++-- .../src/export/modules/content-types.ts | 6 +++--- .../src/export/modules/custom-roles.ts | 6 +++--- .../src/export/modules/entries.ts | 10 +++++----- .../src/export/modules/environments.ts | 8 ++++---- .../src/export/modules/extensions.ts | 8 ++++---- .../src/export/modules/global-fields.ts | 4 ++-- .../src/export/modules/labels.ts | 8 ++++---- .../src/export/modules/locales.ts | 4 ++-- .../src/export/modules/marketplace-apps.ts | 12 ++++++------ .../src/export/modules/personalize.ts | 10 +++++----- .../src/export/modules/stack.ts | 6 +++--- .../src/export/modules/taxonomies.ts | 8 ++++---- .../src/export/modules/webhooks.ts | 8 ++++---- .../src/export/modules/workflows.ts | 8 ++++---- .../contentstack-export/src/utils/basic-login.ts | 10 +++++----- packages/contentstack-utilities/src/index.ts | 2 +- .../contentstack-variants/src/export/attributes.ts | 8 ++++---- .../contentstack-variants/src/export/audiences.ts | 8 ++++---- .../contentstack-variants/src/export/events.ts | 8 ++++---- .../src/export/experiences.ts | 10 +++++----- .../contentstack-variants/src/export/projects.ts | 10 +++++----- .../src/export/variant-entries.ts | 4 ++-- 26 files changed, 101 insertions(+), 101 deletions(-) diff --git a/packages/contentstack-export/src/commands/cm/stacks/export.ts b/packages/contentstack-export/src/commands/cm/stacks/export.ts index 0fd40cc683..fe07d809ec 100644 --- a/packages/contentstack-export/src/commands/cm/stacks/export.ts +++ b/packages/contentstack-export/src/commands/cm/stacks/export.ts @@ -10,7 +10,7 @@ import { pathValidator, sanitizePath, configHandler, - v2Logger, + log, handleAndLogError, getLogPath } from '@contentstack/cli-utilities'; @@ -126,8 +126,8 @@ export default class ExportCommand extends Command { if (!exportConfig.branches?.length) { writeExportMetaFile(exportConfig); } - v2Logger.success(`The content of the stack ${exportConfig.apiKey} has been exported successfully!`,exportConfig.context) - v2Logger.info(`The log has been stored at '${getLogPath()}'`, exportConfig.context) + log.success(`The content of the stack ${exportConfig.apiKey} has been exported successfully!`,exportConfig.context) + log.success(`The log has been stored at '${getLogPath()}'`, exportConfig.context) } catch (error) { handleAndLogError(error, { ...exportConfig.context }); } diff --git a/packages/contentstack-export/src/export/module-exporter.ts b/packages/contentstack-export/src/export/module-exporter.ts index a90f53c9c9..ada028250d 100644 --- a/packages/contentstack-export/src/export/module-exporter.ts +++ b/packages/contentstack-export/src/export/module-exporter.ts @@ -1,6 +1,6 @@ import * as path from 'path'; -import { ContentstackClient, handleAndLogError, messageHandler, v2Logger } from '@contentstack/cli-utilities'; -import { setupBranches, setupExportDir, log, formatError, writeExportMetaFile } from '../utils'; +import { ContentstackClient, handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; +import { setupBranches, setupExportDir, writeExportMetaFile } from '../utils'; import startModuleExport from './modules'; import startJSModuleExport from './modules-js'; import { ExportConfig, Modules } from '../types'; @@ -38,10 +38,10 @@ class ModuleExporter { this.exportConfig.branchName = branch.uid; this.stackAPIClient.stackHeaders.branch = branch.uid; this.exportConfig.branchDir = path.join(this.exportConfig.exportDir, branch.uid); - v2Logger.info(`Exporting content from branch ${branch.uid}`, this.exportConfig.context); + log.info(`Exporting content from branch ${branch.uid}`, this.exportConfig.context); writeExportMetaFile(this.exportConfig, this.exportConfig.branchDir); await this.export(); - v2Logger.success( + log.success( `The content of branch ${branch.uid} has been exported successfully!`, this.exportConfig.context, ); @@ -57,7 +57,7 @@ class ModuleExporter { } async export() { - v2Logger.info( + log.info( `Started to export content, version is ${this.exportConfig.contentVersion}`, this.exportConfig.context, ); @@ -69,7 +69,7 @@ class ModuleExporter { } async exportByModuleByName(moduleName: Modules) { - v2Logger.info(`Exporting module: ${moduleName}`, this.exportConfig.context); + log.info(`Exporting module: ${moduleName}`, this.exportConfig.context); // export the modules by name // calls the module runner which inturn calls the module itself let exportedModuleResponse; diff --git a/packages/contentstack-export/src/export/modules/assets.ts b/packages/contentstack-export/src/export/modules/assets.ts index 716f27994e..76977ca891 100644 --- a/packages/contentstack-export/src/export/modules/assets.ts +++ b/packages/contentstack-export/src/export/modules/assets.ts @@ -15,7 +15,7 @@ import { FsUtility, getDirectories, configHandler, - v2Logger, + log, handleAndLogError, messageHandler, } from '@contentstack/cli-utilities'; @@ -63,7 +63,7 @@ export default class ExportAssets extends BaseClass { // NOTE step 4: Download all assets await this.downloadAssets(); - v2Logger.success(messageHandler.parse('ASSET_EXPORT_COMPLETE'), this.exportConfig.context); + log.success(messageHandler.parse('ASSET_EXPORT_COMPLETE'), this.exportConfig.context); } /** @@ -103,7 +103,7 @@ export default class ExportAssets extends BaseClass { this.assetsFolder, ); } - v2Logger.info( + log.info( messageHandler.parse('ASSET_FOLDERS_EXPORT_COMPLETE', this.assetsFolder.length), this.exportConfig.context, ); @@ -170,7 +170,7 @@ export default class ExportAssets extends BaseClass { concurrencyLimit: this.assetConfig.fetchConcurrency, }).then(() => { fs?.completeFile(true); - v2Logger.info(messageHandler.parse('ASSET_METADATA_EXPORT_COMPLETE'), this.exportConfig.context); + log.info(messageHandler.parse('ASSET_METADATA_EXPORT_COMPLETE'), this.exportConfig.context); }); } @@ -247,7 +247,7 @@ export default class ExportAssets extends BaseClass { promisifyHandler, ).then(() => { fs?.completeFile(true); - v2Logger.info(messageHandler.parse('ASSET_VERSIONED_METADATA_EXPORT_COMPLETE'), this.exportConfig.context); + log.info(messageHandler.parse('ASSET_VERSIONED_METADATA_EXPORT_COMPLETE'), this.exportConfig.context); }); } @@ -338,7 +338,7 @@ export default class ExportAssets extends BaseClass { data.pipe(assetWriterStream); } - v2Logger.success( + log.success( messageHandler.parse('ASSET_DOWNLOAD_SUCCESS', asset.filename, asset.uid), this.exportConfig.context, ); @@ -378,7 +378,7 @@ export default class ExportAssets extends BaseClass { }, promisifyHandler, ).then(() => { - v2Logger.success(messageHandler.parse('ASSET_DOWNLOAD_COMPLETE'), this.exportConfig.context); + log.success(messageHandler.parse('ASSET_DOWNLOAD_COMPLETE'), this.exportConfig.context); }); } } diff --git a/packages/contentstack-export/src/export/modules/base-class.ts b/packages/contentstack-export/src/export/modules/base-class.ts index 6e91a455d7..fea62e19bf 100644 --- a/packages/contentstack-export/src/export/modules/base-class.ts +++ b/packages/contentstack-export/src/export/modules/base-class.ts @@ -5,7 +5,7 @@ import chunk from 'lodash/chunk'; import isEmpty from 'lodash/isEmpty'; import entries from 'lodash/entries'; import isEqual from 'lodash/isEqual'; -import { v2Logger } from '@contentstack/cli-utilities'; +import { log } from '@contentstack/cli-utilities'; import { ExportConfig, ModuleClassParams } from '../../types'; @@ -134,7 +134,7 @@ export default abstract class BaseClass { async logMsgAndWaitIfRequired(module: string, start: number, batchNo: number): Promise { const end = Date.now(); const exeTime = end - start; - v2Logger.success( + log.success( `Batch No. ${batchNo} of ${module} is complete. Time taken: ${exeTime} milliseconds`, this.exportConfig.context, ); diff --git a/packages/contentstack-export/src/export/modules/content-types.ts b/packages/contentstack-export/src/export/modules/content-types.ts index 0488044fcc..97f8126832 100644 --- a/packages/contentstack-export/src/export/modules/content-types.ts +++ b/packages/contentstack-export/src/export/modules/content-types.ts @@ -3,7 +3,7 @@ import { ContentstackClient, handleAndLogError, messageHandler, - v2Logger, + log, sanitizePath, } from '@contentstack/cli-utilities'; @@ -63,7 +63,7 @@ export default class ContentTypesExport extends BaseClass { await fsUtil.makeDirectory(this.contentTypesDirPath); await this.getContentTypes(); await this.writeContentTypes(this.contentTypes); - v2Logger.success(messageHandler.parse('CONTENT_TYPE_EXPORT_COMPLETE'), this.exportConfig.context); + log.success(messageHandler.parse('CONTENT_TYPE_EXPORT_COMPLETE'), this.exportConfig.context); } catch (error) { handleAndLogError(error, { ...this.exportConfig.context }); throw new Error(messageHandler.parse('CONTENT_TYPE_EXPORT_FAILED')); @@ -85,7 +85,7 @@ export default class ContentTypesExport extends BaseClass { } return await this.getContentTypes(skip); } else { - v2Logger.info(messageHandler.parse('CONTENT_TYPE_NO_TYPES'), this.exportConfig.context); + log.info(messageHandler.parse('CONTENT_TYPE_NO_TYPES'), this.exportConfig.context); } } diff --git a/packages/contentstack-export/src/export/modules/custom-roles.ts b/packages/contentstack-export/src/export/modules/custom-roles.ts index 3360113dd7..9a46f53709 100644 --- a/packages/contentstack-export/src/export/modules/custom-roles.ts +++ b/packages/contentstack-export/src/export/modules/custom-roles.ts @@ -3,7 +3,7 @@ import find from 'lodash/find'; import forEach from 'lodash/forEach'; import values from 'lodash/values'; import { resolve as pResolve } from 'node:path'; -import { handleAndLogError, messageHandler, v2Logger } from '@contentstack/cli-utilities'; +import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; import { fsUtil } from '../../utils'; @@ -51,12 +51,12 @@ export default class ExportCustomRoles extends BaseClass { const customRoles = roles.items.filter((role: any) => !this.existingRoles[role.name]); if (!customRoles.length) { - v2Logger.info(messageHandler.parse('ROLES_NO_CUSTOM_ROLES'), this.exportConfig.context); + log.info(messageHandler.parse('ROLES_NO_CUSTOM_ROLES'), this.exportConfig.context); return; } customRoles.forEach((role: any) => { - v2Logger.info(messageHandler.parse('ROLES_EXPORTING_ROLE', role.name), this.exportConfig.context); + log.info(messageHandler.parse('ROLES_EXPORTING_ROLE', role.name), this.exportConfig.context); this.customRoles[role.uid] = role; }); fsUtil.writeFile(pResolve(this.rolesFolderPath, this.customRolesConfig.fileName), this.customRoles); diff --git a/packages/contentstack-export/src/export/modules/entries.ts b/packages/contentstack-export/src/export/modules/entries.ts index c55ec817dd..23b6ca57ae 100644 --- a/packages/contentstack-export/src/export/modules/entries.ts +++ b/packages/contentstack-export/src/export/modules/entries.ts @@ -4,7 +4,7 @@ import { FsUtility, handleAndLogError, messageHandler, - v2Logger, + log, } from '@contentstack/cli-utilities'; import { Export, ExportProjects } from '@contentstack/cli-variants'; import { sanitizePath } from '@contentstack/cli-utilities'; @@ -66,7 +66,7 @@ export default class EntriesExport extends BaseClass { const locales = fsUtil.readFile(this.localesFilePath) as Array>; const contentTypes = fsUtil.readFile(this.schemaFilePath) as Array>; if (contentTypes.length === 0) { - v2Logger.info(messageHandler.parse('CONTENT_TYPE_NO_TYPES'), this.exportConfig.context); + log.info(messageHandler.parse('CONTENT_TYPE_NO_TYPES'), this.exportConfig.context); return; } @@ -91,7 +91,7 @@ export default class EntriesExport extends BaseClass { for (let entryRequestOption of entryRequestOptions) { await this.getEntries(entryRequestOption); this.entriesFileHelper?.completeFile(true); - v2Logger.success( + log.success( messageHandler.parse( 'ENTRIES_EXPORT_COMPLETE', entryRequestOption.contentType, @@ -100,7 +100,7 @@ export default class EntriesExport extends BaseClass { this.exportConfig.context, ); } - v2Logger.success(messageHandler.parse('ENTRIES_EXPORT_SUCCESS'), this.exportConfig.context); + log.success(messageHandler.parse('ENTRIES_EXPORT_SUCCESS'), this.exportConfig.context); } catch (error) { handleAndLogError(error, { ...this.exportConfig.context }); } @@ -216,7 +216,7 @@ export default class EntriesExport extends BaseClass { path.join(sanitizePath(options.versionedEntryPath), sanitizePath(`${entry.uid}.json`)), response, ); - v2Logger.success( + log.success( messageHandler.parse('ENTRIES_VERSIONED_EXPORT_SUCCESS', options.contentType, entry.uid, options.locale), this.exportConfig.context, ); diff --git a/packages/contentstack-export/src/export/modules/environments.ts b/packages/contentstack-export/src/export/modules/environments.ts index ce5de2d94d..909f4b5363 100644 --- a/packages/contentstack-export/src/export/modules/environments.ts +++ b/packages/contentstack-export/src/export/modules/environments.ts @@ -1,7 +1,7 @@ import { resolve as pResolve } from 'node:path'; import omit from 'lodash/omit'; import isEmpty from 'lodash/isEmpty'; -import { handleAndLogError, messageHandler, v2Logger } from '@contentstack/cli-utilities'; +import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; import { fsUtil } from '../../utils'; @@ -35,10 +35,10 @@ export default class ExportEnvironments extends BaseClass { await this.getEnvironments(); if (this.environments === undefined || isEmpty(this.environments)) { - v2Logger.info(messageHandler.parse('ENVIRONMENT_NOT_FOUND'), this.exportConfig.context); + log.info(messageHandler.parse('ENVIRONMENT_NOT_FOUND'), this.exportConfig.context); } else { fsUtil.writeFile(pResolve(this.environmentsFolderPath, this.environmentConfig.fileName), this.environments); - v2Logger.success( + log.success( messageHandler.parse('ENVIRONMENT_EXPORT_COMPLETE', Object.keys(this.environments).length), this.exportConfig.context, ); @@ -74,7 +74,7 @@ export default class ExportEnvironments extends BaseClass { const extUid = environments[index].uid; const envName = environments[index]?.name; this.environments[extUid] = omit(environments[index], ['ACL']); - v2Logger.success(messageHandler.parse('ENVIRONMENT_EXPORT_SUCCESS', envName ), this.exportConfig.context); + log.success(messageHandler.parse('ENVIRONMENT_EXPORT_SUCCESS', envName ), this.exportConfig.context); } } } diff --git a/packages/contentstack-export/src/export/modules/extensions.ts b/packages/contentstack-export/src/export/modules/extensions.ts index e1552a1174..54fb0e5daa 100644 --- a/packages/contentstack-export/src/export/modules/extensions.ts +++ b/packages/contentstack-export/src/export/modules/extensions.ts @@ -1,7 +1,7 @@ import omit from 'lodash/omit'; import isEmpty from 'lodash/isEmpty'; import { resolve as pResolve } from 'node:path'; -import { handleAndLogError, messageHandler, v2Logger } from '@contentstack/cli-utilities'; +import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; import { fsUtil } from '../../utils'; @@ -35,10 +35,10 @@ export default class ExportExtensions extends BaseClass { await this.getExtensions(); if (this.extensions === undefined || isEmpty(this.extensions)) { - v2Logger.info(messageHandler.parse('EXTENSION_NOT_FOUND'), this.exportConfig.context); + log.info(messageHandler.parse('EXTENSION_NOT_FOUND'), this.exportConfig.context); } else { fsUtil.writeFile(pResolve(this.extensionsFolderPath, this.extensionConfig.fileName), this.extensions); - v2Logger.success( + log.success( messageHandler.parse('EXTENSION_EXPORT_COMPLETE', Object.keys(this.extensions).length ), this.exportConfig.context, ); @@ -74,7 +74,7 @@ export default class ExportExtensions extends BaseClass { const extUid = extensions[index].uid; const extTitle = extensions[index]?.title; this.extensions[extUid] = omit(extensions[index], ['SYS_ACL']); - v2Logger.info(messageHandler.parse('EXTENSION_EXPORT_SUCCESS', extTitle), this.exportConfig.context); + log.info(messageHandler.parse('EXTENSION_EXPORT_SUCCESS', extTitle), this.exportConfig.context); } } } diff --git a/packages/contentstack-export/src/export/modules/global-fields.ts b/packages/contentstack-export/src/export/modules/global-fields.ts index 238d53efa1..6fd87c139d 100644 --- a/packages/contentstack-export/src/export/modules/global-fields.ts +++ b/packages/contentstack-export/src/export/modules/global-fields.ts @@ -3,7 +3,7 @@ import { ContentstackClient, handleAndLogError, messageHandler, - v2Logger, + log, sanitizePath, } from '@contentstack/cli-utilities'; @@ -57,7 +57,7 @@ export default class GlobalFieldsExport extends BaseClass { await fsUtil.makeDirectory(this.globalFieldsDirPath); await this.getGlobalFields(); fsUtil.writeFile(path.join(this.globalFieldsDirPath, this.globalFieldsConfig.fileName), this.globalFields); - v2Logger.success( + log.success( messageHandler.parse('GLOBAL_FIELDS_EXPORT_COMPLETE', this.globalFields.length), this.exportConfig.context, ); diff --git a/packages/contentstack-export/src/export/modules/labels.ts b/packages/contentstack-export/src/export/modules/labels.ts index b033ed3374..8012cc9023 100644 --- a/packages/contentstack-export/src/export/modules/labels.ts +++ b/packages/contentstack-export/src/export/modules/labels.ts @@ -1,7 +1,7 @@ import omit from 'lodash/omit'; import isEmpty from 'lodash/isEmpty'; import { resolve as pResolve } from 'node:path'; -import { handleAndLogError, messageHandler, v2Logger } from '@contentstack/cli-utilities'; +import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; import { fsUtil } from '../../utils'; @@ -34,10 +34,10 @@ export default class ExportLabels extends BaseClass { await fsUtil.makeDirectory(this.labelsFolderPath); await this.getLabels(); if (this.labels === undefined || isEmpty(this.labels)) { - v2Logger.info(messageHandler.parse('LABELS_NOT_FOUND'), this.exportConfig.context); + log.info(messageHandler.parse('LABELS_NOT_FOUND'), this.exportConfig.context); } else { fsUtil.writeFile(pResolve(this.labelsFolderPath, this.labelConfig.fileName), this.labels); - v2Logger.success( + log.success( messageHandler.parse('LABELS_EXPORT_COMPLETE', Object.keys(this.labels).length), this.exportConfig.context, ); @@ -73,7 +73,7 @@ export default class ExportLabels extends BaseClass { const labelUid = labels[index].uid; const labelName = labels[index]?.name; this.labels[labelUid] = omit(labels[index], this.labelConfig.invalidKeys); - v2Logger.info(messageHandler.parse('LABEL_EXPORT_SUCCESS', labelName), this.exportConfig.context); + log.info(messageHandler.parse('LABEL_EXPORT_SUCCESS', labelName), this.exportConfig.context); } } } diff --git a/packages/contentstack-export/src/export/modules/locales.ts b/packages/contentstack-export/src/export/modules/locales.ts index 4584f25868..341326eb8c 100644 --- a/packages/contentstack-export/src/export/modules/locales.ts +++ b/packages/contentstack-export/src/export/modules/locales.ts @@ -3,7 +3,7 @@ import { ContentstackClient, handleAndLogError, messageHandler, - v2Logger, + log, sanitizePath, } from '@contentstack/cli-utilities'; @@ -63,7 +63,7 @@ export default class LocaleExport extends BaseClass { await this.getLocales(); fsUtil.writeFile(path.join(this.localesPath, this.localeConfig.fileName), this.locales); fsUtil.writeFile(path.join(this.localesPath, this.masterLocaleConfig.fileName), this.masterLocale); - v2Logger.success( + log.success( messageHandler.parse( 'LOCALES_EXPORT_COMPLETE', Object.keys(this.locales).length, diff --git a/packages/contentstack-export/src/export/modules/marketplace-apps.ts b/packages/contentstack-export/src/export/modules/marketplace-apps.ts index 64605c344b..df1c2109a3 100644 --- a/packages/contentstack-export/src/export/modules/marketplace-apps.ts +++ b/packages/contentstack-export/src/export/modules/marketplace-apps.ts @@ -12,7 +12,7 @@ import { isAuthenticated, marketplaceSDKClient, ContentstackMarketplaceClient, - v2Logger, + log, messageHandler, handleAndLogError, } from '@contentstack/cli-utilities'; @@ -87,7 +87,7 @@ export default class ExportMarketplaceApps { */ async getAppManifestAndAppConfig(): Promise { if (isEmpty(this.installedApps)) { - v2Logger.info(messageHandler.parse('MARKETPLACE_APPS_NOT_FOUND'), this.exportConfig.context); + log.info(messageHandler.parse('MARKETPLACE_APPS_NOT_FOUND'), this.exportConfig.context); } else { for (const [index, app] of entries(this.installedApps)) { if (app.manifest.visibility === 'private') { @@ -101,7 +101,7 @@ export default class ExportMarketplaceApps { fsUtil.writeFile(pResolve(this.marketplaceAppPath, this.marketplaceAppConfig.fileName), this.installedApps); - v2Logger.success( + log.success( messageHandler.parse('MARKETPLACE_APPS_EXPORT_COMPLETE', Object.keys(this.installedApps).length), this.exportConfig.context, ); @@ -151,7 +151,7 @@ export default class ExportMarketplaceApps { const appName = appInstallation?.manifest?.name; const appUid = appInstallation?.manifest?.uid; const app = appName || appUid; - v2Logger.info(messageHandler.parse('MARKETPLACE_APP_CONFIG_EXPORT', app), this.exportConfig.context); + log.info(messageHandler.parse('MARKETPLACE_APP_CONFIG_EXPORT', app), this.exportConfig.context); await this.appSdk .marketplace(this.exportConfig.org_uid) @@ -171,9 +171,9 @@ export default class ExportMarketplaceApps { if (!isEmpty(data?.server_configuration)) { this.installedApps[index]['server_configuration'] = this.nodeCrypto.encrypt(data.server_configuration); - v2Logger.success(messageHandler.parse('MARKETPLACE_APP_CONFIG_SUCCESS', app), this.exportConfig.context); + log.success(messageHandler.parse('MARKETPLACE_APP_CONFIG_SUCCESS', app), this.exportConfig.context); } else { - v2Logger.success(messageHandler.parse('MARKETPLACE_APP_EXPORT_SUCCESS', app), this.exportConfig.context); + log.success(messageHandler.parse('MARKETPLACE_APP_EXPORT_SUCCESS', app), this.exportConfig.context); } } else if (error) { handleAndLogError( diff --git a/packages/contentstack-export/src/export/modules/personalize.ts b/packages/contentstack-export/src/export/modules/personalize.ts index 913cda7300..9fe009a5a7 100644 --- a/packages/contentstack-export/src/export/modules/personalize.ts +++ b/packages/contentstack-export/src/export/modules/personalize.ts @@ -6,7 +6,7 @@ import { ExportAudiences, AnyProperty, } from '@contentstack/cli-variants'; -import { handleAndLogError, messageHandler, v2Logger } from '@contentstack/cli-utilities'; +import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; import { ModuleClassParams, ExportConfig } from '../../types'; @@ -22,12 +22,12 @@ export default class ExportPersonalize { async start(): Promise { try { if (!this.personalizeConfig.baseURL[this.exportConfig.region.name]) { - v2Logger.info(messageHandler.parse('PERSONALIZE_URL_NOT_SET'), this.exportConfig.context); + log.info(messageHandler.parse('PERSONALIZE_URL_NOT_SET'), this.exportConfig.context); this.exportConfig.personalizationEnabled = false; return; } if (this.exportConfig.management_token) { - v2Logger.info(messageHandler.parse('PERSONALIZE_SKIPPING_WITH_MANAGEMENT_TOKEN'), this.exportConfig.context); + log.info(messageHandler.parse('PERSONALIZE_SKIPPING_WITH_MANAGEMENT_TOKEN'), this.exportConfig.context); this.exportConfig.personalizationEnabled = false; return; } @@ -47,7 +47,7 @@ export default class ExportPersonalize { if (moduleMapper[module]) { await moduleMapper[module].start(); } else { - v2Logger.info( + log.info( messageHandler.parse('PERSONALIZE_MODULE_NOT_IMPLEMENTED', module), this.exportConfig.context, ); @@ -56,7 +56,7 @@ export default class ExportPersonalize { } } catch (error) { if (error === 'Forbidden') { - v2Logger.info(messageHandler.parse('PERSONALIZE_NOT_ENABLED'), this.exportConfig.context); + log.info(messageHandler.parse('PERSONALIZE_NOT_ENABLED'), this.exportConfig.context); } else { handleAndLogError(error, { ...this.exportConfig.context }); } diff --git a/packages/contentstack-export/src/export/modules/stack.ts b/packages/contentstack-export/src/export/modules/stack.ts index 7e77873b37..1e856d82f5 100644 --- a/packages/contentstack-export/src/export/modules/stack.ts +++ b/packages/contentstack-export/src/export/modules/stack.ts @@ -1,6 +1,6 @@ import find from 'lodash/find'; import { resolve as pResolve } from 'node:path'; -import { handleAndLogError, isAuthenticated, managementSDKClient, v2Logger } from '@contentstack/cli-utilities'; +import { handleAndLogError, isAuthenticated, managementSDKClient, log } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; import { fsUtil } from '../../utils'; @@ -66,7 +66,7 @@ export default class ExportStack extends BaseClass { if (masterLocalObj) { return masterLocalObj; } else if (skip >= count) { - v2Logger.error( + log.error( `Master locale not found in the stack ${this.exportConfig.source_stack}. Please ensure that the stack has a master locale.`, this.exportConfig.context, ); @@ -92,7 +92,7 @@ export default class ExportStack extends BaseClass { .fetch() .then((resp: any) => { fsUtil.writeFile(pResolve(this.stackFolderPath, this.stackConfig.fileName), resp); - v2Logger.success( + log.success( `Stack details exported successfully for stack ${this.exportConfig.source_stack}`, this.exportConfig.context, ); diff --git a/packages/contentstack-export/src/export/modules/taxonomies.ts b/packages/contentstack-export/src/export/modules/taxonomies.ts index 7fd48ef185..c3a42c221c 100644 --- a/packages/contentstack-export/src/export/modules/taxonomies.ts +++ b/packages/contentstack-export/src/export/modules/taxonomies.ts @@ -2,7 +2,7 @@ import omit from 'lodash/omit'; import keys from 'lodash/keys'; import isEmpty from 'lodash/isEmpty'; import { resolve as pResolve } from 'node:path'; -import { handleAndLogError, messageHandler, v2Logger } from '@contentstack/cli-utilities'; +import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; import { fsUtil } from '../../utils'; @@ -39,13 +39,13 @@ export default class ExportTaxonomies extends BaseClass { //fetch all taxonomies and write into taxonomies folder await this.getAllTaxonomies(); if (this.taxonomies === undefined || isEmpty(this.taxonomies)) { - v2Logger.info(messageHandler.parse('TAXONOMY_NOT_FOUND'), this.exportConfig.context); + log.info(messageHandler.parse('TAXONOMY_NOT_FOUND'), this.exportConfig.context); return; } else { fsUtil.writeFile(pResolve(this.taxonomiesFolderPath, 'taxonomies.json'), this.taxonomies); await this.exportTaxonomies(); } - v2Logger.success( + log.success( messageHandler.parse('TAXONOMY_EXPORT_COMPLETE', keys(this.taxonomies).length ), this.exportConfig.context, ); @@ -104,7 +104,7 @@ export default class ExportTaxonomies extends BaseClass { const onSuccess = ({ response, uid }: any) => { const filePath = pResolve(this.taxonomiesFolderPath, `${uid}.json`); fsUtil.writeFile(filePath, response); - v2Logger.success( + log.success( messageHandler.parse('TAXONOMY_EXPORT_SUCCESS', uid), this.exportConfig.context, ); diff --git a/packages/contentstack-export/src/export/modules/webhooks.ts b/packages/contentstack-export/src/export/modules/webhooks.ts index 2b52ca5637..c4c10057ce 100644 --- a/packages/contentstack-export/src/export/modules/webhooks.ts +++ b/packages/contentstack-export/src/export/modules/webhooks.ts @@ -1,7 +1,7 @@ import omit from 'lodash/omit'; import isEmpty from 'lodash/isEmpty'; import { resolve as pResolve } from 'node:path'; -import { handleAndLogError, messageHandler, v2Logger } from '@contentstack/cli-utilities'; +import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; import { fsUtil } from '../../utils'; @@ -35,10 +35,10 @@ export default class ExportWebhooks extends BaseClass { await fsUtil.makeDirectory(this.webhooksFolderPath); await this.getWebhooks(); if (this.webhooks === undefined || isEmpty(this.webhooks)) { - v2Logger.info(messageHandler.parse('WEBHOOK_NOT_FOUND'), this.exportConfig.context); + log.info(messageHandler.parse('WEBHOOK_NOT_FOUND'), this.exportConfig.context); } else { fsUtil.writeFile(pResolve(this.webhooksFolderPath, this.webhookConfig.fileName), this.webhooks); - v2Logger.success( + log.success( messageHandler.parse('WEBHOOK_EXPORT_COMPLETE', Object.keys(this.webhooks).length), this.exportConfig.context, ); @@ -74,7 +74,7 @@ export default class ExportWebhooks extends BaseClass { const webhookUid = webhooks[index].uid; const webhookName = webhooks[index]?.name; this.webhooks[webhookUid] = omit(webhooks[index], ['SYS_ACL']); - v2Logger.success(messageHandler.parse('WEBHOOK_EXPORT_SUCCESS', webhookName), this.exportConfig.context); + log.success(messageHandler.parse('WEBHOOK_EXPORT_SUCCESS', webhookName), this.exportConfig.context); } } } diff --git a/packages/contentstack-export/src/export/modules/workflows.ts b/packages/contentstack-export/src/export/modules/workflows.ts index 801815c260..54d0ab2b78 100644 --- a/packages/contentstack-export/src/export/modules/workflows.ts +++ b/packages/contentstack-export/src/export/modules/workflows.ts @@ -1,7 +1,7 @@ import omit from 'lodash/omit'; import isEmpty from 'lodash/isEmpty'; import { resolve as pResolve } from 'node:path'; -import { handleAndLogError, messageHandler, v2Logger } from '@contentstack/cli-utilities'; +import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; import { fsUtil } from '../../utils'; @@ -35,10 +35,10 @@ export default class ExportWorkFlows extends BaseClass { await this.getWorkflows(); if (this.workflows === undefined || isEmpty(this.workflows)) { - v2Logger.info(messageHandler.parse('WORKFLOW_NOT_FOUND'), this.exportConfig.context); + log.info(messageHandler.parse('WORKFLOW_NOT_FOUND'), this.exportConfig.context); } else { fsUtil.writeFile(pResolve(this.webhooksFolderPath, this.workflowConfig.fileName), this.workflows); - v2Logger.success( + log.success( messageHandler.parse('WORKFLOW_EXPORT_COMPLETE', Object.keys(this.workflows).length ), this.exportConfig.context, ); @@ -77,7 +77,7 @@ export default class ExportWorkFlows extends BaseClass { const workflowUid = workflows[index].uid; const workflowName = workflows[index]?.name || ''; this.workflows[workflowUid] = omit(workflows[index], this.workflowConfig.invalidKeys); - v2Logger.success( + log.success( messageHandler.parse('WORKFLOW_EXPORT_SUCCESS', workflowName), this.exportConfig.context, ); diff --git a/packages/contentstack-export/src/utils/basic-login.ts b/packages/contentstack-export/src/utils/basic-login.ts index 7f8245d56f..60c730f445 100644 --- a/packages/contentstack-export/src/utils/basic-login.ts +++ b/packages/contentstack-export/src/utils/basic-login.ts @@ -7,7 +7,7 @@ * MIT Licensed */ -import { v2Logger, managementSDKClient, authHandler } from '@contentstack/cli-utilities'; +import { log, managementSDKClient, authHandler } from '@contentstack/cli-utilities'; import { ExternalConfig } from '../types'; const login = async (config: ExternalConfig): Promise => { @@ -22,18 +22,18 @@ const login = async (config: ExternalConfig): Promise => { 'X-User-Agent': 'contentstack-export/v', }; await authHandler.setConfigData('basicAuth', response.user); - v2Logger.success(`Contentstack account authenticated successfully!`, config.context); + log.success(`Contentstack account authenticated successfully!`, config.context); return config; } else { - v2Logger.error(`Failed to login, Invalid credentials`, config.context); + log.error(`Failed to login, Invalid credentials`, config.context); process.exit(1); } } else if (!config.email && !config.password && config.source_stack && config.access_token) { - v2Logger.info( + log.info( `Content types, entries, assets, labels, global fields, extensions modules will be exported`, config.context, ); - v2Logger.info( + log.info( `Email, password, or management token is not set in the config, cannot export Webhook and label modules`, config.context, ); diff --git a/packages/contentstack-utilities/src/index.ts b/packages/contentstack-utilities/src/index.ts index 2be5817d33..be28362868 100644 --- a/packages/contentstack-utilities/src/index.ts +++ b/packages/contentstack-utilities/src/index.ts @@ -77,4 +77,4 @@ export { default as TablePrompt } from './inquirer-table-prompt'; export { Logger }; export { default as authenticationHandler } from './authentication-handler'; -export {v2Logger, cliErrorHandler, handleAndLogError, getLogPath} from './logger/log' +export {v2Logger as log, cliErrorHandler, handleAndLogError, getLogPath} from './logger/log' diff --git a/packages/contentstack-variants/src/export/attributes.ts b/packages/contentstack-variants/src/export/attributes.ts index 35b089daa7..f82b28b92b 100644 --- a/packages/contentstack-variants/src/export/attributes.ts +++ b/packages/contentstack-variants/src/export/attributes.ts @@ -1,6 +1,6 @@ import omit from 'lodash/omit'; import { resolve as pResolve } from 'node:path'; -import { sanitizePath, v2Logger, handleAndLogError } from '@contentstack/cli-utilities'; +import { sanitizePath, log, handleAndLogError } from '@contentstack/cli-utilities'; import { formatError, fsUtil, PersonalizationAdapter } from '../utils'; import { PersonalizeConfig, ExportConfig, AttributesConfig, AttributeStruct } from '../types'; @@ -29,20 +29,20 @@ export default class ExportAttributes extends PersonalizationAdapter { async start() { try { - v2Logger.info('Starting events export', this.exportConfig.context); + log.info('Starting events export', this.exportConfig.context); await this.init(); await fsUtil.makeDirectory(this.eventsFolderPath); this.events = (await this.getEvents()) as EventStruct[]; if (!this.events?.length) { - v2Logger.info('No Events found with the given project!', this.exportConfig.context); + log.info('No Events found with the given project!', this.exportConfig.context); return; } else { this.sanitizeAttribs(); fsUtil.writeFile(pResolve(this.eventsFolderPath, this.eventsConfig.fileName), this.events); - v2Logger.success( + log.success( `Events exported successfully! Total events: ${this.events.length}`, this.exportConfig.context, ); diff --git a/packages/contentstack-variants/src/export/experiences.ts b/packages/contentstack-variants/src/export/experiences.ts index 19f5648231..1e678329b9 100644 --- a/packages/contentstack-variants/src/export/experiences.ts +++ b/packages/contentstack-variants/src/export/experiences.ts @@ -1,5 +1,5 @@ import * as path from 'path'; -import { sanitizePath, v2Logger, handleAndLogError } from '@contentstack/cli-utilities'; +import { sanitizePath, log, handleAndLogError } from '@contentstack/cli-utilities'; import { PersonalizeConfig, ExportConfig, ExperienceStruct } from '../types'; import { fsUtil, PersonalizationAdapter } from '../utils'; @@ -32,13 +32,13 @@ export default class ExportExperiences extends PersonalizationAdapter = (await this.getExperiences()) || []; if (!experiences || experiences?.length < 1) { - v2Logger.info('No Experiences found with the given project!', this.exportConfig.context); + log.info('No Experiences found with the given project!', this.exportConfig.context); return; } fsUtil.writeFile(path.resolve(sanitizePath(this.experiencesFolderPath), 'experiences.json'), experiences); @@ -62,7 +62,7 @@ export default class ExportExperiences extends PersonalizationAdapter async start() { try { - v2Logger.info(`Starting projects export`, this.exportConfig.context); + log.info(`Starting projects export`, this.exportConfig.context); await this.init(); await fsUtil.makeDirectory(this.projectFolderPath); const project = await this.projects({ connectedStackApiKey: this.exportConfig.apiKey }); if (!project || project?.length < 1) { - v2Logger.info(`No Personalize Project connected with the given stack`, this.exportConfig.context); + log.info(`No Personalize Project connected with the given stack`, this.exportConfig.context); this.exportConfig.personalizationEnabled = false; return; } this.exportConfig.personalizationEnabled = true; this.exportConfig.project_id = project[0]?.uid; fsUtil.writeFile(path.resolve(sanitizePath(this.projectFolderPath), 'projects.json'), project); - v2Logger.success(`Projects exported successfully!`, this.exportConfig.context); + log.success(`Projects exported successfully!`, this.exportConfig.context); } catch (error) { if (error !== 'Forbidden') { - v2Logger.error('Failed to export projects!', this.exportConfig.context); + log.error('Failed to export projects!', this.exportConfig.context); } throw error; } diff --git a/packages/contentstack-variants/src/export/variant-entries.ts b/packages/contentstack-variants/src/export/variant-entries.ts index 5c19b20bc7..5097b596bc 100644 --- a/packages/contentstack-variants/src/export/variant-entries.ts +++ b/packages/contentstack-variants/src/export/variant-entries.ts @@ -1,6 +1,6 @@ import { existsSync, mkdirSync } from 'fs'; import { join, resolve } from 'path'; -import { FsUtility, sanitizePath, v2Logger, handleAndLogError } from '@contentstack/cli-utilities'; +import { FsUtility, sanitizePath, log, handleAndLogError } from '@contentstack/cli-utilities'; import { APIConfig, AdapterType, ExportConfig } from '../types'; import VariantAdapter, { VariantHttpClient } from '../utils/variant-api-adapter'; @@ -77,7 +77,7 @@ export default class VariantEntries extends VariantAdapter Date: Fri, 6 Jun 2025 16:05:13 +0530 Subject: [PATCH 07/68] refactor: updated talismanrc --- .talismanrc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.talismanrc b/.talismanrc index 3111c5a42a..f821df17fb 100644 --- a/.talismanrc +++ b/.talismanrc @@ -135,13 +135,13 @@ fileignoreconfig: - filename: packages/contentstack-utilities/src/logger/logger.ts checksum: 09f3b73dd995bafc253265c676f06308513e6b1842d9bc01d39e6b6945a54c7d - filename: packages/contentstack-export/src/export/modules/environments.ts - checksum: 71dd1965e4ba66cefca578838cba125da0c8e4ef02fd95276b8236f66c018dce + checksum: 10cb048a8f30e2645a4c949fd2a51d0c741b7fdacb377768d2c0cfe34bdaf4e2 - filename: packages/contentstack-export/src/utils/basic-login.ts checksum: f95d4c0976729bd17238bf64713b3851d8852dbf60591210412c12ddaddd60c9 - filename: packages/contentstack-utilities/src/interfaces/index.ts checksum: 70079d81524ae4c196ffc77f13306184a8944b2903b881947dd06120150f31b0 - filename: packages/contentstack-export/src/commands/cm/stacks/export.ts - checksum: 4ea47b064ec18532da5fa7e5df47ad173fb7e878eb7899c934d4e1cdf1192956 + checksum: 941c6a8d59ba58e2004030202ee6282cdd2a424cf8b089aef70a85198553fefe - filename: packages/contentstack-utilities/src/logger/logger.ts checksum: b56504c1e4fb31b676cc1931eb30afc7b9466f03890fe3c76977309e1fd066a6 version: "1.0" From 8e3af7de50e117423396dae7dc197bd157c14d5f Mon Sep 17 00:00:00 2001 From: Aman Kumar Date: Wed, 11 Jun 2025 10:40:07 +0530 Subject: [PATCH 08/68] feat: Integrated Logger and cliErrorHanlder in auth plugin --- .../contentstack-auth/messages/index.json | 2 +- .../contentstack-auth/src/base-command.ts | 22 +++++++++++++++--- .../src/commands/auth/login.ts | 17 +++++--------- .../src/commands/auth/logout.ts | 17 ++++++-------- .../src/commands/auth/tokens/add.ts | 15 ++++++------ .../src/commands/auth/tokens/index.ts | 14 +++++++---- .../src/commands/auth/tokens/remove.ts | 12 ++++------ .../src/commands/auth/whoami.ts | 11 ++++----- .../contentstack-auth/src/interfaces/index.ts | 11 +++++++++ .../src/utils/auth-handler.ts | 23 +++++++------------ .../src/utils/tokens-validation.ts | 13 ++++------- 11 files changed, 81 insertions(+), 76 deletions(-) diff --git a/packages/contentstack-auth/messages/index.json b/packages/contentstack-auth/messages/index.json index f4e600e87c..0e9423a2c4 100644 --- a/packages/contentstack-auth/messages/index.json +++ b/packages/contentstack-auth/messages/index.json @@ -20,7 +20,7 @@ "CLI_AUTH_LOGOUT_ALREADY": "You're already logged out", "CLI_AUTH_LOGOUT_NO_AUTHORIZATIONS": "No authorizations found", "CLI_AUTH_LOGOUT_NO_AUTHORIZATIONS_USER": "No authorizations found for current user", - "CLI_AUTH_WHOAMI_LOGGED_IN_AS": "You are currently logged in with email", + "CLI_AUTH_WHOAMI_LOGGED_IN_AS": "You are currently logged in with email '%s'", "CLI_AUTH_WHOAMI_FAILED": "Failed to get the current user details", "CLI_AUTH_WHOAMI_DESCRIPTION": "Display current users email address", "CLI_AUTH_TOKENS_ADD_ASK_TOKEN_ALIAS": "Provide alias to store token", diff --git a/packages/contentstack-auth/src/base-command.ts b/packages/contentstack-auth/src/base-command.ts index 76188417bb..cf712d4984 100644 --- a/packages/contentstack-auth/src/base-command.ts +++ b/packages/contentstack-auth/src/base-command.ts @@ -1,5 +1,6 @@ import { Command } from '@contentstack/cli-command'; -import { FlagInput, Flags, Interfaces, LoggerService } from '@contentstack/cli-utilities'; +import { configHandler, FlagInput, Flags, Interfaces, LoggerService } from '@contentstack/cli-utilities'; +import { Context } from './interfaces'; export type Args = Interfaces.InferredArgs; export type Flags = Interfaces.InferredFlags<(typeof BaseCommand)['baseFlags'] & T['flags']>; @@ -8,7 +9,7 @@ export abstract class BaseCommand extends Command { public logger!: LoggerService; protected args!: Args; protected flags!: Flags; - + public contextDetails!: Context; /** * The `init` function initializes the command by parsing arguments and flags, registering search @@ -18,6 +19,7 @@ export abstract class BaseCommand extends Command { await super.init(); // Init logger this.logger = new LoggerService(process.cwd(), 'cli-log'); + this.contextDetails = this.createExportContext(); } /** @@ -45,4 +47,18 @@ export abstract class BaseCommand extends Command { // called after run and catch regardless of whether or not the command errored return super.finally(_); } -} \ No newline at end of file + + // Create export context object + protected createExportContext(apiKey?: string): Context { + return { + command: this.context.info.command, + module: '', + userId: configHandler.get('userId'), + email: configHandler.get('email'), + sessionId: this.context.sessionId, + clientId: this.context.clientId, + apiKey: apiKey || '', + orgId: configHandler.get('organization_uid') || '', + }; + } +} diff --git a/packages/contentstack-auth/src/commands/auth/login.ts b/packages/contentstack-auth/src/commands/auth/login.ts index aea7a35ed9..43d918d2c6 100644 --- a/packages/contentstack-auth/src/commands/auth/login.ts +++ b/packages/contentstack-auth/src/commands/auth/login.ts @@ -1,4 +1,3 @@ -import { Command } from '@contentstack/cli-command'; import { cliux, CLIError, @@ -6,7 +5,9 @@ import { flags, managementSDKClient, FlagInput, - formatError + log, + handleAndLogError, + messageHandler } from '@contentstack/cli-utilities'; import { User } from '../../interfaces'; import { authHandler, interactive } from '../../utils'; @@ -61,17 +62,12 @@ export default class LoginCommand extends BaseCommand { } else { const username = loginFlags?.username || (await interactive.askUsername()); const password = loginFlags?.password || (await interactive.askPassword()); - this.logger.debug('username', username); + log.debug('login flags', loginFlags); await this.login(username, password); } } catch (error) { - let errorMessage = formatError(error) || 'Something went wrong while logging. Please try again.'; - if (typeof errorMessage === 'object' && Object.keys(errorMessage)?.length === 0) { - console.log(error); - } - this.logger.error('login failed', errorMessage); cliux.error('CLI_AUTH_LOGIN_FAILED'); - cliux.error(errorMessage); + handleAndLogError(error, {...this.contextDetails}) process.exit(); } } @@ -83,8 +79,7 @@ export default class LoginCommand extends BaseCommand { throw new CLIError('Failed to login - invalid response'); } await oauthHandler.setConfigData('basicAuth', user); - this.logger.info('successfully logged in'); - cliux.success('CLI_AUTH_LOGIN_SUCCESS'); + log.success(messageHandler.parse('CLI_AUTH_LOGIN_SUCCESS'), this.contextDetails); } catch (error) { throw error; } diff --git a/packages/contentstack-auth/src/commands/auth/logout.ts b/packages/contentstack-auth/src/commands/auth/logout.ts index 7aba5bcfee..f293992ae5 100644 --- a/packages/contentstack-auth/src/commands/auth/logout.ts +++ b/packages/contentstack-auth/src/commands/auth/logout.ts @@ -1,4 +1,3 @@ -import { Command } from '@contentstack/cli-command'; import { cliux, configHandler, @@ -7,7 +6,9 @@ import { authHandler as oauthHandler, managementSDKClient, FlagInput, - formatError, + log, + handleAndLogError, + messageHandler } from '@contentstack/cli-utilities'; import { authHandler } from '../../utils'; @@ -50,7 +51,7 @@ export default class LogoutCommand extends BaseCommand { try { const managementAPIClient = await managementSDKClient({ host: this.cmaHost, skipTokenValidity: true }); authHandler.client = managementAPIClient; - if (confirm === true && (await oauthHandler.isAuthenticated())) { + if (confirm === true && (oauthHandler.isAuthenticated())) { cliux.loader('CLI_AUTH_LOGOUT_LOADER_START'); if (await oauthHandler.isAuthorisationTypeBasic()) { await authHandler.logout(configHandler.get('authtoken')); @@ -58,17 +59,13 @@ export default class LogoutCommand extends BaseCommand { await oauthHandler.oauthLogout(); } cliux.loader(''); - this.logger.info('successfully logged out'); - cliux.success('CLI_AUTH_LOGOUT_SUCCESS'); + log.success(messageHandler.parse('CLI_AUTH_LOGOUT_SUCCESS'), this.contextDetails); } else { - cliux.success('CLI_AUTH_LOGOUT_ALREADY'); + log.success(messageHandler.parse('CLI_AUTH_LOGOUT_ALREADY'), this.contextDetails); } } catch (error) { - let errorMessage = formatError(error) || 'Something went wrong while logging out. Please try again.'; - - this.logger.error('Logout failed', errorMessage); cliux.print('CLI_AUTH_LOGOUT_FAILED', { color: 'yellow' }); - cliux.print(errorMessage, { color: 'red' }); + handleAndLogError(error, { ...this.contextDetails }); } finally { if (confirm === true) { await oauthHandler.setConfigData('logout'); diff --git a/packages/contentstack-auth/src/commands/auth/tokens/add.ts b/packages/contentstack-auth/src/commands/auth/tokens/add.ts index 07480aaf09..3c407aad97 100644 --- a/packages/contentstack-auth/src/commands/auth/tokens/add.ts +++ b/packages/contentstack-auth/src/commands/auth/tokens/add.ts @@ -1,4 +1,3 @@ -import { Command } from '@contentstack/cli-command'; import { cliux, configHandler, @@ -8,10 +7,12 @@ import { HttpClient, messageHandler, Flags, - formatError, + log, + handleAndLogError, } from '@contentstack/cli-utilities'; -import { askTokenType } from '../../../utils/interactive'; import { BaseCommand } from '../../../base-command'; +import { askTokenType } from '../../../utils/interactive'; + export default class TokensAddCommand extends BaseCommand { static description = 'Adds management/delivery tokens to your session to use it with other CLI commands'; @@ -100,7 +101,7 @@ export default class TokensAddCommand extends BaseCommand { static aliases = ['tokens']; @@ -55,10 +61,8 @@ export default class TokensListCommand extends BaseCommand { @@ -14,7 +13,6 @@ export default class TokensRemoveCommand extends BaseCommand{ - this.logger.info('selected tokens',ele); + log.info(`Selected token: ${ele}`, this.contextDetails); }) selectedTokens.forEach((element) => { const selectedToken = element.split(':')[0]; configHandler.delete(`tokens.${selectedToken}`); cliux.success('CLI_AUTH_TOKENS_REMOVE_SUCCESS'); - this.logger.info('Token removed successfully !!', element); + log.info(`Token removed: ${selectedToken}`, this.contextDetails); }); } catch (error) { - let errorMessage = formatError(error) || 'Something went wrong while removing token. Please try again.'; - this.logger.error('Token remove error', errorMessage); cliux.print('CLI_AUTH_TOKENS_REMOVE_FAILED', { color: 'yellow' }); - cliux.print(errorMessage, { color: 'red' }); + handleAndLogError(error, {...this.contextDetails} ) } } } diff --git a/packages/contentstack-auth/src/commands/auth/whoami.ts b/packages/contentstack-auth/src/commands/auth/whoami.ts index bb3cd81653..0aa58fa533 100644 --- a/packages/contentstack-auth/src/commands/auth/whoami.ts +++ b/packages/contentstack-auth/src/commands/auth/whoami.ts @@ -1,5 +1,4 @@ -import { Command } from '@contentstack/cli-command'; -import { cliux, formatError } from '@contentstack/cli-utilities'; +import { cliux, log, handleAndLogError, messageHandler } from '@contentstack/cli-utilities'; import { BaseCommand } from '../../base-command'; export default class WhoamiCommand extends BaseCommand { @@ -14,15 +13,13 @@ export default class WhoamiCommand extends BaseCommand { if (this.email) { cliux.print('CLI_AUTH_WHOAMI_LOGGED_IN_AS', { color: 'white' }); cliux.print(this.email, { color: 'green' }); - this.logger.info('Currently logged in user', this.email); + log.info(messageHandler.parse('CLI_AUTH_WHOAMI_LOGGED_IN_AS', this.email), this.contextDetails); } else { - cliux.error('CLI_AUTH_WHOAMI_FAILED'); + log.error(messageHandler.parse('CLI_AUTH_WHOAMI_FAILED'), this.contextDetails); } } catch (error) { - let errorMessage = formatError(error) || 'Something went wrong. Please try again.'; - this.logger.error('whoami error', errorMessage); cliux.print('CLI_AUTH_WHOAMI_FAILED', { color: 'yellow' }); - cliux.print(errorMessage, { color: 'red' }); + handleAndLogError(error, { ...this.contextDetails }); } } } diff --git a/packages/contentstack-auth/src/interfaces/index.ts b/packages/contentstack-auth/src/interfaces/index.ts index 85b593ca1c..0e6ac65fd5 100644 --- a/packages/contentstack-auth/src/interfaces/index.ts +++ b/packages/contentstack-auth/src/interfaces/index.ts @@ -23,3 +23,14 @@ export interface User { email: string; authtoken: string; } + +export interface Context { + command: string; + module: string; + userId: string | undefined; + email: string | undefined; + sessionId: string | undefined; + clientId: string | undefined; + apiKey: string; + orgId: string; +} \ No newline at end of file diff --git a/packages/contentstack-auth/src/utils/auth-handler.ts b/packages/contentstack-auth/src/utils/auth-handler.ts index 0a8a48215f..7941b2bfe8 100644 --- a/packages/contentstack-auth/src/utils/auth-handler.ts +++ b/packages/contentstack-auth/src/utils/auth-handler.ts @@ -1,7 +1,6 @@ -import { cliux, CLIError } from '@contentstack/cli-utilities'; +import { cliux, CLIError, handleAndLogError, log } from '@contentstack/cli-utilities'; import { User } from '../interfaces'; import { askOTPChannel, askOTP } from './interactive'; -import { LoggerService } from '@contentstack/cli-utilities'; /** * @class @@ -10,7 +9,6 @@ import { LoggerService } from '@contentstack/cli-utilities'; class AuthHandler { private _client; private _host; - public logger!: LoggerService; set client(contentStackClient) { this._client = contentStackClient; } @@ -18,9 +16,6 @@ class AuthHandler { this._host = contentStackHost; } - initLog() { - this.logger = new LoggerService(process.cwd(), 'cli-log'); - } /** * * @@ -31,7 +26,6 @@ class AuthHandler { * TBD: take out the otp implementation from login and create a new method/function to handle otp */ async login(email: string, password: string, tfaToken?: string): Promise { - this.initLog(); return new Promise((resolve, reject) => { if (email && password) { const loginPayload: { @@ -45,18 +39,19 @@ class AuthHandler { this._client .login(loginPayload) .then(async (result: any) => { - this.logger.debug('login result', result); + log.debug('login result', result); if (result.user) { resolve(result.user as User); } else if (result.error_code === 294) { const otpChannel = await askOTPChannel(); + log.debug('otp channel', otpChannel); // need to send sms to the mobile if (otpChannel === 'sms') { try { await this._client.axiosInstance.post('/user/request_token_sms', { user: loginPayload }); cliux.print('CLI_AUTH_LOGIN_SECURITY_CODE_SEND_SUCCESS'); } catch (error) { - this.logger.error('Failed to send the security code', error); + handleAndLogError(error, {}, 'Failed to send the security code') reject(new CLIError({ message: 'Failed to login - failed to send the security code' })); return; } @@ -65,7 +60,7 @@ class AuthHandler { try { resolve(await this.login(email, password, tfToken)); } catch (error) { - this.logger.error('Failed to login with tfa token', error); + handleAndLogError(error, {}, 'Failed to login with tfa token') reject(new CLIError({ message: 'Failed to login with the tf token' })); } } else { @@ -73,7 +68,7 @@ class AuthHandler { } }) .catch((error: any) => { - this.logger.error('Failed to login', error); + handleAndLogError(error, {}, 'Failed to login with the credentials'); reject(new CLIError({ message: error.errorMessage })); }); } else { @@ -88,7 +83,6 @@ class AuthHandler { * @returns {Promise} Promise object returns response object from Contentstack */ async logout(authtoken: string): Promise { - this.initLog(); return new Promise((resolve, reject) => { if (authtoken) { this._client @@ -97,7 +91,7 @@ class AuthHandler { return resolve(response); }) .catch((error: Error) => { - this.logger.error('Failed to logout', error); + handleAndLogError(error, {}, 'Failed to logout'); return reject(new CLIError({ message: 'Failed to logout - ' + error.message })); }); } else { @@ -112,14 +106,13 @@ class AuthHandler { * @returns {Promise} Promise object returns response object from Contentstack */ async validateAuthtoken(authtoken: string): Promise { - this.initLog(); return new Promise((resolve, reject) => { if (authtoken) { this._client .getUser() .then((user: object) => resolve(user)) .catch((error: Error) => { - this.logger.error('Failed to validate token', error); + handleAndLogError(error, {}, 'Failed to validate token'); reject(new CLIError({ message: 'Failed to validate token - ' + error.message })); }); } else { diff --git a/packages/contentstack-auth/src/utils/tokens-validation.ts b/packages/contentstack-auth/src/utils/tokens-validation.ts index 0fe2bf0c4d..159b72adac 100644 --- a/packages/contentstack-auth/src/utils/tokens-validation.ts +++ b/packages/contentstack-auth/src/utils/tokens-validation.ts @@ -1,5 +1,4 @@ -import { messageHandler } from '@contentstack/cli-utilities'; -import { LoggerService } from '@contentstack/cli-utilities'; +import { messageHandler, handleAndLogError, log } from '@contentstack/cli-utilities'; /** * Validate environment * @param contentStackClient @@ -12,18 +11,17 @@ export const validateEnvironment = async ( apiKey: string, environment: string, ): Promise => { - const newLogger = new LoggerService(process.cwd(),'cli-log'); let result: { valid: boolean; message: string }; try { const validationResult = await contentStackClient.Stack({ api_key: apiKey }).environment(environment).fetch(); - newLogger.debug('environment validation result', validationResult); + log.debug('environment validation result', validationResult); if (validationResult.name === environment) { result = { valid: true, message: validationResult }; } else { result = { valid: false, message: messageHandler.parse('CLI_AUTH_TOKENS_VALIDATION_INVALID_ENVIRONMENT_NAME') }; } } catch (error) { - newLogger.error('validate environment error', error); + handleAndLogError(error, { apiKey, environment }, ); result = { valid: false, message: 'CLI_AUTH_TOKENS_VALIDATION_INVALID_ENVIRONMENT_NAME' }; } return result; @@ -36,18 +34,17 @@ export const validateEnvironment = async ( * @returns */ export const validateAPIKey = async (contentStackClient: any, apiKey: string): Promise => { - const newLogger = new LoggerService(process.cwd(),'cli-log'); let result: { valid: boolean; message: string }; try { const validateAPIKeyResult = await contentStackClient.stack({ api_key: apiKey }).fetch(); - newLogger.debug('api key validation result', validateAPIKeyResult); + log.debug('validate api key result', validateAPIKeyResult); if (validateAPIKeyResult.api_key === apiKey) { result = { valid: true, message: validateAPIKeyResult }; } else { result = { valid: false, message: messageHandler.parse('CLI_AUTH_TOKENS_VALIDATION_INVALID_API_KEY') }; } } catch (error) { - newLogger.error('validate api key error', error); + handleAndLogError(error, { apiKey }, ); result = { valid: false, message: messageHandler.parse('CLI_AUTH_TOKENS_VALIDATION_INVALID_API_KEY') }; } From 9f39fc0e6d712a6a5f5420ea7d0977b1ddeb760a Mon Sep 17 00:00:00 2001 From: Aman Kumar Date: Wed, 11 Jun 2025 10:43:51 +0530 Subject: [PATCH 09/68] refactor: updated talismanrc file --- .talismanrc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.talismanrc b/.talismanrc index f821df17fb..b2058b42c1 100644 --- a/.talismanrc +++ b/.talismanrc @@ -144,4 +144,10 @@ fileignoreconfig: checksum: 941c6a8d59ba58e2004030202ee6282cdd2a424cf8b089aef70a85198553fefe - filename: packages/contentstack-utilities/src/logger/logger.ts checksum: b56504c1e4fb31b676cc1931eb30afc7b9466f03890fe3c76977309e1fd066a6 + - filename: packages/contentstack-auth/src/base-command.ts + checksum: b7b6b94676f8413bf49cbe591b4242eef7936b9b4660b04cf8c8bcd2e96ce0ec + - filename: packages/contentstack-auth/src/commands/auth/tokens/add.ts + checksum: 40f7a6bdfb4c1d5c19d213feffdf9c76eb2fca451567a2fb1cc26338b2163b26 + - filename: packages/contentstack-auth/src/utils/tokens-validation.ts + checksum: fd7c4ebb6d6d955647012454357c360a292d122227a0d130b39dfd56c41f7529 version: "1.0" From 9b4a6111297b935b7af3e8310755fc7326ea7a0e Mon Sep 17 00:00:00 2001 From: Aman Kumar Date: Fri, 13 Jun 2025 11:46:38 +0530 Subject: [PATCH 10/68] feat: Added Support for config get & config set for Logging Configuration --- packages/contentstack-config/README.md | 43 ++++ .../contentstack-config/messages/index.json | 6 +- .../src/commands/config/get/log.ts | 26 +++ .../src/commands/config/set/log.ts | 48 +++++ .../src/utils/interactive.ts | 23 +++ .../test/unit/commands/log.test.ts | 190 ++++++++++++++++++ packages/contentstack/README.md | 43 ++++ 7 files changed, 378 insertions(+), 1 deletion(-) create mode 100644 packages/contentstack-config/src/commands/config/get/log.ts create mode 100644 packages/contentstack-config/src/commands/config/set/log.ts create mode 100644 packages/contentstack-config/test/unit/commands/log.test.ts diff --git a/packages/contentstack-config/README.md b/packages/contentstack-config/README.md index 73d3a2a375..ce036bb966 100644 --- a/packages/contentstack-config/README.md +++ b/packages/contentstack-config/README.md @@ -32,6 +32,7 @@ USAGE * [`csdx config:get:base-branch`](#csdx-configgetbase-branch) * [`csdx config:get:ea-header`](#csdx-configgetea-header) * [`csdx config:get:early-access-header`](#csdx-configgetearly-access-header) +* [`csdx config:get:log`](#csdx-configgetlog) * [`csdx config:get:rate-limit`](#csdx-configgetrate-limit) * [`csdx config:get:region`](#csdx-configgetregion) * [`csdx config:remove:base-branch`](#csdx-configremovebase-branch) @@ -41,6 +42,7 @@ USAGE * [`csdx config:set:base-branch`](#csdx-configsetbase-branch) * [`csdx config:set:ea-header`](#csdx-configsetea-header) * [`csdx config:set:early-access-header`](#csdx-configsetearly-access-header) +* [`csdx config:set:log`](#csdx-configsetlog) * [`csdx config:set:rate-limit`](#csdx-configsetrate-limit) * [`csdx config:set:region [REGION]`](#csdx-configsetregion-region) @@ -99,6 +101,23 @@ EXAMPLES _See code: [src/commands/config/get/early-access-header.ts](https://github.com/contentstack/cli/blob/main/packages/contentstack-config/src/commands/config/get/early-access-header.ts)_ +## `csdx config:get:log` + +Get current logging configuration for CLI + +``` +USAGE + $ csdx config:get:log + +DESCRIPTION + Get current logging configuration for CLI + +EXAMPLES + $ csdx config:get:log +``` + +_See code: [src/commands/config/get/log.ts](https://github.com/contentstack/cli/blob/main/packages/contentstack-config/src/commands/config/get/log.ts)_ + ## `csdx config:get:rate-limit` Get rate-limit of organizations @@ -301,6 +320,30 @@ EXAMPLES _See code: [src/commands/config/set/early-access-header.ts](https://github.com/contentstack/cli/blob/main/packages/contentstack-config/src/commands/config/set/early-access-header.ts)_ +## `csdx config:set:log` + +Set logging configuration for CLI + +``` +USAGE + $ csdx config:set:log [--log-level debug|info|warn|error] [--log-path ] + +FLAGS + --log-level=