diff --git a/package-lock.json b/package-lock.json index 3beaacb55c..481ae29974 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25681,7 +25681,7 @@ "@contentstack/cli-audit": "~1.5.1", "@contentstack/cli-auth": "~1.3.17", "@contentstack/cli-cm-bootstrap": "~1.9.0", - "@contentstack/cli-cm-branches": "~1.0.23", + "@contentstack/cli-cm-branches": "~1.0.24", "@contentstack/cli-cm-bulk-publish": "~1.4.3", "@contentstack/cli-cm-clone": "~1.10.3", "@contentstack/cli-cm-export": "~1.11.1", @@ -25692,7 +25692,7 @@ "@contentstack/cli-command": "~1.2.17", "@contentstack/cli-config": "~1.6.3", "@contentstack/cli-launch": "~1.0.17", - "@contentstack/cli-migration": "~1.5.0", + "@contentstack/cli-migration": "~1.5.2", "@contentstack/cli-utilities": "~1.6.0", "@contentstack/management": "~1.15.3", "@oclif/core": "^2.9.3", @@ -26128,7 +26128,7 @@ }, "packages/contentstack-branches": { "name": "@contentstack/cli-cm-branches", - "version": "1.0.23", + "version": "1.0.24", "license": "MIT", "dependencies": { "@contentstack/cli-command": "~1.2.16", @@ -27625,7 +27625,7 @@ }, "packages/contentstack-migration": { "name": "@contentstack/cli-migration", - "version": "1.5.1", + "version": "1.5.2", "license": "MIT", "dependencies": { "@contentstack/cli-command": "~1.2.16", diff --git a/packages/contentstack-branches/package.json b/packages/contentstack-branches/package.json index e44875a087..d21b85f260 100644 --- a/packages/contentstack-branches/package.json +++ b/packages/contentstack-branches/package.json @@ -1,7 +1,7 @@ { "name": "@contentstack/cli-cm-branches", "description": "Contentstack CLI plugin to do branches operations", - "version": "1.0.23", + "version": "1.0.24", "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { @@ -95,4 +95,4 @@ } }, "repository": "https://github.com/contentstack/cli" -} +} \ No newline at end of file diff --git a/packages/contentstack-branches/src/utils/asset-folder-create-script.ts b/packages/contentstack-branches/src/utils/asset-folder-create-script.ts index 30ad3ec1fe..a0c97bfd1c 100644 --- a/packages/contentstack-branches/src/utils/asset-folder-create-script.ts +++ b/packages/contentstack-branches/src/utils/asset-folder-create-script.ts @@ -114,9 +114,9 @@ export function assetFolderCreateScript(contentType) { const createAssetTask = () => { return { - title: 'Create Assets Folder', + title: 'Check and create asset folder in base branch', successTitle: 'Assets folder Created Successfully', - failedTitle: 'Failed to create assets folder', + failedTitle: 'Failed to create assets folder in base branch', task: async () => { try { const baseAssetsFolderCount = await getAssetCount(branch, true); diff --git a/packages/contentstack-branches/src/utils/entry-create-script.ts b/packages/contentstack-branches/src/utils/entry-create-script.ts index f3388ead13..f97f3b3309 100644 --- a/packages/contentstack-branches/src/utils/entry-create-script.ts +++ b/packages/contentstack-branches/src/utils/entry-create-script.ts @@ -9,7 +9,6 @@ export function entryCreateScript(contentType) { const omit = require('lodash/omit'); const compact = require('lodash/compact') const isPlainObject = require('lodash/isPlainObject'); - const {cliux, LoggerService} = require('@contentstack/cli-utilities') module.exports = async ({ migration, stackSDKInstance, managementAPIClient, config, branch, apiKey }) => { const keysToRemove = [ 'content_type_uid', @@ -41,7 +40,6 @@ export function entryCreateScript(contentType) { let assetRefPath = {}; let downloadedAssets = []; let parent=[]; - let logger; function getValueByPath(obj, path) { return path.split('[').reduce((o, key) => o && o[key.replace(/\]$/, '')], obj); @@ -470,10 +468,6 @@ export function entryCreateScript(contentType) { successTitle: 'Entries Created Successfully', failedTitle: 'Failed to create entries', task: async () => { - //logger file - if(!fs.existsSync(path.join(filePath, 'entry-migration'))){ - logger = new LoggerService(filePath, 'entry-migration'); - } const compareBranchEntries = await managementAPIClient .stack({ api_key: stackSDKInstance.api_key, branch_uid: compareBranch }) @@ -520,17 +514,7 @@ export function entryCreateScript(contentType) { async function updateEntry(entry, entryDetails) { Object.assign(entry, { ...entryDetails }); - await entry.update().catch(err => { - let errorMsg = 'Entry update failed for uid: ' + entry?.uid + ', title: ' + entry?.title + '. '; - if(err?.errors?.title){ - errorMsg += 'title'+ err?.errors?.title; - }else if(err?.errors?.entry){ - errorMsg += err?.errors?.entry; - }else{ - errorMsg += (err?.entry?.errorMessage || err?.errorMessage || err?.message) ?? 'Something went wrong!'; - } - logger.error(errorMsg) - }); + await entry.update() } async function updateReferences(entryDetails, baseEntry, references) { @@ -558,29 +542,21 @@ export function entryCreateScript(contentType) { } try { - compareFilteredProperties.length !== 0 && - compareFilteredProperties.forEach(async (entryDetails) => { - if(entryDetails !== undefined){ + if (compareFilteredProperties.length !== 0) { + for (let i = 0; i < compareFilteredProperties.length; i++) { + let entryDetails = compareFilteredProperties[i]; + if (entryDetails !== undefined) { entryDetails = updateAssetDetailsInEntries(entryDetails); - let createdEntry = await stackSDKInstance.contentType('${contentType}').entry().create({ entry: entryDetails }).catch(err => { - let errorMsg = 'Entry creation failed for contentType: ' + contentType + ', title: ' + entryDetails?.title + '. '; - if(err?.errors?.title){ - errorMsg += err?.errors?.title; - }else if(err?.errors?.entry){ - errorMsg += err?.errors?.entry; - }else{ - errorMsg += (err?.entry?.errorMessage || err?.errorMessage || err?.message) ?? 'Something went wrong!'; - } - logger.error(errorMsg) - }); - if(createdEntry){ + let createdEntry = await stackSDKInstance.contentType('${contentType}').entry().create({ entry: entryDetails }) + if (createdEntry) { if (flag.references) { await updateReferences(entryDetails, createdEntry, references); } - await updateEntry(createdEntry, entryDetails); + await updateEntry(createdEntry, entryDetails) } } - }); + } + } } catch (error) { throw error; } diff --git a/packages/contentstack-branches/src/utils/entry-create-update-script.ts b/packages/contentstack-branches/src/utils/entry-create-update-script.ts index fe52aaedac..564ad5c776 100644 --- a/packages/contentstack-branches/src/utils/entry-create-update-script.ts +++ b/packages/contentstack-branches/src/utils/entry-create-update-script.ts @@ -9,7 +9,6 @@ export function entryCreateUpdateScript(contentType) { const omit = require('lodash/omit'); const compact = require('lodash/compact') const isPlainObject = require('lodash/isPlainObject'); - const {cliux, LoggerService} = require('@contentstack/cli-utilities') module.exports = async ({ migration, stackSDKInstance, managementAPIClient, config, branch, apiKey }) => { const keysToRemove = [ 'content_type_uid', @@ -42,7 +41,6 @@ export function entryCreateUpdateScript(contentType) { let assetUrlMapper = {}; let assetRefPath = {}; let parent=[]; - let logger; function converter(data) { let arr = []; @@ -485,10 +483,6 @@ export function entryCreateUpdateScript(contentType) { successMessage: 'Entries Updated Successfully', failedMessage: 'Failed to update entries', task: async () => { - //logger file - if(!fs.existsSync(path.join(filePath, 'entry-migration'))){ - logger = new LoggerService(filePath, 'entry-migration'); - } let compareBranchEntries = await managementAPIClient .stack({ api_key: stackSDKInstance.api_key, branch_uid: compareBranch }) .contentType('${contentType}') @@ -539,17 +533,7 @@ export function entryCreateUpdateScript(contentType) { async function updateEntry(entry, entryDetails) { if (entry) { Object.assign(entry, { ...entryDetails }); - await entry.update().catch(err => { - let errorMsg = 'Entry update failed for uid: ' + entry?.uid + ', title: ' + entry?.title + '.'; - if(err?.errors?.title){ - errorMsg += err?.errors?.title; - }else if(err?.errors?.entry){ - errorMsg += err?.errors?.entry; - }else{ - errorMsg += (err?.entry?.errorMessage || err?.errorMessage || err?.message) ?? 'Something went wrong!'; - } - logger.error(errorMsg) - }); + await entry.update(); } } @@ -622,9 +606,6 @@ export function entryCreateUpdateScript(contentType) { .contentType('${contentType}') .entry() .create({ entry: entryDetails }) - .catch(err => { - (err?.errorMessage || err?.message) ? err?.errorMessage || err?.message : 'Something went wrong!' - }) if(createdEntry){ if (flag.references) { diff --git a/packages/contentstack-branches/src/utils/entry-update-script.ts b/packages/contentstack-branches/src/utils/entry-update-script.ts index 59222ac58d..d99f5c79d3 100644 --- a/packages/contentstack-branches/src/utils/entry-update-script.ts +++ b/packages/contentstack-branches/src/utils/entry-update-script.ts @@ -9,7 +9,6 @@ export function entryUpdateScript(contentType) { const omit = require('lodash/omit'); const compact = require('lodash/compact') const isPlainObject = require('lodash/isPlainObject'); - const {cliux, LoggerService} = require('@contentstack/cli-utilities') module.exports = async ({ migration, stackSDKInstance, managementAPIClient, config, branch, apiKey }) => { const keysToRemove = [ 'content_type_uid', @@ -42,7 +41,6 @@ export function entryUpdateScript(contentType) { let assetUrlMapper = {}; let assetRefPath = {}; let parent=[]; - let logger; function converter(data) { let arr = []; @@ -484,10 +482,6 @@ export function entryUpdateScript(contentType) { successMessage: 'Entries Updated Successfully', failedMessage: 'Failed to update entries', task: async () => { - //logger file - if(!fs.existsSync(path.join(filePath, 'entry-migration'))){ - logger = new LoggerService(filePath, 'entry-migration'); - } let compareBranchEntries = await managementAPIClient .stack({ api_key: stackSDKInstance.api_key, branch_uid: compareBranch }) @@ -538,17 +532,7 @@ export function entryUpdateScript(contentType) { async function updateEntry(entry, entryDetails) { Object.assign(entry, { ...entryDetails }); - await entry.update().catch(err => { - let errorMsg = 'Entry update failed for uid: ' + entry?.uid + ', title: ' + entry?.title + '.'; - if(err?.errors?.title){ - errorMsg += err?.errors?.title; - }else if(err?.errors?.entry){ - errorMsg += err?.errors?.entry; - }else{ - errorMsg += (err?.entry?.errorMessage || err?.errorMessage || err?.message) ?? 'Something went wrong!'; - } - logger.error(errorMsg) - }); + await entry.update(); } async function updateReferences(entryDetails, baseEntry, references) { @@ -619,9 +603,6 @@ export function entryUpdateScript(contentType) { .contentType('${contentType}') .entry() .create({ entry: entryDetails }) - .catch(err => { - (err?.errorMessage || err?.message) ? err?.errorMessage || err?.message : 'Something went wrong!' - }) if(createdEntry){ if (flag.references) { diff --git a/packages/contentstack-migration/package.json b/packages/contentstack-migration/package.json index aae748882a..a1ccf29819 100644 --- a/packages/contentstack-migration/package.json +++ b/packages/contentstack-migration/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/cli-migration", - "version": "1.5.1", + "version": "1.5.2", "author": "@contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { @@ -66,4 +66,4 @@ "cm:migration": "O-MGRTN" } } -} +} \ No newline at end of file diff --git a/packages/contentstack-migration/src/commands/cm/stacks/migration.js b/packages/contentstack-migration/src/commands/cm/stacks/migration.js index 293a110512..cf591102bb 100644 --- a/packages/contentstack-migration/src/commands/cm/stacks/migration.js +++ b/packages/contentstack-migration/src/commands/cm/stacks/migration.js @@ -12,6 +12,7 @@ const { Parser } = require('../../../modules'); const { ActionList } = require('../../../actions'); const fs = require('fs'); const chalk = require('chalk'); +const isEmpty = require('lodash/isEmpty'); const { printFlagDeprecation, managementSDKClient, @@ -24,8 +25,6 @@ const { ApiError, SchemaValidator, MigrationError, FieldValidator } = require('. // Utils const { map: _map, constants, safePromise, errorHelper } = require('../../../utils'); -const { success } = require('../../../utils/logger'); - // Properties const { get, set, getMapInstance, resetMapInstance } = _map; const { @@ -134,6 +133,10 @@ class MigrationCommand extends Command { } else { await this.execSingleFile(filePath, mapInstance); } + const errLogPath = `${process.cwd()}/migration-logs`; + if (fs.existsSync(errLogPath)) { + this.log(`The log has been stored at: `, errLogPath); + } } async execSingleFile(filePath, mapInstance) { @@ -160,21 +163,11 @@ class MigrationCommand extends Command { const listr = new Listr(tasks); - await listr.run().catch((error) => { - this.handleErrors(error); - // When the process is child, send error message to parent - if (process.send) process.send({ errorOccurred: true }); - }); + await listr.run(); requests.splice(0, requests.length); } catch (error) { - // errorHandler(null, null, null, error) - if (error.message) { - this.log(error.message); - } else if (error.errorMessage) { - this.log(error.errorMessage); - } else { - this.log(error); - } + errorHelper(error, filePath); + if (process.send) process.send({ errorOccurred: true }); } } @@ -186,7 +179,6 @@ class MigrationCommand extends Command { for (const element of files) { const file = element; if (extname(file) === '.js') { - success(chalk`{white Executing file:} {grey {bold ${file}}}`); // eslint-disable-next-line no-await-in-loop await this.execSingleFile(pathValidator(resolve(filePath, file)), mapInstance); } diff --git a/packages/contentstack-migration/src/utils/error-handler.js b/packages/contentstack-migration/src/utils/error-handler.js deleted file mode 100644 index e79710354e..0000000000 --- a/packages/contentstack-migration/src/utils/error-handler.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict'; - -const { error } = require('./logger'); -const { errorMessageHandler } = require('./constants'); - -module.exports = (data, type, method, err) => { - if (data && type && method) { - error(`Error occurred while ${errorMessageHandler[method]} ${type}: ${data}.`); - } - - if (err.errorMessage) { - error(err.errorMessage); - } - if (err instanceof Error && err && err.message && err.stack) { - error(err.message); - // error(err.stack) - } else { - error(err); - } - // throw new Error(err); -}; diff --git a/packages/contentstack-migration/src/utils/error-helper.js b/packages/contentstack-migration/src/utils/error-helper.js index f1048eb743..47a748d183 100644 --- a/packages/contentstack-migration/src/utils/error-helper.js +++ b/packages/contentstack-migration/src/utils/error-helper.js @@ -1,8 +1,9 @@ const { highlight } = require('cardinal'); const { keys } = Object; const chalk = require('chalk'); -const isEmpty = require('lodash/isEmpty') - +const isEmpty = require('lodash/isEmpty'); +const MigrationLogger = require('./migration-logger'); +const fs = require('fs'); const { readFile } = require('./fs-helper'); const groupBy = require('./group-by'); @@ -19,43 +20,72 @@ const getLineWithContext = (lines, lineNumber, context) => { }; }; -module.exports = (errors) => { +function removeSpecialCharacter(str) { + return str.replace(/\u001b\[\d+m/g, ''); +} + +module.exports = (errors, filePath) => { + const logger = new MigrationLogger(process.cwd()); + const errorsByFile = groupBy(errors, 'file'); const messages = []; - for (const file of keys(errorsByFile)) { - const fileContents = readFile(file); - const highlightedCode = highlight(fileContents, { linenos: true }); - const lines = highlightedCode.split('\n'); - - const fileErrorsMessage = chalk`{red Errors in ${file}}\n\n`; - const errorMessages = errorsByFile[file] - .map((error) => { - const callsite = error.meta.callsite; - const context = 2; - const { before, line, after } = getLineWithContext(lines, callsite.line, context); - - const beforeLines = before.map((_line) => chalk`${_line}\n`); - const afterLines = after.map((_line) => chalk`${_line}\n`); - const highlightedLine = chalk`{bold ${line}}\n`; - - const formattedCode = beforeLines + highlightedLine + afterLines; - if (error.payload.apiError) { - return chalk`{red Line ${String(callsite.line)}:} {bold ${error.payload.apiError.message}}\n${formattedCode}`; - } - if (error.message) { - return chalk`{red Line ${String(callsite.line)}:} {bold ${error.message}}\n${formattedCode}`; - } - return chalk`{red Line ${String(callsite.line)}:} {bold something went wrong here.}\n${formattedCode}`; - }) - .join('\n'); - - messages.push(`${fileErrorsMessage}${errorMessages}`); - } - if (isEmpty(messages) && errors !== undefined && isEmpty(errorsByFile)) { - console.error('Migration error---', errors); + if (filePath) { + if (errors.request) { + errors.data = errors.request?.data; + delete errors.request; + } + if (errors.message) { + delete errors.message; + } + logger.log('error', { [filePath]: errors }); } else { - console.log(messages.join('\n')); + for (const file of keys(errorsByFile)) { + const errorLogs = {}; + errorLogs[file] = {}; + const fileContents = readFile(file); + const highlightedCode = highlight(fileContents, { linenos: true }); + const lines = highlightedCode.split('\n'); + + const fileErrorsMessage = chalk`{red Errors in ${file}}\n\n`; + errorLogs[file].fileErrorsMessage = fileErrorsMessage.replace(/\u001b\[\d+m/g, ''); + const errorMessages = errorsByFile[file] + .map((error) => { + const callsite = error.meta.callsite; + const context = 2; + let { before, line, after } = getLineWithContext(lines, callsite.line, context); + + const beforeLines = before.map((_line) => chalk`${_line}\n`); + const afterLines = after.map((_line) => chalk`${_line}\n`); + const highlightedLine = chalk`{bold ${line}}\n`; + + before = removeSpecialCharacter(before.join('\n')); + after = removeSpecialCharacter(after.join('\n')); + line = removeSpecialCharacter(line); + errorLogs[file].lines = { before, line, after }; + + const formattedCode = beforeLines + highlightedLine + afterLines; + if (error.payload?.apiError) { + errorLogs[file].apiError = true; + errorLogs[file].errorCode = error.payload.apiError.errorCode; + errorLogs[file].errors = error.payload.apiError.errors; + } + if (error.message && !error.payload.apiError) { + errorLogs[file].apiError = false; + errorLogs[file].error = error.message; + } + }) + .join('\n'); + + messages.push(`${fileErrorsMessage}${errorMessages}`); + logger.log('error', errorLogs); + } + if (isEmpty(messages) && errors !== undefined && isEmpty(errorsByFile)) { + logger.log('error', errors); + console.log(chalk`{bold.red Migration unsuccessful}`); + } else { + logger.log('error', { error: messages.join('\n') }); + } } // eslint-disable-next-line - console.log(chalk`{bold.red Migration unsuccessful}`); + // console.log(chalk`{bold.red Migration unsuccessful}`); }; diff --git a/packages/contentstack-migration/src/utils/index.js b/packages/contentstack-migration/src/utils/index.js index dd3ea9763a..18553758e4 100644 --- a/packages/contentstack-migration/src/utils/index.js +++ b/packages/contentstack-migration/src/utils/index.js @@ -11,7 +11,6 @@ module.exports = { safePromise: require('./safe-promise'), getConfig: require('./get-config'), successHandler: require('./success-handler'), - errorHandler: require('./error-handler'), getCallsite: require('./callsite'), errorHelper: require('./error-helper'), groupBy: require('./group-by'), diff --git a/packages/contentstack-migration/src/utils/logger.js b/packages/contentstack-migration/src/utils/logger.js index f2c1ea57dc..d6f96953c1 100644 --- a/packages/contentstack-migration/src/utils/logger.js +++ b/packages/contentstack-migration/src/utils/logger.js @@ -36,7 +36,7 @@ function init(logFileName) { const logPath = pathValidator(join(logsDir, logFileName + '.log')); const logger = createLogger({ format: combine(colorize(), label({ label: 'Migration' }), customFormat), - transports: [new transports.File({ filename: logPath }), new transports.Console()], + transports: [new transports.File({ filename: logPath })], }); let args; @@ -54,9 +54,9 @@ function init(logFileName) { logString && logger.log('warn', logString); }, error: function () { - args = slice.call(arguments); - logString = getString(args); - logString && logger.log('error', logString); + // args = slice.call(arguments); + // logString = getString(args); + // logString && logger.log('error', logString); }, debug: function () { args = slice.call(arguments); diff --git a/packages/contentstack-migration/src/utils/migration-logger.js b/packages/contentstack-migration/src/utils/migration-logger.js new file mode 100644 index 0000000000..0417f1e637 --- /dev/null +++ b/packages/contentstack-migration/src/utils/migration-logger.js @@ -0,0 +1,20 @@ +const winston = require('winston'); +const path = require('path'); +module.exports = class MigrationLogger { + constructor(filePath) { + this.filePath = path.join(filePath, 'migration-logs'); + this.logger = winston.createLogger({ + levels: { error: 1 }, + transports: [ + new winston.transports.File({ + level: 'error', + filename: path.join(this.filePath, 'error.logs'), + format: winston.format.combine(winston.format.timestamp(), winston.format.json()), + }), + ], + }); + } + log(level, message) { + this.logger.log('error', message); + } +}; diff --git a/packages/contentstack/package.json b/packages/contentstack/package.json index 5f08ac8688..dc91fc8e98 100755 --- a/packages/contentstack/package.json +++ b/packages/contentstack/package.json @@ -25,7 +25,7 @@ "@contentstack/cli-audit": "~1.5.1", "@contentstack/cli-auth": "~1.3.17", "@contentstack/cli-cm-bootstrap": "~1.9.0", - "@contentstack/cli-cm-branches": "~1.0.23", + "@contentstack/cli-cm-branches": "~1.0.24", "@contentstack/cli-cm-bulk-publish": "~1.4.3", "@contentstack/cli-cm-export": "~1.11.1", "@contentstack/cli-cm-clone": "~1.10.3", @@ -36,7 +36,7 @@ "@contentstack/cli-command": "~1.2.17", "@contentstack/cli-config": "~1.6.3", "@contentstack/cli-launch": "~1.0.17", - "@contentstack/cli-migration": "~1.5.0", + "@contentstack/cli-migration": "~1.5.2", "@contentstack/cli-utilities": "~1.6.0", "@contentstack/management": "~1.15.3", "@oclif/core": "^2.9.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e4234954c6..61d66c7bc6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,7 +13,7 @@ importers: '@contentstack/cli-audit': ~1.5.1 '@contentstack/cli-auth': ~1.3.17 '@contentstack/cli-cm-bootstrap': ~1.9.0 - '@contentstack/cli-cm-branches': ~1.0.23 + '@contentstack/cli-cm-branches': ~1.0.24 '@contentstack/cli-cm-bulk-publish': ~1.4.3 '@contentstack/cli-cm-clone': ~1.10.3 '@contentstack/cli-cm-export': ~1.11.1 @@ -24,7 +24,7 @@ importers: '@contentstack/cli-command': ~1.2.17 '@contentstack/cli-config': ~1.6.3 '@contentstack/cli-launch': ~1.0.17 - '@contentstack/cli-migration': ~1.5.0 + '@contentstack/cli-migration': ~1.5.2 '@contentstack/cli-utilities': ~1.6.0 '@contentstack/management': ~1.15.3 '@oclif/core': ^2.9.3