@wise/wds-codemods 0.0.1-experimental-517fc6b → 0.0.1-experimental-d6a8c5c

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["path","fs","findPackages","findProjectRoot","loadTransformModules","logToInquirer","transformFile: string","runTransformPrompts","getOptions","assessPrerequisites","error: unknown"],"sources":["../src/controller/index.ts","../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { execSync } from 'node:child_process';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { select as list } from '@inquirer/prompts';\n\nimport {\n assessPrerequisites,\n findPackages,\n findProjectRoot,\n getOptions,\n loadTransformModules,\n logToInquirer,\n runTransformPrompts,\n} from './helpers';\n\nlet isDebug = false;\nconst currentFilePath = fileURLToPath(import.meta.url);\nconst currentDirPath = path.dirname(currentFilePath);\nconst ICONS = {\n info: '\\x1b[34mℹ\\x1b[0m', // Blue info icon\n focus: '\\x1b[34m➙\\x1b[0m', // Blue arrow icon\n success: '\\x1b[32m✔\\x1b[0m', // Green checkmark\n warning: '\\x1b[33m⚠\\x1b[0m', // Yellow warning icon\n error: '\\x1b[31m✖\\x1b[0m', // Red cross icon\n};\n\nconst resetReportFile = async (reportPath: string) => {\n try {\n await fs.access(reportPath);\n await fs.rm(reportPath);\n console.debug(`${ICONS.info} Removed existing report file${isDebug ? `: ${reportPath}` : '.'}`);\n } catch {\n console.debug(\n `${ICONS.info} No existing report file to remove${isDebug ? `: ${reportPath}` : '.'}`,\n );\n }\n};\n\nconst summariseReportFile = async (reportPath: string) => {\n try {\n const reportContent = await fs.readFile(reportPath, 'utf8');\n const lines = reportContent.split('\\n').filter(Boolean);\n if (lines.length) {\n console.debug(\n `\\n⚠️ ${lines.length} manual review${lines.length > 1 ? 's are' : ' is'} required. See ${reportPath} for details.`,\n );\n } else {\n console.debug(\n `${ICONS.info} Report file exists but is empty${isDebug ? `: ${reportPath}` : '.'}`,\n );\n }\n } catch {\n console.debug(`${ICONS.info} No report file generated - no manual reviews needed`);\n }\n};\n\nasync function runCodemod(transformsDir?: string) {\n try {\n const args = process.argv.slice(2);\n const candidate = args[0];\n isDebug = args.includes('--debug');\n const packages = findPackages();\n const reportPath = path.resolve(findProjectRoot(), 'codemod-report.txt');\n const resolvedTransformsDir =\n transformsDir ?? path.resolve(currentDirPath, '../dist/transforms');\n\n if (isDebug) {\n console.debug(`${ICONS.info} Resolved transforms directory: ${resolvedTransformsDir}`);\n }\n\n await resetReportFile(reportPath);\n\n const { transformFiles } = await loadTransformModules(resolvedTransformsDir);\n // eslint-disable-next-line @typescript-eslint/await-thenable\n const resolvedTransformNames = await Promise.all(transformFiles);\n if (resolvedTransformNames.length === 0) {\n throw new Error(\n `${ICONS.error} No transform scripts found${isDebug ? ` in: ${resolvedTransformsDir}` : '.'}`,\n );\n }\n\n const log = (label: string, value: string): void => {\n if (typeof logToInquirer === 'function') {\n logToInquirer(label, value);\n } else {\n console.info(label, value);\n }\n };\n\n let transformFile: string;\n\n if (candidate && resolvedTransformNames.includes(candidate)) {\n log('Select codemod to run:', candidate);\n transformFile = candidate;\n } else {\n transformFile = await list({\n message: 'Select codemod to run:',\n choices: resolvedTransformNames.map((name) => ({ name, value: name })),\n });\n log('Selected codemod:', transformFile);\n }\n\n const codemodPath = path.resolve(resolvedTransformsDir, transformFile, 'transformer.js');\n if (isDebug) {\n console.debug(`${ICONS.info} Resolved codemod path: ${codemodPath}`);\n }\n\n const promptAnswers = await runTransformPrompts(codemodPath);\n\n const options = await getOptions({\n packages,\n root: findProjectRoot(),\n transformFiles: resolvedTransformNames,\n preselectedTransformFile: transformFile,\n });\n\n options.targetPaths.map((targetPath) => {\n console.info(`${ICONS.focus} \\x1b[1mProcessing:\\x1b[0m \\x1b[32m${targetPath}\\x1b[0m`);\n\n const isCompliant = assessPrerequisites(targetPath, codemodPath);\n if (isCompliant) {\n const answerArgs = Object.entries(promptAnswers).map(\n ([promptName, answerValue]) => `--${promptName}=${String(answerValue)}`,\n );\n\n const argsList = [\n '-t',\n codemodPath,\n targetPath,\n options.isDry ? '--dry' : '',\n options.isPrint ? '--print' : '',\n options.ignorePatterns\n ? options.ignorePatterns\n .split(',')\n .map((pattern) => `--ignore-pattern=${pattern.trim()}`)\n .join(' ')\n : '',\n options.useGitIgnore ? '--gitignore' : '',\n ...answerArgs,\n ].filter(Boolean);\n\n const command = `npx jscodeshift ${argsList.join(' ')}`;\n if (isDebug) {\n console.debug(`${ICONS.info} Running: ${command}`);\n }\n return execSync(command, { stdio: 'inherit' });\n }\n return undefined;\n });\n\n await summariseReportFile(reportPath);\n } catch (error: unknown) {\n if (error instanceof Error) {\n console.error(`${ICONS.error} Error running codemod:`, error.message);\n } else {\n console.error(`${ICONS.error} Error running codemod:`, error);\n }\n if (process.env.NODE_ENV !== 'test') {\n process.exit(1);\n }\n }\n}\n\nexport { runCodemod };\n","#!/usr/bin/env node\nimport { runCodemod } from './controller';\n\nvoid runCodemod();\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["path","fs","findPackages","findProjectRoot","loadTransformModules","logToInquirer","transformFile: string","runTransformPrompts","getOptions","assessPrerequisites","error: unknown"],"sources":["../src/controller/index.ts","../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { execSync } from 'node:child_process';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { select as list } from '@inquirer/prompts';\n\nimport {\n assessPrerequisites,\n findPackages,\n findProjectRoot,\n getOptions,\n loadTransformModules,\n logToInquirer,\n runTransformPrompts,\n} from './helpers';\n\nlet isDebug = false;\nconst currentFilePath = fileURLToPath(import.meta.url);\nconst currentDirPath = path.dirname(currentFilePath);\nconst ICONS = {\n info: '\\x1b[34mℹ\\x1b[0m', // Blue info icon\n focus: '\\x1b[34m➙\\x1b[0m', // Blue arrow icon\n success: '\\x1b[32m✔\\x1b[0m', // Green checkmark\n warning: '\\x1b[33m⚠\\x1b[0m', // Yellow warning icon\n error: '\\x1b[31m✖\\x1b[0m', // Red cross icon\n};\n\nconst resetReportFile = async (reportPath: string) => {\n try {\n await fs.access(reportPath);\n await fs.rm(reportPath);\n console.debug(`${ICONS.info} Removed existing report file${isDebug ? `: ${reportPath}` : '.'}`);\n } catch {\n console.debug(\n `${ICONS.info} No existing report file to remove${isDebug ? `: ${reportPath}` : '.'}`,\n );\n }\n};\n\nconst summariseReportFile = async (reportPath: string) => {\n try {\n const reportContent = await fs.readFile(reportPath, 'utf8');\n const lines = reportContent.split('\\n').filter(Boolean);\n if (lines.length) {\n console.debug(\n `\\n⚠️ ${lines.length} manual review${lines.length > 1 ? 's are' : ' is'} required. See ${reportPath} for details.`,\n );\n } else {\n console.debug(\n `${ICONS.info} Report file exists but is empty${isDebug ? `: ${reportPath}` : '.'}`,\n );\n }\n } catch {\n console.debug(`${ICONS.info} No report file generated - no manual reviews needed`);\n }\n};\n\nasync function runCodemod(transformsDir?: string) {\n try {\n const args = process.argv.slice(2);\n const candidate = args[0];\n isDebug = args.includes('--debug');\n const packages = findPackages();\n const reportPath = path.resolve(findProjectRoot(), 'codemod-report.txt');\n const resolvedTransformsDir =\n transformsDir ?? path.resolve(currentDirPath, '../dist/transforms');\n\n if (isDebug) {\n console.debug(`${ICONS.info} Resolved transforms directory: ${resolvedTransformsDir}`);\n }\n\n await resetReportFile(reportPath);\n\n const { transformFiles } = await loadTransformModules(resolvedTransformsDir);\n\n const resolvedTransformNames = await Promise.all(transformFiles);\n if (resolvedTransformNames.length === 0) {\n throw new Error(\n `${ICONS.error} No transform scripts found${isDebug ? ` in: ${resolvedTransformsDir}` : '.'}`,\n );\n }\n\n const log = (label: string, value: string): void => {\n if (typeof logToInquirer === 'function') {\n logToInquirer(label, value);\n } else {\n console.info(label, value);\n }\n };\n\n let transformFile: string;\n\n if (candidate && resolvedTransformNames.includes(candidate)) {\n log('Select codemod to run:', candidate);\n transformFile = candidate;\n } else {\n transformFile = await list({\n message: 'Select codemod to run:',\n choices: resolvedTransformNames.map((name) => ({ name, value: name })),\n });\n log('Selected codemod:', transformFile);\n }\n\n const codemodPath = path.resolve(resolvedTransformsDir, transformFile, 'transformer.js');\n if (isDebug) {\n console.debug(`${ICONS.info} Resolved codemod path: ${codemodPath}`);\n }\n\n const promptAnswers = await runTransformPrompts(codemodPath);\n\n const options = await getOptions({\n packages,\n root: findProjectRoot(),\n transformFiles: resolvedTransformNames,\n preselectedTransformFile: transformFile,\n });\n\n options.targetPaths.map((targetPath) => {\n console.info(`${ICONS.focus} \\x1b[1mProcessing:\\x1b[0m \\x1b[32m${targetPath}\\x1b[0m`);\n\n const isCompliant = assessPrerequisites(targetPath, codemodPath);\n if (isCompliant) {\n const answerArgs = Object.entries(promptAnswers).map(\n ([promptName, answerValue]) => `--${promptName}=${String(answerValue)}`,\n );\n\n const argsList = [\n '-t',\n codemodPath,\n targetPath,\n options.isDry ? '--dry' : '',\n options.isPrint ? '--print' : '',\n options.ignorePatterns\n ? options.ignorePatterns\n .split(',')\n .map((pattern) => `--ignore-pattern=${pattern.trim()}`)\n .join(' ')\n : '',\n options.useGitIgnore ? '--gitignore' : '',\n ...answerArgs,\n ].filter(Boolean);\n\n const command = `npx jscodeshift ${argsList.join(' ')}`;\n if (isDebug) {\n console.debug(`${ICONS.info} Running: ${command}`);\n }\n return execSync(command, { stdio: 'inherit' });\n }\n return undefined;\n });\n\n await summariseReportFile(reportPath);\n } catch (error: unknown) {\n if (error instanceof Error) {\n console.error(`${ICONS.error} Error running codemod:`, error.message);\n } else {\n console.error(`${ICONS.error} Error running codemod:`, error);\n }\n if (process.env.NODE_ENV !== 'test') {\n process.exit(1);\n }\n }\n}\n\nexport { runCodemod };\n","#!/usr/bin/env node\nimport { runCodemod } from './controller';\n\nvoid runCodemod();\n"],"mappings":"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"}
@@ -32,9 +32,22 @@ var addImport_default = addImport;
32
32
  */
33
33
  function hasImport(root, sourceValue, importName, j) {
34
34
  const importDeclarations = root.find(j.ImportDeclaration, { source: { value: sourceValue } });
35
+ /**
36
+ * Finds all ImportSpecifier nodes that expose `importName` but
37
+ * from a different source than `sourceValue`.
38
+ */
39
+ const conflictingImports = (() => {
40
+ const result = [];
41
+ root.find(j.ImportDeclaration).filter((path) => path.node.source.value !== sourceValue).forEach((path) => {
42
+ for (const specifier of path.node.specifiers ?? []) if (specifier.type === "ImportSpecifier" && specifier.imported.name === importName && specifier.local?.name === importName) result.push(specifier);
43
+ });
44
+ return result;
45
+ })();
35
46
  if (importDeclarations.size() === 0) return {
36
47
  exists: false,
37
- remove: () => {}
48
+ remove: () => {},
49
+ resolvedName: importName,
50
+ conflictingImports
38
51
  };
39
52
  const namedImport = importDeclarations.find(j.ImportSpecifier, { imported: { name: importName } });
40
53
  const defaultImport = importDeclarations.find(j.ImportDefaultSpecifier, { local: { name: importName } });
@@ -42,6 +55,15 @@ function hasImport(root, sourceValue, importName, j) {
42
55
  return path.node.imported.name === importName && path.node.imported.name !== path.node.local?.name;
43
56
  });
44
57
  const exists = namedImport.size() > 0 || defaultImport.size() > 0;
58
+ const resolveName = () => {
59
+ if (aliasImport.size() > 0) {
60
+ const localName = aliasImport.get(0).node.local?.name;
61
+ if (typeof localName === "string") return localName;
62
+ if (localName && typeof localName === "object" && "name" in localName && typeof localName.name === "string") return localName.name;
63
+ return importName;
64
+ }
65
+ return importName;
66
+ };
45
67
  const remove = () => {
46
68
  importDeclarations.forEach((path) => {
47
69
  const filteredSpecifiers = path.node.specifiers?.filter((specifier) => {
@@ -56,7 +78,9 @@ function hasImport(root, sourceValue, importName, j) {
56
78
  return {
57
79
  exists,
58
80
  remove,
59
- aliases: aliasImport
81
+ aliases: aliasImport,
82
+ resolvedName: resolveName(),
83
+ conflictingImports
60
84
  };
61
85
  }
62
86
  var hasImport_default = hasImport;
@@ -131,6 +155,17 @@ const addAttributesIfMissing = (j, openingElement, attributesToAdd) => {
131
155
  if (!hasAttributeOnElement(openingElement, name)) attrs.push(attribute);
132
156
  });
133
157
  };
158
+ /**
159
+ * Returns a collection of JSX elements that match the specified
160
+ * exported name or names of the found aliases.
161
+ */
162
+ const findJSXElementsByName = (root, j) => (exportedName, aliases) => {
163
+ const aliasNames = aliases?.size() ? aliases.paths().map((path) => path.node.local?.name) : [];
164
+ return root.find(j.JSXElement).filter((path) => {
165
+ const { name } = path.node.openingElement;
166
+ return name.type === "JSXIdentifier" && (name.name === exportedName || aliasNames.includes(name.name));
167
+ });
168
+ };
134
169
 
135
170
  //#endregion
136
171
  //#region src/helpers/jsxReportingUtils.ts
@@ -257,6 +292,12 @@ var CodemodReporter = class {
257
292
  reportAliases(element) {
258
293
  this.reportElement(element, "is used via an import alias and needs manual review");
259
294
  }
295
+ /**
296
+ * Finds and reports instances of non-DS import declarations that conflict with the component name
297
+ */
298
+ reportConflictingImports(node) {
299
+ this.addIssue(`Manual review required: Non-WDS package resulting in an import conflict at line ${this.getLineNumber(node)}.`);
300
+ }
260
301
  getNode(element) {
261
302
  return "node" in element ? element.node : element;
262
303
  }
@@ -384,7 +425,8 @@ const transformer = (file, api, options) => {
384
425
  return priority;
385
426
  };
386
427
  const reporter = createReporter(j, manualReviewIssues);
387
- const { exists: hasButtonImport, aliases: buttonAliases } = hasImport_default(root, "@transferwise/components", "Button", j);
428
+ const { exists: hasButtonImport, aliases: buttonAliases, resolvedName: buttonName, conflictingImports: conflictingButtonImport } = hasImport_default(root, "@transferwise/components", "Button", j);
429
+ if (conflictingButtonImport.length) conflictingButtonImport.forEach((node) => reporter.reportConflictingImports(node));
388
430
  const { exists: hasActionButtonImport, remove: removeActionButtonImport, aliases: actionButtonAliases } = hasImport_default(root, "@transferwise/components", "ActionButton", j);
389
431
  const iconImports = /* @__PURE__ */ new Set();
390
432
  root.find(j.ImportDeclaration, { source: { value: "@transferwise/icons" } }).forEach((path) => {
@@ -397,15 +439,10 @@ const transformer = (file, api, options) => {
397
439
  });
398
440
  if (hasActionButtonImport) {
399
441
  if (!hasButtonImport) addImport_default(root, "@transferwise/components", "Button", j);
400
- if (actionButtonAliases && actionButtonAliases.size() > 0) actionButtonAliases.forEach((path) => {
401
- root.findJSXElements(path.node.local?.name).forEach((el) => {
402
- reporter.reportAliases(el);
403
- });
404
- });
405
- root.findJSXElements("ActionButton").forEach((path) => {
442
+ findJSXElementsByName(root, j)("ActionButton", actionButtonAliases).forEach((path) => {
406
443
  const { openingElement, closingElement } = path.node;
407
- openingElement.name = setNameIfJSXIdentifier(openingElement.name, "Button");
408
- if (closingElement) closingElement.name = setNameIfJSXIdentifier(closingElement.name, "Button");
444
+ openingElement.name = setNameIfJSXIdentifier(openingElement.name, buttonName);
445
+ if (closingElement) closingElement.name = setNameIfJSXIdentifier(closingElement.name, buttonName);
409
446
  iconUtils_default(j, path.node.children, iconImports, openingElement);
410
447
  if ((openingElement.attributes ?? []).some((attr) => attr.type === "JSXSpreadAttribute")) reporter.reportSpreadProps(path);
411
448
  const legacyPropNames = [
@@ -446,120 +483,113 @@ const transformer = (file, api, options) => {
446
483
  });
447
484
  removeActionButtonImport();
448
485
  }
449
- if (hasButtonImport) {
450
- if (buttonAliases && buttonAliases.size() > 0) buttonAliases.forEach((path) => {
451
- root.findJSXElements(path.node.local?.name).forEach((el) => {
452
- reporter.reportAliases(el);
453
- });
454
- });
455
- root.findJSXElements("Button").forEach((path) => {
456
- const { openingElement } = path.node;
457
- if (hasAttributeOnElement(openingElement, "v2")) return;
458
- const hasJSXChildren = path.node.children?.some((child) => child.type === "JSXText" && child.value.trim() !== "" || child.type === "JSXElement" || child.type === "JSXFragment" && child.children && child.children.length > 0 || child.type === "JSXExpressionContainer" && child.expression.type !== "JSXEmptyExpression");
459
- const hasChildrenAsProp = openingElement.attributes?.some((attr) => attr.type === "JSXAttribute" && attr.name?.type === "JSXIdentifier" && attr.name.name === "children");
460
- if (!hasJSXChildren && !hasChildrenAsProp) return;
461
- addAttributesIfMissing(j, openingElement, [{
462
- attribute: j.jsxAttribute(j.jsxIdentifier("v2")),
463
- name: "v2"
464
- }]);
465
- iconUtils_default(j, path.node.children, iconImports, openingElement);
466
- const legacyProps = {};
467
- const legacyPropNames = [
468
- "priority",
469
- "size",
470
- "type",
471
- "htmlType",
472
- "sentiment"
473
- ];
474
- openingElement.attributes?.forEach((attr) => {
475
- if (attr.type === "JSXAttribute" && attr.name && attr.name.type === "JSXIdentifier") {
476
- const { name } = attr.name;
477
- if (legacyPropNames.includes(name)) if (attr.value) {
478
- if (attr.value.type === "StringLiteral") legacyProps[name] = attr.value.value;
479
- else if (attr.value.type === "JSXExpressionContainer") legacyProps[name] = convertEnumValue(String(j(attr.value.expression).toSource()));
480
- } else legacyProps[name] = void 0;
481
- }
482
- });
483
- if (openingElement.attributes) openingElement.attributes = openingElement.attributes.filter((attr) => !(attr.type === "JSXAttribute" && attr.name && legacyPropNames.includes(attr.name.name)));
484
- if ("size" in legacyProps) {
485
- const rawValue = legacyProps.size;
486
- const resolved = resolveSize(rawValue);
487
- if (typeof rawValue === "string" && typeof resolved === "string" && [
488
- "sm",
489
- "md",
490
- "lg",
491
- "xl"
492
- ].includes(resolved)) openingElement.attributes?.push(j.jsxAttribute(j.jsxIdentifier("size"), j.literal(resolved)));
493
- else if (typeof rawValue === "string") reporter.reportUnsupportedValue(path, "size", rawValue);
494
- else if (rawValue !== void 0) reporter.reportAmbiguousExpression(path, "size");
486
+ if (hasButtonImport) findJSXElementsByName(root, j)("Button", buttonAliases).forEach((path) => {
487
+ const { openingElement } = path.node;
488
+ if (hasAttributeOnElement(openingElement, "v2")) return;
489
+ const hasJSXChildren = path.node.children?.some((child) => child.type === "JSXText" && child.value.trim() !== "" || child.type === "JSXElement" || child.type === "JSXFragment" && child.children && child.children.length > 0 || child.type === "JSXExpressionContainer" && child.expression.type !== "JSXEmptyExpression");
490
+ const hasChildrenAsProp = openingElement.attributes?.some((attr) => attr.type === "JSXAttribute" && attr.name?.type === "JSXIdentifier" && attr.name.name === "children");
491
+ if (!hasJSXChildren && !hasChildrenAsProp) return;
492
+ addAttributesIfMissing(j, openingElement, [{
493
+ attribute: j.jsxAttribute(j.jsxIdentifier("v2")),
494
+ name: "v2"
495
+ }]);
496
+ iconUtils_default(j, path.node.children, iconImports, openingElement);
497
+ const legacyProps = {};
498
+ const legacyPropNames = [
499
+ "priority",
500
+ "size",
501
+ "type",
502
+ "htmlType",
503
+ "sentiment"
504
+ ];
505
+ openingElement.attributes?.forEach((attr) => {
506
+ if (attr.type === "JSXAttribute" && attr.name && attr.name.type === "JSXIdentifier") {
507
+ const { name } = attr.name;
508
+ if (legacyPropNames.includes(name)) if (attr.value) {
509
+ if (attr.value.type === "StringLiteral") legacyProps[name] = attr.value.value;
510
+ else if (attr.value.type === "JSXExpressionContainer") legacyProps[name] = convertEnumValue(String(j(attr.value.expression).toSource()));
511
+ } else legacyProps[name] = void 0;
495
512
  }
496
- if ("priority" in legacyProps) {
497
- const rawValue = legacyProps.priority;
498
- const converted = convertEnumValue(rawValue);
499
- const mapped = resolvePriority(legacyProps.type, converted);
500
- if (typeof rawValue === "string" && typeof mapped === "string" && [
501
- "primary",
502
- "secondary",
503
- "tertiary",
504
- "secondary-neutral"
505
- ].includes(mapped)) openingElement.attributes?.push(j.jsxAttribute(j.jsxIdentifier("priority"), j.literal(mapped)));
506
- else if (typeof rawValue === "string") reporter.reportUnsupportedValue(path, "priority", rawValue);
507
- else if (rawValue !== void 0) reporter.reportAmbiguousExpression(path, "priority");
508
- }
509
- if ("type" in legacyProps || "htmlType" in legacyProps) {
510
- const rawType = legacyProps.type;
511
- const rawHtmlType = legacyProps.htmlType;
512
- const resolvedType = typeof rawType === "string" ? rawType : rawType && typeof rawType === "object" ? convertEnumValue(j(rawType).toSource()) : void 0;
513
- const resolved = resolveType(resolvedType, rawHtmlType);
514
- if (typeof resolved === "string" && [
515
- "accent",
516
- "negative",
517
- "positive",
518
- "primary",
519
- "pay",
520
- "secondary",
521
- "danger",
522
- "link",
523
- "submit",
524
- "button",
525
- "reset"
526
- ].includes(resolved)) {
527
- openingElement.attributes?.push(j.jsxAttribute(j.jsxIdentifier("type"), j.literal(resolved)));
528
- if (resolved === "negative") openingElement.attributes?.push(j.jsxAttribute(j.jsxIdentifier("sentiment"), j.literal("negative")));
529
- } else if (typeof rawType === "string" || typeof rawHtmlType === "string") reporter.reportUnsupportedValue(path, "type", rawType ?? rawHtmlType ?? "");
530
- else if (rawType !== void 0 || rawHtmlType !== void 0) reporter.reportAmbiguousExpression(path, "type");
531
- }
532
- if ("sentiment" in legacyProps) {
533
- const rawValue = legacyProps.sentiment;
534
- if (rawValue === "negative") openingElement.attributes?.push(j.jsxAttribute(j.jsxIdentifier("sentiment"), j.literal("negative")));
535
- else if (typeof rawValue === "string") reporter.reportUnsupportedValue(path, "sentiment", rawValue);
536
- else if (rawValue !== void 0) reporter.reportAmbiguousExpression(path, "sentiment");
537
- }
538
- let asIndex = -1;
539
- let asValue = null;
540
- let hrefExists = false;
541
- openingElement.attributes?.forEach((attr, index) => {
542
- if (attr.type === "JSXAttribute" && attr.name) {
543
- if (attr.name.name === "as") {
544
- if (attr.value) {
545
- if (attr.value.type === "StringLiteral") asValue = attr.value.value;
546
- else if (attr.value.type === "JSXExpressionContainer") reporter.reportAttribute(attr, path);
547
- }
548
- asIndex = index;
549
- }
550
- if (attr.name.name === "href") {
551
- hrefExists = true;
552
- if (attr.value && attr.value.type !== "StringLiteral") reporter.reportAttribute(attr, path);
513
+ });
514
+ if (openingElement.attributes) openingElement.attributes = openingElement.attributes.filter((attr) => !(attr.type === "JSXAttribute" && attr.name && legacyPropNames.includes(attr.name.name)));
515
+ if ("size" in legacyProps) {
516
+ const rawValue = legacyProps.size;
517
+ const resolved = resolveSize(rawValue);
518
+ if (typeof rawValue === "string" && typeof resolved === "string" && [
519
+ "sm",
520
+ "md",
521
+ "lg",
522
+ "xl"
523
+ ].includes(resolved)) openingElement.attributes?.push(j.jsxAttribute(j.jsxIdentifier("size"), j.literal(resolved)));
524
+ else if (typeof rawValue === "string") reporter.reportUnsupportedValue(path, "size", rawValue);
525
+ else if (rawValue !== void 0) reporter.reportAmbiguousExpression(path, "size");
526
+ }
527
+ if ("priority" in legacyProps) {
528
+ const rawValue = legacyProps.priority;
529
+ const converted = convertEnumValue(rawValue);
530
+ const mapped = resolvePriority(legacyProps.type, converted);
531
+ if (typeof rawValue === "string" && typeof mapped === "string" && [
532
+ "primary",
533
+ "secondary",
534
+ "tertiary",
535
+ "secondary-neutral"
536
+ ].includes(mapped)) openingElement.attributes?.push(j.jsxAttribute(j.jsxIdentifier("priority"), j.literal(mapped)));
537
+ else if (typeof rawValue === "string") reporter.reportUnsupportedValue(path, "priority", rawValue);
538
+ else if (rawValue !== void 0) reporter.reportAmbiguousExpression(path, "priority");
539
+ }
540
+ if ("type" in legacyProps || "htmlType" in legacyProps) {
541
+ const rawType = legacyProps.type;
542
+ const rawHtmlType = legacyProps.htmlType;
543
+ const resolvedType = typeof rawType === "string" ? rawType : rawType && typeof rawType === "object" ? convertEnumValue(j(rawType).toSource()) : void 0;
544
+ const resolved = resolveType(resolvedType, rawHtmlType);
545
+ if (typeof resolved === "string" && [
546
+ "accent",
547
+ "negative",
548
+ "positive",
549
+ "primary",
550
+ "pay",
551
+ "secondary",
552
+ "danger",
553
+ "link",
554
+ "submit",
555
+ "button",
556
+ "reset"
557
+ ].includes(resolved)) {
558
+ openingElement.attributes?.push(j.jsxAttribute(j.jsxIdentifier("type"), j.literal(resolved)));
559
+ if (resolved === "negative") openingElement.attributes?.push(j.jsxAttribute(j.jsxIdentifier("sentiment"), j.literal("negative")));
560
+ } else if (typeof rawType === "string" || typeof rawHtmlType === "string") reporter.reportUnsupportedValue(path, "type", rawType ?? rawHtmlType ?? "");
561
+ else if (rawType !== void 0 || rawHtmlType !== void 0) reporter.reportAmbiguousExpression(path, "type");
562
+ }
563
+ if ("sentiment" in legacyProps) {
564
+ const rawValue = legacyProps.sentiment;
565
+ if (rawValue === "negative") openingElement.attributes?.push(j.jsxAttribute(j.jsxIdentifier("sentiment"), j.literal("negative")));
566
+ else if (typeof rawValue === "string") reporter.reportUnsupportedValue(path, "sentiment", rawValue);
567
+ else if (rawValue !== void 0) reporter.reportAmbiguousExpression(path, "sentiment");
568
+ }
569
+ let asIndex = -1;
570
+ let asValue = null;
571
+ let hrefExists = false;
572
+ openingElement.attributes?.forEach((attr, index) => {
573
+ if (attr.type === "JSXAttribute" && attr.name) {
574
+ if (attr.name.name === "as") {
575
+ if (attr.value) {
576
+ if (attr.value.type === "StringLiteral") asValue = attr.value.value;
577
+ else if (attr.value.type === "JSXExpressionContainer") reporter.reportAttribute(attr, path);
553
578
  }
579
+ asIndex = index;
580
+ }
581
+ if (attr.name.name === "href") {
582
+ hrefExists = true;
583
+ if (attr.value && attr.value.type !== "StringLiteral") reporter.reportAttribute(attr, path);
554
584
  }
555
- });
556
- if (asValue === "a") {
557
- if (asIndex !== -1) openingElement.attributes = openingElement.attributes?.filter((_attr, idx) => idx !== asIndex);
558
- if (!hrefExists) openingElement.attributes = [...openingElement.attributes ?? [], j.jsxAttribute(j.jsxIdentifier("href"), j.literal("#"))];
559
585
  }
560
- if ((openingElement.attributes ?? []).some((attr) => attr.type === "JSXSpreadAttribute")) reporter.reportSpreadProps(path);
561
586
  });
562
- }
587
+ if (asValue === "a") {
588
+ if (asIndex !== -1) openingElement.attributes = openingElement.attributes?.filter((_attr, idx) => idx !== asIndex);
589
+ if (!hrefExists) openingElement.attributes = [...openingElement.attributes ?? [], j.jsxAttribute(j.jsxIdentifier("href"), j.literal("#"))];
590
+ }
591
+ if ((openingElement.attributes ?? []).some((attr) => attr.type === "JSXSpreadAttribute")) reporter.reportSpreadProps(path);
592
+ });
563
593
  if (manualReviewIssues.length > 0) manualReviewIssues.forEach(async (issue) => {
564
594
  await require_helpers.reportManualReview_default(file.path, issue);
565
595
  });
@@ -1 +1 @@
1
- {"version":3,"file":"transformer.js","names":["sizeMap: Record<string, string>","j: JSCodeshift","manualReviewIssues: string[]","hasImport","legacyProps: LegacyProps","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 { 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): { exists: boolean; remove: () => void; aliases?: Collection<ImportSpecifier> } {\n const importDeclarations = root.find(j.ImportDeclaration, {\n source: { value: sourceValue },\n });\n\n if (importDeclarations.size() === 0) {\n return {\n exists: false,\n remove: () => {},\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 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 };\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 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","import type {\n ASTPath,\n Collection,\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 // 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, JSXFragment, JSXIdentifier, Options } from 'jscodeshift';\n\nimport { reportManualReview } from '../../controller/helpers';\nimport {\n addAttributesIfMissing,\n addImport,\n createReporter,\n hasAttributeOnElement,\n hasImport,\n processIconChildren,\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 };\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 resolveType = (type?: string, htmlType?: string): string | null => {\n if (htmlType) {\n return htmlType;\n }\n const legacyButtonTypes = [\n 'accent',\n 'negative',\n 'positive',\n 'primary',\n 'pay',\n 'secondary',\n 'danger',\n 'link',\n ];\n return type && legacyButtonTypes.includes(type) ? 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 * 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 { exists: hasButtonImport, aliases: buttonAliases } = hasImport(\n root,\n '@transferwise/components',\n 'Button',\n j,\n );\n const {\n exists: hasActionButtonImport,\n remove: removeActionButtonImport,\n aliases: actionButtonAliases,\n } = hasImport(root, '@transferwise/components', 'ActionButton', j);\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 // Report aliased ActionButton components\n if (actionButtonAliases && actionButtonAliases.size() > 0) {\n actionButtonAliases.forEach((path) => {\n root.findJSXElements(path.node.local?.name as string).forEach((el) => {\n reporter.reportAliases(el);\n });\n });\n }\n\n root.findJSXElements('ActionButton').forEach((path) => {\n const { openingElement, closingElement } = path.node;\n\n openingElement.name = setNameIfJSXIdentifier(openingElement.name, 'Button')!;\n if (closingElement) {\n closingElement.name = setNameIfJSXIdentifier(closingElement.name, 'Button')!;\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 reporter.reportAttribute(attr, path);\n }\n }\n }\n }\n });\n\n if (openingElement.attributes) {\n openingElement.attributes = openingElement.attributes.filter(\n (attr) =>\n !(\n attr.type === 'JSXAttribute' &&\n attr.name &&\n legacyPropNames.includes((attr.name as JSXIdentifier).name)\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 // Assign necessary props based on newly replaced path, instead of original openingElement\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 // Report aliased Button components\n if (buttonAliases && buttonAliases.size() > 0) {\n buttonAliases.forEach((path) => {\n root.findJSXElements(path.node.local?.name as string).forEach((el) => {\n reporter.reportAliases(el);\n });\n });\n }\n\n root.findJSXElements('Button').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 legacyProps[name] = convertEnumValue(String(j(attr.value.expression).toSource()));\n }\n } else {\n legacyProps[name] = undefined;\n }\n }\n }\n });\n\n if (openingElement.attributes) {\n openingElement.attributes = openingElement.attributes.filter(\n (attr) =>\n !(\n attr.type === 'JSXAttribute' &&\n attr.name &&\n legacyPropNames.includes((attr.name as JSXIdentifier).name)\n ),\n );\n }\n\n if ('size' in legacyProps) {\n const rawValue = legacyProps.size;\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 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 if ('priority' in legacyProps) {\n const rawValue = legacyProps.priority;\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 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 if ('type' in legacyProps || 'htmlType' in legacyProps) {\n const rawType = legacyProps.type;\n const rawHtmlType = legacyProps.htmlType;\n const resolvedType =\n typeof rawType === 'string'\n ? rawType\n : rawType && typeof rawType === 'object'\n ? convertEnumValue(j(rawType).toSource())\n : undefined;\n const resolved = resolveType(resolvedType, rawHtmlType);\n\n const supportedTypes = [\n 'accent',\n 'negative',\n 'positive',\n 'primary',\n 'pay',\n 'secondary',\n 'danger',\n 'link',\n 'submit',\n 'button',\n 'reset',\n ];\n\n if (typeof resolved === 'string' && supportedTypes.includes(resolved)) {\n openingElement.attributes?.push(\n j.jsxAttribute(j.jsxIdentifier('type'), j.literal(resolved)),\n );\n if (resolved === 'negative') {\n openingElement.attributes?.push(\n j.jsxAttribute(j.jsxIdentifier('sentiment'), j.literal('negative')),\n );\n }\n } else if (typeof rawType === 'string' || typeof rawHtmlType === 'string') {\n reporter.reportUnsupportedValue(path, 'type', rawType ?? rawHtmlType ?? '');\n } else if (rawType !== undefined || rawHtmlType !== undefined) {\n reporter.reportAmbiguousExpression(path, 'type');\n }\n }\n\n if ('sentiment' in legacyProps) {\n const rawValue = legacyProps.sentiment;\n if (rawValue === 'negative') {\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 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","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","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 // 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, JSXIdentifier, 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 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 };\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 resolveType = (type?: string, htmlType?: string): string | null => {\n if (htmlType) {\n return htmlType;\n }\n const legacyButtonTypes = [\n 'accent',\n 'negative',\n 'positive',\n 'primary',\n 'pay',\n 'secondary',\n 'danger',\n 'link',\n ];\n return type && legacyButtonTypes.includes(type) ? 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 * 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 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 reporter.reportAttribute(attr, path);\n }\n }\n }\n }\n });\n\n if (openingElement.attributes) {\n openingElement.attributes = openingElement.attributes.filter(\n (attr) =>\n !(\n attr.type === 'JSXAttribute' &&\n attr.name &&\n legacyPropNames.includes((attr.name as JSXIdentifier).name)\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 // Assign necessary props based on newly replaced path, instead of original openingElement\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 legacyProps[name] = convertEnumValue(String(j(attr.value.expression).toSource()));\n }\n } else {\n legacyProps[name] = undefined;\n }\n }\n }\n });\n\n if (openingElement.attributes) {\n openingElement.attributes = openingElement.attributes.filter(\n (attr) =>\n !(\n attr.type === 'JSXAttribute' &&\n attr.name &&\n legacyPropNames.includes((attr.name as JSXIdentifier).name)\n ),\n );\n }\n\n if ('size' in legacyProps) {\n const rawValue = legacyProps.size;\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 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 if ('priority' in legacyProps) {\n const rawValue = legacyProps.priority;\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 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 if ('type' in legacyProps || 'htmlType' in legacyProps) {\n const rawType = legacyProps.type;\n const rawHtmlType = legacyProps.htmlType;\n const resolvedType =\n typeof rawType === 'string'\n ? rawType\n : rawType && typeof rawType === 'object'\n ? convertEnumValue(j(rawType).toSource())\n : undefined;\n const resolved = resolveType(resolvedType, rawHtmlType);\n\n const supportedTypes = [\n 'accent',\n 'negative',\n 'positive',\n 'primary',\n 'pay',\n 'secondary',\n 'danger',\n 'link',\n 'submit',\n 'button',\n 'reset',\n ];\n\n if (typeof resolved === 'string' && supportedTypes.includes(resolved)) {\n openingElement.attributes?.push(\n j.jsxAttribute(j.jsxIdentifier('type'), j.literal(resolved)),\n );\n if (resolved === 'negative') {\n openingElement.attributes?.push(\n j.jsxAttribute(j.jsxIdentifier('sentiment'), j.literal('negative')),\n );\n }\n } else if (typeof rawType === 'string' || typeof rawHtmlType === 'string') {\n reporter.reportUnsupportedValue(path, 'type', rawType ?? rawHtmlType ?? '');\n } else if (rawType !== undefined || rawHtmlType !== undefined) {\n reporter.reportAmbiguousExpression(path, 'type');\n }\n }\n\n if ('sentiment' in legacyProps) {\n const rawValue = legacyProps.sentiment;\n if (rawValue === 'negative') {\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 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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wise/wds-codemods",
3
- "version": "0.0.1-experimental-517fc6b",
3
+ "version": "0.0.1-experimental-d6a8c5c",
4
4
  "license": "UNLICENSED",
5
5
  "author": "Wise Payments Ltd.",
6
6
  "repository": {