@wise/wds-codemods 1.0.0-experimental-88c6a83 → 1.0.0-experimental-b6085e2

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.
@@ -1,25 +1,14 @@
1
- const require_chunk = require('./chunk-CInkuQNp.js');
1
+ const require_constants = require('./constants-BhVbK_XZ.js');
2
2
  let node_child_process = require("node:child_process");
3
3
  let node_path = require("node:path");
4
4
  let ora = require("ora");
5
- ora = require_chunk.__toESM(ora);
5
+ ora = require_constants.__toESM(ora);
6
6
  let node_https = require("node:https");
7
- node_https = require_chunk.__toESM(node_https);
7
+ node_https = require_constants.__toESM(node_https);
8
8
  let __anthropic_ai_claude_agent_sdk = require("@anthropic-ai/claude-agent-sdk");
9
9
  let node_fs = require("node:fs");
10
10
  let diff = require("diff");
11
11
 
12
- //#region src/constants.ts
13
- const CONSOLE_ICONS = {
14
- info: "\x1B[34mℹ\x1B[0m",
15
- focus: "\x1B[34m➙\x1B[0m",
16
- success: "\x1B[32m✔\x1B[0m",
17
- warning: "\x1B[33m⚠\x1B[0m",
18
- error: "\x1B[31m✖\x1B[0m",
19
- claude: "\x1B[35m💬\x1B[0m"
20
- };
21
-
22
- //#endregion
23
12
  //#region src/transforms/list-item/constants.ts
24
13
  const DEPRECATED_COMPONENT_NAMES = [
25
14
  "ActionOption",
@@ -326,7 +315,7 @@ function getQueryOptions(sessionId, codemodOptions, isDebug) {
326
315
  };
327
316
  if (isDebug) {
328
317
  const { ANTHROPIC_AUTH_TOKEN, ...restVars } = envVars;
329
- console.log(`${CONSOLE_ICONS.info} Claude configuration environment variables, excluding ANTHROPIC_AUTH_TOKEN:`);
318
+ console.log(`${require_constants.CONSOLE_ICONS.info} Claude configuration environment variables, excluding ANTHROPIC_AUTH_TOKEN:`);
330
319
  console.log(restVars);
331
320
  }
332
321
  const promptPrefix = !codemodOptions?.useGitIgnore ? "Do not use .gitignore to exclude files from the migration. Ensure all relevant files are included." : "Respect .gitignore when determining which files to include in the migration.";
@@ -382,26 +371,26 @@ async function queryClaude(path, options, codemodOptions, isDebug = false) {
382
371
  case "assistant":
383
372
  for (const msg of message.message.content) switch (msg.type) {
384
373
  case "tool_use":
385
- if (msg.name === "Glob") console.log(`${CONSOLE_ICONS.info} Finding all files within: ${formatPathOutput(path)}...`);
386
- else if (msg.name === "Grep") console.log(`${CONSOLE_ICONS.info} Identifying files with deprecated imports: ${formatPathOutput(path)}...`);
387
- else if (msg.name === "Read") console.log(`${CONSOLE_ICONS.info} Reading ${formatPathOutput(path, msg.input.file_path)}`);
374
+ if (msg.name === "Glob") console.log(`${require_constants.CONSOLE_ICONS.info} Finding all files within: ${formatPathOutput(path)}...`);
375
+ else if (msg.name === "Grep") console.log(`${require_constants.CONSOLE_ICONS.info} Identifying files with deprecated imports: ${formatPathOutput(path)}...`);
376
+ else if (msg.name === "Read") console.log(`${require_constants.CONSOLE_ICONS.info} Reading ${formatPathOutput(path, msg.input.file_path)}`);
388
377
  else if ((msg.name === "Write" || msg.name === "Edit") && !modifiedFiles.includes(msg.input.file_path)) {
389
378
  modifiedFiles.push(msg.input.file_path);
390
379
  if (codemodOptions.isPrint || codemodOptions.isDry) {
391
- console.log(`${CONSOLE_ICONS.info} ${codemodOptions.isDry ? "Proposed changes" : "Changes"} for ${formatPathOutput(path, msg.input.file_path)}:`);
380
+ console.log(`${require_constants.CONSOLE_ICONS.info} ${codemodOptions.isDry ? "Proposed changes" : "Changes"} for ${formatPathOutput(path, msg.input.file_path)}:`);
392
381
  console.log(generateDiff(msg.input.old_string, msg.input.new_string));
393
- } else console.log(`${CONSOLE_ICONS.info} Migrated ${formatPathOutput(path, msg.input.file_path)}`);
382
+ } else console.log(`${require_constants.CONSOLE_ICONS.info} Migrated ${formatPathOutput(path, msg.input.file_path)}`);
394
383
  }
395
384
  break;
396
385
  case "text":
397
- if (isDebug) console.log(`${CONSOLE_ICONS.claude} ${formatClaudeResponseContent(msg.text)}`);
386
+ if (isDebug) console.log(`${require_constants.CONSOLE_ICONS.claude} ${formatClaudeResponseContent(msg.text)}`);
398
387
  break;
399
388
  default: if (isDebug) console.log(msg);
400
389
  }
401
390
  break;
402
391
  case "result":
403
- if (message.subtype === "success") console.log(`${CONSOLE_ICONS.success} Migrated all applicable files in ${formatPathOutput(path)}`);
404
- else console.log(`${CONSOLE_ICONS.error} Claude encountered an error: ${message.errors.join("\n").trim()}`);
392
+ if (message.subtype === "success") console.log(`${require_constants.CONSOLE_ICONS.success} Migrated all applicable files in ${formatPathOutput(path)}`);
393
+ else console.log(`${require_constants.CONSOLE_ICONS.error} Claude encountered an error: ${message.errors.join("\n").trim()}`);
405
394
  break;
406
395
  default:
407
396
  }
