rflib-plugin 0.14.0 → 0.16.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 +2 -0
- package/lib/commands/rflib/logging/apex/instrument.js +23 -5
- package/lib/commands/rflib/logging/apex/instrument.js.map +1 -1
- package/lib/commands/rflib/logging/aura/instrument.d.ts +2 -0
- package/lib/commands/rflib/logging/aura/instrument.js +35 -10
- package/lib/commands/rflib/logging/aura/instrument.js.map +1 -1
- package/lib/commands/rflib/logging/flow/instrument.d.ts +2 -0
- package/lib/commands/rflib/logging/flow/instrument.js +23 -5
- package/lib/commands/rflib/logging/flow/instrument.js.map +1 -1
- package/lib/commands/rflib/logging/lwc/instrument.d.ts +2 -0
- package/lib/commands/rflib/logging/lwc/instrument.js +23 -5
- package/lib/commands/rflib/logging/lwc/instrument.js.map +1 -1
- package/lib/shared/concurrency.d.ts +1 -0
- package/lib/shared/concurrency.js +16 -0
- package/lib/shared/concurrency.js.map +1 -0
- package/messages/rflib.logging.apex.instrument.md +16 -0
- package/messages/rflib.logging.aura.instrument.md +16 -0
- package/messages/rflib.logging.flow.instrument.md +16 -0
- package/messages/rflib.logging.lwc.instrument.md +16 -0
- package/oclif.lock +132 -131
- package/oclif.manifest.json +147 -71
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -44,6 +44,7 @@ sf rflib logging apex instrument --sourcepath force-app --skip-instrumented
|
|
|
44
44
|
- `--prettier (-p)`: Format modified files using Prettier
|
|
45
45
|
- `--skip-instrumented`: Do not instrument files where RFLIB logging is already present
|
|
46
46
|
- `--verbose (-v)`: Print paths of the files that would be modified (useful with --dryrun)
|
|
47
|
+
- `--exclude (-e)`: Exclude files or directories from instrumentation based on a glob pattern
|
|
47
48
|
|
|
48
49
|
### `sf rflib logging lwc instrument`
|
|
49
50
|
|
|
@@ -70,6 +71,7 @@ sf rflib logging lwc instrument --sourcepath force-app --skip-instrumented
|
|
|
70
71
|
- `--prettier (-p)`: Format modified files using Prettier
|
|
71
72
|
- `--skip-instrumented`: Do not instrument files where RFLIB logging is already present
|
|
72
73
|
- `--verbose (-v)`: Print paths of the files that would be modified (useful with --dryrun)
|
|
74
|
+
- `--exclude (-e)`: Exclude files or directories from instrumentation based on a glob pattern
|
|
73
75
|
|
|
74
76
|
### `sf rflib logging aura instrument`
|
|
75
77
|
|
|
@@ -96,6 +98,7 @@ sf rflib logging aura instrument --sourcepath force-app --skip-instrumented
|
|
|
96
98
|
- `--prettier (-p)`: Format modified files using Prettier
|
|
97
99
|
- `--skip-instrumented`: Do not instrument files where RFLIB logging is already present
|
|
98
100
|
- `--verbose (-v)`: Print paths of the files that would be modified (useful with --dryrun)
|
|
101
|
+
- `--exclude (-e)`: Exclude files or directories from instrumentation based on a glob pattern
|
|
99
102
|
|
|
100
103
|
### `sf rflib logging flow instrument`
|
|
101
104
|
|
|
@@ -118,6 +121,7 @@ sf rflib logging flow instrument --sourcepath force-app --skip-instrumented
|
|
|
118
121
|
- `--dryrun (-d)`: Preview changes without modifying files
|
|
119
122
|
- `--skip-instrumented`: Do not instrument files where RFLIB logging is already present
|
|
120
123
|
- `--verbose (-v)`: Print paths of the files that would be modified (useful with --dryrun)
|
|
124
|
+
- `--exclude (-e)`: Exclude files or directories from instrumentation based on a glob pattern
|
|
121
125
|
|
|
122
126
|
#### Features
|
|
123
127
|
|
|
@@ -16,6 +16,8 @@ export default class RflibLoggingApexInstrument extends SfCommand<RflibLoggingAp
|
|
|
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>;
|
|
20
|
+
concurrency: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
19
21
|
};
|
|
20
22
|
private logger;
|
|
21
23
|
private readonly stats;
|
|
@@ -3,6 +3,8 @@ import * as path from 'node:path';
|
|
|
3
3
|
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
|
|
4
4
|
import { Messages, Logger } from '@salesforce/core';
|
|
5
5
|
import * as prettier from 'prettier';
|
|
6
|
+
import { minimatch } from 'minimatch';
|
|
7
|
+
import { processWithConcurrency } from '../../../../shared/concurrency.js';
|
|
6
8
|
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
7
9
|
const messages = Messages.loadMessages('rflib-plugin', 'rflib.logging.apex.instrument');
|
|
8
10
|
class ApexInstrumentationService {
|
|
@@ -272,6 +274,17 @@ export default class RflibLoggingApexInstrument extends SfCommand {
|
|
|
272
274
|
char: 'v',
|
|
273
275
|
default: false,
|
|
274
276
|
}),
|
|
277
|
+
exclude: Flags.string({
|
|
278
|
+
summary: messages.getMessage('flags.exclude.summary'),
|
|
279
|
+
description: messages.getMessage('flags.exclude.description'),
|
|
280
|
+
char: 'e',
|
|
281
|
+
}),
|
|
282
|
+
concurrency: Flags.integer({
|
|
283
|
+
summary: messages.getMessage('flags.concurrency.summary'),
|
|
284
|
+
description: messages.getMessage('flags.concurrency.description'),
|
|
285
|
+
char: 'c',
|
|
286
|
+
default: 10,
|
|
287
|
+
}),
|
|
275
288
|
};
|
|
276
289
|
logger;
|
|
277
290
|
stats = {
|
|
@@ -291,12 +304,13 @@ export default class RflibLoggingApexInstrument extends SfCommand {
|
|
|
291
304
|
noIf: flags['no-if'],
|
|
292
305
|
skipInstrumented: flags['skip-instrumented'],
|
|
293
306
|
verbose: flags.verbose,
|
|
307
|
+
exclude: flags.exclude,
|
|
294
308
|
};
|
|
295
309
|
this.log(`Scanning Apex classes in ${sourcePath} and sub directories`);
|
|
296
310
|
this.logger.debug(`Dry run mode: ${isDryRun}`);
|
|
297
311
|
this.spinner.start('Running...');
|
|
298
|
-
const files = await this.findAllApexFiles(sourcePath);
|
|
299
|
-
await
|
|
312
|
+
const files = await this.findAllApexFiles(sourcePath, instrumentationOpts.exclude);
|
|
313
|
+
await processWithConcurrency(files, flags.concurrency, async (filePath) => {
|
|
300
314
|
const fileName = path.basename(filePath);
|
|
301
315
|
if (fileName.includes('Test')) {
|
|
302
316
|
await this.processTestFile(filePath, isDryRun, instrumentationOpts);
|
|
@@ -304,7 +318,7 @@ export default class RflibLoggingApexInstrument extends SfCommand {
|
|
|
304
318
|
else {
|
|
305
319
|
await this.instrumentApexClass(filePath, isDryRun, instrumentationOpts);
|
|
306
320
|
}
|
|
307
|
-
})
|
|
321
|
+
});
|
|
308
322
|
this.spinner.stop();
|
|
309
323
|
const duration = Date.now() - startTime;
|
|
310
324
|
this.logger.debug(`Completed instrumentation in ${duration}ms`);
|
|
@@ -314,13 +328,17 @@ export default class RflibLoggingApexInstrument extends SfCommand {
|
|
|
314
328
|
this.log(`Formatted files: ${this.stats.formattedFiles}`);
|
|
315
329
|
return { ...this.stats };
|
|
316
330
|
}
|
|
317
|
-
async findAllApexFiles(dirPath) {
|
|
331
|
+
async findAllApexFiles(dirPath, excludePattern) {
|
|
318
332
|
this.logger.debug(`Scanning directory: ${dirPath}`);
|
|
319
333
|
const entries = await fs.promises.readdir(dirPath, { withFileTypes: true });
|
|
320
334
|
const results = await Promise.all(entries.map(async (entry) => {
|
|
321
335
|
const filePath = path.join(dirPath, entry.name);
|
|
336
|
+
if (excludePattern && minimatch(filePath, excludePattern, { matchBase: true })) {
|
|
337
|
+
this.logger.debug(`Skipping excluded path: ${filePath}`);
|
|
338
|
+
return [];
|
|
339
|
+
}
|
|
322
340
|
if (entry.isDirectory()) {
|
|
323
|
-
return this.findAllApexFiles(filePath);
|
|
341
|
+
return this.findAllApexFiles(filePath, excludePattern);
|
|
324
342
|
}
|
|
325
343
|
if (entry.name.endsWith('.cls')) {
|
|
326
344
|
return [filePath];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrument.js","sourceRoot":"","sources":["../../../../../src/commands/rflib/logging/apex/instrument.ts"],"names":[],"mappings":"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","sourcesContent":["import * 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 ApexMethodMatch = {\n auraEnabled?: string;\n access: string;\n isStatic?: string;\n returnType: string;\n methodName: string;\n args: string;\n}\n\ntype IfCondition = {\n condition: string;\n position: number;\n}\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 ProcessedParameters = {\n readonly paramList: readonly string[];\n readonly logArgs: string;\n}\n\nexport type RflibLoggingApexInstrumentResult = {\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.apex.instrument');\n\nclass ApexInstrumentationService {\n public static readonly TEST_SETUP_REGEX =\n /@TestSetup\\s+((public|private|protected|global)s+)?(?:static\\s+)?void\\s+(\\w+)\\s*\\([^)]*\\)\\s*{/g;\n\n private static readonly METHOD_REGEX =\n /(@AuraEnabled\\s*[\\s\\S]*?)?\\b(public|private|protected|global)\\s+(static\\s+)?(?:(\\w+(?:\\s*<(?:[^<>]|<[^<>]*>)*>)?)|void)\\s+(\\w+)\\s*\\(([\\s\\S]*?)\\)\\s*{/g;\n private static readonly CLASS_REGEX = /\\bclass\\s+\\w+\\s*{/;\n private static readonly CLASS_LOGGER_REGEX = /\\bprivate\\s+(?:static\\s+)?(?:final\\s+)?rflib_Logger\\s+(\\w+)\\b/;\n private static readonly GENERIC_ARGS_REGEX = /<[^>]+>/g;\n private static readonly CATCH_REGEX = /catch\\s*\\(\\s*\\w+\\s+(\\w+)\\s*\\)\\s*{/g;\n private static readonly IF_STATEMENT_REGEX =\n /if\\s*\\((.*?)\\)\\s*(?:{([^]*?(?:(?<!{){(?:[^]*?)}(?!})[^]*?)*)}|([^{].*?)(?=\\s*(?:;|$));)/g;\n private static readonly ELSE_REGEX = /\\s*else(?!\\s*if\\b)\\s*(?:{((?:[^{}]|{(?:[^{}]|{[^{}]*})*})*)}|([^{;]*(?:;|$)))/g;\n private static readonly IS_INSTRUMENTED_REGEX = /(\\brflib_Logger\\b|\\brflib_TestUtil\\b)/;\n private static readonly SYSTEM_DEBUG_START_REGEX = /System\\.debug\\s*\\(/g;\n private static readonly LOGGING_LEVEL_REGEX = /^LoggingLevel\\.(\\w+)\\s*,\\s*([\\s\\S]*)$/;\n\n private static readonly PRIMITIVE_TYPES = new Set([\n 'STRING',\n 'INTEGER',\n 'LONG',\n 'DECIMAL',\n 'DOUBLE',\n 'BOOLEAN',\n 'DATE',\n 'DATETIME',\n 'TIME',\n 'ID',\n ]);\n\n private static readonly PRETTIER_CONFIG: prettier.Options = {\n parser: 'apex',\n plugins: ['prettier-plugin-apex'],\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.IS_INSTRUMENTED_REGEX.test(content);\n }\n\n public static detectLogger(content: string): LoggerInfo {\n const match = content.match(this.CLASS_LOGGER_REGEX);\n return {\n exists: this.CLASS_LOGGER_REGEX.test(content),\n variableName: match ? match[1] : 'LOGGER',\n };\n }\n\n public static addLoggerDeclaration(content: string, className: string): string {\n const { exists, variableName } = this.detectLogger(content);\n if (!exists) {\n const loggerDecl = `private static final rflib_Logger ${variableName} = rflib_LoggerUtil.getFactory().createLogger('${className}');`;\n return content.replace(this.CLASS_REGEX, `$&\\n ${loggerDecl}`);\n }\n return content;\n }\n\n public static processMethodDeclarations(content: string, loggerName: string): string {\n return content.replace(this.METHOD_REGEX, (match: string, ...args: unknown[]) => {\n const methodInfo: ApexMethodMatch = {\n auraEnabled: args[0] as string,\n access: args[1] as string,\n isStatic: args[2] as string,\n returnType: args[3] as string,\n methodName: args[4] as string,\n args: args[5] as string,\n };\n\n const { paramList, logArgs } = this.processParameters(methodInfo.args);\n\n return `${match}\\n ${loggerName}.info('${methodInfo.methodName}(${paramList\n .map((_, i) => `{${i}}`)\n .join(', ')})'${logArgs});\\n`;\n });\n }\n\n public static processCatchBlocks(content: string, loggerName: string): string {\n return content.replace(this.CATCH_REGEX, (match: string, exceptionVar: string, offset: number) => {\n const contentBeforeCatch = content.substring(0, offset);\n const methodMatches = [...contentBeforeCatch.matchAll(this.METHOD_REGEX)];\n const lastMethodMatch = methodMatches[methodMatches.length - 1];\n const methodName = lastMethodMatch ? lastMethodMatch[5] : 'unknown';\n\n return `${match}\\n ${loggerName}.error('An error occurred in ${methodName}()', ${exceptionVar.trim()});`;\n });\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({\n condition: cleanedUpCondition,\n position: offset,\n });\n\n const logStatement = `${loggerName}.debug('if (${cleanedUpCondition})');\\n `;\n\n if (blockBody) {\n return `if (${condition}) {\\n ${logStatement}${blockBody}}\\n`;\n } else if (singleLineBody) {\n const cleanBody = singleLineBody.replace(/;$/, '').trim();\n return `if (${condition}) {\\n ${logStatement}${cleanBody};\\n }\\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 processSystemDebugStatements(content: string, loggerName: string): string {\n const debugStartRegex = new RegExp(this.SYSTEM_DEBUG_START_REGEX);\n let match;\n let lastIndex = 0;\n let output = '';\n\n while ((match = debugStartRegex.exec(content)) !== null) {\n output += content.substring(lastIndex, match.index);\n\n const openParenIndex = match.index + match[0].length - 1;\n let depth = 1;\n let i = openParenIndex + 1;\n let inString = false;\n let isEscaped = false;\n\n for (; i < content.length && depth > 0; i++) {\n const char = content[i];\n\n if (inString) {\n if (isEscaped) {\n isEscaped = false;\n } else if (char === '\\\\') {\n isEscaped = true;\n } else if (char === \"'\") {\n inString = false;\n }\n } else if (char === \"'\") {\n inString = true;\n } else if (char === '(') {\n depth++;\n } else if (char === ')') {\n depth--;\n }\n }\n\n if (depth === 0) {\n const closeParenIndex = i - 1;\n const remaining = content.substring(closeParenIndex + 1);\n const semiColonMatch = remaining.match(/^\\s*;/);\n\n if (semiColonMatch) {\n const endOfStatement = closeParenIndex + 1 + semiColonMatch[0].length;\n const args = content.substring(openParenIndex + 1, closeParenIndex);\n const processed = this.transformSystemDebug(args, loggerName);\n output += processed;\n lastIndex = endOfStatement;\n debugStartRegex.lastIndex = endOfStatement;\n } else {\n output += match[0];\n lastIndex = match.index + match[0].length;\n }\n } else {\n output += match[0];\n lastIndex = match.index + match[0].length;\n }\n }\n\n output += content.substring(lastIndex);\n return output;\n }\n\n private static transformSystemDebug(args: string, loggerName: string): string {\n const trimmedArgs = args.trim();\n const levelMatch = trimmedArgs.match(this.LOGGING_LEVEL_REGEX);\n\n if (levelMatch) {\n const level = levelMatch[1].toUpperCase();\n const message = levelMatch[2].trim();\n let method = 'debug';\n\n if (level === 'ERROR') {\n method = 'error';\n } else if (level === 'WARN') {\n method = 'warn';\n } else if (level === 'INFO') {\n method = 'info';\n }\n\n const formattedMessage = message.startsWith(\"'\") ? message : `JSON.serialize(${message})`;\n return `${loggerName}.${method}(${formattedMessage});`;\n }\n\n const formattedArgs = trimmedArgs.startsWith(\"'\") ? trimmedArgs : `JSON.serialize(${trimmedArgs})`;\n return `${loggerName}.debug(${formattedArgs});`;\n }\n\n private static isComplexType(paramType: string): boolean {\n return (\n paramType.includes('<') ||\n paramType.includes('[') ||\n paramType === 'Object' ||\n !this.PRIMITIVE_TYPES.has(paramType.toUpperCase())\n );\n }\n\n private static processParameters(args: string): ProcessedParameters {\n const parameters = args\n ? args\n .replaceAll(this.GENERIC_ARGS_REGEX, '')\n .split(',')\n .map((param) => param.trim())\n : [];\n\n const logArgs =\n parameters.length > 0 && parameters[0] !== ''\n ? `, new Object[] { ${parameters\n .map((p) => {\n const [paramType, ...rest] = p.split(' ');\n const paramName = rest.length > 0 ? rest.join(' ') : paramType;\n return this.isComplexType(paramType) ? `JSON.serialize(${paramName})` : paramName;\n })\n .join(', ')} }`\n : '';\n\n return { paramList: parameters, logArgs };\n }\n}\n\nexport default class RflibLoggingApexInstrument extends SfCommand<RflibLoggingApexInstrumentResult> {\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 prettier: Flags.boolean({\n summary: messages.getMessage('flags.prettier.summary'),\n description: messages.getMessage('flags.prettier.description'),\n char: 'p',\n default: false,\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: RflibLoggingApexInstrumentResult = {\n processedFiles: 0,\n modifiedFiles: 0,\n formattedFiles: 0,\n modifiedFilePaths: [],\n };\n\n public async run(): Promise<RflibLoggingApexInstrumentResult> {\n this.logger = await Logger.child(this.ctor.name);\n const startTime = Date.now();\n\n const { flags } = await this.parse(RflibLoggingApexInstrument);\n const sourcePath = flags.sourcepath;\n const isDryRun = flags.dryrun;\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 Apex classes in ${sourcePath} and sub directories`);\n this.logger.debug(`Dry run mode: ${isDryRun}`);\n\n this.spinner.start('Running...');\n\n const files = await this.findAllApexFiles(sourcePath);\n await Promise.all(\n files.map(async (filePath) => {\n const fileName = path.basename(filePath);\n if (fileName.includes('Test')) {\n await this.processTestFile(filePath, isDryRun, instrumentationOpts);\n } else {\n await this.instrumentApexClass(filePath, isDryRun, instrumentationOpts);\n }\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 this.log(`Formatted files: ${this.stats.formattedFiles}`);\n\n return { ...this.stats };\n }\n\n private async findAllApexFiles(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.findAllApexFiles(filePath);\n }\n\n if (entry.name.endsWith('.cls')) {\n return [filePath];\n }\n\n return [];\n })\n );\n\n return results.flat();\n }\n\n private async processTestFile(\n filePath: string,\n isDryRun: boolean,\n instrumentationOpts: InstrumentationOptions,\n ): Promise<void> {\n this.logger.debug(`Processing test file: ${filePath}`);\n let content = await fs.promises.readFile(filePath, 'utf8');\n const originalContent = content;\n\n if (instrumentationOpts.skipInstrumented && ApexInstrumentationService.isInstrumented(content)) {\n this.logger.info(`Skipping instrumented test class: ${filePath}`);\n return;\n }\n\n content = content.replace(\n ApexInstrumentationService.TEST_SETUP_REGEX,\n (match) => `${match}\\n rflib_TestUtil.prepareLoggerForUnitTests();`,\n );\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 ApexInstrumentationService.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 test file: ${filePath}`);\n } else {\n this.logger.info(`Modified test file: ${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 test file without formatting: ${filePath}`);\n }\n } else {\n this.logger.info(`Would modify test file: ${filePath}`);\n if (instrumentationOpts.verbose) {\n this.log(`Would modify test file: ${filePath}`);\n }\n }\n }\n }\n\n private async instrumentApexClass(\n filePath: string,\n isDryRun: boolean,\n instrumentationOpts: InstrumentationOptions,\n ): Promise<void> {\n const className = path.basename(filePath, '.cls');\n this.logger.debug(`Processing class: ${className}`);\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 && ApexInstrumentationService.isInstrumented(content)) {\n this.logger.info(`Skipping instrumented class: ${className}`);\n return;\n }\n\n const { variableName } = ApexInstrumentationService.detectLogger(content);\n content = ApexInstrumentationService.addLoggerDeclaration(content, className);\n content = ApexInstrumentationService.processMethodDeclarations(content, variableName);\n content = ApexInstrumentationService.processSystemDebugStatements(content, variableName);\n content = ApexInstrumentationService.processCatchBlocks(content, variableName);\n\n if (!instrumentationOpts.noIf) {\n content = ApexInstrumentationService.processIfStatements(content, variableName);\n }\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 ApexInstrumentationService.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 class ${className}`, error);\n throw error;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"instrument.js","sourceRoot":"","sources":["../../../../../src/commands/rflib/logging/apex/instrument.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAyC3E,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,cAAc,EAAE,+BAA+B,CAAC,CAAC;AAExF,MAAM,0BAA0B;IACvB,MAAM,CAAU,gBAAgB,GACrC,gGAAgG,CAAC;IAE3F,MAAM,CAAU,YAAY,GAClC,uJAAuJ,CAAC;IAClJ,MAAM,CAAU,WAAW,GAAG,mBAAmB,CAAC;IAClD,MAAM,CAAU,kBAAkB,GAAG,+DAA+D,CAAC;IACrG,MAAM,CAAU,kBAAkB,GAAG,UAAU,CAAC;IAChD,MAAM,CAAU,WAAW,GAAG,oCAAoC,CAAC;IACnE,MAAM,CAAU,kBAAkB,GACxC,0FAA0F,CAAC;IACrF,MAAM,CAAU,UAAU,GAAG,gFAAgF,CAAC;IAC9G,MAAM,CAAU,qBAAqB,GAAG,uCAAuC,CAAC;IAChF,MAAM,CAAU,wBAAwB,GAAG,qBAAqB,CAAC;IACjE,MAAM,CAAU,mBAAmB,GAAG,uCAAuC,CAAC;IAE9E,MAAM,CAAU,eAAe,GAAG,IAAI,GAAG,CAAC;QAChD,QAAQ;QACR,SAAS;QACT,MAAM;QACN,SAAS;QACT,QAAQ;QACR,SAAS;QACT,MAAM;QACN,UAAU;QACV,MAAM;QACN,IAAI;KACL,CAAC,CAAC;IAEK,MAAM,CAAU,eAAe,GAAqB;QAC1D,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,CAAC,sBAAsB,CAAC;QACjC,UAAU,EAAE,GAAG;QACf,QAAQ,EAAE,CAAC;QACX,OAAO,EAAE,KAAK;QACd,WAAW,EAAE,IAAI;KAClB,CAAC;IAEK,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,OAAe;QAC/C,IAAI,CAAC;YACH,OAAO,MAAM,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAC9D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CAAC,sBAAsB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACzD,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAEM,MAAM,CAAC,cAAc,CAAC,OAAe;QAC1C,OAAO,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAClD,CAAC;IAEM,MAAM,CAAC,YAAY,CAAC,OAAe;QACxC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACrD,OAAO;YACL,MAAM,EAAE,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC;YAC7C,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ;SAC1C,CAAC;IACJ,CAAC;IAEM,MAAM,CAAC,oBAAoB,CAAC,OAAe,EAAE,SAAiB;QACnE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAC5D,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,UAAU,GAAG,qCAAqC,YAAY,kDAAkD,SAAS,KAAK,CAAC;YACrI,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,UAAU,EAAE,CAAC,CAAC;QACpE,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAEM,MAAM,CAAC,yBAAyB,CAAC,OAAe,EAAE,UAAkB;QACzE,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,KAAa,EAAE,GAAG,IAAe,EAAE,EAAE;YAC9E,MAAM,UAAU,GAAoB;gBAClC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAW;gBAC9B,MAAM,EAAE,IAAI,CAAC,CAAC,CAAW;gBACzB,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAW;gBAC3B,UAAU,EAAE,IAAI,CAAC,CAAC,CAAW;gBAC7B,UAAU,EAAE,IAAI,CAAC,CAAC,CAAW;gBAC7B,IAAI,EAAE,IAAI,CAAC,CAAC,CAAW;aACxB,CAAC;YAEF,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAEvE,OAAO,GAAG,KAAK,aAAa,UAAU,UAAU,UAAU,CAAC,UAAU,IAAI,SAAS;iBAC/E,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;iBACvB,IAAI,CAAC,IAAI,CAAC,KAAK,OAAO,MAAM,CAAC;QAClC,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,kBAAkB,CAAC,OAAe,EAAE,UAAkB;QAClE,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,KAAa,EAAE,YAAoB,EAAE,MAAc,EAAE,EAAE;YAC/F,MAAM,kBAAkB,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;YACxD,MAAM,aAAa,GAAG,CAAC,GAAG,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;YAC1E,MAAM,eAAe,GAAG,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAChE,MAAM,UAAU,GAAG,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAEpE,OAAO,GAAG,KAAK,iBAAiB,UAAU,gCAAgC,UAAU,QAAQ,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC;QACtH,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,mBAAmB,CAAC,OAAe,EAAE,UAAkB;QACnE,MAAM,UAAU,GAAkB,EAAE,CAAC;QAErC,IAAI,QAAQ,GAAG,OAAO,CAAC,OAAO,CAC5B,IAAI,CAAC,kBAAkB,EACvB,CAAC,KAAa,EAAE,SAAiB,EAAE,SAAiB,EAAE,cAAsB,EAAE,MAAc,EAAE,EAAE;YAC9F,MAAM,kBAAkB,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACnE,UAAU,CAAC,IAAI,CAAC;gBACd,SAAS,EAAE,kBAAkB;gBAC7B,QAAQ,EAAE,MAAM;aACjB,CAAC,CAAC;YAEH,MAAM,YAAY,GAAG,GAAG,UAAU,eAAe,kBAAkB,gBAAgB,CAAC;YAEpF,IAAI,SAAS,EAAE,CAAC;gBACd,OAAO,OAAO,SAAS,gBAAgB,YAAY,GAAG,SAAS,KAAK,CAAC;YACvE,CAAC;iBAAM,IAAI,cAAc,EAAE,CAAC;gBAC1B,MAAM,SAAS,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC1D,OAAO,OAAO,SAAS,gBAAgB,YAAY,GAAG,SAAS,YAAY,CAAC;YAC9E,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC,CACF,CAAC;QAEF,QAAQ,GAAG,QAAQ,CAAC,OAAO,CACzB,IAAI,CAAC,UAAU,EACf,CAAC,KAAa,EAAE,SAAkB,EAAE,cAAuB,EAAE,MAAe,EAAE,EAAE;YAC9E,MAAM,SAAS,GAAG,UAAU;iBACzB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;iBACzC,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YAElF,MAAM,YAAY,GAAG,SAAS;gBAC5B,CAAC,CAAC,GAAG,UAAU,wBAAwB,SAAS,CAAC,SAAS,gBAAgB;gBAC1E,CAAC,CAAC,GAAG,UAAU,qCAAqC,CAAC;YAEvD,IAAI,SAAS,EAAE,CAAC;gBACd,OAAO,oBAAoB,YAAY,GAAG,SAAS,GAAG,CAAC;YACzD,CAAC;iBAAM,IAAI,cAAc,EAAE,CAAC;gBAC1B,OAAO,oBAAoB,YAAY,GAAG,cAAc,SAAS,CAAC;YACpE,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC,CACF,CAAC;QAEF,OAAO,QAAQ,CAAC;IAClB,CAAC;IAEM,MAAM,CAAC,4BAA4B,CAAC,OAAe,EAAE,UAAkB;QAC5E,MAAM,eAAe,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QAClE,IAAI,KAAK,CAAC;QACV,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,OAAO,CAAC,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACxD,MAAM,IAAI,OAAO,CAAC,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YAEpD,MAAM,cAAc,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YACzD,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,IAAI,CAAC,GAAG,cAAc,GAAG,CAAC,CAAC;YAC3B,IAAI,QAAQ,GAAG,KAAK,CAAC;YACrB,IAAI,SAAS,GAAG,KAAK,CAAC;YAEtB,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC5C,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;gBAExB,IAAI,QAAQ,EAAE,CAAC;oBACb,IAAI,SAAS,EAAE,CAAC;wBACd,SAAS,GAAG,KAAK,CAAC;oBACpB,CAAC;yBAAM,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;wBACzB,SAAS,GAAG,IAAI,CAAC;oBACnB,CAAC;yBAAM,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;wBACxB,QAAQ,GAAG,KAAK,CAAC;oBACnB,CAAC;gBACH,CAAC;qBAAM,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;oBACxB,QAAQ,GAAG,IAAI,CAAC;gBAClB,CAAC;qBAAM,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;oBACxB,KAAK,EAAE,CAAC;gBACV,CAAC;qBAAM,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;oBACxB,KAAK,EAAE,CAAC;gBACV,CAAC;YACH,CAAC;YAED,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gBAChB,MAAM,eAAe,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC9B,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC;gBACzD,MAAM,cAAc,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBAEhD,IAAI,cAAc,EAAE,CAAC;oBACnB,MAAM,cAAc,GAAG,eAAe,GAAG,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;oBACtE,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,cAAc,GAAG,CAAC,EAAE,eAAe,CAAC,CAAC;oBACpE,MAAM,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;oBAC9D,MAAM,IAAI,SAAS,CAAC;oBACpB,SAAS,GAAG,cAAc,CAAC;oBAC3B,eAAe,CAAC,SAAS,GAAG,cAAc,CAAC;gBAC7C,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;oBACnB,SAAS,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;gBAC5C,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;gBACnB,SAAS,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YAC5C,CAAC;QACH,CAAC;QAED,MAAM,IAAI,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACvC,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,MAAM,CAAC,oBAAoB,CAAC,IAAY,EAAE,UAAkB;QAClE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAChC,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAE/D,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YAC1C,MAAM,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACrC,IAAI,MAAM,GAAG,OAAO,CAAC;YAErB,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;gBACtB,MAAM,GAAG,OAAO,CAAC;YACnB,CAAC;iBAAM,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;gBAC5B,MAAM,GAAG,MAAM,CAAC;YAClB,CAAC;iBAAM,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;gBAC5B,MAAM,GAAG,MAAM,CAAC;YAClB,CAAC;YAED,MAAM,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,OAAO,GAAG,CAAC;YAC1F,OAAO,GAAG,UAAU,IAAI,MAAM,IAAI,gBAAgB,IAAI,CAAC;QACzD,CAAC;QAED,MAAM,aAAa,GAAG,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,kBAAkB,WAAW,GAAG,CAAC;QACnG,OAAO,GAAG,UAAU,UAAU,aAAa,IAAI,CAAC;IAClD,CAAC;IAEO,MAAM,CAAC,aAAa,CAAC,SAAiB;QAC5C,OAAO,CACL,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC;YACvB,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC;YACvB,SAAS,KAAK,QAAQ;YACtB,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,CACnD,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,iBAAiB,CAAC,IAAY;QAC3C,MAAM,UAAU,GAAG,IAAI;YACrB,CAAC,CAAC,IAAI;iBACH,UAAU,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,CAAC;iBACvC,KAAK,CAAC,GAAG,CAAC;iBACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAC/B,CAAC,CAAC,EAAE,CAAC;QAEP,MAAM,OAAO,GACX,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,KAAK,EAAE;YAC3C,CAAC,CAAC,oBAAoB,UAAU;iBAC7B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBACT,MAAM,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBAC/D,OAAO,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,kBAAkB,SAAS,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;YACpF,CAAC,CAAC;iBACD,IAAI,CAAC,IAAI,CAAC,IAAI;YACjB,CAAC,CAAC,EAAE,CAAC;QAET,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;IAC5C,CAAC;;AAGH,MAAM,CAAC,OAAO,OAAO,0BAA2B,SAAQ,SAA2C;IAC1F,MAAM,CAAU,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACzD,MAAM,CAAU,WAAW,GAAG,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IACjE,MAAM,CAAU,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAE5D,MAAM,CAAU,KAAK,GAAG;QAC7B,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC;YACvB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,0BAA0B,CAAC;YACxD,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,8BAA8B,CAAC;YAChE,IAAI,EAAE,GAAG;YACT,QAAQ,EAAE,IAAI;SACf,CAAC;QACF,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC;YACpB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,sBAAsB,CAAC;YACpD,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,0BAA0B,CAAC;YAC5D,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,KAAK;SACf,CAAC;QACF,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC;YACtB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,wBAAwB,CAAC;YACtD,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,4BAA4B,CAAC;YAC9D,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,KAAK;SACf,CAAC;QACF,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;YACrB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,qBAAqB,CAAC;YACnD,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,yBAAyB,CAAC;YAC3D,OAAO,EAAE,KAAK;SACf,CAAC;QACF,mBAAmB,EAAE,KAAK,CAAC,OAAO,CAAC;YACjC,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,iCAAiC,CAAC;YAC/D,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,qCAAqC,CAAC;YACvE,OAAO,EAAE,KAAK;SACf,CAAC;QACF,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;YACrB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,uBAAuB,CAAC;YACrD,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,2BAA2B,CAAC;YAC7D,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,KAAK;SACf,CAAC;QACF,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC;YACpB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,uBAAuB,CAAC;YACrD,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,2BAA2B,CAAC;YAC7D,IAAI,EAAE,GAAG;SACV,CAAC;QACF,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC;YACzB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,2BAA2B,CAAC;YACzD,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,+BAA+B,CAAC;YACjE,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,EAAE;SACZ,CAAC;KACH,CAAC;IAEM,MAAM,CAAU;IACP,KAAK,GAAqC;QACzD,cAAc,EAAE,CAAC;QACjB,aAAa,EAAE,CAAC;QAChB,cAAc,EAAE,CAAC;QACjB,iBAAiB,EAAE,EAAE;KACtB,CAAC;IAEK,KAAK,CAAC,GAAG;QACd,IAAI,CAAC,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC/D,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;QACpC,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC;QAE9B,MAAM,mBAAmB,GAA2B;YAClD,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC;YACpB,gBAAgB,EAAE,KAAK,CAAC,mBAAmB,CAAC;YAC5C,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,4BAA4B,UAAU,sBAAsB,CAAC,CAAC;QACvE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,QAAQ,EAAE,CAAC,CAAC;QAE/C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAEjC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,mBAAmB,CAAC,OAAO,CAAC,CAAC;QACnF,MAAM,sBAAsB,CAC1B,KAAK,EACL,KAAK,CAAC,WAAW,EACjB,KAAK,EAAE,QAAQ,EAAE,EAAE;YACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACzC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC9B,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,QAAQ,EAAE,mBAAmB,CAAC,CAAC;YACtE,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,EAAE,mBAAmB,CAAC,CAAC;YAC1E,CAAC;QACH,CAAC,CACF,CAAC;QAEF,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAEpB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,QAAQ,IAAI,CAAC,CAAC;QAEhE,IAAI,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;QACxC,IAAI,CAAC,GAAG,CAAC,oBAAoB,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC;QAC1D,IAAI,CAAC,GAAG,CAAC,mBAAmB,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,GAAG,CAAC,oBAAoB,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC;QAE1D,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,OAAe,EAAE,cAAuB;QACrE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,OAAO,EAAE,CAAC,CAAC;QACpD,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAE5E,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAEhD,IAAI,cAAc,IAAI,SAAS,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;gBAC/E,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,QAAQ,EAAE,CAAC,CAAC;gBACzD,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,OAAO,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;YACzD,CAAC;YAED,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAChC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACpB,CAAC;YAED,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CACH,CAAC;QAEF,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC;IACxB,CAAC;IAEO,KAAK,CAAC,eAAe,CAC3B,QAAgB,EAChB,QAAiB,EACjB,mBAA2C;QAE3C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;QACvD,IAAI,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC3D,MAAM,eAAe,GAAG,OAAO,CAAC;QAEhC,IAAI,mBAAmB,CAAC,gBAAgB,IAAI,0BAA0B,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/F,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qCAAqC,QAAQ,EAAE,CAAC,CAAC;YAClE,OAAO;QACT,CAAC;QAED,OAAO,GAAG,OAAO,CAAC,OAAO,CACvB,0BAA0B,CAAC,gBAAgB,EAC3C,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,uDAAuD,CAC3E,CAAC;QAEF,IAAI,OAAO,KAAK,eAAe,EAAE,CAAC;YAChC,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;YAC3B,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC7C,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,IAAI,CAAC;oBACH,MAAM,YAAY,GAAG,mBAAmB,CAAC,QAAQ;wBAC/C,CAAC,CAAC,MAAM,0BAA0B,CAAC,aAAa,CAAC,OAAO,CAAC;wBACzD,CAAC,CAAC,OAAO,CAAC;oBAEZ,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;oBAEpD,IAAI,mBAAmB,CAAC,QAAQ,EAAE,CAAC;wBACjC,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;wBAC5B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qCAAqC,QAAQ,EAAE,CAAC,CAAC;oBACpE,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uBAAuB,QAAQ,EAAE,CAAC,CAAC;oBACtD,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,QAAQ,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;oBAC5G,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAC/C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0CAA0C,QAAQ,EAAE,CAAC,CAAC;gBACzE,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,2BAA2B,QAAQ,EAAE,CAAC,CAAC;gBACxD,IAAI,mBAAmB,CAAC,OAAO,EAAE,CAAC;oBAChC,IAAI,CAAC,GAAG,CAAC,2BAA2B,QAAQ,EAAE,CAAC,CAAC;gBAClD,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,mBAAmB,CAC/B,QAAgB,EAChB,QAAiB,EACjB,mBAA2C;QAE3C,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,SAAS,EAAE,CAAC,CAAC;QAEpD,IAAI,CAAC;YACH,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;YAC5B,IAAI,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC3D,MAAM,eAAe,GAAG,OAAO,CAAC;YAEhC,IAAI,mBAAmB,CAAC,gBAAgB,IAAI,0BAA0B,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC/F,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,SAAS,EAAE,CAAC,CAAC;gBAC9D,OAAO;YACT,CAAC;YAED,MAAM,EAAE,YAAY,EAAE,GAAG,0BAA0B,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAC1E,OAAO,GAAG,0BAA0B,CAAC,oBAAoB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YAC9E,OAAO,GAAG,0BAA0B,CAAC,yBAAyB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YACtF,OAAO,GAAG,0BAA0B,CAAC,4BAA4B,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YACzF,OAAO,GAAG,0BAA0B,CAAC,kBAAkB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YAE/E,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC;gBAC9B,OAAO,GAAG,0BAA0B,CAAC,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YAClF,CAAC;YAED,IAAI,OAAO,KAAK,eAAe,EAAE,CAAC;gBAChC,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;gBAC3B,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC7C,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,IAAI,CAAC;wBACH,MAAM,YAAY,GAAG,mBAAmB,CAAC,QAAQ;4BAC/C,CAAC,CAAC,MAAM,0BAA0B,CAAC,aAAa,CAAC,OAAO,CAAC;4BACzD,CAAC,CAAC,OAAO,CAAC;wBAEZ,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;wBAEpD,IAAI,mBAAmB,CAAC,QAAQ,EAAE,CAAC;4BACjC,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;4BAC5B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,2BAA2B,QAAQ,EAAE,CAAC,CAAC;wBAC1D,CAAC;6BAAM,CAAC;4BACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,QAAQ,EAAE,CAAC,CAAC;wBAC5C,CAAC;oBACH,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,QAAQ,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;wBAC5G,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;wBAC/C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,QAAQ,EAAE,CAAC,CAAC;oBAC/D,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,QAAQ,EAAE,CAAC,CAAC;oBAC9C,IAAI,mBAAmB,CAAC,OAAO,EAAE,CAAC;wBAChC,IAAI,CAAC,GAAG,CAAC,iBAAiB,QAAQ,EAAE,CAAC,CAAC;oBACxC,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,SAAS,EAAE,EAAE,KAAK,CAAC,CAAC;YAChE,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC","sourcesContent":["import * 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';\nimport { processWithConcurrency } from '../../../../shared/concurrency.js';\n\ntype ApexMethodMatch = {\n auraEnabled?: string;\n access: string;\n isStatic?: string;\n returnType: string;\n methodName: string;\n args: string;\n}\n\ntype IfCondition = {\n condition: string;\n position: number;\n}\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 ProcessedParameters = {\n readonly paramList: readonly string[];\n readonly logArgs: string;\n}\n\nexport type RflibLoggingApexInstrumentResult = {\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.apex.instrument');\n\nclass ApexInstrumentationService {\n public static readonly TEST_SETUP_REGEX =\n /@TestSetup\\s+((public|private|protected|global)s+)?(?:static\\s+)?void\\s+(\\w+)\\s*\\([^)]*\\)\\s*{/g;\n\n private static readonly METHOD_REGEX =\n /(@AuraEnabled\\s*[\\s\\S]*?)?\\b(public|private|protected|global)\\s+(static\\s+)?(?:(\\w+(?:\\s*<(?:[^<>]|<[^<>]*>)*>)?)|void)\\s+(\\w+)\\s*\\(([\\s\\S]*?)\\)\\s*{/g;\n private static readonly CLASS_REGEX = /\\bclass\\s+\\w+\\s*{/;\n private static readonly CLASS_LOGGER_REGEX = /\\bprivate\\s+(?:static\\s+)?(?:final\\s+)?rflib_Logger\\s+(\\w+)\\b/;\n private static readonly GENERIC_ARGS_REGEX = /<[^>]+>/g;\n private static readonly CATCH_REGEX = /catch\\s*\\(\\s*\\w+\\s+(\\w+)\\s*\\)\\s*{/g;\n private static readonly IF_STATEMENT_REGEX =\n /if\\s*\\((.*?)\\)\\s*(?:{([^]*?(?:(?<!{){(?:[^]*?)}(?!})[^]*?)*)}|([^{].*?)(?=\\s*(?:;|$));)/g;\n private static readonly ELSE_REGEX = /\\s*else(?!\\s*if\\b)\\s*(?:{((?:[^{}]|{(?:[^{}]|{[^{}]*})*})*)}|([^{;]*(?:;|$)))/g;\n private static readonly IS_INSTRUMENTED_REGEX = /(\\brflib_Logger\\b|\\brflib_TestUtil\\b)/;\n private static readonly SYSTEM_DEBUG_START_REGEX = /System\\.debug\\s*\\(/g;\n private static readonly LOGGING_LEVEL_REGEX = /^LoggingLevel\\.(\\w+)\\s*,\\s*([\\s\\S]*)$/;\n\n private static readonly PRIMITIVE_TYPES = new Set([\n 'STRING',\n 'INTEGER',\n 'LONG',\n 'DECIMAL',\n 'DOUBLE',\n 'BOOLEAN',\n 'DATE',\n 'DATETIME',\n 'TIME',\n 'ID',\n ]);\n\n private static readonly PRETTIER_CONFIG: prettier.Options = {\n parser: 'apex',\n plugins: ['prettier-plugin-apex'],\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.IS_INSTRUMENTED_REGEX.test(content);\n }\n\n public static detectLogger(content: string): LoggerInfo {\n const match = content.match(this.CLASS_LOGGER_REGEX);\n return {\n exists: this.CLASS_LOGGER_REGEX.test(content),\n variableName: match ? match[1] : 'LOGGER',\n };\n }\n\n public static addLoggerDeclaration(content: string, className: string): string {\n const { exists, variableName } = this.detectLogger(content);\n if (!exists) {\n const loggerDecl = `private static final rflib_Logger ${variableName} = rflib_LoggerUtil.getFactory().createLogger('${className}');`;\n return content.replace(this.CLASS_REGEX, `$&\\n ${loggerDecl}`);\n }\n return content;\n }\n\n public static processMethodDeclarations(content: string, loggerName: string): string {\n return content.replace(this.METHOD_REGEX, (match: string, ...args: unknown[]) => {\n const methodInfo: ApexMethodMatch = {\n auraEnabled: args[0] as string,\n access: args[1] as string,\n isStatic: args[2] as string,\n returnType: args[3] as string,\n methodName: args[4] as string,\n args: args[5] as string,\n };\n\n const { paramList, logArgs } = this.processParameters(methodInfo.args);\n\n return `${match}\\n ${loggerName}.info('${methodInfo.methodName}(${paramList\n .map((_, i) => `{${i}}`)\n .join(', ')})'${logArgs});\\n`;\n });\n }\n\n public static processCatchBlocks(content: string, loggerName: string): string {\n return content.replace(this.CATCH_REGEX, (match: string, exceptionVar: string, offset: number) => {\n const contentBeforeCatch = content.substring(0, offset);\n const methodMatches = [...contentBeforeCatch.matchAll(this.METHOD_REGEX)];\n const lastMethodMatch = methodMatches[methodMatches.length - 1];\n const methodName = lastMethodMatch ? lastMethodMatch[5] : 'unknown';\n\n return `${match}\\n ${loggerName}.error('An error occurred in ${methodName}()', ${exceptionVar.trim()});`;\n });\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({\n condition: cleanedUpCondition,\n position: offset,\n });\n\n const logStatement = `${loggerName}.debug('if (${cleanedUpCondition})');\\n `;\n\n if (blockBody) {\n return `if (${condition}) {\\n ${logStatement}${blockBody}}\\n`;\n } else if (singleLineBody) {\n const cleanBody = singleLineBody.replace(/;$/, '').trim();\n return `if (${condition}) {\\n ${logStatement}${cleanBody};\\n }\\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 processSystemDebugStatements(content: string, loggerName: string): string {\n const debugStartRegex = new RegExp(this.SYSTEM_DEBUG_START_REGEX);\n let match;\n let lastIndex = 0;\n let output = '';\n\n while ((match = debugStartRegex.exec(content)) !== null) {\n output += content.substring(lastIndex, match.index);\n\n const openParenIndex = match.index + match[0].length - 1;\n let depth = 1;\n let i = openParenIndex + 1;\n let inString = false;\n let isEscaped = false;\n\n for (; i < content.length && depth > 0; i++) {\n const char = content[i];\n\n if (inString) {\n if (isEscaped) {\n isEscaped = false;\n } else if (char === '\\\\') {\n isEscaped = true;\n } else if (char === \"'\") {\n inString = false;\n }\n } else if (char === \"'\") {\n inString = true;\n } else if (char === '(') {\n depth++;\n } else if (char === ')') {\n depth--;\n }\n }\n\n if (depth === 0) {\n const closeParenIndex = i - 1;\n const remaining = content.substring(closeParenIndex + 1);\n const semiColonMatch = remaining.match(/^\\s*;/);\n\n if (semiColonMatch) {\n const endOfStatement = closeParenIndex + 1 + semiColonMatch[0].length;\n const args = content.substring(openParenIndex + 1, closeParenIndex);\n const processed = this.transformSystemDebug(args, loggerName);\n output += processed;\n lastIndex = endOfStatement;\n debugStartRegex.lastIndex = endOfStatement;\n } else {\n output += match[0];\n lastIndex = match.index + match[0].length;\n }\n } else {\n output += match[0];\n lastIndex = match.index + match[0].length;\n }\n }\n\n output += content.substring(lastIndex);\n return output;\n }\n\n private static transformSystemDebug(args: string, loggerName: string): string {\n const trimmedArgs = args.trim();\n const levelMatch = trimmedArgs.match(this.LOGGING_LEVEL_REGEX);\n\n if (levelMatch) {\n const level = levelMatch[1].toUpperCase();\n const message = levelMatch[2].trim();\n let method = 'debug';\n\n if (level === 'ERROR') {\n method = 'error';\n } else if (level === 'WARN') {\n method = 'warn';\n } else if (level === 'INFO') {\n method = 'info';\n }\n\n const formattedMessage = message.startsWith(\"'\") ? message : `JSON.serialize(${message})`;\n return `${loggerName}.${method}(${formattedMessage});`;\n }\n\n const formattedArgs = trimmedArgs.startsWith(\"'\") ? trimmedArgs : `JSON.serialize(${trimmedArgs})`;\n return `${loggerName}.debug(${formattedArgs});`;\n }\n\n private static isComplexType(paramType: string): boolean {\n return (\n paramType.includes('<') ||\n paramType.includes('[') ||\n paramType === 'Object' ||\n !this.PRIMITIVE_TYPES.has(paramType.toUpperCase())\n );\n }\n\n private static processParameters(args: string): ProcessedParameters {\n const parameters = args\n ? args\n .replaceAll(this.GENERIC_ARGS_REGEX, '')\n .split(',')\n .map((param) => param.trim())\n : [];\n\n const logArgs =\n parameters.length > 0 && parameters[0] !== ''\n ? `, new Object[] { ${parameters\n .map((p) => {\n const [paramType, ...rest] = p.split(' ');\n const paramName = rest.length > 0 ? rest.join(' ') : paramType;\n return this.isComplexType(paramType) ? `JSON.serialize(${paramName})` : paramName;\n })\n .join(', ')} }`\n : '';\n\n return { paramList: parameters, logArgs };\n }\n}\n\nexport default class RflibLoggingApexInstrument extends SfCommand<RflibLoggingApexInstrumentResult> {\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 prettier: Flags.boolean({\n summary: messages.getMessage('flags.prettier.summary'),\n description: messages.getMessage('flags.prettier.description'),\n char: 'p',\n default: false,\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 concurrency: Flags.integer({\n summary: messages.getMessage('flags.concurrency.summary'),\n description: messages.getMessage('flags.concurrency.description'),\n char: 'c',\n default: 10,\n }),\n };\n\n private logger!: Logger;\n private readonly stats: RflibLoggingApexInstrumentResult = {\n processedFiles: 0,\n modifiedFiles: 0,\n formattedFiles: 0,\n modifiedFilePaths: [],\n };\n\n public async run(): Promise<RflibLoggingApexInstrumentResult> {\n this.logger = await Logger.child(this.ctor.name);\n const startTime = Date.now();\n\n const { flags } = await this.parse(RflibLoggingApexInstrument);\n const sourcePath = flags.sourcepath;\n const isDryRun = flags.dryrun;\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 Apex classes in ${sourcePath} and sub directories`);\n this.logger.debug(`Dry run mode: ${isDryRun}`);\n\n this.spinner.start('Running...');\n\n const files = await this.findAllApexFiles(sourcePath, instrumentationOpts.exclude);\n await processWithConcurrency(\n files,\n flags.concurrency,\n async (filePath) => {\n const fileName = path.basename(filePath);\n if (fileName.includes('Test')) {\n await this.processTestFile(filePath, isDryRun, instrumentationOpts);\n } else {\n await this.instrumentApexClass(filePath, isDryRun, instrumentationOpts);\n }\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 this.log(`Formatted files: ${this.stats.formattedFiles}`);\n\n return { ...this.stats };\n }\n\n private async findAllApexFiles(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.findAllApexFiles(filePath, excludePattern);\n }\n\n if (entry.name.endsWith('.cls')) {\n return [filePath];\n }\n\n return [];\n })\n );\n\n return results.flat();\n }\n\n private async processTestFile(\n filePath: string,\n isDryRun: boolean,\n instrumentationOpts: InstrumentationOptions,\n ): Promise<void> {\n this.logger.debug(`Processing test file: ${filePath}`);\n let content = await fs.promises.readFile(filePath, 'utf8');\n const originalContent = content;\n\n if (instrumentationOpts.skipInstrumented && ApexInstrumentationService.isInstrumented(content)) {\n this.logger.info(`Skipping instrumented test class: ${filePath}`);\n return;\n }\n\n content = content.replace(\n ApexInstrumentationService.TEST_SETUP_REGEX,\n (match) => `${match}\\n rflib_TestUtil.prepareLoggerForUnitTests();`,\n );\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 ApexInstrumentationService.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 test file: ${filePath}`);\n } else {\n this.logger.info(`Modified test file: ${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 test file without formatting: ${filePath}`);\n }\n } else {\n this.logger.info(`Would modify test file: ${filePath}`);\n if (instrumentationOpts.verbose) {\n this.log(`Would modify test file: ${filePath}`);\n }\n }\n }\n }\n\n private async instrumentApexClass(\n filePath: string,\n isDryRun: boolean,\n instrumentationOpts: InstrumentationOptions,\n ): Promise<void> {\n const className = path.basename(filePath, '.cls');\n this.logger.debug(`Processing class: ${className}`);\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 && ApexInstrumentationService.isInstrumented(content)) {\n this.logger.info(`Skipping instrumented class: ${className}`);\n return;\n }\n\n const { variableName } = ApexInstrumentationService.detectLogger(content);\n content = ApexInstrumentationService.addLoggerDeclaration(content, className);\n content = ApexInstrumentationService.processMethodDeclarations(content, variableName);\n content = ApexInstrumentationService.processSystemDebugStatements(content, variableName);\n content = ApexInstrumentationService.processCatchBlocks(content, variableName);\n\n if (!instrumentationOpts.noIf) {\n content = ApexInstrumentationService.processIfStatements(content, variableName);\n }\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 ApexInstrumentationService.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 class ${className}`, error);\n throw error;\n }\n }\n}\n"]}
|
|
@@ -16,6 +16,8 @@ export default class RflibLoggingAuraInstrument extends SfCommand<RflibLoggingAu
|
|
|
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>;
|
|
20
|
+
concurrency: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
19
21
|
};
|
|
20
22
|
private logger;
|
|
21
23
|
private readonly stats;
|
|
@@ -3,6 +3,8 @@ import * as path from 'node:path';
|
|
|
3
3
|
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
|
|
4
4
|
import { Messages, Logger } from '@salesforce/core';
|
|
5
5
|
import * as prettier from 'prettier';
|
|
6
|
+
import { minimatch } from 'minimatch';
|
|
7
|
+
import { processWithConcurrency } from '../../../../shared/concurrency.js';
|
|
6
8
|
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
7
9
|
const messages = Messages.loadMessages('rflib-plugin', 'rflib.logging.aura.instrument');
|
|
8
10
|
class AuraInstrumentationService {
|
|
@@ -169,6 +171,17 @@ export default class RflibLoggingAuraInstrument extends SfCommand {
|
|
|
169
171
|
char: 'v',
|
|
170
172
|
default: false,
|
|
171
173
|
}),
|
|
174
|
+
exclude: Flags.string({
|
|
175
|
+
summary: messages.getMessage('flags.exclude.summary'),
|
|
176
|
+
description: messages.getMessage('flags.exclude.description'),
|
|
177
|
+
char: 'e',
|
|
178
|
+
}),
|
|
179
|
+
concurrency: Flags.integer({
|
|
180
|
+
summary: messages.getMessage('flags.concurrency.summary'),
|
|
181
|
+
description: messages.getMessage('flags.concurrency.description'),
|
|
182
|
+
char: 'c',
|
|
183
|
+
default: 10,
|
|
184
|
+
}),
|
|
172
185
|
};
|
|
173
186
|
logger;
|
|
174
187
|
stats = {
|
|
@@ -185,14 +198,15 @@ export default class RflibLoggingAuraInstrument extends SfCommand {
|
|
|
185
198
|
noIf: flags['no-if'],
|
|
186
199
|
skipInstrumented: flags['skip-instrumented'],
|
|
187
200
|
verbose: flags.verbose,
|
|
201
|
+
exclude: flags.exclude,
|
|
188
202
|
};
|
|
189
203
|
this.log(`Starting Aura component instrumentation in ${flags.sourcepath}`);
|
|
190
204
|
this.logger.debug(`Dry run mode: ${flags.dryrun}`);
|
|
191
205
|
this.spinner.start('Running...');
|
|
192
|
-
const components = await this.findAllAuraComponents(flags.sourcepath);
|
|
193
|
-
await
|
|
206
|
+
const components = await this.findAllAuraComponents(flags.sourcepath, instrumentationOpts.exclude);
|
|
207
|
+
await processWithConcurrency(components, flags.concurrency, async (component) => {
|
|
194
208
|
await this.processAuraComponent(component.path, component.name, flags.dryrun, instrumentationOpts);
|
|
195
|
-
})
|
|
209
|
+
});
|
|
196
210
|
this.spinner.stop();
|
|
197
211
|
this.log('\nInstrumentation complete.');
|
|
198
212
|
this.log(`Processed files: ${this.stats.processedFiles}`);
|
|
@@ -200,12 +214,16 @@ export default class RflibLoggingAuraInstrument extends SfCommand {
|
|
|
200
214
|
this.log(`Formatted files: ${this.stats.formattedFiles}`);
|
|
201
215
|
return { ...this.stats };
|
|
202
216
|
}
|
|
203
|
-
async findAllAuraComponents(dirPath) {
|
|
217
|
+
async findAllAuraComponents(dirPath, excludePattern) {
|
|
204
218
|
this.logger.debug(`Scanning directory: ${dirPath}`);
|
|
205
219
|
const dirName = path.basename(dirPath);
|
|
206
220
|
const parentName = path.basename(path.dirname(dirPath));
|
|
207
221
|
// Case 1: The sourcepath points directly to a component (inside an 'aura' folder)
|
|
208
222
|
if (parentName === 'aura') {
|
|
223
|
+
if (excludePattern && minimatch(dirPath, excludePattern, { matchBase: true })) {
|
|
224
|
+
this.logger.debug(`Skipping excluded path: ${dirPath}`);
|
|
225
|
+
return [];
|
|
226
|
+
}
|
|
209
227
|
return [{
|
|
210
228
|
path: dirPath,
|
|
211
229
|
name: dirName
|
|
@@ -216,17 +234,24 @@ export default class RflibLoggingAuraInstrument extends SfCommand {
|
|
|
216
234
|
const entries = await fs.promises.readdir(dirPath, { withFileTypes: true });
|
|
217
235
|
const components = await Promise.all(entries
|
|
218
236
|
.filter(entry => entry.isDirectory())
|
|
219
|
-
.map(entry =>
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
237
|
+
.map(entry => {
|
|
238
|
+
const cmpPath = path.join(dirPath, entry.name);
|
|
239
|
+
if (excludePattern && minimatch(cmpPath, excludePattern, { matchBase: true })) {
|
|
240
|
+
this.logger.debug(`Skipping excluded path: ${cmpPath}`);
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
return {
|
|
244
|
+
path: cmpPath,
|
|
245
|
+
name: entry.name
|
|
246
|
+
};
|
|
247
|
+
}));
|
|
248
|
+
return components.filter((c) => c !== null);
|
|
224
249
|
}
|
|
225
250
|
// Case 3: Recursion
|
|
226
251
|
const entries = await fs.promises.readdir(dirPath, { withFileTypes: true });
|
|
227
252
|
const results = await Promise.all(entries.map(async (entry) => {
|
|
228
253
|
if (entry.isDirectory()) {
|
|
229
|
-
return this.findAllAuraComponents(path.join(dirPath, entry.name));
|
|
254
|
+
return this.findAllAuraComponents(path.join(dirPath, entry.name), excludePattern);
|
|
230
255
|
}
|
|
231
256
|
return [];
|
|
232
257
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrument.js","sourceRoot":"","sources":["../../../../../src/commands/rflib/logging/aura/instrument.ts"],"names":[],"mappings":"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","sourcesContent":["import * 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 IfCondition = {\n readonly condition: string;\n readonly position: number;\n}\n\ntype InstrumentationOptions = {\n readonly prettier: boolean;\n readonly noIf: boolean;\n readonly skipInstrumented: boolean;\n readonly verbose: boolean;\n}\n\nexport type RflibLoggingAuraInstrumentResult = {\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.aura.instrument');\n\nclass AuraInstrumentationService {\n public static readonly ATTRIBUTE_REGEX = /<aura:attribute[^>]*>/g;\n public static readonly LOGGER_COMPONENT_REGEX =\n /<c:rflibLoggerCmp\\s+aura:id=\"([^\"]+)\"\\s+name=\"([^\"]+)\"\\s+appendComponentId=\"([^\"]+)\"\\s*\\/>/;\n\n private static readonly LOGGER_VAR_REGEX = /var\\s+(\\w+)\\s*=\\s*\\w+\\.find\\(['\"](\\w+)['\"]\\);/;\n private static readonly METHOD_REGEX =\n /(\\b\\w+)\\s*:\\s*function\\s*\\((.*?)\\)\\s*{((?:[^{}]|{(?:[^{}]|{(?:[^{}]|{(?:[^{}]|{(?:[^{}]|{[^{}]*})*})*})*})*})*?)}/g;\n private static readonly PROMISE_CHAIN_REGEX = /\\.(then|catch|finally)\\s*\\(\\s*function\\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 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 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 trailingComma: 'none',\n };\n\n public static isInstrumented(content: string, loggerId: string): boolean {\n return new RegExp(`\\\\.find\\\\(['\"]${loggerId}['\"]\\\\)`, 'g').test(content);\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 processMethodLogging(content: string, loggerId: string, isHelper: boolean, noIf: boolean): string {\n return content.replace(this.METHOD_REGEX, (match: string, methodName: string, params: string, body: string) => {\n const paramList = params\n .split(',')\n .map((p) => p.trim())\n .filter(Boolean);\n let loggerVar = 'logger';\n let bodyContent = body;\n\n const paramsToLog = isHelper ? paramList : paramList.slice(1, 2);\n const placeholders = paramsToLog.map((_, i) => `{${i}}`).join(', ');\n const logParams = paramsToLog.length > 0 ? `, [${paramsToLog.join(', ')}]` : '';\n\n const loggerMatch = body.match(this.LOGGER_VAR_REGEX);\n if (loggerMatch && loggerMatch[2] === loggerId) {\n loggerVar = loggerMatch[1];\n const loggerIndex = body.indexOf(loggerMatch[0]) + loggerMatch[0].length;\n bodyContent = `${body.slice(0, loggerIndex)}\\n ${loggerVar}.info('${methodName}(${placeholders})'${logParams});${body.slice(loggerIndex)}`;\n } else {\n const loggerInit = `var ${loggerVar} = ${paramList[0]}.find('${loggerId}');\\n`;\n bodyContent = `\\n ${loggerInit} ${loggerVar}.info('${methodName}(${placeholders})'${logParams});${body}`;\n }\n\n if (!noIf) {\n bodyContent = this.processIfStatements(bodyContent, loggerVar);\n }\n\n bodyContent = AuraInstrumentationService.processPromiseChains(bodyContent, loggerVar);\n bodyContent = AuraInstrumentationService.processConsoleStatements(bodyContent, loggerVar);\n\n return `${methodName}: function(${params}) {${bodyContent}}`;\n });\n }\n\n public static processPromiseChains(content: string, loggerVar: string): string {\n return content.replace(\n this.PROMISE_CHAIN_REGEX,\n (match: string, type: string, param: string, blockBody: string) => {\n const logStatement = this.processPromiseType(type, param?.trim() || '', loggerVar);\n\n return match.replace(blockBody, `\\n ${logStatement}\\n ${blockBody}`);\n },\n );\n }\n\n public static processTryCatchBlocks(content: string): string {\n return content.replace(this.TRY_CATCH_BLOCK_REGEX, (match: string, exceptionVar: string) => {\n const errorVar = exceptionVar.trim().split(' ')[0] || 'error';\n return match.replace(\n /catch\\s*\\(([^)]*)\\)\\s*{/,\n `catch(${exceptionVar}) {\n logger.error('An error occurred', ${errorVar});`,\n );\n });\n }\n\n private static processPromiseType(type: string, paramName: string, loggerVar: string): string {\n switch (type) {\n case 'then':\n return `${loggerVar}.info('Promise resolved. Result={0}', ${paramName});`;\n case 'catch':\n return `${loggerVar}.error('An error occurred', ${paramName});`;\n case 'finally':\n return `${loggerVar}.info('Promise chain completed');`;\n default:\n throw new Error(`Unsupported promise type: ${type}`);\n }\n }\n\n private 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)\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 private 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\nexport default class RflibLoggingAuraInstrument extends SfCommand<RflibLoggingAuraInstrumentResult> {\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: RflibLoggingAuraInstrumentResult = {\n processedFiles: 0,\n modifiedFiles: 0,\n formattedFiles: 0,\n modifiedFilePaths: [],\n };\n\n public async run(): Promise<RflibLoggingAuraInstrumentResult> {\n this.logger = await Logger.child(this.ctor.name);\n const { flags } = await this.parse(RflibLoggingAuraInstrument);\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(`Starting Aura component instrumentation in ${flags.sourcepath}`);\n this.logger.debug(`Dry run mode: ${flags.dryrun}`);\n\n this.spinner.start('Running...');\n\n const components = await this.findAllAuraComponents(flags.sourcepath);\n await Promise.all(\n components.map(async (component) => {\n await this.processAuraComponent(component.path, component.name, 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 findAllAuraComponents(dirPath: string): Promise<Array<{ path: string; name: string }>> {\n this.logger.debug(`Scanning directory: ${dirPath}`);\n\n const dirName = path.basename(dirPath);\n const parentName = path.basename(path.dirname(dirPath));\n\n // Case 1: The sourcepath points directly to a component (inside an 'aura' folder)\n if (parentName === 'aura') {\n return [{\n path: dirPath,\n name: dirName\n }];\n }\n\n // Case 2: The sourcepath points to an 'aura' folder\n if (dirName === 'aura') {\n const entries = await fs.promises.readdir(dirPath, { withFileTypes: true });\n const components = await Promise.all(\n entries\n .filter(entry => entry.isDirectory())\n .map(entry => ({\n path: path.join(dirPath, entry.name),\n name: entry.name\n }))\n );\n return components;\n }\n\n // Case 3: Recursion\n const entries = await fs.promises.readdir(dirPath, { withFileTypes: true });\n const results = await Promise.all(\n entries.map(async (entry) => {\n if (entry.isDirectory()) {\n return this.findAllAuraComponents(path.join(dirPath, entry.name));\n }\n return [];\n })\n );\n\n return results.flat();\n }\n\n private async processAuraComponent(\n componentPath: string,\n componentName: string,\n isDryRun: boolean,\n instrumentationOpts: InstrumentationOptions,\n ): Promise<void> {\n this.logger.info(`Processing Aura component: ${componentName}`);\n\n const cmpPath = path.join(componentPath, `${componentName}.cmp`);\n const controllerPath = path.join(componentPath, `${componentName}Controller.js`);\n const helperPath = path.join(componentPath, `${componentName}Helper.js`);\n const rendererPath = path.join(componentPath, `${componentName}Renderer.js`);\n\n try {\n const loggerId = await this.instrumentCmpFile(cmpPath, componentName, isDryRun, instrumentationOpts);\n this.logger.debug(`Using logger ID: ${loggerId}`);\n\n await Promise.all([\n this.instrumentJsFile(controllerPath, loggerId, isDryRun, instrumentationOpts),\n this.instrumentJsFile(helperPath, loggerId, isDryRun, instrumentationOpts),\n this.instrumentJsFile(rendererPath, loggerId, isDryRun, instrumentationOpts),\n ]);\n } catch (error) {\n this.logger.error(`Error processing Aura component ${componentName}`, error);\n throw error;\n }\n }\n\n private async instrumentCmpFile(filePath: string, componentName: string, isDryRun: boolean, instrumentationOpts: InstrumentationOptions): Promise<string> {\n if (!fs.existsSync(filePath)) {\n this.logger.warn(`Component file not found: ${filePath}`);\n return 'logger';\n }\n\n this.logger.debug(`Instrumenting component file: ${filePath}`);\n this.stats.processedFiles++;\n\n let content = await fs.promises.readFile(filePath, 'utf8');\n const originalContent = content;\n\n const loggerMatch = content.match(AuraInstrumentationService.LOGGER_COMPONENT_REGEX);\n if (loggerMatch) {\n return loggerMatch[1];\n }\n\n const lastAttributeMatch = [...content.matchAll(AuraInstrumentationService.ATTRIBUTE_REGEX)].pop();\n if (lastAttributeMatch) {\n const insertPosition = lastAttributeMatch.index + lastAttributeMatch[0].length;\n const loggerComponent = `\\n <c:rflibLoggerCmp aura:id=\"logger\" name=\"${componentName}\" appendComponentId=\"false\" />`;\n content = content.slice(0, insertPosition) + loggerComponent + content.slice(insertPosition);\n }\n\n if (content !== originalContent) {\n this.stats.modifiedFiles++;\n this.stats.modifiedFilePaths?.push(filePath);\n if (!isDryRun) {\n await fs.promises.writeFile(filePath, content, 'utf8');\n this.logger.info(`Modified component file: ${filePath}`);\n } else {\n this.logger.info(`Would modify component file: ${filePath}`);\n if (instrumentationOpts.verbose) {\n this.log(`Would modify component file: ${filePath}`);\n }\n }\n }\n\n return 'logger';\n }\n\n private async instrumentJsFile(\n filePath: string,\n loggerId: string,\n isDryRun: boolean,\n instrumentationOpts: InstrumentationOptions,\n ): Promise<void> {\n if (!fs.existsSync(filePath)) {\n this.logger.debug(`JavaScript file not found: ${filePath}`);\n return;\n }\n\n this.logger.debug(`Instrumenting JavaScript file: ${filePath}`);\n this.stats.processedFiles++;\n\n let content = await fs.promises.readFile(filePath, 'utf8');\n\n if (instrumentationOpts.skipInstrumented && AuraInstrumentationService.isInstrumented(content, loggerId)) {\n this.logger.info(`Skipping instrumented file: ${filePath}`);\n return;\n }\n\n const originalContent = content;\n const isHelper = filePath.endsWith('Helper.js');\n\n // Process methods and other patterns\n content = AuraInstrumentationService.processMethodLogging(content, loggerId, isHelper, instrumentationOpts.noIf);\n content = AuraInstrumentationService.processTryCatchBlocks(content);\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 AuraInstrumentationService.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 }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"instrument.js","sourceRoot":"","sources":["../../../../../src/commands/rflib/logging/aura/instrument.ts"],"names":[],"mappings":"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","sourcesContent":["import * 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';\nimport { processWithConcurrency } from '../../../../shared/concurrency.js';\n\ntype IfCondition = {\n readonly condition: string;\n readonly position: number;\n}\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\nexport type RflibLoggingAuraInstrumentResult = {\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.aura.instrument');\n\nclass AuraInstrumentationService {\n public static readonly ATTRIBUTE_REGEX = /<aura:attribute[^>]*>/g;\n public static readonly LOGGER_COMPONENT_REGEX =\n /<c:rflibLoggerCmp\\s+aura:id=\"([^\"]+)\"\\s+name=\"([^\"]+)\"\\s+appendComponentId=\"([^\"]+)\"\\s*\\/>/;\n\n private static readonly LOGGER_VAR_REGEX = /var\\s+(\\w+)\\s*=\\s*\\w+\\.find\\(['\"](\\w+)['\"]\\);/;\n private static readonly METHOD_REGEX =\n /(\\b\\w+)\\s*:\\s*function\\s*\\((.*?)\\)\\s*{((?:[^{}]|{(?:[^{}]|{(?:[^{}]|{(?:[^{}]|{(?:[^{}]|{[^{}]*})*})*})*})*})*?)}/g;\n private static readonly PROMISE_CHAIN_REGEX = /\\.(then|catch|finally)\\s*\\(\\s*function\\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 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 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 trailingComma: 'none',\n };\n\n public static isInstrumented(content: string, loggerId: string): boolean {\n return new RegExp(`\\\\.find\\\\(['\"]${loggerId}['\"]\\\\)`, 'g').test(content);\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 processMethodLogging(content: string, loggerId: string, isHelper: boolean, noIf: boolean): string {\n return content.replace(this.METHOD_REGEX, (match: string, methodName: string, params: string, body: string) => {\n const paramList = params\n .split(',')\n .map((p) => p.trim())\n .filter(Boolean);\n let loggerVar = 'logger';\n let bodyContent = body;\n\n const paramsToLog = isHelper ? paramList : paramList.slice(1, 2);\n const placeholders = paramsToLog.map((_, i) => `{${i}}`).join(', ');\n const logParams = paramsToLog.length > 0 ? `, [${paramsToLog.join(', ')}]` : '';\n\n const loggerMatch = body.match(this.LOGGER_VAR_REGEX);\n if (loggerMatch && loggerMatch[2] === loggerId) {\n loggerVar = loggerMatch[1];\n const loggerIndex = body.indexOf(loggerMatch[0]) + loggerMatch[0].length;\n bodyContent = `${body.slice(0, loggerIndex)}\\n ${loggerVar}.info('${methodName}(${placeholders})'${logParams});${body.slice(loggerIndex)}`;\n } else {\n const loggerInit = `var ${loggerVar} = ${paramList[0]}.find('${loggerId}');\\n`;\n bodyContent = `\\n ${loggerInit} ${loggerVar}.info('${methodName}(${placeholders})'${logParams});${body}`;\n }\n\n if (!noIf) {\n bodyContent = this.processIfStatements(bodyContent, loggerVar);\n }\n\n bodyContent = AuraInstrumentationService.processPromiseChains(bodyContent, loggerVar);\n bodyContent = AuraInstrumentationService.processConsoleStatements(bodyContent, loggerVar);\n\n return `${methodName}: function(${params}) {${bodyContent}}`;\n });\n }\n\n public static processPromiseChains(content: string, loggerVar: string): string {\n return content.replace(\n this.PROMISE_CHAIN_REGEX,\n (match: string, type: string, param: string, blockBody: string) => {\n const logStatement = this.processPromiseType(type, param?.trim() || '', loggerVar);\n\n return match.replace(blockBody, `\\n ${logStatement}\\n ${blockBody}`);\n },\n );\n }\n\n public static processTryCatchBlocks(content: string): string {\n return content.replace(this.TRY_CATCH_BLOCK_REGEX, (match: string, exceptionVar: string) => {\n const errorVar = exceptionVar.trim().split(' ')[0] || 'error';\n return match.replace(\n /catch\\s*\\(([^)]*)\\)\\s*{/,\n `catch(${exceptionVar}) {\n logger.error('An error occurred', ${errorVar});`,\n );\n });\n }\n\n private static processPromiseType(type: string, paramName: string, loggerVar: string): string {\n switch (type) {\n case 'then':\n return `${loggerVar}.info('Promise resolved. Result={0}', ${paramName});`;\n case 'catch':\n return `${loggerVar}.error('An error occurred', ${paramName});`;\n case 'finally':\n return `${loggerVar}.info('Promise chain completed');`;\n default:\n throw new Error(`Unsupported promise type: ${type}`);\n }\n }\n\n private 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)\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 private 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\nexport default class RflibLoggingAuraInstrument extends SfCommand<RflibLoggingAuraInstrumentResult> {\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 concurrency: Flags.integer({\n summary: messages.getMessage('flags.concurrency.summary'),\n description: messages.getMessage('flags.concurrency.description'),\n char: 'c',\n default: 10,\n }),\n };\n\n private logger!: Logger;\n private readonly stats: RflibLoggingAuraInstrumentResult = {\n processedFiles: 0,\n modifiedFiles: 0,\n formattedFiles: 0,\n modifiedFilePaths: [],\n };\n\n public async run(): Promise<RflibLoggingAuraInstrumentResult> {\n this.logger = await Logger.child(this.ctor.name);\n const { flags } = await this.parse(RflibLoggingAuraInstrument);\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(`Starting Aura component instrumentation in ${flags.sourcepath}`);\n this.logger.debug(`Dry run mode: ${flags.dryrun}`);\n\n this.spinner.start('Running...');\n\n const components = await this.findAllAuraComponents(flags.sourcepath, instrumentationOpts.exclude);\n await processWithConcurrency(\n components,\n flags.concurrency,\n async (component) => {\n await this.processAuraComponent(component.path, component.name, 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 findAllAuraComponents(dirPath: string, excludePattern?: string): Promise<Array<{ path: string; name: string }>> {\n this.logger.debug(`Scanning directory: ${dirPath}`);\n\n const dirName = path.basename(dirPath);\n const parentName = path.basename(path.dirname(dirPath));\n\n // Case 1: The sourcepath points directly to a component (inside an 'aura' folder)\n if (parentName === 'aura') {\n if (excludePattern && minimatch(dirPath, excludePattern, { matchBase: true })) {\n this.logger.debug(`Skipping excluded path: ${dirPath}`);\n return [];\n }\n return [{\n path: dirPath,\n name: dirName\n }];\n }\n\n // Case 2: The sourcepath points to an 'aura' folder\n if (dirName === 'aura') {\n const entries = await fs.promises.readdir(dirPath, { withFileTypes: true });\n const components = await Promise.all(\n entries\n .filter(entry => entry.isDirectory())\n .map(entry => {\n const cmpPath = path.join(dirPath, entry.name);\n if (excludePattern && minimatch(cmpPath, excludePattern, { matchBase: true })) {\n this.logger.debug(`Skipping excluded path: ${cmpPath}`);\n return null;\n }\n return {\n path: cmpPath,\n name: entry.name\n };\n })\n );\n return components.filter((c): c is { path: string; name: string } => c !== null);\n }\n\n // Case 3: Recursion\n const entries = await fs.promises.readdir(dirPath, { withFileTypes: true });\n const results = await Promise.all(\n entries.map(async (entry) => {\n if (entry.isDirectory()) {\n return this.findAllAuraComponents(path.join(dirPath, entry.name), excludePattern);\n }\n return [];\n })\n );\n\n return results.flat();\n }\n\n private async processAuraComponent(\n componentPath: string,\n componentName: string,\n isDryRun: boolean,\n instrumentationOpts: InstrumentationOptions,\n ): Promise<void> {\n this.logger.info(`Processing Aura component: ${componentName}`);\n\n const cmpPath = path.join(componentPath, `${componentName}.cmp`);\n const controllerPath = path.join(componentPath, `${componentName}Controller.js`);\n const helperPath = path.join(componentPath, `${componentName}Helper.js`);\n const rendererPath = path.join(componentPath, `${componentName}Renderer.js`);\n\n try {\n const loggerId = await this.instrumentCmpFile(cmpPath, componentName, isDryRun, instrumentationOpts);\n this.logger.debug(`Using logger ID: ${loggerId}`);\n\n await Promise.all([\n this.instrumentJsFile(controllerPath, loggerId, isDryRun, instrumentationOpts),\n this.instrumentJsFile(helperPath, loggerId, isDryRun, instrumentationOpts),\n this.instrumentJsFile(rendererPath, loggerId, isDryRun, instrumentationOpts),\n ]);\n } catch (error) {\n this.logger.error(`Error processing Aura component ${componentName}`, error);\n throw error;\n }\n }\n\n private async instrumentCmpFile(filePath: string, componentName: string, isDryRun: boolean, instrumentationOpts: InstrumentationOptions): Promise<string> {\n if (!fs.existsSync(filePath)) {\n this.logger.warn(`Component file not found: ${filePath}`);\n return 'logger';\n }\n\n this.logger.debug(`Instrumenting component file: ${filePath}`);\n this.stats.processedFiles++;\n\n let content = await fs.promises.readFile(filePath, 'utf8');\n const originalContent = content;\n\n const loggerMatch = content.match(AuraInstrumentationService.LOGGER_COMPONENT_REGEX);\n if (loggerMatch) {\n return loggerMatch[1];\n }\n\n const lastAttributeMatch = [...content.matchAll(AuraInstrumentationService.ATTRIBUTE_REGEX)].pop();\n if (lastAttributeMatch) {\n const insertPosition = lastAttributeMatch.index + lastAttributeMatch[0].length;\n const loggerComponent = `\\n <c:rflibLoggerCmp aura:id=\"logger\" name=\"${componentName}\" appendComponentId=\"false\" />`;\n content = content.slice(0, insertPosition) + loggerComponent + content.slice(insertPosition);\n }\n\n if (content !== originalContent) {\n this.stats.modifiedFiles++;\n this.stats.modifiedFilePaths?.push(filePath);\n if (!isDryRun) {\n await fs.promises.writeFile(filePath, content, 'utf8');\n this.logger.info(`Modified component file: ${filePath}`);\n } else {\n this.logger.info(`Would modify component file: ${filePath}`);\n if (instrumentationOpts.verbose) {\n this.log(`Would modify component file: ${filePath}`);\n }\n }\n }\n\n return 'logger';\n }\n\n private async instrumentJsFile(\n filePath: string,\n loggerId: string,\n isDryRun: boolean,\n instrumentationOpts: InstrumentationOptions,\n ): Promise<void> {\n if (!fs.existsSync(filePath)) {\n this.logger.debug(`JavaScript file not found: ${filePath}`);\n return;\n }\n\n this.logger.debug(`Instrumenting JavaScript file: ${filePath}`);\n this.stats.processedFiles++;\n\n let content = await fs.promises.readFile(filePath, 'utf8');\n\n if (instrumentationOpts.skipInstrumented && AuraInstrumentationService.isInstrumented(content, loggerId)) {\n this.logger.info(`Skipping instrumented file: ${filePath}`);\n return;\n }\n\n const originalContent = content;\n const isHelper = filePath.endsWith('Helper.js');\n\n // Process methods and other patterns\n content = AuraInstrumentationService.processMethodLogging(content, loggerId, isHelper, instrumentationOpts.noIf);\n content = AuraInstrumentationService.processTryCatchBlocks(content);\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 AuraInstrumentationService.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 }\n}\n"]}
|
|
@@ -31,6 +31,8 @@ export default class RflibLoggingFlowInstrument extends SfCommand<RflibLoggingFl
|
|
|
31
31
|
dryrun: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
32
32
|
'skip-instrumented': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
33
33
|
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
34
|
+
exclude: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
35
|
+
concurrency: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
34
36
|
};
|
|
35
37
|
private logger;
|
|
36
38
|
private readonly stats;
|