@microsoft/windows-admin-center-sdk
Version:
Microsoft - Windows Admin Center Shell
1 lines • 11 kB
Source Map (JSON)
{"version":3,"sources":["../../../packages/tools/wac-cli/src/upgrade/error-updater.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiB,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAInE,qBAAa,YAAY;IACrB;;;;;OAKG;IACU,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAOvF;;;;;OAKG;IACU,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAaxF,SAAS,CAAC,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IA2BjE,SAAS,CAAC,gBAAgB,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;cAQpC,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;cAsClH,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmC/I,SAAS,CAAC,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,EAAE;IAuD1D,SAAS,CAAC,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,EAAE;CA4C/D","file":"error-updater.d.ts","sourcesContent":["import { exec } from 'child_process';\r\nimport fse from 'fs-extra';\r\nimport { Common, ResolveState } from '../common';\r\nimport { UpdaterLookup } from './error-updaters/updater-lookup';\r\nimport { ErrorPosition, ErrorResult } from './models/error-result';\r\nimport { Updater } from './models/updater-interface';\r\nimport { Logger } from '../angular15/utils/logger';\r\n\r\nexport class ErrorUpdater {\r\n /**\r\n * Executes 'ng lint' and attempts to fix returned errors.\r\n * @param {boolean} audit Flag indicating if upgrade is running it audit mode\r\n * @param {string[]} updateSource Array used to emit logs to file\r\n * @returns {Promise<number>} Count of unresolved errors.\r\n */\r\n public async resolveLintErrors(audit: boolean, updateSource: string[]): Promise<number> {\r\n const errors = await this.parseLintErrors(audit);\r\n const unresolvedCount = await this.fixErrors(audit, errors, updateSource);\r\n\r\n return new Promise((resolve) => resolve(unresolvedCount));\r\n }\r\n\r\n /**\r\n * Executes 'ng build' and attempts to fix returned errors.\r\n * @param {boolean} audit Flag indicating if upgrade is running it audit mode\r\n * @param {string[]} updateSource Array used to emit logs to file\r\n * @returns {Promise<number>} Count of unresolved errors.\r\n */\r\n public async resolveBuildErrors(audit: boolean, updateSource: string[]): Promise<number> {\r\n // If running in audit mode, we don't want to build\r\n if (audit) {\r\n return new Promise(resolve => resolve(0));\r\n }\r\n\r\n const errors = await this.parseBuildErrors();\r\n const unresolvedCount = await this.fixErrors(false, errors, updateSource);\r\n\r\n Logger.log('INFO - unresolvedCount' + unresolvedCount);\r\n return new Promise((resolve) => resolve(unresolvedCount));\r\n }\r\n\r\n protected parseLintErrors(audit: boolean): Promise<ErrorResult[]> {\r\n // If audit is true, run without --fix flag\r\n const cmd = audit ? 'ng lint --project module-app --format json' : 'ng lint --project module-app --fix --format json';\r\n\r\n console.log('Linting, please wait...');\r\n return new Promise((resolve) => {\r\n exec(cmd, (_, stdout) => {\r\n const output = JSON.parse(stdout);\r\n\r\n const results: ErrorResult[] = [];\r\n for (const error of output) {\r\n if (error.ruleSeverity === 'error') {\r\n results.push({\r\n filePath: error.name,\r\n type: error.ruleName,\r\n message: error.failure,\r\n position: { line: error.startPosition.line, character: error.startPosition.character },\r\n resolved: ResolveState.Unresolved\r\n });\r\n }\r\n }\r\n\r\n resolve(results);\r\n });\r\n });\r\n }\r\n\r\n protected parseBuildErrors(): Promise<ErrorResult[]> {\r\n console.log('Building, please wait...');\r\n\r\n return new Promise((resolve) => exec('ng build', (_error, _stdout, stderr) => {\r\n resolve(this.parseBuildErrorsCore(stderr));\r\n }));\r\n }\r\n\r\n protected async fixErrors(audit: boolean, errors: ErrorResult[], updateSource: string[], angularVersion?: string): Promise<number> {\r\n if (!errors || !errors.length) {\r\n return new Promise(resolve => resolve(0));\r\n }\r\n\r\n let unresolvedCount = errors.length;\r\n\r\n for (const error of errors) {\r\n let message = `File path: ${error.filePath}`;\r\n console.log(message);\r\n updateSource.push(message + '\\n');\r\n\r\n let fileData = Common.readFileData(error.filePath);\r\n\r\n if (!fileData) {\r\n message = `Couldn't retrieve file data for path ${error.filePath}. Please verify this path is valid.`;\r\n console.log(message);\r\n updateSource.push(message + '\\n');\r\n continue;\r\n }\r\n\r\n fileData = await this.fixError(audit, fileData, error, updateSource, angularVersion);\r\n\r\n if (error.resolved === ResolveState.Resolved) {\r\n unresolvedCount--;\r\n }\r\n\r\n if (fileData) {\r\n fse.writeFileSync(error.filePath, fileData);\r\n }\r\n\r\n console.log('');\r\n updateSource.push('\\n');\r\n }\r\n\r\n return new Promise(resolve => resolve(unresolvedCount));\r\n }\r\n\r\n protected async fixError(audit: boolean, fileData: string, error: ErrorResult, updateSource: string[], augularVerion?: string): Promise<string> {\r\n let message = `\\tType: ${error.type}`;\r\n console.log(message);\r\n updateSource.push(message + '\\n');\r\n\r\n message = `\\tLine: ${error?.position?.line}`;\r\n console.log(message);\r\n updateSource.push(message + '\\n');\r\n\r\n message = `\\tChar: ${error?.position?.character}`;\r\n console.log(message);\r\n updateSource.push(message + '\\n');\r\n\r\n message = `\\tMessage: ${error.message}`;\r\n console.log(message);\r\n updateSource.push(message + '\\n');\r\n\r\n if (audit) {\r\n return fileData;\r\n }\r\n\r\n const updaterLookup = UpdaterLookup.initialize(augularVerion);\r\n const updater: Updater = updaterLookup[error.type];\r\n\r\n Logger.log(`error.type = ${error.type}`);\r\n Logger.log(updater ? `Found updater for ${error.type}` : `No updater found for ${error.type}`);\r\n\r\n const result = updater != null ? await updater.update(fileData, error) : fileData;\r\n\r\n message = `\\tResolved: ${error.resolved}\\n`;\r\n console.log(message);\r\n updateSource.push(message + '\\n');\r\n return new Promise(resolve => resolve(result));\r\n }\r\n\r\n protected parseBuildErrorsCore(log: string): ErrorResult[] {\r\n const captureAll = /[\\s\\S]+?(?=(Error|Warning):)/g; // Capture array of build error/warning output by file\r\n const captureFilePath = /(?<=Error: )(.+)(?=:\\d+:\\d+)/g; // Capture file path of individual error\r\n const captureErrorPosition = /(?<=Error: .+)(\\d+:\\d+)(?= - error)/g; // Capture file position of individual error\r\n const captureErrorCode = /(?<=Error:.+- error )(TS\\d+)/g; // Capture error code of individual error\r\n const captureErrorMessage = /(?<=TS\\d+: ).+/g; // Capture error message of individual error\r\n\r\n log = log + '\\n\\n\\nWarning:';\r\n const buildOutputByCode = log.match(captureAll);\r\n\r\n const results: ErrorResult[] = [];\r\n\r\n if (!buildOutputByCode) {\r\n return results;\r\n }\r\n \r\n for (const file of buildOutputByCode) {\r\n const filePath = file.match(captureFilePath);\r\n\r\n // If no file path found, this match doesn't contain errors\r\n if (!filePath || filePath.length === 0) {\r\n continue;\r\n }\r\n\r\n const errorPositionString = file.match(captureErrorPosition);\r\n\r\n // If there isn't a position found this isn't a parsable error, skip to next file\r\n if (!errorPositionString || errorPositionString.length === 0) {\r\n continue;\r\n }\r\n\r\n const splitValues = errorPositionString[0].split(':');\r\n const errorPosition: ErrorPosition = { line: parseInt(splitValues[0], null), character: parseInt(splitValues[1], null) };\r\n\r\n const errorCode = file.match(captureErrorCode);\r\n\r\n // Couldn't get error code, skip to next file\r\n if (!errorCode || errorCode.length === 0) {\r\n continue;\r\n }\r\n\r\n const errorMessage = file.match(captureErrorMessage);\r\n\r\n results.push({\r\n filePath: filePath[0],\r\n type: errorCode[0],\r\n message: errorMessage[0],\r\n position: errorPosition,\r\n resolved: ResolveState.Unresolved\r\n });\r\n }\r\n\r\n return results;\r\n }\r\n\r\n protected parseBuildWarningsCore(log: string): ErrorResult[] {\r\n // Capture array of build error/warning output by file\r\n const captureAll = /[\\s\\S]+?(?=(Error|Warning):)/g;\r\n\r\n // Capture file path of individual error\r\n const captureFilePath = /([^\\s\\r\\n].*\\.css)\\s*(?=:)/g;\r\n\r\n log = log + '\\n\\n\\nWarning:';\r\n const buildOutputByCode = log.match(captureAll);\r\n\r\n const results: ErrorResult[] = [];\r\n\r\n if (!buildOutputByCode) {\r\n return results;\r\n }\r\n \r\n for (const file of buildOutputByCode) {\r\n const filePath = file.match(captureFilePath);\r\n\r\n // If no file path found, this match doesn't contain errors\r\n if (!filePath || filePath.length === 0) {\r\n continue;\r\n }\r\n\r\n let errorCode;\r\n if (file.includes('css-syntax-error')) {\r\n errorCode = ['css-syntax-error'];\r\n }\r\n\r\n // Couldn't get error code, skip to next file\r\n if (!errorCode || errorCode.length === 0) {\r\n continue;\r\n }\r\n\r\n results.push({\r\n filePath: filePath[0],\r\n type: errorCode[0],\r\n message: file,\r\n resolved: ResolveState.Unresolved\r\n });\r\n }\r\n\r\n return results;\r\n }\r\n}\r\n"]}