@@ -412,23 +401,17 @@ async function queryClaude(path, options, codemodOptions, isDebug = false) {
412
401
  const transformer = async (targetPaths, codemodOptions, isDebug = false) => {
413
402
  const startTime = Date.now();
414
403
  const queryOptions = await initiateClaudeSessionOptions(codemodOptions, isDebug);
415
- console.log(`${CONSOLE_ICONS.info} Analysing targetted paths - this may take a while...`);
404
+ console.log(`${require_constants.CONSOLE_ICONS.info} Analysing targetted paths - this may take a while...`);
416
405
  for (const directory of targetPaths) await queryClaude(directory, queryOptions, codemodOptions, isDebug);
417
- console.log(`${CONSOLE_ICONS.success} Finished migrating - elapsed time: \x1b[1m${generateElapsedTime(startTime)}\x1b[0m`);
406
+ console.log(`${require_constants.CONSOLE_ICONS.success} Finished migrating - elapsed time: \x1b[1m${generateElapsedTime(startTime)}\x1b[0m`);
418
407
  };
419
408
  var transformer_default = transformer;
420
409
 
421
410
  //#endregion
422
- Object.defineProperty(exports, 'CONSOLE_ICONS', {
423
- enumerable: true,
424
- get: function () {
425
- return CONSOLE_ICONS;
426
- }
427
- });
428
411
  Object.defineProperty(exports, 'transformer_default', {
429
412
  enumerable: true,
430
413
  get: function () {
431
414
  return transformer_default;
432
415
  }
433
416
  });
434
- //# sourceMappingURL=transformer-1c7Qg1GE.js.map
417
+ //# sourceMappingURL=transformer-C-pTwN11.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transformer-C-pTwN11.js","names":["https","CONSOLE_ICONS","modifiedFiles: string[]","CONSOLE_ICONS"],"sources":["../src/transforms/list-item/constants.ts","../src/transforms/list-item/helpers.ts","../src/transforms/list-item/claude.ts","../src/transforms/list-item/transformer.ts"],"sourcesContent":["const DEPRECATED_COMPONENT_NAMES = [\n 'ActionOption',\n 'NavigationOption',\n 'NavigationOptionsList',\n 'Summary',\n 'SwitchOption',\n 'CheckboxOption',\n 'RadioOption',\n];\n\nconst MIGRATION_RULES = `Migration rules:\n# Legacy Component → ListItem Migration Guide\n\n## Universal Rules\n\n1. \\`title\\` → \\`title\\` (direct)\n2. \\`content\\` or \\`description\\` → \\`subtitle\\`\n3. \\`disabled\\` stays on \\`ListItem\\` (not controls)\n4. Keep HTML attributes (\\`id\\`, \\`name\\`, \\`aria-label\\`), remove: \\`as\\`, \\`complex\\`, \\`showMediaAtAllSizes\\`, \\`showMediaCircle\\`, \\`isContainerAligned\\`\n5. In strings, don't convert \\`\\`to\\`'\\`or\\`\"\\`. Preserve what is there.\n\n---\n\n## ActionOption → ListItem.Button\n\n- \\`action\\` → Button children\n- \\`onClick\\` → Button \\`onClick\\`\n- Priority: default/\\`\"primary\"\\` → \\`\"primary\"\\`, \\`\"secondary\"\\` → \\`\"secondary-neutral\"\\`, \\`\"secondary-send\"\\` → \\`\"secondary\"\\`, \\`\"tertiary\"\\` → \\`\"tertiary\"\\`\n\n\\`\\`\\`tsx\n<ActionOption title=\"Title\" content=\"Text\" action=\"Click\" priority=\"secondary\" onClick={fn} />\n→\n<ListItem title=\"Title\" subtitle=\"Text\" control={<ListItem.Button priority=\"secondary-neutral\" onClick={fn}>Click</ListItem.Button>} />\n\\`\\`\\`\n\n---\n\n## CheckboxOption → ListItem.Checkbox\n\n- \\`onChange\\`: \\`(checked: boolean)\\` → \\`(event: ChangeEvent)\\` use \\`event.target.checked\\`\n- \\`name\\` move to Checkbox\n- Don't move \\`id\\` to Checkbox\n\n\\`\\`\\`tsx\n<CheckboxOption id=\"x\" name=\"y\" title=\"Title\" content=\"Text\" checked={v} onChange={(c) => set(c)} />\n→\n<ListItem title=\"Title\" subtitle=\"Text\" control={<ListItem.Checkbox name=\"y\" checked={v} onChange={(e) => set(e.target.checked)} />} />\n\\`\\`\\`\n\n---\n\n## RadioOption → ListItem.Radio\n\n- \\`name\\`, \\`value\\`, \\`checked\\`, \\`onChange\\` move to Radio\n- Don't move \\`id\\` to Radio\n\n\\`\\`\\`tsx\n<RadioOption id=\"x\" name=\"y\" value=\"v\" title=\"Title\" content=\"Text\" checked={v==='v'} onChange={set} />\n→\n<ListItem title=\"Title\" subtitle=\"Text\" control={<ListItem.Radio name=\"y\" value=\"v\" checked={v==='v'} onChange={set} />} />\n\\`\\`\\`\n\n---\n\n## SwitchOption → ListItem.Switch\n\n- \\`onChange\\` → \\`onClick\\`, toggle manually\n- \\`aria-label\\` moves to Switch\n\n\\`\\`\\`tsx\n<SwitchOption title=\"Title\" content=\"Text\" checked={v} aria-label=\"Toggle\" onChange={set} />\n→\n<ListItem title=\"Title\" subtitle=\"Text\" control={<ListItem.Switch checked={v} aria-label=\"Toggle\" onClick={() => set(!v)} />} />\n\\`\\`\\`\n\n---\n\n## NavigationOption → ListItem.Navigation\n\n- \\`onClick\\` or \\`href\\` move to Navigation\n\n\\`\\`\\`tsx\n<NavigationOption title=\"Title\" content=\"Text\" onClick={fn} />\n→\n<ListItem title=\"Title\" subtitle=\"Text\" control={<ListItem.Navigation onClick={fn} />} />\n\\`\\`\\`\n\n---\n\n## Option → ListItem\n\n- Wrap \\`media\\` in \\`ListItem.AvatarView\\`\n\n\\`\\`\\`tsx\n<Option media={<Icon />} title=\"Title\" />\n→\n<ListItem title=\"Title\" media={<ListItem.AvatarView><Icon /></ListItem.AvatarView>} />\n\\`\\`\\`\n\n---\n\n## Summary → ListItem\n\n**Basic:**\n\n- \\`icon\\` → wrap in \\`ListItem.AvatarView\\` with \\`size={32}\\` as \\`media\\`\n- Remove \\`size\\` from child \\`<Icon />\\`\n\n**Status:**\n\n- \\`Status.DONE\\` → \\`badge={{ status: 'positive' }}\\`\n- \\`Status.PENDING\\` → \\`badge={{ status: 'pending' }}\\`\n- \\`Status.NOT_DONE\\` → no badge\n\n**Action:**\n\n- \\`action.text\\` → \\`action.label\\` in \\`ListItem.AdditionalInfo\\` as \\`additionalInfo\\`\n\n**Info (requires state):**\n\n- \\`MODAL\\` → \\`ListItem.IconButton partiallyInteractive\\` + \\`<Modal>\\` in \\`control\\`\n- \\`POPOVER\\` → \\`<Popover>\\` wrapping \\`ListItem.IconButton partiallyInteractive\\` in \\`control\\`\n- Use \\`QuestionMarkCircle\\` icon (import from \\`@transferwise/icons\\`)\n\n\\`\\`\\`tsx\n// Basic\n<Summary title=\"T\" description=\"D\" icon={<Icon />} />\n→\n<ListItem title=\"T\" subtitle=\"D\" media={<ListItem.AvatarView size={32}><Icon /></ListItem.AvatarView>} />\n\n// Status\n<Summary title=\"T\" description=\"D\" icon={<Icon />} status={Status.DONE} />\n→\n<ListItem title=\"T\" subtitle=\"D\" media={<ListItem.AvatarView size={32} badge={{status:'positive'}}><Icon /></ListItem.AvatarView>} />\n\n// Action\n<Summary title=\"T\" description=\"D\" icon={<Icon />} action={{text:'Go', href:'/go'}} />\n→\n<ListItem title=\"T\" subtitle=\"D\" media={<ListItem.AvatarView size={32}><Icon /></ListItem.AvatarView>} additionalInfo={<ListItem.AdditionalInfo action={{label:'Go', href:'/go'}} />} />\n\n// Modal (add: const [open, setOpen] = useState(false))\n<Summary title=\"T\" description=\"D\" icon={<Icon />} info={{title:'Help', content:'Text', presentation:'MODAL', 'aria-label':'Info'}} />\n→\n<ListItem title=\"T\" subtitle=\"D\" media={<ListItem.AvatarView size={32}><Icon /></ListItem.AvatarView>} control={<ListItem.IconButton partiallyInteractive aria-label=\"Info\" onClick={()=>setOpen(!open)}><QuestionMarkCircle /><Modal open={open} title=\"Help\" body=\"Text\" onClose={()=>setOpen(false)} /></ListItem.IconButton>} />\n\n// Popover\n<Summary title=\"T\" description=\"D\" icon={<Icon />} info={{title:'Help', content:'Text', presentation:'POPOVER', 'aria-label':'Info'}} />\n→\n<ListItem title=\"T\" subtitle=\"D\" media={<ListItem.AvatarView size={32}><Icon /></ListItem.AvatarView>} control={<Popover title=\"Help\" content=\"Text\" onClose={()=>setOpen(false)}><ListItem.IconButton partiallyInteractive aria-label=\"Info\"><QuestionMarkCircle /></ListItem.IconButton></Popover>} />\n\\`\\`\\`\n\n---\n\n## DefinitionList → Multiple ListItem\n\n- Array → individual \\`ListItem\\`s\n- \\`value\\` → \\`subtitle\\`\n- \\`key\\` → React \\`key\\` prop\n- Action type: \"Edit\"/\"Update\"/\"View\" → \\`ListItem.Button priority=\"secondary-neutral\"\\`, \"Change\"/\"Password\" → \\`ListItem.Navigation\\`, \"Copy\" → \\`ListItem.IconButton\\`\n\n\\`\\`\\`tsx\n<DefinitionList definitions={[\n {title:'T1', value:'V1', key:'k1'},\n {title:'T2', value:'V2', key:'k2', action:{label:'Edit', onClick:fn}}\n]} />\n→\n\n <ListItem key=\"k1\" title=\"T1\" subtitle=\"V1\" />\n <ListItem key=\"k2\" title=\"T2\" subtitle=\"V2\" control={<ListItem.Button priority=\"secondary-neutral\" onClick={fn}>Edit</ListItem.Button>} />\n\n\\`\\`\\`\n`;\n\nexport const SYSTEM_PROMPT = `You are a code migration assistant that helps migrate TypeScript/JSX code from deprecated Wise Design System (WDS) components to the new ListItem component and ListItem subcomponents from '@transferwise/components'.\n\nProcess and migrate each file individually, before reading the next file. Make only a single comprehensive edit per file to replace all necessary code according to the migration context and rules provided. Do not make multiple incremental edits per file.\n\nRules:\n1. Ignore any files that do not contain deprecated WDS components and are not .tsx files, unless they are necessary for context.\n2. Do not migrate files matching the provided patterns in the ignore list.\n3. Migrate components per provided migration rules\n4. Maintain TypeScript type safety and update types to match new API\n5. Map props: handle renamed, deprecated, new required, and changed types\n6. Update imports to new WDS components and types\n7. Preserve code style, formatting, and calculated logic\n8. Handle conditional rendering, spread props, and complex expressions\n9. Note: New components may lack feature parity with legacy versions\n10. Only modify code requiring changes per migration rules, and any impacted surrounding code for context.\n11. Do not summarise the initial user request in a response.\n12. Use glob to find files in the directory and then grep to identify files with deprecated imports.\n13. Final result response should just be whether the migration was successful overall, or if any errors were encountered\n14. Explain your reasoning and justification before making changes, as you edit each file. Keep it concise and succinct as only bullet points\n15. Do not summarise the changes made after modifying a file.\n16. If you do not have permission to modify a file, still attempt to edit it and then move onto the next file.\n\nMake the necessary updates to the files. \n\nYou'll receive:\n- File paths/directories to search in individual queries\n- Deprecated component names at the end of this prompt\n- Migration context and rules for each deprecated component\n\nDeprecated components: ${DEPRECATED_COMPONENT_NAMES.join(', ')}.\n\n${MIGRATION_RULES}`;\n","import { createPatch } from 'diff';\n\n/** Split the path to get the relative path after the directory, and wrap with ANSI color codes */\nexport function formatPathOutput(directory: string, path?: string): string {\n return `\\x1b[32m${path ? (path.split(directory)[1] ?? path) : directory}\\x1b[0m`;\n}\n\n/** Generates a formatted string representing the total elapsed time since the given start time */\nexport function generateElapsedTime(startTime: number): string {\n const endTime = Date.now();\n const elapsedTime = Math.floor((endTime - startTime) / 1000);\n const hours = Math.floor(elapsedTime / 3600);\n const minutes = Math.floor((elapsedTime % 3600) / 60);\n const seconds = elapsedTime % 60;\n\n return `${hours ? `${hours}h ` : ''}${minutes ? `${minutes}m ` : ''}${seconds ? `${seconds}s` : ''}`;\n}\n\n// Formats Claude response with ANSI codes (bold for **, green for `), indenting all lines except the first. Also wraps entire content in dim color\nexport function formatClaudeResponseContent(content: string): string {\n const formatted = content\n .replace(/\\*\\*(.+?)\\*\\*/gu, '\\x1b[1m$1\\x1b[0m\\x1b[2m')\n .replace(/`(.+?)`/gu, '\\x1b[32m$1\\x1b[0m\\x1b[2m')\n .split('\\n')\n .map((line, index) => (index === 0 ? line : ` ${line}`))\n .join('\\n');\n\n return `\\x1b[2m${formatted}\\x1b[0m`;\n}\n\n// Generates a unified diff between the original and modified strings, with ANSI color codes for additions and deletions and line numbers\nexport function generateDiff(original: string, modified: string): string {\n const diffResult = createPatch('', original, modified, '', '').trim();\n\n // Parse and colorize the diff output\n const lines = diffResult\n .split('\\n')\n .slice(4) // Skip the header lines\n .filter((line) => !line.startsWith('\\\')); // Remove \"No newline\" messages\n\n // Track current line numbers from hunk headers\n let oldLineNumber = 0;\n let newLineNumber = 0;\n\n const colouredDiff = lines\n .map((line: string) => {\n const trimmedLine = line.trimEnd();\n\n // Parse hunk header to get starting line numbers - format: @@ -oldStart,oldCount +newStart,newCount @@\n if (trimmedLine.startsWith('@@')) {\n const match = /@@ -(\\d+)(?:,\\d+)? \\+(\\d+)(?:,\\d+)? @@/u.exec(trimmedLine);\n if (match) {\n oldLineNumber = Number.parseInt(match[1], 10);\n newLineNumber = Number.parseInt(match[2], 10);\n }\n return `\\x1b[36m${trimmedLine}\\x1b[0m`; // Cyan for hunk headers\n }\n\n let linePrefix = '';\n // Green styling for additions\n if (trimmedLine.startsWith('+')) {\n linePrefix = `${newLineNumber.toString().padStart(4, ' ')} `;\n newLineNumber += 1;\n return `\\x1b[32m${linePrefix}${trimmedLine}\\x1b[0m`;\n }\n\n // Red styling for deletions\n if (trimmedLine.startsWith('-')) {\n linePrefix = `${oldLineNumber.toString().padStart(4, ' ')} `;\n oldLineNumber += 1;\n return `\\x1b[31m${linePrefix}${trimmedLine}\\x1b[0m`;\n }\n\n // Handle unchanged lines\n linePrefix = `${oldLineNumber.toString().padStart(4, ' ')} `;\n oldLineNumber += 1;\n newLineNumber += 1;\n return `${linePrefix}${trimmedLine}`;\n })\n .join('\\n');\n\n return colouredDiff;\n}\n","import https from 'node:https';\n\nimport { type Options, query } from '@anthropic-ai/claude-agent-sdk';\nimport { execSync } from 'child_process';\nimport { readFileSync } from 'fs';\nimport ora from 'ora';\nimport { resolve } from 'path';\n\nimport { CONSOLE_ICONS } from '../../constants';\nimport type { CodemodOptions } from '../../controller/types';\nimport { SYSTEM_PROMPT } from './constants';\nimport { formatClaudeResponseContent, formatPathOutput, generateDiff } from './helpers';\nimport type { ClaudeResponseToolUse, ClaudeSettings } from './types';\n\nconst CLAUDE_SETTINGS_FILE = '.claude/settings.json';\n\nasync function checkVPN(baseUrl?: string): Promise<boolean> {\n if (baseUrl) {\n const vpnSpinner = ora('Checking VPN connection...').start();\n const checkOnce = async (): Promise<boolean> =>\n new Promise<boolean>((resolveCheck) => {\n const url = new URL('/health', baseUrl);\n const req = https.get(url, { timeout: 2000, rejectUnauthorized: false }, (res) => {\n const ok = !!(res.statusCode && res.statusCode >= 200 && res.statusCode < 400);\n res.resume();\n resolveCheck(ok);\n });\n req.on('timeout', () => {\n req.destroy(new Error('timeout'));\n });\n req.on('error', () => resolveCheck(false));\n });\n\n while (true) {\n const ok = await checkOnce();\n if (ok) {\n vpnSpinner.succeed('Connected to VPN');\n break;\n }\n vpnSpinner.text = 'Please connect to VPN... retrying in 3s';\n await new Promise<void>((response) => {\n setTimeout(response, 3000);\n });\n }\n }\n return true;\n}\n\nexport function getQueryOptions(\n sessionId?: string,\n codemodOptions?: CodemodOptions,\n isDebug?: boolean,\n): Options {\n // Read settings from ~/.claude/settings.json to get headers and apiKeyHelper\n const claudeSettingsPath = resolve(process.env.HOME || '', CLAUDE_SETTINGS_FILE);\n const settings = JSON.parse(readFileSync(claudeSettingsPath, 'utf-8')) as ClaudeSettings;\n\n // Get API key by executing the apiKeyHelper script, for authenticating with Okta via LLM Gateway\n let apiKey;\n try {\n apiKey = execSync(`bash ${settings.apiKeyHelper}`, {\n encoding: 'utf-8',\n }).trim();\n } catch {}\n\n if (!apiKey) {\n throw new Error(\n 'Failed to retrieve Anthropic API key. Please check your Claude Code x LLM Gateway configuration - https://transferwise.atlassian.net/wiki/x/_YUe3Q',\n );\n }\n\n const { ANTHROPIC_CUSTOM_HEADERS, ...restEnvVars } = settings?.env ?? {};\n\n const envVars = {\n ANTHROPIC_AUTH_TOKEN: apiKey,\n ANTHROPIC_CUSTOM_HEADERS,\n ...restEnvVars,\n PATH: process.env.PATH, // Specifying PATH, as Claude Agent SDK seems to struggle consuming the actual environment PATH\n };\n\n if (isDebug) {\n // Not logging the auth token and path\n const { ANTHROPIC_AUTH_TOKEN, ...restVars } = envVars;\n console.log(\n `${CONSOLE_ICONS.info} Claude configuration environment variables, excluding ANTHROPIC_AUTH_TOKEN:`,\n );\n console.log(restVars);\n }\n\n const promptPrefix = !codemodOptions?.useGitIgnore\n ? 'Do not use .gitignore to exclude files from the migration. Ensure all relevant files are included.'\n : 'Respect .gitignore when determining which files to include in the migration.';\n\n // NOTE: ignore patterns not working...\n // codemodOptions?.ignorePatterns?.length ? `Ignore any files with names matching the following .gitignore glob patterns, separated by commas and do not migrate them: ${codemodOptions.ignorePatterns.replaceAll(',', ', ')}` : '';\n\n return {\n resume: sessionId,\n env: envVars,\n permissionMode: codemodOptions?.isDry ? undefined : 'acceptEdits',\n systemPrompt: {\n type: 'preset',\n preset: 'claude_code',\n append: `${promptPrefix}\\n${SYSTEM_PROMPT}`,\n },\n allowedTools: ['Glob', 'Grep', 'Read', ...(!codemodOptions?.isDry ? ['Write', 'Edit'] : [])],\n settingSources: ['local', 'project', 'user'],\n };\n}\n\n/** Initiate a new Claude session/conversation and return reusable options */\nexport async function initiateClaudeSessionOptions(\n codemodOptions: CodemodOptions,\n isDebug = false,\n): Promise<Options> {\n const options = getQueryOptions(undefined, codemodOptions, isDebug);\n await checkVPN(options.env?.ANTHROPIC_BASE_URL);\n\n const claudeSessionSpinner = ora(\n 'Starting Claude instance - your browser may open for Okta authentication if required.',\n ).start();\n\n const result = query({\n options,\n prompt: `You'll be given file paths in additional individual queries to search in for files using deprecated Wise Design System (WDS) components. Migrate the code per the provided migration rules.`,\n });\n\n for await (const message of result) {\n switch (message.type) {\n case 'system':\n if (message.subtype === 'init' && !options.resume) {\n claudeSessionSpinner.succeed('Successfully initialised Claude instance');\n\n // Set the session ID to resume the conversation in future queries\n options.resume = message.session_id;\n }\n break;\n default:\n if (message.type === 'result' && message.subtype !== 'success') {\n claudeSessionSpinner.fail(`Claude encountered an error: ${message.errors.join('\\n')}`);\n }\n }\n }\n\n return options;\n}\n\n// Queries Claude with the given path and handles logging of tool uses and results\nexport async function queryClaude(\n path: string,\n options: Options,\n codemodOptions: CodemodOptions,\n isDebug = false,\n) {\n const result = query({\n options,\n prompt: path,\n });\n const modifiedFiles: string[] = [];\n\n for await (const message of result) {\n switch (message.type) {\n case 'assistant':\n for (const msg of message.message.content) {\n switch (msg.type) {\n // Handles logging of tool uses to determine key stages of the migration\n case 'tool_use':\n if (msg.name === 'Glob') {\n console.log(\n `${CONSOLE_ICONS.info} Finding all files within: ${formatPathOutput(path)}...`,\n );\n } else if (msg.name === 'Grep') {\n console.log(\n `${CONSOLE_ICONS.info} Identifying files with deprecated imports: ${formatPathOutput(path)}...`,\n );\n } else if (msg.name === 'Read') {\n console.log(\n `${CONSOLE_ICONS.info} Reading ${formatPathOutput(path, (msg as ClaudeResponseToolUse).input.file_path)}`,\n );\n } else if (\n (msg.name === 'Write' || msg.name === 'Edit') &&\n !modifiedFiles.includes((msg as ClaudeResponseToolUse).input.file_path) // Safeguard against duplicate logs, where Claude may write multiple times to the same file\n ) {\n // TODO: Consider how to handle multiple writes to the same file more gracefully (logged changes won't always match final file content)\n modifiedFiles.push((msg as ClaudeResponseToolUse).input.file_path);\n\n // Generate and print out a pretty diff of changes made by Claude\n if (codemodOptions.isPrint || codemodOptions.isDry) {\n console.log(\n `${CONSOLE_ICONS.info} ${codemodOptions.isDry ? 'Proposed changes' : 'Changes'} for ${formatPathOutput(path, (msg as ClaudeResponseToolUse).input.file_path)}:`,\n );\n console.log(\n generateDiff(\n (msg as ClaudeResponseToolUse).input.old_string as string,\n (msg as ClaudeResponseToolUse).input.new_string as string,\n ),\n );\n } else {\n console.log(\n `${CONSOLE_ICONS.info} Migrated ${formatPathOutput(path, (msg as ClaudeResponseToolUse).input.file_path)}`,\n );\n }\n }\n break;\n case 'text':\n // Logs Claude's textual responses in debug mode, to help with understanding justifications/errors\n if (isDebug) {\n console.log(`${CONSOLE_ICONS.claude} ${formatClaudeResponseContent(msg.text)}`);\n }\n break;\n default:\n if (isDebug) {\n console.log(msg);\n }\n }\n }\n break;\n case 'result':\n if (message.subtype === 'success') {\n // TODO: Handle case where migration failed for some files - maybe due to failed dependency checks?\n console.log(\n `${CONSOLE_ICONS.success} Migrated all applicable files in ${formatPathOutput(path)}`,\n );\n } else {\n console.log(\n `${CONSOLE_ICONS.error} Claude encountered an error: ${message.errors.join('\\n').trim()}`,\n );\n }\n break;\n default:\n }\n }\n}\n","import { CONSOLE_ICONS } from '../../constants';\nimport type { CodemodOptions } from '../../controller/types';\nimport { initiateClaudeSessionOptions, queryClaude } from './claude';\nimport { generateElapsedTime } from './helpers';\n\nconst transformer = async (\n targetPaths: string[],\n codemodOptions: CodemodOptions,\n isDebug = false,\n) => {\n const startTime = Date.now();\n const queryOptions = await initiateClaudeSessionOptions(codemodOptions, isDebug);\n\n console.log(`${CONSOLE_ICONS.info} Analysing targetted paths - this may take a while...`);\n\n for (const directory of targetPaths) {\n await queryClaude(directory, queryOptions, codemodOptions, isDebug);\n }\n\n console.log(\n `${CONSOLE_ICONS.success} Finished migrating - elapsed time: \\x1b[1m${generateElapsedTime(startTime)}\\x1b[0m`,\n );\n};\n\nexport default transformer;\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  Object.defineProperty(exports, '__esModule', { value: true });
2
- const require_helpers = require('../../helpers-Bgz_nSwk.js');
2
+ require('../../constants-BhVbK_XZ.js');
3
+ const require_helpers = require('../../helpers-B_v1Ye7N.js');
3
4
 
4
5
  //#region src/helpers/addImport.ts
5
6
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"transformer.js","names":["result: ImportSpecifier[]","sizeMap: Record<string, string>","j: JSCodeshift","manualReviewIssues: string[]","hasImport","legacyProps: LegacyProps","resolvedType: string | undefined","typeValue: string | undefined","asValue: string | null","reportManualReview"],"sources":["../../../src/helpers/addImport.ts","../../../src/helpers/hasImport.ts","../../../src/helpers/iconUtils.ts","../../../src/helpers/jsxElementUtils.ts","../../../src/helpers/jsxReportingUtils.ts","../../../src/transforms/button/transformer.ts"],"sourcesContent":["import type { Collection, JSCodeshift } from 'jscodeshift';\n\n/**\n * Adds a named import if it doesn't already exist.\n */\nfunction addImport(\n root: Collection,\n sourceValue: string,\n importName: string,\n j: JSCodeshift,\n): void {\n const existingImports = root.find(j.ImportDeclaration, {\n source: { value: sourceValue },\n });\n\n if (existingImports.size() > 0) {\n const namedImport = existingImports.find(j.ImportSpecifier, {\n imported: { name: importName },\n });\n\n if (namedImport.size() > 0) {\n return;\n }\n\n existingImports.forEach((path) => {\n if (path.node.specifiers) {\n path.node.specifiers.push(j.importSpecifier(j.identifier(importName)));\n }\n });\n } else {\n const newImport = j.importDeclaration(\n [j.importSpecifier(j.identifier(importName))],\n j.literal(sourceValue),\n );\n\n const firstImport = root.find(j.ImportDeclaration).at(0);\n if (firstImport.size() > 0) {\n firstImport.insertBefore(newImport);\n } else {\n // Insert at the beginning of the program\n const program = root.find(j.Program);\n if (program.size() > 0) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n program.get('body', 0).insertBefore(newImport);\n }\n }\n }\n}\n\nexport default addImport;\n","import type { ASTPath, Collection, ImportSpecifier, JSCodeshift } from 'jscodeshift';\n\n/**\n * Checks if a specific import exists in the given root collection and provides\n * a method to remove it if found.\n */\nfunction hasImport(\n root: Collection,\n sourceValue: string,\n importName: string,\n j: JSCodeshift,\n): {\n exists: boolean;\n remove: () => void;\n aliases?: Collection<ImportSpecifier>;\n resolvedName: string;\n conflictingImports: ImportSpecifier[];\n} {\n const importDeclarations = root.find(j.ImportDeclaration, {\n source: { value: sourceValue },\n });\n\n /**\n * Finds all ImportSpecifier nodes that expose `importName` but\n * from a different source than `sourceValue`.\n */\n const conflictingImports = ((): ImportSpecifier[] => {\n const result: ImportSpecifier[] = [];\n root\n .find(j.ImportDeclaration)\n .filter((path) => path.node.source.value !== sourceValue)\n .forEach((path) => {\n for (const specifier of path.node.specifiers ?? []) {\n if (\n specifier.type === 'ImportSpecifier' &&\n specifier.imported.name === importName &&\n specifier.local?.name === importName\n ) {\n result.push(specifier);\n }\n }\n });\n return result;\n })();\n\n if (importDeclarations.size() === 0) {\n return {\n exists: false,\n remove: () => {},\n resolvedName: importName,\n conflictingImports,\n };\n }\n\n const namedImport = importDeclarations.find(j.ImportSpecifier, {\n imported: { name: importName },\n });\n\n const defaultImport = importDeclarations.find(j.ImportDefaultSpecifier, {\n local: { name: importName },\n });\n\n const aliasImport = importDeclarations.find(j.ImportSpecifier).filter((path) => {\n return (\n path.node.imported.name === importName && path.node.imported.name !== path.node.local?.name\n );\n });\n\n const exists = namedImport.size() > 0 || defaultImport.size() > 0;\n\n const resolveName = (): string => {\n if (aliasImport.size() > 0) {\n const importPath = aliasImport.get(0) as ASTPath<ImportSpecifier>;\n const localName = importPath.node.local?.name;\n\n if (typeof localName === 'string') {\n return localName;\n }\n\n if (\n localName &&\n typeof localName === 'object' &&\n 'name' in localName &&\n typeof localName.name === 'string'\n ) {\n return localName.name;\n }\n\n return importName;\n }\n\n return importName;\n };\n\n const remove = () => {\n importDeclarations.forEach((path) => {\n const filteredSpecifiers =\n path.node.specifiers?.filter((specifier) => {\n if (specifier.type === 'ImportSpecifier' && specifier.imported.name === importName) {\n return false;\n }\n if (specifier.type === 'ImportDefaultSpecifier' && specifier.local?.name === importName) {\n return false;\n }\n return true;\n }) ?? [];\n\n if (filteredSpecifiers.length === 0) {\n path.prune();\n } else {\n j(path).replaceWith(\n j.importDeclaration(filteredSpecifiers, path.node.source, path.node.importKind),\n );\n }\n });\n };\n\n return {\n exists,\n remove,\n aliases: aliasImport,\n resolvedName: resolveName(),\n conflictingImports,\n };\n}\n\nexport default hasImport;\n","import type { JSCodeshift, JSXElement, JSXExpressionContainer } from 'jscodeshift';\n\n/**\n * Process children of a JSX element to detect icon components and add iconStart or iconEnd attributes accordingly.\n * This is specific to icon handling but can be reused in codemods dealing with icon children.\n */\nconst processIconChildren = (\n j: JSCodeshift,\n children: (JSXElement | JSXExpressionContainer | unknown)[] | undefined,\n iconImports: Set<string>,\n openingElement: JSXElement['openingElement'],\n) => {\n if (!children || !openingElement.attributes) return;\n\n const unwrapJsxElement = (node: unknown): JSXElement | unknown => {\n if (\n typeof node === 'object' &&\n node !== null &&\n 'type' in node &&\n node.type === 'JSXExpressionContainer' &&\n j.JSXElement.check((node as JSXExpressionContainer).expression)\n ) {\n return (node as JSXExpressionContainer).expression;\n }\n return node;\n };\n\n const totalChildren = children.length;\n\n // Find index of icon child\n const iconChildIndex = children.findIndex((child) => {\n const unwrapped = unwrapJsxElement(child);\n return (\n j.JSXElement.check(unwrapped) &&\n unwrapped.openingElement.name.type === 'JSXIdentifier' &&\n iconImports.has(unwrapped.openingElement.name.name)\n );\n });\n\n if (iconChildIndex === -1) return;\n\n const iconChild = unwrapJsxElement(children[iconChildIndex]) as JSXElement;\n\n if (!iconChild || iconChild.openingElement.name.type !== 'JSXIdentifier') return;\n\n const iconName = iconChild.openingElement.name.name;\n\n // Determine if icon is closer to start or end\n const distanceToStart = iconChildIndex;\n const distanceToEnd = totalChildren - 1 - iconChildIndex;\n const iconPropName = distanceToStart <= distanceToEnd ? 'addonStart' : 'addonEnd';\n\n // Build: { type: 'icon', value: <IconName /> }\n const iconObject = j.objectExpression([\n j.property('init', j.identifier('type'), j.literal('icon')),\n j.property('init', j.identifier('value'), iconChild),\n ]);\n const iconProp = j.jsxAttribute(\n j.jsxIdentifier(iconPropName),\n j.jsxExpressionContainer(iconObject),\n );\n\n openingElement.attributes.push(iconProp);\n\n // Remove the icon child\n children.splice(iconChildIndex, 1);\n\n // Helper to check if a child is whitespace-only JSXText\n const isWhitespaceJsxText = (node: unknown): boolean => {\n return (\n typeof node === 'object' &&\n node !== null &&\n (node as { type?: unknown }).type === 'JSXText' &&\n typeof (node as { value?: string }).value === 'string' &&\n (node as { value?: string }).value!.trim() === ''\n );\n };\n\n // Remove adjacent whitespace-only JSXText node if any\n if (iconChildIndex - 1 >= 0 && isWhitespaceJsxText(children[iconChildIndex - 1])) {\n children.splice(iconChildIndex - 1, 1);\n } else if (isWhitespaceJsxText(children[iconChildIndex])) {\n children.splice(iconChildIndex, 1);\n }\n};\n\nexport default processIconChildren;\n","import type {\n Collection,\n ImportSpecifier,\n JSCodeshift,\n JSXAttribute,\n JSXElement,\n JSXIdentifier,\n JSXMemberExpression,\n JSXNamespacedName,\n JSXSpreadAttribute,\n} from 'jscodeshift';\n\n/**\n * Rename a JSX element name if it is a JSXIdentifier.\n */\nexport const setNameIfJSXIdentifier = (\n elementName: JSXIdentifier | JSXNamespacedName | JSXMemberExpression | undefined,\n newName: string,\n): JSXIdentifier | JSXNamespacedName | JSXMemberExpression | undefined => {\n if (elementName && elementName.type === 'JSXIdentifier') {\n return { ...elementName, name: newName };\n }\n return elementName;\n};\n\n/**\n * Check if a list of attributes contains a specific attribute by name.\n */\nexport const hasAttribute = (\n attributes: (JSXAttribute | JSXSpreadAttribute)[] | undefined,\n attributeName: string,\n): boolean => {\n return (\n Array.isArray(attributes) &&\n attributes.some(\n (attr): attr is JSXAttribute =>\n attr.type === 'JSXAttribute' &&\n attr.name.type === 'JSXIdentifier' &&\n attr.name.name === attributeName,\n )\n );\n};\n\n/**\n * Check if a JSX element's openingElement has a specific attribute.\n */\nexport const hasAttributeOnElement = (\n element: JSXElement['openingElement'],\n attributeName: string,\n): boolean => {\n return hasAttribute(element.attributes, attributeName);\n};\n\n/**\n * Add specified attributes to a JSX element's openingElement if they are not already present.\n */\nexport const addAttributesIfMissing = (\n j: JSCodeshift,\n openingElement: JSXElement['openingElement'],\n attributesToAdd: { attribute: JSXAttribute; name: string }[],\n) => {\n if (!Array.isArray(openingElement.attributes)) return;\n const attrs = openingElement.attributes;\n attributesToAdd.forEach(({ attribute, name }) => {\n if (!hasAttributeOnElement(openingElement, name)) {\n attrs.push(attribute);\n }\n });\n};\n\n/**\n * Returns a collection of JSX elements that match the specified\n * exported name or names of the found aliases.\n */\nexport const findJSXElementsByName =\n (root: Collection, j: JSCodeshift) =>\n (exportedName: string, aliases?: Collection<ImportSpecifier>) => {\n const aliasNames = aliases?.size()\n ? aliases.paths().map((path) => path.node.local?.name as string)\n : [];\n\n return root.find(j.JSXElement).filter((path) => {\n const { name } = path.node.openingElement;\n return (\n name.type === 'JSXIdentifier' &&\n (name.name === exportedName || aliasNames.includes(name.name))\n );\n });\n };\n\n/**\n * Removes an attribute by name from a JSX element's openingElement.\n */\nexport const removeAttributeByName = (\n j: JSCodeshift,\n openingElement: JSXElement['openingElement'],\n attributeName: string,\n) => {\n if (!Array.isArray(openingElement.attributes)) return;\n // eslint-disable-next-line no-param-reassign\n openingElement.attributes = openingElement.attributes.filter((attr) => {\n return !(\n attr.type === 'JSXAttribute' &&\n attr.name.type === 'JSXIdentifier' &&\n attr.name.name === attributeName\n );\n });\n};\n","import type {\n ASTPath,\n ImportSpecifier,\n JSCodeshift,\n JSXAttribute,\n JSXElement,\n Node,\n} from 'jscodeshift';\n\nexport interface ReporterOptions {\n jscodeshift: JSCodeshift;\n issues: string[];\n}\n\n/**\n * CodemodReporter is a utility class for reporting issues found during codemod transformations.\n * It provides methods to report issues related to JSX elements, props, and attributes.\n *\n * @example\n * ```typescript\n * const issues: string[] = [];\n * const reporter = createReporter(j, issues);\n *\n * // Report a deprecated prop\n * reporter.reportDeprecatedProp(buttonElement, 'flat', 'variant=\"text\"');\n *\n * // Report complex expression that needs review\n * reporter.reportAmbiguousExpression(element, 'size');\n *\n * // Auto-detect common issues\n * reporter.reportAttributeIssues(element);\n * ```\n */\nexport class CodemodReporter {\n private readonly j: JSCodeshift;\n private readonly issues: string[];\n\n constructor(options: ReporterOptions) {\n this.j = options.jscodeshift;\n this.issues = options.issues;\n }\n\n /**\n * Reports an issue with a JSX element\n */\n reportElement(element: JSXElement | ASTPath<JSXElement>, reason: string): void {\n const node = this.getNode(element);\n const componentName = this.getComponentName(node);\n const line = this.getLineNumber(node);\n\n this.addIssue(`Manual review required: <${componentName}> at line ${line} ${reason}.`);\n }\n\n /**\n * Reports an issue with a specific prop\n */\n reportProp(element: JSXElement | ASTPath<JSXElement>, propName: string, reason: string): void {\n const node = this.getNode(element);\n const componentName = this.getComponentName(node);\n const line = this.getLineNumber(node);\n\n this.addIssue(\n `Manual review required: prop \"${propName}\" on <${componentName}> at line ${line} ${reason}.`,\n );\n }\n\n /**\n * Reports an issue with a JSX attribute directly\n */\n reportAttribute(\n attr: JSXAttribute,\n element: JSXElement | ASTPath<JSXElement>,\n reason?: string,\n ): void {\n const node = this.getNode(element);\n const componentName = this.getComponentName(node);\n const propName = this.getAttributeName(attr);\n const line = this.getLineNumber(attr) || this.getLineNumber(node);\n\n const defaultReason = this.getAttributeReason(attr);\n const finalReason = reason || defaultReason;\n\n this.addIssue(\n `Manual review required: prop \"${propName}\" on <${componentName}> at line ${line} ${finalReason}.`,\n );\n }\n\n /**\n * Reports spread props on an element\n */\n reportSpreadProps(element: JSXElement | ASTPath<JSXElement>): void {\n this.reportElement(element, 'contains spread props that need manual review');\n }\n\n /**\n * Reports conflicting prop and children\n */\n reportPropWithChildren(element: JSXElement | ASTPath<JSXElement>, propName: string): void {\n this.reportProp(\n element,\n propName,\n `conflicts with children - both \"${propName}\" prop and children are present`,\n );\n }\n\n /**\n * Reports unsupported prop value\n */\n reportUnsupportedValue(\n element: JSXElement | ASTPath<JSXElement>,\n propName: string,\n value: string,\n ): void {\n this.reportProp(element, propName, `has unsupported value \"${value}\"`);\n }\n\n /**\n * Reports ambiguous expression in prop\n */\n reportAmbiguousExpression(element: JSXElement | ASTPath<JSXElement>, propName: string): void {\n this.reportProp(element, propName, 'contains a complex expression that needs manual review');\n }\n\n /**\n * Reports ambiguous children (like dynamic icons)\n */\n reportAmbiguousChildren(element: JSXElement | ASTPath<JSXElement>, childType = 'content'): void {\n this.reportElement(element, `contains ambiguous ${childType} that needs manual review`);\n }\n\n /**\n * Reports deprecated prop usage\n */\n reportDeprecatedProp(\n element: JSXElement | ASTPath<JSXElement>,\n propName: string,\n alternative?: string,\n ): void {\n const suggestion = alternative ? ` Use ${alternative} instead` : '';\n this.reportProp(element, propName, `is deprecated${suggestion}`);\n }\n\n /**\n * Reports missing required prop\n */\n reportMissingRequiredProp(element: JSXElement | ASTPath<JSXElement>, propName: string): void {\n this.reportProp(element, propName, 'is required but missing');\n }\n\n /**\n * Reports conflicting props\n */\n reportConflictingProps(element: JSXElement | ASTPath<JSXElement>, propNames: string[]): void {\n const propList = propNames.map((name) => `\"${name}\"`).join(', ');\n this.reportElement(element, `has conflicting props: ${propList} cannot be used together`);\n }\n\n /**\n * Auto-detects and reports common attribute issues\n */\n reportAttributeIssues(element: JSXElement | ASTPath<JSXElement>): void {\n const node = this.getNode(element);\n const { attributes } = node.openingElement;\n\n if (!attributes) return;\n\n // Check for spread props\n if (attributes.some((attr) => attr.type === 'JSXSpreadAttribute')) {\n this.reportSpreadProps(element);\n }\n\n // Check for complex expressions in attributes\n attributes.forEach((attr) => {\n if (attr.type === 'JSXAttribute' && attr.value?.type === 'JSXExpressionContainer') {\n this.reportAttribute(attr, element);\n }\n });\n }\n\n /**\n * Finds and reports instances of components that are under an alias (imported with a different name)\n */\n reportAliases(element: JSXElement | ASTPath<JSXElement>): void {\n this.reportElement(element, 'is used via an import alias and needs manual review');\n }\n\n /**\n * Finds and reports instances of non-DS import declarations that conflict with the component name\n */\n reportConflictingImports(node: ImportSpecifier): void {\n this.addIssue(\n `Manual review required: Non-WDS package resulting in an import conflict at line ${this.getLineNumber(node)}.`,\n );\n }\n\n /**\n * Reports enum usage for future conversion tracking\n */\n reportEnumUsage(\n element: JSXElement | ASTPath<JSXElement>,\n propName: string,\n enumValue: string,\n ): void {\n this.reportProp(\n element,\n propName,\n `uses enum value \"${enumValue}\" which has been preserved but should be migrated to a string literal in the future`,\n );\n }\n\n // Private helper methods\n private getNode(element: JSXElement | ASTPath<JSXElement>): JSXElement {\n return 'node' in element ? element.node : element;\n }\n\n private getComponentName(node: JSXElement): string {\n const { name } = node.openingElement;\n if (name.type === 'JSXIdentifier') {\n return name.name;\n }\n // Handle JSXMemberExpression, JSXNamespacedName, etc.\n return this.j(name).toSource();\n }\n\n private getLineNumber(node: JSXElement | JSXAttribute | Node): string {\n return node.loc?.start.line?.toString() || 'unknown';\n }\n\n private getAttributeName(attr: JSXAttribute): string {\n if (attr.name.type === 'JSXIdentifier') {\n return attr.name.name;\n }\n return this.j(attr.name).toSource();\n }\n\n private getAttributeReason(attr: JSXAttribute): string {\n if (!attr.value) return 'has no value';\n\n if (attr.value.type === 'JSXExpressionContainer') {\n const expr = attr.value.expression;\n const expressionType = expr.type.replace('Expression', '').toLowerCase();\n\n // Show actual value for simple cases\n if (expr.type === 'Identifier' || expr.type === 'MemberExpression') {\n const valueText = this.j(expr).toSource();\n return `contains a ${expressionType} (${valueText})`;\n }\n\n return `contains a complex ${expressionType} expression`;\n }\n\n return 'needs manual review';\n }\n\n private addIssue(message: string): void {\n this.issues.push(message);\n }\n}\n\nexport const createReporter = (j: JSCodeshift, issues: string[]): CodemodReporter => {\n return new CodemodReporter({ jscodeshift: j, issues });\n};\n","import type { API, FileInfo, JSCodeshift, Options } from 'jscodeshift';\n\nimport { reportManualReview } from '../../controller/helpers';\nimport {\n addAttributesIfMissing,\n addImport,\n createReporter,\n findJSXElementsByName,\n hasAttributeOnElement,\n hasImport,\n processIconChildren,\n removeAttributeByName,\n setNameIfJSXIdentifier,\n} from '../../helpers';\n\nexport const parser = 'tsx';\n\ninterface LegacyProps {\n priority?: string;\n size?: string;\n type?: string;\n htmlType?: string;\n sentiment?: string;\n [key: string]: unknown;\n}\n\ninterface ExtendedOptions extends Options {\n accentSecondaryMapping?: string;\n positiveSecondaryMapping?: string;\n}\n\ntype PriorityMapping = Record<string, Record<string, string>>;\n\nconst buildPriorityMapping = (opts: Options): PriorityMapping => {\n const extendedOpts = opts as ExtendedOptions;\n const accentSecondary = extendedOpts.accentSecondaryMapping || 'secondary-neutral';\n const positiveSecondary = extendedOpts.positiveSecondaryMapping || 'secondary-neutral';\n return {\n accent: {\n primary: 'primary',\n secondary: accentSecondary,\n tertiary: 'tertiary',\n },\n positive: {\n primary: 'primary',\n secondary: positiveSecondary,\n tertiary: positiveSecondary,\n },\n negative: {\n primary: 'primary',\n secondary: 'secondary',\n tertiary: 'secondary',\n },\n primary: {\n primary: 'primary',\n secondary: accentSecondary,\n tertiary: 'tertiary',\n },\n pay: {\n primary: 'primary',\n secondary: accentSecondary,\n tertiary: accentSecondary,\n },\n };\n};\n\nconst sizeMap: Record<string, string> = {\n EXTRA_SMALL: 'xs',\n SMALL: 'sm',\n MEDIUM: 'md',\n LARGE: 'lg',\n EXTRA_LARGE: 'xl',\n xs: 'sm',\n sm: 'sm',\n md: 'md',\n lg: 'lg',\n xl: 'xl',\n};\n\nconst resolveSize = (size?: string): string | undefined => {\n if (!size) return size;\n const match = /^Size\\.(EXTRA_SMALL|SMALL|MEDIUM|LARGE|EXTRA_LARGE)$/u.exec(size);\n if (match) {\n return sizeMap[match[1]];\n }\n return sizeMap[size] || size;\n};\n\nconst legacyButtonTypes = [\n 'accent',\n 'negative',\n 'positive',\n 'primary',\n 'pay',\n 'secondary',\n 'danger',\n 'link',\n];\n\nconst getConsistentTypeConversions = (\n type?: string,\n): { priority?: string; sentiment?: string } | null => {\n const consistentTypeConversions: Record<string, { priority?: string; sentiment?: string }> = {\n secondary: { priority: 'secondary-neutral' },\n link: { priority: 'tertiary' },\n danger: { priority: 'secondary', sentiment: 'negative' },\n };\n\n return consistentTypeConversions[type || ''] || null;\n};\n\nconst convertEnumValue = (value?: string): string | undefined => {\n if (!value) return value;\n const strippedValue = value.replace(/^['\"]|['\"]$/gu, '');\n const enumMapping: Record<string, string> = {\n 'Priority.SECONDARY': 'secondary',\n 'Priority.PRIMARY': 'primary',\n 'Priority.TERTIARY': 'tertiary',\n 'ControlType.NEGATIVE': 'negative',\n 'ControlType.POSITIVE': 'positive',\n 'ControlType.ACCENT': 'accent',\n };\n return enumMapping[strippedValue] || strippedValue;\n};\n\n/**\n * Detects if a value is an enum pattern (e.g., Priority.PRIMARY, ControlType.ACCENT, Size.LARGE, Type.PRIMARY)\n */\nconst isEnumValue = (value: string): boolean => {\n const enumPatterns = [\n /^Priority\\.(PRIMARY|SECONDARY|TERTIARY|SECONDARY_NEUTRAL)$/u,\n /^ControlType\\.(ACCENT|NEGATIVE|POSITIVE)$/u,\n /^Size\\.(EXTRA_SMALL|SMALL|MEDIUM|LARGE|EXTRA_LARGE)$/u,\n /^Type\\.(PRIMARY|SECONDARY|TERTIARY|PAY|DANGER|LINK|ACCENT|POSITIVE|NEGATIVE)$/u,\n ];\n return enumPatterns.some((pattern) => pattern.test(value));\n};\n\n/**\n * Maps enum values to their expected string equivalents for validation purposes\n * This is ONLY used to validate the enum maps to a supported value\n */\nconst getEnumEquivalent = (value: string): string | undefined => {\n const enumMapping: Record<string, string> = {\n 'Priority.PRIMARY': 'primary',\n 'Priority.SECONDARY': 'secondary',\n 'Priority.TERTIARY': 'tertiary',\n 'Priority.SECONDARY_NEUTRAL': 'secondary-neutral',\n 'ControlType.NEGATIVE': 'negative',\n 'ControlType.POSITIVE': 'positive',\n 'ControlType.ACCENT': 'accent',\n 'Size.EXTRA_SMALL': 'sm',\n 'Size.SMALL': 'sm',\n 'Size.MEDIUM': 'md',\n 'Size.LARGE': 'lg',\n 'Size.EXTRA_LARGE': 'xl',\n };\n return enumMapping[value];\n};\n\n/**\n * This transform function modifies the Button and ActionButton components from the @transferwise/components library.\n * It updates the ActionButton component to use the Button component with specific attributes and mappings.\n * It also processes icon children and removes legacy props.\n *\n * @param {FileInfo} file - The file information object.\n * @param {API} api - The API object for jscodeshift.\n * @param {Options} options - The options object for jscodeshift.\n * @returns {string} - The transformed source code.\n */\nconst transformer = (file: FileInfo, api: API, options: Options) => {\n const j: JSCodeshift = api.jscodeshift;\n const root = j(file.source);\n const manualReviewIssues: string[] = [];\n const priorityMapping = buildPriorityMapping(options);\n\n const resolvePriority = (type?: string, priority?: string): string | undefined => {\n if (type && priority) {\n return priorityMapping[type]?.[priority] || priority;\n }\n return priority;\n };\n\n // Create reporter instance\n const reporter = createReporter(j, manualReviewIssues);\n\n const {\n exists: hasButtonImport,\n aliases: buttonAliases,\n resolvedName: buttonName,\n conflictingImports: conflictingButtonImport,\n } = hasImport(root, '@transferwise/components', 'Button', j);\n\n if (conflictingButtonImport.length) {\n conflictingButtonImport.forEach((node) => reporter.reportConflictingImports(node));\n }\n\n const {\n exists: hasActionButtonImport,\n remove: removeActionButtonImport,\n aliases: actionButtonAliases,\n } = hasImport(root, '@transferwise/components', 'ActionButton', j);\n\n if (!hasButtonImport && !hasActionButtonImport) {\n return file.source;\n }\n\n const iconImports = new Set<string>();\n root.find(j.ImportDeclaration, { source: { value: '@transferwise/icons' } }).forEach((path) => {\n path.node.specifiers?.forEach((specifier) => {\n if (\n (specifier.type === 'ImportDefaultSpecifier' || specifier.type === 'ImportSpecifier') &&\n specifier.local\n ) {\n const localName = (specifier.local as { name: string }).name;\n iconImports.add(localName);\n }\n });\n });\n\n if (hasActionButtonImport) {\n if (!hasButtonImport) {\n addImport(root, '@transferwise/components', 'Button', j);\n }\n\n const instances = findJSXElementsByName(root, j)('ActionButton', actionButtonAliases);\n\n instances.forEach((path) => {\n const { openingElement, closingElement } = path.node;\n\n openingElement.name = setNameIfJSXIdentifier(openingElement.name, buttonName)!;\n if (closingElement) {\n closingElement.name = setNameIfJSXIdentifier(closingElement.name, buttonName)!;\n }\n\n processIconChildren(j, path.node.children, iconImports, openingElement);\n\n if ((openingElement.attributes ?? []).some((attr) => attr.type === 'JSXSpreadAttribute')) {\n reporter.reportSpreadProps(path);\n }\n\n const legacyPropNames = ['priority', 'text', 'size'];\n const legacyProps: LegacyProps = {};\n\n openingElement.attributes?.forEach((attr) => {\n if (attr.type === 'JSXAttribute' && attr.name && attr.name.type === 'JSXIdentifier') {\n const { name } = attr.name;\n if (legacyPropNames.includes(name)) {\n if (attr.value) {\n if (attr.value.type === 'StringLiteral') {\n legacyProps[name] = attr.value.value;\n } else if (attr.value.type === 'JSXExpressionContainer') {\n legacyProps[name] = convertEnumValue(String(j(attr.value.expression).toSource()));\n }\n }\n }\n }\n });\n\n const hasTextProp = 'text' in legacyProps;\n const hasChildren =\n path.node.children?.some(\n (child) =>\n (child.type === 'JSXText' && child.value.trim() !== '') ||\n child.type === 'JSXElement' ||\n child.type === 'JSXExpressionContainer',\n ) ||\n (path.node.children && path.node.children?.length > 0);\n\n if (hasTextProp && hasChildren) {\n reporter.reportPropWithChildren(path, 'text');\n } else if (hasTextProp && !hasChildren && openingElement.selfClosing) {\n // Self-closing tag with text prop but no children, so we can convert to a normal element with children\n path.replace(\n j.jsxElement(\n j.jsxOpeningElement(openingElement.name, openingElement.attributes),\n j.jsxClosingElement(openingElement.name),\n [j.jsxText((legacyProps.text as string) || '')],\n ),\n );\n }\n\n addAttributesIfMissing(j, path.node.openingElement, [\n { attribute: j.jsxAttribute(j.jsxIdentifier('v2')), name: 'v2' },\n { attribute: j.jsxAttribute(j.jsxIdentifier('size'), j.literal('sm')), name: 'size' },\n ]);\n\n (path.node.children || []).forEach((child) => {\n if (child.type === 'JSXExpressionContainer') {\n const expr = child.expression;\n if (\n expr.type === 'ConditionalExpression' ||\n expr.type === 'CallExpression' ||\n expr.type === 'Identifier' ||\n expr.type === 'MemberExpression'\n ) {\n reporter.reportAmbiguousChildren(path, 'icon');\n }\n }\n });\n });\n\n removeActionButtonImport();\n }\n\n if (hasButtonImport) {\n const instances = findJSXElementsByName(root, j)('Button', buttonAliases);\n\n instances.forEach((path) => {\n const { openingElement } = path.node;\n\n if (hasAttributeOnElement(openingElement, 'v2')) return;\n\n const hasJSXChildren = path.node.children?.some(\n (child) =>\n (child.type === 'JSXText' && child.value.trim() !== '') ||\n child.type === 'JSXElement' ||\n (child.type === 'JSXFragment' && child.children && child.children.length > 0) ||\n (child.type === 'JSXExpressionContainer' &&\n child.expression.type !== 'JSXEmptyExpression'),\n );\n const hasChildrenAsProp = openingElement.attributes?.some(\n (attr) =>\n attr.type === 'JSXAttribute' &&\n attr.name?.type === 'JSXIdentifier' &&\n attr.name.name === 'children',\n );\n if (!hasJSXChildren && !hasChildrenAsProp) return;\n\n addAttributesIfMissing(j, openingElement, [\n { attribute: j.jsxAttribute(j.jsxIdentifier('v2')), name: 'v2' },\n ]);\n processIconChildren(j, path.node.children, iconImports, openingElement);\n\n const legacyProps: LegacyProps = {};\n const legacyPropNames = ['priority', 'size', 'type', 'htmlType', 'sentiment'];\n\n openingElement.attributes?.forEach((attr) => {\n if (attr.type === 'JSXAttribute' && attr.name && attr.name.type === 'JSXIdentifier') {\n const { name } = attr.name;\n if (legacyPropNames.includes(name)) {\n if (attr.value) {\n if (attr.value.type === 'StringLiteral') {\n legacyProps[name] = attr.value.value;\n } else if (attr.value.type === 'JSXExpressionContainer') {\n const expressionSource = String(j(attr.value.expression).toSource());\n legacyProps[name] = expressionSource;\n }\n } else {\n legacyProps[name] = undefined;\n }\n }\n }\n });\n\n if ('size' in legacyProps) {\n const rawValue = legacyProps.size;\n\n if (typeof rawValue === 'string' && isEnumValue(rawValue)) {\n const equivalent = getEnumEquivalent(rawValue);\n const supportedSizes = ['sm', 'md', 'lg', 'xl'];\n\n if (equivalent && supportedSizes.includes(equivalent)) {\n } else {\n reporter.reportUnsupportedValue(path, 'size', rawValue);\n }\n } else {\n const resolved = resolveSize(rawValue);\n const supportedSizes = ['sm', 'md', 'lg', 'xl'];\n if (\n typeof rawValue === 'string' &&\n typeof resolved === 'string' &&\n supportedSizes.includes(resolved)\n ) {\n removeAttributeByName(j, openingElement, 'size');\n openingElement.attributes?.push(\n j.jsxAttribute(j.jsxIdentifier('size'), j.literal(resolved)),\n );\n } else if (typeof rawValue === 'string') {\n reporter.reportUnsupportedValue(path, 'size', rawValue);\n } else if (rawValue !== undefined) {\n reporter.reportAmbiguousExpression(path, 'size');\n }\n }\n }\n\n if ('priority' in legacyProps) {\n const rawValue = legacyProps.priority;\n\n if (typeof rawValue === 'string' && isEnumValue(rawValue)) {\n const equivalent = getEnumEquivalent(rawValue);\n const supportedPriorities = ['primary', 'secondary', 'tertiary', 'secondary-neutral'];\n\n if (equivalent && supportedPriorities.includes(equivalent)) {\n } else {\n reporter.reportUnsupportedValue(path, 'priority', rawValue);\n }\n } else {\n const converted = convertEnumValue(rawValue);\n const mapped = resolvePriority(legacyProps.type, converted);\n const supportedPriorities = ['primary', 'secondary', 'tertiary', 'secondary-neutral'];\n if (\n typeof rawValue === 'string' &&\n typeof mapped === 'string' &&\n supportedPriorities.includes(mapped)\n ) {\n removeAttributeByName(j, openingElement, 'priority');\n openingElement.attributes?.push(\n j.jsxAttribute(j.jsxIdentifier('priority'), j.literal(mapped)),\n );\n } else if (typeof rawValue === 'string') {\n reporter.reportUnsupportedValue(path, 'priority', rawValue);\n } else if (rawValue !== undefined) {\n reporter.reportAmbiguousExpression(path, 'priority');\n }\n }\n }\n\n if ('type' in legacyProps || 'htmlType' in legacyProps) {\n const rawType = legacyProps.type;\n const rawHtmlType = legacyProps.htmlType;\n\n let resolvedType: string | undefined;\n let isTypeEnum = false;\n let isControlTypeEnum = false;\n\n if (typeof rawType === 'string' && isEnumValue(rawType)) {\n isTypeEnum = true;\n const equivalent = getEnumEquivalent(rawType);\n resolvedType = equivalent;\n isControlTypeEnum = rawType.startsWith('ControlType.');\n\n if (!isControlTypeEnum) {\n reporter.reportUnsupportedValue(path, 'type', rawType);\n }\n } else {\n let typeValue: string | undefined;\n if (typeof rawType === 'string') {\n typeValue = rawType;\n } else if (rawType && typeof rawType === 'object') {\n typeValue = convertEnumValue(j(rawType).toSource());\n }\n resolvedType = typeValue;\n }\n\n let finalHtmlType = null;\n if (resolvedType && !legacyButtonTypes.includes(resolvedType)) {\n finalHtmlType = resolvedType;\n }\n\n if (rawHtmlType) {\n finalHtmlType = rawHtmlType;\n }\n\n const htmlTypes = ['submit', 'button', 'reset'];\n\n if (resolvedType === 'negative' && isControlTypeEnum) {\n removeAttributeByName(j, openingElement, 'type');\n\n if (hasAttributeOnElement(openingElement, 'sentiment')) {\n removeAttributeByName(j, openingElement, 'sentiment');\n }\n\n addAttributesIfMissing(j, openingElement, [\n {\n attribute: j.jsxAttribute(j.jsxIdentifier('priority'), j.literal('primary')),\n name: 'priority',\n },\n ]);\n\n // Keep as enum\n if (rawType) {\n openingElement.attributes?.push(\n j.jsxAttribute(\n j.jsxIdentifier('sentiment'),\n j.jsxExpressionContainer(j.identifier(rawType)),\n ),\n );\n }\n } else if (resolvedType === 'negative' && !isTypeEnum) {\n // String literal 'negative'\n removeAttributeByName(j, openingElement, 'type');\n\n if (hasAttributeOnElement(openingElement, 'sentiment')) {\n removeAttributeByName(j, openingElement, 'sentiment');\n }\n\n openingElement.attributes?.push(\n j.jsxAttribute(j.jsxIdentifier('sentiment'), j.literal('negative')),\n );\n } else if (\n isControlTypeEnum &&\n resolvedType &&\n ['positive', 'accent'].includes(resolvedType)\n ) {\n removeAttributeByName(j, openingElement, 'type');\n addAttributesIfMissing(j, openingElement, [\n {\n attribute: j.jsxAttribute(j.jsxIdentifier('priority'), j.literal('primary')),\n name: 'priority',\n },\n ]);\n }\n\n if (\n resolvedType &&\n typeof resolvedType === 'string' &&\n legacyButtonTypes.includes(resolvedType) &&\n !isTypeEnum // Don't convert if it's an enum\n ) {\n const consistentConversion = getConsistentTypeConversions(resolvedType);\n\n if (consistentConversion) {\n removeAttributeByName(j, openingElement, 'type');\n removeAttributeByName(j, openingElement, 'priority');\n removeAttributeByName(j, openingElement, 'sentiment');\n\n if (consistentConversion.priority) {\n openingElement.attributes?.push(\n j.jsxAttribute(\n j.jsxIdentifier('priority'),\n j.literal(consistentConversion.priority),\n ),\n );\n }\n if (consistentConversion.sentiment) {\n openingElement.attributes?.push(\n j.jsxAttribute(\n j.jsxIdentifier('sentiment'),\n j.literal(consistentConversion.sentiment),\n ),\n );\n }\n } else {\n // if priority is present, then type is already handled. if not, add priority. always remove legacy type\n removeAttributeByName(j, openingElement, 'type');\n addAttributesIfMissing(j, openingElement, [\n {\n attribute: j.jsxAttribute(j.jsxIdentifier('priority'), j.literal('primary')),\n name: 'priority',\n },\n ]);\n }\n } else if (isTypeEnum) {\n // Enum value that isn't a supported control type - keep it as-is (already reported above)\n // Don't modify the attribute\n }\n\n // Handle htmlType conversion to type\n if (typeof finalHtmlType === 'string' && htmlTypes.includes(finalHtmlType)) {\n removeAttributeByName(j, openingElement, 'htmlType');\n openingElement.attributes?.push(\n j.jsxAttribute(j.jsxIdentifier('type'), j.literal(finalHtmlType)),\n );\n } else if (typeof rawType === 'string' || typeof rawHtmlType === 'string') {\n const valueToCheck = rawType ?? rawHtmlType ?? '';\n const legacyTypes = [\n 'accent',\n 'positive',\n 'negative',\n 'primary',\n 'secondary',\n 'danger',\n 'link',\n ];\n\n if (!legacyTypes.includes(valueToCheck)) {\n reporter.reportUnsupportedValue(path, 'type', valueToCheck);\n }\n } else if (rawType !== undefined || rawHtmlType !== undefined) {\n // Report ambiguous if we cannot determine the value\n reporter.reportAmbiguousExpression(\n path,\n typeof rawType === 'string' ? 'type' : 'htmlType',\n );\n }\n }\n\n // Handle sentiment prop\n if ('sentiment' in legacyProps) {\n const hasSentimentAttribute = openingElement.attributes?.some(\n (attr) => attr.type === 'JSXAttribute' && attr.name && attr.name.name === 'sentiment',\n );\n\n if (!hasSentimentAttribute) {\n const rawValue = legacyProps.sentiment;\n\n if (rawValue === 'negative') {\n removeAttributeByName(j, openingElement, 'sentiment');\n openingElement.attributes?.push(\n j.jsxAttribute(j.jsxIdentifier('sentiment'), j.literal('negative')),\n );\n } else if (typeof rawValue === 'string') {\n reporter.reportUnsupportedValue(path, 'sentiment', rawValue);\n } else if (rawValue !== undefined) {\n reporter.reportAmbiguousExpression(path, 'sentiment');\n }\n }\n }\n\n // Handle as prop and href\n let asIndex = -1;\n let asValue: string | null = null;\n let hrefExists = false;\n let asAmbiguous = false;\n let hrefAmbiguous = false;\n\n openingElement.attributes?.forEach((attr, index) => {\n if (attr.type === 'JSXAttribute' && attr.name) {\n if (attr.name.name === 'as') {\n if (attr.value) {\n if (attr.value.type === 'StringLiteral') {\n asValue = attr.value.value;\n } else if (attr.value.type === 'JSXExpressionContainer') {\n asAmbiguous = true;\n reporter.reportAttribute(attr, path);\n }\n }\n asIndex = index;\n }\n if (attr.name.name === 'href') {\n hrefExists = true;\n if (attr.value && attr.value.type !== 'StringLiteral') {\n hrefAmbiguous = true;\n reporter.reportAttribute(attr, path);\n }\n }\n }\n });\n\n if (asValue === 'a') {\n if (asIndex !== -1) {\n openingElement.attributes = openingElement.attributes?.filter(\n (_attr, idx) => idx !== asIndex,\n );\n }\n if (!hrefExists) {\n openingElement.attributes = [\n ...(openingElement.attributes ?? []),\n j.jsxAttribute(j.jsxIdentifier('href'), j.literal('#')),\n ];\n }\n }\n\n if ((openingElement.attributes ?? []).some((attr) => attr.type === 'JSXSpreadAttribute')) {\n reporter.reportSpreadProps(path);\n }\n });\n }\n\n if (manualReviewIssues.length > 0) {\n manualReviewIssues.forEach(async (issue) => {\n await reportManualReview(file.path, issue);\n });\n }\n\n return root.toSource();\n};\n\nexport default transformer;\n"],"mappings":"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"}
1
+ {"version":3,"file":"transformer.js","names":["result: ImportSpecifier[]","sizeMap: Record<string, string>","j: JSCodeshift","manualReviewIssues: string[]","hasImport","legacyProps: LegacyProps","resolvedType: string | undefined","typeValue: string | undefined","asValue: string | null","reportManualReview"],"sources":["../../../src/helpers/addImport.ts","../../../src/helpers/hasImport.ts","../../../src/helpers/iconUtils.ts","../../../src/helpers/jsxElementUtils.ts","../../../src/helpers/jsxReportingUtils.ts","../../../src/transforms/button/transformer.ts"],"sourcesContent":["import type { Collection, JSCodeshift } from 'jscodeshift';\n\n/**\n * Adds a named import if it doesn't already exist.\n */\nfunction addImport(\n root: Collection,\n sourceValue: string,\n importName: string,\n j: JSCodeshift,\n): void {\n const existingImports = root.find(j.ImportDeclaration, {\n source: { value: sourceValue },\n });\n\n if (existingImports.size() > 0) {\n const namedImport = existingImports.find(j.ImportSpecifier, {\n imported: { name: importName },\n });\n\n if (namedImport.size() > 0) {\n return;\n }\n\n existingImports.forEach((path) => {\n if (path.node.specifiers) {\n path.node.specifiers.push(j.importSpecifier(j.identifier(importName)));\n }\n });\n } else {\n const newImport = j.importDeclaration(\n [j.importSpecifier(j.identifier(importName))],\n j.literal(sourceValue),\n );\n\n const firstImport = root.find(j.ImportDeclaration).at(0);\n if (firstImport.size() > 0) {\n firstImport.insertBefore(newImport);\n } else {\n // Insert at the beginning of the program\n const program = root.find(j.Program);\n if (program.size() > 0) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n program.get('body', 0).insertBefore(newImport);\n }\n }\n }\n}\n\nexport default addImport;\n","import type { ASTPath, Collection, ImportSpecifier, JSCodeshift } from 'jscodeshift';\n\n/**\n * Checks if a specific import exists in the given root collection and provides\n * a method to remove it if found.\n */\nfunction hasImport(\n root: Collection,\n sourceValue: string,\n importName: string,\n j: JSCodeshift,\n): {\n exists: boolean;\n remove: () => void;\n aliases?: Collection<ImportSpecifier>;\n resolvedName: string;\n conflictingImports: ImportSpecifier[];\n} {\n const importDeclarations = root.find(j.ImportDeclaration, {\n source: { value: sourceValue },\n });\n\n /**\n * Finds all ImportSpecifier nodes that expose `importName` but\n * from a different source than `sourceValue`.\n */\n const conflictingImports = ((): ImportSpecifier[] => {\n const result: ImportSpecifier[] = [];\n root\n .find(j.ImportDeclaration)\n .filter((path) => path.node.source.value !== sourceValue)\n .forEach((path) => {\n for (const specifier of path.node.specifiers ?? []) {\n if (\n specifier.type === 'ImportSpecifier' &&\n specifier.imported.name === importName &&\n specifier.local?.name === importName\n ) {\n result.push(specifier);\n }\n }\n });\n return result;\n })();\n\n if (importDeclarations.size() === 0) {\n return {\n exists: false,\n remove: () => {},\n resolvedName: importName,\n conflictingImports,\n };\n }\n\n const namedImport = importDeclarations.find(j.ImportSpecifier, {\n imported: { name: importName },\n });\n\n const defaultImport = importDeclarations.find(j.ImportDefaultSpecifier, {\n local: { name: importName },\n });\n\n const aliasImport = importDeclarations.find(j.ImportSpecifier).filter((path) => {\n return (\n path.node.imported.name === importName && path.node.imported.name !== path.node.local?.name\n );\n });\n\n const exists = namedImport.size() > 0 || defaultImport.size() > 0;\n\n const resolveName = (): string => {\n if (aliasImport.size() > 0) {\n const importPath = aliasImport.get(0) as ASTPath<ImportSpecifier>;\n const localName = importPath.node.local?.name;\n\n if (typeof localName === 'string') {\n return localName;\n }\n\n if (\n localName &&\n typeof localName === 'object' &&\n 'name' in localName &&\n typeof localName.name === 'string'\n ) {\n return localName.name;\n }\n\n return importName;\n }\n\n return importName;\n };\n\n const remove = () => {\n importDeclarations.forEach((path) => {\n const filteredSpecifiers =\n path.node.specifiers?.filter((specifier) => {\n if (specifier.type === 'ImportSpecifier' && specifier.imported.name === importName) {\n return false;\n }\n if (specifier.type === 'ImportDefaultSpecifier' && specifier.local?.name === importName) {\n return false;\n }\n return true;\n }) ?? [];\n\n if (filteredSpecifiers.length === 0) {\n path.prune();\n } else {\n j(path).replaceWith(\n j.importDeclaration(filteredSpecifiers, path.node.source, path.node.importKind),\n );\n }\n });\n };\n\n return {\n exists,\n remove,\n aliases: aliasImport,\n resolvedName: resolveName(),\n conflictingImports,\n };\n}\n\nexport default hasImport;\n","import type { JSCodeshift, JSXElement, JSXExpressionContainer } from 'jscodeshift';\n\n/**\n * Process children of a JSX element to detect icon components and add iconStart or iconEnd attributes accordingly.\n * This is specific to icon handling but can be reused in codemods dealing with icon children.\n */\nconst processIconChildren = (\n j: JSCodeshift,\n children: (JSXElement | JSXExpressionContainer | unknown)[] | undefined,\n iconImports: Set<string>,\n openingElement: JSXElement['openingElement'],\n) => {\n if (!children || !openingElement.attributes) return;\n\n const unwrapJsxElement = (node: unknown): JSXElement | unknown => {\n if (\n typeof node === 'object' &&\n node !== null &&\n 'type' in node &&\n node.type === 'JSXExpressionContainer' &&\n j.JSXElement.check((node as JSXExpressionContainer).expression)\n ) {\n return (node as JSXExpressionContainer).expression;\n }\n return node;\n };\n\n const totalChildren = children.length;\n\n // Find index of icon child\n const iconChildIndex = children.findIndex((child) => {\n const unwrapped = unwrapJsxElement(child);\n return (\n j.JSXElement.check(unwrapped) &&\n unwrapped.openingElement.name.type === 'JSXIdentifier' &&\n iconImports.has(unwrapped.openingElement.name.name)\n );\n });\n\n if (iconChildIndex === -1) return;\n\n const iconChild = unwrapJsxElement(children[iconChildIndex]) as JSXElement;\n\n if (!iconChild || iconChild.openingElement.name.type !== 'JSXIdentifier') return;\n\n const iconName = iconChild.openingElement.name.name;\n\n // Determine if icon is closer to start or end\n const distanceToStart = iconChildIndex;\n const distanceToEnd = totalChildren - 1 - iconChildIndex;\n const iconPropName = distanceToStart <= distanceToEnd ? 'addonStart' : 'addonEnd';\n\n // Build: { type: 'icon', value: <IconName /> }\n const iconObject = j.objectExpression([\n j.property('init', j.identifier('type'), j.literal('icon')),\n j.property('init', j.identifier('value'), iconChild),\n ]);\n const iconProp = j.jsxAttribute(\n j.jsxIdentifier(iconPropName),\n j.jsxExpressionContainer(iconObject),\n );\n\n openingElement.attributes.push(iconProp);\n\n // Remove the icon child\n children.splice(iconChildIndex, 1);\n\n // Helper to check if a child is whitespace-only JSXText\n const isWhitespaceJsxText = (node: unknown): boolean => {\n return (\n typeof node === 'object' &&\n node !== null &&\n (node as { type?: unknown }).type === 'JSXText' &&\n typeof (node as { value?: string }).value === 'string' &&\n (node as { value?: string }).value!.trim() === ''\n );\n };\n\n // Remove adjacent whitespace-only JSXText node if any\n if (iconChildIndex - 1 >= 0 && isWhitespaceJsxText(children[iconChildIndex - 1])) {\n children.splice(iconChildIndex - 1, 1);\n } else if (isWhitespaceJsxText(children[iconChildIndex])) {\n children.splice(iconChildIndex, 1);\n }\n};\n\nexport default processIconChildren;\n","import type {\n Collection,\n ImportSpecifier,\n JSCodeshift,\n JSXAttribute,\n JSXElement,\n JSXIdentifier,\n JSXMemberExpression,\n JSXNamespacedName,\n JSXSpreadAttribute,\n} from 'jscodeshift';\n\n/**\n * Rename a JSX element name if it is a JSXIdentifier.\n */\nexport const setNameIfJSXIdentifier = (\n elementName: JSXIdentifier | JSXNamespacedName | JSXMemberExpression | undefined,\n newName: string,\n): JSXIdentifier | JSXNamespacedName | JSXMemberExpression | undefined => {\n if (elementName && elementName.type === 'JSXIdentifier') {\n return { ...elementName, name: newName };\n }\n return elementName;\n};\n\n/**\n * Check if a list of attributes contains a specific attribute by name.\n */\nexport const hasAttribute = (\n attributes: (JSXAttribute | JSXSpreadAttribute)[] | undefined,\n attributeName: string,\n): boolean => {\n return (\n Array.isArray(attributes) &&\n attributes.some(\n (attr): attr is JSXAttribute =>\n attr.type === 'JSXAttribute' &&\n attr.name.type === 'JSXIdentifier' &&\n attr.name.name === attributeName,\n )\n );\n};\n\n/**\n * Check if a JSX element's openingElement has a specific attribute.\n */\nexport const hasAttributeOnElement = (\n element: JSXElement['openingElement'],\n attributeName: string,\n): boolean => {\n return hasAttribute(element.attributes, attributeName);\n};\n\n/**\n * Add specified attributes to a JSX element's openingElement if they are not already present.\n */\nexport const addAttributesIfMissing = (\n j: JSCodeshift,\n openingElement: JSXElement['openingElement'],\n attributesToAdd: { attribute: JSXAttribute; name: string }[],\n) => {\n if (!Array.isArray(openingElement.attributes)) return;\n const attrs = openingElement.attributes;\n attributesToAdd.forEach(({ attribute, name }) => {\n if (!hasAttributeOnElement(openingElement, name)) {\n attrs.push(attribute);\n }\n });\n};\n\n/**\n * Returns a collection of JSX elements that match the specified\n * exported name or names of the found aliases.\n */\nexport const findJSXElementsByName =\n (root: Collection, j: JSCodeshift) =>\n (exportedName: string, aliases?: Collection<ImportSpecifier>) => {\n const aliasNames = aliases?.size()\n ? aliases.paths().map((path) => path.node.local?.name as string)\n : [];\n\n return root.find(j.JSXElement).filter((path) => {\n const { name } = path.node.openingElement;\n return (\n name.type === 'JSXIdentifier' &&\n (name.name === exportedName || aliasNames.includes(name.name))\n );\n });\n };\n\n/**\n * Removes an attribute by name from a JSX element's openingElement.\n */\nexport const removeAttributeByName = (\n j: JSCodeshift,\n openingElement: JSXElement['openingElement'],\n attributeName: string,\n) => {\n if (!Array.isArray(openingElement.attributes)) return;\n // eslint-disable-next-line no-param-reassign\n openingElement.attributes = openingElement.attributes.filter((attr) => {\n return !(\n attr.type === 'JSXAttribute' &&\n attr.name.type === 'JSXIdentifier' &&\n attr.name.name === attributeName\n );\n });\n};\n","import type {\n ASTPath,\n ImportSpecifier,\n JSCodeshift,\n JSXAttribute,\n JSXElement,\n Node,\n} from 'jscodeshift';\n\nexport interface ReporterOptions {\n jscodeshift: JSCodeshift;\n issues: string[];\n}\n\n/**\n * CodemodReporter is a utility class for reporting issues found during codemod transformations.\n * It provides methods to report issues related to JSX elements, props, and attributes.\n *\n * @example\n * ```typescript\n * const issues: string[] = [];\n * const reporter = createReporter(j, issues);\n *\n * // Report a deprecated prop\n * reporter.reportDeprecatedProp(buttonElement, 'flat', 'variant=\"text\"');\n *\n * // Report complex expression that needs review\n * reporter.reportAmbiguousExpression(element, 'size');\n *\n * // Auto-detect common issues\n * reporter.reportAttributeIssues(element);\n * ```\n */\nexport class CodemodReporter {\n private readonly j: JSCodeshift;\n private readonly issues: string[];\n\n constructor(options: ReporterOptions) {\n this.j = options.jscodeshift;\n this.issues = options.issues;\n }\n\n /**\n * Reports an issue with a JSX element\n */\n reportElement(element: JSXElement | ASTPath<JSXElement>, reason: string): void {\n const node = this.getNode(element);\n const componentName = this.getComponentName(node);\n const line = this.getLineNumber(node);\n\n this.addIssue(`Manual review required: <${componentName}> at line ${line} ${reason}.`);\n }\n\n /**\n * Reports an issue with a specific prop\n */\n reportProp(element: JSXElement | ASTPath<JSXElement>, propName: string, reason: string): void {\n const node = this.getNode(element);\n const componentName = this.getComponentName(node);\n const line = this.getLineNumber(node);\n\n this.addIssue(\n `Manual review required: prop \"${propName}\" on <${componentName}> at line ${line} ${reason}.`,\n );\n }\n\n /**\n * Reports an issue with a JSX attribute directly\n */\n reportAttribute(\n attr: JSXAttribute,\n element: JSXElement | ASTPath<JSXElement>,\n reason?: string,\n ): void {\n const node = this.getNode(element);\n const componentName = this.getComponentName(node);\n const propName = this.getAttributeName(attr);\n const line = this.getLineNumber(attr) || this.getLineNumber(node);\n\n const defaultReason = this.getAttributeReason(attr);\n const finalReason = reason || defaultReason;\n\n this.addIssue(\n `Manual review required: prop \"${propName}\" on <${componentName}> at line ${line} ${finalReason}.`,\n );\n }\n\n /**\n * Reports spread props on an element\n */\n reportSpreadProps(element: JSXElement | ASTPath<JSXElement>): void {\n this.reportElement(element, 'contains spread props that need manual review');\n }\n\n /**\n * Reports conflicting prop and children\n */\n reportPropWithChildren(element: JSXElement | ASTPath<JSXElement>, propName: string): void {\n this.reportProp(\n element,\n propName,\n `conflicts with children - both \"${propName}\" prop and children are present`,\n );\n }\n\n /**\n * Reports unsupported prop value\n */\n reportUnsupportedValue(\n element: JSXElement | ASTPath<JSXElement>,\n propName: string,\n value: string,\n ): void {\n this.reportProp(element, propName, `has unsupported value \"${value}\"`);\n }\n\n /**\n * Reports ambiguous expression in prop\n */\n reportAmbiguousExpression(element: JSXElement | ASTPath<JSXElement>, propName: string): void {\n this.reportProp(element, propName, 'contains a complex expression that needs manual review');\n }\n\n /**\n * Reports ambiguous children (like dynamic icons)\n */\n reportAmbiguousChildren(element: JSXElement | ASTPath<JSXElement>, childType = 'content'): void {\n this.reportElement(element, `contains ambiguous ${childType} that needs manual review`);\n }\n\n /**\n * Reports deprecated prop usage\n */\n reportDeprecatedProp(\n element: JSXElement | ASTPath<JSXElement>,\n propName: string,\n alternative?: string,\n ): void {\n const suggestion = alternative ? ` Use ${alternative} instead` : '';\n this.reportProp(element, propName, `is deprecated${suggestion}`);\n }\n\n /**\n * Reports missing required prop\n */\n reportMissingRequiredProp(element: JSXElement | ASTPath<JSXElement>, propName: string): void {\n this.reportProp(element, propName, 'is required but missing');\n }\n\n /**\n * Reports conflicting props\n */\n reportConflictingProps(element: JSXElement | ASTPath<JSXElement>, propNames: string[]): void {\n const propList = propNames.map((name) => `\"${name}\"`).join(', ');\n this.reportElement(element, `has conflicting props: ${propList} cannot be used together`);\n }\n\n /**\n * Auto-detects and reports common attribute issues\n */\n reportAttributeIssues(element: JSXElement | ASTPath<JSXElement>): void {\n const node = this.getNode(element);\n const { attributes } = node.openingElement;\n\n if (!attributes) return;\n\n // Check for spread props\n if (attributes.some((attr) => attr.type === 'JSXSpreadAttribute')) {\n this.reportSpreadProps(element);\n }\n\n // Check for complex expressions in attributes\n attributes.forEach((attr) => {\n if (attr.type === 'JSXAttribute' && attr.value?.type === 'JSXExpressionContainer') {\n this.reportAttribute(attr, element);\n }\n });\n }\n\n /**\n * Finds and reports instances of components that are under an alias (imported with a different name)\n */\n reportAliases(element: JSXElement | ASTPath<JSXElement>): void {\n this.reportElement(element, 'is used via an import alias and needs manual review');\n }\n\n /**\n * Finds and reports instances of non-DS import declarations that conflict with the component name\n */\n reportConflictingImports(node: ImportSpecifier): void {\n this.addIssue(\n `Manual review required: Non-WDS package resulting in an import conflict at line ${this.getLineNumber(node)}.`,\n );\n }\n\n /**\n * Reports enum usage for future conversion tracking\n */\n reportEnumUsage(\n element: JSXElement | ASTPath<JSXElement>,\n propName: string,\n enumValue: string,\n ): void {\n this.reportProp(\n element,\n propName,\n `uses enum value \"${enumValue}\" which has been preserved but should be migrated to a string literal in the future`,\n );\n }\n\n // Private helper methods\n private getNode(element: JSXElement | ASTPath<JSXElement>): JSXElement {\n return 'node' in element ? element.node : element;\n }\n\n private getComponentName(node: JSXElement): string {\n const { name } = node.openingElement;\n if (name.type === 'JSXIdentifier') {\n return name.name;\n }\n // Handle JSXMemberExpression, JSXNamespacedName, etc.\n return this.j(name).toSource();\n }\n\n private getLineNumber(node: JSXElement | JSXAttribute | Node): string {\n return node.loc?.start.line?.toString() || 'unknown';\n }\n\n private getAttributeName(attr: JSXAttribute): string {\n if (attr.name.type === 'JSXIdentifier') {\n return attr.name.name;\n }\n return this.j(attr.name).toSource();\n }\n\n private getAttributeReason(attr: JSXAttribute): string {\n if (!attr.value) return 'has no value';\n\n if (attr.value.type === 'JSXExpressionContainer') {\n const expr = attr.value.expression;\n const expressionType = expr.type.replace('Expression', '').toLowerCase();\n\n // Show actual value for simple cases\n if (expr.type === 'Identifier' || expr.type === 'MemberExpression') {\n const valueText = this.j(expr).toSource();\n return `contains a ${expressionType} (${valueText})`;\n }\n\n return `contains a complex ${expressionType} expression`;\n }\n\n return 'needs manual review';\n }\n\n private addIssue(message: string): void {\n this.issues.push(message);\n }\n}\n\nexport const createReporter = (j: JSCodeshift, issues: string[]): CodemodReporter => {\n return new CodemodReporter({ jscodeshift: j, issues });\n};\n","import type { API, FileInfo, JSCodeshift, Options } from 'jscodeshift';\n\nimport { reportManualReview } from '../../controller/helpers';\nimport {\n addAttributesIfMissing,\n addImport,\n createReporter,\n findJSXElementsByName,\n hasAttributeOnElement,\n hasImport,\n processIconChildren,\n removeAttributeByName,\n setNameIfJSXIdentifier,\n} from '../../helpers';\n\nexport const parser = 'tsx';\n\ninterface LegacyProps {\n priority?: string;\n size?: string;\n type?: string;\n htmlType?: string;\n sentiment?: string;\n [key: string]: unknown;\n}\n\ninterface ExtendedOptions extends Options {\n accentSecondaryMapping?: string;\n positiveSecondaryMapping?: string;\n}\n\ntype PriorityMapping = Record<string, Record<string, string>>;\n\nconst buildPriorityMapping = (opts: Options): PriorityMapping => {\n const extendedOpts = opts as ExtendedOptions;\n const accentSecondary = extendedOpts.accentSecondaryMapping || 'secondary-neutral';\n const positiveSecondary = extendedOpts.positiveSecondaryMapping || 'secondary-neutral';\n return {\n accent: {\n primary: 'primary',\n secondary: accentSecondary,\n tertiary: 'tertiary',\n },\n positive: {\n primary: 'primary',\n secondary: positiveSecondary,\n tertiary: positiveSecondary,\n },\n negative: {\n primary: 'primary',\n secondary: 'secondary',\n tertiary: 'secondary',\n },\n primary: {\n primary: 'primary',\n secondary: accentSecondary,\n tertiary: 'tertiary',\n },\n pay: {\n primary: 'primary',\n secondary: accentSecondary,\n tertiary: accentSecondary,\n },\n };\n};\n\nconst sizeMap: Record<string, string> = {\n EXTRA_SMALL: 'xs',\n SMALL: 'sm',\n MEDIUM: 'md',\n LARGE: 'lg',\n EXTRA_LARGE: 'xl',\n xs: 'sm',\n sm: 'sm',\n md: 'md',\n lg: 'lg',\n xl: 'xl',\n};\n\nconst resolveSize = (size?: string): string | undefined => {\n if (!size) return size;\n const match = /^Size\\.(EXTRA_SMALL|SMALL|MEDIUM|LARGE|EXTRA_LARGE)$/u.exec(size);\n if (match) {\n return sizeMap[match[1]];\n }\n return sizeMap[size] || size;\n};\n\nconst legacyButtonTypes = [\n 'accent',\n 'negative',\n 'positive',\n 'primary',\n 'pay',\n 'secondary',\n 'danger',\n 'link',\n];\n\nconst getConsistentTypeConversions = (\n type?: string,\n): { priority?: string; sentiment?: string } | null => {\n const consistentTypeConversions: Record<string, { priority?: string; sentiment?: string }> = {\n secondary: { priority: 'secondary-neutral' },\n link: { priority: 'tertiary' },\n danger: { priority: 'secondary', sentiment: 'negative' },\n };\n\n return consistentTypeConversions[type || ''] || null;\n};\n\nconst convertEnumValue = (value?: string): string | undefined => {\n if (!value) return value;\n const strippedValue = value.replace(/^['\"]|['\"]$/gu, '');\n const enumMapping: Record<string, string> = {\n 'Priority.SECONDARY': 'secondary',\n 'Priority.PRIMARY': 'primary',\n 'Priority.TERTIARY': 'tertiary',\n 'ControlType.NEGATIVE': 'negative',\n 'ControlType.POSITIVE': 'positive',\n 'ControlType.ACCENT': 'accent',\n };\n return enumMapping[strippedValue] || strippedValue;\n};\n\n/**\n * Detects if a value is an enum pattern (e.g., Priority.PRIMARY, ControlType.ACCENT, Size.LARGE, Type.PRIMARY)\n */\nconst isEnumValue = (value: string): boolean => {\n const enumPatterns = [\n /^Priority\\.(PRIMARY|SECONDARY|TERTIARY|SECONDARY_NEUTRAL)$/u,\n /^ControlType\\.(ACCENT|NEGATIVE|POSITIVE)$/u,\n /^Size\\.(EXTRA_SMALL|SMALL|MEDIUM|LARGE|EXTRA_LARGE)$/u,\n /^Type\\.(PRIMARY|SECONDARY|TERTIARY|PAY|DANGER|LINK|ACCENT|POSITIVE|NEGATIVE)$/u,\n ];\n return enumPatterns.some((pattern) => pattern.test(value));\n};\n\n/**\n * Maps enum values to their expected string equivalents for validation purposes\n * This is ONLY used to validate the enum maps to a supported value\n */\nconst getEnumEquivalent = (value: string): string | undefined => {\n const enumMapping: Record<string, string> = {\n 'Priority.PRIMARY': 'primary',\n 'Priority.SECONDARY': 'secondary',\n 'Priority.TERTIARY': 'tertiary',\n 'Priority.SECONDARY_NEUTRAL': 'secondary-neutral',\n 'ControlType.NEGATIVE': 'negative',\n 'ControlType.POSITIVE': 'positive',\n 'ControlType.ACCENT': 'accent',\n 'Size.EXTRA_SMALL': 'sm',\n 'Size.SMALL': 'sm',\n 'Size.MEDIUM': 'md',\n 'Size.LARGE': 'lg',\n 'Size.EXTRA_LARGE': 'xl',\n };\n return enumMapping[value];\n};\n\n/**\n * This transform function modifies the Button and ActionButton components from the @transferwise/components library.\n * It updates the ActionButton component to use the Button component with specific attributes and mappings.\n * It also processes icon children and removes legacy props.\n *\n * @param {FileInfo} file - The file information object.\n * @param {API} api - The API object for jscodeshift.\n * @param {Options} options - The options object for jscodeshift.\n * @returns {string} - The transformed source code.\n */\nconst transformer = (file: FileInfo, api: API, options: Options) => {\n const j: JSCodeshift = api.jscodeshift;\n const root = j(file.source);\n const manualReviewIssues: string[] = [];\n const priorityMapping = buildPriorityMapping(options);\n\n const resolvePriority = (type?: string, priority?: string): string | undefined => {\n if (type && priority) {\n return priorityMapping[type]?.[priority] || priority;\n }\n return priority;\n };\n\n // Create reporter instance\n const reporter = createReporter(j, manualReviewIssues);\n\n const {\n exists: hasButtonImport,\n aliases: buttonAliases,\n resolvedName: buttonName,\n conflictingImports: conflictingButtonImport,\n } = hasImport(root, '@transferwise/components', 'Button', j);\n\n if (conflictingButtonImport.length) {\n conflictingButtonImport.forEach((node) => reporter.reportConflictingImports(node));\n }\n\n const {\n exists: hasActionButtonImport,\n remove: removeActionButtonImport,\n aliases: actionButtonAliases,\n } = hasImport(root, '@transferwise/components', 'ActionButton', j);\n\n if (!hasButtonImport && !hasActionButtonImport) {\n return file.source;\n }\n\n const iconImports = new Set<string>();\n root.find(j.ImportDeclaration, { source: { value: '@transferwise/icons' } }).forEach((path) => {\n path.node.specifiers?.forEach((specifier) => {\n if (\n (specifier.type === 'ImportDefaultSpecifier' || specifier.type === 'ImportSpecifier') &&\n specifier.local\n ) {\n const localName = (specifier.local as { name: string }).name;\n iconImports.add(localName);\n }\n });\n });\n\n if (hasActionButtonImport) {\n if (!hasButtonImport) {\n addImport(root, '@transferwise/components', 'Button', j);\n }\n\n const instances = findJSXElementsByName(root, j)('ActionButton', actionButtonAliases);\n\n instances.forEach((path) => {\n const { openingElement, closingElement } = path.node;\n\n openingElement.name = setNameIfJSXIdentifier(openingElement.name, buttonName)!;\n if (closingElement) {\n closingElement.name = setNameIfJSXIdentifier(closingElement.name, buttonName)!;\n }\n\n processIconChildren(j, path.node.children, iconImports, openingElement);\n\n if ((openingElement.attributes ?? []).some((attr) => attr.type === 'JSXSpreadAttribute')) {\n reporter.reportSpreadProps(path);\n }\n\n const legacyPropNames = ['priority', 'text', 'size'];\n const legacyProps: LegacyProps = {};\n\n openingElement.attributes?.forEach((attr) => {\n if (attr.type === 'JSXAttribute' && attr.name && attr.name.type === 'JSXIdentifier') {\n const { name } = attr.name;\n if (legacyPropNames.includes(name)) {\n if (attr.value) {\n if (attr.value.type === 'StringLiteral') {\n legacyProps[name] = attr.value.value;\n } else if (attr.value.type === 'JSXExpressionContainer') {\n legacyProps[name] = convertEnumValue(String(j(attr.value.expression).toSource()));\n }\n }\n }\n }\n });\n\n const hasTextProp = 'text' in legacyProps;\n const hasChildren =\n path.node.children?.some(\n (child) =>\n (child.type === 'JSXText' && child.value.trim() !== '') ||\n child.type === 'JSXElement' ||\n child.type === 'JSXExpressionContainer',\n ) ||\n (path.node.children && path.node.children?.length > 0);\n\n if (hasTextProp && hasChildren) {\n reporter.reportPropWithChildren(path, 'text');\n } else if (hasTextProp && !hasChildren && openingElement.selfClosing) {\n // Self-closing tag with text prop but no children, so we can convert to a normal element with children\n path.replace(\n j.jsxElement(\n j.jsxOpeningElement(openingElement.name, openingElement.attributes),\n j.jsxClosingElement(openingElement.name),\n [j.jsxText((legacyProps.text as string) || '')],\n ),\n );\n }\n\n addAttributesIfMissing(j, path.node.openingElement, [\n { attribute: j.jsxAttribute(j.jsxIdentifier('v2')), name: 'v2' },\n { attribute: j.jsxAttribute(j.jsxIdentifier('size'), j.literal('sm')), name: 'size' },\n ]);\n\n (path.node.children || []).forEach((child) => {\n if (child.type === 'JSXExpressionContainer') {\n const expr = child.expression;\n if (\n expr.type === 'ConditionalExpression' ||\n expr.type === 'CallExpression' ||\n expr.type === 'Identifier' ||\n expr.type === 'MemberExpression'\n ) {\n reporter.reportAmbiguousChildren(path, 'icon');\n }\n }\n });\n });\n\n removeActionButtonImport();\n }\n\n if (hasButtonImport) {\n const instances = findJSXElementsByName(root, j)('Button', buttonAliases);\n\n instances.forEach((path) => {\n const { openingElement } = path.node;\n\n if (hasAttributeOnElement(openingElement, 'v2')) return;\n\n const hasJSXChildren = path.node.children?.some(\n (child) =>\n (child.type === 'JSXText' && child.value.trim() !== '') ||\n child.type === 'JSXElement' ||\n (child.type === 'JSXFragment' && child.children && child.children.length > 0) ||\n (child.type === 'JSXExpressionContainer' &&\n child.expression.type !== 'JSXEmptyExpression'),\n );\n const hasChildrenAsProp = openingElement.attributes?.some(\n (attr) =>\n attr.type === 'JSXAttribute' &&\n attr.name?.type === 'JSXIdentifier' &&\n attr.name.name === 'children',\n );\n if (!hasJSXChildren && !hasChildrenAsProp) return;\n\n addAttributesIfMissing(j, openingElement, [\n { attribute: j.jsxAttribute(j.jsxIdentifier('v2')), name: 'v2' },\n ]);\n processIconChildren(j, path.node.children, iconImports, openingElement);\n\n const legacyProps: LegacyProps = {};\n const legacyPropNames = ['priority', 'size', 'type', 'htmlType', 'sentiment'];\n\n openingElement.attributes?.forEach((attr) => {\n if (attr.type === 'JSXAttribute' && attr.name && attr.name.type === 'JSXIdentifier') {\n const { name } = attr.name;\n if (legacyPropNames.includes(name)) {\n if (attr.value) {\n if (attr.value.type === 'StringLiteral') {\n legacyProps[name] = attr.value.value;\n } else if (attr.value.type === 'JSXExpressionContainer') {\n const expressionSource = String(j(attr.value.expression).toSource());\n legacyProps[name] = expressionSource;\n }\n } else {\n legacyProps[name] = undefined;\n }\n }\n }\n });\n\n if ('size' in legacyProps) {\n const rawValue = legacyProps.size;\n\n if (typeof rawValue === 'string' && isEnumValue(rawValue)) {\n const equivalent = getEnumEquivalent(rawValue);\n const supportedSizes = ['sm', 'md', 'lg', 'xl'];\n\n if (equivalent && supportedSizes.includes(equivalent)) {\n } else {\n reporter.reportUnsupportedValue(path, 'size', rawValue);\n }\n } else {\n const resolved = resolveSize(rawValue);\n const supportedSizes = ['sm', 'md', 'lg', 'xl'];\n if (\n typeof rawValue === 'string' &&\n typeof resolved === 'string' &&\n supportedSizes.includes(resolved)\n ) {\n removeAttributeByName(j, openingElement, 'size');\n openingElement.attributes?.push(\n j.jsxAttribute(j.jsxIdentifier('size'), j.literal(resolved)),\n );\n } else if (typeof rawValue === 'string') {\n reporter.reportUnsupportedValue(path, 'size', rawValue);\n } else if (rawValue !== undefined) {\n reporter.reportAmbiguousExpression(path, 'size');\n }\n }\n }\n\n if ('priority' in legacyProps) {\n const rawValue = legacyProps.priority;\n\n if (typeof rawValue === 'string' && isEnumValue(rawValue)) {\n const equivalent = getEnumEquivalent(rawValue);\n const supportedPriorities = ['primary', 'secondary', 'tertiary', 'secondary-neutral'];\n\n if (equivalent && supportedPriorities.includes(equivalent)) {\n } else {\n reporter.reportUnsupportedValue(path, 'priority', rawValue);\n }\n } else {\n const converted = convertEnumValue(rawValue);\n const mapped = resolvePriority(legacyProps.type, converted);\n const supportedPriorities = ['primary', 'secondary', 'tertiary', 'secondary-neutral'];\n if (\n typeof rawValue === 'string' &&\n typeof mapped === 'string' &&\n supportedPriorities.includes(mapped)\n ) {\n removeAttributeByName(j, openingElement, 'priority');\n openingElement.attributes?.push(\n j.jsxAttribute(j.jsxIdentifier('priority'), j.literal(mapped)),\n );\n } else if (typeof rawValue === 'string') {\n reporter.reportUnsupportedValue(path, 'priority', rawValue);\n } else if (rawValue !== undefined) {\n reporter.reportAmbiguousExpression(path, 'priority');\n }\n }\n }\n\n if ('type' in legacyProps || 'htmlType' in legacyProps) {\n const rawType = legacyProps.type;\n const rawHtmlType = legacyProps.htmlType;\n\n let resolvedType: string | undefined;\n let isTypeEnum = false;\n let isControlTypeEnum = false;\n\n if (typeof rawType === 'string' && isEnumValue(rawType)) {\n isTypeEnum = true;\n const equivalent = getEnumEquivalent(rawType);\n resolvedType = equivalent;\n isControlTypeEnum = rawType.startsWith('ControlType.');\n\n if (!isControlTypeEnum) {\n reporter.reportUnsupportedValue(path, 'type', rawType);\n }\n } else {\n let typeValue: string | undefined;\n if (typeof rawType === 'string') {\n typeValue = rawType;\n } else if (rawType && typeof rawType === 'object') {\n typeValue = convertEnumValue(j(rawType).toSource());\n }\n resolvedType = typeValue;\n }\n\n let finalHtmlType = null;\n if (resolvedType && !legacyButtonTypes.includes(resolvedType)) {\n finalHtmlType = resolvedType;\n }\n\n if (rawHtmlType) {\n finalHtmlType = rawHtmlType;\n }\n\n const htmlTypes = ['submit', 'button', 'reset'];\n\n if (resolvedType === 'negative' && isControlTypeEnum) {\n removeAttributeByName(j, openingElement, 'type');\n\n if (hasAttributeOnElement(openingElement, 'sentiment')) {\n removeAttributeByName(j, openingElement, 'sentiment');\n }\n\n addAttributesIfMissing(j, openingElement, [\n {\n attribute: j.jsxAttribute(j.jsxIdentifier('priority'), j.literal('primary')),\n name: 'priority',\n },\n ]);\n\n // Keep as enum\n if (rawType) {\n openingElement.attributes?.push(\n j.jsxAttribute(\n j.jsxIdentifier('sentiment'),\n j.jsxExpressionContainer(j.identifier(rawType)),\n ),\n );\n }\n } else if (resolvedType === 'negative' && !isTypeEnum) {\n // String literal 'negative'\n removeAttributeByName(j, openingElement, 'type');\n\n if (hasAttributeOnElement(openingElement, 'sentiment')) {\n removeAttributeByName(j, openingElement, 'sentiment');\n }\n\n openingElement.attributes?.push(\n j.jsxAttribute(j.jsxIdentifier('sentiment'), j.literal('negative')),\n );\n } else if (\n isControlTypeEnum &&\n resolvedType &&\n ['positive', 'accent'].includes(resolvedType)\n ) {\n removeAttributeByName(j, openingElement, 'type');\n addAttributesIfMissing(j, openingElement, [\n {\n attribute: j.jsxAttribute(j.jsxIdentifier('priority'), j.literal('primary')),\n name: 'priority',\n },\n ]);\n }\n\n if (\n resolvedType &&\n typeof resolvedType === 'string' &&\n legacyButtonTypes.includes(resolvedType) &&\n !isTypeEnum // Don't convert if it's an enum\n ) {\n const consistentConversion = getConsistentTypeConversions(resolvedType);\n\n if (consistentConversion) {\n removeAttributeByName(j, openingElement, 'type');\n removeAttributeByName(j, openingElement, 'priority');\n removeAttributeByName(j, openingElement, 'sentiment');\n\n if (consistentConversion.priority) {\n openingElement.attributes?.push(\n j.jsxAttribute(\n j.jsxIdentifier('priority'),\n j.literal(consistentConversion.priority),\n ),\n );\n }\n if (consistentConversion.sentiment) {\n openingElement.attributes?.push(\n j.jsxAttribute(\n j.jsxIdentifier('sentiment'),\n j.literal(consistentConversion.sentiment),\n ),\n );\n }\n } else {\n // if priority is present, then type is already handled. if not, add priority. always remove legacy type\n removeAttributeByName(j, openingElement, 'type');\n addAttributesIfMissing(j, openingElement, [\n {\n attribute: j.jsxAttribute(j.jsxIdentifier('priority'), j.literal('primary')),\n name: 'priority',\n },\n ]);\n }\n } else if (isTypeEnum) {\n // Enum value that isn't a supported control type - keep it as-is (already reported above)\n // Don't modify the attribute\n }\n\n // Handle htmlType conversion to type\n if (typeof finalHtmlType === 'string' && htmlTypes.includes(finalHtmlType)) {\n removeAttributeByName(j, openingElement, 'htmlType');\n openingElement.attributes?.push(\n j.jsxAttribute(j.jsxIdentifier('type'), j.literal(finalHtmlType)),\n );\n } else if (typeof rawType === 'string' || typeof rawHtmlType === 'string') {\n const valueToCheck = rawType ?? rawHtmlType ?? '';\n const legacyTypes = [\n 'accent',\n 'positive',\n 'negative',\n 'primary',\n 'secondary',\n 'danger',\n 'link',\n ];\n\n if (!legacyTypes.includes(valueToCheck)) {\n reporter.reportUnsupportedValue(path, 'type', valueToCheck);\n }\n } else if (rawType !== undefined || rawHtmlType !== undefined) {\n // Report ambiguous if we cannot determine the value\n reporter.reportAmbiguousExpression(\n path,\n typeof rawType === 'string' ? 'type' : 'htmlType',\n );\n }\n }\n\n // Handle sentiment prop\n if ('sentiment' in legacyProps) {\n const hasSentimentAttribute = openingElement.attributes?.some(\n (attr) => attr.type === 'JSXAttribute' && attr.name && attr.name.name === 'sentiment',\n );\n\n if (!hasSentimentAttribute) {\n const rawValue = legacyProps.sentiment;\n\n if (rawValue === 'negative') {\n removeAttributeByName(j, openingElement, 'sentiment');\n openingElement.attributes?.push(\n j.jsxAttribute(j.jsxIdentifier('sentiment'), j.literal('negative')),\n );\n } else if (typeof rawValue === 'string') {\n reporter.reportUnsupportedValue(path, 'sentiment', rawValue);\n } else if (rawValue !== undefined) {\n reporter.reportAmbiguousExpression(path, 'sentiment');\n }\n }\n }\n\n // Handle as prop and href\n let asIndex = -1;\n let asValue: string | null = null;\n let hrefExists = false;\n let asAmbiguous = false;\n let hrefAmbiguous = false;\n\n openingElement.attributes?.forEach((attr, index) => {\n if (attr.type === 'JSXAttribute' && attr.name) {\n if (attr.name.name === 'as') {\n if (attr.value) {\n if (attr.value.type === 'StringLiteral') {\n asValue = attr.value.value;\n } else if (attr.value.type === 'JSXExpressionContainer') {\n asAmbiguous = true;\n reporter.reportAttribute(attr, path);\n }\n }\n asIndex = index;\n }\n if (attr.name.name === 'href') {\n hrefExists = true;\n if (attr.value && attr.value.type !== 'StringLiteral') {\n hrefAmbiguous = true;\n reporter.reportAttribute(attr, path);\n }\n }\n }\n });\n\n if (asValue === 'a') {\n if (asIndex !== -1) {\n openingElement.attributes = openingElement.attributes?.filter(\n (_attr, idx) => idx !== asIndex,\n );\n }\n if (!hrefExists) {\n openingElement.attributes = [\n ...(openingElement.attributes ?? []),\n j.jsxAttribute(j.jsxIdentifier('href'), j.literal('#')),\n ];\n }\n }\n\n if ((openingElement.attributes ?? []).some((attr) => attr.type === 'JSXSpreadAttribute')) {\n reporter.reportSpreadProps(path);\n }\n });\n }\n\n if (manualReviewIssues.length > 0) {\n manualReviewIssues.forEach(async (issue) => {\n await reportManualReview(file.path, issue);\n });\n }\n\n return root.toSource();\n};\n\nexport default transformer;\n"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
- const require_transformer = require('../../transformer-1c7Qg1GE.js');
1
+ require('../../constants-BhVbK_XZ.js');
2
+ const require_transformer = require('../../transformer-C-pTwN11.js');
2
3
 
3
4
  module.exports = require_transformer.transformer_default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wise/wds-codemods",
3
- "version": "1.0.0-experimental-88c6a83",
3
+ "version": "1.0.0-experimental-b6085e2",
4
4
  "license": "UNLICENSED",
5
5
  "author": "Wise Payments Ltd.",
6
6
  "repository": {