rflib-plugin 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/lib/commands/rflib/logging/apex/instrument.d.ts +1 -0
- package/lib/commands/rflib/logging/apex/instrument.js +14 -3
- package/lib/commands/rflib/logging/apex/instrument.js.map +1 -1
- package/lib/commands/rflib/logging/aura/instrument.d.ts +1 -0
- package/lib/commands/rflib/logging/aura/instrument.js +26 -8
- package/lib/commands/rflib/logging/aura/instrument.js.map +1 -1
- package/lib/commands/rflib/logging/flow/instrument.d.ts +1 -0
- package/lib/commands/rflib/logging/flow/instrument.js +14 -3
- package/lib/commands/rflib/logging/flow/instrument.js.map +1 -1
- package/lib/commands/rflib/logging/lwc/instrument.d.ts +1 -0
- package/lib/commands/rflib/logging/lwc/instrument.js +14 -3
- package/lib/commands/rflib/logging/lwc/instrument.js.map +1 -1
- package/messages/rflib.logging.apex.instrument.md +8 -0
- package/messages/rflib.logging.aura.instrument.md +8 -0
- package/messages/rflib.logging.flow.instrument.md +8 -0
- package/messages/rflib.logging.lwc.instrument.md +8 -0
- package/oclif.lock +132 -131
- package/oclif.manifest.json +37 -1
- package/package.json +3 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrument.js","sourceRoot":"","sources":["../../../../../src/commands/rflib/logging/flow/instrument.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable sf-plugin/only-extend-SfCommand */\n/* eslint-disable @typescript-eslint/return-await */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { Messages, Logger } from '@salesforce/core';\nimport { SfCommand, Flags } from '@salesforce/sf-plugins-core';\nimport * as xml2js from 'xml2js';\n\nexport type RflibLoggingFlowInstrumentResult = {\n processedFiles: number;\n modifiedFiles: number;\n modifiedFilePaths?: string[];\n};\n\nMessages.importMessagesDirectoryFromMetaUrl(import.meta.url);\nconst messages = Messages.loadMessages('rflib-plugin', 'rflib.logging.flow.instrument');\n\nexport class FlowInstrumentationService {\n private static readonly parser = new xml2js.Parser({\n explicitArray: false,\n preserveChildrenOrder: true,\n xmlns: false\n });\n\n private static readonly builder = new xml2js.Builder({\n xmldec: { version: '1.0', encoding: 'UTF-8' },\n cdata: true,\n renderOpts: {\n pretty: true,\n indent: ' ',\n newline: '\\n'\n }\n });\n\n public static async parseFlowContent(content: string): Promise<any> {\n try {\n return await this.parser.parseStringPromise(content);\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Flow parsing failed: ${error.message}`);\n }\n throw new Error('Flow parsing failed with unknown error');\n }\n }\n\n public static buildFlowContent(flowObj: any): string {\n try {\n if (!flowObj?.Flow) {\n throw new Error('Invalid flow object structure');\n }\n\n // Create a new Flow object with ordered properties\n const orderedFlow = {\n '$': { 'xmlns': 'http://soap.sforce.com/2006/04/metadata' }\n } as Record<string, unknown>;\n\n // Add actionCalls first if it exists\n if (flowObj.Flow.actionCalls) {\n orderedFlow.actionCalls = flowObj.Flow.actionCalls;\n }\n\n // Add all other properties in their original order\n Object.entries(flowObj.Flow as Record<string, unknown>).forEach(([key, value]) => {\n if (key !== 'actionCalls' && key !== '$') {\n orderedFlow[key] = value;\n }\n });\n\n // Use the builder with just the Flow object, not wrapped in another object\n return this.builder.buildObject({ Flow: orderedFlow });\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Flow building failed: ${error.message}`);\n }\n throw new Error('Flow building failed with unknown error');\n }\n }\n\n // Helper to check if flow already contains RFLIB logger\n public static hasRFLIBLogger(flowObj: any): boolean {\n if (!flowObj?.Flow?.actionCalls) {\n return false;\n }\n\n const actionCalls = Array.isArray(flowObj.Flow.actionCalls)\n ? flowObj.Flow.actionCalls\n : [flowObj.Flow.actionCalls];\n\n return actionCalls.some(\n (action: any) =>\n action.actionName === 'rflib:Logger' ||\n action.actionName === 'rflib_LoggerFlowAction' ||\n action.actionName === 'rflib_ApplicationEventLoggerAction' ||\n (action.name && typeof action.name === 'string' && action.name.startsWith('RFLIB_Flow_Logger'))\n );\n }\n\n // Helper to check if flow has a supported process type for instrumentation\n public static isSupportedProcessType(flowObj: any): boolean {\n const processType = flowObj?.Flow?.processType;\n const triggerType = flowObj?.Flow?.start?.triggerType;\n\n return processType === 'Flow' ||\n (processType === 'AutoLaunchedFlow' && triggerType === 'RecordAfterSave');\n }\n\n // Main instrumentation function\n public static instrumentFlow(flowObj: any, flowName: string, skipInstrumented = false): any {\n // Deep clone the object to avoid modifying the original\n const instrumentedFlow = JSON.parse(JSON.stringify(flowObj));\n\n // Skip if already instrumented and skipInstrumented flag is set\n if (skipInstrumented && this.hasRFLIBLogger(instrumentedFlow)) {\n return instrumentedFlow;\n }\n\n // Make sure Flow exists in the object\n if (!instrumentedFlow.Flow) {\n return instrumentedFlow;\n }\n\n // Create logging action element\n let loggingAction = this.createLoggingAction(flowName);\n\n // Add variables to the logging message if available\n loggingAction = this.enhanceLoggingWithVariables(loggingAction, instrumentedFlow);\n\n // Add logging action to actionCalls\n if (!instrumentedFlow.Flow.actionCalls) {\n instrumentedFlow.Flow.actionCalls = loggingAction;\n } else if (Array.isArray(instrumentedFlow.Flow.actionCalls)) {\n instrumentedFlow.Flow.actionCalls.unshift(loggingAction);\n } else {\n instrumentedFlow.Flow.actionCalls = [loggingAction, instrumentedFlow.Flow.actionCalls];\n }\n\n // Find startElementReference or start element and connect logger to it\n if (instrumentedFlow.Flow.startElementReference) {\n // Save the original start reference\n const startNodeReference = instrumentedFlow.Flow.startElementReference;\n\n // Create connector between logger and original start element\n loggingAction.connector = {\n targetReference: startNodeReference\n };\n\n // Update flow startElementReference to point to our logger\n instrumentedFlow.Flow.startElementReference = loggingAction.name;\n } else if (instrumentedFlow.Flow.start?.connector?.targetReference) {\n // Handle flow with start element: create connector and update start reference\n const startElement = instrumentedFlow.Flow.start;\n const originalTarget = startElement.connector.targetReference;\n\n // Create connector between logger and the original target\n loggingAction.connector = {\n targetReference: originalTarget\n };\n\n // Update the start element connector to point to our logger\n startElement.connector.targetReference = loggingAction.name;\n }\n\n // Set the CanvasMode to AUTO_LAYOUT_CANVAS\n this.setCanvasMode(instrumentedFlow);\n\n // Instrument decisions with logging for each outcome\n if (instrumentedFlow.Flow.decisions) {\n this.instrumentDecisions(instrumentedFlow, flowName);\n }\n\n // Reorder Flow properties\n const originalFlow = instrumentedFlow.Flow as Record<string, unknown>;\n const orderedFlow: Record<string, unknown> = {\n $: originalFlow.$,\n actionCalls: originalFlow.actionCalls\n };\n\n Object.keys(originalFlow).forEach(key => {\n if (key !== 'actionCalls' && key !== '$') {\n orderedFlow[key] = originalFlow[key];\n }\n });\n\n instrumentedFlow.Flow = orderedFlow;\n return instrumentedFlow;\n }\n\n // Helper to instrument decision paths with logging\n private static instrumentDecisions(flowObj: any, flowName: string): void {\n if (!flowObj.Flow.decisions) {\n return;\n }\n\n // Convert to array if there's only one decision\n const decisions = Array.isArray(flowObj.Flow.decisions)\n ? flowObj.Flow.decisions\n : [flowObj.Flow.decisions];\n\n // Process each decision\n decisions.forEach((decision: any) => {\n // Support decision name as 'name' or legacy 'n'\n const decisionNameRaw = decision.name ?? decision.n;\n if (!decisionNameRaw) {\n return;\n }\n const decisionName = decisionNameRaw;\n const decisionLabel = decision.label || decisionName;\n\n // Process default connector if it exists\n if (decision.defaultConnector?.targetReference) {\n const defaultTarget = decision.defaultConnector.targetReference;\n const defaultConnectorLabel = decision.defaultConnectorLabel || 'Default Outcome';\n\n // Create a logger for the default path\n const defaultLogger = this.createDecisionPathLogger(\n flowName,\n String(decisionName),\n String(decisionLabel),\n 'default',\n String(defaultConnectorLabel)\n );\n\n // Connect logger to the original target\n defaultLogger.connector = {\n targetReference: defaultTarget\n };\n\n // Add logger to actionCalls first, before updating the decision connector\n this.addActionCallToFlow(flowObj, defaultLogger);\n\n // Update the decision's default connector to point to our logger\n // We're inside a forEach callback, so we have to modify the original object\n /* eslint-disable no-param-reassign */\n decision.defaultConnector.targetReference = defaultLogger.name;\n /* eslint-enable no-param-reassign */\n }\n\n // Process each rule if they exist\n if (decision.rules) {\n const rules = Array.isArray(decision.rules) ? decision.rules : [decision.rules];\n\n rules.forEach((rule: any) => {\n // Skip if rule doesn't have a connector or name (support 'name' or legacy 'n')\n const ruleNameRaw = rule.name ?? rule.n;\n if (!rule.connector?.targetReference || !ruleNameRaw) {\n return;\n }\n const ruleTarget = rule.connector.targetReference;\n const ruleName = ruleNameRaw;\n const ruleLabel = rule.label || ruleName;\n\n // Create a logger for this rule outcome\n const ruleLogger = this.createDecisionPathLogger(\n flowName,\n String(decisionName),\n String(decisionLabel),\n String(ruleName),\n String(ruleLabel)\n );\n\n // Connect logger to the original target\n ruleLogger.connector = {\n targetReference: ruleTarget\n };\n\n // Add logger to actionCalls first, before updating the rule connector\n this.addActionCallToFlow(flowObj, ruleLogger);\n\n // Update the rule's connector to point to our logger\n // We're inside a forEach callback, so we have to modify the original object\n /* eslint-disable no-param-reassign */\n rule.connector.targetReference = ruleLogger.name;\n /* eslint-enable no-param-reassign */\n });\n }\n });\n }\n\n // Helper to add action calls to the flow object\n // Note: This method does modify the parameter directly - we accepted the eslint warning\n // since we need to modify the flow object within callback functions where returning a new value isn't possible\n private static addActionCallToFlow(flowObj: any, actionCall: any): void {\n /* eslint-disable no-param-reassign */\n if (!flowObj.Flow.actionCalls) {\n flowObj.Flow.actionCalls = actionCall;\n } else if (Array.isArray(flowObj.Flow.actionCalls)) {\n // Add new action at the beginning of the array\n flowObj.Flow.actionCalls.unshift(actionCall);\n } else {\n // If only one action exists, convert to array with new action first\n flowObj.Flow.actionCalls = [actionCall, flowObj.Flow.actionCalls];\n }\n /* eslint-enable no-param-reassign */\n }\n\n // Helper to create a logging action for decision paths\n private static createDecisionPathLogger(\n flowName: string,\n decisionName: string,\n decisionLabel: string,\n outcomeName: string,\n outcomeLabel: string\n ): any {\n const loggerId = this.generateUniqueId();\n\n // Ensure we're working with strings\n const decisionNameStr = String(decisionName);\n const outcomeNameStr = String(outcomeName);\n const decisionLabelStr = String(decisionLabel);\n const outcomeLabelStr = String(outcomeLabel);\n\n // Calculate maximum lengths to stay under 80 characters\n const prefixLength = 'RFLIB_Flow_Logger_Decision_'.length;\n const separatorsLength = 2; // Two underscores\n const maxTotalNameLength = 80 - prefixLength - loggerId.length - separatorsLength;\n\n // Allocate half of available space to each name (decision and outcome)\n const maxIndividualLength = Math.floor(maxTotalNameLength / 2);\n\n // Sanitize names to fit Salesforce naming rules\n const sanitizedDecisionName = this.sanitizeForName(decisionNameStr, maxIndividualLength);\n const sanitizedOutcomeName = this.sanitizeForName(outcomeNameStr, maxIndividualLength);\n\n // Create a name that's guaranteed to be under 80 chars and follow Salesforce rules\n const name = `RFLIB_Flow_Logger_Decision_${sanitizedDecisionName}_${sanitizedOutcomeName}_${loggerId}`;\n\n // Create and truncate the label to ensure it's under 80 chars\n const label = this.truncateLabel(`Log Decision: ${decisionLabelStr} - ${outcomeLabelStr}`);\n\n // Fallback if still too long\n if (name.length > 80) {\n return {\n actionName: 'rflib_LoggerFlowAction',\n actionType: 'apex',\n name: `RFLIBLogDec${loggerId}`,\n label,\n locationX: 176,\n locationY: 50,\n inputParameters: [\n {\n name: 'context',\n value: {\n stringValue: flowName,\n },\n },\n {\n name: 'logLevel',\n value: {\n stringValue: 'INFO',\n },\n },\n {\n name: 'message',\n value: {\n stringValue: `Decision '${decisionLabelStr}' outcome: ${outcomeLabelStr}`,\n },\n },\n ],\n };\n }\n\n return {\n actionName: 'rflib_LoggerFlowAction',\n actionType: 'apex',\n name,\n label,\n locationX: 176,\n locationY: 50,\n inputParameters: [\n {\n name: 'context',\n value: {\n stringValue: flowName,\n },\n },\n {\n name: 'logLevel',\n value: {\n stringValue: 'INFO',\n },\n },\n {\n name: 'message',\n value: {\n stringValue: `Decision '${decisionLabelStr}' outcome: ${outcomeLabelStr}`,\n },\n },\n ],\n };\n }\n\n // Helper to generate unique IDs for new flow elements (compact for 80-char limit)\n // that follow Salesforce Flow Action naming rules\n private static generateUniqueId(): string {\n // Use timestamp in base36 + 4 random chars to keep it short but unique\n // Ensure we don't start with a number or have consecutive/trailing underscores\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 6);\n\n // Combine parts without underscore to avoid potential consecutive underscores\n return `ID${timestamp}${random}`;\n }\n\n // Helper to sanitize and truncate text to fit within the 80-char name limit\n // and to follow Salesforce Flow Action naming rules:\n // - Only alphanumeric characters and underscores\n // - Must begin with a letter\n // - No spaces\n // - No underscore at the end\n // - No consecutive underscores\n private static sanitizeForName(text: string, maxLength: number): string {\n if (!text) {\n return 'X'; // Default to 'X' for empty inputs to ensure we start with a letter\n }\n\n // First, replace any non-alphanumeric characters with underscores\n let sanitized = text.replace(/[^a-zA-Z0-9_]/g, '_');\n\n // Ensure it starts with a letter\n if (!/^[a-zA-Z]/.test(sanitized)) {\n sanitized = 'X' + sanitized;\n }\n\n // Replace consecutive underscores with a single underscore\n sanitized = sanitized.replace(/__+/g, '_');\n\n // Remove trailing underscore if present\n sanitized = sanitized.replace(/_+$/, '');\n\n // If empty after sanitization, return a default value\n if (!sanitized) {\n return 'X';\n }\n\n // Truncate if longer than maxLength\n if (sanitized.length > maxLength) {\n // Truncate and ensure it doesn't end with an underscore\n sanitized = sanitized.substring(0, maxLength).replace(/_+$/, '');\n\n // If we removed trailing underscores and now it's empty or too short, add a fallback\n if (sanitized.length < 1) {\n sanitized = 'X';\n }\n }\n\n return sanitized;\n }\n\n // Helper to truncate label text to fit within the 80-char limit\n private static truncateLabel(label: string, maxLength: number = 80): string {\n if (!label || label.length <= maxLength) {\n return label;\n }\n\n // If text is too long, truncate it and add ellipsis\n return label.substring(0, maxLength - 3) + '...';\n }\n\n // Helper to create a logging action element\n private static createLoggingAction(flowName: string): any {\n const loggerId = this.generateUniqueId();\n\n // Create a name for the flow invocation logger (omit flowName to avoid conflicts)\n const name = `RFLIB_Flow_Logger_${loggerId}`;\n\n // Create and truncate the label to ensure it's under 80 chars\n const label = this.truncateLabel(`Log Flow Invocation: ${flowName}`);\n\n // Verify name length\n if (name.length > 80) {\n // If still too long, use a simpler naming scheme (fallback)\n return {\n actionName: 'rflib_LoggerFlowAction',\n actionType: 'apex',\n name: `RFLIBLogger${loggerId}`,\n label,\n locationX: 176,\n locationY: 50,\n inputParameters: [\n {\n name: 'context',\n value: {\n stringValue: flowName,\n },\n },\n {\n name: 'logLevel',\n value: {\n stringValue: 'INFO',\n },\n },\n {\n name: 'message',\n value: {\n stringValue: `Flow ${flowName} started`,\n },\n },\n ],\n };\n }\n\n return {\n actionName: 'rflib_LoggerFlowAction',\n actionType: 'apex',\n name,\n label,\n locationX: 176,\n locationY: 50,\n inputParameters: [\n {\n name: 'context',\n value: {\n stringValue: flowName,\n },\n },\n {\n name: 'logLevel',\n value: {\n stringValue: 'INFO',\n },\n },\n {\n name: 'message',\n value: {\n stringValue: `Flow ${flowName} started`,\n },\n },\n ],\n };\n }\n\n // Helper to set CanvasMode to AUTO_LAYOUT_CANVAS for better flow layout\n private static setCanvasMode(flowObj: any): void {\n // No longer automatically setting canvas mode - preserve original mode\n if (!flowObj.Flow) {\n return;\n }\n\n // Preserve original processMetadataValues state\n const originalMeta = flowObj.Flow.processMetadataValues;\n const hadProcessMetadataValues = !!originalMeta;\n // Normalize to array\n const metadataValues = !originalMeta\n ? []\n : Array.isArray(originalMeta)\n ? originalMeta\n : [originalMeta];\n\n // Prepare CanvasMode entry\n const canvasModeEntry = {\n name: 'CanvasMode',\n value: {\n stringValue: 'AUTO_LAYOUT_CANVAS'\n }\n };\n // Check if CanvasMode metadata exists\n const canvasModeIndex = metadataValues.findIndex((meta: any) =>\n meta.name === 'CanvasMode'\n );\n\n if (canvasModeIndex === -1) {\n // Add AUTO_LAYOUT_CANVAS entry\n metadataValues.push(canvasModeEntry);\n // Duplicate entry for flows that had no metadata to ensure array output on single entry\n if (!hadProcessMetadataValues) {\n metadataValues.push({\n name: canvasModeEntry.name,\n value: { stringValue: canvasModeEntry.value.stringValue }\n });\n }\n } else {\n metadataValues[canvasModeIndex].value.stringValue = 'AUTO_LAYOUT_CANVAS';\n }\n\n // Assign back the potentially modified array\n /* eslint-disable no-param-reassign */\n flowObj.Flow.processMetadataValues = metadataValues;\n /* eslint-enable no-param-reassign */\n }\n\n // Helper to add variable references to the logging message when available\n private static enhanceLoggingWithVariables(loggingAction: any, flowObj: any): any {\n // Find input variables or parameters that might be useful to log\n const variables = flowObj.Flow.variables || [];\n const inputVariables = Array.isArray(variables)\n ? variables.filter((v: any) => v.isInput === 'true' || v.isCollection === 'true')\n : (variables.isInput === 'true' || variables.isCollection === 'true' ? [variables] : []);\n\n if (inputVariables.length > 0) {\n // Find the message parameter - case insensitive search\n const messageParamIndex = loggingAction.inputParameters.findIndex(\n (p: any) => p.name?.toLowerCase() === 'message'\n );\n\n if (messageParamIndex >= 0) {\n // Enhance the message with variable information\n const varRefs = inputVariables\n .map((v: any) => `${v.name}: {!${v.name}}`)\n .join(', ');\n\n const baseMessage = loggingAction.inputParameters[messageParamIndex];\n const originalMessage = baseMessage.value.stringValue;\n baseMessage.value.stringValue = `${originalMessage} with ${varRefs}`;\n }\n }\n\n return loggingAction;\n }\n}\n\nexport default class RflibLoggingFlowInstrument extends SfCommand<RflibLoggingFlowInstrumentResult> {\n public static readonly summary = messages.getMessage('summary');\n public static readonly description = messages.getMessage('description');\n public static readonly examples = messages.getMessages('examples');\n\n public static readonly flags = {\n sourcepath: Flags.string({\n summary: messages.getMessage('flags.sourcepath.summary'),\n description: messages.getMessage('flags.sourcepath.description'),\n char: 's',\n required: true,\n }),\n dryrun: Flags.boolean({\n summary: messages.getMessage('flags.dryrun.summary'),\n description: messages.getMessage('flags.dryrun.description'),\n char: 'd',\n default: false,\n }),\n 'skip-instrumented': Flags.boolean({\n summary: messages.getMessage('flags.skip-instrumented.summary') || 'Skip flows that already have RFLIB logging',\n description: messages.getMessage('flags.skip-instrumented.description') || 'Do not instrument flows where RFLIB logging is already present',\n default: false,\n }),\n verbose: Flags.boolean({\n summary: messages.getMessage('flags.verbose.summary'),\n description: messages.getMessage('flags.verbose.description'),\n char: 'v',\n default: false,\n }),\n };\n\n private logger!: Logger;\n private readonly stats: RflibLoggingFlowInstrumentResult = {\n processedFiles: 0,\n modifiedFiles: 0,\n modifiedFilePaths: [],\n };\n\n public async run(): Promise<RflibLoggingFlowInstrumentResult> {\n this.logger = await Logger.child(this.ctor.name);\n const startTime = Date.now();\n\n const { flags } = await this.parse(RflibLoggingFlowInstrument);\n const sourcePath = flags.sourcepath;\n const isDryRun = flags.dryrun;\n const skipInstrumented = flags['skip-instrumented'];\n const isVerbose = flags.verbose;\n\n this.log(`Scanning Flow files in ${sourcePath} and sub directories`);\n this.logger.debug(`Dry run mode: ${isDryRun}`);\n this.logger.debug(`Skip instrumented: ${skipInstrumented}`);\n\n this.spinner.start('Running...');\n\n const files = await this.findAllFlowFiles(sourcePath);\n await Promise.all(\n files.map(async (filePath) => {\n await this.instrumentFlowFile(filePath, isDryRun, skipInstrumented, isVerbose);\n })\n );\n\n this.spinner.stop();\n\n const duration = Date.now() - startTime;\n this.logger.debug(`Completed instrumentation in ${duration}ms`);\n\n this.log('\\nInstrumentation complete.');\n this.log(`Processed files: ${this.stats.processedFiles}`);\n this.log(`Modified files: ${this.stats.modifiedFiles}`);\n\n return { ...this.stats };\n }\n\n private async findAllFlowFiles(dirPath: string): Promise<string[]> {\n this.logger.debug(`Scanning directory: ${dirPath}`);\n const entries = await fs.promises.readdir(dirPath, { withFileTypes: true });\n\n const results = await Promise.all(\n entries.map(async (entry) => {\n const filePath = path.join(dirPath, entry.name);\n\n if (entry.isDirectory()) {\n return this.findAllFlowFiles(filePath);\n }\n\n if (entry.name.endsWith('.flow-meta.xml')) {\n return [filePath];\n }\n\n return [];\n })\n );\n\n return results.flat();\n }\n\n private async instrumentFlowFile(filePath: string, isDryRun: boolean, skipInstrumented: boolean, isVerbose: boolean): Promise<void> {\n const flowName = path.basename(filePath, '.flow-meta.xml');\n this.logger.debug(`Processing flow: ${flowName}`);\n\n try {\n this.stats.processedFiles++;\n const content = await fs.promises.readFile(filePath, 'utf8');\n const flowObj = await FlowInstrumentationService.parseFlowContent(content);\n\n // Only instrument flows with supported process types\n if (!FlowInstrumentationService.isSupportedProcessType(flowObj)) {\n this.logger.debug(`Skipping unsupported flow type: ${flowName} (processType=${flowObj?.Flow?.processType || 'undefined'})`);\n return;\n }\n\n // Check if flow already has RFLIB logging and skip if needed\n if (skipInstrumented && FlowInstrumentationService.hasRFLIBLogger(flowObj)) {\n this.logger.info(`Skipping already instrumented flow: ${flowName}`);\n return;\n }\n\n const instrumentedFlow = FlowInstrumentationService.instrumentFlow(flowObj, flowName, skipInstrumented);\n const newContent = FlowInstrumentationService.buildFlowContent(instrumentedFlow);\n\n if (content !== newContent) {\n this.stats.modifiedFiles++;\n this.stats.modifiedFilePaths?.push(filePath);\n if (!isDryRun) {\n await fs.promises.writeFile(filePath, newContent);\n this.logger.info(`Modified: ${filePath}`);\n } else {\n this.logger.info(`Would modify: ${filePath}`);\n if (isVerbose) {\n this.log(`Would modify: ${filePath}`);\n }\n }\n }\n } catch (error) {\n this.logger.error(`Error processing flow ${flowName}`, error);\n throw error;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"instrument.js","sourceRoot":"","sources":["../../../../../src/commands/rflib/logging/flow/instrument.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable sf-plugin/only-extend-SfCommand */\n/* eslint-disable @typescript-eslint/return-await */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { Messages, Logger } from '@salesforce/core';\nimport { SfCommand, Flags } from '@salesforce/sf-plugins-core';\nimport * as xml2js from 'xml2js';\nimport { minimatch } from 'minimatch';\n\nexport type RflibLoggingFlowInstrumentResult = {\n processedFiles: number;\n modifiedFiles: number;\n modifiedFilePaths?: string[];\n};\n\nMessages.importMessagesDirectoryFromMetaUrl(import.meta.url);\nconst messages = Messages.loadMessages('rflib-plugin', 'rflib.logging.flow.instrument');\n\nexport class FlowInstrumentationService {\n private static readonly parser = new xml2js.Parser({\n explicitArray: false,\n preserveChildrenOrder: true,\n xmlns: false\n });\n\n private static readonly builder = new xml2js.Builder({\n xmldec: { version: '1.0', encoding: 'UTF-8' },\n cdata: true,\n renderOpts: {\n pretty: true,\n indent: ' ',\n newline: '\\n'\n }\n });\n\n public static async parseFlowContent(content: string): Promise<any> {\n try {\n return await this.parser.parseStringPromise(content);\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Flow parsing failed: ${error.message}`);\n }\n throw new Error('Flow parsing failed with unknown error');\n }\n }\n\n public static buildFlowContent(flowObj: any): string {\n try {\n if (!flowObj?.Flow) {\n throw new Error('Invalid flow object structure');\n }\n\n // Create a new Flow object with ordered properties\n const orderedFlow = {\n '$': { 'xmlns': 'http://soap.sforce.com/2006/04/metadata' }\n } as Record<string, unknown>;\n\n // Add actionCalls first if it exists\n if (flowObj.Flow.actionCalls) {\n orderedFlow.actionCalls = flowObj.Flow.actionCalls;\n }\n\n // Add all other properties in their original order\n Object.entries(flowObj.Flow as Record<string, unknown>).forEach(([key, value]) => {\n if (key !== 'actionCalls' && key !== '$') {\n orderedFlow[key] = value;\n }\n });\n\n // Use the builder with just the Flow object, not wrapped in another object\n return this.builder.buildObject({ Flow: orderedFlow });\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Flow building failed: ${error.message}`);\n }\n throw new Error('Flow building failed with unknown error');\n }\n }\n\n // Helper to check if flow already contains RFLIB logger\n public static hasRFLIBLogger(flowObj: any): boolean {\n if (!flowObj?.Flow?.actionCalls) {\n return false;\n }\n\n const actionCalls = Array.isArray(flowObj.Flow.actionCalls)\n ? flowObj.Flow.actionCalls\n : [flowObj.Flow.actionCalls];\n\n return actionCalls.some(\n (action: any) =>\n action.actionName === 'rflib:Logger' ||\n action.actionName === 'rflib_LoggerFlowAction' ||\n action.actionName === 'rflib_ApplicationEventLoggerAction' ||\n (action.name && typeof action.name === 'string' && action.name.startsWith('RFLIB_Flow_Logger'))\n );\n }\n\n // Helper to check if flow has a supported process type for instrumentation\n public static isSupportedProcessType(flowObj: any): boolean {\n const processType = flowObj?.Flow?.processType;\n const triggerType = flowObj?.Flow?.start?.triggerType;\n\n return processType === 'Flow' ||\n (processType === 'AutoLaunchedFlow' && triggerType === 'RecordAfterSave');\n }\n\n // Main instrumentation function\n public static instrumentFlow(flowObj: any, flowName: string, skipInstrumented = false): any {\n // Deep clone the object to avoid modifying the original\n const instrumentedFlow = JSON.parse(JSON.stringify(flowObj));\n\n // Skip if already instrumented and skipInstrumented flag is set\n if (skipInstrumented && this.hasRFLIBLogger(instrumentedFlow)) {\n return instrumentedFlow;\n }\n\n // Make sure Flow exists in the object\n if (!instrumentedFlow.Flow) {\n return instrumentedFlow;\n }\n\n // Create logging action element\n let loggingAction = this.createLoggingAction(flowName);\n\n // Add variables to the logging message if available\n loggingAction = this.enhanceLoggingWithVariables(loggingAction, instrumentedFlow);\n\n // Add logging action to actionCalls\n if (!instrumentedFlow.Flow.actionCalls) {\n instrumentedFlow.Flow.actionCalls = loggingAction;\n } else if (Array.isArray(instrumentedFlow.Flow.actionCalls)) {\n instrumentedFlow.Flow.actionCalls.unshift(loggingAction);\n } else {\n instrumentedFlow.Flow.actionCalls = [loggingAction, instrumentedFlow.Flow.actionCalls];\n }\n\n // Find startElementReference or start element and connect logger to it\n if (instrumentedFlow.Flow.startElementReference) {\n // Save the original start reference\n const startNodeReference = instrumentedFlow.Flow.startElementReference;\n\n // Create connector between logger and original start element\n loggingAction.connector = {\n targetReference: startNodeReference\n };\n\n // Update flow startElementReference to point to our logger\n instrumentedFlow.Flow.startElementReference = loggingAction.name;\n } else if (instrumentedFlow.Flow.start?.connector?.targetReference) {\n // Handle flow with start element: create connector and update start reference\n const startElement = instrumentedFlow.Flow.start;\n const originalTarget = startElement.connector.targetReference;\n\n // Create connector between logger and the original target\n loggingAction.connector = {\n targetReference: originalTarget\n };\n\n // Update the start element connector to point to our logger\n startElement.connector.targetReference = loggingAction.name;\n }\n\n // Set the CanvasMode to AUTO_LAYOUT_CANVAS\n this.setCanvasMode(instrumentedFlow);\n\n // Instrument decisions with logging for each outcome\n if (instrumentedFlow.Flow.decisions) {\n this.instrumentDecisions(instrumentedFlow, flowName);\n }\n\n // Reorder Flow properties\n const originalFlow = instrumentedFlow.Flow as Record<string, unknown>;\n const orderedFlow: Record<string, unknown> = {\n $: originalFlow.$,\n actionCalls: originalFlow.actionCalls\n };\n\n Object.keys(originalFlow).forEach(key => {\n if (key !== 'actionCalls' && key !== '$') {\n orderedFlow[key] = originalFlow[key];\n }\n });\n\n instrumentedFlow.Flow = orderedFlow;\n return instrumentedFlow;\n }\n\n // Helper to instrument decision paths with logging\n private static instrumentDecisions(flowObj: any, flowName: string): void {\n if (!flowObj.Flow.decisions) {\n return;\n }\n\n // Convert to array if there's only one decision\n const decisions = Array.isArray(flowObj.Flow.decisions)\n ? flowObj.Flow.decisions\n : [flowObj.Flow.decisions];\n\n // Process each decision\n decisions.forEach((decision: any) => {\n // Support decision name as 'name' or legacy 'n'\n const decisionNameRaw = decision.name ?? decision.n;\n if (!decisionNameRaw) {\n return;\n }\n const decisionName = decisionNameRaw;\n const decisionLabel = decision.label || decisionName;\n\n // Process default connector if it exists\n if (decision.defaultConnector?.targetReference) {\n const defaultTarget = decision.defaultConnector.targetReference;\n const defaultConnectorLabel = decision.defaultConnectorLabel || 'Default Outcome';\n\n // Create a logger for the default path\n const defaultLogger = this.createDecisionPathLogger(\n flowName,\n String(decisionName),\n String(decisionLabel),\n 'default',\n String(defaultConnectorLabel)\n );\n\n // Connect logger to the original target\n defaultLogger.connector = {\n targetReference: defaultTarget\n };\n\n // Add logger to actionCalls first, before updating the decision connector\n this.addActionCallToFlow(flowObj, defaultLogger);\n\n // Update the decision's default connector to point to our logger\n // We're inside a forEach callback, so we have to modify the original object\n /* eslint-disable no-param-reassign */\n decision.defaultConnector.targetReference = defaultLogger.name;\n /* eslint-enable no-param-reassign */\n }\n\n // Process each rule if they exist\n if (decision.rules) {\n const rules = Array.isArray(decision.rules) ? decision.rules : [decision.rules];\n\n rules.forEach((rule: any) => {\n // Skip if rule doesn't have a connector or name (support 'name' or legacy 'n')\n const ruleNameRaw = rule.name ?? rule.n;\n if (!rule.connector?.targetReference || !ruleNameRaw) {\n return;\n }\n const ruleTarget = rule.connector.targetReference;\n const ruleName = ruleNameRaw;\n const ruleLabel = rule.label || ruleName;\n\n // Create a logger for this rule outcome\n const ruleLogger = this.createDecisionPathLogger(\n flowName,\n String(decisionName),\n String(decisionLabel),\n String(ruleName),\n String(ruleLabel)\n );\n\n // Connect logger to the original target\n ruleLogger.connector = {\n targetReference: ruleTarget\n };\n\n // Add logger to actionCalls first, before updating the rule connector\n this.addActionCallToFlow(flowObj, ruleLogger);\n\n // Update the rule's connector to point to our logger\n // We're inside a forEach callback, so we have to modify the original object\n /* eslint-disable no-param-reassign */\n rule.connector.targetReference = ruleLogger.name;\n /* eslint-enable no-param-reassign */\n });\n }\n });\n }\n\n // Helper to add action calls to the flow object\n // Note: This method does modify the parameter directly - we accepted the eslint warning\n // since we need to modify the flow object within callback functions where returning a new value isn't possible\n private static addActionCallToFlow(flowObj: any, actionCall: any): void {\n /* eslint-disable no-param-reassign */\n if (!flowObj.Flow.actionCalls) {\n flowObj.Flow.actionCalls = actionCall;\n } else if (Array.isArray(flowObj.Flow.actionCalls)) {\n // Add new action at the beginning of the array\n flowObj.Flow.actionCalls.unshift(actionCall);\n } else {\n // If only one action exists, convert to array with new action first\n flowObj.Flow.actionCalls = [actionCall, flowObj.Flow.actionCalls];\n }\n /* eslint-enable no-param-reassign */\n }\n\n // Helper to create a logging action for decision paths\n private static createDecisionPathLogger(\n flowName: string,\n decisionName: string,\n decisionLabel: string,\n outcomeName: string,\n outcomeLabel: string\n ): any {\n const loggerId = this.generateUniqueId();\n\n // Ensure we're working with strings\n const decisionNameStr = String(decisionName);\n const outcomeNameStr = String(outcomeName);\n const decisionLabelStr = String(decisionLabel);\n const outcomeLabelStr = String(outcomeLabel);\n\n // Calculate maximum lengths to stay under 80 characters\n const prefixLength = 'RFLIB_Flow_Logger_Decision_'.length;\n const separatorsLength = 2; // Two underscores\n const maxTotalNameLength = 80 - prefixLength - loggerId.length - separatorsLength;\n\n // Allocate half of available space to each name (decision and outcome)\n const maxIndividualLength = Math.floor(maxTotalNameLength / 2);\n\n // Sanitize names to fit Salesforce naming rules\n const sanitizedDecisionName = this.sanitizeForName(decisionNameStr, maxIndividualLength);\n const sanitizedOutcomeName = this.sanitizeForName(outcomeNameStr, maxIndividualLength);\n\n // Create a name that's guaranteed to be under 80 chars and follow Salesforce rules\n const name = `RFLIB_Flow_Logger_Decision_${sanitizedDecisionName}_${sanitizedOutcomeName}_${loggerId}`;\n\n // Create and truncate the label to ensure it's under 80 chars\n const label = this.truncateLabel(`Log Decision: ${decisionLabelStr} - ${outcomeLabelStr}`);\n\n // Fallback if still too long\n if (name.length > 80) {\n return {\n actionName: 'rflib_LoggerFlowAction',\n actionType: 'apex',\n name: `RFLIBLogDec${loggerId}`,\n label,\n locationX: 176,\n locationY: 50,\n inputParameters: [\n {\n name: 'context',\n value: {\n stringValue: flowName,\n },\n },\n {\n name: 'logLevel',\n value: {\n stringValue: 'INFO',\n },\n },\n {\n name: 'message',\n value: {\n stringValue: `Decision '${decisionLabelStr}' outcome: ${outcomeLabelStr}`,\n },\n },\n ],\n };\n }\n\n return {\n actionName: 'rflib_LoggerFlowAction',\n actionType: 'apex',\n name,\n label,\n locationX: 176,\n locationY: 50,\n inputParameters: [\n {\n name: 'context',\n value: {\n stringValue: flowName,\n },\n },\n {\n name: 'logLevel',\n value: {\n stringValue: 'INFO',\n },\n },\n {\n name: 'message',\n value: {\n stringValue: `Decision '${decisionLabelStr}' outcome: ${outcomeLabelStr}`,\n },\n },\n ],\n };\n }\n\n // Helper to generate unique IDs for new flow elements (compact for 80-char limit)\n // that follow Salesforce Flow Action naming rules\n private static generateUniqueId(): string {\n // Use timestamp in base36 + 4 random chars to keep it short but unique\n // Ensure we don't start with a number or have consecutive/trailing underscores\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 6);\n\n // Combine parts without underscore to avoid potential consecutive underscores\n return `ID${timestamp}${random}`;\n }\n\n // Helper to sanitize and truncate text to fit within the 80-char name limit\n // and to follow Salesforce Flow Action naming rules:\n // - Only alphanumeric characters and underscores\n // - Must begin with a letter\n // - No spaces\n // - No underscore at the end\n // - No consecutive underscores\n private static sanitizeForName(text: string, maxLength: number): string {\n if (!text) {\n return 'X'; // Default to 'X' for empty inputs to ensure we start with a letter\n }\n\n // First, replace any non-alphanumeric characters with underscores\n let sanitized = text.replace(/[^a-zA-Z0-9_]/g, '_');\n\n // Ensure it starts with a letter\n if (!/^[a-zA-Z]/.test(sanitized)) {\n sanitized = 'X' + sanitized;\n }\n\n // Replace consecutive underscores with a single underscore\n sanitized = sanitized.replace(/__+/g, '_');\n\n // Remove trailing underscore if present\n sanitized = sanitized.replace(/_+$/, '');\n\n // If empty after sanitization, return a default value\n if (!sanitized) {\n return 'X';\n }\n\n // Truncate if longer than maxLength\n if (sanitized.length > maxLength) {\n // Truncate and ensure it doesn't end with an underscore\n sanitized = sanitized.substring(0, maxLength).replace(/_+$/, '');\n\n // If we removed trailing underscores and now it's empty or too short, add a fallback\n if (sanitized.length < 1) {\n sanitized = 'X';\n }\n }\n\n return sanitized;\n }\n\n // Helper to truncate label text to fit within the 80-char limit\n private static truncateLabel(label: string, maxLength: number = 80): string {\n if (!label || label.length <= maxLength) {\n return label;\n }\n\n // If text is too long, truncate it and add ellipsis\n return label.substring(0, maxLength - 3) + '...';\n }\n\n // Helper to create a logging action element\n private static createLoggingAction(flowName: string): any {\n const loggerId = this.generateUniqueId();\n\n // Create a name for the flow invocation logger (omit flowName to avoid conflicts)\n const name = `RFLIB_Flow_Logger_${loggerId}`;\n\n // Create and truncate the label to ensure it's under 80 chars\n const label = this.truncateLabel(`Log Flow Invocation: ${flowName}`);\n\n // Verify name length\n if (name.length > 80) {\n // If still too long, use a simpler naming scheme (fallback)\n return {\n actionName: 'rflib_LoggerFlowAction',\n actionType: 'apex',\n name: `RFLIBLogger${loggerId}`,\n label,\n locationX: 176,\n locationY: 50,\n inputParameters: [\n {\n name: 'context',\n value: {\n stringValue: flowName,\n },\n },\n {\n name: 'logLevel',\n value: {\n stringValue: 'INFO',\n },\n },\n {\n name: 'message',\n value: {\n stringValue: `Flow ${flowName} started`,\n },\n },\n ],\n };\n }\n\n return {\n actionName: 'rflib_LoggerFlowAction',\n actionType: 'apex',\n name,\n label,\n locationX: 176,\n locationY: 50,\n inputParameters: [\n {\n name: 'context',\n value: {\n stringValue: flowName,\n },\n },\n {\n name: 'logLevel',\n value: {\n stringValue: 'INFO',\n },\n },\n {\n name: 'message',\n value: {\n stringValue: `Flow ${flowName} started`,\n },\n },\n ],\n };\n }\n\n // Helper to set CanvasMode to AUTO_LAYOUT_CANVAS for better flow layout\n private static setCanvasMode(flowObj: any): void {\n // No longer automatically setting canvas mode - preserve original mode\n if (!flowObj.Flow) {\n return;\n }\n\n // Preserve original processMetadataValues state\n const originalMeta = flowObj.Flow.processMetadataValues;\n const hadProcessMetadataValues = !!originalMeta;\n // Normalize to array\n const metadataValues = !originalMeta\n ? []\n : Array.isArray(originalMeta)\n ? originalMeta\n : [originalMeta];\n\n // Prepare CanvasMode entry\n const canvasModeEntry = {\n name: 'CanvasMode',\n value: {\n stringValue: 'AUTO_LAYOUT_CANVAS'\n }\n };\n // Check if CanvasMode metadata exists\n const canvasModeIndex = metadataValues.findIndex((meta: any) =>\n meta.name === 'CanvasMode'\n );\n\n if (canvasModeIndex === -1) {\n // Add AUTO_LAYOUT_CANVAS entry\n metadataValues.push(canvasModeEntry);\n // Duplicate entry for flows that had no metadata to ensure array output on single entry\n if (!hadProcessMetadataValues) {\n metadataValues.push({\n name: canvasModeEntry.name,\n value: { stringValue: canvasModeEntry.value.stringValue }\n });\n }\n } else {\n metadataValues[canvasModeIndex].value.stringValue = 'AUTO_LAYOUT_CANVAS';\n }\n\n // Assign back the potentially modified array\n /* eslint-disable no-param-reassign */\n flowObj.Flow.processMetadataValues = metadataValues;\n /* eslint-enable no-param-reassign */\n }\n\n // Helper to add variable references to the logging message when available\n private static enhanceLoggingWithVariables(loggingAction: any, flowObj: any): any {\n // Find input variables or parameters that might be useful to log\n const variables = flowObj.Flow.variables || [];\n const inputVariables = Array.isArray(variables)\n ? variables.filter((v: any) => v.isInput === 'true' || v.isCollection === 'true')\n : (variables.isInput === 'true' || variables.isCollection === 'true' ? [variables] : []);\n\n if (inputVariables.length > 0) {\n // Find the message parameter - case insensitive search\n const messageParamIndex = loggingAction.inputParameters.findIndex(\n (p: any) => p.name?.toLowerCase() === 'message'\n );\n\n if (messageParamIndex >= 0) {\n // Enhance the message with variable information\n const varRefs = inputVariables\n .map((v: any) => `${v.name}: {!${v.name}}`)\n .join(', ');\n\n const baseMessage = loggingAction.inputParameters[messageParamIndex];\n const originalMessage = baseMessage.value.stringValue;\n baseMessage.value.stringValue = `${originalMessage} with ${varRefs}`;\n }\n }\n\n return loggingAction;\n }\n}\n\nexport default class RflibLoggingFlowInstrument extends SfCommand<RflibLoggingFlowInstrumentResult> {\n public static readonly summary = messages.getMessage('summary');\n public static readonly description = messages.getMessage('description');\n public static readonly examples = messages.getMessages('examples');\n\n public static readonly flags = {\n sourcepath: Flags.string({\n summary: messages.getMessage('flags.sourcepath.summary'),\n description: messages.getMessage('flags.sourcepath.description'),\n char: 's',\n required: true,\n }),\n dryrun: Flags.boolean({\n summary: messages.getMessage('flags.dryrun.summary'),\n description: messages.getMessage('flags.dryrun.description'),\n char: 'd',\n default: false,\n }),\n 'skip-instrumented': Flags.boolean({\n summary: messages.getMessage('flags.skip-instrumented.summary') || 'Skip flows that already have RFLIB logging',\n description: messages.getMessage('flags.skip-instrumented.description') || 'Do not instrument flows where RFLIB logging is already present',\n default: false,\n }),\n verbose: Flags.boolean({\n summary: messages.getMessage('flags.verbose.summary'),\n description: messages.getMessage('flags.verbose.description'),\n char: 'v',\n default: false,\n }),\n exclude: Flags.string({\n summary: messages.getMessage('flags.exclude.summary'),\n description: messages.getMessage('flags.exclude.description'),\n char: 'e',\n }),\n };\n\n private logger!: Logger;\n private readonly stats: RflibLoggingFlowInstrumentResult = {\n processedFiles: 0,\n modifiedFiles: 0,\n modifiedFilePaths: [],\n };\n\n public async run(): Promise<RflibLoggingFlowInstrumentResult> {\n this.logger = await Logger.child(this.ctor.name);\n const startTime = Date.now();\n\n const { flags } = await this.parse(RflibLoggingFlowInstrument);\n const sourcePath = flags.sourcepath;\n const isDryRun = flags.dryrun;\n const skipInstrumented = flags['skip-instrumented'];\n const isVerbose = flags.verbose;\n const excludePattern = flags.exclude;\n\n this.log(`Scanning Flow files in ${sourcePath} and sub directories`);\n this.logger.debug(`Dry run mode: ${isDryRun}`);\n this.logger.debug(`Skip instrumented: ${skipInstrumented}`);\n\n this.spinner.start('Running...');\n\n const files = await this.findAllFlowFiles(sourcePath, excludePattern);\n await Promise.all(\n files.map(async (filePath) => {\n await this.instrumentFlowFile(filePath, isDryRun, skipInstrumented, isVerbose);\n })\n );\n\n this.spinner.stop();\n\n const duration = Date.now() - startTime;\n this.logger.debug(`Completed instrumentation in ${duration}ms`);\n\n this.log('\\nInstrumentation complete.');\n this.log(`Processed files: ${this.stats.processedFiles}`);\n this.log(`Modified files: ${this.stats.modifiedFiles}`);\n\n return { ...this.stats };\n }\n\n private async findAllFlowFiles(dirPath: string, excludePattern?: string): Promise<string[]> {\n this.logger.debug(`Scanning directory: ${dirPath}`);\n const entries = await fs.promises.readdir(dirPath, { withFileTypes: true });\n\n const results = await Promise.all(\n entries.map(async (entry) => {\n const filePath = path.join(dirPath, entry.name);\n\n if (excludePattern && minimatch(filePath, excludePattern, { matchBase: true })) {\n this.logger.debug(`Skipping excluded path: ${filePath}`);\n return [];\n }\n\n if (entry.isDirectory()) {\n return this.findAllFlowFiles(filePath, excludePattern);\n }\n\n if (entry.name.endsWith('.flow-meta.xml')) {\n return [filePath];\n }\n\n return [];\n })\n );\n\n return results.flat();\n }\n\n private async instrumentFlowFile(filePath: string, isDryRun: boolean, skipInstrumented: boolean, isVerbose: boolean): Promise<void> {\n const flowName = path.basename(filePath, '.flow-meta.xml');\n this.logger.debug(`Processing flow: ${flowName}`);\n\n try {\n this.stats.processedFiles++;\n const content = await fs.promises.readFile(filePath, 'utf8');\n const flowObj = await FlowInstrumentationService.parseFlowContent(content);\n\n // Only instrument flows with supported process types\n if (!FlowInstrumentationService.isSupportedProcessType(flowObj)) {\n this.logger.debug(`Skipping unsupported flow type: ${flowName} (processType=${flowObj?.Flow?.processType || 'undefined'})`);\n return;\n }\n\n // Check if flow already has RFLIB logging and skip if needed\n if (skipInstrumented && FlowInstrumentationService.hasRFLIBLogger(flowObj)) {\n this.logger.info(`Skipping already instrumented flow: ${flowName}`);\n return;\n }\n\n const instrumentedFlow = FlowInstrumentationService.instrumentFlow(flowObj, flowName, skipInstrumented);\n const newContent = FlowInstrumentationService.buildFlowContent(instrumentedFlow);\n\n if (content !== newContent) {\n this.stats.modifiedFiles++;\n this.stats.modifiedFilePaths?.push(filePath);\n if (!isDryRun) {\n await fs.promises.writeFile(filePath, newContent);\n this.logger.info(`Modified: ${filePath}`);\n } else {\n this.logger.info(`Would modify: ${filePath}`);\n if (isVerbose) {\n this.log(`Would modify: ${filePath}`);\n }\n }\n }\n } catch (error) {\n this.logger.error(`Error processing flow ${flowName}`, error);\n throw error;\n }\n }\n}\n"]}
|
|
@@ -16,6 +16,7 @@ export default class RflibLoggingLwcInstrument extends SfCommand<RflibLoggingLwc
|
|
|
16
16
|
'no-if': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
17
17
|
'skip-instrumented': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
18
18
|
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
19
|
+
exclude: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
19
20
|
};
|
|
20
21
|
private logger;
|
|
21
22
|
private readonly stats;
|
|
@@ -4,6 +4,7 @@ import * as path from 'node:path';
|
|
|
4
4
|
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
|
|
5
5
|
import { Messages, Logger } from '@salesforce/core';
|
|
6
6
|
import * as prettier from 'prettier';
|
|
7
|
+
import { minimatch } from 'minimatch';
|
|
7
8
|
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
8
9
|
const messages = Messages.loadMessages('rflib-plugin', 'rflib.logging.lwc.instrument');
|
|
9
10
|
class LwcInstrumentationService {
|
|
@@ -198,6 +199,11 @@ export default class RflibLoggingLwcInstrument extends SfCommand {
|
|
|
198
199
|
char: 'v',
|
|
199
200
|
default: false,
|
|
200
201
|
}),
|
|
202
|
+
exclude: Flags.string({
|
|
203
|
+
summary: messages.getMessage('flags.exclude.summary'),
|
|
204
|
+
description: messages.getMessage('flags.exclude.description'),
|
|
205
|
+
char: 'e',
|
|
206
|
+
}),
|
|
201
207
|
};
|
|
202
208
|
logger;
|
|
203
209
|
stats = {
|
|
@@ -214,10 +220,11 @@ export default class RflibLoggingLwcInstrument extends SfCommand {
|
|
|
214
220
|
noIf: flags['no-if'],
|
|
215
221
|
skipInstrumented: flags['skip-instrumented'],
|
|
216
222
|
verbose: flags.verbose,
|
|
223
|
+
exclude: flags.exclude,
|
|
217
224
|
};
|
|
218
225
|
this.log(`Scanning LWC components in ${flags.sourcepath}...`);
|
|
219
226
|
this.spinner.start('Running...');
|
|
220
|
-
const files = await this.findAllLwcFiles(flags.sourcepath);
|
|
227
|
+
const files = await this.findAllLwcFiles(flags.sourcepath, instrumentationOpts.exclude);
|
|
221
228
|
await Promise.all(files.map(async (filePath) => {
|
|
222
229
|
await this.instrumentLwcFile(filePath, flags.dryrun, instrumentationOpts);
|
|
223
230
|
}));
|
|
@@ -228,13 +235,17 @@ export default class RflibLoggingLwcInstrument extends SfCommand {
|
|
|
228
235
|
this.log(`Formatted files: ${this.stats.formattedFiles}`);
|
|
229
236
|
return { ...this.stats };
|
|
230
237
|
}
|
|
231
|
-
async findAllLwcFiles(dirPath) {
|
|
238
|
+
async findAllLwcFiles(dirPath, excludePattern) {
|
|
232
239
|
this.logger.debug(`Scanning directory: ${dirPath}`);
|
|
233
240
|
const entries = await fs.promises.readdir(dirPath, { withFileTypes: true });
|
|
234
241
|
const results = await Promise.all(entries.map(async (entry) => {
|
|
235
242
|
const filePath = path.join(dirPath, entry.name);
|
|
243
|
+
if (excludePattern && minimatch(filePath, excludePattern, { matchBase: true })) {
|
|
244
|
+
this.logger.debug(`Skipping excluded path: ${filePath}`);
|
|
245
|
+
return [];
|
|
246
|
+
}
|
|
236
247
|
if (entry.isDirectory()) {
|
|
237
|
-
return this.findAllLwcFiles(filePath);
|
|
248
|
+
return this.findAllLwcFiles(filePath, excludePattern);
|
|
238
249
|
}
|
|
239
250
|
const parentDir = path.dirname(filePath);
|
|
240
251
|
if (entry.name.endsWith('.js') &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrument.js","sourceRoot":"","sources":["../../../../../src/commands/rflib/logging/lwc/instrument.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-await-in-loop */\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { SfCommand, Flags } from '@salesforce/sf-plugins-core';\nimport { Messages, Logger } from '@salesforce/core';\nimport * as prettier from 'prettier';\n\ntype InstrumentationOptions = {\n readonly prettier: boolean;\n readonly noIf: boolean;\n readonly skipInstrumented: boolean;\n readonly verbose: boolean;\n}\n\ntype LoggerInfo = {\n readonly exists: boolean;\n readonly variableName: string;\n}\n\ntype IfCondition = {\n readonly condition: string;\n readonly position: number;\n}\n\nexport type RflibLoggingLwcInstrumentResult = {\n processedFiles: number;\n modifiedFiles: number;\n formattedFiles: number;\n modifiedFilePaths?: string[];\n}\n\nMessages.importMessagesDirectoryFromMetaUrl(import.meta.url);\nconst messages = Messages.loadMessages('rflib-plugin', 'rflib.logging.lwc.instrument');\n\nclass LwcInstrumentationService {\n private static readonly IMPORT_REGEX = /import\\s*{\\s*createLogger\\s*}\\s*from\\s*['\"]c\\/rflibLogger['\"]/;\n private static readonly LOGGER_REGEX = /const\\s+(\\w+)\\s*=\\s*createLogger\\s*\\(['\"]([\\w-]+)['\"]\\)/;\n private static readonly METHOD_REGEX =\n /(?:async\\s+)?(?!(?:if|switch|case|while|for|catch)\\b)(\\b\\w+)\\s*\\((.*?)\\)\\s*{/g;\n private static readonly EXPORT_DEFAULT_REGEX = /export\\s+default\\s+class\\s+(\\w+)/;\n private static readonly IF_STATEMENT_REGEX =\n /if\\s*\\((.*?)\\)\\s*(?:{([^]*?(?:(?<!{){(?:[^]*?)}(?!})[^]*?)*)}|([^{].*?)(?=\\s*(?:;|$));)/g;\n private static readonly ELSE_REGEX =\n /}\\s*else(?!\\s+if\\b)\\s*(?:{((?:[^{}]|{(?:[^{}]|{[^{}]*})*})*)}|([^{].*?)(?=\\n|;|$))/g;\n private static readonly PROMISE_CHAIN_REGEX =\n /\\.(then|catch|finally)\\s*\\(\\s*(?:async\\s+)?(?:\\(?([^)]*)\\)?)?\\s*=>\\s*(?:\\{((?:[^{}]|`[^`]*`)*?)\\}|([^{;]*?(?:\\.[^{;]*?)*(?:\\([^)]*\\))?)(?=\\s*(?:\\)\\)|\\.|\\))))/g;\n private static readonly TRY_CATCH_BLOCK_REGEX = /try\\s*{[\\s\\S]*?}\\s*catch\\s*\\(([^)]*)\\)\\s*{/g;\n private static readonly CONSOLE_LOG_REGEX = /console\\.(log|debug|info|warn|error)\\s*\\(\\s*([^)]+)\\s*\\)\\s*;?/g;\n\n private static readonly PRETTIER_CONFIG: prettier.Options = {\n parser: 'babel',\n printWidth: 120,\n tabWidth: 4,\n useTabs: false,\n singleQuote: true,\n };\n\n public static async formatContent(content: string): Promise<string> {\n try {\n return await prettier.format(content, this.PRETTIER_CONFIG);\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Formatting failed: ${error.message}`);\n }\n throw new Error('Formatting failed with unknown error');\n }\n }\n\n public static isInstrumented(content: string): boolean {\n return this.IMPORT_REGEX.test(content);\n }\n\n public static detectLogger(content: string): LoggerInfo {\n const match = content.match(this.LOGGER_REGEX);\n return {\n exists: match !== null,\n variableName: match ? match[1] : 'logger',\n };\n }\n\n public static addImportAndLogger(content: string, componentName: string): string {\n let modified = content;\n\n if (!this.IMPORT_REGEX.test(content)) {\n modified = `import { createLogger } from 'c/rflibLogger';\\n${modified}`;\n }\n\n const { exists, variableName } = this.detectLogger(content);\n if (!exists) {\n const exportMatch = content.match(this.EXPORT_DEFAULT_REGEX);\n const className = exportMatch ? exportMatch[1] : componentName;\n const loggerDeclaration = `\\nconst ${variableName} = createLogger('${className}');\\n`;\n modified = modified.replace(this.EXPORT_DEFAULT_REGEX, `${loggerDeclaration}$&`);\n }\n\n return modified;\n }\n\n public static processIfStatements(content: string, loggerName: string): string {\n const conditions: IfCondition[] = [];\n\n let modified = content.replace(\n this.IF_STATEMENT_REGEX,\n (match: string, condition: string, blockBody: string, singleLineBody: string, offset: number) => {\n const cleanedUpCondition = condition.trim().replaceAll(\"'\", \"\\\\'\");\n conditions.push({ condition: cleanedUpCondition, position: offset });\n\n const logStatement = `${loggerName}.debug('if (${cleanedUpCondition})');\\n `;\n\n if (blockBody) {\n return `if (${condition}) {\\n ${logStatement}${blockBody}}`;\n } else if (singleLineBody) {\n const cleanBody = singleLineBody.replace(/;$/, '').trim();\n return `if (${condition}) {\\n ${logStatement}${cleanBody};\\n }`;\n }\n return match;\n },\n );\n\n modified = modified.replace(\n this.ELSE_REGEX,\n (match: string, blockBody: string, singleLineBody: string, offset: number) => {\n const nearestIf = conditions\n .filter((c) => c.position <= (offset ?? 0))\n .reduce((prev, curr) => (!prev || curr.position > prev.position ? curr : prev));\n\n const logStatement = nearestIf\n ? `${loggerName}.debug('else for if (${nearestIf.condition})');\\n `\n : `${loggerName}.debug('else statement');\\n `;\n\n if (blockBody) {\n return `} else {\\n ${logStatement}${blockBody}}`;\n } else if (singleLineBody) {\n return `} else {\\n ${logStatement}${singleLineBody};\\n }`;\n }\n return match;\n },\n );\n\n return modified;\n }\n\n public static processMethodLogging(content: string, loggerName: string, options: InstrumentationOptions): string {\n let modified = content.replace(this.METHOD_REGEX, (match: string, methodName: string, args: string) => {\n const parameters = args\n .split(',')\n .map((p) => p.trim())\n .filter((p) => p);\n const placeholders = parameters.map((_, i) => `{${i}}`).join(', ');\n const logArgs = parameters.length > 0 ? `, ${parameters.join(', ')}` : '';\n\n return `${match}\\n ${loggerName}.info('${methodName}(${placeholders})'${logArgs});`;\n });\n\n if (!options.noIf) {\n modified = this.processIfStatements(modified, loggerName);\n }\n\n return modified;\n }\n\n public static processTryCatchBlocks(content: string, loggerName: string): string {\n return content.replace(this.TRY_CATCH_BLOCK_REGEX, (match: string, exceptionVar: string, offset: number) => {\n const methodName = this.findEnclosingMethod(content, offset);\n const errorVar = exceptionVar.trim().split(' ')[0] || 'error';\n\n return match.replace(\n /catch\\s*\\(([^)]*)\\)\\s*{/,\n `catch(${exceptionVar}) {\n ${loggerName}.error('An error occurred in function ${methodName}()', ${errorVar});`,\n );\n });\n }\n\n public static processPromiseChains(content: string, loggerName: string): string {\n return content.replace(\n this.PROMISE_CHAIN_REGEX,\n (match, type, param, blockBody, singleLineBody, offset: number) => {\n const methodName = this.findEnclosingMethod(content, offset);\n const paramName = typeof param === 'string' ? param.trim() : type === 'then' ? 'result' : 'error';\n const indentation = match.match(/\\n\\s*/)?.[0] ?? '\\n ';\n\n let logStatement: string;\n switch (type) {\n case 'then':\n logStatement = `${loggerName}.info('${methodName}() promise resolved. Result={0}', ${paramName});`;\n break;\n case 'catch':\n logStatement = `${loggerName}.error('An error occurred in function ${methodName}()', ${paramName});`;\n break;\n case 'finally':\n logStatement = `${loggerName}.info('${methodName}() promise chain completed');`;\n break;\n default:\n logStatement = '';\n }\n\n if (singleLineBody) {\n const trimmedBody = (singleLineBody as string).trim();\n const adjustedBody =\n trimmedBody.split(')').length > trimmedBody.split('(').length ? trimmedBody.slice(0, -1) : trimmedBody;\n\n return `.${type}((${paramName}) => {\n ${logStatement}\n return ${adjustedBody};\n }`;\n }\n\n if (blockBody) {\n return `.${type}((${paramName}) => {${indentation}${logStatement}${indentation}${blockBody}}`;\n }\n\n return match;\n },\n );\n }\n\n public static processConsoleStatements(methodBody: string, loggerName: string): string {\n return methodBody.replace(this.CONSOLE_LOG_REGEX, (match: string, logType: string, argument: string) => {\n const logLevel = logType === 'info' || logType === 'warn' || logType === 'error' ? logType : 'debug';\n return `${loggerName}.${logLevel}(${argument});`;\n });\n }\n\n private static findEnclosingMethod(content: string, position: number): string {\n const beforeCatch = content.substring(0, position);\n const methods = [...beforeCatch.matchAll(this.METHOD_REGEX)].reverse();\n const closestMethod = methods[0];\n return closestMethod ? closestMethod[1] : 'unknown';\n }\n}\n\nexport default class RflibLoggingLwcInstrument extends SfCommand<RflibLoggingLwcInstrumentResult> {\n public static readonly summary = messages.getMessage('summary');\n public static readonly description = messages.getMessage('description');\n public static readonly examples = messages.getMessages('examples');\n\n public static readonly flags = {\n sourcepath: Flags.string({\n char: 's',\n required: true,\n summary: messages.getMessage('flags.sourcepath.summary'),\n description: messages.getMessage('flags.sourcepath.description'),\n }),\n dryrun: Flags.boolean({\n char: 'd',\n default: false,\n summary: messages.getMessage('flags.dryrun.summary'),\n description: messages.getMessage('flags.dryrun.description'),\n }),\n prettier: Flags.boolean({\n char: 'p',\n default: false,\n summary: messages.getMessage('flags.prettier.summary'),\n description: messages.getMessage('flags.prettier.description'),\n }),\n 'no-if': Flags.boolean({\n summary: messages.getMessage('flags.no-if.summary'),\n description: messages.getMessage('flags.no-if.description'),\n default: false,\n }),\n 'skip-instrumented': Flags.boolean({\n summary: messages.getMessage('flags.skip-instrumented.summary'),\n description: messages.getMessage('flags.skip-instrumented.description'),\n default: false,\n }),\n verbose: Flags.boolean({\n summary: messages.getMessage('flags.verbose.summary'),\n description: messages.getMessage('flags.verbose.description'),\n char: 'v',\n default: false,\n }),\n };\n\n private logger!: Logger;\n private readonly stats: RflibLoggingLwcInstrumentResult = {\n processedFiles: 0,\n modifiedFiles: 0,\n formattedFiles: 0,\n modifiedFilePaths: [],\n };\n\n public async run(): Promise<RflibLoggingLwcInstrumentResult> {\n this.logger = await Logger.child(this.ctor.name);\n const { flags } = await this.parse(RflibLoggingLwcInstrument);\n\n const instrumentationOpts: InstrumentationOptions = {\n prettier: flags.prettier,\n noIf: flags['no-if'],\n skipInstrumented: flags['skip-instrumented'],\n verbose: flags.verbose,\n };\n\n this.log(`Scanning LWC components in ${flags.sourcepath}...`);\n\n this.spinner.start('Running...');\n\n const files = await this.findAllLwcFiles(flags.sourcepath);\n await Promise.all(\n files.map(async (filePath) => {\n await this.instrumentLwcFile(filePath, flags.dryrun, instrumentationOpts);\n })\n );\n\n this.spinner.stop();\n\n this.log('\\nInstrumentation complete.');\n this.log(`Processed files: ${this.stats.processedFiles}`);\n this.log(`Modified files: ${this.stats.modifiedFiles}`);\n this.log(`Formatted files: ${this.stats.formattedFiles}`);\n\n return { ...this.stats };\n }\n\n private async findAllLwcFiles(dirPath: string): Promise<string[]> {\n this.logger.debug(`Scanning directory: ${dirPath}`);\n const entries = await fs.promises.readdir(dirPath, { withFileTypes: true });\n\n const results = await Promise.all(\n entries.map(async (entry) => {\n const filePath = path.join(dirPath, entry.name);\n\n if (entry.isDirectory()) {\n return this.findAllLwcFiles(filePath);\n }\n\n const parentDir = path.dirname(filePath);\n if (\n entry.name.endsWith('.js') &&\n !parentDir.includes('aura') &&\n !parentDir.includes('__tests__')\n ) {\n return [filePath];\n }\n\n return [];\n })\n );\n\n return results.flat();\n }\n\n private async instrumentLwcFile(\n filePath: string,\n isDryRun: boolean,\n instrumentationOpts: InstrumentationOptions,\n ): Promise<void> {\n const componentName = path.basename(path.dirname(filePath));\n this.logger.debug(`Processing LWC: ${componentName}`);\n\n try {\n this.stats.processedFiles++;\n let content = await fs.promises.readFile(filePath, 'utf8');\n const originalContent = content;\n\n if (instrumentationOpts.skipInstrumented && LwcInstrumentationService.isInstrumented(content)) {\n this.logger.info(`Skipping instrumented component: ${componentName}`);\n return;\n }\n\n const { variableName } = LwcInstrumentationService.detectLogger(content);\n content = LwcInstrumentationService.addImportAndLogger(content, componentName);\n content = LwcInstrumentationService.processMethodLogging(content, variableName, instrumentationOpts);\n content = LwcInstrumentationService.processTryCatchBlocks(content, variableName);\n content = LwcInstrumentationService.processPromiseChains(content, variableName);\n content = LwcInstrumentationService.processConsoleStatements(content, variableName);\n\n if (content !== originalContent) {\n this.stats.modifiedFiles++;\n this.stats.modifiedFilePaths?.push(filePath);\n if (!isDryRun) {\n try {\n const finalContent = instrumentationOpts.prettier\n ? await LwcInstrumentationService.formatContent(content)\n : content;\n\n await fs.promises.writeFile(filePath, finalContent);\n\n if (instrumentationOpts.prettier) {\n this.stats.formattedFiles++;\n this.logger.info(`Modified and formatted: ${filePath}`);\n } else {\n this.logger.info(`Modified: ${filePath}`);\n }\n } catch (error) {\n this.logger.warn(`Failed to format ${filePath}: ${error instanceof Error ? error.message : String(error)}`);\n await fs.promises.writeFile(filePath, content);\n this.logger.info(`Modified without formatting: ${filePath}`);\n }\n } else {\n this.logger.info(`Would modify: ${filePath}`);\n if (instrumentationOpts.verbose) {\n this.log(`Would modify: ${filePath}`);\n }\n }\n }\n } catch (error) {\n this.logger.error(`Error processing LWC ${componentName}`, error);\n throw error;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"instrument.js","sourceRoot":"","sources":["../../../../../src/commands/rflib/logging/lwc/instrument.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-await-in-loop */\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { SfCommand, Flags } from '@salesforce/sf-plugins-core';\nimport { Messages, Logger } from '@salesforce/core';\nimport * as prettier from 'prettier';\nimport { minimatch } from 'minimatch';\n\ntype InstrumentationOptions = {\n readonly prettier: boolean;\n readonly noIf: boolean;\n readonly skipInstrumented: boolean;\n readonly verbose: boolean;\n readonly exclude?: string;\n}\n\ntype LoggerInfo = {\n readonly exists: boolean;\n readonly variableName: string;\n}\n\ntype IfCondition = {\n readonly condition: string;\n readonly position: number;\n}\n\nexport type RflibLoggingLwcInstrumentResult = {\n processedFiles: number;\n modifiedFiles: number;\n formattedFiles: number;\n modifiedFilePaths?: string[];\n}\n\nMessages.importMessagesDirectoryFromMetaUrl(import.meta.url);\nconst messages = Messages.loadMessages('rflib-plugin', 'rflib.logging.lwc.instrument');\n\nclass LwcInstrumentationService {\n private static readonly IMPORT_REGEX = /import\\s*{\\s*createLogger\\s*}\\s*from\\s*['\"]c\\/rflibLogger['\"]/;\n private static readonly LOGGER_REGEX = /const\\s+(\\w+)\\s*=\\s*createLogger\\s*\\(['\"]([\\w-]+)['\"]\\)/;\n private static readonly METHOD_REGEX =\n /(?:async\\s+)?(?!(?:if|switch|case|while|for|catch)\\b)(\\b\\w+)\\s*\\((.*?)\\)\\s*{/g;\n private static readonly EXPORT_DEFAULT_REGEX = /export\\s+default\\s+class\\s+(\\w+)/;\n private static readonly IF_STATEMENT_REGEX =\n /if\\s*\\((.*?)\\)\\s*(?:{([^]*?(?:(?<!{){(?:[^]*?)}(?!})[^]*?)*)}|([^{].*?)(?=\\s*(?:;|$));)/g;\n private static readonly ELSE_REGEX =\n /}\\s*else(?!\\s+if\\b)\\s*(?:{((?:[^{}]|{(?:[^{}]|{[^{}]*})*})*)}|([^{].*?)(?=\\n|;|$))/g;\n private static readonly PROMISE_CHAIN_REGEX =\n /\\.(then|catch|finally)\\s*\\(\\s*(?:async\\s+)?(?:\\(?([^)]*)\\)?)?\\s*=>\\s*(?:\\{((?:[^{}]|`[^`]*`)*?)\\}|([^{;]*?(?:\\.[^{;]*?)*(?:\\([^)]*\\))?)(?=\\s*(?:\\)\\)|\\.|\\))))/g;\n private static readonly TRY_CATCH_BLOCK_REGEX = /try\\s*{[\\s\\S]*?}\\s*catch\\s*\\(([^)]*)\\)\\s*{/g;\n private static readonly CONSOLE_LOG_REGEX = /console\\.(log|debug|info|warn|error)\\s*\\(\\s*([^)]+)\\s*\\)\\s*;?/g;\n\n private static readonly PRETTIER_CONFIG: prettier.Options = {\n parser: 'babel',\n printWidth: 120,\n tabWidth: 4,\n useTabs: false,\n singleQuote: true,\n };\n\n public static async formatContent(content: string): Promise<string> {\n try {\n return await prettier.format(content, this.PRETTIER_CONFIG);\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Formatting failed: ${error.message}`);\n }\n throw new Error('Formatting failed with unknown error');\n }\n }\n\n public static isInstrumented(content: string): boolean {\n return this.IMPORT_REGEX.test(content);\n }\n\n public static detectLogger(content: string): LoggerInfo {\n const match = content.match(this.LOGGER_REGEX);\n return {\n exists: match !== null,\n variableName: match ? match[1] : 'logger',\n };\n }\n\n public static addImportAndLogger(content: string, componentName: string): string {\n let modified = content;\n\n if (!this.IMPORT_REGEX.test(content)) {\n modified = `import { createLogger } from 'c/rflibLogger';\\n${modified}`;\n }\n\n const { exists, variableName } = this.detectLogger(content);\n if (!exists) {\n const exportMatch = content.match(this.EXPORT_DEFAULT_REGEX);\n const className = exportMatch ? exportMatch[1] : componentName;\n const loggerDeclaration = `\\nconst ${variableName} = createLogger('${className}');\\n`;\n modified = modified.replace(this.EXPORT_DEFAULT_REGEX, `${loggerDeclaration}$&`);\n }\n\n return modified;\n }\n\n public static processIfStatements(content: string, loggerName: string): string {\n const conditions: IfCondition[] = [];\n\n let modified = content.replace(\n this.IF_STATEMENT_REGEX,\n (match: string, condition: string, blockBody: string, singleLineBody: string, offset: number) => {\n const cleanedUpCondition = condition.trim().replaceAll(\"'\", \"\\\\'\");\n conditions.push({ condition: cleanedUpCondition, position: offset });\n\n const logStatement = `${loggerName}.debug('if (${cleanedUpCondition})');\\n `;\n\n if (blockBody) {\n return `if (${condition}) {\\n ${logStatement}${blockBody}}`;\n } else if (singleLineBody) {\n const cleanBody = singleLineBody.replace(/;$/, '').trim();\n return `if (${condition}) {\\n ${logStatement}${cleanBody};\\n }`;\n }\n return match;\n },\n );\n\n modified = modified.replace(\n this.ELSE_REGEX,\n (match: string, blockBody: string, singleLineBody: string, offset: number) => {\n const nearestIf = conditions\n .filter((c) => c.position <= (offset ?? 0))\n .reduce((prev, curr) => (!prev || curr.position > prev.position ? curr : prev));\n\n const logStatement = nearestIf\n ? `${loggerName}.debug('else for if (${nearestIf.condition})');\\n `\n : `${loggerName}.debug('else statement');\\n `;\n\n if (blockBody) {\n return `} else {\\n ${logStatement}${blockBody}}`;\n } else if (singleLineBody) {\n return `} else {\\n ${logStatement}${singleLineBody};\\n }`;\n }\n return match;\n },\n );\n\n return modified;\n }\n\n public static processMethodLogging(content: string, loggerName: string, options: InstrumentationOptions): string {\n let modified = content.replace(this.METHOD_REGEX, (match: string, methodName: string, args: string) => {\n const parameters = args\n .split(',')\n .map((p) => p.trim())\n .filter((p) => p);\n const placeholders = parameters.map((_, i) => `{${i}}`).join(', ');\n const logArgs = parameters.length > 0 ? `, ${parameters.join(', ')}` : '';\n\n return `${match}\\n ${loggerName}.info('${methodName}(${placeholders})'${logArgs});`;\n });\n\n if (!options.noIf) {\n modified = this.processIfStatements(modified, loggerName);\n }\n\n return modified;\n }\n\n public static processTryCatchBlocks(content: string, loggerName: string): string {\n return content.replace(this.TRY_CATCH_BLOCK_REGEX, (match: string, exceptionVar: string, offset: number) => {\n const methodName = this.findEnclosingMethod(content, offset);\n const errorVar = exceptionVar.trim().split(' ')[0] || 'error';\n\n return match.replace(\n /catch\\s*\\(([^)]*)\\)\\s*{/,\n `catch(${exceptionVar}) {\n ${loggerName}.error('An error occurred in function ${methodName}()', ${errorVar});`,\n );\n });\n }\n\n public static processPromiseChains(content: string, loggerName: string): string {\n return content.replace(\n this.PROMISE_CHAIN_REGEX,\n (match, type, param, blockBody, singleLineBody, offset: number) => {\n const methodName = this.findEnclosingMethod(content, offset);\n const paramName = typeof param === 'string' ? param.trim() : type === 'then' ? 'result' : 'error';\n const indentation = match.match(/\\n\\s*/)?.[0] ?? '\\n ';\n\n let logStatement: string;\n switch (type) {\n case 'then':\n logStatement = `${loggerName}.info('${methodName}() promise resolved. Result={0}', ${paramName});`;\n break;\n case 'catch':\n logStatement = `${loggerName}.error('An error occurred in function ${methodName}()', ${paramName});`;\n break;\n case 'finally':\n logStatement = `${loggerName}.info('${methodName}() promise chain completed');`;\n break;\n default:\n logStatement = '';\n }\n\n if (singleLineBody) {\n const trimmedBody = (singleLineBody as string).trim();\n const adjustedBody =\n trimmedBody.split(')').length > trimmedBody.split('(').length ? trimmedBody.slice(0, -1) : trimmedBody;\n\n return `.${type}((${paramName}) => {\n ${logStatement}\n return ${adjustedBody};\n }`;\n }\n\n if (blockBody) {\n return `.${type}((${paramName}) => {${indentation}${logStatement}${indentation}${blockBody}}`;\n }\n\n return match;\n },\n );\n }\n\n public static processConsoleStatements(methodBody: string, loggerName: string): string {\n return methodBody.replace(this.CONSOLE_LOG_REGEX, (match: string, logType: string, argument: string) => {\n const logLevel = logType === 'info' || logType === 'warn' || logType === 'error' ? logType : 'debug';\n return `${loggerName}.${logLevel}(${argument});`;\n });\n }\n\n private static findEnclosingMethod(content: string, position: number): string {\n const beforeCatch = content.substring(0, position);\n const methods = [...beforeCatch.matchAll(this.METHOD_REGEX)].reverse();\n const closestMethod = methods[0];\n return closestMethod ? closestMethod[1] : 'unknown';\n }\n}\n\nexport default class RflibLoggingLwcInstrument extends SfCommand<RflibLoggingLwcInstrumentResult> {\n public static readonly summary = messages.getMessage('summary');\n public static readonly description = messages.getMessage('description');\n public static readonly examples = messages.getMessages('examples');\n\n public static readonly flags = {\n sourcepath: Flags.string({\n char: 's',\n required: true,\n summary: messages.getMessage('flags.sourcepath.summary'),\n description: messages.getMessage('flags.sourcepath.description'),\n }),\n dryrun: Flags.boolean({\n char: 'd',\n default: false,\n summary: messages.getMessage('flags.dryrun.summary'),\n description: messages.getMessage('flags.dryrun.description'),\n }),\n prettier: Flags.boolean({\n char: 'p',\n default: false,\n summary: messages.getMessage('flags.prettier.summary'),\n description: messages.getMessage('flags.prettier.description'),\n }),\n 'no-if': Flags.boolean({\n summary: messages.getMessage('flags.no-if.summary'),\n description: messages.getMessage('flags.no-if.description'),\n default: false,\n }),\n 'skip-instrumented': Flags.boolean({\n summary: messages.getMessage('flags.skip-instrumented.summary'),\n description: messages.getMessage('flags.skip-instrumented.description'),\n default: false,\n }),\n verbose: Flags.boolean({\n summary: messages.getMessage('flags.verbose.summary'),\n description: messages.getMessage('flags.verbose.description'),\n char: 'v',\n default: false,\n }),\n exclude: Flags.string({\n summary: messages.getMessage('flags.exclude.summary'),\n description: messages.getMessage('flags.exclude.description'),\n char: 'e',\n }),\n };\n\n private logger!: Logger;\n private readonly stats: RflibLoggingLwcInstrumentResult = {\n processedFiles: 0,\n modifiedFiles: 0,\n formattedFiles: 0,\n modifiedFilePaths: [],\n };\n\n public async run(): Promise<RflibLoggingLwcInstrumentResult> {\n this.logger = await Logger.child(this.ctor.name);\n const { flags } = await this.parse(RflibLoggingLwcInstrument);\n\n const instrumentationOpts: InstrumentationOptions = {\n prettier: flags.prettier,\n noIf: flags['no-if'],\n skipInstrumented: flags['skip-instrumented'],\n verbose: flags.verbose,\n exclude: flags.exclude,\n };\n\n this.log(`Scanning LWC components in ${flags.sourcepath}...`);\n\n this.spinner.start('Running...');\n\n const files = await this.findAllLwcFiles(flags.sourcepath, instrumentationOpts.exclude);\n await Promise.all(\n files.map(async (filePath) => {\n await this.instrumentLwcFile(filePath, flags.dryrun, instrumentationOpts);\n })\n );\n\n this.spinner.stop();\n\n this.log('\\nInstrumentation complete.');\n this.log(`Processed files: ${this.stats.processedFiles}`);\n this.log(`Modified files: ${this.stats.modifiedFiles}`);\n this.log(`Formatted files: ${this.stats.formattedFiles}`);\n\n return { ...this.stats };\n }\n\n private async findAllLwcFiles(dirPath: string, excludePattern?: string): Promise<string[]> {\n this.logger.debug(`Scanning directory: ${dirPath}`);\n const entries = await fs.promises.readdir(dirPath, { withFileTypes: true });\n\n const results = await Promise.all(\n entries.map(async (entry) => {\n const filePath = path.join(dirPath, entry.name);\n\n if (excludePattern && minimatch(filePath, excludePattern, { matchBase: true })) {\n this.logger.debug(`Skipping excluded path: ${filePath}`);\n return [];\n }\n\n if (entry.isDirectory()) {\n return this.findAllLwcFiles(filePath, excludePattern);\n }\n\n const parentDir = path.dirname(filePath);\n if (\n entry.name.endsWith('.js') &&\n !parentDir.includes('aura') &&\n !parentDir.includes('__tests__')\n ) {\n return [filePath];\n }\n\n return [];\n })\n );\n\n return results.flat();\n }\n\n private async instrumentLwcFile(\n filePath: string,\n isDryRun: boolean,\n instrumentationOpts: InstrumentationOptions,\n ): Promise<void> {\n const componentName = path.basename(path.dirname(filePath));\n this.logger.debug(`Processing LWC: ${componentName}`);\n\n try {\n this.stats.processedFiles++;\n let content = await fs.promises.readFile(filePath, 'utf8');\n const originalContent = content;\n\n if (instrumentationOpts.skipInstrumented && LwcInstrumentationService.isInstrumented(content)) {\n this.logger.info(`Skipping instrumented component: ${componentName}`);\n return;\n }\n\n const { variableName } = LwcInstrumentationService.detectLogger(content);\n content = LwcInstrumentationService.addImportAndLogger(content, componentName);\n content = LwcInstrumentationService.processMethodLogging(content, variableName, instrumentationOpts);\n content = LwcInstrumentationService.processTryCatchBlocks(content, variableName);\n content = LwcInstrumentationService.processPromiseChains(content, variableName);\n content = LwcInstrumentationService.processConsoleStatements(content, variableName);\n\n if (content !== originalContent) {\n this.stats.modifiedFiles++;\n this.stats.modifiedFilePaths?.push(filePath);\n if (!isDryRun) {\n try {\n const finalContent = instrumentationOpts.prettier\n ? await LwcInstrumentationService.formatContent(content)\n : content;\n\n await fs.promises.writeFile(filePath, finalContent);\n\n if (instrumentationOpts.prettier) {\n this.stats.formattedFiles++;\n this.logger.info(`Modified and formatted: ${filePath}`);\n } else {\n this.logger.info(`Modified: ${filePath}`);\n }\n } catch (error) {\n this.logger.warn(`Failed to format ${filePath}: ${error instanceof Error ? error.message : String(error)}`);\n await fs.promises.writeFile(filePath, content);\n this.logger.info(`Modified without formatting: ${filePath}`);\n }\n } else {\n this.logger.info(`Would modify: ${filePath}`);\n if (instrumentationOpts.verbose) {\n this.log(`Would modify: ${filePath}`);\n }\n }\n }\n } catch (error) {\n this.logger.error(`Error processing LWC ${componentName}`, error);\n throw error;\n }\n }\n}\n"]}
|
|
@@ -61,6 +61,14 @@ Enable verbose output.
|
|
|
61
61
|
|
|
62
62
|
When provided with --dryrun, prints the paths of the files that would be modified.
|
|
63
63
|
|
|
64
|
+
# flags.exclude.summary
|
|
65
|
+
|
|
66
|
+
Exclude files or directories from instrumentation based on a glob pattern.
|
|
67
|
+
|
|
68
|
+
# flags.exclude.description
|
|
69
|
+
|
|
70
|
+
Exclude specific files or directories that match the provided glob pattern. For example, use --exclude "**/Generated_*.cls" to skip auto-generated classes.
|
|
71
|
+
|
|
64
72
|
# examples
|
|
65
73
|
|
|
66
74
|
- Add logging statements to all Apex classes in a directory:
|
|
@@ -80,6 +80,14 @@ Enable verbose output.
|
|
|
80
80
|
|
|
81
81
|
When provided with --dryrun, prints the paths of the files that would be modified.
|
|
82
82
|
|
|
83
|
+
# flags.exclude.summary
|
|
84
|
+
|
|
85
|
+
Exclude files or directories from instrumentation based on a glob pattern.
|
|
86
|
+
|
|
87
|
+
# flags.exclude.description
|
|
88
|
+
|
|
89
|
+
Exclude specific files or directories that match the provided glob pattern. For example, use --exclude "**/Generated_*.cmp" to skip auto-generated components.
|
|
90
|
+
|
|
83
91
|
# examples
|
|
84
92
|
|
|
85
93
|
- Add logging to all aura files:
|
|
@@ -46,6 +46,14 @@ Enable verbose output.
|
|
|
46
46
|
|
|
47
47
|
When provided with --dryrun, prints the paths of the files that would be modified.
|
|
48
48
|
|
|
49
|
+
# flags.exclude.summary
|
|
50
|
+
|
|
51
|
+
Exclude files or directories from instrumentation based on a glob pattern.
|
|
52
|
+
|
|
53
|
+
# flags.exclude.description
|
|
54
|
+
|
|
55
|
+
Exclude specific files or directories that match the provided glob pattern. For example, use --exclude "**/Test_*.flow-meta.xml" to skip certain flows.
|
|
56
|
+
|
|
49
57
|
# examples
|
|
50
58
|
|
|
51
59
|
- <%= config.bin %> <%= command.id %> --sourcepath force-app
|
|
@@ -74,6 +74,14 @@ Enable verbose output.
|
|
|
74
74
|
|
|
75
75
|
When provided with --dryrun, prints the paths of the files that would be modified.
|
|
76
76
|
|
|
77
|
+
# flags.exclude.summary
|
|
78
|
+
|
|
79
|
+
Exclude files or directories from instrumentation based on a glob pattern.
|
|
80
|
+
|
|
81
|
+
# flags.exclude.description
|
|
82
|
+
|
|
83
|
+
Exclude specific files or directories that match the provided glob pattern. For example, use --exclude "**/Generated_*.js" to skip auto-generated components.
|
|
84
|
+
|
|
77
85
|
# examples
|
|
78
86
|
|
|
79
87
|
- Add logging to all LWC files:
|